use cache for static data

This commit is contained in:
g1nt0ki
2025-10-22 10:15:46 +02:00
parent d5dd513e6b
commit 0de91d6649
19 changed files with 94 additions and 203 deletions

View File

@@ -1,6 +1,6 @@
const { PublicKey } = require("@solana/web3.js");
const { getMultipleAccounts } = require('../helper/solana')
const axios = require("axios");
const { getConfig } = require("../helper/cache");
function deserializeUserPositions(accountInfo) {
if (!accountInfo) {
@@ -95,16 +95,8 @@ async function fetchVaultUserAddressesWithOffset(data, offset) {
}
async function fetchVaultAddresses() {
try {
const response = await axios.get('https://raw.githubusercontent.com/LuckyFutureAi/LuckyFuture-Assets/refs/heads/main/vaults-info.json');
if (response.status !== 200) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.data.vaults;
} catch (error) {
console.error('Error fetching vault addresses:', error);
throw error;
}
const data = await getConfig('lucky-future/vaults', 'https://raw.githubusercontent.com/LuckyFutureAi/LuckyFuture-Assets/refs/heads/main/vaults-info.json');
return data.vaults
}

View File

@@ -5,8 +5,8 @@ const {
} = require('../helper/solana');
const ADDRESSES = require('../helper/coreAssets.json')
const {PublicKey} = require('@solana/web3.js')
const {default: axios} = require('axios')
const {getLowestOfferPrice, getOfferTokenAccounts} = require('./offerUtils');
const { getConfig } = require('../helper/cache');
const MINT = '5Y8NV33Vv7WbnLfq3zBcKSdYPrk7g2KoiQoe7M2tcxp5';
@@ -17,8 +17,7 @@ const onreOffchain = 'https://onre-api-prod.ew.r.appspot.com/offers';
async function tvl(api) {
// --- Dynamic offers implementation ---
const offers = (await axios.get(onreOffchain)).data;
console.log(offers);
const offers = await getConfig('onre/offers', onreOffchain);
const lowestPrice = getLowestOfferPrice(offers, ADDRESSES.solana.USDC);
const allTokenAccounts = getOfferTokenAccounts(offers, MINT, programId);
const bossTokenAccount = getAssociatedTokenAddress(MINT, BOSS);

View File

@@ -1,4 +1,3 @@
const axios = require("axios");
const { fetchLocal, mkMeta } = require("../helper/pact");
const chainId = "3";

View File

@@ -1,13 +1,12 @@
const axios = require('axios')
const bitcoinAddressBook = require("../helper/bitcoin-book/index.js");
const { sumTokensExport } = require('../helper/sumTokens')
const ADDRESSES = require('../helper/coreAssets.json')
const { defaultTokens } = require('../helper/cex')
const { getConfig } = require('../helper/cache.js')
const API_URL = 'https://api.backpack.exchange/api/v1/wallets'
const getConfig = async () => {
const { data } = await axios.get(API_URL)
const _getConfig = async () => {
const data = await getConfig('backpack/wallets', API_URL)
const config = {}
data.forEach(({ address, blockchain }) => {
let chain = blockchain.toLowerCase()
@@ -24,7 +23,7 @@ const chains = ['ethereum', 'solana', 'bitcoin', 'litecoin', 'arbitrum', 'optimi
chains.forEach((chain) => {
exportObj[chain] = {
tvl: async () => {
const config = await getConfig()
const config = await _getConfig()
const entry = config[chain]
if (!entry) return {}

View File

@@ -1,10 +1,10 @@
const axios = require('axios')
const { queryContract: queryContractCosmos } = require("../helper/chain/cosmos");
const { getConfig } = require('../helper/cache');
const URL = "https://blackpanther.fi/mainnet/api/vaults"
const tvl = async (api) => {
const { data } = await axios.get(URL)
const data = await getConfig('blackpanther/vaults', URL);
const vaults = data.map((d) => d.vault_address)
for (const vault of vaults) {
const { asset } = await queryContractCosmos({ chain: api.chain, contract: vault, data: { total_vault: {} } });

View File

@@ -1,16 +1,14 @@
const ADDRESSES = require('../helper/coreAssets.json')
const { default: axios } = require("axios")
const { get } = require('../helper/http')
const token = ADDRESSES.ethereum.cbETH
module.exports = {
timetravel: false,
ethereum: {
tvl: async (timestamp, block) => {
if(timestamp < Date.now()/1e3 - 3600){
throw new Error("Only works for current info")
}
const data = await axios.get("https://api.exchange.coinbase.com/wrapped-assets/CBETH")
tvl: async () => {
const data = await get("https://api.exchange.coinbase.com/wrapped-assets/CBETH")
return {
[token]: data.data.circulating_supply * 1e18
[token]: data.circulating_supply * 1e18
}
}
}

View File

@@ -1,4 +1,4 @@
const axios = require('axios')
const { getConfig } = require('../helper/cache')
const URL = 'https://apy.api.concrete.xyz/v1/vault:tvl/all'
@@ -10,7 +10,7 @@ const abis = {
const tvl = async (api) => {
const chainId = api.chainId
const { data } = await axios.get(URL)
const data = await getConfig('concrete-xyz/vaults', URL)
const datas = Object.values(data[chainId]).map(v => v.address)
const [assets, strategiess] = await Promise.all([

View File

@@ -1,13 +1,13 @@
const axios = require("axios");
const { sui } = require("../helper/chain/rpcProxy");
const { getConfig } = require("../helper/cache");
const PACKAGE_ID =
"0xc83d5406fd355f34d3ce87b35ab2c0b099af9d309ba96c17e40309502a49976f";
async function suiTvl(api) {
const vaults = (
await axios.get(`https://vaults.api.sui-prod.bluefin.io/api/v1/vaults/info`)
).data.Vaults;
await getConfig('ember-protocol/vaults', `https://vaults.api.sui-prod.bluefin.io/api/v1/vaults/info`)
).Vaults;
for (const vault of Object.values(vaults)) {
const vaultTvl = await sui.query({
target: `${PACKAGE_ID}::vault::get_vault_tvl`,

View File

@@ -1,10 +1,10 @@
const axios = require("axios");
const suiTx = require("./suiTx");
const { getConfig } = require("../helper/cache");
async function suiTVL(api) {
const packageId = "0x8462eb7e1c52018f42f2dd2c33605f7212ad8702739a5eaacb0e1a0106f3dc6a";
const resp = await axios.get("https://haedal.xyz/api/v3/sui/vaults/pools?category=haedal&order_by=tvl&id=&coin_type=");
const vaultList = resp?.data?.data?.list;
const resp = await getConfig('haedal/vault', "https://haedal.xyz/api/v3/sui/vaults/pools?category=haedal&order_by=tvl&id=&coin_type=");
const vaultList = resp?.data?.list;
for (const vault of vaultList) {
const { coin_type_a, coin_type_b, lp_type, id, clmm_pool } = vault;

View File

@@ -1,92 +1,41 @@
const ADDRESSES = require("../helper/coreAssets.json");
const { getConfig } = require("../helper/cache");
const { staking } = require("../helper/staking");
const { sumTokensExport } = require("../helper/unknownTokens");
const axios = require('axios');
const lisLPs = [
"0xe8f4644637f127aFf11F9492F41269eB5e8b8dD2", // Lista LP Stable-LP
"0xFf5ed1E64aCA62c822B178FFa5C36B40c112Eb00", // Lista LP aSnBNB-WBNB
"0x4b2D67Bf25245783Fc4C33a48962775437F9159c", // Lista LP aUSDT-LISTA
"0xC23d348f9cC86dDB059ec798e87E7F76FBC077C1", // Lista LP aHAY-USDT
"0xF6aB5cfdB46357f37b0190b793fB199D62Dcf504", // Lista LP UV-17-THE
"0x1Cf9c6D475CdcA67942d41B0a34BD9cB9D336C4d", // Lista LP sAMM-HAY/FRAX
"0x9eb77a54a33069a319d91f493e6b1c9066fb38f7" // Lista LP pancake lisUSD/USDT
];
"0xe8f4644637f127aFf11F9492F41269eB5e8b8dD2", // Lista LP Stable-LP
"0xFf5ed1E64aCA62c822B178FFa5C36B40c112Eb00", // Lista LP aSnBNB-WBNB
"0x4b2D67Bf25245783Fc4C33a48962775437F9159c", // Lista LP aUSDT-LISTA
"0xC23d348f9cC86dDB059ec798e87E7F76FBC077C1", // Lista LP aHAY-USDT
"0xF6aB5cfdB46357f37b0190b793fB199D62Dcf504", // Lista LP UV-17-THE
"0x1Cf9c6D475CdcA67942d41B0a34BD9cB9D336C4d", // Lista LP sAMM-HAY/FRAX
"0x9eb77a54a33069a319d91f493e6b1c9066fb38f7" // Lista LP pancake lisUSD/USDT
];
const abi = {
lpToken: "address:lpToken",
totalSupply: "uint256:totalSupply",
lpToken: "address:lpToken",
totalSupply: "uint256:totalSupply",
};
const pool2 = async (api) => {
const [lisLpTokens, lisLpBalances] = await Promise.all([
api.multiCall({calls: lisLPs.map((lis) => ({ target: lis })), abi: abi.lpToken }),
api.multiCall({calls: lisLPs.map((lis) => ({ target: lis })), abi: abi.totalSupply }),
]);
const [lisLpTokens, lisLpBalances] = await Promise.all([
api.multiCall({ calls: lisLPs, abi: abi.lpToken }),
api.multiCall({ calls: lisLPs, abi: abi.totalSupply }),
]);
lisLPs.forEach((_lp, i) => {
api.add(lisLpTokens[i], lisLpBalances[i])
})
api.add(lisLpTokens, lisLpBalances)
}
module.exports = {
methodology: "The TVL is calculated by summing the values of tokens held in the specified vault addresses",
hallmarks: [
[1669939200, "aBNBc exploit"],
//[1670544000,"aBNBc to AnkrBNB swap & HAY buyback"]
],
bsc: {
tvl: async (api) => {
let tokensAndOwners;
try {
const { data } = await axios.get('https://api.lista.org/api/defiLlama/cdp-vault-list');
if (data && data.code === '000000000' && Array.isArray(data.data)) {
tokensAndOwners = data.data;
} else {
throw new Error('Invalid API response');
}
} catch (e) {
// fallback to static if API fails
tokensAndOwners = [
[ADDRESSES.null, "0x986b40C2618fF295a49AC442c5ec40febB26CC54"],
["0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B", "0x6F28FeC449dbd2056b76ac666350Af8773E03873"],
["0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B", "0x91e49983598685DD5ACAc90CEb4061A772f6E5Ae"],
[ADDRESSES.bsc.ETH, "0xA230805C28121cc97B348f8209c79BEBEa3839C0"],
[ADDRESSES.bsc.wBETH, "0xf45C3b619Ee86F653805E007fE211B7e930E0b3B"],
[ADDRESSES.bsc.wBETH, "0xA230805C28121cc97B348f8209c79BEBEa3839C0"],
[ADDRESSES.bsc.BTCB, "0xad9eAAe95617c39019aCC42301a1dCa4ea5b6f65"],
[ADDRESSES.blast.ezETH, "0xd7E33948e2a43e7C1ec2F19937bf5bf8BbF9BaE8"],
[ADDRESSES.blast.weETH, "0x2367f2Da6fd39De6944218CC9EC706BCdc9a6918"],
[ADDRESSES.scroll.STONE, "0x876cd9a380Ee7712129b52f8293F6f06056c3104"],
["0x4aae823a6a0b376De6A78e74eCC5b079d38cBCf7", "0xA94AA72e033b39AD7CD448f38Bc1eda5B52f7079"],
["0xF5e11df1ebCf78b6b6D26E04FF19cD786a1e81dC", "0x157c9a692ee99C39272856055957083a928cE299"],
["0x26c5e01524d2E6280A48F2c50fF6De7e52E9611C", "0xf8Ca8D2B59A97125751af1069d4a5C4F7eB7A677"],
["0x1346b618dC92810EC74163e4c27004c921D446a5","0x03DB750d6212C6a0BCa9258E8cB7cf46dfD63067"],
[ADDRESSES.bsc.USDT, "0xAd406CcF75f9E6216fA4349635B0cD77D0059b1f"],
[ADDRESSES.ethereum.FDUSD,"0x2202a491752Fee0E616F06A89E2eF416E2Fcd7e9"],
["0x7788A3538C5fc7F9c7C8A74EAC4c898fC8d87d92", "0x98b167359566c1ea05335D52794C7Eb6f8E6739a"],
["0xfd5840cd36d94d7229439859c0112a4185bc0255","0xf76D9cFD08dF91491680313B1A5b44307129CDa9"],
["0xf9C4FF105803A77eCB5DAE300871Ad76c2794fa4", "0xEA44dDC58eC6b4902E19A353c554B6A4F32b9e6E"],
["0x7c1cCA5b25Fa0bC9AF9275Fb53cBA89DC172b878", "0x8A016f1896dC2939fFDbB60f6E42bCc245e2bB0b"],
["0x581FA684D0Ec11ccb46B1d92F1F24C8A3F95C0CA", "0x605356cc9f725e6744A51E78CD49E6029DcC4404"],
["0x7dc91cbd6cb5a3e6a95eed713aa6bf1d987146c8", "0x3cd434f0A58018B87eF1D2436cb710ca46F0fC43"],
["0x5A110fC00474038f6c02E89C707D638602EA44B5", "0x8B35291ecF29fD36BA405A03C9832725f2E9e164"],
["0x917AF46B3C3c6e1Bb7286B9F59637Fb7C65851Fb", "0xB53e69b662a2d10343f857eBa9e3b6158Acf632F"],
[ADDRESSES.bsc.BTCB, "0x1AfA1589a634BE568D7872dCF1bbE6F79e11FaD5"],
];
}
return sumTokensExport({ tokensAndOwners })(api);
},
pool2,
staking: staking('0xd0C380D31DB43CD291E2bbE2Da2fD6dc877b87b3','0xFceB31A79F71AC9CBDCF853519c1b12D379EdC46')
methodology: "The TVL is calculated by summing the values of tokens held in the specified vault addresses",
hallmarks: [
[1669939200, "aBNBc exploit"],
],
bsc: {
tvl: async (api) => {
const { data: tokensAndOwners } = await getConfig('helio/vaults', 'https://api.lista.org/api/defiLlama/cdp-vault-list');
return api.sumTokens({ tokensAndOwners })
},
pool2,
staking: staking('0xd0C380D31DB43CD291E2bbE2Da2fD6dc877b87b3', '0xFceB31A79F71AC9CBDCF853519c1b12D379EdC46')
},
};
// execute with `node test.js projects/helio-money`

View File

@@ -1,58 +1,10 @@
const axios = require("axios");
const { uniTvlExports } = require('../helper/unknownTokens')
module.exports = uniTvlExports({
'hedera': '0x0000000000000000000000000000000000134224'
})
const urlConfigs = {
graphQLUrl: "https://heliswap-prod-362307.oa.r.appspot.com/query",
tokenListUrl: "https://heliswap-api.ey.r.appspot.com/tokens/whitelisted/",
};
module.exports.hallmarks = [
['2023-10-30', 'Protocol is sunset'],
]
const axiosConfig = {
url: urlConfigs.graphQLUrl,
method: "post",
};
const getWhitelistedTokenAddresses = async () => {
const response = await axios(urlConfigs.tokenListUrl);
const { data: whitelistedTokens } = response;
return whitelistedTokens;
};
const tvl = async () => {
let totalTVL = 0;
const whitelistedAddresses = await getWhitelistedTokenAddresses();
const { url, method } = axiosConfig;
const requestData = {
query: `query getWhitelistedPools($tokens: [String]!) {
poolsConsistingOf(tokens: $tokens) {
tvl
}
}`,
variables: {
tokens: whitelistedAddresses,
},
};
const requestObject = {
url,
method,
data: requestData,
};
const {
data: { data: { poolsConsistingOf }}
} = await axios(requestObject);
totalTVL = poolsConsistingOf.reduce((acc, pool) => (isNaN(+pool.tvl) || +pool.tvl > 1e8) ? acc : acc + +pool.tvl, 0)
return { tether: totalTVL };
};
module.exports = {
timetravel: false,
misrepresentedTokens: true,
hedera: {
tvl,
},
};
console.log(module.exports)

View File

@@ -117,6 +117,10 @@ const fixBalancesTokens = {
'0x7bbc63d01ca42491c3e084c941c3e86e55951404': { coingeckoId: 'zero-gravity', decimals: 18 }, // st0G (Liquid Staking 0G from Gimo)
'0x9cc1d782e6dfe5936204c3295cb430e641dcf300': { coingeckoId: 'ethereum', decimals: 18 }, // WETH (Wrapped ETH)
'0x1f3aa82227281ca364bfb3d253b0f1af1da6473e': { coingeckoId: 'usd-coin', decimals: 6 }, // USDCe (Bridged USDC)
},
'hedera': {
'0x00000000000000000000000000000000000F7e89': { coingeckoId: 'hedera-hashgraph', decimals: 8 },
'0x00000000000000000000000000000000002cc823': { coingeckoId: 'hedera-hashgraph', decimals: 8 },
}
}

View File

@@ -1,4 +1,4 @@
const axios = require('axios')
const { getConfig } = require('../helper/cache');
const API_URL = "https://api.liminal.money/api/info/tvl-history";
const API_ASSET_URL = "https://api.liminal.money/api/info/strategy-assets";
@@ -16,14 +16,14 @@ const COINGECKO_MAPPING = {
};
async function fetchAssetList() {
const response = await axios.get(API_ASSET_URL);
const assets = response.data.data;
const response = await getConfig('liminal-money/asset-list', API_ASSET_URL);
const assets = response.data;
return assets.map(({ _id, perpName, spotName }) => ({ id: _id, perpName, spotName }))
}
const getClosestRecord = async (api) => {
const targetMs = api.timestamp * 1000;
const { data: { data: records } } = await axios.get(API_URL);
const { data: records } = await getConfig('liminal-money/tvl-history', API_URL);
const closest = records
.map((r) => ({ ...r, diff: Math.abs(new Date(r.timestamp).getTime() - targetMs) }))

View File

@@ -1,6 +1,6 @@
const { queryContract } = require('../helper/chain/cosmos');
const axios = require('axios');
const BigNumber = require('bignumber.js');
const { getConfig } = require('../helper/cache');
const contractAddresses = {
osmosis: {
@@ -54,7 +54,7 @@ async function tvl(api) {
const assetDenoms = assetParams.map((asset) => asset.denom);
// fetch pool infos from the poolsApi based on chain
const poolInfos = await axios.get(poolsApis[chain]);
const poolInfos = await getConfig(`mars-protocol/${chain}-pools`, poolsApis[chain]);
// query the deposited amount for each asset and add it to the depositCoins array
await Promise.all(
@@ -66,7 +66,7 @@ async function tvl(api) {
});
// check if the token is a liquidity pool share (deposited via farm)
// and find it in the api data
const poolInfo = poolInfos.data.tokens.find((pool) => pool.lpAddress === denom);
const poolInfo = poolInfos.tokens.find((pool) => pool.lpAddress === denom);
if (poolInfo) {
// check for the underlying asset and calculate how much underlying assets a pool share holds

View File

@@ -1,5 +1,5 @@
const axios = require("axios");
const { function_view } = require('../helper/chain/aptos');
const { getConfig } = require("../helper/cache");
const PROPS_FA = "0x6dba1728c73363be1bdd4d504844c40fbb893e368ccbeff1d1bd83497dbc756d";
const USDC_FA = "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b";
@@ -16,7 +16,7 @@ module.exports = {
aptos: {
tvl: async (api) => {
const chain = "aptos";
const { data } = await axios.get(`https://contractaddress.propbase.app/production`);
const data = await getConfig('propbase/config', `https://contractaddress.propbase.app/production`);
// --- RWA Pools (USDC) ---
for (const pool of data.NOVA_POOLS) {
@@ -81,7 +81,7 @@ module.exports = {
staking: async (api) => {
const chain = "aptos";
const { data } = await axios.get(`https://contractaddress.propbase.app/production`);
const data = await getConfig('propbase/config', `https://contractaddress.propbase.app/production`);
for (const pool of data.STAKING_POOLS) {
const fa_balance = await function_view({

View File

@@ -1,8 +1,8 @@
const ADDRESSES = require('../helper/coreAssets.json')
const axios = require('axios');
const ADDRESSES = require('../helper/coreAssets.json')
const { PublicKey } = require("@solana/web3.js");
const { sumTokens2, ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } = require('../helper/solana');
const BN = require("bn.js");
const { getConfig } = require('../helper/cache');
const programId = new PublicKey('ProPh6ruVL41JR3XXPuy6hN6TPH1ERqpWkZ9dp9YSEe')
const globalState = new PublicKey('6PZKJowZMUAgxLxAJmHsrvzEL8PdXNymqYSJDwPRgh6V')
@@ -33,10 +33,11 @@ function getPredictionMarketAddress(marketId) {
}
async function tvl(api) {
const lastRoundId = await axios.get("https://backend.prophet.fun/business-metrics/last-round-id")
const { data } = await getConfig('prophet-fun/markets', 'https://backend.prophet.fun/business-metrics/get-markets?page=1&perPage=1000&sortDirection=desc&sortField=volume24h&statusFromFront=active')
const ids = data.map(market => market.marketBase.id)
const tokenAccounts = []
Array.from({ length: lastRoundId.data.roundId }, (_, i) => i + 1).forEach((roundId) => {
ids.forEach((roundId) => {
const marketAddress = getPredictionMarketAddress(roundId)
const marketAta = getAta(marketAddress)
tokenAccounts.push(marketAta)

View File

@@ -1,8 +1,7 @@
const axios = require('axios');
const { getConfig } = require('../helper/cache');
async function getOraclePackages() {
const response = await axios.get('https://v2.roaracle.app/records');
const raw = response.data;
const raw = await getConfig('rho/oracle', 'https://v2.roaracle.app/records');
return raw.map(entry => ({
marketId: entry.oraclePackage.marketId,

View File

@@ -1,11 +0,0 @@
module.exports = {
ethereum: 1,
optimism: 10,
bsc: 56,
manta: 169,
canto: 7700,
base: 8453,
arbitrum: 42161,
scroll: 534352,
swellchain: 1923,
}

View File

@@ -1,10 +1,20 @@
const { getConfig } = require("../helper/cache");
const { sumTokens2 } = require("../helper/unwrapLPs");
const chains = require("./chains");
const axios = require("axios");
const chains = {
ethereum: 1,
optimism: 10,
bsc: 56,
manta: 169,
canto: 7700,
base: 8453,
arbitrum: 42161,
scroll: 534352,
swellchain: 1923,
}
async function tvl(api) {
const response = await axios.get(`https://protocol-service-api.tempestfinance.xyz/api/v1/vaults?chainId=${chains[api.chain]}`)
const vaults = response.data.data.vaults;
const response = await getConfig(`tempest-fi/${api.chain}`, `https://protocol-service-api.tempestfinance.xyz/api/v1/vaults?chainId=${chains[api.chain]}`)
const vaults = response.data.vaults;
const tokens = vaults.map(vault => vault.mainAsset);
const balances = await api.multiCall({ abi: 'uint256:totalAssets', calls: vaults.map(vault => vault.address) });