@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.
- package/README.md +3 -1
- package/dist/cjs/src/FormoAnalytics.d.ts +17 -1
- package/dist/cjs/src/FormoAnalytics.js +150 -82
- package/dist/cjs/src/FormoAnalyticsProvider.js +5 -1
- package/dist/cjs/src/constants/base.d.ts +4 -0
- package/dist/cjs/src/constants/base.js +8 -1
- package/dist/cjs/src/lib/browser/browsers.d.ts +3 -0
- package/dist/cjs/src/lib/browser/browsers.js +132 -0
- package/dist/cjs/src/lib/consent.d.ts +35 -0
- package/dist/cjs/src/lib/consent.js +102 -0
- package/dist/cjs/src/lib/event/EventFactory.d.ts +10 -10
- package/dist/cjs/src/lib/event/EventFactory.js +272 -140
- package/dist/cjs/src/lib/event/EventManager.d.ts +1 -1
- package/dist/cjs/src/lib/event/EventManager.js +62 -9
- package/dist/cjs/src/lib/event/type.d.ts +2 -2
- package/dist/cjs/src/lib/index.d.ts +1 -0
- package/dist/cjs/src/lib/index.js +1 -0
- package/dist/cjs/src/lib/storage/built-in/blueprint.js +2 -1
- 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 +3 -0
- package/dist/cjs/src/utils/address.d.ts +7 -0
- package/dist/cjs/src/utils/address.js +21 -1
- package/dist/cjs/src/utils/hash.d.ts +10 -0
- package/dist/cjs/src/utils/hash.js +21 -0
- package/dist/cjs/src/utils/index.d.ts +1 -0
- package/dist/cjs/src/utils/index.js +1 -0
- package/dist/esm/src/FormoAnalytics.d.ts +17 -1
- package/dist/esm/src/FormoAnalytics.js +152 -84
- package/dist/esm/src/FormoAnalyticsProvider.js +5 -1
- package/dist/esm/src/constants/base.d.ts +4 -0
- package/dist/esm/src/constants/base.js +7 -0
- package/dist/esm/src/lib/browser/browsers.d.ts +3 -0
- package/dist/esm/src/lib/browser/browsers.js +129 -0
- package/dist/esm/src/lib/consent.d.ts +35 -0
- package/dist/esm/src/lib/consent.js +97 -0
- package/dist/esm/src/lib/event/EventFactory.d.ts +10 -10
- package/dist/esm/src/lib/event/EventFactory.js +272 -140
- package/dist/esm/src/lib/event/EventManager.d.ts +1 -1
- package/dist/esm/src/lib/event/EventManager.js +62 -9
- package/dist/esm/src/lib/event/type.d.ts +2 -2
- package/dist/esm/src/lib/index.d.ts +1 -0
- package/dist/esm/src/lib/index.js +1 -0
- package/dist/esm/src/lib/storage/built-in/blueprint.js +2 -1
- 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 +3 -0
- package/dist/esm/src/utils/address.d.ts +7 -0
- package/dist/esm/src/utils/address.js +19 -0
- package/dist/esm/src/utils/hash.d.ts +10 -0
- package/dist/esm/src/utils/hash.js +18 -0
- package/dist/esm/src/utils/index.d.ts +1 -0
- package/dist/esm/src/utils/index.js +1 -0
- package/dist/index.umd.min.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -24,7 +24,9 @@ You can install Formo on:
|
|
|
24
24
|
- [React apps](https://docs.formo.so/install#react)
|
|
25
25
|
- [Next.js apps](https://docs.formo.so/install#next-js-app-router)
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
## Configuration
|
|
28
|
+
|
|
29
|
+
Visit Formo's [Developer Docs](https://docs.formo.so) for detailed guides on local testing, debugging, and consent management.
|
|
28
30
|
|
|
29
31
|
## Methodology
|
|
30
32
|
|
|
@@ -177,6 +177,22 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
177
177
|
* @returns {Promise<void>}
|
|
178
178
|
*/
|
|
179
179
|
track(event: string, properties?: IFormoEventProperties, context?: IFormoEventContext, callback?: (...args: unknown[]) => void): Promise<void>;
|
|
180
|
+
/**
|
|
181
|
+
* Opt out of tracking.
|
|
182
|
+
* @returns {void}
|
|
183
|
+
*/
|
|
184
|
+
optOutTracking(): void;
|
|
185
|
+
/**
|
|
186
|
+
* Opt back into tracking after previously opting out. This will re-enable analytics tracking
|
|
187
|
+
* and switch back to persistent storage.
|
|
188
|
+
* @returns {void}
|
|
189
|
+
*/
|
|
190
|
+
optInTracking(): void;
|
|
191
|
+
/**
|
|
192
|
+
* Check if the user has opted out of tracking.
|
|
193
|
+
* @returns {boolean} True if the user has opted out
|
|
194
|
+
*/
|
|
195
|
+
hasOptedOutTracking(): boolean;
|
|
180
196
|
private trackProvider;
|
|
181
197
|
private trackProviders;
|
|
182
198
|
private addProviderListener;
|
|
@@ -204,7 +220,7 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
204
220
|
private trackPageHit;
|
|
205
221
|
private trackEvent;
|
|
206
222
|
/**
|
|
207
|
-
* Determines if tracking should be enabled based on configuration
|
|
223
|
+
* Determines if tracking should be enabled based on configuration and consent
|
|
208
224
|
* @returns {boolean} True if tracking should be enabled
|
|
209
225
|
*/
|
|
210
226
|
private shouldTrack;
|
|
@@ -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) {
|
|
@@ -126,13 +126,17 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
126
126
|
maxQueueSize: options.maxQueueSize,
|
|
127
127
|
flushInterval: options.flushInterval,
|
|
128
128
|
}));
|
|
129
|
+
// Check consent status on initialization
|
|
130
|
+
if (this.hasOptedOutTracking()) {
|
|
131
|
+
lib_1.logger.info("User has previously opted out of tracking");
|
|
132
|
+
}
|
|
129
133
|
// Handle initial provider (injected) as fallback; listeners for EIP-6963 are added later
|
|
130
134
|
var provider = undefined;
|
|
131
135
|
var optProvider = options.provider;
|
|
132
136
|
if (optProvider) {
|
|
133
137
|
provider = optProvider;
|
|
134
138
|
}
|
|
135
|
-
else if (typeof window !==
|
|
139
|
+
else if (typeof window !== "undefined" && window.ethereum) {
|
|
136
140
|
provider = window.ethereum;
|
|
137
141
|
}
|
|
138
142
|
if (provider) {
|
|
@@ -159,9 +163,9 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
159
163
|
FormoAnalytics.prototype.isProviderInValidState = function (provider) {
|
|
160
164
|
// Basic validation: ensure provider exists and has required methods
|
|
161
165
|
return (provider &&
|
|
162
|
-
typeof provider.request ===
|
|
163
|
-
typeof provider.on ===
|
|
164
|
-
typeof provider.removeListener ===
|
|
166
|
+
typeof provider.request === "function" &&
|
|
167
|
+
typeof provider.on === "function" &&
|
|
168
|
+
typeof provider.removeListener === "function");
|
|
165
169
|
};
|
|
166
170
|
FormoAnalytics.init = function (writeKey, options) {
|
|
167
171
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -280,16 +284,18 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
280
284
|
case 0:
|
|
281
285
|
chainId = (params === null || params === void 0 ? void 0 : params.chainId) || this.currentChainId;
|
|
282
286
|
address = (params === null || params === void 0 ? void 0 : params.address) || this.currentAddress;
|
|
283
|
-
providerInfo = this._provider
|
|
287
|
+
providerInfo = this._provider
|
|
288
|
+
? this.getProviderInfo(this._provider)
|
|
289
|
+
: null;
|
|
284
290
|
lib_1.logger.info("Disconnect: Emitting disconnect event with:", {
|
|
285
291
|
chainId: chainId,
|
|
286
292
|
address: address,
|
|
287
293
|
providerName: providerInfo === null || providerInfo === void 0 ? void 0 : providerInfo.name,
|
|
288
|
-
rdns: providerInfo === null || providerInfo === void 0 ? void 0 : providerInfo.rdns
|
|
294
|
+
rdns: providerInfo === null || providerInfo === void 0 ? void 0 : providerInfo.rdns,
|
|
289
295
|
});
|
|
290
296
|
disconnectProperties = __assign(__assign({}, (providerInfo && {
|
|
291
297
|
providerName: providerInfo.name,
|
|
292
|
-
rdns: providerInfo.rdns
|
|
298
|
+
rdns: providerInfo.rdns,
|
|
293
299
|
})), properties);
|
|
294
300
|
return [4 /*yield*/, this.trackEvent(constants_1.EventType.DISCONNECT, __assign(__assign({}, (chainId && { chainId: chainId })), (address && { address: address })), disconnectProperties, context, callback)];
|
|
295
301
|
case 1:
|
|
@@ -436,9 +442,12 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
436
442
|
validAddress: validAddress_1,
|
|
437
443
|
rdns: providerDetail.info.rdns,
|
|
438
444
|
providerName: providerDetail.info.name,
|
|
439
|
-
isAlreadyIdentified: validAddress_1
|
|
445
|
+
isAlreadyIdentified: validAddress_1
|
|
446
|
+
? this.session.isWalletIdentified(validAddress_1, providerDetail.info.rdns)
|
|
447
|
+
: false,
|
|
440
448
|
});
|
|
441
|
-
if (!(validAddress_1 &&
|
|
449
|
+
if (!(validAddress_1 &&
|
|
450
|
+
!this.session.isWalletIdentified(validAddress_1, providerDetail.info.rdns))) return [3 /*break*/, 5];
|
|
442
451
|
lib_1.logger.info("Auto-identifying", validAddress_1, providerDetail.info.name, providerDetail.info.rdns);
|
|
443
452
|
// NOTE: do not set this.currentAddress without explicit connect or identify
|
|
444
453
|
return [4 /*yield*/, this.identify({
|
|
@@ -482,23 +491,25 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
482
491
|
this.currentUserId = userId;
|
|
483
492
|
(0, lib_1.cookie)().set(constants_1.SESSION_USER_ID_KEY, userId);
|
|
484
493
|
}
|
|
485
|
-
isAlreadyIdentified = validAddress
|
|
494
|
+
isAlreadyIdentified = validAddress
|
|
495
|
+
? this.session.isWalletIdentified(validAddress, rdns || "")
|
|
496
|
+
: false;
|
|
486
497
|
lib_1.logger.debug("Identify: Checking deduplication", {
|
|
487
498
|
validAddress: validAddress,
|
|
488
499
|
rdns: rdns,
|
|
489
500
|
providerName: providerName,
|
|
490
501
|
hasValidAddress: !!validAddress,
|
|
491
502
|
hasRdns: !!rdns,
|
|
492
|
-
isAlreadyIdentified: isAlreadyIdentified
|
|
503
|
+
isAlreadyIdentified: isAlreadyIdentified,
|
|
493
504
|
});
|
|
494
505
|
if (isAlreadyIdentified) {
|
|
495
|
-
lib_1.logger.info("Identify: Wallet ".concat(providerName ||
|
|
506
|
+
lib_1.logger.info("Identify: Wallet ".concat(providerName || "Unknown", " with address ").concat(validAddress, " already identified in this session (rdns: ").concat(rdns || "empty", ")"));
|
|
496
507
|
return [2 /*return*/];
|
|
497
508
|
}
|
|
498
509
|
// Mark as identified before emitting the event
|
|
499
510
|
// Mark even if rdns is empty to prevent duplicate empty identifies
|
|
500
511
|
if (validAddress) {
|
|
501
|
-
this.session.markWalletIdentified(validAddress, rdns ||
|
|
512
|
+
this.session.markWalletIdentified(validAddress, rdns || "");
|
|
502
513
|
}
|
|
503
514
|
return [4 /*yield*/, this.trackEvent(constants_1.EventType.IDENTIFY, {
|
|
504
515
|
address: validAddress,
|
|
@@ -567,6 +578,39 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
567
578
|
});
|
|
568
579
|
});
|
|
569
580
|
};
|
|
581
|
+
/*
|
|
582
|
+
Consent management functions
|
|
583
|
+
*/
|
|
584
|
+
/**
|
|
585
|
+
* Opt out of tracking.
|
|
586
|
+
* @returns {void}
|
|
587
|
+
*/
|
|
588
|
+
FormoAnalytics.prototype.optOutTracking = function () {
|
|
589
|
+
lib_1.logger.info("Opting out of tracking");
|
|
590
|
+
// Set opt-out flag in persistent storage using direct cookie access
|
|
591
|
+
// This must be done before switching storage to ensure persistence
|
|
592
|
+
(0, lib_1.setConsentFlag)(this.writeKey, constants_1.CONSENT_OPT_OUT_KEY, "true");
|
|
593
|
+
this.reset();
|
|
594
|
+
lib_1.logger.info("Successfully opted out of tracking");
|
|
595
|
+
};
|
|
596
|
+
/**
|
|
597
|
+
* Opt back into tracking after previously opting out. This will re-enable analytics tracking
|
|
598
|
+
* and switch back to persistent storage.
|
|
599
|
+
* @returns {void}
|
|
600
|
+
*/
|
|
601
|
+
FormoAnalytics.prototype.optInTracking = function () {
|
|
602
|
+
lib_1.logger.info("Opting back into tracking");
|
|
603
|
+
// Remove opt-out flag
|
|
604
|
+
(0, lib_1.removeConsentFlag)(this.writeKey, constants_1.CONSENT_OPT_OUT_KEY);
|
|
605
|
+
lib_1.logger.info("Successfully opted back into tracking");
|
|
606
|
+
};
|
|
607
|
+
/**
|
|
608
|
+
* Check if the user has opted out of tracking.
|
|
609
|
+
* @returns {boolean} True if the user has opted out
|
|
610
|
+
*/
|
|
611
|
+
FormoAnalytics.prototype.hasOptedOutTracking = function () {
|
|
612
|
+
return (0, lib_1.getConsentFlag)(this.writeKey, constants_1.CONSENT_OPT_OUT_KEY) === "true";
|
|
613
|
+
};
|
|
570
614
|
/*
|
|
571
615
|
SDK tracking and event listener functions
|
|
572
616
|
*/
|
|
@@ -633,7 +677,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
633
677
|
// Prevent concurrent processing of accountsChanged events to avoid race conditions
|
|
634
678
|
if (this._processingAccountsChanged) {
|
|
635
679
|
lib_1.logger.debug("OnAccountsChanged: Already processing accountsChanged, skipping", {
|
|
636
|
-
provider: this.getProviderInfo(provider).name
|
|
680
|
+
provider: this.getProviderInfo(provider).name,
|
|
637
681
|
});
|
|
638
682
|
return [2 /*return*/];
|
|
639
683
|
}
|
|
@@ -674,7 +718,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
674
718
|
lib_1.logger.info("OnAccountsChanged: Detecting disconnect, current state:", {
|
|
675
719
|
currentAddress: this.currentAddress,
|
|
676
720
|
currentChainId: this.currentChainId,
|
|
677
|
-
providerMatch: this._provider === provider
|
|
721
|
+
providerMatch: this._provider === provider,
|
|
678
722
|
});
|
|
679
723
|
_a.label = 1;
|
|
680
724
|
case 1:
|
|
@@ -682,7 +726,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
682
726
|
// Pass current state explicitly to ensure we have the data for the disconnect event
|
|
683
727
|
return [4 /*yield*/, this.disconnect({
|
|
684
728
|
chainId: this.currentChainId,
|
|
685
|
-
address: this.currentAddress
|
|
729
|
+
address: this.currentAddress,
|
|
686
730
|
})];
|
|
687
731
|
case 2:
|
|
688
732
|
// Pass current state explicitly to ensure we have the data for the disconnect event
|
|
@@ -710,7 +754,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
710
754
|
activeProvider: this.getProviderInfo(this._provider).name,
|
|
711
755
|
eventProvider: this.getProviderInfo(provider).name,
|
|
712
756
|
currentStoredAddress: currentStoredAddress,
|
|
713
|
-
newProviderAddress: newProviderAddress
|
|
757
|
+
newProviderAddress: newProviderAddress,
|
|
714
758
|
});
|
|
715
759
|
_a.label = 8;
|
|
716
760
|
case 8:
|
|
@@ -720,22 +764,26 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
720
764
|
activeProviderAccounts = _a.sent();
|
|
721
765
|
lib_1.logger.info("OnAccountsChanged: Checking current provider accounts", {
|
|
722
766
|
activeProvider: this.getProviderInfo(this._provider).name,
|
|
723
|
-
accountsLength: activeProviderAccounts
|
|
724
|
-
|
|
767
|
+
accountsLength: activeProviderAccounts
|
|
768
|
+
? activeProviderAccounts.length
|
|
769
|
+
: 0,
|
|
770
|
+
accounts: activeProviderAccounts,
|
|
725
771
|
});
|
|
726
772
|
if (!(activeProviderAccounts && activeProviderAccounts.length > 0)) return [3 /*break*/, 13];
|
|
727
|
-
if (!(newProviderAddress &&
|
|
773
|
+
if (!(newProviderAddress &&
|
|
774
|
+
currentStoredAddress &&
|
|
775
|
+
newProviderAddress !== currentStoredAddress)) return [3 /*break*/, 11];
|
|
728
776
|
lib_1.logger.info("OnAccountsChanged: Different address detected, switching providers despite current provider having accounts", {
|
|
729
777
|
activeProvider: this.getProviderInfo(this._provider).name,
|
|
730
778
|
eventProvider: this.getProviderInfo(provider).name,
|
|
731
779
|
currentAddress: currentStoredAddress,
|
|
732
780
|
newAddress: newProviderAddress,
|
|
733
|
-
reason: PROVIDER_SWITCH_REASONS.ADDRESS_MISMATCH
|
|
781
|
+
reason: PROVIDER_SWITCH_REASONS.ADDRESS_MISMATCH,
|
|
734
782
|
});
|
|
735
783
|
// Emit disconnect for the old provider
|
|
736
784
|
return [4 /*yield*/, this.disconnect({
|
|
737
785
|
chainId: this.currentChainId,
|
|
738
|
-
address: this.currentAddress
|
|
786
|
+
address: this.currentAddress,
|
|
739
787
|
})];
|
|
740
788
|
case 10:
|
|
741
789
|
// Emit disconnect for the old provider
|
|
@@ -749,7 +797,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
749
797
|
eventProvider: this.getProviderInfo(provider).name,
|
|
750
798
|
activeProviderAccountsCount: activeProviderAccounts.length,
|
|
751
799
|
currentAddress: currentStoredAddress,
|
|
752
|
-
newAddress: newProviderAddress
|
|
800
|
+
newAddress: newProviderAddress,
|
|
753
801
|
});
|
|
754
802
|
return [2 /*return*/];
|
|
755
803
|
case 12: return [3 /*break*/, 15];
|
|
@@ -757,12 +805,12 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
757
805
|
lib_1.logger.info("OnAccountsChanged: Current provider has no accounts, switching to new provider", {
|
|
758
806
|
oldProvider: this.getProviderInfo(this._provider).name,
|
|
759
807
|
newProvider: this.getProviderInfo(provider).name,
|
|
760
|
-
reason: PROVIDER_SWITCH_REASONS.NO_ACCOUNTS
|
|
808
|
+
reason: PROVIDER_SWITCH_REASONS.NO_ACCOUNTS,
|
|
761
809
|
});
|
|
762
810
|
// Emit disconnect for the old provider that didn't signal properly
|
|
763
811
|
return [4 /*yield*/, this.disconnect({
|
|
764
812
|
chainId: this.currentChainId,
|
|
765
|
-
address: this.currentAddress
|
|
813
|
+
address: this.currentAddress,
|
|
766
814
|
})];
|
|
767
815
|
case 14:
|
|
768
816
|
// Emit disconnect for the old provider that didn't signal properly
|
|
@@ -776,14 +824,16 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
776
824
|
lib_1.logger.warn("OnAccountsChanged: Could not check current provider accounts, switching to new provider", {
|
|
777
825
|
error: error_2 instanceof Error ? error_2.message : String(error_2),
|
|
778
826
|
errorType: error_2 instanceof Error ? error_2.constructor.name : typeof error_2,
|
|
779
|
-
oldProvider: this._provider
|
|
827
|
+
oldProvider: this._provider
|
|
828
|
+
? this.getProviderInfo(this._provider).name
|
|
829
|
+
: "unknown",
|
|
780
830
|
newProvider: this.getProviderInfo(provider).name,
|
|
781
|
-
reason: PROVIDER_SWITCH_REASONS.CHECK_FAILED
|
|
831
|
+
reason: PROVIDER_SWITCH_REASONS.CHECK_FAILED,
|
|
782
832
|
});
|
|
783
833
|
// If we can't check the current provider, assume it's disconnected
|
|
784
834
|
return [4 /*yield*/, this.disconnect({
|
|
785
835
|
chainId: this.currentChainId,
|
|
786
|
-
address: this.currentAddress
|
|
836
|
+
address: this.currentAddress,
|
|
787
837
|
})];
|
|
788
838
|
case 17:
|
|
789
839
|
// If we can't check the current provider, assume it's disconnected
|
|
@@ -812,7 +862,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
812
862
|
wasDisconnected: wasDisconnected,
|
|
813
863
|
providerName: providerInfo.name,
|
|
814
864
|
rdns: providerInfo.rdns,
|
|
815
|
-
hasChainId: !!nextChainId
|
|
865
|
+
hasChainId: !!nextChainId,
|
|
816
866
|
});
|
|
817
867
|
effectiveChainId = nextChainId || 0;
|
|
818
868
|
if (effectiveChainId === 0) {
|
|
@@ -820,10 +870,10 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
820
870
|
}
|
|
821
871
|
this.connect({
|
|
822
872
|
chainId: effectiveChainId,
|
|
823
|
-
address: address
|
|
873
|
+
address: address,
|
|
824
874
|
}, {
|
|
825
875
|
providerName: providerInfo.name,
|
|
826
|
-
rdns: providerInfo.rdns
|
|
876
|
+
rdns: providerInfo.rdns,
|
|
827
877
|
}).catch(function (error) {
|
|
828
878
|
lib_1.logger.error("Failed to track connect event during account change:", error);
|
|
829
879
|
});
|
|
@@ -905,7 +955,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
905
955
|
return [2 /*return*/];
|
|
906
956
|
lib_1.logger.info("OnDisconnect: Wallet disconnect event received, current state:", {
|
|
907
957
|
currentAddress: this.currentAddress,
|
|
908
|
-
currentChainId: this.currentChainId
|
|
958
|
+
currentChainId: this.currentChainId,
|
|
909
959
|
});
|
|
910
960
|
_a.label = 1;
|
|
911
961
|
case 1:
|
|
@@ -913,7 +963,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
913
963
|
// Pass current state explicitly to ensure we have the data for the disconnect event
|
|
914
964
|
return [4 /*yield*/, this.disconnect({
|
|
915
965
|
chainId: this.currentChainId,
|
|
916
|
-
address: this.currentAddress
|
|
966
|
+
address: this.currentAddress,
|
|
917
967
|
})];
|
|
918
968
|
case 2:
|
|
919
969
|
// Pass current state explicitly to ensure we have the data for the disconnect event
|
|
@@ -940,7 +990,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
940
990
|
_a.label = 1;
|
|
941
991
|
case 1:
|
|
942
992
|
_a.trys.push([1, 3, , 4]);
|
|
943
|
-
if (!(connection === null || connection === void 0 ? void 0 : connection.chainId) || typeof connection.chainId !==
|
|
993
|
+
if (!(connection === null || connection === void 0 ? void 0 : connection.chainId) || typeof connection.chainId !== "string")
|
|
944
994
|
return [2 /*return*/];
|
|
945
995
|
chainId = (0, chain_1.parseChainId)(connection.chainId);
|
|
946
996
|
return [4 /*yield*/, this.getAddress(provider)];
|
|
@@ -956,7 +1006,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
956
1006
|
// Only update global state (chainId/address) from the active provider
|
|
957
1007
|
if (isActiveProvider) {
|
|
958
1008
|
this.currentChainId = chainId;
|
|
959
|
-
this.currentAddress =
|
|
1009
|
+
this.currentAddress =
|
|
1010
|
+
this.validateAndChecksumAddress(address) || undefined;
|
|
960
1011
|
}
|
|
961
1012
|
if (isActiveProvider && this.currentAddress) {
|
|
962
1013
|
providerInfo = this.getProviderInfo(provider);
|
|
@@ -966,7 +1017,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
966
1017
|
providerName: providerInfo.name,
|
|
967
1018
|
rdns: providerInfo.rdns,
|
|
968
1019
|
hasChainId: !!chainId,
|
|
969
|
-
isActiveProvider: isActiveProvider
|
|
1020
|
+
isActiveProvider: isActiveProvider,
|
|
970
1021
|
});
|
|
971
1022
|
effectiveChainId = chainId || 0;
|
|
972
1023
|
if (effectiveChainId === 0) {
|
|
@@ -974,10 +1025,10 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
974
1025
|
}
|
|
975
1026
|
this.connect({
|
|
976
1027
|
chainId: effectiveChainId,
|
|
977
|
-
address: address
|
|
1028
|
+
address: address,
|
|
978
1029
|
}, {
|
|
979
1030
|
providerName: providerInfo.name,
|
|
980
|
-
rdns: providerInfo.rdns
|
|
1031
|
+
rdns: providerInfo.rdns,
|
|
981
1032
|
}).catch(function (error) {
|
|
982
1033
|
lib_1.logger.error("Failed to track connect event during provider connection:", error);
|
|
983
1034
|
});
|
|
@@ -989,7 +1040,9 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
989
1040
|
providerName: providerInfo.name,
|
|
990
1041
|
rdns: providerInfo.rdns,
|
|
991
1042
|
isActiveProvider: isActiveProvider,
|
|
992
|
-
activeProviderInfo: this._provider
|
|
1043
|
+
activeProviderInfo: this._provider
|
|
1044
|
+
? this.getProviderInfo(this._provider)
|
|
1045
|
+
: null,
|
|
993
1046
|
});
|
|
994
1047
|
}
|
|
995
1048
|
}
|
|
@@ -1171,7 +1224,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1171
1224
|
}); };
|
|
1172
1225
|
// Mark the wrapper so we can detect if request is replaced externally and keep a reference on provider
|
|
1173
1226
|
wrappedRequest[types_1.WRAPPED_REQUEST_SYMBOL] = true;
|
|
1174
|
-
provider[types_1.WRAPPED_REQUEST_REF_SYMBOL] =
|
|
1227
|
+
provider[types_1.WRAPPED_REQUEST_REF_SYMBOL] =
|
|
1228
|
+
wrappedRequest;
|
|
1175
1229
|
try {
|
|
1176
1230
|
// Attempt to assign the wrapped request function (rely on try-catch for mutability errors)
|
|
1177
1231
|
provider.request = wrappedRequest;
|
|
@@ -1261,44 +1315,55 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1261
1315
|
};
|
|
1262
1316
|
FormoAnalytics.prototype.trackEvent = function (type, payload, properties, context, callback) {
|
|
1263
1317
|
return __awaiter(this, void 0, void 0, function () {
|
|
1318
|
+
var error_5;
|
|
1264
1319
|
return __generator(this, function (_a) {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1320
|
+
switch (_a.label) {
|
|
1321
|
+
case 0:
|
|
1322
|
+
_a.trys.push([0, 2, , 3]);
|
|
1323
|
+
if (!this.shouldTrack()) {
|
|
1324
|
+
lib_1.logger.info("Skipping ".concat(type, " event due to tracking configuration"));
|
|
1325
|
+
return [2 /*return*/];
|
|
1326
|
+
}
|
|
1327
|
+
return [4 /*yield*/, this.eventManager.addEvent(__assign(__assign({ type: type }, payload), { properties: properties, context: context, callback: callback }), this.currentAddress, this.currentUserId)];
|
|
1328
|
+
case 1:
|
|
1329
|
+
_a.sent();
|
|
1330
|
+
return [3 /*break*/, 3];
|
|
1331
|
+
case 2:
|
|
1332
|
+
error_5 = _a.sent();
|
|
1333
|
+
lib_1.logger.error("Error tracking event:", error_5);
|
|
1334
|
+
return [3 /*break*/, 3];
|
|
1335
|
+
case 3: return [2 /*return*/];
|
|
1274
1336
|
}
|
|
1275
|
-
return [2 /*return*/];
|
|
1276
1337
|
});
|
|
1277
1338
|
});
|
|
1278
1339
|
};
|
|
1279
1340
|
/**
|
|
1280
|
-
* Determines if tracking should be enabled based on configuration
|
|
1341
|
+
* Determines if tracking should be enabled based on configuration and consent
|
|
1281
1342
|
* @returns {boolean} True if tracking should be enabled
|
|
1282
1343
|
*/
|
|
1283
1344
|
FormoAnalytics.prototype.shouldTrack = function () {
|
|
1345
|
+
// First check if user has opted out of tracking
|
|
1346
|
+
if (this.hasOptedOutTracking()) {
|
|
1347
|
+
return false;
|
|
1348
|
+
}
|
|
1284
1349
|
// Check if tracking is explicitly provided as a boolean
|
|
1285
|
-
if (typeof this.options.tracking ===
|
|
1350
|
+
if (typeof this.options.tracking === "boolean") {
|
|
1286
1351
|
return this.options.tracking;
|
|
1287
1352
|
}
|
|
1288
1353
|
// Handle object configuration with exclusion rules
|
|
1289
1354
|
if (this.options.tracking !== null &&
|
|
1290
|
-
typeof this.options.tracking ===
|
|
1355
|
+
typeof this.options.tracking === "object" &&
|
|
1291
1356
|
!Array.isArray(this.options.tracking)) {
|
|
1292
1357
|
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;
|
|
1293
1358
|
// Check hostname exclusions - use exact matching
|
|
1294
|
-
if (excludeHosts.length > 0 && typeof window !==
|
|
1359
|
+
if (excludeHosts.length > 0 && typeof window !== "undefined") {
|
|
1295
1360
|
var hostname = window.location.hostname;
|
|
1296
1361
|
if (excludeHosts.includes(hostname)) {
|
|
1297
1362
|
return false;
|
|
1298
1363
|
}
|
|
1299
1364
|
}
|
|
1300
1365
|
// Check path exclusions - use exact matching
|
|
1301
|
-
if (excludePaths.length > 0 && typeof window !==
|
|
1366
|
+
if (excludePaths.length > 0 && typeof window !== "undefined") {
|
|
1302
1367
|
var pathname = window.location.pathname;
|
|
1303
1368
|
if (excludePaths.includes(pathname)) {
|
|
1304
1369
|
return false;
|
|
@@ -1330,14 +1395,14 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1330
1395
|
if (eip6963Provider) {
|
|
1331
1396
|
return {
|
|
1332
1397
|
name: eip6963Provider.info.name,
|
|
1333
|
-
rdns: eip6963Provider.info.rdns
|
|
1398
|
+
rdns: eip6963Provider.info.rdns,
|
|
1334
1399
|
};
|
|
1335
1400
|
}
|
|
1336
1401
|
// Fallback to injected provider detection
|
|
1337
1402
|
var injectedInfo = this.detectInjectedProviderInfo(provider);
|
|
1338
1403
|
return {
|
|
1339
1404
|
name: injectedInfo.name,
|
|
1340
|
-
rdns: injectedInfo.rdns
|
|
1405
|
+
rdns: injectedInfo.rdns,
|
|
1341
1406
|
};
|
|
1342
1407
|
};
|
|
1343
1408
|
/**
|
|
@@ -1347,45 +1412,45 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1347
1412
|
*/
|
|
1348
1413
|
FormoAnalytics.prototype.detectInjectedProviderInfo = function (provider) {
|
|
1349
1414
|
// Try to detect provider type from common properties
|
|
1350
|
-
var name =
|
|
1351
|
-
var rdns =
|
|
1415
|
+
var name = "Injected Provider";
|
|
1416
|
+
var rdns = "io.injected.provider";
|
|
1352
1417
|
// Use WalletProviderFlags interface for type safety
|
|
1353
1418
|
var flags = provider;
|
|
1354
1419
|
// Check if it's MetaMask
|
|
1355
1420
|
if (flags.isMetaMask) {
|
|
1356
|
-
name =
|
|
1357
|
-
rdns =
|
|
1421
|
+
name = "MetaMask";
|
|
1422
|
+
rdns = "io.metamask";
|
|
1358
1423
|
}
|
|
1359
1424
|
// Check if it's Coinbase Wallet
|
|
1360
1425
|
else if (flags.isCoinbaseWallet) {
|
|
1361
|
-
name =
|
|
1362
|
-
rdns =
|
|
1426
|
+
name = "Coinbase Wallet";
|
|
1427
|
+
rdns = "com.coinbase.wallet";
|
|
1363
1428
|
}
|
|
1364
1429
|
// Check if it's WalletConnect
|
|
1365
1430
|
else if (flags.isWalletConnect) {
|
|
1366
|
-
name =
|
|
1367
|
-
rdns =
|
|
1431
|
+
name = "WalletConnect";
|
|
1432
|
+
rdns = "com.walletconnect";
|
|
1368
1433
|
}
|
|
1369
1434
|
// Check if it's Trust Wallet
|
|
1370
1435
|
else if (flags.isTrust) {
|
|
1371
|
-
name =
|
|
1372
|
-
rdns =
|
|
1436
|
+
name = "Trust Wallet";
|
|
1437
|
+
rdns = "com.trustwallet";
|
|
1373
1438
|
}
|
|
1374
1439
|
// Check if it's Brave Wallet
|
|
1375
1440
|
else if (flags.isBraveWallet) {
|
|
1376
|
-
name =
|
|
1377
|
-
rdns =
|
|
1441
|
+
name = "Brave Wallet";
|
|
1442
|
+
rdns = "com.brave.wallet";
|
|
1378
1443
|
}
|
|
1379
1444
|
// Check if it's Phantom
|
|
1380
1445
|
else if (flags.isPhantom) {
|
|
1381
|
-
name =
|
|
1382
|
-
rdns =
|
|
1446
|
+
name = "Phantom";
|
|
1447
|
+
rdns = "app.phantom";
|
|
1383
1448
|
}
|
|
1384
1449
|
return {
|
|
1385
1450
|
name: name,
|
|
1386
1451
|
rdns: rdns,
|
|
1387
|
-
uuid: "injected-".concat(rdns.replace(/[^a-zA-Z0-9]/g,
|
|
1388
|
-
icon: constants_1.DEFAULT_PROVIDER_ICON
|
|
1452
|
+
uuid: "injected-".concat(rdns.replace(/[^a-zA-Z0-9]/g, "-")),
|
|
1453
|
+
icon: constants_1.DEFAULT_PROVIDER_ICON,
|
|
1389
1454
|
};
|
|
1390
1455
|
};
|
|
1391
1456
|
FormoAnalytics.prototype.getProviders = function () {
|
|
@@ -1439,7 +1504,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1439
1504
|
});
|
|
1440
1505
|
// Fallback to injected provider if no providers are found
|
|
1441
1506
|
if (providers.length === 0) {
|
|
1442
|
-
injected_1 = typeof window !==
|
|
1507
|
+
injected_1 = typeof window !== "undefined" ? window.ethereum : undefined;
|
|
1443
1508
|
if (injected_1) {
|
|
1444
1509
|
// If we have already detected and cached the injected provider, and it's the same instance, return the cached result
|
|
1445
1510
|
if (this._injectedProviderDetail &&
|
|
@@ -1450,7 +1515,9 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1450
1515
|
}
|
|
1451
1516
|
// Merge with existing providers instead of overwriting
|
|
1452
1517
|
if (!this._providers.some(function (existing) { return existing.provider === injected_1; })) {
|
|
1453
|
-
this._providers = __spreadArray(__spreadArray([], this._providers, true), [
|
|
1518
|
+
this._providers = __spreadArray(__spreadArray([], this._providers, true), [
|
|
1519
|
+
this._injectedProviderDetail,
|
|
1520
|
+
], false);
|
|
1454
1521
|
}
|
|
1455
1522
|
return [2 /*return*/, this._providers];
|
|
1456
1523
|
}
|
|
@@ -1461,7 +1528,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1461
1528
|
injectedProviderInfo = this.detectInjectedProviderInfo(injected_1);
|
|
1462
1529
|
injectedDetail = {
|
|
1463
1530
|
provider: injected_1,
|
|
1464
|
-
info: injectedProviderInfo
|
|
1531
|
+
info: injectedProviderInfo,
|
|
1465
1532
|
};
|
|
1466
1533
|
// Cache the detected injected provider detail
|
|
1467
1534
|
this._injectedProviderDetail = injectedDetail;
|
|
@@ -1800,9 +1867,10 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1800
1867
|
*/
|
|
1801
1868
|
FormoAnalytics.prototype.isProviderAlreadyWrapped = function (provider, currentRequest) {
|
|
1802
1869
|
return !!(currentRequest &&
|
|
1803
|
-
typeof currentRequest ===
|
|
1870
|
+
typeof currentRequest === "function" &&
|
|
1804
1871
|
currentRequest[types_1.WRAPPED_REQUEST_SYMBOL] &&
|
|
1805
|
-
provider[types_1.WRAPPED_REQUEST_REF_SYMBOL] ===
|
|
1872
|
+
provider[types_1.WRAPPED_REQUEST_REF_SYMBOL] ===
|
|
1873
|
+
currentRequest);
|
|
1806
1874
|
};
|
|
1807
1875
|
/**
|
|
1808
1876
|
* Handle provider mismatch by switching to the new provider and invalidating old tokens
|
|
@@ -1891,7 +1959,7 @@ var FormoAnalyticsSession = /** @class */ (function () {
|
|
|
1891
1959
|
lib_1.logger.debug("Session: Checking wallet identification", {
|
|
1892
1960
|
identifiedKey: identifiedKey,
|
|
1893
1961
|
isIdentified: isIdentified,
|
|
1894
|
-
hasRdns: !!rdns
|
|
1962
|
+
hasRdns: !!rdns,
|
|
1895
1963
|
});
|
|
1896
1964
|
return isIdentified;
|
|
1897
1965
|
};
|
|
@@ -1909,14 +1977,14 @@ var FormoAnalyticsSession = /** @class */ (function () {
|
|
|
1909
1977
|
});
|
|
1910
1978
|
lib_1.logger.debug("Session: Marked wallet as identified", {
|
|
1911
1979
|
identifiedKey: identifiedKey,
|
|
1912
|
-
hasRdns: !!rdns
|
|
1980
|
+
hasRdns: !!rdns,
|
|
1913
1981
|
});
|
|
1914
1982
|
}
|
|
1915
1983
|
else {
|
|
1916
1984
|
lib_1.logger.info("Session: Wallet already marked as identified", {
|
|
1917
1985
|
identifiedKey: identifiedKey,
|
|
1918
1986
|
existingWallets: identifiedWallets,
|
|
1919
|
-
hasRdns: !!rdns
|
|
1987
|
+
hasRdns: !!rdns,
|
|
1920
1988
|
});
|
|
1921
1989
|
}
|
|
1922
1990
|
};
|
|
@@ -55,7 +55,7 @@ var lib_1 = require("./lib");
|
|
|
55
55
|
var defaultContext = {
|
|
56
56
|
chain: function () { return Promise.resolve(); },
|
|
57
57
|
page: function () { return Promise.resolve(); },
|
|
58
|
-
reset: function () {
|
|
58
|
+
reset: function () { },
|
|
59
59
|
detect: function () { return Promise.resolve(); },
|
|
60
60
|
connect: function () { return Promise.resolve(); },
|
|
61
61
|
disconnect: function () { return Promise.resolve(); },
|
|
@@ -63,6 +63,10 @@ var defaultContext = {
|
|
|
63
63
|
transaction: function () { return Promise.resolve(); },
|
|
64
64
|
identify: function () { return Promise.resolve(); },
|
|
65
65
|
track: function () { return Promise.resolve(); },
|
|
66
|
+
// Consent management methods
|
|
67
|
+
optOutTracking: function () { },
|
|
68
|
+
optInTracking: function () { },
|
|
69
|
+
hasOptedOutTracking: function () { return false; },
|
|
66
70
|
};
|
|
67
71
|
exports.FormoAnalyticsContext = (0, react_1.createContext)(defaultContext);
|
|
68
72
|
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
|