@arkade-os/swap 0.0.12 → 0.0.14
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/dist/{chunk-XXWOODUE.js → chunk-IFZOBTTG.js} +8 -8
- package/dist/index.cjs +311 -49
- package/dist/index.d.cts +131 -6
- package/dist/index.d.ts +131 -6
- package/dist/index.js +303 -31
- 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-DlLvj_y6.d.ts → repository-D5JoeqwB.d.ts} +1 -1
- package/dist/{repository-DaK1RzRq.d.cts → repository-Vfx65uF1.d.cts} +1 -1
- package/dist/{rfq-DzsmhXX3.d.ts → rfq-CYfKvAPp.d.cts} +14 -8
- package/dist/{rfq-DzsmhXX3.d.cts → rfq-CYfKvAPp.d.ts} +14 -8
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
unilateralRefundWithoutReceiverDelay,
|
|
66
66
|
verifyLockupAddress,
|
|
67
67
|
verifyReceiveInvoice
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-IFZOBTTG.js";
|
|
69
69
|
import {
|
|
70
70
|
InMemoryAssetSwapRepository,
|
|
71
71
|
marketsCacheKey
|
|
@@ -1417,6 +1417,7 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
|
|
|
1417
1417
|
import { base64 as base642, hex as hex6 } from "@scure/base";
|
|
1418
1418
|
import {
|
|
1419
1419
|
ArkAddress as ArkAddress3,
|
|
1420
|
+
isContractVtxoEvent,
|
|
1420
1421
|
RestIndexerProvider as RestIndexerProvider3,
|
|
1421
1422
|
Transaction as Transaction2
|
|
1422
1423
|
} from "@arkade-os/sdk";
|
|
@@ -1487,7 +1488,7 @@ async function watchOfferSwaps({
|
|
|
1487
1488
|
}
|
|
1488
1489
|
};
|
|
1489
1490
|
const unsubscribe = manager.onContractEvent((event) => {
|
|
1490
|
-
if (event.type !== "vtxo_spent") return;
|
|
1491
|
+
if (!isContractVtxoEvent(event) || event.type !== "vtxo_spent") return;
|
|
1491
1492
|
enqueue(() => handleSpend(event));
|
|
1492
1493
|
});
|
|
1493
1494
|
return {
|
|
@@ -1580,7 +1581,14 @@ var solverRendezvous = (markets, payoutCorridor, amountSats, fallbackEmulatorPub
|
|
|
1580
1581
|
};
|
|
1581
1582
|
|
|
1582
1583
|
// src/payment/solverOnchain.ts
|
|
1583
|
-
import {
|
|
1584
|
+
import {
|
|
1585
|
+
assertNoAssets,
|
|
1586
|
+
assetsOf,
|
|
1587
|
+
btcTarget,
|
|
1588
|
+
makeHandle,
|
|
1589
|
+
resolveSendAmount,
|
|
1590
|
+
tryResolveSendAmount
|
|
1591
|
+
} from "@arkade-os/sdk";
|
|
1584
1592
|
var SOLVER_ONCHAIN_RAIL = "solver-onchain";
|
|
1585
1593
|
var solverOnchainRendezvous = (markets, amountSats, fallbackEmulatorPubkey) => solverRendezvous(markets, "onchain", amountSats, fallbackEmulatorPubkey);
|
|
1586
1594
|
function solverOnchainRail(deps) {
|
|
@@ -1593,6 +1601,7 @@ function solverOnchainRail(deps) {
|
|
|
1593
1601
|
id: SOLVER_ONCHAIN_RAIL,
|
|
1594
1602
|
match: (req) => btcTarget(req.raw) !== void 0,
|
|
1595
1603
|
available: async (req) => {
|
|
1604
|
+
if (assetsOf(req).length > 0) return false;
|
|
1596
1605
|
const address = btcTarget(req.raw);
|
|
1597
1606
|
if (!address) return false;
|
|
1598
1607
|
try {
|
|
@@ -1606,6 +1615,7 @@ function solverOnchainRail(deps) {
|
|
|
1606
1615
|
},
|
|
1607
1616
|
quote: async (req, ctx) => {
|
|
1608
1617
|
const address = btcTarget(req.raw);
|
|
1618
|
+
assertNoAssets(SOLVER_ONCHAIN_RAIL, req);
|
|
1609
1619
|
const amount = resolveSendAmount(SOLVER_ONCHAIN_RAIL, req.raw, req.amount);
|
|
1610
1620
|
const payoutPkScript = l1ScriptForAddress(address, deps.l1Network);
|
|
1611
1621
|
const rendezvous = await rendezvousFor(amount);
|
|
@@ -1682,7 +1692,7 @@ function solverOnchainRail(deps) {
|
|
|
1682
1692
|
}
|
|
1683
1693
|
|
|
1684
1694
|
// src/payment/solverLightning.ts
|
|
1685
|
-
import { invoiceTarget, makeHandle as makeHandle2 } from "@arkade-os/sdk";
|
|
1695
|
+
import { assertNoAssets as assertNoAssets2, assetsOf as assetsOf2, invoiceTarget, makeHandle as makeHandle2 } from "@arkade-os/sdk";
|
|
1686
1696
|
var SOLVER_LIGHTNING_RAIL = "solver-lightning";
|
|
1687
1697
|
var factsOf = (raw, decode, now) => {
|
|
1688
1698
|
const invoice = invoiceTarget(raw);
|
|
@@ -1704,12 +1714,14 @@ function solverLightningRail(deps) {
|
|
|
1704
1714
|
id: SOLVER_LIGHTNING_RAIL,
|
|
1705
1715
|
match: (req) => invoiceTarget(req.raw) !== void 0,
|
|
1706
1716
|
available: async (req) => {
|
|
1717
|
+
if (assetsOf2(req).length > 0) return false;
|
|
1707
1718
|
const facts = factsOf(req.raw, deps.decodeInvoice, Math.floor(Date.now() / 1e3));
|
|
1708
1719
|
if (!facts) return false;
|
|
1709
1720
|
if (req.amount !== void 0 && req.amount !== facts.amountSats) return false;
|
|
1710
1721
|
return await rendezvousFor(facts.amountSats) !== void 0;
|
|
1711
1722
|
},
|
|
1712
1723
|
quote: async (req, ctx) => {
|
|
1724
|
+
assertNoAssets2(SOLVER_LIGHTNING_RAIL, req);
|
|
1713
1725
|
const facts = factsOf(req.raw, deps.decodeInvoice, Math.floor(Date.now() / 1e3));
|
|
1714
1726
|
if (!facts) {
|
|
1715
1727
|
throw new Error(
|
|
@@ -1782,10 +1794,260 @@ function solverLightningRail(deps) {
|
|
|
1782
1794
|
};
|
|
1783
1795
|
}
|
|
1784
1796
|
|
|
1785
|
-
// src/
|
|
1786
|
-
import {
|
|
1797
|
+
// src/payment/crossAsset.ts
|
|
1798
|
+
import {
|
|
1799
|
+
arkTarget,
|
|
1800
|
+
asset as assetExt,
|
|
1801
|
+
assetsOf as assetsOf3,
|
|
1802
|
+
makeHandle as makeHandle3,
|
|
1803
|
+
resolveAssetAmount
|
|
1804
|
+
} from "@arkade-os/sdk";
|
|
1805
|
+
var CROSS_ASSET_RAIL = "cross-asset";
|
|
1806
|
+
var DEFAULT_CARRIER_SATS = 330;
|
|
1807
|
+
var parseAssetId = (assetId) => {
|
|
1808
|
+
try {
|
|
1809
|
+
return assetExt.AssetId.fromString(assetId);
|
|
1810
|
+
} catch {
|
|
1811
|
+
return void 0;
|
|
1812
|
+
}
|
|
1813
|
+
};
|
|
1814
|
+
function crossAssetRail(deps) {
|
|
1815
|
+
const planFor = async (asset2) => {
|
|
1816
|
+
const markets = await deps.discover();
|
|
1817
|
+
const found = findMarket(markets, BTC_ASSET_ID, asset2.assetId);
|
|
1818
|
+
const market = found?.market;
|
|
1819
|
+
if (!market) return void 0;
|
|
1820
|
+
const plan = await deps.quote(market, found.give, asset2.amount);
|
|
1821
|
+
const [balance, dust] = await Promise.all([deps.btcBalance(), deps.dust()]);
|
|
1822
|
+
return { plan, error: validatePlan(plan, balance, dust) };
|
|
1823
|
+
};
|
|
1824
|
+
return {
|
|
1825
|
+
id: CROSS_ASSET_RAIL,
|
|
1826
|
+
match: (req) => arkTarget(req.raw) !== void 0,
|
|
1827
|
+
available: async (req) => {
|
|
1828
|
+
const assets = assetsOf3(req);
|
|
1829
|
+
if (assets.length !== 1) return false;
|
|
1830
|
+
const [asset2] = assets;
|
|
1831
|
+
if (asset2.assetId === BTC_ASSET_ID) return false;
|
|
1832
|
+
if (typeof asset2.amount !== "bigint" || asset2.amount <= 0n) return false;
|
|
1833
|
+
if (!parseAssetId(asset2.assetId)) return false;
|
|
1834
|
+
const planned = await planFor(asset2);
|
|
1835
|
+
return planned !== void 0 && planned.error === void 0;
|
|
1836
|
+
},
|
|
1837
|
+
quote: async (req, ctx) => {
|
|
1838
|
+
const payTo = arkTarget(req.raw);
|
|
1839
|
+
const asset2 = resolveAssetAmount(CROSS_ASSET_RAIL, req);
|
|
1840
|
+
const wantAsset = parseAssetId(asset2.assetId);
|
|
1841
|
+
if (!wantAsset) {
|
|
1842
|
+
throw new Error(
|
|
1843
|
+
`${CROSS_ASSET_RAIL}: ${asset2.assetId} is not an asset id (expected 34 bytes of hex)`
|
|
1844
|
+
);
|
|
1845
|
+
}
|
|
1846
|
+
const planned = await planFor(asset2);
|
|
1847
|
+
if (!planned) {
|
|
1848
|
+
throw new Error(`${CROSS_ASSET_RAIL}: no market swaps BTC into ${asset2.assetId}`);
|
|
1849
|
+
}
|
|
1850
|
+
if (planned.error) {
|
|
1851
|
+
throw new Error(
|
|
1852
|
+
`${CROSS_ASSET_RAIL}: cannot swap into ${asset2.assetId} \u2014 ${planned.error}`
|
|
1853
|
+
);
|
|
1854
|
+
}
|
|
1855
|
+
const { plan } = planned;
|
|
1856
|
+
if (!Number.isSafeInteger(Number(plan.deposit.atomic))) {
|
|
1857
|
+
throw new Error(
|
|
1858
|
+
`${CROSS_ASSET_RAIL}: deposit of ${plan.deposit.atomic} does not fit a JS number`
|
|
1859
|
+
);
|
|
1860
|
+
}
|
|
1861
|
+
const depositSats = Number(plan.deposit.atomic);
|
|
1862
|
+
const carrier = deps.carrierSats ?? DEFAULT_CARRIER_SATS;
|
|
1863
|
+
return {
|
|
1864
|
+
railId: CROSS_ASSET_RAIL,
|
|
1865
|
+
// OPEN QUESTION for review: `total = amount + fee` forces the
|
|
1866
|
+
// purchase price into `fee`, which reads as a service charge.
|
|
1867
|
+
// A third field instead? `assets.spent` labels it correctly.
|
|
1868
|
+
amount: carrier,
|
|
1869
|
+
fee: depositSats,
|
|
1870
|
+
total: depositSats + carrier,
|
|
1871
|
+
assets: {
|
|
1872
|
+
delivered: asset2,
|
|
1873
|
+
spent: { assetId: BTC_ASSET_ID, amount: plan.deposit.atomic }
|
|
1874
|
+
},
|
|
1875
|
+
meta: {
|
|
1876
|
+
market: plan.market.pair,
|
|
1877
|
+
priceDisplay: plan.priceDisplay,
|
|
1878
|
+
give: plan.give
|
|
1879
|
+
},
|
|
1880
|
+
send: async () => makeHandle3(CROSS_ASSET_RAIL, async (emit) => {
|
|
1881
|
+
const offer = await createOffer(ctx.wallet, deps.arkServerUrl, {
|
|
1882
|
+
wantAmount: asset2.amount,
|
|
1883
|
+
wantAsset,
|
|
1884
|
+
...deps.emulatorPubkey ? { emulatorPubkey: deps.emulatorPubkey } : {}
|
|
1885
|
+
});
|
|
1886
|
+
const swap = {
|
|
1887
|
+
phase: "quoted",
|
|
1888
|
+
offerHex: offer.offerHex,
|
|
1889
|
+
address: offer.address,
|
|
1890
|
+
swapPkScript: offer.swapPkScript,
|
|
1891
|
+
depositSats,
|
|
1892
|
+
asset: asset2,
|
|
1893
|
+
payTo,
|
|
1894
|
+
plan
|
|
1895
|
+
};
|
|
1896
|
+
await deps.persist(swap);
|
|
1897
|
+
await ctx.wallet.send({
|
|
1898
|
+
address: offer.address,
|
|
1899
|
+
amount: depositSats,
|
|
1900
|
+
extensions: [offer.extension]
|
|
1901
|
+
});
|
|
1902
|
+
emit({ status: "sent" });
|
|
1903
|
+
await deps.awaitFill(swap);
|
|
1904
|
+
await deps.persist({ ...swap, phase: "filled" });
|
|
1905
|
+
await deps.persist({ ...swap, phase: "paying" });
|
|
1906
|
+
const txid = await ctx.wallet.send({
|
|
1907
|
+
address: payTo,
|
|
1908
|
+
amount: carrier,
|
|
1909
|
+
assets: [asset2]
|
|
1910
|
+
});
|
|
1911
|
+
await deps.persist({ ...swap, phase: "settled", txid });
|
|
1912
|
+
const result = {
|
|
1913
|
+
railId: CROSS_ASSET_RAIL,
|
|
1914
|
+
txid,
|
|
1915
|
+
swapId: offer.offerHex
|
|
1916
|
+
};
|
|
1917
|
+
emit({ status: "settled", result });
|
|
1918
|
+
return result;
|
|
1919
|
+
})
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
};
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
// src/reveal.ts
|
|
1926
|
+
import { base64 as base643, hex as hex9 } from "@scure/base";
|
|
1787
1927
|
import { ripemd160 } from "@noble/hashes/legacy.js";
|
|
1788
|
-
import { sha256 as
|
|
1928
|
+
import { sha256 as sha2562 } from "@noble/hashes/sha2.js";
|
|
1929
|
+
import { ArkAddress as ArkAddress4 } from "@arkade-os/sdk";
|
|
1930
|
+
var CovclaimdRevealError = class extends Error {
|
|
1931
|
+
name = "CovclaimdRevealError";
|
|
1932
|
+
status;
|
|
1933
|
+
detail;
|
|
1934
|
+
retryable;
|
|
1935
|
+
constructor(what, status, detail) {
|
|
1936
|
+
super(`covclaimd ${what} failed: ${status || "no response"} ${detail}`.trimEnd());
|
|
1937
|
+
this.status = status;
|
|
1938
|
+
this.detail = detail;
|
|
1939
|
+
this.retryable = status === 0 || status === 429 || status >= 500;
|
|
1940
|
+
}
|
|
1941
|
+
};
|
|
1942
|
+
var decodeKey = (value, field) => {
|
|
1943
|
+
if (typeof value !== "string") throw new Error(`covclaimd info: ${field} is not a string`);
|
|
1944
|
+
let bytes;
|
|
1945
|
+
try {
|
|
1946
|
+
bytes = hex9.decode(value);
|
|
1947
|
+
} catch {
|
|
1948
|
+
throw new Error(`covclaimd info: ${field} is not hex`);
|
|
1949
|
+
}
|
|
1950
|
+
if (bytes.length !== 33) {
|
|
1951
|
+
throw new Error(`covclaimd info: ${field} must be 33-byte compressed, got ${bytes.length}`);
|
|
1952
|
+
}
|
|
1953
|
+
return bytes;
|
|
1954
|
+
};
|
|
1955
|
+
var LOOPBACK = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]"]);
|
|
1956
|
+
var assertTransportSecure = (baseUrl, allowInsecureHttp) => {
|
|
1957
|
+
const { protocol, hostname } = new URL(baseUrl);
|
|
1958
|
+
if (protocol === "https:" || allowInsecureHttp) return;
|
|
1959
|
+
if (protocol === "http:" && LOOPBACK.has(hostname)) return;
|
|
1960
|
+
throw new Error(
|
|
1961
|
+
`covclaimd URL must be https (got ${protocol}//${hostname}): the key it serves is the one the preimage gets sealed to. Pass allowInsecureHttp to override.`
|
|
1962
|
+
);
|
|
1963
|
+
};
|
|
1964
|
+
var covclaimdClient = (baseUrl, options = {}) => {
|
|
1965
|
+
assertTransportSecure(baseUrl, options.allowInsecureHttp === true);
|
|
1966
|
+
const url = baseUrl.replace(/\/+$/, "");
|
|
1967
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
1968
|
+
const timeoutMs = options.timeoutMs ?? 3e4;
|
|
1969
|
+
const send = async (what, path, init) => {
|
|
1970
|
+
let response;
|
|
1971
|
+
try {
|
|
1972
|
+
response = await fetchImpl(`${url}${path}`, {
|
|
1973
|
+
...init,
|
|
1974
|
+
// a redirect would move the key fetch off the vetted origin
|
|
1975
|
+
redirect: "error",
|
|
1976
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
1977
|
+
});
|
|
1978
|
+
} catch (error) {
|
|
1979
|
+
throw new CovclaimdRevealError(what, 0, String(error));
|
|
1980
|
+
}
|
|
1981
|
+
if (!response.ok) {
|
|
1982
|
+
throw new CovclaimdRevealError(what, response.status, await response.text());
|
|
1983
|
+
}
|
|
1984
|
+
return response;
|
|
1985
|
+
};
|
|
1986
|
+
const readJson = async (what, response) => {
|
|
1987
|
+
const body = await response.text();
|
|
1988
|
+
try {
|
|
1989
|
+
return JSON.parse(body);
|
|
1990
|
+
} catch {
|
|
1991
|
+
throw new CovclaimdRevealError(
|
|
1992
|
+
what,
|
|
1993
|
+
response.status,
|
|
1994
|
+
`non-JSON body: ${body.slice(0, 200)}`
|
|
1995
|
+
);
|
|
1996
|
+
}
|
|
1997
|
+
};
|
|
1998
|
+
return {
|
|
1999
|
+
async info() {
|
|
2000
|
+
const response = await send("info", "/v1/preimage/covclaimd-pubkey", {
|
|
2001
|
+
method: "GET"
|
|
2002
|
+
});
|
|
2003
|
+
const body = await readJson("info", response);
|
|
2004
|
+
return {
|
|
2005
|
+
covclaimdPubkey: decodeKey(body?.covclaimd_pub_key, "covclaimd_pub_key"),
|
|
2006
|
+
emulatorPubkey: hex9.encode(decodeKey(body?.emulator_pub_key, "emulator_pub_key"))
|
|
2007
|
+
};
|
|
2008
|
+
},
|
|
2009
|
+
async reveal(params) {
|
|
2010
|
+
await send("reveal", "/v1/reveal", {
|
|
2011
|
+
method: "POST",
|
|
2012
|
+
headers: { "content-type": "application/json" },
|
|
2013
|
+
body: JSON.stringify({
|
|
2014
|
+
swap_address: params.swapAddress,
|
|
2015
|
+
packet: { ciphertext: params.ciphertext, arkade_script: params.arkadeScript },
|
|
2016
|
+
taptree: params.taptree
|
|
2017
|
+
})
|
|
2018
|
+
});
|
|
2019
|
+
}
|
|
2020
|
+
};
|
|
2021
|
+
};
|
|
2022
|
+
function revealFieldsFromScript(script) {
|
|
2023
|
+
if (!script.nonInteractiveClaimArkadeScript) {
|
|
2024
|
+
throw new Error("this covenant has no non-interactive claim leaf to reveal against");
|
|
2025
|
+
}
|
|
2026
|
+
return {
|
|
2027
|
+
arkadeScript: base643.encode(script.nonInteractiveClaimArkadeScript),
|
|
2028
|
+
taptree: hex9.encode(script.encode())
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
async function revealClaimPacket(client, input) {
|
|
2032
|
+
const fields = revealFieldsFromScript(input.script);
|
|
2033
|
+
if (hex9.encode(ArkAddress4.decode(input.address).pkScript) !== hex9.encode(input.script.pkScript)) {
|
|
2034
|
+
throw new Error("address does not belong to this covenant");
|
|
2035
|
+
}
|
|
2036
|
+
if (hex9.encode(ripemd160(sha2562(input.preimage))) !== hex9.encode(input.script.options.preimageHash)) {
|
|
2037
|
+
throw new Error("preimage does not match the covenant's payment hash");
|
|
2038
|
+
}
|
|
2039
|
+
const { ciphertext } = await sealClaimPacket({
|
|
2040
|
+
preimage: input.preimage,
|
|
2041
|
+
covclaimdPubkey: (await client.info()).covclaimdPubkey
|
|
2042
|
+
});
|
|
2043
|
+
await client.reveal({ swapAddress: input.address, ciphertext, ...fields });
|
|
2044
|
+
return { ciphertext };
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
// src/claim.ts
|
|
2048
|
+
import { hex as hex11 } from "@scure/base";
|
|
2049
|
+
import { ripemd160 as ripemd1602 } from "@noble/hashes/legacy.js";
|
|
2050
|
+
import { sha256 as sha2564 } from "@noble/hashes/sha2.js";
|
|
1789
2051
|
import {
|
|
1790
2052
|
CSVMultisigTapscript as CSVMultisigTapscript2,
|
|
1791
2053
|
claimWithPreimageIdentity,
|
|
@@ -1793,8 +2055,8 @@ import {
|
|
|
1793
2055
|
} from "@arkade-os/sdk";
|
|
1794
2056
|
|
|
1795
2057
|
// src/refund.ts
|
|
1796
|
-
import { base64 as
|
|
1797
|
-
import { sha256 as
|
|
2058
|
+
import { base64 as base644, hex as hex10 } from "@scure/base";
|
|
2059
|
+
import { sha256 as sha2563 } from "@noble/hashes/sha2.js";
|
|
1798
2060
|
import {
|
|
1799
2061
|
CSVMultisigTapscript,
|
|
1800
2062
|
ConditionWitness,
|
|
@@ -1851,7 +2113,7 @@ var LockupNeedsRecoveryError = class extends Error {
|
|
|
1851
2113
|
}
|
|
1852
2114
|
};
|
|
1853
2115
|
async function findLockupVtxos(indexer, swapPkScript) {
|
|
1854
|
-
const scripts = [
|
|
2116
|
+
const scripts = [hex10.encode(swapPkScript)];
|
|
1855
2117
|
const [spendable, recoverable] = await Promise.all([
|
|
1856
2118
|
indexer.getVtxos({ scripts, spendableOnly: true }),
|
|
1857
2119
|
indexer.getVtxos({ scripts, recoverableOnly: true })
|
|
@@ -1877,13 +2139,13 @@ async function findLockupVtxos(indexer, swapPkScript) {
|
|
|
1877
2139
|
}
|
|
1878
2140
|
return out;
|
|
1879
2141
|
}
|
|
1880
|
-
var hashesTo = (candidate, paymentHash) =>
|
|
2142
|
+
var hashesTo = (candidate, paymentHash) => hex10.encode(sha2563(candidate)) === paymentHash;
|
|
1881
2143
|
var candidateWitnessItems = (tx, inputIndex) => [
|
|
1882
2144
|
...getArkPsbtFields(tx, inputIndex, ConditionWitness).flat(),
|
|
1883
2145
|
...tx.getInput(inputIndex).finalScriptWitness ?? []
|
|
1884
2146
|
];
|
|
1885
2147
|
async function readLockupFate(indexer, input) {
|
|
1886
|
-
const { vtxos } = await indexer.getVtxos({ scripts: [
|
|
2148
|
+
const { vtxos } = await indexer.getVtxos({ scripts: [hex10.encode(input.swapPkScript)] });
|
|
1887
2149
|
const all = vtxos ?? [];
|
|
1888
2150
|
if (all.length === 0) return { fate: "unknown" };
|
|
1889
2151
|
const exited = all.filter((vtxo) => vtxo.isUnrolled && !hasTerminalSpend(vtxo));
|
|
@@ -1910,7 +2172,7 @@ async function readLockupFate(indexer, input) {
|
|
|
1910
2172
|
for (const raw of txs) {
|
|
1911
2173
|
let tx;
|
|
1912
2174
|
try {
|
|
1913
|
-
tx = Transaction3.fromPSBT(
|
|
2175
|
+
tx = Transaction3.fromPSBT(base644.decode(raw));
|
|
1914
2176
|
} catch {
|
|
1915
2177
|
continue;
|
|
1916
2178
|
}
|
|
@@ -1918,7 +2180,7 @@ async function readLockupFate(indexer, input) {
|
|
|
1918
2180
|
for (let i = 0; i < tx.inputsLength; i++) {
|
|
1919
2181
|
const spent = tx.getInput(i);
|
|
1920
2182
|
if (!spent.txid) continue;
|
|
1921
|
-
const txid =
|
|
2183
|
+
const txid = hex10.encode(spent.txid);
|
|
1922
2184
|
if (!all.some((vtxo) => vtxo.txid === txid && vtxo.vout === spent.index)) continue;
|
|
1923
2185
|
for (const candidate of candidateWitnessItems(tx, i)) {
|
|
1924
2186
|
if (hashesTo(candidate, input.paymentHash)) {
|
|
@@ -1947,7 +2209,7 @@ async function pushRefundWithoutReceiver(ark, input) {
|
|
|
1947
2209
|
const info = await ark.getInfo();
|
|
1948
2210
|
let serverUnrollScript;
|
|
1949
2211
|
try {
|
|
1950
|
-
serverUnrollScript = CSVMultisigTapscript.decode(
|
|
2212
|
+
serverUnrollScript = CSVMultisigTapscript.decode(hex10.decode(info.checkpointTapscript));
|
|
1951
2213
|
} catch {
|
|
1952
2214
|
throw new Error("invalid checkpointTapscript from the Arkade server");
|
|
1953
2215
|
}
|
|
@@ -1967,8 +2229,8 @@ async function pushRefundWithoutReceiver(ark, input) {
|
|
|
1967
2229
|
);
|
|
1968
2230
|
const signedArkTx = await input.sender.sign(arkTx);
|
|
1969
2231
|
const submitted = await ark.submitTx(
|
|
1970
|
-
|
|
1971
|
-
checkpoints.map((c) =>
|
|
2232
|
+
base644.encode(signedArkTx.toPSBT()),
|
|
2233
|
+
checkpoints.map((c) => base644.encode(c.toPSBT()))
|
|
1972
2234
|
);
|
|
1973
2235
|
assertSubmittedArkTxid(submitted, signedArkTx, "refundWithoutReceiver");
|
|
1974
2236
|
const matched = matchServerCheckpoints(
|
|
@@ -1978,7 +2240,7 @@ async function pushRefundWithoutReceiver(ark, input) {
|
|
|
1978
2240
|
);
|
|
1979
2241
|
const finalCheckpoints = await Promise.all(
|
|
1980
2242
|
matched.map(
|
|
1981
|
-
async ({ server }) =>
|
|
2243
|
+
async ({ server }) => base644.encode((await input.sender.sign(server, [0])).toPSBT())
|
|
1982
2244
|
)
|
|
1983
2245
|
);
|
|
1984
2246
|
await ark.finalizeTx(submitted.arkTxid, finalCheckpoints);
|
|
@@ -2073,13 +2335,13 @@ async function pushClaim(ark, input) {
|
|
|
2073
2335
|
}
|
|
2074
2336
|
}
|
|
2075
2337
|
const committed = input.script.options.preimageHash;
|
|
2076
|
-
if (
|
|
2338
|
+
if (hex11.encode(ripemd1602(sha2564(input.preimage))) !== hex11.encode(committed)) {
|
|
2077
2339
|
throw new Error("preimage does not match the covenant's payment hash");
|
|
2078
2340
|
}
|
|
2079
2341
|
const info = await ark.getInfo();
|
|
2080
2342
|
let serverUnrollScript;
|
|
2081
2343
|
try {
|
|
2082
|
-
serverUnrollScript = CSVMultisigTapscript2.decode(
|
|
2344
|
+
serverUnrollScript = CSVMultisigTapscript2.decode(hex11.decode(info.checkpointTapscript));
|
|
2083
2345
|
} catch {
|
|
2084
2346
|
throw new Error("invalid checkpointTapscript from the Arkade server");
|
|
2085
2347
|
}
|
|
@@ -2198,7 +2460,10 @@ function arkadeRefunder(deps) {
|
|
|
2198
2460
|
}
|
|
2199
2461
|
|
|
2200
2462
|
// src/swapManager.ts
|
|
2201
|
-
import { hex as
|
|
2463
|
+
import { hex as hex12 } from "@scure/base";
|
|
2464
|
+
import {
|
|
2465
|
+
isContractVtxoEvent as isContractVtxoEvent2
|
|
2466
|
+
} from "@arkade-os/sdk";
|
|
2202
2467
|
function nextOnchainAction(input) {
|
|
2203
2468
|
switch (input.phase.phase) {
|
|
2204
2469
|
case "unfunded":
|
|
@@ -2646,7 +2911,7 @@ var RfqSwapManager = class {
|
|
|
2646
2911
|
// ── internals ────────────────────────────────────────────────────────────
|
|
2647
2912
|
track(swap) {
|
|
2648
2913
|
this.monitored.set(swap.rfqId, swap);
|
|
2649
|
-
this.byLockupScript.set(
|
|
2914
|
+
this.byLockupScript.set(hex12.encode(swap.lockupPkScript), swap);
|
|
2650
2915
|
}
|
|
2651
2916
|
/** Drops the swap from BOTH indexes. The event index is the one that stops
|
|
2652
2917
|
* a late event finding a swap that is gone; `pollSwap`'s own
|
|
@@ -2655,7 +2920,7 @@ var RfqSwapManager = class {
|
|
|
2655
2920
|
* them from silently re-driving a cancelled swap. */
|
|
2656
2921
|
untrack(rfqId) {
|
|
2657
2922
|
const swap = this.monitored.get(rfqId);
|
|
2658
|
-
if (swap) this.byLockupScript.delete(
|
|
2923
|
+
if (swap) this.byLockupScript.delete(hex12.encode(swap.lockupPkScript));
|
|
2659
2924
|
this.monitored.delete(rfqId);
|
|
2660
2925
|
this.refundRefused.delete(rfqId);
|
|
2661
2926
|
this.lastClaimError.delete(rfqId);
|
|
@@ -2688,6 +2953,7 @@ var RfqSwapManager = class {
|
|
|
2688
2953
|
});
|
|
2689
2954
|
return;
|
|
2690
2955
|
}
|
|
2956
|
+
if (!isContractVtxoEvent2(event)) return;
|
|
2691
2957
|
const swap = this.byLockupScript.get(event.contractScript);
|
|
2692
2958
|
if (!swap) return;
|
|
2693
2959
|
void this.pollSwap(swap).catch(() => {
|
|
@@ -2717,7 +2983,7 @@ var RfqSwapManager = class {
|
|
|
2717
2983
|
if (!lockup) {
|
|
2718
2984
|
try {
|
|
2719
2985
|
const [existing] = await contracts.getContracts({
|
|
2720
|
-
script:
|
|
2986
|
+
script: hex12.encode(swap.lockupPkScript)
|
|
2721
2987
|
});
|
|
2722
2988
|
if (existing) {
|
|
2723
2989
|
this.registered.set(swap.rfqId, true);
|
|
@@ -2736,13 +3002,13 @@ var RfqSwapManager = class {
|
|
|
2736
3002
|
);
|
|
2737
3003
|
return;
|
|
2738
3004
|
}
|
|
2739
|
-
const script =
|
|
2740
|
-
if (script !==
|
|
3005
|
+
const script = hex12.encode(lockup.script.pkScript);
|
|
3006
|
+
if (script !== hex12.encode(swap.lockupPkScript)) {
|
|
2741
3007
|
this.registered.set(swap.rfqId, false);
|
|
2742
3008
|
this.emitFailed(
|
|
2743
3009
|
swap,
|
|
2744
3010
|
new Error(
|
|
2745
|
-
`swap ${swap.rfqId} lockup script ${script} does not match its lockupPkScript ${
|
|
3011
|
+
`swap ${swap.rfqId} lockup script ${script} does not match its lockupPkScript ${hex12.encode(swap.lockupPkScript)}`
|
|
2746
3012
|
)
|
|
2747
3013
|
);
|
|
2748
3014
|
return;
|
|
@@ -2761,7 +3027,7 @@ var RfqSwapManager = class {
|
|
|
2761
3027
|
* script for its whole life. Best-effort — the swap is over either way. */
|
|
2762
3028
|
retireContract(swap) {
|
|
2763
3029
|
if (!this.deps.contracts || !this.registered.get(swap.rfqId)) return;
|
|
2764
|
-
void this.deps.contracts.setContractWatchState(
|
|
3030
|
+
void this.deps.contracts.setContractWatchState(hex12.encode(swap.lockupPkScript), "retained").catch((error) => this.emitFailed(swap, error));
|
|
2765
3031
|
}
|
|
2766
3032
|
arm() {
|
|
2767
3033
|
if (!this.running) return;
|
|
@@ -3235,9 +3501,9 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
|
|
|
3235
3501
|
|
|
3236
3502
|
// src/activity.ts
|
|
3237
3503
|
import {
|
|
3238
|
-
ArkAddress as
|
|
3504
|
+
ArkAddress as ArkAddress5
|
|
3239
3505
|
} from "@arkade-os/sdk";
|
|
3240
|
-
import { hex as
|
|
3506
|
+
import { hex as hex13 } from "@scure/base";
|
|
3241
3507
|
var LABELS = {
|
|
3242
3508
|
lightning_send: "Lightning send",
|
|
3243
3509
|
lightning_receive: "Lightning receive",
|
|
@@ -3312,7 +3578,7 @@ async function activityInputOf(record, indexer) {
|
|
|
3312
3578
|
async function lockupTxids(indexer, record, wantFunding) {
|
|
3313
3579
|
let script;
|
|
3314
3580
|
try {
|
|
3315
|
-
script =
|
|
3581
|
+
script = hex13.encode(ArkAddress5.decode(record.lockupAddress).pkScript);
|
|
3316
3582
|
} catch {
|
|
3317
3583
|
return [];
|
|
3318
3584
|
}
|
|
@@ -3333,6 +3599,8 @@ export {
|
|
|
3333
3599
|
ARKADE_BTC,
|
|
3334
3600
|
AddressMismatch,
|
|
3335
3601
|
BTC_ASSET_ID,
|
|
3602
|
+
CROSS_ASSET_RAIL,
|
|
3603
|
+
CovclaimdRevealError,
|
|
3336
3604
|
InMemoryAssetSwapRepository,
|
|
3337
3605
|
IndexedDbAssetSwapRepository,
|
|
3338
3606
|
LIGHTNING_BTC,
|
|
@@ -3389,8 +3657,10 @@ export {
|
|
|
3389
3657
|
classifyDepositSpend,
|
|
3390
3658
|
classifyOnchainHtlc,
|
|
3391
3659
|
classifySpend,
|
|
3660
|
+
covclaimdClient,
|
|
3392
3661
|
createOffer,
|
|
3393
3662
|
createRfqSwapRecord,
|
|
3663
|
+
crossAssetRail,
|
|
3394
3664
|
decodeOffer,
|
|
3395
3665
|
deriveLightningReceive,
|
|
3396
3666
|
deriveOnchainReceive,
|
|
@@ -3436,6 +3706,8 @@ export {
|
|
|
3436
3706
|
requestOnchainSend,
|
|
3437
3707
|
restoreAssetSwaps,
|
|
3438
3708
|
retireSettledOfferContracts,
|
|
3709
|
+
revealClaimPacket,
|
|
3710
|
+
revealFieldsFromScript,
|
|
3439
3711
|
rfqClaimSecretOf,
|
|
3440
3712
|
rfqPair,
|
|
3441
3713
|
rfqSecretsProfile,
|
package/dist/nostr.d.cts
CHANGED
package/dist/nostr.d.ts
CHANGED
package/dist/nostr.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RealmLike } from '@arkade-os/sdk/repositories/realm';
|
|
2
|
-
import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-
|
|
2
|
+
import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-Vfx65uF1.cjs';
|
|
3
3
|
import '@arkade-os/solver-discovery';
|
|
4
4
|
import '@arkade-os/sdk';
|
|
5
|
-
import '../../rfq-
|
|
5
|
+
import '../../rfq-CYfKvAPp.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Realm backend for React Native.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RealmLike } from '@arkade-os/sdk/repositories/realm';
|
|
2
|
-
import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-
|
|
2
|
+
import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-D5JoeqwB.js';
|
|
3
3
|
import '@arkade-os/solver-discovery';
|
|
4
4
|
import '@arkade-os/sdk';
|
|
5
|
-
import '../../rfq-
|
|
5
|
+
import '../../rfq-CYfKvAPp.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Realm backend for React Native.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { SQLExecutor } from '@arkade-os/sdk/repositories/sqlite';
|
|
2
|
-
import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-
|
|
2
|
+
import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-Vfx65uF1.cjs';
|
|
3
3
|
import '@arkade-os/solver-discovery';
|
|
4
4
|
import '@arkade-os/sdk';
|
|
5
|
-
import '../../rfq-
|
|
5
|
+
import '../../rfq-CYfKvAPp.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* SQLite backend over the SDK's `SQLExecutor`, so any driver plugs in
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { SQLExecutor } from '@arkade-os/sdk/repositories/sqlite';
|
|
2
|
-
import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-
|
|
2
|
+
import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-D5JoeqwB.js';
|
|
3
3
|
import '@arkade-os/solver-discovery';
|
|
4
4
|
import '@arkade-os/sdk';
|
|
5
|
-
import '../../rfq-
|
|
5
|
+
import '../../rfq-CYfKvAPp.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* SQLite backend over the SDK's `SQLExecutor`, so any driver plugs in
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DiscoveredMarket } from '@arkade-os/solver-discovery';
|
|
2
2
|
import { IWallet, ProvisionedKey, ProvisionedClaimSecret, RestArkProvider, RestIndexerProvider, VHTLC, Identity, IContractManager } from '@arkade-os/sdk';
|
|
3
|
-
import { B as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-
|
|
3
|
+
import { B as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-CYfKvAPp.js';
|
|
4
4
|
|
|
5
5
|
type AssetSwapStatus = "pending" | "cancelling" | "fulfilled" | "cancelled" | "recoverable" | "awaiting_fill" | "claimable" | "claimed" | "refunded_l1";
|
|
6
6
|
/** The sentinel asset id for BTC itself, as opposed to a 68-hex asset id.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DiscoveredMarket } from '@arkade-os/solver-discovery';
|
|
2
2
|
import { IWallet, ProvisionedKey, ProvisionedClaimSecret, RestArkProvider, RestIndexerProvider, VHTLC, Identity, IContractManager } from '@arkade-os/sdk';
|
|
3
|
-
import { B as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-
|
|
3
|
+
import { B as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-CYfKvAPp.cjs';
|
|
4
4
|
|
|
5
5
|
type AssetSwapStatus = "pending" | "cancelling" | "fulfilled" | "cancelled" | "recoverable" | "awaiting_fill" | "claimable" | "claimed" | "refunded_l1";
|
|
6
6
|
/** The sentinel asset id for BTC itself, as opposed to a 68-hex asset id.
|