From 657e6fa85c6c6c3b10cd51602774d5411e7ed62d Mon Sep 17 00:00:00 2001 From: mixmix Date: Wed, 2 Oct 2024 11:49:17 +1300 Subject: [PATCH] fixes --- src/account/command.ts | 12 +++++------- src/account/interaction.ts | 5 +---- src/account/main.ts | 39 +++++++++++++++++++++++++++++++------- src/account/utils.ts | 11 ++++------- src/common/utils-cli.ts | 24 +++++++++++------------ src/config/index.ts | 17 ++++++++++++++++- src/config/types.ts | 1 + src/transfer/command.ts | 8 -------- src/tui.ts | 6 +----- tests/cli.test.sh | 7 +++---- 10 files changed, 75 insertions(+), 55 deletions(-) diff --git a/src/account/command.ts b/src/account/command.ts index 59fa8745..71645feb 100644 --- a/src/account/command.ts +++ b/src/account/command.ts @@ -76,8 +76,11 @@ function entropyAccountList () { .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) + const accounts = await config.get() + .then(storedConfig => EntropyAccount.list(storedConfig)) + .catch(() => []) + // QUESTION: is dropping the error right? Maybe only if "There are currently no accounts" + cliWrite(accounts) process.exit(0) }) @@ -104,16 +107,11 @@ function entropyAccountRegister () { // ) // ) .action(async (opts) => { - console.log('here 0') - console.log(opts) // NOTE: loadEntropy throws if it can't find opts.account const entropy: Entropy = await loadEntropy(opts.account, opts.endpoint) const accountService = new EntropyAccount(entropy, opts.endpoint) - console.log('here 1') - const verifyingKey = await accountService.register() - console.log('here 2') await addVerifyingKeyToAccountAndSelect(verifyingKey, opts.account) cliWrite(verifyingKey) diff --git a/src/account/interaction.ts b/src/account/interaction.ts index bf1c599f..b26103dd 100644 --- a/src/account/interaction.ts +++ b/src/account/interaction.ts @@ -45,10 +45,7 @@ export async function entropyAccount (endpoint: string, storedConfig: EntropyCon return } const { selectedAccount } = await inquirer.prompt(accountSelectQuestions(accounts)) - await config.set({ - ...storedConfig, - selectedAccount: selectedAccount.address - }) + await config.setSelectedAccount(selectedAccount) print('Current selected account is ' + selectedAccount) return diff --git a/src/account/main.ts b/src/account/main.ts index c1395dcb..dac8ce83 100644 --- a/src/account/main.ts +++ b/src/account/main.ts @@ -19,19 +19,19 @@ export class EntropyAccount extends EntropyBase { return EntropyAccount.import({ name, seed, path }) } + // WARNING: #create depends on #import => be careful modifying this function static async import ({ name, seed, path }: AccountImportParams ): Promise { - // 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 - const { admin } = keyring.getAccount() + const data = fixData(fullAccount) + // const encryptedData = password ? passwordFlow.encrypt(data, password) : data - const data = fullAccount + const { admin } = keyring.getAccount() delete admin.pair - // const encryptedData = password ? passwordFlow.encrypt(data, password) : data - + return { name, address: admin.address, @@ -90,7 +90,7 @@ export class EntropyAccount extends EntropyBase { dispatchError.asModule ) const { docs, name, section } = decoded - + msg = `${section}.${name}: ${docs.join(' ')}` } else { // Other, CannotLookup, BadOrigin, no extra info @@ -107,3 +107,28 @@ export class EntropyAccount extends EntropyBase { }) } } + +// TODO: there is a bug in SDK that is munting this data +function fixData (data) { + if (data.admin) { + data.admin.pair.addressRaw = objToUint8Array(data.admin.pair.addressRaw) + data.admin.pair.secretKey = objToUint8Array(data.admin.pair.secretKey) + data.admin.pair.publicKey = objToUint8Array(data.admin.pair.publicKey) + } + + if (data.registration) { + data.registration.pair.addressRaw = objToUint8Array(data.registration.pair.addressRaw) + data.registration.pair.secretKey = objToUint8Array(data.registration.pair.secretKey) + data.registration.pair.publicKey = objToUint8Array(data.registration.pair.publicKey) + } + + return data +} + +function objToUint8Array (obj) { + const values: any = Object.entries(obj) + .sort((a, b) => Number(a[0]) - Number(b[0])) // sort entries by keys + .map(entry => entry[1]) + + return new Uint8Array(values) +} diff --git a/src/account/utils.ts b/src/account/utils.ts index cf51603a..16e5e4cc 100644 --- a/src/account/utils.ts +++ b/src/account/utils.ts @@ -19,22 +19,19 @@ export async function selectAndPersistNewAccount (newAccount: EntropyAccountConf accounts.push(newAccount) await config.set({ ...storedConfig, - selectedAccount: newAccount.address + selectedAccount: newAccount.name }) } export async function addVerifyingKeyToAccountAndSelect (verifyingKey: string, accountNameOrAddress: string) { - const storedConfig = await config.get() - const account = findAccountByAddressOrName(storedConfig.accounts, accountNameOrAddress) + const { accounts } = await config.get() + const account = findAccountByAddressOrName(accounts, accountNameOrAddress) if (!account) throw Error(`Unable to persist verifyingKey "${verifyingKey}" to unknown account "${accountNameOrAddress}"`) account.data.registration.verifyingKeys.push(verifyingKey) // persist to config, set selectedAccount - await config.set({ - ...storedConfig, - selectedAccount: account.address - }) + await config.setSelectedAccount(account) } function validateSeedInput (seed) { diff --git a/src/common/utils-cli.ts b/src/common/utils-cli.ts index f185cd05..37e29ffc 100644 --- a/src/common/utils-cli.ts +++ b/src/common/utils-cli.ts @@ -39,7 +39,7 @@ export function endpointOption () { return endpoint }) .default('ws://testnet.entropy.xyz:9944/') - // NOTE: argParser is only run IF an option is provided, so this cannot be 'test-net' + // NOTE: argParser only runs IF the -e/--endpoint option called, so this default cannot be 'test-net' } export function passwordOption (description?: string) { @@ -61,20 +61,20 @@ export function accountOption () { ].join(' ') ) .env('ENTROPY_ACCOUNT') - .argParser(async (account) => { - if (storedConfig && storedConfig.selectedAccount !== account) { - // Updated selected account in config with new address from this option - await config.set({ - ...storedConfig, - selectedAccount: account - }) - } + .argParser(async (addressOrName) => { + // We try to map addressOrName to an account we have stored + if (!storedConfig) return addressOrName - return account + const account = findAccountByAddressOrName(storedConfig.accounts, addressOrName) + if (!account) return addressOrName + + // If we find one, we set this account as the future default + await config.setSelectedAccount(account) + + // We finally return the account name to be as consistent as possible (using name, not address) + return account.name }) .default(storedConfig?.selectedAccount) - // TODO: display the *name* not address - // TODO: standardise whether selectedAccount is name or address. } export async function loadEntropy (addressOrName: string, endpoint: string, password?: string): Promise { diff --git a/src/config/index.ts b/src/config/index.ts index 049b6775..93b6f351 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -6,7 +6,7 @@ import envPaths from 'env-paths' import allMigrations from './migrations' import { serialize, deserialize } from './encoding' -import { EntropyConfig } from './types' +import { EntropyConfig, EntropyAccountConfig } from './types' const paths = envPaths('entropy-cryptography', { suffix: '' }) const CONFIG_PATH = join(paths.config, 'entropy-cli.json') @@ -63,6 +63,7 @@ export async function get (configPath = CONFIG_PATH) { export function getSync (configPath = CONFIG_PATH) { const configStr = readFileSync(configPath, 'utf8') + // console.log('getSync', configPath, configStr) return deserialize(configStr) } @@ -73,6 +74,20 @@ export async function set (config: EntropyConfig, configPath = CONFIG_PATH) { await writeFile(configPath, serialize(config)) } +export async function setSelectedAccount (account: EntropyAccountConfig, configPath = CONFIG_PATH) { + const storedConfig = await get(configPath) + + if (storedConfig.selectedAccount === account.name) return storedConfig + // no need for update + + const newConfig = { + ...storedConfig, + selectedAccount: account.name + } + await set(newConfig, configPath) + return newConfig +} + /* util */ function noop () {} function assertConfigPath (configPath) { diff --git a/src/config/types.ts b/src/config/types.ts index 7d4deb78..66e1c6cc 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -4,6 +4,7 @@ export interface EntropyConfig { dev: string; 'test-net': string } + // selectedAccount is account.name (alias) for the account selectedAccount: string 'migration-version': string } diff --git a/src/transfer/command.ts b/src/transfer/command.ts index db3bf157..c3683553 100644 --- a/src/transfer/command.ts +++ b/src/transfer/command.ts @@ -12,16 +12,8 @@ export function entropyTransferCommand () { .addOption(endpointOption()) .addOption(passwordOption('Password for the source account (if required)')) .action(async (destination, amount, opts) => { - console.log({ destination, amount, opts }) - // TODO: destination as ? const entropy = await loadEntropy(opts.account, opts.endpoint) - .catch(err => { - // WIP here. SOMETHING is wrecking the config upstream - console.error("loadEntropy failed", err) - throw err - }) - const transferService = new EntropyTransfer(entropy, opts.endpoint) await transferService.transfer(destination, amount) diff --git a/src/tui.ts b/src/tui.ts index bd7780cf..f02d82da 100644 --- a/src/tui.ts +++ b/src/tui.ts @@ -19,11 +19,7 @@ async function setupConfig () { // set selectedAccount if we can if (!storedConfig.selectedAccount && storedConfig.accounts.length) { - await config.set({ - ...storedConfig, - selectedAccount: storedConfig.accounts[0].address - }) - storedConfig = await config.get() + storedConfig = await config.setSelectedAccount(storedConfig.accounts[0]) } return storedConfig diff --git a/tests/cli.test.sh b/tests/cli.test.sh index 0e2a0374..f22ee2c6 100755 --- a/tests/cli.test.sh +++ b/tests/cli.test.sh @@ -15,9 +15,9 @@ print () { print "// ACCOUNT /////////////////////////////////////////////////" -# Errors (correct, but messy?) -# print "account ls:" -# entropy account ls | jq +print "account ls" +entropy account ls | jq +# TODO: change this to return [] ? print "account create" entropy account create naynay | jq @@ -45,7 +45,6 @@ print "// TRANSFER ////////////////////////////////////////////////" print "entropy transfer" NAYNAY_ADDRESS=`entropy account ls | jq --raw-output ".[0].address"` -# NOTE: --raw-output is needed to drop the quotes entropy transfer -a faucet ${NAYNAY_ADDRESS} 2.5 entropy balance naynay