From 4b802e0bfcc03ca93cdeba8a6b58714093235a67 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 31 Jul 2024 15:46:59 -0400 Subject: [PATCH 01/14] [NayNay] File Restructure: Base Class + Balance Restructure - created new base entropy class to handle the shared nature of the intended use of the class - restructured balance to be in its own parent directory in the root of src - created command and util file to contain pure functions and controller functions --- src/balance/command.ts | 21 +++++++++++++++ src/balance/constants.ts | 1 + src/{flows => }/balance/types.ts | 0 src/balance/utils.ts | 44 +++++++++++++++++++++++++++++++ src/common/entropy-base.ts | 12 +++++++++ src/common/logger.ts | 2 +- src/flows/balance/balance.ts | 36 ------------------------- src/flows/balance/cli.ts | 9 ++++--- src/flows/balance/index.ts | 11 +++++--- tests/balance.test.ts | 14 +++++----- tests/testing-utils/setup-test.ts | 12 +++++---- tests/transfer.test.ts | 14 +++++----- 12 files changed, 114 insertions(+), 62 deletions(-) create mode 100644 src/balance/command.ts create mode 100644 src/balance/constants.ts rename src/{flows => }/balance/types.ts (100%) create mode 100644 src/balance/utils.ts create mode 100644 src/common/entropy-base.ts delete mode 100644 src/flows/balance/balance.ts diff --git a/src/balance/command.ts b/src/balance/command.ts new file mode 100644 index 00000000..09f96d4f --- /dev/null +++ b/src/balance/command.ts @@ -0,0 +1,21 @@ +import Entropy from "@entropyxyz/sdk" +import { EntropyBase } from "../common/entropy-base" +import { BalanceService } from "./utils" +import { FLOW_CONTEXT } from "./constants" + +export class BalanceController extends EntropyBase { + private readonly balanceService: BalanceService + + constructor (entropy: Entropy, endpoint: string) { + super(entropy, endpoint, FLOW_CONTEXT) + this.balanceService = new BalanceService(this.entropy, endpoint) + } + + public async getBalance (address: string) { + const balance = await this.balanceService.getBalance(address) + + this.logger.log(`Current balance of ${address}: ${balance}`, `${BalanceController.name}`) + + return `${balance.toLocaleString('en-US')} BITS` + } +} \ No newline at end of file diff --git a/src/balance/constants.ts b/src/balance/constants.ts new file mode 100644 index 00000000..204e8cd2 --- /dev/null +++ b/src/balance/constants.ts @@ -0,0 +1 @@ +export const FLOW_CONTEXT = 'ENTROPY-BALANCE' \ No newline at end of file diff --git a/src/flows/balance/types.ts b/src/balance/types.ts similarity index 100% rename from src/flows/balance/types.ts rename to src/balance/types.ts diff --git a/src/balance/utils.ts b/src/balance/utils.ts new file mode 100644 index 00000000..4b809dcd --- /dev/null +++ b/src/balance/utils.ts @@ -0,0 +1,44 @@ +import Entropy from "@entropyxyz/sdk"; +import { EntropyBase } from "../common/entropy-base"; +import { BalanceInfo } from "./types"; +import { FLOW_CONTEXT } from "./constants"; + +const hexToBigInt = (hexString: string) => BigInt(hexString) + +export class BalanceService extends EntropyBase { + constructor (entropy: Entropy, endpoint: string) { + super(entropy, endpoint, FLOW_CONTEXT) + } + + public async getBalance (address: string): Promise { + try { + const accountInfo = (await this.entropy.substrate.query.system.account(address)) as any + + return parseInt(hexToBigInt(accountInfo.data.free).toString()) + } catch (error) { + this.logger.error(`There was an error getting balance for [acct = ${address}]`, error); + throw new Error(error.message) + } + } + + public async getBalances (addresses: string[]): Promise { + const balanceInfo: BalanceInfo = {} + try { + await Promise.all(addresses.map(async address => { + try { + const balance = await this.getBalance(address) + + balanceInfo[address] = { balance } + } catch (error) { + this.logger.error(`Error retrieving balance for ${address}`, error); + balanceInfo[address] = { error: error.message } + } + })) + + return balanceInfo + } catch (error) { + this.logger.error(`There was an error getting balances for [${addresses}]`, error); + throw new Error(error.message) + } + } +} \ No newline at end of file diff --git a/src/common/entropy-base.ts b/src/common/entropy-base.ts new file mode 100644 index 00000000..1e14bf3b --- /dev/null +++ b/src/common/entropy-base.ts @@ -0,0 +1,12 @@ +import Entropy from "@entropyxyz/sdk"; +import { EntropyLogger } from "./logger"; + +export abstract class EntropyBase { + protected logger: EntropyLogger + protected entropy: Entropy + + constructor (entropy: Entropy, endpoint: string, flowContext: string) { + this.logger = new EntropyLogger(flowContext, endpoint) + this.entropy = entropy + } +} \ No newline at end of file diff --git a/src/common/logger.ts b/src/common/logger.ts index 7f112143..14a428e6 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -117,7 +117,7 @@ export class EntropyLogger { this.winstonLogger.log({ level, message: maskPayload(message), - context: context || this.context, + context: context ? `${this.context}:${context}` : this.context, endpoint: this.endpoint, description, stack, diff --git a/src/flows/balance/balance.ts b/src/flows/balance/balance.ts deleted file mode 100644 index d2a5ce3b..00000000 --- a/src/flows/balance/balance.ts +++ /dev/null @@ -1,36 +0,0 @@ -import Entropy from "@entropyxyz/sdk"; -import { BalanceInfo } from "./types"; - -const hexToBigInt = (hexString: string) => BigInt(hexString) - -export async function getBalance (entropy: Entropy, address: string): Promise { - try { - const accountInfo = (await entropy.substrate.query.system.account(address)) as any - - return parseInt(hexToBigInt(accountInfo.data.free).toString()) - } catch (error) { - // console.error(`There was an error getting balance for [acct = ${address}]`, error); - throw new Error(error.message) - } -} - -export async function getBalances (entropy: Entropy, addresses: string[]): Promise { - const balanceInfo: BalanceInfo = {} - try { - await Promise.all(addresses.map(async address => { - try { - const balance = await getBalance(entropy, address) - - balanceInfo[address] = { balance } - } catch (error) { - // console.error(`Error retrieving balance for ${address}`, error); - balanceInfo[address] = { error: error.message } - } - })) - - return balanceInfo - } catch (error) { - // console.error(`There was an error getting balances for [${addresses}]`, error); - throw new Error(error.message) - } -} \ No newline at end of file diff --git a/src/flows/balance/cli.ts b/src/flows/balance/cli.ts index 4bcb208d..78fa71a2 100644 --- a/src/flows/balance/cli.ts +++ b/src/flows/balance/cli.ts @@ -1,8 +1,10 @@ +import { BalanceController } from 'src/balance/command' import { initializeEntropy } from '../../common/initializeEntropy' import * as config from '../../config' -import { getBalance } from './balance' import { EntropyLogger } from 'src/common/logger' +// TO-DO: move entropy initialization and account retrieval to a shared container +// should remove the need to initialize entropy every time export async function cliGetBalance ({ address, password, endpoint }) { const logger = new EntropyLogger('CLI::CHECK_BALANCE', endpoint) const storedConfig = await config.get() @@ -17,8 +19,9 @@ export async function cliGetBalance ({ address, password, endpoint }) { } const entropy = await initializeEntropy({ keyMaterial: account.data, password, endpoint }) - const balance = await getBalance(entropy, address) + const balanceController = new BalanceController(entropy, endpoint) + const balance = await balanceController.getBalance(address) - return `${balance.toLocaleString('en-US')} BITS` + return balance } diff --git a/src/flows/balance/index.ts b/src/flows/balance/index.ts index 0481c86e..b13557ac 100644 --- a/src/flows/balance/index.ts +++ b/src/flows/balance/index.ts @@ -1,10 +1,12 @@ import { EntropyLogger } from "src/common/logger"; import { initializeEntropy } from "../../common/initializeEntropy" import { print, getSelectedAccount } from "../../common/utils" -import { getBalance } from "./balance"; +import { BalanceController } from "src/balance/command"; -// TO-DO setup flow method to provide options to allow users to select account, +// TO-DO: setup flow method to provide options to allow users to select account, // use external address, or get balances for all accounts in config +// TO-DO: move entropy initialization and account retrieval to a shared container +// should remove the need to initialize entropy every time export async function checkBalance ({ accounts, selectedAccount: selectedAccountAddress }, options, logger: EntropyLogger) { const FLOW_CONTEXT = 'CHECK_BALANCE' const { endpoint } = options @@ -13,7 +15,8 @@ export async function checkBalance ({ accounts, selectedAccount: selectedAccount const selectedAccount = getSelectedAccount(accounts, selectedAccountAddress) logger.log(selectedAccount, FLOW_CONTEXT) const entropy = await initializeEntropy({ keyMaterial: selectedAccount.data, endpoint }); + const balanceController = new BalanceController(entropy, endpoint) const accountAddress = selectedAccountAddress - const freeBalance = await getBalance(entropy, accountAddress) - print(`Address ${accountAddress} has a balance of: ${freeBalance.toLocaleString('en-US')} BITS`) + const freeBalanceString = await balanceController.getBalance(accountAddress) + print(`Address ${accountAddress} has a balance of: ${freeBalanceString}`) } diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 2d05b25e..3b77d141 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -1,32 +1,32 @@ import test from 'tape' -import { getBalance, getBalances } from '../src/flows/balance/balance' import { setupTest, charlieStashAddress as richAddress } from './testing-utils' +import { BalanceService } from 'src/balance/utils' const networkType = 'two-nodes' test('getBalance + getBalances', async (t) => { - const { run, entropy } = await setupTest(t, { networkType }) - + const { run, entropy, endpoint } = await setupTest(t, { networkType }) + const balanceService = new BalanceService(entropy, endpoint) const newAddress = entropy.keyring.accounts.registration.address /* getBalance */ const newAddressBalance = await run( 'getBalance (newSeed)', - getBalance(entropy, newAddress) + balanceService.getBalance(newAddress) ) t.equal(newAddressBalance, 0, 'newSeed balance = 0') const richAddressBalance = await run( 'getBalance (richAddress)', - getBalance(entropy, richAddress) + balanceService.getBalance(richAddress) ) t.true(richAddressBalance > BigInt(10e10), 'richAddress balance >>> 0') /* getBalances */ const balances = await run( 'getBalances', - getBalances(entropy, [newAddress, richAddress]) + balanceService.getBalances([newAddress, richAddress]) ) t.deepEqual( balances, @@ -40,7 +40,7 @@ test('getBalance + getBalances', async (t) => { const badAddresses = ['5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhr', '5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhrfnD'] const balancesWithNoGoodAddress = await run( 'getBalances::one good address', - getBalances(entropy, badAddresses) + balanceService.getBalances(badAddresses) ) badAddresses.forEach(addr => { diff --git a/tests/testing-utils/setup-test.ts b/tests/testing-utils/setup-test.ts index b2e3206f..ec2e59ce 100644 --- a/tests/testing-utils/setup-test.ts +++ b/tests/testing-utils/setup-test.ts @@ -12,16 +12,18 @@ import { makeSeed, promiseRunner, sleep } from './' interface SetupTestOpts { configPath?: string networkType?: string - seed?: string, + seed?: string + endpoint?: string } const NETWORK_TYPE_DEFAULT = 'two-nodes' let counter = 0 -export async function setupTest (t: Test, opts?: SetupTestOpts): Promise<{ entropy: Entropy; run: any }> { +export async function setupTest (t: Test, opts?: SetupTestOpts): Promise<{ entropy: Entropy; run: any; endpoint: string }> { const { configPath = `/tmp/entropy-cli-${Date.now()}_${counter++}.json`, networkType = NETWORK_TYPE_DEFAULT, - seed = makeSeed() + seed = makeSeed(), + endpoint = 'ws://127.0.0.1:9944', } = opts || {} const run = promiseRunner(t) @@ -45,11 +47,11 @@ export async function setupTest (t: Test, opts?: SetupTestOpts): Promise<{ entro const keyring = new Keyring({ seed, debug: true }) const entropy = await initializeEntropy({ keyMaterial: keyring.getAccount(), - endpoint: 'ws://127.0.0.1:9944', + endpoint, configPath }) await run('entropy ready', entropy.ready) - return { entropy, run } + return { entropy, run, endpoint } } diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index 83379bc2..1cb666b7 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -11,12 +11,13 @@ import { spinNetworkDown } from './testing-utils' -import { getBalance } from '../src/flows/balance/balance' import { initializeEntropy } from 'src/common/initializeEntropy' import { charlieStashAddress, charlieStashSeed } from './testing-utils/constants' import { transfer } from 'src/flows/entropyTransfer/transfer' +import { BalanceService } from 'src/balance/utils' const networkType = 'two-nodes' +const endpoint = 'ws://127.0.0.1:9944' test('Transfer', async (t) => { /* Setup */ @@ -37,8 +38,9 @@ test('Transfer', async (t) => { const naynayKeyring = new Keyring({ seed: naynaySeed, debug: true }) const charlieKeyring = new Keyring({ seed: charlieStashSeed, debug: true }) - const entropy = await initializeEntropy({ keyMaterial: naynayKeyring.getAccount(), endpoint: 'ws://127.0.0.1:9944', }) - const charlieEntropy = await initializeEntropy({ keyMaterial: charlieKeyring.getAccount(), endpoint: 'ws://127.0.0.1:9944', }) + const entropy = await initializeEntropy({ keyMaterial: naynayKeyring.getAccount(), endpoint, }) + const charlieEntropy = await initializeEntropy({ keyMaterial: charlieKeyring.getAccount(), endpoint, }) + const balanceService = new BalanceService(entropy, endpoint) await run('entropy ready', entropy.ready) await run('charlie ready', charlieEntropy.ready) @@ -47,14 +49,14 @@ test('Transfer', async (t) => { // Check Balance of new account let naynayBalance = await run( 'getBalance (naynay)', - getBalance(entropy, recipientAddress) + balanceService.getBalance(recipientAddress) ) t.equal(naynayBalance, 0, 'naynay is broke') let charlieBalance = await run( 'getBalance (charlieStash)', - getBalance(entropy, charlieStashAddress) + balanceService.getBalance(charlieStashAddress) ) t.equal(charlieBalance, 1e17, 'charlie got bank') @@ -73,7 +75,7 @@ test('Transfer', async (t) => { // Re-Check Balance of new account naynayBalance = await run( 'getBalance (naynay)', - getBalance(entropy, recipientAddress) + balanceService.getBalance(recipientAddress) ) t.equal(naynayBalance, 1000 * 10e10, 'naynay is rolling in it!') From 5d647293cdf1cc66fd0d02375a75cbec5f7598ef Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 31 Jul 2024 16:23:14 -0400 Subject: [PATCH 02/14] updated naming scheme for command, utils and base class --- src/balance/command.ts | 12 ++++++------ src/balance/utils.ts | 4 ++-- src/common/{entropy-base.ts => base.ts} | 2 +- src/flows/balance/cli.ts | 4 ++-- src/flows/balance/index.ts | 4 ++-- tests/balance.test.ts | 4 ++-- tests/transfer.test.ts | 4 ++-- 7 files changed, 17 insertions(+), 17 deletions(-) rename src/common/{entropy-base.ts => base.ts} (89%) diff --git a/src/balance/command.ts b/src/balance/command.ts index 09f96d4f..4d0f3aea 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -1,20 +1,20 @@ import Entropy from "@entropyxyz/sdk" -import { EntropyBase } from "../common/entropy-base" -import { BalanceService } from "./utils" +import { Base } from "../common/base" +import { BalanceUtils } from "./utils" import { FLOW_CONTEXT } from "./constants" -export class BalanceController extends EntropyBase { - private readonly balanceService: BalanceService +export class BalanceCommand extends Base { + private readonly balanceService: BalanceUtils constructor (entropy: Entropy, endpoint: string) { super(entropy, endpoint, FLOW_CONTEXT) - this.balanceService = new BalanceService(this.entropy, endpoint) + this.balanceService = new BalanceUtils(this.entropy, endpoint) } public async getBalance (address: string) { const balance = await this.balanceService.getBalance(address) - this.logger.log(`Current balance of ${address}: ${balance}`, `${BalanceController.name}`) + this.logger.log(`Current balance of ${address}: ${balance}`, `${BalanceCommand.name}`) return `${balance.toLocaleString('en-US')} BITS` } diff --git a/src/balance/utils.ts b/src/balance/utils.ts index 4b809dcd..56c721bf 100644 --- a/src/balance/utils.ts +++ b/src/balance/utils.ts @@ -1,11 +1,11 @@ import Entropy from "@entropyxyz/sdk"; -import { EntropyBase } from "../common/entropy-base"; +import { Base } from "../common/base"; import { BalanceInfo } from "./types"; import { FLOW_CONTEXT } from "./constants"; const hexToBigInt = (hexString: string) => BigInt(hexString) -export class BalanceService extends EntropyBase { +export class BalanceUtils extends Base { constructor (entropy: Entropy, endpoint: string) { super(entropy, endpoint, FLOW_CONTEXT) } diff --git a/src/common/entropy-base.ts b/src/common/base.ts similarity index 89% rename from src/common/entropy-base.ts rename to src/common/base.ts index 1e14bf3b..3b264cb9 100644 --- a/src/common/entropy-base.ts +++ b/src/common/base.ts @@ -1,7 +1,7 @@ import Entropy from "@entropyxyz/sdk"; import { EntropyLogger } from "./logger"; -export abstract class EntropyBase { +export abstract class Base { protected logger: EntropyLogger protected entropy: Entropy diff --git a/src/flows/balance/cli.ts b/src/flows/balance/cli.ts index 78fa71a2..d677a2bc 100644 --- a/src/flows/balance/cli.ts +++ b/src/flows/balance/cli.ts @@ -1,4 +1,4 @@ -import { BalanceController } from 'src/balance/command' +import { BalanceCommand } from 'src/balance/command' import { initializeEntropy } from '../../common/initializeEntropy' import * as config from '../../config' import { EntropyLogger } from 'src/common/logger' @@ -19,7 +19,7 @@ export async function cliGetBalance ({ address, password, endpoint }) { } const entropy = await initializeEntropy({ keyMaterial: account.data, password, endpoint }) - const balanceController = new BalanceController(entropy, endpoint) + const balanceController = new BalanceCommand(entropy, endpoint) const balance = await balanceController.getBalance(address) return balance diff --git a/src/flows/balance/index.ts b/src/flows/balance/index.ts index b13557ac..210b34be 100644 --- a/src/flows/balance/index.ts +++ b/src/flows/balance/index.ts @@ -1,7 +1,7 @@ import { EntropyLogger } from "src/common/logger"; import { initializeEntropy } from "../../common/initializeEntropy" import { print, getSelectedAccount } from "../../common/utils" -import { BalanceController } from "src/balance/command"; +import { BalanceCommand } from "src/balance/command"; // TO-DO: setup flow method to provide options to allow users to select account, // use external address, or get balances for all accounts in config @@ -15,7 +15,7 @@ export async function checkBalance ({ accounts, selectedAccount: selectedAccount const selectedAccount = getSelectedAccount(accounts, selectedAccountAddress) logger.log(selectedAccount, FLOW_CONTEXT) const entropy = await initializeEntropy({ keyMaterial: selectedAccount.data, endpoint }); - const balanceController = new BalanceController(entropy, endpoint) + const balanceController = new BalanceCommand(entropy, endpoint) const accountAddress = selectedAccountAddress const freeBalanceString = await balanceController.getBalance(accountAddress) print(`Address ${accountAddress} has a balance of: ${freeBalanceString}`) diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 3b77d141..4c2e67e5 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -1,13 +1,13 @@ import test from 'tape' import { setupTest, charlieStashAddress as richAddress } from './testing-utils' -import { BalanceService } from 'src/balance/utils' +import { BalanceUtils } from 'src/balance/utils' const networkType = 'two-nodes' test('getBalance + getBalances', async (t) => { const { run, entropy, endpoint } = await setupTest(t, { networkType }) - const balanceService = new BalanceService(entropy, endpoint) + const balanceService = new BalanceUtils(entropy, endpoint) const newAddress = entropy.keyring.accounts.registration.address /* getBalance */ diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index 1cb666b7..4d1bc798 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -14,7 +14,7 @@ import { import { initializeEntropy } from 'src/common/initializeEntropy' import { charlieStashAddress, charlieStashSeed } from './testing-utils/constants' import { transfer } from 'src/flows/entropyTransfer/transfer' -import { BalanceService } from 'src/balance/utils' +import { BalanceUtils } from 'src/balance/utils' const networkType = 'two-nodes' const endpoint = 'ws://127.0.0.1:9944' @@ -40,7 +40,7 @@ test('Transfer', async (t) => { const entropy = await initializeEntropy({ keyMaterial: naynayKeyring.getAccount(), endpoint, }) const charlieEntropy = await initializeEntropy({ keyMaterial: charlieKeyring.getAccount(), endpoint, }) - const balanceService = new BalanceService(entropy, endpoint) + const balanceService = new BalanceUtils(entropy, endpoint) await run('entropy ready', entropy.ready) await run('charlie ready', charlieEntropy.ready) From 366072b0e728fd6baa8d36331208f6a5be76efe2 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 31 Jul 2024 16:25:32 -0400 Subject: [PATCH 03/14] more naming changes --- tests/balance.test.ts | 10 +++++----- tests/transfer.test.ts | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 4c2e67e5..f609ddba 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -7,26 +7,26 @@ const networkType = 'two-nodes' test('getBalance + getBalances', async (t) => { const { run, entropy, endpoint } = await setupTest(t, { networkType }) - const balanceService = new BalanceUtils(entropy, endpoint) + const balanceUtils = new BalanceUtils(entropy, endpoint) const newAddress = entropy.keyring.accounts.registration.address /* getBalance */ const newAddressBalance = await run( 'getBalance (newSeed)', - balanceService.getBalance(newAddress) + balanceUtils.getBalance(newAddress) ) t.equal(newAddressBalance, 0, 'newSeed balance = 0') const richAddressBalance = await run( 'getBalance (richAddress)', - balanceService.getBalance(richAddress) + balanceUtils.getBalance(richAddress) ) t.true(richAddressBalance > BigInt(10e10), 'richAddress balance >>> 0') /* getBalances */ const balances = await run( 'getBalances', - balanceService.getBalances([newAddress, richAddress]) + balanceUtils.getBalances([newAddress, richAddress]) ) t.deepEqual( balances, @@ -40,7 +40,7 @@ test('getBalance + getBalances', async (t) => { const badAddresses = ['5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhr', '5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhrfnD'] const balancesWithNoGoodAddress = await run( 'getBalances::one good address', - balanceService.getBalances(badAddresses) + balanceUtils.getBalances(badAddresses) ) badAddresses.forEach(addr => { diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index 4d1bc798..d0c12101 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -40,7 +40,7 @@ test('Transfer', async (t) => { const entropy = await initializeEntropy({ keyMaterial: naynayKeyring.getAccount(), endpoint, }) const charlieEntropy = await initializeEntropy({ keyMaterial: charlieKeyring.getAccount(), endpoint, }) - const balanceService = new BalanceUtils(entropy, endpoint) + const balanceUtils = new BalanceUtils(entropy, endpoint) await run('entropy ready', entropy.ready) await run('charlie ready', charlieEntropy.ready) @@ -49,14 +49,14 @@ test('Transfer', async (t) => { // Check Balance of new account let naynayBalance = await run( 'getBalance (naynay)', - balanceService.getBalance(recipientAddress) + balanceUtils.getBalance(recipientAddress) ) t.equal(naynayBalance, 0, 'naynay is broke') let charlieBalance = await run( 'getBalance (charlieStash)', - balanceService.getBalance(charlieStashAddress) + balanceUtils.getBalance(charlieStashAddress) ) t.equal(charlieBalance, 1e17, 'charlie got bank') @@ -75,7 +75,7 @@ test('Transfer', async (t) => { // Re-Check Balance of new account naynayBalance = await run( 'getBalance (naynay)', - balanceService.getBalance(recipientAddress) + balanceUtils.getBalance(recipientAddress) ) t.equal(naynayBalance, 1000 * 10e10, 'naynay is rolling in it!') From cd1b81743445f2e4d611a7e7fd102e98ab2cf0a4 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 31 Jul 2024 16:30:51 -0400 Subject: [PATCH 04/14] changelog updated --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 248b0cbd..50d596c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,10 +27,13 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil - new: 'src/flows/user-program-management/view.ts' - service file for pure functions of viewing user programs - new: 'src/flows/user-program-management/helpers/utils.ts' - utility helper file for user program management specific methods - new: './src/flows/user-program-management/remove.ts' - service file for removing user program pure function +- new: './src/common/base.ts' - base abstract class for new command and utils classes +- new: './src/balance' - new file structure for our CLI/TUI flows ### Changed - folder name for user programs to match the kebab-case style for folder namespace - updated SDK version to v0.2.3 +- logger to handle nested contexts for better organization of logs ## [0.0.3] Blade - 2024-07-17 (entropy-core compatibility: 0.2.0) From c0fbd87efd7ba78b5195e56132136ea158aa9ab7 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 31 Jul 2024 16:33:18 -0400 Subject: [PATCH 05/14] naming is fun --- src/flows/balance/cli.ts | 4 ++-- src/flows/balance/index.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/flows/balance/cli.ts b/src/flows/balance/cli.ts index d677a2bc..99e7879e 100644 --- a/src/flows/balance/cli.ts +++ b/src/flows/balance/cli.ts @@ -19,8 +19,8 @@ export async function cliGetBalance ({ address, password, endpoint }) { } const entropy = await initializeEntropy({ keyMaterial: account.data, password, endpoint }) - const balanceController = new BalanceCommand(entropy, endpoint) - const balance = await balanceController.getBalance(address) + const balanceCommand = new BalanceCommand(entropy, endpoint) + const balance = await balanceCommand.getBalance(address) return balance } diff --git a/src/flows/balance/index.ts b/src/flows/balance/index.ts index 210b34be..fda87176 100644 --- a/src/flows/balance/index.ts +++ b/src/flows/balance/index.ts @@ -15,8 +15,8 @@ export async function checkBalance ({ accounts, selectedAccount: selectedAccount const selectedAccount = getSelectedAccount(accounts, selectedAccountAddress) logger.log(selectedAccount, FLOW_CONTEXT) const entropy = await initializeEntropy({ keyMaterial: selectedAccount.data, endpoint }); - const balanceController = new BalanceCommand(entropy, endpoint) + const balanceCommand = new BalanceCommand(entropy, endpoint) const accountAddress = selectedAccountAddress - const freeBalanceString = await balanceController.getBalance(accountAddress) + const freeBalanceString = await balanceCommand.getBalance(accountAddress) print(`Address ${accountAddress} has a balance of: ${freeBalanceString}`) } From 05c82ed0e840e7d0eb5c211e043e7c08c3f8ab90 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 31 Jul 2024 21:21:07 -0400 Subject: [PATCH 06/14] updated utils to be pure functions rather than class; updated tests; updated changelog --- CHANGELOG.md | 4 ++- src/balance/command.ts | 11 +++--- src/balance/utils.ts | 46 +++++++------------------ src/common/{base.ts => base-command.ts} | 2 +- tests/balance.test.ts | 11 +++--- tests/transfer.test.ts | 9 +++-- 6 files changed, 30 insertions(+), 53 deletions(-) rename src/common/{base.ts => base-command.ts} (89%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50d596c7..f87a58f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,8 +27,10 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil - new: 'src/flows/user-program-management/view.ts' - service file for pure functions of viewing user programs - new: 'src/flows/user-program-management/helpers/utils.ts' - utility helper file for user program management specific methods - new: './src/flows/user-program-management/remove.ts' - service file for removing user program pure function -- new: './src/common/base.ts' - base abstract class for new command and utils classes +- new: './src/common/base.ts' - base abstract class for new command classes - new: './src/balance' - new file structure for our CLI/TUI flows + - new: './src/balance/command.ts' - main entry file for balance command for tui/cli + - new: './src/balance/utils.ts' - utilities and helper methods for all things balance ### Changed - folder name for user programs to match the kebab-case style for folder namespace diff --git a/src/balance/command.ts b/src/balance/command.ts index 4d0f3aea..cab1adf7 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -1,18 +1,15 @@ import Entropy from "@entropyxyz/sdk" -import { Base } from "../common/base" -import { BalanceUtils } from "./utils" +import { BaseCommand } from "../common/base-command" +import * as BalanceUtils from "./utils" import { FLOW_CONTEXT } from "./constants" -export class BalanceCommand extends Base { - private readonly balanceService: BalanceUtils - +export class BalanceCommand extends BaseCommand { constructor (entropy: Entropy, endpoint: string) { super(entropy, endpoint, FLOW_CONTEXT) - this.balanceService = new BalanceUtils(this.entropy, endpoint) } public async getBalance (address: string) { - const balance = await this.balanceService.getBalance(address) + const balance = await BalanceUtils.getBalance(this.entropy, address) this.logger.log(`Current balance of ${address}: ${balance}`, `${BalanceCommand.name}`) diff --git a/src/balance/utils.ts b/src/balance/utils.ts index 56c721bf..917d0840 100644 --- a/src/balance/utils.ts +++ b/src/balance/utils.ts @@ -1,44 +1,24 @@ import Entropy from "@entropyxyz/sdk"; -import { Base } from "../common/base"; import { BalanceInfo } from "./types"; -import { FLOW_CONTEXT } from "./constants"; const hexToBigInt = (hexString: string) => BigInt(hexString) -export class BalanceUtils extends Base { - constructor (entropy: Entropy, endpoint: string) { - super(entropy, endpoint, FLOW_CONTEXT) - } +export async function getBalance (entropy: Entropy, address: string): Promise { + const accountInfo = (await entropy.substrate.query.system.account(address)) as any + return parseInt(hexToBigInt(accountInfo.data.free).toString()) +} - public async getBalance (address: string): Promise { +export async function getBalances (entropy: Entropy, addresses: string[]): Promise { + const balanceInfo: BalanceInfo = {} + await Promise.all(addresses.map(async address => { try { - const accountInfo = (await this.entropy.substrate.query.system.account(address)) as any + const balance = await getBalance(entropy, address) - return parseInt(hexToBigInt(accountInfo.data.free).toString()) + balanceInfo[address] = { balance } } catch (error) { - this.logger.error(`There was an error getting balance for [acct = ${address}]`, error); - throw new Error(error.message) + balanceInfo[address] = { error: error.message } } - } - - public async getBalances (addresses: string[]): Promise { - const balanceInfo: BalanceInfo = {} - try { - await Promise.all(addresses.map(async address => { - try { - const balance = await this.getBalance(address) - - balanceInfo[address] = { balance } - } catch (error) { - this.logger.error(`Error retrieving balance for ${address}`, error); - balanceInfo[address] = { error: error.message } - } - })) - - return balanceInfo - } catch (error) { - this.logger.error(`There was an error getting balances for [${addresses}]`, error); - throw new Error(error.message) - } - } + })) + + return balanceInfo } \ No newline at end of file diff --git a/src/common/base.ts b/src/common/base-command.ts similarity index 89% rename from src/common/base.ts rename to src/common/base-command.ts index 3b264cb9..ded342e4 100644 --- a/src/common/base.ts +++ b/src/common/base-command.ts @@ -1,7 +1,7 @@ import Entropy from "@entropyxyz/sdk"; import { EntropyLogger } from "./logger"; -export abstract class Base { +export abstract class BaseCommand { protected logger: EntropyLogger protected entropy: Entropy diff --git a/tests/balance.test.ts b/tests/balance.test.ts index f609ddba..2fe9e39b 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -1,32 +1,31 @@ import test from 'tape' import { setupTest, charlieStashAddress as richAddress } from './testing-utils' -import { BalanceUtils } from 'src/balance/utils' +import * as BalanceUtils from 'src/balance/utils' const networkType = 'two-nodes' test('getBalance + getBalances', async (t) => { const { run, entropy, endpoint } = await setupTest(t, { networkType }) - const balanceUtils = new BalanceUtils(entropy, endpoint) const newAddress = entropy.keyring.accounts.registration.address /* getBalance */ const newAddressBalance = await run( 'getBalance (newSeed)', - balanceUtils.getBalance(newAddress) + BalanceUtils.getBalance(entropy, newAddress) ) t.equal(newAddressBalance, 0, 'newSeed balance = 0') const richAddressBalance = await run( 'getBalance (richAddress)', - balanceUtils.getBalance(richAddress) + BalanceUtils.getBalance(entropy, richAddress) ) t.true(richAddressBalance > BigInt(10e10), 'richAddress balance >>> 0') /* getBalances */ const balances = await run( 'getBalances', - balanceUtils.getBalances([newAddress, richAddress]) + BalanceUtils.getBalances(entropy, [newAddress, richAddress]) ) t.deepEqual( balances, @@ -40,7 +39,7 @@ test('getBalance + getBalances', async (t) => { const badAddresses = ['5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhr', '5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhrfnD'] const balancesWithNoGoodAddress = await run( 'getBalances::one good address', - balanceUtils.getBalances(badAddresses) + BalanceUtils.getBalances(entropy, badAddresses) ) badAddresses.forEach(addr => { diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index d0c12101..22a0fe86 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -14,7 +14,7 @@ import { import { initializeEntropy } from 'src/common/initializeEntropy' import { charlieStashAddress, charlieStashSeed } from './testing-utils/constants' import { transfer } from 'src/flows/entropyTransfer/transfer' -import { BalanceUtils } from 'src/balance/utils' +import * as BalanceUtils from 'src/balance/utils' const networkType = 'two-nodes' const endpoint = 'ws://127.0.0.1:9944' @@ -40,7 +40,6 @@ test('Transfer', async (t) => { const entropy = await initializeEntropy({ keyMaterial: naynayKeyring.getAccount(), endpoint, }) const charlieEntropy = await initializeEntropy({ keyMaterial: charlieKeyring.getAccount(), endpoint, }) - const balanceUtils = new BalanceUtils(entropy, endpoint) await run('entropy ready', entropy.ready) await run('charlie ready', charlieEntropy.ready) @@ -49,14 +48,14 @@ test('Transfer', async (t) => { // Check Balance of new account let naynayBalance = await run( 'getBalance (naynay)', - balanceUtils.getBalance(recipientAddress) + BalanceUtils.getBalance(entropy, recipientAddress) ) t.equal(naynayBalance, 0, 'naynay is broke') let charlieBalance = await run( 'getBalance (charlieStash)', - balanceUtils.getBalance(charlieStashAddress) + BalanceUtils.getBalance(entropy, charlieStashAddress) ) t.equal(charlieBalance, 1e17, 'charlie got bank') @@ -75,7 +74,7 @@ test('Transfer', async (t) => { // Re-Check Balance of new account naynayBalance = await run( 'getBalance (naynay)', - balanceUtils.getBalance(recipientAddress) + BalanceUtils.getBalance(entropy, recipientAddress) ) t.equal(naynayBalance, 1000 * 10e10, 'naynay is rolling in it!') From e8aef10214132aa14eef2dbba52a618016e06fcc Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 31 Jul 2024 22:20:45 -0400 Subject: [PATCH 07/14] Update CHANGELOG.md Co-authored-by: mix irving --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f87a58f1..f3a286a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil - new: 'src/flows/user-program-management/view.ts' - service file for pure functions of viewing user programs - new: 'src/flows/user-program-management/helpers/utils.ts' - utility helper file for user program management specific methods - new: './src/flows/user-program-management/remove.ts' - service file for removing user program pure function -- new: './src/common/base.ts' - base abstract class for new command classes +- new: './src/common/base-commands.ts' - base abstract class for new command classes - new: './src/balance' - new file structure for our CLI/TUI flows - new: './src/balance/command.ts' - main entry file for balance command for tui/cli - new: './src/balance/utils.ts' - utilities and helper methods for all things balance From f1b87f4abbb0cd7e3ae92922fbe3b1bbecf9117b Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 31 Jul 2024 22:43:16 -0400 Subject: [PATCH 08/14] lint errors --- tests/balance.test.ts | 2 +- tests/testing-utils/setup-test.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 2fe9e39b..f95d7e16 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -1,7 +1,7 @@ import test from 'tape' import { setupTest, charlieStashAddress as richAddress } from './testing-utils' -import * as BalanceUtils from 'src/balance/utils' +import * as BalanceUtils from '../src/balance/utils' const networkType = 'two-nodes' diff --git a/tests/testing-utils/setup-test.ts b/tests/testing-utils/setup-test.ts index dffc28b0..36391127 100644 --- a/tests/testing-utils/setup-test.ts +++ b/tests/testing-utils/setup-test.ts @@ -44,6 +44,7 @@ export async function setupTest (t: Test, opts?: SetupTestOpts): Promise<{ entro // as done in src/flows/manage-accounts/new-key.ts const keyring = new Keyring({ seed, debug: true }) const entropy = await initializeEntropy({ + // @ts-expect-error keyMaterial: keyring.getAccount(), endpoint, configPath From 67c33cb922ca33712f2d55f033354d0f51a96341 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Thu, 1 Aug 2024 15:30:48 -0400 Subject: [PATCH 09/14] added lifecycle hook to main entropy entry point to load entropy instance on every command; used to be passed down to each of the commands; added new option to define new address as selected account --- src/cli.ts | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- src/tui.ts | 11 ++++++----- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index f8dab60c..8d9ce7a4 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -10,7 +10,9 @@ import { cliGetBalance } from './flows/balance/cli' import { cliListAccounts } from './flows/manage-accounts/cli' import { cliEntropyTransfer } from './flows/entropyTransfer/cli' import { cliSign } from './flows/sign/cli' -import { stringify } from './common/utils' +import { getSelectedAccount, stringify } from './common/utils' +import Entropy from '@entropyxyz/sdk' +import { initializeEntropy } from './common/initializeEntropy' const program = new Command() @@ -45,11 +47,40 @@ function passwordOption (description?: string) { ) } +function currentAccountAddressOption () { + const storedConfig = config.getSync() + return new Option( + '-a, --account ', + 'Sets the current account for the session or defaults to the account stored in the config' + ) + .env('ACCOUNT_ADDRESS') + .argParser(async (address) => { + if (address === storedConfig.selectedAccount) return address + // Updated selected account in config with new address from this option + const newConfigUpdates = { selectedAccount: address } + await config.set({ ...storedConfig, ...newConfigUpdates }) + + return address + }) + .hideHelp() + .default(storedConfig.selectedAccount) +} + +let entropy: Entropy + +async function loadEntropy (address: string, endpoint: string, password: string) { + const storedConfig = config.getSync() + const selectedAccount = getSelectedAccount(storedConfig.accounts, address) + + entropy = await initializeEntropy({ keyMaterial: selectedAccount.data, endpoint, password }) +} + /* no command */ program .name('entropy') .description('CLI interface for interacting with entropy.xyz. Running without commands starts an interactive ui') .addOption(endpointOption()) + .addOption(currentAccountAddressOption()) .addOption( new Option( '-d, --dev', @@ -58,8 +89,19 @@ program .env('DEV_MODE') .hideHelp() ) + .hook('preAction', async (_thisCommand, actionCommand) => { + if (!entropy || (entropy.keyring.accounts.registration.address !== actionCommand.args[0] || entropy.keyring.accounts.registration.address !== actionCommand.opts().account)) { + // balance includes an address argument, use that address to instantiate entropy + if (actionCommand.name() === 'balance') { + await loadEntropy(actionCommand.args[0], actionCommand.opts().endpoint, actionCommand.opts().password) + } else { + // if address is not an argument, use the address from the option + await loadEntropy(actionCommand.opts().account, actionCommand.opts().endpoint, actionCommand.opts().password) + } + } + }) .action((options: EntropyTuiOptions) => { - launchTui(options) + launchTui(entropy, options) }) /* list */ @@ -93,6 +135,7 @@ program.command('transfer') .argument('amount', 'Amount of funds to be moved') .addOption(passwordOption('Password for the source account (if required)')) .addOption(endpointOption()) + .addOption(currentAccountAddressOption()) .action(async (source, destination, amount, opts) => { await cliEntropyTransfer({ source, destination, amount, ...opts }) // writeOut(??) // TODO: write the output @@ -106,6 +149,7 @@ program.command('sign') .argument('message', 'Message you would like to sign') .addOption(passwordOption('Password for the source account (if required)')) .addOption(endpointOption()) + .addOption(currentAccountAddressOption()) .action(async (address, message, opts) => { const signature = await cliSign({ address, message, ...opts }) writeOut(signature) @@ -117,4 +161,4 @@ function writeOut (result) { process.stdout.write(prettyResult) } -program.parse() +program.parseAsync().then(() => {}) diff --git a/src/tui.ts b/src/tui.ts index 746640fa..339c010f 100644 --- a/src/tui.ts +++ b/src/tui.ts @@ -1,4 +1,5 @@ import inquirer from 'inquirer' +import Entropy from '@entropyxyz/sdk' import * as config from './config' import * as flows from './flows' import { EntropyTuiOptions } from './types' @@ -9,9 +10,9 @@ import { EntropyLogger } from './common/logger' let shouldInit = true // tui = text user interface -export default function tui (options: EntropyTuiOptions) { +export default function tui (entropy: Entropy, options: EntropyTuiOptions) { const logger = new EntropyLogger('TUI', options.endpoint) - console.clear() + // console.clear() console.log(logo) // the Entropy logo logger.debug(options) @@ -36,10 +37,10 @@ export default function tui (options: EntropyTuiOptions) { // assign exit so its last Object.assign(choices, { 'Exit': async () => {} }) - main(choices, options, logger) + main(entropy, choices, options, logger) } -async function main (choices, options, logger: EntropyLogger) { +async function main (entropy: Entropy, choices, options, logger: EntropyLogger) { if (shouldInit) { await config.init() shouldInit = false @@ -90,7 +91,7 @@ async function main (choices, options, logger: EntropyLogger) { }])) } - if (returnToMain) main(choices, options, logger) + if (returnToMain) main(entropy, choices, options, logger) else { print('Have a nice day') process.exit() From d6d8d76c8d6696aaca9965afa9241918f49c915c Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Thu, 1 Aug 2024 15:53:01 -0400 Subject: [PATCH 10/14] updated tui and cli to be the main source of entry for everything and removed flows/balance directory --- src/cli.ts | 14 +++++++++++--- src/flows/balance/cli.ts | 27 --------------------------- src/flows/balance/index.ts | 22 ---------------------- src/flows/index.ts | 1 - src/tui.ts | 27 ++++++++++++++++++++------- 5 files changed, 31 insertions(+), 60 deletions(-) delete mode 100644 src/flows/balance/cli.ts delete mode 100644 src/flows/balance/index.ts diff --git a/src/cli.ts b/src/cli.ts index 8d9ce7a4..f0f56424 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -6,13 +6,13 @@ import launchTui from './tui' import * as config from './config' import { EntropyTuiOptions } from './types' -import { cliGetBalance } from './flows/balance/cli' import { cliListAccounts } from './flows/manage-accounts/cli' import { cliEntropyTransfer } from './flows/entropyTransfer/cli' import { cliSign } from './flows/sign/cli' import { getSelectedAccount, stringify } from './common/utils' import Entropy from '@entropyxyz/sdk' import { initializeEntropy } from './common/initializeEntropy' +import { BalanceCommand } from './balance/command' const program = new Command() @@ -72,6 +72,13 @@ async function loadEntropy (address: string, endpoint: string, password: string) const storedConfig = config.getSync() const selectedAccount = getSelectedAccount(storedConfig.accounts, address) + if (!selectedAccount) throw Error(`No account with address ${address}`) + + // check if data is encrypted + we have a password + if (typeof selectedAccount.data === 'string' && !password) { + throw Error('This account requires a password, add --password ') + } + entropy = await initializeEntropy({ keyMaterial: selectedAccount.data, endpoint, password }) } @@ -92,7 +99,7 @@ program .hook('preAction', async (_thisCommand, actionCommand) => { if (!entropy || (entropy.keyring.accounts.registration.address !== actionCommand.args[0] || entropy.keyring.accounts.registration.address !== actionCommand.opts().account)) { // balance includes an address argument, use that address to instantiate entropy - if (actionCommand.name() === 'balance') { + if (actionCommand.name() === 'balance' && actionCommand.args.length) { await loadEntropy(actionCommand.args[0], actionCommand.opts().endpoint, actionCommand.opts().password) } else { // if address is not an argument, use the address from the option @@ -122,7 +129,8 @@ program.command('balance') .addOption(passwordOption()) .addOption(endpointOption()) .action(async (address, opts) => { - const balance = await cliGetBalance({ address, ...opts }) + const balanceCommand = new BalanceCommand(entropy, opts.endpoint) + const balance = await balanceCommand.getBalance(address) writeOut(balance) process.exit(0) }) diff --git a/src/flows/balance/cli.ts b/src/flows/balance/cli.ts deleted file mode 100644 index 99e7879e..00000000 --- a/src/flows/balance/cli.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { BalanceCommand } from 'src/balance/command' -import { initializeEntropy } from '../../common/initializeEntropy' -import * as config from '../../config' -import { EntropyLogger } from 'src/common/logger' - -// TO-DO: move entropy initialization and account retrieval to a shared container -// should remove the need to initialize entropy every time -export async function cliGetBalance ({ address, password, endpoint }) { - const logger = new EntropyLogger('CLI::CHECK_BALANCE', endpoint) - const storedConfig = await config.get() - const account = storedConfig.accounts.find(account => account.address === address) - if (!account) throw Error(`No account with address ${address}`) - // QUESTION: is throwing the right response? - logger.debug('account', account) - - // check if data is encrypted + we have a password - if (typeof account.data === 'string' && !password) { - throw Error('This account requires a password, add --password ') - } - - const entropy = await initializeEntropy({ keyMaterial: account.data, password, endpoint }) - const balanceCommand = new BalanceCommand(entropy, endpoint) - const balance = await balanceCommand.getBalance(address) - - return balance -} - diff --git a/src/flows/balance/index.ts b/src/flows/balance/index.ts deleted file mode 100644 index fda87176..00000000 --- a/src/flows/balance/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { EntropyLogger } from "src/common/logger"; -import { initializeEntropy } from "../../common/initializeEntropy" -import { print, getSelectedAccount } from "../../common/utils" -import { BalanceCommand } from "src/balance/command"; - -// TO-DO: setup flow method to provide options to allow users to select account, -// use external address, or get balances for all accounts in config -// TO-DO: move entropy initialization and account retrieval to a shared container -// should remove the need to initialize entropy every time -export async function checkBalance ({ accounts, selectedAccount: selectedAccountAddress }, options, logger: EntropyLogger) { - const FLOW_CONTEXT = 'CHECK_BALANCE' - const { endpoint } = options - logger.debug(`endpoint: ${endpoint}`, FLOW_CONTEXT) - - const selectedAccount = getSelectedAccount(accounts, selectedAccountAddress) - logger.log(selectedAccount, FLOW_CONTEXT) - const entropy = await initializeEntropy({ keyMaterial: selectedAccount.data, endpoint }); - const balanceCommand = new BalanceCommand(entropy, endpoint) - const accountAddress = selectedAccountAddress - const freeBalanceString = await balanceCommand.getBalance(accountAddress) - print(`Address ${accountAddress} has a balance of: ${freeBalanceString}`) -} diff --git a/src/flows/index.ts b/src/flows/index.ts index 82c5a11e..1aac99a8 100644 --- a/src/flows/index.ts +++ b/src/flows/index.ts @@ -1,5 +1,4 @@ export { entropyFaucet } from './entropyFaucet' -export { checkBalance } from './balance' export { entropyRegister } from './register' export { userPrograms, devPrograms } from './programs' export { sign } from './sign' diff --git a/src/tui.ts b/src/tui.ts index 339c010f..ebb24acb 100644 --- a/src/tui.ts +++ b/src/tui.ts @@ -6,6 +6,7 @@ import { EntropyTuiOptions } from './types' import { logo } from './common/ascii' import { print } from './common/utils' import { EntropyLogger } from './common/logger' +import { BalanceCommand } from './balance/command' let shouldInit = true @@ -18,7 +19,8 @@ export default function tui (entropy: Entropy, options: EntropyTuiOptions) { const choices = { 'Manage Accounts': flows.manageAccounts, - 'Balance': flows.checkBalance, + // leaving as a noop function until all flows are restructured + 'Balance': () => {}, 'Register': flows.entropyRegister, 'Sign': flows.sign, 'Transfer': flows.entropyTransfer, @@ -74,13 +76,24 @@ async function main (entropy: Entropy, choices, options, logger: EntropyLogger) console.error('There are currently no accounts available, please create or import your new account using the Manage Accounts feature') } else { logger.debug(answers) - const newConfigUpdates = await choices[answers.choice](storedConfig, options, logger) - if (typeof newConfigUpdates === 'string' && newConfigUpdates === 'exit') { - returnToMain = true - } else { - await config.set({ ...storedConfig, ...newConfigUpdates }) + switch (answers.choice) { + case "Balance": { + const balanceCommand = new BalanceCommand(entropy, options.endpoint) + const balanceString = await balanceCommand.getBalance(storedConfig.selectedAccount) + print(`Address ${storedConfig.selectedAccount} has a balance of: ${balanceString}`) + break; + } + default: { + const newConfigUpdates = await choices[answers.choice](storedConfig, options, logger) + if (typeof newConfigUpdates === 'string' && newConfigUpdates === 'exit') { + returnToMain = true + } else { + await config.set({ ...storedConfig, ...newConfigUpdates }) + } + storedConfig = await config.get() + break; + } } - storedConfig = await config.get() } if (!returnToMain) { From aefe05e64ee548d44f6642be34fd8e91754dabe6 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Thu, 1 Aug 2024 16:03:06 -0400 Subject: [PATCH 11/14] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f93ac80..1a554011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil - updated SDK version to v0.2.3 - logger to handle nested contexts for better organization of logs - merged user + dev program folders + tests +- removed flows/balance/*.ts directory with file restructure ### Broke From 197a8151ea7437a92b6f29d18215378ac2f2265e Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Thu, 1 Aug 2024 18:04:49 -0400 Subject: [PATCH 12/14] undid commented code --- src/tui.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tui.ts b/src/tui.ts index ebb24acb..e22f71ac 100644 --- a/src/tui.ts +++ b/src/tui.ts @@ -13,7 +13,7 @@ let shouldInit = true // tui = text user interface export default function tui (entropy: Entropy, options: EntropyTuiOptions) { const logger = new EntropyLogger('TUI', options.endpoint) - // console.clear() + console.clear() console.log(logo) // the Entropy logo logger.debug(options) From 423631c279c87da91c0a856acf1402bf352ecd88 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Thu, 1 Aug 2024 18:17:03 -0400 Subject: [PATCH 13/14] little cleanup --- src/cli.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cli.ts b/src/cli.ts index f0f56424..5af9da0a 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -15,6 +15,8 @@ import { initializeEntropy } from './common/initializeEntropy' import { BalanceCommand } from './balance/command' const program = new Command() +// Array of restructured commands to make it easier to migrate them to the new "flow" +const RESTRUCTURED_COMMANDS = ['balance'] function endpointOption (){ return new Option( @@ -99,7 +101,8 @@ program .hook('preAction', async (_thisCommand, actionCommand) => { if (!entropy || (entropy.keyring.accounts.registration.address !== actionCommand.args[0] || entropy.keyring.accounts.registration.address !== actionCommand.opts().account)) { // balance includes an address argument, use that address to instantiate entropy - if (actionCommand.name() === 'balance' && actionCommand.args.length) { + // can keep the conditional to check for length of args, and use the first index since it is our pattern to have the address as the first argument + if (RESTRUCTURED_COMMANDS.includes(actionCommand.name()) && actionCommand.args.length) { await loadEntropy(actionCommand.args[0], actionCommand.opts().endpoint, actionCommand.opts().password) } else { // if address is not an argument, use the address from the option From ddbd6e32e2735d1fabe64714f840208e38daa594 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Thu, 1 Aug 2024 22:15:19 -0400 Subject: [PATCH 14/14] removed unnecessary constants file --- src/balance/command.ts | 2 +- src/balance/constants.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 src/balance/constants.ts diff --git a/src/balance/command.ts b/src/balance/command.ts index cab1adf7..d3c1a70f 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -1,8 +1,8 @@ import Entropy from "@entropyxyz/sdk" import { BaseCommand } from "../common/base-command" import * as BalanceUtils from "./utils" -import { FLOW_CONTEXT } from "./constants" +const FLOW_CONTEXT = 'ENTROPY-BALANCE' export class BalanceCommand extends BaseCommand { constructor (entropy: Entropy, endpoint: string) { super(entropy, endpoint, FLOW_CONTEXT) diff --git a/src/balance/constants.ts b/src/balance/constants.ts deleted file mode 100644 index 204e8cd2..00000000 --- a/src/balance/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const FLOW_CONTEXT = 'ENTROPY-BALANCE' \ No newline at end of file