@theliem/xmarket-sdk 3.4.2 → 3.5.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
@@ -563,6 +563,7 @@ declare class ClobClient {
563
563
  ensureAlt(condition: PublicKey, collateralMint: PublicKey, takerSigned: SignedOrder, makers: SignedOrder[]): Promise<AddressLookupTableAccount>;
564
564
  private _sendLegacyTxSig;
565
565
  private _sendLegacyTx;
566
+ private _ensureClobOutcomeAtas;
566
567
  /**
567
568
  * Send a match transaction as versioned (v0) with optional ALT.
568
569
  * Both operator wallet and payer (this.provider.wallet) sign.
@@ -602,6 +603,13 @@ declare class ClobClient {
602
603
  * Phase 2: 1 atomic match tx.
603
604
  */
604
605
  private matchComplementary;
606
+ /**
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.
611
+ */
612
+ private matchComplementarySellVsMultiBuy;
605
613
  /**
606
614
  * MINT: 1 YES buyer (taker) + N NO buyers (makers).
607
615
  * Phase 1: register taker + all NO makers in parallel.
package/dist/index.d.ts CHANGED
@@ -563,6 +563,7 @@ declare class ClobClient {
563
563
  ensureAlt(condition: PublicKey, collateralMint: PublicKey, takerSigned: SignedOrder, makers: SignedOrder[]): Promise<AddressLookupTableAccount>;
564
564
  private _sendLegacyTxSig;
565
565
  private _sendLegacyTx;
566
+ private _ensureClobOutcomeAtas;
566
567
  /**
567
568
  * Send a match transaction as versioned (v0) with optional ALT.
568
569
  * Both operator wallet and payer (this.provider.wallet) sign.
@@ -602,6 +603,13 @@ declare class ClobClient {
602
603
  * Phase 2: 1 atomic match tx.
603
604
  */
604
605
  private matchComplementary;
606
+ /**
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.
611
+ */
612
+ private matchComplementarySellVsMultiBuy;
605
613
  /**
606
614
  * MINT: 1 YES buyer (taker) + N NO buyers (makers).
607
615
  * Phase 1: register taker + all NO makers in parallel.
package/dist/index.js CHANGED
@@ -1407,15 +1407,39 @@ var ClobClient = class {
1407
1407
  takerOrderRecord
1408
1408
  ];
1409
1409
  if (feeRecipientAddr) addresses.push(feeRecipientAddr);
1410
+ const [collateralVault] = PDA.collateralVault(collateralMint, this.programIds);
1411
+ const [vaultToken] = PDA.vaultToken(collateralMint, this.programIds);
1412
+ const [mintAuth] = PDA.mintAuthority(condition, this.programIds);
1413
+ const [extraMetaNo] = PDA.extraAccountMetaList(noMint, this.programIds);
1414
+ const clobUsdcAta = splToken.getAssociatedTokenAddressSync(collateralMint, clobConfigPda, true);
1415
+ const clobYesAta = splToken.getAssociatedTokenAddressSync(yesMint, clobConfigPda, true, splToken.TOKEN_2022_PROGRAM_ID);
1416
+ const clobNoAta = splToken.getAssociatedTokenAddressSync(noMint, clobConfigPda, true, splToken.TOKEN_2022_PROGRAM_ID);
1417
+ const [clobYesPos] = PDA.position(condition, 1, clobConfigPda, this.programIds);
1418
+ const [clobNoPos] = PDA.position(condition, 0, clobConfigPda, this.programIds);
1419
+ addresses.push(
1420
+ collateralVault,
1421
+ vaultToken,
1422
+ mintAuth,
1423
+ extraMetaNo,
1424
+ clobUsdcAta,
1425
+ clobYesAta,
1426
+ clobNoAta,
1427
+ clobYesPos,
1428
+ clobNoPos,
1429
+ collateralMint,
1430
+ splToken.ASSOCIATED_TOKEN_PROGRAM_ID
1431
+ );
1410
1432
  for (const m of makers) {
1411
1433
  const seller = m.order.maker;
1412
- const [sellerPos] = PDA.position(condition, tokenId, seller, this.programIds);
1434
+ const makerTokenId = m.order.tokenId;
1435
+ const makerMint = makerTokenId === 1 ? yesMint : noMint;
1436
+ const [sellerPos] = PDA.position(condition, makerTokenId, seller, this.programIds);
1413
1437
  const [sellerStatus] = PDA.orderStatus(seller, m.order.nonce, this.programIds);
1414
1438
  const [sellerRecord] = PDA.orderRecord(seller, m.order.nonce, this.programIds);
1415
1439
  addresses.push(
1416
1440
  seller,
1417
1441
  sellerRecord,
1418
- splToken.getAssociatedTokenAddressSync(outcomeMint, seller, false, splToken.TOKEN_2022_PROGRAM_ID),
1442
+ splToken.getAssociatedTokenAddressSync(makerMint, seller, false, splToken.TOKEN_2022_PROGRAM_ID),
1419
1443
  splToken.getAssociatedTokenAddressSync(collateralMint, seller),
1420
1444
  sellerPos,
1421
1445
  sellerStatus
@@ -1487,6 +1511,36 @@ ${logs.join("\n")}`);
1487
1511
  async _sendLegacyTx(instructions) {
1488
1512
  await this._sendLegacyTxSig(instructions);
1489
1513
  }
1514
+ async _ensureClobOutcomeAtas(yesMint, noMint, clobConfig, clobYesAta, clobNoAta) {
1515
+ const { connection } = this.provider;
1516
+ const [yesInfo, noInfo] = await Promise.all([
1517
+ connection.getAccountInfo(clobYesAta),
1518
+ connection.getAccountInfo(clobNoAta)
1519
+ ]);
1520
+ const { createAssociatedTokenAccountIdempotentInstruction: createAssociatedTokenAccountIdempotentInstruction2 } = await import('@solana/spl-token');
1521
+ const ixs = [];
1522
+ if (!yesInfo) {
1523
+ ixs.push(createAssociatedTokenAccountIdempotentInstruction2(
1524
+ this.walletPubkey,
1525
+ clobYesAta,
1526
+ clobConfig,
1527
+ yesMint,
1528
+ splToken.TOKEN_2022_PROGRAM_ID
1529
+ ));
1530
+ }
1531
+ if (!noInfo) {
1532
+ ixs.push(createAssociatedTokenAccountIdempotentInstruction2(
1533
+ this.walletPubkey,
1534
+ clobNoAta,
1535
+ clobConfig,
1536
+ noMint,
1537
+ splToken.TOKEN_2022_PROGRAM_ID
1538
+ ));
1539
+ }
1540
+ if (ixs.length > 0) {
1541
+ await this._sendLegacyTx(ixs);
1542
+ }
1543
+ }
1490
1544
  /**
1491
1545
  * Send a match transaction as versioned (v0) with optional ALT.
1492
1546
  * Both operator wallet and payer (this.provider.wallet) sign.
@@ -1494,11 +1548,12 @@ ${logs.join("\n")}`);
1494
1548
  async sendMatchTx(instructions, lookupTable, whitelistedWallet) {
1495
1549
  const { connection } = this.provider;
1496
1550
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
1497
- const cuLimit = web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units: 8e5 });
1551
+ const cuLimit = web3_js.ComputeBudgetProgram.setComputeUnitLimit({ units: 14e5 });
1552
+ const heapFrame = web3_js.ComputeBudgetProgram.requestHeapFrame({ bytes: 262144 });
1498
1553
  const message = new web3_js.TransactionMessage({
1499
1554
  payerKey: this.walletPubkey,
1500
1555
  recentBlockhash: blockhash,
1501
- instructions: [cuLimit, ...instructions]
1556
+ instructions: [cuLimit, heapFrame, ...instructions]
1502
1557
  }).compileToV0Message(lookupTable ? [lookupTable] : []);
1503
1558
  const vtx = new web3_js.VersionedTransaction(message);
1504
1559
  const signers = [this.provider.wallet.payer];
@@ -1507,7 +1562,7 @@ ${logs.join("\n")}`);
1507
1562
  }
1508
1563
  vtx.sign(signers);
1509
1564
  const sig = await connection.sendRawTransaction(vtx.serialize(), {
1510
- skipPreflight: true
1565
+ skipPreflight: false
1511
1566
  });
1512
1567
  const result = await connection.confirmTransaction(
1513
1568
  { signature: sig, blockhash, lastValidBlockHeight },
@@ -1710,6 +1765,47 @@ ${logs.join("\n")}`);
1710
1765
  const sig = await this.sendMatchTx(ixs, lookupTable, operatorWallet);
1711
1766
  return { signature: sig };
1712
1767
  }
1768
+ /**
1769
+ * 1 SELL taker vs N BUY makers.
1770
+ * Rust program only supports BUY-as-taker, so we decompose into N instructions
1771
+ * (BUY_i as taker, SELL as single maker) combined into one atomic transaction.
1772
+ * Engine must use limitPrice for BUY.makerAmount to pass per-pair crossing check.
1773
+ */
1774
+ async matchComplementarySellVsMultiBuy(sellTaker, buyMakers, collateralMint, feeRecipient, operatorWallet, lookupTable, opts) {
1775
+ await Promise.all([
1776
+ this.registerOrderIfNeeded(sellTaker),
1777
+ ...buyMakers.map((m) => this.registerOrderIfNeeded(m))
1778
+ ]);
1779
+ const sell = sellTaker.order;
1780
+ const crossingBuys = buyMakers.filter((b) => {
1781
+ const buy = b.order;
1782
+ const lhs = BigInt(buy.makerAmount.toString()) * BigInt(sell.makerAmount.toString());
1783
+ const rhs = BigInt(buy.takerAmount.toString()) * BigInt(sell.takerAmount.toString());
1784
+ return lhs >= rhs;
1785
+ });
1786
+ if (crossingBuys.length === 0) {
1787
+ throw new InvalidParamError("COMPLEMENTARY: no BUY maker orders cross with the SELL taker");
1788
+ }
1789
+ if (crossingBuys.length < buyMakers.length) {
1790
+ console.warn(`[matchOrders] SELL+BUY: filtered ${buyMakers.length - crossingBuys.length} non-crossing BUY(s)`);
1791
+ }
1792
+ const allIxs = [];
1793
+ for (const buyMaker of crossingBuys) {
1794
+ const ixs = await this.buildMatchComplementaryIxs(
1795
+ buyMaker,
1796
+ // BUY as taker
1797
+ [sellTaker],
1798
+ // SELL as maker
1799
+ collateralMint,
1800
+ feeRecipient,
1801
+ operatorWallet.publicKey,
1802
+ opts
1803
+ );
1804
+ allIxs.push(...ixs);
1805
+ }
1806
+ const sig = await this.sendMatchTx(allIxs, lookupTable, operatorWallet);
1807
+ return { signature: sig };
1808
+ }
1713
1809
  /**
1714
1810
  * MINT: 1 YES buyer (taker) + N NO buyers (makers).
1715
1811
  * Phase 1: register taker + all NO makers in parallel.
@@ -1727,6 +1823,7 @@ ${logs.join("\n")}`);
1727
1823
  const taker = yesSigned.order.maker;
1728
1824
  const takerNonce = yesSigned.order.nonce;
1729
1825
  const fillAmount = new anchor5__namespace.BN("18446744073709551615");
1826
+ const clobConfig = this.configPda();
1730
1827
  const [yesMint] = PDA.yesMint(condition, this.programIds);
1731
1828
  const [noMint] = PDA.noMint(condition, this.programIds);
1732
1829
  const [mintAuthority] = PDA.mintAuthority(condition, this.programIds);
@@ -1737,6 +1834,15 @@ ${logs.join("\n")}`);
1737
1834
  const takerYesToken = splToken.getAssociatedTokenAddressSync(yesMint, taker, false, splToken.TOKEN_2022_PROGRAM_ID);
1738
1835
  const [takerYesPosition] = PDA.position(condition, 1, taker, this.programIds);
1739
1836
  const [takerOrderStatus] = PDA.orderStatus(taker, takerNonce, this.programIds);
1837
+ const clobUsdcAta = splToken.getAssociatedTokenAddressSync(collateralMint, clobConfig, true);
1838
+ const clobYesAta = splToken.getAssociatedTokenAddressSync(yesMint, clobConfig, true, splToken.TOKEN_2022_PROGRAM_ID);
1839
+ const clobNoAta = splToken.getAssociatedTokenAddressSync(noMint, clobConfig, true, splToken.TOKEN_2022_PROGRAM_ID);
1840
+ const [clobYesPos] = PDA.position(condition, 1, clobConfig, this.programIds);
1841
+ const [clobNoPos] = PDA.position(condition, 0, clobConfig, this.programIds);
1842
+ const [extraMetaYes] = PDA.extraAccountMetaList(yesMint, this.programIds);
1843
+ const [extraMetaNo] = PDA.extraAccountMetaList(noMint, this.programIds);
1844
+ const [hookConfig] = PDA.hookConfig(this.programIds);
1845
+ const hookProgram = this.programIds.hook;
1740
1846
  const remainingAccounts = [];
1741
1847
  for (const nm of noMakers) {
1742
1848
  const noMaker = nm.order.maker;
@@ -1746,6 +1852,7 @@ ${logs.join("\n")}`);
1746
1852
  const [noPosition] = PDA.position(condition, 0, noMaker, this.programIds);
1747
1853
  const [noStatus] = PDA.orderStatus(noMaker, nm.order.nonce, this.programIds);
1748
1854
  remainingAccounts.push(
1855
+ { pubkey: noMaker, isSigner: false, isWritable: false },
1749
1856
  { pubkey: noRecord, isSigner: false, isWritable: false },
1750
1857
  { pubkey: noToken, isSigner: false, isWritable: true },
1751
1858
  { pubkey: noCollateral, isSigner: false, isWritable: true },
@@ -1753,10 +1860,16 @@ ${logs.join("\n")}`);
1753
1860
  { pubkey: noStatus, isSigner: false, isWritable: true }
1754
1861
  );
1755
1862
  }
1863
+ remainingAccounts.push(
1864
+ { pubkey: extraMetaYes, isSigner: false, isWritable: false },
1865
+ { pubkey: extraMetaNo, isSigner: false, isWritable: false },
1866
+ { pubkey: hookConfig, isSigner: false, isWritable: false },
1867
+ { pubkey: hookProgram, isSigner: false, isWritable: false }
1868
+ );
1756
1869
  const matchIx = await this.program.methods.matchMintOrders(takerNonce, fillAmount).accounts({
1757
1870
  operator: operatorWallet.publicKey,
1758
1871
  payer: this.walletPubkey,
1759
- clobConfig: this.configPda(),
1872
+ clobConfig,
1760
1873
  condition,
1761
1874
  taker,
1762
1875
  takerOrderRecord,
@@ -1764,16 +1877,25 @@ ${logs.join("\n")}`);
1764
1877
  takerYesToken,
1765
1878
  takerYesPosition,
1766
1879
  takerOrderStatus,
1880
+ clobUsdcAta,
1881
+ clobYesAta,
1882
+ clobNoAta,
1883
+ clobYesPosition: clobYesPos,
1884
+ clobNoPosition: clobNoPos,
1767
1885
  collateralVault,
1768
1886
  vaultTokenAccount,
1887
+ collateralMint,
1769
1888
  yesMint,
1770
1889
  noMint,
1771
1890
  mintAuthority,
1772
- clobAuthority: this.configPda(),
1891
+ clobAuthority: clobConfig,
1773
1892
  conditionalTokensProgram: this.programIds.conditionalTokens,
1774
1893
  collateralTokenProgram: splToken.TOKEN_PROGRAM_ID,
1894
+ token2022Program: splToken.TOKEN_2022_PROGRAM_ID,
1895
+ associatedTokenProgram: splToken.ASSOCIATED_TOKEN_PROGRAM_ID,
1775
1896
  systemProgram: web3_js.SystemProgram.programId
1776
1897
  }).remainingAccounts(remainingAccounts).instruction();
1898
+ await this._ensureClobOutcomeAtas(yesMint, noMint, clobConfig, clobYesAta, clobNoAta);
1777
1899
  const sig = await this.sendMatchTx([matchIx], lookupTable, operatorWallet);
1778
1900
  return { signature: sig };
1779
1901
  }
@@ -1795,9 +1917,9 @@ ${logs.join("\n")}`);
1795
1917
  const sellerYes = yesSigned.order.maker;
1796
1918
  const takerNonce = yesSigned.order.nonce;
1797
1919
  const fillAmount = new anchor5__namespace.BN("18446744073709551615");
1920
+ const clobConfig = this.configPda();
1798
1921
  const [yesMint] = PDA.yesMint(condition, this.programIds);
1799
1922
  const [noMint] = PDA.noMint(condition, this.programIds);
1800
- const [mintAuthority] = PDA.mintAuthority(condition, this.programIds);
1801
1923
  const [collateralVault] = PDA.collateralVault(collateralMint, this.programIds);
1802
1924
  const [vaultTokenAccount] = PDA.vaultToken(collateralMint, this.programIds);
1803
1925
  const [takerOrderRecord] = PDA.orderRecord(sellerYes, takerNonce, this.programIds);
@@ -1805,6 +1927,15 @@ ${logs.join("\n")}`);
1805
1927
  const [takerYesPosition] = PDA.position(condition, 1, sellerYes, this.programIds);
1806
1928
  const takerCollateral = splToken.getAssociatedTokenAddressSync(collateralMint, sellerYes);
1807
1929
  const [takerOrderStatus] = PDA.orderStatus(sellerYes, takerNonce, this.programIds);
1930
+ const clobUsdcAta = splToken.getAssociatedTokenAddressSync(collateralMint, clobConfig, true);
1931
+ const clobYesAta = splToken.getAssociatedTokenAddressSync(yesMint, clobConfig, true, splToken.TOKEN_2022_PROGRAM_ID);
1932
+ const clobNoAta = splToken.getAssociatedTokenAddressSync(noMint, clobConfig, true, splToken.TOKEN_2022_PROGRAM_ID);
1933
+ const [clobYesPos] = PDA.position(condition, 1, clobConfig, this.programIds);
1934
+ const [clobNoPos] = PDA.position(condition, 0, clobConfig, this.programIds);
1935
+ const [extraMetaYes] = PDA.extraAccountMetaList(yesMint, this.programIds);
1936
+ const [extraMetaNo] = PDA.extraAccountMetaList(noMint, this.programIds);
1937
+ const [hookConfig] = PDA.hookConfig(this.programIds);
1938
+ const hookProgram = this.programIds.hook;
1808
1939
  const remainingAccounts = [];
1809
1940
  for (const nm of noMakers) {
1810
1941
  const noMaker = nm.order.maker;
@@ -1814,6 +1945,7 @@ ${logs.join("\n")}`);
1814
1945
  const [noPosition] = PDA.position(condition, 0, noMaker, this.programIds);
1815
1946
  const [noStatus] = PDA.orderStatus(noMaker, nm.order.nonce, this.programIds);
1816
1947
  remainingAccounts.push(
1948
+ { pubkey: noMaker, isSigner: false, isWritable: false },
1817
1949
  { pubkey: noRecord, isSigner: false, isWritable: false },
1818
1950
  { pubkey: noToken, isSigner: false, isWritable: true },
1819
1951
  { pubkey: noCollateral, isSigner: false, isWritable: true },
@@ -1821,6 +1953,12 @@ ${logs.join("\n")}`);
1821
1953
  { pubkey: noStatus, isSigner: false, isWritable: true }
1822
1954
  );
1823
1955
  }
1956
+ remainingAccounts.push(
1957
+ { pubkey: extraMetaYes, isSigner: false, isWritable: false },
1958
+ { pubkey: extraMetaNo, isSigner: false, isWritable: false },
1959
+ { pubkey: hookConfig, isSigner: false, isWritable: false },
1960
+ { pubkey: hookProgram, isSigner: false, isWritable: false }
1961
+ );
1824
1962
  if (yesSigned.order.fee.gtn(0) && this.programIds.feeManagement && this.feeConfigOwner) {
1825
1963
  const companyAddr = await this.companyAddress();
1826
1964
  if (companyAddr) {
@@ -1837,7 +1975,7 @@ ${logs.join("\n")}`);
1837
1975
  const matchIx = await this.program.methods.matchMergeOrders(takerNonce, fillAmount).accounts({
1838
1976
  operator: operatorWallet.publicKey,
1839
1977
  payer: this.walletPubkey,
1840
- clobConfig: this.configPda(),
1978
+ clobConfig,
1841
1979
  condition,
1842
1980
  taker: sellerYes,
1843
1981
  takerOrderRecord,
@@ -1845,17 +1983,24 @@ ${logs.join("\n")}`);
1845
1983
  takerYesPosition,
1846
1984
  takerCollateral,
1847
1985
  takerOrderStatus,
1986
+ clobUsdcAta,
1987
+ clobYesAta,
1988
+ clobNoAta,
1989
+ clobYesPosition: clobYesPos,
1990
+ clobNoPosition: clobNoPos,
1848
1991
  collateralVault,
1849
1992
  vaultTokenAccount,
1993
+ collateralMint,
1850
1994
  yesMint,
1851
1995
  noMint,
1852
- mintAuthority,
1853
- feeRecipient,
1854
- clobAuthority: this.configPda(),
1996
+ clobAuthority: clobConfig,
1855
1997
  conditionalTokensProgram: this.programIds.conditionalTokens,
1856
1998
  collateralTokenProgram: splToken.TOKEN_PROGRAM_ID,
1999
+ token2022Program: splToken.TOKEN_2022_PROGRAM_ID,
2000
+ associatedTokenProgram: splToken.ASSOCIATED_TOKEN_PROGRAM_ID,
1857
2001
  systemProgram: web3_js.SystemProgram.programId
1858
2002
  }).remainingAccounts(remainingAccounts).instruction();
2003
+ await this._ensureClobOutcomeAtas(yesMint, noMint, clobConfig, clobYesAta, clobNoAta);
1859
2004
  const sig = await this.sendMatchTx([matchIx], lookupTable, operatorWallet);
1860
2005
  return { signature: sig };
1861
2006
  }
@@ -1896,38 +2041,22 @@ ${logs.join("\n")}`);
1896
2041
  buySignedOrder = taker;
1897
2042
  sellCandidates = makers;
1898
2043
  } else if (t.side === SIDE_SELL && makers.every((m) => m.order.side === SIDE_BUY)) {
1899
- buySignedOrder = makers[0];
1900
- sellCandidates = [taker, ...makers.slice(1)];
2044
+ return this.matchComplementarySellVsMultiBuy(taker, makers, collateralMint, feeRecipient, operatorWallet, alt, opts);
1901
2045
  } else {
1902
2046
  throw new InvalidParamError("COMPLEMENTARY requires one BUY and one or more SELLs on same tokenId");
1903
2047
  }
1904
- const budget = BigInt(buySignedOrder.order.makerAmount.toString());
1905
- const totalAsk = sellCandidates.reduce(
1906
- (s, m) => s + BigInt(m.order.takerAmount.toString()),
1907
- BigInt(0)
1908
- );
1909
- let finalSells;
1910
- if (budget >= totalAsk) {
1911
- finalSells = sellCandidates;
1912
- } else {
1913
- const sorted = [...sellCandidates].sort((a, b) => {
1914
- const pa = BigInt(a.order.takerAmount.toString()) * BigInt(b.order.makerAmount.toString());
1915
- const pb = BigInt(b.order.takerAmount.toString()) * BigInt(a.order.makerAmount.toString());
1916
- return pa < pb ? -1 : pa > pb ? 1 : 0;
1917
- });
1918
- finalSells = [];
1919
- let remaining = budget;
1920
- for (const s of sorted) {
1921
- const cost = BigInt(s.order.takerAmount.toString());
1922
- if (remaining >= cost) {
1923
- finalSells.push(s);
1924
- remaining -= cost;
1925
- }
1926
- }
1927
- if (finalSells.length === 0) {
1928
- throw new InvalidParamError("COMPLEMENTARY: taker budget insufficient for any maker");
1929
- }
1930
- console.warn(`[matchOrders] budget ${budget} < totalAsk ${totalAsk}: matched ${finalSells.length}/${sellCandidates.length} makers`);
2048
+ const buy = buySignedOrder.order;
2049
+ const finalSells = sellCandidates.filter((s) => {
2050
+ const sell = s.order;
2051
+ const lhs = BigInt(buy.makerAmount.toString()) * BigInt(sell.makerAmount.toString());
2052
+ const rhs = BigInt(buy.takerAmount.toString()) * BigInt(sell.takerAmount.toString());
2053
+ return lhs >= rhs;
2054
+ });
2055
+ if (finalSells.length === 0) {
2056
+ throw new InvalidParamError("COMPLEMENTARY: no maker orders cross with the buy order");
2057
+ }
2058
+ if (finalSells.length < sellCandidates.length) {
2059
+ console.warn(`[matchOrders] filtered ${sellCandidates.length - finalSells.length} non-crossing maker(s)`);
1931
2060
  }
1932
2061
  return this.matchComplementary(buySignedOrder, finalSells, collateralMint, feeRecipient, operatorWallet, alt, opts);
1933
2062
  }
@@ -8630,7 +8759,8 @@ var clob_exchange_default = {
8630
8759
  }
8631
8760
  },
8632
8761
  {
8633
- name: "condition"
8762
+ name: "condition",
8763
+ writable: true
8634
8764
  },
8635
8765
  {
8636
8766
  name: "taker"
@@ -8706,27 +8836,98 @@ var clob_exchange_default = {
8706
8836
  }
8707
8837
  },
8708
8838
  {
8709
- name: "collateral_vault",
8839
+ name: "clob_usdc_ata",
8840
+ docs: [
8841
+ "USDC ATA owned by clob_config \u2014 receives USDC from vault after merge"
8842
+ ],
8843
+ writable: true,
8844
+ pda: {
8845
+ seeds: [
8846
+ {
8847
+ kind: "account",
8848
+ path: "clob_config"
8849
+ },
8850
+ {
8851
+ kind: "account",
8852
+ path: "collateral_token_program"
8853
+ },
8854
+ {
8855
+ kind: "account",
8856
+ path: "collateral_mint"
8857
+ }
8858
+ ],
8859
+ program: {
8860
+ kind: "const",
8861
+ value: [
8862
+ 140,
8863
+ 151,
8864
+ 37,
8865
+ 143,
8866
+ 78,
8867
+ 36,
8868
+ 137,
8869
+ 241,
8870
+ 187,
8871
+ 61,
8872
+ 16,
8873
+ 41,
8874
+ 20,
8875
+ 142,
8876
+ 13,
8877
+ 131,
8878
+ 11,
8879
+ 90,
8880
+ 19,
8881
+ 153,
8882
+ 218,
8883
+ 255,
8884
+ 16,
8885
+ 132,
8886
+ 4,
8887
+ 142,
8888
+ 123,
8889
+ 216,
8890
+ 219,
8891
+ 233,
8892
+ 248,
8893
+ 89
8894
+ ]
8895
+ }
8896
+ }
8897
+ },
8898
+ {
8899
+ name: "clob_yes_ata",
8710
8900
  writable: true
8711
8901
  },
8712
8902
  {
8713
- name: "vault_token_account",
8903
+ name: "clob_no_ata",
8714
8904
  writable: true
8715
8905
  },
8716
8906
  {
8717
- name: "yes_mint",
8907
+ name: "clob_yes_position",
8718
8908
  writable: true
8719
8909
  },
8720
8910
  {
8721
- name: "no_mint",
8911
+ name: "clob_no_position",
8722
8912
  writable: true
8723
8913
  },
8724
8914
  {
8725
- name: "mint_authority",
8915
+ name: "collateral_vault",
8726
8916
  writable: true
8727
8917
  },
8728
8918
  {
8729
- name: "fee_recipient",
8919
+ name: "vault_token_account",
8920
+ writable: true
8921
+ },
8922
+ {
8923
+ name: "collateral_mint"
8924
+ },
8925
+ {
8926
+ name: "yes_mint",
8927
+ writable: true
8928
+ },
8929
+ {
8930
+ name: "no_mint",
8730
8931
  writable: true
8731
8932
  },
8732
8933
  {
@@ -8760,6 +8961,14 @@ var clob_exchange_default = {
8760
8961
  name: "collateral_token_program",
8761
8962
  address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
8762
8963
  },
8964
+ {
8965
+ name: "token_2022_program",
8966
+ address: "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
8967
+ },
8968
+ {
8969
+ name: "associated_token_program",
8970
+ address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
8971
+ },
8763
8972
  {
8764
8973
  name: "system_program",
8765
8974
  address: "11111111111111111111111111111111"
@@ -8825,7 +9034,8 @@ var clob_exchange_default = {
8825
9034
  }
8826
9035
  },
8827
9036
  {
8828
- name: "condition"
9037
+ name: "condition",
9038
+ writable: true
8829
9039
  },
8830
9040
  {
8831
9041
  name: "taker"
@@ -8900,6 +9110,94 @@ var clob_exchange_default = {
8900
9110
  ]
8901
9111
  }
8902
9112
  },
9113
+ {
9114
+ name: "clob_usdc_ata",
9115
+ docs: [
9116
+ "USDC ATA owned by clob_config \u2014 receives combined USDC, then split_position pulls from here"
9117
+ ],
9118
+ writable: true,
9119
+ pda: {
9120
+ seeds: [
9121
+ {
9122
+ kind: "account",
9123
+ path: "clob_config"
9124
+ },
9125
+ {
9126
+ kind: "account",
9127
+ path: "collateral_token_program"
9128
+ },
9129
+ {
9130
+ kind: "account",
9131
+ path: "collateral_mint"
9132
+ }
9133
+ ],
9134
+ program: {
9135
+ kind: "const",
9136
+ value: [
9137
+ 140,
9138
+ 151,
9139
+ 37,
9140
+ 143,
9141
+ 78,
9142
+ 36,
9143
+ 137,
9144
+ 241,
9145
+ 187,
9146
+ 61,
9147
+ 16,
9148
+ 41,
9149
+ 20,
9150
+ 142,
9151
+ 13,
9152
+ 131,
9153
+ 11,
9154
+ 90,
9155
+ 19,
9156
+ 153,
9157
+ 218,
9158
+ 255,
9159
+ 16,
9160
+ 132,
9161
+ 4,
9162
+ 142,
9163
+ 123,
9164
+ 216,
9165
+ 219,
9166
+ 233,
9167
+ 248,
9168
+ 89
9169
+ ]
9170
+ }
9171
+ }
9172
+ },
9173
+ {
9174
+ name: "clob_yes_ata",
9175
+ docs: [
9176
+ "YES Token-2022 ATA owned by clob_config \u2014 receives YES from split, then transferred to taker"
9177
+ ],
9178
+ writable: true
9179
+ },
9180
+ {
9181
+ name: "clob_no_ata",
9182
+ docs: [
9183
+ "NO Token-2022 ATA owned by clob_config \u2014 receives NO from split, then transferred to makers"
9184
+ ],
9185
+ writable: true
9186
+ },
9187
+ {
9188
+ name: "clob_yes_position",
9189
+ docs: [
9190
+ "YES Position PDA for clob_config (set by CTF split_position init_if_needed)"
9191
+ ],
9192
+ writable: true
9193
+ },
9194
+ {
9195
+ name: "clob_no_position",
9196
+ docs: [
9197
+ "NO Position PDA for clob_config (set by CTF split_position init_if_needed)"
9198
+ ],
9199
+ writable: true
9200
+ },
8903
9201
  {
8904
9202
  name: "collateral_vault",
8905
9203
  writable: true
@@ -8908,6 +9206,9 @@ var clob_exchange_default = {
8908
9206
  name: "vault_token_account",
8909
9207
  writable: true
8910
9208
  },
9209
+ {
9210
+ name: "collateral_mint"
9211
+ },
8911
9212
  {
8912
9213
  name: "yes_mint",
8913
9214
  writable: true
@@ -8951,6 +9252,14 @@ var clob_exchange_default = {
8951
9252
  name: "collateral_token_program",
8952
9253
  address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
8953
9254
  },
9255
+ {
9256
+ name: "token_2022_program",
9257
+ address: "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
9258
+ },
9259
+ {
9260
+ name: "associated_token_program",
9261
+ address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
9262
+ },
8954
9263
  {
8955
9264
  name: "system_program",
8956
9265
  address: "11111111111111111111111111111111"