@arkade-os/lnurl-client 0.6.0 → 0.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 +141 -4
- package/dist/addresses-CPAzIbJ_.d.ts +514 -0
- package/dist/arkade.d.ts +81 -6
- package/dist/arkade.js +217 -16
- package/dist/browser.d.ts +6 -0
- package/dist/browser.js +60 -0
- package/dist/{chunk-YKBY6NCA.js → chunk-4ELYU6DY.js} +342 -82
- package/dist/chunk-H7W5RHP2.js +58 -0
- package/dist/hd.d.ts +16 -0
- package/dist/hd.js +389 -0
- package/dist/index.d.ts +81 -461
- package/dist/index.js +24 -4
- package/package.json +59 -43
package/dist/arkade.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
|
-
LnurlError,
|
|
3
2
|
createLnurlClient,
|
|
3
|
+
createPendingConfirmations,
|
|
4
4
|
deriveSessionId,
|
|
5
5
|
deriveSessionTokenWithSigner,
|
|
6
|
+
formatUnitAmount,
|
|
6
7
|
syncPayments
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-4ELYU6DY.js";
|
|
9
|
+
import {
|
|
10
|
+
LnurlError
|
|
11
|
+
} from "./chunk-H7W5RHP2.js";
|
|
8
12
|
|
|
9
13
|
// packages/client/src/arkade.ts
|
|
10
|
-
import { ArkAddress } from "@arkade-os/sdk";
|
|
11
|
-
import { hex } from "@scure/base";
|
|
14
|
+
import { ArkAddress as ArkAddress2 } from "@arkade-os/sdk";
|
|
15
|
+
import { hex as hex2 } from "@scure/base";
|
|
12
16
|
|
|
13
17
|
// packages/client/src/rail.ts
|
|
14
18
|
import { isLnurl } from "@arkade-os/sdk";
|
|
@@ -54,6 +58,11 @@ function makeRail(type, id, inner, deps, resolveOnce) {
|
|
|
54
58
|
} catch {
|
|
55
59
|
return false;
|
|
56
60
|
}
|
|
61
|
+
if (req.unitAmount) {
|
|
62
|
+
if (!unitOf(pr, req.unitAmount.unit)) return false;
|
|
63
|
+
if (pr.paymentOptions === void 0) return type === "lightning";
|
|
64
|
+
return pr.paymentOptions.some((o) => o.type === type && o.available !== false);
|
|
65
|
+
}
|
|
57
66
|
if (pr.paymentOptions === void 0) {
|
|
58
67
|
if (type !== "lightning") return false;
|
|
59
68
|
if (req.amount === void 0) return true;
|
|
@@ -68,24 +77,41 @@ function makeRail(type, id, inner, deps, resolveOnce) {
|
|
|
68
77
|
},
|
|
69
78
|
async quote(req, ctx) {
|
|
70
79
|
const pr = await resolveOnce(req.raw);
|
|
71
|
-
|
|
80
|
+
const inUnit = req.unitAmount;
|
|
81
|
+
if (req.amount === void 0 && !inUnit) throw new LnurlError(`${id} needs an explicit amount`);
|
|
72
82
|
const option = pr.paymentOptions?.find((o) => o.type === type && o.available !== false)?.id;
|
|
73
|
-
const
|
|
74
|
-
amountSat: req.amount,
|
|
83
|
+
const extra = {
|
|
75
84
|
...option !== void 0 ? { paymentOption: option } : {},
|
|
76
85
|
...deps.comment !== void 0 ? { comment: deps.comment } : {}
|
|
77
|
-
}
|
|
78
|
-
const
|
|
86
|
+
};
|
|
87
|
+
const result = await deps.client.requestInvoice(
|
|
88
|
+
pr,
|
|
89
|
+
inUnit ? { ...extra, unit: inUnit.unit, amount: inUnit.amount } : { ...extra, amountSat: req.amount }
|
|
90
|
+
);
|
|
91
|
+
const quotedSat = inUnit ? Number(result.paymentQuote?.payment.amount) / 1e3 : req.amount;
|
|
92
|
+
if (!Number.isSafeInteger(quotedSat)) throw new LnurlError(`${id}: the quote names no whole number of sats`);
|
|
93
|
+
const delegated = result.kind === "bolt11" ? { raw: result.pr } : { raw: destinationOf(result.paymentDestination, id), amount: quotedSat };
|
|
79
94
|
if (!inner.match(delegated, ctx)) {
|
|
80
95
|
throw new LnurlError(`${id}: ${inner.id} cannot pay the destination the callback returned`);
|
|
81
96
|
}
|
|
82
97
|
const quote = await inner.quote(delegated, ctx);
|
|
83
98
|
const expect = result.kind === "bolt11" ? { pr: result.pr } : { paymentOption: result.paymentOption, paymentDestination: result.paymentDestination };
|
|
84
|
-
const
|
|
99
|
+
const unit = inUnit ? unitOf(pr, inUnit.unit) : void 0;
|
|
100
|
+
const lnurl = {
|
|
101
|
+
target: req.raw,
|
|
102
|
+
via: inner.id,
|
|
103
|
+
verify: result.verify,
|
|
104
|
+
verifyBatch: result.verifyBatch,
|
|
105
|
+
expect,
|
|
106
|
+
...inUnit && unit ? { quote: { amount: String(inUnit.amount), unit: unit.code, decimals: unit.decimals } } : {}
|
|
107
|
+
};
|
|
85
108
|
return { ...quote, railId: id, meta: { ...quote.meta, lnurl } };
|
|
86
109
|
}
|
|
87
110
|
};
|
|
88
111
|
}
|
|
112
|
+
function unitOf(pr, code) {
|
|
113
|
+
return pr.units?.find((u) => u.code.toUpperCase() === code.toUpperCase());
|
|
114
|
+
}
|
|
89
115
|
function destinationOf(destination, id) {
|
|
90
116
|
if (!destination) throw new LnurlError(`${id}: the callback returned no payment destination`);
|
|
91
117
|
return destination;
|
|
@@ -139,7 +165,11 @@ function arkadeLnurl(opts) {
|
|
|
139
165
|
const { wallet, baseUrl } = opts;
|
|
140
166
|
const domain = opts.domain ?? new URL(baseUrl).hostname;
|
|
141
167
|
const identity = wallet ? wallet.identity : opts.identity;
|
|
142
|
-
const addresses = async () =>
|
|
168
|
+
const addresses = async () => {
|
|
169
|
+
if (wallet) return { arkadeAddress: await wallet.getAddress(), boardingAddress: await wallet.getBoardingAddress() };
|
|
170
|
+
if (!opts.arkadeAddress) throw new LnurlError("Static receive requires an Arkade address");
|
|
171
|
+
return { arkadeAddress: opts.arkadeAddress, ...opts.boardingAddress ? { boardingAddress: opts.boardingAddress } : {} };
|
|
172
|
+
};
|
|
143
173
|
const client = opts.client ?? createLnurlClient({ baseUrl });
|
|
144
174
|
const payer = createLnurlClient();
|
|
145
175
|
let tokenOnce;
|
|
@@ -180,6 +210,7 @@ function arkadeLnurl(opts) {
|
|
|
180
210
|
return entry.pr;
|
|
181
211
|
},
|
|
182
212
|
payments: (listOpts) => client.listPayments(held, handle, { domain, ...listOpts }),
|
|
213
|
+
allocations: (listOpts) => client.listHdAllocations(held, handle, { domain, ...listOpts }),
|
|
183
214
|
sync: async () => syncPayments(
|
|
184
215
|
[{ baseUrl, token: held, handle, domain }],
|
|
185
216
|
{ client: (target) => createLnurlClient({ baseUrl: target }), store: needStore() }
|
|
@@ -216,7 +247,7 @@ function arkadeLnurl(opts) {
|
|
|
216
247
|
);
|
|
217
248
|
}
|
|
218
249
|
await client.registerArkadeIdentity(
|
|
219
|
-
await arkadeIdentityRequest({
|
|
250
|
+
opts.hd ? { token: held, handle: registered.handle, domain, hd: opts.hd } : await arkadeIdentityRequest({
|
|
220
251
|
identity,
|
|
221
252
|
token: held,
|
|
222
253
|
handle: registered.handle,
|
|
@@ -227,11 +258,15 @@ function arkadeLnurl(opts) {
|
|
|
227
258
|
return receiverFrom(held, registered.handle, registered.lightningAddress, flagged);
|
|
228
259
|
},
|
|
229
260
|
router,
|
|
230
|
-
options: (target,
|
|
261
|
+
options: (target, amount, prefs) => router().options(
|
|
262
|
+
typeof amount === "number" ? { raw: target.trim(), amount } : { raw: target.trim(), unitAmount: amount },
|
|
263
|
+
{ priority: DEFAULT_RAIL_PRIORITY, ...prefs }
|
|
264
|
+
)
|
|
231
265
|
};
|
|
232
266
|
}
|
|
233
267
|
|
|
234
268
|
// packages/client/src/activity.ts
|
|
269
|
+
var quotedLabel = (q) => `${formatUnitAmount(q.amount, q.decimals)} ${q.unit}`;
|
|
235
270
|
var LNURL_RESOLVER_ID = "lnurl:payments";
|
|
236
271
|
var SENT_RESOLVER_ID = "lnurl:sends";
|
|
237
272
|
var LNURL_GROUP_PREFIX = "lnurl:";
|
|
@@ -264,6 +299,7 @@ function sentActivityResolver(sends) {
|
|
|
264
299
|
target: sent.target,
|
|
265
300
|
rail: sent.railId,
|
|
266
301
|
delivered: `${sent.amountSat} sats`,
|
|
302
|
+
...sent.quote ? { requested: quotedLabel(sent.quote) } : {},
|
|
267
303
|
...sent.feeSat > 0 ? { fee: `${sent.feeSat} sats` } : {},
|
|
268
304
|
...sent.swapId ? { swap: sent.swapId } : {},
|
|
269
305
|
...sent.preimage ? { preimage: sent.preimage } : {},
|
|
@@ -293,17 +329,176 @@ function lnurlActivityResolver(payments) {
|
|
|
293
329
|
rail: railOf(payment),
|
|
294
330
|
lightningAddress: payment.lightningAddress,
|
|
295
331
|
identifier: payment.identifier,
|
|
296
|
-
verified: payment.settled
|
|
332
|
+
verified: payment.settled,
|
|
333
|
+
...payment.quote ? { requested: quotedLabel(payment.quote) } : {}
|
|
297
334
|
}
|
|
298
335
|
}];
|
|
299
336
|
}
|
|
300
337
|
};
|
|
301
338
|
}
|
|
302
339
|
|
|
340
|
+
// packages/client/src/sends.ts
|
|
341
|
+
function createLnurlSendTracker(store, options) {
|
|
342
|
+
const confirmations = options.confirmations ?? createPendingConfirmations();
|
|
343
|
+
const subscriptions = /* @__PURE__ */ new Set();
|
|
344
|
+
let generation = 0;
|
|
345
|
+
const persist = (update) => {
|
|
346
|
+
try {
|
|
347
|
+
const rows = update(store.read());
|
|
348
|
+
if (rows) store.write(rows);
|
|
349
|
+
} catch (error) {
|
|
350
|
+
options.onError(error);
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
const save = (sent) => persist((rows) => mergeSentPayment(rows, sent));
|
|
354
|
+
const mark = (txid, confirmed) => persist((rows) => {
|
|
355
|
+
const sent = rows.find((row) => row.txid === txid);
|
|
356
|
+
return sent ? mergeSentPayment(rows, { ...sent, receiverConfirmed: confirmed }) : void 0;
|
|
357
|
+
});
|
|
358
|
+
const watch = (txid, verify, verifyBatch, startedAt, expect) => {
|
|
359
|
+
const current = generation;
|
|
360
|
+
confirmations.add({
|
|
361
|
+
key: txid,
|
|
362
|
+
verifyUrl: verify,
|
|
363
|
+
verifyBatch,
|
|
364
|
+
startedAt,
|
|
365
|
+
expect,
|
|
366
|
+
onSettled: () => {
|
|
367
|
+
if (current === generation) mark(txid, true);
|
|
368
|
+
},
|
|
369
|
+
onError: () => {
|
|
370
|
+
if (current === generation) mark(txid, false);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
};
|
|
374
|
+
return {
|
|
375
|
+
all: () => store.read(),
|
|
376
|
+
record(handle, quote, target) {
|
|
377
|
+
const createdAt = Date.now();
|
|
378
|
+
const current = generation;
|
|
379
|
+
const meta = lnurlQuoteMeta(quote);
|
|
380
|
+
let stopped = false;
|
|
381
|
+
let unsubscribe;
|
|
382
|
+
const stop = () => {
|
|
383
|
+
stopped = true;
|
|
384
|
+
unsubscribe?.();
|
|
385
|
+
subscriptions.delete(stop);
|
|
386
|
+
};
|
|
387
|
+
subscriptions.add(stop);
|
|
388
|
+
unsubscribe = handle.subscribe(({ status, result }) => {
|
|
389
|
+
if (stopped || current !== generation) return;
|
|
390
|
+
try {
|
|
391
|
+
if (result?.txid) save({
|
|
392
|
+
txid: result.txid,
|
|
393
|
+
target: meta?.target ?? target,
|
|
394
|
+
railId: quote.railId,
|
|
395
|
+
amountSat: quote.amount,
|
|
396
|
+
feeSat: quote.fee,
|
|
397
|
+
createdAt,
|
|
398
|
+
...result.swapId ? { swapId: result.swapId } : {},
|
|
399
|
+
...result.preimage ? { preimage: result.preimage } : {},
|
|
400
|
+
...meta?.verify ? { verify: meta.verify } : {},
|
|
401
|
+
...meta?.verifyBatch ? { verifyBatch: meta.verifyBatch } : {},
|
|
402
|
+
...meta?.expect ? { expect: meta.expect } : {},
|
|
403
|
+
...meta?.quote ? { quote: meta.quote } : {}
|
|
404
|
+
});
|
|
405
|
+
} finally {
|
|
406
|
+
if (status === "settled" || status === "failed") stop();
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
if (stopped) unsubscribe();
|
|
410
|
+
return stop;
|
|
411
|
+
},
|
|
412
|
+
watch,
|
|
413
|
+
resume() {
|
|
414
|
+
for (const sent of store.read()) {
|
|
415
|
+
if (sent.verify && sent.receiverConfirmed === void 0)
|
|
416
|
+
watch(sent.txid, sent.verify, sent.verifyBatch, sent.createdAt, sent.expect);
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
mark,
|
|
420
|
+
forget() {
|
|
421
|
+
generation++;
|
|
422
|
+
confirmations.forget();
|
|
423
|
+
for (const stop of subscriptions) stop();
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// packages/client/src/receive-rails.ts
|
|
429
|
+
import { ArkAddress } from "@arkade-os/sdk";
|
|
430
|
+
import { hex } from "@scure/base";
|
|
431
|
+
function lnurlRailLimits(payRequest) {
|
|
432
|
+
const options = payRequest.paymentOptions ?? [{ id: "lightning", type: "lightning" }];
|
|
433
|
+
return options.filter((option) => option.id !== "" && option.available !== false && option.asset === void 0).map((option) => ({
|
|
434
|
+
type: option.type,
|
|
435
|
+
min: Math.ceil((option.minSendable ?? payRequest.minSendable) / 1e3),
|
|
436
|
+
max: Math.floor((option.maxSendable ?? payRequest.maxSendable) / 1e3)
|
|
437
|
+
}));
|
|
438
|
+
}
|
|
439
|
+
function sameOperator(a, b) {
|
|
440
|
+
try {
|
|
441
|
+
const [x, y] = [ArkAddress.decode(a), ArkAddress.decode(b)];
|
|
442
|
+
return x.hrp === y.hrp && hex.encode(x.serverPubKey) === hex.encode(y.serverPubKey);
|
|
443
|
+
} catch {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
async function resolveLnurlRails(receiver, amountSat, rails, own, client = createLnurlClient()) {
|
|
448
|
+
const payRequest = await receiver.payRequest();
|
|
449
|
+
return Promise.allSettled(rails.map(async (rail) => {
|
|
450
|
+
const option = payRequest.paymentOptions?.find((candidate) => candidate.id !== "" && candidate.type === rail && candidate.available !== false && candidate.asset === void 0);
|
|
451
|
+
const legacyLightning = payRequest.paymentOptions === void 0 && rail === "lightning";
|
|
452
|
+
if (!option && !legacyLightning) throw new LnurlError(`the LNURL offers no ${rail} rail`);
|
|
453
|
+
const min = option?.minSendable ?? payRequest.minSendable;
|
|
454
|
+
const max = option?.maxSendable ?? payRequest.maxSendable;
|
|
455
|
+
const amountMsat = amountSat * 1e3;
|
|
456
|
+
if (!Number.isSafeInteger(amountMsat) || amountMsat < min || amountMsat > max) {
|
|
457
|
+
throw new LnurlError(`Amount must be between ${min} and ${max} whole millisats`);
|
|
458
|
+
}
|
|
459
|
+
const result = await client.requestInvoice(payRequest, { amountSat, paymentOption: option?.id });
|
|
460
|
+
if (option && result.paymentOption !== void 0 && result.paymentOption !== option.id) {
|
|
461
|
+
throw new LnurlError(`The callback answered for ${result.paymentOption}, not ${option.id}`);
|
|
462
|
+
}
|
|
463
|
+
const target = result.kind === "bolt11" ? result.pr : result.paymentDestination;
|
|
464
|
+
if (!target || result.kind === "bolt11" !== (rail === "lightning")) {
|
|
465
|
+
throw new LnurlError(`the LNURL answered the ${rail} rail with nothing payable on it`);
|
|
466
|
+
}
|
|
467
|
+
if (rail === "onchain" && target !== own.onchain) {
|
|
468
|
+
throw new LnurlError("the LNURL gave an on-chain address that is not this wallet's");
|
|
469
|
+
}
|
|
470
|
+
if (rail === "arkade" && !sameOperator(target, own.arkade)) {
|
|
471
|
+
throw new LnurlError("the LNURL gave an Arkade address on another operator");
|
|
472
|
+
}
|
|
473
|
+
return target;
|
|
474
|
+
}));
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// packages/client/src/receiver-bootstrap.ts
|
|
478
|
+
async function bootstrapReceiver(facade, opts = {}) {
|
|
479
|
+
const receiver = await facade.owned();
|
|
480
|
+
if (receiver?.lightningAddress) return { kind: "ready", receiver, claimed: false };
|
|
481
|
+
if (receiver) {
|
|
482
|
+
try {
|
|
483
|
+
return { kind: "ready", receiver, claimed: false, capabilities: await facade.capabilities() };
|
|
484
|
+
} catch (capabilitiesError) {
|
|
485
|
+
return { kind: "ready", receiver, claimed: false, capabilitiesError };
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
const capabilities = await facade.capabilities();
|
|
489
|
+
if (opts.autoClaimNameless && capabilities.allocationModes.includes("session") && !capabilities.requireApiKey) {
|
|
490
|
+
return { kind: "ready", receiver: await facade.claim({ nameless: true }), claimed: true, capabilities };
|
|
491
|
+
}
|
|
492
|
+
return { kind: "onboarding", capabilities };
|
|
493
|
+
}
|
|
494
|
+
async function claimOrAdopt(facade, opts) {
|
|
495
|
+
return await facade.owned() ?? facade.claim(opts);
|
|
496
|
+
}
|
|
497
|
+
|
|
303
498
|
// packages/client/src/arkade.ts
|
|
304
499
|
function isArkadeAddress(address) {
|
|
305
500
|
try {
|
|
306
|
-
|
|
501
|
+
ArkAddress2.decode(address);
|
|
307
502
|
return true;
|
|
308
503
|
} catch {
|
|
309
504
|
return false;
|
|
@@ -317,7 +512,7 @@ async function claimPublicKeyOf(identity) {
|
|
|
317
512
|
if (key.length !== 33) {
|
|
318
513
|
throw new LnurlError(`expected a 33-byte compressed public key, got ${key.length} bytes`);
|
|
319
514
|
}
|
|
320
|
-
return
|
|
515
|
+
return hex2.encode(key);
|
|
321
516
|
}
|
|
322
517
|
async function arkadeIdentityRequest(params) {
|
|
323
518
|
if (!isArkadeAddress(params.arkadeAddress)) {
|
|
@@ -344,14 +539,20 @@ export {
|
|
|
344
539
|
arkadeIdentityRequest,
|
|
345
540
|
arkadeLnurl,
|
|
346
541
|
arkadePaymentRouter,
|
|
542
|
+
bootstrapReceiver,
|
|
543
|
+
claimOrAdopt,
|
|
347
544
|
claimPublicKeyOf,
|
|
545
|
+
createLnurlSendTracker,
|
|
348
546
|
deriveSessionTokenForIdentity,
|
|
349
547
|
encodeLnurl,
|
|
350
548
|
isArkadeAddress,
|
|
351
549
|
lnurlActivityResolver,
|
|
352
550
|
lnurlQuoteMeta,
|
|
551
|
+
lnurlRailLimits,
|
|
353
552
|
lnurlRails,
|
|
354
553
|
mergeSentPayment,
|
|
554
|
+
quotedLabel,
|
|
355
555
|
railOf,
|
|
556
|
+
resolveLnurlRails,
|
|
356
557
|
sentActivityResolver
|
|
357
558
|
};
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// packages/client/src/browser.ts
|
|
2
|
+
function createIndexedDbLnurlPaymentStore(dbName = "arkade-lnurl-payments", storeName = "payments") {
|
|
3
|
+
const open = () => new Promise((resolve, reject) => {
|
|
4
|
+
const request = indexedDB.open(dbName, 1);
|
|
5
|
+
request.onupgradeneeded = () => {
|
|
6
|
+
if (!request.result.objectStoreNames.contains(storeName)) {
|
|
7
|
+
request.result.createObjectStore(storeName, { keyPath: "key" });
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
request.onsuccess = () => resolve(request.result);
|
|
11
|
+
request.onerror = () => reject(request.error);
|
|
12
|
+
});
|
|
13
|
+
const run = (mode, work) => open().then((db) => new Promise((resolve, reject) => {
|
|
14
|
+
const fail = (error) => {
|
|
15
|
+
db.close();
|
|
16
|
+
reject(error ?? new DOMException("Transaction aborted", "AbortError"));
|
|
17
|
+
};
|
|
18
|
+
let started;
|
|
19
|
+
try {
|
|
20
|
+
const tx = db.transaction(storeName, mode);
|
|
21
|
+
started = tx;
|
|
22
|
+
tx.onabort = () => fail(tx.error);
|
|
23
|
+
const result = work(tx.objectStore(storeName));
|
|
24
|
+
tx.oncomplete = () => {
|
|
25
|
+
db.close();
|
|
26
|
+
try {
|
|
27
|
+
resolve(result());
|
|
28
|
+
} catch (error) {
|
|
29
|
+
reject(error);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (started) {
|
|
34
|
+
started.onabort = () => fail(error);
|
|
35
|
+
try {
|
|
36
|
+
started.abort();
|
|
37
|
+
} catch {
|
|
38
|
+
fail(error);
|
|
39
|
+
}
|
|
40
|
+
} else fail(error);
|
|
41
|
+
}
|
|
42
|
+
}));
|
|
43
|
+
return {
|
|
44
|
+
read: () => run("readonly", (store) => {
|
|
45
|
+
const request = store.getAll();
|
|
46
|
+
return () => request.result;
|
|
47
|
+
}),
|
|
48
|
+
write: (records) => run("readwrite", (store) => {
|
|
49
|
+
for (const record of records) store.put(record);
|
|
50
|
+
return () => void 0;
|
|
51
|
+
}),
|
|
52
|
+
clear: () => run("readwrite", (store) => {
|
|
53
|
+
store.clear();
|
|
54
|
+
return () => void 0;
|
|
55
|
+
})
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
createIndexedDbLnurlPaymentStore
|
|
60
|
+
};
|