Appearance
Prompting for consent to delegated actions
INFO
Users must consent to delegated actions directly from their device. In kind, delegation is handled via Privy's React SDK which runs on the user's device, in their browser.
To allow users to consent to delegated actions, please first follow this guide to integrate @privy-io/react-auth
into your app's frontend.
Prior to taking delegated actions with users' wallets, Privy requires that your app prompt users for consent to these actions.
Neither Privy nor your app can take any actions beyond what the user consents to.
Granting consent
To prompt users to grant consent for delegated actions, first check that the wallet has not already granted delegated permissions to your app following this guide.
Then, for wallets that have not already been delegated, prompt users to grant consent for delegated actions. 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.address && 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>
);
}
Getting user consent again
After a user has granted your app delegated actions, they are able to revoke consent. This will prevent your app from taking any further wallet actions on the user's behalf.
Consent can by revoked in the following scenarios:
- Your user revokes consent via the revocation interface that you surface in your app
- You delete or rotate your authorization keypair
- You modify the permissions your app requests, such as request additional permissions
Highly recommended. You can check if your user has revoked consent to delegated actions as follows: 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.