@arkade-os/swap 0.0.18 → 0.0.20
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 +2 -1
- package/dist/{chunk-N3W6LXH6.js → chunk-QJKMTPRQ.js} +1047 -96
- package/dist/index.cjs +230 -38
- package/dist/index.d.cts +16 -8
- package/dist/index.d.ts +16 -8
- package/dist/index.js +156 -862
- package/dist/nostr.cjs +108 -3
- 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-BwasQwkR.d.cts → repository-BrTpVPLy.d.ts} +4 -1
- package/dist/{repository-CucjFZN1.d.ts → repository-Cop29z0c.d.cts} +4 -1
- package/dist/{rfq-B_2hM0xk.d.ts → rfq-B95nPfaa.d.cts} +125 -10
- package/dist/{rfq-B_2hM0xk.d.cts → rfq-B95nPfaa.d.ts} +125 -10
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -84,6 +84,7 @@ __export(index_exports, {
|
|
|
84
84
|
arkadeAssetLeg: () => arkadeAssetLeg,
|
|
85
85
|
arkadeRefunder: () => arkadeRefunder,
|
|
86
86
|
arkadeSwapRequest: () => arkadeSwapRequest,
|
|
87
|
+
assertArkadeFundable: () => assertArkadeFundable,
|
|
87
88
|
assertFundable: () => assertFundable,
|
|
88
89
|
assertReceivable: () => assertReceivable,
|
|
89
90
|
awaitLockupFunding: () => awaitLockupFunding,
|
|
@@ -92,6 +93,7 @@ __export(index_exports, {
|
|
|
92
93
|
buildHtlcClaim: () => buildHtlcClaim,
|
|
93
94
|
buildHtlcRefund: () => buildHtlcRefund,
|
|
94
95
|
cancelOffer: () => cancelOffer,
|
|
96
|
+
canonicalAssetAmount: () => canonicalAssetAmount,
|
|
95
97
|
chainSourceFrom: () => chainSourceFrom,
|
|
96
98
|
claimOnchainFill: () => claimOnchainFill,
|
|
97
99
|
claimPacketShape: () => claimPacketShape,
|
|
@@ -132,6 +134,8 @@ __export(index_exports, {
|
|
|
132
134
|
newPreimage: () => newPreimage,
|
|
133
135
|
newRfqId: () => newRfqId,
|
|
134
136
|
nextOnchainAction: () => nextOnchainAction,
|
|
137
|
+
normalizeMakerPkScript: () => normalizeMakerPkScript,
|
|
138
|
+
normalizeMakerPublicKey: () => normalizeMakerPublicKey,
|
|
135
139
|
offerTermsFromQuote: () => offerTermsFromQuote,
|
|
136
140
|
offerVtxoScript: () => offerVtxoScript,
|
|
137
141
|
onchainHtlcScript: () => onchainHtlcScript,
|
|
@@ -149,6 +153,7 @@ __export(index_exports, {
|
|
|
149
153
|
registerAssetSwapRestore: () => registerAssetSwapRestore,
|
|
150
154
|
registerLockupContract: () => registerLockupContract,
|
|
151
155
|
relayTransport: () => relayTransport,
|
|
156
|
+
requestArkadeSwap: () => requestArkadeSwap,
|
|
152
157
|
requestLightningReceive: () => requestLightningReceive,
|
|
153
158
|
requestLightningSend: () => requestLightningSend,
|
|
154
159
|
requestOnchainReceive: () => requestOnchainReceive,
|
|
@@ -186,6 +191,7 @@ __export(index_exports, {
|
|
|
186
191
|
updateRfqSwapRecord: () => updateRfqSwapRecord,
|
|
187
192
|
validatePlan: () => validatePlan,
|
|
188
193
|
verifyLockupAddress: () => verifyLockupAddress,
|
|
194
|
+
verifyOfferAddress: () => verifyOfferAddress,
|
|
189
195
|
verifyReceiveInvoice: () => verifyReceiveInvoice,
|
|
190
196
|
watchOfferSwaps: () => watchOfferSwaps
|
|
191
197
|
});
|
|
@@ -1064,12 +1070,14 @@ var discoverMarkets = async (options) => {
|
|
|
1064
1070
|
fetchImpl,
|
|
1065
1071
|
useCache = true
|
|
1066
1072
|
} = options;
|
|
1067
|
-
if (!
|
|
1068
|
-
const
|
|
1073
|
+
if (!(0, import_solver_discovery.isNetwork)(network)) return [];
|
|
1074
|
+
const registries = registry ? [registry] : void 0;
|
|
1075
|
+
const registryKey = registries?.[0] ?? (0, import_solver_discovery.registryIndexUrl)(network);
|
|
1076
|
+
const cached = repository && await readMarketsCache(repository, network, registryKey);
|
|
1069
1077
|
if (useCache && cached && Date.now() - cached.fetchedAt < MARKETS_CACHE_TTL_MS)
|
|
1070
1078
|
return cached.markets;
|
|
1071
1079
|
const { markets, sources, warnings } = await (0, import_solver_discovery.discover)({
|
|
1072
|
-
registries
|
|
1080
|
+
registries,
|
|
1073
1081
|
localCards,
|
|
1074
1082
|
network,
|
|
1075
1083
|
fetchImpl
|
|
@@ -1079,7 +1087,7 @@ var discoverMarkets = async (options) => {
|
|
|
1079
1087
|
if (!reachable && cached) return cached.markets;
|
|
1080
1088
|
if (reachable && repository) {
|
|
1081
1089
|
try {
|
|
1082
|
-
await repository.saveCachedMarkets(network,
|
|
1090
|
+
await repository.saveCachedMarkets(network, registryKey, {
|
|
1083
1091
|
markets,
|
|
1084
1092
|
fetchedAt: Date.now()
|
|
1085
1093
|
});
|
|
@@ -1980,6 +1988,7 @@ function onchainSendProfile(result) {
|
|
|
1980
1988
|
network: result.l1Network,
|
|
1981
1989
|
htlcAddress: result.htlc.address,
|
|
1982
1990
|
minConfirmations: result.minConfirmations,
|
|
1991
|
+
expectedAmount: result.expectedAmount,
|
|
1983
1992
|
payoutPkScript: import_base5.hex.encode(result.payoutPkScript)
|
|
1984
1993
|
};
|
|
1985
1994
|
}
|
|
@@ -1991,6 +2000,7 @@ var OnchainSendCorridor = {
|
|
|
1991
2000
|
project: (swap) => {
|
|
1992
2001
|
const send = swap;
|
|
1993
2002
|
return {
|
|
2003
|
+
expectedAmount: send.expectedAmount,
|
|
1994
2004
|
...send.funding ? { funding: send.funding } : {},
|
|
1995
2005
|
...send.claimTxid ? { claimTxid: send.claimTxid } : {}
|
|
1996
2006
|
};
|
|
@@ -2007,6 +2017,11 @@ var OnchainSendCorridor = {
|
|
|
2007
2017
|
`onchain_send record carries no usable minConfirmations (${String(profile.minConfirmations)}); the confirmation gate cannot be checked \u2014 refusing to restore a swap that would claim an unconfirmed fill`
|
|
2008
2018
|
);
|
|
2009
2019
|
}
|
|
2020
|
+
if (!Number.isSafeInteger(profile.expectedAmount) || profile.expectedAmount <= 0) {
|
|
2021
|
+
throw new Error(
|
|
2022
|
+
`onchain_send record carries no usable expectedAmount (${String(profile.expectedAmount)}); the funded value cannot be checked \u2014 refusing to restore a swap that would claim an underfunded fill`
|
|
2023
|
+
);
|
|
2024
|
+
}
|
|
2010
2025
|
const htlc = onchainHtlcScript(
|
|
2011
2026
|
{
|
|
2012
2027
|
// From the profile, not the covenant: the lockup commits to
|
|
@@ -2029,6 +2044,7 @@ var OnchainSendCorridor = {
|
|
|
2029
2044
|
paymentHash,
|
|
2030
2045
|
htlc,
|
|
2031
2046
|
minConfirmations: profile.minConfirmations,
|
|
2047
|
+
expectedAmount: profile.expectedAmount,
|
|
2032
2048
|
// Optional here, required at the write: throwing on an older
|
|
2033
2049
|
// record would strand the refund it is still owed.
|
|
2034
2050
|
...profile.payoutPkScript ? { payoutPkScript: import_base5.hex.decode(profile.payoutPkScript) } : {},
|
|
@@ -2419,6 +2435,12 @@ var solverHex = (value, field) => {
|
|
|
2419
2435
|
throw new Error(`solver sent malformed hex for ${field}`);
|
|
2420
2436
|
}
|
|
2421
2437
|
};
|
|
2438
|
+
var quoteSats = (value, field) => {
|
|
2439
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value)) {
|
|
2440
|
+
throw new Error(`HTLC quote carries a non-sats ${field}: ${String(value)}`);
|
|
2441
|
+
}
|
|
2442
|
+
return value;
|
|
2443
|
+
};
|
|
2422
2444
|
var ARKADE_BTC = "arkade:BTC";
|
|
2423
2445
|
var LIGHTNING_BTC = "lightning:BTC";
|
|
2424
2446
|
var ONCHAIN_BTC = "onchain:BTC";
|
|
@@ -2530,12 +2552,7 @@ var lightningSendRequest = (input) => ({
|
|
|
2530
2552
|
var arkadeSwapRequest = (input) => {
|
|
2531
2553
|
if (!input.wantAsset && !input.offerAsset) {
|
|
2532
2554
|
throw new Error(
|
|
2533
|
-
"set
|
|
2534
|
-
);
|
|
2535
|
-
}
|
|
2536
|
-
if (input.wantAsset && input.offerAsset) {
|
|
2537
|
-
throw new Error(
|
|
2538
|
-
"set exactly one of wantAsset (BTC->asset) or offerAsset (asset->BTC) \u2014 asset->asset is nameable on the wire but no solver quotes it yet"
|
|
2555
|
+
"set at least one of wantAsset or offerAsset \u2014 with neither set both legs are BTC, which is not a swap"
|
|
2539
2556
|
);
|
|
2540
2557
|
}
|
|
2541
2558
|
const pair = rfqPair(
|
|
@@ -2548,16 +2565,59 @@ var arkadeSwapRequest = (input) => {
|
|
|
2548
2565
|
type: "rfq_request",
|
|
2549
2566
|
rfq_id: input.rfqId,
|
|
2550
2567
|
pair,
|
|
2551
|
-
amount_side: input.amountSide,
|
|
2552
|
-
amount: input.amount,
|
|
2553
|
-
// The pair
|
|
2554
|
-
//
|
|
2555
|
-
//
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2568
|
+
amount_side: input.amountSide ?? "from",
|
|
2569
|
+
amount: canonicalAssetAmount(input.amount),
|
|
2570
|
+
// The pair names the assets; the profile names the trader. Both are
|
|
2571
|
+
// covenant parameters, and the solver's `.strict()` schema refuses
|
|
2572
|
+
// anything else — an undeclared key is `unsupported_payload`.
|
|
2573
|
+
profile: {
|
|
2574
|
+
maker_pk_script: normalizeMakerPkScript(input.makerPkScript),
|
|
2575
|
+
maker_public_key: normalizeMakerPublicKey(input.makerPublicKey)
|
|
2576
|
+
}
|
|
2559
2577
|
};
|
|
2560
2578
|
};
|
|
2579
|
+
var canonicalAssetAmount = (amount) => {
|
|
2580
|
+
if (typeof amount === "bigint") {
|
|
2581
|
+
if (amount <= 0n) throw new Error(`amount must be positive, got ${amount}`);
|
|
2582
|
+
return amount.toString();
|
|
2583
|
+
}
|
|
2584
|
+
if (typeof amount === "number") {
|
|
2585
|
+
if (!Number.isSafeInteger(amount) || amount <= 0) {
|
|
2586
|
+
throw new Error(`amount must be a positive safe integer, got ${amount}`);
|
|
2587
|
+
}
|
|
2588
|
+
return String(amount);
|
|
2589
|
+
}
|
|
2590
|
+
if (!/^(0|[1-9][0-9]*)$/.test(amount) || BigInt(amount) <= 0n) {
|
|
2591
|
+
throw new Error(`amount must be a canonical decimal string of atomic units, got ${amount}`);
|
|
2592
|
+
}
|
|
2593
|
+
return amount;
|
|
2594
|
+
};
|
|
2595
|
+
var normalizeHexBytes = (value, expectedBytes, label) => {
|
|
2596
|
+
if (value === void 0 || value === null) {
|
|
2597
|
+
throw new Error(`${label} is required`);
|
|
2598
|
+
}
|
|
2599
|
+
const bytes = typeof value === "string" ? solverHex(value, label) : value;
|
|
2600
|
+
if (!(bytes instanceof Uint8Array) || bytes.length !== expectedBytes) {
|
|
2601
|
+
const got = bytes instanceof Uint8Array ? bytes.length : typeof bytes;
|
|
2602
|
+
throw new Error(`${label} must be ${expectedBytes} bytes, got ${got}`);
|
|
2603
|
+
}
|
|
2604
|
+
return import_base10.hex.encode(bytes);
|
|
2605
|
+
};
|
|
2606
|
+
var normalizeMakerPkScript = (value) => {
|
|
2607
|
+
const encoded = normalizeHexBytes(value, 34, "maker_pk_script");
|
|
2608
|
+
if (!encoded.startsWith("5100") && !encoded.startsWith("5120")) {
|
|
2609
|
+
throw new Error("maker_pk_script must be a taproot scriptPubKey (OP_1 <32-byte program>)");
|
|
2610
|
+
}
|
|
2611
|
+
return encoded;
|
|
2612
|
+
};
|
|
2613
|
+
var normalizeMakerPublicKey = (value) => {
|
|
2614
|
+
const raw = typeof value === "string" ? value : import_base10.hex.encode(value);
|
|
2615
|
+
const bytes = solverHex(raw, "maker_public_key");
|
|
2616
|
+
if (bytes.length === 33) {
|
|
2617
|
+
throw new Error("maker_public_key must be x-only (32 bytes), not compressed (33 bytes)");
|
|
2618
|
+
}
|
|
2619
|
+
return normalizeHexBytes(bytes, 32, "maker_public_key");
|
|
2620
|
+
};
|
|
2561
2621
|
var MIN_HEADROOM_SECONDS = 90 * 60;
|
|
2562
2622
|
var gateError = (reason, message) => {
|
|
2563
2623
|
const error = new Error(message);
|
|
@@ -2605,6 +2665,9 @@ var assertFundable = (input) => {
|
|
|
2605
2665
|
}
|
|
2606
2666
|
if (input.now >= input.quote.valid_until)
|
|
2607
2667
|
fail("quote_expired", "quote expired \u2014 request a fresh one");
|
|
2668
|
+
if (quoteSats(input.quote.from_amount, "from_amount") <= 0 || quoteSats(input.quote.to_amount, "to_amount") <= 0) {
|
|
2669
|
+
fail("non_positive_amount", "quote carries a non-positive amount");
|
|
2670
|
+
}
|
|
2608
2671
|
if (input.quote.refund_locktime !== void 0 && input.quote.refund_locktime - input.now < MIN_HEADROOM_SECONDS) {
|
|
2609
2672
|
fail("insufficient_headroom", "refund deadline headroom below 90 minutes");
|
|
2610
2673
|
}
|
|
@@ -2634,13 +2697,12 @@ var assertFundable = (input) => {
|
|
|
2634
2697
|
`maxFee.referenceRate must be a positive finite number, got ${referenceRate}`
|
|
2635
2698
|
);
|
|
2636
2699
|
}
|
|
2637
|
-
const
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
sats ?? 0,
|
|
2642
|
-
Math.floor(input.quote.from_amount * (bps ?? 0) / 1e4)
|
|
2700
|
+
const fromSats = quoteSats(input.quote.from_amount, "from_amount");
|
|
2701
|
+
const toSats = quoteSats(input.quote.to_amount, "to_amount");
|
|
2702
|
+
const fee = sameAsset ? fromSats - toSats : Math.ceil(
|
|
2703
|
+
(fromSats * referenceRate - toSats) / referenceRate
|
|
2643
2704
|
);
|
|
2705
|
+
const allowed = Math.max(sats ?? 0, Math.floor(fromSats * (bps ?? 0) / 1e4));
|
|
2644
2706
|
if (fee > allowed) {
|
|
2645
2707
|
fail("fee_too_high", `fee ${fee} exceeds the ${allowed} this client allows`);
|
|
2646
2708
|
}
|
|
@@ -2882,12 +2944,12 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
|
2882
2944
|
if (receiverPkScriptHex === void 0) {
|
|
2883
2945
|
throw new Error("lightning-send quote is missing profile.receiver_pk_script");
|
|
2884
2946
|
}
|
|
2885
|
-
if (quote.to_amount !== params.invoice.amountSats) {
|
|
2947
|
+
if (quoteSats(quote.to_amount, "to_amount") !== params.invoice.amountSats) {
|
|
2886
2948
|
throw new Error(
|
|
2887
2949
|
`quote to_amount ${quote.to_amount} does not match the invoice's ${params.invoice.amountSats}`
|
|
2888
2950
|
);
|
|
2889
2951
|
}
|
|
2890
|
-
if (quote.from_amount < quote.to_amount) {
|
|
2952
|
+
if (quoteSats(quote.from_amount, "from_amount") < quoteSats(quote.to_amount, "to_amount")) {
|
|
2891
2953
|
throw new Error(
|
|
2892
2954
|
`quote from_amount ${quote.from_amount} is below the invoice amount \u2014 a negative spread is not a quote`
|
|
2893
2955
|
);
|
|
@@ -2933,7 +2995,7 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
|
2933
2995
|
address,
|
|
2934
2996
|
// What the lockup must carry: the quote's `from_amount` — the invoice
|
|
2935
2997
|
// PLUS the corridor's fee, never the bare invoice amount.
|
|
2936
|
-
fundAmount: quote.from_amount,
|
|
2998
|
+
fundAmount: quoteSats(quote.from_amount, "from_amount"),
|
|
2937
2999
|
swapPkScript: script.pkScript,
|
|
2938
3000
|
script,
|
|
2939
3001
|
refundAddress,
|
|
@@ -2943,11 +3005,116 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
|
|
|
2943
3005
|
};
|
|
2944
3006
|
}
|
|
2945
3007
|
var offerTermsFromQuote = (quote, assets) => {
|
|
2946
|
-
if (
|
|
2947
|
-
throw new Error("set
|
|
3008
|
+
if (!assets.wantAsset && !assets.offerAsset) {
|
|
3009
|
+
throw new Error("set at least one of wantAsset or offerAsset");
|
|
2948
3010
|
}
|
|
2949
|
-
|
|
3011
|
+
const wantAmount = BigInt(quote.to_amount);
|
|
3012
|
+
if (assets.wantAsset) return { wantAmount, wantAsset: assets.wantAsset };
|
|
3013
|
+
return { wantAmount, offerAsset: assets.offerAsset };
|
|
3014
|
+
};
|
|
3015
|
+
var verifyOfferAddress = (quote, derived) => {
|
|
3016
|
+
const quotedAddress = quote.profile?.offer_address;
|
|
3017
|
+
const quotedScript = quote.profile?.offer_pk_script;
|
|
3018
|
+
const derivedScript = import_base10.hex.encode(derived.swapPkScript);
|
|
3019
|
+
if (quotedAddress !== derived.address || quotedScript !== derivedScript) {
|
|
3020
|
+
throw new AddressMismatch([derived.address], quotedAddress);
|
|
3021
|
+
}
|
|
3022
|
+
return derived;
|
|
2950
3023
|
};
|
|
3024
|
+
var assertArkadeFundable = (input) => {
|
|
3025
|
+
const now = input.now ?? Math.floor(Date.now() / 1e3);
|
|
3026
|
+
if (!Number.isSafeInteger(input.quote.valid_until)) {
|
|
3027
|
+
throw gateError("quote_expired", "quote carries no valid_until");
|
|
3028
|
+
}
|
|
3029
|
+
if (now >= input.quote.valid_until) {
|
|
3030
|
+
throw gateError("quote_expired", `quote lapsed at ${input.quote.valid_until} (now ${now})`);
|
|
3031
|
+
}
|
|
3032
|
+
if (BigInt(input.quote.from_amount) <= 0n || BigInt(input.quote.to_amount) <= 0n) {
|
|
3033
|
+
throw gateError("quote_expired", "quote carries a non-positive amount");
|
|
3034
|
+
}
|
|
3035
|
+
};
|
|
3036
|
+
var quoteCarrierSats = (quote) => {
|
|
3037
|
+
const published = quote.carrier_sats === void 0 ? 0n : BigInt(quote.carrier_sats);
|
|
3038
|
+
return published > 0n ? published : ASSET_CARRIER_SATS;
|
|
3039
|
+
};
|
|
3040
|
+
async function requestArkadeSwap(wallet, arkServerUrl, transport, params) {
|
|
3041
|
+
if (!params.wantAsset && !params.offerAsset) {
|
|
3042
|
+
throw new Error("set at least one of wantAsset or offerAsset; BTC-to-BTC is not a swap");
|
|
3043
|
+
}
|
|
3044
|
+
const rfqId = params.rfqId ?? newRfqId();
|
|
3045
|
+
const amountSide = params.amountSide ?? "from";
|
|
3046
|
+
const [makerAddress, makerPublicKey] = await Promise.all([
|
|
3047
|
+
wallet.getAddress(),
|
|
3048
|
+
wallet.identity.xOnlyPublicKey()
|
|
3049
|
+
]);
|
|
3050
|
+
const makerPkScript = import_sdk10.ArkAddress.decode(makerAddress).pkScript;
|
|
3051
|
+
const pair = rfqPair(
|
|
3052
|
+
params.offerAsset ? arkadeAssetLeg(params.offerAsset) : ARKADE_BTC,
|
|
3053
|
+
params.wantAsset ? arkadeAssetLeg(params.wantAsset) : ARKADE_BTC
|
|
3054
|
+
);
|
|
3055
|
+
const quote = await transport.requestQuote(
|
|
3056
|
+
arkadeSwapRequest({
|
|
3057
|
+
rfqId,
|
|
3058
|
+
...params.offerAsset !== void 0 ? { offerAsset: params.offerAsset } : {},
|
|
3059
|
+
...params.wantAsset !== void 0 ? { wantAsset: params.wantAsset } : {},
|
|
3060
|
+
amount: params.amount,
|
|
3061
|
+
amountSide,
|
|
3062
|
+
makerPkScript,
|
|
3063
|
+
makerPublicKey
|
|
3064
|
+
})
|
|
3065
|
+
);
|
|
3066
|
+
if (quote.pair !== pair) {
|
|
3067
|
+
throw new Error(`solver quoted ${JSON.stringify(quote.pair)}, not the requested ${pair}`);
|
|
3068
|
+
}
|
|
3069
|
+
assertArkadeFundable({ quote, ...params.now !== void 0 ? { now: params.now } : {} });
|
|
3070
|
+
const terms = offerTermsFromQuote(quote, {
|
|
3071
|
+
...params.offerAsset !== void 0 ? { offerAsset: params.offerAsset } : {},
|
|
3072
|
+
...params.wantAsset !== void 0 ? { wantAsset: params.wantAsset } : {}
|
|
3073
|
+
});
|
|
3074
|
+
const quoted = amountSide === "from" ? quote.from_amount : quote.to_amount;
|
|
3075
|
+
if (BigInt(quoted).toString() !== canonicalAssetAmount(params.amount)) {
|
|
3076
|
+
throw new Error(
|
|
3077
|
+
`quote ${amountSide}_amount ${quoted} does not match the requested ${canonicalAssetAmount(params.amount)}`
|
|
3078
|
+
);
|
|
3079
|
+
}
|
|
3080
|
+
if (params.maxFromAmount !== void 0) {
|
|
3081
|
+
const cap = BigInt(canonicalAssetAmount(params.maxFromAmount));
|
|
3082
|
+
if (BigInt(quote.from_amount) > cap) {
|
|
3083
|
+
throw gateError(
|
|
3084
|
+
"quote_amount_rejected",
|
|
3085
|
+
`quote from_amount ${quote.from_amount} exceeds maxFromAmount ${cap}`
|
|
3086
|
+
);
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
if (params.minToAmount !== void 0) {
|
|
3090
|
+
const floorAmount = BigInt(canonicalAssetAmount(params.minToAmount));
|
|
3091
|
+
if (BigInt(quote.to_amount) < floorAmount) {
|
|
3092
|
+
throw gateError(
|
|
3093
|
+
"quote_amount_rejected",
|
|
3094
|
+
`quote to_amount ${quote.to_amount} is under minToAmount ${floorAmount}`
|
|
3095
|
+
);
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3098
|
+
const offer = await createOffer(wallet, arkServerUrl, {
|
|
3099
|
+
wantAmount: terms.wantAmount,
|
|
3100
|
+
...terms.wantAsset !== void 0 ? { wantAsset: terms.wantAsset } : {},
|
|
3101
|
+
...terms.offerAsset !== void 0 ? { offerAsset: terms.offerAsset } : {},
|
|
3102
|
+
...params.emulatorPubkey !== void 0 ? { emulatorPubkey: params.emulatorPubkey } : {}
|
|
3103
|
+
});
|
|
3104
|
+
verifyOfferAddress(quote, offer);
|
|
3105
|
+
const fundAmount = BigInt(quote.from_amount);
|
|
3106
|
+
return {
|
|
3107
|
+
rfqId,
|
|
3108
|
+
quote,
|
|
3109
|
+
pair,
|
|
3110
|
+
address: offer.address,
|
|
3111
|
+
fundAmount,
|
|
3112
|
+
carrierSats: params.offerAsset !== void 0 ? quoteCarrierSats(quote) : 0n,
|
|
3113
|
+
swapPkScript: offer.swapPkScript,
|
|
3114
|
+
offerHex: offer.offerHex,
|
|
3115
|
+
extension: offer.extension
|
|
3116
|
+
};
|
|
3117
|
+
}
|
|
2951
3118
|
var l1NetworkFromArk = (network) => network === "bitcoin" ? "bitcoin" : network === "regtest" ? "regtest" : "testnet";
|
|
2952
3119
|
var onchainSendRequest = (input) => ({
|
|
2953
3120
|
v: 1,
|
|
@@ -3038,7 +3205,8 @@ function deriveOnchainSend(input) {
|
|
|
3038
3205
|
l1Network: input.l1Network,
|
|
3039
3206
|
refundLocktime,
|
|
3040
3207
|
htlcLocktime,
|
|
3041
|
-
minConfirmations
|
|
3208
|
+
minConfirmations,
|
|
3209
|
+
expectedAmount: quoteSats(quote.to_amount, "to_amount")
|
|
3042
3210
|
};
|
|
3043
3211
|
}
|
|
3044
3212
|
async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
|
|
@@ -3101,7 +3269,8 @@ async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
|
|
|
3101
3269
|
rfqId,
|
|
3102
3270
|
quote,
|
|
3103
3271
|
address: derived.address,
|
|
3104
|
-
fundAmount: quote.from_amount,
|
|
3272
|
+
fundAmount: quoteSats(quote.from_amount, "from_amount"),
|
|
3273
|
+
expectedAmount: quoteSats(quote.to_amount, "to_amount"),
|
|
3105
3274
|
swapPkScript: derived.swapPkScript,
|
|
3106
3275
|
script: derived.script,
|
|
3107
3276
|
refundAddress,
|
|
@@ -3114,7 +3283,7 @@ async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
|
|
|
3114
3283
|
};
|
|
3115
3284
|
}
|
|
3116
3285
|
var assertQuotedAmount = (quote, amountSide, amount) => {
|
|
3117
|
-
const quoted = amountSide === "from" ? quote.from_amount : quote.to_amount;
|
|
3286
|
+
const quoted = amountSide === "from" ? quoteSats(quote.from_amount, "from_amount") : quoteSats(quote.to_amount, "to_amount");
|
|
3118
3287
|
if (quoted !== amount) {
|
|
3119
3288
|
throw new Error(
|
|
3120
3289
|
`quote ${amountSide === "from" ? "from_amount" : "to_amount"} ${quoted} does not match the requested ${amount} \u2014 not this trade's quote`
|
|
@@ -3173,7 +3342,7 @@ var assertReceivable = (input) => {
|
|
|
3173
3342
|
`a payment at the deadline would leave under ${minClaimWindow}s to claim before the solver's refund opens`
|
|
3174
3343
|
);
|
|
3175
3344
|
}
|
|
3176
|
-
if (input.maxPayAmount !== void 0 && input.quote.from_amount > input.maxPayAmount) {
|
|
3345
|
+
if (input.maxPayAmount !== void 0 && quoteSats(input.quote.from_amount, "from_amount") > input.maxPayAmount) {
|
|
3177
3346
|
throw gateError(
|
|
3178
3347
|
"price_too_high",
|
|
3179
3348
|
`quote asks ${input.quote.from_amount} sats, above the ${input.maxPayAmount} ceiling`
|
|
@@ -3304,8 +3473,8 @@ async function requestLightningReceive(wallet, arkServerUrl, transport, params)
|
|
|
3304
3473
|
rfqId,
|
|
3305
3474
|
quote,
|
|
3306
3475
|
invoice: derived.invoice,
|
|
3307
|
-
payAmount: quote.from_amount,
|
|
3308
|
-
expectedAmount: quote.to_amount,
|
|
3476
|
+
payAmount: quoteSats(quote.from_amount, "from_amount"),
|
|
3477
|
+
expectedAmount: quoteSats(quote.to_amount, "to_amount"),
|
|
3309
3478
|
invoiceExpiresAt: payDeadline,
|
|
3310
3479
|
address: derived.address,
|
|
3311
3480
|
swapPkScript: derived.swapPkScript,
|
|
@@ -3431,8 +3600,8 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
|
|
|
3431
3600
|
rfqId,
|
|
3432
3601
|
quote,
|
|
3433
3602
|
address: derived.address,
|
|
3434
|
-
fundAmount: quote.from_amount,
|
|
3435
|
-
expectedAmount: quote.to_amount,
|
|
3603
|
+
fundAmount: quoteSats(quote.from_amount, "from_amount"),
|
|
3604
|
+
expectedAmount: quoteSats(quote.to_amount, "to_amount"),
|
|
3436
3605
|
swapPkScript: derived.swapPkScript,
|
|
3437
3606
|
script: derived.script,
|
|
3438
3607
|
htlc: derived.htlc,
|
|
@@ -5144,6 +5313,21 @@ var RfqSwapManager = class {
|
|
|
5144
5313
|
});
|
|
5145
5314
|
if (action === "claim" && phase.phase === "claimable") {
|
|
5146
5315
|
if (swap.claimTxid) return "continue";
|
|
5316
|
+
if (!Number.isSafeInteger(swap.expectedAmount) || swap.expectedAmount <= 0) {
|
|
5317
|
+
this.block(
|
|
5318
|
+
swap,
|
|
5319
|
+
`expectedAmount is not a positive number of sats (${String(swap.expectedAmount)}), so the funded value cannot be checked \u2014 refusing to publish the preimage`
|
|
5320
|
+
);
|
|
5321
|
+
return "handled";
|
|
5322
|
+
}
|
|
5323
|
+
const filled = Number(phase.utxo.amount);
|
|
5324
|
+
if (!Number.isFinite(filled) || filled < swap.expectedAmount) {
|
|
5325
|
+
this.block(
|
|
5326
|
+
swap,
|
|
5327
|
+
`fill holds ${filled} sats, below the agreed ${swap.expectedAmount} \u2014 refusing to publish the preimage`
|
|
5328
|
+
);
|
|
5329
|
+
return "handled";
|
|
5330
|
+
}
|
|
5147
5331
|
if (this.callbacks && !this.callbacks.claimOnchain) {
|
|
5148
5332
|
this.block(
|
|
5149
5333
|
swap,
|
|
@@ -5197,6 +5381,8 @@ var RfqSwapManager = class {
|
|
|
5197
5381
|
if (pushed) {
|
|
5198
5382
|
swap.refundArkTxid = pushed.arkTxid;
|
|
5199
5383
|
this.touch(swap);
|
|
5384
|
+
} else if (now < swap.refundLocktime + REFUND_MTP_LAG_SECONDS) {
|
|
5385
|
+
return;
|
|
5200
5386
|
}
|
|
5201
5387
|
this.setState(swap, "refunded");
|
|
5202
5388
|
this.emitAction(swap, "refundArkade");
|
|
@@ -5565,6 +5751,7 @@ async function lockupTxids(indexer, record, wantFunding) {
|
|
|
5565
5751
|
arkadeAssetLeg,
|
|
5566
5752
|
arkadeRefunder,
|
|
5567
5753
|
arkadeSwapRequest,
|
|
5754
|
+
assertArkadeFundable,
|
|
5568
5755
|
assertFundable,
|
|
5569
5756
|
assertReceivable,
|
|
5570
5757
|
awaitLockupFunding,
|
|
@@ -5573,6 +5760,7 @@ async function lockupTxids(indexer, record, wantFunding) {
|
|
|
5573
5760
|
buildHtlcClaim,
|
|
5574
5761
|
buildHtlcRefund,
|
|
5575
5762
|
cancelOffer,
|
|
5763
|
+
canonicalAssetAmount,
|
|
5576
5764
|
chainSourceFrom,
|
|
5577
5765
|
claimOnchainFill,
|
|
5578
5766
|
claimPacketShape,
|
|
@@ -5613,6 +5801,8 @@ async function lockupTxids(indexer, record, wantFunding) {
|
|
|
5613
5801
|
newPreimage,
|
|
5614
5802
|
newRfqId,
|
|
5615
5803
|
nextOnchainAction,
|
|
5804
|
+
normalizeMakerPkScript,
|
|
5805
|
+
normalizeMakerPublicKey,
|
|
5616
5806
|
offerTermsFromQuote,
|
|
5617
5807
|
offerVtxoScript,
|
|
5618
5808
|
onchainHtlcScript,
|
|
@@ -5630,6 +5820,7 @@ async function lockupTxids(indexer, record, wantFunding) {
|
|
|
5630
5820
|
registerAssetSwapRestore,
|
|
5631
5821
|
registerLockupContract,
|
|
5632
5822
|
relayTransport,
|
|
5823
|
+
requestArkadeSwap,
|
|
5633
5824
|
requestLightningReceive,
|
|
5634
5825
|
requestLightningSend,
|
|
5635
5826
|
requestOnchainReceive,
|
|
@@ -5667,6 +5858,7 @@ async function lockupTxids(indexer, record, wantFunding) {
|
|
|
5667
5858
|
updateRfqSwapRecord,
|
|
5668
5859
|
validatePlan,
|
|
5669
5860
|
verifyLockupAddress,
|
|
5861
|
+
verifyOfferAddress,
|
|
5670
5862
|
verifyReceiveInvoice,
|
|
5671
5863
|
watchOfferSwaps
|
|
5672
5864
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ProvisionedKey, ProvisionedClaimSecret, ArkTxInput, asset, RelativeTimelock, IWallet, EmulatorProvider, arkade, RestIndexerProvider, Transaction, IContractManager, OnchainProvider, PaymentRail, Asset, VHTLC, Identity, ActivityResolver } from '@arkade-os/sdk';
|
|
2
|
-
import { S as SwapSecretsProjection, R as RfqSwapRecord, A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry, b as RefundArkProvider, c as RefundIndexer, L as LockupVtxo, d as RfqSwap, e as ArkadeRefundResult, f as LockupSpendIndexer, g as RfqSwapState } from './repository-
|
|
3
|
-
export { h as AssetSwapStatus, i as AvailableRfqSwapManagerCallbacks, B as BTC_ASSET_ID, I as InMemoryAssetSwapRepository, j as LightningReceiveSwap, k as LightningSendSwap, l as LockupFate, m as LockupNeedsRecoveryError, n as LockupParams, o as LockupSpend, O as OnchainSendAction, p as OnchainSendSwap, P as PersistableRfqSwap, q as PreimageBlockedReason, r as PreimageNotRecoverableError, s as REFUND_MTP_LAG_SECONDS, t as RFQ_RESOLVED_STATES, u as RFQ_SWAP_RETENTION_SECONDS, v as RFQ_SWAP_TERMINAL_STATES, w as RefundOutcome, x as RfqRestoreFailure, y as RfqRestoreOptions, z as RfqRestoreResult, C as RfqSwapActionName, D as RfqSwapLockup, E as RfqSwapManager, F as RfqSwapManagerCallbacks, G as RfqSwapManagerConfig, H as RfqSwapManagerDeps, J as RfqSwapManagerEvents, K as RfqSwapOrigin, N as RfqSwapOriginRequired, Q as RfqSwapOutcome, T as RfqSwapRecordStore, U as SwapContractRegistry, V as addAssetSwap, W as awaitRfqResolution, X as createRfqSwapRecord, Y as findLockupVtxos, Z as getAssetSwaps, _ as getAssetSwapsOrThrow, $ as isRfqSwapTerminal, a0 as isRfqTerminal, a1 as nextOnchainAction, a2 as preimageForSwapRecord, a3 as pushRefundWithoutReceiver, a4 as readLockupFate, a5 as rebuildRfqSwap, a6 as refundIfUnresolved, a7 as rfqSwapOriginOf, a8 as shouldRetainRfqSwap, a9 as swapSecretsToRecord, aa as updateAssetSwap, ab as updateAssetSwapBestEffort, ac as updateRfqSwapRecord } from './repository-
|
|
2
|
+
import { S as SwapSecretsProjection, R as RfqSwapRecord, A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry, b as RefundArkProvider, c as RefundIndexer, L as LockupVtxo, d as RfqSwap, e as ArkadeRefundResult, f as LockupSpendIndexer, g as RfqSwapState } from './repository-Cop29z0c.cjs';
|
|
3
|
+
export { h as AssetSwapStatus, i as AvailableRfqSwapManagerCallbacks, B as BTC_ASSET_ID, I as InMemoryAssetSwapRepository, j as LightningReceiveSwap, k as LightningSendSwap, l as LockupFate, m as LockupNeedsRecoveryError, n as LockupParams, o as LockupSpend, O as OnchainSendAction, p as OnchainSendSwap, P as PersistableRfqSwap, q as PreimageBlockedReason, r as PreimageNotRecoverableError, s as REFUND_MTP_LAG_SECONDS, t as RFQ_RESOLVED_STATES, u as RFQ_SWAP_RETENTION_SECONDS, v as RFQ_SWAP_TERMINAL_STATES, w as RefundOutcome, x as RfqRestoreFailure, y as RfqRestoreOptions, z as RfqRestoreResult, C as RfqSwapActionName, D as RfqSwapLockup, E as RfqSwapManager, F as RfqSwapManagerCallbacks, G as RfqSwapManagerConfig, H as RfqSwapManagerDeps, J as RfqSwapManagerEvents, K as RfqSwapOrigin, N as RfqSwapOriginRequired, Q as RfqSwapOutcome, T as RfqSwapRecordStore, U as SwapContractRegistry, V as addAssetSwap, W as awaitRfqResolution, X as createRfqSwapRecord, Y as findLockupVtxos, Z as getAssetSwaps, _ as getAssetSwapsOrThrow, $ as isRfqSwapTerminal, a0 as isRfqTerminal, a1 as nextOnchainAction, a2 as preimageForSwapRecord, a3 as pushRefundWithoutReceiver, a4 as readLockupFate, a5 as rebuildRfqSwap, a6 as refundIfUnresolved, a7 as rfqSwapOriginOf, a8 as shouldRetainRfqSwap, a9 as swapSecretsToRecord, aa as updateAssetSwap, ab as updateAssetSwapBestEffort, ac as updateRfqSwapRecord } from './repository-Cop29z0c.cjs';
|
|
4
4
|
import { Network, LocalCardInput, DiscoveredMarket, Side, OfferPlan } from '@arkade-os/solver-discovery';
|
|
5
|
-
import { O as OnchainNetwork, a as OnchainHtlc, b as OnchainHtlcParams, C as ChainSource, R as RfqTransport, r as requestOnchainSend, I as InvoiceFacts, c as requestLightningSend } from './rfq-
|
|
6
|
-
export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, f as ChainUtxo, H as HtlcUtxo, L as LIGHTNING_BTC, g as LIGHTNING_RECEIVE_PAIR, h as LIGHTNING_SEND_PAIR, i as LOCKTIME_THRESHOLD, j as LightningReceiveTreeParams, k as LightningSendTreeParams, M as MAX_MIN_CONFIRMATIONS, l as MIN_CLAIM_WINDOW_SECONDS, m as MIN_HEADROOM_SECONDS, n as ONCHAIN_BTC, o as ONCHAIN_CLAIM_MARGIN_SECONDS, p as ONCHAIN_DUST_SATS, q as ONCHAIN_ORDER_MARGIN_SECONDS, s as ONCHAIN_RECEIVE_PAIR, t as ONCHAIN_SECONDS_PER_BLOCK, u as ONCHAIN_SEND_PAIR, v as OnchainHtlcPhase, w as RFQ_REFUSAL_ERROR_CODES, x as RFQ_TERMINAL_STATES, y as RelaySocket, z as RfqQuote, B as RfqRefusalDetail, D as RfqRefusalErrorCode, E as RfqRefusalReason, F as RfqRefusalUnit, G as RfqStatus, S as SOLO_REFUND_HEADROOM_SECONDS, J as SwapRefusal, K as arkadeAssetLeg, N as arkadeSwapRequest, P as
|
|
5
|
+
import { O as OnchainNetwork, a as OnchainHtlc, b as OnchainHtlcParams, C as ChainSource, R as RfqTransport, r as requestOnchainSend, I as InvoiceFacts, c as requestLightningSend } from './rfq-B95nPfaa.cjs';
|
|
6
|
+
export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, f as ChainUtxo, H as HtlcUtxo, L as LIGHTNING_BTC, g as LIGHTNING_RECEIVE_PAIR, h as LIGHTNING_SEND_PAIR, i as LOCKTIME_THRESHOLD, j as LightningReceiveTreeParams, k as LightningSendTreeParams, M as MAX_MIN_CONFIRMATIONS, l as MIN_CLAIM_WINDOW_SECONDS, m as MIN_HEADROOM_SECONDS, n as ONCHAIN_BTC, o as ONCHAIN_CLAIM_MARGIN_SECONDS, p as ONCHAIN_DUST_SATS, q as ONCHAIN_ORDER_MARGIN_SECONDS, s as ONCHAIN_RECEIVE_PAIR, t as ONCHAIN_SECONDS_PER_BLOCK, u as ONCHAIN_SEND_PAIR, v as OnchainHtlcPhase, w as RFQ_REFUSAL_ERROR_CODES, x as RFQ_TERMINAL_STATES, y as RelaySocket, z as RfqQuote, B as RfqRefusalDetail, D as RfqRefusalErrorCode, E as RfqRefusalReason, F as RfqRefusalUnit, G as RfqStatus, S as SOLO_REFUND_HEADROOM_SECONDS, J as SwapRefusal, K as arkadeAssetLeg, N as arkadeSwapRequest, P as assertArkadeFundable, Q as assertFundable, T as assertReceivable, U as awaitOnchainFill, V as buildHtlcClaim, W as buildHtlcRefund, X as canonicalAssetAmount, Y as claimOnchainFill, Z as classifyOnchainHtlc, _ as deriveLightningReceive, $ as deriveOnchainReceive, a0 as deriveOnchainSend, a1 as extractPreimage, a2 as httpTransport, a3 as isRfqRefusalErrorCode, a4 as l1ScriptForAddress, a5 as lightningReceiveRequest, a6 as lightningSendRequest, a7 as lightningSendVtxoScript, a8 as newPreimage, a9 as newRfqId, aa as normalizeMakerPkScript, ab as normalizeMakerPublicKey, ac as offerTermsFromQuote, ad as onchainHtlcScript, ae as onchainReceiveRequest, af as onchainSendRequest, ag as paymentHashOf, ah as receiveVtxoScript, ai as relayTransport, aj as requestArkadeSwap, ak as requestLightningReceive, al as requestOnchainReceive, am as rfqPair, an as unilateralClaimDelay, ao as unilateralRefundDelay, ap as unilateralRefundWithoutReceiverDelay, aq as verifyLockupAddress, ar as verifyOfferAddress, as as verifyReceiveInvoice } from './rfq-B95nPfaa.cjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Which wallet key signs this leg. Stored at `profile.signer`.
|
|
@@ -141,6 +141,7 @@ interface OnchainSendProfile extends Record<string, unknown> {
|
|
|
141
141
|
htlcAddress: string;
|
|
142
142
|
/** `profile.min_confirmations`; gates when the fill is claimable. */
|
|
143
143
|
minConfirmations: number;
|
|
144
|
+
expectedAmount: number;
|
|
144
145
|
/** Where the claim PAYS, hex. The spender's own choice, so nothing else
|
|
145
146
|
* gives it back — and `buildHtlcClaim` needs it. */
|
|
146
147
|
payoutPkScript: string;
|
|
@@ -183,6 +184,7 @@ declare function onchainSendProfile(result: {
|
|
|
183
184
|
htlcParams: OnchainHtlcParams;
|
|
184
185
|
l1Network: OnchainNetwork;
|
|
185
186
|
minConfirmations: number;
|
|
187
|
+
expectedAmount: number;
|
|
186
188
|
payoutPkScript: Uint8Array;
|
|
187
189
|
}): Omit<OnchainSendProfile, "signer" | "hashlock">;
|
|
188
190
|
|
|
@@ -503,7 +505,11 @@ declare const QUOTE_OPTIONS: {
|
|
|
503
505
|
declare const makeCachedFeedFetch: (ttlMs?: number, fetchImpl?: typeof fetch) => typeof fetch;
|
|
504
506
|
interface DiscoverMarketsOptions {
|
|
505
507
|
network: Network;
|
|
506
|
-
/**
|
|
508
|
+
/** Overrides the registry this network publishes by default. Omit (or pass
|
|
509
|
+
* `undefined`) to follow `@arkade-os/solver-discovery`'s per-network
|
|
510
|
+
* default index, which the library can move in a release without a client
|
|
511
|
+
* change; this package never hardcodes the URL. The markets cache is keyed
|
|
512
|
+
* by the URL actually followed, default included. */
|
|
507
513
|
registryUrl: string | undefined;
|
|
508
514
|
/** Backs the 1-hour markets cache and its stale fallback. Omit for a
|
|
509
515
|
* one-shot discovery that always hits the registry. */
|
|
@@ -523,9 +529,11 @@ interface DiscoverMarketsOptions {
|
|
|
523
529
|
useCache?: boolean;
|
|
524
530
|
}
|
|
525
531
|
/**
|
|
526
|
-
* Markets from
|
|
527
|
-
*
|
|
528
|
-
*
|
|
532
|
+
* Markets from this network's solver registry — the caller's `registryUrl` when
|
|
533
|
+
* given, else the network's published default. Only an unrecognised network
|
|
534
|
+
* yields []. Registry content changes rarely, so results are cached for an hour
|
|
535
|
+
* and a stale cache backstops an unreachable registry (quotes stay live either
|
|
536
|
+
* way).
|
|
529
537
|
*/
|
|
530
538
|
declare const discoverMarkets: (options: DiscoverMarketsOptions) => Promise<DiscoveredMarket[]>;
|
|
531
539
|
/** Best market for a from/to pair, in either orientation. `give` is the side
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ProvisionedKey, ProvisionedClaimSecret, ArkTxInput, asset, RelativeTimelock, IWallet, EmulatorProvider, arkade, RestIndexerProvider, Transaction, IContractManager, OnchainProvider, PaymentRail, Asset, VHTLC, Identity, ActivityResolver } from '@arkade-os/sdk';
|
|
2
|
-
import { S as SwapSecretsProjection, R as RfqSwapRecord, A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry, b as RefundArkProvider, c as RefundIndexer, L as LockupVtxo, d as RfqSwap, e as ArkadeRefundResult, f as LockupSpendIndexer, g as RfqSwapState } from './repository-
|
|
3
|
-
export { h as AssetSwapStatus, i as AvailableRfqSwapManagerCallbacks, B as BTC_ASSET_ID, I as InMemoryAssetSwapRepository, j as LightningReceiveSwap, k as LightningSendSwap, l as LockupFate, m as LockupNeedsRecoveryError, n as LockupParams, o as LockupSpend, O as OnchainSendAction, p as OnchainSendSwap, P as PersistableRfqSwap, q as PreimageBlockedReason, r as PreimageNotRecoverableError, s as REFUND_MTP_LAG_SECONDS, t as RFQ_RESOLVED_STATES, u as RFQ_SWAP_RETENTION_SECONDS, v as RFQ_SWAP_TERMINAL_STATES, w as RefundOutcome, x as RfqRestoreFailure, y as RfqRestoreOptions, z as RfqRestoreResult, C as RfqSwapActionName, D as RfqSwapLockup, E as RfqSwapManager, F as RfqSwapManagerCallbacks, G as RfqSwapManagerConfig, H as RfqSwapManagerDeps, J as RfqSwapManagerEvents, K as RfqSwapOrigin, N as RfqSwapOriginRequired, Q as RfqSwapOutcome, T as RfqSwapRecordStore, U as SwapContractRegistry, V as addAssetSwap, W as awaitRfqResolution, X as createRfqSwapRecord, Y as findLockupVtxos, Z as getAssetSwaps, _ as getAssetSwapsOrThrow, $ as isRfqSwapTerminal, a0 as isRfqTerminal, a1 as nextOnchainAction, a2 as preimageForSwapRecord, a3 as pushRefundWithoutReceiver, a4 as readLockupFate, a5 as rebuildRfqSwap, a6 as refundIfUnresolved, a7 as rfqSwapOriginOf, a8 as shouldRetainRfqSwap, a9 as swapSecretsToRecord, aa as updateAssetSwap, ab as updateAssetSwapBestEffort, ac as updateRfqSwapRecord } from './repository-
|
|
2
|
+
import { S as SwapSecretsProjection, R as RfqSwapRecord, A as AssetSwapRepository, a as AssetSwap, M as MarketsCacheEntry, b as RefundArkProvider, c as RefundIndexer, L as LockupVtxo, d as RfqSwap, e as ArkadeRefundResult, f as LockupSpendIndexer, g as RfqSwapState } from './repository-BrTpVPLy.js';
|
|
3
|
+
export { h as AssetSwapStatus, i as AvailableRfqSwapManagerCallbacks, B as BTC_ASSET_ID, I as InMemoryAssetSwapRepository, j as LightningReceiveSwap, k as LightningSendSwap, l as LockupFate, m as LockupNeedsRecoveryError, n as LockupParams, o as LockupSpend, O as OnchainSendAction, p as OnchainSendSwap, P as PersistableRfqSwap, q as PreimageBlockedReason, r as PreimageNotRecoverableError, s as REFUND_MTP_LAG_SECONDS, t as RFQ_RESOLVED_STATES, u as RFQ_SWAP_RETENTION_SECONDS, v as RFQ_SWAP_TERMINAL_STATES, w as RefundOutcome, x as RfqRestoreFailure, y as RfqRestoreOptions, z as RfqRestoreResult, C as RfqSwapActionName, D as RfqSwapLockup, E as RfqSwapManager, F as RfqSwapManagerCallbacks, G as RfqSwapManagerConfig, H as RfqSwapManagerDeps, J as RfqSwapManagerEvents, K as RfqSwapOrigin, N as RfqSwapOriginRequired, Q as RfqSwapOutcome, T as RfqSwapRecordStore, U as SwapContractRegistry, V as addAssetSwap, W as awaitRfqResolution, X as createRfqSwapRecord, Y as findLockupVtxos, Z as getAssetSwaps, _ as getAssetSwapsOrThrow, $ as isRfqSwapTerminal, a0 as isRfqTerminal, a1 as nextOnchainAction, a2 as preimageForSwapRecord, a3 as pushRefundWithoutReceiver, a4 as readLockupFate, a5 as rebuildRfqSwap, a6 as refundIfUnresolved, a7 as rfqSwapOriginOf, a8 as shouldRetainRfqSwap, a9 as swapSecretsToRecord, aa as updateAssetSwap, ab as updateAssetSwapBestEffort, ac as updateRfqSwapRecord } from './repository-BrTpVPLy.js';
|
|
4
4
|
import { Network, LocalCardInput, DiscoveredMarket, Side, OfferPlan } from '@arkade-os/solver-discovery';
|
|
5
|
-
import { O as OnchainNetwork, a as OnchainHtlc, b as OnchainHtlcParams, C as ChainSource, R as RfqTransport, r as requestOnchainSend, I as InvoiceFacts, c as requestLightningSend } from './rfq-
|
|
6
|
-
export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, f as ChainUtxo, H as HtlcUtxo, L as LIGHTNING_BTC, g as LIGHTNING_RECEIVE_PAIR, h as LIGHTNING_SEND_PAIR, i as LOCKTIME_THRESHOLD, j as LightningReceiveTreeParams, k as LightningSendTreeParams, M as MAX_MIN_CONFIRMATIONS, l as MIN_CLAIM_WINDOW_SECONDS, m as MIN_HEADROOM_SECONDS, n as ONCHAIN_BTC, o as ONCHAIN_CLAIM_MARGIN_SECONDS, p as ONCHAIN_DUST_SATS, q as ONCHAIN_ORDER_MARGIN_SECONDS, s as ONCHAIN_RECEIVE_PAIR, t as ONCHAIN_SECONDS_PER_BLOCK, u as ONCHAIN_SEND_PAIR, v as OnchainHtlcPhase, w as RFQ_REFUSAL_ERROR_CODES, x as RFQ_TERMINAL_STATES, y as RelaySocket, z as RfqQuote, B as RfqRefusalDetail, D as RfqRefusalErrorCode, E as RfqRefusalReason, F as RfqRefusalUnit, G as RfqStatus, S as SOLO_REFUND_HEADROOM_SECONDS, J as SwapRefusal, K as arkadeAssetLeg, N as arkadeSwapRequest, P as
|
|
5
|
+
import { O as OnchainNetwork, a as OnchainHtlc, b as OnchainHtlcParams, C as ChainSource, R as RfqTransport, r as requestOnchainSend, I as InvoiceFacts, c as requestLightningSend } from './rfq-B95nPfaa.js';
|
|
6
|
+
export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, f as ChainUtxo, H as HtlcUtxo, L as LIGHTNING_BTC, g as LIGHTNING_RECEIVE_PAIR, h as LIGHTNING_SEND_PAIR, i as LOCKTIME_THRESHOLD, j as LightningReceiveTreeParams, k as LightningSendTreeParams, M as MAX_MIN_CONFIRMATIONS, l as MIN_CLAIM_WINDOW_SECONDS, m as MIN_HEADROOM_SECONDS, n as ONCHAIN_BTC, o as ONCHAIN_CLAIM_MARGIN_SECONDS, p as ONCHAIN_DUST_SATS, q as ONCHAIN_ORDER_MARGIN_SECONDS, s as ONCHAIN_RECEIVE_PAIR, t as ONCHAIN_SECONDS_PER_BLOCK, u as ONCHAIN_SEND_PAIR, v as OnchainHtlcPhase, w as RFQ_REFUSAL_ERROR_CODES, x as RFQ_TERMINAL_STATES, y as RelaySocket, z as RfqQuote, B as RfqRefusalDetail, D as RfqRefusalErrorCode, E as RfqRefusalReason, F as RfqRefusalUnit, G as RfqStatus, S as SOLO_REFUND_HEADROOM_SECONDS, J as SwapRefusal, K as arkadeAssetLeg, N as arkadeSwapRequest, P as assertArkadeFundable, Q as assertFundable, T as assertReceivable, U as awaitOnchainFill, V as buildHtlcClaim, W as buildHtlcRefund, X as canonicalAssetAmount, Y as claimOnchainFill, Z as classifyOnchainHtlc, _ as deriveLightningReceive, $ as deriveOnchainReceive, a0 as deriveOnchainSend, a1 as extractPreimage, a2 as httpTransport, a3 as isRfqRefusalErrorCode, a4 as l1ScriptForAddress, a5 as lightningReceiveRequest, a6 as lightningSendRequest, a7 as lightningSendVtxoScript, a8 as newPreimage, a9 as newRfqId, aa as normalizeMakerPkScript, ab as normalizeMakerPublicKey, ac as offerTermsFromQuote, ad as onchainHtlcScript, ae as onchainReceiveRequest, af as onchainSendRequest, ag as paymentHashOf, ah as receiveVtxoScript, ai as relayTransport, aj as requestArkadeSwap, ak as requestLightningReceive, al as requestOnchainReceive, am as rfqPair, an as unilateralClaimDelay, ao as unilateralRefundDelay, ap as unilateralRefundWithoutReceiverDelay, aq as verifyLockupAddress, ar as verifyOfferAddress, as as verifyReceiveInvoice } from './rfq-B95nPfaa.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Which wallet key signs this leg. Stored at `profile.signer`.
|
|
@@ -141,6 +141,7 @@ interface OnchainSendProfile extends Record<string, unknown> {
|
|
|
141
141
|
htlcAddress: string;
|
|
142
142
|
/** `profile.min_confirmations`; gates when the fill is claimable. */
|
|
143
143
|
minConfirmations: number;
|
|
144
|
+
expectedAmount: number;
|
|
144
145
|
/** Where the claim PAYS, hex. The spender's own choice, so nothing else
|
|
145
146
|
* gives it back — and `buildHtlcClaim` needs it. */
|
|
146
147
|
payoutPkScript: string;
|
|
@@ -183,6 +184,7 @@ declare function onchainSendProfile(result: {
|
|
|
183
184
|
htlcParams: OnchainHtlcParams;
|
|
184
185
|
l1Network: OnchainNetwork;
|
|
185
186
|
minConfirmations: number;
|
|
187
|
+
expectedAmount: number;
|
|
186
188
|
payoutPkScript: Uint8Array;
|
|
187
189
|
}): Omit<OnchainSendProfile, "signer" | "hashlock">;
|
|
188
190
|
|
|
@@ -503,7 +505,11 @@ declare const QUOTE_OPTIONS: {
|
|
|
503
505
|
declare const makeCachedFeedFetch: (ttlMs?: number, fetchImpl?: typeof fetch) => typeof fetch;
|
|
504
506
|
interface DiscoverMarketsOptions {
|
|
505
507
|
network: Network;
|
|
506
|
-
/**
|
|
508
|
+
/** Overrides the registry this network publishes by default. Omit (or pass
|
|
509
|
+
* `undefined`) to follow `@arkade-os/solver-discovery`'s per-network
|
|
510
|
+
* default index, which the library can move in a release without a client
|
|
511
|
+
* change; this package never hardcodes the URL. The markets cache is keyed
|
|
512
|
+
* by the URL actually followed, default included. */
|
|
507
513
|
registryUrl: string | undefined;
|
|
508
514
|
/** Backs the 1-hour markets cache and its stale fallback. Omit for a
|
|
509
515
|
* one-shot discovery that always hits the registry. */
|
|
@@ -523,9 +529,11 @@ interface DiscoverMarketsOptions {
|
|
|
523
529
|
useCache?: boolean;
|
|
524
530
|
}
|
|
525
531
|
/**
|
|
526
|
-
* Markets from
|
|
527
|
-
*
|
|
528
|
-
*
|
|
532
|
+
* Markets from this network's solver registry — the caller's `registryUrl` when
|
|
533
|
+
* given, else the network's published default. Only an unrecognised network
|
|
534
|
+
* yields []. Registry content changes rarely, so results are cached for an hour
|
|
535
|
+
* and a stale cache backstops an unreachable registry (quotes stay live either
|
|
536
|
+
* way).
|
|
529
537
|
*/
|
|
530
538
|
declare const discoverMarkets: (options: DiscoverMarketsOptions) => Promise<DiscoveredMarket[]>;
|
|
531
539
|
/** Best market for a from/to pair, in either orientation. `give` is the side
|