@openreceive/react 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +21 -5
- package/dist/index.js +202 -193
- package/dist/styles.css +1 -1
- package/package.json +4 -3
- package/skills/debug-openreceive-payment/SKILL.md +89 -0
- package/skills/integrate-openreceive/SKILL.md +116 -0
- package/skills/integrate-openreceive/references/node.md +484 -0
- package/skills/integrate-openreceive/references/rails.md +577 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { CheckoutComponentProps, CheckoutState, QrEncoder, BrowserLoggerOption, CheckoutStatusRefresh, Status, SwapRefundStaging, CheckoutSnapshot, AssetUrlResolver, BrowserLogContext, CheckoutInvoiceSnapshot,
|
|
2
|
+
import { CheckoutComponentProps, CheckoutState, QrEncoder, BrowserLoggerOption, CheckoutStatusRefresh, Status, SwapRefundStaging, CheckoutSnapshot, AssetUrlResolver, ThemePreference, BrowserLogContext, CheckoutInvoiceSnapshot, ResolvedTheme, ThemeModel, CheckoutPhase, CheckoutStatusModel, UnixSeconds, BrowserLogger, TransactionDetailsSource } from '@openreceive/browser/headless';
|
|
3
3
|
export { TransactionDetailsSource, resolveTransactionDetailRows } from '@openreceive/browser/headless';
|
|
4
4
|
|
|
5
5
|
interface CheckoutData {
|
|
@@ -164,11 +164,23 @@ interface CheckoutProps extends CheckoutComponentProps, CheckoutEventHandlers, O
|
|
|
164
164
|
readonly children?: CheckoutChildren;
|
|
165
165
|
/** Passed through to the payment wizard. See {@link PaymentWizardProps.resolveAssetUrl}. */
|
|
166
166
|
readonly resolveAssetUrl?: AssetUrlResolver;
|
|
167
|
+
/**
|
|
168
|
+
* Lock the checkout to one theme. Wins over the stored preference and any
|
|
169
|
+
* ancestor ThemeScope, and hides the toggle: a host embedding the checkout in
|
|
170
|
+
* a page that is already dark passes `theme="dark"` and is done. `"system"`
|
|
171
|
+
* locks to `prefers-color-scheme`, ignoring the stored preference. Unset (the
|
|
172
|
+
* default), the payer's stored choice applies, falling back to
|
|
173
|
+
* `defaultTheme`, falling back to the system scheme. The custom element's
|
|
174
|
+
* `theme` attribute is the same lock.
|
|
175
|
+
*/
|
|
176
|
+
readonly theme?: ThemePreference;
|
|
167
177
|
}
|
|
168
178
|
interface UseThemeOptions {
|
|
169
179
|
readonly defaultTheme?: ThemePreference;
|
|
170
180
|
readonly storageKey?: string;
|
|
171
181
|
readonly storage?: Storage;
|
|
182
|
+
/** Lock: this preference wins over storage and scope, and `setTheme` becomes a no-op. */
|
|
183
|
+
readonly theme?: ThemePreference;
|
|
172
184
|
}
|
|
173
185
|
interface UseThemeResult {
|
|
174
186
|
readonly theme: ThemePreference;
|
|
@@ -195,6 +207,8 @@ interface ThemeScopeProps extends Omit<React.HTMLAttributes<HTMLElement>, "child
|
|
|
195
207
|
readonly defaultTheme?: ThemePreference;
|
|
196
208
|
readonly storageKey?: string;
|
|
197
209
|
readonly storage?: Storage;
|
|
210
|
+
/** Lock: this preference wins over storage, and the toggle is not rendered. */
|
|
211
|
+
readonly theme?: ThemePreference;
|
|
198
212
|
readonly themeToggle?: boolean;
|
|
199
213
|
readonly topbarClassName?: string;
|
|
200
214
|
readonly themeToggleClassName?: string;
|
|
@@ -225,10 +239,12 @@ interface PaymentWizardProps {
|
|
|
225
239
|
readonly decodeLinkUrl?: string;
|
|
226
240
|
/**
|
|
227
241
|
* Rewrite a packaged asset path (`assets/provider-icons/strike.png`,
|
|
228
|
-
* `assets/
|
|
229
|
-
* only resolve under Vite/Rollup; every other bundler needs
|
|
230
|
-
*
|
|
231
|
-
* links.
|
|
242
|
+
* `assets/pay_tutorials/strike-1.webp`) into a URL this host can serve. The
|
|
243
|
+
* packaged URLs only resolve under Vite/Rollup; every other bundler needs
|
|
244
|
+
* this, or the provider logos and pay tutorials come out as dead `file://`
|
|
245
|
+
* links. The payment-method icons are compiled in as `data:` URIs and need
|
|
246
|
+
* nothing; given a resolver they go through it too (`assets/icons/btc.svg`).
|
|
247
|
+
* See docs/guides/provider-registry.md.
|
|
232
248
|
*/
|
|
233
249
|
readonly resolveAssetUrl?: AssetUrlResolver;
|
|
234
250
|
/**
|
package/dist/index.js
CHANGED
|
@@ -469,6 +469,7 @@ function useLocalTheme(options = {}) {
|
|
|
469
469
|
const storageKey = options.storageKey ?? OPENRECEIVE_THEME_STORAGE_KEY;
|
|
470
470
|
const storage = options.storage;
|
|
471
471
|
const defaultTheme = options.defaultTheme;
|
|
472
|
+
const lockedTheme = options.theme;
|
|
472
473
|
const theme = React4.useSyncExternalStore(
|
|
473
474
|
subscribeStoredTheme,
|
|
474
475
|
React4.useCallback(
|
|
@@ -493,9 +494,10 @@ function useLocalTheme(options = {}) {
|
|
|
493
494
|
getSystemDark,
|
|
494
495
|
getServerSystemDark
|
|
495
496
|
);
|
|
496
|
-
const themeModel = createThemeModel(theme, { systemDark });
|
|
497
|
+
const themeModel = createThemeModel(lockedTheme ?? theme, { systemDark });
|
|
497
498
|
const setTheme = React4.useCallback(
|
|
498
499
|
(nextTheme) => {
|
|
500
|
+
if (lockedTheme !== void 0) return;
|
|
499
501
|
lastSetTheme.set(storageKey, nextTheme);
|
|
500
502
|
writeThemePreference(nextTheme, {
|
|
501
503
|
storage,
|
|
@@ -503,13 +505,13 @@ function useLocalTheme(options = {}) {
|
|
|
503
505
|
});
|
|
504
506
|
notifyStoredThemeChange();
|
|
505
507
|
},
|
|
506
|
-
[storage, storageKey]
|
|
508
|
+
[storage, storageKey, lockedTheme]
|
|
507
509
|
);
|
|
508
510
|
const toggleTheme = React4.useCallback(() => {
|
|
509
511
|
setTheme(themeModel.nextTheme);
|
|
510
512
|
}, [setTheme, themeModel.nextTheme]);
|
|
511
513
|
return {
|
|
512
|
-
theme,
|
|
514
|
+
theme: lockedTheme ?? theme,
|
|
513
515
|
resolvedTheme: themeModel.resolvedTheme,
|
|
514
516
|
model: themeModel,
|
|
515
517
|
nextTheme: themeModel.nextTheme,
|
|
@@ -525,7 +527,7 @@ function useTheme(options = {}) {
|
|
|
525
527
|
const scoped = React4.useContext(ThemeContext);
|
|
526
528
|
const local = useLocalTheme(options);
|
|
527
529
|
const storageKey = options.storageKey ?? OPENRECEIVE_THEME_STORAGE_KEY;
|
|
528
|
-
if (scoped !== null && options.storage === void 0 && (options.storageKey === void 0 || options.storageKey === storageKey) && options.defaultTheme === void 0) {
|
|
530
|
+
if (scoped !== null && options.theme === void 0 && options.storage === void 0 && (options.storageKey === void 0 || options.storageKey === storageKey) && options.defaultTheme === void 0) {
|
|
529
531
|
return { ...scoped, fromScope: true };
|
|
530
532
|
}
|
|
531
533
|
return local;
|
|
@@ -568,6 +570,7 @@ function ThemeScope(props) {
|
|
|
568
570
|
defaultTheme,
|
|
569
571
|
storageKey,
|
|
570
572
|
storage,
|
|
573
|
+
theme: lockedTheme,
|
|
571
574
|
themeToggle = false,
|
|
572
575
|
topbarClassName,
|
|
573
576
|
themeToggleClassName,
|
|
@@ -578,9 +581,11 @@ function ThemeScope(props) {
|
|
|
578
581
|
const theme = useLocalTheme({
|
|
579
582
|
defaultTheme,
|
|
580
583
|
storageKey,
|
|
581
|
-
storage
|
|
584
|
+
storage,
|
|
585
|
+
theme: lockedTheme
|
|
582
586
|
});
|
|
583
587
|
const scopedChildren = typeof children === "function" ? children(theme) : children;
|
|
588
|
+
const showsToggle = themeToggle && lockedTheme === void 0;
|
|
584
589
|
return React4.createElement(
|
|
585
590
|
ThemeContext.Provider,
|
|
586
591
|
{ value: theme },
|
|
@@ -591,7 +596,7 @@ function ThemeScope(props) {
|
|
|
591
596
|
...elementProps,
|
|
592
597
|
...theme.attributes
|
|
593
598
|
},
|
|
594
|
-
|
|
599
|
+
showsToggle ? React4.createElement(
|
|
595
600
|
"div",
|
|
596
601
|
{
|
|
597
602
|
className: topbarClassName
|
|
@@ -3086,6 +3091,7 @@ function CheckoutView(props) {
|
|
|
3086
3091
|
pollIntervalMs,
|
|
3087
3092
|
paymentWizard = true,
|
|
3088
3093
|
themeToggle = true,
|
|
3094
|
+
theme: lockedTheme,
|
|
3089
3095
|
defaultTheme,
|
|
3090
3096
|
storageKey,
|
|
3091
3097
|
components,
|
|
@@ -3111,9 +3117,11 @@ function CheckoutView(props) {
|
|
|
3111
3117
|
});
|
|
3112
3118
|
const theme = useTheme({
|
|
3113
3119
|
defaultTheme,
|
|
3114
|
-
storageKey
|
|
3120
|
+
storageKey,
|
|
3121
|
+
theme: lockedTheme
|
|
3115
3122
|
});
|
|
3116
|
-
const
|
|
3123
|
+
const stampsTheme = !theme.fromScope;
|
|
3124
|
+
const ownsTheme = themeToggle && !theme.fromScope && lockedTheme === void 0;
|
|
3117
3125
|
const [swapFocused, setSwapFocused] = React10.useState(false);
|
|
3118
3126
|
const QRCodeComponent = components?.QRCode ?? QRCode;
|
|
3119
3127
|
const InvoiceSummaryComponent = components?.InvoiceSummary ?? InvoiceSummary;
|
|
@@ -3160,206 +3168,207 @@ function CheckoutView(props) {
|
|
|
3160
3168
|
className: joinClassNames(className, orClasses7.root, classNames?.root),
|
|
3161
3169
|
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.root]: "",
|
|
3162
3170
|
// Under ThemeScope, inherit data-theme from the page. Standalone Checkout owns it.
|
|
3163
|
-
...
|
|
3171
|
+
...stampsTheme ? theme.attributes : {}
|
|
3164
3172
|
},
|
|
3165
|
-
|
|
3166
|
-
//
|
|
3167
|
-
// the
|
|
3168
|
-
//
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
className: orClasses7.creating
|
|
3194
|
-
},
|
|
3195
|
-
React10.createElement("span", {
|
|
3196
|
-
className: orClasses7.spinner,
|
|
3197
|
-
"aria-hidden": "true"
|
|
3198
|
-
}),
|
|
3199
|
-
React10.createElement("p", null, checkoutLabels6.preparingPayment)
|
|
3200
|
-
) : null,
|
|
3201
|
-
hideLightning ? null : React10.createElement(
|
|
3202
|
-
"div",
|
|
3203
|
-
{
|
|
3204
|
-
key: "payment-layout",
|
|
3205
|
-
className: expired || settled ? orClasses7.paymentLayoutExpired : orClasses7.paymentLayout
|
|
3206
|
-
},
|
|
3207
|
-
lightningPane,
|
|
3208
|
-
React10.createElement(
|
|
3173
|
+
[
|
|
3174
|
+
// Order context from the host, composed ABOVE the shipped payment UI —
|
|
3175
|
+
// the same position as the custom element's `order` slot. Children never
|
|
3176
|
+
// replace the payment UI; a host that wants its own checkout builds on
|
|
3177
|
+
// useCheckout / @openreceive/browser/headless instead.
|
|
3178
|
+
customChildren === void 0 ? null : React10.createElement(React10.Fragment, { key: "order-children" }, customChildren),
|
|
3179
|
+
...[
|
|
3180
|
+
// Above the amount and OUTSIDE the Lightning pane, which drops out on
|
|
3181
|
+
// the swap deposit panel, on expiry and on the receipt — the payer
|
|
3182
|
+
// needs to know what they are buying on all four screens.
|
|
3183
|
+
checkoutModel.checkout.description === void 0 || checkoutModel.checkout.description === "" ? null : React10.createElement(
|
|
3184
|
+
"p",
|
|
3185
|
+
{
|
|
3186
|
+
key: "order-description",
|
|
3187
|
+
className: joinClassNames(orClasses7.orderDescription, classNames?.orderDescription),
|
|
3188
|
+
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.orderDescription]: ""
|
|
3189
|
+
},
|
|
3190
|
+
checkoutModel.checkout.description
|
|
3191
|
+
),
|
|
3192
|
+
ownsTheme ? React10.createElement(ThemeToggle, {
|
|
3193
|
+
key: "theme",
|
|
3194
|
+
className: classNames?.themeToggle,
|
|
3195
|
+
theme: theme.theme,
|
|
3196
|
+
resolvedTheme: theme.resolvedTheme,
|
|
3197
|
+
onThemeChange: theme.setTheme,
|
|
3198
|
+
ButtonComponent
|
|
3199
|
+
}) : null,
|
|
3200
|
+
mintingLightning ? React10.createElement(
|
|
3209
3201
|
"div",
|
|
3210
3202
|
{
|
|
3211
|
-
key: "
|
|
3212
|
-
className: orClasses7.
|
|
3203
|
+
key: "minting-lightning",
|
|
3204
|
+
className: orClasses7.creating
|
|
3213
3205
|
},
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
key: "invoice-title",
|
|
3218
|
-
className: joinClassNames(
|
|
3219
|
-
orClasses7.invoiceTitle,
|
|
3220
|
-
classNames?.invoiceTitle
|
|
3221
|
-
)
|
|
3222
|
-
},
|
|
3223
|
-
checkoutLabels6.bitcoinLightningInvoice
|
|
3224
|
-
),
|
|
3225
|
-
React10.createElement(WaitingState, {
|
|
3226
|
-
key: "waiting",
|
|
3227
|
-
waiting: checkoutModel.waiting,
|
|
3228
|
-
statusTitle: checkoutModel.statusTitle,
|
|
3229
|
-
statusDetail: checkoutModel.statusDetail,
|
|
3230
|
-
settled,
|
|
3231
|
-
className: classNames?.waiting
|
|
3206
|
+
React10.createElement("span", {
|
|
3207
|
+
className: orClasses7.spinner,
|
|
3208
|
+
"aria-hidden": "true"
|
|
3232
3209
|
}),
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
{ className: orClasses7.countdownStrong },
|
|
3244
|
-
checkoutModel.countdownLabel
|
|
3245
|
-
)
|
|
3246
|
-
),
|
|
3247
|
-
showSummaryMeta ? React10.createElement(InvoiceSummaryComponent, {
|
|
3248
|
-
key: "summary",
|
|
3249
|
-
status: checkoutModel.status,
|
|
3250
|
-
PaymentStateComponent,
|
|
3251
|
-
className: classNames?.summary,
|
|
3252
|
-
classNames
|
|
3253
|
-
}) : null,
|
|
3254
|
-
settled ? React10.createElement(TransactionDetails, {
|
|
3255
|
-
key: "transaction-details",
|
|
3256
|
-
// The model IS the checkout state, so the panel reads
|
|
3257
|
-
// the same derivation the rest of the screen does. It
|
|
3258
|
-
// used to re-flatten the snapshot separately, which
|
|
3259
|
-
// reported the displayed ATTEMPT's transaction /
|
|
3260
|
-
// workflow state on a checkout the state already knows
|
|
3261
|
-
// is paid.
|
|
3262
|
-
//
|
|
3263
|
-
// The SAME panel the swap flow renders one screen
|
|
3264
|
-
// earlier. A payer's whole evidence that they paid is a
|
|
3265
|
-
// payment hash and, on a swap, a deposit txid — so the
|
|
3266
|
-
// most keep-worthy screen gets copy buttons and
|
|
3267
|
-
// explorer links, not un-copyable text. No
|
|
3268
|
-
// `decodeLinkUrl` is passed, so the bolt11 never
|
|
3269
|
-
// reaches a third party.
|
|
3270
|
-
state: checkoutModel,
|
|
3271
|
-
className: classNames?.details,
|
|
3272
|
-
onError
|
|
3273
|
-
}) : expired ? React10.createElement(
|
|
3210
|
+
React10.createElement("p", null, checkoutLabels6.preparingPayment)
|
|
3211
|
+
) : null,
|
|
3212
|
+
hideLightning ? null : React10.createElement(
|
|
3213
|
+
"div",
|
|
3214
|
+
{
|
|
3215
|
+
key: "payment-layout",
|
|
3216
|
+
className: expired || settled ? orClasses7.paymentLayoutExpired : orClasses7.paymentLayout
|
|
3217
|
+
},
|
|
3218
|
+
lightningPane,
|
|
3219
|
+
React10.createElement(
|
|
3274
3220
|
"div",
|
|
3275
3221
|
{
|
|
3276
|
-
key: "
|
|
3277
|
-
className:
|
|
3278
|
-
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.actions]: ""
|
|
3222
|
+
key: "payment-info",
|
|
3223
|
+
className: orClasses7.paymentInfo
|
|
3279
3224
|
},
|
|
3280
|
-
React10.createElement(
|
|
3281
|
-
|
|
3225
|
+
expired || settled ? null : React10.createElement(
|
|
3226
|
+
"p",
|
|
3282
3227
|
{
|
|
3283
|
-
|
|
3284
|
-
className: orClasses7.
|
|
3285
|
-
onClick: startOver
|
|
3228
|
+
key: "invoice-title",
|
|
3229
|
+
className: joinClassNames(orClasses7.invoiceTitle, classNames?.invoiceTitle)
|
|
3286
3230
|
},
|
|
3287
|
-
checkoutLabels6.
|
|
3288
|
-
)
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
React10.createElement(CopyButton, {
|
|
3297
|
-
key: "copy-invoice",
|
|
3298
|
-
invoice: checkoutModel.invoice,
|
|
3299
|
-
copyInvoice: checkoutModel.copyInvoice,
|
|
3300
|
-
onError,
|
|
3301
|
-
logger,
|
|
3302
|
-
ButtonComponent,
|
|
3303
|
-
className: classNames?.copyButton
|
|
3304
|
-
}),
|
|
3305
|
-
// Opt-in slot: the default checkout ships no wallet button, so a
|
|
3306
|
-
// desktop payer is never sent to a handler that does not exist.
|
|
3307
|
-
OpenWalletButtonComponent === void 0 ? null : React10.createElement(OpenWalletButtonComponent, {
|
|
3308
|
-
key: "open-wallet",
|
|
3309
|
-
invoice: checkoutModel.invoice,
|
|
3310
|
-
openWallet: checkoutModel.openWallet,
|
|
3311
|
-
onError,
|
|
3312
|
-
logger,
|
|
3313
|
-
ButtonComponent,
|
|
3314
|
-
className: classNames?.openWalletButton
|
|
3231
|
+
checkoutLabels6.bitcoinLightningInvoice
|
|
3232
|
+
),
|
|
3233
|
+
React10.createElement(WaitingState, {
|
|
3234
|
+
key: "waiting",
|
|
3235
|
+
waiting: checkoutModel.waiting,
|
|
3236
|
+
statusTitle: checkoutModel.statusTitle,
|
|
3237
|
+
statusDetail: checkoutModel.statusDetail,
|
|
3238
|
+
settled,
|
|
3239
|
+
className: classNames?.waiting
|
|
3315
3240
|
}),
|
|
3316
|
-
|
|
3317
|
-
"
|
|
3241
|
+
checkoutModel.countdownLabel === void 0 ? null : React10.createElement(
|
|
3242
|
+
"div",
|
|
3243
|
+
{
|
|
3244
|
+
key: "countdown",
|
|
3245
|
+
className: joinClassNames(orClasses7.countdown, classNames?.countdown)
|
|
3246
|
+
},
|
|
3247
|
+
checkoutModel.countdownPrefix,
|
|
3248
|
+
" ",
|
|
3249
|
+
React10.createElement(
|
|
3250
|
+
"strong",
|
|
3251
|
+
{ className: orClasses7.countdownStrong },
|
|
3252
|
+
checkoutModel.countdownLabel
|
|
3253
|
+
)
|
|
3254
|
+
),
|
|
3255
|
+
showSummaryMeta ? React10.createElement(InvoiceSummaryComponent, {
|
|
3256
|
+
key: "summary",
|
|
3257
|
+
status: checkoutModel.status,
|
|
3258
|
+
PaymentStateComponent,
|
|
3259
|
+
className: classNames?.summary,
|
|
3260
|
+
classNames
|
|
3261
|
+
}) : null,
|
|
3262
|
+
settled ? React10.createElement(TransactionDetails, {
|
|
3263
|
+
key: "transaction-details",
|
|
3264
|
+
// The model IS the checkout state, so the panel reads
|
|
3265
|
+
// the same derivation the rest of the screen does. It
|
|
3266
|
+
// used to re-flatten the snapshot separately, which
|
|
3267
|
+
// reported the displayed ATTEMPT's transaction /
|
|
3268
|
+
// workflow state on a checkout the state already knows
|
|
3269
|
+
// is paid.
|
|
3270
|
+
//
|
|
3271
|
+
// The SAME panel the swap flow renders one screen
|
|
3272
|
+
// earlier. A payer's whole evidence that they paid is a
|
|
3273
|
+
// payment hash and, on a swap, a deposit txid — so the
|
|
3274
|
+
// most keep-worthy screen gets copy buttons and
|
|
3275
|
+
// explorer links, not un-copyable text. No
|
|
3276
|
+
// `decodeLinkUrl` is passed, so the bolt11 never
|
|
3277
|
+
// reaches a third party.
|
|
3278
|
+
state: checkoutModel,
|
|
3279
|
+
className: classNames?.details,
|
|
3280
|
+
onError
|
|
3281
|
+
}) : expired ? React10.createElement(
|
|
3282
|
+
"div",
|
|
3318
3283
|
{
|
|
3319
|
-
key: "
|
|
3320
|
-
className: orClasses7.
|
|
3321
|
-
|
|
3322
|
-
rel: "noreferrer",
|
|
3323
|
-
target: "_blank"
|
|
3284
|
+
key: "expired-actions",
|
|
3285
|
+
className: joinClassNames(orClasses7.actions, classNames?.actions),
|
|
3286
|
+
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.actions]: ""
|
|
3324
3287
|
},
|
|
3325
|
-
|
|
3288
|
+
React10.createElement(
|
|
3289
|
+
ButtonComponent ?? "button",
|
|
3290
|
+
{
|
|
3291
|
+
type: "button",
|
|
3292
|
+
className: orClasses7.btn,
|
|
3293
|
+
onClick: startOver
|
|
3294
|
+
},
|
|
3295
|
+
checkoutLabels6.startOver
|
|
3296
|
+
)
|
|
3297
|
+
) : React10.createElement(
|
|
3298
|
+
"div",
|
|
3299
|
+
{
|
|
3300
|
+
key: "actions",
|
|
3301
|
+
className: joinClassNames(orClasses7.actions, classNames?.actions),
|
|
3302
|
+
[OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES3.actions]: ""
|
|
3303
|
+
},
|
|
3304
|
+
React10.createElement(CopyButton, {
|
|
3305
|
+
key: "copy-invoice",
|
|
3306
|
+
invoice: checkoutModel.invoice,
|
|
3307
|
+
copyInvoice: checkoutModel.copyInvoice,
|
|
3308
|
+
onError,
|
|
3309
|
+
logger,
|
|
3310
|
+
ButtonComponent,
|
|
3311
|
+
className: classNames?.copyButton
|
|
3312
|
+
}),
|
|
3313
|
+
// Opt-in slot: the default checkout ships no wallet button, so a
|
|
3314
|
+
// desktop payer is never sent to a handler that does not exist.
|
|
3315
|
+
OpenWalletButtonComponent === void 0 ? null : React10.createElement(OpenWalletButtonComponent, {
|
|
3316
|
+
key: "open-wallet",
|
|
3317
|
+
invoice: checkoutModel.invoice,
|
|
3318
|
+
openWallet: checkoutModel.openWallet,
|
|
3319
|
+
onError,
|
|
3320
|
+
logger,
|
|
3321
|
+
ButtonComponent,
|
|
3322
|
+
className: classNames?.openWalletButton
|
|
3323
|
+
}),
|
|
3324
|
+
decodeInvoiceHref === void 0 ? null : React10.createElement(
|
|
3325
|
+
"a",
|
|
3326
|
+
{
|
|
3327
|
+
key: "decode-invoice",
|
|
3328
|
+
className: orClasses7.btn,
|
|
3329
|
+
href: decodeInvoiceHref,
|
|
3330
|
+
rel: "noreferrer",
|
|
3331
|
+
target: "_blank"
|
|
3332
|
+
},
|
|
3333
|
+
checkoutLabels6.decodeInvoice
|
|
3334
|
+
)
|
|
3326
3335
|
)
|
|
3327
3336
|
)
|
|
3328
|
-
)
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
]
|
|
3337
|
+
),
|
|
3338
|
+
paymentWizard && !settled && (!expired || swapFocused) ? React10.createElement(PaymentWizard, {
|
|
3339
|
+
key: "wizard",
|
|
3340
|
+
// Only pass invoice when it's a real bolt11 (non-empty, non-deferred).
|
|
3341
|
+
invoice: checkoutModel.invoice || void 0,
|
|
3342
|
+
checkout: checkoutModel.checkout,
|
|
3343
|
+
className: classNames?.wizard,
|
|
3344
|
+
logger,
|
|
3345
|
+
onError,
|
|
3346
|
+
onSwapFocusChange: setSwapFocused,
|
|
3347
|
+
prefix,
|
|
3348
|
+
qrEncoder,
|
|
3349
|
+
decodeLinkUrl,
|
|
3350
|
+
logContext: getCheckoutLogContext({
|
|
3351
|
+
invoice_id: checkoutModel.invoice_id,
|
|
3352
|
+
payment_hash: checkoutModel.payment_hash,
|
|
3353
|
+
amount_msats: checkoutModel.amount_msats
|
|
3354
|
+
}),
|
|
3355
|
+
onProviderCopy,
|
|
3356
|
+
onCopy,
|
|
3357
|
+
onRequestLightning,
|
|
3358
|
+
onSwapStarted,
|
|
3359
|
+
resolveAssetUrl,
|
|
3360
|
+
assetBaseUrl,
|
|
3361
|
+
// Whether a payer who closes the tab has a URL to come back
|
|
3362
|
+
// to. Explicit wins — only the host knows about a per-order
|
|
3363
|
+
// route of its own; otherwise infer it from the two props that
|
|
3364
|
+
// put the reference in the URL.
|
|
3365
|
+
resumable: resumable ?? (syncUrl === true || routeReference !== void 0),
|
|
3366
|
+
// The engine's staged refund address rides the controller this
|
|
3367
|
+
// model owns, so a poll cannot wipe a review in progress.
|
|
3368
|
+
swapRefund: checkoutModel
|
|
3369
|
+
}) : null
|
|
3370
|
+
]
|
|
3371
|
+
]
|
|
3363
3372
|
);
|
|
3364
3373
|
}
|
|
3365
3374
|
|