This guide covers the full implementation of delegated wallets: registering end users, creating wallets they control, and letting them perform actions with their passkeys.Documentation Index
Fetch the complete documentation index at: https://docs.dfns.co/llms.txt
Use this file to discover all available pages before exploring further.
Setup: service account client
All backend operations use your service account. Set up the client once. It’s used for registration, login, and wallet creation.Step 1: Register and log in end users
Registration (new users)
Use the Delegated Registration flow. Your service account creates the user, your frontend collects the passkey.Create a registration challenge
Authenticate the user with your own system first, then call Create Delegated Registration Challenge.
User creates a passkey (frontend)
Send the challenge to your frontend. The browser prompts the user to create a passkey.
Frontend
Complete registration
Send the attestation back to your backend. Use Complete User Registration with the
temporaryAuthenticationToken from step 1 as the auth token.Login (returning users)
Use Delegated Login. Authenticate the user with your system first, then get their Dfns auth token with a single call.token is the end user’s auth token. You’ll need it for step 3.
Step 2: Create delegated wallets
We recommend creating wallets after registration rather than during it. This gives you more control over when and which networks to provision. Two approaches:By your service account
Your service account creates a wallet and delegates it to a user via thedelegateTo field on Create Wallet. This is the simplest approach. The service account’s signer handles action signing automatically.
By the end user
The end user can also create their own wallets using the delegated client. This follows the Init/Complete pattern. The user must sign with their passkey.delegateTo field needed.
Step 3: Delegated actions
Once a user is logged in, they can perform actions on their wallets (transfers, signatures, etc.). These write operations require the user to sign with their passkey.The delegated client
UseDfnsDelegatedApiClient (TypeScript) or DfnsDelegatedClient (Python) with the end user’s auth token. Unlike the service account client, this client does not have a signer. Signing happens on the user’s device.
The Init / Complete pattern
Every write method on the delegated client is split into two calls:methodInit(): sends the request payload to Dfns, returns a challengemethodComplete(): sends the same payload + the user’s signed challenge, executes the action
This pattern applies to all write operations:
transferAssetInit/Complete, generateSignatureInit/Complete, createWalletInit/Complete, etc. See the signing flows reference for details including direct API calls without the SDK.
Alternative: social registration
Instead of delegated registration, users can authenticate directly with an identity provider (like Google). No service account is needed.Security considerations
- Never expose your service account credentials to the frontend
- Validate tokens on your backend before creating Dfns users
- Store the mapping between your user IDs and Dfns user IDs securely
- Implement rate limiting on registration endpoints
Recovery is not optional
Delegated wallets put signing authority on the user’s device. If they lose that device and have no recovery credential, the wallet is permanently inaccessible. Dfns cannot restore it for them. Before going to production, build the recovery flow:- Register a
recoveryCredentialat signup, in the sameComplete User Registrationcall as the first passkey (see the registration step above). - Prompt users to add a second passkey on a different device shortly after onboarding.
- Generate a fresh recovery credential whenever a user completes recovery, since a successful recovery invalidates all previous credentials.
Next steps
Configure WebAuthn
Configure passkeys for your domain
Signing flows
Full Init/Complete signing reference
Registration flows
API reference for user registration
