# Memona signature plugin Opens a WebDAV server as a folder inside Memona and signs every Markdown file saved to it with an ENS name, writing `signer` and `signature` into the file's frontmatter so anyone can check who wrote it against the name's current ENSv2 records. Signing comes from the [md-ens-signature](https://github.com/capsulizers/md-ens-signature) library. The plugin is a WASI component: it speaks no sockets of its own and makes every request through the host's HTTP interface, under the connection's permissions. It registers one provider, `signature`, for the `signed-webdav` scheme. ## Connecting | Field | Meaning | | --- | --- | | Server address | The folder's address, for example `https://dav.example.com/files/` | | Username | Optional account name for HTTP basic authentication | | Password | Optional password, stored as a secret | | Signer name | The ENS name that signs, for example `laptop.alice.eth` | | Signing key | The private key of the address the name resolves to, stored as a secret | | Sepolia RPC address | The endpoint used to check signers against ENS, by default `https://ethereum-sepolia-rpc.publicnode.com` | Listing, reading, writing, creating directories, renaming and deleting behave as in the WebDAV plugin: reads and writes stream in pieces of at most 1 MiB, conditional writes use `If-Match` and `If-None-Match`, change polling is not supported, a rename never replaces an existing target, and a folder with contents is refused rather than removed whole. ## Signing Saving a `.md` file holds it whole, up to 96 KiB, and writes it once finished, with `signer` and `signature` set in its frontmatter; every other file streams straight through. The signature is EIP-191 `personal_sign` over the signer name and the body's SHA-256, made with the configured key; other frontmatter and the body stay byte for byte. A key that is not 32 bytes of hex refuses the connection, and a `.md` file that is not UTF-8 refuses the save. ## Verifying Reading a `.md` file of up to 40 KiB checks its signature against ENSv2 on Sepolia through the RPC address and adds an `ens-verification` line to the frontmatter Memona receives, which Memona shows as a badge; a larger one up to 1 MiB is marked as not checked. Both limits keep hashing and key recovery inside the instruction budget Memona gives each call. The line never reaches the server: a save drops it before signing, and one stored on the server is replaced. Verdicts are reused for 30 seconds per signed body. ## Building ```sh rustup target add wasm32-wasip2 cargo build --locked --release --target wasm32-wasip2 cargo test --locked --lib ``` The component lands at `target/wasm32-wasip2/release/memona_plugin_signature.wasm`. `wit/filesystem.wit` is a copy of the canonical Memona filesystem contract, and `src/sdk.rs` generates the guest bindings from it, so this repository builds without a Memona checkout. Refresh the copy from `plugin_system/sdk/wit` in the [Memona repository](https://git.capsulizers.com/lead/memona) when the contract moves, and keep `apiVersion` in `manifest.json` in step. ## Packaging for the plugin store A `.memona-plugin` package is a ZIP archive with the files at its root, never inside a directory: ```sh cargo build --locked --release --target wasm32-wasip2 cp target/wasm32-wasip2/release/memona_plugin_signature.wasm plugin.wasm zip memona-plugin-signature.memona-plugin \ manifest.json plugin.wasm README.md LICENSE ``` `manifest.json` and `plugin.wasm` are required; `README.md` becomes the guide on the plugin's public page and `LICENSE` is shown beside it. ## Attribution The WebDAV code in `src/lib.rs`, `src/dav.rs` and `src/sdk.rs` is copied from the MIT-licensed [Memona WebDAV plugin](https://git.capsulizers.com/commons/memona-plugin-webdav) at commit `3d69750`. That crate keeps its provider, reader and writer private and exports the component's entry points itself, so it cannot be wrapped as a dependency without forking it; the copy stays as close to the original as the signing hook allows, so fixes there carry over with a plain diff.