The attest button.
A one-click Attest with Mneme button injected into ChatGPT, Claude, and Gemini. The wallet hashes prompt and reply locally, asks you to approve, and submits a Proof of Prompt receipt to Ligate. The chain never sees plaintext.
The Attest with Mneme button is the moment the chain becomes tangible for an end user. It turns any conversation with a supported model into a verifiable on-chain receipt without leaving the AI tab. The flow is privacy-preserving: the chain stores hashes and signatures, never the prompt or the model output.
Where it appears
A content script injects the button into the supported AI chat UIs at these surfaces:
- → ChatGPT (chat.openai.com): adjacent to the share / regenerate controls below a completed assistant turn
- → Claude (claude.ai): in the message-actions toolbar that appears on hover
- → Gemini (gemini.google.com): next to the rating buttons under each response
The selectors are versioned and ship with the extension. When a host site changes its DOM, the affected version of Mneme falls back to a floating action button anchored to the bottom-right of the conversation until the next release.
What happens on click
1. Local capture
Mneme reads the prompt and the assistant reply from the page. Nothing leaves the browser yet.
2. Local hashing
The extension computes:
prompt_hash = sha256(canonicalize(prompt)) output_hash = sha256(canonicalize(reply))
Canonicalization rules follow the Proof of Prompt spec (UTF-8, LF-only line endings, no tokenizer normalization). The hashes are deterministic across operating systems and Mneme versions.
3. Approval popup
Mneme opens its standard sign-and-submit popup. You see:
- → The schema being attested under:
themisra.proof-of-prompt/v1 - → The model identifier (e.g.
openai/gpt-5) - → The two payload hashes
- → Estimated fee (~0.0001 LGT in the v0 fee schedule)
- → Your account (
lig1...) and balance
Approving signs the call message with your ed25519 key. Rejecting discards the local hashes and nothing leaves the browser.
4. Submission
Mneme submits a SubmitAttestation transaction to a Ligate RPC endpoint. The chain enforces three invariants on receipt:
- → The schema id exists and is
themisra.proof-of-prompt/v1 - → The signature meets the schema's attestor-set threshold (in v0 this is the Themisra federated set)
- → The
(schema_id, payload_hash)pair has not been written before
On success the popup shows the block height and an explorer link. The anchored receipt typically lands within ~200ms of submission.
What it does not do
- → It does not exfiltrate the prompt or output. The chain sees hashes only. Mneme keeps no remote copy.
- → It does not call the model. The button is post-hoc — you receive the reply normally, then attest if you want a receipt.
- → It does not auto-attest by default. Every receipt requires explicit approval. An opt-in "auto-attest replies from this assistant" toggle lands in v1.
Bypassing the button
Power users and automation paths can attest directly via the dApp connector without going through the chat-UI button. See dApp connector.