@theliem/xmarket-sdk 3.6.1 → 3.7.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.mts CHANGED
@@ -605,9 +605,8 @@ declare class ClobClient {
605
605
  private matchComplementary;
606
606
  /**
607
607
  * 1 SELL taker vs N BUY makers.
608
- * Rust program only supports BUY-as-taker, so we decompose into N instructions
609
- * (BUY_i as taker, SELL as single maker) combined into one atomic transaction.
610
- * Engine must use limitPrice for BUY.makerAmount to pass per-pair crossing check.
608
+ * Program now supports SELL-as-taker natively 1 instruction with all BUY makers
609
+ * in remaining_accounts (same structure as BUY taker case).
611
610
  */
612
611
  private matchComplementarySellVsMultiBuy;
613
612
  /**
package/dist/index.d.ts CHANGED
@@ -605,9 +605,8 @@ declare class ClobClient {
605
605
  private matchComplementary;
606
606
  /**
607
607
  * 1 SELL taker vs N BUY makers.
608
- * Rust program only supports BUY-as-taker, so we decompose into N instructions
609
- * (BUY_i as taker, SELL as single maker) combined into one atomic transaction.
610
- * Engine must use limitPrice for BUY.makerAmount to pass per-pair crossing check.
608
+ * Program now supports SELL-as-taker natively 1 instruction with all BUY makers
609
+ * in remaining_accounts (same structure as BUY taker case).
611
610
  */
612
611
  private matchComplementarySellVsMultiBuy;
613
612
  /**
package/dist/index.js CHANGED
@@ -1869,19 +1869,14 @@ ${logs.join("\n")}`);
1869
1869
  }
1870
1870
  /**
1871
1871
  * 1 SELL taker vs N BUY makers.
1872
- * Rust program only supports BUY-as-taker, so we decompose into N instructions
1873
- * (BUY_i as taker, SELL as single maker) combined into one atomic transaction.
1874
- * Engine must use limitPrice for BUY.makerAmount to pass per-pair crossing check.
1872
+ * Program now supports SELL-as-taker natively 1 instruction with all BUY makers
1873
+ * in remaining_accounts (same structure as BUY taker case).
1875
1874
  */
1876
1875
  async matchComplementarySellVsMultiBuy(sellTaker, buyMakers, collateralMint, feeRecipient, operatorWallet, lookupTable, opts) {
1877
- await Promise.all([
1878
- this.registerOrderIfNeeded(sellTaker),
1879
- ...buyMakers.map((m) => this.registerOrderIfNeeded(m))
1880
- ]);
1881
- const sell = sellTaker.order;
1882
1876
  if (buyMakers.length === 0) {
1883
1877
  throw new InvalidParamError("COMPLEMENTARY: no BUY maker orders provided");
1884
1878
  }
1879
+ const sell = sellTaker.order;
1885
1880
  const totalBuyPayment = buyMakers.reduce(
1886
1881
  (acc, b) => acc + BigInt(b.order.makerAmount.toString()),
1887
1882
  BigInt(0)
@@ -1892,24 +1887,20 @@ ${logs.join("\n")}`);
1892
1887
  `COMPLEMENTARY: total buyer payments ${totalBuyPayment} < seller expected ${sellExpected}`
1893
1888
  );
1894
1889
  }
1895
- const crossingBuys = buyMakers;
1896
- const allIxs = [];
1897
- for (const buyMaker of crossingBuys) {
1898
- const ixs = await this.buildMatchComplementaryIxs(
1899
- buyMaker,
1900
- // BUY as taker
1901
- [sellTaker],
1902
- // SELL as maker
1903
- collateralMint,
1904
- feeRecipient,
1905
- operatorWallet.publicKey,
1906
- opts,
1907
- true
1908
- // useTakerPrice: SELL gets filled at BUY's price (maker's price per doc)
1909
- );
1910
- allIxs.push(...ixs);
1911
- }
1912
- const sig = await this.sendMatchTx(allIxs, lookupTable, operatorWallet);
1890
+ await Promise.all([
1891
+ this.registerOrderIfNeeded(sellTaker),
1892
+ ...buyMakers.map((m) => this.registerOrderIfNeeded(m))
1893
+ ]);
1894
+ const ixs = await this.buildMatchComplementaryIxs(
1895
+ sellTaker,
1896
+ buyMakers,
1897
+ collateralMint,
1898
+ feeRecipient,
1899
+ operatorWallet.publicKey,
1900
+ opts,
1901
+ false
1902
+ );
1903
+ const sig = await this.sendMatchTx(ixs, lookupTable, operatorWallet);
1913
1904
  return { signature: sig };
1914
1905
  }
1915
1906
  /**
@@ -2152,18 +2143,17 @@ ${logs.join("\n")}`);
2152
2143
  throw new InvalidParamError("COMPLEMENTARY requires one BUY and one or more SELLs on same tokenId");
2153
2144
  }
2154
2145
  const buy = buySignedOrder.order;
2155
- const finalSells = sellCandidates.filter((s) => {
2156
- const sell = s.order;
2157
- const lhs = BigInt(buy.makerAmount.toString()) * BigInt(sell.makerAmount.toString());
2158
- const rhs = BigInt(buy.takerAmount.toString()) * BigInt(sell.takerAmount.toString());
2159
- return lhs >= rhs;
2160
- });
2161
- if (finalSells.length === 0) {
2162
- throw new InvalidParamError("COMPLEMENTARY: no maker orders cross with the buy order");
2163
- }
2164
- if (finalSells.length < sellCandidates.length) {
2165
- console.warn(`[matchOrders] filtered ${sellCandidates.length - finalSells.length} non-crossing maker(s)`);
2146
+ const totalSellDemand = sellCandidates.reduce(
2147
+ (acc, s) => acc + BigInt(s.order.takerAmount.toString()),
2148
+ BigInt(0)
2149
+ );
2150
+ const buyBudget = BigInt(buy.makerAmount.toString());
2151
+ if (buyBudget < totalSellDemand) {
2152
+ throw new InvalidParamError(
2153
+ `COMPLEMENTARY: total sell demand ${totalSellDemand} > buy budget ${buyBudget}. Build taker order with limitPrice, not averageMatchedPrice.`
2154
+ );
2166
2155
  }
2156
+ const finalSells = sellCandidates;
2167
2157
  return this.matchComplementary(buySignedOrder, finalSells, collateralMint, feeRecipient, operatorWallet, alt, opts);
2168
2158
  }
2169
2159
  const allBuy = t.side === SIDE_BUY && makers.every((m) => m.order.side === SIDE_BUY);