diff --git a/CHANGELOG.md b/CHANGELOG.md index a6e9a9bc..9c5538e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,12 +27,22 @@ 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-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 +- new: './src/transfer' - new file structure for our CLI/TUI flows + - new: './src/transfer/command.ts' - main entry file for transfer command for tui/cli + - new: './src/transfer/utils.ts' - utilities and helper methods for all things transfer ### 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 - merged user + dev program folders + tests +- removed flows/balance/*.ts directory with file restructure +- removed flows/entropyTransfer/*.ts directory with file restructure ### Broke diff --git a/src/balance/command.ts b/src/balance/command.ts new file mode 100644 index 00000000..d3c1a70f --- /dev/null +++ b/src/balance/command.ts @@ -0,0 +1,18 @@ +import Entropy from "@entropyxyz/sdk" +import { BaseCommand } from "../common/base-command" +import * as BalanceUtils from "./utils" + +const FLOW_CONTEXT = 'ENTROPY-BALANCE' +export class BalanceCommand extends BaseCommand { + constructor (entropy: Entropy, endpoint: string) { + super(entropy, endpoint, FLOW_CONTEXT) + } + + public async getBalance (address: string) { + const balance = await BalanceUtils.getBalance(this.entropy, address) + + this.logger.log(`Current balance of ${address}: ${balance}`, `${BalanceCommand.name}`) + + return `${balance.toLocaleString('en-US')} BITS` + } +} \ 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..917d0840 --- /dev/null +++ b/src/balance/utils.ts @@ -0,0 +1,24 @@ +import Entropy from "@entropyxyz/sdk"; +import { BalanceInfo } from "./types"; + +const hexToBigInt = (hexString: string) => BigInt(hexString) + +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()) +} + +export async function getBalances (entropy: Entropy, addresses: string[]): Promise { + const balanceInfo: BalanceInfo = {} + await Promise.all(addresses.map(async address => { + try { + const balance = await getBalance(entropy, address) + + balanceInfo[address] = { balance } + } catch (error) { + balanceInfo[address] = { error: error.message } + } + })) + + return balanceInfo +} \ No newline at end of file diff --git a/src/cli.ts b/src/cli.ts index ec5e8cb1..61b26d51 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -4,22 +4,51 @@ import { Command, Option } from 'commander' import launchTui from './tui' import { EntropyTuiOptions } from './types' +import * as config from './config' -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 { cliWrite, passwordOption, endpointOption } from './cli/util' -import { entropyProgram } from './cli/commands' +import { cliWrite, passwordOption, endpointOption, currentAccountAddressOption } from './cli/util' +import { entropyProgram } from './cli/commands' // TODO move +import { getSelectedAccount, stringify } from './common/utils' +import Entropy from '@entropyxyz/sdk' +import { initializeEntropy } from './common/initializeEntropy' +import { BalanceCommand } from './balance/command' +import { TransferCommand } from './transfer/command' const program = new Command() +// Array of restructured commands to make it easier to migrate them to the new "flow" +const RESTRUCTURED_COMMANDS = ['balance'] + +let entropy: Entropy + +export async function loadEntropy (address: string, endpoint: string, password?: string): Promise { + 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 }) + + if (!entropy?.keyring?.accounts?.registration?.pair) { + throw new Error("Signer keypair is undefined or not properly initialized.") + } + + return entropy +} /* 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', @@ -28,8 +57,20 @@ 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 + // 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 + await loadEntropy(actionCommand.opts().account, actionCommand.opts().endpoint, actionCommand.opts().password) + } + } + }) .action((options: EntropyTuiOptions) => { - launchTui(options) + launchTui(entropy, options) }) /* Install commands */ @@ -58,8 +99,9 @@ program.command('balance') .addOption(passwordOption()) .addOption(endpointOption()) .action(async (address, opts) => { - const balance = await cliGetBalance({ address, ...opts }) - cliWrite(balance) + const balanceCommand = new BalanceCommand(entropy, opts.endpoint) + const balance = await balanceCommand.getBalance(address) + writeOut(balance) process.exit(0) }) @@ -71,8 +113,10 @@ program.command('transfer') .argument('amount', 'Amount of funds to be moved') .addOption(passwordOption('Password for the source account (if required)')) .addOption(endpointOption()) - .action(async (source, destination, amount, opts) => { - await cliEntropyTransfer({ source, destination, amount, ...opts }) + .addOption(currentAccountAddressOption()) + .action(async (_source, destination, amount, opts) => { + const transferCommand = new TransferCommand(entropy, opts.endpoint) + await transferCommand.sendTransfer(destination, amount) // writeOut(??) // TODO: write the output process.exit(0) }) @@ -84,10 +128,16 @@ 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 }) cliWrite(signature) process.exit(0) }) -program.parse() +program.parseAsync().then(() => {}) + +function writeOut (result) { + const prettyResult = stringify(result) + process.stdout.write(prettyResult) +} diff --git a/src/cli/util.ts b/src/cli/util.ts index f03ca322..cbfe96c8 100644 --- a/src/cli/util.ts +++ b/src/cli/util.ts @@ -38,6 +38,26 @@ export function passwordOption (description?: string) { ) } +export 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) +} + + export function aliasOrAddressOption () { return new Option( '-a, --address ', diff --git a/src/common/base-command.ts b/src/common/base-command.ts new file mode 100644 index 00000000..ded342e4 --- /dev/null +++ b/src/common/base-command.ts @@ -0,0 +1,12 @@ +import Entropy from "@entropyxyz/sdk"; +import { EntropyLogger } from "./logger"; + +export abstract class BaseCommand { + 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/common/progress.ts b/src/common/progress.ts index a2410501..bbdd6564 100644 --- a/src/common/progress.ts +++ b/src/common/progress.ts @@ -11,10 +11,10 @@ export function setupProgress (label: string): { start: () => void; stop: () => }) const start = () => { - // 160 was found through trial and error, don't believe there is a formula to + // 150 was found through trial and error, don't believe there is a formula to // determine the exact time it takes for the transaction to be processed and finalized // TO-DO: Change progress bar to loading animation? - b1.start(160, 0, { + b1.start(150, 0, { speed: "N/A" }) // update values 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 deleted file mode 100644 index 4bcb208d..00000000 --- a/src/flows/balance/cli.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { initializeEntropy } from '../../common/initializeEntropy' -import * as config from '../../config' -import { getBalance } from './balance' -import { EntropyLogger } from 'src/common/logger' - -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 balance = await getBalance(entropy, address) - - return `${balance.toLocaleString('en-US')} BITS` -} - diff --git a/src/flows/balance/index.ts b/src/flows/balance/index.ts deleted file mode 100644 index 0481c86e..00000000 --- a/src/flows/balance/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { EntropyLogger } from "src/common/logger"; -import { initializeEntropy } from "../../common/initializeEntropy" -import { print, getSelectedAccount } from "../../common/utils" -import { getBalance } from "./balance"; - -// 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 -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 accountAddress = selectedAccountAddress - const freeBalance = await getBalance(entropy, accountAddress) - print(`Address ${accountAddress} has a balance of: ${freeBalance.toLocaleString('en-US')} BITS`) -} diff --git a/src/flows/entropyTransfer/cli.ts b/src/flows/entropyTransfer/cli.ts deleted file mode 100644 index 1a0abe51..00000000 --- a/src/flows/entropyTransfer/cli.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { initializeEntropy } from '../../common/initializeEntropy' -import * as config from '../../config' -import { formatAmountAsHex } from '../../common/utils' -import { EntropyLogger } from 'src/common/logger' - -export async function cliEntropyTransfer ({ source, password, destination, amount, endpoint }) { - const logger = new EntropyLogger('CLI::TRANSFER', endpoint) - // NOTE: password is optional, is only for source account (if that is encrypted) - - const storedConfig = await config.get() - const account = storedConfig.accounts.find(account => account.address === source) - if (!account) throw Error(`No account with address ${source}`) - // QUESTION: is throwing the right response? - logger.debug('account', account) - - const entropy = await initializeEntropy({ keyMaterial: account.data, password, endpoint }) - - if (!entropy?.registrationManager?.signer?.pair) { - throw new Error("Signer keypair is undefined or not properly initialized.") - } - const formattedAmount = formatAmountAsHex(amount) - const tx = await entropy.substrate.tx.balances.transferAllowDeath( - destination, - BigInt(formattedAmount), - // WARNING: this is moving ... a lot? What? - ) - - await tx.signAndSend (entropy.registrationManager.signer.pair, ({ status }) => { - logger.debug('signAndSend status:') - logger.debug(status) - }) -} diff --git a/src/flows/entropyTransfer/index.ts b/src/flows/entropyTransfer/index.ts deleted file mode 100644 index 43f5532e..00000000 --- a/src/flows/entropyTransfer/index.ts +++ /dev/null @@ -1,64 +0,0 @@ -import inquirer from "inquirer" -import { getSelectedAccount, print } from "../../common/utils" -import { initializeEntropy } from "../../common/initializeEntropy" -import { transfer } from "./transfer" -import { setupProgress } from "src/common/progress" - -const question = [ - { - type: "input", - name: "amount", - message: "Input amount to transfer:", - default: "1", - validate: (amount) => { - if (isNaN(amount) || parseInt(amount) <= 0) { - return 'Please enter a value greater than 0' - } - return true - } - }, - { - type: "input", - name: "recipientAddress", - message: "Input recipient's address:", - }, -] - -export async function entropyTransfer ({ accounts, selectedAccount: selectedAccountAddress }, options) { - const { endpoint } = options - const selectedAccount = getSelectedAccount(accounts, selectedAccountAddress) - - const { start: startProgress, stop: stopProgress } = setupProgress('Transferring Funds') - - try { - const entropy = await initializeEntropy({ - keyMaterial: selectedAccount.data, - endpoint - }) - - const { amount, recipientAddress } = await inquirer.prompt(question) - - if (!entropy?.keyring?.accounts?.registration?.pair) { - throw new Error("Signer keypair is undefined or not properly initialized.") - } - const formattedAmount = BigInt(parseInt(amount) * 1e10) - startProgress() - const transferStatus = await transfer( - entropy, - { - from: entropy.keyring.accounts.registration.pair, - to: recipientAddress, - amount: formattedAmount - } - ) - if (transferStatus.isFinalized) stopProgress() - - print('') - print(`Transaction successful: Sent ${amount} to ${recipientAddress}`) - print('') - print('Press enter to return to main menu') - } catch (error) { - stopProgress() - console.error('ERR:::', error); - } -} diff --git a/src/flows/index.ts b/src/flows/index.ts index 82c5a11e..474d6823 100644 --- a/src/flows/index.ts +++ b/src/flows/index.ts @@ -1,7 +1,5 @@ export { entropyFaucet } from './entropyFaucet' -export { checkBalance } from './balance' export { entropyRegister } from './register' export { userPrograms, devPrograms } from './programs' export { sign } from './sign' -export { entropyTransfer } from './entropyTransfer' export { manageAccounts } from './manage-accounts' diff --git a/src/transfer/command.ts b/src/transfer/command.ts new file mode 100644 index 00000000..7fee0ff1 --- /dev/null +++ b/src/transfer/command.ts @@ -0,0 +1,51 @@ +import Entropy from "@entropyxyz/sdk"; +import { BaseCommand } from "../common/base-command"; +import { setupProgress } from "../common/progress"; +import * as TransferUtils from './utils' +import inquirer from "inquirer"; + +const FLOW_CONTEXT = 'ENTROPY_TRANSFER' +const question = [ + { + type: "input", + name: "amount", + message: "Input amount to transfer:", + default: "1", + validate: (amount) => { + if (isNaN(amount) || parseInt(amount) <= 0) { + return 'Please enter a value greater than 0' + } + return true + } + }, + { + type: "input", + name: "recipientAddress", + message: "Input recipient's address:", + }, +] + +export class TransferCommand extends BaseCommand { + constructor (entropy: Entropy, endpoint: string) { + super(entropy, endpoint, FLOW_CONTEXT) + } + + public async askQuestions () { + return inquirer.prompt(question) + } + + public async sendTransfer (toAddress: string, amount: string) { + const { start: startProgress, stop: stopProgress } = setupProgress('Transferring Funds') + + const formattedAmount = BigInt(parseInt(amount) * 1e10) + startProgress() + try { + const transferStatus = await TransferUtils.transfer(this.entropy, { from: this.entropy.keyring.accounts.registration.pair, to: toAddress, amount: formattedAmount }) + if (transferStatus.isFinalized) return stopProgress() + } catch (error) { + this.logger.error('There was an issue sending this transfer', error) + stopProgress() + throw error + } + } +} \ No newline at end of file diff --git a/src/flows/entropyTransfer/types.ts b/src/transfer/types.ts similarity index 99% rename from src/flows/entropyTransfer/types.ts rename to src/transfer/types.ts index c23b6b77..1ceaf8b2 100644 --- a/src/flows/entropyTransfer/types.ts +++ b/src/transfer/types.ts @@ -1,5 +1,6 @@ // @ts-ignore import { Pair } from '@entropyxyz/sdk/keys' + export interface TransferOptions { from: Pair to: string diff --git a/src/flows/entropyTransfer/transfer.ts b/src/transfer/utils.ts similarity index 100% rename from src/flows/entropyTransfer/transfer.ts rename to src/transfer/utils.ts diff --git a/src/tui.ts b/src/tui.ts index 746640fa..4db275f4 100644 --- a/src/tui.ts +++ b/src/tui.ts @@ -1,15 +1,19 @@ import inquirer from 'inquirer' +import Entropy from '@entropyxyz/sdk' import * as config from './config' import * as flows from './flows' import { EntropyTuiOptions } from './types' import { logo } from './common/ascii' import { print } from './common/utils' import { EntropyLogger } from './common/logger' +import { BalanceCommand } from './balance/command' +import { TransferCommand } from './transfer/command' +import { loadEntropy } from './cli' 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.log(logo) // the Entropy logo @@ -17,10 +21,11 @@ export default function tui (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, + 'Transfer': () => {}, // TODO: design programs in TUI (merge deploy+user programs) 'Deploy Program': flows.devPrograms, 'User Programs': flows.userPrograms, @@ -36,10 +41,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 @@ -54,6 +59,11 @@ async function main (choices, options, logger: EntropyLogger) { storedConfig = await config.get() } + // If the selected account changes within the TUI we need to reset the entropy instance being used + if (storedConfig.selectedAccount !== entropy.keyring.accounts.registration.address) { + entropy = await loadEntropy(storedConfig.selectedAccount, options.endpoint) + } + const answers = await inquirer.prompt([{ type: 'list', name: 'choice', @@ -73,13 +83,42 @@ async function main (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": { + try { + const balanceCommand = new BalanceCommand(entropy, options.endpoint) + const balanceString = await balanceCommand.getBalance(storedConfig.selectedAccount) + print(`Address ${storedConfig.selectedAccount} has a balance of: ${balanceString}`) + } catch (error) { + console.error('There was an error retrieving balance', error) + } + break; + } + case "Transfer": { + try { + const transferCommand = new TransferCommand(entropy, options.endpoint) + const { amount, recipientAddress } = await transferCommand.askQuestions() + await transferCommand.sendTransfer(recipientAddress, amount) + print('') + print(`Transaction successful: Sent ${amount} to ${recipientAddress}`) + print('') + print('Press enter to return to main menu') + } catch (error) { + console.error('There was an error sending the transfer', error) + } + 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) { @@ -90,7 +129,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() diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 2d05b25e..f95d7e16 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -1,32 +1,31 @@ import test from 'tape' -import { getBalance, getBalances } from '../src/flows/balance/balance' import { setupTest, charlieStashAddress as richAddress } from './testing-utils' +import * as BalanceUtils 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 newAddress = entropy.keyring.accounts.registration.address /* getBalance */ const newAddressBalance = await run( 'getBalance (newSeed)', - getBalance(entropy, newAddress) + BalanceUtils.getBalance(entropy, newAddress) ) t.equal(newAddressBalance, 0, 'newSeed balance = 0') const richAddressBalance = await run( 'getBalance (richAddress)', - getBalance(entropy, richAddress) + BalanceUtils.getBalance(entropy, richAddress) ) t.true(richAddressBalance > BigInt(10e10), 'richAddress balance >>> 0') /* getBalances */ const balances = await run( 'getBalances', - getBalances(entropy, [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', - getBalances(entropy, badAddresses) + BalanceUtils.getBalances(entropy, badAddresses) ) badAddresses.forEach(addr => { diff --git a/tests/testing-utils/setup-test.ts b/tests/testing-utils/setup-test.ts index 92817e82..36391127 100644 --- a/tests/testing-utils/setup-test.ts +++ b/tests/testing-utils/setup-test.ts @@ -12,16 +12,18 @@ import { makeSeed, promiseRunner } 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) @@ -42,12 +44,13 @@ 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: '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 033d648a..12c9736c 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -10,12 +10,13 @@ import { spinNetworkDown } from './testing-utils' -import { getBalance } from '../src/flows/balance/balance' import { initializeEntropy } from '../src/common/initializeEntropy' -import { transfer } from '../src/flows/entropyTransfer/transfer' +import * as BalanceUtils from '../src/balance/utils' +import * as TransferUtils from '../src/transfer/utils' import { charlieStashAddress, charlieStashSeed } from './testing-utils/constants' const networkType = 'two-nodes' +const endpoint = 'ws://127.0.0.1:9944' test('Transfer', async (t) => { /* Setup */ @@ -34,9 +35,11 @@ test('Transfer', async (t) => { const naynaySeed = makeSeed() 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', }) + // Below expect errors are in place until we fix types export from sdk + // @ts-expect-error + const entropy = await initializeEntropy({ keyMaterial: naynayKeyring.getAccount(), endpoint, }) + // @ts-expect-error + const charlieEntropy = await initializeEntropy({ keyMaterial: charlieKeyring.getAccount(), endpoint, }) await run('entropy ready', entropy.ready) await run('charlie ready', charlieEntropy.ready) @@ -45,21 +48,21 @@ test('Transfer', async (t) => { // Check Balance of new account let naynayBalance = await run( 'getBalance (naynay)', - getBalance(entropy, recipientAddress) + BalanceUtils.getBalance(entropy, recipientAddress) ) t.equal(naynayBalance, 0, 'naynay is broke') let charlieBalance = await run( 'getBalance (charlieStash)', - getBalance(entropy, charlieStashAddress) + BalanceUtils.getBalance(entropy, charlieStashAddress) ) t.equal(charlieBalance, 1e17, 'charlie got bank') const transferStatus = await run( 'transfer', - transfer(entropy, { + TransferUtils.transfer(entropy, { from: charlieEntropy.keyring.accounts.registration.pair, to: recipientAddress, amount: BigInt(1000 * 10e10) @@ -71,7 +74,7 @@ test('Transfer', async (t) => { // Re-Check Balance of new account naynayBalance = await run( 'getBalance (naynay)', - getBalance(entropy, recipientAddress) + BalanceUtils.getBalance(entropy, recipientAddress) ) t.equal(naynayBalance, 1000 * 10e10, 'naynay is rolling in it!')