@openreceive/browser 0.2.4 → 0.3.0

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/dist/headless.js CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS,
7
7
  OPENRECEIVE_CHECKOUT_ELEMENT_PARTS,
8
8
  OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS,
9
+ OPENRECEIVE_CHECKOUT_ELEMENT_SLOTS,
9
10
  OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME,
10
11
  OPENRECEIVE_COPY_FEEDBACK_MS,
11
12
  OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS,
@@ -23,7 +24,6 @@ import {
23
24
  buildMethodGridEntries,
24
25
  checkoutElementStyles,
25
26
  checkoutLabels,
26
- checkoutRoutes,
27
27
  copyInvoice,
28
28
  createBlockExplorerUrl,
29
29
  createCheckoutActionEvent,
@@ -36,7 +36,7 @@ import {
36
36
  createCheckoutStatusModel,
37
37
  createDetailExternalLink,
38
38
  createLightningInvoiceDecodeUrl,
39
- createPaymentDataEntries,
39
+ createMethodGridDisplay,
40
40
  createPaymentWizardController,
41
41
  createPaymentWizardModel,
42
42
  createPaymentWizardSelection,
@@ -57,9 +57,7 @@ import {
57
57
  enterCheckoutResumePath,
58
58
  escapeHtml,
59
59
  findReusableLightningInvoice,
60
- findSwapGridGroup,
61
60
  formatAmountCaption,
62
- formatChooseNetworkHeading,
63
61
  formatDepositAmount,
64
62
  formatFiatAmount,
65
63
  formatMsats,
@@ -69,6 +67,7 @@ import {
69
67
  getExplorerNetwork,
70
68
  getNetworkIcon,
71
69
  getPaymentMethodIcon,
70
+ getRouteIconPath,
72
71
  getRouteNetworkLabel,
73
72
  getSwapOptionIcon,
74
73
  getSwapRefundFormError,
@@ -82,10 +81,9 @@ import {
82
81
  networkCheckClasses,
83
82
  networkMobileRevealClasses,
84
83
  networkSummaryIconClasses,
84
+ normalizeSwapStartInvoice,
85
85
  openWallet,
86
- optionalSafeInteger,
87
86
  orClasses,
88
- overlaySwapRefundStaging,
89
87
  parseBooleanAttribute,
90
88
  parseMethodPickerKey,
91
89
  parseOptionalInteger,
@@ -96,25 +94,22 @@ import {
96
94
  paymentIconPaths,
97
95
  paymentIconUrls,
98
96
  paymentMethods,
97
+ postJson,
99
98
  prepareCheckout,
100
- readJsonResponse,
101
99
  requestCheckout,
102
- requestHeaders,
103
- resolveBrowserLogger,
104
- resolvePreservedNetworkSelection,
100
+ requestSwapRefund,
105
101
  resolveTransactionDetailRows,
106
- sanitizeBrowserLogEntry,
102
+ resolveWizardSelection,
107
103
  selectCheckoutDisplayInvoice,
104
+ selectCurrentSwapInvoice,
105
+ startSwapRequest,
108
106
  swapAssetMatchesRoute,
109
107
  swapDepositRisk,
110
- swapGroupLimitOption,
111
108
  swapOptionLimitMessage,
112
109
  swapOptionLimitSentence,
113
110
  swapPickerKey,
114
- updatePaymentWizardSelection,
115
- updateSelectedSwapNetworks,
116
- wizardNetworkGroupIds
117
- } from "./chunk-GA4FMG7L.js";
111
+ updatePaymentWizardSelection
112
+ } from "./chunk-NVEGYGZ5.js";
118
113
 
119
114
  // src/internal/checkout-props.ts
120
115
  var CREATE_MODE_ONLY_PROPS = [
@@ -144,201 +139,11 @@ function validateCheckoutProps(props) {
144
139
  }
145
140
 
146
141
  // src/internal/checkout-session.ts
147
- import { recordOrEmpty as recordOrEmpty2 } from "@openreceive/core";
148
-
149
- // src/internal/swap-http.ts
150
- import { nonEmptyString, recordOrEmpty } from "@openreceive/core";
151
- async function postJson(options) {
152
- const { body } = options;
153
- const routes = checkoutRoutes(options.prefix);
154
- const reference = nonEmptyString(body.reference);
155
- const action = nonEmptyString(body.action);
156
- if (action !== void 0 && action !== "swap_quote" && action !== "refund_swap") {
157
- throw new Error(`Unrecognized checkout action ${action}.`);
158
- }
159
- emitSwapActionLog(options.logger, "requested", body);
160
- try {
161
- const result = action === "swap_quote" ? await requestJson(options, routes.swapsQuote, {
162
- reference,
163
- pay_in_asset: body.pay_in_asset
164
- }) : action === "refund_swap" ? await refundRequest(options, routes, body, reference) : await requestJson(options, routes.paymentsCheck, withoutAction(body));
165
- if (action === "refund_swap") {
166
- emitSwapActionLog(options.logger, "succeeded", body, swapActionResultFields(result));
167
- }
168
- return result;
169
- } catch (error) {
170
- emitSwapActionLog(options.logger, "failed", body, {
171
- error_message: error instanceof Error ? error.message : String(error)
172
- });
173
- throw error;
174
- }
175
- }
176
- function normalizeSwapStartInvoice(body) {
177
- const outer = recordOrEmpty(body);
178
- const swap = recordOrEmpty(outer.swap ?? body);
179
- const checkout = recordOrEmpty(swap.checkout);
180
- const paymentHash = nonEmptyString(swap.payment_hash ?? checkout.payment_hash);
181
- 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") {
182
- throw new Error("Swap response did not include provider instructions.");
183
- }
184
- const amountMsats = optionalSafeInteger(checkout.amount_msats, "amount_msats");
185
- return {
186
- invoice_id: paymentHash,
187
- rail: "swap",
188
- payment_hash: paymentHash,
189
- ...amountMsats === void 0 ? {} : { amount_msats: amountMsats },
190
- transaction_state: "pending",
191
- workflow_state: "invoice_created",
192
- expires_at: swap.provider_expires_at,
193
- swap: {
194
- provider: swap.provider,
195
- pay_in_asset: swap.pay_in_asset,
196
- deposit_address: swap.deposit_address,
197
- deposit_amount: swap.deposit_amount,
198
- provider_state: swap.provider_state,
199
- provider_expires_at: swap.provider_expires_at,
200
- ...copyOptionalSwapFields(swap)
201
- }
202
- };
203
- }
204
- async function startSwapRequest(options) {
205
- const logBody = {
206
- action: "start_swap",
207
- reference: options.reference,
208
- pay_in_asset: options.payInAsset
209
- };
210
- emitSwapActionLog(options.logger, "requested", logBody);
211
- try {
212
- const body = await requestJson(options, checkoutRoutes(options.prefix).swaps, {
213
- reference: options.reference,
214
- pay_in_asset: options.payInAsset
215
- });
216
- emitSwapActionLog(options.logger, "succeeded", logBody, swapActionResultFields(body));
217
- return normalizeSwapStartInvoice(body);
218
- } catch (error) {
219
- emitSwapActionLog(options.logger, "failed", logBody, {
220
- error_message: error instanceof Error ? error.message : String(error)
221
- });
222
- throw error;
223
- }
224
- }
225
- async function requestSwapRefund(options) {
226
- const payment = options.invoices.find(
227
- (invoice) => invoice != null && (invoice.swap?.attempt_id ?? invoice.invoice_id) === options.attemptId
228
- );
229
- if (payment?.payment_hash === void 0) {
230
- throw new Error("Swap refund requires the original payment hash.");
231
- }
232
- const body = await postJson({
233
- fetch: options.fetch,
234
- prefix: options.prefix,
235
- ...options.logger === void 0 ? {} : { logger: options.logger },
236
- ...options.headers === void 0 ? {} : { headers: options.headers },
237
- body: {
238
- ...options.reference === void 0 ? {} : { reference: options.reference },
239
- payment_hash: payment.payment_hash,
240
- action: "refund_swap",
241
- attempt_id: options.attemptId,
242
- refund_address: options.refundAddress,
243
- confirm: options.confirm
244
- }
245
- });
246
- return normalizeSwapStartInvoice(body);
247
- }
248
- async function refundRequest(options, routes, body, reference) {
249
- if (reference === void 0) throw new Error("Swap refund requires reference.");
250
- const refundAddress = nonEmptyString(body.refund_address);
251
- if (refundAddress === void 0) throw new Error("Swap refund requires refund_address.");
252
- const paymentHash = nonEmptyString(body.payment_hash);
253
- if (paymentHash === void 0) throw new Error("Swap refund requires payment_hash.");
254
- if (body.confirm === true) {
255
- const status2 = recordOrEmpty(
256
- await requestJson(options, routes.swapsRefunds, {
257
- reference,
258
- payment_hash: paymentHash,
259
- refund_address: refundAddress
260
- })
261
- );
262
- return { swap: status2 };
263
- }
264
- const status = recordOrEmpty(
265
- await requestJson(options, routes.swapsStatus, {
266
- reference,
267
- payment_hash: paymentHash
268
- })
269
- );
270
- return { swap: { ...status, refund_address: refundAddress } };
271
- }
272
- function withoutAction(body) {
273
- const { action: _action, ...rest } = body;
274
- return rest;
275
- }
276
- async function requestJson(options, url, body) {
277
- const fetcher = options.fetch;
278
- const response = await fetcher(url, {
279
- method: "POST",
280
- headers: requestHeaders(options.headers),
281
- body: JSON.stringify(body)
282
- });
283
- return readJsonResponse(response, "OpenReceive request failed.");
284
- }
285
- function copyOptionalSwapFields(swap) {
286
- const output = {};
287
- for (const key of [
288
- "deposit_memo",
289
- "deposit_tx_id",
290
- "payout_tx_id",
291
- "refund_tx_id",
292
- "refund_reason",
293
- "refund_amount",
294
- "attention",
295
- "attempt_id",
296
- "provider_order_id",
297
- "refund_address",
298
- "attention_reason",
299
- "deposit_received_amount",
300
- "fee"
301
- ]) {
302
- if (swap[key] !== void 0) output[key] = swap[key];
303
- }
304
- return output;
305
- }
306
- function emitSwapActionLog(logger, outcome, body, extra = {}) {
307
- const sink = resolveBrowserLogger(logger);
308
- if (sink === void 0) return;
309
- const action = nonEmptyString(body.action);
310
- if (action !== "start_swap" && action !== "refund_swap") return;
311
- const event = action === "start_swap" ? `swap.start.${outcome}` : `swap.refund.${outcome}`;
312
- const level = outcome === "failed" ? "warn" : outcome === "requested" ? "debug" : "info";
313
- try {
314
- sink(
315
- sanitizeBrowserLogEntry({
316
- level,
317
- event,
318
- message: `${action === "start_swap" ? "Swap start" : "Swap refund"} ${outcome}.`,
319
- reference: nonEmptyString(body.reference),
320
- pay_in_asset: nonEmptyString(body.pay_in_asset),
321
- ...action === "refund_swap" ? { confirm: body.confirm === true } : {},
322
- ...extra
323
- })
324
- );
325
- } catch {
326
- }
327
- }
328
- function swapActionResultFields(body) {
329
- const swap = recordOrEmpty(recordOrEmpty(body).swap ?? body);
330
- return {
331
- payment_hash: nonEmptyString(swap.payment_hash),
332
- provider_state: nonEmptyString(swap.provider_state),
333
- attention: typeof swap.attention === "boolean" ? swap.attention : void 0
334
- };
335
- }
336
-
337
- // src/internal/checkout-session.ts
142
+ import { recordOrEmpty } from "@openreceive/core";
338
143
  var SWAP_START_FAILED = "Could not prepare the payment address. Please try again.";
339
144
  var MINT_FAILED = "Could not create the Lightning invoice. Please try again.";
340
145
  function normalizeSwapQuote(body) {
341
- const quote = recordOrEmpty2(recordOrEmpty2(body).quote ?? body);
146
+ const quote = recordOrEmpty(recordOrEmpty(body).quote ?? body);
342
147
  const payInAsset = quote.pay_in_asset ?? quote.pay_asset;
343
148
  return typeof payInAsset === "string" ? { ...quote, pay_in_asset: payInAsset } : void 0;
344
149
  }
@@ -610,6 +415,9 @@ function sharedElementAttributes(options) {
610
415
  if (options.decodeLinkUrl !== void 0) {
611
416
  attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.decodeLinkUrl] = options.decodeLinkUrl;
612
417
  }
418
+ if (isSet(options.assetBaseUrl)) {
419
+ attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.assetBaseUrl] = options.assetBaseUrl;
420
+ }
613
421
  if (options.polling !== void 0) {
614
422
  attributes[OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.polling] = String(options.polling);
615
423
  }
@@ -768,6 +576,9 @@ function createCheckoutShell(snapshot, options = {}) {
768
576
  themeToggle
769
577
  };
770
578
  }
579
+
580
+ // src/headless.ts
581
+ import { createAssetBaseUrlResolver } from "@openreceive/provider-data";
771
582
  export {
772
583
  BrowserRequestError,
773
584
  OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES,
@@ -776,6 +587,7 @@ export {
776
587
  OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS,
777
588
  OPENRECEIVE_CHECKOUT_ELEMENT_PARTS,
778
589
  OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS,
590
+ OPENRECEIVE_CHECKOUT_ELEMENT_SLOTS,
779
591
  OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME,
780
592
  OPENRECEIVE_COPY_FEEDBACK_MS,
781
593
  OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS,
@@ -795,6 +607,7 @@ export {
795
607
  checkoutElementStyles,
796
608
  checkoutLabels,
797
609
  copyInvoice,
610
+ createAssetBaseUrlResolver,
798
611
  createBlockExplorerUrl,
799
612
  createCheckoutActionEvent,
800
613
  createCheckoutController,
@@ -811,7 +624,7 @@ export {
811
624
  createCheckoutStatusModel,
812
625
  createDetailExternalLink,
813
626
  createLightningInvoiceDecodeUrl,
814
- createPaymentDataEntries,
627
+ createMethodGridDisplay,
815
628
  createPaymentWizardController,
816
629
  createPaymentWizardModel,
817
630
  createPaymentWizardSelection,
@@ -835,9 +648,7 @@ export {
835
648
  deriveStatus,
836
649
  enterCheckoutResumePath,
837
650
  escapeHtml,
838
- findSwapGridGroup,
839
651
  formatAmountCaption,
840
- formatChooseNetworkHeading,
841
652
  formatDepositAmount,
842
653
  formatFiatAmount,
843
654
  formatMsats,
@@ -847,6 +658,7 @@ export {
847
658
  getExplorerNetwork,
848
659
  getNetworkIcon,
849
660
  getPaymentMethodIcon,
661
+ getRouteIconPath,
850
662
  getRouteNetworkLabel,
851
663
  getSwapOptionIcon,
852
664
  getSwapRefundFormError,
@@ -861,7 +673,6 @@ export {
861
673
  normalizeSwapStartInvoice,
862
674
  openWallet,
863
675
  orClasses,
864
- overlaySwapRefundStaging,
865
676
  parseBooleanAttribute,
866
677
  parseMethodPickerKey,
867
678
  parseOptionalInteger,
@@ -877,21 +688,19 @@ export {
877
688
  readThemePreference,
878
689
  requestCheckout,
879
690
  requestSwapRefund,
880
- resolvePreservedNetworkSelection,
881
691
  resolveTransactionDetailRows,
692
+ resolveWizardSelection,
882
693
  selectCheckoutDisplayInvoice,
694
+ selectCurrentSwapInvoice,
883
695
  startSwapRequest,
884
696
  swapAssetMatchesRoute,
885
697
  swapDepositRisk,
886
- swapGroupLimitOption,
887
698
  swapOptionLimitMessage,
888
699
  swapOptionLimitSentence,
889
700
  swapPickerKey,
890
701
  syncStoredThemeControls,
891
702
  toggleStoredThemeControls,
892
703
  updatePaymentWizardSelection,
893
- updateSelectedSwapNetworks,
894
704
  validateCheckoutProps,
895
- wizardNetworkGroupIds,
896
705
  writeThemePreference
897
706
  };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { aK as BrowserLogLevel } from './status-D3VhJsUp.js';
2
- export { aL as BrowserLogEntry, X as BrowserLogger, B as BrowserLoggerOption, Y as BrowserRequestError, Z as CheckoutController, _ as CheckoutControllerOptions, l as CheckoutSnapshot, i as CheckoutState, aM as CopyInvoiceOptions, aN as GuestCheckoutResumeController, aO as GuestCheckoutResumeOptions, aP as OpenWalletOptions, aQ as PrepareCheckoutOptions, aR as QrOptions, aS as RequestCheckoutOptions, ak as Status, aT as StatusInvoiceLike, U as UnixSeconds, an as copyInvoice, ap as createCheckoutController, aU as createGuestCheckoutResume, aV as createGuestOrderFetcher, aW as createLightningUri, aX as createQrPngDataUrl, au as createQrSvg, ay as deriveStatus, az as enterCheckoutResumePath, aH as openWallet, aI as prepareCheckout, aJ as requestCheckout } from './status-D3VhJsUp.js';
1
+ import { aM as BrowserLogLevel } from './status-C-zvqBau.js';
2
+ export { aN as BrowserLogEntry, V as BrowserLogger, B as BrowserLoggerOption, X as BrowserRequestError, Y as CheckoutController, Z as CheckoutControllerOptions, g as CheckoutSnapshot, i as CheckoutState, aO as CopyInvoiceOptions, aP as GuestCheckoutResumeController, aQ as GuestCheckoutResumeOptions, aR as OpenWalletOptions, aS as PrepareCheckoutOptions, aT as QrOptions, aU as RequestCheckoutOptions, ak as Status, aV as StatusInvoiceLike, U as UnixSeconds, ap as copyInvoice, ar as createCheckoutController, aW as createGuestCheckoutResume, aX as createGuestOrderFetcher, aY as createLightningUri, aZ as createQrPngDataUrl, aw as createQrSvg, aA as deriveStatus, aB as enterCheckoutResumePath, aJ as openWallet, aK as prepareCheckout, aL as requestCheckout } from './status-C-zvqBau.js';
3
3
  import '@openreceive/provider-data';
4
4
  import '@openreceive/core';
5
5
 
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  openWallet,
14
14
  prepareCheckout,
15
15
  requestCheckout
16
- } from "./chunk-GA4FMG7L.js";
16
+ } from "./chunk-NVEGYGZ5.js";
17
17
  export {
18
18
  BrowserRequestError,
19
19
  copyInvoice,
@@ -174,6 +174,8 @@ declare const OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES: {
174
174
  readonly meta: "data-openreceive-meta";
175
175
  readonly state: "data-openreceive-state";
176
176
  readonly actions: "data-openreceive-actions";
177
+ /** What the payer is buying, when the host's amount hook named it. */
178
+ readonly orderDescription: "data-openreceive-order-description";
177
179
  readonly theme: "data-openreceive-theme";
178
180
  readonly themeToggle: "data-openreceive-theme-toggle";
179
181
  };
@@ -183,6 +185,7 @@ declare const OPENRECEIVE_CHECKOUT_DATA_SELECTORS: {
183
185
  readonly meta: "[data-openreceive-meta]";
184
186
  readonly state: "[data-openreceive-state]";
185
187
  readonly actions: "[data-openreceive-actions]";
188
+ readonly orderDescription: "[data-openreceive-order-description]";
186
189
  readonly theme: "[data-openreceive-theme]";
187
190
  readonly themeToggle: "[data-openreceive-theme-toggle]";
188
191
  };
@@ -190,6 +193,17 @@ declare const OPENRECEIVE_CHECKOUT_ELEMENT_PARTS: {
190
193
  readonly copy: "copy";
191
194
  readonly startOver: "start-over";
192
195
  };
196
+ /**
197
+ * Named slots the checkout element projects host light-DOM children into.
198
+ *
199
+ * `order` is the element's answer to React's render-prop `children`: a line-item
200
+ * strip, a thumbnail, a "you are buying" summary, drawn from the order
201
+ * OpenReceive does not own. It is projected through a `<slot>` in the shadow
202
+ * root, so it survives every re-render of the shell's `innerHTML` untouched.
203
+ */
204
+ declare const OPENRECEIVE_CHECKOUT_ELEMENT_SLOTS: {
205
+ readonly order: "order";
206
+ };
193
207
  declare const OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS: {
194
208
  readonly copy: "[part=\"copy\"]";
195
209
  readonly startOver: "[part=\"start-over\"]";
@@ -259,6 +273,17 @@ declare const OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES: {
259
273
  * default), no decode link is rendered and the invoice never leaves the page.
260
274
  */
261
275
  readonly decodeLinkUrl: "decode-link-url";
276
+ /**
277
+ * Where this app serves the packages' `dist/assets` trees, as one base URL —
278
+ * the string form of the `resolveAssetUrl` seam, so plain markup and the
279
+ * Vue/Svelte/Angular wrappers can reach it (a function cannot cross an HTML
280
+ * attribute). Every packaged key is a relative path under one `assets/` root,
281
+ * so the value is joined to it directly: `asset-base-url="/openreceive-assets"`
282
+ * makes `assets/icons/btc.svg` load from
283
+ * `/openreceive-assets/assets/icons/btc.svg`. A `resolveAssetUrl` passed to
284
+ * `defineElements` wins over it.
285
+ */
286
+ readonly assetBaseUrl: "asset-base-url";
262
287
  /** `polling="false"` renders the snapshot without status polling (no POST /payments/check). */
263
288
  readonly polling: "polling";
264
289
  /** Status poll cadence in milliseconds; defaults to OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS. */
@@ -390,6 +415,15 @@ interface SwapFeeBreakdown {
390
415
  /** The fee as a percentage of the cart total, e.g. "5.9%", when computable. */
391
416
  readonly feePercent?: string;
392
417
  }
418
+ /** One value the payer has to reproduce, with the affordance that lets them. */
419
+ interface SwapCopyRow {
420
+ readonly label: string;
421
+ readonly value: string;
422
+ /** The untruncated string a copy button writes, when it differs from `value`. */
423
+ readonly copyValue?: string;
424
+ /** Render the value in a selectable field rather than a code block. */
425
+ readonly selectable: boolean;
426
+ }
393
427
  /**
394
428
  * How a deposit on this rail can actually go missing, which is what decides how
395
429
  * loud the deposit panel should be.
@@ -448,7 +482,22 @@ interface SwapDisplayModel {
448
482
  readonly networkWarning: string;
449
483
  readonly depositAddress: string;
450
484
  readonly depositMemo?: string;
485
+ /**
486
+ * BARE, with no asset symbol appended: it pastes into a wallet's amount field,
487
+ * where "0.032664 SOL" is not a number. Join the symbol at the point of
488
+ * display if a sentence needs it.
489
+ */
451
490
  readonly depositAmount: string;
491
+ /**
492
+ * Every value the payer must reproduce, as labelled rows: the deposit address,
493
+ * the memo where the rail has one, and the amount. The amount is the one that
494
+ * gets left out and the one that costs money — on token rails (USDT_TRON,
495
+ * USDT_ETH, USDC_ETH) the QR encodes the bare address and carries NO amount,
496
+ * so the payer types it off the screen, and a short send against a fixed-rate
497
+ * swap order is an underpayment: `refund_required`, a refund form, and a payer
498
+ * who has to come back.
499
+ */
500
+ readonly copyRows: readonly SwapCopyRow[];
452
501
  readonly providerStateLabel: string;
453
502
  readonly providerStateDetail: string;
454
503
  readonly state: "creating" | "deposit" | "progress" | "settled" | "expired" | "refund_required" | "refund_pending" | "refunded" | "attention" | "failed";
@@ -490,6 +539,11 @@ interface CheckoutInvoiceSnapshot {
490
539
  readonly expires_at?: number;
491
540
  readonly settled_at?: number;
492
541
  readonly swap?: CheckoutInvoiceSwapSnapshot;
542
+ /**
543
+ * What the payer is buying, carried through from the snapshot. Data, not a
544
+ * derived label, so it survives `normalizeCheckoutState`.
545
+ */
546
+ readonly description?: string;
493
547
  }
494
548
  interface CheckoutPaymentMethod {
495
549
  readonly pay_in_asset: string;
@@ -524,6 +578,13 @@ interface CheckoutSnapshot {
524
578
  readonly active?: CheckoutInvoiceSnapshot;
525
579
  readonly invoices: readonly CheckoutInvoiceSnapshot[];
526
580
  readonly payment_methods?: readonly CheckoutPaymentMethod[];
581
+ /**
582
+ * What the payer is buying, in the host's own words — one display string the
583
+ * host returned from `amountFor` / `amount_for`. OpenReceive owns no line
584
+ * items, so this is the whole of what it carries; a richer summary is the
585
+ * host's own markup (React `children`, the element's `order` slot).
586
+ */
587
+ readonly description?: string;
527
588
  }
528
589
  interface CheckoutElementAttributeOptions {
529
590
  /**
@@ -563,6 +624,14 @@ interface CheckoutElementAttributeOptions {
563
624
  * renders no "Decode" link and the invoice is never sent to a third party.
564
625
  */
565
626
  readonly decodeLinkUrl?: string;
627
+ /**
628
+ * Where this app serves the packages' `dist/assets` trees, as one base URL.
629
+ * The string form of the `resolveAssetUrl` seam: every packaged asset key is a
630
+ * relative path under one `assets/` root, so the value is joined to it
631
+ * directly. Emitted as the element's `asset-base-url` attribute, which is how
632
+ * the Vue/Svelte/Angular wrappers reach a seam a function cannot cross.
633
+ */
634
+ readonly assetBaseUrl?: string;
566
635
  /** False renders the snapshot without status polling (no POST /payments/check). */
567
636
  readonly polling?: boolean;
568
637
  /** Status poll cadence in milliseconds; defaults to OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS. */
@@ -737,12 +806,49 @@ interface CheckoutControllerOptions extends Omit<CheckoutWatcherOptions, "onStat
737
806
  * to render a snapshot without polling.
738
807
  */
739
808
  readonly prefix?: string;
809
+ /**
810
+ * False renders the snapshot without a status fetcher of its own. `prefix`
811
+ * still names the mount, so the swap-refund calls keep working — polling and
812
+ * "where the routes live" are two questions.
813
+ */
814
+ readonly polling?: boolean;
740
815
  readonly fetch?: typeof globalThis.fetch;
741
816
  readonly statusHeaders?: Readonly<Record<string, string>>;
742
817
  readonly clipboard?: Pick<Clipboard, "writeText">;
743
818
  readonly open?: (uri: string) => void;
744
819
  }
745
- interface CheckoutController {
820
+ /**
821
+ * The two-step swap refund, and the staging that makes it survive polling. The
822
+ * controller implements it; a renderer that is handed one (React's
823
+ * `PaymentWizard`) takes exactly this much of it.
824
+ */
825
+ interface SwapRefundStaging {
826
+ /**
827
+ * Step one: post `/swaps/status` and hold the address the payer typed so the
828
+ * panel can show it back for confirmation. It touches no refund route —
829
+ * nothing is submitted until {@link confirmSwapRefund}.
830
+ *
831
+ * The staged address is folded into every later snapshot, so polling cannot
832
+ * wipe what the payer is reviewing. `attemptId` is
833
+ * `SwapDisplayModel.attemptId`; the payment hash is resolved from the
834
+ * snapshot already in hand.
835
+ */
836
+ stageSwapRefund(options: {
837
+ readonly attemptId: string;
838
+ readonly refundAddress: string;
839
+ }): Promise<CheckoutInvoiceSnapshot>;
840
+ /** Step two: the only call that posts `/swaps/refunds`. */
841
+ confirmSwapRefund(options: {
842
+ readonly attemptId: string;
843
+ readonly refundAddress: string;
844
+ }): Promise<CheckoutInvoiceSnapshot>;
845
+ /**
846
+ * Drop the staged address. The payer leaving the swap for Lightning is the one
847
+ * exit that is not a submitted refund.
848
+ */
849
+ clearSwapRefundStaging(): void;
850
+ }
851
+ interface CheckoutController extends SwapRefundStaging {
746
852
  start(): CheckoutState;
747
853
  stop(): void;
748
854
  getState(): CheckoutState | undefined;
@@ -863,6 +969,8 @@ interface WizardRouteAssetDisplay {
863
969
  readonly label: string;
864
970
  readonly subtitle: string;
865
971
  readonly icon: string;
972
+ /** The packaged key behind `icon`, for a host serving the files itself. */
973
+ readonly iconPath: string;
866
974
  readonly selected: boolean;
867
975
  }
868
976
  interface WizardProviderTutorialDisplay {
@@ -1071,4 +1179,4 @@ declare function deriveStatus(invoice: StatusInvoiceLike, options?: {
1071
1179
  readonly now?: UnixSeconds;
1072
1180
  }): Status;
1073
1181
 
1074
- export { type CheckoutPhase as $, type ThemeToggleElementAttributeOptions as A, type BrowserLoggerOption as B, type CheckoutInvoiceSnapshot as C, type ThemeToggleElementAttributes as D, type StoredThemeModelOptions as E, type ThemeModel as F, type ThemeModelOptions as G, type ReadThemePreferenceOptions as H, type ThemeControlTargets as I, type ThemeStorageOptions as J, type PaymentWizardControllerOptions as K, type PaymentWizardController as L, type PaymentWizardSelection as M, type PaymentWizardModel as N, type WizardRouteDisplay as O, type ParseOpenReceiveOptionalIntegerOptions as P, type PaymentWizardSelectionAction as Q, type ResolvedTheme as R, type SwapDisplayModel as S, type ThemePreference as T, type UnixSeconds as U, type BrowserLogContext as V, type WizardRouteAssetDisplay as W, type BrowserLogger as X, BrowserRequestError as Y, type CheckoutController as Z, type CheckoutControllerOptions as _, type PaymentMethod as a, type CheckoutStatusRefresh as a0, OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES as a1, OPENRECEIVE_CHECKOUT_DATA_SELECTORS as a2, OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES as a3, OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS as a4, OPENRECEIVE_CHECKOUT_ELEMENT_PARTS as a5, OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS as a6, OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME as a7, OPENRECEIVE_COPY_FEEDBACK_MS as a8, OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS as a9, escapeHtml as aA, formatAmountCaption as aB, formatDepositAmount as aC, formatFiatAmount as aD, formatMsats as aE, formatSwapLimit as aF, formatUnixTime as aG, openWallet as aH, prepareCheckout as aI, requestCheckout as aJ, type BrowserLogLevel as aK, type BrowserLogEntry as aL, type CopyInvoiceOptions as aM, type GuestCheckoutResumeController as aN, type GuestCheckoutResumeOptions as aO, type OpenWalletOptions as aP, type PrepareCheckoutOptions as aQ, type QrOptions as aR, type RequestCheckoutOptions as aS, type StatusInvoiceLike as aT, createGuestCheckoutResume as aU, createGuestOrderFetcher as aV, createLightningUri as aW, createQrPngDataUrl as aX, OPENRECEIVE_DEFAULT_PREFIX as aa, OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES as ab, OPENRECEIVE_PAYMENT_WIZARD_SELECTORS as ac, OPENRECEIVE_THEME_STORAGE_KEY as ad, OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES as ae, OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS as af, OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS as ag, OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS as ah, OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME as ai, type QrEncoder as aj, type Status as ak, type WizardProviderDisplay as al, assertDisplayInvoice as am, copyInvoice as an, createCheckoutActionEvent as ao, createCheckoutController as ap, createCheckoutErrorEvent as aq, createCheckoutProviderCopyEvent as ar, createCheckoutStateEvent as as, createQrPayloadSvg as at, createQrSvg as au, createStatusFetcher as av, createThemeChangeEvent as aw, deriveCheckoutStateLabels as ax, deriveStatus as ay, enterCheckoutResumePath as az, type PaymentMethodOption as b, type TickingValueOptions as c, type TickingValueController as d, type TransientFeedbackOptions as e, type TransientFeedbackController as f, type SwapDepositRisk as g, type CheckoutInvoiceSwapSnapshot as h, type CheckoutState as i, type TransactionDetailsInput as j, type TransactionDetailRow as k, type CheckoutSnapshot as l, type CreateCheckoutStateOptions as m, type CheckoutStatusModelInput as n, type CheckoutStatusModel as o, type CheckoutPaymentMethod as p, type ThemeAttributeTarget as q, type CheckoutElementAttributes as r, type CheckoutElementAttributeOptions as s, type CheckoutElementEventHandlers as t, type CheckoutElementListeners as u, type CreateCheckoutShellOptions as v, type CheckoutShellElements as w, type CheckoutShellOptions as x, type CheckoutShellModel as y, type CreateOpenReceiveThemeToggleElementOptions as z };
1182
+ export { type CheckoutStatusRefresh 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 UnixSeconds as U, type BrowserLogger as V, type WizardRouteAssetDisplay as W, BrowserRequestError as X, type CheckoutController as Y, type CheckoutControllerOptions as Z, type CheckoutPhase as _, type PaymentMethod as a, OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES as a0, OPENRECEIVE_CHECKOUT_DATA_SELECTORS as a1, OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES as a2, OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS as a3, OPENRECEIVE_CHECKOUT_ELEMENT_PARTS as a4, OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS as a5, OPENRECEIVE_CHECKOUT_ELEMENT_SLOTS as a6, OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME as a7, OPENRECEIVE_COPY_FEEDBACK_MS as a8, OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS as a9, deriveStatus as aA, enterCheckoutResumePath as aB, escapeHtml as aC, formatAmountCaption as aD, formatDepositAmount as aE, formatFiatAmount as aF, formatMsats as aG, formatSwapLimit as aH, formatUnixTime as aI, openWallet as aJ, prepareCheckout as aK, requestCheckout as aL, type BrowserLogLevel as aM, type BrowserLogEntry as aN, type CopyInvoiceOptions as aO, type GuestCheckoutResumeController as aP, type GuestCheckoutResumeOptions as aQ, type OpenWalletOptions as aR, type PrepareCheckoutOptions as aS, type QrOptions as aT, type RequestCheckoutOptions as aU, type StatusInvoiceLike as aV, createGuestCheckoutResume as aW, createGuestOrderFetcher as aX, createLightningUri as aY, createQrPngDataUrl as aZ, OPENRECEIVE_DEFAULT_PREFIX as aa, OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES as ab, OPENRECEIVE_PAYMENT_WIZARD_SELECTORS as ac, OPENRECEIVE_THEME_STORAGE_KEY as ad, OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES as ae, OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS as af, OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS as ag, OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS as ah, OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME as ai, type QrEncoder as aj, type Status as ak, type SwapCopyRow as al, type SwapRefundStaging as am, type WizardProviderDisplay as an, assertDisplayInvoice as ao, copyInvoice as ap, createCheckoutActionEvent as aq, createCheckoutController as ar, createCheckoutErrorEvent as as, createCheckoutProviderCopyEvent as at, createCheckoutStateEvent as au, createQrPayloadSvg as av, createQrSvg as aw, createStatusFetcher as ax, createThemeChangeEvent as ay, deriveCheckoutStateLabels as az, type PaymentMethodOption as b, type TickingValueOptions as c, type TickingValueController as d, type TransientFeedbackOptions as e, type TransientFeedbackController as f, type CheckoutSnapshot as g, type SwapDepositRisk as h, type CheckoutState as i, type TransactionDetailsInput as j, type TransactionDetailRow 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 };