@syncswap/sdk
Version:
SyncSwap TypeScript SDK for building DeFi applications
69 lines • 2.55 kB
JavaScript
import { Token } from "./token.js";
import ContractRegistry from "../contracts/contractRegistry.js";
import { TokenRegistry } from "./tokenRegistry.js";
// Token metadata are relatively immutable so it's safe to keep a static cache.
const cacheMap = new Map();
export default async function fetchToken(provider, address) {
address = address.toLowerCase(); // fix case
if (address === Token.ETHER.address) {
return Token.ETHER;
}
const known = TokenRegistry.getTokenByAddress(address);
if (known) {
return known;
}
const cached = cacheMap.get(address);
if (cached) {
return cached;
}
try {
const tokenHelper = ContractRegistry.getContractByName("token_helper");
const { decimals, symbol, name, isPermit } = await retry(async () => await tokenHelper.tokenMetadata(address));
//console.log('fetchToken', decimals, symbol, name, address);
// invalid tokens (contract that is not a token?)
if (decimals === 0 && symbol == "" && name == "") {
return null;
}
const token = new Token(address, decimals, symbol == "" ? address.substring(0, 6) : symbol, name == "" ? address.substring(0, 8) : name, isPermit);
cacheMap.set(address, token);
return token;
}
catch (error) {
console.error("fetchToken: error on fetch token", address, error);
return null;
}
}
async function retry(doFunc, retry = 5) {
return new Promise(async (resolve, reject) => {
for (let i = 0; i < retry; i++) {
try {
// use promise.race to kill first promise when execute over 10 seconds
const res = await Promise.any([
doFunc(),
new Promise((resolve) => {
setTimeout(() => resolve(false), 10000);
}),
]);
if (res === false) {
throw new Error("RPC Error: JsonRpcEngine: Response timeout");
}
return resolve(res);
}
catch (error) {
if (i === retry - 1) {
console.error("retry: request failed after retry", doFunc, error);
return reject(error);
}
else {
await sleep(100);
}
}
}
});
}
async function sleep(timeout) {
await setTimeout(() => {
// do nothing
}, timeout);
}
//# sourceMappingURL=fetchToken.js.map