> ## Documentation Index
> Fetch the complete documentation index at: https://base-a060aa97-docs-use-case-ia-overhaul.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Spend Permissions

> Enable trusted spenders to move assets without additional signatures

export const GithubRepoCard = ({title, githubUrl}) => {
  return <a href={githubUrl} target="_blank" rel="noopener noreferrer" className="mb-4 flex items-center rounded-lg bg-zinc-900 p-4 text-white transition-all hover:bg-zinc-800">
      <div className="flex w-full items-center gap-3">
        <svg height="24" width="24" className="flex-shrink-0 dark:fill-white" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
          <path fill="currentColor" fillRule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" />
        </svg>

        <div className="flex min-w-0 flex-grow flex-col">
          <span className="truncate text-base font-medium">{title}</span>
          <span className="truncate text-xs text-zinc-400">{githubUrl}</span>
        </div>

        <svg className="h-5 w-5 flex-shrink-0 text-zinc-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
        </svg>
      </div>
    </a>;
};

Learn how to create and manage Spend Permissions that allow trusted spenders to move assets from Base Accounts without requiring additional user signatures.

## Overview

Spend Permissions enable users to grant timely allowances to trusted spenders, allowing them to move assets on behalf of the user within defined limits. This creates seamless user experiences for recurring payments, subscriptions, and automated transactions.

### What you'll achieve

By the end of this guide, you will:

* Create Spend Permissions with specific allowances and time periods
* Fetch and manage existing Spend Permissions
* Use Spend Permissions to execute transactions
* Implement Spend Permission functionality in your React application

The code snippets in this guide are based on the following example project:

<GithubRepoCard title="Base Account Privy Template" githubUrl="https://github.com/base/base-account-privy" />

## Setup

Follow the [Setup](/sdks/base-account/framework-integrations/privy/setup) guide to set up Privy with Base Account.

## Implementation

### Component Setup

<CodeGroup>
  ```tsx Spend Permissions Component (components/sections/spend-permissions.tsx) expandable theme={null}
  "use client";

  import { useState, useEffect, useCallback, useMemo } from "react";
  import { useBaseAccountSdk, useWallets } from "@privy-io/react-auth";
  import {
    requestSpendPermission,
    prepareSpendCallData,
    fetchPermissions,
    getPermissionStatus,
    type SpendPermission,
  } from "@base-org/account/spend-permission/browser";
  import { base } from "@privy-io/chains";

  export const SpendPermissions = () => {
    const { baseAccountSdk } = useBaseAccountSdk();
    const { wallets } = useWallets();
    const [permissions, setPermissions] = useState<SpendPermission[]>([]);
    const [selectedPermission, setSelectedPermission] = useState<SpendPermission | null>(null);
    const [loading, setLoading] = useState(false);
    
    // Configuration
    const spenderAddress = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045";
    const tokenAddress = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"; // USDC on Base

    // Find the Base Account wallet
    const baseAccount = useMemo(() => {
      return wallets.find((wallet) => wallet.walletClientType === 'base_account');
    }, [wallets]);

    const provider = baseAccountSdk?.getProvider();
    const account = baseAccount?.address;

    const loadPermissions = useCallback(async () => {
      if (!account || !provider || !spenderAddress) return;
      
      try {
        setLoading(true);
        const fetchedPermissions = await fetchPermissions({
          account,
          chainId: base.id,
          spender: spenderAddress,
          provider,
        });
        setPermissions(fetchedPermissions);
      } catch (error) {
        console.error("Failed to load permissions:", error);
      } finally {
        setLoading(false);
      }
    }, [account, provider, spenderAddress]);

    const handleRequestSpendPermission = async () => {
      if (!account || !provider || !spenderAddress || !tokenAddress) return;

      try {
        setLoading(true);
        
        const permission = await requestSpendPermission({
          account,
          spender: spenderAddress,
          token: tokenAddress,
          chainId: base.id,
          allowance: BigInt(1) * BigInt(10 ** 6), // 1 USDC (6 decimals)
          periodInDays: 1, // 1 day
          provider,
        });

        setPermissions([...permissions, permission]);
      } catch (error) {
        console.error("Failed to create Spend Permission:", error);
      } finally {
        setLoading(false);
      }
    };

    const handleUseSpendPermission = async () => {
      if (!selectedPermission || !provider || !spenderAddress) return;

      try {
        setLoading(true);
        
        // Check permission status
        const { isActive, remainingSpend } = await getPermissionStatus(selectedPermission);
        
        if (!isActive) {
          console.error("Selected permission is not active");
          return;
        }

        const spendAmount = BigInt(100) * BigInt(10 ** 6); // 100 USDC
        
        if (remainingSpend < spendAmount) {
          console.error("Insufficient remaining allowance");
          return;
        }

        // Prepare spend calls
        const spendCalls = await prepareSpendCallData(selectedPermission, spendAmount);
        console.log("Spend calls prepared:", spendCalls);
        
      } catch (error) {
        console.error("Failed to use Spend Permission:", error);
      } finally {
        setLoading(false);
      }
    };

    return (
      <div className="space-y-4">
        <div className="flex gap-4">
          <button 
            onClick={handleRequestSpendPermission}
            disabled={loading || !account}
            className="px-4 py-2 bg-blue-600 text-white rounded disabled:opacity-50"
          >
            Create Spend Permission
          </button>
          <button 
            onClick={loadPermissions}
            disabled={loading || !account}
            className="px-4 py-2 bg-green-600 text-white rounded disabled:opacity-50"
          >
            Load Permissions
          </button>
          <button 
            onClick={handleUseSpendPermission}
            disabled={loading || !selectedPermission}
            className="px-4 py-2 bg-purple-600 text-white rounded disabled:opacity-50"
          >
            Use Permission
          </button>
        </div>

        {/* Configuration display */}
        <div className="p-4 rounded-lg">
          <h4 className="font-semibold mb-3">Configuration</h4>
          <div className="text-sm space-y-1">
            <div><strong>Spender:</strong> {spenderAddress}</div>
            <div><strong>Token:</strong> {tokenAddress} (USDC)</div>
            <div><strong>Allowance:</strong> $1 USDC per day</div>
          </div>
        </div>

        {/* Permissions list */}
        {permissions.length > 0 && (
          <div className="p-4 rounded-lg">
            <h4 className="font-semibold mb-3">Existing Permissions</h4>
            <div className="space-y-2">
              {permissions.map((permission, index) => (
                <div
                  key={index}
                  className={`p-3 border rounded-md cursor-pointer ${
                    selectedPermission === permission
                      ? "border-blue-500"
                      : "border-gray-300"
                  }`}
                  onClick={() => setSelectedPermission(permission)}
                >
                  <div className="text-sm">
                    <div><strong>Spender:</strong> {permission.permission.spender?.slice(0, 10)}...</div>
                    <div><strong>Token:</strong> {permission.permission.token?.slice(0, 10)}...</div>
                    <div><strong>Allowance:</strong> {permission.permission.allowance?.toString()}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    );
  };
  ```
</CodeGroup>

### Key Methods

#### Creating Spend Permissions

Use `requestSpendPermission` to create new Spend Permissions:

```tsx theme={null}
const permission = await requestSpendPermission({
  account,
  spender: spenderAddress,
  token: tokenAddress,
  chainId: base.id,
  allowance: BigInt(1) * BigInt(10 ** 6), // 1 USDC
  periodInDays: 1, // 1 day
  provider,
});
```

#### Fetching Permissions

Use `fetchPermissions` to retrieve existing permissions:

```tsx theme={null}
const permissions = await fetchPermissions({
  account,
  chainId: base.id,
  spender: spenderAddress,
  provider,
});
```

#### Using Permissions

Check permission status and prepare spend calls:

```tsx theme={null}
// Check if permission is active
const { isActive, remainingSpend } = await getPermissionStatus(permission);

// Prepare spend transaction data
const spendCalls = await prepareSpendCallData(permission, spendAmount);
```

### Configuration Options

#### Allowance and Period

Configure spending limits and time periods:

```tsx theme={null}
{
  allowance: BigInt(100) * BigInt(10 ** 6), // 100 USDC (6 decimals)
  periodInDays: 7, // 7 days
}
```

#### Token Addresses

Common token addresses on Base:

* **USDC**: `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`
* **ETH**: Native token `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`
* **DAI**: `0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb`

### Use Cases

Spend permissions are ideal for:

* **Subscriptions**: Recurring payments without user interaction
* **DeFi protocols**: Automated trading and yield farming
* **Gaming**: In-game purchases and rewards
* **Commerce**: Streamlined checkout experiences

<GithubRepoCard title="Base Account Privy Template" githubUrl="https://github.com/base/base-account-privy" />
