Skip to main content
Version: Testnet (v5.0.0-rc.1)

Wallet SDK

The @aztec/wallet-sdk package defines how dApps and wallet extensions communicate on Aztec. It handles wallet discovery, establishes encrypted channels via ECDH key exchange, and provides a capability-based permission system — analogous to EIP-1193 and MetaMask's provider on Ethereum, but with built-in encryption and visual verification.

This section covers both sides of the integration:

  1. dApp Integration — Discover wallets, establish secure channels, request capabilities, and use the wallet
  2. Wallet Extension Integration — Handle discovery requests, manage sessions, route messages, and extend BaseWallet

Features

FeatureDescription
Wallet discoverydApps broadcast via window.postMessage, wallet extensions respond after user approval
ECDH key exchangeP-256 ephemeral key pairs derive a shared secret for each session
AES-256-GCM encryptionAll wallet method calls and responses are encrypted after key exchange
Emoji verificationA 9-emoji grid (72-bit security) lets users visually confirm there's no man-in-the-middle
Capability permissionsdApps declare what they need (AppCapabilities), wallets grant or deny each capability
Trusted origin reconnectPreviously approved origins auto-reconnect without re-verification
BaseWalletAbstract class that wallet extensions extend — provides sendTx, simulateTx, batch, and more

Architecture

┌──────────────┐ window.postMessage ┌──────────────────────────────┐
│ │ ←─────────────────────────────→ │ Content Script │
│ dApp │ (discovery only) │ ContentScriptConnectionHandler
│ │ └──────────┬───────────────────┘
│ WalletManager│ MessagePort (encrypted) │ chrome.runtime
│ ExtensionWallet ←────────────────────────────→ ┌──────────▼───────────────────┐
│ │ │ Background Service Worker │
└──────────────┘ │ BackgroundConnectionHandler │
└──────────┬───────────────────┘
│ persistent port
┌──────────▼───────────────────┐
│ Offscreen Document │
│ OffscreenWallet (BaseWallet) │
│ PXE + WASM proofs │
└──────────────────────────────┘

Discovery uses window.postMessage (unencrypted, public). After the user approves, a MessagePort is transferred and ECDH key exchange establishes an encrypted channel. All subsequent wallet method calls flow through this encrypted MessagePort.

Package Exports

The SDK is split into focused entry points:

Import pathWhat it provides
@aztec/wallet-sdk/managerWalletManager, WalletProvider, PendingConnection, DiscoverySession — dApp-side discovery and connection
@aztec/wallet-sdk/cryptohashToEmoji — convert verification hash to emoji string
@aztec/wallet-sdk/extension/handlersBackgroundConnectionHandler, ContentScriptConnectionHandler — wallet extension handlers
@aztec/wallet-sdk/extension/providerExtensionWallet, ExtensionProvider — low-level provider classes
@aztec/wallet-sdk/base-walletBaseWallet — abstract wallet class that extensions subclass

Security Model

The protocol has three phases with increasing trust:

  1. Discovery (public) — The dApp broadcasts a request. Wallet extensions only respond after the user explicitly approves the connection in the extension popup. No cryptographic material is exchanged.

  2. Key exchange (authenticated) — Both sides generate ephemeral ECDH P-256 key pairs. The shared secret is expanded via HKDF into an AES-256-GCM encryption key and an HMAC verification key. A 2-second timeout limits the window for interception.

  3. Verified channel (encrypted) — The HMAC verification key produces a hash that both sides independently convert to a 9-emoji grid. The user visually confirms the emojis match on both the dApp and wallet extension, defending against man-in-the-middle attacks. After confirmation, all messages are encrypted with AES-256-GCM.

Next steps

Related Tutorials

The Wallet Extension Tutorial walks through building a complete Chrome extension wallet step by step, covering service workers, offscreen documents, encrypted storage, and approval flows.