@formo/analytics 1.19.7 → 1.19.8
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 +12 -0
- package/dist/cjs/src/FormoAnalytics.js +166 -53
- package/dist/cjs/src/lib/version.d.ts +1 -1
- package/dist/cjs/src/lib/version.js +1 -1
- package/dist/cjs/src/utils/base.js +10 -1
- package/dist/esm/src/FormoAnalytics.d.ts +12 -0
- package/dist/esm/src/FormoAnalytics.js +166 -53
- package/dist/esm/src/lib/version.d.ts +1 -1
- package/dist/esm/src/lib/version.js +1 -1
- package/dist/esm/src/utils/base.js +10 -1
- package/dist/index.umd.min.js +1 -1
- package/package.json +1 -1
|
@@ -62,6 +62,14 @@ import { toChecksumAddress } from "./utils";
|
|
|
62
62
|
import { getValidAddress } from "./utils/address";
|
|
63
63
|
import { isLocalhost } from "./validators";
|
|
64
64
|
import { parseChainId } from "./utils/chain";
|
|
65
|
+
/**
|
|
66
|
+
* Constants for provider switching reasons
|
|
67
|
+
*/
|
|
68
|
+
var PROVIDER_SWITCH_REASONS = {
|
|
69
|
+
ADDRESS_MISMATCH: "Address mismatch indicates wallet switch",
|
|
70
|
+
NO_ACCOUNTS: "Current provider has no accounts",
|
|
71
|
+
CHECK_FAILED: "Could not check current provider accounts"
|
|
72
|
+
};
|
|
65
73
|
var FormoAnalytics = /** @class */ (function () {
|
|
66
74
|
function FormoAnalytics(writeKey, options) {
|
|
67
75
|
if (options === void 0) { options = {}; }
|
|
@@ -83,6 +91,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
83
91
|
* - A provider can be tracked but later removed from discovery
|
|
84
92
|
*/
|
|
85
93
|
this._trackedProviders = new Set();
|
|
94
|
+
// Flag to prevent concurrent processing of accountsChanged events
|
|
95
|
+
this._processingAccountsChanged = false;
|
|
86
96
|
// Set to efficiently track seen providers for deduplication and O(1) lookup
|
|
87
97
|
this._seenProviders = new Set();
|
|
88
98
|
this.currentUserId = "";
|
|
@@ -282,7 +292,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
282
292
|
_a.sent();
|
|
283
293
|
this.currentAddress = undefined;
|
|
284
294
|
this.currentChainId = undefined;
|
|
285
|
-
|
|
295
|
+
this._provider = undefined;
|
|
296
|
+
logger.info("Wallet disconnected: Cleared currentAddress, currentChainId, and provider");
|
|
286
297
|
return [2 /*return*/];
|
|
287
298
|
}
|
|
288
299
|
});
|
|
@@ -580,12 +591,49 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
580
591
|
};
|
|
581
592
|
FormoAnalytics.prototype.onAccountsChanged = function (provider, accounts) {
|
|
582
593
|
return __awaiter(this, void 0, void 0, function () {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
return __generator(this, function (_d) {
|
|
586
|
-
switch (_d.label) {
|
|
594
|
+
return __generator(this, function (_a) {
|
|
595
|
+
switch (_a.label) {
|
|
587
596
|
case 0:
|
|
588
597
|
logger.info("onAccountsChanged", accounts);
|
|
598
|
+
// Prevent concurrent processing of accountsChanged events to avoid race conditions
|
|
599
|
+
if (this._processingAccountsChanged) {
|
|
600
|
+
logger.debug("OnAccountsChanged: Already processing accountsChanged, skipping", {
|
|
601
|
+
provider: this.getProviderInfo(provider).name
|
|
602
|
+
});
|
|
603
|
+
return [2 /*return*/];
|
|
604
|
+
}
|
|
605
|
+
this._processingAccountsChanged = true;
|
|
606
|
+
_a.label = 1;
|
|
607
|
+
case 1:
|
|
608
|
+
_a.trys.push([1, , 3, 4]);
|
|
609
|
+
return [4 /*yield*/, this._handleAccountsChanged(provider, accounts)];
|
|
610
|
+
case 2:
|
|
611
|
+
_a.sent();
|
|
612
|
+
return [3 /*break*/, 4];
|
|
613
|
+
case 3:
|
|
614
|
+
this._processingAccountsChanged = false;
|
|
615
|
+
return [7 /*endfinally*/];
|
|
616
|
+
case 4: return [2 /*return*/];
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
});
|
|
620
|
+
};
|
|
621
|
+
/**
|
|
622
|
+
* Handles changes to the accounts of a given EIP-1193 provider.
|
|
623
|
+
*
|
|
624
|
+
* @param provider - The EIP-1193 provider whose accounts have changed.
|
|
625
|
+
* @param accounts - The new array of account addresses. An empty array indicates a disconnect.
|
|
626
|
+
* @returns A promise that resolves when the account change has been processed.
|
|
627
|
+
*
|
|
628
|
+
* If the accounts array is empty and the provider is the active provider, this method triggers
|
|
629
|
+
* a disconnect flow. Otherwise, it updates the state to reflect the new accounts as needed.
|
|
630
|
+
*/
|
|
631
|
+
FormoAnalytics.prototype._handleAccountsChanged = function (provider, accounts) {
|
|
632
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
633
|
+
var error_1, address, currentStoredAddress, newProviderAddress, activeProviderAccounts, error_2, nextChainId, wasDisconnected, providerInfo, effectiveChainId;
|
|
634
|
+
return __generator(this, function (_a) {
|
|
635
|
+
switch (_a.label) {
|
|
636
|
+
case 0:
|
|
589
637
|
if (!(accounts.length === 0)) return [3 /*break*/, 7];
|
|
590
638
|
if (!(this._provider === provider)) return [3 /*break*/, 5];
|
|
591
639
|
logger.info("OnAccountsChanged: Detecting disconnect, current state:", {
|
|
@@ -593,9 +641,9 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
593
641
|
currentChainId: this.currentChainId,
|
|
594
642
|
providerMatch: this._provider === provider
|
|
595
643
|
});
|
|
596
|
-
|
|
644
|
+
_a.label = 1;
|
|
597
645
|
case 1:
|
|
598
|
-
|
|
646
|
+
_a.trys.push([1, 3, , 4]);
|
|
599
647
|
// Pass current state explicitly to ensure we have the data for the disconnect event
|
|
600
648
|
return [4 /*yield*/, this.disconnect({
|
|
601
649
|
chainId: this.currentChainId,
|
|
@@ -603,16 +651,16 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
603
651
|
})];
|
|
604
652
|
case 2:
|
|
605
653
|
// Pass current state explicitly to ensure we have the data for the disconnect event
|
|
606
|
-
|
|
654
|
+
_a.sent();
|
|
607
655
|
return [3 /*break*/, 4];
|
|
608
656
|
case 3:
|
|
609
|
-
error_1 =
|
|
657
|
+
error_1 = _a.sent();
|
|
610
658
|
logger.error("Failed to disconnect provider on accountsChanged", error_1);
|
|
611
659
|
return [3 /*break*/, 4];
|
|
612
660
|
case 4: return [3 /*break*/, 6];
|
|
613
661
|
case 5:
|
|
614
662
|
logger.info("OnAccountsChanged: Ignoring disconnect for non-active provider");
|
|
615
|
-
|
|
663
|
+
_a.label = 6;
|
|
616
664
|
case 6: return [2 /*return*/];
|
|
617
665
|
case 7:
|
|
618
666
|
address = this.validateAndChecksumAddress(accounts[0]);
|
|
@@ -620,54 +668,106 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
620
668
|
logger.warn("onAccountsChanged: Invalid address received", accounts[0]);
|
|
621
669
|
return [2 /*return*/];
|
|
622
670
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
isProviderSwitch = this._provider && this._provider !== provider;
|
|
632
|
-
logger.info("OnAccountsChanged: Provider switching analysis:", {
|
|
633
|
-
currentProvider: ((_b = (_a = this._provider) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name) || 'none',
|
|
634
|
-
newProvider: ((_c = provider === null || provider === void 0 ? void 0 : provider.constructor) === null || _c === void 0 ? void 0 : _c.name) || 'unknown',
|
|
635
|
-
currentAddress: this.currentAddress,
|
|
636
|
-
wasDisconnected: wasDisconnected,
|
|
637
|
-
isProviderMismatch: isProviderSwitch
|
|
671
|
+
if (!(this._provider && this._provider !== provider)) return [3 /*break*/, 18];
|
|
672
|
+
currentStoredAddress = this.currentAddress;
|
|
673
|
+
newProviderAddress = this.validateAndChecksumAddress(address);
|
|
674
|
+
logger.info("OnAccountsChanged: Different provider attempting to connect", {
|
|
675
|
+
activeProvider: this.getProviderInfo(this._provider).name,
|
|
676
|
+
eventProvider: this.getProviderInfo(provider).name,
|
|
677
|
+
currentStoredAddress: currentStoredAddress,
|
|
678
|
+
newProviderAddress: newProviderAddress
|
|
638
679
|
});
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
_d.label = 9;
|
|
680
|
+
_a.label = 8;
|
|
681
|
+
case 8:
|
|
682
|
+
_a.trys.push([8, 16, , 18]);
|
|
683
|
+
return [4 /*yield*/, this.getAccounts(this._provider)];
|
|
644
684
|
case 9:
|
|
645
|
-
|
|
685
|
+
activeProviderAccounts = _a.sent();
|
|
686
|
+
logger.info("OnAccountsChanged: Checking current provider accounts", {
|
|
687
|
+
activeProvider: this.getProviderInfo(this._provider).name,
|
|
688
|
+
accountsLength: activeProviderAccounts ? activeProviderAccounts.length : 0,
|
|
689
|
+
accounts: activeProviderAccounts
|
|
690
|
+
});
|
|
691
|
+
if (!(activeProviderAccounts && activeProviderAccounts.length > 0)) return [3 /*break*/, 13];
|
|
692
|
+
if (!(newProviderAddress && currentStoredAddress && newProviderAddress !== currentStoredAddress)) return [3 /*break*/, 11];
|
|
693
|
+
logger.info("OnAccountsChanged: Different address detected, switching providers despite current provider having accounts", {
|
|
694
|
+
activeProvider: this.getProviderInfo(this._provider).name,
|
|
695
|
+
eventProvider: this.getProviderInfo(provider).name,
|
|
696
|
+
currentAddress: currentStoredAddress,
|
|
697
|
+
newAddress: newProviderAddress,
|
|
698
|
+
reason: PROVIDER_SWITCH_REASONS.ADDRESS_MISMATCH
|
|
699
|
+
});
|
|
700
|
+
// Emit disconnect for the old provider
|
|
646
701
|
return [4 /*yield*/, this.disconnect({
|
|
647
702
|
chainId: this.currentChainId,
|
|
648
703
|
address: this.currentAddress
|
|
649
704
|
})];
|
|
650
705
|
case 10:
|
|
651
|
-
|
|
706
|
+
// Emit disconnect for the old provider
|
|
707
|
+
_a.sent();
|
|
708
|
+
// Clear state and let the new provider become active
|
|
709
|
+
this._provider = undefined;
|
|
652
710
|
return [3 /*break*/, 12];
|
|
653
711
|
case 11:
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
712
|
+
logger.info("OnAccountsChanged: Current provider still has accounts and same address, ignoring new provider", {
|
|
713
|
+
activeProvider: this.getProviderInfo(this._provider).name,
|
|
714
|
+
eventProvider: this.getProviderInfo(provider).name,
|
|
715
|
+
activeProviderAccountsCount: activeProviderAccounts.length,
|
|
716
|
+
currentAddress: currentStoredAddress,
|
|
717
|
+
newAddress: newProviderAddress
|
|
718
|
+
});
|
|
719
|
+
return [2 /*return*/];
|
|
720
|
+
case 12: return [3 /*break*/, 15];
|
|
721
|
+
case 13:
|
|
722
|
+
logger.info("OnAccountsChanged: Current provider has no accounts, switching to new provider", {
|
|
723
|
+
oldProvider: this.getProviderInfo(this._provider).name,
|
|
724
|
+
newProvider: this.getProviderInfo(provider).name,
|
|
725
|
+
reason: PROVIDER_SWITCH_REASONS.NO_ACCOUNTS
|
|
726
|
+
});
|
|
727
|
+
// Emit disconnect for the old provider that didn't signal properly
|
|
728
|
+
return [4 /*yield*/, this.disconnect({
|
|
729
|
+
chainId: this.currentChainId,
|
|
730
|
+
address: this.currentAddress
|
|
731
|
+
})];
|
|
732
|
+
case 14:
|
|
733
|
+
// Emit disconnect for the old provider that didn't signal properly
|
|
734
|
+
_a.sent();
|
|
735
|
+
// Clear state and let the new provider become active
|
|
736
|
+
this._provider = undefined;
|
|
737
|
+
_a.label = 15;
|
|
738
|
+
case 15: return [3 /*break*/, 18];
|
|
739
|
+
case 16:
|
|
740
|
+
error_2 = _a.sent();
|
|
741
|
+
logger.warn("OnAccountsChanged: Could not check current provider accounts, switching to new provider", {
|
|
742
|
+
error: error_2 instanceof Error ? error_2.message : String(error_2),
|
|
743
|
+
errorType: error_2 instanceof Error ? error_2.constructor.name : typeof error_2,
|
|
744
|
+
oldProvider: this._provider ? this.getProviderInfo(this._provider).name : 'unknown',
|
|
745
|
+
newProvider: this.getProviderInfo(provider).name,
|
|
746
|
+
reason: PROVIDER_SWITCH_REASONS.CHECK_FAILED
|
|
747
|
+
});
|
|
748
|
+
// If we can't check the current provider, assume it's disconnected
|
|
749
|
+
return [4 /*yield*/, this.disconnect({
|
|
750
|
+
chainId: this.currentChainId,
|
|
751
|
+
address: this.currentAddress
|
|
752
|
+
})];
|
|
753
|
+
case 17:
|
|
754
|
+
// If we can't check the current provider, assume it's disconnected
|
|
755
|
+
_a.sent();
|
|
756
|
+
this._provider = undefined;
|
|
757
|
+
return [3 /*break*/, 18];
|
|
758
|
+
case 18:
|
|
759
|
+
// Set provider if none exists (first connection)
|
|
760
|
+
if (!this._provider) {
|
|
761
|
+
this._provider = provider;
|
|
662
762
|
}
|
|
663
|
-
|
|
664
|
-
|
|
763
|
+
// If both the provider and address are the same, no-op
|
|
764
|
+
if (this._provider === provider && address === this.currentAddress) {
|
|
665
765
|
return [2 /*return*/];
|
|
666
766
|
}
|
|
667
|
-
|
|
668
|
-
case
|
|
669
|
-
|
|
670
|
-
|
|
767
|
+
return [4 /*yield*/, this.getCurrentChainId(provider)];
|
|
768
|
+
case 19:
|
|
769
|
+
nextChainId = _a.sent();
|
|
770
|
+
wasDisconnected = !this.currentAddress;
|
|
671
771
|
this.currentAddress = address;
|
|
672
772
|
this.currentChainId = nextChainId;
|
|
673
773
|
providerInfo = this.getProviderInfo(provider);
|
|
@@ -675,7 +775,6 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
675
775
|
chainId: nextChainId,
|
|
676
776
|
address: address,
|
|
677
777
|
wasDisconnected: wasDisconnected,
|
|
678
|
-
isProviderSwitch: isProviderSwitch,
|
|
679
778
|
providerName: providerInfo.name,
|
|
680
779
|
rdns: providerInfo.rdns,
|
|
681
780
|
hasChainId: !!nextChainId
|
|
@@ -798,7 +897,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
798
897
|
};
|
|
799
898
|
FormoAnalytics.prototype.onConnected = function (provider, connection) {
|
|
800
899
|
return __awaiter(this, void 0, void 0, function () {
|
|
801
|
-
var chainId, address, wasDisconnected, providerInfo, effectiveChainId, e_3;
|
|
900
|
+
var chainId, address, wasDisconnected, isActiveProvider, providerInfo, effectiveChainId, providerInfo, e_3;
|
|
802
901
|
return __generator(this, function (_a) {
|
|
803
902
|
switch (_a.label) {
|
|
804
903
|
case 0:
|
|
@@ -818,17 +917,21 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
818
917
|
if (!this._provider) {
|
|
819
918
|
this._provider = provider;
|
|
820
919
|
}
|
|
821
|
-
this.
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
920
|
+
isActiveProvider = this._provider === provider;
|
|
921
|
+
// Only update global state (chainId/address) from the active provider
|
|
922
|
+
if (isActiveProvider) {
|
|
923
|
+
this.currentChainId = chainId;
|
|
924
|
+
this.currentAddress = this.validateAndChecksumAddress(address) || undefined;
|
|
925
|
+
}
|
|
926
|
+
if (isActiveProvider && this.currentAddress) {
|
|
825
927
|
providerInfo = this.getProviderInfo(provider);
|
|
826
928
|
logger.info("OnConnected: Detected wallet connection, emitting connect event", {
|
|
827
929
|
chainId: chainId,
|
|
828
930
|
wasDisconnected: wasDisconnected,
|
|
829
931
|
providerName: providerInfo.name,
|
|
830
932
|
rdns: providerInfo.rdns,
|
|
831
|
-
hasChainId: !!chainId
|
|
933
|
+
hasChainId: !!chainId,
|
|
934
|
+
isActiveProvider: isActiveProvider
|
|
832
935
|
});
|
|
833
936
|
effectiveChainId = chainId || 0;
|
|
834
937
|
if (effectiveChainId === 0) {
|
|
@@ -844,6 +947,16 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
844
947
|
logger.error("Failed to track connect event during provider connection:", error);
|
|
845
948
|
});
|
|
846
949
|
}
|
|
950
|
+
else if (address && !isActiveProvider) {
|
|
951
|
+
providerInfo = this.getProviderInfo(provider);
|
|
952
|
+
logger.debug("OnConnected: Skipping connect event for non-active provider", {
|
|
953
|
+
chainId: chainId,
|
|
954
|
+
providerName: providerInfo.name,
|
|
955
|
+
rdns: providerInfo.rdns,
|
|
956
|
+
isActiveProvider: isActiveProvider,
|
|
957
|
+
activeProviderInfo: this._provider ? this.getProviderInfo(this._provider) : null
|
|
958
|
+
});
|
|
959
|
+
}
|
|
847
960
|
}
|
|
848
961
|
return [3 /*break*/, 4];
|
|
849
962
|
case 3:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "1.19.
|
|
1
|
+
export declare const version = "1.19.7";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
export var getActionDescriptor = function (type, properties) {
|
|
2
|
-
|
|
2
|
+
var descriptor = type;
|
|
3
|
+
// Add status for events that have it (e.g., signature, transaction)
|
|
4
|
+
if (properties === null || properties === void 0 ? void 0 : properties.status) {
|
|
5
|
+
descriptor += " ".concat(properties.status);
|
|
6
|
+
}
|
|
7
|
+
// Add RDNS for connect/disconnect events to identify the wallet provider
|
|
8
|
+
if ((type === 'connect' || type === 'disconnect') && (properties === null || properties === void 0 ? void 0 : properties.rdns)) {
|
|
9
|
+
descriptor += " (".concat(properties.rdns, ")");
|
|
10
|
+
}
|
|
11
|
+
return descriptor;
|
|
3
12
|
};
|
|
4
13
|
//# sourceMappingURL=base.js.map
|