@arkade-os/swap 0.0.4 → 0.0.6
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 +201 -40
- package/dist/{chunk-DLM6BVTB.js → chunk-Q4FAYBXS.js} +6 -4
- package/dist/chunk-WGRU2DBF.js +38 -0
- package/dist/index.cjs +211 -93
- package/dist/index.d.cts +47 -151
- package/dist/index.d.ts +47 -151
- package/dist/index.js +125 -41
- package/dist/nostr.cjs +11 -0
- package/dist/nostr.d.cts +17 -4
- package/dist/nostr.d.ts +17 -4
- package/dist/nostr.js +9 -1
- package/dist/repositories/realm/index.cjs +138 -0
- package/dist/repositories/realm/index.d.cts +103 -0
- package/dist/repositories/realm/index.d.ts +103 -0
- package/dist/repositories/realm/index.js +108 -0
- package/dist/repositories/sqlite/index.cjs +163 -0
- package/dist/repositories/sqlite/index.d.cts +63 -0
- package/dist/repositories/sqlite/index.d.ts +63 -0
- package/dist/repositories/sqlite/index.js +138 -0
- package/dist/repository-BwnZ8N62.d.cts +236 -0
- package/dist/repository-BwnZ8N62.d.ts +236 -0
- package/dist/{rfq-DjZlesr4.d.cts → rfq-3jWha5xA.d.cts} +40 -16
- package/dist/{rfq-DjZlesr4.d.ts → rfq-3jWha5xA.d.ts} +40 -16
- package/package.json +24 -4
package/dist/index.cjs
CHANGED
|
@@ -53,6 +53,7 @@ __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
59
|
RFQ_RESOLVED_STATES: () => RFQ_RESOLVED_STATES,
|
|
@@ -60,6 +61,7 @@ __export(index_exports, {
|
|
|
60
61
|
RFQ_TERMINAL_STATES: () => RFQ_TERMINAL_STATES,
|
|
61
62
|
RefundNotLocallyPossibleError: () => RefundNotLocallyPossibleError,
|
|
62
63
|
RfqSwapManager: () => RfqSwapManager,
|
|
64
|
+
SOLO_REFUND_HEADROOM_SECONDS: () => SOLO_REFUND_HEADROOM_SECONDS,
|
|
63
65
|
SWAP_LOCKUP_CONTRACT_KIND: () => SWAP_LOCKUP_CONTRACT_KIND,
|
|
64
66
|
SWAP_LOCKUP_CONTRACT_LABEL: () => SWAP_LOCKUP_CONTRACT_LABEL,
|
|
65
67
|
SWAP_LOCKUP_CONTRACT_TYPE: () => SWAP_LOCKUP_CONTRACT_TYPE,
|
|
@@ -107,6 +109,7 @@ __export(index_exports, {
|
|
|
107
109
|
onchainReceiveRequest: () => onchainReceiveRequest,
|
|
108
110
|
onchainSendRequest: () => onchainSendRequest,
|
|
109
111
|
paymentHashOf: () => paymentHashOf,
|
|
112
|
+
preimageForSwapRecord: () => preimageForSwapRecord,
|
|
110
113
|
pushClaim: () => pushClaim,
|
|
111
114
|
pushRefundWithoutReceiver: () => pushRefundWithoutReceiver,
|
|
112
115
|
readLockupFate: () => readLockupFate,
|
|
@@ -125,6 +128,7 @@ __export(index_exports, {
|
|
|
125
128
|
senderIdentityForSwapRecord: () => senderIdentityForSwapRecord,
|
|
126
129
|
spendTxidsOf: () => spendTxidsOf,
|
|
127
130
|
spendUpdate: () => spendUpdate,
|
|
131
|
+
swapActivityResolver: () => swapActivityResolver,
|
|
128
132
|
swapPrograms: () => swapPrograms,
|
|
129
133
|
swapSecretsToRecord: () => swapSecretsToRecord,
|
|
130
134
|
unilateralClaimDelay: () => unilateralClaimDelay,
|
|
@@ -142,7 +146,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
142
146
|
// src/offer.ts
|
|
143
147
|
var import_base2 = require("@scure/base");
|
|
144
148
|
var import_utils = require("@scure/btc-signer/utils.js");
|
|
145
|
-
var
|
|
149
|
+
var import_sdk2 = require("@arkade-os/sdk");
|
|
146
150
|
|
|
147
151
|
// src/swap-want-asset.program.json
|
|
148
152
|
var swap_want_asset_program_default = {
|
|
@@ -273,6 +277,8 @@ async function retireSettledOfferContracts(manager, swaps) {
|
|
|
273
277
|
|
|
274
278
|
// src/store.ts
|
|
275
279
|
var import_base = require("@scure/base");
|
|
280
|
+
var import_sha2 = require("@noble/hashes/sha2.js");
|
|
281
|
+
var import_sdk = require("@arkade-os/sdk");
|
|
276
282
|
var BTC_ASSET_ID = "btc";
|
|
277
283
|
var byNewest = (a, b) => b.createdAt - a.createdAt;
|
|
278
284
|
var getAssetSwapsOrThrow = async (repository) => {
|
|
@@ -327,13 +333,66 @@ var updateAssetSwapBestEffort = async (repository, id, changes) => {
|
|
|
327
333
|
};
|
|
328
334
|
var swapSecretsToRecord = (secrets) => ({
|
|
329
335
|
signingDescriptor: secrets.descriptor,
|
|
330
|
-
..."mustPersistPreimage" in secrets && secrets.mustPersistPreimage ? { preimageHex: import_base.hex.encode(secrets.preimage) } : {}
|
|
336
|
+
..."mustPersistPreimage" in secrets && secrets.mustPersistPreimage ? { preimageHex: import_base.hex.encode(secrets.preimage) } : {},
|
|
337
|
+
..."preimageSalt" in secrets && secrets.preimageSalt ? { preimageSaltHex: import_base.hex.encode(secrets.preimageSalt) } : {}
|
|
331
338
|
});
|
|
339
|
+
var decodeHex32 = (value, field) => {
|
|
340
|
+
const bytes = import_base.hex.decode(value);
|
|
341
|
+
if (bytes.length !== 32) {
|
|
342
|
+
throw new Error(`${field} must be 32 bytes, got ${bytes.length}`);
|
|
343
|
+
}
|
|
344
|
+
return bytes;
|
|
345
|
+
};
|
|
346
|
+
var PreimageNotRecoverableError = class extends Error {
|
|
347
|
+
constructor(reason, message, options) {
|
|
348
|
+
super(message, options);
|
|
349
|
+
this.reason = reason;
|
|
350
|
+
}
|
|
351
|
+
reason;
|
|
352
|
+
name = "PreimageNotRecoverableError";
|
|
353
|
+
};
|
|
354
|
+
var preimageForSwapRecord = async (wallet, record) => {
|
|
355
|
+
if (!record.signingDescriptor) {
|
|
356
|
+
throw new PreimageNotRecoverableError(
|
|
357
|
+
"no-secrets",
|
|
358
|
+
"this swap record carries no signing descriptor"
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
let stored;
|
|
362
|
+
let salt;
|
|
363
|
+
try {
|
|
364
|
+
stored = record.preimageHex ? decodeHex32(record.preimageHex, "preimageHex") : void 0;
|
|
365
|
+
salt = record.preimageSaltHex ? decodeHex32(record.preimageSaltHex, "preimageSaltHex") : void 0;
|
|
366
|
+
} catch (cause) {
|
|
367
|
+
throw new PreimageNotRecoverableError(
|
|
368
|
+
"malformed-record",
|
|
369
|
+
`this swap record's secrets projection is unreadable: ${String(cause)}`,
|
|
370
|
+
{ cause }
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
let preimage;
|
|
374
|
+
try {
|
|
375
|
+
preimage = await (0, import_sdk.contractPreimage)(wallet, record.signingDescriptor, { stored, salt });
|
|
376
|
+
} catch (cause) {
|
|
377
|
+
throw new PreimageNotRecoverableError(
|
|
378
|
+
"not-derivable",
|
|
379
|
+
`this wallet cannot produce the preimage for ${record.signingDescriptor}`,
|
|
380
|
+
{ cause }
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
if (record.paymentHash && import_base.hex.encode((0, import_sha2.sha256)(preimage)) !== record.paymentHash.toLowerCase()) {
|
|
384
|
+
throw new PreimageNotRecoverableError(
|
|
385
|
+
"hash-mismatch",
|
|
386
|
+
"the derived preimage does not match this swap's payment hash: wrong wallet, or a tampered salt"
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
return preimage;
|
|
390
|
+
};
|
|
332
391
|
|
|
333
392
|
// src/offer.ts
|
|
334
393
|
var swapPrograms = {
|
|
335
|
-
wantAsset:
|
|
336
|
-
wantBtc:
|
|
394
|
+
wantAsset: import_sdk2.arkade.parseArtifact(swap_want_asset_program_default),
|
|
395
|
+
wantBtc: import_sdk2.arkade.parseArtifact(swap_want_btc_program_default)
|
|
337
396
|
};
|
|
338
397
|
function swapProgramBinding(offer, serverPubkey) {
|
|
339
398
|
if (offer.makerPkScript.length !== FIELDS.makerPkScript.width) {
|
|
@@ -361,7 +420,7 @@ function swapProgramBinding(offer, serverPubkey) {
|
|
|
361
420
|
}
|
|
362
421
|
function offerVtxoScript(offer, serverPubkey) {
|
|
363
422
|
const { program, args, keys } = swapProgramBinding(offer, serverPubkey);
|
|
364
|
-
return new
|
|
423
|
+
return new import_sdk2.arkade.ArkadeProgramScript(program, args, keys);
|
|
365
424
|
}
|
|
366
425
|
var OFFER_PACKET_TYPE = 3;
|
|
367
426
|
var FIELDS = {
|
|
@@ -443,8 +502,8 @@ function decodeOffer(data) {
|
|
|
443
502
|
return {
|
|
444
503
|
swapPkScript: need("swapPkScript"),
|
|
445
504
|
wantAmount: new DataView(amount.buffer, amount.byteOffset).getBigUint64(0, false),
|
|
446
|
-
...fields.wantAsset && { wantAsset:
|
|
447
|
-
...fields.offerAsset && { offerAsset:
|
|
505
|
+
...fields.wantAsset && { wantAsset: import_sdk2.asset.AssetId.fromBytes(fields.wantAsset) },
|
|
506
|
+
...fields.offerAsset && { offerAsset: import_sdk2.asset.AssetId.fromBytes(fields.offerAsset) },
|
|
448
507
|
makerPkScript: need("makerPkScript"),
|
|
449
508
|
makerPublicKey: need("makerPublicKey"),
|
|
450
509
|
emulatorPubkey: need("emulatorPubkey")
|
|
@@ -455,17 +514,17 @@ var OFFER_CONTRACT_KIND = "asset-swap-offer";
|
|
|
455
514
|
async function registerOfferContract(wallet, arkServerUrl, network, binding, serverPubkey, expectedPkScript) {
|
|
456
515
|
const { program, args, keys } = swapProgramBinding(binding, serverPubkey);
|
|
457
516
|
const contractManager = await wallet.getContractManager();
|
|
458
|
-
const client = await
|
|
459
|
-
arkade: new
|
|
460
|
-
indexer: new
|
|
517
|
+
const client = await import_sdk2.arkade.Arkade.connect({
|
|
518
|
+
arkade: new import_sdk2.RestArkProvider(arkServerUrl),
|
|
519
|
+
indexer: new import_sdk2.RestIndexerProvider(arkServerUrl),
|
|
461
520
|
identity: wallet.identity,
|
|
462
521
|
// without this the row's `address` would be derived against the SDK's
|
|
463
522
|
// default network while its script is right — a row that disagrees with
|
|
464
523
|
// the address the user is about to fund
|
|
465
|
-
network: (0,
|
|
524
|
+
network: (0, import_sdk2.getNetwork)(network),
|
|
466
525
|
contractManager
|
|
467
526
|
});
|
|
468
|
-
const contract = new
|
|
527
|
+
const contract = new import_sdk2.arkade.ArkadeContract(client, program, args, keys);
|
|
469
528
|
if (import_base2.hex.encode(contract.pkScript) !== import_base2.hex.encode(expectedPkScript)) {
|
|
470
529
|
throw new Error("derived covenant does not match the offer's swapPkScript");
|
|
471
530
|
}
|
|
@@ -480,20 +539,20 @@ async function createOffer(wallet, arkServerUrl, params) {
|
|
|
480
539
|
throw new Error("set exactly one of wantAsset (BTC->asset) or offerAsset (asset->BTC)");
|
|
481
540
|
}
|
|
482
541
|
const [info, makerAddress, makerPublicKey] = await Promise.all([
|
|
483
|
-
new
|
|
542
|
+
new import_sdk2.RestArkProvider(arkServerUrl).getInfo(),
|
|
484
543
|
wallet.getAddress(),
|
|
485
544
|
wallet.identity.xOnlyPublicKey()
|
|
486
545
|
]);
|
|
487
|
-
const serverPubKey = import_base2.hex.decode((0,
|
|
488
|
-
const network = (0,
|
|
546
|
+
const serverPubKey = import_base2.hex.decode((0, import_sdk2.toXOnlySignerHex)(info.signerPubkey));
|
|
547
|
+
const network = (0, import_sdk2.getNetwork)(info.network);
|
|
489
548
|
const emuKey = import_base2.hex.decode(
|
|
490
|
-
(0,
|
|
549
|
+
(0, import_sdk2.toXOnlySignerHex)((0, import_sdk2.resolveEmulatorPubkey)(network, params.emulatorPubkey))
|
|
491
550
|
);
|
|
492
551
|
const binding = {
|
|
493
552
|
wantAmount: params.wantAmount,
|
|
494
553
|
wantAsset: params.wantAsset,
|
|
495
554
|
offerAsset: params.offerAsset,
|
|
496
|
-
makerPkScript:
|
|
555
|
+
makerPkScript: import_sdk2.ArkAddress.decode(makerAddress).pkScript,
|
|
497
556
|
makerPublicKey,
|
|
498
557
|
emulatorPubkey: emuKey
|
|
499
558
|
};
|
|
@@ -521,9 +580,9 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
|
|
|
521
580
|
const { repository, fundingTxid, swapAddress } = opts;
|
|
522
581
|
const offer = decodeOffer(import_base2.hex.decode(offerHex));
|
|
523
582
|
const contractManager = await wallet.getContractManager();
|
|
524
|
-
const client = await
|
|
525
|
-
arkade: new
|
|
526
|
-
indexer: new
|
|
583
|
+
const client = await import_sdk2.arkade.Arkade.connect({
|
|
584
|
+
arkade: new import_sdk2.RestArkProvider(arkServerUrl),
|
|
585
|
+
indexer: new import_sdk2.RestIndexerProvider(arkServerUrl),
|
|
527
586
|
identity: wallet.identity,
|
|
528
587
|
// registered offers resolve their VTXOs from the contract repository
|
|
529
588
|
// instead of a direct indexer query; the indexer above stays as the
|
|
@@ -533,15 +592,15 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
|
|
|
533
592
|
// script and the payout script comes from wallet.getAddress(), so the
|
|
534
593
|
// client's network (which only shapes address derivation) is unused here
|
|
535
594
|
});
|
|
536
|
-
const serverKey = swapAddress ?
|
|
595
|
+
const serverKey = swapAddress ? import_sdk2.ArkAddress.decode(swapAddress).serverPubKey : client.serverKey;
|
|
537
596
|
const { program, args, keys } = swapProgramBinding(offer, serverKey);
|
|
538
|
-
const rebuilt = new
|
|
597
|
+
const rebuilt = new import_sdk2.arkade.ArkadeProgramScript(program, args, keys);
|
|
539
598
|
if (import_base2.hex.encode(rebuilt.pkScript) !== import_base2.hex.encode(offer.swapPkScript)) {
|
|
540
599
|
throw new Error(
|
|
541
600
|
"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"
|
|
542
601
|
);
|
|
543
602
|
}
|
|
544
|
-
const contract = new
|
|
603
|
+
const contract = new import_sdk2.arkade.ArkadeContract(client, program, args, keys);
|
|
545
604
|
const [vtxos, makerAddress] = await Promise.all([contract.getUtxos(), wallet.getAddress()]);
|
|
546
605
|
if (!fundingTxid && vtxos.length > 1) {
|
|
547
606
|
throw new Error(
|
|
@@ -550,7 +609,7 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
|
|
|
550
609
|
}
|
|
551
610
|
const vtxo = fundingTxid ? vtxos.find((v) => v.txid === fundingTxid) : vtxos[0];
|
|
552
611
|
if (!vtxo) throw new Error("no spendable VTXO at the swap address");
|
|
553
|
-
const makerPkScript =
|
|
612
|
+
const makerPkScript = import_sdk2.ArkAddress.decode(makerAddress).pkScript;
|
|
554
613
|
const cancel = contract.functions.cancel().from({ txid: vtxo.txid, vout: vtxo.vout, value: vtxo.value }).to(makerPkScript, BigInt(vtxo.value));
|
|
555
614
|
for (const a of vtxo.assets ?? []) {
|
|
556
615
|
cancel.withAsset({
|
|
@@ -577,7 +636,7 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
|
|
|
577
636
|
|
|
578
637
|
// src/markets.ts
|
|
579
638
|
var import_solver_discovery = require("@arkade-os/solver-discovery");
|
|
580
|
-
var
|
|
639
|
+
var import_sdk3 = require("@arkade-os/sdk");
|
|
581
640
|
var QUOTE_OPTIONS = { safetyBps: 0 };
|
|
582
641
|
var makeCachedFeedFetch = (ttlMs = 3e4, fetchImpl = fetch) => {
|
|
583
642
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -694,7 +753,7 @@ var validatePlan = (plan, giveBalance, dust) => {
|
|
|
694
753
|
const receiveIsBtc = plan.receive.asset.id === BTC_ASSET_ID;
|
|
695
754
|
if (depositIsBtc || receiveIsBtc) {
|
|
696
755
|
const btcSide = depositIsBtc ? plan.deposit.atomic : plan.receive.atomic;
|
|
697
|
-
if ((0,
|
|
756
|
+
if ((0, import_sdk3.isSubdust)(btcSide, dust)) return "below-dust";
|
|
698
757
|
}
|
|
699
758
|
return void 0;
|
|
700
759
|
};
|
|
@@ -702,7 +761,7 @@ var validatePlan = (plan, giveBalance, dust) => {
|
|
|
702
761
|
// src/repository.ts
|
|
703
762
|
var marketsCacheKey = (network, registry) => `arkade-intents-markets-${network}-${registry}`;
|
|
704
763
|
var InMemoryAssetSwapRepository = class {
|
|
705
|
-
version =
|
|
764
|
+
version = 2;
|
|
706
765
|
swaps = /* @__PURE__ */ new Map();
|
|
707
766
|
scanned = /* @__PURE__ */ new Set();
|
|
708
767
|
markets = /* @__PURE__ */ new Map();
|
|
@@ -734,7 +793,7 @@ var InMemoryAssetSwapRepository = class {
|
|
|
734
793
|
};
|
|
735
794
|
|
|
736
795
|
// src/indexedDbRepository.ts
|
|
737
|
-
var
|
|
796
|
+
var import_sdk4 = require("@arkade-os/sdk");
|
|
738
797
|
var DEFAULT_DB_NAME = "arkade-intents";
|
|
739
798
|
var DB_VERSION = 1;
|
|
740
799
|
var STORE_SWAPS = "swaps";
|
|
@@ -764,7 +823,7 @@ var IndexedDbAssetSwapRepository = class {
|
|
|
764
823
|
this.dbName = dbName;
|
|
765
824
|
}
|
|
766
825
|
dbName;
|
|
767
|
-
version =
|
|
826
|
+
version = 2;
|
|
768
827
|
// the promise, not the resolved database: openDatabase bumps a refcount on
|
|
769
828
|
// every call including cache hits, while dispose closes once, so two
|
|
770
829
|
// concurrent first calls would strand the refcount above zero and leak the
|
|
@@ -772,7 +831,7 @@ var IndexedDbAssetSwapRepository = class {
|
|
|
772
831
|
// can be retried rather than cached forever.
|
|
773
832
|
dbPromise = null;
|
|
774
833
|
ensureDb() {
|
|
775
|
-
return this.dbPromise ??= (0,
|
|
834
|
+
return this.dbPromise ??= (0, import_sdk4.openDatabase)(this.dbName, DB_VERSION, initDatabase).catch(
|
|
776
835
|
(err) => {
|
|
777
836
|
this.dbPromise = null;
|
|
778
837
|
throw err;
|
|
@@ -829,14 +888,14 @@ var IndexedDbAssetSwapRepository = class {
|
|
|
829
888
|
}
|
|
830
889
|
async [Symbol.asyncDispose]() {
|
|
831
890
|
if (!this.dbPromise) return;
|
|
832
|
-
await (0,
|
|
891
|
+
await (0, import_sdk4.closeDatabase)(this.dbName);
|
|
833
892
|
this.dbPromise = null;
|
|
834
893
|
}
|
|
835
894
|
};
|
|
836
895
|
|
|
837
896
|
// src/restore.ts
|
|
838
897
|
var import_base3 = require("@scure/base");
|
|
839
|
-
var
|
|
898
|
+
var import_sdk5 = require("@arkade-os/sdk");
|
|
840
899
|
var TXS_PER_REQUEST = 50;
|
|
841
900
|
async function fetchParsedTxs(indexer, txids) {
|
|
842
901
|
const parsedByTxid = /* @__PURE__ */ new Map();
|
|
@@ -852,7 +911,7 @@ async function fetchParsedTxs(indexer, txids) {
|
|
|
852
911
|
if (result.status !== "fulfilled") continue;
|
|
853
912
|
for (const psbt of result.value) {
|
|
854
913
|
try {
|
|
855
|
-
const parsed =
|
|
914
|
+
const parsed = import_sdk5.Transaction.fromPSBT(import_base3.base64.decode(psbt));
|
|
856
915
|
parsedByTxid.set(parsed.id, parsed);
|
|
857
916
|
} catch {
|
|
858
917
|
}
|
|
@@ -880,7 +939,7 @@ function classifySpend(offer, serverPubkey, spendTx, deposit) {
|
|
|
880
939
|
if (!input.txid || input.index !== deposit.vout) continue;
|
|
881
940
|
if (import_base3.hex.encode(input.txid) !== deposit.txid) continue;
|
|
882
941
|
for (const leaf of input.tapLeafScript ?? []) {
|
|
883
|
-
const spent = import_base3.hex.encode((0,
|
|
942
|
+
const spent = import_base3.hex.encode((0, import_sdk5.scriptFromTapLeafScript)(leaf));
|
|
884
943
|
if (leaves.cancel && spent === import_base3.hex.encode(leaves.cancel)) return "cancelled";
|
|
885
944
|
if (leaves.fulfill && spent === import_base3.hex.encode(leaves.fulfill)) return "fulfilled";
|
|
886
945
|
}
|
|
@@ -911,7 +970,7 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
|
|
|
911
970
|
if (!fundingTx) continue;
|
|
912
971
|
fetchedTxids.push(txid);
|
|
913
972
|
try {
|
|
914
|
-
const packet =
|
|
973
|
+
const packet = import_sdk5.Extension.fromTx(parsed).getPacketByType(OFFER_PACKET_TYPE);
|
|
915
974
|
if (!packet) continue;
|
|
916
975
|
const payload = packet.serialize();
|
|
917
976
|
found.push({
|
|
@@ -1002,7 +1061,7 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
|
|
|
1002
1061
|
|
|
1003
1062
|
// src/watch.ts
|
|
1004
1063
|
var import_base4 = require("@scure/base");
|
|
1005
|
-
var
|
|
1064
|
+
var import_sdk6 = require("@arkade-os/sdk");
|
|
1006
1065
|
var TERMINAL = ["fulfilled", "cancelled", "recoverable"];
|
|
1007
1066
|
function spendUpdate(swap, spend) {
|
|
1008
1067
|
if (TERMINAL.includes(swap.status)) return void 0;
|
|
@@ -1022,8 +1081,8 @@ async function watchOfferSwaps({
|
|
|
1022
1081
|
onUpdate
|
|
1023
1082
|
}) {
|
|
1024
1083
|
const manager = await wallet.getContractManager();
|
|
1025
|
-
const serverPubkey =
|
|
1026
|
-
const indexer = new
|
|
1084
|
+
const serverPubkey = import_sdk6.ArkAddress.decode(await wallet.getAddress()).serverPubKey;
|
|
1085
|
+
const indexer = new import_sdk6.RestIndexerProvider(arkServerUrl);
|
|
1027
1086
|
let queue = Promise.resolve();
|
|
1028
1087
|
const enqueue = (task) => {
|
|
1029
1088
|
queue = queue.then(task).catch(() => {
|
|
@@ -1038,7 +1097,7 @@ async function watchOfferSwaps({
|
|
|
1038
1097
|
return classifyDepositSpend(
|
|
1039
1098
|
decodeOffer(import_base4.hex.decode(swap.offerHex)),
|
|
1040
1099
|
serverPubkey,
|
|
1041
|
-
txs.map((psbt) =>
|
|
1100
|
+
txs.map((psbt) => import_sdk6.Transaction.fromPSBT(import_base4.base64.decode(psbt))),
|
|
1042
1101
|
{ txid: vtxo.txid, vout: vtxo.vout }
|
|
1043
1102
|
);
|
|
1044
1103
|
} catch {
|
|
@@ -1082,11 +1141,11 @@ async function watchOfferSwaps({
|
|
|
1082
1141
|
// src/rfq.ts
|
|
1083
1142
|
var import_base8 = require("@scure/base");
|
|
1084
1143
|
var import_legacy2 = require("@noble/hashes/legacy.js");
|
|
1085
|
-
var
|
|
1144
|
+
var import_sdk8 = require("@arkade-os/sdk");
|
|
1086
1145
|
|
|
1087
1146
|
// src/onchainHtlc.ts
|
|
1088
1147
|
var import_base5 = require("@scure/base");
|
|
1089
|
-
var
|
|
1148
|
+
var import_sha22 = require("@noble/hashes/sha2.js");
|
|
1090
1149
|
var import_legacy = require("@noble/hashes/legacy.js");
|
|
1091
1150
|
var btc = __toESM(require("@scure/btc-signer"), 1);
|
|
1092
1151
|
var ONCHAIN_ORDER_MARGIN_SECONDS = 2 * 60 * 60;
|
|
@@ -1095,7 +1154,7 @@ var MAX_MIN_CONFIRMATIONS = 6;
|
|
|
1095
1154
|
var ONCHAIN_SECONDS_PER_BLOCK = 600;
|
|
1096
1155
|
var ONCHAIN_DUST_SATS = BigInt(330);
|
|
1097
1156
|
var newPreimage = () => crypto.getRandomValues(new Uint8Array(32));
|
|
1098
|
-
var paymentHashOf = (preimage) => import_base5.hex.encode((0,
|
|
1157
|
+
var paymentHashOf = (preimage) => import_base5.hex.encode((0, import_sha22.sha256)(preimage));
|
|
1099
1158
|
var h160FromPaymentHash = (paymentHash) => (0, import_legacy.ripemd160)(import_base5.hex.decode(paymentHash));
|
|
1100
1159
|
var L1_NETWORKS = {
|
|
1101
1160
|
bitcoin: btc.NETWORK,
|
|
@@ -1236,7 +1295,7 @@ function extractPreimage(txHex, paymentHash) {
|
|
|
1236
1295
|
}
|
|
1237
1296
|
for (const stack of raw.witnesses ?? []) {
|
|
1238
1297
|
for (const item of stack) {
|
|
1239
|
-
if (item.length === 32 && import_base5.hex.encode((0,
|
|
1298
|
+
if (item.length === 32 && import_base5.hex.encode((0, import_sha22.sha256)(item)) === paymentHash) return item;
|
|
1240
1299
|
}
|
|
1241
1300
|
}
|
|
1242
1301
|
return null;
|
|
@@ -1291,13 +1350,13 @@ async function classifyOnchainHtlc(chain, input) {
|
|
|
1291
1350
|
}
|
|
1292
1351
|
|
|
1293
1352
|
// src/rfq.ts
|
|
1294
|
-
var
|
|
1353
|
+
var import_sdk9 = require("@arkade-os/sdk");
|
|
1295
1354
|
|
|
1296
1355
|
// src/claimPacket.ts
|
|
1297
1356
|
var import_base6 = require("@scure/base");
|
|
1298
1357
|
var import_secp256k1 = require("@noble/curves/secp256k1.js");
|
|
1299
1358
|
var import_hkdf = require("@noble/hashes/hkdf.js");
|
|
1300
|
-
var
|
|
1359
|
+
var import_sha23 = require("@noble/hashes/sha2.js");
|
|
1301
1360
|
var HKDF_INFO = new TextEncoder().encode("covclaimd/preimage/v1");
|
|
1302
1361
|
async function sealClaimPacket(input) {
|
|
1303
1362
|
return sealWithEntropy(
|
|
@@ -1313,7 +1372,7 @@ async function sealWithEntropy(input, ephemeralKey, nonce) {
|
|
|
1313
1372
|
}
|
|
1314
1373
|
const ephemeralPub = import_secp256k1.secp256k1.getPublicKey(ephemeralKey, true);
|
|
1315
1374
|
const sharedX = import_secp256k1.secp256k1.getSharedSecret(ephemeralKey, input.covclaimdPubkey, true).subarray(1);
|
|
1316
|
-
const key = (0, import_hkdf.hkdf)(
|
|
1375
|
+
const key = (0, import_hkdf.hkdf)(import_sha23.sha256, sharedX, ephemeralPub, HKDF_INFO, 32);
|
|
1317
1376
|
if (nonce.length !== 12) throw new Error("nonce must be 12 bytes");
|
|
1318
1377
|
const aesKey = await crypto.subtle.importKey("raw", key, "AES-GCM", false, [
|
|
1319
1378
|
"encrypt"
|
|
@@ -1338,7 +1397,7 @@ async function sealWithEntropy(input, ephemeralKey, nonce) {
|
|
|
1338
1397
|
|
|
1339
1398
|
// src/lockupContract.ts
|
|
1340
1399
|
var import_base7 = require("@scure/base");
|
|
1341
|
-
var
|
|
1400
|
+
var import_sdk7 = require("@arkade-os/sdk");
|
|
1342
1401
|
var SWAP_LOCKUP_CONTRACT_TYPE = "vhtlc-v2";
|
|
1343
1402
|
var SWAP_LOCKUP_CONTRACT_LABEL = "Arkade RFQ swap lockup";
|
|
1344
1403
|
var SWAP_LOCKUP_CONTRACT_KIND = "rfq-swap-lockup";
|
|
@@ -1360,7 +1419,7 @@ async function registerLockupContract(contracts, script, address) {
|
|
|
1360
1419
|
try {
|
|
1361
1420
|
await contracts.createContract({
|
|
1362
1421
|
type: SWAP_LOCKUP_CONTRACT_TYPE,
|
|
1363
|
-
params:
|
|
1422
|
+
params: import_sdk7.VHTLCV2ContractHandler.serializeParams(script.options),
|
|
1364
1423
|
script: import_base7.hex.encode(script.pkScript),
|
|
1365
1424
|
address,
|
|
1366
1425
|
label: SWAP_LOCKUP_CONTRACT_LABEL,
|
|
@@ -1622,27 +1681,28 @@ var relayTransport = (relayUrl, options) => {
|
|
|
1622
1681
|
};
|
|
1623
1682
|
};
|
|
1624
1683
|
var SEQUENCE_GRANULARITY_SECONDS = 512;
|
|
1684
|
+
var SOLO_REFUND_HEADROOM_SECONDS = 8 * SEQUENCE_GRANULARITY_SECONDS;
|
|
1625
1685
|
var unilateralClaimDelay = (serverExitDelaySeconds) => {
|
|
1626
1686
|
if (!Number.isFinite(serverExitDelaySeconds) || serverExitDelaySeconds < SEQUENCE_GRANULARITY_SECONDS) {
|
|
1627
1687
|
throw new Error(
|
|
1628
1688
|
`server exit delay must be at least ${SEQUENCE_GRANULARITY_SECONDS}s of seconds, got ${serverExitDelaySeconds}`
|
|
1629
1689
|
);
|
|
1630
1690
|
}
|
|
1631
|
-
if (serverExitDelaySeconds >
|
|
1691
|
+
if (serverExitDelaySeconds > 65535 * SEQUENCE_GRANULARITY_SECONDS - SOLO_REFUND_HEADROOM_SECONDS) {
|
|
1632
1692
|
throw new Error(
|
|
1633
|
-
`server exit delay ${serverExitDelaySeconds}s exceeds what BIP68 can encode once the
|
|
1693
|
+
`server exit delay ${serverExitDelaySeconds}s exceeds what BIP68 can encode once the solo refund's headroom is stacked above it`
|
|
1634
1694
|
);
|
|
1635
1695
|
}
|
|
1636
1696
|
return Math.ceil(serverExitDelaySeconds / SEQUENCE_GRANULARITY_SECONDS) * SEQUENCE_GRANULARITY_SECONDS;
|
|
1637
1697
|
};
|
|
1638
|
-
var unilateralRefundDelay = (claimDelay) => claimDelay
|
|
1639
|
-
var unilateralRefundWithoutReceiverDelay = (claimDelay) => claimDelay +
|
|
1698
|
+
var unilateralRefundDelay = (claimDelay) => claimDelay;
|
|
1699
|
+
var unilateralRefundWithoutReceiverDelay = (claimDelay) => claimDelay + SOLO_REFUND_HEADROOM_SECONDS;
|
|
1640
1700
|
function lightningSendVtxoScript(params) {
|
|
1641
1701
|
const seconds = (value) => ({
|
|
1642
1702
|
type: "seconds",
|
|
1643
1703
|
value: BigInt(value)
|
|
1644
1704
|
});
|
|
1645
|
-
return new
|
|
1705
|
+
return new import_sdk8.VHTLC.ScriptV2({
|
|
1646
1706
|
sender: params.senderPubkey,
|
|
1647
1707
|
receiver: params.solverPubkey,
|
|
1648
1708
|
server: params.serverPubkey,
|
|
@@ -1665,10 +1725,10 @@ function lightningSendVtxoScript(params) {
|
|
|
1665
1725
|
}
|
|
1666
1726
|
async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
1667
1727
|
const rfqId = params.rfqId ?? newRfqId();
|
|
1668
|
-
const secrets = await (0,
|
|
1728
|
+
const secrets = await (0, import_sdk9.provisionRefundKey)(wallet);
|
|
1669
1729
|
const senderPubkey = secrets.pubkey;
|
|
1670
1730
|
const [info, refundAddress] = await Promise.all([
|
|
1671
|
-
new
|
|
1731
|
+
new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
|
|
1672
1732
|
wallet.getAddress()
|
|
1673
1733
|
]);
|
|
1674
1734
|
const quote = await transport.requestQuote(
|
|
@@ -1692,7 +1752,7 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
|
1692
1752
|
);
|
|
1693
1753
|
}
|
|
1694
1754
|
const serverPubkey = xOnly(import_base8.hex.decode(info.signerPubkey), "ark signer key");
|
|
1695
|
-
const network = (0,
|
|
1755
|
+
const network = (0, import_sdk8.getNetwork)(info.network);
|
|
1696
1756
|
const script = lightningSendVtxoScript({
|
|
1697
1757
|
solverPubkey: xOnly(import_base8.hex.decode(quote.solver_pubkey), "solver key"),
|
|
1698
1758
|
refundLocktime: quote.refund_locktime,
|
|
@@ -1700,12 +1760,12 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
|
1700
1760
|
paymentHash: params.invoice.paymentHash,
|
|
1701
1761
|
claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
|
|
1702
1762
|
emulatorPubkey: xOnly(
|
|
1703
|
-
import_base8.hex.decode((0,
|
|
1763
|
+
import_base8.hex.decode((0, import_sdk8.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
|
|
1704
1764
|
"emulator signer key"
|
|
1705
1765
|
),
|
|
1706
1766
|
senderPubkey,
|
|
1707
1767
|
receiverPkScript: solverHex(receiverPkScriptHex, "profile.receiver_pk_script"),
|
|
1708
|
-
refundPkScript:
|
|
1768
|
+
refundPkScript: import_sdk8.ArkAddress.decode(refundAddress).pkScript
|
|
1709
1769
|
});
|
|
1710
1770
|
const address = script.address(network.hrp, serverPubkey).encode();
|
|
1711
1771
|
verifyLockupAddress(quote, address);
|
|
@@ -1800,7 +1860,7 @@ function deriveOnchainSend(input) {
|
|
|
1800
1860
|
emulatorPubkey: input.emulatorPubkey,
|
|
1801
1861
|
senderPubkey: input.senderPubkey,
|
|
1802
1862
|
receiverPkScript: solverHex(receiverPkScriptHex, "profile.receiver_pk_script"),
|
|
1803
|
-
refundPkScript:
|
|
1863
|
+
refundPkScript: import_sdk8.ArkAddress.decode(input.refundAddress).pkScript
|
|
1804
1864
|
});
|
|
1805
1865
|
const address = script.address(input.hrp, input.serverPubkey).encode();
|
|
1806
1866
|
verifyLockupAddress(quote, address);
|
|
@@ -1826,7 +1886,7 @@ function deriveOnchainSend(input) {
|
|
|
1826
1886
|
}
|
|
1827
1887
|
async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
|
|
1828
1888
|
const rfqId = params.rfqId ?? newRfqId();
|
|
1829
|
-
const secrets = await (0,
|
|
1889
|
+
const secrets = await (0, import_sdk9.provisionClaimSecret)(wallet, { preimage: params.preimage });
|
|
1830
1890
|
if (secrets.mustPersistPreimage) {
|
|
1831
1891
|
console.warn(
|
|
1832
1892
|
"[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before funding"
|
|
@@ -1835,7 +1895,7 @@ async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
|
|
|
1835
1895
|
const paymentHash = import_base8.hex.encode(secrets.paymentHash);
|
|
1836
1896
|
const senderPubkey = secrets.pubkey;
|
|
1837
1897
|
const [info, refundAddress] = await Promise.all([
|
|
1838
|
-
new
|
|
1898
|
+
new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
|
|
1839
1899
|
wallet.getAddress()
|
|
1840
1900
|
]);
|
|
1841
1901
|
const quote = await transport.requestQuote(
|
|
@@ -1849,14 +1909,14 @@ async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
|
|
|
1849
1909
|
amountSide: params.amountSide
|
|
1850
1910
|
})
|
|
1851
1911
|
);
|
|
1852
|
-
const network = (0,
|
|
1912
|
+
const network = (0, import_sdk8.getNetwork)(info.network);
|
|
1853
1913
|
const derived = deriveOnchainSend({
|
|
1854
1914
|
quote,
|
|
1855
1915
|
paymentHash,
|
|
1856
1916
|
payoutPubkey: params.payoutPubkey,
|
|
1857
1917
|
serverPubkey: xOnly(import_base8.hex.decode(info.signerPubkey), "ark signer key"),
|
|
1858
1918
|
emulatorPubkey: xOnly(
|
|
1859
|
-
import_base8.hex.decode((0,
|
|
1919
|
+
import_base8.hex.decode((0, import_sdk8.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
|
|
1860
1920
|
"emulator signer key"
|
|
1861
1921
|
),
|
|
1862
1922
|
claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
|
|
@@ -1964,7 +2024,7 @@ function receiveVtxoScript(params) {
|
|
|
1964
2024
|
type: "seconds",
|
|
1965
2025
|
value: BigInt(value)
|
|
1966
2026
|
});
|
|
1967
|
-
return new
|
|
2027
|
+
return new import_sdk8.VHTLC.ScriptV2({
|
|
1968
2028
|
sender: params.solverPubkey,
|
|
1969
2029
|
receiver: params.payoutPubkey,
|
|
1970
2030
|
server: params.serverPubkey,
|
|
@@ -2003,7 +2063,7 @@ function deriveLightningReceive(input) {
|
|
|
2003
2063
|
emulatorPubkey: input.emulatorPubkey,
|
|
2004
2064
|
solverRefundPkScript: solverHex(solverRefundPkScriptHex, "profile.solver_refund_pk_script"),
|
|
2005
2065
|
payoutPubkey: input.payoutPubkey,
|
|
2006
|
-
payoutPkScript:
|
|
2066
|
+
payoutPkScript: import_sdk8.ArkAddress.decode(input.payoutAddress).pkScript
|
|
2007
2067
|
});
|
|
2008
2068
|
const address = script.address(input.hrp, input.serverPubkey).encode();
|
|
2009
2069
|
verifyLockupAddress(quote, address);
|
|
@@ -2011,7 +2071,7 @@ function deriveLightningReceive(input) {
|
|
|
2011
2071
|
}
|
|
2012
2072
|
async function requestLightningReceive(wallet, arkServerUrl, transport, params) {
|
|
2013
2073
|
const rfqId = params.rfqId ?? newRfqId();
|
|
2014
|
-
const secrets = await (0,
|
|
2074
|
+
const secrets = await (0, import_sdk9.provisionClaimSecret)(wallet);
|
|
2015
2075
|
if (secrets.mustPersistPreimage) {
|
|
2016
2076
|
console.warn(
|
|
2017
2077
|
"[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before paying"
|
|
@@ -2021,7 +2081,7 @@ async function requestLightningReceive(wallet, arkServerUrl, transport, params)
|
|
|
2021
2081
|
const paymentHash = import_base8.hex.encode(secrets.paymentHash);
|
|
2022
2082
|
const payoutPubkey = secrets.pubkey;
|
|
2023
2083
|
const [info, payoutAddress] = await Promise.all([
|
|
2024
|
-
new
|
|
2084
|
+
new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
|
|
2025
2085
|
wallet.getAddress()
|
|
2026
2086
|
]);
|
|
2027
2087
|
const claimPacket = await sealClaimPacket({
|
|
@@ -2040,7 +2100,7 @@ async function requestLightningReceive(wallet, arkServerUrl, transport, params)
|
|
|
2040
2100
|
})
|
|
2041
2101
|
);
|
|
2042
2102
|
assertQuotedAmount(quote, params.amountSide, params.amount);
|
|
2043
|
-
const network = (0,
|
|
2103
|
+
const network = (0, import_sdk8.getNetwork)(info.network);
|
|
2044
2104
|
const derived = deriveLightningReceive({
|
|
2045
2105
|
quote,
|
|
2046
2106
|
paymentHash,
|
|
@@ -2048,7 +2108,7 @@ async function requestLightningReceive(wallet, arkServerUrl, transport, params)
|
|
|
2048
2108
|
payoutAddress,
|
|
2049
2109
|
serverPubkey: xOnly(import_base8.hex.decode(info.signerPubkey), "ark signer key"),
|
|
2050
2110
|
emulatorPubkey: xOnly(
|
|
2051
|
-
import_base8.hex.decode((0,
|
|
2111
|
+
import_base8.hex.decode((0, import_sdk8.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
|
|
2052
2112
|
"emulator signer key"
|
|
2053
2113
|
),
|
|
2054
2114
|
claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
|
|
@@ -2103,7 +2163,7 @@ function deriveOnchainReceive(input) {
|
|
|
2103
2163
|
emulatorPubkey: input.emulatorPubkey,
|
|
2104
2164
|
solverRefundPkScript: solverHex(solverRefundPkScriptHex, "profile.solver_refund_pk_script"),
|
|
2105
2165
|
payoutPubkey: input.payoutPubkey,
|
|
2106
|
-
payoutPkScript:
|
|
2166
|
+
payoutPkScript: import_sdk8.ArkAddress.decode(input.payoutAddress).pkScript
|
|
2107
2167
|
});
|
|
2108
2168
|
const address = script.address(input.hrp, input.serverPubkey).encode();
|
|
2109
2169
|
verifyLockupAddress(quote, address);
|
|
@@ -2129,7 +2189,7 @@ function deriveOnchainReceive(input) {
|
|
|
2129
2189
|
}
|
|
2130
2190
|
async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
|
|
2131
2191
|
const rfqId = params.rfqId ?? newRfqId();
|
|
2132
|
-
const secrets = await (0,
|
|
2192
|
+
const secrets = await (0, import_sdk9.provisionClaimSecret)(wallet);
|
|
2133
2193
|
if (secrets.mustPersistPreimage) {
|
|
2134
2194
|
console.warn(
|
|
2135
2195
|
"[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before funding"
|
|
@@ -2139,7 +2199,7 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
|
|
|
2139
2199
|
const paymentHash = import_base8.hex.encode(secrets.paymentHash);
|
|
2140
2200
|
const payoutPubkey = secrets.pubkey;
|
|
2141
2201
|
const [info, payoutAddress] = await Promise.all([
|
|
2142
|
-
new
|
|
2202
|
+
new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
|
|
2143
2203
|
wallet.getAddress()
|
|
2144
2204
|
]);
|
|
2145
2205
|
const claimPacket = await sealClaimPacket({
|
|
@@ -2159,7 +2219,7 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
|
|
|
2159
2219
|
})
|
|
2160
2220
|
);
|
|
2161
2221
|
assertQuotedAmount(quote, params.amountSide, params.amount);
|
|
2162
|
-
const network = (0,
|
|
2222
|
+
const network = (0, import_sdk8.getNetwork)(info.network);
|
|
2163
2223
|
const derived = deriveOnchainReceive({
|
|
2164
2224
|
quote,
|
|
2165
2225
|
paymentHash,
|
|
@@ -2168,7 +2228,7 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
|
|
|
2168
2228
|
refundPubkey: params.refundPubkey,
|
|
2169
2229
|
serverPubkey: xOnly(import_base8.hex.decode(info.signerPubkey), "ark signer key"),
|
|
2170
2230
|
emulatorPubkey: xOnly(
|
|
2171
|
-
import_base8.hex.decode((0,
|
|
2231
|
+
import_base8.hex.decode((0, import_sdk8.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
|
|
2172
2232
|
"emulator signer key"
|
|
2173
2233
|
),
|
|
2174
2234
|
claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
|
|
@@ -2207,13 +2267,13 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
|
|
|
2207
2267
|
// src/claim.ts
|
|
2208
2268
|
var import_base10 = require("@scure/base");
|
|
2209
2269
|
var import_legacy3 = require("@noble/hashes/legacy.js");
|
|
2210
|
-
var
|
|
2211
|
-
var
|
|
2270
|
+
var import_sha25 = require("@noble/hashes/sha2.js");
|
|
2271
|
+
var import_sdk11 = require("@arkade-os/sdk");
|
|
2212
2272
|
|
|
2213
2273
|
// src/refund.ts
|
|
2214
2274
|
var import_base9 = require("@scure/base");
|
|
2215
|
-
var
|
|
2216
|
-
var
|
|
2275
|
+
var import_sha24 = require("@noble/hashes/sha2.js");
|
|
2276
|
+
var import_sdk10 = require("@arkade-os/sdk");
|
|
2217
2277
|
var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2218
2278
|
var isRfqTerminal = (state) => RFQ_TERMINAL_STATES.includes(state);
|
|
2219
2279
|
var RFQ_RESOLVED_STATES = ["settled", "refunded"];
|
|
@@ -2285,9 +2345,9 @@ async function findLockupVtxos(indexer, swapPkScript) {
|
|
|
2285
2345
|
}
|
|
2286
2346
|
return out;
|
|
2287
2347
|
}
|
|
2288
|
-
var hashesTo = (candidate, paymentHash) => import_base9.hex.encode((0,
|
|
2348
|
+
var hashesTo = (candidate, paymentHash) => import_base9.hex.encode((0, import_sha24.sha256)(candidate)) === paymentHash;
|
|
2289
2349
|
var candidateWitnessItems = (tx, inputIndex) => [
|
|
2290
|
-
...(0,
|
|
2350
|
+
...(0, import_sdk10.getArkPsbtFields)(tx, inputIndex, import_sdk10.ConditionWitness).flat(),
|
|
2291
2351
|
...tx.getInput(inputIndex).finalScriptWitness ?? []
|
|
2292
2352
|
];
|
|
2293
2353
|
async function readLockupFate(indexer, input) {
|
|
@@ -2306,7 +2366,7 @@ async function readLockupFate(indexer, input) {
|
|
|
2306
2366
|
for (const raw of txs) {
|
|
2307
2367
|
let tx;
|
|
2308
2368
|
try {
|
|
2309
|
-
tx =
|
|
2369
|
+
tx = import_sdk10.Transaction.fromPSBT(import_base9.base64.decode(raw));
|
|
2310
2370
|
} catch {
|
|
2311
2371
|
continue;
|
|
2312
2372
|
}
|
|
@@ -2343,14 +2403,14 @@ async function pushRefundWithoutReceiver(ark, input) {
|
|
|
2343
2403
|
const info = await ark.getInfo();
|
|
2344
2404
|
let serverUnrollScript;
|
|
2345
2405
|
try {
|
|
2346
|
-
serverUnrollScript =
|
|
2406
|
+
serverUnrollScript = import_sdk10.CSVMultisigTapscript.decode(import_base9.hex.decode(info.checkpointTapscript));
|
|
2347
2407
|
} catch {
|
|
2348
2408
|
throw new Error("invalid checkpointTapscript from the Arkade server");
|
|
2349
2409
|
}
|
|
2350
2410
|
const leaf = input.script.refundWithoutReceiver();
|
|
2351
2411
|
const tapTree = input.script.encode();
|
|
2352
2412
|
const amount = input.vtxos.reduce((sum, vtxo) => sum + vtxo.value, 0);
|
|
2353
|
-
const { arkTx, checkpoints } = (0,
|
|
2413
|
+
const { arkTx, checkpoints } = (0, import_sdk10.buildOffchainTx)(
|
|
2354
2414
|
input.vtxos.map((vtxo) => ({
|
|
2355
2415
|
txid: vtxo.txid,
|
|
2356
2416
|
vout: vtxo.vout,
|
|
@@ -2366,8 +2426,8 @@ async function pushRefundWithoutReceiver(ark, input) {
|
|
|
2366
2426
|
import_base9.base64.encode(signedArkTx.toPSBT()),
|
|
2367
2427
|
checkpoints.map((c) => import_base9.base64.encode(c.toPSBT()))
|
|
2368
2428
|
);
|
|
2369
|
-
(0,
|
|
2370
|
-
const matched = (0,
|
|
2429
|
+
(0, import_sdk10.assertSubmittedArkTxid)(submitted, signedArkTx, "refundWithoutReceiver");
|
|
2430
|
+
const matched = (0, import_sdk10.matchServerCheckpoints)(
|
|
2371
2431
|
submitted.signedCheckpointTxs,
|
|
2372
2432
|
checkpoints,
|
|
2373
2433
|
"refundWithoutReceiver"
|
|
@@ -2454,20 +2514,20 @@ async function pushClaim(ark, input) {
|
|
|
2454
2514
|
}
|
|
2455
2515
|
}
|
|
2456
2516
|
const committed = input.script.options.preimageHash;
|
|
2457
|
-
if (import_base10.hex.encode((0, import_legacy3.ripemd160)((0,
|
|
2517
|
+
if (import_base10.hex.encode((0, import_legacy3.ripemd160)((0, import_sha25.sha256)(input.preimage))) !== import_base10.hex.encode(committed)) {
|
|
2458
2518
|
throw new Error("preimage does not match the covenant's payment hash");
|
|
2459
2519
|
}
|
|
2460
2520
|
const info = await ark.getInfo();
|
|
2461
2521
|
let serverUnrollScript;
|
|
2462
2522
|
try {
|
|
2463
|
-
serverUnrollScript =
|
|
2523
|
+
serverUnrollScript = import_sdk11.CSVMultisigTapscript.decode(import_base10.hex.decode(info.checkpointTapscript));
|
|
2464
2524
|
} catch {
|
|
2465
2525
|
throw new Error("invalid checkpointTapscript from the Arkade server");
|
|
2466
2526
|
}
|
|
2467
2527
|
const leaf = input.script.claim();
|
|
2468
2528
|
const tapTree = input.script.encode();
|
|
2469
|
-
const arkTxid = await (0,
|
|
2470
|
-
identity: (0,
|
|
2529
|
+
const arkTxid = await (0, import_sdk11.signAndSubmitOffchainTx)({
|
|
2530
|
+
identity: (0, import_sdk11.claimWithPreimageIdentity)(input.receiver, input.preimage),
|
|
2471
2531
|
provider: ark,
|
|
2472
2532
|
inputs: input.vtxos.map((vtxo) => ({
|
|
2473
2533
|
txid: vtxo.txid,
|
|
@@ -2514,7 +2574,7 @@ async function claimReceiveLockup(indexer, ark, input) {
|
|
|
2514
2574
|
}
|
|
2515
2575
|
|
|
2516
2576
|
// src/refundBlocked.ts
|
|
2517
|
-
var
|
|
2577
|
+
var import_sdk12 = require("@arkade-os/sdk");
|
|
2518
2578
|
var RefundNotLocallyPossibleError = class extends Error {
|
|
2519
2579
|
constructor(reason, message, options) {
|
|
2520
2580
|
super(message, options);
|
|
@@ -2531,16 +2591,16 @@ async function senderIdentityForSwapRecord(wallet, record) {
|
|
|
2531
2591
|
);
|
|
2532
2592
|
}
|
|
2533
2593
|
try {
|
|
2534
|
-
return await (0,
|
|
2594
|
+
return await (0, import_sdk12.contractSigner)(wallet, record.signingDescriptor);
|
|
2535
2595
|
} catch (cause) {
|
|
2536
|
-
if (cause instanceof
|
|
2596
|
+
if (cause instanceof import_sdk12.WalletCannotSignError) {
|
|
2537
2597
|
throw new RefundNotLocallyPossibleError(
|
|
2538
2598
|
"unsignable-wallet",
|
|
2539
2599
|
`this wallet holds ${record.signingDescriptor} but cannot sign with it; attach its signer`,
|
|
2540
2600
|
{ cause }
|
|
2541
2601
|
);
|
|
2542
2602
|
}
|
|
2543
|
-
if (cause instanceof
|
|
2603
|
+
if (cause instanceof import_sdk12.ForeignDescriptorError) {
|
|
2544
2604
|
throw new RefundNotLocallyPossibleError(
|
|
2545
2605
|
"foreign-descriptor",
|
|
2546
2606
|
`this wallet cannot derive ${record.signingDescriptor}; the swap was created on another wallet`,
|
|
@@ -3317,6 +3377,60 @@ var outcomeOf = (swap) => {
|
|
|
3317
3377
|
};
|
|
3318
3378
|
var errorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
3319
3379
|
var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
3380
|
+
|
|
3381
|
+
// src/activity.ts
|
|
3382
|
+
var LABELS = {
|
|
3383
|
+
lightning_send: "Lightning send",
|
|
3384
|
+
lightning_receive: "Lightning receive",
|
|
3385
|
+
onchain_send: "Onchain send"
|
|
3386
|
+
};
|
|
3387
|
+
var OUTCOME = {
|
|
3388
|
+
pending: "pending",
|
|
3389
|
+
// `claimable` and `claimed` are both in-progress states with no
|
|
3390
|
+
// user-visible phase distinct from "pending". `needs_counterparty` is
|
|
3391
|
+
// different in kind — the swap is BLOCKED, not merely in flight, since no
|
|
3392
|
+
// unilateral trader move exists (see `RfqSwapState`). Collapsing it into
|
|
3393
|
+
// `pending` here is a deliberate choice the opaque-token design permits —
|
|
3394
|
+
// apps map tokens themselves — but a future reader weighing a `"blocked"`
|
|
3395
|
+
// or `"stuck"` token should know this was already considered.
|
|
3396
|
+
claimable: "pending",
|
|
3397
|
+
claimed: "pending",
|
|
3398
|
+
needs_counterparty: "pending",
|
|
3399
|
+
settled: "settled",
|
|
3400
|
+
refunded: "refunded",
|
|
3401
|
+
failed: "failed"
|
|
3402
|
+
};
|
|
3403
|
+
function swapActivityResolver(deps) {
|
|
3404
|
+
let byTxid = /* @__PURE__ */ new Map();
|
|
3405
|
+
return {
|
|
3406
|
+
id: "arkade:swap",
|
|
3407
|
+
async prepare() {
|
|
3408
|
+
const swaps = await deps.listSwaps();
|
|
3409
|
+
const index = /* @__PURE__ */ new Map();
|
|
3410
|
+
for (const swap of swaps) {
|
|
3411
|
+
for (const txid of swap.txids) {
|
|
3412
|
+
if (txid) index.set(txid, swap);
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
byTxid = index;
|
|
3416
|
+
},
|
|
3417
|
+
resolve(tx) {
|
|
3418
|
+
const key = tx.key.arkTxid || tx.key.commitmentTxid || tx.key.boardingTxid;
|
|
3419
|
+
const swap = key ? byTxid.get(key) : void 0;
|
|
3420
|
+
if (!swap) return void 0;
|
|
3421
|
+
const lostReceive = swap.kind === "lightning_receive" && swap.state === "refunded";
|
|
3422
|
+
return [
|
|
3423
|
+
{
|
|
3424
|
+
groupId: `swap:${swap.rfqId}`,
|
|
3425
|
+
label: LABELS[swap.kind],
|
|
3426
|
+
kind: "swap",
|
|
3427
|
+
outcome: lostReceive ? "lost" : OUTCOME[swap.state],
|
|
3428
|
+
metadata: { rfqId: swap.rfqId, swapKind: swap.kind }
|
|
3429
|
+
}
|
|
3430
|
+
];
|
|
3431
|
+
}
|
|
3432
|
+
};
|
|
3433
|
+
}
|
|
3320
3434
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3321
3435
|
0 && (module.exports = {
|
|
3322
3436
|
ARKADE_ASSET,
|
|
@@ -3342,6 +3456,7 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3342
3456
|
ONCHAIN_RECEIVE_PAIR,
|
|
3343
3457
|
ONCHAIN_SECONDS_PER_BLOCK,
|
|
3344
3458
|
ONCHAIN_SEND_PAIR,
|
|
3459
|
+
PreimageNotRecoverableError,
|
|
3345
3460
|
QUOTE_OPTIONS,
|
|
3346
3461
|
REFUND_MTP_LAG_SECONDS,
|
|
3347
3462
|
RFQ_RESOLVED_STATES,
|
|
@@ -3349,6 +3464,7 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3349
3464
|
RFQ_TERMINAL_STATES,
|
|
3350
3465
|
RefundNotLocallyPossibleError,
|
|
3351
3466
|
RfqSwapManager,
|
|
3467
|
+
SOLO_REFUND_HEADROOM_SECONDS,
|
|
3352
3468
|
SWAP_LOCKUP_CONTRACT_KIND,
|
|
3353
3469
|
SWAP_LOCKUP_CONTRACT_LABEL,
|
|
3354
3470
|
SWAP_LOCKUP_CONTRACT_TYPE,
|
|
@@ -3396,6 +3512,7 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3396
3512
|
onchainReceiveRequest,
|
|
3397
3513
|
onchainSendRequest,
|
|
3398
3514
|
paymentHashOf,
|
|
3515
|
+
preimageForSwapRecord,
|
|
3399
3516
|
pushClaim,
|
|
3400
3517
|
pushRefundWithoutReceiver,
|
|
3401
3518
|
readLockupFate,
|
|
@@ -3414,6 +3531,7 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3414
3531
|
senderIdentityForSwapRecord,
|
|
3415
3532
|
spendTxidsOf,
|
|
3416
3533
|
spendUpdate,
|
|
3534
|
+
swapActivityResolver,
|
|
3417
3535
|
swapPrograms,
|
|
3418
3536
|
swapSecretsToRecord,
|
|
3419
3537
|
unilateralClaimDelay,
|