@satora/swap 1.5.0 → 1.6.0

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/index.d.cts CHANGED
@@ -313,6 +313,13 @@ type HtlcRef = {
313
313
  * → `invalid`, so the client never claims a short-funded leg.
314
314
  */
315
315
  expectedAmount: bigint;
316
+ /**
317
+ * Overrides {@link expectedAmount} as the `invalid` threshold, leaving the
318
+ * `isActive` tuple on the expected amount. For the client's own
319
+ * coordinator-locked leg, whose amount is DEX output: the server decides
320
+ * whether a short lock is acceptable, so the client doesn't second-guess it.
321
+ */
322
+ minAmount?: bigint;
316
323
  /** Expected token address; the funding is `invalid` if it locks another token. */
317
324
  expectedToken?: `0x${string}`;
318
325
  /**
@@ -666,6 +673,8 @@ declare class Client {
666
673
  /** Delegated to the legacy client (migration checkpoint). */
667
674
  claim(...args: Parameters<Client$1["claim"]>): ReturnType<Client$1["claim"]>;
668
675
  /** Delegated to the legacy client (migration checkpoint). */
676
+ claimEvmWithSigner(...args: Parameters<Client$1["claimEvmWithSigner"]>): ReturnType<Client$1["claimEvmWithSigner"]>;
677
+ /** Delegated to the legacy client (migration checkpoint). */
669
678
  claimViaGasless(...args: Parameters<Client$1["claimViaGasless"]>): ReturnType<Client$1["claimViaGasless"]>;
670
679
  /** Delegated to the legacy client (migration checkpoint). */
671
680
  claimArkade(...args: Parameters<Client$1["claimArkade"]>): ReturnType<Client$1["claimArkade"]>;
package/dist/index.d.ts CHANGED
@@ -313,6 +313,13 @@ type HtlcRef = {
313
313
  * → `invalid`, so the client never claims a short-funded leg.
314
314
  */
315
315
  expectedAmount: bigint;
316
+ /**
317
+ * Overrides {@link expectedAmount} as the `invalid` threshold, leaving the
318
+ * `isActive` tuple on the expected amount. For the client's own
319
+ * coordinator-locked leg, whose amount is DEX output: the server decides
320
+ * whether a short lock is acceptable, so the client doesn't second-guess it.
321
+ */
322
+ minAmount?: bigint;
316
323
  /** Expected token address; the funding is `invalid` if it locks another token. */
317
324
  expectedToken?: `0x${string}`;
318
325
  /**
@@ -666,6 +673,8 @@ declare class Client {
666
673
  /** Delegated to the legacy client (migration checkpoint). */
667
674
  claim(...args: Parameters<Client$1["claim"]>): ReturnType<Client$1["claim"]>;
668
675
  /** Delegated to the legacy client (migration checkpoint). */
676
+ claimEvmWithSigner(...args: Parameters<Client$1["claimEvmWithSigner"]>): ReturnType<Client$1["claimEvmWithSigner"]>;
677
+ /** Delegated to the legacy client (migration checkpoint). */
669
678
  claimViaGasless(...args: Parameters<Client$1["claimViaGasless"]>): ReturnType<Client$1["claimViaGasless"]>;
670
679
  /** Delegated to the legacy client (migration checkpoint). */
671
680
  claimArkade(...args: Parameters<Client$1["claimArkade"]>): ReturnType<Client$1["claimArkade"]>;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  electrumReader
3
- } from "./chunk-INWVLX4A.js";
3
+ } from "./chunk-3ZMSZSAV.js";
4
4
  import {
5
5
  DEFAULT_ESPLORA_URLS,
6
6
  esploraReader,
@@ -630,7 +630,7 @@ var BitcoinContractManager = class _BitcoinContractManager {
630
630
  );
631
631
  if (config.electrumWsUrl) {
632
632
  const [{ electrumReader: electrumReader2 }, { ElectrumWsClient }] = await Promise.all([
633
- import("./bitcoin-reader-electrum-Z2YCNDLB.js"),
633
+ import("./bitcoin-reader-electrum-KEI7VWW6.js"),
634
634
  import("@lendasat/lendaswap-sdk-pure")
635
635
  ]);
636
636
  reader = electrumReader2(new ElectrumWsClient(config.electrumWsUrl), {
@@ -815,7 +815,9 @@ var AVG_BLOCK_MS = {
815
815
  1: 12e3,
816
816
  137: 2100,
817
817
  42161: 250,
818
- 30: 3e4
818
+ 30: 3e4,
819
+ 31: 3e4
820
+ // Rootstock testnet: same merge-mined cadence
819
821
  };
820
822
  var SCAN_MARGIN_BLOCKS = 1000n;
821
823
  var EvmContractManager = class _EvmContractManager {
@@ -996,7 +998,10 @@ var EvmContractManager = class _EvmContractManager {
996
998
  for (const ref of refs) {
997
999
  const { observation, preimage } = evmObservation(
998
1000
  events.get(refQueryKey(ref)) ?? [],
999
- { amount: ref.expectedAmount, token: ref.expectedToken }
1001
+ {
1002
+ amount: ref.minAmount ?? ref.expectedAmount,
1003
+ token: ref.expectedToken
1004
+ }
1000
1005
  );
1001
1006
  const key = htlcKey(ref);
1002
1007
  if (preimage) this.#preimages.set(key, preimage);
@@ -1083,7 +1088,8 @@ var DEFAULT_EVM_RPCS = {
1083
1088
  "https://arbitrum-one-rpc.publicnode.com"
1084
1089
  ],
1085
1090
  // Rootstock: the public node, HTTP only (no WebSocket endpoint exists).
1086
- 30: ["https://public-node.rsk.co"]
1091
+ 30: ["https://public-node.rsk.co"],
1092
+ 31: ["https://public-node.testnet.rsk.co"]
1087
1093
  };
1088
1094
  var SWAP_CREATED = parseAbiItem(
1089
1095
  "event SwapCreated(bytes32 indexed preimageHash, address indexed refundAddress, address indexed claimAddress, address token, uint256 amount, uint256 timelock, bytes32 key)"
@@ -1284,7 +1290,8 @@ function createEvmRpcReader(rpcUrls, options = {}) {
1284
1290
  return evmReaderFromClient(client, options);
1285
1291
  }
1286
1292
  var EVM_LOG_RANGE_LIMITS = {
1287
- 30: 2000n
1293
+ 30: 2000n,
1294
+ 31: 2000n
1288
1295
  };
1289
1296
  function defaultEvmReaders(overrides) {
1290
1297
  const chainIds = /* @__PURE__ */ new Set([
@@ -1757,6 +1764,11 @@ function defaultWebSocketFactory(url) {
1757
1764
  return new WS(url);
1758
1765
  }
1759
1766
 
1767
+ // src/tracker/from-swap.ts
1768
+ import {
1769
+ NATIVE_TOKEN_ADDRESS
1770
+ } from "@lendasat/lendaswap-sdk-pure";
1771
+
1760
1772
  // src/contracts/arkade-vhtlc.ts
1761
1773
  import { VHTLCContractHandler } from "@arkade-os/sdk";
1762
1774
  import {
@@ -1845,6 +1857,7 @@ function evmLeg(args) {
1845
1857
  preimageHash: ensure0x(args.hashLock),
1846
1858
  claimAddress: ensure0x(args.claimAddress),
1847
1859
  expectedAmount: BigInt(args.expectedSats),
1860
+ minAmount: args.minAmount,
1848
1861
  expectedToken: args.token ? ensure0x(args.token) : void 0,
1849
1862
  sender: args.sender ? ensure0x(args.sender) : void 0,
1850
1863
  timelockSec: args.timelockSec,
@@ -1852,6 +1865,13 @@ function evmLeg(args) {
1852
1865
  };
1853
1866
  }
1854
1867
  var CLIENT_FUNDING_MIN_CONFIRMATIONS = 1;
1868
+ var FEE_ROUNDING_SLACK_SATS = 2;
1869
+ function minServerPayout(r) {
1870
+ return Math.max(
1871
+ 0,
1872
+ Number(r.target_amount) - r.fee_sats - FEE_ROUNDING_SLACK_SATS
1873
+ );
1874
+ }
1855
1875
  function bitcoinLeg(address, hashLock, expectedSats, minConfirmations) {
1856
1876
  return {
1857
1877
  ledger: "bitcoin",
@@ -1896,15 +1916,19 @@ function swapToTracked(stored) {
1896
1916
  claimAddress: r.server_evm_address,
1897
1917
  // the server claims the client's EVM HTLC
1898
1918
  expectedSats: r.evm_expected_sats,
1899
- // evm_to_arkade doesn't expose the locked token — fall back to the
1900
- // per-chain mainnet constant so the isActive tuple is complete.
1901
- token: lockedTokenFallback(r.evm_chain_id, r.network),
1902
- sender: r.client_evm_address,
1903
- // the client funded it
1919
+ minAmount: 0n,
1920
+ // see SHORT_LOCK_RULE
1921
+ // A native lock's asset word is zero; an ERC20 lock's token is not
1922
+ // on this response yet, so fall back to the per-chain mainnet
1923
+ // constant to complete the isActive tuple.
1924
+ token: r.evm_htlc_kind === "native" ? NATIVE_TOKEN_ADDRESS : lockedTokenFallback(r.evm_chain_id, r.network),
1925
+ // The coordinator created the HTLC on the client's behalf, so it
1926
+ // is the lock's sender (refund address), as on evm_to_lightning.
1927
+ sender: r.evm_coordinator_address,
1904
1928
  timelockSec: r.evm_refund_locktime,
1905
1929
  createdAt: r.created_at
1906
1930
  }),
1907
- serverHtlc: arkadeLeg(r, r.btc_vhtlc_address, Number(r.target_amount)),
1931
+ serverHtlc: arkadeLeg(r, r.btc_vhtlc_address, minServerPayout(r)),
1908
1932
  clientRefundLocktime: ms(r.evm_refund_locktime),
1909
1933
  serverRefundLocktime: ms(r.vhtlc_refund_locktime)
1910
1934
  };
@@ -1945,16 +1969,19 @@ function swapToTracked(stored) {
1945
1969
  claimAddress: r.server_evm_address,
1946
1970
  // the server claims the client's EVM HTLC
1947
1971
  expectedSats: r.evm_expected_sats,
1972
+ minAmount: 0n,
1973
+ // see SHORT_LOCK_RULE
1948
1974
  token: r.wbtc_address,
1949
- sender: r.client_evm_address,
1950
- // the client funded it
1975
+ // The coordinator created the HTLC on the client's behalf, so it
1976
+ // is the lock's sender (refund address).
1977
+ sender: r.evm_coordinator_address,
1951
1978
  timelockSec: r.evm_refund_locktime,
1952
1979
  createdAt: r.created_at
1953
1980
  }),
1954
1981
  serverHtlc: bitcoinLeg(
1955
1982
  r.btc_htlc_address,
1956
1983
  r.evm_hash_lock,
1957
- Number(r.target_amount)
1984
+ minServerPayout(r)
1958
1985
  ),
1959
1986
  clientRefundLocktime: ms(r.evm_refund_locktime),
1960
1987
  serverRefundLocktime: ms(r.btc_refund_locktime)
@@ -2629,6 +2656,10 @@ var Client = class {
2629
2656
  return this.#legacy.claim(...args);
2630
2657
  }
2631
2658
  /** Delegated to the legacy client (migration checkpoint). */
2659
+ claimEvmWithSigner(...args) {
2660
+ return this.#legacy.claimEvmWithSigner(...args);
2661
+ }
2662
+ /** Delegated to the legacy client (migration checkpoint). */
2632
2663
  claimViaGasless(...args) {
2633
2664
  return this.#legacy.claimViaGasless(...args);
2634
2665
  }