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

wallet_grantPermissions

Grant granular permissions to a spender address for delegated transaction execution with spending limits and call restrictions.

Authentication Required: Yes

Request

await jaw.provider.request({
  method: 'wallet_grantPermissions',
  params: [{
    expiry: 1735689600, // Unix timestamp
    spender: '0x5678...', // Who gets permissions
    permissions: {
      calls: [{
        target: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        functionSignature: 'transfer(address,uint256)',
      }],
      spends: [{
        token: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
        allowance: '0x16345785d8a0000', // 0.1 ETH
        unit: 'day',
      }],
    },
    // chainId: '0x1', // Optional - defaults to connected chain
  }],
});

Parameters

NameTypeRequiredDescription
expirynumberYesExpiration timestamp (seconds)
spender0x${string}YesAddress receiving permissions
permissionsobjectYesPermission details
chainId0x${string}NoTarget chain ID (defaults to connected chain)

Permission Details

calls

Array of call permissions. Each permission:

NameTypeRequiredDescription
target0x${string}YesContract address
functionSignaturestringNo*Function signature (e.g., "transfer(address,uint256)")
selector0x${string}No*4-byte function selector (0x...)

*Either functionSignature or selector is required.

spends (Optional*)

Array of spend limits. Each limit:

NameTypeRequiredDescription
token0x${string}YesToken address (0xEeee... for native token)
allowance0x${string}YesSpending allowance in wei (hex)
unitstringYesTime unit for allowance reset
multipliernumberNoMultiplier for the time unit (default: 1)
Valid Units:
  • minute - Resets every minute
  • hour - Resets every hour
  • day - Resets every day
  • week - Resets every week
  • month - Resets every month
  • year - Resets every year
  • forever - Never resets (one-time allowance)

*Spend Limits are required if moving funds.

Response

Returns permission grant result with generated permission ID.

{
  "account": "0x1234567890123456789012345678901234567890",
  "spender": "0x5678901234567890123456789012345678901234",
  "start": 1704067200,
  "end": 1735689600,
  "salt": "0x1a2b3c...",
  "calls": [{
    "target": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "selector": "0xa9059cbb"
  }],
  "spends": [{
    "token": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
    "allowance": "0x16345785d8a0000",
    "unit": "day",
    "multiplier": 1
  }],
  "permissionId": "0xabc123...",
  "chainId": "0x1"
}

Behavior

  • Opens popup for user approval
  • Approves permission
  • Returns permission ID for future revocation

Errors

CodeDescription
4001User rejected the request
4100Unauthorized (not authenticated)
-32602Invalid params

Example

// Allow DeFi protocol to swap USDC with daily limit
const permission = await jaw.provider.request({
  method: 'wallet_grantPermissions',
  params: [{
    expiry: Math.floor(Date.now() / 1000) + (365 * 24 * 60 * 60), // 1 year
    spender: dexRouterAddress,
    permissions: {
      calls: [{
        target: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        functionSignature: 'approve(address,uint256)',
      }, {
        target: dexRouterAddress,
        functionSignature: 'swap(address,address,uint256,uint256)',
      }],
      spends: [{
        token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        allowance: '0x' + (1000n * 10n**6n).toString(16),
        unit: 'day',
      }],
    },
    // chainId: '0x1', // Optional - defaults to connected chain
  }],
});

Related Methods