You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| Tx hash on (re)submission | Not exposed |`hash` field on every `submitted` event |
263
+
| Control | Minimal — fire and forget | Full — react to each status change via WS subscription |
264
+
265
+
**Sync** — call `sendTransactionSync` to send the transaction and get the receipt in the same call. If the transaction is not included, the SDK will handle it internally and return a final `TransactionReceipt` by racing http polls and ws updates. Simplest approach when you just need the result:
266
+
267
+
```typescript
268
+
const receipt =awaitrelayer.sendTransactionSync({ chainId, to, data });
269
+
```
270
+
271
+
**Async** — call `sendTransaction` to get a ID immediately, then subscribe via WebSocket for granular status updates. **WS subscriptions give you full control over the transaction lifecycle** — you can react to resubmissions, display tx hashes to users in real time, handle rejections immediately, and more. The `submitted` event includes the transaction `hash` each time the relay (re)submits the transaction (e.g. with bumped gas):
272
+
273
+
```typescript
274
+
const id =awaitrelayer.sendTransaction({ chainId, to, data });
275
+
const subscription =awaitrelayer.ws.subscribe({ id });
276
+
277
+
subscription.on('submitted', (data) => {
278
+
console.log(`Tx hash: ${data.hash}`); // available on every (re)submission
279
+
});
280
+
281
+
subscription.on('success', (data) => {
282
+
console.log(`Confirmed in block ${data.receipt.blockNumber}`);
|`sendTransaction`|`{ chainId, to, data, authorizationList?, context? }`|`Promise<Hex>`| Submit a transaction |
214
-
|`sendTransactionSync`|`{ chainId, to, data, timeout?, pollingInterval?, ... }`|`Promise<TransactionReceipt>`| Send and wait for receipt |
306
+
|`sendTransactionSync`|`{ chainId, to, data, timeout?, pollingInterval?, throwOnReverted?, ... }`|`Promise<TransactionReceipt>`| Send and wait for receipt |
215
307
|`getStatus`|`{ id: string }`|`Promise<Status>`| Get transaction status |
216
-
|`waitForStatus`|`{ id: string, timeout?, pollingInterval? }`|`Promise<TerminalStatus>`| Wait for final status |
217
-
|`waitForReceipt`|`{ id: string, timeout?, pollingInterval? }`|`Promise<TransactionReceipt>`| Wait for receipt, throws on failure |
308
+
|`waitForReceipt`|`{ id: string, timeout?, pollingInterval?, throwOnReverted? }`|`Promise<TransactionReceipt>`| Wait for receipt, throws on failure |
218
309
|`getCapabilities`| - |`Promise<Capabilities>`| Get supported chains |
219
310
|`getFeeData`|`{ chainId, gas, l1Fee? }`|`Promise<FeeData>`| Get network fee data |
All synchronous methods (`sendTransactionSync`, `sendUserOperationSync`, `waitForStatus`, `waitForReceipt`) support customizable polling behavior:
354
+
All synchronous methods (`sendTransactionSync`, `sendUserOperationSync`, `waitForReceipt`) support customizable polling behavior:
265
355
266
356
-`timeout` (optional): Maximum wait time in milliseconds
267
357
- Default: `120000` (2 minutes)
@@ -370,9 +460,7 @@ type Call = {
370
460
## Status Handling
371
461
372
462
```typescript
373
-
import { StatusCode } from'@gelatocloud/gasless';
374
-
375
-
const status =awaitclient.waitForStatus({ id: hash });
463
+
const status =awaitclient.getStatus({ id: hash });
376
464
377
465
switch (status.status) {
378
466
caseStatusCode.Success:
@@ -391,7 +479,7 @@ switch (status.status) {
391
479
392
480
### Timeout Errors
393
481
394
-
Synchronous methods (`sendTransactionSync`, `waitForStatus`, `waitForReceipt`) throw `TimeoutError` when operations don't complete within the configured timeout:
482
+
Synchronous methods (`sendTransactionSync`, `waitForReceipt`) throw `TimeoutError` when operations don't complete within the configured timeout:
When `sendTransactionSync`times out, it automatically falls back to polling for the transaction status. If you see a warning message like:
507
+
By default, `sendTransactionSync`and `waitForReceipt` return the receipt even when a transaction reverts on-chain. Set `throwOnReverted: true` to throw a `TransactionRevertedError` instead:
420
508
421
-
```
422
-
Transaction 0x... sync call timed out, falling back to polling for completion. DO NOT RETRY this transaction.
// Also available: error.id, error.chainId, error.createdAt
525
+
}
526
+
}
423
527
```
424
528
425
-
This means your transaction was successfully submitted but the sync method timed out. The SDK will continue polling for completion automatically. **Do not retry the operation** as this could result in duplicate transactions.
529
+
Available on both relayer and account clients via `sendTransactionSync` and `waitForReceipt`. Properties on `TransactionRevertedError`: `receipt`, `id`, `chainId`, `createdAt`, `errorData`, `errorMessage`.
426
530
427
-
### Recovery Strategies
531
+
### Simulation Errors
428
532
429
-
If a timeout occurs:
430
-
1.**Wait for automatic fallback**: `sendTransactionSync` automatically polls after timeout
431
-
2.**Check status manually**: Use `getStatus({ id })` to check if transaction is still processing
432
-
3.**Retry with longer timeout**: Increase `timeout` and call `waitForStatus` again
433
-
4.**Use async methods**: Switch to async pattern for more control
533
+
When the relayer simulates a transaction before submission and the simulation reverts, a `SimulationFailedRpcError` is thrown with error code `4211`. This happens _before_ the transaction is sent on-chain:
// error.params contains the original { to, chainId, data } sent
458
549
}
459
550
}
460
551
```
461
552
553
+
Properties on `SimulationFailedRpcError`: `revertData`, `params`, `code` (`4211`).
554
+
555
+
### Automatic Fallback on Timeout
556
+
557
+
When `sendTransactionSync` rpc request times out, the SDK automatically falls back to polling for the transaction status. If you see a warning message like:
558
+
559
+
```
560
+
Transaction 0x... sync call timed out, falling back to polling for completion. DO NOT RETRY this transaction.
561
+
```
562
+
563
+
This means your transaction was successfully submitted but the sync method timed out. The SDK will continue polling for completion automatically. **Do not retry the operation** as this could result in duplicate transactions.
564
+
565
+
### Recovery Strategies
566
+
567
+
If a timeout occurs:
568
+
1.**Wait for automatic fallback**: `sendTransactionSync` automatically polls after timeout
569
+
2.**Check status manually**: Use `getStatus({ id })` to check if transaction is still processing if needed
570
+
3.**Retry with longer timeout**: Increase `timeout` and call `waitForReceipt` again
571
+
4.**Use async methods**: Switch to async pattern for more control
572
+
573
+
462
574
### Configuration Limits
463
575
464
576
The SDK enforces the following limits to prevent denial of service:
465
577
466
578
```typescript
467
579
import {
580
+
TimeoutError,
581
+
TransactionRevertedError,
582
+
SimulationFailedRpcError,
468
583
MIN_TIMEOUT,
469
584
MAX_TIMEOUT,
470
585
MIN_POLLING_INTERVAL,
@@ -508,6 +623,9 @@ See the [`/examples`](./examples) directory for complete working examples:
508
623
-[`examples/relayer/sponsored`](./examples/relayer/sponsored) - Direct relayer usage
0 commit comments