@openreceive/node 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.js CHANGED
@@ -1,8 +1,12 @@
1
1
  import {
2
+ HEX_64,
2
3
  OPENRECEIVE_SWAP_PAY_IN_ASSETS,
4
+ ReceiveCheckoutValidationError,
3
5
  TransientSwapCache,
6
+ WalletPreflightError,
4
7
  createLscSwapProvidersFromEnvironment,
5
8
  createNwcEndpointLogger,
9
+ createNwcReceiveClient,
6
10
  emitLog,
7
11
  fixedFloatCompatibleSwapProvider,
8
12
  fixedFloatProvider,
@@ -12,953 +16,10 @@ import {
12
16
  sanitizeEvent,
13
17
  summarizeSwapProviderApiRequest,
14
18
  summarizeSwapProviderApiResponse
15
- } from "./chunk-SDCOJGCF.js";
19
+ } from "./chunk-ZYS6QECW.js";
16
20
 
17
21
  // src/index.ts
18
- import { OpenReceiveError as OpenReceiveError4 } from "@openreceive/core";
19
-
20
- // src/alby-nwc.ts
21
- import {
22
- compact,
23
- formatSpendCapabilityRefusedMessage,
24
- formatSpendCapabilityWarningMessage,
25
- OpenReceiveError as OpenReceiveError2,
26
- parseNwcUri
27
- } from "@openreceive/core";
28
-
29
- // src/nwc/errors.ts
30
- import {
31
- isErrorCode,
32
- isRetryableErrorCode,
33
- OpenReceiveError
34
- } from "@openreceive/core";
35
- var WalletPreflightError = class extends Error {
36
- code;
37
- summary;
38
- constructor(code, message, summary) {
39
- super(message);
40
- this.name = "WalletPreflightError";
41
- this.code = code;
42
- this.summary = summary;
43
- }
44
- };
45
- var ReceiveCheckoutValidationError = class extends Error {
46
- constructor(message) {
47
- super(message);
48
- this.name = "ReceiveCheckoutValidationError";
49
- }
50
- };
51
- var NWC_ERROR_CODE_ALIASES = {
52
- ABORT_ERROR: "TIMEOUT",
53
- BAD_REQUEST: "INVALID_REQUEST",
54
- CONNECTION_ERROR: "WALLET_UNAVAILABLE",
55
- EXPIRED: "INVOICE_EXPIRED",
56
- FETCH_ERROR: "WALLET_UNAVAILABLE",
57
- FORBIDDEN: "RESTRICTED",
58
- INVOICE_NOT_FOUND: "NOT_FOUND",
59
- INVALID_PARAMETER: "INVALID_REQUEST",
60
- INVALID_PARAMETERS: "INVALID_REQUEST",
61
- INVALID_PARAMS: "INVALID_REQUEST",
62
- METHOD_NOT_FOUND: "UNSUPPORTED_METHOD",
63
- NETWORK_ERROR: "WALLET_UNAVAILABLE",
64
- NIP47_NETWORK_ERROR: "WALLET_UNAVAILABLE",
65
- NOSTR_NETWORK_ERROR: "WALLET_UNAVAILABLE",
66
- NOT_AUTHORIZED: "UNAUTHORIZED",
67
- NOT_SUPPORTED: "UNSUPPORTED_METHOD",
68
- NOTFOUND: "NOT_FOUND",
69
- PERMISSION_DENIED: "RESTRICTED",
70
- RELAY_CONNECTION_ERROR: "WALLET_UNAVAILABLE",
71
- REQUEST_TIMEOUT: "TIMEOUT",
72
- SERVICE_UNAVAILABLE: "WALLET_UNAVAILABLE",
73
- TIMED_OUT: "TIMEOUT",
74
- TIMEOUT_ERROR: "TIMEOUT",
75
- UNKNOWN_METHOD: "UNSUPPORTED_METHOD",
76
- UNSUPPORTED: "UNSUPPORTED_METHOD",
77
- UNSUPPORTED_ENCRYPTION_MODE: "UNSUPPORTED_ENCRYPTION",
78
- WALLET_OFFLINE: "WALLET_UNAVAILABLE",
79
- WALLET_UNREACHABLE: "WALLET_UNAVAILABLE"
80
- };
81
- var OPENRECEIVE_ERROR_MESSAGES = {
82
- NOT_IMPLEMENTED: "NWC wallet service does not implement this method.",
83
- RESTRICTED: "NWC wallet service restricted this request.",
84
- UNAUTHORIZED: "NWC wallet service rejected authorization.",
85
- FORBIDDEN: "The host application did not authorize this request.",
86
- RATE_LIMITED: "NWC wallet service rate limited this request.",
87
- QUOTA_EXCEEDED: "NWC wallet service quota was exceeded.",
88
- INTERNAL: "NWC wallet service returned an internal error.",
89
- UNSUPPORTED_ENCRYPTION: "NWC wallet service does not support the required encryption mode.",
90
- OTHER: "NWC wallet service returned an unknown error.",
91
- NOT_FOUND: "NWC wallet service could not find the requested resource.",
92
- TIMEOUT: "NWC wallet service request timed out.",
93
- INVALID_REQUEST: "OpenReceive sent an invalid NWC wallet request.",
94
- WALLET_UNAVAILABLE: "NWC wallet service is unavailable.",
95
- INVOICE_EXPIRED: "NWC wallet reported that the invoice is expired.",
96
- UNSUPPORTED_METHOD: "NWC wallet service does not support the requested method.",
97
- CONFLICT: "NWC wallet service reported a conflicting request."
98
- };
99
- function normalizeNwcWalletError(error) {
100
- if (error instanceof OpenReceiveError) return error;
101
- const records = collectErrorRecords(error);
102
- const code = knownErrorCode(error) ?? errorCodeFromRecords(records) ?? (typeof error === "string" ? normalizeNwcErrorCode(error) : void 0) ?? "OTHER";
103
- const message = errorMessageFromRecords(records, error, code);
104
- const retryable = firstBooleanField(records, ["retryable"]) ?? isRetryableErrorCode(code);
105
- const requestId = firstStringField(records, ["request_id", "requestId"]);
106
- const details = firstRecordField(records, ["details"]);
107
- const body = {
108
- code,
109
- message,
110
- retryable,
111
- ...requestId === void 0 ? {} : { request_id: requestId },
112
- ...details === void 0 ? {} : { details }
113
- };
114
- return new OpenReceiveError(body, { cause: error });
115
- }
116
- function knownErrorCode(error) {
117
- if (error instanceof ReceiveCheckoutValidationError) {
118
- return "INVALID_REQUEST";
119
- }
120
- if (error instanceof WalletPreflightError) {
121
- if (error.code === "missing_required_method") return "UNSUPPORTED_METHOD";
122
- if (error.code === "spend_capability_advertised") return "RESTRICTED";
123
- if (error.code === "unsupported_encryption") return "UNSUPPORTED_ENCRYPTION";
124
- return "WALLET_UNAVAILABLE";
125
- }
126
- return void 0;
127
- }
128
- function errorCodeFromRecords(records) {
129
- for (const record of records) {
130
- const directCode = normalizeNwcErrorCode(record.code) ?? normalizeNwcErrorCode(record.error_code) ?? normalizeNwcErrorCode(record.errorCode) ?? normalizeNwcErrorCode(record.type);
131
- if (directCode !== void 0 && directCode !== "OTHER") return directCode;
132
- const nameCode = normalizeNwcErrorCode(record.name);
133
- if (nameCode !== void 0 && nameCode !== "OTHER") return nameCode;
134
- if (directCode !== void 0) return directCode;
135
- }
136
- return void 0;
137
- }
138
- function normalizeNwcErrorCode(value) {
139
- if (typeof value !== "string" || value.trim().length === 0) return void 0;
140
- const normalized = normalizeNwcErrorCodeText(value);
141
- return NWC_ERROR_CODE_ALIASES[normalized] ?? (isErrorCode(normalized) ? normalized : void 0);
142
- }
143
- function normalizeNwcErrorCodeText(value) {
144
- return value.trim().replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
145
- }
146
- function errorMessageFromRecords(records, error, code) {
147
- const message = firstStringField(records, ["message", "description", "reason"]);
148
- if (message !== void 0 && normalizeNwcErrorCode(message) !== code) {
149
- return message;
150
- }
151
- if (typeof error === "string" && normalizeNwcErrorCode(error) === void 0) {
152
- const trimmed = error.trim();
153
- if (trimmed.length > 0) return trimmed;
154
- }
155
- return OPENRECEIVE_ERROR_MESSAGES[code];
156
- }
157
- function collectErrorRecords(value) {
158
- const records = [];
159
- collectErrorRecordsInto(value, records, /* @__PURE__ */ new Set());
160
- return records;
161
- }
162
- function collectErrorRecordsInto(value, records, seen) {
163
- if (typeof value !== "object" || value === null || seen.has(value)) return;
164
- seen.add(value);
165
- const record = value;
166
- records.push(record);
167
- for (const key of ["error", "result", "cause", "data"]) {
168
- collectErrorRecordsInto(record[key], records, seen);
169
- }
170
- }
171
- function firstStringField(records, fields) {
172
- for (const record of records) {
173
- for (const field of fields) {
174
- const value = record[field];
175
- if (typeof value === "string" && value.trim().length > 0) {
176
- return value;
177
- }
178
- }
179
- }
180
- return void 0;
181
- }
182
- function firstBooleanField(records, fields) {
183
- for (const record of records) {
184
- for (const field of fields) {
185
- const value = record[field];
186
- if (typeof value === "boolean") return value;
187
- }
188
- }
189
- return void 0;
190
- }
191
- function firstRecordField(records, fields) {
192
- for (const record of records) {
193
- for (const field of fields) {
194
- const value = record[field];
195
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
196
- return value;
197
- }
198
- }
199
- }
200
- return void 0;
201
- }
202
-
203
- // src/nwc/normalize.ts
204
- import {
205
- OPENRECEIVE_MAX_AMOUNT_MSATS,
206
- OPENRECEIVE_MIN_AMOUNT_MSATS,
207
- OPENRECEIVE_NWC_METADATA_MAX_BYTES,
208
- nonEmptyString,
209
- recordOrEmpty
210
- } from "@openreceive/core";
211
-
212
- // src/hex.ts
213
- var HEX_64 = /^[0-9a-fA-F]{64}$/;
214
-
215
- // src/nwc/normalize.ts
216
- var REQUIRED_RECEIVE_METHODS = ["make_invoice", "list_transactions"];
217
- var SPEND_METHODS = [
218
- "pay_invoice",
219
- "multi_pay_invoice",
220
- "pay_keysend",
221
- "multi_pay_keysend"
222
- ];
223
- function summarizeWalletCapabilities(connection, rawInfo, rawServiceInfo) {
224
- const unwrappedInfo = unwrapNwcResult(rawInfo);
225
- const info = recordOrEmpty(unwrappedInfo);
226
- const serviceInfo = rawServiceInfo === void 0 ? void 0 : recordOrEmpty(unwrapNwcResult(rawServiceInfo));
227
- const methods = normalizeStringList(
228
- info.methods ?? info.capabilities ?? info.supported_methods ?? info.supportedMethods ?? (typeof unwrappedInfo === "string" ? unwrappedInfo : void 0)
229
- ).map(normalizeNwcMethodName);
230
- const encryption = chooseEncryptionMode(
231
- normalizeStringList(
232
- serviceInfo?.encryption ?? serviceInfo?.encryptions ?? info.encryption ?? info.encryptions
233
- )
234
- );
235
- const spendMethods = spendMethodsIn(methods);
236
- const missingMethods = REQUIRED_RECEIVE_METHODS.filter((method) => !methods.includes(method));
237
- const warnings = spendMethods.map(
238
- (method) => `Wallet advertises spend method '${method}'; OpenReceive checkout will not expose it.`
239
- );
240
- return {
241
- walletPubkey: connection.walletPubkey,
242
- relays: [...connection.relays],
243
- methods,
244
- encryption,
245
- spendCapabilityAdvertised: spendMethods.length > 0,
246
- receiveCheckoutReady: missingMethods.length === 0,
247
- warnings
248
- };
249
- }
250
- function spendMethodsIn(methods) {
251
- return methods.filter(
252
- (method) => SPEND_METHODS.includes(method)
253
- );
254
- }
255
- function toNip47MakeInvoiceParams(request) {
256
- const params = {
257
- amount: toSafeNumber(request.amount_msats, "amount_msats")
258
- };
259
- if (request.description !== void 0) params.description = request.description;
260
- if (request.description_hash !== void 0) {
261
- params.description_hash = request.description_hash;
262
- }
263
- if (request.expiry !== void 0) params.expiry = request.expiry;
264
- if (request.metadata !== void 0) params.metadata = request.metadata;
265
- return params;
266
- }
267
- function toNip47ListTransactionsParams(request) {
268
- const params = {};
269
- if (request.from !== void 0) params.from = request.from;
270
- if (request.until !== void 0) params.until = request.until;
271
- if (request.limit !== void 0) params.limit = request.limit;
272
- if (request.offset !== void 0) params.offset = request.offset;
273
- if (request.unpaid !== void 0) params.unpaid = request.unpaid;
274
- if (request.type !== void 0) params.type = request.type;
275
- return params;
276
- }
277
- function validateMakeInvoiceRequest(request) {
278
- if (request.amount_msats < OPENRECEIVE_MIN_AMOUNT_MSATS) {
279
- throw new ReceiveCheckoutValidationError("amount_msats must be at least 1000");
280
- }
281
- if (request.amount_msats > OPENRECEIVE_MAX_AMOUNT_MSATS) {
282
- throw new ReceiveCheckoutValidationError("amount_msats exceeds JSON safe integer boundary");
283
- }
284
- if (request.description !== void 0 && request.description_hash !== void 0) {
285
- throw new ReceiveCheckoutValidationError(
286
- "At most one of description or description_hash may be present"
287
- );
288
- }
289
- if (request.description_hash !== void 0 && !HEX_64.test(request.description_hash)) {
290
- throw new ReceiveCheckoutValidationError("description_hash must be 64 hex characters");
291
- }
292
- if (request.metadata !== void 0) {
293
- const metadataBytes = byteLength(JSON.stringify(request.metadata));
294
- if (metadataBytes > OPENRECEIVE_NWC_METADATA_MAX_BYTES) {
295
- throw new ReceiveCheckoutValidationError(
296
- `metadata must serialize below ${OPENRECEIVE_NWC_METADATA_MAX_BYTES} bytes`
297
- );
298
- }
299
- }
300
- }
301
- function validateListTransactionsRequest(request) {
302
- validateOptionalNonNegativeInteger(request.from, "from");
303
- validateOptionalNonNegativeInteger(request.until, "until");
304
- validateOptionalNonNegativeInteger(request.offset, "offset");
305
- if (request.limit !== void 0 && (!Number.isSafeInteger(request.limit) || request.limit <= 0)) {
306
- throw new ReceiveCheckoutValidationError("limit must be a positive safe integer");
307
- }
308
- if (request.from !== void 0 && request.until !== void 0 && request.from > request.until) {
309
- throw new ReceiveCheckoutValidationError("from must be less than or equal to until");
310
- }
311
- if (request.type !== void 0 && request.type !== "incoming" && request.type !== "outgoing") {
312
- throw new ReceiveCheckoutValidationError("type must be incoming or outgoing");
313
- }
314
- }
315
- function validateOptionalNonNegativeInteger(value, field) {
316
- if (value === void 0) return;
317
- if (!Number.isSafeInteger(value) || value < 0) {
318
- throw new ReceiveCheckoutValidationError(`${field} must be a non-negative safe integer`);
319
- }
320
- }
321
- function normalizeMakeInvoiceResult(rawResult) {
322
- const result = recordOrEmpty(unwrapNwcResult(rawResult));
323
- const invoice = requiredString(result.invoice, "invoice");
324
- const paymentHash = requiredString(result.payment_hash ?? result.paymentHash, "payment_hash");
325
- if (!HEX_64.test(paymentHash)) {
326
- throw new TypeError("payment_hash must be 64 hex characters");
327
- }
328
- const amountMsats = toBigInt(result.amount_msats ?? result.amount, "amount_msats");
329
- const createdAt = parseOptionalInteger(result.created_at ?? result.createdAt, "created_at");
330
- const expiresAt = parseOptionalInteger(result.expires_at ?? result.expiresAt, "expires_at");
331
- return {
332
- invoice,
333
- payment_hash: paymentHash,
334
- amount_msats: amountMsats,
335
- ...createdAt === void 0 ? {} : { created_at: createdAt },
336
- ...expiresAt === void 0 ? {} : { expires_at: expiresAt }
337
- };
338
- }
339
- function normalizeListTransactionsResult(rawResult) {
340
- const unwrapped = unwrapNwcResult(rawResult);
341
- const result = recordOrEmpty(unwrapped);
342
- let rawTransactions;
343
- if (Array.isArray(result.transactions)) {
344
- rawTransactions = result.transactions;
345
- } else if (Array.isArray(unwrapped)) {
346
- rawTransactions = unwrapped;
347
- } else if ((unwrapped === void 0 || unwrapped === null || typeof unwrapped === "object") && Object.keys(result).length === 0) {
348
- rawTransactions = [];
349
- } else {
350
- throw new TypeError("list_transactions returned an unrecognized result shape");
351
- }
352
- const transactions = [];
353
- let skippedRows = 0;
354
- for (const rawTransaction of rawTransactions) {
355
- try {
356
- transactions.push(normalizeNwcTransaction(rawTransaction));
357
- } catch {
358
- skippedRows += 1;
359
- }
360
- }
361
- if (transactions.length === 0 && skippedRows > 0) {
362
- throw new TypeError("list_transactions returned no usable rows");
363
- }
364
- return { transactions, skippedRows };
365
- }
366
- function normalizeNwcTransaction(rawTransaction) {
367
- const result = recordOrEmpty(rawTransaction);
368
- const normalized = {};
369
- const type = normalizeTransactionType(result.type);
370
- if (type !== void 0) normalized.type = type;
371
- const invoice = nonEmptyString(result.invoice);
372
- if (invoice !== void 0) normalized.invoice = invoice;
373
- const paymentHash = nonEmptyString(result.payment_hash ?? result.paymentHash);
374
- if (paymentHash !== void 0) {
375
- if (!/^[0-9a-fA-F]{64}$/.test(paymentHash)) {
376
- throw new TypeError("payment_hash must be 64 hexadecimal characters");
377
- }
378
- normalized.payment_hash = paymentHash;
379
- }
380
- if (result.amount_msats !== void 0 || result.amount !== void 0) {
381
- normalized.amount_msats = toBigInt(result.amount_msats ?? result.amount, "amount_msats");
382
- }
383
- const transactionState = normalizeTransactionState(
384
- result.transaction_state ?? result.transactionState ?? result.state
385
- ) ?? (result.settled === true || result.paid === true ? "settled" : void 0);
386
- if (transactionState !== void 0) {
387
- normalized.transaction_state = transactionState;
388
- }
389
- const createdAt = optionalUnixSeconds(result.created_at ?? result.createdAt, "created_at");
390
- if (createdAt !== void 0) normalized.created_at = createdAt;
391
- const expiresAt = optionalUnixSeconds(result.expires_at ?? result.expiresAt, "expires_at");
392
- if (expiresAt !== void 0) normalized.expires_at = expiresAt;
393
- const settledAt = optionalUnixSeconds(result.settled_at ?? result.settledAt, "settled_at");
394
- if (settledAt !== void 0) normalized.settled_at = settledAt;
395
- const preimage = nonEmptyString(result.preimage);
396
- if (preimage !== void 0) normalized.preimage = preimage;
397
- const description = nonEmptyString(result.description);
398
- if (description !== void 0) normalized.description = description;
399
- const descriptionHash = nonEmptyString(result.description_hash ?? result.descriptionHash);
400
- if (descriptionHash !== void 0) normalized.description_hash = descriptionHash;
401
- if (result.fees_paid !== void 0 || result.feesPaid !== void 0) {
402
- normalized.fees_paid_msats = toBigInt(result.fees_paid ?? result.feesPaid, "fees_paid");
403
- }
404
- return normalized;
405
- }
406
- function normalizeNwcNotification(rawNotification) {
407
- const record = recordOrEmpty(rawNotification);
408
- const type = typeof record.notification_type === "string" ? record.notification_type : typeof record.notificationType === "string" ? record.notificationType : typeof record.type === "string" ? record.type : "unknown";
409
- const payload = recordOrEmpty(record.notification);
410
- let transaction;
411
- if (Object.keys(payload).length > 0) {
412
- try {
413
- transaction = normalizeNwcTransaction(payload);
414
- } catch {
415
- }
416
- }
417
- const rawHash = payload.payment_hash ?? payload.paymentHash ?? record.payment_hash ?? record.paymentHash;
418
- const paymentHash = typeof rawHash === "string" && rawHash.length > 0 ? rawHash : transaction?.payment_hash;
419
- return {
420
- type,
421
- ...paymentHash === void 0 ? {} : { payment_hash: paymentHash },
422
- ...transaction === void 0 ? {} : { transaction }
423
- };
424
- }
425
- function chooseEncryptionMode(encryptionModes) {
426
- const normalized = encryptionModes.map((mode) => mode.toLowerCase().replace(/[- ]/g, "_"));
427
- if (normalized.includes("nip44_v2") || normalized.includes("nip44") || normalized.includes("nip_44")) {
428
- return "nip44_v2";
429
- }
430
- if (normalized.length === 0 || normalized.includes("nip04") || normalized.includes("nip_04")) {
431
- return "nip04";
432
- }
433
- return void 0;
434
- }
435
- function normalizeStringList(value) {
436
- if (Array.isArray(value)) {
437
- return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
438
- }
439
- if (typeof value === "string") {
440
- return value.split(/[,\s]+/).map((item) => item.trim()).filter(Boolean);
441
- }
442
- return [];
443
- }
444
- function normalizeNwcMethodName(value) {
445
- return value.trim().replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[-\s]+/g, "_").toLowerCase();
446
- }
447
- function normalizeTransactionState(value) {
448
- if (typeof value !== "string") return void 0;
449
- const normalized = value.toLowerCase();
450
- if (normalized === "pending" || normalized === "settled" || normalized === "expired" || normalized === "failed" || normalized === "accepted") {
451
- return normalized;
452
- }
453
- return void 0;
454
- }
455
- function normalizeTransactionType(value) {
456
- if (typeof value !== "string") return void 0;
457
- const normalized = value.toLowerCase();
458
- if (normalized === "incoming" || normalized === "outgoing") return normalized;
459
- return void 0;
460
- }
461
- function parseOptionalInteger(value, fieldName) {
462
- if (value === void 0 || value === null) return void 0;
463
- if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
464
- throw new TypeError(`${fieldName} must be a non-negative safe integer`);
465
- }
466
- return value;
467
- }
468
- function optionalUnixSeconds(value, fieldName) {
469
- if (value === void 0 || value === null) return void 0;
470
- if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
471
- throw new TypeError(`${fieldName} must be a non-negative number of Unix seconds`);
472
- }
473
- return Math.floor(value);
474
- }
475
- function requiredString(value, fieldName) {
476
- if (typeof value !== "string" || value.length === 0) {
477
- throw new TypeError(`${fieldName} must be a non-empty string`);
478
- }
479
- return value;
480
- }
481
- function toBigInt(value, fieldName) {
482
- if (typeof value === "bigint") return value;
483
- if (typeof value === "number" && Number.isSafeInteger(value)) {
484
- return BigInt(value);
485
- }
486
- if (typeof value === "string" && /^[0-9]+$/.test(value)) {
487
- return BigInt(value);
488
- }
489
- throw new TypeError(`${fieldName} must be an integer`);
490
- }
491
- function toSafeNumber(value, fieldName) {
492
- if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
493
- throw new ReceiveCheckoutValidationError(`${fieldName} exceeds JSON safe integer boundary`);
494
- }
495
- return Number(value);
496
- }
497
- function byteLength(value) {
498
- return new TextEncoder().encode(value).length;
499
- }
500
- function unwrapNwcResult(value) {
501
- const record = recordOrEmpty(value);
502
- return record.result ?? value;
503
- }
504
-
505
- // src/nwc/transport.ts
506
- import { createRequire } from "module";
507
- import { pathToFileURL } from "url";
508
- import { recordOrEmpty as recordOrEmpty2 } from "@openreceive/core";
509
- var require2 = createRequire(import.meta.url);
510
- async function callRequiredMethod(client, names, request) {
511
- for (const name of names) {
512
- const method = client[name];
513
- if (typeof method === "function") {
514
- return await method.call(
515
- client,
516
- request
517
- );
518
- }
519
- }
520
- throw new WalletPreflightError(
521
- "wallet_unavailable",
522
- `NWC client does not expose ${names.join(" or ")}.`
523
- );
524
- }
525
- async function createDefaultAlbyNwcClient(connectionString) {
526
- ensureNodeWebSocket();
527
- const dynamicImport = new Function("specifier", "return import(specifier)");
528
- const namespace = recordOrEmpty2(
529
- await dynamicImport(pathToFileURL(require2.resolve("@getalby/sdk/nwc")).href)
530
- );
531
- const Constructor = namespace.NWCClient;
532
- if (typeof Constructor !== "function") {
533
- throw new WalletPreflightError(
534
- "wallet_unavailable",
535
- "@getalby/sdk/nwc did not expose NWCClient."
536
- );
537
- }
538
- const NWCClientConstructor = Constructor;
539
- return new NWCClientConstructor({
540
- nostrWalletConnectUrl: connectionString
541
- });
542
- }
543
- function ensureNodeWebSocket() {
544
- if (globalThis.WebSocket !== void 0) return;
545
- throw new WalletPreflightError(
546
- "wallet_unavailable",
547
- "OpenReceive requires Node 22 or newer with the built-in WebSocket API."
548
- );
549
- }
550
- async function closeNwcNotificationSubscription(subscription) {
551
- if (typeof subscription !== "function") {
552
- throw new TypeError("NWC subscribeNotifications must resolve to an unsubscribe function.");
553
- }
554
- await subscription();
555
- }
556
- function delay(milliseconds) {
557
- return new Promise((resolve) => {
558
- setTimeout(resolve, milliseconds);
559
- });
560
- }
561
-
562
- // src/alby-nwc.ts
563
- var AlbyNwcReceiveClient = class {
564
- /**
565
- * Safe, loggable view of the connection (wallet pubkey, relays, lud16, and
566
- * the secret-redacted URI). The parsed connection with the client secret is
567
- * deliberately private: `console.log(client)` or host error serialization
568
- * must never leak the secret.
569
- */
570
- connection;
571
- #connection;
572
- #connectionString;
573
- #client;
574
- #clientPromise;
575
- #clientFactory;
576
- #preflightSummary;
577
- #preflightPromise;
578
- #requirePreflight;
579
- #logger;
580
- #allowSpendCapableWallet;
581
- #spendCapabilityWarningDelayMs;
582
- #spendCapabilityWarning;
583
- #closed = false;
584
- constructor(options) {
585
- this.#connectionString = options.connectionString;
586
- this.#connection = parseNwcUri(options.connectionString);
587
- this.connection = {
588
- walletPubkey: this.#connection.walletPubkey,
589
- relays: [...this.#connection.relays],
590
- ...this.#connection.lud16 === void 0 ? {} : { lud16: this.#connection.lud16 },
591
- redacted: this.#connection.redacted
592
- };
593
- this.#client = options.client;
594
- this.#clientFactory = options.clientFactory;
595
- this.#requirePreflight = options.requirePreflight ?? true;
596
- this.#logger = options.logger;
597
- this.#allowSpendCapableWallet = options.allowSpendCapableWallet ?? false;
598
- this.#spendCapabilityWarningDelayMs = options.spendCapabilityWarningDelayMs ?? 0;
599
- this.#spendCapabilityWarning = options.spendCapabilityWarning ?? ((message) => {
600
- if (this.#logger === void 0) console.error(message);
601
- else this.#log("error", "nwc.spend_capability_warning", message);
602
- });
603
- }
604
- #log(level, event, message, fields = {}) {
605
- if (this.#logger === void 0) return;
606
- try {
607
- this.#logger({
608
- level,
609
- event,
610
- message,
611
- wallet_pubkey: this.connection.walletPubkey,
612
- ...fields
613
- });
614
- } catch {
615
- }
616
- }
617
- async preflight() {
618
- const client = await this.getClient();
619
- const hasGetInfo = typeof client.getInfo === "function" || typeof client.get_info === "function";
620
- const hasInfoEvent = typeof client.getWalletServiceInfo === "function";
621
- const rawInfo = hasGetInfo || !hasInfoEvent ? await this.#fetchWalletInfo(
622
- "get_info",
623
- () => callRequiredMethod(client, ["getInfo", "get_info"], {})
624
- ) : void 0;
625
- const rawServiceInfo = hasInfoEvent ? await this.#fetchWalletInfo(
626
- "info_event",
627
- () => client.getWalletServiceInfo()
628
- ) : void 0;
629
- if (rawInfo === void 0) {
630
- this.#log(
631
- "warn",
632
- "nwc.info_event.methods_fallback",
633
- "NWC client exposes no get_info; proving receive-only from the service-wide info event (kind 13194) rather than this connection's own method list."
634
- );
635
- }
636
- const summary = summarizeWalletCapabilities(
637
- this.#connection,
638
- rawInfo ?? rawServiceInfo,
639
- rawServiceInfo
640
- );
641
- this.#log("debug", "nwc.preflight.summarized", "NWC wallet capabilities summarized.", {
642
- methods_source: rawInfo === void 0 ? "info_event" : "get_info",
643
- methods: summary.methods,
644
- encryption: summary.encryption,
645
- receive_checkout_ready: summary.receiveCheckoutReady,
646
- spend_capability_advertised: summary.spendCapabilityAdvertised
647
- });
648
- if (!summary.receiveCheckoutReady) {
649
- throw new WalletPreflightError(
650
- "missing_required_method",
651
- "NWC wallet must advertise make_invoice and list_transactions for receive checkout.",
652
- summary
653
- );
654
- }
655
- if (summary.encryption !== "nip04" && summary.encryption !== "nip44_v2") {
656
- throw new WalletPreflightError(
657
- "unsupported_encryption",
658
- "NWC wallet must support NIP-04 or NIP-44 v2 encryption.",
659
- summary
660
- );
661
- }
662
- if (summary.spendCapabilityAdvertised) {
663
- const spendMethods = spendMethodsIn(summary.methods);
664
- if (!this.#allowSpendCapableWallet) {
665
- this.#log(
666
- "error",
667
- "nwc.spend_capability_advertised",
668
- "NWC connection advertises send-payment methods; refusing to boot without an explicit override.",
669
- { methods: spendMethods }
670
- );
671
- throw new WalletPreflightError(
672
- "spend_capability_advertised",
673
- formatSpendCapabilityRefusedMessage({ spendMethods }),
674
- summary
675
- );
676
- }
677
- const warning = formatSpendCapabilityWarningMessage({
678
- spendMethods
679
- });
680
- this.#log(
681
- "error",
682
- "nwc.spend_capability_advertised",
683
- "NWC connection advertises send-payment methods; continuing because the spend-capable override is set.",
684
- { methods: spendMethods }
685
- );
686
- try {
687
- this.#spendCapabilityWarning(warning);
688
- } catch {
689
- }
690
- if (this.#spendCapabilityWarningDelayMs > 0) {
691
- await delay(this.#spendCapabilityWarningDelayMs);
692
- }
693
- }
694
- this.#preflightSummary = summary;
695
- return summary;
696
- }
697
- async makeInvoice(request) {
698
- await this.ensurePreflight();
699
- validateMakeInvoiceRequest(request);
700
- this.#log(
701
- "debug",
702
- "nwc.make_invoice.requested",
703
- "Calling NWC wallet make_invoice.",
704
- compact({
705
- method: "make_invoice",
706
- // String form: msats above 2^53 would silently round through Number().
707
- amount_msats: request.amount_msats.toString(),
708
- expiry: request.expiry,
709
- has_description: request.description !== void 0,
710
- has_description_hash: request.description_hash !== void 0
711
- })
712
- );
713
- const startedAt = Date.now();
714
- let rawResult;
715
- try {
716
- rawResult = await callRequiredMethod(
717
- await this.getClient(),
718
- ["makeInvoice", "make_invoice"],
719
- toNip47MakeInvoiceParams(request)
720
- );
721
- } catch (error) {
722
- const normalized = normalizeNwcWalletError(error);
723
- this.#log("error", "nwc.make_invoice.failed", "NWC wallet make_invoice failed.", {
724
- method: "make_invoice",
725
- duration_ms: Date.now() - startedAt,
726
- error_code: normalized.code,
727
- error_message: normalized.message
728
- });
729
- throw normalized;
730
- }
731
- let result;
732
- try {
733
- result = normalizeMakeInvoiceResult(rawResult);
734
- } catch (error) {
735
- const normalized = normalizeNwcWalletError(error);
736
- this.#log("error", "nwc.make_invoice.failed", "NWC wallet make_invoice failed.", {
737
- method: "make_invoice",
738
- duration_ms: Date.now() - startedAt,
739
- error_code: normalized.code,
740
- error_message: normalized.message
741
- });
742
- throw normalized;
743
- }
744
- this.#log("debug", "nwc.make_invoice.completed", "NWC wallet make_invoice completed.", {
745
- method: "make_invoice",
746
- duration_ms: Date.now() - startedAt,
747
- payment_hash: result.payment_hash,
748
- amount_msats: result.amount_msats.toString()
749
- });
750
- return result;
751
- }
752
- async listTransactions(request) {
753
- await this.ensurePreflight();
754
- validateListTransactionsRequest(request);
755
- this.#log(
756
- "debug",
757
- "nwc.list_transactions.requested",
758
- "Calling NWC wallet list_transactions.",
759
- compact({
760
- method: "list_transactions",
761
- from: request.from,
762
- until: request.until,
763
- limit: request.limit,
764
- offset: request.offset,
765
- unpaid: request.unpaid,
766
- type: request.type
767
- })
768
- );
769
- const startedAt = Date.now();
770
- let rawResult;
771
- try {
772
- rawResult = await callRequiredMethod(
773
- await this.getClient(),
774
- ["listTransactions", "list_transactions"],
775
- toNip47ListTransactionsParams(request)
776
- );
777
- } catch (error) {
778
- const normalized = normalizeNwcWalletError(error);
779
- this.#log("error", "nwc.list_transactions.failed", "NWC wallet list_transactions failed.", {
780
- method: "list_transactions",
781
- duration_ms: Date.now() - startedAt,
782
- error_code: normalized.code,
783
- error_message: normalized.message
784
- });
785
- throw normalized;
786
- }
787
- let result;
788
- try {
789
- result = normalizeListTransactionsResult(rawResult);
790
- } catch (error) {
791
- const normalized = normalizeNwcWalletError(error);
792
- this.#log("error", "nwc.list_transactions.failed", "NWC wallet list_transactions failed.", {
793
- method: "list_transactions",
794
- duration_ms: Date.now() - startedAt,
795
- error_code: normalized.code,
796
- error_message: normalized.message
797
- });
798
- throw normalized;
799
- }
800
- if (result.skippedRows > 0) {
801
- this.#log(
802
- "warn",
803
- "nwc.list_transactions.rows_skipped",
804
- "Skipped wallet transaction rows that could not be normalized.",
805
- {
806
- method: "list_transactions",
807
- skipped_count: result.skippedRows
808
- }
809
- );
810
- }
811
- this.#log(
812
- "debug",
813
- "nwc.list_transactions.completed",
814
- "NWC wallet list_transactions completed.",
815
- {
816
- method: "list_transactions",
817
- duration_ms: Date.now() - startedAt,
818
- transaction_count: result.transactions.length
819
- }
820
- );
821
- return {
822
- transactions: result.transactions,
823
- ...result.skippedRows === 0 ? {} : { skippedRows: result.skippedRows }
824
- };
825
- }
826
- /**
827
- * Opt-in NWC-02 notification subscription, limited to `payment_received`.
828
- * Notifications are authenticated wallet data: the handler receives the
829
- * payload normalized like a `list_transactions` row so a payload satisfying
830
- * the settlement rule can settle its pending attempt directly, while
831
- * anything less only wakes reconciliation. Direct settlement assumes the
832
- * client binds notification decryption to the connection's wallet pubkey
833
- * (the bundled @getalby/sdk does). Resolves to an unsubscribe function.
834
- * Throws an OpenReceiveError with code `UNSUPPORTED_METHOD` when the
835
- * underlying wallet client does not support NWC notifications.
836
- */
837
- async subscribeNotifications(handler) {
838
- const client = await this.getClient();
839
- const subscribe = client.subscribeNotifications;
840
- if (typeof subscribe !== "function") {
841
- throw new OpenReceiveError2({
842
- code: "UNSUPPORTED_METHOD",
843
- message: "NWC wallet client does not support NWC notifications (subscribeNotifications). Keep polling reconciliation.",
844
- retryable: false
845
- });
846
- }
847
- this.#log(
848
- "debug",
849
- "nwc.notifications.subscribe.requested",
850
- "Subscribing to NWC-02 payment_received notifications.",
851
- { notification_types: ["payment_received"] }
852
- );
853
- let subscription;
854
- try {
855
- subscription = await subscribe.call(
856
- client,
857
- (rawNotification) => {
858
- const notification = normalizeNwcNotification(rawNotification);
859
- if (notification.type !== "payment_received") return;
860
- this.#log(
861
- "debug",
862
- "nwc.notifications.received",
863
- "NWC payment_received notification received.",
864
- compact({
865
- notification_type: notification.type,
866
- payment_hash: notification.payment_hash
867
- })
868
- );
869
- try {
870
- handler(notification);
871
- } catch {
872
- }
873
- },
874
- ["payment_received"]
875
- );
876
- } catch (error) {
877
- const normalized = normalizeNwcWalletError(error);
878
- this.#log(
879
- "error",
880
- "nwc.notifications.subscribe.failed",
881
- "NWC notification subscription failed.",
882
- { error_code: normalized.code, error_message: normalized.message }
883
- );
884
- throw normalized;
885
- }
886
- this.#log(
887
- "info",
888
- "nwc.notifications.subscribe.completed",
889
- "Subscribed to NWC-02 payment_received notifications; polling reconciliation remains the safety net."
890
- );
891
- return async () => {
892
- await closeNwcNotificationSubscription(subscription);
893
- this.#log(
894
- "info",
895
- "nwc.notifications.unsubscribed",
896
- "Unsubscribed from NWC-02 wallet notifications."
897
- );
898
- };
899
- }
900
- async #fetchWalletInfo(source, call) {
901
- const method = source === "get_info" ? "get_info" : "getWalletServiceInfo";
902
- const label = source === "get_info" ? "get_info" : "info event (kind 13194)";
903
- this.#log("debug", `nwc.${source}.requested`, `Fetching NWC wallet ${label}.`, { method });
904
- const startedAt = Date.now();
905
- try {
906
- const raw = await call();
907
- this.#log("debug", `nwc.${source}.completed`, `NWC wallet ${label} loaded.`, {
908
- method,
909
- duration_ms: Date.now() - startedAt
910
- });
911
- return raw;
912
- } catch (error) {
913
- const normalized = normalizeNwcWalletError(error);
914
- this.#log("error", `nwc.${source}.failed`, `NWC wallet ${label} fetch failed.`, {
915
- method,
916
- duration_ms: Date.now() - startedAt,
917
- error_code: normalized.code,
918
- error_message: normalized.message
919
- });
920
- throw normalized;
921
- }
922
- }
923
- async close() {
924
- if (this.#closed) return;
925
- this.#closed = true;
926
- const client = this.#client ?? await this.#clientPromise?.catch(() => void 0);
927
- this.#client = void 0;
928
- this.#clientPromise = void 0;
929
- await client?.close?.();
930
- }
931
- async ensurePreflight() {
932
- if (!this.#requirePreflight || this.#preflightSummary !== void 0) return;
933
- this.#preflightPromise ??= this.preflight();
934
- try {
935
- await this.#preflightPromise;
936
- } catch (error) {
937
- this.#preflightPromise = void 0;
938
- throw error;
939
- }
940
- }
941
- async getClient() {
942
- if (this.#closed) {
943
- throw new Error("OpenReceive NWC receive client is closed; create a new client.");
944
- }
945
- if (this.#client !== void 0) return this.#client;
946
- this.#clientPromise ??= (async () => {
947
- const client = this.#clientFactory !== void 0 ? await this.#clientFactory(this.#connection) : await createDefaultAlbyNwcClient(this.#connectionString);
948
- this.#client = client;
949
- return client;
950
- })();
951
- try {
952
- return await this.#clientPromise;
953
- } catch (error) {
954
- this.#clientPromise = void 0;
955
- throw error;
956
- }
957
- }
958
- };
959
- function createNwcReceiveClient(options) {
960
- return new AlbyNwcReceiveClient(options);
961
- }
22
+ import { OpenReceiveError as OpenReceiveError2 } from "@openreceive/core";
962
23
 
963
24
  // src/service.ts
964
25
  import {
@@ -966,8 +27,8 @@ import {
966
27
  formatMissingNwcMessage,
967
28
  NwcUriParseError,
968
29
  OPENRECEIVE_NWC_CODE_HELP_URL,
969
- OpenReceiveError as OpenReceiveError3,
970
- parseNwcUri as parseNwcUri2,
30
+ OpenReceiveError,
31
+ parseNwcUri,
971
32
  reconcilePaymentAttempts,
972
33
  unixSeconds
973
34
  } from "@openreceive/core";
@@ -990,10 +51,10 @@ var ConfigError = class extends Error {
990
51
  import { appendFileSync, existsSync, mkdirSync, renameSync, statSync, unlinkSync } from "fs";
991
52
  import { appendFile } from "fs/promises";
992
53
  import path from "path";
993
- import { compact as compact3 } from "@openreceive/core";
54
+ import { compact as compact2 } from "@openreceive/core";
994
55
 
995
56
  // src/console-logger.ts
996
- import { compact as compact2 } from "@openreceive/core";
57
+ import { compact } from "@openreceive/core";
997
58
 
998
59
  // src/log-level.ts
999
60
  var LOG_LEVEL_ORDER = {
@@ -1045,7 +106,7 @@ function createConsoleLogger(options = {}) {
1045
106
  event,
1046
107
  message
1047
108
  }),
1048
- compact2(fields)
109
+ compact(fields)
1049
110
  );
1050
111
  };
1051
112
  }
@@ -1066,7 +127,7 @@ function createAppConsoleLogger(options) {
1066
127
  event,
1067
128
  message
1068
129
  }),
1069
- compact2(fields)
130
+ compact(fields)
1070
131
  );
1071
132
  };
1072
133
  }
@@ -1214,7 +275,7 @@ function attachLogging(options) {
1214
275
  const fileLogger = createFileLoggerFromConfig(options.logging);
1215
276
  const consoleEnabled = options.logging?.console ?? options.logger === void 0;
1216
277
  const consoleLogger = consoleEnabled ? createConsoleLogger(
1217
- compact3({
278
+ compact2({
1218
279
  prefix: options.logging?.prefix ?? "openreceive",
1219
280
  minLevel: options.logging?.level
1220
281
  })
@@ -1224,10 +285,10 @@ function attachLogging(options) {
1224
285
  }
1225
286
 
1226
287
  // src/service/checkouts.ts
1227
- import { OPENRECEIVE_NWC_METADATA_MAX_BYTES as OPENRECEIVE_NWC_METADATA_MAX_BYTES2 } from "@openreceive/core";
288
+ import { OPENRECEIVE_NWC_METADATA_MAX_BYTES } from "@openreceive/core";
1228
289
 
1229
290
  // src/service/requests.ts
1230
- import { isBitcoinAmountCurrency, isRecord as isRecord2, nonEmptyString as nonEmptyString2 } from "@openreceive/core";
291
+ import { isBitcoinAmountCurrency, isRecord as isRecord2, nonEmptyString } from "@openreceive/core";
1231
292
 
1232
293
  // src/service/core-utils.ts
1233
294
  import { isRecord } from "@openreceive/core";
@@ -1290,14 +351,14 @@ function normalizeCreateCheckoutRequest(input) {
1290
351
  throw serviceError(400, "INVALID_REQUEST", `Unexpected create checkout field: ${key}.`);
1291
352
  }
1292
353
  }
1293
- const reference = nonEmptyString2(body.reference);
354
+ const reference = nonEmptyString(body.reference);
1294
355
  if (reference === void 0) throw serviceError(400, "INVALID_REQUEST", "reference is required.");
1295
356
  if (reference.length > 200) {
1296
357
  throw serviceError(400, "INVALID_REQUEST", "reference must be 200 characters or fewer.");
1297
358
  }
1298
359
  const amount = normalizeCreateCheckoutAmount(body.amount);
1299
- const memo = nonEmptyString2(body.memo);
1300
- const descriptionHash = nonEmptyString2(body.descriptionHash);
360
+ const memo = nonEmptyString(body.memo);
361
+ const descriptionHash = nonEmptyString(body.descriptionHash);
1301
362
  getCreateDescriptionFields({ memo, descriptionHash });
1302
363
  const metadata = parseOptionalRecord(body.metadata, "metadata");
1303
364
  const expirySeconds = body.expirySeconds;
@@ -1324,8 +385,8 @@ function normalizeCreateCheckoutAmount(value) {
1324
385
  if (keys.some((key) => key !== "currency" && key !== "value")) {
1325
386
  throw serviceError(400, "INVALID_REQUEST", "amount contains unsupported fields.");
1326
387
  }
1327
- const currency = nonEmptyString2(value.currency);
1328
- const amountValue = nonEmptyString2(value.value);
388
+ const currency = nonEmptyString(value.currency);
389
+ const amountValue = nonEmptyString(value.value);
1329
390
  if (currency === void 0 || amountValue === void 0) {
1330
391
  throw serviceError(400, "INVALID_REQUEST", "amount must be { sats } or { currency, value }.");
1331
392
  }
@@ -1347,8 +408,8 @@ function normalizeSatsValue(value) {
1347
408
  throw serviceError(400, "INVALID_REQUEST", "sats must be a positive integer.");
1348
409
  }
1349
410
  function getCreateDescriptionFields(input) {
1350
- const memo = nonEmptyString2(input.memo);
1351
- const descriptionHash = nonEmptyString2(input.descriptionHash);
411
+ const memo = nonEmptyString(input.memo);
412
+ const descriptionHash = nonEmptyString(input.descriptionHash);
1352
413
  if (memo !== void 0 && memo.length > 500) {
1353
414
  throw serviceError(400, "INVALID_REQUEST", "memo must be 500 characters or fewer.");
1354
415
  }
@@ -1371,7 +432,7 @@ import {
1371
432
  isResolvedPriceProvider,
1372
433
  OPENRECEIVE_PRICE_FEED_FALLBACK_URL_ENV,
1373
434
  OPENRECEIVE_PRICE_FEED_PRIMARY_URL_ENV,
1374
- nonEmptyString as nonEmptyString3,
435
+ nonEmptyString as nonEmptyString2,
1375
436
  quoteBitcoinAmountToMsats,
1376
437
  quoteFiatToMsatsWithPrice
1377
438
  } from "@openreceive/core";
@@ -1578,8 +639,8 @@ function parseFiatAmount(value) {
1578
639
  if (record === void 0) {
1579
640
  throw serviceError(400, "INVALID_REQUEST", "fiat must be a JSON object.");
1580
641
  }
1581
- const currency = nonEmptyString3(record.currency);
1582
- const amountValue = nonEmptyString3(record.value);
642
+ const currency = nonEmptyString2(record.currency);
643
+ const amountValue = nonEmptyString2(record.value);
1583
644
  if (currency === void 0 || !/^[A-Z]{3}$/.test(currency)) {
1584
645
  throw serviceError(400, "INVALID_REQUEST", "fiat.currency must be an ISO 4217 uppercase code");
1585
646
  }
@@ -1596,8 +657,8 @@ function parseBitcoinAmount(value) {
1596
657
  if (record === void 0) {
1597
658
  throw serviceError(400, "INVALID_REQUEST", "amount must be a JSON object.");
1598
659
  }
1599
- const currency = nonEmptyString3(record.currency);
1600
- const amountValue = nonEmptyString3(record.value);
660
+ const currency = nonEmptyString2(record.currency);
661
+ const amountValue = nonEmptyString2(record.value);
1601
662
  if (currency === void 0 || !["BTC", "SAT", "SATS"].includes(currency)) {
1602
663
  throw serviceError(
1603
664
  400,
@@ -1643,7 +704,7 @@ async function createCheckout(context, request) {
1643
704
  ...input.metadata ?? {},
1644
705
  reference: input.reference
1645
706
  };
1646
- if (Buffer.byteLength(JSON.stringify(metadata), "utf8") > OPENRECEIVE_NWC_METADATA_MAX_BYTES2) {
707
+ if (Buffer.byteLength(JSON.stringify(metadata), "utf8") > OPENRECEIVE_NWC_METADATA_MAX_BYTES) {
1647
708
  throw serviceError(400, "INVALID_REQUEST", "metadata is too large for NIP-47.");
1648
709
  }
1649
710
  const walletInvoice = await context.options.client.makeInvoice({
@@ -1791,7 +852,7 @@ var OPENRECEIVE_SWAP_STATES = {
1791
852
  };
1792
853
 
1793
854
  // src/swap/weight-budget.ts
1794
- import { compact as compact4 } from "@openreceive/core";
855
+ import { compact as compact3 } from "@openreceive/core";
1795
856
  var SWAP_PROVIDER_WEIGHT_WINDOW_SECONDS = 60;
1796
857
  var SWAP_PROVIDER_WEIGHT_SOFT_CAP = 200;
1797
858
  var SWAP_PROVIDER_CREATE_WEIGHT_GATE = 150;
@@ -1861,7 +922,7 @@ var SwapProviderWeightBudget = class {
1861
922
  #deny(path2, reason, cost, gate, message) {
1862
923
  throw weightBudgetError(
1863
924
  message,
1864
- compact4({
925
+ compact3({
1865
926
  provider: this.providerId,
1866
927
  path: path2,
1867
928
  reason,
@@ -2356,7 +1417,7 @@ async function createOpenReceive(supplied = {}) {
2356
1417
  subscribeWalletNotifications: async (handler) => {
2357
1418
  const subscribe = client.subscribeNotifications;
2358
1419
  if (typeof subscribe !== "function") {
2359
- throw new OpenReceiveError3({
1420
+ throw new OpenReceiveError({
2360
1421
  code: "UNSUPPORTED_METHOD",
2361
1422
  message: "NWC wallet client does not support NWC notifications (subscribeNotifications). Keep polling reconciliation.",
2362
1423
  retryable: false
@@ -2426,7 +1487,7 @@ function requireNwc(value, { subject }) {
2426
1487
  });
2427
1488
  }
2428
1489
  try {
2429
- parseNwcUri2(value.trim());
1490
+ parseNwcUri(value.trim());
2430
1491
  } catch (error) {
2431
1492
  const reason = error instanceof NwcUriParseError ? error.description : "Invalid NWC URI.";
2432
1493
  throw new ConfigError({
@@ -2474,7 +1535,7 @@ import {
2474
1535
  formatInvalidNwcMessage as formatInvalidNwcMessage2,
2475
1536
  formatMissingNwcMessage as formatMissingNwcMessage2,
2476
1537
  NwcUriParseError as NwcUriParseError2,
2477
- parseNwcUri as parseNwcUri3
1538
+ parseNwcUri as parseNwcUri2
2478
1539
  } from "@openreceive/core";
2479
1540
  function readNwcFromEnvironment(options = {}) {
2480
1541
  const subject = options.subject ?? "OpenReceive";
@@ -2483,7 +1544,7 @@ function readNwcFromEnvironment(options = {}) {
2483
1544
  throw new Error(formatMissingNwcMessage2({ subject }));
2484
1545
  }
2485
1546
  try {
2486
- parseNwcUri3(value);
1547
+ parseNwcUri2(value);
2487
1548
  } catch (error) {
2488
1549
  const reason = error instanceof NwcUriParseError2 ? error.description : "Invalid NWC URI.";
2489
1550
  throw new Error(formatInvalidNwcMessage2({ reason }));
@@ -2494,7 +1555,7 @@ export {
2494
1555
  ConfigError,
2495
1556
  OPENRECEIVE_SWAP_PAY_IN_ASSETS,
2496
1557
  OPENRECEIVE_SWAP_STATES,
2497
- OpenReceiveError4 as OpenReceiveError,
1558
+ OpenReceiveError2 as OpenReceiveError,
2498
1559
  ReceiveCheckoutValidationError,
2499
1560
  ServiceError,
2500
1561
  WalletPreflightError,