@formo/analytics 1.25.0 → 1.27.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 (192) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +6 -4
  3. package/dist/cjs/src/FormoAnalytics.d.ts +27 -15
  4. package/dist/cjs/src/FormoAnalytics.js +198 -257
  5. package/dist/cjs/src/FormoAnalyticsProvider.js +71 -13
  6. package/dist/{esm/src/lib/consent.d.ts → cjs/src/consent/index.d.ts} +1 -1
  7. package/dist/cjs/src/{lib/consent.js → consent/index.js} +1 -1
  8. package/dist/cjs/src/constants/base.d.ts +0 -2
  9. package/dist/cjs/src/constants/base.js +3 -3
  10. package/dist/cjs/src/constants/config.js +1 -1
  11. package/dist/cjs/src/{lib/event → event}/EventFactory.d.ts +2 -2
  12. package/dist/cjs/src/{lib/event → event}/EventFactory.js +9 -9
  13. package/dist/cjs/src/{lib/event → event}/EventManager.d.ts +1 -1
  14. package/dist/cjs/src/{lib/event → event}/EventManager.js +1 -1
  15. package/dist/cjs/src/{lib/event → event}/type.d.ts +1 -1
  16. package/dist/cjs/src/{lib/event → event}/utils.d.ts +1 -1
  17. package/dist/cjs/src/{lib/event → event}/utils.js +1 -1
  18. package/dist/cjs/src/fetch/index.d.ts +11 -0
  19. package/dist/cjs/src/fetch/index.js +126 -0
  20. package/dist/cjs/src/provider/detection.d.ts +58 -0
  21. package/dist/cjs/src/provider/detection.js +103 -0
  22. package/dist/cjs/src/provider/index.d.ts +6 -0
  23. package/dist/cjs/src/provider/index.js +11 -0
  24. package/dist/cjs/src/queue/EventQueue.d.ts +56 -0
  25. package/dist/cjs/src/{lib/queue → queue}/EventQueue.js +161 -52
  26. package/dist/{esm/src/lib → cjs/src}/queue/type.d.ts +1 -1
  27. package/dist/cjs/src/session/index.d.ts +91 -0
  28. package/dist/cjs/src/session/index.js +126 -0
  29. package/dist/cjs/src/{lib/storage → storage}/built-in/blueprint.js +1 -1
  30. package/dist/cjs/src/types/base.d.ts +35 -1
  31. package/dist/cjs/src/types/events.d.ts +5 -3
  32. package/dist/cjs/src/validators/object.js +0 -2
  33. package/dist/cjs/src/version.d.ts +1 -1
  34. package/dist/cjs/src/version.js +1 -1
  35. package/dist/cjs/src/wagmi/WagmiEventHandler.d.ts +93 -0
  36. package/dist/cjs/src/wagmi/WagmiEventHandler.js +669 -0
  37. package/dist/cjs/src/wagmi/index.d.ts +9 -0
  38. package/dist/cjs/src/wagmi/index.js +12 -0
  39. package/dist/cjs/src/wagmi/types.d.ts +146 -0
  40. package/dist/cjs/src/wagmi/types.js +10 -0
  41. package/dist/cjs/src/wagmi/utils.d.ts +74 -0
  42. package/dist/cjs/src/wagmi/utils.js +198 -0
  43. package/dist/esm/src/FormoAnalytics.d.ts +27 -15
  44. package/dist/esm/src/FormoAnalytics.js +88 -147
  45. package/dist/esm/src/FormoAnalyticsProvider.js +68 -10
  46. package/dist/{cjs/src/lib/consent.d.ts → esm/src/consent/index.d.ts} +1 -1
  47. package/dist/esm/src/{lib/consent.js → consent/index.js} +1 -1
  48. package/dist/esm/src/constants/base.d.ts +0 -2
  49. package/dist/esm/src/constants/base.js +2 -2
  50. package/dist/esm/src/constants/config.js +1 -1
  51. package/dist/esm/src/{lib/event → event}/EventFactory.d.ts +2 -2
  52. package/dist/esm/src/{lib/event → event}/EventFactory.js +9 -9
  53. package/dist/esm/src/{lib/event → event}/EventManager.d.ts +1 -1
  54. package/dist/esm/src/{lib/event → event}/EventManager.js +1 -1
  55. package/dist/esm/src/{lib/event → event}/type.d.ts +1 -1
  56. package/dist/esm/src/{lib/event → event}/utils.d.ts +1 -1
  57. package/dist/esm/src/{lib/event → event}/utils.js +1 -1
  58. package/dist/esm/src/fetch/index.d.ts +11 -0
  59. package/dist/esm/src/fetch/index.js +124 -0
  60. package/dist/esm/src/provider/detection.d.ts +58 -0
  61. package/dist/esm/src/provider/detection.js +98 -0
  62. package/dist/esm/src/provider/index.d.ts +6 -0
  63. package/dist/esm/src/provider/index.js +5 -0
  64. package/dist/esm/src/queue/EventQueue.d.ts +56 -0
  65. package/dist/esm/src/{lib/queue → queue}/EventQueue.js +161 -52
  66. package/dist/{cjs/src/lib → esm/src}/queue/type.d.ts +1 -1
  67. package/dist/esm/src/session/index.d.ts +91 -0
  68. package/dist/esm/src/session/index.js +123 -0
  69. package/dist/esm/src/{lib/storage → storage}/built-in/blueprint.js +1 -1
  70. package/dist/esm/src/types/base.d.ts +35 -1
  71. package/dist/esm/src/types/events.d.ts +5 -3
  72. package/dist/esm/src/validators/object.js +0 -2
  73. package/dist/esm/src/version.d.ts +1 -1
  74. package/dist/esm/src/version.js +1 -1
  75. package/dist/esm/src/wagmi/WagmiEventHandler.d.ts +93 -0
  76. package/dist/esm/src/wagmi/WagmiEventHandler.js +666 -0
  77. package/dist/esm/src/wagmi/index.d.ts +9 -0
  78. package/dist/esm/src/wagmi/index.js +8 -0
  79. package/dist/esm/src/wagmi/types.d.ts +146 -0
  80. package/dist/esm/src/wagmi/types.js +9 -0
  81. package/dist/esm/src/wagmi/utils.d.ts +74 -0
  82. package/dist/esm/src/wagmi/utils.js +192 -0
  83. package/dist/index.umd.min.js +1 -1
  84. package/package.json +23 -4
  85. package/dist/cjs/src/lib/fetch.d.ts +0 -3
  86. package/dist/cjs/src/lib/fetch.js +0 -8
  87. package/dist/cjs/src/lib/index.d.ts +0 -7
  88. package/dist/cjs/src/lib/index.js +0 -28
  89. package/dist/cjs/src/lib/queue/EventQueue.d.ts +0 -34
  90. package/dist/esm/src/lib/fetch.d.ts +0 -3
  91. package/dist/esm/src/lib/fetch.js +0 -3
  92. package/dist/esm/src/lib/index.d.ts +0 -7
  93. package/dist/esm/src/lib/index.js +0 -7
  94. package/dist/esm/src/lib/queue/EventQueue.d.ts +0 -34
  95. /package/dist/cjs/src/{lib/browser → browser}/browsers.d.ts +0 -0
  96. /package/dist/cjs/src/{lib/browser → browser}/browsers.js +0 -0
  97. /package/dist/cjs/src/{lib/event → event}/constants.d.ts +0 -0
  98. /package/dist/cjs/src/{lib/event → event}/constants.js +0 -0
  99. /package/dist/cjs/src/{lib/event → event}/index.d.ts +0 -0
  100. /package/dist/cjs/src/{lib/event → event}/index.js +0 -0
  101. /package/dist/cjs/src/{lib/event → event}/type.js +0 -0
  102. /package/dist/cjs/src/{lib/logger → logger}/Logger.d.ts +0 -0
  103. /package/dist/cjs/src/{lib/logger → logger}/Logger.js +0 -0
  104. /package/dist/cjs/src/{lib/logger → logger}/index.d.ts +0 -0
  105. /package/dist/cjs/src/{lib/logger → logger}/index.js +0 -0
  106. /package/dist/cjs/src/{lib/logger → logger}/type.d.ts +0 -0
  107. /package/dist/cjs/src/{lib/logger → logger}/type.js +0 -0
  108. /package/dist/cjs/src/{lib/queue → queue}/index.d.ts +0 -0
  109. /package/dist/cjs/src/{lib/queue → queue}/index.js +0 -0
  110. /package/dist/cjs/src/{lib/queue → queue}/type.js +0 -0
  111. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_curry1.d.ts +0 -0
  112. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_curry1.js +0 -0
  113. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_curry2.d.ts +0 -0
  114. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_curry2.js +0 -0
  115. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_curry3.d.ts +0 -0
  116. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_curry3.js +0 -0
  117. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_has.d.ts +0 -0
  118. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_has.js +0 -0
  119. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_isObject.d.ts +0 -0
  120. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_isObject.js +0 -0
  121. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_isPlaceholder.d.ts +0 -0
  122. /package/dist/cjs/src/{lib/ramda → ramda}/internal/_isPlaceholder.js +0 -0
  123. /package/dist/cjs/src/{lib/ramda → ramda}/mergeDeepRight.d.ts +0 -0
  124. /package/dist/cjs/src/{lib/ramda → ramda}/mergeDeepRight.js +0 -0
  125. /package/dist/cjs/src/{lib/ramda → ramda}/mergeDeepWithKey.d.ts +0 -0
  126. /package/dist/cjs/src/{lib/ramda → ramda}/mergeDeepWithKey.js +0 -0
  127. /package/dist/cjs/src/{lib/ramda → ramda}/mergeWithKey.d.ts +0 -0
  128. /package/dist/cjs/src/{lib/ramda → ramda}/mergeWithKey.js +0 -0
  129. /package/dist/cjs/src/{lib/storage → storage}/StorageManager.d.ts +0 -0
  130. /package/dist/cjs/src/{lib/storage → storage}/StorageManager.js +0 -0
  131. /package/dist/cjs/src/{lib/storage → storage}/built-in/blueprint.d.ts +0 -0
  132. /package/dist/cjs/src/{lib/storage → storage}/built-in/cookie.d.ts +0 -0
  133. /package/dist/cjs/src/{lib/storage → storage}/built-in/cookie.js +0 -0
  134. /package/dist/cjs/src/{lib/storage → storage}/built-in/memory.d.ts +0 -0
  135. /package/dist/cjs/src/{lib/storage → storage}/built-in/memory.js +0 -0
  136. /package/dist/cjs/src/{lib/storage → storage}/built-in/web.d.ts +0 -0
  137. /package/dist/cjs/src/{lib/storage → storage}/built-in/web.js +0 -0
  138. /package/dist/cjs/src/{lib/storage → storage}/constant.d.ts +0 -0
  139. /package/dist/cjs/src/{lib/storage → storage}/constant.js +0 -0
  140. /package/dist/cjs/src/{lib/storage → storage}/index.d.ts +0 -0
  141. /package/dist/cjs/src/{lib/storage → storage}/index.js +0 -0
  142. /package/dist/cjs/src/{lib/storage → storage}/type.d.ts +0 -0
  143. /package/dist/cjs/src/{lib/storage → storage}/type.js +0 -0
  144. /package/dist/esm/src/{lib/browser → browser}/browsers.d.ts +0 -0
  145. /package/dist/esm/src/{lib/browser → browser}/browsers.js +0 -0
  146. /package/dist/esm/src/{lib/event → event}/constants.d.ts +0 -0
  147. /package/dist/esm/src/{lib/event → event}/constants.js +0 -0
  148. /package/dist/esm/src/{lib/event → event}/index.d.ts +0 -0
  149. /package/dist/esm/src/{lib/event → event}/index.js +0 -0
  150. /package/dist/esm/src/{lib/event → event}/type.js +0 -0
  151. /package/dist/esm/src/{lib/logger → logger}/Logger.d.ts +0 -0
  152. /package/dist/esm/src/{lib/logger → logger}/Logger.js +0 -0
  153. /package/dist/esm/src/{lib/logger → logger}/index.d.ts +0 -0
  154. /package/dist/esm/src/{lib/logger → logger}/index.js +0 -0
  155. /package/dist/esm/src/{lib/logger → logger}/type.d.ts +0 -0
  156. /package/dist/esm/src/{lib/logger → logger}/type.js +0 -0
  157. /package/dist/esm/src/{lib/queue → queue}/index.d.ts +0 -0
  158. /package/dist/esm/src/{lib/queue → queue}/index.js +0 -0
  159. /package/dist/esm/src/{lib/queue → queue}/type.js +0 -0
  160. /package/dist/esm/src/{lib/ramda → ramda}/internal/_curry1.d.ts +0 -0
  161. /package/dist/esm/src/{lib/ramda → ramda}/internal/_curry1.js +0 -0
  162. /package/dist/esm/src/{lib/ramda → ramda}/internal/_curry2.d.ts +0 -0
  163. /package/dist/esm/src/{lib/ramda → ramda}/internal/_curry2.js +0 -0
  164. /package/dist/esm/src/{lib/ramda → ramda}/internal/_curry3.d.ts +0 -0
  165. /package/dist/esm/src/{lib/ramda → ramda}/internal/_curry3.js +0 -0
  166. /package/dist/esm/src/{lib/ramda → ramda}/internal/_has.d.ts +0 -0
  167. /package/dist/esm/src/{lib/ramda → ramda}/internal/_has.js +0 -0
  168. /package/dist/esm/src/{lib/ramda → ramda}/internal/_isObject.d.ts +0 -0
  169. /package/dist/esm/src/{lib/ramda → ramda}/internal/_isObject.js +0 -0
  170. /package/dist/esm/src/{lib/ramda → ramda}/internal/_isPlaceholder.d.ts +0 -0
  171. /package/dist/esm/src/{lib/ramda → ramda}/internal/_isPlaceholder.js +0 -0
  172. /package/dist/esm/src/{lib/ramda → ramda}/mergeDeepRight.d.ts +0 -0
  173. /package/dist/esm/src/{lib/ramda → ramda}/mergeDeepRight.js +0 -0
  174. /package/dist/esm/src/{lib/ramda → ramda}/mergeDeepWithKey.d.ts +0 -0
  175. /package/dist/esm/src/{lib/ramda → ramda}/mergeDeepWithKey.js +0 -0
  176. /package/dist/esm/src/{lib/ramda → ramda}/mergeWithKey.d.ts +0 -0
  177. /package/dist/esm/src/{lib/ramda → ramda}/mergeWithKey.js +0 -0
  178. /package/dist/esm/src/{lib/storage → storage}/StorageManager.d.ts +0 -0
  179. /package/dist/esm/src/{lib/storage → storage}/StorageManager.js +0 -0
  180. /package/dist/esm/src/{lib/storage → storage}/built-in/blueprint.d.ts +0 -0
  181. /package/dist/esm/src/{lib/storage → storage}/built-in/cookie.d.ts +0 -0
  182. /package/dist/esm/src/{lib/storage → storage}/built-in/cookie.js +0 -0
  183. /package/dist/esm/src/{lib/storage → storage}/built-in/memory.d.ts +0 -0
  184. /package/dist/esm/src/{lib/storage → storage}/built-in/memory.js +0 -0
  185. /package/dist/esm/src/{lib/storage → storage}/built-in/web.d.ts +0 -0
  186. /package/dist/esm/src/{lib/storage → storage}/built-in/web.js +0 -0
  187. /package/dist/esm/src/{lib/storage → storage}/constant.d.ts +0 -0
  188. /package/dist/esm/src/{lib/storage → storage}/constant.js +0 -0
  189. /package/dist/esm/src/{lib/storage → storage}/index.d.ts +0 -0
  190. /package/dist/esm/src/{lib/storage → storage}/index.js +0 -0
  191. /package/dist/esm/src/{lib/storage → storage}/type.d.ts +0 -0
  192. /package/dist/esm/src/{lib/storage → storage}/type.js +0 -0
@@ -0,0 +1,669 @@
1
+ "use strict";
2
+ /**
3
+ * WagmiEventHandler
4
+ *
5
+ * Handles wallet event tracking by hooking into Wagmi v2's config.subscribe()
6
+ * and TanStack Query's MutationCache. This replaces the EIP-1193 provider
7
+ * wrapping approach when Wagmi mode is enabled.
8
+ */
9
+ var __assign = (this && this.__assign) || function () {
10
+ __assign = Object.assign || function(t) {
11
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
12
+ s = arguments[i];
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
14
+ t[p] = s[p];
15
+ }
16
+ return t;
17
+ };
18
+ return __assign.apply(this, arguments);
19
+ };
20
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
21
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
22
+ return new (P || (P = Promise))(function (resolve, reject) {
23
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
24
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
25
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
26
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
27
+ });
28
+ };
29
+ var __generator = (this && this.__generator) || function (thisArg, body) {
30
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
31
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
32
+ function verb(n) { return function (v) { return step([n, v]); }; }
33
+ function step(op) {
34
+ if (f) throw new TypeError("Generator is already executing.");
35
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
36
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
37
+ if (y = 0, t) op = [op[0] & 2, t.value];
38
+ switch (op[0]) {
39
+ case 0: case 1: t = op; break;
40
+ case 4: _.label++; return { value: op[1], done: false };
41
+ case 5: _.label++; y = op[1]; op = [0]; continue;
42
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
43
+ default:
44
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
45
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
46
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
47
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
48
+ if (t[2]) _.ops.pop();
49
+ _.trys.pop(); continue;
50
+ }
51
+ op = body.call(thisArg, _);
52
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
53
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
54
+ }
55
+ };
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ exports.WagmiEventHandler = void 0;
58
+ var events_1 = require("../types/events");
59
+ var logger_1 = require("../logger");
60
+ var utils_1 = require("./utils");
61
+ /**
62
+ * Built-in transaction fields that could collide with function args.
63
+ * Defined at module level to avoid recreating on every method call.
64
+ */
65
+ var RESERVED_FIELDS = new Set([
66
+ "status",
67
+ "chainId",
68
+ "address",
69
+ "data",
70
+ "to",
71
+ "value",
72
+ "transactionHash",
73
+ "function_name",
74
+ "function_args",
75
+ ]);
76
+ /**
77
+ * Clean up old entries from a Set to prevent memory leaks.
78
+ * Removes oldest entries when size exceeds maxSize.
79
+ *
80
+ * @param set - The Set to clean up
81
+ * @param maxSize - Maximum allowed size before cleanup (default: 1000)
82
+ * @param removeCount - Number of entries to remove (default: 500)
83
+ */
84
+ function cleanupOldEntries(set, maxSize, removeCount) {
85
+ if (maxSize === void 0) { maxSize = 1000; }
86
+ if (removeCount === void 0) { removeCount = 500; }
87
+ if (set.size > maxSize) {
88
+ var entries = Array.from(set);
89
+ for (var i = 0; i < removeCount && i < entries.length; i++) {
90
+ set.delete(entries[i]);
91
+ }
92
+ }
93
+ }
94
+ var WagmiEventHandler = /** @class */ (function () {
95
+ function WagmiEventHandler(formoAnalytics, wagmiConfig, queryClient) {
96
+ this.unsubscribers = [];
97
+ this.trackingState = {
98
+ isProcessing: false,
99
+ };
100
+ /**
101
+ * Track processed mutation states to prevent duplicate event emissions
102
+ * Key format: `${mutationId}:${status}`
103
+ */
104
+ this.processedMutations = new Set();
105
+ /**
106
+ * Track processed query states to prevent duplicate event emissions
107
+ * Key format: `${queryHash}:${status}`
108
+ */
109
+ this.processedQueries = new Set();
110
+ /**
111
+ * Store transaction details from BROADCASTED events for use in CONFIRMED/REVERTED
112
+ * Key: transactionHash, Value: transaction details including the original sender address
113
+ */
114
+ this.pendingTransactions = new Map();
115
+ this.formo = formoAnalytics;
116
+ this.wagmiConfig = wagmiConfig;
117
+ this.queryClient = queryClient;
118
+ logger_1.logger.info("WagmiEventHandler: Initializing Wagmi integration");
119
+ // Set up connection/disconnection/chain listeners
120
+ this.setupConnectionListeners();
121
+ // Set up mutation and query tracking if QueryClient is provided
122
+ if (this.queryClient) {
123
+ this.setupMutationTracking();
124
+ this.setupQueryTracking();
125
+ }
126
+ else {
127
+ logger_1.logger.warn("WagmiEventHandler: QueryClient not provided, signature and transaction events will not be tracked");
128
+ }
129
+ }
130
+ /**
131
+ * Set up listeners for wallet connection, disconnection, and chain changes
132
+ */
133
+ WagmiEventHandler.prototype.setupConnectionListeners = function () {
134
+ var _this = this;
135
+ logger_1.logger.info("WagmiEventHandler: Setting up connection listeners");
136
+ // Subscribe to status changes (connect/disconnect)
137
+ var statusUnsubscribe = this.wagmiConfig.subscribe(function (state) { return state.status; }, function (status, prevStatus) {
138
+ _this.handleStatusChange(status, prevStatus);
139
+ });
140
+ this.unsubscribers.push(statusUnsubscribe);
141
+ // Subscribe to chain ID changes
142
+ var chainIdUnsubscribe = this.wagmiConfig.subscribe(function (state) { return state.chainId; }, function (chainId, prevChainId) {
143
+ _this.handleChainChange(chainId, prevChainId);
144
+ });
145
+ this.unsubscribers.push(chainIdUnsubscribe);
146
+ logger_1.logger.info("WagmiEventHandler: Connection listeners set up successfully");
147
+ };
148
+ /**
149
+ * Handle status changes (connect/disconnect)
150
+ */
151
+ WagmiEventHandler.prototype.handleStatusChange = function (status, prevStatus) {
152
+ return __awaiter(this, void 0, void 0, function () {
153
+ var state, address, chainId, connectorName, error_1;
154
+ return __generator(this, function (_a) {
155
+ switch (_a.label) {
156
+ case 0:
157
+ // Prevent concurrent processing
158
+ if (this.trackingState.isProcessing) {
159
+ logger_1.logger.debug("WagmiEventHandler: Already processing status change, skipping");
160
+ return [2 /*return*/];
161
+ }
162
+ this.trackingState.isProcessing = true;
163
+ _a.label = 1;
164
+ case 1:
165
+ _a.trys.push([1, 7, 8, 9]);
166
+ state = this.getState();
167
+ address = this.getConnectedAddress(state);
168
+ chainId = state.chainId;
169
+ logger_1.logger.info("WagmiEventHandler: Status changed", {
170
+ status: status,
171
+ prevStatus: prevStatus,
172
+ address: address,
173
+ chainId: chainId,
174
+ });
175
+ if (!(status === "disconnected" && prevStatus === "connected")) return [3 /*break*/, 4];
176
+ if (!this.formo.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 3];
177
+ return [4 /*yield*/, this.formo.disconnect({
178
+ chainId: this.trackingState.lastChainId,
179
+ address: this.trackingState.lastAddress,
180
+ })];
181
+ case 2:
182
+ _a.sent();
183
+ _a.label = 3;
184
+ case 3:
185
+ this.trackingState.lastAddress = undefined;
186
+ this.trackingState.lastChainId = undefined;
187
+ _a.label = 4;
188
+ case 4:
189
+ if (!(status === "connected" && prevStatus !== "connected")) return [3 /*break*/, 6];
190
+ if (!(address && chainId !== undefined)) return [3 /*break*/, 6];
191
+ this.trackingState.lastAddress = address;
192
+ this.trackingState.lastChainId = chainId;
193
+ if (!this.formo.isAutocaptureEnabled("connect")) return [3 /*break*/, 6];
194
+ connectorName = this.getConnectorName(state);
195
+ return [4 /*yield*/, this.formo.connect({ chainId: chainId, address: address }, __assign({}, (connectorName && { providerName: connectorName })))];
196
+ case 5:
197
+ _a.sent();
198
+ _a.label = 6;
199
+ case 6:
200
+ this.trackingState.lastStatus = status;
201
+ return [3 /*break*/, 9];
202
+ case 7:
203
+ error_1 = _a.sent();
204
+ logger_1.logger.error("WagmiEventHandler: Error handling status change:", error_1);
205
+ return [3 /*break*/, 9];
206
+ case 8:
207
+ this.trackingState.isProcessing = false;
208
+ return [7 /*endfinally*/];
209
+ case 9: return [2 /*return*/];
210
+ }
211
+ });
212
+ });
213
+ };
214
+ /**
215
+ * Handle chain ID changes
216
+ */
217
+ WagmiEventHandler.prototype.handleChainChange = function (chainId, prevChainId) {
218
+ return __awaiter(this, void 0, void 0, function () {
219
+ var state, address, error_2;
220
+ return __generator(this, function (_a) {
221
+ switch (_a.label) {
222
+ case 0:
223
+ if (chainId === prevChainId || chainId === undefined) {
224
+ return [2 /*return*/];
225
+ }
226
+ state = this.getState();
227
+ if (state.status !== "connected") {
228
+ return [2 /*return*/];
229
+ }
230
+ address = this.getConnectedAddress(state);
231
+ if (!address) {
232
+ logger_1.logger.warn("WagmiEventHandler: Chain changed but no address found");
233
+ return [2 /*return*/];
234
+ }
235
+ logger_1.logger.info("WagmiEventHandler: Chain changed", {
236
+ chainId: chainId,
237
+ prevChainId: prevChainId,
238
+ address: address,
239
+ });
240
+ this.trackingState.lastChainId = chainId;
241
+ if (!this.formo.isAutocaptureEnabled("chain")) return [3 /*break*/, 4];
242
+ _a.label = 1;
243
+ case 1:
244
+ _a.trys.push([1, 3, , 4]);
245
+ return [4 /*yield*/, this.formo.chain({ chainId: chainId, address: address })];
246
+ case 2:
247
+ _a.sent();
248
+ return [3 /*break*/, 4];
249
+ case 3:
250
+ error_2 = _a.sent();
251
+ logger_1.logger.error("WagmiEventHandler: Error tracking chain change:", error_2);
252
+ return [3 /*break*/, 4];
253
+ case 4: return [2 /*return*/];
254
+ }
255
+ });
256
+ });
257
+ };
258
+ /**
259
+ * Set up mutation tracking for signatures and transactions
260
+ */
261
+ WagmiEventHandler.prototype.setupMutationTracking = function () {
262
+ var _this = this;
263
+ if (!this.queryClient) {
264
+ return;
265
+ }
266
+ logger_1.logger.info("WagmiEventHandler: Setting up mutation tracking");
267
+ var mutationCache = this.queryClient.getMutationCache();
268
+ var unsubscribe = mutationCache.subscribe(function (event) {
269
+ _this.handleMutationEvent(event);
270
+ });
271
+ this.unsubscribers.push(unsubscribe);
272
+ logger_1.logger.info("WagmiEventHandler: Mutation tracking set up successfully");
273
+ };
274
+ /**
275
+ * Set up query tracking for transaction confirmations
276
+ * Listens for waitForTransactionReceipt queries to detect CONFIRMED status
277
+ */
278
+ WagmiEventHandler.prototype.setupQueryTracking = function () {
279
+ var _this = this;
280
+ if (!this.queryClient) {
281
+ return;
282
+ }
283
+ logger_1.logger.info("WagmiEventHandler: Setting up query tracking");
284
+ var queryCache = this.queryClient.getQueryCache();
285
+ var unsubscribe = queryCache.subscribe(function (event) {
286
+ _this.handleQueryEvent(event);
287
+ });
288
+ this.unsubscribers.push(unsubscribe);
289
+ logger_1.logger.info("WagmiEventHandler: Query tracking set up successfully");
290
+ };
291
+ /**
292
+ * Handle query cache events (transaction confirmations)
293
+ */
294
+ WagmiEventHandler.prototype.handleQueryEvent = function (event) {
295
+ if (event.type !== "updated") {
296
+ return;
297
+ }
298
+ var query = event.query;
299
+ var queryKey = query.queryKey;
300
+ if (!queryKey || queryKey.length === 0) {
301
+ return;
302
+ }
303
+ var queryType = queryKey[0];
304
+ // Only handle waitForTransactionReceipt queries
305
+ if (queryType !== "waitForTransactionReceipt") {
306
+ return;
307
+ }
308
+ var state = query.state;
309
+ // Extract receipt status early to include in deduplication key
310
+ // This ensures CONFIRMED vs REVERTED outcomes are processed separately
311
+ var receipt = state.data;
312
+ var receiptStatus = receipt === null || receipt === void 0 ? void 0 : receipt.status;
313
+ // Create a unique key for this query state to prevent duplicate processing
314
+ // Include receipt status to distinguish between CONFIRMED and REVERTED outcomes
315
+ var queryStateKey = "".concat(query.queryHash, ":").concat(state.status, ":").concat(receiptStatus || "");
316
+ // Skip if we've already processed this query state
317
+ if (this.processedQueries.has(queryStateKey)) {
318
+ logger_1.logger.debug("WagmiEventHandler: Skipping duplicate query event", {
319
+ queryType: queryType,
320
+ queryHash: query.queryHash,
321
+ status: state.status,
322
+ receiptStatus: receiptStatus,
323
+ });
324
+ return;
325
+ }
326
+ // Mark this query state as processed
327
+ this.processedQueries.add(queryStateKey);
328
+ logger_1.logger.debug("WagmiEventHandler: Query event", {
329
+ queryType: queryType,
330
+ queryHash: query.queryHash,
331
+ status: state.status,
332
+ });
333
+ // Handle transaction receipt queries
334
+ this.handleTransactionReceiptQuery(query);
335
+ // Clean up old processed queries to prevent memory leaks
336
+ cleanupOldEntries(this.processedQueries);
337
+ };
338
+ /**
339
+ * Handle waitForTransactionReceipt query completion
340
+ * Emits CONFIRMED or REVERTED transaction status
341
+ */
342
+ WagmiEventHandler.prototype.handleTransactionReceiptQuery = function (query) {
343
+ var _a;
344
+ if (!this.formo.isAutocaptureEnabled("transaction")) {
345
+ return;
346
+ }
347
+ var state = query.state;
348
+ var queryKey = query.queryKey;
349
+ // Only handle successful queries (transaction confirmed on chain)
350
+ if (state.status !== "success") {
351
+ return;
352
+ }
353
+ // Extract hash and chainId from query key
354
+ // Query key format: ['waitForTransactionReceipt', { hash, chainId, ... }]
355
+ var params = queryKey[1];
356
+ var transactionHash = params === null || params === void 0 ? void 0 : params.hash;
357
+ var chainId = (params === null || params === void 0 ? void 0 : params.chainId) || this.trackingState.lastChainId;
358
+ if (!transactionHash) {
359
+ logger_1.logger.warn("WagmiEventHandler: Transaction receipt query but no hash found");
360
+ return;
361
+ }
362
+ // Retrieve stored transaction details from BROADCASTED event
363
+ // Normalize hash to lowercase for consistent lookup
364
+ var normalizedHash = transactionHash.toLowerCase();
365
+ var pendingTx = this.pendingTransactions.get(normalizedHash);
366
+ // Use the original sender address from BROADCASTED event if available,
367
+ // otherwise fall back to current connected address.
368
+ // This handles wallet switches between broadcast and confirmation.
369
+ var address = (pendingTx === null || pendingTx === void 0 ? void 0 : pendingTx.address) || this.trackingState.lastAddress;
370
+ if (!address) {
371
+ logger_1.logger.warn("WagmiEventHandler: Transaction receipt query but no address available");
372
+ return;
373
+ }
374
+ try {
375
+ // Extract receipt data
376
+ var receipt = state.data;
377
+ // Determine transaction status from receipt
378
+ // receipt.status is 'success' or 'reverted' in viem
379
+ var txStatus = (receipt === null || receipt === void 0 ? void 0 : receipt.status) === "reverted"
380
+ ? events_1.TransactionStatus.REVERTED
381
+ : events_1.TransactionStatus.CONFIRMED;
382
+ logger_1.logger.info("WagmiEventHandler: Tracking transaction confirmation", {
383
+ status: txStatus,
384
+ transactionHash: transactionHash,
385
+ address: address,
386
+ chainId: chainId,
387
+ blockNumber: (_a = receipt === null || receipt === void 0 ? void 0 : receipt.blockNumber) === null || _a === void 0 ? void 0 : _a.toString(),
388
+ });
389
+ this.formo.transaction(__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 })),
390
+ // Spread function args as additional properties (only colliding keys are prefixed)
391
+ pendingTx === null || pendingTx === void 0 ? void 0 : pendingTx.safeFunctionArgs);
392
+ // Clean up the pending transaction after confirmation
393
+ this.pendingTransactions.delete(normalizedHash);
394
+ }
395
+ catch (error) {
396
+ logger_1.logger.error("WagmiEventHandler: Error handling transaction receipt query:", error);
397
+ }
398
+ };
399
+ /**
400
+ * Handle mutation cache events (signatures, transactions)
401
+ */
402
+ WagmiEventHandler.prototype.handleMutationEvent = function (event) {
403
+ if (event.type !== "updated") {
404
+ return;
405
+ }
406
+ var mutation = event.mutation;
407
+ var mutationKey = mutation.options.mutationKey;
408
+ if (!mutationKey || mutationKey.length === 0) {
409
+ return;
410
+ }
411
+ var mutationType = mutationKey[0];
412
+ var state = mutation.state;
413
+ // Create a unique key for this mutation state to prevent duplicate processing
414
+ var mutationStateKey = "".concat(mutation.mutationId, ":").concat(state.status);
415
+ // Skip if we've already processed this mutation state
416
+ if (this.processedMutations.has(mutationStateKey)) {
417
+ logger_1.logger.debug("WagmiEventHandler: Skipping duplicate mutation event", {
418
+ mutationType: mutationType,
419
+ mutationId: mutation.mutationId,
420
+ status: state.status,
421
+ });
422
+ return;
423
+ }
424
+ // Mark this mutation state as processed
425
+ this.processedMutations.add(mutationStateKey);
426
+ logger_1.logger.debug("WagmiEventHandler: Mutation event", {
427
+ mutationType: mutationType,
428
+ mutationId: mutation.mutationId,
429
+ status: state.status,
430
+ });
431
+ // Handle signature mutations
432
+ if (mutationType === "signMessage" || mutationType === "signTypedData") {
433
+ this.handleSignatureMutation(mutationType, mutation);
434
+ }
435
+ // Handle transaction mutations
436
+ if (mutationType === "sendTransaction" || mutationType === "writeContract") {
437
+ this.handleTransactionMutation(mutationType, mutation);
438
+ }
439
+ // Clean up old processed mutations to prevent memory leaks
440
+ cleanupOldEntries(this.processedMutations);
441
+ };
442
+ /**
443
+ * Handle signature mutations (signMessage, signTypedData)
444
+ */
445
+ WagmiEventHandler.prototype.handleSignatureMutation = function (mutationType, mutation) {
446
+ if (!this.formo.isAutocaptureEnabled("signature")) {
447
+ return;
448
+ }
449
+ var state = mutation.state;
450
+ var variables = state.variables || {};
451
+ var chainId = this.trackingState.lastChainId;
452
+ var address = this.trackingState.lastAddress;
453
+ if (!address) {
454
+ logger_1.logger.warn("WagmiEventHandler: Signature event but no address available");
455
+ return;
456
+ }
457
+ try {
458
+ // Map Wagmi mutation status to Formo signature status
459
+ var status_1;
460
+ var signatureHash = void 0;
461
+ if (state.status === "pending") {
462
+ status_1 = events_1.SignatureStatus.REQUESTED;
463
+ }
464
+ else if (state.status === "success") {
465
+ status_1 = events_1.SignatureStatus.CONFIRMED;
466
+ signatureHash = state.data;
467
+ }
468
+ else if (state.status === "error") {
469
+ status_1 = events_1.SignatureStatus.REJECTED;
470
+ }
471
+ else {
472
+ return; // Ignore idle state
473
+ }
474
+ // Extract message from variables
475
+ var message = void 0;
476
+ if (mutationType === "signMessage") {
477
+ message = variables.message || "";
478
+ }
479
+ else {
480
+ // For signTypedData, stringify the typed data
481
+ message = JSON.stringify(variables.message || variables.types || {});
482
+ }
483
+ logger_1.logger.info("WagmiEventHandler: Tracking signature event", {
484
+ status: status_1,
485
+ mutationType: mutationType,
486
+ address: address,
487
+ chainId: chainId,
488
+ });
489
+ this.formo.signature(__assign({ status: status_1, chainId: chainId, address: address, message: message }, (signatureHash && { signatureHash: signatureHash })));
490
+ }
491
+ catch (error) {
492
+ logger_1.logger.error("WagmiEventHandler: Error handling signature mutation:", error);
493
+ }
494
+ };
495
+ /**
496
+ * Handle transaction mutations (sendTransaction, writeContract)
497
+ */
498
+ WagmiEventHandler.prototype.handleTransactionMutation = function (mutationType, mutation) {
499
+ var _a;
500
+ if (!this.formo.isAutocaptureEnabled("transaction")) {
501
+ return;
502
+ }
503
+ var state = mutation.state;
504
+ var variables = state.variables || {};
505
+ var chainId = this.trackingState.lastChainId || variables.chainId;
506
+ // For sendTransaction, user's address is the 'from'
507
+ // For writeContract, variables.address is the contract address, not the user
508
+ // variables.account can be a string address or an Account object with an address property
509
+ var accountValue = variables.account;
510
+ var accountAddress = typeof accountValue === "string"
511
+ ? accountValue
512
+ : accountValue === null || accountValue === void 0 ? void 0 : accountValue.address;
513
+ var userAddress = this.trackingState.lastAddress || accountAddress || variables.from;
514
+ if (!userAddress) {
515
+ logger_1.logger.warn("WagmiEventHandler: Transaction event but no address available");
516
+ return;
517
+ }
518
+ try {
519
+ // Map Wagmi mutation status to Formo transaction status
520
+ var status_2;
521
+ var transactionHash = void 0;
522
+ if (state.status === "pending") {
523
+ status_2 = events_1.TransactionStatus.STARTED;
524
+ }
525
+ else if (state.status === "success") {
526
+ status_2 = events_1.TransactionStatus.BROADCASTED;
527
+ transactionHash = state.data;
528
+ }
529
+ else if (state.status === "error") {
530
+ status_2 = events_1.TransactionStatus.REJECTED;
531
+ }
532
+ else {
533
+ return; // Ignore idle state
534
+ }
535
+ // Extract transaction details based on mutation type
536
+ var data = void 0;
537
+ var to = void 0;
538
+ var function_name = void 0;
539
+ var function_args = void 0;
540
+ var value = (_a = variables.value) === null || _a === void 0 ? void 0 : _a.toString();
541
+ if (mutationType === "writeContract") {
542
+ // For writeContract, extract function info and encode data
543
+ var abi = variables.abi, fnName = variables.functionName, args = variables.args, contractAddress = variables.address;
544
+ to = contractAddress;
545
+ function_name = fnName;
546
+ if (abi && fnName) {
547
+ // Extract function arguments as a name-value map
548
+ function_args = (0, utils_1.extractFunctionArgs)(abi, fnName, args);
549
+ // Encode the function data synchronously if viem is available
550
+ var encodedData = (0, utils_1.encodeWriteContractData)(abi, fnName, args);
551
+ if (encodedData) {
552
+ data = encodedData;
553
+ logger_1.logger.debug("WagmiEventHandler: Encoded writeContract data", data.substring(0, 10));
554
+ }
555
+ }
556
+ }
557
+ else {
558
+ // For sendTransaction, use variables directly
559
+ // Only data is available, function_name and function_args are not sent
560
+ data = variables.data;
561
+ to = variables.to;
562
+ }
563
+ logger_1.logger.info("WagmiEventHandler: Tracking transaction event", {
564
+ status: status_2,
565
+ mutationType: mutationType,
566
+ address: userAddress,
567
+ chainId: chainId,
568
+ transactionHash: transactionHash,
569
+ function_name: function_name,
570
+ });
571
+ // Build safeFunctionArgs with collision handling and struct flattening
572
+ var safeFunctionArgs = (0, utils_1.buildSafeFunctionArgs)(function_args, RESERVED_FIELDS);
573
+ // Store transaction details for BROADCASTED status to use in CONFIRMED/REVERTED
574
+ // Normalize hash to lowercase for consistent lookup
575
+ // Include the sender address to handle wallet switches between broadcast and confirmation
576
+ if (status_2 === events_1.TransactionStatus.BROADCASTED && transactionHash) {
577
+ var normalizedHash = transactionHash.toLowerCase();
578
+ var txDetails = __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 })), (safeFunctionArgs && { safeFunctionArgs: safeFunctionArgs }));
579
+ this.pendingTransactions.set(normalizedHash, txDetails);
580
+ logger_1.logger.debug("WagmiEventHandler: Stored pending transaction for confirmation", {
581
+ transactionHash: normalizedHash,
582
+ });
583
+ // Clean up old pending transactions to prevent memory leaks (keep max 100)
584
+ // Remove oldest 50 entries when limit exceeded to handle high-throughput scenarios
585
+ if (this.pendingTransactions.size > 100) {
586
+ var keys = Array.from(this.pendingTransactions.keys());
587
+ for (var i = 0; i < 50 && i < keys.length; i++) {
588
+ this.pendingTransactions.delete(keys[i]);
589
+ }
590
+ }
591
+ }
592
+ this.formo.transaction(__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 })),
593
+ // Spread function args as additional properties (only colliding keys are prefixed)
594
+ safeFunctionArgs);
595
+ }
596
+ catch (error) {
597
+ logger_1.logger.error("WagmiEventHandler: Error handling transaction mutation:", error);
598
+ }
599
+ };
600
+ /**
601
+ * Get the current Wagmi state
602
+ * Supports both getState() method and direct state property access
603
+ * for compatibility with different Wagmi wrappers (RainbowKit, etc.)
604
+ */
605
+ WagmiEventHandler.prototype.getState = function () {
606
+ // Try getState() method first (standard Wagmi API)
607
+ if (typeof this.wagmiConfig.getState === "function") {
608
+ return this.wagmiConfig.getState();
609
+ }
610
+ // Fall back to direct state property (RainbowKit and some Wagmi setups)
611
+ if (this.wagmiConfig.state) {
612
+ return this.wagmiConfig.state;
613
+ }
614
+ // Return a default disconnected state if neither is available
615
+ logger_1.logger.warn("WagmiEventHandler: Unable to get state from config, returning default state");
616
+ return {
617
+ status: "disconnected",
618
+ connections: new Map(),
619
+ current: undefined,
620
+ chainId: undefined,
621
+ };
622
+ };
623
+ /**
624
+ * Get the currently connected address from Wagmi state
625
+ */
626
+ WagmiEventHandler.prototype.getConnectedAddress = function (state) {
627
+ if (!state.current) {
628
+ return undefined;
629
+ }
630
+ var connection = state.connections.get(state.current);
631
+ if (!connection || connection.accounts.length === 0) {
632
+ return undefined;
633
+ }
634
+ return connection.accounts[0];
635
+ };
636
+ /**
637
+ * Get the connector name from Wagmi state
638
+ */
639
+ WagmiEventHandler.prototype.getConnectorName = function (state) {
640
+ if (!state.current) {
641
+ return undefined;
642
+ }
643
+ var connection = state.connections.get(state.current);
644
+ return connection === null || connection === void 0 ? void 0 : connection.connector.name;
645
+ };
646
+ /**
647
+ * Clean up all subscriptions
648
+ */
649
+ WagmiEventHandler.prototype.cleanup = function () {
650
+ logger_1.logger.info("WagmiEventHandler: Cleaning up subscriptions");
651
+ for (var _i = 0, _a = this.unsubscribers; _i < _a.length; _i++) {
652
+ var unsubscribe = _a[_i];
653
+ try {
654
+ unsubscribe();
655
+ }
656
+ catch (error) {
657
+ logger_1.logger.error("WagmiEventHandler: Error during cleanup:", error);
658
+ }
659
+ }
660
+ this.unsubscribers = [];
661
+ this.processedMutations.clear();
662
+ this.processedQueries.clear();
663
+ this.pendingTransactions.clear();
664
+ logger_1.logger.info("WagmiEventHandler: Cleanup complete");
665
+ };
666
+ return WagmiEventHandler;
667
+ }());
668
+ exports.WagmiEventHandler = WagmiEventHandler;
669
+ //# sourceMappingURL=WagmiEventHandler.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Wagmi integration module
3
+ *
4
+ * Provides integration with Wagmi v2 for wallet event tracking.
5
+ * This module exports the WagmiEventHandler and related types.
6
+ */
7
+ export { WagmiEventHandler } from "./WagmiEventHandler";
8
+ export type { WagmiState, WagmiConnection, WagmiConnector, WagmiConfig, MutationState, Mutation, MutationCacheEvent, MutationCache, QueryClient, UnsubscribeFn, WagmiMutationKey, WagmiTrackingState, } from "./types";
9
+ //# sourceMappingURL=index.d.ts.map