@arkade-os/swap 0.0.17 → 0.0.19

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/nostr.cjs CHANGED
@@ -39,9 +39,9 @@ __export(nostr_exports, {
39
39
  module.exports = __toCommonJS(nostr_exports);
40
40
 
41
41
  // src/rfq.ts
42
- var import_base4 = require("@scure/base");
42
+ var import_base6 = require("@scure/base");
43
43
  var import_legacy2 = require("@noble/hashes/legacy.js");
44
- var import_sdk2 = require("@arkade-os/sdk");
44
+ var import_sdk4 = require("@arkade-os/sdk");
45
45
 
46
46
  // src/onchainHtlc.ts
47
47
  var import_base = require("@scure/base");
@@ -58,7 +58,7 @@ var L1_NETWORKS = {
58
58
  };
59
59
 
60
60
  // src/rfq.ts
61
- var import_sdk3 = require("@arkade-os/sdk");
61
+ var import_sdk5 = require("@arkade-os/sdk");
62
62
 
63
63
  // src/claimPacket.ts
64
64
  var import_base2 = require("@scure/base");
@@ -73,6 +73,111 @@ var HKDF_INFO = new TextEncoder().encode("covclaimd/preimage/v1");
73
73
  var import_base3 = require("@scure/base");
74
74
  var import_sdk = require("@arkade-os/sdk");
75
75
 
76
+ // src/offer.ts
77
+ var import_base5 = require("@scure/base");
78
+ var import_utils2 = require("@scure/btc-signer/utils.js");
79
+ var import_sdk3 = require("@arkade-os/sdk");
80
+
81
+ // src/swap-want-asset.program.json
82
+ var swap_want_asset_program_default = {
83
+ version: 0,
84
+ name: "banco-btc-to-asset",
85
+ params: [
86
+ { name: "makerWP", type: "pubkey" },
87
+ { name: "wantAmount", type: "int" },
88
+ { name: "wantAssetTxid", type: "hash" },
89
+ { name: "wantAssetGroupIndex", type: "int" },
90
+ { name: "server", type: "pubkey" },
91
+ { name: "user", type: "pubkey" }
92
+ ],
93
+ functions: {
94
+ fulfill: {
95
+ tapscript: { signers: ["$server"] },
96
+ arkadeScript: {
97
+ asm: [
98
+ 0,
99
+ "$wantAssetTxid",
100
+ "$wantAssetGroupIndex",
101
+ "INSPECTOUTASSETLOOKUP",
102
+ "VERIFY",
103
+ "$wantAmount",
104
+ "GREATERTHANOREQUAL",
105
+ "VERIFY",
106
+ 0,
107
+ "INSPECTOUTPUTSCRIPTPUBKEY",
108
+ 1,
109
+ "EQUALVERIFY",
110
+ "$makerWP",
111
+ "EQUAL"
112
+ ]
113
+ }
114
+ },
115
+ cancel: {
116
+ tapscript: { signers: ["$user", "$server"] }
117
+ }
118
+ }
119
+ };
120
+
121
+ // src/swap-want-btc.program.json
122
+ var swap_want_btc_program_default = {
123
+ version: 0,
124
+ name: "banco-asset-to-btc",
125
+ params: [
126
+ { name: "makerWP", type: "pubkey" },
127
+ { name: "wantAmount", type: "int" },
128
+ { name: "server", type: "pubkey" },
129
+ { name: "user", type: "pubkey" }
130
+ ],
131
+ functions: {
132
+ fulfill: {
133
+ tapscript: { signers: ["$server"] },
134
+ arkadeScript: {
135
+ asm: [
136
+ 0,
137
+ "INSPECTOUTPUTVALUE",
138
+ "$wantAmount",
139
+ "GREATERTHANOREQUAL",
140
+ "VERIFY",
141
+ 0,
142
+ "INSPECTOUTPUTSCRIPTPUBKEY",
143
+ 1,
144
+ "EQUALVERIFY",
145
+ "$makerWP",
146
+ "EQUAL"
147
+ ]
148
+ }
149
+ },
150
+ cancel: {
151
+ tapscript: { signers: ["$user", "$server"] }
152
+ }
153
+ }
154
+ };
155
+
156
+ // src/store.ts
157
+ var import_base4 = require("@scure/base");
158
+ var import_sha23 = require("@noble/hashes/sha2.js");
159
+ var import_sdk2 = require("@arkade-os/sdk");
160
+
161
+ // src/offer.ts
162
+ var swapPrograms = {
163
+ wantAsset: import_sdk3.arkade.parseArtifact(swap_want_asset_program_default),
164
+ wantBtc: import_sdk3.arkade.parseArtifact(swap_want_btc_program_default)
165
+ };
166
+ var FIELDS = {
167
+ swapPkScript: { tag: 1, width: 34 },
168
+ wantAmount: { tag: 2, width: 8 },
169
+ wantAsset: { tag: 3, width: void 0 },
170
+ makerPkScript: { tag: 5, width: 34 },
171
+ makerPublicKey: { tag: 7, width: 32 },
172
+ emulatorPubkey: { tag: 8, width: 32 },
173
+ ratioNum: { tag: 9, width: 8 },
174
+ ratioDen: { tag: 10, width: 8 },
175
+ offerAsset: { tag: 11, width: void 0 },
176
+ exitTimelock: { tag: 12, width: 9 }
177
+ };
178
+ var NAMES = Object.fromEntries(Object.entries(FIELDS).map(([k, f]) => [f.tag, k]));
179
+ var ASSET_CARRIER_SATS = BigInt(import_sdk3.ASSET_CARRIER_SATS);
180
+
76
181
  // src/rfq.ts
77
182
  var ARKADE_BTC = "arkade:BTC";
78
183
  var LIGHTNING_BTC = "lightning:BTC";
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-D96aLvCA.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-D96aLvCA.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-IRDBAAJZ.js";
4
+ } from "./chunk-D7GDHZCG.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-BXIcmIIC.cjs';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-DirJn_4k.cjs';
5
+ import '../../rfq-D96aLvCA.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-B6VPDGHC.js';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-DirJn_4k.js';
5
+ import '../../rfq-D96aLvCA.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-BXIcmIIC.cjs';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-DirJn_4k.cjs';
5
+ import '../../rfq-D96aLvCA.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-B6VPDGHC.js';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-DirJn_4k.js';
5
+ import '../../rfq-D96aLvCA.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.js';
3
+ import { G as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-D96aLvCA.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.
@@ -829,6 +829,9 @@ interface OnchainSendSwap extends RfqSwapCommon {
829
829
  htlc: OnchainHtlc;
830
830
  /** `profile.min_confirmations` from the quote. */
831
831
  minConfirmations: number;
832
+ /** The quote's `to_amount`, captured at REQUEST time: read at claim time it
833
+ * would be whatever the solver funded. */
834
+ expectedAmount: number;
832
835
  /** Where {@link RfqSwapManagerCallbacks.claimOnchain} pays; optional only
833
836
  * so records predating its profile slot still restore. */
834
837
  payoutPkScript?: Uint8Array;
@@ -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-D96aLvCA.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.
@@ -829,6 +829,9 @@ interface OnchainSendSwap extends RfqSwapCommon {
829
829
  htlc: OnchainHtlc;
830
830
  /** `profile.min_confirmations` from the quote. */
831
831
  minConfirmations: number;
832
+ /** The quote's `to_amount`, captured at REQUEST time: read at claim time it
833
+ * would be whatever the solver funded. */
834
+ expectedAmount: number;
832
835
  /** Where {@link RfqSwapManagerCallbacks.claimOnchain} pays; optional only
833
836
  * so records predating its profile slot still restore. */
834
837
  payoutPkScript?: Uint8Array;
@@ -298,8 +298,11 @@ interface RfqQuote {
298
298
  type: "rfq_quote";
299
299
  rfq_id: string;
300
300
  pair: string;
301
- from_amount: number;
302
- to_amount: number;
301
+ /** Sats on HTLC-class corridors (number); canonical decimal string on
302
+ * arkade↔arkade asset legs (bigint range, see WIRE_ASSET_AMOUNT on the
303
+ * solver). */
304
+ from_amount: number | string;
305
+ to_amount: number | string;
303
306
  solver_pubkey: string;
304
307
  valid_until: number;
305
308
  /** HTLC-class quotes only; absent for arkade↔arkade. */
@@ -308,6 +311,9 @@ interface RfqQuote {
308
311
  [key: string]: unknown;
309
312
  payment_hash?: string;
310
313
  lockup_address?: string;
314
+ refund_without_receiver_delay?: number;
315
+ offer_address?: string;
316
+ offer_pk_script?: string;
311
317
  };
312
318
  [key: string]: unknown;
313
319
  }
@@ -335,20 +341,44 @@ declare const lightningSendRequest: (input: {
335
341
  refundAddress: string;
336
342
  senderPubkey: Uint8Array;
337
343
  }) => Record<string, unknown>;
338
- /** The rfq_request for an arkade↔arkade swap. Exactly one side may name an
339
- * asset id per direction (BTC has none), and the id is the leg itself — see
340
- * {@link arkadeAssetLeg}. Forward-looking: the wire shape is specified, the
341
- * reference solver does not serve it yet. */
344
+ /** The rfq_request for an arkade↔arkade swap. At least one side names an asset
345
+ * id (BTC has none), and the id is the leg itself — see
346
+ * {@link arkadeAssetLeg}.
347
+ *
348
+ * Wire-compatible with the reference solver (`AssetRfqRequest`, strict):
349
+ * `amount` is a canonical decimal string of atomic units (never a JSON
350
+ * number — an Arkade asset's precision is not knowable client-side, so the
351
+ * losslessness carve-out cannot be checked), `amount_side` is exact-in only
352
+ * (`"from"`), and `profile` carries the trader's own covenant position
353
+ * (`maker_pk_script`, `maker_public_key`) — the fill pays that script, and
354
+ * `cancel` is signed by that key. */
342
355
  declare const arkadeSwapRequest: (input: {
343
356
  rfqId: string;
344
357
  /** Asset the trader deposits; omit when depositing BTC. */
345
358
  offerAsset?: asset.AssetId;
346
359
  /** Asset the trader wants; omit when wanting BTC. */
347
360
  wantAsset?: asset.AssetId;
348
- amountSide: "from" | "to";
349
- /** Integer base units of the side named by `amountSide`. */
350
- amount: number;
361
+ /** Exact-in only. `"to"` is refused client-side: the solver answers
362
+ * `exact_out_unsupported`, since the two legs are different assets. */
363
+ amountSide?: "from" | "to";
364
+ /** Atomic units of the deposit (`from`) leg. bigint-safe: encoded as a
365
+ * canonical decimal string on the wire. */
366
+ amount: bigint | number | string;
367
+ /** Trader's own taproot scriptPubKey (34 bytes, `OP_1 <32-byte program>`),
368
+ * as bytes or lowercase hex. The covenant's `makerWP` minus its prefix. */
369
+ makerPkScript: Uint8Array | string;
370
+ /** Trader's own x-only key (32 bytes), as bytes or lowercase hex. The
371
+ * `cancel` path's `user` signer. */
372
+ makerPublicKey: Uint8Array | string;
351
373
  }) => Record<string, unknown>;
374
+ /** Canonical decimal string of atomic units: ASCII digits, no sign, point,
375
+ * exponent, or leading zero (unless the value is exactly "0"). bigint passes
376
+ * through; number must be a safe integer; string must already be canonical. */
377
+ declare const canonicalAssetAmount: (amount: bigint | number | string) => string;
378
+ /** 34-byte taproot scriptPubKey (`OP_1 <32-byte program>`), lowercase hex. */
379
+ declare const normalizeMakerPkScript: (value: Uint8Array | string) => string;
380
+ /** 32-byte x-only key, lowercase hex. Never a 33-byte compressed key. */
381
+ declare const normalizeMakerPublicKey: (value: Uint8Array | string) => string;
352
382
  /** Funding gate: refuse unless ≥90 min remain before the refund path opens.
353
383
  * 90 because the refund CLTV matures against median-time-past (BIP-113),
354
384
  * which lags wall clock by ~1h — a smaller wall-clock margin is no margin. */
@@ -502,6 +532,8 @@ declare function lightningSendVtxoScript(params: {
502
532
  * {@link unilateralRefundDelay} and {@link unilateralRefundWithoutReceiverDelay}
503
533
  * derive from this same value — one rounding, shared across all three tiers. */
504
534
  claimDelay: number;
535
+ /** Binding quote field. Optional only for rebuilding pre-upgrade scripts. */
536
+ refundWithoutReceiverDelay?: number;
505
537
  /** Emulator x-only key (32 bytes). */
506
538
  emulatorPubkey: Uint8Array;
507
539
  /** Where a refund must pay: the trader's P2TR pkScript (34 bytes). Also
@@ -619,6 +651,10 @@ declare function requestLightningSend(wallet: IWallet, arkServerUrl: string, tra
619
651
  * transaction that delivers the quoted want-amount to the trader, so the
620
652
  * solver fills or nothing moves. There is no rfq_fill message and no refund
621
653
  * timelock; an unfilled offer is cancelled cooperatively (`cancelOffer`).
654
+ *
655
+ * For asset-to-asset, the offer contract commits to the wanted asset only.
656
+ * The offered/deposit asset is carried by the funding VTXO and its asset
657
+ * packet; it is not part of the covenant derivation.
622
658
  */
623
659
  declare const offerTermsFromQuote: (quote: RfqQuote, assets: {
624
660
  wantAsset?: asset.AssetId;
@@ -628,6 +664,80 @@ declare const offerTermsFromQuote: (quote: RfqQuote, assets: {
628
664
  wantAsset?: asset.AssetId;
629
665
  offerAsset?: asset.AssetId;
630
666
  };
667
+ /** Compare-only check of the solver's offer address against YOUR OWN
668
+ * derivation — never extends trust, only narrows it. Funds only on an exact
669
+ * match of both the address (what the wallet sends to) and the script (what
670
+ * `offerVtxoScript` compiles to). Throws {@link AddressMismatch} otherwise. */
671
+ declare const verifyOfferAddress: (quote: RfqQuote, derived: {
672
+ address: string;
673
+ swapPkScript: Uint8Array;
674
+ }) => {
675
+ address: string;
676
+ swapPkScript: Uint8Array;
677
+ };
678
+ /** Gate an arkade↔arkade quote immediately before funding. No timelock exists
679
+ * on this class (neither `fulfill` nor `cancel` carries one), so the only
680
+ * clock is `valid_until`: funding after it is a deposit the solver will
681
+ * refuse to fill, reclaimable only via cooperative `cancelOffer`. */
682
+ declare const assertArkadeFundable: (input: {
683
+ quote: RfqQuote;
684
+ now?: number;
685
+ }) => void;
686
+ /**
687
+ * The arkade↔arkade user flow, mirroring `requestLightningSend`'s shape:
688
+ * quote → derive locally → verify → gate. Pure of funding on purpose — it
689
+ * returns the offer and the deposit it must carry, and the caller funds with
690
+ * its own wallet before `quote.valid_until`, after which the user may go
691
+ * offline: filling is non-interactive. An unfilled offer is cancelled
692
+ * cooperatively (`cancelOffer`); there is no timelock refund.
693
+ *
694
+ * Maker keys are the wallet's own (address script + identity x-only key), read
695
+ * here so the request profile and the local `createOffer` derivation cannot
696
+ * diverge. The quote's `offer_address`/`offer_pk_script` are compare-only:
697
+ * a mismatch throws {@link AddressMismatch} and must never be funded.
698
+ *
699
+ * Works over any {@link RfqTransport} — HTTP, dev relay, or Nostr — since the
700
+ * negotiation is one `rfq_request` round trip. Throws {@link SwapRefusal}
701
+ * (closed reason), {@link AddressMismatch} (never fund), or a gate error with
702
+ * a stable `reason`.
703
+ *
704
+ * Funding (caller's job, immediately after, before `valid_until`):
705
+ * - BTC->asset (`wantAsset`): `wallet.send({ address, amount: Number(fundAmount), extensions: [extension] })`
706
+ * - asset->BTC or asset->asset (`offerAsset`): `wallet.send({ address, amount: Number(carrierSats), assets: [{ assetId: offerAsset, amount: fundAmount }], extensions: [extension] })`
707
+ */
708
+ declare function requestArkadeSwap(wallet: IWallet, arkServerUrl: string, transport: RfqTransport, params: {
709
+ /** Asset the trader deposits; omit when depositing BTC. */
710
+ offerAsset?: asset.AssetId;
711
+ /** Asset the trader wants; omit when wanting BTC. */
712
+ wantAsset?: asset.AssetId;
713
+ /** Deposit amount, in atomic units of the `from` leg. */
714
+ amount: bigint | number | string;
715
+ rfqId?: string;
716
+ /** Co-signer key override (33-byte compressed hex); see `createOffer`. */
717
+ emulatorPubkey?: string;
718
+ now?: number;
719
+ }): Promise<{
720
+ rfqId: string;
721
+ quote: RfqQuote;
722
+ pair: string;
723
+ /** The trader's OWN derivation — the only address to fund. */
724
+ address: string;
725
+ /** What the deposit must carry: the quote's `from_amount`. Sats for a BTC
726
+ * deposit, asset units for an asset deposit (plus a dust carrier). */
727
+ fundAmount: bigint;
728
+ /** Dust sats carrier for an asset deposit; 0n for a BTC deposit. */
729
+ carrierSats: bigint;
730
+ /** The covenant's scriptPubKey, for watching the deposit and its spend. */
731
+ swapPkScript: Uint8Array;
732
+ /** The encoded offer. Persist this — it is the only input `cancelOffer`
733
+ * needs, and the restore scan reads it back off the funding tx. */
734
+ offerHex: string;
735
+ /** Ready for `wallet.send`'s `extensions`. */
736
+ extension: {
737
+ type: number;
738
+ payload: Uint8Array;
739
+ };
740
+ }>;
631
741
  /** The rfq_request for `arkade:BTC->onchain:BTC`. Exact-out means "this much
632
742
  * lands in the L1 HTLC". `senderPubkey` is the user's own key for the
633
743
  * VHTLC's sender-side leaves — same role as in {@link lightningSendRequest}.
@@ -724,6 +834,7 @@ declare function deriveOnchainSend(input: {
724
834
  refundLocktime: number;
725
835
  htlcLocktime: number;
726
836
  minConfirmations: number;
837
+ expectedAmount: number;
727
838
  };
728
839
  /**
729
840
  * The `arkade:BTC->onchain:BTC` user flow, mirroring `requestLightningSend`:
@@ -764,6 +875,8 @@ declare function requestOnchainSend(wallet: IWallet, arkServerUrl: string, trans
764
875
  /** The user's OWN arkade lockup derivation — the only address to fund. */
765
876
  address: string;
766
877
  fundAmount: number;
878
+ /** What the solver's L1 fill must carry — persist it with the record. */
879
+ expectedAmount: number;
767
880
  swapPkScript: Uint8Array;
768
881
  /** The arkade covenant itself — the record's `lockup` for
769
882
  * `RfqSwapManager`, same role as {@link requestLightningSend}'s. */
@@ -1081,4 +1194,4 @@ declare function requestOnchainReceive(wallet: IWallet, arkServerUrl: string, tr
1081
1194
  secrets: ProvisionedClaimSecret;
1082
1195
  }>;
1083
1196
 
1084
- export { extractPreimage as $, ARKADE_ASSET as A, type RfqRefusalDetail as B, type ChainSource as C, type RfqRefusalErrorCode as D, type RfqRefusalReason as E, type RfqRefusalUnit as F, type RfqStatus as G, type HtlcUtxo as H, type InvoiceFacts as I, SwapRefusal as J, arkadeAssetLeg as K, LIGHTNING_BTC as L, MAX_MIN_CONFIRMATIONS as M, arkadeSwapRequest as N, type OnchainNetwork as O, assertFundable as P, assertReceivable as Q, type RfqTransport as R, SOLO_REFUND_HEADROOM_SECONDS as S, awaitOnchainFill as T, buildHtlcClaim as U, buildHtlcRefund as V, claimOnchainFill as W, classifyOnchainHtlc as X, deriveLightningReceive as Y, deriveOnchainReceive as Z, deriveOnchainSend as _, type OnchainHtlc as a, httpTransport as a0, isRfqRefusalErrorCode as a1, l1ScriptForAddress as a2, lightningReceiveRequest as a3, lightningSendRequest as a4, lightningSendVtxoScript as a5, newPreimage as a6, newRfqId as a7, offerTermsFromQuote as a8, onchainHtlcScript as a9, onchainReceiveRequest as aa, onchainSendRequest as ab, paymentHashOf as ac, receiveVtxoScript as ad, relayTransport as ae, requestLightningReceive as af, requestOnchainReceive as ag, rfqPair as ah, unilateralClaimDelay as ai, unilateralRefundDelay as aj, unilateralRefundWithoutReceiverDelay as ak, verifyLockupAddress as al, verifyReceiveInvoice as am, type OnchainHtlcParams as b, requestLightningSend as c, ARKADE_BTC as d, AddressMismatch as e, type ChainUtxo as f, LIGHTNING_RECEIVE_PAIR as g, LIGHTNING_SEND_PAIR as h, LOCKTIME_THRESHOLD as i, type LightningReceiveTreeParams as j, type LightningSendTreeParams as k, MIN_CLAIM_WINDOW_SECONDS as l, MIN_HEADROOM_SECONDS as m, ONCHAIN_BTC as n, ONCHAIN_CLAIM_MARGIN_SECONDS as o, ONCHAIN_DUST_SATS as p, ONCHAIN_ORDER_MARGIN_SECONDS as q, requestOnchainSend as r, ONCHAIN_RECEIVE_PAIR as s, ONCHAIN_SECONDS_PER_BLOCK as t, ONCHAIN_SEND_PAIR as u, type OnchainHtlcPhase as v, RFQ_REFUSAL_ERROR_CODES as w, RFQ_TERMINAL_STATES as x, type RelaySocket as y, type RfqQuote as z };
1197
+ export { deriveOnchainReceive as $, ARKADE_ASSET as A, type RfqRefusalDetail as B, type ChainSource as C, type RfqRefusalErrorCode as D, type RfqRefusalReason as E, type RfqRefusalUnit as F, type RfqStatus as G, type HtlcUtxo as H, type InvoiceFacts as I, SwapRefusal as J, arkadeAssetLeg as K, LIGHTNING_BTC as L, MAX_MIN_CONFIRMATIONS as M, arkadeSwapRequest as N, type OnchainNetwork as O, assertArkadeFundable as P, assertFundable as Q, type RfqTransport as R, SOLO_REFUND_HEADROOM_SECONDS as S, assertReceivable as T, awaitOnchainFill as U, buildHtlcClaim as V, buildHtlcRefund as W, canonicalAssetAmount as X, claimOnchainFill as Y, classifyOnchainHtlc as Z, deriveLightningReceive as _, type OnchainHtlc as a, deriveOnchainSend as a0, extractPreimage as a1, httpTransport as a2, isRfqRefusalErrorCode as a3, l1ScriptForAddress as a4, lightningReceiveRequest as a5, lightningSendRequest as a6, lightningSendVtxoScript as a7, newPreimage as a8, newRfqId as a9, normalizeMakerPkScript as aa, normalizeMakerPublicKey as ab, offerTermsFromQuote as ac, onchainHtlcScript as ad, onchainReceiveRequest as ae, onchainSendRequest as af, paymentHashOf as ag, receiveVtxoScript as ah, relayTransport as ai, requestArkadeSwap as aj, requestLightningReceive as ak, requestOnchainReceive as al, rfqPair as am, unilateralClaimDelay as an, unilateralRefundDelay as ao, unilateralRefundWithoutReceiverDelay as ap, verifyLockupAddress as aq, verifyOfferAddress as ar, verifyReceiveInvoice as as, type OnchainHtlcParams as b, requestLightningSend as c, ARKADE_BTC as d, AddressMismatch as e, type ChainUtxo as f, LIGHTNING_RECEIVE_PAIR as g, LIGHTNING_SEND_PAIR as h, LOCKTIME_THRESHOLD as i, type LightningReceiveTreeParams as j, type LightningSendTreeParams as k, MIN_CLAIM_WINDOW_SECONDS as l, MIN_HEADROOM_SECONDS as m, ONCHAIN_BTC as n, ONCHAIN_CLAIM_MARGIN_SECONDS as o, ONCHAIN_DUST_SATS as p, ONCHAIN_ORDER_MARGIN_SECONDS as q, requestOnchainSend as r, ONCHAIN_RECEIVE_PAIR as s, ONCHAIN_SECONDS_PER_BLOCK as t, ONCHAIN_SEND_PAIR as u, type OnchainHtlcPhase as v, RFQ_REFUSAL_ERROR_CODES as w, RFQ_TERMINAL_STATES as x, type RelaySocket as y, type RfqQuote as z };
@@ -298,8 +298,11 @@ interface RfqQuote {
298
298
  type: "rfq_quote";
299
299
  rfq_id: string;
300
300
  pair: string;
301
- from_amount: number;
302
- to_amount: number;
301
+ /** Sats on HTLC-class corridors (number); canonical decimal string on
302
+ * arkade↔arkade asset legs (bigint range, see WIRE_ASSET_AMOUNT on the
303
+ * solver). */
304
+ from_amount: number | string;
305
+ to_amount: number | string;
303
306
  solver_pubkey: string;
304
307
  valid_until: number;
305
308
  /** HTLC-class quotes only; absent for arkade↔arkade. */
@@ -308,6 +311,9 @@ interface RfqQuote {
308
311
  [key: string]: unknown;
309
312
  payment_hash?: string;
310
313
  lockup_address?: string;
314
+ refund_without_receiver_delay?: number;
315
+ offer_address?: string;
316
+ offer_pk_script?: string;
311
317
  };
312
318
  [key: string]: unknown;
313
319
  }
@@ -335,20 +341,44 @@ declare const lightningSendRequest: (input: {
335
341
  refundAddress: string;
336
342
  senderPubkey: Uint8Array;
337
343
  }) => Record<string, unknown>;
338
- /** The rfq_request for an arkade↔arkade swap. Exactly one side may name an
339
- * asset id per direction (BTC has none), and the id is the leg itself — see
340
- * {@link arkadeAssetLeg}. Forward-looking: the wire shape is specified, the
341
- * reference solver does not serve it yet. */
344
+ /** The rfq_request for an arkade↔arkade swap. At least one side names an asset
345
+ * id (BTC has none), and the id is the leg itself — see
346
+ * {@link arkadeAssetLeg}.
347
+ *
348
+ * Wire-compatible with the reference solver (`AssetRfqRequest`, strict):
349
+ * `amount` is a canonical decimal string of atomic units (never a JSON
350
+ * number — an Arkade asset's precision is not knowable client-side, so the
351
+ * losslessness carve-out cannot be checked), `amount_side` is exact-in only
352
+ * (`"from"`), and `profile` carries the trader's own covenant position
353
+ * (`maker_pk_script`, `maker_public_key`) — the fill pays that script, and
354
+ * `cancel` is signed by that key. */
342
355
  declare const arkadeSwapRequest: (input: {
343
356
  rfqId: string;
344
357
  /** Asset the trader deposits; omit when depositing BTC. */
345
358
  offerAsset?: asset.AssetId;
346
359
  /** Asset the trader wants; omit when wanting BTC. */
347
360
  wantAsset?: asset.AssetId;
348
- amountSide: "from" | "to";
349
- /** Integer base units of the side named by `amountSide`. */
350
- amount: number;
361
+ /** Exact-in only. `"to"` is refused client-side: the solver answers
362
+ * `exact_out_unsupported`, since the two legs are different assets. */
363
+ amountSide?: "from" | "to";
364
+ /** Atomic units of the deposit (`from`) leg. bigint-safe: encoded as a
365
+ * canonical decimal string on the wire. */
366
+ amount: bigint | number | string;
367
+ /** Trader's own taproot scriptPubKey (34 bytes, `OP_1 <32-byte program>`),
368
+ * as bytes or lowercase hex. The covenant's `makerWP` minus its prefix. */
369
+ makerPkScript: Uint8Array | string;
370
+ /** Trader's own x-only key (32 bytes), as bytes or lowercase hex. The
371
+ * `cancel` path's `user` signer. */
372
+ makerPublicKey: Uint8Array | string;
351
373
  }) => Record<string, unknown>;
374
+ /** Canonical decimal string of atomic units: ASCII digits, no sign, point,
375
+ * exponent, or leading zero (unless the value is exactly "0"). bigint passes
376
+ * through; number must be a safe integer; string must already be canonical. */
377
+ declare const canonicalAssetAmount: (amount: bigint | number | string) => string;
378
+ /** 34-byte taproot scriptPubKey (`OP_1 <32-byte program>`), lowercase hex. */
379
+ declare const normalizeMakerPkScript: (value: Uint8Array | string) => string;
380
+ /** 32-byte x-only key, lowercase hex. Never a 33-byte compressed key. */
381
+ declare const normalizeMakerPublicKey: (value: Uint8Array | string) => string;
352
382
  /** Funding gate: refuse unless ≥90 min remain before the refund path opens.
353
383
  * 90 because the refund CLTV matures against median-time-past (BIP-113),
354
384
  * which lags wall clock by ~1h — a smaller wall-clock margin is no margin. */
@@ -502,6 +532,8 @@ declare function lightningSendVtxoScript(params: {
502
532
  * {@link unilateralRefundDelay} and {@link unilateralRefundWithoutReceiverDelay}
503
533
  * derive from this same value — one rounding, shared across all three tiers. */
504
534
  claimDelay: number;
535
+ /** Binding quote field. Optional only for rebuilding pre-upgrade scripts. */
536
+ refundWithoutReceiverDelay?: number;
505
537
  /** Emulator x-only key (32 bytes). */
506
538
  emulatorPubkey: Uint8Array;
507
539
  /** Where a refund must pay: the trader's P2TR pkScript (34 bytes). Also
@@ -619,6 +651,10 @@ declare function requestLightningSend(wallet: IWallet, arkServerUrl: string, tra
619
651
  * transaction that delivers the quoted want-amount to the trader, so the
620
652
  * solver fills or nothing moves. There is no rfq_fill message and no refund
621
653
  * timelock; an unfilled offer is cancelled cooperatively (`cancelOffer`).
654
+ *
655
+ * For asset-to-asset, the offer contract commits to the wanted asset only.
656
+ * The offered/deposit asset is carried by the funding VTXO and its asset
657
+ * packet; it is not part of the covenant derivation.
622
658
  */
623
659
  declare const offerTermsFromQuote: (quote: RfqQuote, assets: {
624
660
  wantAsset?: asset.AssetId;
@@ -628,6 +664,80 @@ declare const offerTermsFromQuote: (quote: RfqQuote, assets: {
628
664
  wantAsset?: asset.AssetId;
629
665
  offerAsset?: asset.AssetId;
630
666
  };
667
+ /** Compare-only check of the solver's offer address against YOUR OWN
668
+ * derivation — never extends trust, only narrows it. Funds only on an exact
669
+ * match of both the address (what the wallet sends to) and the script (what
670
+ * `offerVtxoScript` compiles to). Throws {@link AddressMismatch} otherwise. */
671
+ declare const verifyOfferAddress: (quote: RfqQuote, derived: {
672
+ address: string;
673
+ swapPkScript: Uint8Array;
674
+ }) => {
675
+ address: string;
676
+ swapPkScript: Uint8Array;
677
+ };
678
+ /** Gate an arkade↔arkade quote immediately before funding. No timelock exists
679
+ * on this class (neither `fulfill` nor `cancel` carries one), so the only
680
+ * clock is `valid_until`: funding after it is a deposit the solver will
681
+ * refuse to fill, reclaimable only via cooperative `cancelOffer`. */
682
+ declare const assertArkadeFundable: (input: {
683
+ quote: RfqQuote;
684
+ now?: number;
685
+ }) => void;
686
+ /**
687
+ * The arkade↔arkade user flow, mirroring `requestLightningSend`'s shape:
688
+ * quote → derive locally → verify → gate. Pure of funding on purpose — it
689
+ * returns the offer and the deposit it must carry, and the caller funds with
690
+ * its own wallet before `quote.valid_until`, after which the user may go
691
+ * offline: filling is non-interactive. An unfilled offer is cancelled
692
+ * cooperatively (`cancelOffer`); there is no timelock refund.
693
+ *
694
+ * Maker keys are the wallet's own (address script + identity x-only key), read
695
+ * here so the request profile and the local `createOffer` derivation cannot
696
+ * diverge. The quote's `offer_address`/`offer_pk_script` are compare-only:
697
+ * a mismatch throws {@link AddressMismatch} and must never be funded.
698
+ *
699
+ * Works over any {@link RfqTransport} — HTTP, dev relay, or Nostr — since the
700
+ * negotiation is one `rfq_request` round trip. Throws {@link SwapRefusal}
701
+ * (closed reason), {@link AddressMismatch} (never fund), or a gate error with
702
+ * a stable `reason`.
703
+ *
704
+ * Funding (caller's job, immediately after, before `valid_until`):
705
+ * - BTC->asset (`wantAsset`): `wallet.send({ address, amount: Number(fundAmount), extensions: [extension] })`
706
+ * - asset->BTC or asset->asset (`offerAsset`): `wallet.send({ address, amount: Number(carrierSats), assets: [{ assetId: offerAsset, amount: fundAmount }], extensions: [extension] })`
707
+ */
708
+ declare function requestArkadeSwap(wallet: IWallet, arkServerUrl: string, transport: RfqTransport, params: {
709
+ /** Asset the trader deposits; omit when depositing BTC. */
710
+ offerAsset?: asset.AssetId;
711
+ /** Asset the trader wants; omit when wanting BTC. */
712
+ wantAsset?: asset.AssetId;
713
+ /** Deposit amount, in atomic units of the `from` leg. */
714
+ amount: bigint | number | string;
715
+ rfqId?: string;
716
+ /** Co-signer key override (33-byte compressed hex); see `createOffer`. */
717
+ emulatorPubkey?: string;
718
+ now?: number;
719
+ }): Promise<{
720
+ rfqId: string;
721
+ quote: RfqQuote;
722
+ pair: string;
723
+ /** The trader's OWN derivation — the only address to fund. */
724
+ address: string;
725
+ /** What the deposit must carry: the quote's `from_amount`. Sats for a BTC
726
+ * deposit, asset units for an asset deposit (plus a dust carrier). */
727
+ fundAmount: bigint;
728
+ /** Dust sats carrier for an asset deposit; 0n for a BTC deposit. */
729
+ carrierSats: bigint;
730
+ /** The covenant's scriptPubKey, for watching the deposit and its spend. */
731
+ swapPkScript: Uint8Array;
732
+ /** The encoded offer. Persist this — it is the only input `cancelOffer`
733
+ * needs, and the restore scan reads it back off the funding tx. */
734
+ offerHex: string;
735
+ /** Ready for `wallet.send`'s `extensions`. */
736
+ extension: {
737
+ type: number;
738
+ payload: Uint8Array;
739
+ };
740
+ }>;
631
741
  /** The rfq_request for `arkade:BTC->onchain:BTC`. Exact-out means "this much
632
742
  * lands in the L1 HTLC". `senderPubkey` is the user's own key for the
633
743
  * VHTLC's sender-side leaves — same role as in {@link lightningSendRequest}.
@@ -724,6 +834,7 @@ declare function deriveOnchainSend(input: {
724
834
  refundLocktime: number;
725
835
  htlcLocktime: number;
726
836
  minConfirmations: number;
837
+ expectedAmount: number;
727
838
  };
728
839
  /**
729
840
  * The `arkade:BTC->onchain:BTC` user flow, mirroring `requestLightningSend`:
@@ -764,6 +875,8 @@ declare function requestOnchainSend(wallet: IWallet, arkServerUrl: string, trans
764
875
  /** The user's OWN arkade lockup derivation — the only address to fund. */
765
876
  address: string;
766
877
  fundAmount: number;
878
+ /** What the solver's L1 fill must carry — persist it with the record. */
879
+ expectedAmount: number;
767
880
  swapPkScript: Uint8Array;
768
881
  /** The arkade covenant itself — the record's `lockup` for
769
882
  * `RfqSwapManager`, same role as {@link requestLightningSend}'s. */
@@ -1081,4 +1194,4 @@ declare function requestOnchainReceive(wallet: IWallet, arkServerUrl: string, tr
1081
1194
  secrets: ProvisionedClaimSecret;
1082
1195
  }>;
1083
1196
 
1084
- export { extractPreimage as $, ARKADE_ASSET as A, type RfqRefusalDetail as B, type ChainSource as C, type RfqRefusalErrorCode as D, type RfqRefusalReason as E, type RfqRefusalUnit as F, type RfqStatus as G, type HtlcUtxo as H, type InvoiceFacts as I, SwapRefusal as J, arkadeAssetLeg as K, LIGHTNING_BTC as L, MAX_MIN_CONFIRMATIONS as M, arkadeSwapRequest as N, type OnchainNetwork as O, assertFundable as P, assertReceivable as Q, type RfqTransport as R, SOLO_REFUND_HEADROOM_SECONDS as S, awaitOnchainFill as T, buildHtlcClaim as U, buildHtlcRefund as V, claimOnchainFill as W, classifyOnchainHtlc as X, deriveLightningReceive as Y, deriveOnchainReceive as Z, deriveOnchainSend as _, type OnchainHtlc as a, httpTransport as a0, isRfqRefusalErrorCode as a1, l1ScriptForAddress as a2, lightningReceiveRequest as a3, lightningSendRequest as a4, lightningSendVtxoScript as a5, newPreimage as a6, newRfqId as a7, offerTermsFromQuote as a8, onchainHtlcScript as a9, onchainReceiveRequest as aa, onchainSendRequest as ab, paymentHashOf as ac, receiveVtxoScript as ad, relayTransport as ae, requestLightningReceive as af, requestOnchainReceive as ag, rfqPair as ah, unilateralClaimDelay as ai, unilateralRefundDelay as aj, unilateralRefundWithoutReceiverDelay as ak, verifyLockupAddress as al, verifyReceiveInvoice as am, type OnchainHtlcParams as b, requestLightningSend as c, ARKADE_BTC as d, AddressMismatch as e, type ChainUtxo as f, LIGHTNING_RECEIVE_PAIR as g, LIGHTNING_SEND_PAIR as h, LOCKTIME_THRESHOLD as i, type LightningReceiveTreeParams as j, type LightningSendTreeParams as k, MIN_CLAIM_WINDOW_SECONDS as l, MIN_HEADROOM_SECONDS as m, ONCHAIN_BTC as n, ONCHAIN_CLAIM_MARGIN_SECONDS as o, ONCHAIN_DUST_SATS as p, ONCHAIN_ORDER_MARGIN_SECONDS as q, requestOnchainSend as r, ONCHAIN_RECEIVE_PAIR as s, ONCHAIN_SECONDS_PER_BLOCK as t, ONCHAIN_SEND_PAIR as u, type OnchainHtlcPhase as v, RFQ_REFUSAL_ERROR_CODES as w, RFQ_TERMINAL_STATES as x, type RelaySocket as y, type RfqQuote as z };
1197
+ export { deriveOnchainReceive as $, ARKADE_ASSET as A, type RfqRefusalDetail as B, type ChainSource as C, type RfqRefusalErrorCode as D, type RfqRefusalReason as E, type RfqRefusalUnit as F, type RfqStatus as G, type HtlcUtxo as H, type InvoiceFacts as I, SwapRefusal as J, arkadeAssetLeg as K, LIGHTNING_BTC as L, MAX_MIN_CONFIRMATIONS as M, arkadeSwapRequest as N, type OnchainNetwork as O, assertArkadeFundable as P, assertFundable as Q, type RfqTransport as R, SOLO_REFUND_HEADROOM_SECONDS as S, assertReceivable as T, awaitOnchainFill as U, buildHtlcClaim as V, buildHtlcRefund as W, canonicalAssetAmount as X, claimOnchainFill as Y, classifyOnchainHtlc as Z, deriveLightningReceive as _, type OnchainHtlc as a, deriveOnchainSend as a0, extractPreimage as a1, httpTransport as a2, isRfqRefusalErrorCode as a3, l1ScriptForAddress as a4, lightningReceiveRequest as a5, lightningSendRequest as a6, lightningSendVtxoScript as a7, newPreimage as a8, newRfqId as a9, normalizeMakerPkScript as aa, normalizeMakerPublicKey as ab, offerTermsFromQuote as ac, onchainHtlcScript as ad, onchainReceiveRequest as ae, onchainSendRequest as af, paymentHashOf as ag, receiveVtxoScript as ah, relayTransport as ai, requestArkadeSwap as aj, requestLightningReceive as ak, requestOnchainReceive as al, rfqPair as am, unilateralClaimDelay as an, unilateralRefundDelay as ao, unilateralRefundWithoutReceiverDelay as ap, verifyLockupAddress as aq, verifyOfferAddress as ar, verifyReceiveInvoice as as, type OnchainHtlcParams as b, requestLightningSend as c, ARKADE_BTC as d, AddressMismatch as e, type ChainUtxo as f, LIGHTNING_RECEIVE_PAIR as g, LIGHTNING_SEND_PAIR as h, LOCKTIME_THRESHOLD as i, type LightningReceiveTreeParams as j, type LightningSendTreeParams as k, MIN_CLAIM_WINDOW_SECONDS as l, MIN_HEADROOM_SECONDS as m, ONCHAIN_BTC as n, ONCHAIN_CLAIM_MARGIN_SECONDS as o, ONCHAIN_DUST_SATS as p, ONCHAIN_ORDER_MARGIN_SECONDS as q, requestOnchainSend as r, ONCHAIN_RECEIVE_PAIR as s, ONCHAIN_SECONDS_PER_BLOCK as t, ONCHAIN_SEND_PAIR as u, type OnchainHtlcPhase as v, RFQ_REFUSAL_ERROR_CODES as w, RFQ_TERMINAL_STATES as x, type RelaySocket as y, type RfqQuote as z };