Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use this version of bip32 to port some code? #78

Open
zydjohnHotmail opened this issue Jun 2, 2023 · 10 comments
Open

How to use this version of bip32 to port some code? #78

zydjohnHotmail opened this issue Jun 2, 2023 · 10 comments

Comments

@zydjohnHotmail
Copy link

Hello:
I want to port some old code to new code. I am trying to create some QTUM wallet, which has the derivePath of "m/88'/0'/0'".
The Wallet definition for QTUM looks like this:
export class Wallet {
  public address: string
  private insight: Insight

    constructor(public keyPair: bip32.BIP32Interface,
        public network: INetworkInfo)
    {
        this.address = this.keyPair.toBase58();
        this.insight = Insight.forNetwork(this.network)
    }

I want to use the following TS code:
import * as ecc from 'tiny-secp256k1';
import { BIP32Factory } from 'bip32';

export class Network {
constructor(public info: INetworkInfo) {}

/**

  • Restore a HD-wallet address from mnemonic & password
  • @param mnemonic
  • @param password

*/
public fromMnemonic(mnemonic: string, password?: string): Wallet {
const hdNode = ethers.HDNodeWallet.fromMnemonic(mnemonic, password);
const accountNode = hdNode.derivePath("m/88'/0'/0'");
const privateKey = accountNode.privateKey;
const bip32 = BIP32Factory(ecc);
const chainCode = accountNode.chainCode;
const node = bip32.fromPrivateKey(Buffer.from(privateKey), Buffer.from(chainCode));
const keyPair = KeyPair.fromPrivateKey(Buffer.from(privateKey));
return new Wallet(keyPair, this.info);
}

But the keyPair is not correct. I think keyPair is only one data type for private_key and public_key, right?
However, I don’t know how to get a public key from the private key.
Please let me know how can I make the code to work?
PS: I am using Node.js version 20.2 on Windows 10 (22H2)
Thanks,

@junderw
Copy link
Member

junderw commented Jun 2, 2023

Your code doesn't do anything with bip32. It creates the node variable and does nothing with it.

You essentially are just using ethers.HDNodeWallet and KeyPair classes. (although I don't see where they are defined, so I have no clue what they are.)

I am confused as to what you are asking here.

@zydjohnHotmail
Copy link
Author

The definition for Qtum Wallet:
constructor(public keyPair: bip32.BIP32Interface, public network: INetworkInfo)
I need 2 parameters, one for bip32.BIP32Interface, another for INetworkInfo).
I don't know how to get the first parameter in order to pass the paramters to Qtum Wallet's constructor.

@junderw
Copy link
Member

junderw commented Jun 2, 2023

Pass node instead of keypair.

I don't even know what keypair is... where did KeyPair class come from? Does KeyPair implement the BIP32Interface? I'm guessing not, since you say there's an error.

You aren't giving me enough information.

@zydjohnHotmail
Copy link
Author

Hi, I show you the original code using old version of 'bitcoinjs-lib':
import { HDNode, ECPair } from "bitcoinjs-lib"
export interface INetworkInfo {
name: string

messagePrefix: string
bech32: string

// HDWallet https://en.bitcoin.it/wiki/BIP_0032
bip32: {
public: number
private: number
}

pubKeyHash: number
scriptHash: number
wif: number
}
export class Network {
constructor(public info: INetworkInfo) {}

/**

  • Restore a HD-wallet address from mnemonic & password
  • @param mnemonic
  • @param password

*/
public fromMnemonic(mnemonic: string, password?: string): Wallet {
// if (bip39.validateMnemonic(mnemonic) == false) return false
const seedHex = bip39.mnemonicToSeedSync(mnemonic, password).toString('hex')
const hdNode = HDNode.fromSeedHex(seedHex, this.info)
const account = hdNode
.deriveHardened(88)
.deriveHardened(0)
.deriveHardened(0)
const keyPair = account.keyPair

return new Wallet(keyPair, this.info)

}

=> The old code seems to be good for old version of 'bitcoinjs-lib', but I want to use new version, I have no idea on how to port from old 'bitcoinjs-lib' to new version.

@junderw
Copy link
Member

junderw commented Jun 2, 2023

This still doesn't tell me what ethers is or KeyPair is...

Did you read the examples? Like this one?

In this example, the variable child is a BIP32Interface

@zydjohnHotmail
Copy link
Author

Hello:
I want to port some old code to new code. The 'ethers' means the npm package 'ethers', but this 'ethers' npm package also changes a lot, the old version has almost all modules in the npm package, but the new version (v6.4.1) has some different npm packages starting with '@ethersproject', like: '@ethersproject/abi' and many many more. So to port old code to new code, I have to install many many new npm packages, like '@ethersproject/abi', '@ethersproject/address', '@ethersproject/web'..., In this function I want to port from old to new is bascially that I want to create a Qtum Wallet, the major difference between Qtum Wallet and Bitcoin Wallet is the derive path: for Qtum Wallet, its value is: "m/88'/0'/0'", for Bitcoin Wallet, the value is "m/44'/0'/0'". But since the new 'bitcoinjs-lib' version is rather different from the old version, so my code is not working as expected. There is one GUI tools: https://iancoleman.io/bip39/
You can pickup a random Mnemonic, then input m/88'/0'/0' in the BIP32 Derivation Path input box below the 'BIP141' tab, then you can see this Gui tools generate some private keys, public keys and Derived Addresses with different derive path, like: m/88'/0'/0'/0, m/88'/0'/0'/1; m/88'/0'/0'/2, etc. So what I want is to change the code to do something you can see from https://iancoleman.io/bip39/. The 'ethers' means the npm package 'ethers', the latest version is 6.4.1. Hope you understand.

@junderw
Copy link
Member

junderw commented Jun 2, 2023

Please read the example I posted.


In response to your explanation:

Yes, I know what ethers is.

When I say "What is ethers?" it means "What is this doing here in the code? Why are you using it? Is there a specific reason why it needs to be used in this way?"


To give another example of this English used in a different context:

If you hand me a pizza with a dead bird on top of it, and I say "What is this bird?"

I am not asking you to link a Wikipedia article on the exact species of bird and all the information about the bird's migration patterns.

I am asking "Under the pretense that dead birds shouldn't be on top of pizza, I would like to ask you why there is a bird on this pizza when there is no need. Did you put it there? Did the store clerk put it there? Is this a special exotic pizza where I'm supposed to eat the dead bird?" etc. but all of that is shortened down to "What is this bird?"

@zydjohnHotmail
Copy link
Author

Hi,
I see your meaning. But for me, the 'ethers' npm package may not be necessary. But since the 'bitcoinjs-lib' npm package has changed a lot, so I don't know where I can find the module 'HDNode'. If you can port the original code to use latest version of 'bitcoinjs-lib', then without using 'ethers' is OK. The original code looks like this:

import { HDNode, ECPair } from "bitcoinjs-lib"
public fromMnemonic(mnemonic: string, password?: string): Wallet {
// if (bip39.validateMnemonic(mnemonic) == false) return false
const seedHex = bip39.mnemonicToSeedSync(mnemonic, password).toString('hex')
const hdNode = HDNode.fromSeedHex(seedHex, this.info)
const account = hdNode
.deriveHardened(88)
.deriveHardened(0)
.deriveHardened(0)
const keyPair = account.keyPair

return new Wallet(keyPair, this.info)

}
If you can port the code to new npm version without using 'ethers' npm package, it is better.

@junderw
Copy link
Member

junderw commented Jun 2, 2023

@zydjohnHotmail
Copy link
Author

Hi, I read the example, but I have some strange issues with the following code:
import * as assert from 'assert';
import BIP32Factory from 'bip32';
import * as ecc from 'tiny-secp256k1';
import * as bip39 from 'bip39';
import { describe, it } from 'mocha';
import * as bitcoin from '../..';

const bip32 = BIP32Factory(ecc);

const bip32 = BIP32Factory(ecc); =>
This expression is not callable.
Type 'typeof import("e:/npms/qtumjs/node_modules/bip32/types/index")' has no call signatures.
The following is my 'tsconfig.json' file: {
"compilerOptions": {
"target": "es6",
"module": "es2015",
"moduleResolution": "nodeNext",
"skipLibCheck": true
}
}
Let me know what is your 'tsconfig.json' file when running the example, which compilerOptions I have missed? I am using Node.js version 20.2 on Windows 10.
By the way, since the new version of 'bip32' seems have only one module 'BIP32Factory', then how can I define a wallet with a BIP32Interface with the new 'bip32' npm package?
Thanks,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants