mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-03-15 16:12:16 +00:00
add litecoin support
This commit is contained in:
parent
4c4df1b618
commit
c0fddcd822
20 changed files with 305 additions and 139 deletions
BIN
assets/images/litecoin.png
Normal file
BIN
assets/images/litecoin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 322 KiB |
11
assets/svg/coin_icons/Litecoin.svg
Normal file
11
assets/svg/coin_icons/Litecoin.svg
Normal file
|
@ -0,0 +1,11 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_6052_99642)">
|
||||
<rect width="24" height="24" rx="12" fill="white"/>
|
||||
<path d="M11.9976 0C9.62389 0 7.30353 0.703873 5.3299 2.02261C3.35627 3.34135 1.81802 5.21572 0.909655 7.4087C0.00129377 9.60167 -0.236375 12.0148 0.226704 14.3428C0.689782 16.6709 1.83281 18.8093 3.51124 20.4878C5.18968 22.1662 7.32813 23.3092 9.65618 23.7723C11.9842 24.2354 14.3973 23.9977 16.5903 23.0893C18.7833 22.181 20.6577 20.6427 21.9764 18.6691C23.2951 16.6955 23.999 14.3751 23.999 12.0015C23.999 10.4254 23.6886 8.86478 23.0854 7.4087C22.4823 5.95261 21.5983 4.62958 20.4839 3.51514C19.3694 2.40071 18.0464 1.51669 16.5903 0.913556C15.1342 0.310427 13.5736 0 11.9976 0V0ZM12.1921 12.3963L10.9437 16.6087H17.6209C17.674 16.6088 17.7263 16.6213 17.7738 16.6451C17.8212 16.669 17.8625 16.7035 17.8943 16.746C17.9261 16.7885 17.9476 16.8378 17.9571 16.8901C17.9666 16.9423 17.9638 16.9961 17.9489 17.0471L17.3683 19.0473C17.3406 19.1429 17.2826 19.2268 17.203 19.2865C17.1234 19.3462 17.0265 19.3784 16.927 19.3783H6.72841L8.45286 13.5546L6.54551 14.1352L6.96646 12.7737L8.87671 12.1931L11.2979 4.0121C11.3245 3.91623 11.3818 3.8317 11.4609 3.77142C11.5401 3.71114 11.6368 3.67842 11.7363 3.67824H14.32C14.3731 3.67805 14.4254 3.69017 14.4729 3.71364C14.5205 3.73712 14.5619 3.77131 14.594 3.81352C14.6261 3.85573 14.6479 3.90482 14.6578 3.95691C14.6677 4.009 14.6654 4.06267 14.651 4.11371L12.6188 11.0318L14.5262 10.4512L14.1168 11.836L12.1921 12.3963Z" fill="#315D9E"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_6052_99642">
|
||||
<rect width="24" height="24" rx="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
103
lib/main.dart
103
lib/main.dart
|
@ -68,7 +68,7 @@ final openedFromSWBFileStringStateProvider =
|
|||
void main() async {
|
||||
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
|
||||
GoogleFonts.config.allowRuntimeFetching = false;
|
||||
if(Platform.isIOS){
|
||||
if (Platform.isIOS) {
|
||||
Util.libraryPath = await getLibraryDirectory();
|
||||
}
|
||||
|
||||
|
@ -209,56 +209,59 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
|
|||
bool didLoad = false;
|
||||
|
||||
Future<void> load() async {
|
||||
if (didLoad) {
|
||||
return;
|
||||
}
|
||||
didLoad = true;
|
||||
|
||||
await DB.instance.init();
|
||||
await _prefs.init();
|
||||
|
||||
_notificationsService = ref.read(notificationsProvider);
|
||||
_nodeService = ref.read(nodeServiceChangeNotifierProvider);
|
||||
_tradesService = ref.read(tradesServiceProvider);
|
||||
|
||||
NotificationApi.prefs = _prefs;
|
||||
NotificationApi.notificationsService = _notificationsService;
|
||||
|
||||
unawaited(ref.read(baseCurrenciesProvider).update());
|
||||
|
||||
await _nodeService.updateDefaults();
|
||||
await _notificationsService.init(
|
||||
nodeService: _nodeService,
|
||||
tradesService: _tradesService,
|
||||
prefs: _prefs,
|
||||
);
|
||||
ref.read(priceAnd24hChangeNotifierProvider).start(true);
|
||||
await _wallets.load(_prefs);
|
||||
loadingCompleter.complete();
|
||||
// TODO: this should probably run unawaited. Keep commented out for now as proper community nodes ui hasn't been implemented yet
|
||||
// unawaited(_nodeService.updateCommunityNodes());
|
||||
|
||||
// run without awaiting
|
||||
if (Constants.enableExchange &&
|
||||
_prefs.externalCalls &&
|
||||
await _prefs.isExternalCallsSet()) {
|
||||
unawaited(ExchangeDataLoadingService().loadAll(ref));
|
||||
}
|
||||
|
||||
if (_prefs.isAutoBackupEnabled) {
|
||||
switch (_prefs.backupFrequencyType) {
|
||||
case BackupFrequencyType.everyTenMinutes:
|
||||
ref
|
||||
.read(autoSWBServiceProvider)
|
||||
.startPeriodicBackupTimer(duration: const Duration(minutes: 10));
|
||||
break;
|
||||
case BackupFrequencyType.everyAppStart:
|
||||
unawaited(ref.read(autoSWBServiceProvider).doBackup());
|
||||
break;
|
||||
case BackupFrequencyType.afterClosingAWallet:
|
||||
// ignore this case here
|
||||
break;
|
||||
try {
|
||||
if (didLoad) {
|
||||
return;
|
||||
}
|
||||
didLoad = true;
|
||||
|
||||
await DB.instance.init();
|
||||
await _prefs.init();
|
||||
|
||||
_notificationsService = ref.read(notificationsProvider);
|
||||
_nodeService = ref.read(nodeServiceChangeNotifierProvider);
|
||||
_tradesService = ref.read(tradesServiceProvider);
|
||||
|
||||
NotificationApi.prefs = _prefs;
|
||||
NotificationApi.notificationsService = _notificationsService;
|
||||
|
||||
unawaited(ref.read(baseCurrenciesProvider).update());
|
||||
|
||||
await _nodeService.updateDefaults();
|
||||
await _notificationsService.init(
|
||||
nodeService: _nodeService,
|
||||
tradesService: _tradesService,
|
||||
prefs: _prefs,
|
||||
);
|
||||
ref.read(priceAnd24hChangeNotifierProvider).start(true);
|
||||
await _wallets.load(_prefs);
|
||||
loadingCompleter.complete();
|
||||
// TODO: this should probably run unawaited. Keep commented out for now as proper community nodes ui hasn't been implemented yet
|
||||
// unawaited(_nodeService.updateCommunityNodes());
|
||||
|
||||
// run without awaiting
|
||||
if (Constants.enableExchange &&
|
||||
_prefs.externalCalls &&
|
||||
await _prefs.isExternalCallsSet()) {
|
||||
unawaited(ExchangeDataLoadingService().loadAll(ref));
|
||||
}
|
||||
|
||||
if (_prefs.isAutoBackupEnabled) {
|
||||
switch (_prefs.backupFrequencyType) {
|
||||
case BackupFrequencyType.everyTenMinutes:
|
||||
ref.read(autoSWBServiceProvider).startPeriodicBackupTimer(
|
||||
duration: const Duration(minutes: 10));
|
||||
break;
|
||||
case BackupFrequencyType.everyAppStart:
|
||||
unawaited(ref.read(autoSWBServiceProvider).doBackup());
|
||||
break;
|
||||
case BackupFrequencyType.afterClosingAWallet:
|
||||
// ignore this case here
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logger.print("$e $s", normalLength: false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,11 +52,13 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
|
|||
switch (coin) {
|
||||
case Coin.bitcoin:
|
||||
case Coin.bitcoincash:
|
||||
case Coin.litecoin:
|
||||
case Coin.dogecoin:
|
||||
case Coin.epicCash:
|
||||
case Coin.firo:
|
||||
case Coin.namecoin:
|
||||
case Coin.bitcoinTestNet:
|
||||
case Coin.litecoinTestNet:
|
||||
case Coin.bitcoincashTestnet:
|
||||
case Coin.dogecoinTestNet:
|
||||
case Coin.firoTestNet:
|
||||
|
|
|
@ -531,11 +531,13 @@ class _NodeFormState extends ConsumerState<NodeForm> {
|
|||
// TODO: which coin servers can have username and password?
|
||||
switch (coin) {
|
||||
case Coin.bitcoin:
|
||||
case Coin.litecoin:
|
||||
case Coin.dogecoin:
|
||||
case Coin.firo:
|
||||
case Coin.namecoin:
|
||||
case Coin.bitcoincash:
|
||||
case Coin.bitcoinTestNet:
|
||||
case Coin.litecoinTestNet:
|
||||
case Coin.bitcoincashTestnet:
|
||||
case Coin.firoTestNet:
|
||||
case Coin.dogecoinTestNet:
|
||||
|
|
|
@ -98,6 +98,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
|
|||
break;
|
||||
|
||||
case Coin.bitcoin:
|
||||
case Coin.litecoin:
|
||||
case Coin.dogecoin:
|
||||
case Coin.firo:
|
||||
case Coin.bitcoinTestNet:
|
||||
|
@ -105,6 +106,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
|
|||
case Coin.dogecoinTestNet:
|
||||
case Coin.bitcoincash:
|
||||
case Coin.namecoin:
|
||||
case Coin.litecoinTestNet:
|
||||
case Coin.bitcoincashTestnet:
|
||||
final client = ElectrumX(
|
||||
host: node!.host,
|
||||
|
|
|
@ -15,6 +15,8 @@ import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
|||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/prefs.dart';
|
||||
|
||||
import 'litecoin/litecoin_wallet.dart';
|
||||
|
||||
abstract class CoinServiceAPI {
|
||||
CoinServiceAPI();
|
||||
|
||||
|
@ -90,6 +92,26 @@ abstract class CoinServiceAPI {
|
|||
tracker: tracker,
|
||||
);
|
||||
|
||||
case Coin.litecoin:
|
||||
return LitecoinWallet(
|
||||
walletId: walletId,
|
||||
walletName: walletName,
|
||||
coin: coin,
|
||||
client: client,
|
||||
cachedClient: cachedClient,
|
||||
tracker: tracker,
|
||||
);
|
||||
|
||||
case Coin.litecoinTestNet:
|
||||
return LitecoinWallet(
|
||||
walletId: walletId,
|
||||
walletName: walletName,
|
||||
coin: coin,
|
||||
client: client,
|
||||
cachedClient: cachedClient,
|
||||
tracker: tracker,
|
||||
);
|
||||
|
||||
case Coin.bitcoinTestNet:
|
||||
return BitcoinWallet(
|
||||
walletId: walletId,
|
||||
|
|
|
@ -46,9 +46,9 @@ const int MINIMUM_CONFIRMATIONS = 1;
|
|||
const int DUST_LIMIT = 294;
|
||||
|
||||
const String GENESIS_HASH_MAINNET =
|
||||
"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f";
|
||||
"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2";
|
||||
const String GENESIS_HASH_TESTNET =
|
||||
"000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943";
|
||||
"4966625a4b2851d9fdee139e56211a0d88575f59ed816ff5e6a63deb4e3e29a0";
|
||||
|
||||
enum DerivePathType { bip44, bip49, bip84 }
|
||||
|
||||
|
@ -86,14 +86,14 @@ bip32.BIP32 getBip32NodeFromRoot(
|
|||
) {
|
||||
String coinType;
|
||||
switch (root.network.wif) {
|
||||
case 0x80: // btc mainnet wif
|
||||
coinType = "0"; // btc mainnet
|
||||
case 0xb0: // ltc mainnet wif
|
||||
coinType = "2"; // ltc mainnet
|
||||
break;
|
||||
case 0xef: // btc testnet wif
|
||||
coinType = "1"; // btc testnet
|
||||
case 0xef: // ltc testnet wif
|
||||
coinType = "1"; // ltc testnet
|
||||
break;
|
||||
default:
|
||||
throw Exception("Invalid Bitcoin network type used!");
|
||||
throw Exception("Invalid Litecoin network type used!");
|
||||
}
|
||||
switch (derivePathType) {
|
||||
case DerivePathType.bip44:
|
||||
|
@ -138,7 +138,7 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) {
|
|||
return getBip32Root(args.item1, args.item2);
|
||||
}
|
||||
|
||||
class BitcoinWallet extends CoinServiceAPI {
|
||||
class LitecoinWallet extends CoinServiceAPI {
|
||||
static const integrationTestFlag =
|
||||
bool.fromEnvironment("IS_INTEGRATION_TEST");
|
||||
|
||||
|
@ -151,10 +151,10 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
|
||||
NetworkType get _network {
|
||||
switch (coin) {
|
||||
case Coin.bitcoin:
|
||||
return bitcoin;
|
||||
case Coin.bitcoinTestNet:
|
||||
return testnet;
|
||||
case Coin.litecoin:
|
||||
return litecoin;
|
||||
case Coin.litecoinTestNet:
|
||||
return litecointestnet;
|
||||
default:
|
||||
throw Exception("Invalid network type!");
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
throw ArgumentError('Invalid version or Network mismatch');
|
||||
} else {
|
||||
try {
|
||||
decodeBech32 = segwit.decode(address);
|
||||
decodeBech32 = segwit.decode(address, _network.bech32!);
|
||||
} catch (err) {
|
||||
// Bech32 decode fail
|
||||
}
|
||||
|
@ -347,19 +347,19 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
final features = await electrumXClient.getServerFeatures();
|
||||
Logging.instance.log("features: $features", level: LogLevel.Info);
|
||||
switch (coin) {
|
||||
case Coin.bitcoin:
|
||||
case Coin.litecoin:
|
||||
if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
|
||||
throw Exception("genesis hash does not match main net!");
|
||||
}
|
||||
break;
|
||||
case Coin.bitcoinTestNet:
|
||||
case Coin.litecoinTestNet:
|
||||
if (features['genesis_hash'] != GENESIS_HASH_TESTNET) {
|
||||
throw Exception("genesis hash does not match test net!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw Exception(
|
||||
"Attempted to generate a BitcoinWallet using a non bitcoin coin type: ${coin.name}");
|
||||
"Attempted to generate a LitecoinWallet using a non litecoin coin type: ${coin.name}");
|
||||
}
|
||||
// if (_networkType == BasicNetworkType.main) {
|
||||
// if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
|
||||
|
@ -446,7 +446,8 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
data: PaymentData(
|
||||
redeem: P2WPKH(
|
||||
data: PaymentData(pubkey: node.publicKey),
|
||||
network: _network)
|
||||
network: _network,
|
||||
overridePrefix: _network.bech32!)
|
||||
.data),
|
||||
network: _network)
|
||||
.data
|
||||
|
@ -455,7 +456,8 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
case DerivePathType.bip84:
|
||||
address = P2WPKH(
|
||||
network: _network,
|
||||
data: PaymentData(pubkey: node.publicKey))
|
||||
data: PaymentData(pubkey: node.publicKey),
|
||||
overridePrefix: _network.bech32!)
|
||||
.data
|
||||
.address!;
|
||||
break;
|
||||
|
@ -1284,7 +1286,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
|
||||
@override
|
||||
bool validateAddress(String address) {
|
||||
return Address.validateAddress(address, _network);
|
||||
return Address.validateAddress(address, _network, _network.bech32!);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1311,7 +1313,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
|
||||
late PriceAPI _priceAPI;
|
||||
|
||||
BitcoinWallet({
|
||||
LitecoinWallet({
|
||||
required String walletId,
|
||||
required String walletName,
|
||||
required Coin coin,
|
||||
|
@ -1469,19 +1471,20 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
final features = await electrumXClient.getServerFeatures();
|
||||
Logging.instance.log("features: $features", level: LogLevel.Info);
|
||||
switch (coin) {
|
||||
case Coin.bitcoin:
|
||||
case Coin.litecoin:
|
||||
if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
|
||||
print(features['genesis_hash']);
|
||||
throw Exception("genesis hash does not match main net!");
|
||||
}
|
||||
break;
|
||||
case Coin.bitcoinTestNet:
|
||||
case Coin.litecoinTestNet:
|
||||
if (features['genesis_hash'] != GENESIS_HASH_TESTNET) {
|
||||
throw Exception("genesis hash does not match test net!");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw Exception(
|
||||
"Attempted to generate a BitcoinWallet using a non bitcoin coin type: ${coin.name}");
|
||||
"Attempted to generate a LitecoinWallet using a non litecoin coin type: ${coin.name}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1636,13 +1639,20 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
case DerivePathType.bip49:
|
||||
address = P2SH(
|
||||
data: PaymentData(
|
||||
redeem: P2WPKH(data: data, network: _network).data),
|
||||
redeem: P2WPKH(
|
||||
data: data,
|
||||
network: _network,
|
||||
overridePrefix: _network.bech32!)
|
||||
.data),
|
||||
network: _network)
|
||||
.data
|
||||
.address!;
|
||||
break;
|
||||
case DerivePathType.bip84:
|
||||
address = P2WPKH(network: _network, data: data).data.address!;
|
||||
address = P2WPKH(
|
||||
network: _network, data: data, overridePrefix: _network.bech32!)
|
||||
.data
|
||||
.address!;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2216,10 +2226,11 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
|
||||
/// attempts to convert a string to a valid scripthash
|
||||
///
|
||||
/// Returns the scripthash or throws an exception on invalid bitcoin address
|
||||
String _convertToScriptHash(String bitcoinAddress, NetworkType network) {
|
||||
/// Returns the scripthash or throws an exception on invalid litecoin address
|
||||
String _convertToScriptHash(String litecoinAddress, NetworkType network) {
|
||||
try {
|
||||
final output = Address.addressToOutputScript(bitcoinAddress, network);
|
||||
final output = Address.addressToOutputScript(
|
||||
litecoinAddress, network, _network.bech32!);
|
||||
final hash = sha256.convert(output.toList(growable: false)).toString();
|
||||
|
||||
final chars = hash.split("");
|
||||
|
@ -2442,7 +2453,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
|
||||
for (final out in tx["vout"] as List) {
|
||||
if (prevOut == out["n"]) {
|
||||
final address = out["scriptPubKey"]["address"] as String?;
|
||||
final address = out["scriptPubKey"]["addresses"][0] as String?;
|
||||
if (address != null) {
|
||||
sendersArray.add(address);
|
||||
}
|
||||
|
@ -2453,7 +2464,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info);
|
||||
|
||||
for (final output in txObject["vout"] as List) {
|
||||
final address = output["scriptPubKey"]["address"] as String?;
|
||||
final address = output["scriptPubKey"]["addresses"][0] as String?;
|
||||
if (address != null) {
|
||||
recipientsArray.add(address);
|
||||
}
|
||||
|
@ -2493,7 +2504,8 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
int totalOutput = 0;
|
||||
|
||||
for (final output in txObject["vout"] as List) {
|
||||
final String address = output["scriptPubKey"]!["address"] as String;
|
||||
final String address =
|
||||
output["scriptPubKey"]!["addresses"][0] as String;
|
||||
final value = output["value"]!;
|
||||
final _value = (Decimal.parse(value.toString()) *
|
||||
Decimal.fromInt(Constants.satsPerCoin))
|
||||
|
@ -2518,7 +2530,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
|
||||
// add up received tx value
|
||||
for (final output in txObject["vout"] as List) {
|
||||
final address = output["scriptPubKey"]["address"];
|
||||
final address = output["scriptPubKey"]["addresses"][0];
|
||||
if (address != null) {
|
||||
final value = (Decimal.parse(output["value"].toString()) *
|
||||
Decimal.fromInt(Constants.satsPerCoin))
|
||||
|
@ -3034,7 +3046,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
for (final output in tx["vout"] as List) {
|
||||
final n = output["n"];
|
||||
if (n != null && n == utxosToUse[i].vout) {
|
||||
final address = output["scriptPubKey"]["address"] as String;
|
||||
final address = output["scriptPubKey"]["addresses"][0] as String;
|
||||
if (!addressTxid.containsKey(address)) {
|
||||
addressTxid[address] = <String>[];
|
||||
}
|
||||
|
@ -3132,7 +3144,8 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
data: PaymentData(
|
||||
pubkey: Format.stringToUint8List(
|
||||
receiveDerivation["pubKey"] as String)),
|
||||
network: _network)
|
||||
network: _network,
|
||||
overridePrefix: _network.bech32!)
|
||||
.data;
|
||||
|
||||
final redeemScript = p2wpkh.output;
|
||||
|
@ -3159,7 +3172,8 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
data: PaymentData(
|
||||
pubkey: Format.stringToUint8List(
|
||||
changeDerivation["pubKey"] as String)),
|
||||
network: _network)
|
||||
network: _network,
|
||||
overridePrefix: _network.bech32!)
|
||||
.data;
|
||||
|
||||
final redeemScript = p2wpkh.output;
|
||||
|
@ -3201,11 +3215,12 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
// if a match exists it will not be null
|
||||
if (receiveDerivation != null) {
|
||||
final data = P2WPKH(
|
||||
data: PaymentData(
|
||||
pubkey: Format.stringToUint8List(
|
||||
receiveDerivation["pubKey"] as String)),
|
||||
network: _network,
|
||||
).data;
|
||||
data: PaymentData(
|
||||
pubkey: Format.stringToUint8List(
|
||||
receiveDerivation["pubKey"] as String)),
|
||||
network: _network,
|
||||
overridePrefix: _network.bech32!)
|
||||
.data;
|
||||
|
||||
for (String tx in addressTxid[addressesP2WPKH[i]]!) {
|
||||
results[tx] = {
|
||||
|
@ -3222,11 +3237,12 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
// if a match exists it will not be null
|
||||
if (changeDerivation != null) {
|
||||
final data = P2WPKH(
|
||||
data: PaymentData(
|
||||
pubkey: Format.stringToUint8List(
|
||||
changeDerivation["pubKey"] as String)),
|
||||
network: _network,
|
||||
).data;
|
||||
data: PaymentData(
|
||||
pubkey: Format.stringToUint8List(
|
||||
changeDerivation["pubKey"] as String)),
|
||||
network: _network,
|
||||
overridePrefix: _network.bech32!)
|
||||
.data;
|
||||
|
||||
for (String tx in addressTxid[addressesP2WPKH[i]]!) {
|
||||
results[tx] = {
|
||||
|
@ -3267,12 +3283,12 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
for (var i = 0; i < utxosToUse.length; i++) {
|
||||
final txid = utxosToUse[i].txid;
|
||||
txb.addInput(txid, utxosToUse[i].vout, null,
|
||||
utxoSigningData[txid]["output"] as Uint8List);
|
||||
utxoSigningData[txid]["output"] as Uint8List, _network.bech32!);
|
||||
}
|
||||
|
||||
// Add transaction output
|
||||
for (var i = 0; i < recipients.length; i++) {
|
||||
txb.addOutput(recipients[i], satoshiAmounts[i]);
|
||||
txb.addOutput(recipients[i], satoshiAmounts[i], _network.bech32!);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -3280,11 +3296,11 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
for (var i = 0; i < utxosToUse.length; i++) {
|
||||
final txid = utxosToUse[i].txid;
|
||||
txb.sign(
|
||||
vin: i,
|
||||
keyPair: utxoSigningData[txid]["keyPair"] as ECPair,
|
||||
witnessValue: utxosToUse[i].value,
|
||||
redeemScript: utxoSigningData[txid]["redeemScript"] as Uint8List?,
|
||||
);
|
||||
vin: i,
|
||||
keyPair: utxoSigningData[txid]["keyPair"] as ECPair,
|
||||
witnessValue: utxosToUse[i].value,
|
||||
redeemScript: utxoSigningData[txid]["redeemScript"] as Uint8List?,
|
||||
overridePrefix: _network.bech32!);
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("Caught exception while signing transaction: $e\n$s",
|
||||
|
@ -3292,7 +3308,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
rethrow;
|
||||
}
|
||||
|
||||
final builtTx = txb.build();
|
||||
final builtTx = txb.build(_network.bech32!);
|
||||
final vSize = builtTx.virtualSize();
|
||||
|
||||
return {"hex": builtTx.toHex(), "vSize": vSize};
|
||||
|
@ -3794,3 +3810,19 @@ class BitcoinWallet extends CoinServiceAPI {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
final litecoin = NetworkType(
|
||||
messagePrefix: '\x19Litecoin Signed Message:\n',
|
||||
bech32: 'ltc',
|
||||
bip32: Bip32Type(public: 0x0488b21e, private: 0x0488ade4),
|
||||
pubKeyHash: 0x30,
|
||||
scriptHash: 0x32,
|
||||
wif: 0xb0);
|
||||
|
||||
final litecointestnet = NetworkType(
|
||||
messagePrefix: '\x19Litecoin Signed Message:\n',
|
||||
bech32: 'tltc',
|
||||
bip32: Bip32Type(public: 0x043587cf, private: 0x04358394),
|
||||
pubKeyHash: 0x6f,
|
||||
scriptHash: 0x3a,
|
||||
wif: 0xef);
|
||||
|
|
|
@ -87,7 +87,7 @@ class PriceAPI {
|
|||
Map<Coin, Tuple2<Decimal, double>> result = {};
|
||||
try {
|
||||
final uri = Uri.parse(
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false");
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false");
|
||||
// final uri = Uri.parse(
|
||||
// "https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero%2Cbitcoin%2Cepic-cash%2Czcoin%2Cdogecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false");
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:flutter_libepiccash/epic_cash.dart';
|
|||
import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/litecoin/litecoin_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
|
@ -42,6 +43,8 @@ class AddressUtils {
|
|||
switch (coin) {
|
||||
case Coin.bitcoin:
|
||||
return Address.validateAddress(address, bitcoin);
|
||||
case Coin.litecoin:
|
||||
return Address.validateAddress(address, litecoin);
|
||||
case Coin.bitcoincash:
|
||||
return Address.validateAddress(address, bitcoincash);
|
||||
case Coin.dogecoin:
|
||||
|
@ -60,6 +63,8 @@ class AddressUtils {
|
|||
return Address.validateAddress(address, namecoin, namecoin.bech32!);
|
||||
case Coin.bitcoinTestNet:
|
||||
return Address.validateAddress(address, testnet);
|
||||
case Coin.litecoinTestNet:
|
||||
return Address.validateAddress(address, litecointestnet);
|
||||
case Coin.bitcoincashTestnet:
|
||||
return Address.validateAddress(address, bitcoincashtestnet);
|
||||
case Coin.firoTestNet:
|
||||
|
|
|
@ -149,6 +149,7 @@ class _SVG {
|
|||
String get ellipse2 => "assets/svg/Ellipse-42.svg";
|
||||
|
||||
String get bitcoin => "assets/svg/coin_icons/Bitcoin.svg";
|
||||
String get litecoin => "assets/svg/coin_icons/Litecoin.svg";
|
||||
String get bitcoincash => "assets/svg/coin_icons/Bitcoincash.svg";
|
||||
String get dogecoin => "assets/svg/coin_icons/Dogecoin.svg";
|
||||
String get epicCash => "assets/svg/coin_icons/EpicCash.svg";
|
||||
|
@ -173,6 +174,9 @@ class _SVG {
|
|||
switch (coin) {
|
||||
case Coin.bitcoin:
|
||||
return bitcoin;
|
||||
case Coin.litecoin:
|
||||
case Coin.litecoinTestNet:
|
||||
return litecoin;
|
||||
case Coin.bitcoincash:
|
||||
return bitcoincash;
|
||||
case Coin.dogecoin:
|
||||
|
@ -210,6 +214,7 @@ class _PNG {
|
|||
String get firo => "assets/images/firo.png";
|
||||
String get dogecoin => "assets/images/doge.png";
|
||||
String get bitcoin => "assets/images/bitcoin.png";
|
||||
String get litecoin => "assets/images/litecoin.png";
|
||||
String get epicCash => "assets/images/epic-cash.png";
|
||||
String get bitcoincash => "assets/images/bitcoincash.png";
|
||||
String get namecoin => "assets/images/namecoin.png";
|
||||
|
@ -219,6 +224,9 @@ class _PNG {
|
|||
case Coin.bitcoin:
|
||||
case Coin.bitcoinTestNet:
|
||||
return bitcoin;
|
||||
case Coin.litecoin:
|
||||
case Coin.litecoinTestNet:
|
||||
return litecoin;
|
||||
case Coin.bitcoincash:
|
||||
case Coin.bitcoincashTestnet:
|
||||
return bitcoincash;
|
||||
|
|
|
@ -7,6 +7,10 @@ Uri getBlockExplorerTransactionUrlFor({
|
|||
switch (coin) {
|
||||
case Coin.bitcoin:
|
||||
return Uri.parse("https://chain.so/tx/BTC/$txid");
|
||||
case Coin.litecoin:
|
||||
return Uri.parse("https://chain.so/tx/LTC/$txid");
|
||||
case Coin.litecoinTestNet:
|
||||
return Uri.parse("https://chain.so/tx/LTCTEST/$txid");
|
||||
case Coin.bitcoinTestNet:
|
||||
return Uri.parse("https://chain.so/tx/BTCTEST/$txid");
|
||||
case Coin.dogecoin:
|
||||
|
|
|
@ -48,6 +48,8 @@ abstract class Constants {
|
|||
final List<int> values = [];
|
||||
switch (coin) {
|
||||
case Coin.bitcoin:
|
||||
case Coin.litecoin:
|
||||
case Coin.litecoinTestNet:
|
||||
case Coin.bitcoincash:
|
||||
case Coin.bitcoincashTestnet:
|
||||
case Coin.dogecoin:
|
||||
|
@ -85,6 +87,10 @@ abstract class Constants {
|
|||
case Coin.dogecoinTestNet:
|
||||
return 60;
|
||||
|
||||
case Coin.litecoin:
|
||||
case Coin.litecoinTestNet:
|
||||
return 150;
|
||||
|
||||
case Coin.firo:
|
||||
case Coin.firoTestNet:
|
||||
return 150;
|
||||
|
|
|
@ -9,6 +9,7 @@ abstract class DefaultNodes {
|
|||
|
||||
static List<NodeModel> get all => [
|
||||
bitcoin,
|
||||
litecoin,
|
||||
dogecoin,
|
||||
firo,
|
||||
monero,
|
||||
|
@ -17,6 +18,7 @@ abstract class DefaultNodes {
|
|||
namecoin,
|
||||
wownero,
|
||||
bitcoinTestnet,
|
||||
litecoinTestNet,
|
||||
bitcoincashTestnet,
|
||||
dogecoinTestnet,
|
||||
firoTestnet,
|
||||
|
@ -34,6 +36,30 @@ abstract class DefaultNodes {
|
|||
isDown: false,
|
||||
);
|
||||
|
||||
static NodeModel get litecoin => NodeModel(
|
||||
host: "electrum1.cipig.net",
|
||||
port: 20063,
|
||||
name: defaultName,
|
||||
id: _nodeId(Coin.litecoin),
|
||||
useSSL: true,
|
||||
enabled: true,
|
||||
coinName: Coin.litecoin.name,
|
||||
isFailover: true,
|
||||
isDown: false,
|
||||
);
|
||||
|
||||
static NodeModel get litecoinTestNet => NodeModel(
|
||||
host: "electrum.ltc.xurious.com",
|
||||
port: 51002,
|
||||
name: defaultName,
|
||||
id: _nodeId(Coin.litecoinTestNet),
|
||||
useSSL: true,
|
||||
enabled: true,
|
||||
coinName: Coin.litecoinTestNet.name,
|
||||
isFailover: true,
|
||||
isDown: false,
|
||||
);
|
||||
|
||||
static NodeModel get bitcoincash => NodeModel(
|
||||
host: "bitcoincash.stackwallet.com",
|
||||
port: 50002,
|
||||
|
@ -171,6 +197,9 @@ abstract class DefaultNodes {
|
|||
case Coin.bitcoin:
|
||||
return bitcoin;
|
||||
|
||||
case Coin.litecoin:
|
||||
return litecoin;
|
||||
|
||||
case Coin.bitcoincash:
|
||||
return bitcoincash;
|
||||
|
||||
|
@ -195,6 +224,9 @@ abstract class DefaultNodes {
|
|||
case Coin.bitcoinTestNet:
|
||||
return bitcoinTestnet;
|
||||
|
||||
case Coin.litecoinTestNet:
|
||||
return litecoinTestNet;
|
||||
|
||||
case Coin.bitcoincashTestnet:
|
||||
return bitcoincashTestnet;
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as btc;
|
||||
import 'package:stackwallet/services/coins/litecoin/litecoin_wallet.dart'
|
||||
as ltc;
|
||||
import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'
|
||||
as bch;
|
||||
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'
|
||||
|
@ -22,10 +24,13 @@ enum Coin {
|
|||
namecoin,
|
||||
|
||||
///
|
||||
litecoin,
|
||||
|
||||
///
|
||||
///
|
||||
|
||||
bitcoinTestNet,
|
||||
litecoinTestNet,
|
||||
bitcoincashTestnet,
|
||||
dogecoinTestNet,
|
||||
firoTestNet,
|
||||
|
@ -39,6 +44,8 @@ extension CoinExt on Coin {
|
|||
switch (this) {
|
||||
case Coin.bitcoin:
|
||||
return "Bitcoin";
|
||||
case Coin.litecoin:
|
||||
return "Litecoin";
|
||||
case Coin.bitcoincash:
|
||||
return "Bitcoin Cash";
|
||||
case Coin.dogecoin:
|
||||
|
@ -55,6 +62,8 @@ extension CoinExt on Coin {
|
|||
return "Namecoin";
|
||||
case Coin.bitcoinTestNet:
|
||||
return "tBitcoin";
|
||||
case Coin.litecoinTestNet:
|
||||
return "tLitecoin";
|
||||
case Coin.bitcoincashTestnet:
|
||||
return "tBitcoin Cash";
|
||||
case Coin.firoTestNet:
|
||||
|
@ -68,6 +77,8 @@ extension CoinExt on Coin {
|
|||
switch (this) {
|
||||
case Coin.bitcoin:
|
||||
return "BTC";
|
||||
case Coin.litecoin:
|
||||
return "LTC";
|
||||
case Coin.bitcoincash:
|
||||
return "BCH";
|
||||
case Coin.dogecoin:
|
||||
|
@ -84,6 +95,8 @@ extension CoinExt on Coin {
|
|||
return "NMC";
|
||||
case Coin.bitcoinTestNet:
|
||||
return "tBTC";
|
||||
case Coin.litecoinTestNet:
|
||||
return "tLTC";
|
||||
case Coin.bitcoincashTestnet:
|
||||
return "tBCH";
|
||||
case Coin.firoTestNet:
|
||||
|
@ -97,6 +110,8 @@ extension CoinExt on Coin {
|
|||
switch (this) {
|
||||
case Coin.bitcoin:
|
||||
return "bitcoin";
|
||||
case Coin.litecoin:
|
||||
return "litecoin";
|
||||
case Coin.bitcoincash:
|
||||
return "bitcoincash";
|
||||
case Coin.dogecoin:
|
||||
|
@ -114,6 +129,8 @@ extension CoinExt on Coin {
|
|||
return "namecoin";
|
||||
case Coin.bitcoinTestNet:
|
||||
return "bitcoin";
|
||||
case Coin.litecoinTestNet:
|
||||
return "litecoin";
|
||||
case Coin.bitcoincashTestnet:
|
||||
return "bitcoincash";
|
||||
case Coin.firoTestNet:
|
||||
|
@ -126,11 +143,13 @@ extension CoinExt on Coin {
|
|||
bool get isElectrumXCoin {
|
||||
switch (this) {
|
||||
case Coin.bitcoin:
|
||||
case Coin.litecoin:
|
||||
case Coin.bitcoincash:
|
||||
case Coin.dogecoin:
|
||||
case Coin.firo:
|
||||
case Coin.namecoin:
|
||||
case Coin.bitcoinTestNet:
|
||||
case Coin.litecoinTestNet:
|
||||
case Coin.bitcoincashTestnet:
|
||||
case Coin.firoTestNet:
|
||||
case Coin.dogecoinTestNet:
|
||||
|
@ -149,6 +168,10 @@ extension CoinExt on Coin {
|
|||
case Coin.bitcoinTestNet:
|
||||
return btc.MINIMUM_CONFIRMATIONS;
|
||||
|
||||
case Coin.litecoin:
|
||||
case Coin.litecoinTestNet:
|
||||
return ltc.MINIMUM_CONFIRMATIONS;
|
||||
|
||||
case Coin.bitcoincash:
|
||||
case Coin.bitcoincashTestnet:
|
||||
return bch.MINIMUM_CONFIRMATIONS;
|
||||
|
@ -182,6 +205,10 @@ Coin coinFromPrettyName(String name) {
|
|||
case "bitcoin":
|
||||
return Coin.bitcoin;
|
||||
|
||||
case "Litecoin":
|
||||
case "litecoin":
|
||||
return Coin.litecoin;
|
||||
|
||||
case "Bitcoincash":
|
||||
case "bitcoincash":
|
||||
case "Bitcoin Cash":
|
||||
|
@ -212,6 +239,12 @@ Coin coinFromPrettyName(String name) {
|
|||
case "bitcoinTestNet":
|
||||
return Coin.bitcoinTestNet;
|
||||
|
||||
case "Litecoin Testnet":
|
||||
case "tlitecoin":
|
||||
case "litecoinTestNet":
|
||||
case "tLitecoin":
|
||||
return Coin.litecoinTestNet;
|
||||
|
||||
case "Bitcoincash Testnet":
|
||||
case "tBitcoin Cash":
|
||||
case "Bitcoin Cash Testnet":
|
||||
|
@ -243,6 +276,8 @@ Coin coinFromTickerCaseInsensitive(String ticker) {
|
|||
switch (ticker.toLowerCase()) {
|
||||
case "btc":
|
||||
return Coin.bitcoin;
|
||||
case "ltc":
|
||||
return Coin.litecoin;
|
||||
case "bch":
|
||||
return Coin.bitcoincash;
|
||||
case "doge":
|
||||
|
|
|
@ -181,6 +181,7 @@ class CoinThemeColor {
|
|||
const CoinThemeColor();
|
||||
|
||||
Color get bitcoin => const Color(0xFFFCC17B);
|
||||
Color get litecoin => const Color(0xFF7FA6E1);
|
||||
Color get bitcoincash => const Color(0xFF7BCFB8);
|
||||
Color get firo => const Color(0xFFFF897A);
|
||||
Color get dogecoin => const Color(0xFFFFE079);
|
||||
|
@ -194,6 +195,9 @@ class CoinThemeColor {
|
|||
case Coin.bitcoin:
|
||||
case Coin.bitcoinTestNet:
|
||||
return bitcoin;
|
||||
case Coin.litecoin:
|
||||
case Coin.litecoinTestNet:
|
||||
return litecoin;
|
||||
case Coin.bitcoincash:
|
||||
case Coin.bitcoincashTestnet:
|
||||
return bitcoincash;
|
||||
|
|
|
@ -1406,6 +1406,9 @@ class StackColors extends ThemeExtension<StackColors> {
|
|||
case Coin.bitcoin:
|
||||
case Coin.bitcoinTestNet:
|
||||
return _coin.bitcoin;
|
||||
case Coin.litecoin:
|
||||
case Coin.litecoinTestNet:
|
||||
return _coin.litecoin;
|
||||
case Coin.bitcoincash:
|
||||
case Coin.bitcoincashTestnet:
|
||||
return _coin.bitcoincash;
|
||||
|
|
43
pubspec.lock
43
pubspec.lock
|
@ -42,7 +42,7 @@ packages:
|
|||
name: archive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.11"
|
||||
version: "3.3.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -63,7 +63,7 @@ packages:
|
|||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.8.2"
|
||||
version: "2.9.0"
|
||||
barcode_scan2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -190,14 +190,7 @@ packages:
|
|||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
version: "1.2.1"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -211,7 +204,7 @@ packages:
|
|||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -281,7 +274,7 @@ packages:
|
|||
name: coverage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.5.0"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -435,7 +428,7 @@ packages:
|
|||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -864,21 +857,21 @@ packages:
|
|||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.11"
|
||||
version: "0.12.12"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.4"
|
||||
version: "0.1.5"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
version: "1.8.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -990,7 +983,7 @@ packages:
|
|||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.1"
|
||||
version: "1.8.2"
|
||||
path_drawing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1366,7 +1359,7 @@ packages:
|
|||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
version: "1.9.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1424,35 +1417,35 @@ packages:
|
|||
name: sync_http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
version: "0.3.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
test:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.21.1"
|
||||
version: "1.21.4"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.9"
|
||||
version: "0.4.12"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.13"
|
||||
version: "0.4.16"
|
||||
time:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1501,7 +1494,7 @@ packages:
|
|||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.3.1"
|
||||
universal_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1585,7 +1578,7 @@ packages:
|
|||
name: vm_service
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.2.2"
|
||||
version: "9.0.0"
|
||||
wakelock:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
@ -196,6 +196,7 @@ flutter:
|
|||
- assets/images/monero.png
|
||||
- assets/images/wownero.png
|
||||
- assets/images/firo.png
|
||||
- assets/images/litecoin.png
|
||||
- assets/images/doge.png
|
||||
- assets/images/bitcoin.png
|
||||
- assets/images/epic-cash.png
|
||||
|
@ -310,6 +311,7 @@ flutter:
|
|||
- assets/svg/exit-desktop.svg
|
||||
# coin icons
|
||||
- assets/svg/coin_icons/Bitcoin.svg
|
||||
- assets/svg/coin_icons/Litecoin.svg
|
||||
- assets/svg/coin_icons/Bitcoincash.svg
|
||||
- assets/svg/coin_icons/Dogecoin.svg
|
||||
- assets/svg/coin_icons/EpicCash.svg
|
||||
|
|
|
@ -26,7 +26,7 @@ void main() {
|
|||
|
||||
when(client.get(
|
||||
Uri.parse(
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
})).thenAnswer((_) async => Response(
|
||||
|
@ -39,10 +39,10 @@ void main() {
|
|||
final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
|
||||
|
||||
expect(price.toString(),
|
||||
'{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
|
||||
'{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
|
||||
verify(client.get(
|
||||
Uri.parse(
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
headers: {'Content-Type': 'application/json'})).called(1);
|
||||
|
||||
verifyNoMoreInteractions(client);
|
||||
|
@ -53,7 +53,7 @@ void main() {
|
|||
|
||||
when(client.get(
|
||||
Uri.parse(
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
})).thenAnswer((_) async => Response(
|
||||
|
@ -71,12 +71,12 @@ void main() {
|
|||
await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
|
||||
|
||||
expect(cachedPrice.toString(),
|
||||
'{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
|
||||
'{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
|
||||
|
||||
// verify only called once during filling of cache
|
||||
verify(client.get(
|
||||
Uri.parse(
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
headers: {'Content-Type': 'application/json'})).called(1);
|
||||
|
||||
verifyNoMoreInteractions(client);
|
||||
|
@ -87,7 +87,7 @@ void main() {
|
|||
|
||||
when(client.get(
|
||||
Uri.parse(
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
})).thenAnswer((_) async => Response(
|
||||
|
@ -100,7 +100,7 @@ void main() {
|
|||
final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
|
||||
|
||||
expect(price.toString(),
|
||||
'{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
|
||||
'{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
|
||||
});
|
||||
|
||||
test("no internet available", () async {
|
||||
|
@ -108,7 +108,7 @@ void main() {
|
|||
|
||||
when(client.get(
|
||||
Uri.parse(
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
})).thenThrow(const SocketException(
|
||||
|
@ -120,7 +120,7 @@ void main() {
|
|||
final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
|
||||
|
||||
expect(price.toString(),
|
||||
'{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
|
||||
'{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
|
Loading…
Reference in a new issue