@formo/analytics 1.19.10 → 1.21.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 (55) hide show
  1. package/README.md +3 -1
  2. package/dist/cjs/src/FormoAnalytics.d.ts +17 -1
  3. package/dist/cjs/src/FormoAnalytics.js +150 -82
  4. package/dist/cjs/src/FormoAnalyticsProvider.js +5 -1
  5. package/dist/cjs/src/constants/base.d.ts +4 -0
  6. package/dist/cjs/src/constants/base.js +8 -1
  7. package/dist/cjs/src/lib/browser/browsers.d.ts +3 -0
  8. package/dist/cjs/src/lib/browser/browsers.js +132 -0
  9. package/dist/cjs/src/lib/consent.d.ts +35 -0
  10. package/dist/cjs/src/lib/consent.js +102 -0
  11. package/dist/cjs/src/lib/event/EventFactory.d.ts +10 -10
  12. package/dist/cjs/src/lib/event/EventFactory.js +272 -140
  13. package/dist/cjs/src/lib/event/EventManager.d.ts +1 -1
  14. package/dist/cjs/src/lib/event/EventManager.js +62 -9
  15. package/dist/cjs/src/lib/event/type.d.ts +2 -2
  16. package/dist/cjs/src/lib/index.d.ts +1 -0
  17. package/dist/cjs/src/lib/index.js +1 -0
  18. package/dist/cjs/src/lib/storage/built-in/blueprint.js +2 -1
  19. package/dist/cjs/src/lib/version.d.ts +1 -1
  20. package/dist/cjs/src/lib/version.js +1 -1
  21. package/dist/cjs/src/types/base.d.ts +3 -0
  22. package/dist/cjs/src/utils/address.d.ts +7 -0
  23. package/dist/cjs/src/utils/address.js +21 -1
  24. package/dist/cjs/src/utils/hash.d.ts +10 -0
  25. package/dist/cjs/src/utils/hash.js +21 -0
  26. package/dist/cjs/src/utils/index.d.ts +1 -0
  27. package/dist/cjs/src/utils/index.js +1 -0
  28. package/dist/esm/src/FormoAnalytics.d.ts +17 -1
  29. package/dist/esm/src/FormoAnalytics.js +152 -84
  30. package/dist/esm/src/FormoAnalyticsProvider.js +5 -1
  31. package/dist/esm/src/constants/base.d.ts +4 -0
  32. package/dist/esm/src/constants/base.js +7 -0
  33. package/dist/esm/src/lib/browser/browsers.d.ts +3 -0
  34. package/dist/esm/src/lib/browser/browsers.js +129 -0
  35. package/dist/esm/src/lib/consent.d.ts +35 -0
  36. package/dist/esm/src/lib/consent.js +97 -0
  37. package/dist/esm/src/lib/event/EventFactory.d.ts +10 -10
  38. package/dist/esm/src/lib/event/EventFactory.js +272 -140
  39. package/dist/esm/src/lib/event/EventManager.d.ts +1 -1
  40. package/dist/esm/src/lib/event/EventManager.js +62 -9
  41. package/dist/esm/src/lib/event/type.d.ts +2 -2
  42. package/dist/esm/src/lib/index.d.ts +1 -0
  43. package/dist/esm/src/lib/index.js +1 -0
  44. package/dist/esm/src/lib/storage/built-in/blueprint.js +2 -1
  45. package/dist/esm/src/lib/version.d.ts +1 -1
  46. package/dist/esm/src/lib/version.js +1 -1
  47. package/dist/esm/src/types/base.d.ts +3 -0
  48. package/dist/esm/src/utils/address.d.ts +7 -0
  49. package/dist/esm/src/utils/address.js +19 -0
  50. package/dist/esm/src/utils/hash.d.ts +10 -0
  51. package/dist/esm/src/utils/hash.js +18 -0
  52. package/dist/esm/src/utils/index.d.ts +1 -0
  53. package/dist/esm/src/utils/index.js +1 -0
  54. package/dist/index.umd.min.js +1 -1
  55. package/package.json +2 -2
@@ -55,8 +55,8 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
55
55
  return to.concat(ar || Array.prototype.slice.call(from));
56
56
  };
57
57
  import { createStore } from "mipd";
58
- import { EVENTS_API_URL, EventType, LOCAL_ANONYMOUS_ID_KEY, SESSION_CURRENT_URL_KEY, SESSION_USER_ID_KEY, SESSION_WALLET_DETECTED_KEY, SESSION_WALLET_IDENTIFIED_KEY, DEFAULT_PROVIDER_ICON, } from "./constants";
59
- import { cookie, EventManager, EventQueue, initStorageManager, logger, Logger, } from "./lib";
58
+ import { EVENTS_API_URL, EventType, LOCAL_ANONYMOUS_ID_KEY, SESSION_CURRENT_URL_KEY, SESSION_USER_ID_KEY, SESSION_WALLET_DETECTED_KEY, SESSION_WALLET_IDENTIFIED_KEY, DEFAULT_PROVIDER_ICON, CONSENT_OPT_OUT_KEY, } from "./constants";
59
+ import { cookie, EventManager, EventQueue, initStorageManager, logger, Logger, setConsentFlag, getConsentFlag, removeConsentFlag, } from "./lib";
60
60
  import { SignatureStatus, TransactionStatus, WRAPPED_REQUEST_SYMBOL, WRAPPED_REQUEST_REF_SYMBOL, } from "./types";
61
61
  import { toChecksumAddress } from "./utils";
62
62
  import { getValidAddress } from "./utils/address";
@@ -68,7 +68,7 @@ import { parseChainId } from "./utils/chain";
68
68
  var PROVIDER_SWITCH_REASONS = {
69
69
  ADDRESS_MISMATCH: "Address mismatch indicates wallet switch",
70
70
  NO_ACCOUNTS: "Current provider has no accounts",
71
- CHECK_FAILED: "Could not check current provider accounts"
71
+ CHECK_FAILED: "Could not check current provider accounts",
72
72
  };
73
73
  var FormoAnalytics = /** @class */ (function () {
74
74
  function FormoAnalytics(writeKey, options) {
@@ -123,13 +123,17 @@ var FormoAnalytics = /** @class */ (function () {
123
123
  maxQueueSize: options.maxQueueSize,
124
124
  flushInterval: options.flushInterval,
125
125
  }));
126
+ // Check consent status on initialization
127
+ if (this.hasOptedOutTracking()) {
128
+ logger.info("User has previously opted out of tracking");
129
+ }
126
130
  // Handle initial provider (injected) as fallback; listeners for EIP-6963 are added later
127
131
  var provider = undefined;
128
132
  var optProvider = options.provider;
129
133
  if (optProvider) {
130
134
  provider = optProvider;
131
135
  }
132
- else if (typeof window !== 'undefined' && window.ethereum) {
136
+ else if (typeof window !== "undefined" && window.ethereum) {
133
137
  provider = window.ethereum;
134
138
  }
135
139
  if (provider) {
@@ -156,9 +160,9 @@ var FormoAnalytics = /** @class */ (function () {
156
160
  FormoAnalytics.prototype.isProviderInValidState = function (provider) {
157
161
  // Basic validation: ensure provider exists and has required methods
158
162
  return (provider &&
159
- typeof provider.request === 'function' &&
160
- typeof provider.on === 'function' &&
161
- typeof provider.removeListener === 'function');
163
+ typeof provider.request === "function" &&
164
+ typeof provider.on === "function" &&
165
+ typeof provider.removeListener === "function");
162
166
  };
163
167
  FormoAnalytics.init = function (writeKey, options) {
164
168
  return __awaiter(this, void 0, void 0, function () {
@@ -277,16 +281,18 @@ var FormoAnalytics = /** @class */ (function () {
277
281
  case 0:
278
282
  chainId = (params === null || params === void 0 ? void 0 : params.chainId) || this.currentChainId;
279
283
  address = (params === null || params === void 0 ? void 0 : params.address) || this.currentAddress;
280
- providerInfo = this._provider ? this.getProviderInfo(this._provider) : null;
284
+ providerInfo = this._provider
285
+ ? this.getProviderInfo(this._provider)
286
+ : null;
281
287
  logger.info("Disconnect: Emitting disconnect event with:", {
282
288
  chainId: chainId,
283
289
  address: address,
284
290
  providerName: providerInfo === null || providerInfo === void 0 ? void 0 : providerInfo.name,
285
- rdns: providerInfo === null || providerInfo === void 0 ? void 0 : providerInfo.rdns
291
+ rdns: providerInfo === null || providerInfo === void 0 ? void 0 : providerInfo.rdns,
286
292
  });
287
293
  disconnectProperties = __assign(__assign({}, (providerInfo && {
288
294
  providerName: providerInfo.name,
289
- rdns: providerInfo.rdns
295
+ rdns: providerInfo.rdns,
290
296
  })), properties);
291
297
  return [4 /*yield*/, this.trackEvent(EventType.DISCONNECT, __assign(__assign({}, (chainId && { chainId: chainId })), (address && { address: address })), disconnectProperties, context, callback)];
292
298
  case 1:
@@ -433,9 +439,12 @@ var FormoAnalytics = /** @class */ (function () {
433
439
  validAddress: validAddress_1,
434
440
  rdns: providerDetail.info.rdns,
435
441
  providerName: providerDetail.info.name,
436
- isAlreadyIdentified: validAddress_1 ? this.session.isWalletIdentified(validAddress_1, providerDetail.info.rdns) : false
442
+ isAlreadyIdentified: validAddress_1
443
+ ? this.session.isWalletIdentified(validAddress_1, providerDetail.info.rdns)
444
+ : false,
437
445
  });
438
- if (!(validAddress_1 && !this.session.isWalletIdentified(validAddress_1, providerDetail.info.rdns))) return [3 /*break*/, 5];
446
+ if (!(validAddress_1 &&
447
+ !this.session.isWalletIdentified(validAddress_1, providerDetail.info.rdns))) return [3 /*break*/, 5];
439
448
  logger.info("Auto-identifying", validAddress_1, providerDetail.info.name, providerDetail.info.rdns);
440
449
  // NOTE: do not set this.currentAddress without explicit connect or identify
441
450
  return [4 /*yield*/, this.identify({
@@ -479,23 +488,25 @@ var FormoAnalytics = /** @class */ (function () {
479
488
  this.currentUserId = userId;
480
489
  cookie().set(SESSION_USER_ID_KEY, userId);
481
490
  }
482
- isAlreadyIdentified = validAddress ? this.session.isWalletIdentified(validAddress, rdns || '') : false;
491
+ isAlreadyIdentified = validAddress
492
+ ? this.session.isWalletIdentified(validAddress, rdns || "")
493
+ : false;
483
494
  logger.debug("Identify: Checking deduplication", {
484
495
  validAddress: validAddress,
485
496
  rdns: rdns,
486
497
  providerName: providerName,
487
498
  hasValidAddress: !!validAddress,
488
499
  hasRdns: !!rdns,
489
- isAlreadyIdentified: isAlreadyIdentified
500
+ isAlreadyIdentified: isAlreadyIdentified,
490
501
  });
491
502
  if (isAlreadyIdentified) {
492
- logger.info("Identify: Wallet ".concat(providerName || 'Unknown', " with address ").concat(validAddress, " already identified in this session (rdns: ").concat(rdns || 'empty', ")"));
503
+ logger.info("Identify: Wallet ".concat(providerName || "Unknown", " with address ").concat(validAddress, " already identified in this session (rdns: ").concat(rdns || "empty", ")"));
493
504
  return [2 /*return*/];
494
505
  }
495
506
  // Mark as identified before emitting the event
496
507
  // Mark even if rdns is empty to prevent duplicate empty identifies
497
508
  if (validAddress) {
498
- this.session.markWalletIdentified(validAddress, rdns || '');
509
+ this.session.markWalletIdentified(validAddress, rdns || "");
499
510
  }
500
511
  return [4 /*yield*/, this.trackEvent(EventType.IDENTIFY, {
501
512
  address: validAddress,
@@ -564,6 +575,39 @@ var FormoAnalytics = /** @class */ (function () {
564
575
  });
565
576
  });
566
577
  };
578
+ /*
579
+ Consent management functions
580
+ */
581
+ /**
582
+ * Opt out of tracking.
583
+ * @returns {void}
584
+ */
585
+ FormoAnalytics.prototype.optOutTracking = function () {
586
+ logger.info("Opting out of tracking");
587
+ // Set opt-out flag in persistent storage using direct cookie access
588
+ // This must be done before switching storage to ensure persistence
589
+ setConsentFlag(this.writeKey, CONSENT_OPT_OUT_KEY, "true");
590
+ this.reset();
591
+ logger.info("Successfully opted out of tracking");
592
+ };
593
+ /**
594
+ * Opt back into tracking after previously opting out. This will re-enable analytics tracking
595
+ * and switch back to persistent storage.
596
+ * @returns {void}
597
+ */
598
+ FormoAnalytics.prototype.optInTracking = function () {
599
+ logger.info("Opting back into tracking");
600
+ // Remove opt-out flag
601
+ removeConsentFlag(this.writeKey, CONSENT_OPT_OUT_KEY);
602
+ logger.info("Successfully opted back into tracking");
603
+ };
604
+ /**
605
+ * Check if the user has opted out of tracking.
606
+ * @returns {boolean} True if the user has opted out
607
+ */
608
+ FormoAnalytics.prototype.hasOptedOutTracking = function () {
609
+ return getConsentFlag(this.writeKey, CONSENT_OPT_OUT_KEY) === "true";
610
+ };
567
611
  /*
568
612
  SDK tracking and event listener functions
569
613
  */
@@ -630,7 +674,7 @@ var FormoAnalytics = /** @class */ (function () {
630
674
  // Prevent concurrent processing of accountsChanged events to avoid race conditions
631
675
  if (this._processingAccountsChanged) {
632
676
  logger.debug("OnAccountsChanged: Already processing accountsChanged, skipping", {
633
- provider: this.getProviderInfo(provider).name
677
+ provider: this.getProviderInfo(provider).name,
634
678
  });
635
679
  return [2 /*return*/];
636
680
  }
@@ -671,7 +715,7 @@ var FormoAnalytics = /** @class */ (function () {
671
715
  logger.info("OnAccountsChanged: Detecting disconnect, current state:", {
672
716
  currentAddress: this.currentAddress,
673
717
  currentChainId: this.currentChainId,
674
- providerMatch: this._provider === provider
718
+ providerMatch: this._provider === provider,
675
719
  });
676
720
  _a.label = 1;
677
721
  case 1:
@@ -679,7 +723,7 @@ var FormoAnalytics = /** @class */ (function () {
679
723
  // Pass current state explicitly to ensure we have the data for the disconnect event
680
724
  return [4 /*yield*/, this.disconnect({
681
725
  chainId: this.currentChainId,
682
- address: this.currentAddress
726
+ address: this.currentAddress,
683
727
  })];
684
728
  case 2:
685
729
  // Pass current state explicitly to ensure we have the data for the disconnect event
@@ -707,7 +751,7 @@ var FormoAnalytics = /** @class */ (function () {
707
751
  activeProvider: this.getProviderInfo(this._provider).name,
708
752
  eventProvider: this.getProviderInfo(provider).name,
709
753
  currentStoredAddress: currentStoredAddress,
710
- newProviderAddress: newProviderAddress
754
+ newProviderAddress: newProviderAddress,
711
755
  });
712
756
  _a.label = 8;
713
757
  case 8:
@@ -717,22 +761,26 @@ var FormoAnalytics = /** @class */ (function () {
717
761
  activeProviderAccounts = _a.sent();
718
762
  logger.info("OnAccountsChanged: Checking current provider accounts", {
719
763
  activeProvider: this.getProviderInfo(this._provider).name,
720
- accountsLength: activeProviderAccounts ? activeProviderAccounts.length : 0,
721
- accounts: activeProviderAccounts
764
+ accountsLength: activeProviderAccounts
765
+ ? activeProviderAccounts.length
766
+ : 0,
767
+ accounts: activeProviderAccounts,
722
768
  });
723
769
  if (!(activeProviderAccounts && activeProviderAccounts.length > 0)) return [3 /*break*/, 13];
724
- if (!(newProviderAddress && currentStoredAddress && newProviderAddress !== currentStoredAddress)) return [3 /*break*/, 11];
770
+ if (!(newProviderAddress &&
771
+ currentStoredAddress &&
772
+ newProviderAddress !== currentStoredAddress)) return [3 /*break*/, 11];
725
773
  logger.info("OnAccountsChanged: Different address detected, switching providers despite current provider having accounts", {
726
774
  activeProvider: this.getProviderInfo(this._provider).name,
727
775
  eventProvider: this.getProviderInfo(provider).name,
728
776
  currentAddress: currentStoredAddress,
729
777
  newAddress: newProviderAddress,
730
- reason: PROVIDER_SWITCH_REASONS.ADDRESS_MISMATCH
778
+ reason: PROVIDER_SWITCH_REASONS.ADDRESS_MISMATCH,
731
779
  });
732
780
  // Emit disconnect for the old provider
733
781
  return [4 /*yield*/, this.disconnect({
734
782
  chainId: this.currentChainId,
735
- address: this.currentAddress
783
+ address: this.currentAddress,
736
784
  })];
737
785
  case 10:
738
786
  // Emit disconnect for the old provider
@@ -746,7 +794,7 @@ var FormoAnalytics = /** @class */ (function () {
746
794
  eventProvider: this.getProviderInfo(provider).name,
747
795
  activeProviderAccountsCount: activeProviderAccounts.length,
748
796
  currentAddress: currentStoredAddress,
749
- newAddress: newProviderAddress
797
+ newAddress: newProviderAddress,
750
798
  });
751
799
  return [2 /*return*/];
752
800
  case 12: return [3 /*break*/, 15];
@@ -754,12 +802,12 @@ var FormoAnalytics = /** @class */ (function () {
754
802
  logger.info("OnAccountsChanged: Current provider has no accounts, switching to new provider", {
755
803
  oldProvider: this.getProviderInfo(this._provider).name,
756
804
  newProvider: this.getProviderInfo(provider).name,
757
- reason: PROVIDER_SWITCH_REASONS.NO_ACCOUNTS
805
+ reason: PROVIDER_SWITCH_REASONS.NO_ACCOUNTS,
758
806
  });
759
807
  // Emit disconnect for the old provider that didn't signal properly
760
808
  return [4 /*yield*/, this.disconnect({
761
809
  chainId: this.currentChainId,
762
- address: this.currentAddress
810
+ address: this.currentAddress,
763
811
  })];
764
812
  case 14:
765
813
  // Emit disconnect for the old provider that didn't signal properly
@@ -773,14 +821,16 @@ var FormoAnalytics = /** @class */ (function () {
773
821
  logger.warn("OnAccountsChanged: Could not check current provider accounts, switching to new provider", {
774
822
  error: error_2 instanceof Error ? error_2.message : String(error_2),
775
823
  errorType: error_2 instanceof Error ? error_2.constructor.name : typeof error_2,
776
- oldProvider: this._provider ? this.getProviderInfo(this._provider).name : 'unknown',
824
+ oldProvider: this._provider
825
+ ? this.getProviderInfo(this._provider).name
826
+ : "unknown",
777
827
  newProvider: this.getProviderInfo(provider).name,
778
- reason: PROVIDER_SWITCH_REASONS.CHECK_FAILED
828
+ reason: PROVIDER_SWITCH_REASONS.CHECK_FAILED,
779
829
  });
780
830
  // If we can't check the current provider, assume it's disconnected
781
831
  return [4 /*yield*/, this.disconnect({
782
832
  chainId: this.currentChainId,
783
- address: this.currentAddress
833
+ address: this.currentAddress,
784
834
  })];
785
835
  case 17:
786
836
  // If we can't check the current provider, assume it's disconnected
@@ -809,7 +859,7 @@ var FormoAnalytics = /** @class */ (function () {
809
859
  wasDisconnected: wasDisconnected,
810
860
  providerName: providerInfo.name,
811
861
  rdns: providerInfo.rdns,
812
- hasChainId: !!nextChainId
862
+ hasChainId: !!nextChainId,
813
863
  });
814
864
  effectiveChainId = nextChainId || 0;
815
865
  if (effectiveChainId === 0) {
@@ -817,10 +867,10 @@ var FormoAnalytics = /** @class */ (function () {
817
867
  }
818
868
  this.connect({
819
869
  chainId: effectiveChainId,
820
- address: address
870
+ address: address,
821
871
  }, {
822
872
  providerName: providerInfo.name,
823
- rdns: providerInfo.rdns
873
+ rdns: providerInfo.rdns,
824
874
  }).catch(function (error) {
825
875
  logger.error("Failed to track connect event during account change:", error);
826
876
  });
@@ -902,7 +952,7 @@ var FormoAnalytics = /** @class */ (function () {
902
952
  return [2 /*return*/];
903
953
  logger.info("OnDisconnect: Wallet disconnect event received, current state:", {
904
954
  currentAddress: this.currentAddress,
905
- currentChainId: this.currentChainId
955
+ currentChainId: this.currentChainId,
906
956
  });
907
957
  _a.label = 1;
908
958
  case 1:
@@ -910,7 +960,7 @@ var FormoAnalytics = /** @class */ (function () {
910
960
  // Pass current state explicitly to ensure we have the data for the disconnect event
911
961
  return [4 /*yield*/, this.disconnect({
912
962
  chainId: this.currentChainId,
913
- address: this.currentAddress
963
+ address: this.currentAddress,
914
964
  })];
915
965
  case 2:
916
966
  // Pass current state explicitly to ensure we have the data for the disconnect event
@@ -937,7 +987,7 @@ var FormoAnalytics = /** @class */ (function () {
937
987
  _a.label = 1;
938
988
  case 1:
939
989
  _a.trys.push([1, 3, , 4]);
940
- if (!(connection === null || connection === void 0 ? void 0 : connection.chainId) || typeof connection.chainId !== 'string')
990
+ if (!(connection === null || connection === void 0 ? void 0 : connection.chainId) || typeof connection.chainId !== "string")
941
991
  return [2 /*return*/];
942
992
  chainId = parseChainId(connection.chainId);
943
993
  return [4 /*yield*/, this.getAddress(provider)];
@@ -953,7 +1003,8 @@ var FormoAnalytics = /** @class */ (function () {
953
1003
  // Only update global state (chainId/address) from the active provider
954
1004
  if (isActiveProvider) {
955
1005
  this.currentChainId = chainId;
956
- this.currentAddress = this.validateAndChecksumAddress(address) || undefined;
1006
+ this.currentAddress =
1007
+ this.validateAndChecksumAddress(address) || undefined;
957
1008
  }
958
1009
  if (isActiveProvider && this.currentAddress) {
959
1010
  providerInfo = this.getProviderInfo(provider);
@@ -963,7 +1014,7 @@ var FormoAnalytics = /** @class */ (function () {
963
1014
  providerName: providerInfo.name,
964
1015
  rdns: providerInfo.rdns,
965
1016
  hasChainId: !!chainId,
966
- isActiveProvider: isActiveProvider
1017
+ isActiveProvider: isActiveProvider,
967
1018
  });
968
1019
  effectiveChainId = chainId || 0;
969
1020
  if (effectiveChainId === 0) {
@@ -971,10 +1022,10 @@ var FormoAnalytics = /** @class */ (function () {
971
1022
  }
972
1023
  this.connect({
973
1024
  chainId: effectiveChainId,
974
- address: address
1025
+ address: address,
975
1026
  }, {
976
1027
  providerName: providerInfo.name,
977
- rdns: providerInfo.rdns
1028
+ rdns: providerInfo.rdns,
978
1029
  }).catch(function (error) {
979
1030
  logger.error("Failed to track connect event during provider connection:", error);
980
1031
  });
@@ -986,7 +1037,9 @@ var FormoAnalytics = /** @class */ (function () {
986
1037
  providerName: providerInfo.name,
987
1038
  rdns: providerInfo.rdns,
988
1039
  isActiveProvider: isActiveProvider,
989
- activeProviderInfo: this._provider ? this.getProviderInfo(this._provider) : null
1040
+ activeProviderInfo: this._provider
1041
+ ? this.getProviderInfo(this._provider)
1042
+ : null,
990
1043
  });
991
1044
  }
992
1045
  }
@@ -1168,7 +1221,8 @@ var FormoAnalytics = /** @class */ (function () {
1168
1221
  }); };
1169
1222
  // Mark the wrapper so we can detect if request is replaced externally and keep a reference on provider
1170
1223
  wrappedRequest[WRAPPED_REQUEST_SYMBOL] = true;
1171
- provider[WRAPPED_REQUEST_REF_SYMBOL] = wrappedRequest;
1224
+ provider[WRAPPED_REQUEST_REF_SYMBOL] =
1225
+ wrappedRequest;
1172
1226
  try {
1173
1227
  // Attempt to assign the wrapped request function (rely on try-catch for mutability errors)
1174
1228
  provider.request = wrappedRequest;
@@ -1258,44 +1312,55 @@ var FormoAnalytics = /** @class */ (function () {
1258
1312
  };
1259
1313
  FormoAnalytics.prototype.trackEvent = function (type, payload, properties, context, callback) {
1260
1314
  return __awaiter(this, void 0, void 0, function () {
1315
+ var error_5;
1261
1316
  return __generator(this, function (_a) {
1262
- try {
1263
- if (!this.shouldTrack()) {
1264
- logger.info("Skipping ".concat(type, " event due to tracking configuration"));
1265
- return [2 /*return*/];
1266
- }
1267
- this.eventManager.addEvent(__assign(__assign({ type: type }, payload), { properties: properties, context: context, callback: callback }), this.currentAddress, this.currentUserId);
1268
- }
1269
- catch (error) {
1270
- logger.error("Error tracking event:", error);
1317
+ switch (_a.label) {
1318
+ case 0:
1319
+ _a.trys.push([0, 2, , 3]);
1320
+ if (!this.shouldTrack()) {
1321
+ logger.info("Skipping ".concat(type, " event due to tracking configuration"));
1322
+ return [2 /*return*/];
1323
+ }
1324
+ return [4 /*yield*/, this.eventManager.addEvent(__assign(__assign({ type: type }, payload), { properties: properties, context: context, callback: callback }), this.currentAddress, this.currentUserId)];
1325
+ case 1:
1326
+ _a.sent();
1327
+ return [3 /*break*/, 3];
1328
+ case 2:
1329
+ error_5 = _a.sent();
1330
+ logger.error("Error tracking event:", error_5);
1331
+ return [3 /*break*/, 3];
1332
+ case 3: return [2 /*return*/];
1271
1333
  }
1272
- return [2 /*return*/];
1273
1334
  });
1274
1335
  });
1275
1336
  };
1276
1337
  /**
1277
- * Determines if tracking should be enabled based on configuration
1338
+ * Determines if tracking should be enabled based on configuration and consent
1278
1339
  * @returns {boolean} True if tracking should be enabled
1279
1340
  */
1280
1341
  FormoAnalytics.prototype.shouldTrack = function () {
1342
+ // First check if user has opted out of tracking
1343
+ if (this.hasOptedOutTracking()) {
1344
+ return false;
1345
+ }
1281
1346
  // Check if tracking is explicitly provided as a boolean
1282
- if (typeof this.options.tracking === 'boolean') {
1347
+ if (typeof this.options.tracking === "boolean") {
1283
1348
  return this.options.tracking;
1284
1349
  }
1285
1350
  // Handle object configuration with exclusion rules
1286
1351
  if (this.options.tracking !== null &&
1287
- typeof this.options.tracking === 'object' &&
1352
+ typeof this.options.tracking === "object" &&
1288
1353
  !Array.isArray(this.options.tracking)) {
1289
1354
  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;
1290
1355
  // Check hostname exclusions - use exact matching
1291
- if (excludeHosts.length > 0 && typeof window !== 'undefined') {
1356
+ if (excludeHosts.length > 0 && typeof window !== "undefined") {
1292
1357
  var hostname = window.location.hostname;
1293
1358
  if (excludeHosts.includes(hostname)) {
1294
1359
  return false;
1295
1360
  }
1296
1361
  }
1297
1362
  // Check path exclusions - use exact matching
1298
- if (excludePaths.length > 0 && typeof window !== 'undefined') {
1363
+ if (excludePaths.length > 0 && typeof window !== "undefined") {
1299
1364
  var pathname = window.location.pathname;
1300
1365
  if (excludePaths.includes(pathname)) {
1301
1366
  return false;
@@ -1327,14 +1392,14 @@ var FormoAnalytics = /** @class */ (function () {
1327
1392
  if (eip6963Provider) {
1328
1393
  return {
1329
1394
  name: eip6963Provider.info.name,
1330
- rdns: eip6963Provider.info.rdns
1395
+ rdns: eip6963Provider.info.rdns,
1331
1396
  };
1332
1397
  }
1333
1398
  // Fallback to injected provider detection
1334
1399
  var injectedInfo = this.detectInjectedProviderInfo(provider);
1335
1400
  return {
1336
1401
  name: injectedInfo.name,
1337
- rdns: injectedInfo.rdns
1402
+ rdns: injectedInfo.rdns,
1338
1403
  };
1339
1404
  };
1340
1405
  /**
@@ -1344,45 +1409,45 @@ var FormoAnalytics = /** @class */ (function () {
1344
1409
  */
1345
1410
  FormoAnalytics.prototype.detectInjectedProviderInfo = function (provider) {
1346
1411
  // Try to detect provider type from common properties
1347
- var name = 'Injected Provider';
1348
- var rdns = 'io.injected.provider';
1412
+ var name = "Injected Provider";
1413
+ var rdns = "io.injected.provider";
1349
1414
  // Use WalletProviderFlags interface for type safety
1350
1415
  var flags = provider;
1351
1416
  // Check if it's MetaMask
1352
1417
  if (flags.isMetaMask) {
1353
- name = 'MetaMask';
1354
- rdns = 'io.metamask';
1418
+ name = "MetaMask";
1419
+ rdns = "io.metamask";
1355
1420
  }
1356
1421
  // Check if it's Coinbase Wallet
1357
1422
  else if (flags.isCoinbaseWallet) {
1358
- name = 'Coinbase Wallet';
1359
- rdns = 'com.coinbase.wallet';
1423
+ name = "Coinbase Wallet";
1424
+ rdns = "com.coinbase.wallet";
1360
1425
  }
1361
1426
  // Check if it's WalletConnect
1362
1427
  else if (flags.isWalletConnect) {
1363
- name = 'WalletConnect';
1364
- rdns = 'com.walletconnect';
1428
+ name = "WalletConnect";
1429
+ rdns = "com.walletconnect";
1365
1430
  }
1366
1431
  // Check if it's Trust Wallet
1367
1432
  else if (flags.isTrust) {
1368
- name = 'Trust Wallet';
1369
- rdns = 'com.trustwallet';
1433
+ name = "Trust Wallet";
1434
+ rdns = "com.trustwallet";
1370
1435
  }
1371
1436
  // Check if it's Brave Wallet
1372
1437
  else if (flags.isBraveWallet) {
1373
- name = 'Brave Wallet';
1374
- rdns = 'com.brave.wallet';
1438
+ name = "Brave Wallet";
1439
+ rdns = "com.brave.wallet";
1375
1440
  }
1376
1441
  // Check if it's Phantom
1377
1442
  else if (flags.isPhantom) {
1378
- name = 'Phantom';
1379
- rdns = 'app.phantom';
1443
+ name = "Phantom";
1444
+ rdns = "app.phantom";
1380
1445
  }
1381
1446
  return {
1382
1447
  name: name,
1383
1448
  rdns: rdns,
1384
- uuid: "injected-".concat(rdns.replace(/[^a-zA-Z0-9]/g, '-')),
1385
- icon: DEFAULT_PROVIDER_ICON
1449
+ uuid: "injected-".concat(rdns.replace(/[^a-zA-Z0-9]/g, "-")),
1450
+ icon: DEFAULT_PROVIDER_ICON,
1386
1451
  };
1387
1452
  };
1388
1453
  FormoAnalytics.prototype.getProviders = function () {
@@ -1436,7 +1501,7 @@ var FormoAnalytics = /** @class */ (function () {
1436
1501
  });
1437
1502
  // Fallback to injected provider if no providers are found
1438
1503
  if (providers.length === 0) {
1439
- injected_1 = typeof window !== 'undefined' ? window.ethereum : undefined;
1504
+ injected_1 = typeof window !== "undefined" ? window.ethereum : undefined;
1440
1505
  if (injected_1) {
1441
1506
  // If we have already detected and cached the injected provider, and it's the same instance, return the cached result
1442
1507
  if (this._injectedProviderDetail &&
@@ -1447,7 +1512,9 @@ var FormoAnalytics = /** @class */ (function () {
1447
1512
  }
1448
1513
  // Merge with existing providers instead of overwriting
1449
1514
  if (!this._providers.some(function (existing) { return existing.provider === injected_1; })) {
1450
- this._providers = __spreadArray(__spreadArray([], this._providers, true), [this._injectedProviderDetail], false);
1515
+ this._providers = __spreadArray(__spreadArray([], this._providers, true), [
1516
+ this._injectedProviderDetail,
1517
+ ], false);
1451
1518
  }
1452
1519
  return [2 /*return*/, this._providers];
1453
1520
  }
@@ -1458,7 +1525,7 @@ var FormoAnalytics = /** @class */ (function () {
1458
1525
  injectedProviderInfo = this.detectInjectedProviderInfo(injected_1);
1459
1526
  injectedDetail = {
1460
1527
  provider: injected_1,
1461
- info: injectedProviderInfo
1528
+ info: injectedProviderInfo,
1462
1529
  };
1463
1530
  // Cache the detected injected provider detail
1464
1531
  this._injectedProviderDetail = injectedDetail;
@@ -1797,9 +1864,10 @@ var FormoAnalytics = /** @class */ (function () {
1797
1864
  */
1798
1865
  FormoAnalytics.prototype.isProviderAlreadyWrapped = function (provider, currentRequest) {
1799
1866
  return !!(currentRequest &&
1800
- typeof currentRequest === 'function' &&
1867
+ typeof currentRequest === "function" &&
1801
1868
  currentRequest[WRAPPED_REQUEST_SYMBOL] &&
1802
- provider[WRAPPED_REQUEST_REF_SYMBOL] === currentRequest);
1869
+ provider[WRAPPED_REQUEST_REF_SYMBOL] ===
1870
+ currentRequest);
1803
1871
  };
1804
1872
  /**
1805
1873
  * Handle provider mismatch by switching to the new provider and invalidating old tokens
@@ -1888,7 +1956,7 @@ var FormoAnalyticsSession = /** @class */ (function () {
1888
1956
  logger.debug("Session: Checking wallet identification", {
1889
1957
  identifiedKey: identifiedKey,
1890
1958
  isIdentified: isIdentified,
1891
- hasRdns: !!rdns
1959
+ hasRdns: !!rdns,
1892
1960
  });
1893
1961
  return isIdentified;
1894
1962
  };
@@ -1906,14 +1974,14 @@ var FormoAnalyticsSession = /** @class */ (function () {
1906
1974
  });
1907
1975
  logger.debug("Session: Marked wallet as identified", {
1908
1976
  identifiedKey: identifiedKey,
1909
- hasRdns: !!rdns
1977
+ hasRdns: !!rdns,
1910
1978
  });
1911
1979
  }
1912
1980
  else {
1913
1981
  logger.info("Session: Wallet already marked as identified", {
1914
1982
  identifiedKey: identifiedKey,
1915
1983
  existingWallets: identifiedWallets,
1916
- hasRdns: !!rdns
1984
+ hasRdns: !!rdns,
1917
1985
  });
1918
1986
  }
1919
1987
  };
@@ -52,7 +52,7 @@ import { initStorageManager, logger } from "./lib";
52
52
  var defaultContext = {
53
53
  chain: function () { return Promise.resolve(); },
54
54
  page: function () { return Promise.resolve(); },
55
- reset: function () { return Promise.resolve(); },
55
+ reset: function () { },
56
56
  detect: function () { return Promise.resolve(); },
57
57
  connect: function () { return Promise.resolve(); },
58
58
  disconnect: function () { return Promise.resolve(); },
@@ -60,6 +60,10 @@ var defaultContext = {
60
60
  transaction: function () { return Promise.resolve(); },
61
61
  identify: function () { return Promise.resolve(); },
62
62
  track: function () { return Promise.resolve(); },
63
+ // Consent management methods
64
+ optOutTracking: function () { },
65
+ optInTracking: function () { },
66
+ hasOptedOutTracking: function () { return false; },
63
67
  };
64
68
  export var FormoAnalyticsContext = createContext(defaultContext);
65
69
  export var FormoAnalyticsProvider = function (props) {
@@ -4,5 +4,9 @@ export declare const SESSION_WALLET_IDENTIFIED_KEY = "wallet-identified";
4
4
  export declare const SESSION_CURRENT_URL_KEY = "analytics-current-url";
5
5
  export declare const SESSION_USER_ID_KEY = "user-id";
6
6
  export declare const LOCAL_ANONYMOUS_ID_KEY = "anonymous-id";
7
+ export declare const CONSENT_OPT_OUT_KEY = "opt-out-tracking";
7
8
  export declare const DEFAULT_PROVIDER_ICON = "data:image/svg+xml;base64,";
9
+ export declare const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
10
+ export declare const DEAD_ADDRESS = "0x000000000000000000000000000000000000dEaD";
11
+ export declare const BLOCKED_ADDRESSES: readonly ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"];
8
12
  //# sourceMappingURL=base.d.ts.map
@@ -4,6 +4,13 @@ export var SESSION_WALLET_IDENTIFIED_KEY = "wallet-identified";
4
4
  export var SESSION_CURRENT_URL_KEY = "analytics-current-url";
5
5
  export var SESSION_USER_ID_KEY = "user-id";
6
6
  export var LOCAL_ANONYMOUS_ID_KEY = "anonymous-id";
7
+ // Consent management keys
8
+ export var CONSENT_OPT_OUT_KEY = "opt-out-tracking";
7
9
  // Default provider icon (empty data URL)
8
10
  export var DEFAULT_PROVIDER_ICON = 'data:image/svg+xml;base64,';
11
+ // Blocked addresses that should not emit events
12
+ export var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
13
+ export var DEAD_ADDRESS = "0x000000000000000000000000000000000000dEaD";
14
+ // Array of all blocked addresses for easy checking
15
+ export var BLOCKED_ADDRESSES = [ZERO_ADDRESS, DEAD_ADDRESS];
9
16
  //# sourceMappingURL=base.js.map
@@ -0,0 +1,3 @@
1
+ export type BrowserName = "brave" | "chrome" | "edge" | "firefox" | "safari" | "opera" | "unknown";
2
+ export declare function detectBrowser(): Promise<BrowserName>;
3
+ //# sourceMappingURL=browsers.d.ts.map