@formo/analytics 1.16.7 → 1.16.9
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 +9 -49
- package/dist/cjs/src/FormoAnalytics.d.ts.map +1 -1
- package/dist/cjs/src/FormoAnalytics.js +123 -50
- package/dist/cjs/src/FormoAnalytics.js.map +1 -1
- package/dist/cjs/src/FormoAnalyticsProvider.d.ts +3 -4
- package/dist/cjs/src/FormoAnalyticsProvider.d.ts.map +1 -1
- package/dist/cjs/src/FormoAnalyticsProvider.js +14 -2
- package/dist/cjs/src/FormoAnalyticsProvider.js.map +1 -1
- package/dist/cjs/src/constants/base.d.ts +5 -4
- package/dist/cjs/src/constants/base.d.ts.map +1 -1
- package/dist/cjs/src/constants/base.js +6 -7
- package/dist/cjs/src/constants/base.js.map +1 -1
- package/dist/cjs/src/lib/event/EventFactory.d.ts +4 -1
- package/dist/cjs/src/lib/event/EventFactory.d.ts.map +1 -1
- package/dist/cjs/src/lib/event/EventFactory.js +52 -10
- package/dist/cjs/src/lib/event/EventFactory.js.map +1 -1
- package/dist/cjs/src/lib/event/EventManager.d.ts +2 -1
- package/dist/cjs/src/lib/event/EventManager.d.ts.map +1 -1
- package/dist/cjs/src/lib/event/EventManager.js +2 -2
- package/dist/cjs/src/lib/event/EventManager.js.map +1 -1
- package/dist/cjs/src/lib/event/utils.d.ts +1 -1
- package/dist/cjs/src/lib/event/utils.d.ts.map +1 -1
- package/dist/cjs/src/lib/event/utils.js +3 -4
- package/dist/cjs/src/lib/event/utils.js.map +1 -1
- package/dist/cjs/src/lib/storage/index.d.ts +2 -0
- package/dist/cjs/src/lib/storage/index.d.ts.map +1 -1
- package/dist/cjs/src/lib/storage/index.js +18 -1
- package/dist/cjs/src/lib/storage/index.js.map +1 -1
- package/dist/cjs/src/lib/storage/key.d.ts +9 -0
- package/dist/cjs/src/lib/storage/key.d.ts.map +1 -0
- package/dist/cjs/src/lib/storage/key.js +15 -0
- package/dist/cjs/src/lib/storage/key.js.map +1 -0
- package/dist/cjs/src/lib/storage/native.js +1 -1
- package/dist/cjs/src/lib/storage/native.js.map +1 -1
- package/dist/cjs/src/lib/storage/type.d.ts +4 -0
- package/dist/cjs/src/lib/storage/type.d.ts.map +1 -0
- package/dist/cjs/src/lib/storage/type.js +3 -0
- package/dist/cjs/src/lib/storage/type.js.map +1 -0
- 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 +44 -0
- package/dist/cjs/src/types/base.d.ts.map +1 -1
- package/dist/cjs/src/types/events.d.ts +11 -1
- package/dist/cjs/src/types/events.d.ts.map +1 -1
- package/dist/cjs/src/types/events.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/src/FormoAnalytics.d.ts +9 -49
- package/dist/esm/src/FormoAnalytics.d.ts.map +1 -1
- package/dist/esm/src/FormoAnalytics.js +124 -51
- package/dist/esm/src/FormoAnalytics.js.map +1 -1
- package/dist/esm/src/FormoAnalyticsProvider.d.ts +3 -4
- package/dist/esm/src/FormoAnalyticsProvider.d.ts.map +1 -1
- package/dist/esm/src/FormoAnalyticsProvider.js +15 -3
- package/dist/esm/src/FormoAnalyticsProvider.js.map +1 -1
- package/dist/esm/src/constants/base.d.ts +5 -4
- package/dist/esm/src/constants/base.d.ts.map +1 -1
- package/dist/esm/src/constants/base.js +5 -6
- package/dist/esm/src/constants/base.js.map +1 -1
- package/dist/esm/src/lib/event/EventFactory.d.ts +4 -1
- package/dist/esm/src/lib/event/EventFactory.d.ts.map +1 -1
- package/dist/esm/src/lib/event/EventFactory.js +54 -12
- package/dist/esm/src/lib/event/EventFactory.js.map +1 -1
- package/dist/esm/src/lib/event/EventManager.d.ts +2 -1
- package/dist/esm/src/lib/event/EventManager.d.ts.map +1 -1
- package/dist/esm/src/lib/event/EventManager.js +2 -2
- package/dist/esm/src/lib/event/EventManager.js.map +1 -1
- package/dist/esm/src/lib/event/utils.d.ts +1 -1
- package/dist/esm/src/lib/event/utils.d.ts.map +1 -1
- package/dist/esm/src/lib/event/utils.js +3 -4
- package/dist/esm/src/lib/event/utils.js.map +1 -1
- package/dist/esm/src/lib/storage/index.d.ts +2 -0
- package/dist/esm/src/lib/storage/index.d.ts.map +1 -1
- package/dist/esm/src/lib/storage/index.js +2 -0
- package/dist/esm/src/lib/storage/index.js.map +1 -1
- package/dist/esm/src/lib/storage/key.d.ts +9 -0
- package/dist/esm/src/lib/storage/key.d.ts.map +1 -0
- package/dist/esm/src/lib/storage/key.js +12 -0
- package/dist/esm/src/lib/storage/key.js.map +1 -0
- package/dist/esm/src/lib/storage/native.js +1 -1
- package/dist/esm/src/lib/storage/native.js.map +1 -1
- package/dist/esm/src/lib/storage/type.d.ts +4 -0
- package/dist/esm/src/lib/storage/type.d.ts.map +1 -0
- package/dist/esm/src/lib/storage/type.js +2 -0
- package/dist/esm/src/lib/storage/type.js.map +1 -0
- 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 +44 -0
- package/dist/esm/src/types/base.d.ts.map +1 -1
- package/dist/esm/src/types/events.d.ts +11 -1
- package/dist/esm/src/types/events.d.ts.map +1 -1
- package/dist/esm/src/types/events.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/index.umd.min.js +1 -1
- package/dist/index.umd.min.js.map +1 -1
- package/package.json +2 -2
- package/src/FormoAnalytics.ts +124 -125
- package/src/FormoAnalyticsProvider.tsx +18 -6
- package/src/constants/base.ts +5 -12
- package/src/lib/event/EventFactory.ts +89 -15
- package/src/lib/event/EventManager.ts +3 -2
- package/src/lib/event/utils.ts +3 -4
- package/src/lib/storage/index.ts +2 -0
- package/src/lib/storage/key.ts +16 -0
- package/src/lib/storage/native.ts +1 -1
- package/src/lib/storage/type.ts +3 -0
- package/src/lib/version.ts +1 -1
- package/src/types/base.ts +83 -0
- package/src/types/events.ts +11 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formo/analytics",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.9",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/getformo/sdk.git"
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"size-limit": [
|
|
88
88
|
{
|
|
89
89
|
"path": "dist/index.umd.min.js",
|
|
90
|
-
"limit": "
|
|
90
|
+
"limit": "26 KB"
|
|
91
91
|
}
|
|
92
92
|
],
|
|
93
93
|
"peerDependencies": {
|
package/src/FormoAnalytics.ts
CHANGED
|
@@ -12,16 +12,19 @@ import {
|
|
|
12
12
|
EventManager,
|
|
13
13
|
EventQueue,
|
|
14
14
|
IEventManager,
|
|
15
|
+
IStorageKeyManager,
|
|
15
16
|
local,
|
|
16
17
|
logger,
|
|
17
18
|
Logger,
|
|
18
19
|
session,
|
|
20
|
+
StorageKey,
|
|
19
21
|
} from "./lib";
|
|
20
22
|
import {
|
|
21
23
|
Address,
|
|
22
24
|
ChainID,
|
|
23
25
|
Config,
|
|
24
26
|
EIP1193Provider,
|
|
27
|
+
IFormoAnalytics,
|
|
25
28
|
IFormoEventContext,
|
|
26
29
|
IFormoEventProperties,
|
|
27
30
|
Options,
|
|
@@ -32,94 +35,18 @@ import {
|
|
|
32
35
|
} from "./types";
|
|
33
36
|
import { isAddress, isLocalhost } from "./validators";
|
|
34
37
|
|
|
35
|
-
interface IFormoAnalytics {
|
|
36
|
-
page(
|
|
37
|
-
category?: string,
|
|
38
|
-
name?: string,
|
|
39
|
-
properties?: IFormoEventProperties,
|
|
40
|
-
context?: IFormoEventContext,
|
|
41
|
-
callback?: (...args: unknown[]) => void
|
|
42
|
-
): void;
|
|
43
|
-
reset(): void;
|
|
44
|
-
detect(
|
|
45
|
-
params: { rdns: string; providerName: string },
|
|
46
|
-
properties?: IFormoEventProperties,
|
|
47
|
-
context?: IFormoEventContext,
|
|
48
|
-
callback?: (...args: unknown[]) => void
|
|
49
|
-
): Promise<void>;
|
|
50
|
-
connect(
|
|
51
|
-
params: { chainId: ChainID; address: Address },
|
|
52
|
-
properties?: IFormoEventProperties,
|
|
53
|
-
context?: IFormoEventContext,
|
|
54
|
-
callback?: (...args: unknown[]) => void
|
|
55
|
-
): Promise<void>;
|
|
56
|
-
disconnect(
|
|
57
|
-
params?: { chainId?: ChainID; address?: Address },
|
|
58
|
-
properties?: IFormoEventProperties,
|
|
59
|
-
context?: IFormoEventContext,
|
|
60
|
-
callback?: (...args: unknown[]) => void
|
|
61
|
-
): Promise<void>;
|
|
62
|
-
chain(
|
|
63
|
-
params: { chainId: ChainID; address?: Address },
|
|
64
|
-
properties?: IFormoEventProperties,
|
|
65
|
-
context?: IFormoEventContext,
|
|
66
|
-
callback?: (...args: unknown[]) => void
|
|
67
|
-
): Promise<void>;
|
|
68
|
-
signature(
|
|
69
|
-
params: {
|
|
70
|
-
status: SignatureStatus;
|
|
71
|
-
chainId?: ChainID;
|
|
72
|
-
address: Address;
|
|
73
|
-
message: string;
|
|
74
|
-
signatureHash?: string;
|
|
75
|
-
},
|
|
76
|
-
properties?: IFormoEventProperties,
|
|
77
|
-
context?: IFormoEventContext,
|
|
78
|
-
callback?: (...args: unknown[]) => void
|
|
79
|
-
): Promise<void>;
|
|
80
|
-
transaction(
|
|
81
|
-
params: {
|
|
82
|
-
status: TransactionStatus;
|
|
83
|
-
chainId: ChainID;
|
|
84
|
-
address: Address;
|
|
85
|
-
data?: string;
|
|
86
|
-
to?: string;
|
|
87
|
-
value?: string;
|
|
88
|
-
transactionHash?: string;
|
|
89
|
-
},
|
|
90
|
-
properties?: IFormoEventProperties,
|
|
91
|
-
context?: IFormoEventContext,
|
|
92
|
-
callback?: (...args: unknown[]) => void
|
|
93
|
-
): Promise<void>;
|
|
94
|
-
identify(
|
|
95
|
-
params: {
|
|
96
|
-
address: Address;
|
|
97
|
-
providerName?: string;
|
|
98
|
-
userId?: string;
|
|
99
|
-
rdns?: string;
|
|
100
|
-
},
|
|
101
|
-
properties?: IFormoEventProperties,
|
|
102
|
-
context?: IFormoEventContext,
|
|
103
|
-
callback?: (...args: unknown[]) => void
|
|
104
|
-
): Promise<void>;
|
|
105
|
-
track(
|
|
106
|
-
event: string,
|
|
107
|
-
properties?: IFormoEventProperties,
|
|
108
|
-
context?: IFormoEventContext,
|
|
109
|
-
callback?: (...args: unknown[]) => void
|
|
110
|
-
): Promise<void>;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
38
|
export class FormoAnalytics implements IFormoAnalytics {
|
|
114
39
|
private _provider?: EIP1193Provider;
|
|
115
40
|
private _providerListeners: Record<string, (...args: unknown[]) => void> = {};
|
|
116
41
|
private session: FormoAnalyticsSession;
|
|
117
42
|
private eventManager: IEventManager;
|
|
43
|
+
private storageKeyManager: IStorageKeyManager;
|
|
44
|
+
private _providers: readonly EIP6963ProviderDetail[] = [];
|
|
118
45
|
|
|
119
46
|
config: Config;
|
|
120
47
|
currentChainId?: ChainID;
|
|
121
|
-
currentAddress?: Address;
|
|
122
|
-
currentUserId?: string;
|
|
48
|
+
currentAddress?: Address = "";
|
|
49
|
+
currentUserId?: string = "";
|
|
123
50
|
|
|
124
51
|
private constructor(
|
|
125
52
|
public readonly writeKey: string,
|
|
@@ -130,9 +57,22 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
130
57
|
trackLocalhost: options.trackLocalhost || false,
|
|
131
58
|
};
|
|
132
59
|
|
|
133
|
-
this.
|
|
60
|
+
this.storageKeyManager = new StorageKey(this.config.writeKey);
|
|
61
|
+
|
|
62
|
+
this.session = new FormoAnalyticsSession(this.storageKeyManager);
|
|
134
63
|
this.currentUserId =
|
|
135
|
-
(session.get(
|
|
64
|
+
(session.get(
|
|
65
|
+
this.storageKeyManager.getKey(SESSION_USER_ID_KEY)
|
|
66
|
+
) as string) || undefined;
|
|
67
|
+
|
|
68
|
+
this.identify = this.identify.bind(this);
|
|
69
|
+
this.connect = this.connect.bind(this);
|
|
70
|
+
this.disconnect = this.disconnect.bind(this);
|
|
71
|
+
this.chain = this.chain.bind(this);
|
|
72
|
+
this.signature = this.signature.bind(this);
|
|
73
|
+
this.transaction = this.transaction.bind(this);
|
|
74
|
+
this.detect = this.detect.bind(this);
|
|
75
|
+
this.track = this.track.bind(this);
|
|
136
76
|
|
|
137
77
|
// Initialize logger with configuration from options
|
|
138
78
|
Logger.init({
|
|
@@ -147,7 +87,8 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
147
87
|
retryCount: options.retryCount,
|
|
148
88
|
maxQueueSize: options.maxQueueSize,
|
|
149
89
|
flushInterval: options.flushInterval,
|
|
150
|
-
})
|
|
90
|
+
}),
|
|
91
|
+
this.storageKeyManager
|
|
151
92
|
);
|
|
152
93
|
|
|
153
94
|
// TODO: replace with eip6963
|
|
@@ -167,8 +108,8 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
167
108
|
const analytics = new FormoAnalytics(writeKey, options);
|
|
168
109
|
|
|
169
110
|
// Auto-detect wallet provider
|
|
170
|
-
|
|
171
|
-
await analytics.detectWallets(
|
|
111
|
+
analytics._providers = await analytics.getProviders();
|
|
112
|
+
await analytics.detectWallets(analytics._providers);
|
|
172
113
|
|
|
173
114
|
return analytics;
|
|
174
115
|
}
|
|
@@ -200,8 +141,8 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
200
141
|
*/
|
|
201
142
|
public reset(): void {
|
|
202
143
|
this.currentUserId = undefined;
|
|
203
|
-
local.remove(LOCAL_ANONYMOUS_ID_KEY);
|
|
204
|
-
session.remove(SESSION_USER_ID_KEY);
|
|
144
|
+
local.remove(this.storageKeyManager.getKey(LOCAL_ANONYMOUS_ID_KEY));
|
|
145
|
+
session.remove(this.storageKeyManager.getKey(SESSION_USER_ID_KEY));
|
|
205
146
|
}
|
|
206
147
|
|
|
207
148
|
/**
|
|
@@ -429,17 +370,17 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
429
370
|
|
|
430
371
|
/**
|
|
431
372
|
* Emits an identify event with current wallet address and provider info.
|
|
432
|
-
* @param {string} params.providerName
|
|
433
|
-
* @param {string} params.rdns
|
|
434
|
-
* @param {string} params.userId
|
|
435
373
|
* @param {string} params.address
|
|
374
|
+
* @param {string} params.userId
|
|
375
|
+
* @param {string} params.rdns
|
|
376
|
+
* @param {string} params.providerName
|
|
436
377
|
* @param {IFormoEventProperties} properties
|
|
437
378
|
* @param {IFormoEventContext} context
|
|
438
379
|
* @param {(...args: unknown[]) => void} callback
|
|
439
380
|
* @returns {Promise<void>}
|
|
440
381
|
*/
|
|
441
|
-
|
|
442
|
-
params
|
|
382
|
+
async identify(
|
|
383
|
+
params?: {
|
|
443
384
|
address?: Address;
|
|
444
385
|
providerName?: string;
|
|
445
386
|
userId?: string;
|
|
@@ -449,26 +390,52 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
449
390
|
context?: IFormoEventContext,
|
|
450
391
|
callback?: (...args: unknown[]) => void
|
|
451
392
|
): Promise<void> {
|
|
452
|
-
|
|
393
|
+
try {
|
|
394
|
+
if (!params) { // If no params provided, auto-identify
|
|
395
|
+
for (const providerDetail of this._providers) {
|
|
396
|
+
const provider = providerDetail.provider;
|
|
397
|
+
if (!provider) continue;
|
|
398
|
+
|
|
399
|
+
try {
|
|
400
|
+
const address = await this.getAddress(provider);
|
|
401
|
+
if (address) {
|
|
402
|
+
// NOTE: do not set this.currentAddress without explicit connect or identify
|
|
403
|
+
await this.identify({
|
|
404
|
+
address,
|
|
405
|
+
providerName: providerDetail.info.name,
|
|
406
|
+
rdns: providerDetail.info.rdns,
|
|
407
|
+
}, properties, context, callback);
|
|
408
|
+
}
|
|
409
|
+
} catch (err) {
|
|
410
|
+
logger.error(`Failed to identify provider ${providerDetail.info.name}:`, err);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
453
415
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
this.
|
|
457
|
-
|
|
458
|
-
|
|
416
|
+
// Explicit identify
|
|
417
|
+
const { userId, address, providerName, rdns } = params;
|
|
418
|
+
if (address) this.currentAddress = address;
|
|
419
|
+
if (userId) {
|
|
420
|
+
this.currentUserId = userId;
|
|
421
|
+
session.set(this.storageKeyManager.getKey(SESSION_USER_ID_KEY), userId);
|
|
422
|
+
}
|
|
459
423
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
424
|
+
await this.trackEvent(
|
|
425
|
+
EventType.IDENTIFY,
|
|
426
|
+
{
|
|
427
|
+
address,
|
|
428
|
+
providerName,
|
|
429
|
+
userId,
|
|
430
|
+
rdns,
|
|
431
|
+
},
|
|
432
|
+
properties,
|
|
433
|
+
context,
|
|
434
|
+
callback
|
|
435
|
+
);
|
|
436
|
+
} catch (e) {
|
|
437
|
+
logger.log("identify error", e);
|
|
438
|
+
}
|
|
472
439
|
}
|
|
473
440
|
|
|
474
441
|
/**
|
|
@@ -734,7 +701,7 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
734
701
|
};
|
|
735
702
|
this.currentChainId = undefined;
|
|
736
703
|
this.currentAddress = undefined;
|
|
737
|
-
session.remove(SESSION_USER_ID_KEY);
|
|
704
|
+
session.remove(this.storageKeyManager.getKey(SESSION_USER_ID_KEY));
|
|
738
705
|
|
|
739
706
|
await this.trackEvent(
|
|
740
707
|
EventType.DISCONNECT,
|
|
@@ -783,8 +750,14 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
783
750
|
}
|
|
784
751
|
|
|
785
752
|
private async trackFirstPageHit(): Promise<void> {
|
|
786
|
-
if (
|
|
787
|
-
session.
|
|
753
|
+
if (
|
|
754
|
+
session.get(this.storageKeyManager.getKey(SESSION_CURRENT_URL_KEY)) ===
|
|
755
|
+
null
|
|
756
|
+
) {
|
|
757
|
+
session.set(
|
|
758
|
+
this.storageKeyManager.getKey(SESSION_CURRENT_URL_KEY),
|
|
759
|
+
window.location.href
|
|
760
|
+
);
|
|
788
761
|
}
|
|
789
762
|
|
|
790
763
|
return this.trackPageHit();
|
|
@@ -810,10 +783,15 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
810
783
|
}
|
|
811
784
|
|
|
812
785
|
private async onLocationChange(): Promise<void> {
|
|
813
|
-
const currentUrl = session.get(
|
|
786
|
+
const currentUrl = session.get(
|
|
787
|
+
this.storageKeyManager.getKey(SESSION_CURRENT_URL_KEY)
|
|
788
|
+
);
|
|
814
789
|
|
|
815
790
|
if (currentUrl !== window.location.href) {
|
|
816
|
-
session.set(
|
|
791
|
+
session.set(
|
|
792
|
+
this.storageKeyManager.getKey(SESSION_CURRENT_URL_KEY),
|
|
793
|
+
window.location.href
|
|
794
|
+
);
|
|
817
795
|
this.trackPageHit();
|
|
818
796
|
}
|
|
819
797
|
}
|
|
@@ -876,16 +854,24 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
876
854
|
private async getProviders(): Promise<readonly EIP6963ProviderDetail[]> {
|
|
877
855
|
const store = createStore();
|
|
878
856
|
let providers = store.getProviders();
|
|
879
|
-
|
|
880
|
-
|
|
857
|
+
store.subscribe((providerDetails) => {
|
|
858
|
+
providers = providerDetails;
|
|
859
|
+
this._providers = providers;
|
|
860
|
+
});
|
|
881
861
|
|
|
882
862
|
// Fallback to injected provider if no providers are found
|
|
883
863
|
if (providers.length === 0) {
|
|
884
|
-
|
|
864
|
+
this._providers = window?.ethereum ? [window.ethereum] : [];
|
|
865
|
+
return this._providers;
|
|
885
866
|
}
|
|
867
|
+
this._providers = providers;
|
|
886
868
|
return providers;
|
|
887
869
|
}
|
|
888
870
|
|
|
871
|
+
get providers(): readonly EIP6963ProviderDetail[] {
|
|
872
|
+
return this._providers;
|
|
873
|
+
}
|
|
874
|
+
|
|
889
875
|
private async detectWallets(
|
|
890
876
|
providers: readonly EIP6963ProviderDetail[]
|
|
891
877
|
): Promise<void> {
|
|
@@ -905,15 +891,16 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
905
891
|
return this._provider;
|
|
906
892
|
}
|
|
907
893
|
|
|
908
|
-
private async getAddress(): Promise<Address | null> {
|
|
894
|
+
private async getAddress(provider?: EIP1193Provider): Promise<Address | null> {
|
|
909
895
|
if (this.currentAddress) return this.currentAddress;
|
|
910
|
-
|
|
896
|
+
const p = provider || this.provider;
|
|
897
|
+
if (!p) {
|
|
911
898
|
logger.info("The provider is not set");
|
|
912
899
|
return null;
|
|
913
900
|
}
|
|
914
901
|
|
|
915
902
|
try {
|
|
916
|
-
const accounts = await this.getAccounts();
|
|
903
|
+
const accounts = await this.getAccounts(p);
|
|
917
904
|
if (accounts && accounts.length > 0) {
|
|
918
905
|
if (isAddress(accounts[0])) {
|
|
919
906
|
return accounts[0];
|
|
@@ -1023,16 +1010,28 @@ interface IFormoAnalyticsSession {
|
|
|
1023
1010
|
}
|
|
1024
1011
|
|
|
1025
1012
|
class FormoAnalyticsSession implements IFormoAnalyticsSession {
|
|
1026
|
-
|
|
1013
|
+
private storageKeyManager: IStorageKeyManager;
|
|
1014
|
+
constructor(storageKeyManager: IStorageKeyManager) {
|
|
1015
|
+
this.storageKeyManager = storageKeyManager;
|
|
1016
|
+
}
|
|
1027
1017
|
|
|
1028
1018
|
public isWalletDetected(rdns: string): boolean {
|
|
1029
|
-
const rdnses =
|
|
1019
|
+
const rdnses =
|
|
1020
|
+
(session.get(
|
|
1021
|
+
this.storageKeyManager.getKey(SESSION_WALLET_DETECTED_KEY)
|
|
1022
|
+
) as string[]) || [];
|
|
1030
1023
|
return rdnses.includes(rdns);
|
|
1031
1024
|
}
|
|
1032
1025
|
|
|
1033
1026
|
public markWalletDetected(rdns: string): void {
|
|
1034
|
-
const rdnses =
|
|
1027
|
+
const rdnses =
|
|
1028
|
+
(session.get(
|
|
1029
|
+
this.storageKeyManager.getKey(SESSION_WALLET_DETECTED_KEY)
|
|
1030
|
+
) as string[]) || [];
|
|
1035
1031
|
rdnses.push(rdns);
|
|
1036
|
-
session.set(
|
|
1032
|
+
session.set(
|
|
1033
|
+
this.storageKeyManager.getKey(SESSION_WALLET_DETECTED_KEY),
|
|
1034
|
+
rdnses
|
|
1035
|
+
);
|
|
1037
1036
|
}
|
|
1038
1037
|
}
|
|
@@ -1,11 +1,23 @@
|
|
|
1
|
-
import { createContext, useContext, useEffect,
|
|
1
|
+
import { createContext, useContext, useEffect, useRef, useState } from "react";
|
|
2
2
|
import { FormoAnalytics } from "./FormoAnalytics";
|
|
3
|
-
import { FormoAnalyticsProviderProps } from "./types";
|
|
4
3
|
import { logger } from "./lib";
|
|
4
|
+
import { FormoAnalyticsProviderProps, IFormoAnalytics } from "./types";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
)
|
|
6
|
+
const defaultContext: IFormoAnalytics = {
|
|
7
|
+
chain: () => Promise.resolve(),
|
|
8
|
+
page: () => Promise.resolve(),
|
|
9
|
+
reset: () => Promise.resolve(),
|
|
10
|
+
detect: () => Promise.resolve(),
|
|
11
|
+
connect: () => Promise.resolve(),
|
|
12
|
+
disconnect: () => Promise.resolve(),
|
|
13
|
+
signature: () => Promise.resolve(),
|
|
14
|
+
transaction: () => Promise.resolve(),
|
|
15
|
+
identify: () => Promise.resolve(),
|
|
16
|
+
track: () => Promise.resolve(),
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const FormoAnalyticsContext =
|
|
20
|
+
createContext<IFormoAnalytics>(defaultContext);
|
|
9
21
|
|
|
10
22
|
export const FormoAnalyticsProvider = (props: FormoAnalyticsProviderProps) => {
|
|
11
23
|
const { writeKey, disabled = false, children } = props;
|
|
@@ -29,7 +41,7 @@ const InitializedAnalytics = ({
|
|
|
29
41
|
options,
|
|
30
42
|
children,
|
|
31
43
|
}: FormoAnalyticsProviderProps) => {
|
|
32
|
-
const [sdk, setSdk] = useState<
|
|
44
|
+
const [sdk, setSdk] = useState<IFormoAnalytics>(defaultContext);
|
|
33
45
|
const initializedStartedRef = useRef(false);
|
|
34
46
|
|
|
35
47
|
const initializeFormoAnalytics = async (writeKey: string, options: any) => {
|
package/src/constants/base.ts
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
export const SESSION_TRAFFIC_SOURCE_KEY = "traffic-source";
|
|
2
|
+
export const SESSION_WALLET_DETECTED_KEY = "wallet-detected";
|
|
3
|
+
export const SESSION_CURRENT_URL_KEY = "analytics-current-url";
|
|
4
|
+
export const SESSION_USER_ID_KEY = "user-id";
|
|
2
5
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
export const SESSION_WALLET_DETECTED_KEY = generateStoragePrefix(
|
|
6
|
-
"session-wallet-detected"
|
|
7
|
-
);
|
|
8
|
-
export const SESSION_CURRENT_URL_KEY = generateStoragePrefix(
|
|
9
|
-
"analytics-current-url"
|
|
10
|
-
);
|
|
11
|
-
export const SESSION_USER_ID_KEY = generateStoragePrefix("user-id");
|
|
12
|
-
|
|
13
|
-
export const LOCAL_ANONYMOUS_ID_KEY = generateStoragePrefix("anonymous-id");
|
|
6
|
+
export const LOCAL_ANONYMOUS_ID_KEY = "anonymous-id";
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
COUNTRY_LIST,
|
|
3
|
+
LOCAL_ANONYMOUS_ID_KEY,
|
|
4
|
+
SESSION_TRAFFIC_SOURCE_KEY,
|
|
5
|
+
} from "../../constants";
|
|
2
6
|
import {
|
|
3
7
|
Address,
|
|
4
8
|
APIEvent,
|
|
@@ -6,6 +10,7 @@ import {
|
|
|
6
10
|
IFormoEvent,
|
|
7
11
|
IFormoEventContext,
|
|
8
12
|
IFormoEventProperties,
|
|
13
|
+
ITrafficSource,
|
|
9
14
|
Nullable,
|
|
10
15
|
SignatureStatus,
|
|
11
16
|
TransactionStatus,
|
|
@@ -20,14 +25,17 @@ import { getCurrentTimeFormatted } from "../../utils/timestamp";
|
|
|
20
25
|
import { isUndefined } from "../../validators";
|
|
21
26
|
import { logger } from "../logger";
|
|
22
27
|
import mergeDeepRight from "../ramda/mergeDeepRight";
|
|
23
|
-
import { local } from "../storage";
|
|
28
|
+
import { IStorageKeyManager, local, session } from "../storage";
|
|
24
29
|
import { version } from "../version";
|
|
25
30
|
import { CHANNEL, VERSION } from "./constants";
|
|
26
31
|
import { IEventFactory } from "./type";
|
|
27
32
|
import { generateAnonymousId } from "./utils";
|
|
28
33
|
|
|
29
34
|
class EventFactory implements IEventFactory {
|
|
30
|
-
|
|
35
|
+
private storageKeyManager: IStorageKeyManager;
|
|
36
|
+
constructor(storageKeyManager: IStorageKeyManager) {
|
|
37
|
+
this.storageKeyManager = storageKeyManager;
|
|
38
|
+
}
|
|
31
39
|
|
|
32
40
|
private getTimezone(): string {
|
|
33
41
|
try {
|
|
@@ -68,23 +76,84 @@ class EventFactory implements IEventFactory {
|
|
|
68
76
|
}
|
|
69
77
|
|
|
70
78
|
private extractUTMParameters = (url: string): UTMParameters => {
|
|
71
|
-
const result: UTMParameters = {
|
|
79
|
+
const result: UTMParameters = {
|
|
80
|
+
utm_campaign: "",
|
|
81
|
+
utm_content: "",
|
|
82
|
+
utm_medium: "",
|
|
83
|
+
utm_source: "",
|
|
84
|
+
utm_term: "",
|
|
85
|
+
};
|
|
72
86
|
try {
|
|
73
87
|
const urlObj = new URL(url);
|
|
74
88
|
const UTM_PREFIX = "utm_";
|
|
75
89
|
urlObj.searchParams.forEach((value, sParam) => {
|
|
76
90
|
if (sParam.startsWith(UTM_PREFIX)) {
|
|
77
|
-
result[sParam] = value.trim()
|
|
91
|
+
result[sParam as keyof UTMParameters] = value.trim();
|
|
78
92
|
}
|
|
79
93
|
});
|
|
80
94
|
} catch (error) {}
|
|
81
95
|
return result;
|
|
82
96
|
};
|
|
83
97
|
|
|
98
|
+
private getTrafficSources = (url: string): ITrafficSource => {
|
|
99
|
+
const urlObj = new URL(url);
|
|
100
|
+
const contextTrafficSources: ITrafficSource = {
|
|
101
|
+
...this.extractUTMParameters(url),
|
|
102
|
+
ref: urlObj.searchParams.get("ref")?.trim() || "",
|
|
103
|
+
referrer: document.referrer,
|
|
104
|
+
};
|
|
105
|
+
const storedTrafficSources =
|
|
106
|
+
(session.get(
|
|
107
|
+
this.storageKeyManager.getKey(SESSION_TRAFFIC_SOURCE_KEY)
|
|
108
|
+
) as ITrafficSource) || {};
|
|
109
|
+
|
|
110
|
+
const finalTrafficSources: ITrafficSource = {
|
|
111
|
+
ref: contextTrafficSources.ref || storedTrafficSources?.ref || "",
|
|
112
|
+
referrer:
|
|
113
|
+
contextTrafficSources.referrer || storedTrafficSources?.referrer,
|
|
114
|
+
utm_campaign:
|
|
115
|
+
contextTrafficSources.utm_campaign ||
|
|
116
|
+
storedTrafficSources?.utm_campaign ||
|
|
117
|
+
"",
|
|
118
|
+
utm_content:
|
|
119
|
+
contextTrafficSources.utm_content ||
|
|
120
|
+
storedTrafficSources?.utm_content ||
|
|
121
|
+
"",
|
|
122
|
+
utm_medium:
|
|
123
|
+
contextTrafficSources.utm_medium ||
|
|
124
|
+
storedTrafficSources?.utm_medium ||
|
|
125
|
+
"",
|
|
126
|
+
utm_source:
|
|
127
|
+
contextTrafficSources.utm_source ||
|
|
128
|
+
storedTrafficSources?.utm_source ||
|
|
129
|
+
"",
|
|
130
|
+
utm_term:
|
|
131
|
+
contextTrafficSources.utm_term || storedTrafficSources?.utm_term || "",
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// Store to session
|
|
135
|
+
const sessionStoredTrafficSources = Object.keys(finalTrafficSources).reduce(
|
|
136
|
+
(res: any, key: any) => {
|
|
137
|
+
const value = finalTrafficSources[key as keyof ITrafficSource];
|
|
138
|
+
if (!isUndefined(value) && value !== "") {
|
|
139
|
+
res[key as keyof ITrafficSource] = value;
|
|
140
|
+
}
|
|
141
|
+
return res;
|
|
142
|
+
},
|
|
143
|
+
{}
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
if (Object.keys(sessionStoredTrafficSources).length)
|
|
147
|
+
session.set(
|
|
148
|
+
this.storageKeyManager.getKey(SESSION_TRAFFIC_SOURCE_KEY),
|
|
149
|
+
sessionStoredTrafficSources
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
return finalTrafficSources;
|
|
153
|
+
};
|
|
154
|
+
|
|
84
155
|
// Contextual fields that are automatically collected and populated by the Formo SDK
|
|
85
156
|
private generateContext(context?: IFormoEventContext): IFormoEventContext {
|
|
86
|
-
const url = new URL(globalThis.location.href);
|
|
87
|
-
const params = new URLSearchParams(url.search);
|
|
88
157
|
const path = globalThis.location.pathname;
|
|
89
158
|
const language = this.getLanguage();
|
|
90
159
|
const timezone = this.getTimezone();
|
|
@@ -97,12 +166,10 @@ class EventFactory implements IEventFactory {
|
|
|
97
166
|
locale: language,
|
|
98
167
|
timezone,
|
|
99
168
|
location,
|
|
100
|
-
|
|
101
|
-
...this.extractUTMParameters(globalThis.location.href),
|
|
102
|
-
ref: params.get("ref")?.trim() || "",
|
|
169
|
+
...this.getTrafficSources(globalThis.location.href),
|
|
103
170
|
page_path: path,
|
|
104
171
|
page_title: document.title,
|
|
105
|
-
page_url:
|
|
172
|
+
page_url: globalThis.location.href,
|
|
106
173
|
library_name: "Formo Web SDK",
|
|
107
174
|
library_version,
|
|
108
175
|
};
|
|
@@ -156,7 +223,9 @@ class EventFactory implements IEventFactory {
|
|
|
156
223
|
if (!local.isAvailable()) {
|
|
157
224
|
commonEventData.anonymous_id = generateNativeUUID();
|
|
158
225
|
} else {
|
|
159
|
-
commonEventData.anonymous_id = generateAnonymousId(
|
|
226
|
+
commonEventData.anonymous_id = generateAnonymousId(
|
|
227
|
+
this.storageKeyManager.getKey(LOCAL_ANONYMOUS_ID_KEY)
|
|
228
|
+
);
|
|
160
229
|
}
|
|
161
230
|
|
|
162
231
|
if (formoEvent.address) {
|
|
@@ -354,11 +423,16 @@ class EventFactory implements IEventFactory {
|
|
|
354
423
|
const trackEvent: Partial<IFormoEvent> = {
|
|
355
424
|
properties: {
|
|
356
425
|
...properties,
|
|
357
|
-
...(properties?.revenue !== undefined && {
|
|
426
|
+
...(properties?.revenue !== undefined && {
|
|
358
427
|
revenue: Number(properties.revenue),
|
|
359
|
-
currency: (typeof properties?.currency === "string"
|
|
428
|
+
currency: (typeof properties?.currency === "string"
|
|
429
|
+
? properties.currency
|
|
430
|
+
: "USD"
|
|
431
|
+
).toLowerCase(),
|
|
432
|
+
}),
|
|
433
|
+
...(properties?.points !== undefined && {
|
|
434
|
+
points: Number(properties.points),
|
|
360
435
|
}),
|
|
361
|
-
...(properties?.points !== undefined && { points: Number(properties.points) }),
|
|
362
436
|
},
|
|
363
437
|
event,
|
|
364
438
|
type: "track",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Address, APIEvent } from "../../types";
|
|
2
2
|
import { logger } from "../logger";
|
|
3
3
|
import { IEventQueue } from "../queue";
|
|
4
|
+
import { IStorageKeyManager } from "../storage";
|
|
4
5
|
import { EventFactory } from "./EventFactory";
|
|
5
6
|
import { IEventFactory, IEventManager } from "./type";
|
|
6
7
|
|
|
@@ -15,9 +16,9 @@ class EventManager implements IEventManager {
|
|
|
15
16
|
*
|
|
16
17
|
* @param eventQueue Event queue instance
|
|
17
18
|
*/
|
|
18
|
-
constructor(eventQueue: IEventQueue) {
|
|
19
|
+
constructor(eventQueue: IEventQueue, storageKeyManager: IStorageKeyManager) {
|
|
19
20
|
this.eventQueue = eventQueue;
|
|
20
|
-
this.eventFactory = new EventFactory();
|
|
21
|
+
this.eventFactory = new EventFactory(storageKeyManager);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
/**
|
package/src/lib/event/utils.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { LOCAL_ANONYMOUS_ID_KEY } from "../../constants";
|
|
2
1
|
import { AnonymousID } from "../../types";
|
|
3
2
|
import { generateNativeUUID } from "../../utils";
|
|
4
3
|
import { local } from "../storage";
|
|
5
4
|
|
|
6
|
-
const generateAnonymousId = (): AnonymousID => {
|
|
7
|
-
const storedAnonymousId = local.get(
|
|
5
|
+
const generateAnonymousId = (key: string): AnonymousID => {
|
|
6
|
+
const storedAnonymousId = local.get(key);
|
|
8
7
|
if (storedAnonymousId && typeof storedAnonymousId === "string")
|
|
9
8
|
return storedAnonymousId as AnonymousID;
|
|
10
9
|
const newAnonymousId = generateNativeUUID();
|
|
11
|
-
local.set(
|
|
10
|
+
local.set(key, newAnonymousId);
|
|
12
11
|
return newAnonymousId;
|
|
13
12
|
};
|
|
14
13
|
|
package/src/lib/storage/index.ts
CHANGED