@openreceive/elements 0.3.0 → 0.3.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.
@@ -119,18 +119,20 @@ function createElementCheckoutSession(host) {
119
119
  });
120
120
  },
121
121
  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();
122
+ swap: {
123
+ selection: host.swapSelection,
124
+ prefix: () => host.resolvePollPrefix(currentReference()),
125
+ fetch: () => globalThis.fetch,
126
+ // A swap attempt is NOT written back as attributes: a bolt11 attribute
127
+ // would take the element out of create mode. It re-keys the poll
128
+ // controller onto the merged snapshot and nothing else.
129
+ onStarted: (invoice) => {
130
+ const reference = currentReference();
131
+ if (reference === void 0) return;
132
+ const previous = host.latestCheckoutSnapshot() ?? host.currentCheckoutSnapshot();
133
+ host.handleControllerSnapshot(mergeAttemptIntoCheckout(invoice, previous, reference));
134
+ host.startCheckoutController();
135
+ }
134
136
  },
135
137
  logger: host.logger,
136
138
  onError: (error) => host.dispatchError(error),
@@ -626,7 +628,9 @@ function elementsSwapLimitMessage(option, view) {
626
628
  return swapOptionLimitMessage(option, elementsSwapLimitContext(view));
627
629
  }
628
630
  function renderElementSwapPanelHtml(invoice, view = {}) {
629
- const display = createSwapDisplayModel(invoice);
631
+ const display = createSwapDisplayModel(invoice, {
632
+ ...view.resumable === void 0 ? {} : { resumable: view.resumable }
633
+ });
630
634
  if (display === void 0) return "";
631
635
  const backButton = `
632
636
  <button part="swap-back" class="${orClasses4.swapBack}" ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapBack} type="button">${escapeHtml4(checkoutLabels4.payWithLightningInstead)}</button>
@@ -784,7 +788,7 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
784
788
  </form>
785
789
  `}
786
790
  ${supportDetails}
787
- ${renderElementSwapRefundReturnWarningHtml()}
791
+ ${renderElementSwapRefundReturnWarningHtml(display)}
788
792
  </section>
789
793
  `;
790
794
  }
@@ -799,7 +803,7 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
799
803
  ${display.refundTxId === void 0 ? "" : renderElementSwapCopyDetailHtml("Refund transaction", display.refundTxId, { kind: "tx", payInAsset: display.payInAsset })}
800
804
  </dl>
801
805
  ${supportDetails}
802
- ${renderElementSwapRefundReturnWarningHtml()}
806
+ ${renderElementSwapRefundReturnWarningHtml(display)}
803
807
  </section>
804
808
  `;
805
809
  }
@@ -812,9 +816,9 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
812
816
  </section>
813
817
  `;
814
818
  }
815
- function renderElementSwapRefundReturnWarningHtml() {
819
+ function renderElementSwapRefundReturnWarningHtml(display) {
816
820
  return `
817
- <p part="swap-refund-return" class="${orClasses4.swapWarning}">${escapeHtml4(checkoutLabels4.refundReturnWarning)}</p>
821
+ <p part="swap-refund-return" class="${orClasses4.swapWarning}">${escapeHtml4(display.refundReturnLabel)}</p>
818
822
  `;
819
823
  }
820
824
  function renderElementSwapRefundFactsHtml(display) {
@@ -1080,7 +1084,7 @@ function renderElementCompactPaymentSelectorHtml(swapAssetOptions, view) {
1080
1084
  const display = createMethodGridDisplay({
1081
1085
  entries: buildMethodGridEntries(paymentMethods, swapAssetOptions),
1082
1086
  selectedPickerKey: view.selectedPickerKey ?? null,
1083
- selectedNetworks: view.selectedSwapNetworks ?? {},
1087
+ selectedAssetByGroup: view.selectedSwapAssetByGroup ?? {},
1084
1088
  startingAsset: wizardStartingAsset(view) ?? null,
1085
1089
  ...limitContext === void 0 ? {} : { checkout: limitContext }
1086
1090
  });
@@ -1492,7 +1496,7 @@ function defineElements(options = {}) {
1492
1496
  activeTutorialCopied = false;
1493
1497
  swapOptions = [];
1494
1498
  swapOptionsLoaded = false;
1495
- selectedSwapNetworks = {};
1499
+ selectedSwapAssetByGroup = {};
1496
1500
  selectedPickerKey = null;
1497
1501
  selectedSwapAsset = null;
1498
1502
  startedSwapInvoice;
@@ -1576,6 +1580,7 @@ function defineElements(options = {}) {
1576
1580
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.syncUrl,
1577
1581
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumePathPrefix,
1578
1582
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.routeReference,
1583
+ OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumable,
1579
1584
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.polling,
1580
1585
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.pollIntervalMs,
1581
1586
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.decodeLinkUrl,
@@ -1594,7 +1599,7 @@ function defineElements(options = {}) {
1594
1599
  attributeChangedCallback(name, oldValue, newValue) {
1595
1600
  if (!this.isConnected || this.session.applyingOwnAttributes) return;
1596
1601
  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;
1602
+ 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
1603
  if (displayOnly) {
1599
1604
  this.render();
1600
1605
  this.syncThemeAncestorObserver();
@@ -1686,11 +1691,29 @@ function defineElements(options = {}) {
1686
1691
  }
1687
1692
  return parsed;
1688
1693
  }
1694
+ /**
1695
+ * Whether a payer who closes this tab has a URL to come back to. Only
1696
+ * `sync-url` puts one there — the refund screen's copy has to say the true
1697
+ * thing either way, so this is read rather than assumed.
1698
+ */
1699
+ isResumable() {
1700
+ const declared = parseBooleanAttribute(
1701
+ this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumable)
1702
+ );
1703
+ if (declared !== void 0) return declared;
1704
+ const routeReference = this.getAttribute(
1705
+ OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.routeReference
1706
+ );
1707
+ if (routeReference !== null && routeReference.length > 0) return true;
1708
+ return parseBooleanAttribute(
1709
+ this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.syncUrl)
1710
+ ) === true;
1711
+ }
1689
1712
  /** Order data belongs to the host; this only performs optional History API sync. */
1690
1713
  syncResumePath(reference) {
1691
1714
  const syncUrl = parseBooleanAttribute(
1692
1715
  this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.syncUrl)
1693
- );
1716
+ ) === true;
1694
1717
  if (syncUrl) {
1695
1718
  const resumePathPrefix = this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumePathPrefix) ?? "/checkout";
1696
1719
  const routeReference = this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.routeReference) ?? void 0;
@@ -1778,10 +1801,11 @@ function defineElements(options = {}) {
1778
1801
  selectedBitcoinRoute: this.selection.selectedBitcoinRoute,
1779
1802
  swapOptions: this.swapOptions,
1780
1803
  currenciesLoading: !this.swapOptionsLoaded,
1781
- selectedSwapNetworks: this.selectedSwapNetworks,
1804
+ selectedSwapAssetByGroup: this.selectedSwapAssetByGroup,
1782
1805
  selectedPickerKey: this.selectedPickerKey,
1783
1806
  startingSwapAsset: this.session.startingSwapAsset,
1784
1807
  selectedSwapAsset: this.selectedSwapAsset,
1808
+ resumable: this.isResumable(),
1785
1809
  ...this.latestCheckoutSnapshot?.amount_msats === void 0 ? {} : { amountMsats: this.latestCheckoutSnapshot.amount_msats },
1786
1810
  ...this.latestCheckoutSnapshot?.fiat === void 0 ? {} : { fiat: this.latestCheckoutSnapshot.fiat },
1787
1811
  ...this.latestCheckoutSnapshot?.reference === void 0 ? {} : { reference: this.latestCheckoutSnapshot.reference },
@@ -1975,7 +1999,7 @@ function defineElements(options = {}) {
1975
1999
  }
1976
2000
  const swapInvoice = this.currentSwapInvoice();
1977
2001
  if (swapInvoice !== void 0) {
1978
- const display = createSwapDisplayModel2(swapInvoice, {});
2002
+ const display = createSwapDisplayModel2(swapInvoice, { resumable: this.isResumable() });
1979
2003
  const swapCountdown = root.querySelector('[part="swap-countdown"]');
1980
2004
  if (swapCountdown !== null && display !== void 0) {
1981
2005
  swapCountdown.textContent = display.countdownLabel;
@@ -2014,7 +2038,7 @@ function defineElements(options = {}) {
2014
2038
  pickerKey: key,
2015
2039
  previousKey: this.selectedPickerKey,
2016
2040
  entries: buildMethodGridEntries2(paymentMethods2, this.swapOptions),
2017
- selectedNetworks: this.selectedSwapNetworks
2041
+ selectedAssetByGroup: this.selectedSwapAssetByGroup
2018
2042
  });
2019
2043
  if (selection.kind === "none") return;
2020
2044
  if (selection.kind === "select_method") {
@@ -2037,7 +2061,7 @@ function defineElements(options = {}) {
2037
2061
  return;
2038
2062
  }
2039
2063
  this.selectedPickerKey = key;
2040
- this.selectedSwapNetworks = selection.selectedNetworks;
2064
+ this.selectedSwapAssetByGroup = selection.selectedAssetByGroup;
2041
2065
  this.render();
2042
2066
  });
2043
2067
  });
@@ -2067,7 +2091,7 @@ function defineElements(options = {}) {
2067
2091
  if (target === "swap-asset") {
2068
2092
  this.selectedSwapAsset = null;
2069
2093
  this.selectedPickerKey = null;
2070
- this.selectedSwapNetworks = {};
2094
+ this.selectedSwapAssetByGroup = {};
2071
2095
  this.render();
2072
2096
  return;
2073
2097
  }
@@ -2116,8 +2140,8 @@ function defineElements(options = {}) {
2116
2140
  if (groupKey === null || groupKey.length === 0 || payInAsset === null) return;
2117
2141
  const details = button.closest("details");
2118
2142
  if (details instanceof HTMLDetailsElement) details.open = false;
2119
- this.selectedSwapNetworks = {
2120
- ...this.selectedSwapNetworks,
2143
+ this.selectedSwapAssetByGroup = {
2144
+ ...this.selectedSwapAssetByGroup,
2121
2145
  [groupKey]: payInAsset
2122
2146
  };
2123
2147
  this.render();
@@ -2128,7 +2152,7 @@ function defineElements(options = {}) {
2128
2152
  this.dismissedSwapInvoiceId = current?.invoice_id ?? null;
2129
2153
  this.selectedSwapAsset = null;
2130
2154
  this.selectedPickerKey = null;
2131
- this.selectedSwapNetworks = {};
2155
+ this.selectedSwapAssetByGroup = {};
2132
2156
  this.clearRefundAddressDraft();
2133
2157
  this.controller?.clearSwapRefundStaging();
2134
2158
  void this.session.ensureLightning();
@@ -55,13 +55,20 @@ interface ElementsWizardView {
55
55
  */
56
56
  readonly currenciesLoading?: boolean;
57
57
  /** Selected pay-in asset per multi-network coin label (e.g. USDT → USDT_TRON). */
58
- readonly selectedSwapNetworks?: Readonly<Record<string, string>>;
58
+ readonly selectedSwapAssetByGroup?: Readonly<Record<string, string>>;
59
59
  /** Compact selector highlight: `method:bitcoin` or `swap:USDT`. */
60
60
  readonly selectedPickerKey?: string | null;
61
61
  /** Pay-in asset whose swap create is in flight — method tiles spin and disable. */
62
62
  readonly startingSwapAsset?: string | null;
63
63
  /** When set, the wizard shows the focused swap deposit flow for this pay-in asset. */
64
64
  readonly selectedSwapAsset?: string | null;
65
+ /**
66
+ * Whether this checkout has a URL the payer can return to — `sync-url` is
67
+ * set, or the host mounted the element on its own per-order route. Decides
68
+ * which of the two refund-return warnings the deposit panel shows; see
69
+ * {@link SwapDisplayModel.refundReturnLabel}.
70
+ */
71
+ readonly resumable?: boolean;
65
72
  /** Invoice amount + fiat, used to render fiat limit messages for out-of-range assets. */
66
73
  readonly amountMsats?: number;
67
74
  readonly fiat?: {
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { TransactionDetailsSource } from '@openreceive/browser/headless';
2
2
  export { OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES, OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS, OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME, OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES, OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS, OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME, TransactionDetailsSource, createThemeToggleElement } from '@openreceive/browser/headless';
3
- import { C as CheckoutView } from './define-elements-LL8dK1E-.js';
4
- export { D as DefineElementsOptions, E as ElementsWizardView, d as defineElements } from './define-elements-LL8dK1E-.js';
3
+ import { C as CheckoutView } from './define-elements-CV0JlfbJ.js';
4
+ export { D as DefineElementsOptions, E as ElementsWizardView, d as defineElements } from './define-elements-CV0JlfbJ.js';
5
5
 
6
6
  declare function renderCheckoutHtml(view: CheckoutView): string;
7
7
  /**
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  renderCheckoutHtml,
13
13
  renderThemeToggleHtml,
14
14
  renderTransactionDetailsHtml
15
- } from "./chunk-SJEIQZYE.js";
15
+ } from "./chunk-MKA6MJU5.js";
16
16
  export {
17
17
  OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES,
18
18
  OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS,
@@ -1,6 +1,6 @@
1
1
  import { OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME, CheckoutElementAttributes, CheckoutElementListeners, CheckoutElementAttributeOptions, CheckoutElementEventHandlers, CheckoutComponentProps, CheckoutShellOptions, ThemeModel, OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME, ThemeToggleElementAttributes, CheckoutSnapshot, ThemeToggleElementAttributeOptions } from '@openreceive/browser/headless';
2
2
  export { CheckoutComponentProps, CheckoutController, CheckoutControllerOptions, CheckoutElementAttributeOptions, CheckoutElementAttributes, CheckoutElementEventHandlers, CheckoutElementListeners, CheckoutPropsValidation, CheckoutShellElements, CheckoutShellOptions, CheckoutSnapshot, CreateCheckoutShellOptions, OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME, OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME, StoredThemeModelOptions, ThemeModel, ThemeModelOptions, ThemePreference, ThemeToggleElementAttributeOptions, ThemeToggleElementAttributes, createCheckoutController, createCheckoutShell, createStoredThemeModel, createThemeModel, validateCheckoutProps } from '@openreceive/browser/headless';
3
- export { D as DefineElementsOptions, d as defineElements } from './define-elements-LL8dK1E-.js';
3
+ export { D as DefineElementsOptions, d as defineElements } from './define-elements-CV0JlfbJ.js';
4
4
 
5
5
  /**
6
6
  * Every event the checkout element dispatches, in one place. `docs/internal/wrapper-parity.md`
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineElements
3
- } from "./chunk-SJEIQZYE.js";
3
+ } from "./chunk-MKA6MJU5.js";
4
4
 
5
5
  // src/wrapper-shared.ts
6
6
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openreceive/elements",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "The OpenReceive checkout custom element (<openreceive-checkout>) and theme toggle.",
5
5
  "keywords": [
6
6
  "bitcoin",
@@ -20,7 +20,7 @@
20
20
  "main": "./dist/index.js",
21
21
  "types": "./dist/index.d.ts",
22
22
  "dependencies": {
23
- "@openreceive/browser": "0.3.0"
23
+ "@openreceive/browser": "0.3.1"
24
24
  },
25
25
  "exports": {
26
26
  ".": {