@openreceive/browser 0.1.0 → 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.
Files changed (87) hide show
  1. package/README.md +63 -0
  2. package/dist/chunk-V7C55QB2.js +2996 -0
  3. package/dist/headless.d.ts +799 -0
  4. package/dist/headless.js +932 -0
  5. package/dist/index.d.ts +32 -4
  6. package/dist/index.js +32 -2
  7. package/dist/status-CLCX5lfx.d.ts +963 -0
  8. package/dist/styles.css +3 -759
  9. package/package.json +57 -15
  10. package/dist/assets/icons/bank.svg +0 -12
  11. package/dist/assets/icons/bnb.svg +0 -1
  12. package/dist/assets/icons/card.svg +0 -14
  13. package/dist/assets/icons/doge.svg +0 -1
  14. package/dist/assets/pay_tutorials/boltz-1.webp +0 -0
  15. package/dist/assets/pay_tutorials/boltz-2.webp +0 -0
  16. package/dist/assets/pay_tutorials/cashapp-1.webp +0 -0
  17. package/dist/assets/pay_tutorials/cashapp-2.webp +0 -0
  18. package/dist/assets/pay_tutorials/cashapp-3.webp +0 -0
  19. package/dist/assets/pay_tutorials/cashapp-4.webp +0 -0
  20. package/dist/assets/pay_tutorials/cashapp-5.webp +0 -0
  21. package/dist/assets/pay_tutorials/cashapp-6.webp +0 -0
  22. package/dist/assets/pay_tutorials/coinbase-1.webp +0 -0
  23. package/dist/assets/pay_tutorials/coinbase-2.webp +0 -0
  24. package/dist/assets/pay_tutorials/fixedfloat-1.webp +0 -0
  25. package/dist/assets/pay_tutorials/fixedfloat-2.webp +0 -0
  26. package/dist/assets/pay_tutorials/kraken-1.webp +0 -0
  27. package/dist/assets/pay_tutorials/kraken-2.webp +0 -0
  28. package/dist/assets/pay_tutorials/kraken-3.webp +0 -0
  29. package/dist/assets/pay_tutorials/kraken-4.webp +0 -0
  30. package/dist/assets/pay_tutorials/strike-1.webp +0 -0
  31. package/dist/assets/pay_tutorials/strike-2.webp +0 -0
  32. package/dist/assets/pay_tutorials/strike-3.webp +0 -0
  33. package/dist/assets/pay_tutorials/strike-4.webp +0 -0
  34. package/dist/assets/provider-icons/aqua.png +0 -0
  35. package/dist/assets/provider-icons/belo.png +0 -0
  36. package/dist/assets/provider-icons/binance.png +0 -0
  37. package/dist/assets/provider-icons/bipa.png +0 -0
  38. package/dist/assets/provider-icons/bitfinex.png +0 -0
  39. package/dist/assets/provider-icons/bitget.png +0 -0
  40. package/dist/assets/provider-icons/bitnob.png +0 -0
  41. package/dist/assets/provider-icons/bitso.png +0 -0
  42. package/dist/assets/provider-icons/bity.png +0 -0
  43. package/dist/assets/provider-icons/blink.png +0 -0
  44. package/dist/assets/provider-icons/bluewallet.png +0 -0
  45. package/dist/assets/provider-icons/boltz.png +0 -0
  46. package/dist/assets/provider-icons/bringin.png +0 -0
  47. package/dist/assets/provider-icons/bullbitcoin.png +0 -0
  48. package/dist/assets/provider-icons/cakewallet.png +0 -0
  49. package/dist/assets/provider-icons/cashapp.png +0 -0
  50. package/dist/assets/provider-icons/changenow.png +0 -0
  51. package/dist/assets/provider-icons/chivo.png +0 -0
  52. package/dist/assets/provider-icons/coinbase.png +0 -0
  53. package/dist/assets/provider-icons/coincorner.png +0 -0
  54. package/dist/assets/provider-icons/fixedfloat.png +0 -0
  55. package/dist/assets/provider-icons/getalby.png +0 -0
  56. package/dist/assets/provider-icons/kraken.png +0 -0
  57. package/dist/assets/provider-icons/kryptex.png +0 -0
  58. package/dist/assets/provider-icons/kucoin.png +0 -0
  59. package/dist/assets/provider-icons/manifest.json +0 -207
  60. package/dist/assets/provider-icons/mtpelerin.png +0 -0
  61. package/dist/assets/provider-icons/muun.png +0 -0
  62. package/dist/assets/provider-icons/okcoin.png +0 -0
  63. package/dist/assets/provider-icons/okx.png +0 -0
  64. package/dist/assets/provider-icons/phoenix.png +0 -0
  65. package/dist/assets/provider-icons/pouch.png +0 -0
  66. package/dist/assets/provider-icons/ripio.png +0 -0
  67. package/dist/assets/provider-icons/river.png +0 -0
  68. package/dist/assets/provider-icons/rizful.png +0 -0
  69. package/dist/assets/provider-icons/shakepay.png +0 -0
  70. package/dist/assets/provider-icons/sideshift.png +0 -0
  71. package/dist/assets/provider-icons/simpleswap.png +0 -0
  72. package/dist/assets/provider-icons/speed.png +0 -0
  73. package/dist/assets/provider-icons/strike.png +0 -0
  74. package/dist/assets/provider-icons/trocador.png +0 -0
  75. package/dist/assets/provider-icons/walletofsatoshi.png +0 -0
  76. package/dist/assets/provider-icons/zeus.png +0 -0
  77. package/dist/country-map.d.ts +0 -5
  78. package/dist/country-map.js +0 -17
  79. package/dist/internal.d.ts +0 -834
  80. package/dist/internal.js +0 -2617
  81. package/dist/pay-tutorials.d.ts +0 -1
  82. package/dist/pay-tutorials.js +0 -42
  83. package/dist/provider-icons.d.ts +0 -1
  84. package/dist/provider-icons.js +0 -84
  85. package/dist/qrcode.d.ts +0 -11
  86. package/dist/status.d.ts +0 -9
  87. package/dist/status.js +0 -25
@@ -0,0 +1,932 @@
1
+ import {
2
+ BrowserRequestError,
3
+ OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES,
4
+ OPENRECEIVE_CHECKOUT_DATA_SELECTORS,
5
+ OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES,
6
+ OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS,
7
+ OPENRECEIVE_CHECKOUT_ELEMENT_PARTS,
8
+ OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS,
9
+ OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME,
10
+ OPENRECEIVE_COPY_FEEDBACK_MS,
11
+ OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS,
12
+ OPENRECEIVE_DEFAULT_PREFIX,
13
+ OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES,
14
+ OPENRECEIVE_PAYMENT_WIZARD_SELECTORS,
15
+ OPENRECEIVE_THEME_STORAGE_KEY,
16
+ OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES,
17
+ OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS,
18
+ OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS,
19
+ OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS,
20
+ OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME,
21
+ assertDisplayInvoice,
22
+ assetButtonClasses,
23
+ buildMethodGridEntries,
24
+ checkoutElementStyles,
25
+ checkoutLabels,
26
+ checkoutRoutes,
27
+ copyInvoice,
28
+ createBlockExplorerUrl,
29
+ createCheckoutActionEvent,
30
+ createCheckoutController,
31
+ createCheckoutErrorEvent,
32
+ createCheckoutProviderCopyEvent,
33
+ createCheckoutSnapshotFromInvoice,
34
+ createCheckoutState,
35
+ createCheckoutStateEvent,
36
+ createCheckoutStatusModel,
37
+ createDetailExternalLink,
38
+ createLightningInvoiceDecodeUrl,
39
+ createPaymentDataEntries,
40
+ createPaymentWizardController,
41
+ createPaymentWizardModel,
42
+ createPaymentWizardSelection,
43
+ createQrPayloadSvg,
44
+ createQrSvg,
45
+ createStatusFetcher,
46
+ createSwapDisplayModel,
47
+ createSwapUnavailableModel,
48
+ createThemeChangeEvent,
49
+ createTickingValueController,
50
+ createTransactionDetails,
51
+ createTransactionDetailsFromState,
52
+ createTransientFeedbackController,
53
+ createWizardRouteAssetDisplays,
54
+ createWizardRouteDisplays,
55
+ deriveCheckoutStateLabels,
56
+ deriveStatus,
57
+ enterCheckoutResumePath,
58
+ escapeHtml,
59
+ findSwapGridGroup,
60
+ formatAmountCaption,
61
+ formatChooseNetworkHeading,
62
+ formatDepositAmount,
63
+ formatFiatAmount,
64
+ formatMsats,
65
+ formatNetworkSummary,
66
+ formatSwapLimit,
67
+ formatUnixTime,
68
+ getExplorerNetwork,
69
+ getNetworkIcon,
70
+ getPaymentMethodIcon,
71
+ getRouteNetworkLabel,
72
+ getSwapOptionIcon,
73
+ getSwapRefundFormError,
74
+ getWizardEmptyMessage,
75
+ isPaidCheckoutSnapshot,
76
+ isReusableLightningInvoice,
77
+ networkButtonClasses,
78
+ networkCheckClasses,
79
+ networkMobileRevealClasses,
80
+ networkSummaryIconClasses,
81
+ openWallet,
82
+ optionalSafeInteger,
83
+ orClasses,
84
+ overlaySwapRefundStaging,
85
+ parseBooleanAttribute,
86
+ parseMethodPickerKey,
87
+ parseOptionalInteger,
88
+ parsePaymentMethod,
89
+ parseResolvedTheme,
90
+ parseThemePreference,
91
+ paymentAccentId,
92
+ paymentIconUrls,
93
+ paymentMethods,
94
+ prepareCheckout,
95
+ readJsonResponse,
96
+ requestCheckout,
97
+ requestHeaders,
98
+ resolveBrowserLogger,
99
+ resolvePreservedNetworkSelection,
100
+ resolveTransactionDetailRows,
101
+ sanitizeBrowserLogEntry,
102
+ selectCheckoutDisplayInvoice,
103
+ swapAssetMatchesRoute,
104
+ swapGroupLimitOption,
105
+ swapOptionLimitMessage,
106
+ swapPickerKey,
107
+ updatePaymentWizardSelection,
108
+ updateSelectedSwapNetworks,
109
+ wizardNetworkGroupIds
110
+ } from "./chunk-V7C55QB2.js";
111
+
112
+ // src/internal/checkout-merge.ts
113
+ function findReusableLightningInvoice(snapshot, now) {
114
+ return snapshot.invoices.find(
115
+ (invoice) => invoice.rail === "lightning" && typeof invoice.invoice === "string" && invoice.invoice.length > 0 && invoice.expires_at !== void 0 && isReusableLightningInvoice(invoice.expires_at, now)
116
+ );
117
+ }
118
+ function mergeAttemptIntoSnapshot(invoice, base) {
119
+ const withoutSame = base.invoices.filter(
120
+ (entry) => entry.invoice_id !== invoice.invoice_id && entry.rail !== "checkout_lock"
121
+ );
122
+ return {
123
+ ...base,
124
+ checkout_id: invoice.invoice_id,
125
+ active: invoice,
126
+ invoices: [invoice, ...withoutSame],
127
+ ...invoice.amount_msats === void 0 ? {} : { amount_msats: invoice.amount_msats }
128
+ };
129
+ }
130
+ function mergeAttemptIntoCheckout(invoice, previous, reference) {
131
+ const base = previous ?? {
132
+ checkout_id: invoice.invoice_id,
133
+ reference,
134
+ status: "open",
135
+ amount_msats: invoice.amount_msats ?? 0,
136
+ invoices: []
137
+ };
138
+ return mergeAttemptIntoSnapshot(invoice, base);
139
+ }
140
+ function mergeMintedCheckout(checkout, previous) {
141
+ const minted = selectCheckoutDisplayInvoice(checkout) ?? checkout.active;
142
+ if (minted === void 0) {
143
+ return {
144
+ ...checkout,
145
+ ...previous?.payment_methods === void 0 ? {} : { payment_methods: previous.payment_methods }
146
+ };
147
+ }
148
+ if (previous === void 0) return mergeAttemptIntoSnapshot(minted, checkout);
149
+ return mergeAttemptIntoSnapshot(minted, {
150
+ ...previous,
151
+ ...checkout,
152
+ invoices: previous.invoices,
153
+ payment_methods: previous.payment_methods ?? checkout.payment_methods
154
+ });
155
+ }
156
+
157
+ // src/internal/checkout-props.ts
158
+ var CREATE_MODE_ONLY_PROPS = [
159
+ "metadata",
160
+ "syncUrl",
161
+ "resumePathPrefix",
162
+ "routeReference"
163
+ ];
164
+ var warnedSnapshotModeProps = /* @__PURE__ */ new Set();
165
+ function validateCheckoutProps(props) {
166
+ const snapshot = props.checkout ?? null;
167
+ if (snapshot === null && (props.reference === void 0 || props.reference.length === 0)) {
168
+ throw new TypeError(
169
+ `${props.framework} Checkout requires a checkout snapshot or a reference (create mode).`
170
+ );
171
+ }
172
+ if (snapshot === null) return;
173
+ const ignored = CREATE_MODE_ONLY_PROPS.filter((name) => props[name] !== void 0);
174
+ if (ignored.length === 0) return;
175
+ const key = `${props.framework}:${ignored.join(",")}`;
176
+ if (warnedSnapshotModeProps.has(key)) return;
177
+ warnedSnapshotModeProps.add(key);
178
+ const warn = props.warn ?? ((message) => globalThis.console?.warn?.(message));
179
+ warn(
180
+ `${props.framework} Checkout ignores ${ignored.join(", ")} in snapshot mode; those props only apply when the component creates the checkout from a reference.`
181
+ );
182
+ }
183
+
184
+ // src/internal/checkout-session.ts
185
+ import { recordOrEmpty as recordOrEmpty2 } from "@openreceive/core";
186
+
187
+ // src/internal/swap-http.ts
188
+ import { nonEmptyString, recordOrEmpty } from "@openreceive/core";
189
+ async function postJson(options) {
190
+ const { body } = options;
191
+ const routes = checkoutRoutes(options.prefix);
192
+ const reference = nonEmptyString(body.reference);
193
+ const action = nonEmptyString(body.action);
194
+ if (action !== void 0 && action !== "swap_quote" && action !== "refund_swap") {
195
+ throw new Error(`Unrecognized checkout action ${action}.`);
196
+ }
197
+ emitSwapActionLog(options.logger, "requested", body);
198
+ try {
199
+ const result = action === "swap_quote" ? await requestJson(options, routes.swapsQuote, {
200
+ reference,
201
+ pay_in_asset: body.pay_in_asset
202
+ }) : action === "refund_swap" ? await refundRequest(options, routes, body, reference) : await requestJson(options, routes.paymentsCheck, withoutAction(body));
203
+ if (action === "refund_swap") {
204
+ emitSwapActionLog(options.logger, "succeeded", body, swapActionResultFields(result));
205
+ }
206
+ return result;
207
+ } catch (error) {
208
+ emitSwapActionLog(options.logger, "failed", body, {
209
+ error_message: error instanceof Error ? error.message : String(error)
210
+ });
211
+ throw error;
212
+ }
213
+ }
214
+ function normalizeSwapStartInvoice(body) {
215
+ const outer = recordOrEmpty(body);
216
+ const swap = recordOrEmpty(outer.swap ?? body);
217
+ const checkout = recordOrEmpty(swap.checkout);
218
+ const paymentHash = nonEmptyString(swap.payment_hash ?? checkout.payment_hash);
219
+ if (paymentHash === void 0 || nonEmptyString(swap.provider) === void 0 || nonEmptyString(swap.pay_in_asset) === void 0 || nonEmptyString(swap.deposit_address) === void 0 || nonEmptyString(swap.deposit_amount) === void 0 || nonEmptyString(swap.provider_state) === void 0 || typeof swap.provider_expires_at !== "number") {
220
+ throw new Error("Swap response did not include provider instructions.");
221
+ }
222
+ const amountMsats = optionalSafeInteger(checkout.amount_msats, "amount_msats");
223
+ return {
224
+ invoice_id: paymentHash,
225
+ rail: "swap",
226
+ payment_hash: paymentHash,
227
+ ...amountMsats === void 0 ? {} : { amount_msats: amountMsats },
228
+ transaction_state: "pending",
229
+ workflow_state: "invoice_created",
230
+ expires_at: swap.provider_expires_at,
231
+ swap: {
232
+ provider: swap.provider,
233
+ pay_in_asset: swap.pay_in_asset,
234
+ deposit_address: swap.deposit_address,
235
+ deposit_amount: swap.deposit_amount,
236
+ provider_state: swap.provider_state,
237
+ provider_expires_at: swap.provider_expires_at,
238
+ ...copyOptionalSwapFields(swap)
239
+ }
240
+ };
241
+ }
242
+ async function startSwapRequest(options) {
243
+ const logBody = {
244
+ action: "start_swap",
245
+ reference: options.reference,
246
+ pay_in_asset: options.payInAsset
247
+ };
248
+ emitSwapActionLog(options.logger, "requested", logBody);
249
+ try {
250
+ const body = await requestJson(options, checkoutRoutes(options.prefix).swaps, {
251
+ reference: options.reference,
252
+ pay_in_asset: options.payInAsset
253
+ });
254
+ emitSwapActionLog(options.logger, "succeeded", logBody, swapActionResultFields(body));
255
+ return normalizeSwapStartInvoice(body);
256
+ } catch (error) {
257
+ emitSwapActionLog(options.logger, "failed", logBody, {
258
+ error_message: error instanceof Error ? error.message : String(error)
259
+ });
260
+ throw error;
261
+ }
262
+ }
263
+ async function requestSwapRefund(options) {
264
+ const payment = options.invoices.find(
265
+ (invoice) => invoice != null && (invoice.swap?.attempt_id ?? invoice.invoice_id) === options.attemptId
266
+ );
267
+ if (payment?.payment_hash === void 0) {
268
+ throw new Error("Swap refund requires the original payment hash.");
269
+ }
270
+ const body = await postJson({
271
+ fetch: options.fetch,
272
+ prefix: options.prefix,
273
+ ...options.logger === void 0 ? {} : { logger: options.logger },
274
+ ...options.headers === void 0 ? {} : { headers: options.headers },
275
+ body: {
276
+ ...options.reference === void 0 ? {} : { reference: options.reference },
277
+ payment_hash: payment.payment_hash,
278
+ action: "refund_swap",
279
+ attempt_id: options.attemptId,
280
+ refund_address: options.refundAddress,
281
+ confirm: options.confirm
282
+ }
283
+ });
284
+ return normalizeSwapStartInvoice(body);
285
+ }
286
+ async function refundRequest(options, routes, body, reference) {
287
+ if (reference === void 0) throw new Error("Swap refund requires reference.");
288
+ const refundAddress = nonEmptyString(body.refund_address);
289
+ if (refundAddress === void 0) throw new Error("Swap refund requires refund_address.");
290
+ const paymentHash = nonEmptyString(body.payment_hash);
291
+ if (paymentHash === void 0) throw new Error("Swap refund requires payment_hash.");
292
+ if (body.confirm === true) {
293
+ const status2 = recordOrEmpty(
294
+ await requestJson(options, routes.swapsRefunds, {
295
+ reference,
296
+ payment_hash: paymentHash,
297
+ refund_address: refundAddress
298
+ })
299
+ );
300
+ return { swap: status2 };
301
+ }
302
+ const status = recordOrEmpty(
303
+ await requestJson(options, routes.swapsStatus, {
304
+ reference,
305
+ payment_hash: paymentHash
306
+ })
307
+ );
308
+ return { swap: { ...status, refund_address: refundAddress } };
309
+ }
310
+ function withoutAction(body) {
311
+ const { action: _action, ...rest } = body;
312
+ return rest;
313
+ }
314
+ async function requestJson(options, url, body) {
315
+ const fetcher = options.fetch;
316
+ const response = await fetcher(url, {
317
+ method: "POST",
318
+ headers: requestHeaders(options.headers),
319
+ body: JSON.stringify(body)
320
+ });
321
+ return readJsonResponse(response, "OpenReceive request failed.");
322
+ }
323
+ function copyOptionalSwapFields(swap) {
324
+ const output = {};
325
+ for (const key of [
326
+ "deposit_memo",
327
+ "deposit_tx_id",
328
+ "payout_tx_id",
329
+ "refund_tx_id",
330
+ "refund_reason",
331
+ "refund_amount",
332
+ "attention",
333
+ "attempt_id",
334
+ "provider_order_id",
335
+ "refund_address",
336
+ "attention_reason",
337
+ "deposit_received_amount",
338
+ "fee"
339
+ ]) {
340
+ if (swap[key] !== void 0) output[key] = swap[key];
341
+ }
342
+ return output;
343
+ }
344
+ function emitSwapActionLog(logger, outcome, body, extra = {}) {
345
+ const sink = resolveBrowserLogger(logger);
346
+ if (sink === void 0) return;
347
+ const action = nonEmptyString(body.action);
348
+ if (action !== "start_swap" && action !== "refund_swap") return;
349
+ const event = action === "start_swap" ? `swap.start.${outcome}` : `swap.refund.${outcome}`;
350
+ const level = outcome === "failed" ? "warn" : outcome === "requested" ? "debug" : "info";
351
+ try {
352
+ sink(
353
+ sanitizeBrowserLogEntry({
354
+ level,
355
+ event,
356
+ message: `${action === "start_swap" ? "Swap start" : "Swap refund"} ${outcome}.`,
357
+ reference: nonEmptyString(body.reference),
358
+ pay_in_asset: nonEmptyString(body.pay_in_asset),
359
+ ...action === "refund_swap" ? { confirm: body.confirm === true } : {},
360
+ ...extra
361
+ })
362
+ );
363
+ } catch {
364
+ }
365
+ }
366
+ function swapActionResultFields(body) {
367
+ const swap = recordOrEmpty(recordOrEmpty(body).swap ?? body);
368
+ return {
369
+ payment_hash: nonEmptyString(swap.payment_hash),
370
+ provider_state: nonEmptyString(swap.provider_state),
371
+ attention: typeof swap.attention === "boolean" ? swap.attention : void 0
372
+ };
373
+ }
374
+
375
+ // src/internal/checkout-session.ts
376
+ var SWAP_START_FAILED = "Could not prepare the payment address. Please try again.";
377
+ var MINT_FAILED = "Could not create the Lightning invoice. Please try again.";
378
+ function normalizeSwapQuote(body) {
379
+ const quote = recordOrEmpty2(recordOrEmpty2(body).quote ?? body);
380
+ const payInAsset = quote.pay_in_asset ?? quote.pay_asset;
381
+ return typeof payInAsset === "string" ? { ...quote, pay_in_asset: payInAsset } : void 0;
382
+ }
383
+ function payerFacingMessage(error, fallback) {
384
+ return error instanceof Error && error.message.length > 0 ? error.message : fallback;
385
+ }
386
+ function createCheckoutSession(options) {
387
+ let wizardError;
388
+ let swapStartError;
389
+ let lightningRequested = false;
390
+ let mintingLightning = false;
391
+ let startingSwapAsset = null;
392
+ let swapQuotes = {};
393
+ async function ensureLightning() {
394
+ if (mintingLightning) return;
395
+ const reference = options.reference();
396
+ if (reference === void 0 || reference.length === 0) return;
397
+ const current = options.snapshot();
398
+ if (current !== void 0) {
399
+ const reusableLightning = findReusableLightningInvoice(current);
400
+ if (reusableLightning !== void 0) {
401
+ lightningRequested = true;
402
+ options.onSnapshot?.(mergeAttemptIntoSnapshot(reusableLightning, current));
403
+ options.onChange();
404
+ return;
405
+ }
406
+ }
407
+ mintingLightning = true;
408
+ wizardError = void 0;
409
+ options.onChange();
410
+ try {
411
+ const pending = options.requestCheckout?.(reference);
412
+ if (pending === void 0) return;
413
+ const checkout = await pending;
414
+ lightningRequested = true;
415
+ options.onSnapshot?.(mergeMintedCheckout(checkout, options.snapshot()));
416
+ } catch (error) {
417
+ wizardError = payerFacingMessage(error, MINT_FAILED);
418
+ options.onError(error);
419
+ } finally {
420
+ mintingLightning = false;
421
+ options.onChange();
422
+ }
423
+ }
424
+ async function startSwap(payInAsset) {
425
+ if (startingSwapAsset !== null) return;
426
+ const selection = options.swapSelection;
427
+ const prefix = options.swapPrefix?.();
428
+ const fetcher = options.fetch?.();
429
+ const reference = options.reference();
430
+ if (selection === void 0 || prefix === void 0 || fetcher === void 0) return;
431
+ if (reference === void 0 || reference.length === 0) return;
432
+ const alreadyStarted = selection.started();
433
+ if (alreadyStarted?.swap?.pay_in_asset === payInAsset && alreadyStarted.invoice_id !== selection.dismissedInvoiceId()) {
434
+ selection.setSelectedAsset(payInAsset);
435
+ options.onChange();
436
+ return;
437
+ }
438
+ startingSwapAsset = payInAsset;
439
+ swapStartError = void 0;
440
+ options.onChange();
441
+ try {
442
+ const quote = await quoteSwapAsset(payInAsset, prefix, fetcher, reference);
443
+ if (quote !== void 0 && quote.available === false) return;
444
+ const started = await startSwapRequest({
445
+ fetch: fetcher,
446
+ prefix,
447
+ reference,
448
+ payInAsset,
449
+ ...options.logger === void 0 ? {} : { logger: options.logger }
450
+ });
451
+ selection.setStarted(started);
452
+ selection.setDismissedInvoiceId(null);
453
+ options.onSwapStarted?.(started);
454
+ selection.setSelectedAsset(payInAsset);
455
+ options.onChange();
456
+ } catch (error) {
457
+ const landed = selection.started();
458
+ if (landed?.swap?.pay_in_asset === payInAsset && landed.invoice_id !== selection.dismissedInvoiceId()) {
459
+ selection.setSelectedAsset(payInAsset);
460
+ options.onChange();
461
+ return;
462
+ }
463
+ selection.setSelectedAsset(payInAsset);
464
+ failSwapStart(error);
465
+ } finally {
466
+ startingSwapAsset = null;
467
+ }
468
+ }
469
+ async function quoteSwapAsset(payInAsset, prefix, fetcher, reference) {
470
+ const body = await postJson({
471
+ fetch: fetcher,
472
+ prefix,
473
+ ...options.logger === void 0 ? {} : { logger: options.logger },
474
+ body: { reference, action: "swap_quote", pay_in_asset: payInAsset }
475
+ });
476
+ const quote = normalizeSwapQuote(body);
477
+ if (quote === void 0) return void 0;
478
+ swapQuotes = { ...swapQuotes, [quote.pay_in_asset]: quote };
479
+ return quote;
480
+ }
481
+ function failSwapStart(error) {
482
+ swapStartError = payerFacingMessage(error, SWAP_START_FAILED);
483
+ options.onError(error);
484
+ options.onChange();
485
+ }
486
+ return {
487
+ get wizardError() {
488
+ return wizardError;
489
+ },
490
+ get swapStartError() {
491
+ return swapStartError;
492
+ },
493
+ get lightningRequested() {
494
+ return lightningRequested;
495
+ },
496
+ get mintingLightning() {
497
+ return mintingLightning;
498
+ },
499
+ get startingSwapAsset() {
500
+ return startingSwapAsset;
501
+ },
502
+ get swapQuotes() {
503
+ return swapQuotes;
504
+ },
505
+ ensureLightning,
506
+ startSwap,
507
+ resetLightningRequest() {
508
+ lightningRequested = false;
509
+ },
510
+ clearSwapStartError() {
511
+ swapStartError = void 0;
512
+ }
513
+ };
514
+ }
515
+
516
+ // src/internal/theme.ts
517
+ function readThemePreference(options = {}) {
518
+ const value = readStorageValue(
519
+ options.storage ?? getBrowserStorage(),
520
+ options.storageKey ?? OPENRECEIVE_THEME_STORAGE_KEY
521
+ );
522
+ return value === "light" || value === "dark" || value === "system" ? value : options.defaultTheme ?? "system";
523
+ }
524
+ function writeThemePreference(theme, options = {}) {
525
+ writeStorageValue(
526
+ options.storage ?? getBrowserStorage(),
527
+ options.storageKey ?? OPENRECEIVE_THEME_STORAGE_KEY,
528
+ theme
529
+ );
530
+ }
531
+ function resolveTheme(theme, options = {}) {
532
+ if (theme === "light" || theme === "dark") return theme;
533
+ if (options.systemDark !== void 0) return options.systemDark ? "dark" : "light";
534
+ return globalThis.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
535
+ }
536
+ function getNextThemePreference(theme, options = {}) {
537
+ return resolveTheme(theme, options) === "dark" ? "light" : "dark";
538
+ }
539
+ function getThemeToggleLabel(resolvedTheme) {
540
+ return `${resolvedTheme} mode`;
541
+ }
542
+ function createThemeModel(theme, options = {}) {
543
+ const resolvedTheme = resolveTheme(theme, options);
544
+ return {
545
+ theme,
546
+ resolvedTheme,
547
+ nextTheme: getNextThemePreference(theme, options),
548
+ toggleLabel: getThemeToggleLabel(resolvedTheme),
549
+ attributes: {
550
+ "data-theme": resolvedTheme,
551
+ "data-openreceive-theme": resolvedTheme
552
+ },
553
+ checkoutElementAttributes: {
554
+ theme: resolvedTheme
555
+ }
556
+ };
557
+ }
558
+ function createStoredThemeModel(options = {}) {
559
+ const theme = readThemePreference(options);
560
+ return createThemeModel(theme, { systemDark: options.systemDark });
561
+ }
562
+ function toggleStoredThemePreference(options = {}) {
563
+ const currentTheme = createStoredThemeModel(options);
564
+ writeThemePreference(currentTheme.nextTheme, options);
565
+ return createStoredThemeModel(options);
566
+ }
567
+ function applyThemeAttributes(target, theme) {
568
+ if (target === null || target === void 0) return;
569
+ for (const [name, value] of Object.entries(theme.attributes)) {
570
+ if (target.getAttribute(name) !== value) target.setAttribute(name, value);
571
+ }
572
+ }
573
+ function applyCheckoutThemeAttributes(target, theme) {
574
+ if (target === null || target === void 0) return;
575
+ for (const [name, value] of Object.entries(theme.checkoutElementAttributes)) {
576
+ if (target.getAttribute(name) !== value) target.setAttribute(name, value);
577
+ }
578
+ }
579
+ function applyThemeControls(targets, theme) {
580
+ applyThemeAttributes(targets.root, theme);
581
+ applyCheckoutThemeAttributes(targets.checkout, theme);
582
+ if (targets.toggle !== null && targets.toggle !== void 0) {
583
+ targets.toggle.textContent = theme.toggleLabel;
584
+ }
585
+ }
586
+ function syncStoredThemeControls(targets, options = {}) {
587
+ const theme = createStoredThemeModel(options);
588
+ applyThemeControls(targets, theme);
589
+ return theme;
590
+ }
591
+ function toggleStoredThemeControls(targets, options = {}) {
592
+ const theme = toggleStoredThemePreference(options);
593
+ applyThemeControls(targets, theme);
594
+ return theme;
595
+ }
596
+ function readStorageValue(storage, key) {
597
+ try {
598
+ return storage?.getItem(key) ?? null;
599
+ } catch {
600
+ return null;
601
+ }
602
+ }
603
+ function writeStorageValue(storage, key, value) {
604
+ try {
605
+ storage?.setItem(key, value);
606
+ } catch {
607
+ }
608
+ }
609
+ function getBrowserStorage() {
610
+ try {
611
+ return globalThis.localStorage;
612
+ } catch {
613
+ return void 0;
614
+ }
615
+ }
616
+
617
+ // src/internal/elements.ts
618
+ function createModeAttributes(options) {
619
+ const attributes = {};
620
+ if (options.metadata !== void 0) {
621
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.metadata] = JSON.stringify(options.metadata);
622
+ }
623
+ if (options.syncUrl === true) {
624
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.syncUrl] = "";
625
+ }
626
+ if (options.resumePathPrefix !== void 0) {
627
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.resumePathPrefix] = options.resumePathPrefix;
628
+ }
629
+ if (options.routeReference !== void 0) {
630
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.routeReference] = options.routeReference;
631
+ }
632
+ return attributes;
633
+ }
634
+ function sharedElementAttributes(options) {
635
+ const attributes = {};
636
+ const isSet = (value) => value !== void 0 && value !== null;
637
+ if (isSet(options.prefix)) {
638
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.prefix] = options.prefix;
639
+ }
640
+ if (isSet(options.theme)) {
641
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.theme] = options.theme;
642
+ }
643
+ if (options.paymentWizard !== void 0) {
644
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.paymentWizard] = String(
645
+ options.paymentWizard
646
+ );
647
+ }
648
+ if (options.decodeLinkUrl !== void 0) {
649
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.decodeLinkUrl] = options.decodeLinkUrl;
650
+ }
651
+ if (options.polling !== void 0) {
652
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.polling] = String(options.polling);
653
+ }
654
+ if (options.pollIntervalMs !== void 0) {
655
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.pollIntervalMs] = String(
656
+ options.pollIntervalMs
657
+ );
658
+ }
659
+ return attributes;
660
+ }
661
+ function createCheckoutElementAttributes(snapshot, options = {}) {
662
+ if (snapshot === null) {
663
+ if (options.reference === void 0 || options.reference.length === 0) {
664
+ throw new TypeError(
665
+ "OpenReceive checkout element create mode requires a reference when no snapshot is given."
666
+ );
667
+ }
668
+ return {
669
+ [OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.reference]: options.reference,
670
+ ...sharedElementAttributes(options),
671
+ ...createModeAttributes(options)
672
+ };
673
+ }
674
+ const displayInvoice = selectCheckoutDisplayInvoice(snapshot);
675
+ const bolt11 = displayInvoice?.invoice;
676
+ if (displayInvoice === void 0 || typeof bolt11 !== "string") {
677
+ const deferred = {
678
+ [OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.reference]: snapshot.reference,
679
+ ...sharedElementAttributes(options),
680
+ ...createModeAttributes(options)
681
+ };
682
+ if (snapshot.amount_msats !== void 0) {
683
+ deferred[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.amountMsats] = String(snapshot.amount_msats);
684
+ }
685
+ return deferred;
686
+ }
687
+ const invoice = displayInvoice;
688
+ assertDisplayInvoice(bolt11);
689
+ const attributes = {
690
+ [OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.reference]: snapshot.reference,
691
+ [OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.invoiceId]: invoice.invoice_id,
692
+ [OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.invoice]: bolt11,
693
+ [OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.rail]: invoice.rail
694
+ };
695
+ if (invoice.payment_hash !== void 0) {
696
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.paymentHash] = invoice.payment_hash;
697
+ }
698
+ const amountMsats = invoice.amount_msats ?? snapshot.amount_msats;
699
+ if (amountMsats !== void 0) {
700
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.amountMsats] = String(amountMsats);
701
+ }
702
+ const fiat = invoice.fiat_quote?.fiat ?? snapshot.fiat;
703
+ if (fiat?.currency !== void 0) {
704
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.fiatCurrency] = fiat.currency;
705
+ }
706
+ if (fiat?.value !== void 0) {
707
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.fiatValue] = fiat.value;
708
+ }
709
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.status] = isPaidCheckoutSnapshot(snapshot) ? "settled" : snapshot.status === "expired" ? "expired" : deriveStatus(invoice);
710
+ if (invoice.expires_at !== void 0) {
711
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.expiresAt] = String(invoice.expires_at);
712
+ }
713
+ return { ...attributes, ...sharedElementAttributes(options) };
714
+ }
715
+ function createThemeToggleElementAttributes(options = {}) {
716
+ return {
717
+ ...options.rootSelector === void 0 ? {} : { [OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES.rootSelector]: options.rootSelector },
718
+ ...options.checkoutSelector === void 0 ? {} : {
719
+ [OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES.checkoutSelector]: options.checkoutSelector
720
+ },
721
+ ...options.defaultTheme === void 0 ? {} : { [OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES.defaultTheme]: options.defaultTheme },
722
+ ...options.storageKey === void 0 ? {} : { [OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES.storageKey]: options.storageKey }
723
+ };
724
+ }
725
+ function createCheckoutElementListeners(handlers = {}) {
726
+ return {
727
+ ...handlers.onCopy === void 0 ? {} : { [OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.copy]: handlers.onCopy },
728
+ ...handlers.onOpenWallet === void 0 ? {} : { [OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.openWallet]: handlers.onOpenWallet },
729
+ ...handlers.onState === void 0 ? {} : { [OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.state]: handlers.onState },
730
+ ...handlers.onSettled === void 0 ? {} : { [OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.settled]: handlers.onSettled },
731
+ ...handlers.onProviderCopy === void 0 ? {} : { [OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.providerCopy]: handlers.onProviderCopy },
732
+ ...handlers.onStartOver === void 0 ? {} : { [OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.startOver]: handlers.onStartOver },
733
+ ...handlers.onError === void 0 ? {} : { [OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS.error]: handlers.onError }
734
+ };
735
+ }
736
+ function createCheckoutShellModel(snapshot, options = {}) {
737
+ const theme = createStoredThemeModel(options);
738
+ const ownTheme = options.themeToggle !== false;
739
+ return {
740
+ theme,
741
+ rootAttributes: ownTheme ? theme.attributes : {},
742
+ checkout: {
743
+ tagName: OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME,
744
+ attributes: createCheckoutElementAttributes(snapshot, {
745
+ ...options,
746
+ ...ownTheme ? { theme: theme.resolvedTheme } : {}
747
+ }),
748
+ listeners: createCheckoutElementListeners(options)
749
+ },
750
+ themeToggle: ownTheme ? {
751
+ tagName: OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME,
752
+ attributes: createThemeToggleElementAttributes({
753
+ rootSelector: options.rootSelector,
754
+ checkoutSelector: options.checkoutSelector ?? OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME,
755
+ defaultTheme: options.defaultTheme,
756
+ storageKey: options.storageKey
757
+ })
758
+ } : null
759
+ };
760
+ }
761
+ function applyCheckoutElementAttributes(target, attributes) {
762
+ for (const [name, value] of Object.entries(attributes)) {
763
+ if (value !== void 0 && value !== null) target.setAttribute(name, value);
764
+ }
765
+ }
766
+ function applyCheckoutElementListeners(target, listeners) {
767
+ for (const [name, listener] of Object.entries(listeners)) {
768
+ if (listener !== void 0) target.addEventListener(name, listener);
769
+ }
770
+ }
771
+ function applyThemeToggleElementAttributes(target, attributes) {
772
+ for (const [name, value] of Object.entries(attributes)) {
773
+ if (value !== void 0) target.setAttribute(name, value);
774
+ }
775
+ }
776
+ function createThemeToggleElement(options = {}) {
777
+ const ownerDocument = options.document ?? globalThis.document;
778
+ if (ownerDocument === void 0) {
779
+ throw new Error("OpenReceive theme toggle element creation requires document.");
780
+ }
781
+ const element = ownerDocument.createElement(OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME);
782
+ applyThemeToggleElementAttributes(element, createThemeToggleElementAttributes(options));
783
+ return element;
784
+ }
785
+ function createCheckoutShell(snapshot, options = {}) {
786
+ const ownerDocument = options.document ?? globalThis.document;
787
+ if (ownerDocument === void 0) {
788
+ throw new Error("OpenReceive checkout shell creation requires document.");
789
+ }
790
+ const shell = createCheckoutShellModel(snapshot, options);
791
+ if (shell.themeToggle !== null) {
792
+ applyThemeAttributes(options.root, shell.theme);
793
+ }
794
+ const checkout = ownerDocument.createElement(shell.checkout.tagName);
795
+ applyCheckoutElementAttributes(checkout, shell.checkout.attributes);
796
+ applyCheckoutElementListeners(checkout, shell.checkout.listeners);
797
+ let themeToggle = null;
798
+ if (shell.themeToggle !== null) {
799
+ themeToggle = ownerDocument.createElement(shell.themeToggle.tagName);
800
+ applyThemeToggleElementAttributes(themeToggle, shell.themeToggle.attributes);
801
+ }
802
+ return {
803
+ theme: shell.theme,
804
+ rootAttributes: shell.rootAttributes,
805
+ checkout,
806
+ themeToggle
807
+ };
808
+ }
809
+ export {
810
+ BrowserRequestError,
811
+ OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES,
812
+ OPENRECEIVE_CHECKOUT_DATA_SELECTORS,
813
+ OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES,
814
+ OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS,
815
+ OPENRECEIVE_CHECKOUT_ELEMENT_PARTS,
816
+ OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS,
817
+ OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME,
818
+ OPENRECEIVE_COPY_FEEDBACK_MS,
819
+ OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS,
820
+ OPENRECEIVE_DEFAULT_PREFIX,
821
+ OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES,
822
+ OPENRECEIVE_PAYMENT_WIZARD_SELECTORS,
823
+ OPENRECEIVE_THEME_STORAGE_KEY,
824
+ OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES,
825
+ OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS,
826
+ OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS,
827
+ OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS,
828
+ OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME,
829
+ applyCheckoutElementAttributes,
830
+ assertDisplayInvoice,
831
+ assetButtonClasses,
832
+ buildMethodGridEntries,
833
+ checkoutElementStyles,
834
+ checkoutLabels,
835
+ copyInvoice,
836
+ createBlockExplorerUrl,
837
+ createCheckoutActionEvent,
838
+ createCheckoutController,
839
+ createCheckoutElementAttributes,
840
+ createCheckoutElementListeners,
841
+ createCheckoutErrorEvent,
842
+ createCheckoutProviderCopyEvent,
843
+ createCheckoutSession,
844
+ createCheckoutShell,
845
+ createCheckoutShellModel,
846
+ createCheckoutSnapshotFromInvoice,
847
+ createCheckoutState,
848
+ createCheckoutStateEvent,
849
+ createCheckoutStatusModel,
850
+ createDetailExternalLink,
851
+ createLightningInvoiceDecodeUrl,
852
+ createPaymentDataEntries,
853
+ createPaymentWizardController,
854
+ createPaymentWizardModel,
855
+ createPaymentWizardSelection,
856
+ createQrPayloadSvg,
857
+ createQrSvg,
858
+ createStatusFetcher,
859
+ createStoredThemeModel,
860
+ createSwapDisplayModel,
861
+ createSwapUnavailableModel,
862
+ createThemeChangeEvent,
863
+ createThemeModel,
864
+ createThemeToggleElement,
865
+ createThemeToggleElementAttributes,
866
+ createTickingValueController,
867
+ createTransactionDetails,
868
+ createTransactionDetailsFromState,
869
+ createTransientFeedbackController,
870
+ createWizardRouteAssetDisplays,
871
+ createWizardRouteDisplays,
872
+ deriveCheckoutStateLabels,
873
+ deriveStatus,
874
+ enterCheckoutResumePath,
875
+ escapeHtml,
876
+ findSwapGridGroup,
877
+ formatAmountCaption,
878
+ formatChooseNetworkHeading,
879
+ formatDepositAmount,
880
+ formatFiatAmount,
881
+ formatMsats,
882
+ formatNetworkSummary,
883
+ formatSwapLimit,
884
+ formatUnixTime,
885
+ getExplorerNetwork,
886
+ getNetworkIcon,
887
+ getPaymentMethodIcon,
888
+ getRouteNetworkLabel,
889
+ getSwapOptionIcon,
890
+ getSwapRefundFormError,
891
+ getWizardEmptyMessage,
892
+ isReusableLightningInvoice,
893
+ mergeAttemptIntoCheckout,
894
+ mergeAttemptIntoSnapshot,
895
+ networkButtonClasses,
896
+ networkCheckClasses,
897
+ networkMobileRevealClasses,
898
+ networkSummaryIconClasses,
899
+ normalizeSwapStartInvoice,
900
+ openWallet,
901
+ orClasses,
902
+ overlaySwapRefundStaging,
903
+ parseBooleanAttribute,
904
+ parseMethodPickerKey,
905
+ parseOptionalInteger,
906
+ parsePaymentMethod,
907
+ parseResolvedTheme,
908
+ parseThemePreference,
909
+ paymentAccentId,
910
+ paymentIconUrls,
911
+ paymentMethods,
912
+ postJson,
913
+ prepareCheckout,
914
+ readThemePreference,
915
+ requestCheckout,
916
+ requestSwapRefund,
917
+ resolvePreservedNetworkSelection,
918
+ resolveTransactionDetailRows,
919
+ selectCheckoutDisplayInvoice,
920
+ startSwapRequest,
921
+ swapAssetMatchesRoute,
922
+ swapGroupLimitOption,
923
+ swapOptionLimitMessage,
924
+ swapPickerKey,
925
+ syncStoredThemeControls,
926
+ toggleStoredThemeControls,
927
+ updatePaymentWizardSelection,
928
+ updateSelectedSwapNetworks,
929
+ validateCheckoutProps,
930
+ wizardNetworkGroupIds,
931
+ writeThemePreference
932
+ };