Appearance
Delegating wallets
Privy enables your app to request permission to take certain embedded wallet actions on behalf of users, without needing the user to be in the loop. This is known as delegated actions. Neither Privy nor your app can take any actions beyond what the user consents to.
Privy makes it easy to prompt your user for delegation consent or build your own UIs for delegation. Follow the guide below to delegate user's wallets, enabling your app to securely interact with these wallets from your servers.
INFO
Prior to integrating delegated actions, learn more about the feature and make sure to configure your app to enable delegated actions in the Dashboard.
Enabling automated wallet controls
You can either prompt users to delegate their wallets via a consent screen (with UIs) or automatically(substituting Privy UIs with your own). Make sure to follow the appropriate guide below.
Before delegating a wallet, first check that the wallet has not already been delegated.
To prompt users to delegate their wallets with a consent screen, use the delegateWallet
method from the useDelegatedActions
hook:
tsx
import {useDelegatedActions} from '@privy-io/react-auth';
...
const {delegateWallet} = useDelegatedActions();
As a parameter to this method, pass an object with the following fields:
Field | Type | Description |
---|---|---|
address | string | Address of the embedded wallet to delegate. |
chainType | 'ethereum' | 'solana' | Chain type of the embedded wallet to delegate. |
When invoked, the delegateWallet
method will open a Privy modal where the user can either approve or reject the delegation.
If the user approves, Privy will initiate the process to enable delegated actions for the wallet. If the user refuses or there is another error during delegation, this method will throw an error.
As an example, you might have a button within your app to prompt delegation like so:
tsx
import {
usePrivy,
useSolanaWallets,
useDelegatedActions,
type WalletWithMetadata,
} from '@privy-io/react-auth';
function DelegateActionButton() {
const {user} = usePrivy();
const {ready, wallets} = useSolanaWallets(); // or useWallets()
const {delegateWallet} = useDelegatedActions();
// Find the embedded wallet to delegate from the array of the user's wallets
const walletToDelegate = wallets.find((wallet) => wallet.walletClientType === 'privy');
// Check if the wallet to delegate by inspecting the user's linked accounts
const isAlreadyDelegated = !!user.linkedAccounts.find(
(account): account is WalletWithMetadata => account.type === 'wallet' && account.delegated,
);
const onDelegate = async () => {
if (!walletToDelegate || !ready) return; // Button is disabled to prevent this case
await delegateWallet({address: walletToDelegate.address, chainType: 'solana'}); // or chainType: 'ethereum'
};
return (
<button disabled={!ready || !walletToDelegate || isAlreadyDelegated} onClick={onDelegate}>
Delegate access
</button>
);
}
Reprompting
If you rotate your authorization key or the user revokes consent, you will need to re-delegate users' wallets.
Highly recommended. We recommend you wrap your code in a guard that detects if the user should be prompted with the consent flow. For example, you can get the user's delegated wallets and automatically reprompt if no wallets are delegated.