Skip to content

How to iterate through BIP44 addresses? #155

@shayanb

Description

@shayanb

I'm trying to use eth-lightwallet to generate BIP32/44 style addresses using custom paths, let's say:

BasePath = m'/0'/0''

Address 1= m'/0'/0'/1
Address 2= m'/0'/0'/2
Address 3= m'/0'/0'/3
...

The way eth-lightwallet seems to be working is by using ks.generateNewAddress(pwDerivedKey, 1); you'd get the next address but I couldn't find a way to get either the path for that address or input the custom path to generate the address in the path I want.

There's a way to iterate through the addresses which is a bit hacky, something like the following:

BasePath = m'/0'/0'/0'

Address 1= m'/0'/0'/1/1
Address 2= m'/0'/0'/2/1
Address 3= m'/0'/0'/3/1
...

Here is the source code for such iteration:

function generateNewAddress (seed, password, HdPathString, newAddressIdentifier, done) {
  // newAddressIdentifier is the incremental value for new address
  // the final path is basically HdPathString/newAddressIdentifier
  const finalHdPath = HdPathString + '/' + newAddressIdentifier.toString() + "'";
  console.log('finalHdPath', finalHdPath);

  lightwallet.keystore.deriveKeyFromPassword(password, function (err, pwDerivedKey) {
    var ks = new lightwallet.keystore(secretSeed, pwDerivedKey, finalHdPath);

    ks.generateNewAddress(pwDerivedKey, 1);
    var addr = ks.getAddresses()[0];
    console.log('addr', addr);
    var privKey = ks.exportPrivateKey(addr, pwDerivedKey, finalHdPath);
    const retObj = {address: addr,
      privateKey: privKey};
    done(null, retObj);
  });
}

The ^ solution is using the deprecated function which will be removed on next updates.

However using the new method KeyStore.createVault() even this hack is not possible as it would throw exception.

this works fine when the finalHdPath is m/0'/0'/0'. but fails as soon as we try to run it using any other default path:

function generateNewAddress (seed, password, HdPathString, newAddressIdentifier, done) {
  // newAddressIdentifier is the incremental value for new address
  // the final path is basically HdPathString/newAddressIdentifier
  const finalHdPath = HdPathString + '/' + newAddressIdentifier.toString() + "'";
  console.log('finalHdPath', finalHdPath);

  lightwallet.keystore.createVault({
    password: password,
    seedPhrase: secretSeed,
    HdPathString: finalHdPath
  }, function (err, ks) {
    if (err) done(err);
    ks.keyFromPassword(password, function (err, pwDerivedKey) {
      if (err) done(err);
      ks.generateNewAddress(pwDerivedKey, 1, finalHdPath); // generateNewAddress(pwDerivedKey, [num,] [hdPathString])
      console.log(ks.getAddresses());
      var addr = ks.getAddresses()[0];
      var privKey = ks.exportPrivateKey(addr, pwDerivedKey, finalHdPath);
      console.log(ks.defaultHdPathString);
      console.log('addr', addr);
      const retObj = {address: addr,
        privateKey: privKey};
      done(null, retObj);
    });
  });
}

for input m/0'/0'/0':

[ 'fff3a90735a619bd1a5780450b446d1515928b68' ]
m/0'/0'/0'
addr fff3a90735a619bd1a5780450b446d1515928b68
{ address: 'fff3a90735a619bd1a5780450b446d1515928b68',
  privateKey: 'fa746519af5b0bb64163d96bb13548e7e15410080e45ac8df388b9568f01042a' }

for input m/0'/0'/1':

hdPathString m/0'/0'/1'
this.ksData[hdPathString] undefined
/token_eth_sweeper/testFlow.js:43
  if (err) throw err;
           ^

TypeError: Cannot read property 'info' of undefined
    at KeyStore.generateNewAddress (/token_eth_sweeper/node_modules/eth-lightwallet/lib/keystore.js:443:32)
    at /token_eth_sweeper/testFlow.js:29:10
    at cb (/token_eth_sweeper/node_modules/eth-lightwallet/lib/keystore.js:524:7)
    at /token_eth_sweeper/node_modules/scrypt-async/scrypt-async.js:518:13
    at Immediate._onImmediate (/token_eth_sweeper/node_modules/scrypt-async/scrypt-async.js:481:11)
    at runCallback (timers.js:800:20)
    at tryOnImmediate (timers.js:762:5)
    at processImmediate [as _immediateCallback] (timers.js:733:5)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions