Core Concepts
WalletPair has three specifications that work together. The relay routes public metadata and opaque frames; the encryption protocol authenticates and protects each frame; the Ethereum protocol defines the EIP-1193 messages inside those frames.
Pairing URI and trust boundary
The dApp creates a random 32-byte channel ID and fresh X25519 key pair, then displays a QR URI
with exactly six fields: ch, pubkey, relay, name, url, and icon. Values are percent-encoded with RFC 3986 rules. The dApp
uses the same channel ID, public key, and metadata when it connects to the relay.
The wallet obtains the dApp public key from the QR code and calculates a four-digit pairing code
from the channel ID, dApp metadata, and key. After the user compares the code, the wallet pins the
dApp key. The dApp deliberately has no matching wallet-identity guarantee: it uses the first
eligible non-self channel_joined participant and ignores later participants.
Key schedule
Each peer derives an X25519 shared secret, rejects an all-zero result, then uses HKDF-SHA256 with the channel ID and transcript hash. This produces independent dApp-to-wallet and wallet-to-dApp ChaCha20-Poly1305 keys. Shared secrets and root keys are erased after use.
Encrypted frames
Every application frame is a MessagePack value from the JSON data model, bounded to 64 KiB and 64 nesting levels. The on-wire text frame is:
base64url(uint32_be(sequence) || ciphertext_tag)@caip-2-chain-id The suffix (for example eip155:1) is visible to the relay but included in AEAD
additional data. A receiver accepts only strictly increasing sequences; gaps are allowed, while
replays and out-of-order frames are rejected after authentication succeeds.
Relay transport
A peer connects to GET /v1 over WebSocket with five query fields: ch, name, url, icon, and pubkey.
The relay broadcasts a channel_joined JSON event to active channel members and forwards
all later text or binary application frames unchanged to the other members.
EVM application messages
The current application specification uses EIP-1193 envelopes. A request has id and method; a response has id and exactly one of result or error; an event has event and data. These are not JSON-RPC
2.0 envelopes and never include a jsonrpc field.
Read the complete Ethereum protocol before handling signing or transaction requests.