@@ -9,29 +9,25 @@ import 'dart:convert';
9
9
class Bip32Type {
10
10
int public;
11
11
int private;
12
- Bip32Type ({this .public, this .private});
13
-
12
+ Bip32Type ({required this .public, required this .private});
14
13
}
14
+
15
15
class NetworkType {
16
16
int wif;
17
17
Bip32Type bip32;
18
- NetworkType ({this .wif, this .bip32});
18
+ NetworkType ({required this .wif, required this .bip32});
19
19
}
20
20
21
21
final _BITCOIN = new NetworkType (
22
- wif: 0x80 ,
23
- bip32: new Bip32Type (
24
- public: 0x0488b21e ,
25
- private: 0x0488ade4
26
- )
27
- );
22
+ wif: 0x80 , bip32: new Bip32Type (public: 0x0488b21e , private: 0x0488ade4 ));
28
23
const HIGHEST_BIT = 0x80000000 ;
29
24
const UINT31_MAX = 2147483647 ; // 2^31 - 1
30
25
const UINT32_MAX = 4294967295 ; // 2^32 - 1
26
+
31
27
/// Checks if you are awesome. Spoiler: you are.
32
28
class BIP32 {
33
- Uint8List _d;
34
- Uint8List _Q ;
29
+ Uint8List ? _d;
30
+ Uint8List ? _Q ;
35
31
Uint8List chainCode;
36
32
int depth = 0 ;
37
33
int index = 0 ;
@@ -40,11 +36,11 @@ class BIP32 {
40
36
BIP32 (this ._d, this ._Q , this .chainCode, this .network);
41
37
42
38
Uint8List get publicKey {
43
- if (_Q == null ) _Q = ecc.pointFromScalar (_d, true );
44
- return _Q ;
39
+ if (_Q == null ) _Q = ecc.pointFromScalar (_d! , true )! ;
40
+ return _Q ! ;
45
41
}
46
42
47
- Uint8List get privateKey => _d;
43
+ Uint8List ? get privateKey => _d;
48
44
Uint8List get identifier => hash160 (publicKey);
49
45
Uint8List get fingerprint => identifier.sublist (0 , 4 );
50
46
@@ -53,15 +49,17 @@ class BIP32 {
53
49
}
54
50
55
51
BIP32 neutered () {
56
- final neutered = BIP32 .fromPublicKey (this .publicKey, this .chainCode, this .network);
52
+ final neutered =
53
+ BIP32 .fromPublicKey (this .publicKey, this .chainCode, this .network);
57
54
neutered.depth = this .depth;
58
55
neutered.index = this .index;
59
56
neutered.parentFingerprint = this .parentFingerprint;
60
57
return neutered;
61
58
}
62
59
63
60
String toBase58 () {
64
- final version = (! isNeutered ()) ? network.bip32.private : network.bip32.public;
61
+ final version =
62
+ (! isNeutered ()) ? network.bip32.private : network.bip32.public;
65
63
Uint8List buffer = new Uint8List (78 );
66
64
ByteData bytes = buffer.buffer.asByteData ();
67
65
bytes.setUint32 (0 , version);
@@ -71,7 +69,7 @@ class BIP32 {
71
69
buffer.setRange (13 , 45 , chainCode);
72
70
if (! isNeutered ()) {
73
71
bytes.setUint8 (45 , 0 );
74
- buffer.setRange (46 , 78 , privateKey);
72
+ buffer.setRange (46 , 78 , privateKey! );
75
73
} else {
76
74
buffer.setRange (45 , 78 , publicKey);
77
75
}
@@ -83,22 +81,20 @@ class BIP32 {
83
81
throw new ArgumentError ("Missing private key" );
84
82
}
85
83
return wif.encode (new wif.WIF (
86
- version: network.wif,
87
- privateKey: privateKey,
88
- compressed: true
89
- ));
84
+ version: network.wif, privateKey: privateKey! , compressed: true ));
90
85
}
91
86
92
87
BIP32 derive (int index) {
93
- if (index > UINT32_MAX || index < 0 ) throw new ArgumentError ("Expected UInt32" );
88
+ if (index > UINT32_MAX || index < 0 )
89
+ throw new ArgumentError ("Expected UInt32" );
94
90
final isHardened = index >= HIGHEST_BIT ;
95
91
Uint8List data = new Uint8List (37 );
96
92
if (isHardened) {
97
93
if (isNeutered ()) {
98
94
throw new ArgumentError ("Missing private key for hardened child key" );
99
95
}
100
96
data[0 ] = 0x00 ;
101
- data.setRange (1 , 33 , privateKey);
97
+ data.setRange (1 , 33 , privateKey! );
102
98
data.buffer.asByteData ().setUint32 (33 , index);
103
99
} else {
104
100
data.setRange (0 , 33 , publicKey);
@@ -112,7 +108,7 @@ class BIP32 {
112
108
}
113
109
BIP32 hd;
114
110
if (! isNeutered ()) {
115
- final ki = ecc.privateAdd (privateKey, IL );
111
+ final ki = ecc.privateAdd (privateKey! , IL );
116
112
if (ki == null ) return derive (index + 1 );
117
113
hd = BIP32 .fromPrivateKey (ki, IR , network);
118
114
} else {
@@ -127,7 +123,8 @@ class BIP32 {
127
123
}
128
124
129
125
BIP32 deriveHardened (int index) {
130
- if (index > UINT31_MAX || index < 0 ) throw new ArgumentError ("Expected UInt31" );
126
+ if (index > UINT31_MAX || index < 0 )
127
+ throw new ArgumentError ("Expected UInt31" );
131
128
return this .derive (index + HIGHEST_BIT );
132
129
}
133
130
@@ -136,10 +133,11 @@ class BIP32 {
136
133
if (! regex.hasMatch (path)) throw new ArgumentError ("Expected BIP32 Path" );
137
134
List <String > splitPath = path.split ("/" );
138
135
if (splitPath[0 ] == "m" ) {
139
- if (parentFingerprint != 0 ) throw new ArgumentError ("Expected master, got child" );
136
+ if (parentFingerprint != 0 )
137
+ throw new ArgumentError ("Expected master, got child" );
140
138
splitPath = splitPath.sublist (1 );
141
139
}
142
- return splitPath.fold (this , (BIP32 prevHd,String indexStr) {
140
+ return splitPath.fold (this , (BIP32 prevHd, String indexStr) {
143
141
int index;
144
142
if (indexStr.substring (indexStr.length - 1 ) == "'" ) {
145
143
index = int .parse (indexStr.substring (0 , indexStr.length - 1 ));
@@ -152,14 +150,14 @@ class BIP32 {
152
150
}
153
151
154
152
sign (Uint8List hash) {
155
- return ecc.sign (hash, privateKey);
153
+ return ecc.sign (hash, privateKey! );
156
154
}
157
155
158
156
verify (Uint8List hash, Uint8List signature) {
159
157
return ecc.verify (hash, publicKey, signature);
160
158
}
161
159
162
- factory BIP32 .fromBase58 (String string, [NetworkType nw]) {
160
+ factory BIP32 .fromBase58 (String string, [NetworkType ? nw]) {
163
161
Uint8List buffer = bs58check.decode (string);
164
162
if (buffer.length != 78 ) throw new ArgumentError ("Invalid buffer length" );
165
163
NetworkType network = nw ?? _BITCOIN ;
@@ -175,7 +173,8 @@ class BIP32 {
175
173
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
176
174
var parentFingerprint = bytes.getUint32 (5 );
177
175
if (depth == 0 ) {
178
- if (parentFingerprint != 0x00000000 ) throw new ArgumentError ("Invalid parent fingerprint" );
176
+ if (parentFingerprint != 0x00000000 )
177
+ throw new ArgumentError ("Invalid parent fingerprint" );
179
178
}
180
179
181
180
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized.
@@ -189,7 +188,8 @@ class BIP32 {
189
188
190
189
// 33 bytes: private key data (0x00 + k)
191
190
if (version == network.bip32.private) {
192
- if (bytes.getUint8 (45 ) != 0x00 ) throw new ArgumentError ("Invalid private key" );
191
+ if (bytes.getUint8 (45 ) != 0x00 )
192
+ throw new ArgumentError ("Invalid private key" );
193
193
Uint8List k = buffer.sublist (46 , 78 );
194
194
hd = BIP32 .fromPrivateKey (k, chainCode, network);
195
195
} else {
@@ -203,30 +203,35 @@ class BIP32 {
203
203
return hd;
204
204
}
205
205
206
- factory BIP32 .fromPublicKey (Uint8List publicKey, Uint8List chainCode, [NetworkType nw]) {
206
+ factory BIP32 .fromPublicKey (Uint8List publicKey, Uint8List chainCode,
207
+ [NetworkType ? nw]) {
207
208
NetworkType network = nw ?? _BITCOIN ;
208
209
if (! ecc.isPoint (publicKey)) {
209
210
throw new ArgumentError ("Point is not on the curve" );
210
211
}
211
212
return new BIP32 (null , publicKey, chainCode, network);
212
213
}
213
214
214
- factory BIP32 .fromPrivateKey (Uint8List privateKey, Uint8List chainCode, [NetworkType nw]) {
215
+ factory BIP32 .fromPrivateKey (Uint8List privateKey, Uint8List chainCode,
216
+ [NetworkType ? nw]) {
215
217
NetworkType network = nw ?? _BITCOIN ;
216
- if (privateKey.length != 32 ) throw new ArgumentError ("Expected property privateKey of type Buffer(Length: 32)" );
217
- if (! ecc.isPrivate (privateKey)) throw new ArgumentError ("Private key not in range [1, n]" );
218
+ if (privateKey.length != 32 )
219
+ throw new ArgumentError (
220
+ "Expected property privateKey of type Buffer(Length: 32)" );
221
+ if (! ecc.isPrivate (privateKey))
222
+ throw new ArgumentError ("Private key not in range [1, n]" );
218
223
return new BIP32 (privateKey, null , chainCode, network);
219
224
}
220
225
221
- factory BIP32 .fromSeed (Uint8List seed, [NetworkType nw]) {
226
+ factory BIP32 .fromSeed (Uint8List seed, [NetworkType ? nw]) {
222
227
if (seed.length < 16 ) {
223
228
throw new ArgumentError ("Seed should be at least 128 bits" );
224
229
}
225
230
if (seed.length > 64 ) {
226
231
throw new ArgumentError ("Seed should be at most 512 bits" );
227
232
}
228
233
NetworkType network = nw ?? _BITCOIN ;
229
- final I = hmacSHA512 (utf8.encode ("Bitcoin seed" ), seed);
234
+ final I = hmacSHA512 (utf8.encode ("Bitcoin seed" ) as Uint8List , seed);
230
235
final IL = I .sublist (0 , 32 );
231
236
final IR = I .sublist (32 );
232
237
return BIP32 .fromPrivateKey (IL , IR , network);
0 commit comments