@arkade-os/swap 0.0.3 → 0.0.5
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 +189 -54
- package/dist/{chunk-HLMMA3LJ.js → chunk-Q4FAYBXS.js} +60 -247
- package/dist/index.cjs +212 -301
- package/dist/index.d.cts +283 -10
- package/dist/index.d.ts +283 -10
- package/dist/index.js +150 -69
- package/dist/nostr.cjs +21 -14
- package/dist/nostr.d.cts +14 -3
- package/dist/nostr.d.ts +14 -3
- package/dist/nostr.js +10 -2
- package/dist/{rfq-CCAFoFtR.d.cts → rfq-BH2yvo3O.d.cts} +50 -335
- package/dist/{rfq-CCAFoFtR.d.ts → rfq-BH2yvo3O.d.ts} +50 -335
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -53,20 +53,20 @@ __export(index_exports, {
|
|
|
53
53
|
ONCHAIN_RECEIVE_PAIR: () => ONCHAIN_RECEIVE_PAIR,
|
|
54
54
|
ONCHAIN_SECONDS_PER_BLOCK: () => ONCHAIN_SECONDS_PER_BLOCK,
|
|
55
55
|
ONCHAIN_SEND_PAIR: () => ONCHAIN_SEND_PAIR,
|
|
56
|
+
PreimageNotRecoverableError: () => PreimageNotRecoverableError,
|
|
56
57
|
QUOTE_OPTIONS: () => QUOTE_OPTIONS,
|
|
57
58
|
REFUND_MTP_LAG_SECONDS: () => REFUND_MTP_LAG_SECONDS,
|
|
58
|
-
RFQ_PREIMAGE_TAG: () => RFQ_PREIMAGE_TAG,
|
|
59
59
|
RFQ_RESOLVED_STATES: () => RFQ_RESOLVED_STATES,
|
|
60
60
|
RFQ_SWAP_TERMINAL_STATES: () => RFQ_SWAP_TERMINAL_STATES,
|
|
61
61
|
RFQ_TERMINAL_STATES: () => RFQ_TERMINAL_STATES,
|
|
62
62
|
RefundNotLocallyPossibleError: () => RefundNotLocallyPossibleError,
|
|
63
63
|
RfqSwapManager: () => RfqSwapManager,
|
|
64
|
+
SOLO_REFUND_HEADROOM_SECONDS: () => SOLO_REFUND_HEADROOM_SECONDS,
|
|
64
65
|
SWAP_LOCKUP_CONTRACT_KIND: () => SWAP_LOCKUP_CONTRACT_KIND,
|
|
65
66
|
SWAP_LOCKUP_CONTRACT_LABEL: () => SWAP_LOCKUP_CONTRACT_LABEL,
|
|
66
67
|
SWAP_LOCKUP_CONTRACT_TYPE: () => SWAP_LOCKUP_CONTRACT_TYPE,
|
|
67
68
|
SwapRefusal: () => SwapRefusal,
|
|
68
69
|
addAssetSwap: () => addAssetSwap,
|
|
69
|
-
adoptSwapDescriptor: () => adoptSwapDescriptor,
|
|
70
70
|
arkadeSwapRequest: () => arkadeSwapRequest,
|
|
71
71
|
assertFundable: () => assertFundable,
|
|
72
72
|
assertReceivable: () => assertReceivable,
|
|
@@ -75,7 +75,6 @@ __export(index_exports, {
|
|
|
75
75
|
awaitRfqResolution: () => awaitRfqResolution,
|
|
76
76
|
buildHtlcClaim: () => buildHtlcClaim,
|
|
77
77
|
buildHtlcRefund: () => buildHtlcRefund,
|
|
78
|
-
buildPreimageMessage: () => buildPreimageMessage,
|
|
79
78
|
cancelOffer: () => cancelOffer,
|
|
80
79
|
claimOnchainFill: () => claimOnchainFill,
|
|
81
80
|
claimReceiveLockup: () => claimReceiveLockup,
|
|
@@ -87,8 +86,6 @@ __export(index_exports, {
|
|
|
87
86
|
deriveLightningReceive: () => deriveLightningReceive,
|
|
88
87
|
deriveOnchainReceive: () => deriveOnchainReceive,
|
|
89
88
|
deriveOnchainSend: () => deriveOnchainSend,
|
|
90
|
-
derivePreimage: () => derivePreimage,
|
|
91
|
-
deriveSwapSecrets: () => deriveSwapSecrets,
|
|
92
89
|
discoverMarkets: () => discoverMarkets,
|
|
93
90
|
encodeOffer: () => encodeOffer,
|
|
94
91
|
extractPreimage: () => extractPreimage,
|
|
@@ -97,7 +94,6 @@ __export(index_exports, {
|
|
|
97
94
|
getAssetSwaps: () => getAssetSwaps,
|
|
98
95
|
getAssetSwapsOrThrow: () => getAssetSwapsOrThrow,
|
|
99
96
|
httpTransport: () => httpTransport,
|
|
100
|
-
isDeterministicSigner: () => isDeterministicSigner,
|
|
101
97
|
isRfqSwapTerminal: () => isRfqSwapTerminal,
|
|
102
98
|
isRfqTerminal: () => isRfqTerminal,
|
|
103
99
|
lightningReceiveRequest: () => lightningReceiveRequest,
|
|
@@ -113,10 +109,9 @@ __export(index_exports, {
|
|
|
113
109
|
onchainReceiveRequest: () => onchainReceiveRequest,
|
|
114
110
|
onchainSendRequest: () => onchainSendRequest,
|
|
115
111
|
paymentHashOf: () => paymentHashOf,
|
|
116
|
-
|
|
112
|
+
preimageForSwapRecord: () => preimageForSwapRecord,
|
|
117
113
|
pushClaim: () => pushClaim,
|
|
118
114
|
pushRefundWithoutReceiver: () => pushRefundWithoutReceiver,
|
|
119
|
-
randomSwapSecrets: () => randomSwapSecrets,
|
|
120
115
|
readLockupFate: () => readLockupFate,
|
|
121
116
|
receiveVtxoScript: () => receiveVtxoScript,
|
|
122
117
|
refundIfUnresolved: () => refundIfUnresolved,
|
|
@@ -129,15 +124,12 @@ __export(index_exports, {
|
|
|
129
124
|
restoreAssetSwaps: () => restoreAssetSwaps,
|
|
130
125
|
retireSettledOfferContracts: () => retireSettledOfferContracts,
|
|
131
126
|
rfqPair: () => rfqPair,
|
|
132
|
-
rfqSecretsOfRecord: () => rfqSecretsOfRecord,
|
|
133
|
-
rfqSecretsToRecord: () => rfqSecretsToRecord,
|
|
134
127
|
sealClaimPacket: () => sealClaimPacket,
|
|
135
|
-
senderIdentityForRfqSecrets: () => senderIdentityForRfqSecrets,
|
|
136
128
|
senderIdentityForSwapRecord: () => senderIdentityForSwapRecord,
|
|
137
|
-
senderPubkeyForRfqSecrets: () => senderPubkeyForRfqSecrets,
|
|
138
129
|
spendTxidsOf: () => spendTxidsOf,
|
|
139
130
|
spendUpdate: () => spendUpdate,
|
|
140
131
|
swapPrograms: () => swapPrograms,
|
|
132
|
+
swapSecretsToRecord: () => swapSecretsToRecord,
|
|
141
133
|
unilateralClaimDelay: () => unilateralClaimDelay,
|
|
142
134
|
unilateralRefundDelay: () => unilateralRefundDelay,
|
|
143
135
|
unilateralRefundWithoutReceiverDelay: () => unilateralRefundWithoutReceiverDelay,
|
|
@@ -151,9 +143,9 @@ __export(index_exports, {
|
|
|
151
143
|
module.exports = __toCommonJS(index_exports);
|
|
152
144
|
|
|
153
145
|
// src/offer.ts
|
|
154
|
-
var
|
|
146
|
+
var import_base2 = require("@scure/base");
|
|
155
147
|
var import_utils = require("@scure/btc-signer/utils.js");
|
|
156
|
-
var
|
|
148
|
+
var import_sdk2 = require("@arkade-os/sdk");
|
|
157
149
|
|
|
158
150
|
// src/swap-want-asset.program.json
|
|
159
151
|
var swap_want_asset_program_default = {
|
|
@@ -283,6 +275,9 @@ async function retireSettledOfferContracts(manager, swaps) {
|
|
|
283
275
|
}
|
|
284
276
|
|
|
285
277
|
// src/store.ts
|
|
278
|
+
var import_base = require("@scure/base");
|
|
279
|
+
var import_sha2 = require("@noble/hashes/sha2.js");
|
|
280
|
+
var import_sdk = require("@arkade-os/sdk");
|
|
286
281
|
var BTC_ASSET_ID = "btc";
|
|
287
282
|
var byNewest = (a, b) => b.createdAt - a.createdAt;
|
|
288
283
|
var getAssetSwapsOrThrow = async (repository) => {
|
|
@@ -335,11 +330,68 @@ var updateAssetSwapBestEffort = async (repository, id, changes) => {
|
|
|
335
330
|
return { swaps, persisted: false };
|
|
336
331
|
}
|
|
337
332
|
};
|
|
333
|
+
var swapSecretsToRecord = (secrets) => ({
|
|
334
|
+
signingDescriptor: secrets.descriptor,
|
|
335
|
+
..."mustPersistPreimage" in secrets && secrets.mustPersistPreimage ? { preimageHex: import_base.hex.encode(secrets.preimage) } : {},
|
|
336
|
+
..."preimageSalt" in secrets && secrets.preimageSalt ? { preimageSaltHex: import_base.hex.encode(secrets.preimageSalt) } : {}
|
|
337
|
+
});
|
|
338
|
+
var decodeHex32 = (value, field) => {
|
|
339
|
+
const bytes = import_base.hex.decode(value);
|
|
340
|
+
if (bytes.length !== 32) {
|
|
341
|
+
throw new Error(`${field} must be 32 bytes, got ${bytes.length}`);
|
|
342
|
+
}
|
|
343
|
+
return bytes;
|
|
344
|
+
};
|
|
345
|
+
var PreimageNotRecoverableError = class extends Error {
|
|
346
|
+
constructor(reason, message, options) {
|
|
347
|
+
super(message, options);
|
|
348
|
+
this.reason = reason;
|
|
349
|
+
}
|
|
350
|
+
reason;
|
|
351
|
+
name = "PreimageNotRecoverableError";
|
|
352
|
+
};
|
|
353
|
+
var preimageForSwapRecord = async (wallet, record) => {
|
|
354
|
+
if (!record.signingDescriptor) {
|
|
355
|
+
throw new PreimageNotRecoverableError(
|
|
356
|
+
"no-secrets",
|
|
357
|
+
"this swap record carries no signing descriptor"
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
let stored;
|
|
361
|
+
let salt;
|
|
362
|
+
try {
|
|
363
|
+
stored = record.preimageHex ? decodeHex32(record.preimageHex, "preimageHex") : void 0;
|
|
364
|
+
salt = record.preimageSaltHex ? decodeHex32(record.preimageSaltHex, "preimageSaltHex") : void 0;
|
|
365
|
+
} catch (cause) {
|
|
366
|
+
throw new PreimageNotRecoverableError(
|
|
367
|
+
"malformed-record",
|
|
368
|
+
`this swap record's secrets projection is unreadable: ${String(cause)}`,
|
|
369
|
+
{ cause }
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
let preimage;
|
|
373
|
+
try {
|
|
374
|
+
preimage = await (0, import_sdk.contractPreimage)(wallet, record.signingDescriptor, { stored, salt });
|
|
375
|
+
} catch (cause) {
|
|
376
|
+
throw new PreimageNotRecoverableError(
|
|
377
|
+
"not-derivable",
|
|
378
|
+
`this wallet cannot produce the preimage for ${record.signingDescriptor}`,
|
|
379
|
+
{ cause }
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
if (record.paymentHash && import_base.hex.encode((0, import_sha2.sha256)(preimage)) !== record.paymentHash.toLowerCase()) {
|
|
383
|
+
throw new PreimageNotRecoverableError(
|
|
384
|
+
"hash-mismatch",
|
|
385
|
+
"the derived preimage does not match this swap's payment hash: wrong wallet, or a tampered salt"
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
return preimage;
|
|
389
|
+
};
|
|
338
390
|
|
|
339
391
|
// src/offer.ts
|
|
340
392
|
var swapPrograms = {
|
|
341
|
-
wantAsset:
|
|
342
|
-
wantBtc:
|
|
393
|
+
wantAsset: import_sdk2.arkade.parseArtifact(swap_want_asset_program_default),
|
|
394
|
+
wantBtc: import_sdk2.arkade.parseArtifact(swap_want_btc_program_default)
|
|
343
395
|
};
|
|
344
396
|
function swapProgramBinding(offer, serverPubkey) {
|
|
345
397
|
if (offer.makerPkScript.length !== FIELDS.makerPkScript.width) {
|
|
@@ -367,7 +419,7 @@ function swapProgramBinding(offer, serverPubkey) {
|
|
|
367
419
|
}
|
|
368
420
|
function offerVtxoScript(offer, serverPubkey) {
|
|
369
421
|
const { program, args, keys } = swapProgramBinding(offer, serverPubkey);
|
|
370
|
-
return new
|
|
422
|
+
return new import_sdk2.arkade.ArkadeProgramScript(program, args, keys);
|
|
371
423
|
}
|
|
372
424
|
var OFFER_PACKET_TYPE = 3;
|
|
373
425
|
var FIELDS = {
|
|
@@ -449,8 +501,8 @@ function decodeOffer(data) {
|
|
|
449
501
|
return {
|
|
450
502
|
swapPkScript: need("swapPkScript"),
|
|
451
503
|
wantAmount: new DataView(amount.buffer, amount.byteOffset).getBigUint64(0, false),
|
|
452
|
-
...fields.wantAsset && { wantAsset:
|
|
453
|
-
...fields.offerAsset && { offerAsset:
|
|
504
|
+
...fields.wantAsset && { wantAsset: import_sdk2.asset.AssetId.fromBytes(fields.wantAsset) },
|
|
505
|
+
...fields.offerAsset && { offerAsset: import_sdk2.asset.AssetId.fromBytes(fields.offerAsset) },
|
|
454
506
|
makerPkScript: need("makerPkScript"),
|
|
455
507
|
makerPublicKey: need("makerPublicKey"),
|
|
456
508
|
emulatorPubkey: need("emulatorPubkey")
|
|
@@ -461,45 +513,45 @@ var OFFER_CONTRACT_KIND = "asset-swap-offer";
|
|
|
461
513
|
async function registerOfferContract(wallet, arkServerUrl, network, binding, serverPubkey, expectedPkScript) {
|
|
462
514
|
const { program, args, keys } = swapProgramBinding(binding, serverPubkey);
|
|
463
515
|
const contractManager = await wallet.getContractManager();
|
|
464
|
-
const client = await
|
|
465
|
-
arkade: new
|
|
466
|
-
indexer: new
|
|
516
|
+
const client = await import_sdk2.arkade.Arkade.connect({
|
|
517
|
+
arkade: new import_sdk2.RestArkProvider(arkServerUrl),
|
|
518
|
+
indexer: new import_sdk2.RestIndexerProvider(arkServerUrl),
|
|
467
519
|
identity: wallet.identity,
|
|
468
520
|
// without this the row's `address` would be derived against the SDK's
|
|
469
521
|
// default network while its script is right — a row that disagrees with
|
|
470
522
|
// the address the user is about to fund
|
|
471
|
-
network: (0,
|
|
523
|
+
network: (0, import_sdk2.getNetwork)(network),
|
|
472
524
|
contractManager
|
|
473
525
|
});
|
|
474
|
-
const contract = new
|
|
475
|
-
if (
|
|
526
|
+
const contract = new import_sdk2.arkade.ArkadeContract(client, program, args, keys);
|
|
527
|
+
if (import_base2.hex.encode(contract.pkScript) !== import_base2.hex.encode(expectedPkScript)) {
|
|
476
528
|
throw new Error("derived covenant does not match the offer's swapPkScript");
|
|
477
529
|
}
|
|
478
530
|
await contract.register({
|
|
479
531
|
label: OFFER_CONTRACT_LABEL,
|
|
480
532
|
metadata: { genericallySpendable: false, kind: OFFER_CONTRACT_KIND }
|
|
481
533
|
});
|
|
482
|
-
await promoteOfferContract(contractManager,
|
|
534
|
+
await promoteOfferContract(contractManager, import_base2.hex.encode(expectedPkScript));
|
|
483
535
|
}
|
|
484
536
|
async function createOffer(wallet, arkServerUrl, params) {
|
|
485
537
|
if (Boolean(params.wantAsset) === Boolean(params.offerAsset)) {
|
|
486
538
|
throw new Error("set exactly one of wantAsset (BTC->asset) or offerAsset (asset->BTC)");
|
|
487
539
|
}
|
|
488
540
|
const [info, makerAddress, makerPublicKey] = await Promise.all([
|
|
489
|
-
new
|
|
541
|
+
new import_sdk2.RestArkProvider(arkServerUrl).getInfo(),
|
|
490
542
|
wallet.getAddress(),
|
|
491
543
|
wallet.identity.xOnlyPublicKey()
|
|
492
544
|
]);
|
|
493
|
-
const serverPubKey =
|
|
494
|
-
const network = (0,
|
|
495
|
-
const emuKey =
|
|
496
|
-
(0,
|
|
545
|
+
const serverPubKey = import_base2.hex.decode((0, import_sdk2.toXOnlySignerHex)(info.signerPubkey));
|
|
546
|
+
const network = (0, import_sdk2.getNetwork)(info.network);
|
|
547
|
+
const emuKey = import_base2.hex.decode(
|
|
548
|
+
(0, import_sdk2.toXOnlySignerHex)((0, import_sdk2.resolveEmulatorPubkey)(network, params.emulatorPubkey))
|
|
497
549
|
);
|
|
498
550
|
const binding = {
|
|
499
551
|
wantAmount: params.wantAmount,
|
|
500
552
|
wantAsset: params.wantAsset,
|
|
501
553
|
offerAsset: params.offerAsset,
|
|
502
|
-
makerPkScript:
|
|
554
|
+
makerPkScript: import_sdk2.ArkAddress.decode(makerAddress).pkScript,
|
|
503
555
|
makerPublicKey,
|
|
504
556
|
emulatorPubkey: emuKey
|
|
505
557
|
};
|
|
@@ -515,7 +567,7 @@ async function createOffer(wallet, arkServerUrl, params) {
|
|
|
515
567
|
);
|
|
516
568
|
const payload = encodeOffer(offer);
|
|
517
569
|
return {
|
|
518
|
-
offerHex:
|
|
570
|
+
offerHex: import_base2.hex.encode(payload),
|
|
519
571
|
extension: { type: OFFER_PACKET_TYPE, payload },
|
|
520
572
|
// VtxoScript.address owns address construction; assembling an ArkAddress
|
|
521
573
|
// from tweakedPublicKey here would silently miss any future step it gains
|
|
@@ -525,11 +577,11 @@ async function createOffer(wallet, arkServerUrl, params) {
|
|
|
525
577
|
}
|
|
526
578
|
async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
|
|
527
579
|
const { repository, fundingTxid, swapAddress } = opts;
|
|
528
|
-
const offer = decodeOffer(
|
|
580
|
+
const offer = decodeOffer(import_base2.hex.decode(offerHex));
|
|
529
581
|
const contractManager = await wallet.getContractManager();
|
|
530
|
-
const client = await
|
|
531
|
-
arkade: new
|
|
532
|
-
indexer: new
|
|
582
|
+
const client = await import_sdk2.arkade.Arkade.connect({
|
|
583
|
+
arkade: new import_sdk2.RestArkProvider(arkServerUrl),
|
|
584
|
+
indexer: new import_sdk2.RestIndexerProvider(arkServerUrl),
|
|
533
585
|
identity: wallet.identity,
|
|
534
586
|
// registered offers resolve their VTXOs from the contract repository
|
|
535
587
|
// instead of a direct indexer query; the indexer above stays as the
|
|
@@ -539,15 +591,15 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
|
|
|
539
591
|
// script and the payout script comes from wallet.getAddress(), so the
|
|
540
592
|
// client's network (which only shapes address derivation) is unused here
|
|
541
593
|
});
|
|
542
|
-
const serverKey = swapAddress ?
|
|
594
|
+
const serverKey = swapAddress ? import_sdk2.ArkAddress.decode(swapAddress).serverPubKey : client.serverKey;
|
|
543
595
|
const { program, args, keys } = swapProgramBinding(offer, serverKey);
|
|
544
|
-
const rebuilt = new
|
|
545
|
-
if (
|
|
596
|
+
const rebuilt = new import_sdk2.arkade.ArkadeProgramScript(program, args, keys);
|
|
597
|
+
if (import_base2.hex.encode(rebuilt.pkScript) !== import_base2.hex.encode(offer.swapPkScript)) {
|
|
546
598
|
throw new Error(
|
|
547
599
|
"rebuilt covenant does not match the offer's swapPkScript \u2014 the server signing key has likely rotated since funding; pass swapAddress (the funded address) to pin the original key"
|
|
548
600
|
);
|
|
549
601
|
}
|
|
550
|
-
const contract = new
|
|
602
|
+
const contract = new import_sdk2.arkade.ArkadeContract(client, program, args, keys);
|
|
551
603
|
const [vtxos, makerAddress] = await Promise.all([contract.getUtxos(), wallet.getAddress()]);
|
|
552
604
|
if (!fundingTxid && vtxos.length > 1) {
|
|
553
605
|
throw new Error(
|
|
@@ -556,7 +608,7 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
|
|
|
556
608
|
}
|
|
557
609
|
const vtxo = fundingTxid ? vtxos.find((v) => v.txid === fundingTxid) : vtxos[0];
|
|
558
610
|
if (!vtxo) throw new Error("no spendable VTXO at the swap address");
|
|
559
|
-
const makerPkScript =
|
|
611
|
+
const makerPkScript = import_sdk2.ArkAddress.decode(makerAddress).pkScript;
|
|
560
612
|
const cancel = contract.functions.cancel().from({ txid: vtxo.txid, vout: vtxo.vout, value: vtxo.value }).to(makerPkScript, BigInt(vtxo.value));
|
|
561
613
|
for (const a of vtxo.assets ?? []) {
|
|
562
614
|
cancel.withAsset({
|
|
@@ -575,7 +627,7 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
|
|
|
575
627
|
spentTxid: txid
|
|
576
628
|
});
|
|
577
629
|
if (persisted) {
|
|
578
|
-
await retireOfferContract(contractManager, swaps,
|
|
630
|
+
await retireOfferContract(contractManager, swaps, import_base2.hex.encode(offer.swapPkScript));
|
|
579
631
|
}
|
|
580
632
|
}
|
|
581
633
|
return txid;
|
|
@@ -583,7 +635,7 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
|
|
|
583
635
|
|
|
584
636
|
// src/markets.ts
|
|
585
637
|
var import_solver_discovery = require("@arkade-os/solver-discovery");
|
|
586
|
-
var
|
|
638
|
+
var import_sdk3 = require("@arkade-os/sdk");
|
|
587
639
|
var QUOTE_OPTIONS = { safetyBps: 0 };
|
|
588
640
|
var makeCachedFeedFetch = (ttlMs = 3e4, fetchImpl = fetch) => {
|
|
589
641
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -700,7 +752,7 @@ var validatePlan = (plan, giveBalance, dust) => {
|
|
|
700
752
|
const receiveIsBtc = plan.receive.asset.id === BTC_ASSET_ID;
|
|
701
753
|
if (depositIsBtc || receiveIsBtc) {
|
|
702
754
|
const btcSide = depositIsBtc ? plan.deposit.atomic : plan.receive.atomic;
|
|
703
|
-
if ((0,
|
|
755
|
+
if ((0, import_sdk3.isSubdust)(btcSide, dust)) return "below-dust";
|
|
704
756
|
}
|
|
705
757
|
return void 0;
|
|
706
758
|
};
|
|
@@ -708,7 +760,7 @@ var validatePlan = (plan, giveBalance, dust) => {
|
|
|
708
760
|
// src/repository.ts
|
|
709
761
|
var marketsCacheKey = (network, registry) => `arkade-intents-markets-${network}-${registry}`;
|
|
710
762
|
var InMemoryAssetSwapRepository = class {
|
|
711
|
-
version =
|
|
763
|
+
version = 2;
|
|
712
764
|
swaps = /* @__PURE__ */ new Map();
|
|
713
765
|
scanned = /* @__PURE__ */ new Set();
|
|
714
766
|
markets = /* @__PURE__ */ new Map();
|
|
@@ -740,7 +792,7 @@ var InMemoryAssetSwapRepository = class {
|
|
|
740
792
|
};
|
|
741
793
|
|
|
742
794
|
// src/indexedDbRepository.ts
|
|
743
|
-
var
|
|
795
|
+
var import_sdk4 = require("@arkade-os/sdk");
|
|
744
796
|
var DEFAULT_DB_NAME = "arkade-intents";
|
|
745
797
|
var DB_VERSION = 1;
|
|
746
798
|
var STORE_SWAPS = "swaps";
|
|
@@ -770,7 +822,7 @@ var IndexedDbAssetSwapRepository = class {
|
|
|
770
822
|
this.dbName = dbName;
|
|
771
823
|
}
|
|
772
824
|
dbName;
|
|
773
|
-
version =
|
|
825
|
+
version = 2;
|
|
774
826
|
// the promise, not the resolved database: openDatabase bumps a refcount on
|
|
775
827
|
// every call including cache hits, while dispose closes once, so two
|
|
776
828
|
// concurrent first calls would strand the refcount above zero and leak the
|
|
@@ -778,7 +830,7 @@ var IndexedDbAssetSwapRepository = class {
|
|
|
778
830
|
// can be retried rather than cached forever.
|
|
779
831
|
dbPromise = null;
|
|
780
832
|
ensureDb() {
|
|
781
|
-
return this.dbPromise ??= (0,
|
|
833
|
+
return this.dbPromise ??= (0, import_sdk4.openDatabase)(this.dbName, DB_VERSION, initDatabase).catch(
|
|
782
834
|
(err) => {
|
|
783
835
|
this.dbPromise = null;
|
|
784
836
|
throw err;
|
|
@@ -835,14 +887,14 @@ var IndexedDbAssetSwapRepository = class {
|
|
|
835
887
|
}
|
|
836
888
|
async [Symbol.asyncDispose]() {
|
|
837
889
|
if (!this.dbPromise) return;
|
|
838
|
-
await (0,
|
|
890
|
+
await (0, import_sdk4.closeDatabase)(this.dbName);
|
|
839
891
|
this.dbPromise = null;
|
|
840
892
|
}
|
|
841
893
|
};
|
|
842
894
|
|
|
843
895
|
// src/restore.ts
|
|
844
|
-
var
|
|
845
|
-
var
|
|
896
|
+
var import_base3 = require("@scure/base");
|
|
897
|
+
var import_sdk5 = require("@arkade-os/sdk");
|
|
846
898
|
var TXS_PER_REQUEST = 50;
|
|
847
899
|
async function fetchParsedTxs(indexer, txids) {
|
|
848
900
|
const parsedByTxid = /* @__PURE__ */ new Map();
|
|
@@ -858,7 +910,7 @@ async function fetchParsedTxs(indexer, txids) {
|
|
|
858
910
|
if (result.status !== "fulfilled") continue;
|
|
859
911
|
for (const psbt of result.value) {
|
|
860
912
|
try {
|
|
861
|
-
const parsed =
|
|
913
|
+
const parsed = import_sdk5.Transaction.fromPSBT(import_base3.base64.decode(psbt));
|
|
862
914
|
parsedByTxid.set(parsed.id, parsed);
|
|
863
915
|
} catch {
|
|
864
916
|
}
|
|
@@ -873,7 +925,7 @@ function classifySpend(offer, serverPubkey, spendTx, deposit) {
|
|
|
873
925
|
let leaves;
|
|
874
926
|
try {
|
|
875
927
|
const script = offerVtxoScript(offer, serverPubkey);
|
|
876
|
-
if (
|
|
928
|
+
if (import_base3.hex.encode(script.pkScript) !== import_base3.hex.encode(offer.swapPkScript)) return "indeterminate";
|
|
877
929
|
leaves = {
|
|
878
930
|
cancel: script.functionByName("cancel")?.leafScript,
|
|
879
931
|
fulfill: script.functionByName("fulfill")?.leafScript
|
|
@@ -884,11 +936,11 @@ function classifySpend(offer, serverPubkey, spendTx, deposit) {
|
|
|
884
936
|
for (let i = 0; i < spendTx.inputsLength; i++) {
|
|
885
937
|
const input = spendTx.getInput(i);
|
|
886
938
|
if (!input.txid || input.index !== deposit.vout) continue;
|
|
887
|
-
if (
|
|
939
|
+
if (import_base3.hex.encode(input.txid) !== deposit.txid) continue;
|
|
888
940
|
for (const leaf of input.tapLeafScript ?? []) {
|
|
889
|
-
const spent =
|
|
890
|
-
if (leaves.cancel && spent ===
|
|
891
|
-
if (leaves.fulfill && spent ===
|
|
941
|
+
const spent = import_base3.hex.encode((0, import_sdk5.scriptFromTapLeafScript)(leaf));
|
|
942
|
+
if (leaves.cancel && spent === import_base3.hex.encode(leaves.cancel)) return "cancelled";
|
|
943
|
+
if (leaves.fulfill && spent === import_base3.hex.encode(leaves.fulfill)) return "fulfilled";
|
|
892
944
|
}
|
|
893
945
|
}
|
|
894
946
|
return "indeterminate";
|
|
@@ -917,19 +969,19 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
|
|
|
917
969
|
if (!fundingTx) continue;
|
|
918
970
|
fetchedTxids.push(txid);
|
|
919
971
|
try {
|
|
920
|
-
const packet =
|
|
972
|
+
const packet = import_sdk5.Extension.fromTx(parsed).getPacketByType(OFFER_PACKET_TYPE);
|
|
921
973
|
if (!packet) continue;
|
|
922
974
|
const payload = packet.serialize();
|
|
923
975
|
found.push({
|
|
924
976
|
fundingTx,
|
|
925
977
|
offer: decodeOffer(payload),
|
|
926
|
-
offerHex:
|
|
978
|
+
offerHex: import_base3.hex.encode(payload)
|
|
927
979
|
});
|
|
928
980
|
} catch {
|
|
929
981
|
}
|
|
930
982
|
}
|
|
931
983
|
if (found.length === 0) return { restored: [], scannedTxids: fetchedTxids };
|
|
932
|
-
const scripts = [...new Set(found.map((f) =>
|
|
984
|
+
const scripts = [...new Set(found.map((f) => import_base3.hex.encode(f.offer.swapPkScript)))];
|
|
933
985
|
const { vtxos } = await indexer.getVtxos({ scripts });
|
|
934
986
|
const vtxoByScriptAndTxid = new Map(vtxos.map((v) => [`${v.script}:${v.txid}`, v]));
|
|
935
987
|
const txByAnyId = /* @__PURE__ */ new Map();
|
|
@@ -941,7 +993,7 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
|
|
|
941
993
|
const spendTxids = /* @__PURE__ */ new Set();
|
|
942
994
|
for (const { fundingTx, offer } of found) {
|
|
943
995
|
const vtxo = vtxoByScriptAndTxid.get(
|
|
944
|
-
`${
|
|
996
|
+
`${import_base3.hex.encode(offer.swapPkScript)}:${fundingTx.redeemTxid}`
|
|
945
997
|
);
|
|
946
998
|
if (vtxo?.virtualStatus.state !== "spent") continue;
|
|
947
999
|
for (const txid of spendTxidsOf(vtxo)) spendTxids.add(txid);
|
|
@@ -950,7 +1002,7 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
|
|
|
950
1002
|
const restored = [];
|
|
951
1003
|
const unresolved = /* @__PURE__ */ new Set();
|
|
952
1004
|
for (const { fundingTx, offer, offerHex } of found) {
|
|
953
|
-
const swapPkScript =
|
|
1005
|
+
const swapPkScript = import_base3.hex.encode(offer.swapPkScript);
|
|
954
1006
|
const vtxo = vtxoByScriptAndTxid.get(`${swapPkScript}:${fundingTx.redeemTxid}`);
|
|
955
1007
|
if (!vtxo) {
|
|
956
1008
|
unresolved.add(fundingTx.redeemTxid);
|
|
@@ -1007,8 +1059,8 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
|
|
|
1007
1059
|
}
|
|
1008
1060
|
|
|
1009
1061
|
// src/watch.ts
|
|
1010
|
-
var
|
|
1011
|
-
var
|
|
1062
|
+
var import_base4 = require("@scure/base");
|
|
1063
|
+
var import_sdk6 = require("@arkade-os/sdk");
|
|
1012
1064
|
var TERMINAL = ["fulfilled", "cancelled", "recoverable"];
|
|
1013
1065
|
function spendUpdate(swap, spend) {
|
|
1014
1066
|
if (TERMINAL.includes(swap.status)) return void 0;
|
|
@@ -1028,8 +1080,8 @@ async function watchOfferSwaps({
|
|
|
1028
1080
|
onUpdate
|
|
1029
1081
|
}) {
|
|
1030
1082
|
const manager = await wallet.getContractManager();
|
|
1031
|
-
const serverPubkey =
|
|
1032
|
-
const indexer = new
|
|
1083
|
+
const serverPubkey = import_sdk6.ArkAddress.decode(await wallet.getAddress()).serverPubKey;
|
|
1084
|
+
const indexer = new import_sdk6.RestIndexerProvider(arkServerUrl);
|
|
1033
1085
|
let queue = Promise.resolve();
|
|
1034
1086
|
const enqueue = (task) => {
|
|
1035
1087
|
queue = queue.then(task).catch(() => {
|
|
@@ -1042,9 +1094,9 @@ async function watchOfferSwaps({
|
|
|
1042
1094
|
if (candidates.length === 0) return "indeterminate";
|
|
1043
1095
|
const { txs } = await indexer.getVirtualTxs(candidates);
|
|
1044
1096
|
return classifyDepositSpend(
|
|
1045
|
-
decodeOffer(
|
|
1097
|
+
decodeOffer(import_base4.hex.decode(swap.offerHex)),
|
|
1046
1098
|
serverPubkey,
|
|
1047
|
-
txs.map((psbt) =>
|
|
1099
|
+
txs.map((psbt) => import_sdk6.Transaction.fromPSBT(import_base4.base64.decode(psbt))),
|
|
1048
1100
|
{ txid: vtxo.txid, vout: vtxo.vout }
|
|
1049
1101
|
);
|
|
1050
1102
|
} catch {
|
|
@@ -1091,8 +1143,8 @@ var import_legacy2 = require("@noble/hashes/legacy.js");
|
|
|
1091
1143
|
var import_sdk8 = require("@arkade-os/sdk");
|
|
1092
1144
|
|
|
1093
1145
|
// src/onchainHtlc.ts
|
|
1094
|
-
var
|
|
1095
|
-
var
|
|
1146
|
+
var import_base5 = require("@scure/base");
|
|
1147
|
+
var import_sha22 = require("@noble/hashes/sha2.js");
|
|
1096
1148
|
var import_legacy = require("@noble/hashes/legacy.js");
|
|
1097
1149
|
var btc = __toESM(require("@scure/btc-signer"), 1);
|
|
1098
1150
|
var ONCHAIN_ORDER_MARGIN_SECONDS = 2 * 60 * 60;
|
|
@@ -1101,8 +1153,8 @@ var MAX_MIN_CONFIRMATIONS = 6;
|
|
|
1101
1153
|
var ONCHAIN_SECONDS_PER_BLOCK = 600;
|
|
1102
1154
|
var ONCHAIN_DUST_SATS = BigInt(330);
|
|
1103
1155
|
var newPreimage = () => crypto.getRandomValues(new Uint8Array(32));
|
|
1104
|
-
var paymentHashOf = (preimage) =>
|
|
1105
|
-
var h160FromPaymentHash = (paymentHash) => (0, import_legacy.ripemd160)(
|
|
1156
|
+
var paymentHashOf = (preimage) => import_base5.hex.encode((0, import_sha22.sha256)(preimage));
|
|
1157
|
+
var h160FromPaymentHash = (paymentHash) => (0, import_legacy.ripemd160)(import_base5.hex.decode(paymentHash));
|
|
1106
1158
|
var L1_NETWORKS = {
|
|
1107
1159
|
bitcoin: btc.NETWORK,
|
|
1108
1160
|
testnet: btc.TEST_NETWORK,
|
|
@@ -1143,7 +1195,7 @@ function onchainHtlcScript(params, network) {
|
|
|
1143
1195
|
);
|
|
1144
1196
|
const controlBlockFor = (leaf) => {
|
|
1145
1197
|
for (const [block, script] of payment.tapLeafScript ?? []) {
|
|
1146
|
-
if (script.length - 1 === leaf.length &&
|
|
1198
|
+
if (script.length - 1 === leaf.length && import_base5.hex.encode(script.subarray(0, leaf.length)) === import_base5.hex.encode(leaf)) {
|
|
1147
1199
|
return btc.TaprootControlBlock.encode(block);
|
|
1148
1200
|
}
|
|
1149
1201
|
}
|
|
@@ -1236,13 +1288,13 @@ var buildHtlcRefund = (input) => buildLeafSpend({
|
|
|
1236
1288
|
function extractPreimage(txHex, paymentHash) {
|
|
1237
1289
|
let raw;
|
|
1238
1290
|
try {
|
|
1239
|
-
raw = btc.RawTx.decode(
|
|
1291
|
+
raw = btc.RawTx.decode(import_base5.hex.decode(txHex));
|
|
1240
1292
|
} catch {
|
|
1241
1293
|
return null;
|
|
1242
1294
|
}
|
|
1243
1295
|
for (const stack of raw.witnesses ?? []) {
|
|
1244
1296
|
for (const item of stack) {
|
|
1245
|
-
if (item.length === 32 &&
|
|
1297
|
+
if (item.length === 32 && import_base5.hex.encode((0, import_sha22.sha256)(item)) === paymentHash) return item;
|
|
1246
1298
|
}
|
|
1247
1299
|
}
|
|
1248
1300
|
return null;
|
|
@@ -1283,7 +1335,7 @@ async function classifyOnchainHtlc(chain, input) {
|
|
|
1283
1335
|
const spend = await chain.getSpendingTx(input.funding.txid, input.funding.vout);
|
|
1284
1336
|
if (!spend) return { phase: "unfunded" };
|
|
1285
1337
|
const preimage = extractPreimage(spend.txHex, input.htlc.paymentHash);
|
|
1286
|
-
const txid = btc.Transaction.fromRaw(
|
|
1338
|
+
const txid = btc.Transaction.fromRaw(import_base5.hex.decode(spend.txHex), {
|
|
1287
1339
|
allowUnknownInputs: true,
|
|
1288
1340
|
allowUnknownOutputs: true
|
|
1289
1341
|
}).id;
|
|
@@ -1296,177 +1348,19 @@ async function classifyOnchainHtlc(chain, input) {
|
|
|
1296
1348
|
return { phase: "claimable", utxo: best };
|
|
1297
1349
|
}
|
|
1298
1350
|
|
|
1299
|
-
// src/
|
|
1300
|
-
var
|
|
1301
|
-
var import_sha22 = require("@noble/hashes/sha2.js");
|
|
1302
|
-
var import_utils2 = require("@noble/hashes/utils.js");
|
|
1303
|
-
var import_secp256k1 = require("@noble/curves/secp256k1.js");
|
|
1304
|
-
var import_sdk6 = require("@arkade-os/sdk");
|
|
1305
|
-
var RFQ_PREIMAGE_TAG = "Arkade-RFQ-Preimage-v1";
|
|
1306
|
-
function buildPreimageMessage(xonly, index) {
|
|
1307
|
-
if (xonly.length !== 32) {
|
|
1308
|
-
throw new Error(`x-only pubkey must be 32 bytes, got ${xonly.length}`);
|
|
1309
|
-
}
|
|
1310
|
-
if (!Number.isInteger(index) || index < 0 || index > 4294967295) {
|
|
1311
|
-
throw new Error(`index must be a u32, got ${index}`);
|
|
1312
|
-
}
|
|
1313
|
-
const tag = new TextEncoder().encode(RFQ_PREIMAGE_TAG);
|
|
1314
|
-
const message = new Uint8Array(tag.length + 32 + 4);
|
|
1315
|
-
message.set(tag, 0);
|
|
1316
|
-
message.set(xonly, tag.length);
|
|
1317
|
-
new DataView(message.buffer).setUint32(tag.length + 32, index, true);
|
|
1318
|
-
return message;
|
|
1319
|
-
}
|
|
1320
|
-
var PREIMAGE_INDEX = 0;
|
|
1321
|
-
async function deriveSwapSecrets(wallet) {
|
|
1322
|
-
if (!(0, import_sdk6.isHDAllocationCapable)(wallet)) return void 0;
|
|
1323
|
-
const signingDescriptor = await wallet.getNextSigningDescriptor();
|
|
1324
|
-
if (!signingDescriptor) return void 0;
|
|
1325
|
-
return { derivable: true, signingDescriptor };
|
|
1326
|
-
}
|
|
1327
|
-
function randomSwapSecrets(opts = {}) {
|
|
1328
|
-
if (opts.preimage instanceof Uint8Array && opts.preimage.length !== 32) {
|
|
1329
|
-
throw new Error(`preimage must be 32 bytes, got ${opts.preimage.length}`);
|
|
1330
|
-
}
|
|
1331
|
-
const preimage = opts.preimage instanceof Uint8Array ? opts.preimage : opts.preimage ? (0, import_utils2.randomBytes)(32) : void 0;
|
|
1332
|
-
return {
|
|
1333
|
-
derivable: false,
|
|
1334
|
-
senderPrivateKey: import_secp256k1.schnorr.utils.randomSecretKey(),
|
|
1335
|
-
...preimage ? { preimage } : {}
|
|
1336
|
-
};
|
|
1337
|
-
}
|
|
1338
|
-
function rfqSecretsToRecord(secrets) {
|
|
1339
|
-
if (secrets.derivable) {
|
|
1340
|
-
return {
|
|
1341
|
-
signingDescriptor: secrets.signingDescriptor,
|
|
1342
|
-
...secrets.preimage ? { preimageHex: import_base5.hex.encode(secrets.preimage) } : {}
|
|
1343
|
-
};
|
|
1344
|
-
}
|
|
1345
|
-
return {
|
|
1346
|
-
fallbackSecrets: {
|
|
1347
|
-
version: 1,
|
|
1348
|
-
type: "stored",
|
|
1349
|
-
senderPrivateKeyHex: import_base5.hex.encode(secrets.senderPrivateKey),
|
|
1350
|
-
...secrets.preimage ? { preimageHex: import_base5.hex.encode(secrets.preimage) } : {}
|
|
1351
|
-
}
|
|
1352
|
-
};
|
|
1353
|
-
}
|
|
1354
|
-
function rfqSecretsOfRecord(record) {
|
|
1355
|
-
if (record.signingDescriptor) {
|
|
1356
|
-
return {
|
|
1357
|
-
derivable: true,
|
|
1358
|
-
signingDescriptor: record.signingDescriptor,
|
|
1359
|
-
...record.preimageHex ? { preimage: decodeHex32(record.preimageHex, "preimageHex") } : {}
|
|
1360
|
-
};
|
|
1361
|
-
}
|
|
1362
|
-
const fallback = record.fallbackSecrets;
|
|
1363
|
-
if (!fallback) return void 0;
|
|
1364
|
-
if (fallback.version !== 1 || fallback.type !== "stored") {
|
|
1365
|
-
throw new Error("unsupported RFQ fallback secrets record");
|
|
1366
|
-
}
|
|
1367
|
-
return {
|
|
1368
|
-
derivable: false,
|
|
1369
|
-
senderPrivateKey: decodeHex32(fallback.senderPrivateKeyHex, "senderPrivateKeyHex"),
|
|
1370
|
-
...fallback.preimageHex ? { preimage: decodeHex32(fallback.preimageHex, "preimageHex") } : {}
|
|
1371
|
-
};
|
|
1372
|
-
}
|
|
1373
|
-
function decodeHex32(value, label) {
|
|
1374
|
-
const bytes = import_base5.hex.decode(value);
|
|
1375
|
-
if (bytes.length !== 32) {
|
|
1376
|
-
throw new Error(label + " must be 32 bytes, got " + bytes.length);
|
|
1377
|
-
}
|
|
1378
|
-
return bytes;
|
|
1379
|
-
}
|
|
1380
|
-
async function adoptSwapDescriptor(wallet, signingDescriptor) {
|
|
1381
|
-
if (!(0, import_sdk6.isHDAllocationCapable)(wallet)) return;
|
|
1382
|
-
await wallet.advanceSigningDescriptorWatermark(signingDescriptor);
|
|
1383
|
-
}
|
|
1384
|
-
var RefundNotLocallyPossibleError = class extends Error {
|
|
1385
|
-
constructor(reason, message, options) {
|
|
1386
|
-
super(message, options);
|
|
1387
|
-
this.reason = reason;
|
|
1388
|
-
}
|
|
1389
|
-
reason;
|
|
1390
|
-
name = "RefundNotLocallyPossibleError";
|
|
1391
|
-
};
|
|
1392
|
-
async function senderIdentityForRfqSecrets(wallet, secrets) {
|
|
1393
|
-
if (!secrets.derivable) return import_sdk6.SingleKey.fromPrivateKey(secrets.senderPrivateKey);
|
|
1394
|
-
const signer = (0, import_sdk6.isHDWalletCapable)(wallet) ? await wallet.signerForDescriptor(secrets.signingDescriptor) : void 0;
|
|
1395
|
-
if (!signer || !isDeterministicSigner(signer)) {
|
|
1396
|
-
throw new RefundNotLocallyPossibleError(
|
|
1397
|
-
"foreign-descriptor",
|
|
1398
|
-
`this wallet cannot derive ${secrets.signingDescriptor}; the swap was created on another wallet`
|
|
1399
|
-
);
|
|
1400
|
-
}
|
|
1401
|
-
return signer;
|
|
1402
|
-
}
|
|
1403
|
-
async function senderIdentityForSwapRecord(wallet, record) {
|
|
1404
|
-
let secrets;
|
|
1405
|
-
try {
|
|
1406
|
-
secrets = rfqSecretsOfRecord(record);
|
|
1407
|
-
} catch (error) {
|
|
1408
|
-
throw new RefundNotLocallyPossibleError(
|
|
1409
|
-
"unreadable-secrets",
|
|
1410
|
-
error instanceof Error ? error.message : String(error),
|
|
1411
|
-
// the record's own diagnosis, kept for a caller that wants more
|
|
1412
|
-
// than the message
|
|
1413
|
-
{ cause: error }
|
|
1414
|
-
);
|
|
1415
|
-
}
|
|
1416
|
-
if (!secrets) {
|
|
1417
|
-
throw new RefundNotLocallyPossibleError(
|
|
1418
|
-
"no-secrets",
|
|
1419
|
-
"this swap record carries no signing descriptor and no fallback secrets"
|
|
1420
|
-
);
|
|
1421
|
-
}
|
|
1422
|
-
return senderIdentityForRfqSecrets(wallet, secrets);
|
|
1423
|
-
}
|
|
1424
|
-
async function senderPubkeyForRfqSecrets(wallet, secrets) {
|
|
1425
|
-
if (!secrets.derivable) return import_secp256k1.schnorr.getPublicKey(secrets.senderPrivateKey);
|
|
1426
|
-
return (await senderIdentityForRfqSecrets(wallet, secrets)).xOnlyPublicKey();
|
|
1427
|
-
}
|
|
1428
|
-
function isDeterministicSigner(value) {
|
|
1429
|
-
if (typeof value !== "object" || value === null) return false;
|
|
1430
|
-
const v = value;
|
|
1431
|
-
return typeof v.signSchnorrDeterministic === "function" && typeof v.xOnlyPublicKey === "function";
|
|
1432
|
-
}
|
|
1433
|
-
async function derivePreimage(signer) {
|
|
1434
|
-
const xonly = await signer.xOnlyPublicKey();
|
|
1435
|
-
const message = buildPreimageMessage(xonly, PREIMAGE_INDEX);
|
|
1436
|
-
return (0, import_sha22.sha256)(await signer.signSchnorrDeterministic((0, import_sha22.sha256)(message)));
|
|
1437
|
-
}
|
|
1438
|
-
async function preimageForRfqSecrets(wallet, secrets) {
|
|
1439
|
-
if (!secrets.derivable) {
|
|
1440
|
-
if (!secrets.preimage) throw new Error("this swap carries no stored preimage");
|
|
1441
|
-
return secrets.preimage;
|
|
1442
|
-
}
|
|
1443
|
-
if (secrets.preimage) return secrets.preimage;
|
|
1444
|
-
const signer = await senderIdentityForRfqSecrets(wallet, secrets);
|
|
1445
|
-
if (!isDeterministicSigner(signer)) {
|
|
1446
|
-
throw new Error(
|
|
1447
|
-
`wallet cannot sign deterministically for ${secrets.signingDescriptor}; its preimage is not derivable`
|
|
1448
|
-
);
|
|
1449
|
-
}
|
|
1450
|
-
try {
|
|
1451
|
-
return await derivePreimage(signer);
|
|
1452
|
-
} catch (cause) {
|
|
1453
|
-
throw new Error(
|
|
1454
|
-
`wallet cannot sign deterministically for ${secrets.signingDescriptor}; its preimage is not derivable`,
|
|
1455
|
-
{ cause }
|
|
1456
|
-
);
|
|
1457
|
-
}
|
|
1458
|
-
}
|
|
1351
|
+
// src/rfq.ts
|
|
1352
|
+
var import_sdk9 = require("@arkade-os/sdk");
|
|
1459
1353
|
|
|
1460
1354
|
// src/claimPacket.ts
|
|
1461
1355
|
var import_base6 = require("@scure/base");
|
|
1462
|
-
var
|
|
1356
|
+
var import_secp256k1 = require("@noble/curves/secp256k1.js");
|
|
1463
1357
|
var import_hkdf = require("@noble/hashes/hkdf.js");
|
|
1464
1358
|
var import_sha23 = require("@noble/hashes/sha2.js");
|
|
1465
1359
|
var HKDF_INFO = new TextEncoder().encode("covclaimd/preimage/v1");
|
|
1466
1360
|
async function sealClaimPacket(input) {
|
|
1467
1361
|
return sealWithEntropy(
|
|
1468
1362
|
input,
|
|
1469
|
-
|
|
1363
|
+
import_secp256k1.secp256k1.utils.randomSecretKey(),
|
|
1470
1364
|
crypto.getRandomValues(new Uint8Array(12))
|
|
1471
1365
|
);
|
|
1472
1366
|
}
|
|
@@ -1475,8 +1369,8 @@ async function sealWithEntropy(input, ephemeralKey, nonce) {
|
|
|
1475
1369
|
if (input.covclaimdPubkey.length !== 33) {
|
|
1476
1370
|
throw new Error("covclaimd pubkey must be 33-byte compressed");
|
|
1477
1371
|
}
|
|
1478
|
-
const ephemeralPub =
|
|
1479
|
-
const sharedX =
|
|
1372
|
+
const ephemeralPub = import_secp256k1.secp256k1.getPublicKey(ephemeralKey, true);
|
|
1373
|
+
const sharedX = import_secp256k1.secp256k1.getSharedSecret(ephemeralKey, input.covclaimdPubkey, true).subarray(1);
|
|
1480
1374
|
const key = (0, import_hkdf.hkdf)(import_sha23.sha256, sharedX, ephemeralPub, HKDF_INFO, 32);
|
|
1481
1375
|
if (nonce.length !== 12) throw new Error("nonce must be 12 bytes");
|
|
1482
1376
|
const aesKey = await crypto.subtle.importKey("raw", key, "AES-GCM", false, [
|
|
@@ -1786,21 +1680,22 @@ var relayTransport = (relayUrl, options) => {
|
|
|
1786
1680
|
};
|
|
1787
1681
|
};
|
|
1788
1682
|
var SEQUENCE_GRANULARITY_SECONDS = 512;
|
|
1683
|
+
var SOLO_REFUND_HEADROOM_SECONDS = 8 * SEQUENCE_GRANULARITY_SECONDS;
|
|
1789
1684
|
var unilateralClaimDelay = (serverExitDelaySeconds) => {
|
|
1790
1685
|
if (!Number.isFinite(serverExitDelaySeconds) || serverExitDelaySeconds < SEQUENCE_GRANULARITY_SECONDS) {
|
|
1791
1686
|
throw new Error(
|
|
1792
1687
|
`server exit delay must be at least ${SEQUENCE_GRANULARITY_SECONDS}s of seconds, got ${serverExitDelaySeconds}`
|
|
1793
1688
|
);
|
|
1794
1689
|
}
|
|
1795
|
-
if (serverExitDelaySeconds >
|
|
1690
|
+
if (serverExitDelaySeconds > 65535 * SEQUENCE_GRANULARITY_SECONDS - SOLO_REFUND_HEADROOM_SECONDS) {
|
|
1796
1691
|
throw new Error(
|
|
1797
|
-
`server exit delay ${serverExitDelaySeconds}s exceeds what BIP68 can encode once the
|
|
1692
|
+
`server exit delay ${serverExitDelaySeconds}s exceeds what BIP68 can encode once the solo refund's headroom is stacked above it`
|
|
1798
1693
|
);
|
|
1799
1694
|
}
|
|
1800
1695
|
return Math.ceil(serverExitDelaySeconds / SEQUENCE_GRANULARITY_SECONDS) * SEQUENCE_GRANULARITY_SECONDS;
|
|
1801
1696
|
};
|
|
1802
|
-
var unilateralRefundDelay = (claimDelay) => claimDelay
|
|
1803
|
-
var unilateralRefundWithoutReceiverDelay = (claimDelay) => claimDelay +
|
|
1697
|
+
var unilateralRefundDelay = (claimDelay) => claimDelay;
|
|
1698
|
+
var unilateralRefundWithoutReceiverDelay = (claimDelay) => claimDelay + SOLO_REFUND_HEADROOM_SECONDS;
|
|
1804
1699
|
function lightningSendVtxoScript(params) {
|
|
1805
1700
|
const seconds = (value) => ({
|
|
1806
1701
|
type: "seconds",
|
|
@@ -1829,13 +1724,8 @@ function lightningSendVtxoScript(params) {
|
|
|
1829
1724
|
}
|
|
1830
1725
|
async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
1831
1726
|
const rfqId = params.rfqId ?? newRfqId();
|
|
1832
|
-
const secrets = await
|
|
1833
|
-
|
|
1834
|
-
console.warn(
|
|
1835
|
-
"[swap] wallet cannot allocate an HD descriptor: the sender key is random and MUST be persisted before funding"
|
|
1836
|
-
);
|
|
1837
|
-
}
|
|
1838
|
-
const senderPubkey = await senderPubkeyForRfqSecrets(wallet, secrets);
|
|
1727
|
+
const secrets = await (0, import_sdk9.provisionRefundKey)(wallet);
|
|
1728
|
+
const senderPubkey = secrets.pubkey;
|
|
1839
1729
|
const [info, refundAddress] = await Promise.all([
|
|
1840
1730
|
new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
|
|
1841
1731
|
wallet.getAddress()
|
|
@@ -1995,23 +1885,14 @@ function deriveOnchainSend(input) {
|
|
|
1995
1885
|
}
|
|
1996
1886
|
async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
|
|
1997
1887
|
const rfqId = params.rfqId ?? newRfqId();
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
}
|
|
2001
|
-
const derivedSecrets = await deriveSwapSecrets(wallet);
|
|
2002
|
-
const secrets = derivedSecrets ? params.preimage ? { ...derivedSecrets, preimage: params.preimage } : derivedSecrets : randomSwapSecrets({ preimage: params.preimage ?? true });
|
|
2003
|
-
if (!secrets.derivable) {
|
|
1888
|
+
const secrets = await (0, import_sdk9.provisionClaimSecret)(wallet, { preimage: params.preimage });
|
|
1889
|
+
if (secrets.mustPersistPreimage) {
|
|
2004
1890
|
console.warn(
|
|
2005
|
-
|
|
2006
|
-
);
|
|
2007
|
-
} else if (params.preimage) {
|
|
2008
|
-
console.warn(
|
|
2009
|
-
"[swap] this swap's preimage was supplied by the caller and MUST be persisted with the signing descriptor before funding"
|
|
1891
|
+
"[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before funding"
|
|
2010
1892
|
);
|
|
2011
1893
|
}
|
|
2012
|
-
const
|
|
2013
|
-
const
|
|
2014
|
-
const senderPubkey = await senderPubkeyForRfqSecrets(wallet, secrets);
|
|
1894
|
+
const paymentHash = import_base8.hex.encode(secrets.paymentHash);
|
|
1895
|
+
const senderPubkey = secrets.pubkey;
|
|
2015
1896
|
const [info, refundAddress] = await Promise.all([
|
|
2016
1897
|
new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
|
|
2017
1898
|
wallet.getAddress()
|
|
@@ -2189,15 +2070,15 @@ function deriveLightningReceive(input) {
|
|
|
2189
2070
|
}
|
|
2190
2071
|
async function requestLightningReceive(wallet, arkServerUrl, transport, params) {
|
|
2191
2072
|
const rfqId = params.rfqId ?? newRfqId();
|
|
2192
|
-
const secrets = await
|
|
2193
|
-
if (
|
|
2073
|
+
const secrets = await (0, import_sdk9.provisionClaimSecret)(wallet);
|
|
2074
|
+
if (secrets.mustPersistPreimage) {
|
|
2194
2075
|
console.warn(
|
|
2195
|
-
"[swap] this swap's preimage
|
|
2076
|
+
"[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before paying"
|
|
2196
2077
|
);
|
|
2197
2078
|
}
|
|
2198
|
-
const preimage =
|
|
2199
|
-
const paymentHash =
|
|
2200
|
-
const payoutPubkey =
|
|
2079
|
+
const preimage = secrets.preimage;
|
|
2080
|
+
const paymentHash = import_base8.hex.encode(secrets.paymentHash);
|
|
2081
|
+
const payoutPubkey = secrets.pubkey;
|
|
2201
2082
|
const [info, payoutAddress] = await Promise.all([
|
|
2202
2083
|
new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
|
|
2203
2084
|
wallet.getAddress()
|
|
@@ -2307,15 +2188,15 @@ function deriveOnchainReceive(input) {
|
|
|
2307
2188
|
}
|
|
2308
2189
|
async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
|
|
2309
2190
|
const rfqId = params.rfqId ?? newRfqId();
|
|
2310
|
-
const secrets = await
|
|
2311
|
-
if (
|
|
2191
|
+
const secrets = await (0, import_sdk9.provisionClaimSecret)(wallet);
|
|
2192
|
+
if (secrets.mustPersistPreimage) {
|
|
2312
2193
|
console.warn(
|
|
2313
|
-
"[swap] this swap's preimage
|
|
2194
|
+
"[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before funding"
|
|
2314
2195
|
);
|
|
2315
2196
|
}
|
|
2316
|
-
const preimage =
|
|
2317
|
-
const paymentHash =
|
|
2318
|
-
const payoutPubkey =
|
|
2197
|
+
const preimage = secrets.preimage;
|
|
2198
|
+
const paymentHash = import_base8.hex.encode(secrets.paymentHash);
|
|
2199
|
+
const payoutPubkey = secrets.pubkey;
|
|
2319
2200
|
const [info, payoutAddress] = await Promise.all([
|
|
2320
2201
|
new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
|
|
2321
2202
|
wallet.getAddress()
|
|
@@ -2386,12 +2267,12 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
|
|
|
2386
2267
|
var import_base10 = require("@scure/base");
|
|
2387
2268
|
var import_legacy3 = require("@noble/hashes/legacy.js");
|
|
2388
2269
|
var import_sha25 = require("@noble/hashes/sha2.js");
|
|
2389
|
-
var
|
|
2270
|
+
var import_sdk11 = require("@arkade-os/sdk");
|
|
2390
2271
|
|
|
2391
2272
|
// src/refund.ts
|
|
2392
2273
|
var import_base9 = require("@scure/base");
|
|
2393
2274
|
var import_sha24 = require("@noble/hashes/sha2.js");
|
|
2394
|
-
var
|
|
2275
|
+
var import_sdk10 = require("@arkade-os/sdk");
|
|
2395
2276
|
var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2396
2277
|
var isRfqTerminal = (state) => RFQ_TERMINAL_STATES.includes(state);
|
|
2397
2278
|
var RFQ_RESOLVED_STATES = ["settled", "refunded"];
|
|
@@ -2465,7 +2346,7 @@ async function findLockupVtxos(indexer, swapPkScript) {
|
|
|
2465
2346
|
}
|
|
2466
2347
|
var hashesTo = (candidate, paymentHash) => import_base9.hex.encode((0, import_sha24.sha256)(candidate)) === paymentHash;
|
|
2467
2348
|
var candidateWitnessItems = (tx, inputIndex) => [
|
|
2468
|
-
...(0,
|
|
2349
|
+
...(0, import_sdk10.getArkPsbtFields)(tx, inputIndex, import_sdk10.ConditionWitness).flat(),
|
|
2469
2350
|
...tx.getInput(inputIndex).finalScriptWitness ?? []
|
|
2470
2351
|
];
|
|
2471
2352
|
async function readLockupFate(indexer, input) {
|
|
@@ -2484,7 +2365,7 @@ async function readLockupFate(indexer, input) {
|
|
|
2484
2365
|
for (const raw of txs) {
|
|
2485
2366
|
let tx;
|
|
2486
2367
|
try {
|
|
2487
|
-
tx =
|
|
2368
|
+
tx = import_sdk10.Transaction.fromPSBT(import_base9.base64.decode(raw));
|
|
2488
2369
|
} catch {
|
|
2489
2370
|
continue;
|
|
2490
2371
|
}
|
|
@@ -2521,14 +2402,14 @@ async function pushRefundWithoutReceiver(ark, input) {
|
|
|
2521
2402
|
const info = await ark.getInfo();
|
|
2522
2403
|
let serverUnrollScript;
|
|
2523
2404
|
try {
|
|
2524
|
-
serverUnrollScript =
|
|
2405
|
+
serverUnrollScript = import_sdk10.CSVMultisigTapscript.decode(import_base9.hex.decode(info.checkpointTapscript));
|
|
2525
2406
|
} catch {
|
|
2526
2407
|
throw new Error("invalid checkpointTapscript from the Arkade server");
|
|
2527
2408
|
}
|
|
2528
2409
|
const leaf = input.script.refundWithoutReceiver();
|
|
2529
2410
|
const tapTree = input.script.encode();
|
|
2530
2411
|
const amount = input.vtxos.reduce((sum, vtxo) => sum + vtxo.value, 0);
|
|
2531
|
-
const { arkTx, checkpoints } = (0,
|
|
2412
|
+
const { arkTx, checkpoints } = (0, import_sdk10.buildOffchainTx)(
|
|
2532
2413
|
input.vtxos.map((vtxo) => ({
|
|
2533
2414
|
txid: vtxo.txid,
|
|
2534
2415
|
vout: vtxo.vout,
|
|
@@ -2544,8 +2425,8 @@ async function pushRefundWithoutReceiver(ark, input) {
|
|
|
2544
2425
|
import_base9.base64.encode(signedArkTx.toPSBT()),
|
|
2545
2426
|
checkpoints.map((c) => import_base9.base64.encode(c.toPSBT()))
|
|
2546
2427
|
);
|
|
2547
|
-
(0,
|
|
2548
|
-
const matched = (0,
|
|
2428
|
+
(0, import_sdk10.assertSubmittedArkTxid)(submitted, signedArkTx, "refundWithoutReceiver");
|
|
2429
|
+
const matched = (0, import_sdk10.matchServerCheckpoints)(
|
|
2549
2430
|
submitted.signedCheckpointTxs,
|
|
2550
2431
|
checkpoints,
|
|
2551
2432
|
"refundWithoutReceiver"
|
|
@@ -2638,14 +2519,14 @@ async function pushClaim(ark, input) {
|
|
|
2638
2519
|
const info = await ark.getInfo();
|
|
2639
2520
|
let serverUnrollScript;
|
|
2640
2521
|
try {
|
|
2641
|
-
serverUnrollScript =
|
|
2522
|
+
serverUnrollScript = import_sdk11.CSVMultisigTapscript.decode(import_base10.hex.decode(info.checkpointTapscript));
|
|
2642
2523
|
} catch {
|
|
2643
2524
|
throw new Error("invalid checkpointTapscript from the Arkade server");
|
|
2644
2525
|
}
|
|
2645
2526
|
const leaf = input.script.claim();
|
|
2646
2527
|
const tapTree = input.script.encode();
|
|
2647
|
-
const arkTxid = await (0,
|
|
2648
|
-
identity: (0,
|
|
2528
|
+
const arkTxid = await (0, import_sdk11.signAndSubmitOffchainTx)({
|
|
2529
|
+
identity: (0, import_sdk11.claimWithPreimageIdentity)(input.receiver, input.preimage),
|
|
2649
2530
|
provider: ark,
|
|
2650
2531
|
inputs: input.vtxos.map((vtxo) => ({
|
|
2651
2532
|
txid: vtxo.txid,
|
|
@@ -2691,6 +2572,44 @@ async function claimReceiveLockup(indexer, ark, input) {
|
|
|
2691
2572
|
});
|
|
2692
2573
|
}
|
|
2693
2574
|
|
|
2575
|
+
// src/refundBlocked.ts
|
|
2576
|
+
var import_sdk12 = require("@arkade-os/sdk");
|
|
2577
|
+
var RefundNotLocallyPossibleError = class extends Error {
|
|
2578
|
+
constructor(reason, message, options) {
|
|
2579
|
+
super(message, options);
|
|
2580
|
+
this.reason = reason;
|
|
2581
|
+
}
|
|
2582
|
+
reason;
|
|
2583
|
+
name = "RefundNotLocallyPossibleError";
|
|
2584
|
+
};
|
|
2585
|
+
async function senderIdentityForSwapRecord(wallet, record) {
|
|
2586
|
+
if (!record.signingDescriptor) {
|
|
2587
|
+
throw new RefundNotLocallyPossibleError(
|
|
2588
|
+
"no-secrets",
|
|
2589
|
+
"this swap record carries no signing descriptor"
|
|
2590
|
+
);
|
|
2591
|
+
}
|
|
2592
|
+
try {
|
|
2593
|
+
return await (0, import_sdk12.contractSigner)(wallet, record.signingDescriptor);
|
|
2594
|
+
} catch (cause) {
|
|
2595
|
+
if (cause instanceof import_sdk12.WalletCannotSignError) {
|
|
2596
|
+
throw new RefundNotLocallyPossibleError(
|
|
2597
|
+
"unsignable-wallet",
|
|
2598
|
+
`this wallet holds ${record.signingDescriptor} but cannot sign with it; attach its signer`,
|
|
2599
|
+
{ cause }
|
|
2600
|
+
);
|
|
2601
|
+
}
|
|
2602
|
+
if (cause instanceof import_sdk12.ForeignDescriptorError) {
|
|
2603
|
+
throw new RefundNotLocallyPossibleError(
|
|
2604
|
+
"foreign-descriptor",
|
|
2605
|
+
`this wallet cannot derive ${record.signingDescriptor}; the swap was created on another wallet`,
|
|
2606
|
+
{ cause }
|
|
2607
|
+
);
|
|
2608
|
+
}
|
|
2609
|
+
throw cause;
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
|
|
2694
2613
|
// src/swapManager.ts
|
|
2695
2614
|
var import_base11 = require("@scure/base");
|
|
2696
2615
|
var RFQ_SWAP_TERMINAL_STATES = ["settled", "refunded", "failed"];
|
|
@@ -3482,20 +3401,20 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3482
3401
|
ONCHAIN_RECEIVE_PAIR,
|
|
3483
3402
|
ONCHAIN_SECONDS_PER_BLOCK,
|
|
3484
3403
|
ONCHAIN_SEND_PAIR,
|
|
3404
|
+
PreimageNotRecoverableError,
|
|
3485
3405
|
QUOTE_OPTIONS,
|
|
3486
3406
|
REFUND_MTP_LAG_SECONDS,
|
|
3487
|
-
RFQ_PREIMAGE_TAG,
|
|
3488
3407
|
RFQ_RESOLVED_STATES,
|
|
3489
3408
|
RFQ_SWAP_TERMINAL_STATES,
|
|
3490
3409
|
RFQ_TERMINAL_STATES,
|
|
3491
3410
|
RefundNotLocallyPossibleError,
|
|
3492
3411
|
RfqSwapManager,
|
|
3412
|
+
SOLO_REFUND_HEADROOM_SECONDS,
|
|
3493
3413
|
SWAP_LOCKUP_CONTRACT_KIND,
|
|
3494
3414
|
SWAP_LOCKUP_CONTRACT_LABEL,
|
|
3495
3415
|
SWAP_LOCKUP_CONTRACT_TYPE,
|
|
3496
3416
|
SwapRefusal,
|
|
3497
3417
|
addAssetSwap,
|
|
3498
|
-
adoptSwapDescriptor,
|
|
3499
3418
|
arkadeSwapRequest,
|
|
3500
3419
|
assertFundable,
|
|
3501
3420
|
assertReceivable,
|
|
@@ -3504,7 +3423,6 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3504
3423
|
awaitRfqResolution,
|
|
3505
3424
|
buildHtlcClaim,
|
|
3506
3425
|
buildHtlcRefund,
|
|
3507
|
-
buildPreimageMessage,
|
|
3508
3426
|
cancelOffer,
|
|
3509
3427
|
claimOnchainFill,
|
|
3510
3428
|
claimReceiveLockup,
|
|
@@ -3516,8 +3434,6 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3516
3434
|
deriveLightningReceive,
|
|
3517
3435
|
deriveOnchainReceive,
|
|
3518
3436
|
deriveOnchainSend,
|
|
3519
|
-
derivePreimage,
|
|
3520
|
-
deriveSwapSecrets,
|
|
3521
3437
|
discoverMarkets,
|
|
3522
3438
|
encodeOffer,
|
|
3523
3439
|
extractPreimage,
|
|
@@ -3526,7 +3442,6 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3526
3442
|
getAssetSwaps,
|
|
3527
3443
|
getAssetSwapsOrThrow,
|
|
3528
3444
|
httpTransport,
|
|
3529
|
-
isDeterministicSigner,
|
|
3530
3445
|
isRfqSwapTerminal,
|
|
3531
3446
|
isRfqTerminal,
|
|
3532
3447
|
lightningReceiveRequest,
|
|
@@ -3542,10 +3457,9 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3542
3457
|
onchainReceiveRequest,
|
|
3543
3458
|
onchainSendRequest,
|
|
3544
3459
|
paymentHashOf,
|
|
3545
|
-
|
|
3460
|
+
preimageForSwapRecord,
|
|
3546
3461
|
pushClaim,
|
|
3547
3462
|
pushRefundWithoutReceiver,
|
|
3548
|
-
randomSwapSecrets,
|
|
3549
3463
|
readLockupFate,
|
|
3550
3464
|
receiveVtxoScript,
|
|
3551
3465
|
refundIfUnresolved,
|
|
@@ -3558,15 +3472,12 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3558
3472
|
restoreAssetSwaps,
|
|
3559
3473
|
retireSettledOfferContracts,
|
|
3560
3474
|
rfqPair,
|
|
3561
|
-
rfqSecretsOfRecord,
|
|
3562
|
-
rfqSecretsToRecord,
|
|
3563
3475
|
sealClaimPacket,
|
|
3564
|
-
senderIdentityForRfqSecrets,
|
|
3565
3476
|
senderIdentityForSwapRecord,
|
|
3566
|
-
senderPubkeyForRfqSecrets,
|
|
3567
3477
|
spendTxidsOf,
|
|
3568
3478
|
spendUpdate,
|
|
3569
3479
|
swapPrograms,
|
|
3480
|
+
swapSecretsToRecord,
|
|
3570
3481
|
unilateralClaimDelay,
|
|
3571
3482
|
unilateralRefundDelay,
|
|
3572
3483
|
unilateralRefundWithoutReceiverDelay,
|