@etherkit/viem-tx-tracker 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +322 -0
- package/dist/TrackedWalletClient.d.ts +17 -0
- package/dist/TrackedWalletClient.d.ts.map +1 -0
- package/dist/TrackedWalletClient.js +264 -0
- package/dist/TrackedWalletClient.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +189 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +59 -0
- package/src/TrackedWalletClient.ts +472 -0
- package/src/index.ts +15 -0
- package/src/types.ts +328 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023-present Ronan Sandford
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# @etherkit/tx-observer
|
|
2
|
+
|
|
3
|
+
A TypeScript library for monitoring Ethereum onchain operations containing multiple transactions, with automatic status merging and finality tracking.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Operation Processor tracks **operations** - logical groupings of transactions that belong together. This is useful when:
|
|
8
|
+
|
|
9
|
+
- **Gas price bumping**: Multiple transactions with the same nonce but different gas prices
|
|
10
|
+
- **Sequential retries**: Transactions with different nonces for the same logical action
|
|
11
|
+
- **Multi-step operations**: Related transactions that form a single user action
|
|
12
|
+
|
|
13
|
+
The processor monitors all transactions in an operation and computes a merged status, emitting events when the operation status changes.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @etherkit/tx-observer
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { initTransactionProcessor } from '@etherkit/tx-observer';
|
|
25
|
+
import type { OnchainOperation, BroadcastedTransaction, OnchainOperationEvent } from '@etherkit/tx-observer';
|
|
26
|
+
|
|
27
|
+
// Initialize the processor
|
|
28
|
+
const processor = initTransactionProcessor({
|
|
29
|
+
finality: 12, // blocks until considered final
|
|
30
|
+
throttle: 5000, // optional: throttle process() calls
|
|
31
|
+
provider: window.ethereum,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Create an operation with one or more transactions
|
|
35
|
+
const operation: OnchainOperation = {
|
|
36
|
+
transactions: [
|
|
37
|
+
{
|
|
38
|
+
hash: '0xabc...',
|
|
39
|
+
from: '0x123...',
|
|
40
|
+
nonce: 5,
|
|
41
|
+
broadcastTimestamp: Date.now(),
|
|
42
|
+
},
|
|
43
|
+
],,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Add the operation to tracking (ID is passed separately)
|
|
47
|
+
processor.add('my-operation-1', operation);
|
|
48
|
+
|
|
49
|
+
// Listen for operation status changes (for UI updates)
|
|
50
|
+
processor.onOperationStatusUpdated((event: OnchainOperationEvent) => {
|
|
51
|
+
console.log(`Operation ${event.id}: ${event.operation.state?.inclusion}`);
|
|
52
|
+
|
|
53
|
+
if (event.operation.state?.inclusion === 'Included') {
|
|
54
|
+
const winningTx = event.operation.transactions[event.operation.state.txIndex];
|
|
55
|
+
console.log(`Status: ${event.operation.state.status}`);
|
|
56
|
+
console.log(`Winning TX: ${winningTx.hash}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return () => {}; // cleanup function
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Listen for any transaction changes (for persistence)
|
|
63
|
+
processor.onOperationUpdated((event: OnchainOperationEvent) => {
|
|
64
|
+
console.log(`Operation ${event.id} updated, save to storage`);
|
|
65
|
+
return () => {}; // cleanup function
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Process periodically (check for status updates)
|
|
69
|
+
setInterval(() => processor.process(), 5000);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API Reference
|
|
73
|
+
|
|
74
|
+
### `initTransactionProcessor(config)`
|
|
75
|
+
|
|
76
|
+
Creates a new operation processor instance.
|
|
77
|
+
|
|
78
|
+
**Config:**
|
|
79
|
+
|
|
80
|
+
| Field | Type | Description |
|
|
81
|
+
|-------|------|-------------|
|
|
82
|
+
| `finality` | `number` | Number of blocks until a transaction is considered final |
|
|
83
|
+
| `throttle` | `number?` | Optional: throttle interval in ms for `process()` calls |
|
|
84
|
+
| `provider` | `EIP1193ProviderWithoutEvents?` | Optional Ethereum provider (can be set later) |
|
|
85
|
+
|
|
86
|
+
**Returns:** Processor instance with the following methods:
|
|
87
|
+
|
|
88
|
+
#### `add(id: string, operation: OnchainOperation)`
|
|
89
|
+
|
|
90
|
+
Add an operation to track. If an operation with the same ID already exists, the transactions are merged into the existing operation.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// Add new operation
|
|
94
|
+
processor.add('my-operation-1', operation);
|
|
95
|
+
|
|
96
|
+
// Add another transaction to existing operation (same ID merges)
|
|
97
|
+
processor.add('my-operation-1', {
|
|
98
|
+
transactions: [bumpedTx], // New tx with higher gas
|
|
99
|
+
// ... state fields
|
|
100
|
+
});
|
|
101
|
+
// and in case where you track the txs already you can simply re-add
|
|
102
|
+
operation.transactions.push(bumpedTx);
|
|
103
|
+
processor.add('my-operation-1', operation);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### `addMultiple(operations: {[id: string]: OnchainOperation})`
|
|
107
|
+
|
|
108
|
+
Add multiple operations at once.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
processor.addMultiple({
|
|
112
|
+
'operation-1': operation1,
|
|
113
|
+
'operation-2': operation2,
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### `remove(operationId: string)`
|
|
118
|
+
|
|
119
|
+
Remove an operation by ID and stop tracking it.
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
processor.remove('my-operation-1');
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### `clear()`
|
|
126
|
+
|
|
127
|
+
Remove all operations.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
processor.clear();
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### `process(): Promise<void>`
|
|
134
|
+
|
|
135
|
+
Check and update the status of all tracked operations. This queries the Ethereum provider for transaction receipts and updates statuses accordingly.
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
await processor.process();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### `setProvider(provider: EIP1193Provider)`
|
|
142
|
+
|
|
143
|
+
Update the Ethereum provider.
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
processor.setProvider(newProvider);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### `onOperationUpdated(listener): void`
|
|
150
|
+
|
|
151
|
+
Subscribe to any operation changes (when any transaction in the operation changes). Useful for persistence.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
processor.onOperationUpdated((event: OnchainOperationEvent) => {
|
|
155
|
+
console.log(`Operation ${event.id} changed:`, event.operation);
|
|
156
|
+
return () => {}; // cleanup
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### `offOperationUpdated(listener): void`
|
|
161
|
+
|
|
162
|
+
Unsubscribe from operation changes.
|
|
163
|
+
|
|
164
|
+
#### `onOperationStatusUpdated(listener): void`
|
|
165
|
+
|
|
166
|
+
Subscribe to operation status changes only (when the merged status changes). Useful for UI updates.
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
processor.onOperationStatusUpdated((event: OnchainOperationEvent) => {
|
|
170
|
+
console.log(`Operation ${event.id} status:`, event.operation.state?.inclusion);
|
|
171
|
+
return () => {}; // cleanup
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### `offOperationStatusUpdated(listener): void`
|
|
176
|
+
|
|
177
|
+
Unsubscribe from operation status changes.
|
|
178
|
+
|
|
179
|
+
## Types
|
|
180
|
+
|
|
181
|
+
### `BroadcastedTransaction`
|
|
182
|
+
|
|
183
|
+
Represents a single broadcasted transaction.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
type BroadcastedTransaction = {
|
|
187
|
+
readonly hash: `0x${string}`;
|
|
188
|
+
readonly from: `0x${string}`;
|
|
189
|
+
nonce?: number;
|
|
190
|
+
readonly broadcastTimestamp: number;
|
|
191
|
+
state?: BroadcastedTransactionState;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
type BroadcastedTransactionState =
|
|
195
|
+
| { inclusion: 'InMemPool' | 'NotFound'; final: undefined; status: undefined }
|
|
196
|
+
| { inclusion: 'Dropped'; final?: number; status: undefined }
|
|
197
|
+
| { inclusion: 'Included'; status: 'Failure' | 'Success'; final?: number };
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### `OnchainOperationStatus`
|
|
201
|
+
|
|
202
|
+
The merged status of all transactions in an operation.
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
type OnchainOperationStatus =
|
|
206
|
+
| { inclusion: 'InMemPool' | 'NotFound'; final: undefined; status: undefined; txIndex: undefined }
|
|
207
|
+
| { inclusion: 'Dropped'; final?: number; status: undefined; txIndex: undefined }
|
|
208
|
+
| { inclusion: 'Included'; status: 'Failure' | 'Success'; final?: number; txIndex: number };
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- `txIndex`: Index into `transactions[]` for the "winning" transaction (first success, or first failure if all failed)
|
|
212
|
+
- Get the winning tx hash via: `operation.transactions[operation.state.txIndex].hash`
|
|
213
|
+
|
|
214
|
+
### `OnchainOperation`
|
|
215
|
+
|
|
216
|
+
An operation containing multiple transactions.
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
type OnchainOperation = {
|
|
220
|
+
transactions: BroadcastedTransaction[];
|
|
221
|
+
state?: OnchainOperationStatus;
|
|
222
|
+
};
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### `OnchainOperationEvent`
|
|
226
|
+
|
|
227
|
+
Event payload emitted by listeners, includes both the operation ID and operation data.
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
type OnchainOperationEvent = {
|
|
231
|
+
id: string;
|
|
232
|
+
operation: OnchainOperation;
|
|
233
|
+
};
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Status States
|
|
237
|
+
|
|
238
|
+
| Inclusion | Description |
|
|
239
|
+
|-----------|-------------|
|
|
240
|
+
| `Broadcasted` | At least one transaction is visible in the mempool |
|
|
241
|
+
| `NotFound` | No transactions visible in mempool (may be temporary) |
|
|
242
|
+
| `Dropped` | All transactions dropped (nonce was used by external tx) |
|
|
243
|
+
| `Included` | At least one transaction was included in a block |
|
|
244
|
+
|
|
245
|
+
## Status Merging Logic
|
|
246
|
+
|
|
247
|
+
When an operation contains multiple transactions, their statuses are merged using the following priority (highest wins):
|
|
248
|
+
|
|
249
|
+
1. **Included** - Any tx included in a block → operation is `Included`
|
|
250
|
+
2. **Broadcasted** - Any tx in mempool → operation is `Broadcasted`
|
|
251
|
+
3. **NotFound** - None visible → operation is `NotFound`
|
|
252
|
+
4. **Dropped** - ALL txs dropped → operation is `Dropped`
|
|
253
|
+
|
|
254
|
+
### For `Included` Operations
|
|
255
|
+
|
|
256
|
+
- If **any** transaction succeeded → `status: 'Success'`
|
|
257
|
+
- If **all** included transactions failed → `status: 'Failure'`
|
|
258
|
+
- `txIndex` points to the first successful tx, or first failure if all failed
|
|
259
|
+
|
|
260
|
+
This allows scenarios like:
|
|
261
|
+
- Tx A (nonce 5) succeeds, Tx B (nonce 6) fails due to nonce conflict → Operation is **Success**
|
|
262
|
+
- Tx A (nonce 5, low gas) dropped, Tx B (nonce 5, high gas) succeeds → Operation is **Success**
|
|
263
|
+
|
|
264
|
+
## Use Cases
|
|
265
|
+
|
|
266
|
+
### Gas Price Bumping
|
|
267
|
+
|
|
268
|
+
When network congestion increases, submit a replacement transaction with the same nonce but higher gas price:
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
// Initial transaction
|
|
272
|
+
const tx1: BroadcastedTransaction = {
|
|
273
|
+
hash: '0x111...',
|
|
274
|
+
from: '0xabc...',
|
|
275
|
+
nonce: 5,
|
|
276
|
+
broadcastTimestamp: Date.now(),
|
|
277
|
+
state: {
|
|
278
|
+
inclusion: 'InMemPool',
|
|
279
|
+
status: undefined,
|
|
280
|
+
final: undefined,
|
|
281
|
+
},
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
processor.add('transfer-1', {
|
|
285
|
+
transactions: [tx1],
|
|
286
|
+
state: {
|
|
287
|
+
inclusion: 'InMemPool',
|
|
288
|
+
status: undefined,
|
|
289
|
+
final: undefined,
|
|
290
|
+
txIndex: undefined,
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// Later, bump gas price (same nonce)
|
|
295
|
+
const tx2: BroadcastedTransaction = {
|
|
296
|
+
...tx1,
|
|
297
|
+
hash: '0x222...', // Different hash
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
processor.add('transfer-1', { // Same ID → merges
|
|
301
|
+
transactions: [tx2],
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// Operation now tracks both txs
|
|
305
|
+
// Whichever is included first determines the operation result
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Sequential Retry
|
|
309
|
+
|
|
310
|
+
If a transaction is stuck, retry with a new nonce:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
processor.add('my-action', {
|
|
314
|
+
transactions: [
|
|
315
|
+
{ hash: '0x1...', from: '0xabc...', nonce: 5, broadcastTimestamp: Date.now() }, // Original
|
|
316
|
+
{ hash: '0x2...', from: '0xabc...', nonce: 6, broadcastTimestamp: Date.now() }, // Retry with new nonce
|
|
317
|
+
],
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// If tx with nonce 5 succeeds, operation is Success
|
|
321
|
+
// Even if tx with nonce 6 fails (nonce conflict), operation is still Success
|
|
322
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Account, type Chain, type PublicClient, type Transport, type WalletClient } from 'viem';
|
|
2
|
+
import type { TrackedWalletClient } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create a tracked wallet client that wraps a viem WalletClient.
|
|
5
|
+
*
|
|
6
|
+
* The tracked client provides the same API as WalletClient but with:
|
|
7
|
+
* - Optional metadata field for transaction tracking
|
|
8
|
+
* - Automatic nonce fetching (with 'pending' by default)
|
|
9
|
+
* - Post-broadcast transaction verification
|
|
10
|
+
* - TODO: Event emission for tracking
|
|
11
|
+
*
|
|
12
|
+
* @param walletClient - The underlying viem WalletClient
|
|
13
|
+
* @param publicClient - A PublicClient for nonce fetching and tx verification
|
|
14
|
+
* @returns A TrackedWalletClient instance
|
|
15
|
+
*/
|
|
16
|
+
export declare function createTrackedWalletClient<TTransport extends Transport = Transport, TChain extends Chain | undefined = Chain | undefined, TAccount extends Account | undefined = Account | undefined>(walletClient: WalletClient<TTransport, TChain, TAccount>, publicClient: PublicClient): TrackedWalletClient<TTransport, TChain, TAccount>;
|
|
17
|
+
//# sourceMappingURL=TrackedWalletClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrackedWalletClient.d.ts","sourceRoot":"","sources":["../src/TrackedWalletClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,OAAO,EAEZ,KAAK,KAAK,EAIV,KAAK,YAAY,EAGjB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EAMX,mBAAmB,EAGnB,MAAM,YAAY,CAAC;AA+CpB;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACxC,UAAU,SAAS,SAAS,GAAG,SAAS,EACxC,MAAM,SAAS,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,EACpD,QAAQ,SAAS,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,EAE1D,YAAY,EAAE,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EACxD,YAAY,EAAE,YAAY,GACxB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CA0XnD"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { parseTransaction, recoverTransactionAddress, } from 'viem';
|
|
2
|
+
import { Emitter } from 'radiate';
|
|
3
|
+
/**
|
|
4
|
+
* Check if a value is a block tag string
|
|
5
|
+
*/
|
|
6
|
+
function isBlockTag(value) {
|
|
7
|
+
return (typeof value === 'string' &&
|
|
8
|
+
['latest', 'pending', 'earliest', 'safe', 'finalized'].includes(value));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the account address from various account formats
|
|
12
|
+
*/
|
|
13
|
+
function resolveAccountAddress(account) {
|
|
14
|
+
if (!account)
|
|
15
|
+
return undefined;
|
|
16
|
+
if (typeof account === 'string')
|
|
17
|
+
return account;
|
|
18
|
+
return account.address;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Coerce potentially null account to undefined for type compatibility with extractTransactionContext
|
|
22
|
+
*/
|
|
23
|
+
function normalizeAccount(account) {
|
|
24
|
+
return account === null ? undefined : account;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generate a unique tracking ID if not provided in metadata
|
|
28
|
+
*/
|
|
29
|
+
function generateTrackingId() {
|
|
30
|
+
return crypto.randomUUID();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a tracked wallet client that wraps a viem WalletClient.
|
|
34
|
+
*
|
|
35
|
+
* The tracked client provides the same API as WalletClient but with:
|
|
36
|
+
* - Optional metadata field for transaction tracking
|
|
37
|
+
* - Automatic nonce fetching (with 'pending' by default)
|
|
38
|
+
* - Post-broadcast transaction verification
|
|
39
|
+
* - TODO: Event emission for tracking
|
|
40
|
+
*
|
|
41
|
+
* @param walletClient - The underlying viem WalletClient
|
|
42
|
+
* @param publicClient - A PublicClient for nonce fetching and tx verification
|
|
43
|
+
* @returns A TrackedWalletClient instance
|
|
44
|
+
*/
|
|
45
|
+
export function createTrackedWalletClient(walletClient, publicClient) {
|
|
46
|
+
// Create emitter for transaction broadcast events
|
|
47
|
+
const emitter = new Emitter();
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the nonce to use for a transaction.
|
|
50
|
+
*
|
|
51
|
+
* @param nonceOption - The nonce option provided by the caller
|
|
52
|
+
* @param from - The sender address
|
|
53
|
+
* @returns The resolved nonce number
|
|
54
|
+
*/
|
|
55
|
+
async function resolveNonce(nonceOption, from) {
|
|
56
|
+
if (typeof nonceOption === 'number') {
|
|
57
|
+
// Explicit number - use as-is
|
|
58
|
+
return nonceOption;
|
|
59
|
+
}
|
|
60
|
+
// Block tag (string) or undefined - fetch from chain
|
|
61
|
+
const blockTag = isBlockTag(nonceOption) ? nonceOption : 'pending';
|
|
62
|
+
return await publicClient.getTransactionCount({
|
|
63
|
+
address: from,
|
|
64
|
+
blockTag,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Extract common transaction context (account, nonce) from request args.
|
|
69
|
+
* This is the shared logic between all transaction methods.
|
|
70
|
+
*
|
|
71
|
+
* @param args - The transaction args containing account and nonce options
|
|
72
|
+
* @returns TransactionContext with resolved from address and nonce
|
|
73
|
+
*/
|
|
74
|
+
async function extractTransactionContext(args) {
|
|
75
|
+
// Get account/from address
|
|
76
|
+
const account = args.account ?? walletClient.account;
|
|
77
|
+
const from = resolveAccountAddress(account);
|
|
78
|
+
if (!from) {
|
|
79
|
+
throw new Error('[TrackedWalletClient] No account available. ' +
|
|
80
|
+
'Provide an account in the request or configure the wallet client with an account.');
|
|
81
|
+
}
|
|
82
|
+
// Resolve nonce
|
|
83
|
+
const intendedNonce = await resolveNonce(args.nonce, from);
|
|
84
|
+
return { from, intendedNonce };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Extract transaction context from a serialized (signed) transaction.
|
|
88
|
+
* Parses the transaction and recovers the sender address.
|
|
89
|
+
*
|
|
90
|
+
* @param serializedTransaction - The RLP-encoded signed transaction
|
|
91
|
+
* @returns TransactionContext with from address and nonce
|
|
92
|
+
*/
|
|
93
|
+
async function extractRawTransactionContext(serializedTransaction) {
|
|
94
|
+
// Parse the serialized transaction to get the nonce
|
|
95
|
+
const parsedTx = parseTransaction(serializedTransaction);
|
|
96
|
+
if (parsedTx.nonce === undefined) {
|
|
97
|
+
throw new Error('[TrackedWalletClient] Could not extract nonce from serialized transaction.');
|
|
98
|
+
}
|
|
99
|
+
// Recover the sender address from the signature
|
|
100
|
+
const from = await recoverTransactionAddress({
|
|
101
|
+
serializedTransaction,
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
from,
|
|
105
|
+
intendedNonce: parsedTx.nonce,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Fetch the transaction after broadcast to verify nonce.
|
|
110
|
+
* Logs a warning if the nonce was overridden or if tx cannot be found.
|
|
111
|
+
*
|
|
112
|
+
* @param hash - The transaction hash
|
|
113
|
+
* @param intendedNonce - The nonce we intended to use
|
|
114
|
+
* @returns The actual nonce, or the intended nonce if fetch failed
|
|
115
|
+
*/
|
|
116
|
+
async function verifyTransactionNonce(hash, intendedNonce) {
|
|
117
|
+
try {
|
|
118
|
+
const tx = await publicClient.getTransaction({ hash });
|
|
119
|
+
const actualNonce = tx.nonce;
|
|
120
|
+
if (actualNonce !== intendedNonce) {
|
|
121
|
+
console.warn(`[TrackedWalletClient] Nonce mismatch: intended ${intendedNonce}, actual ${actualNonce}. ` +
|
|
122
|
+
`Wallet may have overridden the nonce.`);
|
|
123
|
+
}
|
|
124
|
+
return actualNonce;
|
|
125
|
+
}
|
|
126
|
+
catch (fetchError) {
|
|
127
|
+
// Transaction not found in mempool/chain yet
|
|
128
|
+
console.warn(`[TrackedWalletClient] Could not fetch tx ${hash} after broadcast. ` +
|
|
129
|
+
`It may not be in the mempool yet.`);
|
|
130
|
+
return intendedNonce;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Create a tracked transaction record.
|
|
135
|
+
*/
|
|
136
|
+
function createTrackedTransaction(txHash, from, nonce, metadata, request) {
|
|
137
|
+
return {
|
|
138
|
+
trackingId: metadata?.id ?? generateTrackingId(),
|
|
139
|
+
txHash,
|
|
140
|
+
from,
|
|
141
|
+
nonce,
|
|
142
|
+
chainId: walletClient.chain?.id ?? 1,
|
|
143
|
+
metadata: (metadata ?? {}),
|
|
144
|
+
initiatedAt: Date.now(),
|
|
145
|
+
request,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Common wrapper for transaction methods that broadcast (sendTransaction, writeContract).
|
|
150
|
+
* Handles nonce resolution, underlying call, post-broadcast verification, and tracking record creation.
|
|
151
|
+
*/
|
|
152
|
+
async function executeTrackedTransaction(args) {
|
|
153
|
+
const { metadata, restArgs, execute, extractHash } = args;
|
|
154
|
+
// Extract common context
|
|
155
|
+
const { from, intendedNonce } = await extractTransactionContext(args);
|
|
156
|
+
// Execute the underlying transaction with nonce injected
|
|
157
|
+
const result = await execute({ ...restArgs, nonce: intendedNonce });
|
|
158
|
+
const hash = extractHash(result);
|
|
159
|
+
// Verify transaction and get actual nonce
|
|
160
|
+
const actualNonce = await verifyTransactionNonce(hash, intendedNonce);
|
|
161
|
+
// Create tracked transaction record
|
|
162
|
+
const trackedTx = createTrackedTransaction(hash, from, actualNonce, metadata, restArgs);
|
|
163
|
+
// Emit transaction broadcasted event
|
|
164
|
+
emitter.emit('transaction:broadcasted', trackedTx);
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Common wrapper for raw transaction broadcasts (sendRawTransaction).
|
|
169
|
+
* Decodes the transaction to extract from/nonce, broadcasts, and creates tracking record.
|
|
170
|
+
*/
|
|
171
|
+
async function executeTrackedRawTransaction(args) {
|
|
172
|
+
const { serializedTransaction, metadata, execute, extractHash } = args;
|
|
173
|
+
// Extract context from the serialized transaction
|
|
174
|
+
const { from, intendedNonce } = await extractRawTransactionContext(serializedTransaction);
|
|
175
|
+
// Execute the broadcast
|
|
176
|
+
const result = await execute();
|
|
177
|
+
const hash = extractHash(result);
|
|
178
|
+
// For raw transactions, the nonce is already embedded, so no verification needed
|
|
179
|
+
// (wallet cannot override nonce in an already-signed transaction)
|
|
180
|
+
// Create tracked transaction record
|
|
181
|
+
const trackedTx = createTrackedTransaction(hash, from, intendedNonce, metadata, { serializedTransaction });
|
|
182
|
+
// Emit transaction broadcasted event
|
|
183
|
+
emitter.emit('transaction:broadcasted', trackedTx);
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
walletClient,
|
|
188
|
+
publicClient,
|
|
189
|
+
// ============================================
|
|
190
|
+
// Async methods (return hash)
|
|
191
|
+
// ============================================
|
|
192
|
+
async writeContract(args) {
|
|
193
|
+
const { metadata, nonce, ...writeArgs } = args;
|
|
194
|
+
return executeTrackedTransaction({
|
|
195
|
+
account: normalizeAccount(args.account),
|
|
196
|
+
nonce,
|
|
197
|
+
metadata,
|
|
198
|
+
restArgs: writeArgs,
|
|
199
|
+
execute: (argsWithNonce) => walletClient.writeContract(argsWithNonce),
|
|
200
|
+
extractHash: (hash) => hash,
|
|
201
|
+
});
|
|
202
|
+
},
|
|
203
|
+
async sendTransaction(args) {
|
|
204
|
+
const { metadata, nonce, ...sendArgs } = args;
|
|
205
|
+
return executeTrackedTransaction({
|
|
206
|
+
account: normalizeAccount(args.account),
|
|
207
|
+
nonce,
|
|
208
|
+
metadata,
|
|
209
|
+
restArgs: sendArgs,
|
|
210
|
+
execute: (argsWithNonce) => walletClient.sendTransaction(argsWithNonce),
|
|
211
|
+
extractHash: (hash) => hash,
|
|
212
|
+
});
|
|
213
|
+
},
|
|
214
|
+
async sendRawTransaction(args) {
|
|
215
|
+
const { metadata, serializedTransaction } = args;
|
|
216
|
+
return executeTrackedRawTransaction({
|
|
217
|
+
serializedTransaction,
|
|
218
|
+
metadata,
|
|
219
|
+
execute: () => walletClient.sendRawTransaction({ serializedTransaction }),
|
|
220
|
+
extractHash: (hash) => hash,
|
|
221
|
+
});
|
|
222
|
+
},
|
|
223
|
+
// ============================================
|
|
224
|
+
// Sync methods (return receipt, wait for confirmation)
|
|
225
|
+
// ============================================
|
|
226
|
+
async writeContractSync(args) {
|
|
227
|
+
const { metadata, nonce, ...writeArgs } = args;
|
|
228
|
+
return executeTrackedTransaction({
|
|
229
|
+
account: normalizeAccount(args.account),
|
|
230
|
+
nonce,
|
|
231
|
+
metadata,
|
|
232
|
+
restArgs: writeArgs,
|
|
233
|
+
execute: (argsWithNonce) => walletClient.writeContractSync(argsWithNonce),
|
|
234
|
+
extractHash: (receipt) => receipt.transactionHash,
|
|
235
|
+
});
|
|
236
|
+
},
|
|
237
|
+
async sendTransactionSync(args) {
|
|
238
|
+
const { metadata, nonce, ...sendArgs } = args;
|
|
239
|
+
return executeTrackedTransaction({
|
|
240
|
+
account: normalizeAccount(args.account),
|
|
241
|
+
nonce,
|
|
242
|
+
metadata,
|
|
243
|
+
restArgs: sendArgs,
|
|
244
|
+
execute: (argsWithNonce) => walletClient.sendTransactionSync(argsWithNonce),
|
|
245
|
+
extractHash: (receipt) => receipt.transactionHash,
|
|
246
|
+
});
|
|
247
|
+
},
|
|
248
|
+
async sendRawTransactionSync(args) {
|
|
249
|
+
const { metadata, serializedTransaction } = args;
|
|
250
|
+
return executeTrackedRawTransaction({
|
|
251
|
+
serializedTransaction,
|
|
252
|
+
metadata,
|
|
253
|
+
execute: () => walletClient.sendRawTransactionSync({ serializedTransaction }),
|
|
254
|
+
extractHash: (receipt) => receipt.transactionHash,
|
|
255
|
+
});
|
|
256
|
+
},
|
|
257
|
+
// ============================================
|
|
258
|
+
// Event subscription methods
|
|
259
|
+
// ============================================
|
|
260
|
+
onTransactionBroadcasted: (listener) => emitter.on('transaction:broadcasted', listener),
|
|
261
|
+
offTransactionBroadcasted: (listener) => emitter.off('transaction:broadcasted', listener),
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=TrackedWalletClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrackedWalletClient.js","sourceRoot":"","sources":["../src/TrackedWalletClient.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { BlockTag, ExpectedEvent, NonceOption, TrackedRawTransactionParameters, TrackedSendTransactionParameters, TrackedTransaction, TrackedWalletClient, TrackedWriteContractParameters, TransactionMetadata, } from './types.js';
|
|
2
|
+
export { createTrackedWalletClient } from './TrackedWalletClient.js';
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACX,QAAQ,EACR,aAAa,EACb,WAAW,EACX,+BAA+B,EAC/B,gCAAgC,EAChC,kBAAkB,EAClB,mBAAmB,EACnB,8BAA8B,EAC9B,mBAAmB,GACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,UAAU;AACV,OAAO,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC"}
|