Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

account.grantPermissions()

Grant permissions to a spender.

Type: instance async

Signature

async grantPermissions(
  expiry: number,
  spender: Address,
  permissions: PermissionsDetail,
  paymasterUrlOverride?: string,
  paymasterContextOverride?: Record<string, unknown>
): Promise<WalletGrantPermissionsResponse>

Parameters

expiry

Type: number

Unix timestamp (in seconds) when the permission expires.

spender

Type: Address

The address that can use this permission to execute calls on behalf of the account.

permissions

Type: PermissionsDetail

The permissions to grant.

interface PermissionsDetail {
  /** Call permissions - which contracts and functions can be called */
  calls?: CallPermissionDetail[];
  /** Spend permissions - token spending limits */
  spends?: SpendPermissionDetail[];
}
 
interface CallPermissionDetail {
  /** Target contract address */
  target: Address;
  /** Function selector (4 bytes) - computed from functionSignature if not provided */
  selector?: Hex;
  /** Human-readable function signature (e.g., "transfer(address,uint256)") */
  functionSignature?: string;
}
 
interface SpendPermissionDetail {
  /** Token address (use 0xEee...EEeE for native ETH) */
  token: Address;
  /** Spending allowance in wei (hex format) */
  allowance: string;
  /** Period unit of the spend limit */
  unit: 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year' | 'forever';
  /** Multiplier for the period (1-255), defaults to 1 */
  multiplier?: number;
}

paymasterUrlOverride (optional)

Type: string

Custom paymaster URL for gas sponsorship or ERC-20 token payment. Overrides the paymaster URL configured in AccountConfig.

paymasterContextOverride (optional)

Type: Record<string, unknown>

Custom paymaster context. For ERC-20 payment, include the token address:

{ token: '0xUSDC_ADDRESS...' }

Returns

Promise<WalletGrantPermissionsResponse> - The granted permission details.

interface WalletGrantPermissionsResponse {
  /** Smart account this permission is valid for */
  account: Address;
  /** Entity that can use this permission */
  spender: Address;
  /** Timestamp (in seconds) that specifies when this permission becomes valid */
  start: number;
  /** Timestamp (in seconds) that specifies the time by which this permission expires */
  end: number;
  /** Salt used for permission uniqueness (as hex string) */
  salt: Hex;
  /** Array of call permissions */
  calls: CallPermissionDetail[];
  /** Array of spend permissions */
  spends: SpendPermissionDetail[];
  /** Permission identifier - the permission hash from the contract */
  permissionId: Hex;
  /** Chain ID in hex format */
  chainId: Hex;
}

Behavior

  1. Creates a permission with the specified constraints
  2. Signs the permission with the smart account
  3. Registers the permission with the JAW relay
  4. Returns the permission details including the unique ID

Example

// Grant both call and spend permissions
const permission = await account.grantPermissions(
  Math.floor(Date.now() / 1000) + 86400 * 7, // 1 week
  '0xSpenderAddress...',
  {
    calls: [
      {
        target: ROUTER_ADDRESS,
        selector: '0x38ed1739', // swapExactTokensForTokens
      },
      {
        target: ROUTER_ADDRESS,
        selector: '0x7ff36ab5', // swapExactETHForTokens
      }
    ],
    spends: [
      {
        token: USDC_ADDRESS,
        limit: '1000000000', // 1000 USDC
        period: 'week',
      }
    ],
  }
);
 
console.log('Permission ID:', permission.permissionId);
console.log('Expires:', new Date(permission.end * 1000));

Use Cases

  • Session keys - Allow a temporary key to perform specific actions
  • Subscription services - Grant recurring spending permissions
  • Automated trading - Allow a bot to execute specific trades
  • Gaming - Let a game contract execute moves without prompts

Related