While I was wiring the mnemospark backend APIs, I kept bumping into this idea: this stack expects callers to interact with payment via an Ethereum wallet and address. So, if that is where the road ultimately goes, why let traffic in to wander around into JSON bodies and storage flows before anyone had even shown they could present a valid wallet?
If you cannot prove control of a wallet at the door, the service should not behave as if you are ready to complete the rest of the flow and it should not burn additional trust and cycles on you.
That is the practical origin of wallet proof: treat it as the API’s handshake layer, the same role session establishment plays in older stacks, except the handshake is verifiable at the edge, bound to this HTTP call, and aligned with how the API Gateway and Lambdas are wired into the mnemospark-backend.
Thus the “wallet proof” concept was born:
The wallet proof is a cryptographically signed value that authenticates the client to the mnemospark-backend. The client proves it holds the private key for a given wallet address by signing a structured request payload. The backend verifies the signature and can reject requests with invalid or expired proofs.
So how does it work?
Client — the mnemospark client holds a EVM compatible wallet and can sign transactions and produce a
X-Wallet-Signature.Edge — API Gateway fronts the REST API. A Lambda request authorizer runs on protected invocations: decode
X-Wallet-Signature, verify cryptography, enforce freshness and replay rules, then return allow with wallet context or deny. Only after allow does traffic reach the route Lambda.Application — Handlers for quotes, storage, payment settlement, persistence (DynamoDB and object storage) rely on the authorizer outcome to scope data by wallet, not to re-invent trust from ad-hoc headers alone.
An OpenAPI v3.2 spec file sits beside this as the published contract: paths, methods, error shapes and the wallet proof security scheme.
A mnemospark request payload is built from:
Field | Description |
|---|---|
| HTTP method, normalized to uppercase (e.g. |
| Request path, normalized: leading slash, no trailing slash, no query/fragment (e.g. |
| EVM address (checksummed) of the wallet that will sign. |
| 32-byte cryptographically random hex string ( |
| Unix time in seconds (string). |
The payload is signed as EIP-712 typed data (see EIP-712), using types that align with Solidity and OpenZeppelin EIP712 (v4 encoding).
The X-Wallet-Signature header value is a base64-encoded JSON object with:
Field | Description |
|---|---|
| Base64-encoded JSON of the MnemosparkRequest payload. |
| The EIP-712 signature (hex string). |
| The signer’s address (must match payload’s |
So: X-Wallet-Signature: base64(JSON.stringify({ payloadB64, signature, address })).
Plugin / OpenClaw (via proxy)
The local mnemospark proxy holds the wallet key. When the plugin sends a storage or price-storage request, the proxy builds the payload for the requested method and path, signs it with the configured wallet, and forwards the request to the backend with X-Wallet-Signature set
The wallet proof is sent on every request to mnemospark backend APIs that are scoped to a wallet:
Price / storage quote:
POST /price-storageUpload:
POST /storage/uploadList:
POST /storage/lsDownload:
POST /storage/downloadDelete:
POST /storage/delete
The client sets the HTTP header:
X-Wallet-Signature: <base64 envelope>The backend:
Decodes the envelope and payload.
Verifies the EIP-712 signature for the given domain and message.
Can enforce nonce/timestamp (e.g. reject expired or replay).
Returns
403withwallet_proof_invalid(or similar) when the proof is missing, malformed, or fails verification.
The wallet proof is used to authenticate the caller as the holder of that wallet and to bind the signature to method, path and nonce/timestamp.
The same OpenAPI surface documents HTTP 402 and payment headers for USDC / x402-style flows. Those layers are intentionally separate:
Wallet proof answers who is calling.
Payment artifacts answer whether they paid for the resource.
A caller can be cryptographically identified and still receive 402 Payment Required until settlement headers satisfy the payment path.
Wallet proof is gate keeping, not a full zero-trust program: it does not fix operator key custody on the machine that signs, and it does not stop a legitimate wallet from misbehaving after it is admitted. What it does do is give you a clean, repeatable eligibility decision at the edge that opens room for stricter, more creative policy before expensive work runs.
The obvious next layers are identity-aware screening at the same choke point, wallet deny-lists where your risk model calls for them, and where your legal and compliance posture requires it. Such as hooks into sanctions and AML workflows that evaluate addresses against authoritative lists (for example OFAC and UN consolidated screening expectations) so high-risk traffic can be refused early.

