Send Wallet
Send is a passkey-based Canton wallet that exposes the splice-wallet-kernel OpenRPC contract via window.canton. The dApp connection layer is open-sourced as Sigilry; this PartyLayer adapter wraps that contract with the same surface every other Canton wallet uses.
How Send Differs
Installation
Send is delivered as a browser extension. Direct your users to the Send wallet homepage at sigilry.org for current installation instructions before they can connect.
With PartyLayerKit auto-discovery there is no further wiring — Send appears in the wallet picker automatically. If you build a custom adapter set, register SendAdapter alongside the others:
getBuiltinAdapters(). The example above is only meaningful if you previously passed a manually-curated adapter list.Connection Flow
End-to-end user experience:
- User clicks Connect with Send.
- Send extension shows its Connect to Site? permission prompt.
- On approval, the OS surfaces a passkey prompt (Touch ID / Face ID).
- Once unlocked, the SDK receives a session containing
partyId,kernelId, and the wallet's public key.
signMessage, submitTransaction) prompts a fresh passkey unlock — this is by design. Send does not cache passkey approval across calls.Reading the Ledger
Send proxies the Canton v2 JSON Ledger API through Sigilry's ledgerApi RPC method. Use useLedgerApi for any read-side query:
For active-contracts queries with eventFormat, see the Wallet Balances guide — Send accepts the same request shape as the other ledger-API-capable adapters.
Token Standard Transfers (CIP-56)
Send signs and submits transactions in a single step via prepareExecuteAndWait. The wallet handles Scan-side coordination, choice context lookup, and passkey signing internally. Adapter consumers call submitTransaction with a JsPrepareSubmissionRequest:
See Token Transfers for the full CIP-56 flow including the Scan /registry/transfer-instruction/v1/transfer-factory endpoint and the choice-context tagged-union shape.
Amulet_Transfer exercise on Splice.Amulet:Amulet throws an actionable error pointing at this page.Capability Matrix
- connect — supported (Sigilry
connectRPC +getPrimaryAccount) - disconnect — supported
- restore — supported (silent
statusprobe; no popup on reload) - signMessage — supported (passkey-signed)
- signTransaction — not supported; fused into
prepareExecute. Calling it throwsCapabilityNotSupportedErrorpointing atsubmitTransaction. - submitTransaction — supported via
prepareExecuteAndWait; receipt populated fromtx.payload.updateId. - ledgerApi — supported (full Sigilry passthrough; matches Console / Nightly).
- events — supported;
txChangedbridged to PartyLayertx:status. - injected — supported via
window.cantonwith kernel.id guard.
Network Support
This adapter integrates with Send on canton:mainnet.
localhost:3000 defaults its network label to devnet. That label reflects the demo's configuration — not the actual network the connected wallet sits on. Send's adapter reads the live network from window.canton.getActiveNetwork() and reports canton:mainnet when Send is active. dApps that ship to production should configure PartyLayerKit with network="mainnet" when targeting Send.Troubleshooting
- "Send not detected" — the extension is missing, or
window.canton.kernel.iddoesn't match Send. The adapter intentionally refuses to claim foreign providers (e.g. another splice-wallet-kernel-compatible extension); install Send and reload. - "Connection cancelled" — the user dismissed the passkey prompt or the extension popup. Triggering connect again is safe.
- "Authentication Failed: Cannot reach authentication server" — Send's backend at
auth.cantonwallet.comis unreachable. Check network and retry. - "OAuth state mismatch" — stale Send session. Clear cookies for
cantonwallet.comand reconnect. - Transaction errors with hint "Execute Unknown on Unknown" — legacy
Amulet_Transferexercise onSplice.Amulet:Amulet. Migrate to CIP-56TransferFactory_Transfer; see Token Transfers.
Security Notes
- Private keys never leave the extension. Passkey signing happens on the user's device through WebAuthn-PRF; PartyLayer never touches the underlying key material.
- Session JWT is held by the extension. The adapter receives an access token in
status.session.accessTokenfor the lifetime of the connection; PartyLayer's session-persistence layer encrypts state at rest in the dApp's configured storage. - Registry-driven detection guard. Every Send adapter call verifies the live
window.cantonprovider against the registry'sproviderDetectionrules before forwarding. If a different splice-wallet-kernel-compatible extension grabs the global, Send adapter cleanly returns not installed and yields to the matching adapter rather than acting on a foreign provider.