mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-23 03:49:22 +00:00
added extra checks to BCH as well as test cases
This commit is contained in:
parent
48a0e3a5ca
commit
c962f597fd
2 changed files with 199 additions and 23 deletions
|
@ -208,9 +208,9 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
_getCurrentAddressForChain(0, DerivePathType.bip44);
|
_getCurrentAddressForChain(0, DerivePathType.bip44);
|
||||||
Future<String>? _currentReceivingAddressP2PKH;
|
Future<String>? _currentReceivingAddressP2PKH;
|
||||||
|
|
||||||
Future<String> get currentReceivingAddressP2SH =>
|
// Future<String> get currentReceivingAddressP2SH =>
|
||||||
_currentReceivingAddressP2SH ??=
|
// _currentReceivingAddressP2SH ??=
|
||||||
_getCurrentAddressForChain(0, DerivePathType.bip49);
|
// _getCurrentAddressForChain(0, DerivePathType.bip49);
|
||||||
Future<String>? _currentReceivingAddressP2SH;
|
Future<String>? _currentReceivingAddressP2SH;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -269,7 +269,11 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
try {
|
try {
|
||||||
if (bitbox.Address.detectFormat(address) ==
|
if (bitbox.Address.detectFormat(address) ==
|
||||||
bitbox.Address.formatCashAddr) {
|
bitbox.Address.formatCashAddr) {
|
||||||
address = bitbox.Address.toLegacyAddress(address);
|
if (validateCashAddr(address)) {
|
||||||
|
address = bitbox.Address.toLegacyAddress(address);
|
||||||
|
} else {
|
||||||
|
throw ArgumentError('$address is not currently supported');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e, s) {}
|
} catch (e, s) {}
|
||||||
try {
|
try {
|
||||||
|
@ -294,11 +298,14 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Bech32 decode fail
|
// Bech32 decode fail
|
||||||
}
|
}
|
||||||
if (_network.bech32 != decodeBech32!.hrp) {
|
|
||||||
throw ArgumentError('Invalid prefix or Network mismatch');
|
if (decodeBech32 != null) {
|
||||||
}
|
if (_network.bech32 != decodeBech32.hrp) {
|
||||||
if (decodeBech32.version != 0) {
|
throw ArgumentError('Invalid prefix or Network mismatch');
|
||||||
throw ArgumentError('Invalid address version');
|
}
|
||||||
|
if (decodeBech32.version != 0) {
|
||||||
|
throw ArgumentError('Invalid address version');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw ArgumentError('$address has no matching Script');
|
throw ArgumentError('$address has no matching Script');
|
||||||
|
@ -1203,6 +1210,15 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
_transactionData = Future(() => cachedTxData!);
|
_transactionData = Future(() => cachedTxData!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool validateCashAddr(String cashAddr) {
|
||||||
|
String addr = cashAddr;
|
||||||
|
if (cashAddr.contains(":")) {
|
||||||
|
addr = cashAddr.split(":").last;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr.startsWith("q");
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool validateAddress(String address) {
|
bool validateAddress(String address) {
|
||||||
try {
|
try {
|
||||||
|
@ -1217,12 +1233,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == bitbox.Address.formatCashAddr) {
|
if (format == bitbox.Address.formatCashAddr) {
|
||||||
String addr = address;
|
return validateCashAddr(address);
|
||||||
if (address.contains(":")) {
|
|
||||||
addr = address.split(":").last;
|
|
||||||
}
|
|
||||||
|
|
||||||
return addr.startsWith("q");
|
|
||||||
} else {
|
} else {
|
||||||
return address.startsWith("1");
|
return address.startsWith("1");
|
||||||
}
|
}
|
||||||
|
@ -2085,7 +2096,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
String _convertToScriptHash(String bchAddress, NetworkType network) {
|
String _convertToScriptHash(String bchAddress, NetworkType network) {
|
||||||
try {
|
try {
|
||||||
if (bitbox.Address.detectFormat(bchAddress) ==
|
if (bitbox.Address.detectFormat(bchAddress) ==
|
||||||
bitbox.Address.formatCashAddr) {
|
bitbox.Address.formatCashAddr &&
|
||||||
|
validateCashAddr(bchAddress)) {
|
||||||
bchAddress = bitbox.Address.toLegacyAddress(bchAddress);
|
bchAddress = bitbox.Address.toLegacyAddress(bchAddress);
|
||||||
}
|
}
|
||||||
final output = Address.addressToOutputScript(bchAddress, network);
|
final output = Address.addressToOutputScript(bchAddress, network);
|
||||||
|
@ -2163,7 +2175,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
List<String> allAddressesOld = await _fetchAllOwnAddresses();
|
List<String> allAddressesOld = await _fetchAllOwnAddresses();
|
||||||
List<String> allAddresses = [];
|
List<String> allAddresses = [];
|
||||||
for (String address in allAddressesOld) {
|
for (String address in allAddressesOld) {
|
||||||
if (bitbox.Address.detectFormat(address) == bitbox.Address.formatLegacy) {
|
if (bitbox.Address.detectFormat(address) == bitbox.Address.formatLegacy &&
|
||||||
|
addressType(address: address) == DerivePathType.bip44) {
|
||||||
allAddresses.add(bitbox.Address.toCashAddress(address));
|
allAddresses.add(bitbox.Address.toCashAddress(address));
|
||||||
} else {
|
} else {
|
||||||
allAddresses.add(address);
|
allAddresses.add(address);
|
||||||
|
@ -2882,7 +2895,12 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
String address = output["scriptPubKey"]["addresses"][0] as String;
|
String address = output["scriptPubKey"]["addresses"][0] as String;
|
||||||
if (bitbox.Address.detectFormat(address) ==
|
if (bitbox.Address.detectFormat(address) ==
|
||||||
bitbox.Address.formatCashAddr) {
|
bitbox.Address.formatCashAddr) {
|
||||||
address = bitbox.Address.toLegacyAddress(address);
|
if (validateCashAddr(address)) {
|
||||||
|
address = bitbox.Address.toLegacyAddress(address);
|
||||||
|
} else {
|
||||||
|
throw Exception(
|
||||||
|
"Unsupported address found during fetchBuildTxData(): $address");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!addressTxid.containsKey(address)) {
|
if (!addressTxid.containsKey(address)) {
|
||||||
addressTxid[address] = <String>[];
|
addressTxid[address] = <String>[];
|
||||||
|
@ -2913,10 +2931,6 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
);
|
);
|
||||||
for (int i = 0; i < p2pkhLength; i++) {
|
for (int i = 0; i < p2pkhLength; i++) {
|
||||||
String address = addressesP2PKH[i];
|
String address = addressesP2PKH[i];
|
||||||
if (bitbox.Address.detectFormat(address) ==
|
|
||||||
bitbox.Address.formatCashAddr) {
|
|
||||||
address = bitbox.Address.toLegacyAddress(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
// receives
|
// receives
|
||||||
final receiveDerivation = receiveDerivations[address];
|
final receiveDerivation = receiveDerivations[address];
|
||||||
|
|
|
@ -60,7 +60,7 @@ void main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group("validate mainnet bitcoincash addresses", () {
|
group("mainnet bitcoincash addressType", () {
|
||||||
MockElectrumX? client;
|
MockElectrumX? client;
|
||||||
MockCachedElectrumX? cachedClient;
|
MockCachedElectrumX? cachedClient;
|
||||||
MockPriceAPI? priceAPI;
|
MockPriceAPI? priceAPI;
|
||||||
|
@ -136,6 +136,168 @@ void main() {
|
||||||
verifyNoMoreInteractions(priceAPI);
|
verifyNoMoreInteractions(priceAPI);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("P2PKH cashaddr with prefix", () {
|
||||||
|
expect(
|
||||||
|
mainnetWallet?.addressType(
|
||||||
|
address:
|
||||||
|
"bitcoincash:qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"),
|
||||||
|
DerivePathType.bip44);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("P2PKH cashaddr without prefix", () {
|
||||||
|
expect(
|
||||||
|
mainnetWallet?.addressType(
|
||||||
|
address: "qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"),
|
||||||
|
DerivePathType.bip44);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Multisig cashaddr with prefix", () {
|
||||||
|
expect(
|
||||||
|
() => mainnetWallet?.addressType(
|
||||||
|
address:
|
||||||
|
"bitcoincash:pzpp3nchmzzf0gr69lj82ymurg5u3ds6kcwr5m07np"),
|
||||||
|
throwsArgumentError);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Multisig cashaddr without prefix", () {
|
||||||
|
expect(
|
||||||
|
() => mainnetWallet?.addressType(
|
||||||
|
address: "pzpp3nchmzzf0gr69lj82ymurg5u3ds6kcwr5m07np"),
|
||||||
|
throwsArgumentError);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Multisig/P2SH address", () {
|
||||||
|
expect(
|
||||||
|
mainnetWallet?.addressType(
|
||||||
|
address: "3DYuVEmuKWQFxJcF7jDPhwPiXLTiNnyMFb"),
|
||||||
|
DerivePathType.bip49);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group("validate mainnet bitcoincash addresses", () {
|
||||||
|
MockElectrumX? client;
|
||||||
|
MockCachedElectrumX? cachedClient;
|
||||||
|
MockPriceAPI? priceAPI;
|
||||||
|
FakeSecureStorage? secureStore;
|
||||||
|
MockTransactionNotificationTracker? tracker;
|
||||||
|
|
||||||
|
BitcoinCashWallet? mainnetWallet;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
client = MockElectrumX();
|
||||||
|
cachedClient = MockCachedElectrumX();
|
||||||
|
priceAPI = MockPriceAPI();
|
||||||
|
secureStore = FakeSecureStorage();
|
||||||
|
tracker = MockTransactionNotificationTracker();
|
||||||
|
|
||||||
|
mainnetWallet = BitcoinCashWallet(
|
||||||
|
walletId: "validateAddressMainNet",
|
||||||
|
walletName: "validateAddressMainNet",
|
||||||
|
coin: Coin.bitcoincash,
|
||||||
|
client: client!,
|
||||||
|
cachedClient: cachedClient!,
|
||||||
|
tracker: tracker!,
|
||||||
|
priceAPI: priceAPI,
|
||||||
|
secureStore: secureStore,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("valid mainnet legacy/p2pkh address type", () {
|
||||||
|
expect(
|
||||||
|
mainnetWallet?.validateAddress("1DP3PUePwMa5CoZwzjznVKhzdLsZftjcAT"),
|
||||||
|
true);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("valid mainnet legacy/p2pkh cashaddr with prefix address type", () {
|
||||||
|
expect(
|
||||||
|
mainnetWallet?.validateAddress(
|
||||||
|
"bitcoincash:qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"),
|
||||||
|
true);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("valid mainnet legacy/p2pkh cashaddr without prefix address type", () {
|
||||||
|
expect(
|
||||||
|
mainnetWallet
|
||||||
|
?.validateAddress("qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"),
|
||||||
|
true);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("invalid legacy/p2pkh address type", () {
|
||||||
|
expect(
|
||||||
|
mainnetWallet?.validateAddress("mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"),
|
||||||
|
false);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
"invalid cashaddr (is valid multisig but bitbox is broken for multisig)",
|
||||||
|
() {
|
||||||
|
expect(
|
||||||
|
mainnetWallet
|
||||||
|
?.validateAddress("pzpp3nchmzzf0gr69lj82ymurg5u3ds6kcwr5m07np"),
|
||||||
|
false);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("multisig address should fail for bitbox", () {
|
||||||
|
expect(
|
||||||
|
mainnetWallet?.validateAddress("3DYuVEmuKWQFxJcF7jDPhwPiXLTiNnyMFb"),
|
||||||
|
false);
|
||||||
|
expect(secureStore?.interactions, 0);
|
||||||
|
verifyNoMoreInteractions(client);
|
||||||
|
verifyNoMoreInteractions(cachedClient);
|
||||||
|
verifyNoMoreInteractions(tracker);
|
||||||
|
verifyNoMoreInteractions(priceAPI);
|
||||||
|
});
|
||||||
|
|
||||||
test("invalid mainnet bitcoincash legacy/p2pkh address", () {
|
test("invalid mainnet bitcoincash legacy/p2pkh address", () {
|
||||||
expect(
|
expect(
|
||||||
mainnetWallet?.validateAddress("mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"),
|
mainnetWallet?.validateAddress("mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"),
|
||||||
|
|
Loading…
Reference in a new issue