From 5003452b486018bb16e14988507a2e19e79771ce Mon Sep 17 00:00:00 2001 From: Wietse Wind Date: Wed, 19 Feb 2020 14:15:37 +0100 Subject: [PATCH 1/2] Support for xrpl-secret-numbers encoded seed https://github.com/WietseWind/xrpl-secret-numbers --- package-lock.json | 18 ++++++++++++++++ package.json | 3 ++- src/wallet.ts | 21 +++++++++++++++++++ test/wallet-test.ts | 50 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index ade403fb..2ac5df22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -240,6 +240,14 @@ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", "dev": true }, + "@types/brorand": { + "version": "1.0.30", + "resolved": "https://registry.npmjs.org/@types/brorand/-/brorand-1.0.30.tgz", + "integrity": "sha1-NmaYVFCddw4TA3xYBMyAlfwcors=", + "requires": { + "@types/node": "*" + } + }, "@types/chai": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.9.tgz", @@ -8435,6 +8443,16 @@ "typedarray-to-buffer": "^3.1.5" } }, + "xrpl-secret-numbers": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/xrpl-secret-numbers/-/xrpl-secret-numbers-0.2.0.tgz", + "integrity": "sha512-RXdBPY2qnNE0TKFEhUiaxM7K70FKDp/Ep8RlqPlh0uWQNv3+DnAFz8imCKD3La0zTHho0coKvG2HwFFOhi/zvw==", + "requires": { + "@types/brorand": "^1.0.30", + "brorand": "^1.1.0", + "ripple-keypairs": "^1.0.0" + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 00c17993..3180a8ba 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "grpc-web": "1.0.7", "ripple-address-codec": "4.1.0", "ripple-binary-codec": "0.2.6", - "ripple-keypairs": "^1.0.0" + "ripple-keypairs": "^1.0.0", + "xrpl-secret-numbers": "^0.2.0" }, "scripts": { "build": "npm run clean && ./scripts/regenerate_protos.sh && npm run lint && tsc -d && copyfiles -u 2 './src/generated/**/*' ./build/generated", diff --git a/src/wallet.ts b/src/wallet.ts index 5d545496..bca54fe2 100644 --- a/src/wallet.ts +++ b/src/wallet.ts @@ -1,6 +1,7 @@ import * as bip32 from 'bip32' import * as bip39 from 'bip39' import * as rippleKeyPair from 'ripple-keypairs' +import { Account as SecretNumbersAccount } from 'xrpl-secret-numbers' import Utils from './utils' /** @@ -129,6 +130,26 @@ class Wallet { } } + /** + * Generate a new wallet from the given secret numbers. + * + * @param secretNumbers The given seed for the wallet. + * @param test Whether the address is for use on a test network, defaults to `false`. + * @returns A new wallet from the given seed, or undefined if the seed was invalid. + */ + public static generateWalletFromSecretNumbers( + secretNumbers: string | string[], + test = false, + ): Wallet | undefined { + try { + const account = new SecretNumbersAccount(secretNumbers) + const keyPair = account.getKeypair() + return new Wallet(keyPair.publicKey, keyPair.privateKey, test) + } catch (exception) { + return undefined + } + } + /** * Create a new Wallet object. * diff --git a/test/wallet-test.ts b/test/wallet-test.ts index 073d319f..6e41fcb1 100644 --- a/test/wallet-test.ts +++ b/test/wallet-test.ts @@ -214,6 +214,56 @@ describe('wallet', function(): void { assert.isUndefined(wallet) }) + it('walletFromSecretNumbers - MainNet', function(): void { + // GIVEN a seed used to generate a wallet on MainNet + const seed = [ + '554872', + '394230', + '209376', + '323698', + '140250', + '387423', + '652803', + '258676', + ] + const isTestNet = false + + // WHEN a wallet is generated from the seed. + const wallet = Wallet.generateWalletFromSecretNumbers(seed, isTestNet) + + // THEN the wallet has the expected address. + assert.equal( + wallet!.getAddress(), + 'XVPCcgRJZmYGpSczab57QWbcoTnP2FQsKrCTFWughwrqBH2', + ) + }) + + it('walletFromSecretNumbers - TestNet', function(): void { + // GIVEN a seed used to generate a wallet on TestNet + const seed = '554872 394230 209376 323698 140250 387423 652803 258676' + const test = true + + // WHEN a wallet is generated from the seed. + const wallet = Wallet.generateWalletFromSecretNumbers(seed, test) + + // THEN the wallet has the expected address. + assert.equal( + wallet!.getAddress(), + 'TVKUp82HRjaHTxPb4QTEJWMXGtcUaQhnGBcv3U9UekYpy9T', + ) + }) + + it('walletFromSecretNumbers - invalid seed', function(): void { + // GIVEN an invalid seed. + const seed = '554872 394230 209372 323695 140250 387423 652803 258676' + + // WHEN a wallet is generated from the seed. + const wallet = Wallet.generateWalletFromSecretNumbers(seed) + + // THEN the wallet is undefined. + assert.isUndefined(wallet) + }) + it('sign', function(): void { // GIVEN a wallet. const testData = derivationPathTestCases.index0 From 4a41f0481bdab9609920afbda629fd303e447c96 Mon Sep 17 00:00:00 2001 From: Wietse Wind Date: Thu, 20 Feb 2020 11:00:34 +0100 Subject: [PATCH 2/2] Remove custom ripple-keypairs type --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2ac5df22..b141e89b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8444,9 +8444,9 @@ } }, "xrpl-secret-numbers": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/xrpl-secret-numbers/-/xrpl-secret-numbers-0.2.0.tgz", - "integrity": "sha512-RXdBPY2qnNE0TKFEhUiaxM7K70FKDp/Ep8RlqPlh0uWQNv3+DnAFz8imCKD3La0zTHho0coKvG2HwFFOhi/zvw==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/xrpl-secret-numbers/-/xrpl-secret-numbers-0.2.1.tgz", + "integrity": "sha512-jC9LVNoX6vKmIGip43uuS+yi/R2hdnI+f9QeFTXzZFN+0SBSaSeBxDeGXV7DoBUn1/9Z+mR0nn4cHsDS/+uQjA==", "requires": { "@types/brorand": "^1.0.30", "brorand": "^1.1.0", diff --git a/package.json b/package.json index 3180a8ba..3d07fe13 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "ripple-address-codec": "4.1.0", "ripple-binary-codec": "0.2.6", "ripple-keypairs": "^1.0.0", - "xrpl-secret-numbers": "^0.2.0" + "xrpl-secret-numbers": "^0.2.1" }, "scripts": { "build": "npm run clean && ./scripts/regenerate_protos.sh && npm run lint && tsc -d && copyfiles -u 2 './src/generated/**/*' ./build/generated",