@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/README.md +26 -24
- package/dist/index.d.ts +38 -1
- package/dist/index.js +236 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +236 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -12
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
|
}
|