mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-09 12:19:24 +00:00
Merge remote-tracking branch 'origin_SW/ui-fixes' into ordinals
# Conflicts: # lib/db/isar/main_db.dart
This commit is contained in:
commit
80dad5156a
19 changed files with 2339 additions and 919 deletions
|
@ -177,6 +177,9 @@ class DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Box<dynamic>> getTxCacheBox({required Coin coin}) async {
|
Future<Box<dynamic>> getTxCacheBox({required Coin coin}) async {
|
||||||
|
if (_txCacheBoxes[coin]?.isOpen != true) {
|
||||||
|
_txCacheBoxes.remove(coin);
|
||||||
|
}
|
||||||
return _txCacheBoxes[coin] ??=
|
return _txCacheBoxes[coin] ??=
|
||||||
await Hive.openBox<dynamic>(_boxNameTxCache(coin: coin));
|
await Hive.openBox<dynamic>(_boxNameTxCache(coin: coin));
|
||||||
}
|
}
|
||||||
|
@ -186,6 +189,9 @@ class DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Box<dynamic>> getAnonymitySetCacheBox({required Coin coin}) async {
|
Future<Box<dynamic>> getAnonymitySetCacheBox({required Coin coin}) async {
|
||||||
|
if (_setCacheBoxes[coin]?.isOpen != true) {
|
||||||
|
_setCacheBoxes.remove(coin);
|
||||||
|
}
|
||||||
return _setCacheBoxes[coin] ??=
|
return _setCacheBoxes[coin] ??=
|
||||||
await Hive.openBox<dynamic>(_boxNameSetCache(coin: coin));
|
await Hive.openBox<dynamic>(_boxNameSetCache(coin: coin));
|
||||||
}
|
}
|
||||||
|
@ -195,6 +201,9 @@ class DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Box<dynamic>> getUsedSerialsCacheBox({required Coin coin}) async {
|
Future<Box<dynamic>> getUsedSerialsCacheBox({required Coin coin}) async {
|
||||||
|
if (_usedSerialsCacheBoxes[coin]?.isOpen != true) {
|
||||||
|
_usedSerialsCacheBoxes.remove(coin);
|
||||||
|
}
|
||||||
return _usedSerialsCacheBoxes[coin] ??=
|
return _usedSerialsCacheBoxes[coin] ??=
|
||||||
await Hive.openBox<dynamic>(_boxNameUsedSerialsCache(coin: coin));
|
await Hive.openBox<dynamic>(_boxNameUsedSerialsCache(coin: coin));
|
||||||
}
|
}
|
||||||
|
@ -265,8 +274,15 @@ class DB {
|
||||||
{required dynamic key, required String boxName}) async =>
|
{required dynamic key, required String boxName}) async =>
|
||||||
await mutex.protect(() async => await Hive.box<T>(boxName).delete(key));
|
await mutex.protect(() async => await Hive.box<T>(boxName).delete(key));
|
||||||
|
|
||||||
Future<void> deleteAll<T>({required String boxName}) async =>
|
Future<void> deleteAll<T>({required String boxName}) async {
|
||||||
await mutex.protect(() async => await Hive.box<T>(boxName).clear());
|
await mutex.protect(() async {
|
||||||
|
Box<T> box = Hive.box<T>(boxName);
|
||||||
|
if (!box.isOpen) {
|
||||||
|
box = await Hive.openBox(boxName);
|
||||||
|
}
|
||||||
|
await box.clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> deleteBoxFromDisk({required String boxName}) async =>
|
Future<void> deleteBoxFromDisk({required String boxName}) async =>
|
||||||
await mutex.protect(() async => await Hive.deleteBoxFromDisk(boxName));
|
await mutex.protect(() async => await Hive.deleteBoxFromDisk(boxName));
|
||||||
|
|
|
@ -56,6 +56,7 @@ class MainDB {
|
||||||
StackThemeSchema,
|
StackThemeSchema,
|
||||||
ContactEntrySchema,
|
ContactEntrySchema,
|
||||||
OrdinalSchema,
|
OrdinalSchema,
|
||||||
|
LelantusCoinSchema,
|
||||||
],
|
],
|
||||||
directory: (await StackFileSystem.applicationIsarDirectory()).path,
|
directory: (await StackFileSystem.applicationIsarDirectory()).path,
|
||||||
// inspector: kDebugMode,
|
// inspector: kDebugMode,
|
||||||
|
@ -377,6 +378,8 @@ class MainDB {
|
||||||
final transactionCount = await getTransactions(walletId).count();
|
final transactionCount = await getTransactions(walletId).count();
|
||||||
final addressCount = await getAddresses(walletId).count();
|
final addressCount = await getAddresses(walletId).count();
|
||||||
final utxoCount = await getUTXOs(walletId).count();
|
final utxoCount = await getUTXOs(walletId).count();
|
||||||
|
final lelantusCoinCount =
|
||||||
|
await isar.lelantusCoins.where().walletIdEqualTo(walletId).count();
|
||||||
|
|
||||||
await isar.writeTxn(() async {
|
await isar.writeTxn(() async {
|
||||||
const paginateLimit = 50;
|
const paginateLimit = 50;
|
||||||
|
@ -410,6 +413,18 @@ class MainDB {
|
||||||
.findAll();
|
.findAll();
|
||||||
await isar.utxos.deleteAll(utxoIds);
|
await isar.utxos.deleteAll(utxoIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lelantusCoins
|
||||||
|
for (int i = 0; i < lelantusCoinCount; i += paginateLimit) {
|
||||||
|
final lelantusCoinIds = await isar.lelantusCoins
|
||||||
|
.where()
|
||||||
|
.walletIdEqualTo(walletId)
|
||||||
|
.offset(i)
|
||||||
|
.limit(paginateLimit)
|
||||||
|
.idProperty()
|
||||||
|
.findAll();
|
||||||
|
await isar.lelantusCoins.deleteAll(lelantusCoinIds);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,4 +519,15 @@ class MainDB {
|
||||||
isar.writeTxn(() async {
|
isar.writeTxn(() async {
|
||||||
await isar.ethContracts.putAll(contracts);
|
await isar.ethContracts.putAll(contracts);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ========== Lelantus =======================================================
|
||||||
|
|
||||||
|
Future<int?> getHighestUsedMintIndex({required String walletId}) async {
|
||||||
|
return await isar.lelantusCoins
|
||||||
|
.where()
|
||||||
|
.walletIdEqualTo(walletId)
|
||||||
|
.sortByMintIndexDesc()
|
||||||
|
.mintIndexProperty()
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,14 +164,16 @@ class CachedElectrumX {
|
||||||
|
|
||||||
final _list = box.get("serials") as List?;
|
final _list = box.get("serials") as List?;
|
||||||
|
|
||||||
List<String> cachedSerials =
|
Set<String> cachedSerials =
|
||||||
_list == null ? [] : List<String>.from(_list);
|
_list == null ? {} : List<String>.from(_list).toSet();
|
||||||
|
|
||||||
final startNumber = cachedSerials.length;
|
// startNumber is broken currently
|
||||||
|
final startNumber = 0; // cachedSerials.length;
|
||||||
|
|
||||||
final serials =
|
final serials = await electrumXClient.getUsedCoinSerials(
|
||||||
await electrumXClient.getUsedCoinSerials(startNumber: startNumber);
|
startNumber: startNumber,
|
||||||
List<String> newSerials = [];
|
);
|
||||||
|
Set<String> newSerials = {};
|
||||||
|
|
||||||
for (final element in (serials["serials"] as List)) {
|
for (final element in (serials["serials"] as List)) {
|
||||||
if (!isHexadecimal(element as String)) {
|
if (!isHexadecimal(element as String)) {
|
||||||
|
@ -182,12 +184,14 @@ class CachedElectrumX {
|
||||||
}
|
}
|
||||||
cachedSerials.addAll(newSerials);
|
cachedSerials.addAll(newSerials);
|
||||||
|
|
||||||
|
final resultingList = cachedSerials.toList();
|
||||||
|
|
||||||
await box.put(
|
await box.put(
|
||||||
"serials",
|
"serials",
|
||||||
cachedSerials,
|
resultingList,
|
||||||
);
|
);
|
||||||
|
|
||||||
return cachedSerials;
|
return resultingList;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
"Failed to process CachedElectrumX.getTransaction(): $e\n$s",
|
"Failed to process CachedElectrumX.getTransaction(): $e\n$s",
|
||||||
|
|
|
@ -159,8 +159,8 @@ class ElectrumX {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"JSONRPC response\n"
|
"JSONRPC response\n"
|
||||||
" command: $command\n"
|
" command: $command\n"
|
||||||
" args: $args\n"
|
" error: ${response.data}"
|
||||||
" error: ${response.data}",
|
" args: $args\n",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ class JsonRPC {
|
||||||
|
|
||||||
// TODO different timeout length?
|
// TODO different timeout length?
|
||||||
req.initiateTimeout(
|
req.initiateTimeout(
|
||||||
const Duration(seconds: 10),
|
Duration(seconds: connectionTimeout.inSeconds ~/ 2),
|
||||||
onTimedOut: () {
|
onTimedOut: () {
|
||||||
_requestQueue.remove(req);
|
_requestQueue.remove(req);
|
||||||
},
|
},
|
||||||
|
|
81
lib/models/isar/models/firo_specific/lelantus_coin.dart
Normal file
81
lib/models/isar/models/firo_specific/lelantus_coin.dart
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
|
part 'lelantus_coin.g.dart';
|
||||||
|
|
||||||
|
@collection
|
||||||
|
class LelantusCoin {
|
||||||
|
Id id = Isar.autoIncrement;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
final String txid;
|
||||||
|
|
||||||
|
final String value; // can't use BigInt in isar :shrug:
|
||||||
|
|
||||||
|
@Index(
|
||||||
|
unique: true,
|
||||||
|
replace: false,
|
||||||
|
composite: [
|
||||||
|
CompositeIndex("walletId"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
final int mintIndex;
|
||||||
|
|
||||||
|
final int anonymitySetId;
|
||||||
|
|
||||||
|
final bool isUsed;
|
||||||
|
|
||||||
|
final bool isJMint;
|
||||||
|
|
||||||
|
final String? otherData;
|
||||||
|
|
||||||
|
LelantusCoin({
|
||||||
|
required this.walletId,
|
||||||
|
required this.txid,
|
||||||
|
required this.value,
|
||||||
|
required this.mintIndex,
|
||||||
|
required this.anonymitySetId,
|
||||||
|
required this.isUsed,
|
||||||
|
required this.isJMint,
|
||||||
|
required this.otherData,
|
||||||
|
});
|
||||||
|
|
||||||
|
LelantusCoin copyWith({
|
||||||
|
String? walletId,
|
||||||
|
String? publicCoin,
|
||||||
|
String? txid,
|
||||||
|
String? value,
|
||||||
|
int? mintIndex,
|
||||||
|
int? anonymitySetId,
|
||||||
|
bool? isUsed,
|
||||||
|
bool? isJMint,
|
||||||
|
String? otherData,
|
||||||
|
}) {
|
||||||
|
return LelantusCoin(
|
||||||
|
walletId: walletId ?? this.walletId,
|
||||||
|
txid: txid ?? this.txid,
|
||||||
|
value: value ?? this.value,
|
||||||
|
mintIndex: mintIndex ?? this.mintIndex,
|
||||||
|
anonymitySetId: anonymitySetId ?? this.anonymitySetId,
|
||||||
|
isUsed: isUsed ?? this.isUsed,
|
||||||
|
isJMint: isJMint ?? this.isJMint,
|
||||||
|
otherData: otherData ?? this.otherData,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LelantusCoin{'
|
||||||
|
'id: $id, '
|
||||||
|
'walletId: $walletId, '
|
||||||
|
'txid: $txid, '
|
||||||
|
'value: $value, '
|
||||||
|
'mintIndex: $mintIndex, '
|
||||||
|
'anonymitySetId: $anonymitySetId, '
|
||||||
|
'otherData: $otherData, '
|
||||||
|
'isJMint: $isJMint, '
|
||||||
|
'isUsed: $isUsed'
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
1629
lib/models/isar/models/firo_specific/lelantus_coin.g.dart
Normal file
1629
lib/models/isar/models/firo_specific/lelantus_coin.g.dart
Normal file
File diff suppressed because it is too large
Load diff
|
@ -15,5 +15,6 @@ export 'blockchain_data/output.dart';
|
||||||
export 'blockchain_data/transaction.dart';
|
export 'blockchain_data/transaction.dart';
|
||||||
export 'blockchain_data/utxo.dart';
|
export 'blockchain_data/utxo.dart';
|
||||||
export 'ethereum/eth_contract.dart';
|
export 'ethereum/eth_contract.dart';
|
||||||
|
export 'firo_specific/lelantus_coin.dart';
|
||||||
export 'log.dart';
|
export 'log.dart';
|
||||||
export 'transaction_note.dart';
|
export 'transaction_note.dart';
|
||||||
|
|
|
@ -12,6 +12,7 @@ import 'package:hive/hive.dart';
|
||||||
|
|
||||||
part 'type_adaptors/lelantus_coin.g.dart';
|
part 'type_adaptors/lelantus_coin.g.dart';
|
||||||
|
|
||||||
|
@Deprecated("Use Isar object instead")
|
||||||
// @HiveType(typeId: 9)
|
// @HiveType(typeId: 9)
|
||||||
class LelantusCoin {
|
class LelantusCoin {
|
||||||
// @HiveField(0)
|
// @HiveField(0)
|
||||||
|
@ -27,6 +28,7 @@ class LelantusCoin {
|
||||||
// @HiveField(5)
|
// @HiveField(5)
|
||||||
bool isUsed;
|
bool isUsed;
|
||||||
|
|
||||||
|
@Deprecated("Use Isar object instead")
|
||||||
LelantusCoin(
|
LelantusCoin(
|
||||||
this.index,
|
this.index,
|
||||||
this.value,
|
this.value,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,61 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Stack Wallet.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2023 Cypher Stack
|
|
||||||
* All Rights Reserved.
|
|
||||||
* The code is distributed under GPLv3 license, see LICENSE file for details.
|
|
||||||
* Generated by Cypher Stack on 2023-05-26
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
import 'package:stackwallet/db/hive/db.dart';
|
|
||||||
|
|
||||||
mixin FiroHive {
|
|
||||||
late final String _walletId;
|
|
||||||
|
|
||||||
void initFiroHive(String walletId) {
|
|
||||||
_walletId = walletId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// jindex
|
|
||||||
List? firoGetJIndex() {
|
|
||||||
return DB.instance.get<dynamic>(boxName: _walletId, key: "jindex") as List?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> firoUpdateJIndex(List jIndex) async {
|
|
||||||
await DB.instance.put<dynamic>(
|
|
||||||
boxName: _walletId,
|
|
||||||
key: "jindex",
|
|
||||||
value: jIndex,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _lelantus_coins
|
|
||||||
List? firoGetLelantusCoins() {
|
|
||||||
return DB.instance.get<dynamic>(boxName: _walletId, key: "_lelantus_coins")
|
|
||||||
as List?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> firoUpdateLelantusCoins(List lelantusCoins) async {
|
|
||||||
await DB.instance.put<dynamic>(
|
|
||||||
boxName: _walletId,
|
|
||||||
key: "_lelantus_coins",
|
|
||||||
value: lelantusCoins,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// mintIndex
|
|
||||||
int firoGetMintIndex() {
|
|
||||||
return DB.instance.get<dynamic>(boxName: _walletId, key: "mintIndex")
|
|
||||||
as int? ??
|
|
||||||
0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> firoUpdateMintIndex(int mintIndex) async {
|
|
||||||
await DB.instance.put<dynamic>(
|
|
||||||
boxName: _walletId,
|
|
||||||
key: "mintIndex",
|
|
||||||
value: mintIndex,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -77,8 +77,10 @@ class NotificationApi {
|
||||||
final id = prefs.currentNotificationId;
|
final id = prefs.currentNotificationId;
|
||||||
|
|
||||||
String confirms = "";
|
String confirms = "";
|
||||||
if (txid != null) {
|
if (txid != null &&
|
||||||
confirms = " (${confirmations!}/${requiredConfirmations!})";
|
confirmations != null &&
|
||||||
|
requiredConfirmations != null) {
|
||||||
|
confirms = " ($confirmations/$requiredConfirmations)";
|
||||||
}
|
}
|
||||||
|
|
||||||
final NotificationModel model = NotificationModel(
|
final NotificationModel model = NotificationModel(
|
||||||
|
|
|
@ -58,7 +58,7 @@ abstract class Constants {
|
||||||
// Enable Logger.print statements
|
// Enable Logger.print statements
|
||||||
static const bool disableLogger = false;
|
static const bool disableLogger = false;
|
||||||
|
|
||||||
static const int currentDataVersion = 10;
|
static const int currentDataVersion = 11;
|
||||||
|
|
||||||
static const int rescanV1 = 1;
|
static const int rescanV1 = 1;
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,6 @@ class DbVersionMigrator with WalletDB {
|
||||||
// clear possible broken firo cache
|
// clear possible broken firo cache
|
||||||
await DB.instance.clearSharedTransactionCache(coin: Coin.firo);
|
await DB.instance.clearSharedTransactionCache(coin: Coin.firo);
|
||||||
|
|
||||||
|
|
||||||
// update version
|
// update version
|
||||||
await DB.instance.put<dynamic>(
|
await DB.instance.put<dynamic>(
|
||||||
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 4);
|
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 4);
|
||||||
|
@ -343,12 +342,85 @@ class DbVersionMigrator with WalletDB {
|
||||||
// try to continue migrating
|
// try to continue migrating
|
||||||
return await migrate(10, secureStore: secureStore);
|
return await migrate(10, secureStore: secureStore);
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
// migrate
|
||||||
|
await _v10(secureStore);
|
||||||
|
|
||||||
|
// update version
|
||||||
|
await DB.instance.put<dynamic>(
|
||||||
|
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 11);
|
||||||
|
|
||||||
|
// try to continue migrating
|
||||||
|
return await migrate(11, secureStore: secureStore);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// finally return
|
// finally return
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _v10(SecureStorageInterface secureStore) async {
|
||||||
|
await Hive.openBox<dynamic>(DB.boxNameAllWalletsData);
|
||||||
|
await Hive.openBox<dynamic>(DB.boxNamePrefs);
|
||||||
|
final walletsService = WalletsService(secureStorageInterface: secureStore);
|
||||||
|
final prefs = Prefs.instance;
|
||||||
|
final walletInfoList = await walletsService.walletNames;
|
||||||
|
await prefs.init();
|
||||||
|
await MainDB.instance.initMainDB();
|
||||||
|
|
||||||
|
for (final walletId in walletInfoList.keys) {
|
||||||
|
final info = walletInfoList[walletId]!;
|
||||||
|
assert(info.walletId == walletId);
|
||||||
|
|
||||||
|
if (info.coin == Coin.firo &&
|
||||||
|
MainDB.instance.isar.lelantusCoins
|
||||||
|
.where()
|
||||||
|
.walletIdEqualTo(walletId)
|
||||||
|
.countSync() ==
|
||||||
|
0) {
|
||||||
|
final walletBox = await Hive.openBox<dynamic>(walletId);
|
||||||
|
|
||||||
|
final hiveLCoins = DB.instance.get<dynamic>(
|
||||||
|
boxName: walletId,
|
||||||
|
key: "_lelantus_coins",
|
||||||
|
) as List? ??
|
||||||
|
[];
|
||||||
|
|
||||||
|
final jindexes = (DB.instance
|
||||||
|
.get<dynamic>(boxName: walletId, key: "jindex") as List? ??
|
||||||
|
[])
|
||||||
|
.cast<int>();
|
||||||
|
|
||||||
|
final List<isar_models.LelantusCoin> coins = [];
|
||||||
|
for (final e in hiveLCoins) {
|
||||||
|
final map = e as Map;
|
||||||
|
final lcoin = map.values.first as LelantusCoin;
|
||||||
|
|
||||||
|
final isJMint = jindexes.contains(lcoin.index);
|
||||||
|
|
||||||
|
final coin = isar_models.LelantusCoin(
|
||||||
|
walletId: walletId,
|
||||||
|
txid: lcoin.txId,
|
||||||
|
value: lcoin.value.toString(),
|
||||||
|
mintIndex: lcoin.index,
|
||||||
|
anonymitySetId: lcoin.anonymitySetId,
|
||||||
|
isUsed: lcoin.isUsed,
|
||||||
|
isJMint: isJMint,
|
||||||
|
otherData: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
coins.add(coin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coins.isNotEmpty) {
|
||||||
|
await MainDB.instance.isar.writeTxn(() async {
|
||||||
|
await MainDB.instance.isar.lelantusCoins.putAll(coins);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _v4(SecureStorageInterface secureStore) async {
|
Future<void> _v4(SecureStorageInterface secureStore) async {
|
||||||
await Hive.openBox<dynamic>(DB.boxNameAllWalletsData);
|
await Hive.openBox<dynamic>(DB.boxNameAllWalletsData);
|
||||||
await Hive.openBox<dynamic>(DB.boxNamePrefs);
|
await Hive.openBox<dynamic>(DB.boxNamePrefs);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import 'dart:async';
|
||||||
import 'package:event_bus/event_bus.dart';
|
import 'package:event_bus/event_bus.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/services/notifications_api.dart';
|
import 'package:stackwallet/services/notifications_api.dart';
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
@ -84,6 +85,8 @@ class _CryptoNotificationsState extends ConsumerState<CryptoNotifications> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
NotificationApi.prefs = ref.read(prefsChangeNotifierProvider);
|
||||||
|
NotificationApi.notificationsService = ref.read(notificationsProvider);
|
||||||
_streamSubscription = CryptoNotificationsEventBus.instance
|
_streamSubscription = CryptoNotificationsEventBus.instance
|
||||||
.on<CryptoNotificationEvent>()
|
.on<CryptoNotificationEvent>()
|
||||||
.listen(
|
.listen(
|
||||||
|
|
|
@ -11,9 +11,7 @@ import 'package:mockito/mockito.dart';
|
||||||
import 'package:stackwallet/db/isar/main_db.dart';
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
|
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
|
||||||
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
|
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
|
|
||||||
import 'package:stackwallet/models/lelantus_coin.dart';
|
|
||||||
import 'package:stackwallet/models/lelantus_fee_data.dart';
|
import 'package:stackwallet/models/lelantus_fee_data.dart';
|
||||||
import 'package:stackwallet/models/paymint/transactions_model.dart' as old;
|
import 'package:stackwallet/models/paymint/transactions_model.dart' as old;
|
||||||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||||
|
@ -72,6 +70,7 @@ void main() {
|
||||||
setData,
|
setData,
|
||||||
List<String>.from(usedSerials),
|
List<String>.from(usedSerials),
|
||||||
firoNetwork,
|
firoNetwork,
|
||||||
|
"walletId",
|
||||||
);
|
);
|
||||||
const currentHeight = 100000000000;
|
const currentHeight = 100000000000;
|
||||||
|
|
||||||
|
@ -113,10 +112,7 @@ void main() {
|
||||||
final result = await staticProcessRestore(txData, message, currentHeight);
|
final result = await staticProcessRestore(txData, message, currentHeight);
|
||||||
|
|
||||||
expect(result, isA<Map<String, dynamic>>());
|
expect(result, isA<Map<String, dynamic>>());
|
||||||
expect(result["mintIndex"], 8);
|
expect(result["_lelantus_coins"], isA<List<LelantusCoin>>());
|
||||||
expect(result["jindex"], [2, 4, 6]);
|
|
||||||
expect(
|
|
||||||
result["_lelantus_coins"], isA<List<Map<dynamic, LelantusCoin>>>());
|
|
||||||
expect(result["newTxMap"], isA<Map<String, Transaction>>());
|
expect(result["newTxMap"], isA<Map<String, Transaction>>());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -133,6 +129,7 @@ void main() {
|
||||||
setData,
|
setData,
|
||||||
List<String>.from(usedSerials),
|
List<String>.from(usedSerials),
|
||||||
firoNetwork,
|
firoNetwork,
|
||||||
|
"walletId",
|
||||||
),
|
),
|
||||||
throwsA(isA<Error>()));
|
throwsA(isA<Error>()));
|
||||||
});
|
});
|
||||||
|
@ -530,18 +527,10 @@ void main() {
|
||||||
group("FiroWallet service class functions that depend on shared storage", () {
|
group("FiroWallet service class functions that depend on shared storage", () {
|
||||||
const testWalletId = "testWalletID";
|
const testWalletId = "testWalletID";
|
||||||
const testWalletName = "Test Wallet";
|
const testWalletName = "Test Wallet";
|
||||||
bool hiveAdaptersRegistered = false;
|
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
await setUpTestHive();
|
await setUpTestHive();
|
||||||
|
|
||||||
if (!hiveAdaptersRegistered) {
|
|
||||||
hiveAdaptersRegistered = true;
|
|
||||||
|
|
||||||
// Registering Lelantus Model Adapters
|
|
||||||
Hive.registerAdapter(LelantusCoinAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
final wallets = await Hive.openBox<dynamic>('wallets');
|
final wallets = await Hive.openBox<dynamic>('wallets');
|
||||||
await wallets.put('currentWalletName', testWalletName);
|
await wallets.put('currentWalletName', testWalletName);
|
||||||
});
|
});
|
||||||
|
@ -1202,13 +1191,33 @@ void main() {
|
||||||
txHash: BuildMintTxTestParams.utxoInfo["txid"] as String,
|
txHash: BuildMintTxTestParams.utxoInfo["txid"] as String,
|
||||||
coin: Coin.firo,
|
coin: Coin.firo,
|
||||||
)).thenAnswer((_) async => BuildMintTxTestParams.cachedClientResponse);
|
)).thenAnswer((_) async => BuildMintTxTestParams.cachedClientResponse);
|
||||||
|
when(cachedClient.getAnonymitySet(
|
||||||
|
groupId: "1",
|
||||||
|
coin: Coin.firo,
|
||||||
|
)).thenAnswer(
|
||||||
|
(_) async => GetAnonymitySetSampleData.data,
|
||||||
|
);
|
||||||
|
when(cachedClient.getAnonymitySet(
|
||||||
|
groupId: "2",
|
||||||
|
coin: Coin.firo,
|
||||||
|
)).thenAnswer(
|
||||||
|
(_) async => GetAnonymitySetSampleData.data,
|
||||||
|
);
|
||||||
|
|
||||||
when(client.getBlockHeadTip()).thenAnswer(
|
when(client.getBlockHeadTip()).thenAnswer(
|
||||||
(_) async => {"height": 455873, "hex": "this value not used here"});
|
(_) async => {"height": 455873, "hex": "this value not used here"});
|
||||||
|
when(client.getLatestCoinId()).thenAnswer((_) async => 2);
|
||||||
|
|
||||||
when(mainDB.getAddress("${testWalletId}buildMintTransaction", any))
|
when(mainDB.getAddress("${testWalletId}buildMintTransaction", any))
|
||||||
.thenAnswer((realInvocation) async => null);
|
.thenAnswer((realInvocation) async => null);
|
||||||
|
|
||||||
|
when(mainDB.getHighestUsedMintIndex(
|
||||||
|
walletId: "${testWalletId}submitHexToNetwork"))
|
||||||
|
.thenAnswer((_) async => null);
|
||||||
|
when(mainDB.getHighestUsedMintIndex(
|
||||||
|
walletId: "testWalletIDbuildMintTransaction"))
|
||||||
|
.thenAnswer((_) async => null);
|
||||||
|
|
||||||
final firo = FiroWallet(
|
final firo = FiroWallet(
|
||||||
walletName: testWalletName,
|
walletName: testWalletName,
|
||||||
walletId: "${testWalletId}buildMintTransaction",
|
walletId: "${testWalletId}buildMintTransaction",
|
||||||
|
|
|
@ -1151,4 +1151,14 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<void>.value(),
|
returnValue: _i5.Future<void>.value(),
|
||||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||||
) as _i5.Future<void>);
|
) as _i5.Future<void>);
|
||||||
|
@override
|
||||||
|
_i5.Future<int?> getHighestUsedMintIndex({required String? walletId}) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#getHighestUsedMintIndex,
|
||||||
|
[],
|
||||||
|
{#walletId: walletId},
|
||||||
|
),
|
||||||
|
returnValue: _i5.Future<int?>.value(),
|
||||||
|
) as _i5.Future<int?>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i5;
|
||||||
import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i4;
|
import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i4;
|
||||||
import 'package:stackwallet/models/balance.dart' as _i6;
|
import 'package:stackwallet/models/balance.dart' as _i6;
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i13;
|
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i13;
|
||||||
import 'package:stackwallet/models/lelantus_coin.dart' as _i15;
|
|
||||||
import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i3;
|
import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i3;
|
||||||
import 'package:stackwallet/models/signing_data.dart' as _i14;
|
import 'package:stackwallet/models/signing_data.dart' as _i14;
|
||||||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as _i10;
|
import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as _i10;
|
||||||
|
@ -589,15 +588,6 @@ class MockFiroWallet extends _i1.Mock implements _i10.FiroWallet {
|
||||||
returnValueForMissingStub: _i11.Future<void>.value(),
|
returnValueForMissingStub: _i11.Future<void>.value(),
|
||||||
) as _i11.Future<void>);
|
) as _i11.Future<void>);
|
||||||
@override
|
@override
|
||||||
List<Map<dynamic, _i15.LelantusCoin>> getLelantusCoinMap() =>
|
|
||||||
(super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#getLelantusCoinMap,
|
|
||||||
[],
|
|
||||||
),
|
|
||||||
returnValue: <Map<dynamic, _i15.LelantusCoin>>[],
|
|
||||||
) as List<Map<dynamic, _i15.LelantusCoin>>);
|
|
||||||
@override
|
|
||||||
_i11.Future<void> anonymizeAllPublicFunds() => (super.noSuchMethod(
|
_i11.Future<void> anonymizeAllPublicFunds() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#anonymizeAllPublicFunds,
|
#anonymizeAllPublicFunds,
|
||||||
|
@ -755,15 +745,6 @@ class MockFiroWallet extends _i1.Mock implements _i10.FiroWallet {
|
||||||
returnValueForMissingStub: _i11.Future<void>.value(),
|
returnValueForMissingStub: _i11.Future<void>.value(),
|
||||||
) as _i11.Future<void>);
|
) as _i11.Future<void>);
|
||||||
@override
|
@override
|
||||||
_i11.Future<dynamic> getCoinsToJoinSplit(int? required) =>
|
|
||||||
(super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#getCoinsToJoinSplit,
|
|
||||||
[required],
|
|
||||||
),
|
|
||||||
returnValue: _i11.Future<dynamic>.value(),
|
|
||||||
) as _i11.Future<dynamic>);
|
|
||||||
@override
|
|
||||||
_i11.Future<int> estimateJoinSplitFee(int? spendAmount) =>
|
_i11.Future<int> estimateJoinSplitFee(int? spendAmount) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -1061,51 +1042,6 @@ class MockFiroWallet extends _i1.Mock implements _i10.FiroWallet {
|
||||||
),
|
),
|
||||||
returnValueForMissingStub: null,
|
returnValueForMissingStub: null,
|
||||||
);
|
);
|
||||||
@override
|
|
||||||
void initFiroHive(String? walletId) => super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#initFiroHive,
|
|
||||||
[walletId],
|
|
||||||
),
|
|
||||||
returnValueForMissingStub: null,
|
|
||||||
);
|
|
||||||
@override
|
|
||||||
_i11.Future<void> firoUpdateJIndex(List<dynamic>? jIndex) =>
|
|
||||||
(super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#firoUpdateJIndex,
|
|
||||||
[jIndex],
|
|
||||||
),
|
|
||||||
returnValue: _i11.Future<void>.value(),
|
|
||||||
returnValueForMissingStub: _i11.Future<void>.value(),
|
|
||||||
) as _i11.Future<void>);
|
|
||||||
@override
|
|
||||||
_i11.Future<void> firoUpdateLelantusCoins(List<dynamic>? lelantusCoins) =>
|
|
||||||
(super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#firoUpdateLelantusCoins,
|
|
||||||
[lelantusCoins],
|
|
||||||
),
|
|
||||||
returnValue: _i11.Future<void>.value(),
|
|
||||||
returnValueForMissingStub: _i11.Future<void>.value(),
|
|
||||||
) as _i11.Future<void>);
|
|
||||||
@override
|
|
||||||
int firoGetMintIndex() => (super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#firoGetMintIndex,
|
|
||||||
[],
|
|
||||||
),
|
|
||||||
returnValue: 0,
|
|
||||||
) as int);
|
|
||||||
@override
|
|
||||||
_i11.Future<void> firoUpdateMintIndex(int? mintIndex) => (super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#firoUpdateMintIndex,
|
|
||||||
[mintIndex],
|
|
||||||
),
|
|
||||||
returnValue: _i11.Future<void>.value(),
|
|
||||||
returnValueForMissingStub: _i11.Future<void>.value(),
|
|
||||||
) as _i11.Future<void>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A class which mocks [ElectrumX].
|
/// A class which mocks [ElectrumX].
|
||||||
|
|
|
@ -1607,15 +1607,6 @@ class MockFiroWallet extends _i1.Mock implements _i23.FiroWallet {
|
||||||
returnValueForMissingStub: _i19.Future<void>.value(),
|
returnValueForMissingStub: _i19.Future<void>.value(),
|
||||||
) as _i19.Future<void>);
|
) as _i19.Future<void>);
|
||||||
@override
|
@override
|
||||||
List<Map<dynamic, _i8.LelantusCoin>> getLelantusCoinMap() =>
|
|
||||||
(super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#getLelantusCoinMap,
|
|
||||||
[],
|
|
||||||
),
|
|
||||||
returnValue: <Map<dynamic, _i8.LelantusCoin>>[],
|
|
||||||
) as List<Map<dynamic, _i8.LelantusCoin>>);
|
|
||||||
@override
|
|
||||||
_i19.Future<void> anonymizeAllPublicFunds() => (super.noSuchMethod(
|
_i19.Future<void> anonymizeAllPublicFunds() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#anonymizeAllPublicFunds,
|
#anonymizeAllPublicFunds,
|
||||||
|
@ -1773,15 +1764,6 @@ class MockFiroWallet extends _i1.Mock implements _i23.FiroWallet {
|
||||||
returnValueForMissingStub: _i19.Future<void>.value(),
|
returnValueForMissingStub: _i19.Future<void>.value(),
|
||||||
) as _i19.Future<void>);
|
) as _i19.Future<void>);
|
||||||
@override
|
@override
|
||||||
_i19.Future<dynamic> getCoinsToJoinSplit(int? required) =>
|
|
||||||
(super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#getCoinsToJoinSplit,
|
|
||||||
[required],
|
|
||||||
),
|
|
||||||
returnValue: _i19.Future<dynamic>.value(),
|
|
||||||
) as _i19.Future<dynamic>);
|
|
||||||
@override
|
|
||||||
_i19.Future<int> estimateJoinSplitFee(int? spendAmount) =>
|
_i19.Future<int> estimateJoinSplitFee(int? spendAmount) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -2080,51 +2062,6 @@ class MockFiroWallet extends _i1.Mock implements _i23.FiroWallet {
|
||||||
),
|
),
|
||||||
returnValueForMissingStub: null,
|
returnValueForMissingStub: null,
|
||||||
);
|
);
|
||||||
@override
|
|
||||||
void initFiroHive(String? walletId) => super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#initFiroHive,
|
|
||||||
[walletId],
|
|
||||||
),
|
|
||||||
returnValueForMissingStub: null,
|
|
||||||
);
|
|
||||||
@override
|
|
||||||
_i19.Future<void> firoUpdateJIndex(List<dynamic>? jIndex) =>
|
|
||||||
(super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#firoUpdateJIndex,
|
|
||||||
[jIndex],
|
|
||||||
),
|
|
||||||
returnValue: _i19.Future<void>.value(),
|
|
||||||
returnValueForMissingStub: _i19.Future<void>.value(),
|
|
||||||
) as _i19.Future<void>);
|
|
||||||
@override
|
|
||||||
_i19.Future<void> firoUpdateLelantusCoins(List<dynamic>? lelantusCoins) =>
|
|
||||||
(super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#firoUpdateLelantusCoins,
|
|
||||||
[lelantusCoins],
|
|
||||||
),
|
|
||||||
returnValue: _i19.Future<void>.value(),
|
|
||||||
returnValueForMissingStub: _i19.Future<void>.value(),
|
|
||||||
) as _i19.Future<void>);
|
|
||||||
@override
|
|
||||||
int firoGetMintIndex() => (super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#firoGetMintIndex,
|
|
||||||
[],
|
|
||||||
),
|
|
||||||
returnValue: 0,
|
|
||||||
) as int);
|
|
||||||
@override
|
|
||||||
_i19.Future<void> firoUpdateMintIndex(int? mintIndex) => (super.noSuchMethod(
|
|
||||||
Invocation.method(
|
|
||||||
#firoUpdateMintIndex,
|
|
||||||
[mintIndex],
|
|
||||||
),
|
|
||||||
returnValue: _i19.Future<void>.value(),
|
|
||||||
returnValueForMissingStub: _i19.Future<void>.value(),
|
|
||||||
) as _i19.Future<void>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A class which mocks [LocaleService].
|
/// A class which mocks [LocaleService].
|
||||||
|
@ -3564,4 +3501,14 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB {
|
||||||
returnValue: _i19.Future<void>.value(),
|
returnValue: _i19.Future<void>.value(),
|
||||||
returnValueForMissingStub: _i19.Future<void>.value(),
|
returnValueForMissingStub: _i19.Future<void>.value(),
|
||||||
) as _i19.Future<void>);
|
) as _i19.Future<void>);
|
||||||
|
@override
|
||||||
|
_i19.Future<int?> getHighestUsedMintIndex({required String? walletId}) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#getHighestUsedMintIndex,
|
||||||
|
[],
|
||||||
|
{#walletId: walletId},
|
||||||
|
),
|
||||||
|
returnValue: _i19.Future<int?>.value(),
|
||||||
|
) as _i19.Future<int?>);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue