Skip to content

Commit

Permalink
[cli] Checks on cmds + support use of signer
Browse files Browse the repository at this point in the history
  • Loading branch information
mcortesi committed Oct 24, 2019
1 parent f88651d commit c4501ec
Show file tree
Hide file tree
Showing 35 changed files with 882 additions and 141 deletions.
1 change: 1 addition & 0 deletions packages/cli/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
node_modules
oclif.manifest.json
src/generated
.devchain/
3 changes: 3 additions & 0 deletions packages/cli/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['<rootDir>/src/**/?(*.)+(spec|test).ts?(x)'],
setupFilesAfterEnv: ['<rootDir>/src/test-utils/matchers.ts'],
globalSetup: '<rootDir>/src/test-utils/ganache.setup.ts',
globalTeardown: '<rootDir>/src/test-utils/ganache.teardown.ts',
}
2 changes: 2 additions & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
"docs": "yarn oclif-dev readme --multi --dir=../docs/command-line-interface && yarn prettier ../docs/command-line-interface/*.md --write",
"lint": "tslint -c tslint.json --project tsconfig.json",
"prepack": "yarn run build && oclif-dev manifest && oclif-dev readme",
"test:reset": "yarn --cwd ../protocol devchain generate .devchain",
"test:livechain": "yarn --cwd ../protocol devchain run .devchain",
"test": "TZ=UTC jest"
},
"dependencies": {
Expand Down
19 changes: 19 additions & 0 deletions packages/cli/src/commands/lockedgold/authorize.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Web3 from 'web3'
import { testWithGanache } from '../../test-utils/ganache-test'
import Authorize from './authorize'
import Register from './register'

testWithGanache('account:authorize cmd', (web3: Web3) => {
test('can authorize account', async () => {
const accounts = await web3.eth.getAccounts()
await Register.run(['--from', accounts[0]])
await Authorize.run(['--from', accounts[0], '--role', 'validator', '--to', accounts[1]])
})

test('fails if from is not an account', async () => {
const accounts = await web3.eth.getAccounts()
await expect(
Authorize.run(['--from', accounts[0], '--role', 'validator', '--to', accounts[1]])
).rejects.toThrow()
})
})
6 changes: 6 additions & 0 deletions packages/cli/src/commands/lockedgold/authorize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { flags } from '@oclif/command'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

Expand Down Expand Up @@ -38,6 +39,11 @@ export default class Authorize extends BaseCommand {

this.kit.defaultAccount = res.flags.from
const lockedGold = await this.kit.contracts.getLockedGold()

await newCheckBuilder(this)
.isAccount(res.flags.from)
.runChecks()

let tx: any
if (res.flags.role === 'voter') {
tx = await lockedGold.authorizeVoter(res.flags.from, res.flags.to)
Expand Down
14 changes: 8 additions & 6 deletions packages/cli/src/commands/lockedgold/lock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Address } from '@celo/utils/lib/address'
import { flags } from '@oclif/command'
import BigNumber from 'bignumber.js'
import { BaseCommand } from '../../base'
import { displaySendTx, failWith } from '../../utils/cli'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'
import { LockedGoldArgs } from '../../utils/lockedgold'

Expand All @@ -26,14 +27,15 @@ export default class Lock extends BaseCommand {
const address: Address = res.flags.from

this.kit.defaultAccount = address
const lockedGold = await this.kit.contracts.getLockedGold()

const value = new BigNumber(res.flags.value)

if (!value.gt(new BigNumber(0))) {
failWith(`Provided value must be greater than zero => [${value.toString()}]`)
}
await newCheckBuilder(this)
.addCheck(`Value [${value.toString()}] is >= 0`, () => value.gt(0))
.isAccount(address)
.hasEnoughGold(address, value)
.runChecks()

const lockedGold = await this.kit.contracts.getLockedGold()
const tx = lockedGold.lock()
await displaySendTx('lock', tx, { value: value.toString() })
}
Expand Down
17 changes: 17 additions & 0 deletions packages/cli/src/commands/lockedgold/register.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Web3 from 'web3'
import { testWithGanache } from '../../test-utils/ganache-test'
import Register from './register'

testWithGanache('account:register cmd', (web3: Web3) => {
test('can register account', async () => {
const accounts = await web3.eth.getAccounts()

await Register.run(['--from', accounts[0]])
})

test('fails if from is missing', async () => {
// const accounts = await web3.eth.getAccounts()

await expect(Register.run()).rejects.toThrow('Missing required flag')
})
})
5 changes: 5 additions & 0 deletions packages/cli/src/commands/lockedgold/register.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

Expand All @@ -18,6 +19,10 @@ export default class Register extends BaseCommand {
const res = this.parse(Register)
this.kit.defaultAccount = res.flags.from
const lockedGold = await this.kit.contracts.getLockedGold()

await newCheckBuilder(this)
.isNotAccount(res.flags.from)
.runChecks()
await displaySendTx('register', lockedGold.createAccount())
}
}
7 changes: 6 additions & 1 deletion packages/cli/src/commands/lockedgold/show.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { printValueMapRecursive } from '../../utils/cli'
import { Args } from '../../utils/command'

Expand All @@ -14,10 +15,14 @@ export default class Show extends BaseCommand {
static examples = ['show 0x5409ed021d9299bf6814279a6a1411a7e866a631']

async run() {
// tslint:disable-next-line
const { args } = this.parse(Show)

const lockedGold = await this.kit.contracts.getLockedGold()

await newCheckBuilder(this)
.isAccount(args.account)
.runChecks()

printValueMapRecursive(await lockedGold.getAccountSummary(args.account))
}
}
6 changes: 6 additions & 0 deletions packages/cli/src/commands/lockedgold/unlock.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { flags } from '@oclif/command'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'
import { LockedGoldArgs } from '../../utils/lockedgold'
Expand All @@ -21,6 +22,11 @@ export default class Unlock extends BaseCommand {
const res = this.parse(Unlock)
this.kit.defaultAccount = res.flags.from
const lockedgold = await this.kit.contracts.getLockedGold()

await newCheckBuilder(this)
.isAccount(res.flags.from)
.runChecks()

await displaySendTx('unlock', lockedgold.unlock(res.flags.value))
}
}
7 changes: 6 additions & 1 deletion packages/cli/src/commands/lockedgold/withdraw.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

Expand All @@ -17,8 +18,12 @@ export default class Withdraw extends BaseCommand {
const { flags } = this.parse(Withdraw)
this.kit.defaultAccount = flags.from
const lockedgold = await this.kit.contracts.getLockedGold()
const currentTime = Math.round(new Date().getTime() / 1000)

await newCheckBuilder(this)
.isAccount(flags.from)
.runChecks()

const currentTime = Math.round(new Date().getTime() / 1000)
while (true) {
let madeWithdrawal = false
const pendingWithdrawals = await lockedgold.getPendingWithdrawals(flags.from)
Expand Down
9 changes: 9 additions & 0 deletions packages/cli/src/commands/validator/affiliate.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IArg } from '@oclif/parser/lib/args'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Args, Flags } from '../../utils/command'

Expand All @@ -23,6 +24,14 @@ export default class ValidatorAffiliate extends BaseCommand {
const res = this.parse(ValidatorAffiliate)
this.kit.defaultAccount = res.flags.from
const validators = await this.kit.contracts.getValidators()

await newCheckBuilder(this, res.flags.from)
.isSignerOrAccount()
.canSignValidatorTxs()
.signerAccountIsValidator()
.isValidatorGroup(res.args.groupAddress)
.runChecks()

await displaySendTx('affiliate', validators.affiliate(res.args.groupAddress))
}
}
8 changes: 8 additions & 0 deletions packages/cli/src/commands/validator/deaffiliate.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

Expand All @@ -16,6 +17,13 @@ export default class ValidatorDeAffiliate extends BaseCommand {
const res = this.parse(ValidatorDeAffiliate)
this.kit.defaultAccount = res.flags.from
const validators = await this.kit.contracts.getValidators()

await newCheckBuilder(this, res.flags.from)
.isSignerOrAccount()
.canSignValidatorTxs()
.signerAccountIsValidator()
.runChecks()

await displaySendTx('deaffiliate', validators.deaffiliate())
}
}
24 changes: 11 additions & 13 deletions packages/cli/src/commands/validator/deregister.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Address } from '@celo/contractkit'
import { IArg } from '@oclif/parser/lib/args'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Args, Flags } from '../../utils/command'
import { Flags } from '../../utils/command'

export default class ValidatorDeregister extends BaseCommand {
static description = 'Deregister a Validator'
Expand All @@ -12,22 +11,21 @@ export default class ValidatorDeregister extends BaseCommand {
from: Flags.address({ required: true, description: "Signer or Validator's address" }),
}

static args: IArg[] = [
Args.address('validatorAddress', { description: "Validator's address", required: false }),
]

static examples = [
'deregister --from 0x47e172f6cfb6c7d01c1574fa3e2be7cc73269d95',
'deregister --from 0x47e172f6cfb6c7d01c1574fa3e2be7cc73269d95 0x97f7333c51897469e8d98e7af8653aab468050a3',
]
static examples = ['deregister --from 0x47e172f6cfb6c7d01c1574fa3e2be7cc73269d95']

async run() {
const res = this.parse(ValidatorDeregister)

this.kit.defaultAccount = res.flags.from
const validatorAddress: Address = res.args.validatorAddress || res.args.from
const validators = await this.kit.contracts.getValidators()

await displaySendTx('deregister', await validators.deregisterValidator(validatorAddress))
await newCheckBuilder(this, res.flags.from)
.isSignerOrAccount()
.canSignValidatorTxs()
.signerAccountIsValidator()
.runChecks()

const validator = await validators.signerToAccount(res.flags.from)
await displaySendTx('deregister', await validators.deregisterValidator(validator))
}
}
9 changes: 9 additions & 0 deletions packages/cli/src/commands/validator/register.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { flags } from '@oclif/command'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'
import { getPubKeyFromAddrAndWeb3 } from '../../utils/helpers'
Expand All @@ -20,8 +21,16 @@ export default class ValidatorRegister extends BaseCommand {
async run() {
const res = this.parse(ValidatorRegister)
this.kit.defaultAccount = res.flags.from

const validators = await this.kit.contracts.getValidators()
const attestations = await this.kit.contracts.getAttestations()

await newCheckBuilder(this, res.flags.from)
.isSignerOrAccount()
.canSignValidatorTxs()
.signerMeetsValidatorBalanceRequirements()
.runChecks()

await displaySendTx(
'registerValidator',
validators.registerValidator(res.flags.name, res.flags.publicKey as any)
Expand Down
22 changes: 22 additions & 0 deletions packages/cli/src/commands/validator/requirements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { BaseCommand } from '../../base'
import { printValueMap } from '../../utils/cli'

export default class ValidatorRequirements extends BaseCommand {
static description = 'Get Requirements for Validators'

static flags = {
...BaseCommand.flags,
}

static examples = ['requirements']

async run() {
this.parse(ValidatorRequirements)

const validators = await this.kit.contracts.getValidators()

const requirements = await validators.getBalanceRequirements()

printValueMap(requirements)
}
}
6 changes: 6 additions & 0 deletions packages/cli/src/commands/validator/show.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IArg } from '@oclif/parser/lib/args'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { printValueMap } from '../../utils/cli'
import { Args } from '../../utils/command'

Expand All @@ -18,6 +19,11 @@ export default class ValidatorShow extends BaseCommand {
const { args } = this.parse(ValidatorShow)
const address = args.validatorAddress
const validators = await this.kit.contracts.getValidators()

await newCheckBuilder(this)
.isValidator(address)
.runChecks()

const validator = await validators.getValidator(address)
printValueMap(validator)
}
Expand Down
32 changes: 32 additions & 0 deletions packages/cli/src/commands/validatorgroup/deregister.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

export default class ValidatorGroupDeRegister extends BaseCommand {
static description = 'Deregister a ValidatorGroup'

static flags = {
...BaseCommand.flags,
from: Flags.address({ required: true, description: "Signer or ValidatorGroup's address" }),
}

static examples = ['deregister --from 0x47e172f6cfb6c7d01c1574fa3e2be7cc73269d95']

async run() {
const res = this.parse(ValidatorGroupDeRegister)

this.kit.defaultAccount = res.flags.from
const validators = await this.kit.contracts.getValidators()

const account = await validators.signerToAccount(res.flags.from)

await newCheckBuilder(this, res.flags.from)
.isSignerOrAccount()
.canSignValidatorTxs()
.signerAccountIsValidatorGroup()
.runChecks()

await displaySendTx('deregister', await validators.deregisterValidatorGroup(account))
}
}
Loading

0 comments on commit c4501ec

Please sign in to comment.