diff --git a/docs/node/CATEGORIES/05-wallet.md b/docs/node/CATEGORIES/05-wallet.md index 6301aabb02..6a1733ec96 100644 --- a/docs/node/CATEGORIES/05-wallet.md +++ b/docs/node/CATEGORIES/05-wallet.md @@ -407,3 +407,19 @@ interface wallet { signMessage (address: string, message: string): Promise } ``` + +## addMultiSigAddress + +Add an nrequired-to-sign multisignature address to the wallet. Requires a new wallet backup. + +```ts title="client.wallet.addMultiSigAddress()" +interface wallet { + addMultiSigAddress (nRequired: number, keys: string, label?: string, addressType?: string): Promise +} + +interface MultiSigAddressResult { + address: string + redeemScript: string + descriptor: string +} +``` \ No newline at end of file diff --git a/packages/jellyfish-api-core/__tests__/category/wallet/addMultiSigAddress.test.ts b/packages/jellyfish-api-core/__tests__/category/wallet/addMultiSigAddress.test.ts new file mode 100644 index 0000000000..3008ceb557 --- /dev/null +++ b/packages/jellyfish-api-core/__tests__/category/wallet/addMultiSigAddress.test.ts @@ -0,0 +1,48 @@ +import { MasterNodeRegTestContainer } from '@defichain/testcontainers' +import { ContainerAdapterClient } from '../../container_adapter_client' +import { RpcApiError } from '@defichain/jellyfish-api-core' + +describe('Wallet with masternode', () => { + const container = new MasterNodeRegTestContainer() + const client = new ContainerAdapterClient(container) + + beforeAll(async () => { + await container.start() + }) + + afterAll(async () => { + await container.stop() + }) + + it('should throw error when number of keys provided =/= nrequired', async () => { + const n = 3 + const pubKeyA = await client.wallet.getNewAddress() + const pubKeyB = await client.wallet.getNewAddress() + const keys = [pubKeyA, pubKeyB] + + const promise = await client.wallet.addMultiSigAddress(n, keys) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toMatchObject({ + payload: { + code: -8, + message: 'not enough keys supplied (got 2 keys, but need at least 3 to redeem)', + method: 'addmultisigaddress' + } + }) + }) + + it('should throw error when public key provided is invalid', async () => { + const n = 3 + const pubKey = ['invalid key'] + + const promise = await client.wallet.addMultiSigAddress(n, pubKey) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toMatchObject({ + payload: { + code: -5, + message: 'Invalid address: invalid key', + method: 'addmultisigaddress' + } + }) + }) +}) diff --git a/packages/jellyfish-api-core/src/category/wallet.ts b/packages/jellyfish-api-core/src/category/wallet.ts index 8785b1796d..9b660f25ff 100644 --- a/packages/jellyfish-api-core/src/category/wallet.ts +++ b/packages/jellyfish-api-core/src/category/wallet.ts @@ -336,6 +336,19 @@ export class Wallet { async signMessage (address: string, message: string): Promise { return await this.client.call('signmessage', [address, message], 'number') } + + /** + * Add an nrequired-to-sign multisignature address to the wallet. Requires a new wallet backup. + * + * @param {number} nRequired The number of required signatures based on number of keys/addresses. + * @param {string[]} keys The DeFi addresses or hex-encoded public keys. + * @param {string} label optional, a label to assign the addresses to. + * @param {string} addressType optional, the address type to use. E.g: “legacy”, “p2sh-segwit”, and “bech32”. + * @return {Promise} + */ + async addMultiSigAddress (nRequired: number, keys: string[], label?: string, addressType?: string): Promise { + return await this.client.call('addmultisigaddress', [nRequired, keys, label, addressType], 'number') + } } export interface UTXO { @@ -521,3 +534,9 @@ export interface WalletWatchOnlyBalances { untrusted_pending: BigNumber immature: BigNumber } + +export interface MultiSigAddressResult { + address: string + redeemScript: string + descriptor: string +}