Comments (6)
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;
},
);
from bip32.
Segwit p2sh and native not covered.
Not sure if it belongs in readme, but if anyone will be searching for "electrum" in issues - here it is...
Ref:
https://github.com/spesmilo/electrum/blob/1600241b0221f74b30d8130e8f2e25c03814e61d/electrum/keystore.py#L984
https://github.com/spesmilo/electrum/blob/master/electrum/mnemonic.py
from bip32.
I added a validator to check the validity of the backup...
from bip32.
Also note that this example is missing normalize_text which means if you use a passphrase that isn't normalized you could potentially create a wallet that is not recoverable in Electrum.
from bip32.
Good catch! To anyone who reads this, normalization is
The normalization function (prepare_seed) removes all but one space between words. It also removes diacritics, and it removes spaces between Asian CJK characters.
https://electrum.readthedocs.io/en/latest/seedphrase.html
Thanks for the complete example! Cheers!
from bip32.
@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
from bip32.
Related Issues (20)
- Path to derive grandchildren from children HOT 1
- Non-hardened keys have... private keys? HOT 1
- TypeError: BIP32Factory is not a function HOT 9
- Alternatives to tiny-secp256k1? HOT 11
- Improve usage with hw-app-eth keys HOT 4
- [ERROR] Digital envelope routines::unsupported HOT 7
- Buffer is not defined HOT 8
- TypeError: bip32.fromSeed is not a function HOT 7
- TypeError: bip32.fromSeed is not a function HOT 2
- Add support for other xpub versions (zpub & ypub) HOT 2
- Derivation path elements > 2147483647 should throw? HOT 3
- Understanding the BIP32 version HOT 3
- ecc.isPoint is not a function HOT 1
- Optional passphrase upon wallet generation HOT 1
- Serializing to Extended keys HOT 1
- How to use this version of bip32 to port some code? HOT 10
- "Invalid network version" when calling the toWIF() method on derived private key HOT 2
- Not able to run in browser HOT 1
- How to sign a message using ECDSA HOT 1
- toWIF failed in browser?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bip32.