question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

(not an issue) Electrum seed format example

See original GitHub issue

Edit 2 (from junderw): I made an Electrum seed library: Here is the github and it can be installed with npm install electrum-mnemonic

Edit (from junderw): See my reply below for an example of segwit wallet as well

After wasting half a day and reading Electrum docs & sources, here’s an example how to work with electrum seed format:

const crypto = require('crypto');
const bitcoin = require('bitcoinjs-lib');

function  mnemonic2seed(mnemonic, passphrase = '', iterations = 2048) {
    return crypto.pbkdf2Sync(mnemonic, 'electrum' + passphrase, iterations, 64, 'sha512');
}

const root = bitcoin.bip32.fromSeed(mnemonic2seed("<SEED HERE>"));
let xpub = root.toBase58();

const index = 1;
const node = bitcoin.bip32.fromBase58(xpub);
const externalAddress = bitcoin.payments.p2pkh({
  pubkey: node.derive(0).derive(index).publicKey,
}).address;

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
junderwcommented, Apr 16, 2020

This is a bit more complete and covers both legacy and segwit.

const crypto = require('crypto');
const bitcoin = require('bitcoinjs-lib');
const bs58 = require('bs58check');
const assert = require('assert');

function mnemonic2seed(mnemonic, passphrase = '', iterations = 2048) {
  return crypto.pbkdf2Sync(
    mnemonic,
    'electrum' + passphrase,
    iterations,
    64,
    'sha512',
  );
}

function toXpub(yOrZPub) {
  return bs58.encode(
    Buffer.concat([
      Buffer.from('0488B21E', 'hex'),
      bs58.decode(yOrZPub).slice(4),
    ]),
  );
}

function checkBackup(backup, type = 'segwit') {
  const versions = {
    segwit: '100',
    standard: '01',
  }
  const hmac = crypto.createHmac('SHA512', 'Seed version')
  hmac.update(backup)
  const hx = hmac.digest('hex')
  if (!hx.startsWith(versions[type])) throw new Error('Invalid Backup Seed')

  return backup
}

function electrumWalletTests(
  backup,
  expectedAddress,
  expectedXpub,
  paymentFunc, // turn pubkey into payment object
  xpubDeriveFunc, // turn the root of bip32 master node into master pub node
) {
  const seed = mnemonic2seed(backup);
  const root = bitcoin.bip32.fromSeed(seed);
  const xpub = xpubDeriveFunc(root).neutered().toBase58();

  assert.strictEqual(xpub, expectedXpub);

  const index = 0;
  const node = bitcoin.bip32.fromBase58(xpub);
  const externalAddress = paymentFunc(node.derivePath(`0/${index}`).publicKey)
    .address;

  assert.strictEqual(externalAddress, expectedAddress);
}

// segwit wallet
electrumWalletTests(
  checkBackup('bullet wife mass allow quick degree rhythm fetch divert hotel vintage cruel', 'segwit'),
  'bc1qc8t8tadxwnw5fqfqycxl9ljahgp8g6yl9zzuwy',
  toXpub(
    'zpub6mux8KS53pqPCudXHvZYfj9UGmgWPMsJj9vczmosXE5dR3QubjQNw4ZqDovPa3af4hxFoVPvY8Q8VGQsriZRAjsRiDNLmaj3Yx9iKcjaBVV',
  ),
  function (pubkey) {
    return bitcoin.payments.p2wpkh({
      pubkey,
    });
  },
  function (root) {
    return root.derivePath("m/0'");
  },
);

// legacy wallet
electrumWalletTests(
  checkBackup('decade width renew post mistake orange record drink vintage sorry chalk hard', 'standard'),
  '1U9sVduetA4qE388QASN2sqpcee3PJbmx',
  'xpub661MyMwAqRbcFm9rdav51WyLWC3oEHU91XUWAv8Y8AkPg5hXDu2ta1B9C3u1aWDVFo5qmJD8bJTUUJD6dUJ9AeW1NM5rGNyysXx41u5gmmH',
  function (pubkey) {
    return bitcoin.payments.p2pkh({
      pubkey,
    });
  },
  function (root) {
    return root;
  },
);
0reactions
junderwcommented, Apr 16, 2020

@Overtorment I made a library that normalizes as close to Python3 as possible.

I tried a few Japanese seeds and it works with Electrum… but it’s kinda scary to include non-english wordlists rn.

https://github.com/bitcoinjs/electrum-mnemonic

Read more comments on GitHub >

github_iconTop Results From Across the Web

Electrum Seed Version System
Electrum 2.0 derives keys and addresses from a hash of the UTF8 normalized seed phrase with no dependency on a fixed wordlist.
Read more >
Restoring your standard wallet from seed - Bitcoin Electrum
Begin by creating a new wallet file as per this guide. Click on next to see the wallet type selection window: As you...
Read more >
ELECTRUM SEED MYSTERY: MANUALLY EXTENDED ...
I'm just asking because you say that you have written down only the seed phrase, which is not enough if you don't have...
Read more >
Electrum seed gives invalid mnemonic error · Issue #448
When I make a new Segwit (bech32) wallet in Electrum the seeds it generates are not considered valid. Is that expected behavior?
Read more >
Seed phrase - Bitcoin Wiki
BIP39 is the most common standard used for seed phrases. One notable example is Electrum wallet, which is using its own standard, and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found