/** * Utility functions for extracting profile properties from Privy user objects. */ import { PrivyProfileProperties, PrivyUser, PrivyWalletInfo } from "./types"; import { IFormoAnalytics } from "../types/base"; import { IFormoEventProperties } from "../types/events"; /** * Extract profile properties and wallet addresses from a Privy user object. * * Parses the Privy user's linked accounts into a flat properties object * (email, social accounts, etc.) and extracts all linked wallet addresses. * * For most apps prefer the {@link identifyPrivyUser} one-liner, which builds on * this function and also forwards per-wallet metadata and handles event * attribution. Use `parsePrivyProperties` directly only for advanced/custom * flows. * * @param user - The Privy user object from `usePrivy()` * @returns An object with `properties` and `wallets` * * @example * ```ts * import { parsePrivyProperties } from '@formo/analytics'; * * const { user } = usePrivy(); * if (user) { * const { properties, wallets } = parsePrivyProperties(user); * * for (const wallet of wallets) { * formo.identify({ address: wallet.address, userId: user.id }, properties); * } * } * ``` */ export declare function parsePrivyProperties(user: PrivyUser): { properties: PrivyProfileProperties; wallets: PrivyWalletInfo[]; }; /** * Options for {@link identifyPrivyUser}. */ export interface IdentifyPrivyUserOptions { /** * Optional override for the wallet that should own event attribution - the * one promoted to the SDK's current address/user, while every other linked * wallet is recorded only for clustering. * * You usually don't need this. When omitted, the helper first uses the wallet * the SDK already treats as active (a prior wagmi/EIP-1193 connect), then * Privy's own surfaced wallet (`user.wallet`), then a best-effort guess * (embedded wallets deprioritized, so the last external wallet). Pass it only * when you want to pin attribution to a specific wallet - e.g. the currently * connected wallet from `useWallets()[0]?.address`, which reflects the live * active wallet more precisely than `user.wallet`. * * Matched strictly: if it doesn't correspond to one of the user's linked * wallets, no wallet is promoted and the SDK's current wallet is left as-is * (so a connected wallet that isn't linked in Privy is preserved). */ activeAddress?: string; /** * Extra properties merged into every identify call, on top of the profile * properties parsed from the Privy user (email, socials, DID, …) and the * per-wallet metadata (`wallet_client`, `chain_type`, `is_embedded`). * * Identify events are deduped per `(wallet, user, properties)` within a * session, so changing these properties re-emits with the updated profile * rather than being swallowed. The flip side: a value that changes on every * call (a timestamp, a random id) makes every identify a new event. Pass * stable identity metadata here and put volatile values on `track()` events. */ properties?: IFormoEventProperties; } /** * Identify every wallet linked to a Privy user under that user's Privy DID. * * This is the one-liner replacement for hand-rolling a loop over * {@link parsePrivyProperties}. For each linked wallet it calls * `analytics.identify({ address, userId: user.id }, …)` with the shared * profile properties plus that wallet's `wallet_client`, `chain_type`, and * `is_embedded` metadata. Because every wallet is tagged with the same Privy * `userId`, Formo can cluster them server-side into a single user. * * Attribution: only the active wallet (see * {@link IdentifyPrivyUserOptions.activeAddress}) promotes the SDK's current * address/user; every other linked wallet is recorded purely for clustering and * does not repoint attribution. Because the clustering identifies don't touch * active state, a connected wallet that isn't linked in Privy is left untouched * rather than overwritten. This does not change the public `identify()` API. * * Before emitting, it reconciles the SDK's chain id with the active wallet's * chain namespace (clearing a stale EVM chain id when a Solana wallet becomes * active, and vice versa), so identifies aren't dropped by an `excludeChains` * gate and later events aren't paired with the wrong chain. This happens here, * so the direct helper and the `formo.identify(user)` form * behave identically. * * Returns the active linked wallet's `{ address, chainType }` (the one now * owning attribution), or `undefined` when no linked wallet matched the * requested active address (or the user had no wallets). * * All linked wallet addresses used here come from `user.linkedAccounts`, which * is fully available on the frontend from Privy's `usePrivy()` hook. * * Note: `identify()` is keyed on a wallet address, so a Privy user with no * linked wallet is a no-op (nothing is emitted). Attaching a user identity that * has no wallet is out of scope for this address-keyed helper. * * @param analytics - The Formo analytics instance (e.g. from `useFormo()`) * @param user - The Privy user object from `usePrivy()` * @param options - See {@link IdentifyPrivyUserOptions} * * @example * ```ts * import { identifyPrivyUser } from '@formo/analytics'; * * const { user } = usePrivy(); * const { wallets } = useWallets(); * if (user) { * // activeAddress is optional - omit it if the SDK already tracks the * // connected wallet via a wagmi/EIP-1193 connect. * await identifyPrivyUser(formo, user, { * activeAddress: wallets[0]?.address, * }); * } * ``` */ export declare function identifyPrivyUser(analytics: IFormoAnalytics, user: PrivyUser, options?: IdentifyPrivyUserOptions): Promise<{ address: string; chainType?: string; } | undefined>; //# sourceMappingURL=utils.d.ts.map