@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.
- package/README.md +302 -0
- package/lib/commonjs/FormoAnalytics.js +526 -0
- package/lib/commonjs/FormoAnalytics.js.map +1 -0
- package/lib/commonjs/FormoAnalyticsProvider.js +265 -0
- package/lib/commonjs/FormoAnalyticsProvider.js.map +1 -0
- package/lib/commonjs/constants/config.js +69 -0
- package/lib/commonjs/constants/config.js.map +1 -0
- package/lib/commonjs/constants/events.js +30 -0
- package/lib/commonjs/constants/events.js.map +1 -0
- package/lib/commonjs/constants/index.js +39 -0
- package/lib/commonjs/constants/index.js.map +1 -0
- package/lib/commonjs/constants/storage.js +23 -0
- package/lib/commonjs/constants/storage.js.map +1 -0
- package/lib/commonjs/index.js +65 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/lib/consent/index.js +56 -0
- package/lib/commonjs/lib/consent/index.js.map +1 -0
- package/lib/commonjs/lib/event/EventFactory.js +493 -0
- package/lib/commonjs/lib/event/EventFactory.js.map +1 -0
- package/lib/commonjs/lib/event/EventManager.js +46 -0
- package/lib/commonjs/lib/event/EventManager.js.map +1 -0
- package/lib/commonjs/lib/event/EventQueue.js +290 -0
- package/lib/commonjs/lib/event/EventQueue.js.map +1 -0
- package/lib/commonjs/lib/event/index.js +50 -0
- package/lib/commonjs/lib/event/index.js.map +1 -0
- package/lib/commonjs/lib/event/types.js +6 -0
- package/lib/commonjs/lib/event/types.js.map +1 -0
- package/lib/commonjs/lib/lifecycle/index.js +196 -0
- package/lib/commonjs/lib/lifecycle/index.js.map +1 -0
- package/lib/commonjs/lib/logger/index.js +48 -0
- package/lib/commonjs/lib/logger/index.js.map +1 -0
- package/lib/commonjs/lib/session/index.js +109 -0
- package/lib/commonjs/lib/session/index.js.map +1 -0
- package/lib/commonjs/lib/storage/AsyncStorageAdapter.js +164 -0
- package/lib/commonjs/lib/storage/AsyncStorageAdapter.js.map +1 -0
- package/lib/commonjs/lib/storage/MemoryStorage.js +41 -0
- package/lib/commonjs/lib/storage/MemoryStorage.js.map +1 -0
- package/lib/commonjs/lib/storage/StorageBlueprint.js +24 -0
- package/lib/commonjs/lib/storage/StorageBlueprint.js.map +1 -0
- package/lib/commonjs/lib/storage/StorageManager.js +126 -0
- package/lib/commonjs/lib/storage/StorageManager.js.map +1 -0
- package/lib/commonjs/lib/storage/index.js +49 -0
- package/lib/commonjs/lib/storage/index.js.map +1 -0
- package/lib/commonjs/lib/storage/types.js +2 -0
- package/lib/commonjs/lib/storage/types.js.map +1 -0
- package/lib/commonjs/lib/wagmi/WagmiEventHandler.js +445 -0
- package/lib/commonjs/lib/wagmi/WagmiEventHandler.js.map +1 -0
- package/lib/commonjs/lib/wagmi/index.js +28 -0
- package/lib/commonjs/lib/wagmi/index.js.map +1 -0
- package/lib/commonjs/lib/wagmi/types.js +2 -0
- package/lib/commonjs/lib/wagmi/types.js.map +1 -0
- package/lib/commonjs/types/base.js +6 -0
- package/lib/commonjs/types/base.js.map +1 -0
- package/lib/commonjs/types/events.js +22 -0
- package/lib/commonjs/types/events.js.map +1 -0
- package/lib/commonjs/types/index.js +28 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/utils/address.js +82 -0
- package/lib/commonjs/utils/address.js.map +1 -0
- package/lib/commonjs/utils/hash.js +30 -0
- package/lib/commonjs/utils/hash.js.map +1 -0
- package/lib/commonjs/utils/helpers.js +116 -0
- package/lib/commonjs/utils/helpers.js.map +1 -0
- package/lib/commonjs/utils/index.js +61 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/commonjs/utils/timestamp.js +34 -0
- package/lib/commonjs/utils/timestamp.js.map +1 -0
- package/lib/commonjs/utils/trafficSource.js +147 -0
- package/lib/commonjs/utils/trafficSource.js.map +1 -0
- package/lib/commonjs/version.js +10 -0
- package/lib/commonjs/version.js.map +1 -0
- package/lib/module/FormoAnalytics.js +519 -0
- package/lib/module/FormoAnalytics.js.map +1 -0
- package/lib/module/FormoAnalyticsProvider.js +256 -0
- package/lib/module/FormoAnalyticsProvider.js.map +1 -0
- package/lib/module/constants/config.js +62 -0
- package/lib/module/constants/config.js.map +1 -0
- package/lib/module/constants/events.js +24 -0
- package/lib/module/constants/events.js.map +1 -0
- package/lib/module/constants/index.js +4 -0
- package/lib/module/constants/index.js.map +1 -0
- package/lib/module/constants/storage.js +17 -0
- package/lib/module/constants/storage.js.map +1 -0
- package/lib/module/index.js +51 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/lib/consent/index.js +49 -0
- package/lib/module/lib/consent/index.js.map +1 -0
- package/lib/module/lib/event/EventFactory.js +488 -0
- package/lib/module/lib/event/EventFactory.js.map +1 -0
- package/lib/module/lib/event/EventManager.js +41 -0
- package/lib/module/lib/event/EventManager.js.map +1 -0
- package/lib/module/lib/event/EventQueue.js +283 -0
- package/lib/module/lib/event/EventQueue.js.map +1 -0
- package/lib/module/lib/event/index.js +5 -0
- package/lib/module/lib/event/index.js.map +1 -0
- package/lib/module/lib/event/types.js +2 -0
- package/lib/module/lib/event/types.js.map +1 -0
- package/lib/module/lib/lifecycle/index.js +190 -0
- package/lib/module/lib/lifecycle/index.js.map +1 -0
- package/lib/module/lib/logger/index.js +42 -0
- package/lib/module/lib/logger/index.js.map +1 -0
- package/lib/module/lib/session/index.js +92 -0
- package/lib/module/lib/session/index.js.map +1 -0
- package/lib/module/lib/storage/AsyncStorageAdapter.js +158 -0
- package/lib/module/lib/storage/AsyncStorageAdapter.js.map +1 -0
- package/lib/module/lib/storage/MemoryStorage.js +35 -0
- package/lib/module/lib/storage/MemoryStorage.js.map +1 -0
- package/lib/module/lib/storage/StorageBlueprint.js +18 -0
- package/lib/module/lib/storage/StorageBlueprint.js.map +1 -0
- package/lib/module/lib/storage/StorageManager.js +115 -0
- package/lib/module/lib/storage/StorageManager.js.map +1 -0
- package/lib/module/lib/storage/index.js +5 -0
- package/lib/module/lib/storage/index.js.map +1 -0
- package/lib/module/lib/storage/types.js +2 -0
- package/lib/module/lib/storage/types.js.map +1 -0
- package/lib/module/lib/wagmi/WagmiEventHandler.js +439 -0
- package/lib/module/lib/wagmi/WagmiEventHandler.js.map +1 -0
- package/lib/module/lib/wagmi/index.js +3 -0
- package/lib/module/lib/wagmi/index.js.map +1 -0
- package/lib/module/lib/wagmi/types.js +2 -0
- package/lib/module/lib/wagmi/types.js.map +1 -0
- package/lib/module/types/base.js +2 -0
- package/lib/module/types/base.js.map +1 -0
- package/lib/module/types/events.js +17 -0
- package/lib/module/types/events.js.map +1 -0
- package/lib/module/types/index.js +3 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/utils/address.js +74 -0
- package/lib/module/utils/address.js.map +1 -0
- package/lib/module/utils/hash.js +24 -0
- package/lib/module/utils/hash.js.map +1 -0
- package/lib/module/utils/helpers.js +105 -0
- package/lib/module/utils/helpers.js.map +1 -0
- package/lib/module/utils/index.js +6 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/module/utils/timestamp.js +26 -0
- package/lib/module/utils/timestamp.js.map +1 -0
- package/lib/module/utils/trafficSource.js +137 -0
- package/lib/module/utils/trafficSource.js.map +1 -0
- package/lib/module/version.js +4 -0
- package/lib/module/version.js.map +1 -0
- package/lib/typescript/FormoAnalytics.d.ts +163 -0
- package/lib/typescript/FormoAnalytics.d.ts.map +1 -0
- package/lib/typescript/FormoAnalyticsProvider.d.ts +29 -0
- package/lib/typescript/FormoAnalyticsProvider.d.ts.map +1 -0
- package/lib/typescript/constants/config.d.ts +8 -0
- package/lib/typescript/constants/config.d.ts.map +1 -0
- package/lib/typescript/constants/events.d.ts +23 -0
- package/lib/typescript/constants/events.d.ts.map +1 -0
- package/lib/typescript/constants/index.d.ts +4 -0
- package/lib/typescript/constants/index.d.ts.map +1 -0
- package/lib/typescript/constants/storage.d.ts +10 -0
- package/lib/typescript/constants/storage.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +44 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/lib/consent/index.d.ts +13 -0
- package/lib/typescript/lib/consent/index.d.ts.map +1 -0
- package/lib/typescript/lib/event/EventFactory.d.ts +61 -0
- package/lib/typescript/lib/event/EventFactory.d.ts.map +1 -0
- package/lib/typescript/lib/event/EventManager.d.ts +17 -0
- package/lib/typescript/lib/event/EventManager.d.ts.map +1 -0
- package/lib/typescript/lib/event/EventQueue.d.ts +74 -0
- package/lib/typescript/lib/event/EventQueue.d.ts.map +1 -0
- package/lib/typescript/lib/event/index.d.ts +5 -0
- package/lib/typescript/lib/event/index.d.ts.map +1 -0
- package/lib/typescript/lib/event/types.d.ts +23 -0
- package/lib/typescript/lib/event/types.d.ts.map +1 -0
- package/lib/typescript/lib/lifecycle/index.d.ts +46 -0
- package/lib/typescript/lib/lifecycle/index.d.ts.map +1 -0
- package/lib/typescript/lib/logger/index.d.ts +19 -0
- package/lib/typescript/lib/logger/index.d.ts.map +1 -0
- package/lib/typescript/lib/session/index.d.ts +41 -0
- package/lib/typescript/lib/session/index.d.ts.map +1 -0
- package/lib/typescript/lib/storage/AsyncStorageAdapter.d.ts +48 -0
- package/lib/typescript/lib/storage/AsyncStorageAdapter.d.ts.map +1 -0
- package/lib/typescript/lib/storage/MemoryStorage.d.ts +18 -0
- package/lib/typescript/lib/storage/MemoryStorage.d.ts.map +1 -0
- package/lib/typescript/lib/storage/StorageBlueprint.d.ts +21 -0
- package/lib/typescript/lib/storage/StorageBlueprint.d.ts.map +1 -0
- package/lib/typescript/lib/storage/StorageManager.d.ts +45 -0
- package/lib/typescript/lib/storage/StorageManager.d.ts.map +1 -0
- package/lib/typescript/lib/storage/index.d.ts +5 -0
- package/lib/typescript/lib/storage/index.d.ts.map +1 -0
- package/lib/typescript/lib/storage/types.d.ts +22 -0
- package/lib/typescript/lib/storage/types.d.ts.map +1 -0
- package/lib/typescript/lib/wagmi/WagmiEventHandler.d.ts +104 -0
- package/lib/typescript/lib/wagmi/WagmiEventHandler.d.ts.map +1 -0
- package/lib/typescript/lib/wagmi/index.d.ts +3 -0
- package/lib/typescript/lib/wagmi/index.d.ts.map +1 -0
- package/lib/typescript/lib/wagmi/types.d.ts +54 -0
- package/lib/typescript/lib/wagmi/types.d.ts.map +1 -0
- package/lib/typescript/types/base.d.ts +219 -0
- package/lib/typescript/types/base.d.ts.map +1 -0
- package/lib/typescript/types/events.d.ts +111 -0
- package/lib/typescript/types/events.d.ts.map +1 -0
- package/lib/typescript/types/index.d.ts +3 -0
- package/lib/typescript/types/index.d.ts.map +1 -0
- package/lib/typescript/utils/address.d.ts +25 -0
- package/lib/typescript/utils/address.d.ts.map +1 -0
- package/lib/typescript/utils/hash.d.ts +10 -0
- package/lib/typescript/utils/hash.d.ts.map +1 -0
- package/lib/typescript/utils/helpers.d.ts +26 -0
- package/lib/typescript/utils/helpers.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +6 -0
- package/lib/typescript/utils/index.d.ts.map +1 -0
- package/lib/typescript/utils/timestamp.d.ts +13 -0
- package/lib/typescript/utils/timestamp.d.ts.map +1 -0
- package/lib/typescript/utils/trafficSource.d.ts +30 -0
- package/lib/typescript/utils/trafficSource.d.ts.map +1 -0
- package/lib/typescript/version.d.ts +2 -0
- package/lib/typescript/version.d.ts.map +1 -0
- package/package.json +143 -0
- package/src/FormoAnalytics.ts +685 -0
- package/src/FormoAnalyticsProvider.tsx +296 -0
- package/src/constants/config.ts +62 -0
- package/src/constants/events.ts +26 -0
- package/src/constants/index.ts +3 -0
- package/src/constants/storage.ts +16 -0
- package/src/index.ts +55 -0
- package/src/lib/consent/index.ts +52 -0
- package/src/lib/event/EventFactory.ts +682 -0
- package/src/lib/event/EventManager.ts +50 -0
- package/src/lib/event/EventQueue.ts +371 -0
- package/src/lib/event/index.ts +4 -0
- package/src/lib/event/types.ts +107 -0
- package/src/lib/lifecycle/index.ts +215 -0
- package/src/lib/logger/index.ts +56 -0
- package/src/lib/session/index.ts +103 -0
- package/src/lib/storage/AsyncStorageAdapter.ts +173 -0
- package/src/lib/storage/MemoryStorage.ts +43 -0
- package/src/lib/storage/StorageBlueprint.ts +30 -0
- package/src/lib/storage/StorageManager.ts +121 -0
- package/src/lib/storage/index.ts +4 -0
- package/src/lib/storage/types.ts +23 -0
- package/src/lib/wagmi/WagmiEventHandler.ts +574 -0
- package/src/lib/wagmi/index.ts +2 -0
- package/src/lib/wagmi/types.ts +71 -0
- package/src/types/base.ts +287 -0
- package/src/types/events.ts +140 -0
- package/src/types/index.ts +2 -0
- package/src/utils/address.ts +84 -0
- package/src/utils/hash.ts +23 -0
- package/src/utils/helpers.ts +139 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/timestamp.ts +25 -0
- package/src/utils/trafficSource.ts +153 -0
- 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,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,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
|
+
}
|