@formo/analytics 1.33.1 → 1.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/cjs/src/FormoAnalytics.d.ts +65 -19
- package/dist/cjs/src/FormoAnalytics.js +188 -94
- package/dist/cjs/src/event/EventFactory.d.ts +1 -1
- package/dist/cjs/src/event/EventFactory.js +32 -16
- package/dist/cjs/src/event/sanitize.d.ts +13 -0
- package/dist/cjs/src/event/sanitize.js +94 -0
- package/dist/cjs/src/privy/index.d.ts +8 -2
- package/dist/cjs/src/privy/index.js +8 -2
- package/dist/cjs/src/privy/types.d.ts +25 -2
- package/dist/cjs/src/privy/utils.d.ts +100 -0
- package/dist/cjs/src/privy/utils.js +375 -16
- package/dist/cjs/src/session/index.d.ts +73 -6
- package/dist/cjs/src/session/index.js +309 -12
- package/dist/cjs/src/solana/SolanaManager.d.ts +1 -1
- package/dist/cjs/src/solana/SolanaManager.js +1 -1
- package/dist/cjs/src/solana/storeTypes.d.ts +1 -1
- package/dist/cjs/src/solana/storeTypes.js +1 -1
- package/dist/cjs/src/solana/types.d.ts +2 -2
- package/dist/cjs/src/types/base.d.ts +17 -1
- package/dist/cjs/src/version.d.ts +1 -1
- package/dist/cjs/src/version.js +1 -1
- package/dist/esm/src/FormoAnalytics.d.ts +65 -19
- package/dist/esm/src/FormoAnalytics.js +188 -94
- package/dist/esm/src/event/EventFactory.d.ts +1 -1
- package/dist/esm/src/event/EventFactory.js +32 -16
- package/dist/esm/src/event/sanitize.d.ts +13 -0
- package/dist/esm/src/event/sanitize.js +88 -0
- package/dist/esm/src/privy/index.d.ts +8 -2
- package/dist/esm/src/privy/index.js +8 -2
- package/dist/esm/src/privy/types.d.ts +25 -2
- package/dist/esm/src/privy/utils.d.ts +100 -0
- package/dist/esm/src/privy/utils.js +374 -16
- package/dist/esm/src/session/index.d.ts +73 -6
- package/dist/esm/src/session/index.js +309 -12
- package/dist/esm/src/solana/SolanaManager.d.ts +1 -1
- package/dist/esm/src/solana/SolanaManager.js +1 -1
- package/dist/esm/src/solana/storeTypes.d.ts +1 -1
- package/dist/esm/src/solana/storeTypes.js +1 -1
- package/dist/esm/src/solana/types.d.ts +2 -2
- package/dist/esm/src/types/base.d.ts +17 -1
- package/dist/esm/src/version.d.ts +1 -1
- package/dist/esm/src/version.js +1 -1
- package/dist/index.umd.min.js +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -29,6 +29,9 @@ You can install Formo on:
|
|
|
29
29
|
|
|
30
30
|
Visit Formo's [Developer Docs](https://docs.formo.so) for detailed guides on local testing, debugging, and consent management.
|
|
31
31
|
|
|
32
|
+
Using [Privy](./docs/PRIVY_INTEGRATION.md)? `identify(user)`
|
|
33
|
+
clusters all of a Privy user's linked wallets under a single identity.
|
|
34
|
+
|
|
32
35
|
## Methodology
|
|
33
36
|
|
|
34
37
|
Learn how Formo handles [onchain attribution](https://docs.formo.so/data/attribution) and [data collection](https://docs.formo.so/data/what-we-collect).
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EIP6963ProviderDetail } from "mipd";
|
|
2
2
|
import { Address, ChainID, Config, EIP1193Provider, IFormoAnalytics, IFormoEventContext, IFormoEventProperties, Options, SignatureStatus, TransactionStatus } from "./types";
|
|
3
3
|
import { SolanaManager } from "./solana/SolanaManager";
|
|
4
|
+
import type { PrivyUser } from "./privy";
|
|
4
5
|
export declare class FormoAnalytics implements IFormoAnalytics {
|
|
5
6
|
readonly writeKey: string;
|
|
6
7
|
options: Options;
|
|
@@ -189,23 +190,50 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
189
190
|
* // Basic identify
|
|
190
191
|
* formo.identify({ address: '0x...', userId: 'user123' });
|
|
191
192
|
*
|
|
192
|
-
* //
|
|
193
|
-
*
|
|
193
|
+
* // Privy: pass the usePrivy() user to identify every linked wallet under
|
|
194
|
+
* // the user's DID in one call. Attribution stays on the already-connected
|
|
195
|
+
* // wallet when there is one, else Privy's primary (user.wallet); pass
|
|
196
|
+
* // `activeAddress` to pin a specific wallet.
|
|
194
197
|
* const { user } = usePrivy();
|
|
195
|
-
* if (user)
|
|
196
|
-
* const { properties, wallets } = parsePrivyProperties(user);
|
|
197
|
-
* for (const wallet of wallets) {
|
|
198
|
-
* formo.identify({ address: wallet.address, userId: user.id }, properties);
|
|
199
|
-
* }
|
|
200
|
-
* }
|
|
198
|
+
* if (user) formo.identify(user);
|
|
201
199
|
* ```
|
|
202
200
|
*/
|
|
201
|
+
identify(user: PrivyUser, options?: {
|
|
202
|
+
activeAddress?: string;
|
|
203
|
+
properties?: IFormoEventProperties;
|
|
204
|
+
}): Promise<void>;
|
|
203
205
|
identify(params?: {
|
|
204
206
|
address: Address;
|
|
205
207
|
providerName?: string;
|
|
206
208
|
userId?: string;
|
|
207
209
|
rdns?: string;
|
|
208
210
|
}, properties?: IFormoEventProperties, context?: IFormoEventContext, callback?: (...args: unknown[]) => void): Promise<void>;
|
|
211
|
+
/**
|
|
212
|
+
* Reconcile currentChainId with a newly-activated Privy wallet's chain
|
|
213
|
+
* namespace. identify() sets currentAddress but never touches the chain id
|
|
214
|
+
* (that comes from connect()/chain()/wagmi), so activating e.g. a Solana
|
|
215
|
+
* wallet while an EVM chain id is current would leave the address paired with
|
|
216
|
+
* a mismatched chain in events, excludeChains, and the active-wallet cookie.
|
|
217
|
+
*
|
|
218
|
+
* We can't infer the wallet's specific chain id from Privy's chainType, so on
|
|
219
|
+
* a namespace mismatch we clear the chain id rather than assert a wrong one; a
|
|
220
|
+
* real wallet connect will set the correct chain. Same-namespace activations
|
|
221
|
+
* (and wallets whose namespace can't be determined) leave the chain id alone.
|
|
222
|
+
*
|
|
223
|
+
* Privy doesn't always supply `chainType`: a `smart_wallet` entry is
|
|
224
|
+
* `{ type, address, smartWalletType }`, and `cross_app` wallets are bare
|
|
225
|
+
* `{ address }`. A `0x`-prefixed 20-byte address is unambiguously EVM though,
|
|
226
|
+
* so fall back to the address shape - otherwise activating an EVM smart
|
|
227
|
+
* wallet while a Solana chain id is current would leave the address paired
|
|
228
|
+
* with the wrong chain, and an `excludeChains` gate could drop the identify
|
|
229
|
+
* after it was already dedup-marked.
|
|
230
|
+
*
|
|
231
|
+
* @internal Not part of the public IFormoAnalytics contract - invoked by
|
|
232
|
+
* `identifyPrivyUser` (via a structural cast) before it emits, so both the
|
|
233
|
+
* `identify(user,{privy:true})` and direct `identifyPrivyUser()` paths
|
|
234
|
+
* reconcile the chain.
|
|
235
|
+
*/
|
|
236
|
+
syncPrivyActiveChain(chainType?: string, address?: string): void;
|
|
209
237
|
/**
|
|
210
238
|
* Emits a detect wallet event with current wallet provider info.
|
|
211
239
|
* @param {string} params.providerName
|
|
@@ -286,20 +314,38 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
286
314
|
* Visitor-level tracking suppression.
|
|
287
315
|
*
|
|
288
316
|
* Returns true when the SDK must not persist any identity/session/chain
|
|
289
|
-
* state or send any events for this visitor
|
|
317
|
+
* state or send any events for this visitor - i.e. an explicit opt-out or a
|
|
290
318
|
* jurisdiction/timezone exclusion. Public entry points that write state
|
|
291
319
|
* before reaching the `shouldTrack()` event gate (identify/connect/detect)
|
|
292
320
|
* check this first so suppressed visitors leave no cookies or session state.
|
|
293
321
|
* @returns {boolean} True if all tracking and persistence must be suppressed
|
|
322
|
+
* @internal Also read by `identifyPrivyUser` (via a structural cast) so the
|
|
323
|
+
* Privy sync skips chain reconciliation and emission for suppressed visitors.
|
|
324
|
+
*/
|
|
325
|
+
isTrackingSuppressed(): boolean;
|
|
326
|
+
/**
|
|
327
|
+
* Whether the current chain id is in `tracking.excludeChains`.
|
|
328
|
+
*
|
|
329
|
+
* Split out from `shouldTrack()` so `identify()` can check it *before*
|
|
330
|
+
* mutating identity state. `trackEvent()` drops an excluded event silently
|
|
331
|
+
* and returns void, but `identify()` marks the wallet as identified first, so
|
|
332
|
+
* without this guard an identify on an excluded chain is dedup-marked and
|
|
333
|
+
* then discarded, and the wallet never re-emits for the rest of the session
|
|
334
|
+
* even after switching to an allowed chain. On the Privy path that loses the
|
|
335
|
+
* user's whole cluster at once rather than a single wallet.
|
|
336
|
+
*
|
|
337
|
+
* Mirrors the chain rule in `shouldTrack()`: only applies when `tracking` is
|
|
338
|
+
* an options object with `excludeChains` set, and only once a chain id is
|
|
339
|
+
* known.
|
|
294
340
|
*/
|
|
295
|
-
private
|
|
341
|
+
private isCurrentChainExcluded;
|
|
296
342
|
/**
|
|
297
|
-
* Whether the current environment is excluded from tracking
|
|
343
|
+
* Whether the current environment is excluded from tracking - the visitor's
|
|
298
344
|
* timezone, the current hostname, or the current pathname matches a
|
|
299
345
|
* configured exclusion.
|
|
300
346
|
*
|
|
301
347
|
* Timezone is visitor/session-level (stable for the session); host/path are
|
|
302
|
-
* current-page-level and transient
|
|
348
|
+
* current-page-level and transient - if a SPA navigates to an allowed path,
|
|
303
349
|
* tracking resumes for future actions. Used as the "do not write identity or
|
|
304
350
|
* send events" gate at every entry point that would persist state before the
|
|
305
351
|
* `shouldTrack()` event gate.
|
|
@@ -308,19 +354,19 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
308
354
|
private isCurrentEnvironmentExcluded;
|
|
309
355
|
/**
|
|
310
356
|
* Whether the current hostname matches a configured `tracking.excludeHosts`
|
|
311
|
-
* entry (exact match). Current-page-level
|
|
357
|
+
* entry (exact match). Current-page-level - see isCurrentEnvironmentExcluded.
|
|
312
358
|
* @returns {boolean} True if the current hostname is excluded
|
|
313
359
|
*/
|
|
314
360
|
private isHostExcluded;
|
|
315
361
|
/**
|
|
316
362
|
* Whether the current pathname matches a configured `tracking.excludePaths`
|
|
317
|
-
* entry (exact match). Current-page-level
|
|
363
|
+
* entry (exact match). Current-page-level - see isCurrentEnvironmentExcluded.
|
|
318
364
|
* @returns {boolean} True if the current pathname is excluded
|
|
319
365
|
*/
|
|
320
366
|
private isPathExcluded;
|
|
321
367
|
/**
|
|
322
|
-
* Whether the current call is in a visitor-level suppression state
|
|
323
|
-
* or excluded timezone
|
|
368
|
+
* Whether the current call is in a visitor-level suppression state - opt-out
|
|
369
|
+
* or excluded timezone - for which any persisted identity cookie should be
|
|
324
370
|
* actively purged (not merely skipped). Host/path exclusions are
|
|
325
371
|
* deliberately excluded here: they are transient current-page states, so a
|
|
326
372
|
* cookie legitimately written on an allowed page must survive a visit to an
|
|
@@ -331,7 +377,7 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
331
377
|
/**
|
|
332
378
|
* Whether the visitor's browser-resolved timezone matches a configured
|
|
333
379
|
* `tracking.excludeTimezones` entry (case-insensitive). Client-side and
|
|
334
|
-
* best-effort
|
|
380
|
+
* best-effort - see TrackingOptions.excludeTimezones.
|
|
335
381
|
* @returns {boolean} True if the current timezone is excluded
|
|
336
382
|
*/
|
|
337
383
|
private isTimezoneExcluded;
|
|
@@ -445,7 +491,7 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
445
491
|
* WITHOUT emitting an event.
|
|
446
492
|
*
|
|
447
493
|
* Integrations (e.g. the wagmi handler) must call this on every
|
|
448
|
-
* connect / chain-change / disconnect
|
|
494
|
+
* connect / chain-change / disconnect - even when the corresponding
|
|
449
495
|
* autocapture event is disabled. Otherwise `currentChainId` stays
|
|
450
496
|
* stale/undefined and `shouldTrack()`'s `tracking.excludeChains`
|
|
451
497
|
* check (which keys off `currentChainId`, not the event payload) can
|
|
@@ -467,7 +513,7 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
467
513
|
/**
|
|
468
514
|
* Persist (or clear) the current wallet snapshot in a cookie so that the
|
|
469
515
|
* SDK can repopulate `currentAddress`/`currentChainId` at init on the next
|
|
470
|
-
* page load
|
|
516
|
+
* page load - closing the gap between page-show and wagmi/EIP-1193
|
|
471
517
|
* reconnection during which track()/page() events would otherwise ship
|
|
472
518
|
* with an empty address.
|
|
473
519
|
*/
|