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 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 8 MiB, 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. Reading passes every file through unchanged. The RPC address is for verifying signers, which a later version adds to reads.

Building

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 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:

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 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.

S
Description
Sign Markdown files with an ENS name as they are saved to a WebDAV folder in Memona.
Readme MIT 313 KiB
Languages
Rust 100%