@arkade-os/swap 0.0.16 → 0.0.18

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 CHANGED
@@ -537,9 +537,9 @@ runs before signing — `P` reaches the Ark server at submit — and is skipped
537
537
  have already partially claimed (`partiallyClaimed`), where `P` is public anyway. The push itself is
538
538
  core's `signAndSubmitOffchainTx` plus `claimWithPreimageIdentity`, with `verifyServerSignatures`
539
539
  on: the server's countersignature is checked per input, against the leaf the local build spends,
540
- before finalizing. Until covclaimd's
541
- reference vectors are cross-checked, the `sealClaimPacket` test vector is pinned from this
542
- implementation and marked provisional (`TODO(claim-packet-vectors)`).
540
+ before finalizing. The `sealClaimPacket` vector is cross-checked against
541
+ covclaimd's own `preimage.Decrypt`, and the TLV framing against its `DeserializeClaim`, so both
542
+ are pinned by the reference implementation rather than by this one.
543
543
 
544
544
  `RfqSwapManager` drives the lightning-receive leg too, as `kind: "lightning_receive"` records
545
545
  carrying `expectedAmount` and wired to a `claimLockup` callback (`pushClaim`, with `expectedAmount`
@@ -222,6 +222,7 @@ async function classifyOnchainHtlc(chain, input) {
222
222
 
223
223
  // src/claimPacket.ts
224
224
  import { base64 } from "@scure/base";
225
+ import { concatBytes } from "@scure/btc-signer/utils.js";
225
226
  import { gcm } from "@noble/ciphers/aes.js";
226
227
  import { secp256k1 } from "@noble/curves/secp256k1.js";
227
228
  import { hkdf } from "@noble/hashes/hkdf.js";
@@ -244,12 +245,74 @@ async function sealWithEntropy(input, ephemeralKey, nonce) {
244
245
  const key = hkdf(sha2562, sharedX, ephemeralPub, HKDF_INFO, 32);
245
246
  if (nonce.length !== 12) throw new Error("nonce must be 12 bytes");
246
247
  const sealed = gcm(key, nonce, ephemeralPub).encrypt(input.preimage);
247
- const packet = new Uint8Array(33 + 12 + sealed.length);
248
- packet.set(ephemeralPub, 0);
249
- packet.set(nonce, 33);
250
- packet.set(sealed, 45);
251
- return { ciphertext: base64.encode(packet) };
248
+ const ciphertext = new Uint8Array(33 + 12 + sealed.length);
249
+ ciphertext.set(ephemeralPub, 0);
250
+ ciphertext.set(nonce, 33);
251
+ ciphertext.set(sealed, 45);
252
+ return {
253
+ ciphertext: base64.encode(ciphertext),
254
+ packet: base64.encode(
255
+ concatBytes(
256
+ tlv(TLV_CIPHERTEXT, ciphertext),
257
+ tlv(TLV_COVCLAIMD_PUBKEY, input.covclaimdPubkey)
258
+ )
259
+ )
260
+ };
252
261
  }
262
+ var TLV_CIPHERTEXT = 1;
263
+ var TLV_ARKADE_SCRIPT = 2;
264
+ var TLV_COVCLAIMD_PUBKEY = 3;
265
+ var COMPRESSED_PUBKEY_LENGTH = 33;
266
+ var SEALED_CIPHERTEXT_LENGTH = 93;
267
+ var CLAIM_PACKET_TYPE = 4;
268
+ var tlv = (type, value) => Uint8Array.from([type, value.length >> 8 & 255, value.length & 255, ...value]);
269
+ var appendArkadeScript = (body, arkadeScript) => Uint8Array.from([...body, ...tlv(TLV_ARKADE_SCRIPT, arkadeScript)]);
270
+ var parseTlv = (data) => {
271
+ let ciphertextLength;
272
+ let hasArkadeScript = false;
273
+ let pubkey;
274
+ let offset = 0;
275
+ while (offset < data.length) {
276
+ if (offset + 3 > data.length) throw new Error("truncated TLV header");
277
+ const type = data[offset];
278
+ const length = data[offset + 1] << 8 | data[offset + 2];
279
+ offset += 3;
280
+ if (offset + length > data.length) {
281
+ throw new Error(`TLV type 0x${type.toString(16)} overruns the buffer`);
282
+ }
283
+ const value = data.subarray(offset, offset + length);
284
+ offset += length;
285
+ if (type === TLV_CIPHERTEXT) ciphertextLength = value.length;
286
+ else if (type === TLV_ARKADE_SCRIPT) hasArkadeScript = true;
287
+ else if (type === TLV_COVCLAIMD_PUBKEY) {
288
+ if (value.length !== COMPRESSED_PUBKEY_LENGTH) {
289
+ throw new Error(
290
+ `covclaimd_pub_key TLV is ${value.length} bytes, want ${COMPRESSED_PUBKEY_LENGTH}`
291
+ );
292
+ }
293
+ pubkey = value;
294
+ }
295
+ }
296
+ return { ciphertextLength, hasArkadeScript, pubkey };
297
+ };
298
+ var claimPacketShape = (b64) => {
299
+ try {
300
+ const raw = base64.decode(b64);
301
+ if (raw.length === SEALED_CIPHERTEXT_LENGTH) return { kind: "ciphertext" };
302
+ const { ciphertextLength, hasArkadeScript, pubkey } = parseTlv(raw);
303
+ if (ciphertextLength !== SEALED_CIPHERTEXT_LENGTH || pubkey === void 0) {
304
+ return { kind: "ciphertext" };
305
+ }
306
+ return {
307
+ kind: "packet",
308
+ body: raw,
309
+ needsArkadeScript: !hasArkadeScript,
310
+ ...pubkey ? { covclaimdPubkey: pubkey } : {}
311
+ };
312
+ } catch {
313
+ return { kind: "ciphertext" };
314
+ }
315
+ };
253
316
 
254
317
  // src/lockupContract.ts
255
318
  import { hex as hex2 } from "@scure/base";
@@ -756,7 +819,7 @@ function lightningSendVtxoScript(params) {
756
819
  unilateralClaimDelay: seconds(params.claimDelay),
757
820
  unilateralRefundDelay: seconds(unilateralRefundDelay(params.claimDelay)),
758
821
  unilateralRefundWithoutReceiverDelay: seconds(
759
- unilateralRefundWithoutReceiverDelay(params.claimDelay)
822
+ params.refundWithoutReceiverDelay ?? unilateralRefundWithoutReceiverDelay(params.claimDelay)
760
823
  ),
761
824
  nonInteractiveParameters: {
762
825
  receiverPkScript: params.receiverPkScript,
@@ -778,6 +841,18 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
778
841
  if (quote.refund_locktime === void 0) {
779
842
  throw new Error("lightning-send quote is missing refund_locktime");
780
843
  }
844
+ const now = Math.floor(Date.now() / 1e3);
845
+ const claimDelay = unilateralClaimDelay(Number(info.unilateralExitDelay));
846
+ const refundWithoutReceiverDelay = quote.profile?.refund_without_receiver_delay;
847
+ if (refundWithoutReceiverDelay === void 0) {
848
+ throw new Error("lightning-send quote is missing profile.refund_without_receiver_delay");
849
+ }
850
+ if (!Number.isSafeInteger(refundWithoutReceiverDelay) || refundWithoutReceiverDelay < claimDelay || refundWithoutReceiverDelay % SEQUENCE_GRANULARITY_SECONDS !== 0 || refundWithoutReceiverDelay > 65535 * SEQUENCE_GRANULARITY_SECONDS) {
851
+ throw new Error("lightning-send quote carries an invalid refund_without_receiver_delay");
852
+ }
853
+ if (refundWithoutReceiverDelay < quote.refund_locktime - now) {
854
+ throw new Error("lightning-send quote lets the solo refund open before refund_locktime");
855
+ }
781
856
  const receiverPkScriptHex = quote.profile?.receiver_pk_script;
782
857
  if (receiverPkScriptHex === void 0) {
783
858
  throw new Error("lightning-send quote is missing profile.receiver_pk_script");
@@ -799,7 +874,8 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
799
874
  refundLocktime: quote.refund_locktime,
800
875
  serverPubkey,
801
876
  paymentHash: params.invoice.paymentHash,
802
- claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
877
+ claimDelay,
878
+ refundWithoutReceiverDelay,
803
879
  emulatorPubkey: toXOnly(
804
880
  hex3.decode(resolveEmulatorPubkey(network, params.emulatorPubkey)),
805
881
  "emulator signer key"
@@ -823,7 +899,7 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
823
899
  assertFundable({
824
900
  quote,
825
901
  invoiceExpiresAt: params.invoice.expiresAt,
826
- now: Math.floor(Date.now() / 1e3)
902
+ now
827
903
  });
828
904
  await registerLockupContract(await wallet.getContractManager(), script, address);
829
905
  return {
@@ -1166,7 +1242,7 @@ async function requestLightningReceive(wallet, arkServerUrl, transport, params)
1166
1242
  paymentHash,
1167
1243
  payoutAddress,
1168
1244
  payoutPubkey,
1169
- claimPacket: claimPacket?.ciphertext,
1245
+ claimPacket: claimPacket?.packet,
1170
1246
  amount: params.amount,
1171
1247
  amountSide: params.amountSide
1172
1248
  })
@@ -1290,7 +1366,7 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
1290
1366
  payoutAddress,
1291
1367
  payoutPubkey,
1292
1368
  refundPubkey: params.refundPubkey,
1293
- claimPacket: claimPacket?.ciphertext,
1369
+ claimPacket: claimPacket?.packet,
1294
1370
  amount: params.amount,
1295
1371
  amountSide: params.amountSide
1296
1372
  })
@@ -1360,6 +1436,10 @@ export {
1360
1436
  claimOnchainFill,
1361
1437
  classifyOnchainHtlc,
1362
1438
  sealClaimPacket,
1439
+ SEALED_CIPHERTEXT_LENGTH,
1440
+ CLAIM_PACKET_TYPE,
1441
+ appendArkadeScript,
1442
+ claimPacketShape,
1363
1443
  SWAP_LOCKUP_CONTRACT_TYPE,
1364
1444
  SWAP_LOCKUP_CONTRACT_LABEL,
1365
1445
  SWAP_LOCKUP_CONTRACT_KIND,
package/dist/index.cjs CHANGED
@@ -35,6 +35,7 @@ __export(index_exports, {
35
35
  ASSET_CARRIER_SATS: () => ASSET_CARRIER_SATS,
36
36
  AddressMismatch: () => AddressMismatch,
37
37
  BTC_ASSET_ID: () => BTC_ASSET_ID,
38
+ CLAIM_PACKET_TYPE: () => CLAIM_PACKET_TYPE,
38
39
  CROSS_ASSET_RAIL: () => CROSS_ASSET_RAIL,
39
40
  CovclaimdRevealError: () => CovclaimdRevealError,
40
41
  InMemoryAssetSwapRepository: () => InMemoryAssetSwapRepository,
@@ -70,6 +71,7 @@ __export(index_exports, {
70
71
  RefundNotLocallyPossibleError: () => RefundNotLocallyPossibleError,
71
72
  RfqSwapManager: () => RfqSwapManager,
72
73
  RfqSwapOriginRequired: () => RfqSwapOriginRequired,
74
+ SEALED_CIPHERTEXT_LENGTH: () => SEALED_CIPHERTEXT_LENGTH,
73
75
  SOLO_REFUND_HEADROOM_SECONDS: () => SOLO_REFUND_HEADROOM_SECONDS,
74
76
  SOLVER_LIGHTNING_RAIL: () => SOLVER_LIGHTNING_RAIL,
75
77
  SOLVER_ONCHAIN_RAIL: () => SOLVER_ONCHAIN_RAIL,
@@ -78,6 +80,7 @@ __export(index_exports, {
78
80
  SWAP_LOCKUP_CONTRACT_TYPE: () => SWAP_LOCKUP_CONTRACT_TYPE,
79
81
  SwapRefusal: () => SwapRefusal,
80
82
  addAssetSwap: () => addAssetSwap,
83
+ appendArkadeScript: () => appendArkadeScript,
81
84
  arkadeAssetLeg: () => arkadeAssetLeg,
82
85
  arkadeRefunder: () => arkadeRefunder,
83
86
  arkadeSwapRequest: () => arkadeSwapRequest,
@@ -91,6 +94,7 @@ __export(index_exports, {
91
94
  cancelOffer: () => cancelOffer,
92
95
  chainSourceFrom: () => chainSourceFrom,
93
96
  claimOnchainFill: () => claimOnchainFill,
97
+ claimPacketShape: () => claimPacketShape,
94
98
  claimReceiveLockup: () => claimReceiveLockup,
95
99
  classifyDepositSpend: () => classifyDepositSpend,
96
100
  classifyOnchainHtlc: () => classifyOnchainHtlc,
@@ -1090,11 +1094,11 @@ var findMarket = (markets, fromId, toId) => {
1090
1094
  for (const market of markets) {
1091
1095
  for (const side of ["base", "quote"]) {
1092
1096
  const asset3 = side === "base" ? market.base_asset : market.quote_asset;
1093
- if (asset3.id === id) return id;
1097
+ if (asset3.id === id) return (0, import_solver_discovery.marketLegKey)(market, side);
1094
1098
  const canonical = marketAssetId(market, side) ?? "";
1095
1099
  const matchesBtc = id === BTC_ASSET_ID && /^arkade:[^/]+\/slip44:(?:0|1)$/.test(canonical);
1096
1100
  const matchesAsset = /^[0-9a-f]{68}$/.test(id) && canonical.endsWith(`/asset:${id}`);
1097
- if ((matchesBtc || matchesAsset) && typeof asset3.id === "string") return asset3.id;
1101
+ if (matchesBtc || matchesAsset) return (0, import_solver_discovery.marketLegKey)(market, side);
1098
1102
  }
1099
1103
  }
1100
1104
  return id;
@@ -2260,6 +2264,7 @@ var import_sdk11 = require("@arkade-os/sdk");
2260
2264
 
2261
2265
  // src/claimPacket.ts
2262
2266
  var import_base8 = require("@scure/base");
2267
+ var import_utils2 = require("@scure/btc-signer/utils.js");
2263
2268
  var import_aes = require("@noble/ciphers/aes.js");
2264
2269
  var import_secp256k1 = require("@noble/curves/secp256k1.js");
2265
2270
  var import_hkdf = require("@noble/hashes/hkdf.js");
@@ -2282,12 +2287,74 @@ async function sealWithEntropy(input, ephemeralKey, nonce) {
2282
2287
  const key = (0, import_hkdf.hkdf)(import_sha23.sha256, sharedX, ephemeralPub, HKDF_INFO, 32);
2283
2288
  if (nonce.length !== 12) throw new Error("nonce must be 12 bytes");
2284
2289
  const sealed = (0, import_aes.gcm)(key, nonce, ephemeralPub).encrypt(input.preimage);
2285
- const packet = new Uint8Array(33 + 12 + sealed.length);
2286
- packet.set(ephemeralPub, 0);
2287
- packet.set(nonce, 33);
2288
- packet.set(sealed, 45);
2289
- return { ciphertext: import_base8.base64.encode(packet) };
2290
+ const ciphertext = new Uint8Array(33 + 12 + sealed.length);
2291
+ ciphertext.set(ephemeralPub, 0);
2292
+ ciphertext.set(nonce, 33);
2293
+ ciphertext.set(sealed, 45);
2294
+ return {
2295
+ ciphertext: import_base8.base64.encode(ciphertext),
2296
+ packet: import_base8.base64.encode(
2297
+ (0, import_utils2.concatBytes)(
2298
+ tlv2(TLV_CIPHERTEXT, ciphertext),
2299
+ tlv2(TLV_COVCLAIMD_PUBKEY, input.covclaimdPubkey)
2300
+ )
2301
+ )
2302
+ };
2290
2303
  }
2304
+ var TLV_CIPHERTEXT = 1;
2305
+ var TLV_ARKADE_SCRIPT = 2;
2306
+ var TLV_COVCLAIMD_PUBKEY = 3;
2307
+ var COMPRESSED_PUBKEY_LENGTH = 33;
2308
+ var SEALED_CIPHERTEXT_LENGTH = 93;
2309
+ var CLAIM_PACKET_TYPE = 4;
2310
+ var tlv2 = (type, value) => Uint8Array.from([type, value.length >> 8 & 255, value.length & 255, ...value]);
2311
+ var appendArkadeScript = (body, arkadeScript) => Uint8Array.from([...body, ...tlv2(TLV_ARKADE_SCRIPT, arkadeScript)]);
2312
+ var parseTlv = (data) => {
2313
+ let ciphertextLength;
2314
+ let hasArkadeScript = false;
2315
+ let pubkey;
2316
+ let offset = 0;
2317
+ while (offset < data.length) {
2318
+ if (offset + 3 > data.length) throw new Error("truncated TLV header");
2319
+ const type = data[offset];
2320
+ const length = data[offset + 1] << 8 | data[offset + 2];
2321
+ offset += 3;
2322
+ if (offset + length > data.length) {
2323
+ throw new Error(`TLV type 0x${type.toString(16)} overruns the buffer`);
2324
+ }
2325
+ const value = data.subarray(offset, offset + length);
2326
+ offset += length;
2327
+ if (type === TLV_CIPHERTEXT) ciphertextLength = value.length;
2328
+ else if (type === TLV_ARKADE_SCRIPT) hasArkadeScript = true;
2329
+ else if (type === TLV_COVCLAIMD_PUBKEY) {
2330
+ if (value.length !== COMPRESSED_PUBKEY_LENGTH) {
2331
+ throw new Error(
2332
+ `covclaimd_pub_key TLV is ${value.length} bytes, want ${COMPRESSED_PUBKEY_LENGTH}`
2333
+ );
2334
+ }
2335
+ pubkey = value;
2336
+ }
2337
+ }
2338
+ return { ciphertextLength, hasArkadeScript, pubkey };
2339
+ };
2340
+ var claimPacketShape = (b64) => {
2341
+ try {
2342
+ const raw = import_base8.base64.decode(b64);
2343
+ if (raw.length === SEALED_CIPHERTEXT_LENGTH) return { kind: "ciphertext" };
2344
+ const { ciphertextLength, hasArkadeScript, pubkey } = parseTlv(raw);
2345
+ if (ciphertextLength !== SEALED_CIPHERTEXT_LENGTH || pubkey === void 0) {
2346
+ return { kind: "ciphertext" };
2347
+ }
2348
+ return {
2349
+ kind: "packet",
2350
+ body: raw,
2351
+ needsArkadeScript: !hasArkadeScript,
2352
+ ...pubkey ? { covclaimdPubkey: pubkey } : {}
2353
+ };
2354
+ } catch {
2355
+ return { kind: "ciphertext" };
2356
+ }
2357
+ };
2291
2358
 
2292
2359
  // src/lockupContract.ts
2293
2360
  var import_base9 = require("@scure/base");
@@ -2777,7 +2844,7 @@ function lightningSendVtxoScript(params) {
2777
2844
  unilateralClaimDelay: seconds(params.claimDelay),
2778
2845
  unilateralRefundDelay: seconds(unilateralRefundDelay(params.claimDelay)),
2779
2846
  unilateralRefundWithoutReceiverDelay: seconds(
2780
- unilateralRefundWithoutReceiverDelay(params.claimDelay)
2847
+ params.refundWithoutReceiverDelay ?? unilateralRefundWithoutReceiverDelay(params.claimDelay)
2781
2848
  ),
2782
2849
  nonInteractiveParameters: {
2783
2850
  receiverPkScript: params.receiverPkScript,
@@ -2799,6 +2866,18 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
2799
2866
  if (quote.refund_locktime === void 0) {
2800
2867
  throw new Error("lightning-send quote is missing refund_locktime");
2801
2868
  }
2869
+ const now = Math.floor(Date.now() / 1e3);
2870
+ const claimDelay = unilateralClaimDelay(Number(info.unilateralExitDelay));
2871
+ const refundWithoutReceiverDelay = quote.profile?.refund_without_receiver_delay;
2872
+ if (refundWithoutReceiverDelay === void 0) {
2873
+ throw new Error("lightning-send quote is missing profile.refund_without_receiver_delay");
2874
+ }
2875
+ if (!Number.isSafeInteger(refundWithoutReceiverDelay) || refundWithoutReceiverDelay < claimDelay || refundWithoutReceiverDelay % SEQUENCE_GRANULARITY_SECONDS !== 0 || refundWithoutReceiverDelay > 65535 * SEQUENCE_GRANULARITY_SECONDS) {
2876
+ throw new Error("lightning-send quote carries an invalid refund_without_receiver_delay");
2877
+ }
2878
+ if (refundWithoutReceiverDelay < quote.refund_locktime - now) {
2879
+ throw new Error("lightning-send quote lets the solo refund open before refund_locktime");
2880
+ }
2802
2881
  const receiverPkScriptHex = quote.profile?.receiver_pk_script;
2803
2882
  if (receiverPkScriptHex === void 0) {
2804
2883
  throw new Error("lightning-send quote is missing profile.receiver_pk_script");
@@ -2820,7 +2899,8 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
2820
2899
  refundLocktime: quote.refund_locktime,
2821
2900
  serverPubkey,
2822
2901
  paymentHash: params.invoice.paymentHash,
2823
- claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
2902
+ claimDelay,
2903
+ refundWithoutReceiverDelay,
2824
2904
  emulatorPubkey: (0, import_sdk10.toXOnly)(
2825
2905
  import_base10.hex.decode((0, import_sdk10.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
2826
2906
  "emulator signer key"
@@ -2844,7 +2924,7 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
2844
2924
  assertFundable({
2845
2925
  quote,
2846
2926
  invoiceExpiresAt: params.invoice.expiresAt,
2847
- now: Math.floor(Date.now() / 1e3)
2927
+ now
2848
2928
  });
2849
2929
  await registerLockupContract(await wallet.getContractManager(), script, address);
2850
2930
  return {
@@ -3187,7 +3267,7 @@ async function requestLightningReceive(wallet, arkServerUrl, transport, params)
3187
3267
  paymentHash,
3188
3268
  payoutAddress,
3189
3269
  payoutPubkey,
3190
- claimPacket: claimPacket?.ciphertext,
3270
+ claimPacket: claimPacket?.packet,
3191
3271
  amount: params.amount,
3192
3272
  amountSide: params.amountSide
3193
3273
  })
@@ -3311,7 +3391,7 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
3311
3391
  payoutAddress,
3312
3392
  payoutPubkey,
3313
3393
  refundPubkey: params.refundPubkey,
3314
- claimPacket: claimPacket?.ciphertext,
3394
+ claimPacket: claimPacket?.packet,
3315
3395
  amount: params.amount,
3316
3396
  amountSide: params.amountSide
3317
3397
  })
@@ -3429,12 +3509,11 @@ var solverRendezvous = (markets, payoutCorridor, amountSats, fallbackEmulatorPub
3429
3509
  const encoded = fallbackEmulatorPubkey ? import_base12.hex.encode(fallbackEmulatorPubkey) : void 0;
3430
3510
  if (encoded !== void 0 && !XONLY_HEX.test(encoded)) return void 0;
3431
3511
  const pinned = encoded;
3432
- const candidates = (0, import_solver_discovery2.selectMarkets)(markets, {
3433
- baseId: BTC_ASSET_ID,
3434
- quoteId: BTC_ASSET_ID,
3435
- baseCorridor: "arkade",
3436
- quoteCorridor: payoutCorridor
3437
- });
3512
+ const quoteCorridor = payoutCorridor === "lightning" ? "bolt11" : "bitcoin";
3513
+ const isBtc = (id) => id === "btc" || /^\w+:[^/]+\/slip44:(?:0|1)$/.test(id ?? "");
3514
+ const candidates = markets.filter(
3515
+ (market) => marketCorridor(market, "base") === "arkade" && marketCorridor(market, "quote") === quoteCorridor && isBtc(marketAssetId(market, "base")) && isBtc(marketAssetId(market, "quote"))
3516
+ );
3438
3517
  for (const market of candidates) {
3439
3518
  const rendezvous = rendezvousOf(market, pinned);
3440
3519
  if (!rendezvous) continue;
@@ -5437,6 +5516,7 @@ async function lockupTxids(indexer, record, wantFunding) {
5437
5516
  ASSET_CARRIER_SATS,
5438
5517
  AddressMismatch,
5439
5518
  BTC_ASSET_ID,
5519
+ CLAIM_PACKET_TYPE,
5440
5520
  CROSS_ASSET_RAIL,
5441
5521
  CovclaimdRevealError,
5442
5522
  InMemoryAssetSwapRepository,
@@ -5472,6 +5552,7 @@ async function lockupTxids(indexer, record, wantFunding) {
5472
5552
  RefundNotLocallyPossibleError,
5473
5553
  RfqSwapManager,
5474
5554
  RfqSwapOriginRequired,
5555
+ SEALED_CIPHERTEXT_LENGTH,
5475
5556
  SOLO_REFUND_HEADROOM_SECONDS,
5476
5557
  SOLVER_LIGHTNING_RAIL,
5477
5558
  SOLVER_ONCHAIN_RAIL,
@@ -5480,6 +5561,7 @@ async function lockupTxids(indexer, record, wantFunding) {
5480
5561
  SWAP_LOCKUP_CONTRACT_TYPE,
5481
5562
  SwapRefusal,
5482
5563
  addAssetSwap,
5564
+ appendArkadeScript,
5483
5565
  arkadeAssetLeg,
5484
5566
  arkadeRefunder,
5485
5567
  arkadeSwapRequest,
@@ -5493,6 +5575,7 @@ async function lockupTxids(indexer, record, wantFunding) {
5493
5575
  cancelOffer,
5494
5576
  chainSourceFrom,
5495
5577
  claimOnchainFill,
5578
+ claimPacketShape,
5496
5579
  claimReceiveLockup,
5497
5580
  classifyDepositSpend,
5498
5581
  classifyOnchainHtlc,
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-rwU1Sv2-.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-rwU1Sv2-.cjs';
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-BwasQwkR.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-BwasQwkR.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-DirJn_4k.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 assertFundable, Q as assertReceivable, T as awaitOnchainFill, U as buildHtlcClaim, V as buildHtlcRefund, W as claimOnchainFill, X as classifyOnchainHtlc, Y as deriveLightningReceive, Z as deriveOnchainReceive, _ as deriveOnchainSend, $ as extractPreimage, a0 as httpTransport, a1 as isRfqRefusalErrorCode, a2 as l1ScriptForAddress, a3 as lightningReceiveRequest, a4 as lightningSendRequest, a5 as lightningSendVtxoScript, a6 as newPreimage, a7 as newRfqId, a8 as offerTermsFromQuote, a9 as onchainHtlcScript, aa as onchainReceiveRequest, ab as onchainSendRequest, ac as paymentHashOf, ad as receiveVtxoScript, ae as relayTransport, af as requestLightningReceive, ag as requestOnchainReceive, ah as rfqPair, ai as unilateralClaimDelay, aj as unilateralRefundDelay, ak as unilateralRefundWithoutReceiverDelay, al as verifyLockupAddress, am as verifyReceiveInvoice } from './rfq-DirJn_4k.cjs';
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-B_2hM0xk.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 assertFundable, Q as assertReceivable, T as awaitOnchainFill, U as buildHtlcClaim, V as buildHtlcRefund, W as claimOnchainFill, X as classifyOnchainHtlc, Y as deriveLightningReceive, Z as deriveOnchainReceive, _ as deriveOnchainSend, $ as extractPreimage, a0 as httpTransport, a1 as isRfqRefusalErrorCode, a2 as l1ScriptForAddress, a3 as lightningReceiveRequest, a4 as lightningSendRequest, a5 as lightningSendVtxoScript, a6 as newPreimage, a7 as newRfqId, a8 as offerTermsFromQuote, a9 as onchainHtlcScript, aa as onchainReceiveRequest, ab as onchainSendRequest, ac as paymentHashOf, ad as receiveVtxoScript, ae as relayTransport, af as requestLightningReceive, ag as requestOnchainReceive, ah as rfqPair, ai as unilateralClaimDelay, aj as unilateralRefundDelay, ak as unilateralRefundWithoutReceiverDelay, al as verifyLockupAddress, am as verifyReceiveInvoice } from './rfq-B_2hM0xk.cjs';
7
7
 
8
8
  /**
9
9
  * Which wallet key signs this leg. Stored at `profile.signer`.
@@ -1014,10 +1014,28 @@ interface CrossAssetRailDeps {
1014
1014
  declare function crossAssetRail(deps: CrossAssetRailDeps): PaymentRail;
1015
1015
 
1016
1016
  interface SealedClaimPacket {
1017
- /** `ephPub(33) ‖ nonce(12) ‖ ciphertext`, base64 — wire-ready. This is
1018
- * the whole packet: the RFQ request's `claim_packet` field carries
1019
- * exactly this string. */
1017
+ /** `ephPub(33) ‖ nonce(12) ‖ ciphertext`, base64 — the bare sealed bytes,
1018
+ * 93 decoded. The older of the two `claim_packet` shapes: a solver holding
1019
+ * it can only hand it to covclaimd over the Reveal API, which needs both
1020
+ * sides pointed at the SAME covclaimd — an agreement nothing on the wire
1021
+ * expresses. Prefer {@link SealedClaimPacket.packet}. */
1020
1022
  ciphertext: string;
1023
+ /**
1024
+ * covclaimd's serialised `ClaimPacket` body, base64 — TLV `0x01` ciphertext
1025
+ * and `0x03` covclaimd_pub_key. **This is what `claim_packet` should
1026
+ * carry** (§ 7.1.2: senders SHOULD prefer the packet shape).
1027
+ *
1028
+ * It is what lets the solver stamp the funding transaction as Arkade
1029
+ * extension packet `0x04`, which covclaimd finds on the arkd stream by
1030
+ * itself. The `0x03` TLV is what its filter selects on, so the client alone
1031
+ * chooses which covclaimd — the solver needs none configured or reachable.
1032
+ *
1033
+ * `0x02` arkade_script is deliberately absent: the covenant commits to
1034
+ * `taggedHash("ArkScriptHash", script)`, so the funder holds the only copy
1035
+ * guaranteed to match and appends it. A client deriving its own would add a
1036
+ * way for the two to disagree and strand the claim.
1037
+ */
1038
+ packet: string;
1021
1039
  }
1022
1040
  interface ClaimPacketInput {
1023
1041
  preimage: Uint8Array;
@@ -1035,6 +1053,38 @@ interface ClaimPacketInput {
1035
1053
  * helper, where no consumer reaches it by accident.
1036
1054
  */
1037
1055
  declare function sealClaimPacket(input: ClaimPacketInput): Promise<SealedClaimPacket>;
1056
+ /** `ephPub(33) ‖ nonce(12) ‖ preimage(32) ‖ GCM tag(16)` — fixed by the sealing
1057
+ * scheme, and what tells the two `claim_packet` shapes apart: a TLV body needs
1058
+ * 96 bytes to carry this much, so the two lengths cannot collide. */
1059
+ declare const SEALED_CIPHERTEXT_LENGTH = 93;
1060
+ /** The Arkade extension packet type covclaimd scans the arkd tx stream for. */
1061
+ declare const CLAIM_PACKET_TYPE = 4;
1062
+ /**
1063
+ * Stamp the covenant script into a client's packet — the solver's half.
1064
+ *
1065
+ * The covenant commits to `taggedHash("ArkScriptHash", script)`, so its funder
1066
+ * holds the only copy guaranteed to match, which is why a client never sends
1067
+ * `0x02`. Appending rather than rebuilding is safe because covclaimd's
1068
+ * `DeserializeClaim` is an order-agnostic switch: the `0x01, 0x03, 0x02` this
1069
+ * produces and its own `Serialize`'s `0x01, 0x02, 0x03` read back identically.
1070
+ */
1071
+ declare const appendArkadeScript: (body: Uint8Array, arkadeScript: Uint8Array) => Uint8Array;
1072
+ type ClaimPacketShape = {
1073
+ kind: "ciphertext";
1074
+ } | {
1075
+ kind: "packet";
1076
+ body: Uint8Array;
1077
+ covclaimdPubkey?: Uint8Array;
1078
+ needsArkadeScript: boolean;
1079
+ };
1080
+ /**
1081
+ * Which of the two `claim_packet` shapes a base64 field carries.
1082
+ *
1083
+ * Never throws: anything not unambiguously a packet reads as the legacy bare
1084
+ * ciphertext, which keeps the older Reveal-API path rather than failing a swap
1085
+ * over a field this side may simply not understand.
1086
+ */
1087
+ declare const claimPacketShape: (b64: string) => ClaimPacketShape;
1038
1088
 
1039
1089
  /**
1040
1090
  * `retryable` is the point of the type: a 400 says the packet does not bind to
@@ -1441,4 +1491,4 @@ interface RfqSwapActivityDeps {
1441
1491
  */
1442
1492
  declare function rfqSwapActivityInputs(deps: RfqSwapActivityDeps): Promise<SwapActivityInput[]>;
1443
1493
 
1444
- export { ASSET_CARRIER_SATS, ArkadeRefundResult, type ArkadeRefunderDeps, AssetSwap, AssetSwapRepository, type AssetSwapRestoreChange, CROSS_ASSET_RAIL, ChainSource, type ClaimArkProvider, type ClaimPacketInput, type CovclaimdClient, type CovclaimdInfo, CovclaimdRevealError, type CrossAssetPhase, type CrossAssetRailDeps, type CrossAssetSwap, type DiscoverMarketsOptions, type FillFunding, IndexedDbAssetSwapRepository, InvoiceFacts, type LightningReceiveProfile, type LightningSendProfile, LockupAmountMismatchError, LockupContractMissing, type LockupContractReader, type LockupContractWriter, LockupRegistrationFailed, LockupSpendIndexer, LockupVtxo, MARKET_CORRIDORS, type MarketCorridor, type MarketLike, MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcParams, OnchainNetwork, type OnchainSendProfile, type PlanError, QUOTE_OPTIONS, RefundArkProvider, type RefundBlockedReason, RefundIndexer, RefundNotLocallyPossibleError, type RegisterAssetSwapRestoreOptions, type RestoreAssetSwapRepositoryOptions, type RestoreAssetSwapRepositoryResult, type RestoreIndexer, type RevealParams, type RfqClaimSecretProjection, type RfqHashlockProjection, type RfqSignerProjection, RfqSwap, type RfqSwapActivityDeps, RfqSwapRecord, RfqSwapState, RfqTransport, SOLVER_LIGHTNING_RAIL, SOLVER_ONCHAIN_RAIL, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SolverLightningRailDeps, type SolverLightningSend, type SolverOnchainRailDeps, type SolverOnchainSend, type SolverRendezvous, type SpendKind, type SwapActivityInput, SwapSecretsProjection, type Tx, type WatchOfferSwapsParams, arkadeRefunder, awaitLockupFunding, cancelOffer, chainSourceFrom, claimReceiveLockup, classifyDepositSpend, classifySpend, covclaimdClient, createOffer, crossAssetRail, decodeOffer, discoverMarkets, encodeOffer, fillOffer, findMarket, isRfqMarket, lockupContractParams, makeCachedFeedFetch, marketAssetId, marketCorridor, marketPairLabel, offerVtxoScript, onchainSendProfile, pushClaim, registerAssetSwapRestore, registerLockupContract, requestLightningSend, requestOnchainSend, restoreAssetSwapRepository, restoreAssetSwaps, restoreOfferCoverage, retireSettledOfferContracts, revealClaimPacket, revealFieldsFromScript, rfqClaimSecretOf, rfqSecretsProfile, rfqSignerOf, rfqSwapActivityInputs, sealClaimPacket, senderIdentityForSwapRecord, solverLightningRail, solverLightningRendezvous, solverOnchainRail, solverOnchainRendezvous, solverRendezvous, spendTxidsOf, spendUpdate, swapActivityResolver, swapPrograms, validatePlan, watchOfferSwaps };
1494
+ export { ASSET_CARRIER_SATS, ArkadeRefundResult, type ArkadeRefunderDeps, AssetSwap, AssetSwapRepository, type AssetSwapRestoreChange, CLAIM_PACKET_TYPE, CROSS_ASSET_RAIL, ChainSource, type ClaimArkProvider, type ClaimPacketInput, type ClaimPacketShape, type CovclaimdClient, type CovclaimdInfo, CovclaimdRevealError, type CrossAssetPhase, type CrossAssetRailDeps, type CrossAssetSwap, type DiscoverMarketsOptions, type FillFunding, IndexedDbAssetSwapRepository, InvoiceFacts, type LightningReceiveProfile, type LightningSendProfile, LockupAmountMismatchError, LockupContractMissing, type LockupContractReader, type LockupContractWriter, LockupRegistrationFailed, LockupSpendIndexer, LockupVtxo, MARKET_CORRIDORS, type MarketCorridor, type MarketLike, MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcParams, OnchainNetwork, type OnchainSendProfile, type PlanError, QUOTE_OPTIONS, RefundArkProvider, type RefundBlockedReason, RefundIndexer, RefundNotLocallyPossibleError, type RegisterAssetSwapRestoreOptions, type RestoreAssetSwapRepositoryOptions, type RestoreAssetSwapRepositoryResult, type RestoreIndexer, type RevealParams, type RfqClaimSecretProjection, type RfqHashlockProjection, type RfqSignerProjection, RfqSwap, type RfqSwapActivityDeps, RfqSwapRecord, RfqSwapState, RfqTransport, SEALED_CIPHERTEXT_LENGTH, SOLVER_LIGHTNING_RAIL, SOLVER_ONCHAIN_RAIL, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SolverLightningRailDeps, type SolverLightningSend, type SolverOnchainRailDeps, type SolverOnchainSend, type SolverRendezvous, type SpendKind, type SwapActivityInput, SwapSecretsProjection, type Tx, type WatchOfferSwapsParams, appendArkadeScript, arkadeRefunder, awaitLockupFunding, cancelOffer, chainSourceFrom, claimPacketShape, claimReceiveLockup, classifyDepositSpend, classifySpend, covclaimdClient, createOffer, crossAssetRail, decodeOffer, discoverMarkets, encodeOffer, fillOffer, findMarket, isRfqMarket, lockupContractParams, makeCachedFeedFetch, marketAssetId, marketCorridor, marketPairLabel, offerVtxoScript, onchainSendProfile, pushClaim, registerAssetSwapRestore, registerLockupContract, requestLightningSend, requestOnchainSend, restoreAssetSwapRepository, restoreAssetSwaps, restoreOfferCoverage, retireSettledOfferContracts, revealClaimPacket, revealFieldsFromScript, rfqClaimSecretOf, rfqSecretsProfile, rfqSignerOf, rfqSwapActivityInputs, sealClaimPacket, senderIdentityForSwapRecord, solverLightningRail, solverLightningRendezvous, solverOnchainRail, solverOnchainRendezvous, solverRendezvous, spendTxidsOf, spendUpdate, swapActivityResolver, swapPrograms, validatePlan, watchOfferSwaps };
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-DH5zjdw4.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-DH5zjdw4.js';
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-CucjFZN1.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-CucjFZN1.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-DirJn_4k.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 assertFundable, Q as assertReceivable, T as awaitOnchainFill, U as buildHtlcClaim, V as buildHtlcRefund, W as claimOnchainFill, X as classifyOnchainHtlc, Y as deriveLightningReceive, Z as deriveOnchainReceive, _ as deriveOnchainSend, $ as extractPreimage, a0 as httpTransport, a1 as isRfqRefusalErrorCode, a2 as l1ScriptForAddress, a3 as lightningReceiveRequest, a4 as lightningSendRequest, a5 as lightningSendVtxoScript, a6 as newPreimage, a7 as newRfqId, a8 as offerTermsFromQuote, a9 as onchainHtlcScript, aa as onchainReceiveRequest, ab as onchainSendRequest, ac as paymentHashOf, ad as receiveVtxoScript, ae as relayTransport, af as requestLightningReceive, ag as requestOnchainReceive, ah as rfqPair, ai as unilateralClaimDelay, aj as unilateralRefundDelay, ak as unilateralRefundWithoutReceiverDelay, al as verifyLockupAddress, am as verifyReceiveInvoice } from './rfq-DirJn_4k.js';
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-B_2hM0xk.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 assertFundable, Q as assertReceivable, T as awaitOnchainFill, U as buildHtlcClaim, V as buildHtlcRefund, W as claimOnchainFill, X as classifyOnchainHtlc, Y as deriveLightningReceive, Z as deriveOnchainReceive, _ as deriveOnchainSend, $ as extractPreimage, a0 as httpTransport, a1 as isRfqRefusalErrorCode, a2 as l1ScriptForAddress, a3 as lightningReceiveRequest, a4 as lightningSendRequest, a5 as lightningSendVtxoScript, a6 as newPreimage, a7 as newRfqId, a8 as offerTermsFromQuote, a9 as onchainHtlcScript, aa as onchainReceiveRequest, ab as onchainSendRequest, ac as paymentHashOf, ad as receiveVtxoScript, ae as relayTransport, af as requestLightningReceive, ag as requestOnchainReceive, ah as rfqPair, ai as unilateralClaimDelay, aj as unilateralRefundDelay, ak as unilateralRefundWithoutReceiverDelay, al as verifyLockupAddress, am as verifyReceiveInvoice } from './rfq-B_2hM0xk.js';
7
7
 
8
8
  /**
9
9
  * Which wallet key signs this leg. Stored at `profile.signer`.
@@ -1014,10 +1014,28 @@ interface CrossAssetRailDeps {
1014
1014
  declare function crossAssetRail(deps: CrossAssetRailDeps): PaymentRail;
1015
1015
 
1016
1016
  interface SealedClaimPacket {
1017
- /** `ephPub(33) ‖ nonce(12) ‖ ciphertext`, base64 — wire-ready. This is
1018
- * the whole packet: the RFQ request's `claim_packet` field carries
1019
- * exactly this string. */
1017
+ /** `ephPub(33) ‖ nonce(12) ‖ ciphertext`, base64 — the bare sealed bytes,
1018
+ * 93 decoded. The older of the two `claim_packet` shapes: a solver holding
1019
+ * it can only hand it to covclaimd over the Reveal API, which needs both
1020
+ * sides pointed at the SAME covclaimd — an agreement nothing on the wire
1021
+ * expresses. Prefer {@link SealedClaimPacket.packet}. */
1020
1022
  ciphertext: string;
1023
+ /**
1024
+ * covclaimd's serialised `ClaimPacket` body, base64 — TLV `0x01` ciphertext
1025
+ * and `0x03` covclaimd_pub_key. **This is what `claim_packet` should
1026
+ * carry** (§ 7.1.2: senders SHOULD prefer the packet shape).
1027
+ *
1028
+ * It is what lets the solver stamp the funding transaction as Arkade
1029
+ * extension packet `0x04`, which covclaimd finds on the arkd stream by
1030
+ * itself. The `0x03` TLV is what its filter selects on, so the client alone
1031
+ * chooses which covclaimd — the solver needs none configured or reachable.
1032
+ *
1033
+ * `0x02` arkade_script is deliberately absent: the covenant commits to
1034
+ * `taggedHash("ArkScriptHash", script)`, so the funder holds the only copy
1035
+ * guaranteed to match and appends it. A client deriving its own would add a
1036
+ * way for the two to disagree and strand the claim.
1037
+ */
1038
+ packet: string;
1021
1039
  }
1022
1040
  interface ClaimPacketInput {
1023
1041
  preimage: Uint8Array;
@@ -1035,6 +1053,38 @@ interface ClaimPacketInput {
1035
1053
  * helper, where no consumer reaches it by accident.
1036
1054
  */
1037
1055
  declare function sealClaimPacket(input: ClaimPacketInput): Promise<SealedClaimPacket>;
1056
+ /** `ephPub(33) ‖ nonce(12) ‖ preimage(32) ‖ GCM tag(16)` — fixed by the sealing
1057
+ * scheme, and what tells the two `claim_packet` shapes apart: a TLV body needs
1058
+ * 96 bytes to carry this much, so the two lengths cannot collide. */
1059
+ declare const SEALED_CIPHERTEXT_LENGTH = 93;
1060
+ /** The Arkade extension packet type covclaimd scans the arkd tx stream for. */
1061
+ declare const CLAIM_PACKET_TYPE = 4;
1062
+ /**
1063
+ * Stamp the covenant script into a client's packet — the solver's half.
1064
+ *
1065
+ * The covenant commits to `taggedHash("ArkScriptHash", script)`, so its funder
1066
+ * holds the only copy guaranteed to match, which is why a client never sends
1067
+ * `0x02`. Appending rather than rebuilding is safe because covclaimd's
1068
+ * `DeserializeClaim` is an order-agnostic switch: the `0x01, 0x03, 0x02` this
1069
+ * produces and its own `Serialize`'s `0x01, 0x02, 0x03` read back identically.
1070
+ */
1071
+ declare const appendArkadeScript: (body: Uint8Array, arkadeScript: Uint8Array) => Uint8Array;
1072
+ type ClaimPacketShape = {
1073
+ kind: "ciphertext";
1074
+ } | {
1075
+ kind: "packet";
1076
+ body: Uint8Array;
1077
+ covclaimdPubkey?: Uint8Array;
1078
+ needsArkadeScript: boolean;
1079
+ };
1080
+ /**
1081
+ * Which of the two `claim_packet` shapes a base64 field carries.
1082
+ *
1083
+ * Never throws: anything not unambiguously a packet reads as the legacy bare
1084
+ * ciphertext, which keeps the older Reveal-API path rather than failing a swap
1085
+ * over a field this side may simply not understand.
1086
+ */
1087
+ declare const claimPacketShape: (b64: string) => ClaimPacketShape;
1038
1088
 
1039
1089
  /**
1040
1090
  * `retryable` is the point of the type: a 400 says the packet does not bind to
@@ -1441,4 +1491,4 @@ interface RfqSwapActivityDeps {
1441
1491
  */
1442
1492
  declare function rfqSwapActivityInputs(deps: RfqSwapActivityDeps): Promise<SwapActivityInput[]>;
1443
1493
 
1444
- export { ASSET_CARRIER_SATS, ArkadeRefundResult, type ArkadeRefunderDeps, AssetSwap, AssetSwapRepository, type AssetSwapRestoreChange, CROSS_ASSET_RAIL, ChainSource, type ClaimArkProvider, type ClaimPacketInput, type CovclaimdClient, type CovclaimdInfo, CovclaimdRevealError, type CrossAssetPhase, type CrossAssetRailDeps, type CrossAssetSwap, type DiscoverMarketsOptions, type FillFunding, IndexedDbAssetSwapRepository, InvoiceFacts, type LightningReceiveProfile, type LightningSendProfile, LockupAmountMismatchError, LockupContractMissing, type LockupContractReader, type LockupContractWriter, LockupRegistrationFailed, LockupSpendIndexer, LockupVtxo, MARKET_CORRIDORS, type MarketCorridor, type MarketLike, MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcParams, OnchainNetwork, type OnchainSendProfile, type PlanError, QUOTE_OPTIONS, RefundArkProvider, type RefundBlockedReason, RefundIndexer, RefundNotLocallyPossibleError, type RegisterAssetSwapRestoreOptions, type RestoreAssetSwapRepositoryOptions, type RestoreAssetSwapRepositoryResult, type RestoreIndexer, type RevealParams, type RfqClaimSecretProjection, type RfqHashlockProjection, type RfqSignerProjection, RfqSwap, type RfqSwapActivityDeps, RfqSwapRecord, RfqSwapState, RfqTransport, SOLVER_LIGHTNING_RAIL, SOLVER_ONCHAIN_RAIL, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SolverLightningRailDeps, type SolverLightningSend, type SolverOnchainRailDeps, type SolverOnchainSend, type SolverRendezvous, type SpendKind, type SwapActivityInput, SwapSecretsProjection, type Tx, type WatchOfferSwapsParams, arkadeRefunder, awaitLockupFunding, cancelOffer, chainSourceFrom, claimReceiveLockup, classifyDepositSpend, classifySpend, covclaimdClient, createOffer, crossAssetRail, decodeOffer, discoverMarkets, encodeOffer, fillOffer, findMarket, isRfqMarket, lockupContractParams, makeCachedFeedFetch, marketAssetId, marketCorridor, marketPairLabel, offerVtxoScript, onchainSendProfile, pushClaim, registerAssetSwapRestore, registerLockupContract, requestLightningSend, requestOnchainSend, restoreAssetSwapRepository, restoreAssetSwaps, restoreOfferCoverage, retireSettledOfferContracts, revealClaimPacket, revealFieldsFromScript, rfqClaimSecretOf, rfqSecretsProfile, rfqSignerOf, rfqSwapActivityInputs, sealClaimPacket, senderIdentityForSwapRecord, solverLightningRail, solverLightningRendezvous, solverOnchainRail, solverOnchainRendezvous, solverRendezvous, spendTxidsOf, spendUpdate, swapActivityResolver, swapPrograms, validatePlan, watchOfferSwaps };
1494
+ export { ASSET_CARRIER_SATS, ArkadeRefundResult, type ArkadeRefunderDeps, AssetSwap, AssetSwapRepository, type AssetSwapRestoreChange, CLAIM_PACKET_TYPE, CROSS_ASSET_RAIL, ChainSource, type ClaimArkProvider, type ClaimPacketInput, type ClaimPacketShape, type CovclaimdClient, type CovclaimdInfo, CovclaimdRevealError, type CrossAssetPhase, type CrossAssetRailDeps, type CrossAssetSwap, type DiscoverMarketsOptions, type FillFunding, IndexedDbAssetSwapRepository, InvoiceFacts, type LightningReceiveProfile, type LightningSendProfile, LockupAmountMismatchError, LockupContractMissing, type LockupContractReader, type LockupContractWriter, LockupRegistrationFailed, LockupSpendIndexer, LockupVtxo, MARKET_CORRIDORS, type MarketCorridor, type MarketLike, MarketsCacheEntry, OFFER_PACKET_TYPE, type Offer, type OfferContractRetirer, type OfferSwapWatcher, OnchainHtlc, OnchainHtlcParams, OnchainNetwork, type OnchainSendProfile, type PlanError, QUOTE_OPTIONS, RefundArkProvider, type RefundBlockedReason, RefundIndexer, RefundNotLocallyPossibleError, type RegisterAssetSwapRestoreOptions, type RestoreAssetSwapRepositoryOptions, type RestoreAssetSwapRepositoryResult, type RestoreIndexer, type RevealParams, type RfqClaimSecretProjection, type RfqHashlockProjection, type RfqSignerProjection, RfqSwap, type RfqSwapActivityDeps, RfqSwapRecord, RfqSwapState, RfqTransport, SEALED_CIPHERTEXT_LENGTH, SOLVER_LIGHTNING_RAIL, SOLVER_ONCHAIN_RAIL, SWAP_LOCKUP_CONTRACT_KIND, SWAP_LOCKUP_CONTRACT_LABEL, SWAP_LOCKUP_CONTRACT_TYPE, type SealedClaimPacket, type SolverLightningRailDeps, type SolverLightningSend, type SolverOnchainRailDeps, type SolverOnchainSend, type SolverRendezvous, type SpendKind, type SwapActivityInput, SwapSecretsProjection, type Tx, type WatchOfferSwapsParams, appendArkadeScript, arkadeRefunder, awaitLockupFunding, cancelOffer, chainSourceFrom, claimPacketShape, claimReceiveLockup, classifyDepositSpend, classifySpend, covclaimdClient, createOffer, crossAssetRail, decodeOffer, discoverMarkets, encodeOffer, fillOffer, findMarket, isRfqMarket, lockupContractParams, makeCachedFeedFetch, marketAssetId, marketCorridor, marketPairLabel, offerVtxoScript, onchainSendProfile, pushClaim, registerAssetSwapRestore, registerLockupContract, requestLightningSend, requestOnchainSend, restoreAssetSwapRepository, restoreAssetSwaps, restoreOfferCoverage, retireSettledOfferContracts, revealClaimPacket, revealFieldsFromScript, rfqClaimSecretOf, rfqSecretsProfile, rfqSignerOf, rfqSwapActivityInputs, sealClaimPacket, senderIdentityForSwapRecord, solverLightningRail, solverLightningRendezvous, solverOnchainRail, solverOnchainRendezvous, solverRendezvous, spendTxidsOf, spendUpdate, swapActivityResolver, swapPrograms, validatePlan, watchOfferSwaps };
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  ARKADE_ASSET,
3
3
  ARKADE_BTC,
4
4
  AddressMismatch,
5
+ CLAIM_PACKET_TYPE,
5
6
  L1_NETWORKS,
6
7
  LIGHTNING_BTC,
7
8
  LIGHTNING_RECEIVE_PAIR,
@@ -21,11 +22,13 @@ import {
21
22
  ONCHAIN_SEND_PAIR,
22
23
  RFQ_REFUSAL_ERROR_CODES,
23
24
  RFQ_TERMINAL_STATES,
25
+ SEALED_CIPHERTEXT_LENGTH,
24
26
  SOLO_REFUND_HEADROOM_SECONDS,
25
27
  SWAP_LOCKUP_CONTRACT_KIND,
26
28
  SWAP_LOCKUP_CONTRACT_LABEL,
27
29
  SWAP_LOCKUP_CONTRACT_TYPE,
28
30
  SwapRefusal,
31
+ appendArkadeScript,
29
32
  arkadeAssetLeg,
30
33
  arkadeSwapRequest,
31
34
  assertFundable,
@@ -34,6 +37,7 @@ import {
34
37
  buildHtlcClaim,
35
38
  buildHtlcRefund,
36
39
  claimOnchainFill,
40
+ claimPacketShape,
37
41
  classifyOnchainHtlc,
38
42
  deriveLightningReceive,
39
43
  deriveOnchainReceive,
@@ -67,7 +71,7 @@ import {
67
71
  unilateralRefundWithoutReceiverDelay,
68
72
  verifyLockupAddress,
69
73
  verifyReceiveInvoice
70
- } from "./chunk-7N7XO4PY.js";
74
+ } from "./chunk-N3W6LXH6.js";
71
75
  import {
72
76
  InMemoryAssetSwapRepository,
73
77
  marketsCacheKey
@@ -847,6 +851,7 @@ import {
847
851
  bestMarket,
848
852
  discover,
849
853
  isNetwork,
854
+ marketLegKey,
850
855
  sideLimits
851
856
  } from "@arkade-os/solver-discovery";
852
857
  import { isSubdust } from "@arkade-os/sdk";
@@ -992,11 +997,11 @@ var findMarket = (markets, fromId, toId) => {
992
997
  for (const market of markets) {
993
998
  for (const side of ["base", "quote"]) {
994
999
  const asset2 = side === "base" ? market.base_asset : market.quote_asset;
995
- if (asset2.id === id) return id;
1000
+ if (asset2.id === id) return marketLegKey(market, side);
996
1001
  const canonical = marketAssetId(market, side) ?? "";
997
1002
  const matchesBtc = id === BTC_ASSET_ID && /^arkade:[^/]+\/slip44:(?:0|1)$/.test(canonical);
998
1003
  const matchesAsset = /^[0-9a-f]{68}$/.test(id) && canonical.endsWith(`/asset:${id}`);
999
- if ((matchesBtc || matchesAsset) && typeof asset2.id === "string") return asset2.id;
1004
+ if (matchesBtc || matchesAsset) return marketLegKey(market, side);
1000
1005
  }
1001
1006
  }
1002
1007
  return id;
@@ -1941,7 +1946,7 @@ var chainSourceFrom = (provider, network) => {
1941
1946
  };
1942
1947
 
1943
1948
  // src/payment/rendezvous.ts
1944
- import { selectMarkets, sideLimits as sideLimits2 } from "@arkade-os/solver-discovery";
1949
+ import { sideLimits as sideLimits2 } from "@arkade-os/solver-discovery";
1945
1950
  import { hex as hex8 } from "@scure/base";
1946
1951
  var XONLY_HEX = /^[0-9a-f]{64}$/;
1947
1952
  var rendezvousOf = (market, pinned) => {
@@ -1964,12 +1969,11 @@ var solverRendezvous = (markets, payoutCorridor, amountSats, fallbackEmulatorPub
1964
1969
  const encoded = fallbackEmulatorPubkey ? hex8.encode(fallbackEmulatorPubkey) : void 0;
1965
1970
  if (encoded !== void 0 && !XONLY_HEX.test(encoded)) return void 0;
1966
1971
  const pinned = encoded;
1967
- const candidates = selectMarkets(markets, {
1968
- baseId: BTC_ASSET_ID,
1969
- quoteId: BTC_ASSET_ID,
1970
- baseCorridor: "arkade",
1971
- quoteCorridor: payoutCorridor
1972
- });
1972
+ const quoteCorridor = payoutCorridor === "lightning" ? "bolt11" : "bitcoin";
1973
+ const isBtc = (id) => id === "btc" || /^\w+:[^/]+\/slip44:(?:0|1)$/.test(id ?? "");
1974
+ const candidates = markets.filter(
1975
+ (market) => marketCorridor(market, "base") === "arkade" && marketCorridor(market, "quote") === quoteCorridor && isBtc(marketAssetId(market, "base")) && isBtc(marketAssetId(market, "quote"))
1976
+ );
1973
1977
  for (const market of candidates) {
1974
1978
  const rendezvous = rendezvousOf(market, pinned);
1975
1979
  if (!rendezvous) continue;
@@ -4005,6 +4009,7 @@ export {
4005
4009
  ASSET_CARRIER_SATS,
4006
4010
  AddressMismatch,
4007
4011
  BTC_ASSET_ID,
4012
+ CLAIM_PACKET_TYPE,
4008
4013
  CROSS_ASSET_RAIL,
4009
4014
  CovclaimdRevealError,
4010
4015
  InMemoryAssetSwapRepository,
@@ -4040,6 +4045,7 @@ export {
4040
4045
  RefundNotLocallyPossibleError,
4041
4046
  RfqSwapManager,
4042
4047
  RfqSwapOriginRequired,
4048
+ SEALED_CIPHERTEXT_LENGTH,
4043
4049
  SOLO_REFUND_HEADROOM_SECONDS,
4044
4050
  SOLVER_LIGHTNING_RAIL,
4045
4051
  SOLVER_ONCHAIN_RAIL,
@@ -4048,6 +4054,7 @@ export {
4048
4054
  SWAP_LOCKUP_CONTRACT_TYPE,
4049
4055
  SwapRefusal,
4050
4056
  addAssetSwap,
4057
+ appendArkadeScript,
4051
4058
  arkadeAssetLeg,
4052
4059
  arkadeRefunder,
4053
4060
  arkadeSwapRequest,
@@ -4061,6 +4068,7 @@ export {
4061
4068
  cancelOffer,
4062
4069
  chainSourceFrom,
4063
4070
  claimOnchainFill,
4071
+ claimPacketShape,
4064
4072
  claimReceiveLockup,
4065
4073
  classifyDepositSpend,
4066
4074
  classifyOnchainHtlc,
package/dist/nostr.cjs CHANGED
@@ -62,6 +62,7 @@ var import_sdk3 = require("@arkade-os/sdk");
62
62
 
63
63
  // src/claimPacket.ts
64
64
  var import_base2 = require("@scure/base");
65
+ var import_utils = require("@scure/btc-signer/utils.js");
65
66
  var import_aes = require("@noble/ciphers/aes.js");
66
67
  var import_secp256k1 = require("@noble/curves/secp256k1.js");
67
68
  var import_hkdf = require("@noble/hashes/hkdf.js");
package/dist/nostr.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { R as RfqTransport } from './rfq-DirJn_4k.cjs';
1
+ import { R as RfqTransport } from './rfq-B_2hM0xk.cjs';
2
2
  import { SimplePool } from 'nostr-tools';
3
3
  import '@arkade-os/sdk';
4
4
 
package/dist/nostr.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { R as RfqTransport } from './rfq-DirJn_4k.js';
1
+ import { R as RfqTransport } from './rfq-B_2hM0xk.js';
2
2
  import { SimplePool } from 'nostr-tools';
3
3
  import '@arkade-os/sdk';
4
4
 
package/dist/nostr.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  expectQuote,
3
3
  pairOf
4
- } from "./chunk-7N7XO4PY.js";
4
+ } from "./chunk-N3W6LXH6.js";
5
5
 
6
6
  // src/nostr.ts
7
7
  import {
@@ -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-rwU1Sv2-.cjs';
2
+ import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-BwasQwkR.cjs';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-DirJn_4k.cjs';
5
+ import '../../rfq-B_2hM0xk.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-DH5zjdw4.js';
2
+ import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-CucjFZN1.js';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-DirJn_4k.js';
5
+ import '../../rfq-B_2hM0xk.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-rwU1Sv2-.cjs';
2
+ import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-BwasQwkR.cjs';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-DirJn_4k.cjs';
5
+ import '../../rfq-B_2hM0xk.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-DH5zjdw4.js';
2
+ import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-CucjFZN1.js';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-DirJn_4k.js';
5
+ import '../../rfq-B_2hM0xk.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 { G as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-DirJn_4k.cjs';
3
+ import { G as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-B_2hM0xk.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.
@@ -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 { G as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-DirJn_4k.js';
3
+ import { G as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-B_2hM0xk.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.
@@ -308,6 +308,7 @@ interface RfqQuote {
308
308
  [key: string]: unknown;
309
309
  payment_hash?: string;
310
310
  lockup_address?: string;
311
+ refund_without_receiver_delay?: number;
311
312
  };
312
313
  [key: string]: unknown;
313
314
  }
@@ -502,6 +503,8 @@ declare function lightningSendVtxoScript(params: {
502
503
  * {@link unilateralRefundDelay} and {@link unilateralRefundWithoutReceiverDelay}
503
504
  * derive from this same value — one rounding, shared across all three tiers. */
504
505
  claimDelay: number;
506
+ /** Binding quote field. Optional only for rebuilding pre-upgrade scripts. */
507
+ refundWithoutReceiverDelay?: number;
505
508
  /** Emulator x-only key (32 bytes). */
506
509
  emulatorPubkey: Uint8Array;
507
510
  /** Where a refund must pay: the trader's P2TR pkScript (34 bytes). Also
@@ -308,6 +308,7 @@ interface RfqQuote {
308
308
  [key: string]: unknown;
309
309
  payment_hash?: string;
310
310
  lockup_address?: string;
311
+ refund_without_receiver_delay?: number;
311
312
  };
312
313
  [key: string]: unknown;
313
314
  }
@@ -502,6 +503,8 @@ declare function lightningSendVtxoScript(params: {
502
503
  * {@link unilateralRefundDelay} and {@link unilateralRefundWithoutReceiverDelay}
503
504
  * derive from this same value — one rounding, shared across all three tiers. */
504
505
  claimDelay: number;
506
+ /** Binding quote field. Optional only for rebuilding pre-upgrade scripts. */
507
+ refundWithoutReceiverDelay?: number;
505
508
  /** Emulator x-only key (32 bytes). */
506
509
  emulatorPubkey: Uint8Array;
507
510
  /** Where a refund must pay: the trader's P2TR pkScript (34 bytes). Also
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkade-os/swap",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "type": "module",
5
5
  "description": "Client-side Arkade Intents asset swaps: discover markets, quote, create/track/cancel offers, restore from chain.",
6
6
  "repository": {
@@ -64,7 +64,7 @@
64
64
  "author": "Arkade-OS",
65
65
  "license": "MIT",
66
66
  "dependencies": {
67
- "@arkade-os/solver-discovery": "0.2.3",
67
+ "@arkade-os/solver-discovery": "0.2.4",
68
68
  "@noble/ciphers": "2.1.1",
69
69
  "@noble/curves": "2.0.1",
70
70
  "@noble/hashes": "2.0.1",
@@ -95,8 +95,8 @@
95
95
  "lint": "biome format src test",
96
96
  "test": "vitest run --exclude test/e2e",
97
97
  "test:unit": "vitest run --exclude test/e2e",
98
- "test:integration": "vitest run test/e2e/** --exclude test/e2e/rfq*.test.ts",
99
- "test:integration:rfq": "vitest run test/e2e/rfq*.test.ts",
98
+ "test:integration": "vitest run --exclude \"test/e2e/rfq*.test.ts\" test/e2e/",
99
+ "test:integration:rfq": "vitest run test/e2e/rfq",
100
100
  "smoke:dist": "node scripts/smoke-dist.mjs"
101
101
  }
102
102
  }