@@ -147,25 +147,14 @@ pub async fn mine_a_block(endpoint: BitcoindHttpEndpoint) -> anyhow::Result<()>
147
147
Ok ( ( ) )
148
148
}
149
149
150
- pub struct DerivationPath {
151
- path : Vec < ChildNumber > ,
152
- }
150
+ #[ derive( Debug , Clone ) ]
151
+ pub struct DerivationPath ( Vec < ChildNumber > ) ;
153
152
154
153
impl Display for DerivationPath {
155
154
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
156
- for i in 0 ..self . path . len ( ) {
157
- let elem = self . path . get ( i) . unwrap ( ) ;
158
-
159
- let separator = if i == self . path . len ( ) - 1 { "" } else { "/" } ;
160
-
161
- match elem {
162
- ChildNumber :: Normal { index } => {
163
- write ! ( f, "{:?}{:0}" , index, separator) ?;
164
- }
165
- ChildNumber :: Hardened { index } => {
166
- write ! ( f, "{:?}h{:0}" , index, separator) ?;
167
- }
168
- }
155
+ for i in & self . 0 {
156
+ write ! ( f, "/" ) ?;
157
+ fmt:: Display :: fmt ( i, f) ?;
169
158
}
170
159
171
160
Ok ( ( ) )
@@ -174,22 +163,21 @@ impl Display for DerivationPath {
174
163
175
164
impl DerivationPath {
176
165
pub fn bip44_bitcoin_testnet ( ) -> anyhow:: Result < Self > {
177
- Ok ( Self {
178
- path : vec ! [
179
- ChildNumber :: from_hardened_idx( 44 ) ?,
180
- ChildNumber :: from_hardened_idx( 1 ) ?,
181
- ChildNumber :: from_hardened_idx( 0 ) ?,
182
- ChildNumber :: from_normal_idx( 0 ) ?,
183
- ChildNumber :: from_normal_idx( 0 ) ?,
184
- ] ,
185
- } )
166
+ Ok ( Self ( vec ! [
167
+ ChildNumber :: from_hardened_idx( 44 ) ?,
168
+ ChildNumber :: from_hardened_idx( 1 ) ?,
169
+ ChildNumber :: from_hardened_idx( 0 ) ?,
170
+ ChildNumber :: from_normal_idx( 0 ) ?,
171
+ ChildNumber :: from_normal_idx( 0 ) ?,
172
+ ] ) )
186
173
}
187
174
}
188
175
189
- #[ derive( Clone ) ]
176
+ #[ derive( Debug , Clone ) ]
190
177
pub struct Account {
191
178
pub master : ExtendedPrivKey ,
192
179
first_account : rust_bitcoin:: util:: key:: PrivateKey ,
180
+ derivation_path : DerivationPath ,
193
181
}
194
182
195
183
impl Account {
@@ -206,13 +194,14 @@ impl Account {
206
194
207
195
// derive a private key from the master key
208
196
let priv_key = master
209
- . derive_priv ( & Secp256k1 :: new ( ) , & derivation_path. path )
197
+ . derive_priv ( & Secp256k1 :: new ( ) , & derivation_path. 0 )
210
198
. map ( |secret_key| secret_key. private_key ) ?;
211
199
212
200
// it is not great to store derived data in here but since the derivation can fail, it is better to fail early instead of later
213
201
Ok ( Self {
214
202
master,
215
203
first_account : priv_key,
204
+ derivation_path,
216
205
} )
217
206
}
218
207
@@ -224,6 +213,17 @@ impl Account {
224
213
}
225
214
}
226
215
216
+ impl Display for Account {
217
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
218
+ write ! ( f, "wpkh(" ) ?;
219
+ fmt:: Display :: fmt ( & self . master , f) ?;
220
+ fmt:: Display :: fmt ( & self . derivation_path , f) ?;
221
+ write ! ( f, ")" ) ?;
222
+
223
+ Ok ( ( ) )
224
+ }
225
+ }
226
+
227
227
#[ derive( Debug , serde:: Serialize ) ]
228
228
pub struct NewAddressRequest {
229
229
jsonrpc : String ,
@@ -386,7 +386,23 @@ mod tests {
386
386
let derivation_path = DerivationPath :: bip44_bitcoin_testnet ( ) . unwrap ( ) ;
387
387
388
388
let to_string = derivation_path. to_string ( ) ;
389
- assert_eq ! ( to_string, "44h/1h/0h/0/0" )
389
+ assert_eq ! ( to_string, "/44'/1'/0'/0/0" )
390
+ }
391
+
392
+ #[ test]
393
+ fn format_account ( ) {
394
+ let account = Account :: new_random ( ) . unwrap ( ) ;
395
+ let master = account. master ;
396
+
397
+ let to_string = account. to_string ( ) ;
398
+ assert_eq ! (
399
+ to_string,
400
+ format!(
401
+ "wpkh({}{})" ,
402
+ master,
403
+ DerivationPath :: bip44_bitcoin_testnet( ) . unwrap( )
404
+ )
405
+ )
390
406
}
391
407
392
408
#[ test]
0 commit comments