Wallets
The primary identity primitive for authentication and asset ownership on the Dual network.
What are Wallets?
Wallets are the identity layer in Dual. Every user, application, or service account is represented by a wallet. Wallets serve three purposes: they authenticate API requests, they own objects, and they hold membership in organizations.
Under the hood, each wallet is backed by a cryptographic key pair used for EIP-712 typed data signatures. This means every state-changing action a wallet takes is cryptographically signed, providing a tamper-proof audit trail without requiring on-chain transactions for every operation.
Registration & Verification
The standard registration flow is a two-step process:
// Step 1: RegisterPOST /wallets/register{"email": "alice@example.com","password": "secure-password"}// Step 2: Verify (with token from email)POST /wallets/register/verify{ "token": "verification-token-from-email" }
Both steps return a TokenPair containing an access_token (JWT) and a refresh_token. The access token is short-lived; refresh it with POST /wallets/token/refresh before it expires.
Authentication Modes
Once registered, there are two ways to authenticate:
- Email + password login,
POST /wallets/loginreturns a JWT token pair. Best for user-facing applications. - API key, Created via
POST /api-keysand passed in thex-api-keyheader. Best for server-to-server integrations and CI/CD pipelines.
See Authentication for header format details.
Guest Login
For applications that need anonymous or ephemeral access, POST /wallets/login/guest creates a temporary wallet session without requiring registration. Guest wallets can be upgraded to full wallets later by linking credentials.
Wallet Profile
Every wallet has a profile you can read and update:
// Read profileGET /wallets/me→ { "id": "w_abc", "email": "alice@example.com", "name": "Alice", "avatar": "https://..." }// Update profilePATCH /wallets/me{ "name": "Alice Smith", "avatar": "https://cdn.example.com/alice.jpg" }
The meta field is a freeform JSON object you can use to store application-specific data, preferences, onboarding state, feature flags, etc.
Linked Wallets
Users can link multiple wallets together, enabling cross-identity asset management. This is useful when:
- A user has multiple email addresses and wants a unified view of their objects.
- An application needs to associate an external wallet (e.g. MetaMask) with a Dual wallet.
- A service account needs to act on behalf of a user wallet.
Link wallets with POST /wallets/link and query linked wallets with GET /wallets/me/linked or GET /wallets/{id}/linked.
Password Reset
The password reset flow is also two-step: request a reset code with POST /wallets/reset-code, then verify the code and set a new password with POST /wallets/reset-code/verify.
Wallet Deletion
A wallet can be permanently deleted with DELETE /wallets/me. This is irreversible, all objects owned by the wallet become orphaned. Transfer ownership of important objects before deletion.
Relationship to Other Concepts
- Organizations, A wallet can be a member of many organizations with different roles in each.
- Objects, Wallets own objects. When an action transfers an object, the
owner_idchanges from one wallet to another. - Actions, Every action is signed by the wallet that initiates it, creating a cryptographic audit trail.