@@ -16,17 +16,45 @@ class Address {
16
16
17
17
static const _CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l' ;
18
18
static const _CHARSET_INVERSE_INDEX = {
19
- 'q' : 0 , 'p' : 1 , 'z' : 2 , 'r' : 3 , 'y' : 4 , '9' : 5 , 'x' : 6 , '8' : 7 ,
20
- 'g' : 8 , 'f' : 9 , '2' : 10 , 't' : 11 , 'v' : 12 , 'd' : 13 , 'w' : 14 , '0' : 15 ,
21
- 's' : 16 , '3' : 17 , 'j' : 18 , 'n' : 19 , '5' : 20 , '4' : 21 , 'k' : 22 , 'h' : 23 ,
22
- 'c' : 24 , 'e' : 25 , '6' : 26 , 'm' : 27 , 'u' : 28 , 'a' : 29 , '7' : 30 , 'l' : 31 ,
19
+ 'q' : 0 ,
20
+ 'p' : 1 ,
21
+ 'z' : 2 ,
22
+ 'r' : 3 ,
23
+ 'y' : 4 ,
24
+ '9' : 5 ,
25
+ 'x' : 6 ,
26
+ '8' : 7 ,
27
+ 'g' : 8 ,
28
+ 'f' : 9 ,
29
+ '2' : 10 ,
30
+ 't' : 11 ,
31
+ 'v' : 12 ,
32
+ 'd' : 13 ,
33
+ 'w' : 14 ,
34
+ '0' : 15 ,
35
+ 's' : 16 ,
36
+ '3' : 17 ,
37
+ 'j' : 18 ,
38
+ 'n' : 19 ,
39
+ '5' : 20 ,
40
+ '4' : 21 ,
41
+ 'k' : 22 ,
42
+ 'h' : 23 ,
43
+ 'c' : 24 ,
44
+ 'e' : 25 ,
45
+ '6' : 26 ,
46
+ 'm' : 27 ,
47
+ 'u' : 28 ,
48
+ 'a' : 29 ,
49
+ '7' : 30 ,
50
+ 'l' : 31 ,
23
51
};
24
52
25
53
/// Returns information about the given Bitcoin Cash address.
26
54
///
27
55
/// See https://developer.bitcoin.com/bitbox/docs/util for details about returned format
28
56
static Future <Map <String , dynamic >> validateAddress (String address) async =>
29
- await RestApi .sendGetRequest ("util/validateAddress" , address);
57
+ await RestApi .sendGetRequest ("util/validateAddress" , address);
30
58
31
59
/// Returns details of the provided address or addresses
32
60
///
@@ -40,7 +68,7 @@ class Address {
40
68
/// See https://developer.bitcoin.com/bitbox/docs/address#details for details about returned format. However
41
69
/// note, that processing from array to map is done on the library side
42
70
static Future <dynamic > details (addresses, [returnAsMap = false ]) async =>
43
- await _sendRequest ("details" , addresses, returnAsMap);
71
+ await _sendRequest ("details" , addresses, returnAsMap);
44
72
45
73
/// Returns list of unconfirmed transactions
46
74
///
@@ -53,7 +81,8 @@ class Address {
53
81
///
54
82
/// See https://developer.bitcoin.com/bitbox/docs/address#unconfirmed for details about the returned format. However
55
83
/// note, that processing from array to map is done on the library side
56
- static Future <dynamic > getUnconfirmed (addresses, [returnAsMap = false ]) async {
84
+ static Future <dynamic > getUnconfirmed (addresses,
85
+ [returnAsMap = false ]) async {
57
86
final result = await _sendRequest ("unconfirmed" , addresses);
58
87
59
88
if (result is Map ) {
@@ -64,9 +93,11 @@ class Address {
64
93
65
94
result.forEach ((addressUtxoMap) {
66
95
if (returnAsMap) {
67
- returnMap[addressUtxoMap["cashAddr" ]] = Utxo .convertMapListToUtxos (addressUtxoMap["utxos" ]);
96
+ returnMap[addressUtxoMap["cashAddr" ]] =
97
+ Utxo .convertMapListToUtxos (addressUtxoMap["utxos" ]);
68
98
} else {
69
- addressUtxoMap["utxos" ] = Utxo .convertMapListToUtxos (addressUtxoMap["utxos" ]);
99
+ addressUtxoMap["utxos" ] =
100
+ Utxo .convertMapListToUtxos (addressUtxoMap["utxos" ]);
70
101
returnList.add (addressUtxoMap);
71
102
}
72
103
});
@@ -95,9 +126,11 @@ class Address {
95
126
96
127
result.forEach ((addressUtxoMap) {
97
128
if (returnAsMap) {
98
- returnMap[addressUtxoMap["cashAddress" ]] = Utxo .convertMapListToUtxos (addressUtxoMap["utxos" ]);
129
+ returnMap[addressUtxoMap["cashAddress" ]] =
130
+ Utxo .convertMapListToUtxos (addressUtxoMap["utxos" ]);
99
131
} else {
100
- addressUtxoMap["utxos" ] = Utxo .convertMapListToUtxos (addressUtxoMap["utxos" ]);
132
+ addressUtxoMap["utxos" ] =
133
+ Utxo .convertMapListToUtxos (addressUtxoMap["utxos" ]);
101
134
returnList.add (addressUtxoMap);
102
135
}
103
136
});
@@ -109,15 +142,16 @@ class Address {
109
142
}
110
143
111
144
/// Converts legacy address to cash address
112
- static String toCashAddress (String legacyAddress, [bool includePrefix = true ]) {
145
+ static String toCashAddress (String legacyAddress,
146
+ [bool includePrefix = true ]) {
113
147
final decoded = Address ._decodeLegacyAddress (legacyAddress);
114
148
String prefix = "" ;
115
149
if (includePrefix) {
116
150
switch (decoded["version" ]) {
117
- case Network .bchPublic :
151
+ case Network .bchPublic:
118
152
prefix = "bitcoincash" ;
119
153
break ;
120
- case Network .bchTestnetPublic :
154
+ case Network .bchTestnetPublic:
121
155
prefix = "bchtest" ;
122
156
break ;
123
157
default :
@@ -172,22 +206,25 @@ class Address {
172
206
static _encode (String prefix, String type, Uint8List hash) {
173
207
final prefixData = _prefixToUint5List (prefix) + Uint8List (1 );
174
208
final versionByte = _getHashSizeBits (hash);
175
- final payloadData = _convertBits (Uint8List .fromList ([versionByte] + hash), 8 , 5 );
209
+ final payloadData =
210
+ _convertBits (Uint8List .fromList ([versionByte] + hash), 8 , 5 );
176
211
final checksumData = prefixData + payloadData + Uint8List (8 );
177
212
final payload = payloadData + _checksumToUint5Array (_polymod (checksumData));
178
213
return "$prefix :" + _base32Encode (payload);
179
214
}
180
215
181
216
/// Helper method for sending generic requests to Bitbox API. Accepts [String] or [List] of Strings and optionally
182
217
/// converts the List returned by Bitbox into [Map] , which uses cashAddress as a key
183
- static Future <dynamic > _sendRequest (String path, dynamic addresses, [bool returnAsMap = false ]) async {
218
+ static Future <dynamic > _sendRequest (String path, dynamic addresses,
219
+ [bool returnAsMap = false ]) async {
184
220
assert (addresses is String || addresses is List <String >);
185
221
186
222
if (addresses is String ) {
187
223
return await RestApi .sendGetRequest ("address/$path " , addresses) as Map ;
188
224
} else if (addresses is List <String >) {
189
- return await RestApi .sendPostRequest ("address/$path " , "addresses" , addresses,
190
- returnKey: returnAsMap ? "cashAddress" : null );
225
+ return await RestApi .sendPostRequest (
226
+ "address/$path " , "addresses" , addresses,
227
+ returnKey: returnAsMap ? "cashAddress" : null );
191
228
} else {
192
229
throw TypeError ();
193
230
}
@@ -274,7 +311,7 @@ class Address {
274
311
return < String , dynamic > {
275
312
"version" : buffer.first,
276
313
"hash" : buffer.sublist (1 ),
277
- "format" : formatLegacy,
314
+ "format" : formatLegacy,
278
315
};
279
316
}
280
317
@@ -316,7 +353,8 @@ class Address {
316
353
continue ;
317
354
}
318
355
319
- final payloadData = _fromUint5Array (payload.sublist (0 , payload.length - 8 ));
356
+ final payloadData =
357
+ _fromUint5Array (payload.sublist (0 , payload.length - 8 ));
320
358
final hash = payloadData.sublist (1 );
321
359
322
360
if (_getHashSize (payloadData[0 ]) != hash.length * 8 ) {
@@ -327,9 +365,9 @@ class Address {
327
365
// If the loop got all the way here, it means validations went through and the address was decoded.
328
366
// Return the decoded data
329
367
return < String , dynamic > {
330
- "prefix" : prefixes[i],
331
- "hash" : hash,
332
- "format" : formatCashAddr
368
+ "prefix" : prefixes[i],
369
+ "hash" : hash,
370
+ "format" : formatCashAddr
333
371
};
334
372
}
335
373
@@ -357,8 +395,11 @@ class Address {
357
395
358
396
/// Converts a list of integers made up of 'from' bits into an array of integers made up of 'to' bits.
359
397
/// The output array is zero-padded if necessary, unless strict mode is true.
360
- static Uint8List _convertBits (List data, int from, int to, [bool strictMode = false ]) {
361
- final length = strictMode ? (data.length * from / to).floor () : (data.length * from / to).ceil ();
398
+ static Uint8List _convertBits (List data, int from, int to,
399
+ [bool strictMode = false ]) {
400
+ final length = strictMode
401
+ ? (data.length * from / to).floor ()
402
+ : (data.length * from / to).ceil ();
362
403
int mask = (1 << to) - 1 ;
363
404
var result = Uint8List (length);
364
405
int index = 0 ;
@@ -382,7 +423,8 @@ class Address {
382
423
}
383
424
} else {
384
425
if (bits < from && ((accumulator << (to - bits)) & mask).toInt () != 0 ) {
385
- throw FormatException ("Input cannot be converted to $to bits without padding, but strict mode was used." );
426
+ throw FormatException (
427
+ "Input cannot be converted to $to bits without padding, but strict mode was used." );
386
428
}
387
429
}
388
430
return result;
@@ -391,7 +433,13 @@ class Address {
391
433
/// Computes a checksum from the given input data as specified for the CashAddr format:
392
434
// https://github.com/Bitcoin-UAHF/spec/blob/master/cashaddr.md.
393
435
static int _polymod (List data) {
394
- const GENERATOR = [0x98f2bc8e61 , 0x79b76d99e2 , 0xf33e5fb3c4 , 0xae2eabe2a8 , 0x1e4f43e470 ];
436
+ const GENERATOR = [
437
+ 0x98f2bc8e61 ,
438
+ 0x79b76d99e2 ,
439
+ 0xf33e5fb3c4 ,
440
+ 0xae2eabe2a8 ,
441
+ 0x1e4f43e470
442
+ ];
395
443
396
444
int checksum = 1 ;
397
445
@@ -414,7 +462,8 @@ class Address {
414
462
final data = Uint8List (string.length);
415
463
for (int i = 0 ; i < string.length; i++ ) {
416
464
final value = string[i];
417
- if (! _CHARSET_INVERSE_INDEX .containsKey (value)) throw FormatException ("Invalid character '$value '" );
465
+ if (! _CHARSET_INVERSE_INDEX .containsKey (value))
466
+ throw FormatException ("Invalid character '$value '" );
418
467
data[i] = _CHARSET_INVERSE_INDEX [string[i]];
419
468
}
420
469
@@ -452,16 +501,17 @@ class Utxo {
452
501
final int height;
453
502
final int confirmations;
454
503
455
- Utxo (this .txid, this .vout, this .amount, this .satoshis, this .height, this .confirmations);
504
+ Utxo (this .txid, this .vout, this .amount, this .satoshis, this .height,
505
+ this .confirmations);
456
506
457
507
/// Create [Utxo] instance from utxo [Map]
458
- Utxo .fromMap (Map <String , dynamic > utxoMap) :
459
- this .txid = utxoMap['txid' ],
460
- this .vout = utxoMap['vout' ],
461
- this .amount = utxoMap['amount' ],
462
- this .satoshis = utxoMap['satoshis' ],
463
- this .height = utxoMap.containsKey ('height' ) ? utxoMap['height' ] : null ,
464
- this .confirmations = utxoMap['confirmations' ];
508
+ Utxo .fromMap (Map <String , dynamic > utxoMap)
509
+ : this .txid = utxoMap['txid' ],
510
+ this .vout = utxoMap['vout' ],
511
+ this .amount = utxoMap['amount' ],
512
+ this .satoshis = utxoMap['satoshis' ],
513
+ this .height = utxoMap.containsKey ('height' ) ? utxoMap['height' ] : null ,
514
+ this .confirmations = utxoMap['confirmations' ];
465
515
466
516
/// Converts List of utxo maps into a list of [Utxo] objects
467
517
static List <Utxo > convertMapListToUtxos (List utxoMapList) {
@@ -475,11 +525,11 @@ class Utxo {
475
525
476
526
@override
477
527
String toString () => jsonEncode ({
478
- "txid" : txid,
479
- "vout" : vout,
480
- "amount" : amount,
481
- "satoshis" : satoshis,
482
- "height" : height,
483
- "confirmations" : confirmations
484
- });
485
- }
528
+ "txid" : txid,
529
+ "vout" : vout,
530
+ "amount" : amount,
531
+ "satoshis" : satoshis,
532
+ "height" : height,
533
+ "confirmations" : confirmations
534
+ });
535
+ }
0 commit comments