Skip to content
This repository has been archived by the owner on Oct 4, 2024. It is now read-only.

Enchancing Generate key #531

Merged
merged 9 commits into from
Sep 15, 2020
12 changes: 12 additions & 0 deletions bin/near-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,17 @@ yargs // eslint-disable-line
type: 'string',
default: "44'/397'/0'/0'/1'"
})
.options('seedPhrase', {
desc: 'Seed phrase mnemonic',
type: 'string',
required: false
})
.options('seedPath', {
desc: 'HD path derivation',
type: 'string',
default: "m/44'/397'/0'",
required: false
})
.option('walletUrl', {
desc: 'Website for NEAR Wallet',
type: 'string'
Expand Down Expand Up @@ -212,6 +223,7 @@ yargs // eslint-disable-line
.middleware(require('../middleware/print-options'))
.middleware(require('../middleware/key-store'))
.middleware(require('../middleware/ledger'))
.middleware(require('../middleware/seed-phrase'))
.command(require('../commands/create-account').createAccountCommand)
.command(require('../commands/create-account').createAccountCommandDeprecated)
.command(viewAccount)
Expand Down
31 changes: 21 additions & 10 deletions commands/generate-key.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
const KeyPair = require('near-api-js').KeyPair;
const exitOnError = require('../utils/exit-on-error');
const implicitAccountId = require('../utils/implicit-accountid');

module.exports = {
command: 'generate-key <account-id>',
desc: 'generate key ',
command: 'generate-key [account-id]',
desc: 'generate key or show key from Ledger',
builder: (yargs) => yargs,
handler: exitOnError(async (argv) => {
let near = await require('../utils/connect')(argv);
if (!argv.accountId) {
return;
}

if (argv.usingLedger) {
await argv.signer.getPublicKey();
// NOTE: Command above already prints public key
if (argv.accountId) {
console.log('WARN: Account id is provided but ignored in case of using Ledger.');
}
const publicKey = await argv.signer.getPublicKey();
// NOTE: Command above already prints public key.
console.log(`Implicit account: ${implicitAccountId(publicKey.toString())}`);
// TODO: query all accounts with this public key here.
// TODO: check if implicit account exist, and if the key doen't match already.
return;
}

Expand All @@ -24,8 +28,15 @@ module.exports = {
return;
}

const keyPair = KeyPair.fromRandom('ed25519');
await keyStore.setKey(argv.networkId, argv.accountId, keyPair);
console.log(`Generated key pair with ${keyPair.publicKey} public key`);
// If key doesn't exist, create one and store in the keyStore.
// Otherwise, it's expected that both key and accountId are already provided in arguments.
if (!argv.publicKey) {
const keyPair = KeyPair.fromRandom('ed25519');
argv.publicKey = keyPair.publicKey.toString();
argv.accountId = argv.accountId || implicitAccountId(argv.publicKey);
await keyStore.setKey(argv.networkId, argv.accountId, keyPair);
}

console.log(`Key pair with ${argv.publicKey} public key for an account "${argv.accountId}"`);
})
};
23 changes: 23 additions & 0 deletions middleware/seed-phrase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { parseSeedPhrase } = require('near-seed-phrase');
const { utils: { KeyPair }, InMemorySigner } = require('near-api-js');
const { InMemoryKeyStore } = require('near-api-js/lib/key_stores');

const implicitAccountId = require('../utils/implicit-accountid');

// near ... --seedPhrase="phrase" --seedPath="m/44'/397'/0'"
// near generate-key --seedPhrase="phrase"
module.exports = async function useSeedPhrase({ seedPhrase, seedPath, publicKey, accountId }, yargs) {
if (!seedPhrase) {
return;
}
if (yargs.usingLedger) {
throw new Error('Can not use both --useLedgerKey and --seedPhrase at the same time');
}
const result = parseSeedPhrase(seedPhrase, seedPath);
publicKey = result.publicKey;
let keyStore = new InMemoryKeyStore();
accountId = accountId || implicitAccountId(publicKey);
await keyStore.setKey(yargs.networkId, accountId, KeyPair.fromString(result.secretKey));
let signer = new InMemorySigner(keyStore);
return { signer, publicKey, accountId };
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"mixpanel": "^0.11.0",
"ncp": "^2.0.0",
"near-api-js": "^0.29.1",
"near-seed-phrase": "^0.1.0",
"open": "^7.0.1",
"rimraf": "^3.0.0",
"stoppable": "^1.1.0",
Expand Down
2 changes: 1 addition & 1 deletion test/test_generate_key.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ if [[ ! -f "${KEY_FILE}" ]]; then
exit 1
fi

EXPECTED=".*Generated key pair with ed25519:.+ public key.*"
EXPECTED=".*Key pair with ed25519:.+ public key.*"
if [[ ! "$RESULT" =~ $EXPECTED ]]; then
echo FAILURE Unexpected output from near generate-key
exit 1
Expand Down
5 changes: 5 additions & 0 deletions utils/implicit-accountid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const { decode } = require('bs58');

module.exports = (publicKey) => {
return decode(publicKey.replace('ed25519:', '')).toString('hex');
};
146 changes: 142 additions & 4 deletions yarn.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.