Skip to content

Commit 713c379

Browse files
pedrocrvzclaude
andauthored
feat: add getBalance action (#35)
* feat: add getBalance action across relayer, account, and bundler Add gelato_getBalance RPC support to query Gas Tank balance from all three client types. Includes tests, fixtures, examples, and README docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: changeset --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0d3865e commit 713c379

20 files changed

Lines changed: 262 additions & 4 deletions

File tree

.changeset/config.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
"account-sponsored-payment",
1313
"account-ws",
1414
"relayer-ws",
15-
"bundler-ws"
15+
"bundler-ws",
16+
"relayer-get-balance",
17+
"bundler-get-balance"
1618
],
1719
"linked": [],
1820
"updateInternalDependencies": "patch"

.changeset/wicked-sloths-count.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@gelatocloud/gasless": patch
3+
---
4+
5+
feat: gas tank balance action

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,15 @@ await relayer.ws.unsubscribe(subscription.subscriptionId);
251251
relayer.ws.disconnect();
252252
```
253253

254+
### Get Balance
255+
256+
Check your Gas Tank balance. Available on all client types.
257+
258+
```typescript
259+
const { balance, decimals, unit } = await relayer.getBalance();
260+
// Also: client.getBalance(), bundler.getBalance()
261+
```
262+
254263
## Sync vs Async
255264

256265
The SDK offers two ways to send transactions:
@@ -307,6 +316,7 @@ const client = createGelatoEvmRelayerClient({
307316
| `sendTransactionSync` | `{ chainId, to, data, timeout?, pollingInterval?, throwOnReverted?, ... }` | `Promise<TransactionReceipt>` | Send and wait for receipt |
308317
| `getStatus` | `{ id: string }` | `Promise<Status>` | Get transaction status |
309318
| `waitForReceipt` | `{ id: string, timeout?, pollingInterval?, throwOnReverted? }` | `Promise<TransactionReceipt>` | Wait for receipt, throws on failure |
319+
| `getBalance` | - | `Promise<Balance>` | Get Gas Tank balance |
310320
| `getCapabilities` | - | `Promise<Capabilities>` | Get supported chains |
311321
| `getFeeData` | `{ chainId, gas, l1Fee? }` | `Promise<FeeData>` | Get network fee data |
312322

@@ -344,6 +354,7 @@ const client = await createGelatoSmartAccountClient({
344354
| `sendTransactionSync` | `{ calls, nonce?, nonceKey?, timeout?, pollingInterval?, throwOnReverted?, ... }` | `Promise<TransactionReceipt>` | Send and wait for receipt |
345355
| `getStatus` | `{ id: string }` | `Promise<Status>` | Get transaction status |
346356
| `waitForReceipt` | `{ id: string, timeout?, pollingInterval?, throwOnReverted? }` | `Promise<TransactionReceipt>` | Wait for receipt, throws on failure |
357+
| `getBalance` | - | `Promise<Balance>` | Get Gas Tank balance |
347358
| `getCapabilities` | - | `Promise<Capabilities>` | Get supported chains |
348359

349360
**Nonce Options:**
@@ -397,6 +408,7 @@ const bundler = await createGelatoBundlerClient({
397408
| `sendUserOperation` | `{ calls }` | `Promise<Hex>` | Send a user operation |
398409
| `sendUserOperationSync` | `{ calls, timeout?, pollingInterval? }` | `Promise<UserOperationReceipt>` | Send and wait for receipt |
399410
| `waitForUserOperationReceipt` | `{ hash }` | `Promise<{ receipt }>` | Wait for receipt |
411+
| `getBalance` | - | `Promise<Balance>` | Get Gas Tank balance |
400412
| `estimateUserOperationGas` | `UserOperationParams` | `Promise<GasEstimate>` | Estimate gas |
401413
| `prepareUserOperation` | `UserOperationParams` | `Promise<UserOperation>` | Prepare operation |
402414
| `getUserOperationGasPrice` | - | `Promise<GasPrice>` | Get current gas prices |
@@ -622,8 +634,10 @@ const receipt = await relayer.sendTransactionSync({
622634
See the [`/examples`](./examples) directory for complete working examples:
623635

624636
- [`examples/relayer/sponsored`](./examples/relayer/sponsored) - Direct relayer usage
637+
- [`examples/relayer/get-balance`](./examples/relayer/get-balance) - Get Gas Tank balance
625638
- [`examples/account/sponsored`](./examples/account/sponsored) - Gelato smart account
626639
- [`examples/bundler/sponsored`](./examples/bundler/sponsored) - ERC-4337 bundler
640+
- [`examples/bundler/get-balance`](./examples/bundler/get-balance) - Get Gas Tank balance (bundler)
627641
- [`examples/relayer/ws`](./examples/relayer/ws) - Relayer WebSocket usage
628642
- [`examples/bundler/ws`](./examples/bundler/ws) - Bundler WebSocket usage
629643
- [`examples/account/ws`](./examples/account/ws) - Account WebSocket usage
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
GELATO_API_KEY="Get your api key at https://app.gelato.cloud/"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "bundler-get-balance",
3+
"private": true,
4+
"version": "0.0.1",
5+
"scripts": {
6+
"dev": "tsx src/index.ts"
7+
},
8+
"dependencies": {
9+
"@gelatocloud/gasless": "workspace:*",
10+
"viem": "catalog:"
11+
},
12+
"devDependencies": {
13+
"@types/node": "latest",
14+
"dotenv": "^17.2.3",
15+
"tsx": "^4.21.0",
16+
"typescript": "catalog:"
17+
}
18+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { resolve } from 'node:path';
2+
import { config } from 'dotenv';
3+
4+
// Load root .env first (defaults)
5+
config({ path: resolve(__dirname, '../../../../.env'), quiet: true });
6+
7+
// Load local .env to override (optional)
8+
config({ override: true, quiet: true });
9+
10+
import { createGelatoBundlerClient, toGelatoSmartAccount } from '@gelatocloud/gasless';
11+
import { createPublicClient, type Hex, http } from 'viem';
12+
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
13+
import { baseSepolia } from 'viem/chains';
14+
15+
const GELATO_API_KEY = process.env['GELATO_API_KEY'];
16+
const PRIVATE_KEY = process.env['PRIVATE_KEY'];
17+
18+
if (!GELATO_API_KEY) {
19+
throw new Error('GELATO_API_KEY is not set');
20+
}
21+
22+
const chain = baseSepolia;
23+
24+
const main = async () => {
25+
const owner = privateKeyToAccount((PRIVATE_KEY ?? generatePrivateKey()) as Hex);
26+
27+
const client = createPublicClient({
28+
chain,
29+
transport: http()
30+
});
31+
32+
const account = toGelatoSmartAccount({
33+
client,
34+
owner
35+
});
36+
37+
const bundler = await createGelatoBundlerClient({
38+
account,
39+
apiKey: GELATO_API_KEY,
40+
client,
41+
sponsored: true
42+
});
43+
44+
const { balance, decimals, unit } = await bundler.getBalance();
45+
46+
console.log(`Balance: ${balance} (${decimals} decimals, ${unit})`);
47+
48+
process.exit(0);
49+
};
50+
51+
main().catch((error) => {
52+
console.error(error);
53+
process.exit(1);
54+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "../../../tsconfig.json"
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
GELATO_API_KEY="Get your api key at https://app.gelato.cloud/"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "relayer-get-balance",
3+
"private": true,
4+
"version": "0.0.1",
5+
"scripts": {
6+
"dev": "tsx src/index.ts"
7+
},
8+
"dependencies": {
9+
"@gelatocloud/gasless": "workspace:*"
10+
},
11+
"devDependencies": {
12+
"@types/node": "latest",
13+
"dotenv": "^17.2.3",
14+
"tsx": "^4.21.0",
15+
"typescript": "catalog:"
16+
}
17+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { resolve } from 'node:path';
2+
import { config } from 'dotenv';
3+
4+
// Load root .env first (defaults)
5+
config({ path: resolve(__dirname, '../../../../.env'), quiet: true });
6+
7+
// Load local .env to override (optional)
8+
config({ override: true, quiet: true });
9+
10+
import { createGelatoEvmRelayerClient } from '@gelatocloud/gasless';
11+
12+
const GELATO_API_KEY = process.env['GELATO_API_KEY'];
13+
14+
if (!GELATO_API_KEY) {
15+
throw new Error('GELATO_API_KEY is not set');
16+
}
17+
18+
const main = async () => {
19+
const relayer = createGelatoEvmRelayerClient({ apiKey: GELATO_API_KEY });
20+
21+
const { balance, decimals, unit } = await relayer.getBalance();
22+
23+
console.log(`Balance: ${balance} (${decimals} decimals, ${unit})`);
24+
};
25+
26+
main().catch((error) => {
27+
console.error(error);
28+
process.exit(1);
29+
});

0 commit comments

Comments
 (0)