diff --git a/back/back.js b/back/back.js index 3d5a5c1..d8e4498 100644 --- a/back/back.js +++ b/back/back.js @@ -8,6 +8,11 @@ import express from 'express' import fetch from 'node-fetch' import { createClient } from 'redis' +import dotenv from 'dotenv' +dotenv.config({ + path: '.env' +}) +console.log(process.env.THE_GRAPH_API) /******************************** @@ -38,6 +43,16 @@ const HISTORY_SIZE = process.env.NODE_ENV === 'production' ? 320 : 96 // more da const HISTORY_SIZE_24H = 96 // 24h / 15min const TOP_SIZE = 6 +const THE_GRAPH_API = process.env.THE_GRAPH_API +const THE_GRAPH_BASE_URL = `https://gateway.thegraph.com/api/${THE_GRAPH_API}/subgraphs/id` + +const THE_GRAPH_UniswapV3Ethereum = THE_GRAPH_BASE_URL + '/5zvR82QoaXYFyDEKLZ9t6v9adgnptxYpKpSbxtgVENFV' +const THE_GRAPH_UniswapV3Arbitrum = THE_GRAPH_BASE_URL + '/FbCGRftH4a3yZugY7TnbYgPJVEv2LvMT6oF1fxPe9aJM' +const THE_GRAPH_UniswapV3Optimism = THE_GRAPH_BASE_URL + '/Cghf4LfVqPiFw6fp6Y5X5Ubc8UpmUhSfJL82zwiBFLaj' +const THE_GRAPH_UniswapV3Polygon = THE_GRAPH_BASE_URL + '/3hCPRGf4z88VC5rsBKU5AA9FBBq5nF3jbKJG7VZCbhjm' +const THE_GRAPH_PancakeswapV3BNB = THE_GRAPH_BASE_URL + '/A1fvJWQLBeUAggX2WQTMm3FKjXTekNXo77ZySun4YN2m' +const THE_GRAPH_HoneyswapGnosis = THE_GRAPH_BASE_URL + '/HTxWvPGcZ5oqWLYEVtWnVJDfnai2Ud1WaABiAR72JaSJ' + /* Redis */ @@ -77,7 +92,7 @@ async function get(url, query = null) { const pancakeswap_request = ` query { - tokens(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc, where: { volumeUSD_gt: "10000", derivedETH_gt: "0", totalValueLockedUSD_gt: "25000" } ) { + tokens(first: 400, orderBy: totalValueLockedUSD, orderDirection: desc, where: { volumeUSD_gt: "10000", derivedETH_gt: "0", totalValueLockedUSD_gt: "25000" } ) { id name symbol @@ -92,7 +107,7 @@ query // Use TheGraph API - https://thegraph.com/hosted-service/subgraph/pancakeswap/exchange-v3-bsc async function getPancakeswapTopTokens() { - return await get('https://api.thegraph.com/subgraphs/name/pancakeswap/exchange-v3-bsc', pancakeswap_request) + return await get(THE_GRAPH_PancakeswapV3BNB, pancakeswap_request) } @@ -147,7 +162,7 @@ async function getUniswapV3BNBTopTokens() { const uniswapV3_arbitrum_request = ` query { - tokens(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc, where: { volumeUSD_gt: "50000", derivedETH_gt: "0", totalValueLockedUSD_gt: "25000" } ) { + tokens(first: 400, orderBy: totalValueLockedUSD, orderDirection: desc, where: { volumeUSD_gt: "50000", derivedETH_gt: "0", totalValueLockedUSD_gt: "25000" } ) { id name symbol @@ -163,14 +178,14 @@ query // Use TheGraph API - https://thegraph.com/hosted-service/subgraph/revert-finance/uniswap-v3-arbitrum // https://github.com/revert-finance/uniswap-v3-subgraph async function getUniswapV3ArbitrumTopTokens() { - return await get('https://api.thegraph.com/subgraphs/name/revert-finance/uniswap-v3-arbitrum', uniswapV3_arbitrum_request) + return await get(THE_GRAPH_UniswapV3Arbitrum, uniswapV3_arbitrum_request) } // Get Uniswap v3 top const uniswapV3_request = ` query { - tokens(first: 1000, orderBy: totalValueLockedUSD, orderDirection: desc, where: { volumeUSD_gt: "10000", derivedETH_gt: "0", totalValueLockedUSD_gt: "50000" } ) { + tokens(first: 400, orderBy: totalValueLockedUSD, orderDirection: desc, where: { volumeUSD_gt: "10000", derivedETH_gt: "0", totalValueLockedUSD_gt: "50000" } ) { id name symbol @@ -185,7 +200,7 @@ query // Use TheGraph API - https://thegraph.com/hosted-service/subgraph/uniswap/uniswap-v3 async function getUniswapV3TopTokens() { - return await get('https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3', uniswapV3_request) + return await get(THE_GRAPH_UniswapV3Ethereum, uniswapV3_request) } // Get Uniswap v2 top @@ -254,6 +269,30 @@ async function getPolygonSushiSwapTopTokens() { return await get('https://api.thegraph.com/subgraphs/name/sushiswap/matic-exchange', polygon_sushiswap_request) } + +// Get Uniswap v3 top on Polygon/Matic +const uniswapV3Polygon_request = ` +query +{ + tokens(first: 400, orderBy: totalValueLockedUSD, orderDirection: desc, where: { volumeUSD_gt: "10000", derivedETH_gt: "0", totalValueLockedUSD_gt: "50000" } ) { + id + name + symbol + derivedETH + volumeUSD + } + bundle(id: "1" ) { + ethPriceUSD + } +} +` + +// Use TheGraph API - https://thegraph.com/hosted-service/subgraph/uniswap/uniswap-v3 +async function getUniswapV3PolygonTopTokens() { + return await get(THE_GRAPH_UniswapV3Polygon, uniswapV3Polygon_request) +} + + // Get Spiritswap's top const spiritswap_request = ` query @@ -280,22 +319,22 @@ async function getSpiritswapTopTokens() { const honeyswap_request = ` query { - tokens(first: 1000, orderBy: tradeVolumeUSD, orderDirection: desc, where: { tradeVolumeUSD_gt: "100000", derivedETH_gt: "0" } ) { + tokens(first: 250, orderBy: tradeVolumeUSD, orderDirection: desc, where: { tradeVolumeUSD_gt: "100000", derivedNativeCurrency_gt: "0" } ) { id name symbol - derivedETH + derivedNativeCurrency tradeVolumeUSD } bundle(id: "1" ) { - ethPrice + nativeCurrencyPrice } } ` // Use TheGraph API - https://thegraph.com/explorer/subgraph/kirkins/honeyswap async function getHoneyswapTopTokens() { - return await get('https://api.thegraph.com/subgraphs/name/kirkins/honeyswap', honeyswap_request) + return await get(THE_GRAPH_HoneyswapGnosis, honeyswap_request) } @@ -431,7 +470,7 @@ async function launchGnosis() { const time = Date.now() const tokens = top.data ? top.data.tokens : [] - const xdai_price = top.data ? top.data.bundle.ethPrice : 0 + const xdai_price = top.data ? top.data.bundle.nativeCurrencyPrice : 0 if(xdai_price === 0 || tokens.length === 0) return try { @@ -446,7 +485,7 @@ async function launchGnosis() { address: token.id, symbol: token.symbol, name: token.name, - price: token.derivedETH * xdai_price, + price: token.derivedNativeCurrency * xdai_price, volumeUSD: token.tradeVolumeUSD } @@ -480,12 +519,12 @@ async function launchPolygon() { let data = {} // get data from Uniswap - const top = await getQuickswapV3TopTokens() + const top = await getUniswapV3PolygonTopTokens() const time = Date.now() const tokens = top.data ? top.data.tokens : [] - const matic_price = top.data ? top.data.bundle.maticPriceUSD : 0 + const matic_price = top.data ? top.data.bundle.ethPriceUSD : 0 if(matic_price === 0 || tokens.length === 0) return try { @@ -500,7 +539,7 @@ async function launchPolygon() { address: token.id, symbol: token.symbol, name: token.name, - price: token.derivedMatic * matic_price, + price: token.derivedETH * matic_price, volumeUSD: token.volumeUSD } @@ -790,7 +829,7 @@ async function main() { setTimeout(launchPolygon, 20000) - setTimeout(launchFantom, 25000) + // setTimeout(launchFantom, 25000) setTimeout(launchArbitrum, 30000) diff --git a/beta/charts.html b/beta/charts.html index e143034..df88382 100644 --- a/beta/charts.html +++ b/beta/charts.html @@ -47,7 +47,7 @@ - + diff --git a/beta/public/common.js b/beta/public/common.js index 26b5079..3c991ba 100644 --- a/beta/public/common.js +++ b/beta/public/common.js @@ -134,7 +134,7 @@ const NETWORK = { shortName: 'bnb', img: '/img/bsc-icon.svg', color: '#f0b931', - rpc: 'https://1rpc.io/bnb', + rpc: 'https://bsc.meowrpc.com', // https://1rpc.io/bnb explorer: 'https://bscscan.com/token/', normaltx: 'https://api.bscscan.com/api?module=account&action=txlist&address=WALLET_ADDRESS&startblock=START_BLOCK&sort=asc', tokentx: 'https://api.bscscan.com/api?module=account&action=tokentx&address=WALLET_ADDRESS&startblock=START_BLOCK&sort=asc', @@ -232,10 +232,10 @@ const NETWORK = { tokenPriceContract: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', subgraph_url: 'https://thegraph.com/hosted-service/subgraph/layer3org/spiritswap-analytics', coingecko_name: 'fantom', - tokens: { - token: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', - base: '0x04068da6c83afcfa0e13ba15a6696662335d5b75' - }, + // tokens: { + // token: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + // base: '0x04068da6c83afcfa0e13ba15a6696662335d5b75' + // }, url: 'https://www.spiritswap.finance/', url_swap: 'https://swap.spiritswap.finance/#/swap' }, @@ -439,6 +439,13 @@ async function get(url, query = null) { }) } +Object.defineProperty(BigInt.prototype, "toJSON", { + get() { + "use strict" + return () => String(this) + } +}) + document.addEventListener('DOMContentLoaded', function() { diff --git a/beta/public/js/paraswap.js b/beta/public/js/paraswap.js index c27eabf..d7a4a2d 100644 --- a/beta/public/js/paraswap.js +++ b/beta/public/js/paraswap.js @@ -27,7 +27,7 @@ const configureParaswap = (srcToken, destToken, amount, srcDecimals, destDecimal } const setParaswapAmount = (amount) => { - paraswapAmount = Math.floor(Number(amount) * Math.pow(10, paraswapSrcDecimals)) + paraswapAmount = Math.floor(Number(amount) * Math.pow(10, Number(paraswapSrcDecimals))) setQueries() } @@ -49,5 +49,5 @@ const getParaswapPrices = async () => { let response = await get(paraswapPricesQuery) console.log(response) paraswapTransferProxy = response.priceRoute.tokenTransferProxy - return Number(response.priceRoute.destAmount) * Math.pow(10, -paraswapDestDecimals) + return Number(response.priceRoute.destAmount) * Math.pow(10, -Number(paraswapDestDecimals)) } diff --git a/beta/public/script.js b/beta/public/script.js index d2003a7..7f08408 100644 --- a/beta/public/script.js +++ b/beta/public/script.js @@ -969,7 +969,7 @@ const setSwapper = async () => { // document.getElementById('paraswap_dest_amount').value = null const srcDecimals = await getTokenDecimals(selectedToken, chain) const destDecimals = await getTokenDecimals(selectedBase, chain) - let srcBalance = (await getTokenBalanceWeb3(selectedToken, walletConnected, chain)) * Math.pow(10, -srcDecimals) + let srcBalance = (await getTokenBalanceWeb3(selectedToken, walletConnected, chain)) * Math.pow(10, -Number(srcDecimals)) if(!srcBalance || srcBalance === 0) { //document.getElementById('paraswap_src_max_amount').classList.toggle('none', true) } else { diff --git a/beta/public/wallet.js b/beta/public/wallet.js index 0d51d2a..aa97794 100644 --- a/beta/public/wallet.js +++ b/beta/public/wallet.js @@ -668,7 +668,7 @@ async function getContractAddressPrice(transaction, network, balance = 1) { } // Balancer Pool else if(transaction.tokenSymbol?.startsWith('B-') && balance > 0) { - price = await getPriceFromBalancerPool(transaction.contractAddress, transaction.tokenSymbol, balance, network) + //price = await getPriceFromBalancerPool(transaction.contractAddress, transaction.tokenSymbol, balance, network) if(price) { return price } @@ -1282,7 +1282,7 @@ function displayTransactions() { if(tx.tokenDecimal) { spanBalance.innerHTML = sign + calculateBalance(tx.value, tx.tokenDecimal) } else { - spanBalance.innerHTML = sign + web3.utils.fromWei(tx.value) + spanBalance.innerHTML = sign + web3.utils.fromWei(tx.value, 'ether') } spanBalance.classList.add('txBalance') li.appendChild(spanBalance) @@ -1549,22 +1549,22 @@ function simpleDataTimers() { Object.keys(NETWORK).filter((network) => typeof NETWORK[network].url_data === 'string').forEach((network, i) => { setTimeout(() => getSimpleData(NETWORK[network].enum, displayWallet), (i+1) * 250) if(network === NETWORK.ETHEREUM.enum) { - getAaveEthereumUnderlyingAddresses(displayWallet) - getCompoundEthereumUnderlyingAddresses(displayWallet) - getAaveV3UnderlyingAddresses(displayWallet) + //getAaveEthereumUnderlyingAddresses(displayWallet) + //getCompoundEthereumUnderlyingAddresses(displayWallet) + //getAaveV3UnderlyingAddresses(displayWallet) } else if(network === NETWORK.POLYGON.enum) { - getAavePolygonUnderlyingAddresses(displayWallet) - getAaveV3PolygonUnderlyingAddresses(displayWallet) + //getAavePolygonUnderlyingAddresses(displayWallet) + //getAaveV3PolygonUnderlyingAddresses(displayWallet) } else if(network === NETWORK.XDAI.enum) { - getRmmGnosisUnderlyingAddresses(displayWallet) + //getRmmGnosisUnderlyingAddresses(displayWallet) } else if(network === NETWORK.BSC.enum) { - getVenusBscUnderlyingAddresses(displayWallet) + //getVenusBscUnderlyingAddresses(displayWallet) } else if(network === NETWORK.ARBITRUM_ONE.enum) { - getAaveV3ArbitrumUnderlyingAddresses(displayWallet) + //getAaveV3ArbitrumUnderlyingAddresses(displayWallet) } /*else if(network === NETWORK.OPTIMISM.enum) { getAaveV3OptimismUnderlyingAddresses(displayWallet) }*/ else if(network === NETWORK.AVALANCHE.enum) { - getAaveV3AvalancheUnderlyingAddresses(displayWallet) + //getAaveV3AvalancheUnderlyingAddresses(displayWallet) } }) setTimeout(simpleDataTimers, 100000) @@ -2039,8 +2039,8 @@ const sortWallet = (a, b) => { if(NETWORK[b.network].tokenContract === b.contract) return 1 // then sort by price value if(a.price && b.price) { - if(a.value * a.price > b.value * b.price) return -1 - if(a.value * a.price < b.value * b.price) return 1 + if(Number(a.value) * a.price > Number(b.value) * b.price) return -1 + if(Number(a.value) * a.price < Number(b.value) * b.price) return 1 } if(!a.price && b.price) return 1 if(a.price && !b.price) return -1 @@ -2129,15 +2129,15 @@ const filteredNFTTokens = () => { /* Utils - Calculate balance from value */ const calculateBalance = (balance, decimal) => { - if(balance && Math.abs(balance) > 0) { - return precise(balance * (decimal ? Math.pow(10, -decimal) : 1)) + if(balance && Math.abs(Number(balance)) > 0) { + return precise(Number(balance) * (decimal ? Math.pow(10, -decimal) : 1)) } return 0 } /* Utils - Calculate value from value */ const calculateValue = (balance, price, decimal) => { - if(balance && price && Math.abs(balance * price) > 0) { - return calculateBalance(balance * price, decimal) + if(balance && price && Math.abs(Number(balance) * price) > 0) { + return calculateBalance(Number(balance) * price, decimal) } return 0 } @@ -2150,7 +2150,7 @@ const displayBalance = (value, decimal) => { } /* Utils - Display dollar value readable by human */ const displayValue = (balance, price, decimal) => { - const value = calculateBalance(balance * price, decimal) + const value = calculateBalance(Number(balance) * price, decimal) if(value === 0) return 0 if(Math.abs(value) < 0.01) return '≈ 0' return '$' + value diff --git a/beta/wallet.html b/beta/wallet.html index c5e5fe9..e2b6485 100644 --- a/beta/wallet.html +++ b/beta/wallet.html @@ -47,7 +47,7 @@ - + diff --git a/cron.js b/cron.js index ea5d71a..8ebd9af 100644 --- a/cron.js +++ b/cron.js @@ -5,8 +5,9 @@ import cp from 'child_process' const backFolder = './back' -const MAIN_TIMEOUT = process.env.NODE_ENV === 'production' ? 45000 : 120000 // 45 or 120 seconds -const COINGECKO_TIMEOUT = process.env.NODE_ENV === 'production' ? 20000 : 45000 // 20 or 45 seconds + +const MAIN_TIMEOUT = process.env.NODE_ENV === 'production' ? 720000 : 360000 // 12 minutes or 6 minutes +const COINGECKO_TIMEOUT = process.env.NODE_ENV === 'production' ? 25000 : 45000 // 25 or 45 seconds start() diff --git a/package-lock.json b/package-lock.json index 203a9e0..a4b9afd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "dependencies": { "@node-redis/json": "^1.0.2", "compression": "*", + "dotenv": "*", "express": "*", "express-rate-limit": "*", "express-ws": "*", @@ -2614,6 +2615,17 @@ "node": ">=6.0.0" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -8574,6 +8586,11 @@ "esutils": "^2.0.2" } }, + "dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==" + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", diff --git a/package.json b/package.json index ad6693f..f792ce6 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "dependencies": { "@node-redis/json": "^1.0.2", "compression": "*", + "dotenv": "*", "express": "*", "express-rate-limit": "*", "express-ws": "*", diff --git a/yarn.lock b/yarn.lock index fb1c32a..43a8d0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1598,6 +1598,11 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dotenv@*: + version "16.4.5" + resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"