Skip to content

Commit

Permalink
Merge pull request #18 from celo-org/master
Browse files Browse the repository at this point in the history
master
  • Loading branch information
aaitor committed Dec 5, 2019
2 parents ed0ed8e + a330768 commit e8f19dd
Show file tree
Hide file tree
Showing 53 changed files with 385 additions and 322 deletions.
2 changes: 1 addition & 1 deletion packages/celotool/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Run this command:
### How to Faucet an Account

Run this command:
`celotooljs account faucet --celo-env <integration-or-your-testnet> --account <account-address>`
`celotooljs account faucet --celo-env <integration-or-your-testnet> --account <account-address> --gold 10 --dollar 10`

### How to Setup a Local Celo Blockchain Node

Expand Down
14 changes: 6 additions & 8 deletions packages/celotool/src/cmds/account/faucet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const describe = 'command for fauceting an address with gold and/or dolla
interface FaucetArgv extends AccountArgv {
account: string
gold: number
dollars: number
dollar: number
}

export const builder = (argv: yargs.Argv) => {
Expand All @@ -30,15 +30,15 @@ export const builder = (argv: yargs.Argv) => {
return address
},
})
.option('dollars', {
.option('dollar', {
type: 'number',
description: 'Number of dollars to faucet',
default: 0,
demand: 'Please specify dollars to faucet',
})
.option('gold', {
type: 'number',
description: 'Amount of gold to faucet',
default: 0,
demand: 'Please specify gold to faucet',
})
}

Expand All @@ -59,10 +59,8 @@ export const handler = async (argv: FaucetArgv) => {
kit.contracts.getReserve(),
])
const goldAmount = await convertToContractDecimals(argv.gold, goldToken)
const stableTokenAmount = await convertToContractDecimals(argv.dollars, stableToken)
console.log(
`Fauceting ${goldAmount.toFixed()} Gold and ${stableTokenAmount.toFixed()} StableToken to ${address}`
)
const stableTokenAmount = await convertToContractDecimals(argv.dollar, stableToken)
console.log(`Fauceting ${argv.gold} Gold and ${argv.dollar} StableToken to ${address}`)
if (!goldAmount.isZero()) {
if (await reserve.isSpender(account)) {
await reserve.transferGold(address, goldAmount.toFixed()).sendAndWaitForReceipt()
Expand Down
2 changes: 1 addition & 1 deletion packages/celotool/src/cmds/account/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const builder = (argv: yargs.Argv) => {
return argv
.option('phone', {
type: 'string',
description: 'Phone number to attest to,',
description: `Phone number to attest to. Should be an E.164 number matching formatted like +451234567890.`,
demand: 'Please specify phone number to attest to',
})
.option('num', {
Expand Down
2 changes: 2 additions & 0 deletions packages/celotool/src/lib/generate_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export enum AccountType {
FAUCET = 4,
ATTESTATION = 5,
PRICE_ORACLE = 6,
ATTESTATION_BOT = 7,
}

export enum ConsensusType {
Expand All @@ -53,6 +54,7 @@ export const MNEMONIC_ACCOUNT_TYPE_CHOICES = [
'faucet',
'attestation',
'price_oracle',
'attestation_bot',
]

export const add0x = (str: string) => {
Expand Down
11 changes: 9 additions & 2 deletions packages/celotool/src/lib/migration-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,21 @@ function getAttestationKeys() {

export function migrationOverrides() {
const mnemonic = fetchEnv(envVar.MNEMONIC)
const faucetAccounts = getAddressesFor(AccountType.FAUCET, mnemonic, 2)
const attestationBotAccount = getAddressesFor(AccountType.ATTESTATION_BOT, mnemonic, 1)
return {
validators: {
validatorKeys: validatorKeys(),
attestationKeys: getAttestationKeys(),
},
stableToken: {
initialAccounts: getAddressesFor(AccountType.FAUCET, mnemonic, 2),
values: getAddressesFor(AccountType.FAUCET, mnemonic, 2).map(() => '60000000000000000000000'), // 60k Celo Dollars
initialBalances: {
addresses: [...faucetAccounts, ...attestationBotAccount],
values: [
...faucetAccounts.map(() => '60000000000000000000000' /* 60k Celo Dollars */),
...attestationBotAccount.map(() => '10000000000000000000000' /* 10k Celo Dollars */),
],
},
oracles: getAddressesFor(AccountType.PRICE_ORACLE, mnemonic, 1),
},
}
Expand Down
33 changes: 22 additions & 11 deletions packages/cli/src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,29 @@ import { getNodeUrl } from './utils/config'
import { injectDebugProvider } from './utils/eth-debug-provider'
import { requireNodeIsSynced } from './utils/helpers'

export abstract class BaseCommand extends Command {
// Base for commands that do not need web3.
export abstract class LocalCommand extends Command {
static flags = {
logLevel: flags.string({ char: 'l', hidden: true }),
help: flags.help({ char: 'h', hidden: true }),
}

// TODO(yorke): implement log(msg) switch on logLevel with chalk colored output
log(msg: string, logLevel: string = 'info') {
if (logLevel === 'info') {
console.debug(msg)
} else if (logLevel === 'error') {
console.error(msg)
}
}
}

// tslint:disable-next-line:max-classes-per-file
export abstract class BaseCommand extends LocalCommand {
static flags = {
...LocalCommand.flags,
privateKey: flags.string({ hidden: true }),
node: flags.string({ char: 'n', hidden: true }),
}

// This specifies whether the node needs to be synced before the command
Expand All @@ -31,7 +49,9 @@ export abstract class BaseCommand extends Command {

get web3() {
if (!this._web3) {
this._web3 = new Web3(getNodeUrl(this.config.configDir))
const res: ParserOutput<any, any> = this.parse()
const nodeUrl = (res.flags && res.flags.node) || getNodeUrl(this.config.configDir)
this._web3 = new Web3(nodeUrl)
this._originalProvider = this._web3.currentProvider
injectDebugProvider(this._web3)
}
Expand All @@ -56,15 +76,6 @@ export abstract class BaseCommand extends Command {
}
}

// TODO(yorke): implement log(msg) switch on logLevel with chalk colored output
log(msg: string, logLevel: string = 'info') {
if (logLevel === 'info') {
console.debug(msg)
} else if (logLevel === 'error') {
console.error(msg)
}
}

finally(arg: Error | undefined): Promise<any> {
try {
// If local-signing accounts are added, the debug wrapper is itself wrapped
Expand Down
10 changes: 7 additions & 3 deletions packages/cli/src/commands/account/claim-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { flags } from '@oclif/command'
import { ClaimCommand } from '../../utils/identity'

export default class ClaimAccount extends ClaimCommand {
static description = 'Claim another account in a local metadata file'
static description =
'Claim another account, and optionally its public key, and add the claim to a local metadata file'
static flags = {
...ClaimCommand.flags,
address: flags.string({
Expand All @@ -12,11 +13,14 @@ export default class ClaimAccount extends ClaimCommand {
}),
publicKey: flags.string({
default: undefined,
description: 'The public key of the account if you want others to encrypt messages to you',
description:
'The public key of the account that others may use to send you encrypted messages',
}),
}
static args = ClaimCommand.args
static examples = ['claim-account ~/metadata.json --address test.com --from 0x0']
static examples = [
'claim-account ~/metadata.json --address 0xc1912fEE45d61C87Cc5EA59DaE31190FFFFf232d --from 0x47e172F6CfB6c7D01C1574fa3E2Be7CC73269D95',
]
self = ClaimAccount
async run() {
const res = this.parse(ClaimAccount)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { createAttestationServiceURLClaim } from '@celo/contractkit/lib/identity
import { Flags } from '../../utils/command'
import { ClaimCommand } from '../../utils/identity'
export default class ClaimAttestationServiceUrl extends ClaimCommand {
static description = 'Claim the URL of the attestation service in a local metadata file'
static description =
'Claim the URL of the attestation service and add the claim to a local metadata file'
static flags = {
...ClaimCommand.flags,
url: Flags.url({
Expand All @@ -12,7 +13,7 @@ export default class ClaimAttestationServiceUrl extends ClaimCommand {
}
static args = ClaimCommand.args
static examples = [
'claim-attestation-service-url ~/metadata.json --url http://test.com/myurl --from 0x0',
'claim-attestation-service-url ~/metadata.json --url http://test.com/myurl --from 0x47e172F6CfB6c7D01C1574fa3E2Be7CC73269D95',
]
self = ClaimAttestationServiceUrl

Expand Down
6 changes: 4 additions & 2 deletions packages/cli/src/commands/account/claim-domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { flags } from '@oclif/command'
import { ClaimCommand } from '../../utils/identity'

export default class ClaimDomain extends ClaimCommand {
static description = 'Change the domain in a local metadata file'
static description = 'Claim a domain and add the claim to a local metadata file'
static flags = {
...ClaimCommand.flags,
domain: flags.string({
Expand All @@ -12,7 +12,9 @@ export default class ClaimDomain extends ClaimCommand {
}),
}
static args = ClaimCommand.args
static examples = ['claim-domain ~/metadata.json --domain test.com --from 0x0']
static examples = [
'claim-domain ~/metadata.json --domain test.com --from 0x47e172F6CfB6c7D01C1574fa3E2Be7CC73269D95',
]
self = ClaimDomain
async run() {
const res = this.parse(ClaimDomain)
Expand Down
6 changes: 4 additions & 2 deletions packages/cli/src/commands/account/claim-keybase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { commandExists, execCmdWithError, execWith0Exit } from '../../utils/exec
import { ClaimCommand } from '../../utils/identity'

export default class ClaimKeybase extends ClaimCommand {
static description = 'Claim a keybase username in a local metadata file'
static description = 'Claim a keybase username and add the claim to a local metadata file'
static flags = {
...ClaimCommand.flags,
username: flags.string({
Expand All @@ -27,7 +27,9 @@ export default class ClaimKeybase extends ClaimCommand {
}),
}
static args = ClaimCommand.args
static examples = ['claim-keybase ~/metadata.json --from 0x0 --username test']
static examples = [
'claim-keybase ~/metadata.json --from 0x47e172F6CfB6c7D01C1574fa3E2Be7CC73269D95 --username myusername',
]
self = ClaimKeybase

async run() {
Expand Down
6 changes: 4 additions & 2 deletions packages/cli/src/commands/account/claim-name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { flags } from '@oclif/command'
import { ClaimCommand } from '../../utils/identity'

export default class ClaimName extends ClaimCommand {
static description = 'Change the name in a local metadata file'
static description = 'Claim a name and add the claim to a local metadata file'
static flags = {
...ClaimCommand.flags,
name: flags.string({
Expand All @@ -12,7 +12,9 @@ export default class ClaimName extends ClaimCommand {
}),
}
static args = ClaimCommand.args
static examples = ['change-name ~/metadata.json --from 0x0 --name myname']
static examples = [
'claim-name ~/metadata.json --from 0x47e172F6CfB6c7D01C1574fa3E2Be7CC73269D95 --name myname',
]
self = ClaimName
async run() {
const res = this.parse(ClaimName)
Expand Down
7 changes: 5 additions & 2 deletions packages/cli/src/commands/account/create-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import { Args } from '../../utils/command'
import { ClaimCommand } from '../../utils/identity'

export default class CreateMetadata extends ClaimCommand {
static description = 'Create an empty metadata file'
static description =
'Create an empty identity metadata file. Use this metadata file to store claims attesting to ownership of off-chain resources. Claims can be generated with the account:claim-* commands.'
static flags = ClaimCommand.flags
static args: IArg[] = [
Args.newFile('file', { description: 'Path where the metadata should be saved' }),
]
static examples = ['create-metadata ~/metadata.json --from 0x0']
static examples = [
'create-metadata ~/metadata.json --from 0x47e172F6CfB6c7D01C1574fa3E2Be7CC73269D95',
]

async run() {
const res = this.parse(CreateMetadata)
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/commands/account/get-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { Args } from '../../utils/command'
import { displayMetadata } from '../../utils/identity'

export default class GetMetadata extends BaseCommand {
static description = 'Show information about an address'
static description =
'Show information about an address. Retreives the metadata URL for an account from the on-chain, then fetches the metadata file off-chain and verifies proofs as able.'

static flags = {
...BaseCommand.flags,
Expand Down
15 changes: 9 additions & 6 deletions packages/cli/src/commands/account/new.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { ec as EC } from 'elliptic'
import Web3 from 'web3'
import { BaseCommand } from '../../base'
import { LocalCommand } from '../../base'
import { printValueMap } from '../../utils/cli'
import { ReactNativeBip39MnemonicGenerator } from '../../utils/key_generator'

export default class NewAccount extends BaseCommand {
static description = 'Creates a new account'
export default class NewAccount extends LocalCommand {
static description =
'Creates a new account locally and print out the key information. Save this information for local transaction signing or import into a Celo node.'

static flags = {
...LocalCommand.flags,
}

static examples = ['new']

Expand Down Expand Up @@ -33,16 +38,14 @@ export default class NewAccount extends BaseCommand {
return new Web3().eth.accounts.privateKeyToAccount(privateKey).address
}

requireSynced = false

async run() {
// Generate a random mnemonic (uses crypto.randomBytes under the hood), defaults to 128-bits of entropy
const mnemonic: string = NewAccount.getRandomMnemonic()
const privateKey = NewAccount.getPrivateKey(mnemonic)
const publicKey = NewAccount.getPublicKey(privateKey)
const accountAddress = NewAccount.generateAccountAddressFromPrivateKey(privateKey)
this.log(
'This is not being stored anywhere, so, save the mnemonic somewhere to use this account at a later point\n'
'This is not being stored anywhere. Save the mnemonic somewhere to use this account at a later point.\n'
)
printValueMap({ mnemonic: mnemonic, privateKey, publicKey, accountAddress })
}
Expand Down
7 changes: 5 additions & 2 deletions packages/cli/src/commands/account/register-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { displaySendTx } from '../../utils/cli'
import { Flags } from '../../utils/command'

export default class RegisterMetadata extends BaseCommand {
static description = 'Register metadata about an address'
static description =
'Register metadata URL for an account where users will be able to retieve the metadata file and verify your claims'

static flags = {
...BaseCommand.flags,
Expand All @@ -18,7 +19,9 @@ export default class RegisterMetadata extends BaseCommand {
}),
}

static examples = ['register-metadata --url https://www.celo.org --from 0x0']
static examples = [
'register-metadata --url https://www.mywebsite.com/celo-metadata --from 0x47e172F6CfB6c7D01C1574fa3E2Be7CC73269D95',
]

async run() {
const { flags } = this.parse(RegisterMetadata)
Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/commands/account/unlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ export default class Unlock extends BaseCommand {

static examples = ['unlock --account 0x5409ed021d9299bf6814279a6a1411a7e866a631']

requireSynced = false

async run() {
const res = this.parse(Unlock)
// Unlock till geth exits
// Source: https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_unlockaccount
const unlockDurationInMs = 0
const password = res.flags.password || (await cli.prompt('Password', { type: 'hide' }))
const password =
res.flags.password || (await cli.prompt('Password', { type: 'hide', required: false }))

this.web3.eth.personal.unlockAccount(res.flags.account, password, unlockDurationInMs)
}
Expand Down
8 changes: 3 additions & 5 deletions packages/cli/src/commands/config/get.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { BaseCommand } from '../../base'
import { LocalCommand } from '../../base'
import { printValueMap } from '../../utils/cli'
import { readConfig } from '../../utils/config'

export default class Get extends BaseCommand {
export default class Get extends LocalCommand {
static description = 'Output network node configuration'

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

requireSynced = false

async run() {
printValueMap(readConfig(this.config.configDir))
}
Expand Down
Loading

0 comments on commit e8f19dd

Please sign in to comment.