feat(infra): Command to create endpoint secrets; cleaning up endpoints (#3922)
### Description - clean up references to the single rpc secrets which are redundant as the multi rpc secret includes the single one - add get-rpc-urls script to get secret rpc urls for a given environment and chain - add set-rpc-urls script to: 1) create the secret if it does not exist and add the first secret version or 2) add new secret version to an existing secret and disable the previous version of the secret. The script with test all rpc urls to ensure that they are valid example usage: get-rpc-urls `yarn tsx scripts/secret-rpc-urls/get-rpc-urls.ts -e testnet2 -c fuji` set-rpc-urls `yarn tsx scripts/secret-rpc-urls/set-rpc-urls.ts -e testnet2 -c fuji -r https://api.avax-test.network/ext/bc/C/rpc,https://rpc.ankr.com/avalanche_fuji` <!-- What's included in this PR? --> ### Drive-by changes <!-- Are there any minor or drive-by changes also included? --> - replace `withNetwork` util with `withChain` as we rarely use network internally to reference a chain ### Related issues <!-- - Fixes #[issue number here] --> ### Backward compatibility <!-- Are these changes backward compatible? Are there any infrastructure implications, e.g. changes that would prohibit deploying older commits using this infra tooling? Yes/No --> ### Testing - manual <!-- What kind of testing have these changes undergone? None/Manual/Unit Tests -->pull/3928/head
parent
942aba8e55
commit
36e9a2e783
@ -0,0 +1,26 @@ |
||||
import { |
||||
getSecretRpcEndpoints, |
||||
secretRpcEndpointsExist, |
||||
} from '../../src/agents/index.js'; |
||||
import { getArgs, withChainRequired } from '../agent-utils.js'; |
||||
|
||||
async function main() { |
||||
const { environment, chain } = await withChainRequired(getArgs()).argv; |
||||
const secretExists = await secretRpcEndpointsExist(environment, chain); |
||||
if (!secretExists) { |
||||
console.log( |
||||
`No secret rpc urls found for ${chain} in ${environment} environment`, |
||||
); |
||||
process.exit(0); |
||||
} |
||||
|
||||
const secrets = await getSecretRpcEndpoints(environment, chain); |
||||
console.log(secrets); |
||||
} |
||||
|
||||
main() |
||||
.then() |
||||
.catch((e) => { |
||||
console.error(e); |
||||
process.exit(1); |
||||
}); |
@ -0,0 +1,120 @@ |
||||
import { confirm } from '@inquirer/prompts'; |
||||
import { ethers } from 'ethers'; |
||||
|
||||
import { |
||||
getSecretRpcEndpoints, |
||||
getSecretRpcEndpointsLatestVersionName, |
||||
secretRpcEndpointsExist, |
||||
setSecretRpcEndpoints, |
||||
} from '../../src/agents/index.js'; |
||||
import { disableGCPSecretVersion } from '../../src/utils/gcloud.js'; |
||||
import { isEthereumProtocolChain } from '../../src/utils/utils.js'; |
||||
import { getArgs, withChainRequired, withRpcUrls } from '../agent-utils.js'; |
||||
|
||||
async function testProviders(rpcUrlsArray: string[]): Promise<boolean> { |
||||
let providersSucceeded = true; |
||||
for (const url of rpcUrlsArray) { |
||||
const provider = new ethers.providers.StaticJsonRpcProvider(url); |
||||
try { |
||||
const blockNumber = await provider.getBlockNumber(); |
||||
console.log(`Valid provider for ${url} with block number ${blockNumber}`); |
||||
} catch (e) { |
||||
console.error(`Provider failed: ${url}`); |
||||
providersSucceeded = false; |
||||
} |
||||
} |
||||
|
||||
return providersSucceeded; |
||||
} |
||||
|
||||
async function main() { |
||||
const { environment, chain, rpcUrls } = await withRpcUrls( |
||||
withChainRequired(getArgs()), |
||||
).argv; |
||||
|
||||
const rpcUrlsArray = rpcUrls |
||||
.split(/,\s*/) |
||||
.filter(Boolean) // filter out empty strings
|
||||
.map((url) => url.trim()); |
||||
|
||||
if (!rpcUrlsArray.length) { |
||||
console.error('No rpc urls provided, Exiting.'); |
||||
process.exit(1); |
||||
} |
||||
|
||||
const secretPayload = JSON.stringify(rpcUrlsArray); |
||||
|
||||
const secretExists = await secretRpcEndpointsExist(environment, chain); |
||||
if (!secretExists) { |
||||
console.log( |
||||
`No secret rpc urls found for ${chain} in ${environment} environment\n`, |
||||
); |
||||
} else { |
||||
const currentSecrets = await getSecretRpcEndpoints(environment, chain); |
||||
console.log( |
||||
`Current secrets found for ${chain} in ${environment} environment:\n${JSON.stringify( |
||||
currentSecrets, |
||||
null, |
||||
2, |
||||
)}\n`,
|
||||
); |
||||
} |
||||
|
||||
const confirmedSet = await confirm({ |
||||
message: `Are you sure you want to set the following RPC URLs for ${chain} in ${environment}?\n${secretPayload}\n`, |
||||
}); |
||||
|
||||
if (!confirmedSet) { |
||||
console.log('Exiting without setting secret.'); |
||||
process.exit(0); |
||||
} |
||||
|
||||
if (isEthereumProtocolChain(chain)) { |
||||
console.log('\nTesting providers...'); |
||||
const testPassed = await testProviders(rpcUrlsArray); |
||||
if (!testPassed) { |
||||
console.error('At least one provider failed. Exiting.'); |
||||
process.exit(1); |
||||
} |
||||
|
||||
const confirmedProviders = await confirm({ |
||||
message: `All providers passed. Do you want to continue setting the secret?\n`, |
||||
}); |
||||
|
||||
if (!confirmedProviders) { |
||||
console.log('Exiting without setting secret.'); |
||||
process.exit(0); |
||||
} |
||||
} else { |
||||
console.log( |
||||
'Skipping provider testing as chain is not an Ethereum protocol chain.', |
||||
); |
||||
} |
||||
|
||||
let latestVersionName; |
||||
if (secretExists) { |
||||
latestVersionName = await getSecretRpcEndpointsLatestVersionName( |
||||
environment, |
||||
chain, |
||||
); |
||||
} |
||||
console.log(`Setting secret...`); |
||||
await setSecretRpcEndpoints(environment, chain, secretPayload); |
||||
console.log(`Added secret version!`); |
||||
|
||||
if (latestVersionName) { |
||||
try { |
||||
await disableGCPSecretVersion(latestVersionName); |
||||
console.log(`Disabled previous version of the secret!`); |
||||
} catch (e) { |
||||
console.log(`Could not disable previous version of the secret`); |
||||
} |
||||
} |
||||
} |
||||
|
||||
main() |
||||
.then() |
||||
.catch((e) => { |
||||
console.error(e); |
||||
process.exit(1); |
||||
}); |
Loading…
Reference in new issue