Merge pull request #180 from cypherstack/add-litecoin

Add litecoin
This commit is contained in:
Marco Salazar 2022-10-28 13:15:26 -06:00 committed by GitHub
commit 5de8b44d5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 4048 additions and 86 deletions

BIN
assets/images/litecoin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

View 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

View file

@ -68,7 +68,7 @@ final openedFromSWBFileStringStateProvider =
void main() async { void main() async {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized(); WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
GoogleFonts.config.allowRuntimeFetching = false; GoogleFonts.config.allowRuntimeFetching = false;
if(Platform.isIOS){ if (Platform.isIOS) {
Util.libraryPath = await getLibraryDirectory(); Util.libraryPath = await getLibraryDirectory();
} }
@ -209,56 +209,59 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
bool didLoad = false; bool didLoad = false;
Future<void> load() async { Future<void> load() async {
if (didLoad) { try {
return; 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;
} }
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);
} }
} }

View file

@ -52,11 +52,13 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:
case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.litecoin:
case Coin.dogecoin: case Coin.dogecoin:
case Coin.epicCash: case Coin.epicCash:
case Coin.firo: case Coin.firo:
case Coin.namecoin: case Coin.namecoin:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
case Coin.litecoinTestNet:
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
case Coin.firoTestNet: case Coin.firoTestNet:

View file

@ -531,11 +531,13 @@ class _NodeFormState extends ConsumerState<NodeForm> {
// TODO: which coin servers can have username and password? // TODO: which coin servers can have username and password?
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:
case Coin.litecoin:
case Coin.dogecoin: case Coin.dogecoin:
case Coin.firo: case Coin.firo:
case Coin.namecoin: case Coin.namecoin:
case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
case Coin.litecoinTestNet:
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
case Coin.firoTestNet: case Coin.firoTestNet:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:

View file

@ -98,6 +98,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
break; break;
case Coin.bitcoin: case Coin.bitcoin:
case Coin.litecoin:
case Coin.dogecoin: case Coin.dogecoin:
case Coin.firo: case Coin.firo:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
@ -105,6 +106,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.namecoin: case Coin.namecoin:
case Coin.litecoinTestNet:
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
final client = ElectrumX( final client = ElectrumX(
host: node!.host, host: node!.host,

View file

@ -15,6 +15,8 @@ import 'package:stackwallet/services/transaction_notification_tracker.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/prefs.dart'; import 'package:stackwallet/utilities/prefs.dart';
import 'litecoin/litecoin_wallet.dart';
abstract class CoinServiceAPI { abstract class CoinServiceAPI {
CoinServiceAPI(); CoinServiceAPI();
@ -90,6 +92,26 @@ abstract class CoinServiceAPI {
tracker: tracker, 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: case Coin.bitcoinTestNet:
return BitcoinWallet( return BitcoinWallet(
walletId: walletId, walletId: walletId,

File diff suppressed because it is too large Load diff

View file

@ -87,7 +87,7 @@ class PriceAPI {
Map<Coin, Tuple2<Decimal, double>> result = {}; Map<Coin, Tuple2<Decimal, double>> result = {};
try { try {
final uri = Uri.parse( 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( // 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"); // "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");

View file

@ -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/bitcoincash/bitcoincash_wallet.dart';
import 'package:stackwallet/services/coins/dogecoin/dogecoin_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/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/services/coins/namecoin/namecoin_wallet.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/logger.dart';
@ -42,6 +43,8 @@ class AddressUtils {
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:
return Address.validateAddress(address, bitcoin); return Address.validateAddress(address, bitcoin);
case Coin.litecoin:
return Address.validateAddress(address, litecoin);
case Coin.bitcoincash: case Coin.bitcoincash:
return Address.validateAddress(address, bitcoincash); return Address.validateAddress(address, bitcoincash);
case Coin.dogecoin: case Coin.dogecoin:
@ -60,6 +63,8 @@ class AddressUtils {
return Address.validateAddress(address, namecoin, namecoin.bech32!); return Address.validateAddress(address, namecoin, namecoin.bech32!);
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return Address.validateAddress(address, testnet); return Address.validateAddress(address, testnet);
case Coin.litecoinTestNet:
return Address.validateAddress(address, litecointestnet);
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
return Address.validateAddress(address, bitcoincashtestnet); return Address.validateAddress(address, bitcoincashtestnet);
case Coin.firoTestNet: case Coin.firoTestNet:

View file

@ -149,6 +149,7 @@ class _SVG {
String get ellipse2 => "assets/svg/Ellipse-42.svg"; String get ellipse2 => "assets/svg/Ellipse-42.svg";
String get bitcoin => "assets/svg/coin_icons/Bitcoin.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 bitcoincash => "assets/svg/coin_icons/Bitcoincash.svg";
String get dogecoin => "assets/svg/coin_icons/Dogecoin.svg"; String get dogecoin => "assets/svg/coin_icons/Dogecoin.svg";
String get epicCash => "assets/svg/coin_icons/EpicCash.svg"; String get epicCash => "assets/svg/coin_icons/EpicCash.svg";
@ -173,6 +174,9 @@ class _SVG {
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:
return bitcoin; return bitcoin;
case Coin.litecoin:
case Coin.litecoinTestNet:
return litecoin;
case Coin.bitcoincash: case Coin.bitcoincash:
return bitcoincash; return bitcoincash;
case Coin.dogecoin: case Coin.dogecoin:
@ -210,6 +214,7 @@ class _PNG {
String get firo => "assets/images/firo.png"; String get firo => "assets/images/firo.png";
String get dogecoin => "assets/images/doge.png"; String get dogecoin => "assets/images/doge.png";
String get bitcoin => "assets/images/bitcoin.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 epicCash => "assets/images/epic-cash.png";
String get bitcoincash => "assets/images/bitcoincash.png"; String get bitcoincash => "assets/images/bitcoincash.png";
String get namecoin => "assets/images/namecoin.png"; String get namecoin => "assets/images/namecoin.png";
@ -219,6 +224,9 @@ class _PNG {
case Coin.bitcoin: case Coin.bitcoin:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return bitcoin; return bitcoin;
case Coin.litecoin:
case Coin.litecoinTestNet:
return litecoin;
case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
return bitcoincash; return bitcoincash;

View file

@ -7,6 +7,10 @@ Uri getBlockExplorerTransactionUrlFor({
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:
return Uri.parse("https://chain.so/tx/BTC/$txid"); 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: case Coin.bitcoinTestNet:
return Uri.parse("https://chain.so/tx/BTCTEST/$txid"); return Uri.parse("https://chain.so/tx/BTCTEST/$txid");
case Coin.dogecoin: case Coin.dogecoin:

View file

@ -48,6 +48,8 @@ abstract class Constants {
final List<int> values = []; final List<int> values = [];
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:
case Coin.litecoin:
case Coin.litecoinTestNet:
case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
case Coin.dogecoin: case Coin.dogecoin:
@ -85,6 +87,10 @@ abstract class Constants {
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
return 60; return 60;
case Coin.litecoin:
case Coin.litecoinTestNet:
return 150;
case Coin.firo: case Coin.firo:
case Coin.firoTestNet: case Coin.firoTestNet:
return 150; return 150;

View file

@ -9,6 +9,7 @@ abstract class DefaultNodes {
static List<NodeModel> get all => [ static List<NodeModel> get all => [
bitcoin, bitcoin,
litecoin,
dogecoin, dogecoin,
firo, firo,
monero, monero,
@ -17,6 +18,7 @@ abstract class DefaultNodes {
namecoin, namecoin,
wownero, wownero,
bitcoinTestnet, bitcoinTestnet,
litecoinTestNet,
bitcoincashTestnet, bitcoincashTestnet,
dogecoinTestnet, dogecoinTestnet,
firoTestnet, firoTestnet,
@ -34,6 +36,30 @@ abstract class DefaultNodes {
isDown: false, 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( static NodeModel get bitcoincash => NodeModel(
host: "bitcoincash.stackwallet.com", host: "bitcoincash.stackwallet.com",
port: 50002, port: 50002,
@ -171,6 +197,9 @@ abstract class DefaultNodes {
case Coin.bitcoin: case Coin.bitcoin:
return bitcoin; return bitcoin;
case Coin.litecoin:
return litecoin;
case Coin.bitcoincash: case Coin.bitcoincash:
return bitcoincash; return bitcoincash;
@ -195,6 +224,9 @@ abstract class DefaultNodes {
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return bitcoinTestnet; return bitcoinTestnet;
case Coin.litecoinTestNet:
return litecoinTestNet;
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
return bitcoincashTestnet; return bitcoincashTestnet;

View file

@ -1,4 +1,6 @@
import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as btc; 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' import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'
as bch; as bch;
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart' import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'
@ -22,10 +24,13 @@ enum Coin {
namecoin, namecoin,
/// ///
litecoin,
/// ///
/// ///
bitcoinTestNet, bitcoinTestNet,
litecoinTestNet,
bitcoincashTestnet, bitcoincashTestnet,
dogecoinTestNet, dogecoinTestNet,
firoTestNet, firoTestNet,
@ -39,6 +44,8 @@ extension CoinExt on Coin {
switch (this) { switch (this) {
case Coin.bitcoin: case Coin.bitcoin:
return "Bitcoin"; return "Bitcoin";
case Coin.litecoin:
return "Litecoin";
case Coin.bitcoincash: case Coin.bitcoincash:
return "Bitcoin Cash"; return "Bitcoin Cash";
case Coin.dogecoin: case Coin.dogecoin:
@ -55,6 +62,8 @@ extension CoinExt on Coin {
return "Namecoin"; return "Namecoin";
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return "tBitcoin"; return "tBitcoin";
case Coin.litecoinTestNet:
return "tLitecoin";
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
return "tBitcoin Cash"; return "tBitcoin Cash";
case Coin.firoTestNet: case Coin.firoTestNet:
@ -68,6 +77,8 @@ extension CoinExt on Coin {
switch (this) { switch (this) {
case Coin.bitcoin: case Coin.bitcoin:
return "BTC"; return "BTC";
case Coin.litecoin:
return "LTC";
case Coin.bitcoincash: case Coin.bitcoincash:
return "BCH"; return "BCH";
case Coin.dogecoin: case Coin.dogecoin:
@ -84,6 +95,8 @@ extension CoinExt on Coin {
return "NMC"; return "NMC";
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return "tBTC"; return "tBTC";
case Coin.litecoinTestNet:
return "tLTC";
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
return "tBCH"; return "tBCH";
case Coin.firoTestNet: case Coin.firoTestNet:
@ -97,6 +110,8 @@ extension CoinExt on Coin {
switch (this) { switch (this) {
case Coin.bitcoin: case Coin.bitcoin:
return "bitcoin"; return "bitcoin";
case Coin.litecoin:
return "litecoin";
case Coin.bitcoincash: case Coin.bitcoincash:
return "bitcoincash"; return "bitcoincash";
case Coin.dogecoin: case Coin.dogecoin:
@ -114,6 +129,8 @@ extension CoinExt on Coin {
return "namecoin"; return "namecoin";
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return "bitcoin"; return "bitcoin";
case Coin.litecoinTestNet:
return "litecoin";
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
return "bitcoincash"; return "bitcoincash";
case Coin.firoTestNet: case Coin.firoTestNet:
@ -126,11 +143,13 @@ extension CoinExt on Coin {
bool get isElectrumXCoin { bool get isElectrumXCoin {
switch (this) { switch (this) {
case Coin.bitcoin: case Coin.bitcoin:
case Coin.litecoin:
case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.dogecoin: case Coin.dogecoin:
case Coin.firo: case Coin.firo:
case Coin.namecoin: case Coin.namecoin:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
case Coin.litecoinTestNet:
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
case Coin.firoTestNet: case Coin.firoTestNet:
case Coin.dogecoinTestNet: case Coin.dogecoinTestNet:
@ -149,6 +168,10 @@ extension CoinExt on Coin {
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return btc.MINIMUM_CONFIRMATIONS; return btc.MINIMUM_CONFIRMATIONS;
case Coin.litecoin:
case Coin.litecoinTestNet:
return ltc.MINIMUM_CONFIRMATIONS;
case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
return bch.MINIMUM_CONFIRMATIONS; return bch.MINIMUM_CONFIRMATIONS;
@ -182,6 +205,10 @@ Coin coinFromPrettyName(String name) {
case "bitcoin": case "bitcoin":
return Coin.bitcoin; return Coin.bitcoin;
case "Litecoin":
case "litecoin":
return Coin.litecoin;
case "Bitcoincash": case "Bitcoincash":
case "bitcoincash": case "bitcoincash":
case "Bitcoin Cash": case "Bitcoin Cash":
@ -212,6 +239,12 @@ Coin coinFromPrettyName(String name) {
case "bitcoinTestNet": case "bitcoinTestNet":
return Coin.bitcoinTestNet; return Coin.bitcoinTestNet;
case "Litecoin Testnet":
case "tlitecoin":
case "litecoinTestNet":
case "tLitecoin":
return Coin.litecoinTestNet;
case "Bitcoincash Testnet": case "Bitcoincash Testnet":
case "tBitcoin Cash": case "tBitcoin Cash":
case "Bitcoin Cash Testnet": case "Bitcoin Cash Testnet":
@ -243,6 +276,8 @@ Coin coinFromTickerCaseInsensitive(String ticker) {
switch (ticker.toLowerCase()) { switch (ticker.toLowerCase()) {
case "btc": case "btc":
return Coin.bitcoin; return Coin.bitcoin;
case "ltc":
return Coin.litecoin;
case "bch": case "bch":
return Coin.bitcoincash; return Coin.bitcoincash;
case "doge": case "doge":

View file

@ -181,6 +181,7 @@ class CoinThemeColor {
const CoinThemeColor(); const CoinThemeColor();
Color get bitcoin => const Color(0xFFFCC17B); Color get bitcoin => const Color(0xFFFCC17B);
Color get litecoin => const Color(0xFF7FA6E1);
Color get bitcoincash => const Color(0xFF7BCFB8); Color get bitcoincash => const Color(0xFF7BCFB8);
Color get firo => const Color(0xFFFF897A); Color get firo => const Color(0xFFFF897A);
Color get dogecoin => const Color(0xFFFFE079); Color get dogecoin => const Color(0xFFFFE079);
@ -194,6 +195,9 @@ class CoinThemeColor {
case Coin.bitcoin: case Coin.bitcoin:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return bitcoin; return bitcoin;
case Coin.litecoin:
case Coin.litecoinTestNet:
return litecoin;
case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
return bitcoincash; return bitcoincash;

View file

@ -1406,6 +1406,9 @@ class StackColors extends ThemeExtension<StackColors> {
case Coin.bitcoin: case Coin.bitcoin:
case Coin.bitcoinTestNet: case Coin.bitcoinTestNet:
return _coin.bitcoin; return _coin.bitcoin;
case Coin.litecoin:
case Coin.litecoinTestNet:
return _coin.litecoin;
case Coin.bitcoincash: case Coin.bitcoincash:
case Coin.bitcoincashTestnet: case Coin.bitcoincashTestnet:
return _coin.bitcoincash; return _coin.bitcoincash;

View file

@ -42,7 +42,7 @@ packages:
name: archive name: archive
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.1.11" version: "3.3.0"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -63,7 +63,7 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.2" version: "2.9.0"
barcode_scan2: barcode_scan2:
dependency: "direct main" dependency: "direct main"
description: description:
@ -190,14 +190,7 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.1"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
@ -211,7 +204,7 @@ packages:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
code_builder: code_builder:
dependency: transitive dependency: transitive
description: description:
@ -281,7 +274,7 @@ packages:
name: coverage name: coverage
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.5.0"
cross_file: cross_file:
dependency: transitive dependency: transitive
description: description:
@ -435,7 +428,7 @@ packages:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.1"
ffi: ffi:
dependency: "direct main" dependency: "direct main"
description: description:
@ -864,21 +857,21 @@ packages:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.11" version: "0.12.12"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.4" version: "0.1.5"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -990,7 +983,7 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.1" version: "1.8.2"
path_drawing: path_drawing:
dependency: transitive dependency: transitive
description: description:
@ -1366,7 +1359,7 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.2" version: "1.9.0"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -1424,35 +1417,35 @@ packages:
name: sync_http name: sync_http
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.0" version: "0.3.1"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.1"
test: test:
dependency: transitive dependency: transitive
description: description:
name: test name: test
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.21.1" version: "1.21.4"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.9" version: "0.4.12"
test_core: test_core:
dependency: transitive dependency: transitive
description: description:
name: test_core name: test_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.13" version: "0.4.16"
time: time:
dependency: transitive dependency: transitive
description: description:
@ -1501,7 +1494,7 @@ packages:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.1"
universal_io: universal_io:
dependency: transitive dependency: transitive
description: description:
@ -1585,7 +1578,7 @@ packages:
name: vm_service name: vm_service
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "8.2.2" version: "9.0.0"
wakelock: wakelock:
dependency: "direct main" dependency: "direct main"
description: description:

View file

@ -196,6 +196,7 @@ flutter:
- assets/images/monero.png - assets/images/monero.png
- assets/images/wownero.png - assets/images/wownero.png
- assets/images/firo.png - assets/images/firo.png
- assets/images/litecoin.png
- assets/images/doge.png - assets/images/doge.png
- assets/images/bitcoin.png - assets/images/bitcoin.png
- assets/images/epic-cash.png - assets/images/epic-cash.png
@ -310,6 +311,7 @@ flutter:
- assets/svg/exit-desktop.svg - assets/svg/exit-desktop.svg
# coin icons # coin icons
- assets/svg/coin_icons/Bitcoin.svg - assets/svg/coin_icons/Bitcoin.svg
- assets/svg/coin_icons/Litecoin.svg
- assets/svg/coin_icons/Bitcoincash.svg - assets/svg/coin_icons/Bitcoincash.svg
- assets/svg/coin_icons/Dogecoin.svg - assets/svg/coin_icons/Dogecoin.svg
- assets/svg/coin_icons/EpicCash.svg - assets/svg/coin_icons/EpicCash.svg

View file

@ -26,7 +26,7 @@ void main() {
when(client.get( when(client.get(
Uri.parse( 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: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
})).thenAnswer((_) async => Response( })).thenAnswer((_) async => Response(
@ -39,10 +39,10 @@ void main() {
final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc"); final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
expect(price.toString(), 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( verify(client.get(
Uri.parse( 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); headers: {'Content-Type': 'application/json'})).called(1);
verifyNoMoreInteractions(client); verifyNoMoreInteractions(client);
@ -53,7 +53,7 @@ void main() {
when(client.get( when(client.get(
Uri.parse( 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: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
})).thenAnswer((_) async => Response( })).thenAnswer((_) async => Response(
@ -71,12 +71,12 @@ void main() {
await priceAPI.getPricesAnd24hChange(baseCurrency: "btc"); await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
expect(cachedPrice.toString(), 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 only called once during filling of cache
verify(client.get( verify(client.get(
Uri.parse( 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); headers: {'Content-Type': 'application/json'})).called(1);
verifyNoMoreInteractions(client); verifyNoMoreInteractions(client);
@ -87,7 +87,7 @@ void main() {
when(client.get( when(client.get(
Uri.parse( 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: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
})).thenAnswer((_) async => Response( })).thenAnswer((_) async => Response(
@ -100,7 +100,7 @@ void main() {
final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc"); final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
expect(price.toString(), 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 { test("no internet available", () async {
@ -108,7 +108,7 @@ void main() {
when(client.get( when(client.get(
Uri.parse( 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: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
})).thenThrow(const SocketException( })).thenThrow(const SocketException(
@ -120,7 +120,7 @@ void main() {
final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc"); final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
expect(price.toString(), 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 { tearDown(() async {