diff --git a/README.md b/README.md index 171165a144..e251d71f8f 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,19 @@ Below is an example of a query: https://stats.invariant.app/svm/pool_daily_data/mainnet/aggregated/BRt1iVYDNoohkL1upEb8UfHE8yji6gEDAmuN9Y4yekyc?limit=10 ``` +# Scripts + +## Cumulative Stats + +Usage: + +```bash +npm run get-cumulative-stats -- +``` + +Possible chains: `solana`, `eclipse`, `aleph-zero`, `alephium`, `vara` +Possible networks: `mainnet`, `testnet`, `devnet` + # Most popular pool addresses | Token X | Token Y | Fee | Address | diff --git a/package-lock.json b/package-lock.json index 68500a5142..3413ad591e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "web3-eclipse": "npm:@solana/web3.js@^1.95.4" }, "devDependencies": { + "@types/node": "^22.10.1", "typescript": "^4.5.5" } }, diff --git a/package.json b/package.json index e7a2a9f5ce..e57380e804 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "description": "", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "get-cumulative-stats": "export NODE_OPTIONS='--max-old-space-size=8192' && npx ts-node scripts/get-cumulative-stats.ts" }, "author": "", "license": "ISC", @@ -31,6 +32,7 @@ } }, "devDependencies": { + "@types/node": "^22.10.1", "typescript": "^4.5.5" } } diff --git a/scripts/get-cumulative-stats.ts b/scripts/get-cumulative-stats.ts new file mode 100644 index 0000000000..fe73578bd6 --- /dev/null +++ b/scripts/get-cumulative-stats.ts @@ -0,0 +1,70 @@ +import { getCumulativeStats } from "../utils/utils"; +import SOLANA_MAINNET_DATA from "../data/mainnet.json"; +import SOLANA_DEVNET_DATA from "../data/devnet.json"; +import ECLIPSE_MAINNET_DATA from "../data/eclipse/mainnet.json"; +import ECLIPSE_TESTNET_DATA from "../data/eclipse/testnet.json"; +import ECLIPSE_DEVNET_DATA from "../data/eclipse/devnet.json"; +import ALEPH_ZERO_MAINNET_DATA from "../data/a0/mainnet.json"; +import ALEPH_ZERO_TESTNET_DATA from "../data/a0/testnet.json"; +import ALEPHIUM_MAINNET_DATA from "../data/alph/mainnet.json"; +import ALEPHIUM_TESTNET_DATA from "../data/alph/testnet.json"; +import VARA_TESTNET_DATA from "../data/vara/testnet.json"; +import { PoolStatsData } from "../api/utils"; + +const main = async () => { + const chain = process.argv[2]; + const network = process.argv[3]; + const startTimestamp = +process.argv[4]; + const endTimestamp = +process.argv[5]; + let snaps: Record = {}; + + switch (`${chain}-${network}`) { + case "solana-mainnet": + snaps = SOLANA_MAINNET_DATA as Record; + break; + case "solana-devnet": + snaps = SOLANA_DEVNET_DATA as Record; + break; + case "eclipse-mainnet": + snaps = ECLIPSE_MAINNET_DATA as Record; + break; + case "eclipse-testnet": + snaps = ECLIPSE_TESTNET_DATA as Record; + break; + case "eclipse-devnet": + snaps = ECLIPSE_DEVNET_DATA as Record; + break; + case "aleph-zero-mainnet": + snaps = ALEPH_ZERO_MAINNET_DATA as Record; + break; + case "aleph-zero-testnet": + snaps = ALEPH_ZERO_TESTNET_DATA as Record; + break; + case "alephium-mainnet": + snaps = ALEPHIUM_MAINNET_DATA as Record; + break; + case "alephium-testnet": + snaps = ALEPHIUM_TESTNET_DATA as Record; + break; + case "vara-testnet": + snaps = VARA_TESTNET_DATA as Record; + break; + default: + throw new Error("Invalid chain or network"); + } + + const { volume, fee } = getCumulativeStats( + startTimestamp, + endTimestamp, + snaps + ); + console.log( + `Chain: ${chain.toUpperCase()}, Network: ${network.toUpperCase()}, Volume: $${volume + .toFixed(2) + .replace(/\B(?=(\d{3})+(?!\d))/g, ",")}, Fee: $${fee + .toFixed(2) + .replace(/\B(?=(\d{3})+(?!\d))/g, ",")}` + ); +}; + +main(); diff --git a/utils/utils.ts b/utils/utils.ts new file mode 100644 index 0000000000..2fa33b5771 --- /dev/null +++ b/utils/utils.ts @@ -0,0 +1,24 @@ +import { PoolStatsData } from "../api/utils"; + +export const getCumulativeStats = ( + startTimestamp: number, + endTimestamp: number, + data: Record +): { volume: number; fee: number } => { + let volume = 0; + let fee = 0; + + Object.entries(data).forEach(([_, value]) => { + for (const snapshot of value.snapshots) { + if ( + snapshot.timestamp >= startTimestamp && + snapshot.timestamp <= endTimestamp + ) { + volume += snapshot.volumeX.usdValue24 + snapshot.volumeY.usdValue24; + fee += snapshot.feeX.usdValue24 + snapshot.feeY.usdValue24; + } + } + }); + + return { volume, fee }; +};