@t402/btc 2.7.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/README.md +120 -0
- package/dist/cjs/exact/client/index.d.ts +89 -0
- package/dist/cjs/exact/client/index.js +145 -0
- package/dist/cjs/exact/client/index.js.map +1 -0
- package/dist/cjs/exact/facilitator/index.d.ts +114 -0
- package/dist/cjs/exact/facilitator/index.js +218 -0
- package/dist/cjs/exact/facilitator/index.js.map +1 -0
- package/dist/cjs/exact/server/index.d.ts +101 -0
- package/dist/cjs/exact/server/index.js +161 -0
- package/dist/cjs/exact/server/index.js.map +1 -0
- package/dist/cjs/index.d.ts +179 -0
- package/dist/cjs/index.js +849 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/lightning/client/index.d.ts +82 -0
- package/dist/cjs/lightning/client/index.js +114 -0
- package/dist/cjs/lightning/client/index.js.map +1 -0
- package/dist/cjs/lightning/facilitator/index.d.ts +93 -0
- package/dist/cjs/lightning/facilitator/index.js +211 -0
- package/dist/cjs/lightning/facilitator/index.js.map +1 -0
- package/dist/cjs/lightning/server/index.d.ts +96 -0
- package/dist/cjs/lightning/server/index.js +157 -0
- package/dist/cjs/lightning/server/index.js.map +1 -0
- package/dist/cjs/signer-B_Z4WGLa.d.ts +64 -0
- package/dist/esm/chunk-2DEKJ7ER.mjs +123 -0
- package/dist/esm/chunk-2DEKJ7ER.mjs.map +1 -0
- package/dist/esm/chunk-3IOPLDQH.mjs +74 -0
- package/dist/esm/chunk-3IOPLDQH.mjs.map +1 -0
- package/dist/esm/chunk-7IU3Z36R.mjs +103 -0
- package/dist/esm/chunk-7IU3Z36R.mjs.map +1 -0
- package/dist/esm/chunk-HNFWDITA.mjs +170 -0
- package/dist/esm/chunk-HNFWDITA.mjs.map +1 -0
- package/dist/esm/chunk-MX3PAUPJ.mjs +65 -0
- package/dist/esm/chunk-MX3PAUPJ.mjs.map +1 -0
- package/dist/esm/chunk-YJYTK2QQ.mjs +127 -0
- package/dist/esm/chunk-YJYTK2QQ.mjs.map +1 -0
- package/dist/esm/chunk-YWZC2RR7.mjs +38 -0
- package/dist/esm/chunk-YWZC2RR7.mjs.map +1 -0
- package/dist/esm/chunk-ZOL5R3HZ.mjs +177 -0
- package/dist/esm/chunk-ZOL5R3HZ.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +89 -0
- package/dist/esm/exact/client/index.mjs +11 -0
- package/dist/esm/exact/client/index.mjs.map +1 -0
- package/dist/esm/exact/facilitator/index.d.mts +114 -0
- package/dist/esm/exact/facilitator/index.mjs +11 -0
- package/dist/esm/exact/facilitator/index.mjs.map +1 -0
- package/dist/esm/exact/server/index.d.mts +101 -0
- package/dist/esm/exact/server/index.mjs +10 -0
- package/dist/esm/exact/server/index.mjs.map +1 -0
- package/dist/esm/index.d.mts +179 -0
- package/dist/esm/index.mjs +77 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/lightning/client/index.d.mts +82 -0
- package/dist/esm/lightning/client/index.mjs +11 -0
- package/dist/esm/lightning/client/index.mjs.map +1 -0
- package/dist/esm/lightning/facilitator/index.d.mts +93 -0
- package/dist/esm/lightning/facilitator/index.mjs +11 -0
- package/dist/esm/lightning/facilitator/index.mjs.map +1 -0
- package/dist/esm/lightning/server/index.d.mts +96 -0
- package/dist/esm/lightning/server/index.mjs +10 -0
- package/dist/esm/lightning/server/index.mjs.map +1 -0
- package/dist/esm/signer-B_Z4WGLa.d.mts +64 -0
- package/package.json +142 -0
|
@@ -0,0 +1,849 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
21
|
+
|
|
22
|
+
// src/index.ts
|
|
23
|
+
var src_exports = {};
|
|
24
|
+
__export(src_exports, {
|
|
25
|
+
ALL_NETWORKS: () => ALL_NETWORKS,
|
|
26
|
+
BTC_MAINNET: () => BTC_MAINNET,
|
|
27
|
+
BTC_NETWORKS: () => BTC_NETWORKS,
|
|
28
|
+
BTC_TESTNET: () => BTC_TESTNET,
|
|
29
|
+
DEFAULT_VALIDITY_DURATION: () => DEFAULT_VALIDITY_DURATION,
|
|
30
|
+
DUST_LIMIT: () => DUST_LIMIT,
|
|
31
|
+
ExactBtcScheme: () => ExactBtcScheme,
|
|
32
|
+
LIGHTNING_MAINNET: () => LIGHTNING_MAINNET,
|
|
33
|
+
LIGHTNING_NETWORKS: () => LIGHTNING_NETWORKS,
|
|
34
|
+
LIGHTNING_TESTNET: () => LIGHTNING_TESTNET,
|
|
35
|
+
LightningScheme: () => LightningScheme,
|
|
36
|
+
MAINNET_ADDRESS_PREFIXES: () => MAINNET_ADDRESS_PREFIXES,
|
|
37
|
+
MIN_RELAY_FEE: () => MIN_RELAY_FEE,
|
|
38
|
+
SATS_PER_BTC: () => SATS_PER_BTC,
|
|
39
|
+
SCHEME_EXACT: () => SCHEME_EXACT,
|
|
40
|
+
TESTNET_ADDRESS_PREFIXES: () => TESTNET_ADDRESS_PREFIXES,
|
|
41
|
+
btcToSatoshis: () => btcToSatoshis,
|
|
42
|
+
isMainnetAddress: () => isMainnetAddress,
|
|
43
|
+
isTestnetAddress: () => isTestnetAddress,
|
|
44
|
+
isValidHex: () => isValidHex,
|
|
45
|
+
registerExactBtcClientScheme: () => registerExactBtcScheme,
|
|
46
|
+
registerExactBtcFacilitatorScheme: () => registerExactBtcScheme3,
|
|
47
|
+
registerExactBtcServerScheme: () => registerExactBtcScheme2,
|
|
48
|
+
registerLightningClientScheme: () => registerLightningScheme,
|
|
49
|
+
registerLightningFacilitatorScheme: () => registerLightningScheme3,
|
|
50
|
+
registerLightningServerScheme: () => registerLightningScheme2,
|
|
51
|
+
satoshisToBtc: () => satoshisToBtc,
|
|
52
|
+
validateBitcoinAddress: () => validateBitcoinAddress,
|
|
53
|
+
validateBolt11Invoice: () => validateBolt11Invoice
|
|
54
|
+
});
|
|
55
|
+
module.exports = __toCommonJS(src_exports);
|
|
56
|
+
|
|
57
|
+
// src/constants.ts
|
|
58
|
+
var BTC_MAINNET = "bip122:000000000019d6689c085ae165831e93";
|
|
59
|
+
var BTC_TESTNET = "bip122:000000000933ea01ad0ee984209779ba";
|
|
60
|
+
var LIGHTNING_MAINNET = "lightning:mainnet";
|
|
61
|
+
var LIGHTNING_TESTNET = "lightning:testnet";
|
|
62
|
+
var BTC_NETWORKS = [BTC_MAINNET, BTC_TESTNET];
|
|
63
|
+
var LIGHTNING_NETWORKS = [LIGHTNING_MAINNET, LIGHTNING_TESTNET];
|
|
64
|
+
var ALL_NETWORKS = [...BTC_NETWORKS, ...LIGHTNING_NETWORKS];
|
|
65
|
+
var DUST_LIMIT = 546;
|
|
66
|
+
var MIN_RELAY_FEE = 1e3;
|
|
67
|
+
var SATS_PER_BTC = 1e8;
|
|
68
|
+
var SCHEME_EXACT = "exact";
|
|
69
|
+
var DEFAULT_VALIDITY_DURATION = 3600;
|
|
70
|
+
var MAINNET_ADDRESS_PREFIXES = ["bc1", "1", "3"];
|
|
71
|
+
var TESTNET_ADDRESS_PREFIXES = ["tb1", "m", "n", "2"];
|
|
72
|
+
|
|
73
|
+
// src/utils.ts
|
|
74
|
+
function satoshisToBtc(sats) {
|
|
75
|
+
const satsBigInt = BigInt(sats);
|
|
76
|
+
const whole = satsBigInt / BigInt(SATS_PER_BTC);
|
|
77
|
+
const frac = satsBigInt % BigInt(SATS_PER_BTC);
|
|
78
|
+
if (frac === 0n) {
|
|
79
|
+
return whole.toString();
|
|
80
|
+
}
|
|
81
|
+
const fracStr = frac.toString().padStart(8, "0");
|
|
82
|
+
return `${whole}.${fracStr}`.replace(/\.?0+$/, "");
|
|
83
|
+
}
|
|
84
|
+
function btcToSatoshis(btc) {
|
|
85
|
+
const btcStr = typeof btc === "number" ? btc.toString() : btc;
|
|
86
|
+
const [wholePart, fracPart = ""] = btcStr.split(".");
|
|
87
|
+
const paddedFrac = fracPart.padEnd(8, "0").slice(0, 8);
|
|
88
|
+
const combined = wholePart + paddedFrac;
|
|
89
|
+
const result = BigInt(combined.replace(/^0+/, "") || "0");
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
function validateBitcoinAddress(address) {
|
|
93
|
+
if (!address || address.length < 14 || address.length > 90) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
const allPrefixes = [...MAINNET_ADDRESS_PREFIXES, ...TESTNET_ADDRESS_PREFIXES];
|
|
97
|
+
return allPrefixes.some((prefix) => address.startsWith(prefix));
|
|
98
|
+
}
|
|
99
|
+
function isMainnetAddress(address) {
|
|
100
|
+
return MAINNET_ADDRESS_PREFIXES.some((prefix) => address.startsWith(prefix));
|
|
101
|
+
}
|
|
102
|
+
function isTestnetAddress(address) {
|
|
103
|
+
return TESTNET_ADDRESS_PREFIXES.some((prefix) => address.startsWith(prefix));
|
|
104
|
+
}
|
|
105
|
+
function validateBolt11Invoice(invoice) {
|
|
106
|
+
if (!invoice || invoice.length < 20) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
const lower = invoice.toLowerCase();
|
|
110
|
+
return lower.startsWith("lnbc") || lower.startsWith("lntb") || lower.startsWith("lnbcrt");
|
|
111
|
+
}
|
|
112
|
+
function isValidHex(hex, expectedLength) {
|
|
113
|
+
if (!/^[0-9a-fA-F]+$/.test(hex)) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
if (expectedLength !== void 0 && hex.length !== expectedLength * 2) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/exact/client/scheme.ts
|
|
123
|
+
var ExactBtcScheme = class {
|
|
124
|
+
/**
|
|
125
|
+
* Creates a new ExactBtcScheme instance.
|
|
126
|
+
*
|
|
127
|
+
* @param signer - The Bitcoin signer for client operations
|
|
128
|
+
*/
|
|
129
|
+
constructor(signer) {
|
|
130
|
+
this.signer = signer;
|
|
131
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Creates a payment payload for the Exact scheme.
|
|
135
|
+
*
|
|
136
|
+
* The payload contains a signed PSBT with a single output
|
|
137
|
+
* paying the required amount to the payTo address.
|
|
138
|
+
*
|
|
139
|
+
* @param t402Version - The t402 protocol version
|
|
140
|
+
* @param paymentRequirements - The payment requirements
|
|
141
|
+
* @returns Promise resolving to a payment payload
|
|
142
|
+
*/
|
|
143
|
+
async createPaymentPayload(t402Version, paymentRequirements) {
|
|
144
|
+
if (!paymentRequirements.payTo) {
|
|
145
|
+
throw new Error("PayTo address is required");
|
|
146
|
+
}
|
|
147
|
+
if (!paymentRequirements.amount) {
|
|
148
|
+
throw new Error("Amount is required");
|
|
149
|
+
}
|
|
150
|
+
if (!validateBitcoinAddress(paymentRequirements.payTo)) {
|
|
151
|
+
throw new Error(`Invalid Bitcoin address: ${paymentRequirements.payTo}`);
|
|
152
|
+
}
|
|
153
|
+
const amountSats = BigInt(paymentRequirements.amount);
|
|
154
|
+
if (amountSats < BigInt(DUST_LIMIT)) {
|
|
155
|
+
throw new Error(`Amount ${amountSats} satoshis is below dust limit (${DUST_LIMIT})`);
|
|
156
|
+
}
|
|
157
|
+
const unsignedPsbt = this.buildUnsignedPsbt(paymentRequirements);
|
|
158
|
+
const signedPsbt = await this.signer.signPsbt(unsignedPsbt);
|
|
159
|
+
const payload = {
|
|
160
|
+
signedPsbt
|
|
161
|
+
};
|
|
162
|
+
return {
|
|
163
|
+
t402Version,
|
|
164
|
+
payload
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Build an unsigned PSBT for the payment.
|
|
169
|
+
*
|
|
170
|
+
* Creates a minimal PSBT representation with the required output.
|
|
171
|
+
* The actual UTXO selection and fee calculation should be handled
|
|
172
|
+
* by the signer implementation (which typically has wallet context).
|
|
173
|
+
*
|
|
174
|
+
* @param requirements - Payment requirements
|
|
175
|
+
* @returns Base64-encoded unsigned PSBT
|
|
176
|
+
*/
|
|
177
|
+
buildUnsignedPsbt(requirements) {
|
|
178
|
+
const psbtData = {
|
|
179
|
+
outputs: [
|
|
180
|
+
{
|
|
181
|
+
address: requirements.payTo,
|
|
182
|
+
value: requirements.amount
|
|
183
|
+
}
|
|
184
|
+
],
|
|
185
|
+
network: requirements.network,
|
|
186
|
+
fromAddress: this.signer.getAddress(),
|
|
187
|
+
fromPubKey: this.signer.getPublicKey()
|
|
188
|
+
};
|
|
189
|
+
return Buffer.from(JSON.stringify(psbtData)).toString("base64");
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// src/exact/client/register.ts
|
|
194
|
+
function registerExactBtcScheme(client, config) {
|
|
195
|
+
const scheme = new ExactBtcScheme(config.signer);
|
|
196
|
+
if (config.networks && config.networks.length > 0) {
|
|
197
|
+
config.networks.forEach((network) => {
|
|
198
|
+
client.register(network, scheme);
|
|
199
|
+
});
|
|
200
|
+
} else {
|
|
201
|
+
client.register("bip122:*", scheme);
|
|
202
|
+
}
|
|
203
|
+
if (config.policies) {
|
|
204
|
+
config.policies.forEach((policy) => {
|
|
205
|
+
client.registerPolicy(policy);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
return client;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/lightning/client/scheme.ts
|
|
212
|
+
var LightningScheme = class {
|
|
213
|
+
/**
|
|
214
|
+
* Creates a new LightningScheme instance.
|
|
215
|
+
*
|
|
216
|
+
* @param signer - The Lightning signer for client operations
|
|
217
|
+
*/
|
|
218
|
+
constructor(signer) {
|
|
219
|
+
this.signer = signer;
|
|
220
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Creates a payment payload for the Lightning scheme.
|
|
224
|
+
*
|
|
225
|
+
* 1. Extracts the BOLT11 invoice from requirements.extra.bolt11Invoice
|
|
226
|
+
* 2. Pays the invoice using the Lightning signer
|
|
227
|
+
* 3. Returns the preimage and payment hash as proof of payment
|
|
228
|
+
*
|
|
229
|
+
* @param t402Version - The t402 protocol version
|
|
230
|
+
* @param paymentRequirements - The payment requirements
|
|
231
|
+
* @returns Promise resolving to a payment payload
|
|
232
|
+
*/
|
|
233
|
+
async createPaymentPayload(t402Version, paymentRequirements) {
|
|
234
|
+
const bolt11Invoice = paymentRequirements.extra?.bolt11Invoice;
|
|
235
|
+
if (!bolt11Invoice) {
|
|
236
|
+
throw new Error("BOLT11 invoice is required in requirements.extra.bolt11Invoice");
|
|
237
|
+
}
|
|
238
|
+
if (!validateBolt11Invoice(bolt11Invoice)) {
|
|
239
|
+
throw new Error(`Invalid BOLT11 invoice format: ${bolt11Invoice.slice(0, 20)}...`);
|
|
240
|
+
}
|
|
241
|
+
const { preimage, paymentHash } = await this.signer.payInvoice(bolt11Invoice);
|
|
242
|
+
const payload = {
|
|
243
|
+
paymentHash,
|
|
244
|
+
preimage,
|
|
245
|
+
bolt11Invoice
|
|
246
|
+
};
|
|
247
|
+
return {
|
|
248
|
+
t402Version,
|
|
249
|
+
payload
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// src/lightning/client/register.ts
|
|
255
|
+
function registerLightningScheme(client, config) {
|
|
256
|
+
const scheme = new LightningScheme(config.signer);
|
|
257
|
+
if (config.networks && config.networks.length > 0) {
|
|
258
|
+
config.networks.forEach((network) => {
|
|
259
|
+
client.register(network, scheme);
|
|
260
|
+
});
|
|
261
|
+
} else {
|
|
262
|
+
client.register("lightning:*", scheme);
|
|
263
|
+
}
|
|
264
|
+
if (config.policies) {
|
|
265
|
+
config.policies.forEach((policy) => {
|
|
266
|
+
client.registerPolicy(policy);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return client;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// src/exact/server/scheme.ts
|
|
273
|
+
var ExactBtcScheme2 = class {
|
|
274
|
+
constructor(config) {
|
|
275
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
276
|
+
__publicField(this, "moneyParsers", []);
|
|
277
|
+
__publicField(this, "config");
|
|
278
|
+
this.config = config;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Register a custom money parser in the parser chain.
|
|
282
|
+
*
|
|
283
|
+
* @param parser - Custom function to convert amount to AssetAmount (or null to skip)
|
|
284
|
+
* @returns The server instance for chaining
|
|
285
|
+
*/
|
|
286
|
+
registerMoneyParser(parser) {
|
|
287
|
+
this.moneyParsers.push(parser);
|
|
288
|
+
return this;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Parses a price into an asset amount in satoshis.
|
|
292
|
+
*
|
|
293
|
+
* Accepts:
|
|
294
|
+
* - Number: treated as USD, converted to satoshis at a default rate
|
|
295
|
+
* - String with $: treated as USD
|
|
296
|
+
* - AssetAmount: returned directly
|
|
297
|
+
*
|
|
298
|
+
* For Bitcoin, amounts are always in satoshis and the asset is "BTC".
|
|
299
|
+
*
|
|
300
|
+
* @param price - The price to parse
|
|
301
|
+
* @param network - The network to use
|
|
302
|
+
* @returns Promise that resolves to the parsed asset amount
|
|
303
|
+
*/
|
|
304
|
+
async parsePrice(price, network) {
|
|
305
|
+
if (typeof price === "object" && price !== null && "amount" in price) {
|
|
306
|
+
if (!price.asset) {
|
|
307
|
+
throw new Error(`Asset must be specified for AssetAmount on network ${network}`);
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
amount: price.amount,
|
|
311
|
+
asset: price.asset,
|
|
312
|
+
extra: price.extra || {}
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
const amount = this.parseMoneyToDecimal(price);
|
|
316
|
+
for (const parser of this.moneyParsers) {
|
|
317
|
+
const result = await parser(amount, network);
|
|
318
|
+
if (result !== null) {
|
|
319
|
+
return result;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return this.defaultMoneyConversion(amount);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Build payment requirements for this scheme/network combination.
|
|
326
|
+
*
|
|
327
|
+
* @param paymentRequirements - Base payment requirements with amount/asset already set
|
|
328
|
+
* @param supportedKind - The supported kind from facilitator
|
|
329
|
+
* @param extensionKeys - Extensions supported by the facilitator
|
|
330
|
+
* @returns Enhanced payment requirements
|
|
331
|
+
*/
|
|
332
|
+
async enhancePaymentRequirements(paymentRequirements, supportedKind, extensionKeys) {
|
|
333
|
+
void supportedKind;
|
|
334
|
+
void extensionKeys;
|
|
335
|
+
return {
|
|
336
|
+
...paymentRequirements,
|
|
337
|
+
payTo: paymentRequirements.payTo || this.config.payTo,
|
|
338
|
+
asset: paymentRequirements.asset || "BTC"
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Parse Money (string | number) to a decimal number.
|
|
343
|
+
*/
|
|
344
|
+
parseMoneyToDecimal(money) {
|
|
345
|
+
if (typeof money === "number") {
|
|
346
|
+
if (!Number.isFinite(money)) {
|
|
347
|
+
throw new Error(`Invalid money value: ${money}`);
|
|
348
|
+
}
|
|
349
|
+
return money;
|
|
350
|
+
}
|
|
351
|
+
const cleanMoney = money.replace(/^\$/, "").trim();
|
|
352
|
+
const amount = parseFloat(cleanMoney);
|
|
353
|
+
if (isNaN(amount)) {
|
|
354
|
+
throw new Error(`Invalid money format: ${money}`);
|
|
355
|
+
}
|
|
356
|
+
return amount;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Default money conversion: treat amount as satoshis.
|
|
360
|
+
* For direct satoshi amounts, the amount is used as-is.
|
|
361
|
+
*/
|
|
362
|
+
defaultMoneyConversion(amount) {
|
|
363
|
+
const sats = Math.floor(amount * SATS_PER_BTC);
|
|
364
|
+
return {
|
|
365
|
+
amount: sats.toString(),
|
|
366
|
+
asset: "BTC",
|
|
367
|
+
extra: {
|
|
368
|
+
symbol: "BTC",
|
|
369
|
+
decimals: 8
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
// src/exact/server/register.ts
|
|
376
|
+
function registerExactBtcScheme2(server, config) {
|
|
377
|
+
const scheme = new ExactBtcScheme2(config.schemeConfig);
|
|
378
|
+
if (config.networks && config.networks.length > 0) {
|
|
379
|
+
config.networks.forEach((network) => {
|
|
380
|
+
server.register(network, scheme);
|
|
381
|
+
});
|
|
382
|
+
} else {
|
|
383
|
+
server.register("bip122:*", scheme);
|
|
384
|
+
}
|
|
385
|
+
return server;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// src/exact/facilitator/scheme.ts
|
|
389
|
+
var ExactBtcScheme3 = class {
|
|
390
|
+
constructor(signer) {
|
|
391
|
+
this.signer = signer;
|
|
392
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
393
|
+
__publicField(this, "caipFamily", "bip122:*");
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Get mechanism-specific extra data for the supported kinds endpoint.
|
|
397
|
+
* Bitcoin on-chain has no extra data.
|
|
398
|
+
*/
|
|
399
|
+
getExtra(_network) {
|
|
400
|
+
return void 0;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Get signer addresses used by this facilitator.
|
|
404
|
+
*/
|
|
405
|
+
getSigners(_network) {
|
|
406
|
+
return [...this.signer.getAddresses()];
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Verifies a payment payload.
|
|
410
|
+
*
|
|
411
|
+
* Validates:
|
|
412
|
+
* 1. Scheme and network matching
|
|
413
|
+
* 2. PSBT structure and signatures
|
|
414
|
+
* 3. Output matches (payTo, amount)
|
|
415
|
+
* 4. Amount above dust limit
|
|
416
|
+
*/
|
|
417
|
+
async verify(payload, requirements) {
|
|
418
|
+
const btcPayload = payload.payload;
|
|
419
|
+
if (!btcPayload?.signedPsbt) {
|
|
420
|
+
return {
|
|
421
|
+
isValid: false,
|
|
422
|
+
invalidReason: "invalid_payload_structure",
|
|
423
|
+
payer: void 0
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
if (payload.accepted.scheme !== SCHEME_EXACT || requirements.scheme !== SCHEME_EXACT) {
|
|
427
|
+
return {
|
|
428
|
+
isValid: false,
|
|
429
|
+
invalidReason: "unsupported_scheme",
|
|
430
|
+
payer: void 0
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
const validNetworks = BTC_NETWORKS;
|
|
434
|
+
if (!validNetworks.includes(requirements.network)) {
|
|
435
|
+
return {
|
|
436
|
+
isValid: false,
|
|
437
|
+
invalidReason: "unsupported_network",
|
|
438
|
+
payer: void 0
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
if (payload.accepted.network !== requirements.network) {
|
|
442
|
+
return {
|
|
443
|
+
isValid: false,
|
|
444
|
+
invalidReason: "network_mismatch",
|
|
445
|
+
payer: void 0
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
if (!validateBitcoinAddress(requirements.payTo)) {
|
|
449
|
+
return {
|
|
450
|
+
isValid: false,
|
|
451
|
+
invalidReason: "invalid_pay_to_address",
|
|
452
|
+
payer: void 0
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
if (BigInt(requirements.amount) < BigInt(DUST_LIMIT)) {
|
|
456
|
+
return {
|
|
457
|
+
isValid: false,
|
|
458
|
+
invalidReason: "amount_below_dust_limit",
|
|
459
|
+
payer: void 0
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
try {
|
|
463
|
+
const result = await this.signer.verifyPsbt({
|
|
464
|
+
signedPsbt: btcPayload.signedPsbt,
|
|
465
|
+
expectedPayTo: requirements.payTo,
|
|
466
|
+
expectedAmount: requirements.amount
|
|
467
|
+
});
|
|
468
|
+
if (!result.valid) {
|
|
469
|
+
return {
|
|
470
|
+
isValid: false,
|
|
471
|
+
invalidReason: result.reason || "psbt_verification_failed",
|
|
472
|
+
payer: result.payer
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
return {
|
|
476
|
+
isValid: true,
|
|
477
|
+
invalidReason: void 0,
|
|
478
|
+
payer: result.payer
|
|
479
|
+
};
|
|
480
|
+
} catch (error) {
|
|
481
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
482
|
+
return {
|
|
483
|
+
isValid: false,
|
|
484
|
+
invalidReason: `verification_error: ${errorMessage}`,
|
|
485
|
+
payer: void 0
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Settles a payment by finalizing and broadcasting the PSBT.
|
|
491
|
+
*/
|
|
492
|
+
async settle(payload, requirements) {
|
|
493
|
+
const btcPayload = payload.payload;
|
|
494
|
+
if (!btcPayload?.signedPsbt) {
|
|
495
|
+
return {
|
|
496
|
+
success: false,
|
|
497
|
+
network: payload.accepted.network,
|
|
498
|
+
transaction: "",
|
|
499
|
+
errorReason: "invalid_payload_structure",
|
|
500
|
+
payer: void 0
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
const verifyResult = await this.verify(payload, requirements);
|
|
504
|
+
if (!verifyResult.isValid) {
|
|
505
|
+
return {
|
|
506
|
+
success: false,
|
|
507
|
+
network: payload.accepted.network,
|
|
508
|
+
transaction: "",
|
|
509
|
+
errorReason: verifyResult.invalidReason ?? "verification_failed",
|
|
510
|
+
payer: verifyResult.payer
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
try {
|
|
514
|
+
const txId = await this.signer.broadcastPsbt(btcPayload.signedPsbt);
|
|
515
|
+
const confirmation = await this.signer.waitForConfirmation(txId, 1);
|
|
516
|
+
if (!confirmation.confirmed) {
|
|
517
|
+
return {
|
|
518
|
+
success: false,
|
|
519
|
+
errorReason: "transaction_not_confirmed",
|
|
520
|
+
transaction: txId,
|
|
521
|
+
network: payload.accepted.network,
|
|
522
|
+
payer: verifyResult.payer
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
return {
|
|
526
|
+
success: true,
|
|
527
|
+
transaction: txId,
|
|
528
|
+
network: payload.accepted.network,
|
|
529
|
+
payer: verifyResult.payer
|
|
530
|
+
};
|
|
531
|
+
} catch (error) {
|
|
532
|
+
console.error("Failed to settle Bitcoin transaction:", error);
|
|
533
|
+
return {
|
|
534
|
+
success: false,
|
|
535
|
+
errorReason: "transaction_failed",
|
|
536
|
+
transaction: "",
|
|
537
|
+
network: payload.accepted.network,
|
|
538
|
+
payer: verifyResult.payer
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
// src/exact/facilitator/register.ts
|
|
545
|
+
function registerExactBtcScheme3(facilitator, config) {
|
|
546
|
+
facilitator.register(config.networks, new ExactBtcScheme3(config.signer));
|
|
547
|
+
return facilitator;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// src/lightning/server/scheme.ts
|
|
551
|
+
var LightningScheme2 = class {
|
|
552
|
+
constructor(config) {
|
|
553
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
554
|
+
__publicField(this, "moneyParsers", []);
|
|
555
|
+
__publicField(this, "config");
|
|
556
|
+
this.config = config;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Register a custom money parser in the parser chain.
|
|
560
|
+
*
|
|
561
|
+
* @param parser - Custom function to convert amount to AssetAmount (or null to skip)
|
|
562
|
+
* @returns The server instance for chaining
|
|
563
|
+
*/
|
|
564
|
+
registerMoneyParser(parser) {
|
|
565
|
+
this.moneyParsers.push(parser);
|
|
566
|
+
return this;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Parses a price into an asset amount in satoshis.
|
|
570
|
+
*
|
|
571
|
+
* @param price - The price to parse
|
|
572
|
+
* @param network - The network to use
|
|
573
|
+
* @returns Promise that resolves to the parsed asset amount
|
|
574
|
+
*/
|
|
575
|
+
async parsePrice(price, network) {
|
|
576
|
+
if (typeof price === "object" && price !== null && "amount" in price) {
|
|
577
|
+
if (!price.asset) {
|
|
578
|
+
throw new Error(`Asset must be specified for AssetAmount on network ${network}`);
|
|
579
|
+
}
|
|
580
|
+
return {
|
|
581
|
+
amount: price.amount,
|
|
582
|
+
asset: price.asset,
|
|
583
|
+
extra: price.extra || {}
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
const amount = this.parseMoneyToDecimal(price);
|
|
587
|
+
for (const parser of this.moneyParsers) {
|
|
588
|
+
const result = await parser(amount, network);
|
|
589
|
+
if (result !== null) {
|
|
590
|
+
return result;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return this.defaultMoneyConversion(amount);
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Build payment requirements for Lightning Network.
|
|
597
|
+
*
|
|
598
|
+
* Generates a BOLT11 invoice and adds it to the extra field.
|
|
599
|
+
*/
|
|
600
|
+
async enhancePaymentRequirements(paymentRequirements, supportedKind, extensionKeys) {
|
|
601
|
+
void extensionKeys;
|
|
602
|
+
const extra = { ...paymentRequirements.extra };
|
|
603
|
+
const invoice = await this.config.generateInvoice(
|
|
604
|
+
paymentRequirements.amount,
|
|
605
|
+
`t402 payment on ${supportedKind.network}`,
|
|
606
|
+
paymentRequirements.maxTimeoutSeconds
|
|
607
|
+
);
|
|
608
|
+
extra.bolt11Invoice = invoice.bolt11Invoice;
|
|
609
|
+
extra.paymentHash = invoice.paymentHash;
|
|
610
|
+
return {
|
|
611
|
+
...paymentRequirements,
|
|
612
|
+
asset: paymentRequirements.asset || "BTC",
|
|
613
|
+
extra
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Parse Money (string | number) to a decimal number.
|
|
618
|
+
*/
|
|
619
|
+
parseMoneyToDecimal(money) {
|
|
620
|
+
if (typeof money === "number") {
|
|
621
|
+
if (!Number.isFinite(money)) {
|
|
622
|
+
throw new Error(`Invalid money value: ${money}`);
|
|
623
|
+
}
|
|
624
|
+
return money;
|
|
625
|
+
}
|
|
626
|
+
const cleanMoney = money.replace(/^\$/, "").trim();
|
|
627
|
+
const amount = parseFloat(cleanMoney);
|
|
628
|
+
if (isNaN(amount)) {
|
|
629
|
+
throw new Error(`Invalid money format: ${money}`);
|
|
630
|
+
}
|
|
631
|
+
return amount;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Default money conversion: treat amount as BTC, convert to satoshis.
|
|
635
|
+
*/
|
|
636
|
+
defaultMoneyConversion(amount) {
|
|
637
|
+
const sats = Math.floor(amount * SATS_PER_BTC);
|
|
638
|
+
return {
|
|
639
|
+
amount: sats.toString(),
|
|
640
|
+
asset: "BTC",
|
|
641
|
+
extra: {
|
|
642
|
+
symbol: "BTC",
|
|
643
|
+
decimals: 8
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
// src/lightning/server/register.ts
|
|
650
|
+
function registerLightningScheme2(server, config) {
|
|
651
|
+
const scheme = new LightningScheme2(config.schemeConfig);
|
|
652
|
+
if (config.networks && config.networks.length > 0) {
|
|
653
|
+
config.networks.forEach((network) => {
|
|
654
|
+
server.register(network, scheme);
|
|
655
|
+
});
|
|
656
|
+
} else {
|
|
657
|
+
server.register("lightning:*", scheme);
|
|
658
|
+
}
|
|
659
|
+
return server;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// src/lightning/facilitator/scheme.ts
|
|
663
|
+
async function sha256Hex(preimageHex) {
|
|
664
|
+
const bytes = new Uint8Array(preimageHex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
|
|
665
|
+
const hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", bytes);
|
|
666
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
667
|
+
return Array.from(hashArray).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
668
|
+
}
|
|
669
|
+
var LightningScheme3 = class {
|
|
670
|
+
constructor(signer) {
|
|
671
|
+
this.signer = signer;
|
|
672
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
673
|
+
__publicField(this, "caipFamily", "lightning:*");
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Get mechanism-specific extra data for the supported kinds endpoint.
|
|
677
|
+
* Lightning has no extra data.
|
|
678
|
+
*/
|
|
679
|
+
getExtra(_network) {
|
|
680
|
+
return void 0;
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Get signer addresses (node public keys) for this facilitator.
|
|
684
|
+
*/
|
|
685
|
+
getSigners(_network) {
|
|
686
|
+
return [...this.signer.getAddresses()];
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Verifies a Lightning payment payload.
|
|
690
|
+
*
|
|
691
|
+
* Validates:
|
|
692
|
+
* 1. Payload structure (paymentHash, preimage, bolt11Invoice)
|
|
693
|
+
* 2. Preimage verification: SHA-256(preimage) === paymentHash
|
|
694
|
+
* 3. Payment lookup on the Lightning node
|
|
695
|
+
*/
|
|
696
|
+
async verify(payload, requirements) {
|
|
697
|
+
const lnPayload = payload.payload;
|
|
698
|
+
if (!lnPayload?.paymentHash || !lnPayload?.preimage || !lnPayload?.bolt11Invoice) {
|
|
699
|
+
return {
|
|
700
|
+
isValid: false,
|
|
701
|
+
invalidReason: "invalid_payload_structure",
|
|
702
|
+
payer: void 0
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
if (payload.accepted.scheme !== SCHEME_EXACT || requirements.scheme !== SCHEME_EXACT) {
|
|
706
|
+
return {
|
|
707
|
+
isValid: false,
|
|
708
|
+
invalidReason: "unsupported_scheme",
|
|
709
|
+
payer: void 0
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
const validNetworks = LIGHTNING_NETWORKS;
|
|
713
|
+
if (!validNetworks.includes(requirements.network)) {
|
|
714
|
+
return {
|
|
715
|
+
isValid: false,
|
|
716
|
+
invalidReason: "unsupported_network",
|
|
717
|
+
payer: void 0
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
if (!isValidHex(lnPayload.preimage, 32)) {
|
|
721
|
+
return {
|
|
722
|
+
isValid: false,
|
|
723
|
+
invalidReason: "invalid_preimage_format",
|
|
724
|
+
payer: void 0
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
if (!isValidHex(lnPayload.paymentHash, 32)) {
|
|
728
|
+
return {
|
|
729
|
+
isValid: false,
|
|
730
|
+
invalidReason: "invalid_payment_hash_format",
|
|
731
|
+
payer: void 0
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
try {
|
|
735
|
+
const computedHash = await sha256Hex(lnPayload.preimage);
|
|
736
|
+
if (computedHash !== lnPayload.paymentHash.toLowerCase()) {
|
|
737
|
+
return {
|
|
738
|
+
isValid: false,
|
|
739
|
+
invalidReason: "preimage_hash_mismatch",
|
|
740
|
+
payer: void 0
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
} catch {
|
|
744
|
+
return {
|
|
745
|
+
isValid: false,
|
|
746
|
+
invalidReason: "preimage_verification_failed",
|
|
747
|
+
payer: void 0
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
try {
|
|
751
|
+
const payment = await this.signer.lookupPayment(lnPayload.paymentHash);
|
|
752
|
+
if (!payment.settled) {
|
|
753
|
+
return {
|
|
754
|
+
isValid: false,
|
|
755
|
+
invalidReason: "payment_not_settled",
|
|
756
|
+
payer: void 0
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
if (payment.amountSats && BigInt(payment.amountSats) < BigInt(requirements.amount)) {
|
|
760
|
+
return {
|
|
761
|
+
isValid: false,
|
|
762
|
+
invalidReason: "insufficient_amount",
|
|
763
|
+
payer: void 0
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
} catch (error) {
|
|
767
|
+
console.warn("Could not verify payment with Lightning node:", error);
|
|
768
|
+
}
|
|
769
|
+
return {
|
|
770
|
+
isValid: true,
|
|
771
|
+
invalidReason: void 0,
|
|
772
|
+
payer: void 0
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Settles a Lightning payment.
|
|
777
|
+
*
|
|
778
|
+
* Lightning payments are atomic (settle-on-pay), so this is effectively
|
|
779
|
+
* a confirmation that the payment was already completed. The actual
|
|
780
|
+
* settlement happened when the client paid the invoice.
|
|
781
|
+
*/
|
|
782
|
+
async settle(payload, requirements) {
|
|
783
|
+
const lnPayload = payload.payload;
|
|
784
|
+
if (!lnPayload?.paymentHash || !lnPayload?.preimage) {
|
|
785
|
+
return {
|
|
786
|
+
success: false,
|
|
787
|
+
network: payload.accepted.network,
|
|
788
|
+
transaction: "",
|
|
789
|
+
errorReason: "invalid_payload_structure",
|
|
790
|
+
payer: void 0
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
const verifyResult = await this.verify(payload, requirements);
|
|
794
|
+
if (!verifyResult.isValid) {
|
|
795
|
+
return {
|
|
796
|
+
success: false,
|
|
797
|
+
network: payload.accepted.network,
|
|
798
|
+
transaction: "",
|
|
799
|
+
errorReason: verifyResult.invalidReason ?? "verification_failed",
|
|
800
|
+
payer: void 0
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
return {
|
|
804
|
+
success: true,
|
|
805
|
+
transaction: lnPayload.paymentHash,
|
|
806
|
+
network: payload.accepted.network,
|
|
807
|
+
payer: void 0
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
// src/lightning/facilitator/register.ts
|
|
813
|
+
function registerLightningScheme3(facilitator, config) {
|
|
814
|
+
facilitator.register(config.networks, new LightningScheme3(config.signer));
|
|
815
|
+
return facilitator;
|
|
816
|
+
}
|
|
817
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
818
|
+
0 && (module.exports = {
|
|
819
|
+
ALL_NETWORKS,
|
|
820
|
+
BTC_MAINNET,
|
|
821
|
+
BTC_NETWORKS,
|
|
822
|
+
BTC_TESTNET,
|
|
823
|
+
DEFAULT_VALIDITY_DURATION,
|
|
824
|
+
DUST_LIMIT,
|
|
825
|
+
ExactBtcScheme,
|
|
826
|
+
LIGHTNING_MAINNET,
|
|
827
|
+
LIGHTNING_NETWORKS,
|
|
828
|
+
LIGHTNING_TESTNET,
|
|
829
|
+
LightningScheme,
|
|
830
|
+
MAINNET_ADDRESS_PREFIXES,
|
|
831
|
+
MIN_RELAY_FEE,
|
|
832
|
+
SATS_PER_BTC,
|
|
833
|
+
SCHEME_EXACT,
|
|
834
|
+
TESTNET_ADDRESS_PREFIXES,
|
|
835
|
+
btcToSatoshis,
|
|
836
|
+
isMainnetAddress,
|
|
837
|
+
isTestnetAddress,
|
|
838
|
+
isValidHex,
|
|
839
|
+
registerExactBtcClientScheme,
|
|
840
|
+
registerExactBtcFacilitatorScheme,
|
|
841
|
+
registerExactBtcServerScheme,
|
|
842
|
+
registerLightningClientScheme,
|
|
843
|
+
registerLightningFacilitatorScheme,
|
|
844
|
+
registerLightningServerScheme,
|
|
845
|
+
satoshisToBtc,
|
|
846
|
+
validateBitcoinAddress,
|
|
847
|
+
validateBolt11Invoice
|
|
848
|
+
});
|
|
849
|
+
//# sourceMappingURL=index.js.map
|