> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# useWalletDelegation

<Card title="Recommended: JavaScript SDK with React Hooks" icon="react" color="#4779FE">
  For new React apps, we recommend the JavaScript SDK with React Hooks (`@dynamic-labs-sdk/react-hooks`) instead of the legacy React SDK documented here. The JS SDK comes with many benefits such as a much smaller bundle size and other optimizations. Use the [React quickstart (JavaScript SDK)](/javascript/reference/react-quickstart) to get started.
</Card>

<Warning>
  Only available from v4.37.0 onwards.
</Warning>

### 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](/overview/wallets/embedded-wallets/mpc/delegated-access/overview).

The hook needs to be initialized within a child of [DynamicContextProvider](/react/reference/providers/dynamiccontextprovider).

### Return Value

The hook returns an object with the following properties:

```typescript theme={"system"}
{
  initDelegationProcess: (options?: { wallets?: Wallet[] }) => Promise<void>;
  shouldPromptWalletDelegation: () => boolean;
  getWalletsDelegatedStatus: () => { address: string; chain: string; status: WalletDelegationStatus }[];
  delegateKeyShares: (wallets?: { chainName: ChainEnum; accountAddress: string }[]) => Promise<void>;
  revokeDelegation: (wallets: { chainName: ChainEnum; accountAddress: string; status: WalletDelegationStatus }[]) => Promise<void>;
  denyWalletDelegation: () => void;
  dismissDelegationPrompt: () => void;
  clearDelegationSessionState: () => void;
  delegatedAccessEnabled: boolean | undefined;
  requiresDelegation: boolean | undefined;
}
```

### 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:**

```typescript theme={"system"}
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:**

```typescript theme={"system"}
const { shouldPromptWalletDelegation } = useWalletDelegation();

if (shouldPromptWalletDelegation()) {
  // Show custom UI or automatically trigger delegation
}
```

#### `getWalletsDelegatedStatus`

Returns the delegation status of all MPC wallets for the current user.

**Returns:** An array of objects containing:

* `address`: string - The wallet address
* `chain`: string - The chain the wallet is on
* `status`: WalletDelegationStatus - The delegation status ('delegated', 'pending', or 'not\_delegated')

**Example:**

```typescript theme={"system"}
const { getWalletsDelegatedStatus } = useWalletDelegation();

const walletStatuses = getWalletsDelegatedStatus();

walletStatuses.forEach((wallet) => {
  console.log(`${wallet.address} on ${wallet.chain}: ${wallet.status}`);
});

// Filter for delegated wallets
const delegatedWallets = walletStatuses.filter(
  (wallet) => wallet.status === 'delegated'
);
```

#### `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](/overview/wallets/embedded-wallets/mpc/delegated-access/overview)).

**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 on success. The function automatically refreshes user data after delegation completes.

**Errors:** Throws [`DelegationError`](#delegationerror) when one or more per-wallet delegations fail. The hook still attempts every wallet and still calls refresh — the error is thrown *after* the loop with the full set of successful and failed wallets attached, so callers can decide what to retry.

**Example:**

```typescript theme={"system"}
import { ChainEnum } from '@dynamic-labs/sdk-api-core';
import { DelegationError } from '@dynamic-labs/sdk-react-core';

const { delegateKeyShares } = useWalletDelegation();

try {
  await delegateKeyShares([
    {
      chainName: ChainEnum.Evm,
      accountAddress: '0x123...',
    },
  ]);
} catch (err) {
  if (err instanceof DelegationError) {
    console.log(
      `${err.failureCount} of ${err.successCount + err.failureCount} wallets failed`,
    );
    // err.successfulWallets / err.failedWallets are structured for retry logic
  }
}

// Delegate all pending wallets
await delegateKeyShares();
```

**Behavior:**

* Delegates wallets sequentially (one at a time)
* Continues iterating even if individual wallets fail
* Always refreshes user data after the loop (even on partial failure) so wallet state stays in sync
* Throws a single `DelegationError` at the end if any per-wallet delegation failed

#### `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](/react/wallets/embedded-wallets/mpc/delegated-access/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 on success. The function automatically refreshes user data after revocation completes.

**Errors:** Throws [`DelegationError`](#delegationerror) when one or more per-wallet revocations fail. The hook still attempts every wallet and still calls refresh — the error is thrown *after* the loop.

**Example:**

```typescript theme={"system"}
import { ChainEnum } from '@dynamic-labs/sdk-api-core';
import { DelegationError } from '@dynamic-labs/sdk-react-core';

const { revokeDelegation, getWalletsDelegatedStatus } = useWalletDelegation();

// Get delegated wallets and revoke them
const delegatedWallets = getWalletsDelegatedStatus().filter(
  (wallet) => wallet.status === 'delegated'
);

try {
  await revokeDelegation(
    delegatedWallets.map((wallet) => ({
      chainName: wallet.chain as ChainEnum,
      accountAddress: wallet.address,
      status: wallet.status,
    }))
  );
} catch (err) {
  if (err instanceof DelegationError) {
    // err.operation === 'revoke' here
    // Inspect err.failedWallets to decide what to retry
  }
}
```

**Behavior:**

* Revokes wallets sequentially (one at a time)
* Only attempts to revoke wallets with status 'delegated' (logs a warning and skips others)
* Continues iterating even if individual revocations fail
* Always refreshes user data after the loop (even on partial failure) so wallet state stays in sync
* Throws a single `DelegationError` at the end if any per-wallet revocation failed

#### `denyWalletDelegation`

Permanently denies wallet delegation for the current user. This sets a flag that prevents the delegation prompt from appearing again, even if the user has undelegated wallets.

**Returns:** `void`

**Example:**

```typescript theme={"system"}
const { denyWalletDelegation, shouldPromptWalletDelegation } = useWalletDelegation();

// User clicks "Don't ask again" button
const handleDenyDelegation = () => {
  denyWalletDelegation();
  // shouldPromptWalletDelegation() will now return false
};
```

#### `dismissDelegationPrompt`

Temporarily dismisses the delegation prompt for the current session. Unlike `denyWalletDelegation`, this does not permanently prevent the prompt from appearing - it will show again in future sessions.

**Returns:** `void`

**Example:**

```typescript theme={"system"}
const { dismissDelegationPrompt } = useWalletDelegation();

// User clicks "Maybe later" button
const handleDismiss = () => {
  dismissDelegationPrompt();
  // Prompt won't appear again this session
};
```

#### `clearDelegationSessionState`

Clears all delegation-related session state, including any "denied" or "dismissed" flags. This resets the delegation prompt behavior, allowing it to appear again based on the user's wallet status.

**Returns:** `void`

**Example:**

```typescript theme={"system"}
const { clearDelegationSessionState, shouldPromptWalletDelegation } = useWalletDelegation();

// Reset delegation state (e.g., when user wants to reconsider)
const handleResetDelegationState = () => {
  clearDelegationSessionState();
  // Delegation prompt can now appear again if conditions are met
  if (shouldPromptWalletDelegation()) {
    // Show delegation prompt
  }
};
```

### `DelegationError`

Thrown by `delegateKeyShares` and `revokeDelegation` when one or more per-wallet operations fail. Extends [`AggregateError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError), so callers reading the underlying causes via `.errors` keep working; structured fields make it easy to drive partial-failure UI without parsing the message.

**Fields:**

* `operation`: `'delegate' | 'revoke'` — which method threw.
* `successfulWallets`: `{ chainName: ChainEnum; accountAddress: string }[]` — wallets that completed before the error was thrown.
* `failedWallets`: `{ wallet: { chainName: ChainEnum; accountAddress: string }; cause: unknown }[]` — wallets that failed and their underlying causes.
* `successCount`: `number` — convenience getter.
* `failureCount`: `number` — convenience getter.
* `message`: `string` — `"Delegation failed for X of Y wallet(s): <first underlying cause>"` (or `"Revoke delegation failed for ..."` for revocations).

**Example — partial-failure retry:**

```typescript theme={"system"}
import { DelegationError } from '@dynamic-labs/sdk-react-core';

try {
  await delegateKeyShares(wallets);
} catch (err) {
  if (err instanceof DelegationError) {
    // Re-attempt only the wallets that failed
    const retryTargets = err.failedWallets.map((f) => f.wallet);
    await delegateKeyShares(retryTargets);
  } else {
    throw err;
  }
}
```

### Properties

#### `delegatedAccessEnabled`

A boolean value from your project settings that indicates whether delegated access is enabled for your application.

**Type:** `boolean | undefined`

**Example:**

```typescript theme={"system"}
const { delegatedAccessEnabled } = useWalletDelegation();

if (delegatedAccessEnabled) {
  // Delegated access feature is enabled
  // You can show delegation-related UI
}
```

#### `requiresDelegation`

A boolean value from your project settings that indicates whether wallet delegation is required for your application.

**Type:** `boolean | undefined`

**Example:**

```typescript theme={"system"}
const { requiresDelegation } = useWalletDelegation();

if (requiresDelegation) {
  // Delegation is mandatory for this application
  // You might want to block certain actions until delegation is complete
}
```

### Usage

```typescript theme={"system"}
import { useWalletDelegation } from '@dynamic-labs/sdk-react-core';

const MyComponent = () => {
  const { 
    initDelegationProcess, 
    shouldPromptWalletDelegation,
    getWalletsDelegatedStatus,
    denyWalletDelegation,
    dismissDelegationPrompt,
    delegatedAccessEnabled,
    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();
    }
  }, []);

  // Check delegation status of wallets
  const walletStatuses = getWalletsDelegatedStatus();
  const hasDelegatedWallets = walletStatuses.some(w => w.status === 'delegated');

  return (
    <div>
      {delegatedAccessEnabled && !hasDelegatedWallets && (
        <div>
          <p>Enable delegated access for a better experience</p>
          <button onClick={handleDelegateWallet}>Delegate Wallet</button>
          <button onClick={dismissDelegationPrompt}>Maybe Later</button>
          <button onClick={denyWalletDelegation}>Don't Ask Again</button>
        </div>
      )}
      {requiresDelegation && !hasDelegatedWallets && (
        <p>This app requires wallet delegation to function</p>
      )}
    </div>
  );
};
```

### Advanced Usage

Delegate specific wallets:

```typescript theme={"system"}
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

* [Delegated Access Documentation](/overview/wallets/embedded-wallets/mpc/delegated-access/overview)
* [MPC Embedded Wallets](/overview/wallets/embedded-wallets/mpc/overview)
* [DynamicContextProvider](/react/reference/providers/dynamiccontextprovider)
