From 106849be9a8849ee6fba14ebc80b9a838f0c5107 Mon Sep 17 00:00:00 2001 From: surangap Date: Thu, 20 May 2021 15:19:15 +0800 Subject: [PATCH 1/5] Added sendmany RPC --- .../jellyfish-api-core/src/category/wallet.ts | 43 +++++++++++++++++++ website/docs/jellyfish/api/wallet.md | 17 ++++++++ 2 files changed, 60 insertions(+) diff --git a/packages/jellyfish-api-core/src/category/wallet.ts b/packages/jellyfish-api-core/src/category/wallet.ts index cb4c71ed9f..a13def4e73 100644 --- a/packages/jellyfish-api-core/src/category/wallet.ts +++ b/packages/jellyfish-api-core/src/category/wallet.ts @@ -213,6 +213,42 @@ export class Wallet { async listAddressGroupings (): Promise { return await this.client.call('listaddressgroupings', [], 'bignumber') } + + /** + * Send given amounts to multiple given address and return a transaction id + * + * @param {any} amounts Dictionary/map with individual addresses and amounts + * @param {string[]} subtractfeefrom Array of addresses from which fee needs to be deducted. + * @param {SendManyOptions} options + * @param {string} [options.comment] A comment + * @param {boolean} [options.replaceable] Allow this transaction to be replaced by a transaction with higher fees via BIP 125 + * @param {number} [options.confTarget] Confirmation target (in blocks) + * @param {Mode} [options.estimateMode] The fee estimate mode, must be one of (Mode.UNSET, Mode.ECONOMICAL, Mode.CONSERVATIVE) + * @return {Promise} hex string of the transaction + */ + async sendMany ( + amounts: any, + subtractfeefrom: string [] = [], + options: SendManyOptions = {}): Promise { + const { + comment = '', + replaceable = false, + confTarget = 6, + estimateMode = Mode.UNSET + } = options + + const dummy: string = '' // Must be set to '' for backward compatibality. + const minconf: number = 0 // Ignored dummy value + + return await this.client.call( + 'sendmany', + [ + dummy, amounts, minconf, comment, subtractfeefrom, + replaceable, confTarget, estimateMode + ], + 'bignumber' + ) + } } export interface UTXO { @@ -263,6 +299,13 @@ export interface SendToAddressOptions { avoidReuse?: boolean } +export interface SendManyOptions { + comment?: string + replaceable?: boolean + confTarget?: number + estimateMode?: Mode +} + export interface CreateWalletResult { name: string warning: string diff --git a/website/docs/jellyfish/api/wallet.md b/website/docs/jellyfish/api/wallet.md index 4f98bb5f16..7221ef1611 100644 --- a/website/docs/jellyfish/api/wallet.md +++ b/website/docs/jellyfish/api/wallet.md @@ -256,3 +256,20 @@ interface wallet { listAddressGroupings (): Promise } ``` + +## sendMany + +Send given amounts to multiple given address and return a transaction id. + +```ts title="client.wallet.sendMany()" +interface wallet { + async sendMany (amounts: any , subtractfeefrom: string [] = [], options: SendManyOptions = {}): Promise +} + +interface SendManyOptions { + comment?: string + replaceable?: boolean + confTarget?: number + estimateMode?: Mode +} +``` From 3a5aabe8bda4d1af34073953f1f735aee6f072be Mon Sep 17 00:00:00 2001 From: surangap Date: Fri, 21 May 2021 00:39:19 +0800 Subject: [PATCH 2/5] Updated sendMany RPC amounts param to do proper type checking --- packages/jellyfish-api-core/src/category/wallet.ts | 4 ++-- website/docs/jellyfish/api/wallet.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/jellyfish-api-core/src/category/wallet.ts b/packages/jellyfish-api-core/src/category/wallet.ts index a13def4e73..eb3043ffbd 100644 --- a/packages/jellyfish-api-core/src/category/wallet.ts +++ b/packages/jellyfish-api-core/src/category/wallet.ts @@ -217,7 +217,7 @@ export class Wallet { /** * Send given amounts to multiple given address and return a transaction id * - * @param {any} amounts Dictionary/map with individual addresses and amounts + * @param {Record} amounts Dictionary/map with individual addresses and amounts * @param {string[]} subtractfeefrom Array of addresses from which fee needs to be deducted. * @param {SendManyOptions} options * @param {string} [options.comment] A comment @@ -227,7 +227,7 @@ export class Wallet { * @return {Promise} hex string of the transaction */ async sendMany ( - amounts: any, + amounts: Record, subtractfeefrom: string [] = [], options: SendManyOptions = {}): Promise { const { diff --git a/website/docs/jellyfish/api/wallet.md b/website/docs/jellyfish/api/wallet.md index 7221ef1611..ae7a2c615a 100644 --- a/website/docs/jellyfish/api/wallet.md +++ b/website/docs/jellyfish/api/wallet.md @@ -263,7 +263,7 @@ Send given amounts to multiple given address and return a transaction id. ```ts title="client.wallet.sendMany()" interface wallet { - async sendMany (amounts: any , subtractfeefrom: string [] = [], options: SendManyOptions = {}): Promise + async sendMany (amounts: Record , subtractfeefrom: string [] = [], options: SendManyOptions = {}): Promise } interface SendManyOptions { From aa0630f5966e0f37def26bb0af79528a6584bd7e Mon Sep 17 00:00:00 2001 From: surangap Date: Fri, 21 May 2021 12:55:34 +0800 Subject: [PATCH 3/5] Added tests for sendMany RPC --- .../__tests__/category/wallet.test.ts | 184 +++++++++++++++++- website/docs/jellyfish/api/wallet.md | 2 +- 2 files changed, 184 insertions(+), 2 deletions(-) diff --git a/packages/jellyfish-api-core/__tests__/category/wallet.test.ts b/packages/jellyfish-api-core/__tests__/category/wallet.test.ts index e505330f7b..866935c000 100644 --- a/packages/jellyfish-api-core/__tests__/category/wallet.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/wallet.test.ts @@ -2,7 +2,7 @@ import { ContainerAdapterClient } from '../container_adapter_client' import { MasterNodeRegTestContainer, RegTestContainer } from '@defichain/testcontainers' import { BigNumber, wallet } from '../../src' import waitForExpect from 'wait-for-expect' -import { UTXO, ListUnspentOptions, WalletFlag, SendToAddressOptions, Mode } from '../../src/category/wallet' +import { UTXO, ListUnspentOptions, WalletFlag, SendToAddressOptions, Mode, SendManyOptions } from '../../src/category/wallet' describe('non masternode', () => { const container = new RegTestContainer() @@ -632,3 +632,185 @@ describe('masternode', () => { }) }) }) + +describe('sendMany', () => { + // NOTE(sp): defid side(c++) does not have much tests for sendmany RPC atm. + 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() + }) + + // util functions NOTE(sp) : may be move to a common util file if possible ?? + /** + * Returns matching utxos for given transaction id and address. + * + * @param {string} txId transaction id + * @param {string} address address + * @return {Promise} matching UTXO[] + */ + const getMatchingUTXO = async (txId: string, address: string): Promise => { + const options: ListUnspentOptions = { + addresses: [address] + } + const matchingUTXOs: UTXO[] = [] + + const listUnspent = async (): Promise => { + const utxos: UTXO[] = await client.wallet.listUnspent(1, 9999999, options) + utxos.forEach(utxo => { + expect(utxo.address).toBe(address) + if (utxo.txid === txId) { + matchingUTXOs.push(utxo) + } + }) + } + await listUnspent() + return matchingUTXOs + } + + //= ============================================================================================== + it('should getBalance >= 100', async () => { + return await waitForExpect(async () => { + const balance: BigNumber = await client.wallet.getBalance() + expect(balance.isGreaterThan(new BigNumber('100'))).toBe(true) + }) + }) + + it('should send one address using sendMany', async () => { + const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001 } + return await waitForExpect(async () => { + const transactionId = await client.wallet.sendMany(amounts) + expect(typeof transactionId).toBe('string') + + // generate one block + await container.generate(1) + + // check the corresponding UTXO + const utxos = await getMatchingUTXO(transactionId, 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + // In this case the we should only have one matching utxo + expect(utxos.length).toBe(1) + utxos.forEach(utxo => { + expect(utxo.address).toBe('mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + expect(utxo.amount.isEqualTo(0.00001)).toBe(true) + }) + }) + }) + + it('should send multiple address using sendMany', async () => { + const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 0.00002 } + return await waitForExpect(async () => { + const transactionId = await client.wallet.sendMany(amounts) + expect(typeof transactionId).toBe('string') + + // generate one block + await container.generate(1) + + // check the corresponding UTXOs + const utxos = await getMatchingUTXO(transactionId, 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + // In this case the we should only have one matching utxo + expect(utxos.length).toBe(1) + utxos.forEach(utxo => { + expect(utxo.address).toBe('mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + expect(utxo.amount.isEqualTo(0.00001)).toBe(true) + }) + + const utxos2 = await getMatchingUTXO(transactionId, 'mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') + // In this case the we should only have one matching utxo + expect(utxos2.length).toBe(1) + utxos2.forEach(utxo => { + expect(utxo.address).toBe('mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') + expect(utxo.amount.isEqualTo(0.00002)).toBe(true) + }) + }) + }) + + it('should sendMany with comment', async () => { + const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 0.00002 } + return await waitForExpect(async () => { + const options: SendManyOptions = { + comment: 'test comment' + } + const transactionId = await client.wallet.sendMany(amounts, [], options) + + expect(typeof transactionId).toBe('string') + + // NOTE(sp): How to test the comment is there and where + }) + }) + + it('should sendMany with replaceable', async () => { + const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 0.00002 } + return await waitForExpect(async () => { + const options: SendManyOptions = { + replaceable: true + } + const transactionId = await client.wallet.sendMany(amounts, [], options) + + expect(typeof transactionId).toBe('string') + }) + }) + + it('should sendMany with confTarget', async () => { + const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 0.00002 } + return await waitForExpect(async () => { + const options: SendManyOptions = { + confTarget: 60 + } + const transactionId = await client.wallet.sendMany(amounts, [], options) + + expect(typeof transactionId).toBe('string') + + // NOTE(sp): How to test the effect of confTarget + }) + }) + + it('should sendMany with estimateMode', async () => { + const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 0.00002 } + return await waitForExpect(async () => { + const options: SendManyOptions = { + estimateMode: Mode.ECONOMICAL + } + const transactionId = await client.wallet.sendMany(amounts, [], options) + + expect(typeof transactionId).toBe('string') + }) + }) + + it('should sendMany with fee substracted from mentioned recipients', async () => { + const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 10.5 } + const subtractFeeFrom: string [] = ['mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy'] + return await waitForExpect(async () => { + const transactionId = await client.wallet.sendMany(amounts, subtractFeeFrom) + expect(typeof transactionId).toBe('string') + + // generate one block + await container.generate(1) + + // check the corresponding UTXOs + const utxos = await getMatchingUTXO(transactionId, 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + // In this case the we should only have one matching utxo + expect(utxos.length).toBe(1) + utxos.forEach(utxo => { + expect(utxo.address).toBe('mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + // amount should be equal to 0.00001 + expect(utxo.amount.isEqualTo(0.00001)).toBe(true) + }) + + const utxos2 = await getMatchingUTXO(transactionId, 'mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') + // In this case the we should only have one matching utxo + expect(utxos2.length).toBe(1) + utxos2.forEach(utxo => { + expect(utxo.address).toBe('mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') + // amount should be less than 10.5 + expect(utxo.amount.isLessThan(10.5)).toBe(true) + }) + }) + }) +}) diff --git a/website/docs/jellyfish/api/wallet.md b/website/docs/jellyfish/api/wallet.md index ae7a2c615a..ca61664e6b 100644 --- a/website/docs/jellyfish/api/wallet.md +++ b/website/docs/jellyfish/api/wallet.md @@ -263,7 +263,7 @@ Send given amounts to multiple given address and return a transaction id. ```ts title="client.wallet.sendMany()" interface wallet { - async sendMany (amounts: Record , subtractfeefrom: string [] = [], options: SendManyOptions = {}): Promise + async sendMany (amounts: Record , subtractfeefrom: string [] = [], options: SendManyOptions = {}): Promise } interface SendManyOptions { From 1f0043b5d12fb203687e33f992ea8342036ffbf1 Mon Sep 17 00:00:00 2001 From: surangap Date: Mon, 24 May 2021 14:36:27 +0800 Subject: [PATCH 4/5] Refactored Code as per review suggestions. --- .../__tests__/category/wallet.test.ts | 202 +++++++----------- .../jellyfish-api-core/src/category/wallet.ts | 2 +- 2 files changed, 80 insertions(+), 124 deletions(-) diff --git a/packages/jellyfish-api-core/__tests__/category/wallet.test.ts b/packages/jellyfish-api-core/__tests__/category/wallet.test.ts index 866935c000..6b194971bb 100644 --- a/packages/jellyfish-api-core/__tests__/category/wallet.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/wallet.test.ts @@ -634,7 +634,7 @@ describe('masternode', () => { }) describe('sendMany', () => { - // NOTE(sp): defid side(c++) does not have much tests for sendmany RPC atm. + // NOTE(surangap): defid side(c++) does not have much tests for sendmany RPC atm. const container = new MasterNodeRegTestContainer() const client = new ContainerAdapterClient(container) @@ -642,175 +642,131 @@ describe('sendMany', () => { await container.start() await container.waitForReady() await container.waitForWalletCoinbaseMaturity() + await container.waitForWalletBalanceGTE(101) }) afterAll(async () => { await container.stop() }) - // util functions NOTE(sp) : may be move to a common util file if possible ?? - /** - * Returns matching utxos for given transaction id and address. - * - * @param {string} txId transaction id - * @param {string} address address - * @return {Promise} matching UTXO[] - */ + // Returns matching utxos for given transaction id and address. const getMatchingUTXO = async (txId: string, address: string): Promise => { const options: ListUnspentOptions = { addresses: [address] } - const matchingUTXOs: UTXO[] = [] - - const listUnspent = async (): Promise => { - const utxos: UTXO[] = await client.wallet.listUnspent(1, 9999999, options) - utxos.forEach(utxo => { - expect(utxo.address).toBe(address) - if (utxo.txid === txId) { - matchingUTXOs.push(utxo) - } - }) - } - await listUnspent() - return matchingUTXOs - } - //= ============================================================================================== - it('should getBalance >= 100', async () => { - return await waitForExpect(async () => { - const balance: BigNumber = await client.wallet.getBalance() - expect(balance.isGreaterThan(new BigNumber('100'))).toBe(true) + const utxos: UTXO[] = await client.wallet.listUnspent(1, 9999999, options) + return utxos.filter((utxo) => { + return (utxo.address === address) && (utxo.txid === txId) }) - }) + } it('should send one address using sendMany', async () => { const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001 } - return await waitForExpect(async () => { - const transactionId = await client.wallet.sendMany(amounts) - expect(typeof transactionId).toBe('string') + const transactionId = await client.wallet.sendMany(amounts) + expect(typeof transactionId).toBe('string') - // generate one block - await container.generate(1) + // generate one block + await container.generate(1) - // check the corresponding UTXO - const utxos = await getMatchingUTXO(transactionId, 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') - // In this case the we should only have one matching utxo - expect(utxos.length).toBe(1) - utxos.forEach(utxo => { - expect(utxo.address).toBe('mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') - expect(utxo.amount.isEqualTo(0.00001)).toBe(true) - }) + // check the corresponding UTXO + const utxos = await getMatchingUTXO(transactionId, 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + // In this case the we should only have one matching utxo + expect(utxos.length).toStrictEqual(1) + utxos.forEach(utxo => { + expect(utxo.address).toStrictEqual('mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + expect(utxo.amount).toStrictEqual(new BigNumber(0.00001)) }) }) it('should send multiple address using sendMany', async () => { const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 0.00002 } - return await waitForExpect(async () => { - const transactionId = await client.wallet.sendMany(amounts) - expect(typeof transactionId).toBe('string') + const transactionId = await client.wallet.sendMany(amounts) + expect(typeof transactionId).toBe('string') - // generate one block - await container.generate(1) + // generate one block + await container.generate(1) - // check the corresponding UTXOs - const utxos = await getMatchingUTXO(transactionId, 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') - // In this case the we should only have one matching utxo - expect(utxos.length).toBe(1) - utxos.forEach(utxo => { - expect(utxo.address).toBe('mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') - expect(utxo.amount.isEqualTo(0.00001)).toBe(true) - }) + // check the corresponding UTXOs + const utxos = await getMatchingUTXO(transactionId, 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + // In this case the we should only have one matching utxo + expect(utxos.length).toStrictEqual(1) + utxos.forEach(utxo => { + expect(utxo.address).toStrictEqual('mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + expect(utxo.amount).toStrictEqual(new BigNumber(0.00001)) + }) - const utxos2 = await getMatchingUTXO(transactionId, 'mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') - // In this case the we should only have one matching utxo - expect(utxos2.length).toBe(1) - utxos2.forEach(utxo => { - expect(utxo.address).toBe('mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') - expect(utxo.amount.isEqualTo(0.00002)).toBe(true) - }) + const utxos2 = await getMatchingUTXO(transactionId, 'mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') + // In this case the we should only have one matching utxo + expect(utxos2.length).toStrictEqual(1) + utxos2.forEach(utxo => { + expect(utxo.address).toStrictEqual('mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') + expect(utxo.amount).toStrictEqual(new BigNumber(0.00002)) }) }) it('should sendMany with comment', async () => { const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 0.00002 } - return await waitForExpect(async () => { - const options: SendManyOptions = { - comment: 'test comment' - } - const transactionId = await client.wallet.sendMany(amounts, [], options) - - expect(typeof transactionId).toBe('string') - - // NOTE(sp): How to test the comment is there and where - }) + const options: SendManyOptions = { + comment: 'test comment' + } + const transactionId = await client.wallet.sendMany(amounts, [], options) + expect(typeof transactionId).toBe('string') }) it('should sendMany with replaceable', async () => { const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 0.00002 } - return await waitForExpect(async () => { - const options: SendManyOptions = { - replaceable: true - } - const transactionId = await client.wallet.sendMany(amounts, [], options) - - expect(typeof transactionId).toBe('string') - }) + const options: SendManyOptions = { + replaceable: true + } + const transactionId = await client.wallet.sendMany(amounts, [], options) + expect(typeof transactionId).toBe('string') }) it('should sendMany with confTarget', async () => { const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 0.00002 } - return await waitForExpect(async () => { - const options: SendManyOptions = { - confTarget: 60 - } - const transactionId = await client.wallet.sendMany(amounts, [], options) - - expect(typeof transactionId).toBe('string') - - // NOTE(sp): How to test the effect of confTarget - }) + const options: SendManyOptions = { + confTarget: 60 + } + const transactionId = await client.wallet.sendMany(amounts, [], options) + expect(typeof transactionId).toBe('string') }) it('should sendMany with estimateMode', async () => { const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 0.00002 } - return await waitForExpect(async () => { - const options: SendManyOptions = { - estimateMode: Mode.ECONOMICAL - } - const transactionId = await client.wallet.sendMany(amounts, [], options) - - expect(typeof transactionId).toBe('string') - }) + const options: SendManyOptions = { + estimateMode: Mode.ECONOMICAL + } + const transactionId = await client.wallet.sendMany(amounts, [], options) + expect(typeof transactionId).toBe('string') }) it('should sendMany with fee substracted from mentioned recipients', async () => { const amounts: Record = { mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU: 0.00001, mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy: 10.5 } const subtractFeeFrom: string [] = ['mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy'] - return await waitForExpect(async () => { - const transactionId = await client.wallet.sendMany(amounts, subtractFeeFrom) - expect(typeof transactionId).toBe('string') - - // generate one block - await container.generate(1) - - // check the corresponding UTXOs - const utxos = await getMatchingUTXO(transactionId, 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') - // In this case the we should only have one matching utxo - expect(utxos.length).toBe(1) - utxos.forEach(utxo => { - expect(utxo.address).toBe('mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') - // amount should be equal to 0.00001 - expect(utxo.amount.isEqualTo(0.00001)).toBe(true) - }) - - const utxos2 = await getMatchingUTXO(transactionId, 'mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') - // In this case the we should only have one matching utxo - expect(utxos2.length).toBe(1) - utxos2.forEach(utxo => { - expect(utxo.address).toBe('mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') - // amount should be less than 10.5 - expect(utxo.amount.isLessThan(10.5)).toBe(true) - }) + const transactionId = await client.wallet.sendMany(amounts, subtractFeeFrom) + expect(typeof transactionId).toBe('string') + + // generate one block + await container.generate(1) + + // check the corresponding UTXOs + const utxos = await getMatchingUTXO(transactionId, 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + // In this case the we should only have one matching utxo + expect(utxos.length).toStrictEqual(1) + utxos.forEach(utxo => { + expect(utxo.address).toStrictEqual('mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU') + // amount should be equal to 0.00001 + expect(utxo.amount).toStrictEqual(new BigNumber(0.00001)) + }) + + const utxos2 = await getMatchingUTXO(transactionId, 'mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') + // In this case the we should only have one matching utxo + expect(utxos2.length).toStrictEqual(1) + utxos2.forEach(utxo => { + expect(utxo.address).toStrictEqual('mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy') + // amount should be less than 10.5 + expect(utxo.amount.isLessThan(10.5)).toBe(true) }) }) }) diff --git a/packages/jellyfish-api-core/src/category/wallet.ts b/packages/jellyfish-api-core/src/category/wallet.ts index eb3043ffbd..ad3e5992ca 100644 --- a/packages/jellyfish-api-core/src/category/wallet.ts +++ b/packages/jellyfish-api-core/src/category/wallet.ts @@ -215,7 +215,7 @@ export class Wallet { } /** - * Send given amounts to multiple given address and return a transaction id + * Send given amounts to multiple given address and return a transaction id. * * @param {Record} amounts Dictionary/map with individual addresses and amounts * @param {string[]} subtractfeefrom Array of addresses from which fee needs to be deducted. From 17ac8050ae55944e8a6a618d2cfd201b6be7e75d Mon Sep 17 00:00:00 2001 From: surangap Date: Tue, 25 May 2021 11:12:46 +0800 Subject: [PATCH 5/5] Added SendManyOptions estimateMode enum Mode to the docs --- website/docs/jellyfish/api/wallet.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/website/docs/jellyfish/api/wallet.md b/website/docs/jellyfish/api/wallet.md index ca61664e6b..e0cad446c0 100644 --- a/website/docs/jellyfish/api/wallet.md +++ b/website/docs/jellyfish/api/wallet.md @@ -272,4 +272,10 @@ interface SendManyOptions { confTarget?: number estimateMode?: Mode } + +enum Mode { + UNSET = 'UNSET', + ECONOMICAL = 'ECONOMICAL', + CONSERVATIVE = 'CONSERVATIVE' +} ```