Overview
Delegated signing lets your backend sign transactions on behalf of end users without requiring them to be online or have an active session. The end user grants a time-bound delegation from your frontend, and your server can then take actions on their account using only your CDP API key and Wallet Secret. This is useful for:- Automated transactions — Execute transactions triggered by webhooks or onchain events when the user is offline
- Agentic wallets — Allow a backend service or agent to operate a user’s wallet with scoped permissions
- Background operations — Process user-initiated flows that complete asynchronously after the user has left your app
How it works
Two parties are involved:- End user — Authenticates on your frontend and grants a time-bound delegation to your app
- Developer — Uses their CDP API key, CDP Wallet Secret, and the active delegation to sign transactions from the backend with no user interaction required
- Grant — The authenticated end user calls
createDelegationon the frontend, specifying an expiry time - Sign — Your backend uses the CDP SDK with your API key to perform actions on behalf of the user
- Revoke — The delegation can be revoked before expiry by the end user or the developer
Available delegated signing methods
With an active delegation, your backend can call the following methods viacdp.endUser.* on behalf of an end user:
EVM: Sign
| Method | Description |
|---|---|
signEvmTransaction({ userId, address, transaction }) | Sign an EVM transaction |
signEvmMessage({ userId, address, message }) | Sign an EIP-191 message |
signEvmTypedData({ userId, address, typedData }) | Sign EIP-712 typed data |
EVM: Send
| Method | Description |
|---|---|
sendEvmTransaction({ userId, address, transaction, network }) | Send a signed EVM transaction |
sendEvmAsset({ userId, address, to, amount, network }) | Send an EVM asset (e.g. USDC) |
sendUserOperation({ userId, address, network, calls }) | Send a smart account user operation |
createEvmEip7702Delegation({ userId, address, network }) | Create an EIP-7702 delegation |
Solana: Sign
| Method | Description |
|---|---|
signSolanaMessage({ userId, address, message }) | Sign a Solana message |
signSolanaTransaction({ userId, address, transaction }) | Sign a Solana transaction |
Solana: Send
| Method | Description |
|---|---|
sendSolanaTransaction({ userId, address, transaction, network }) | Send a signed Solana transaction |
sendSolanaAsset({ userId, address, to, amount, network }) | Send a Solana asset (e.g. USDC) |
Prerequisites
- In the CDP Portal, go to Embedded Wallets → Policies and enable the Delegated Signing toggle.

- Install the required packages:
@coinbase/cdp-hooks):
@coinbase/cdp-sdk):
.env file:
.env
Set
moduleResolution: "node16" or "nodenext" in your tsconfig.json to avoid compilation errors with the CDP SDK.Step 1: End user creates a delegation (React)
The authenticated end user grants your app a time-bound delegation. This is the only step that requires the user to be present.Only one active delegation is allowed per user at a time. If a delegation already exists, revoke it or let it expire before creating a new one.
React
Step 2: Developer signs on behalf of the end user (Node.js)
Once a delegation is active, your backend can submit transactions for the end user using your CDP API key and Wallet Secret — no user session needed.Node (TypeScript)
Step 3: Revoke a delegation
A delegation can be revoked before it expires — either by the end user from the frontend, or by the developer from the backend.End user revokes (React)
React
Developer revokes (Node.js)
Node (TypeScript)