@openreceive/elements 0.2.4 → 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.
- package/dist/{chunk-P5HNOT3S.js → chunk-MKA6MJU5.js} +161 -155
- package/dist/{define-elements-BZVyBJjO.d.ts → define-elements-CV0JlfbJ.d.ts} +15 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/wrapper-shared.d.ts +1 -1
- package/dist/wrapper-shared.js +1 -1
- package/package.json +2 -2
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
buildMethodGridEntries as buildMethodGridEntries2,
|
|
15
15
|
copyInvoice,
|
|
16
|
+
createAssetBaseUrlResolver,
|
|
16
17
|
createCheckoutActionEvent,
|
|
17
18
|
createCheckoutController,
|
|
18
19
|
createCheckoutErrorEvent,
|
|
@@ -27,7 +28,6 @@ import {
|
|
|
27
28
|
createQrSvg,
|
|
28
29
|
deriveStatus as deriveStatus2,
|
|
29
30
|
enterCheckoutResumePath,
|
|
30
|
-
findSwapGridGroup as findSwapGridGroup2,
|
|
31
31
|
getSwapRefundFormError,
|
|
32
32
|
OPENRECEIVE_CHECKOUT_DATA_SELECTORS,
|
|
33
33
|
OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES as OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3,
|
|
@@ -42,18 +42,16 @@ import {
|
|
|
42
42
|
OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME,
|
|
43
43
|
paymentMethods as paymentMethods2,
|
|
44
44
|
orClasses as orClasses7,
|
|
45
|
-
overlaySwapRefundStaging,
|
|
46
45
|
parseBooleanAttribute,
|
|
47
|
-
parseMethodPickerKey,
|
|
48
46
|
parseOptionalInteger,
|
|
49
47
|
parsePaymentMethod,
|
|
50
48
|
parseResolvedTheme,
|
|
51
49
|
parseThemePreference,
|
|
52
|
-
|
|
50
|
+
resolveWizardSelection,
|
|
51
|
+
selectCurrentSwapInvoice,
|
|
53
52
|
syncStoredThemeControls,
|
|
54
53
|
toggleStoredThemeControls,
|
|
55
|
-
updatePaymentWizardSelection
|
|
56
|
-
updateSelectedSwapNetworks
|
|
54
|
+
updatePaymentWizardSelection
|
|
57
55
|
} from "@openreceive/browser/headless";
|
|
58
56
|
|
|
59
57
|
// src/element-checkout-session.ts
|
|
@@ -121,18 +119,20 @@ function createElementCheckoutSession(host) {
|
|
|
121
119
|
});
|
|
122
120
|
},
|
|
123
121
|
onSnapshot: publishSnapshot,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
+
}
|
|
136
136
|
},
|
|
137
137
|
logger: host.logger,
|
|
138
138
|
onError: (error) => host.dispatchError(error),
|
|
@@ -393,6 +393,7 @@ import {
|
|
|
393
393
|
escapeHtml as escapeHtml6,
|
|
394
394
|
formatAmountCaption,
|
|
395
395
|
OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES,
|
|
396
|
+
OPENRECEIVE_CHECKOUT_ELEMENT_SLOTS,
|
|
396
397
|
OPENRECEIVE_CHECKOUT_ELEMENT_PARTS,
|
|
397
398
|
OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES as OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES6,
|
|
398
399
|
OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS,
|
|
@@ -405,13 +406,12 @@ import {
|
|
|
405
406
|
assetButtonClasses,
|
|
406
407
|
buildMethodGridEntries,
|
|
407
408
|
checkoutLabels as checkoutLabels5,
|
|
409
|
+
createMethodGridDisplay,
|
|
408
410
|
createPaymentWizardModel,
|
|
409
411
|
createSwapUnavailableModel,
|
|
410
412
|
createWizardRouteAssetDisplays,
|
|
411
413
|
createWizardRouteDisplays,
|
|
412
414
|
escapeHtml as escapeHtml5,
|
|
413
|
-
findSwapGridGroup,
|
|
414
|
-
formatChooseNetworkHeading,
|
|
415
415
|
formatNetworkSummary,
|
|
416
416
|
getNetworkIcon,
|
|
417
417
|
getPaymentMethodIcon,
|
|
@@ -423,12 +423,8 @@ import {
|
|
|
423
423
|
networkSummaryIconClasses,
|
|
424
424
|
OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES as OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES5,
|
|
425
425
|
orClasses as orClasses5,
|
|
426
|
-
paymentAccentId,
|
|
427
426
|
paymentMethods,
|
|
428
|
-
swapAssetMatchesRoute as swapAssetMatchesRoute2
|
|
429
|
-
swapGroupLimitOption,
|
|
430
|
-
swapPickerKey,
|
|
431
|
-
wizardNetworkGroupIds
|
|
427
|
+
swapAssetMatchesRoute as swapAssetMatchesRoute2
|
|
432
428
|
} from "@openreceive/browser/headless";
|
|
433
429
|
|
|
434
430
|
// src/render-provider-tutorial.ts
|
|
@@ -621,15 +617,20 @@ function renderElementSwapActionsHtml(routeKey, options, view) {
|
|
|
621
617
|
</div>
|
|
622
618
|
`;
|
|
623
619
|
}
|
|
624
|
-
function
|
|
625
|
-
|
|
620
|
+
function elementsSwapLimitContext(view) {
|
|
621
|
+
if (view.amountMsats === void 0) return void 0;
|
|
622
|
+
return {
|
|
626
623
|
amount_msats: view.amountMsats,
|
|
627
624
|
...view.fiat?.currency === void 0 || view.fiat.value === void 0 ? {} : { fiat: { currency: view.fiat.currency, value: view.fiat.value } }
|
|
628
625
|
};
|
|
629
|
-
|
|
626
|
+
}
|
|
627
|
+
function elementsSwapLimitMessage(option, view) {
|
|
628
|
+
return swapOptionLimitMessage(option, elementsSwapLimitContext(view));
|
|
630
629
|
}
|
|
631
630
|
function renderElementSwapPanelHtml(invoice, view = {}) {
|
|
632
|
-
const display = createSwapDisplayModel(invoice
|
|
631
|
+
const display = createSwapDisplayModel(invoice, {
|
|
632
|
+
...view.resumable === void 0 ? {} : { resumable: view.resumable }
|
|
633
|
+
});
|
|
633
634
|
if (display === void 0) return "";
|
|
634
635
|
const backButton = `
|
|
635
636
|
<button part="swap-back" class="${orClasses4.swapBack}" ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapBack} type="button">${escapeHtml4(checkoutLabels4.payWithLightningInstead)}</button>
|
|
@@ -677,11 +678,12 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
|
|
|
677
678
|
<div part="swap-qr" class="${orClasses4.swapQr}" ${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES4.swapQr}="${escapeHtml4(display.qrPayload)}"></div>
|
|
678
679
|
<div part="swap-deposit-side" class="${orClasses4.swapDepositSide}">
|
|
679
680
|
<dl part="swap-details" class="${orClasses4.swapDetails}">
|
|
680
|
-
${
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
681
|
+
${display.copyRows.map(
|
|
682
|
+
(row) => renderElementSwapCopyDetailHtml(row.label, row.copyValue ?? row.value, {
|
|
683
|
+
selectable: row.selectable,
|
|
684
|
+
displayValue: row.value
|
|
685
|
+
})
|
|
686
|
+
).join("")}
|
|
685
687
|
</dl>
|
|
686
688
|
${waitingStatus}
|
|
687
689
|
${feeBreakdown}
|
|
@@ -786,7 +788,7 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
|
|
|
786
788
|
</form>
|
|
787
789
|
`}
|
|
788
790
|
${supportDetails}
|
|
789
|
-
${renderElementSwapRefundReturnWarningHtml()}
|
|
791
|
+
${renderElementSwapRefundReturnWarningHtml(display)}
|
|
790
792
|
</section>
|
|
791
793
|
`;
|
|
792
794
|
}
|
|
@@ -801,7 +803,7 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
|
|
|
801
803
|
${display.refundTxId === void 0 ? "" : renderElementSwapCopyDetailHtml("Refund transaction", display.refundTxId, { kind: "tx", payInAsset: display.payInAsset })}
|
|
802
804
|
</dl>
|
|
803
805
|
${supportDetails}
|
|
804
|
-
${renderElementSwapRefundReturnWarningHtml()}
|
|
806
|
+
${renderElementSwapRefundReturnWarningHtml(display)}
|
|
805
807
|
</section>
|
|
806
808
|
`;
|
|
807
809
|
}
|
|
@@ -814,9 +816,9 @@ function renderElementSwapPanelHtml(invoice, view = {}) {
|
|
|
814
816
|
</section>
|
|
815
817
|
`;
|
|
816
818
|
}
|
|
817
|
-
function renderElementSwapRefundReturnWarningHtml() {
|
|
819
|
+
function renderElementSwapRefundReturnWarningHtml(display) {
|
|
818
820
|
return `
|
|
819
|
-
<p part="swap-refund-return" class="${orClasses4.swapWarning}">${escapeHtml4(
|
|
821
|
+
<p part="swap-refund-return" class="${orClasses4.swapWarning}">${escapeHtml4(display.refundReturnLabel)}</p>
|
|
820
822
|
`;
|
|
821
823
|
}
|
|
822
824
|
function renderElementSwapRefundFactsHtml(display) {
|
|
@@ -917,9 +919,6 @@ function wizardStartingAsset(view) {
|
|
|
917
919
|
const asset = view.startingSwapAsset;
|
|
918
920
|
return asset !== void 0 && asset !== null && asset.length > 0 ? asset : void 0;
|
|
919
921
|
}
|
|
920
|
-
function swapGroupIsStarting(group, startingAsset) {
|
|
921
|
-
return startingAsset !== void 0 && group.options.some((option) => option.pay_in_asset === startingAsset);
|
|
922
|
-
}
|
|
923
922
|
function renderElementSwapUnavailableHtml(quote, checkout) {
|
|
924
923
|
const model = createSwapUnavailableModel(quote, checkout);
|
|
925
924
|
return `<section part="swap-panel" class="${orClasses5.swapPanel}">
|
|
@@ -1081,49 +1080,33 @@ function renderPaymentWizardHtml(view = {}) {
|
|
|
1081
1080
|
`;
|
|
1082
1081
|
}
|
|
1083
1082
|
function renderElementCompactPaymentSelectorHtml(swapAssetOptions, view) {
|
|
1084
|
-
const
|
|
1083
|
+
const limitContext = elementsSwapLimitContext(view);
|
|
1084
|
+
const display = createMethodGridDisplay({
|
|
1085
|
+
entries: buildMethodGridEntries(paymentMethods, swapAssetOptions),
|
|
1086
|
+
selectedPickerKey: view.selectedPickerKey ?? null,
|
|
1087
|
+
selectedAssetByGroup: view.selectedSwapAssetByGroup ?? {},
|
|
1088
|
+
startingAsset: wizardStartingAsset(view) ?? null,
|
|
1089
|
+
...limitContext === void 0 ? {} : { checkout: limitContext }
|
|
1090
|
+
});
|
|
1085
1091
|
const currenciesLoading = view.currenciesLoading === true && swapAssetOptions.length === 0;
|
|
1086
|
-
const
|
|
1087
|
-
const selectedGroup = findSwapGridGroup(entries, selectedKey);
|
|
1088
|
-
const networkRequired = selectedGroup !== void 0 && selectedGroup.options.length > 1;
|
|
1089
|
-
const selectedNetworks = view.selectedSwapNetworks ?? {};
|
|
1090
|
-
const selectedGroupKey = selectedGroup?.label.trim().toUpperCase();
|
|
1091
|
-
const selectedNetworkAsset = selectedGroupKey === void 0 ? void 0 : selectedNetworks[selectedGroupKey];
|
|
1092
|
-
const selectedNetworkOption = selectedGroup === void 0 || selectedNetworkAsset === void 0 ? void 0 : selectedGroup.options.find((option) => option.pay_in_asset === selectedNetworkAsset);
|
|
1093
|
-
const startingAsset = wizardStartingAsset(view);
|
|
1094
|
-
const gridBusy = startingAsset !== void 0;
|
|
1095
|
-
let continueDisabled = selectedNetworkOption === void 0 || gridBusy;
|
|
1096
|
-
let continueAttr = "";
|
|
1097
|
-
let continueLabel = escapeHtml5(checkoutLabels5.continue);
|
|
1098
|
-
const continueStarting = selectedNetworkOption !== void 0 && selectedNetworkOption.pay_in_asset === startingAsset;
|
|
1099
|
-
if (selectedNetworkOption !== void 0) {
|
|
1100
|
-
const disabled = selectedNetworkOption.available === false;
|
|
1101
|
-
const limitMessage = elementsSwapLimitMessage(selectedNetworkOption, view);
|
|
1102
|
-
continueDisabled = disabled || gridBusy;
|
|
1103
|
-
continueAttr = disabled || gridBusy ? "" : `${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES5.swapStart}="${escapeHtml5(selectedNetworkOption.pay_in_asset)}"`;
|
|
1104
|
-
if (disabled && limitMessage !== void 0) continueLabel = escapeHtml5(limitMessage);
|
|
1105
|
-
else if (continueStarting) continueLabel = escapeHtml5(checkoutLabels5.preparingPayment);
|
|
1106
|
-
} else if (networkRequired) {
|
|
1107
|
-
continueDisabled = true;
|
|
1108
|
-
}
|
|
1092
|
+
const { gridBusy, networkRequired, selectedGroup, continueTarget } = display;
|
|
1109
1093
|
const continueButton = (className) => renderElementMethodConfirmHtml({
|
|
1110
1094
|
className,
|
|
1111
|
-
disabled:
|
|
1112
|
-
starting:
|
|
1113
|
-
swapStartAsset:
|
|
1114
|
-
label:
|
|
1095
|
+
disabled: continueTarget === void 0 || continueTarget.disabled,
|
|
1096
|
+
starting: continueTarget?.starting === true,
|
|
1097
|
+
swapStartAsset: continueTarget === void 0 || continueTarget.disabled ? void 0 : continueTarget.payInAsset,
|
|
1098
|
+
label: escapeHtml5(continueTarget?.label ?? checkoutLabels5.continue)
|
|
1115
1099
|
});
|
|
1116
|
-
const tiles = entries.map((entry) => {
|
|
1100
|
+
const tiles = display.entries.map((entry) => {
|
|
1117
1101
|
if (entry.kind === "method") {
|
|
1118
1102
|
const method = entry.method;
|
|
1119
|
-
const accent = paymentAccentId(method.id);
|
|
1120
1103
|
return `
|
|
1121
1104
|
<button
|
|
1122
1105
|
part="method"
|
|
1123
1106
|
type="button"
|
|
1124
|
-
class="${assetButtonClasses({ accent, selected: false, disabled:
|
|
1107
|
+
class="${assetButtonClasses({ accent: entry.accent, selected: false, disabled: entry.disabled })}"
|
|
1125
1108
|
${OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES5.method}="${escapeHtml5(method.id)}"
|
|
1126
|
-
${
|
|
1109
|
+
${entry.disabled ? 'disabled aria-disabled="true"' : ""}
|
|
1127
1110
|
>
|
|
1128
1111
|
<span aria-hidden="true" class="${orClasses5.methodIconWrap}">
|
|
1129
1112
|
<img class="${orClasses5.methodIcon}" alt="" src="${escapeHtml5(getPaymentMethodIcon(method.id, view.resolveAssetUrl))}">
|
|
@@ -1136,8 +1119,8 @@ function renderElementCompactPaymentSelectorHtml(swapAssetOptions, view) {
|
|
|
1136
1119
|
return renderElementSwapMethodGroupHtml(
|
|
1137
1120
|
entry.group,
|
|
1138
1121
|
view,
|
|
1139
|
-
|
|
1140
|
-
|
|
1122
|
+
gridBusy,
|
|
1123
|
+
entry.group.selected ? continueButton(orClasses5.methodConfirmDesktop) : void 0
|
|
1141
1124
|
);
|
|
1142
1125
|
}).join("");
|
|
1143
1126
|
const loadingTile = currenciesLoading ? `<div part="currencies-loading" role="status" aria-live="polite" class="${orClasses5.methodCurrenciesLoading}">
|
|
@@ -1164,12 +1147,7 @@ function renderElementCompactPaymentSelectorHtml(swapAssetOptions, view) {
|
|
|
1164
1147
|
`;
|
|
1165
1148
|
}
|
|
1166
1149
|
function renderElementNetworkSelectorHtml(group, view, continueButtonHtml, mobile) {
|
|
1167
|
-
const accent =
|
|
1168
|
-
const groupKey = group.label.trim().toUpperCase();
|
|
1169
|
-
const selectedNetworks = view.selectedSwapNetworks ?? {};
|
|
1170
|
-
const selectedAsset = selectedNetworks[groupKey];
|
|
1171
|
-
const selectedOption = selectedAsset === void 0 ? void 0 : group.options.find((option) => option.pay_in_asset === selectedAsset);
|
|
1172
|
-
const { panelId, headingId } = wizardNetworkGroupIds(groupKey);
|
|
1150
|
+
const { accent, groupKey, panelId, headingId, selectedOption } = group;
|
|
1173
1151
|
const networkButtons = group.options.map((option) => {
|
|
1174
1152
|
const optionDisabled = option.available === false;
|
|
1175
1153
|
const optionSelected = option.pay_in_asset === selectedOption?.pay_in_asset;
|
|
@@ -1211,7 +1189,7 @@ function renderElementNetworkSelectorHtml(group, view, continueButtonHtml, mobil
|
|
|
1211
1189
|
<div class="${orClasses5.methodNetworkLayout}">
|
|
1212
1190
|
<div>
|
|
1213
1191
|
<h3 id="${headingId}" class="${orClasses5.methodNetworkHeading}">${escapeHtml5(
|
|
1214
|
-
|
|
1192
|
+
group.heading
|
|
1215
1193
|
)}</h3>
|
|
1216
1194
|
<p class="${orClasses5.methodNetworkHint}">${escapeHtml5(
|
|
1217
1195
|
checkoutLabels5.selectNetworkToContinue
|
|
@@ -1238,25 +1216,19 @@ function renderElementMethodConfirmHtml(options) {
|
|
|
1238
1216
|
${options.starting ? 'aria-busy="true"' : ""}
|
|
1239
1217
|
>${options.starting ? `<span part="spinner" class="${orClasses5.continueSpinner}" aria-hidden="true"></span>` : ""}${options.label}</button>`;
|
|
1240
1218
|
}
|
|
1241
|
-
function renderElementSwapMethodGroupHtml(group, view,
|
|
1242
|
-
const
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
const gridBusy = startingAsset !== void 0;
|
|
1255
|
-
const disabled = group.options.every((option) => option.available === false);
|
|
1256
|
-
const accent = paymentAccentId(group.label);
|
|
1257
|
-
const limitOption = disabled ? swapGroupLimitOption(group.options) ?? activeOption : activeOption;
|
|
1258
|
-
const limitMessage = elementsSwapLimitMessage(limitOption, view);
|
|
1259
|
-
const { panelId } = wizardNetworkGroupIds(groupKey);
|
|
1219
|
+
function renderElementSwapMethodGroupHtml(group, view, gridBusy, continueButtonHtml) {
|
|
1220
|
+
const {
|
|
1221
|
+
pickerKey,
|
|
1222
|
+
selected,
|
|
1223
|
+
displayOption,
|
|
1224
|
+
selectedOption,
|
|
1225
|
+
multiNetwork,
|
|
1226
|
+
starting,
|
|
1227
|
+
disabled,
|
|
1228
|
+
accent,
|
|
1229
|
+
limitMessage,
|
|
1230
|
+
panelId
|
|
1231
|
+
} = group;
|
|
1260
1232
|
const networkDetail = !disabled && multiNetwork ? selected && selectedOption !== void 0 ? `${escapeHtml5(selectedOption.network_label)} network` : escapeHtml5(checkoutLabels5.selectNetwork) : void 0;
|
|
1261
1233
|
const mobileReveal = multiNetwork ? `
|
|
1262
1234
|
<div class="${orClasses5.methodNetworkRevealAnim} ${selected ? orClasses5.methodNetworkRevealAnimOpen : orClasses5.methodNetworkRevealAnimClosed}">
|
|
@@ -1408,9 +1380,12 @@ function renderCheckoutHtml(view) {
|
|
|
1408
1380
|
renderTransactionDetailsHtml(checkoutState ?? { ...view, rail: view.rail ?? "lightning" })
|
|
1409
1381
|
) : expired ? `<div part="actions" class="${orClasses6.actions}">${startOverButton}</div>` : `<div part="actions" class="${orClasses6.actions}">${copyButton}${decodeButton}</div>`;
|
|
1410
1382
|
const resolvedTheme = view.theme ?? "light";
|
|
1383
|
+
const orderDescription = view.description === void 0 || view.description === "" ? "" : `<p part="order-description" ${OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES.orderDescription} class="${orClasses6.orderDescription}">${escapeHtml6(view.description)}</p>`;
|
|
1411
1384
|
return `
|
|
1412
1385
|
${styleTag(view.inlineStyles)}
|
|
1413
1386
|
<section part="root" data-theme="${escapeHtml6(resolvedTheme)}" class="${orClasses6.root}">
|
|
1387
|
+
<slot name="${OPENRECEIVE_CHECKOUT_ELEMENT_SLOTS.order}"></slot>
|
|
1388
|
+
${orderDescription}
|
|
1414
1389
|
${hideLightning ? "" : `<div part="payment-layout" class="${paymentLayoutClass}">
|
|
1415
1390
|
${lightningPane}
|
|
1416
1391
|
<div part="payment-info" class="${orClasses6.paymentInfo}">
|
|
@@ -1505,6 +1480,7 @@ function checkoutSnapshotDisplayKey(snapshot) {
|
|
|
1505
1480
|
)
|
|
1506
1481
|
});
|
|
1507
1482
|
}
|
|
1483
|
+
var warnedAssetSeamConflict = false;
|
|
1508
1484
|
function defineElements(options = {}) {
|
|
1509
1485
|
const registry = options.registry ?? globalThis.customElements;
|
|
1510
1486
|
const HTMLElementCtor = globalThis.HTMLElement;
|
|
@@ -1520,7 +1496,7 @@ function defineElements(options = {}) {
|
|
|
1520
1496
|
activeTutorialCopied = false;
|
|
1521
1497
|
swapOptions = [];
|
|
1522
1498
|
swapOptionsLoaded = false;
|
|
1523
|
-
|
|
1499
|
+
selectedSwapAssetByGroup = {};
|
|
1524
1500
|
selectedPickerKey = null;
|
|
1525
1501
|
selectedSwapAsset = null;
|
|
1526
1502
|
startedSwapInvoice;
|
|
@@ -1604,9 +1580,11 @@ function defineElements(options = {}) {
|
|
|
1604
1580
|
OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.syncUrl,
|
|
1605
1581
|
OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumePathPrefix,
|
|
1606
1582
|
OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.routeReference,
|
|
1583
|
+
OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumable,
|
|
1607
1584
|
OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.polling,
|
|
1608
1585
|
OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.pollIntervalMs,
|
|
1609
|
-
OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.decodeLinkUrl
|
|
1586
|
+
OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.decodeLinkUrl,
|
|
1587
|
+
OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.assetBaseUrl
|
|
1610
1588
|
];
|
|
1611
1589
|
}
|
|
1612
1590
|
connectedCallback() {
|
|
@@ -1621,7 +1599,7 @@ function defineElements(options = {}) {
|
|
|
1621
1599
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
1622
1600
|
if (!this.isConnected || this.session.applyingOwnAttributes) return;
|
|
1623
1601
|
if (oldValue === newValue) return;
|
|
1624
|
-
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;
|
|
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;
|
|
1625
1603
|
if (displayOnly) {
|
|
1626
1604
|
this.render();
|
|
1627
1605
|
this.syncThemeAncestorObserver();
|
|
@@ -1654,6 +1632,27 @@ function defineElements(options = {}) {
|
|
|
1654
1632
|
this.stopCheckoutController();
|
|
1655
1633
|
this.stopThemeAncestorObserver();
|
|
1656
1634
|
}
|
|
1635
|
+
/**
|
|
1636
|
+
* The asset seam for this element. `resolveAssetUrl` on `defineElements` is
|
|
1637
|
+
* the explicit, programmatic answer and wins; `asset-base-url` is the string
|
|
1638
|
+
* every host can reach — plain markup and the Vue/Svelte/Angular wrappers
|
|
1639
|
+
* included, since `defineElements` is first-write-wins and all three call it
|
|
1640
|
+
* with no options. Setting both is a host mistake worth naming once.
|
|
1641
|
+
*/
|
|
1642
|
+
resolveAssetUrlResolver() {
|
|
1643
|
+
const base = this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.assetBaseUrl);
|
|
1644
|
+
if (options.resolveAssetUrl !== void 0) {
|
|
1645
|
+
if (base !== null && !warnedAssetSeamConflict) {
|
|
1646
|
+
warnedAssetSeamConflict = true;
|
|
1647
|
+
globalThis.console?.warn(
|
|
1648
|
+
"[openreceive] Both defineElements({ resolveAssetUrl }) and asset-base-url are set; resolveAssetUrl wins. Drop one."
|
|
1649
|
+
);
|
|
1650
|
+
}
|
|
1651
|
+
return options.resolveAssetUrl;
|
|
1652
|
+
}
|
|
1653
|
+
if (base === null || base.trim() === "") return void 0;
|
|
1654
|
+
return createAssetBaseUrlResolver(base);
|
|
1655
|
+
}
|
|
1657
1656
|
// Create mode: a `reference` is set but no `invoice` snapshot is provided. The element
|
|
1658
1657
|
// owns the whole lifecycle — it prepares the checkout against
|
|
1659
1658
|
// `${prefix}/checkouts/prepare` (locking the amount without minting), mints a Lightning
|
|
@@ -1692,11 +1691,29 @@ function defineElements(options = {}) {
|
|
|
1692
1691
|
}
|
|
1693
1692
|
return parsed;
|
|
1694
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
|
+
}
|
|
1695
1712
|
/** Order data belongs to the host; this only performs optional History API sync. */
|
|
1696
1713
|
syncResumePath(reference) {
|
|
1697
1714
|
const syncUrl = parseBooleanAttribute(
|
|
1698
1715
|
this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.syncUrl)
|
|
1699
|
-
);
|
|
1716
|
+
) === true;
|
|
1700
1717
|
if (syncUrl) {
|
|
1701
1718
|
const resumePathPrefix = this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.resumePathPrefix) ?? "/checkout";
|
|
1702
1719
|
const routeReference = this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.routeReference) ?? void 0;
|
|
@@ -1716,7 +1733,7 @@ function defineElements(options = {}) {
|
|
|
1716
1733
|
(invoice) => invoice.rail === "swap" && invoice.swap !== void 0
|
|
1717
1734
|
);
|
|
1718
1735
|
if (swapInvoice !== void 0) {
|
|
1719
|
-
this.startedSwapInvoice =
|
|
1736
|
+
this.startedSwapInvoice = swapInvoice;
|
|
1720
1737
|
}
|
|
1721
1738
|
const displayKey = checkoutSnapshotDisplayKey(snapshot);
|
|
1722
1739
|
if (this.lastSnapshotDisplayKey === displayKey) return;
|
|
@@ -1753,6 +1770,7 @@ function defineElements(options = {}) {
|
|
|
1753
1770
|
const invoice = invoiceAttr ?? "";
|
|
1754
1771
|
const lightningRequested = !this.isCreateMode() || this.session.lightningRequested || invoice.length > 0;
|
|
1755
1772
|
const decodeLinkUrl = this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.decodeLinkUrl) ?? void 0;
|
|
1773
|
+
const assetUrlResolver = this.resolveAssetUrlResolver();
|
|
1756
1774
|
const selectedQuote = this.selectedSwapAsset === null ? void 0 : this.session.swapQuotes[this.selectedSwapAsset];
|
|
1757
1775
|
const unavailableSwapQuote = selectedQuote?.available === false ? selectedQuote : void 0;
|
|
1758
1776
|
const { root, inlineStyles } = this.prepareShadowRoot();
|
|
@@ -1769,6 +1787,10 @@ function defineElements(options = {}) {
|
|
|
1769
1787
|
this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.status)
|
|
1770
1788
|
),
|
|
1771
1789
|
expires_at: readElementExpiresAt(this),
|
|
1790
|
+
// Host-owned order context, straight off the polled snapshot: the
|
|
1791
|
+
// element has no attribute for it because the payer must never be able
|
|
1792
|
+
// to write the copy next to the amount.
|
|
1793
|
+
...this.latestCheckoutSnapshot?.description === void 0 ? {} : { description: this.latestCheckoutSnapshot.description },
|
|
1772
1794
|
theme: this.resolveTheme(),
|
|
1773
1795
|
payment_wizard: parseBooleanAttribute(
|
|
1774
1796
|
this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.paymentWizard)
|
|
@@ -1779,17 +1801,18 @@ function defineElements(options = {}) {
|
|
|
1779
1801
|
selectedBitcoinRoute: this.selection.selectedBitcoinRoute,
|
|
1780
1802
|
swapOptions: this.swapOptions,
|
|
1781
1803
|
currenciesLoading: !this.swapOptionsLoaded,
|
|
1782
|
-
|
|
1804
|
+
selectedSwapAssetByGroup: this.selectedSwapAssetByGroup,
|
|
1783
1805
|
selectedPickerKey: this.selectedPickerKey,
|
|
1784
1806
|
startingSwapAsset: this.session.startingSwapAsset,
|
|
1785
1807
|
selectedSwapAsset: this.selectedSwapAsset,
|
|
1808
|
+
resumable: this.isResumable(),
|
|
1786
1809
|
...this.latestCheckoutSnapshot?.amount_msats === void 0 ? {} : { amountMsats: this.latestCheckoutSnapshot.amount_msats },
|
|
1787
1810
|
...this.latestCheckoutSnapshot?.fiat === void 0 ? {} : { fiat: this.latestCheckoutSnapshot.fiat },
|
|
1788
1811
|
...this.latestCheckoutSnapshot?.reference === void 0 ? {} : { reference: this.latestCheckoutSnapshot.reference },
|
|
1789
1812
|
...this.latestCheckoutSnapshot?.checkout_id === void 0 ? {} : { checkoutId: this.latestCheckoutSnapshot.checkout_id },
|
|
1790
1813
|
lightningInvoice: invoice,
|
|
1791
1814
|
...decodeLinkUrl === void 0 ? {} : { decodeLinkUrl },
|
|
1792
|
-
...
|
|
1815
|
+
...assetUrlResolver === void 0 ? {} : { resolveAssetUrl: assetUrlResolver },
|
|
1793
1816
|
...this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.paymentHash) === null ? {} : {
|
|
1794
1817
|
paymentHash: this.getAttribute(OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES3.paymentHash) ?? void 0
|
|
1795
1818
|
},
|
|
@@ -1863,7 +1886,8 @@ function defineElements(options = {}) {
|
|
|
1863
1886
|
startCheckoutController() {
|
|
1864
1887
|
const attributeSnapshot = this.currentCheckoutSnapshot();
|
|
1865
1888
|
const latest = this.latestCheckoutSnapshot;
|
|
1866
|
-
const
|
|
1889
|
+
const chosen = latest?.active?.rail === "swap" ? latest : attributeSnapshot ?? latest;
|
|
1890
|
+
const snapshot = chosen !== void 0 && chosen.description === void 0 && latest?.description !== void 0 && latest.reference === chosen.reference ? { ...chosen, description: latest.description } : chosen;
|
|
1867
1891
|
const prefix = this.resolvePollPrefix(snapshot?.reference);
|
|
1868
1892
|
if (snapshot === void 0) {
|
|
1869
1893
|
this.stopCheckoutController();
|
|
@@ -1879,7 +1903,8 @@ function defineElements(options = {}) {
|
|
|
1879
1903
|
this.stopCheckoutController();
|
|
1880
1904
|
this.controller = createCheckoutController({
|
|
1881
1905
|
snapshot,
|
|
1882
|
-
...prefix === void 0
|
|
1906
|
+
...prefix === void 0 ? {} : { prefix },
|
|
1907
|
+
polling,
|
|
1883
1908
|
...pollIntervalMs === void 0 ? {} : { pollIntervalMs },
|
|
1884
1909
|
logger: options.logger,
|
|
1885
1910
|
onError: (error) => this.dispatchError(error),
|
|
@@ -1974,7 +1999,7 @@ function defineElements(options = {}) {
|
|
|
1974
1999
|
}
|
|
1975
2000
|
const swapInvoice = this.currentSwapInvoice();
|
|
1976
2001
|
if (swapInvoice !== void 0) {
|
|
1977
|
-
const display = createSwapDisplayModel2(swapInvoice, {});
|
|
2002
|
+
const display = createSwapDisplayModel2(swapInvoice, { resumable: this.isResumable() });
|
|
1978
2003
|
const swapCountdown = root.querySelector('[part="swap-countdown"]');
|
|
1979
2004
|
if (swapCountdown !== null && display !== void 0) {
|
|
1980
2005
|
swapCountdown.textContent = display.countdownLabel;
|
|
@@ -2009,9 +2034,15 @@ function defineElements(options = {}) {
|
|
|
2009
2034
|
if (!(button instanceof HTMLButtonElement) || button.disabled) return;
|
|
2010
2035
|
const key = button.getAttribute(OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES7.pickerSelect);
|
|
2011
2036
|
if (key === null || key.length === 0) return;
|
|
2012
|
-
const
|
|
2013
|
-
|
|
2014
|
-
|
|
2037
|
+
const selection = resolveWizardSelection({
|
|
2038
|
+
pickerKey: key,
|
|
2039
|
+
previousKey: this.selectedPickerKey,
|
|
2040
|
+
entries: buildMethodGridEntries2(paymentMethods2, this.swapOptions),
|
|
2041
|
+
selectedAssetByGroup: this.selectedSwapAssetByGroup
|
|
2042
|
+
});
|
|
2043
|
+
if (selection.kind === "none") return;
|
|
2044
|
+
if (selection.kind === "select_method") {
|
|
2045
|
+
const method = parsePaymentMethod(selection.methodId);
|
|
2015
2046
|
if (method === null) return;
|
|
2016
2047
|
this.selectedPickerKey = null;
|
|
2017
2048
|
this.selection = updatePaymentWizardSelection(this.selection, {
|
|
@@ -2024,23 +2055,13 @@ function defineElements(options = {}) {
|
|
|
2024
2055
|
this.render();
|
|
2025
2056
|
return;
|
|
2026
2057
|
}
|
|
2027
|
-
|
|
2028
|
-
this.selectedPickerKey = key;
|
|
2029
|
-
const entries = buildMethodGridEntries2(paymentMethods2, this.swapOptions);
|
|
2030
|
-
const nextGroup = findSwapGridGroup2(entries, key);
|
|
2031
|
-
if (nextGroup !== void 0 && nextGroup.options.length === 1) {
|
|
2032
|
-
const option = nextGroup.options.find((entry) => entry.available !== false) ?? nextGroup.options[0];
|
|
2033
|
-
if (option === void 0 || option.available === false) return;
|
|
2058
|
+
if (selection.kind === "start_swap") {
|
|
2034
2059
|
this.selectedPickerKey = null;
|
|
2035
|
-
void this.session.startSwap(
|
|
2060
|
+
void this.session.startSwap(selection.payInAsset);
|
|
2036
2061
|
return;
|
|
2037
2062
|
}
|
|
2038
|
-
this.
|
|
2039
|
-
|
|
2040
|
-
nextKey: key,
|
|
2041
|
-
previousKey,
|
|
2042
|
-
selectedNetworks: this.selectedSwapNetworks
|
|
2043
|
-
});
|
|
2063
|
+
this.selectedPickerKey = key;
|
|
2064
|
+
this.selectedSwapAssetByGroup = selection.selectedAssetByGroup;
|
|
2044
2065
|
this.render();
|
|
2045
2066
|
});
|
|
2046
2067
|
});
|
|
@@ -2070,7 +2091,7 @@ function defineElements(options = {}) {
|
|
|
2070
2091
|
if (target === "swap-asset") {
|
|
2071
2092
|
this.selectedSwapAsset = null;
|
|
2072
2093
|
this.selectedPickerKey = null;
|
|
2073
|
-
this.
|
|
2094
|
+
this.selectedSwapAssetByGroup = {};
|
|
2074
2095
|
this.render();
|
|
2075
2096
|
return;
|
|
2076
2097
|
}
|
|
@@ -2119,8 +2140,8 @@ function defineElements(options = {}) {
|
|
|
2119
2140
|
if (groupKey === null || groupKey.length === 0 || payInAsset === null) return;
|
|
2120
2141
|
const details = button.closest("details");
|
|
2121
2142
|
if (details instanceof HTMLDetailsElement) details.open = false;
|
|
2122
|
-
this.
|
|
2123
|
-
...this.
|
|
2143
|
+
this.selectedSwapAssetByGroup = {
|
|
2144
|
+
...this.selectedSwapAssetByGroup,
|
|
2124
2145
|
[groupKey]: payInAsset
|
|
2125
2146
|
};
|
|
2126
2147
|
this.render();
|
|
@@ -2131,8 +2152,9 @@ function defineElements(options = {}) {
|
|
|
2131
2152
|
this.dismissedSwapInvoiceId = current?.invoice_id ?? null;
|
|
2132
2153
|
this.selectedSwapAsset = null;
|
|
2133
2154
|
this.selectedPickerKey = null;
|
|
2134
|
-
this.
|
|
2155
|
+
this.selectedSwapAssetByGroup = {};
|
|
2135
2156
|
this.clearRefundAddressDraft();
|
|
2157
|
+
this.controller?.clearSwapRefundStaging();
|
|
2136
2158
|
void this.session.ensureLightning();
|
|
2137
2159
|
this.render();
|
|
2138
2160
|
});
|
|
@@ -2271,20 +2293,10 @@ function defineElements(options = {}) {
|
|
|
2271
2293
|
}
|
|
2272
2294
|
}
|
|
2273
2295
|
async refundSwap(attemptId, refundAddress, confirm) {
|
|
2274
|
-
const
|
|
2275
|
-
|
|
2276
|
-
if (prefix === void 0) return;
|
|
2296
|
+
const controller = this.controller;
|
|
2297
|
+
if (controller === void 0) return;
|
|
2277
2298
|
try {
|
|
2278
|
-
this.startedSwapInvoice = await
|
|
2279
|
-
fetch: globalThis.fetch,
|
|
2280
|
-
prefix,
|
|
2281
|
-
...reference === null ? {} : { reference },
|
|
2282
|
-
invoices: [this.startedSwapInvoice, ...this.latestCheckoutSnapshot?.invoices ?? []],
|
|
2283
|
-
attemptId,
|
|
2284
|
-
refundAddress,
|
|
2285
|
-
confirm,
|
|
2286
|
-
logger: options.logger
|
|
2287
|
-
});
|
|
2299
|
+
this.startedSwapInvoice = confirm ? await controller.confirmSwapRefund({ attemptId, refundAddress }) : await controller.stageSwapRefund({ attemptId, refundAddress });
|
|
2288
2300
|
this.dismissedSwapInvoiceId = null;
|
|
2289
2301
|
this.render();
|
|
2290
2302
|
} catch (error) {
|
|
@@ -2292,16 +2304,10 @@ function defineElements(options = {}) {
|
|
|
2292
2304
|
}
|
|
2293
2305
|
}
|
|
2294
2306
|
currentSwapInvoice() {
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
return fromSnapshot;
|
|
2300
|
-
}
|
|
2301
|
-
const matched = this.latestCheckoutSnapshot?.invoices.find(
|
|
2302
|
-
(invoice) => invoice.invoice_id === this.startedSwapInvoice?.invoice_id
|
|
2303
|
-
) ?? this.startedSwapInvoice;
|
|
2304
|
-
return overlaySwapRefundStaging(matched, this.startedSwapInvoice);
|
|
2307
|
+
return selectCurrentSwapInvoice(this.latestCheckoutSnapshot, {
|
|
2308
|
+
started: this.startedSwapInvoice,
|
|
2309
|
+
dismissedInvoiceId: this.dismissedSwapInvoiceId
|
|
2310
|
+
});
|
|
2305
2311
|
}
|
|
2306
2312
|
renderSwapQrCodes(root) {
|
|
2307
2313
|
root.querySelectorAll(OPENRECEIVE_PAYMENT_WIZARD_SELECTORS3.swapQr).forEach((target) => {
|