From f424e89a34b49c8757548e39945ae39cbbcaa8db Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Fri, 6 Jun 2025 13:37:13 -0700 Subject: [PATCH 01/10] feat(entropy-tester): Init --- apps/entropy-tester/.eslintrc.js | 10 + apps/entropy-tester/.gitignore | 1 + apps/entropy-tester/config.sample.yaml | 2 + apps/entropy-tester/package.json | 58 +++++ apps/entropy-tester/src/index.ts | 126 ++++++++++ apps/entropy-tester/tsconfig.json | 15 ++ pnpm-lock.yaml | 313 ++++++++----------------- 7 files changed, 315 insertions(+), 210 deletions(-) create mode 100644 apps/entropy-tester/.eslintrc.js create mode 100644 apps/entropy-tester/.gitignore create mode 100644 apps/entropy-tester/config.sample.yaml create mode 100644 apps/entropy-tester/package.json create mode 100644 apps/entropy-tester/src/index.ts create mode 100644 apps/entropy-tester/tsconfig.json diff --git a/apps/entropy-tester/.eslintrc.js b/apps/entropy-tester/.eslintrc.js new file mode 100644 index 0000000000..a32b4a16d8 --- /dev/null +++ b/apps/entropy-tester/.eslintrc.js @@ -0,0 +1,10 @@ +module.exports = { + root: true, + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint"], + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + rules: { + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-non-null-assertion": "off", + }, +}; diff --git a/apps/entropy-tester/.gitignore b/apps/entropy-tester/.gitignore new file mode 100644 index 0000000000..a65b41774a --- /dev/null +++ b/apps/entropy-tester/.gitignore @@ -0,0 +1 @@ +lib diff --git a/apps/entropy-tester/config.sample.yaml b/apps/entropy-tester/config.sample.yaml new file mode 100644 index 0000000000..049c2d89fb --- /dev/null +++ b/apps/entropy-tester/config.sample.yaml @@ -0,0 +1,2 @@ +chain-id: berachain_mainnet +interval: 14h diff --git a/apps/entropy-tester/package.json b/apps/entropy-tester/package.json new file mode 100644 index 0000000000..01ba7bae9a --- /dev/null +++ b/apps/entropy-tester/package.json @@ -0,0 +1,58 @@ +{ + "name": "@pythnetwork/entropy-tester", + "version": "1.0.0", + "description": "Utility to test entropy provider callbacks", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib/**/*" + ], + "scripts": { + "build": "tsc", + "fix:format": "prettier --write \"src/**/*.ts\"", + "fix:lint": "eslint src/ --fix --max-warnings 0", + "test:format": "prettier --check \"src/**/*.ts\"", + "test:lint": "eslint src/ --max-warnings 0", + "start": "node lib/index.js", + "dev": "ts-node src/index.ts", + "prepublishOnly": "pnpm run build && pnpm run test:lint", + "preversion": "pnpm run test:lint", + "version": "pnpm run test:format && pnpm run test:lint && git add -A src" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/pyth-network/pyth-crosschain.git", + "directory": "apps/entropy-tester" + }, + "bin": { + "pyth-entropy-tester": "./lib/index.js" + }, + "devDependencies": { + "@types/ethereum-protocol": "^1.0.2", + "@types/express": "^4.17.21", + "@types/jest": "^27.4.1", + "@types/yargs": "^17.0.10", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", + "eslint": "^8.13.0", + "jest": "^29.7.0", + "pino-pretty": "^11.2.1", + "prettier": "catalog:", + "ts-jest": "^29.1.1", + "ts-node": "catalog:", + "typescript": "catalog:" + }, + "dependencies": { + "@pythnetwork/contract-manager": "workspace:*", + "joi": "^17.6.0", + "pino": "^9.2.0", + "prom-client": "^15.1.0", + "viem": "^2.19.4", + "yaml": "^2.1.1", + "yargs": "^17.5.1" + }, + "keywords": [], + "author": "", + "license": "Apache-2.0", + "packageManager": "pnpm@10.7.0" +} diff --git a/apps/entropy-tester/src/index.ts b/apps/entropy-tester/src/index.ts new file mode 100644 index 0000000000..31f213e21f --- /dev/null +++ b/apps/entropy-tester/src/index.ts @@ -0,0 +1,126 @@ +#!/usr/bin/env node +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; +import YAML from "yaml"; +import fs from "fs"; +import pino from "pino"; +import { DefaultStore } from "@pythnetwork/contract-manager/node/store"; +import { EvmEntropyContract } from "@pythnetwork/contract-manager/core/contracts/evm"; +import { PrivateKey, toPrivateKey } from "@pythnetwork/contract-manager/core/base"; + +type DurationSeconds = number; +type LoadedConfig = { + contract: EvmEntropyContract, + interval: DurationSeconds +} + +function timeToSeconds(timeStr: string): number { + const match = timeStr.match(/^(\d+)([hms])$/i); + if (!match) throw new Error("Invalid format. Use formats like '6h', '15m', or '30s'."); + + const value = parseInt(match[1], 10); + const unit = match[2].toLowerCase(); + + switch (unit) { + case 'h': return value * 3600; + case 'm': return value * 60; + case 's': return value; + default: throw new Error("Unsupported time unit."); + } +} +const logger = pino(); + +function loadConfig(configPath: string): LoadedConfig { + const config = YAML.parse(fs.readFileSync(configPath, "utf-8")); + const contracts = Object.values(DefaultStore.entropy_contracts).filter((contract) => ( + contract.chain.getId() == config['chain-id'] + )) + if (contracts.length === 0) { + logger.error("Couldn't find the contract id, check contract manager store.") + process.exit(1) + } + const interval = timeToSeconds(config['interval']); + return { contract: contracts[0], interval } +} + + +async function testLatency( + contract: EvmEntropyContract, + privateKey: PrivateKey, +) { + const provider = await contract.getDefaultProvider(); + const userRandomNumber = contract.generateUserRandomNumber(); + const requestResponse = await contract.requestRandomness( + userRandomNumber, + provider, + privateKey, + true, // with callback + ); + // Read the sequence number for the request from the transaction events. + const sequenceNumber = + parseInt(requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber); + logger.info(`Request tx hash: ${requestResponse.transactionHash} Seq. No: ${sequenceNumber}`); + + const startTime = Date.now(); + + // eslint-disable-next-line no-constant-condition + while (true) { + await new Promise((resolve) => setTimeout(resolve, 2000)); + const request = await contract.getRequest(provider, sequenceNumber); + logger.debug(request) + + if (parseInt(request.sequenceNumber) === 0) { // 0 means the request is cleared + const endTime = Date.now(); + logger.info(`Fortuna Latency: ${endTime - startTime}ms`); + break; + } + if (Date.now() - startTime > 60000) { + logger.error("Timeout: 60s passed without the callback being called."); + break; + } + } +} + + +yargs(hideBin(process.argv)) + .parserConfiguration({ + "parse-numbers": false, + }) + .command({ + command: "run", + describe: "run the tester until manually stopped", + builder: { + validate: { + description: "Only validate the configs and exit", + type: "boolean", + default: false, + required: false + }, + config: { + description: "Yaml config file", + type: "string", + required: true, + }, + "private-key": { + type: "string", + required: true, + description: "Path to the private key to sign the transactions with. Should be hex encoded", + }, + }, + handler: async (argv: any) => { + const { contract, interval } = loadConfig(argv.config); + if (argv.validate) { + logger.info("Config validated") + return; + } + const privateKey = toPrivateKey(fs.readFileSync(argv['private-key'], "utf-8").replace('0x', '').trimEnd()) + logger.info("Running") + // eslint-disable-next-line no-constant-condition + while (true) { + await testLatency(contract, privateKey); + await new Promise((resolve) => setTimeout(resolve, interval)); + } + } + }) + .demandCommand() + .help().argv; diff --git a/apps/entropy-tester/tsconfig.json b/apps/entropy-tester/tsconfig.json new file mode 100644 index 0000000000..be11dcb27f --- /dev/null +++ b/apps/entropy-tester/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "target": "esnext", + "module": "nodenext", + "declaration": true, + "rootDir": "src/", + "outDir": "./lib", + "strict": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["src"], + "exclude": ["node_modules", "**/__tests__/*"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6ff625065c..648460156f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -786,6 +786,70 @@ importers: specifier: 'catalog:' version: 41.4.1(encoding@0.1.13) + apps/entropy-tester: + dependencies: + '@pythnetwork/contract-manager': + specifier: workspace:* + version: link:../../contract_manager + joi: + specifier: ^17.6.0 + version: 17.13.3 + pino: + specifier: ^9.2.0 + version: 9.6.0 + prom-client: + specifier: ^15.1.0 + version: 15.1.3 + viem: + specifier: ^2.19.4 + version: 2.24.3(bufferutil@4.0.9)(typescript@5.8.2)(utf-8-validate@6.0.3)(zod@3.24.4) + yaml: + specifier: ^2.1.1 + version: 2.7.1 + yargs: + specifier: ^17.5.1 + version: 17.7.2 + devDependencies: + '@types/ethereum-protocol': + specifier: ^1.0.2 + version: 1.0.5 + '@types/express': + specifier: ^4.17.21 + version: 4.17.21 + '@types/jest': + specifier: ^27.4.1 + version: 27.5.2 + '@types/yargs': + specifier: ^17.0.10 + version: 17.0.33 + '@typescript-eslint/eslint-plugin': + specifier: ^6.0.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0)(typescript@5.8.2) + '@typescript-eslint/parser': + specifier: ^6.0.0 + version: 6.21.0(eslint@8.56.0)(typescript@5.8.2) + eslint: + specifier: ^8.13.0 + version: 8.56.0 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)) + pino-pretty: + specifier: ^11.2.1 + version: 11.3.0 + prettier: + specifier: 'catalog:' + version: 3.5.3 + ts-jest: + specifier: ^29.1.1 + version: 29.3.1(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(esbuild@0.25.4)(jest@29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)))(typescript@5.8.2) + ts-node: + specifier: 'catalog:' + version: 10.9.2(@types/node@22.14.0)(typescript@5.8.2) + typescript: + specifier: 'catalog:' + version: 5.8.2 + apps/hermes/client/js: dependencies: '@zodios/core': @@ -1153,7 +1217,7 @@ importers: version: 0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) '@solana/wallet-adapter-wallets': specifier: 'catalog:' - version: 0.19.33(@babel/runtime@7.27.0)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2) + version: 0.19.33(@babel/runtime@7.27.0)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2) '@solana/web3.js': specifier: 'catalog:' version: 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) @@ -18650,6 +18714,7 @@ packages: path-match@1.2.4: resolution: {integrity: sha512-UWlehEdqu36jmh4h5CWJ7tARp1OEVKGHKm6+dg9qMq5RKUTV5WJrGgaZ3dN2m7WFAXDbjlHzvJvL/IUpy84Ktw==} + deprecated: This package is archived and no longer maintained. For support, visit https://github.com/expressjs/express/discussions path-normalize@6.0.13: resolution: {integrity: sha512-PfC1Pc+IEhI77UEN731pj2nMs9gHAV36IA6IW6VdXWjoQesf+jtO9hdMUqTRS6mwR0T5rmyUrQzd5vw0VwL1Lw==} @@ -27106,17 +27171,6 @@ snapshots: '@ethersproject/properties': 5.8.0 '@ethersproject/strings': 5.8.0 - '@everstake/wallet-sdk-solana@2.0.9(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana-program/compute-budget': 0.6.1(@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana-program/stake': 0.1.0(@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana-program/system': 0.6.2(@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana/web3.js': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - typescript - - ws - '@everstake/wallet-sdk-solana@2.0.9(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana-program/compute-budget': 0.6.1(@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))) @@ -33334,60 +33388,31 @@ snapshots: - react - react-native - '@solana-program/compute-budget@0.6.1(@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/web3.js': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/compute-budget@0.6.1(@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: '@solana/web3.js': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/compute-budget@0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/compute-budget@0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/stake@0.1.0(@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/web3.js': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/stake@0.1.0(@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: '@solana/web3.js': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/system@0.6.2(@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/web3.js': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/system@0.6.2(@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: '@solana/web3.js': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/system@0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/system@0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/token-2022@0.4.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))': - dependencies: - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana-program/token-2022@0.4.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana-program/token@0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/token@0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) @@ -33727,31 +33752,6 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/accounts': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/codecs': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/errors': 2.1.0(typescript@5.8.2) - '@solana/functional': 2.1.0(typescript@5.8.2) - '@solana/instructions': 2.1.0(typescript@5.8.2) - '@solana/keys': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/programs': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/rpc': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/rpc-parsed-types': 2.1.0(typescript@5.8.2) - '@solana/rpc-spec-types': 2.1.0(typescript@5.8.2) - '@solana/rpc-subscriptions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/signers': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/transaction-confirmation': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/transaction-messages': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/transactions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/accounts': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) @@ -33938,15 +33938,6 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/rpc-subscriptions-channel-websocket@2.0.0(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.0.0(typescript@5.8.2) - '@solana/functional': 2.0.0(typescript@5.8.2) - '@solana/rpc-subscriptions-spec': 2.0.0(typescript@5.8.2) - '@solana/subscribable': 2.0.0(typescript@5.8.2) - typescript: 5.8.2 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@solana/rpc-subscriptions-channel-websocket@2.0.0(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.0.0(typescript@5.8.2) @@ -33956,15 +33947,6 @@ snapshots: typescript: 5.8.2 ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@solana/rpc-subscriptions-channel-websocket@2.1.0(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.1.0(typescript@5.8.2) - '@solana/functional': 2.1.0(typescript@5.8.2) - '@solana/rpc-subscriptions-spec': 2.1.0(typescript@5.8.2) - '@solana/subscribable': 2.1.0(typescript@5.8.2) - typescript: 5.8.2 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@solana/rpc-subscriptions-channel-websocket@2.1.0(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.1.0(typescript@5.8.2) @@ -33990,24 +33972,6 @@ snapshots: '@solana/subscribable': 2.1.0(typescript@5.8.2) typescript: 5.8.2 - '@solana/rpc-subscriptions@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.0.0(typescript@5.8.2) - '@solana/fast-stable-stringify': 2.0.0(typescript@5.8.2) - '@solana/functional': 2.0.0(typescript@5.8.2) - '@solana/promises': 2.0.0(typescript@5.8.2) - '@solana/rpc-spec-types': 2.0.0(typescript@5.8.2) - '@solana/rpc-subscriptions-api': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/rpc-subscriptions-channel-websocket': 2.0.0(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-subscriptions-spec': 2.0.0(typescript@5.8.2) - '@solana/rpc-transformers': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/rpc-types': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/subscribable': 2.0.0(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/rpc-subscriptions@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.0.0(typescript@5.8.2) @@ -34026,24 +33990,6 @@ snapshots: - fastestsmallesttextencoderdecoder - ws - '@solana/rpc-subscriptions@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.1.0(typescript@5.8.2) - '@solana/fast-stable-stringify': 2.1.0(typescript@5.8.2) - '@solana/functional': 2.1.0(typescript@5.8.2) - '@solana/promises': 2.1.0(typescript@5.8.2) - '@solana/rpc-spec-types': 2.1.0(typescript@5.8.2) - '@solana/rpc-subscriptions-api': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/rpc-subscriptions-channel-websocket': 2.1.0(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-subscriptions-spec': 2.1.0(typescript@5.8.2) - '@solana/rpc-transformers': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/subscribable': 2.1.0(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/rpc-subscriptions@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.1.0(typescript@5.8.2) @@ -34314,23 +34260,6 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/transaction-confirmation@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/addresses': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/codecs-strings': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/errors': 2.0.0(typescript@5.8.2) - '@solana/keys': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/promises': 2.0.0(typescript@5.8.2) - '@solana/rpc': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/rpc-subscriptions': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/transaction-messages': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/transactions': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/transaction-confirmation@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/addresses': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) @@ -34348,23 +34277,6 @@ snapshots: - fastestsmallesttextencoderdecoder - ws - '@solana/transaction-confirmation@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/codecs-strings': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/errors': 2.1.0(typescript@5.8.2) - '@solana/keys': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/promises': 2.1.0(typescript@5.8.2) - '@solana/rpc': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/rpc-subscriptions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/transaction-messages': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/transactions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/transaction-confirmation@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) @@ -34738,11 +34650,11 @@ snapshots: - utf-8-validate - ws - '@solana/wallet-adapter-trezor@0.1.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@solana/wallet-adapter-trezor@0.1.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@trezor/connect-web': 9.5.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@trezor/connect-web': 9.5.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) buffer: 6.0.3 transitivePeerDependencies: - '@solana/sysvars' @@ -34906,7 +34818,7 @@ snapshots: - ws - zod - '@solana/wallet-adapter-wallets@0.19.33(@babel/runtime@7.27.0)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2)': + '@solana/wallet-adapter-wallets@0.19.33(@babel/runtime@7.27.0)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2)': dependencies: '@solana/wallet-adapter-alpha': 0.1.11(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-avana': 0.1.14(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) @@ -34939,7 +34851,7 @@ snapshots: '@solana/wallet-adapter-tokenary': 0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-tokenpocket': 0.4.20(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-torus': 0.11.29(@babel/runtime@7.27.0)(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-trezor': 0.1.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-trezor': 0.1.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-trust': 0.1.14(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-unsafe-burner': 0.1.8(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-walletconnect': 0.1.17(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(typescript@5.8.2)(utf-8-validate@5.0.10)(zod@3.24.2) @@ -35165,31 +35077,6 @@ snapshots: - encoding - utf-8-validate - '@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/accounts': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/addresses': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/codecs': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/errors': 2.0.0(typescript@5.8.2) - '@solana/functional': 2.0.0(typescript@5.8.2) - '@solana/instructions': 2.0.0(typescript@5.8.2) - '@solana/keys': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/programs': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/rpc': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/rpc-parsed-types': 2.0.0(typescript@5.8.2) - '@solana/rpc-spec-types': 2.0.0(typescript@5.8.2) - '@solana/rpc-subscriptions': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/signers': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/sysvars': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/transaction-confirmation': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/transaction-messages': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - '@solana/transactions': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/web3.js@2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/accounts': 2.0.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2) @@ -36250,17 +36137,6 @@ snapshots: - expo-localization - react-native - '@trezor/blockchain-link-types@1.3.3(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@trezor/type-utils': 1.1.5 - '@trezor/utxo-lib': 2.3.3(tslib@2.8.1) - tslib: 2.8.1 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - typescript - - ws - '@trezor/blockchain-link-types@1.3.3(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) @@ -36323,13 +36199,13 @@ snapshots: - utf-8-validate - ws - '@trezor/blockchain-link@2.4.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@trezor/blockchain-link@2.4.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@everstake/wallet-sdk-solana': 2.0.9(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/token': 0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)) - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@trezor/blockchain-link-types': 1.3.3(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@everstake/wallet-sdk-solana': 2.0.9(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana-program/token': 0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token-2022': 0.4.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)) + '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@trezor/blockchain-link-types': 1.3.3(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@trezor/blockchain-link-utils': 1.3.3(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/env-utils': 1.3.2(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/utils': 9.3.3(tslib@2.8.1) @@ -36409,9 +36285,9 @@ snapshots: - utf-8-validate - ws - '@trezor/connect-web@9.5.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@trezor/connect-web@9.5.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@trezor/connect': 9.5.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@trezor/connect': 9.5.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@trezor/connect-common': 0.3.3(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/utils': 9.3.3(tslib@2.8.1) tslib: 2.8.1 @@ -36472,7 +36348,7 @@ snapshots: - utf-8-validate - ws - '@trezor/connect@9.5.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@trezor/connect@9.5.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@ethereumjs/common': 4.4.0 '@ethereumjs/tx': 5.4.0 @@ -36480,13 +36356,13 @@ snapshots: '@mobily/ts-belt': 3.13.1 '@noble/hashes': 1.7.1 '@scure/bip39': 1.5.4 - '@solana-program/compute-budget': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana-program/system': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana-program/token': 0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)) - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@trezor/blockchain-link': 2.4.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@trezor/blockchain-link-types': 1.3.3(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.8.2)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana-program/compute-budget': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/system': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token-2022': 0.4.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)) + '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@trezor/blockchain-link': 2.4.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@trezor/blockchain-link-types': 1.3.3(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.8.2)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@trezor/blockchain-link-utils': 1.3.3(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/connect-analytics': 1.3.2(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/connect-common': 0.3.3(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(tslib@2.8.1) @@ -53169,6 +53045,23 @@ snapshots: - utf-8-validate - zod + viem@2.24.3(bufferutil@4.0.9)(typescript@5.8.2)(utf-8-validate@6.0.3)(zod@3.24.4): + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.2)(zod@3.24.4) + isows: 1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.3)) + ox: 0.6.9(typescript@5.8.2)(zod@3.24.4) + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.3) + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + vlq@1.0.1: {} vlq@2.0.4: {} From 97e9fcc8b9d740c4aadecb238e394b6c52e52825 Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Fri, 6 Jun 2025 14:02:55 -0700 Subject: [PATCH 02/10] handle multiple chains --- apps/entropy-tester/config.sample.yaml | 8 +++- apps/entropy-tester/src/index.ts | 57 ++++++++++++++++---------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/apps/entropy-tester/config.sample.yaml b/apps/entropy-tester/config.sample.yaml index 049c2d89fb..c7f19be98e 100644 --- a/apps/entropy-tester/config.sample.yaml +++ b/apps/entropy-tester/config.sample.yaml @@ -1,2 +1,6 @@ -chain-id: berachain_mainnet -interval: 14h +- chain-id: berachain_mainnet + interval: 3h +- chain-id: apechain_mainnet + interval: 6h +- chain-id: blast + interval: 10m diff --git a/apps/entropy-tester/src/index.ts b/apps/entropy-tester/src/index.ts index 31f213e21f..b7861f8989 100644 --- a/apps/entropy-tester/src/index.ts +++ b/apps/entropy-tester/src/index.ts @@ -3,7 +3,7 @@ import yargs from "yargs"; import { hideBin } from "yargs/helpers"; import YAML from "yaml"; import fs from "fs"; -import pino from "pino"; +import pino, { Logger } from "pino"; import { DefaultStore } from "@pythnetwork/contract-manager/node/store"; import { EvmEntropyContract } from "@pythnetwork/contract-manager/core/contracts/evm"; import { PrivateKey, toPrivateKey } from "@pythnetwork/contract-manager/core/base"; @@ -28,25 +28,29 @@ function timeToSeconds(timeStr: string): number { default: throw new Error("Unsupported time unit."); } } -const logger = pino(); -function loadConfig(configPath: string): LoadedConfig { - const config = YAML.parse(fs.readFileSync(configPath, "utf-8")); - const contracts = Object.values(DefaultStore.entropy_contracts).filter((contract) => ( - contract.chain.getId() == config['chain-id'] - )) - if (contracts.length === 0) { - logger.error("Couldn't find the contract id, check contract manager store.") - process.exit(1) + +function loadConfig(configPath: string): LoadedConfig[] { + const configs = YAML.parse(fs.readFileSync(configPath, "utf-8")); + const loadedConfigs = []; + for (const config of configs) { + const interval = timeToSeconds(config['interval']); + const contracts = Object.values(DefaultStore.entropy_contracts).filter((contract) => ( + contract.chain.getId() == config['chain-id'] + )) + if (contracts.length !== 1) { + throw new Error(`Can not find the contract id ${config['chain-id']}, check contract manager store.`) + } + loadedConfigs.push({ contract: contracts[0], interval }) } - const interval = timeToSeconds(config['interval']); - return { contract: contracts[0], interval } + return loadedConfigs } async function testLatency( contract: EvmEntropyContract, privateKey: PrivateKey, + logger: Logger ) { const provider = await contract.getDefaultProvider(); const userRandomNumber = contract.generateUserRandomNumber(); @@ -59,7 +63,7 @@ async function testLatency( // Read the sequence number for the request from the transaction events. const sequenceNumber = parseInt(requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber); - logger.info(`Request tx hash: ${requestResponse.transactionHash} Seq. No: ${sequenceNumber}`); + logger.info({ sequnce: sequenceNumber, txHash: requestResponse.transactionHash }, `Request submitted`); const startTime = Date.now(); @@ -71,11 +75,11 @@ async function testLatency( if (parseInt(request.sequenceNumber) === 0) { // 0 means the request is cleared const endTime = Date.now(); - logger.info(`Fortuna Latency: ${endTime - startTime}ms`); + logger.info({ sequnce: sequenceNumber, latency: endTime - startTime }, `Successful callback`); break; } if (Date.now() - startTime > 60000) { - logger.error("Timeout: 60s passed without the callback being called."); + logger.error({ sequnce: sequenceNumber }, "Timeout: 60s passed without the callback being called"); break; } } @@ -108,18 +112,29 @@ yargs(hideBin(process.argv)) }, }, handler: async (argv: any) => { - const { contract, interval } = loadConfig(argv.config); + const logger = pino(); + const configs = loadConfig(argv.config); if (argv.validate) { logger.info("Config validated") return; } const privateKey = toPrivateKey(fs.readFileSync(argv['private-key'], "utf-8").replace('0x', '').trimEnd()) logger.info("Running") - // eslint-disable-next-line no-constant-condition - while (true) { - await testLatency(contract, privateKey); - await new Promise((resolve) => setTimeout(resolve, interval)); - } + const promises = configs.map(async ({ contract, interval }) => { + const child = logger.child({ chain: contract.chain.getId() }) + // eslint-disable-next-line no-constant-condition + while (true) { + try { + await testLatency(contract, privateKey, child); + } + catch (e) { + child.error(e, "Error testing latency") + } + await new Promise((resolve) => setTimeout(resolve, interval * 1000)); + } + }); + await Promise.all(promises); + } }) .demandCommand() From 91d8de318cf4aa4cdf075e6ee751f8cffaca4693 Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Fri, 6 Jun 2025 14:09:16 -0700 Subject: [PATCH 03/10] typo --- apps/entropy-tester/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/entropy-tester/src/index.ts b/apps/entropy-tester/src/index.ts index b7861f8989..8297ed65f3 100644 --- a/apps/entropy-tester/src/index.ts +++ b/apps/entropy-tester/src/index.ts @@ -63,7 +63,7 @@ async function testLatency( // Read the sequence number for the request from the transaction events. const sequenceNumber = parseInt(requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber); - logger.info({ sequnce: sequenceNumber, txHash: requestResponse.transactionHash }, `Request submitted`); + logger.info({ sequence: sequenceNumber, txHash: requestResponse.transactionHash }, `Request submitted`); const startTime = Date.now(); @@ -75,11 +75,11 @@ async function testLatency( if (parseInt(request.sequenceNumber) === 0) { // 0 means the request is cleared const endTime = Date.now(); - logger.info({ sequnce: sequenceNumber, latency: endTime - startTime }, `Successful callback`); + logger.info({ sequence: sequenceNumber, latency: endTime - startTime }, `Successful callback`); break; } if (Date.now() - startTime > 60000) { - logger.error({ sequnce: sequenceNumber }, "Timeout: 60s passed without the callback being called"); + logger.error({ sequence: sequenceNumber }, "Timeout: 60s passed without the callback being called"); break; } } From b3a9394c1dbbcd3864aefed842f7aee1a180eec1 Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Fri, 6 Jun 2025 14:09:48 -0700 Subject: [PATCH 04/10] polish --- apps/entropy-tester/src/index.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/entropy-tester/src/index.ts b/apps/entropy-tester/src/index.ts index 8297ed65f3..59f7bbe263 100644 --- a/apps/entropy-tester/src/index.ts +++ b/apps/entropy-tester/src/index.ts @@ -38,8 +38,11 @@ function loadConfig(configPath: string): LoadedConfig[] { const contracts = Object.values(DefaultStore.entropy_contracts).filter((contract) => ( contract.chain.getId() == config['chain-id'] )) - if (contracts.length !== 1) { - throw new Error(`Can not find the contract id ${config['chain-id']}, check contract manager store.`) + if (contracts.length === 0) { + throw new Error(`Can not find the contract for chain ${config['chain-id']}, check contract manager store.`) + } + if (contracts.length > 1) { + throw new Error(`Multiple contracts found for chain ${config['chain-id']}, check contract manager store.`) } loadedConfigs.push({ contract: contracts[0], interval }) } @@ -63,7 +66,7 @@ async function testLatency( // Read the sequence number for the request from the transaction events. const sequenceNumber = parseInt(requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber); - logger.info({ sequence: sequenceNumber, txHash: requestResponse.transactionHash }, `Request submitted`); + logger.info({ sequenceNumber, txHash: requestResponse.transactionHash }, `Request submitted`); const startTime = Date.now(); @@ -75,11 +78,11 @@ async function testLatency( if (parseInt(request.sequenceNumber) === 0) { // 0 means the request is cleared const endTime = Date.now(); - logger.info({ sequence: sequenceNumber, latency: endTime - startTime }, `Successful callback`); + logger.info({ sequenceNumber, latency: endTime - startTime }, `Successful callback`); break; } if (Date.now() - startTime > 60000) { - logger.error({ sequence: sequenceNumber }, "Timeout: 60s passed without the callback being called"); + logger.error({ sequenceNumber }, "Timeout: 60s passed without the callback being called"); break; } } @@ -134,7 +137,6 @@ yargs(hideBin(process.argv)) } }); await Promise.all(promises); - } }) .demandCommand() From e2291360a1677394a0e41b6341ab574470e6c276 Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Fri, 6 Jun 2025 14:18:25 -0700 Subject: [PATCH 05/10] prettier --- apps/entropy-tester/src/index.ts | 249 +++++++++++++++++-------------- 1 file changed, 137 insertions(+), 112 deletions(-) diff --git a/apps/entropy-tester/src/index.ts b/apps/entropy-tester/src/index.ts index 59f7bbe263..53163edcae 100644 --- a/apps/entropy-tester/src/index.ts +++ b/apps/entropy-tester/src/index.ts @@ -6,138 +6,163 @@ import fs from "fs"; import pino, { Logger } from "pino"; import { DefaultStore } from "@pythnetwork/contract-manager/node/store"; import { EvmEntropyContract } from "@pythnetwork/contract-manager/core/contracts/evm"; -import { PrivateKey, toPrivateKey } from "@pythnetwork/contract-manager/core/base"; +import { + PrivateKey, + toPrivateKey, +} from "@pythnetwork/contract-manager/core/base"; type DurationSeconds = number; type LoadedConfig = { - contract: EvmEntropyContract, - interval: DurationSeconds -} + contract: EvmEntropyContract; + interval: DurationSeconds; +}; function timeToSeconds(timeStr: string): number { - const match = timeStr.match(/^(\d+)([hms])$/i); - if (!match) throw new Error("Invalid format. Use formats like '6h', '15m', or '30s'."); + const match = timeStr.match(/^(\d+)([hms])$/i); + if (!match) + throw new Error("Invalid format. Use formats like '6h', '15m', or '30s'."); - const value = parseInt(match[1], 10); - const unit = match[2].toLowerCase(); + const value = parseInt(match[1], 10); + const unit = match[2].toLowerCase(); - switch (unit) { - case 'h': return value * 3600; - case 'm': return value * 60; - case 's': return value; - default: throw new Error("Unsupported time unit."); - } + switch (unit) { + case "h": + return value * 3600; + case "m": + return value * 60; + case "s": + return value; + default: + throw new Error("Unsupported time unit."); + } } - function loadConfig(configPath: string): LoadedConfig[] { - const configs = YAML.parse(fs.readFileSync(configPath, "utf-8")); - const loadedConfigs = []; - for (const config of configs) { - const interval = timeToSeconds(config['interval']); - const contracts = Object.values(DefaultStore.entropy_contracts).filter((contract) => ( - contract.chain.getId() == config['chain-id'] - )) - if (contracts.length === 0) { - throw new Error(`Can not find the contract for chain ${config['chain-id']}, check contract manager store.`) - } - if (contracts.length > 1) { - throw new Error(`Multiple contracts found for chain ${config['chain-id']}, check contract manager store.`) - } - loadedConfigs.push({ contract: contracts[0], interval }) + const configs = YAML.parse(fs.readFileSync(configPath, "utf-8")); + const loadedConfigs = []; + for (const config of configs) { + const interval = timeToSeconds(config["interval"]); + const contracts = Object.values(DefaultStore.entropy_contracts).filter( + (contract) => contract.chain.getId() == config["chain-id"], + ); + if (contracts.length === 0) { + throw new Error( + `Can not find the contract for chain ${config["chain-id"]}, check contract manager store.`, + ); + } + if (contracts.length > 1) { + throw new Error( + `Multiple contracts found for chain ${config["chain-id"]}, check contract manager store.`, + ); } - return loadedConfigs + loadedConfigs.push({ contract: contracts[0], interval }); + } + return loadedConfigs; } - async function testLatency( - contract: EvmEntropyContract, - privateKey: PrivateKey, - logger: Logger + contract: EvmEntropyContract, + privateKey: PrivateKey, + logger: Logger, ) { - const provider = await contract.getDefaultProvider(); - const userRandomNumber = contract.generateUserRandomNumber(); - const requestResponse = await contract.requestRandomness( - userRandomNumber, - provider, - privateKey, - true, // with callback - ); - // Read the sequence number for the request from the transaction events. - const sequenceNumber = - parseInt(requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber); - logger.info({ sequenceNumber, txHash: requestResponse.transactionHash }, `Request submitted`); + const provider = await contract.getDefaultProvider(); + const userRandomNumber = contract.generateUserRandomNumber(); + const requestResponse = await contract.requestRandomness( + userRandomNumber, + provider, + privateKey, + true, // with callback + ); + // Read the sequence number for the request from the transaction events. + const sequenceNumber = parseInt( + requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber, + ); + logger.info( + { sequenceNumber, txHash: requestResponse.transactionHash }, + `Request submitted`, + ); - const startTime = Date.now(); + const startTime = Date.now(); - // eslint-disable-next-line no-constant-condition - while (true) { - await new Promise((resolve) => setTimeout(resolve, 2000)); - const request = await contract.getRequest(provider, sequenceNumber); - logger.debug(request) + // eslint-disable-next-line no-constant-condition + while (true) { + await new Promise((resolve) => setTimeout(resolve, 2000)); + const request = await contract.getRequest(provider, sequenceNumber); + logger.debug(request); - if (parseInt(request.sequenceNumber) === 0) { // 0 means the request is cleared - const endTime = Date.now(); - logger.info({ sequenceNumber, latency: endTime - startTime }, `Successful callback`); - break; - } - if (Date.now() - startTime > 60000) { - logger.error({ sequenceNumber }, "Timeout: 60s passed without the callback being called"); - break; - } + if (parseInt(request.sequenceNumber) === 0) { + // 0 means the request is cleared + const endTime = Date.now(); + logger.info( + { sequenceNumber, latency: endTime - startTime }, + `Successful callback`, + ); + break; + } + if (Date.now() - startTime > 60000) { + logger.error( + { sequenceNumber }, + "Timeout: 60s passed without the callback being called", + ); + break; } + } } - yargs(hideBin(process.argv)) - .parserConfiguration({ - "parse-numbers": false, - }) - .command({ - command: "run", - describe: "run the tester until manually stopped", - builder: { - validate: { - description: "Only validate the configs and exit", - type: "boolean", - default: false, - required: false - }, - config: { - description: "Yaml config file", - type: "string", - required: true, - }, - "private-key": { - type: "string", - required: true, - description: "Path to the private key to sign the transactions with. Should be hex encoded", - }, - }, - handler: async (argv: any) => { - const logger = pino(); - const configs = loadConfig(argv.config); - if (argv.validate) { - logger.info("Config validated") - return; - } - const privateKey = toPrivateKey(fs.readFileSync(argv['private-key'], "utf-8").replace('0x', '').trimEnd()) - logger.info("Running") - const promises = configs.map(async ({ contract, interval }) => { - const child = logger.child({ chain: contract.chain.getId() }) - // eslint-disable-next-line no-constant-condition - while (true) { - try { - await testLatency(contract, privateKey, child); - } - catch (e) { - child.error(e, "Error testing latency") - } - await new Promise((resolve) => setTimeout(resolve, interval * 1000)); - } - }); - await Promise.all(promises); + .parserConfiguration({ + "parse-numbers": false, + }) + .command({ + command: "run", + describe: "run the tester until manually stopped", + builder: { + validate: { + description: "Only validate the configs and exit", + type: "boolean", + default: false, + required: false, + }, + config: { + description: "Yaml config file", + type: "string", + required: true, + }, + "private-key": { + type: "string", + required: true, + description: + "Path to the private key to sign the transactions with. Should be hex encoded", + }, + }, + handler: async (argv: any) => { + const logger = pino(); + const configs = loadConfig(argv.config); + if (argv.validate) { + logger.info("Config validated"); + return; + } + const privateKey = toPrivateKey( + fs + .readFileSync(argv["private-key"], "utf-8") + .replace("0x", "") + .trimEnd(), + ); + logger.info("Running"); + const promises = configs.map(async ({ contract, interval }) => { + const child = logger.child({ chain: contract.chain.getId() }); + // eslint-disable-next-line no-constant-condition + while (true) { + try { + await testLatency(contract, privateKey, child); + } catch (e) { + child.error(e, "Error testing latency"); + } + await new Promise((resolve) => setTimeout(resolve, interval * 1000)); } - }) - .demandCommand() - .help().argv; + }); + await Promise.all(promises); + }, + }) + .demandCommand() + .help().argv; From 3adf9921edef5ceb2034afc3ce8c2835326a201c Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Mon, 9 Jun 2025 10:34:56 -0700 Subject: [PATCH 06/10] fixed some of the issues --- apps/entropy-tester/.eslintrc.js | 10 - apps/entropy-tester/cli/run.js | 3 + apps/entropy-tester/eslint.config.js | 1 + apps/entropy-tester/package.json | 47 +++-- apps/entropy-tester/src/index.ts | 296 ++++++++++++++------------- apps/entropy-tester/tsconfig.json | 16 +- pnpm-lock.yaml | 188 +++++++++++++++-- 7 files changed, 351 insertions(+), 210 deletions(-) delete mode 100644 apps/entropy-tester/.eslintrc.js create mode 100644 apps/entropy-tester/cli/run.js create mode 100644 apps/entropy-tester/eslint.config.js diff --git a/apps/entropy-tester/.eslintrc.js b/apps/entropy-tester/.eslintrc.js deleted file mode 100644 index a32b4a16d8..0000000000 --- a/apps/entropy-tester/.eslintrc.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - root: true, - parser: "@typescript-eslint/parser", - plugins: ["@typescript-eslint"], - extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], - rules: { - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-non-null-assertion": "off", - }, -}; diff --git a/apps/entropy-tester/cli/run.js b/apps/entropy-tester/cli/run.js new file mode 100644 index 0000000000..88949bac02 --- /dev/null +++ b/apps/entropy-tester/cli/run.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node +import { main } from "../dist/index.js"; +main(); diff --git a/apps/entropy-tester/eslint.config.js b/apps/entropy-tester/eslint.config.js new file mode 100644 index 0000000000..7035c57cb4 --- /dev/null +++ b/apps/entropy-tester/eslint.config.js @@ -0,0 +1 @@ +export { nextjs as default } from "@cprussin/eslint-config"; diff --git a/apps/entropy-tester/package.json b/apps/entropy-tester/package.json index 01ba7bae9a..aafd4204c3 100644 --- a/apps/entropy-tester/package.json +++ b/apps/entropy-tester/package.json @@ -2,22 +2,27 @@ "name": "@pythnetwork/entropy-tester", "version": "1.0.0", "description": "Utility to test entropy provider callbacks", - "main": "lib/index.js", - "types": "lib/index.d.ts", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, "files": [ - "lib/**/*" + "dist/**/*", + "cli/**/*" ], "scripts": { "build": "tsc", - "fix:format": "prettier --write \"src/**/*.ts\"", - "fix:lint": "eslint src/ --fix --max-warnings 0", - "test:format": "prettier --check \"src/**/*.ts\"", - "test:lint": "eslint src/ --max-warnings 0", - "start": "node lib/index.js", - "dev": "ts-node src/index.ts", - "prepublishOnly": "pnpm run build && pnpm run test:lint", - "preversion": "pnpm run test:lint", - "version": "pnpm run test:format && pnpm run test:lint && git add -A src" + "fix:format": "prettier --write .", + "fix:lint": "eslint --fix .", + "test:format": "prettier --check .", + "test:lint": "eslint . --max-warnings 0", + "test:types": "tsc", + "start": "tsc && node cli/run.js" }, "repository": { "type": "git", @@ -25,34 +30,32 @@ "directory": "apps/entropy-tester" }, "bin": { - "pyth-entropy-tester": "./lib/index.js" + "pyth-entropy-tester": "./cli/run.js" }, "devDependencies": { - "@types/ethereum-protocol": "^1.0.2", + "@cprussin/eslint-config": "catalog:", + "@cprussin/prettier-config": "catalog:", + "@cprussin/tsconfig": "catalog:", "@types/express": "^4.17.21", - "@types/jest": "^27.4.1", "@types/yargs": "^17.0.10", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", - "eslint": "^8.13.0", - "jest": "^29.7.0", + "eslint": "catalog:", "pino-pretty": "^11.2.1", "prettier": "catalog:", - "ts-jest": "^29.1.1", "ts-node": "catalog:", "typescript": "catalog:" }, "dependencies": { "@pythnetwork/contract-manager": "workspace:*", "joi": "^17.6.0", - "pino": "^9.2.0", + "pino": "catalog:", "prom-client": "^15.1.0", - "viem": "^2.19.4", + "viem": "catalog:", "yaml": "^2.1.1", "yargs": "^17.5.1" }, "keywords": [], "author": "", - "license": "Apache-2.0", - "packageManager": "pnpm@10.7.0" + "license": "Apache-2.0" } diff --git a/apps/entropy-tester/src/index.ts b/apps/entropy-tester/src/index.ts index 53163edcae..ea7cb5411f 100644 --- a/apps/entropy-tester/src/index.ts +++ b/apps/entropy-tester/src/index.ts @@ -1,168 +1,176 @@ -#!/usr/bin/env node -import yargs from "yargs"; -import { hideBin } from "yargs/helpers"; -import YAML from "yaml"; -import fs from "fs"; -import pino, { Logger } from "pino"; -import { DefaultStore } from "@pythnetwork/contract-manager/node/store"; -import { EvmEntropyContract } from "@pythnetwork/contract-manager/core/contracts/evm"; +import fs from "node:fs"; + +import type {PrivateKey} from "@pythnetwork/contract-manager/core/base"; import { - PrivateKey, - toPrivateKey, + toPrivateKey } from "@pythnetwork/contract-manager/core/base"; +import { EvmEntropyContract } from "@pythnetwork/contract-manager/core/contracts/evm"; +import { DefaultStore } from "@pythnetwork/contract-manager/node/store"; +import type {Logger} from "pino"; +import { pino } from "pino"; +import YAML from "yaml"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; + type DurationSeconds = number; type LoadedConfig = { - contract: EvmEntropyContract; - interval: DurationSeconds; + contract: EvmEntropyContract; + interval: DurationSeconds; }; function timeToSeconds(timeStr: string): number { - const match = timeStr.match(/^(\d+)([hms])$/i); - if (!match) - throw new Error("Invalid format. Use formats like '6h', '15m', or '30s'."); + const match = /^(\d+)([hms])$/i.exec(timeStr); + if (!match?.[1] || !match[2]) + throw new Error("Invalid format. Use formats like '6h', '15m', or '30s'."); - const value = parseInt(match[1], 10); - const unit = match[2].toLowerCase(); + const value = Number.parseInt(match[1], 10); + const unit = match[2].toLowerCase(); - switch (unit) { - case "h": - return value * 3600; - case "m": - return value * 60; - case "s": - return value; - default: - throw new Error("Unsupported time unit."); - } + switch (unit) { + case "h": { + return value * 3600; + } + case "m": { + return value * 60; + } + case "s": { + return value; + } + default: { + throw new Error("Unsupported time unit."); + } + } } function loadConfig(configPath: string): LoadedConfig[] { - const configs = YAML.parse(fs.readFileSync(configPath, "utf-8")); - const loadedConfigs = []; - for (const config of configs) { - const interval = timeToSeconds(config["interval"]); - const contracts = Object.values(DefaultStore.entropy_contracts).filter( - (contract) => contract.chain.getId() == config["chain-id"], - ); - if (contracts.length === 0) { - throw new Error( - `Can not find the contract for chain ${config["chain-id"]}, check contract manager store.`, - ); - } - if (contracts.length > 1) { - throw new Error( - `Multiple contracts found for chain ${config["chain-id"]}, check contract manager store.`, - ); + const configs: any = YAML.parse(fs.readFileSync(configPath, "utf8")); + const loadedConfigs = []; + for (const config of configs) { + const interval = timeToSeconds(config.interval); + const contracts = Object.values(DefaultStore.entropy_contracts).filter( + (contract) => contract.chain.getId() == config["chain-id"], + ); + if (contracts.length === 0) { + throw new Error( + `Can not find the contract for chain ${config["chain-id"]}, check contract manager store.`, + ); + } + if (contracts.length > 1) { + throw new Error( + `Multiple contracts found for chain ${config["chain-id"]}, check contract manager store.`, + ); + } + loadedConfigs.push({ contract: contracts[0]!, interval }); } - loadedConfigs.push({ contract: contracts[0], interval }); - } - return loadedConfigs; + return loadedConfigs; } async function testLatency( - contract: EvmEntropyContract, - privateKey: PrivateKey, - logger: Logger, + contract: EvmEntropyContract, + privateKey: PrivateKey, + logger: Logger, ) { - const provider = await contract.getDefaultProvider(); - const userRandomNumber = contract.generateUserRandomNumber(); - const requestResponse = await contract.requestRandomness( - userRandomNumber, - provider, - privateKey, - true, // with callback - ); - // Read the sequence number for the request from the transaction events. - const sequenceNumber = parseInt( - requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber, - ); - logger.info( - { sequenceNumber, txHash: requestResponse.transactionHash }, - `Request submitted`, - ); + const provider = await contract.getDefaultProvider(); + const userRandomNumber = contract.generateUserRandomNumber(); + const requestResponse = await contract.requestRandomness( + userRandomNumber, + provider, + privateKey, + true, // with callback + ); + // Read the sequence number for the request from the transaction events. + const sequenceNumber = Number.parseInt( + requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber, + ); + logger.info( + { sequenceNumber, txHash: requestResponse.transactionHash }, + `Request submitted`, + ); - const startTime = Date.now(); + const startTime = Date.now(); - // eslint-disable-next-line no-constant-condition - while (true) { - await new Promise((resolve) => setTimeout(resolve, 2000)); - const request = await contract.getRequest(provider, sequenceNumber); - logger.debug(request); - if (parseInt(request.sequenceNumber) === 0) { - // 0 means the request is cleared - const endTime = Date.now(); - logger.info( - { sequenceNumber, latency: endTime - startTime }, - `Successful callback`, - ); - break; - } - if (Date.now() - startTime > 60000) { - logger.error( - { sequenceNumber }, - "Timeout: 60s passed without the callback being called", - ); - break; + while (true) { + await new Promise((resolve) => setTimeout(resolve, 2000)); + const request = await contract.getRequest(provider, sequenceNumber); + logger.debug(request); + + if (Number.parseInt(request.sequenceNumber) === 0) { + // 0 means the request is cleared + const endTime = Date.now(); + logger.info( + { sequenceNumber, latency: endTime - startTime }, + `Successful callback`, + ); + break; + } + if (Date.now() - startTime > 60_000) { + logger.error( + { sequenceNumber }, + "Timeout: 60s passed without the callback being called", + ); + break; + } } - } } -yargs(hideBin(process.argv)) - .parserConfiguration({ - "parse-numbers": false, - }) - .command({ - command: "run", - describe: "run the tester until manually stopped", - builder: { - validate: { - description: "Only validate the configs and exit", - type: "boolean", - default: false, - required: false, - }, - config: { - description: "Yaml config file", - type: "string", - required: true, - }, - "private-key": { - type: "string", - required: true, - description: - "Path to the private key to sign the transactions with. Should be hex encoded", - }, - }, - handler: async (argv: any) => { - const logger = pino(); - const configs = loadConfig(argv.config); - if (argv.validate) { - logger.info("Config validated"); - return; - } - const privateKey = toPrivateKey( - fs - .readFileSync(argv["private-key"], "utf-8") - .replace("0x", "") - .trimEnd(), - ); - logger.info("Running"); - const promises = configs.map(async ({ contract, interval }) => { - const child = logger.child({ chain: contract.chain.getId() }); - // eslint-disable-next-line no-constant-condition - while (true) { - try { - await testLatency(contract, privateKey, child); - } catch (e) { - child.error(e, "Error testing latency"); - } - await new Promise((resolve) => setTimeout(resolve, interval * 1000)); - } - }); - await Promise.all(promises); - }, - }) - .demandCommand() - .help().argv; +export const main = function () { + yargs(hideBin(process.argv)) + .parserConfiguration({ + "parse-numbers": false, + }) + .command({ + command: "run", + describe: "run the tester until manually stopped", + builder: { + validate: { + description: "Only validate the configs and exit", + type: "boolean", + default: false, + required: false, + }, + config: { + description: "Yaml config file", + type: "string", + required: true, + }, + "private-key": { + type: "string", + required: true, + description: + "Path to the private key to sign the transactions with. Should be hex encoded", + }, + }, + handler: async (argv: any) => { + const logger = pino(); + const configs = loadConfig(argv.config); + if (argv.validate) { + logger.info("Config validated"); + return; + } + const privateKey = toPrivateKey( + fs + .readFileSync(argv["private-key"], "utf8") + .replace("0x", "") + .trimEnd(), + ); + logger.info("Running"); + const promises = configs.map(async ({ contract, interval }) => { + const child = logger.child({ chain: contract.chain.getId() }); + + while (true) { + try { + await testLatency(contract, privateKey, child); + } catch (error) { + child.error(error, "Error testing latency"); + } + await new Promise((resolve) => setTimeout(resolve, interval * 1000)); + } + }); + await Promise.all(promises); + }, + }) + .demandCommand() + .help().argv; +} diff --git a/apps/entropy-tester/tsconfig.json b/apps/entropy-tester/tsconfig.json index be11dcb27f..dfd9bf96d0 100644 --- a/apps/entropy-tester/tsconfig.json +++ b/apps/entropy-tester/tsconfig.json @@ -1,15 +1,5 @@ { - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "target": "esnext", - "module": "nodenext", - "declaration": true, - "rootDir": "src/", - "outDir": "./lib", - "strict": true, - "esModuleInterop": true, - "resolveJsonModule": true - }, - "include": ["src"], - "exclude": ["node_modules", "**/__tests__/*"] + "extends": "@cprussin/tsconfig/nextjs.json", + "include": ["svg.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 648460156f..db321ecf2d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -795,13 +795,13 @@ importers: specifier: ^17.6.0 version: 17.13.3 pino: - specifier: ^9.2.0 + specifier: 'catalog:' version: 9.6.0 prom-client: specifier: ^15.1.0 version: 15.1.3 viem: - specifier: ^2.19.4 + specifier: 'catalog:' version: 2.24.3(bufferutil@4.0.9)(typescript@5.8.2)(utf-8-validate@6.0.3)(zod@3.24.4) yaml: specifier: ^2.1.1 @@ -810,39 +810,39 @@ importers: specifier: ^17.5.1 version: 17.7.2 devDependencies: - '@types/ethereum-protocol': - specifier: ^1.0.2 - version: 1.0.5 + '@cprussin/eslint-config': + specifier: 'catalog:' + version: 4.0.2(@testing-library/dom@10.4.0)(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(jest@29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)))(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2))(turbo@2.4.4)(typescript@5.8.2) + '@cprussin/jest-config': + specifier: 'catalog:' + version: 2.0.2(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(bufferutil@4.0.9)(esbuild@0.25.4)(eslint@9.23.0(jiti@2.4.2))(jest@29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)))(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.86.1))(prettier@3.5.3)(typescript@5.8.2)(utf-8-validate@6.0.3) + '@cprussin/prettier-config': + specifier: 'catalog:' + version: 2.2.2(prettier@3.5.3) + '@cprussin/tsconfig': + specifier: 'catalog:' + version: 3.1.2(typescript@5.8.2) '@types/express': specifier: ^4.17.21 version: 4.17.21 - '@types/jest': - specifier: ^27.4.1 - version: 27.5.2 '@types/yargs': specifier: ^17.0.10 version: 17.0.33 '@typescript-eslint/eslint-plugin': specifier: ^6.0.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0)(typescript@5.8.2) + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) '@typescript-eslint/parser': specifier: ^6.0.0 - version: 6.21.0(eslint@8.56.0)(typescript@5.8.2) + version: 6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) eslint: - specifier: ^8.13.0 - version: 8.56.0 - jest: - specifier: ^29.7.0 - version: 29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)) + specifier: 'catalog:' + version: 9.23.0(jiti@2.4.2) pino-pretty: specifier: ^11.2.1 version: 11.3.0 prettier: specifier: 'catalog:' version: 3.5.3 - ts-jest: - specifier: ^29.1.1 - version: 29.3.1(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(esbuild@0.25.4)(jest@29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)))(typescript@5.8.2) ts-node: specifier: 'catalog:' version: 10.9.2(@types/node@22.14.0)(typescript@5.8.2) @@ -25985,6 +25985,43 @@ snapshots: transitivePeerDependencies: - debug + '@cprussin/eslint-config@4.0.2(@testing-library/dom@10.4.0)(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(jest@29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)))(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2))(turbo@2.4.4)(typescript@5.8.2)': + dependencies: + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.23.0 + '@next/eslint-plugin-next': 15.2.4 + eslint: 9.23.0(jiti@2.4.2) + eslint-config-prettier: 10.1.1(eslint@9.23.0(jiti@2.4.2)) + eslint-config-turbo: 2.4.4(eslint@9.23.0(jiti@2.4.2))(turbo@2.4.4) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-jest: 28.11.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(jest@29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)))(typescript@5.8.2) + eslint-plugin-jest-dom: 5.5.0(@testing-library/dom@10.4.0)(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-jsonc: 2.20.0(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-n: 17.17.0(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-react: 7.37.4(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-storybook: 0.11.6(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint-plugin-tailwindcss: 3.18.0(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2))) + eslint-plugin-testing-library: 7.1.1(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint-plugin-tsdoc: 0.4.0 + eslint-plugin-unicorn: 57.0.0(eslint@9.23.0(jiti@2.4.2)) + globals: 16.0.0 + tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)) + typescript-eslint: 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + transitivePeerDependencies: + - '@eslint/json' + - '@testing-library/dom' + - '@typescript-eslint/eslint-plugin' + - '@typescript-eslint/parser' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + - ts-node + - turbo + - typescript + '@cprussin/eslint-config@4.0.2(@testing-library/dom@10.4.0)(@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(jest@29.7.0(@types/node@18.19.86)(ts-node@10.9.2(@types/node@18.19.86)(typescript@5.8.2)))(ts-node@10.9.2(@types/node@18.19.86)(typescript@5.8.2))(turbo@2.4.4)(typescript@5.8.2)': dependencies: '@eslint/eslintrc': 3.3.1 @@ -37327,6 +37364,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/utils': 6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.4.0(supports-color@8.1.1) + eslint: 9.23.0(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + semver: 7.7.1 + ts-api-utils: 1.4.3(typescript@5.8.2) + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0)(typescript@5.8.2)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -37417,6 +37474,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + dependencies: + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.2) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.4.0(supports-color@8.1.1) + eslint: 9.23.0(jiti@2.4.2) + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@7.18.0(eslint@8.56.0)(typescript@5.8.2)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 @@ -37498,6 +37568,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/type-utils@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + dependencies: + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.2) + '@typescript-eslint/utils': 6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + debug: 4.4.0(supports-color@8.1.1) + eslint: 9.23.0(jiti@2.4.2) + ts-api-utils: 1.4.3(typescript@5.8.2) + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/type-utils@7.18.0(eslint@8.56.0)(typescript@5.8.2)': dependencies: '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.2) @@ -37645,6 +37727,20 @@ snapshots: - supports-color - typescript + '@typescript-eslint/utils@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + dependencies: + '@eslint-community/eslint-utils': 4.5.1(eslint@9.23.0(jiti@2.4.2)) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.0 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.2) + eslint: 9.23.0(jiti@2.4.2) + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/utils@7.18.0(eslint@8.56.0)(typescript@5.8.2)': dependencies: '@eslint-community/eslint-utils': 4.5.1(eslint@8.56.0) @@ -42106,7 +42202,7 @@ snapshots: eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.56.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.56.0) eslint-plugin-react: 7.37.4(eslint@8.56.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.56.0) @@ -42150,7 +42246,7 @@ snapshots: tinyglobby: 0.2.12 unrs-resolver: 1.3.3 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.56.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) transitivePeerDependencies: - supports-color @@ -42171,6 +42267,16 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.23.0(jiti@2.4.2)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint: 9.23.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.23.0(jiti@2.4.2)): dependencies: debug: 3.2.7 @@ -42188,7 +42294,7 @@ snapshots: eslint: 9.23.0(jiti@2.4.2) eslint-compat-utils: 0.5.1(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.56.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -42217,6 +42323,35 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2)): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.23.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.23.0(jiti@2.4.2)) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 @@ -42254,6 +42389,17 @@ snapshots: optionalDependencies: '@testing-library/dom': 10.4.0 + eslint-plugin-jest@28.11.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(jest@29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)))(typescript@5.8.2): + dependencies: + '@typescript-eslint/utils': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint: 9.23.0(jiti@2.4.2) + optionalDependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + jest: 29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)) + transitivePeerDependencies: + - supports-color + - typescript + eslint-plugin-jest@28.11.0(@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(jest@29.7.0(@types/node@18.19.86)(ts-node@10.9.2(@types/node@18.19.86)(typescript@5.8.2)))(typescript@5.8.2): dependencies: '@typescript-eslint/utils': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) From d478132185fb0ef58bff8169468984d0a2c352ce Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Mon, 9 Jun 2025 15:39:33 -0700 Subject: [PATCH 07/10] fix --- apps/entropy-tester/config.sample.json | 14 ++ apps/entropy-tester/config.sample.yaml | 6 - apps/entropy-tester/package.json | 1 - apps/entropy-tester/src/index.ts | 301 +++++++++++++------------ pnpm-lock.yaml | 12 +- 5 files changed, 177 insertions(+), 157 deletions(-) create mode 100644 apps/entropy-tester/config.sample.json delete mode 100644 apps/entropy-tester/config.sample.yaml diff --git a/apps/entropy-tester/config.sample.json b/apps/entropy-tester/config.sample.json new file mode 100644 index 0000000000..7ceb05dd28 --- /dev/null +++ b/apps/entropy-tester/config.sample.json @@ -0,0 +1,14 @@ +[ + { + "chain-id": "berachain_mainnet", + "interval": "3h" + }, + { + "chain-id": "apechain_mainnet", + "interval": "6h" + }, + { + "chain-id": "blast", + "interval": "10m" + } +] diff --git a/apps/entropy-tester/config.sample.yaml b/apps/entropy-tester/config.sample.yaml deleted file mode 100644 index c7f19be98e..0000000000 --- a/apps/entropy-tester/config.sample.yaml +++ /dev/null @@ -1,6 +0,0 @@ -- chain-id: berachain_mainnet - interval: 3h -- chain-id: apechain_mainnet - interval: 6h -- chain-id: blast - interval: 10m diff --git a/apps/entropy-tester/package.json b/apps/entropy-tester/package.json index aafd4204c3..afd4a1687c 100644 --- a/apps/entropy-tester/package.json +++ b/apps/entropy-tester/package.json @@ -52,7 +52,6 @@ "pino": "catalog:", "prom-client": "^15.1.0", "viem": "catalog:", - "yaml": "^2.1.1", "yargs": "^17.5.1" }, "keywords": [], diff --git a/apps/entropy-tester/src/index.ts b/apps/entropy-tester/src/index.ts index ea7cb5411f..5ec3a61f67 100644 --- a/apps/entropy-tester/src/index.ts +++ b/apps/entropy-tester/src/index.ts @@ -1,176 +1,195 @@ -import fs from "node:fs"; +import fs from "node:fs/promises"; -import type {PrivateKey} from "@pythnetwork/contract-manager/core/base"; -import { - toPrivateKey -} from "@pythnetwork/contract-manager/core/base"; +import type { PrivateKey } from "@pythnetwork/contract-manager/core/base"; +import { toPrivateKey } from "@pythnetwork/contract-manager/core/base"; import { EvmEntropyContract } from "@pythnetwork/contract-manager/core/contracts/evm"; import { DefaultStore } from "@pythnetwork/contract-manager/node/store"; -import type {Logger} from "pino"; -import { pino } from "pino"; -import YAML from "yaml"; +import type { Logger } from "pino"; +import { pino } from "pino"; +import type { ArgumentsCamelCase, InferredOptionTypes } from "yargs"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; - type DurationSeconds = number; type LoadedConfig = { - contract: EvmEntropyContract; - interval: DurationSeconds; + contract: EvmEntropyContract; + interval: DurationSeconds; }; function timeToSeconds(timeStr: string): number { - const match = /^(\d+)([hms])$/i.exec(timeStr); - if (!match?.[1] || !match[2]) - throw new Error("Invalid format. Use formats like '6h', '15m', or '30s'."); + const match = /^(\d+)([hms])$/i.exec(timeStr); + if (!match?.[1] || !match[2]) + throw new Error("Invalid format. Use formats like '6h', '15m', or '30s'."); - const value = Number.parseInt(match[1], 10); - const unit = match[2].toLowerCase(); + const value = Number.parseInt(match[1], 10); + const unit = match[2].toLowerCase(); - switch (unit) { - case "h": { - return value * 3600; - } - case "m": { - return value * 60; - } - case "s": { - return value; - } - default: { - throw new Error("Unsupported time unit."); - } + switch (unit) { + case "h": { + return value * 3600; } + case "m": { + return value * 60; + } + case "s": { + return value; + } + default: { + throw new Error("Unsupported time unit."); + } + } } -function loadConfig(configPath: string): LoadedConfig[] { - const configs: any = YAML.parse(fs.readFileSync(configPath, "utf8")); - const loadedConfigs = []; - for (const config of configs) { - const interval = timeToSeconds(config.interval); - const contracts = Object.values(DefaultStore.entropy_contracts).filter( - (contract) => contract.chain.getId() == config["chain-id"], - ); - if (contracts.length === 0) { - throw new Error( - `Can not find the contract for chain ${config["chain-id"]}, check contract manager store.`, - ); - } - if (contracts.length > 1) { - throw new Error( - `Multiple contracts found for chain ${config["chain-id"]}, check contract manager store.`, - ); - } - loadedConfigs.push({ contract: contracts[0]!, interval }); +type ParsedConfig = { + "chain-id": string; + interval: string; +}; + +async function loadConfig(configPath: string): Promise { + const configs = (await import(configPath, { + with: { type: "json" }, + })) as { default: ParsedConfig[] }; + const loadedConfigs = configs.default.map((config) => { + const interval = timeToSeconds(config.interval); + const contracts = Object.values(DefaultStore.entropy_contracts).filter( + (contract) => contract.chain.getId() == config["chain-id"], + ); + if (contracts.length === 0 || !contracts[0]) { + throw new Error( + `Can not find the contract for chain ${config["chain-id"]}, check contract manager store.`, + ); + } + if (contracts.length > 1) { + throw new Error( + `Multiple contracts found for chain ${config["chain-id"]}, check contract manager store.`, + ); } - return loadedConfigs; + return { contract: contracts[0], interval }; + }); + return loadedConfigs; } async function testLatency( - contract: EvmEntropyContract, - privateKey: PrivateKey, - logger: Logger, + contract: EvmEntropyContract, + privateKey: PrivateKey, + logger: Logger, ) { - const provider = await contract.getDefaultProvider(); - const userRandomNumber = contract.generateUserRandomNumber(); - const requestResponse = await contract.requestRandomness( - userRandomNumber, - provider, - privateKey, - true, // with callback - ); - // Read the sequence number for the request from the transaction events. - const sequenceNumber = Number.parseInt( - requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber, - ); - logger.info( - { sequenceNumber, txHash: requestResponse.transactionHash }, - `Request submitted`, - ); - - const startTime = Date.now(); + const provider = await contract.getDefaultProvider(); + const userRandomNumber = contract.generateUserRandomNumber(); + const requestResponse = (await contract.requestRandomness( + userRandomNumber, + provider, + privateKey, + true, // with callback + )) as { + transactionHash: string; + events: { + RequestedWithCallback: { + returnValues: { + sequenceNumber: string; + }; + }; + }; + }; + // Read the sequence number for the request from the transaction events. + const sequenceNumber = Number.parseInt( + requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber, + ); + logger.info( + { sequenceNumber, txHash: requestResponse.transactionHash }, + `Request submitted`, + ); + const startTime = Date.now(); - while (true) { - await new Promise((resolve) => setTimeout(resolve, 2000)); - const request = await contract.getRequest(provider, sequenceNumber); - logger.debug(request); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + while (true) { + await new Promise((resolve) => setTimeout(resolve, 2000)); + const request = await contract.getRequest(provider, sequenceNumber); + logger.debug(request); - if (Number.parseInt(request.sequenceNumber) === 0) { - // 0 means the request is cleared - const endTime = Date.now(); - logger.info( - { sequenceNumber, latency: endTime - startTime }, - `Successful callback`, - ); - break; - } - if (Date.now() - startTime > 60_000) { - logger.error( - { sequenceNumber }, - "Timeout: 60s passed without the callback being called", - ); - break; - } + if (Number.parseInt(request.sequenceNumber) === 0) { + // 0 means the request is cleared + const endTime = Date.now(); + logger.info( + { sequenceNumber, latency: endTime - startTime }, + `Successful callback`, + ); + break; } + if (Date.now() - startTime > 60_000) { + logger.error( + { sequenceNumber }, + "Timeout: 60s passed without the callback being called", + ); + break; + } + } } +const RUN_OPTIONS = { + validate: { + description: "Only validate the configs and exit", + type: "boolean", + default: false, + required: false, + }, + config: { + description: "Yaml config file", + type: "string", + required: true, + }, + "private-key": { + type: "string", + required: true, + description: + "Path to the private key to sign the transactions with. Should be hex encoded", + }, +} as const; + export const main = function () { - yargs(hideBin(process.argv)) + yargs(hideBin(process.argv)) .parserConfiguration({ - "parse-numbers": false, + "parse-numbers": false, }) .command({ - command: "run", - describe: "run the tester until manually stopped", - builder: { - validate: { - description: "Only validate the configs and exit", - type: "boolean", - default: false, - required: false, - }, - config: { - description: "Yaml config file", - type: "string", - required: true, - }, - "private-key": { - type: "string", - required: true, - description: - "Path to the private key to sign the transactions with. Should be hex encoded", - }, - }, - handler: async (argv: any) => { - const logger = pino(); - const configs = loadConfig(argv.config); - if (argv.validate) { - logger.info("Config validated"); - return; + command: "run", + describe: "run the tester until manually stopped", + builder: RUN_OPTIONS, + handler: async ( + argv: ArgumentsCamelCase>, + ) => { + const logger = pino(); + const configs = await loadConfig(argv.config); + if (argv.validate) { + logger.info("Config validated"); + return; + } + const privateKeyFileContent = await fs.readFile( + argv["private-key"], + "utf8", + ); + const privateKey = toPrivateKey( + privateKeyFileContent.replace("0x", "").trimEnd(), + ); + logger.info("Running"); + const promises = configs.map(async ({ contract, interval }) => { + const child = logger.child({ chain: contract.chain.getId() }); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + while (true) { + try { + await testLatency(contract, privateKey, child); + } catch (error) { + child.error(error, "Error testing latency"); } - const privateKey = toPrivateKey( - fs - .readFileSync(argv["private-key"], "utf8") - .replace("0x", "") - .trimEnd(), + await new Promise((resolve) => + setTimeout(resolve, interval * 1000), ); - logger.info("Running"); - const promises = configs.map(async ({ contract, interval }) => { - const child = logger.child({ chain: contract.chain.getId() }); - - while (true) { - try { - await testLatency(contract, privateKey, child); - } catch (error) { - child.error(error, "Error testing latency"); - } - await new Promise((resolve) => setTimeout(resolve, interval * 1000)); - } - }); - await Promise.all(promises); - }, + } + }); + await Promise.all(promises); + }, }) .demandCommand() - .help().argv; -} + .help(); +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db321ecf2d..f6993ed0e4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -803,9 +803,6 @@ importers: viem: specifier: 'catalog:' version: 2.24.3(bufferutil@4.0.9)(typescript@5.8.2)(utf-8-validate@6.0.3)(zod@3.24.4) - yaml: - specifier: ^2.1.1 - version: 2.7.1 yargs: specifier: ^17.5.1 version: 17.7.2 @@ -813,9 +810,6 @@ importers: '@cprussin/eslint-config': specifier: 'catalog:' version: 4.0.2(@testing-library/dom@10.4.0)(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(@typescript-eslint/parser@6.21.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(jest@29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)))(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2))(turbo@2.4.4)(typescript@5.8.2) - '@cprussin/jest-config': - specifier: 'catalog:' - version: 2.0.2(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(bufferutil@4.0.9)(esbuild@0.25.4)(eslint@9.23.0(jiti@2.4.2))(jest@29.7.0(@types/node@22.14.0)(ts-node@10.9.2(@types/node@22.14.0)(typescript@5.8.2)))(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.86.1))(prettier@3.5.3)(typescript@5.8.2)(utf-8-validate@6.0.3) '@cprussin/prettier-config': specifier: 'catalog:' version: 2.2.2(prettier@3.5.3) @@ -42202,7 +42196,7 @@ snapshots: eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.56.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.56.0) eslint-plugin-react: 7.37.4(eslint@8.56.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.56.0) @@ -42246,7 +42240,7 @@ snapshots: tinyglobby: 0.2.12 unrs-resolver: 1.3.3 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.56.0) transitivePeerDependencies: - supports-color @@ -42294,7 +42288,7 @@ snapshots: eslint: 9.23.0(jiti@2.4.2) eslint-compat-utils: 0.5.1(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.56.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 From 0d7f6fa46de33145e7059660deb379e9b5bb3483 Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Mon, 9 Jun 2025 15:42:26 -0700 Subject: [PATCH 08/10] fix --- apps/entropy-tester/src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/entropy-tester/src/index.ts b/apps/entropy-tester/src/index.ts index 5ec3a61f67..fe6718531d 100644 --- a/apps/entropy-tester/src/index.ts +++ b/apps/entropy-tester/src/index.ts @@ -10,10 +10,9 @@ import type { ArgumentsCamelCase, InferredOptionTypes } from "yargs"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; -type DurationSeconds = number; type LoadedConfig = { contract: EvmEntropyContract; - interval: DurationSeconds; + interval: number; }; function timeToSeconds(timeStr: string): number { From cd2b56e44a651aaaae320cf6788b086126bbf278 Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Mon, 9 Jun 2025 18:02:58 -0700 Subject: [PATCH 09/10] more fix --- apps/entropy-tester/package.json | 3 +- apps/entropy-tester/src/index.ts | 57 +++++++++++++++++-------------- apps/entropy-tester/tsconfig.json | 2 +- pnpm-lock.yaml | 22 +++--------- 4 files changed, 39 insertions(+), 45 deletions(-) diff --git a/apps/entropy-tester/package.json b/apps/entropy-tester/package.json index afd4a1687c..ec4f9b4d25 100644 --- a/apps/entropy-tester/package.json +++ b/apps/entropy-tester/package.json @@ -52,7 +52,8 @@ "pino": "catalog:", "prom-client": "^15.1.0", "viem": "catalog:", - "yargs": "^17.5.1" + "yargs": "^17.5.1", + "zod": "catalog:" }, "keywords": [], "author": "", diff --git a/apps/entropy-tester/src/index.ts b/apps/entropy-tester/src/index.ts index fe6718531d..fc5a7d1c14 100644 --- a/apps/entropy-tester/src/index.ts +++ b/apps/entropy-tester/src/index.ts @@ -9,6 +9,7 @@ import { pino } from "pino"; import type { ArgumentsCamelCase, InferredOptionTypes } from "yargs"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; +import { z } from "zod"; type LoadedConfig = { contract: EvmEntropyContract; @@ -39,21 +40,24 @@ function timeToSeconds(timeStr: string): number { } } -type ParsedConfig = { - "chain-id": string; - interval: string; -}; - async function loadConfig(configPath: string): Promise { - const configs = (await import(configPath, { + const configSchema = z.array( + z.strictObject({ + "chain-id": z.string(), + interval: z.string(), + }), + ); + const configContent = (await import(configPath, { with: { type: "json" }, - })) as { default: ParsedConfig[] }; - const loadedConfigs = configs.default.map((config) => { + })) as { default: string }; + const configs = configSchema.parse(configContent.default); + const loadedConfigs = configs.map((config) => { const interval = timeToSeconds(config.interval); const contracts = Object.values(DefaultStore.entropy_contracts).filter( (contract) => contract.chain.getId() == config["chain-id"], ); - if (contracts.length === 0 || !contracts[0]) { + const firstContract = contracts[0]; + if (contracts.length === 0 || !firstContract) { throw new Error( `Can not find the contract for chain ${config["chain-id"]}, check contract manager store.`, ); @@ -63,7 +67,7 @@ async function loadConfig(configPath: string): Promise { `Multiple contracts found for chain ${config["chain-id"]}, check contract manager store.`, ); } - return { contract: contracts[0], interval }; + return { contract: firstContract, interval }; }); return loadedConfigs; } @@ -75,21 +79,24 @@ async function testLatency( ) { const provider = await contract.getDefaultProvider(); const userRandomNumber = contract.generateUserRandomNumber(); - const requestResponse = (await contract.requestRandomness( - userRandomNumber, - provider, - privateKey, - true, // with callback - )) as { - transactionHash: string; - events: { - RequestedWithCallback: { - returnValues: { - sequenceNumber: string; - }; - }; - }; - }; + const requestResponseSchema = z.object({ + transactionHash: z.string(), + events: z.object({ + RequestedWithCallback: z.object({ + returnValues: z.object({ + sequenceNumber: z.string(), + }), + }), + }), + }); + const requestResponse = requestResponseSchema.parse( + await contract.requestRandomness( + userRandomNumber, + provider, + privateKey, + true, // with callback + ), + ); // Read the sequence number for the request from the transaction events. const sequenceNumber = Number.parseInt( requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber, diff --git a/apps/entropy-tester/tsconfig.json b/apps/entropy-tester/tsconfig.json index dfd9bf96d0..fd12d1332d 100644 --- a/apps/entropy-tester/tsconfig.json +++ b/apps/entropy-tester/tsconfig.json @@ -1,5 +1,5 @@ { "extends": "@cprussin/tsconfig/nextjs.json", - "include": ["svg.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "include": ["**/*.ts", "**/*.tsx"], "exclude": ["node_modules"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6993ed0e4..c5fa1d6f77 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -802,10 +802,13 @@ importers: version: 15.1.3 viem: specifier: 'catalog:' - version: 2.24.3(bufferutil@4.0.9)(typescript@5.8.2)(utf-8-validate@6.0.3)(zod@3.24.4) + version: 2.24.3(bufferutil@4.0.9)(typescript@5.8.2)(utf-8-validate@6.0.3)(zod@3.24.2) yargs: specifier: ^17.5.1 version: 17.7.2 + zod: + specifier: 'catalog:' + version: 3.24.2 devDependencies: '@cprussin/eslint-config': specifier: 'catalog:' @@ -53185,23 +53188,6 @@ snapshots: - utf-8-validate - zod - viem@2.24.3(bufferutil@4.0.9)(typescript@5.8.2)(utf-8-validate@6.0.3)(zod@3.24.4): - dependencies: - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.8.2)(zod@3.24.4) - isows: 1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.3)) - ox: 0.6.9(typescript@5.8.2)(zod@3.24.4) - ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.3) - optionalDependencies: - typescript: 5.8.2 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - zod - vlq@1.0.1: {} vlq@2.0.4: {} From 7b805e844547ef275a1b0571fc0cf71d950c3277 Mon Sep 17 00:00:00 2001 From: Amin Moghaddam Date: Tue, 10 Jun 2025 10:25:15 -0700 Subject: [PATCH 10/10] last fix --- apps/entropy-tester/src/index.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/apps/entropy-tester/src/index.ts b/apps/entropy-tester/src/index.ts index fc5a7d1c14..9269ee62e3 100644 --- a/apps/entropy-tester/src/index.ts +++ b/apps/entropy-tester/src/index.ts @@ -6,7 +6,6 @@ import { EvmEntropyContract } from "@pythnetwork/contract-manager/core/contracts import { DefaultStore } from "@pythnetwork/contract-manager/node/store"; import type { Logger } from "pino"; import { pino } from "pino"; -import type { ArgumentsCamelCase, InferredOptionTypes } from "yargs"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; import { z } from "zod"; @@ -158,13 +157,11 @@ export const main = function () { .parserConfiguration({ "parse-numbers": false, }) - .command({ - command: "run", - describe: "run the tester until manually stopped", - builder: RUN_OPTIONS, - handler: async ( - argv: ArgumentsCamelCase>, - ) => { + .command( + "run", + "run the tester until manually stopped", + RUN_OPTIONS, + async (argv) => { const logger = pino(); const configs = await loadConfig(argv.config); if (argv.validate) { @@ -195,7 +192,7 @@ export const main = function () { }); await Promise.all(promises); }, - }) + ) .demandCommand() .help(); };