Add user balances retrieval functionality to Liquidswap
- Implemented `getUsersBalances` method in the Liquidswap class to fetch user token balances from the Aptos API. - Added helper functions in a new `lp.ts` file to parse liquidity pool types. - Created a GraphQL query in a new `token-balances.ts` file for fetching fungible asset balances. - Introduced a new tool `getBalancesByAddressTool` for accessing user balances by address. - Updated tools index to include the new balances tool.
This commit is contained in:
1 parent
8679bd2072
commit
29c7931b68
6 files changed
+138
No files matched your search
@@ -0,0 +1,42 @@
|
||||
export function destructCoinStorePoolStr(type: string): string[] {
|
||||
if (type.length === 0) return [];
|
||||
return (
|
||||
type
|
||||
//
|
||||
.split('<')[2]
|
||||
.split('>')[0]
|
||||
.replaceAll(' ', '')
|
||||
.split(',')
|
||||
);
|
||||
}
|
||||
|
||||
export function destructCoinStorePoolV1Str(type: string): string[] {
|
||||
if (type.length === 0) return [];
|
||||
return (
|
||||
type
|
||||
//
|
||||
.split('<')[1]
|
||||
.split('>')[0]
|
||||
.replaceAll(' ', '')
|
||||
.split(',')
|
||||
);
|
||||
}
|
||||
|
||||
export function getTokensByLpType(type: string): {coinX: string, coinY: string} | undefined {
|
||||
let result: string[] = [];
|
||||
try {
|
||||
const tokens = destructCoinStorePoolV1Str(type)
|
||||
result = tokens
|
||||
} catch {
|
||||
try {
|
||||
result = destructCoinStorePoolStr(type)
|
||||
} catch {
|
||||
result = []
|
||||
}
|
||||
}
|
||||
if (!result.length) return undefined;
|
||||
return {
|
||||
coinX: result[0],
|
||||
coinY: result[1],
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
import { BE_URL } from "../constants.js";
|
||||
import { getTokensByLpType } from "./helpers/lp.js";
|
||||
import { getTokenBalancesQuery } from "./queries/token-balances.js";
|
||||
|
||||
export class Liquidswap {
|
||||
private readonly url = BE_URL
|
||||
@@ -27,6 +29,55 @@ export class Liquidswap {
|
||||
const response = await this.fetch(`/sentio/historical_tvls?start=${from}&end=${to}`)
|
||||
return response
|
||||
}
|
||||
|
||||
public async getUsersBalances(address: string, offset: number = 0) {
|
||||
|
||||
const data = await fetch('https://api.mainnet.aptoslabs.com/v1/graphql', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${process.env.APTOS_API_KEY}`,
|
||||
},
|
||||
body: JSON.stringify({ query: getTokenBalancesQuery(address, offset) }),
|
||||
})
|
||||
|
||||
const response = await data.json()
|
||||
|
||||
const tokens = response.data.current_fungible_asset_balances as {asset_type: string, amount: string}[];
|
||||
|
||||
const lsTokens = await this.getTokens()
|
||||
const lsTokensMap = new Map(lsTokens.map((token: any) => [token.type, token]))
|
||||
|
||||
const tokensWithNames = tokens.map((token: any) => {
|
||||
const lsToken = lsTokensMap.get(token.asset_type) as {name: string, symbol: string, decimals: number, logo_url: string}
|
||||
|
||||
if (!lsToken) {
|
||||
const tokens = getTokensByLpType(token.asset_type)
|
||||
if (tokens) {
|
||||
const coinX = lsTokensMap.get(tokens.coinX) as {name: string, symbol: string, decimals: number, logo_url: string}
|
||||
const coinY = lsTokensMap.get(tokens.coinY) as {name: string, symbol: string, decimals: number, logo_url: string}
|
||||
return {
|
||||
...token,
|
||||
name: `${coinX?.name} / ${coinY?.name}`,
|
||||
symbol: `${coinX?.symbol} / ${coinY?.symbol}`,
|
||||
isLp: true,
|
||||
coinX,
|
||||
coinY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...token,
|
||||
name: lsToken?.name,
|
||||
symbol: lsToken?.symbol,
|
||||
decimals: lsToken?.decimals,
|
||||
logo: lsToken?.logo_url,
|
||||
}
|
||||
})
|
||||
|
||||
return tokensWithNames
|
||||
}
|
||||
}
|
||||
|
||||
export const liquidswap = new Liquidswap()
|
||||
@@ -0,0 +1,15 @@
|
||||
export const getTokenBalancesQuery = (address: string, offset: number = 0) => {
|
||||
return `
|
||||
query GetTokenBalances {
|
||||
current_fungible_asset_balances(
|
||||
where: {owner_address: {_eq: "${address}"}, token_standard: {_eq: "v1"}}
|
||||
offset: ${offset}
|
||||
limit: 100
|
||||
order_by: {amount: desc}
|
||||
) {
|
||||
asset_type
|
||||
amount
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { Tool } from "../../types/tools.js";
|
||||
import { liquidswap } from "../../core/liquidswap.js";
|
||||
import { z } from "zod";
|
||||
|
||||
const getBalancesByAddress: Tool<typeof parameters>['execute'] = async (args) => {
|
||||
const data = await liquidswap.getUsersBalances(args.address);
|
||||
|
||||
return {
|
||||
content: data.map((item: any) => ({
|
||||
type: "text",
|
||||
text: JSON.stringify(item, null, 2)
|
||||
})),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
const parameters = z.object({
|
||||
address: z.string().describe("Aptos address to get the balances for"),
|
||||
});
|
||||
|
||||
|
||||
export const getBalancesByAddressTool: Tool<typeof parameters> = {
|
||||
name: "get_balances_by_address",
|
||||
description: "Get balances for a given Aptos address",
|
||||
execute: getBalancesByAddress,
|
||||
parameters,
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./get-balances-by-address.js";
|
||||
@@ -3,12 +3,14 @@ import { getTokensTool } from "./get-tokens/get-tokens.js";
|
||||
import { getPoolsTool } from "./get-pools/get-pools.js";
|
||||
import { getPoolsHistoricalAprsTool } from "./get-pools-historical-aprs/index.js";
|
||||
import { getPoolsHistoricalTvlsTool } from "./get-pools-historical-tvls/index.js";
|
||||
import { getBalancesByAddressTool } from "./get-balances-by-address/index.js";
|
||||
|
||||
const tools: Tool<any>[] = [
|
||||
getTokensTool,
|
||||
getPoolsTool,
|
||||
getPoolsHistoricalAprsTool,
|
||||
getPoolsHistoricalTvlsTool,
|
||||
getBalancesByAddressTool,
|
||||
];
|
||||
|
||||
export default tools;
|
||||
Reference in new issue
Block a user