diff --git a/.networks-cache.json b/.networks-cache.json index 0c9afcc..c48f0ac 100644 --- a/.networks-cache.json +++ b/.networks-cache.json @@ -1,79 +1,79 @@ { - "metall2": "http://metall2.hypersync.xyz", - "curtis": "http://curtis.hypersync.xyz", - "abstract": "http://abstract.hypersync.xyz", - "hyperliquid": "http://hyperliquid.hypersync.xyz", - "soneium": "http://soneium.hypersync.xyz", - "megaeth-testnet": "http://megaeth-testnet.hypersync.xyz", - "unichain": "http://unichain.hypersync.xyz", - "taraxa": "http://taraxa.hypersync.xyz", - "xdc": "http://xdc.hypersync.xyz", - "chiliz": "http://chiliz.hypersync.xyz", - "gnosis-traces": "http://gnosis-traces.hypersync.xyz", - "xdc-testnet": "http://xdc-testnet.hypersync.xyz", - "arbitrum-sepolia": "http://arbitrum-sepolia.hypersync.xyz", - "worldchain": "http://worldchain.hypersync.xyz", - "arbitrum-nova": "http://arbitrum-nova.hypersync.xyz", - "ink": "http://ink.hypersync.xyz", - "unichain-sepolia": "http://unichain-sepolia.hypersync.xyz", - "optimism": "http://optimism.hypersync.xyz", - "mantle": "http://mantle.hypersync.xyz", - "swell": "http://swell.hypersync.xyz", - "cyber": "http://cyber.hypersync.xyz", - "saakuru": "http://saakuru.hypersync.xyz", - "arbitrum": "http://arbitrum.hypersync.xyz", - "base": "http://base.hypersync.xyz", - "blast-sepolia": "http://blast-sepolia.hypersync.xyz", - "fraxtal": "http://fraxtal.hypersync.xyz", - "aurora": "http://aurora.hypersync.xyz", - "scroll": "http://scroll.hypersync.xyz", - "eth": "http://eth.hypersync.xyz", - "moonbeam": "http://moonbeam.hypersync.xyz", - "polygon-amoy": "http://polygon-amoy.hypersync.xyz", - "morph": "http://morph.hypersync.xyz", - "fantom": "http://fantom.hypersync.xyz", - "polygon-zkevm": "http://polygon-zkevm.hypersync.xyz", - "base-sepolia": "http://base-sepolia.hypersync.xyz", - "shimmer-evm": "http://shimmer-evm.hypersync.xyz", - "blast": "http://blast.hypersync.xyz", - "boba": "http://boba.hypersync.xyz", - "sonic": "http://sonic.hypersync.xyz", - "citrea-testnet": "http://citrea-testnet.hypersync.xyz", - "rootstock": "http://rootstock.hypersync.xyz", - "bsc-testnet": "http://bsc-testnet.hypersync.xyz", - "optimism-sepolia": "http://optimism-sepolia.hypersync.xyz", - "manta": "http://manta.hypersync.xyz", - "merlin": "http://merlin.hypersync.xyz", - "kroma": "http://kroma.hypersync.xyz", - "bsc": "http://bsc.hypersync.xyz", - "zksync": "http://zksync.hypersync.xyz", - "polygon": "http://polygon.hypersync.xyz", - "mode": "http://mode.hypersync.xyz", - "monad-testnet": "http://monad-testnet.hypersync.xyz", - "flare": "http://flare.hypersync.xyz", - "avalanche": "http://avalanche.hypersync.xyz", - "sepolia": "http://sepolia.hypersync.xyz", - "moonbase-alpha": "http://moonbase-alpha.hypersync.xyz", - "sophon-testnet": "http://sophon-testnet.hypersync.xyz", - "lisk": "http://lisk.hypersync.xyz", - "gnosis-chiado": "http://gnosis-chiado.hypersync.xyz", - "eth-traces": "http://eth-traces.hypersync.xyz", - "opbnb": "http://opbnb.hypersync.xyz", - "zeta": "http://zeta.hypersync.xyz", - "berachain-bartio": "http://berachain-bartio.hypersync.xyz", - "zora": "http://zora.hypersync.xyz", - "fuji": "http://fuji.hypersync.xyz", - "mev-commit": "http://mev-commit.hypersync.xyz", - "lukso": "http://lukso.hypersync.xyz", - "holesky": "http://holesky.hypersync.xyz", - "galadriel-devnet": "http://galadriel-devnet.hypersync.xyz", - "linea": "http://linea.hypersync.xyz", - "zircuit": "http://zircuit.hypersync.xyz", - "gnosis": "http://gnosis.hypersync.xyz", - "lukso-testnet": "http://lukso-testnet.hypersync.xyz", - "berachain": "http://berachain.hypersync.xyz", - "sophon": "http://sophon.hypersync.xyz", - "celo": "http://celo.hypersync.xyz", - "superseed": "http://superseed.hypersync.xyz", - "harmony-shard-0": "http://harmony-shard-0.hypersync.xyz" + "metall2": "https://metall2.hypersync.xyz", + "curtis": "https://curtis.hypersync.xyz", + "abstract": "https://abstract.hypersync.xyz", + "hyperliquid": "https://hyperliquid.hypersync.xyz", + "soneium": "https://soneium.hypersync.xyz", + "megaeth-testnet": "https://megaeth-testnet.hypersync.xyz", + "unichain": "https://unichain.hypersync.xyz", + "taraxa": "https://taraxa.hypersync.xyz", + "xdc": "https://xdc.hypersync.xyz", + "chiliz": "https://chiliz.hypersync.xyz", + "gnosis-traces": "https://gnosis-traces.hypersync.xyz", + "xdc-testnet": "https://xdc-testnet.hypersync.xyz", + "arbitrum-sepolia": "https://arbitrum-sepolia.hypersync.xyz", + "worldchain": "https://worldchain.hypersync.xyz", + "arbitrum-nova": "https://arbitrum-nova.hypersync.xyz", + "ink": "https://ink.hypersync.xyz", + "unichain-sepolia": "https://unichain-sepolia.hypersync.xyz", + "optimism": "https://optimism.hypersync.xyz", + "mantle": "https://mantle.hypersync.xyz", + "swell": "https://swell.hypersync.xyz", + "cyber": "https://cyber.hypersync.xyz", + "saakuru": "https://saakuru.hypersync.xyz", + "arbitrum": "https://arbitrum.hypersync.xyz", + "base": "https://base.hypersync.xyz", + "blast-sepolia": "https://blast-sepolia.hypersync.xyz", + "fraxtal": "https://fraxtal.hypersync.xyz", + "aurora": "https://aurora.hypersync.xyz", + "scroll": "https://scroll.hypersync.xyz", + "eth": "https://eth.hypersync.xyz", + "moonbeam": "https://moonbeam.hypersync.xyz", + "polygon-amoy": "https://polygon-amoy.hypersync.xyz", + "morph": "https://morph.hypersync.xyz", + "fantom": "https://fantom.hypersync.xyz", + "polygon-zkevm": "https://polygon-zkevm.hypersync.xyz", + "base-sepolia": "https://base-sepolia.hypersync.xyz", + "shimmer-evm": "https://shimmer-evm.hypersync.xyz", + "blast": "https://blast.hypersync.xyz", + "boba": "https://boba.hypersync.xyz", + "sonic": "https://sonic.hypersync.xyz", + "citrea-testnet": "https://citrea-testnet.hypersync.xyz", + "rootstock": "https://rootstock.hypersync.xyz", + "bsc-testnet": "https://bsc-testnet.hypersync.xyz", + "optimism-sepolia": "https://optimism-sepolia.hypersync.xyz", + "manta": "https://manta.hypersync.xyz", + "merlin": "https://merlin.hypersync.xyz", + "kroma": "https://kroma.hypersync.xyz", + "bsc": "https://bsc.hypersync.xyz", + "zksync": "https://zksync.hypersync.xyz", + "polygon": "https://polygon.hypersync.xyz", + "mode": "https://mode.hypersync.xyz", + "monad-testnet": "https://monad-testnet.hypersync.xyz", + "flare": "https://flare.hypersync.xyz", + "avalanche": "https://avalanche.hypersync.xyz", + "sepolia": "https://sepolia.hypersync.xyz", + "moonbase-alpha": "https://moonbase-alpha.hypersync.xyz", + "sophon-testnet": "https://sophon-testnet.hypersync.xyz", + "lisk": "https://lisk.hypersync.xyz", + "gnosis-chiado": "https://gnosis-chiado.hypersync.xyz", + "eth-traces": "https://eth-traces.hypersync.xyz", + "opbnb": "https://opbnb.hypersync.xyz", + "zeta": "https://zeta.hypersync.xyz", + "berachain-bartio": "https://berachain-bartio.hypersync.xyz", + "zora": "https://zora.hypersync.xyz", + "fuji": "https://fuji.hypersync.xyz", + "mev-commit": "https://mev-commit.hypersync.xyz", + "lukso": "https://lukso.hypersync.xyz", + "holesky": "https://holesky.hypersync.xyz", + "galadriel-devnet": "https://galadriel-devnet.hypersync.xyz", + "linea": "https://linea.hypersync.xyz", + "zircuit": "https://zircuit.hypersync.xyz", + "gnosis": "https://gnosis.hypersync.xyz", + "lukso-testnet": "https://lukso-testnet.hypersync.xyz", + "berachain": "https://berachain.hypersync.xyz", + "sophon": "https://sophon.hypersync.xyz", + "celo": "https://celo.hypersync.xyz", + "superseed": "https://superseed.hypersync.xyz", + "harmony-shard-0": "https://harmony-shard-0.hypersync.xyz" } \ No newline at end of file diff --git a/README.md b/README.md index 0f77b2c..0915f4c 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,9 @@ logtui # Track Uniswap V4 events logtui uniswap-v4 +# Monitor GMX v1 perps events on Arbitrum +logtui gmx-v1-perps arbitrum + # Monitor Chainlink price feed updates logtui chainlink-price-feeds @@ -102,6 +105,8 @@ LogTUI automatically discovers and caches all networks supported by Hypersync: This ensures you always have access to all supported networks, even when working offline. +LogTUI uses secure `https://*.hypersync.xyz` endpoints for network connections. + ### CLI Options ``` @@ -141,7 +146,7 @@ await fetchNetworks(); // Option 1: Using direct parameters createScanner({ - networkUrl: "http://eth.hypersync.xyz", + networkUrl: "https://eth.hypersync.xyz", eventSignatures: [ "Transfer(address,address,uint256)", "Approval(address,address,uint256)", @@ -203,6 +208,7 @@ Run `logtui --list-networks` to see the complete, up-to-date list of all support - `curve`: Curve Finance pool events (TokenExchange, AddLiquidity) - `weth`: Wrapped Ether events (Deposit, Withdrawal, Transfer) - `usdc`: USD Coin stablecoin events +- `gmx-v1-perps`: GMX v1 perps order lifecycle, position updates, and liquidations ### Cross-chain & L2 @@ -215,6 +221,8 @@ Run `logtui --list-networks` to see the complete, up-to-date list of all support - `axie`: Axie Infinity game events - `ens`: Ethereum Name Service registry events + + ### Emerging Tech - `erc4337`: Account Abstraction (ERC-4337) events diff --git a/lib/config.js b/lib/config.js index bfd63f6..b931de2 100644 --- a/lib/config.js +++ b/lib/config.js @@ -13,14 +13,26 @@ const __dirname = path.dirname(__filename); // Path to store cached networks const CACHE_FILE = path.join(__dirname, "../.networks-cache.json"); +const HYPERSYNC_PROTOCOL = "https://"; + +function normalizeNetworkUrl(url) { + if (typeof url !== "string") return url; + return url.replace(/^http:\/\//, HYPERSYNC_PROTOCOL); +} + +function normalizeNetworks(networks) { + return Object.fromEntries( + Object.entries(networks).map(([name, url]) => [name, normalizeNetworkUrl(url)]) + ); +} // Default network endpoint configuration (used as fallback if API fetch fails) export const DEFAULT_NETWORKS = { - eth: "http://eth.hypersync.xyz", - arbitrum: "http://arbitrum.hypersync.xyz", - optimism: "http://optimism.hypersync.xyz", - base: "http://base.hypersync.xyz", - polygon: "http://polygon.hypersync.xyz", + eth: "https://eth.hypersync.xyz", + arbitrum: "https://arbitrum.hypersync.xyz", + optimism: "https://optimism.hypersync.xyz", + base: "https://base.hypersync.xyz", + polygon: "https://polygon.hypersync.xyz", }; // Runtime networks object that will be populated @@ -38,8 +50,12 @@ function loadNetworksFromCache() { if (fs.existsSync(CACHE_FILE)) { const data = fs.readFileSync(CACHE_FILE, "utf8"); const networks = JSON.parse(data); + const normalizedNetworks = normalizeNetworks(networks); + if (JSON.stringify(networks) !== JSON.stringify(normalizedNetworks)) { + saveNetworksToCache(normalizedNetworks); + } console.debug("Loaded networks from cache"); - return networks; + return normalizedNetworks; } } catch (error) { console.warn(`Failed to load networks from cache: ${error.message}`); @@ -53,7 +69,7 @@ function loadNetworksFromCache() { */ function saveNetworksToCache(networks) { try { - const data = JSON.stringify(networks, null, 2); + const data = JSON.stringify(normalizeNetworks(networks), null, 2); fs.writeFileSync(CACHE_FILE, data); console.debug("Saved networks to cache"); } catch (error) { @@ -95,7 +111,7 @@ export async function fetchNetworks(forceRefresh = false) { if (network.ecosystem !== "evm") return; // Convert network name to URL format - const url = `http://${network.name}.hypersync.xyz`; + const url = `${HYPERSYNC_PROTOCOL}${network.name}.hypersync.xyz`; result[network.name] = url; }); @@ -328,6 +344,38 @@ export const EVENT_PRESETS = { "ERC1155Transferred(address,address,address,uint256,uint256)", ], }, + "gmx-v1-perps": { + name: "GMX V1 Perps", + description: "GMX v1 perps orders, position changes, and liquidations", + signatures: [ + // Vault position lifecycle + "IncreasePosition(bytes32,address,address,address,uint256,uint256,bool,uint256,uint256)", + "DecreasePosition(bytes32,address,address,address,uint256,uint256,bool,uint256,uint256)", + "LiquidatePosition(bytes32,address,address,address,bool,uint256,uint256,uint256,int256,uint256)", + "UpdatePosition(bytes32,uint256,uint256,uint256,uint256,uint256,int256,uint256)", + "ClosePosition(bytes32,uint256,uint256,uint256,uint256,uint256,int256)", + + // PositionRouter order lifecycle (increase) + "CreateIncreasePosition(address,address[],address,uint256,uint256,uint256,bool,uint256,uint256,uint256,uint256,uint256,uint256,uint256)", + "ExecuteIncreasePosition(address,address[],address,uint256,uint256,uint256,bool,uint256,uint256,uint256,uint256)", + "CancelIncreasePosition(address,address[],address,uint256,uint256,uint256,bool,uint256,uint256,uint256,uint256)", + + // PositionRouter order lifecycle (decrease) + "CreateDecreasePosition(address,address[],address,uint256,uint256,bool,address,uint256,uint256,uint256,uint256,uint256,uint256,uint256)", + "ExecuteDecreasePosition(address,address[],address,uint256,uint256,bool,address,uint256,uint256,uint256,uint256)", + "CancelDecreasePosition(address,address[],address,uint256,uint256,bool,address,uint256,uint256,uint256,uint256)", + + // OrderBook (increase orders) + "CreateIncreaseOrder(address,uint256,address,uint256,address,address,uint256,bool,uint256,bool,uint256)", + "ExecuteIncreaseOrder(address,uint256,address,uint256,address,address,uint256,bool,uint256,bool,uint256,uint256)", + "CancelIncreaseOrder(address,uint256,address,uint256,address,address,uint256,bool,uint256,bool,uint256)", + + // OrderBook (decrease orders) + "CreateDecreaseOrder(address,uint256,address,uint256,address,uint256,bool,uint256,bool,uint256)", + "ExecuteDecreaseOrder(address,uint256,address,uint256,address,uint256,bool,uint256,bool,uint256,uint256)", + "CancelDecreaseOrder(address,uint256,address,uint256,address,uint256,bool,uint256,bool,uint256)", + ], + }, }; /**