From 87193e41f9c25c023bfce2dfb419596d03100944 Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Mon, 16 Jan 2023 10:54:18 +0800 Subject: [PATCH 1/7] feat: add deriveAddresses function --- docs/node/CATEGORIES/13-misc.md | 10 ++++ .../category/misc/deriveAddresses.test.ts | 58 +++++++++++++++++++ .../jellyfish-api-core/src/category/misc.ts | 11 ++++ 3 files changed, 79 insertions(+) create mode 100644 packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts diff --git a/docs/node/CATEGORIES/13-misc.md b/docs/node/CATEGORIES/13-misc.md index efa5018597..baca64af8c 100644 --- a/docs/node/CATEGORIES/13-misc.md +++ b/docs/node/CATEGORIES/13-misc.md @@ -42,3 +42,13 @@ interface misc { signMessageWithPrivKey (privkey: string, message: string): Promise } ``` + +# deriveAddresses + +Derives one or more addresses corresponding to an output descriptor. + +```ts title="client.misc.deriveAddresses()" +interface misc { + deriveAddresses (descriptor: string, range?: number[]): Promise +} +``` \ No newline at end of file diff --git a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts new file mode 100644 index 0000000000..5fa0224524 --- /dev/null +++ b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts @@ -0,0 +1,58 @@ +import { RegTestContainer } from '@defichain/testcontainers/dist/index' +import { ContainerAdapterClient } from '../../container_adapter_client' +import { RpcApiError } from '../../../src' + +describe('derive addresses', () => { + const container = new RegTestContainer() + const client = new ContainerAdapterClient(container) + + beforeAll(async () => { + await container.start() + }) + + afterAll(async () => { + await container.stop() + }) + + it('should derive an address without range', async () => { + const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0)#t6wfjs64' + const address = ['bcrt1qjqmxmkpmxt80xz4y3746zgt0q3u3ferr34acd5'] + expect(await client.misc.deriveAddresses(descriptor)).toStrictEqual(address) + }) + + it('should derive an address with range', async () => { + const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)#kft60nuy' + const address = ['bcrt1qhku5rq7jz8ulufe2y6fkcpnlvpsta7rq4442dy', 'bcrt1qpgptk2gvshyl0s9lqshsmx932l9ccsv265tvaq'] + expect(await client.misc.deriveAddresses(descriptor, [1, 2])).toStrictEqual(address) + }) + + it('should raise an error if the range is specified for un-ranged descriptor', async () => { + const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0)#t6wfjs64' + await expect(client.misc.deriveAddresses(descriptor, [1, 3])).rejects.toThrow(RpcApiError) + }) + + it('should raise an error if there is no range for a range descriptor', async () => { + const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' + await expect(client.misc.deriveAddresses(descriptor, [1, 3])).rejects.toThrow(RpcApiError) + }) + + it('should raise an error if end of range is too high', async () => { + const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' + await expect(client.misc.deriveAddresses(descriptor, [100000])).rejects.toThrow(RpcApiError) + }) + + it('should raise an error if range is too large', async () => { + const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' + await expect(client.misc.deriveAddresses(descriptor, [1, 100000])).rejects.toThrow(RpcApiError) + }) + + it('should raise an error if range is inferior to 0', async () => { + const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' + await expect(client.misc.deriveAddresses(descriptor, [-1, 2])).rejects.toThrow(RpcApiError) + }) + + it('should raise an error if end of range is inferior to beginning', async () => { + const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' + await expect(client.misc.deriveAddresses(descriptor, [2, 0])).rejects.toThrow(RpcApiError) + }) +}) diff --git a/packages/jellyfish-api-core/src/category/misc.ts b/packages/jellyfish-api-core/src/category/misc.ts index 2e8e102c86..3db462fab5 100644 --- a/packages/jellyfish-api-core/src/category/misc.ts +++ b/packages/jellyfish-api-core/src/category/misc.ts @@ -43,4 +43,15 @@ export class Misc { async signMessageWithPrivKey (privkey: string, message: string): Promise { return await this.client.call('signmessagewithprivkey', [privkey, message], 'number') } + + /** + * Derives one or more addresses corresponding to an output descriptor. + * + * @param {string} descriptor The descriptor. + * @param {number[]} range If a ranged descriptor is used, this specifies the end or the range (in [begin,end] notation) to derive. + * @return Promise the derived addresses + */ + async deriveAddresses (descriptor: string, range?: number[]): Promise { + return await this.client.call('deriveaddresses', [descriptor, range].filter(x => x !== undefined), 'number') + } } From 877d12107ab3833f74a4ee09fba3b3e9a0506e00 Mon Sep 17 00:00:00 2001 From: DrPing Date: Tue, 17 Jan 2023 15:25:04 +0800 Subject: [PATCH 2/7] Update packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts Co-authored-by: Shoham Chakraborty Signed-off-by: DrPing --- .../__tests__/category/misc/deriveAddresses.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts index 5fa0224524..b5263f6471 100644 --- a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts @@ -46,7 +46,7 @@ describe('derive addresses', () => { await expect(client.misc.deriveAddresses(descriptor, [1, 100000])).rejects.toThrow(RpcApiError) }) - it('should raise an error if range is inferior to 0', async () => { + it('should raise an error if range is less than 0', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' await expect(client.misc.deriveAddresses(descriptor, [-1, 2])).rejects.toThrow(RpcApiError) }) From 174b3685069dc81d4b0feeb2b2bfe40f1a418735 Mon Sep 17 00:00:00 2001 From: DrPing Date: Tue, 17 Jan 2023 15:25:12 +0800 Subject: [PATCH 3/7] Update packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts Co-authored-by: Shoham Chakraborty Signed-off-by: DrPing --- .../__tests__/category/misc/deriveAddresses.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts index b5263f6471..01a12a4fe9 100644 --- a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts @@ -51,7 +51,7 @@ describe('derive addresses', () => { await expect(client.misc.deriveAddresses(descriptor, [-1, 2])).rejects.toThrow(RpcApiError) }) - it('should raise an error if end of range is inferior to beginning', async () => { + it('should raise an error if end of range is smaller than the start', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' await expect(client.misc.deriveAddresses(descriptor, [2, 0])).rejects.toThrow(RpcApiError) }) From f94d943fba173be24fd010c1d0968a1610778951 Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Tue, 17 Jan 2023 17:18:55 +0800 Subject: [PATCH 4/7] make error check more specific for deriveAddresses test --- .../category/misc/deriveAddresses.test.ts | 75 +++++++++++++++++-- 1 file changed, 68 insertions(+), 7 deletions(-) diff --git a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts index 01a12a4fe9..0abec8212e 100644 --- a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts @@ -28,31 +28,92 @@ describe('derive addresses', () => { it('should raise an error if the range is specified for un-ranged descriptor', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0)#t6wfjs64' - await expect(client.misc.deriveAddresses(descriptor, [1, 3])).rejects.toThrow(RpcApiError) + const promise = client.misc.deriveAddresses(descriptor, [1, 3]) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toMatchObject({ + payload: { + code: -8, + message: 'Range should not be specified for an un-ranged descriptor', + method: 'deriveaddresses' + } + }) }) it('should raise an error if there is no range for a range descriptor', async () => { - const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' - await expect(client.misc.deriveAddresses(descriptor, [1, 3])).rejects.toThrow(RpcApiError) + const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)#kft60nuy' + const promise = client.misc.deriveAddresses(descriptor) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toMatchObject({ + payload: { + code: -8, + message: 'Range must be specified for a ranged descriptor', + method: 'deriveaddresses' + } + }) }) it('should raise an error if end of range is too high', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' - await expect(client.misc.deriveAddresses(descriptor, [100000])).rejects.toThrow(RpcApiError) + const promise = client.misc.deriveAddresses(descriptor, [100000]) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toMatchObject({ + payload: { + code: -8, + message: 'Range must be specified as end or as [begin,end]', + method: 'deriveaddresses' + } + }) }) it('should raise an error if range is too large', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' - await expect(client.misc.deriveAddresses(descriptor, [1, 100000])).rejects.toThrow(RpcApiError) + const promise = client.misc.deriveAddresses(descriptor, [1, 1000000000]) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toMatchObject({ + payload: { + code: -8, + message: 'Range is too large', + method: 'deriveaddresses' + } + }) }) it('should raise an error if range is less than 0', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' - await expect(client.misc.deriveAddresses(descriptor, [-1, 2])).rejects.toThrow(RpcApiError) + const promise = client.misc.deriveAddresses(descriptor, [-1, 2]) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toMatchObject({ + payload: { + code: -8, + message: 'Range should be greater or equal than 0', + method: 'deriveaddresses' + } + }) }) it('should raise an error if end of range is smaller than the start', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)' - await expect(client.misc.deriveAddresses(descriptor, [2, 0])).rejects.toThrow(RpcApiError) + const promise = client.misc.deriveAddresses(descriptor, [2, 0]) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toMatchObject({ + payload: { + code: -8, + message: 'Range specified as [begin,end] must not have begin after end', + method: 'deriveaddresses' + } + }) + }) + + it('should raise an error if there is wrong drescriptor', async () => { + const descriptor = 'descriptor' + const promise = client.misc.deriveAddresses(descriptor, [0, 2]) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toMatchObject({ + payload: { + code: -5, + message: 'Missing checksum', + method: 'deriveaddresses' + } + }) }) }) From 4a280871e897115223067584d98faa7c11b193be Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Wed, 18 Jan 2023 10:48:25 +0800 Subject: [PATCH 5/7] add test deriveAddresses for pkh and sh descriptor --- .../__tests__/category/misc/deriveAddresses.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts index 0abec8212e..b6d16700b6 100644 --- a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts @@ -26,6 +26,18 @@ describe('derive addresses', () => { expect(await client.misc.deriveAddresses(descriptor, [1, 2])).toStrictEqual(address) }) + it('should derive an address without range pkh descriptor', async () => { + const descriptor = 'pkh([d6043800/0\'/0\'/18\']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk' + const address = ['ms7ruzvL4atCu77n47dStMb3of6iScS8kZ'] + expect(await client.misc.deriveAddresses(descriptor)).toStrictEqual(address) + }) + + it('should derive an address without range sh descriptor', async () => { + const descriptor = 'sh(wpkh(tpubDCJtdt5dgJpdhW4MtaVYDhG4T4tF6jcLR1PxL43q9pq1mxvXgMS9Mzw1HnXG15vxUGQJMMSqCQHMTy3F1eW5VkgVroWzchsPD5BUojrcWs8/0/*))#e8nc36sh' + const address = ['2NA1PWXse3JjGGMcyjMETTCQnTpsLtQETQW', '2MzzJMkCmixHarCD47sFavseb3uTrPnxKav'] + expect(await client.misc.deriveAddresses(descriptor, [0, 1])).toStrictEqual(address) + }) + it('should raise an error if the range is specified for un-ranged descriptor', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0)#t6wfjs64' const promise = client.misc.deriveAddresses(descriptor, [1, 3]) From 549dce929b9fa28350fbc50326a62b37c4ffa859 Mon Sep 17 00:00:00 2001 From: DrPing Date: Wed, 18 Jan 2023 11:41:51 +0800 Subject: [PATCH 6/7] Update packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts Co-authored-by: Shoham Chakraborty Signed-off-by: DrPing --- .../__tests__/category/misc/deriveAddresses.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts index b6d16700b6..50c23a7ccb 100644 --- a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts @@ -23,7 +23,7 @@ describe('derive addresses', () => { it('should derive an address with range', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)#kft60nuy' const address = ['bcrt1qhku5rq7jz8ulufe2y6fkcpnlvpsta7rq4442dy', 'bcrt1qpgptk2gvshyl0s9lqshsmx932l9ccsv265tvaq'] - expect(await client.misc.deriveAddresses(descriptor, [1, 2])).toStrictEqual(address) + await expect(client.misc.deriveAddresses(descriptor, [1, 2])).toStrictEqual(address) }) it('should derive an address without range pkh descriptor', async () => { From 213be03310867b47ce4ddee9239b7a006ed19d2f Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Wed, 18 Jan 2023 11:51:45 +0800 Subject: [PATCH 7/7] move the await outside the expect for deriveAddresses tests --- .../__tests__/category/misc/deriveAddresses.test.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts index 50c23a7ccb..07d1e6b996 100644 --- a/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/misc/deriveAddresses.test.ts @@ -17,25 +17,29 @@ describe('derive addresses', () => { it('should derive an address without range', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0)#t6wfjs64' const address = ['bcrt1qjqmxmkpmxt80xz4y3746zgt0q3u3ferr34acd5'] - expect(await client.misc.deriveAddresses(descriptor)).toStrictEqual(address) + const promise = await client.misc.deriveAddresses(descriptor) + expect(promise).toStrictEqual(address) }) it('should derive an address with range', async () => { const descriptor = 'wpkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)#kft60nuy' const address = ['bcrt1qhku5rq7jz8ulufe2y6fkcpnlvpsta7rq4442dy', 'bcrt1qpgptk2gvshyl0s9lqshsmx932l9ccsv265tvaq'] - await expect(client.misc.deriveAddresses(descriptor, [1, 2])).toStrictEqual(address) + const promise = await client.misc.deriveAddresses(descriptor, [1, 2]) + expect(promise).toStrictEqual(address) }) it('should derive an address without range pkh descriptor', async () => { const descriptor = 'pkh([d6043800/0\'/0\'/18\']03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388)#4ahsl9pk' const address = ['ms7ruzvL4atCu77n47dStMb3of6iScS8kZ'] - expect(await client.misc.deriveAddresses(descriptor)).toStrictEqual(address) + const promise = await client.misc.deriveAddresses(descriptor) + expect(promise).toStrictEqual(address) }) it('should derive an address without range sh descriptor', async () => { const descriptor = 'sh(wpkh(tpubDCJtdt5dgJpdhW4MtaVYDhG4T4tF6jcLR1PxL43q9pq1mxvXgMS9Mzw1HnXG15vxUGQJMMSqCQHMTy3F1eW5VkgVroWzchsPD5BUojrcWs8/0/*))#e8nc36sh' const address = ['2NA1PWXse3JjGGMcyjMETTCQnTpsLtQETQW', '2MzzJMkCmixHarCD47sFavseb3uTrPnxKav'] - expect(await client.misc.deriveAddresses(descriptor, [0, 1])).toStrictEqual(address) + const promise = await client.misc.deriveAddresses(descriptor, [0, 1]) + expect(promise).toStrictEqual(address) }) it('should raise an error if the range is specified for un-ranged descriptor', async () => {