From 30ef58ac14d3088dac9c3aebf780d74b9f18e1ab Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Fri, 22 Nov 2024 13:32:56 -0500 Subject: [PATCH 01/18] [NayNay] Balance for any address - updated balance for prg cli to be able to retrieve balance for any address - using newly exposed utility method to getSubstrate from sdk --- src/balance/command.ts | 20 ++++---------------- src/balance/main.ts | 16 ++++++++++++++++ src/common/entropy-base.ts | 2 +- tests/balance.test.ts | 17 ++++++++++++++++- tests/testing-utils/constants.mjs | 4 +++- tests/testing-utils/setup-test.ts | 4 ++-- 6 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/balance/command.ts b/src/balance/command.ts index d99ba2e2..bb1951f2 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -1,28 +1,16 @@ import { Command } from "commander"; -import Entropy from "@entropyxyz/sdk"; import { EntropyBalance } from "./main"; -import { endpointOption, cliWrite, loadEntropy } from "../common/utils-cli"; -import { findAccountByAddressOrName } from "../common/utils"; -import * as config from "../config"; +import { endpointOption, cliWrite } from "../common/utils-cli"; export function entropyBalanceCommand () { const balanceCommand = new Command('balance') balanceCommand .description('Command to retrieive the balance of an account on the Entropy Network') - .argument('', [ - 'The address an account address whose balance you want to query.', - 'Can also be the human-readable name of one of your accounts' - ].join(' ')) + .argument('
', 'Any SS58 address you would like to get the balance of') .addOption(endpointOption()) - .action(async (account, opts) => { - const entropy: Entropy = await loadEntropy(account, opts.endpoint) - const BalanceService = new EntropyBalance(entropy, opts.endpoint) - - const { accounts } = await config.get() - const address = findAccountByAddressOrName(accounts, account)?.address - - const balance = await BalanceService.getBalance(address) + .action(async (address, opts) => { + const balance = await EntropyBalance.getAnyBalance(opts.endpoint, address) cliWrite(`${balance.toLocaleString('en-US')} BITS`) process.exit(0) }) diff --git a/src/balance/main.ts b/src/balance/main.ts index 7f7345f4..3d831df6 100644 --- a/src/balance/main.ts +++ b/src/balance/main.ts @@ -1,4 +1,6 @@ import Entropy from "@entropyxyz/sdk" +// @ts-expect-error +import { getSubstrate } from '@entropyxyz/sdk/utils' import { EntropyBase } from "../common/entropy-base" import * as BalanceUtils from "./utils" import { BalanceInfo } from "./types" @@ -9,6 +11,20 @@ export class EntropyBalance extends EntropyBase { super({ entropy, endpoint, flowContext: FLOW_CONTEXT }) } + static async getAnyBalance (endpoint: string, address: string) { + const substrate = getSubstrate(endpoint) + await substrate.isReadyOrError + + const accountInfo = (await substrate.query.system.account(address)) as any + const balance = parseInt(BalanceUtils.hexToBigInt(accountInfo.data.free).toString()) + + // closing substrate + await substrate.disconnect() + .catch(err => console.error('Error closing connection', err.message)) + + return balance + } + async getBalance (address: string): Promise { const accountInfo = (await this.entropy.substrate.query.system.account(address)) as any const balance = parseInt(BalanceUtils.hexToBigInt(accountInfo.data.free).toString()) diff --git a/src/common/entropy-base.ts b/src/common/entropy-base.ts index e24c9479..6e65b276 100644 --- a/src/common/entropy-base.ts +++ b/src/common/entropy-base.ts @@ -6,7 +6,7 @@ export abstract class EntropyBase { protected entropy: Entropy protected endpoint: string - constructor ({ entropy, endpoint, flowContext }: { entropy: Entropy, endpoint: string, flowContext: string }) { + constructor ({ entropy, endpoint, flowContext }: { entropy?: Entropy, endpoint: string, flowContext: string }) { this.logger = new EntropyLogger(flowContext, endpoint) this.entropy = entropy this.endpoint = endpoint diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 07c394f3..3b1551be 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -1,7 +1,8 @@ import test from 'tape' -import { setupTest, charlieStashAddress as richAddress } from './testing-utils' +import { setupTest, charlieStashAddress as richAddress, promiseRunner, DEFAULT_ENDPOINT } from './testing-utils' import { EntropyBalance } from '../src/balance/main' +import { EntropyAccount } from '../src/account/main' test('getBalance + getBalances', async (t) => { const { run, entropy, endpoint } = await setupTest(t) @@ -50,3 +51,17 @@ test('getBalance + getBalances', async (t) => { t.end() }) + +test('getAnyBalance', async (t) => { + const run = promiseRunner(t) + // create new account, not saved in config + const newAccount = await EntropyAccount.create({ name: 'TestAnyBalance1' }) + + const balance = await run( + 'getAnyBalance (newAccount)', + EntropyBalance.getAnyBalance(DEFAULT_ENDPOINT, newAccount.address) + ) + t.equal(balance, 0, 'newSeed balance = 0') + + t.end() +}) diff --git a/tests/testing-utils/constants.mjs b/tests/testing-utils/constants.mjs index 53090266..fee27775 100644 --- a/tests/testing-utils/constants.mjs +++ b/tests/testing-utils/constants.mjs @@ -8,4 +8,6 @@ export const charlieAddress = '5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y' export const eveSeed = '0x786ad0e2df456fe43dd1f91ebca22e235bc162e0bb8d53c633e8c85b2af68b7a' -export const eveAddress = '5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw' \ No newline at end of file +export const eveAddress = '5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw' + +export const DEFAULT_ENDPOINT = 'ws://127.0.0.1:9944' \ No newline at end of file diff --git a/tests/testing-utils/setup-test.ts b/tests/testing-utils/setup-test.ts index b8f77f58..6a3575c4 100644 --- a/tests/testing-utils/setup-test.ts +++ b/tests/testing-utils/setup-test.ts @@ -8,7 +8,7 @@ import { join } from 'node:path' import { initializeEntropy } from '../../src/common/initializeEntropy' import * as config from '../../src/config' -import { promiseRunner } from './' +import { DEFAULT_ENDPOINT, promiseRunner } from './' interface SetupTestOpts { configPath?: string @@ -28,7 +28,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) From a20921f047c370731d2ad40fb029ba6700a53838 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Fri, 22 Nov 2024 13:43:18 -0500 Subject: [PATCH 02/18] updated changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b403cfc..f97d6090 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,11 +22,14 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil - TUI - animation on tui load (while entropy loads) [#288](https://github.com/entropyxyz/cli/pull/288) -### Changes +### Changed - Shared - updated return data displayed to user on account creation (create or import) [#311](https://github.com/entropyxyz/cli/pull/311) +- 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) + ## [0.1.1] Deadpool - 2024-11-06 (entropy-core compatibility: 0.3.0) From fc8b42843a76606d79aefdd8a3c198ff51ddab55 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Fri, 22 Nov 2024 13:44:58 -0500 Subject: [PATCH 03/18] not needed change --- src/common/entropy-base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/entropy-base.ts b/src/common/entropy-base.ts index 6e65b276..e24c9479 100644 --- a/src/common/entropy-base.ts +++ b/src/common/entropy-base.ts @@ -6,7 +6,7 @@ export abstract class EntropyBase { protected entropy: Entropy protected endpoint: string - constructor ({ entropy, endpoint, flowContext }: { entropy?: Entropy, endpoint: string, flowContext: string }) { + constructor ({ entropy, endpoint, flowContext }: { entropy: Entropy, endpoint: string, flowContext: string }) { this.logger = new EntropyLogger(flowContext, endpoint) this.entropy = entropy this.endpoint = endpoint From 4bbfa6c111bd23b12ef7a76b6eadc0c23dd60674 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Fri, 22 Nov 2024 13:54:47 -0500 Subject: [PATCH 04/18] fn name change; --- src/balance/main.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/balance/main.ts b/src/balance/main.ts index 3d831df6..7325f5dc 100644 --- a/src/balance/main.ts +++ b/src/balance/main.ts @@ -1,6 +1,6 @@ import Entropy from "@entropyxyz/sdk" // @ts-expect-error -import { getSubstrate } from '@entropyxyz/sdk/utils' +import { createSubstrate } from '@entropyxyz/sdk/utils' import { EntropyBase } from "../common/entropy-base" import * as BalanceUtils from "./utils" import { BalanceInfo } from "./types" @@ -12,12 +12,12 @@ export class EntropyBalance extends EntropyBase { } static async getAnyBalance (endpoint: string, address: string) { - const substrate = getSubstrate(endpoint) + const substrate = createSubstrate(endpoint) await substrate.isReadyOrError const accountInfo = (await substrate.query.system.account(address)) as any const balance = parseInt(BalanceUtils.hexToBigInt(accountInfo.data.free).toString()) - + // closing substrate await substrate.disconnect() .catch(err => console.error('Error closing connection', err.message)) From 3c920e94c017c8419c3aac61b9791f9724fdfc16 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Mon, 2 Dec 2024 17:52:04 -0500 Subject: [PATCH 05/18] updated sdk to new rc --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index dad2d266..6c8bb7dd 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", "ansi-colors": "^4.1.3", "cli-progress": "^3.12.0", "commander": "^12.1.0", diff --git a/yarn.lock b/yarn.lock index 4f359b82..f63a9d62 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" From d094af4cc16f0cae343d02b2ed958e3f09181046 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 4 Dec 2024 13:27:46 -0500 Subject: [PATCH 06/18] added tests --- src/transfer/main.ts | 2 +- tests/balance.test.ts | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/transfer/main.ts b/src/transfer/main.ts index aa58b097..18bab98b 100644 --- a/src/transfer/main.ts +++ b/src/transfer/main.ts @@ -17,7 +17,7 @@ export class EntropyTransfer extends EntropyBase { // - progress callbacks (optional) async transfer (toAddress: string, amountInBits: string, progress?: { start: ()=>void, stop: ()=>void }) { - const { decimals } = await getTokenDetails(this.entropy) + const { decimals } = await getTokenDetails(this.entropy.substrate) const nanoBits = bitsToNanoBits(Number(amountInBits), decimals) if (progress) progress.start() diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 3b1551be..067f1c50 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -1,8 +1,9 @@ import test from 'tape' -import { setupTest, charlieStashAddress as richAddress, promiseRunner, DEFAULT_ENDPOINT } from './testing-utils' +import { setupTest, charlieStashAddress as richAddress, promiseRunner, DEFAULT_ENDPOINT, eveAddress } from './testing-utils' import { EntropyBalance } from '../src/balance/main' import { EntropyAccount } from '../src/account/main' +import { createSubstrate } from '@entropyxyz/sdk/utils' test('getBalance + getBalances', async (t) => { const { run, entropy, endpoint } = await setupTest(t) @@ -52,16 +53,30 @@ test('getBalance + getBalances', async (t) => { t.end() }) -test('getAnyBalance', async (t) => { +test('getAnyBalance: new account', async (t) => { const run = promiseRunner(t) // create new account, not saved in config const newAccount = await EntropyAccount.create({ name: 'TestAnyBalance1' }) - + const substrate = createSubstrate(DEFAULT_ENDPOINT) + await run('substrate ready', substrate.isReadyOrError) const balance = await run( 'getAnyBalance (newAccount)', - EntropyBalance.getAnyBalance(DEFAULT_ENDPOINT, newAccount.address) + EntropyBalance.getAnyBalance(substrate, newAccount.address) ) t.equal(balance, 0, 'newSeed balance = 0') + await run('close substrate', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) + t.end() +}) +test('getAnyBalance: test account', async (t) => { + const run = promiseRunner(t) + const substrate = createSubstrate(DEFAULT_ENDPOINT) + await run('substrate ready', substrate.isReadyOrError) + const balance = await run( + 'getAnyBalance (eve account)', + EntropyBalance.getAnyBalance(substrate, eveAddress) + ) + t.true(balance > BigInt(10e10), 'richAddress balance >>> 0') + await run('close substrate', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) t.end() }) From 62bf5e678f4dc7ece85f74c18070e676e28cb602 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 4 Dec 2024 13:33:44 -0500 Subject: [PATCH 07/18] added failure test --- tests/balance.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 067f1c50..9326db71 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -80,3 +80,20 @@ test('getAnyBalance: test account', async (t) => { await run('close substrate', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) t.end() }) + +test('getAnyBalance: bad account', async (t) => { + const run = promiseRunner(t) + const substrate = createSubstrate(DEFAULT_ENDPOINT) + await run('substrate ready', substrate.isReadyOrError) + try { + await run( + 'getAnyBalance (bad account)', + EntropyBalance.getAnyBalance(substrate, 'not-a-real-account') + ) + t.fail('Getting balance should fail') + } catch (error) { + t.pass('Getting balance failed due to bad account') + } + await run('close substrate', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) + t.end() +}) From e3c403cb79fa4606eda034fbeff7a9c547768a4a Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 4 Dec 2024 13:51:09 -0500 Subject: [PATCH 08/18] could fix failing test --- tests/balance.test.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 9326db71..38e488cb 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -85,15 +85,12 @@ test('getAnyBalance: bad account', async (t) => { const run = promiseRunner(t) const substrate = createSubstrate(DEFAULT_ENDPOINT) await run('substrate ready', substrate.isReadyOrError) - try { - await run( - 'getAnyBalance (bad account)', - EntropyBalance.getAnyBalance(substrate, 'not-a-real-account') - ) - t.fail('Getting balance should fail') - } catch (error) { - t.pass('Getting balance failed due to bad account') - } + await run( + 'getAnyBalance (bad account)', + EntropyBalance.getAnyBalance(substrate, 'not-a-real-account') + ) + .then(() => t.fail('Getting balance should fail')) + .catch(() => t.pass('Getting balance should fail')) await run('close substrate', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) t.end() }) From 5d76c1d1d6e36d4c93b17fce8916214e12825fda Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 4 Dec 2024 14:18:10 -0500 Subject: [PATCH 09/18] fixed failing test --- tests/balance.test.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 38e488cb..2c8804f1 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -85,10 +85,7 @@ test('getAnyBalance: bad account', async (t) => { const run = promiseRunner(t) const substrate = createSubstrate(DEFAULT_ENDPOINT) await run('substrate ready', substrate.isReadyOrError) - await run( - 'getAnyBalance (bad account)', - EntropyBalance.getAnyBalance(substrate, 'not-a-real-account') - ) + await EntropyBalance.getAnyBalance(substrate, 'not-a-real-account') .then(() => t.fail('Getting balance should fail')) .catch(() => t.pass('Getting balance should fail')) await run('close substrate', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) From c4410e53b20a9dc044484160f856d9ab1650076a Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 11 Dec 2024 18:03:18 -0500 Subject: [PATCH 10/18] found another nano --- src/balance/command.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/balance/command.ts b/src/balance/command.ts index c822b8d4..3c62c520 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -25,7 +25,7 @@ export function entropyBalanceCommand () { const substrate = createSubstrate(opts.endpoint) await substrate.isReadyOrError const { decimals, symbol } = await getTokenDetails(substrate) - const toBits = (nanoBits: number) => round(lilBitsToBits(nanoBits, decimals)) + const toBits = (lilBits: number) => round(lilBitsToBits(lilBits, decimals)) const { accounts } = await config.get(opts.config) if (opts.all) { // Balances for all admin accounts From f710ff779699dd990e4c2a04041e120c23459f70 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 11 Dec 2024 18:42:46 -0500 Subject: [PATCH 11/18] updated tests --- src/balance/main.ts | 16 ++++++++-------- tests/balance.test.ts | 8 ++++++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/balance/main.ts b/src/balance/main.ts index 2c25ea40..e51ed49f 100644 --- a/src/balance/main.ts +++ b/src/balance/main.ts @@ -16,14 +16,6 @@ export class EntropyBalance extends EntropyBase { return balance } - async getBalance (address: string): Promise { - const accountInfo = (await this.entropy.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 - } - static async getBalances (substrate, addresses: string[]): Promise { return Promise.all( addresses.map(async address => { @@ -37,4 +29,12 @@ export class EntropyBalance extends EntropyBase { }) ) } + + async getBalance (address: string): Promise { + const accountInfo = (await this.entropy.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 + } } diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 9e365fd2..20a9c1ab 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -3,12 +3,15 @@ import test from 'tape' import { setupTest, charlieStashAddress as richAddress, promiseRunner, DEFAULT_ENDPOINT, eveAddress } from './testing-utils' import { EntropyBalance } from '../src/balance/main' import { EntropyAccount } from '../src/account/main' +// @ts-expect-error import { createSubstrate } from '@entropyxyz/sdk/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 + const substrate = createSubstrate(endpoint) + await run('substrate ready', substrate.isReadyOrError) /* getBalance */ const newAddressBalance = await run( @@ -26,7 +29,7 @@ test('getBalance + getBalances', async (t) => { /* getBalances */ const balances = await run( 'getBalances', - balanceService.getBalances([newAddress, richAddress]) + EntropyBalance.getBalances(substrate, [newAddress, richAddress]) ) t.deepEqual( balances, @@ -40,13 +43,14 @@ test('getBalance + getBalances', async (t) => { const badAddresses = ['5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhr', '5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhrfnD'] const balancesWithNoGoodAddress = await run( 'getBalances::one good address', - balanceService.getBalances(badAddresses) + EntropyBalance.getBalances(substrate, 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', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) // TODO: // - test getBalances with 1 good address, 1 bung seed From 624e64fea650be78af28519d93abf251f62e4d4e Mon Sep 17 00:00:00 2001 From: mix irving Date: Sat, 14 Dec 2024 09:19:29 +1300 Subject: [PATCH 12/18] mixmix - fixes to naynay/any-balance (#327) * fix getTokenDetail calls, fix faucet sendMoney... * ensure load-entropy works with default account (selectedAccount) * ensure register works with default account (selectedAccount) * fix transfer relying on opts.account * fix balance account-checking logic --- src/account/utils.ts | 4 ++-- src/balance/command.ts | 17 +++++++++-------- src/balance/interaction.ts | 2 +- src/common/load-entropy.ts | 2 +- src/faucet/interaction.ts | 8 ++++---- src/transfer/command.ts | 4 ++-- src/transfer/interaction.ts | 2 +- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/account/utils.ts b/src/account/utils.ts index d8ef02c4..68a066ce 100644 --- a/src/account/utils.ts +++ b/src/account/utils.ts @@ -28,11 +28,11 @@ 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 - const account = findAccountByAddressOrName(accounts, accountNameOrAddress) + const account = findAccountByAddressOrName(accounts, accountNameOrAddress || storedConfig.selectedAccount) if (!account) throw Error(`Unable to persist verifyingKey "${verifyingKey}" to unknown account "${accountNameOrAddress}"`) // persist to config, set selectedAccount diff --git a/src/balance/command.ts b/src/balance/command.ts index 3c62c520..fe859a3e 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -14,9 +14,9 @@ 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()) @@ -45,13 +45,14 @@ export function entropyBalanceCommand () { cliWrite(balances) } else { let address = findAccountByAddressOrName(accounts, account)?.address - if (!address && isValidSubstrateAddress(account)) { + if (!address) { // provided account does not exist in the users config - 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) + 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 balance = await EntropyBalance.getAnyBalance(substrate, address) diff --git a/src/balance/interaction.ts b/src/balance/interaction.ts index 28c7ffff..58131bb7 100644 --- a/src/balance/interaction.ts +++ b/src/balance/interaction.ts @@ -6,7 +6,7 @@ import { EntropyTuiOptions } from '../types' export async function entropyBalance (entropy, opts: EntropyTuiOptions, storedConfig) { try { // grabbing decimals from chain spec as that is the source of truth for the value - const { decimals, symbol } = await getTokenDetails(entropy) + const { decimals, symbol } = await getTokenDetails(entropy.substrate) const balanceService = new EntropyBalance(entropy, opts.endpoint) const address = findAccountByAddressOrName(storedConfig.accounts, storedConfig.selectedAccount)?.address const lilBalance = await balanceService.getBalance(address) diff --git a/src/common/load-entropy.ts b/src/common/load-entropy.ts index 230490dd..fdd77f89 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, diff --git a/src/faucet/interaction.ts b/src/faucet/interaction.ts index f76fc053..7281cc69 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/transfer/command.ts b/src/transfer/command.ts index 62601dc3..a5f11736 100644 --- a/src/transfer/command.ts +++ b/src/transfer/command.ts @@ -18,12 +18,12 @@ export function entropyTransferCommand () { // TODO: destination as ? const entropy = await loadEntropyCli(opts) const transferService = new EntropyTransfer(entropy, opts.endpoint) - const { symbol } = await getTokenDetails(entropy) + const { symbol } = await getTokenDetails(entropy.substrate) await transferService.transfer(destination, amount) cliWrite({ - source: opts.account, + source: entropy.keyring.accounts.registration.address, destination, amount, symbol diff --git a/src/transfer/interaction.ts b/src/transfer/interaction.ts index 59ba6af6..4d32134a 100644 --- a/src/transfer/interaction.ts +++ b/src/transfer/interaction.ts @@ -14,7 +14,7 @@ export async function entropyTransfer (entropy, opts: EntropyTuiOptions) { transferSpinner.text = SPINNER_TEXT if (transferSpinner.isSpinning) transferSpinner.stop() try { - const { symbol } = await getTokenDetails(entropy) + const { symbol } = await getTokenDetails(entropy.substrate) const transferService = new EntropyTransfer(entropy, opts.endpoint) const { amount, recipientAddress } = await inquirer.prompt(transferInputQuestions) if (!transferSpinner.isSpinning) transferSpinner.start() From d1f6fa65936e6f934c1f706aa0f7076ca1e5b51a Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Mon, 16 Dec 2024 15:10:54 -0500 Subject: [PATCH 13/18] updated to only use generated substrate instead of entropy instance for balance flows --- src/balance/command.ts | 9 +++--- src/balance/interaction.ts | 17 ++++++----- src/balance/main.ts | 17 ++--------- src/common/substrate-utils.ts | 14 +++++++++ src/faucet/main.ts | 3 +- src/tui.ts | 2 +- tests/balance.test.ts | 55 +++++++++-------------------------- tests/faucet.test.ts | 6 ++-- tests/transfer.test.ts | 11 +++---- 9 files changed, 51 insertions(+), 83 deletions(-) create mode 100644 src/common/substrate-utils.ts diff --git a/src/balance/command.ts b/src/balance/command.ts index fe859a3e..559e7fe7 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -1,12 +1,13 @@ import { Command } from "commander"; // @ts-expect-error -import { createSubstrate, isValidSubstrateAddress } from '@entropyxyz/sdk/utils' +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 * 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') @@ -22,8 +23,7 @@ export function entropyBalanceCommand () { .addOption(configOption()) .addOption(endpointOption()) .action(async (account, opts) => { - const substrate = createSubstrate(opts.endpoint) - await substrate.isReadyOrError + const substrate = await getLoadedSubstrate(opts.endpoint) const { decimals, symbol } = await getTokenDetails(substrate) const toBits = (lilBits: number) => round(lilBitsToBits(lilBits, decimals)) const { accounts } = await config.get(opts.config) @@ -60,8 +60,7 @@ export function entropyBalanceCommand () { cliWrite({ account, balance, symbol }) } // closing substrate - await substrate.disconnect() - .catch(err => console.error('Error closing connection', err.message)) + await closeSubstrate(substrate) process.exit(0) }) diff --git a/src/balance/interaction.ts b/src/balance/interaction.ts index 58131bb7..3173b855 100644 --- a/src/balance/interaction.ts +++ b/src/balance/interaction.ts @@ -1,17 +1,20 @@ -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) // grabbing decimals from chain spec as that is the source of truth for the value - const { decimals, symbol } = await getTokenDetails(entropy.substrate) - 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 EntropyBalance.getAnyBalance(substrate, 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 e51ed49f..678eb784 100644 --- a/src/balance/main.ts +++ b/src/balance/main.ts @@ -1,13 +1,8 @@ -import Entropy from "@entropyxyz/sdk" -import { EntropyBase } from "../common/entropy-base" import * as BalanceUtils from "./utils" import { BalanceInfo } from "./types" -const FLOW_CONTEXT = 'ENTROPY-BALANCE' -export class EntropyBalance extends EntropyBase { - constructor (entropy: Entropy, endpoint: string) { - super({ entropy, endpoint, flowContext: FLOW_CONTEXT }) - } +export class EntropyBalance { + constructor () {} static async getAnyBalance (substrate, address: string) { const accountInfo = (await substrate.query.system.account(address)) as any @@ -29,12 +24,4 @@ export class EntropyBalance extends EntropyBase { }) ) } - - async getBalance (address: string): Promise { - const accountInfo = (await this.entropy.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 - } } diff --git a/src/common/substrate-utils.ts b/src/common/substrate-utils.ts new file mode 100644 index 00000000..17969016 --- /dev/null +++ b/src/common/substrate-utils.ts @@ -0,0 +1,14 @@ +// @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) { + // closing substrate + return await substrate.disconnect() + .catch(err => console.error('Error closing connection', err.message)) +} \ No newline at end of file diff --git a/src/faucet/main.ts b/src/faucet/main.ts index 84346b59..103aaf02 100644 --- a/src/faucet/main.ts +++ b/src/faucet/main.ts @@ -71,11 +71,10 @@ 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) // check balance of faucet address - const balance = await balanceService.getBalance(faucetAddress) + const balance = await EntropyBalance.getAnyBalance(this.entropy.substrate, 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/tui.ts b/src/tui.ts index 35f3f00f..cd876048 100644 --- a/src/tui.ts +++ b/src/tui.ts @@ -155,7 +155,7 @@ 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 } diff --git a/tests/balance.test.ts b/tests/balance.test.ts index 20a9c1ab..e14ef13a 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -1,28 +1,27 @@ import test from 'tape' +import { createSubstrate } from '@entropyxyz/sdk/utils' -import { setupTest, charlieStashAddress as richAddress, promiseRunner, DEFAULT_ENDPOINT, eveAddress } from './testing-utils' import { EntropyBalance } from '../src/balance/main' import { EntropyAccount } from '../src/account/main' -// @ts-expect-error -import { createSubstrate } from '@entropyxyz/sdk/utils' +import { closeSubstrate } 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 - const substrate = createSubstrate(endpoint) - await run('substrate ready', substrate.isReadyOrError) +import { charlieStashAddress as richAddress, promiseRunner, DEFAULT_ENDPOINT, eveAddress } 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 = createSubstrate(DEFAULT_ENDPOINT) + await run('substrate ready', substrate.isReadyOrError) const newAddressBalance = await run( - 'getBalance (newSeed)', - balanceService.getBalance(newAddress) + 'getAnyBalance (newAccount)', + EntropyBalance.getAnyBalance(substrate, newAddress) ) t.equal(newAddressBalance, 0, 'newSeed balance = 0') const richAddressBalance = await run( 'getBalance (richAddress)', - balanceService.getBalance(richAddress) + EntropyBalance.getAnyBalance(substrate, richAddress) ) t.true(richAddressBalance > BigInt(10e10), 'richAddress balance >>> 0') @@ -50,7 +49,7 @@ test('getBalance + getBalances', async (t) => { const match = balancesWithNoGoodAddress.find(info => info.address === addr) t.true(!!match.error, `error field is populated for ${addr}`) }) - await run('close substrate', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) + await run('close substrate', closeSubstrate(substrate)) // TODO: // - test getBalances with 1 good address, 1 bung seed @@ -58,34 +57,6 @@ test('getBalance + getBalances', async (t) => { t.end() }) -test('getAnyBalance: new account', async (t) => { - const run = promiseRunner(t) - // create new account, not saved in config - const newAccount = await EntropyAccount.create({ name: 'TestAnyBalance1' }) - const substrate = createSubstrate(DEFAULT_ENDPOINT) - await run('substrate ready', substrate.isReadyOrError) - const balance = await run( - 'getAnyBalance (newAccount)', - EntropyBalance.getAnyBalance(substrate, newAccount.address) - ) - t.equal(balance, 0, 'newSeed balance = 0') - await run('close substrate', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) - t.end() -}) - -test('getAnyBalance: test account', async (t) => { - const run = promiseRunner(t) - const substrate = createSubstrate(DEFAULT_ENDPOINT) - await run('substrate ready', substrate.isReadyOrError) - const balance = await run( - 'getAnyBalance (eve account)', - EntropyBalance.getAnyBalance(substrate, eveAddress) - ) - t.true(balance > BigInt(10e10), 'richAddress balance >>> 0') - await run('close substrate', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) - t.end() -}) - test('getAnyBalance: bad account', async (t) => { const run = promiseRunner(t) const substrate = createSubstrate(DEFAULT_ENDPOINT) diff --git a/tests/faucet.test.ts b/tests/faucet.test.ts index 61941cb6..122b466f 100644 --- a/tests/faucet.test.ts +++ b/tests/faucet.test.ts @@ -77,9 +77,8 @@ 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) - let naynayBalance = await balance.getBalance(naynayAddress) + let naynayBalance = await EntropyBalance.getAnyBalance(naynay.substrate, naynayAddress) t.equal(naynayBalance, 0, 'Naynay is broke af') // 2 BITS @@ -96,7 +95,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 EntropyBalance.getAnyBalance(naynay.substrate, naynayAddress) t.equal(naynayBalance, amount, 'Naynay is drippin in faucet tokens') // Test if user can register after receiving funds @@ -106,7 +105,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/transfer.test.ts b/tests/transfer.test.ts index c66900c6..c4e25f91 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -6,28 +6,25 @@ import { EntropyBalance } from '../src/balance/main' import { promiseRunner, setupTest } from './testing-utils' import { charlieStashAddress, charlieStashSeed, DEFAULT_TOKEN_DECIMALS } from './testing-utils/constants.mjs' -const endpoint = 'ws://127.0.0.1:9944' - test('Transfer', async (t) => { /* Setup */ const run = promiseRunner(t) - const { entropy: charlie }= await setupTest(t, { seed: charlieStashSeed }) + const { entropy: charlie, endpoint }= await setupTest(t, { seed: charlieStashSeed }) const { entropy: naynay } = await setupTest(t) const naynayAddress = naynay.keyring.accounts.registration.address // Check initial balances - const balanceService = new EntropyBalance(naynay, endpoint) let naynayBalance = await run( 'getBalance (naynay)', - balanceService.getBalance(naynayAddress) + EntropyBalance.getAnyBalance(naynay.substrate, naynayAddress) ) t.equal(naynayBalance, 0, 'naynay is broke') let charlieBalance = await run( 'getBalance (charlieStash)', - balanceService.getBalance(charlieStashAddress) + EntropyBalance.getAnyBalance(charlie.substrate, charlieStashAddress) ) t.true(charlieBalance > 9e16, 'charlie got bank') @@ -42,7 +39,7 @@ test('Transfer', async (t) => { // Re-Check balance naynayBalance = await run( 'getBalance (naynay)', - balanceService.getBalance(naynayAddress) + EntropyBalance.getAnyBalance(naynay.substrate, naynayAddress) ) const expected = Number(inputAmount) * lilBitsPerBits(DEFAULT_TOKEN_DECIMALS) t.equal(naynayBalance, expected, 'naynay is rolling in it!') From 3e103b8761891c25e1588d2807a07146fdceb865 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Mon, 16 Dec 2024 18:16:45 -0500 Subject: [PATCH 14/18] [NayNay] Only substrate - updated trasnfer to only need substrate rather than the entire entropy instance --- src/common/utils.ts | 5 ++--- src/faucet/main.ts | 2 +- src/transfer/command.ts | 4 ++-- src/transfer/interaction.ts | 4 ++-- src/transfer/main.ts | 35 +++++++++++++++++++++++------------ tests/account.test.ts | 6 +++--- tests/faucet.test.ts | 4 ++-- tests/transfer.test.ts | 4 ++-- 8 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/common/utils.ts b/src/common/utils.ts index 80174397..86f67385 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 diff --git a/src/faucet/main.ts b/src/faucet/main.ts index 103aaf02..9b875e28 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) diff --git a/src/transfer/command.ts b/src/transfer/command.ts index a5f11736..5d22f66a 100644 --- a/src/transfer/command.ts +++ b/src/transfer/command.ts @@ -17,10 +17,10 @@ export function entropyTransferCommand () { .action(async (destination, amount, opts) => { // TODO: destination as ? const entropy = await loadEntropyCli(opts) - const transferService = new EntropyTransfer(entropy, opts.endpoint) + const transferService = new EntropyTransfer(opts.endpoint) const { symbol } = await getTokenDetails(entropy.substrate) - await transferService.transfer(destination, amount) + await transferService.transfer(entropy.keyring.accounts.registration.pair, destination, amount) cliWrite({ source: entropy.keyring.accounts.registration.address, diff --git a/src/transfer/interaction.ts b/src/transfer/interaction.ts index 4d32134a..454238d0 100644 --- a/src/transfer/interaction.ts +++ b/src/transfer/interaction.ts @@ -15,10 +15,10 @@ export async function entropyTransfer (entropy, opts: EntropyTuiOptions) { if (transferSpinner.isSpinning) transferSpinner.stop() try { const { symbol } = await getTokenDetails(entropy.substrate) - const transferService = new EntropyTransfer(entropy, opts.endpoint) + const transferService = new EntropyTransfer(opts.endpoint) const { amount, recipientAddress } = await inquirer.prompt(transferInputQuestions) if (!transferSpinner.isSpinning) transferSpinner.start() - await transferService.transfer(recipientAddress, amount) + await transferService.transfer(entropy.keyring.accounts.registration.pair, recipientAddress, amount) if (transferSpinner.isSpinning) transferSpinner.stop() print('') print(`Transaction successful: Sent ${amount} ${symbol} to ${recipientAddress}`) diff --git a/src/transfer/main.ts b/src/transfer/main.ts index a22f035e..d65c608c 100644 --- a/src/transfer/main.ts +++ b/src/transfer/main.ts @@ -1,14 +1,21 @@ -import Entropy from "@entropyxyz/sdk"; +// @ts-ignore +import { Pair } from '@entropyxyz/sdk/keys' -import { EntropyBase } from "../common/entropy-base"; +import { closeSubstrate, getLoadedSubstrate } from "../common/substrate-utils"; +import { EntropyLogger } from "../common/logger"; import { bitsToLilBits, formatDispatchError, getTokenDetails } from "../common/utils"; + import { TransferOptions } from "./types"; const FLOW_CONTEXT = 'ENTROPY_TRANSFER' -export class EntropyTransfer extends EntropyBase { - constructor (entropy: Entropy, endpoint: string) { - super({ entropy, endpoint, flowContext: FLOW_CONTEXT }) +export class EntropyTransfer { + private readonly substrate: any + private readonly logger: EntropyLogger + private readonly endpoint: string + constructor (endpoint: string) { + this.logger = new EntropyLogger(FLOW_CONTEXT, endpoint) + this.endpoint = endpoint } // NOTE: a more accessible function which handles @@ -16,29 +23,33 @@ export class EntropyTransfer extends EntropyBase { // - converting `amount` (string => BigInt) // - progress callbacks (optional) - async transfer (toAddress: string, amountInBits: string) { - const { decimals } = await getTokenDetails(this.entropy.substrate) + async transfer (from: Pair, toAddress: string, amountInBits: string) { + const substrate = await getLoadedSubstrate(this.endpoint) + const { decimals } = await getTokenDetails(substrate) const lilBits = bitsToLilBits(Number(amountInBits), decimals) - return this.rawTransfer({ - from: this.entropy.keyring.accounts.registration.pair, + const transferStatus = await this.rawTransfer(substrate, { + from, to: toAddress, lilBits }) + + await closeSubstrate(substrate) + return transferStatus } - private async rawTransfer (payload: TransferOptions): Promise { + private async rawTransfer (substrate: any, payload: TransferOptions): Promise { const { from, to, lilBits } = payload 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 + 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/tests/account.test.ts b/tests/account.test.ts index 645801cc..d6e60360 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(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/faucet.test.ts b/tests/faucet.test.ts index 122b466f..ffc3394f 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(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 } } diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index c4e25f91..d1bc82ee 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -29,11 +29,11 @@ test('Transfer', async (t) => { t.true(charlieBalance > 9e16, 'charlie got bank') // Do transer - const transferService = new EntropyTransfer(charlie, endpoint) + const transferService = new EntropyTransfer(endpoint) const inputAmount = "1.5" await run( 'transfer', - transferService.transfer(naynayAddress, inputAmount) + transferService.transfer(charlie.keyring.accounts.registration.pair, naynayAddress, inputAmount) ) // Re-Check balance From afe5fa09a5aabfcee2e1981bee9ec294db9012e7 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Mon, 16 Dec 2024 18:24:11 -0500 Subject: [PATCH 15/18] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d3df9ef..cf219492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ 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) From 6fa210a5a1bd1dddc4f808d86a7f3da1b804ccbd Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 18 Dec 2024 13:38:38 -0500 Subject: [PATCH 16/18] completely removed entropy instance from full transfer flow --- src/common/load-entropy.ts | 2 +- src/transfer/command.ts | 18 ++++++++++++------ src/transfer/interaction.ts | 16 ++++++++++++---- src/tui.ts | 2 +- tests/transfer.test.ts | 38 ++++++++++++++++++++++--------------- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/src/common/load-entropy.ts b/src/common/load-entropy.ts index fdd77f89..0abc1a8c 100644 --- a/src/common/load-entropy.ts +++ b/src/common/load-entropy.ts @@ -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/transfer/command.ts b/src/transfer/command.ts index 5d22f66a..70a3ab6a 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 { 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(opts.endpoint) - const { symbol } = await getTokenDetails(entropy.substrate) + const { symbol } = await getTokenDetails(substrate) - await transferService.transfer(entropy.keyring.accounts.registration.pair, destination, amount) + await transferService.transfer(loadedKeyring.accounts.registration.pair, destination, amount) cliWrite({ - source: entropy.keyring.accounts.registration.address, + 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 454238d0..b91d05f0 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.substrate) + 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(opts.endpoint) const { amount, recipientAddress } = await inquirer.prompt(transferInputQuestions) if (!transferSpinner.isSpinning) transferSpinner.start() - await transferService.transfer(entropy.keyring.accounts.registration.pair, 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/tui.ts b/src/tui.ts index cd876048..01b208ea 100644 --- a/src/tui.ts +++ b/src/tui.ts @@ -160,7 +160,7 @@ async function main (entropy: Entropy, choices: string[], opts: EntropyTuiOption 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/transfer.test.ts b/tests/transfer.test.ts index d1bc82ee..97c077df 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -1,30 +1,38 @@ 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 { closeSubstrate, getLoadedSubstrate } from '../src/common/substrate-utils' +import { lilBitsPerBits } from "../src/common/utils" +import { EntropyTransfer } from '../src/transfer/main' + +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, endpoint }= 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 naynayAddress = naynay.address + const charlieKeyring = new Keyring({ seed: charlieStashSeed, path: '', debug: true }) // Check initial balances let naynayBalance = await run( 'getBalance (naynay)', - EntropyBalance.getAnyBalance(naynay.substrate, naynayAddress) + EntropyBalance.getAnyBalance(substrate, naynayAddress) ) t.equal(naynayBalance, 0, 'naynay is broke') let charlieBalance = await run( 'getBalance (charlieStash)', - EntropyBalance.getAnyBalance(charlie.substrate, charlieStashAddress) + EntropyBalance.getAnyBalance(substrate, charlieStashAddress) ) t.true(charlieBalance > 9e16, 'charlie got bank') @@ -33,16 +41,16 @@ test('Transfer', async (t) => { const inputAmount = "1.5" await run( 'transfer', - transferService.transfer(charlie.keyring.accounts.registration.pair, naynayAddress, inputAmount) + transferService.transfer(charlieKeyring.accounts.registration.pair, naynayAddress, inputAmount) ) // Re-Check balance naynayBalance = await run( 'getBalance (naynay)', - EntropyBalance.getAnyBalance(naynay.substrate, naynayAddress) + EntropyBalance.getAnyBalance(substrate, 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() }) From 3223ce1685943d59972d78c875f4b05d7d13bb93 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 18 Dec 2024 15:11:17 -0500 Subject: [PATCH 17/18] updated to use class instantiation for balance, created new substrate base class --- src/balance/command.ts | 5 +++-- src/balance/interaction.ts | 3 ++- src/balance/main.ts | 16 ++++++++++------ src/common/entropy-substrate-base.ts | 13 +++++++++++++ src/faucet/main.ts | 3 ++- tests/account.test.ts | 2 +- tests/balance.test.ts | 25 ++++++++++++------------- tests/faucet.test.ts | 5 +++-- tests/transfer.test.ts | 14 +++++++------- 9 files changed, 53 insertions(+), 33 deletions(-) create mode 100644 src/common/entropy-substrate-base.ts diff --git a/src/balance/command.ts b/src/balance/command.ts index 559e7fe7..4278a5fb 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -24,13 +24,14 @@ export function entropyBalanceCommand () { .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) if (opts.all) { // Balances for all admin accounts const addresses: string[] = accounts.map((acct: EntropyConfigAccount) => acct.address) - const balances = await EntropyBalance.getBalances(substrate, addresses) + const balances = await BalanceService.getBalances(addresses) .then((infos: BalanceInfo[]) => { return infos.map(info => { return { @@ -55,7 +56,7 @@ export function entropyBalanceCommand () { } } // Balance for singular account - const balance = await EntropyBalance.getAnyBalance(substrate, address) + const balance = await BalanceService.getAnyBalance(address) .then(toBits) cliWrite({ account, balance, symbol }) } diff --git a/src/balance/interaction.ts b/src/balance/interaction.ts index 3173b855..a19c9db0 100644 --- a/src/balance/interaction.ts +++ b/src/balance/interaction.ts @@ -7,10 +7,11 @@ 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(substrate) const address = findAccountByAddressOrName(storedConfig.accounts, storedConfig.selectedAccount)?.address - const lilBalance = await EntropyBalance.getAnyBalance(substrate, 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 diff --git a/src/balance/main.ts b/src/balance/main.ts index 678eb784..1f5d3bf0 100644 --- a/src/balance/main.ts +++ b/src/balance/main.ts @@ -1,20 +1,24 @@ import * as BalanceUtils from "./utils" import { BalanceInfo } from "./types" +import { EntropySubstrateBase } from "src/common/entropy-substrate-base" -export class EntropyBalance { - constructor () {} +const FLOW_CONTEXT = 'ENTROPY-BALANCE' +export class EntropyBalance extends EntropySubstrateBase { + constructor (substrate, endpoint) { + super({ substrate, endpoint, flowContext: FLOW_CONTEXT }) + } - static async getAnyBalance (substrate, address: string) { - const accountInfo = (await 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()) return balance } - static async getBalances (substrate, addresses: string[]): Promise { + async getBalances (addresses: string[]): Promise { return Promise.all( addresses.map(async address => { - return EntropyBalance.getAnyBalance(substrate, 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 00000000..9d5b674e --- /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/faucet/main.ts b/src/faucet/main.ts index 103aaf02..dbd3d6b8 100644 --- a/src/faucet/main.ts +++ b/src/faucet/main.ts @@ -72,9 +72,10 @@ export class EntropyFaucet extends EntropyBase { }: SendMoneyParams ): Promise { 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 EntropyBalance.getAnyBalance(this.entropy.substrate, 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/tests/account.test.ts b/tests/account.test.ts index 645801cc..eb41c2a1 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) diff --git a/tests/balance.test.ts b/tests/balance.test.ts index e14ef13a..affaa0fa 100644 --- a/tests/balance.test.ts +++ b/tests/balance.test.ts @@ -1,34 +1,33 @@ import test from 'tape' -import { createSubstrate } from '@entropyxyz/sdk/utils' import { EntropyBalance } from '../src/balance/main' import { EntropyAccount } from '../src/account/main' -import { closeSubstrate } from '../src/common/substrate-utils' +import { closeSubstrate, getLoadedSubstrate } from '../src/common/substrate-utils' -import { charlieStashAddress as richAddress, promiseRunner, DEFAULT_ENDPOINT, eveAddress } from './testing-utils' +import { charlieStashAddress as richAddress, promiseRunner, DEFAULT_ENDPOINT } from './testing-utils' 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 = createSubstrate(DEFAULT_ENDPOINT) - await run('substrate ready', substrate.isReadyOrError) + const substrate = await run('load substrate', getLoadedSubstrate(DEFAULT_ENDPOINT)) + const BalanceService = new EntropyBalance(substrate, DEFAULT_ENDPOINT) const newAddressBalance = await run( 'getAnyBalance (newAccount)', - EntropyBalance.getAnyBalance(substrate, newAddress) + BalanceService.getAnyBalance(newAddress) ) t.equal(newAddressBalance, 0, 'newSeed balance = 0') const richAddressBalance = await run( 'getBalance (richAddress)', - EntropyBalance.getAnyBalance(substrate, richAddress) + BalanceService.getAnyBalance(richAddress) ) t.true(richAddressBalance > BigInt(10e10), 'richAddress balance >>> 0') /* getBalances */ const balances = await run( 'getBalances', - EntropyBalance.getBalances(substrate, [newAddress, richAddress]) + BalanceService.getBalances([newAddress, richAddress]) ) t.deepEqual( balances, @@ -42,7 +41,7 @@ test('getAnyBalance + getBalances', async (t) => { const badAddresses = ['5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhr', '5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhrfnD'] const balancesWithNoGoodAddress = await run( 'getBalances::one good address', - EntropyBalance.getBalances(substrate, badAddresses) + BalanceService.getBalances(badAddresses) ) badAddresses.forEach((addr) => { @@ -59,11 +58,11 @@ test('getAnyBalance + getBalances', async (t) => { test('getAnyBalance: bad account', async (t) => { const run = promiseRunner(t) - const substrate = createSubstrate(DEFAULT_ENDPOINT) - await run('substrate ready', substrate.isReadyOrError) - await EntropyBalance.getAnyBalance(substrate, 'not-a-real-account') + 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', substrate.disconnect().catch(err => console.error('Error closing connection', err.message))) + await run('close substrate', closeSubstrate(substrate)) t.end() }) diff --git a/tests/faucet.test.ts b/tests/faucet.test.ts index 122b466f..b6bb9b73 100644 --- a/tests/faucet.test.ts +++ b/tests/faucet.test.ts @@ -77,8 +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 BalanceService = new EntropyBalance(naynay.substrate, endpoint) - let naynayBalance = await EntropyBalance.getAnyBalance(naynay.substrate, naynayAddress) + let naynayBalance = await BalanceService.getAnyBalance(naynayAddress) t.equal(naynayBalance, 0, 'Naynay is broke af') // 2 BITS @@ -95,7 +96,7 @@ test('Faucet Tests: Successfully send funds and register', async t => { ) t.ok(transferStatus.isFinalized, 'Transfer is good') - naynayBalance = await EntropyBalance.getAnyBalance(naynay.substrate, naynayAddress) + naynayBalance = await BalanceService.getAnyBalance(naynayAddress) t.equal(naynayBalance, amount, 'Naynay is drippin in faucet tokens') // Test if user can register after receiving funds diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index c4e25f91..822f5611 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -8,28 +8,28 @@ import { charlieStashAddress, charlieStashSeed, DEFAULT_TOKEN_DECIMALS } from '. test('Transfer', async (t) => { /* Setup */ - const run = promiseRunner(t) - - const { entropy: charlie, endpoint }= await setupTest(t, { seed: charlieStashSeed }) + const { run, entropy: charlie, endpoint }= await setupTest(t, { seed: charlieStashSeed }) const { entropy: naynay } = await setupTest(t) + const transferService = new EntropyTransfer(charlie, endpoint) + const BalanceService = new EntropyBalance(charlie.substrate, endpoint) + const naynayAddress = naynay.keyring.accounts.registration.address // Check initial balances let naynayBalance = await run( 'getBalance (naynay)', - EntropyBalance.getAnyBalance(naynay.substrate, naynayAddress) + BalanceService.getAnyBalance(naynayAddress) ) t.equal(naynayBalance, 0, 'naynay is broke') let charlieBalance = await run( 'getBalance (charlieStash)', - EntropyBalance.getAnyBalance(charlie.substrate, 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', @@ -39,7 +39,7 @@ test('Transfer', async (t) => { // Re-Check balance naynayBalance = await run( 'getBalance (naynay)', - EntropyBalance.getAnyBalance(naynay.substrate, naynayAddress) + BalanceService.getAnyBalance(naynayAddress) ) const expected = Number(inputAmount) * lilBitsPerBits(DEFAULT_TOKEN_DECIMALS) t.equal(naynayBalance, expected, 'naynay is rolling in it!') From 811cf733f7effeb672cdf7bdcd79e851f1b6f2b9 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 18 Dec 2024 17:24:37 -0500 Subject: [PATCH 18/18] pr updates --- src/account/utils.ts | 2 +- src/balance/main.ts | 2 +- src/common/substrate-utils.ts | 10 +++++++--- src/transfer/command.ts | 2 +- src/transfer/interaction.ts | 2 +- src/transfer/main.ts | 23 ++++++++--------------- tests/account.test.ts | 2 +- tests/faucet.test.ts | 2 +- tests/transfer.test.ts | 2 +- 9 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/account/utils.ts b/src/account/utils.ts index 206babf1..55b849dd 100644 --- a/src/account/utils.ts +++ b/src/account/utils.ts @@ -32,7 +32,7 @@ export async function persistVerifyingKeyToAccount (configPath: string, verifyin const storedConfig = await config.get(configPath) const { accounts } = storedConfig - const account = findAccountByAddressOrName(accounts, accountNameOrAddress || storedConfig.selectedAccount) + const account = findAccountByAddressOrName(accounts, accountNameOrAddress) if (!account) throw Error(`Unable to persist verifyingKey "${verifyingKey}" to unknown account "${accountNameOrAddress}"`) // persist to config, set selectedAccount diff --git a/src/balance/main.ts b/src/balance/main.ts index 1f5d3bf0..8b1d3790 100644 --- a/src/balance/main.ts +++ b/src/balance/main.ts @@ -4,7 +4,7 @@ import { EntropySubstrateBase } from "src/common/entropy-substrate-base" const FLOW_CONTEXT = 'ENTROPY-BALANCE' export class EntropyBalance extends EntropySubstrateBase { - constructor (substrate, endpoint) { + constructor (substrate: any, endpoint: string) { super({ substrate, endpoint, flowContext: FLOW_CONTEXT }) } diff --git a/src/common/substrate-utils.ts b/src/common/substrate-utils.ts index 17969016..9d5ef1a4 100644 --- a/src/common/substrate-utils.ts +++ b/src/common/substrate-utils.ts @@ -8,7 +8,11 @@ export async function getLoadedSubstrate (endpoint: string) { } export async function closeSubstrate (substrate: any) { - // closing substrate - return await substrate.disconnect() - .catch(err => console.error('Error closing connection', err.message)) + 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/transfer/command.ts b/src/transfer/command.ts index 70a3ab6a..20a3016b 100644 --- a/src/transfer/command.ts +++ b/src/transfer/command.ts @@ -22,7 +22,7 @@ export function entropyTransferCommand () { const substrate = await getLoadedSubstrate(opts.endpoint) const account = findAccountByAddressOrName(accounts, opts.account || selectedAccount) const loadedKeyring = await loadKeyring(account) - const transferService = new EntropyTransfer(opts.endpoint) + const transferService = new EntropyTransfer(substrate, opts.endpoint) const { symbol } = await getTokenDetails(substrate) await transferService.transfer(loadedKeyring.accounts.registration.pair, destination, amount) diff --git a/src/transfer/interaction.ts b/src/transfer/interaction.ts index b91d05f0..f199d987 100644 --- a/src/transfer/interaction.ts +++ b/src/transfer/interaction.ts @@ -21,7 +21,7 @@ export async function entropyTransfer (opts: EntropyTuiOptions, storedConfig: En const currentAccount = findAccountByAddressOrName(storedConfig.accounts, opts.account || storedConfig.selectedAccount) const loadedKeyring = await loadKeyring(currentAccount) const { symbol } = await getTokenDetails(substrate) - const transferService = new EntropyTransfer(opts.endpoint) + const transferService = new EntropyTransfer(substrate, opts.endpoint) const { amount, recipientAddress } = await inquirer.prompt(transferInputQuestions) if (!transferSpinner.isSpinning) transferSpinner.start() await transferService.transfer(loadedKeyring.accounts.registration.pair, recipientAddress, amount) diff --git a/src/transfer/main.ts b/src/transfer/main.ts index d65c608c..61968b3d 100644 --- a/src/transfer/main.ts +++ b/src/transfer/main.ts @@ -1,21 +1,16 @@ // @ts-ignore import { Pair } from '@entropyxyz/sdk/keys' -import { closeSubstrate, getLoadedSubstrate } from "../common/substrate-utils"; -import { EntropyLogger } from "../common/logger"; 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 { - private readonly substrate: any - private readonly logger: EntropyLogger - private readonly endpoint: string - constructor (endpoint: string) { - this.logger = new EntropyLogger(FLOW_CONTEXT, endpoint) - this.endpoint = endpoint +export class EntropyTransfer extends EntropySubstrateBase { + constructor (substrate: any, endpoint: string) { + super({ substrate, endpoint, flowContext: FLOW_CONTEXT }) } // NOTE: a more accessible function which handles @@ -24,27 +19,25 @@ export class EntropyTransfer { // - progress callbacks (optional) async transfer (from: Pair, toAddress: string, amountInBits: string) { - const substrate = await getLoadedSubstrate(this.endpoint) - const { decimals } = await getTokenDetails(substrate) + const { decimals } = await getTokenDetails(this.substrate) const lilBits = bitsToLilBits(Number(amountInBits), decimals) - const transferStatus = await this.rawTransfer(substrate, { + const transferStatus = await this.rawTransfer({ from, to: toAddress, lilBits }) - await closeSubstrate(substrate) return transferStatus } - private async rawTransfer (substrate: any, payload: TransferOptions): Promise { + private async rawTransfer (payload: TransferOptions): Promise { const { from, to, lilBits } = payload return new Promise((resolve, reject) => { // WARN: await signAndSend is dangerous as it does not resolve // after transaction is complete :melt: - substrate.tx.balances + this.substrate.tx.balances .transferAllowDeath(to, lilBits) // @ts-ignore .signAndSend(from, ({ status, dispatchError }) => { diff --git a/tests/account.test.ts b/tests/account.test.ts index d6e60360..c12a0a6b 100644 --- a/tests/account.test.ts +++ b/tests/account.test.ts @@ -84,7 +84,7 @@ 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(endpoint) + const transfer = new EntropyTransfer(charlie.substrate, endpoint) await transfer.transfer(charlie.keyring.accounts.registration.pair, entropy.keyring.accounts.registration.address, "1000") } diff --git a/tests/faucet.test.ts b/tests/faucet.test.ts index 2d9fb173..94a8ca1b 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(endpoint) + const transfer = new EntropyTransfer(entropy.substrate, endpoint) const faucet = new EntropyFaucet(entropy, endpoint) // Deploy faucet program diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index e11a8a7b..ad4f65f3 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -20,7 +20,7 @@ test('Transfer', async (t) => { // 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(endpoint) + const transferService = new EntropyTransfer(substrate, endpoint) const BalanceService = new EntropyBalance(substrate, endpoint) const naynayAddress = naynay.address