I am trying to make an hd wallet based on nodejs. So to have a secure wallet I have created wallet in my offline machine

const hdkey = require('ethereumjs-wallet/hdkey');
const bip39 = require('bip39');
var seed = bip39.mnemonicToSeed('my_mnemonic', 'my_password');
var chain = hdkey.fromMasterSeed(seed);
var xpub = chain.publicExtendedKey();
var xpriv = chain.privateExtendedKey();

Than using xpub I am generating addresses for users.

const wallet = require('ethereumjs-wallet');
const hdkey = require('ethereumjs-wallet/hdkey');
const _____ = require('dotenv').config();

const generate = async (index) => {

    const xpub = process.env.ETH_XPUB;

    const hdk = hdkey.fromExtendedKey(xpub);

    index = index || 0;

    const child = hdk.deriveChild(index);
    const w = wallet.fromExtendedPublicKey(child.publicExtendedKey());

    return w.getAddressString();
generate().then(v => {
}).catch(error => {

Ok, now I want to send coins from these addreses to my own address using extended private key - xpriv

const ethTx = require('ethereumjs-tx');
const Web3 = require('web3');

const web3 = new Web3(
    new Web3.providers.HttpProvider('http://localhost:8545')

//Verify connection is successful
    .then(() => console.log('is connected'))
    .catch(e => console.log('Wow. Something went wrong'));

const params = {
    nonce: 0,
    to: '0x4584158529818ef77D1142bEeb0b6648BD8eDb2f',
    value: '0.1',
    gasPrice: 5000000000,
    gasLimit: 21000,
    chainId: 3
const privKey = new Buffer('xprv9s21ZrQH143K36eJpjZxNPYbNjzzUMvqLSG6P6Sex1unL8meREsNkcMNRw4ntv3WjJ2tJJX3CrdxkCJdyo7zLnjqdFppov2BAvY4iXYuMCY','base64');
const tx = new ethTx(params);

//Signing the transaction with the correct private key
tx.sign(privKey); //ERROR HERE

const serializedTx = tx.serialize();
    (error, result) => {
        if (error) { console.log(`Error: ${error}`); }
        else { console.log(`Result: ${result}`); }

When trying to sign I am getting an error that the private key is invalid. Waht private key I need to use to sign transactions.

  • May I suggest you to remove your private key from the code above? Oct 28, 2018 at 10:51
  • I am not going to use it ) Oct 28, 2018 at 11:05

1 Answer 1


You don't sign the transaction with the Master Private Key. You sign it with the private key that corresponds to the sender's address:

const hdkey = require('ethereumjs-wallet/hdkey');
const bip39 = require('bip39');
var seed = bip39.mnemonicToSeed('my_mnemonic', 'my_password');
var chain = hdkey.fromMasterSeed(seed);
var addr_node = chain.derivePath(senders_derivation_path);
//if addr is the same with the address you want to send from, then its corresponding private_key will also be valid. Otherwise, most probably the senders_derivation_path is wrong
var addr = addr_node.getWallet().getAddressString();
var private_key = addr_node.getWallet().getPrivateKey();
  • But what if I dont want to use private key in my online service ? Its not secure , and if someone hacked my server can withdraw coins using this private key Oct 28, 2018 at 16:38
  • you create the transaction on the online computer, but sign it on the offline one. I thought your issue in this particular question was how to get the private key for the signing address, and that's what my answer is for. Oct 28, 2018 at 16:40
  • can you provide the code, so that I can understand? Oct 28, 2018 at 16:44
  • maybe, in a separate question, once you upvote and accept the questions I already answered you. Let's try and use this forum as it is intended to be used: one punctual question/thread. Oct 28, 2018 at 16:45
  • the answer did not help me solve the problem Oct 28, 2018 at 17:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.