From baf47824473cbc6d062ef845512f8449b9b4ca8e Mon Sep 17 00:00:00 2001 From: Aik Chun Date: Wed, 23 Jun 2021 13:30:02 +0800 Subject: [PATCH] Added getBalances RPC (#362) --- .../category/wallet/getBalances.test.ts | 99 +++++++++++++++++++ .../jellyfish-api-core/src/category/wallet.ts | 27 +++++ website/docs/jellyfish/api/wallet.md | 27 +++++ 3 files changed, 153 insertions(+) create mode 100644 packages/jellyfish-api-core/__tests__/category/wallet/getBalances.test.ts diff --git a/packages/jellyfish-api-core/__tests__/category/wallet/getBalances.test.ts b/packages/jellyfish-api-core/__tests__/category/wallet/getBalances.test.ts new file mode 100644 index 0000000000..1bd4cf7a29 --- /dev/null +++ b/packages/jellyfish-api-core/__tests__/category/wallet/getBalances.test.ts @@ -0,0 +1,99 @@ +import { MasterNodeRegTestContainer, RegTestContainer } from '@defichain/testcontainers' +import { ContainerAdapterClient } from '../../container_adapter_client' +import { BigNumber } from 'bignumber.js' +import { WalletFlag, WalletBalances } from '../../../src/category/wallet' + +// TODO(aikchun): Add behavior tests for untrusted_pending, immature, used. Currently unable to do multi-node testing +describe('getBalances on masternode', () => { + const container = new MasterNodeRegTestContainer() + const client = new ContainerAdapterClient(container) + + beforeAll(async () => { + await container.start() + await container.waitForReady() + await container.waitForWalletCoinbaseMaturity() + }) + + afterAll(async () => { + await container.stop() + }) + + it('should getBalances', async () => { + const balances: WalletBalances = await client.wallet.getBalances() + expect(BigNumber.isBigNumber(balances.mine.trusted)).toStrictEqual(true) + expect(BigNumber.isBigNumber(balances.mine.untrusted_pending)).toStrictEqual(true) + expect(BigNumber.isBigNumber(balances.mine.immature)).toStrictEqual(true) + expect(typeof balances.mine.used).toStrictEqual('undefined') + + expect(typeof balances.watchonly).toStrictEqual('undefined') + }) + + it('should show balances after sending the amount out', async () => { + const balanceBefore: WalletBalances = await client.wallet.getBalances() + + await client.wallet.sendToAddress('bcrt1q2tke5fa7wx26m684d7yuyt85rvjl36u6q8l6e2', 10000) + await container.generate(1) + + const balanceAfter: WalletBalances = await client.wallet.getBalances() + + expect(balanceBefore.mine.trusted.gt(balanceAfter.mine.trusted)).toStrictEqual(true) + }) + + it('test watchOnly', async () => { + await container.call('importaddress', ['bcrt1q2tke5fa7wx26m684d7yuyt85rvjl36u6q8l6e2']) + + const balances: WalletBalances = await client.wallet.getBalances() + + expect(BigNumber.isBigNumber(balances.watchonly?.trusted)).toStrictEqual(true) + expect(BigNumber.isBigNumber(balances.watchonly?.untrusted_pending)).toStrictEqual(true) + expect(BigNumber.isBigNumber(balances.watchonly?.immature)).toStrictEqual(true) + }) +}) + +describe('getBalances without masternode', () => { + const container = new RegTestContainer() + const client = new ContainerAdapterClient(container) + + beforeAll(async () => { + await container.start() + await container.waitForReady() + }) + + afterAll(async () => { + await container.stop() + }) + + it('should getBalances.mine.trusted = 0', async () => { + const balances: WalletBalances = await client.wallet.getBalances() + + expect(balances.mine.trusted.isEqualTo(new BigNumber('0'))).toStrictEqual(true) + }) +}) + +describe('getBalances when wallet is set to avoid_reuse', () => { + const container = new MasterNodeRegTestContainer() + const client = new ContainerAdapterClient(container) + + beforeAll(async () => { + await container.start() + await container.waitForReady() + await container.waitForWalletCoinbaseMaturity() + await client.wallet.setWalletFlag(WalletFlag.AVOID_REUSE) + await container.generate(1) + }) + + afterAll(async () => { + await container.stop() + }) + + it('should have used', async () => { + const balances: WalletBalances = await client.wallet.getBalances() + + expect(BigNumber.isBigNumber(balances.mine.trusted)).toStrictEqual(true) + expect(BigNumber.isBigNumber(balances.mine.untrusted_pending)).toStrictEqual(true) + expect(BigNumber.isBigNumber(balances.mine.immature)).toStrictEqual(true) + expect(BigNumber.isBigNumber(balances.mine.used)).toStrictEqual(true) + + expect(typeof balances.watchonly).toStrictEqual('undefined') + }) +}) diff --git a/packages/jellyfish-api-core/src/category/wallet.ts b/packages/jellyfish-api-core/src/category/wallet.ts index 3b30ff1330..74f04a6889 100644 --- a/packages/jellyfish-api-core/src/category/wallet.ts +++ b/packages/jellyfish-api-core/src/category/wallet.ts @@ -72,6 +72,15 @@ export class Wallet { return await this.client.call('getunconfirmedbalance', [false], 'bignumber') } + /** + * Returns an object with all balances. + * + * @return {Promise} + */ + async getBalances (): Promise { + return await this.client.call('getbalances', [false], 'bignumber') + } + /** * Get list of UTXOs in wallet. * @@ -472,3 +481,21 @@ export interface InWalletTransactionDetail { fee: number abandoned: boolean } + +export interface WalletBalances { + mine: WalletMineBalances + watchonly?: WalletWatchOnlyBalances +} + +export interface WalletMineBalances { + trusted: BigNumber + untrusted_pending: BigNumber + immature: BigNumber + used?: BigNumber +} + +export interface WalletWatchOnlyBalances { + trusted: BigNumber + untrusted_pending: BigNumber + immature: BigNumber +} diff --git a/website/docs/jellyfish/api/wallet.md b/website/docs/jellyfish/api/wallet.md index 8c9f9b543b..c4650ffb4f 100644 --- a/website/docs/jellyfish/api/wallet.md +++ b/website/docs/jellyfish/api/wallet.md @@ -36,6 +36,33 @@ Identical to getBalance to get untrusted pending balance. ```ts title="client.wallet.getUnconfirmedBalance()" interface wallet { getUnconfirmedBalance (): Promise +``` + +## getBalances + +Returns an object with all balances. + +```ts title="client.wallet.getBalances()" +interface wallet { + getBalances (): Promise +} + +interface WalletBalances { + mine: WalletMineBalances + watchonly?: WalletWatchOnlyBalances +} + +interface WalletMineBalances { + trusted: BigNumber + untrusted_pending: BigNumber + immature: BigNumber + used?: BigNumber +} + +interface WalletWatchOnlyBalances { + trusted: BigNumber + untrusted_pending: BigNumber + immature: BigNumber } ```