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
| Name | Type | Required | Description |
|---|---|---|---|
expiry | number | Yes | Expiration timestamp (seconds) |
spender | 0x${string} | Yes | Address receiving permissions |
permissions | object | Yes | Permission details |
chainId | 0x${string} | No | Target chain ID (defaults to connected chain) |
Permission Details
calls
Array of call permissions. Each permission:
| Name | Type | Required | Description |
|---|---|---|---|
target | 0x${string} | Yes | Contract address |
functionSignature | string | No* | Function signature (e.g., "transfer(address,uint256)") |
selector | 0x${string} | No* | 4-byte function selector (0x...) |
*Either functionSignature or selector is required.
spends (Optional*)
Array of spend limits. Each limit:
| Name | Type | Required | Description |
|---|---|---|---|
token | 0x${string} | Yes | Token address (0xEeee... for native token) |
allowance | 0x${string} | Yes | Spending allowance in wei (hex) |
unit | string | Yes | Time unit for allowance reset |
multiplier | number | No | Multiplier for the time unit (default: 1) |
minute- Resets every minutehour- Resets every hourday- Resets every dayweek- Resets every weekmonth- Resets every monthyear- Resets every yearforever- 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
| Code | Description |
|---|---|
| 4001 | User rejected the request |
| 4100 | Unauthorized (not authenticated) |
| -32602 | Invalid 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
- wallet_revokePermissions - Revoke permissions
- wallet_getPermissions - Query permissions