@etherkit/viem-tx-tracker 0.1.0 → 0.2.0

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/src/types.ts CHANGED
@@ -108,6 +108,46 @@ export type MetadataField<TMetadata> = undefined extends TMetadata
108
108
  ? {metadata?: TMetadata}
109
109
  : {metadata: TMetadata};
110
110
 
111
+ /**
112
+ * The optional, opaque, per-call correlation marker.
113
+ *
114
+ * It answers "which caller-side request does this send answer?", so the code
115
+ * that receives `transaction:broadcasted` can match the event to the in-flight
116
+ * send it issued, without an out-of-band map keyed on something like
117
+ * `from:nonce` (which is not unique: cancelling a stuck transaction creates a
118
+ * second operation at the same nonce by design).
119
+ *
120
+ * Three fields are carried on a tracked transaction and they answer three
121
+ * different questions:
122
+ *
123
+ * | field | question | lifetime |
124
+ * | ------------- | -------------------------------------------- | ------------------- |
125
+ * | `metadata` | what the application says the tx MEANS | persisted |
126
+ * | `source` | WHICH SIGNING ROUTE produced it | persisted |
127
+ * | `correlation` | which CALLER-SIDE REQUEST this send answers | ephemeral plumbing |
128
+ *
129
+ * `correlation` is deliberately NOT any of the following:
130
+ *
131
+ * - It is not intended to be persisted. It is routing plumbing for the session
132
+ * that issued the send, not a property of the transaction.
133
+ * - It is not an identity for the transaction. `hash` is that.
134
+ * - It is meaningless outside the session that issued the send, so a value
135
+ * rehydrated from storage carries no information.
136
+ *
137
+ * The tracker never inspects, interprets, validates or defaults it, exactly as
138
+ * with `source`. It is a sibling of `metadata`, never nested inside it,
139
+ * precisely because metadata is what gets persisted.
140
+ */
141
+ export type CorrelationField = {
142
+ /**
143
+ * Opaque per-call marker tying this send back to the caller-side request
144
+ * that issued it. Carried verbatim onto the emitted transaction. Ephemeral:
145
+ * not intended to be persisted, not an identity, meaningless outside the
146
+ * issuing session. See {@link CorrelationField}.
147
+ */
148
+ correlation?: string;
149
+ };
150
+
111
151
  /**
112
152
  * Access list type used in EIP-2930 and EIP-1559 transactions.
113
153
  */
@@ -145,6 +185,27 @@ type CommonTrackedFields<TMetadata, TSource = undefined> = {
145
185
  * the application said the transaction means.
146
186
  */
147
187
  readonly source: TSource;
188
+ /**
189
+ * Opaque marker of which caller-side request this send answers, supplied per
190
+ * call and carried verbatim: the tracker never inspects or interprets it.
191
+ * Carried on every emitted transaction, so it reaches `transaction:known`
192
+ * as well as `transaction:broadcasted`.
193
+ *
194
+ * Ephemeral plumbing, unlike its two siblings: `metadata` is what the
195
+ * application says the transaction MEANS and `source` is WHICH SIGNING ROUTE
196
+ * produced it, both of which consumers persist. `correlation` is not
197
+ * intended to be persisted, is not an identity for the transaction, and is
198
+ * meaningless outside the session that issued the send.
199
+ * See {@link CorrelationField} for the full three-way distinction.
200
+ *
201
+ * Optional here, unlike the required `source` above, and deliberately so.
202
+ * The property is in fact always present at runtime, so `string | undefined`
203
+ * would be the more faithful type, but making it required would stop every
204
+ * consumer-authored tracked-transaction literal (mocks, fixtures, values
205
+ * rehydrated from storage) from compiling, turning an additive change into a
206
+ * breaking one. Do not "tidy" this into a required property.
207
+ */
208
+ readonly correlation?: string;
148
209
  readonly to: `0x${string}` | null;
149
210
  readonly value: bigint;
150
211
  readonly data: `0x${string}`;
@@ -152,9 +213,10 @@ type CommonTrackedFields<TMetadata, TSource = undefined> = {
152
213
  };
153
214
 
154
215
  /**
155
- * A fully known tracked transaction with all fields confirmed from chain.
156
- * Emitted via transaction:fetched when tx data is fetched from chain,
157
- * or immediately for sendRawTransaction where we can parse the tx.
216
+ * A fully known tracked transaction: every field is a final value.
217
+ * Emitted via transaction:known, either once the tx has been read back from
218
+ * the chain, or immediately for sendRawTransaction where the signed payload
219
+ * can be parsed.
158
220
  *
159
221
  * When known=true, all values are the actual confirmed values used by the chain.
160
222
  * Uses discriminated union by txType to enforce correct field combinations.
@@ -261,7 +323,8 @@ export type UnknownTrackedTransaction<
261
323
 
262
324
  /**
263
325
  * A tracked transaction - discriminated by 'known' field.
264
- * - known=true: Values are confirmed from chain fetch
326
+ * - known=true: Values are final, read back from chain or parsed from a
327
+ * signed payload
265
328
  * - known=false: Values are intended/provided, may differ from actual
266
329
  */
267
330
  export type TrackedTransaction<TMetadata, TSource = undefined> =
@@ -303,7 +366,8 @@ export type TrackedWriteContractParameters<
303
366
  * - undefined: fetch nonce using 'pending' (default)
304
367
  */
305
368
  nonce?: NonceOption;
306
- } & MetadataField<TMetadata>;
369
+ } & MetadataField<TMetadata> &
370
+ CorrelationField;
307
371
 
308
372
  /**
309
373
  * The fields that are auto-populated by writeContract.
@@ -395,7 +459,8 @@ export type TrackedWriteContractAutoPopulateParameters<
395
459
  * - undefined: fetch nonce using 'pending' (default)
396
460
  */
397
461
  nonce?: NonceOption;
398
- } & WriteContractAutoPopulateMetadataField<TMetadata>;
462
+ } & WriteContractAutoPopulateMetadataField<TMetadata> &
463
+ CorrelationField;
399
464
 
400
465
  /**
401
466
  * Extended SendTransactionParameters with metadata and flexible nonce.
@@ -417,7 +482,8 @@ export type TrackedSendTransactionParameters<
417
482
  * - undefined: fetch nonce using 'pending' (default)
418
483
  */
419
484
  nonce?: NonceOption;
420
- } & MetadataField<TMetadata>;
485
+ } & MetadataField<TMetadata> &
486
+ CorrelationField;
421
487
 
422
488
  /**
423
489
  * Parameters for sendRawTransaction with metadata.
@@ -429,7 +495,8 @@ export type TrackedRawTransactionParameters<TMetadata> = {
429
495
  * The RLP-encoded signed transaction.
430
496
  */
431
497
  serializedTransaction: TransactionSerialized;
432
- } & MetadataField<TMetadata>;
498
+ } & MetadataField<TMetadata> &
499
+ CorrelationField;
433
500
 
434
501
  /**
435
502
  * A wallet client wrapper that tracks transactions with metadata.
@@ -593,10 +660,25 @@ export type TrackedWalletClientEvents<TMetadata, TSource = undefined> = {
593
660
  */
594
661
  'transaction:broadcasted': TrackedTransaction<TMetadata, TSource>;
595
662
  /**
596
- * Emitted when full transaction data is successfully fetched from chain.
597
- * Not guaranteed to fire if fetch fails (tx not in mempool yet, network issues, etc.)
663
+ * Emitted when the transaction's values are known to be the final ones
664
+ * rather than the ones that were merely intended.
665
+ *
666
+ * The name states the promise, not the mechanism, because the mechanism
667
+ * differs by path: the values are read back from the chain for a normal
668
+ * send, and parsed from the signed payload for a raw send. Both yield final
669
+ * values, so both emit this event, and a consumer can persist on it alone.
670
+ *
671
+ * Note the two paths differ in RELIABILITY, which the name cannot express:
672
+ *
673
+ * - Normal sends: best effort. If the read fails (not in the mempool yet,
674
+ * network trouble) this simply never fires and a warning is logged.
675
+ * - Raw sends: always fires, immediately, since nothing can fail. The same
676
+ * object is delivered to `transaction:broadcasted` first.
677
+ *
678
+ * So treat `transaction:broadcasted` as the event you must handle, and this
679
+ * one as a refinement that is usually but not always delivered.
598
680
  */
599
- 'transaction:fetched': KnownTrackedTransaction<TMetadata, TSource>;
681
+ 'transaction:known': KnownTrackedTransaction<TMetadata, TSource>;
600
682
  };
601
683
 
602
684
  /**