-
Notifications
You must be signed in to change notification settings - Fork 812
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
Wallet: support import of x/y/zpubkey (BIP49 and BIP84) #616
base: master
Are you sure you want to change the base?
Conversation
Codecov Report
@@ Coverage Diff @@
## master #616 +/- ##
==========================================
+ Coverage 61.94% 62.07% +0.13%
==========================================
Files 156 156
Lines 26084 26162 +78
==========================================
+ Hits 16157 16240 +83
+ Misses 9927 9922 -5
Continue to review full report at Codecov.
|
dc464f6
to
7f5fc42
Compare
@pinheadmz what is the status on the TODOs for this pull request? |
Rebased on master. I think this has been a useful branch to maintain for some users even if it doesn't get merged. BIP49 nested-segwit wallets were the default on Trezor for a while and this patch can functionally watch those accounts. |
Rebased on master again, to include client inside repo. Also added |
Todo:
purpose
as an optionAddresses #606
Supports BIP49 and BIP84
Motivation
I wanted to create a watch-only bcoin wallet that follows my Trezor wallet. For SegWit users, Trezor created
ypub
andzpub
version types (see SLIP32):0x0488b21e
-xpub
0x0488ade4
-xprv
0x049d7cb2
-ypub
0x049d7878
-yprv
0x04b24746
-zpub
0x04b2430c
-zprv
Currently bcoin only supports
xpub
and in fact all wallets derive accounts and addresses from the pathm/44'
so these new paths would be unreachable.Method
Networks
I started with the
keyPrefix
object in networks.js to add all the new codes. Note that bcoin usesxprv
internally for testnet even though those keys are prefixed withtprv
like so:I maintain that convention and use x/y/z throughout, even though the actual user-facing prefixes may be different.
HD private/public key
Key objects have a new property
purpose
that is eitherx
(default),y
, orz
.purpose
can be passed as an option, but mainly it is derived from an imported extended private or public key, based on the prefix bytes.Wallet Account
Wallets and Accounts also have a
purpose
that is either passed as an option or derived from theaccountKey
option (for watch-only). This is mostly where the x/y/z/ logic gets switched. Eachpurpose
has a specific BIP44 purpose in the derivation path AND specifically dictated address types. Fory
andz
,witness
is alwaystrue
. Fory
, addresses are always witness-nested-in-P2SH. Normally these addresses could only be derived onbranch = 2
from a regular wallet. This PR ALWAYS returns nested addresses for receive and change if the account type isy
. Similarly,z
wallets always return bech32-encoded native SegWit addresses.Serialized Account for database
Ok here's where it gets a bit touchy. Accounts are serialized before saving to the database. Currently, all the relevant bits from the
accountKey
are included EXCEPT the header bytes:So what I did was, steal the TWO leftmost bits of the
flags
byte and re-purposed them forpurpose
. This means we can only have 4 values forpurpose
and we still have 6 bits for actual flags (of which only two are currently used:initialized
andwitness
).Alternatively, this can be adjusted if we want more future-proof-ness and use less bits for flags and more for
purpose
, etc.This has the benefit of some backwards-compatibility:
y
orz
: no failures buty
andz
wallets will not derive new addresses correctly (they will derive everything as if it ispurpose = 'x'
)