The connector.
A standard window.mneme provider injected into every page so any Ligate dApp can request the active account, sign messages, and submit transactions in one snippet. No bespoke per-product wallet plumbing.
The Mneme connector is the canonical wallet integration for any dApp running on Ligate Chain. Themisra, Kleidon, Iris, and partner schemas all wire through the same provider object, so end users authenticate once and every Ligate-native product feels continuous.
The provider object
When Mneme is installed, window.mneme becomes available on every page. Detect it the same way you would detect MetaMask:
if (typeof window.mneme === 'undefined') {
// Mneme is not installed. Show an install prompt linking
// to the Chrome / Firefox / Edge stores.
}Connect
Request the user's active account. Mneme opens an approval popup the first time a given origin asks; subsequent calls return cached permission until the user revokes it.
const { address, publicKey } = await window.mneme.connect({
appName: 'Themisra',
origin: 'https://themisra.xyz',
})
// → address : 'lig1h72nh5c7jfjkcygku4thsh2t53dyh33kkpktpy84w06qwr4agvt'
// → publicKey : 'lpk1...'The connector returns the active lig1... address and the matching lpk1... public key. Per ed25519 derivation rules the address and public key encode the same key material in two different prefixes.
Sign and submit
The connector exposes one combined submit method that signs and broadcasts a transaction in one popup:
const result = await window.mneme.submit({
type: 'SubmitAttestation',
schema_id: 'lsc1_eu_ai_content_v1...',
payload_hash: 'lph19zc4...ea3d',
signatures: [/* attestor signatures, if applicable */],
})
// → { tx_hash, block_height, attestation_id }Mneme renders a transaction summary tailored to the call message kind. For SubmitAttestation the popup shows the schema, the payload hash, the fee, and the attestor set the schema is bound to. For RegisterSchema and RegisterAttestorSet it shows the registration fee and the configured fields. Other call messages get a generic JSON view.
Sign without submitting
For relayer-driven flows (Iris pattern) the dApp can request a signed but un-broadcast transaction:
const { signed_tx } = await window.mneme.sign({
type: 'SubmitAttestation',
schema_id: '...',
payload_hash: '...',
})
// dApp / relayer broadcasts via its own RPC.Events
The provider emits events when the user changes state:
- →
accountsChanged— fires when the user switches the active account - →
disconnect— fires when the user revokes the origin's permission - →
chainChanged— fires when the user switches between mainnet, devnet, and local chains. Carries the chain hash so dApps can verify they're still talking to the network they expect.
window.mneme.on('accountsChanged', (accounts) => {
if (accounts.length === 0) {
// User disconnected; reset dApp UI to logged-out state.
} else {
// Re-fetch state for the new active account.
}
})MetaMask compatibility
When EVM auth lands in v1 (the secp256k1 lane lands as a composable authenticator in the runtime), the Mneme connector keeps the same surface. The provider auto-routes ed25519 signing to Mneme and secp256k1 signing to MetaMask if both are installed. dApp code does not have to branch.
Permissions and revocation
Mneme tracks per-origin permissions. The user can review and revoke them from the extension settings. Revocation fires the disconnect event on every active page from that origin.
Permissions are scoped to the connect call. A site that asked only for connect cannot call submit without the user approving each transaction in the popup. There is no "approve everything for the next hour" mode in v0; that lands as session keys in v1 and is opt-in per origin.
Reference dApp
The Themisra reference dApp (@ligate/themisra-app) integrates the connector in ~30 lines and is the canonical example. Walkthrough lands in this page once the v0.5 build is published.