@formo/analytics 1.17.8 → 1.18.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 (62) hide show
  1. package/README.md +0 -1
  2. package/dist/cjs/src/FormoAnalytics.d.ts +20 -13
  3. package/dist/cjs/src/FormoAnalytics.d.ts.map +1 -1
  4. package/dist/cjs/src/FormoAnalytics.js +368 -199
  5. package/dist/cjs/src/FormoAnalytics.js.map +1 -1
  6. package/dist/cjs/src/FormoAnalyticsProvider.js +4 -4
  7. package/dist/cjs/src/FormoAnalyticsProvider.js.map +1 -1
  8. package/dist/cjs/src/lib/event/EventFactory.d.ts +3 -2
  9. package/dist/cjs/src/lib/event/EventFactory.d.ts.map +1 -1
  10. package/dist/cjs/src/lib/event/EventFactory.js +17 -5
  11. package/dist/cjs/src/lib/event/EventFactory.js.map +1 -1
  12. package/dist/cjs/src/lib/logger/Logger.js +1 -1
  13. package/dist/cjs/src/lib/logger/Logger.js.map +1 -1
  14. package/dist/cjs/src/types/base.d.ts +15 -8
  15. package/dist/cjs/src/types/base.d.ts.map +1 -1
  16. package/dist/cjs/src/types/events.d.ts +6 -3
  17. package/dist/cjs/src/types/events.d.ts.map +1 -1
  18. package/dist/cjs/src/types/events.js +2 -0
  19. package/dist/cjs/src/types/events.js.map +1 -1
  20. package/dist/cjs/src/types/provider.d.ts +3 -0
  21. package/dist/cjs/src/types/provider.d.ts.map +1 -1
  22. package/dist/cjs/src/utils/chain.d.ts +7 -0
  23. package/dist/cjs/src/utils/chain.d.ts.map +1 -0
  24. package/dist/cjs/src/utils/chain.js +17 -0
  25. package/dist/cjs/src/utils/chain.js.map +1 -0
  26. package/dist/cjs/src/validators/address.d.ts +2 -2
  27. package/dist/cjs/src/validators/address.d.ts.map +1 -1
  28. package/dist/cjs/src/validators/address.js +6 -6
  29. package/dist/cjs/src/validators/address.js.map +1 -1
  30. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  31. package/dist/esm/src/FormoAnalytics.d.ts +20 -13
  32. package/dist/esm/src/FormoAnalytics.d.ts.map +1 -1
  33. package/dist/esm/src/FormoAnalytics.js +368 -199
  34. package/dist/esm/src/FormoAnalytics.js.map +1 -1
  35. package/dist/esm/src/FormoAnalyticsProvider.js +4 -4
  36. package/dist/esm/src/FormoAnalyticsProvider.js.map +1 -1
  37. package/dist/esm/src/lib/event/EventFactory.d.ts +3 -2
  38. package/dist/esm/src/lib/event/EventFactory.d.ts.map +1 -1
  39. package/dist/esm/src/lib/event/EventFactory.js +17 -5
  40. package/dist/esm/src/lib/event/EventFactory.js.map +1 -1
  41. package/dist/esm/src/lib/logger/Logger.js +1 -1
  42. package/dist/esm/src/lib/logger/Logger.js.map +1 -1
  43. package/dist/esm/src/types/base.d.ts +15 -8
  44. package/dist/esm/src/types/base.d.ts.map +1 -1
  45. package/dist/esm/src/types/events.d.ts +6 -3
  46. package/dist/esm/src/types/events.d.ts.map +1 -1
  47. package/dist/esm/src/types/events.js +2 -0
  48. package/dist/esm/src/types/events.js.map +1 -1
  49. package/dist/esm/src/types/provider.d.ts +3 -0
  50. package/dist/esm/src/types/provider.d.ts.map +1 -1
  51. package/dist/esm/src/utils/chain.d.ts +7 -0
  52. package/dist/esm/src/utils/chain.d.ts.map +1 -0
  53. package/dist/esm/src/utils/chain.js +14 -0
  54. package/dist/esm/src/utils/chain.js.map +1 -0
  55. package/dist/esm/src/validators/address.d.ts +2 -2
  56. package/dist/esm/src/validators/address.d.ts.map +1 -1
  57. package/dist/esm/src/validators/address.js +4 -4
  58. package/dist/esm/src/validators/address.js.map +1 -1
  59. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  60. package/dist/index.umd.min.js +1 -1
  61. package/dist/index.umd.min.js.map +1 -1
  62. package/package.json +1 -1
@@ -50,6 +50,7 @@ import { EVENTS_API_URL, EventType, LOCAL_ANONYMOUS_ID_KEY, SESSION_CURRENT_URL_
50
50
  import { cookie, EventManager, EventQueue, initStorageManager, logger, Logger, } from "./lib";
51
51
  import { SignatureStatus, TransactionStatus, } from "./types";
52
52
  import { isAddress, isLocalhost } from "./validators";
53
+ import { parseChainId } from "./utils/chain";
53
54
  var FormoAnalytics = /** @class */ (function () {
54
55
  function FormoAnalytics(writeKey, options) {
55
56
  if (options === void 0) { options = {}; }
@@ -62,8 +63,8 @@ var FormoAnalytics = /** @class */ (function () {
62
63
  this.currentUserId = "";
63
64
  this.config = {
64
65
  writeKey: writeKey,
65
- trackLocalhost: options.trackLocalhost || false,
66
66
  };
67
+ this.options = options;
67
68
  this.session = new FormoAnalyticsSession();
68
69
  this.currentUserId =
69
70
  cookie().get(SESSION_USER_ID_KEY) || undefined;
@@ -92,7 +93,7 @@ var FormoAnalytics = /** @class */ (function () {
92
93
  if (provider) {
93
94
  this.trackProvider(provider);
94
95
  }
95
- this.trackFirstPageHit();
96
+ this.trackPageHit();
96
97
  this.trackPageHits();
97
98
  }
98
99
  FormoAnalytics.init = function (writeKey, options) {
@@ -126,13 +127,14 @@ var FormoAnalytics = /** @class */ (function () {
126
127
  * @param {string} name - The name of the page
127
128
  * @param {Record<string, any>} properties - Additional properties to include
128
129
  * @param {Record<string, any>} context - Additional context to include
130
+ * @param {(...args: unknown[]) => void} callback - Optional callback function
129
131
  * @returns {Promise<void>}
130
132
  */
131
- FormoAnalytics.prototype.page = function (category, name, properties, context) {
133
+ FormoAnalytics.prototype.page = function (category, name, properties, context, callback) {
132
134
  return __awaiter(this, void 0, void 0, function () {
133
135
  return __generator(this, function (_a) {
134
136
  switch (_a.label) {
135
- case 0: return [4 /*yield*/, this.trackPageHit(category, name, properties, context)];
137
+ case 0: return [4 /*yield*/, this.trackPageHit(category, name, properties, context, callback)];
136
138
  case 1:
137
139
  _a.sent();
138
140
  return [2 /*return*/];
@@ -185,9 +187,9 @@ var FormoAnalytics = /** @class */ (function () {
185
187
  });
186
188
  };
187
189
  /**
188
- * Emits a wallet disconnect event.
189
- * @param {ChainID} params.chainId
190
- * @param {Address} params.address
190
+ * Emits a disconnect wallet event.
191
+ * @param {ChainID} [params.chainId]
192
+ * @param {Address} [params.address]
191
193
  * @param {IFormoEventProperties} properties
192
194
  * @param {IFormoEventContext} context
193
195
  * @param {(...args: unknown[]) => void} callback
@@ -195,15 +197,21 @@ var FormoAnalytics = /** @class */ (function () {
195
197
  */
196
198
  FormoAnalytics.prototype.disconnect = function (params, properties, context, callback) {
197
199
  return __awaiter(this, void 0, void 0, function () {
198
- var address, chainId;
200
+ var chainId, address;
199
201
  return __generator(this, function (_a) {
200
202
  switch (_a.label) {
201
203
  case 0:
202
- address = (params === null || params === void 0 ? void 0 : params.address) || this.currentAddress;
203
204
  chainId = (params === null || params === void 0 ? void 0 : params.chainId) || this.currentChainId;
204
- return [4 /*yield*/, this.handleDisconnect(chainId, address, properties, context, callback)];
205
+ address = (params === null || params === void 0 ? void 0 : params.address) || this.currentAddress;
206
+ return [4 /*yield*/, this.trackEvent(EventType.DISCONNECT, {
207
+ chainId: chainId,
208
+ address: address,
209
+ }, properties, context, callback)];
205
210
  case 1:
206
211
  _a.sent();
212
+ this.currentAddress = undefined;
213
+ this.currentChainId = undefined;
214
+ logger.info("Wallet disconnected: Cleared currentAddress and currentChainId");
207
215
  return [2 /*return*/];
208
216
  }
209
217
  });
@@ -435,6 +443,7 @@ var FormoAnalytics = /** @class */ (function () {
435
443
  SDK tracking and event listener functions
436
444
  */
437
445
  FormoAnalytics.prototype.trackProvider = function (provider) {
446
+ logger.info("trackProvider", provider);
438
447
  try {
439
448
  if (provider === this._provider) {
440
449
  logger.warn("TrackProvider: Provider already tracked.");
@@ -452,168 +461,54 @@ var FormoAnalytics = /** @class */ (function () {
452
461
  }
453
462
  this._provider = provider;
454
463
  // Register listeners for web3 provider events
455
- this.registerAddressChangedListener();
464
+ this.registerAccountsChangedListener();
456
465
  this.registerChainChangedListener();
457
- this.registerSignatureListener();
458
- this.registerTransactionListener();
466
+ this.registerConnectListener();
467
+ this.registerRequestListeners();
459
468
  }
460
469
  catch (error) {
461
470
  logger.error("Error tracking provider:", error);
462
471
  }
463
472
  };
464
- FormoAnalytics.prototype.registerAddressChangedListener = function () {
473
+ FormoAnalytics.prototype.registerAccountsChangedListener = function () {
465
474
  var _this = this;
466
- var _a, _b;
475
+ var _a;
476
+ logger.info("registerAccountsChangedListener");
467
477
  var listener = function () {
468
478
  var args = [];
469
479
  for (var _i = 0; _i < arguments.length; _i++) {
470
480
  args[_i] = arguments[_i];
471
481
  }
472
- return _this.onAddressChanged(args[0]);
482
+ return _this.onAccountsChanged(args[0]);
473
483
  };
474
484
  (_a = this._provider) === null || _a === void 0 ? void 0 : _a.on("accountsChanged", listener);
475
485
  this._providerListeners["accountsChanged"] = listener;
476
- var onAddressDisconnected = this.onAddressDisconnected.bind(this);
477
- (_b = this._provider) === null || _b === void 0 ? void 0 : _b.on("disconnect", onAddressDisconnected);
478
- this._providerListeners["disconnect"] = onAddressDisconnected;
479
- };
480
- FormoAnalytics.prototype.registerChainChangedListener = function () {
481
- var _this = this;
482
- var _a;
483
- var listener = function () {
484
- var args = [];
485
- for (var _i = 0; _i < arguments.length; _i++) {
486
- args[_i] = arguments[_i];
487
- }
488
- return _this.onChainChanged(args[0]);
489
- };
490
- (_a = this.provider) === null || _a === void 0 ? void 0 : _a.on("chainChanged", listener);
491
- this._providerListeners["chainChanged"] = listener;
492
486
  };
493
- FormoAnalytics.prototype.registerSignatureListener = function () {
494
- var _this = this;
495
- var _a;
496
- if (!this.provider) {
497
- logger.error("Provider not found for signature tracking");
498
- return;
499
- }
500
- if (((_a = Object.getOwnPropertyDescriptor(this.provider, "request")) === null || _a === void 0 ? void 0 : _a.writable) ===
501
- false) {
502
- logger.warn("Provider.request is not writable");
503
- return;
504
- }
505
- var request = this.provider.request.bind(this.provider);
506
- this.provider.request = function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
507
- var response, error_1, rpcError;
508
- var method = _b.method, params = _b.params;
509
- return __generator(this, function (_c) {
510
- switch (_c.label) {
511
- case 0:
512
- if (!(Array.isArray(params) &&
513
- ["eth_signTypedData_v4", "personal_sign"].includes(method))) return [3 /*break*/, 4];
514
- // Emit signature request event
515
- this.signature(__assign({ status: SignatureStatus.REQUESTED }, this.buildSignatureEventPayload(method, params)));
516
- _c.label = 1;
517
- case 1:
518
- _c.trys.push([1, 3, , 4]);
519
- return [4 /*yield*/, request({ method: method, params: params })];
520
- case 2:
521
- response = (_c.sent());
522
- if (response) {
523
- // Emit signature confirmed event
524
- this.signature(__assign({ status: SignatureStatus.CONFIRMED }, this.buildSignatureEventPayload(method, params, response)));
525
- }
526
- return [2 /*return*/, response];
527
- case 3:
528
- error_1 = _c.sent();
529
- rpcError = error_1;
530
- if (rpcError && (rpcError === null || rpcError === void 0 ? void 0 : rpcError.code) === 4001) {
531
- // Emit signature rejected event
532
- this.signature(__assign({ status: SignatureStatus.REJECTED }, this.buildSignatureEventPayload(method, params)));
533
- }
534
- throw error_1;
535
- case 4: return [2 /*return*/, request({ method: method, params: params })];
536
- }
537
- });
538
- }); };
539
- return;
540
- };
541
- FormoAnalytics.prototype.registerTransactionListener = function () {
542
- var _this = this;
543
- var _a;
544
- if (!this.provider) {
545
- logger.error("Provider not found for transaction tracking");
546
- return;
547
- }
548
- if (((_a = Object.getOwnPropertyDescriptor(this.provider, "request")) === null || _a === void 0 ? void 0 : _a.writable) ===
549
- false) {
550
- logger.warn("Provider.request is not writable");
551
- return;
552
- }
553
- var request = this.provider.request.bind(this.provider);
554
- this.provider.request = function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
555
- var payload, transactionHash, error_2, rpcError;
556
- var method = _b.method, params = _b.params;
557
- return __generator(this, function (_c) {
558
- switch (_c.label) {
559
- case 0:
560
- if (!(Array.isArray(params) &&
561
- method === "eth_sendTransaction" &&
562
- params[0])) return [3 /*break*/, 5];
563
- return [4 /*yield*/, this.buildTransactionEventPayload(params)];
564
- case 1:
565
- payload = _c.sent();
566
- this.transaction(__assign({ status: TransactionStatus.STARTED }, payload));
567
- _c.label = 2;
568
- case 2:
569
- _c.trys.push([2, 4, , 5]);
570
- return [4 /*yield*/, request({ method: method, params: params })];
571
- case 3:
572
- transactionHash = (_c.sent());
573
- // Track transaction broadcast
574
- this.transaction(__assign(__assign({ status: TransactionStatus.BROADCASTED }, payload), { transactionHash: transactionHash }));
575
- return [2 /*return*/];
576
- case 4:
577
- error_2 = _c.sent();
578
- logger.error("Transaction error:", error_2);
579
- rpcError = error_2;
580
- if (rpcError && (rpcError === null || rpcError === void 0 ? void 0 : rpcError.code) === 4001) {
581
- // Emit transaction rejected event
582
- this.transaction(__assign({ status: TransactionStatus.REJECTED }, payload));
583
- }
584
- throw error_2;
585
- case 5: return [2 /*return*/, request({ method: method, params: params })];
586
- }
587
- });
588
- }); };
589
- return;
590
- };
591
- FormoAnalytics.prototype.onAddressChanged = function (addresses) {
592
- return __awaiter(this, void 0, void 0, function () {
593
- return __generator(this, function (_a) {
594
- if (addresses.length > 0) {
595
- this.onAddressConnected(addresses[0]);
596
- }
597
- else {
598
- this.onAddressDisconnected();
599
- }
600
- return [2 /*return*/];
601
- });
602
- });
603
- };
604
- FormoAnalytics.prototype.onAddressConnected = function (address) {
487
+ FormoAnalytics.prototype.onAccountsChanged = function (accounts) {
605
488
  return __awaiter(this, void 0, void 0, function () {
606
- var _a;
489
+ var address, _a;
607
490
  return __generator(this, function (_b) {
608
491
  switch (_b.label) {
609
492
  case 0:
610
- if (address === this.currentAddress)
493
+ logger.info("onAccountsChanged", accounts);
494
+ if (!(accounts.length === 0)) return [3 /*break*/, 2];
495
+ // Handle wallet disconnect
496
+ return [4 /*yield*/, this.disconnect()];
497
+ case 1:
498
+ // Handle wallet disconnect
499
+ _b.sent();
500
+ return [2 /*return*/];
501
+ case 2:
502
+ address = accounts[0];
503
+ if (address === this.currentAddress) {
611
504
  // We have already reported this address
612
505
  return [2 /*return*/];
506
+ }
507
+ // Handle wallet connect
613
508
  this.currentAddress = address;
614
509
  _a = this;
615
510
  return [4 /*yield*/, this.getCurrentChainId()];
616
- case 1:
511
+ case 3:
617
512
  _a.currentChainId = _b.sent();
618
513
  this.connect({ chainId: this.currentChainId, address: address });
619
514
  return [2 /*return*/];
@@ -621,38 +516,19 @@ var FormoAnalytics = /** @class */ (function () {
621
516
  });
622
517
  });
623
518
  };
624
- FormoAnalytics.prototype.handleDisconnect = function (chainId, address, properties, context, callback) {
625
- return __awaiter(this, void 0, void 0, function () {
626
- var payload;
627
- return __generator(this, function (_a) {
628
- switch (_a.label) {
629
- case 0:
630
- payload = {
631
- chainId: chainId || this.currentChainId,
632
- address: address || this.currentAddress,
633
- };
634
- this.currentChainId = undefined;
635
- this.currentAddress = undefined;
636
- cookie().remove(SESSION_USER_ID_KEY);
637
- return [4 /*yield*/, this.trackEvent(EventType.DISCONNECT, payload, properties, context, callback)];
638
- case 1:
639
- _a.sent();
640
- return [2 /*return*/];
641
- }
642
- });
643
- });
644
- };
645
- FormoAnalytics.prototype.onAddressDisconnected = function () {
646
- return __awaiter(this, void 0, void 0, function () {
647
- return __generator(this, function (_a) {
648
- switch (_a.label) {
649
- case 0: return [4 /*yield*/, this.handleDisconnect(this.currentChainId, this.currentAddress)];
650
- case 1:
651
- _a.sent();
652
- return [2 /*return*/];
653
- }
654
- });
655
- });
519
+ FormoAnalytics.prototype.registerChainChangedListener = function () {
520
+ var _this = this;
521
+ var _a;
522
+ logger.info("registerChainChangedListener");
523
+ var listener = function () {
524
+ var args = [];
525
+ for (var _i = 0; _i < arguments.length; _i++) {
526
+ args[_i] = arguments[_i];
527
+ }
528
+ return _this.onChainChanged(args[0]);
529
+ };
530
+ (_a = this.provider) === null || _a === void 0 ? void 0 : _a.on("chainChanged", listener);
531
+ this._providerListeners["chainChanged"] = listener;
656
532
  };
657
533
  FormoAnalytics.prototype.onChainChanged = function (chainIdHex) {
658
534
  return __awaiter(this, void 0, void 0, function () {
@@ -660,7 +536,8 @@ var FormoAnalytics = /** @class */ (function () {
660
536
  return __generator(this, function (_a) {
661
537
  switch (_a.label) {
662
538
  case 0:
663
- this.currentChainId = parseInt(chainIdHex);
539
+ logger.info("onChainChanged", chainIdHex);
540
+ this.currentChainId = parseChainId(chainIdHex);
664
541
  if (!!this.currentAddress) return [3 /*break*/, 2];
665
542
  if (!this.provider) {
666
543
  logger.info("OnChainChanged: Provider not found. CHAIN_CHANGED not reported");
@@ -691,13 +568,217 @@ var FormoAnalytics = /** @class */ (function () {
691
568
  });
692
569
  });
693
570
  };
694
- FormoAnalytics.prototype.trackFirstPageHit = function () {
571
+ FormoAnalytics.prototype.registerConnectListener = function () {
572
+ var _this = this;
573
+ var _a;
574
+ logger.info("registerConnectListener");
575
+ var listener = function () {
576
+ var args = [];
577
+ for (var _i = 0; _i < arguments.length; _i++) {
578
+ args[_i] = arguments[_i];
579
+ }
580
+ var connection = args[0];
581
+ _this.onConnected(connection);
582
+ };
583
+ (_a = this._provider) === null || _a === void 0 ? void 0 : _a.on("connect", listener);
584
+ this._providerListeners["connect"] = listener;
585
+ };
586
+ FormoAnalytics.prototype.onConnected = function (connection) {
587
+ return __awaiter(this, void 0, void 0, function () {
588
+ var chainId, address, e_2;
589
+ return __generator(this, function (_a) {
590
+ switch (_a.label) {
591
+ case 0:
592
+ logger.info("onConnected", connection);
593
+ _a.label = 1;
594
+ case 1:
595
+ _a.trys.push([1, 3, , 4]);
596
+ if (!connection || typeof connection.chainId !== 'string')
597
+ return [2 /*return*/];
598
+ chainId = parseChainId(connection.chainId);
599
+ return [4 /*yield*/, this.getAddress()];
600
+ case 2:
601
+ address = _a.sent();
602
+ if (chainId !== null && chainId !== undefined && address) {
603
+ this.connect({ chainId: chainId, address: address });
604
+ }
605
+ return [3 /*break*/, 4];
606
+ case 3:
607
+ e_2 = _a.sent();
608
+ logger.error("Error handling connect event", e_2);
609
+ return [3 /*break*/, 4];
610
+ case 4: return [2 /*return*/];
611
+ }
612
+ });
613
+ });
614
+ };
615
+ FormoAnalytics.prototype.registerRequestListeners = function () {
616
+ var _this = this;
617
+ var _a;
618
+ logger.info("registerRequestListeners");
619
+ if (!this.provider) {
620
+ logger.error("Provider not found for request (signature, transaction) tracking");
621
+ return;
622
+ }
623
+ if (((_a = Object.getOwnPropertyDescriptor(this.provider, "request")) === null || _a === void 0 ? void 0 : _a.writable) ===
624
+ false) {
625
+ logger.warn("Provider.request is not writable");
626
+ return;
627
+ }
628
+ var request = this.provider.request.bind(this.provider);
629
+ this.provider.request = function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
630
+ var response_1, error_1, transactionHash_1, error_2;
631
+ var _this = this;
632
+ var method = _b.method, params = _b.params;
633
+ return __generator(this, function (_c) {
634
+ switch (_c.label) {
635
+ case 0:
636
+ if (!(Array.isArray(params) &&
637
+ ["eth_signTypedData_v4", "personal_sign"].includes(method))) return [3 /*break*/, 4];
638
+ // Fire-and-forget tracking
639
+ (function () { return __awaiter(_this, void 0, void 0, function () {
640
+ return __generator(this, function (_a) {
641
+ try {
642
+ this.signature(__assign({ status: SignatureStatus.REQUESTED }, this.buildSignatureEventPayload(method, params)));
643
+ }
644
+ catch (e) {
645
+ logger.error("Formo: Failed to track signature request", e);
646
+ }
647
+ return [2 /*return*/];
648
+ });
649
+ }); })();
650
+ _c.label = 1;
651
+ case 1:
652
+ _c.trys.push([1, 3, , 4]);
653
+ return [4 /*yield*/, request({ method: method, params: params })];
654
+ case 2:
655
+ response_1 = (_c.sent());
656
+ (function () { return __awaiter(_this, void 0, void 0, function () {
657
+ return __generator(this, function (_a) {
658
+ try {
659
+ if (response_1) {
660
+ this.signature(__assign({ status: SignatureStatus.CONFIRMED }, this.buildSignatureEventPayload(method, params, response_1)));
661
+ }
662
+ }
663
+ catch (e) {
664
+ logger.error("Formo: Failed to track signature confirmation", e);
665
+ }
666
+ return [2 /*return*/];
667
+ });
668
+ }); })();
669
+ return [2 /*return*/, response_1];
670
+ case 3:
671
+ error_1 = _c.sent();
672
+ (function () { return __awaiter(_this, void 0, void 0, function () {
673
+ var rpcError;
674
+ return __generator(this, function (_a) {
675
+ try {
676
+ rpcError = error_1;
677
+ if (rpcError && (rpcError === null || rpcError === void 0 ? void 0 : rpcError.code) === 4001) {
678
+ this.signature(__assign({ status: SignatureStatus.REJECTED }, this.buildSignatureEventPayload(method, params)));
679
+ }
680
+ }
681
+ catch (e) {
682
+ logger.error("Formo: Failed to track signature rejection", e);
683
+ }
684
+ return [2 /*return*/];
685
+ });
686
+ }); })();
687
+ throw error_1;
688
+ case 4:
689
+ if (!(Array.isArray(params) &&
690
+ method === "eth_sendTransaction" &&
691
+ params[0])) return [3 /*break*/, 8];
692
+ (function () { return __awaiter(_this, void 0, void 0, function () {
693
+ var payload, e_3;
694
+ return __generator(this, function (_a) {
695
+ switch (_a.label) {
696
+ case 0:
697
+ _a.trys.push([0, 2, , 3]);
698
+ return [4 /*yield*/, this.buildTransactionEventPayload(params)];
699
+ case 1:
700
+ payload = _a.sent();
701
+ this.transaction(__assign({ status: TransactionStatus.STARTED }, payload));
702
+ return [3 /*break*/, 3];
703
+ case 2:
704
+ e_3 = _a.sent();
705
+ logger.error("Formo: Failed to track transaction start", e_3);
706
+ return [3 /*break*/, 3];
707
+ case 3: return [2 /*return*/];
708
+ }
709
+ });
710
+ }); })();
711
+ _c.label = 5;
712
+ case 5:
713
+ _c.trys.push([5, 7, , 8]);
714
+ return [4 /*yield*/, request({
715
+ method: method,
716
+ params: params,
717
+ })];
718
+ case 6:
719
+ transactionHash_1 = (_c.sent());
720
+ (function () { return __awaiter(_this, void 0, void 0, function () {
721
+ var payload, e_4;
722
+ return __generator(this, function (_a) {
723
+ switch (_a.label) {
724
+ case 0:
725
+ _a.trys.push([0, 2, , 3]);
726
+ return [4 /*yield*/, this.buildTransactionEventPayload(params)];
727
+ case 1:
728
+ payload = _a.sent();
729
+ this.transaction(__assign(__assign({ status: TransactionStatus.BROADCASTED }, payload), { transactionHash: transactionHash_1 }));
730
+ // Start async polling for transaction receipt
731
+ this.pollTransactionReceipt(transactionHash_1, payload);
732
+ return [3 /*break*/, 3];
733
+ case 2:
734
+ e_4 = _a.sent();
735
+ logger.error("Formo: Failed to track transaction broadcast", e_4);
736
+ return [3 /*break*/, 3];
737
+ case 3: return [2 /*return*/];
738
+ }
739
+ });
740
+ }); })();
741
+ return [2 /*return*/, transactionHash_1];
742
+ case 7:
743
+ error_2 = _c.sent();
744
+ (function () { return __awaiter(_this, void 0, void 0, function () {
745
+ var rpcError, payload, e_5;
746
+ return __generator(this, function (_a) {
747
+ switch (_a.label) {
748
+ case 0:
749
+ _a.trys.push([0, 3, , 4]);
750
+ rpcError = error_2;
751
+ if (!(rpcError && (rpcError === null || rpcError === void 0 ? void 0 : rpcError.code) === 4001)) return [3 /*break*/, 2];
752
+ return [4 /*yield*/, this.buildTransactionEventPayload(params)];
753
+ case 1:
754
+ payload = _a.sent();
755
+ this.transaction(__assign({ status: TransactionStatus.REJECTED }, payload));
756
+ _a.label = 2;
757
+ case 2: return [3 /*break*/, 4];
758
+ case 3:
759
+ e_5 = _a.sent();
760
+ logger.error("Formo: Failed to track transaction rejection", e_5);
761
+ return [3 /*break*/, 4];
762
+ case 4: return [2 /*return*/];
763
+ }
764
+ });
765
+ }); })();
766
+ throw error_2;
767
+ case 8: return [2 /*return*/, request({ method: method, params: params })];
768
+ }
769
+ });
770
+ }); };
771
+ };
772
+ FormoAnalytics.prototype.onLocationChange = function () {
695
773
  return __awaiter(this, void 0, void 0, function () {
774
+ var currentUrl;
696
775
  return __generator(this, function (_a) {
697
- if (cookie().get(SESSION_CURRENT_URL_KEY) === null) {
776
+ currentUrl = cookie().get(SESSION_CURRENT_URL_KEY);
777
+ if (currentUrl !== window.location.href) {
698
778
  cookie().set(SESSION_CURRENT_URL_KEY, window.location.href);
779
+ this.trackPageHit();
699
780
  }
700
- return [2 /*return*/, this.trackPageHit()];
781
+ return [2 /*return*/];
701
782
  });
702
783
  });
703
784
  };
@@ -732,25 +813,13 @@ var FormoAnalytics = /** @class */ (function () {
732
813
  });
733
814
  });
734
815
  };
735
- FormoAnalytics.prototype.onLocationChange = function () {
736
- return __awaiter(this, void 0, void 0, function () {
737
- var currentUrl;
738
- return __generator(this, function (_a) {
739
- currentUrl = cookie().get(SESSION_CURRENT_URL_KEY);
740
- if (currentUrl !== window.location.href) {
741
- cookie().set(SESSION_CURRENT_URL_KEY, window.location.href);
742
- this.trackPageHit();
743
- }
744
- return [2 /*return*/];
745
- });
746
- });
747
- };
748
816
  FormoAnalytics.prototype.trackPageHit = function (category, name, properties, context, callback) {
749
817
  return __awaiter(this, void 0, void 0, function () {
750
818
  var _this = this;
751
819
  return __generator(this, function (_a) {
752
- if (!this.config.trackLocalhost && isLocalhost()) {
753
- return [2 /*return*/, logger.warn("Track page hit: Ignoring event because website is running locally")];
820
+ if (!this.shouldTrack()) {
821
+ logger.info("Track page hit: Skipping event due to tracking configuration");
822
+ return [2 /*return*/];
754
823
  }
755
824
  setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
756
825
  return __generator(this, function (_a) {
@@ -769,6 +838,10 @@ var FormoAnalytics = /** @class */ (function () {
769
838
  return __awaiter(this, void 0, void 0, function () {
770
839
  return __generator(this, function (_a) {
771
840
  try {
841
+ if (!this.shouldTrack()) {
842
+ logger.info("Skipping ".concat(type, " event due to tracking configuration"));
843
+ return [2 /*return*/];
844
+ }
772
845
  this.eventManager.addEvent(__assign(__assign({ type: type }, payload), { properties: properties, context: context, callback: callback }), this.currentAddress, this.currentUserId);
773
846
  }
774
847
  catch (error) {
@@ -778,6 +851,46 @@ var FormoAnalytics = /** @class */ (function () {
778
851
  });
779
852
  });
780
853
  };
854
+ /**
855
+ * Determines if tracking should be enabled based on configuration
856
+ * @returns {boolean} True if tracking should be enabled
857
+ */
858
+ FormoAnalytics.prototype.shouldTrack = function () {
859
+ // Check if tracking is explicitly provided as a boolean
860
+ if (typeof this.options.tracking === 'boolean') {
861
+ return this.options.tracking;
862
+ }
863
+ // Handle object configuration with exclusion rules
864
+ if (this.options.tracking !== null &&
865
+ typeof this.options.tracking === 'object' &&
866
+ !Array.isArray(this.options.tracking)) {
867
+ var _a = this.options.tracking, _b = _a.excludeHosts, excludeHosts = _b === void 0 ? [] : _b, _c = _a.excludePaths, excludePaths = _c === void 0 ? [] : _c, _d = _a.excludeChains, excludeChains = _d === void 0 ? [] : _d;
868
+ // Check hostname exclusions - use exact matching
869
+ if (excludeHosts.length > 0 && typeof window !== 'undefined') {
870
+ var hostname = window.location.hostname;
871
+ if (excludeHosts.includes(hostname)) {
872
+ return false;
873
+ }
874
+ }
875
+ // Check path exclusions - use exact matching
876
+ if (excludePaths.length > 0 && typeof window !== 'undefined') {
877
+ var pathname = window.location.pathname;
878
+ if (excludePaths.includes(pathname)) {
879
+ return false;
880
+ }
881
+ }
882
+ // Check chainId exclusions
883
+ if (excludeChains.length > 0 &&
884
+ this.currentChainId &&
885
+ excludeChains.includes(this.currentChainId)) {
886
+ return false;
887
+ }
888
+ // If nothing is excluded, tracking is enabled
889
+ return true;
890
+ }
891
+ // Default behavior: track everywhere except localhost
892
+ return !isLocalhost();
893
+ };
781
894
  /*
782
895
  Utility functions
783
896
  */
@@ -933,7 +1046,7 @@ var FormoAnalytics = /** @class */ (function () {
933
1046
  logger.info("Chain id not found");
934
1047
  return [2 /*return*/, 0];
935
1048
  }
936
- return [2 /*return*/, parseInt(chainIdHex, 16)];
1049
+ return [2 /*return*/, parseChainId(chainIdHex)];
937
1050
  case 3:
938
1051
  err_5 = _b.sent();
939
1052
  logger.error("eth_chainId threw an error:", err_5);
@@ -981,6 +1094,62 @@ var FormoAnalytics = /** @class */ (function () {
981
1094
  });
982
1095
  });
983
1096
  };
1097
+ /**
1098
+ * Polls for transaction receipt and emits tx.status = CONFIRMED or REVERTED.
1099
+ */
1100
+ FormoAnalytics.prototype.pollTransactionReceipt = function (transactionHash_2, payload_1) {
1101
+ return __awaiter(this, arguments, void 0, function (transactionHash, payload, maxAttempts, intervalMs) {
1102
+ var attempts, provider, poll;
1103
+ var _this = this;
1104
+ if (maxAttempts === void 0) { maxAttempts = 10; }
1105
+ if (intervalMs === void 0) { intervalMs = 3000; }
1106
+ return __generator(this, function (_a) {
1107
+ attempts = 0;
1108
+ provider = this.provider;
1109
+ if (!provider)
1110
+ return [2 /*return*/];
1111
+ poll = function () { return __awaiter(_this, void 0, void 0, function () {
1112
+ var receipt, e_6;
1113
+ return __generator(this, function (_a) {
1114
+ switch (_a.label) {
1115
+ case 0:
1116
+ _a.trys.push([0, 2, , 3]);
1117
+ return [4 /*yield*/, provider.request({
1118
+ method: "eth_getTransactionReceipt",
1119
+ params: [transactionHash],
1120
+ })];
1121
+ case 1:
1122
+ receipt = (_a.sent());
1123
+ if (receipt) {
1124
+ // status: 1 = success, 0 = reverted
1125
+ if (receipt.status === "0x1" || receipt.status === 1) {
1126
+ this.transaction(__assign(__assign({ status: TransactionStatus.CONFIRMED }, payload), { transactionHash: transactionHash }));
1127
+ return [2 /*return*/];
1128
+ }
1129
+ else if (receipt.status === "0x0" || receipt.status === 0) {
1130
+ this.transaction(__assign(__assign({ status: TransactionStatus.REVERTED }, payload), { transactionHash: transactionHash }));
1131
+ return [2 /*return*/];
1132
+ }
1133
+ }
1134
+ return [3 /*break*/, 3];
1135
+ case 2:
1136
+ e_6 = _a.sent();
1137
+ logger.error("Error polling transaction receipt", e_6);
1138
+ return [3 /*break*/, 3];
1139
+ case 3:
1140
+ attempts++;
1141
+ if (attempts < maxAttempts) {
1142
+ setTimeout(poll, intervalMs);
1143
+ }
1144
+ return [2 /*return*/];
1145
+ }
1146
+ });
1147
+ }); };
1148
+ poll();
1149
+ return [2 /*return*/];
1150
+ });
1151
+ });
1152
+ };
984
1153
  return FormoAnalytics;
985
1154
  }());
986
1155
  export { FormoAnalytics };