@meteora-ag/dlmm 1.9.12 → 1.9.13

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.mjs CHANGED
@@ -16748,6 +16748,242 @@ var DLMM = class {
16748
16748
  }
16749
16749
  return positionsMap;
16750
16750
  }
16751
+ /**
16752
+ * The function `getPositionsByUserAndTokenAddress` retrieves all of a user's positions across every
16753
+ * DLMM pool that includes the given token mint as either the X or Y token.
16754
+ * @param {Connection} connection - The `connection` parameter is an instance of the `Connection`
16755
+ * class, which represents the connection to the Solana blockchain.
16756
+ * @param {PublicKey} userPubKey - The user's wallet public key.
16757
+ * @param {PublicKey} tokenMint - The token mint used to filter pools. Only positions in pools whose
16758
+ * `tokenXMint` or `tokenYMint` matches this mint are returned.
16759
+ * @param {Opt} [opt] - An optional object that contains additional options for the function.
16760
+ * @param {GetPositionsOpt} [getPositionsOpt] - Optional settings for chunked position fetching
16761
+ * @returns The function `getPositionsByUserAndTokenAddress` returns a `Promise` that resolves to a
16762
+ * `Map` object. The `Map` object contains key-value pairs, where the key is a string representing the
16763
+ * LB Pair account, and the value is an object of PositionInfo. Only pools containing `tokenMint` are
16764
+ * included.
16765
+ */
16766
+ static async getPositionsByUserAndTokenAddress(connection, userPubKey, tokenMint, opt, getPositionsOpt) {
16767
+ const allPositions = await DLMM.getAllLbPairPositionsByUser(
16768
+ connection,
16769
+ userPubKey,
16770
+ opt,
16771
+ getPositionsOpt
16772
+ );
16773
+ const targetMint = tokenMint.toBase58();
16774
+ const filteredPositions = /* @__PURE__ */ new Map();
16775
+ for (const [lbPairKey, positionInfo] of allPositions) {
16776
+ const tokenXMint = positionInfo.lbPair.tokenXMint.toBase58();
16777
+ const tokenYMint = positionInfo.lbPair.tokenYMint.toBase58();
16778
+ if (tokenXMint === targetMint || tokenYMint === targetMint) {
16779
+ filteredPositions.set(lbPairKey, positionInfo);
16780
+ }
16781
+ }
16782
+ return filteredPositions;
16783
+ }
16784
+ /**
16785
+ * The function `getLimitOrdersByUserAndTokenAddress` retrieves all of a user's limit orders across
16786
+ * every DLMM pool that includes the given token mint as either the X or Y token.
16787
+ * @param {Connection} connection - The `connection` parameter is an instance of the `Connection`
16788
+ * class, which represents the connection to the Solana blockchain.
16789
+ * @param {PublicKey} userPubKey - The user's wallet public key.
16790
+ * @param {PublicKey} tokenMint - The token mint used to filter pools. Only limit orders in pools
16791
+ * whose `tokenXMint` or `tokenYMint` matches this mint are returned.
16792
+ * @param {Opt} [opt] - An optional object that contains additional options for the function.
16793
+ * @returns The function `getLimitOrdersByUserAndTokenAddress` returns a `Promise` that resolves to a
16794
+ * `Map` object keyed by LB Pair account (base58), where each value is a `LimitOrderInfo` containing
16795
+ * the LB pair state, token reserves, and the parsed limit orders for that pool.
16796
+ */
16797
+ static async getLimitOrdersByUserAndTokenAddress(connection, userPubKey, tokenMint, opt) {
16798
+ const program = createProgram(connection, opt);
16799
+ const limitOrderAccounts = await chunkedGetProgramAccounts(
16800
+ program.provider.connection,
16801
+ program.programId,
16802
+ [limitOrderFilter(), limitOrderOwnerFilter(userPubKey)]
16803
+ );
16804
+ const limitOrderWrappers = limitOrderAccounts.map(
16805
+ ({ pubkey, account }) => wrapLimitOrder(program, pubkey, account)
16806
+ );
16807
+ if (limitOrderWrappers.length === 0) {
16808
+ return /* @__PURE__ */ new Map();
16809
+ }
16810
+ const lbPairKeys = Array.from(
16811
+ new Set(limitOrderWrappers.map((lo) => lo.lbPair().toBase58()))
16812
+ ).map((key) => new PublicKey10(key));
16813
+ const lbPairAccInfos = await chunkedGetMultipleAccountInfos(
16814
+ connection,
16815
+ lbPairKeys
16816
+ );
16817
+ const lbPairMap = /* @__PURE__ */ new Map();
16818
+ lbPairKeys.forEach((lbPairPubkey, i) => {
16819
+ const accInfo = lbPairAccInfos[i];
16820
+ if (!accInfo) {
16821
+ throw new Error(`LB Pair account ${lbPairPubkey.toBase58()} not found`);
16822
+ }
16823
+ lbPairMap.set(
16824
+ lbPairPubkey.toBase58(),
16825
+ decodeAccount(program, "lbPair", accInfo.data)
16826
+ );
16827
+ });
16828
+ const targetMint = tokenMint.toBase58();
16829
+ const matchingLbPairKeys = lbPairKeys.filter((lbPairPubkey) => {
16830
+ const lbPairState = lbPairMap.get(lbPairPubkey.toBase58());
16831
+ return lbPairState.tokenXMint.toBase58() === targetMint || lbPairState.tokenYMint.toBase58() === targetMint;
16832
+ });
16833
+ if (matchingLbPairKeys.length === 0) {
16834
+ return /* @__PURE__ */ new Map();
16835
+ }
16836
+ const matchingLbPairSet = new Set(
16837
+ matchingLbPairKeys.map((key) => key.toBase58())
16838
+ );
16839
+ const matchingLimitOrders = limitOrderWrappers.filter(
16840
+ (lo) => matchingLbPairSet.has(lo.lbPair().toBase58())
16841
+ );
16842
+ const reserveAndMintKeys = matchingLbPairKeys.map((lbPairPubkey) => {
16843
+ const { reserveX, reserveY, tokenXMint, tokenYMint } = lbPairMap.get(
16844
+ lbPairPubkey.toBase58()
16845
+ );
16846
+ return [reserveX, reserveY, tokenXMint, tokenYMint];
16847
+ }).flat();
16848
+ const binArrayPubkeySet = /* @__PURE__ */ new Set();
16849
+ matchingLimitOrders.forEach((lo) => {
16850
+ lo.getBinArrayKeysCoverage(program.programId).forEach((key) => {
16851
+ binArrayPubkeySet.add(key.toBase58());
16852
+ });
16853
+ });
16854
+ const binArrayKeys = Array.from(binArrayPubkeySet).map(
16855
+ (key) => new PublicKey10(key)
16856
+ );
16857
+ const [clockAccInfo, ...rest] = await chunkedGetMultipleAccountInfos(
16858
+ connection,
16859
+ [SYSVAR_CLOCK_PUBKEY2, ...binArrayKeys, ...reserveAndMintKeys]
16860
+ );
16861
+ const binArraysAccInfo = rest.slice(0, binArrayKeys.length);
16862
+ const reserveAndMintAccInfo = rest.slice(binArrayKeys.length);
16863
+ const clock = ClockLayout.decode(clockAccInfo.data);
16864
+ const binArrayMap = /* @__PURE__ */ new Map();
16865
+ binArrayKeys.forEach((binArrayPubkey, i) => {
16866
+ const accInfo = binArraysAccInfo[i];
16867
+ if (accInfo) {
16868
+ binArrayMap.set(
16869
+ binArrayPubkey.toBase58(),
16870
+ decodeAccount(program, "binArray", accInfo.data)
16871
+ );
16872
+ }
16873
+ });
16874
+ const seenMints = /* @__PURE__ */ new Set();
16875
+ const mintsWithAccount = matchingLbPairKeys.flatMap((lbPairPubkey, idx) => {
16876
+ const { tokenXMint, tokenYMint } = lbPairMap.get(
16877
+ lbPairPubkey.toBase58()
16878
+ );
16879
+ const index = idx * 4;
16880
+ return [
16881
+ {
16882
+ mintAddress: tokenXMint,
16883
+ mintAccountInfo: reserveAndMintAccInfo[index + 2]
16884
+ },
16885
+ {
16886
+ mintAddress: tokenYMint,
16887
+ mintAccountInfo: reserveAndMintAccInfo[index + 3]
16888
+ }
16889
+ ];
16890
+ }).filter(({ mintAddress, mintAccountInfo }) => {
16891
+ if (!mintAccountInfo || seenMints.has(mintAddress.toBase58())) {
16892
+ return false;
16893
+ }
16894
+ seenMints.add(mintAddress.toBase58());
16895
+ return true;
16896
+ });
16897
+ const mintHookAccountsMap = await getMultipleMintsExtraAccountMetasForTransferHook(
16898
+ connection,
16899
+ mintsWithAccount
16900
+ );
16901
+ const lbPairTokenMap = /* @__PURE__ */ new Map();
16902
+ matchingLbPairKeys.forEach((lbPairPubkey, idx) => {
16903
+ const index = idx * 4;
16904
+ const reserveXAccount = reserveAndMintAccInfo[index];
16905
+ const reserveYAccount = reserveAndMintAccInfo[index + 1];
16906
+ const mintXAccount = reserveAndMintAccInfo[index + 2];
16907
+ const mintYAccount = reserveAndMintAccInfo[index + 3];
16908
+ if (!reserveXAccount || !reserveYAccount) {
16909
+ throw new Error(
16910
+ `Reserve account for LB Pair ${lbPairPubkey.toBase58()} not found`
16911
+ );
16912
+ }
16913
+ if (!mintXAccount || !mintYAccount) {
16914
+ throw new Error(
16915
+ `Mint account for LB Pair ${lbPairPubkey.toBase58()} not found`
16916
+ );
16917
+ }
16918
+ const lbPairState = lbPairMap.get(lbPairPubkey.toBase58());
16919
+ const reserveAccX = AccountLayout.decode(reserveXAccount.data);
16920
+ const reserveAccY = AccountLayout.decode(reserveYAccount.data);
16921
+ const mintX = unpackMint2(
16922
+ reserveAccX.mint,
16923
+ mintXAccount,
16924
+ mintXAccount.owner
16925
+ );
16926
+ const mintY = unpackMint2(
16927
+ reserveAccY.mint,
16928
+ mintYAccount,
16929
+ mintYAccount.owner
16930
+ );
16931
+ const { tokenXProgram, tokenYProgram } = getTokenProgramId(lbPairState);
16932
+ const tokenX = {
16933
+ publicKey: lbPairState.tokenXMint,
16934
+ reserve: lbPairState.reserveX,
16935
+ amount: reserveAccX.amount,
16936
+ mint: mintX,
16937
+ owner: tokenXProgram,
16938
+ transferHookAccountMetas: mintHookAccountsMap.get(lbPairState.tokenXMint.toBase58()) ?? []
16939
+ };
16940
+ const tokenY = {
16941
+ publicKey: lbPairState.tokenYMint,
16942
+ reserve: lbPairState.reserveY,
16943
+ amount: reserveAccY.amount,
16944
+ mint: mintY,
16945
+ owner: tokenYProgram,
16946
+ transferHookAccountMetas: mintHookAccountsMap.get(lbPairState.tokenYMint.toBase58()) ?? []
16947
+ };
16948
+ lbPairTokenMap.set(lbPairPubkey.toBase58(), {
16949
+ tokenX,
16950
+ tokenY,
16951
+ mintX,
16952
+ mintY
16953
+ });
16954
+ });
16955
+ const limitOrdersMap = /* @__PURE__ */ new Map();
16956
+ for (const lo of matchingLimitOrders) {
16957
+ const lbPairKey = lo.lbPair().toBase58();
16958
+ const lbPairState = lbPairMap.get(lbPairKey);
16959
+ const { tokenX, tokenY, mintX, mintY } = lbPairTokenMap.get(lbPairKey);
16960
+ const parsedLo = lo.parseInfo(
16961
+ program.programId,
16962
+ lbPairState,
16963
+ mintX,
16964
+ mintY,
16965
+ clock,
16966
+ binArrayMap
16967
+ );
16968
+ const entry = {
16969
+ publicKey: lo.address(),
16970
+ limitOrderData: parsedLo
16971
+ };
16972
+ const existing = limitOrdersMap.get(lbPairKey);
16973
+ if (existing) {
16974
+ existing.limitOrders.push(entry);
16975
+ } else {
16976
+ limitOrdersMap.set(lbPairKey, {
16977
+ publicKey: lo.lbPair(),
16978
+ lbPair: lbPairState,
16979
+ tokenX,
16980
+ tokenY,
16981
+ limitOrders: [entry]
16982
+ });
16983
+ }
16984
+ }
16985
+ return limitOrdersMap;
16986
+ }
16751
16987
  static getPricePerLamport(tokenXDecimal, tokenYDecimal, price) {
16752
16988
  return new Decimal11(price).mul(new Decimal11(10 ** (tokenYDecimal - tokenXDecimal))).toString();
16753
16989
  }