Skip to content

Commit

Permalink
Merge pull request #23 from armada-network/abi-rpc
Browse files Browse the repository at this point in the history
Add flags to customize development settings
  • Loading branch information
the-masthead authored Nov 3, 2022
2 parents 536d1cb + 07a5203 commit 6a86f86
Show file tree
Hide file tree
Showing 17 changed files with 81 additions and 78 deletions.
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",
}),
};

static enableJsonFlag = true;
Expand Down
7 changes: 3 additions & 4 deletions src/commands/node/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@ export default class NodeList extends BlockchainCommand {

public async run(): Promise<Record<string, unknown>[]> {
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) => {
return await nodes.getNodes(operatorId, flags.topology, i, n, { blockTag });
});
const records = results.slice(flags.skip, flags.skip + flags.size);

const records = results.slice(flags.skip, flags.skip + flags.size);
const output = normalizeRecords(records);
if (!flags.json) console.log(output);
return output;
Expand Down
6 changes: 2 additions & 4 deletions src/commands/node/show.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ export default class NodeShow extends BlockchainCommand {

public async run(): Promise<Record<string, unknown>> {
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);

const output = normalizeRecord(record);
if (!flags.json) console.log(output);
return output;
Expand Down
5 changes: 2 additions & 3 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 All @@ -35,7 +35,6 @@ export default class ProjectContent extends TransactionCommand {
const receipt = await tx.wait();
CliUx.ux.action.stop("done");
const event = await decodeEvent(receipt, projects, "ProjectContentChanged");

const output = normalizeRecord(event);
if (!flags.json) console.log(output);
return output;
Expand Down
5 changes: 2 additions & 3 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 All @@ -35,7 +35,6 @@ export default class ProjectCreate extends TransactionCommand {
const receipt = await tx.wait();
CliUx.ux.action.stop("done");
const event = await decodeEvent(receipt, projects, "ProjectCreated");

const output = normalizeRecord(event);
if (!flags.json) console.log(output);
return output;
Expand Down
6 changes: 2 additions & 4 deletions src/commands/project/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ export default class ProjectDelete extends TransactionCommand {

public async run(): Promise<Record<string, unknown>> {
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 All @@ -23,7 +22,6 @@ export default class ProjectDelete extends TransactionCommand {
const receipt = await tx.wait();
CliUx.ux.action.stop("done");
const event = await decodeEvent(receipt, projects, "ProjectDeleted");

const output = normalizeRecord(event);
if (!flags.json) console.log(output);
return output;
Expand Down
5 changes: 2 additions & 3 deletions src/commands/project/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ export default class ProjectList extends BlockchainCommand {

public async run(): Promise<Record<string, unknown>[]> {
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
6 changes: 2 additions & 4 deletions src/commands/project/owner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ export default class ProjectOwner extends TransactionCommand {

public async run(): Promise<Record<string, unknown>> {
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 All @@ -27,7 +26,6 @@ export default class ProjectOwner extends TransactionCommand {
const receipt = await tx.wait();
CliUx.ux.action.stop("done");
const event = await decodeEvent(receipt, projects, "ProjectOwnerChanged");

const output = normalizeRecord(event);
if (!flags.json) console.log(output);
return output;
Expand Down
6 changes: 2 additions & 4 deletions src/commands/project/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ export default class ProjectProps extends TransactionCommand {

public async run(): Promise<Record<string, unknown>> {
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 All @@ -27,7 +26,6 @@ export default class ProjectProps extends TransactionCommand {
const receipt = await tx.wait();
CliUx.ux.action.stop("done");
const event = await decodeEvent(receipt, projects, "ProjectPropsChanged");

const output = normalizeRecord(event);
if (!flags.json) console.log(output);
return output;
Expand Down
6 changes: 2 additions & 4 deletions src/commands/project/show.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ export default class ProjectShow extends BlockchainCommand {

public async run(): Promise<Record<string, unknown>> {
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);

const output = normalizeRecord(record);
if (!flags.json) console.log(output);
return output;
Expand Down
5 changes: 2 additions & 3 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 All @@ -44,7 +44,6 @@ export default class ReservationCreate extends TransactionCommand {
const receipt = await tx.wait();
CliUx.ux.action.stop("done");
const events = await decodeEvents(receipt, reservations, "ReservationCreated");

const output = normalizeRecords(events);
if (!flags.json) console.log(output);
return output;
Expand Down
5 changes: 2 additions & 3 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 All @@ -35,7 +35,6 @@ export default class ReservationDelete extends TransactionCommand {
const receipt = await tx.wait();
CliUx.ux.action.stop("done");
const events = await decodeEvents(receipt, reservations, "ReservationDeleted");

const output = normalizeRecords(events);
if (!flags.json) console.log(output);
return output;
Expand Down
5 changes: 2 additions & 3 deletions src/commands/reservation/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ export default class ReservationList extends BlockchainCommand {

public async run(): Promise<Record<string, unknown>[]> {
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 @@ -63,18 +65,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 @@ -124,10 +127,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

0 comments on commit 6a86f86

Please sign in to comment.