mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-16 17:27:39 +00:00
WIP restructure w/moving from hive to isar for wallets and using coinlib
This commit is contained in:
parent
5ac7ae95cb
commit
adfe3e181e
22 changed files with 2994 additions and 104 deletions
|
@ -20,6 +20,7 @@ import 'package:stackwallet/models/isar/stack_theme.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/stack_file_system.dart';
|
import 'package:stackwallet/utilities/stack_file_system.dart';
|
||||||
|
import 'package:stackwallet/wallets/isar_models/wallet_info.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
part '../queries/queries.dart';
|
part '../queries/queries.dart';
|
||||||
|
@ -57,6 +58,7 @@ class MainDB {
|
||||||
ContactEntrySchema,
|
ContactEntrySchema,
|
||||||
OrdinalSchema,
|
OrdinalSchema,
|
||||||
LelantusCoinSchema,
|
LelantusCoinSchema,
|
||||||
|
WalletInfoSchema,
|
||||||
],
|
],
|
||||||
directory: (await StackFileSystem.applicationIsarDirectory()).path,
|
directory: (await StackFileSystem.applicationIsarDirectory()).path,
|
||||||
// inspector: kDebugMode,
|
// inspector: kDebugMode,
|
||||||
|
@ -67,6 +69,41 @@ class MainDB {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> putWalletInfo(WalletInfo walletInfo) async {
|
||||||
|
try {
|
||||||
|
await isar.writeTxn(() async {
|
||||||
|
await isar.walletInfo.put(walletInfo);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw MainDBException("failed putWalletInfo()", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updateWalletInfo(WalletInfo walletInfo) async {
|
||||||
|
try {
|
||||||
|
await isar.writeTxn(() async {
|
||||||
|
final info = await isar.walletInfo
|
||||||
|
.where()
|
||||||
|
.walletIdEqualTo(walletInfo.walletId)
|
||||||
|
.findFirst();
|
||||||
|
if (info == null) {
|
||||||
|
throw Exception("updateWalletInfo() called with new WalletInfo."
|
||||||
|
" Use putWalletInfo()");
|
||||||
|
}
|
||||||
|
|
||||||
|
await isar.walletInfo.deleteByWalletId(walletInfo.walletId);
|
||||||
|
await isar.walletInfo.put(walletInfo);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw MainDBException("failed updateWalletInfo()", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO refactor this elsewhere as it not only interacts with MainDB's isar
|
||||||
|
Future<void> deleteWallet({required String walletId}) async {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
// contact entries
|
// contact entries
|
||||||
List<ContactEntry> getContactEntries() {
|
List<ContactEntry> getContactEntries() {
|
||||||
return isar.contactEntrys.where().sortByName().findAllSync();
|
return isar.contactEntrys.where().sortByName().findAllSync();
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
|
||||||
class Balance {
|
class Balance {
|
||||||
final Amount total;
|
final Amount total;
|
||||||
|
@ -25,6 +26,20 @@ class Balance {
|
||||||
required this.pendingSpendable,
|
required this.pendingSpendable,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
factory Balance.zeroForCoin({required Coin coin}) {
|
||||||
|
final amount = Amount(
|
||||||
|
rawValue: BigInt.zero,
|
||||||
|
fractionDigits: coin.decimals,
|
||||||
|
);
|
||||||
|
|
||||||
|
return Balance(
|
||||||
|
total: amount,
|
||||||
|
spendable: amount,
|
||||||
|
blockedTotal: amount,
|
||||||
|
pendingSpendable: amount,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
String toJsonIgnoreCoin() => jsonEncode({
|
String toJsonIgnoreCoin() => jsonEncode({
|
||||||
"total": total.toJsonString(),
|
"total": total.toJsonString(),
|
||||||
"spendable": spendable.toJsonString(),
|
"spendable": spendable.toJsonString(),
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
|
import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
|
import 'package:stackwallet/wallets/models/tx_recipient.dart';
|
||||||
|
|
||||||
// TODO use something like this instead of Map<String, dynamic> transactionObject
|
// TODO use something like this instead of Map<String, dynamic> transactionObject
|
||||||
|
|
||||||
|
@ -43,13 +44,3 @@ class TxInfo {
|
||||||
recipients: recipients ?? this.recipients,
|
recipients: recipients ?? this.recipients,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class TxRecipient {
|
|
||||||
final String address;
|
|
||||||
final Amount amount;
|
|
||||||
|
|
||||||
TxRecipient({
|
|
||||||
required this.address,
|
|
||||||
required this.amount,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
22
lib/wallets/coin/bip39_hd_currency.dart
Normal file
22
lib/wallets/coin/bip39_hd_currency.dart
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import 'package:coinlib/coinlib.dart' as coinlib;
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
|
||||||
|
import 'package:stackwallet/wallets/coin/crypto_currency.dart';
|
||||||
|
|
||||||
|
abstract class Bip39HDCurrency extends CryptoCurrency {
|
||||||
|
Bip39HDCurrency(super.network);
|
||||||
|
|
||||||
|
coinlib.NetworkParams get networkParams;
|
||||||
|
|
||||||
|
String constructDerivePath({
|
||||||
|
required DerivePathType derivePathType,
|
||||||
|
int account = 0,
|
||||||
|
required int chain,
|
||||||
|
required int index,
|
||||||
|
});
|
||||||
|
|
||||||
|
({coinlib.Address address, AddressType addressType}) getAddressForPublicKey({
|
||||||
|
required coinlib.ECPublicKey publicKey,
|
||||||
|
required DerivePathType derivePathType,
|
||||||
|
});
|
||||||
|
}
|
29
lib/wallets/coin/coin_params.dart
Normal file
29
lib/wallets/coin/coin_params.dart
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import 'package:coinlib/coinlib.dart';
|
||||||
|
|
||||||
|
abstract class CoinParams {
|
||||||
|
static const bitcoin = BitcoinParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
class BitcoinParams {
|
||||||
|
const BitcoinParams();
|
||||||
|
|
||||||
|
final NetworkParams mainNet = const NetworkParams(
|
||||||
|
wifPrefix: 0x80,
|
||||||
|
p2pkhPrefix: 0x00,
|
||||||
|
p2shPrefix: 0x05,
|
||||||
|
privHDPrefix: 0x0488ade4,
|
||||||
|
pubHDPrefix: 0x0488b21e,
|
||||||
|
bech32Hrp: "bc",
|
||||||
|
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
||||||
|
);
|
||||||
|
|
||||||
|
final NetworkParams testNet = const NetworkParams(
|
||||||
|
wifPrefix: 0xef,
|
||||||
|
p2pkhPrefix: 0x6f,
|
||||||
|
p2shPrefix: 0xc4,
|
||||||
|
privHDPrefix: 0x04358394,
|
||||||
|
pubHDPrefix: 0x043587cf,
|
||||||
|
bech32Hrp: "tb",
|
||||||
|
messagePrefix: "\x18Bitcoin Signed Message:\n",
|
||||||
|
);
|
||||||
|
}
|
115
lib/wallets/coin/coins/bitcoin.dart
Normal file
115
lib/wallets/coin/coins/bitcoin.dart
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
import 'package:coinlib/coinlib.dart' as coinlib;
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
|
||||||
|
import 'package:stackwallet/wallets/coin/bip39_hd_currency.dart';
|
||||||
|
import 'package:stackwallet/wallets/coin/coin_params.dart';
|
||||||
|
import 'package:stackwallet/wallets/coin/crypto_currency.dart';
|
||||||
|
|
||||||
|
class Bitcoin extends Bip39HDCurrency {
|
||||||
|
Bitcoin(super.network) {
|
||||||
|
switch (network) {
|
||||||
|
case CryptoCurrencyNetwork.main:
|
||||||
|
coin = Coin.bitcoin;
|
||||||
|
case CryptoCurrencyNetwork.test:
|
||||||
|
coin = Coin.bitcoinTestNet;
|
||||||
|
default:
|
||||||
|
throw Exception("Unsupported network: $network");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
coinlib.NetworkParams get networkParams {
|
||||||
|
switch (network) {
|
||||||
|
case CryptoCurrencyNetwork.main:
|
||||||
|
return CoinParams.bitcoin.mainNet;
|
||||||
|
case CryptoCurrencyNetwork.test:
|
||||||
|
return CoinParams.bitcoin.testNet;
|
||||||
|
default:
|
||||||
|
throw Exception("Unsupported network: $network");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String constructDerivePath({
|
||||||
|
required DerivePathType derivePathType,
|
||||||
|
int account = 0,
|
||||||
|
required int chain,
|
||||||
|
required int index,
|
||||||
|
}) {
|
||||||
|
String coinType;
|
||||||
|
|
||||||
|
if (networkParams.wifPrefix == CoinParams.bitcoin.mainNet.wifPrefix) {
|
||||||
|
coinType = "0"; // btc mainnet
|
||||||
|
} else if (networkParams.wifPrefix ==
|
||||||
|
CoinParams.bitcoin.testNet.wifPrefix) {
|
||||||
|
coinType = "1"; // btc testnet
|
||||||
|
} else {
|
||||||
|
throw Exception("Invalid Bitcoin network wif used!");
|
||||||
|
}
|
||||||
|
|
||||||
|
int purpose;
|
||||||
|
switch (derivePathType) {
|
||||||
|
case DerivePathType.bip44:
|
||||||
|
purpose = 44;
|
||||||
|
break;
|
||||||
|
case DerivePathType.bip49:
|
||||||
|
purpose = 49;
|
||||||
|
break;
|
||||||
|
case DerivePathType.bip84:
|
||||||
|
purpose = 84;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Exception("DerivePathType $derivePathType not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
return "m/$purpose'/$coinType'/$account'/$chain/$index";
|
||||||
|
}
|
||||||
|
|
||||||
|
({coinlib.Address address, AddressType addressType}) getAddressForPublicKey({
|
||||||
|
required coinlib.ECPublicKey publicKey,
|
||||||
|
required DerivePathType derivePathType,
|
||||||
|
}) {
|
||||||
|
switch (derivePathType) {
|
||||||
|
case DerivePathType.bip44:
|
||||||
|
final addr = coinlib.P2PKHAddress.fromPublicKey(
|
||||||
|
publicKey,
|
||||||
|
version: networkParams.p2pkhPrefix,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (address: addr, addressType: AddressType.p2sh);
|
||||||
|
break;
|
||||||
|
case DerivePathType.bip49:
|
||||||
|
// addressString = P2SH(
|
||||||
|
// data: PaymentData(
|
||||||
|
// redeem: P2WPKH(data: data, network: _network).data),
|
||||||
|
// network: _network)
|
||||||
|
// .data
|
||||||
|
// .address!;
|
||||||
|
|
||||||
|
// todo ?????????????????? Does not match with current BTC
|
||||||
|
final adr = coinlib.P2WPKHAddress.fromPublicKey(
|
||||||
|
publicKey,
|
||||||
|
hrp: networkParams.bech32Hrp,
|
||||||
|
);
|
||||||
|
final addr = coinlib.P2SHAddress.fromHash(
|
||||||
|
adr.program.pkHash,
|
||||||
|
version: networkParams.p2shPrefix,
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO ??????????????
|
||||||
|
return (address: addr, addressType: AddressType.p2sh);
|
||||||
|
|
||||||
|
case DerivePathType.bip84:
|
||||||
|
final addr = coinlib.P2WPKHAddress.fromPublicKey(
|
||||||
|
publicKey,
|
||||||
|
hrp: networkParams.bech32Hrp,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (address: addr, addressType: AddressType.p2wpkh);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Exception("DerivePathType $derivePathType not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
lib/wallets/coin/crypto_currency.dart
Normal file
16
lib/wallets/coin/crypto_currency.dart
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
|
||||||
|
enum CryptoCurrencyNetwork {
|
||||||
|
main,
|
||||||
|
test,
|
||||||
|
stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CryptoCurrency {
|
||||||
|
@Deprecated("Should eventually move away from Coin enum")
|
||||||
|
late final Coin coin;
|
||||||
|
|
||||||
|
final CryptoCurrencyNetwork network;
|
||||||
|
|
||||||
|
CryptoCurrency(this.network);
|
||||||
|
}
|
149
lib/wallets/isar_models/wallet_info.dart
Normal file
149
lib/wallets/isar_models/wallet_info.dart
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/models/balance.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
|
||||||
|
part 'wallet_info.g.dart';
|
||||||
|
|
||||||
|
@Collection(accessor: "walletInfo")
|
||||||
|
class WalletInfo {
|
||||||
|
Id id = Isar.autoIncrement;
|
||||||
|
|
||||||
|
@Index(unique: true, replace: false)
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
@enumerated
|
||||||
|
final WalletType walletType;
|
||||||
|
|
||||||
|
@enumerated
|
||||||
|
final AddressType mainAddressType;
|
||||||
|
|
||||||
|
/// Only exposed for Isar. Use the [cachedBalance] getter.
|
||||||
|
// Only exposed for isar as Amount cannot be stored in isar easily
|
||||||
|
final String? cachedBalanceString;
|
||||||
|
|
||||||
|
/// Only exposed for Isar. Use the [coin] getter.
|
||||||
|
// Only exposed for isar to avoid dealing with storing enums as Coin can change
|
||||||
|
final String coinName;
|
||||||
|
|
||||||
|
final bool isFavourite;
|
||||||
|
|
||||||
|
/// User set favourites ordering. No restrictions are placed on uniqueness.
|
||||||
|
/// Reordering logic in the ui code should ensure this is unique.
|
||||||
|
final int favouriteOrderIndex;
|
||||||
|
|
||||||
|
/// Wallets without this flag set to true should be deleted on next app run
|
||||||
|
/// and should not be displayed in the ui.
|
||||||
|
final bool isMnemonicVerified;
|
||||||
|
|
||||||
|
/// The highest block height the wallet has scanned.
|
||||||
|
final int cachedChainHeight;
|
||||||
|
|
||||||
|
/// Wallet creation chain height. Applies to select coin only.
|
||||||
|
final int creationHeight;
|
||||||
|
|
||||||
|
/// Wallet restore chain height. Applies to select coin only.
|
||||||
|
final int restoreHeight;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
@ignore
|
||||||
|
Coin get coin => Coin.values.byName(coinName);
|
||||||
|
|
||||||
|
@ignore
|
||||||
|
Balance get cachedBalance {
|
||||||
|
if (cachedBalanceString == null) {
|
||||||
|
return Balance.zeroForCoin(coin: coin);
|
||||||
|
} else {
|
||||||
|
return Balance.fromJson(cachedBalanceString!, coin.decimals);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletInfo({
|
||||||
|
required this.coinName,
|
||||||
|
required this.walletId,
|
||||||
|
required this.name,
|
||||||
|
required this.walletType,
|
||||||
|
required this.mainAddressType,
|
||||||
|
this.isFavourite = false,
|
||||||
|
this.favouriteOrderIndex = 0,
|
||||||
|
this.cachedChainHeight = 0,
|
||||||
|
this.creationHeight = 0,
|
||||||
|
this.restoreHeight = 0,
|
||||||
|
this.isMnemonicVerified = false,
|
||||||
|
this.cachedBalanceString,
|
||||||
|
}) : assert(
|
||||||
|
Coin.values.map((e) => e.name).contains(coinName),
|
||||||
|
);
|
||||||
|
|
||||||
|
WalletInfo copyWith({
|
||||||
|
String? coinName,
|
||||||
|
String? name,
|
||||||
|
bool? isFavourite,
|
||||||
|
int? favouriteOrderIndex,
|
||||||
|
int? cachedChainHeight,
|
||||||
|
int? creationHeight,
|
||||||
|
int? restoreHeight,
|
||||||
|
bool? isMnemonicVerified,
|
||||||
|
String? cachedBalanceString,
|
||||||
|
}) {
|
||||||
|
return WalletInfo(
|
||||||
|
coinName: coinName ?? this.coinName,
|
||||||
|
walletId: walletId,
|
||||||
|
name: name ?? this.name,
|
||||||
|
walletType: walletType,
|
||||||
|
mainAddressType: mainAddressType,
|
||||||
|
isFavourite: isFavourite ?? this.isFavourite,
|
||||||
|
favouriteOrderIndex: favouriteOrderIndex ?? this.favouriteOrderIndex,
|
||||||
|
cachedChainHeight: cachedChainHeight ?? this.cachedChainHeight,
|
||||||
|
creationHeight: creationHeight ?? this.creationHeight,
|
||||||
|
restoreHeight: restoreHeight ?? this.restoreHeight,
|
||||||
|
isMnemonicVerified: isMnemonicVerified ?? this.isMnemonicVerified,
|
||||||
|
cachedBalanceString: cachedBalanceString ?? this.cachedBalanceString,
|
||||||
|
)..id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Legacy support")
|
||||||
|
factory WalletInfo.fromJson(Map<String, dynamic> jsonObject,
|
||||||
|
WalletType walletType, AddressType mainAddressType) {
|
||||||
|
final coin = Coin.values.byName(jsonObject["coin"] as String);
|
||||||
|
return WalletInfo(
|
||||||
|
coinName: coin.name,
|
||||||
|
walletId: jsonObject["id"] as String,
|
||||||
|
name: jsonObject["name"] as String,
|
||||||
|
walletType: walletType,
|
||||||
|
mainAddressType: mainAddressType,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Legacy support")
|
||||||
|
Map<String, String> toMap() {
|
||||||
|
return {
|
||||||
|
"name": name,
|
||||||
|
"id": walletId,
|
||||||
|
"coin": coin.name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Legacy support")
|
||||||
|
String toJsonString() {
|
||||||
|
return jsonEncode(toMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return "WalletInfo: ${toJsonString()}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used in Isar db and stored there as int indexes so adding/removing values
|
||||||
|
// in this definition should be done extremely carefully in production
|
||||||
|
enum WalletType {
|
||||||
|
bip39,
|
||||||
|
cryptonote,
|
||||||
|
privateKeyBased;
|
||||||
|
}
|
1900
lib/wallets/isar_models/wallet_info.g.dart
Normal file
1900
lib/wallets/isar_models/wallet_info.g.dart
Normal file
File diff suppressed because it is too large
Load diff
106
lib/wallets/models/tx_data.dart
Normal file
106
lib/wallets/models/tx_data.dart
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
|
||||||
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
|
||||||
|
|
||||||
|
class TxData {
|
||||||
|
final FeeRateType? feeRateType;
|
||||||
|
final int? feeRateAmount;
|
||||||
|
final int? satsPerVByte;
|
||||||
|
|
||||||
|
final Amount? fee;
|
||||||
|
final int? vSize;
|
||||||
|
|
||||||
|
final String? raw;
|
||||||
|
|
||||||
|
final String? txid;
|
||||||
|
final String? txHash;
|
||||||
|
|
||||||
|
final String? note;
|
||||||
|
final String? noteOnChain;
|
||||||
|
|
||||||
|
final List<({String address, Amount amount})>? recipients;
|
||||||
|
final Set<UTXO>? utxos;
|
||||||
|
|
||||||
|
final String? changeAddress;
|
||||||
|
|
||||||
|
final String? frostMSConfig;
|
||||||
|
|
||||||
|
TxData({
|
||||||
|
this.feeRateType,
|
||||||
|
this.feeRateAmount,
|
||||||
|
this.satsPerVByte,
|
||||||
|
this.fee,
|
||||||
|
this.vSize,
|
||||||
|
this.raw,
|
||||||
|
this.txid,
|
||||||
|
this.txHash,
|
||||||
|
this.note,
|
||||||
|
this.noteOnChain,
|
||||||
|
this.recipients,
|
||||||
|
this.utxos,
|
||||||
|
this.changeAddress,
|
||||||
|
this.frostMSConfig,
|
||||||
|
});
|
||||||
|
|
||||||
|
Amount? get amount => recipients != null && recipients!.isNotEmpty
|
||||||
|
? recipients!
|
||||||
|
.map((e) => e.amount)
|
||||||
|
.reduce((total, amount) => total += amount)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
int? get estimatedSatsPerVByte => fee != null && vSize != null
|
||||||
|
? (fee!.raw ~/ BigInt.from(vSize!)).toInt()
|
||||||
|
: null;
|
||||||
|
|
||||||
|
TxData copyWith({
|
||||||
|
FeeRateType? feeRateType,
|
||||||
|
int? feeRateAmount,
|
||||||
|
int? satsPerVByte,
|
||||||
|
Amount? fee,
|
||||||
|
int? vSize,
|
||||||
|
String? raw,
|
||||||
|
String? txid,
|
||||||
|
String? txHash,
|
||||||
|
String? note,
|
||||||
|
String? noteOnChain,
|
||||||
|
Set<UTXO>? utxos,
|
||||||
|
List<({String address, Amount amount})>? recipients,
|
||||||
|
String? frostMSConfig,
|
||||||
|
String? changeAddress,
|
||||||
|
}) {
|
||||||
|
return TxData(
|
||||||
|
feeRateType: feeRateType ?? this.feeRateType,
|
||||||
|
feeRateAmount: feeRateAmount ?? this.feeRateAmount,
|
||||||
|
satsPerVByte: satsPerVByte ?? this.satsPerVByte,
|
||||||
|
fee: fee ?? this.fee,
|
||||||
|
vSize: vSize ?? this.vSize,
|
||||||
|
raw: raw ?? this.raw,
|
||||||
|
txid: txid ?? this.txid,
|
||||||
|
txHash: txHash ?? this.txHash,
|
||||||
|
note: note ?? this.note,
|
||||||
|
noteOnChain: noteOnChain ?? this.noteOnChain,
|
||||||
|
utxos: utxos ?? this.utxos,
|
||||||
|
recipients: recipients ?? this.recipients,
|
||||||
|
frostMSConfig: frostMSConfig ?? this.frostMSConfig,
|
||||||
|
changeAddress: changeAddress ?? this.changeAddress,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'TxData{'
|
||||||
|
'feeRateType: $feeRateType, '
|
||||||
|
'feeRateAmount: $feeRateAmount, '
|
||||||
|
'satsPerVByte: $satsPerVByte, '
|
||||||
|
'fee: $fee, '
|
||||||
|
'vSize: $vSize, '
|
||||||
|
'raw: $raw, '
|
||||||
|
'txid: $txid, '
|
||||||
|
'txHash: $txHash, '
|
||||||
|
'note: $note, '
|
||||||
|
'noteOnChain: $noteOnChain, '
|
||||||
|
'recipients: $recipients, '
|
||||||
|
'utxos: $utxos, '
|
||||||
|
'frostMSConfig: $frostMSConfig, '
|
||||||
|
'changeAddress: $changeAddress'
|
||||||
|
'}';
|
||||||
|
}
|
11
lib/wallets/models/tx_recipient.dart
Normal file
11
lib/wallets/models/tx_recipient.dart
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
|
|
||||||
|
class TxRecipient {
|
||||||
|
final String address;
|
||||||
|
final Amount amount;
|
||||||
|
|
||||||
|
TxRecipient({
|
||||||
|
required this.address,
|
||||||
|
required this.amount,
|
||||||
|
});
|
||||||
|
}
|
152
lib/wallets/wallet/bip39_hd_wallet.dart
Normal file
152
lib/wallets/wallet/bip39_hd_wallet.dart
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
import 'package:bip39/bip39.dart' as bip39;
|
||||||
|
import 'package:coinlib/coinlib.dart' as coinlib;
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/exceptions/sw_exception.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
|
||||||
|
import 'package:stackwallet/wallets/coin/bip39_hd_currency.dart';
|
||||||
|
import 'package:stackwallet/wallets/models/tx_data.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
||||||
|
|
||||||
|
class Bip39HDWallet<T extends Bip39HDCurrency> extends Wallet<T> {
|
||||||
|
Bip39HDWallet(super.cryptoCurrency);
|
||||||
|
|
||||||
|
/// Generates a receiving address of [walletInfo.mainAddressType]. If none
|
||||||
|
/// are in the current wallet db it will generate at index 0, otherwise the
|
||||||
|
/// highest index found in the current wallet db.
|
||||||
|
Future<Address> generateNewReceivingAddress() async {
|
||||||
|
final current = await _currentReceivingAddress;
|
||||||
|
final index = current?.derivationIndex ?? 0;
|
||||||
|
const chain = 0; // receiving address
|
||||||
|
|
||||||
|
final DerivePathType derivePathType;
|
||||||
|
switch (walletInfo.mainAddressType) {
|
||||||
|
case AddressType.p2pkh:
|
||||||
|
derivePathType = DerivePathType.bip44;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AddressType.p2sh:
|
||||||
|
derivePathType = DerivePathType.bip44;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AddressType.p2wpkh:
|
||||||
|
derivePathType = DerivePathType.bip44;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw Exception(
|
||||||
|
"Invalid AddressType accessed in $runtimeType generateNewReceivingAddress()",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final address = await _generateAddress(
|
||||||
|
chain: chain,
|
||||||
|
index: index,
|
||||||
|
derivePathType: derivePathType,
|
||||||
|
);
|
||||||
|
|
||||||
|
await mainDB.putAddress(address);
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> getMnemonic() async {
|
||||||
|
final mnemonic = await secureStorageInterface.read(
|
||||||
|
key: Wallet.mnemonicKey(walletId: walletInfo.walletId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mnemonic == null) {
|
||||||
|
throw SWException("mnemonic has not been set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return mnemonic;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> getMnemonicPassphrase() async {
|
||||||
|
final mnemonicPassphrase = await secureStorageInterface.read(
|
||||||
|
key: Wallet.mnemonicPassphraseKey(walletId: walletInfo.walletId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mnemonicPassphrase == null) {
|
||||||
|
throw SWException("mnemonicPassphrase has not been set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return mnemonicPassphrase;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== Private ========================================================
|
||||||
|
|
||||||
|
Future<Address?> get _currentReceivingAddress async =>
|
||||||
|
await mainDB.isar.addresses
|
||||||
|
.where()
|
||||||
|
.walletIdEqualTo(walletId)
|
||||||
|
.filter()
|
||||||
|
.typeEqualTo(walletInfo.mainAddressType)
|
||||||
|
.subTypeEqualTo(AddressSubType.receiving)
|
||||||
|
.sortByDerivationIndexDesc()
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
Future<coinlib.HDPrivateKey> _generateRootHDNode() async {
|
||||||
|
final seed = bip39.mnemonicToSeed(
|
||||||
|
await getMnemonic(),
|
||||||
|
passphrase: await getMnemonicPassphrase(),
|
||||||
|
);
|
||||||
|
return coinlib.HDPrivateKey.fromSeed(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Address> _generateAddress({
|
||||||
|
required int chain,
|
||||||
|
required int index,
|
||||||
|
required DerivePathType derivePathType,
|
||||||
|
}) async {
|
||||||
|
final root = await _generateRootHDNode();
|
||||||
|
|
||||||
|
final derivationPath = cryptoCurrency.constructDerivePath(
|
||||||
|
derivePathType: derivePathType,
|
||||||
|
chain: chain,
|
||||||
|
index: index,
|
||||||
|
);
|
||||||
|
|
||||||
|
final keys = root.derivePath(derivationPath);
|
||||||
|
|
||||||
|
final data = cryptoCurrency.getAddressForPublicKey(
|
||||||
|
publicKey: keys.publicKey,
|
||||||
|
derivePathType: derivePathType,
|
||||||
|
);
|
||||||
|
|
||||||
|
final AddressSubType subType;
|
||||||
|
|
||||||
|
if (chain == 0) {
|
||||||
|
subType = AddressSubType.receiving;
|
||||||
|
} else if (chain == 1) {
|
||||||
|
subType = AddressSubType.change;
|
||||||
|
} else {
|
||||||
|
// TODO others?
|
||||||
|
subType = AddressSubType.unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Address(
|
||||||
|
walletId: walletId,
|
||||||
|
value: data.address.toString(),
|
||||||
|
publicKey: keys.publicKey.data,
|
||||||
|
derivationIndex: index,
|
||||||
|
derivationPath: DerivationPath()..value = derivationPath,
|
||||||
|
type: data.addressType,
|
||||||
|
subType: subType,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== Overrides ======================================================
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TxData> confirmSend({required TxData txData}) {
|
||||||
|
// TODO: implement confirmSend
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TxData> prepareSend({required TxData txData}) {
|
||||||
|
// TODO: implement prepareSend
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
33
lib/wallets/wallet/cryptonote_wallet.dart
Normal file
33
lib/wallets/wallet/cryptonote_wallet.dart
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import 'package:stackwallet/exceptions/sw_exception.dart';
|
||||||
|
import 'package:stackwallet/wallets/models/tx_data.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
||||||
|
|
||||||
|
class CryptonoteWallet extends Wallet {
|
||||||
|
CryptonoteWallet(super.cryptoCurrency);
|
||||||
|
|
||||||
|
Future<String> getMnemonic() async {
|
||||||
|
final mnemonic = await secureStorageInterface.read(
|
||||||
|
key: Wallet.mnemonicKey(walletId: walletInfo.walletId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mnemonic == null) {
|
||||||
|
throw SWException("mnemonic has not been set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return mnemonic;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== Overrides ======================================================
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TxData> confirmSend({required TxData txData}) {
|
||||||
|
// TODO: implement confirmSend
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TxData> prepareSend({required TxData txData}) {
|
||||||
|
// TODO: implement prepareSend
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
33
lib/wallets/wallet/private_key_based_wallet.dart
Normal file
33
lib/wallets/wallet/private_key_based_wallet.dart
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import 'package:stackwallet/exceptions/sw_exception.dart';
|
||||||
|
import 'package:stackwallet/wallets/models/tx_data.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
||||||
|
|
||||||
|
class PrivateKeyBasedWallet extends Wallet {
|
||||||
|
PrivateKeyBasedWallet(super.cryptoCurrency);
|
||||||
|
|
||||||
|
Future<String> getPrivateKey() async {
|
||||||
|
final privateKey = await secureStorageInterface.read(
|
||||||
|
key: Wallet.privateKeyKey(walletId: walletInfo.walletId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (privateKey == null) {
|
||||||
|
throw SWException("privateKey has not been set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== Overrides ======================================================
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TxData> confirmSend({required TxData txData}) {
|
||||||
|
// TODO: implement confirmSend
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TxData> prepareSend({required TxData txData}) {
|
||||||
|
// TODO: implement prepareSend
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
174
lib/wallets/wallet/wallet.dart
Normal file
174
lib/wallets/wallet/wallet.dart
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
|
||||||
|
import 'package:stackwallet/wallets/coin/bip39_hd_currency.dart';
|
||||||
|
import 'package:stackwallet/wallets/coin/coins/bitcoin.dart';
|
||||||
|
import 'package:stackwallet/wallets/coin/crypto_currency.dart';
|
||||||
|
import 'package:stackwallet/wallets/isar_models/wallet_info.dart';
|
||||||
|
import 'package:stackwallet/wallets/models/tx_data.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/bip39_hd_wallet.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/private_key_based_wallet.dart';
|
||||||
|
|
||||||
|
abstract class Wallet<T extends CryptoCurrency> {
|
||||||
|
Wallet(this.cryptoCurrency);
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// ========== Properties =====================================================
|
||||||
|
|
||||||
|
final T cryptoCurrency;
|
||||||
|
|
||||||
|
late final MainDB mainDB;
|
||||||
|
late final SecureStorageInterface secureStorageInterface;
|
||||||
|
late final WalletInfo walletInfo;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// ========== Wallet Info Convenience Getters ================================
|
||||||
|
|
||||||
|
String get walletId => walletInfo.walletId;
|
||||||
|
WalletType get walletType => walletInfo.walletType;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// ========== Static Main ====================================================
|
||||||
|
|
||||||
|
/// Create a new wallet and save [walletInfo] to db.
|
||||||
|
static Future<Wallet> create({
|
||||||
|
required WalletInfo walletInfo,
|
||||||
|
required MainDB mainDB,
|
||||||
|
required SecureStorageInterface secureStorageInterface,
|
||||||
|
String? mnemonic,
|
||||||
|
String? mnemonicPassphrase,
|
||||||
|
String? privateKey,
|
||||||
|
int? startDate,
|
||||||
|
}) async {
|
||||||
|
final Wallet wallet = await _construct(
|
||||||
|
walletInfo: walletInfo,
|
||||||
|
mainDB: mainDB,
|
||||||
|
secureStorageInterface: secureStorageInterface,
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (walletInfo.walletType) {
|
||||||
|
case WalletType.bip39:
|
||||||
|
await secureStorageInterface.write(
|
||||||
|
key: mnemonicKey(walletId: walletInfo.walletId),
|
||||||
|
value: mnemonic,
|
||||||
|
);
|
||||||
|
await secureStorageInterface.write(
|
||||||
|
key: mnemonicPassphraseKey(walletId: walletInfo.walletId),
|
||||||
|
value: mnemonicPassphrase,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WalletType.cryptonote:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WalletType.privateKeyBased:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store in db after wallet creation
|
||||||
|
await wallet.mainDB.isar.walletInfo.put(wallet.walletInfo);
|
||||||
|
|
||||||
|
return wallet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load an existing wallet via [WalletInfo] using [walletId].
|
||||||
|
static Future<Wallet> load({
|
||||||
|
required String walletId,
|
||||||
|
required MainDB mainDB,
|
||||||
|
required SecureStorageInterface secureStorageInterface,
|
||||||
|
}) async {
|
||||||
|
final walletInfo = await mainDB.isar.walletInfo
|
||||||
|
.where()
|
||||||
|
.walletIdEqualTo(walletId)
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
if (walletInfo == null) {
|
||||||
|
throw Exception(
|
||||||
|
"WalletInfo not found for $walletId when trying to call Wallet.load()",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await _construct(
|
||||||
|
walletInfo: walletInfo!,
|
||||||
|
mainDB: mainDB,
|
||||||
|
secureStorageInterface: secureStorageInterface,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// ========== Static Util ====================================================
|
||||||
|
|
||||||
|
static String mnemonicKey({
|
||||||
|
required String walletId,
|
||||||
|
}) =>
|
||||||
|
"${walletId}_mnemonic";
|
||||||
|
|
||||||
|
static String mnemonicPassphraseKey({
|
||||||
|
required String walletId,
|
||||||
|
}) =>
|
||||||
|
"${walletId}_mnemonicPassphrase";
|
||||||
|
|
||||||
|
static String privateKeyKey({
|
||||||
|
required String walletId,
|
||||||
|
}) =>
|
||||||
|
"${walletId}_privateKey";
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// ========== Private ========================================================
|
||||||
|
|
||||||
|
/// Construct wallet instance by [WalletType] from [walletInfo]
|
||||||
|
static Future<Wallet> _construct({
|
||||||
|
required WalletInfo walletInfo,
|
||||||
|
required MainDB mainDB,
|
||||||
|
required SecureStorageInterface secureStorageInterface,
|
||||||
|
}) async {
|
||||||
|
final Wallet wallet;
|
||||||
|
|
||||||
|
final cryptoCurrency = _loadCurrency(walletInfo: walletInfo);
|
||||||
|
|
||||||
|
switch (walletInfo.walletType) {
|
||||||
|
case WalletType.bip39:
|
||||||
|
wallet = Bip39HDWallet(cryptoCurrency as Bip39HDCurrency);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WalletType.cryptonote:
|
||||||
|
wallet = PrivateKeyBasedWallet(cryptoCurrency);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WalletType.privateKeyBased:
|
||||||
|
wallet = PrivateKeyBasedWallet(cryptoCurrency);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wallet
|
||||||
|
..secureStorageInterface = secureStorageInterface
|
||||||
|
..mainDB = mainDB
|
||||||
|
..walletInfo = walletInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CryptoCurrency _loadCurrency({
|
||||||
|
required WalletInfo walletInfo,
|
||||||
|
}) {
|
||||||
|
switch (walletInfo.coin) {
|
||||||
|
case Coin.bitcoin:
|
||||||
|
return Bitcoin(CryptoCurrencyNetwork.main);
|
||||||
|
case Coin.bitcoinTestNet:
|
||||||
|
return Bitcoin(CryptoCurrencyNetwork.test);
|
||||||
|
|
||||||
|
default:
|
||||||
|
// should never hit in reality
|
||||||
|
throw Exception("Unknown cryupto currency");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// ========== Must override ==================================================
|
||||||
|
|
||||||
|
/// Create and sign a transaction in preparation to submit to network
|
||||||
|
Future<TxData> prepareSend({required TxData txData});
|
||||||
|
|
||||||
|
/// Broadcast transaction to network. On success update local wallet state to
|
||||||
|
/// reflect updated balance, transactions, utxos, etc.
|
||||||
|
Future<TxData> confirmSend({required TxData txData});
|
||||||
|
}
|
3
lib/wallets/wallet_mixins/electrumx_mixin.dart
Normal file
3
lib/wallets/wallet_mixins/electrumx_mixin.dart
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
mixin ElectrumXMixin {
|
||||||
|
//
|
||||||
|
}
|
15
lib/wallets/wallets_service.dart
Normal file
15
lib/wallets/wallets_service.dart
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
|
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
|
||||||
|
|
||||||
|
class WalletsService {
|
||||||
|
late final SecureStorageInterface _secureStore;
|
||||||
|
late final MainDB _mainDB;
|
||||||
|
|
||||||
|
WalletsService({
|
||||||
|
required SecureStorageInterface secureStorageInterface,
|
||||||
|
required MainDB mainDB,
|
||||||
|
}) {
|
||||||
|
_secureStore = secureStorageInterface;
|
||||||
|
_mainDB = mainDB;
|
||||||
|
}
|
||||||
|
}
|
16
pubspec.lock
16
pubspec.lock
|
@ -254,6 +254,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.5.0"
|
version: "4.5.0"
|
||||||
|
coinlib:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: coinlib
|
||||||
|
sha256: c8018027801ddcb093837ad8f27e9ac014434b84860ecd3114ca28980614ec4a
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0-rc.3"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1844,6 +1852,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.12+1"
|
version: "0.0.12+1"
|
||||||
|
wasm_interop:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: wasm_interop
|
||||||
|
sha256: b1b378f07a4cf0103c25faf34d9a64d2c3312135b9efb47e0ec116ec3b14e48f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.1"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -144,6 +144,7 @@ dependencies:
|
||||||
stellar_flutter_sdk: ^1.5.3
|
stellar_flutter_sdk: ^1.5.3
|
||||||
tezart: ^2.0.5
|
tezart: ^2.0.5
|
||||||
socks5_proxy: ^1.0.3+dev.3
|
socks5_proxy: ^1.0.3+dev.3
|
||||||
|
coinlib: ^1.0.0-rc.3
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
8
scripts/dev/build_runner.sh
Executable file
8
scripts/dev/build_runner.sh
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
|
||||||
|
PROJECT_ROOT_DIR="$SCRIPT_DIR/../.."
|
||||||
|
|
||||||
|
cd "$PROJECT_ROOT_DIR" || exit
|
||||||
|
dart run build_runner build --delete-conflicting-outputs
|
|
@ -11,13 +11,14 @@ import 'package:mockito/mockito.dart' as _i1;
|
||||||
import 'package:stackwallet/db/isar/main_db.dart' as _i9;
|
import 'package:stackwallet/db/isar/main_db.dart' as _i9;
|
||||||
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i6;
|
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i6;
|
||||||
import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i3;
|
import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i3;
|
||||||
import 'package:stackwallet/models/isar/models/block_explorer.dart' as _i11;
|
import 'package:stackwallet/models/isar/models/block_explorer.dart' as _i12;
|
||||||
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i10;
|
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i11;
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i12;
|
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i13;
|
||||||
import 'package:stackwallet/services/transaction_notification_tracker.dart'
|
import 'package:stackwallet/services/transaction_notification_tracker.dart'
|
||||||
as _i8;
|
as _i8;
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i7;
|
import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i7;
|
||||||
import 'package:tuple/tuple.dart' as _i13;
|
import 'package:stackwallet/wallets/isar_models/wallet_info.dart' as _i10;
|
||||||
|
import 'package:tuple/tuple.dart' as _i14;
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: avoid_redundant_argument_values
|
// ignore_for_file: avoid_redundant_argument_values
|
||||||
|
@ -635,13 +636,44 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<bool>.value(false),
|
returnValue: _i5.Future<bool>.value(false),
|
||||||
) as _i5.Future<bool>);
|
) as _i5.Future<bool>);
|
||||||
@override
|
@override
|
||||||
List<_i10.ContactEntry> getContactEntries() => (super.noSuchMethod(
|
_i5.Future<void> putWalletInfo(_i10.WalletInfo? walletInfo) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#putWalletInfo,
|
||||||
|
[walletInfo],
|
||||||
|
),
|
||||||
|
returnValue: _i5.Future<void>.value(),
|
||||||
|
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||||
|
) as _i5.Future<void>);
|
||||||
|
@override
|
||||||
|
_i5.Future<void> updateWalletInfo(_i10.WalletInfo? walletInfo) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#updateWalletInfo,
|
||||||
|
[walletInfo],
|
||||||
|
),
|
||||||
|
returnValue: _i5.Future<void>.value(),
|
||||||
|
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||||
|
) as _i5.Future<void>);
|
||||||
|
@override
|
||||||
|
_i5.Future<void> deleteWallet({required String? walletId}) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#deleteWallet,
|
||||||
|
[],
|
||||||
|
{#walletId: walletId},
|
||||||
|
),
|
||||||
|
returnValue: _i5.Future<void>.value(),
|
||||||
|
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||||
|
) as _i5.Future<void>);
|
||||||
|
@override
|
||||||
|
List<_i11.ContactEntry> getContactEntries() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactEntries,
|
#getContactEntries,
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
returnValue: <_i10.ContactEntry>[],
|
returnValue: <_i11.ContactEntry>[],
|
||||||
) as List<_i10.ContactEntry>);
|
) as List<_i11.ContactEntry>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<bool> deleteContactEntry({required String? id}) =>
|
_i5.Future<bool> deleteContactEntry({required String? id}) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
|
@ -663,15 +695,15 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<bool>.value(false),
|
returnValue: _i5.Future<bool>.value(false),
|
||||||
) as _i5.Future<bool>);
|
) as _i5.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i10.ContactEntry? getContactEntry({required String? id}) =>
|
_i11.ContactEntry? getContactEntry({required String? id}) =>
|
||||||
(super.noSuchMethod(Invocation.method(
|
(super.noSuchMethod(Invocation.method(
|
||||||
#getContactEntry,
|
#getContactEntry,
|
||||||
[],
|
[],
|
||||||
{#id: id},
|
{#id: id},
|
||||||
)) as _i10.ContactEntry?);
|
)) as _i11.ContactEntry?);
|
||||||
@override
|
@override
|
||||||
_i5.Future<bool> putContactEntry(
|
_i5.Future<bool> putContactEntry(
|
||||||
{required _i10.ContactEntry? contactEntry}) =>
|
{required _i11.ContactEntry? contactEntry}) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putContactEntry,
|
#putContactEntry,
|
||||||
|
@ -681,16 +713,16 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<bool>.value(false),
|
returnValue: _i5.Future<bool>.value(false),
|
||||||
) as _i5.Future<bool>);
|
) as _i5.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i11.TransactionBlockExplorer? getTransactionBlockExplorer(
|
_i12.TransactionBlockExplorer? getTransactionBlockExplorer(
|
||||||
{required _i7.Coin? coin}) =>
|
{required _i7.Coin? coin}) =>
|
||||||
(super.noSuchMethod(Invocation.method(
|
(super.noSuchMethod(Invocation.method(
|
||||||
#getTransactionBlockExplorer,
|
#getTransactionBlockExplorer,
|
||||||
[],
|
[],
|
||||||
{#coin: coin},
|
{#coin: coin},
|
||||||
)) as _i11.TransactionBlockExplorer?);
|
)) as _i12.TransactionBlockExplorer?);
|
||||||
@override
|
@override
|
||||||
_i5.Future<int> putTransactionBlockExplorer(
|
_i5.Future<int> putTransactionBlockExplorer(
|
||||||
_i11.TransactionBlockExplorer? explorer) =>
|
_i12.TransactionBlockExplorer? explorer) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putTransactionBlockExplorer,
|
#putTransactionBlockExplorer,
|
||||||
|
@ -699,13 +731,13 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<int>.value(0),
|
returnValue: _i5.Future<int>.value(0),
|
||||||
) as _i5.Future<int>);
|
) as _i5.Future<int>);
|
||||||
@override
|
@override
|
||||||
_i4.QueryBuilder<_i12.Address, _i12.Address, _i4.QAfterWhereClause>
|
_i4.QueryBuilder<_i13.Address, _i13.Address, _i4.QAfterWhereClause>
|
||||||
getAddresses(String? walletId) => (super.noSuchMethod(
|
getAddresses(String? walletId) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getAddresses,
|
#getAddresses,
|
||||||
[walletId],
|
[walletId],
|
||||||
),
|
),
|
||||||
returnValue: _FakeQueryBuilder_4<_i12.Address, _i12.Address,
|
returnValue: _FakeQueryBuilder_4<_i13.Address, _i13.Address,
|
||||||
_i4.QAfterWhereClause>(
|
_i4.QAfterWhereClause>(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -714,9 +746,9 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i4
|
) as _i4
|
||||||
.QueryBuilder<_i12.Address, _i12.Address, _i4.QAfterWhereClause>);
|
.QueryBuilder<_i13.Address, _i13.Address, _i4.QAfterWhereClause>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<int> putAddress(_i12.Address? address) => (super.noSuchMethod(
|
_i5.Future<int> putAddress(_i13.Address? address) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putAddress,
|
#putAddress,
|
||||||
[address],
|
[address],
|
||||||
|
@ -724,7 +756,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<int>.value(0),
|
returnValue: _i5.Future<int>.value(0),
|
||||||
) as _i5.Future<int>);
|
) as _i5.Future<int>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<List<int>> putAddresses(List<_i12.Address>? addresses) =>
|
_i5.Future<List<int>> putAddresses(List<_i13.Address>? addresses) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putAddresses,
|
#putAddresses,
|
||||||
|
@ -733,7 +765,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<List<int>>.value(<int>[]),
|
returnValue: _i5.Future<List<int>>.value(<int>[]),
|
||||||
) as _i5.Future<List<int>>);
|
) as _i5.Future<List<int>>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<List<int>> updateOrPutAddresses(List<_i12.Address>? addresses) =>
|
_i5.Future<List<int>> updateOrPutAddresses(List<_i13.Address>? addresses) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#updateOrPutAddresses,
|
#updateOrPutAddresses,
|
||||||
|
@ -742,7 +774,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<List<int>>.value(<int>[]),
|
returnValue: _i5.Future<List<int>>.value(<int>[]),
|
||||||
) as _i5.Future<List<int>>);
|
) as _i5.Future<List<int>>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<_i12.Address?> getAddress(
|
_i5.Future<_i13.Address?> getAddress(
|
||||||
String? walletId,
|
String? walletId,
|
||||||
String? address,
|
String? address,
|
||||||
) =>
|
) =>
|
||||||
|
@ -754,12 +786,12 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
address,
|
address,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
returnValue: _i5.Future<_i12.Address?>.value(),
|
returnValue: _i5.Future<_i13.Address?>.value(),
|
||||||
) as _i5.Future<_i12.Address?>);
|
) as _i5.Future<_i13.Address?>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<int> updateAddress(
|
_i5.Future<int> updateAddress(
|
||||||
_i12.Address? oldAddress,
|
_i13.Address? oldAddress,
|
||||||
_i12.Address? newAddress,
|
_i13.Address? newAddress,
|
||||||
) =>
|
) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -772,13 +804,13 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<int>.value(0),
|
returnValue: _i5.Future<int>.value(0),
|
||||||
) as _i5.Future<int>);
|
) as _i5.Future<int>);
|
||||||
@override
|
@override
|
||||||
_i4.QueryBuilder<_i12.Transaction, _i12.Transaction, _i4.QAfterWhereClause>
|
_i4.QueryBuilder<_i13.Transaction, _i13.Transaction, _i4.QAfterWhereClause>
|
||||||
getTransactions(String? walletId) => (super.noSuchMethod(
|
getTransactions(String? walletId) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getTransactions,
|
#getTransactions,
|
||||||
[walletId],
|
[walletId],
|
||||||
),
|
),
|
||||||
returnValue: _FakeQueryBuilder_4<_i12.Transaction, _i12.Transaction,
|
returnValue: _FakeQueryBuilder_4<_i13.Transaction, _i13.Transaction,
|
||||||
_i4.QAfterWhereClause>(
|
_i4.QAfterWhereClause>(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -786,10 +818,10 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
[walletId],
|
[walletId],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i4.QueryBuilder<_i12.Transaction, _i12.Transaction,
|
) as _i4.QueryBuilder<_i13.Transaction, _i13.Transaction,
|
||||||
_i4.QAfterWhereClause>);
|
_i4.QAfterWhereClause>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<int> putTransaction(_i12.Transaction? transaction) =>
|
_i5.Future<int> putTransaction(_i13.Transaction? transaction) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putTransaction,
|
#putTransaction,
|
||||||
|
@ -798,7 +830,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<int>.value(0),
|
returnValue: _i5.Future<int>.value(0),
|
||||||
) as _i5.Future<int>);
|
) as _i5.Future<int>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<List<int>> putTransactions(List<_i12.Transaction>? transactions) =>
|
_i5.Future<List<int>> putTransactions(List<_i13.Transaction>? transactions) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putTransactions,
|
#putTransactions,
|
||||||
|
@ -807,7 +839,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<List<int>>.value(<int>[]),
|
returnValue: _i5.Future<List<int>>.value(<int>[]),
|
||||||
) as _i5.Future<List<int>>);
|
) as _i5.Future<List<int>>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<_i12.Transaction?> getTransaction(
|
_i5.Future<_i13.Transaction?> getTransaction(
|
||||||
String? walletId,
|
String? walletId,
|
||||||
String? txid,
|
String? txid,
|
||||||
) =>
|
) =>
|
||||||
|
@ -819,10 +851,10 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
txid,
|
txid,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
returnValue: _i5.Future<_i12.Transaction?>.value(),
|
returnValue: _i5.Future<_i13.Transaction?>.value(),
|
||||||
) as _i5.Future<_i12.Transaction?>);
|
) as _i5.Future<_i13.Transaction?>);
|
||||||
@override
|
@override
|
||||||
_i5.Stream<_i12.Transaction?> watchTransaction({
|
_i5.Stream<_i13.Transaction?> watchTransaction({
|
||||||
required int? id,
|
required int? id,
|
||||||
bool? fireImmediately = false,
|
bool? fireImmediately = false,
|
||||||
}) =>
|
}) =>
|
||||||
|
@ -835,10 +867,10 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
#fireImmediately: fireImmediately,
|
#fireImmediately: fireImmediately,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
returnValue: _i5.Stream<_i12.Transaction?>.empty(),
|
returnValue: _i5.Stream<_i13.Transaction?>.empty(),
|
||||||
) as _i5.Stream<_i12.Transaction?>);
|
) as _i5.Stream<_i13.Transaction?>);
|
||||||
@override
|
@override
|
||||||
_i4.QueryBuilder<_i12.UTXO, _i12.UTXO, _i4.QAfterWhereClause> getUTXOs(
|
_i4.QueryBuilder<_i13.UTXO, _i13.UTXO, _i4.QAfterWhereClause> getUTXOs(
|
||||||
String? walletId) =>
|
String? walletId) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -846,16 +878,16 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
[walletId],
|
[walletId],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_FakeQueryBuilder_4<_i12.UTXO, _i12.UTXO, _i4.QAfterWhereClause>(
|
_FakeQueryBuilder_4<_i13.UTXO, _i13.UTXO, _i4.QAfterWhereClause>(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getUTXOs,
|
#getUTXOs,
|
||||||
[walletId],
|
[walletId],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i4.QueryBuilder<_i12.UTXO, _i12.UTXO, _i4.QAfterWhereClause>);
|
) as _i4.QueryBuilder<_i13.UTXO, _i13.UTXO, _i4.QAfterWhereClause>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<void> putUTXO(_i12.UTXO? utxo) => (super.noSuchMethod(
|
_i5.Future<void> putUTXO(_i13.UTXO? utxo) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putUTXO,
|
#putUTXO,
|
||||||
[utxo],
|
[utxo],
|
||||||
|
@ -864,7 +896,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||||
) as _i5.Future<void>);
|
) as _i5.Future<void>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<void> putUTXOs(List<_i12.UTXO>? utxos) => (super.noSuchMethod(
|
_i5.Future<void> putUTXOs(List<_i13.UTXO>? utxos) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putUTXOs,
|
#putUTXOs,
|
||||||
[utxos],
|
[utxos],
|
||||||
|
@ -875,7 +907,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
@override
|
@override
|
||||||
_i5.Future<bool> updateUTXOs(
|
_i5.Future<bool> updateUTXOs(
|
||||||
String? walletId,
|
String? walletId,
|
||||||
List<_i12.UTXO>? utxos,
|
List<_i13.UTXO>? utxos,
|
||||||
) =>
|
) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -888,7 +920,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<bool>.value(false),
|
returnValue: _i5.Future<bool>.value(false),
|
||||||
) as _i5.Future<bool>);
|
) as _i5.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i5.Stream<_i12.UTXO?> watchUTXO({
|
_i5.Stream<_i13.UTXO?> watchUTXO({
|
||||||
required int? id,
|
required int? id,
|
||||||
bool? fireImmediately = false,
|
bool? fireImmediately = false,
|
||||||
}) =>
|
}) =>
|
||||||
|
@ -901,10 +933,10 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
#fireImmediately: fireImmediately,
|
#fireImmediately: fireImmediately,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
returnValue: _i5.Stream<_i12.UTXO?>.empty(),
|
returnValue: _i5.Stream<_i13.UTXO?>.empty(),
|
||||||
) as _i5.Stream<_i12.UTXO?>);
|
) as _i5.Stream<_i13.UTXO?>);
|
||||||
@override
|
@override
|
||||||
_i4.QueryBuilder<_i12.TransactionNote, _i12.TransactionNote,
|
_i4.QueryBuilder<_i13.TransactionNote, _i13.TransactionNote,
|
||||||
_i4.QAfterWhereClause> getTransactionNotes(
|
_i4.QAfterWhereClause> getTransactionNotes(
|
||||||
String? walletId) =>
|
String? walletId) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
|
@ -912,18 +944,18 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
#getTransactionNotes,
|
#getTransactionNotes,
|
||||||
[walletId],
|
[walletId],
|
||||||
),
|
),
|
||||||
returnValue: _FakeQueryBuilder_4<_i12.TransactionNote,
|
returnValue: _FakeQueryBuilder_4<_i13.TransactionNote,
|
||||||
_i12.TransactionNote, _i4.QAfterWhereClause>(
|
_i13.TransactionNote, _i4.QAfterWhereClause>(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getTransactionNotes,
|
#getTransactionNotes,
|
||||||
[walletId],
|
[walletId],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i4.QueryBuilder<_i12.TransactionNote, _i12.TransactionNote,
|
) as _i4.QueryBuilder<_i13.TransactionNote, _i13.TransactionNote,
|
||||||
_i4.QAfterWhereClause>);
|
_i4.QAfterWhereClause>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<void> putTransactionNote(_i12.TransactionNote? transactionNote) =>
|
_i5.Future<void> putTransactionNote(_i13.TransactionNote? transactionNote) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putTransactionNote,
|
#putTransactionNote,
|
||||||
|
@ -934,7 +966,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
) as _i5.Future<void>);
|
) as _i5.Future<void>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<void> putTransactionNotes(
|
_i5.Future<void> putTransactionNotes(
|
||||||
List<_i12.TransactionNote>? transactionNotes) =>
|
List<_i13.TransactionNote>? transactionNotes) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putTransactionNotes,
|
#putTransactionNotes,
|
||||||
|
@ -944,7 +976,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||||
) as _i5.Future<void>);
|
) as _i5.Future<void>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<_i12.TransactionNote?> getTransactionNote(
|
_i5.Future<_i13.TransactionNote?> getTransactionNote(
|
||||||
String? walletId,
|
String? walletId,
|
||||||
String? txid,
|
String? txid,
|
||||||
) =>
|
) =>
|
||||||
|
@ -956,10 +988,10 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
txid,
|
txid,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
returnValue: _i5.Future<_i12.TransactionNote?>.value(),
|
returnValue: _i5.Future<_i13.TransactionNote?>.value(),
|
||||||
) as _i5.Future<_i12.TransactionNote?>);
|
) as _i5.Future<_i13.TransactionNote?>);
|
||||||
@override
|
@override
|
||||||
_i5.Stream<_i12.TransactionNote?> watchTransactionNote({
|
_i5.Stream<_i13.TransactionNote?> watchTransactionNote({
|
||||||
required int? id,
|
required int? id,
|
||||||
bool? fireImmediately = false,
|
bool? fireImmediately = false,
|
||||||
}) =>
|
}) =>
|
||||||
|
@ -972,27 +1004,27 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
#fireImmediately: fireImmediately,
|
#fireImmediately: fireImmediately,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
returnValue: _i5.Stream<_i12.TransactionNote?>.empty(),
|
returnValue: _i5.Stream<_i13.TransactionNote?>.empty(),
|
||||||
) as _i5.Stream<_i12.TransactionNote?>);
|
) as _i5.Stream<_i13.TransactionNote?>);
|
||||||
@override
|
@override
|
||||||
_i4.QueryBuilder<_i12.AddressLabel, _i12.AddressLabel, _i4.QAfterWhereClause>
|
_i4.QueryBuilder<_i13.AddressLabel, _i13.AddressLabel, _i4.QAfterWhereClause>
|
||||||
getAddressLabels(String? walletId) => (super.noSuchMethod(
|
getAddressLabels(String? walletId) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getAddressLabels,
|
#getAddressLabels,
|
||||||
[walletId],
|
[walletId],
|
||||||
),
|
),
|
||||||
returnValue: _FakeQueryBuilder_4<_i12.AddressLabel,
|
returnValue: _FakeQueryBuilder_4<_i13.AddressLabel,
|
||||||
_i12.AddressLabel, _i4.QAfterWhereClause>(
|
_i13.AddressLabel, _i4.QAfterWhereClause>(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getAddressLabels,
|
#getAddressLabels,
|
||||||
[walletId],
|
[walletId],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i4.QueryBuilder<_i12.AddressLabel, _i12.AddressLabel,
|
) as _i4.QueryBuilder<_i13.AddressLabel, _i13.AddressLabel,
|
||||||
_i4.QAfterWhereClause>);
|
_i4.QAfterWhereClause>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<int> putAddressLabel(_i12.AddressLabel? addressLabel) =>
|
_i5.Future<int> putAddressLabel(_i13.AddressLabel? addressLabel) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putAddressLabel,
|
#putAddressLabel,
|
||||||
|
@ -1001,7 +1033,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<int>.value(0),
|
returnValue: _i5.Future<int>.value(0),
|
||||||
) as _i5.Future<int>);
|
) as _i5.Future<int>);
|
||||||
@override
|
@override
|
||||||
int putAddressLabelSync(_i12.AddressLabel? addressLabel) =>
|
int putAddressLabelSync(_i13.AddressLabel? addressLabel) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putAddressLabelSync,
|
#putAddressLabelSync,
|
||||||
|
@ -1010,7 +1042,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: 0,
|
returnValue: 0,
|
||||||
) as int);
|
) as int);
|
||||||
@override
|
@override
|
||||||
_i5.Future<void> putAddressLabels(List<_i12.AddressLabel>? addressLabels) =>
|
_i5.Future<void> putAddressLabels(List<_i13.AddressLabel>? addressLabels) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putAddressLabels,
|
#putAddressLabels,
|
||||||
|
@ -1020,7 +1052,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||||
) as _i5.Future<void>);
|
) as _i5.Future<void>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<_i12.AddressLabel?> getAddressLabel(
|
_i5.Future<_i13.AddressLabel?> getAddressLabel(
|
||||||
String? walletId,
|
String? walletId,
|
||||||
String? addressString,
|
String? addressString,
|
||||||
) =>
|
) =>
|
||||||
|
@ -1032,10 +1064,10 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
addressString,
|
addressString,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
returnValue: _i5.Future<_i12.AddressLabel?>.value(),
|
returnValue: _i5.Future<_i13.AddressLabel?>.value(),
|
||||||
) as _i5.Future<_i12.AddressLabel?>);
|
) as _i5.Future<_i13.AddressLabel?>);
|
||||||
@override
|
@override
|
||||||
_i12.AddressLabel? getAddressLabelSync(
|
_i13.AddressLabel? getAddressLabelSync(
|
||||||
String? walletId,
|
String? walletId,
|
||||||
String? addressString,
|
String? addressString,
|
||||||
) =>
|
) =>
|
||||||
|
@ -1045,9 +1077,9 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
walletId,
|
walletId,
|
||||||
addressString,
|
addressString,
|
||||||
],
|
],
|
||||||
)) as _i12.AddressLabel?);
|
)) as _i13.AddressLabel?);
|
||||||
@override
|
@override
|
||||||
_i5.Stream<_i12.AddressLabel?> watchAddressLabel({
|
_i5.Stream<_i13.AddressLabel?> watchAddressLabel({
|
||||||
required int? id,
|
required int? id,
|
||||||
bool? fireImmediately = false,
|
bool? fireImmediately = false,
|
||||||
}) =>
|
}) =>
|
||||||
|
@ -1060,10 +1092,10 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
#fireImmediately: fireImmediately,
|
#fireImmediately: fireImmediately,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
returnValue: _i5.Stream<_i12.AddressLabel?>.empty(),
|
returnValue: _i5.Stream<_i13.AddressLabel?>.empty(),
|
||||||
) as _i5.Stream<_i12.AddressLabel?>);
|
) as _i5.Stream<_i13.AddressLabel?>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<int> updateAddressLabel(_i12.AddressLabel? addressLabel) =>
|
_i5.Future<int> updateAddressLabel(_i13.AddressLabel? addressLabel) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#updateAddressLabel,
|
#updateAddressLabel,
|
||||||
|
@ -1102,7 +1134,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
) as _i5.Future<void>);
|
) as _i5.Future<void>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<void> addNewTransactionData(
|
_i5.Future<void> addNewTransactionData(
|
||||||
List<_i13.Tuple2<_i12.Transaction, _i12.Address?>>? transactionsData,
|
List<_i14.Tuple2<_i13.Transaction, _i13.Address?>>? transactionsData,
|
||||||
String? walletId,
|
String? walletId,
|
||||||
) =>
|
) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
|
@ -1117,13 +1149,13 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||||
) as _i5.Future<void>);
|
) as _i5.Future<void>);
|
||||||
@override
|
@override
|
||||||
_i4.QueryBuilder<_i12.EthContract, _i12.EthContract, _i4.QWhere>
|
_i4.QueryBuilder<_i13.EthContract, _i13.EthContract, _i4.QWhere>
|
||||||
getEthContracts() => (super.noSuchMethod(
|
getEthContracts() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getEthContracts,
|
#getEthContracts,
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
returnValue: _FakeQueryBuilder_4<_i12.EthContract, _i12.EthContract,
|
returnValue: _FakeQueryBuilder_4<_i13.EthContract, _i13.EthContract,
|
||||||
_i4.QWhere>(
|
_i4.QWhere>(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -1132,24 +1164,24 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i4
|
) as _i4
|
||||||
.QueryBuilder<_i12.EthContract, _i12.EthContract, _i4.QWhere>);
|
.QueryBuilder<_i13.EthContract, _i13.EthContract, _i4.QWhere>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<_i12.EthContract?> getEthContract(String? contractAddress) =>
|
_i5.Future<_i13.EthContract?> getEthContract(String? contractAddress) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getEthContract,
|
#getEthContract,
|
||||||
[contractAddress],
|
[contractAddress],
|
||||||
),
|
),
|
||||||
returnValue: _i5.Future<_i12.EthContract?>.value(),
|
returnValue: _i5.Future<_i13.EthContract?>.value(),
|
||||||
) as _i5.Future<_i12.EthContract?>);
|
) as _i5.Future<_i13.EthContract?>);
|
||||||
@override
|
@override
|
||||||
_i12.EthContract? getEthContractSync(String? contractAddress) =>
|
_i13.EthContract? getEthContractSync(String? contractAddress) =>
|
||||||
(super.noSuchMethod(Invocation.method(
|
(super.noSuchMethod(Invocation.method(
|
||||||
#getEthContractSync,
|
#getEthContractSync,
|
||||||
[contractAddress],
|
[contractAddress],
|
||||||
)) as _i12.EthContract?);
|
)) as _i13.EthContract?);
|
||||||
@override
|
@override
|
||||||
_i5.Future<int> putEthContract(_i12.EthContract? contract) =>
|
_i5.Future<int> putEthContract(_i13.EthContract? contract) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putEthContract,
|
#putEthContract,
|
||||||
|
@ -1158,7 +1190,7 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB {
|
||||||
returnValue: _i5.Future<int>.value(0),
|
returnValue: _i5.Future<int>.value(0),
|
||||||
) as _i5.Future<int>);
|
) as _i5.Future<int>);
|
||||||
@override
|
@override
|
||||||
_i5.Future<void> putEthContracts(List<_i12.EthContract>? contracts) =>
|
_i5.Future<void> putEthContracts(List<_i13.EthContract>? contracts) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putEthContracts,
|
#putEthContracts,
|
||||||
|
|
|
@ -16,8 +16,8 @@ import 'package:stackwallet/db/isar/main_db.dart' as _i14;
|
||||||
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i13;
|
import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i13;
|
||||||
import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i12;
|
import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i12;
|
||||||
import 'package:stackwallet/models/balance.dart' as _i9;
|
import 'package:stackwallet/models/balance.dart' as _i9;
|
||||||
import 'package:stackwallet/models/isar/models/block_explorer.dart' as _i37;
|
import 'package:stackwallet/models/isar/models/block_explorer.dart' as _i38;
|
||||||
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i36;
|
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i37;
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i23;
|
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i23;
|
||||||
import 'package:stackwallet/models/isar/stack_theme.dart' as _i34;
|
import 'package:stackwallet/models/isar/stack_theme.dart' as _i34;
|
||||||
import 'package:stackwallet/models/models.dart' as _i8;
|
import 'package:stackwallet/models/models.dart' as _i8;
|
||||||
|
@ -41,6 +41,7 @@ import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i28;
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i19;
|
import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i19;
|
||||||
import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i27;
|
import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i27;
|
||||||
import 'package:stackwallet/utilities/prefs.dart' as _i21;
|
import 'package:stackwallet/utilities/prefs.dart' as _i21;
|
||||||
|
import 'package:stackwallet/wallets/isar_models/wallet_info.dart' as _i36;
|
||||||
import 'package:tuple/tuple.dart' as _i15;
|
import 'package:tuple/tuple.dart' as _i15;
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
|
@ -3044,13 +3045,44 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB {
|
||||||
returnValue: _i20.Future<bool>.value(false),
|
returnValue: _i20.Future<bool>.value(false),
|
||||||
) as _i20.Future<bool>);
|
) as _i20.Future<bool>);
|
||||||
@override
|
@override
|
||||||
List<_i36.ContactEntry> getContactEntries() => (super.noSuchMethod(
|
_i20.Future<void> putWalletInfo(_i36.WalletInfo? walletInfo) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#putWalletInfo,
|
||||||
|
[walletInfo],
|
||||||
|
),
|
||||||
|
returnValue: _i20.Future<void>.value(),
|
||||||
|
returnValueForMissingStub: _i20.Future<void>.value(),
|
||||||
|
) as _i20.Future<void>);
|
||||||
|
@override
|
||||||
|
_i20.Future<void> updateWalletInfo(_i36.WalletInfo? walletInfo) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#updateWalletInfo,
|
||||||
|
[walletInfo],
|
||||||
|
),
|
||||||
|
returnValue: _i20.Future<void>.value(),
|
||||||
|
returnValueForMissingStub: _i20.Future<void>.value(),
|
||||||
|
) as _i20.Future<void>);
|
||||||
|
@override
|
||||||
|
_i20.Future<void> deleteWallet({required String? walletId}) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#deleteWallet,
|
||||||
|
[],
|
||||||
|
{#walletId: walletId},
|
||||||
|
),
|
||||||
|
returnValue: _i20.Future<void>.value(),
|
||||||
|
returnValueForMissingStub: _i20.Future<void>.value(),
|
||||||
|
) as _i20.Future<void>);
|
||||||
|
@override
|
||||||
|
List<_i37.ContactEntry> getContactEntries() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactEntries,
|
#getContactEntries,
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
returnValue: <_i36.ContactEntry>[],
|
returnValue: <_i37.ContactEntry>[],
|
||||||
) as List<_i36.ContactEntry>);
|
) as List<_i37.ContactEntry>);
|
||||||
@override
|
@override
|
||||||
_i20.Future<bool> deleteContactEntry({required String? id}) =>
|
_i20.Future<bool> deleteContactEntry({required String? id}) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
|
@ -3072,15 +3104,15 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB {
|
||||||
returnValue: _i20.Future<bool>.value(false),
|
returnValue: _i20.Future<bool>.value(false),
|
||||||
) as _i20.Future<bool>);
|
) as _i20.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i36.ContactEntry? getContactEntry({required String? id}) =>
|
_i37.ContactEntry? getContactEntry({required String? id}) =>
|
||||||
(super.noSuchMethod(Invocation.method(
|
(super.noSuchMethod(Invocation.method(
|
||||||
#getContactEntry,
|
#getContactEntry,
|
||||||
[],
|
[],
|
||||||
{#id: id},
|
{#id: id},
|
||||||
)) as _i36.ContactEntry?);
|
)) as _i37.ContactEntry?);
|
||||||
@override
|
@override
|
||||||
_i20.Future<bool> putContactEntry(
|
_i20.Future<bool> putContactEntry(
|
||||||
{required _i36.ContactEntry? contactEntry}) =>
|
{required _i37.ContactEntry? contactEntry}) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putContactEntry,
|
#putContactEntry,
|
||||||
|
@ -3090,16 +3122,16 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB {
|
||||||
returnValue: _i20.Future<bool>.value(false),
|
returnValue: _i20.Future<bool>.value(false),
|
||||||
) as _i20.Future<bool>);
|
) as _i20.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i37.TransactionBlockExplorer? getTransactionBlockExplorer(
|
_i38.TransactionBlockExplorer? getTransactionBlockExplorer(
|
||||||
{required _i19.Coin? coin}) =>
|
{required _i19.Coin? coin}) =>
|
||||||
(super.noSuchMethod(Invocation.method(
|
(super.noSuchMethod(Invocation.method(
|
||||||
#getTransactionBlockExplorer,
|
#getTransactionBlockExplorer,
|
||||||
[],
|
[],
|
||||||
{#coin: coin},
|
{#coin: coin},
|
||||||
)) as _i37.TransactionBlockExplorer?);
|
)) as _i38.TransactionBlockExplorer?);
|
||||||
@override
|
@override
|
||||||
_i20.Future<int> putTransactionBlockExplorer(
|
_i20.Future<int> putTransactionBlockExplorer(
|
||||||
_i37.TransactionBlockExplorer? explorer) =>
|
_i38.TransactionBlockExplorer? explorer) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#putTransactionBlockExplorer,
|
#putTransactionBlockExplorer,
|
||||||
|
|
Loading…
Reference in a new issue