diff --git a/CHANGELOG.md b/CHANGELOG.md index 92aa3f9..cf21949 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,7 +42,11 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil - Shared - updated return data displayed to user on account creation (create or import) [#311](https://github.com/entropyxyz/cli/pull/311) - Balance now displays the number of BITS to the nearest 4 decimal places [#306](https://github.com/entropyxyz/cli/pull/306) + - removed use of entropy instance from transfer flow [#329](https://github.com/entropyxyz/cli/pull/329) +- CLI + - updated balance command to take in any address, and be able to return the balance for the inputted address [#315](https://github.com/entropyxyz/cli/pull/315) + - TUI - updated regsitration and transfer flow to use progress loader to provide a signal to the user something is happening [#324](https://github.com/entropyxyz/cli/pull/324) - removed use of progress bar throughout TUI [#324](https://github.com/entropyxyz/cli/pull/324) diff --git a/package.json b/package.json index fe01309..4c86db9 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ }, "homepage": "https://github.com/entropyxyz/cli#readme", "dependencies": { - "@entropyxyz/sdk": "0.4.0", + "@entropyxyz/sdk": "0.4.1-0", "ajv": "^8.17.1", "commander": "^12.1.0", "env-paths": "^3.0.0", diff --git a/src/account/utils.ts b/src/account/utils.ts index 50da9f8..55b849d 100644 --- a/src/account/utils.ts +++ b/src/account/utils.ts @@ -28,7 +28,7 @@ export async function selectAndPersistNewAccount (configPath: string, newAccount }) } -export async function persistVerifyingKeyToAccount (configPath: string, verifyingKey: string, accountNameOrAddress: string) { +export async function persistVerifyingKeyToAccount (configPath: string, verifyingKey: string, accountNameOrAddress?: string) { const storedConfig = await config.get(configPath) const { accounts } = storedConfig diff --git a/src/balance/command.ts b/src/balance/command.ts index 1290d70..4278a5f 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -1,13 +1,13 @@ import { Command } from "commander"; -import Entropy from "@entropyxyz/sdk"; - +// @ts-expect-error +import { isValidSubstrateAddress } from '@entropyxyz/sdk/utils' import { EntropyBalance } from "./main"; import { BalanceInfo } from "./types"; import { configOption, endpointOption, cliWrite } from "../common/utils-cli"; import { findAccountByAddressOrName, getTokenDetails, lilBitsToBits, round } from "../common/utils"; -import { loadEntropyCli } from "../common/load-entropy" import * as config from "../config"; import { EntropyConfigAccount } from "src/config/types"; +import { closeSubstrate, getLoadedSubstrate } from "src/common/substrate-utils"; export function entropyBalanceCommand () { const balanceCommand = new Command('balance') @@ -15,34 +15,23 @@ export function entropyBalanceCommand () { // view the balances of all accounts balanceCommand .description('Command to retrieive the balance of an account on the Entropy Network') - .argument('[account] ', [ + .argument('[account]', [ 'The address an account address whose balance you want to query.', - 'Can also be the human-readable name of one of your accounts' + 'Can also be the human-readable name of one of your accounts.' ].join(' ')) .option('-a, --all', 'Get balances for all admin accounts in the config') .addOption(configOption()) .addOption(endpointOption()) .action(async (account, opts) => { + const substrate = await getLoadedSubstrate(opts.endpoint) + const BalanceService = new EntropyBalance(substrate, opts.endpoint) + const { decimals, symbol } = await getTokenDetails(substrate) + const toBits = (lilBits: number) => round(lilBitsToBits(lilBits, decimals)) const { accounts } = await config.get(opts.config) - - let entropy: Entropy - if (!account && opts.all) { - const tempAddress = accounts[0].address - entropy = await loadEntropyCli({ account: tempAddress, ...opts }) - } else if (account && !opts.all) { - entropy = await loadEntropyCli({ account, ...opts }) - } else { - return balanceCommand.help() - } - - const balanceService = new EntropyBalance(entropy, opts.endpoint) - const { decimals, symbol } = await getTokenDetails(entropy) - const toBits = (nanoBits: number) => round(lilBitsToBits(nanoBits, decimals)) - if (opts.all) { // Balances for all admin accounts const addresses: string[] = accounts.map((acct: EntropyConfigAccount) => acct.address) - const balances = await balanceService.getBalances(addresses) + const balances = await BalanceService.getBalances(addresses) .then((infos: BalanceInfo[]) => { return infos.map(info => { return { @@ -56,13 +45,23 @@ export function entropyBalanceCommand () { }) cliWrite(balances) } else { + let address = findAccountByAddressOrName(accounts, account)?.address + if (!address) { + // provided account does not exist in the users config + if (isValidSubstrateAddress(account)) address = account + else { + // account is either null or not a valid substrate address + console.error(`Provided [account=${account}] is not a valid substrate address`) + process.exit(1) + } + } // Balance for singular account - const address = findAccountByAddressOrName(accounts, account)?.address - const balance = await balanceService.getBalance(address) + const balance = await BalanceService.getAnyBalance(address) .then(toBits) cliWrite({ account, balance, symbol }) } - + // closing substrate + await closeSubstrate(substrate) process.exit(0) }) diff --git a/src/balance/interaction.ts b/src/balance/interaction.ts index 28c7fff..a19c9db 100644 --- a/src/balance/interaction.ts +++ b/src/balance/interaction.ts @@ -1,17 +1,21 @@ -import { EntropyBalance } from "./main" -import { findAccountByAddressOrName, getTokenDetails, print, round, lilBitsToBits } from "src/common/utils" - +import { closeSubstrate, getLoadedSubstrate } from '../common/substrate-utils' +import { findAccountByAddressOrName, getTokenDetails, print, round, lilBitsToBits } from "../common/utils" import { EntropyTuiOptions } from '../types' -export async function entropyBalance (entropy, opts: EntropyTuiOptions, storedConfig) { +import { EntropyBalance } from "./main" + +export async function entropyBalance (opts: EntropyTuiOptions, storedConfig) { try { + const substrate = await getLoadedSubstrate(opts.endpoint) + const BalanceService = new EntropyBalance(substrate, opts.endpoint) // grabbing decimals from chain spec as that is the source of truth for the value - const { decimals, symbol } = await getTokenDetails(entropy) - const balanceService = new EntropyBalance(entropy, opts.endpoint) + const { decimals, symbol } = await getTokenDetails(substrate) const address = findAccountByAddressOrName(storedConfig.accounts, storedConfig.selectedAccount)?.address - const lilBalance = await balanceService.getBalance(address) + const lilBalance = await BalanceService.getAnyBalance(address) const balance = round(lilBitsToBits(lilBalance, decimals)) print(`Entropy Account [${storedConfig.selectedAccount}] (${address}) has a balance of: ${balance} ${symbol}`) + // closing substrate + await closeSubstrate(substrate) } catch (error) { console.error('There was an error retrieving balance', error) } diff --git a/src/balance/main.ts b/src/balance/main.ts index bbf6a47..8b1d379 100644 --- a/src/balance/main.ts +++ b/src/balance/main.ts @@ -1,26 +1,24 @@ -import Entropy from "@entropyxyz/sdk" -import { EntropyBase } from "../common/entropy-base" import * as BalanceUtils from "./utils" import { BalanceInfo } from "./types" +import { EntropySubstrateBase } from "src/common/entropy-substrate-base" const FLOW_CONTEXT = 'ENTROPY-BALANCE' -export class EntropyBalance extends EntropyBase { - constructor (entropy: Entropy, endpoint: string) { - super({ entropy, endpoint, flowContext: FLOW_CONTEXT }) +export class EntropyBalance extends EntropySubstrateBase { + constructor (substrate: any, endpoint: string) { + super({ substrate, endpoint, flowContext: FLOW_CONTEXT }) } - async getBalance (address: string): Promise { - const accountInfo = (await this.entropy.substrate.query.system.account(address)) as any + async getAnyBalance (address: string) { + const accountInfo = (await this.substrate.query.system.account(address)) as any const balance = parseInt(BalanceUtils.hexToBigInt(accountInfo.data.free).toString()) - this.logger.log(`Current balance of ${address}: ${balance}`, EntropyBalance.name) return balance } async getBalances (addresses: string[]): Promise { return Promise.all( addresses.map(async address => { - return this.getBalance(address) + return this.getAnyBalance(address) .then((balance: number) => { return { address, balance } }) diff --git a/src/common/entropy-substrate-base.ts b/src/common/entropy-substrate-base.ts new file mode 100644 index 0000000..9d5b674 --- /dev/null +++ b/src/common/entropy-substrate-base.ts @@ -0,0 +1,13 @@ +import { EntropyLogger } from "./logger"; + +export abstract class EntropySubstrateBase { + protected logger: EntropyLogger + protected substrate: any + protected endpoint: string + + constructor ({ substrate, endpoint, flowContext }: { substrate: any, endpoint: string, flowContext: string }) { + this.logger = new EntropyLogger(flowContext, endpoint) + this.substrate = substrate + this.endpoint = endpoint + } +} diff --git a/src/common/load-entropy.ts b/src/common/load-entropy.ts index 230490d..0abc1a8 100644 --- a/src/common/load-entropy.ts +++ b/src/common/load-entropy.ts @@ -117,7 +117,7 @@ async function loadEntropy (opts: LoadEntropyOpts): Promise { const storedConfig = await opts.config.get() if (!storedConfig) throw Error('no config!!') // TEMP: want to see if we hit this! - let account = resolveAccount(storedConfig, opts.account) + let account = resolveAccount(storedConfig, opts.account || storedConfig.selectedAccount) const endpoint = resolveEndpoint(storedConfig, opts.endpoint) // NOTE: while it would be nice to parse opts --account, --endpoint with Commander // the argParser for these Options does not have access to the --config option, @@ -211,7 +211,7 @@ async function setupRegistrationSubAccount (account: EntropyConfigAccount, confi } const keyringCache = {} -async function loadKeyring (account: EntropyConfigAccount) { +export async function loadKeyring (account: EntropyConfigAccount) { const { address } = account.data.admin || {} if (!address) throw new Error('Cannot load keyring, no admin address') diff --git a/src/common/substrate-utils.ts b/src/common/substrate-utils.ts new file mode 100644 index 0000000..9d5ef1a --- /dev/null +++ b/src/common/substrate-utils.ts @@ -0,0 +1,18 @@ +// @ts-expect-error +import { createSubstrate } from '@entropyxyz/sdk/utils' + +export async function getLoadedSubstrate (endpoint: string) { + const substrate = createSubstrate(endpoint) + await substrate.isReadyOrError + return substrate +} + +export async function closeSubstrate (substrate: any) { + try { + // closing substrate + await substrate.disconnect() + } catch (error) { + console.error('SubstrateError: Error closing connection', error) + throw error + } +} \ No newline at end of file diff --git a/src/common/utils.ts b/src/common/utils.ts index bbb242f..86f6738 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -1,4 +1,3 @@ -import { Entropy } from '@entropyxyz/sdk' import { Buffer } from 'node:buffer' import { homedir } from 'node:os' import { join } from 'node:path' @@ -111,11 +110,11 @@ export function absolutePath (somePath: string) { } } -export function formatDispatchError (entropy: Entropy, dispatchError) { +export function formatDispatchError (substrate: any, dispatchError) { let msg: string if (dispatchError.isModule) { // for module errors, we have the section indexed, lookup - const decoded = entropy.substrate.registry.findMetaError( + const decoded = substrate.registry.findMetaError( dispatchError.asModule ) const { docs, name, section } = decoded @@ -147,9 +146,9 @@ export async function jumpStartNetwork (entropy, endpoint): Promise { // caching details to reduce number of calls made to the rpc endpoint let tokenDetails: TokenDetails -export async function getTokenDetails (entropy): Promise { +export async function getTokenDetails (substrate): Promise { if (tokenDetails) return tokenDetails - const chainProperties = await entropy.substrate.rpc.system.properties() + const chainProperties = await substrate.rpc.system.properties() const decimals = chainProperties.tokenDecimals.toHuman()[0] const symbol = chainProperties.tokenSymbol.toHuman()[0] tokenDetails = { decimals: parseInt(decimals), symbol } diff --git a/src/faucet/interaction.ts b/src/faucet/interaction.ts index f76fc05..7281cc6 100644 --- a/src/faucet/interaction.ts +++ b/src/faucet/interaction.ts @@ -26,12 +26,12 @@ export async function entropyFaucet (entropy: Entropy, opts: EntropyTuiOptions, throw new Error("Keys are undefined") } - const { decimals } = await getTokenDetails(entropy) + const { decimals } = await getTokenDetails(entropy.substrate) const amount = bitsToLilBits(2, decimals) const faucetService = new EntropyFaucet(entropy, opts.endpoint) const verifyingKeys = await faucetService.getAllFaucetVerifyingKeys() - // @ts-expect-error - return sendMoneyFromRandomFaucet(entropy, options.endpoint, verifyingKeys, amount.toString(), logger) + // @ts-expect-error verifyingKeys + return sendMoneyFromRandomFaucet(entropy, opts.endpoint, verifyingKeys, amount.toString(), logger) } // Method that takes in the initial list of verifying keys (to avoid multiple calls to the rpc) and recursively retries each faucet until @@ -41,7 +41,7 @@ async function sendMoneyFromRandomFaucet (entropy: Entropy, endpoint: string, ve faucetSpinner.start() } const faucetService = new EntropyFaucet(entropy, endpoint) - const { decimals, symbol } = await getTokenDetails(entropy) + const { decimals, symbol } = await getTokenDetails(entropy.substrate) const selectedAccountAddress = entropy.keyring.accounts.registration.address let chosenVerifyingKey: string try { diff --git a/src/faucet/main.ts b/src/faucet/main.ts index 84346b5..a196927 100644 --- a/src/faucet/main.ts +++ b/src/faucet/main.ts @@ -34,7 +34,7 @@ export class EntropyFaucet extends EntropyBase { // status would still be set, but in the case of error we can shortcut // to just check it (so an error would indicate InBlock or Finalized) if (dispatchError) { - const error = formatDispatchError(this.entropy, dispatchError) + const error = formatDispatchError(this.entropy.substrate, dispatchError) return reject(error) } if (status.isFinalized) resolve(status) @@ -71,11 +71,11 @@ export class EntropyFaucet extends EntropyBase { faucetProgramPointer = FAUCET_PROGRAM_POINTER }: SendMoneyParams ): Promise { - const balanceService = new EntropyBalance(this.entropy, this.endpoint) const programService = new EntropyProgram(this.entropy, this.endpoint) + const BalanceService = new EntropyBalance(this.entropy.substrate, this.endpoint) // check balance of faucet address - const balance = await balanceService.getBalance(faucetAddress) + const balance = await BalanceService.getAnyBalance(faucetAddress) if (balance <= 0) throw new Error('FundsError: Faucet Account does not have funds') // check verifying key has ONLY the exact program installed diff --git a/src/transfer/command.ts b/src/transfer/command.ts index 62601dc..20a3016 100644 --- a/src/transfer/command.ts +++ b/src/transfer/command.ts @@ -2,8 +2,10 @@ import { Command } from "commander" import { EntropyTransfer } from "./main" import { accountOption, configOption, endpointOption, cliWrite } from "../common/utils-cli" -import { loadEntropyCli } from "../common/load-entropy" -import { getTokenDetails } from "../common/utils" +import { loadKeyring } from "../common/load-entropy" +import { findAccountByAddressOrName, getTokenDetails } from "../common/utils" +import * as config from "../config"; +import { closeSubstrate, getLoadedSubstrate } from "src/common/substrate-utils" export function entropyTransferCommand () { const transferCommand = new Command('transfer') @@ -16,18 +18,22 @@ export function entropyTransferCommand () { .addOption(endpointOption()) .action(async (destination, amount, opts) => { // TODO: destination as ? - const entropy = await loadEntropyCli(opts) - const transferService = new EntropyTransfer(entropy, opts.endpoint) - const { symbol } = await getTokenDetails(entropy) + const { accounts, selectedAccount } = await config.get(opts.config) + const substrate = await getLoadedSubstrate(opts.endpoint) + const account = findAccountByAddressOrName(accounts, opts.account || selectedAccount) + const loadedKeyring = await loadKeyring(account) + const transferService = new EntropyTransfer(substrate, opts.endpoint) + const { symbol } = await getTokenDetails(substrate) - await transferService.transfer(destination, amount) + await transferService.transfer(loadedKeyring.accounts.registration.pair, destination, amount) cliWrite({ - source: opts.account, + source: loadedKeyring.accounts.registration.address, destination, amount, symbol }) + await closeSubstrate(substrate) process.exit(0) }) return transferCommand diff --git a/src/transfer/interaction.ts b/src/transfer/interaction.ts index 59ba6af..f199d98 100644 --- a/src/transfer/interaction.ts +++ b/src/transfer/interaction.ts @@ -1,24 +1,31 @@ import inquirer from "inquirer" import yoctoSpinner from "yocto-spinner" -import { getTokenDetails, print } from "../common/utils" +import { findAccountByAddressOrName, getTokenDetails, print } from "../common/utils" import { EntropyTransfer } from "./main" import { transferInputQuestions } from "./utils" import { EntropyTuiOptions } from '../types' +import { EntropyConfig } from "src/config/types" +import { closeSubstrate, getLoadedSubstrate } from "src/common/substrate-utils" +import { loadKeyring } from "src/common/load-entropy" const transferSpinner = yoctoSpinner() const SPINNER_TEXT = 'Transferring funds...' -export async function entropyTransfer (entropy, opts: EntropyTuiOptions) { +export async function entropyTransfer (opts: EntropyTuiOptions, storedConfig: EntropyConfig) { transferSpinner.text = SPINNER_TEXT if (transferSpinner.isSpinning) transferSpinner.stop() try { - const { symbol } = await getTokenDetails(entropy) - const transferService = new EntropyTransfer(entropy, opts.endpoint) + const substrate = await getLoadedSubstrate(opts.endpoint) + const currentAccount = findAccountByAddressOrName(storedConfig.accounts, opts.account || storedConfig.selectedAccount) + const loadedKeyring = await loadKeyring(currentAccount) + const { symbol } = await getTokenDetails(substrate) + const transferService = new EntropyTransfer(substrate, opts.endpoint) const { amount, recipientAddress } = await inquirer.prompt(transferInputQuestions) if (!transferSpinner.isSpinning) transferSpinner.start() - await transferService.transfer(recipientAddress, amount) + await transferService.transfer(loadedKeyring.accounts.registration.pair, recipientAddress, amount) + await closeSubstrate(opts.endpoint) if (transferSpinner.isSpinning) transferSpinner.stop() print('') print(`Transaction successful: Sent ${amount} ${symbol} to ${recipientAddress}`) @@ -26,6 +33,7 @@ export async function entropyTransfer (entropy, opts: EntropyTuiOptions) { print('Press enter to return to main menu') } catch (error) { transferSpinner.text = 'Transfer failed...' + await closeSubstrate(opts.endpoint) if (transferSpinner.isSpinning) transferSpinner.stop() print.error('TransferError:', error.message); } diff --git a/src/transfer/main.ts b/src/transfer/main.ts index 2771042..61968b3 100644 --- a/src/transfer/main.ts +++ b/src/transfer/main.ts @@ -1,14 +1,16 @@ -import Entropy from "@entropyxyz/sdk"; +// @ts-ignore +import { Pair } from '@entropyxyz/sdk/keys' -import { EntropyBase } from "../common/entropy-base"; import { bitsToLilBits, formatDispatchError, getTokenDetails } from "../common/utils"; + import { TransferOptions } from "./types"; +import { EntropySubstrateBase } from 'src/common/entropy-substrate-base'; const FLOW_CONTEXT = 'ENTROPY_TRANSFER' -export class EntropyTransfer extends EntropyBase { - constructor (entropy: Entropy, endpoint: string) { - super({ entropy, endpoint, flowContext: FLOW_CONTEXT }) +export class EntropyTransfer extends EntropySubstrateBase { + constructor (substrate: any, endpoint: string) { + super({ substrate, endpoint, flowContext: FLOW_CONTEXT }) } // NOTE: a more accessible function which handles @@ -16,15 +18,17 @@ export class EntropyTransfer extends EntropyBase { // - converting `amount` (string => BigInt) // - progress callbacks (optional) - async transfer (toAddress: string, amountInBits: string) { - const { decimals } = await getTokenDetails(this.entropy) + async transfer (from: Pair, toAddress: string, amountInBits: string) { + const { decimals } = await getTokenDetails(this.substrate) const lilBits = bitsToLilBits(Number(amountInBits), decimals) - return this.rawTransfer({ - from: this.entropy.keyring.accounts.registration.pair, + const transferStatus = await this.rawTransfer({ + from, to: toAddress, lilBits }) + + return transferStatus } private async rawTransfer (payload: TransferOptions): Promise { @@ -33,12 +37,12 @@ export class EntropyTransfer extends EntropyBase { return new Promise((resolve, reject) => { // WARN: await signAndSend is dangerous as it does not resolve // after transaction is complete :melt: - this.entropy.substrate.tx.balances + this.substrate.tx.balances .transferAllowDeath(to, lilBits) // @ts-ignore .signAndSend(from, ({ status, dispatchError }) => { if (dispatchError) { - const error = formatDispatchError(this.entropy, dispatchError) + const error = formatDispatchError(this.substrate, dispatchError) this.logger.error('There was an issue sending this transfer', error) return reject(error) } diff --git a/src/tui.ts b/src/tui.ts index 35f3f00..01b208e 100644 --- a/src/tui.ts +++ b/src/tui.ts @@ -155,12 +155,12 @@ async function main (entropy: Entropy, choices: string[], opts: EntropyTuiOption break } case 'Balance': { - await entropyBalance(entropy, opts, storedConfig) + await entropyBalance(opts, storedConfig) .catch(err => console.error('There was an error retrieving balance', err)) break } case 'Transfer': { - await entropyTransfer(entropy, opts) + await entropyTransfer(opts, storedConfig) .catch(err => console.error('There was an error sending the transfer', err)) break } diff --git a/tests/account.test.ts b/tests/account.test.ts index 645801c..c12a0a6 100644 --- a/tests/account.test.ts +++ b/tests/account.test.ts @@ -35,7 +35,7 @@ test('Account - list', async t => { 'test-net': 'wss://testnet.entropy.xyz', }, selectedAccount: account.name, - 'migration-version': '0' + 'migration-version': 0 } const accountsArray = EntropyAccount.list(config) @@ -84,9 +84,9 @@ const endpoint = 'ws://127.0.0.1:9944' async function fundAccount (t, entropy: Entropy) { const { entropy: charlie } = await setupTest(t, { seed: charlieStashSeed }) - const transfer = new EntropyTransfer(charlie, endpoint) + const transfer = new EntropyTransfer(charlie.substrate, endpoint) - await transfer.transfer(entropy.keyring.accounts.registration.address, "1000") + await transfer.transfer(charlie.keyring.accounts.registration.pair, entropy.keyring.accounts.registration.address, "1000") } diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 6b9227b..affaa0f 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -1,30 +1,33 @@ import test from 'tape' -import { setupTest, charlieStashAddress as richAddress } from './testing-utils' import { EntropyBalance } from '../src/balance/main' +import { EntropyAccount } from '../src/account/main' +import { closeSubstrate, getLoadedSubstrate } from '../src/common/substrate-utils' -test('getBalance + getBalances', async (t) => { - const { run, entropy, endpoint } = await setupTest(t) - const balanceService = new EntropyBalance(entropy, endpoint) - const newAddress = entropy.keyring.accounts.registration.address +import { charlieStashAddress as richAddress, promiseRunner, DEFAULT_ENDPOINT } from './testing-utils' - /* getBalance */ +test('getAnyBalance + getBalances', async (t) => { + const run = promiseRunner(t) + // create new account, not saved in config + const { address: newAddress } = await EntropyAccount.create({ name: 'TestAnyBalance1' }) + const substrate = await run('load substrate', getLoadedSubstrate(DEFAULT_ENDPOINT)) + const BalanceService = new EntropyBalance(substrate, DEFAULT_ENDPOINT) const newAddressBalance = await run( - 'getBalance (newSeed)', - balanceService.getBalance(newAddress) + 'getAnyBalance (newAccount)', + BalanceService.getAnyBalance(newAddress) ) t.equal(newAddressBalance, 0, 'newSeed balance = 0') const richAddressBalance = await run( 'getBalance (richAddress)', - balanceService.getBalance(richAddress) + BalanceService.getAnyBalance(richAddress) ) t.true(richAddressBalance > BigInt(10e10), 'richAddress balance >>> 0') /* getBalances */ const balances = await run( 'getBalances', - balanceService.getBalances([newAddress, richAddress]) + BalanceService.getBalances([newAddress, richAddress]) ) t.deepEqual( balances, @@ -38,16 +41,28 @@ test('getBalance + getBalances', async (t) => { const badAddresses = ['5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhr', '5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhrfnD'] const balancesWithNoGoodAddress = await run( 'getBalances::one good address', - balanceService.getBalances(badAddresses) + BalanceService.getBalances(badAddresses) ) badAddresses.forEach((addr) => { const match = balancesWithNoGoodAddress.find(info => info.address === addr) t.true(!!match.error, `error field is populated for ${addr}`) }) + await run('close substrate', closeSubstrate(substrate)) // TODO: // - test getBalances with 1 good address, 1 bung seed t.end() }) + +test('getAnyBalance: bad account', async (t) => { + const run = promiseRunner(t) + const substrate = await run('load substrate', getLoadedSubstrate(DEFAULT_ENDPOINT)) + const BalanceService = new EntropyBalance(substrate, DEFAULT_ENDPOINT) + await BalanceService.getAnyBalance('not-a-real-account') + .then(() => t.fail('Getting balance should fail')) + .catch(() => t.pass('Getting balance should fail')) + await run('close substrate', closeSubstrate(substrate)) + t.end() +}) diff --git a/tests/faucet.test.ts b/tests/faucet.test.ts index 61941cb..94a8ca1 100644 --- a/tests/faucet.test.ts +++ b/tests/faucet.test.ts @@ -13,7 +13,7 @@ async function setupAndFundFaucet (t) { const { run, entropy, endpoint } = await setupTest(t, { seed: eveSeed }) const account = new EntropyAccount(entropy, endpoint) - const transfer = new EntropyTransfer(entropy, endpoint) + const transfer = new EntropyTransfer(entropy.substrate, endpoint) const faucet = new EntropyFaucet(entropy, endpoint) // Deploy faucet program @@ -65,7 +65,7 @@ async function setupAndFundFaucet (t) { const verifyingKeys = await faucet.getAllFaucetVerifyingKeys(eveAddress) // @ts-expect-error const { chosenVerifyingKey, faucetAddress } = faucet.getRandomFaucet([], verifyingKeys) - await run('Transfer funds to faucet address', transfer.transfer(faucetAddress, "1000")) + await run('Transfer funds to faucet address', transfer.transfer(entropy.keyring.accounts.registration.pair, faucetAddress, "1000")) return { faucetProgramPointer, chosenVerifyingKey, faucetAddress } } @@ -77,9 +77,9 @@ test('Faucet Tests: Successfully send funds and register', async t => { const naynayAddress = naynay.keyring.accounts.registration.address const faucet = new EntropyFaucet(naynay, endpoint) - const balance = new EntropyBalance(naynay, endpoint) + const BalanceService = new EntropyBalance(naynay.substrate, endpoint) - let naynayBalance = await balance.getBalance(naynayAddress) + let naynayBalance = await BalanceService.getAnyBalance(naynayAddress) t.equal(naynayBalance, 0, 'Naynay is broke af') // 2 BITS @@ -96,7 +96,7 @@ test('Faucet Tests: Successfully send funds and register', async t => { ) t.ok(transferStatus.isFinalized, 'Transfer is good') - naynayBalance = await balance.getBalance(naynayAddress) + naynayBalance = await BalanceService.getAnyBalance(naynayAddress) t.equal(naynayBalance, amount, 'Naynay is drippin in faucet tokens') // Test if user can register after receiving funds @@ -106,7 +106,6 @@ test('Faucet Tests: Successfully send funds and register', async t => { const fullAccount = naynay.keyring.getAccount() t.equal(verifyingKey, fullAccount?.registration?.verifyingKeys?.[0], 'verifying key matches key added to registration account') - t.end() }) diff --git a/tests/testing-utils/constants.mjs b/tests/testing-utils/constants.mjs index 3701752..971ce8d 100644 --- a/tests/testing-utils/constants.mjs +++ b/tests/testing-utils/constants.mjs @@ -10,4 +10,5 @@ export const eveSeed = '0x786ad0e2df456fe43dd1f91ebca22e235bc162e0bb8d53c633e8c85b2af68b7a' export const eveAddress = '5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw' -export const DEFAULT_TOKEN_DECIMALS = 10 \ No newline at end of file +export const DEFAULT_ENDPOINT = 'ws://127.0.0.1:9944' +export const DEFAULT_TOKEN_DECIMALS = 10 diff --git a/tests/testing-utils/setup-test.ts b/tests/testing-utils/setup-test.ts index cfcf2ec..0efe980 100644 --- a/tests/testing-utils/setup-test.ts +++ b/tests/testing-utils/setup-test.ts @@ -7,7 +7,7 @@ import { join } from 'node:path' import { loadEntropyTest } from '../../src/common/load-entropy' import * as config from '../../src/config' -import { promiseRunner } from './' +import { DEFAULT_ENDPOINT, promiseRunner } from './' interface SetupTestOpts { configPath?: string @@ -27,7 +27,7 @@ export async function setupTest (t: Test, opts?: SetupTestOpts): Promise<{ entro const { configPath = uniqueConfigPath(), seed = randomAsHex(32), - endpoint = 'ws://127.0.0.1:9944', + endpoint = DEFAULT_ENDPOINT, } = opts || {} const run = promiseRunner(t) diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index c66900c..ad4f65f 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -1,51 +1,57 @@ import test from 'tape' +import { randomAsHex } from '@polkadot/util-crypto' +import Keyring from '@entropyxyz/sdk/keys'; -import { lilBitsPerBits } from "../src/common/utils"; -import { EntropyTransfer } from '../src/transfer/main' +import { EntropyAccount } from '../src/account/main' import { EntropyBalance } from '../src/balance/main' -import { promiseRunner, setupTest } from './testing-utils' -import { charlieStashAddress, charlieStashSeed, DEFAULT_TOKEN_DECIMALS } from './testing-utils/constants.mjs' +import { closeSubstrate, getLoadedSubstrate } from '../src/common/substrate-utils' +import { lilBitsPerBits } from "../src/common/utils" +import { EntropyTransfer } from '../src/transfer/main' -const endpoint = 'ws://127.0.0.1:9944' +import { setupTest } from './testing-utils' +import { charlieStashAddress, charlieStashSeed, DEFAULT_TOKEN_DECIMALS } from './testing-utils/constants.mjs' test('Transfer', async (t) => { /* Setup */ - const run = promiseRunner(t) - - const { entropy: charlie }= await setupTest(t, { seed: charlieStashSeed }) - const { entropy: naynay } = await setupTest(t) - - const naynayAddress = naynay.keyring.accounts.registration.address - + const testAccountSeed = randomAsHex(32) + const testAccountName = 'Test Account' + const naynay = await EntropyAccount.import({ name: testAccountName, seed: testAccountSeed }) + + // setuptest still needed to run here to start up wasm and get the config ready + const { run, endpoint }= await setupTest(t, { seed: charlieStashSeed }) + const substrate = await run('load substrate', getLoadedSubstrate(endpoint)) + const transferService = new EntropyTransfer(substrate, endpoint) + const BalanceService = new EntropyBalance(substrate, endpoint) + + const naynayAddress = naynay.address + const charlieKeyring = new Keyring({ seed: charlieStashSeed, path: '', debug: true }) // Check initial balances - const balanceService = new EntropyBalance(naynay, endpoint) let naynayBalance = await run( 'getBalance (naynay)', - balanceService.getBalance(naynayAddress) + BalanceService.getAnyBalance(naynayAddress) ) t.equal(naynayBalance, 0, 'naynay is broke') let charlieBalance = await run( 'getBalance (charlieStash)', - balanceService.getBalance(charlieStashAddress) + BalanceService.getAnyBalance(charlieStashAddress) ) t.true(charlieBalance > 9e16, 'charlie got bank') // Do transer - const transferService = new EntropyTransfer(charlie, endpoint) const inputAmount = "1.5" await run( 'transfer', - transferService.transfer(naynayAddress, inputAmount) + transferService.transfer(charlieKeyring.accounts.registration.pair, naynayAddress, inputAmount) ) // Re-Check balance naynayBalance = await run( 'getBalance (naynay)', - balanceService.getBalance(naynayAddress) + BalanceService.getAnyBalance(naynayAddress) ) const expected = Number(inputAmount) * lilBitsPerBits(DEFAULT_TOKEN_DECIMALS) t.equal(naynayBalance, expected, 'naynay is rolling in it!') - + await run('closeSubstrate', closeSubstrate(substrate)) t.end() }) diff --git a/yarn.lock b/yarn.lock index c4156bc..c2148f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,10 +26,10 @@ resolved "https://registry.npmjs.org/@entropyxyz/entropy-protocol-web/-/entropy-protocol-web-0.2.0.tgz" integrity sha512-lLa/lLNJnwH1R8fJvLlUn1kw7d4Rbnt9LjhUC69HKxkU69J+bw/EY6fAjBnpVbgNmqCnYpf/DBLtMyOayZeNDQ== -"@entropyxyz/sdk@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@entropyxyz/sdk/-/sdk-0.4.0.tgz#92ae53b19fe9630584cc1a4a40122b8a5142b003" - integrity sha512-WL6GzMROqBDuyC5KDQxRV68hG3MWjgsifcXD0zoL75tgSi4kJGfMgPvwHtO+kCg9aYKEaLFVdpyaOU4bDkl41w== +"@entropyxyz/sdk@0.4.1-0": + version "0.4.1-0" + resolved "https://registry.yarnpkg.com/@entropyxyz/sdk/-/sdk-0.4.1-0.tgz#dee5a51f420ad6ae600021d305ae051ddc7bc870" + integrity sha512-Mgd7FpR78jVA9WRM/IYWvLxmXGcP4zXX2f/tjpQzg7a0/GvNbfeC7gRp+ehKcmK0Ecau0L3iOWIe8jhPstl3FQ== dependencies: "@entropyxyz/entropy-protocol-nodejs" "^0.2.0" "@entropyxyz/entropy-protocol-web" "^0.2.0"