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

Add alternate BIP32 Prefixes (BIP 49 & 84) #59

Open
wants to merge 138 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 68 commits
Commits
Show all changes
138 commits
Select commit Hold shift + click to select a range
5af3018
fix typo
SachinMeier Jan 7, 2021
bb1191e
add private key module
SachinMeier Jan 7, 2021
f2ab1e5
add der serialization
SachinMeier Jan 7, 2021
4a3fe87
fix der casing
SachinMeier Jan 7, 2021
ce9fc16
add DER parse & serialize
SachinMeier Jan 8, 2021
7a95429
rm debug function
SachinMeier Jan 8, 2021
6971e0c
test encoding of sig
SachinMeier Jan 8, 2021
5eca299
cleanup
SachinMeier Jan 8, 2021
e6ca99a
add signature verification and 1 test
SachinMeier Jan 8, 2021
c48c95d
add parse_wif & tests
SachinMeier Jan 9, 2021
0e177be
add parse for uncompressed
SachinMeier Jan 8, 2021
1b19e70
add parse for uncompressed
SachinMeier Jan 8, 2021
9fd38dd
add parse code-nonfunctional
SachinMeier Jan 8, 2021
e7cb52d
add utils
SachinMeier Jan 9, 2021
8a1ad79
finish pubkey parse
SachinMeier Jan 10, 2021
f525d57
fix pubkey tests
SachinMeier Jan 10, 2021
5b9236d
rebase, clean up, add fuzz testing
SachinMeier Jan 12, 2021
8d6739a
test parse uncompressed
SachinMeier Jan 12, 2021
eae9dbd
mix format
SachinMeier Jan 13, 2021
fa53e8c
update testing for privkey s -> d
SachinMeier Jan 18, 2021
6268e61
add comments, parse pubkey from str
SachinMeier Jan 18, 2021
8a873da
change key s -> d, comment & update deterministic_k
SachinMeier Jan 18, 2021
4bcd0ad
mix format
SachinMeier Jan 20, 2021
c551248
fix specs
SachinMeier Jan 20, 2021
00b4f32
remove duplicate spec
SachinMeier Jan 20, 2021
1777891
add parse pubkey from hex test
SachinMeier Jan 20, 2021
8da50bf
format
SachinMeier Jan 22, 2021
a92dbc3
Merge pull request #1 from SachinMeier/sachin--add-privkey
SachinMeier Feb 13, 2021
cad0b80
add test vectors for deterministic_k function
SachinMeier Feb 16, 2021
1db066a
add description to sign function
SachinMeier Feb 16, 2021
58f666f
Merge pull request #3 from SachinMeier/sachin--add-privkey
SachinMeier Feb 16, 2021
66b9a15
Merge branch 'master' of github.com:RiverFinancial/bitcoinex
SachinMeier Mar 13, 2021
6a5e75a
Merge branch 'master' of github.com:RiverFinancial/bitcoinex
SachinMeier Apr 14, 2021
d6d2204
add parse for uncompressed
SachinMeier Jan 8, 2021
9659d74
add parse code-nonfunctional
SachinMeier Jan 8, 2021
f3570bd
finish pubkey parse
SachinMeier Jan 10, 2021
e62dd16
fix pubkey tests
SachinMeier Jan 10, 2021
334c63f
init
SachinMeier Jan 12, 2021
39fefd9
add wordlists
SachinMeier Jan 13, 2021
28b2f0e
fix wordlist
SachinMeier Jan 13, 2021
30e8509
init xkey
SachinMeier Jan 13, 2021
b15b9b0
update
SachinMeier Jan 22, 2021
17811aa
derive child
SachinMeier Jan 23, 2021
4e802c2
add child derivation, testing for bip84
SachinMeier Feb 10, 2021
758bb93
add more xpub testing
SachinMeier Feb 13, 2021
506d17a
edit specs
SachinMeier Feb 13, 2021
f1a32f1
documentation
SachinMeier Mar 2, 2021
385abde
add derivation path module
SachinMeier Mar 5, 2021
961687a
# This is a combination of 3 commits.
SachinMeier Jan 8, 2021
46ff859
msg
SachinMeier Apr 14, 2021
b7084ee
add wordlists
SachinMeier Jan 13, 2021
5bc495f
derive child
SachinMeier Jan 23, 2021
eb385f5
add child derivation, testing for bip84
SachinMeier Feb 10, 2021
7dcfef6
add testing for deriv paths
SachinMeier Mar 5, 2021
408cd88
remove wordlist
SachinMeier Apr 14, 2021
5e5806c
rm seed.ex
SachinMeier Apr 14, 2021
91ec102
format
SachinMeier Apr 14, 2021
b18f7e9
Merge pull request #2 from SachinMeier/sachin--add-bip32
SachinMeier Apr 14, 2021
6d50f6f
fix ckd and add failure testing
SachinMeier Apr 14, 2021
2c73fa2
add check valid pubkey on all xkeys
SachinMeier Apr 15, 2021
bb50411
Merge branch 'master' of github.com:RiverFinancial/bitcoinex
SachinMeier Apr 16, 2021
0ec7102
Update jason to 1.2.2 so that we can remove the overide for decimal (…
philipglazman Apr 19, 2021
f4c9bc6
credo refactor code, add wildcard to deriv paths
SachinMeier Apr 21, 2021
6b87987
remove raise error
SachinMeier Apr 24, 2021
6599520
Merge branch 'master' of github.com:RiverFinancial/bitcoinex
SachinMeier Apr 26, 2021
785df11
use derivation paths in PSBT
SachinMeier Nov 2, 2021
f66784a
rename parse/serialize/display functions
SachinMeier Nov 2, 2021
7845135
use xpubs in PSBT
SachinMeier Nov 2, 2021
0fdbd74
rename prv functions
SachinMeier Nov 3, 2021
3944215
remove checksum from xkey struct && add switch prefix functionality
SachinMeier Sep 4, 2022
a5b40f3
merge master
SachinMeier Sep 4, 2022
009f578
fix tests & fmt
SachinMeier Sep 5, 2022
a40c8dd
simplify func signatures
SachinMeier Oct 21, 2022
f479ccb
first draft adaptor signatures
SachinMeier Oct 22, 2022
2ccff2e
fmt
SachinMeier Oct 22, 2022
40372d5
fix typo
SachinMeier Oct 22, 2022
4baa1f2
simplify code & add extract_sig from adaptor
SachinMeier Oct 22, 2022
a04f43e
make code consistent across sign & adaptor sign
SachinMeier Oct 22, 2022
47d2a01
temp: try to fix R+T not even bug
SachinMeier Oct 27, 2022
25eef34
make ExtendedKey.serialize elixir-idiomatic
SachinMeier Jan 17, 2023
35cdda1
Merge branch 'master' into sachin--psbt-use-deriv-and-xpub
SachinMeier Jan 17, 2023
05f5edd
temp fix adaptors
SachinMeier Jan 28, 2023
ab82799
Merge branch 'master' into sachin--adaptor-signatures
SachinMeier Jan 28, 2023
b7d5739
fix schnorr adaptor signatures
SachinMeier Jan 30, 2023
ce1f869
finish adaptor signatures!
SachinMeier Jan 31, 2023
6a4e775
add comments, make tests realistic by force even tweak
SachinMeier Jan 31, 2023
8bccf20
fmt
SachinMeier Jan 31, 2023
f4dc730
do not assume even tweak
SachinMeier Feb 1, 2023
932687b
do not assume tweak is even in tests
SachinMeier Feb 1, 2023
92ae2b4
add key-only taproot script creation
SachinMeier Feb 1, 2023
f9054d2
add Taproot.build_control_block and merkle tree handling
SachinMeier Feb 4, 2023
7f34d80
improve create_p2tr signature
SachinMeier Feb 4, 2023
ad34bf6
finish bip341 sighash & tx signing
SachinMeier Feb 5, 2023
02a7fbd
add scriptpath spend, op_checksigadd, scripts for examples
SachinMeier Feb 6, 2023
11fe186
add tx hex to taproot multi-spend ex
SachinMeier Feb 6, 2023
8792568
cleanup
SachinMeier Feb 6, 2023
406e73f
rm tapscript.ex
SachinMeier Feb 6, 2023
a65df93
Merge branch 'sachin--adaptor-signatures' into sachin--add-key-only-t…
SachinMeier Feb 6, 2023
17e28df
add full DLC example
SachinMeier Feb 9, 2023
0d18d7a
syntax
SachinMeier Feb 9, 2023
45ea0b3
add spec for function
SachinMeier Feb 12, 2023
e9fadf4
Merge branch 'master' into sachin--psbt-use-deriv-and-xpub
SachinMeier Feb 13, 2023
b977596
add psbt new fields
SachinMeier Feb 13, 2023
f4d7a3d
psbt v2 serialization funcs
SachinMeier Feb 17, 2023
41fd7d5
fix lints
SachinMeier Feb 17, 2023
31dedf7
rm duplicate test cases & add serialization & improve logic for handl…
SachinMeier Feb 21, 2023
5820c75
add psbt test vectors
SachinMeier Feb 21, 2023
ed4f6b6
add all fields to psbt global serializer
SachinMeier Feb 21, 2023
5eba54e
add BIP370 & 371 test vectors for psbt
SachinMeier Feb 24, 2023
d534c26
add todo
SachinMeier Feb 24, 2023
289e49c
lint
SachinMeier Feb 24, 2023
5bed706
Merge branch 'sachin--adaptor-signatures' into sachin--add-key-only-t…
SachinMeier Feb 24, 2023
5cc1ef6
lint
SachinMeier Feb 24, 2023
e659a67
lint
SachinMeier Feb 24, 2023
581403f
fmt
SachinMeier Feb 24, 2023
02ab1cf
fmt
SachinMeier Feb 24, 2023
9bd20fa
lint
SachinMeier Feb 24, 2023
afadef2
fmt
SachinMeier Feb 24, 2023
e133c5c
fix aliases
SachinMeier Feb 24, 2023
72a89d0
lint
SachinMeier Feb 24, 2023
3a48dbd
lint
SachinMeier Feb 24, 2023
73b7500
lint
SachinMeier Feb 24, 2023
e2cf4a0
Merge pull request #11 from SachinMeier/sachin--psbt-use-deriv-and-xpub
SachinMeier Feb 24, 2023
2043883
Merge pull request #12 from SachinMeier/sachin--adaptor-signatures
SachinMeier Feb 24, 2023
fa7df7f
lint
SachinMeier Feb 24, 2023
d81cd49
Merge branch 'master' into sachin--add-key-only-taproot-script-creation
SachinMeier Feb 24, 2023
3294369
Merge pull request #13 from SachinMeier/sachin--add-key-only-taproot-…
SachinMeier Feb 24, 2023
eb0b3eb
Add PSBT fields functionality (#14)
SachinMeier Mar 4, 2023
e64c0e4
Add tapscript multisig helpers & BIP 67 & BIP 69 (#15)
SachinMeier Mar 8, 2023
059cee5
fix bip69 bug
SachinMeier Mar 9, 2023
2feb258
Add Tx vbyte size calculation (#16)
SachinMeier Mar 9, 2023
b044347
fix bip69 bug (#17)
SachinMeier Mar 9, 2023
369b720
Merge branch 'master' of https://github.com/SachinMeier/bitcoinex
SachinMeier Mar 9, 2023
9c67b08
fix bugs with calculate_signature_point (#18)
SachinMeier Mar 18, 2023
b9f6482
privkey to hex
SachinMeier Apr 15, 2023
2c0fde6
rebase
SachinMeier Jan 24, 2024
bdc6bdd
fix test
SachinMeier Jan 24, 2024
3e08e30
fmt
SachinMeier Jan 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 140 additions & 49 deletions lib/extendedkey.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule Bitcoinex.ExtendedKey do

defmodule DerivationPath do
@moduledoc """
Contains a list of integers (or the :any atom) representing a bip32 derivation path.
Contains a list of integers (or the :any atom) representing a bip32 derivation path.
The :any atom represents a wildcard in the derivation path. DerivationPath structs can
be used by ExtendedKey.derive_extended_key to derive a child key at the given path.
"""
Expand Down Expand Up @@ -43,17 +43,17 @@ defmodule Bitcoinex.ExtendedKey do
def new(), do: %__MODULE__{child_nums: []}

@spec to_string(t()) :: {:ok, String.t()} | {:error, String.t()}
def to_string(%__MODULE__{child_nums: path}), do: tto_string(path, "")
def to_string(%__MODULE__{child_nums: path}), do: to_string(path, "")

defp tto_string([], path_acc), do: {:ok, path_acc}
defp to_string([], path_acc), do: {:ok, path_acc}

defp tto_string([l | rest], path_acc) do
defp to_string([l | rest], path_acc) do
cond do
l == :any ->
tto_string(rest, path_acc <> "*/")
to_string(rest, path_acc <> "*/")

l == :anyh ->
tto_string(rest, path_acc <> "*'/")
to_string(rest, path_acc <> "*'/")

l > @max_hardened_child_num ->
{:error, "index cannot be greater than #{@max_hardened_child_num}"}
Expand All @@ -63,7 +63,7 @@ defmodule Bitcoinex.ExtendedKey do

# hardened
l >= @min_hardened_child_num ->
tto_string(
to_string(
rest,
path_acc <>
(l
Expand All @@ -74,28 +74,28 @@ defmodule Bitcoinex.ExtendedKey do

# unhardened
true ->
tto_string(rest, path_acc <> Integer.to_string(l) <> "/")
to_string(rest, path_acc <> Integer.to_string(l) <> "/")
end
end

@spec from_string(String.t()) :: {:ok, t()} | {:error, String.t()}
def from_string(pathstr) do
def from_string(pathstr) when is_binary(pathstr) do
try do
{:ok, %__MODULE__{child_nums: tfrom_string(String.split(pathstr, "/"))}}
{:ok, %__MODULE__{child_nums: from_string(String.split(pathstr, "/"))}}
rescue
e in ArgumentError -> {:error, e.message}
end
end

defp tfrom_string(path_list) do
def from_string(path_list) when is_list(path_list) do
case path_list do
[] -> []
[""] -> []
["m" | rest] -> tfrom_string(rest)
["*" | rest] -> [:any | tfrom_string(rest)]
["*'" | rest] -> [:anyh | tfrom_string(rest)]
["*h" | rest] -> [:anyh | tfrom_string(rest)]
[i | rest] -> [str_to_level(i) | tfrom_string(rest)]
["m" | rest] -> from_string(rest)
["*" | rest] -> [:any | from_string(rest)]
["*'" | rest] -> [:anyh | from_string(rest)]
["*h" | rest] -> [:anyh | from_string(rest)]
[i | rest] -> [str_to_level(i) | from_string(rest)]
end
end

Expand Down Expand Up @@ -132,8 +132,7 @@ defmodule Bitcoinex.ExtendedKey do
parent_fingerprint: binary,
child_num: binary,
chaincode: binary,
key: binary,
checksum: binary
key: binary
}

@enforce_keys [
Expand All @@ -142,8 +141,7 @@ defmodule Bitcoinex.ExtendedKey do
:parent_fingerprint,
:child_num,
:chaincode,
:key,
:checksum
:key
]

defstruct [
Expand All @@ -152,23 +150,55 @@ defmodule Bitcoinex.ExtendedKey do
:parent_fingerprint,
:child_num,
:chaincode,
:key,
:checksum
:key
]

# Single Sig
# xpub
@xpub_pfx <<0x04, 0x88, 0xB2, 0x1E>>
# xprv
@xprv_pfx <<0x04, 0x88, 0xAD, 0xE4>>
# tpub
@tpub_pfx <<0x04, 0x35, 0x87, 0xCF>>
# tprv
@tprv_pfx <<0x04, 0x35, 0x83, 0x94>>

# ypub
@ypub_pfx <<0x04, 0x9D, 0x7C, 0xB2>>
# yprv
@yprv_pfx <<0x04, 0x9D, 0x78, 0x78>>
# upub
@upub_pfx <<0x04, 0x4A, 0x52, 0x62>>
# uprv
@uprv_pfx <<0x04, 0x4A, 0x4E, 0x28>>
# zpub
@zpub_pfx <<0x04, 0xB2, 0x47, 0x46>>
# zprv
@zprv_pfx <<0x04, 0xB2, 0x43, 0x0C>>
# vpub
@vpub_pfx <<0x04, 0x5F, 0x1C, 0xF6>>
# vprv
@vprv_pfx <<0x04, 0x5F, 0x18, 0xBC>>
# Multisig (no BIP or derivation path, from SLIP-132)
# @y_pub_pfx <<0x02,0x95,0xb4,0x3f>> #Ypub
# @y_prv_pfx <<0x02,0x95,0xb0,0x05>> #Yprv
# @z_pub_pfx <<0x02,0xaa,0x7e,0xd3>> #Zpub
# @z_prv_pfx <<0x02,0xaa,0x7a,0x99>> #Zprv
@prv_prefixes [
@xprv_pfx,
@tprv_pfx
@tprv_pfx,
@yprv_pfx,
@uprv_pfx,
@zprv_pfx,
@vprv_pfx
]

@pub_prefixes [
@xpub_pfx,
@tpub_pfx
@tpub_pfx,
@ypub_pfx,
@upub_pfx,
@zpub_pfx,
@vpub_pfx
]

@all_prefixes @prv_prefixes ++ @pub_prefixes
Expand All @@ -179,34 +209,96 @@ defmodule Bitcoinex.ExtendedKey do
:xprv -> @xprv_pfx
:tpub -> @tpub_pfx
:tprv -> @tprv_pfx
:ypub -> @ypub_pfx
:yprv -> @yprv_pfx
:upub -> @upub_pfx
:uprv -> @uprv_pfx
:zpub -> @zpub_pfx
:zprv -> @zprv_pfx
:vpub -> @vpub_pfx
:vprv -> @vprv_pfx
end
end

defp bip44 do
[
@xpub_pfx,
@xprv_pfx,
@tpub_pfx,
@tprv_pfx
]
end

defp bip49 do
[
@ypub_pfx,
@yprv_pfx,
@upub_pfx,
@uprv_pfx
]
end

defp bip84 do
[
@zpub_pfx,
@zprv_pfx,
@vpub_pfx,
@vprv_pfx
]
end

defp prv_to_pub_prefix(prv_pfx) do
case prv_pfx do
@xprv_pfx -> @xpub_pfx
@tprv_pfx -> @tpub_pfx
@yprv_pfx -> @ypub_pfx
@uprv_pfx -> @upub_pfx
@zprv_pfx -> @zpub_pfx
@vprv_pfx -> @vpub_pfx
end
end

defp mainnet_prefixes do
[
@xpub_pfx,
@xprv_pfx
@xprv_pfx,
@ypub_pfx,
@yprv_pfx,
@zpub_pfx,
@zprv_pfx
]
end

@spec network_from_prefix(binary) :: atom
defp network_from_prefix(prefix) do
def network_from_prefix(prefix) do
if prefix in mainnet_prefixes(), do: :mainnet, else: :testnet
end

@doc """
network_from_extended_key returns :testnet or :mainnet
depending on the network prefix of the key.
"""
@spec network_from_extended_key(t()) :: atom
def network_from_extended_key(%__MODULE__{prefix: prefix}), do: network_from_prefix(prefix)
@spec script_type_from_prefix(binary) :: atom
def script_type_from_prefix(prefix) do
cond do
prefix in bip44() -> :p2pkh
# p2sh or p2sh_p2wpkh?
prefix in bip49() -> :p2sh_p2wpkh
prefix in bip84() -> :p2wpkh
end
end

@spec switch_prefix(t(), atom) :: t() | {:error, String.t()}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's more consistent to wrap succes type in :ok tag like {:ok, t()} if error tuple is another possible return value

def switch_prefix(xkey = %__MODULE__{prefix: pfx}, new_pfx) do
new_pfx_bin = pfx_atom_to_bin(new_pfx)

cond do
new_pfx_bin in @prv_prefixes and pfx in @prv_prefixes ->
%__MODULE__{xkey | prefix: new_pfx_bin}

new_pfx_bin in @pub_prefixes and pfx in @pub_prefixes ->
%__MODULE__{xkey | prefix: new_pfx_bin}

true ->
{:error, "switching between public and private prefixes will result in a useless key"}
end
end

# GETTERS

Expand Down Expand Up @@ -242,18 +334,18 @@ defmodule Bitcoinex.ExtendedKey do
@spec get_child_num(t()) :: binary
def get_child_num(%__MODULE__{child_num: child_num}), do: child_num

# PARSE & SERIALIZE
# PARSE & SERIALIZE

@doc """
parse_extended_key takes binary or string representation
parse_extended_key takes binary or string representation
of an extended key and parses it to an extended key object
"""
@spec parse_extended_key(binary) :: {:ok, t()} | {:error, String.t()}
def parse_extended_key(
xkey =
<<prefix::binary-size(4), depth::binary-size(1), parent_fingerprint::binary-size(4),
child_num::binary-size(4), chaincode::binary-size(32), key::binary-size(33),
checksum::binary-size(4)>>
_checksum::binary-size(4)>>
) do
cond do
prefix not in @all_prefixes ->
Expand All @@ -276,8 +368,7 @@ defmodule Bitcoinex.ExtendedKey do
parent_fingerprint: parent_fingerprint,
child_num: child_num,
chaincode: chaincode,
key: key,
checksum: checksum
key: key
}}
end
end
Expand Down Expand Up @@ -324,7 +415,7 @@ defmodule Bitcoinex.ExtendedKey do
end

@doc """
seed_to_master_private_key transforms a bip32 seed
seed_to_master_private_key transforms a bip32 seed
into a master extended private key
"""
@spec seed_to_master_private_key(binary, atom) :: {:ok, t()} | {:error, String.t()}
Expand Down Expand Up @@ -393,7 +484,7 @@ defmodule Bitcoinex.ExtendedKey do
end

@doc """
to_public_key takes an extended key xkey and
to_public_key takes an extended key xkey and
returns the public key.
"""
@spec to_public_key(t()) :: {:ok, Point.t()} | {:error, String.t()}
Expand All @@ -410,7 +501,7 @@ defmodule Bitcoinex.ExtendedKey do

@doc """
derive_child uses a public or private key xkey to
derive the public or private key at index idx.
derive the public or private key at index idx.
public key -> public child
private key -> private child
"""
Expand Down Expand Up @@ -482,8 +573,8 @@ defmodule Bitcoinex.ExtendedKey do
end

@doc """
derive_private_child uses a private key xkey to
derive the private key at index idx
derive_private_child uses a private key xkey to
derive the private key at index idx
"""
@spec derive_private_child(t(), non_neg_integer()) :: {:ok, t()} | {:error, String.t()}
def derive_private_child(_, idx) when idx >>> 32 != 0, do: {:error, "idx must be in 0..2**32-1"}
Expand Down Expand Up @@ -573,21 +664,21 @@ defmodule Bitcoinex.ExtendedKey do
end

@doc """
derive_extended_key uses an extended xkey and a derivation
derive_extended_key uses an extended xkey and a derivation
path to derive the extended key at that path
"""
@spec derive_extended_key(t() | binary, DerivationPath.t()) :: {:ok, t()} | {:error, String.t()}
def derive_extended_key(xkey = %__MODULE__{}, %DerivationPath{child_nums: path}),
do: rderive_extended_key(xkey, path)
do: derive_extended_key(xkey, path)

def derive_extended_key(seed, %DerivationPath{child_nums: path}) do
{:ok, xkey} = seed_to_master_private_key(seed)
rderive_extended_key(xkey, path)
derive_extended_key(xkey, path)
end

defp rderive_extended_key(xkey = %__MODULE__{}, []), do: {:ok, xkey}
def derive_extended_key(xkey = %__MODULE__{}, []), do: {:ok, xkey}

defp rderive_extended_key(xkey = %__MODULE__{}, [p | rest]) do
def derive_extended_key(xkey = %__MODULE__{}, [p | rest]) do
try do
case p do
# if asterisk (:any) is in path, return the immediate parent xkey
Expand All @@ -597,7 +688,7 @@ defmodule Bitcoinex.ExtendedKey do
# otherwise it is an integer, so derive child at that index.
_ ->
case derive_child_key(xkey, p) do
{:ok, child_key} -> rderive_extended_key(child_key, rest)
{:ok, child_key} -> derive_extended_key(child_key, rest)
{:error, msg} -> {:error, msg}
end
end
Expand Down
Loading