@formo/analytics 1.20.0 → 1.22.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.
@@ -71,7 +71,7 @@ var chain_1 = require("./utils/chain");
71
71
  var PROVIDER_SWITCH_REASONS = {
72
72
  ADDRESS_MISMATCH: "Address mismatch indicates wallet switch",
73
73
  NO_ACCOUNTS: "Current provider has no accounts",
74
- CHECK_FAILED: "Could not check current provider accounts"
74
+ CHECK_FAILED: "Could not check current provider accounts",
75
75
  };
76
76
  var FormoAnalytics = /** @class */ (function () {
77
77
  function FormoAnalytics(writeKey, options) {
@@ -114,6 +114,7 @@ var FormoAnalytics = /** @class */ (function () {
114
114
  this.transaction = this.transaction.bind(this);
115
115
  this.detect = this.detect.bind(this);
116
116
  this.track = this.track.bind(this);
117
+ this.isAutocaptureEnabled = this.isAutocaptureEnabled.bind(this);
117
118
  // Initialize logger with configuration from options
118
119
  lib_1.Logger.init({
119
120
  enabled: ((_a = options.logger) === null || _a === void 0 ? void 0 : _a.enabled) || false,
@@ -136,7 +137,7 @@ var FormoAnalytics = /** @class */ (function () {
136
137
  if (optProvider) {
137
138
  provider = optProvider;
138
139
  }
139
- else if (typeof window !== 'undefined' && window.ethereum) {
140
+ else if (typeof window !== "undefined" && window.ethereum) {
140
141
  provider = window.ethereum;
141
142
  }
142
143
  if (provider) {
@@ -163,9 +164,9 @@ var FormoAnalytics = /** @class */ (function () {
163
164
  FormoAnalytics.prototype.isProviderInValidState = function (provider) {
164
165
  // Basic validation: ensure provider exists and has required methods
165
166
  return (provider &&
166
- typeof provider.request === 'function' &&
167
- typeof provider.on === 'function' &&
168
- typeof provider.removeListener === 'function');
167
+ typeof provider.request === "function" &&
168
+ typeof provider.on === "function" &&
169
+ typeof provider.removeListener === "function");
169
170
  };
170
171
  FormoAnalytics.init = function (writeKey, options) {
171
172
  return __awaiter(this, void 0, void 0, function () {
@@ -284,16 +285,18 @@ var FormoAnalytics = /** @class */ (function () {
284
285
  case 0:
285
286
  chainId = (params === null || params === void 0 ? void 0 : params.chainId) || this.currentChainId;
286
287
  address = (params === null || params === void 0 ? void 0 : params.address) || this.currentAddress;
287
- providerInfo = this._provider ? this.getProviderInfo(this._provider) : null;
288
+ providerInfo = this._provider
289
+ ? this.getProviderInfo(this._provider)
290
+ : null;
288
291
  lib_1.logger.info("Disconnect: Emitting disconnect event with:", {
289
292
  chainId: chainId,
290
293
  address: address,
291
294
  providerName: providerInfo === null || providerInfo === void 0 ? void 0 : providerInfo.name,
292
- rdns: providerInfo === null || providerInfo === void 0 ? void 0 : providerInfo.rdns
295
+ rdns: providerInfo === null || providerInfo === void 0 ? void 0 : providerInfo.rdns,
293
296
  });
294
297
  disconnectProperties = __assign(__assign({}, (providerInfo && {
295
298
  providerName: providerInfo.name,
296
- rdns: providerInfo.rdns
299
+ rdns: providerInfo.rdns,
297
300
  })), properties);
298
301
  return [4 /*yield*/, this.trackEvent(constants_1.EventType.DISCONNECT, __assign(__assign({}, (chainId && { chainId: chainId })), (address && { address: address })), disconnectProperties, context, callback)];
299
302
  case 1:
@@ -440,9 +443,12 @@ var FormoAnalytics = /** @class */ (function () {
440
443
  validAddress: validAddress_1,
441
444
  rdns: providerDetail.info.rdns,
442
445
  providerName: providerDetail.info.name,
443
- isAlreadyIdentified: validAddress_1 ? this.session.isWalletIdentified(validAddress_1, providerDetail.info.rdns) : false
446
+ isAlreadyIdentified: validAddress_1
447
+ ? this.session.isWalletIdentified(validAddress_1, providerDetail.info.rdns)
448
+ : false,
444
449
  });
445
- if (!(validAddress_1 && !this.session.isWalletIdentified(validAddress_1, providerDetail.info.rdns))) return [3 /*break*/, 5];
450
+ if (!(validAddress_1 &&
451
+ !this.session.isWalletIdentified(validAddress_1, providerDetail.info.rdns))) return [3 /*break*/, 5];
446
452
  lib_1.logger.info("Auto-identifying", validAddress_1, providerDetail.info.name, providerDetail.info.rdns);
447
453
  // NOTE: do not set this.currentAddress without explicit connect or identify
448
454
  return [4 /*yield*/, this.identify({
@@ -486,23 +492,25 @@ var FormoAnalytics = /** @class */ (function () {
486
492
  this.currentUserId = userId;
487
493
  (0, lib_1.cookie)().set(constants_1.SESSION_USER_ID_KEY, userId);
488
494
  }
489
- isAlreadyIdentified = validAddress ? this.session.isWalletIdentified(validAddress, rdns || '') : false;
495
+ isAlreadyIdentified = validAddress
496
+ ? this.session.isWalletIdentified(validAddress, rdns || "")
497
+ : false;
490
498
  lib_1.logger.debug("Identify: Checking deduplication", {
491
499
  validAddress: validAddress,
492
500
  rdns: rdns,
493
501
  providerName: providerName,
494
502
  hasValidAddress: !!validAddress,
495
503
  hasRdns: !!rdns,
496
- isAlreadyIdentified: isAlreadyIdentified
504
+ isAlreadyIdentified: isAlreadyIdentified,
497
505
  });
498
506
  if (isAlreadyIdentified) {
499
- lib_1.logger.info("Identify: Wallet ".concat(providerName || 'Unknown', " with address ").concat(validAddress, " already identified in this session (rdns: ").concat(rdns || 'empty', ")"));
507
+ lib_1.logger.info("Identify: Wallet ".concat(providerName || "Unknown", " with address ").concat(validAddress, " already identified in this session (rdns: ").concat(rdns || "empty", ")"));
500
508
  return [2 /*return*/];
501
509
  }
502
510
  // Mark as identified before emitting the event
503
511
  // Mark even if rdns is empty to prevent duplicate empty identifies
504
512
  if (validAddress) {
505
- this.session.markWalletIdentified(validAddress, rdns || '');
513
+ this.session.markWalletIdentified(validAddress, rdns || "");
506
514
  }
507
515
  return [4 /*yield*/, this.trackEvent(constants_1.EventType.IDENTIFY, {
508
516
  address: validAddress,
@@ -616,12 +624,26 @@ var FormoAnalytics = /** @class */ (function () {
616
624
  lib_1.logger.warn("TrackProvider: Provider already tracked.");
617
625
  return;
618
626
  }
619
- // Register listeners for this provider first
627
+ // CRITICAL: Always register accountsChanged for state management
628
+ // This ensures currentAddress, currentChainId, and _provider are always up-to-date
629
+ // Event emission is controlled conditionally inside the handlers
620
630
  this.registerAccountsChangedListener(provider);
621
- this.registerChainChangedListener(provider);
622
- this.registerConnectListener(provider);
623
- this.registerRequestListeners(provider);
624
- this.registerDisconnectListener(provider);
631
+ // Register other listeners based on autocapture configuration
632
+ if (this.isAutocaptureEnabled("chain")) {
633
+ this.registerChainChangedListener(provider);
634
+ }
635
+ if (this.isAutocaptureEnabled("connect")) {
636
+ this.registerConnectListener(provider);
637
+ }
638
+ if (this.isAutocaptureEnabled("signature") || this.isAutocaptureEnabled("transaction")) {
639
+ this.registerRequestListeners(provider);
640
+ }
641
+ else {
642
+ lib_1.logger.debug("TrackProvider: Skipping request wrapping (both signature and transaction autocapture disabled)");
643
+ }
644
+ if (this.isAutocaptureEnabled("disconnect")) {
645
+ this.registerDisconnectListener(provider);
646
+ }
625
647
  // Only add to tracked providers after all listeners are successfully registered
626
648
  this._trackedProviders.add(provider);
627
649
  }
@@ -670,7 +692,7 @@ var FormoAnalytics = /** @class */ (function () {
670
692
  // Prevent concurrent processing of accountsChanged events to avoid race conditions
671
693
  if (this._processingAccountsChanged) {
672
694
  lib_1.logger.debug("OnAccountsChanged: Already processing accountsChanged, skipping", {
673
- provider: this.getProviderInfo(provider).name
695
+ provider: this.getProviderInfo(provider).name,
674
696
  });
675
697
  return [2 /*return*/];
676
698
  }
@@ -706,20 +728,21 @@ var FormoAnalytics = /** @class */ (function () {
706
728
  return __generator(this, function (_a) {
707
729
  switch (_a.label) {
708
730
  case 0:
709
- if (!(accounts.length === 0)) return [3 /*break*/, 7];
710
- if (!(this._provider === provider)) return [3 /*break*/, 5];
731
+ if (!(accounts.length === 0)) return [3 /*break*/, 9];
732
+ if (!(this._provider === provider)) return [3 /*break*/, 7];
711
733
  lib_1.logger.info("OnAccountsChanged: Detecting disconnect, current state:", {
712
734
  currentAddress: this.currentAddress,
713
735
  currentChainId: this.currentChainId,
714
- providerMatch: this._provider === provider
736
+ providerMatch: this._provider === provider,
715
737
  });
738
+ if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 5];
716
739
  _a.label = 1;
717
740
  case 1:
718
741
  _a.trys.push([1, 3, , 4]);
719
742
  // Pass current state explicitly to ensure we have the data for the disconnect event
720
743
  return [4 /*yield*/, this.disconnect({
721
744
  chainId: this.currentChainId,
722
- address: this.currentAddress
745
+ address: this.currentAddress,
723
746
  })];
724
747
  case 2:
725
748
  // Pass current state explicitly to ensure we have the data for the disconnect event
@@ -731,103 +754,138 @@ var FormoAnalytics = /** @class */ (function () {
731
754
  return [3 /*break*/, 4];
732
755
  case 4: return [3 /*break*/, 6];
733
756
  case 5:
734
- lib_1.logger.info("OnAccountsChanged: Ignoring disconnect for non-active provider");
757
+ lib_1.logger.debug("OnAccountsChanged: Disconnect event skipped (autocapture.disconnect: false)");
758
+ // Still clear state even if not tracking the event
759
+ this.currentAddress = undefined;
760
+ this.currentChainId = undefined;
761
+ this.clearActiveProvider();
735
762
  _a.label = 6;
736
- case 6: return [2 /*return*/];
763
+ case 6: return [3 /*break*/, 8];
737
764
  case 7:
765
+ lib_1.logger.info("OnAccountsChanged: Ignoring disconnect for non-active provider");
766
+ _a.label = 8;
767
+ case 8: return [2 /*return*/];
768
+ case 9:
738
769
  address = this.validateAndChecksumAddress(accounts[0]);
739
770
  if (!address) {
740
771
  lib_1.logger.warn("onAccountsChanged: Invalid address received", accounts[0]);
741
772
  return [2 /*return*/];
742
773
  }
743
- if (!(this._provider && this._provider !== provider)) return [3 /*break*/, 18];
774
+ if (!(this._provider && this._provider !== provider)) return [3 /*break*/, 26];
744
775
  currentStoredAddress = this.currentAddress;
745
776
  newProviderAddress = this.validateAndChecksumAddress(address);
746
777
  lib_1.logger.info("OnAccountsChanged: Different provider attempting to connect", {
747
778
  activeProvider: this.getProviderInfo(this._provider).name,
748
779
  eventProvider: this.getProviderInfo(provider).name,
749
780
  currentStoredAddress: currentStoredAddress,
750
- newProviderAddress: newProviderAddress
781
+ newProviderAddress: newProviderAddress,
751
782
  });
752
- _a.label = 8;
753
- case 8:
754
- _a.trys.push([8, 16, , 18]);
783
+ _a.label = 10;
784
+ case 10:
785
+ _a.trys.push([10, 22, , 26]);
755
786
  return [4 /*yield*/, this.getAccounts(this._provider)];
756
- case 9:
787
+ case 11:
757
788
  activeProviderAccounts = _a.sent();
758
789
  lib_1.logger.info("OnAccountsChanged: Checking current provider accounts", {
759
790
  activeProvider: this.getProviderInfo(this._provider).name,
760
- accountsLength: activeProviderAccounts ? activeProviderAccounts.length : 0,
761
- accounts: activeProviderAccounts
791
+ accountsLength: activeProviderAccounts
792
+ ? activeProviderAccounts.length
793
+ : 0,
794
+ accounts: activeProviderAccounts,
762
795
  });
763
- if (!(activeProviderAccounts && activeProviderAccounts.length > 0)) return [3 /*break*/, 13];
764
- if (!(newProviderAddress && currentStoredAddress && newProviderAddress !== currentStoredAddress)) return [3 /*break*/, 11];
796
+ if (!(activeProviderAccounts && activeProviderAccounts.length > 0)) return [3 /*break*/, 17];
797
+ if (!(newProviderAddress &&
798
+ currentStoredAddress &&
799
+ newProviderAddress !== currentStoredAddress)) return [3 /*break*/, 15];
765
800
  lib_1.logger.info("OnAccountsChanged: Different address detected, switching providers despite current provider having accounts", {
766
801
  activeProvider: this.getProviderInfo(this._provider).name,
767
802
  eventProvider: this.getProviderInfo(provider).name,
768
803
  currentAddress: currentStoredAddress,
769
804
  newAddress: newProviderAddress,
770
- reason: PROVIDER_SWITCH_REASONS.ADDRESS_MISMATCH
805
+ reason: PROVIDER_SWITCH_REASONS.ADDRESS_MISMATCH,
771
806
  });
772
- // Emit disconnect for the old provider
807
+ if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 13];
773
808
  return [4 /*yield*/, this.disconnect({
774
809
  chainId: this.currentChainId,
775
- address: this.currentAddress
810
+ address: this.currentAddress,
776
811
  })];
777
- case 10:
778
- // Emit disconnect for the old provider
812
+ case 12:
779
813
  _a.sent();
814
+ return [3 /*break*/, 14];
815
+ case 13:
816
+ lib_1.logger.debug("OnAccountsChanged: Disconnect event skipped during provider switch (autocapture.disconnect: false)");
817
+ // Still clear state even if not tracking the event
818
+ this.currentAddress = undefined;
819
+ this.currentChainId = undefined;
820
+ _a.label = 14;
821
+ case 14:
780
822
  // Clear state and let the new provider become active
781
823
  this.clearActiveProvider();
782
- return [3 /*break*/, 12];
783
- case 11:
824
+ return [3 /*break*/, 16];
825
+ case 15:
784
826
  lib_1.logger.info("OnAccountsChanged: Current provider still has accounts and same address, ignoring new provider", {
785
827
  activeProvider: this.getProviderInfo(this._provider).name,
786
828
  eventProvider: this.getProviderInfo(provider).name,
787
829
  activeProviderAccountsCount: activeProviderAccounts.length,
788
830
  currentAddress: currentStoredAddress,
789
- newAddress: newProviderAddress
831
+ newAddress: newProviderAddress,
790
832
  });
791
833
  return [2 /*return*/];
792
- case 12: return [3 /*break*/, 15];
793
- case 13:
834
+ case 16: return [3 /*break*/, 21];
835
+ case 17:
794
836
  lib_1.logger.info("OnAccountsChanged: Current provider has no accounts, switching to new provider", {
795
837
  oldProvider: this.getProviderInfo(this._provider).name,
796
838
  newProvider: this.getProviderInfo(provider).name,
797
- reason: PROVIDER_SWITCH_REASONS.NO_ACCOUNTS
839
+ reason: PROVIDER_SWITCH_REASONS.NO_ACCOUNTS,
798
840
  });
799
- // Emit disconnect for the old provider that didn't signal properly
841
+ if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 19];
800
842
  return [4 /*yield*/, this.disconnect({
801
843
  chainId: this.currentChainId,
802
- address: this.currentAddress
844
+ address: this.currentAddress,
803
845
  })];
804
- case 14:
805
- // Emit disconnect for the old provider that didn't signal properly
846
+ case 18:
806
847
  _a.sent();
848
+ return [3 /*break*/, 20];
849
+ case 19:
850
+ lib_1.logger.debug("OnAccountsChanged: Disconnect event skipped for old provider (autocapture.disconnect: false)");
851
+ // Still clear state even if not tracking the event
852
+ this.currentAddress = undefined;
853
+ this.currentChainId = undefined;
854
+ _a.label = 20;
855
+ case 20:
807
856
  // Clear state and let the new provider become active
808
857
  this.clearActiveProvider();
809
- _a.label = 15;
810
- case 15: return [3 /*break*/, 18];
811
- case 16:
858
+ _a.label = 21;
859
+ case 21: return [3 /*break*/, 26];
860
+ case 22:
812
861
  error_2 = _a.sent();
813
862
  lib_1.logger.warn("OnAccountsChanged: Could not check current provider accounts, switching to new provider", {
814
863
  error: error_2 instanceof Error ? error_2.message : String(error_2),
815
864
  errorType: error_2 instanceof Error ? error_2.constructor.name : typeof error_2,
816
- oldProvider: this._provider ? this.getProviderInfo(this._provider).name : 'unknown',
865
+ oldProvider: this._provider
866
+ ? this.getProviderInfo(this._provider).name
867
+ : "unknown",
817
868
  newProvider: this.getProviderInfo(provider).name,
818
- reason: PROVIDER_SWITCH_REASONS.CHECK_FAILED
869
+ reason: PROVIDER_SWITCH_REASONS.CHECK_FAILED,
819
870
  });
820
- // If we can't check the current provider, assume it's disconnected
871
+ if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 24];
821
872
  return [4 /*yield*/, this.disconnect({
822
873
  chainId: this.currentChainId,
823
- address: this.currentAddress
874
+ address: this.currentAddress,
824
875
  })];
825
- case 17:
826
- // If we can't check the current provider, assume it's disconnected
876
+ case 23:
827
877
  _a.sent();
878
+ return [3 /*break*/, 25];
879
+ case 24:
880
+ lib_1.logger.debug("OnAccountsChanged: Disconnect event skipped for failed provider check (autocapture.disconnect: false)");
881
+ // Still clear state even if not tracking the event
882
+ this.currentAddress = undefined;
883
+ this.currentChainId = undefined;
884
+ _a.label = 25;
885
+ case 25:
828
886
  this.clearActiveProvider();
829
- return [3 /*break*/, 18];
830
- case 18:
887
+ return [3 /*break*/, 26];
888
+ case 26:
831
889
  // Set provider if none exists (first connection)
832
890
  if (!this._provider) {
833
891
  this._provider = provider;
@@ -837,33 +895,44 @@ var FormoAnalytics = /** @class */ (function () {
837
895
  return [2 /*return*/];
838
896
  }
839
897
  return [4 /*yield*/, this.getCurrentChainId(provider)];
840
- case 19:
898
+ case 27:
841
899
  nextChainId = _a.sent();
842
900
  wasDisconnected = !this.currentAddress;
901
+ // CRITICAL: Always update state regardless of whether connect tracking is enabled
902
+ // This ensures disconnect events will have valid address/chainId values
843
903
  this.currentAddress = address;
844
904
  this.currentChainId = nextChainId;
845
905
  providerInfo = this.getProviderInfo(provider);
846
- lib_1.logger.info("OnAccountsChanged: Detected wallet connection, emitting connect event", {
847
- chainId: nextChainId,
848
- address: address,
849
- wasDisconnected: wasDisconnected,
850
- providerName: providerInfo.name,
851
- rdns: providerInfo.rdns,
852
- hasChainId: !!nextChainId
853
- });
854
906
  effectiveChainId = nextChainId || 0;
855
- if (effectiveChainId === 0) {
856
- lib_1.logger.info("OnAccountsChanged: Using fallback chainId 0 for connect event");
907
+ if (this.isAutocaptureEnabled("connect")) {
908
+ lib_1.logger.info("OnAccountsChanged: Detected wallet connection, emitting connect event", {
909
+ chainId: nextChainId,
910
+ address: address,
911
+ wasDisconnected: wasDisconnected,
912
+ providerName: providerInfo.name,
913
+ rdns: providerInfo.rdns,
914
+ hasChainId: !!nextChainId,
915
+ });
916
+ if (effectiveChainId === 0) {
917
+ lib_1.logger.info("OnAccountsChanged: Using fallback chainId 0 for connect event");
918
+ }
919
+ this.connect({
920
+ chainId: effectiveChainId,
921
+ address: address,
922
+ }, {
923
+ providerName: providerInfo.name,
924
+ rdns: providerInfo.rdns,
925
+ }).catch(function (error) {
926
+ lib_1.logger.error("Failed to track connect event during account change:", error);
927
+ });
928
+ }
929
+ else {
930
+ lib_1.logger.debug("OnAccountsChanged: Connect event skipped (autocapture.connect: false)", {
931
+ chainId: nextChainId,
932
+ address: address,
933
+ providerName: providerInfo.name,
934
+ });
857
935
  }
858
- this.connect({
859
- chainId: effectiveChainId,
860
- address: address
861
- }, {
862
- providerName: providerInfo.name,
863
- rdns: providerInfo.rdns
864
- }).catch(function (error) {
865
- lib_1.logger.error("Failed to track connect event during account change:", error);
866
- });
867
936
  return [2 /*return*/];
868
937
  }
869
938
  });
@@ -904,10 +973,18 @@ var FormoAnalytics = /** @class */ (function () {
904
973
  this.currentChainId = nextChainId;
905
974
  try {
906
975
  // This is just a chain change since we already confirmed currentAddress exists
907
- return [2 /*return*/, this.chain({
976
+ if (this.isAutocaptureEnabled("chain")) {
977
+ return [2 /*return*/, this.chain({
978
+ chainId: this.currentChainId,
979
+ address: this.currentAddress,
980
+ })];
981
+ }
982
+ else {
983
+ lib_1.logger.debug("OnChainChanged: Chain event skipped (autocapture.chain: false)", {
908
984
  chainId: this.currentChainId,
909
985
  address: this.currentAddress,
910
- })];
986
+ });
987
+ }
911
988
  }
912
989
  catch (error) {
913
990
  lib_1.logger.error("OnChainChanged: Failed to emit chain event:", error);
@@ -942,15 +1019,16 @@ var FormoAnalytics = /** @class */ (function () {
942
1019
  return [2 /*return*/];
943
1020
  lib_1.logger.info("OnDisconnect: Wallet disconnect event received, current state:", {
944
1021
  currentAddress: this.currentAddress,
945
- currentChainId: this.currentChainId
1022
+ currentChainId: this.currentChainId,
946
1023
  });
1024
+ if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 5];
947
1025
  _a.label = 1;
948
1026
  case 1:
949
1027
  _a.trys.push([1, 3, , 4]);
950
1028
  // Pass current state explicitly to ensure we have the data for the disconnect event
951
1029
  return [4 /*yield*/, this.disconnect({
952
1030
  chainId: this.currentChainId,
953
- address: this.currentAddress
1031
+ address: this.currentAddress,
954
1032
  })];
955
1033
  case 2:
956
1034
  // Pass current state explicitly to ensure we have the data for the disconnect event
@@ -960,7 +1038,15 @@ var FormoAnalytics = /** @class */ (function () {
960
1038
  e_2 = _a.sent();
961
1039
  lib_1.logger.error("Error during disconnect in disconnect listener", e_2);
962
1040
  return [3 /*break*/, 4];
963
- case 4: return [2 /*return*/];
1041
+ case 4: return [3 /*break*/, 6];
1042
+ case 5:
1043
+ lib_1.logger.debug("OnDisconnect: Disconnect event skipped (autocapture.disconnect: false)");
1044
+ // Still clear state even if not tracking the event
1045
+ this.currentAddress = undefined;
1046
+ this.currentChainId = undefined;
1047
+ this.clearActiveProvider();
1048
+ _a.label = 6;
1049
+ case 6: return [2 /*return*/];
964
1050
  }
965
1051
  });
966
1052
  }); };
@@ -977,7 +1063,7 @@ var FormoAnalytics = /** @class */ (function () {
977
1063
  _a.label = 1;
978
1064
  case 1:
979
1065
  _a.trys.push([1, 3, , 4]);
980
- if (!(connection === null || connection === void 0 ? void 0 : connection.chainId) || typeof connection.chainId !== 'string')
1066
+ if (!(connection === null || connection === void 0 ? void 0 : connection.chainId) || typeof connection.chainId !== "string")
981
1067
  return [2 /*return*/];
982
1068
  chainId = (0, chain_1.parseChainId)(connection.chainId);
983
1069
  return [4 /*yield*/, this.getAddress(provider)];
@@ -990,34 +1076,46 @@ var FormoAnalytics = /** @class */ (function () {
990
1076
  this._provider = provider;
991
1077
  }
992
1078
  isActiveProvider = this._provider === provider;
993
- // Only update global state (chainId/address) from the active provider
1079
+ // CRITICAL: Always update state from active provider regardless of tracking config
1080
+ // This ensures disconnect events will have valid address/chainId values
994
1081
  if (isActiveProvider) {
995
1082
  this.currentChainId = chainId;
996
- this.currentAddress = this.validateAndChecksumAddress(address) || undefined;
1083
+ this.currentAddress =
1084
+ this.validateAndChecksumAddress(address) || undefined;
997
1085
  }
1086
+ // Conditionally emit connect event based on tracking configuration
998
1087
  if (isActiveProvider && this.currentAddress) {
999
1088
  providerInfo = this.getProviderInfo(provider);
1000
- lib_1.logger.info("OnConnected: Detected wallet connection, emitting connect event", {
1001
- chainId: chainId,
1002
- wasDisconnected: wasDisconnected,
1003
- providerName: providerInfo.name,
1004
- rdns: providerInfo.rdns,
1005
- hasChainId: !!chainId,
1006
- isActiveProvider: isActiveProvider
1007
- });
1008
1089
  effectiveChainId = chainId || 0;
1009
- if (effectiveChainId === 0) {
1010
- lib_1.logger.info("OnConnected: Using fallback chainId 0 for connect event");
1090
+ if (this.isAutocaptureEnabled("connect")) {
1091
+ lib_1.logger.info("OnConnected: Detected wallet connection, emitting connect event", {
1092
+ chainId: chainId,
1093
+ wasDisconnected: wasDisconnected,
1094
+ providerName: providerInfo.name,
1095
+ rdns: providerInfo.rdns,
1096
+ hasChainId: !!chainId,
1097
+ isActiveProvider: isActiveProvider,
1098
+ });
1099
+ if (effectiveChainId === 0) {
1100
+ lib_1.logger.info("OnConnected: Using fallback chainId 0 for connect event");
1101
+ }
1102
+ this.connect({
1103
+ chainId: effectiveChainId,
1104
+ address: address,
1105
+ }, {
1106
+ providerName: providerInfo.name,
1107
+ rdns: providerInfo.rdns,
1108
+ }).catch(function (error) {
1109
+ lib_1.logger.error("Failed to track connect event during provider connection:", error);
1110
+ });
1111
+ }
1112
+ else {
1113
+ lib_1.logger.debug("OnConnected: Connect event skipped (autocapture.connect: false)", {
1114
+ chainId: chainId,
1115
+ address: address,
1116
+ providerName: providerInfo.name,
1117
+ });
1011
1118
  }
1012
- this.connect({
1013
- chainId: effectiveChainId,
1014
- address: address
1015
- }, {
1016
- providerName: providerInfo.name,
1017
- rdns: providerInfo.rdns
1018
- }).catch(function (error) {
1019
- lib_1.logger.error("Failed to track connect event during provider connection:", error);
1020
- });
1021
1119
  }
1022
1120
  else if (address && !isActiveProvider) {
1023
1121
  providerInfo = this.getProviderInfo(provider);
@@ -1026,7 +1124,9 @@ var FormoAnalytics = /** @class */ (function () {
1026
1124
  providerName: providerInfo.name,
1027
1125
  rdns: providerInfo.rdns,
1028
1126
  isActiveProvider: isActiveProvider,
1029
- activeProviderInfo: this._provider ? this.getProviderInfo(this._provider) : null
1127
+ activeProviderInfo: this._provider
1128
+ ? this.getProviderInfo(this._provider)
1129
+ : null,
1030
1130
  });
1031
1131
  }
1032
1132
  }
@@ -1063,6 +1163,10 @@ var FormoAnalytics = /** @class */ (function () {
1063
1163
  case 0:
1064
1164
  if (!(Array.isArray(params) &&
1065
1165
  ["eth_signTypedData_v4", "personal_sign"].includes(method))) return [3 /*break*/, 6];
1166
+ if (!this.isAutocaptureEnabled("signature")) {
1167
+ lib_1.logger.debug("Signature event skipped (autocapture.signature: false)", { method: method });
1168
+ return [2 /*return*/, request({ method: method, params: params })];
1169
+ }
1066
1170
  _c = this.currentChainId;
1067
1171
  if (_c) return [3 /*break*/, 2];
1068
1172
  return [4 /*yield*/, this.getCurrentChainId(provider)];
@@ -1126,6 +1230,10 @@ var FormoAnalytics = /** @class */ (function () {
1126
1230
  if (!(Array.isArray(params) &&
1127
1231
  method === "eth_sendTransaction" &&
1128
1232
  params[0])) return [3 /*break*/, 10];
1233
+ if (!this.isAutocaptureEnabled("transaction")) {
1234
+ lib_1.logger.debug("Transaction event skipped (autocapture.transaction: false)", { method: method });
1235
+ return [2 /*return*/, request({ method: method, params: params })];
1236
+ }
1129
1237
  (function () { return __awaiter(_this, void 0, void 0, function () {
1130
1238
  var payload, e_4;
1131
1239
  return __generator(this, function (_a) {
@@ -1208,7 +1316,8 @@ var FormoAnalytics = /** @class */ (function () {
1208
1316
  }); };
1209
1317
  // Mark the wrapper so we can detect if request is replaced externally and keep a reference on provider
1210
1318
  wrappedRequest[types_1.WRAPPED_REQUEST_SYMBOL] = true;
1211
- provider[types_1.WRAPPED_REQUEST_REF_SYMBOL] = wrappedRequest;
1319
+ provider[types_1.WRAPPED_REQUEST_REF_SYMBOL] =
1320
+ wrappedRequest;
1212
1321
  try {
1213
1322
  // Attempt to assign the wrapped request function (rely on try-catch for mutability errors)
1214
1323
  provider.request = wrappedRequest;
@@ -1298,18 +1407,25 @@ var FormoAnalytics = /** @class */ (function () {
1298
1407
  };
1299
1408
  FormoAnalytics.prototype.trackEvent = function (type, payload, properties, context, callback) {
1300
1409
  return __awaiter(this, void 0, void 0, function () {
1410
+ var error_5;
1301
1411
  return __generator(this, function (_a) {
1302
- try {
1303
- if (!this.shouldTrack()) {
1304
- lib_1.logger.info("Skipping ".concat(type, " event due to tracking configuration"));
1305
- return [2 /*return*/];
1306
- }
1307
- this.eventManager.addEvent(__assign(__assign({ type: type }, payload), { properties: properties, context: context, callback: callback }), this.currentAddress, this.currentUserId);
1308
- }
1309
- catch (error) {
1310
- lib_1.logger.error("Error tracking event:", error);
1412
+ switch (_a.label) {
1413
+ case 0:
1414
+ _a.trys.push([0, 2, , 3]);
1415
+ if (!this.shouldTrack()) {
1416
+ lib_1.logger.info("Skipping ".concat(type, " event due to tracking configuration"));
1417
+ return [2 /*return*/];
1418
+ }
1419
+ return [4 /*yield*/, this.eventManager.addEvent(__assign(__assign({ type: type }, payload), { properties: properties, context: context, callback: callback }), this.currentAddress, this.currentUserId)];
1420
+ case 1:
1421
+ _a.sent();
1422
+ return [3 /*break*/, 3];
1423
+ case 2:
1424
+ error_5 = _a.sent();
1425
+ lib_1.logger.error("Error tracking event:", error_5);
1426
+ return [3 /*break*/, 3];
1427
+ case 3: return [2 /*return*/];
1311
1428
  }
1312
- return [2 /*return*/];
1313
1429
  });
1314
1430
  });
1315
1431
  };
@@ -1323,23 +1439,23 @@ var FormoAnalytics = /** @class */ (function () {
1323
1439
  return false;
1324
1440
  }
1325
1441
  // Check if tracking is explicitly provided as a boolean
1326
- if (typeof this.options.tracking === 'boolean') {
1442
+ if (typeof this.options.tracking === "boolean") {
1327
1443
  return this.options.tracking;
1328
1444
  }
1329
1445
  // Handle object configuration with exclusion rules
1330
1446
  if (this.options.tracking !== null &&
1331
- typeof this.options.tracking === 'object' &&
1447
+ typeof this.options.tracking === "object" &&
1332
1448
  !Array.isArray(this.options.tracking)) {
1333
1449
  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;
1334
1450
  // Check hostname exclusions - use exact matching
1335
- if (excludeHosts.length > 0 && typeof window !== 'undefined') {
1451
+ if (excludeHosts.length > 0 && typeof window !== "undefined") {
1336
1452
  var hostname = window.location.hostname;
1337
1453
  if (excludeHosts.includes(hostname)) {
1338
1454
  return false;
1339
1455
  }
1340
1456
  }
1341
1457
  // Check path exclusions - use exact matching
1342
- if (excludePaths.length > 0 && typeof window !== 'undefined') {
1458
+ if (excludePaths.length > 0 && typeof window !== "undefined") {
1343
1459
  var pathname = window.location.pathname;
1344
1460
  if (excludePaths.includes(pathname)) {
1345
1461
  return false;
@@ -1357,6 +1473,30 @@ var FormoAnalytics = /** @class */ (function () {
1357
1473
  // Default behavior: track everywhere except localhost
1358
1474
  return !(0, validators_1.isLocalhost)();
1359
1475
  };
1476
+ /**
1477
+ * Check if a specific wallet event type is enabled for autocapture
1478
+ * @param eventType The wallet event type to check
1479
+ * @returns {boolean} True if the event type should be autocaptured
1480
+ */
1481
+ FormoAnalytics.prototype.isAutocaptureEnabled = function (eventType) {
1482
+ // If no configuration provided, default to enabled
1483
+ if (this.options.autocapture === undefined) {
1484
+ return true;
1485
+ }
1486
+ // If boolean, return that value for all events
1487
+ if (typeof this.options.autocapture === "boolean") {
1488
+ return this.options.autocapture;
1489
+ }
1490
+ // If it's an object, check the specific event configuration
1491
+ if (this.options.autocapture !== null &&
1492
+ typeof this.options.autocapture === "object") {
1493
+ var eventConfig = this.options.autocapture[eventType];
1494
+ // Default to true if not explicitly set to false
1495
+ return eventConfig !== false;
1496
+ }
1497
+ // Default to enabled if no specific configuration
1498
+ return true;
1499
+ };
1360
1500
  /*
1361
1501
  Utility functions
1362
1502
  */
@@ -1371,14 +1511,14 @@ var FormoAnalytics = /** @class */ (function () {
1371
1511
  if (eip6963Provider) {
1372
1512
  return {
1373
1513
  name: eip6963Provider.info.name,
1374
- rdns: eip6963Provider.info.rdns
1514
+ rdns: eip6963Provider.info.rdns,
1375
1515
  };
1376
1516
  }
1377
1517
  // Fallback to injected provider detection
1378
1518
  var injectedInfo = this.detectInjectedProviderInfo(provider);
1379
1519
  return {
1380
1520
  name: injectedInfo.name,
1381
- rdns: injectedInfo.rdns
1521
+ rdns: injectedInfo.rdns,
1382
1522
  };
1383
1523
  };
1384
1524
  /**
@@ -1388,45 +1528,45 @@ var FormoAnalytics = /** @class */ (function () {
1388
1528
  */
1389
1529
  FormoAnalytics.prototype.detectInjectedProviderInfo = function (provider) {
1390
1530
  // Try to detect provider type from common properties
1391
- var name = 'Injected Provider';
1392
- var rdns = 'io.injected.provider';
1531
+ var name = "Injected Provider";
1532
+ var rdns = "io.injected.provider";
1393
1533
  // Use WalletProviderFlags interface for type safety
1394
1534
  var flags = provider;
1395
1535
  // Check if it's MetaMask
1396
1536
  if (flags.isMetaMask) {
1397
- name = 'MetaMask';
1398
- rdns = 'io.metamask';
1537
+ name = "MetaMask";
1538
+ rdns = "io.metamask";
1399
1539
  }
1400
1540
  // Check if it's Coinbase Wallet
1401
1541
  else if (flags.isCoinbaseWallet) {
1402
- name = 'Coinbase Wallet';
1403
- rdns = 'com.coinbase.wallet';
1542
+ name = "Coinbase Wallet";
1543
+ rdns = "com.coinbase.wallet";
1404
1544
  }
1405
1545
  // Check if it's WalletConnect
1406
1546
  else if (flags.isWalletConnect) {
1407
- name = 'WalletConnect';
1408
- rdns = 'com.walletconnect';
1547
+ name = "WalletConnect";
1548
+ rdns = "com.walletconnect";
1409
1549
  }
1410
1550
  // Check if it's Trust Wallet
1411
1551
  else if (flags.isTrust) {
1412
- name = 'Trust Wallet';
1413
- rdns = 'com.trustwallet';
1552
+ name = "Trust Wallet";
1553
+ rdns = "com.trustwallet";
1414
1554
  }
1415
1555
  // Check if it's Brave Wallet
1416
1556
  else if (flags.isBraveWallet) {
1417
- name = 'Brave Wallet';
1418
- rdns = 'com.brave.wallet';
1557
+ name = "Brave Wallet";
1558
+ rdns = "com.brave.wallet";
1419
1559
  }
1420
1560
  // Check if it's Phantom
1421
1561
  else if (flags.isPhantom) {
1422
- name = 'Phantom';
1423
- rdns = 'app.phantom';
1562
+ name = "Phantom";
1563
+ rdns = "app.phantom";
1424
1564
  }
1425
1565
  return {
1426
1566
  name: name,
1427
1567
  rdns: rdns,
1428
- uuid: "injected-".concat(rdns.replace(/[^a-zA-Z0-9]/g, '-')),
1429
- icon: constants_1.DEFAULT_PROVIDER_ICON
1568
+ uuid: "injected-".concat(rdns.replace(/[^a-zA-Z0-9]/g, "-")),
1569
+ icon: constants_1.DEFAULT_PROVIDER_ICON,
1430
1570
  };
1431
1571
  };
1432
1572
  FormoAnalytics.prototype.getProviders = function () {
@@ -1480,7 +1620,7 @@ var FormoAnalytics = /** @class */ (function () {
1480
1620
  });
1481
1621
  // Fallback to injected provider if no providers are found
1482
1622
  if (providers.length === 0) {
1483
- injected_1 = typeof window !== 'undefined' ? window.ethereum : undefined;
1623
+ injected_1 = typeof window !== "undefined" ? window.ethereum : undefined;
1484
1624
  if (injected_1) {
1485
1625
  // If we have already detected and cached the injected provider, and it's the same instance, return the cached result
1486
1626
  if (this._injectedProviderDetail &&
@@ -1491,7 +1631,9 @@ var FormoAnalytics = /** @class */ (function () {
1491
1631
  }
1492
1632
  // Merge with existing providers instead of overwriting
1493
1633
  if (!this._providers.some(function (existing) { return existing.provider === injected_1; })) {
1494
- this._providers = __spreadArray(__spreadArray([], this._providers, true), [this._injectedProviderDetail], false);
1634
+ this._providers = __spreadArray(__spreadArray([], this._providers, true), [
1635
+ this._injectedProviderDetail,
1636
+ ], false);
1495
1637
  }
1496
1638
  return [2 /*return*/, this._providers];
1497
1639
  }
@@ -1502,7 +1644,7 @@ var FormoAnalytics = /** @class */ (function () {
1502
1644
  injectedProviderInfo = this.detectInjectedProviderInfo(injected_1);
1503
1645
  injectedDetail = {
1504
1646
  provider: injected_1,
1505
- info: injectedProviderInfo
1647
+ info: injectedProviderInfo,
1506
1648
  };
1507
1649
  // Cache the detected injected provider detail
1508
1650
  this._injectedProviderDetail = injectedDetail;
@@ -1841,9 +1983,10 @@ var FormoAnalytics = /** @class */ (function () {
1841
1983
  */
1842
1984
  FormoAnalytics.prototype.isProviderAlreadyWrapped = function (provider, currentRequest) {
1843
1985
  return !!(currentRequest &&
1844
- typeof currentRequest === 'function' &&
1986
+ typeof currentRequest === "function" &&
1845
1987
  currentRequest[types_1.WRAPPED_REQUEST_SYMBOL] &&
1846
- provider[types_1.WRAPPED_REQUEST_REF_SYMBOL] === currentRequest);
1988
+ provider[types_1.WRAPPED_REQUEST_REF_SYMBOL] ===
1989
+ currentRequest);
1847
1990
  };
1848
1991
  /**
1849
1992
  * Handle provider mismatch by switching to the new provider and invalidating old tokens
@@ -1932,7 +2075,7 @@ var FormoAnalyticsSession = /** @class */ (function () {
1932
2075
  lib_1.logger.debug("Session: Checking wallet identification", {
1933
2076
  identifiedKey: identifiedKey,
1934
2077
  isIdentified: isIdentified,
1935
- hasRdns: !!rdns
2078
+ hasRdns: !!rdns,
1936
2079
  });
1937
2080
  return isIdentified;
1938
2081
  };
@@ -1950,14 +2093,14 @@ var FormoAnalyticsSession = /** @class */ (function () {
1950
2093
  });
1951
2094
  lib_1.logger.debug("Session: Marked wallet as identified", {
1952
2095
  identifiedKey: identifiedKey,
1953
- hasRdns: !!rdns
2096
+ hasRdns: !!rdns,
1954
2097
  });
1955
2098
  }
1956
2099
  else {
1957
2100
  lib_1.logger.info("Session: Wallet already marked as identified", {
1958
2101
  identifiedKey: identifiedKey,
1959
2102
  existingWallets: identifiedWallets,
1960
- hasRdns: !!rdns
2103
+ hasRdns: !!rdns,
1961
2104
  });
1962
2105
  }
1963
2106
  };