@quantara/sdk
Version:
JavaScript/TypeScript SDK for interacting with Quantara Protocol on Neura Testnet
152 lines (151 loc) • 5.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Tokens = void 0;
const contracts_1 = require("../../configs/contracts");
const tokens_1 = require("../../configs/tokens");
const tokens_2 = require("../../utils/tokens");
const base_1 = require("../base");
class Tokens extends base_1.Module {
constructor() {
super(...arguments);
this._tokensConfigs = undefined;
}
get tokensConfig() {
if (this._tokensConfigs) {
return this._tokensConfigs;
}
const tokenConfigs = this._tokensConfigs ?? (0, tokens_1.getTokensMap)(this.chainId);
Object.entries(this.sdk.config.tokens ?? []).forEach(([address, token]) => {
tokenConfigs[address] = {
...tokenConfigs[address],
...token,
};
});
this._tokensConfigs = tokenConfigs;
return tokenConfigs;
}
getTokenRecentPrices() {
return this.oracle.getTickers().then((priceItems) => {
const result = {};
priceItems.forEach((priceItem) => {
let tokenConfig;
try {
tokenConfig = (0, tokens_1.getToken)(this.chainId, priceItem.tokenAddress);
}
catch (e) {
// ignore unknown token errors
return;
}
result[tokenConfig.address] = {
minPrice: (0, tokens_2.parseContractPrice)(BigInt(priceItem.minPrice), tokenConfig.decimals),
maxPrice: (0, tokens_2.parseContractPrice)(BigInt(priceItem.maxPrice), tokenConfig.decimals),
};
});
const wrappedToken = (0, tokens_1.getWrappedToken)(this.chainId);
if (result[wrappedToken.address] && !result[tokens_1.NATIVE_TOKEN_ADDRESS]) {
result[tokens_1.NATIVE_TOKEN_ADDRESS] = result[wrappedToken.address];
}
return {
pricesData: result,
updatedAt: Date.now(),
};
});
}
getTokensBalances(account, tokensList) {
account = account || this.sdk.config.account;
tokensList = tokensList || (0, tokens_1.getV2Tokens)(this.chainId);
return this.sdk
.executeMulticall(tokensList.reduce((acc, token) => {
// Skip synthetic tokens
if (token.isSynthetic)
return acc;
const address = token.address;
if (address === tokens_1.NATIVE_TOKEN_ADDRESS) {
acc[address] = {
contractAddress: (0, contracts_1.getContract)(this.chainId, "Multicall"),
abiId: "Multicall",
calls: {
balance: {
methodName: "getEthBalance",
params: [account],
},
},
};
}
else {
acc[address] = {
contractAddress: address,
abiId: "Token",
calls: {
balance: {
methodName: "balanceOf",
params: [account],
},
},
};
}
return acc;
}, {}))
.then((res) => {
return Object.keys(res.data).reduce((tokenBalances, tokenAddress) => {
tokenBalances[tokenAddress] = res.data[tokenAddress].balance.returnValues[0];
return tokenBalances;
}, {});
});
}
getNativeToken() {
return this.tokensConfig[tokens_1.NATIVE_TOKEN_ADDRESS];
}
async getTokensData() {
const tokenConfigs = this.tokensConfig;
// Try to get API tokens and prices separately to handle failures gracefully
let allTokens = [];
let pricesData;
let pricesUpdatedAt;
try {
allTokens = await this.sdk.oracle.getTokens();
}
catch (error) {
console.warn('Failed to fetch API tokens:', error.message);
}
try {
const pricesResult = await this.getTokenRecentPrices();
pricesData = pricesResult.pricesData;
pricesUpdatedAt = pricesResult.updatedAt;
}
catch (error) {
console.warn('Failed to fetch token prices:', error.message);
pricesData = undefined;
pricesUpdatedAt = undefined;
}
const nativeToken = this.getNativeToken();
const tokens = [nativeToken, ...allTokens];
const balancesData = this.account ? await this.getTokensBalances(this.account, tokens) : {};
if (!pricesData) {
return {
tokensData: undefined,
pricesUpdatedAt: undefined,
};
}
return {
tokensData: tokens.reduce((acc, token) => {
const tokenAddress = token.address;
const prices = pricesData[tokenAddress];
const balance = balancesData?.[tokenAddress];
const tokenConfig = tokenConfigs[tokenAddress];
if (!prices) {
return acc;
}
acc[tokenAddress] = {
...token,
...tokenConfig,
prices,
balance,
};
return acc;
}, {}),
pricesUpdatedAt,
};
}
}
exports.Tokens = Tokens;