import { PaymentWizardRoute, AssetIndexEntry } from '@openreceive/provider-data'; import { TransactionSettlementStatus } from '@openreceive/core'; declare const OPENRECEIVE_PAYMENT_ICON_IDS: readonly ["btc", "crypto", "eth", "lightning", "ltc", "sol", "trx", "usdc", "usdt", "xmr", "xrp"]; type PaymentIconId = (typeof OPENRECEIVE_PAYMENT_ICON_IDS)[number]; /** Each packaged payment icon as minified SVG markup, keyed by id. */ declare const paymentIconSvgs: Readonly>; /** * Trim insignificant trailing zeros from a decimal crypto amount for display, * e.g. "12.25900000" -> "12.259" and "5.000" -> "5". Only fractional digits are * stripped: integer amounts like "100" keep their zeros, and non-numeric input * is returned unchanged. */ declare function formatDepositAmount(amount: string): string; declare function escapeHtml(value: string): string; /** * Throws on a non-amount, and every caller lets it: wire construction, amount * validation, and the display sites share this formatter, and a malformed * amount from our own server is a bug that must surface, not be smoothed over. */ declare function formatMsats(amountMsats: number): string; declare function formatFiatAmount(fiat: { readonly currency?: string; readonly value?: string; } | null | undefined): string | undefined; /** Combined QR caption, e.g. `19,174 sats / $12.00 USD` — the ISO code, because "$" alone does not say which dollar. */ declare function formatAmountCaption(options: { readonly amountLabel?: string; readonly fiatLabel?: string; readonly fiatCurrency?: string; }): string | undefined; /** * Renders an invoice-side (Lightning receive) msat limit as a short amount for * display under a disabled swap asset, e.g. "$10.00". Converts to the * checkout's own fiat currency using its rate; falls back to a sats figure when * the checkout is sats/BTC-denominated or no usable rate is available. * * Minimums ceil and maximums floor to the display scale so the note never * understates a floor or overstates a ceiling. */ declare function formatSwapLimit(checkout: { readonly amount_msats: number; readonly fiat?: { readonly currency: string; readonly value: string; }; }, limitMsats: number | undefined, rounding?: "ceil" | "floor"): string | undefined; /** * ECHOES rather than throws on a value it cannot render — the one place this * rule reads differently from the amount rule above, deliberately. * `formatMsats` throws because wire construction and amount validation share * it and a bad amount there must surface; nothing constructs or validates * anything through this formatter, so degrading to the raw value is its * contract. */ declare function formatUnixTime(seconds: number): string; /** The payer-facing labels a {@link CheckoutState} carries next to its raw fields. */ interface CheckoutStateLabels { readonly amountLabel?: string; readonly fiatLabel?: string; readonly paymentHashLabel?: string; } /** * THE label rule — one copy, applied everywhere a checkout is shown. * * `normalizeCheckoutState` runs it so every CheckoutState already carries its * labels, and the elements renderer runs it over raw attributes in create mode, * before there is an attempt to build a state from. It replaces the label half * of the deleted `createCheckoutDisplayModel`; the other half (the `lightning:` * URI) belongs to `createCheckoutState`, which is the only place that knows the * rail. * * `transactionStateLabel` is deliberately NOT here: it was a verbatim copy of * `transaction_state`, which the state already carries, and nothing read it. */ declare function deriveCheckoutStateLabels(source: { readonly amount_msats?: number; readonly fiat_quote?: { readonly fiat?: { readonly currency?: string; readonly value?: string; }; } | null; readonly payment_hash?: string; }): CheckoutStateLabels; declare const OPENRECEIVE_THEME_STORAGE_KEY: "openreceive.theme"; declare const OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS: 3000; /** * Default base path the shipped OpenReceive router is mounted at. When a developer passes * only an order id (React `` / ``), this is * the prefix every route is derived from — see `checkoutRoutes` in ./routes.ts. It is * the only URL input the checkout components accept. */ declare const OPENRECEIVE_DEFAULT_PREFIX: "/openreceive"; declare const OPENRECEIVE_COPY_FEEDBACK_MS: 1800; declare const OPENRECEIVE_PROVIDER_PREVIEW_LIMIT: 4; declare const OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME: "openreceive-checkout"; declare const OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME: "openreceive-theme-toggle"; declare const OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS: { readonly copy: "openreceive-copy"; readonly openWallet: "openreceive-open-wallet"; readonly state: "openreceive-state"; readonly settled: "openreceive-settled"; readonly providerCopy: "openreceive-provider-copy"; readonly startOver: "openreceive-start-over"; readonly error: "openreceive-error"; }; declare const OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS: { readonly change: "openreceive-theme-change"; }; declare const OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES: { readonly root: "data-openreceive-wizard"; readonly breadcrumb: "data-or-breadcrumb"; readonly method: "data-or-method"; readonly route: "data-or-route"; readonly swapStart: "data-or-swap-start"; readonly swapBack: "data-or-swap-back"; readonly swapQr: "data-or-swap-qr"; readonly swapCopy: "data-or-swap-copy"; readonly swapCopyLabel: "data-or-swap-copy-label"; readonly swapSelectAll: "data-or-swap-select-all"; readonly swapNetwork: "data-or-swap-network"; readonly swapNetworkValue: "data-or-swap-network-value"; readonly pickerSelect: "data-or-picker-select"; readonly pickerContinue: "data-or-picker-continue"; readonly swapRefundForm: "data-or-swap-refund-form"; readonly swapRefundAddress: "data-or-swap-refund-address"; readonly swapRefundAllowed: "data-or-swap-refund-allowed"; readonly swapRefundConfirm: "data-or-swap-refund-confirm"; readonly swapRefundPayInAsset: "data-or-swap-refund-pay-in-asset"; readonly swapRefundNetworkLabel: "data-or-swap-refund-network-label"; readonly swapRefundError: "data-or-swap-refund-error"; readonly providerCopy: "data-or-provider-copy"; readonly providerTutorial: "data-or-provider-tutorial"; readonly providerTutorialIndex: "data-or-provider-tutorial-index"; }; declare const OPENRECEIVE_PAYMENT_WIZARD_SELECTORS: { readonly root: "[data-openreceive-wizard]"; readonly breadcrumb: "[data-or-breadcrumb]"; readonly method: "[data-or-method]"; readonly route: "[data-or-route]"; readonly swapStart: "[data-or-swap-start]"; readonly swapBack: "[data-or-swap-back]"; readonly swapQr: "[data-or-swap-qr]"; readonly swapCopy: "[data-or-swap-copy]"; readonly swapCopyLabel: "[data-or-swap-copy-label]"; readonly swapSelectAll: "[data-or-swap-select-all]"; readonly swapNetwork: "[data-or-swap-network]"; readonly swapNetworkValue: "[data-or-swap-network-value]"; readonly pickerSelect: "[data-or-picker-select]"; readonly pickerContinue: "[data-or-picker-continue]"; readonly swapRefundForm: "[data-or-swap-refund-form]"; readonly swapRefundAddress: "[data-or-swap-refund-address]"; readonly swapRefundAllowed: "[data-or-swap-refund-allowed]"; readonly swapRefundConfirm: "[data-or-swap-refund-confirm]"; readonly swapRefundPayInAsset: "[data-or-swap-refund-pay-in-asset]"; readonly swapRefundNetworkLabel: "[data-or-swap-refund-network-label]"; readonly swapRefundError: "[data-or-swap-refund-error]"; readonly providerCopy: "[data-or-provider-copy]"; readonly providerTutorial: "[data-or-provider-tutorial]"; readonly providerTutorialIndex: "[data-or-provider-tutorial-index]"; }; declare const OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES: { readonly root: "data-openreceive-checkout"; readonly qr: "data-openreceive-qr"; readonly meta: "data-openreceive-meta"; readonly state: "data-openreceive-state"; readonly actions: "data-openreceive-actions"; /** What the payer is buying, when the host's amount hook named it. */ readonly orderDescription: "data-openreceive-order-description"; readonly theme: "data-openreceive-theme"; readonly themeToggle: "data-openreceive-theme-toggle"; }; declare const OPENRECEIVE_CHECKOUT_DATA_SELECTORS: { readonly root: "[data-openreceive-checkout]"; readonly qr: "[data-openreceive-qr]"; readonly meta: "[data-openreceive-meta]"; readonly state: "[data-openreceive-state]"; readonly actions: "[data-openreceive-actions]"; readonly orderDescription: "[data-openreceive-order-description]"; readonly theme: "[data-openreceive-theme]"; readonly themeToggle: "[data-openreceive-theme-toggle]"; }; /** * The stylesheet scope marker. The shipped `styles.css` is rewritten at build * time (tools/package/scope-styles.mjs) so every rule — preflight, theme * variables, daisyUI components — applies only on or under an element carrying * this attribute; loaded into a host page it is otherwise inert. Every * light-DOM entry the packages render stamps it (React `` and * ``, the Vue/Svelte/Angular shell). Custom markup styled from * `orClasses` needs it on its own container, together with the resolved * `data-theme`, because the theme palette no longer flows from `:root`. */ declare const OPENRECEIVE_STYLE_ROOT_ATTRIBUTE: "data-openreceive-root"; declare const OPENRECEIVE_STYLE_ROOT_SELECTOR: "[data-openreceive-root]"; declare const OPENRECEIVE_CHECKOUT_ELEMENT_PARTS: { readonly copy: "copy"; readonly startOver: "start-over"; }; /** * Named slots the checkout element projects host light-DOM children into. * * `order` is the element's answer to React's render-prop `children`: a line-item * strip, a thumbnail, a "you are buying" summary, drawn from the order * OpenReceive does not own. It is projected through a `` in the shadow * root, so it survives every re-render of the shell's `innerHTML` untouched. */ declare const OPENRECEIVE_CHECKOUT_ELEMENT_SLOTS: { readonly order: "order"; }; declare const OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS: { readonly copy: "[part=\"copy\"]"; readonly startOver: "[part=\"start-over\"]"; }; declare const OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS: { readonly button: "button"; }; declare const OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS: { readonly button: "[part=\"button\"]"; }; type CheckoutElementEventName = (typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS)[keyof typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS]; interface CheckoutProviderCopyEventDetail { readonly providerId: string; } interface CheckoutStateEventDetail { readonly state: CheckoutState; } interface CheckoutErrorEventDetail { readonly error: unknown; } interface ThemeChangeEventDetail { readonly theme: ThemePreference; readonly resolvedTheme: ResolvedTheme; } declare function createCheckoutProviderCopyEvent(providerId: string): CustomEvent; declare function createCheckoutActionEvent(eventName: typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.copy | typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.openWallet | typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.startOver): CustomEvent; declare function createCheckoutStateEvent(eventName: typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.state | typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.settled, state: CheckoutState): CustomEvent; declare function createCheckoutErrorEvent(error: unknown): CustomEvent; declare function createThemeChangeEvent(theme: ThemeModel): CustomEvent; declare const OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES: { readonly reference: "reference"; /** * Base path the shipped router is mounted at (default `/openreceive`). The * element's ONLY URL input: create, prepare, payment-check and the four swap * routes are all derived from it. There is deliberately no per-route * attribute — see `checkoutRoutes` in ../internal/routes.ts. */ readonly prefix: "prefix"; /** * Header name the page's `` value is sent under on * every request the element makes. Default `X-CSRF-Token` (Rails, Laravel); * Django reads `X-CSRFToken`, WordPress REST reads `X-WP-Nonce`. The meta * tag name is fixed; only the header name is the host's to choose. */ readonly csrfHeader: "csrf-header"; /** JSON-encoded create-time metadata forwarded to the create request. */ readonly metadata: "metadata"; readonly invoiceId: "invoice-id"; readonly invoice: "invoice"; readonly rail: "rail"; readonly paymentHash: "payment-hash"; readonly amountMsats: "amount-msats"; readonly fiatCurrency: "fiat-currency"; readonly fiatValue: "fiat-value"; readonly status: "status"; readonly expiresAt: "expires-at"; readonly theme: "theme"; readonly paymentWizard: "payment-wizard"; /** * Opt into History API URL sync to `{resume-path-prefix}/{reference}`. * Summary fetch always runs in create mode; this only controls URL mutation. */ readonly syncUrl: "sync-url"; /** History API path prefix when `sync-url` is set. Default `/checkout`. */ readonly resumePathPrefix: "resume-path-prefix"; /** * Order id owned by the app router (e.g. Next.js). When set, the element does not * push/replace the URL via the History API. */ readonly routeReference: "route-reference"; /** * Create mode only. Payment hash of a swap attempt this order already has in * flight; the element reopens it after prepare instead of showing the method * grid. A hash the server will not serve is ignored. */ readonly resumePaymentHash: "resume-payment-hash"; readonly resumePaymentRail: "resume-payment-rail"; /** * Does a payer who closes this tab have a URL that brings them back to this * checkout? Only the refund screen's copy depends on it — see * `SwapDisplayModel.refundReturnLabel`. Unset, the element infers it from * `sync-url` / `route-reference`; set it when the host owns a per-order route * of its own, which the element cannot see. */ readonly resumable: "resumable"; /** * Base URL of an external bolt11 decoder. When set, the checkout shows a * "Decode" link to `{decode-link-url}?invoice={bolt11}`. Omitted (the * default), no decode link is rendered and the invoice never leaves the page. */ readonly decodeLinkUrl: "decode-link-url"; /** `polling="false"` renders the snapshot without status polling (no POST /payments/check). */ readonly polling: "polling"; /** Status poll cadence in milliseconds; defaults to OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS. */ readonly pollIntervalMs: "poll-interval-ms"; }; declare const OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES: { readonly rootSelector: "root-selector"; readonly checkoutSelector: "checkout-selector"; readonly defaultTheme: "default-theme"; readonly storageKey: "storage-key"; }; /** * A unix timestamp in **seconds** — the unit every OpenReceive wire field uses * (`expires_at`, `provider_expires_at`, `settled_at`, `paid_at`) and therefore * the unit every `now` option compares against. * * It is a plain `number`; the alias exists so the unit shows up where the * option does. `Date.now()` is MILLISECONDS and is the wrong value here — * {@link resolveNow} rejects it rather than letting every invoice read as * expired. Use `Math.floor(Date.now() / 1000)`. */ type UnixSeconds = number; interface TransientFeedbackOptions { readonly resetValue: T; readonly delayMs?: number; readonly setTimeout?: typeof globalThis.setTimeout; readonly clearTimeout?: typeof globalThis.clearTimeout; readonly onValue: (value: T) => void; } interface TransientFeedbackController { show(value: T): void; clear(): void; } interface TickingValueOptions { readonly active?: boolean; readonly intervalMs?: number; /** Clock returning unix **seconds** ({@link UnixSeconds}), not milliseconds. */ readonly now?: () => UnixSeconds; readonly setInterval?: typeof globalThis.setInterval; readonly clearInterval?: typeof globalThis.clearInterval; readonly onValue: (value: number) => void; } interface TickingValueController { start(): void; stop(): void; refresh(): void; } interface QrEncoder { toString(payload: string, options: Record): Promise | string; toDataURL?(payload: string, options: Record): Promise | string; } interface QrOptions { encoder?: QrEncoder; width?: number; } interface CopyInvoiceOptions { invoice: string; clipboard?: Pick; logger?: BrowserLoggerOption; logContext?: BrowserLogContext; } interface OpenWalletOptions { invoice: string; /** * Where to send the `lightning:` URI. Omitted, {@link openWallet} calls * `location.assign` on the CURRENT window, which navigates the payer off a * still-polling checkout on any device that has a handler registered. */ open?: (uri: string) => void; logger?: BrowserLoggerOption; logContext?: BrowserLogContext; } type BrowserLogLevel = "debug" | "info" | "warn" | "error"; interface BrowserLogEntry { readonly level: BrowserLogLevel; readonly event: string; readonly message: string; readonly [key: string]: unknown; } type BrowserLogger = (entry: BrowserLogEntry) => void; /** * Browser logger option. Omit/`undefined` attaches the built-in console logger * (honoring `LOG_LEVEL`). Pass `false` to disable OpenReceive browser logs. */ type BrowserLoggerOption = BrowserLogger | false; interface BrowserLogContext { readonly reference?: string; readonly invoice_id?: string; readonly payment_hash?: string; readonly amount_msats?: number; readonly transaction_state?: string; readonly workflow_state?: string; readonly [key: string]: unknown; } type CheckoutPhase = "invoice_created" | "verifying" | "settled" | "expired" | "failed" | "cancelled"; type SwapProviderState = "creating_provider_order" | "awaiting_deposit" | "confirming" | "exchanging" | "paying_invoice" | "completed" | "expired" | "refund_required" | "refund_pending" | "refunded" | "attention" | "failed"; /** * Provider-reported fiat equivalents of both sides of a swap. `pay_in_fiat` is the * value of the crypto the payer must send; `payout_fiat` is the cart total delivered * to the merchant. Their gap is the swap fee the payer absorbs. */ interface CheckoutInvoiceSwapFee { readonly currency: string; readonly pay_in_fiat: string; readonly payout_fiat: string; } interface CheckoutInvoiceSwapSnapshot { readonly attempt_id?: string; readonly provider: string; readonly provider_order_id?: string; readonly pay_in_asset: string; readonly deposit_address: string; readonly deposit_memo?: string; readonly deposit_amount: string; readonly provider_state: SwapProviderState; readonly provider_expires_at: number; readonly deposit_tx_id?: string; readonly payout_tx_id?: string; readonly refund_address?: string; readonly refund_tx_id?: string; readonly attention?: boolean; readonly attention_reason?: string; readonly refund_reason?: string; readonly deposit_received_amount?: string; readonly refund_amount?: string; readonly fee?: CheckoutInvoiceSwapFee; } /** * Formatted fee breakout for the deposit panel, explaining why the payer sends more * than the cart total. All figures are display-ready strings. `cartTotal` is * always fiat; `youSend` and `fee` are fiat for a floating asset and token * amounts ("50.05 USDC") for a stablecoin pegged to the fee currency, where a * fiat valuation would read as the deposit amount with a typo. */ interface SwapFeeBreakdown { /** Cart total delivered to the merchant, e.g. "$10.00". */ readonly cartTotal: string; /** What the payer sends: its fiat value ("$10.59") or, for a pegged stablecoin, the deposit amount itself ("10.59 USDC"). */ readonly youSend: string; /** The swap fee absorbed by the payer (exchange spread + network fees), e.g. "$0.59" or "0.59 USDC". */ readonly fee: string; /** The fee as a percentage of the cart total, e.g. "5.9%", when computable. */ readonly feePercent?: string; } /** One value the payer has to reproduce, with the affordance that lets them. */ interface SwapCopyRow { readonly label: string; readonly value: string; /** The untruncated string a copy button writes, when it differs from `value`. */ readonly copyValue?: string; /** Render the value in a selectable field rather than a code block. */ readonly selectable: boolean; } /** * How a deposit on this rail can actually go missing, which is what decides how * loud the deposit panel should be. * * The exposure comes from the deposit ADDRESS failing to pin the chain or the * asset, never from whether the coin is native: * * - `chain_ambiguous` — the address is byte-identical on other chains, so a * withdrawal can land somewhere unreachable. Every EVM rail (`ETH_ETH`, * `USDT_ETH`, `USDC_ETH`): a `0x…` address is the same string on Ethereum, * Arbitrum, Optimism, Base, BSC and Polygon and carries nothing that says * which. A rail whose network OpenReceive cannot classify is reported here * too — an unrecognized format has no rule proving it is safe. * - `asset_only` — the address format pins the chain, but the asset is a token * on it, and every exchange's withdrawal dropdown offers that ticker on a * dozen networks (`USDT_TRON`). * - `pinned` — the address format pins the chain AND the asset is that chain's * native coin, so neither mistake is reachable (`SOL_SOL`). Sending an SPL * token to a Solana address still will not credit the order, so the panel * still states the exact amount — it just does not shout about lost funds. * * `chain_ambiguous` and `asset_only` both warrant the full alarm; they are kept * apart because they are different mistakes and a custom UI may want to say so. * Note the counter-intuitive half: `ETH_ETH` is a NATIVE coin and needs the * alarm most of anything on the list. */ type SwapDepositRisk = "chain_ambiguous" | "asset_only" | "pinned"; interface SwapDisplayModel { readonly provider: string; readonly attemptId: string; readonly payInAsset: string; readonly assetLabel: string; readonly networkLabel: string; /** * Which of the two ways a deposit is lost is reachable on this rail. Drives * `networkWarningTitle`/`networkWarning` below, and is exposed so a custom UI * can pick its own chrome without re-deriving the asset table. See * {@link SwapDepositRisk}. */ readonly depositRisk: SwapDepositRisk; /** * Deposit-panel heading. A strong alert ("Wrong currency or network = lost * funds") when `depositRisk` is anything but `pinned`, and a quiet * "Send the exact amount" when it is. A banner shown on every rail is read on * none, and the rails where it is load-bearing are the ones that pay for it. */ readonly networkWarningTitle: string; /** Exact amount + asset + network to emphasize, e.g. "15.01 USDT on the Solana network". */ readonly networkWarningEmphasis: string; /** * Full plain-text network warning (accessible / non-HTML consumers). The * lost-funds sentence is present only when `depositRisk` is not `pinned`. */ readonly networkWarning: string; readonly depositAddress: string; readonly depositMemo?: string; /** * BARE, with no asset symbol appended: it pastes into a wallet's amount field, * where "0.032664 SOL" is not a number. Join the symbol at the point of * display if a sentence needs it. */ readonly depositAmount: string; /** * Every value the payer must reproduce, as labelled rows: the deposit address, * the memo where the rail has one, and the amount. The amount is the one that * gets left out and the one that costs money — on token rails (USDT_TRON, * USDT_ETH, USDC_ETH) the QR encodes the bare address and carries NO amount, * so the payer types it off the screen, and a short send against a fixed-rate * swap order is an underpayment: `refund_required`, a refund form, and a payer * who has to come back. */ readonly copyRows: readonly SwapCopyRow[]; readonly providerStateLabel: string; readonly providerStateDetail: string; readonly state: "creating" | "deposit" | "progress" | "settled" | "expired" | "refund_required" | "refund_pending" | "refunded" | "attention" | "failed"; readonly expiresInSeconds: number; readonly countdownLabel: string; readonly qrPayload: string; /** Ready-to-render fee breakout, present when the provider reported fiat equivalents. */ readonly feeBreakdown?: SwapFeeBreakdown; readonly depositTxId?: string; readonly payoutTxId?: string; readonly refundAddress?: string; /** * Whether the refund form may be submitted. The review-then-confirm gate is * entirely client-side: OpenReceive mints no refund tokens, the server sends * none, and the confirmed request carries only reference, payment_hash, and * refund_address. */ readonly refundAllowed: boolean; /** * What to tell the payer about getting BACK to this refund screen, already * decided from whether the host said the checkout is resumable. * * `checkoutLabels.refundReturnWarning` — "Bookmark this page…" — is only true * if the checkout HAS a URL. A swap checkout that lives at one route with no * per-order path (a single-page shop, a modal) sends that payer back to an * empty checkout and their deposit is unreachable through the UI. So the * choice is made here, from one declared fact, rather than left to every host * to notice: render this string, never either label directly. */ readonly refundReturnLabel: string; /** * Whether the host declared this checkout resumable — the fact * {@link SwapDisplayModel.refundReturnLabel} was chosen from. Exposed so a UI * can render the affordance the sentence names (a copy button for the URL) * without re-deriving the decision or string-matching the label. */ readonly resumable: boolean; readonly refundTxId?: string; readonly refundReason?: string; readonly depositReceivedAmount?: string; readonly refundAmount?: string; readonly providerOrderId?: string; } interface CheckoutInvoiceSnapshot { readonly invoice_id: string; readonly invoice?: string | null; readonly rail: "lightning" | "swap" | "checkout_lock"; readonly payment_hash?: string; readonly amount_msats?: number; readonly fiat_quote?: { readonly fiat?: { readonly currency?: string; readonly value?: string; }; } | null; readonly transaction_state?: string; readonly workflow_state?: string; readonly expires_at?: number; readonly settled_at?: number; readonly swap?: CheckoutInvoiceSwapSnapshot; /** * What the payer is buying, carried through from the snapshot. Data, not a * derived label, so it survives `normalizeCheckoutState`. */ readonly description?: string; } interface CheckoutPaymentMethod { readonly pay_in_asset: string; readonly label: string; readonly network_label: string; readonly provider: string; readonly available: boolean; readonly unavailable_reason?: string; readonly unavailable_message?: string; readonly pay_amount?: string; readonly minimum_pay_amount?: string; readonly maximum_pay_amount?: string; readonly minimum_invoice_amount_msats?: number; readonly maximum_invoice_amount_msats?: number; } /** * Client-side snapshot of one Checkout (the server's `Checkout` / * the wire's `WireCheckout`), aggregated across its payment * attempts as the browser polls. Snake_case because it holds wire data * verbatim. */ interface CheckoutSnapshot { readonly checkout_id: string; readonly reference: string; readonly status: "open" | "paid" | "expired"; readonly paid_at?: number; readonly amount_msats: number; readonly fiat?: { readonly currency: string; readonly value: string; }; readonly active?: CheckoutInvoiceSnapshot; readonly invoices: readonly CheckoutInvoiceSnapshot[]; readonly payment_methods?: readonly CheckoutPaymentMethod[]; /** * What the payer is buying, in the host's own words — one display string the * host returned from `amountFor` / `amount_for`. OpenReceive owns no line * items, so this is the whole of what it carries; a richer summary is the * host's own markup (React `children`, the element's `order` slot). */ readonly description?: string; } interface CheckoutElementAttributeOptions { /** * Order id for create mode. When no checkout snapshot is supplied, the element is rendered * with this as its `reference` attribute (paired with `prefix`) and owns the whole * create/poll lifecycle itself. Ignored when a snapshot is supplied — the snapshot's * `reference` wins. */ readonly reference?: string; /** * Base path the shipped router is mounted at. Emitted as the element's `prefix` attribute * so a create-mode element (`reference` with no `invoice`) can derive its create/order * routes without spelling them out. */ readonly prefix?: string; /** * Header name the page's `` value is sent under on * every request the element makes. Emitted as the element's `csrf-header` * attribute. Default `X-CSRF-Token` (Rails, Laravel); Django reads * `X-CSRFToken`, WordPress REST reads `X-WP-Nonce`. */ readonly csrfHeader?: string; /** * Optional create-time metadata (parity with the React `` * prop): JSON-encoded onto the element's `metadata` attribute and sent with * the Lightning mint request. */ readonly metadata?: Record; readonly theme?: ResolvedTheme; readonly paymentWizard?: boolean; /** * Opt into History API URL sync to `{resumePathPrefix}/{reference}` (default `/checkout/:id`). * This controls URL mutation only; order-resume data remains a host concern. */ readonly syncUrl?: boolean; /** History API path prefix when `syncUrl` is set. Default `/checkout`. */ readonly resumePathPrefix?: string; /** * Order id from the app router (e.g. Next.js). When set, skip History API URL sync. */ readonly routeReference?: string; /** * Payment hash of a swap attempt this order already has in flight. Create * mode reopens it after prepare instead of showing the method grid; a hash * the server will not serve is ignored. */ readonly resumePaymentHash?: string; readonly resumePaymentRail?: "lightning" | "swap"; /** * Does a payer who closes this tab have a URL that brings them back? Emitted * in every mode, because the refund screen it governs shows in every mode. */ readonly resumable?: boolean; /** * Base URL of an external bolt11 decoder. Omitted (the default), the element * renders no "Decode" link and the invoice is never sent to a third party. */ readonly decodeLinkUrl?: string; /** False renders the snapshot without status polling (no POST /payments/check). */ readonly polling?: boolean; /** Status poll cadence in milliseconds; defaults to OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS. */ readonly pollIntervalMs?: number; } interface ThemeToggleElementAttributeOptions { readonly rootSelector?: string; readonly checkoutSelector?: string; readonly defaultTheme?: ThemePreference; readonly storageKey?: string; } type CheckoutElementAttributeName = (typeof OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES)[keyof typeof OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES]; type CheckoutElementAttributes = Partial>; type ThemeToggleElementAttributeName = (typeof OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES)[keyof typeof OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES]; type ThemeToggleElementAttributes = Partial>; interface CheckoutElementEventHandlers { readonly onCopy?: (event: Event) => void; readonly onOpenWallet?: (event: Event) => void; readonly onState?: (event: Event) => void; readonly onSettled?: (event: Event) => void; readonly onProviderCopy?: (event: Event) => void; readonly onStartOver?: (event: Event) => void; readonly onError?: (event: Event) => void; } type CheckoutElementListeners = Partial void>>; interface CheckoutShellOptions extends Omit, CheckoutElementEventHandlers, StoredThemeModelOptions { readonly rootSelector?: string; readonly checkoutSelector?: string; /** * When false, omit the package theme toggle and do not stamp `data-theme` on the * shell root or checkout. The checkout inherits from an ancestor `[data-theme]` * (e.g. React `ThemeScope`). Default true for standalone embeds. */ readonly themeToggle?: boolean; } interface CheckoutShellCheckoutBinding { readonly tagName: typeof OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME; readonly attributes: CheckoutElementAttributes; readonly listeners: CheckoutElementListeners; } interface CheckoutShellThemeToggleBinding { readonly tagName: typeof OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME; readonly attributes: ThemeToggleElementAttributes; } interface CheckoutShellModel { readonly theme: ThemeModel; readonly rootAttributes: CheckoutShellRootAttributes; readonly checkout: CheckoutShellCheckoutBinding; readonly themeToggle: CheckoutShellThemeToggleBinding | null; } interface CheckoutElementDocument { createElement(tagName: string): HTMLElement; } interface CreateOpenReceiveThemeToggleElementOptions extends ThemeToggleElementAttributeOptions { readonly document?: CheckoutElementDocument; } interface CreateCheckoutShellOptions extends CheckoutShellOptions { readonly document?: CheckoutElementDocument; readonly root?: ThemeAttributeTarget | null; } interface CheckoutShellElements { readonly theme: ThemeModel; readonly rootAttributes: CheckoutShellRootAttributes; readonly checkout: HTMLElement; readonly themeToggle: HTMLElement | null; } /** * The ONE derived view of a checkout: a snapshot plus a clock, flattened onto * the attempt the payer is looking at, with the phase machine's verdict and the * labels the UI prints. Produced only by `createCheckoutState`. * * It extends {@link CheckoutStateLabels}, so the labels ship with the state — * including in the `openreceive-state` CustomEvent's `detail.state`. */ interface CheckoutState extends CheckoutStateLabels { readonly checkout_id: string; readonly reference: string; readonly invoice_id: string; readonly invoice: string; readonly rail: "lightning" | "swap" | "checkout_lock"; readonly lightning_uri: string; readonly payment_hash?: string; readonly amount_msats?: number; readonly fiat_quote?: CheckoutInvoiceSnapshot["fiat_quote"]; readonly transaction_state: string; readonly workflow_state: string; readonly expires_at?: number; readonly expires_in_seconds?: number; readonly phase: CheckoutPhase; readonly settled: boolean; readonly terminal: boolean; readonly paid: boolean; readonly settled_at?: number; readonly swap?: CheckoutInvoiceSwapSnapshot; } interface CheckoutStatusModelInput { readonly phase?: CheckoutPhase; readonly waiting?: boolean; readonly expires_in_seconds?: number; } interface CheckoutStatusModel { readonly phase: CheckoutPhase; readonly waiting: boolean; readonly title: string; readonly detail: string; readonly countdownPrefix: string; readonly expires_in_seconds?: number; readonly countdownLabel?: string; } type CheckoutStatusRefresh = (reference: string) => Promise; interface RequestCheckoutOptions extends RequestCheckoutBaseOptions { /** * The snapshot already on screen — normally what {@link prepareCheckout} * returned, or the running snapshot after an earlier attempt. * * `POST /checkouts` answers with the minted bolt11 alone; it does NOT carry * the warmed `payment_methods` catalog that prepare returned. Without this, * minting Lightning ERASES the method list a picker renders from: the payer * selects Bitcoin, changes their mind, and the swap options are gone. * Passing the previous snapshot folds the mint into it, keeping * `payment_methods` and any sibling attempts. */ readonly previous?: CheckoutSnapshot; } /** * `prepareCheckout` posts only the order id — it locks the amount and lists * payment methods without minting — so there is no memo or metadata to carry. */ type PrepareCheckoutOptions = Pick; interface RequestCheckoutBaseOptions { readonly signal?: AbortSignal; /** * Base path the shipped router is mounted at (e.g. `/openreceive`). The create and * prepare routes are derived from it — see {@link checkoutRoutes}. It is required * because it is the only URL input: there is no per-route override. */ readonly prefix: string; readonly reference: string; readonly fetch?: typeof globalThis.fetch; readonly headers?: Readonly>; /** * Header name the page's `` value is sent under. * Default `X-CSRF-Token` (Rails, Laravel); Django reads `X-CSRFToken`, * WordPress REST reads `X-WP-Nonce`. The meta tag name itself is fixed. */ readonly csrfHeader?: string; readonly memo?: string; readonly metadata?: Record; } interface CreateOpenReceiveStatusFetcherOptions { /** * Base path the shipped router is mounted at. The fetcher polls * `${prefix}/payments/check` and reads live swap state from * `${prefix}/swaps/status` — see {@link checkoutRoutes}. */ readonly prefix: string; readonly snapshot: CheckoutSnapshot; readonly fetch?: typeof globalThis.fetch; readonly headers?: Readonly>; /** Header name the page's `` is sent under; default `X-CSRF-Token`. */ readonly csrfHeader?: string; } interface CheckoutWatcherOptions { readonly snapshot: CheckoutSnapshot; readonly refreshStatus?: CheckoutStatusRefresh; readonly pollIntervalMs?: number; /** Clock returning unix **seconds** ({@link UnixSeconds}), not milliseconds. */ readonly now?: () => UnixSeconds; readonly setInterval?: typeof globalThis.setInterval; readonly clearInterval?: typeof globalThis.clearInterval; readonly logger?: BrowserLoggerOption; readonly onState: (state: CheckoutState) => void; readonly onSnapshot?: (snapshot: CheckoutSnapshot) => void; readonly onError?: (error: unknown) => void; } interface CheckoutControllerOptions extends Omit { readonly onState?: (state: CheckoutState) => void; /** * Base path the shipped router is mounted at. Omitted, the controller does no * status polling of its own — pass `refreshStatus` instead, or nothing at all * to render a snapshot without polling. */ readonly prefix?: string; /** * False renders the snapshot without a status fetcher of its own. `prefix` * still names the mount, so the swap-refund calls keep working — polling and * "where the routes live" are two questions. */ readonly polling?: boolean; readonly fetch?: typeof globalThis.fetch; readonly statusHeaders?: Readonly>; /** * Header name the page's `` is sent under, on the * status poll and the swap refund calls alike. Default `X-CSRF-Token`. */ readonly csrfHeader?: string; readonly clipboard?: Pick; readonly open?: (uri: string) => void; } /** * The two-step swap refund, and the staging that makes it survive polling. The * controller implements it; a renderer that is handed one (React's * `PaymentWizard`) takes exactly this much of it. */ interface SwapRefundStaging { /** * Step one: post `/swaps/status` and hold the address the payer typed so the * panel can show it back for confirmation. It touches no refund route — * nothing is submitted until {@link confirmSwapRefund}. * * The staged address is folded into every later snapshot, so polling cannot * wipe what the payer is reviewing. `attemptId` is * `SwapDisplayModel.attemptId`; the payment hash is resolved from the * snapshot already in hand. */ stageSwapRefund(options: { readonly attemptId: string; readonly refundAddress: string; }): Promise; /** Step two: the only call that posts `/swaps/refunds`. */ confirmSwapRefund(options: { readonly attemptId: string; readonly refundAddress: string; }): Promise; /** * Drop the staged address. The payer leaving the swap for Lightning is the one * exit that is not a submitted refund. */ clearSwapRefundStaging(): void; } interface CheckoutController extends SwapRefundStaging { start(): CheckoutState; stop(): void; getState(): CheckoutState | undefined; reloadState(): Promise; /** * Stop all timers and mark the checkout `cancelled`: the returned state (and * every later `getState()`) carries the terminal `cancelled` phase. */ cancel(): CheckoutState; copyInvoice(): Promise; openWallet(): string; } interface CreateCheckoutStateOptions { /** * Unix timestamp in **seconds** ({@link UnixSeconds}) the expiry clock is * measured against; defaults to the current time. Milliseconds * (`Date.now()`) throw a RangeError — see the type. */ readonly now?: UnixSeconds; readonly logger?: BrowserLoggerOption; /** * How this state was produced. Controls which browser log events fire: * - `create` (default): `checkout.state.created` * - `refresh`: `checkout.state.refreshed` plus `swap.state.changed` when swap fields move * - `countdown`: no log (avoids per-second spam from the expiry ticker) */ readonly source?: "create" | "refresh" | "countdown"; /** Prior checkout state; used with `source: "refresh"` to emit swap transition audits. */ readonly previousState?: CheckoutState; } type PaymentMethod = "bitcoin"; type ThemePreference = "light" | "dark" | "system"; type ResolvedTheme = "light" | "dark"; interface PaymentMethodOption { readonly id: PaymentMethod; readonly title: string; readonly detail: string; } interface ParseOpenReceiveOptionalIntegerOptions { readonly label?: string; } interface ThemeModelOptions { readonly systemDark?: boolean; } interface ThemeStorageOptions { readonly storage?: Storage; readonly storageKey?: string; } interface ReadThemePreferenceOptions extends ThemeStorageOptions { readonly defaultTheme?: ThemePreference; } interface StoredThemeModelOptions extends ReadThemePreferenceOptions, ThemeModelOptions { } interface ThemeAttributeTarget { getAttribute(name: string): string | null; setAttribute(name: string, value: string): void; } interface ThemeLabelTarget { textContent: string | null; } interface ThemeControlTargets { readonly root?: ThemeAttributeTarget | null; readonly checkout?: ThemeAttributeTarget | null; readonly toggle?: ThemeLabelTarget | null; } interface ThemeModel { readonly theme: ThemePreference; readonly resolvedTheme: ResolvedTheme; readonly nextTheme: ThemePreference; readonly toggleLabel: string; readonly attributes: { readonly "data-theme": ResolvedTheme; readonly "data-openreceive-theme": ResolvedTheme; }; readonly checkoutElementAttributes: { readonly theme: ResolvedTheme; }; } /** * What the Vue/Svelte/Angular shell `
` carries: the stylesheet scope * marker always (see OPENRECEIVE_STYLE_ROOT_ATTRIBUTE in dom-contract.ts), the * theme stamp only when the shell owns the theme. */ type CheckoutShellRootAttributes = Partial & { readonly "data-openreceive-root": ""; }; interface PaymentWizardSelection { readonly selectedMethod: PaymentMethod | null; readonly selectedBitcoinRoute: string | null; } type PaymentWizardSelectionAction = { readonly type: "select_method"; readonly method: PaymentMethod; } | { readonly type: "change_method"; } | { readonly type: "change_route"; } | { readonly type: "select_route"; readonly route: string; }; interface PaymentWizardState { readonly selectedRouteId: string | null; readonly routes: readonly PaymentWizardRoute[]; } interface PaymentWizardModel { readonly selection: PaymentWizardSelection; readonly wizard: PaymentWizardState; readonly routeAssets: readonly AssetIndexEntry[]; readonly selectedRoute: string | null; } interface PaymentWizardControllerOptions { readonly selection?: PaymentWizardSelection; readonly onSelection?: (selection: PaymentWizardSelection) => void; } interface PaymentWizardController { getSelection(): PaymentWizardSelection; getModel(): PaymentWizardModel; update(action: PaymentWizardSelectionAction): PaymentWizardSelection; selectMethod(method: PaymentMethod): PaymentWizardSelection; changeMethod(): PaymentWizardSelection; selectRoute(route: string): PaymentWizardSelection; } interface WizardRouteAssetDisplay { readonly id: string; readonly label: string; readonly subtitle: string; /** The icon as a `data:` URI. */ readonly icon: string; /** The key behind `icon`, into `paymentIconSvgs` for a renderer drawing it inline. */ readonly iconId: PaymentIconId; readonly selected: boolean; } interface WizardProviderTutorialDisplay { readonly index: number; readonly path: string; /** * The screenshot as a `data:` URI, or `undefined` until * `loadPayTutorialImages()` has resolved (the caption renders alone until then). */ readonly image: string | undefined; readonly caption: string; } interface WizardProviderDisplay { readonly id: string; readonly name: string; readonly kind: string; readonly url: string; /** The wallet logo as a `data:` URI. */ readonly icon: string; readonly tutorials: readonly WizardProviderTutorialDisplay[]; readonly copyLabel: string; readonly copiedLabel: string; readonly openLabel: string; } interface WizardRouteDisplay { readonly key: string; readonly title: string; readonly subtitle: string; /** * The providers to draw — every one the route has, or the first * `providerPreviewLimit` of them. */ readonly providers: readonly WizardProviderDisplay[]; /** * How many the route has in total, before any preview limit. The registry * carries ~37 wallets for Lightning, so a host that renders them beside a QR * needs a limit and a "show all N" affordance; this is the N, and * {@link WizardRouteDisplay.providers}.length is what it is showing. */ readonly providerCount: number; } /** * One display row for post-settlement transaction details. Values are already * formatted for UI; `copyValue` is the full string when the display value is truncated. * Never includes NWC secrets — those are not part of checkout public state. * Optional `href` is a block-explorer or Lightning invoice decode link. */ interface TransactionDetailRow { readonly label: string; readonly value: string; readonly copyValue?: string; readonly href?: string; readonly hrefLabel?: string; } interface TransactionDetailsInput { readonly reference?: string; readonly checkout_id?: string; readonly invoice_id?: string; readonly invoice?: string | null; readonly rail?: "lightning" | "swap" | "checkout_lock"; readonly payment_hash?: string; readonly amount_msats?: number; readonly fiat_quote?: CheckoutInvoiceSnapshot["fiat_quote"]; readonly transaction_state?: string; readonly workflow_state?: string; readonly expires_at?: number; readonly settled_at?: number; readonly swap?: CheckoutInvoiceSwapSnapshot; /** * Base URL of a host-chosen bolt11 decoder. Omitted (the default), the * Lightning invoice row carries no decode link and the invoice is never * handed to a third party. */ readonly decodeLinkUrl?: string; } declare function assertDisplayInvoice(invoice: string): void; declare function createLightningUri(invoice: string): string; declare class BrowserRequestError extends Error { readonly status: number; readonly code?: string; readonly retryable?: boolean; readonly retryAfterSeconds?: number; constructor(message: string, options: { readonly status: number; readonly code?: string; readonly retryable?: boolean; readonly retryAfterSeconds?: number; }); } declare function requestCheckout(options: RequestCheckoutOptions): Promise; /** * Lock the host order amount and load payment methods without minting Lightning. * Bitcoin selection later calls {@link requestCheckout} to mint (or reuse) a bolt11. */ declare function prepareCheckout(options: PrepareCheckoutOptions): Promise; declare function createStatusFetcher(options: CreateOpenReceiveStatusFetcherOptions): CheckoutStatusRefresh; declare function createQrSvg(invoice: string, options?: QrOptions): Promise; declare function createQrPayloadSvg(payload: string, options?: QrOptions): Promise; declare function createQrPngDataUrl(invoice: string, options?: QrOptions): Promise; declare function copyInvoice(options: CopyInvoiceOptions): Promise; /** * Hand the invoice to the payer's wallet as a `lightning:` URI, and return the * URI. **Touch devices.** * * The default path is `location.assign` on the CURRENT window — the right * primitive for a custom-scheme deep link on a phone, and the wrong thing * anywhere else. With no registered `lightning:` handler the call does nothing * visible; with one, it navigates the payer off a checkout that is still * polling `/payments/check`. Pass `open` to route the URI somewhere that is not * the checkout window. * * This is why the shipped `` renders no wallet button of its own and * exposes `components.OpenWalletButton` as an opt-in slot instead: a desktop * payer is never sent to a handler that does not exist, next to the QR code * that IS the desktop payment path. A custom UI drawing its own button owns * that decision — see docs/guides/headless-checkout.md. */ declare function openWallet(options: OpenWalletOptions): string; /** * A QR that follows a changing payload, without every host rewriting the same * effect. * * {@link createQrSvg} and {@link createQrPayloadSvg} are ASYNC, and that is the * trap: `dangerouslySetInnerHTML={{ __html: createQrSvg(invoice) }}` type-checks * (React types `__html` as `string | TrustedHTML`, and `TrustedHTML` is an empty * interface every object satisfies) and paints the literal text * "[object Promise]" inside the QR box. Resolving it by hand then needs the * other half nobody writes the first time: a slow encode that lands AFTER the * payload changed must not paint the old QR over the new one. * * So: call `show`/`showPayload` whenever the payload changes and render what * `onValue` last handed you. Only the newest call can publish — an earlier * encode still in flight is dropped, resolved or rejected. `stop()` drops the * one in flight, for a host going away. Same shape as * {@link createTickingValueController}: DOM-free, framework-free, one * implementation instead of one per renderer. */ interface QrSvgControllerOptions { /** The newest encoded SVG. Not called for a superseded or stopped encode. */ onValue(svg: string): void; /** Encode failures, on the same terms. */ onError?(error: unknown): void; readonly encoder?: QrEncoder; readonly width?: number; } interface QrSvgController { /** Encode a bolt11, as the `lightning:` URI a wallet expects. */ show(invoice: string): void; /** Encode a payload verbatim — a swap deposit URI, say. */ showPayload(payload: string): void; /** Publish nothing further; the encode in flight is abandoned. */ stop(): void; } declare function createQrSvgController(options: QrSvgControllerOptions): QrSvgController; declare function createCheckoutController(options: CheckoutControllerOptions): CheckoutController; /** * Guest checkout resume helpers for no-account content sites. * * Pattern: * - Put the public `reference` in the URL (`/checkout/:reference`) so refresh/share works. * - Let the host authorize access to the order using its normal session or guest-order policy. * - Mirror an optional host order summary in sessionStorage for instant same-tab restore; * use the host-supplied `fetchOrder` when storage is empty. * */ interface GuestCheckoutResumeOptions { /** * URL path prefix before the order id. Default `"/checkout"` → `/checkout/:reference`. * Leading/trailing slashes are normalized. */ readonly pathPrefix?: string; /** sessionStorage key prefix for host order summaries (required so hosts do not collide). */ readonly storageKeyPrefix: string; /** Extract the public order id used as the storage/URL key. */ readonly referenceOf: (order: TOrder) => string; /** Validate a value from storage or a fetch body as a host order. */ readonly parseOrder: (value: unknown) => TOrder | undefined; /** * Load an order when sessionStorage misses (new tab / shared link). * Return `undefined` for missing or unauthorized orders. */ readonly fetchOrder?: (reference: string) => Promise; /** Path to push when leaving a checkout URL. Default `"/"`. */ readonly homePath?: string; } interface GuestCheckoutResumeController { /** Normalized path prefix including a leading slash, e.g. `"/checkout"`. */ readonly pathPrefix: string; checkoutPath(reference: string): string; /** Parse `/checkout/:reference` from a pathname. Returns undefined when not a resume URL. */ parseReference(pathname: string): string | undefined; rememberOrder(order: TOrder): void; readRememberedOrder(reference: string): TOrder | undefined; /** Forget one order, or every order under this storage prefix when `reference` is omitted. */ forgetOrder(reference?: string): void; /** Push the checkout path when not already there (History API / SPAs). */ enterCheckout(reference: string): void; /** Return to `homePath` when the current location is a checkout resume URL. */ leaveCheckout(): void; /** sessionStorage first, then optional `fetchOrder`. */ loadOrderForResume(reference: string): Promise; } /** * Create a host-owned guest resume controller. OpenReceive does not invent a host session — * this is the reusable URL + sessionStorage glue so demos (and apps) do not copy-paste it. */ declare function createGuestCheckoutResume(options: GuestCheckoutResumeOptions): GuestCheckoutResumeController; /** * Push `/checkout/:reference` (or a custom path prefix) via the History API when not already * there. Used by `` and hosts that sync the URL after creating an order. * No-ops when `routeReference` is provided (app router already owns the URL). */ declare function enterCheckoutResumePath(reference: string, options?: { readonly pathPrefix?: string; /** When set, skip History API sync (Next.js / file-based routes own the URL). */ readonly routeReference?: string; }): void; /** * The URL a resumable checkout tells the payer to copy, or `undefined` off a * browser. * * `checkoutLabels.refundReturnWarning` says "Bookmark this page, or copy its * URL", and a sentence that names an affordance should be next to one. Both * renderers read it through this function so the refund screens cannot disagree * about what "its URL" means. */ declare function currentCheckoutUrl(): string | undefined; /** * Guest resume fetch for a host-owned order endpoint. OpenReceive ships no order-read route. * Pass the result as `fetchOrder` to {@link createGuestCheckoutResume}. */ declare function createGuestOrderFetcher(options: { readonly parseOrder: (value: unknown) => TOrder | undefined; /** * Build the URL of the HOST APPLICATION's own order endpoint (e.g. `/orders/:id`). * Nothing here is an OpenReceive route: the mounted router's routes all come from * `prefix` (see ./routes.ts), and it serves no order-read endpoint at all. */ readonly hostOrderUrl: (reference: string) => string; readonly fetch?: typeof globalThis.fetch; }): (reference: string) => Promise; /** The payer-facing status: exactly {@link TransactionSettlementStatus}, derived from the server's verdict and the expiry clock. */ type Status = TransactionSettlementStatus; interface StatusInvoiceLike { readonly transaction_state?: string; readonly expires_at?: number | string | null; } /** * @param options.now Unix timestamp in **seconds** ({@link UnixSeconds}) to * compare `expires_at` against; defaults to the current time. Milliseconds * (`Date.now()`) throw a RangeError rather than reading every invoice as * expired. */ declare function deriveStatus(invoice: StatusInvoiceLike, options?: { readonly now?: UnixSeconds; }): Status; export { type CheckoutPhase as $, type ThemeToggleElementAttributeOptions as A, type BrowserLoggerOption as B, type CheckoutInvoiceSnapshot as C, type ThemeToggleElementAttributes as D, type StoredThemeModelOptions as E, type ThemeModel as F, type ThemeModelOptions as G, type ReadThemePreferenceOptions as H, type ThemeControlTargets as I, type ThemeStorageOptions as J, type PaymentWizardControllerOptions as K, type PaymentWizardController as L, type PaymentWizardSelection as M, type PaymentWizardModel as N, type WizardRouteDisplay as O, type PaymentIconId as P, type PaymentWizardSelectionAction as Q, type ResolvedTheme as R, type SwapDisplayModel as S, type ThemePreference as T, type UnixSeconds as U, type BrowserLogContext as V, type WizardRouteAssetDisplay as W, type BrowserLogger as X, BrowserRequestError as Y, type CheckoutController as Z, type CheckoutControllerOptions as _, type ParseOpenReceiveOptionalIntegerOptions as a, type OpenWalletOptions as a$, type CheckoutShellRootAttributes as a0, type CheckoutStatusRefresh as a1, OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES as a2, OPENRECEIVE_CHECKOUT_DATA_SELECTORS as a3, OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES as a4, OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS as a5, OPENRECEIVE_CHECKOUT_ELEMENT_PARTS as a6, OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS as a7, OPENRECEIVE_CHECKOUT_ELEMENT_SLOTS as a8, OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME as a9, createCheckoutProviderCopyEvent as aA, createCheckoutStateEvent as aB, createQrPayloadSvg as aC, createQrSvg as aD, createQrSvgController as aE, createStatusFetcher as aF, createThemeChangeEvent as aG, currentCheckoutUrl as aH, deriveCheckoutStateLabels as aI, deriveStatus as aJ, enterCheckoutResumePath as aK, escapeHtml as aL, formatAmountCaption as aM, formatDepositAmount as aN, formatFiatAmount as aO, formatMsats as aP, formatSwapLimit as aQ, formatUnixTime as aR, openWallet as aS, paymentIconSvgs as aT, prepareCheckout as aU, requestCheckout as aV, type BrowserLogLevel as aW, type BrowserLogEntry as aX, type CopyInvoiceOptions as aY, type GuestCheckoutResumeController as aZ, type GuestCheckoutResumeOptions as a_, OPENRECEIVE_COPY_FEEDBACK_MS as aa, OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS as ab, OPENRECEIVE_DEFAULT_PREFIX as ac, OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES as ad, OPENRECEIVE_PAYMENT_WIZARD_SELECTORS as ae, OPENRECEIVE_PROVIDER_PREVIEW_LIMIT as af, OPENRECEIVE_STYLE_ROOT_ATTRIBUTE as ag, OPENRECEIVE_STYLE_ROOT_SELECTOR as ah, OPENRECEIVE_THEME_STORAGE_KEY as ai, OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES as aj, OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS as ak, OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS as al, OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS as am, OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME as an, type QrEncoder as ao, type QrSvgController as ap, type QrSvgControllerOptions as aq, type Status as ar, type SwapCopyRow as as, type SwapRefundStaging as at, type WizardProviderDisplay as au, assertDisplayInvoice as av, copyInvoice as aw, createCheckoutActionEvent as ax, createCheckoutController as ay, createCheckoutErrorEvent as az, type PaymentMethod as b, type PrepareCheckoutOptions as b0, type QrOptions as b1, type RequestCheckoutOptions as b2, type StatusInvoiceLike as b3, createGuestCheckoutResume as b4, createGuestOrderFetcher as b5, createLightningUri as b6, createQrPngDataUrl as b7, type PaymentMethodOption as c, type TickingValueOptions as d, type TickingValueController as e, type TransientFeedbackOptions as f, type TransientFeedbackController as g, type CheckoutSnapshot as h, type SwapDepositRisk as i, type CheckoutState as j, type TransactionDetailsInput as k, type TransactionDetailRow as l, type CreateCheckoutStateOptions as m, type CheckoutStatusModelInput as n, type CheckoutStatusModel as o, type CheckoutPaymentMethod as p, type ThemeAttributeTarget as q, type CheckoutElementAttributes as r, type CheckoutElementAttributeOptions as s, type CheckoutElementEventHandlers as t, type CheckoutElementListeners as u, type CreateCheckoutShellOptions as v, type CheckoutShellElements as w, type CheckoutShellOptions as x, type CheckoutShellModel as y, type CreateOpenReceiveThemeToggleElementOptions as z };