mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-23 20:09:23 +00:00
Merge branch 'staging' into ui-fixes
This commit is contained in:
commit
a899e97ae2
31 changed files with 1959 additions and 39 deletions
23
.github/workflows/test.yaml
vendored
23
.github/workflows/test.yaml
vendored
|
@ -54,12 +54,31 @@ jobs:
|
|||
Write-Output "::set-output name=SECRET_FILE_FIRO::$secretFileFiro";
|
||||
Write-Output "::set-output name=SECRET_FILE_FIRO_HASH::$($secretFileFiroHash.Hash)";
|
||||
Write-Output "Secret file $secretFileFiro has hash $($secretFileFiroHash.Hash)";
|
||||
|
||||
$secretFileBitcoinCash = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "test/services/coins/bitcoincash/bitcoincash_wallet_test_parameters.dart";
|
||||
$encodedBytes = [System.Convert]::FromBase64String($env:BITCOINCASH_TEST);
|
||||
Set-Content $secretFileBitcoinCash -Value $encodedBytes -AsByteStream;
|
||||
$secretFileBitcoinCashHash = Get-FileHash $secretFileBitcoinCash;
|
||||
Write-Output "::set-output name=SECRET_FILE_BITCOINCASH::$secretFileBitcoinCash";
|
||||
Write-Output "::set-output name=SECRET_FILE_BITCOINCASH_HASH::$($secretFileBitcoinCashHash.Hash)";
|
||||
Write-Output "Secret file $secretFileBitcoinCash has hash $($secretFileBitcoinCashHash.Hash)";
|
||||
|
||||
$secretFileNamecoin = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "test/services/coins/namecoin/namecoin_wallet_test_parameters.dart";
|
||||
$encodedBytes = [System.Convert]::FromBase64String($env:NAMECOIN_TEST);
|
||||
Set-Content $secretFileNamecoin -Value $encodedBytes -AsByteStream;
|
||||
$secretFileNamecoinHash = Get-FileHash $secretFileNamecoin;
|
||||
Write-Output "::set-output name=SECRET_FILE_NAMECOIN::$secretFileNamecoin";
|
||||
Write-Output "::set-output name=SECRET_FILE_NAMECOIN_HASH::$($secretFileNamecoinHash.Hash)";
|
||||
Write-Output "Secret file $secretFileNamecoin has hash $($secretFileNamecoinHash.Hash)";
|
||||
|
||||
shell: pwsh
|
||||
env:
|
||||
CHANGE_NOW: ${{ secrets.CHANGE_NOW }}
|
||||
BITCOIN_TEST: ${{ secrets.BITCOIN_TEST }}
|
||||
DOGECOIN_TEST: ${{ secrets.DOGECOIN_TEST }}
|
||||
FIRO_TEST: ${{ secrets.FIRO_TEST }}
|
||||
BITCOINCASH_TEST: ${{ secrets.BITCOINCASH_TEST }}
|
||||
NAMECOIN_TEST: ${{ secrets.NAMECOIN_TEST }}
|
||||
# - name: Analyze
|
||||
# run: flutter analyze
|
||||
- name: Test
|
||||
|
@ -76,6 +95,8 @@ jobs:
|
|||
Remove-Item -Path $env:BITCOIN_TEST;
|
||||
Remove-Item -Path $env:DOGECOIN_TEST;
|
||||
Remove-Item -Path $env:FIRO_TEST;
|
||||
Remove-Item -Path $env:BITCOINCASH_TEST;
|
||||
Remove-Item -Path $env:NAMECOIN_TEST;
|
||||
shell: pwsh
|
||||
if: always()
|
||||
env:
|
||||
|
@ -83,3 +104,5 @@ jobs:
|
|||
BITCOIN_TEST: ${{ steps.secret-file1.outputs.SECRET_FILE_BITCOIN }}
|
||||
DOGECOIN_TEST: ${{ steps.secret-file1.outputs.SECRET_FILE_DOGECOIN }}
|
||||
FIRO_TEST: ${{ steps.secret-file1.outputs.SECRET_FILE_FIRO }}
|
||||
BITCOINCASH_TEST: ${{ steps.secret-file1.outputs.SECRET_FILE_BITCOINCASH }}
|
||||
NAMECOIN_TEST: ${{ steps.secret-file1.outputs.SECRET_FILE_NAMECOIN }}
|
||||
|
|
7
assets/svg/coin_icons/Wownero.svg
Normal file
7
assets/svg/coin_icons/Wownero.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 23.8456C18.5421 23.8456 23.8456 18.5421 23.8456 12C23.8456 5.45778 18.5421 0.154297 12 0.154297C5.45778 0.154297 0.154297 5.45778 0.154297 12C0.154297 18.5421 5.45778 23.8456 12 23.8456Z" fill="white"/>
|
||||
<path d="M12 24C5.38264 24 0 18.6174 0 12C0 5.38264 5.38264 0 12 0C18.6174 0 24 5.38264 24 12C24 18.6174 18.6174 24 12 24ZM12 0.327974C5.55627 0.327974 0.327974 5.57556 0.327974 12C0.327974 18.4244 5.57556 23.672 12 23.672C18.4244 23.672 23.672 18.4244 23.672 12C23.672 5.57556 18.4437 0.327974 12 0.327974Z" fill="#D0509D"/>
|
||||
<path d="M11.9995 0.154297C6.75195 0.154297 2.29536 3.58838 0.751953 8.31507H6.73266V15.7427L11.961 10.0707H12.0381L17.2664 15.762V8.31507H23.2471C21.7037 3.58838 17.2471 0.154297 11.9995 0.154297Z" fill="#FFCD05"/>
|
||||
<path d="M6.56007 16.1672V8.48875H0.521484L0.598655 8.27653C2.19994 3.31833 6.79158 0 12.0006 0C17.2096 0 21.8012 3.31833 23.4025 8.27653L23.4797 8.48875H17.4411V16.1672L12.0006 10.283L6.56007 16.1672ZM11.9041 9.9164H12.1163L17.1131 15.3376V8.16077H23.036C21.3961 3.47267 16.9974 0.327974 12.0006 0.327974C7.0038 0.327974 2.60509 3.47267 0.965214 8.16077H6.88804V15.3376L11.9041 9.9164Z" fill="#D0509D"/>
|
||||
<path d="M18.2473 18.2508L16.5495 16.418L11.9965 11.4791L7.4434 16.418L5.74565 18.2508V15.762V9.5498H1.59774C1.40482 10.3601 1.28906 11.209 1.28906 12.0964C1.28906 18 6.07363 22.8038 11.9965 22.8038C17.9193 22.8038 22.7039 18.0193 22.7039 12.0964C22.7039 11.2283 22.5881 10.3794 22.3952 9.5498H18.228V15.762V18.2508H18.2473Z" fill="#D0519D"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -1 +1 @@
|
|||
Subproject commit 4bffa40cb60ad3d98cf0ea5b5d819f3f4895dcd6
|
||||
Subproject commit 8e3afd002968d21a3de788569356587a70818022
|
|
@ -8,6 +8,7 @@ import 'package:cw_core/wallet_type.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_libmonero/monero/monero.dart';
|
||||
import 'package:flutter_libmonero/wownero/wownero.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
|
@ -84,7 +85,6 @@ void main() async {
|
|||
appDirectory = (await getLibraryDirectory());
|
||||
}
|
||||
// FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
|
||||
await Hive.initFlutter(appDirectory.path);
|
||||
if (!(Logging.isArmLinux || Logging.isTestEnv)) {
|
||||
final isar = await Isar.open(
|
||||
[LogSchema],
|
||||
|
@ -128,11 +128,14 @@ void main() async {
|
|||
|
||||
Hive.registerAdapter(NodeAdapter());
|
||||
|
||||
Hive.registerAdapter(WalletInfoAdapter());
|
||||
if (!Hive.isAdapterRegistered(WalletInfoAdapter().typeId)) {
|
||||
Hive.registerAdapter(WalletInfoAdapter());
|
||||
}
|
||||
|
||||
Hive.registerAdapter(WalletTypeAdapter());
|
||||
|
||||
Hive.registerAdapter(UnspentCoinsInfoAdapter());
|
||||
await Hive.initFlutter(appDirectory.path);
|
||||
|
||||
await Hive.openBox<dynamic>(DB.boxNameDBInfo);
|
||||
int dbVersion = DB.instance.get<dynamic>(
|
||||
|
@ -143,6 +146,7 @@ void main() async {
|
|||
}
|
||||
|
||||
monero.onStartup();
|
||||
wownero.onStartup();
|
||||
|
||||
await Hive.openBox<dynamic>(DB.boxNameTheme);
|
||||
|
||||
|
|
|
@ -59,7 +59,9 @@ class _NewWalletRecoveryPhraseWarningViewState
|
|||
|
||||
final _numberOfPhraseWords = coin == Coin.monero
|
||||
? Constants.seedPhraseWordCountMonero
|
||||
: Constants.seedPhraseWordCountBip39;
|
||||
: coin == Coin.wownero
|
||||
? 14
|
||||
: Constants.seedPhraseWordCountBip39;
|
||||
|
||||
return MasterScaffold(
|
||||
isDesktop: isDesktop,
|
||||
|
|
|
@ -200,7 +200,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
|
|||
|
||||
// TODO: do actual check to make sure it is a valid mnemonic for monero
|
||||
if (bip39.validateMnemonic(mnemonic) == false &&
|
||||
!(widget.coin == Coin.monero)) {
|
||||
!(widget.coin == Coin.monero || widget.coin == Coin.wownero)) {
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.warning,
|
||||
message: "Invalid seed phrase!",
|
||||
|
|
|
@ -85,7 +85,7 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
|
|||
height: 8,
|
||||
),
|
||||
Text(
|
||||
"You need to send ${amount.toStringAsFixed(coin == Coin.monero ? 12 : 8)} ${coin.ticker}",
|
||||
"You need to send ${amount.toStringAsFixed(coin == Coin.monero ? Constants.satsPerCoinMonero : coin == Coin.wownero ? Constants.satsPerCoinWownero : Constants.satsPerCoin)} ${coin.ticker}",
|
||||
style: STextStyles.itemSubtitle(context),
|
||||
),
|
||||
const SizedBox(
|
||||
|
@ -307,7 +307,11 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
|
|||
"${Format.localizedStringAsFixed(
|
||||
value: snapshot.data!,
|
||||
locale: locale,
|
||||
decimalPlaces: coin == Coin.monero ? 12 : 8,
|
||||
decimalPlaces: coin == Coin.monero
|
||||
? Constants.satsPerCoinMonero
|
||||
: coin == Coin.wownero
|
||||
? Constants.satsPerCoinWownero
|
||||
: Constants.satsPerCoin,
|
||||
)} ${coin.ticker}",
|
||||
style: STextStyles.itemSubtitle(context),
|
||||
);
|
||||
|
|
|
@ -90,6 +90,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
|
|||
break;
|
||||
|
||||
case Coin.monero:
|
||||
case Coin.wownero:
|
||||
try {
|
||||
final uri = Uri.parse(formData.host!);
|
||||
if (uri.scheme.startsWith("http")) {
|
||||
|
@ -384,6 +385,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
|
|||
// strip unused path
|
||||
String address = formData.host!;
|
||||
if (coin == Coin.monero ||
|
||||
coin == Coin.wownero ||
|
||||
coin == Coin.epicCash) {
|
||||
if (address.startsWith("http")) {
|
||||
final uri = Uri.parse(address);
|
||||
|
@ -539,6 +541,7 @@ class _NodeFormState extends ConsumerState<NodeForm> {
|
|||
|
||||
case Coin.epicCash:
|
||||
case Coin.monero:
|
||||
case Coin.wownero:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -699,7 +702,9 @@ class _NodeFormState extends ConsumerState<NodeForm> {
|
|||
focusNode: _hostFocusNode,
|
||||
style: STextStyles.field(context),
|
||||
decoration: standardInputDecoration(
|
||||
(widget.coin != Coin.monero && widget.coin != Coin.epicCash)
|
||||
(widget.coin != Coin.monero &&
|
||||
widget.coin != Coin.wownero &&
|
||||
widget.coin != Coin.epicCash)
|
||||
? "IP address"
|
||||
: "Url",
|
||||
_hostFocusNode,
|
||||
|
@ -880,7 +885,9 @@ class _NodeFormState extends ConsumerState<NodeForm> {
|
|||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (widget.coin != Coin.monero && widget.coin != Coin.epicCash)
|
||||
if (widget.coin != Coin.monero &&
|
||||
widget.coin != Coin.wownero &&
|
||||
widget.coin != Coin.epicCash)
|
||||
Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
|
@ -931,11 +938,15 @@ class _NodeFormState extends ConsumerState<NodeForm> {
|
|||
),
|
||||
],
|
||||
),
|
||||
if (widget.coin != Coin.monero && widget.coin != Coin.epicCash)
|
||||
if (widget.coin != Coin.monero &&
|
||||
widget.coin != Coin.wownero &&
|
||||
widget.coin != Coin.epicCash)
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (widget.coin != Coin.monero && widget.coin != Coin.epicCash)
|
||||
if (widget.coin != Coin.monero &&
|
||||
widget.coin != Coin.wownero &&
|
||||
widget.coin != Coin.epicCash)
|
||||
Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
|
|
|
@ -81,6 +81,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
|
|||
break;
|
||||
|
||||
case Coin.monero:
|
||||
case Coin.wownero:
|
||||
try {
|
||||
final uri = Uri.parse(node!.host);
|
||||
if (uri.scheme.startsWith("http")) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_net
|
|||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/monero/monero_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
|
||||
import 'package:stackwallet/services/event_bus/events/global/blocks_remaining_event.dart';
|
||||
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
|
||||
import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart';
|
||||
|
@ -205,7 +206,7 @@ class _WalletNetworkSettingsViewState
|
|||
.getManager(widget.walletId)
|
||||
.coin;
|
||||
|
||||
if (coin == Coin.monero || coin == Coin.epicCash) {
|
||||
if (coin == Coin.monero || coin == Coin.wownero || coin == Coin.epicCash) {
|
||||
_blocksRemainingSubscription = eventBus.on<BlocksRemainingEvent>().listen(
|
||||
(event) async {
|
||||
if (event.walletId == widget.walletId) {
|
||||
|
@ -271,6 +272,15 @@ class _WalletNetworkSettingsViewState
|
|||
if (_percent < highestPercent) {
|
||||
_percent = highestPercent.clamp(0.0, 1.0);
|
||||
}
|
||||
} else if (coin == Coin.wownero) {
|
||||
double highestPercent = (ref
|
||||
.read(walletsChangeNotifierProvider)
|
||||
.getManager(widget.walletId)
|
||||
.wallet as WowneroWallet)
|
||||
.highestPercentCached;
|
||||
if (_percent < highestPercent) {
|
||||
_percent = highestPercent.clamp(0.0, 1.0);
|
||||
}
|
||||
} else if (coin == Coin.epicCash) {
|
||||
double highestPercent = (ref
|
||||
.read(walletsChangeNotifierProvider)
|
||||
|
@ -545,6 +555,7 @@ class _WalletNetworkSettingsViewState
|
|||
),
|
||||
),
|
||||
if (coin == Coin.monero ||
|
||||
coin == Coin.wownero ||
|
||||
coin == Coin.epicCash)
|
||||
Text(
|
||||
" (Blocks to go: ${_blocksRemaining == -1 ? "?" : _blocksRemaining})",
|
||||
|
|
|
@ -241,7 +241,9 @@ class _TransactionDetailsViewState
|
|||
"$amountPrefix${Format.localizedStringAsFixed(
|
||||
value: coin == Coin.monero
|
||||
? (amount / 10000.toDecimal()).toDecimal()
|
||||
: amount,
|
||||
: coin == Coin.wownero
|
||||
? (amount / 1000.toDecimal()).toDecimal()
|
||||
: amount,
|
||||
locale: ref.watch(
|
||||
localeServiceChangeNotifierProvider
|
||||
.select((value) => value.locale),
|
||||
|
@ -254,7 +256,7 @@ class _TransactionDetailsViewState
|
|||
height: 2,
|
||||
),
|
||||
SelectableText(
|
||||
"${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch(
|
||||
"${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch(
|
||||
localeServiceChangeNotifierProvider
|
||||
.select((value) => value.locale),
|
||||
), decimalPlaces: 2)} ${ref.watch(
|
||||
|
@ -298,14 +300,14 @@ class _TransactionDetailsViewState
|
|||
],
|
||||
),
|
||||
),
|
||||
if (!(coin == Coin.monero &&
|
||||
if (!((coin == Coin.monero || coin == Coin.wownero) &&
|
||||
_transaction.txType.toLowerCase() == "sent") &&
|
||||
!((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
||||
_transaction.subType == "mint"))
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
if (!(coin == Coin.monero &&
|
||||
if (!((coin == Coin.monero || coin == Coin.wownero) &&
|
||||
_transaction.txType.toLowerCase() == "sent") &&
|
||||
!((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
||||
_transaction.subType == "mint"))
|
||||
|
@ -464,7 +466,10 @@ class _TransactionDetailsViewState
|
|||
? Format.localizedStringAsFixed(
|
||||
value: coin == Coin.monero
|
||||
? (fee / 10000.toDecimal()).toDecimal()
|
||||
: fee,
|
||||
: coin == Coin.wownero
|
||||
? (fee / 1000.toDecimal())
|
||||
.toDecimal()
|
||||
: fee,
|
||||
locale: ref.watch(
|
||||
localeServiceChangeNotifierProvider
|
||||
.select((value) => value.locale)),
|
||||
|
@ -473,7 +478,9 @@ class _TransactionDetailsViewState
|
|||
: Format.localizedStringAsFixed(
|
||||
value: coin == Coin.monero
|
||||
? (fee / 10000.toDecimal()).toDecimal()
|
||||
: fee,
|
||||
: coin == Coin.wownero
|
||||
? (fee / 1000.toDecimal()).toDecimal()
|
||||
: fee,
|
||||
locale: ref.watch(
|
||||
localeServiceChangeNotifierProvider
|
||||
.select((value) => value.locale)),
|
||||
|
|
|
@ -755,6 +755,11 @@ class _TransactionSearchViewState
|
|||
.floor()
|
||||
.toBigInt()
|
||||
.toInt();
|
||||
} else if (widget.coin == Coin.wownero) {
|
||||
amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoinWownero))
|
||||
.floor()
|
||||
.toBigInt()
|
||||
.toInt();
|
||||
} else {
|
||||
amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoin))
|
||||
.floor()
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
|
|||
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/monero/monero_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
|
||||
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
|
@ -145,6 +146,14 @@ abstract class CoinServiceAPI {
|
|||
// tracker: tracker,
|
||||
);
|
||||
|
||||
case Coin.wownero:
|
||||
return WowneroWallet(
|
||||
walletId: walletId,
|
||||
walletName: walletName,
|
||||
coin: coin,
|
||||
// tracker: tracker,
|
||||
);
|
||||
|
||||
case Coin.namecoin:
|
||||
return NamecoinWallet(
|
||||
walletId: walletId,
|
||||
|
|
1560
lib/services/coins/wownero/wownero_wallet.dart
Normal file
1560
lib/services/coins/wownero/wownero_wallet.dart
Normal file
File diff suppressed because it is too large
Load diff
|
@ -79,7 +79,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&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,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");
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ class Wallets extends ChangeNotifier {
|
|||
final shouldSetAutoSync = shouldAutoSyncAll ||
|
||||
walletIdsToEnableAutoSync.contains(manager.walletId);
|
||||
|
||||
if (manager.coin == Coin.monero) {
|
||||
if (manager.coin == Coin.monero || manager.coin == Coin.wownero) {
|
||||
walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
||||
} else {
|
||||
walletInitFutures.add(manager.initializeExisting().then((value) {
|
||||
|
@ -312,7 +312,7 @@ class Wallets extends ChangeNotifier {
|
|||
final shouldSetAutoSync = shouldAutoSyncAll ||
|
||||
walletIdsToEnableAutoSync.contains(manager.walletId);
|
||||
|
||||
if (manager.coin == Coin.monero) {
|
||||
if (manager.coin == Coin.monero || manager.coin == Coin.wownero) {
|
||||
walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync));
|
||||
} else {
|
||||
walletInitFutures.add(manager.initializeExisting().then((value) {
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_libmonero/monero/monero.dart';
|
||||
import 'package:flutter_libmonero/wownero/wownero.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:stackwallet/hive/db.dart';
|
||||
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
|
||||
|
@ -367,8 +368,13 @@ class WalletsService extends ChangeNotifier {
|
|||
await DB.instance.delete<dynamic>(
|
||||
boxName: DB.boxNameAllWalletsData,
|
||||
key: "${walletId}_mnemonicHasBeenVerified");
|
||||
|
||||
if (coinFromPrettyName(shell['coin'] as String) == Coin.monero) {
|
||||
if (coinFromPrettyName(shell['coin'] as String) == Coin.wownero) {
|
||||
final wowService =
|
||||
wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
|
||||
await wowService.remove(walletId);
|
||||
Logging.instance
|
||||
.log("monero wallet: $walletId deleted", level: LogLevel.Info);
|
||||
} else if (coinFromPrettyName(shell['coin'] as String) == Coin.monero) {
|
||||
final xmrService =
|
||||
monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
|
||||
await xmrService.remove(walletId);
|
||||
|
|
|
@ -53,6 +53,9 @@ class AddressUtils {
|
|||
case Coin.monero:
|
||||
return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
|
||||
RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
|
||||
case Coin.wownero:
|
||||
return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
|
||||
RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
|
||||
case Coin.namecoin:
|
||||
return Address.validateAddress(address, namecoin, namecoin.bech32!);
|
||||
case Coin.bitcoinTestNet:
|
||||
|
|
|
@ -128,6 +128,7 @@ class _SVG {
|
|||
String get epicCash => "assets/svg/coin_icons/EpicCash.svg";
|
||||
String get firo => "assets/svg/coin_icons/Firo.svg";
|
||||
String get monero => "assets/svg/coin_icons/Monero.svg";
|
||||
String get wownero => "assets/svg/coin_icons/Wownero.svg";
|
||||
String get namecoin => "assets/svg/coin_icons/Namecoin.svg";
|
||||
|
||||
String get chevronRight => "assets/svg/chevron-right.svg";
|
||||
|
@ -156,6 +157,8 @@ class _SVG {
|
|||
return firo;
|
||||
case Coin.monero:
|
||||
return monero;
|
||||
case Coin.wownero:
|
||||
return wownero;
|
||||
case Coin.namecoin:
|
||||
return namecoin;
|
||||
case Coin.bitcoinTestNet:
|
||||
|
@ -177,6 +180,7 @@ class _PNG {
|
|||
String get splash => "assets/images/splash.png";
|
||||
|
||||
String get monero => "assets/images/monero.png";
|
||||
String get wownero => "assets/images/wownero.png";
|
||||
String get firo => "assets/images/firo.png";
|
||||
String get dogecoin => "assets/images/doge.png";
|
||||
String get bitcoin => "assets/images/bitcoin.png";
|
||||
|
@ -203,6 +207,8 @@ class _PNG {
|
|||
return firo;
|
||||
case Coin.monero:
|
||||
return monero;
|
||||
case Coin.wownero:
|
||||
return wownero;
|
||||
case Coin.namecoin:
|
||||
return namecoin;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ Uri getBlockExplorerTransactionUrlFor({
|
|||
throw UnimplementedError("missing block explorer for epic cash");
|
||||
case Coin.monero:
|
||||
return Uri.parse("https://xmrchain.net/tx/$txid");
|
||||
case Coin.wownero:
|
||||
return Uri.parse("https://explore.wownero.com/search?value=$txid");
|
||||
case Coin.firo:
|
||||
return Uri.parse("https://explorer.firo.org/tx/$txid");
|
||||
case Coin.firoTestNet:
|
||||
|
|
|
@ -18,6 +18,7 @@ abstract class Constants {
|
|||
|
||||
//TODO: correct for monero?
|
||||
static const int satsPerCoinMonero = 1000000000000;
|
||||
static const int satsPerCoinWownero = 100000000000;
|
||||
static const int satsPerCoin = 100000000;
|
||||
static const int decimalPlaces = 8;
|
||||
|
||||
|
@ -54,6 +55,9 @@ abstract class Constants {
|
|||
case Coin.monero:
|
||||
values.addAll([25]);
|
||||
break;
|
||||
case Coin.wownero:
|
||||
values.addAll([14]);
|
||||
break;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
@ -83,6 +87,9 @@ abstract class Constants {
|
|||
case Coin.monero:
|
||||
return 120;
|
||||
|
||||
case Coin.wownero:
|
||||
return 120;
|
||||
|
||||
case Coin.namecoin:
|
||||
return 600;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ abstract class DefaultNodes {
|
|||
epicCash,
|
||||
bitcoincash,
|
||||
namecoin,
|
||||
wownero,
|
||||
bitcoinTestnet,
|
||||
bitcoincashTestnet,
|
||||
dogecoinTestnet,
|
||||
|
@ -83,6 +84,20 @@ abstract class DefaultNodes {
|
|||
isDown: false,
|
||||
);
|
||||
|
||||
// TODO: eventually enable ssl and set scheme to https
|
||||
// currently get certificate failure
|
||||
static NodeModel get wownero => NodeModel(
|
||||
host: "http://eu-west-2.wow.xmr.pm",
|
||||
port: 34568,
|
||||
name: defaultName,
|
||||
id: _nodeId(Coin.wownero),
|
||||
useSSL: false,
|
||||
enabled: true,
|
||||
coinName: Coin.wownero.name,
|
||||
isFailover: true,
|
||||
isDown: false,
|
||||
);
|
||||
|
||||
static NodeModel get epicCash => NodeModel(
|
||||
host: "http://epiccash.stackwallet.com",
|
||||
port: 3413,
|
||||
|
@ -175,6 +190,9 @@ abstract class DefaultNodes {
|
|||
case Coin.monero:
|
||||
return monero;
|
||||
|
||||
case Coin.wownero:
|
||||
return wownero;
|
||||
|
||||
case Coin.namecoin:
|
||||
return namecoin;
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as firo;
|
|||
import 'package:stackwallet/services/coins/monero/monero_wallet.dart' as xmr;
|
||||
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'
|
||||
as nmc;
|
||||
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart' as wow;
|
||||
|
||||
enum Coin {
|
||||
bitcoin,
|
||||
|
@ -17,6 +18,7 @@ enum Coin {
|
|||
epicCash,
|
||||
firo,
|
||||
monero,
|
||||
wownero,
|
||||
namecoin,
|
||||
|
||||
///
|
||||
|
@ -47,6 +49,8 @@ extension CoinExt on Coin {
|
|||
return "Firo";
|
||||
case Coin.monero:
|
||||
return "Monero";
|
||||
case Coin.wownero:
|
||||
return "Wownero";
|
||||
case Coin.namecoin:
|
||||
return "Namecoin";
|
||||
case Coin.bitcoinTestNet:
|
||||
|
@ -74,6 +78,8 @@ extension CoinExt on Coin {
|
|||
return "FIRO";
|
||||
case Coin.monero:
|
||||
return "XMR";
|
||||
case Coin.wownero:
|
||||
return "WOW";
|
||||
case Coin.namecoin:
|
||||
return "NMC";
|
||||
case Coin.bitcoinTestNet:
|
||||
|
@ -102,6 +108,8 @@ extension CoinExt on Coin {
|
|||
return "firo";
|
||||
case Coin.monero:
|
||||
return "monero";
|
||||
case Coin.wownero:
|
||||
return "wownero";
|
||||
case Coin.namecoin:
|
||||
return "namecoin";
|
||||
case Coin.bitcoinTestNet:
|
||||
|
@ -130,6 +138,7 @@ extension CoinExt on Coin {
|
|||
|
||||
case Coin.epicCash:
|
||||
case Coin.monero:
|
||||
case Coin.wownero:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -157,6 +166,10 @@ extension CoinExt on Coin {
|
|||
|
||||
case Coin.monero:
|
||||
return xmr.MINIMUM_CONFIRMATIONS;
|
||||
|
||||
case Coin.wownero:
|
||||
return wow.MINIMUM_CONFIRMATIONS;
|
||||
|
||||
case Coin.namecoin:
|
||||
return nmc.MINIMUM_CONFIRMATIONS;
|
||||
}
|
||||
|
@ -204,6 +217,10 @@ Coin coinFromPrettyName(String name) {
|
|||
case "tDogecoin":
|
||||
case "dogecoinTestNet":
|
||||
return Coin.dogecoinTestNet;
|
||||
case "Wownero":
|
||||
case "tWownero":
|
||||
case "wownero":
|
||||
return Coin.wownero;
|
||||
default:
|
||||
throw ArgumentError.value(
|
||||
name, "name", "No Coin enum value with that prettyName");
|
||||
|
@ -234,6 +251,8 @@ Coin coinFromTickerCaseInsensitive(String ticker) {
|
|||
return Coin.firoTestNet;
|
||||
case "tdoge":
|
||||
return Coin.dogecoinTestNet;
|
||||
case "wow":
|
||||
return Coin.wownero;
|
||||
default:
|
||||
throw ArgumentError.value(
|
||||
ticker, "name", "No Coin enum value with that ticker");
|
||||
|
|
|
@ -209,8 +209,8 @@ class CoinThemeColor {
|
|||
return monero;
|
||||
case Coin.namecoin:
|
||||
return namecoin;
|
||||
// case Coin.wownero:
|
||||
// return wownero;
|
||||
case Coin.wownero:
|
||||
return wownero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1422,8 +1422,8 @@ class StackColors extends ThemeExtension<StackColors> {
|
|||
return _coin.monero;
|
||||
case Coin.namecoin:
|
||||
return _coin.namecoin;
|
||||
// case Coin.wownero:
|
||||
// return wownero;
|
||||
case Coin.wownero:
|
||||
return _coin.wownero;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ class NodeOptionsSheet extends ConsumerWidget {
|
|||
break;
|
||||
|
||||
case Coin.monero:
|
||||
case Coin.wownero:
|
||||
try {
|
||||
final uri = Uri.parse(node.host);
|
||||
if (uri.scheme.startsWith("http")) {
|
||||
|
|
|
@ -172,7 +172,9 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
|
|||
builder: (_) {
|
||||
final amount = coin == Coin.monero
|
||||
? (_transaction.amount ~/ 10000)
|
||||
: _transaction.amount;
|
||||
: coin == Coin.wownero
|
||||
? (_transaction.amount ~/ 1000)
|
||||
: _transaction.amount;
|
||||
return Text(
|
||||
"${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}",
|
||||
style:
|
||||
|
@ -212,6 +214,8 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
|
|||
int value = _transaction.amount;
|
||||
if (coin == Coin.monero) {
|
||||
value = (value ~/ 10000);
|
||||
} else if (coin == Coin.wownero) {
|
||||
value = (value ~/ 1000);
|
||||
}
|
||||
|
||||
return Text(
|
||||
|
|
|
@ -317,6 +317,13 @@ packages:
|
|||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
cw_wownero:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "crypto_plugins/flutter_libmonero/cw_wownero"
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
dart_numerics:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
@ -11,7 +11,7 @@ description: Stack Wallet
|
|||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.4.50+65
|
||||
version: 1.4.52+68
|
||||
|
||||
environment:
|
||||
sdk: ">=2.17.0 <3.0.0"
|
||||
|
@ -31,6 +31,9 @@ dependencies:
|
|||
cw_monero:
|
||||
path: ./crypto_plugins/flutter_libmonero/cw_monero
|
||||
|
||||
cw_wownero:
|
||||
path: ./crypto_plugins/flutter_libmonero/cw_wownero
|
||||
|
||||
cw_core:
|
||||
path: ./crypto_plugins/flutter_libmonero/cw_core
|
||||
|
||||
|
@ -189,6 +192,7 @@ flutter:
|
|||
- assets/svg/clipboard.svg
|
||||
- assets/images/stack.png
|
||||
- assets/images/monero.png
|
||||
- assets/images/wownero.png
|
||||
- assets/images/firo.png
|
||||
- assets/images/doge.png
|
||||
- assets/images/bitcoin.png
|
||||
|
@ -292,6 +296,7 @@ flutter:
|
|||
- assets/svg/coin_icons/EpicCash.svg
|
||||
- assets/svg/coin_icons/Firo.svg
|
||||
- assets/svg/coin_icons/Monero.svg
|
||||
- assets/svg/coin_icons/Wownero.svg
|
||||
- assets/svg/coin_icons/Namecoin.svg
|
||||
# lottie animations
|
||||
- assets/lottie/test.json
|
||||
|
|
|
@ -1,7 +1,152 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:stackwallet/models/models.dart';
|
||||
|
||||
import '../services/coins/firo/sample_data/transaction_data_samples.dart';
|
||||
|
||||
void main() {
|
||||
group("TransactionData", () {
|
||||
test("TransactionData from Json", () {
|
||||
final txChunk = TransactionChunk.fromJson({
|
||||
"timestamp": 993260735,
|
||||
"transactions": [
|
||||
{
|
||||
"txid": "txid",
|
||||
"confirmed_status": true,
|
||||
"timestamp": 1876352482,
|
||||
"txType": "txType",
|
||||
"amount": 10,
|
||||
"worthNow": "1",
|
||||
"worthAtBlockTimestamp": "1",
|
||||
"fees": 1,
|
||||
"inputSize": 1,
|
||||
"outputSize": 1,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"address": "address",
|
||||
"height": 1,
|
||||
"confirmations": 1,
|
||||
"aliens": [],
|
||||
"subType": "mint",
|
||||
"isCancelled": false,
|
||||
"slateId": "slateId",
|
||||
"otherData": "otherData",
|
||||
}
|
||||
]
|
||||
});
|
||||
final txdata =
|
||||
TransactionData.fromJson({"dateTimeChunks": [], "txChunks": []});
|
||||
txdata.findTransaction("txid");
|
||||
txdata.getAllTransactions();
|
||||
});
|
||||
});
|
||||
|
||||
group("Timestamp", () {
|
||||
test("Timestamp is now", () {
|
||||
final date = extractDateFromTimestamp(0);
|
||||
});
|
||||
|
||||
test("Timestamp is null", () {
|
||||
final date = extractDateFromTimestamp(null);
|
||||
});
|
||||
|
||||
test("Timestamp is a random date", () {
|
||||
final date = extractDateFromTimestamp(1876352482);
|
||||
});
|
||||
});
|
||||
|
||||
group("Transaction", () {
|
||||
test("Transaction from Json", () {
|
||||
final tx = Transaction.fromJson({
|
||||
"txid": "txid",
|
||||
"confirmed_status": true,
|
||||
"timestamp": 1876352482,
|
||||
"txType": "txType",
|
||||
"amount": 10,
|
||||
"worthNow": "1",
|
||||
"worthAtBlockTimestamp": "1",
|
||||
"fees": 1,
|
||||
"inputSize": 1,
|
||||
"outputSize": 1,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"address": "address",
|
||||
"height": 1,
|
||||
"confirmations": 1,
|
||||
"aliens": [],
|
||||
"subType": "mint",
|
||||
"isCancelled": false,
|
||||
"slateId": "slateId",
|
||||
"otherData": "otherData",
|
||||
});
|
||||
});
|
||||
|
||||
test("Transaction from Lelantus Json", () {
|
||||
final tx = Transaction.fromLelantusJson({
|
||||
"txid": "txid",
|
||||
"confirmed_status": true,
|
||||
"timestamp": 1876352482,
|
||||
"txType": "txType",
|
||||
"amount": 10,
|
||||
"worthNow": "1",
|
||||
"worthAtBlockTimestamp": "1",
|
||||
"fees": 1,
|
||||
"inputSize": 1,
|
||||
"outputSize": 1,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"address": "address",
|
||||
"height": 1,
|
||||
"confirmations": 1,
|
||||
"aliens": [],
|
||||
"subType": "mint",
|
||||
"isCancelled": false,
|
||||
"slateId": "slateId",
|
||||
"otherData": "otherData",
|
||||
});
|
||||
});
|
||||
|
||||
test("TransactionChunk", () {
|
||||
final transactionchunk = TransactionChunk.fromJson({
|
||||
"timestamp": 45920,
|
||||
"transactions": [],
|
||||
});
|
||||
expect(
|
||||
transactionchunk.toString(), "timestamp: 45920 transactions: [\n]");
|
||||
});
|
||||
|
||||
test("TransactionChunk with a transaction", () {
|
||||
final txChunk = TransactionChunk.fromJson({
|
||||
"timestamp": 993260735,
|
||||
"transactions": [
|
||||
{
|
||||
"txid": "txid",
|
||||
"confirmed_status": true,
|
||||
"timestamp": 1876352482,
|
||||
"txType": "txType",
|
||||
"amount": 10,
|
||||
"worthNow": "1",
|
||||
"worthAtBlockTimestamp": "1",
|
||||
"fees": 1,
|
||||
"inputSize": 1,
|
||||
"outputSize": 1,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"address": "address",
|
||||
"height": 1,
|
||||
"confirmations": 1,
|
||||
"aliens": [],
|
||||
"subType": "mint",
|
||||
"isCancelled": false,
|
||||
"slateId": "slateId",
|
||||
"otherData": "otherData",
|
||||
}
|
||||
]
|
||||
});
|
||||
expect(txChunk.toString(),
|
||||
"timestamp: 993260735 transactions: [\n {txid: txid, type: txType, subType: mint, value: 10, fee: 1, height: 1, confirm: true, confirmations: 1, address: address, timestamp: 1876352482, worthNow: 1, inputs: [], slateid: slateId } \n]");
|
||||
});
|
||||
});
|
||||
|
||||
group("Transaction isMinting", () {
|
||||
test("Transaction isMinting unconfirmed mint", () {
|
||||
final tx = Transaction(
|
||||
|
@ -94,4 +239,57 @@ void main() {
|
|||
expect(tx1 == tx2, false);
|
||||
expect(tx2.toString(), tx1.toString());
|
||||
});
|
||||
|
||||
group("Input", () {
|
||||
test("Input.toString", () {
|
||||
final input = Input(
|
||||
txid: "txid",
|
||||
vout: 1,
|
||||
prevout: null,
|
||||
scriptsig: "scriptsig",
|
||||
scriptsigAsm: "scriptsigAsm",
|
||||
witness: [],
|
||||
isCoinbase: false,
|
||||
sequence: 1,
|
||||
innerRedeemscriptAsm: "innerRedeemscriptAsm",
|
||||
); //Input
|
||||
|
||||
expect(input.toString(), "{txid: txid}");
|
||||
});
|
||||
|
||||
test("Input.toString", () {
|
||||
final input = Input.fromJson({
|
||||
"txid": "txid",
|
||||
"vout": 1,
|
||||
"prevout": null,
|
||||
"scriptSig": {"hex": "somehexString", "asm": "someasmthing"},
|
||||
"scriptsigAsm": "scriptsigAsm",
|
||||
"witness": [],
|
||||
"isCoinbase": false,
|
||||
"sequence": 1,
|
||||
"innerRedeemscriptAsm": "innerRedeemscriptAsm",
|
||||
}); //Input
|
||||
|
||||
expect(input.toString(), "{txid: txid}");
|
||||
});
|
||||
});
|
||||
|
||||
group("Output", () {
|
||||
test("Output.toString", () {
|
||||
final output = Output.fromJson({
|
||||
"scriptPubKey": {
|
||||
"hex": "somehexSting",
|
||||
"asm": "someasmthing",
|
||||
"type": "sometype",
|
||||
"addresses": "someaddresses",
|
||||
},
|
||||
"scriptpubkeyAsm": "scriptpubkeyAsm",
|
||||
"scriptpubkeyType": "scriptpubkeyType",
|
||||
"scriptpubkeyAddress": "address",
|
||||
"value": 2,
|
||||
}); //Input
|
||||
|
||||
expect(output.toString(), "Instance of \'Output\'");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -23,7 +23,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&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,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(
|
||||
|
@ -36,10 +36,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.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.bitcoinTestNet: [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&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,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);
|
||||
|
@ -50,7 +50,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&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,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(
|
||||
|
@ -68,12 +68,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.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.bitcoinTestNet: [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&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,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);
|
||||
|
@ -84,7 +84,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&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,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(
|
||||
|
@ -97,7 +97,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.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.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
|
||||
});
|
||||
|
||||
test("no internet available", () async {
|
||||
|
@ -105,7 +105,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&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,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(
|
||||
|
@ -117,7 +117,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.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.bitcoinTestNet: [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