@arkade-os/swap 0.0.19 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1283,11 +1283,6 @@ var arkadeSwapRequest = (input) => {
1283
1283
  "set at least one of wantAsset or offerAsset \u2014 with neither set both legs are BTC, which is not a swap"
1284
1284
  );
1285
1285
  }
1286
- if (input.amountSide !== void 0 && input.amountSide !== "from") {
1287
- throw new Error(
1288
- 'arkade\u2194arkade quotes are exact-in only: use amountSide "from" with the deposit amount'
1289
- );
1290
- }
1291
1286
  const pair = rfqPair(
1292
1287
  input.offerAsset ? arkadeAssetLeg(input.offerAsset) : ARKADE_BTC,
1293
1288
  input.wantAsset ? arkadeAssetLeg(input.wantAsset) : ARKADE_BTC
@@ -1298,7 +1293,7 @@ var arkadeSwapRequest = (input) => {
1298
1293
  type: "rfq_request",
1299
1294
  rfq_id: input.rfqId,
1300
1295
  pair,
1301
- amount_side: "from",
1296
+ amount_side: input.amountSide ?? "from",
1302
1297
  amount: canonicalAssetAmount(input.amount),
1303
1298
  // The pair names the assets; the profile names the trader. Both are
1304
1299
  // covenant parameters, and the solver's `.strict()` schema refuses
@@ -1766,11 +1761,16 @@ var assertArkadeFundable = (input) => {
1766
1761
  throw gateError("quote_expired", "quote carries a non-positive amount");
1767
1762
  }
1768
1763
  };
1764
+ var quoteCarrierSats = (quote) => {
1765
+ const published = quote.carrier_sats === void 0 ? 0n : BigInt(quote.carrier_sats);
1766
+ return published > 0n ? published : ASSET_CARRIER_SATS;
1767
+ };
1769
1768
  async function requestArkadeSwap(wallet, arkServerUrl, transport, params) {
1770
1769
  if (!params.wantAsset && !params.offerAsset) {
1771
1770
  throw new Error("set at least one of wantAsset or offerAsset; BTC-to-BTC is not a swap");
1772
1771
  }
1773
1772
  const rfqId = params.rfqId ?? newRfqId();
1773
+ const amountSide = params.amountSide ?? "from";
1774
1774
  const [makerAddress, makerPublicKey] = await Promise.all([
1775
1775
  wallet.getAddress(),
1776
1776
  wallet.identity.xOnlyPublicKey()
@@ -1786,6 +1786,7 @@ async function requestArkadeSwap(wallet, arkServerUrl, transport, params) {
1786
1786
  ...params.offerAsset !== void 0 ? { offerAsset: params.offerAsset } : {},
1787
1787
  ...params.wantAsset !== void 0 ? { wantAsset: params.wantAsset } : {},
1788
1788
  amount: params.amount,
1789
+ amountSide,
1789
1790
  makerPkScript,
1790
1791
  makerPublicKey
1791
1792
  })
@@ -1798,11 +1799,30 @@ async function requestArkadeSwap(wallet, arkServerUrl, transport, params) {
1798
1799
  ...params.offerAsset !== void 0 ? { offerAsset: params.offerAsset } : {},
1799
1800
  ...params.wantAsset !== void 0 ? { wantAsset: params.wantAsset } : {}
1800
1801
  });
1801
- if (BigInt(quote.from_amount).toString() !== canonicalAssetAmount(params.amount)) {
1802
+ const quoted = amountSide === "from" ? quote.from_amount : quote.to_amount;
1803
+ if (BigInt(quoted).toString() !== canonicalAssetAmount(params.amount)) {
1802
1804
  throw new Error(
1803
- `quote from_amount ${quote.from_amount} does not match the requested ${canonicalAssetAmount(params.amount)}`
1805
+ `quote ${amountSide}_amount ${quoted} does not match the requested ${canonicalAssetAmount(params.amount)}`
1804
1806
  );
1805
1807
  }
1808
+ if (params.maxFromAmount !== void 0) {
1809
+ const cap = BigInt(canonicalAssetAmount(params.maxFromAmount));
1810
+ if (BigInt(quote.from_amount) > cap) {
1811
+ throw gateError(
1812
+ "quote_amount_rejected",
1813
+ `quote from_amount ${quote.from_amount} exceeds maxFromAmount ${cap}`
1814
+ );
1815
+ }
1816
+ }
1817
+ if (params.minToAmount !== void 0) {
1818
+ const floorAmount = BigInt(canonicalAssetAmount(params.minToAmount));
1819
+ if (BigInt(quote.to_amount) < floorAmount) {
1820
+ throw gateError(
1821
+ "quote_amount_rejected",
1822
+ `quote to_amount ${quote.to_amount} is under minToAmount ${floorAmount}`
1823
+ );
1824
+ }
1825
+ }
1806
1826
  const offer = await createOffer(wallet, arkServerUrl, {
1807
1827
  wantAmount: terms.wantAmount,
1808
1828
  ...terms.wantAsset !== void 0 ? { wantAsset: terms.wantAsset } : {},
@@ -1817,7 +1837,7 @@ async function requestArkadeSwap(wallet, arkServerUrl, transport, params) {
1817
1837
  pair,
1818
1838
  address: offer.address,
1819
1839
  fundAmount,
1820
- carrierSats: params.offerAsset !== void 0 ? ASSET_CARRIER_SATS : 0n,
1840
+ carrierSats: params.offerAsset !== void 0 ? quoteCarrierSats(quote) : 0n,
1821
1841
  swapPkScript: offer.swapPkScript,
1822
1842
  offerHex: offer.offerHex,
1823
1843
  extension: offer.extension
package/dist/index.cjs CHANGED
@@ -2555,11 +2555,6 @@ var arkadeSwapRequest = (input) => {
2555
2555
  "set at least one of wantAsset or offerAsset \u2014 with neither set both legs are BTC, which is not a swap"
2556
2556
  );
2557
2557
  }
2558
- if (input.amountSide !== void 0 && input.amountSide !== "from") {
2559
- throw new Error(
2560
- 'arkade\u2194arkade quotes are exact-in only: use amountSide "from" with the deposit amount'
2561
- );
2562
- }
2563
2558
  const pair = rfqPair(
2564
2559
  input.offerAsset ? arkadeAssetLeg(input.offerAsset) : ARKADE_BTC,
2565
2560
  input.wantAsset ? arkadeAssetLeg(input.wantAsset) : ARKADE_BTC
@@ -2570,7 +2565,7 @@ var arkadeSwapRequest = (input) => {
2570
2565
  type: "rfq_request",
2571
2566
  rfq_id: input.rfqId,
2572
2567
  pair,
2573
- amount_side: "from",
2568
+ amount_side: input.amountSide ?? "from",
2574
2569
  amount: canonicalAssetAmount(input.amount),
2575
2570
  // The pair names the assets; the profile names the trader. Both are
2576
2571
  // covenant parameters, and the solver's `.strict()` schema refuses
@@ -3038,11 +3033,16 @@ var assertArkadeFundable = (input) => {
3038
3033
  throw gateError("quote_expired", "quote carries a non-positive amount");
3039
3034
  }
3040
3035
  };
3036
+ var quoteCarrierSats = (quote) => {
3037
+ const published = quote.carrier_sats === void 0 ? 0n : BigInt(quote.carrier_sats);
3038
+ return published > 0n ? published : ASSET_CARRIER_SATS;
3039
+ };
3041
3040
  async function requestArkadeSwap(wallet, arkServerUrl, transport, params) {
3042
3041
  if (!params.wantAsset && !params.offerAsset) {
3043
3042
  throw new Error("set at least one of wantAsset or offerAsset; BTC-to-BTC is not a swap");
3044
3043
  }
3045
3044
  const rfqId = params.rfqId ?? newRfqId();
3045
+ const amountSide = params.amountSide ?? "from";
3046
3046
  const [makerAddress, makerPublicKey] = await Promise.all([
3047
3047
  wallet.getAddress(),
3048
3048
  wallet.identity.xOnlyPublicKey()
@@ -3058,6 +3058,7 @@ async function requestArkadeSwap(wallet, arkServerUrl, transport, params) {
3058
3058
  ...params.offerAsset !== void 0 ? { offerAsset: params.offerAsset } : {},
3059
3059
  ...params.wantAsset !== void 0 ? { wantAsset: params.wantAsset } : {},
3060
3060
  amount: params.amount,
3061
+ amountSide,
3061
3062
  makerPkScript,
3062
3063
  makerPublicKey
3063
3064
  })
@@ -3070,11 +3071,30 @@ async function requestArkadeSwap(wallet, arkServerUrl, transport, params) {
3070
3071
  ...params.offerAsset !== void 0 ? { offerAsset: params.offerAsset } : {},
3071
3072
  ...params.wantAsset !== void 0 ? { wantAsset: params.wantAsset } : {}
3072
3073
  });
3073
- if (BigInt(quote.from_amount).toString() !== canonicalAssetAmount(params.amount)) {
3074
+ const quoted = amountSide === "from" ? quote.from_amount : quote.to_amount;
3075
+ if (BigInt(quoted).toString() !== canonicalAssetAmount(params.amount)) {
3074
3076
  throw new Error(
3075
- `quote from_amount ${quote.from_amount} does not match the requested ${canonicalAssetAmount(params.amount)}`
3077
+ `quote ${amountSide}_amount ${quoted} does not match the requested ${canonicalAssetAmount(params.amount)}`
3076
3078
  );
3077
3079
  }
3080
+ if (params.maxFromAmount !== void 0) {
3081
+ const cap = BigInt(canonicalAssetAmount(params.maxFromAmount));
3082
+ if (BigInt(quote.from_amount) > cap) {
3083
+ throw gateError(
3084
+ "quote_amount_rejected",
3085
+ `quote from_amount ${quote.from_amount} exceeds maxFromAmount ${cap}`
3086
+ );
3087
+ }
3088
+ }
3089
+ if (params.minToAmount !== void 0) {
3090
+ const floorAmount = BigInt(canonicalAssetAmount(params.minToAmount));
3091
+ if (BigInt(quote.to_amount) < floorAmount) {
3092
+ throw gateError(
3093
+ "quote_amount_rejected",
3094
+ `quote to_amount ${quote.to_amount} is under minToAmount ${floorAmount}`
3095
+ );
3096
+ }
3097
+ }
3078
3098
  const offer = await createOffer(wallet, arkServerUrl, {
3079
3099
  wantAmount: terms.wantAmount,
3080
3100
  ...terms.wantAsset !== void 0 ? { wantAsset: terms.wantAsset } : {},
@@ -3089,7 +3109,7 @@ async function requestArkadeSwap(wallet, arkServerUrl, transport, params) {
3089
3109
  pair,
3090
3110
  address: offer.address,
3091
3111
  fundAmount,
3092
- carrierSats: params.offerAsset !== void 0 ? ASSET_CARRIER_SATS : 0n,
3112
+ carrierSats: params.offerAsset !== void 0 ? quoteCarrierSats(quote) : 0n,
3093
3113
  swapPkScript: offer.swapPkScript,
3094
3114
  offerHex: offer.offerHex,
3095
3115
  extension: offer.extension
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-BXIcmIIC.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-BXIcmIIC.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-Cop29z0c.cjs';
3
+ export { h as AssetSwapStatus, i as AvailableRfqSwapManagerCallbacks, B as BTC_ASSET_ID, I as InMemoryAssetSwapRepository, j as LightningReceiveSwap, k as LightningSendSwap, l as LockupFate, m as LockupNeedsRecoveryError, n as LockupParams, o as LockupSpend, O as OnchainSendAction, p as OnchainSendSwap, P as PersistableRfqSwap, q as PreimageBlockedReason, r as PreimageNotRecoverableError, s as REFUND_MTP_LAG_SECONDS, t as RFQ_RESOLVED_STATES, u as RFQ_SWAP_RETENTION_SECONDS, v as RFQ_SWAP_TERMINAL_STATES, w as RefundOutcome, x as RfqRestoreFailure, y as RfqRestoreOptions, z as RfqRestoreResult, C as RfqSwapActionName, D as RfqSwapLockup, E as RfqSwapManager, F as RfqSwapManagerCallbacks, G as RfqSwapManagerConfig, H as RfqSwapManagerDeps, J as RfqSwapManagerEvents, K as RfqSwapOrigin, N as RfqSwapOriginRequired, Q as RfqSwapOutcome, T as RfqSwapRecordStore, U as SwapContractRegistry, V as addAssetSwap, W as awaitRfqResolution, X as createRfqSwapRecord, Y as findLockupVtxos, Z as getAssetSwaps, _ as getAssetSwapsOrThrow, $ as isRfqSwapTerminal, a0 as isRfqTerminal, a1 as nextOnchainAction, a2 as preimageForSwapRecord, a3 as pushRefundWithoutReceiver, a4 as readLockupFate, a5 as rebuildRfqSwap, a6 as refundIfUnresolved, a7 as rfqSwapOriginOf, a8 as shouldRetainRfqSwap, a9 as swapSecretsToRecord, aa as updateAssetSwap, ab as updateAssetSwapBestEffort, ac as updateRfqSwapRecord } from './repository-Cop29z0c.cjs';
4
4
  import { Network, LocalCardInput, DiscoveredMarket, Side, OfferPlan } from '@arkade-os/solver-discovery';
5
- import { O as OnchainNetwork, a as OnchainHtlc, b as OnchainHtlcParams, C as ChainSource, R as RfqTransport, r as requestOnchainSend, I as InvoiceFacts, c as requestLightningSend } from './rfq-D96aLvCA.cjs';
6
- export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, f as ChainUtxo, H as HtlcUtxo, L as LIGHTNING_BTC, g as LIGHTNING_RECEIVE_PAIR, h as LIGHTNING_SEND_PAIR, i as LOCKTIME_THRESHOLD, j as LightningReceiveTreeParams, k as LightningSendTreeParams, M as MAX_MIN_CONFIRMATIONS, l as MIN_CLAIM_WINDOW_SECONDS, m as MIN_HEADROOM_SECONDS, n as ONCHAIN_BTC, o as ONCHAIN_CLAIM_MARGIN_SECONDS, p as ONCHAIN_DUST_SATS, q as ONCHAIN_ORDER_MARGIN_SECONDS, s as ONCHAIN_RECEIVE_PAIR, t as ONCHAIN_SECONDS_PER_BLOCK, u as ONCHAIN_SEND_PAIR, v as OnchainHtlcPhase, w as RFQ_REFUSAL_ERROR_CODES, x as RFQ_TERMINAL_STATES, y as RelaySocket, z as RfqQuote, B as RfqRefusalDetail, D as RfqRefusalErrorCode, E as RfqRefusalReason, F as RfqRefusalUnit, G as RfqStatus, S as SOLO_REFUND_HEADROOM_SECONDS, J as SwapRefusal, K as arkadeAssetLeg, N as arkadeSwapRequest, P as assertArkadeFundable, Q as assertFundable, T as assertReceivable, U as awaitOnchainFill, V as buildHtlcClaim, W as buildHtlcRefund, X as canonicalAssetAmount, Y as claimOnchainFill, Z as classifyOnchainHtlc, _ as deriveLightningReceive, $ as deriveOnchainReceive, a0 as deriveOnchainSend, a1 as extractPreimage, a2 as httpTransport, a3 as isRfqRefusalErrorCode, a4 as l1ScriptForAddress, a5 as lightningReceiveRequest, a6 as lightningSendRequest, a7 as lightningSendVtxoScript, a8 as newPreimage, a9 as newRfqId, aa as normalizeMakerPkScript, ab as normalizeMakerPublicKey, ac as offerTermsFromQuote, ad as onchainHtlcScript, ae as onchainReceiveRequest, af as onchainSendRequest, ag as paymentHashOf, ah as receiveVtxoScript, ai as relayTransport, aj as requestArkadeSwap, ak as requestLightningReceive, al as requestOnchainReceive, am as rfqPair, an as unilateralClaimDelay, ao as unilateralRefundDelay, ap as unilateralRefundWithoutReceiverDelay, aq as verifyLockupAddress, ar as verifyOfferAddress, as as verifyReceiveInvoice } from './rfq-D96aLvCA.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-B95nPfaa.cjs';
6
+ export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, f as ChainUtxo, H as HtlcUtxo, L as LIGHTNING_BTC, g as LIGHTNING_RECEIVE_PAIR, h as LIGHTNING_SEND_PAIR, i as LOCKTIME_THRESHOLD, j as LightningReceiveTreeParams, k as LightningSendTreeParams, M as MAX_MIN_CONFIRMATIONS, l as MIN_CLAIM_WINDOW_SECONDS, m as MIN_HEADROOM_SECONDS, n as ONCHAIN_BTC, o as ONCHAIN_CLAIM_MARGIN_SECONDS, p as ONCHAIN_DUST_SATS, q as ONCHAIN_ORDER_MARGIN_SECONDS, s as ONCHAIN_RECEIVE_PAIR, t as ONCHAIN_SECONDS_PER_BLOCK, u as ONCHAIN_SEND_PAIR, v as OnchainHtlcPhase, w as RFQ_REFUSAL_ERROR_CODES, x as RFQ_TERMINAL_STATES, y as RelaySocket, z as RfqQuote, B as RfqRefusalDetail, D as RfqRefusalErrorCode, E as RfqRefusalReason, F as RfqRefusalUnit, G as RfqStatus, S as SOLO_REFUND_HEADROOM_SECONDS, J as SwapRefusal, K as arkadeAssetLeg, N as arkadeSwapRequest, P as assertArkadeFundable, Q as assertFundable, T as assertReceivable, U as awaitOnchainFill, V as buildHtlcClaim, W as buildHtlcRefund, X as canonicalAssetAmount, Y as claimOnchainFill, Z as classifyOnchainHtlc, _ as deriveLightningReceive, $ as deriveOnchainReceive, a0 as deriveOnchainSend, a1 as extractPreimage, a2 as httpTransport, a3 as isRfqRefusalErrorCode, a4 as l1ScriptForAddress, a5 as lightningReceiveRequest, a6 as lightningSendRequest, a7 as lightningSendVtxoScript, a8 as newPreimage, a9 as newRfqId, aa as normalizeMakerPkScript, ab as normalizeMakerPublicKey, ac as offerTermsFromQuote, ad as onchainHtlcScript, ae as onchainReceiveRequest, af as onchainSendRequest, ag as paymentHashOf, ah as receiveVtxoScript, ai as relayTransport, aj as requestArkadeSwap, ak as requestLightningReceive, al as requestOnchainReceive, am as rfqPair, an as unilateralClaimDelay, ao as unilateralRefundDelay, ap as unilateralRefundWithoutReceiverDelay, aq as verifyLockupAddress, ar as verifyOfferAddress, as as verifyReceiveInvoice } from './rfq-B95nPfaa.cjs';
7
7
 
8
8
  /**
9
9
  * Which wallet key signs this leg. Stored at `profile.signer`.
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-B6VPDGHC.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-B6VPDGHC.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-BrTpVPLy.js';
3
+ export { h as AssetSwapStatus, i as AvailableRfqSwapManagerCallbacks, B as BTC_ASSET_ID, I as InMemoryAssetSwapRepository, j as LightningReceiveSwap, k as LightningSendSwap, l as LockupFate, m as LockupNeedsRecoveryError, n as LockupParams, o as LockupSpend, O as OnchainSendAction, p as OnchainSendSwap, P as PersistableRfqSwap, q as PreimageBlockedReason, r as PreimageNotRecoverableError, s as REFUND_MTP_LAG_SECONDS, t as RFQ_RESOLVED_STATES, u as RFQ_SWAP_RETENTION_SECONDS, v as RFQ_SWAP_TERMINAL_STATES, w as RefundOutcome, x as RfqRestoreFailure, y as RfqRestoreOptions, z as RfqRestoreResult, C as RfqSwapActionName, D as RfqSwapLockup, E as RfqSwapManager, F as RfqSwapManagerCallbacks, G as RfqSwapManagerConfig, H as RfqSwapManagerDeps, J as RfqSwapManagerEvents, K as RfqSwapOrigin, N as RfqSwapOriginRequired, Q as RfqSwapOutcome, T as RfqSwapRecordStore, U as SwapContractRegistry, V as addAssetSwap, W as awaitRfqResolution, X as createRfqSwapRecord, Y as findLockupVtxos, Z as getAssetSwaps, _ as getAssetSwapsOrThrow, $ as isRfqSwapTerminal, a0 as isRfqTerminal, a1 as nextOnchainAction, a2 as preimageForSwapRecord, a3 as pushRefundWithoutReceiver, a4 as readLockupFate, a5 as rebuildRfqSwap, a6 as refundIfUnresolved, a7 as rfqSwapOriginOf, a8 as shouldRetainRfqSwap, a9 as swapSecretsToRecord, aa as updateAssetSwap, ab as updateAssetSwapBestEffort, ac as updateRfqSwapRecord } from './repository-BrTpVPLy.js';
4
4
  import { Network, LocalCardInput, DiscoveredMarket, Side, OfferPlan } from '@arkade-os/solver-discovery';
5
- import { O as OnchainNetwork, a as OnchainHtlc, b as OnchainHtlcParams, C as ChainSource, R as RfqTransport, r as requestOnchainSend, I as InvoiceFacts, c as requestLightningSend } from './rfq-D96aLvCA.js';
6
- export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, f as ChainUtxo, H as HtlcUtxo, L as LIGHTNING_BTC, g as LIGHTNING_RECEIVE_PAIR, h as LIGHTNING_SEND_PAIR, i as LOCKTIME_THRESHOLD, j as LightningReceiveTreeParams, k as LightningSendTreeParams, M as MAX_MIN_CONFIRMATIONS, l as MIN_CLAIM_WINDOW_SECONDS, m as MIN_HEADROOM_SECONDS, n as ONCHAIN_BTC, o as ONCHAIN_CLAIM_MARGIN_SECONDS, p as ONCHAIN_DUST_SATS, q as ONCHAIN_ORDER_MARGIN_SECONDS, s as ONCHAIN_RECEIVE_PAIR, t as ONCHAIN_SECONDS_PER_BLOCK, u as ONCHAIN_SEND_PAIR, v as OnchainHtlcPhase, w as RFQ_REFUSAL_ERROR_CODES, x as RFQ_TERMINAL_STATES, y as RelaySocket, z as RfqQuote, B as RfqRefusalDetail, D as RfqRefusalErrorCode, E as RfqRefusalReason, F as RfqRefusalUnit, G as RfqStatus, S as SOLO_REFUND_HEADROOM_SECONDS, J as SwapRefusal, K as arkadeAssetLeg, N as arkadeSwapRequest, P as assertArkadeFundable, Q as assertFundable, T as assertReceivable, U as awaitOnchainFill, V as buildHtlcClaim, W as buildHtlcRefund, X as canonicalAssetAmount, Y as claimOnchainFill, Z as classifyOnchainHtlc, _ as deriveLightningReceive, $ as deriveOnchainReceive, a0 as deriveOnchainSend, a1 as extractPreimage, a2 as httpTransport, a3 as isRfqRefusalErrorCode, a4 as l1ScriptForAddress, a5 as lightningReceiveRequest, a6 as lightningSendRequest, a7 as lightningSendVtxoScript, a8 as newPreimage, a9 as newRfqId, aa as normalizeMakerPkScript, ab as normalizeMakerPublicKey, ac as offerTermsFromQuote, ad as onchainHtlcScript, ae as onchainReceiveRequest, af as onchainSendRequest, ag as paymentHashOf, ah as receiveVtxoScript, ai as relayTransport, aj as requestArkadeSwap, ak as requestLightningReceive, al as requestOnchainReceive, am as rfqPair, an as unilateralClaimDelay, ao as unilateralRefundDelay, ap as unilateralRefundWithoutReceiverDelay, aq as verifyLockupAddress, ar as verifyOfferAddress, as as verifyReceiveInvoice } from './rfq-D96aLvCA.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-B95nPfaa.js';
6
+ export { A as ARKADE_ASSET, d as ARKADE_BTC, e as AddressMismatch, f as ChainUtxo, H as HtlcUtxo, L as LIGHTNING_BTC, g as LIGHTNING_RECEIVE_PAIR, h as LIGHTNING_SEND_PAIR, i as LOCKTIME_THRESHOLD, j as LightningReceiveTreeParams, k as LightningSendTreeParams, M as MAX_MIN_CONFIRMATIONS, l as MIN_CLAIM_WINDOW_SECONDS, m as MIN_HEADROOM_SECONDS, n as ONCHAIN_BTC, o as ONCHAIN_CLAIM_MARGIN_SECONDS, p as ONCHAIN_DUST_SATS, q as ONCHAIN_ORDER_MARGIN_SECONDS, s as ONCHAIN_RECEIVE_PAIR, t as ONCHAIN_SECONDS_PER_BLOCK, u as ONCHAIN_SEND_PAIR, v as OnchainHtlcPhase, w as RFQ_REFUSAL_ERROR_CODES, x as RFQ_TERMINAL_STATES, y as RelaySocket, z as RfqQuote, B as RfqRefusalDetail, D as RfqRefusalErrorCode, E as RfqRefusalReason, F as RfqRefusalUnit, G as RfqStatus, S as SOLO_REFUND_HEADROOM_SECONDS, J as SwapRefusal, K as arkadeAssetLeg, N as arkadeSwapRequest, P as assertArkadeFundable, Q as assertFundable, T as assertReceivable, U as awaitOnchainFill, V as buildHtlcClaim, W as buildHtlcRefund, X as canonicalAssetAmount, Y as claimOnchainFill, Z as classifyOnchainHtlc, _ as deriveLightningReceive, $ as deriveOnchainReceive, a0 as deriveOnchainSend, a1 as extractPreimage, a2 as httpTransport, a3 as isRfqRefusalErrorCode, a4 as l1ScriptForAddress, a5 as lightningReceiveRequest, a6 as lightningSendRequest, a7 as lightningSendVtxoScript, a8 as newPreimage, a9 as newRfqId, aa as normalizeMakerPkScript, ab as normalizeMakerPublicKey, ac as offerTermsFromQuote, ad as onchainHtlcScript, ae as onchainReceiveRequest, af as onchainSendRequest, ag as paymentHashOf, ah as receiveVtxoScript, ai as relayTransport, aj as requestArkadeSwap, ak as requestLightningReceive, al as requestOnchainReceive, am as rfqPair, an as unilateralClaimDelay, ao as unilateralRefundDelay, ap as unilateralRefundWithoutReceiverDelay, aq as verifyLockupAddress, ar as verifyOfferAddress, as as verifyReceiveInvoice } from './rfq-B95nPfaa.js';
7
7
 
8
8
  /**
9
9
  * Which wallet key signs this leg. Stored at `profile.signer`.
package/dist/index.js CHANGED
@@ -100,7 +100,7 @@ import {
100
100
  verifyLockupAddress,
101
101
  verifyOfferAddress,
102
102
  verifyReceiveInvoice
103
- } from "./chunk-D7GDHZCG.js";
103
+ } from "./chunk-QJKMTPRQ.js";
104
104
  import {
105
105
  InMemoryAssetSwapRepository,
106
106
  marketsCacheKey
package/dist/nostr.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { R as RfqTransport } from './rfq-D96aLvCA.cjs';
1
+ import { R as RfqTransport } from './rfq-B95nPfaa.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-D96aLvCA.js';
1
+ import { R as RfqTransport } from './rfq-B95nPfaa.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-D7GDHZCG.js";
4
+ } from "./chunk-QJKMTPRQ.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-BXIcmIIC.cjs';
2
+ import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-Cop29z0c.cjs';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-D96aLvCA.cjs';
5
+ import '../../rfq-B95nPfaa.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-B6VPDGHC.js';
2
+ import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-BrTpVPLy.js';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-D96aLvCA.js';
5
+ import '../../rfq-B95nPfaa.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-BXIcmIIC.cjs';
2
+ import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-Cop29z0c.cjs';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-D96aLvCA.cjs';
5
+ import '../../rfq-B95nPfaa.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-B6VPDGHC.js';
2
+ import { A as AssetSwapRepository, a as AssetSwap, R as RfqSwapRecord, M as MarketsCacheEntry } from '../../repository-BrTpVPLy.js';
3
3
  import '@arkade-os/solver-discovery';
4
4
  import '@arkade-os/sdk';
5
- import '../../rfq-D96aLvCA.js';
5
+ import '../../rfq-B95nPfaa.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-D96aLvCA.js';
3
+ import { G as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-B95nPfaa.js';
4
4
 
5
5
  type AssetSwapStatus = "pending" | "cancelling" | "fulfilled" | "cancelled" | "recoverable" | "awaiting_fill" | "claimable" | "claimed" | "refunded_l1";
6
6
  /** The sentinel asset id for BTC itself, as opposed to a 68-hex asset id.
@@ -1,6 +1,6 @@
1
1
  import { DiscoveredMarket } from '@arkade-os/solver-discovery';
2
2
  import { IWallet, ProvisionedKey, ProvisionedClaimSecret, RestArkProvider, RestIndexerProvider, VHTLC, Identity, IContractManager } from '@arkade-os/sdk';
3
- import { G as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-D96aLvCA.cjs';
3
+ import { G as RfqStatus, R as RfqTransport, a as OnchainHtlc, f as ChainUtxo, C as ChainSource, v as OnchainHtlcPhase } from './rfq-B95nPfaa.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.
@@ -303,6 +303,8 @@ interface RfqQuote {
303
303
  * solver). */
304
304
  from_amount: number | string;
305
305
  to_amount: number | string;
306
+ /** Dust an asset rides on. NOT a fee — already netted into the amounts above. */
307
+ carrier_sats?: number | string;
306
308
  solver_pubkey: string;
307
309
  valid_until: number;
308
310
  /** HTLC-class quotes only; absent for arkade↔arkade. */
@@ -348,8 +350,8 @@ declare const lightningSendRequest: (input: {
348
350
  * Wire-compatible with the reference solver (`AssetRfqRequest`, strict):
349
351
  * `amount` is a canonical decimal string of atomic units (never a JSON
350
352
  * 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
+ * losslessness carve-out cannot be checked), `amount_side` is `"from"` or
354
+ * `"to"`, and `profile` carries the trader's own covenant position
353
355
  * (`maker_pk_script`, `maker_public_key`) — the fill pays that script, and
354
356
  * `cancel` is signed by that key. */
355
357
  declare const arkadeSwapRequest: (input: {
@@ -358,8 +360,6 @@ declare const arkadeSwapRequest: (input: {
358
360
  offerAsset?: asset.AssetId;
359
361
  /** Asset the trader wants; omit when wanting BTC. */
360
362
  wantAsset?: asset.AssetId;
361
- /** Exact-in only. `"to"` is refused client-side: the solver answers
362
- * `exact_out_unsupported`, since the two legs are different assets. */
363
363
  amountSide?: "from" | "to";
364
364
  /** Atomic units of the deposit (`from`) leg. bigint-safe: encoded as a
365
365
  * canonical decimal string on the wire. */
@@ -710,8 +710,13 @@ declare function requestArkadeSwap(wallet: IWallet, arkServerUrl: string, transp
710
710
  offerAsset?: asset.AssetId;
711
711
  /** Asset the trader wants; omit when wanting BTC. */
712
712
  wantAsset?: asset.AssetId;
713
- /** Deposit amount, in atomic units of the `from` leg. */
713
+ /** Atomic units of whichever leg `amountSide` names. */
714
714
  amount: bigint | number | string;
715
+ amountSide?: "from" | "to";
716
+ /** Bounds the side the SOLVER chose — the named side is echoed back verbatim,
717
+ * so asserting it proves nothing and an unbounded caller funds what it is asked. */
718
+ maxFromAmount?: bigint | number | string;
719
+ minToAmount?: bigint | number | string;
715
720
  rfqId?: string;
716
721
  /** Co-signer key override (33-byte compressed hex); see `createOffer`. */
717
722
  emulatorPubkey?: string;
@@ -725,7 +730,7 @@ declare function requestArkadeSwap(wallet: IWallet, arkServerUrl: string, transp
725
730
  /** What the deposit must carry: the quote's `from_amount`. Sats for a BTC
726
731
  * deposit, asset units for an asset deposit (plus a dust carrier). */
727
732
  fundAmount: bigint;
728
- /** Dust sats carrier for an asset deposit; 0n for a BTC deposit. */
733
+ /** Dust sats to attach to an asset deposit; 0n for a BTC deposit. */
729
734
  carrierSats: bigint;
730
735
  /** The covenant's scriptPubKey, for watching the deposit and its spend. */
731
736
  swapPkScript: Uint8Array;
@@ -303,6 +303,8 @@ interface RfqQuote {
303
303
  * solver). */
304
304
  from_amount: number | string;
305
305
  to_amount: number | string;
306
+ /** Dust an asset rides on. NOT a fee — already netted into the amounts above. */
307
+ carrier_sats?: number | string;
306
308
  solver_pubkey: string;
307
309
  valid_until: number;
308
310
  /** HTLC-class quotes only; absent for arkade↔arkade. */
@@ -348,8 +350,8 @@ declare const lightningSendRequest: (input: {
348
350
  * Wire-compatible with the reference solver (`AssetRfqRequest`, strict):
349
351
  * `amount` is a canonical decimal string of atomic units (never a JSON
350
352
  * 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
+ * losslessness carve-out cannot be checked), `amount_side` is `"from"` or
354
+ * `"to"`, and `profile` carries the trader's own covenant position
353
355
  * (`maker_pk_script`, `maker_public_key`) — the fill pays that script, and
354
356
  * `cancel` is signed by that key. */
355
357
  declare const arkadeSwapRequest: (input: {
@@ -358,8 +360,6 @@ declare const arkadeSwapRequest: (input: {
358
360
  offerAsset?: asset.AssetId;
359
361
  /** Asset the trader wants; omit when wanting BTC. */
360
362
  wantAsset?: asset.AssetId;
361
- /** Exact-in only. `"to"` is refused client-side: the solver answers
362
- * `exact_out_unsupported`, since the two legs are different assets. */
363
363
  amountSide?: "from" | "to";
364
364
  /** Atomic units of the deposit (`from`) leg. bigint-safe: encoded as a
365
365
  * canonical decimal string on the wire. */
@@ -710,8 +710,13 @@ declare function requestArkadeSwap(wallet: IWallet, arkServerUrl: string, transp
710
710
  offerAsset?: asset.AssetId;
711
711
  /** Asset the trader wants; omit when wanting BTC. */
712
712
  wantAsset?: asset.AssetId;
713
- /** Deposit amount, in atomic units of the `from` leg. */
713
+ /** Atomic units of whichever leg `amountSide` names. */
714
714
  amount: bigint | number | string;
715
+ amountSide?: "from" | "to";
716
+ /** Bounds the side the SOLVER chose — the named side is echoed back verbatim,
717
+ * so asserting it proves nothing and an unbounded caller funds what it is asked. */
718
+ maxFromAmount?: bigint | number | string;
719
+ minToAmount?: bigint | number | string;
715
720
  rfqId?: string;
716
721
  /** Co-signer key override (33-byte compressed hex); see `createOffer`. */
717
722
  emulatorPubkey?: string;
@@ -725,7 +730,7 @@ declare function requestArkadeSwap(wallet: IWallet, arkServerUrl: string, transp
725
730
  /** What the deposit must carry: the quote's `from_amount`. Sats for a BTC
726
731
  * deposit, asset units for an asset deposit (plus a dust carrier). */
727
732
  fundAmount: bigint;
728
- /** Dust sats carrier for an asset deposit; 0n for a BTC deposit. */
733
+ /** Dust sats to attach to an asset deposit; 0n for a BTC deposit. */
729
734
  carrierSats: bigint;
730
735
  /** The covenant's scriptPubKey, for watching the deposit and its spend. */
731
736
  swapPkScript: Uint8Array;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkade-os/swap",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
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,13 +64,13 @@
64
64
  "author": "Arkade-OS",
65
65
  "license": "MIT",
66
66
  "dependencies": {
67
- "@arkade-os/solver-discovery": "0.2.5",
67
+ "@arkade-os/solver-discovery": "0.2.7",
68
68
  "@noble/ciphers": "2.1.1",
69
69
  "@noble/curves": "2.0.1",
70
70
  "@noble/hashes": "2.0.1",
71
71
  "@scure/base": "2.0.0",
72
72
  "@scure/btc-signer": "2.0.1",
73
- "@arkade-os/sdk": "0.4.73"
73
+ "@arkade-os/sdk": "0.4.74"
74
74
  },
75
75
  "peerDependencies": {
76
76
  "nostr-tools": "^2.12.0"