@openreceive/browser 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -0
- package/dist/chunk-V7C55QB2.js +2996 -0
- package/dist/headless.d.ts +799 -0
- package/dist/headless.js +932 -0
- package/dist/index.d.ts +32 -4
- package/dist/index.js +32 -2
- package/dist/status-CLCX5lfx.d.ts +963 -0
- package/dist/styles.css +3 -759
- package/package.json +57 -15
- package/dist/assets/icons/bank.svg +0 -12
- package/dist/assets/icons/bnb.svg +0 -1
- package/dist/assets/icons/card.svg +0 -14
- package/dist/assets/icons/doge.svg +0 -1
- package/dist/assets/pay_tutorials/boltz-1.webp +0 -0
- package/dist/assets/pay_tutorials/boltz-2.webp +0 -0
- package/dist/assets/pay_tutorials/cashapp-1.webp +0 -0
- package/dist/assets/pay_tutorials/cashapp-2.webp +0 -0
- package/dist/assets/pay_tutorials/cashapp-3.webp +0 -0
- package/dist/assets/pay_tutorials/cashapp-4.webp +0 -0
- package/dist/assets/pay_tutorials/cashapp-5.webp +0 -0
- package/dist/assets/pay_tutorials/cashapp-6.webp +0 -0
- package/dist/assets/pay_tutorials/coinbase-1.webp +0 -0
- package/dist/assets/pay_tutorials/coinbase-2.webp +0 -0
- package/dist/assets/pay_tutorials/fixedfloat-1.webp +0 -0
- package/dist/assets/pay_tutorials/fixedfloat-2.webp +0 -0
- package/dist/assets/pay_tutorials/kraken-1.webp +0 -0
- package/dist/assets/pay_tutorials/kraken-2.webp +0 -0
- package/dist/assets/pay_tutorials/kraken-3.webp +0 -0
- package/dist/assets/pay_tutorials/kraken-4.webp +0 -0
- package/dist/assets/pay_tutorials/strike-1.webp +0 -0
- package/dist/assets/pay_tutorials/strike-2.webp +0 -0
- package/dist/assets/pay_tutorials/strike-3.webp +0 -0
- package/dist/assets/pay_tutorials/strike-4.webp +0 -0
- package/dist/assets/provider-icons/aqua.png +0 -0
- package/dist/assets/provider-icons/belo.png +0 -0
- package/dist/assets/provider-icons/binance.png +0 -0
- package/dist/assets/provider-icons/bipa.png +0 -0
- package/dist/assets/provider-icons/bitfinex.png +0 -0
- package/dist/assets/provider-icons/bitget.png +0 -0
- package/dist/assets/provider-icons/bitnob.png +0 -0
- package/dist/assets/provider-icons/bitso.png +0 -0
- package/dist/assets/provider-icons/bity.png +0 -0
- package/dist/assets/provider-icons/blink.png +0 -0
- package/dist/assets/provider-icons/bluewallet.png +0 -0
- package/dist/assets/provider-icons/boltz.png +0 -0
- package/dist/assets/provider-icons/bringin.png +0 -0
- package/dist/assets/provider-icons/bullbitcoin.png +0 -0
- package/dist/assets/provider-icons/cakewallet.png +0 -0
- package/dist/assets/provider-icons/cashapp.png +0 -0
- package/dist/assets/provider-icons/changenow.png +0 -0
- package/dist/assets/provider-icons/chivo.png +0 -0
- package/dist/assets/provider-icons/coinbase.png +0 -0
- package/dist/assets/provider-icons/coincorner.png +0 -0
- package/dist/assets/provider-icons/fixedfloat.png +0 -0
- package/dist/assets/provider-icons/getalby.png +0 -0
- package/dist/assets/provider-icons/kraken.png +0 -0
- package/dist/assets/provider-icons/kryptex.png +0 -0
- package/dist/assets/provider-icons/kucoin.png +0 -0
- package/dist/assets/provider-icons/manifest.json +0 -207
- package/dist/assets/provider-icons/mtpelerin.png +0 -0
- package/dist/assets/provider-icons/muun.png +0 -0
- package/dist/assets/provider-icons/okcoin.png +0 -0
- package/dist/assets/provider-icons/okx.png +0 -0
- package/dist/assets/provider-icons/phoenix.png +0 -0
- package/dist/assets/provider-icons/pouch.png +0 -0
- package/dist/assets/provider-icons/ripio.png +0 -0
- package/dist/assets/provider-icons/river.png +0 -0
- package/dist/assets/provider-icons/rizful.png +0 -0
- package/dist/assets/provider-icons/shakepay.png +0 -0
- package/dist/assets/provider-icons/sideshift.png +0 -0
- package/dist/assets/provider-icons/simpleswap.png +0 -0
- package/dist/assets/provider-icons/speed.png +0 -0
- package/dist/assets/provider-icons/strike.png +0 -0
- package/dist/assets/provider-icons/trocador.png +0 -0
- package/dist/assets/provider-icons/walletofsatoshi.png +0 -0
- package/dist/assets/provider-icons/zeus.png +0 -0
- package/dist/country-map.d.ts +0 -5
- package/dist/country-map.js +0 -17
- package/dist/internal.d.ts +0 -834
- package/dist/internal.js +0 -2615
- package/dist/pay-tutorials.d.ts +0 -1
- package/dist/pay-tutorials.js +0 -1
- package/dist/provider-icons.d.ts +0 -1
- package/dist/provider-icons.js +0 -1
- package/dist/qrcode.d.ts +0 -11
- package/dist/status.d.ts +0 -9
- package/dist/status.js +0 -25
|
@@ -0,0 +1,963 @@
|
|
|
1
|
+
import { PaymentWizardRoute, AssetIndexEntry } from '@openreceive/provider-data';
|
|
2
|
+
import { TransactionSettlementStatus } from '@openreceive/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Trim insignificant trailing zeros from a decimal crypto amount for display,
|
|
6
|
+
* e.g. "12.25900000" -> "12.259" and "5.000" -> "5". Only fractional digits are
|
|
7
|
+
* stripped: integer amounts like "100" keep their zeros, and non-numeric input
|
|
8
|
+
* is returned unchanged.
|
|
9
|
+
*/
|
|
10
|
+
declare function formatDepositAmount(amount: string): string;
|
|
11
|
+
declare function escapeHtml(value: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Throws on a non-amount, and every caller lets it: wire construction, amount
|
|
14
|
+
* validation, and the display sites share this formatter, and a malformed
|
|
15
|
+
* amount from our own server is a bug that must surface, not be smoothed over.
|
|
16
|
+
*/
|
|
17
|
+
declare function formatMsats(amountMsats: number): string;
|
|
18
|
+
declare function formatFiatAmount(fiat: {
|
|
19
|
+
readonly currency?: string;
|
|
20
|
+
readonly value?: string;
|
|
21
|
+
} | null | undefined): string | undefined;
|
|
22
|
+
/** Combined QR caption, e.g. `19,174 sats / $12.00 US`. */
|
|
23
|
+
declare function formatAmountCaption(options: {
|
|
24
|
+
readonly amountLabel?: string;
|
|
25
|
+
readonly fiatLabel?: string;
|
|
26
|
+
readonly fiatCurrency?: string;
|
|
27
|
+
}): string | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Renders an invoice-side (Lightning receive) msat limit as a short amount for
|
|
30
|
+
* display under a disabled swap asset, e.g. "$10.00". Converts to the
|
|
31
|
+
* checkout's own fiat currency using its rate; falls back to a sats figure when
|
|
32
|
+
* the checkout is sats/BTC-denominated or no usable rate is available.
|
|
33
|
+
*
|
|
34
|
+
* Minimums ceil and maximums floor to the display scale so the note never
|
|
35
|
+
* understates a floor or overstates a ceiling.
|
|
36
|
+
*/
|
|
37
|
+
declare function formatSwapLimit(checkout: {
|
|
38
|
+
readonly amount_msats: number;
|
|
39
|
+
readonly fiat?: {
|
|
40
|
+
readonly currency: string;
|
|
41
|
+
readonly value: string;
|
|
42
|
+
};
|
|
43
|
+
}, limitMsats: number | undefined, rounding?: "ceil" | "floor"): string | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* ECHOES rather than throws on a value it cannot render — the one place this
|
|
46
|
+
* rule reads differently from the amount rule above, deliberately.
|
|
47
|
+
* `formatMsats` throws because wire construction and amount validation share
|
|
48
|
+
* it and a bad amount there must surface; nothing constructs or validates
|
|
49
|
+
* anything through this formatter, so degrading to the raw value is its
|
|
50
|
+
* contract.
|
|
51
|
+
*/
|
|
52
|
+
declare function formatUnixTime(seconds: number): string;
|
|
53
|
+
/** The payer-facing labels a {@link CheckoutState} carries next to its raw fields. */
|
|
54
|
+
interface CheckoutStateLabels {
|
|
55
|
+
readonly amountLabel?: string;
|
|
56
|
+
readonly fiatLabel?: string;
|
|
57
|
+
readonly paymentHashLabel?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* THE label rule — one copy, applied everywhere a checkout is shown.
|
|
61
|
+
*
|
|
62
|
+
* `normalizeCheckoutState` runs it so every CheckoutState already carries its
|
|
63
|
+
* labels, and the elements renderer runs it over raw attributes in create mode,
|
|
64
|
+
* before there is an attempt to build a state from. It replaces the label half
|
|
65
|
+
* of the deleted `createCheckoutDisplayModel`; the other half (the `lightning:`
|
|
66
|
+
* URI) belongs to `createCheckoutState`, which is the only place that knows the
|
|
67
|
+
* rail.
|
|
68
|
+
*
|
|
69
|
+
* `transactionStateLabel` is deliberately NOT here: it was a verbatim copy of
|
|
70
|
+
* `transaction_state`, which the state already carries, and nothing read it.
|
|
71
|
+
*/
|
|
72
|
+
declare function deriveCheckoutStateLabels(source: {
|
|
73
|
+
readonly amount_msats?: number;
|
|
74
|
+
readonly fiat_quote?: {
|
|
75
|
+
readonly fiat?: {
|
|
76
|
+
readonly currency?: string;
|
|
77
|
+
readonly value?: string;
|
|
78
|
+
};
|
|
79
|
+
} | null;
|
|
80
|
+
readonly payment_hash?: string;
|
|
81
|
+
}): CheckoutStateLabels;
|
|
82
|
+
|
|
83
|
+
declare const OPENRECEIVE_THEME_STORAGE_KEY: "openreceive.theme";
|
|
84
|
+
declare const OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS: 3000;
|
|
85
|
+
/**
|
|
86
|
+
* Default base path the shipped OpenReceive router is mounted at. When a developer passes
|
|
87
|
+
* only an order id (React `<Checkout reference>` / `<openreceive-checkout reference>`), this is
|
|
88
|
+
* the prefix every route is derived from — see `checkoutRoutes` in ./routes.ts. It is
|
|
89
|
+
* the only URL input the checkout components accept.
|
|
90
|
+
*/
|
|
91
|
+
declare const OPENRECEIVE_DEFAULT_PREFIX: "/openreceive";
|
|
92
|
+
declare const OPENRECEIVE_COPY_FEEDBACK_MS: 1800;
|
|
93
|
+
declare const OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME: "openreceive-checkout";
|
|
94
|
+
declare const OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME: "openreceive-theme-toggle";
|
|
95
|
+
declare const OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS: {
|
|
96
|
+
readonly copy: "openreceive-copy";
|
|
97
|
+
readonly openWallet: "openreceive-open-wallet";
|
|
98
|
+
readonly state: "openreceive-state";
|
|
99
|
+
readonly settled: "openreceive-settled";
|
|
100
|
+
readonly providerCopy: "openreceive-provider-copy";
|
|
101
|
+
readonly startOver: "openreceive-start-over";
|
|
102
|
+
readonly error: "openreceive-error";
|
|
103
|
+
};
|
|
104
|
+
declare const OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS: {
|
|
105
|
+
readonly change: "openreceive-theme-change";
|
|
106
|
+
};
|
|
107
|
+
declare const OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES: {
|
|
108
|
+
readonly root: "data-openreceive-wizard";
|
|
109
|
+
readonly breadcrumb: "data-or-breadcrumb";
|
|
110
|
+
readonly method: "data-or-method";
|
|
111
|
+
readonly route: "data-or-route";
|
|
112
|
+
readonly swapStart: "data-or-swap-start";
|
|
113
|
+
readonly swapBack: "data-or-swap-back";
|
|
114
|
+
readonly swapQr: "data-or-swap-qr";
|
|
115
|
+
readonly swapCopy: "data-or-swap-copy";
|
|
116
|
+
readonly swapCopyLabel: "data-or-swap-copy-label";
|
|
117
|
+
readonly swapSelectAll: "data-or-swap-select-all";
|
|
118
|
+
readonly swapNetwork: "data-or-swap-network";
|
|
119
|
+
readonly swapNetworkValue: "data-or-swap-network-value";
|
|
120
|
+
readonly pickerSelect: "data-or-picker-select";
|
|
121
|
+
readonly pickerContinue: "data-or-picker-continue";
|
|
122
|
+
readonly swapRefundForm: "data-or-swap-refund-form";
|
|
123
|
+
readonly swapRefundAddress: "data-or-swap-refund-address";
|
|
124
|
+
readonly swapRefundAllowed: "data-or-swap-refund-allowed";
|
|
125
|
+
readonly swapRefundConfirm: "data-or-swap-refund-confirm";
|
|
126
|
+
readonly swapRefundPayInAsset: "data-or-swap-refund-pay-in-asset";
|
|
127
|
+
readonly swapRefundNetworkLabel: "data-or-swap-refund-network-label";
|
|
128
|
+
readonly swapRefundError: "data-or-swap-refund-error";
|
|
129
|
+
readonly providerCopy: "data-or-provider-copy";
|
|
130
|
+
readonly providerTutorial: "data-or-provider-tutorial";
|
|
131
|
+
readonly providerTutorialIndex: "data-or-provider-tutorial-index";
|
|
132
|
+
};
|
|
133
|
+
declare const OPENRECEIVE_PAYMENT_WIZARD_SELECTORS: {
|
|
134
|
+
readonly root: "[data-openreceive-wizard]";
|
|
135
|
+
readonly breadcrumb: "[data-or-breadcrumb]";
|
|
136
|
+
readonly method: "[data-or-method]";
|
|
137
|
+
readonly route: "[data-or-route]";
|
|
138
|
+
readonly swapStart: "[data-or-swap-start]";
|
|
139
|
+
readonly swapBack: "[data-or-swap-back]";
|
|
140
|
+
readonly swapQr: "[data-or-swap-qr]";
|
|
141
|
+
readonly swapCopy: "[data-or-swap-copy]";
|
|
142
|
+
readonly swapCopyLabel: "[data-or-swap-copy-label]";
|
|
143
|
+
readonly swapSelectAll: "[data-or-swap-select-all]";
|
|
144
|
+
readonly swapNetwork: "[data-or-swap-network]";
|
|
145
|
+
readonly swapNetworkValue: "[data-or-swap-network-value]";
|
|
146
|
+
readonly pickerSelect: "[data-or-picker-select]";
|
|
147
|
+
readonly pickerContinue: "[data-or-picker-continue]";
|
|
148
|
+
readonly swapRefundForm: "[data-or-swap-refund-form]";
|
|
149
|
+
readonly swapRefundAddress: "[data-or-swap-refund-address]";
|
|
150
|
+
readonly swapRefundAllowed: "[data-or-swap-refund-allowed]";
|
|
151
|
+
readonly swapRefundConfirm: "[data-or-swap-refund-confirm]";
|
|
152
|
+
readonly swapRefundPayInAsset: "[data-or-swap-refund-pay-in-asset]";
|
|
153
|
+
readonly swapRefundNetworkLabel: "[data-or-swap-refund-network-label]";
|
|
154
|
+
readonly swapRefundError: "[data-or-swap-refund-error]";
|
|
155
|
+
readonly providerCopy: "[data-or-provider-copy]";
|
|
156
|
+
readonly providerTutorial: "[data-or-provider-tutorial]";
|
|
157
|
+
readonly providerTutorialIndex: "[data-or-provider-tutorial-index]";
|
|
158
|
+
};
|
|
159
|
+
declare const OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES: {
|
|
160
|
+
readonly root: "data-openreceive-checkout";
|
|
161
|
+
readonly qr: "data-openreceive-qr";
|
|
162
|
+
readonly meta: "data-openreceive-meta";
|
|
163
|
+
readonly state: "data-openreceive-state";
|
|
164
|
+
readonly actions: "data-openreceive-actions";
|
|
165
|
+
readonly theme: "data-openreceive-theme";
|
|
166
|
+
readonly themeToggle: "data-openreceive-theme-toggle";
|
|
167
|
+
};
|
|
168
|
+
declare const OPENRECEIVE_CHECKOUT_DATA_SELECTORS: {
|
|
169
|
+
readonly root: "[data-openreceive-checkout]";
|
|
170
|
+
readonly qr: "[data-openreceive-qr]";
|
|
171
|
+
readonly meta: "[data-openreceive-meta]";
|
|
172
|
+
readonly state: "[data-openreceive-state]";
|
|
173
|
+
readonly actions: "[data-openreceive-actions]";
|
|
174
|
+
readonly theme: "[data-openreceive-theme]";
|
|
175
|
+
readonly themeToggle: "[data-openreceive-theme-toggle]";
|
|
176
|
+
};
|
|
177
|
+
declare const OPENRECEIVE_CHECKOUT_ELEMENT_PARTS: {
|
|
178
|
+
readonly copy: "copy";
|
|
179
|
+
readonly startOver: "start-over";
|
|
180
|
+
};
|
|
181
|
+
declare const OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS: {
|
|
182
|
+
readonly copy: "[part=\"copy\"]";
|
|
183
|
+
readonly startOver: "[part=\"start-over\"]";
|
|
184
|
+
};
|
|
185
|
+
declare const OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS: {
|
|
186
|
+
readonly button: "button";
|
|
187
|
+
};
|
|
188
|
+
declare const OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS: {
|
|
189
|
+
readonly button: "[part=\"button\"]";
|
|
190
|
+
};
|
|
191
|
+
type CheckoutElementEventName = (typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS)[keyof typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS];
|
|
192
|
+
interface CheckoutProviderCopyEventDetail {
|
|
193
|
+
readonly providerId: string;
|
|
194
|
+
}
|
|
195
|
+
interface CheckoutStateEventDetail {
|
|
196
|
+
readonly state: CheckoutState;
|
|
197
|
+
}
|
|
198
|
+
interface CheckoutErrorEventDetail {
|
|
199
|
+
readonly error: unknown;
|
|
200
|
+
}
|
|
201
|
+
interface ThemeChangeEventDetail {
|
|
202
|
+
readonly theme: ThemePreference;
|
|
203
|
+
readonly resolvedTheme: ResolvedTheme;
|
|
204
|
+
}
|
|
205
|
+
declare function createCheckoutProviderCopyEvent(providerId: string): CustomEvent<CheckoutProviderCopyEventDetail>;
|
|
206
|
+
declare function createCheckoutActionEvent(eventName: typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.copy | typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.openWallet | typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.startOver): CustomEvent;
|
|
207
|
+
declare function createCheckoutStateEvent(eventName: typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.state | typeof OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.settled, state: CheckoutState): CustomEvent<CheckoutStateEventDetail>;
|
|
208
|
+
declare function createCheckoutErrorEvent(error: unknown): CustomEvent<CheckoutErrorEventDetail>;
|
|
209
|
+
declare function createThemeChangeEvent(theme: ThemeModel): CustomEvent<ThemeChangeEventDetail>;
|
|
210
|
+
declare const OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES: {
|
|
211
|
+
readonly reference: "reference";
|
|
212
|
+
/**
|
|
213
|
+
* Base path the shipped router is mounted at (default `/openreceive`). The
|
|
214
|
+
* element's ONLY URL input: create, prepare, payment-check and the four swap
|
|
215
|
+
* routes are all derived from it. There is deliberately no per-route
|
|
216
|
+
* attribute — see `checkoutRoutes` in ../internal/routes.ts.
|
|
217
|
+
*/
|
|
218
|
+
readonly prefix: "prefix";
|
|
219
|
+
/** JSON-encoded create-time metadata forwarded to the create request. */
|
|
220
|
+
readonly metadata: "metadata";
|
|
221
|
+
readonly invoiceId: "invoice-id";
|
|
222
|
+
readonly invoice: "invoice";
|
|
223
|
+
readonly rail: "rail";
|
|
224
|
+
readonly paymentHash: "payment-hash";
|
|
225
|
+
readonly amountMsats: "amount-msats";
|
|
226
|
+
readonly fiatCurrency: "fiat-currency";
|
|
227
|
+
readonly fiatValue: "fiat-value";
|
|
228
|
+
readonly status: "status";
|
|
229
|
+
readonly expiresAt: "expires-at";
|
|
230
|
+
readonly theme: "theme";
|
|
231
|
+
readonly paymentWizard: "payment-wizard";
|
|
232
|
+
/**
|
|
233
|
+
* Opt into History API URL sync to `{resume-path-prefix}/{reference}`.
|
|
234
|
+
* Summary fetch always runs in create mode; this only controls URL mutation.
|
|
235
|
+
*/
|
|
236
|
+
readonly syncUrl: "sync-url";
|
|
237
|
+
/** History API path prefix when `sync-url` is set. Default `/checkout`. */
|
|
238
|
+
readonly resumePathPrefix: "resume-path-prefix";
|
|
239
|
+
/**
|
|
240
|
+
* Order id owned by the app router (e.g. Next.js). When set, the element does not
|
|
241
|
+
* push/replace the URL via the History API.
|
|
242
|
+
*/
|
|
243
|
+
readonly routeReference: "route-reference";
|
|
244
|
+
/**
|
|
245
|
+
* Base URL of an external bolt11 decoder. When set, the checkout shows a
|
|
246
|
+
* "Decode" link to `{decode-link-url}?invoice={bolt11}`. Omitted (the
|
|
247
|
+
* default), no decode link is rendered and the invoice never leaves the page.
|
|
248
|
+
*/
|
|
249
|
+
readonly decodeLinkUrl: "decode-link-url";
|
|
250
|
+
/** `polling="false"` renders the snapshot without status polling (no POST /payments/check). */
|
|
251
|
+
readonly polling: "polling";
|
|
252
|
+
/** Status poll cadence in milliseconds; defaults to OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS. */
|
|
253
|
+
readonly pollIntervalMs: "poll-interval-ms";
|
|
254
|
+
};
|
|
255
|
+
declare const OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES: {
|
|
256
|
+
readonly rootSelector: "root-selector";
|
|
257
|
+
readonly checkoutSelector: "checkout-selector";
|
|
258
|
+
readonly defaultTheme: "default-theme";
|
|
259
|
+
readonly storageKey: "storage-key";
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
interface TransientFeedbackOptions<T> {
|
|
263
|
+
readonly resetValue: T;
|
|
264
|
+
readonly delayMs?: number;
|
|
265
|
+
readonly setTimeout?: typeof globalThis.setTimeout;
|
|
266
|
+
readonly clearTimeout?: typeof globalThis.clearTimeout;
|
|
267
|
+
readonly onValue: (value: T) => void;
|
|
268
|
+
}
|
|
269
|
+
interface TransientFeedbackController<T> {
|
|
270
|
+
show(value: T): void;
|
|
271
|
+
clear(): void;
|
|
272
|
+
}
|
|
273
|
+
interface TickingValueOptions {
|
|
274
|
+
readonly active?: boolean;
|
|
275
|
+
readonly intervalMs?: number;
|
|
276
|
+
readonly now?: () => number;
|
|
277
|
+
readonly setInterval?: typeof globalThis.setInterval;
|
|
278
|
+
readonly clearInterval?: typeof globalThis.clearInterval;
|
|
279
|
+
readonly onValue: (value: number) => void;
|
|
280
|
+
}
|
|
281
|
+
interface TickingValueController {
|
|
282
|
+
start(): void;
|
|
283
|
+
stop(): void;
|
|
284
|
+
refresh(): void;
|
|
285
|
+
}
|
|
286
|
+
interface QrEncoder {
|
|
287
|
+
toString(payload: string, options: Record<string, unknown>): Promise<string> | string;
|
|
288
|
+
toDataURL?(payload: string, options: Record<string, unknown>): Promise<string> | string;
|
|
289
|
+
}
|
|
290
|
+
interface QrOptions {
|
|
291
|
+
encoder?: QrEncoder;
|
|
292
|
+
width?: number;
|
|
293
|
+
}
|
|
294
|
+
interface CopyInvoiceOptions {
|
|
295
|
+
invoice: string;
|
|
296
|
+
clipboard?: Pick<Clipboard, "writeText">;
|
|
297
|
+
logger?: BrowserLoggerOption;
|
|
298
|
+
logContext?: BrowserLogContext;
|
|
299
|
+
}
|
|
300
|
+
interface OpenWalletOptions {
|
|
301
|
+
invoice: string;
|
|
302
|
+
open?: (uri: string) => void;
|
|
303
|
+
logger?: BrowserLoggerOption;
|
|
304
|
+
logContext?: BrowserLogContext;
|
|
305
|
+
}
|
|
306
|
+
type BrowserLogLevel = "debug" | "info" | "warn" | "error";
|
|
307
|
+
interface BrowserLogEntry {
|
|
308
|
+
readonly level: BrowserLogLevel;
|
|
309
|
+
readonly event: string;
|
|
310
|
+
readonly message: string;
|
|
311
|
+
readonly [key: string]: unknown;
|
|
312
|
+
}
|
|
313
|
+
type BrowserLogger = (entry: BrowserLogEntry) => void;
|
|
314
|
+
/**
|
|
315
|
+
* Browser logger option. Omit/`undefined` attaches the built-in console logger
|
|
316
|
+
* (honoring `LOG_LEVEL`). Pass `false` to disable OpenReceive browser logs.
|
|
317
|
+
*/
|
|
318
|
+
type BrowserLoggerOption = BrowserLogger | false;
|
|
319
|
+
interface BrowserLogContext {
|
|
320
|
+
readonly reference?: string;
|
|
321
|
+
readonly invoice_id?: string;
|
|
322
|
+
readonly payment_hash?: string;
|
|
323
|
+
readonly amount_msats?: number;
|
|
324
|
+
readonly transaction_state?: string;
|
|
325
|
+
readonly workflow_state?: string;
|
|
326
|
+
readonly [key: string]: unknown;
|
|
327
|
+
}
|
|
328
|
+
type CheckoutPhase = "invoice_created" | "verifying" | "settled" | "expired" | "failed" | "cancelled";
|
|
329
|
+
type SwapProviderState = "creating_provider_order" | "awaiting_deposit" | "confirming" | "exchanging" | "paying_invoice" | "completed" | "expired" | "refund_required" | "refund_pending" | "refunded" | "attention" | "failed";
|
|
330
|
+
/**
|
|
331
|
+
* Provider-reported fiat equivalents of both sides of a swap. `pay_in_fiat` is the
|
|
332
|
+
* value of the crypto the payer must send; `payout_fiat` is the cart total delivered
|
|
333
|
+
* to the merchant. Their gap is the swap fee the payer absorbs.
|
|
334
|
+
*/
|
|
335
|
+
interface CheckoutInvoiceSwapFee {
|
|
336
|
+
readonly currency: string;
|
|
337
|
+
readonly pay_in_fiat: string;
|
|
338
|
+
readonly payout_fiat: string;
|
|
339
|
+
}
|
|
340
|
+
interface CheckoutInvoiceSwapSnapshot {
|
|
341
|
+
readonly attempt_id?: string;
|
|
342
|
+
readonly provider: string;
|
|
343
|
+
readonly provider_order_id?: string;
|
|
344
|
+
readonly pay_in_asset: string;
|
|
345
|
+
readonly deposit_address: string;
|
|
346
|
+
readonly deposit_memo?: string;
|
|
347
|
+
readonly deposit_amount: string;
|
|
348
|
+
readonly provider_state: SwapProviderState;
|
|
349
|
+
readonly provider_expires_at: number;
|
|
350
|
+
readonly deposit_tx_id?: string;
|
|
351
|
+
readonly payout_tx_id?: string;
|
|
352
|
+
readonly refund_address?: string;
|
|
353
|
+
readonly refund_tx_id?: string;
|
|
354
|
+
readonly attention?: boolean;
|
|
355
|
+
readonly attention_reason?: string;
|
|
356
|
+
readonly refund_reason?: string;
|
|
357
|
+
readonly deposit_received_amount?: string;
|
|
358
|
+
readonly refund_amount?: string;
|
|
359
|
+
readonly fee?: CheckoutInvoiceSwapFee;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Formatted fee breakout for the deposit panel, explaining why the payer sends more
|
|
363
|
+
* than the cart total. All figures are display-ready fiat strings.
|
|
364
|
+
*/
|
|
365
|
+
interface SwapFeeBreakdown {
|
|
366
|
+
/** Cart total delivered to the merchant, e.g. "$10.00". */
|
|
367
|
+
readonly cartTotal: string;
|
|
368
|
+
/** Fiat value of the crypto the payer sends, e.g. "$10.59". */
|
|
369
|
+
readonly youSend: string;
|
|
370
|
+
/** The swap fee absorbed by the payer (exchange spread + network fees), e.g. "$0.59". */
|
|
371
|
+
readonly fee: string;
|
|
372
|
+
/** The fee as a percentage of the cart total, e.g. "5.9%", when computable. */
|
|
373
|
+
readonly feePercent?: string;
|
|
374
|
+
}
|
|
375
|
+
interface SwapDisplayModel {
|
|
376
|
+
readonly provider: string;
|
|
377
|
+
readonly attemptId: string;
|
|
378
|
+
readonly payInAsset: string;
|
|
379
|
+
readonly assetLabel: string;
|
|
380
|
+
readonly networkLabel: string;
|
|
381
|
+
/** Strong deposit-panel alert title, e.g. "Wrong currency or network = lost funds". */
|
|
382
|
+
readonly networkWarningTitle: string;
|
|
383
|
+
/** Exact amount + asset + network to emphasize, e.g. "15.01 USDT on the Solana network". */
|
|
384
|
+
readonly networkWarningEmphasis: string;
|
|
385
|
+
/** Full plain-text network warning (accessible / non-HTML consumers). */
|
|
386
|
+
readonly networkWarning: string;
|
|
387
|
+
readonly depositAddress: string;
|
|
388
|
+
readonly depositMemo?: string;
|
|
389
|
+
readonly depositAmount: string;
|
|
390
|
+
readonly providerStateLabel: string;
|
|
391
|
+
readonly providerStateDetail: string;
|
|
392
|
+
readonly state: "creating" | "deposit" | "progress" | "settled" | "expired" | "refund_required" | "refund_pending" | "refunded" | "attention" | "failed";
|
|
393
|
+
readonly expiresInSeconds: number;
|
|
394
|
+
readonly countdownLabel: string;
|
|
395
|
+
readonly qrPayload: string;
|
|
396
|
+
/** Ready-to-render fee breakout, present when the provider reported fiat equivalents. */
|
|
397
|
+
readonly feeBreakdown?: SwapFeeBreakdown;
|
|
398
|
+
readonly depositTxId?: string;
|
|
399
|
+
readonly payoutTxId?: string;
|
|
400
|
+
readonly refundAddress?: string;
|
|
401
|
+
/**
|
|
402
|
+
* Whether the refund form may be submitted. The review-then-confirm gate is
|
|
403
|
+
* entirely client-side: OpenReceive mints no refund tokens, the server sends
|
|
404
|
+
* none, and the confirmed request carries only reference, payment_hash, and
|
|
405
|
+
* refund_address.
|
|
406
|
+
*/
|
|
407
|
+
readonly refundAllowed: boolean;
|
|
408
|
+
readonly refundTxId?: string;
|
|
409
|
+
readonly refundReason?: string;
|
|
410
|
+
readonly depositReceivedAmount?: string;
|
|
411
|
+
readonly refundAmount?: string;
|
|
412
|
+
readonly providerOrderId?: string;
|
|
413
|
+
}
|
|
414
|
+
interface CheckoutInvoiceSnapshot {
|
|
415
|
+
readonly invoice_id: string;
|
|
416
|
+
readonly invoice?: string | null;
|
|
417
|
+
readonly rail: "lightning" | "swap" | "checkout_lock";
|
|
418
|
+
readonly payment_hash?: string;
|
|
419
|
+
readonly amount_msats?: number;
|
|
420
|
+
readonly fiat_quote?: {
|
|
421
|
+
readonly fiat?: {
|
|
422
|
+
readonly currency?: string;
|
|
423
|
+
readonly value?: string;
|
|
424
|
+
};
|
|
425
|
+
} | null;
|
|
426
|
+
readonly transaction_state?: string;
|
|
427
|
+
readonly workflow_state?: string;
|
|
428
|
+
readonly expires_at?: number;
|
|
429
|
+
readonly settled_at?: number;
|
|
430
|
+
readonly swap?: CheckoutInvoiceSwapSnapshot;
|
|
431
|
+
}
|
|
432
|
+
interface CheckoutPaymentMethod {
|
|
433
|
+
readonly pay_in_asset: string;
|
|
434
|
+
readonly label: string;
|
|
435
|
+
readonly network_label: string;
|
|
436
|
+
readonly provider: string;
|
|
437
|
+
readonly available: boolean;
|
|
438
|
+
readonly unavailable_reason?: string;
|
|
439
|
+
readonly unavailable_message?: string;
|
|
440
|
+
readonly pay_amount?: string;
|
|
441
|
+
readonly minimum_pay_amount?: string;
|
|
442
|
+
readonly maximum_pay_amount?: string;
|
|
443
|
+
readonly minimum_invoice_amount_msats?: number;
|
|
444
|
+
readonly maximum_invoice_amount_msats?: number;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Client-side snapshot of one Checkout (the server's `Checkout` /
|
|
448
|
+
* the wire's `WireCheckout`), aggregated across its payment
|
|
449
|
+
* attempts as the browser polls. Snake_case because it holds wire data
|
|
450
|
+
* verbatim.
|
|
451
|
+
*/
|
|
452
|
+
interface CheckoutSnapshot {
|
|
453
|
+
readonly checkout_id: string;
|
|
454
|
+
readonly reference: string;
|
|
455
|
+
readonly status: "open" | "paid" | "expired";
|
|
456
|
+
readonly paid_at?: number;
|
|
457
|
+
readonly amount_msats: number;
|
|
458
|
+
readonly fiat?: {
|
|
459
|
+
readonly currency: string;
|
|
460
|
+
readonly value: string;
|
|
461
|
+
};
|
|
462
|
+
readonly active?: CheckoutInvoiceSnapshot;
|
|
463
|
+
readonly invoices: readonly CheckoutInvoiceSnapshot[];
|
|
464
|
+
readonly payment_methods?: readonly CheckoutPaymentMethod[];
|
|
465
|
+
}
|
|
466
|
+
interface CheckoutElementAttributeOptions {
|
|
467
|
+
/**
|
|
468
|
+
* Order id for create mode. When no checkout snapshot is supplied, the element is rendered
|
|
469
|
+
* with this as its `reference` attribute (paired with `prefix`) and owns the whole
|
|
470
|
+
* create/poll lifecycle itself. Ignored when a snapshot is supplied — the snapshot's
|
|
471
|
+
* `reference` wins.
|
|
472
|
+
*/
|
|
473
|
+
readonly reference?: string;
|
|
474
|
+
/**
|
|
475
|
+
* Base path the shipped router is mounted at. Emitted as the element's `prefix` attribute
|
|
476
|
+
* so a create-mode element (`reference` with no `invoice`) can derive its create/order
|
|
477
|
+
* routes without spelling them out.
|
|
478
|
+
*/
|
|
479
|
+
readonly prefix?: string;
|
|
480
|
+
/**
|
|
481
|
+
* Optional create-time metadata (parity with the React `<Checkout metadata>`
|
|
482
|
+
* prop): JSON-encoded onto the element's `metadata` attribute and sent with
|
|
483
|
+
* the Lightning mint request.
|
|
484
|
+
*/
|
|
485
|
+
readonly metadata?: Record<string, unknown>;
|
|
486
|
+
readonly theme?: ResolvedTheme;
|
|
487
|
+
readonly paymentWizard?: boolean;
|
|
488
|
+
/**
|
|
489
|
+
* Opt into History API URL sync to `{resumePathPrefix}/{reference}` (default `/checkout/:id`).
|
|
490
|
+
* This controls URL mutation only; order-resume data remains a host concern.
|
|
491
|
+
*/
|
|
492
|
+
readonly syncUrl?: boolean;
|
|
493
|
+
/** History API path prefix when `syncUrl` is set. Default `/checkout`. */
|
|
494
|
+
readonly resumePathPrefix?: string;
|
|
495
|
+
/**
|
|
496
|
+
* Order id from the app router (e.g. Next.js). When set, skip History API URL sync.
|
|
497
|
+
*/
|
|
498
|
+
readonly routeReference?: string;
|
|
499
|
+
/**
|
|
500
|
+
* Base URL of an external bolt11 decoder. Omitted (the default), the element
|
|
501
|
+
* renders no "Decode" link and the invoice is never sent to a third party.
|
|
502
|
+
*/
|
|
503
|
+
readonly decodeLinkUrl?: string;
|
|
504
|
+
/** False renders the snapshot without status polling (no POST /payments/check). */
|
|
505
|
+
readonly polling?: boolean;
|
|
506
|
+
/** Status poll cadence in milliseconds; defaults to OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS. */
|
|
507
|
+
readonly pollIntervalMs?: number;
|
|
508
|
+
}
|
|
509
|
+
interface ThemeToggleElementAttributeOptions {
|
|
510
|
+
readonly rootSelector?: string;
|
|
511
|
+
readonly checkoutSelector?: string;
|
|
512
|
+
readonly defaultTheme?: ThemePreference;
|
|
513
|
+
readonly storageKey?: string;
|
|
514
|
+
}
|
|
515
|
+
type CheckoutElementAttributeName = (typeof OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES)[keyof typeof OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES];
|
|
516
|
+
type CheckoutElementAttributes = Partial<Record<CheckoutElementAttributeName, string>>;
|
|
517
|
+
type ThemeToggleElementAttributeName = (typeof OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES)[keyof typeof OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES];
|
|
518
|
+
type ThemeToggleElementAttributes = Partial<Record<ThemeToggleElementAttributeName, string>>;
|
|
519
|
+
interface CheckoutElementEventHandlers {
|
|
520
|
+
readonly onCopy?: (event: Event) => void;
|
|
521
|
+
readonly onOpenWallet?: (event: Event) => void;
|
|
522
|
+
readonly onState?: (event: Event) => void;
|
|
523
|
+
readonly onSettled?: (event: Event) => void;
|
|
524
|
+
readonly onProviderCopy?: (event: Event) => void;
|
|
525
|
+
readonly onStartOver?: (event: Event) => void;
|
|
526
|
+
readonly onError?: (event: Event) => void;
|
|
527
|
+
}
|
|
528
|
+
type CheckoutElementListeners = Partial<Record<CheckoutElementEventName, (event: Event) => void>>;
|
|
529
|
+
interface CheckoutShellOptions extends Omit<CheckoutElementAttributeOptions, "theme">, CheckoutElementEventHandlers, StoredThemeModelOptions {
|
|
530
|
+
readonly rootSelector?: string;
|
|
531
|
+
readonly checkoutSelector?: string;
|
|
532
|
+
/**
|
|
533
|
+
* When false, omit the package theme toggle and do not stamp `data-theme` on the
|
|
534
|
+
* shell root or checkout. The checkout inherits from an ancestor `[data-theme]`
|
|
535
|
+
* (e.g. React `ThemeScope`). Default true for standalone embeds.
|
|
536
|
+
*/
|
|
537
|
+
readonly themeToggle?: boolean;
|
|
538
|
+
}
|
|
539
|
+
interface CheckoutShellCheckoutBinding {
|
|
540
|
+
readonly tagName: typeof OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME;
|
|
541
|
+
readonly attributes: CheckoutElementAttributes;
|
|
542
|
+
readonly listeners: CheckoutElementListeners;
|
|
543
|
+
}
|
|
544
|
+
interface CheckoutShellThemeToggleBinding {
|
|
545
|
+
readonly tagName: typeof OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME;
|
|
546
|
+
readonly attributes: ThemeToggleElementAttributes;
|
|
547
|
+
}
|
|
548
|
+
interface CheckoutShellModel {
|
|
549
|
+
readonly theme: ThemeModel;
|
|
550
|
+
readonly rootAttributes: Partial<ThemeModel["attributes"]>;
|
|
551
|
+
readonly checkout: CheckoutShellCheckoutBinding;
|
|
552
|
+
readonly themeToggle: CheckoutShellThemeToggleBinding | null;
|
|
553
|
+
}
|
|
554
|
+
interface CheckoutElementDocument {
|
|
555
|
+
createElement(tagName: string): HTMLElement;
|
|
556
|
+
}
|
|
557
|
+
interface CreateOpenReceiveThemeToggleElementOptions extends ThemeToggleElementAttributeOptions {
|
|
558
|
+
readonly document?: CheckoutElementDocument;
|
|
559
|
+
}
|
|
560
|
+
interface CreateCheckoutShellOptions extends CheckoutShellOptions {
|
|
561
|
+
readonly document?: CheckoutElementDocument;
|
|
562
|
+
readonly root?: ThemeAttributeTarget | null;
|
|
563
|
+
}
|
|
564
|
+
interface CheckoutShellElements {
|
|
565
|
+
readonly theme: ThemeModel;
|
|
566
|
+
readonly rootAttributes: Partial<ThemeModel["attributes"]>;
|
|
567
|
+
readonly checkout: HTMLElement;
|
|
568
|
+
readonly themeToggle: HTMLElement | null;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* The ONE derived view of a checkout: a snapshot plus a clock, flattened onto
|
|
572
|
+
* the attempt the payer is looking at, with the phase machine's verdict and the
|
|
573
|
+
* labels the UI prints. Produced only by `createCheckoutState`.
|
|
574
|
+
*
|
|
575
|
+
* It extends {@link CheckoutStateLabels}, so the labels ship with the state —
|
|
576
|
+
* including in the `openreceive-state` CustomEvent's `detail.state`.
|
|
577
|
+
*/
|
|
578
|
+
interface CheckoutState extends CheckoutStateLabels {
|
|
579
|
+
readonly checkout_id: string;
|
|
580
|
+
readonly reference: string;
|
|
581
|
+
readonly invoice_id: string;
|
|
582
|
+
readonly invoice: string;
|
|
583
|
+
readonly rail: "lightning" | "swap" | "checkout_lock";
|
|
584
|
+
readonly lightning_uri: string;
|
|
585
|
+
readonly payment_hash?: string;
|
|
586
|
+
readonly amount_msats?: number;
|
|
587
|
+
readonly fiat_quote?: CheckoutInvoiceSnapshot["fiat_quote"];
|
|
588
|
+
readonly transaction_state: string;
|
|
589
|
+
readonly workflow_state: string;
|
|
590
|
+
readonly expires_at?: number;
|
|
591
|
+
readonly expires_in_seconds?: number;
|
|
592
|
+
readonly phase: CheckoutPhase;
|
|
593
|
+
readonly settled: boolean;
|
|
594
|
+
readonly terminal: boolean;
|
|
595
|
+
readonly paid: boolean;
|
|
596
|
+
readonly settled_at?: number;
|
|
597
|
+
readonly swap?: CheckoutInvoiceSwapSnapshot;
|
|
598
|
+
}
|
|
599
|
+
interface CheckoutStatusModelInput {
|
|
600
|
+
readonly phase?: CheckoutPhase;
|
|
601
|
+
readonly waiting?: boolean;
|
|
602
|
+
readonly expires_in_seconds?: number;
|
|
603
|
+
}
|
|
604
|
+
interface CheckoutStatusModel {
|
|
605
|
+
readonly phase: CheckoutPhase;
|
|
606
|
+
readonly waiting: boolean;
|
|
607
|
+
readonly title: string;
|
|
608
|
+
readonly detail: string;
|
|
609
|
+
readonly countdownPrefix: string;
|
|
610
|
+
readonly expires_in_seconds?: number;
|
|
611
|
+
readonly countdownLabel?: string;
|
|
612
|
+
}
|
|
613
|
+
type CheckoutStatusRefresh = (reference: string) => Promise<CheckoutSnapshot | null>;
|
|
614
|
+
type RequestCheckoutOptions = RequestCheckoutBaseOptions;
|
|
615
|
+
/**
|
|
616
|
+
* `prepareCheckout` posts only the order id — it locks the amount and lists
|
|
617
|
+
* payment methods without minting — so there is no memo or metadata to carry.
|
|
618
|
+
*/
|
|
619
|
+
type PrepareCheckoutOptions = Pick<RequestCheckoutBaseOptions, "prefix" | "reference" | "fetch" | "headers">;
|
|
620
|
+
interface RequestCheckoutBaseOptions {
|
|
621
|
+
/**
|
|
622
|
+
* Base path the shipped router is mounted at (e.g. `/openreceive`). The create and
|
|
623
|
+
* prepare routes are derived from it — see {@link checkoutRoutes}. It is required
|
|
624
|
+
* because it is the only URL input: there is no per-route override.
|
|
625
|
+
*/
|
|
626
|
+
readonly prefix: string;
|
|
627
|
+
readonly reference: string;
|
|
628
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
629
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
630
|
+
readonly memo?: string;
|
|
631
|
+
readonly metadata?: Record<string, unknown>;
|
|
632
|
+
}
|
|
633
|
+
interface CreateOpenReceiveStatusFetcherOptions {
|
|
634
|
+
/**
|
|
635
|
+
* Base path the shipped router is mounted at. The fetcher polls
|
|
636
|
+
* `${prefix}/payments/check` and reads live swap state from
|
|
637
|
+
* `${prefix}/swaps/status` — see {@link checkoutRoutes}.
|
|
638
|
+
*/
|
|
639
|
+
readonly prefix: string;
|
|
640
|
+
readonly snapshot: CheckoutSnapshot;
|
|
641
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
642
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
643
|
+
}
|
|
644
|
+
interface CheckoutWatcherOptions {
|
|
645
|
+
readonly snapshot: CheckoutSnapshot;
|
|
646
|
+
readonly refreshStatus?: CheckoutStatusRefresh;
|
|
647
|
+
readonly pollIntervalMs?: number;
|
|
648
|
+
readonly now?: () => number;
|
|
649
|
+
readonly setInterval?: typeof globalThis.setInterval;
|
|
650
|
+
readonly clearInterval?: typeof globalThis.clearInterval;
|
|
651
|
+
readonly logger?: BrowserLoggerOption;
|
|
652
|
+
readonly onState: (state: CheckoutState) => void;
|
|
653
|
+
readonly onSnapshot?: (snapshot: CheckoutSnapshot) => void;
|
|
654
|
+
readonly onError?: (error: unknown) => void;
|
|
655
|
+
}
|
|
656
|
+
interface CheckoutControllerOptions extends Omit<CheckoutWatcherOptions, "onState"> {
|
|
657
|
+
readonly onState?: (state: CheckoutState) => void;
|
|
658
|
+
/**
|
|
659
|
+
* Base path the shipped router is mounted at. Omitted, the controller does no
|
|
660
|
+
* status polling of its own — pass `refreshStatus` instead, or nothing at all
|
|
661
|
+
* to render a snapshot without polling.
|
|
662
|
+
*/
|
|
663
|
+
readonly prefix?: string;
|
|
664
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
665
|
+
readonly statusHeaders?: Readonly<Record<string, string>>;
|
|
666
|
+
readonly clipboard?: Pick<Clipboard, "writeText">;
|
|
667
|
+
readonly open?: (uri: string) => void;
|
|
668
|
+
}
|
|
669
|
+
interface CheckoutController {
|
|
670
|
+
start(): CheckoutState;
|
|
671
|
+
stop(): void;
|
|
672
|
+
getState(): CheckoutState | undefined;
|
|
673
|
+
reloadState(): Promise<CheckoutState>;
|
|
674
|
+
/**
|
|
675
|
+
* Stop all timers and mark the checkout `cancelled`: the returned state (and
|
|
676
|
+
* every later `getState()`) carries the terminal `cancelled` phase.
|
|
677
|
+
*/
|
|
678
|
+
cancel(): CheckoutState;
|
|
679
|
+
copyInvoice(): Promise<void>;
|
|
680
|
+
openWallet(): string;
|
|
681
|
+
}
|
|
682
|
+
interface CreateCheckoutStateOptions {
|
|
683
|
+
readonly now?: number;
|
|
684
|
+
readonly logger?: BrowserLoggerOption;
|
|
685
|
+
/**
|
|
686
|
+
* How this state was produced. Controls which browser log events fire:
|
|
687
|
+
* - `create` (default): `checkout.state.created`
|
|
688
|
+
* - `refresh`: `checkout.state.refreshed` plus `swap.state.changed` when swap fields move
|
|
689
|
+
* - `countdown`: no log (avoids per-second spam from the expiry ticker)
|
|
690
|
+
*/
|
|
691
|
+
readonly source?: "create" | "refresh" | "countdown";
|
|
692
|
+
/** Prior checkout state; used with `source: "refresh"` to emit swap transition audits. */
|
|
693
|
+
readonly previousState?: CheckoutState;
|
|
694
|
+
}
|
|
695
|
+
type PaymentMethod = "bitcoin";
|
|
696
|
+
type ThemePreference = "light" | "dark" | "system";
|
|
697
|
+
type ResolvedTheme = "light" | "dark";
|
|
698
|
+
interface PaymentMethodOption {
|
|
699
|
+
readonly id: PaymentMethod;
|
|
700
|
+
readonly title: string;
|
|
701
|
+
readonly detail: string;
|
|
702
|
+
}
|
|
703
|
+
interface ParseOpenReceiveOptionalIntegerOptions {
|
|
704
|
+
readonly label?: string;
|
|
705
|
+
}
|
|
706
|
+
interface ThemeModelOptions {
|
|
707
|
+
readonly systemDark?: boolean;
|
|
708
|
+
}
|
|
709
|
+
interface ThemeStorageOptions {
|
|
710
|
+
readonly storage?: Storage;
|
|
711
|
+
readonly storageKey?: string;
|
|
712
|
+
}
|
|
713
|
+
interface ReadThemePreferenceOptions extends ThemeStorageOptions {
|
|
714
|
+
readonly defaultTheme?: ThemePreference;
|
|
715
|
+
}
|
|
716
|
+
interface StoredThemeModelOptions extends ReadThemePreferenceOptions, ThemeModelOptions {
|
|
717
|
+
}
|
|
718
|
+
interface ThemeAttributeTarget {
|
|
719
|
+
getAttribute(name: string): string | null;
|
|
720
|
+
setAttribute(name: string, value: string): void;
|
|
721
|
+
}
|
|
722
|
+
interface ThemeLabelTarget {
|
|
723
|
+
textContent: string | null;
|
|
724
|
+
}
|
|
725
|
+
interface ThemeControlTargets {
|
|
726
|
+
readonly root?: ThemeAttributeTarget | null;
|
|
727
|
+
readonly checkout?: ThemeAttributeTarget | null;
|
|
728
|
+
readonly toggle?: ThemeLabelTarget | null;
|
|
729
|
+
}
|
|
730
|
+
interface ThemeModel {
|
|
731
|
+
readonly theme: ThemePreference;
|
|
732
|
+
readonly resolvedTheme: ResolvedTheme;
|
|
733
|
+
readonly nextTheme: ThemePreference;
|
|
734
|
+
readonly toggleLabel: string;
|
|
735
|
+
readonly attributes: {
|
|
736
|
+
readonly "data-theme": ResolvedTheme;
|
|
737
|
+
readonly "data-openreceive-theme": ResolvedTheme;
|
|
738
|
+
};
|
|
739
|
+
readonly checkoutElementAttributes: {
|
|
740
|
+
readonly theme: ResolvedTheme;
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
interface PaymentWizardSelection {
|
|
744
|
+
readonly selectedMethod: PaymentMethod | null;
|
|
745
|
+
readonly selectedBitcoinRoute: string | null;
|
|
746
|
+
}
|
|
747
|
+
type PaymentWizardSelectionAction = {
|
|
748
|
+
readonly type: "select_method";
|
|
749
|
+
readonly method: PaymentMethod;
|
|
750
|
+
} | {
|
|
751
|
+
readonly type: "change_method";
|
|
752
|
+
} | {
|
|
753
|
+
readonly type: "change_route";
|
|
754
|
+
} | {
|
|
755
|
+
readonly type: "select_route";
|
|
756
|
+
readonly route: string;
|
|
757
|
+
};
|
|
758
|
+
interface PaymentWizardState {
|
|
759
|
+
readonly selectedRouteId: string | null;
|
|
760
|
+
readonly routes: readonly PaymentWizardRoute[];
|
|
761
|
+
}
|
|
762
|
+
interface PaymentWizardModel {
|
|
763
|
+
readonly selection: PaymentWizardSelection;
|
|
764
|
+
readonly wizard: PaymentWizardState;
|
|
765
|
+
readonly routeAssets: readonly AssetIndexEntry[];
|
|
766
|
+
readonly selectedRoute: string | null;
|
|
767
|
+
}
|
|
768
|
+
interface PaymentWizardControllerOptions {
|
|
769
|
+
readonly selection?: PaymentWizardSelection;
|
|
770
|
+
readonly onSelection?: (selection: PaymentWizardSelection) => void;
|
|
771
|
+
}
|
|
772
|
+
interface PaymentWizardController {
|
|
773
|
+
getSelection(): PaymentWizardSelection;
|
|
774
|
+
getModel(): PaymentWizardModel;
|
|
775
|
+
update(action: PaymentWizardSelectionAction): PaymentWizardSelection;
|
|
776
|
+
selectMethod(method: PaymentMethod): PaymentWizardSelection;
|
|
777
|
+
changeMethod(): PaymentWizardSelection;
|
|
778
|
+
selectRoute(route: string): PaymentWizardSelection;
|
|
779
|
+
}
|
|
780
|
+
interface WizardRouteAssetDisplay {
|
|
781
|
+
readonly id: string;
|
|
782
|
+
readonly label: string;
|
|
783
|
+
readonly subtitle: string;
|
|
784
|
+
readonly icon: string;
|
|
785
|
+
readonly selected: boolean;
|
|
786
|
+
}
|
|
787
|
+
interface WizardProviderTutorialDisplay {
|
|
788
|
+
readonly index: number;
|
|
789
|
+
readonly path: string;
|
|
790
|
+
readonly image: string;
|
|
791
|
+
readonly caption: string;
|
|
792
|
+
}
|
|
793
|
+
interface WizardProviderDisplay {
|
|
794
|
+
readonly id: string;
|
|
795
|
+
readonly name: string;
|
|
796
|
+
readonly kind: string;
|
|
797
|
+
readonly url: string;
|
|
798
|
+
readonly icon: string;
|
|
799
|
+
readonly tutorials: readonly WizardProviderTutorialDisplay[];
|
|
800
|
+
readonly copyLabel: string;
|
|
801
|
+
readonly copiedLabel: string;
|
|
802
|
+
readonly openLabel: string;
|
|
803
|
+
}
|
|
804
|
+
interface WizardRouteDisplay {
|
|
805
|
+
readonly key: string;
|
|
806
|
+
readonly title: string;
|
|
807
|
+
readonly subtitle: string;
|
|
808
|
+
readonly providers: readonly WizardProviderDisplay[];
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* One display row for post-settlement transaction details. Values are already
|
|
812
|
+
* formatted for UI; `copyValue` is the full string when the display value is truncated.
|
|
813
|
+
* Never includes NWC secrets — those are not part of checkout public state.
|
|
814
|
+
* Optional `href` is a block-explorer or Lightning invoice decode link.
|
|
815
|
+
*/
|
|
816
|
+
interface TransactionDetailRow {
|
|
817
|
+
readonly label: string;
|
|
818
|
+
readonly value: string;
|
|
819
|
+
readonly copyValue?: string;
|
|
820
|
+
readonly href?: string;
|
|
821
|
+
readonly hrefLabel?: string;
|
|
822
|
+
}
|
|
823
|
+
interface TransactionDetailsInput {
|
|
824
|
+
readonly reference?: string;
|
|
825
|
+
readonly checkout_id?: string;
|
|
826
|
+
readonly invoice_id?: string;
|
|
827
|
+
readonly invoice?: string | null;
|
|
828
|
+
readonly rail?: "lightning" | "swap" | "checkout_lock";
|
|
829
|
+
readonly payment_hash?: string;
|
|
830
|
+
readonly amount_msats?: number;
|
|
831
|
+
readonly fiat_quote?: CheckoutInvoiceSnapshot["fiat_quote"];
|
|
832
|
+
readonly transaction_state?: string;
|
|
833
|
+
readonly workflow_state?: string;
|
|
834
|
+
readonly expires_at?: number;
|
|
835
|
+
readonly settled_at?: number;
|
|
836
|
+
readonly swap?: CheckoutInvoiceSwapSnapshot;
|
|
837
|
+
/**
|
|
838
|
+
* Base URL of a host-chosen bolt11 decoder. Omitted (the default), the
|
|
839
|
+
* Lightning invoice row carries no decode link and the invoice is never
|
|
840
|
+
* handed to a third party.
|
|
841
|
+
*/
|
|
842
|
+
readonly decodeLinkUrl?: string;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
declare function assertDisplayInvoice(invoice: string): void;
|
|
846
|
+
declare function createLightningUri(invoice: string): string;
|
|
847
|
+
|
|
848
|
+
declare class BrowserRequestError extends Error {
|
|
849
|
+
readonly status: number;
|
|
850
|
+
readonly code?: string;
|
|
851
|
+
readonly retryable?: boolean;
|
|
852
|
+
readonly retryAfterSeconds?: number;
|
|
853
|
+
constructor(message: string, options: {
|
|
854
|
+
readonly status: number;
|
|
855
|
+
readonly code?: string;
|
|
856
|
+
readonly retryable?: boolean;
|
|
857
|
+
readonly retryAfterSeconds?: number;
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
declare function requestCheckout(options: RequestCheckoutOptions): Promise<CheckoutSnapshot>;
|
|
861
|
+
/**
|
|
862
|
+
* Lock the host order amount and load payment methods without minting Lightning.
|
|
863
|
+
* Bitcoin selection later calls {@link requestCheckout} to mint (or reuse) a bolt11.
|
|
864
|
+
*/
|
|
865
|
+
declare function prepareCheckout(options: PrepareCheckoutOptions): Promise<CheckoutSnapshot>;
|
|
866
|
+
declare function createStatusFetcher(options: CreateOpenReceiveStatusFetcherOptions): CheckoutStatusRefresh;
|
|
867
|
+
|
|
868
|
+
declare function createQrSvg(invoice: string, options?: QrOptions): Promise<string>;
|
|
869
|
+
declare function createQrPayloadSvg(payload: string, options?: QrOptions): Promise<string>;
|
|
870
|
+
declare function createQrPngDataUrl(invoice: string, options?: QrOptions): Promise<string>;
|
|
871
|
+
declare function copyInvoice(options: CopyInvoiceOptions): Promise<void>;
|
|
872
|
+
declare function openWallet(options: OpenWalletOptions): string;
|
|
873
|
+
|
|
874
|
+
declare function createCheckoutController(options: CheckoutControllerOptions): CheckoutController;
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* Guest checkout resume helpers for no-account content sites.
|
|
878
|
+
*
|
|
879
|
+
* Pattern:
|
|
880
|
+
* - Put the public `reference` in the URL (`/checkout/:reference`) so refresh/share works.
|
|
881
|
+
* - Let the host authorize access to the order using its normal session or guest-order policy.
|
|
882
|
+
* - Mirror an optional host order summary in sessionStorage for instant same-tab restore;
|
|
883
|
+
* use the host-supplied `fetchOrder` when storage is empty.
|
|
884
|
+
*
|
|
885
|
+
*/
|
|
886
|
+
interface GuestCheckoutResumeOptions<TOrder> {
|
|
887
|
+
/**
|
|
888
|
+
* URL path prefix before the order id. Default `"/checkout"` → `/checkout/:reference`.
|
|
889
|
+
* Leading/trailing slashes are normalized.
|
|
890
|
+
*/
|
|
891
|
+
readonly pathPrefix?: string;
|
|
892
|
+
/** sessionStorage key prefix for host order summaries (required so hosts do not collide). */
|
|
893
|
+
readonly storageKeyPrefix: string;
|
|
894
|
+
/** Extract the public order id used as the storage/URL key. */
|
|
895
|
+
readonly referenceOf: (order: TOrder) => string;
|
|
896
|
+
/** Validate a value from storage or a fetch body as a host order. */
|
|
897
|
+
readonly parseOrder: (value: unknown) => TOrder | undefined;
|
|
898
|
+
/**
|
|
899
|
+
* Load an order when sessionStorage misses (new tab / shared link).
|
|
900
|
+
* Return `undefined` for missing or unauthorized orders.
|
|
901
|
+
*/
|
|
902
|
+
readonly fetchOrder?: (reference: string) => Promise<TOrder | undefined>;
|
|
903
|
+
/** Path to push when leaving a checkout URL. Default `"/"`. */
|
|
904
|
+
readonly homePath?: string;
|
|
905
|
+
}
|
|
906
|
+
interface GuestCheckoutResumeController<TOrder> {
|
|
907
|
+
/** Normalized path prefix including a leading slash, e.g. `"/checkout"`. */
|
|
908
|
+
readonly pathPrefix: string;
|
|
909
|
+
checkoutPath(reference: string): string;
|
|
910
|
+
/** Parse `/checkout/:reference` from a pathname. Returns undefined when not a resume URL. */
|
|
911
|
+
parseReference(pathname: string): string | undefined;
|
|
912
|
+
rememberOrder(order: TOrder): void;
|
|
913
|
+
readRememberedOrder(reference: string): TOrder | undefined;
|
|
914
|
+
/** Forget one order, or every order under this storage prefix when `reference` is omitted. */
|
|
915
|
+
forgetOrder(reference?: string): void;
|
|
916
|
+
/** Push the checkout path when not already there (History API / SPAs). */
|
|
917
|
+
enterCheckout(reference: string): void;
|
|
918
|
+
/** Return to `homePath` when the current location is a checkout resume URL. */
|
|
919
|
+
leaveCheckout(): void;
|
|
920
|
+
/** sessionStorage first, then optional `fetchOrder`. */
|
|
921
|
+
loadOrderForResume(reference: string): Promise<TOrder | undefined>;
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Create a host-owned guest resume controller. OpenReceive does not invent a host session —
|
|
925
|
+
* this is the reusable URL + sessionStorage glue so demos (and apps) do not copy-paste it.
|
|
926
|
+
*/
|
|
927
|
+
declare function createGuestCheckoutResume<TOrder>(options: GuestCheckoutResumeOptions<TOrder>): GuestCheckoutResumeController<TOrder>;
|
|
928
|
+
/**
|
|
929
|
+
* Push `/checkout/:reference` (or a custom path prefix) via the History API when not already
|
|
930
|
+
* there. Used by `<Checkout syncUrl>` and hosts that sync the URL after creating an order.
|
|
931
|
+
* No-ops when `routeReference` is provided (app router already owns the URL).
|
|
932
|
+
*/
|
|
933
|
+
declare function enterCheckoutResumePath(reference: string, options?: {
|
|
934
|
+
readonly pathPrefix?: string;
|
|
935
|
+
/** When set, skip History API sync (Next.js / file-based routes own the URL). */
|
|
936
|
+
readonly routeReference?: string;
|
|
937
|
+
}): void;
|
|
938
|
+
/**
|
|
939
|
+
* Guest resume fetch for a host-owned order endpoint. OpenReceive ships no order-read route.
|
|
940
|
+
* Pass the result as `fetchOrder` to {@link createGuestCheckoutResume}.
|
|
941
|
+
*/
|
|
942
|
+
declare function createGuestOrderFetcher<TOrder>(options: {
|
|
943
|
+
readonly parseOrder: (value: unknown) => TOrder | undefined;
|
|
944
|
+
/**
|
|
945
|
+
* Build the URL of the HOST APPLICATION's own order endpoint (e.g. `/orders/:id`).
|
|
946
|
+
* Nothing here is an OpenReceive route: the mounted router's routes all come from
|
|
947
|
+
* `prefix` (see ./routes.ts), and it serves no order-read endpoint at all.
|
|
948
|
+
*/
|
|
949
|
+
readonly hostOrderUrl: (reference: string) => string;
|
|
950
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
951
|
+
}): (reference: string) => Promise<TOrder | undefined>;
|
|
952
|
+
|
|
953
|
+
/** The payer-facing status: exactly {@link TransactionSettlementStatus}, derived from the server's verdict and the expiry clock. */
|
|
954
|
+
type Status = TransactionSettlementStatus;
|
|
955
|
+
interface StatusInvoiceLike {
|
|
956
|
+
readonly transaction_state?: string;
|
|
957
|
+
readonly expires_at?: number | string | null;
|
|
958
|
+
}
|
|
959
|
+
declare function deriveStatus(invoice: StatusInvoiceLike, options?: {
|
|
960
|
+
readonly now?: number;
|
|
961
|
+
}): Status;
|
|
962
|
+
|
|
963
|
+
export { OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES as $, type ThemeToggleElementAttributes as A, type BrowserLoggerOption as B, type CheckoutInvoiceSnapshot as C, type StoredThemeModelOptions as D, type ThemeModel as E, type ThemeModelOptions as F, type ReadThemePreferenceOptions as G, type ThemeControlTargets as H, type ThemeStorageOptions as I, type PaymentWizardControllerOptions as J, type PaymentWizardController as K, type PaymentWizardSelection as L, type PaymentWizardModel as M, type WizardRouteDisplay as N, type PaymentWizardSelectionAction as O, type ParseOpenReceiveOptionalIntegerOptions as P, type BrowserLogContext as Q, type ResolvedTheme as R, type SwapDisplayModel as S, type ThemePreference as T, type BrowserLogger as U, BrowserRequestError as V, type WizardRouteAssetDisplay as W, type CheckoutController as X, type CheckoutControllerOptions as Y, type CheckoutPhase as Z, type CheckoutStatusRefresh as _, type PaymentMethod as a, OPENRECEIVE_CHECKOUT_DATA_SELECTORS as a0, OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES as a1, OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS as a2, OPENRECEIVE_CHECKOUT_ELEMENT_PARTS as a3, OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS as a4, OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME as a5, OPENRECEIVE_COPY_FEEDBACK_MS as a6, OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS as a7, OPENRECEIVE_DEFAULT_PREFIX as a8, OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES as a9, formatDepositAmount as aA, formatFiatAmount as aB, formatMsats as aC, formatSwapLimit as aD, formatUnixTime as aE, openWallet as aF, prepareCheckout as aG, requestCheckout as aH, type BrowserLogLevel as aI, type BrowserLogEntry as aJ, type CopyInvoiceOptions as aK, type GuestCheckoutResumeController as aL, type GuestCheckoutResumeOptions as aM, type OpenWalletOptions as aN, type PrepareCheckoutOptions as aO, type QrOptions as aP, type RequestCheckoutOptions as aQ, type StatusInvoiceLike as aR, createGuestCheckoutResume as aS, createGuestOrderFetcher as aT, createLightningUri as aU, createQrPngDataUrl as aV, OPENRECEIVE_PAYMENT_WIZARD_SELECTORS as aa, OPENRECEIVE_THEME_STORAGE_KEY as ab, OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES as ac, OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS as ad, OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS as ae, OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS as af, OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME as ag, type QrEncoder as ah, type Status as ai, type WizardProviderDisplay as aj, assertDisplayInvoice as ak, copyInvoice as al, createCheckoutActionEvent as am, createCheckoutController as an, createCheckoutErrorEvent as ao, createCheckoutProviderCopyEvent as ap, createCheckoutStateEvent as aq, createQrPayloadSvg as ar, createQrSvg as as, createStatusFetcher as at, createThemeChangeEvent as au, deriveCheckoutStateLabels as av, deriveStatus as aw, enterCheckoutResumePath as ax, escapeHtml as ay, formatAmountCaption as az, type PaymentMethodOption as b, type TickingValueOptions as c, type TickingValueController as d, type TransientFeedbackOptions as e, type TransientFeedbackController as f, type CheckoutInvoiceSwapSnapshot as g, type CheckoutState as h, type TransactionDetailsInput as i, type TransactionDetailRow as j, type CheckoutSnapshot as k, type CreateCheckoutStateOptions as l, type CheckoutStatusModelInput as m, type CheckoutStatusModel as n, type CheckoutPaymentMethod as o, type ThemeAttributeTarget as p, type CheckoutElementAttributes as q, type CheckoutElementAttributeOptions as r, type CheckoutElementEventHandlers as s, type CheckoutElementListeners as t, type CreateCheckoutShellOptions as u, type CheckoutShellElements as v, type CheckoutShellOptions as w, type CheckoutShellModel as x, type CreateOpenReceiveThemeToggleElementOptions as y, type ThemeToggleElementAttributeOptions as z };
|