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