diff --git a/lib/dto/ethereum/eth_token_tx_extra_dto.dart b/lib/dto/ethereum/eth_token_tx_extra_dto.dart index 5629ce959..144194914 100644 --- a/lib/dto/ethereum/eth_token_tx_extra_dto.dart +++ b/lib/dto/ethereum/eth_token_tx_extra_dto.dart @@ -116,13 +116,13 @@ class EthTokenTxExtraDTO { map['timestamp'] = timestamp; map['from'] = from; map['to'] = to; - map['value'] = value; - map['gas'] = gas; - map['gasPrice'] = gasPrice; + map['value'] = value.toJsonString(); + map['gas'] = gas.toJsonString(); + map['gasPrice'] = gasPrice.toJsonString(); map['input'] = input; map['nonce'] = nonce; - map['gasCost'] = gasCost; - map['gasUsed'] = gasUsed; + map['gasCost'] = gasCost.toJsonString(); + map['gasUsed'] = gasUsed.toJsonString(); return map; } diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart index df036a73b..3e7fb37fa 100644 --- a/lib/pages/wallet_view/wallet_view.dart +++ b/lib/pages/wallet_view/wallet_view.dart @@ -680,6 +680,7 @@ class _WalletViewState extends ConsumerState { padding: const EdgeInsets.symmetric(horizontal: 16), child: WalletSummary( walletId: walletId, + aspectRatio: 1.75, initialSyncStatus: ref.watch(managerProvider .select((value) => value.isRefreshing)) ? WalletSyncStatus.syncing diff --git a/lib/services/coins/ethereum/ethereum_wallet.dart b/lib/services/coins/ethereum/ethereum_wallet.dart index 9a6c2dc47..9990406d9 100644 --- a/lib/services/coins/ethereum/ethereum_wallet.dart +++ b/lib/services/coins/ethereum/ethereum_wallet.dart @@ -265,17 +265,23 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { @override Future get fees => EthereumAPI.getFees(); - //Full rescan is not needed for ETH since we have a balance @override Future fullRescan( - int maxUnusedAddressGap, int maxNumberOfIndexesToCheck) { - // TODO: implement fullRescan - throw UnimplementedError(); + int maxUnusedAddressGap, + int maxNumberOfIndexesToCheck, + ) async { + await db.deleteWalletBlockchainData(walletId); + await _generateAndSaveAddress( + (await mnemonicString)!, + (await mnemonicPassphrase)!, + ); + await updateBalance(); + await _refreshTransactions(isRescan: true); } @override Future generateNewAddress() { - // TODO: implement generateNewAddress - might not be needed for ETH + // not used for ETH throw UnimplementedError(); } @@ -291,10 +297,10 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { level: LogLevel.Info, ); - //First get mnemonic so we can initialize credentials - String privateKey = - getPrivateKey((await mnemonicString)!, (await mnemonicPassphrase)!); - _credentials = web3.EthPrivateKey.fromHex(privateKey); + await _initCredentials( + (await mnemonicString)!, + (await mnemonicPassphrase)!, + ); if (getCachedId() == null) { throw Exception( @@ -367,8 +373,24 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { value: "", ); - String privateKey = getPrivateKey(mnemonic, ""); + await _generateAndSaveAddress(mnemonic, ""); + + Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info); + } + + Future _initCredentials( + String mnemonic, + String mnemonicPassphrase, + ) async { + String privateKey = getPrivateKey(mnemonic, mnemonicPassphrase); _credentials = web3.EthPrivateKey.fromHex(privateKey); + } + + Future _generateAndSaveAddress( + String mnemonic, + String mnemonicPassphrase, + ) async { + await _initCredentials(mnemonic, mnemonicPassphrase); final address = Address( walletId: walletId, @@ -381,8 +403,6 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { ); await db.putAddress(address); - - Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info); } bool _isConnected = false; @@ -649,7 +669,7 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { if (!needsRefresh) { var allOwnAddresses = await _fetchAllOwnAddresses(); final response = await EthereumAPI.getEthTransactions( - allOwnAddresses.elementAt(0).value, + address: allOwnAddresses.elementAt(0).value, ); if (response.value != null) { final allTxs = response.value!; @@ -985,10 +1005,25 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { return isValidEthereumAddress(address); } - Future _refreshTransactions() async { + Future _refreshTransactions({bool isRescan = false}) async { String thisAddress = await currentReceivingAddress; - final response = await EthereumAPI.getEthTransactions(thisAddress); + int firstBlock = 0; + + if (!isRescan) { + firstBlock = + await db.getTransactions(walletId).heightProperty().max() ?? 0; + + if (firstBlock > 10) { + // add some buffer + firstBlock -= 10; + } + } + + final response = await EthereumAPI.getEthTransactions( + address: thisAddress, + firstBlock: isRescan ? 0 : firstBlock, + ); if (response.value == null) { Logging.instance.log( @@ -999,6 +1034,11 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { return; } + if (response.value!.isEmpty) { + // no new transactions found + return; + } + final txsResponse = await EthereumAPI.getEthTransactionNonces(response.value!); diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart index 242d85214..6445a2aa5 100644 --- a/lib/services/coins/monero/monero_wallet.dart +++ b/lib/services/coins/monero/monero_wallet.dart @@ -864,6 +864,10 @@ class MoneroWallet extends CoinServiceAPI with WalletCache, WalletDB { // String address = walletBase!.getTransactionAddress(chain, index); + if (address.contains("111")) { + return await _generateAddressForChain(chain, index + 1); + } + return isar_models.Address( walletId: walletId, derivationIndex: index, diff --git a/lib/services/ethereum/ethereum_api.dart b/lib/services/ethereum/ethereum_api.dart index de4a91540..d30b9ea27 100644 --- a/lib/services/ethereum/ethereum_api.dart +++ b/lib/services/ethereum/ethereum_api.dart @@ -47,12 +47,14 @@ class EthereumResponse { abstract class EthereumAPI { static String get stackBaseServer => DefaultNodes.ethereum.host; - static Future>> getEthTransactions( - String address) async { + static Future>> getEthTransactions({ + required String address, + int firstBlock = 0, + }) async { try { final response = await get( Uri.parse( - "$stackBaseServer/export?addrs=$address", + "$stackBaseServer/export?addrs=$address&firstBlock=$firstBlock", ), ); diff --git a/lib/services/ethereum/ethereum_token_service.dart b/lib/services/ethereum/ethereum_token_service.dart index b00551854..ebe55c73e 100644 --- a/lib/services/ethereum/ethereum_token_service.dart +++ b/lib/services/ethereum/ethereum_token_service.dart @@ -507,9 +507,13 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache { } else if (toAddress == addressString) { isIncoming = true; } else { - throw Exception("Unknown token transaction found for " - "${ethWallet.walletName} ${ethWallet.walletId}: " - "${tuple.item1.toString()}"); + // ignore for now I guess since anything here is not reflected in + // balance anyways + continue; + + // throw Exception("Unknown token transaction found for " + // "${ethWallet.walletName} ${ethWallet.walletId}: " + // "${tuple.item1.toString()}"); } final txn = Transaction( diff --git a/lib/themes/coin_icon_provider.dart b/lib/themes/coin_icon_provider.dart index 57695caa0..9bd3990bb 100644 --- a/lib/themes/coin_icon_provider.dart +++ b/lib/themes/coin_icon_provider.dart @@ -30,8 +30,6 @@ final coinIconProvider = Provider.family((ref, coin) { case Coin.dogecoin: case Coin.dogecoinTestNet: return assets.dogecoin; - case Coin.eCash: - return assets.bitcoin; case Coin.epicCash: return assets.epicCash; case Coin.firo: @@ -48,7 +46,7 @@ final coinIconProvider = Provider.family((ref, coin) { case Coin.ethereum: return assets.ethereum; default: - return assets.bitcoin; + return assets.stackIcon; } } else if (assets is ThemeAssetsV2) { return (assets).coinIcons[coin.mainNetVersion]!; diff --git a/lib/themes/theme_service.dart b/lib/themes/theme_service.dart index f384a0f19..c72d778b6 100644 --- a/lib/themes/theme_service.dart +++ b/lib/themes/theme_service.dart @@ -98,7 +98,10 @@ class ThemeService { await db.isar.writeTxn(() async { await db.isar.stackThemes.delete(isarId); }); - await Directory("${themesDir.path}/$themeId").delete(recursive: true); + final dir = Directory("${themesDir.path}/$themeId"); + if (dir.existsSync()) { + await dir.delete(recursive: true); + } } else { Logging.instance.log( "Failed to delete theme $themeId", diff --git a/lib/widgets/coin_card.dart b/lib/widgets/coin_card.dart index 3d122c42a..0bebc5fd8 100644 --- a/lib/widgets/coin_card.dart +++ b/lib/widgets/coin_card.dart @@ -47,8 +47,11 @@ class CoinCard extends ConsumerWidget { width: width, height: height, decoration: BoxDecoration( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), image: DecorationImage( - fit: BoxFit.fill, + fit: BoxFit.cover, image: FileImage( File( ref.watch(coinCardProvider(coin))!,