mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-31 06:35:53 +00:00
WIP eth refactor
This commit is contained in:
parent
784ca8cc2d
commit
36f090a1e7
20 changed files with 1318 additions and 1266 deletions
|
@ -122,6 +122,12 @@ class TransactionV2 {
|
||||||
) -
|
) -
|
||||||
getFee(coin: coin);
|
getFee(coin: coin);
|
||||||
|
|
||||||
|
// negative amounts are likely an error or can happen with coins such as eth
|
||||||
|
// that don't use the btc style inputs/outputs
|
||||||
|
if (amount.raw < BigInt.zero) {
|
||||||
|
return Amount.zeroWith(fractionDigits: coin.decimals);
|
||||||
|
}
|
||||||
|
|
||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/ad
|
||||||
import 'package:stackwallet/pages/home_view/home_view.dart';
|
import 'package:stackwallet/pages/home_view/home_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/desktop_home_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/desktop_home_view.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
@ -32,6 +31,7 @@ import 'package:stackwallet/utilities/default_eth_tokens.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
|
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
import 'package:stackwallet/widgets/background.dart';
|
import 'package:stackwallet/widgets/background.dart';
|
||||||
import 'package:stackwallet/widgets/conditional_parent.dart';
|
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
|
@ -121,7 +121,7 @@ class _EditWalletTokensViewState extends ConsumerState<EditWalletTokensView> {
|
||||||
unawaited(
|
unawaited(
|
||||||
showFloatingFlushBar(
|
showFloatingFlushBar(
|
||||||
type: FlushBarType.success,
|
type: FlushBarType.success,
|
||||||
message: "${ethWallet.walletName} tokens saved",
|
message: "${ethWallet.info.name} tokens saved",
|
||||||
context: context,
|
context: context,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -182,7 +182,8 @@ class _EditWalletTokensViewState extends ConsumerState<EditWalletTokensView> {
|
||||||
|
|
||||||
final walletContracts =
|
final walletContracts =
|
||||||
(ref.read(pWallets).getWallet(widget.walletId) as EthereumWallet)
|
(ref.read(pWallets).getWallet(widget.walletId) as EthereumWallet)
|
||||||
.getWalletTokenContractAddresses();
|
.info
|
||||||
|
.tokenContractAddresses;
|
||||||
|
|
||||||
final shouldMarkAsSelectedContracts = [
|
final shouldMarkAsSelectedContracts = [
|
||||||
...walletContracts,
|
...walletContracts,
|
||||||
|
|
|
@ -42,9 +42,9 @@ import 'package:stackwallet/utilities/logger.dart';
|
||||||
import 'package:stackwallet/utilities/prefs.dart';
|
import 'package:stackwallet/utilities/prefs.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
|
import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/private_key_based_wallet.dart';
|
|
||||||
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/private_key_interface.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
|
@ -298,7 +298,7 @@ abstract class SWB {
|
||||||
backupWallet['mnemonic'] = await wallet.getMnemonic();
|
backupWallet['mnemonic'] = await wallet.getMnemonic();
|
||||||
backupWallet['mnemonicPassphrase'] =
|
backupWallet['mnemonicPassphrase'] =
|
||||||
await wallet.getMnemonicPassphrase();
|
await wallet.getMnemonicPassphrase();
|
||||||
} else if (wallet is PrivateKeyBasedWallet) {
|
} else if (wallet is PrivateKeyInterface) {
|
||||||
backupWallet['privateKey'] = await wallet.getPrivateKey();
|
backupWallet['privateKey'] = await wallet.getPrivateKey();
|
||||||
}
|
}
|
||||||
backupWallet['coinName'] = wallet.info.coin.name;
|
backupWallet['coinName'] = wallet.info.coin.name;
|
||||||
|
|
|
@ -16,13 +16,13 @@ import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/edit_wallet_tokens_view.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/edit_wallet_tokens_view.dart';
|
||||||
import 'package:stackwallet/pages/token_view/sub_widgets/my_tokens_list.dart';
|
import 'package:stackwallet/pages/token_view/sub_widgets/my_tokens_list.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
|
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
import 'package:stackwallet/widgets/background.dart';
|
import 'package:stackwallet/widgets/background.dart';
|
||||||
import 'package:stackwallet/widgets/conditional_parent.dart';
|
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
|
@ -236,7 +236,8 @@ class _MyTokensViewState extends ConsumerState<MyTokensView> {
|
||||||
tokenContracts: ref
|
tokenContracts: ref
|
||||||
.watch(pWallets.select((value) =>
|
.watch(pWallets.select((value) =>
|
||||||
value.getWallet(widget.walletId) as EthereumWallet))
|
value.getWallet(widget.walletId) as EthereumWallet))
|
||||||
.getWalletTokenContractAddresses(),
|
.info
|
||||||
|
.tokenContractAddresses,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -15,7 +15,6 @@ import 'package:stackwallet/pages/token_view/token_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/desktop_token_view.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/desktop_token_view.dart';
|
||||||
import 'package:stackwallet/providers/global/secure_store_provider.dart';
|
import 'package:stackwallet/providers/global/secure_store_provider.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/services/ethereum/cached_eth_token_balance.dart';
|
import 'package:stackwallet/services/ethereum/cached_eth_token_balance.dart';
|
||||||
import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
|
import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
|
||||||
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
||||||
|
@ -27,6 +26,7 @@ import 'package:stackwallet/utilities/show_loading.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
|
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||||
import 'package:stackwallet/widgets/dialogs/basic_dialog.dart';
|
import 'package:stackwallet/widgets/dialogs/basic_dialog.dart';
|
||||||
import 'package:stackwallet/widgets/icon_widgets/eth_token_icon.dart';
|
import 'package:stackwallet/widgets/icon_widgets/eth_token_icon.dart';
|
||||||
|
|
|
@ -18,7 +18,6 @@ import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/dialogs/desktop_expanding_wallet_card.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/dialogs/desktop_expanding_wallet_card.dart';
|
||||||
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
@ -26,6 +25,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
|
import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
||||||
import 'package:stackwallet/widgets/background.dart';
|
import 'package:stackwallet/widgets/background.dart';
|
||||||
import 'package:stackwallet/widgets/conditional_parent.dart';
|
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
|
@ -121,7 +121,7 @@ class _EthWalletsOverviewState extends ConsumerState<WalletsOverview> {
|
||||||
final List<EthContract> contracts = [];
|
final List<EthContract> contracts = [];
|
||||||
final wallet = ref.read(pWallets).getWallet(data.walletId);
|
final wallet = ref.read(pWallets).getWallet(data.walletId);
|
||||||
final contractAddresses =
|
final contractAddresses =
|
||||||
(wallet as EthereumWallet).getWalletTokenContractAddresses();
|
(wallet as EthereumWallet).info.tokenContractAddresses;
|
||||||
|
|
||||||
// fetch each contract
|
// fetch each contract
|
||||||
for (final contractAddress in contractAddresses) {
|
for (final contractAddress in contractAddresses) {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
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/pages/wallet_view/sub_widgets/transactions_list.dart';
|
import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart';
|
||||||
|
@ -90,7 +90,7 @@ class _MyWalletState extends ConsumerState<MyWallet> {
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxHeight: MediaQuery.of(context).size.height - 362,
|
maxHeight: MediaQuery.of(context).size.height - 362,
|
||||||
),
|
),
|
||||||
child: TransactionsList(
|
child: TransactionsV2List(
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -13,10 +13,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
||||||
import 'package:stackwallet/providers/global/secure_store_provider.dart';
|
import 'package:stackwallet/providers/global/secure_store_provider.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
|
import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
|
||||||
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
||||||
import 'package:stackwallet/utilities/logger.dart';
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
|
|
||||||
class ContractWalletId implements Equatable {
|
class ContractWalletId implements Equatable {
|
||||||
final String walletId;
|
final String walletId;
|
||||||
|
|
|
@ -14,7 +14,6 @@ import 'package:stackwallet/models/balance.dart';
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models;
|
import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models;
|
||||||
import 'package:stackwallet/models/node_model.dart';
|
import 'package:stackwallet/models/node_model.dart';
|
||||||
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
|
import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
|
||||||
import 'package:stackwallet/services/coins/particl/particl_wallet.dart';
|
import 'package:stackwallet/services/coins/particl/particl_wallet.dart';
|
||||||
import 'package:stackwallet/services/coins/stellar/stellar_wallet.dart';
|
import 'package:stackwallet/services/coins/stellar/stellar_wallet.dart';
|
||||||
|
@ -103,13 +102,7 @@ abstract class CoinServiceAPI {
|
||||||
throw UnimplementedError("moved");
|
throw UnimplementedError("moved");
|
||||||
|
|
||||||
case Coin.ethereum:
|
case Coin.ethereum:
|
||||||
return EthereumWallet(
|
throw UnimplementedError("moved");
|
||||||
walletId: walletId,
|
|
||||||
walletName: walletName,
|
|
||||||
coin: coin,
|
|
||||||
secureStore: secureStorageInterface,
|
|
||||||
tracker: tracker,
|
|
||||||
);
|
|
||||||
|
|
||||||
case Coin.monero:
|
case Coin.monero:
|
||||||
throw UnimplementedError("moved");
|
throw UnimplementedError("moved");
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,7 +21,6 @@ import 'package:stackwallet/models/balance.dart';
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/models/node_model.dart';
|
import 'package:stackwallet/models/node_model.dart';
|
||||||
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
||||||
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
|
||||||
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
||||||
|
@ -39,6 +38,7 @@ import 'package:stackwallet/utilities/extensions/impl/contract_abi.dart';
|
||||||
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
|
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
|
||||||
import 'package:stackwallet/utilities/logger.dart';
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
import 'package:stackwallet/wallets/models/tx_data.dart';
|
import 'package:stackwallet/wallets/models/tx_data.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
import 'package:web3dart/web3dart.dart' as web3dart;
|
import 'package:web3dart/web3dart.dart' as web3dart;
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
numberOfMessages: null,
|
numberOfMessages: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
Address? address = await ethWallet.db.getAddress(
|
Address? address = await ethWallet.mainDB.getAddress(
|
||||||
ethWallet.walletId,
|
ethWallet.walletId,
|
||||||
addressString,
|
addressString,
|
||||||
);
|
);
|
||||||
|
@ -197,7 +197,7 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
subType: AddressSubType.nonWallet,
|
subType: AddressSubType.nonWallet,
|
||||||
);
|
);
|
||||||
|
|
||||||
await ethWallet.db.addNewTransactionData(
|
await ethWallet.mainDB.addNewTransactionData(
|
||||||
[
|
[
|
||||||
Tuple2(transaction, address),
|
Tuple2(transaction, address),
|
||||||
],
|
],
|
||||||
|
@ -211,7 +211,7 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
address?.value ?? _credentials.address.toString());
|
address?.value ?? _credentials.address.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Address?> get _currentReceivingAddress => ethWallet.db
|
Future<Address?> get _currentReceivingAddress => ethWallet.mainDB
|
||||||
.getAddresses(ethWallet.walletId)
|
.getAddresses(ethWallet.walletId)
|
||||||
.filter()
|
.filter()
|
||||||
.typeEqualTo(AddressType.ethereum)
|
.typeEqualTo(AddressType.ethereum)
|
||||||
|
@ -255,12 +255,12 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String? mnemonicString = await ethWallet.mnemonicString;
|
String? mnemonicString = await ethWallet.getMnemonic();
|
||||||
|
|
||||||
//Get private key for given mnemonic
|
//Get private key for given mnemonic
|
||||||
String privateKey = getPrivateKey(
|
String privateKey = getPrivateKey(
|
||||||
mnemonicString!,
|
mnemonicString!,
|
||||||
(await ethWallet.mnemonicPassphrase) ?? "",
|
(await ethWallet.getMnemonicPassphrase()) ?? "",
|
||||||
);
|
);
|
||||||
_credentials = web3dart.EthPrivateKey.fromHex(privateKey);
|
_credentials = web3dart.EthPrivateKey.fromHex(privateKey);
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
await _refreshTransactions();
|
await _refreshTransactions();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
"Caught exception in ${tokenContract.name} ${ethWallet.walletName} ${ethWallet.walletId} refresh(): $e\n$s",
|
"Caught exception in ${tokenContract.name} ${ethWallet.info.name} ${ethWallet.walletId} refresh(): $e\n$s",
|
||||||
level: LogLevel.Warning,
|
level: LogLevel.Warning,
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -429,7 +429,7 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Transaction>> get transactions => ethWallet.db
|
Future<List<Transaction>> get transactions => ethWallet.mainDB
|
||||||
.getTransactions(ethWallet.walletId)
|
.getTransactions(ethWallet.walletId)
|
||||||
.filter()
|
.filter()
|
||||||
.otherDataEqualTo(tokenContract.address)
|
.otherDataEqualTo(tokenContract.address)
|
||||||
|
@ -557,7 +557,7 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
numberOfMessages: null,
|
numberOfMessages: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
Address? transactionAddress = await ethWallet.db
|
Address? transactionAddress = await ethWallet.mainDB
|
||||||
.getAddresses(ethWallet.walletId)
|
.getAddresses(ethWallet.walletId)
|
||||||
.filter()
|
.filter()
|
||||||
.valueEqualTo(toAddress)
|
.valueEqualTo(toAddress)
|
||||||
|
@ -580,14 +580,14 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
txnsData.add(Tuple2(txn, transactionAddress));
|
txnsData.add(Tuple2(txn, transactionAddress));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await ethWallet.db.addNewTransactionData(txnsData, ethWallet.walletId);
|
await ethWallet.mainDB.addNewTransactionData(txnsData, ethWallet.walletId);
|
||||||
|
|
||||||
// quick hack to notify manager to call notifyListeners if
|
// quick hack to notify manager to call notifyListeners if
|
||||||
// transactions changed
|
// transactions changed
|
||||||
if (txnsData.isNotEmpty) {
|
if (txnsData.isNotEmpty) {
|
||||||
GlobalEventBus.instance.fire(
|
GlobalEventBus.instance.fire(
|
||||||
UpdatedInBackgroundEvent(
|
UpdatedInBackgroundEvent(
|
||||||
"${tokenContract.name} transactions updated/added for: ${ethWallet.walletId} ${ethWallet.walletName}",
|
"${tokenContract.name} transactions updated/added for: ${ethWallet.walletId} ${ethWallet.info.name}",
|
||||||
ethWallet.walletId,
|
ethWallet.walletId,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
37
lib/wallets/crypto_currency/coins/ethereum.dart
Normal file
37
lib/wallets/crypto_currency/coins/ethereum.dart
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import 'package:ethereum_addresses/ethereum_addresses.dart';
|
||||||
|
import 'package:stackwallet/models/node_model.dart';
|
||||||
|
import 'package:stackwallet/utilities/default_nodes.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
|
||||||
|
import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_currency.dart';
|
||||||
|
|
||||||
|
class Ethereum extends Bip39Currency {
|
||||||
|
Ethereum(super.network) {
|
||||||
|
switch (network) {
|
||||||
|
case CryptoCurrencyNetwork.main:
|
||||||
|
coin = Coin.ethereum;
|
||||||
|
default:
|
||||||
|
throw Exception("Unsupported network: $network");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int get gasLimit => 21000;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get hasTokenSupport => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
NodeModel get defaultNode => DefaultNodes.ethereum;
|
||||||
|
|
||||||
|
@override
|
||||||
|
// Not used for eth
|
||||||
|
String get genesisHash => throw UnimplementedError();
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get minConfirms => 3;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool validateAddress(String address) {
|
||||||
|
return isValidEthereumAddress(address);
|
||||||
|
}
|
||||||
|
}
|
|
@ -339,6 +339,25 @@ class WalletInfo implements IsarId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// copies this with a new name and updates the db
|
||||||
|
Future<void> updateContractAddresses({
|
||||||
|
required Set<String> newContractAddresses,
|
||||||
|
required Isar isar,
|
||||||
|
}) async {
|
||||||
|
// only update if there were changes to the name
|
||||||
|
if (tokenContractAddresses
|
||||||
|
.toSet()
|
||||||
|
.difference(newContractAddresses)
|
||||||
|
.isNotEmpty) {
|
||||||
|
await updateOtherData(
|
||||||
|
newEntries: {
|
||||||
|
WalletInfoKeys.tokenContractAddresses: newContractAddresses.toList(),
|
||||||
|
},
|
||||||
|
isar: isar,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
WalletInfo({
|
WalletInfo({
|
||||||
|
|
380
lib/wallets/wallet/impl/ethereum_wallet.dart
Normal file
380
lib/wallets/wallet/impl/ethereum_wallet.dart
Normal file
|
@ -0,0 +1,380 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:ethereum_addresses/ethereum_addresses.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/models/balance.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/v2/input_v2.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/v2/output_v2.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
||||||
|
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||||
|
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
||||||
|
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
|
||||||
|
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
||||||
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/eth_commons.dart';
|
||||||
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
|
import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
|
||||||
|
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
|
||||||
|
import 'package:stackwallet/wallets/models/tx_data.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/intermediate/bip39_wallet.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/private_key_interface.dart';
|
||||||
|
import 'package:web3dart/web3dart.dart' as web3;
|
||||||
|
|
||||||
|
// Eth can not use tor with web3dart
|
||||||
|
|
||||||
|
class EthereumWallet extends Bip39Wallet with PrivateKeyInterface {
|
||||||
|
EthereumWallet(CryptoCurrencyNetwork network) : super(Ethereum(network));
|
||||||
|
|
||||||
|
Timer? timer;
|
||||||
|
late web3.EthPrivateKey _credentials;
|
||||||
|
|
||||||
|
Future<void> updateTokenContracts(List<String> contractAddresses) async {
|
||||||
|
await info.updateContractAddresses(
|
||||||
|
newContractAddresses: contractAddresses.toSet(),
|
||||||
|
isar: mainDB.isar,
|
||||||
|
);
|
||||||
|
|
||||||
|
GlobalEventBus.instance.fire(
|
||||||
|
UpdatedInBackgroundEvent(
|
||||||
|
"$contractAddresses updated/added for: $walletId ${info.name}",
|
||||||
|
walletId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
web3.Web3Client getEthClient() {
|
||||||
|
final node = getCurrentNode();
|
||||||
|
|
||||||
|
// Eth can not use tor with web3dart as Client does not support proxies
|
||||||
|
final client = Client();
|
||||||
|
|
||||||
|
return web3.Web3Client(node.host, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== Private ==============================================
|
||||||
|
|
||||||
|
Future<void> _initCredentials(
|
||||||
|
String mnemonic,
|
||||||
|
String mnemonicPassphrase,
|
||||||
|
) async {
|
||||||
|
String privateKey = getPrivateKey(mnemonic, mnemonicPassphrase);
|
||||||
|
_credentials = web3.EthPrivateKey.fromHex(privateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _generateAndSaveAddress(
|
||||||
|
String mnemonic,
|
||||||
|
String mnemonicPassphrase,
|
||||||
|
) async {
|
||||||
|
await _initCredentials(mnemonic, mnemonicPassphrase);
|
||||||
|
|
||||||
|
final address = Address(
|
||||||
|
walletId: walletId,
|
||||||
|
value: _credentials.address.hexEip55,
|
||||||
|
publicKey: [], // maybe store address bytes here? seems a waste of space though
|
||||||
|
derivationIndex: 0,
|
||||||
|
derivationPath: DerivationPath()..value = "$hdPathEthereum/0",
|
||||||
|
type: AddressType.ethereum,
|
||||||
|
subType: AddressSubType.receiving,
|
||||||
|
);
|
||||||
|
|
||||||
|
await mainDB.updateOrPutAddresses([address]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete
|
||||||
|
@override
|
||||||
|
Future<Address> getCurrentReceivingAddress() async {
|
||||||
|
return Address(
|
||||||
|
walletId: walletId,
|
||||||
|
value:
|
||||||
|
checksumEthereumAddress("0x6Cc3006944070B32D80107D51d843a66EaC00686"),
|
||||||
|
publicKey: [], // maybe store address bytes here? seems a waste of space though
|
||||||
|
derivationIndex: 0,
|
||||||
|
derivationPath: DerivationPath()..value = "$hdPathEthereum/0",
|
||||||
|
type: AddressType.ethereum,
|
||||||
|
subType: AddressSubType.receiving,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== Overrides ============================================
|
||||||
|
|
||||||
|
@override
|
||||||
|
FilterOperation? get changeAddressFilterOperation =>
|
||||||
|
FilterGroup.and(standardChangeAddressFilters);
|
||||||
|
|
||||||
|
@override
|
||||||
|
FilterOperation? get receivingAddressFilterOperation =>
|
||||||
|
FilterGroup.and(standardReceivingAddressFilters);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> init({bool? isRestore}) {
|
||||||
|
// TODO: implement init
|
||||||
|
return super.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Amount> estimateFeeFor(Amount amount, int feeRate) async {
|
||||||
|
return estimateFee(
|
||||||
|
feeRate,
|
||||||
|
(cryptoCurrency as Ethereum).gasLimit,
|
||||||
|
cryptoCurrency.fractionDigits,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<FeeObject> get fees => EthereumAPI.getFees();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> pingCheck() async {
|
||||||
|
web3.Web3Client client = getEthClient();
|
||||||
|
try {
|
||||||
|
await client.getBlockNumber();
|
||||||
|
return true;
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> updateBalance() async {
|
||||||
|
try {
|
||||||
|
final client = getEthClient();
|
||||||
|
|
||||||
|
final addressHex = (await getCurrentReceivingAddress())!.value;
|
||||||
|
final address = web3.EthereumAddress.fromHex(addressHex);
|
||||||
|
web3.EtherAmount ethBalance = await client.getBalance(address);
|
||||||
|
final balance = Balance(
|
||||||
|
total: Amount(
|
||||||
|
rawValue: ethBalance.getInWei,
|
||||||
|
fractionDigits: cryptoCurrency.fractionDigits,
|
||||||
|
),
|
||||||
|
spendable: Amount(
|
||||||
|
rawValue: ethBalance.getInWei,
|
||||||
|
fractionDigits: cryptoCurrency.fractionDigits,
|
||||||
|
),
|
||||||
|
blockedTotal: Amount.zeroWith(
|
||||||
|
fractionDigits: cryptoCurrency.fractionDigits,
|
||||||
|
),
|
||||||
|
pendingSpendable: Amount.zeroWith(
|
||||||
|
fractionDigits: cryptoCurrency.fractionDigits,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await info.updateBalance(
|
||||||
|
newBalance: balance,
|
||||||
|
isar: mainDB.isar,
|
||||||
|
);
|
||||||
|
} catch (e, s) {
|
||||||
|
Logging.instance.log(
|
||||||
|
"$runtimeType wallet failed to update balance: $e\n$s",
|
||||||
|
level: LogLevel.Warning,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> updateChainHeight() async {
|
||||||
|
try {
|
||||||
|
final client = getEthClient();
|
||||||
|
final height = await client.getBlockNumber();
|
||||||
|
|
||||||
|
await info.updateCachedChainHeight(
|
||||||
|
newHeight: height,
|
||||||
|
isar: mainDB.isar,
|
||||||
|
);
|
||||||
|
} catch (e, s) {
|
||||||
|
Logging.instance.log(
|
||||||
|
"$runtimeType Exception caught in chainHeight: $e\n$s",
|
||||||
|
level: LogLevel.Warning,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> updateNode() async {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> updateTransactions({bool isRescan = false}) async {
|
||||||
|
String thisAddress = (await getCurrentReceivingAddress())!.value;
|
||||||
|
|
||||||
|
int firstBlock = 0;
|
||||||
|
|
||||||
|
if (!isRescan) {
|
||||||
|
firstBlock = await mainDB.isar.transactionV2s
|
||||||
|
.where()
|
||||||
|
.walletIdEqualTo(walletId)
|
||||||
|
.heightProperty()
|
||||||
|
.max() ??
|
||||||
|
0;
|
||||||
|
|
||||||
|
if (firstBlock > 10) {
|
||||||
|
// add some buffer
|
||||||
|
firstBlock -= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final response = await EthereumAPI.getEthTransactions(
|
||||||
|
address: thisAddress,
|
||||||
|
firstBlock: isRescan ? 0 : firstBlock,
|
||||||
|
includeTokens: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.value == null) {
|
||||||
|
Logging.instance.log(
|
||||||
|
"Failed to refresh transactions for ${cryptoCurrency.coin.prettyName} ${info.name} "
|
||||||
|
"$walletId: ${response.exception}",
|
||||||
|
level: LogLevel.Warning,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.value!.isEmpty) {
|
||||||
|
// no new transactions found
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final txsResponse =
|
||||||
|
await EthereumAPI.getEthTransactionNonces(response.value!);
|
||||||
|
|
||||||
|
if (txsResponse.value != null) {
|
||||||
|
final allTxs = txsResponse.value!;
|
||||||
|
final List<TransactionV2> txns = [];
|
||||||
|
for (final tuple in allTxs) {
|
||||||
|
final element = tuple.item1;
|
||||||
|
|
||||||
|
//Calculate fees (GasLimit * gasPrice)
|
||||||
|
// int txFee = element.gasPrice * element.gasUsed;
|
||||||
|
Amount txFee = element.gasCost;
|
||||||
|
final transactionAmount = element.value;
|
||||||
|
final addressFrom = checksumEthereumAddress(element.from);
|
||||||
|
final addressTo = checksumEthereumAddress(element.to);
|
||||||
|
|
||||||
|
bool isIncoming;
|
||||||
|
bool txFailed = false;
|
||||||
|
if (addressFrom == thisAddress) {
|
||||||
|
if (element.isError) {
|
||||||
|
txFailed = true;
|
||||||
|
}
|
||||||
|
isIncoming = false;
|
||||||
|
} else if (addressTo == thisAddress) {
|
||||||
|
isIncoming = true;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hack epic tx data into inputs and outputs
|
||||||
|
final List<OutputV2> outputs = [];
|
||||||
|
final List<InputV2> inputs = [];
|
||||||
|
|
||||||
|
OutputV2 output = OutputV2.isarCantDoRequiredInDefaultConstructor(
|
||||||
|
scriptPubKeyHex: "00",
|
||||||
|
valueStringSats: transactionAmount.raw.toString(),
|
||||||
|
addresses: [
|
||||||
|
addressTo,
|
||||||
|
],
|
||||||
|
walletOwns: addressTo == thisAddress,
|
||||||
|
);
|
||||||
|
InputV2 input = InputV2.isarCantDoRequiredInDefaultConstructor(
|
||||||
|
scriptSigHex: null,
|
||||||
|
sequence: null,
|
||||||
|
outpoint: null,
|
||||||
|
addresses: [addressFrom],
|
||||||
|
valueStringSats: transactionAmount.raw.toString(),
|
||||||
|
witness: null,
|
||||||
|
innerRedeemScriptAsm: null,
|
||||||
|
coinbase: null,
|
||||||
|
walletOwns: addressFrom == thisAddress,
|
||||||
|
);
|
||||||
|
|
||||||
|
final TransactionType txType;
|
||||||
|
if (isIncoming) {
|
||||||
|
if (addressFrom == addressTo) {
|
||||||
|
txType = TransactionType.sentToSelf;
|
||||||
|
} else {
|
||||||
|
txType = TransactionType.incoming;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
txType = TransactionType.outgoing;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputs.add(output);
|
||||||
|
inputs.add(input);
|
||||||
|
|
||||||
|
final otherData = {
|
||||||
|
"nonce": tuple.item2,
|
||||||
|
"isCancelled": txFailed,
|
||||||
|
"anonFees": txFee.toJsonString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
final txn = TransactionV2(
|
||||||
|
walletId: walletId,
|
||||||
|
blockHash: element.blockHash,
|
||||||
|
hash: element.hash,
|
||||||
|
txid: element.hash,
|
||||||
|
timestamp: element.timestamp,
|
||||||
|
height: element.blockNumber,
|
||||||
|
inputs: List.unmodifiable(inputs),
|
||||||
|
outputs: List.unmodifiable(outputs),
|
||||||
|
version: -1,
|
||||||
|
type: txType,
|
||||||
|
subType: TransactionSubType.none,
|
||||||
|
otherData: jsonEncode(otherData),
|
||||||
|
);
|
||||||
|
|
||||||
|
txns.add(txn);
|
||||||
|
}
|
||||||
|
await mainDB.updateOrPutTransactionV2s(txns);
|
||||||
|
} else {
|
||||||
|
Logging.instance.log(
|
||||||
|
"Failed to refresh transactions with nonces for ${cryptoCurrency.coin.prettyName} "
|
||||||
|
"${info.name} $walletId: ${txsResponse.exception}",
|
||||||
|
level: LogLevel.Warning,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> updateUTXOs() async {
|
||||||
|
// not used in eth
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TxData> confirmSend({required TxData txData}) {
|
||||||
|
// TODO: implement confirmSend
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TxData> prepareSend({required TxData txData}) {
|
||||||
|
// TODO: implement prepareSend
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> recover({required bool isRescan}) async {
|
||||||
|
if (isRescan) {
|
||||||
|
await mainDB.deleteWalletBlockchainData(walletId);
|
||||||
|
await _generateAndSaveAddress(
|
||||||
|
await getMnemonic(),
|
||||||
|
await getMnemonicPassphrase(),
|
||||||
|
);
|
||||||
|
await updateBalance();
|
||||||
|
await updateTransactions(isRescan: true);
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> exit() async {
|
||||||
|
timer?.cancel();
|
||||||
|
timer = null;
|
||||||
|
await super.exit();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,39 +0,0 @@
|
||||||
import 'package:stackwallet/exceptions/sw_exception.dart';
|
|
||||||
import 'package:stackwallet/wallets/models/tx_data.dart';
|
|
||||||
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
|
||||||
|
|
||||||
abstract class PrivateKeyBasedWallet extends Wallet {
|
|
||||||
PrivateKeyBasedWallet(super.cryptoCurrency);
|
|
||||||
|
|
||||||
Future<String> getPrivateKey() async {
|
|
||||||
final privateKey = await secureStorageInterface.read(
|
|
||||||
key: Wallet.privateKeyKey(walletId: info.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();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> recover({required bool isRescan}) {
|
|
||||||
// TODO: implement recover
|
|
||||||
throw UnimplementedError();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -28,6 +28,7 @@ import 'package:stackwallet/wallets/wallet/impl/bitcoincash_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/impl/dogecoin_wallet.dart';
|
import 'package:stackwallet/wallets/wallet/impl/dogecoin_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/impl/ecash_wallet.dart';
|
import 'package:stackwallet/wallets/wallet/impl/ecash_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/impl/epiccash_wallet.dart';
|
import 'package:stackwallet/wallets/wallet/impl/epiccash_wallet.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
|
import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/impl/litecoin_wallet.dart';
|
import 'package:stackwallet/wallets/wallet/impl/litecoin_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/impl/monero_wallet.dart';
|
import 'package:stackwallet/wallets/wallet/impl/monero_wallet.dart';
|
||||||
|
@ -37,11 +38,11 @@ import 'package:stackwallet/wallets/wallet/impl/particl_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/impl/tezos_wallet.dart';
|
import 'package:stackwallet/wallets/wallet/impl/tezos_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/impl/wownero_wallet.dart';
|
import 'package:stackwallet/wallets/wallet/impl/wownero_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/intermediate/cryptonote_wallet.dart';
|
import 'package:stackwallet/wallets/wallet/intermediate/cryptonote_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/private_key_based_wallet.dart';
|
|
||||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/lelantus_interface.dart';
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/lelantus_interface.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/multi_address_interface.dart';
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/multi_address_interface.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/private_key_interface.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart';
|
import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart';
|
||||||
|
|
||||||
abstract class Wallet<T extends CryptoCurrency> {
|
abstract class Wallet<T extends CryptoCurrency> {
|
||||||
|
@ -156,7 +157,10 @@ abstract class Wallet<T extends CryptoCurrency> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wallet is PrivateKeyBasedWallet) {
|
// TODO [prio=low] handle eth differently?
|
||||||
|
// This would need to be changed if we actually end up allowing eth wallets
|
||||||
|
// to be created with a private key instead of mnemonic only
|
||||||
|
if (wallet is PrivateKeyInterface && wallet is! EthereumWallet) {
|
||||||
await secureStorageInterface.write(
|
await secureStorageInterface.write(
|
||||||
key: privateKeyKey(walletId: walletInfo.walletId),
|
key: privateKeyKey(walletId: walletInfo.walletId),
|
||||||
value: privateKey!,
|
value: privateKey!,
|
||||||
|
@ -278,6 +282,9 @@ abstract class Wallet<T extends CryptoCurrency> {
|
||||||
case Coin.epicCash:
|
case Coin.epicCash:
|
||||||
return EpiccashWallet(CryptoCurrencyNetwork.main);
|
return EpiccashWallet(CryptoCurrencyNetwork.main);
|
||||||
|
|
||||||
|
case Coin.ethereum:
|
||||||
|
return EthereumWallet(CryptoCurrencyNetwork.main);
|
||||||
|
|
||||||
case Coin.firo:
|
case Coin.firo:
|
||||||
return FiroWallet(CryptoCurrencyNetwork.main);
|
return FiroWallet(CryptoCurrencyNetwork.main);
|
||||||
case Coin.firoTestNet:
|
case Coin.firoTestNet:
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import 'package:stackwallet/exceptions/sw_exception.dart';
|
||||||
|
import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
||||||
|
|
||||||
|
mixin PrivateKeyInterface<T extends CryptoCurrency> on Wallet<T> {
|
||||||
|
Future<String> getPrivateKey() async {
|
||||||
|
final privateKey = await secureStorageInterface.read(
|
||||||
|
key: Wallet.privateKeyKey(walletId: info.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();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Future<void> recover({required bool isRescan}) {
|
||||||
|
// // TODO: implement recover
|
||||||
|
// throw UnimplementedError();
|
||||||
|
// }
|
||||||
|
}
|
|
@ -12,11 +12,11 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
import 'package:stackwallet/widgets/animated_widgets/rotate_icon.dart';
|
import 'package:stackwallet/widgets/animated_widgets/rotate_icon.dart';
|
||||||
import 'package:stackwallet/widgets/expandable.dart';
|
import 'package:stackwallet/widgets/expandable.dart';
|
||||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
@ -47,7 +47,7 @@ class _MasterWalletCardState extends ConsumerState<MasterWalletCard> {
|
||||||
final ethWallet =
|
final ethWallet =
|
||||||
ref.read(pWallets).getWallet(widget.walletId) as EthereumWallet;
|
ref.read(pWallets).getWallet(widget.walletId) as EthereumWallet;
|
||||||
|
|
||||||
tokenContractAddresses = ethWallet.getWalletTokenContractAddresses();
|
tokenContractAddresses = ethWallet.info.tokenContractAddresses;
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/des
|
||||||
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
||||||
import 'package:stackwallet/providers/global/secure_store_provider.dart';
|
import 'package:stackwallet/providers/global/secure_store_provider.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
|
import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
|
||||||
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
@ -28,6 +27,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/logger.dart';
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
import 'package:stackwallet/utilities/show_loading.dart';
|
import 'package:stackwallet/utilities/show_loading.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
import 'package:stackwallet/wallets/wallet/wallet.dart';
|
||||||
import 'package:stackwallet/widgets/conditional_parent.dart';
|
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||||
|
@ -58,7 +58,6 @@ class SimpleWalletCard extends ConsumerWidget {
|
||||||
ref.read(tokenServiceStateProvider.state).state = EthTokenWallet(
|
ref.read(tokenServiceStateProvider.state).state = EthTokenWallet(
|
||||||
token: contract,
|
token: contract,
|
||||||
secureStore: ref.read(secureStoreProvider),
|
secureStore: ref.read(secureStoreProvider),
|
||||||
// TODO: [prio=high] FIX THIS BAD as CAST
|
|
||||||
ethWallet: wallet as EthereumWallet,
|
ethWallet: wallet as EthereumWallet,
|
||||||
tracker: TransactionNotificationTracker(
|
tracker: TransactionNotificationTracker(
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
|
|
|
@ -13,13 +13,13 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:stackwallet/db/isar/main_db.dart';
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount_formatter.dart';
|
import 'package:stackwallet/utilities/amount/amount_formatter.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
|
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
|
||||||
|
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
|
||||||
|
|
||||||
class WalletInfoRowBalance extends ConsumerWidget {
|
class WalletInfoRowBalance extends ConsumerWidget {
|
||||||
const WalletInfoRowBalance({
|
const WalletInfoRowBalance({
|
||||||
|
@ -47,7 +47,9 @@ class WalletInfoRowBalance extends ConsumerWidget {
|
||||||
final ethWallet =
|
final ethWallet =
|
||||||
ref.watch(pWallets).getWallet(walletId) as EthereumWallet;
|
ref.watch(pWallets).getWallet(walletId) as EthereumWallet;
|
||||||
contract = MainDB.instance.getEthContractSync(contractAddress!)!;
|
contract = MainDB.instance.getEthContractSync(contractAddress!)!;
|
||||||
totalBalance = ethWallet.getCachedTokenBalance(contract).total;
|
//TODO: [prio=high] fix this for token service/interface
|
||||||
|
// totalBalance = ethWallet.getCachedTokenBalance(contract).total;
|
||||||
|
totalBalance = Amount.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Text(
|
return Text(
|
||||||
|
|
Loading…
Reference in a new issue