From 4c5397225c68603fea2d773e2c64f96ffbd26240 Mon Sep 17 00:00:00 2001 From: Vee C Date: Tue, 23 Apr 2024 04:17:43 +0900 Subject: [PATCH 1/4] add notes to README --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ebdc30b..01b6000 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,14 @@ Generate all the keys needed for use with Stacks 2.0 Mining and Stacking ## prerequisites -You will need to have node.js and npm installed first. Head over to the [node.js download](https://nodejs.org/en/download/) page +You will need to have node.js and npm installed first. Head over to the +[node.js download](https://nodejs.org/en/download/) page. +Tested ok with `node16` but not `node18`. + +## install deps +``` +yarn install # avoid `npm install` +``` ## usage with npx If `npx` is not installed, install it first From 6d978f24ebba49aa6354972c71007c55a7413775 Mon Sep 17 00:00:00 2001 From: Vee C Date: Tue, 23 Apr 2024 04:08:49 +0900 Subject: [PATCH 2/4] make networkDerivationPath an arg --- src/index.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/index.js b/src/index.js index 57e7a7c..1e075e1 100644 --- a/src/index.js +++ b/src/index.js @@ -10,17 +10,11 @@ const stacks_transactions = require('@stacks/transactions') const c32c = require('c32check') const wif = require('wif') const yargs = require('yargs') - + const { generateMnemonic, mnemonicToSeed } = bip39 const { bip32, networks, ECPair } = bitcoin const { ChainID, getAddressFromPrivateKey, TransactionVersion } = stacks_transactions -const networkDerivationPath = `m/44'/5757'/0'/0/0` -const derivationPaths = { - [ChainID.Mainnet]: networkDerivationPath, - [ChainID.Testnet]: networkDerivationPath, -} - function privateKeyToWIF(private_key_hex, mainnet) { return wif.encode(mainnet ? 0x80 : 0xEF, Buffer.from(private_key_hex, 'hex'), true) } @@ -35,9 +29,9 @@ function ecPairToHexString(secretKey) { } } -function deriveStxAddressChain(chain) { +function deriveStxAddressChain(chain, derivationPath) { return (rootNode) => { - const childKey = rootNode.derivePath(derivationPaths[chain]) + const childKey = rootNode.derivePath(derivationPath) if (!childKey.privateKey) { throw new Error('Unable to derive private key from `rootNode`, bip32 master keychain') } @@ -70,10 +64,10 @@ function hash160(data) { return ripemd160(sha256(data)) } -async function generateKeys(seed_phrase, mainnet) { +async function generateKeys(seed_phrase, mainnet, derivationPath) { const seedBuffer = await mnemonicToSeed(seed_phrase) const masterKeychain = bip32.fromSeed(seedBuffer) - const keys = deriveStxAddressChain(mainnet ? ChainID.Mainnet : ChainID.Testnet)(masterKeychain) + const keys = deriveStxAddressChain(mainnet ? ChainID.Mainnet : ChainID.Testnet, derivationPath)(masterKeychain) const uncompressed_hex = bitcoin.ECPair.fromPublicKey( Buffer.from(keys.publicKey, 'hex'), @@ -90,7 +84,8 @@ async function generateKeys(seed_phrase, mainnet) { stacking: `{ hashbytes: 0x${c32c.c32addressDecode(keys.address)[1]}, version: 0x00 }`, btc: c32c.c32ToB58(keys.address), wif: privateKeyToWIF(keys.privateKey, mainnet), - } + derivationPath: derivationPath + } } yargs @@ -113,6 +108,12 @@ yargs default: 24, describe: 'Use 24 or 12 secret phrase', }) + .option('path', { + alias: 'd', + default: `m/44'/5757'/0'/0/0`, + describe: 'The derivation path for network, e.g. "m/44\'/5757\'/0\'/0/0"', + type: 'string', + }) .choices('w', [12, 24]) .command('sk', 'Generate keys for Stacks 2.0', (yargs) => { yargs.positional('sk', { @@ -125,7 +126,7 @@ yargs const phrase = argv.phrase || generateMnemonic(entropy, randombytes) // console.log('generate', phrase, argv.testnet) - console.log(JSON.stringify(await generateKeys(phrase, mainnet), null, 2)) + console.log(JSON.stringify(await generateKeys(phrase, mainnet, argv.path), null, 2)) }) .command('pk ', 'Generate keys for Stacks 2.0 from private key', (yargs) => { yargs.positional('key', { @@ -170,6 +171,7 @@ yargs .demandCommand(1, 'You need at least one command') .requiresArg('w') .requiresArg('p') + .requiresArg('d') .strictCommands(true) .strictOptions(true) .help() From 03a8db732e2db55b5843d004369c717f6b9aa1e2 Mon Sep 17 00:00:00 2001 From: Vee C Date: Fri, 10 May 2024 21:46:19 +0900 Subject: [PATCH 3/4] make account an arg --- src/index.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 1e075e1..0654a77 100644 --- a/src/index.js +++ b/src/index.js @@ -110,10 +110,14 @@ yargs }) .option('path', { alias: 'd', - default: `m/44'/5757'/0'/0/0`, describe: 'The derivation path for network, e.g. "m/44\'/5757\'/0\'/0/0"', type: 'string', }) + .option('account', { + alias: 'a', + describe: 'Specify the account number for the derivation path', + type: 'number', + }) .choices('w', [12, 24]) .command('sk', 'Generate keys for Stacks 2.0', (yargs) => { yargs.positional('sk', { @@ -126,7 +130,19 @@ yargs const phrase = argv.phrase || generateMnemonic(entropy, randombytes) // console.log('generate', phrase, argv.testnet) - console.log(JSON.stringify(await generateKeys(phrase, mainnet, argv.path), null, 2)) + let derivationPath; + if (argv.path && argv.account) { + console.error('Error: Only one of --path or --account can be used, not both.'); + process.exit(1); + } else if (argv.path) { + derivationPath = argv.path; + } else if (argv.account) { + derivationPath = `m/44'/5757'/${argv.account}'/0/0`; + } else { + derivationPath = `m/44'/5757'/0'/0/0`; // default derivation path + } + + console.log(JSON.stringify(await generateKeys(phrase, mainnet, derivationPath), null, 2)) }) .command('pk ', 'Generate keys for Stacks 2.0 from private key', (yargs) => { yargs.positional('key', { @@ -172,6 +188,7 @@ yargs .requiresArg('w') .requiresArg('p') .requiresArg('d') + .requiresArg('a') .strictCommands(true) .strictOptions(true) .help() From 29221dfe1f1ce4318b5e24bd49bb40d3089b826d Mon Sep 17 00:00:00 2001 From: Vee C Date: Wed, 6 Nov 2024 03:32:18 +0900 Subject: [PATCH 4/4] fix uncompress_pubkey cmd --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 0654a77..4789d13 100644 --- a/src/index.js +++ b/src/index.js @@ -170,8 +170,8 @@ yargs wif: privateKeyToWIF(ec_pair_compressed.privateKey, mainnet), }, null, 2)) }) - .command('uncompress_pubpkey', 'Uncompress a public key', (yargs) => { - yargs.positional('uncompress_pubpkey', { + .command('uncompress_pubkey ', 'Uncompress a public key', (yargs) => { + yargs.positional('key', { type: 'string', describe: 'Uncompress a public key' })