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

[NayNay] Removing Mention of Password #252

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ Arguments:
address Account address whose balance you want to query

Options:
-p, --password <password> Password for the account
-e, --endpoint <endpoint> Runs entropy with the given endpoint and ignores network endpoints in
config. Can also be given a stored endpoint name from config eg: `entropy
--endpoint test-net`. (default: "ws://testnet.entropy.xyz:9944/", env:
Expand Down
6 changes: 1 addition & 5 deletions src/account/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { EntropyAccount } from "./main";
import { selectAndPersistNewAccount, addVerifyingKeyToAccountAndSelect } from "./utils";
import { ACCOUNTS_CONTENT } from './constants'
import * as config from '../config'
import { cliWrite, accountOption, endpointOption, loadEntropy, passwordOption } from "../common/utils-cli";
import { cliWrite, accountOption, endpointOption, loadEntropy } from "../common/utils-cli";

export function entropyAccountCommand () {
return new Command('account')
Expand All @@ -19,7 +19,6 @@ 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(
Expand All @@ -44,7 +43,6 @@ function entropyAccountCreate () {
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(
Expand Down Expand Up @@ -72,7 +70,6 @@ function entropyAccountList () {
.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)
Expand All @@ -84,7 +81,6 @@ function entropyAccountList () {
function entropyAccountRegister () {
return new Command('register')
.description('Register an entropy account with a program')
.addOption(passwordOption())
.addOption(endpointOption())
.addOption(accountOption())
// Removing these options for now until we update the design to accept program configs
Expand Down
2 changes: 0 additions & 2 deletions src/account/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,11 @@ export class EntropyAccount extends EntropyBase {

const data = fullAccount
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
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/balance/command.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Command } from "commander";
import Entropy from "@entropyxyz/sdk";
import { cliWrite, endpointOption, loadEntropy, passwordOption } from "src/common/utils-cli";
import { cliWrite, endpointOption, loadEntropy } from "src/common/utils-cli";
import { EntropyBalance } from "./main";

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())
.addOption(endpointOption())
.action(async (address, opts) => {
const entropy: Entropy = await loadEntropy(address, opts.endpoint)
Expand Down
71 changes: 7 additions & 64 deletions src/common/initializeEntropy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import Entropy, { wasmGlobalsReady } from "@entropyxyz/sdk"
// TODO: fix importing of types from @entropy/sdk/keys
// @ts-ignore
import Keyring from "@entropyxyz/sdk/keys"
import inquirer from "inquirer"
import { decrypt, encrypt } from "../flows/password"
import * as config from "../config"
import { EntropyAccountData } from "../config/types"
import { EntropyLogger } from "./logger"
Expand All @@ -27,20 +25,19 @@ export function getKeyring (address?: string) {

interface InitializeEntropyOpts {
keyMaterial: MaybeKeyMaterial,
password?: string,
endpoint: string,
configPath?: string // for testing
}
type MaybeKeyMaterial = EntropyAccountData | string

// WARNING: in programatic cli mode this function should NEVER prompt users, but it will if no password was provided
// This is currently caught earlier in the code
export const initializeEntropy = async ({ keyMaterial, password, endpoint, configPath }: InitializeEntropyOpts): Promise<Entropy> => {
// WARNING: in programatic cli mode this function should NEVER prompt users

export const initializeEntropy = async ({ keyMaterial, endpoint, configPath }: InitializeEntropyOpts): Promise<Entropy> => {
const logger = new EntropyLogger('initializeEntropy', endpoint)
try {
await wasmGlobalsReady()

const { accountData, password: successfulPassword } = await getAccountDataAndPassword(keyMaterial, password)
const { accountData } = await getAccountData(keyMaterial)
// check if there is no admin account and no seed so that we can throw an error
if (!accountData.seed && !accountData.admin) {
throw new Error("Data format is not recognized as either encrypted or unencrypted")
Expand All @@ -52,12 +49,9 @@ export const initializeEntropy = async ({ keyMaterial, password, endpoint, confi
const store = await config.get(configPath)
store.accounts = store.accounts.map((account) => {
if (account.address === accountData.admin.address) {
let data = accountData
// @ts-ignore
if (typeof account.data === 'string' ) data = encrypt(accountData, successfulPassword)
account = {
...account,
data,
data: accountData,
}
}
return account
Expand All @@ -75,11 +69,9 @@ export const initializeEntropy = async ({ keyMaterial, password, endpoint, confi
const store = await config.get(configPath)
store.accounts = store.accounts.map((account) => {
if (account.address === store.selectedAccount) {
let data = newAccountData
if (typeof account.data === 'string') data = encrypt(newAccountData, successfulPassword)
const newAccount = {
...account,
data,
data: newAccountData,
}
return newAccount
}
Expand Down Expand Up @@ -122,65 +114,16 @@ export const initializeEntropy = async ({ keyMaterial, password, endpoint, confi


// NOTE: frankie this was prettier before I had to refactor it for merge conflicts, promise
async function getAccountDataAndPassword (keyMaterial: MaybeKeyMaterial, password?: string): Promise<{ password: string | null, accountData: EntropyAccountData }> {
async function getAccountData (keyMaterial: MaybeKeyMaterial): Promise<{ accountData: EntropyAccountData }> {
if (isEntropyAccountData(keyMaterial)) {
return {
password: null,
accountData: keyMaterial as EntropyAccountData
}
}

if (typeof keyMaterial !== 'string') {
throw new Error("Data format is not recognized as either encrypted or unencrypted")
}

/* Programmatic Mode */
if (password) {
const decryptedData = decrypt(keyMaterial, password)
if (!isEntropyAccountData(decryptedData)) {
throw new Error("Failed to decrypt keyMaterial or decrypted keyMaterial is invalid")
}
// @ts-ignore TODO: some type work here
return { password, accountData: decryptedData }
}

/* Interactive Mode */
let sucessfulPassword: string
let decryptedData
let attempts = 0

while (attempts < 3) {
const answers = await inquirer.prompt([
{
type: 'password',
name: 'password',
message: 'Enter password to decrypt keyMaterial:',
mask: '*',
}
])

try {
decryptedData = decrypt(keyMaterial, answers.password)
//@ts-ignore
if (!isEntropyAccountData(decryptedData)) {
throw new Error("Failed to decrypt keyMaterial or decrypted keyMaterial is invalid")
}

sucessfulPassword = answers.password
break
} catch (error) {
console.error("Incorrect password. Try again")
attempts++
if (attempts >= 3) {
throw new Error("Failed to decrypt keyMaterial after 3 attempts.")
}
}
}

return {
password: sucessfulPassword,
accountData: decryptedData as EntropyAccountData
}
}

function isEntropyAccountData (maybeAccountData: any) {
Expand Down
16 changes: 2 additions & 14 deletions src/common/utils-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,6 @@ export function endpointOption () {
// NOTE: argParser is only run IF an option is provided, so this cannot be 'test-net'
}

export function passwordOption (description?: string) {
return new Option(
'-p, --password <password>',
description || 'Password for the account'
)
}

export function accountOption () {
const storedConfig = getConfigOrNull()

Expand Down Expand Up @@ -76,17 +69,12 @@ export function accountOption () {
// TODO: standardise whether selectedAccount is name or address.
}

export async function loadEntropy (addressOrName: string, endpoint: string, password?: string): Promise<Entropy> {
export async function loadEntropy (addressOrName: string, endpoint: string): Promise<Entropy> {
const accounts = getConfigOrNull()?.accounts || []
const selectedAccount = findAccountByAddressOrName(accounts, addressOrName)
if (!selectedAccount) throw new Error(`No account with name or address: "${addressOrName}"`)

// check if data is encrypted + we have a password
if (typeof selectedAccount.data === 'string' && !password) {
throw new Error('AuthError: This account requires a password, add --password <password>')
}

const entropy = await initializeEntropy({ keyMaterial: selectedAccount.data, endpoint, password })
const entropy = await initializeEntropy({ keyMaterial: selectedAccount.data, endpoint })
if (!entropy?.keyring?.accounts?.registration?.pair) {
throw new Error("Signer keypair is undefined or not properly initialized.")
}
Expand Down
61 changes: 0 additions & 61 deletions src/flows/password/index.ts

This file was deleted.

3 changes: 1 addition & 2 deletions src/sign/command.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Command, /* Option */ } from 'commander'
import { cliWrite, accountOption, endpointOption, loadEntropy, passwordOption } from '../common/utils-cli'
import { cliWrite, accountOption, endpointOption, loadEntropy } from '../common/utils-cli'
import { EntropySign } from './main'

export function entropySignCommand () {
const signCommand = new Command('sign')
.description('Sign a message using the Entropy network. Output is a JSON { verifyingKey, signature }')
.argument('msg', 'Message you would like to sign (string)')
.addOption(passwordOption('Password for the source account (if required)'))
.addOption(endpointOption())
.addOption(accountOption())
// .addOption(
Expand Down
3 changes: 1 addition & 2 deletions src/transfer/command.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Command } from "commander"
import { accountOption, endpointOption, loadEntropy, passwordOption } from "src/common/utils-cli"
import { accountOption, endpointOption, loadEntropy } from "src/common/utils-cli"
import { EntropyTransfer } from "./main"

export function entropyTransferCommand () {
Expand All @@ -8,7 +8,6 @@ export function entropyTransferCommand () {
.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')
.addOption(passwordOption('Password for the source account (if required)'))
.addOption(endpointOption())
.addOption(accountOption())
.action(async (destination, amount, opts) => {
Expand Down
Loading