@arkade-os/swap 0.1.0-rc.3 → 0.1.0-rc.4

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/advanced.cjs CHANGED
@@ -739,7 +739,7 @@ var init_rfq = __esm({
739
739
  payment_hash: input.paymentHash,
740
740
  payout_address: input.payoutAddress,
741
741
  payout_pubkey: import_base7.hex.encode(input.payoutPubkey),
742
- claim_packet: input.claimPacket
742
+ ...input.claimPacket === void 0 ? {} : { claim_packet: input.claimPacket }
743
743
  }
744
744
  });
745
745
  MIN_CLAIM_WINDOW_SECONDS = 30 * 60;
@@ -923,6 +923,7 @@ __export(advanced_exports, {
923
923
  CORRIDOR_FACTORIES: () => CORRIDOR_FACTORIES,
924
924
  CORRIDOR_PASS: () => CORRIDOR_PASS,
925
925
  ClientDisposed: () => ClientDisposed,
926
+ CovclaimdRevealError: () => CovclaimdRevealError,
926
927
  DEFAULT_INVOICE_EXPIRY_SECONDS: () => DEFAULT_INVOICE_EXPIRY_SECONDS,
927
928
  DiscoverySnapshotUnavailable: () => DiscoverySnapshotUnavailable,
928
929
  FEED_TTL_MS: () => FEED_TTL_MS,
@@ -970,6 +971,7 @@ __export(advanced_exports, {
970
971
  corridorOutcome: () => corridorOutcome,
971
972
  corridorRecordStore: () => corridorRecordStore,
972
973
  corridorSet: () => corridorSet,
974
+ covclaimdClient: () => covclaimdClient,
973
975
  createSwapClient: () => createSwapClient,
974
976
  createSwapDrive: () => createSwapDrive,
975
977
  decodeBolt11: () => decodeBolt11,
@@ -1029,6 +1031,8 @@ __export(advanced_exports, {
1029
1031
  resolveCorridorBase: () => resolveCorridorBase,
1030
1032
  resolveCorridorDeps: () => resolveCorridorDeps,
1031
1033
  resolveRoute: () => resolveRoute,
1034
+ revealClaimPacket: () => revealClaimPacket,
1035
+ revealFieldsFromScript: () => revealFieldsFromScript,
1032
1036
  rfqLeg: () => rfqLeg,
1033
1037
  rfqPairFor: () => rfqPairFor,
1034
1038
  rfqRecordOf: () => rfqRecordOf,
@@ -3824,7 +3828,7 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
3824
3828
  const vtxo = vtxoByScriptAndTxid.get(
3825
3829
  `${import_base11.hex.encode(offer.swapPkScript)}:${fundingTx.redeemTxid}`
3826
3830
  );
3827
- if (vtxo?.virtualStatus.state !== "spent") continue;
3831
+ if (!vtxo?.isSpent) continue;
3828
3832
  for (const txid of spendTxidsOf(vtxo)) spendTxids.add(txid);
3829
3833
  }
3830
3834
  const spendTxByTxid = await fetchParsedTxs(indexer, [...spendTxids]);
@@ -3846,11 +3850,10 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
3846
3850
  continue;
3847
3851
  }
3848
3852
  const fromAmount = depositAmount.toString();
3849
- const state = vtxo.virtualStatus.state;
3850
- const spentTxid = state === "spent" ? vtxo.arkTxId || vtxo.spentBy : void 0;
3853
+ const spentTxid = vtxo.isSpent ? vtxo.arkTxId || vtxo.spentBy : void 0;
3851
3854
  let status = "pending";
3852
- if (state === "swept") status = "recoverable";
3853
- else if (state === "spent") {
3855
+ if (vtxo.isSwept) status = "recoverable";
3856
+ else if (vtxo.isSpent) {
3854
3857
  const spendTxs = spendTxidsOf(vtxo).map((id) => spendTxByTxid.get(id)).filter((tx) => tx !== void 0);
3855
3858
  const kind = classifyDepositSpend(offer, operatorPubkey, spendTxs, {
3856
3859
  txid: vtxo.txid,
@@ -6151,7 +6154,7 @@ var usableMarkets = (snapshot, policy) => {
6151
6154
  const allowed = policy?.allowedRegistries;
6152
6155
  return (allowed ? snapshot.markets.filter((card) => allowed.includes(card.source)) : snapshot.markets).filter(isAddressable);
6153
6156
  };
6154
- var eligibleMarkets = (snapshot, legs, policy) => {
6157
+ var eligibleMarkets = (snapshot, legs, policy, takeAmount) => {
6155
6158
  const markets = usableMarkets(snapshot, policy);
6156
6159
  const { give, take } = legs;
6157
6160
  if (give.corridor === take.corridor && give.assetId === take.assetId) return [];
@@ -6165,7 +6168,8 @@ var eligibleMarkets = (snapshot, legs, policy) => {
6165
6168
  quoteCorridor: quote.corridor,
6166
6169
  // The trader receives the take leg, so that side must be one the
6167
6170
  // solver can pay out; a direction nobody solves yields no market.
6168
- wantSide: side === "base" ? "quote" : "base"
6171
+ wantSide: side === "base" ? "quote" : "base",
6172
+ ...takeAmount === void 0 ? {} : { wantAmount: takeAmount }
6169
6173
  }).map((card) => ({
6170
6174
  card,
6171
6175
  give: side,
@@ -6281,7 +6285,12 @@ var resolveRoute = async (input, deps) => {
6281
6285
  claimed?.instrument ?? (takeLeg.corridor === "arkade" ? { kind: "wallet" } : void 0)
6282
6286
  );
6283
6287
  const amount = pinAmount(input, take.instrument);
6284
- const candidates = eligibleMarkets(snapshot, { give: giveLeg, take: takeLeg }, deps.policy);
6288
+ const candidates = eligibleMarkets(
6289
+ snapshot,
6290
+ { give: giveLeg, take: takeLeg },
6291
+ deps.policy,
6292
+ amount?.on === "take" ? amount.value : void 0
6293
+ );
6285
6294
  const market = chooseMarket(candidates, deps.policy);
6286
6295
  const resolution = {
6287
6296
  give,
@@ -7333,6 +7342,129 @@ var createSwapClient = (config) => {
7333
7342
  };
7334
7343
  return client;
7335
7344
  };
7345
+
7346
+ // src/reveal.ts
7347
+ var import_base20 = require("@scure/base");
7348
+ var import_legacy4 = require("@noble/hashes/legacy.js");
7349
+ var import_sha26 = require("@noble/hashes/sha2.js");
7350
+ var import_sdk27 = require("@arkade-os/sdk");
7351
+ init_claimPacket();
7352
+ var CovclaimdRevealError = class extends Error {
7353
+ name = "CovclaimdRevealError";
7354
+ status;
7355
+ detail;
7356
+ retryable;
7357
+ constructor(what, status, detail) {
7358
+ super(`covclaimd ${what} failed: ${status || "no response"} ${detail}`.trimEnd());
7359
+ this.status = status;
7360
+ this.detail = detail;
7361
+ this.retryable = status === 0 || status === 429 || status >= 500;
7362
+ }
7363
+ };
7364
+ var decodeKey = (value, field) => {
7365
+ if (typeof value !== "string") throw new Error(`covclaimd info: ${field} is not a string`);
7366
+ let bytes;
7367
+ try {
7368
+ bytes = import_base20.hex.decode(value);
7369
+ } catch {
7370
+ throw new Error(`covclaimd info: ${field} is not hex`);
7371
+ }
7372
+ if (bytes.length !== 33) {
7373
+ throw new Error(`covclaimd info: ${field} must be 33-byte compressed, got ${bytes.length}`);
7374
+ }
7375
+ return bytes;
7376
+ };
7377
+ var LOOPBACK = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]"]);
7378
+ var assertTransportSecure = (baseUrl, allowInsecureHttp) => {
7379
+ const { protocol, hostname } = new URL(baseUrl);
7380
+ if (protocol === "https:" || allowInsecureHttp) return;
7381
+ if (protocol === "http:" && LOOPBACK.has(hostname)) return;
7382
+ throw new Error(
7383
+ `covclaimd URL must be https (got ${protocol}//${hostname}): the key it serves is the one the preimage gets sealed to. Pass allowInsecureHttp to override.`
7384
+ );
7385
+ };
7386
+ var covclaimdClient = (baseUrl, options = {}) => {
7387
+ assertTransportSecure(baseUrl, options.allowInsecureHttp === true);
7388
+ const url = baseUrl.replace(/\/+$/, "");
7389
+ const fetchImpl = options.fetchImpl ?? fetch;
7390
+ const timeoutMs = options.timeoutMs ?? 3e4;
7391
+ const send = async (what, path, init) => {
7392
+ let response;
7393
+ try {
7394
+ response = await fetchImpl(`${url}${path}`, {
7395
+ ...init,
7396
+ // a redirect would move the key fetch off the vetted origin
7397
+ redirect: "error",
7398
+ signal: AbortSignal.timeout(timeoutMs)
7399
+ });
7400
+ } catch (error) {
7401
+ throw new CovclaimdRevealError(what, 0, String(error));
7402
+ }
7403
+ if (!response.ok) {
7404
+ throw new CovclaimdRevealError(what, response.status, await response.text());
7405
+ }
7406
+ return response;
7407
+ };
7408
+ const readJson = async (what, response) => {
7409
+ const body = await response.text();
7410
+ try {
7411
+ return JSON.parse(body);
7412
+ } catch {
7413
+ throw new CovclaimdRevealError(
7414
+ what,
7415
+ response.status,
7416
+ `non-JSON body: ${body.slice(0, 200)}`
7417
+ );
7418
+ }
7419
+ };
7420
+ return {
7421
+ async info() {
7422
+ const response = await send("info", "/v1/preimage/covclaimd-pubkey", {
7423
+ method: "GET"
7424
+ });
7425
+ const body = await readJson("info", response);
7426
+ return {
7427
+ covclaimdPubkey: decodeKey(body?.covclaimd_pub_key, "covclaimd_pub_key"),
7428
+ emulatorPubkey: import_base20.hex.encode(decodeKey(body?.emulator_pub_key, "emulator_pub_key"))
7429
+ };
7430
+ },
7431
+ async reveal(params) {
7432
+ await send("reveal", "/v1/reveal", {
7433
+ method: "POST",
7434
+ headers: { "content-type": "application/json" },
7435
+ body: JSON.stringify({
7436
+ swap_address: params.swapAddress,
7437
+ packet: { ciphertext: params.ciphertext, arkade_script: params.arkadeScript },
7438
+ taptree: params.taptree
7439
+ })
7440
+ });
7441
+ }
7442
+ };
7443
+ };
7444
+ function revealFieldsFromScript(script) {
7445
+ if (!script.nonInteractiveClaimArkadeScript) {
7446
+ throw new Error("this covenant has no non-interactive claim leaf to reveal against");
7447
+ }
7448
+ return {
7449
+ arkadeScript: import_base20.base64.encode(script.nonInteractiveClaimArkadeScript),
7450
+ taptree: import_base20.hex.encode(script.encode())
7451
+ };
7452
+ }
7453
+ async function revealClaimPacket(client, input) {
7454
+ const fields = revealFieldsFromScript(input.script);
7455
+ if (import_base20.hex.encode(import_sdk27.ArkAddress.decode(input.address).pkScript) !== import_base20.hex.encode(input.script.pkScript)) {
7456
+ throw new Error("address does not belong to this covenant");
7457
+ }
7458
+ if (import_base20.hex.encode((0, import_legacy4.ripemd160)((0, import_sha26.sha256)(input.preimage))) !== import_base20.hex.encode(input.script.options.preimageHash)) {
7459
+ throw new Error("preimage does not match the covenant's payment hash");
7460
+ }
7461
+ const { ciphertext } = await sealClaimPacket({
7462
+ preimage: input.preimage,
7463
+ covclaimdPubkey: (await client.info()).covclaimdPubkey
7464
+ });
7465
+ await client.reveal({ swapAddress: input.address, ciphertext, ...fields });
7466
+ return { ciphertext };
7467
+ }
7336
7468
  // Annotate the CommonJS export names for ESM import in node:
7337
7469
  0 && (module.exports = {
7338
7470
  ACTIVITY_TOKEN,
@@ -7350,6 +7482,7 @@ var createSwapClient = (config) => {
7350
7482
  CORRIDOR_FACTORIES,
7351
7483
  CORRIDOR_PASS,
7352
7484
  ClientDisposed,
7485
+ CovclaimdRevealError,
7353
7486
  DEFAULT_INVOICE_EXPIRY_SECONDS,
7354
7487
  DiscoverySnapshotUnavailable,
7355
7488
  FEED_TTL_MS,
@@ -7397,6 +7530,7 @@ var createSwapClient = (config) => {
7397
7530
  corridorOutcome,
7398
7531
  corridorRecordStore,
7399
7532
  corridorSet,
7533
+ covclaimdClient,
7400
7534
  createSwapClient,
7401
7535
  createSwapDrive,
7402
7536
  decodeBolt11,
@@ -7456,6 +7590,8 @@ var createSwapClient = (config) => {
7456
7590
  resolveCorridorBase,
7457
7591
  resolveCorridorDeps,
7458
7592
  resolveRoute,
7593
+ revealClaimPacket,
7594
+ revealFieldsFromScript,
7459
7595
  rfqLeg,
7460
7596
  rfqPairFor,
7461
7597
  rfqRecordOf,
@@ -1,13 +1,13 @@
1
- import { A as AssetAliasTable, C as CorridorFactory, a as ArkadeCorridorDeps, L as LightningCorridorDeps, O as OnchainCorridorDeps, b as CorridorSet, D as DiscoveryIndex, S as SwapPolicy, c as DiscoveryLeg, M as MarketCandidate, d as DiscoverySnapshot } from './errors-CcvUMXEF.cjs';
2
- export { e as AcceptConflict, f as AcceptInput, g as AmbiguousDestination, h as AmountEncodingUnsupported, i as AmountMismatch, j as AttestingRfqTransport, k as CORRIDOR_FACTORIES, l as CancelInput, m as CancelOutcome, n as ClaimedDestination, o as ClientDisposed, p as CorridorBase, q as CorridorClaim, r as CorridorCovenant, s as CorridorDeadline, t as CorridorDeps, u as CorridorDepsByCorridor, v as CorridorDrive, w as CorridorLockup, x as CorridorModule, y as CorridorOverrides, z as CorridorPass, B as DiscoveryConfig, E as DiscoveryIndexInput, F as DiscoverySnapshotUnavailable, G as DriveMode, H as DriveRefusal, I as ExchangeOptions, J as FEED_TTL_MS, K as FeeCeiling, N as FeedFetch, P as FeedQuoteInput, Q as INDEXED_NETWORKS, R as InconsistentRoute, T as InsufficientFunds, U as LockupOwner, V as Market, W as MaxFeeExceeded, X as MissingCorridorDep, Y as NotCancellable, Z as ONCHAIN_CLAIM_FEE_RATE_SATVB, _ as ObservationSeam, $ as OfferPreparation, a0 as OnchainClaim, a1 as OperatorUnreachable, a2 as ParsedRfqQuote, a3 as PayOptions, a4 as PayResult, a5 as QuoteCheck, a6 as QuoteExpired, a7 as QuotePreparation, a8 as QuoteVerificationFailed, a9 as REGISTRY_URL, aa as ReceiveArtifact, ab as ReceiveOptions, ac as ReceiveRequest, ad as RecoveryResult, ae as RegisteredAsset, af as RfqAuctionPolicy, ag as RfqPreparation, ah as RfqQuoteInput, ai as RfqRendezvous, aj as RfqTransportFactory, ak as RouteSide, al as SWAP_ERROR_NAMES, am as SwapClient, an as SwapClientConfig, ao as SwapDrive, ap as SwapDriveConfig, aq as SwapDriveRefusedError, ar as SwapError, as as SwapErrorName, at as SwapFilter, au as UnsupportedRoute, av as VerbDeps, aw as acceptQuote, ax as attesting, ay as cancelSwap, az as canonicalAssetId, aA as cardMarketOf, aB as chooseMarket, aC as conflictingFields, aD as corridorSet, aE as createSwapClient, aF as createSwapDrive, aG as discoveryIndex, aH as eligibleMarkets, aI as enforceFeeCeiling, aJ as exchange, aK as feedFetch, aL as isAddressable, aM as isCardMarket, aN as isIndexedNetwork, aO as isSwapError, aP as isUsableCard, aQ as liveArkadeInfo, aR as marketBackendOf, aS as marketKeyOf, aT as marketRefOf, aU as nostrTransportFactory, aV as parseRfqQuote, aW as pay, aX as quoteFromFeed, aY as quoteViaRfq, aZ as readableRecord, a_ as receive, a$ as resolveCorridorBase, b0 as resolveCorridorDeps, b1 as rfqLeg, b2 as rfqPairFor, b3 as swapRecordOf, b4 as toDiscoveryLeg, b5 as usableMarkets, b6 as withCanonicalAmount } from './errors-CcvUMXEF.cjs';
1
+ import { A as AssetAliasTable, C as CorridorFactory, a as ArkadeCorridorDeps, L as LightningCorridorDeps, O as OnchainCorridorDeps, b as CorridorSet, D as DiscoveryIndex, S as SwapPolicy, c as DiscoveryLeg, M as MarketCandidate, d as DiscoverySnapshot } from './errors-DwF4nDkm.cjs';
2
+ export { e as AcceptConflict, f as AcceptInput, g as AmbiguousDestination, h as AmountEncodingUnsupported, i as AmountMismatch, j as AttestingRfqTransport, k as CORRIDOR_FACTORIES, l as CancelInput, m as CancelOutcome, n as ClaimedDestination, o as ClientDisposed, p as CorridorBase, q as CorridorClaim, r as CorridorCovenant, s as CorridorDeadline, t as CorridorDeps, u as CorridorDepsByCorridor, v as CorridorDrive, w as CorridorLockup, x as CorridorModule, y as CorridorOverrides, z as CorridorPass, B as DiscoveryConfig, E as DiscoveryIndexInput, F as DiscoverySnapshotUnavailable, G as DriveMode, H as DriveRefusal, I as ExchangeOptions, J as FEED_TTL_MS, K as FeeCeiling, N as FeedFetch, P as FeedQuoteInput, Q as INDEXED_NETWORKS, R as InconsistentRoute, T as InsufficientFunds, U as LockupOwner, V as Market, W as MaxFeeExceeded, X as MissingCorridorDep, Y as NotCancellable, Z as ONCHAIN_CLAIM_FEE_RATE_SATVB, _ as ObservationSeam, $ as OfferPreparation, a0 as OnchainClaim, a1 as OperatorUnreachable, a2 as ParsedRfqQuote, a3 as PayOptions, a4 as PayResult, a5 as QuoteCheck, a6 as QuoteExpired, a7 as QuotePreparation, a8 as QuoteVerificationFailed, a9 as REGISTRY_URL, aa as ReceiveArtifact, ab as ReceiveOptions, ac as ReceiveRequest, ad as RecoveryResult, ae as RegisteredAsset, af as RfqAuctionPolicy, ag as RfqPreparation, ah as RfqQuoteInput, ai as RfqRendezvous, aj as RfqTransportFactory, ak as RouteSide, al as SWAP_ERROR_NAMES, am as SwapClient, an as SwapClientConfig, ao as SwapDrive, ap as SwapDriveConfig, aq as SwapDriveRefusedError, ar as SwapError, as as SwapErrorName, at as SwapFilter, au as UnsupportedRoute, av as VerbDeps, aw as acceptQuote, ax as attesting, ay as cancelSwap, az as canonicalAssetId, aA as cardMarketOf, aB as chooseMarket, aC as conflictingFields, aD as corridorSet, aE as createSwapClient, aF as createSwapDrive, aG as discoveryIndex, aH as eligibleMarkets, aI as enforceFeeCeiling, aJ as exchange, aK as feedFetch, aL as isAddressable, aM as isCardMarket, aN as isIndexedNetwork, aO as isSwapError, aP as isUsableCard, aQ as liveArkadeInfo, aR as marketBackendOf, aS as marketKeyOf, aT as marketRefOf, aU as nostrTransportFactory, aV as parseRfqQuote, aW as pay, aX as quoteFromFeed, aY as quoteViaRfq, aZ as readableRecord, a_ as receive, a$ as resolveCorridorBase, b0 as resolveCorridorDeps, b1 as rfqLeg, b2 as rfqPairFor, b3 as swapRecordOf, b4 as toDiscoveryLeg, b5 as usableMarkets, b6 as withCanonicalAmount } from './errors-DwF4nDkm.cjs';
3
3
  import { DiscoveredMarket } from '@arkade-os/solver-discovery';
4
- import { N as NetworkRef, C as Corridor, A as AssetId, R as Rail, a as RfqSwapRecordStore, b as CorridorSwapRecord, Q as QuoteId, S as SwapRecord, O as OfferSwapRecord, c as AssetSwapRepository, d as RfqSwapRecord, L as LockupSpendIndexer, e as AssetSwapStatus, f as RouteResolution, g as ResolvedEndpoint, P as PinnedAmount, I as Instrument, h as Route, i as QuoteInput, j as Pubkey } from './repository-B8MJY64N.cjs';
5
- export { k as ACTIVITY_TOKEN, l as ARKADE_ASSET_NAMESPACE, m as Amount, n as AmountFormatError, o as AmountOn, p as AmountRefusal, q as Artifact, r as AssetIdError, s as AssetIdRefusal, t as AssetNamespace, u as AssetOn, v as AssetPart, w as AssetRef, x as AssetScale, y as AssetSwapId, z as AtomicDecimal, B as AuctionMarketRef, D as AuctionProvenance, E as BITCOIN_RAILS, F as BTC_ASSET_PART, G as BitcoinRail, H as CORRIDORS, J as CORRIDOR_PASS, K as CardMarketRef, M as CorridorId, T as CorridorKind, U as DepositArtifact, V as DisplayDecimal, W as Endpoint, X as Ep, Y as Hex, Z as LOCKUP_OWNER, _ as MarketBackend, $ as MarketRef, a0 as OFFER_SWAP_ID_PREFIX, a1 as Outcome, a2 as ParsedAssetId, a3 as Quote, a4 as QuoteLeg, a5 as RAILS, a6 as RFQ_SWAP_ID_PREFIX, a7 as RailOf, a8 as RankedBid, a9 as RawState, aa as RecordedArtifact, ab as RecordedEndpoint, ac as RecordedInstrument, ad as RecordedLeg, ae as RfqAmountSide, af as SnapshotRef, ag as Swap, ah as SwapFamily, ai as SwapRecordCommon, aj as SwapUpdate, ak as Unsubscribe, al as arkadeAsset, am as artifactOf, an as assetPartOf, ao as assetSwapIdOf, ap as bitcoinNetworkOf, aq as btcOn, ar as corridorOfRail, as as corridorOutcome, at as decodeRfqAmount, au as encodeRfqAmount, av as familyOfSwapId, aw as formatAssetId, ax as fromAtomicDecimal, ay as fromRfqAmountSide, az as fundsFromWallet, aA as instrumentOf, aB as isAssetId, aC as isAtomicDecimal, aD as isNetworkRef, aE as issuanceOf, aF as legOf, aG as offerOutcome, aH as parseAssetId, aI as quoteIdOfSwapId, aJ as railOf, aK as railOfCorridor, aL as readsChain, aM as recordArtifact, aN as recordEndpoint, aO as recordInstrument, aP as recordLeg, aQ as recordOutcome, aR as sameAsset, aS as swapOf, aT as toAtomicDecimal, aU as toRfqAmountSide, aV as toSafeNumber } from './repository-B8MJY64N.cjs';
6
- import { I as InvoiceFacts, C as ChainSource, R as RfqQuote } from './rfq-CSgBQkjl.cjs';
7
- export { S as SwapRefusal } from './rfq-CSgBQkjl.cjs';
4
+ import { N as NetworkRef, C as Corridor, A as AssetId, R as Rail, a as RfqSwapRecordStore, b as CorridorSwapRecord, Q as QuoteId, S as SwapRecord, O as OfferSwapRecord, c as AssetSwapRepository, d as RfqSwapRecord, L as LockupSpendIndexer, e as AssetSwapStatus, f as RouteResolution, g as ResolvedEndpoint, P as PinnedAmount, I as Instrument, h as Route, i as QuoteInput, j as Pubkey } from './repository-C7wOrIpV.cjs';
5
+ export { k as ACTIVITY_TOKEN, l as ARKADE_ASSET_NAMESPACE, m as Amount, n as AmountFormatError, o as AmountOn, p as AmountRefusal, q as Artifact, r as AssetIdError, s as AssetIdRefusal, t as AssetNamespace, u as AssetOn, v as AssetPart, w as AssetRef, x as AssetScale, y as AssetSwapId, z as AtomicDecimal, B as AuctionMarketRef, D as AuctionProvenance, E as BITCOIN_RAILS, F as BTC_ASSET_PART, G as BitcoinRail, H as CORRIDORS, J as CORRIDOR_PASS, K as CardMarketRef, M as CorridorId, T as CorridorKind, U as DepositArtifact, V as DisplayDecimal, W as Endpoint, X as Ep, Y as Hex, Z as LOCKUP_OWNER, _ as MarketBackend, $ as MarketRef, a0 as OFFER_SWAP_ID_PREFIX, a1 as Outcome, a2 as ParsedAssetId, a3 as Quote, a4 as QuoteLeg, a5 as RAILS, a6 as RFQ_SWAP_ID_PREFIX, a7 as RailOf, a8 as RankedBid, a9 as RawState, aa as RecordedArtifact, ab as RecordedEndpoint, ac as RecordedInstrument, ad as RecordedLeg, ae as RfqAmountSide, af as SnapshotRef, ag as Swap, ah as SwapFamily, ai as SwapRecordCommon, aj as SwapUpdate, ak as Unsubscribe, al as arkadeAsset, am as artifactOf, an as assetPartOf, ao as assetSwapIdOf, ap as bitcoinNetworkOf, aq as btcOn, ar as corridorOfRail, as as corridorOutcome, at as decodeRfqAmount, au as encodeRfqAmount, av as familyOfSwapId, aw as formatAssetId, ax as fromAtomicDecimal, ay as fromRfqAmountSide, az as fundsFromWallet, aA as instrumentOf, aB as isAssetId, aC as isAtomicDecimal, aD as isNetworkRef, aE as issuanceOf, aF as legOf, aG as offerOutcome, aH as parseAssetId, aI as quoteIdOfSwapId, aJ as railOf, aK as railOfCorridor, aL as readsChain, aM as recordArtifact, aN as recordEndpoint, aO as recordInstrument, aP as recordLeg, aQ as recordOutcome, aR as sameAsset, aS as swapOf, aT as toAtomicDecimal, aU as toRfqAmountSide, aV as toSafeNumber } from './repository-C7wOrIpV.cjs';
6
+ import { I as InvoiceFacts, C as ChainSource, R as RfqQuote } from './rfq-RONK76D7.cjs';
7
+ export { S as SwapRefusal } from './rfq-RONK76D7.cjs';
8
8
  import * as btc from '@scure/btc-signer';
9
- import { OnchainProvider, NetworkName, IWallet } from '@arkade-os/sdk';
10
- import { O as OfferSpendChanges, a as OfferSwapFacts, b as OfferSwapSource } from './watch-BjMc3SFo.cjs';
9
+ import { OnchainProvider, NetworkName, IWallet, VHTLC } from '@arkade-os/sdk';
10
+ import { O as OfferSpendChanges, a as OfferSwapFacts, b as OfferSwapSource } from './watch-C3hv5rOW.cjs';
11
11
 
12
12
  /**
13
13
  * The alias table, filled from discovery.
@@ -583,4 +583,75 @@ declare const verifyQuotedAmount: (input: {
583
583
  readonly take: bigint;
584
584
  }) => void;
585
585
 
586
- export { type AddressParams, ArkadeCorridorDeps, AssetAliasTable, AssetId, type ChainSourceBackend, Corridor, CorridorFactory, type CorridorRecordStore, CorridorSet, CorridorSwapRecord, DEFAULT_INVOICE_EXPIRY_SECONDS, DiscoveryIndex, DiscoveryLeg, DiscoverySnapshot, INVOICE_HRPS, Instrument, type L1Tip, LIGHTNING_DRIVE, LightningCorridorDeps, MarketCandidate, NetworkRef, ONCHAIN_DRIVE, OfferSwapRecord, OnchainCorridorDeps, PinnedAmount, Pubkey, QuoteId, QuoteInput, Rail, type RecordSink, type ResolveDeps, ResolvedEndpoint, type ResolvedRoute, Route, RouteResolution, SwapPolicy, SwapRecord, aliasTableFrom, applyOfferSpend, arkadeCorridor, assembleRoute, chainSourceOver, corridorRecordStore, decodeBolt11, esploraChainSource, esploraTip, lightningCorridor, networksOfInvoiceHrp, offerFactsOf, offerRecordSource, onchainCorridor, publicAssetId, resolveRoute, rfqRecordOf, satsOf, scopedToRail, splitRecords, verifyPair, verifyQuoteTtl, verifyQuotedAmount, verifyReceiveInvoiceFacts, verifyReceiveWindow, verifyResponder, verifySendInvoice, verifySendWindow, verifyingDerivation, walletLockupIndexer, withOfferStatus, withRfqState };
586
+ /**
587
+ * `retryable` is the point of the type: a 400 says the packet does not bind to
588
+ * this address at this daemon — wrong key, script or taptree — and retrying
589
+ * changes none of them. Only a full registry (429) and a transport fault (5xx,
590
+ * or `status` 0 for a throwing `fetch`) are worth trying again.
591
+ */
592
+ declare class CovclaimdRevealError extends Error {
593
+ readonly name = "CovclaimdRevealError";
594
+ readonly status: number;
595
+ readonly detail: string;
596
+ readonly retryable: boolean;
597
+ constructor(what: string, status: number, detail: string);
598
+ }
599
+ interface CovclaimdInfo {
600
+ /** 33-byte compressed — feeds {@link sealClaimPacket} unchanged. */
601
+ covclaimdPubkey: Uint8Array;
602
+ /** Compressed hex — feeds `requestLightningReceive`'s `emulatorPubkey`. */
603
+ emulatorPubkey: string;
604
+ }
605
+ /** The four fields `POST /v1/reveal` takes. */
606
+ interface RevealParams {
607
+ /** The funded lockup's Arkade address, bech32m. */
608
+ swapAddress: string;
609
+ /** `sealClaimPacket(...).ciphertext`, base64. */
610
+ ciphertext: string;
611
+ /** The covenant's `enforcePayTo` ArkadeScript, base64. */
612
+ arkadeScript: string;
613
+ /** The lockup's serialized taptree, hex. */
614
+ taptree: string;
615
+ }
616
+ interface CovclaimdClient {
617
+ info(): Promise<CovclaimdInfo>;
618
+ reveal(params: RevealParams): Promise<void>;
619
+ }
620
+ /** `fetchImpl` is injectable, matching `httpTransport` in `rfq.ts`. */
621
+ declare const covclaimdClient: (baseUrl: string, options?: {
622
+ fetchImpl?: typeof fetch;
623
+ timeoutMs?: number;
624
+ /** Opt out of the TLS requirement — a private network you trust. */
625
+ allowInsecureHttp?: boolean;
626
+ }) => CovclaimdClient;
627
+ /**
628
+ * The two wire fields that are functions of the covenant alone.
629
+ *
630
+ * A client-derived `arkadeScript` can differ from the funder's only if the
631
+ * covenants differ: the script is tweaked into the non-interactive claim leaf's
632
+ * co-signer key, so a different one is a different leaf, root, and lockup
633
+ * address — already covered by the address check made before funding.
634
+ */
635
+ declare function revealFieldsFromScript(script: InstanceType<typeof VHTLC.ScriptV2>): {
636
+ arkadeScript: string;
637
+ taptree: string;
638
+ };
639
+ /**
640
+ * Seal `P` to the daemon `client` speaks to and register it there, so covclaimd
641
+ * claims the lockup once the solver funds it and the trader can go offline.
642
+ *
643
+ * Registration EXPIRES — covclaimd drops it 15 minutes after the last reveal —
644
+ * and re-revealing refreshes rather than duplicates it, so a caller waiting on
645
+ * a slow funding should reveal again, not once. The two gates below name a
646
+ * cause covclaimd would otherwise report as an opaque 400.
647
+ */
648
+ declare function revealClaimPacket(client: CovclaimdClient, input: {
649
+ script: InstanceType<typeof VHTLC.ScriptV2>;
650
+ address: string;
651
+ /** `P`, 32 bytes, from the swap's `secrets`. */
652
+ preimage: Uint8Array;
653
+ }): Promise<{
654
+ ciphertext: string;
655
+ }>;
656
+
657
+ export { type AddressParams, ArkadeCorridorDeps, AssetAliasTable, AssetId, type ChainSourceBackend, Corridor, CorridorFactory, type CorridorRecordStore, CorridorSet, CorridorSwapRecord, type CovclaimdClient, type CovclaimdInfo, CovclaimdRevealError, DEFAULT_INVOICE_EXPIRY_SECONDS, DiscoveryIndex, DiscoveryLeg, DiscoverySnapshot, INVOICE_HRPS, Instrument, type L1Tip, LIGHTNING_DRIVE, LightningCorridorDeps, MarketCandidate, NetworkRef, ONCHAIN_DRIVE, OfferSwapRecord, OnchainCorridorDeps, PinnedAmount, Pubkey, QuoteId, QuoteInput, Rail, type RecordSink, type ResolveDeps, ResolvedEndpoint, type ResolvedRoute, type RevealParams, Route, RouteResolution, SwapPolicy, SwapRecord, aliasTableFrom, applyOfferSpend, arkadeCorridor, assembleRoute, chainSourceOver, corridorRecordStore, covclaimdClient, decodeBolt11, esploraChainSource, esploraTip, lightningCorridor, networksOfInvoiceHrp, offerFactsOf, offerRecordSource, onchainCorridor, publicAssetId, resolveRoute, revealClaimPacket, revealFieldsFromScript, rfqRecordOf, satsOf, scopedToRail, splitRecords, verifyPair, verifyQuoteTtl, verifyQuotedAmount, verifyReceiveInvoiceFacts, verifyReceiveWindow, verifyResponder, verifySendInvoice, verifySendWindow, verifyingDerivation, walletLockupIndexer, withOfferStatus, withRfqState };
@@ -1,13 +1,13 @@
1
- import { A as AssetAliasTable, C as CorridorFactory, a as ArkadeCorridorDeps, L as LightningCorridorDeps, O as OnchainCorridorDeps, b as CorridorSet, D as DiscoveryIndex, S as SwapPolicy, c as DiscoveryLeg, M as MarketCandidate, d as DiscoverySnapshot } from './errors-Cwz3Xh72.js';
2
- export { e as AcceptConflict, f as AcceptInput, g as AmbiguousDestination, h as AmountEncodingUnsupported, i as AmountMismatch, j as AttestingRfqTransport, k as CORRIDOR_FACTORIES, l as CancelInput, m as CancelOutcome, n as ClaimedDestination, o as ClientDisposed, p as CorridorBase, q as CorridorClaim, r as CorridorCovenant, s as CorridorDeadline, t as CorridorDeps, u as CorridorDepsByCorridor, v as CorridorDrive, w as CorridorLockup, x as CorridorModule, y as CorridorOverrides, z as CorridorPass, B as DiscoveryConfig, E as DiscoveryIndexInput, F as DiscoverySnapshotUnavailable, G as DriveMode, H as DriveRefusal, I as ExchangeOptions, J as FEED_TTL_MS, K as FeeCeiling, N as FeedFetch, P as FeedQuoteInput, Q as INDEXED_NETWORKS, R as InconsistentRoute, T as InsufficientFunds, U as LockupOwner, V as Market, W as MaxFeeExceeded, X as MissingCorridorDep, Y as NotCancellable, Z as ONCHAIN_CLAIM_FEE_RATE_SATVB, _ as ObservationSeam, $ as OfferPreparation, a0 as OnchainClaim, a1 as OperatorUnreachable, a2 as ParsedRfqQuote, a3 as PayOptions, a4 as PayResult, a5 as QuoteCheck, a6 as QuoteExpired, a7 as QuotePreparation, a8 as QuoteVerificationFailed, a9 as REGISTRY_URL, aa as ReceiveArtifact, ab as ReceiveOptions, ac as ReceiveRequest, ad as RecoveryResult, ae as RegisteredAsset, af as RfqAuctionPolicy, ag as RfqPreparation, ah as RfqQuoteInput, ai as RfqRendezvous, aj as RfqTransportFactory, ak as RouteSide, al as SWAP_ERROR_NAMES, am as SwapClient, an as SwapClientConfig, ao as SwapDrive, ap as SwapDriveConfig, aq as SwapDriveRefusedError, ar as SwapError, as as SwapErrorName, at as SwapFilter, au as UnsupportedRoute, av as VerbDeps, aw as acceptQuote, ax as attesting, ay as cancelSwap, az as canonicalAssetId, aA as cardMarketOf, aB as chooseMarket, aC as conflictingFields, aD as corridorSet, aE as createSwapClient, aF as createSwapDrive, aG as discoveryIndex, aH as eligibleMarkets, aI as enforceFeeCeiling, aJ as exchange, aK as feedFetch, aL as isAddressable, aM as isCardMarket, aN as isIndexedNetwork, aO as isSwapError, aP as isUsableCard, aQ as liveArkadeInfo, aR as marketBackendOf, aS as marketKeyOf, aT as marketRefOf, aU as nostrTransportFactory, aV as parseRfqQuote, aW as pay, aX as quoteFromFeed, aY as quoteViaRfq, aZ as readableRecord, a_ as receive, a$ as resolveCorridorBase, b0 as resolveCorridorDeps, b1 as rfqLeg, b2 as rfqPairFor, b3 as swapRecordOf, b4 as toDiscoveryLeg, b5 as usableMarkets, b6 as withCanonicalAmount } from './errors-Cwz3Xh72.js';
1
+ import { A as AssetAliasTable, C as CorridorFactory, a as ArkadeCorridorDeps, L as LightningCorridorDeps, O as OnchainCorridorDeps, b as CorridorSet, D as DiscoveryIndex, S as SwapPolicy, c as DiscoveryLeg, M as MarketCandidate, d as DiscoverySnapshot } from './errors-C-jdh0_4.js';
2
+ export { e as AcceptConflict, f as AcceptInput, g as AmbiguousDestination, h as AmountEncodingUnsupported, i as AmountMismatch, j as AttestingRfqTransport, k as CORRIDOR_FACTORIES, l as CancelInput, m as CancelOutcome, n as ClaimedDestination, o as ClientDisposed, p as CorridorBase, q as CorridorClaim, r as CorridorCovenant, s as CorridorDeadline, t as CorridorDeps, u as CorridorDepsByCorridor, v as CorridorDrive, w as CorridorLockup, x as CorridorModule, y as CorridorOverrides, z as CorridorPass, B as DiscoveryConfig, E as DiscoveryIndexInput, F as DiscoverySnapshotUnavailable, G as DriveMode, H as DriveRefusal, I as ExchangeOptions, J as FEED_TTL_MS, K as FeeCeiling, N as FeedFetch, P as FeedQuoteInput, Q as INDEXED_NETWORKS, R as InconsistentRoute, T as InsufficientFunds, U as LockupOwner, V as Market, W as MaxFeeExceeded, X as MissingCorridorDep, Y as NotCancellable, Z as ONCHAIN_CLAIM_FEE_RATE_SATVB, _ as ObservationSeam, $ as OfferPreparation, a0 as OnchainClaim, a1 as OperatorUnreachable, a2 as ParsedRfqQuote, a3 as PayOptions, a4 as PayResult, a5 as QuoteCheck, a6 as QuoteExpired, a7 as QuotePreparation, a8 as QuoteVerificationFailed, a9 as REGISTRY_URL, aa as ReceiveArtifact, ab as ReceiveOptions, ac as ReceiveRequest, ad as RecoveryResult, ae as RegisteredAsset, af as RfqAuctionPolicy, ag as RfqPreparation, ah as RfqQuoteInput, ai as RfqRendezvous, aj as RfqTransportFactory, ak as RouteSide, al as SWAP_ERROR_NAMES, am as SwapClient, an as SwapClientConfig, ao as SwapDrive, ap as SwapDriveConfig, aq as SwapDriveRefusedError, ar as SwapError, as as SwapErrorName, at as SwapFilter, au as UnsupportedRoute, av as VerbDeps, aw as acceptQuote, ax as attesting, ay as cancelSwap, az as canonicalAssetId, aA as cardMarketOf, aB as chooseMarket, aC as conflictingFields, aD as corridorSet, aE as createSwapClient, aF as createSwapDrive, aG as discoveryIndex, aH as eligibleMarkets, aI as enforceFeeCeiling, aJ as exchange, aK as feedFetch, aL as isAddressable, aM as isCardMarket, aN as isIndexedNetwork, aO as isSwapError, aP as isUsableCard, aQ as liveArkadeInfo, aR as marketBackendOf, aS as marketKeyOf, aT as marketRefOf, aU as nostrTransportFactory, aV as parseRfqQuote, aW as pay, aX as quoteFromFeed, aY as quoteViaRfq, aZ as readableRecord, a_ as receive, a$ as resolveCorridorBase, b0 as resolveCorridorDeps, b1 as rfqLeg, b2 as rfqPairFor, b3 as swapRecordOf, b4 as toDiscoveryLeg, b5 as usableMarkets, b6 as withCanonicalAmount } from './errors-C-jdh0_4.js';
3
3
  import { DiscoveredMarket } from '@arkade-os/solver-discovery';
4
- import { N as NetworkRef, C as Corridor, A as AssetId, R as Rail, a as RfqSwapRecordStore, b as CorridorSwapRecord, Q as QuoteId, S as SwapRecord, O as OfferSwapRecord, c as AssetSwapRepository, d as RfqSwapRecord, L as LockupSpendIndexer, e as AssetSwapStatus, f as RouteResolution, g as ResolvedEndpoint, P as PinnedAmount, I as Instrument, h as Route, i as QuoteInput, j as Pubkey } from './repository-BGlWfv3c.js';
5
- export { k as ACTIVITY_TOKEN, l as ARKADE_ASSET_NAMESPACE, m as Amount, n as AmountFormatError, o as AmountOn, p as AmountRefusal, q as Artifact, r as AssetIdError, s as AssetIdRefusal, t as AssetNamespace, u as AssetOn, v as AssetPart, w as AssetRef, x as AssetScale, y as AssetSwapId, z as AtomicDecimal, B as AuctionMarketRef, D as AuctionProvenance, E as BITCOIN_RAILS, F as BTC_ASSET_PART, G as BitcoinRail, H as CORRIDORS, J as CORRIDOR_PASS, K as CardMarketRef, M as CorridorId, T as CorridorKind, U as DepositArtifact, V as DisplayDecimal, W as Endpoint, X as Ep, Y as Hex, Z as LOCKUP_OWNER, _ as MarketBackend, $ as MarketRef, a0 as OFFER_SWAP_ID_PREFIX, a1 as Outcome, a2 as ParsedAssetId, a3 as Quote, a4 as QuoteLeg, a5 as RAILS, a6 as RFQ_SWAP_ID_PREFIX, a7 as RailOf, a8 as RankedBid, a9 as RawState, aa as RecordedArtifact, ab as RecordedEndpoint, ac as RecordedInstrument, ad as RecordedLeg, ae as RfqAmountSide, af as SnapshotRef, ag as Swap, ah as SwapFamily, ai as SwapRecordCommon, aj as SwapUpdate, ak as Unsubscribe, al as arkadeAsset, am as artifactOf, an as assetPartOf, ao as assetSwapIdOf, ap as bitcoinNetworkOf, aq as btcOn, ar as corridorOfRail, as as corridorOutcome, at as decodeRfqAmount, au as encodeRfqAmount, av as familyOfSwapId, aw as formatAssetId, ax as fromAtomicDecimal, ay as fromRfqAmountSide, az as fundsFromWallet, aA as instrumentOf, aB as isAssetId, aC as isAtomicDecimal, aD as isNetworkRef, aE as issuanceOf, aF as legOf, aG as offerOutcome, aH as parseAssetId, aI as quoteIdOfSwapId, aJ as railOf, aK as railOfCorridor, aL as readsChain, aM as recordArtifact, aN as recordEndpoint, aO as recordInstrument, aP as recordLeg, aQ as recordOutcome, aR as sameAsset, aS as swapOf, aT as toAtomicDecimal, aU as toRfqAmountSide, aV as toSafeNumber } from './repository-BGlWfv3c.js';
6
- import { I as InvoiceFacts, C as ChainSource, R as RfqQuote } from './rfq-CSgBQkjl.js';
7
- export { S as SwapRefusal } from './rfq-CSgBQkjl.js';
4
+ import { N as NetworkRef, C as Corridor, A as AssetId, R as Rail, a as RfqSwapRecordStore, b as CorridorSwapRecord, Q as QuoteId, S as SwapRecord, O as OfferSwapRecord, c as AssetSwapRepository, d as RfqSwapRecord, L as LockupSpendIndexer, e as AssetSwapStatus, f as RouteResolution, g as ResolvedEndpoint, P as PinnedAmount, I as Instrument, h as Route, i as QuoteInput, j as Pubkey } from './repository-CToRX7Gj.js';
5
+ export { k as ACTIVITY_TOKEN, l as ARKADE_ASSET_NAMESPACE, m as Amount, n as AmountFormatError, o as AmountOn, p as AmountRefusal, q as Artifact, r as AssetIdError, s as AssetIdRefusal, t as AssetNamespace, u as AssetOn, v as AssetPart, w as AssetRef, x as AssetScale, y as AssetSwapId, z as AtomicDecimal, B as AuctionMarketRef, D as AuctionProvenance, E as BITCOIN_RAILS, F as BTC_ASSET_PART, G as BitcoinRail, H as CORRIDORS, J as CORRIDOR_PASS, K as CardMarketRef, M as CorridorId, T as CorridorKind, U as DepositArtifact, V as DisplayDecimal, W as Endpoint, X as Ep, Y as Hex, Z as LOCKUP_OWNER, _ as MarketBackend, $ as MarketRef, a0 as OFFER_SWAP_ID_PREFIX, a1 as Outcome, a2 as ParsedAssetId, a3 as Quote, a4 as QuoteLeg, a5 as RAILS, a6 as RFQ_SWAP_ID_PREFIX, a7 as RailOf, a8 as RankedBid, a9 as RawState, aa as RecordedArtifact, ab as RecordedEndpoint, ac as RecordedInstrument, ad as RecordedLeg, ae as RfqAmountSide, af as SnapshotRef, ag as Swap, ah as SwapFamily, ai as SwapRecordCommon, aj as SwapUpdate, ak as Unsubscribe, al as arkadeAsset, am as artifactOf, an as assetPartOf, ao as assetSwapIdOf, ap as bitcoinNetworkOf, aq as btcOn, ar as corridorOfRail, as as corridorOutcome, at as decodeRfqAmount, au as encodeRfqAmount, av as familyOfSwapId, aw as formatAssetId, ax as fromAtomicDecimal, ay as fromRfqAmountSide, az as fundsFromWallet, aA as instrumentOf, aB as isAssetId, aC as isAtomicDecimal, aD as isNetworkRef, aE as issuanceOf, aF as legOf, aG as offerOutcome, aH as parseAssetId, aI as quoteIdOfSwapId, aJ as railOf, aK as railOfCorridor, aL as readsChain, aM as recordArtifact, aN as recordEndpoint, aO as recordInstrument, aP as recordLeg, aQ as recordOutcome, aR as sameAsset, aS as swapOf, aT as toAtomicDecimal, aU as toRfqAmountSide, aV as toSafeNumber } from './repository-CToRX7Gj.js';
6
+ import { I as InvoiceFacts, C as ChainSource, R as RfqQuote } from './rfq-RONK76D7.js';
7
+ export { S as SwapRefusal } from './rfq-RONK76D7.js';
8
8
  import * as btc from '@scure/btc-signer';
9
- import { OnchainProvider, NetworkName, IWallet } from '@arkade-os/sdk';
10
- import { O as OfferSpendChanges, a as OfferSwapFacts, b as OfferSwapSource } from './watch-DkbPNiqf.js';
9
+ import { OnchainProvider, NetworkName, IWallet, VHTLC } from '@arkade-os/sdk';
10
+ import { O as OfferSpendChanges, a as OfferSwapFacts, b as OfferSwapSource } from './watch-mIKau97G.js';
11
11
 
12
12
  /**
13
13
  * The alias table, filled from discovery.
@@ -583,4 +583,75 @@ declare const verifyQuotedAmount: (input: {
583
583
  readonly take: bigint;
584
584
  }) => void;
585
585
 
586
- export { type AddressParams, ArkadeCorridorDeps, AssetAliasTable, AssetId, type ChainSourceBackend, Corridor, CorridorFactory, type CorridorRecordStore, CorridorSet, CorridorSwapRecord, DEFAULT_INVOICE_EXPIRY_SECONDS, DiscoveryIndex, DiscoveryLeg, DiscoverySnapshot, INVOICE_HRPS, Instrument, type L1Tip, LIGHTNING_DRIVE, LightningCorridorDeps, MarketCandidate, NetworkRef, ONCHAIN_DRIVE, OfferSwapRecord, OnchainCorridorDeps, PinnedAmount, Pubkey, QuoteId, QuoteInput, Rail, type RecordSink, type ResolveDeps, ResolvedEndpoint, type ResolvedRoute, Route, RouteResolution, SwapPolicy, SwapRecord, aliasTableFrom, applyOfferSpend, arkadeCorridor, assembleRoute, chainSourceOver, corridorRecordStore, decodeBolt11, esploraChainSource, esploraTip, lightningCorridor, networksOfInvoiceHrp, offerFactsOf, offerRecordSource, onchainCorridor, publicAssetId, resolveRoute, rfqRecordOf, satsOf, scopedToRail, splitRecords, verifyPair, verifyQuoteTtl, verifyQuotedAmount, verifyReceiveInvoiceFacts, verifyReceiveWindow, verifyResponder, verifySendInvoice, verifySendWindow, verifyingDerivation, walletLockupIndexer, withOfferStatus, withRfqState };
586
+ /**
587
+ * `retryable` is the point of the type: a 400 says the packet does not bind to
588
+ * this address at this daemon — wrong key, script or taptree — and retrying
589
+ * changes none of them. Only a full registry (429) and a transport fault (5xx,
590
+ * or `status` 0 for a throwing `fetch`) are worth trying again.
591
+ */
592
+ declare class CovclaimdRevealError extends Error {
593
+ readonly name = "CovclaimdRevealError";
594
+ readonly status: number;
595
+ readonly detail: string;
596
+ readonly retryable: boolean;
597
+ constructor(what: string, status: number, detail: string);
598
+ }
599
+ interface CovclaimdInfo {
600
+ /** 33-byte compressed — feeds {@link sealClaimPacket} unchanged. */
601
+ covclaimdPubkey: Uint8Array;
602
+ /** Compressed hex — feeds `requestLightningReceive`'s `emulatorPubkey`. */
603
+ emulatorPubkey: string;
604
+ }
605
+ /** The four fields `POST /v1/reveal` takes. */
606
+ interface RevealParams {
607
+ /** The funded lockup's Arkade address, bech32m. */
608
+ swapAddress: string;
609
+ /** `sealClaimPacket(...).ciphertext`, base64. */
610
+ ciphertext: string;
611
+ /** The covenant's `enforcePayTo` ArkadeScript, base64. */
612
+ arkadeScript: string;
613
+ /** The lockup's serialized taptree, hex. */
614
+ taptree: string;
615
+ }
616
+ interface CovclaimdClient {
617
+ info(): Promise<CovclaimdInfo>;
618
+ reveal(params: RevealParams): Promise<void>;
619
+ }
620
+ /** `fetchImpl` is injectable, matching `httpTransport` in `rfq.ts`. */
621
+ declare const covclaimdClient: (baseUrl: string, options?: {
622
+ fetchImpl?: typeof fetch;
623
+ timeoutMs?: number;
624
+ /** Opt out of the TLS requirement — a private network you trust. */
625
+ allowInsecureHttp?: boolean;
626
+ }) => CovclaimdClient;
627
+ /**
628
+ * The two wire fields that are functions of the covenant alone.
629
+ *
630
+ * A client-derived `arkadeScript` can differ from the funder's only if the
631
+ * covenants differ: the script is tweaked into the non-interactive claim leaf's
632
+ * co-signer key, so a different one is a different leaf, root, and lockup
633
+ * address — already covered by the address check made before funding.
634
+ */
635
+ declare function revealFieldsFromScript(script: InstanceType<typeof VHTLC.ScriptV2>): {
636
+ arkadeScript: string;
637
+ taptree: string;
638
+ };
639
+ /**
640
+ * Seal `P` to the daemon `client` speaks to and register it there, so covclaimd
641
+ * claims the lockup once the solver funds it and the trader can go offline.
642
+ *
643
+ * Registration EXPIRES — covclaimd drops it 15 minutes after the last reveal —
644
+ * and re-revealing refreshes rather than duplicates it, so a caller waiting on
645
+ * a slow funding should reveal again, not once. The two gates below name a
646
+ * cause covclaimd would otherwise report as an opaque 400.
647
+ */
648
+ declare function revealClaimPacket(client: CovclaimdClient, input: {
649
+ script: InstanceType<typeof VHTLC.ScriptV2>;
650
+ address: string;
651
+ /** `P`, 32 bytes, from the swap's `secrets`. */
652
+ preimage: Uint8Array;
653
+ }): Promise<{
654
+ ciphertext: string;
655
+ }>;
656
+
657
+ export { type AddressParams, ArkadeCorridorDeps, AssetAliasTable, AssetId, type ChainSourceBackend, Corridor, CorridorFactory, type CorridorRecordStore, CorridorSet, CorridorSwapRecord, type CovclaimdClient, type CovclaimdInfo, CovclaimdRevealError, DEFAULT_INVOICE_EXPIRY_SECONDS, DiscoveryIndex, DiscoveryLeg, DiscoverySnapshot, INVOICE_HRPS, Instrument, type L1Tip, LIGHTNING_DRIVE, LightningCorridorDeps, MarketCandidate, NetworkRef, ONCHAIN_DRIVE, OfferSwapRecord, OnchainCorridorDeps, PinnedAmount, Pubkey, QuoteId, QuoteInput, Rail, type RecordSink, type ResolveDeps, ResolvedEndpoint, type ResolvedRoute, type RevealParams, Route, RouteResolution, SwapPolicy, SwapRecord, aliasTableFrom, applyOfferSpend, arkadeCorridor, assembleRoute, chainSourceOver, corridorRecordStore, covclaimdClient, decodeBolt11, esploraChainSource, esploraTip, lightningCorridor, networksOfInvoiceHrp, offerFactsOf, offerRecordSource, onchainCorridor, publicAssetId, resolveRoute, revealClaimPacket, revealFieldsFromScript, rfqRecordOf, satsOf, scopedToRail, splitRecords, verifyPair, verifyQuoteTtl, verifyQuotedAmount, verifyReceiveInvoiceFacts, verifyReceiveWindow, verifyResponder, verifySendInvoice, verifySendWindow, verifyingDerivation, walletLockupIndexer, withOfferStatus, withRfqState };
package/dist/advanced.js CHANGED
@@ -133,7 +133,7 @@ import {
133
133
  withCanonicalAmount,
134
134
  withOfferStatus,
135
135
  withRfqState
136
- } from "./chunk-H5KFNL5O.js";
136
+ } from "./chunk-2QQYOW46.js";
137
137
  import {
138
138
  ACTIVITY_TOKEN,
139
139
  CORRIDOR_PASS,
@@ -148,10 +148,133 @@ import {
148
148
  onchainCorridor,
149
149
  readsChain,
150
150
  recordOutcome
151
- } from "./chunk-OROIHWXD.js";
151
+ } from "./chunk-4L2CNVXB.js";
152
152
  import {
153
- SwapRefusal
154
- } from "./chunk-LYCMM3VB.js";
153
+ SwapRefusal,
154
+ sealClaimPacket
155
+ } from "./chunk-6HIU2LNP.js";
156
+
157
+ // src/reveal.ts
158
+ import { base64, hex } from "@scure/base";
159
+ import { ripemd160 } from "@noble/hashes/legacy.js";
160
+ import { sha256 } from "@noble/hashes/sha2.js";
161
+ import { ArkAddress } from "@arkade-os/sdk";
162
+ var CovclaimdRevealError = class extends Error {
163
+ name = "CovclaimdRevealError";
164
+ status;
165
+ detail;
166
+ retryable;
167
+ constructor(what, status, detail) {
168
+ super(`covclaimd ${what} failed: ${status || "no response"} ${detail}`.trimEnd());
169
+ this.status = status;
170
+ this.detail = detail;
171
+ this.retryable = status === 0 || status === 429 || status >= 500;
172
+ }
173
+ };
174
+ var decodeKey = (value, field) => {
175
+ if (typeof value !== "string") throw new Error(`covclaimd info: ${field} is not a string`);
176
+ let bytes;
177
+ try {
178
+ bytes = hex.decode(value);
179
+ } catch {
180
+ throw new Error(`covclaimd info: ${field} is not hex`);
181
+ }
182
+ if (bytes.length !== 33) {
183
+ throw new Error(`covclaimd info: ${field} must be 33-byte compressed, got ${bytes.length}`);
184
+ }
185
+ return bytes;
186
+ };
187
+ var LOOPBACK = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]"]);
188
+ var assertTransportSecure = (baseUrl, allowInsecureHttp) => {
189
+ const { protocol, hostname } = new URL(baseUrl);
190
+ if (protocol === "https:" || allowInsecureHttp) return;
191
+ if (protocol === "http:" && LOOPBACK.has(hostname)) return;
192
+ throw new Error(
193
+ `covclaimd URL must be https (got ${protocol}//${hostname}): the key it serves is the one the preimage gets sealed to. Pass allowInsecureHttp to override.`
194
+ );
195
+ };
196
+ var covclaimdClient = (baseUrl, options = {}) => {
197
+ assertTransportSecure(baseUrl, options.allowInsecureHttp === true);
198
+ const url = baseUrl.replace(/\/+$/, "");
199
+ const fetchImpl = options.fetchImpl ?? fetch;
200
+ const timeoutMs = options.timeoutMs ?? 3e4;
201
+ const send = async (what, path, init) => {
202
+ let response;
203
+ try {
204
+ response = await fetchImpl(`${url}${path}`, {
205
+ ...init,
206
+ // a redirect would move the key fetch off the vetted origin
207
+ redirect: "error",
208
+ signal: AbortSignal.timeout(timeoutMs)
209
+ });
210
+ } catch (error) {
211
+ throw new CovclaimdRevealError(what, 0, String(error));
212
+ }
213
+ if (!response.ok) {
214
+ throw new CovclaimdRevealError(what, response.status, await response.text());
215
+ }
216
+ return response;
217
+ };
218
+ const readJson = async (what, response) => {
219
+ const body = await response.text();
220
+ try {
221
+ return JSON.parse(body);
222
+ } catch {
223
+ throw new CovclaimdRevealError(
224
+ what,
225
+ response.status,
226
+ `non-JSON body: ${body.slice(0, 200)}`
227
+ );
228
+ }
229
+ };
230
+ return {
231
+ async info() {
232
+ const response = await send("info", "/v1/preimage/covclaimd-pubkey", {
233
+ method: "GET"
234
+ });
235
+ const body = await readJson("info", response);
236
+ return {
237
+ covclaimdPubkey: decodeKey(body?.covclaimd_pub_key, "covclaimd_pub_key"),
238
+ emulatorPubkey: hex.encode(decodeKey(body?.emulator_pub_key, "emulator_pub_key"))
239
+ };
240
+ },
241
+ async reveal(params) {
242
+ await send("reveal", "/v1/reveal", {
243
+ method: "POST",
244
+ headers: { "content-type": "application/json" },
245
+ body: JSON.stringify({
246
+ swap_address: params.swapAddress,
247
+ packet: { ciphertext: params.ciphertext, arkade_script: params.arkadeScript },
248
+ taptree: params.taptree
249
+ })
250
+ });
251
+ }
252
+ };
253
+ };
254
+ function revealFieldsFromScript(script) {
255
+ if (!script.nonInteractiveClaimArkadeScript) {
256
+ throw new Error("this covenant has no non-interactive claim leaf to reveal against");
257
+ }
258
+ return {
259
+ arkadeScript: base64.encode(script.nonInteractiveClaimArkadeScript),
260
+ taptree: hex.encode(script.encode())
261
+ };
262
+ }
263
+ async function revealClaimPacket(client, input) {
264
+ const fields = revealFieldsFromScript(input.script);
265
+ if (hex.encode(ArkAddress.decode(input.address).pkScript) !== hex.encode(input.script.pkScript)) {
266
+ throw new Error("address does not belong to this covenant");
267
+ }
268
+ if (hex.encode(ripemd160(sha256(input.preimage))) !== hex.encode(input.script.options.preimageHash)) {
269
+ throw new Error("preimage does not match the covenant's payment hash");
270
+ }
271
+ const { ciphertext } = await sealClaimPacket({
272
+ preimage: input.preimage,
273
+ covclaimdPubkey: (await client.info()).covclaimdPubkey
274
+ });
275
+ await client.reveal({ swapAddress: input.address, ciphertext, ...fields });
276
+ return { ciphertext };
277
+ }
155
278
  export {
156
279
  ACTIVITY_TOKEN,
157
280
  ARKADE_ASSET_NAMESPACE,
@@ -168,6 +291,7 @@ export {
168
291
  CORRIDOR_FACTORIES,
169
292
  CORRIDOR_PASS,
170
293
  ClientDisposed,
294
+ CovclaimdRevealError,
171
295
  DEFAULT_INVOICE_EXPIRY_SECONDS,
172
296
  DiscoverySnapshotUnavailable,
173
297
  FEED_TTL_MS,
@@ -215,6 +339,7 @@ export {
215
339
  corridorOutcome,
216
340
  corridorRecordStore,
217
341
  corridorSet,
342
+ covclaimdClient,
218
343
  createSwapClient,
219
344
  createSwapDrive,
220
345
  decodeBolt11,
@@ -274,6 +399,8 @@ export {
274
399
  resolveCorridorBase,
275
400
  resolveCorridorDeps,
276
401
  resolveRoute,
402
+ revealClaimPacket,
403
+ revealFieldsFromScript,
277
404
  rfqLeg,
278
405
  rfqPairFor,
279
406
  rfqRecordOf,