@openreceive/elements 0.3.0 → 0.3.2

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.
@@ -22,10 +22,10 @@ import {
22
22
  createCheckoutStateEvent,
23
23
  createCheckoutStatusModel as createCheckoutStatusModel2,
24
24
  createPaymentWizardSelection,
25
- createSwapDisplayModel as createSwapDisplayModel2,
26
- createThemeChangeEvent,
27
25
  createQrPayloadSvg,
28
26
  createQrSvg,
27
+ createSwapDisplayModel as createSwapDisplayModel3,
28
+ createThemeChangeEvent,
29
29
  deriveStatus as deriveStatus2,
30
30
  enterCheckoutResumePath,
31
31
  getSwapRefundFormError,
@@ -33,20 +33,20 @@ import {
33
33
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES as OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3,
34
34
  OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS,
35
35
  OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS,
36
+ OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME,
36
37
  OPENRECEIVE_DEFAULT_PREFIX as OPENRECEIVE_DEFAULT_PREFIX2,
37
38
  OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES as OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES7,
38
39
  OPENRECEIVE_PAYMENT_WIZARD_SELECTORS as OPENRECEIVE_PAYMENT_WIZARD_SELECTORS3,
39
40
  OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES,
40
41
  OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS,
41
- OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME,
42
42
  OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME,
43
- paymentMethods as paymentMethods2,
44
43
  orClasses as orClasses7,
45
44
  parseBooleanAttribute,
46
45
  parseOptionalInteger,
47
46
  parsePaymentMethod,
48
47
  parseResolvedTheme,
49
48
  parseThemePreference,
49
+ paymentMethods as paymentMethods2,
50
50
  resolveWizardSelection,
51
51
  selectCurrentSwapInvoice,
52
52
  syncStoredThemeControls,
@@ -54,16 +54,147 @@ import {
54
54
  updatePaymentWizardSelection
55
55
  } from "@openreceive/browser/headless";
56
56
 
57
+ // src/dom-helpers.ts
58
+ import {
59
+ createDetailExternalLink,
60
+ createTransientFeedbackController,
61
+ escapeHtml,
62
+ OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES,
63
+ OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES,
64
+ OPENRECEIVE_PAYMENT_WIZARD_SELECTORS,
65
+ checkoutLabels,
66
+ orClasses
67
+ } from "@openreceive/browser/headless";
68
+ var COPY_INVOICE_ICON = `<svg class="${orClasses.copyIcon}" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><rect x="5" y="5" width="8" height="9" rx="1.5" stroke="currentColor" stroke-width="1.5"/><path d="M3.5 11V3.5A1.5 1.5 0 0 1 5 2h5.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>`;
69
+ var elementCopyFeedbackControllers = /* @__PURE__ */ new WeakMap();
70
+ function readElementFiatQuote(element) {
71
+ const currency = element.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.fiatCurrency);
72
+ const value = element.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.fiatValue);
73
+ if (currency === null || value === null) return void 0;
74
+ return {
75
+ fiat: {
76
+ currency,
77
+ value
78
+ }
79
+ };
80
+ }
81
+ function readElementNumberAttribute(element, attribute) {
82
+ const raw = element.getAttribute(attribute);
83
+ if (raw === null || raw.trim() === "") return void 0;
84
+ const parsed = Number(raw);
85
+ return Number.isFinite(parsed) ? parsed : void 0;
86
+ }
87
+ function readElementAmountMsats(element) {
88
+ return readElementNumberAttribute(element, OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.amountMsats);
89
+ }
90
+ function readElementExpiresAt(element) {
91
+ return readElementNumberAttribute(element, OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.expiresAt);
92
+ }
93
+ function parseElementRail(value) {
94
+ if (value === "swap") return "swap";
95
+ if (value === "checkout_lock") return "checkout_lock";
96
+ return "lightning";
97
+ }
98
+ function showElementCopyFeedback(button) {
99
+ if (button === null) return;
100
+ let controller = elementCopyFeedbackControllers.get(button);
101
+ if (controller === void 0) {
102
+ const labelEl = button.querySelector(OPENRECEIVE_PAYMENT_WIZARD_SELECTORS.swapCopyLabel);
103
+ const resetValue = button.getAttribute("aria-label")?.trim() || labelEl?.textContent?.trim() || button.textContent?.trim() || checkoutLabels.copyInvoice;
104
+ controller = createTransientFeedbackController({
105
+ resetValue,
106
+ onValue: (label) => {
107
+ if (!button.isConnected) return;
108
+ if (button instanceof HTMLElement && button.hasAttribute("aria-label")) {
109
+ button.setAttribute("aria-label", label);
110
+ button.setAttribute("title", label);
111
+ }
112
+ if (labelEl instanceof HTMLElement) {
113
+ labelEl.textContent = label;
114
+ return;
115
+ }
116
+ if (!(button instanceof HTMLElement && button.querySelector("svg"))) {
117
+ button.textContent = label;
118
+ }
119
+ }
120
+ });
121
+ elementCopyFeedbackControllers.set(button, controller);
122
+ }
123
+ controller.show(checkoutLabels.copied);
124
+ }
125
+ function wireSwapSelectAllInputs(root) {
126
+ for (const input of root.querySelectorAll(OPENRECEIVE_PAYMENT_WIZARD_SELECTORS.swapSelectAll)) {
127
+ if (!(input instanceof HTMLInputElement)) continue;
128
+ const selectAll = () => {
129
+ input.select();
130
+ };
131
+ input.addEventListener("focus", selectAll);
132
+ input.addEventListener("click", selectAll);
133
+ input.addEventListener("mouseup", (event) => {
134
+ event.preventDefault();
135
+ });
136
+ input.addEventListener("select", () => {
137
+ if (input.selectionStart !== 0 || input.selectionEnd !== input.value.length) {
138
+ input.setSelectionRange(0, input.value.length);
139
+ }
140
+ });
141
+ }
142
+ }
143
+ function renderElementSwapCopyDetailHtml(label, value, options = {}) {
144
+ const displayValue = options.displayValue ?? value;
145
+ const link = options.href === void 0 ? options.kind === void 0 ? void 0 : createDetailExternalLink({
146
+ kind: options.kind,
147
+ value,
148
+ ...options.payInAsset === void 0 ? {} : { payInAsset: options.payInAsset }
149
+ }) : {
150
+ href: options.href,
151
+ hrefLabel: options.hrefLabel ?? checkoutLabels.viewOnExplorer
152
+ };
153
+ const external = link === void 0 ? "" : `<a
154
+ part="swap-external"
155
+ class="${orClasses.swapDetailsLink}"
156
+ href="${escapeHtml(link.href)}"
157
+ rel="noreferrer"
158
+ target="_blank"
159
+ >${escapeHtml(link.hrefLabel)}</a>`;
160
+ const valueField = options.selectable === true ? `<input
161
+ class="${orClasses.swapDetailsInput}"
162
+ type="text"
163
+ readonly
164
+ value="${escapeHtml(displayValue)}"
165
+ aria-label="${escapeHtml(label)}"
166
+ ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES.swapSelectAll}
167
+ />` : `<code class="${orClasses.swapDetailsCode}">${escapeHtml(displayValue)}</code>`;
168
+ return `
169
+ <dt class="${orClasses.swapDetailsDt}">${escapeHtml(label)}</dt>
170
+ <dd class="${orClasses.swapDetailsDd}">
171
+ ${valueField}
172
+ <div class="${orClasses.swapDetailsActions}">
173
+ <button
174
+ part="swap-copy"
175
+ class="${orClasses.detailCopy}"
176
+ aria-label="Copy"
177
+ title="Copy"
178
+ ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES.swapCopy}="${escapeHtml(value)}"
179
+ type="button"
180
+ >${COPY_INVOICE_ICON}</button>
181
+ ${external}
182
+ </div>
183
+ </dd>
184
+ `;
185
+ }
186
+
57
187
  // src/element-checkout-session.ts
58
188
  import {
59
189
  applyCheckoutElementAttributes,
60
190
  createCheckoutElementAttributes,
61
191
  createCheckoutSession,
62
192
  mergeAttemptIntoCheckout,
63
- OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES,
193
+ OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES as OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES2,
64
194
  OPENRECEIVE_DEFAULT_PREFIX,
65
195
  prepareCheckout,
66
- requestCheckout
196
+ requestCheckout,
197
+ resumeSwapAttempt
67
198
  } from "@openreceive/browser/headless";
68
199
  function createElementCheckoutSession(host) {
69
200
  let creating = false;
@@ -71,10 +202,10 @@ function createElementCheckoutSession(host) {
71
202
  let createError;
72
203
  let applyingOwnAttributes = 0;
73
204
  function currentPrefix() {
74
- return host.element.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.prefix) ?? OPENRECEIVE_DEFAULT_PREFIX;
205
+ return host.element.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES2.prefix) ?? OPENRECEIVE_DEFAULT_PREFIX;
75
206
  }
76
207
  function currentReference() {
77
- const reference = host.element.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES.reference);
208
+ const reference = host.element.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES2.reference);
78
209
  return reference === null || reference.length === 0 ? void 0 : reference;
79
210
  }
80
211
  function currentCreateKey() {
@@ -119,18 +250,20 @@ function createElementCheckoutSession(host) {
119
250
  });
120
251
  },
121
252
  onSnapshot: publishSnapshot,
122
- swapPrefix: () => host.resolvePollPrefix(currentReference()),
123
- fetch: () => globalThis.fetch,
124
- swapSelection: host.swapSelection,
125
- // A swap attempt is NOT written back as attributes: a bolt11 attribute
126
- // would take the element out of create mode. It re-keys the poll
127
- // controller onto the merged snapshot and nothing else.
128
- onSwapStarted: (invoice) => {
129
- const reference = currentReference();
130
- if (reference === void 0) return;
131
- const previous = host.latestCheckoutSnapshot() ?? host.currentCheckoutSnapshot();
132
- host.handleControllerSnapshot(mergeAttemptIntoCheckout(invoice, previous, reference));
133
- host.startCheckoutController();
253
+ swap: {
254
+ selection: host.swapSelection,
255
+ prefix: () => host.resolvePollPrefix(currentReference()),
256
+ fetch: () => globalThis.fetch,
257
+ // A swap attempt is NOT written back as attributes: a bolt11 attribute
258
+ // would take the element out of create mode. It re-keys the poll
259
+ // controller onto the merged snapshot and nothing else.
260
+ onStarted: (invoice) => {
261
+ const reference = currentReference();
262
+ if (reference === void 0) return;
263
+ const previous = host.latestCheckoutSnapshot() ?? host.currentCheckoutSnapshot();
264
+ host.handleControllerSnapshot(mergeAttemptIntoCheckout(invoice, previous, reference));
265
+ host.startCheckoutController();
266
+ }
134
267
  },
135
268
  logger: host.logger,
136
269
  onError: (error) => host.dispatchError(error),
@@ -152,11 +285,19 @@ function createElementCheckoutSession(host) {
152
285
  try {
153
286
  createError = void 0;
154
287
  host.syncResumePath(reference);
155
- const checkout = await prepareCheckout({
288
+ const prepared = await prepareCheckout({
156
289
  prefix,
157
290
  reference,
158
291
  fetch: globalThis.fetch
159
292
  });
293
+ const resumeHash = host.resumePaymentHash();
294
+ const checkout = resumeHash === void 0 ? prepared : await resumeSwapAttempt({
295
+ fetch: globalThis.fetch,
296
+ prefix,
297
+ reference,
298
+ paymentHash: resumeHash,
299
+ snapshot: prepared
300
+ });
160
301
  if (currentCreateKey() !== key) return;
161
302
  host.handleControllerSnapshot(checkout);
162
303
  applyOwnAttributes(
@@ -223,136 +364,6 @@ function createElementCheckoutSession(host) {
223
364
  };
224
365
  }
225
366
 
226
- // src/dom-helpers.ts
227
- import {
228
- createDetailExternalLink,
229
- createTransientFeedbackController,
230
- escapeHtml,
231
- OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES as OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES2,
232
- OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES,
233
- OPENRECEIVE_PAYMENT_WIZARD_SELECTORS,
234
- checkoutLabels,
235
- orClasses
236
- } from "@openreceive/browser/headless";
237
- var COPY_INVOICE_ICON = `<svg class="${orClasses.copyIcon}" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><rect x="5" y="5" width="8" height="9" rx="1.5" stroke="currentColor" stroke-width="1.5"/><path d="M3.5 11V3.5A1.5 1.5 0 0 1 5 2h5.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>`;
238
- var elementCopyFeedbackControllers = /* @__PURE__ */ new WeakMap();
239
- function readElementFiatQuote(element) {
240
- const currency = element.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES2.fiatCurrency);
241
- const value = element.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES2.fiatValue);
242
- if (currency === null || value === null) return void 0;
243
- return {
244
- fiat: {
245
- currency,
246
- value
247
- }
248
- };
249
- }
250
- function readElementNumberAttribute(element, attribute) {
251
- const raw = element.getAttribute(attribute);
252
- if (raw === null || raw.trim() === "") return void 0;
253
- const parsed = Number(raw);
254
- return Number.isFinite(parsed) ? parsed : void 0;
255
- }
256
- function readElementAmountMsats(element) {
257
- return readElementNumberAttribute(element, OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES2.amountMsats);
258
- }
259
- function readElementExpiresAt(element) {
260
- return readElementNumberAttribute(element, OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES2.expiresAt);
261
- }
262
- function parseElementRail(value) {
263
- if (value === "swap") return "swap";
264
- if (value === "checkout_lock") return "checkout_lock";
265
- return "lightning";
266
- }
267
- function showElementCopyFeedback(button) {
268
- if (button === null) return;
269
- let controller = elementCopyFeedbackControllers.get(button);
270
- if (controller === void 0) {
271
- const labelEl = button.querySelector(OPENRECEIVE_PAYMENT_WIZARD_SELECTORS.swapCopyLabel);
272
- const resetValue = button.getAttribute("aria-label")?.trim() || labelEl?.textContent?.trim() || button.textContent?.trim() || checkoutLabels.copyInvoice;
273
- controller = createTransientFeedbackController({
274
- resetValue,
275
- onValue: (label) => {
276
- if (!button.isConnected) return;
277
- if (button instanceof HTMLElement && button.hasAttribute("aria-label")) {
278
- button.setAttribute("aria-label", label);
279
- button.setAttribute("title", label);
280
- }
281
- if (labelEl instanceof HTMLElement) {
282
- labelEl.textContent = label;
283
- return;
284
- }
285
- if (!(button instanceof HTMLElement && button.querySelector("svg"))) {
286
- button.textContent = label;
287
- }
288
- }
289
- });
290
- elementCopyFeedbackControllers.set(button, controller);
291
- }
292
- controller.show(checkoutLabels.copied);
293
- }
294
- function wireSwapSelectAllInputs(root) {
295
- for (const input of root.querySelectorAll(OPENRECEIVE_PAYMENT_WIZARD_SELECTORS.swapSelectAll)) {
296
- if (!(input instanceof HTMLInputElement)) continue;
297
- const selectAll = () => {
298
- input.select();
299
- };
300
- input.addEventListener("focus", selectAll);
301
- input.addEventListener("click", selectAll);
302
- input.addEventListener("mouseup", (event) => {
303
- event.preventDefault();
304
- });
305
- input.addEventListener("select", () => {
306
- if (input.selectionStart !== 0 || input.selectionEnd !== input.value.length) {
307
- input.setSelectionRange(0, input.value.length);
308
- }
309
- });
310
- }
311
- }
312
- function renderElementSwapCopyDetailHtml(label, value, options = {}) {
313
- const displayValue = options.displayValue ?? value;
314
- const link = options.href === void 0 ? options.kind === void 0 ? void 0 : createDetailExternalLink({
315
- kind: options.kind,
316
- value,
317
- ...options.payInAsset === void 0 ? {} : { payInAsset: options.payInAsset }
318
- }) : {
319
- href: options.href,
320
- hrefLabel: options.hrefLabel ?? checkoutLabels.viewOnExplorer
321
- };
322
- const external = link === void 0 ? "" : `<a
323
- part="swap-external"
324
- class="${orClasses.swapDetailsLink}"
325
- href="${escapeHtml(link.href)}"
326
- rel="noreferrer"
327
- target="_blank"
328
- >${escapeHtml(link.hrefLabel)}</a>`;
329
- const valueField = options.selectable === true ? `<input
330
- class="${orClasses.swapDetailsInput}"
331
- type="text"
332
- readonly
333
- value="${escapeHtml(displayValue)}"
334
- aria-label="${escapeHtml(label)}"
335
- ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES.swapSelectAll}
336
- />` : `<code class="${orClasses.swapDetailsCode}">${escapeHtml(displayValue)}</code>`;
337
- return `
338
- <dt class="${orClasses.swapDetailsDt}">${escapeHtml(label)}</dt>
339
- <dd class="${orClasses.swapDetailsDd}">
340
- ${valueField}
341
- <div class="${orClasses.swapDetailsActions}">
342
- <button
343
- part="swap-copy"
344
- class="${orClasses.detailCopy}"
345
- aria-label="Copy"
346
- title="Copy"
347
- ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES.swapCopy}="${escapeHtml(value)}"
348
- type="button"
349
- >${COPY_INVOICE_ICON}</button>
350
- ${external}
351
- </div>
352
- </dd>
353
- `;
354
- }
355
-
356
367
  // src/element-styles.ts
357
368
  import { checkoutElementStyles } from "@openreceive/browser/headless";
358
369
  var checkoutStyleTag = `<style>${checkoutElementStyles}</style>`;
@@ -406,10 +417,13 @@ import {
406
417
  checkoutLabels as checkoutLabels5,
407
418
  createMethodGridDisplay,
408
419
  createPaymentWizardModel,
420
+ createSwapDisplayModel as createSwapDisplayModel2,
409
421
  createSwapUnavailableModel,
410
422
  createWizardRouteAssetDisplays,
411
423
  createWizardRouteDisplays,
424
+ currentCheckoutUrl as currentCheckoutUrl2,
412
425
  escapeHtml as escapeHtml5,
426
+ formatMethodNetworkDetail,
413
427
  formatNetworkSummary,
414
428
  getNetworkIcon,
415
429
  getPaymentMethodIcon,
@@ -524,13 +538,14 @@ function renderTutorialModalHtml(routes, activeProviderId, activeTutorialIndex,
524
538
 
525
539
  // src/render-swap-panel.ts
526
540
  import {
541
+ checkoutLabels as checkoutLabels4,
527
542
  createSwapDisplayModel,
543
+ currentCheckoutUrl,
528
544
  escapeHtml as escapeHtml4,
529
545
  OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES as OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4,
530
- checkoutLabels as checkoutLabels4,
546
+ orClasses as orClasses4,
531
547
  swapAssetMatchesRoute,
532
- swapOptionLimitMessage,
533
- orClasses as orClasses4
548
+ swapOptionLimitMessage
534
549
  } from "@openreceive/browser/headless";
535
550
 
536
551
  // src/transaction-details.ts
@@ -626,7 +641,9 @@ function elementsSwapLimitMessage(option, view) {
626
641
  return swapOptionLimitMessage(option, elementsSwapLimitContext(view));
627
642
  }
628
643
  function renderElementSwapPanelHtml(invoice, view = {}) {
629
- const display = createSwapDisplayModel(invoice);
644
+ const display = createSwapDisplayModel(invoice, {
645
+ ...view.resumable === void 0 ? {} : { resumable: view.resumable }
646
+ });
630
647
  if (display === void 0) return "";
631
648
  const backButton = `
632
649
  <button part="swap-back" class="${orClasses4.swapBack}" ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapBack} type="button">${escapeHtml4(checkoutLabels4.payWithLightningInstead)}</button>
@@ -638,6 +655,15 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
638
655
  <span class="${orClasses4.swapHeadingDetail}">${escapeHtml4(display.providerStateDetail)}</span>
639
656
  </div>
640
657
  `;
658
+ const refundHeading = `
659
+ <div part="swap-heading" class="${orClasses4.swapRefundHeading}" role="alert">
660
+ ${renderElementAlertIconHtml("warning")}
661
+ <div class="${orClasses4.swapNetworkWarningContent}">
662
+ <strong class="${orClasses4.swapHeadingTitle}">${escapeHtml4(display.providerStateLabel)}</strong>
663
+ <span class="${orClasses4.swapHeadingDetail}">${escapeHtml4(display.providerStateDetail)}</span>
664
+ </div>
665
+ </div>
666
+ `;
641
667
  if (display.state === "creating") {
642
668
  return `
643
669
  <section part="swap-panel" class="${orClasses4.swapPanel}">
@@ -671,7 +697,7 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
671
697
  <p part="swap-instruction" class="${orClasses4.swapInstruction}">Pay <strong>${escapeHtml4(display.depositAmount)} ${escapeHtml4(display.assetLabel)}</strong> to this address</p>
672
698
  ${renderElementSwapNetworkWarningHtml(display)}
673
699
  <div part="swap-deposit-layout" class="${orClasses4.swapDepositLayout}">
674
- <div part="swap-qr" class="${orClasses4.swapQr}" ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapQr}="${escapeHtml4(display.qrPayload)}"></div>
700
+ <div part="swap-qr" class="${orClasses4.swapQrFrame}" ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapQr}="${escapeHtml4(display.qrPayload)}"></div>
675
701
  <div part="swap-deposit-side" class="${orClasses4.swapDepositSide}">
676
702
  <dl part="swap-details" class="${orClasses4.swapDetails}">
677
703
  ${display.copyRows.map(
@@ -728,12 +754,24 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
728
754
  }
729
755
  if (display.state === "refund_required") {
730
756
  const stagedRefundAddress = display.refundAddress;
731
- const refundFacts = renderElementSwapRefundFactsHtml(display);
757
+ const refundFacts = renderElementSwapAmountFactsHtml(display);
758
+ const refundFormIntro = `
759
+ <p class="${orClasses4.swapSectionTitle}">${escapeHtml4(checkoutLabels4.refundSectionTitle)}</p>
760
+ ${display.refundReason === void 0 ? "" : `<p class="${orClasses4.swapRefundReason}">${escapeHtml4(
761
+ checkoutLabels4.refundReasonLabel.replace(
762
+ "{reason}",
763
+ display.refundReason.replace(/_/g, " ")
764
+ )
765
+ )}</p>`}
766
+ <p class="${orClasses4.swapRefundInstruction}">${escapeHtml4(
767
+ checkoutLabels4.refundAddressOwnership.replace("{network}", display.networkLabel)
768
+ )}</p>
769
+ `;
732
770
  return `
733
771
  <section part="swap-panel" class="${orClasses4.swapPanel}">
734
- ${heading}
772
+ ${refundHeading}
773
+ ${renderElementSwapRefundReturnWarningHtml(display)}
735
774
  ${refundFacts}
736
- <p part="swap-warning" class="${orClasses4.swapWarning}">Use a ${escapeHtml4(display.networkLabel)} address you control. Do not paste the deposit address.</p>
737
775
  ${stagedRefundAddress === void 0 ? `
738
776
  <form
739
777
  part="swap-refund"
@@ -744,6 +782,7 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
744
782
  ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapRefundNetworkLabel}="${escapeHtml4(display.networkLabel)}"
745
783
  ${display.refundAllowed ? `${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapRefundAllowed}="true"` : ""}
746
784
  >
785
+ ${refundFormIntro}
747
786
  <input
748
787
  class="${orClasses4.swapRefundInput}"
749
788
  ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapRefundAddress}
@@ -773,7 +812,8 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
773
812
  ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapRefundConfirm}="true"
774
813
  ${display.refundAllowed ? `${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapRefundAllowed}="true"` : ""}
775
814
  >
776
- <p part="swap-warning" class="${orClasses4.swapWarning}">${escapeHtml4(checkoutLabels4.confirmRefundTo.replace("{address}", stagedRefundAddress))}</p>
815
+ ${refundFormIntro}
816
+ <p class="${orClasses4.swapRefundInstruction}">${escapeHtml4(checkoutLabels4.confirmRefundTo.replace("{address}", stagedRefundAddress))}</p>
777
817
  <input
778
818
  ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapRefundAddress}
779
819
  name="refund_address"
@@ -784,56 +824,74 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
784
824
  </form>
785
825
  `}
786
826
  ${supportDetails}
787
- ${renderElementSwapRefundReturnWarningHtml()}
788
827
  </section>
789
828
  `;
790
829
  }
791
830
  if (display.state === "refund_pending" || display.state === "refunded") {
792
- const refundFacts = renderElementSwapRefundFactsHtml(display);
831
+ const refundFacts = renderElementSwapAmountFactsHtml(display);
793
832
  return `
794
833
  <section part="swap-panel" class="${orClasses4.swapPanel}">
795
- ${heading}
834
+ ${refundHeading}
835
+ ${renderElementSwapRefundReturnWarningHtml(display)}
796
836
  ${refundFacts}
797
837
  <dl part="swap-details" class="${orClasses4.swapDetails}">
798
838
  ${display.refundAddress === void 0 ? "" : renderElementSwapCopyDetailHtml("Refund address", display.refundAddress, { kind: "address", payInAsset: display.payInAsset })}
799
839
  ${display.refundTxId === void 0 ? "" : renderElementSwapCopyDetailHtml("Refund transaction", display.refundTxId, { kind: "tx", payInAsset: display.payInAsset })}
800
840
  </dl>
801
841
  ${supportDetails}
802
- ${renderElementSwapRefundReturnWarningHtml()}
803
842
  </section>
804
843
  `;
805
844
  }
806
845
  return `
807
846
  <section part="swap-panel" class="${orClasses4.swapPanel}">
808
847
  ${heading}
809
- <p part="swap-warning" class="${orClasses4.swapWarning}">${escapeHtml4(checkoutLabels4.supportReviewNeeded)}</p>
810
- ${supportDetails}
848
+ <p part="swap-warning" class="${orClasses4.swapWarning}">${escapeHtml4(checkoutLabels4.supportReviewFacts)}</p>
849
+ ${renderElementSwapAmountFactsHtml(display)}
850
+ ${renderElementSwapSupportDetailsHtml(display, { open: true })}
811
851
  ${backButton}
812
852
  </section>
813
853
  `;
814
854
  }
815
- function renderElementSwapRefundReturnWarningHtml() {
855
+ function renderElementSwapRefundReturnWarningHtml(display) {
856
+ const url = display.resumable ? currentCheckoutUrl() : void 0;
816
857
  return `
817
- <p part="swap-refund-return" class="${orClasses4.swapWarning}">${escapeHtml4(checkoutLabels4.refundReturnWarning)}</p>
858
+ <div part="swap-refund-return" class="${orClasses4.swapRefundReturn}">
859
+ ${renderElementAlertIconHtml("bookmark")}
860
+ <div class="${orClasses4.swapNetworkWarningContent}">
861
+ <p class="${orClasses4.swapRefundReturnTitle}">${escapeHtml4(checkoutLabels4.refundReturnTitle)}</p>
862
+ <p class="${orClasses4.swapRefundReturnBody}">${escapeHtml4(display.refundReturnLabel)}</p>
863
+ ${url === void 0 ? "" : `<dl part="swap-details" class="${orClasses4.swapDetails}">${renderElementSwapCopyDetailHtml(
864
+ checkoutLabels4.refundReturnUrlLabel,
865
+ url,
866
+ { selectable: true }
867
+ )}</dl>`}
868
+ </div>
869
+ </div>
818
870
  `;
819
871
  }
820
- function renderElementSwapRefundFactsHtml(display) {
821
- const rows = [
822
- display.depositReceivedAmount === void 0 ? "" : renderElementSwapCopyDetailHtml(
823
- "Amount received",
824
- `${display.depositReceivedAmount} ${display.assetLabel}`
825
- ),
826
- display.depositReceivedAmount === void 0 ? "" : renderElementSwapCopyDetailHtml(
827
- "Amount required",
828
- `${display.depositAmount} ${display.assetLabel}`
829
- ),
830
- display.refundAmount === void 0 ? "" : renderElementSwapCopyDetailHtml(
831
- "Estimated refund",
832
- `${display.refundAmount} ${display.assetLabel}`
833
- )
834
- ].join("");
835
- if (rows.length === 0) return "";
836
- return `<dl part="swap-details" class="${orClasses4.swapDetails}">${rows}</dl>`;
872
+ function renderElementSwapAmountFactsHtml(display) {
873
+ const facts = [
874
+ ...display.depositReceivedAmount === void 0 ? [] : [
875
+ ["Amount received", `${display.depositReceivedAmount} ${display.assetLabel}`],
876
+ ["Amount required", `${display.depositAmount} ${display.assetLabel}`]
877
+ ],
878
+ ...display.refundAmount === void 0 ? [] : [["Estimated refund", `${display.refundAmount} ${display.assetLabel}`]]
879
+ ];
880
+ if (facts.length === 0) return "";
881
+ const rows = facts.map(
882
+ ([label, value]) => `
883
+ <div class="${orClasses4.swapFactsRow}">
884
+ <dt class="${orClasses4.swapFactsLabel}">${escapeHtml4(label)}</dt>
885
+ <dd class="${orClasses4.swapFactsValue}">${escapeHtml4(value)}</dd>
886
+ </div>`
887
+ ).join("");
888
+ return `<dl part="swap-facts" class="${orClasses4.swapFacts}">${rows}</dl>`;
889
+ }
890
+ function renderElementAlertIconHtml(kind) {
891
+ const path = kind === "warning" ? "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" : "M17 3H7a2 2 0 00-2 2v16l7-3.5L19 21V5a2 2 0 00-2-2z";
892
+ return `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="${orClasses4.swapNetworkWarningIcon}" aria-hidden="true">
893
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="${path}" />
894
+ </svg>`;
837
895
  }
838
896
  function renderElementSwapNetworkWarningHtml(display) {
839
897
  const alarm = display.depositRisk !== "pinned";
@@ -891,12 +949,12 @@ function renderElementSwapFeeBreakdownHtml(breakdown) {
891
949
  </div>
892
950
  `;
893
951
  }
894
- function renderElementSwapSupportDetailsHtml(display) {
952
+ function renderElementSwapSupportDetailsHtml(display, options = {}) {
895
953
  if (display.depositTxId === void 0 && display.payoutTxId === void 0 && display.refundTxId === void 0 && display.providerOrderId === void 0) {
896
954
  return "";
897
955
  }
898
956
  return `
899
- <details part="swap-support" class="${orClasses4.swapSupport}">
957
+ <details part="swap-support" class="${orClasses4.swapSupport}"${options.open === true ? " open" : ""}>
900
958
  <summary class="${orClasses4.swapSupportTitle}">Payment details</summary>
901
959
  <div class="${orClasses4.swapSupportContent}">
902
960
  <dl part="swap-details" class="${orClasses4.swapDetails}">
@@ -927,6 +985,7 @@ function renderElementSwapUnavailableHtml(quote, checkout) {
927
985
  </section>`;
928
986
  }
929
987
  function renderPaymentWizardHtml(view = {}) {
988
+ const keepOrderNote = renderElementKeepOrderNoteHtml(view);
930
989
  const selection = {
931
990
  selectedMethod: view.selectedMethod ?? null,
932
991
  selectedBitcoinRoute: view.selectedBitcoinRoute ?? null
@@ -952,10 +1011,15 @@ function renderPaymentWizardHtml(view = {}) {
952
1011
  if (selectedSwapAsset !== null) {
953
1012
  const label = selectedSwapOption === void 0 ? "this coin" : `${selectedSwapOption.label} \xB7 ${selectedSwapOption.network_label}`;
954
1013
  const activeSwap = view.swapInvoice !== void 0 && view.swapInvoice.swap?.pay_in_asset === selectedSwapAsset ? view.swapInvoice : void 0;
1014
+ const activeSwapState = activeSwap === void 0 ? void 0 : createSwapDisplayModel2(activeSwap, {
1015
+ ...view.resumable === void 0 ? {} : { resumable: view.resumable }
1016
+ })?.state;
1017
+ const refundOwed = activeSwapState === "refund_required";
1018
+ const refundStage = activeSwapState?.startsWith("refund") ?? false;
955
1019
  return `
956
1020
  <section part="wizard" class="${orClasses5.wizard}" ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES5.root}>
957
1021
  <div class="${orClasses5.wizardBody}">
958
- <div part="wizard-breadcrumbs" class="${orClasses5.breadcrumbs}">
1022
+ ${refundOwed ? "" : `<div part="wizard-breadcrumbs" class="${orClasses5.breadcrumbs}">
959
1023
  <button
960
1024
  part="wizard-breadcrumb"
961
1025
  class="${orClasses5.btnGhost}"
@@ -964,7 +1028,7 @@ function renderPaymentWizardHtml(view = {}) {
964
1028
  >${escapeHtml5(checkoutLabels5.switchPaymentMethod)}</button>
965
1029
  <span aria-hidden="true">/</span>
966
1030
  <span part="wizard-breadcrumb-current" class="${orClasses5.breadcrumbCurrent}">${escapeHtml5(label)}</span>
967
- </div>
1031
+ </div>`}
968
1032
  <div part="wizard-results" class="${orClasses5.wizardResults}">
969
1033
  ${activeSwap !== void 0 ? renderElementSwapPanelHtml(activeSwap, view) : view.swapStartError !== void 0 ? `<section part="swap-panel" class="${orClasses5.swapPanel}">
970
1034
  <div part="swap-error" role="alert" class="${orClasses5.paymentStatus}">
@@ -997,6 +1061,7 @@ function renderPaymentWizardHtml(view = {}) {
997
1061
  </div>
998
1062
  </section>`}
999
1063
  </div>
1064
+ ${refundStage ? "" : keepOrderNote}
1000
1065
  </div>
1001
1066
  </section>
1002
1067
  `;
@@ -1006,6 +1071,7 @@ function renderPaymentWizardHtml(view = {}) {
1006
1071
  <section part="wizard" class="${orClasses5.wizard}" ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES5.root}>
1007
1072
  ${view.wizardError === void 0 ? "" : `<p part="wizard-error" role="alert" class="${orClasses5.paymentStatusDetail}">${escapeHtml5(view.wizardError)}</p>`}
1008
1073
  ${methodPicker}
1074
+ ${selection.selectedMethod === null && keepOrderNote.length > 0 ? `<div class="${orClasses5.wizardBody}">${keepOrderNote}</div>` : ""}
1009
1075
  ${selection.selectedMethod === null ? "" : `
1010
1076
  <div class="${orClasses5.wizardBody}">
1011
1077
  ${breadcrumbs}
@@ -1062,6 +1128,7 @@ function renderPaymentWizardHtml(view = {}) {
1062
1128
  }).join("")}
1063
1129
  </div>
1064
1130
  `}
1131
+ ${keepOrderNote}
1065
1132
  </div>
1066
1133
  `}
1067
1134
  ${renderTutorialModalHtml(
@@ -1075,12 +1142,32 @@ function renderPaymentWizardHtml(view = {}) {
1075
1142
  </section>
1076
1143
  `;
1077
1144
  }
1145
+ function renderElementKeepOrderNoteHtml(view) {
1146
+ if (view.resumable !== true) return "";
1147
+ const reference = view.reference ?? "";
1148
+ const url = currentCheckoutUrl2();
1149
+ if (reference.length === 0 && url === void 0) return "";
1150
+ return `
1151
+ <div part="keep-order" class="${orClasses5.keepOrder}">
1152
+ <p class="${orClasses5.swapSectionTitle}">${escapeHtml5(checkoutLabels5.keepOrderTitle)}</p>
1153
+ <p class="${orClasses5.keepOrderBody}">${escapeHtml5(checkoutLabels5.keepOrderBody)}</p>
1154
+ <dl part="swap-details" class="${orClasses5.swapDetails}">
1155
+ ${reference.length === 0 ? "" : renderElementSwapCopyDetailHtml(checkoutLabels5.keepOrderIdLabel, reference, {
1156
+ selectable: true
1157
+ })}
1158
+ ${url === void 0 ? "" : renderElementSwapCopyDetailHtml(checkoutLabels5.keepOrderUrlLabel, url, {
1159
+ selectable: true
1160
+ })}
1161
+ </dl>
1162
+ </div>
1163
+ `;
1164
+ }
1078
1165
  function renderElementCompactPaymentSelectorHtml(swapAssetOptions, view) {
1079
1166
  const limitContext = elementsSwapLimitContext(view);
1080
1167
  const display = createMethodGridDisplay({
1081
1168
  entries: buildMethodGridEntries(paymentMethods, swapAssetOptions),
1082
1169
  selectedPickerKey: view.selectedPickerKey ?? null,
1083
- selectedNetworks: view.selectedSwapNetworks ?? {},
1170
+ selectedAssetByGroup: view.selectedSwapAssetByGroup ?? {},
1084
1171
  startingAsset: wizardStartingAsset(view) ?? null,
1085
1172
  ...limitContext === void 0 ? {} : { checkout: limitContext }
1086
1173
  });
@@ -1109,6 +1196,7 @@ function renderElementCompactPaymentSelectorHtml(swapAssetOptions, view) {
1109
1196
  </span>
1110
1197
  <span class="${orClasses5.methodTitleWrap}">
1111
1198
  <span class="${orClasses5.methodTitle}">${escapeHtml5(method.title)}</span>
1199
+ <span class="${orClasses5.methodTileDetail}">${escapeHtml5(method.detail)}</span>
1112
1200
  </span>
1113
1201
  </button>`;
1114
1202
  }
@@ -1217,7 +1305,6 @@ function renderElementSwapMethodGroupHtml(group, view, gridBusy, continueButtonH
1217
1305
  pickerKey,
1218
1306
  selected,
1219
1307
  displayOption,
1220
- selectedOption,
1221
1308
  multiNetwork,
1222
1309
  starting,
1223
1310
  disabled,
@@ -1225,7 +1312,7 @@ function renderElementSwapMethodGroupHtml(group, view, gridBusy, continueButtonH
1225
1312
  limitMessage,
1226
1313
  panelId
1227
1314
  } = group;
1228
- const networkDetail = !disabled && multiNetwork ? selected && selectedOption !== void 0 ? `${escapeHtml5(selectedOption.network_label)} network` : escapeHtml5(checkoutLabels5.selectNetwork) : void 0;
1315
+ const networkDetail = formatMethodNetworkDetail(group.options);
1229
1316
  const mobileReveal = multiNetwork ? `
1230
1317
  <div class="${orClasses5.methodNetworkRevealAnim} ${selected ? orClasses5.methodNetworkRevealAnimOpen : orClasses5.methodNetworkRevealAnimClosed}">
1231
1318
  <div class="${orClasses5.methodNetworkRevealInner}">
@@ -1253,7 +1340,7 @@ function renderElementSwapMethodGroupHtml(group, view, gridBusy, continueButtonH
1253
1340
  </span>
1254
1341
  <span class="${orClasses5.methodTitleWrap}">
1255
1342
  <span class="${orClasses5.methodTitle}">${escapeHtml5(group.label)}</span>
1256
- ${networkDetail === void 0 ? "" : `<span class="${orClasses5.methodDetailMobile}">${networkDetail}</span>`}
1343
+ ${networkDetail.length === 0 ? "" : `<span class="${orClasses5.methodTileDetail}">${escapeHtml5(networkDetail)}</span>`}
1257
1344
  </span>
1258
1345
  </button>
1259
1346
  ${disabled && limitMessage !== void 0 ? `<span class="${orClasses5.methodLimitHint}">${escapeHtml5(limitMessage)}</span>` : ""}
@@ -1492,7 +1579,7 @@ function defineElements(options = {}) {
1492
1579
  activeTutorialCopied = false;
1493
1580
  swapOptions = [];
1494
1581
  swapOptionsLoaded = false;
1495
- selectedSwapNetworks = {};
1582
+ selectedSwapAssetByGroup = {};
1496
1583
  selectedPickerKey = null;
1497
1584
  selectedSwapAsset = null;
1498
1585
  startedSwapInvoice;
@@ -1550,6 +1637,7 @@ function defineElements(options = {}) {
1550
1637
  syncResumePath: (reference) => {
1551
1638
  this.syncResumePath(reference);
1552
1639
  },
1640
+ resumePaymentHash: () => this.resumePaymentHash(),
1553
1641
  resolvePollPrefix: (reference) => this.resolvePollPrefix(reference),
1554
1642
  dispatchError: (error) => {
1555
1643
  this.dispatchError(error);
@@ -1576,6 +1664,8 @@ function defineElements(options = {}) {
1576
1664
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.syncUrl,
1577
1665
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumePathPrefix,
1578
1666
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.routeReference,
1667
+ OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumePaymentHash,
1668
+ OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumable,
1579
1669
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.polling,
1580
1670
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.pollIntervalMs,
1581
1671
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.decodeLinkUrl,
@@ -1594,7 +1684,7 @@ function defineElements(options = {}) {
1594
1684
  attributeChangedCallback(name, oldValue, newValue) {
1595
1685
  if (!this.isConnected || this.session.applyingOwnAttributes) return;
1596
1686
  if (oldValue === newValue) return;
1597
- const displayOnly = name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.theme || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.syncUrl || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumePathPrefix || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.routeReference || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.decodeLinkUrl || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.assetBaseUrl;
1687
+ const displayOnly = name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.theme || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.syncUrl || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumePathPrefix || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.routeReference || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumable || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.decodeLinkUrl || name === OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.assetBaseUrl;
1598
1688
  if (displayOnly) {
1599
1689
  this.render();
1600
1690
  this.syncThemeAncestorObserver();
@@ -1686,11 +1776,40 @@ function defineElements(options = {}) {
1686
1776
  }
1687
1777
  return parsed;
1688
1778
  }
1779
+ /**
1780
+ * Whether a payer who closes this tab has a URL to come back to. Only
1781
+ * `sync-url` puts one there — the refund screen's copy has to say the true
1782
+ * thing either way, so this is read rather than assumed.
1783
+ */
1784
+ isResumable() {
1785
+ const declared = parseBooleanAttribute(
1786
+ this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumable)
1787
+ );
1788
+ if (declared !== void 0) return declared;
1789
+ const routeReference = this.getAttribute(
1790
+ OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.routeReference
1791
+ );
1792
+ if (routeReference !== null && routeReference.length > 0) return true;
1793
+ return parseBooleanAttribute(
1794
+ this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.syncUrl)
1795
+ ) === true;
1796
+ }
1797
+ /**
1798
+ * The swap attempt this order already has in flight, if the host named one.
1799
+ *
1800
+ * Read from the attribute at prepare time rather than captured at
1801
+ * construction: a host that learns the hash asynchronously (its own order
1802
+ * fetch) sets the attribute late, and the create lifecycle re-runs.
1803
+ */
1804
+ resumePaymentHash() {
1805
+ const value = this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumePaymentHash);
1806
+ return value === null || value.length === 0 ? void 0 : value;
1807
+ }
1689
1808
  /** Order data belongs to the host; this only performs optional History API sync. */
1690
1809
  syncResumePath(reference) {
1691
1810
  const syncUrl = parseBooleanAttribute(
1692
1811
  this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.syncUrl)
1693
- );
1812
+ ) === true;
1694
1813
  if (syncUrl) {
1695
1814
  const resumePathPrefix = this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumePathPrefix) ?? "/checkout";
1696
1815
  const routeReference = this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.routeReference) ?? void 0;
@@ -1778,10 +1897,11 @@ function defineElements(options = {}) {
1778
1897
  selectedBitcoinRoute: this.selection.selectedBitcoinRoute,
1779
1898
  swapOptions: this.swapOptions,
1780
1899
  currenciesLoading: !this.swapOptionsLoaded,
1781
- selectedSwapNetworks: this.selectedSwapNetworks,
1900
+ selectedSwapAssetByGroup: this.selectedSwapAssetByGroup,
1782
1901
  selectedPickerKey: this.selectedPickerKey,
1783
1902
  startingSwapAsset: this.session.startingSwapAsset,
1784
1903
  selectedSwapAsset: this.selectedSwapAsset,
1904
+ resumable: this.isResumable(),
1785
1905
  ...this.latestCheckoutSnapshot?.amount_msats === void 0 ? {} : { amountMsats: this.latestCheckoutSnapshot.amount_msats },
1786
1906
  ...this.latestCheckoutSnapshot?.fiat === void 0 ? {} : { fiat: this.latestCheckoutSnapshot.fiat },
1787
1907
  ...this.latestCheckoutSnapshot?.reference === void 0 ? {} : { reference: this.latestCheckoutSnapshot.reference },
@@ -1975,7 +2095,7 @@ function defineElements(options = {}) {
1975
2095
  }
1976
2096
  const swapInvoice = this.currentSwapInvoice();
1977
2097
  if (swapInvoice !== void 0) {
1978
- const display = createSwapDisplayModel2(swapInvoice, {});
2098
+ const display = createSwapDisplayModel3(swapInvoice, { resumable: this.isResumable() });
1979
2099
  const swapCountdown = root.querySelector('[part="swap-countdown"]');
1980
2100
  if (swapCountdown !== null && display !== void 0) {
1981
2101
  swapCountdown.textContent = display.countdownLabel;
@@ -2014,7 +2134,7 @@ function defineElements(options = {}) {
2014
2134
  pickerKey: key,
2015
2135
  previousKey: this.selectedPickerKey,
2016
2136
  entries: buildMethodGridEntries2(paymentMethods2, this.swapOptions),
2017
- selectedNetworks: this.selectedSwapNetworks
2137
+ selectedAssetByGroup: this.selectedSwapAssetByGroup
2018
2138
  });
2019
2139
  if (selection.kind === "none") return;
2020
2140
  if (selection.kind === "select_method") {
@@ -2037,7 +2157,7 @@ function defineElements(options = {}) {
2037
2157
  return;
2038
2158
  }
2039
2159
  this.selectedPickerKey = key;
2040
- this.selectedSwapNetworks = selection.selectedNetworks;
2160
+ this.selectedSwapAssetByGroup = selection.selectedAssetByGroup;
2041
2161
  this.render();
2042
2162
  });
2043
2163
  });
@@ -2067,7 +2187,7 @@ function defineElements(options = {}) {
2067
2187
  if (target === "swap-asset") {
2068
2188
  this.selectedSwapAsset = null;
2069
2189
  this.selectedPickerKey = null;
2070
- this.selectedSwapNetworks = {};
2190
+ this.selectedSwapAssetByGroup = {};
2071
2191
  this.render();
2072
2192
  return;
2073
2193
  }
@@ -2116,8 +2236,8 @@ function defineElements(options = {}) {
2116
2236
  if (groupKey === null || groupKey.length === 0 || payInAsset === null) return;
2117
2237
  const details = button.closest("details");
2118
2238
  if (details instanceof HTMLDetailsElement) details.open = false;
2119
- this.selectedSwapNetworks = {
2120
- ...this.selectedSwapNetworks,
2239
+ this.selectedSwapAssetByGroup = {
2240
+ ...this.selectedSwapAssetByGroup,
2121
2241
  [groupKey]: payInAsset
2122
2242
  };
2123
2243
  this.render();
@@ -2128,7 +2248,7 @@ function defineElements(options = {}) {
2128
2248
  this.dismissedSwapInvoiceId = current?.invoice_id ?? null;
2129
2249
  this.selectedSwapAsset = null;
2130
2250
  this.selectedPickerKey = null;
2131
- this.selectedSwapNetworks = {};
2251
+ this.selectedSwapAssetByGroup = {};
2132
2252
  this.clearRefundAddressDraft();
2133
2253
  this.controller?.clearSwapRefundStaging();
2134
2254
  void this.session.ensureLightning();