Derived, not stored
The key is deterministically derived from a wallet signature over a fixed message:Optional second seed
The wallet signature can be strengthened with a second seed, so deriving the key takes something you have (the wallet) plus something you know or are:- None (the default today) — the wallet signature alone derives the key
- Password — stretched with Argon2id, so a human passphrase can’t be brute-forced even by someone holding the wallet signature
- Passkey — via the WebAuthn PRF extension: a deterministic secret gated by your device’s biometrics (fingerprint / Face ID) and synced by the platform (Google Password Manager, iCloud Keychain)

The derivation signature in the wallet — note the message text and the key index
key #NNNN counter is the rotation index: revoking a key advances
it, so the replacement key is genuinely different (the message changes, so
the wallet signature changes, so the key changes).
Registration flow
For Stellar wallets, the Soroban leg is submitted by the wallet itself (a normal Soroban transaction underrequire_auth) instead of being
relayed; the EVM leg is still relayed and gas-sponsored.
Registered on both chains
Registration writes the key’s commitment to theBLSKeyRegistry on
both chains, because a trade settles on both. The registration:
- carries a proof of possession — a BLS signature proving you hold the private key you’re registering (prevents rogue-key registrations)
- is authorized by the wallet’s own signature (EIP-712 or SEP-53 depending on the wallet/chain pairing)
- is relayed and gas-sponsored by the relayer — the user just signs. Anyone can self-relay the same registration on-chain instead.
Per wallet, not per user
The contracts checkkeyOf(adCreator) and keyOf(bridger) — the two
deposit wallets of the trade. They have no notion of a “user” with linked
wallets. If you make markets from a Stellar wallet and bridge from an EVM
wallet, each registers its own key (a one-time step per wallet).
Rotation and revocation
- Rotate by registering a new key over the old one — in-flight trades block a rotation until they settle.
- Revoke kills the key on both chains. Revocation is refused while you have open trades (the contracts enforce this), and a revoked wallet can register again — the next key derives at the next rotation index.