@alphafi/alphafi-sdk 0.0.2
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/.babelrc +6 -0
- package/.eslintrc.json +30 -0
- package/README.md +1 -0
- package/dist/common/cetus_mainnet_config.d.ts +3 -0
- package/dist/common/cetus_mainnet_config.d.ts.map +1 -0
- package/dist/common/coins.d.ts +11 -0
- package/dist/common/coins.d.ts.map +1 -0
- package/dist/common/constants.d.ts +294 -0
- package/dist/common/constants.d.ts.map +1 -0
- package/dist/common/maps.d.ts +30 -0
- package/dist/common/maps.d.ts.map +1 -0
- package/dist/common/pyth.d.ts +7 -0
- package/dist/common/pyth.d.ts.map +1 -0
- package/dist/common/types.d.ts +331 -0
- package/dist/common/types.d.ts.map +1 -0
- package/dist/functions.d.ts +20 -0
- package/dist/functions.d.ts.map +1 -0
- package/dist/getVaultBalances.d.ts +5 -0
- package/dist/getVaultBalances.d.ts.map +1 -0
- package/dist/getVaults.d.ts +3 -0
- package/dist/getVaults.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.LICENSE.txt +28 -0
- package/dist/index.js.map +1 -0
- package/dist/portfolioAmount.d.ts +36 -0
- package/dist/portfolioAmount.d.ts.map +1 -0
- package/dist/price.d.ts +19 -0
- package/dist/price.d.ts.map +1 -0
- package/jest.config.js +14 -0
- package/package.json +51 -0
- package/src/common/cetus_mainnet_config.ts +72 -0
- package/src/common/coins.ts +126 -0
- package/src/common/constants.ts +820 -0
- package/src/common/maps.ts +200 -0
- package/src/common/pyth.ts +23 -0
- package/src/common/types.ts +446 -0
- package/src/functions.ts +299 -0
- package/src/getVaultBalances.ts +128 -0
- package/src/getVaults.ts +63 -0
- package/src/index.ts +13 -0
- package/src/portfolioAmount.ts +365 -0
- package/src/price.ts +397 -0
- package/tsconfig.json +21 -0
- package/webpack.config.js +59 -0
package/src/functions.ts
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import BN from "bn.js";
|
|
2
|
+
import { ClmmPoolUtil, TickMath } from "@cetusprotocol/cetus-sui-clmm-sdk";
|
|
3
|
+
import { PaginatedObjectsResponse, SuiClient } from "@mysten/sui/client";
|
|
4
|
+
import Decimal from "decimal.js";
|
|
5
|
+
import { cetusPoolMap, poolInfo } from "./common/maps";
|
|
6
|
+
import {
|
|
7
|
+
CetusInvestor,
|
|
8
|
+
CetusPoolType,
|
|
9
|
+
CoinAmounts,
|
|
10
|
+
PoolName,
|
|
11
|
+
Receipt,
|
|
12
|
+
SimpleCache,
|
|
13
|
+
} from "./common/types";
|
|
14
|
+
import { getPool } from "./portfolioAmount";
|
|
15
|
+
|
|
16
|
+
const receiptsCache = new SimpleCache<Receipt[]>();
|
|
17
|
+
const receiptsPromiseCache = new SimpleCache<Promise<Receipt[]>>();
|
|
18
|
+
export async function getReceipts(
|
|
19
|
+
poolName: string,
|
|
20
|
+
options: {
|
|
21
|
+
address: string;
|
|
22
|
+
suiClient: SuiClient;
|
|
23
|
+
},
|
|
24
|
+
ignoreCache: boolean = false,
|
|
25
|
+
): Promise<Receipt[]> {
|
|
26
|
+
const receiptsCacheKey = `getReceipts-${poolName}-${options.address}`;
|
|
27
|
+
if (ignoreCache) {
|
|
28
|
+
receiptsCache.delete(receiptsCacheKey);
|
|
29
|
+
receiptsPromiseCache.delete(receiptsCacheKey);
|
|
30
|
+
}
|
|
31
|
+
const cachedResponse = receiptsCache.get(receiptsCacheKey);
|
|
32
|
+
if (cachedResponse) {
|
|
33
|
+
return cachedResponse;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const nfts: Receipt[] = [];
|
|
37
|
+
|
|
38
|
+
let cachedPromise = receiptsPromiseCache.get(receiptsCacheKey);
|
|
39
|
+
if (!cachedPromise) {
|
|
40
|
+
cachedPromise = (async (): Promise<Receipt[]> => {
|
|
41
|
+
// const first_package = conf[CONF_ENV].ALPHA_FIRST_PACKAGE_ID;
|
|
42
|
+
let currentCursor: string | null | undefined = null;
|
|
43
|
+
/* eslint-disable-next-line no-constant-condition */
|
|
44
|
+
while (true) {
|
|
45
|
+
const paginatedObjects: PaginatedObjectsResponse =
|
|
46
|
+
await options.suiClient.getOwnedObjects({
|
|
47
|
+
owner: options.address,
|
|
48
|
+
cursor: currentCursor,
|
|
49
|
+
filter: {
|
|
50
|
+
// StructType: `${first_package}::${module}::Receipt`,
|
|
51
|
+
StructType: poolInfo[poolName].receiptType,
|
|
52
|
+
},
|
|
53
|
+
options: {
|
|
54
|
+
showType: true,
|
|
55
|
+
showContent: true,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
// Traverse the current page data and push to coins array
|
|
59
|
+
|
|
60
|
+
paginatedObjects.data.forEach((obj) => {
|
|
61
|
+
const o = obj.data as Receipt;
|
|
62
|
+
if (o) {
|
|
63
|
+
if (poolInfo[poolName].receiptName === o.content.fields.name) {
|
|
64
|
+
nfts.push(o);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Check if there's a next page
|
|
70
|
+
if (paginatedObjects.hasNextPage && paginatedObjects.nextCursor) {
|
|
71
|
+
currentCursor = paginatedObjects.nextCursor;
|
|
72
|
+
} else {
|
|
73
|
+
// No more pages available
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
receiptsCache.set(receiptsCacheKey, nfts);
|
|
78
|
+
receiptsPromiseCache.delete(receiptsCacheKey);
|
|
79
|
+
return nfts;
|
|
80
|
+
})().catch((error) => {
|
|
81
|
+
// TODO: Jugaad
|
|
82
|
+
if (poolInfo[poolName].parentProtocolName === "NAVI") {
|
|
83
|
+
return nfts;
|
|
84
|
+
} else {
|
|
85
|
+
receiptsPromiseCache.delete(receiptsCacheKey); // Remove the promise from cache
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
receiptsPromiseCache.set(receiptsCacheKey, cachedPromise);
|
|
90
|
+
}
|
|
91
|
+
return cachedPromise;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const poolExchangeRateCache = new SimpleCache<Decimal>();
|
|
95
|
+
|
|
96
|
+
export async function getPoolExchangeRate(
|
|
97
|
+
poolName: PoolName,
|
|
98
|
+
options: { suiClient: SuiClient },
|
|
99
|
+
ignoreCache: boolean = false,
|
|
100
|
+
): Promise<Decimal | undefined> {
|
|
101
|
+
const poolExchangeRateCacheKey = `getPoolExchangeRate-${poolName}`;
|
|
102
|
+
if (ignoreCache) {
|
|
103
|
+
poolExchangeRateCache.delete(poolExchangeRateCacheKey);
|
|
104
|
+
}
|
|
105
|
+
const cachedResponse = poolExchangeRateCache.get(poolExchangeRateCacheKey);
|
|
106
|
+
if (cachedResponse) {
|
|
107
|
+
return cachedResponse;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let pool = undefined;
|
|
111
|
+
try {
|
|
112
|
+
if (poolName === "ALPHA") {
|
|
113
|
+
pool = await getPool("ALPHA", options);
|
|
114
|
+
} else if (
|
|
115
|
+
poolName === "ALPHA-SUI" ||
|
|
116
|
+
poolName === "USDT-USDC" ||
|
|
117
|
+
poolName === "USDY-USDC" ||
|
|
118
|
+
poolName === "HASUI-SUI" ||
|
|
119
|
+
poolName === "USDC-SUI" ||
|
|
120
|
+
poolName === "WETH-USDC"
|
|
121
|
+
) {
|
|
122
|
+
pool = await getPool(poolName, options);
|
|
123
|
+
} else {
|
|
124
|
+
pool = await getPool(poolName, options);
|
|
125
|
+
}
|
|
126
|
+
if (pool) {
|
|
127
|
+
const xTokenSupply = new Decimal(pool.content.fields.xTokenSupply);
|
|
128
|
+
let tokensInvested = new Decimal(pool.content.fields.tokensInvested);
|
|
129
|
+
if (poolName == "ALPHA") {
|
|
130
|
+
tokensInvested = new Decimal(pool.content.fields.alpha_bal);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Check for division by zero
|
|
134
|
+
if (xTokenSupply.eq(0)) {
|
|
135
|
+
console.error("Division by zero error: tokensInvested is zero.");
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
const poolExchangeRate = tokensInvested.div(xTokenSupply);
|
|
139
|
+
|
|
140
|
+
poolExchangeRateCache.set(poolExchangeRateCacheKey, poolExchangeRate);
|
|
141
|
+
|
|
142
|
+
return poolExchangeRate;
|
|
143
|
+
}
|
|
144
|
+
} catch (e) {
|
|
145
|
+
console.error(`getPoolExchangeRate failed for poolName: ${poolName}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export async function getCoinAmountsFromLiquidity(
|
|
152
|
+
poolName: PoolName,
|
|
153
|
+
liquidity: number,
|
|
154
|
+
options: { suiClient: SuiClient },
|
|
155
|
+
): Promise<[number, number]> {
|
|
156
|
+
const cetus_pool = await getCetusPool(poolName, options);
|
|
157
|
+
const cetusInvestor = await getCetusInvestor(poolName, options);
|
|
158
|
+
|
|
159
|
+
const upper_bound = 443636;
|
|
160
|
+
let lower_tick = Number(cetusInvestor!.content.fields.lower_tick);
|
|
161
|
+
let upper_tick = Number(cetusInvestor!.content.fields.upper_tick);
|
|
162
|
+
|
|
163
|
+
if (lower_tick > upper_bound) {
|
|
164
|
+
lower_tick = -~(lower_tick - 1);
|
|
165
|
+
}
|
|
166
|
+
if (upper_tick > upper_bound) {
|
|
167
|
+
upper_tick = -~(upper_tick - 1);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (cetus_pool) {
|
|
171
|
+
const liquidityInt = Math.floor(liquidity);
|
|
172
|
+
const coin_amounts: CoinAmounts = ClmmPoolUtil.getCoinAmountFromLiquidity(
|
|
173
|
+
new BN(`${liquidityInt}`),
|
|
174
|
+
new BN(cetus_pool.content.fields.current_sqrt_price),
|
|
175
|
+
TickMath.tickIndexToSqrtPriceX64(lower_tick),
|
|
176
|
+
TickMath.tickIndexToSqrtPriceX64(upper_tick),
|
|
177
|
+
true,
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
return [coin_amounts.coinA.toNumber(), coin_amounts.coinB.toNumber()];
|
|
181
|
+
} else {
|
|
182
|
+
return [0, 0];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const cetusPoolCache = new SimpleCache<CetusPoolType>();
|
|
187
|
+
const cetusPoolPromiseCache = new SimpleCache<
|
|
188
|
+
Promise<CetusPoolType | undefined>
|
|
189
|
+
>();
|
|
190
|
+
|
|
191
|
+
export async function getCetusPool(
|
|
192
|
+
poolName: string,
|
|
193
|
+
options: {
|
|
194
|
+
suiClient: SuiClient;
|
|
195
|
+
},
|
|
196
|
+
ignoreCache: boolean = false,
|
|
197
|
+
): Promise<CetusPoolType | undefined> {
|
|
198
|
+
const cacheKey = `pool_${cetusPoolMap[poolName.toUpperCase()]}`;
|
|
199
|
+
if (ignoreCache) {
|
|
200
|
+
cetusPoolCache.delete(cacheKey);
|
|
201
|
+
cetusPoolPromiseCache.delete(cacheKey);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Check if the pool is already in the cache
|
|
205
|
+
const cachedPool = cetusPoolCache.get(cacheKey);
|
|
206
|
+
if (cachedPool) {
|
|
207
|
+
return cachedPool;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Check if there is already a promise in the cache
|
|
211
|
+
let cetusPoolPromise = cetusPoolPromiseCache.get(cacheKey);
|
|
212
|
+
if (cetusPoolPromise) {
|
|
213
|
+
return cetusPoolPromise;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// If not, create a new promise and cache it
|
|
217
|
+
cetusPoolPromise = (async () => {
|
|
218
|
+
try {
|
|
219
|
+
const o = await options.suiClient.getObject({
|
|
220
|
+
id: cetusPoolMap[poolName.toUpperCase()],
|
|
221
|
+
options: {
|
|
222
|
+
showContent: true,
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
const cetusPool = o.data as CetusPoolType;
|
|
226
|
+
|
|
227
|
+
// Cache the pool object
|
|
228
|
+
cetusPoolCache.set(cacheKey, cetusPool);
|
|
229
|
+
return cetusPool;
|
|
230
|
+
} catch (e) {
|
|
231
|
+
console.error(`getCetusPool failed for poolName: ${poolName}`);
|
|
232
|
+
return undefined;
|
|
233
|
+
} finally {
|
|
234
|
+
// Remove the promise from the cache after it resolves
|
|
235
|
+
cetusPoolPromiseCache.delete(cacheKey);
|
|
236
|
+
}
|
|
237
|
+
})();
|
|
238
|
+
|
|
239
|
+
// Cache the promise
|
|
240
|
+
cetusPoolPromiseCache.set(cacheKey, cetusPoolPromise);
|
|
241
|
+
return cetusPoolPromise;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const cetusInvestorCache = new SimpleCache<CetusInvestor>();
|
|
245
|
+
const cetusInvestorPromiseCache = new SimpleCache<
|
|
246
|
+
Promise<CetusInvestor | undefined>
|
|
247
|
+
>();
|
|
248
|
+
|
|
249
|
+
export async function getCetusInvestor(
|
|
250
|
+
poolName: PoolName,
|
|
251
|
+
options: {
|
|
252
|
+
suiClient: SuiClient;
|
|
253
|
+
},
|
|
254
|
+
ignoreCache: boolean = false,
|
|
255
|
+
): Promise<CetusInvestor | undefined> {
|
|
256
|
+
const cacheKey = `investor_${poolInfo[poolName.toUpperCase()].investorId}`;
|
|
257
|
+
if (ignoreCache) {
|
|
258
|
+
cetusInvestorCache.delete(cacheKey);
|
|
259
|
+
cetusInvestorPromiseCache.delete(cacheKey);
|
|
260
|
+
}
|
|
261
|
+
// Check if the investor is already in the cache
|
|
262
|
+
const cachedInvestor = cetusInvestorCache.get(cacheKey);
|
|
263
|
+
if (cachedInvestor) {
|
|
264
|
+
return cachedInvestor;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Check if there is already a promise in the cache
|
|
268
|
+
let cetusInvestorPromise = cetusInvestorPromiseCache.get(cacheKey);
|
|
269
|
+
if (cetusInvestorPromise) {
|
|
270
|
+
return cetusInvestorPromise;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// If not, create a new promise and cache it
|
|
274
|
+
cetusInvestorPromise = (async () => {
|
|
275
|
+
try {
|
|
276
|
+
const o = await options.suiClient.getObject({
|
|
277
|
+
id: poolInfo[poolName.toUpperCase()].investorId,
|
|
278
|
+
options: {
|
|
279
|
+
showContent: true,
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
const cetus_investor = o.data as CetusInvestor;
|
|
283
|
+
|
|
284
|
+
// Cache the investor object
|
|
285
|
+
cetusInvestorCache.set(cacheKey, cetus_investor);
|
|
286
|
+
return cetus_investor;
|
|
287
|
+
} catch (e) {
|
|
288
|
+
console.error(`getCetusInvestor failed for pool: ${poolName}`);
|
|
289
|
+
return undefined;
|
|
290
|
+
} finally {
|
|
291
|
+
// Remove the promise from the cache after it resolves
|
|
292
|
+
cetusInvestorPromiseCache.delete(cacheKey);
|
|
293
|
+
}
|
|
294
|
+
})();
|
|
295
|
+
|
|
296
|
+
// Cache the promise
|
|
297
|
+
cetusInvestorPromiseCache.set(cacheKey, cetusInvestorPromise);
|
|
298
|
+
return cetusInvestorPromise;
|
|
299
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { getFullnodeUrl, SuiClient } from "@mysten/sui/client";
|
|
2
|
+
import {
|
|
3
|
+
AlphaVaultBalance,
|
|
4
|
+
DoubleAssetVaultBalance,
|
|
5
|
+
PoolName,
|
|
6
|
+
SingleAssetVaultBalance,
|
|
7
|
+
} from "./common/types";
|
|
8
|
+
import {
|
|
9
|
+
getAlphaPortfolioAmount,
|
|
10
|
+
getAlphaPortfolioAmountInUSD,
|
|
11
|
+
getPortfolioAmount,
|
|
12
|
+
getPortfolioAmountInUSD,
|
|
13
|
+
getSingleAssetPortfolioAmount,
|
|
14
|
+
getSingleAssetPortfolioAmountInUSD,
|
|
15
|
+
} from "./portfolioAmount";
|
|
16
|
+
|
|
17
|
+
export async function getAlphaVaultBalance(
|
|
18
|
+
address: string,
|
|
19
|
+
): Promise<AlphaVaultBalance | undefined> {
|
|
20
|
+
const suiClient = new SuiClient({
|
|
21
|
+
url: getFullnodeUrl("mainnet"),
|
|
22
|
+
});
|
|
23
|
+
if (address) {
|
|
24
|
+
const lockedPortfolioAmount = await getAlphaPortfolioAmount("ALPHA", {
|
|
25
|
+
suiClient,
|
|
26
|
+
address,
|
|
27
|
+
isLocked: true,
|
|
28
|
+
});
|
|
29
|
+
const lockedPortfolioAmountInUSD = await getAlphaPortfolioAmountInUSD(
|
|
30
|
+
"ALPHA",
|
|
31
|
+
{ suiClient, address, isLocked: true },
|
|
32
|
+
);
|
|
33
|
+
const unlockedPortfolioAmount = await getAlphaPortfolioAmount("ALPHA", {
|
|
34
|
+
suiClient,
|
|
35
|
+
address,
|
|
36
|
+
isLocked: false,
|
|
37
|
+
});
|
|
38
|
+
const unlockedPortfolioAmountInUSD = await getAlphaPortfolioAmountInUSD(
|
|
39
|
+
"ALPHA",
|
|
40
|
+
{ suiClient, address, isLocked: false },
|
|
41
|
+
);
|
|
42
|
+
const portfolioAmount = await getAlphaPortfolioAmount("ALPHA", {
|
|
43
|
+
suiClient,
|
|
44
|
+
address,
|
|
45
|
+
});
|
|
46
|
+
const portfolioAmountInUSD = await getAlphaPortfolioAmountInUSD("ALPHA", {
|
|
47
|
+
suiClient,
|
|
48
|
+
address,
|
|
49
|
+
});
|
|
50
|
+
if (
|
|
51
|
+
lockedPortfolioAmount !== undefined &&
|
|
52
|
+
lockedPortfolioAmountInUSD !== undefined &&
|
|
53
|
+
unlockedPortfolioAmount !== undefined &&
|
|
54
|
+
unlockedPortfolioAmountInUSD !== undefined &&
|
|
55
|
+
portfolioAmount !== undefined &&
|
|
56
|
+
portfolioAmountInUSD !== undefined
|
|
57
|
+
) {
|
|
58
|
+
const res: AlphaVaultBalance = {
|
|
59
|
+
lockedAlphaCoins: lockedPortfolioAmount,
|
|
60
|
+
lockedAlphaCoinsInUSD: lockedPortfolioAmountInUSD,
|
|
61
|
+
unlockedAlphaCoins: unlockedPortfolioAmount,
|
|
62
|
+
unlockedAlphaCoinsInUSD: unlockedPortfolioAmountInUSD,
|
|
63
|
+
totalAlphaCoins: portfolioAmount,
|
|
64
|
+
totalAlphaCoinsInUSD: portfolioAmountInUSD,
|
|
65
|
+
};
|
|
66
|
+
return res;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function getDoubleAssetVaultBalance(
|
|
73
|
+
address: string,
|
|
74
|
+
poolName: PoolName,
|
|
75
|
+
): Promise<DoubleAssetVaultBalance | undefined> {
|
|
76
|
+
const suiClient = new SuiClient({
|
|
77
|
+
url: getFullnodeUrl("mainnet"),
|
|
78
|
+
});
|
|
79
|
+
if (address && poolName) {
|
|
80
|
+
const portfolioAmount = await getPortfolioAmount(poolName as PoolName, {
|
|
81
|
+
suiClient,
|
|
82
|
+
address,
|
|
83
|
+
});
|
|
84
|
+
const portfolioAmountInUSD = await getPortfolioAmountInUSD(
|
|
85
|
+
poolName as PoolName,
|
|
86
|
+
{ suiClient, address },
|
|
87
|
+
);
|
|
88
|
+
if (portfolioAmount !== undefined && portfolioAmountInUSD !== undefined) {
|
|
89
|
+
const res: DoubleAssetVaultBalance = {
|
|
90
|
+
coinA: portfolioAmount[0].toString(),
|
|
91
|
+
coinB: portfolioAmount[1].toString(),
|
|
92
|
+
valueInUSD: portfolioAmountInUSD,
|
|
93
|
+
};
|
|
94
|
+
return res;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export async function getSingleAssetVaultBalance(
|
|
100
|
+
address: string,
|
|
101
|
+
poolName: PoolName,
|
|
102
|
+
): Promise<SingleAssetVaultBalance | undefined> {
|
|
103
|
+
const suiClient = new SuiClient({
|
|
104
|
+
url: getFullnodeUrl("mainnet"),
|
|
105
|
+
});
|
|
106
|
+
const portfolioAmount = await getSingleAssetPortfolioAmount(
|
|
107
|
+
poolName as PoolName,
|
|
108
|
+
{
|
|
109
|
+
suiClient,
|
|
110
|
+
address,
|
|
111
|
+
},
|
|
112
|
+
);
|
|
113
|
+
const portfolioAmountInUSD = await getSingleAssetPortfolioAmountInUSD(
|
|
114
|
+
poolName as PoolName,
|
|
115
|
+
{
|
|
116
|
+
suiClient,
|
|
117
|
+
address,
|
|
118
|
+
},
|
|
119
|
+
);
|
|
120
|
+
if (portfolioAmount !== undefined && portfolioAmountInUSD !== undefined) {
|
|
121
|
+
const res: SingleAssetVaultBalance = {
|
|
122
|
+
coin: portfolioAmount.toString(),
|
|
123
|
+
valueInUSD: portfolioAmountInUSD,
|
|
124
|
+
};
|
|
125
|
+
return res;
|
|
126
|
+
}
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
package/src/getVaults.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { poolInfo } from "./common/maps";
|
|
2
|
+
import { getFullnodeUrl, SuiClient } from "@mysten/sui/client";
|
|
3
|
+
import { getReceipts } from "./functions";
|
|
4
|
+
import { AlphaFiVault } from "./common/types";
|
|
5
|
+
import { getPool } from "./portfolioAmount";
|
|
6
|
+
|
|
7
|
+
function extractCoinTypes(input: string): {
|
|
8
|
+
coinTypeA: string | null;
|
|
9
|
+
coinTypeB: string | null;
|
|
10
|
+
} {
|
|
11
|
+
let regex = /Pool<([^,>]+),\s*([^>]+)>/;
|
|
12
|
+
let match = input.match(regex);
|
|
13
|
+
if (!match) {
|
|
14
|
+
regex = /Pool<([^,>]+)>/;
|
|
15
|
+
match = input.match(regex);
|
|
16
|
+
if (!match) {
|
|
17
|
+
return { coinTypeA: null, coinTypeB: null };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const coinTypeA = match[1] || null;
|
|
21
|
+
const coinTypeB = match[2] || null;
|
|
22
|
+
return { coinTypeA, coinTypeB };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function getVaults(
|
|
26
|
+
address: string,
|
|
27
|
+
): Promise<AlphaFiVault[] | undefined> {
|
|
28
|
+
const vaultsArr = [];
|
|
29
|
+
const suiClient = new SuiClient({
|
|
30
|
+
url: getFullnodeUrl("mainnet"),
|
|
31
|
+
});
|
|
32
|
+
if (address) {
|
|
33
|
+
for (const pool of Object.keys(poolInfo)) {
|
|
34
|
+
const receipt = await getReceipts(pool, { address, suiClient });
|
|
35
|
+
const poolObject = await getPool(pool, { suiClient });
|
|
36
|
+
if (receipt.length > 0 && poolObject) {
|
|
37
|
+
const name = receipt[0].content.fields.name;
|
|
38
|
+
const res: AlphaFiVault = {
|
|
39
|
+
poolId: poolInfo[pool].poolId,
|
|
40
|
+
poolName: null,
|
|
41
|
+
receiptName: name,
|
|
42
|
+
receiptType: receipt[0].content.type,
|
|
43
|
+
coinTypeA: extractCoinTypes(poolObject.content.type).coinTypeA,
|
|
44
|
+
coinTypeB: extractCoinTypes(poolObject.content.type).coinTypeB,
|
|
45
|
+
};
|
|
46
|
+
if (poolInfo[pool].parentProtocolName === "NAVI") {
|
|
47
|
+
res.poolName = name
|
|
48
|
+
.replace(/^AlphaFi-NAVI /, "")
|
|
49
|
+
.replace(/ Receipt$/, "");
|
|
50
|
+
|
|
51
|
+
res.poolName = "NAVI-" + res.poolName;
|
|
52
|
+
} else if (poolInfo[pool].parentProtocolName === "ALPHAFI") {
|
|
53
|
+
res.poolName = name.replace(/^AlphaFi /, "").replace(/ Receipt$/, "");
|
|
54
|
+
} else {
|
|
55
|
+
res.poolName = name.replace(/^AlphaFi /, "").replace(/ Receipt$/, "");
|
|
56
|
+
}
|
|
57
|
+
vaultsArr.push(res);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return vaultsArr;
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { getVaults } from "./getVaults";
|
|
2
|
+
export {
|
|
3
|
+
getAlphaVaultBalance,
|
|
4
|
+
getSingleAssetVaultBalance,
|
|
5
|
+
getDoubleAssetVaultBalance,
|
|
6
|
+
} from "./getVaultBalances";
|
|
7
|
+
export {
|
|
8
|
+
AlphaFiVault,
|
|
9
|
+
AlphaVaultBalance,
|
|
10
|
+
DoubleAssetVaultBalance,
|
|
11
|
+
SingleAssetVaultBalance,
|
|
12
|
+
PoolName,
|
|
13
|
+
} from "./common/types";
|