@formo/analytics 1.26.0 → 1.28.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.
Files changed (87) hide show
  1. package/README.md +6 -4
  2. package/dist/cjs/src/FormoAnalytics.d.ts +71 -12
  3. package/dist/cjs/src/FormoAnalytics.js +274 -147
  4. package/dist/cjs/src/event/EventFactory.d.ts +10 -2
  5. package/dist/cjs/src/event/EventFactory.js +32 -21
  6. package/dist/cjs/src/fetch/index.d.ts +10 -2
  7. package/dist/cjs/src/fetch/index.js +122 -4
  8. package/dist/cjs/src/index.d.ts +4 -0
  9. package/dist/cjs/src/index.js +6 -0
  10. package/dist/cjs/src/privy/index.d.ts +9 -0
  11. package/dist/cjs/src/privy/index.js +12 -0
  12. package/dist/cjs/src/privy/types.d.ts +175 -0
  13. package/dist/cjs/src/privy/types.js +12 -0
  14. package/dist/cjs/src/privy/utils.d.ts +32 -0
  15. package/dist/cjs/src/privy/utils.js +188 -0
  16. package/dist/cjs/src/queue/EventQueue.d.ts +24 -2
  17. package/dist/cjs/src/queue/EventQueue.js +158 -49
  18. package/dist/cjs/src/session/index.js +2 -1
  19. package/dist/cjs/src/solana/SolanaAdapter.d.ts +211 -0
  20. package/dist/cjs/src/solana/SolanaAdapter.js +975 -0
  21. package/dist/cjs/src/solana/SolanaManager.d.ts +24 -0
  22. package/dist/cjs/src/solana/SolanaManager.js +80 -0
  23. package/dist/cjs/src/solana/address.d.ts +72 -0
  24. package/dist/cjs/src/solana/address.js +176 -0
  25. package/dist/cjs/src/solana/index.d.ts +13 -0
  26. package/dist/cjs/src/solana/index.js +32 -0
  27. package/dist/cjs/src/solana/types.d.ts +206 -0
  28. package/dist/cjs/src/solana/types.js +80 -0
  29. package/dist/cjs/src/types/base.d.ts +25 -0
  30. package/dist/cjs/src/types/events.d.ts +9 -6
  31. package/dist/cjs/src/utils/address.d.ts +21 -0
  32. package/dist/cjs/src/utils/address.js +48 -1
  33. package/dist/cjs/src/utils/builderCode.d.ts +30 -0
  34. package/dist/cjs/src/utils/builderCode.js +143 -0
  35. package/dist/cjs/src/utils/index.d.ts +1 -0
  36. package/dist/cjs/src/utils/index.js +1 -0
  37. package/dist/cjs/src/version.d.ts +1 -1
  38. package/dist/cjs/src/version.js +1 -1
  39. package/dist/cjs/src/wagmi/WagmiEventHandler.d.ts +24 -0
  40. package/dist/cjs/src/wagmi/WagmiEventHandler.js +242 -24
  41. package/dist/cjs/src/wagmi/types.d.ts +31 -0
  42. package/dist/cjs/src/wagmi/utils.d.ts +79 -0
  43. package/dist/cjs/src/wagmi/utils.js +218 -0
  44. package/dist/esm/src/FormoAnalytics.d.ts +71 -12
  45. package/dist/esm/src/FormoAnalytics.js +275 -148
  46. package/dist/esm/src/event/EventFactory.d.ts +10 -2
  47. package/dist/esm/src/event/EventFactory.js +34 -23
  48. package/dist/esm/src/fetch/index.d.ts +10 -2
  49. package/dist/esm/src/fetch/index.js +123 -2
  50. package/dist/esm/src/index.d.ts +4 -0
  51. package/dist/esm/src/index.js +3 -0
  52. package/dist/esm/src/privy/index.d.ts +9 -0
  53. package/dist/esm/src/privy/index.js +8 -0
  54. package/dist/esm/src/privy/types.d.ts +175 -0
  55. package/dist/esm/src/privy/types.js +11 -0
  56. package/dist/esm/src/privy/utils.d.ts +32 -0
  57. package/dist/esm/src/privy/utils.js +185 -0
  58. package/dist/esm/src/queue/EventQueue.d.ts +24 -2
  59. package/dist/esm/src/queue/EventQueue.js +158 -49
  60. package/dist/esm/src/session/index.js +2 -1
  61. package/dist/esm/src/solana/SolanaAdapter.d.ts +211 -0
  62. package/dist/esm/src/solana/SolanaAdapter.js +972 -0
  63. package/dist/esm/src/solana/SolanaManager.d.ts +24 -0
  64. package/dist/esm/src/solana/SolanaManager.js +77 -0
  65. package/dist/esm/src/solana/address.d.ts +72 -0
  66. package/dist/esm/src/solana/address.js +167 -0
  67. package/dist/esm/src/solana/index.d.ts +13 -0
  68. package/dist/esm/src/solana/index.js +13 -0
  69. package/dist/esm/src/solana/types.d.ts +206 -0
  70. package/dist/esm/src/solana/types.js +74 -0
  71. package/dist/esm/src/types/base.d.ts +25 -0
  72. package/dist/esm/src/types/events.d.ts +9 -6
  73. package/dist/esm/src/utils/address.d.ts +21 -0
  74. package/dist/esm/src/utils/address.js +45 -0
  75. package/dist/esm/src/utils/builderCode.d.ts +30 -0
  76. package/dist/esm/src/utils/builderCode.js +140 -0
  77. package/dist/esm/src/utils/index.d.ts +1 -0
  78. package/dist/esm/src/utils/index.js +1 -0
  79. package/dist/esm/src/version.d.ts +1 -1
  80. package/dist/esm/src/version.js +1 -1
  81. package/dist/esm/src/wagmi/WagmiEventHandler.d.ts +24 -0
  82. package/dist/esm/src/wagmi/WagmiEventHandler.js +242 -24
  83. package/dist/esm/src/wagmi/types.d.ts +31 -0
  84. package/dist/esm/src/wagmi/utils.d.ts +79 -0
  85. package/dist/esm/src/wagmi/utils.js +211 -0
  86. package/dist/index.umd.min.js +1 -1
  87. package/package.json +20 -4
@@ -57,6 +57,42 @@ Object.defineProperty(exports, "__esModule", { value: true });
57
57
  exports.WagmiEventHandler = void 0;
58
58
  var events_1 = require("../types/events");
59
59
  var logger_1 = require("../logger");
60
+ var utils_1 = require("./utils");
61
+ var builderCode_1 = require("../utils/builderCode");
62
+ /**
63
+ * Built-in transaction fields that could collide with function args.
64
+ * Defined at module level to avoid recreating on every method call.
65
+ */
66
+ var RESERVED_FIELDS = new Set([
67
+ "status",
68
+ "chainId",
69
+ "address",
70
+ "data",
71
+ "to",
72
+ "value",
73
+ "transactionHash",
74
+ "function_name",
75
+ "function_args",
76
+ "builder_codes",
77
+ ]);
78
+ /**
79
+ * Clean up old entries from a Set to prevent memory leaks.
80
+ * Removes oldest entries when size exceeds maxSize.
81
+ *
82
+ * @param set - The Set to clean up
83
+ * @param maxSize - Maximum allowed size before cleanup (default: 1000)
84
+ * @param removeCount - Number of entries to remove (default: 500)
85
+ */
86
+ function cleanupOldEntries(set, maxSize, removeCount) {
87
+ if (maxSize === void 0) { maxSize = 1000; }
88
+ if (removeCount === void 0) { removeCount = 500; }
89
+ if (set.size > maxSize) {
90
+ var entries = Array.from(set);
91
+ for (var i = 0; i < removeCount && i < entries.length; i++) {
92
+ set.delete(entries[i]);
93
+ }
94
+ }
95
+ }
60
96
  var WagmiEventHandler = /** @class */ (function () {
61
97
  function WagmiEventHandler(formoAnalytics, wagmiConfig, queryClient) {
62
98
  this.unsubscribers = [];
@@ -68,15 +104,26 @@ var WagmiEventHandler = /** @class */ (function () {
68
104
  * Key format: `${mutationId}:${status}`
69
105
  */
70
106
  this.processedMutations = new Set();
107
+ /**
108
+ * Track processed query states to prevent duplicate event emissions
109
+ * Key format: `${queryHash}:${status}`
110
+ */
111
+ this.processedQueries = new Set();
112
+ /**
113
+ * Store transaction details from BROADCASTED events for use in CONFIRMED/REVERTED
114
+ * Key: transactionHash, Value: transaction details including the original sender address
115
+ */
116
+ this.pendingTransactions = new Map();
71
117
  this.formo = formoAnalytics;
72
118
  this.wagmiConfig = wagmiConfig;
73
119
  this.queryClient = queryClient;
74
120
  logger_1.logger.info("WagmiEventHandler: Initializing Wagmi integration");
75
121
  // Set up connection/disconnection/chain listeners
76
122
  this.setupConnectionListeners();
77
- // Set up mutation tracking if QueryClient is provided
123
+ // Set up mutation and query tracking if QueryClient is provided
78
124
  if (this.queryClient) {
79
125
  this.setupMutationTracking();
126
+ this.setupQueryTracking();
80
127
  }
81
128
  else {
82
129
  logger_1.logger.warn("WagmiEventHandler: QueryClient not provided, signature and transaction events will not be tracked");
@@ -226,6 +273,131 @@ var WagmiEventHandler = /** @class */ (function () {
226
273
  this.unsubscribers.push(unsubscribe);
227
274
  logger_1.logger.info("WagmiEventHandler: Mutation tracking set up successfully");
228
275
  };
276
+ /**
277
+ * Set up query tracking for transaction confirmations
278
+ * Listens for waitForTransactionReceipt queries to detect CONFIRMED status
279
+ */
280
+ WagmiEventHandler.prototype.setupQueryTracking = function () {
281
+ var _this = this;
282
+ if (!this.queryClient) {
283
+ return;
284
+ }
285
+ logger_1.logger.info("WagmiEventHandler: Setting up query tracking");
286
+ var queryCache = this.queryClient.getQueryCache();
287
+ var unsubscribe = queryCache.subscribe(function (event) {
288
+ _this.handleQueryEvent(event);
289
+ });
290
+ this.unsubscribers.push(unsubscribe);
291
+ logger_1.logger.info("WagmiEventHandler: Query tracking set up successfully");
292
+ };
293
+ /**
294
+ * Handle query cache events (transaction confirmations)
295
+ */
296
+ WagmiEventHandler.prototype.handleQueryEvent = function (event) {
297
+ if (event.type !== "updated") {
298
+ return;
299
+ }
300
+ var query = event.query;
301
+ var queryKey = query.queryKey;
302
+ if (!queryKey || queryKey.length === 0) {
303
+ return;
304
+ }
305
+ var queryType = queryKey[0];
306
+ // Only handle waitForTransactionReceipt queries
307
+ if (queryType !== "waitForTransactionReceipt") {
308
+ return;
309
+ }
310
+ var state = query.state;
311
+ // Extract receipt status early to include in deduplication key
312
+ // This ensures CONFIRMED vs REVERTED outcomes are processed separately
313
+ var receipt = state.data;
314
+ var receiptStatus = receipt === null || receipt === void 0 ? void 0 : receipt.status;
315
+ // Create a unique key for this query state to prevent duplicate processing
316
+ // Include receipt status to distinguish between CONFIRMED and REVERTED outcomes
317
+ var queryStateKey = "".concat(query.queryHash, ":").concat(state.status, ":").concat(receiptStatus || "");
318
+ // Skip if we've already processed this query state
319
+ if (this.processedQueries.has(queryStateKey)) {
320
+ logger_1.logger.debug("WagmiEventHandler: Skipping duplicate query event", {
321
+ queryType: queryType,
322
+ queryHash: query.queryHash,
323
+ status: state.status,
324
+ receiptStatus: receiptStatus,
325
+ });
326
+ return;
327
+ }
328
+ // Mark this query state as processed
329
+ this.processedQueries.add(queryStateKey);
330
+ logger_1.logger.debug("WagmiEventHandler: Query event", {
331
+ queryType: queryType,
332
+ queryHash: query.queryHash,
333
+ status: state.status,
334
+ });
335
+ // Handle transaction receipt queries
336
+ this.handleTransactionReceiptQuery(query);
337
+ // Clean up old processed queries to prevent memory leaks
338
+ cleanupOldEntries(this.processedQueries);
339
+ };
340
+ /**
341
+ * Handle waitForTransactionReceipt query completion
342
+ * Emits CONFIRMED or REVERTED transaction status
343
+ */
344
+ WagmiEventHandler.prototype.handleTransactionReceiptQuery = function (query) {
345
+ var _a;
346
+ if (!this.formo.isAutocaptureEnabled("transaction")) {
347
+ return;
348
+ }
349
+ var state = query.state;
350
+ var queryKey = query.queryKey;
351
+ // Only handle successful queries (transaction confirmed on chain)
352
+ if (state.status !== "success") {
353
+ return;
354
+ }
355
+ // Extract hash and chainId from query key
356
+ // Query key format: ['waitForTransactionReceipt', { hash, chainId, ... }]
357
+ var params = queryKey[1];
358
+ var transactionHash = params === null || params === void 0 ? void 0 : params.hash;
359
+ var chainId = (params === null || params === void 0 ? void 0 : params.chainId) || this.trackingState.lastChainId;
360
+ if (!transactionHash) {
361
+ logger_1.logger.warn("WagmiEventHandler: Transaction receipt query but no hash found");
362
+ return;
363
+ }
364
+ // Retrieve stored transaction details from BROADCASTED event
365
+ // Normalize hash to lowercase for consistent lookup
366
+ var normalizedHash = transactionHash.toLowerCase();
367
+ var pendingTx = this.pendingTransactions.get(normalizedHash);
368
+ // Use the original sender address from BROADCASTED event if available,
369
+ // otherwise fall back to current connected address.
370
+ // This handles wallet switches between broadcast and confirmation.
371
+ var address = (pendingTx === null || pendingTx === void 0 ? void 0 : pendingTx.address) || this.trackingState.lastAddress;
372
+ if (!address) {
373
+ logger_1.logger.warn("WagmiEventHandler: Transaction receipt query but no address available");
374
+ return;
375
+ }
376
+ try {
377
+ // Extract receipt data
378
+ var receipt = state.data;
379
+ // Determine transaction status from receipt
380
+ // receipt.status is 'success' or 'reverted' in viem
381
+ var txStatus = (receipt === null || receipt === void 0 ? void 0 : receipt.status) === "reverted"
382
+ ? events_1.TransactionStatus.REVERTED
383
+ : events_1.TransactionStatus.CONFIRMED;
384
+ logger_1.logger.info("WagmiEventHandler: Tracking transaction confirmation", {
385
+ status: txStatus,
386
+ transactionHash: transactionHash,
387
+ address: address,
388
+ chainId: chainId,
389
+ blockNumber: (_a = receipt === null || receipt === void 0 ? void 0 : receipt.blockNumber) === null || _a === void 0 ? void 0 : _a.toString(),
390
+ });
391
+ this.formo.transaction(__assign(__assign(__assign(__assign(__assign(__assign({ status: txStatus, chainId: chainId || 0, address: address, transactionHash: transactionHash }, ((pendingTx === null || pendingTx === void 0 ? void 0 : pendingTx.data) && { data: pendingTx.data })), ((pendingTx === null || pendingTx === void 0 ? void 0 : pendingTx.to) && { to: pendingTx.to })), ((pendingTx === null || pendingTx === void 0 ? void 0 : pendingTx.value) && { value: pendingTx.value })), ((pendingTx === null || pendingTx === void 0 ? void 0 : pendingTx.function_name) && { function_name: pendingTx.function_name })), ((pendingTx === null || pendingTx === void 0 ? void 0 : pendingTx.function_args) && { function_args: pendingTx.function_args })), ((pendingTx === null || pendingTx === void 0 ? void 0 : pendingTx.builder_codes) && { builder_codes: pendingTx.builder_codes })),
392
+ // Spread function args as additional properties (only colliding keys are prefixed)
393
+ pendingTx === null || pendingTx === void 0 ? void 0 : pendingTx.safeFunctionArgs);
394
+ // Clean up the pending transaction after confirmation
395
+ this.pendingTransactions.delete(normalizedHash);
396
+ }
397
+ catch (error) {
398
+ logger_1.logger.error("WagmiEventHandler: Error handling transaction receipt query:", error);
399
+ }
400
+ };
229
401
  /**
230
402
  * Handle mutation cache events (signatures, transactions)
231
403
  */
@@ -267,14 +439,7 @@ var WagmiEventHandler = /** @class */ (function () {
267
439
  this.handleTransactionMutation(mutationType, mutation);
268
440
  }
269
441
  // Clean up old processed mutations to prevent memory leaks
270
- // Keep only recent mutations (max 1000 entries)
271
- if (this.processedMutations.size > 1000) {
272
- var entries = Array.from(this.processedMutations);
273
- // Remove oldest 500 entries
274
- for (var i = 0; i < 500; i++) {
275
- this.processedMutations.delete(entries[i]);
276
- }
277
- }
442
+ cleanupOldEntries(this.processedMutations);
278
443
  };
279
444
  /**
280
445
  * Handle signature mutations (signMessage, signTypedData)
@@ -340,8 +505,15 @@ var WagmiEventHandler = /** @class */ (function () {
340
505
  var state = mutation.state;
341
506
  var variables = state.variables || {};
342
507
  var chainId = this.trackingState.lastChainId || variables.chainId;
343
- var address = this.trackingState.lastAddress || variables.account || variables.address;
344
- if (!address) {
508
+ // For sendTransaction, user's address is the 'from'
509
+ // For writeContract, variables.address is the contract address, not the user
510
+ // variables.account can be a string address or an Account object with an address property
511
+ var accountValue = variables.account;
512
+ var accountAddress = typeof accountValue === "string"
513
+ ? accountValue
514
+ : accountValue === null || accountValue === void 0 ? void 0 : accountValue.address;
515
+ var userAddress = this.trackingState.lastAddress || accountAddress || variables.from;
516
+ if (!userAddress) {
345
517
  logger_1.logger.warn("WagmiEventHandler: Transaction event but no address available");
346
518
  return;
347
519
  }
@@ -362,18 +534,62 @@ var WagmiEventHandler = /** @class */ (function () {
362
534
  else {
363
535
  return; // Ignore idle state
364
536
  }
365
- // Extract transaction details from variables
366
- var data = variables.data;
367
- var to = variables.to || variables.address;
537
+ // Extract transaction details based on mutation type
538
+ var data = void 0;
539
+ var to = void 0;
540
+ var function_name = void 0;
541
+ var function_args = void 0;
368
542
  var value = (_a = variables.value) === null || _a === void 0 ? void 0 : _a.toString();
369
- logger_1.logger.info("WagmiEventHandler: Tracking transaction event", {
370
- status: status_2,
371
- mutationType: mutationType,
372
- address: address,
373
- chainId: chainId,
374
- transactionHash: transactionHash,
375
- });
376
- this.formo.transaction(__assign(__assign(__assign(__assign({ status: status_2, chainId: chainId || 0, address: address }, (data && { data: data })), (to && { to: to })), (value && { value: value })), (transactionHash && { transactionHash: transactionHash })));
543
+ if (mutationType === "writeContract") {
544
+ // For writeContract, extract function info and encode data
545
+ var abi = variables.abi, fnName = variables.functionName, args = variables.args, contractAddress = variables.address, dataSuffix = variables.dataSuffix;
546
+ to = contractAddress;
547
+ function_name = fnName;
548
+ if (abi && fnName) {
549
+ // Extract function arguments as a name-value map
550
+ function_args = (0, utils_1.extractFunctionArgs)(abi, fnName, args);
551
+ // Encode the function data synchronously if viem is available
552
+ var encodedData = (0, utils_1.encodeWriteContractData)(abi, fnName, args);
553
+ if (encodedData) {
554
+ // Include dataSuffix (ERC-8021 builder code) so extractBuilderCodes sees full calldata
555
+ data = (0, utils_1.concatCalldataWithSuffix)(encodedData, dataSuffix);
556
+ logger_1.logger.debug("WagmiEventHandler: Encoded writeContract data", data.substring(0, 10));
557
+ }
558
+ }
559
+ }
560
+ else {
561
+ // For sendTransaction, use variables directly
562
+ // Only data is available, function_name and function_args are not sent
563
+ data = variables.data;
564
+ to = variables.to;
565
+ }
566
+ // Extract builder codes from transaction data (ERC-8021)
567
+ var builder_codes = (0, builderCode_1.extractBuilderCodes)(data);
568
+ logger_1.logger.info("WagmiEventHandler: Tracking transaction event", __assign({ status: status_2, mutationType: mutationType, address: userAddress, chainId: chainId, transactionHash: transactionHash, function_name: function_name }, (builder_codes && { builder_codes: builder_codes })));
569
+ // Build safeFunctionArgs with collision handling and struct flattening
570
+ var safeFunctionArgs = (0, utils_1.buildSafeFunctionArgs)(function_args, RESERVED_FIELDS);
571
+ // Store transaction details for BROADCASTED status to use in CONFIRMED/REVERTED
572
+ // Normalize hash to lowercase for consistent lookup
573
+ // Include the sender address to handle wallet switches between broadcast and confirmation
574
+ if (status_2 === events_1.TransactionStatus.BROADCASTED && transactionHash) {
575
+ var normalizedHash = transactionHash.toLowerCase();
576
+ var txDetails = __assign(__assign(__assign(__assign(__assign(__assign(__assign({ address: userAddress }, (data && { data: data })), (to && { to: to })), (value && { value: value })), (function_name && { function_name: function_name })), (function_args && { function_args: function_args })), (builder_codes && { builder_codes: builder_codes })), (safeFunctionArgs && { safeFunctionArgs: safeFunctionArgs }));
577
+ this.pendingTransactions.set(normalizedHash, txDetails);
578
+ logger_1.logger.debug("WagmiEventHandler: Stored pending transaction for confirmation", {
579
+ transactionHash: normalizedHash,
580
+ });
581
+ // Clean up old pending transactions to prevent memory leaks (keep max 100)
582
+ // Remove oldest 50 entries when limit exceeded to handle high-throughput scenarios
583
+ if (this.pendingTransactions.size > 100) {
584
+ var keys = Array.from(this.pendingTransactions.keys());
585
+ for (var i = 0; i < 50 && i < keys.length; i++) {
586
+ this.pendingTransactions.delete(keys[i]);
587
+ }
588
+ }
589
+ }
590
+ this.formo.transaction(__assign(__assign(__assign(__assign(__assign(__assign(__assign({ status: status_2, chainId: chainId || 0, address: userAddress }, (data && { data: data })), (to && { to: to })), (value && { value: value })), (transactionHash && { transactionHash: transactionHash })), (function_name && { function_name: function_name })), (function_args && { function_args: function_args })), (builder_codes && { builder_codes: builder_codes })),
591
+ // Spread function args as additional properties (only colliding keys are prefixed)
592
+ safeFunctionArgs);
377
593
  }
378
594
  catch (error) {
379
595
  logger_1.logger.error("WagmiEventHandler: Error handling transaction mutation:", error);
@@ -429,7 +645,7 @@ var WagmiEventHandler = /** @class */ (function () {
429
645
  * Clean up all subscriptions
430
646
  */
431
647
  WagmiEventHandler.prototype.cleanup = function () {
432
- logger_1.logger.info("WagmiEventHandler: Cleaning up subscriptions");
648
+ logger_1.logger.debug("WagmiEventHandler: Cleaning up subscriptions");
433
649
  for (var _i = 0, _a = this.unsubscribers; _i < _a.length; _i++) {
434
650
  var unsubscribe = _a[_i];
435
651
  try {
@@ -441,7 +657,9 @@ var WagmiEventHandler = /** @class */ (function () {
441
657
  }
442
658
  this.unsubscribers = [];
443
659
  this.processedMutations.clear();
444
- logger_1.logger.info("WagmiEventHandler: Cleanup complete");
660
+ this.processedQueries.clear();
661
+ this.pendingTransactions.clear();
662
+ logger_1.logger.debug("WagmiEventHandler: Cleanup complete");
445
663
  };
446
664
  return WagmiEventHandler;
447
665
  }());
@@ -89,11 +89,42 @@ export interface MutationCacheEvent {
89
89
  export interface MutationCache {
90
90
  subscribe(listener: (event: MutationCacheEvent) => void): () => void;
91
91
  }
92
+ /**
93
+ * React Query query state
94
+ */
95
+ export interface QueryState {
96
+ status: 'pending' | 'success' | 'error';
97
+ data?: any;
98
+ error?: Error | null;
99
+ fetchStatus: 'fetching' | 'paused' | 'idle';
100
+ }
101
+ /**
102
+ * React Query query object
103
+ */
104
+ export interface Query {
105
+ state: QueryState;
106
+ queryKey: readonly unknown[];
107
+ queryHash: string;
108
+ }
109
+ /**
110
+ * React Query query cache event
111
+ */
112
+ export interface QueryCacheEvent {
113
+ type: 'added' | 'removed' | 'updated';
114
+ query: Query;
115
+ }
116
+ /**
117
+ * React Query QueryCache interface
118
+ */
119
+ export interface QueryCache {
120
+ subscribe(listener: (event: QueryCacheEvent) => void): () => void;
121
+ }
92
122
  /**
93
123
  * React Query QueryClient interface
94
124
  */
95
125
  export interface QueryClient {
96
126
  getMutationCache(): MutationCache;
127
+ getQueryCache(): QueryCache;
97
128
  }
98
129
  /**
99
130
  * Unsubscribe function returned by subscriptions
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Utility functions for Wagmi event handling
3
+ *
4
+ * Provides ABI encoding utilities for extracting transaction data from
5
+ * writeContract mutations without requiring viem as a direct dependency.
6
+ */
7
+ /**
8
+ * Flatten a nested object into a flat object with underscore-separated keys.
9
+ * Only leaf values (primitives) are included; intermediate objects are not.
10
+ *
11
+ * Example:
12
+ * Input: { o: { x: "100", inner: { a: "42", b: "0xRecipient" } } }
13
+ * Output: { o_x: "100", o_inner_a: "42", o_inner_b: "0xRecipient" }
14
+ *
15
+ * @param obj - The object to flatten
16
+ * @param prefix - Optional prefix for keys (used in recursion)
17
+ * @returns A flat object with underscore-separated keys
18
+ */
19
+ export declare function flattenObject(obj: Record<string, unknown>, prefix?: string): Record<string, unknown>;
20
+ /**
21
+ * ABI function item type
22
+ */
23
+ export interface AbiItem {
24
+ type: string;
25
+ name?: string;
26
+ inputs?: AbiInput[];
27
+ outputs?: AbiOutput[];
28
+ stateMutability?: string;
29
+ }
30
+ export interface AbiInput {
31
+ name: string;
32
+ type: string;
33
+ indexed?: boolean;
34
+ components?: AbiInput[];
35
+ internalType?: string;
36
+ }
37
+ export interface AbiOutput {
38
+ name: string;
39
+ type: string;
40
+ components?: AbiOutput[];
41
+ internalType?: string;
42
+ }
43
+ /**
44
+ * Concatenate encoded calldata with an optional ERC-8021 dataSuffix (e.g. builder codes).
45
+ * Uses viem's concatHex when available for correct hex handling.
46
+ */
47
+ export declare function concatCalldataWithSuffix(encodedData: string, dataSuffix: string | undefined): string;
48
+ /**
49
+ * Encode writeContract data using viem's encodeFunctionData
50
+ *
51
+ * @param abi - The contract ABI
52
+ * @param functionName - The function name to encode
53
+ * @param args - The function arguments
54
+ * @returns The encoded calldata or undefined if encoding fails
55
+ */
56
+ export declare function encodeWriteContractData(abi: AbiItem[], functionName: string, args?: unknown[]): string | undefined;
57
+ /**
58
+ * Extract function arguments as a name-value map from ABI and args array
59
+ *
60
+ * @param abi - The contract ABI
61
+ * @param functionName - The function name
62
+ * @param args - The function arguments array
63
+ * @returns A map of argument names to values, or undefined if extraction fails
64
+ */
65
+ export declare function extractFunctionArgs(abi: AbiItem[], functionName: string, args?: unknown[]): Record<string, unknown> | undefined;
66
+ /**
67
+ * Build safe function args with collision handling and struct flattening.
68
+ *
69
+ * This function:
70
+ * 1. Prefixes top-level args that collide with reserved fields (e.g., 'to' -> 'arg_to')
71
+ * 2. Flattens nested struct values for easier querying (e.g., order.maker -> order_maker)
72
+ * 3. Skips flattened keys that would collide with existing top-level args
73
+ *
74
+ * @param functionArgs - The extracted function arguments
75
+ * @param reservedFields - Set of reserved field names that need prefixing
76
+ * @returns Safe function args object, or undefined if input is undefined
77
+ */
78
+ export declare function buildSafeFunctionArgs(functionArgs: Record<string, unknown> | undefined, reservedFields: Set<string>): Record<string, unknown> | undefined;
79
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ /**
3
+ * Utility functions for Wagmi event handling
4
+ *
5
+ * Provides ABI encoding utilities for extracting transaction data from
6
+ * writeContract mutations without requiring viem as a direct dependency.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.flattenObject = flattenObject;
10
+ exports.concatCalldataWithSuffix = concatCalldataWithSuffix;
11
+ exports.encodeWriteContractData = encodeWriteContractData;
12
+ exports.extractFunctionArgs = extractFunctionArgs;
13
+ exports.buildSafeFunctionArgs = buildSafeFunctionArgs;
14
+ var logger_1 = require("../logger");
15
+ /**
16
+ * Flatten a nested object into a flat object with underscore-separated keys.
17
+ * Only leaf values (primitives) are included; intermediate objects are not.
18
+ *
19
+ * Example:
20
+ * Input: { o: { x: "100", inner: { a: "42", b: "0xRecipient" } } }
21
+ * Output: { o_x: "100", o_inner_a: "42", o_inner_b: "0xRecipient" }
22
+ *
23
+ * @param obj - The object to flatten
24
+ * @param prefix - Optional prefix for keys (used in recursion)
25
+ * @returns A flat object with underscore-separated keys
26
+ */
27
+ function flattenObject(obj, prefix) {
28
+ if (prefix === void 0) { prefix = ""; }
29
+ var result = {};
30
+ for (var _i = 0, _a = Object.entries(obj); _i < _a.length; _i++) {
31
+ var _b = _a[_i], key = _b[0], value = _b[1];
32
+ var newKey = prefix ? "".concat(prefix, "_").concat(key) : key;
33
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
34
+ // Recursively flatten nested objects
35
+ var nested = flattenObject(value, newKey);
36
+ Object.assign(result, nested);
37
+ }
38
+ else {
39
+ // Leaf value (primitive or array) - add directly
40
+ result[newKey] = value;
41
+ }
42
+ }
43
+ return result;
44
+ }
45
+ /**
46
+ * Recursively convert all BigInt values to strings for JSON serialization
47
+ * Handles nested objects, arrays, and deeply nested structures (e.g., Solidity structs)
48
+ *
49
+ * @param value - The value to convert
50
+ * @returns The value with all BigInt converted to strings
51
+ */
52
+ function convertBigIntToString(value) {
53
+ if (typeof value === "bigint") {
54
+ return value.toString();
55
+ }
56
+ if (Array.isArray(value)) {
57
+ return value.map(convertBigIntToString);
58
+ }
59
+ if (value !== null && typeof value === "object") {
60
+ var result = {};
61
+ for (var _i = 0, _a = Object.entries(value); _i < _a.length; _i++) {
62
+ var _b = _a[_i], key = _b[0], val = _b[1];
63
+ result[key] = convertBigIntToString(val);
64
+ }
65
+ return result;
66
+ }
67
+ return value;
68
+ }
69
+ // Cached viem module reference
70
+ var viemModule;
71
+ /**
72
+ * Try to load viem synchronously via require
73
+ * Returns null if viem is not available
74
+ */
75
+ function tryLoadViem() {
76
+ if (viemModule !== undefined) {
77
+ return viemModule;
78
+ }
79
+ try {
80
+ // Use require to load viem synchronously
81
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
82
+ var viem = require("viem");
83
+ if (viem === null || viem === void 0 ? void 0 : viem.encodeFunctionData) {
84
+ viemModule = {
85
+ encodeFunctionData: viem.encodeFunctionData,
86
+ concatHex: viem.concatHex,
87
+ };
88
+ return viemModule;
89
+ }
90
+ }
91
+ catch (_a) {
92
+ // viem is not available
93
+ }
94
+ viemModule = null;
95
+ return null;
96
+ }
97
+ /**
98
+ * Concatenate encoded calldata with an optional ERC-8021 dataSuffix (e.g. builder codes).
99
+ * Uses viem's concatHex when available for correct hex handling.
100
+ */
101
+ function concatCalldataWithSuffix(encodedData, dataSuffix) {
102
+ if (!dataSuffix || dataSuffix === "0x") {
103
+ return encodedData;
104
+ }
105
+ var viem = tryLoadViem();
106
+ if (viem === null || viem === void 0 ? void 0 : viem.concatHex) {
107
+ return viem.concatHex([
108
+ encodedData,
109
+ dataSuffix,
110
+ ]);
111
+ }
112
+ var suffixHex = dataSuffix.replace(/^0x/i, "");
113
+ return "".concat(encodedData).concat(suffixHex);
114
+ }
115
+ /**
116
+ * Encode writeContract data using viem's encodeFunctionData
117
+ *
118
+ * @param abi - The contract ABI
119
+ * @param functionName - The function name to encode
120
+ * @param args - The function arguments
121
+ * @returns The encoded calldata or undefined if encoding fails
122
+ */
123
+ function encodeWriteContractData(abi, functionName, args) {
124
+ try {
125
+ var viem = tryLoadViem();
126
+ if (!viem) {
127
+ logger_1.logger.debug("WagmiEventHandler: viem not available, cannot encode function data");
128
+ return undefined;
129
+ }
130
+ var data = viem.encodeFunctionData({
131
+ abi: abi,
132
+ functionName: functionName,
133
+ args: args || [],
134
+ });
135
+ return data;
136
+ }
137
+ catch (error) {
138
+ logger_1.logger.warn("WagmiEventHandler: Failed to encode function data", error);
139
+ return undefined;
140
+ }
141
+ }
142
+ /**
143
+ * Extract function arguments as a name-value map from ABI and args array
144
+ *
145
+ * @param abi - The contract ABI
146
+ * @param functionName - The function name
147
+ * @param args - The function arguments array
148
+ * @returns A map of argument names to values, or undefined if extraction fails
149
+ */
150
+ function extractFunctionArgs(abi, functionName, args) {
151
+ if (!abi || !functionName || !args || !Array.isArray(args)) {
152
+ return undefined;
153
+ }
154
+ try {
155
+ // Find the function in the ABI
156
+ var abiItem = abi.find(function (item) { return item.type === "function" && item.name === functionName; });
157
+ if (!(abiItem === null || abiItem === void 0 ? void 0 : abiItem.inputs) || !Array.isArray(abiItem.inputs)) {
158
+ return undefined;
159
+ }
160
+ var result_1 = {};
161
+ abiItem.inputs.forEach(function (input, index) {
162
+ if (index < args.length) {
163
+ var argValue = args[index];
164
+ var argName = input.name || "arg".concat(index);
165
+ // Recursively convert BigInt to string for JSON serialization
166
+ // Handles: direct BigInt, arrays with BigInt, nested objects/structs with BigInt
167
+ result_1[argName] = convertBigIntToString(argValue);
168
+ }
169
+ });
170
+ return result_1;
171
+ }
172
+ catch (error) {
173
+ logger_1.logger.warn("WagmiEventHandler: Failed to extract function args", error);
174
+ return undefined;
175
+ }
176
+ }
177
+ /**
178
+ * Build safe function args with collision handling and struct flattening.
179
+ *
180
+ * This function:
181
+ * 1. Prefixes top-level args that collide with reserved fields (e.g., 'to' -> 'arg_to')
182
+ * 2. Flattens nested struct values for easier querying (e.g., order.maker -> order_maker)
183
+ * 3. Skips flattened keys that would collide with existing top-level args
184
+ *
185
+ * @param functionArgs - The extracted function arguments
186
+ * @param reservedFields - Set of reserved field names that need prefixing
187
+ * @returns Safe function args object, or undefined if input is undefined
188
+ */
189
+ function buildSafeFunctionArgs(functionArgs, reservedFields) {
190
+ if (!functionArgs) {
191
+ return undefined;
192
+ }
193
+ var result = {};
194
+ for (var _i = 0, _a = Object.entries(functionArgs); _i < _a.length; _i++) {
195
+ var _b = _a[_i], key = _b[0], val = _b[1];
196
+ var safeKey = reservedFields.has(key) ? "arg_".concat(key) : key;
197
+ result[safeKey] = val;
198
+ // If the value is a nested object (struct), flatten it
199
+ // Skip flattened keys that would overwrite existing top-level args
200
+ if (val !== null && typeof val === "object" && !Array.isArray(val)) {
201
+ var flattened = flattenObject(val, safeKey);
202
+ for (var _c = 0, _d = Object.entries(flattened); _c < _d.length; _c++) {
203
+ var _e = _d[_c], flatKey = _e[0], flatVal = _e[1];
204
+ if (!(flatKey in result)) {
205
+ result[flatKey] = flatVal;
206
+ }
207
+ else {
208
+ logger_1.logger.debug("WagmiEventHandler: Skipping flattened key collision", {
209
+ flatKey: flatKey,
210
+ existingValue: result[flatKey],
211
+ });
212
+ }
213
+ }
214
+ }
215
+ }
216
+ return result;
217
+ }
218
+ //# sourceMappingURL=utils.js.map