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

Add flags to customize development settings #23

Merged
merged 3 commits into from
Nov 3, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 2 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = {
"import/order": ["error", { alphabetize: { order: "asc", caseInsensitive: true } }],
// Disabled to avoid duplicate diagnostics with node/no-missing-import rule
"import/no-unresolved": "off",
// Disabled because typescript adds support for module import/export to node
"node/no-unsupported-features/es-syntax": ["error", { ignores: ["modules"] }],
// Disabled because typescript adds support for much of this syntax to node
"node/no-unsupported-features/es-syntax": "off",
},
};
10 changes: 10 additions & 0 deletions src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ export abstract class BlockchainCommand extends Command {
options: NetworkNames,
default: "testnet",
}),
abi: Flags.string({
helpGroup: "BASE",
description: "The ABI base directory.",
helpValue: "DIR",
}),
rpc: Flags.string({
helpGroup: "BASE",
description: "Ethereum node endpoint.",
helpValue: "URL",
}),
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/commands/node/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export default class NodeList extends BlockchainCommand {

public async run(): Promise<void> {
const { flags } = await this.parse(NodeList);
const provider = await getProvider(flags.network);
const nodes = await getContract(flags.network, "nodes", provider);
const provider = await getProvider(flags.network, flags.rpc);
const nodes = await getContract(flags.network, flags.abi, "ArmadaNodes", provider);
const operatorId = normalizeHex(flags.operator);
const blockTag = await provider.getBlockNumber();
const results: Result[] = await getAll(flags.page, async (i, n) => {
Expand Down
4 changes: 2 additions & 2 deletions src/commands/node/show.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export default class NodeShow extends BlockchainCommand {

public async run(): Promise<void> {
const { args, flags } = await this.parse(NodeShow);
const provider = await getProvider(flags.network);
const nodes = await getContract(flags.network, "nodes", provider);
const provider = await getProvider(flags.network, flags.rpc);
const nodes = await getContract(flags.network, flags.abi, "ArmadaNodes", provider);
const nodeId = normalizeHex(args.ID);
const record = await nodes.getNode(nodeId);
console.log(normalizeRecord(record));
Expand Down
4 changes: 2 additions & 2 deletions src/commands/project/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export default class ProjectContent extends TransactionCommand {
this.error("URL and SHA must be specified");
}

const signer = await getSigner(flags.network, flags.address, flags.signer);
const projects = await getContract(flags.network, "projects", signer);
const signer = await getSigner(flags.network, flags.rpc, flags.address, flags.signer);
const projects = await getContract(flags.network, flags.abi, "ArmadaProjects", signer);
const projectId = normalizeHex(args.ID);
const bundleSha = normalizeHex(args.SHA);
CliUx.ux.action.start("- Submitting transaction");
Expand Down
4 changes: 2 additions & 2 deletions src/commands/project/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export default class ProjectCreate extends TransactionCommand {
this.error("URL and SHA must be specified together");
}

const signer = await getSigner(flags.network, flags.address, flags.signer);
const projects = await getContract(flags.network, "projects", signer);
const signer = await getSigner(flags.network, flags.rpc, flags.address, flags.signer);
const projects = await getContract(flags.network, flags.abi, "ArmadaProjects", signer);
const owner = flags.owner ? normalizeHex(flags.owner) : await signer.getAddress();
const bundleSha = normalizeHex(args.SHA);
CliUx.ux.action.start("- Submitting transaction");
Expand Down
4 changes: 2 additions & 2 deletions src/commands/project/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export default class ProjectDelete extends TransactionCommand {

public async run(): Promise<void> {
const { args, flags } = await this.parse(ProjectDelete);
const signer = await getSigner(flags.network, flags.address, flags.signer);
const projects = await getContract(flags.network, "projects", signer);
const signer = await getSigner(flags.network, flags.rpc, flags.address, flags.signer);
const projects = await getContract(flags.network, flags.abi, "ArmadaProjects", signer);
const projectId = normalizeHex(args.ID);
CliUx.ux.action.start("- Submitting transaction");
const tx = await projects.deleteProject(projectId);
Expand Down
4 changes: 2 additions & 2 deletions src/commands/project/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export default class ProjectList extends BlockchainCommand {

public async run(): Promise<void> {
const { flags } = await this.parse(ProjectList);
const provider = await getProvider(flags.network);
const projects = await getContract(flags.network, "projects", provider);
const provider = await getProvider(flags.network, flags.rpc);
const projects = await getContract(flags.network, flags.abi, "ArmadaProjects", provider);
const owner = normalizeHex(flags.owner);
const blockTag = await provider.getBlockNumber();
let results: Result[] = await getAll(flags.page, async (i, n) => {
Expand Down
4 changes: 2 additions & 2 deletions src/commands/project/owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export default class ProjectOwner extends TransactionCommand {

public async run(): Promise<void> {
const { args, flags } = await this.parse(ProjectOwner);
const signer = await getSigner(flags.network, flags.address, flags.signer);
const projects = await getContract(flags.network, "projects", signer);
const signer = await getSigner(flags.network, flags.rpc, flags.address, flags.signer);
const projects = await getContract(flags.network, flags.abi, "ArmadaProjects", signer);
const projectId = normalizeHex(args.ID);
CliUx.ux.action.start("- Submitting transaction");
const tx = await projects.setProjectOwner(projectId, args.ADDR);
Expand Down
4 changes: 2 additions & 2 deletions src/commands/project/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export default class ProjectProps extends TransactionCommand {

public async run(): Promise<void> {
const { args, flags } = await this.parse(ProjectProps);
const signer = await getSigner(flags.network, flags.address, flags.signer);
const projects = await getContract(flags.network, "projects", signer);
const signer = await getSigner(flags.network, flags.rpc, flags.address, flags.signer);
const projects = await getContract(flags.network, flags.abi, "ArmadaProjects", signer);
const projectId = normalizeHex(args.ID);
CliUx.ux.action.start("- Submitting transaction");
const tx = await projects.setProjectProps(projectId, args.NAME, args.EMAIL);
Expand Down
4 changes: 2 additions & 2 deletions src/commands/project/show.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export default class ProjectShow extends BlockchainCommand {

public async run(): Promise<void> {
const { args, flags } = await this.parse(ProjectShow);
const provider = await getProvider(flags.network);
const projects = await getContract(flags.network, "projects", provider);
const provider = await getProvider(flags.network, flags.rpc);
const projects = await getContract(flags.network, flags.abi, "ArmadaProjects", provider);
const projectId = normalizeHex(args.ID);
const record = await projects.getProject(projectId);
console.log(normalizeRecord(record));
Expand Down
4 changes: 2 additions & 2 deletions src/commands/reservation/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export default class ReservationCreate extends TransactionCommand {
.slice(1) // Skip ID
.map((id) => normalizeHex(id));

const signer = await getSigner(flags.network, flags.address, flags.signer);
const reservations = await getContract(flags.network, "reservations", signer);
const signer = await getSigner(flags.network, flags.rpc, flags.address, flags.signer);
const reservations = await getContract(flags.network, flags.abi, "ArmadaReservations", signer);
const projectId = normalizeHex(args.ID);
const prices = nodeIds.map(() => parseUnits("1", 18));
CliUx.ux.action.start("- Submitting transaction");
Expand Down
4 changes: 2 additions & 2 deletions src/commands/reservation/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export default class ReservationDelete extends TransactionCommand {
.slice(1) // Skip ID
.map((id) => normalizeHex(id));

const signer = await getSigner(flags.network, flags.address, flags.signer);
const reservations = await getContract(flags.network, "reservations", signer);
const signer = await getSigner(flags.network, flags.rpc, flags.address, flags.signer);
const reservations = await getContract(flags.network, flags.abi, "ArmadaReservations", signer);
const projectId = normalizeHex(args.ID);
CliUx.ux.action.start("- Submitting transaction");
const slot = { last: false, next: true };
Expand Down
4 changes: 2 additions & 2 deletions src/commands/reservation/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export default class ReservationList extends BlockchainCommand {

public async run(): Promise<void> {
const { args, flags } = await this.parse(ReservationList);
const provider = await getProvider(flags.network);
const reservations = await getContract(flags.network, "reservations", provider);
const provider = await getProvider(flags.network, flags.rpc);
const reservations = await getContract(flags.network, flags.abi, "ArmadaReservations", provider);
const projectId = normalizeHex(args.ID);
const blockTag = await provider.getBlockNumber();
const results: Result[] = await getAll(flags.page, async (i, n) => {
Expand Down
26 changes: 26 additions & 0 deletions src/contracts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import fs from "fs";
import type { ContractInterface } from "ethers";

// These imports are necessary to pull these files into dist/
import "../abi/staging/ArmadaNodes.json";
import "../abi/staging/ArmadaProjects.json";
import "../abi/staging/ArmadaReservations.json";
import "../abi/testnet/ArmadaNodes.json";
import "../abi/testnet/ArmadaProjects.json";
import "../abi/testnet/ArmadaReservations.json";

export type ContractName = "ArmadaNodes" | "ArmadaProjects" | "ArmadaReservations";

export interface ContractInfo {
address: string;
abi: ContractInterface;
}

export async function loadAbi(path: string): Promise<ContractInfo> {
const importPrefix = "import://";
if (path.startsWith(importPrefix)) {
return await import(path.slice(importPrefix.length));
} else {
return JSON.parse(fs.readFileSync(path).toString());
}
}
16 changes: 11 additions & 5 deletions src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import path from "path";
import type { Provider, TransactionReceipt } from "@ethersproject/abstract-provider";
import { BigNumber, Contract, ethers, Signer, type Transaction } from "ethers";
import { formatUnits, Result } from "ethers/lib/utils";
import inquirer from "inquirer";
import keytar from "keytar";
import { ContractName, loadAbi } from "./contracts";
import { listWallets, loadWallet } from "./keystore";
import { LedgerSigner } from "./ledger";
import { ContractName, Contracts, NetworkName, Networks } from "./networks";
import { NetworkName, Networks } from "./networks";

export type SignerType = "keystore" | "ledger";
export const SignerTypes: SignerType[] = ["keystore", "ledger"];
Expand Down Expand Up @@ -56,18 +58,19 @@ function normalizeBigNumber(n: BigNumber): string {
}
}

export async function getProvider(network: NetworkName): Promise<Provider> {
const url = Networks[network].url;
export async function getProvider(network: NetworkName, rpcUrl: string | undefined): Promise<Provider> {
const url = rpcUrl ?? Networks[network].url;
const provider = new ethers.providers.JsonRpcProvider(url);
return provider;
}

export async function getSigner(
network: NetworkName,
rpcUrl: string | undefined,
address: string | undefined,
signer: SignerType
): Promise<Signer> {
const url = Networks[network].url;
const url = rpcUrl ?? Networks[network].url;
const provider = new ethers.providers.JsonRpcProvider(url);

let wallet: Signer;
Expand Down Expand Up @@ -117,10 +120,13 @@ export async function getSigner(

export async function getContract(
network: NetworkName,
abiDir: string | undefined,
contract: ContractName,
signerOrProvider: Signer | ethers.providers.Provider
): Promise<Contract> {
const abi = Contracts[network][contract];
const dir = abiDir ?? Networks[network].abi;
const file = path.join(dir, network, contract + ".json");
const abi = await loadAbi(file);
if (signerOrProvider instanceof Signer) {
const signer = signerOrProvider;
const contract = new Contract(abi.address, abi.abi, signer.provider);
Expand Down
36 changes: 7 additions & 29 deletions src/networks.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,22 @@
import type { ContractInterface } from "ethers";

import StagingNodesDeployment from "../abi/staging/ArmadaNodes.json";
import StagingProjectsDeployment from "../abi/staging/ArmadaProjects.json";
import StagingReservationsDeployment from "../abi/staging/ArmadaReservations.json";

import TestnetNodesDeployment from "../abi/testnet/ArmadaNodes.json";
import TestnetProjectsDeployment from "../abi/testnet/ArmadaProjects.json";
import TestnetReservationsDeployment from "../abi/testnet/ArmadaReservations.json";

export type NetworkName = "testnet" | "staging";
export type ContractName = "nodes" | "projects" | "reservations";
export type NetworkName = "testnet" | "staging" | "localhost";

export interface NetworkInfo {
url: string;
}

export interface ContractInfo {
address: string;
abi: ContractInterface;
abi: string;
}

export const Networks: Record<NetworkName, NetworkInfo> = {
testnet: {
url: "https://rpc.ankr.com/eth_goerli",
abi: "import://../abi",
},
staging: {
url: "https://rpc.ankr.com/eth_goerli",
abi: "import://../abi",
},
};

export const Contracts: Record<NetworkName, Record<ContractName, ContractInfo>> = {
testnet: {
nodes: TestnetNodesDeployment,
projects: TestnetProjectsDeployment,
reservations: TestnetReservationsDeployment,
},
staging: {
nodes: StagingNodesDeployment,
projects: StagingProjectsDeployment,
reservations: StagingReservationsDeployment,
localhost: {
url: "http://localhost:8545",
abi: "../armada-contracts/deployments",
},
};

Expand Down