stack_wallet/lib/utilities/address_utils.dart

140 lines
4.9 KiB
Dart
Raw Normal View History

2022-08-26 08:11:35 +00:00
import 'dart:convert';
import 'package:bitcoindart/bitcoindart.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter_libepiccash/epic_cash.dart';
2022-09-26 20:32:53 +00:00
import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart';
2022-08-26 08:11:35 +00:00
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
2023-04-17 13:53:39 +00:00
import 'package:stackwallet/services/coins/ecash/ecash_wallet.dart';
2022-08-26 08:11:35 +00:00
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
2022-10-28 18:03:52 +00:00
import 'package:stackwallet/services/coins/litecoin/litecoin_wallet.dart';
2022-09-12 12:01:42 +00:00
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
2022-10-25 15:06:37 +00:00
import 'package:stackwallet/services/coins/particl/particl_wallet.dart';
2022-08-26 08:11:35 +00:00
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
class AddressUtils {
static String condenseAddress(String address) {
return '${address.substring(0, 5)}...${address.substring(address.length - 5)}';
}
/// attempts to convert a string to a valid scripthash
///
/// Returns the scripthash or throws an exception on invalid firo address
static String convertToScriptHash(
String address,
NetworkType network, [
String overridePrefix = "",
]) {
2022-08-26 08:11:35 +00:00
try {
final output =
Address.addressToOutputScript(address, network, overridePrefix);
2022-08-26 08:11:35 +00:00
final hash = sha256.convert(output.toList(growable: false)).toString();
final chars = hash.split("");
final reversedPairs = <String>[];
// TODO find a better/faster way to do this?
var i = chars.length - 1;
while (i > 0) {
reversedPairs.add(chars[i - 1]);
reversedPairs.add(chars[i]);
i -= 2;
}
return reversedPairs.join("");
} catch (e) {
rethrow;
}
}
static bool validateAddress(String address, Coin coin) {
switch (coin) {
case Coin.bitcoin:
return Address.validateAddress(address, bitcoin);
2022-10-28 18:03:52 +00:00
case Coin.litecoin:
return Address.validateAddress(address, litecoin);
2022-09-26 20:32:53 +00:00
case Coin.bitcoincash:
return Address.validateAddress(address, bitcoincash);
2022-08-26 08:11:35 +00:00
case Coin.dogecoin:
return Address.validateAddress(address, dogecoin);
case Coin.epicCash:
return validateSendAddress(address) == "1";
2022-12-13 17:39:19 +00:00
case Coin.ethereum:
return true; //TODO - validate ETH address
2022-08-26 08:11:35 +00:00
case Coin.firo:
return Address.validateAddress(address, firoNetwork);
2023-04-17 13:53:39 +00:00
case Coin.eCash:
return Address.validateAddress(address, eCashNetwork);
2022-08-26 08:11:35 +00:00
case Coin.monero:
return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
2022-09-27 08:09:31 +00:00
case Coin.wownero:
return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
2022-09-12 12:01:42 +00:00
case Coin.namecoin:
2022-09-23 16:48:27 +00:00
return Address.validateAddress(address, namecoin, namecoin.bech32!);
2022-10-25 15:06:37 +00:00
case Coin.particl:
return Address.validateAddress(address, particl);
2023-06-12 19:03:32 +00:00
case Coin.tezos:
return RegExp(r"^tz[1-9A-HJ-NP-Za-km-z]{34}$").hasMatch(address);
2022-08-26 08:11:35 +00:00
case Coin.bitcoinTestNet:
return Address.validateAddress(address, testnet);
2022-10-28 18:03:52 +00:00
case Coin.litecoinTestNet:
return Address.validateAddress(address, litecointestnet);
2022-09-26 20:32:53 +00:00
case Coin.bitcoincashTestnet:
return Address.validateAddress(address, bitcoincashtestnet);
2022-08-26 08:11:35 +00:00
case Coin.firoTestNet:
return Address.validateAddress(address, firoTestNetwork);
case Coin.dogecoinTestNet:
return Address.validateAddress(address, dogecointestnet);
}
}
/// parse an address uri
/// returns an empty map if the input string does not begin with "firo:"
static Map<String, String> parseUri(String uri) {
Map<String, String> result = {};
try {
final u = Uri.parse(uri);
if (u.hasScheme) {
result["scheme"] = u.scheme.toLowerCase();
result["address"] = u.path;
result.addAll(u.queryParameters);
}
} catch (e) {
Logging.instance
.log("Exception caught in parseUri($uri): $e", level: LogLevel.Error);
}
return result;
}
/// builds a uri string with the given address and query parameters if any
static String buildUriString(
Coin coin,
String address,
Map<String, String> params,
) {
String uriString = "${coin.uriScheme}:$address";
if (params.isNotEmpty) {
uriString += Uri(queryParameters: params).toString();
}
return uriString;
}
/// returns empty if bad data
static Map<String, dynamic> decodeQRSeedData(String data) {
Map<String, dynamic> result = {};
try {
result = Map<String, dynamic>.from(jsonDecode(data) as Map);
} catch (e) {
Logging.instance.log("Exception caught in parseQRSeedData($data): $e",
level: LogLevel.Error);
}
return result;
}
/// encode mnemonic words to qrcode formatted string
static String encodeQRSeedData(List<String> words) {
return jsonEncode({"mnemonic": words});
}
}