Only available from v4.37.0 onwards.
Summary
The useWalletDelegation hook provides methods to trigger and manage the wallet delegation flow for Dynamic embedded wallets.
For more information on how wallet delegation works, see the delegated access documentation.
The hook needs to be initialized within a child of DynamicContextProvider.
Return Value
The hook returns an object with the following properties:
{
initDelegationProcess: (options?: { wallets?: Wallet[] }) => Promise<void>;
delegateKeyShares: (wallets?: { chainName: ChainEnum; accountAddress: string }[]) => Promise<void>;
revokeDelegation: (wallets: { chainName: ChainEnum; accountAddress: string; status: WalletDelegationStatus }[]) => Promise<void>;
requiresDelegation: boolean | undefined;
shouldPromptWalletDelegation: () => boolean;
}
Functions
initDelegationProcess
Initiates the wallet delegation flow by opening the Dynamic modal and displaying the delegation prompt to the user.
Parameters:
options (optional): Configuration object
wallets (optional): Array of specific wallets to delegate. If not provided, delegates all eligible MPC wallets.
Returns: Promise<void> - Resolves when delegation completes successfully, rejects on failure.
Errors:
- Throws
"No primary wallet" if the user doesn’t have a primary wallet connected
- Throws
"user_not_logged_in" if the user is not authenticated
Example:
const { initDelegationProcess } = useWalletDelegation();
try {
await initDelegationProcess();
console.log('Delegation completed successfully');
} catch (error) {
console.error('Delegation failed:', error);
}
shouldPromptWalletDelegation
Determines whether the user should be prompted for wallet delegation based on:
- Delegated access settings in project configuration
- User’s previous delegation decisions (denied or completed)
- Existence of undelegated MPC wallets
Returns: boolean - true if the user should see the delegation prompt, false otherwise.
Example:
const { shouldPromptWalletDelegation } = useWalletDelegation();
if (shouldPromptWalletDelegation()) {
// Show custom UI or automatically trigger delegation
}
delegateKeyShares
Delegates key shares for one or more wallets. This allows your application to act on behalf of the user’s wallet (see Delegated Access).
Parameters:
wallets (optional): Array of wallet objects to delegate. Each wallet object should have:
chainName: ChainEnum - The chain the wallet is associated with
accountAddress: string - The address of the wallet to delegate
If wallets is not provided or is empty, the function will delegate all pending wallets eligible for delegation.
Returns: Promise resolving to void. The function automatically refreshes user data after delegation completes.
Example:
import { ChainEnum } from '@dynamic-labs/sdk-api-core';
const { delegateKeyShares } = useWalletDelegation();
// Delegate a specific wallet
await delegateKeyShares([
{
chainName: ChainEnum.Evm,
accountAddress: '0x123...',
},
]);
// Delegate all pending wallets
await delegateKeyShares();
Behavior:
- Delegates wallets sequentially (one at a time)
- If a wallet connector is not found for a chain, it skips that wallet and continues
- Automatically refreshes user data after all delegations complete
revokeDelegation
Revokes delegation for one or more wallets. This removes your application’s ability to act on behalf of the user’s wallet (see Revoking Delegation).
Parameters:
wallets: Array of wallet objects to revoke. Each wallet object should have:
chainName: ChainEnum - The chain the wallet is associated with
accountAddress: string - The address of the wallet to revoke
status: WalletDelegationStatus - The delegation status of the wallet (must be ‘delegated’ for revocation to proceed)
Returns: Promise resolving to void. The function automatically refreshes user data after revocation completes.
Example:
import { ChainEnum } from '@dynamic-labs/sdk-api-core';
const { revokeDelegation, getWalletsDelegatedStatus } = useWalletDelegation();
// Get delegated wallets and revoke them
const delegatedWallets = getWalletsDelegatedStatus().filter(
(wallet) => wallet.status === 'delegated'
);
await revokeDelegation(
delegatedWallets.map((wallet) => ({
chainName: wallet.chain as ChainEnum,
accountAddress: wallet.address,
status: wallet.status,
}))
);
Behavior:
- Revokes wallets sequentially (one at a time)
- Only attempts to revoke wallets with status ‘delegated’ (logs a warning and skips others)
- If a wallet connector is not found for a chain, it skips that wallet and continues
- If revocation fails for a wallet, it logs an error but continues with other wallets
- Automatically refreshes user data after all revocations complete
Properties
requiresDelegation
A boolean value from your project settings that indicates whether wallet delegation is required for your application.
Type: boolean | undefined
Example:
const { requiresDelegation } = useWalletDelegation();
if (requiresDelegation) {
// Delegation is mandatory for this application
// You might want to block certain actions until delegation is complete
}
Usage
import { useWalletDelegation } from '@dynamic-labs/sdk-react-core';
const MyComponent = () => {
const {
initDelegationProcess,
shouldPromptWalletDelegation,
requiresDelegation
} = useWalletDelegation();
const handleDelegateWallet = async () => {
try {
await initDelegationProcess();
console.log('Wallet delegation successful!');
} catch (error) {
console.error('Failed to delegate wallet:', error);
}
};
// Automatically prompt on mount if needed
useEffect(() => {
if (shouldPromptWalletDelegation()) {
initDelegationProcess();
}
}, []);
return (
<div>
{requiresDelegation && (
<p>This app requires wallet delegation to function</p>
)}
<button onClick={handleDelegateWallet}>
Delegate Wallet Access
</button>
</div>
);
};
Advanced Usage
Delegate specific wallets:
import { useWalletDelegation } from '@dynamic-labs/sdk-react-core';
import { useUserWallets } from '@dynamic-labs/sdk-react-core';
const MyComponent = () => {
const { initDelegationProcess } = useWalletDelegation();
const { userWallets } = useUserWallets();
const delegateSpecificWallet = async (walletId: string) => {
const wallet = userWallets.find(w => w.id === walletId);
if (wallet) {
try {
await initDelegationProcess({ wallets: [wallet] });
console.log('Specific wallet delegated successfully');
} catch (error) {
console.error('Delegation failed:', error);
}
}
};
return (
<div>
{userWallets.map(wallet => (
<button
key={wallet.id}
onClick={() => delegateSpecificWallet(wallet.id)}
>
Delegate {wallet.address}
</button>
))}
</div>
);
};
Important Notes
- The user must be authenticated and have a primary wallet for delegation to work
- The delegation modal is part of the Dynamic UI and handles all user interactions
- User delegation preferences are persisted across sessions using local storage
Learn More