@arkade-os/swap 0.0.9 → 0.0.11
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 +17 -0
- package/dist/{chunk-2FEMUOIH.js → chunk-RIC5ZTZK.js} +71 -33
- package/dist/index.cjs +235 -52
- package/dist/index.d.cts +61 -15
- package/dist/index.d.ts +61 -15
- package/dist/index.js +166 -20
- package/dist/nostr.d.cts +1 -1
- package/dist/nostr.d.ts +1 -1
- package/dist/nostr.js +1 -1
- package/dist/repositories/realm/index.d.cts +2 -2
- package/dist/repositories/realm/index.d.ts +2 -2
- package/dist/repositories/sqlite/index.d.cts +2 -2
- package/dist/repositories/sqlite/index.d.ts +2 -2
- package/dist/{repository-DEHLtD9l.d.cts → repository-B02vsgcV.d.cts} +106 -12
- package/dist/{repository-DIAr5XYk.d.ts → repository-CfE18Fif.d.ts} +106 -12
- package/dist/{rfq-hbzhTWHT.d.ts → rfq-DkckzRKK.d.cts} +54 -24
- package/dist/{rfq-hbzhTWHT.d.cts → rfq-DkckzRKK.d.ts} +54 -24
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -759,6 +759,23 @@ through their stored `preimageHex` or their HD descriptor, and `DB_VERSION` is u
|
|
|
759
759
|
|
|
760
760
|
Notes from before 0.0.1, kept for consumers who tracked the branch.
|
|
761
761
|
|
|
762
|
+
- **`refundIfUnresolved` reports an exited lockup, and its input gained `paymentHash`.**
|
|
763
|
+
`RefundOutcome` has a new `{ outcome: "exited"; outpoints; status }` variant: a lockup whose
|
|
764
|
+
outputs were unilaterally exited lives onchain under the VHTLC script, where no offchain refund
|
|
765
|
+
reaches it. It used to come back as `nothing_to_refund`, which reads as "already resolved" over
|
|
766
|
+
money still sitting at the script — the swept case gets `needs_recovery` for the same reason, and
|
|
767
|
+
this is deliberately **not** that variant: recovery into a fresh batch is a spend no batch can
|
|
768
|
+
make for an onchain output. Complete the unroll and spend the outputs onchain instead.
|
|
769
|
+
|
|
770
|
+
Two required changes for direct callers. The input gains **`paymentHash`** (`sha256(P)` hex — the
|
|
771
|
+
quote's `payment_hash`, which callers already hold): the exit is read through `readLockupFate`,
|
|
772
|
+
and the VHTLC script cannot supply it, since its `preimageHash` is a `hash160` of the same secret.
|
|
773
|
+
And the `indexer` parameter widened from `RefundIndexer` to **`LockupSpendIndexer`**, so it must
|
|
774
|
+
now carry `getVirtualTxs` as well as `getVtxos` — a real `RestIndexerProvider` already does.
|
|
775
|
+
|
|
776
|
+
A lockup funded in two sends of which only one exited reports `exited` for the whole thing and
|
|
777
|
+
leaves the live half unrefunded. That matches `RfqSwapManager`, which reports the same lockup
|
|
778
|
+
`exited` on the same any-output rule; the two must not disagree.
|
|
762
779
|
- **`RfqSwapManager` can own its own persistence.** New optional
|
|
763
780
|
`RfqSwapManagerDeps.repository`, new `restoreFromRepository()` and `pruneRetiredSwaps()`, and
|
|
764
781
|
`addSwap(swap, origin?)` gains an optional second argument. Nothing narrows and nothing is
|
|
@@ -422,8 +422,22 @@ var assertPairLength = (pair) => {
|
|
|
422
422
|
};
|
|
423
423
|
var verifyLockupAddress = (quote, derivedAddress) => {
|
|
424
424
|
const quoted = quote.profile?.lockup_address;
|
|
425
|
-
|
|
426
|
-
|
|
425
|
+
const candidates = Array.isArray(derivedAddress) ? derivedAddress : [derivedAddress];
|
|
426
|
+
const matched = candidates.find((address) => address === quoted);
|
|
427
|
+
if (matched === void 0) throw new AddressMismatch(candidates, quoted);
|
|
428
|
+
return matched;
|
|
429
|
+
};
|
|
430
|
+
var LOCKUP_SHAPE_VARIANTS = [void 0, "preTimelockedRefund"];
|
|
431
|
+
var matchQuotedLockup = (quote, hrp, serverPubkey, build) => {
|
|
432
|
+
const candidates = LOCKUP_SHAPE_VARIANTS.map((legacy) => {
|
|
433
|
+
const script = build(legacy);
|
|
434
|
+
return { script, address: script.address(hrp, serverPubkey).encode(), legacy };
|
|
435
|
+
});
|
|
436
|
+
const matchedAddress = verifyLockupAddress(
|
|
437
|
+
quote,
|
|
438
|
+
candidates.map((candidate) => candidate.address)
|
|
439
|
+
);
|
|
440
|
+
return candidates.find((candidate) => candidate.address === matchedAddress);
|
|
427
441
|
};
|
|
428
442
|
var assertFundable = (input) => {
|
|
429
443
|
const fail = (reason, message) => {
|
|
@@ -625,13 +639,11 @@ function lightningSendVtxoScript(params) {
|
|
|
625
639
|
unilateralRefundWithoutReceiverDelay: seconds(
|
|
626
640
|
unilateralRefundWithoutReceiverDelay(params.claimDelay)
|
|
627
641
|
),
|
|
628
|
-
|
|
642
|
+
nonInteractiveParameters: {
|
|
629
643
|
receiverPkScript: params.receiverPkScript,
|
|
630
|
-
emulatorPubkey: params.emulatorPubkey
|
|
631
|
-
},
|
|
632
|
-
nonInteractiveRefund: {
|
|
633
644
|
senderPkScript: params.refundPkScript,
|
|
634
|
-
emulatorPubkey: params.emulatorPubkey
|
|
645
|
+
emulatorPubkey: params.emulatorPubkey,
|
|
646
|
+
...params.legacy !== void 0 && { legacy: params.legacy }
|
|
635
647
|
}
|
|
636
648
|
});
|
|
637
649
|
}
|
|
@@ -639,10 +651,8 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
|
639
651
|
const rfqId = params.rfqId ?? newRfqId();
|
|
640
652
|
const secrets = await provisionRefundKey(wallet);
|
|
641
653
|
const senderPubkey = secrets.pubkey;
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
wallet.getAddress()
|
|
645
|
-
]);
|
|
654
|
+
const refundAddress = secrets.address;
|
|
655
|
+
const info = await new RestArkProvider(arkServerUrl).getInfo();
|
|
646
656
|
const quote = await transport.requestQuote(
|
|
647
657
|
lightningSendRequest({ rfqId, invoice: params.invoice.raw, refundAddress, senderPubkey })
|
|
648
658
|
);
|
|
@@ -677,11 +687,20 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
|
677
687
|
),
|
|
678
688
|
senderPubkey,
|
|
679
689
|
receiverPkScript: solverHex(receiverPkScriptHex, "profile.receiver_pk_script"),
|
|
680
|
-
refundPkScript:
|
|
690
|
+
refundPkScript: secrets.pkScript
|
|
691
|
+
};
|
|
692
|
+
const matched = matchQuotedLockup(
|
|
693
|
+
quote,
|
|
694
|
+
network.hrp,
|
|
695
|
+
serverPubkey,
|
|
696
|
+
(legacy) => lightningSendVtxoScript({ ...treeParams, ...legacy !== void 0 && { legacy } })
|
|
697
|
+
);
|
|
698
|
+
const script = matched.script;
|
|
699
|
+
const address = matched.address;
|
|
700
|
+
const matchedTreeParams = {
|
|
701
|
+
...treeParams,
|
|
702
|
+
...matched.legacy !== void 0 && { legacy: matched.legacy }
|
|
681
703
|
};
|
|
682
|
-
const script = lightningSendVtxoScript(treeParams);
|
|
683
|
-
const address = script.address(network.hrp, serverPubkey).encode();
|
|
684
|
-
verifyLockupAddress(quote, address);
|
|
685
704
|
assertFundable({
|
|
686
705
|
quote,
|
|
687
706
|
invoiceExpiresAt: params.invoice.expiresAt,
|
|
@@ -700,7 +719,7 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
|
700
719
|
refundAddress,
|
|
701
720
|
senderPubkey,
|
|
702
721
|
secrets,
|
|
703
|
-
treeParams
|
|
722
|
+
treeParams: matchedTreeParams
|
|
704
723
|
};
|
|
705
724
|
}
|
|
706
725
|
var offerTermsFromQuote = (quote, assets) => {
|
|
@@ -765,7 +784,7 @@ function deriveOnchainSend(input) {
|
|
|
765
784
|
if (refundLocktime === void 0 || htlcPubkey === void 0 || htlcLocktime === void 0 || minConfirmations === void 0 || receiverPkScriptHex === void 0) {
|
|
766
785
|
throw new Error("onchain-send quote is missing a binding field");
|
|
767
786
|
}
|
|
768
|
-
const
|
|
787
|
+
const treeParams = {
|
|
769
788
|
solverPubkey: toXOnly(hex3.decode(quote.solver_pubkey), "solver key"),
|
|
770
789
|
refundLocktime,
|
|
771
790
|
serverPubkey: input.serverPubkey,
|
|
@@ -775,9 +794,13 @@ function deriveOnchainSend(input) {
|
|
|
775
794
|
senderPubkey: input.senderPubkey,
|
|
776
795
|
receiverPkScript: solverHex(receiverPkScriptHex, "profile.receiver_pk_script"),
|
|
777
796
|
refundPkScript: ArkAddress2.decode(input.refundAddress).pkScript
|
|
778
|
-
}
|
|
779
|
-
const address =
|
|
780
|
-
|
|
797
|
+
};
|
|
798
|
+
const { script, address } = matchQuotedLockup(
|
|
799
|
+
quote,
|
|
800
|
+
input.hrp,
|
|
801
|
+
input.serverPubkey,
|
|
802
|
+
(legacy) => lightningSendVtxoScript({ ...treeParams, ...legacy !== void 0 && { legacy } })
|
|
803
|
+
);
|
|
781
804
|
const htlcParams = {
|
|
782
805
|
paymentHash: input.paymentHash,
|
|
783
806
|
claimKey: input.payoutPubkey,
|
|
@@ -952,13 +975,11 @@ function receiveVtxoScript(params) {
|
|
|
952
975
|
unilateralRefundWithoutReceiverDelay: seconds(
|
|
953
976
|
unilateralRefundWithoutReceiverDelay(params.claimDelay)
|
|
954
977
|
),
|
|
955
|
-
|
|
978
|
+
nonInteractiveParameters: {
|
|
956
979
|
receiverPkScript: params.payoutPkScript,
|
|
957
|
-
emulatorPubkey: params.emulatorPubkey
|
|
958
|
-
},
|
|
959
|
-
nonInteractiveRefund: {
|
|
960
980
|
senderPkScript: params.solverRefundPkScript,
|
|
961
|
-
emulatorPubkey: params.emulatorPubkey
|
|
981
|
+
emulatorPubkey: params.emulatorPubkey,
|
|
982
|
+
...params.legacy !== void 0 && { legacy: params.legacy }
|
|
962
983
|
}
|
|
963
984
|
});
|
|
964
985
|
}
|
|
@@ -982,10 +1003,23 @@ function deriveLightningReceive(input) {
|
|
|
982
1003
|
payoutPubkey: input.payoutPubkey,
|
|
983
1004
|
payoutPkScript: ArkAddress2.decode(input.payoutAddress).pkScript
|
|
984
1005
|
};
|
|
985
|
-
const
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1006
|
+
const matched = matchQuotedLockup(
|
|
1007
|
+
quote,
|
|
1008
|
+
input.hrp,
|
|
1009
|
+
input.serverPubkey,
|
|
1010
|
+
(legacy) => receiveVtxoScript({ ...treeParams, ...legacy !== void 0 && { legacy } })
|
|
1011
|
+
);
|
|
1012
|
+
return {
|
|
1013
|
+
address: matched.address,
|
|
1014
|
+
swapPkScript: matched.script.pkScript,
|
|
1015
|
+
script: matched.script,
|
|
1016
|
+
invoice,
|
|
1017
|
+
refundLocktime,
|
|
1018
|
+
treeParams: {
|
|
1019
|
+
...treeParams,
|
|
1020
|
+
...matched.legacy !== void 0 && { legacy: matched.legacy }
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
989
1023
|
}
|
|
990
1024
|
async function requestLightningReceive(wallet, arkServerUrl, transport, params) {
|
|
991
1025
|
const rfqId = params.rfqId ?? newRfqId();
|
|
@@ -1073,7 +1107,7 @@ function deriveOnchainReceive(input) {
|
|
|
1073
1107
|
if (refundLocktime === void 0 || claimPubkey === void 0 || htlcLocktime === void 0 || minConfirmations === void 0 || solverRefundPkScriptHex === void 0) {
|
|
1074
1108
|
throw new Error("onchain-receive quote is missing a binding field");
|
|
1075
1109
|
}
|
|
1076
|
-
const
|
|
1110
|
+
const treeParams = {
|
|
1077
1111
|
solverPubkey: toXOnly(hex3.decode(quote.solver_pubkey), "solver key"),
|
|
1078
1112
|
refundLocktime,
|
|
1079
1113
|
serverPubkey: input.serverPubkey,
|
|
@@ -1083,9 +1117,13 @@ function deriveOnchainReceive(input) {
|
|
|
1083
1117
|
solverRefundPkScript: solverHex(solverRefundPkScriptHex, "profile.solver_refund_pk_script"),
|
|
1084
1118
|
payoutPubkey: input.payoutPubkey,
|
|
1085
1119
|
payoutPkScript: ArkAddress2.decode(input.payoutAddress).pkScript
|
|
1086
|
-
}
|
|
1087
|
-
const address =
|
|
1088
|
-
|
|
1120
|
+
};
|
|
1121
|
+
const { script, address } = matchQuotedLockup(
|
|
1122
|
+
quote,
|
|
1123
|
+
input.hrp,
|
|
1124
|
+
input.serverPubkey,
|
|
1125
|
+
(legacy) => receiveVtxoScript({ ...treeParams, ...legacy !== void 0 && { legacy } })
|
|
1126
|
+
);
|
|
1089
1127
|
const htlc = onchainHtlcScript(
|
|
1090
1128
|
{
|
|
1091
1129
|
paymentHash: input.paymentHash,
|