@formo/analytics 1.21.0 → 1.23.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.
- package/dist/cjs/src/FormoAnalytics.d.ts +6 -0
- package/dist/cjs/src/FormoAnalytics.js +194 -78
- package/dist/cjs/src/constants/config.d.ts +2 -3
- package/dist/cjs/src/constants/config.js +3 -4
- package/dist/cjs/src/lib/queue/EventQueue.d.ts +2 -2
- package/dist/cjs/src/lib/queue/EventQueue.js +2 -2
- package/dist/cjs/src/lib/version.d.ts +1 -1
- package/dist/cjs/src/lib/version.js +1 -1
- package/dist/cjs/src/types/base.d.ts +48 -0
- package/dist/esm/src/FormoAnalytics.d.ts +6 -0
- package/dist/esm/src/FormoAnalytics.js +195 -79
- package/dist/esm/src/constants/config.d.ts +2 -3
- package/dist/esm/src/constants/config.js +2 -3
- package/dist/esm/src/lib/queue/EventQueue.d.ts +2 -2
- package/dist/esm/src/lib/queue/EventQueue.js +2 -2
- package/dist/esm/src/lib/version.d.ts +1 -1
- package/dist/esm/src/lib/version.js +1 -1
- package/dist/esm/src/types/base.d.ts +48 -0
- package/dist/index.umd.min.js +1 -1
- package/package.json +1 -1
|
@@ -224,6 +224,12 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
224
224
|
* @returns {boolean} True if tracking should be enabled
|
|
225
225
|
*/
|
|
226
226
|
private shouldTrack;
|
|
227
|
+
/**
|
|
228
|
+
* Check if a specific wallet event type is enabled for autocapture
|
|
229
|
+
* @param eventType The wallet event type to check
|
|
230
|
+
* @returns {boolean} True if the event type should be autocaptured
|
|
231
|
+
*/
|
|
232
|
+
private isAutocaptureEnabled;
|
|
227
233
|
/**
|
|
228
234
|
* Get provider information for a given provider
|
|
229
235
|
* @param provider The provider to get info for
|
|
@@ -114,13 +114,14 @@ 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,
|
|
120
121
|
enabledLevels: ((_b = options.logger) === null || _b === void 0 ? void 0 : _b.levels) || [],
|
|
121
122
|
});
|
|
122
123
|
this.eventManager = new lib_1.EventManager(new lib_1.EventQueue(this.config.writeKey, {
|
|
123
|
-
|
|
124
|
+
apiHost: options.apiHost || constants_1.EVENTS_API_HOST,
|
|
124
125
|
flushAt: options.flushAt,
|
|
125
126
|
retryCount: options.retryCount,
|
|
126
127
|
maxQueueSize: options.maxQueueSize,
|
|
@@ -623,12 +624,26 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
623
624
|
lib_1.logger.warn("TrackProvider: Provider already tracked.");
|
|
624
625
|
return;
|
|
625
626
|
}
|
|
626
|
-
//
|
|
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
|
|
627
630
|
this.registerAccountsChangedListener(provider);
|
|
628
|
-
|
|
629
|
-
this.
|
|
630
|
-
|
|
631
|
-
|
|
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
|
+
}
|
|
632
647
|
// Only add to tracked providers after all listeners are successfully registered
|
|
633
648
|
this._trackedProviders.add(provider);
|
|
634
649
|
}
|
|
@@ -713,13 +728,14 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
713
728
|
return __generator(this, function (_a) {
|
|
714
729
|
switch (_a.label) {
|
|
715
730
|
case 0:
|
|
716
|
-
if (!(accounts.length === 0)) return [3 /*break*/,
|
|
717
|
-
if (!(this._provider === provider)) return [3 /*break*/,
|
|
731
|
+
if (!(accounts.length === 0)) return [3 /*break*/, 9];
|
|
732
|
+
if (!(this._provider === provider)) return [3 /*break*/, 7];
|
|
718
733
|
lib_1.logger.info("OnAccountsChanged: Detecting disconnect, current state:", {
|
|
719
734
|
currentAddress: this.currentAddress,
|
|
720
735
|
currentChainId: this.currentChainId,
|
|
721
736
|
providerMatch: this._provider === provider,
|
|
722
737
|
});
|
|
738
|
+
if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 5];
|
|
723
739
|
_a.label = 1;
|
|
724
740
|
case 1:
|
|
725
741
|
_a.trys.push([1, 3, , 4]);
|
|
@@ -738,16 +754,24 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
738
754
|
return [3 /*break*/, 4];
|
|
739
755
|
case 4: return [3 /*break*/, 6];
|
|
740
756
|
case 5:
|
|
741
|
-
lib_1.logger.
|
|
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();
|
|
742
762
|
_a.label = 6;
|
|
743
|
-
case 6: return [
|
|
763
|
+
case 6: return [3 /*break*/, 8];
|
|
744
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:
|
|
745
769
|
address = this.validateAndChecksumAddress(accounts[0]);
|
|
746
770
|
if (!address) {
|
|
747
771
|
lib_1.logger.warn("onAccountsChanged: Invalid address received", accounts[0]);
|
|
748
772
|
return [2 /*return*/];
|
|
749
773
|
}
|
|
750
|
-
if (!(this._provider && this._provider !== provider)) return [3 /*break*/,
|
|
774
|
+
if (!(this._provider && this._provider !== provider)) return [3 /*break*/, 26];
|
|
751
775
|
currentStoredAddress = this.currentAddress;
|
|
752
776
|
newProviderAddress = this.validateAndChecksumAddress(address);
|
|
753
777
|
lib_1.logger.info("OnAccountsChanged: Different provider attempting to connect", {
|
|
@@ -756,11 +780,11 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
756
780
|
currentStoredAddress: currentStoredAddress,
|
|
757
781
|
newProviderAddress: newProviderAddress,
|
|
758
782
|
});
|
|
759
|
-
_a.label =
|
|
760
|
-
case
|
|
761
|
-
_a.trys.push([
|
|
783
|
+
_a.label = 10;
|
|
784
|
+
case 10:
|
|
785
|
+
_a.trys.push([10, 22, , 26]);
|
|
762
786
|
return [4 /*yield*/, this.getAccounts(this._provider)];
|
|
763
|
-
case
|
|
787
|
+
case 11:
|
|
764
788
|
activeProviderAccounts = _a.sent();
|
|
765
789
|
lib_1.logger.info("OnAccountsChanged: Checking current provider accounts", {
|
|
766
790
|
activeProvider: this.getProviderInfo(this._provider).name,
|
|
@@ -769,10 +793,10 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
769
793
|
: 0,
|
|
770
794
|
accounts: activeProviderAccounts,
|
|
771
795
|
});
|
|
772
|
-
if (!(activeProviderAccounts && activeProviderAccounts.length > 0)) return [3 /*break*/,
|
|
796
|
+
if (!(activeProviderAccounts && activeProviderAccounts.length > 0)) return [3 /*break*/, 17];
|
|
773
797
|
if (!(newProviderAddress &&
|
|
774
798
|
currentStoredAddress &&
|
|
775
|
-
newProviderAddress !== currentStoredAddress)) return [3 /*break*/,
|
|
799
|
+
newProviderAddress !== currentStoredAddress)) return [3 /*break*/, 15];
|
|
776
800
|
lib_1.logger.info("OnAccountsChanged: Different address detected, switching providers despite current provider having accounts", {
|
|
777
801
|
activeProvider: this.getProviderInfo(this._provider).name,
|
|
778
802
|
eventProvider: this.getProviderInfo(provider).name,
|
|
@@ -780,18 +804,25 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
780
804
|
newAddress: newProviderAddress,
|
|
781
805
|
reason: PROVIDER_SWITCH_REASONS.ADDRESS_MISMATCH,
|
|
782
806
|
});
|
|
783
|
-
|
|
807
|
+
if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 13];
|
|
784
808
|
return [4 /*yield*/, this.disconnect({
|
|
785
809
|
chainId: this.currentChainId,
|
|
786
810
|
address: this.currentAddress,
|
|
787
811
|
})];
|
|
788
|
-
case
|
|
789
|
-
// Emit disconnect for the old provider
|
|
812
|
+
case 12:
|
|
790
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:
|
|
791
822
|
// Clear state and let the new provider become active
|
|
792
823
|
this.clearActiveProvider();
|
|
793
|
-
return [3 /*break*/,
|
|
794
|
-
case
|
|
824
|
+
return [3 /*break*/, 16];
|
|
825
|
+
case 15:
|
|
795
826
|
lib_1.logger.info("OnAccountsChanged: Current provider still has accounts and same address, ignoring new provider", {
|
|
796
827
|
activeProvider: this.getProviderInfo(this._provider).name,
|
|
797
828
|
eventProvider: this.getProviderInfo(provider).name,
|
|
@@ -800,26 +831,33 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
800
831
|
newAddress: newProviderAddress,
|
|
801
832
|
});
|
|
802
833
|
return [2 /*return*/];
|
|
803
|
-
case
|
|
804
|
-
case
|
|
834
|
+
case 16: return [3 /*break*/, 21];
|
|
835
|
+
case 17:
|
|
805
836
|
lib_1.logger.info("OnAccountsChanged: Current provider has no accounts, switching to new provider", {
|
|
806
837
|
oldProvider: this.getProviderInfo(this._provider).name,
|
|
807
838
|
newProvider: this.getProviderInfo(provider).name,
|
|
808
839
|
reason: PROVIDER_SWITCH_REASONS.NO_ACCOUNTS,
|
|
809
840
|
});
|
|
810
|
-
|
|
841
|
+
if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 19];
|
|
811
842
|
return [4 /*yield*/, this.disconnect({
|
|
812
843
|
chainId: this.currentChainId,
|
|
813
844
|
address: this.currentAddress,
|
|
814
845
|
})];
|
|
815
|
-
case
|
|
816
|
-
// Emit disconnect for the old provider that didn't signal properly
|
|
846
|
+
case 18:
|
|
817
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:
|
|
818
856
|
// Clear state and let the new provider become active
|
|
819
857
|
this.clearActiveProvider();
|
|
820
|
-
_a.label =
|
|
821
|
-
case
|
|
822
|
-
case
|
|
858
|
+
_a.label = 21;
|
|
859
|
+
case 21: return [3 /*break*/, 26];
|
|
860
|
+
case 22:
|
|
823
861
|
error_2 = _a.sent();
|
|
824
862
|
lib_1.logger.warn("OnAccountsChanged: Could not check current provider accounts, switching to new provider", {
|
|
825
863
|
error: error_2 instanceof Error ? error_2.message : String(error_2),
|
|
@@ -830,17 +868,24 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
830
868
|
newProvider: this.getProviderInfo(provider).name,
|
|
831
869
|
reason: PROVIDER_SWITCH_REASONS.CHECK_FAILED,
|
|
832
870
|
});
|
|
833
|
-
|
|
871
|
+
if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 24];
|
|
834
872
|
return [4 /*yield*/, this.disconnect({
|
|
835
873
|
chainId: this.currentChainId,
|
|
836
874
|
address: this.currentAddress,
|
|
837
875
|
})];
|
|
838
|
-
case
|
|
839
|
-
// If we can't check the current provider, assume it's disconnected
|
|
876
|
+
case 23:
|
|
840
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:
|
|
841
886
|
this.clearActiveProvider();
|
|
842
|
-
return [3 /*break*/,
|
|
843
|
-
case
|
|
887
|
+
return [3 /*break*/, 26];
|
|
888
|
+
case 26:
|
|
844
889
|
// Set provider if none exists (first connection)
|
|
845
890
|
if (!this._provider) {
|
|
846
891
|
this._provider = provider;
|
|
@@ -850,33 +895,44 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
850
895
|
return [2 /*return*/];
|
|
851
896
|
}
|
|
852
897
|
return [4 /*yield*/, this.getCurrentChainId(provider)];
|
|
853
|
-
case
|
|
898
|
+
case 27:
|
|
854
899
|
nextChainId = _a.sent();
|
|
855
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
|
|
856
903
|
this.currentAddress = address;
|
|
857
904
|
this.currentChainId = nextChainId;
|
|
858
905
|
providerInfo = this.getProviderInfo(provider);
|
|
859
|
-
lib_1.logger.info("OnAccountsChanged: Detected wallet connection, emitting connect event", {
|
|
860
|
-
chainId: nextChainId,
|
|
861
|
-
address: address,
|
|
862
|
-
wasDisconnected: wasDisconnected,
|
|
863
|
-
providerName: providerInfo.name,
|
|
864
|
-
rdns: providerInfo.rdns,
|
|
865
|
-
hasChainId: !!nextChainId,
|
|
866
|
-
});
|
|
867
906
|
effectiveChainId = nextChainId || 0;
|
|
868
|
-
if (
|
|
869
|
-
lib_1.logger.info("OnAccountsChanged:
|
|
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
|
+
});
|
|
870
935
|
}
|
|
871
|
-
this.connect({
|
|
872
|
-
chainId: effectiveChainId,
|
|
873
|
-
address: address,
|
|
874
|
-
}, {
|
|
875
|
-
providerName: providerInfo.name,
|
|
876
|
-
rdns: providerInfo.rdns,
|
|
877
|
-
}).catch(function (error) {
|
|
878
|
-
lib_1.logger.error("Failed to track connect event during account change:", error);
|
|
879
|
-
});
|
|
880
936
|
return [2 /*return*/];
|
|
881
937
|
}
|
|
882
938
|
});
|
|
@@ -917,10 +973,18 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
917
973
|
this.currentChainId = nextChainId;
|
|
918
974
|
try {
|
|
919
975
|
// This is just a chain change since we already confirmed currentAddress exists
|
|
920
|
-
|
|
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)", {
|
|
921
984
|
chainId: this.currentChainId,
|
|
922
985
|
address: this.currentAddress,
|
|
923
|
-
})
|
|
986
|
+
});
|
|
987
|
+
}
|
|
924
988
|
}
|
|
925
989
|
catch (error) {
|
|
926
990
|
lib_1.logger.error("OnChainChanged: Failed to emit chain event:", error);
|
|
@@ -957,6 +1021,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
957
1021
|
currentAddress: this.currentAddress,
|
|
958
1022
|
currentChainId: this.currentChainId,
|
|
959
1023
|
});
|
|
1024
|
+
if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 5];
|
|
960
1025
|
_a.label = 1;
|
|
961
1026
|
case 1:
|
|
962
1027
|
_a.trys.push([1, 3, , 4]);
|
|
@@ -973,7 +1038,15 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
973
1038
|
e_2 = _a.sent();
|
|
974
1039
|
lib_1.logger.error("Error during disconnect in disconnect listener", e_2);
|
|
975
1040
|
return [3 /*break*/, 4];
|
|
976
|
-
case 4: 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*/];
|
|
977
1050
|
}
|
|
978
1051
|
});
|
|
979
1052
|
}); };
|
|
@@ -1003,35 +1076,46 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1003
1076
|
this._provider = provider;
|
|
1004
1077
|
}
|
|
1005
1078
|
isActiveProvider = this._provider === provider;
|
|
1006
|
-
//
|
|
1079
|
+
// CRITICAL: Always update state from active provider regardless of tracking config
|
|
1080
|
+
// This ensures disconnect events will have valid address/chainId values
|
|
1007
1081
|
if (isActiveProvider) {
|
|
1008
1082
|
this.currentChainId = chainId;
|
|
1009
1083
|
this.currentAddress =
|
|
1010
1084
|
this.validateAndChecksumAddress(address) || undefined;
|
|
1011
1085
|
}
|
|
1086
|
+
// Conditionally emit connect event based on tracking configuration
|
|
1012
1087
|
if (isActiveProvider && this.currentAddress) {
|
|
1013
1088
|
providerInfo = this.getProviderInfo(provider);
|
|
1014
|
-
lib_1.logger.info("OnConnected: Detected wallet connection, emitting connect event", {
|
|
1015
|
-
chainId: chainId,
|
|
1016
|
-
wasDisconnected: wasDisconnected,
|
|
1017
|
-
providerName: providerInfo.name,
|
|
1018
|
-
rdns: providerInfo.rdns,
|
|
1019
|
-
hasChainId: !!chainId,
|
|
1020
|
-
isActiveProvider: isActiveProvider,
|
|
1021
|
-
});
|
|
1022
1089
|
effectiveChainId = chainId || 0;
|
|
1023
|
-
if (
|
|
1024
|
-
lib_1.logger.info("OnConnected:
|
|
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
|
+
});
|
|
1025
1118
|
}
|
|
1026
|
-
this.connect({
|
|
1027
|
-
chainId: effectiveChainId,
|
|
1028
|
-
address: address,
|
|
1029
|
-
}, {
|
|
1030
|
-
providerName: providerInfo.name,
|
|
1031
|
-
rdns: providerInfo.rdns,
|
|
1032
|
-
}).catch(function (error) {
|
|
1033
|
-
lib_1.logger.error("Failed to track connect event during provider connection:", error);
|
|
1034
|
-
});
|
|
1035
1119
|
}
|
|
1036
1120
|
else if (address && !isActiveProvider) {
|
|
1037
1121
|
providerInfo = this.getProviderInfo(provider);
|
|
@@ -1079,6 +1163,10 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1079
1163
|
case 0:
|
|
1080
1164
|
if (!(Array.isArray(params) &&
|
|
1081
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
|
+
}
|
|
1082
1170
|
_c = this.currentChainId;
|
|
1083
1171
|
if (_c) return [3 /*break*/, 2];
|
|
1084
1172
|
return [4 /*yield*/, this.getCurrentChainId(provider)];
|
|
@@ -1142,6 +1230,10 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1142
1230
|
if (!(Array.isArray(params) &&
|
|
1143
1231
|
method === "eth_sendTransaction" &&
|
|
1144
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
|
+
}
|
|
1145
1237
|
(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1146
1238
|
var payload, e_4;
|
|
1147
1239
|
return __generator(this, function (_a) {
|
|
@@ -1381,6 +1473,30 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1381
1473
|
// Default behavior: track everywhere except localhost
|
|
1382
1474
|
return !(0, validators_1.isLocalhost)();
|
|
1383
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
|
+
};
|
|
1384
1500
|
/*
|
|
1385
1501
|
Utility functions
|
|
1386
1502
|
*/
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const USER_API_URL = "https://events.formo.so/user";
|
|
1
|
+
export declare const EVENTS_API_ORIGIN = "https://events.formo.so";
|
|
2
|
+
export declare const EVENTS_API_HOST = "https://events.formo.so/v0/raw_events";
|
|
4
3
|
export declare const EVENTS_API_REQUEST_HEADER: (writeKey: string) => {
|
|
5
4
|
"Content-Type": string;
|
|
6
5
|
Authorization: string;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.COUNTRY_LIST = exports.EVENTS_API_REQUEST_HEADER = exports.
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
6
|
-
exports.USER_API_URL = "".concat(exports.EVENTS_API_HOST, "/user");
|
|
3
|
+
exports.COUNTRY_LIST = exports.EVENTS_API_REQUEST_HEADER = exports.EVENTS_API_HOST = exports.EVENTS_API_ORIGIN = void 0;
|
|
4
|
+
exports.EVENTS_API_ORIGIN = "https://events.formo.so";
|
|
5
|
+
exports.EVENTS_API_HOST = "".concat(exports.EVENTS_API_ORIGIN, "/v0/raw_events");
|
|
7
6
|
var EVENTS_API_REQUEST_HEADER = function (writeKey) { return ({
|
|
8
7
|
"Content-Type": "application/json",
|
|
9
8
|
Authorization: "Basic ".concat(writeKey),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IFormoEvent } from "../../types";
|
|
2
2
|
import { IEventQueue } from "./type";
|
|
3
3
|
type Options = {
|
|
4
|
-
|
|
4
|
+
apiHost: string;
|
|
5
5
|
flushAt?: number;
|
|
6
6
|
flushInterval?: number;
|
|
7
7
|
host?: string;
|
|
@@ -11,7 +11,7 @@ type Options = {
|
|
|
11
11
|
};
|
|
12
12
|
export declare class EventQueue implements IEventQueue {
|
|
13
13
|
private writeKey;
|
|
14
|
-
private
|
|
14
|
+
private apiHost;
|
|
15
15
|
private queue;
|
|
16
16
|
private timer;
|
|
17
17
|
private flushAt;
|
|
@@ -127,7 +127,7 @@ var EventQueue = /** @class */ (function () {
|
|
|
127
127
|
options = options || {};
|
|
128
128
|
this.queue = [];
|
|
129
129
|
this.writeKey = writeKey;
|
|
130
|
-
this.
|
|
130
|
+
this.apiHost = options.apiHost;
|
|
131
131
|
this.retryCount = (0, utils_1.clampNumber)(options.retryCount || DEFAULT_RETRY, MAX_RETRY, MIN_RETRY);
|
|
132
132
|
this.flushAt = (0, utils_1.clampNumber)(options.flushAt || DEFAULT_FLUSH_AT, MAX_FLUSH_AT, MIN_FLUSH_AT);
|
|
133
133
|
this.maxQueueSize = (0, utils_1.clampNumber)(options.maxQueueSize || DEFAULT_QUEUE_SIZE, MAX_QUEUE_SIZE, MIN_QUEUE_SIZE);
|
|
@@ -245,7 +245,7 @@ var EventQueue = /** @class */ (function () {
|
|
|
245
245
|
});
|
|
246
246
|
callback(err, data);
|
|
247
247
|
};
|
|
248
|
-
return [2 /*return*/, (this.pendingFlush = (0, fetch_1.default)("".concat(this.
|
|
248
|
+
return [2 /*return*/, (this.pendingFlush = (0, fetch_1.default)("".concat(this.apiHost), {
|
|
249
249
|
headers: (0, constants_1.EVENTS_API_REQUEST_HEADER)(this.writeKey),
|
|
250
250
|
method: "POST",
|
|
251
251
|
body: JSON.stringify(data),
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "1.
|
|
1
|
+
export declare const version = "1.22.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -63,9 +63,57 @@ export interface TrackingOptions {
|
|
|
63
63
|
excludePaths?: string[];
|
|
64
64
|
excludeChains?: ChainID[];
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Configuration options for controlling wallet event autocapture
|
|
68
|
+
* All events are enabled by default unless explicitly set to false
|
|
69
|
+
*/
|
|
70
|
+
export interface AutocaptureOptions {
|
|
71
|
+
/**
|
|
72
|
+
* Track wallet connect events
|
|
73
|
+
* @default true
|
|
74
|
+
*/
|
|
75
|
+
connect?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Track wallet disconnect events
|
|
78
|
+
* @default true
|
|
79
|
+
*/
|
|
80
|
+
disconnect?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Track wallet signature events (personal_sign, eth_signTypedData_v4)
|
|
83
|
+
* @default true
|
|
84
|
+
*/
|
|
85
|
+
signature?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Track wallet transaction events (eth_sendTransaction)
|
|
88
|
+
* @default true
|
|
89
|
+
*/
|
|
90
|
+
transaction?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Track wallet chain change events
|
|
93
|
+
* @default true
|
|
94
|
+
*/
|
|
95
|
+
chain?: boolean;
|
|
96
|
+
}
|
|
66
97
|
export interface Options {
|
|
67
98
|
provider?: EIP1193Provider;
|
|
68
99
|
tracking?: boolean | TrackingOptions;
|
|
100
|
+
/**
|
|
101
|
+
* Control wallet event autocapture
|
|
102
|
+
* - `false`: Disable all wallet autocapture
|
|
103
|
+
* - `true`: Enable all wallet events (default)
|
|
104
|
+
* - `AutocaptureOptions`: Granular control over specific events
|
|
105
|
+
* @default true
|
|
106
|
+
*/
|
|
107
|
+
autocapture?: boolean | AutocaptureOptions;
|
|
108
|
+
/**
|
|
109
|
+
* Custom API host for sending events through your own domain to bypass ad blockers
|
|
110
|
+
* - If not provided, events are sent directly to events.formo.so
|
|
111
|
+
* - When provided, events are sent to your custom endpoint which should forward them to Formo
|
|
112
|
+
* - Example: 'https://your-host-url.com/ingest' or '/api/analytics'
|
|
113
|
+
*
|
|
114
|
+
* See https://docs.formo.so/sdks/web#proxy for setup instructions
|
|
115
|
+
*/
|
|
116
|
+
apiHost?: string;
|
|
69
117
|
flushAt?: number;
|
|
70
118
|
flushInterval?: number;
|
|
71
119
|
retryCount?: number;
|
|
@@ -224,6 +224,12 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
224
224
|
* @returns {boolean} True if tracking should be enabled
|
|
225
225
|
*/
|
|
226
226
|
private shouldTrack;
|
|
227
|
+
/**
|
|
228
|
+
* Check if a specific wallet event type is enabled for autocapture
|
|
229
|
+
* @param eventType The wallet event type to check
|
|
230
|
+
* @returns {boolean} True if the event type should be autocaptured
|
|
231
|
+
*/
|
|
232
|
+
private isAutocaptureEnabled;
|
|
227
233
|
/**
|
|
228
234
|
* Get provider information for a given provider
|
|
229
235
|
* @param provider The provider to get info for
|