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

# Embedded wallet delegated access

> Let your app sign for a user's embedded wallet without prompting each time — and let users revoke it.

## Prerequisites

Before this page: have an embedded wallet (see [Post-login user setup](/docs/javascript/building-ui/post-auth-user-setup)) and, if your project uses one, its [password](/docs/javascript/building-ui/embedded-wallet-security).

## What you'll build

Delegated access lets your backend sign for a user's embedded wallet without a prompt every time — useful for automations, scheduled actions, or server-side flows the user has opted into. You'll build:

* **Status** — show whether delegated access is on.
* **Grant** — turn it on, with the user's explicit consent.
* **Revoke** — let the user turn it off at any time.

## Showing delegation status

`hasDelegatedAccess` is a synchronous check for whether the wallet currently has delegated access.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={"system"}
    import { hasDelegatedAccess } from '@dynamic-labs-sdk/client/waas';
    import type { WalletAccount } from '@dynamic-labs-sdk/client';

    function renderDelegationStatus(walletAccount: WalletAccount, el: HTMLElement) {
      el.textContent = hasDelegatedAccess({ walletAccount })
        ? 'Delegated access is on'
        : 'Delegated access is off';
    }
    ```
  </Tab>

  <Tab title="React">
    ```tsx theme={"system"}
    import { hasDelegatedAccess } from '@dynamic-labs-sdk/client/waas';
    import type { WalletAccount } from '@dynamic-labs-sdk/client';

    function DelegationStatus({ walletAccount }: { walletAccount: WalletAccount }) {
      const isDelegated = hasDelegatedAccess({ walletAccount });
      return <span>{isDelegated ? 'Delegated access is on' : 'Delegated access is off'}</span>;
    }
    ```
  </Tab>
</Tabs>

## Granting delegated access

Only grant after clear, explicit consent — you're letting your backend act on the user's behalf. Pass the wallet `password` when your project protects wallets with one.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={"system"}
    import { delegateWaasKeyShares } from '@dynamic-labs-sdk/client/waas';
    import type { WalletAccount } from '@dynamic-labs-sdk/client';

    async function grant(walletAccount: WalletAccount, password?: string) {
      await delegateWaasKeyShares({ password, walletAccount });
      // showGranted is your implementation.
      showGranted();
    }
    ```
  </Tab>

  <Tab title="React">
    ```tsx theme={"system"}
    import type { WalletAccount } from '@dynamic-labs-sdk/client';
    import { useDelegateWaasKeyShares } from '@dynamic-labs-sdk/react-hooks';

    function GrantAccess({
      walletAccount,
      password,
    }: {
      walletAccount: WalletAccount;
      password?: string;
    }) {
      const { mutateAsync: delegate, isPending } = useDelegateWaasKeyShares();

      return (
        <button
          type="button"
          disabled={isPending}
          // Pass password when your project protects wallets with one.
          onClick={() => delegate({ password, walletAccount })}
        >
          {isPending ? 'Enabling…' : 'Enable delegated access'}
        </button>
      );
    }
    ```
  </Tab>
</Tabs>

<Warning>
  Delegated access means your backend can sign without the user present. Explain exactly what it enables, keep it opt-in, and make revoking easy.
</Warning>

## Revoking delegated access

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={"system"}
    import { revokeWaasDelegation } from '@dynamic-labs-sdk/client/waas';
    import type { WalletAccount } from '@dynamic-labs-sdk/client';

    async function revoke(walletAccount: WalletAccount, password?: string) {
      await revokeWaasDelegation({ password, walletAccount });
      // showRevoked is your implementation.
      showRevoked();
    }
    ```
  </Tab>

  <Tab title="React">
    ```tsx theme={"system"}
    import type { WalletAccount } from '@dynamic-labs-sdk/client';
    import { useRevokeWaasDelegation } from '@dynamic-labs-sdk/react-hooks';

    function RevokeAccess({
      walletAccount,
      password,
    }: {
      walletAccount: WalletAccount;
      password?: string;
    }) {
      const { mutateAsync: revoke, isPending } = useRevokeWaasDelegation();

      return (
        <button
          type="button"
          disabled={isPending}
          // Pass password when your project protects wallets with one.
          onClick={() => revoke({ password, walletAccount })}
        >
          {isPending ? 'Revoking…' : 'Revoke delegated access'}
        </button>
      );
    }
    ```
  </Tab>
</Tabs>

## Handling errors

| Situation                           | What to do                                                                       |
| ----------------------------------- | -------------------------------------------------------------------------------- |
| `hasDelegatedAccess` already `true` | Show the revoke action instead of grant.                                         |
| Wrong password on grant/revoke      | Ask the user to re-enter the wallet password; nothing changes.                   |
| Grant rejected by the user          | Leave delegated access off and don't proceed with the automation that needed it. |

## See also

* [Embedded wallet password & security](/docs/javascript/building-ui/embedded-wallet-security) — the password some grant/revoke operations require
* [Transaction confirmation & simulation](/docs/javascript/building-ui/transaction-confirmation) — how signing works when the user is present
* [Post-login user setup](/docs/javascript/building-ui/post-auth-user-setup) — where the embedded wallet is created
