@openreceive/browser 0.4.10 → 0.4.12
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-FIAYCDZO.js → chunk-XDFN6BT3.js} +250 -219
- package/dist/headless.d.ts +22 -5
- package/dist/headless.js +70 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{status-Cnx1Vv-w.d.ts → status-Q1CJqaYo.d.ts} +3 -4
- package/package.json +3 -3
- package/skills/integrate-openreceive/SKILL.md +4 -3
- package/skills/integrate-openreceive/references/btcpay.md +67 -36
- package/skills/integrate-openreceive/references/django.md +291 -244
- package/skills/integrate-openreceive/references/fastapi.md +206 -155
- package/skills/integrate-openreceive/references/fastify.md +200 -147
- package/skills/integrate-openreceive/references/laravel.md +294 -234
- package/skills/integrate-openreceive/references/next.md +210 -162
- package/skills/integrate-openreceive/references/node.md +188 -138
- package/skills/integrate-openreceive/references/php.md +248 -193
- package/skills/integrate-openreceive/references/rails.md +262 -218
- package/skills/integrate-openreceive/references/woocommerce.md +68 -51
package/dist/headless.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AssetIndexEntry, PaymentWizardRoute } from '@openreceive/provider-data';
|
|
2
2
|
export { PaymentWizardRoute, PaymentWizardRouteRequest, getPaymentWizardRoutes, loadPayTutorialImages, payTutorialImage } from '@openreceive/provider-data';
|
|
3
|
-
import { P as PaymentIconId, a as ParseOpenReceiveOptionalIntegerOptions, b as PaymentMethod, R as ResolvedTheme, T as ThemePreference, c as PaymentMethodOption, d as TickingValueOptions, e as TickingValueController, f as TransientFeedbackOptions, g as TransientFeedbackController, C as CheckoutInvoiceSnapshot, U as UnixSeconds, S as SwapDisplayModel, h as CheckoutSnapshot, i as SwapDepositRisk, j as CheckoutState, k as TransactionDetailsInput, l as TransactionDetailRow, m as CreateCheckoutStateOptions, n as CheckoutStatusModelInput, o as CheckoutStatusModel, p as CheckoutPaymentMethod, B as BrowserLoggerOption, q as ThemeAttributeTarget, r as CheckoutElementAttributes, s as CheckoutElementAttributeOptions, t as CheckoutElementEventHandlers, u as CheckoutElementListeners, v as CreateCheckoutShellOptions, w as CheckoutShellElements, x as CheckoutShellOptions, y as CheckoutShellModel, z as CreateOpenReceiveThemeToggleElementOptions, A as ThemeToggleElementAttributeOptions, D as ThemeToggleElementAttributes, E as StoredThemeModelOptions, F as ThemeModel, G as ThemeModelOptions, H as ReadThemePreferenceOptions, I as ThemeControlTargets, J as ThemeStorageOptions, K as PaymentWizardControllerOptions, L as PaymentWizardController, M as PaymentWizardSelection, N as PaymentWizardModel, W as WizardRouteAssetDisplay, O as WizardRouteDisplay, Q as PaymentWizardSelectionAction } from './status-
|
|
4
|
-
export { V as BrowserLogContext, X as BrowserLogger, Y as BrowserRequestError, Z as CheckoutController, _ as CheckoutControllerOptions, $ as CheckoutPhase, a0 as CheckoutShellRootAttributes, a1 as CheckoutStatusRefresh, a2 as OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES, a3 as OPENRECEIVE_CHECKOUT_DATA_SELECTORS, a4 as OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES, a5 as OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS, a6 as OPENRECEIVE_CHECKOUT_ELEMENT_PARTS, a7 as OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS, a8 as OPENRECEIVE_CHECKOUT_ELEMENT_SLOTS, a9 as OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME, aa as OPENRECEIVE_COPY_FEEDBACK_MS, ab as OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS, ac as OPENRECEIVE_DEFAULT_PREFIX, ad as OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES, ae as OPENRECEIVE_PAYMENT_WIZARD_SELECTORS, af as OPENRECEIVE_PROVIDER_PREVIEW_LIMIT, ag as OPENRECEIVE_STYLE_ROOT_ATTRIBUTE, ah as OPENRECEIVE_STYLE_ROOT_SELECTOR, ai as OPENRECEIVE_THEME_STORAGE_KEY, aj as OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES, ak as OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS, al as OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS, am as OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS, an as OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME, ao as QrEncoder, ap as QrSvgController, aq as QrSvgControllerOptions, ar as Status, as as SwapCopyRow, at as SwapRefundStaging, au as WizardProviderDisplay, av as assertDisplayInvoice, aw as copyInvoice, ax as createCheckoutActionEvent, ay as createCheckoutController, az as createCheckoutErrorEvent, aA as createCheckoutProviderCopyEvent, aB as createCheckoutStateEvent, aC as createQrPayloadSvg, aD as createQrSvg, aE as createQrSvgController, aF as createStatusFetcher, aG as createThemeChangeEvent, aH as currentCheckoutUrl, aI as deriveCheckoutStateLabels, aJ as deriveStatus, aK as enterCheckoutResumePath, aL as escapeHtml, aM as formatAmountCaption, aN as formatDepositAmount, aO as formatFiatAmount, aP as formatMsats, aQ as formatSwapLimit, aR as formatUnixTime, aS as openWallet, aT as paymentIconSvgs, aU as prepareCheckout, aV as requestCheckout } from './status-
|
|
3
|
+
import { P as PaymentIconId, a as ParseOpenReceiveOptionalIntegerOptions, b as PaymentMethod, R as ResolvedTheme, T as ThemePreference, c as PaymentMethodOption, d as TickingValueOptions, e as TickingValueController, f as TransientFeedbackOptions, g as TransientFeedbackController, C as CheckoutInvoiceSnapshot, U as UnixSeconds, S as SwapDisplayModel, h as CheckoutSnapshot, i as SwapDepositRisk, j as CheckoutState, k as TransactionDetailsInput, l as TransactionDetailRow, m as CreateCheckoutStateOptions, n as CheckoutStatusModelInput, o as CheckoutStatusModel, p as CheckoutPaymentMethod, B as BrowserLoggerOption, q as ThemeAttributeTarget, r as CheckoutElementAttributes, s as CheckoutElementAttributeOptions, t as CheckoutElementEventHandlers, u as CheckoutElementListeners, v as CreateCheckoutShellOptions, w as CheckoutShellElements, x as CheckoutShellOptions, y as CheckoutShellModel, z as CreateOpenReceiveThemeToggleElementOptions, A as ThemeToggleElementAttributeOptions, D as ThemeToggleElementAttributes, E as StoredThemeModelOptions, F as ThemeModel, G as ThemeModelOptions, H as ReadThemePreferenceOptions, I as ThemeControlTargets, J as ThemeStorageOptions, K as PaymentWizardControllerOptions, L as PaymentWizardController, M as PaymentWizardSelection, N as PaymentWizardModel, W as WizardRouteAssetDisplay, O as WizardRouteDisplay, Q as PaymentWizardSelectionAction } from './status-Q1CJqaYo.js';
|
|
4
|
+
export { V as BrowserLogContext, X as BrowserLogger, Y as BrowserRequestError, Z as CheckoutController, _ as CheckoutControllerOptions, $ as CheckoutPhase, a0 as CheckoutShellRootAttributes, a1 as CheckoutStatusRefresh, a2 as OPENRECEIVE_CHECKOUT_DATA_ATTRIBUTES, a3 as OPENRECEIVE_CHECKOUT_DATA_SELECTORS, a4 as OPENRECEIVE_CHECKOUT_ELEMENT_ATTRIBUTES, a5 as OPENRECEIVE_CHECKOUT_ELEMENT_EVENTS, a6 as OPENRECEIVE_CHECKOUT_ELEMENT_PARTS, a7 as OPENRECEIVE_CHECKOUT_ELEMENT_PART_SELECTORS, a8 as OPENRECEIVE_CHECKOUT_ELEMENT_SLOTS, a9 as OPENRECEIVE_CHECKOUT_ELEMENT_TAG_NAME, aa as OPENRECEIVE_COPY_FEEDBACK_MS, ab as OPENRECEIVE_DEFAULT_POLL_INTERVAL_MS, ac as OPENRECEIVE_DEFAULT_PREFIX, ad as OPENRECEIVE_PAYMENT_WIZARD_ATTRIBUTES, ae as OPENRECEIVE_PAYMENT_WIZARD_SELECTORS, af as OPENRECEIVE_PROVIDER_PREVIEW_LIMIT, ag as OPENRECEIVE_STYLE_ROOT_ATTRIBUTE, ah as OPENRECEIVE_STYLE_ROOT_SELECTOR, ai as OPENRECEIVE_THEME_STORAGE_KEY, aj as OPENRECEIVE_THEME_TOGGLE_ELEMENT_ATTRIBUTES, ak as OPENRECEIVE_THEME_TOGGLE_ELEMENT_EVENTS, al as OPENRECEIVE_THEME_TOGGLE_ELEMENT_PARTS, am as OPENRECEIVE_THEME_TOGGLE_ELEMENT_PART_SELECTORS, an as OPENRECEIVE_THEME_TOGGLE_ELEMENT_TAG_NAME, ao as QrEncoder, ap as QrSvgController, aq as QrSvgControllerOptions, ar as Status, as as SwapCopyRow, at as SwapRefundStaging, au as WizardProviderDisplay, av as assertDisplayInvoice, aw as copyInvoice, ax as createCheckoutActionEvent, ay as createCheckoutController, az as createCheckoutErrorEvent, aA as createCheckoutProviderCopyEvent, aB as createCheckoutStateEvent, aC as createQrPayloadSvg, aD as createQrSvg, aE as createQrSvgController, aF as createStatusFetcher, aG as createThemeChangeEvent, aH as currentCheckoutUrl, aI as deriveCheckoutStateLabels, aJ as deriveStatus, aK as enterCheckoutResumePath, aL as escapeHtml, aM as formatAmountCaption, aN as formatDepositAmount, aO as formatFiatAmount, aP as formatMsats, aQ as formatSwapLimit, aR as formatUnixTime, aS as openWallet, aT as paymentIconSvgs, aU as prepareCheckout, aV as requestCheckout } from './status-Q1CJqaYo.js';
|
|
5
5
|
import '@openreceive/core';
|
|
6
6
|
|
|
7
7
|
/** Each packaged payment icon as a `data:image/svg+xml` URI, keyed by id. */
|
|
@@ -437,8 +437,14 @@ declare function createSwapDisplayModel(invoice: CheckoutInvoiceSnapshot, option
|
|
|
437
437
|
* renderers used to keep a near-identical copy of this; a headless UI holding
|
|
438
438
|
* its own snapshot store wants the same three rules.
|
|
439
439
|
*
|
|
440
|
-
* `dismissedInvoiceId` is the "back to Lightning"
|
|
441
|
-
*
|
|
440
|
+
* `dismissedInvoiceId` is the "back to Lightning" / "switch payment method"
|
|
441
|
+
* exit: while it is set, NO attempt is current until a new start or a refund
|
|
442
|
+
* clears it. The payer walked away from the swap they were looking at, and every
|
|
443
|
+
* older attempt in the snapshot is one they walked away from before that. The
|
|
444
|
+
* snapshot copy is the fallback only when nothing was dismissed (a resumed
|
|
445
|
+
* attempt this session never started). Falling back to "the first other swap"
|
|
446
|
+
* reopened the previous coin's deposit once an order had two attempts, and
|
|
447
|
+
* every further click re-dismissed the same one, so the exit stopped working.
|
|
442
448
|
*/
|
|
443
449
|
declare function selectCurrentSwapInvoice(snapshot: CheckoutSnapshot | undefined, options?: {
|
|
444
450
|
readonly started?: CheckoutInvoiceSnapshot | null;
|
|
@@ -747,13 +753,15 @@ interface CheckoutSessionOptions {
|
|
|
747
753
|
snapshot(): CheckoutSnapshot | undefined;
|
|
748
754
|
/** The order being paid, read at call time (the element's is an attribute). */
|
|
749
755
|
reference(): string | undefined;
|
|
756
|
+
/** Endpoint is part of checkout identity; trailing slashes are equivalent. */
|
|
757
|
+
prefix?(): string | undefined;
|
|
750
758
|
/**
|
|
751
759
|
* Mint a Lightning invoice for this reference (POST `${prefix}/checkouts`).
|
|
752
760
|
* The host closes over its own prefix, metadata and fetch. Answer `undefined`
|
|
753
761
|
* to say "this host cannot mint" — React's payment wizard is such a host: it
|
|
754
762
|
* asks its parent for Lightning through `onRequestLightning` instead.
|
|
755
763
|
*/
|
|
756
|
-
requestCheckout?(reference: string): Promise<CheckoutSnapshot> | undefined;
|
|
764
|
+
requestCheckout?(reference: string, signal?: AbortSignal): Promise<CheckoutSnapshot> | undefined;
|
|
757
765
|
/** Publish a snapshot that now carries the Lightning attempt. */
|
|
758
766
|
onSnapshot?(snapshot: CheckoutSnapshot): void;
|
|
759
767
|
/**
|
|
@@ -785,6 +793,14 @@ interface CheckoutSession {
|
|
|
785
793
|
* carries the accepted range the host renders in its unavailable panel.
|
|
786
794
|
*/
|
|
787
795
|
readonly swapQuotes: Readonly<Record<string, CheckoutPaymentMethod>>;
|
|
796
|
+
/** Invalidate every outstanding action when identity changes. */
|
|
797
|
+
syncIdentity(): void;
|
|
798
|
+
reset(): void;
|
|
799
|
+
dispose(): void;
|
|
800
|
+
capture(): {
|
|
801
|
+
readonly signal: AbortSignal;
|
|
802
|
+
isCurrent(): boolean;
|
|
803
|
+
};
|
|
788
804
|
ensureLightning(): Promise<void>;
|
|
789
805
|
/**
|
|
790
806
|
* Quote the pay-in asset, then start the swap when the quote confirms the
|
|
@@ -825,6 +841,7 @@ declare function createCheckoutShell(snapshot: CheckoutSnapshot, options?: Creat
|
|
|
825
841
|
* URL input — no call in this module takes a route of its own.
|
|
826
842
|
*/
|
|
827
843
|
interface SwapRequestOptions {
|
|
844
|
+
readonly signal?: AbortSignal;
|
|
828
845
|
readonly fetch: typeof globalThis.fetch;
|
|
829
846
|
readonly prefix: string;
|
|
830
847
|
readonly logger?: BrowserLoggerOption;
|
package/dist/headless.js
CHANGED
|
@@ -119,7 +119,7 @@ import {
|
|
|
119
119
|
swapOptionLimitSentence,
|
|
120
120
|
swapPickerKey,
|
|
121
121
|
updatePaymentWizardSelection
|
|
122
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-XDFN6BT3.js";
|
|
123
123
|
|
|
124
124
|
// src/headless.ts
|
|
125
125
|
import {
|
|
@@ -177,7 +177,43 @@ function createCheckoutSession(options) {
|
|
|
177
177
|
let mintingLightning = false;
|
|
178
178
|
let startingSwapAsset = null;
|
|
179
179
|
let swapQuotes = {};
|
|
180
|
+
let generation = 0;
|
|
181
|
+
let abort = new AbortController();
|
|
182
|
+
const identityKey = () => JSON.stringify([
|
|
183
|
+
options.reference(),
|
|
184
|
+
(options.prefix?.() ?? options.swap?.prefix() ?? "").replace(/\/+$/, "")
|
|
185
|
+
]);
|
|
186
|
+
let identity = identityKey();
|
|
187
|
+
function invalidateActions() {
|
|
188
|
+
abort.abort();
|
|
189
|
+
abort = new AbortController();
|
|
190
|
+
generation += 1;
|
|
191
|
+
mintingLightning = false;
|
|
192
|
+
startingSwapAsset = null;
|
|
193
|
+
}
|
|
194
|
+
function reset() {
|
|
195
|
+
invalidateActions();
|
|
196
|
+
identity = identityKey();
|
|
197
|
+
wizardError = void 0;
|
|
198
|
+
swapStartError = void 0;
|
|
199
|
+
lightningRequested = false;
|
|
200
|
+
mintingLightning = false;
|
|
201
|
+
startingSwapAsset = null;
|
|
202
|
+
swapQuotes = {};
|
|
203
|
+
}
|
|
204
|
+
function syncIdentity() {
|
|
205
|
+
if (identityKey() !== identity) reset();
|
|
206
|
+
}
|
|
207
|
+
function capture() {
|
|
208
|
+
syncIdentity();
|
|
209
|
+
const captured = generation;
|
|
210
|
+
return {
|
|
211
|
+
signal: abort.signal,
|
|
212
|
+
isCurrent: () => captured === generation && identityKey() === identity
|
|
213
|
+
};
|
|
214
|
+
}
|
|
180
215
|
async function ensureLightning() {
|
|
216
|
+
const action = capture();
|
|
181
217
|
if (mintingLightning) return;
|
|
182
218
|
const reference = options.reference();
|
|
183
219
|
if (reference === void 0 || reference.length === 0) return;
|
|
@@ -195,20 +231,25 @@ function createCheckoutSession(options) {
|
|
|
195
231
|
wizardError = void 0;
|
|
196
232
|
options.onChange();
|
|
197
233
|
try {
|
|
198
|
-
const pending = options.requestCheckout?.(reference);
|
|
234
|
+
const pending = options.requestCheckout?.(reference, action.signal);
|
|
199
235
|
if (pending === void 0) return;
|
|
200
236
|
const checkout = await pending;
|
|
237
|
+
if (!action.isCurrent()) return;
|
|
201
238
|
lightningRequested = true;
|
|
202
239
|
options.onSnapshot?.(mergeMintedCheckout(checkout, options.snapshot()));
|
|
203
240
|
} catch (error) {
|
|
241
|
+
if (!action.isCurrent()) return;
|
|
204
242
|
wizardError = payerFacingMessage(error, MINT_FAILED);
|
|
205
243
|
options.onError(error);
|
|
206
244
|
} finally {
|
|
207
|
-
|
|
208
|
-
|
|
245
|
+
if (action.isCurrent()) {
|
|
246
|
+
mintingLightning = false;
|
|
247
|
+
options.onChange();
|
|
248
|
+
}
|
|
209
249
|
}
|
|
210
250
|
}
|
|
211
251
|
async function startSwap(payInAsset) {
|
|
252
|
+
const action = capture();
|
|
212
253
|
if (startingSwapAsset !== null) return;
|
|
213
254
|
const swap = options.swap;
|
|
214
255
|
if (swap === void 0) {
|
|
@@ -239,9 +280,18 @@ function createCheckoutSession(options) {
|
|
|
239
280
|
swapStartError = void 0;
|
|
240
281
|
options.onChange();
|
|
241
282
|
try {
|
|
242
|
-
const quote = await quoteSwapAsset(
|
|
283
|
+
const quote = await quoteSwapAsset(
|
|
284
|
+
payInAsset,
|
|
285
|
+
prefix,
|
|
286
|
+
fetcher,
|
|
287
|
+
reference,
|
|
288
|
+
csrfHeader,
|
|
289
|
+
action
|
|
290
|
+
);
|
|
291
|
+
if (!action.isCurrent()) return;
|
|
243
292
|
if (quote !== void 0 && quote.available === false) return;
|
|
244
293
|
const started = await startSwapRequest({
|
|
294
|
+
signal: action.signal,
|
|
245
295
|
fetch: fetcher,
|
|
246
296
|
prefix,
|
|
247
297
|
...csrfHeader === void 0 ? {} : { csrfHeader },
|
|
@@ -249,12 +299,14 @@ function createCheckoutSession(options) {
|
|
|
249
299
|
payInAsset,
|
|
250
300
|
...options.logger === void 0 ? {} : { logger: options.logger }
|
|
251
301
|
});
|
|
302
|
+
if (!action.isCurrent()) return;
|
|
252
303
|
selection.setStarted(started);
|
|
253
304
|
selection.setDismissedInvoiceId(null);
|
|
254
305
|
swap.onStarted?.(started);
|
|
255
306
|
selection.setSelectedAsset(payInAsset);
|
|
256
307
|
options.onChange();
|
|
257
308
|
} catch (error) {
|
|
309
|
+
if (!action.isCurrent()) return;
|
|
258
310
|
const landed = selection.started();
|
|
259
311
|
if (landed?.swap?.pay_in_asset === payInAsset && landed.invoice_id !== selection.dismissedInvoiceId()) {
|
|
260
312
|
selection.setSelectedAsset(payInAsset);
|
|
@@ -264,17 +316,22 @@ function createCheckoutSession(options) {
|
|
|
264
316
|
selection.setSelectedAsset(payInAsset);
|
|
265
317
|
failSwapStart(error);
|
|
266
318
|
} finally {
|
|
267
|
-
|
|
319
|
+
if (action.isCurrent()) {
|
|
320
|
+
startingSwapAsset = null;
|
|
321
|
+
options.onChange();
|
|
322
|
+
}
|
|
268
323
|
}
|
|
269
324
|
}
|
|
270
|
-
async function quoteSwapAsset(payInAsset, prefix, fetcher, reference, csrfHeader) {
|
|
325
|
+
async function quoteSwapAsset(payInAsset, prefix, fetcher, reference, csrfHeader, action) {
|
|
271
326
|
const body = await postJson({
|
|
327
|
+
signal: action.signal,
|
|
272
328
|
fetch: fetcher,
|
|
273
329
|
prefix,
|
|
274
330
|
...csrfHeader === void 0 ? {} : { csrfHeader },
|
|
275
331
|
...options.logger === void 0 ? {} : { logger: options.logger },
|
|
276
332
|
body: { reference, action: "swap_quote", pay_in_asset: payInAsset }
|
|
277
333
|
});
|
|
334
|
+
if (!action.isCurrent()) return void 0;
|
|
278
335
|
const quote = normalizeSwapQuote(body);
|
|
279
336
|
if (quote === void 0) return void 0;
|
|
280
337
|
swapQuotes = { ...swapQuotes, [quote.pay_in_asset]: quote };
|
|
@@ -304,12 +361,17 @@ function createCheckoutSession(options) {
|
|
|
304
361
|
get swapQuotes() {
|
|
305
362
|
return swapQuotes;
|
|
306
363
|
},
|
|
364
|
+
syncIdentity,
|
|
365
|
+
reset,
|
|
366
|
+
dispose: reset,
|
|
367
|
+
capture,
|
|
307
368
|
ensureLightning,
|
|
308
369
|
startSwap,
|
|
309
370
|
resetLightningRequest() {
|
|
310
|
-
|
|
371
|
+
reset();
|
|
311
372
|
},
|
|
312
373
|
clearSwapStartError() {
|
|
374
|
+
invalidateActions();
|
|
313
375
|
swapStartError = void 0;
|
|
314
376
|
}
|
|
315
377
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { aW as BrowserLogLevel } from './status-
|
|
2
|
-
export { aX as BrowserLogEntry, X as BrowserLogger, B as BrowserLoggerOption, Y as BrowserRequestError, Z as CheckoutController, _ as CheckoutControllerOptions, h as CheckoutSnapshot, j as CheckoutState, aY as CopyInvoiceOptions, aZ as GuestCheckoutResumeController, a_ as GuestCheckoutResumeOptions, a$ as OpenWalletOptions, b0 as PrepareCheckoutOptions, b1 as QrOptions, b2 as RequestCheckoutOptions, ar as Status, b3 as StatusInvoiceLike, U as UnixSeconds, aw as copyInvoice, ay as createCheckoutController, b4 as createGuestCheckoutResume, b5 as createGuestOrderFetcher, b6 as createLightningUri, b7 as createQrPngDataUrl, aD as createQrSvg, aJ as deriveStatus, aK as enterCheckoutResumePath, aS as openWallet, aU as prepareCheckout, aV as requestCheckout } from './status-
|
|
1
|
+
import { aW as BrowserLogLevel } from './status-Q1CJqaYo.js';
|
|
2
|
+
export { aX as BrowserLogEntry, X as BrowserLogger, B as BrowserLoggerOption, Y as BrowserRequestError, Z as CheckoutController, _ as CheckoutControllerOptions, h as CheckoutSnapshot, j as CheckoutState, aY as CopyInvoiceOptions, aZ as GuestCheckoutResumeController, a_ as GuestCheckoutResumeOptions, a$ as OpenWalletOptions, b0 as PrepareCheckoutOptions, b1 as QrOptions, b2 as RequestCheckoutOptions, ar as Status, b3 as StatusInvoiceLike, U as UnixSeconds, aw as copyInvoice, ay as createCheckoutController, b4 as createGuestCheckoutResume, b5 as createGuestOrderFetcher, b6 as createLightningUri, b7 as createQrPngDataUrl, aD as createQrSvg, aJ as deriveStatus, aK as enterCheckoutResumePath, aS as openWallet, aU as prepareCheckout, aV as requestCheckout } from './status-Q1CJqaYo.js';
|
|
3
3
|
import '@openreceive/provider-data';
|
|
4
4
|
import '@openreceive/core';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -506,9 +506,7 @@ interface SwapDisplayModel {
|
|
|
506
506
|
readonly networkWarningEmphasis: string;
|
|
507
507
|
/**
|
|
508
508
|
* Full plain-text network warning (accessible / non-HTML consumers). The
|
|
509
|
-
* lost-funds sentence is present only when `depositRisk` is not `pinned
|
|
510
|
-
* "pay with one method only" sentence is on every rail, because double-paying
|
|
511
|
-
* is reachable on all of them.
|
|
509
|
+
* lost-funds sentence is present only when `depositRisk` is not `pinned`.
|
|
512
510
|
*/
|
|
513
511
|
readonly networkWarning: string;
|
|
514
512
|
readonly depositAddress: string;
|
|
@@ -820,8 +818,9 @@ interface RequestCheckoutOptions extends RequestCheckoutBaseOptions {
|
|
|
820
818
|
* `prepareCheckout` posts only the order id — it locks the amount and lists
|
|
821
819
|
* payment methods without minting — so there is no memo or metadata to carry.
|
|
822
820
|
*/
|
|
823
|
-
type PrepareCheckoutOptions = Pick<RequestCheckoutBaseOptions, "prefix" | "reference" | "fetch" | "headers" | "csrfHeader">;
|
|
821
|
+
type PrepareCheckoutOptions = Pick<RequestCheckoutBaseOptions, "prefix" | "reference" | "fetch" | "headers" | "csrfHeader" | "signal">;
|
|
824
822
|
interface RequestCheckoutBaseOptions {
|
|
823
|
+
readonly signal?: AbortSignal;
|
|
825
824
|
/**
|
|
826
825
|
* Base path the shipped router is mounted at (e.g. `/openreceive`). The create and
|
|
827
826
|
* prepare routes are derived from it — see {@link checkoutRoutes}. It is required
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openreceive/browser",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.12",
|
|
4
4
|
"description": "Browser helpers and a headless UI engine for Bitcoin Lightning checkout and optional USDT, USDC, SOL and ETH swaps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bitcoin",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"./styles.css": "./dist/styles.css"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@openreceive/core": "0.4.
|
|
34
|
-
"@openreceive/provider-data": "0.4.
|
|
33
|
+
"@openreceive/core": "0.4.12",
|
|
34
|
+
"@openreceive/provider-data": "0.4.12",
|
|
35
35
|
"qrcode": "^1.5.4"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
@@ -34,9 +34,10 @@ code** (`NWC_URI`).
|
|
|
34
34
|
- BTCPay Server: [references/btcpay.md](references/btcpay.md) — a plugin,
|
|
35
35
|
configured in BTCPay's store UI or Greenfield API; no application code,
|
|
36
36
|
no npm packages, no gem. The rest of this file is about the library.
|
|
37
|
-
3. Follow its **Step 0** first:
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
3. Follow its **Step 0** first: before writing code or searching the machine,
|
|
38
|
+
ask the user for the receive-only NWC code (then the swap URI), one question
|
|
39
|
+
per message, and store each pasted code in the project's env file yourself.
|
|
40
|
+
Never print the value; never invent a placeholder.
|
|
40
41
|
|
|
41
42
|
Install, per adapter — Express: `npm install @openreceive/express @openreceive/react`;
|
|
42
43
|
Fastify: `npm install @openreceive/fastify @openreceive/react`; Next.js:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# OpenReceive agent directions (BTCPay Server)
|
|
2
2
|
|
|
3
|
-
These directions describe OpenReceive 0.4.
|
|
3
|
+
These directions describe OpenReceive 0.4.12.
|
|
4
4
|
|
|
5
5
|
Connect a BTCPay Server store to a receive-only NWC wallet with the OpenReceive
|
|
6
6
|
plugin, and optionally let payers pay BTCPay invoices with USDT, USDC, ETH or
|
|
@@ -35,10 +35,12 @@ refund path on the same checkout screen.
|
|
|
35
35
|
1. Confirm the BTCPay Server version is 2.4.4 or later (Server Settings →
|
|
36
36
|
About, or `GET /api/v1/server/info`). The plugin declares that minimum and
|
|
37
37
|
BTCPay refuses to load it below.
|
|
38
|
-
2. Check whether the plugin is installed (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
2. Check whether the plugin is installed (the Plugins menu — the plug icon in
|
|
39
|
+
the top-right corner — under Installed Plugins, or the store navigation
|
|
40
|
+
shows an "OpenReceive" entry). If not, install it from the BTCPay plugin
|
|
41
|
+
directory (the same Plugins menu → Plugin Directory, search "openreceive",
|
|
42
|
+
then Install and Restart now), as the quickstart says; do not invent an
|
|
43
|
+
installer command.
|
|
42
44
|
3. Check whether the store already has an OpenReceive connection:
|
|
43
45
|
`GET /api/v1/stores/{storeId}/openreceive/settings` returns
|
|
44
46
|
`lightningNodeIsOpenReceive`. If true, the wallet step is done — go to
|
|
@@ -119,6 +121,8 @@ enough; drop the `.md` for the same page a person would read.
|
|
|
119
121
|
Questions, or a problem with the plugin itself:
|
|
120
122
|
https://openreceive.org/contact
|
|
121
123
|
|
|
124
|
+
- https://openreceive.org/guides/payment-safety-upgrade.md — coordinated upgrades and reviewed repair of existing attempts
|
|
125
|
+
|
|
122
126
|
---
|
|
123
127
|
|
|
124
128
|
## The quickstart, in full
|
|
@@ -131,15 +135,15 @@ passes. The page it comes from is https://openreceive.org/guides/quickstart-btcp
|
|
|
131
135
|
Requires BTCPay Server ≥ 2.4.4.
|
|
132
136
|
|
|
133
137
|
The OpenReceive plugin makes a receive-only NWC wallet the Lightning node of a
|
|
134
|
-
BTCPay store. BTCPay
|
|
135
|
-
payments
|
|
136
|
-
BTCPay invoice with USDT, USDC, ETH or SOL through a Lightning Swap Connect
|
|
137
|
-
provider
|
|
138
|
+
BTCPay store. BTCPay creates every Lightning invoice in that wallet. It records
|
|
139
|
+
payments the same way it records any other payment. You can also let payers pay
|
|
140
|
+
a BTCPay invoice with USDT, USDC, ETH or SOL through a Lightning Swap Connect
|
|
141
|
+
provider. The swap pays into the same wallet. The store's internal node is
|
|
138
142
|
never used.
|
|
139
143
|
|
|
140
144
|
This is not the Node or Rails library. There are no hooks, no
|
|
141
|
-
`openreceive_payments` table and no OpenReceive HTTP routes
|
|
142
|
-
invoices, checkout, webhooks and Greenfield API
|
|
145
|
+
`openreceive_payments` table and no OpenReceive HTTP routes. BTCPay's own
|
|
146
|
+
invoices, checkout, webhooks and Greenfield API do that work.
|
|
143
147
|
|
|
144
148
|
### 1. Prerequisites
|
|
145
149
|
|
|
@@ -155,39 +159,66 @@ invoices, checkout, webhooks and Greenfield API are the host.
|
|
|
155
159
|
|
|
156
160
|
### 2. Install the plugin
|
|
157
161
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
Sign in as a **server administrator**. If someone else hosts your server, ask
|
|
163
|
+
them to install the plugin for you.
|
|
164
|
+
|
|
165
|
+
**1. Open the Plugins menu.** It is the plug icon in the top-right corner.
|
|
166
|
+
|
|
167
|
+
**2. Click Plugin Directory.**
|
|
168
|
+
|
|
169
|
+
**3. Search for `openreceive`** and click the **OpenReceive** result.
|
|
170
|
+
|
|
171
|
+
**4. Click Install in BTCPay Server.** Confirm when prompted, then click
|
|
172
|
+
**Restart now** and wait for BTCPay to come back.
|
|
173
|
+
|
|
174
|
+
At startup, BTCPay creates the plugin's two tables in its own Postgres
|
|
175
|
+
database: `openreceive_invoices` and `openreceive_swaps`, in the schema
|
|
176
|
+
`BTCPayServer.Plugins.OpenReceive`. Nothing else is created.
|
|
163
177
|
|
|
164
178
|
To build the plugin from source instead, follow
|
|
165
179
|
[the .NET workspace README](https://github.com/OpenReceive/openreceive/blob/master/packages/dotnet/README.md).
|
|
166
180
|
|
|
167
181
|
### 3. Connect the wallet
|
|
168
182
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
node.
|
|
183
|
+
1. Select your store and open **OpenReceive** in its sidebar, under Wallets.
|
|
184
|
+
2. Paste your receive-only NWC code. To see what the wallet supports first,
|
|
185
|
+
click **Test connection**.
|
|
186
|
+
3. Click **Save NWC Code**.
|
|
187
|
+
4. To turn swaps on, paste a Lightning Swap Connect code and click **Save swap
|
|
188
|
+
settings**.
|
|
176
189
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
190
|
+
The page then shows **Wallet connected**. If you set up a provider, it also
|
|
191
|
+
shows **Swaps on**. There is nothing else to configure. You never open BTCPay's
|
|
192
|
+
Lightning node screen, and the plugin never reads the internal node.
|
|
193
|
+
|
|
194
|
+
Screenshots for each of those steps, and for creating a first test invoice,
|
|
195
|
+
are in the plugin's
|
|
196
|
+
[README](https://github.com/OpenReceive/openreceive/blob/master/packages/dotnet/BTCPayServer.Plugins.OpenReceive/README.md).
|
|
197
|
+
|
|
198
|
+
The plugin refuses to save a code whose wallet advertises a spend method such
|
|
199
|
+
as `pay_invoice`. Create a receive-only code instead. If your wallet cannot
|
|
200
|
+
make one, there is an override, but using it is a deliberate choice and the
|
|
201
|
+
plugin logs it.
|
|
202
|
+
|
|
203
|
+
Turning swaps on raises the store's invoice expiration to 60 minutes if it is
|
|
204
|
+
shorter. A swap needs the invoice to stay open for at least 45 minutes.
|
|
182
205
|
|
|
183
206
|
### 4. Check it
|
|
184
207
|
|
|
185
|
-
**Run a health check** on the OpenReceive page runs every
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
208
|
+
Click **Run a health check** on the OpenReceive page. It runs every check
|
|
209
|
+
right there:
|
|
210
|
+
|
|
211
|
+
- the connection
|
|
212
|
+
- the wallet preflight
|
|
213
|
+
- payment notifications
|
|
214
|
+
- the last wallet scan
|
|
215
|
+
- the swap provider and its assets
|
|
216
|
+
- the invoice expiration
|
|
217
|
+
- swaps that need a human
|
|
218
|
+
|
|
219
|
+
Each failing check comes with a link to the fix.
|
|
189
220
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
`nostr+walletconnect://` string in BTCPay's Lightning node screen.
|
|
221
|
+
The [BTCPay plugin reference](https://openreceive.org/guides/btcpay-reference.md) lists every setting,
|
|
222
|
+
Greenfield route, swap state, log event and check. It also lists what the
|
|
223
|
+
plugin does not support by design: every send-side feature, top-up invoices,
|
|
224
|
+
and a bare `nostr+walletconnect://` string in BTCPay's Lightning node screen.
|