@theliem/xmarket-sdk 3.6.1 → 3.8.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
@@ -596,7 +596,7 @@ declare class ClobClient {
596
596
  buildMatchComplementaryIxs(takerSigned: SignedOrder, makersSigned: SignedOrder[], collateralMint: PublicKey, feeRecipient: PublicKey, operator: PublicKey, opts?: {
597
597
  marketOracleVault?: PublicKey;
598
598
  fillAmount?: anchor.BN;
599
- }, useTakerPrice?: boolean): Promise<TransactionInstruction[]>;
599
+ }, useTakerPrice?: boolean, skipCrossingCheck?: boolean): Promise<TransactionInstruction[]>;
600
600
  /**
601
601
  * COMPLEMENTARY: 1 taker (BUY) + N makers (SELL), same tokenId.
602
602
  * Phase 1: register taker + all makers in parallel.
@@ -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
@@ -596,7 +596,7 @@ declare class ClobClient {
596
596
  buildMatchComplementaryIxs(takerSigned: SignedOrder, makersSigned: SignedOrder[], collateralMint: PublicKey, feeRecipient: PublicKey, operator: PublicKey, opts?: {
597
597
  marketOracleVault?: PublicKey;
598
598
  fillAmount?: anchor.BN;
599
- }, useTakerPrice?: boolean): Promise<TransactionInstruction[]>;
599
+ }, useTakerPrice?: boolean, skipCrossingCheck?: boolean): Promise<TransactionInstruction[]>;
600
600
  /**
601
601
  * COMPLEMENTARY: 1 taker (BUY) + N makers (SELL), same tokenId.
602
602
  * Phase 1: register taker + all makers in parallel.
@@ -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
@@ -1776,7 +1776,7 @@ ${logs.join("\n")}`);
1776
1776
  * [extraAccountMetaList, hookConfig, hookProgram]
1777
1777
  * [feeManagement, fee_config, mkt_override, company_ata, oracle_vault] (when fee > 0)
1778
1778
  */
1779
- async buildMatchComplementaryIxs(takerSigned, makersSigned, collateralMint, feeRecipient, operator, opts, useTakerPrice = false) {
1779
+ async buildMatchComplementaryIxs(takerSigned, makersSigned, collateralMint, feeRecipient, operator, opts, useTakerPrice = false, skipCrossingCheck = true) {
1780
1780
  const condition = takerSigned.order.condition;
1781
1781
  const tokenId = takerSigned.order.tokenId;
1782
1782
  const taker = takerSigned.order.maker;
@@ -1816,17 +1816,21 @@ ${logs.join("\n")}`);
1816
1816
  if (takerSigned.order.fee.gtn(0) && this.programIds.feeManagement && this.feeConfigOwner) {
1817
1817
  const companyAddr = await this.companyAddress();
1818
1818
  if (companyAddr) {
1819
- const oracleVault = opts?.marketOracleVault ?? this.walletPubkey;
1820
- feeAccounts = [
1821
- { pubkey: this.programIds.feeManagement, isSigner: false, isWritable: false },
1822
- { pubkey: PDA.feeConfig(this.feeConfigOwner, this.programIds)[0], isSigner: false, isWritable: false },
1823
- { pubkey: PDA.marketFeeOverride(condition, this.programIds)[0], isSigner: false, isWritable: false },
1824
- { pubkey: splToken.getAssociatedTokenAddressSync(collateralMint, companyAddr), isSigner: false, isWritable: true },
1825
- { pubkey: oracleVault, isSigner: false, isWritable: true }
1826
- ];
1819
+ const feeOverridePda = PDA.marketFeeOverride(condition, this.programIds)[0];
1820
+ const feeOverrideExists = await this.provider.connection.getAccountInfo(feeOverridePda);
1821
+ if (feeOverrideExists) {
1822
+ const oracleVault = opts?.marketOracleVault ?? this.walletPubkey;
1823
+ feeAccounts = [
1824
+ { pubkey: this.programIds.feeManagement, isSigner: false, isWritable: false },
1825
+ { pubkey: PDA.feeConfig(this.feeConfigOwner, this.programIds)[0], isSigner: false, isWritable: false },
1826
+ { pubkey: feeOverridePda, isSigner: false, isWritable: false },
1827
+ { pubkey: splToken.getAssociatedTokenAddressSync(collateralMint, companyAddr), isSigner: false, isWritable: true },
1828
+ { pubkey: oracleVault, isSigner: false, isWritable: true }
1829
+ ];
1830
+ }
1827
1831
  }
1828
1832
  }
1829
- const matchIx = await this.program.methods.matchComplementary(takerNonce, fillAmount, useTakerPrice).accounts({
1833
+ const matchIx = await this.program.methods.matchComplementary(takerNonce, fillAmount, useTakerPrice, skipCrossingCheck).accounts({
1830
1834
  operator,
1831
1835
  payer: this.walletPubkey,
1832
1836
  clobConfig: this.configPda(),
@@ -1869,19 +1873,14 @@ ${logs.join("\n")}`);
1869
1873
  }
1870
1874
  /**
1871
1875
  * 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.
1876
+ * Program now supports SELL-as-taker natively 1 instruction with all BUY makers
1877
+ * in remaining_accounts (same structure as BUY taker case).
1875
1878
  */
1876
1879
  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
1880
  if (buyMakers.length === 0) {
1883
1881
  throw new InvalidParamError("COMPLEMENTARY: no BUY maker orders provided");
1884
1882
  }
1883
+ const sell = sellTaker.order;
1885
1884
  const totalBuyPayment = buyMakers.reduce(
1886
1885
  (acc, b) => acc + BigInt(b.order.makerAmount.toString()),
1887
1886
  BigInt(0)
@@ -1892,24 +1891,20 @@ ${logs.join("\n")}`);
1892
1891
  `COMPLEMENTARY: total buyer payments ${totalBuyPayment} < seller expected ${sellExpected}`
1893
1892
  );
1894
1893
  }
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);
1894
+ await Promise.all([
1895
+ this.registerOrderIfNeeded(sellTaker),
1896
+ ...buyMakers.map((m) => this.registerOrderIfNeeded(m))
1897
+ ]);
1898
+ const ixs = await this.buildMatchComplementaryIxs(
1899
+ sellTaker,
1900
+ buyMakers,
1901
+ collateralMint,
1902
+ feeRecipient,
1903
+ operatorWallet.publicKey,
1904
+ opts,
1905
+ false
1906
+ );
1907
+ const sig = await this.sendMatchTx(ixs, lookupTable, operatorWallet);
1913
1908
  return { signature: sig };
1914
1909
  }
1915
1910
  /**
@@ -2151,19 +2146,7 @@ ${logs.join("\n")}`);
2151
2146
  } else {
2152
2147
  throw new InvalidParamError("COMPLEMENTARY requires one BUY and one or more SELLs on same tokenId");
2153
2148
  }
2154
- 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)`);
2166
- }
2149
+ const finalSells = sellCandidates;
2167
2150
  return this.matchComplementary(buySignedOrder, finalSells, collateralMint, feeRecipient, operatorWallet, alt, opts);
2168
2151
  }
2169
2152
  const allBuy = t.side === SIDE_BUY && makers.every((m) => m.order.side === SIDE_BUY);
@@ -8864,6 +8847,10 @@ var clob_exchange_default = {
8864
8847
  {
8865
8848
  name: "use_taker_price",
8866
8849
  type: "bool"
8850
+ },
8851
+ {
8852
+ name: "skip_crossing_check",
8853
+ type: "bool"
8867
8854
  }
8868
8855
  ]
8869
8856
  },