Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QA file-restructure #247

Merged
merged 25 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
148b6f8
WIP: QA file-restructure
mixmix Oct 1, 2024
657e6fa
fixes
mixmix Oct 1, 2024
ca9e31f
more tweaks
mixmix Oct 2, 2024
c68d66d
Update src/config/encoding.ts
mixmix Oct 2, 2024
c0f24a5
Update tests/qa.sh
mixmix Oct 2, 2024
8730871
fixups
mixmix Oct 3, 2024
96371f8
Merge branch 'dev' of github.com:entropyxyz/cli into mixmix/file-rest…
mixmix Oct 3, 2024
ae8c88c
Merge branch 'mixmix/fix-masking' into mixmix/file-restructure/QA
mixmix Oct 3, 2024
a415db0
rm commander.test.ts
mixmix Oct 3, 2024
fb4691b
fix cli opts bug with multiple accountOptions
mixmix Oct 3, 2024
f686ce3
Merge branch 'mixmix/fix-cli-opts' into mixmix/file-restructure/QA
mixmix Oct 3, 2024
6eccbba
drop async argParser function! (unsupported)
mixmix Oct 3, 2024
27a994e
Merge branch 'mixmix/fix-cli-opts' into mixmix/file-restructure/QA
mixmix Oct 3, 2024
9e6373d
tweeeks
mixmix Oct 3, 2024
ea23881
add setSelectedAccount
mixmix Oct 3, 2024
228ec95
Merge branch 'mixmix/fix-cli-opts' into mixmix/file-restructure/QA
mixmix Oct 3, 2024
215f26f
push verifyingKeys into admin account
mixmix Oct 3, 2024
9d4ed23
revert: push verifyingKeys into registration keyring account
mixmix Oct 3, 2024
d9d69a5
Merge branch 'dev' into mixmix/file-restructure/QA
mixmix Oct 14, 2024
ebaf352
Merge branch 'dev' into mixmix/fix-cli-opts
mixmix Oct 14, 2024
6aa5c15
Merge remote-tracking branch 'origin/dev' into mixmix/fix-cli-opts
mixmix Oct 20, 2024
8724a7f
Merge branch 'mixmix/fix-cli-opts' into mixmix/file-restructure/QA
mixmix Oct 20, 2024
f117c1b
Merge branch 'dev' into mixmix/file-restructure/QA
rh0delta Oct 21, 2024
4f1c0ca
reverting changes from new sdk
rh0delta Oct 21, 2024
3a0f362
Update src/config/types.ts
mixmix Oct 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"@entropyxyz/sdk": "^0.2.3",
"ansi-colors": "^4.1.3",
"cli-progress": "^3.12.0",
"commander": "^12.0.0",
"commander": "^12.1.0",
"env-paths": "^3.0.0",
"inquirer": "8.0.0",
"mkdirp": "^3.0.1",
Expand Down
20 changes: 16 additions & 4 deletions src/account/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export function entropyAccountCommand () {
.addCommand(entropyAccountImport())
.addCommand(entropyAccountList())
.addCommand(entropyAccountRegister())
// .addCommand(entropyAccountAlias())
// IDEA: support aliases for remote accounts (those we don't have seeds for)
// this would make transfers safer/ easier from CLI
}

function entropyAccountCreate () {
Expand All @@ -34,7 +37,8 @@ function entropyAccountCreate () {

cliWrite({
name: newAccount.name,
address: newAccount.address
address: newAccount.address,
verifyingKeys: []
Copy link
Contributor Author

@mixmix mixmix Oct 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PATCH:

entropy account create
entropy account create

Have them output the same format as entropy account ls
✔️ consistency
✔️ set up expectations that there is something interesting/ important meant to go in here

})
process.exit(0)
})
Expand All @@ -59,7 +63,8 @@ function entropyAccountImport () {

cliWrite({
name: newAccount.name,
address: newAccount.address
address: newAccount.address,
verifyingKeys: []
})
process.exit(0)
})
Expand All @@ -70,8 +75,15 @@ function entropyAccountList () {
.alias('ls')
.description('List all accounts. Output is JSON of form [{ name, address, verifyingKeys }]')
.action(async () => {
const storedConfig = await config.get()
const accounts = EntropyAccount.list(storedConfig)
// 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 accounts = await config.get()
.then(storedConfig => EntropyAccount.list(storedConfig))
.catch((err) => {
if (err.message.includes('currently no accounts')) return []

throw err
})

Comment on lines +79 to +86
Copy link
Contributor Author

@mixmix mixmix Oct 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHANGE: entropy account ls

If I don't have any accounts yet I don't expect an error, I expect []

cliWrite(accounts)
process.exit(0)
})
Expand Down
55 changes: 45 additions & 10 deletions src/account/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { FLOW_CONTEXT } from "./constants";
import { AccountCreateParams, AccountImportParams, AccountRegisterParams } from "./types";

import { EntropyBase } from "../common/entropy-base";
import { EntropyAccountConfig } from "../config/types";
import { EntropyAccountConfig, EntropyAccountConfigFormatted } from "../config/types";

export class EntropyAccount extends EntropyBase {
constructor (entropy: Entropy, endpoint: string) {
Expand All @@ -19,26 +19,28 @@ 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<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
const { admin } = keyring.getAccount()
const data = fixData(fullAccount)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a bug in the SDK where you are "cloning" with `JSON.parse(JSON.stringify(obj)) and it fucks up the Uint8Array, which then fucks up config, logging etc.

This is a quick hack

const maybeEncryptedData = data
// const maybeEncryptedData = password ? passwordFlow.encrypt(data, password) : data

const data = fullAccount
const { admin } = keyring.getAccount()
delete admin.pair

return {
name,
address: admin.address,
data
data: maybeEncryptedData,
}
}

static list ({ accounts }: { accounts: EntropyAccountConfig[] }) {
static list ({ accounts }: { accounts: EntropyAccountConfig[] }): EntropyAccountConfigFormatted[] {
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'
Expand All @@ -47,7 +49,7 @@ export class EntropyAccount extends EntropyBase {
return accounts.map((account: EntropyAccountConfig) => ({
name: account.name,
address: account.address,
verifyingKeys: account?.data?.admin?.verifyingKeys
verifyingKeys: account?.data?.registration?.verifyingKeys || []
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 CHECK?
I assume verifyingKeys were meant to go under registration and not admin right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AH tests say no. I don't know what the difference is between `admin + registration.
I changed where vks are being pushed into elsewhere in code too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed tests

}))
}

Expand Down Expand Up @@ -88,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
Expand All @@ -105,3 +107,36 @@ export class EntropyAccount extends EntropyBase {
})
}
}

// TODO: there is a bug in SDK that is munting this data
function fixData (data) {
if (data.admin?.pair) {
const { addressRaw, secretKey, publicKey } = data.admin.pair
Object.assign(data.admin.pair, {
addressRaw: objToUint8Array(addressRaw),
secretKey: objToUint8Array(secretKey),
publicKey: objToUint8Array(publicKey)
})
}

if (data.registration?.pair) {
const { addressRaw, secretKey, publicKey } = data.registration.pair
Object.assign(data.registration.pair, {
addressRaw: objToUint8Array(addressRaw),
secretKey: objToUint8Array(secretKey),
publicKey: objToUint8Array(publicKey)
})
}

return data
}

function objToUint8Array (input) {
if (input instanceof Uint8Array) return input

const values: any = Object.entries(input)
.sort((a, b) => Number(a[0]) - Number(b[0])) // sort entries by keys
.map(entry => entry[1])

return new Uint8Array(values)
}
8 changes: 5 additions & 3 deletions src/account/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,22 @@ 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 } = storedConfig

const account = findAccountByAddressOrName(accounts, accountNameOrAddress)
if (!account) throw Error(`Unable to persist verifyingKey "${verifyingKey}" to unknown account "${accountNameOrAddress}"`)

// persist to config, set selectedAccount
account.data.registration.verifyingKeys.push(verifyingKey)
await config.set({
...storedConfig,
selectedAccount: account.address
setSelectedAccount: account.name
})
}

Expand Down
17 changes: 12 additions & 5 deletions src/balance/command.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
import { Command } from "commander";
import Entropy from "@entropyxyz/sdk";
import { cliWrite, endpointOption, loadEntropy } from "src/common/utils-cli";

import { EntropyBalance } from "./main";
import { endpointOption, cliWrite, loadEntropy } from "../common/utils-cli";
import { findAccountByAddressOrName } from "../common/utils";
import * as config from "../config";

export function entropyBalanceCommand () {
const balanceCommand = new Command('balance')
balanceCommand
.description('Command to retrieive the balance of an account on the Entropy Network')
.argument('address', 'Account address whose balance you want to query')
.argument('account <address|name>', 'Account address whose balance you want to query')
.addOption(endpointOption())
.action(async (address, opts) => {
const entropy: Entropy = await loadEntropy(address, opts.endpoint)
.action(async (account, opts) => {
const entropy: Entropy = await loadEntropy(account, opts.endpoint)
const BalanceService = new EntropyBalance(entropy, opts.endpoint)

const { accounts } = await config.get()
const address = findAccountByAddressOrName(accounts, account)?.address

const balance = await BalanceService.getBalance(address)
cliWrite(`${balance.toLocaleString('en-US')} BITS`)
process.exit(0)
})

return balanceCommand
}
2 changes: 2 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ program
.env('DEV_MODE')
.hideHelp()
)

.addCommand(entropyBalanceCommand())
.addCommand(entropyAccountCommand())
.addCommand(entropyTransferCommand())
.addCommand(entropySignCommand())
.addCommand(entropyProgramCommand())

.action(async (opts: EntropyTuiOptions) => {
const { account, endpoint } = opts
const entropy = account
Expand Down
3 changes: 2 additions & 1 deletion src/common/utils-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ 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: default cannot be "test-net" as argParser only runs if the -e/--endpoint flag
// or ENTROPY_ENDPOINT env set
}

export function accountOption () {
Expand Down
11 changes: 8 additions & 3 deletions src/config/encoding.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
const PREFIX = 'data:application/UI8A;base64,'
// was a UInt8Array, but is stored as base64

export function serialize (config) {
export function serialize (config: object) {
return JSON.stringify(config, replacer, 2)
}

export function deserialize (config) {
return JSON.parse(config, reviver)
export function deserialize (config: string) {
try {
return JSON.parse(config, reviver)
} catch (err) {
console.log('broken config:', config)
throw err
}
}

function replacer (_key: string, value: any) {
Expand Down
5 changes: 4 additions & 1 deletion src/sign/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ export class EntropySign extends EntropyBase {
const signatureHexString = u8aToHex(signature)
this.logger.log(`Signature: ${signatureHexString}`)

return { signature: signatureHexString, verifyingKey: this.entropy.signingManager.verifyingKey }
return {
signature: signatureHexString,
verifyingKey: this.entropy.signingManager.verifyingKey
}
} catch (error) {
this.logger.error('Error signing message', error)
throw error
Expand Down
7 changes: 5 additions & 2 deletions src/transfer/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ import { accountOption, endpointOption, loadEntropy } from "src/common/utils-cli
import { EntropyTransfer } from "./main"

export function entropyTransferCommand () {
const transferCommand = new Command('tranfer')
const transferCommand = new Command('transfer')
mixmix marked this conversation as resolved.
Show resolved Hide resolved
transferCommand
.description('Transfer funds between two Entropy accounts.') // TODO: name the output
.argument('destination', 'Account address funds will be sent to')
.argument('amount', 'Amount of funds to be moved')
.argument('amount', 'Amount of funds to be moved (in "tokens")')
.addOption(accountOption())
.addOption(endpointOption())
.action(async (destination, amount, opts) => {
// TODO: destination as <name|address> ?
const entropy = await loadEntropy(opts.account, opts.endpoint)
const transferService = new EntropyTransfer(entropy, opts.endpoint)

await transferService.transfer(destination, amount)

// cliWrite(??) // TODO: write the output
process.exit(0)
})
Expand Down
2 changes: 1 addition & 1 deletion src/transfer/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class EntropyTransfer extends EntropyBase {
dispatchError.asModule
)
const { docs, name, section } = decoded

msg = `${section}.${name}: ${docs.join(' ')}`
} else {
// Other, CannotLookup, BadOrigin, no extra info
Expand Down
4 changes: 2 additions & 2 deletions tests/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test('Account - list', async t => {
address: charlieStashAddress,
data: {
seed: charlieStashSeed,
admin: {
registration: {
verifyingKeys: ['this-is-a-verifying-key'],
seed: charlieStashSeed,
address: charlieStashAddress,
Expand All @@ -41,7 +41,7 @@ test('Account - list', async t => {
t.deepEqual(accountsArray, [{
name: account.name,
address: account.address,
verifyingKeys: account?.data?.admin?.verifyingKeys
verifyingKeys: account?.data?.registration?.verifyingKeys
}])

// Resetting accounts on config to test for empty list
Expand Down
Loading
Loading