Skip to content

Commit 9986dc3

Browse files
committed
Add stricter analysis options and fix problems
1 parent 73b6c57 commit 9986dc3

40 files changed

+92
-76
lines changed

coinlib/analysis_options.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
include: package:lints/recommended.yaml
22

3+
analyzer:
4+
language:
5+
strict-casts: true
6+
strict-inference: true
7+
strict-raw-types: true
8+
39
# Lint rules and documentation, see http://dart-lang.github.io/linter/lints
410
linter:
511
rules:
@@ -10,3 +16,4 @@ linter:
1016
- unrelated_type_equality_checks
1117
- valid_regexps
1218
- require_trailing_commas
19+
- comment_references

coinlib/lib/src/common/bytes.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ Uint8List copyCheckBytes(
1616
Uint8List bytes, int length, { String name = "Bytes", }
1717
) => Uint8List.fromList(checkBytes(bytes, length, name: name));
1818

19-
/// Determines if two objects are equal Uint8List data
20-
bool bytesEqual(Object? a, Object? b)
21-
=> (a is Uint8List) && (b is Uint8List) && ListEquality().equals(a, b);
19+
/// Determines if two [Uint8List] lists are equal
20+
bool bytesEqual(Uint8List a, Uint8List b) => ListEquality<int>().equals(a, b);
2221

2322
/// Compares two Uint8List bytes from the left-most to right-most byte. If all
2423
/// bytes are the same apart from one list being longer, the shortest list comes

coinlib/lib/src/common/checks.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11

2-
_checkInt(int i, int min, int max, String type, String name) {
2+
void _checkInt(int i, int min, int max, String type, String name) {
33
if (i < min || i > max) {
44
throw ArgumentError.value(i, name, "must be a $type");
55
}
66
}
77

8-
checkUint8(int i, [String name = "i"])
8+
void checkUint8(int i, [String name = "i"])
99
=> _checkInt(i, 0, 0xff, "uint8", name);
1010

11-
checkUint16(int i, [String name = "i"])
11+
void checkUint16(int i, [String name = "i"])
1212
=> _checkInt(i, 0, 0xffff, "uint16", name);
1313

14-
checkUint32(int i, [String name = "i"])
14+
void checkUint32(int i, [String name = "i"])
1515
=> _checkInt(i, 0, 0xffffffff, "uint32", name);
1616

17-
checkInt32(int i, [String name = "i"])
17+
void checkInt32(int i, [String name = "i"])
1818
=> _checkInt(i, -0x80000000, 0x7fffffff, "int32", name);
1919

2020
final BigInt maxUint64 = (BigInt.from(1) << 64) - BigInt.one;
2121

22-
checkUint64(BigInt i, [String name = "i"]) {
22+
void checkUint64(BigInt i, [String name = "i"]) {
2323
if (i.isNegative || i > maxUint64) {
2424
throw ArgumentError.value(i, name, "must be a uint64");
2525
}

coinlib/lib/src/crypto/ec_public_key.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import 'dart:typed_data';
22
import 'package:coinlib/src/secp256k1/secp256k1.dart';
33
import 'package:coinlib/src/common/bytes.dart';
44
import 'package:coinlib/src/common/hex.dart';
5-
import 'package:collection/collection.dart';
65

76
class InvalidPublicKey implements Exception {}
87

@@ -70,7 +69,7 @@ class ECPublicKey {
7069

7170
@override
7271
bool operator ==(Object other)
73-
=> (other is ECPublicKey) && ListEquality().equals(_data, other._data);
72+
=> (other is ECPublicKey) && bytesEqual(_data, other._data);
7473

7574
@override
7675
int get hashCode => _data[1] | _data[2] << 8 | _data[3] << 16 | _data[4] << 24;

coinlib/lib/src/crypto/ecdsa_signature.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class ECDSASignature {
4545
}
4646
}
4747

48-
/// Takes a BIP66 DER formatted [signature] as a HEX string.
48+
/// Takes a BIP66 DER formatted signature as a HEX string.
4949
/// See [ECDSASignature.fromDer].
5050
factory ECDSASignature.fromDerHex(String hex)
5151
=> ECDSASignature.fromDer(hexToBytes(hex));

coinlib/lib/src/crypto/message_signature.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class MagicHash with Writable {
1414
final String prefix;
1515
MagicHash(this.message, this.prefix);
1616

17-
static _writeUtf8(Writer writer, String msg)
17+
static void _writeUtf8(Writer writer, String msg)
1818
=> writer.writeVarSlice(utf8.encode(msg));
1919

2020
@override
@@ -33,7 +33,7 @@ class MessageSignature {
3333

3434
final ECDSARecoverableSignature signature;
3535

36-
static magicHash(String message, String prefix)
36+
static Uint8List magicHash(String message, String prefix)
3737
=> MagicHash(message, prefix).hash;
3838

3939
MessageSignature.fromBase64(String str)

coinlib/lib/src/crypto/nums_public_key.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import 'package:coinlib/src/crypto/random.dart';
44

55
/// A "nothing up my sleeve" [ECPublicKey] that is created from a point with no
66
/// known private key and tweaked with a scalar value named [rTweak]. The key is
7-
/// reproduceable from this scalar using [fromRTweak]. Any of these keys have no
8-
/// known associted private key. Sharing the [rTweak] allows others to verify
9-
/// this. These keys can be used as Taproot internal keys where no key-path
10-
/// spending is desired.
7+
/// reproduceable from this scalar using [fromRTweak()]. Any of
8+
/// these keys have no known associted private key. Sharing the [rTweak] allows
9+
/// others to verify this. These keys can be used as Taproot internal keys where
10+
/// no key-path spending is desired.
1111
class NUMSPublicKey extends ECPublicKey {
1212

1313
/// To prove that this point does not have an associated private key, the

coinlib/lib/src/scripts/operations.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import 'dart:typed_data';
2+
import 'package:coinlib/src/common/bytes.dart';
23
import 'package:coinlib/src/common/hex.dart';
34
import 'package:coinlib/src/common/serial.dart';
45
import 'package:coinlib/src/crypto/ec_public_key.dart';
56
import 'package:coinlib/src/tx/inputs/input_signature.dart';
6-
import 'package:collection/collection.dart';
77
import 'codes.dart';
88

99
class InvalidScriptAsm implements Exception {}
@@ -312,7 +312,7 @@ class ScriptPushData implements ScriptOp {
312312

313313
@override
314314
bool match(ScriptOp other)
315-
=> (other is ScriptPushData && ListEquality().equals(_data, other._data))
315+
=> (other is ScriptPushData && bytesEqual(_data, other._data))
316316
|| (other is ScriptPushDataMatcher && _data.length == other.size);
317317

318318
}

coinlib/lib/src/scripts/program.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ abstract class Program {
2020

2121
/// Takes a [script] and constructs a matching Program subclass if one exists,
2222
/// or a basic [RawProgram] if there is no match. The script should use
23-
/// minimal pushes. [decompile] can be used directly on compiled scripts or
24-
/// [fromAsm] can be used to match directly against ASM.
23+
/// minimal pushes. [Program.decompile] can be used directly on compiled
24+
/// scripts or [Program.fromAsm] can be used to match directly against ASM.
2525
factory Program.match(Script script) {
2626

2727
try {

coinlib/lib/src/scripts/programs/p2sh.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class P2SH implements Program {
1515
late final Uint8List _scriptHash;
1616

1717
/// Construct using an output script, not to be confused with the redeem
18-
/// script. For that use [fromRedeemScript].
18+
/// script. For that use [fromRedeemScript()].
1919
P2SH.fromScript(this.script) {
2020
if (!template.match(script)) throw NoProgramMatch();
2121
_scriptHash = (script[1] as ScriptPushData).data;

coinlib/lib/src/scripts/programs/p2wsh.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import 'package:coinlib/src/scripts/script.dart';
1111
class P2WSH extends P2Witness {
1212

1313
/// Construct using an output script, not to be confused with the witness
14-
/// script. For that use [fromWitnessScript].
14+
/// script. For that use [P2WSH.fromWitnessScript].
1515
P2WSH.fromScript(super.script) : super.fromScript() {
1616
if (data.length != 32 || version != 0) throw NoProgramMatch();
1717
}

coinlib/lib/src/secp256k1/heap_array_base.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ import 'dart:typed_data';
44
abstract class HeapArrayBase<Ptr> {
55
Ptr get ptr;
66
Uint8List get list;
7-
load(Uint8List data);
7+
void load(Uint8List data);
88
}

coinlib/lib/src/secp256k1/heap_array_wasm.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,6 @@ class HeapArrayWasmFactory {
4646

4747
HeapArrayWasmFactory(this.memory, this.malloc, this.free);
4848

49-
create(int size) => HeapArrayWasm(size, memory, malloc, free);
49+
HeapArrayWasm create(int size) => HeapArrayWasm(size, memory, malloc, free);
5050

5151
}

coinlib/lib/src/secp256k1/secp256k1_base.dart

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,16 @@ abstract class Secp256k1Base<
9090
) extSchnorrVerify;
9191

9292
// Heap arrays
93-
late HeapArrayBase key32Array; // Used for private keys and x-only public keys
94-
late HeapArrayBase scalarArray;
95-
late HeapArrayBase serializedPubKeyArray;
96-
late HeapArrayBase hashArray;
97-
late HeapArrayBase entropyArray;
98-
late HeapArrayBase serializedSigArray;
99-
late HeapArrayBase derSigArray;
93+
94+
// Used for private keys and x-only public keys
95+
late HeapArrayBase<HeapArrayPtr> key32Array;
96+
97+
late HeapArrayBase<HeapArrayPtr> scalarArray;
98+
late HeapArrayBase<HeapArrayPtr> serializedPubKeyArray;
99+
late HeapArrayBase<HeapArrayPtr> hashArray;
100+
late HeapArrayBase<HeapArrayPtr> entropyArray;
101+
late HeapArrayBase<HeapArrayPtr> serializedSigArray;
102+
late HeapArrayBase<HeapArrayPtr> derSigArray;
100103

101104
// Other pointers
102105
late CtxPtr ctxPtr;
@@ -194,7 +197,7 @@ abstract class Secp256k1Base<
194197
Future<void> internalLoad() async {}
195198

196199
bool _loaded = false;
197-
_requireLoad() {
200+
void _requireLoad() {
198201
if (!_loaded) throw Secp256k1Exception("load() not called");
199202
}
200203

@@ -311,7 +314,9 @@ abstract class Secp256k1Base<
311314
// Using null as it doesn't require passing an additional constant from
312315
// the web and io implementations.
313316
nullPtr,
314-
extraEntropy == null ? nullPtr : entropyArray.ptr,
317+
// The pointer is not actually null when entropy is provided but NullPtr
318+
// works for void pointers too
319+
extraEntropy == null ? nullPtr : entropyArray.ptr as NullPtr,
315320
) != 1
316321
) {
317322
throw Secp256k1Exception("Cannot sign message with private key");
@@ -441,7 +446,7 @@ abstract class Secp256k1Base<
441446
if (
442447
extSchnorrSign32(
443448
ctxPtr, serializedSigArray.ptr, hashArray.ptr, keyPairPtr,
444-
extraEntropy == null ? nullPtr : entropyArray.ptr,
449+
extraEntropy == null ? nullPtr as HeapArrayPtr : entropyArray.ptr,
445450
) != 1
446451
) {
447452
throw Secp256k1Exception("Cannot sign Schnorr signature");

coinlib/lib/src/secp256k1/secp256k1_web.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ class Secp256k1 extends Secp256k1Base<
3131
// Dummy WASI imports. No file descriptor support provided.
3232
importMap: {
3333
"wasi_snapshot_preview1" : {
34-
"fd_close": () => {},
35-
"fd_seek": () => {},
36-
"fd_write": () => {},
34+
"fd_close": () => Object(),
35+
"fd_seek": () => Object(),
36+
"fd_write": () => Object(),
3737
},
3838
},
3939
);

coinlib/lib/src/taproot.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:typed_data';
2+
import 'package:coinlib/src/common/bytes.dart';
23
import 'package:coinlib/src/common/serial.dart';
34
import 'package:coinlib/src/crypto/ec_private_key.dart';
45
import 'package:coinlib/src/crypto/ec_public_key.dart';
@@ -186,7 +187,7 @@ class TapLeaf with Writable implements TapNode {
186187
bool operator ==(Object other)
187188
=> (other is TapLeaf)
188189
&& version == other.version
189-
&& ListEquality().equals(script.compiled, other.script.compiled);
190+
&& bytesEqual(script.compiled, other.script.compiled);
190191

191192
@override
192193
int get hashCode => hash[0] | hash[1] << 8 | hash[2] << 16 | hash[3] << 24;

coinlib/lib/src/tx/inputs/input.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import 'p2sh_multisig_input.dart';
88
import 'raw_input.dart';
99
import 'witness_input.dart';
1010

11-
/// The base class for all inputs, providing the [match] factory constructor to
12-
/// determine the appropriate subclass from a [RawInput]
11+
/// The base class for all inputs, providing the [Input.match] factory
12+
/// constructor to determine the appropriate subclass from a [RawInput]
1313
abstract class Input with Writable {
1414

1515
static const sequenceFinal = 0xffffffff;

coinlib/lib/src/tx/inputs/input_signature.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:typed_data';
22
import 'package:coinlib/src/crypto/ecdsa_signature.dart';
33
import 'package:coinlib/src/crypto/schnorr_signature.dart';
44
import 'package:coinlib/src/tx/sighash/sighash_type.dart';
5+
import 'input.dart';
56

67
class InvalidInputSignature implements Exception {}
78

coinlib/lib/src/tx/inputs/legacy_input.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import 'package:coinlib/src/tx/sighash/sighash_type.dart';
66
import 'package:coinlib/src/tx/transaction.dart';
77
import 'input.dart';
88
import 'input_signature.dart';
9+
import 'p2pkh_input.dart';
10+
import 'p2sh_multisig_input.dart';
911
import 'raw_input.dart';
1012

1113
/// Inputs that are not witness inputs: [P2PKHInput] and [P2SHMultisigInput].
@@ -24,7 +26,7 @@ abstract class LegacyInput extends RawInput {
2426
required Transaction tx,
2527
required int inputN,
2628
required ECPrivateKey key,
27-
hashType = const SigHashType.all(),
29+
SigHashType hashType = const SigHashType.all(),
2830
});
2931

3032
/// Creates a signature for the input. Used by subclasses to implement
@@ -34,7 +36,7 @@ abstract class LegacyInput extends RawInput {
3436
required int inputN,
3537
required ECPrivateKey key,
3638
required Script scriptCode,
37-
hashType = const SigHashType.all(),
39+
SigHashType hashType = const SigHashType.all(),
3840
}) => ECDSAInputSignature(
3941
ECDSASignature.sign(
4042
key,

coinlib/lib/src/tx/inputs/legacy_witness_input.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ abstract class LegacyWitnessInput extends WitnessInput {
2727
required int inputN,
2828
required ECPrivateKey key,
2929
required BigInt value,
30-
hashType = const SigHashType.all(),
30+
SigHashType hashType = const SigHashType.all(),
3131
});
3232

3333
/// Creates a signature for the input. Used by subclasses to implement
@@ -38,7 +38,7 @@ abstract class LegacyWitnessInput extends WitnessInput {
3838
required ECPrivateKey key,
3939
required Script scriptCode,
4040
required BigInt value,
41-
hashType = const SigHashType.all(),
41+
SigHashType hashType = const SigHashType.all(),
4242
}) => ECDSAInputSignature(
4343
ECDSASignature.sign(
4444
key,

coinlib/lib/src/tx/inputs/p2sh_multisig_input.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:coinlib/src/crypto/ec_public_key.dart';
55
import 'package:coinlib/src/scripts/operations.dart';
66
import 'package:coinlib/src/scripts/program.dart';
77
import 'package:coinlib/src/scripts/programs/multisig.dart';
8+
import 'package:coinlib/src/scripts/programs/p2sh.dart';
89
import 'package:coinlib/src/scripts/script.dart';
910
import 'package:coinlib/src/tx/sighash/legacy_signature_hasher.dart';
1011
import 'package:coinlib/src/tx/sighash/sighash_type.dart';

coinlib/lib/src/tx/inputs/p2wpkh_input.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:typed_data';
22
import 'package:coinlib/src/crypto/ec_private_key.dart';
33
import 'package:coinlib/src/crypto/ec_public_key.dart';
4+
import 'package:coinlib/src/scripts/programs/p2wpkh.dart';
45
import 'package:coinlib/src/tx/sighash/sighash_type.dart';
56
import 'package:coinlib/src/tx/transaction.dart';
67
import 'input.dart';

coinlib/lib/src/tx/inputs/taproot_input.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ abstract class TaprootInput extends WitnessInput {
2727
required int inputN,
2828
required ECPrivateKey key,
2929
required List<Output> prevOuts,
30-
hashType = const SigHashType.all(),
30+
SigHashType hashType = const SigHashType.all(),
3131
}) => throw CannotSignInput("Unimplemented sign() for {this.runtimeType}");
3232

3333
/// Creates a signature for the input. Used by subclasses to implement
@@ -37,7 +37,7 @@ abstract class TaprootInput extends WitnessInput {
3737
required int inputN,
3838
required ECPrivateKey key,
3939
required List<Output> prevOuts,
40-
hashType = const SigHashType.all(),
40+
SigHashType hashType = const SigHashType.all(),
4141
Uint8List? leafHash,
4242
int codeSeperatorPos = 0xFFFFFFFF,
4343
}) => SchnorrInputSignature(

coinlib/lib/src/tx/inputs/taproot_key_input.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class TaprootKeyInput extends TaprootInput {
5353
required int inputN,
5454
required ECPrivateKey key,
5555
required List<Output> prevOuts,
56-
hashType = const SigHashType.all(),
56+
SigHashType hashType = const SigHashType.all(),
5757
}) {
5858

5959
if (inputN >= prevOuts.length) {

coinlib/lib/src/tx/inputs/taproot_script_input.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class TaprootScriptInput extends TaprootInput {
107107
required int inputN,
108108
required ECPrivateKey key,
109109
required List<Output> prevOuts,
110-
hashType = const SigHashType.all(),
110+
SigHashType hashType = const SigHashType.all(),
111111
int codeSeperatorPos = 0xFFFFFFFF,
112112
}) => createInputSignature(
113113
tx: tx,

coinlib/lib/src/tx/outpoint.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'package:coinlib/src/common/bytes.dart';
33
import 'package:coinlib/src/common/checks.dart';
44
import 'package:coinlib/src/common/hex.dart';
55
import 'package:coinlib/src/common/serial.dart';
6-
import 'package:collection/collection.dart';
6+
import 'output.dart';
77

88
/// Reference to an [Output] by transaction hash and index
99
class OutPoint with Writable {
@@ -36,7 +36,7 @@ class OutPoint with Writable {
3636
@override
3737
bool operator ==(Object other)
3838
=> (other is OutPoint)
39-
&& ListEquality().equals(_hash, other._hash)
39+
&& bytesEqual(_hash, other._hash)
4040
&& n == other.n;
4141

4242
@override

0 commit comments

Comments
 (0)