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:

Code
// Step 1: Register
POST /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/login returns a JWT token pair. Best for user-facing applications.
  • API key, Created via POST /api-keys and passed in the x-api-key header. 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:

Code
// Read profile
GET /wallets/me
→ { "id": "w_abc", "email": "alice@example.com", "name": "Alice", "avatar": "https://..." }
// Update profile
PATCH /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_id changes from one wallet to another.
  • Actions, Every action is signed by the wallet that initiates it, creating a cryptographic audit trail.