@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.
@@ -136,6 +136,32 @@ function resolveSource<TSource>(
136
136
  : (source as TSource);
137
137
  }
138
138
 
139
+ /**
140
+ * The values that are carried onto a tracked transaction rather than observed:
141
+ * they exist only because the caller (or the client construction) supplied
142
+ * them, so every emission path must thread them explicitly.
143
+ *
144
+ * They travel as one object so that adding a carried field cannot silently
145
+ * miss a path, and so that two same-typed markers cannot be swapped by a
146
+ * positional-argument mistake.
147
+ *
148
+ * The tracker never inspects any of them.
149
+ */
150
+ interface CarriedFields<TMetadata, TSource> {
151
+ /** What the application says the transaction MEANS. Persisted by consumers. */
152
+ metadata: TMetadata;
153
+ /** WHICH SIGNING ROUTE produced it. Observed at dispatch, persisted. */
154
+ source: TSource;
155
+ /**
156
+ * Which CALLER-SIDE REQUEST this send answers. Ephemeral plumbing.
157
+ *
158
+ * Deliberately a required property of type `string | undefined` rather than
159
+ * an optional one: a new call site must state that it has no correlation,
160
+ * instead of getting `undefined` by forgetting the field.
161
+ */
162
+ correlation: string | undefined;
163
+ }
164
+
139
165
  /**
140
166
  * Create an UnknownTrackedTransaction for immediate emission.
141
167
  * Populates all known intended values from the transaction parameters.
@@ -145,8 +171,7 @@ function createUnknownTrackedTransaction<TMetadata, TSource>(
145
171
  from: Address,
146
172
  nonce: number,
147
173
  chainId: number | undefined,
148
- metadata: TMetadata,
149
- source: TSource,
174
+ carried: CarriedFields<TMetadata, TSource>,
150
175
  broadcastTimestampMs: number,
151
176
  params: IntendedTransactionParams,
152
177
  ): UnknownTrackedTransaction<TMetadata, TSource> {
@@ -157,8 +182,7 @@ function createUnknownTrackedTransaction<TMetadata, TSource>(
157
182
  from,
158
183
  nonce,
159
184
  broadcastTimestampMs,
160
- metadata,
161
- source,
185
+ ...carried,
162
186
  to: params.to,
163
187
  value: params.value,
164
188
  data: params.data,
@@ -278,13 +302,12 @@ function extractTransactionTypeFields(tx: Transaction):
278
302
  * Create a KnownTrackedTransaction from a fetched transaction.
279
303
  *
280
304
  * Note: this object is rebuilt from the chain fetch, not copied from the
281
- * broadcasted one, so every carried-but-not-observed field (metadata, source)
282
- * must be threaded in explicitly.
305
+ * broadcasted one, so every carried-but-not-observed field (metadata, source,
306
+ * correlation) must be threaded in explicitly.
283
307
  */
284
308
  function createKnownTrackedTransaction<TMetadata, TSource>(
285
309
  tx: Transaction,
286
- metadata: TMetadata,
287
- source: TSource,
310
+ carried: CarriedFields<TMetadata, TSource>,
288
311
  broadcastTimestampMs: number,
289
312
  ): KnownTrackedTransaction<TMetadata, TSource> {
290
313
  const base = {
@@ -296,8 +319,7 @@ function createKnownTrackedTransaction<TMetadata, TSource>(
296
319
  value: tx.value,
297
320
  data: tx.input,
298
321
  broadcastTimestampMs,
299
- metadata,
300
- source,
322
+ ...carried,
301
323
  };
302
324
 
303
325
  const typeFields = extractTransactionTypeFields(tx);
@@ -315,8 +337,7 @@ function createKnownTrackedTransactionFromRaw<TMetadata, TSource>(
315
337
  parsedTx: ParseTransactionReturnType<`0x${string}`>,
316
338
  from: `0x${string}`,
317
339
  hash: Hash,
318
- metadata: TMetadata,
319
- source: TSource,
340
+ carried: CarriedFields<TMetadata, TSource>,
320
341
  chainId: number | undefined,
321
342
  broadcastTimestampMs: number,
322
343
  ): KnownTrackedTransaction<TMetadata, TSource> {
@@ -329,8 +350,7 @@ function createKnownTrackedTransactionFromRaw<TMetadata, TSource>(
329
350
  value: parsedTx.value ?? 0n,
330
351
  data: parsedTx.data ?? '0x',
331
352
  broadcastTimestampMs,
332
- metadata,
333
- source,
353
+ ...carried,
334
354
  };
335
355
 
336
356
  // Determine transaction type from parsed tx
@@ -629,7 +649,7 @@ export function createTrackedWalletClient<
629
649
  // Create emitter for transaction events
630
650
  const emitter = new Emitter<{
631
651
  'transaction:broadcasted': TrackedTransaction<TMetadata, TSource>;
632
- 'transaction:fetched': KnownTrackedTransaction<TMetadata, TSource>;
652
+ 'transaction:known': KnownTrackedTransaction<TMetadata, TSource>;
633
653
  }>();
634
654
 
635
655
  /**
@@ -685,29 +705,27 @@ export function createTrackedWalletClient<
685
705
  }
686
706
 
687
707
  /**
688
- * Fetch full transaction data and emit transaction:fetched event.
708
+ * Fetch full transaction data and emit transaction:known event.
689
709
  * Non-blocking, runs in background. Does not throw.
690
710
  */
691
711
  async function fetchAndEmitFullData(
692
712
  hash: Hash,
693
- metadata: TMetadata,
694
- source: TSource,
713
+ carried: CarriedFields<TMetadata, TSource>,
695
714
  broadcastTimestampMs: number,
696
715
  ): Promise<void> {
697
716
  try {
698
717
  const tx = await publicClient.getTransaction({hash});
699
718
  const knownTx = createKnownTrackedTransaction(
700
719
  tx,
701
- metadata,
702
- source,
720
+ carried,
703
721
  broadcastTimestampMs,
704
722
  );
705
- emitter.emit('transaction:fetched', knownTx);
723
+ emitter.emit('transaction:known', knownTx);
706
724
  } catch (error) {
707
- // Log but don't throw - transaction:fetched simply won't fire
725
+ // Log but don't throw - transaction:known simply won't fire
708
726
  console.warn(
709
727
  `[TrackedWalletClient] Could not fetch tx ${hash}. ` +
710
- `transaction:fetched event will not be emitted. Error: ${error}`,
728
+ `transaction:known event will not be emitted. Error: ${error}`,
711
729
  );
712
730
  }
713
731
  }
@@ -715,22 +733,46 @@ export function createTrackedWalletClient<
715
733
  /**
716
734
  * Common wrapper for transaction methods that broadcast (sendTransaction, writeContract).
717
735
  * Emits transaction:broadcasted immediately with intended values,
718
- * then fetches and emits transaction:fetched with actual values.
736
+ * then fetches and emits transaction:known with actual values.
719
737
  */
720
738
  async function executeTrackedTransaction<T, R>(args: {
721
739
  account?: Account | Address;
722
740
  nonce?: NonceOption;
723
741
  metadata: TMetadata;
724
- restArgs: T;
742
+ correlation: string | undefined;
743
+ /**
744
+ * The caller's remaining args, spread verbatim into viem's own call.
745
+ *
746
+ * `{correlation?: never}` is the compile-time half of the no-forwarding
747
+ * rule: a wrapper that forgets to destructure `correlation` out fails
748
+ * here instead of handing the wallet an unrecognised parameter. Nothing
749
+ * downstream would catch it, since the viem call is behind an `as any`.
750
+ */
751
+ restArgs: T & {correlation?: never};
725
752
  intendedParams: IntendedTransactionParams;
726
753
  execute: (argsWithNonce: T & {nonce: number}) => Promise<R>;
727
754
  extractHash: (result: R) => Hash;
728
755
  }): Promise<R> {
729
- const {metadata, restArgs, intendedParams, execute, extractHash} = args;
756
+ const {
757
+ metadata,
758
+ correlation,
759
+ restArgs,
760
+ intendedParams,
761
+ execute,
762
+ extractHash,
763
+ } = args;
730
764
  const broadcastTimestampMs = clock();
731
765
  // Stamped here, in the same step as from/nonce/broadcastTimestampMs.
732
766
  // A thunk is re-evaluated on every send, never captured once.
733
767
  const source = resolveSource(sourceOption);
768
+ // The carried values travel as one bundle from here on: metadata (what
769
+ // the tx means), source (which route signed) and correlation (which
770
+ // caller-side request this send answers). None is interpreted.
771
+ const carried: CarriedFields<TMetadata, TSource> = {
772
+ metadata,
773
+ source,
774
+ correlation,
775
+ };
734
776
 
735
777
  // Extract common context
736
778
  const {from, intendedNonce} = await extractTransactionContext(args);
@@ -750,15 +792,14 @@ export function createTrackedWalletClient<
750
792
  from,
751
793
  intendedNonce,
752
794
  walletClient.chain?.id,
753
- metadata,
754
- source,
795
+ carried,
755
796
  broadcastTimestampMs,
756
797
  intendedParams,
757
798
  );
758
799
  emitter.emit('transaction:broadcasted', unknownTx);
759
800
 
760
- // Fire-and-forget: fetch full data and emit transaction:fetched
761
- fetchAndEmitFullData(hash, metadata, source, broadcastTimestampMs);
801
+ // Fire-and-forget: fetch full data and emit transaction:known
802
+ fetchAndEmitFullData(hash, carried, broadcastTimestampMs);
762
803
 
763
804
  return result;
764
805
  }
@@ -771,14 +812,26 @@ export function createTrackedWalletClient<
771
812
  async function executeTrackedRawTransaction<R>(args: {
772
813
  serializedTransaction: TransactionSerialized;
773
814
  metadata: TMetadata;
815
+ correlation: string | undefined;
774
816
  execute: () => Promise<R>;
775
817
  extractHash: (result: R) => Hash;
776
818
  }): Promise<R> {
777
- const {serializedTransaction, metadata, execute, extractHash} = args;
819
+ const {
820
+ serializedTransaction,
821
+ metadata,
822
+ correlation,
823
+ execute,
824
+ extractHash,
825
+ } = args;
778
826
  const broadcastTimestampMs = clock();
779
827
  // Stamped here, in the same step as from/nonce/broadcastTimestampMs.
780
828
  // A thunk is re-evaluated on every send, never captured once.
781
829
  const source = resolveSource(sourceOption);
830
+ const carried: CarriedFields<TMetadata, TSource> = {
831
+ metadata,
832
+ source,
833
+ correlation,
834
+ };
782
835
 
783
836
  const from = await recoverTransactionAddress({serializedTransaction});
784
837
 
@@ -793,8 +846,7 @@ export function createTrackedWalletClient<
793
846
  parsedTx,
794
847
  from,
795
848
  hash,
796
- metadata,
797
- source,
849
+ carried,
798
850
  walletClient.chain?.id,
799
851
  broadcastTimestampMs,
800
852
  );
@@ -802,8 +854,11 @@ export function createTrackedWalletClient<
802
854
  // Emit as KnownTrackedTransaction since we have all data
803
855
  emitter.emit('transaction:broadcasted', knownTx);
804
856
 
805
- // Also emit to transaction:fetched for consistency
806
- emitter.emit('transaction:fetched', knownTx);
857
+ // The values are final (parsed from the signed payload, not merely
858
+ // intended), which is exactly what transaction:known promises, so it
859
+ // is emitted here too: every tracked transaction reaches that event,
860
+ // and a consumer can persist on it alone.
861
+ emitter.emit('transaction:known', knownTx);
807
862
 
808
863
  return result;
809
864
  }
@@ -843,13 +898,14 @@ export function createTrackedWalletClient<
843
898
  TChainOverride
844
899
  >,
845
900
  ): Promise<Hash> {
846
- const {metadata, nonce, ...writeArgs} = args;
901
+ const {metadata, correlation, nonce, ...writeArgs} = args;
847
902
  const intendedParams = extractIntendedParamsFromWriteContract(args);
848
903
 
849
904
  return executeTrackedTransaction({
850
905
  account: normalizeAccount(args.account),
851
906
  nonce,
852
907
  metadata: metadata as TMetadata,
908
+ correlation,
853
909
  restArgs: writeArgs,
854
910
  intendedParams,
855
911
  execute: (argsWithNonce) =>
@@ -868,13 +924,14 @@ export function createTrackedWalletClient<
868
924
  TChainOverride
869
925
  >,
870
926
  ): Promise<Hash> {
871
- const {metadata, nonce, ...sendArgs} = args;
927
+ const {metadata, correlation, nonce, ...sendArgs} = args;
872
928
  const intendedParams = extractIntendedParamsFromSendTransaction(args);
873
929
 
874
930
  return executeTrackedTransaction({
875
931
  account: normalizeAccount(args.account),
876
932
  nonce,
877
933
  metadata: metadata as TMetadata,
934
+ correlation,
878
935
  restArgs: sendArgs,
879
936
  intendedParams,
880
937
  execute: (argsWithNonce) =>
@@ -886,11 +943,12 @@ export function createTrackedWalletClient<
886
943
  async sendRawTransaction(
887
944
  args: TrackedRawTransactionParameters<TMetadata>,
888
945
  ): Promise<Hash> {
889
- const {metadata, serializedTransaction} = args;
946
+ const {metadata, correlation, serializedTransaction} = args;
890
947
 
891
948
  return executeTrackedRawTransaction({
892
949
  serializedTransaction,
893
950
  metadata: metadata as TMetadata,
951
+ correlation,
894
952
  execute: () =>
895
953
  walletClient.sendRawTransaction({serializedTransaction}),
896
954
  extractHash: (hash) => hash,
@@ -924,13 +982,14 @@ export function createTrackedWalletClient<
924
982
  TChainOverride
925
983
  >,
926
984
  ): Promise<TransactionReceipt> {
927
- const {metadata, nonce, ...writeArgs} = args;
985
+ const {metadata, correlation, nonce, ...writeArgs} = args;
928
986
  const intendedParams = extractIntendedParamsFromWriteContract(args);
929
987
 
930
988
  return executeTrackedTransaction({
931
989
  account: normalizeAccount(args.account),
932
990
  nonce,
933
991
  metadata: metadata as TMetadata,
992
+ correlation,
934
993
  restArgs: writeArgs,
935
994
  intendedParams,
936
995
  execute: (argsWithNonce) =>
@@ -949,13 +1008,14 @@ export function createTrackedWalletClient<
949
1008
  TChainOverride
950
1009
  >,
951
1010
  ): Promise<TransactionReceipt> {
952
- const {metadata, nonce, ...sendArgs} = args;
1011
+ const {metadata, correlation, nonce, ...sendArgs} = args;
953
1012
  const intendedParams = extractIntendedParamsFromSendTransaction(args);
954
1013
 
955
1014
  return executeTrackedTransaction({
956
1015
  account: normalizeAccount(args.account),
957
1016
  nonce,
958
1017
  metadata: metadata as TMetadata,
1018
+ correlation,
959
1019
  restArgs: sendArgs,
960
1020
  intendedParams,
961
1021
  execute: (argsWithNonce) =>
@@ -967,11 +1027,12 @@ export function createTrackedWalletClient<
967
1027
  async sendRawTransactionSync(
968
1028
  args: TrackedRawTransactionParameters<TMetadata>,
969
1029
  ): Promise<TransactionReceipt> {
970
- const {metadata, serializedTransaction} = args;
1030
+ const {metadata, correlation, serializedTransaction} = args;
971
1031
 
972
1032
  return executeTrackedRawTransaction({
973
1033
  serializedTransaction,
974
1034
  metadata: metadata as TMetadata,
1035
+ correlation,
975
1036
  execute: () =>
976
1037
  walletClient.sendRawTransactionSync({serializedTransaction}),
977
1038
  extractHash: (receipt) => receipt.transactionHash,
@@ -1016,7 +1077,7 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1016
1077
  // Create emitter for transaction events
1017
1078
  const emitter = new Emitter<{
1018
1079
  'transaction:broadcasted': TrackedTransaction<TMetadata, TSource>;
1019
- 'transaction:fetched': KnownTrackedTransaction<TMetadata, TSource>;
1080
+ 'transaction:known': KnownTrackedTransaction<TMetadata, TSource>;
1020
1081
  }>();
1021
1082
 
1022
1083
  /**
@@ -1058,29 +1119,27 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1058
1119
  }
1059
1120
 
1060
1121
  /**
1061
- * Fetch full transaction data and emit transaction:fetched event.
1122
+ * Fetch full transaction data and emit transaction:known event.
1062
1123
  * Non-blocking, runs in background. Does not throw.
1063
1124
  */
1064
1125
  async function fetchAndEmitFullData(
1065
1126
  hash: Hash,
1066
- metadata: TMetadata,
1067
- source: TSource,
1127
+ carried: CarriedFields<TMetadata, TSource>,
1068
1128
  broadcastTimestampMs: number,
1069
1129
  ): Promise<void> {
1070
1130
  try {
1071
1131
  const tx = await publicClient.getTransaction({hash});
1072
1132
  const knownTx = createKnownTrackedTransaction(
1073
1133
  tx,
1074
- metadata,
1075
- source,
1134
+ carried,
1076
1135
  broadcastTimestampMs,
1077
1136
  );
1078
- emitter.emit('transaction:fetched', knownTx);
1137
+ emitter.emit('transaction:known', knownTx);
1079
1138
  } catch (error) {
1080
- // Log but don't throw - transaction:fetched simply won't fire
1139
+ // Log but don't throw - transaction:known simply won't fire
1081
1140
  console.warn(
1082
1141
  `[TrackedWalletClient] Could not fetch tx ${hash}. ` +
1083
- `transaction:fetched event will not be emitted. Error: ${error}`,
1142
+ `transaction:known event will not be emitted. Error: ${error}`,
1084
1143
  );
1085
1144
  }
1086
1145
  }
@@ -1117,22 +1176,46 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1117
1176
  /**
1118
1177
  * Common wrapper for transaction methods that broadcast.
1119
1178
  * Emits transaction:broadcasted immediately with intended values,
1120
- * then fetches and emits transaction:fetched with actual values.
1179
+ * then fetches and emits transaction:known with actual values.
1121
1180
  */
1122
1181
  async function executeTrackedTransaction<T, R>(args: {
1123
1182
  account?: Account | Address;
1124
1183
  nonce?: NonceOption;
1125
1184
  metadata: TMetadata;
1126
- restArgs: T;
1185
+ correlation: string | undefined;
1186
+ /**
1187
+ * The caller's remaining args, spread verbatim into viem's own call.
1188
+ *
1189
+ * `{correlation?: never}` is the compile-time half of the no-forwarding
1190
+ * rule: a wrapper that forgets to destructure `correlation` out fails
1191
+ * here instead of handing the wallet an unrecognised parameter. Nothing
1192
+ * downstream would catch it, since the viem call is behind an `as any`.
1193
+ */
1194
+ restArgs: T & {correlation?: never};
1127
1195
  intendedParams: IntendedTransactionParams;
1128
1196
  execute: (argsWithNonce: T & {nonce: number}) => Promise<R>;
1129
1197
  extractHash: (result: R) => Hash;
1130
1198
  }): Promise<R> {
1131
- const {metadata, restArgs, intendedParams, execute, extractHash} = args;
1199
+ const {
1200
+ metadata,
1201
+ correlation,
1202
+ restArgs,
1203
+ intendedParams,
1204
+ execute,
1205
+ extractHash,
1206
+ } = args;
1132
1207
  const broadcastTimestampMs = clock();
1133
1208
  // Stamped here, in the same step as from/nonce/broadcastTimestampMs.
1134
1209
  // A thunk is re-evaluated on every send, never captured once.
1135
1210
  const source = resolveSource(sourceOption);
1211
+ // The carried values travel as one bundle from here on: metadata (what
1212
+ // the tx means), source (which route signed) and correlation (which
1213
+ // caller-side request this send answers). None is interpreted.
1214
+ const carried: CarriedFields<TMetadata, TSource> = {
1215
+ metadata,
1216
+ source,
1217
+ correlation,
1218
+ };
1136
1219
 
1137
1220
  const {from, intendedNonce} = await extractTransactionContext(args);
1138
1221
 
@@ -1150,15 +1233,14 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1150
1233
  from,
1151
1234
  intendedNonce,
1152
1235
  walletClient.chain?.id,
1153
- metadata,
1154
- source,
1236
+ carried,
1155
1237
  broadcastTimestampMs,
1156
1238
  intendedParams,
1157
1239
  );
1158
1240
  emitter.emit('transaction:broadcasted', unknownTx);
1159
1241
 
1160
- // Fire-and-forget: fetch full data and emit transaction:fetched
1161
- fetchAndEmitFullData(hash, metadata, source, broadcastTimestampMs);
1242
+ // Fire-and-forget: fetch full data and emit transaction:known
1243
+ fetchAndEmitFullData(hash, carried, broadcastTimestampMs);
1162
1244
 
1163
1245
  return result;
1164
1246
  }
@@ -1171,14 +1253,26 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1171
1253
  async function executeTrackedRawTransaction<R>(args: {
1172
1254
  serializedTransaction: TransactionSerialized;
1173
1255
  metadata: TMetadata;
1256
+ correlation: string | undefined;
1174
1257
  execute: () => Promise<R>;
1175
1258
  extractHash: (result: R) => Hash;
1176
1259
  }): Promise<R> {
1177
- const {serializedTransaction, metadata, execute, extractHash} = args;
1260
+ const {
1261
+ serializedTransaction,
1262
+ metadata,
1263
+ correlation,
1264
+ execute,
1265
+ extractHash,
1266
+ } = args;
1178
1267
  const broadcastTimestampMs = clock();
1179
1268
  // Stamped here, in the same step as from/nonce/broadcastTimestampMs.
1180
1269
  // A thunk is re-evaluated on every send, never captured once.
1181
1270
  const source = resolveSource(sourceOption);
1271
+ const carried: CarriedFields<TMetadata, TSource> = {
1272
+ metadata,
1273
+ source,
1274
+ correlation,
1275
+ };
1182
1276
 
1183
1277
  const from = await recoverTransactionAddress({serializedTransaction});
1184
1278
  const parsedTx = parseTransaction(serializedTransaction);
@@ -1192,8 +1286,7 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1192
1286
  parsedTx,
1193
1287
  from,
1194
1288
  hash,
1195
- metadata,
1196
- source,
1289
+ carried,
1197
1290
  walletClient.chain?.id,
1198
1291
  broadcastTimestampMs,
1199
1292
  );
@@ -1201,7 +1294,11 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1201
1294
  // Emit as KnownTrackedTransaction since we have all data
1202
1295
  emitter.emit('transaction:broadcasted', knownTx);
1203
1296
 
1204
- // We do not emit fetched as the tx is already known
1297
+ // The values are final (parsed from the signed payload, not merely
1298
+ // intended), which is exactly what transaction:known promises, so it
1299
+ // is emitted here too: every tracked transaction reaches that event,
1300
+ // and a consumer can persist on it alone.
1301
+ emitter.emit('transaction:known', knownTx);
1205
1302
 
1206
1303
  return result;
1207
1304
  }
@@ -1241,7 +1338,12 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1241
1338
  TChainOverride
1242
1339
  >,
1243
1340
  ): Promise<Hash> {
1244
- const {metadata: userMetadata, nonce, ...writeArgs} = args;
1341
+ const {
1342
+ metadata: userMetadata,
1343
+ correlation,
1344
+ nonce,
1345
+ ...writeArgs
1346
+ } = args;
1245
1347
 
1246
1348
  // Validate that user didn't provide operation, functionName or args
1247
1349
  validateNoAutoPopulatedFieldsInMetadata(userMetadata);
@@ -1260,6 +1362,7 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1260
1362
  account: normalizeAccount(args.account),
1261
1363
  nonce,
1262
1364
  metadata: finalMetadata,
1365
+ correlation,
1263
1366
  restArgs: writeArgs,
1264
1367
  intendedParams,
1265
1368
  execute: (argsWithNonce) =>
@@ -1278,13 +1381,14 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1278
1381
  TChainOverride
1279
1382
  >,
1280
1383
  ): Promise<Hash> {
1281
- const {metadata, nonce, ...sendArgs} = args;
1384
+ const {metadata, correlation, nonce, ...sendArgs} = args;
1282
1385
  const intendedParams = extractIntendedParamsFromSendTransaction(args);
1283
1386
 
1284
1387
  return executeTrackedTransaction({
1285
1388
  account: normalizeAccount(args.account),
1286
1389
  nonce,
1287
1390
  metadata: metadata as TMetadata,
1391
+ correlation,
1288
1392
  restArgs: sendArgs,
1289
1393
  intendedParams,
1290
1394
  execute: (argsWithNonce) =>
@@ -1296,11 +1400,12 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1296
1400
  async sendRawTransaction(
1297
1401
  args: TrackedRawTransactionParameters<TMetadata>,
1298
1402
  ): Promise<Hash> {
1299
- const {metadata, serializedTransaction} = args;
1403
+ const {metadata, correlation, serializedTransaction} = args;
1300
1404
 
1301
1405
  return executeTrackedRawTransaction({
1302
1406
  serializedTransaction,
1303
1407
  metadata: metadata as TMetadata,
1408
+ correlation,
1304
1409
  execute: () =>
1305
1410
  walletClient.sendRawTransaction({serializedTransaction}),
1306
1411
  extractHash: (hash) => hash,
@@ -1334,7 +1439,12 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1334
1439
  TChainOverride
1335
1440
  >,
1336
1441
  ): Promise<TransactionReceipt> {
1337
- const {metadata: userMetadata, nonce, ...writeArgs} = args;
1442
+ const {
1443
+ metadata: userMetadata,
1444
+ correlation,
1445
+ nonce,
1446
+ ...writeArgs
1447
+ } = args;
1338
1448
 
1339
1449
  // Validate that user didn't provide operation, functionName or args
1340
1450
  validateNoAutoPopulatedFieldsInMetadata(userMetadata);
@@ -1353,6 +1463,7 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1353
1463
  account: normalizeAccount(args.account),
1354
1464
  nonce,
1355
1465
  metadata: finalMetadata,
1466
+ correlation,
1356
1467
  restArgs: writeArgs,
1357
1468
  intendedParams,
1358
1469
  execute: (argsWithNonce) =>
@@ -1371,13 +1482,14 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1371
1482
  TChainOverride
1372
1483
  >,
1373
1484
  ): Promise<TransactionReceipt> {
1374
- const {metadata, nonce, ...sendArgs} = args;
1485
+ const {metadata, correlation, nonce, ...sendArgs} = args;
1375
1486
  const intendedParams = extractIntendedParamsFromSendTransaction(args);
1376
1487
 
1377
1488
  return executeTrackedTransaction({
1378
1489
  account: normalizeAccount(args.account),
1379
1490
  nonce,
1380
1491
  metadata: metadata as TMetadata,
1492
+ correlation,
1381
1493
  restArgs: sendArgs,
1382
1494
  intendedParams,
1383
1495
  execute: (argsWithNonce) =>
@@ -1389,11 +1501,12 @@ function createAutoPopulateBuilder<TMetadata, TSource>(
1389
1501
  async sendRawTransactionSync(
1390
1502
  args: TrackedRawTransactionParameters<TMetadata>,
1391
1503
  ): Promise<TransactionReceipt> {
1392
- const {metadata, serializedTransaction} = args;
1504
+ const {metadata, correlation, serializedTransaction} = args;
1393
1505
 
1394
1506
  return executeTrackedRawTransaction({
1395
1507
  serializedTransaction,
1396
1508
  metadata: metadata as TMetadata,
1509
+ correlation,
1397
1510
  execute: () =>
1398
1511
  walletClient.sendRawTransactionSync({serializedTransaction}),
1399
1512
  extractHash: (receipt) => receipt.transactionHash,