-
Notifications
You must be signed in to change notification settings - Fork 0
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
QA file-restructure #247
Changes from 4 commits
148b6f8
657e6fa
ca9e31f
c68d66d
c0f24a5
8730871
96371f8
ae8c88c
a415db0
fb4691b
f686ce3
6eccbba
27a994e
9e6373d
ea23881
228ec95
215f26f
9d4ed23
d9d69a5
ebaf352
6aa5c15
8724a7f
f117c1b
4f1c0ca
3a0f362
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 () { | ||
|
@@ -35,7 +38,8 @@ function entropyAccountCreate () { | |
|
||
cliWrite({ | ||
name: newAccount.name, | ||
address: newAccount.address | ||
address: newAccount.address, | ||
verifyingKeys: [] | ||
}) | ||
process.exit(0) | ||
}) | ||
|
@@ -61,7 +65,8 @@ function entropyAccountImport () { | |
|
||
cliWrite({ | ||
name: newAccount.name, | ||
address: newAccount.address | ||
address: newAccount.address, | ||
verifyingKeys: [] | ||
}) | ||
process.exit(0) | ||
}) | ||
|
@@ -73,8 +78,14 @@ 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((err) => { | ||
if (err.message.includes('currently no accounts')) return [] | ||
|
||
throw err | ||
}) | ||
|
||
Comment on lines
+79
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CHANGE: If I don't have any accounts yet I don't expect an error, I expect |
||
cliWrite(accounts) | ||
process.exit(0) | ||
}) | ||
|
@@ -84,9 +95,9 @@ function entropyAccountList () { | |
function entropyAccountRegister () { | ||
return new Command('register') | ||
.description('Register an entropy account with a program') | ||
.addOption(passwordOption()) | ||
.addOption(endpointOption()) | ||
.addOption(accountOption()) | ||
.addOption(endpointOption()) | ||
.addOption(passwordOption()) | ||
// Removing these options for now until we update the design to accept program configs | ||
// .addOption( | ||
// new Option( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
|
@@ -19,28 +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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
// const encryptedData = password ? passwordFlow.encrypt(data, password) : data | ||
|
||
|
||
return { | ||
name, | ||
address: admin.address, | ||
data | ||
// data: encryptedData // TODO: replace once password input is added back | ||
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' | ||
|
@@ -49,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 || [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔥 CHECK? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed tests |
||
})) | ||
} | ||
|
||
|
@@ -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) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,29 @@ | ||
import { Command } from "commander"; | ||
import Entropy from "@entropyxyz/sdk"; | ||
import { cliWrite, endpointOption, loadEntropy, passwordOption } from "src/common/utils-cli"; | ||
|
||
import { EntropyBalance } from "./main"; | ||
import { cliWrite, endpointOption, loadEntropy, passwordOption } 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') | ||
.addOption(passwordOption()) | ||
.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) | ||
.addOption(passwordOption()) | ||
.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 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,38 @@ | ||
import cloneDeep from 'lodash.clonedeep' | ||
|
||
const DEFAULT_MASKED_FIELDS = [ | ||
const PREFIX = 'data:application/UI8A;base64,' | ||
const DEFAULT_MASKED_FIELDS = new Set([ | ||
'seed', | ||
'secretKey', | ||
'addressRaw', | ||
]; | ||
]); | ||
|
||
export function maskPayload (payload: any): any { | ||
if (typeof payload === 'string') return payload | ||
mixmix marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const clonedPayload = cloneDeep(payload); | ||
const maskedPayload = {} | ||
if ( | ||
typeof payload === 'string' || | ||
typeof payload === 'boolean' || | ||
payload === null | ||
) return payload | ||
|
||
if (!clonedPayload) { | ||
return clonedPayload; | ||
} | ||
const maskedPayload = Array.isArray(payload) | ||
? [] | ||
: {} | ||
|
||
// maskJSONFields doesn't handle nested objects very well so we'll | ||
// need to recursively walk to object and mask them one by one | ||
for (const [property, value] of Object.entries(clonedPayload)) { | ||
if (value && typeof value === 'object') { | ||
if (Object.keys(clonedPayload[property]).filter(key => isNaN(parseInt(key))).length === 0) { | ||
const reconstructedUintArr: number[] = Object.values(clonedPayload[property]) | ||
maskedPayload[property] = "base64:" + Buffer.from(reconstructedUintArr).toString("base64"); | ||
} else { | ||
maskedPayload[property] = maskPayload(value); | ||
} | ||
} else if (value && typeof value === 'string' && DEFAULT_MASKED_FIELDS.includes(property)) { | ||
maskedPayload[property] = "*".repeat(clonedPayload[property].length) | ||
} else { | ||
maskedPayload[property] = value | ||
return Object.entries(payload).reduce((acc, [property, value]) => { | ||
if (DEFAULT_MASKED_FIELDS.has(property)) { | ||
// @ts-expect-error .length does not exist on type "unknown" | ||
acc[property] = "*".repeat(value?.length || 32) | ||
} | ||
else if (value instanceof Uint8Array) { | ||
acc[property] = PREFIX + Buffer.from(value).toString('base64') | ||
} | ||
else if (typeof value === 'object') { | ||
acc[property] = maskPayload(value); | ||
} | ||
else { | ||
acc[property] = value | ||
} | ||
} | ||
|
||
return maskedPayload; | ||
return acc | ||
}, maskedPayload) | ||
} |
There was a problem hiding this comment.
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