@formo/analytics 1.12.0-alpha.3 → 2.0.0-alpha.1
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 +7 -48
- package/dist/cjs/src/FormoAnalytics.d.ts.map +1 -1
- package/dist/cjs/src/FormoAnalytics.js +87 -63
- package/dist/cjs/src/FormoAnalytics.js.map +1 -1
- package/dist/cjs/src/constants/events.d.ts +5 -3
- package/dist/cjs/src/constants/events.d.ts.map +1 -1
- package/dist/cjs/src/constants/events.js +4 -2
- package/dist/cjs/src/constants/events.js.map +1 -1
- package/dist/cjs/src/types/index.d.ts +1 -1
- package/dist/cjs/src/types/index.d.ts.map +1 -1
- package/dist/cjs/src/types/index.js +1 -1
- package/dist/cjs/src/types/index.js.map +1 -1
- package/dist/cjs/src/types/{wallet.d.ts → web3.d.ts} +1 -1
- package/dist/cjs/src/types/web3.d.ts.map +1 -0
- package/dist/cjs/src/types/{wallet.js → web3.js} +1 -1
- package/dist/cjs/src/types/web3.js.map +1 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/src/FormoAnalytics.d.ts +7 -48
- package/dist/esm/src/FormoAnalytics.d.ts.map +1 -1
- package/dist/esm/src/FormoAnalytics.js +87 -63
- package/dist/esm/src/FormoAnalytics.js.map +1 -1
- package/dist/esm/src/constants/events.d.ts +5 -3
- package/dist/esm/src/constants/events.d.ts.map +1 -1
- package/dist/esm/src/constants/events.js +4 -2
- package/dist/esm/src/constants/events.js.map +1 -1
- package/dist/esm/src/types/index.d.ts +1 -1
- package/dist/esm/src/types/index.d.ts.map +1 -1
- package/dist/esm/src/types/index.js +1 -1
- package/dist/esm/src/types/index.js.map +1 -1
- package/dist/esm/src/types/{wallet.d.ts → web3.d.ts} +1 -1
- package/dist/esm/src/types/web3.d.ts.map +1 -0
- package/dist/esm/src/types/web3.js +2 -0
- package/dist/esm/src/types/web3.js.map +1 -0
- 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 +1 -1
- package/src/FormoAnalytics.ts +84 -93
- package/src/constants/events.ts +5 -3
- package/src/types/index.ts +1 -1
- package/dist/cjs/src/types/wallet.d.ts.map +0 -1
- package/dist/cjs/src/types/wallet.js.map +0 -1
- package/dist/esm/src/types/wallet.d.ts.map +0 -1
- package/dist/esm/src/types/wallet.js +0 -2
- package/dist/esm/src/types/wallet.js.map +0 -1
- /package/src/types/{wallet.ts → web3.ts} +0 -0
package/package.json
CHANGED
package/src/FormoAnalytics.ts
CHANGED
|
@@ -10,49 +10,19 @@ import { H } from 'highlight.run';
|
|
|
10
10
|
import { ChainID, EIP1193Provider, RequestArguments } from './types';
|
|
11
11
|
|
|
12
12
|
interface IFormoAnalytics {
|
|
13
|
-
/**
|
|
14
|
-
* Initializes the FormoAnalytics instance with the provided API key and project ID.
|
|
15
|
-
*/
|
|
16
13
|
init(apiKey: string, projectId: string): Promise<FormoAnalytics>;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Identifies the user with the provided user data.
|
|
20
|
-
*/
|
|
21
|
-
identify(userData: Record<string, any>): void;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Tracks page visit events.
|
|
25
|
-
*/
|
|
14
|
+
identify(userData: any): void;
|
|
26
15
|
page(): void;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Connects to a wallet with the specified chain ID and address.
|
|
30
|
-
*/
|
|
31
|
-
connect(params: { account: string; chainId: ChainID }): Promise<void>;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Disconnects the current wallet and clears the session information.
|
|
35
|
-
*/
|
|
36
|
-
disconnect(attributes?: { account?: string; chainId?: ChainID }): void;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Tracks a specific event with a name and associated data.
|
|
40
|
-
*/
|
|
41
|
-
track(eventName: string, eventData: Record<string, any>): void;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Switches the blockchain chain context and optionally logs additional attributes.
|
|
45
|
-
*/
|
|
46
|
-
chain(attributes: { chainId: ChainID; account?: string }): void;
|
|
16
|
+
track(eventName: string, eventData: any): void;
|
|
47
17
|
}
|
|
48
18
|
export class FormoAnalytics implements IFormoAnalytics {
|
|
49
19
|
private _provider?: EIP1193Provider;
|
|
20
|
+
private _originalRequest?: EIP1193Provider['request'];
|
|
50
21
|
private _registeredProviderListeners: Record<
|
|
51
22
|
string,
|
|
52
23
|
(...args: unknown[]) => void
|
|
53
24
|
> = {};
|
|
54
25
|
|
|
55
|
-
private sessionKey = 'walletAddress';
|
|
56
26
|
private config: any;
|
|
57
27
|
private sessionIdKey: string = SESSION_STORAGE_ID_KEY;
|
|
58
28
|
private timezoneToCountry: Record<string, string> = COUNTRY_LIST;
|
|
@@ -92,7 +62,7 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
92
62
|
}
|
|
93
63
|
|
|
94
64
|
private identifyUser(userData: any) {
|
|
95
|
-
this.trackEvent(
|
|
65
|
+
this.trackEvent('identify', userData);
|
|
96
66
|
}
|
|
97
67
|
|
|
98
68
|
private getSessionId() {
|
|
@@ -276,7 +246,7 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
276
246
|
setTimeout(() => {
|
|
277
247
|
const url = new URL(window.location.href);
|
|
278
248
|
const params = new URLSearchParams(url.search);
|
|
279
|
-
this.trackEvent(
|
|
249
|
+
this.trackEvent('page_hit', {
|
|
280
250
|
'user-agent': window.navigator.userAgent,
|
|
281
251
|
locale: language,
|
|
282
252
|
location: location,
|
|
@@ -308,13 +278,24 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
308
278
|
);
|
|
309
279
|
delete this._registeredProviderListeners[eventName];
|
|
310
280
|
}
|
|
281
|
+
|
|
282
|
+
// Restore original request
|
|
283
|
+
if (
|
|
284
|
+
this._originalRequest &&
|
|
285
|
+
Object.getOwnPropertyDescriptor(this._provider, 'request')?.writable !==
|
|
286
|
+
false
|
|
287
|
+
) {
|
|
288
|
+
this._provider.request = this._originalRequest;
|
|
289
|
+
}
|
|
311
290
|
}
|
|
312
291
|
|
|
313
292
|
this._provider = provider;
|
|
293
|
+
this._originalRequest = provider?.request;
|
|
314
294
|
|
|
315
295
|
this.getCurrentWallet();
|
|
316
296
|
this.registerAccountsChangedListener();
|
|
317
297
|
this.registerChainChangedListener();
|
|
298
|
+
this.trackSigning();
|
|
318
299
|
}
|
|
319
300
|
|
|
320
301
|
private registerChainChangedListener() {
|
|
@@ -330,12 +311,11 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
330
311
|
}
|
|
331
312
|
|
|
332
313
|
const disconnectAttributes = {
|
|
333
|
-
|
|
314
|
+
account: this.currentConnectedAccount,
|
|
334
315
|
chainId: this.currentChainId,
|
|
335
316
|
};
|
|
336
317
|
this.currentChainId = undefined;
|
|
337
318
|
this.currentConnectedAccount = undefined;
|
|
338
|
-
this.clearWalletAddress();
|
|
339
319
|
|
|
340
320
|
return this.trackEvent(Event.DISCONNECT, disconnectAttributes);
|
|
341
321
|
}
|
|
@@ -353,12 +333,12 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
353
333
|
|
|
354
334
|
try {
|
|
355
335
|
const res: string[] | null | undefined = await this.provider.request({
|
|
356
|
-
method: '
|
|
336
|
+
method: 'eth_requestAccounts',
|
|
357
337
|
});
|
|
358
338
|
if (!res || res.length === 0) {
|
|
359
339
|
console.error(
|
|
360
340
|
'error',
|
|
361
|
-
'FormoAnalytics::onChainChanged: unable to get account.
|
|
341
|
+
'FormoAnalytics::onChainChanged: unable to get account. eth_requestAccounts returned empty'
|
|
362
342
|
);
|
|
363
343
|
return;
|
|
364
344
|
}
|
|
@@ -370,7 +350,7 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
370
350
|
// 4001: The request is rejected by the user , see https://docs.metamask.io/wallet/reference/provider-api/#errors
|
|
371
351
|
console.error(
|
|
372
352
|
'error',
|
|
373
|
-
`FormoAnalytics::onChainChanged: unable to get account.
|
|
353
|
+
`FormoAnalytics::onChainChanged: unable to get account. eth_requestAccounts threw an error`,
|
|
374
354
|
err
|
|
375
355
|
);
|
|
376
356
|
return;
|
|
@@ -386,10 +366,7 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
386
366
|
|
|
387
367
|
private async onAccountsChanged(accounts: string[]) {
|
|
388
368
|
if (accounts.length > 0) {
|
|
389
|
-
|
|
390
|
-
if (newAccount !== this.currentConnectedAccount) {
|
|
391
|
-
this.handleAccountConnected(newAccount);
|
|
392
|
-
}
|
|
369
|
+
this.handleAccountConnected(accounts[0]);
|
|
393
370
|
} else {
|
|
394
371
|
this.handleAccountDisconnected();
|
|
395
372
|
}
|
|
@@ -407,6 +384,49 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
407
384
|
this._registeredProviderListeners['disconnect'] = handleAccountDisconnected;
|
|
408
385
|
}
|
|
409
386
|
|
|
387
|
+
private trackSigning() {
|
|
388
|
+
if (!this.provider) {
|
|
389
|
+
console.error(
|
|
390
|
+
'error',
|
|
391
|
+
'FormoAnalytics::_trackSigning: provider not found'
|
|
392
|
+
);
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (
|
|
397
|
+
Object.getOwnPropertyDescriptor(this.provider, 'request')?.writable ===
|
|
398
|
+
false
|
|
399
|
+
) {
|
|
400
|
+
console.error(
|
|
401
|
+
'warning',
|
|
402
|
+
'FormoAnalytics::_trackSigning: provider.request is not writable'
|
|
403
|
+
);
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Deliberately not using this._original request to not interfere with the transaction tracking's
|
|
408
|
+
// request modification
|
|
409
|
+
const request = this.provider.request.bind(this.provider);
|
|
410
|
+
this.provider.request = async ({ method, params }: RequestArguments) => {
|
|
411
|
+
if (Array.isArray(params)) {
|
|
412
|
+
if (['signTypedData_v4', 'eth_sign'].includes(method)) {
|
|
413
|
+
this.trackEvent(Event.SIGNING_TRIGGERED, {
|
|
414
|
+
account: params[0],
|
|
415
|
+
message: params[1],
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
if (method === 'personal_sign') {
|
|
419
|
+
this.trackEvent(Event.SIGNING_TRIGGERED, {
|
|
420
|
+
message: params[0],
|
|
421
|
+
account: params[1],
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return request({ method, params });
|
|
426
|
+
};
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
|
|
410
430
|
private async getCurrentChainId(): Promise<string> {
|
|
411
431
|
if (!this.provider) {
|
|
412
432
|
console.error('FormoAnalytics::getCurrentChainId: provider not set');
|
|
@@ -435,8 +455,7 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
435
455
|
|
|
436
456
|
this.currentChainId = await this.getCurrentChainId();
|
|
437
457
|
|
|
438
|
-
this.connect({
|
|
439
|
-
this.storeWalletAddress(account);
|
|
458
|
+
return this.connect({ chainId: this.currentChainId, address: account });
|
|
440
459
|
}
|
|
441
460
|
|
|
442
461
|
private async getCurrentWallet() {
|
|
@@ -444,49 +463,21 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
444
463
|
console.warn('FormoAnalytics::getCurrentWallet: the provider is not set');
|
|
445
464
|
return;
|
|
446
465
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
466
|
+
try {
|
|
467
|
+
const accounts = await this.provider.request<string[]>({
|
|
468
|
+
method: 'eth_accounts',
|
|
469
|
+
});
|
|
452
470
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
471
|
+
if (accounts && accounts.length > 0 && accounts[0]) {
|
|
472
|
+
this.handleAccountConnected(accounts[0]);
|
|
473
|
+
return accounts && accounts.length > 0 && accounts[0];
|
|
474
|
+
}
|
|
456
475
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
476
|
+
return '';
|
|
477
|
+
} catch (error) {
|
|
478
|
+
console.error('Failed to fetch connected address:', error);
|
|
460
479
|
return '';
|
|
461
480
|
}
|
|
462
|
-
|
|
463
|
-
this.handleAccountConnected(parsedData.address);
|
|
464
|
-
return parsedData.address || '';
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
/**
|
|
468
|
-
* Stores the wallet address in session storage when connected.
|
|
469
|
-
* @param address - The wallet address to store.
|
|
470
|
-
*/
|
|
471
|
-
private storeWalletAddress(address: string): void {
|
|
472
|
-
if (!address) {
|
|
473
|
-
console.error('No wallet address provided to store.');
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
const sessionData = {
|
|
478
|
-
address,
|
|
479
|
-
timestamp: Date.now(),
|
|
480
|
-
};
|
|
481
|
-
|
|
482
|
-
sessionStorage.setItem(this.sessionKey, JSON.stringify(sessionData));
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* Clears the wallet address from session storage when disconnected.
|
|
487
|
-
*/
|
|
488
|
-
private clearWalletAddress(): void {
|
|
489
|
-
sessionStorage.removeItem(this.sessionKey);
|
|
490
481
|
}
|
|
491
482
|
|
|
492
483
|
// Function to build the API URL
|
|
@@ -507,20 +498,20 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
507
498
|
return 'Error: No token provided';
|
|
508
499
|
}
|
|
509
500
|
|
|
510
|
-
connect({
|
|
501
|
+
connect({ chainId, address }: { chainId: ChainID; address: string }): void {
|
|
511
502
|
if (!chainId) {
|
|
512
|
-
throw new Error('FormoAnalytics::
|
|
503
|
+
throw new Error('FormoAnalytics::wallet: chainId cannot be empty');
|
|
513
504
|
}
|
|
514
|
-
if (!
|
|
515
|
-
throw new Error('FormoAnalytics::
|
|
505
|
+
if (!address) {
|
|
506
|
+
throw new Error('FormoAnalytics::wallet: account cannot be empty');
|
|
516
507
|
}
|
|
517
508
|
|
|
518
509
|
this.currentChainId = chainId.toString();
|
|
519
|
-
this.currentConnectedAccount =
|
|
510
|
+
this.currentConnectedAccount = address;
|
|
520
511
|
|
|
521
|
-
|
|
512
|
+
this.trackEvent(Event.CONNECT, {
|
|
522
513
|
chainId,
|
|
523
|
-
address
|
|
514
|
+
address,
|
|
524
515
|
});
|
|
525
516
|
}
|
|
526
517
|
|
|
@@ -551,7 +542,7 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
551
542
|
|
|
552
543
|
if (!account && !this.currentConnectedAccount) {
|
|
553
544
|
throw new Error(
|
|
554
|
-
'FormoAnalytics::chain: account was empty and no previous account has been recorded. You can either pass an account or call
|
|
545
|
+
'FormoAnalytics::chain: account was empty and no previous account has been recorded. You can either pass an account or call wallet() first'
|
|
555
546
|
);
|
|
556
547
|
}
|
|
557
548
|
|
package/src/constants/events.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export enum Event {
|
|
2
|
-
|
|
3
|
-
PAGE = 'page_hit',
|
|
2
|
+
PAGE = 'page',
|
|
4
3
|
CONNECT = 'connect',
|
|
5
4
|
DISCONNECT = 'disconnect',
|
|
6
5
|
CHAIN_CHANGED = 'chain_changed',
|
|
7
|
-
|
|
6
|
+
SIGNING_TRIGGERED = 'signing_triggered',
|
|
7
|
+
CLICK = 'click',
|
|
8
|
+
CUSTOM = 'custom',
|
|
9
|
+
}
|
package/src/types/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './base';
|
|
2
|
-
export * from './
|
|
2
|
+
export * from './web3'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../../../src/types/wallet.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,QAAQ,CAAA;AAEjC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC7C;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACjE,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAA;IAC5E,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAA;CACzF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../../../src/types/wallet.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../../../src/types/wallet.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,QAAQ,CAAA;AAEjC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC7C;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IACjE,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAA;IAC5E,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAA;CACzF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../../../src/types/wallet.ts"],"names":[],"mappings":""}
|
|
File without changes
|