@formo/analytics 1.12.0-alpha.3 → 2.0.0-alpha.2

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.
Files changed (46) hide show
  1. package/dist/cjs/src/FormoAnalytics.d.ts +7 -48
  2. package/dist/cjs/src/FormoAnalytics.d.ts.map +1 -1
  3. package/dist/cjs/src/FormoAnalytics.js +86 -57
  4. package/dist/cjs/src/FormoAnalytics.js.map +1 -1
  5. package/dist/cjs/src/constants/events.d.ts +5 -3
  6. package/dist/cjs/src/constants/events.d.ts.map +1 -1
  7. package/dist/cjs/src/constants/events.js +4 -2
  8. package/dist/cjs/src/constants/events.js.map +1 -1
  9. package/dist/cjs/src/types/index.d.ts +1 -1
  10. package/dist/cjs/src/types/index.d.ts.map +1 -1
  11. package/dist/cjs/src/types/index.js +1 -1
  12. package/dist/cjs/src/types/index.js.map +1 -1
  13. package/dist/cjs/src/types/{wallet.d.ts → web3.d.ts} +1 -1
  14. package/dist/cjs/src/types/web3.d.ts.map +1 -0
  15. package/dist/cjs/src/types/{wallet.js → web3.js} +1 -1
  16. package/dist/cjs/src/types/web3.js.map +1 -0
  17. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  18. package/dist/esm/src/FormoAnalytics.d.ts +7 -48
  19. package/dist/esm/src/FormoAnalytics.d.ts.map +1 -1
  20. package/dist/esm/src/FormoAnalytics.js +86 -57
  21. package/dist/esm/src/FormoAnalytics.js.map +1 -1
  22. package/dist/esm/src/constants/events.d.ts +5 -3
  23. package/dist/esm/src/constants/events.d.ts.map +1 -1
  24. package/dist/esm/src/constants/events.js +4 -2
  25. package/dist/esm/src/constants/events.js.map +1 -1
  26. package/dist/esm/src/types/index.d.ts +1 -1
  27. package/dist/esm/src/types/index.d.ts.map +1 -1
  28. package/dist/esm/src/types/index.js +1 -1
  29. package/dist/esm/src/types/index.js.map +1 -1
  30. package/dist/esm/src/types/{wallet.d.ts → web3.d.ts} +1 -1
  31. package/dist/esm/src/types/web3.d.ts.map +1 -0
  32. package/dist/esm/src/types/web3.js +2 -0
  33. package/dist/esm/src/types/web3.js.map +1 -0
  34. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  35. package/dist/index.umd.min.js +1 -1
  36. package/dist/index.umd.min.js.map +1 -1
  37. package/package.json +1 -1
  38. package/src/FormoAnalytics.ts +83 -89
  39. package/src/constants/events.ts +5 -3
  40. package/src/types/index.ts +1 -1
  41. package/dist/cjs/src/types/wallet.d.ts.map +0 -1
  42. package/dist/cjs/src/types/wallet.js.map +0 -1
  43. package/dist/esm/src/types/wallet.d.ts.map +0 -1
  44. package/dist/esm/src/types/wallet.js +0 -2
  45. package/dist/esm/src/types/wallet.js.map +0 -1
  46. /package/src/types/{wallet.ts → web3.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formo/analytics",
3
- "version": "1.12.0-alpha.3",
3
+ "version": "2.0.0-alpha.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/getformo/sdk.git"
@@ -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(Event.IDENTIFY, userData);
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(Event.PAGE, {
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
- address: this.currentConnectedAccount,
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: 'eth_accounts',
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. eth_accounts returned empty'
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. eth_accounts threw an error`,
353
+ `FormoAnalytics::onChainChanged: unable to get account. eth_requestAccounts threw an error`,
374
354
  err
375
355
  );
376
356
  return;
@@ -407,6 +387,49 @@ export class FormoAnalytics implements IFormoAnalytics {
407
387
  this._registeredProviderListeners['disconnect'] = handleAccountDisconnected;
408
388
  }
409
389
 
390
+ private trackSigning() {
391
+ if (!this.provider) {
392
+ console.error(
393
+ 'error',
394
+ 'FormoAnalytics::_trackSigning: provider not found'
395
+ );
396
+ return false;
397
+ }
398
+
399
+ if (
400
+ Object.getOwnPropertyDescriptor(this.provider, 'request')?.writable ===
401
+ false
402
+ ) {
403
+ console.error(
404
+ 'warning',
405
+ 'FormoAnalytics::_trackSigning: provider.request is not writable'
406
+ );
407
+ return false;
408
+ }
409
+
410
+ // Deliberately not using this._original request to not interfere with the transaction tracking's
411
+ // request modification
412
+ const request = this.provider.request.bind(this.provider);
413
+ this.provider.request = async ({ method, params }: RequestArguments) => {
414
+ if (Array.isArray(params)) {
415
+ if (['signTypedData_v4', 'eth_sign'].includes(method)) {
416
+ this.trackEvent(Event.SIGNING_TRIGGERED, {
417
+ account: params[0],
418
+ message: params[1],
419
+ });
420
+ }
421
+ if (method === 'personal_sign') {
422
+ this.trackEvent(Event.SIGNING_TRIGGERED, {
423
+ message: params[0],
424
+ account: params[1],
425
+ });
426
+ }
427
+ }
428
+ return request({ method, params });
429
+ };
430
+ return true;
431
+ }
432
+
410
433
  private async getCurrentChainId(): Promise<string> {
411
434
  if (!this.provider) {
412
435
  console.error('FormoAnalytics::getCurrentChainId: provider not set');
@@ -435,8 +458,7 @@ export class FormoAnalytics implements IFormoAnalytics {
435
458
 
436
459
  this.currentChainId = await this.getCurrentChainId();
437
460
 
438
- this.connect({ account, chainId: this.currentChainId });
439
- this.storeWalletAddress(account);
461
+ this.connect({ chainId: this.currentChainId, address: account });
440
462
  }
441
463
 
442
464
  private async getCurrentWallet() {
@@ -444,49 +466,21 @@ export class FormoAnalytics implements IFormoAnalytics {
444
466
  console.warn('FormoAnalytics::getCurrentWallet: the provider is not set');
445
467
  return;
446
468
  }
447
- const sessionData = sessionStorage.getItem(this.sessionKey);
448
-
449
- if (!sessionData) {
450
- return null;
451
- }
469
+ try {
470
+ const accounts = await this.provider.request<string[]>({
471
+ method: 'eth_accounts',
472
+ });
452
473
 
453
- const parsedData = JSON.parse(sessionData);
454
- const sessionExpiry = 30 * 60 * 1000; // 30 minutes
455
- const currentTime = Date.now();
474
+ if (accounts && accounts.length > 0 && accounts[0]) {
475
+ this.handleAccountConnected(accounts[0]);
476
+ return accounts && accounts.length > 0 && accounts[0];
477
+ }
456
478
 
457
- if (currentTime - parsedData.timestamp > sessionExpiry) {
458
- console.warn('Session expired. Ignoring wallet address.');
459
- sessionStorage.removeItem(this.sessionKey); // Clear expired session data
479
+ return '';
480
+ } catch (error) {
481
+ console.error('Failed to fetch connected address:', error);
460
482
  return '';
461
483
  }
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
484
  }
491
485
 
492
486
  // Function to build the API URL
@@ -507,20 +501,20 @@ export class FormoAnalytics implements IFormoAnalytics {
507
501
  return 'Error: No token provided';
508
502
  }
509
503
 
510
- connect({ account, chainId }: { account: string; chainId: ChainID }) {
504
+ connect({ chainId, address }: { chainId: ChainID; address: string }): void {
511
505
  if (!chainId) {
512
- throw new Error('FormoAnalytics::connect: chainId cannot be empty');
506
+ throw new Error('FormoAnalytics::wallet: chainId cannot be empty');
513
507
  }
514
- if (!account) {
515
- throw new Error('FormoAnalytics::connect: account cannot be empty');
508
+ if (!address) {
509
+ throw new Error('FormoAnalytics::wallet: account cannot be empty');
516
510
  }
517
511
 
518
512
  this.currentChainId = chainId.toString();
519
- this.currentConnectedAccount = account;
513
+ this.currentConnectedAccount = address;
520
514
 
521
- return this.trackEvent(Event.CONNECT, {
515
+ this.trackEvent(Event.CONNECT, {
522
516
  chainId,
523
- address: account,
517
+ address,
524
518
  });
525
519
  }
526
520
 
@@ -551,7 +545,7 @@ export class FormoAnalytics implements IFormoAnalytics {
551
545
 
552
546
  if (!account && !this.currentConnectedAccount) {
553
547
  throw new Error(
554
- 'FormoAnalytics::chain: account was empty and no previous account has been recorded. You can either pass an account or call connect() first'
548
+ 'FormoAnalytics::chain: account was empty and no previous account has been recorded. You can either pass an account or call wallet() first'
555
549
  );
556
550
  }
557
551
 
@@ -1,7 +1,9 @@
1
1
  export enum Event {
2
- IDENTIFY = 'identify',
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
+ }
@@ -1,2 +1,2 @@
1
1
  export * from './base';
2
- export * from './wallet'
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,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=wallet.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../../../src/types/wallet.ts"],"names":[],"mappings":""}
File without changes