Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wallet.dumpPrivKey and wallet.importPrivKey RPC #306

Merged
merged 8 commits into from
May 30, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions packages/jellyfish-api-core/__tests__/category/wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -876,3 +876,157 @@ describe('masternode', () => {
})
})
})

describe('dumpPrivKey', () => {
describe('regTest', () => {
const container = new RegTestContainer()
const client = new ContainerAdapterClient(container)

beforeAll(async () => {
await container.start()
await container.waitForReady()
})

afterAll(async () => {
siradji marked this conversation as resolved.
Show resolved Hide resolved
await container.stop()
})

it('should reveal private key of given address', async () => {
await waitForExpect(async () => {
const address = await client.wallet.getNewAddress()
const privateKey = await client.wallet.dumpPrivKey(address)

expect(typeof privateKey).toStrictEqual('string')
})
})

it('should throw and error when invalid DFI address is provided', async () => {
await waitForExpect(async () => {
const invalidAddress = 'invalidAddress'

await expect(client.wallet.dumpPrivKey(invalidAddress)).rejects.toThrow('Invalid Defi address')
})
})
})

describe('masternode', () => {
const container = new MasterNodeRegTestContainer()
const client = new ContainerAdapterClient(container)

beforeAll(async () => {
await container.start()
await container.waitForReady()
await container.waitForWalletCoinbaseMaturity()
await container.waitForWalletBalanceGTE(101)
})

afterAll(async () => {
await container.stop()
})

it('should reveal private key of given address', async () => {
await waitForExpect(async () => {
const address = 'mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU'
const privateKey = await client.wallet.dumpPrivKey(address)

expect(typeof privateKey).toStrictEqual('string')
expect(privateKey).toStrictEqual('cRiRQ9cHmy5evDqNDdEV8f6zfbK6epi9Fpz4CRZsmLEmkwy54dWz')
})
})

it('should throw and error when invalid DFI address is provided', async () => {
await waitForExpect(async () => {
const invalidAddress = 'invalidAddress'

await expect(client.wallet.dumpPrivKey(invalidAddress)).rejects.toThrow('Invalid Defi address')
})
})
})
})

describe('importPrivKey', () => {
describe('regTest', () => {
const container = new RegTestContainer()
const client = new ContainerAdapterClient(container)

beforeAll(async () => {
await container.start()
await container.waitForReady()
})

afterAll(async () => {
await container.stop()
})

it('should should import private key without failing ', async () => {
const privatekey = await client.wallet.dumpPrivKey(await client.wallet.getNewAddress())
const promise = client.wallet.importPrivKey(privatekey)

await expect(promise).resolves.not.toThrow()
})

it('should import private key with rescan set to false', async () => {
const privateKey = await client.wallet.dumpPrivKey(await client.wallet.getNewAddress())
const promise = client.wallet.importPrivKey(privateKey, '', false)

await expect(promise).resolves.not.toThrow()
})

it('should import private key with label passed', async () => {
const privateKey = await client.wallet.dumpPrivKey(await client.wallet.getNewAddress('testing'))
const promise = client.wallet.importPrivKey(privateKey, 'testing')

await expect(promise).resolves.not.toThrow()
})

it('should fail and throw an error with invalid private key', async () => {
const privateKey = 'invalidPrivateKey'
const promise = client.wallet.importPrivKey(privateKey)

await expect(promise).rejects.toThrow('Invalid private key encoding')
})
})

describe('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 should import private key without failing ', async () => {
const privatekey = await client.wallet.dumpPrivKey(await client.wallet.getNewAddress())
const promise = client.wallet.importPrivKey(privatekey)

await expect(promise).resolves.not.toThrow()
})

it('should import private key with rescan set to false', async () => {
const privateKey = await client.wallet.dumpPrivKey(await client.wallet.getNewAddress())
const promise = client.wallet.importPrivKey(privateKey, '', false)

await expect(promise).resolves.not.toThrow()
})

it('should import private key with label passed', async () => {
const privateKey = await client.wallet.dumpPrivKey(await client.wallet.getNewAddress('testing'))
const promise = client.wallet.importPrivKey(privateKey, 'testing')

await expect(promise).resolves.not.toThrow()
})

it('should fail and throw an error with invalid private key', async () => {
const privateKey = 'invalidPrivateKey'
const promise = client.wallet.importPrivKey(privateKey)

await expect(promise).rejects.toThrow('Invalid private key encoding')
})
})
})
22 changes: 22 additions & 0 deletions packages/jellyfish-api-core/src/category/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,28 @@ export class Wallet {
'bignumber'
)
}

/**
* Reveals the private key corresponding to 'address'.
*
* Then the importprivkey can be used with this output.
siradji marked this conversation as resolved.
Show resolved Hide resolved
* @param {string} address The DFI address for the private key.
* @return {Promise<string>}
*/
async dumpPrivKey (address: string): Promise<string> {
return await this.client.call('dumpprivkey', [address], 'number')
}

/**
* Adds a private key (as returned by dumpprivkey) to your wallet. Requires a new wallet backup.
*
* @param {string} privkey The private key (see dumpprivkey)
* @param {string} [label=""] current label if address exists, otherwise "".
* @param {boolean} [rescan=true] Rescan the wallet for transactions
*/
async importPrivKey (privkey: string, label: string = '', rescan: boolean = true): Promise<void> {
return await this.client.call('importprivkey', [privkey, label, rescan], 'number')
}
}

export interface UTXO {
Expand Down
20 changes: 20 additions & 0 deletions website/docs/jellyfish/api/wallet.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,23 @@ enum Mode {
CONSERVATIVE = 'CONSERVATIVE'
}
```

## dumpPrivKey

Reveals the private key corresponding to 'address'. Then the importprivkey can be used with this output.
siradji marked this conversation as resolved.
Show resolved Hide resolved

```ts title="client.wallet.dumpPrivKey()"
interface wallet {
dumpPrivKey(address: string): Promise<string>
jingyi2811 marked this conversation as resolved.
Show resolved Hide resolved
}
```

## importPrivKey

Adds a private key (as returned by dumpprivkey) to your wallet. Requires a new wallet backup.

```ts title="client.wallet.importPrivKey()"
interface wallet {
importPrivKey(privkey: string, label: string = "", rescan: boolean = true): Promise<void>
jingyi2811 marked this conversation as resolved.
Show resolved Hide resolved
}
```