@formo/analytics-react-native 0.1.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.
Files changed (247) hide show
  1. package/README.md +302 -0
  2. package/lib/commonjs/FormoAnalytics.js +526 -0
  3. package/lib/commonjs/FormoAnalytics.js.map +1 -0
  4. package/lib/commonjs/FormoAnalyticsProvider.js +265 -0
  5. package/lib/commonjs/FormoAnalyticsProvider.js.map +1 -0
  6. package/lib/commonjs/constants/config.js +69 -0
  7. package/lib/commonjs/constants/config.js.map +1 -0
  8. package/lib/commonjs/constants/events.js +30 -0
  9. package/lib/commonjs/constants/events.js.map +1 -0
  10. package/lib/commonjs/constants/index.js +39 -0
  11. package/lib/commonjs/constants/index.js.map +1 -0
  12. package/lib/commonjs/constants/storage.js +23 -0
  13. package/lib/commonjs/constants/storage.js.map +1 -0
  14. package/lib/commonjs/index.js +65 -0
  15. package/lib/commonjs/index.js.map +1 -0
  16. package/lib/commonjs/lib/consent/index.js +56 -0
  17. package/lib/commonjs/lib/consent/index.js.map +1 -0
  18. package/lib/commonjs/lib/event/EventFactory.js +493 -0
  19. package/lib/commonjs/lib/event/EventFactory.js.map +1 -0
  20. package/lib/commonjs/lib/event/EventManager.js +46 -0
  21. package/lib/commonjs/lib/event/EventManager.js.map +1 -0
  22. package/lib/commonjs/lib/event/EventQueue.js +290 -0
  23. package/lib/commonjs/lib/event/EventQueue.js.map +1 -0
  24. package/lib/commonjs/lib/event/index.js +50 -0
  25. package/lib/commonjs/lib/event/index.js.map +1 -0
  26. package/lib/commonjs/lib/event/types.js +6 -0
  27. package/lib/commonjs/lib/event/types.js.map +1 -0
  28. package/lib/commonjs/lib/lifecycle/index.js +196 -0
  29. package/lib/commonjs/lib/lifecycle/index.js.map +1 -0
  30. package/lib/commonjs/lib/logger/index.js +48 -0
  31. package/lib/commonjs/lib/logger/index.js.map +1 -0
  32. package/lib/commonjs/lib/session/index.js +109 -0
  33. package/lib/commonjs/lib/session/index.js.map +1 -0
  34. package/lib/commonjs/lib/storage/AsyncStorageAdapter.js +164 -0
  35. package/lib/commonjs/lib/storage/AsyncStorageAdapter.js.map +1 -0
  36. package/lib/commonjs/lib/storage/MemoryStorage.js +41 -0
  37. package/lib/commonjs/lib/storage/MemoryStorage.js.map +1 -0
  38. package/lib/commonjs/lib/storage/StorageBlueprint.js +24 -0
  39. package/lib/commonjs/lib/storage/StorageBlueprint.js.map +1 -0
  40. package/lib/commonjs/lib/storage/StorageManager.js +126 -0
  41. package/lib/commonjs/lib/storage/StorageManager.js.map +1 -0
  42. package/lib/commonjs/lib/storage/index.js +49 -0
  43. package/lib/commonjs/lib/storage/index.js.map +1 -0
  44. package/lib/commonjs/lib/storage/types.js +2 -0
  45. package/lib/commonjs/lib/storage/types.js.map +1 -0
  46. package/lib/commonjs/lib/wagmi/WagmiEventHandler.js +445 -0
  47. package/lib/commonjs/lib/wagmi/WagmiEventHandler.js.map +1 -0
  48. package/lib/commonjs/lib/wagmi/index.js +28 -0
  49. package/lib/commonjs/lib/wagmi/index.js.map +1 -0
  50. package/lib/commonjs/lib/wagmi/types.js +2 -0
  51. package/lib/commonjs/lib/wagmi/types.js.map +1 -0
  52. package/lib/commonjs/types/base.js +6 -0
  53. package/lib/commonjs/types/base.js.map +1 -0
  54. package/lib/commonjs/types/events.js +22 -0
  55. package/lib/commonjs/types/events.js.map +1 -0
  56. package/lib/commonjs/types/index.js +28 -0
  57. package/lib/commonjs/types/index.js.map +1 -0
  58. package/lib/commonjs/utils/address.js +82 -0
  59. package/lib/commonjs/utils/address.js.map +1 -0
  60. package/lib/commonjs/utils/hash.js +30 -0
  61. package/lib/commonjs/utils/hash.js.map +1 -0
  62. package/lib/commonjs/utils/helpers.js +116 -0
  63. package/lib/commonjs/utils/helpers.js.map +1 -0
  64. package/lib/commonjs/utils/index.js +61 -0
  65. package/lib/commonjs/utils/index.js.map +1 -0
  66. package/lib/commonjs/utils/timestamp.js +34 -0
  67. package/lib/commonjs/utils/timestamp.js.map +1 -0
  68. package/lib/commonjs/utils/trafficSource.js +147 -0
  69. package/lib/commonjs/utils/trafficSource.js.map +1 -0
  70. package/lib/commonjs/version.js +10 -0
  71. package/lib/commonjs/version.js.map +1 -0
  72. package/lib/module/FormoAnalytics.js +519 -0
  73. package/lib/module/FormoAnalytics.js.map +1 -0
  74. package/lib/module/FormoAnalyticsProvider.js +256 -0
  75. package/lib/module/FormoAnalyticsProvider.js.map +1 -0
  76. package/lib/module/constants/config.js +62 -0
  77. package/lib/module/constants/config.js.map +1 -0
  78. package/lib/module/constants/events.js +24 -0
  79. package/lib/module/constants/events.js.map +1 -0
  80. package/lib/module/constants/index.js +4 -0
  81. package/lib/module/constants/index.js.map +1 -0
  82. package/lib/module/constants/storage.js +17 -0
  83. package/lib/module/constants/storage.js.map +1 -0
  84. package/lib/module/index.js +51 -0
  85. package/lib/module/index.js.map +1 -0
  86. package/lib/module/lib/consent/index.js +49 -0
  87. package/lib/module/lib/consent/index.js.map +1 -0
  88. package/lib/module/lib/event/EventFactory.js +488 -0
  89. package/lib/module/lib/event/EventFactory.js.map +1 -0
  90. package/lib/module/lib/event/EventManager.js +41 -0
  91. package/lib/module/lib/event/EventManager.js.map +1 -0
  92. package/lib/module/lib/event/EventQueue.js +283 -0
  93. package/lib/module/lib/event/EventQueue.js.map +1 -0
  94. package/lib/module/lib/event/index.js +5 -0
  95. package/lib/module/lib/event/index.js.map +1 -0
  96. package/lib/module/lib/event/types.js +2 -0
  97. package/lib/module/lib/event/types.js.map +1 -0
  98. package/lib/module/lib/lifecycle/index.js +190 -0
  99. package/lib/module/lib/lifecycle/index.js.map +1 -0
  100. package/lib/module/lib/logger/index.js +42 -0
  101. package/lib/module/lib/logger/index.js.map +1 -0
  102. package/lib/module/lib/session/index.js +92 -0
  103. package/lib/module/lib/session/index.js.map +1 -0
  104. package/lib/module/lib/storage/AsyncStorageAdapter.js +158 -0
  105. package/lib/module/lib/storage/AsyncStorageAdapter.js.map +1 -0
  106. package/lib/module/lib/storage/MemoryStorage.js +35 -0
  107. package/lib/module/lib/storage/MemoryStorage.js.map +1 -0
  108. package/lib/module/lib/storage/StorageBlueprint.js +18 -0
  109. package/lib/module/lib/storage/StorageBlueprint.js.map +1 -0
  110. package/lib/module/lib/storage/StorageManager.js +115 -0
  111. package/lib/module/lib/storage/StorageManager.js.map +1 -0
  112. package/lib/module/lib/storage/index.js +5 -0
  113. package/lib/module/lib/storage/index.js.map +1 -0
  114. package/lib/module/lib/storage/types.js +2 -0
  115. package/lib/module/lib/storage/types.js.map +1 -0
  116. package/lib/module/lib/wagmi/WagmiEventHandler.js +439 -0
  117. package/lib/module/lib/wagmi/WagmiEventHandler.js.map +1 -0
  118. package/lib/module/lib/wagmi/index.js +3 -0
  119. package/lib/module/lib/wagmi/index.js.map +1 -0
  120. package/lib/module/lib/wagmi/types.js +2 -0
  121. package/lib/module/lib/wagmi/types.js.map +1 -0
  122. package/lib/module/types/base.js +2 -0
  123. package/lib/module/types/base.js.map +1 -0
  124. package/lib/module/types/events.js +17 -0
  125. package/lib/module/types/events.js.map +1 -0
  126. package/lib/module/types/index.js +3 -0
  127. package/lib/module/types/index.js.map +1 -0
  128. package/lib/module/utils/address.js +74 -0
  129. package/lib/module/utils/address.js.map +1 -0
  130. package/lib/module/utils/hash.js +24 -0
  131. package/lib/module/utils/hash.js.map +1 -0
  132. package/lib/module/utils/helpers.js +105 -0
  133. package/lib/module/utils/helpers.js.map +1 -0
  134. package/lib/module/utils/index.js +6 -0
  135. package/lib/module/utils/index.js.map +1 -0
  136. package/lib/module/utils/timestamp.js +26 -0
  137. package/lib/module/utils/timestamp.js.map +1 -0
  138. package/lib/module/utils/trafficSource.js +137 -0
  139. package/lib/module/utils/trafficSource.js.map +1 -0
  140. package/lib/module/version.js +4 -0
  141. package/lib/module/version.js.map +1 -0
  142. package/lib/typescript/FormoAnalytics.d.ts +163 -0
  143. package/lib/typescript/FormoAnalytics.d.ts.map +1 -0
  144. package/lib/typescript/FormoAnalyticsProvider.d.ts +29 -0
  145. package/lib/typescript/FormoAnalyticsProvider.d.ts.map +1 -0
  146. package/lib/typescript/constants/config.d.ts +8 -0
  147. package/lib/typescript/constants/config.d.ts.map +1 -0
  148. package/lib/typescript/constants/events.d.ts +23 -0
  149. package/lib/typescript/constants/events.d.ts.map +1 -0
  150. package/lib/typescript/constants/index.d.ts +4 -0
  151. package/lib/typescript/constants/index.d.ts.map +1 -0
  152. package/lib/typescript/constants/storage.d.ts +10 -0
  153. package/lib/typescript/constants/storage.d.ts.map +1 -0
  154. package/lib/typescript/index.d.ts +44 -0
  155. package/lib/typescript/index.d.ts.map +1 -0
  156. package/lib/typescript/lib/consent/index.d.ts +13 -0
  157. package/lib/typescript/lib/consent/index.d.ts.map +1 -0
  158. package/lib/typescript/lib/event/EventFactory.d.ts +61 -0
  159. package/lib/typescript/lib/event/EventFactory.d.ts.map +1 -0
  160. package/lib/typescript/lib/event/EventManager.d.ts +17 -0
  161. package/lib/typescript/lib/event/EventManager.d.ts.map +1 -0
  162. package/lib/typescript/lib/event/EventQueue.d.ts +74 -0
  163. package/lib/typescript/lib/event/EventQueue.d.ts.map +1 -0
  164. package/lib/typescript/lib/event/index.d.ts +5 -0
  165. package/lib/typescript/lib/event/index.d.ts.map +1 -0
  166. package/lib/typescript/lib/event/types.d.ts +23 -0
  167. package/lib/typescript/lib/event/types.d.ts.map +1 -0
  168. package/lib/typescript/lib/lifecycle/index.d.ts +46 -0
  169. package/lib/typescript/lib/lifecycle/index.d.ts.map +1 -0
  170. package/lib/typescript/lib/logger/index.d.ts +19 -0
  171. package/lib/typescript/lib/logger/index.d.ts.map +1 -0
  172. package/lib/typescript/lib/session/index.d.ts +41 -0
  173. package/lib/typescript/lib/session/index.d.ts.map +1 -0
  174. package/lib/typescript/lib/storage/AsyncStorageAdapter.d.ts +48 -0
  175. package/lib/typescript/lib/storage/AsyncStorageAdapter.d.ts.map +1 -0
  176. package/lib/typescript/lib/storage/MemoryStorage.d.ts +18 -0
  177. package/lib/typescript/lib/storage/MemoryStorage.d.ts.map +1 -0
  178. package/lib/typescript/lib/storage/StorageBlueprint.d.ts +21 -0
  179. package/lib/typescript/lib/storage/StorageBlueprint.d.ts.map +1 -0
  180. package/lib/typescript/lib/storage/StorageManager.d.ts +45 -0
  181. package/lib/typescript/lib/storage/StorageManager.d.ts.map +1 -0
  182. package/lib/typescript/lib/storage/index.d.ts +5 -0
  183. package/lib/typescript/lib/storage/index.d.ts.map +1 -0
  184. package/lib/typescript/lib/storage/types.d.ts +22 -0
  185. package/lib/typescript/lib/storage/types.d.ts.map +1 -0
  186. package/lib/typescript/lib/wagmi/WagmiEventHandler.d.ts +104 -0
  187. package/lib/typescript/lib/wagmi/WagmiEventHandler.d.ts.map +1 -0
  188. package/lib/typescript/lib/wagmi/index.d.ts +3 -0
  189. package/lib/typescript/lib/wagmi/index.d.ts.map +1 -0
  190. package/lib/typescript/lib/wagmi/types.d.ts +54 -0
  191. package/lib/typescript/lib/wagmi/types.d.ts.map +1 -0
  192. package/lib/typescript/types/base.d.ts +219 -0
  193. package/lib/typescript/types/base.d.ts.map +1 -0
  194. package/lib/typescript/types/events.d.ts +111 -0
  195. package/lib/typescript/types/events.d.ts.map +1 -0
  196. package/lib/typescript/types/index.d.ts +3 -0
  197. package/lib/typescript/types/index.d.ts.map +1 -0
  198. package/lib/typescript/utils/address.d.ts +25 -0
  199. package/lib/typescript/utils/address.d.ts.map +1 -0
  200. package/lib/typescript/utils/hash.d.ts +10 -0
  201. package/lib/typescript/utils/hash.d.ts.map +1 -0
  202. package/lib/typescript/utils/helpers.d.ts +26 -0
  203. package/lib/typescript/utils/helpers.d.ts.map +1 -0
  204. package/lib/typescript/utils/index.d.ts +6 -0
  205. package/lib/typescript/utils/index.d.ts.map +1 -0
  206. package/lib/typescript/utils/timestamp.d.ts +13 -0
  207. package/lib/typescript/utils/timestamp.d.ts.map +1 -0
  208. package/lib/typescript/utils/trafficSource.d.ts +30 -0
  209. package/lib/typescript/utils/trafficSource.d.ts.map +1 -0
  210. package/lib/typescript/version.d.ts +2 -0
  211. package/lib/typescript/version.d.ts.map +1 -0
  212. package/package.json +143 -0
  213. package/src/FormoAnalytics.ts +685 -0
  214. package/src/FormoAnalyticsProvider.tsx +296 -0
  215. package/src/constants/config.ts +62 -0
  216. package/src/constants/events.ts +26 -0
  217. package/src/constants/index.ts +3 -0
  218. package/src/constants/storage.ts +16 -0
  219. package/src/index.ts +55 -0
  220. package/src/lib/consent/index.ts +52 -0
  221. package/src/lib/event/EventFactory.ts +682 -0
  222. package/src/lib/event/EventManager.ts +50 -0
  223. package/src/lib/event/EventQueue.ts +371 -0
  224. package/src/lib/event/index.ts +4 -0
  225. package/src/lib/event/types.ts +107 -0
  226. package/src/lib/lifecycle/index.ts +215 -0
  227. package/src/lib/logger/index.ts +56 -0
  228. package/src/lib/session/index.ts +103 -0
  229. package/src/lib/storage/AsyncStorageAdapter.ts +173 -0
  230. package/src/lib/storage/MemoryStorage.ts +43 -0
  231. package/src/lib/storage/StorageBlueprint.ts +30 -0
  232. package/src/lib/storage/StorageManager.ts +121 -0
  233. package/src/lib/storage/index.ts +4 -0
  234. package/src/lib/storage/types.ts +23 -0
  235. package/src/lib/wagmi/WagmiEventHandler.ts +574 -0
  236. package/src/lib/wagmi/index.ts +2 -0
  237. package/src/lib/wagmi/types.ts +71 -0
  238. package/src/types/base.ts +287 -0
  239. package/src/types/events.ts +140 -0
  240. package/src/types/index.ts +2 -0
  241. package/src/utils/address.ts +84 -0
  242. package/src/utils/hash.ts +23 -0
  243. package/src/utils/helpers.ts +139 -0
  244. package/src/utils/index.ts +5 -0
  245. package/src/utils/timestamp.ts +25 -0
  246. package/src/utils/trafficSource.ts +153 -0
  247. package/src/version.ts +3 -0
@@ -0,0 +1,287 @@
1
+ import { ReactNode } from "react";
2
+ import { LogLevel } from "../lib/logger";
3
+ import {
4
+ IFormoEventContext,
5
+ IFormoEventProperties,
6
+ SignatureStatus,
7
+ TransactionStatus,
8
+ } from "./events";
9
+
10
+ export type Nullable<T> = T | null;
11
+ // Decimal chain ID
12
+ export type ChainID = number;
13
+
14
+ // Address (EVM, Solana, etc.)
15
+ export type Address = string;
16
+
17
+ export type ValidInputTypes = Uint8Array | bigint | string | number | boolean;
18
+
19
+ export interface IFormoAnalytics {
20
+ screen(
21
+ name: string,
22
+ category?: string,
23
+ properties?: IFormoEventProperties,
24
+ context?: IFormoEventContext,
25
+ callback?: (...args: unknown[]) => void
26
+ ): Promise<void>;
27
+ reset(): void;
28
+ cleanup(): Promise<void>;
29
+ detect(
30
+ params: { rdns: string; providerName: string },
31
+ properties?: IFormoEventProperties,
32
+ context?: IFormoEventContext,
33
+ callback?: (...args: unknown[]) => void
34
+ ): Promise<void>;
35
+ connect(
36
+ params: { chainId: ChainID; address: Address },
37
+ properties?: IFormoEventProperties,
38
+ context?: IFormoEventContext,
39
+ callback?: (...args: unknown[]) => void
40
+ ): Promise<void>;
41
+ disconnect(
42
+ params?: { chainId?: ChainID; address?: Address },
43
+ properties?: IFormoEventProperties,
44
+ context?: IFormoEventContext,
45
+ callback?: (...args: unknown[]) => void
46
+ ): Promise<void>;
47
+ chain(
48
+ params: { chainId: ChainID; address?: Address },
49
+ properties?: IFormoEventProperties,
50
+ context?: IFormoEventContext,
51
+ callback?: (...args: unknown[]) => void
52
+ ): Promise<void>;
53
+ signature(
54
+ params: {
55
+ status: SignatureStatus;
56
+ chainId?: ChainID;
57
+ address: Address;
58
+ message: string;
59
+ signatureHash?: string;
60
+ },
61
+ properties?: IFormoEventProperties,
62
+ context?: IFormoEventContext,
63
+ callback?: (...args: unknown[]) => void
64
+ ): Promise<void>;
65
+ transaction(
66
+ params: {
67
+ status: TransactionStatus;
68
+ chainId: ChainID;
69
+ address: Address;
70
+ data?: string;
71
+ to?: string;
72
+ value?: string;
73
+ transactionHash?: string;
74
+ function_name?: string;
75
+ function_args?: Record<string, unknown>;
76
+ },
77
+ properties?: IFormoEventProperties,
78
+ context?: IFormoEventContext,
79
+ callback?: (...args: unknown[]) => void
80
+ ): Promise<void>;
81
+ identify(
82
+ params: {
83
+ address: Address;
84
+ providerName?: string;
85
+ userId?: string;
86
+ rdns?: string;
87
+ },
88
+ properties?: IFormoEventProperties,
89
+ context?: IFormoEventContext,
90
+ callback?: (...args: unknown[]) => void
91
+ ): Promise<void>;
92
+ track(
93
+ event: string,
94
+ properties?: IFormoEventProperties,
95
+ context?: IFormoEventContext,
96
+ callback?: (...args: unknown[]) => void
97
+ ): Promise<void>;
98
+
99
+ // Event flushing
100
+ flush(): Promise<void>;
101
+
102
+ // Traffic source management
103
+ setTrafficSourceFromUrl(url: string): void;
104
+
105
+ // Consent management methods
106
+ optOutTracking(): void;
107
+ optInTracking(): void;
108
+ hasOptedOutTracking(): boolean;
109
+ }
110
+
111
+ export interface Config {
112
+ writeKey: string;
113
+ }
114
+
115
+ /**
116
+ * Configuration options for controlling tracking exclusions
117
+ */
118
+ export interface TrackingOptions {
119
+ excludeChains?: ChainID[];
120
+ }
121
+
122
+ /**
123
+ * Configuration options for controlling wallet event autocapture
124
+ * All events are enabled by default unless explicitly set to false
125
+ */
126
+ export interface AutocaptureOptions {
127
+ /**
128
+ * Track wallet connect events
129
+ * @default true
130
+ */
131
+ connect?: boolean;
132
+
133
+ /**
134
+ * Track wallet disconnect events
135
+ * @default true
136
+ */
137
+ disconnect?: boolean;
138
+
139
+ /**
140
+ * Track wallet signature events (personal_sign, eth_signTypedData_v4)
141
+ * @default true
142
+ */
143
+ signature?: boolean;
144
+
145
+ /**
146
+ * Track wallet transaction events (eth_sendTransaction)
147
+ * @default true
148
+ */
149
+ transaction?: boolean;
150
+
151
+ /**
152
+ * Track wallet chain change events
153
+ * @default true
154
+ */
155
+ chain?: boolean;
156
+
157
+ /**
158
+ * Track application lifecycle events (installed, updated, opened, backgrounded)
159
+ * @default true
160
+ */
161
+ lifecycle?: boolean;
162
+ }
163
+
164
+ /**
165
+ * Configuration options for Wagmi integration
166
+ * Allows the SDK to hook into Wagmi v2 wallet events
167
+ */
168
+ export interface WagmiOptions {
169
+ /**
170
+ * Wagmi config instance from createConfig()
171
+ * The SDK will subscribe to this config's state changes to track wallet events
172
+ */
173
+ config: any;
174
+
175
+ /**
176
+ * Optional QueryClient instance from @tanstack/react-query
177
+ * Required for tracking signature and transaction events via mutation cache
178
+ * If not provided, only connection/disconnection/chain events will be tracked
179
+ */
180
+ queryClient?: any;
181
+ }
182
+
183
+ /**
184
+ * App information for context enrichment
185
+ */
186
+ export interface AppInfo {
187
+ /**
188
+ * App name
189
+ */
190
+ name?: string;
191
+
192
+ /**
193
+ * App version
194
+ */
195
+ version?: string;
196
+
197
+ /**
198
+ * App build number
199
+ */
200
+ build?: string;
201
+
202
+ /**
203
+ * Bundle/package identifier
204
+ */
205
+ bundleId?: string;
206
+ }
207
+
208
+ /**
209
+ * Configuration options for custom referral query parameter parsing
210
+ */
211
+ export interface ReferralOptions {
212
+ /**
213
+ * Custom query parameter names to check for referral codes
214
+ * These are checked in addition to the defaults: ref, referral, refcode, referrer_code
215
+ */
216
+ queryParams?: string[];
217
+ /**
218
+ * Path pattern for extracting referral codes from URL paths
219
+ */
220
+ pathPattern?: string;
221
+ }
222
+
223
+ export interface Options {
224
+ tracking?: boolean | TrackingOptions;
225
+ /**
226
+ * Control wallet event autocapture
227
+ * - `false`: Disable all wallet autocapture
228
+ * - `true`: Enable all wallet events (default)
229
+ * - `AutocaptureOptions`: Granular control over specific events
230
+ * @default true
231
+ */
232
+ autocapture?: boolean | AutocaptureOptions;
233
+ /**
234
+ * Wagmi integration configuration
235
+ * When provided, the SDK will hook into Wagmi's event system
236
+ * @requires wagmi@>=2.0.0
237
+ * @requires @tanstack/react-query@>=5.0.0 (for mutation tracking)
238
+ */
239
+ wagmi?: WagmiOptions;
240
+ /**
241
+ * Custom API host for sending events
242
+ */
243
+ apiHost?: string;
244
+ flushAt?: number;
245
+ flushInterval?: number;
246
+ retryCount?: number;
247
+ maxQueueSize?: number;
248
+ logger?: {
249
+ enabled?: boolean;
250
+ levels?: LogLevel[];
251
+ };
252
+ /**
253
+ * App information for context enrichment
254
+ */
255
+ app?: AppInfo;
256
+ /**
257
+ * Custom referral query parameter configuration
258
+ */
259
+ referral?: ReferralOptions;
260
+ /**
261
+ * Global error handler for SDK errors
262
+ */
263
+ errorHandler?: (err: Error) => void;
264
+ ready?: (formo: IFormoAnalytics) => void;
265
+ }
266
+
267
+ export interface FormoAnalyticsProviderProps {
268
+ writeKey: string;
269
+ options?: Options;
270
+ disabled?: boolean;
271
+ /**
272
+ * AsyncStorage instance from @react-native-async-storage/async-storage
273
+ * Required for persistent storage
274
+ */
275
+ asyncStorage?: import("../lib/storage").AsyncStorageInterface;
276
+ /**
277
+ * Callback when SDK is ready
278
+ * Note: Use useCallback to avoid re-initialization on every render
279
+ */
280
+ onReady?: (sdk: IFormoAnalytics) => void;
281
+ /**
282
+ * Callback when SDK initialization fails
283
+ * Note: Use useCallback to avoid re-initialization on every render
284
+ */
285
+ onError?: (error: Error) => void;
286
+ children: ReactNode;
287
+ }
@@ -0,0 +1,140 @@
1
+ import { Address, ChainID, Nullable } from "./base";
2
+ import { TEventChannel, TEventType } from "../constants";
3
+
4
+ export type AnonymousID = string;
5
+
6
+ export interface ICommonProperties {
7
+ anonymous_id: AnonymousID;
8
+ user_id: Nullable<string>;
9
+ address: Nullable<string>;
10
+ type: TEventType;
11
+ channel: TEventChannel;
12
+ version: string;
13
+ original_timestamp: string;
14
+ event?: Nullable<string>;
15
+ }
16
+
17
+ export type IFormoEventProperties = Record<string, unknown>;
18
+ export type IFormoEventContext = Record<string, unknown>;
19
+
20
+ export type UTMParameters = {
21
+ utm_source: string;
22
+ utm_medium: string;
23
+ utm_campaign: string;
24
+ utm_term: string;
25
+ utm_content: string;
26
+ };
27
+
28
+ export type ITrafficSource = UTMParameters & {
29
+ ref: string;
30
+ referrer: string;
31
+ };
32
+
33
+ export interface IFormoEvent extends ICommonProperties {
34
+ context: Nullable<IFormoEventContext>;
35
+ properties: Nullable<IFormoEventProperties>;
36
+ }
37
+
38
+ export type IFormoEventPayload = IFormoEvent & {
39
+ message_id: string;
40
+ };
41
+
42
+ //#region Specific Event Types
43
+ export interface ScreenAPIEvent {
44
+ type: "screen";
45
+ name: string;
46
+ category?: string;
47
+ }
48
+
49
+ export interface DetectAPIEvent {
50
+ type: "detect";
51
+ providerName: string;
52
+ rdns: string;
53
+ }
54
+
55
+ export interface IdentifyAPIEvent {
56
+ type: "identify";
57
+ address: string;
58
+ providerName: string;
59
+ rdns: string;
60
+ userId?: Nullable<string>;
61
+ }
62
+
63
+ export interface ChainAPIEvent {
64
+ type: "chain";
65
+ chainId: ChainID;
66
+ address: Address;
67
+ }
68
+
69
+ export interface TransactionAPIEvent {
70
+ type: "transaction";
71
+ status: TransactionStatus;
72
+ chainId: ChainID;
73
+ address: Address;
74
+ data?: string;
75
+ to?: string;
76
+ value?: string;
77
+ transactionHash?: string;
78
+ function_name?: string;
79
+ function_args?: Record<string, unknown>;
80
+ }
81
+
82
+ export interface SignatureAPIEvent {
83
+ type: "signature";
84
+ status: SignatureStatus;
85
+ chainId?: ChainID;
86
+ address: Address;
87
+ message: string;
88
+ signatureHash?: string;
89
+ }
90
+
91
+ export interface ConnectAPIEvent {
92
+ type: "connect";
93
+ chainId: ChainID;
94
+ address: Address;
95
+ }
96
+
97
+ export interface DisconnectAPIEvent {
98
+ type: "disconnect";
99
+ chainId?: ChainID;
100
+ address?: Address;
101
+ }
102
+
103
+ export interface TrackAPIEvent {
104
+ type: "track";
105
+ event: string;
106
+ volume?: number;
107
+ revenue?: number;
108
+ currency?: string;
109
+ points?: number;
110
+ }
111
+
112
+ export type APIEvent = {
113
+ properties?: IFormoEventProperties;
114
+ context?: IFormoEventContext;
115
+ callback?: (...args: unknown[]) => void;
116
+ } & (
117
+ | ScreenAPIEvent
118
+ | DetectAPIEvent
119
+ | IdentifyAPIEvent
120
+ | ChainAPIEvent
121
+ | TransactionAPIEvent
122
+ | SignatureAPIEvent
123
+ | ConnectAPIEvent
124
+ | DisconnectAPIEvent
125
+ | TrackAPIEvent
126
+ );
127
+
128
+ export enum SignatureStatus {
129
+ REQUESTED = "requested",
130
+ REJECTED = "rejected",
131
+ CONFIRMED = "confirmed",
132
+ }
133
+
134
+ export enum TransactionStatus {
135
+ STARTED = "started",
136
+ REJECTED = "rejected",
137
+ BROADCASTED = "broadcasted",
138
+ CONFIRMED = "confirmed",
139
+ REVERTED = "reverted",
140
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./base";
2
+ export * from "./events";
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Address validation and checksum utilities
3
+ *
4
+ * Uses ethereum-cryptography for proper EIP-55 checksum computation
5
+ */
6
+
7
+ import { keccak256 } from "ethereum-cryptography/keccak.js";
8
+ import { utf8ToBytes } from "ethereum-cryptography/utils.js";
9
+
10
+ /**
11
+ * Convert Uint8Array to hex string
12
+ */
13
+ function toHex(bytes: Uint8Array): string {
14
+ return Array.from(bytes)
15
+ .map((b) => b.toString(16).padStart(2, "0"))
16
+ .join("");
17
+ }
18
+
19
+ /**
20
+ * Check if a string is a valid Ethereum address
21
+ */
22
+ export function isValidAddress(address: string): boolean {
23
+ if (!address) return false;
24
+ if (typeof address !== "string") return false;
25
+
26
+ // Check if it matches basic hex address format
27
+ return /^0x[a-fA-F0-9]{40}$/.test(address);
28
+ }
29
+
30
+ /**
31
+ * Convert address to EIP-55 checksum format
32
+ *
33
+ * Uses keccak256 from ethereum-cryptography for correct checksumming
34
+ * See: https://eips.ethereum.org/EIPS/eip-55
35
+ */
36
+ export function toChecksumAddress(address: string): string {
37
+ if (!isValidAddress(address)) {
38
+ return address;
39
+ }
40
+
41
+ const lowercaseAddress = address.toLowerCase().replace("0x", "");
42
+ const hash = toHex(keccak256(utf8ToBytes(lowercaseAddress)));
43
+
44
+ let checksumAddress = "0x";
45
+
46
+ for (let i = 0; i < lowercaseAddress.length; i++) {
47
+ const char = lowercaseAddress[i];
48
+ if (char && parseInt(hash[i] || "0", 16) >= 8) {
49
+ checksumAddress += char.toUpperCase();
50
+ } else {
51
+ checksumAddress += char;
52
+ }
53
+ }
54
+
55
+ return checksumAddress;
56
+ }
57
+
58
+ /**
59
+ * Get valid address or null
60
+ */
61
+ export function getValidAddress(
62
+ address: string | undefined | null
63
+ ): string | null {
64
+ if (!address) return null;
65
+ const trimmed = typeof address === "string" ? address.trim() : address;
66
+ if (!isValidAddress(trimmed)) return null;
67
+ return trimmed;
68
+ }
69
+
70
+ /**
71
+ * Blocked addresses that should not emit events
72
+ * (zero address, dead address)
73
+ */
74
+ const BLOCKED_ADDRESSES = new Set<string>([
75
+ "0x0000000000000000000000000000000000000000",
76
+ "0x000000000000000000000000000000000000dead",
77
+ ]);
78
+
79
+ /**
80
+ * Check if address is in blocked list
81
+ */
82
+ export function isBlockedAddress(address: string): boolean {
83
+ return BLOCKED_ADDRESSES.has(address.toLowerCase());
84
+ }
@@ -0,0 +1,23 @@
1
+ import { sha256 } from "ethereum-cryptography/sha256";
2
+ import { utf8ToBytes, bytesToHex } from "ethereum-cryptography/utils";
3
+
4
+ /**
5
+ * Generate a SHA-256 hash for event deduplication
6
+ * Returns full 64 hex chars to match web SDK format
7
+ */
8
+ export async function hash(input: string): Promise<string> {
9
+ const bytes = utf8ToBytes(input);
10
+ const hashBytes = sha256(bytes);
11
+ return bytesToHex(hashBytes);
12
+ }
13
+
14
+ /**
15
+ * Generate a UUID v4
16
+ */
17
+ export function generateUUID(): string {
18
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
19
+ const r = (Math.random() * 16) | 0;
20
+ const v = c === "x" ? r : (r & 0x3) | 0x8;
21
+ return v.toString(16);
22
+ });
23
+ }
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Clamp a number between min and max values
3
+ */
4
+ export function clampNumber(value: number, max: number, min: number): number {
5
+ return Math.min(Math.max(value, min), max);
6
+ }
7
+
8
+ /**
9
+ * Check if value is undefined
10
+ */
11
+ export function isUndefined(value: unknown): value is undefined {
12
+ return value === undefined;
13
+ }
14
+
15
+ /**
16
+ * Convert a camelCase/PascalCase string to snake_case
17
+ * Handles consecutive uppercase letters (acronyms) correctly:
18
+ * - "userID" -> "user_id"
19
+ * - "XMLParser" -> "xml_parser"
20
+ * - "getHTTPResponse" -> "get_http_response"
21
+ */
22
+ function camelToSnake(str: string): string {
23
+ return str
24
+ // Insert underscore before sequences of uppercase followed by lowercase (e.g., "XMLParser" -> "XML_Parser")
25
+ .replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
26
+ // Insert underscore before single uppercase preceded by lowercase (e.g., "userID" -> "user_ID")
27
+ .replace(/([a-z\d])([A-Z])/g, "$1_$2")
28
+ .toLowerCase();
29
+ }
30
+
31
+ /**
32
+ * Check if value is a plain object (not Date, Map, Set, RegExp, etc.)
33
+ */
34
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
35
+ if (value === null || typeof value !== "object") {
36
+ return false;
37
+ }
38
+ const proto = Object.getPrototypeOf(value);
39
+ return proto === Object.prototype || proto === null;
40
+ }
41
+
42
+ /**
43
+ * Convert object keys to snake_case (recursively handles nested objects and arrays)
44
+ * Preserves Date, Map, Set, RegExp, and other built-in objects unchanged
45
+ */
46
+ export function toSnakeCase<T extends Record<string, unknown>>(obj: T): T {
47
+ const result: Record<string, unknown> = {};
48
+
49
+ for (const [key, value] of Object.entries(obj)) {
50
+ const snakeKey = camelToSnake(key);
51
+
52
+ if (Array.isArray(value)) {
53
+ // Recursively convert plain objects inside arrays
54
+ result[snakeKey] = value.map((item) =>
55
+ isPlainObject(item) ? toSnakeCase(item) : item
56
+ );
57
+ } else if (isPlainObject(value)) {
58
+ result[snakeKey] = toSnakeCase(value);
59
+ } else {
60
+ // Preserve Date, Map, Set, RegExp, and other built-in objects unchanged
61
+ result[snakeKey] = value;
62
+ }
63
+ }
64
+
65
+ return result as T;
66
+ }
67
+
68
+ /**
69
+ * Deep merge two objects
70
+ */
71
+ export function mergeDeepRight<T extends Record<string, unknown>>(
72
+ target: T,
73
+ source: Partial<T>
74
+ ): T {
75
+ const output = { ...target };
76
+
77
+ for (const key in source) {
78
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
79
+ const sourceValue = source[key];
80
+ const targetValue = output[key];
81
+
82
+ if (
83
+ sourceValue !== null &&
84
+ typeof sourceValue === "object" &&
85
+ !Array.isArray(sourceValue) &&
86
+ targetValue !== null &&
87
+ typeof targetValue === "object" &&
88
+ !Array.isArray(targetValue)
89
+ ) {
90
+ output[key] = mergeDeepRight(
91
+ targetValue as Record<string, unknown>,
92
+ sourceValue as Record<string, unknown>
93
+ ) as T[Extract<keyof T, string>];
94
+ } else if (sourceValue !== undefined) {
95
+ output[key] = sourceValue as T[Extract<keyof T, string>];
96
+ }
97
+ }
98
+ }
99
+
100
+ return output;
101
+ }
102
+
103
+ /**
104
+ * Get action descriptor for logging
105
+ */
106
+ export function getActionDescriptor(
107
+ type: string,
108
+ properties?: Record<string, unknown> | null
109
+ ): string {
110
+ if (type === "track" && properties?.event) {
111
+ return `track:${properties.event}`;
112
+ }
113
+ if (type === "screen" && properties?.name) {
114
+ return `screen:${properties.name}`;
115
+ }
116
+ return type;
117
+ }
118
+
119
+ /**
120
+ * Check if error is a network error
121
+ */
122
+ export function isNetworkError(error: unknown): boolean {
123
+ if (!error) return false;
124
+
125
+ const message = error instanceof Error ? error.message : String(error);
126
+ const networkErrorMessages = [
127
+ "Network request failed",
128
+ "Failed to fetch",
129
+ "Network Error",
130
+ "timeout",
131
+ "ETIMEDOUT",
132
+ "ECONNREFUSED",
133
+ "ENOTFOUND",
134
+ ];
135
+
136
+ return networkErrorMessages.some((msg) =>
137
+ message.toLowerCase().includes(msg.toLowerCase())
138
+ );
139
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./address";
2
+ export * from "./hash";
3
+ export * from "./timestamp";
4
+ export * from "./helpers";
5
+ export * from "./trafficSource";
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Get current time in ISO format
3
+ */
4
+ export function getCurrentTimeFormatted(): string {
5
+ return new Date().toISOString();
6
+ }
7
+
8
+ /**
9
+ * Format date to YYYY-MM-DD HH:mm format for hashing
10
+ */
11
+ export function toDateHourMinute(date: Date): string {
12
+ const year = date.getFullYear();
13
+ const month = String(date.getMonth() + 1).padStart(2, "0");
14
+ const day = String(date.getDate()).padStart(2, "0");
15
+ const hours = String(date.getHours()).padStart(2, "0");
16
+ const minutes = String(date.getMinutes()).padStart(2, "0");
17
+ return `${year}-${month}-${day} ${hours}:${minutes}`;
18
+ }
19
+
20
+ /**
21
+ * Convert milliseconds to seconds
22
+ */
23
+ export function millisecondsToSecond(ms: number): number {
24
+ return Math.floor(ms / 1000);
25
+ }