diff --git a/.env.sample b/.env.sample index ff25bcb8..13be1314 100644 --- a/.env.sample +++ b/.env.sample @@ -1 +1,2 @@ MNEMONIC=my hot wallet seed words here that has minimal funds +ONLY_OPERATORS=false \ No newline at end of file diff --git a/.gitignore b/.gitignore index a3492741..edbecfec 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ npm-debug.log* .vim .iml +/.idea \ No newline at end of file diff --git a/scripts/autostake.mjs b/scripts/autostake.mjs index b9af8a6c..c0b4dca6 100644 --- a/scripts/autostake.mjs +++ b/scripts/autostake.mjs @@ -3,6 +3,7 @@ import Autostake from "../src/autostake/index.mjs"; const mnemonic = process.env.MNEMONIC const networksOverridePath = process.env.NETWORKS_OVERRIDE_PATH || 'src/networks.local.json' +const onlyOperators = ( process.env.ONLY_OPERATORS || "false") === "true" const autostake = new Autostake(mnemonic); const networkNames = process.argv.slice(2, process.argv.length) -autostake.run(networkNames, networksOverridePath) +autostake.run(networkNames, networksOverridePath,onlyOperators) diff --git a/scripts/dryrun.mjs b/scripts/dryrun.mjs index cae6baf8..d9eb46ff 100644 --- a/scripts/dryrun.mjs +++ b/scripts/dryrun.mjs @@ -4,5 +4,7 @@ import Autostake from "../src/autostake/index.mjs"; const mnemonic = process.env.MNEMONIC const networksOverridePath = process.env.NETWORKS_OVERRIDE_PATH || 'src/networks.local.json' const autostake = new Autostake(mnemonic, { dryRun: true }); +const onlyOperators = ( process.env.ONLY_OPERATORS || "false") === "true" + const networkName = process.argv.slice(2, process.argv.length) -autostake.run(networkName, networksOverridePath) +autostake.run(networkName, networksOverridePath,onlyOperators) diff --git a/src/autostake/Health.mjs b/src/autostake/Health.mjs index 3521ca46..589cd072 100644 --- a/src/autostake/Health.mjs +++ b/src/autostake/Health.mjs @@ -24,8 +24,11 @@ class Health { } } - started(...args) { - timeStamp(...args) + started(onlyOperators,...args) { + if (!onlyOperators) { + timeStamp(...args) + } + if (this.uuid) timeStamp('Starting health', [this.address, this.uuid].join('/')) return this.ping('start', [args.join(' ')]) } diff --git a/src/autostake/index.mjs b/src/autostake/index.mjs index 02bb326e..e23ef44e 100644 --- a/src/autostake/index.mjs +++ b/src/autostake/index.mjs @@ -24,7 +24,8 @@ export default function Autostake(mnemonic, opts) { process.exit() } - async function run(networkNames, networksOverridePath) { + async function run(networkNames, networksOverridePath,onlyOperators) { + const networks = getNetworksData(networksOverridePath) for (const name of networkNames) { if (name && !networks.map(el => el.name).includes(name)){ @@ -38,8 +39,9 @@ export default function Autostake(mnemonic, opts) { if (data.enabled === false) return const health = new Health(data.healthCheck, { dryRun: opts.dryRun, networkName: data.name }) - health.started('⚛') - const results = await runWithRetry(data, health) + health.started(onlyOperators,'⚛') + + const results = await runWithRetry(data, health,undefined,undefined,onlyOperators) const { success, skipped } = results[results.length - 1] || {} if(!skipped && !failed){ health.log(`Autostake ${success ? 'completed' : 'failed'} after ${results.length} attempt(s)`) @@ -48,8 +50,12 @@ export default function Autostake(mnemonic, opts) { logSummary(health, networkRunner, error) }) } - if (success || skipped) { + if (success ) { return health.success('Autostake finished') + }else if ( skipped) { + if (!onlyOperators) { + return health.success('Autostake skipped') + } } else { return health.failed('Autostake failed') } @@ -58,14 +64,15 @@ export default function Autostake(mnemonic, opts) { await executeSync(calls, 1) } - async function runWithRetry(data, health, retries, runners) { + async function runWithRetry(data, health, retries, runners,onlyOperators) { retries = retries || 0 runners = runners || [] const maxRetries = data.autostake?.retries ?? 2 let { failedAddresses } = runners[runners.length - 1] || {} let networkRunner, error try { - networkRunner = await getNetworkRunner(data) + + networkRunner = await getNetworkRunner(data,onlyOperators) if (!networkRunner){ runners.push({ skipped: true }) return runners @@ -83,7 +90,8 @@ export default function Autostake(mnemonic, opts) { if (!networkRunner?.didSucceed() && !networkRunner?.forceFail && retries < maxRetries && !failed) { await logResults(health, networkRunner, error, `Failed attempt ${retries + 1}/${maxRetries + 1}, retrying in 30 seconds...`) await new Promise(r => setTimeout(r, 30 * 1000)); - return await runWithRetry(data, health, retries + 1, runners) + + return await runWithRetry(data, health, retries + 1, runners,onlyOperators) } await logResults(health, networkRunner, error) return runners @@ -110,27 +118,36 @@ export default function Autostake(mnemonic, opts) { if (error) health.log(`Failed with error: ${error}`) } - async function getNetworkRunner(data) { + async function getNetworkRunner(data,onlyOperators) { const network = new Network(data) - let config = { ...opts } + let config = {...opts} try { await network.load() - } catch(e) { - if(e.response.status === 404){ + } catch (e) { + if (e.response.status === 404) { failed = true throw new Error(`${network.name} not found in Chain Registry`) } throw new Error(`Unable to load network data for ${network.name}`) } - timeStamp('Loaded', network.prettyName) + if (!onlyOperators) { + timeStamp('Loaded', network.prettyName) + } + const {signer, slip44} = await getSigner(network,onlyOperators) - const { signer, slip44 } = await getSigner(network) const wallet = new Wallet(network, signer) const botAddress = await wallet.getAddress() - + if (onlyOperators) { + if (!network.getOperatorByBotAddress(botAddress)) { + return + } else { + timeStamp('Loaded', network.prettyName) + } + } timeStamp('Bot address is', botAddress) + if (network.slip44 && network.slip44 !== slip44) { timeStamp("!! You are not using the preferred derivation path !!") timeStamp("!! You should switch to the correct path unless you have grants. Check the README !!") @@ -167,10 +184,14 @@ export default function Autostake(mnemonic, opts) { ) } - async function getSigner(network) { + async function getSigner(network,onlyOperators) { let slip44 if (network.data.autostake?.correctSlip44 || network.slip44 === 60) { - if (network.slip44 === 60) timeStamp('Found ETH coin type') + if (network.slip44 === 60) { + if (!onlyOperators) { + timeStamp('Found ETH coin type') + } + } slip44 = network.slip44 || 118 } else { slip44 = network.data.autostake?.slip44 || 118 @@ -182,7 +203,7 @@ export default function Autostake(mnemonic, opts) { Slip10RawIndex.normal(0), Slip10RawIndex.normal(0), ]; - slip44 != 118 && timeStamp('Using HD Path', pathToString(hdPath)) + if (slip44 !== 118 && !onlyOperators) { timeStamp('Using HD Path', pathToString(hdPath))} let signer = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: network.prefix,