Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mixmix committed Aug 29, 2024
1 parent 9cb1b81 commit dbbb777
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 32 deletions.
59 changes: 47 additions & 12 deletions src/account/command.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Entropy from "@entropyxyz/sdk";
import Entropy from "@entropyxyz/sdk"
import { Command, Option } from 'commander'
import { EntropyAccount } from "./main";
import { ACCOUNTS_CONTENT } from './constants'
Expand All @@ -10,16 +10,17 @@ export async function entropyAccountCommand (entropy: Entropy, rootCommand: Comm
const accountCommand = rootCommand.command('account')
.description('Commands to work with accounts on the Entropy Network')

entropyAccountCreate(accountCommand)
entropyAccountImport(accountCommand)
entropyAccountList(accountCommand)
entropyAccountNew(accountCommand)
}

function entropyAccountNew (accountCommand: Command) {
function entropyAccountCreate (accountCommand: Command) {
accountCommand.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 nem account.')
.argument('<name>', 'A user friendly name for your new account.')
.addOption(
new Option(
'--path',
Expand All @@ -28,24 +29,58 @@ function entropyAccountNew (accountCommand: Command) {
)
.action(async (name, opts) => {
const { path } = opts
const newAccount = EntropyAccount.create({ name, path })
const newAccount = await EntropyAccount.create({ name, path })

const storedConfig = await config.get()
const { accounts } = storedConfig
accounts.push(newAccount)
// WIP - sort out the updateConfig stuff
await updateConfig(storedConfig, {
accounts,
selectedAccount: newAccount.address
await persistAndSelectNewAccount(newAccount)

cliWrite({
name: newAccount.name,
address: newAccount.address
})
process.exit(0)
})
}

function entropyAccountImport (accountCommand: Command) {
accountCommand.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 persistAndSelectNewAccount(newAccount)

cliWrite({
name: newAccount.name,
address: newAccount.address
})
process.exit(0)
})
}

async function persistAndSelectNewAccount (newAccount) {
const storedConfig = await config.get()
const { accounts } = storedConfig

const isExistingName = accounts.find(account => account.name === newAccount.name)
if (isExistingName) {
throw Error(`An account with name "${newAccount.name}" already exists. Choose a different name`)
}

accounts.push(newAccount)
await updateConfig(storedConfig, {
accounts,
selectedAccount: newAccount.address
})
}

function entropyAccountList (accountCommand: Command) {
Expand Down
1 change: 1 addition & 0 deletions src/account/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export async function entropyManageAccounts (endpoint: string, storedConfig: Ent
: EntropyAccount.create({ name, path })
accounts.push(newAccount)

Check failure on line 30 in src/account/interaction.ts

View workflow job for this annotation

GitHub Actions / Build, test, and lint

Argument of type 'Promise<EntropyAccountConfig>' is not assignable to parameter of type 'EntropyAccountConfig'.

// WIP HERE
return {
accounts,
selectedAccount: newAccount.address

Check failure on line 35 in src/account/interaction.ts

View workflow job for this annotation

GitHub Actions / Build, test, and lint

Property 'address' does not exist on type 'Promise<EntropyAccountConfig>'.
Expand Down
24 changes: 14 additions & 10 deletions src/account/main.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import Entropy from "@entropyxyz/sdk";
import Entropy, { wasmGlobalsReady } from "@entropyxyz/sdk";
// @ts-expect-error
import Keyring from '@entropyxyz/sdk/keys'
import { randomAsHex } from '@polkadot/util-crypto'

import { FLOW_CONTEXT } from "./constants";
import { AccountCreateParams, AccountImportParams, AccountRegisterParams } from "./types";
import { print } from "src/common/utils";
import { formatAccountsList } from "./utils";

import { EntropyBase } from "../common/entropy-base";
import { EntropyAccountConfig } from "../config/types";
Expand All @@ -16,12 +15,15 @@ export class EntropyAccount extends EntropyBase {
super({ entropy, endpoint, flowContext: FLOW_CONTEXT })
}

static create ({ name, path }: AccountCreateParams): EntropyAccountConfig {
static async create ({ name, path }: AccountCreateParams): Promise<EntropyAccountConfig> {
const seed = randomAsHex(32)
return EntropyAccount.import({ name, seed, path })
}

static import ({ name, seed, path }: AccountImportParams ): EntropyAccountConfig {
static async import ({ name, seed, path }: AccountImportParams ): Promise<EntropyAccountConfig> {
// WARNING: #create currently depends on this => be careful modifying this function

await wasmGlobalsReady()
const keyring = new Keyring({ seed, path, debug: true })
const fullAccount = keyring.getAccount()
// TODO: sdk should create account on constructor
Expand All @@ -30,7 +32,7 @@ export class EntropyAccount extends EntropyBase {
const data = fullAccount
delete admin.pair
// const encryptedData = password ? passwordFlow.encrypt(data, password) : data

return {
name,
address: admin.address,
Expand All @@ -40,14 +42,16 @@ export class EntropyAccount extends EntropyBase {
}

static list (accounts: EntropyAccountConfig[]) {
const accountsArray = Array.isArray(accounts) && accounts.length
? accounts
: []
if (!accountsArray.length)
if (!accounts.length)
throw new Error(
'AccountsError: There are currently no accounts available, please create or import a new account using the Manage Accounts feature'
)
return formatAccountsList(accountsArray)

return accounts.map((account: EntropyAccountConfig) => ({
name: account.name,
address: account.address,
verifyingKeys: account?.data?.admin?.verifyingKeys
}))
}

async register (params?: AccountRegisterParams): Promise<string> {
Expand Down
8 changes: 0 additions & 8 deletions src/account/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,3 @@ export const manageAccountsQuestions = [
choices: ACCOUNTS_CONTENT.interactionChoice.choices
}
]

export function formatAccountsList (accounts: EntropyAccountConfig[]): AccountListResults[] {
return accounts.map((account: EntropyAccountConfig) => ({
name: account.name,
address: account.address,
verifyingKeys: account?.data?.admin?.verifyingKeys
}))
}
11 changes: 9 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ async function setEntropyGlobal (address: string, endpoint: string, password?: s
if (entropy) {
const currentAddress = entropy?.keyring?.accounts?.registration?.address
if (address !== currentAddress) {
// Is it possible to hit this?
// QUESTION: Is it possible to hit this?
// - programmatic usage kills process after function call
// - tui usage manages mutation of entropy instance itself
await entropy.close()
Expand All @@ -29,6 +29,7 @@ async function setEntropyGlobal (address: string, endpoint: string, password?: s
}

const program = new Command()
let commandName: string // the top level command

/* no command */
program
Expand All @@ -44,9 +45,15 @@ program
.env('DEV_MODE')
.hideHelp()
)
.hook('preSubcommand', async (_thisCommand, subCommand) => {
commandName = subCommand.name()
})
.hook('preAction', async (_thisCommand, actionCommand) => {
if (commandName === 'account') return
// entropy not required for any account commands

const { account, endpoint, password } = actionCommand.opts()
const address = actionCommand.name() === 'balance'
const address = commandName === 'balance'
? actionCommand.args[0]
: account

Expand Down
1 change: 1 addition & 0 deletions src/config/encoding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function deserialize (config) {
}

function replacer (key, value) {
console.log(key, typeof value, value instanceof Uint8Array)
if (value instanceof Uint8Array) {
return PREFIX + Buffer.from(value).toString('base64')
}
Expand Down

0 comments on commit dbbb777

Please sign in to comment.