-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'naynay/file-restructure' into mixmix/deploy_cli
- Loading branch information
Showing
66 changed files
with
1,653 additions
and
998 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import Entropy from "@entropyxyz/sdk" | ||
import { Command, Option } from 'commander' | ||
import { EntropyAccount } from "./main"; | ||
import { selectAndPersistNewAccount } from "./utils"; | ||
import { ACCOUNTS_CONTENT } from './constants' | ||
import * as config from '../config' | ||
import { cliWrite, currentAccountAddressOption, endpointOption, loadEntropy, passwordOption } from "../common/utils-cli"; | ||
import { findAccountByAddressOrName } from "src/common/utils"; | ||
|
||
export function entropyAccountCommand () { | ||
return new Command('account') | ||
.description('Commands to work with accounts on the Entropy Network') | ||
.addCommand(entropyAccountCreate()) | ||
.addCommand(entropyAccountImport()) | ||
.addCommand(entropyAccountList()) | ||
.addCommand(entropyAccountRegister()) | ||
} | ||
|
||
function entropyAccountCreate () { | ||
return new Command('create') | ||
.alias('new') | ||
.description('Create a new entropy account from scratch. Output is JSON of form {name, address}') | ||
.addOption(passwordOption()) | ||
.argument('<name>', 'A user friendly name for your new account.') | ||
.addOption( | ||
new Option( | ||
'--path', | ||
'Derivation path' | ||
).default(ACCOUNTS_CONTENT.path.default) | ||
) | ||
.action(async (name, opts) => { | ||
const { path } = opts | ||
const newAccount = await EntropyAccount.create({ name, path }) | ||
|
||
await selectAndPersistNewAccount(newAccount) | ||
|
||
cliWrite({ | ||
name: newAccount.name, | ||
address: newAccount.address | ||
}) | ||
process.exit(0) | ||
}) | ||
} | ||
|
||
function entropyAccountImport () { | ||
return new Command('import') | ||
.description('Import an existing entropy account from seed. Output is JSON of form {name, address}') | ||
.addOption(passwordOption()) | ||
.argument('<name>', 'A user friendly name for your new account.') | ||
.argument('<seed>', 'The seed for the account you are importing') | ||
.addOption( | ||
new Option( | ||
'--path', | ||
'Derivation path' | ||
).default(ACCOUNTS_CONTENT.path.default) | ||
) | ||
.action(async (name, seed, opts) => { | ||
const { path } = opts | ||
const newAccount = await EntropyAccount.import({ name, seed, path }) | ||
|
||
await selectAndPersistNewAccount(newAccount) | ||
|
||
cliWrite({ | ||
name: newAccount.name, | ||
address: newAccount.address | ||
}) | ||
process.exit(0) | ||
}) | ||
} | ||
|
||
function entropyAccountList () { | ||
return new Command('list') | ||
.alias('ls') | ||
.description('List all accounts. Output is JSON of form [{ name, address, verifyingKeys }]') | ||
.action(async () => { | ||
// TODO: test if it's an encrypted account, if no password provided, throw because later on there's no protection from a prompt coming up | ||
const storedConfig = await config.get() | ||
const accounts = EntropyAccount.list(storedConfig) | ||
cliWrite(accounts) | ||
process.exit(0) | ||
}) | ||
} | ||
|
||
/* register */ | ||
function entropyAccountRegister () { | ||
return new Command('register') | ||
.description('Register an entropy account with a program') | ||
.addOption(passwordOption()) | ||
.addOption(endpointOption()) | ||
.addOption(currentAccountAddressOption()) | ||
// Removing these options for now until we update the design to accept program configs | ||
// .addOption( | ||
// new Option( | ||
// '-pointer, --pointer', | ||
// 'Program pointer of program to be used for registering' | ||
// ) | ||
// ) | ||
// .addOption( | ||
// new Option( | ||
// '-data, --program-data', | ||
// 'Path to file containing program data in JSON format' | ||
// ) | ||
// ) | ||
.action(async (opts) => { | ||
const { account, endpoint, /* password */ } = opts | ||
const storedConfig = await config.get() | ||
const { accounts } = storedConfig | ||
const accountToRegister = findAccountByAddressOrName(accounts, account) | ||
if (!accountToRegister) { | ||
throw new Error('AccountError: Unable to register non-existent account') | ||
} | ||
|
||
const entropy: Entropy = await loadEntropy(accountToRegister.address, endpoint) | ||
const accountService = new EntropyAccount(entropy, endpoint) | ||
const updatedAccount = await accountService.registerAccount(accountToRegister) | ||
|
||
const arrIdx = accounts.indexOf(accountToRegister) | ||
accounts.splice(arrIdx, 1, updatedAccount) | ||
await config.set({ | ||
...storedConfig, | ||
accounts, | ||
selectedAccount: updatedAccount.address | ||
}) | ||
|
||
const verifyingKeys = updatedAccount?.data?.registration?.verifyingKeys | ||
const verifyingKey = verifyingKeys[verifyingKeys.length - 1] | ||
cliWrite(verifyingKey) | ||
process.exit(0) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
export const FLOW_CONTEXT = 'ENTROPY_ACCOUNTS' | ||
|
||
export const ACCOUNTS_CONTENT = { | ||
seed: { | ||
name: 'seed', | ||
message: 'Enter seed:', | ||
invalidSeed: 'Seed provided is not valid' | ||
}, | ||
path: { | ||
name: 'path', | ||
message: 'derivation path:', | ||
default: 'none', | ||
}, | ||
importKey: { | ||
name: 'importKey', | ||
message: 'Would you like to import your own seed?', | ||
default: false | ||
}, | ||
name: { | ||
name: 'name', | ||
default: 'My Key', | ||
}, | ||
selectAccount: { | ||
name: "selectedAccount", | ||
message: "Choose account:", | ||
}, | ||
interactionChoice: { | ||
name: 'interactionChoice', | ||
choices: [ | ||
{ name: 'Create/Import Account', value: 'create-import' }, | ||
{ name: 'Select Account', value: 'select-account' }, | ||
{ name: 'List Accounts', value: 'list-account' }, | ||
{ name: 'Exit to Main Menu', value: 'exit' } | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import inquirer from "inquirer"; | ||
import Entropy from "@entropyxyz/sdk"; | ||
|
||
import { EntropyAccount } from './main' | ||
import { selectAndPersistNewAccount } from "./utils"; | ||
import { findAccountByAddressOrName, print } from "../common/utils" | ||
import { EntropyConfig } from "../config/types"; | ||
import * as config from "../config"; | ||
|
||
import { | ||
manageAccountsQuestions, | ||
newAccountQuestions, | ||
selectAccountQuestions | ||
} from "./utils" | ||
|
||
/* | ||
* @returns partialConfigUpdate | "exit" | undefined | ||
*/ | ||
export async function entropyAccount (endpoint: string, storedConfig: EntropyConfig) { | ||
const { accounts } = storedConfig | ||
const { interactionChoice } = await inquirer.prompt(manageAccountsQuestions) | ||
|
||
switch (interactionChoice) { | ||
|
||
case 'create-import': { | ||
const answers = await inquirer.prompt(newAccountQuestions) | ||
const { name, path, importKey } = answers | ||
let { seed } = answers | ||
if (importKey && seed.includes('#debug')) { | ||
// isDebugMode = true | ||
seed = seed.split('#debug')[0] | ||
} | ||
|
||
const newAccount = seed | ||
? await EntropyAccount.import({ seed, name, path }) | ||
: await EntropyAccount.create({ name, path }) | ||
|
||
await selectAndPersistNewAccount(newAccount) | ||
return | ||
} | ||
|
||
case 'select-account': { | ||
if (!accounts.length) { | ||
console.error('There are currently no accounts available, please create or import a new account using the Manage Accounts feature') | ||
return | ||
} | ||
const { selectedAccount } = await inquirer.prompt(selectAccountQuestions(accounts)) | ||
await config.set({ | ||
...storedConfig, | ||
selectedAccount: selectedAccount.address | ||
}) | ||
|
||
print('Current selected account is ' + selectedAccount) | ||
return | ||
} | ||
|
||
case 'list-account': { | ||
try { | ||
EntropyAccount.list({ accounts }) | ||
.forEach((account) => print(account)) | ||
} catch (error) { | ||
console.error(error.message.split('AccountsError: ')[1]) | ||
} | ||
return | ||
} | ||
|
||
case 'exit': { | ||
return 'exit' | ||
} | ||
|
||
default: | ||
throw new Error('AccountsError: Unknown interaction action') | ||
} | ||
} | ||
|
||
export async function entropyRegister (entropy: Entropy, endpoint: string, storedConfig: EntropyConfig): Promise<Partial<EntropyConfig>> { | ||
const accountService = new EntropyAccount(entropy, endpoint) | ||
|
||
const { accounts, selectedAccount } = storedConfig | ||
const currentAccount = findAccountByAddressOrName(accounts, selectedAccount) | ||
if (!currentAccount) { | ||
print("No account selected to register") | ||
return; | ||
} | ||
print("Attempting to register the address:", currentAccount.address) | ||
const updatedAccount = await accountService.registerAccount(currentAccount) | ||
const arrIdx = accounts.indexOf(currentAccount) | ||
accounts.splice(arrIdx, 1, updatedAccount) | ||
print("Your address", updatedAccount.address, "has been successfully registered.") | ||
|
||
return { accounts, selectedAccount } | ||
} |
Oops, something went wrong.