forked from MystenLabs/sui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BE Wallet] Add util functions for mnemonics (MystenLabs#1891)
Co-authored-by: Clay-Mysten <[email protected]>
- Loading branch information
1 parent
3996636
commit 7b3d8ef
Showing
7 changed files
with
12,396 additions
and
7,484 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Copyright (c) 2022, Mysten Labs, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ | ||
module.exports = { | ||
preset: 'ts-jest', | ||
testEnvironment: 'node', | ||
}; |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,8 @@ | |
"stylelint:fix": "npm run stylelint:check -- --fix", | ||
"lint": "npm run eslint:check && npm run prettier:check && npm run stylelint:check", | ||
"lint:fix": "npm run eslint:fix && npm run prettier:fix && npm run stylelint:fix", | ||
"start": "concurrently --restart-tries 10 --raw \"npm:build:dev -- --watch\" \"npm:prettier:fix:watch\"" | ||
"start": "concurrently --restart-tries 10 --raw \"npm:build:dev -- --watch\" \"npm:prettier:fix:watch\"", | ||
"test": "npx jest" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
|
@@ -31,6 +32,7 @@ | |
"author": "Mysten Labs <[email protected]>", | ||
"license": "Apache-2.0", | ||
"devDependencies": { | ||
"@types/jest": "^27.5.0", | ||
"@types/node": "^17.0.31", | ||
"@types/react": "^18.0.8", | ||
"@types/react-dom": "^18.0.3", | ||
|
@@ -45,6 +47,7 @@ | |
"eslint-config-react-app": "^7.0.1", | ||
"eslint-webpack-plugin": "^3.1.1", | ||
"html-webpack-plugin": "^5.5.0", | ||
"jest": "^28.1.0", | ||
"mini-css-extract-plugin": "^2.6.0", | ||
"onchange": "^7.1.0", | ||
"postcss-loader": "^6.2.1", | ||
|
@@ -56,6 +59,7 @@ | |
"stylelint-config-prettier-scss": "^0.0.1", | ||
"stylelint-config-standard-scss": "^3.0.0", | ||
"stylelint-webpack-plugin": "^3.2.0", | ||
"ts-jest": "^28.0.2", | ||
"ts-loader": "^9.3.0", | ||
"ts-node": "^10.7.0", | ||
"tsconfig-paths": "^4.0.0", | ||
|
@@ -64,8 +68,11 @@ | |
"webpack-merge": "^5.8.0" | ||
}, | ||
"dependencies": { | ||
"@mysten/sui.js": "file:../sdk/typescript", | ||
"bip39-light": "^1.0.7", | ||
"react": "^18.1.0", | ||
"react-dom": "^18.1.0", | ||
"tweetnacl": "^1.0.3", | ||
"webextension-polyfill": "^0.9.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright (c) 2022, Mysten Labs, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
declare module 'bip39-light' { | ||
export function entropyToMnemonic( | ||
entropy: Buffer | string, | ||
wordlist?: string[] | ||
): string; | ||
export function generateMnemonic( | ||
strength?: number, | ||
rng?: (size: number) => Buffer, | ||
wordlist?: string[] | ||
): string; | ||
export function mnemonicToSeed(mnemonic: string, password?: string): Buffer; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright (c) 2022, Mysten Labs, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import bip39 from 'bip39-light'; | ||
import nacl from 'tweetnacl'; | ||
|
||
import type { Ed25519KeypairData } from '@mysten/sui.js'; | ||
|
||
/** | ||
* Generate a 12-word random mnemonic and keypair using crypto.randomBytes | ||
* under the hood, defaults to 128-bits of entropy. | ||
* @returns a tuple of mnemonic and keypair. The mnemonics is a 12-word string | ||
* split by spaces. | ||
*/ | ||
export function generateMnemonicsAndKeypair(): [string, Ed25519KeypairData] { | ||
const mnemonics = bip39.generateMnemonic(); | ||
return [mnemonics, getKeypairFromMnemonics(mnemonics)]; | ||
} | ||
|
||
/** | ||
* Derive public key and private key from the Mnemonics | ||
* @param mnemonics a 12-word seed phrase | ||
* @returns public key and private key | ||
*/ | ||
export function getKeypairFromMnemonics(mnemonics: string): Ed25519KeypairData { | ||
const seed = bip39.mnemonicToSeed(normalizeMnemonics(mnemonics)); | ||
return nacl.sign.keyPair.fromSeed( | ||
// keyPair.fromSeed only takes a 32-byte array where `seed` is a 64-byte array | ||
new Uint8Array(seed.toJSON().data.slice(0, 32)) | ||
); | ||
} | ||
|
||
/** | ||
* Sanitize the mnemonics string provided by user | ||
* @param mnemonics a 12-word string split by spaces that may contain mixed cases | ||
* and extra spaces | ||
* @returns a sanitized mnemonics string | ||
*/ | ||
export function normalizeMnemonics(mnemonics: string): string { | ||
return mnemonics | ||
.trim() | ||
.split(/\s+/) | ||
.map((part) => part.toLowerCase()) | ||
.join(' '); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright (c) 2022, Mysten Labs, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { Base64DataBuffer, Ed25519Keypair } from '@mysten/sui.js'; | ||
|
||
import { | ||
generateMnemonicsAndKeypair, | ||
getKeypairFromMnemonics, | ||
normalizeMnemonics, | ||
} from '../../../src/utils/cryptography/mnemonics'; | ||
|
||
describe('mnemonics', () => { | ||
it('generate mnemonics', () => { | ||
const [mnemonics, keypair] = generateMnemonicsAndKeypair(); | ||
expect(mnemonics.split(' ').length).toBe(12); | ||
const parsedKeypair = getKeypairFromMnemonics(mnemonics); | ||
expect(parsedKeypair.publicKey).toEqual(keypair.publicKey); | ||
expect(parsedKeypair.secretKey).toEqual(keypair.secretKey); | ||
}); | ||
|
||
it('normalize', () => { | ||
expect(normalizeMnemonics(' Almost a Seed Phrase')).toEqual( | ||
'almost a seed phrase' | ||
); | ||
}); | ||
|
||
it('parse mnemonics', () => { | ||
const keypairData = getKeypairFromMnemonics( | ||
'Shoot island position soft burden budget tooth cruel issue economy destroy Above' | ||
); | ||
|
||
const keypair = new Ed25519Keypair(keypairData); | ||
|
||
expect(new Base64DataBuffer(keypairData.secretKey).toString()).toEqual( | ||
'V3zZEK7eJYJminQdR2tF55mOkFpChvcBuHslkjUB+dTGHsYX9tdbrbyu2sALKKQcfTOiz6DAeMOxQ+RNp159nA==' | ||
); | ||
expect(keypair.getPublicKey().toBase64()).toEqual( | ||
'xh7GF/bXW628rtrACyikHH0zos+gwHjDsUPkTadefZw=' | ||
); | ||
}); | ||
}); |