Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: script for getting key material #4829

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions typescript/infra/scripts/agent-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,8 @@ export function withProtocol<T>(args: Argv<T>) {

export function withAgentRole<T>(args: Argv<T>) {
return args
.describe('role', 'agent roles')
.array('role')
.coerce('role', (role: string[]): Role[] => role.map(assertRole))
.describe('role', 'agent role')
.coerce('role', (role: string): Role => assertRole(role))
.demandOption('role')
.alias('r', 'role');
}
Expand All @@ -202,11 +201,16 @@ export function withAgentRoles<T>(args: Argv<T>) {
.coerce('roles', (role: string[]): Role[] => role.map(assertRole))
.choices('roles', Object.values(Role))
// Ensure roles are unique
.coerce('roles', (roles: string[]) => Array.from(new Set(roles)))
.coerce('roles', (roles: Role[]) => Array.from(new Set(roles)))
.alias('r', 'roles')
.alias('role', 'roles')
);
}

export function withAgentRolesRequired<T>(args: Argv<T>) {
return withAgentRoles(args).demandOption('roles');
}

export function withKeyRoleAndChain<T>(args: Argv<T>) {
return args
.describe('role', 'key role')
Expand Down
10 changes: 6 additions & 4 deletions typescript/infra/scripts/agents/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { HelmCommand } from '../../src/utils/helm.js';
import {
assertCorrectKubeContext,
getArgs,
withAgentRole,
withAgentRolesRequired,
withChains,
withContext,
} from '../agent-utils.js';
Expand Down Expand Up @@ -70,21 +70,23 @@ export class AgentCli {

protected async init() {
if (this.initialized) return;
const argv = await withChains(withAgentRole(withContext(getArgs())))
const argv = await withChains(
withAgentRolesRequired(withContext(getArgs())),
)
.describe('dry-run', 'Run through the steps without making any changes')
.boolean('dry-run').argv;

if (
argv.chains &&
argv.chains.length > 0 &&
!argv.role.includes(Role.Validator)
!argv.roles.includes(Role.Validator)
) {
console.warn('Chain argument applies to validator role only. Ignoring.');
}

const { envConfig, agentConfig } = await getConfigsBasedOnArgs(argv);
await assertCorrectKubeContext(envConfig);
this.roles = argv.role;
this.roles = argv.roles;
this.envConfig = envConfig;
this.agentConfig = agentConfig;
this.dryRun = argv.dryRun || false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { createAgentKeysIfNotExists } from '../src/agents/key-utils.js';

import { getAgentConfigsBasedOnArgs } from './agent-utils.js';
import { createAgentKeysIfNotExists } from '../../src/agents/key-utils.js';
import { getAgentConfigsBasedOnArgs } from '../agent-utils.js';

async function main() {
const { agentConfig } = await getAgentConfigsBasedOnArgs();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { deleteAgentKeys } from '../src/agents/key-utils.js';

import { getAgentConfigsBasedOnArgs } from './agent-utils.js';
import { deleteAgentKeys } from '../../src/agents/key-utils.js';
import { getAgentConfigsBasedOnArgs } from '../agent-utils.js';

async function main() {
const { agentConfig } = await getAgentConfigsBasedOnArgs();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { getAllCloudAgentKeys } from '../src/agents/key-utils.js';

import { getArgs, withContext, withProtocol } from './agent-utils.js';
import { getConfigsBasedOnArgs } from './core-utils.js';
import { getAllCloudAgentKeys } from '../../src/agents/key-utils.js';
import { getArgs, withContext, withProtocol } from '../agent-utils.js';
import { getConfigsBasedOnArgs } from '../core-utils.js';

async function main() {
const argv = await withProtocol(withContext(getArgs())).argv;
Expand Down
38 changes: 38 additions & 0 deletions typescript/infra/scripts/keys/get-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { getCloudAgentKey } from '../../src/agents/key-utils.js';
import {
getArgs,
withAgentRole,
withContext,
withProtocol,
} from '../agent-utils.js';
import { getConfigsBasedOnArgs } from '../core-utils.js';

async function main() {
const argv = await withAgentRole(withContext(getArgs())).argv;

const { agentConfig } = await getConfigsBasedOnArgs(argv);

// As a (very rudimentary) security precaution, we don't print the private key directly to
// the console if this script is ran directly.
// We only write the private key to the console if it is not a tty, e.g. if
// this is being called in a subshell or piped to another command.
//
// E.g. this will print the private key:
// $ echo `yarn tsx infra/scripts/keys/get-key.ts -e mainnet3 --role deployer`
// or this too:
// $ echo $(yarn tsx infra/scripts/keys/get-key.ts -e mainnet3 --role deployer)
// and even this:
// $ yarn tsx infra/scripts/keys/get-key.ts -e mainnet3 --role deployer | cat
//
// But this will not print the private key directly to the shell:
// $ yarn tsx infra/scripts/keys/get-key.ts -e mainnet3 --role deployer
if (process.stdout.isTTY) {
console.log('<omitted in tty, use in subshell>');
} else {
const key = getCloudAgentKey(agentConfig, argv.role);
await key.fetch();
console.log(key.privateKey);
}
}

main().catch(console.error);
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { AccountConfig, InterchainAccount } from '@hyperlane-xyz/sdk';
import { Address, eqAddress, isZeroishAddress } from '@hyperlane-xyz/utils';

import { isEthereumProtocolChain } from '../src/utils/utils.js';

import { getArgs as getEnvArgs, withChains } from './agent-utils.js';
import { getEnvironmentConfig, getHyperlaneCore } from './core-utils.js';
import { isEthereumProtocolChain } from '../../src/utils/utils.js';
import { getArgs as getEnvArgs, withChains } from '../agent-utils.js';
import { getEnvironmentConfig, getHyperlaneCore } from '../core-utils.js';

function getArgs() {
return withChains(getEnvArgs())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
getArgs,
withContext,
withKeyRoleAndChain,
} from './agent-utils.js';
} from '../agent-utils.js';

async function rotateKey() {
const argv = await withContext(withKeyRoleAndChain(getArgs())).argv;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
getArgs,
withContext,
withKeyRoleAndChain,
} from './agent-utils.js';
} from '../agent-utils.js';

async function rotateKey() {
const argv = await withKeyRoleAndChain(withContext(getArgs())).argv;
Expand Down