{"version":3,"file":"actions-DwDtd2rq.cjs","names":["getClientId","sdkConfigStore","getBackendUrl","withCache","withCache","withCache","getClientId","isV2Context","isV1Context","getClientId","areAddressesEqual","FrakContextManager","getClientId","sdkConfigStore","getBackendUrl","Deferred"],"sources":["../src/actions/displayEmbeddedWallet.ts","../src/actions/displayModal.ts","../src/actions/displaySharingPage.ts","../src/actions/ensureIdentity.ts","../src/actions/getMerchantInformation.ts","../src/actions/getMergeToken.ts","../src/actions/getUserReferralStatus.ts","../src/actions/prepareSso.ts","../src/actions/sendInteraction.ts","../src/actions/referral/processReferral.ts","../src/actions/referral/referralInteraction.ts","../src/actions/referral/setupReferral.ts","../src/actions/trackPurchaseStatus.ts","../src/actions/watchWalletStatus.ts","../src/actions/wrapper/modalBuilder.ts","../src/actions/wrapper/sendTransaction.ts","../src/actions/wrapper/siweAuthenticate.ts"],"sourcesContent":["import type {\n    DisplayEmbeddedWalletParamsType,\n    DisplayEmbeddedWalletResultType,\n    FrakClient,\n} from \"../types\";\n\n/**\n * Function used to display the Frak embedded wallet popup\n * @param client - The current Frak Client\n * @param params - The parameter used to customise the embedded wallet\n * @param placement - Optional placement ID to associate with this display request\n * @returns The embedded wallet display result\n */\nexport async function displayEmbeddedWallet(\n    client: FrakClient,\n    params: DisplayEmbeddedWalletParamsType,\n    placement?: string\n): Promise<DisplayEmbeddedWalletResultType> {\n    return await client.request({\n        method: \"frak_displayEmbeddedWallet\",\n        params: placement\n            ? [params, client.config.metadata, placement]\n            : [params, client.config.metadata],\n    });\n}\n","import type {\n    DisplayModalParamsType,\n    FrakClient,\n    ModalRpcStepsResultType,\n    ModalStepTypes,\n} from \"../types\";\n\n/**\n * Function used to display a modal\n * @param client - The current Frak Client\n * @param args\n * @param args.steps - The different steps of the modal\n * @param args.metadata - The metadata for the modal (customization, etc)\n * @param placement - Optional placement ID to associate with this modal display\n * @returns The result of each modal steps\n *\n * @description This function will display a modal to the user with the provided steps and metadata.\n *\n * @remarks\n * - The UI of the displayed modal can be configured with the `customCss` property in the `customizations.css` field of the top-level config.\n * - The `login` step will be automatically skipped if the user is already logged in. It's safe to include this step in all cases to ensure proper user state.\n * - Steps are automatically reordered in the following sequence:\n *     1. `login` (if needed)\n *     2. All other steps in the order specified\n *     3. `success` (if included, always last)\n *\n * @example\n * Simple sharing modal with steps:\n *  1. Login (Skipped if already logged in)\n *  2. Display a success message with sharing link option\n *\n * ```ts\n * const results = await displayModal(frakConfig, {\n *     steps: {\n *         // Simple login with no SSO, nor customization\n *         login: { allowSso: false },\n *         // Success message\n *         final: {\n *             action: { key: \"reward\" },\n *             // Skip this step, it will be only displayed in the stepper within the modal\n *             autoSkip: true,\n *         },\n *     },\n * });\n *\n * console.log(\"Login step - wallet\", results.login.wallet);\n * ```\n *\n * @example\n * A full modal example, with a few customization options, with the steps:\n *  1. Login (Skipped if already logged in)\n *  2. Authenticate via SIWE\n *  3. Send a transaction\n *  4. Display a success message with sharing link options\n *\n * ```ts\n * const results = await displayModal(frakConfig, {\n *     steps: {\n *         // Login step\n *         login: {\n *             allowSso: true,\n *             ssoMetadata: {\n *                 logoUrl: \"https://my-app.com/logo.png\",\n *                 homepageLink: \"https://my-app.com\",\n *             },\n *         },\n *         // Siwe authentication\n *         siweAuthenticate: {\n *             siwe: {\n *                 domain: \"my-app.com\",\n *                 uri: \"https://my-app.com/\",\n *                 nonce: generateSiweNonce(),\n *                 version: \"1\",\n *             },\n *         },\n *         // Send batched transaction\n *         sendTransaction: {\n *             tx: [\n *                 { to: \"0xdeadbeef\", data: \"0xdeadbeef\" },\n *                 { to: \"0xdeadbeef\", data: \"0xdeadbeef\" },\n *             ],\n *         },\n *         // Success message with sharing options\n *         final: {\n *             action: {\n *                 key: \"sharing\",\n *                 options: {\n *                     popupTitle: \"Share the app\",\n *                     text: \"Discover my super app website\",\n *                     link: \"https://my-app.com\",\n *                 },\n *             },\n *             dismissedMetadata: {\n *                 title: \"Dismiss\",\n *                 description: \"You won't be rewarded for this sharing action\",\n *             },\n *         },\n *     },\n *     metadata: {\n *         // Header of desktop modals\n *         header: {\n *             title: \"My-App\",\n *             icon: \"https://my-app.com/logo.png\",\n *         },\n *         // Context that will be present in every modal steps\n *         context: \"My-app overkill flow\",\n *     },\n * });\n * ```\n */\nexport async function displayModal<\n    T extends ModalStepTypes[] = ModalStepTypes[],\n>(\n    client: FrakClient,\n    { steps, metadata }: DisplayModalParamsType<T>,\n    placement?: string\n): Promise<ModalRpcStepsResultType<T>> {\n    return (await client.request({\n        method: \"frak_displayModal\",\n        params: placement\n            ? [steps, metadata, client.config.metadata, placement]\n            : [steps, metadata, client.config.metadata],\n    })) as ModalRpcStepsResultType<T>;\n}\n","import type {\n    DisplaySharingPageParamsType,\n    DisplaySharingPageResultType,\n    FrakClient,\n} from \"../types\";\n\n/**\n * Function used to display a sharing page\n * @param client - The current Frak Client\n * @param params - The parameters to customize the sharing page (products, link override, metadata)\n * @param placement - Optional placement ID to associate with this display request\n * @returns The result indicating the user's action (shared, copied, or dismissed)\n *\n * @description This function will display a full-page sharing UI to the user,\n * showing product info, estimated rewards, sharing steps, FAQ, and share/copy buttons.\n * The sharing link is generated from the user's wallet context + merchant info.\n *\n * @remarks\n * - The promise resolves on the first user action (share or copy) but the page stays visible\n * - The user can continue to share/copy multiple times after the initial resolution\n * - Dismissing the page after a share/copy action is a no-op (promise already resolved)\n * - If the user dismisses without any action, the promise resolves with `{ action: \"dismissed\" }`\n *\n * @example\n * ```ts\n * const result = await displaySharingPage(frakClient, {\n *     products: [\n *         {\n *             title: \"Babies camel cuir velours bout carré\",\n *             imageUrl: \"https://example.com/product.jpg\",\n *         },\n *     ],\n * });\n *\n * console.log(\"User action:\", result.action); // \"shared\" | \"copied\" | \"dismissed\"\n * ```\n */\nexport async function displaySharingPage(\n    client: FrakClient,\n    params: DisplaySharingPageParamsType,\n    placement?: string\n): Promise<DisplaySharingPageResultType> {\n    return await client.request({\n        method: \"frak_displaySharingPage\",\n        params: placement\n            ? [params, client.config.metadata, placement]\n            : [params, client.config.metadata],\n    });\n}\n","import { getBackendUrl } from \"../config/backendUrl\";\nimport { getClientId } from \"../config/clientId\";\nimport { sdkConfigStore } from \"../config/sdkConfigStore\";\n\nconst ENSURE_STORAGE_PREFIX = \"frak-identity-ensured-\";\n\n/**\n * Ensure the current wallet ↔ clientId link exists on the backend.\n *\n * Called automatically by {@link watchWalletStatus} when a connected wallet\n * status is received. Acts as a failsafe: if the primary merge (SSO, pairing,\n * login/register) missed or silently failed, this ensures the link is\n * eventually established.\n *\n * The call is:\n * - **Idempotent** — if already linked, backend returns immediately\n * - **Deduplicated** — only fires once per browser session per merchant\n * - **Fire-and-forget** — errors are logged but never thrown\n *\n * @param interactionToken - The SDK JWT from wallet status (x-wallet-sdk-auth)\n *\n * @example\n * ```ts\n * // Usually called automatically via watchWalletStatus side effect.\n * // Can also be called manually if needed:\n * await ensureIdentity(\"eyJhbGciOi...\");\n * ```\n */\nexport async function ensureIdentity(interactionToken: string): Promise<void> {\n    if (typeof window === \"undefined\") {\n        return;\n    }\n\n    const clientId = getClientId();\n    if (!clientId) {\n        return;\n    }\n\n    const merchantId = await sdkConfigStore.resolveMerchantId();\n    if (!merchantId) {\n        return;\n    }\n\n    const storageKey = `${ENSURE_STORAGE_PREFIX}${merchantId}`;\n    if (window.sessionStorage.getItem(storageKey)) {\n        return;\n    }\n\n    try {\n        const backendUrl = getBackendUrl();\n        const response = await fetch(`${backendUrl}/user/identity/ensure`, {\n            method: \"POST\",\n            headers: {\n                Accept: \"application/json\",\n                \"Content-Type\": \"application/json\",\n                \"x-wallet-sdk-auth\": interactionToken,\n                \"x-frak-client-id\": clientId,\n            },\n            body: JSON.stringify({ merchantId }),\n        });\n\n        if (response.ok) {\n            window.sessionStorage.setItem(storageKey, \"1\");\n        }\n    } catch {\n        // Fire-and-forget — retry on next session\n    }\n}\n","import type { FrakClient, GetMerchantInformationReturnType } from \"../types\";\nimport { withCache } from \"../utils/cache\";\n\n/**\n * Fetch the current merchant information (name, rewards, tiers) from the wallet iframe.\n *\n * Results are cached in memory for 30 seconds by default. Concurrent calls\n * while a request is in-flight are deduplicated automatically.\n *\n * @param client - The current Frak Client\n * @param options - Optional cache configuration\n * @param options.cacheTime - Time in ms to cache the result. Default: 30_000 (30s). Set to 0 to disable.\n * @returns The merchant information including available reward tiers\n *\n * @see {@link @frak-labs/core-sdk!index.GetMerchantInformationReturnType | `GetMerchantInformationReturnType`} for the return type shape\n */\nexport async function getMerchantInformation(\n    client: FrakClient,\n    options?: { cacheTime?: number }\n): Promise<GetMerchantInformationReturnType> {\n    return withCache(\n        () =>\n            client.request({\n                method: \"frak_getMerchantInformation\",\n            }),\n        {\n            cacheKey: \"frak_getMerchantInformation\",\n            cacheTime: options?.cacheTime,\n        }\n    );\n}\n","import type { FrakClient } from \"../types\";\nimport { withCache } from \"../utils/cache\";\n\n/**\n * Fetch a merge token for the current anonymous identity.\n *\n * Used by in-app browser redirect flows to preserve identity\n * when switching from a WebView to the system browser.\n * The token is appended as `?fmt=` to the redirect URL.\n *\n * Results are cached in memory for 30 seconds by default. Concurrent calls\n * while a request is in-flight are deduplicated automatically.\n *\n * @param client - The current Frak Client\n * @param options - Optional cache configuration\n * @param options.cacheTime - Time in ms to cache the result. Default: 30_000 (30s). Set to 0 to disable.\n * @returns The merge token string, or null if unavailable\n */\nexport async function getMergeToken(\n    client: FrakClient,\n    options?: { cacheTime?: number }\n): Promise<string | null> {\n    return withCache(\n        () =>\n            client.request({\n                method: \"frak_getMergeToken\",\n            }),\n        {\n            cacheKey: \"frak_getMergeToken\",\n            cacheTime: options?.cacheTime,\n        }\n    );\n}\n","import type { FrakClient, UserReferralStatusType } from \"../types\";\nimport { withCache } from \"../utils/cache\";\n\n/**\n * Fetch the current user's referral status on the current merchant.\n *\n * The listener resolves the user's identity (via clientId or wallet session)\n * and checks whether a referral link exists where the user is the referee.\n *\n * Results are cached in memory for 30 seconds by default. Concurrent calls\n * while a request is in-flight are deduplicated automatically.\n *\n * Returns `null` when the user's identity cannot be resolved.\n *\n * @param client - The current Frak Client\n * @param options - Optional cache configuration\n * @param options.cacheTime - Time in ms to cache the result. Default: 30_000 (30s). Set to 0 to disable.\n * @returns The user's referral status, or `null` if identity cannot be resolved\n *\n * @example\n * ```ts\n * const status = await getUserReferralStatus(client);\n * if (status?.isReferred) {\n *   console.log(\"User was referred to this merchant\");\n * }\n * ```\n */\nexport async function getUserReferralStatus(\n    client: FrakClient,\n    options?: { cacheTime?: number }\n): Promise<UserReferralStatusType | null> {\n    return withCache(\n        () =>\n            client.request({\n                method: \"frak_getUserReferralStatus\",\n            }),\n        {\n            cacheKey: \"frak_getUserReferralStatus\",\n            cacheTime: options?.cacheTime,\n        }\n    );\n}\n","import type {\n    FrakClient,\n    PrepareSsoParamsType,\n    PrepareSsoReturnType,\n} from \"../types\";\n\n/**\n * Generate SSO URL without opening popup\n *\n * This is a **synchronous**, client-side function that generates the SSO URL\n * without any RPC calls to the wallet iframe. Use this when you need:\n * - Custom URL modifications before opening popup\n * - Pre-generation for advanced popup strategies\n * - URL inspection/logging before SSO flow\n *\n * @param client - The current Frak Client\n * @param args - The SSO parameters\n * @returns Object containing the generated ssoUrl\n *\n * @example\n * ```ts\n * // Generate URL for inspection\n * const { ssoUrl } = prepareSso(client, {\n *   metadata: { logoUrl: \"...\" },\n *   directExit: true\n * });\n * console.log(\"Opening SSO:\", ssoUrl);\n *\n * // Add custom params\n * const customUrl = `${ssoUrl}&tracking=abc123`;\n * await openSso(client, { metadata, ssoPopupUrl: customUrl });\n * ```\n *\n * @remarks\n * For most use cases, just use `openSso()` which handles URL generation automatically.\n * Only use `prepareSso()` when you need explicit control over the URL.\n */\nexport async function prepareSso(\n    client: FrakClient,\n    args: PrepareSsoParamsType\n): Promise<PrepareSsoReturnType> {\n    const { metadata, customizations } = client.config;\n\n    return await client.request({\n        method: \"frak_prepareSso\",\n        params: [args, metadata.name, customizations?.css],\n    });\n}\n","import { getClientId } from \"../config/clientId\";\nimport type { FrakClient } from \"../types\";\nimport type { SendInteractionParamsType } from \"../types/rpc/interaction\";\n\n/**\n * Send an interaction to the backend via the listener RPC.\n * Fire-and-forget: errors are caught and logged, not thrown.\n *\n * @param client - The Frak client instance\n * @param params - The interaction parameters\n *\n * @description Sends a user interaction event through the wallet iframe RPC. Supports three interaction types: arrival tracking, sharing events, and custom interactions.\n *\n * @example\n * Track a user arrival with referral attribution:\n * ```ts\n * await sendInteraction(client, {\n *     type: \"arrival\",\n *     referrerWallet: \"0x1234...abcd\",\n *     landingUrl: window.location.href,\n *     utmSource: \"twitter\",\n *     utmMedium: \"social\",\n *     utmCampaign: \"launch-2026\",\n * });\n * ```\n *\n * @example\n * Track a sharing event:\n * ```ts\n * await sendInteraction(client, { type: \"sharing\" });\n * ```\n *\n * @example\n * Send a custom interaction:\n * ```ts\n * await sendInteraction(client, {\n *     type: \"custom\",\n *     customType: \"newsletter_signup\",\n *     data: { email: \"user@example.com\" },\n * });\n * ```\n */\nexport async function sendInteraction(\n    client: FrakClient,\n    params: SendInteractionParamsType\n): Promise<void> {\n    try {\n        await client.request({\n            method: \"frak_sendInteraction\",\n            params: [params, { clientId: getClientId() }],\n        });\n    } catch {\n        // Silent failure - fire-and-forget\n        console.warn(\"[Frak SDK] Failed to send interaction:\", params.type);\n    }\n}\n","import { getClientId } from \"../../config/clientId\";\nimport { FrakContextManager } from \"../../context\";\nimport { areAddressesEqual } from \"../../context/address\";\nimport type {\n    FrakClient,\n    FrakContext,\n    FrakContextV2,\n    WalletStatusReturnType,\n} from \"../../types\";\nimport { isV1Context, isV2Context } from \"../../types\";\nimport { trackEvent } from \"../../utils\";\nimport { sendInteraction } from \"../sendInteraction\";\n\n/**\n * Options for the referral auto-interaction process.\n */\nexport type ProcessReferralOptions = {\n    /**\n     * If true, always replace the URL with the current user's referral context\n     * so the next visitor gets referred by this user.\n     * @defaultValue false\n     */\n    alwaysAppendUrl?: boolean;\n    /**\n     * Merchant ID for building the current user's referral context.\n     * Required when `alwaysAppendUrl` is true and the incoming context is V1.\n     * For V2 contexts, the merchantId is already embedded in the context.\n     */\n    merchantId?: string;\n};\n\n/**\n * The different states of the referral process.\n * @inline\n */\ntype ReferralState =\n    | \"idle\"\n    | \"processing\"\n    | \"success\"\n    | \"no-referrer\"\n    | \"self-referral\";\n\n/**\n * Track an arrival event if the context version is recognized.\n * Sends both tracking analytics and the arrival interaction RPC.\n *\n * @returns true if the context was valid and tracked, false otherwise\n */\nfunction trackArrivalIfValid(\n    client: FrakClient,\n    frakContext: FrakContext,\n    walletStatus?: WalletStatusReturnType\n): boolean {\n    if (isV2Context(frakContext)) {\n        trackEvent(client, \"user_referred_started\", {\n            referrer_client_id: frakContext.c,\n            referrer_wallet: frakContext.w,\n            wallet_status: walletStatus?.key,\n        });\n        sendInteraction(client, {\n            type: \"arrival\",\n            referrerClientId: frakContext.c,\n            referrerMerchantId: frakContext.m,\n            referrerWallet: frakContext.w,\n            referralTimestamp: frakContext.t,\n        });\n        return true;\n    }\n\n    if (isV1Context(frakContext)) {\n        trackEvent(client, \"user_referred_started\", {\n            referrer: frakContext.r,\n            wallet_status: walletStatus?.key,\n        });\n        sendInteraction(client, {\n            type: \"arrival\",\n            referrerWallet: frakContext.r,\n        });\n        return true;\n    }\n\n    return false;\n}\n\n/**\n * Build a V2 context representing the current user for URL replacement.\n *\n * Emits both `c` (anonymous clientId) and `w` (wallet) when available — wallet\n * is the preferred identity signal and takes attribution precedence downstream.\n * Returns null when neither identifier is available.\n */\nfunction buildCurrentUserContext(\n    merchantId: string,\n    wallet?: WalletStatusReturnType[\"wallet\"]\n): FrakContextV2 | null {\n    const clientId = getClientId();\n    if (!clientId && !wallet) return null;\n    return {\n        v: 2,\n        m: merchantId,\n        t: Math.floor(Date.now() / 1000),\n        ...(clientId ? { c: clientId } : {}),\n        ...(wallet ? { w: wallet } : {}),\n    };\n}\n\n/**\n * Client-side self-referral preflight check.\n * Prevents unnecessary backend round-trips for obvious self-referrals.\n */\nfunction isSelfReferral(\n    frakContext: FrakContext,\n    walletStatus?: WalletStatusReturnType\n): boolean {\n    if (isV2Context(frakContext)) {\n        // Wallet match takes precedence — it's the strongest signal we have.\n        if (frakContext.w && walletStatus?.wallet) {\n            return areAddressesEqual(frakContext.w, walletStatus.wallet);\n        }\n        if (frakContext.c) {\n            return getClientId() === frakContext.c;\n        }\n        return false;\n    }\n    if (isV1Context(frakContext) && walletStatus?.wallet) {\n        return areAddressesEqual(frakContext.r, walletStatus.wallet);\n    }\n    return false;\n}\n\n/**\n * Handle the full referral interaction flow:\n *\n *  1. Check if the user has been referred (if not, early exit)\n *  2. Preflight self-referral check (if yes, early exit)\n *  3. Track the arrival event\n *  4. Replace the current URL with the user's own referral context\n *  5. Return the resulting referral state\n *\n * @param client - The current Frak Client\n * @param args\n * @param args.walletStatus - The current user wallet status\n * @param args.frakContext - The referral context parsed from the URL\n * @param args.options - Options for URL replacement and merchant context\n * @returns The referral state\n *\n * @see {@link @frak-labs/core-sdk!ModalStepTypes} for modal step types\n */\nexport function processReferral(\n    client: FrakClient,\n    {\n        walletStatus,\n        frakContext,\n        options,\n    }: {\n        walletStatus?: WalletStatusReturnType;\n        frakContext?: FrakContext | null;\n        options?: ProcessReferralOptions;\n    }\n): ReferralState {\n    if (!frakContext) {\n        return \"no-referrer\";\n    }\n\n    if (isSelfReferral(frakContext, walletStatus)) {\n        return \"self-referral\";\n    }\n\n    if (!trackArrivalIfValid(client, frakContext, walletStatus)) {\n        return \"no-referrer\";\n    }\n\n    // V2 context embeds merchantId; V1 falls back to options\n    const contextMerchantId = isV2Context(frakContext)\n        ? frakContext.m\n        : options?.merchantId;\n\n    const replaceContext =\n        options?.alwaysAppendUrl && contextMerchantId\n            ? buildCurrentUserContext(contextMerchantId, walletStatus?.wallet)\n            : null;\n\n    FrakContextManager.replaceUrl({\n        url: window.location?.href,\n        context: replaceContext,\n    });\n\n    trackEvent(client, \"user_referred_completed\", {\n        status: \"success\",\n    });\n\n    return \"success\";\n}\n","import { FrakContextManager } from \"../../context\";\nimport type { FrakClient } from \"../../types\";\nimport { watchWalletStatus } from \"../index\";\nimport {\n    type ProcessReferralOptions,\n    processReferral,\n} from \"./processReferral\";\n\n/**\n * Function used to handle referral interactions\n * @param client - The current Frak Client\n * @param args\n * @param args.options - Some options for the referral interaction\n *\n * @returns  A promise with the resulting referral state, or undefined in case of an error\n *\n * @description This function will automatically handle the referral interaction process\n *\n * @see {@link processReferral} for more details on the automatic referral handling process\n */\nexport async function referralInteraction(\n    client: FrakClient,\n    {\n        options,\n    }: {\n        options?: ProcessReferralOptions;\n    } = {}\n) {\n    // Get the current frak context\n    const frakContext = FrakContextManager.parse({\n        url: window.location.href,\n    });\n\n    // Get the current wallet status\n    const currentWalletStatus = await watchWalletStatus(client);\n\n    try {\n        return processReferral(client, {\n            walletStatus: currentWalletStatus,\n            frakContext,\n            options,\n        });\n    } catch (error) {\n        console.warn(\"Error processing referral\", { error });\n    }\n    return;\n}\n","import type { FrakClient } from \"../../types\";\nimport { referralInteraction } from \"./referralInteraction\";\n\n/**\n * Custom event name dispatched on successful referral processing.\n *\n * Fired once per page load when a valid referral context is found in the URL\n * and successfully tracked. Consumers (e.g. `<frak-banner>`) listen for this\n * to display a referral success message.\n */\nexport const REFERRAL_SUCCESS_EVENT = \"frak:referral-success\";\n\n/**\n * Process referral context and emit a DOM event on success.\n *\n * - Calls {@link referralInteraction} to detect and track any referral in the URL\n * - On `\"success\"`, dispatches a bare {@link REFERRAL_SUCCESS_EVENT} on `window`\n * - Silently swallows errors (fire-and-forget during SDK init)\n *\n * @param client - The initialized Frak client\n */\nexport async function setupReferral(client: FrakClient): Promise<void> {\n    try {\n        const state = await referralInteraction(client);\n\n        if (state === \"success\") {\n            window.dispatchEvent(new Event(REFERRAL_SUCCESS_EVENT));\n        }\n    } catch (error) {\n        console.warn(\"[Frak] Referral setup failed\", error);\n    }\n}\n","import { getBackendUrl } from \"../config/backendUrl\";\nimport { getClientId } from \"../config/clientId\";\nimport { sdkConfigStore } from \"../config/sdkConfigStore\";\n\n/**\n * Function used to track the status of a purchase\n * when a purchase is tracked, the `purchaseCompleted` interactions will be automatically send for the user when we receive the purchase confirmation via webhook.\n *\n * @param args.customerId - The customer id that made the purchase (on your side)\n * @param args.orderId - The order id of the purchase (on your side)\n * @param args.token - The token of the purchase\n * @param args.merchantId - Optional explicit merchant id to use for the tracking request\n *\n * @description This function will send a request to the backend to listen for the purchase status.\n *\n * @example\n * async function trackPurchase(checkout) {\n *   const payload = {\n *     customerId: checkout.order.customer.id,\n *     orderId: checkout.order.id,\n *     token: checkout.token,\n *     merchantId: \"your-merchant-id\",\n *   };\n *\n *   await trackPurchaseStatus(payload);\n * }\n *\n * @remarks\n * - Merchant id is resolved in this order: explicit `args.merchantId`, then `sdkConfigStore.resolveMerchantId()` (config store → sessionStorage → backend fetch).\n * - This function supports anonymous users and will use the `x-frak-client-id` header when available.\n * - At least one identity source must exist (`frak-wallet-interaction-token` or `x-frak-client-id`), otherwise the tracking request is skipped.\n * - This function will print a warning if used in a non-browser environment or if no identity / merchant id can be resolved.\n */\nexport async function trackPurchaseStatus(args: {\n    customerId: string | number;\n    orderId: string | number;\n    token: string;\n    merchantId?: string;\n}) {\n    if (typeof window === \"undefined\") {\n        console.warn(\"[Frak] No window found, can't track purchase\");\n        return;\n    }\n\n    const interactionToken = window.sessionStorage.getItem(\n        \"frak-wallet-interaction-token\"\n    );\n\n    const clientId = getClientId();\n    if (!interactionToken && !clientId) {\n        console.warn(\"[Frak] No identity found, skipping purchase check\");\n        return;\n    }\n\n    const merchantId =\n        args.merchantId ?? (await sdkConfigStore.resolveMerchantId());\n\n    if (!merchantId) {\n        console.warn(\"[Frak] No merchant id found, skipping purchase check\");\n        return;\n    }\n\n    const headers: Record<string, string> = {\n        Accept: \"application/json\",\n        \"Content-Type\": \"application/json\",\n    };\n\n    if (interactionToken) {\n        headers[\"x-wallet-sdk-auth\"] = interactionToken;\n    }\n\n    if (clientId) {\n        headers[\"x-frak-client-id\"] = clientId;\n    }\n\n    // Submit the listening request\n    const backendUrl = getBackendUrl();\n    await fetch(`${backendUrl}/user/track/purchase`, {\n        method: \"POST\",\n        headers,\n        body: JSON.stringify({\n            customerId: args.customerId,\n            orderId: args.orderId,\n            token: args.token,\n            merchantId,\n        }),\n    });\n}\n","import { Deferred } from \"@frak-labs/frame-connector\";\nimport type { FrakClient } from \"../types/client\";\nimport type { WalletStatusReturnType } from \"../types/rpc/walletStatus\";\nimport { ensureIdentity } from \"./ensureIdentity\";\n\n/**\n * Function used to watch the current frak wallet status\n * @param client - The current Frak Client\n * @param callback - The callback that will receive any wallet status change\n * @returns A promise resolving with the initial wallet status\n *\n * @description This function will return the current wallet status, and will listen to any change in the wallet status.\n *\n * @example\n * await watchWalletStatus(frakConfig, (status: WalletStatusReturnType) => {\n *     if (status.key === \"connected\") {\n *         console.log(\"Wallet connected:\", status.wallet);\n *     } else {\n *         console.log(\"Wallet not connected\");\n *     }\n * });\n */\nexport function watchWalletStatus(\n    client: FrakClient,\n    callback?: (status: WalletStatusReturnType) => void\n): Promise<WalletStatusReturnType> {\n    // If no callback is provided, just do a request with deferred result\n    if (!callback) {\n        return client\n            .request({ method: \"frak_listenToWalletStatus\" })\n            .then((result) => {\n                // Handle side effects of this request\n                walletStatusSideEffect(client, result);\n\n                // Return the result\n                return result;\n            });\n    }\n\n    // Otherwise, listen to the wallet status and return the first one received\n    const firstResult = new Deferred<WalletStatusReturnType>();\n    let hasResolved = false;\n\n    // Start the listening request, and return the first result\n    client.listenerRequest(\n        {\n            method: \"frak_listenToWalletStatus\",\n        },\n        (status) => {\n            // Handle side effects of this request\n            walletStatusSideEffect(client, status);\n\n            // Transmit the status to the callback\n            callback(status);\n\n            // If the promise hasn't resolved yet, resolve it\n            if (!hasResolved) {\n                firstResult.resolve(status);\n                hasResolved = true;\n            }\n        }\n    );\n\n    return firstResult.promise;\n}\n\n/**\n * Helper to save a potential interaction token\n * @param interactionToken\n */\nfunction walletStatusSideEffect(\n    client: FrakClient,\n    status: WalletStatusReturnType\n) {\n    if (typeof window === \"undefined\") {\n        return;\n    }\n\n    // Update the global properties\n    client.openPanel?.setGlobalProperties({\n        wallet: status.wallet ?? null,\n    });\n\n    if (status.interactionToken) {\n        window.sessionStorage.setItem(\n            \"frak-wallet-interaction-token\",\n            status.interactionToken\n        );\n        ensureIdentity(status.interactionToken);\n    } else {\n        window.sessionStorage.removeItem(\"frak-wallet-interaction-token\");\n    }\n}\n","import type {\n    DisplayModalParamsType,\n    FinalActionType,\n    FinalModalStepType,\n    FrakClient,\n    LoginModalStepType,\n    ModalRpcMetadata,\n    ModalRpcStepsResultType,\n    ModalStepTypes,\n    SendTransactionModalStepType,\n} from \"../../types\";\nimport { displayModal } from \"../displayModal\";\n\n/**\n * Represent the type of the modal step builder\n */\nexport type ModalStepBuilder<\n    Steps extends ModalStepTypes[] = ModalStepTypes[],\n> = {\n    /**\n     * The current modal params\n     */\n    params: DisplayModalParamsType<Steps>;\n    /**\n     * Add a send transaction step to the modal\n     */\n    sendTx: (\n        options: SendTransactionModalStepType[\"params\"]\n    ) => ModalStepBuilder<[...Steps, SendTransactionModalStepType]>;\n    /**\n     * Add a final step of type reward to the modal\n     */\n    reward: (\n        options?: Omit<FinalModalStepType[\"params\"], \"action\">\n    ) => ModalStepBuilder<[...Steps, FinalModalStepType]>;\n    /**\n     * Add a final step of type sharing to the modal\n     */\n    sharing: (\n        sharingOptions?: Extract<\n            FinalActionType,\n            { key: \"sharing\" }\n        >[\"options\"],\n        options?: Omit<FinalModalStepType[\"params\"], \"action\">\n    ) => ModalStepBuilder<[...Steps, FinalModalStepType]>;\n    /**\n     * Display the modal\n     * @param metadataOverride - Function returning optional metadata to override the current modal metadata\n     * @param placement - Optional placement ID to associate with this modal display\n     */\n    display: (\n        metadataOverride?: (\n            current?: ModalRpcMetadata\n        ) => ModalRpcMetadata | undefined,\n        placement?: string\n    ) => Promise<ModalRpcStepsResultType<Steps>>;\n};\n\n/**\n * Represent the output type of the modal builder\n */\nexport type ModalBuilder = ModalStepBuilder<[LoginModalStepType]>;\n\n/**\n * Helper to craft Frak modal, and share a base initial config\n * @param client - The current Frak Client\n * @param args\n * @param args.metadata - Common modal metadata (customisation, language etc)\n * @param args.login - Login step parameters\n *\n * @description This function will create a modal builder with the provided metadata and login parameters.\n *\n * @example\n * Here is an example of how to use the `modalBuilder` to create and display a sharing modal:\n *\n * ```js\n * // Create the modal builder\n * const modalBuilder = window.FrakSDK.modalBuilder(frakClient, baseModalConfig);\n *\n * // Configure the information to be shared via the sharing link\n * const sharingConfig = {\n *   popupTitle: \"Share this with your friends\",\n *   text: \"Discover our product!\",\n *   link: window.location.href,\n * };\n *\n * // Display the sharing modal\n * function modalShare() {\n *   modalBuilder.sharing(sharingConfig).display();\n * }\n * ```\n *\n * @see {@link ModalStepTypes} for more info about each modal step types and their parameters\n * @see {@link ModalRpcMetadata} for more info about the metadata that can be passed to the modal\n * @see {@link ModalRpcStepsResultType} for more info about the result of each modal steps\n * @see {@link displayModal} for more info about how the modal is displayed\n */\nexport function modalBuilder(\n    client: FrakClient,\n    {\n        metadata,\n        login,\n    }: {\n        metadata?: ModalRpcMetadata;\n        login?: LoginModalStepType[\"params\"];\n    }\n): ModalBuilder {\n    // Build the initial modal params\n    const baseParams: DisplayModalParamsType<[LoginModalStepType]> = {\n        steps: {\n            login: login ?? {},\n        },\n        metadata,\n    };\n\n    // Return the step builder\n    return modalStepsBuilder(client, baseParams);\n}\n\n/**\n * Modal step builder, allowing to add new steps to the modal, and to build and display it\n */\nfunction modalStepsBuilder<CurrentSteps extends ModalStepTypes[]>(\n    client: FrakClient,\n    params: DisplayModalParamsType<CurrentSteps>\n): ModalStepBuilder<CurrentSteps> {\n    // Function add the send tx step\n    function sendTx(options: SendTransactionModalStepType[\"params\"]) {\n        return modalStepsBuilder<\n            [...CurrentSteps, SendTransactionModalStepType]\n        >(client, {\n            ...params,\n            steps: {\n                ...params.steps,\n                sendTransaction: options,\n            },\n        } as DisplayModalParamsType<\n            [...CurrentSteps, SendTransactionModalStepType]\n        >);\n    }\n\n    // Function to add a reward step at the end\n    function reward(options?: Omit<FinalModalStepType[\"params\"], \"action\">) {\n        return modalStepsBuilder<[...CurrentSteps, FinalModalStepType]>(\n            client,\n            {\n                ...params,\n                steps: {\n                    ...params.steps,\n                    final: {\n                        ...options,\n                        action: { key: \"reward\" },\n                    },\n                },\n            } as DisplayModalParamsType<[...CurrentSteps, FinalModalStepType]>\n        );\n    }\n\n    // Function to add sharing step at the end\n    function sharing(\n        sharingOptions?: Extract<\n            FinalActionType,\n            { key: \"sharing\" }\n        >[\"options\"],\n        options?: Omit<FinalModalStepType[\"params\"], \"action\">\n    ) {\n        return modalStepsBuilder<[...CurrentSteps, FinalModalStepType]>(\n            client,\n            {\n                ...params,\n                steps: {\n                    ...params.steps,\n                    final: {\n                        ...options,\n                        action: { key: \"sharing\", options: sharingOptions },\n                    },\n                },\n            } as DisplayModalParamsType<[...CurrentSteps, FinalModalStepType]>\n        );\n    }\n\n    async function display(\n        metadataOverride?: (\n            current?: ModalRpcMetadata\n        ) => ModalRpcMetadata | undefined,\n        placement?: string\n    ) {\n        if (metadataOverride) {\n            params.metadata = metadataOverride(params.metadata ?? {});\n        }\n        return await displayModal(client, params, placement);\n    }\n\n    return {\n        params,\n        sendTx,\n        reward,\n        sharing,\n        display,\n    };\n}\n","import type {\n    FrakClient,\n    ModalRpcMetadata,\n    SendTransactionModalStepType,\n    SendTransactionReturnType,\n} from \"../../types\";\nimport { displayModal } from \"../displayModal\";\n\n/**\n * Parameters to directly show a modal used to send a transaction\n * @inline\n */\nexport type SendTransactionParams = {\n    /**\n     * The transaction to be sent (either a single tx or multiple ones)\n     */\n    tx: SendTransactionModalStepType[\"params\"][\"tx\"];\n    /**\n     * Custom metadata to be passed to the modal\n     */\n    metadata?: ModalRpcMetadata;\n};\n\n/**\n * Function used to send a user transaction, simple wrapper around the displayModal function to ease the send transaction process\n * @param client - The current Frak Client\n * @param args - The parameters\n * @returns The hash of the transaction that was sent in a promise\n *\n * @description This function will display a modal to the user with the provided transaction and metadata.\n *\n * @example\n * const { hash } = await sendTransaction(frakConfig, {\n *     tx: {\n *         to: \"0xdeadbeef\",\n *         value: toHex(100n),\n *     },\n *     metadata: {\n *         header: {\n *             title: \"Sending eth\",\n *         },\n *         context: \"Send 100wei to 0xdeadbeef\",\n *     },\n * });\n * console.log(\"Transaction hash:\", hash);\n */\nexport async function sendTransaction(\n    client: FrakClient,\n    { tx, metadata }: SendTransactionParams\n): Promise<SendTransactionReturnType> {\n    // Trigger a modal with login options\n    const result = await displayModal(client, {\n        metadata,\n        steps: {\n            login: {},\n            sendTransaction: { tx },\n        },\n    });\n\n    // Return the tx result only\n    return result.sendTransaction;\n}\n","import type {\n    FrakClient,\n    ModalRpcMetadata,\n    SiweAuthenticateReturnType,\n    SiweAuthenticationParams,\n} from \"../../types\";\nimport { displayModal } from \"../displayModal\";\n\n/**\n * Generate a random EIP-4361-compatible nonce.\n *\n * Matches viem/siwe's `generateSiweNonce` shape (96 alphanumeric chars) but\n * inlined here to avoid pulling viem's runtime utilities into the bundle.\n * Uses `crypto.getRandomValues` when available (browsers, modern Node) and\n * falls back to `Math.random` for the rare environment without WebCrypto.\n */\nfunction generateSiweNonce(length = 96): string {\n    const byteCount = Math.ceil(length / 2);\n    let hex = \"\";\n    if (typeof crypto !== \"undefined\" && crypto.getRandomValues) {\n        const bytes = new Uint8Array(byteCount);\n        crypto.getRandomValues(bytes);\n        for (let i = 0; i < bytes.length; i++) {\n            hex += bytes[i].toString(16).padStart(2, \"0\");\n        }\n    } else {\n        for (let i = 0; i < byteCount; i++) {\n            hex += ((Math.random() * 256) | 0).toString(16).padStart(2, \"0\");\n        }\n    }\n    return hex.substring(0, length);\n}\n\n/**\n * Parameter used to directly show a modal used to authenticate with SIWE\n * @inline\n */\nexport type SiweAuthenticateModalParams = {\n    /**\n     * Partial SIWE params, since we can rebuild them from the SDK if they are empty\n     *\n     * If no parameters provider, some fields will be recomputed from the current configuration and environment.\n     *  - `statement` will be set to a default value\n     *  - `nonce` will be generated\n     *  - `uri` will be set to the current domain\n     *  - `version` will be set to \"1\"\n     *  - `domain` will be set to the current window domain\n     *\n     * @default {}\n     */\n    siwe?: Partial<SiweAuthenticationParams>;\n    /**\n     * Custom metadata to be passed to the modal\n     */\n    metadata?: ModalRpcMetadata;\n};\n\n/**\n * Function used to launch a siwe authentication\n * @param client - The current Frak Client\n * @param args - The parameters\n * @returns The SIWE authentication result (message + signature) in a promise\n *\n * @description This function will display a modal to the user with the provided SIWE parameters and metadata.\n *\n * @example\n * import { siweAuthenticate } from \"@frak-labs/core-sdk/actions\";\n * import { parseSiweMessage } from \"viem/siwe\";\n *\n * const { signature, message } = await siweAuthenticate(frakConfig, {\n *     siwe: {\n *         statement: \"Sign in to My App\",\n *         domain: \"my-app.com\",\n *         expirationTimeTimestamp: Date.now() + 1000 * 60 * 5,\n *     },\n *     metadata: {\n *         header: {\n *             title: \"Sign in\",\n *         },\n *         context: \"Sign in to My App\",\n *     },\n * });\n * console.log(\"Parsed final message:\", parseSiweMessage(message));\n * console.log(\"Siwe signature:\", signature);\n */\nexport async function siweAuthenticate(\n    client: FrakClient,\n    { siwe, metadata }: SiweAuthenticateModalParams\n): Promise<SiweAuthenticateReturnType> {\n    const effectiveDomain = client.config?.domain ?? window.location.host;\n    const realStatement =\n        siwe?.statement ??\n        `I confirm that I want to use my Frak wallet on: ${client.config.metadata.name}`;\n\n    // Fill up the siwe request params\n    const builtSiwe: SiweAuthenticationParams = {\n        ...siwe,\n        statement: realStatement,\n        nonce: siwe?.nonce ?? generateSiweNonce(),\n        uri: siwe?.uri ?? `https://${effectiveDomain}`,\n        version: siwe?.version ?? \"1\",\n        domain: effectiveDomain,\n    };\n\n    // Trigger a modal with login options\n    const result = await displayModal(client, {\n        metadata,\n        steps: {\n            login: {},\n            siweAuthenticate: {\n                siwe: builtSiwe,\n            },\n        },\n    });\n\n    // Return the SIWE result only\n    return result.siweAuthenticate;\n}\n"],"mappings":"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"}