@formo/analytics 1.11.14-alpha.1 → 1.11.14-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 (32) hide show
  1. package/CONTRIBUTING.md +43 -0
  2. package/README.md +4 -251
  3. package/dist/cjs/src/FormoAnalytics.d.ts +1 -6
  4. package/dist/cjs/src/FormoAnalytics.d.ts.map +1 -1
  5. package/dist/cjs/src/FormoAnalytics.js +24 -56
  6. package/dist/cjs/src/FormoAnalytics.js.map +1 -1
  7. package/dist/cjs/src/FormoAnalyticsProvider.d.ts.map +1 -1
  8. package/dist/cjs/src/FormoAnalyticsProvider.js +53 -37
  9. package/dist/cjs/src/FormoAnalyticsProvider.js.map +1 -1
  10. package/dist/cjs/src/constants/config.d.ts +0 -1
  11. package/dist/cjs/src/constants/config.d.ts.map +1 -1
  12. package/dist/cjs/src/constants/config.js +1 -2
  13. package/dist/cjs/src/constants/config.js.map +1 -1
  14. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  15. package/dist/esm/src/FormoAnalytics.d.ts +1 -6
  16. package/dist/esm/src/FormoAnalytics.d.ts.map +1 -1
  17. package/dist/esm/src/FormoAnalytics.js +25 -57
  18. package/dist/esm/src/FormoAnalytics.js.map +1 -1
  19. package/dist/esm/src/FormoAnalyticsProvider.d.ts.map +1 -1
  20. package/dist/esm/src/FormoAnalyticsProvider.js +53 -37
  21. package/dist/esm/src/FormoAnalyticsProvider.js.map +1 -1
  22. package/dist/esm/src/constants/config.d.ts +0 -1
  23. package/dist/esm/src/constants/config.d.ts.map +1 -1
  24. package/dist/esm/src/constants/config.js +0 -1
  25. package/dist/esm/src/constants/config.js.map +1 -1
  26. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  27. package/dist/index.umd.min.js +1 -1
  28. package/dist/index.umd.min.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/FormoAnalytics.ts +24 -75
  31. package/src/FormoAnalyticsProvider.tsx +36 -30
  32. package/src/constants/config.ts +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formo/analytics",
3
- "version": "1.11.14-alpha.1",
3
+ "version": "1.11.14-alpha.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/getformo/sdk.git"
@@ -2,7 +2,6 @@ import axios from "axios";
2
2
  import {
3
3
  COUNTRY_LIST,
4
4
  EVENTS_API_URL,
5
- SESSION_STORAGE_ID_KEY,
6
5
  Event,
7
6
  } from "./constants";
8
7
  import { H } from "highlight.run";
@@ -51,7 +50,6 @@ export class FormoAnalytics implements IFormoAnalytics {
51
50
 
52
51
  private walletAddressSessionKey = "walletAddress";
53
52
  private config: Config;
54
- private sessionIdKey: string = SESSION_STORAGE_ID_KEY;
55
53
  private timezoneToCountry: Record<string, string> = COUNTRY_LIST;
56
54
 
57
55
  currentChainId?: string | null;
@@ -89,56 +87,16 @@ export class FormoAnalytics implements IFormoAnalytics {
89
87
  return this._provider;
90
88
  }
91
89
 
92
- private getSessionId() {
93
- const existingSessionId = this.getCookieValue(this.sessionIdKey);
94
-
95
- if (existingSessionId) {
96
- return existingSessionId;
97
- }
98
-
99
- const newSessionId = this.generateSessionId();
100
- return newSessionId;
101
- }
102
-
103
- private getOrigin(): string {
104
- return window.location.origin || "ORIGIN_NOT_FOUND";
105
- }
106
-
107
- // Function to set the session cookie
108
- private setSessionCookie(): void {
109
- const sessionId = this.getSessionId();
110
- let cookieValue = `${
111
- this.sessionIdKey
112
- }=${sessionId}; Max-Age=1800; path=/; secure; domain=${this.getOrigin()}`;
113
- document.cookie = cookieValue;
114
- }
115
-
116
- // Function to generate a new session ID
117
- private generateSessionId(): string {
118
- return crypto.randomUUID();
119
- }
120
-
121
- // Function to get a cookie value by name
122
- private getCookieValue(name: string): string | undefined {
123
- const cookies = document.cookie.split(";").reduce((acc, cookie) => {
124
- const [key, value] = cookie.split("=");
125
- acc[key.trim()] = value;
126
- return acc;
127
- }, {} as Record<string, string>);
128
- return cookies[name];
129
- }
130
90
 
131
91
  // Function to send tracking data
132
92
  private async trackEvent(action: string, payload: any) {
133
93
  const maxRetries = 3;
134
94
  let attempt = 0;
135
95
 
136
- this.setSessionCookie();
137
96
  const address = await this.getCurrentWallet();
138
97
 
139
98
  const requestData = {
140
99
  address: address,
141
- session_id: this.getSessionId(),
142
100
  timestamp: new Date().toISOString(),
143
101
  action,
144
102
  version: "1",
@@ -305,7 +263,7 @@ export class FormoAnalytics implements IFormoAnalytics {
305
263
  return address;
306
264
  }
307
265
  } catch (err) {
308
- console.error("Failed to fetch accounts from provider:", err);
266
+ console.log("Failed to fetch accounts from provider:", err);
309
267
  }
310
268
  return null;
311
269
  }
@@ -327,7 +285,7 @@ export class FormoAnalytics implements IFormoAnalytics {
327
285
  const currentTime = Date.now();
328
286
 
329
287
  if (currentTime - parsedData.timestamp > sessionExpiry) {
330
- console.warn("Session expired. Ignoring wallet address.");
288
+ console.log("Session expired. Ignoring wallet address.");
331
289
  sessionStorage.removeItem(this.walletAddressSessionKey); // Clear expired session data
332
290
  return "";
333
291
  }
@@ -343,8 +301,7 @@ export class FormoAnalytics implements IFormoAnalytics {
343
301
  method: "eth_accounts",
344
302
  });
345
303
  if (!res || res.length === 0) {
346
- console.error(
347
- "error",
304
+ console.log(
348
305
  "FormoAnalytics::fetchAccounts: unable to get account. eth_accounts returned empty"
349
306
  );
350
307
  return null;
@@ -352,8 +309,7 @@ export class FormoAnalytics implements IFormoAnalytics {
352
309
  return res;
353
310
  } catch (err) {
354
311
  if ((err as any).code !== 4001) {
355
- console.error(
356
- "error",
312
+ console.log(
357
313
  "FormoAnalytics::fetchAccounts: eth_accounts threw an error",
358
314
  err
359
315
  );
@@ -369,15 +325,14 @@ export class FormoAnalytics implements IFormoAnalytics {
369
325
  method: "eth_chainId",
370
326
  });
371
327
  if (!chainIdHex) {
372
- console.error(
328
+ console.log(
373
329
  "FormoAnalytics::fetchChainId: chainIdHex is null or undefined"
374
330
  );
375
331
  return null;
376
332
  }
377
333
  return chainIdHex;
378
334
  } catch (err) {
379
- console.error(
380
- "error",
335
+ console.log(
381
336
  "FormoAnalytics::fetchChainId: eth_chainId threw an error",
382
337
  err
383
338
  );
@@ -387,13 +342,13 @@ export class FormoAnalytics implements IFormoAnalytics {
387
342
 
388
343
  private async getCurrentChainId(): Promise<string> {
389
344
  if (!this.provider) {
390
- console.error("FormoAnalytics::getCurrentChainId: provider not set");
345
+ console.log("FormoAnalytics::getCurrentChainId: provider not set");
391
346
  }
392
347
 
393
348
  const chainIdHex = await this.fetchChainId();
394
349
  // Because we're connected, the chainId cannot be null
395
350
  if (!chainIdHex) {
396
- console.error(
351
+ console.log(
397
352
  `FormoAnalytics::getCurrentChainId: chainIdHex is: ${chainIdHex}`
398
353
  );
399
354
  }
@@ -445,28 +400,32 @@ export class FormoAnalytics implements IFormoAnalytics {
445
400
  this.storeWalletAddress(address);
446
401
  }
447
402
 
448
- private onAddressDisconnected() {
449
- if (!this.currentConnectedAddress) {
403
+ private handleDisconnection(chainId?: string, address?: string) {
404
+ if (!address) {
450
405
  return;
451
406
  }
452
-
453
407
  const payload = {
454
- chain_id: this.currentChainId,
455
- address: this.getAndStoreConnectedAddress(),
408
+ chain_id: chainId || this.currentChainId,
409
+ address,
456
410
  };
457
411
  this.currentChainId = undefined;
458
412
  this.currentConnectedAddress = undefined;
459
413
  this.clearWalletAddress();
460
-
461
414
  return this.trackEvent(Event.DISCONNECT, payload);
462
415
  }
463
416
 
417
+ private onAddressDisconnected() {
418
+ if (!this.currentConnectedAddress) {
419
+ return;
420
+ }
421
+ this.handleDisconnection(this.currentChainId || undefined, this.currentConnectedAddress);
422
+ }
423
+
464
424
  private async onChainChanged(chainIdHex: string) {
465
425
  this.currentChainId = parseInt(chainIdHex).toString();
466
426
  if (!this.currentConnectedAddress) {
467
427
  if (!this.provider) {
468
- console.error(
469
- "error",
428
+ console.log(
470
429
  "FormoAnalytics::onChainChanged: provider not found. CHAIN_CHANGED not reported"
471
430
  );
472
431
  return;
@@ -475,8 +434,7 @@ export class FormoAnalytics implements IFormoAnalytics {
475
434
  // Attempt to fetch and store the connected address
476
435
  const address = await this.getAndStoreConnectedAddress();
477
436
  if (!address) {
478
- console.error(
479
- "error",
437
+ console.log(
480
438
  "FormoAnalytics::onChainChanged: Unable to fetch or store connected address"
481
439
  );
482
440
  return;
@@ -492,8 +450,7 @@ export class FormoAnalytics implements IFormoAnalytics {
492
450
  address: this.currentConnectedAddress,
493
451
  });
494
452
  } else {
495
- console.error(
496
- "error",
453
+ console.log(
497
454
  "FormoAnalytics::onChainChanged: currentConnectedAddress is null despite fetch attempt"
498
455
  );
499
456
  }
@@ -505,7 +462,7 @@ export class FormoAnalytics implements IFormoAnalytics {
505
462
  */
506
463
  private storeWalletAddress(address: string): void {
507
464
  if (!address) {
508
- console.error("No wallet address provided to store.");
465
+ console.log("No wallet address provided to store.");
509
466
  return;
510
467
  }
511
468
 
@@ -556,15 +513,7 @@ export class FormoAnalytics implements IFormoAnalytics {
556
513
  // `disconnect` detection
557
514
  return;
558
515
  }
559
-
560
- const payload = {
561
- chain_id: params?.chainId || this.currentChainId,
562
- address,
563
- };
564
- this.currentChainId = undefined;
565
- this.currentConnectedAddress = undefined;
566
-
567
- return this.trackEvent(Event.DISCONNECT, payload);
516
+ return this.handleDisconnection((params?.chainId?.toString() || this.currentChainId) as string, address);
568
517
  }
569
518
 
570
519
  chain({ chainId, address }: { chainId: ChainID; address?: string }) {
@@ -26,6 +26,40 @@ export const FormoAnalyticsProvider = ({
26
26
  const [isInitialized, setIsInitialized] = useState(false);
27
27
  const initializedStartedRef = useRef(false);
28
28
 
29
+ const initializeHighlight = async () => {
30
+ if (HIGHLIGHT_PROJECT_ID) {
31
+ try {
32
+ H.init(HIGHLIGHT_PROJECT_ID, {
33
+ serviceName: 'formo-analytics-sdk',
34
+ tracingOrigins: true,
35
+ networkRecording: {
36
+ enabled: true,
37
+ recordHeadersAndBody: true,
38
+ urlBlocklist: [
39
+ 'https://www.googleapis.com/identitytoolkit',
40
+ 'https://securetoken.googleapis.com',
41
+ ],
42
+ },
43
+ });
44
+ console.log('Highlight.run initialized successfully');
45
+ } catch (error) {
46
+ console.error('Failed to initialize Highlight.run', error);
47
+ }
48
+ }
49
+ };
50
+
51
+ const initializeFormoAnalytics = async (apiKey: string, options: any) => {
52
+ try {
53
+ const sdkInstance = await FormoAnalytics.init(apiKey, options);
54
+ setSdk(sdkInstance);
55
+ console.log('FormoAnalytics SDK initialized successfully');
56
+ } catch (error) {
57
+ console.error('Failed to initialize FormoAnalytics SDK', error);
58
+ } finally {
59
+ setIsInitialized(true); // Ensure UI renders even after failure
60
+ }
61
+ };
62
+
29
63
  useEffect(() => {
30
64
  const initialize = async () => {
31
65
  if (!apiKey) {
@@ -38,37 +72,9 @@ export const FormoAnalyticsProvider = ({
38
72
  }
39
73
  if (initializedStartedRef.current) return;
40
74
  initializedStartedRef.current = true;
41
- // Initialize Highlight.run if project ID is available
42
- if (HIGHLIGHT_PROJECT_ID) {
43
- try {
44
- H.init(HIGHLIGHT_PROJECT_ID, {
45
- serviceName: 'formo-analytics-sdk',
46
- tracingOrigins: true,
47
- networkRecording: {
48
- enabled: true,
49
- recordHeadersAndBody: true,
50
- urlBlocklist: [
51
- 'https://www.googleapis.com/identitytoolkit',
52
- 'https://securetoken.googleapis.com',
53
- ],
54
- },
55
- });
56
- console.log('Highlight.run initialized successfully');
57
- } catch (error) {
58
- console.error('Failed to initialize Highlight.run', error);
59
- }
60
- }
61
75
 
62
- // Initialize FormoAnalytics
63
- try {
64
- const sdkInstance = await FormoAnalytics.init(apiKey, options);
65
- setSdk(sdkInstance);
66
- console.log('FormoAnalytics SDK initialized successfully');
67
- } catch (error) {
68
- console.error('Failed to initialize FormoAnalytics SDK', error);
69
- } finally {
70
- setIsInitialized(true); // Ensure UI renders even after failure
71
- }
76
+ await initializeHighlight();
77
+ await initializeFormoAnalytics(apiKey, options);
72
78
  };
73
79
 
74
80
  initialize();
@@ -1,5 +1,4 @@
1
1
  export const EVENTS_API_URL = 'https://events.formo.so/events';
2
- export const SESSION_STORAGE_ID_KEY = 'formo-analytics-session-id';
3
2
  export const COUNTRY_LIST = {
4
3
  // Africa
5
4
  'Africa/Accra': 'GH',