|
| 1 | +--- |
| 2 | +title: "gasLimitOverride" |
| 3 | +description: "Override gas limits for individual calls in a wallet_sendCalls batch" |
| 4 | +--- |
| 5 | + |
| 6 | +Defined in [ERC-8132](https://github.com/ethereum/ERCs/pull/1485) |
| 7 | + |
| 8 | +<Info> |
| 9 | +The gasLimitOverride capability allows apps to specify gas limits for individual calls within a `wallet_sendCalls` batch. Gas limits can be partially specified — you can provide overrides for only the calls you have context about, and the wallet estimates gas for the rest. Apps often have more context about the gas requirements of their own contract calls than the wallet, making app-provided gas limits more accurate. |
| 10 | +</Info> |
| 11 | + |
| 12 | +## Parameters |
| 13 | + |
| 14 | +This is a **call-level capability**, meaning it is specified on individual calls within a `wallet_sendCalls` batch rather than at the top level. |
| 15 | + |
| 16 | +<ParamField body="value" type="`0x${string}`" required> |
| 17 | +Hex-encoded gas limit for the call. Must be a non-zero value that does not exceed the block gas limit of the target chain. |
| 18 | +</ParamField> |
| 19 | + |
| 20 | +## Returns |
| 21 | + |
| 22 | +<ResponseField name="gasLimitOverride" type="object"> |
| 23 | +The gasLimitOverride capability configuration. |
| 24 | + |
| 25 | +<Expandable title="gasLimitOverride capability properties"> |
| 26 | +<ResponseField name="supported" type="boolean"> |
| 27 | +Indicates whether the wallet supports app-provided gas limit overrides. Reported for all chains (`0x0`) when supported. |
| 28 | +</ResponseField> |
| 29 | +</Expandable> |
| 30 | +</ResponseField> |
| 31 | + |
| 32 | +## Example usage |
| 33 | + |
| 34 | +<RequestExample> |
| 35 | +```typescript Check gasLimitOverride support |
| 36 | +const capabilities = await provider.request({ |
| 37 | + method: 'wallet_getCapabilities', |
| 38 | + params: [userAddress] |
| 39 | +}); |
| 40 | + |
| 41 | +const gasLimitOverrideSupport = capabilities["0x0"]?.gasLimitOverride; |
| 42 | +``` |
| 43 | + |
| 44 | +```typescript Send calls with a gas limit override |
| 45 | +const result = await provider.request({ |
| 46 | + method: "wallet_sendCalls", |
| 47 | + params: [{ |
| 48 | + version: "1.0", |
| 49 | + chainId: "0x2105", |
| 50 | + from: userAddress, |
| 51 | + atomicRequired: true, |
| 52 | + calls: [ |
| 53 | + { |
| 54 | + // Approval — no override, wallet estimates gas |
| 55 | + to: tokenAddress, |
| 56 | + value: "0x0", |
| 57 | + data: approveCallData |
| 58 | + }, |
| 59 | + { |
| 60 | + // Swap — app provides a known gas limit |
| 61 | + to: swapContractAddress, |
| 62 | + value: "0x0", |
| 63 | + data: swapCallData, |
| 64 | + capabilities: { |
| 65 | + gasLimitOverride: { |
| 66 | + value: "0x30D40" // 200,000 gas |
| 67 | + } |
| 68 | + } |
| 69 | + } |
| 70 | + ] |
| 71 | + }] |
| 72 | +}); |
| 73 | +``` |
| 74 | +</RequestExample> |
| 75 | + |
| 76 | +<ResponseExample> |
| 77 | +```json Capability response (supported) |
| 78 | +{ |
| 79 | + "0x0": { |
| 80 | + "gasLimitOverride": { |
| 81 | + "supported": true |
| 82 | + } |
| 83 | + } |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +```json Capability response (unsupported) |
| 88 | +{ |
| 89 | + "0x0": { |
| 90 | + "gasLimitOverride": { |
| 91 | + "supported": false |
| 92 | + } |
| 93 | + } |
| 94 | +} |
| 95 | +``` |
| 96 | +</ResponseExample> |
| 97 | + |
| 98 | +## Error handling |
| 99 | + |
| 100 | +| Code | Message | Description | |
| 101 | +| ------ | -------------------- | --------------------------------------------------------------------------- | |
| 102 | +| -32602 | Invalid params | Gas limit is zero or exceeds the block gas limit of the target chain | |
| 103 | +| 5700 | Capability required | Call includes gasLimitOverride but wallet doesn't support it | |
| 104 | + |
| 105 | +## How it works |
| 106 | + |
| 107 | +When a wallet receives calls with `gasLimitOverride` capabilities: |
| 108 | + |
| 109 | +1. The wallet uses the app-provided gas limit for that call's portion of the batch gas limit. |
| 110 | +2. For calls **without** a `gasLimitOverride`, the wallet estimates gas as usual. |
| 111 | +3. The wallet may add additional gas to account for batch processing overhead (such as smart account execution or EIP-7702 delegation). |
| 112 | + |
| 113 | +This is a call-level capability, so you can specify gas limits for only some calls in a batch. The wallet handles estimation for the rest. |
| 114 | + |
| 115 | +## Use cases |
| 116 | + |
| 117 | +### Nondeterministic gas usage |
| 118 | + |
| 119 | +Some contract calls have nondeterministic gas costs that are difficult for wallets to estimate accurately. Apps with deep knowledge of their contracts can provide better gas limits: |
| 120 | + |
| 121 | +```typescript |
| 122 | +// A complex DeFi operation where gas usage depends on pool state |
| 123 | +const result = await provider.request({ |
| 124 | + method: "wallet_sendCalls", |
| 125 | + params: [{ |
| 126 | + version: "1.0", |
| 127 | + chainId: "0x2105", |
| 128 | + from: userAddress, |
| 129 | + atomicRequired: true, |
| 130 | + calls: [ |
| 131 | + { |
| 132 | + to: routerAddress, |
| 133 | + value: "0x0", |
| 134 | + data: swapCallData, |
| 135 | + capabilities: { |
| 136 | + gasLimitOverride: { |
| 137 | + value: "0x7A120" // 500,000 gas — app knows the swap is complex |
| 138 | + } |
| 139 | + } |
| 140 | + } |
| 141 | + ] |
| 142 | + }] |
| 143 | +}); |
| 144 | +``` |
| 145 | + |
| 146 | +### Partial gas limit specification |
| 147 | + |
| 148 | +You can specify gas limits for only the calls you have context about and let the wallet estimate the rest: |
| 149 | + |
| 150 | +```typescript |
| 151 | +const result = await provider.request({ |
| 152 | + method: "wallet_sendCalls", |
| 153 | + params: [{ |
| 154 | + version: "1.0", |
| 155 | + chainId: "0x2105", |
| 156 | + from: userAddress, |
| 157 | + atomicRequired: true, |
| 158 | + calls: [ |
| 159 | + { |
| 160 | + // Approval — let the wallet estimate gas |
| 161 | + to: tokenAddress, |
| 162 | + value: "0x0", |
| 163 | + data: approveCallData |
| 164 | + }, |
| 165 | + { |
| 166 | + // Swap — app provides a known gas limit |
| 167 | + to: swapContractAddress, |
| 168 | + value: "0x0", |
| 169 | + data: swapCallData, |
| 170 | + capabilities: { |
| 171 | + gasLimitOverride: { |
| 172 | + value: "0x30D40" // 200,000 gas |
| 173 | + } |
| 174 | + } |
| 175 | + } |
| 176 | + ] |
| 177 | + }] |
| 178 | +}); |
| 179 | +``` |
| 180 | + |
| 181 | +## Best practices |
| 182 | + |
| 183 | +1. **Check capabilities first**: Verify `gasLimitOverride` support via `wallet_getCapabilities` before including it in calls |
| 184 | +2. **Use `optional: true` for compatibility**: Mark the capability as optional if your app can function without it, so wallets that don't support it can still process the batch |
| 185 | +3. **Provide accurate limits**: Use gas limits based on your contract's actual requirements — overly tight limits cause reverts, overly generous limits waste block space |
| 186 | +4. **Let the wallet handle overhead**: Only specify gas for the call itself. The wallet accounts for batch processing overhead separately |
| 187 | + |
| 188 | +<Warning> |
| 189 | +The wallet returns an invalid params error (`-32602`) if a provided gas limit is zero or exceeds the block gas limit of the target chain. |
| 190 | +</Warning> |
| 191 | + |
| 192 | +## Related capabilities |
| 193 | + |
| 194 | +- [atomic](/base-account/reference/core/capabilities/atomic) - Use with atomic batch transactions |
| 195 | +- [paymasterService](/base-account/reference/core/capabilities/paymasterService) - Combine with sponsored transactions |
| 196 | + |
| 197 | +import PolicyBanner from "/snippets/PolicyBanner.mdx"; |
| 198 | + |
| 199 | +<PolicyBanner /> |
0 commit comments