import {z} from 'zod' export type AnalyticsEvent = {event_id: string, session_id: string, sequence: number, type: string, timestamp: string, widget_version: string, proxy_origin: string, payload: {[key: string]: unknown}, modal: 'deposit', session_properties: {enabled_funding_methods: Array<'wallet' | 'transfer' | 'fiat_onramp' | 'exchange_connect' | 'asset_migration'>, wallet_integration: 'modal_connected' | 'host_supplied' | 'none', fiat_methods: {source: 'backend_resolved'} | {source: 'configured', identifiers: Array}, asset_migration_providers: Array, initial_asset_migration: string | null, gasless_wallet_flow_enabled: boolean, presentation: 'inline' | 'overlay', overlay_close_enabled: boolean, target_chain?: string | undefined, target_token?: string | undefined, prefills: {source_chain: boolean, source_token: boolean, amount: boolean, initial_asset_migration: boolean}}, funding_method: 'wallet' | 'transfer' | 'fiat_onramp' | 'exchange_connect' | 'asset_migration' | 'null' | null} | {event_id: string, session_id: string, sequence: number, type: string, timestamp: string, widget_version: string, proxy_origin: string, payload: {[key: string]: unknown}, modal: 'withdraw', session_properties: {presentation: 'inline' | 'overlay', overlay_close_enabled: boolean, target_chain?: string | undefined, target_token?: string | undefined, prefills: {target_chain: boolean, target_token: boolean, recipient: boolean, amount: boolean}}} | {event_id: string, session_id: string, sequence: number, type: string, timestamp: string, widget_version: string, proxy_origin: string, payload: {[key: string]: unknown}, modal: 'claim', session_properties: {presentation: 'inline' | 'overlay', overlay_close_enabled: boolean, prefills: {transaction_hash: boolean, refund_destination: boolean}}}; export type AnalyticsEventsRequest = {events: Array}; export type CreateApiAnalyticsEventsArgs = {body: AnalyticsEventsRequest}; export type CreateApiAnalyticsEventsOptions = {baseUrl?: string | undefined, analyticsIngestBearer?: string | undefined, fetch?: typeof fetch | undefined}; export const analyticsEventsResponse = z.object({accepted: z.number().int().gte(1).lte(50)}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Record analytics events * * POST /analytics/events */ export const createApiAnalyticsEvents = async (args: CreateApiAnalyticsEventsArgs, options?: CreateApiAnalyticsEventsOptions) => { const {baseUrl = "https://v1.orchestrator.rhinestone.dev/deposit-processor", fetch: fetchFn = fetch, analyticsIngestBearer} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (analyticsIngestBearer !== undefined) headers.set('authorization', `Bearer ${analyticsIngestBearer}`) const url = `${baseUrl.replace(/\/+$/, '')}/analytics/events${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(analyticsEventsResponse, await res.json()) };