Cw 78 ethereum (#862)

* Add initial flow for ethereum

* Add initial create Eth wallet flow

* Complete Ethereum wallet creation flow

* Fix web3dart versioning issue

* Add primary receive address extracted from private key

* Implement open wallet functionality

* Implement restore wallet from seed functionality

* Fixate web3dart version as higher versions cause some issues

* Add Initial Transaction priorities for eth
Add estimated gas price

* Rename priority value to tip

* Re-order wallet types

* Change ethereum node
Fix connection issues

* Fix estimating gas for priority

* Add case for ethereum to fetch it's seeds

* Add case for ethereum to request node

* Fix Exchange screen initial pairs

* Add initial send transaction flow

* Add missing configure for ethereum class

* Add Eth address initial setup

* Fix Private key for Ethereum wallets

* Change sign/send transaction flow

* - Fix Conflicts with main
- Remove unused function from Haven configure.dart

* Add build command for ethereum package

* Add missing Node list file to pubspec

* - Fix balance display
- Fix parsing of Ethereum amount
- Add more Ethereum Nodes 

* - Fix extracting Ethereum Private key from seeds
- Integrate signing/sending transaction with the send view model

* - Update and Fix Conflicts with main

* Add Balances for ERC20 tokens

* Fix conflicts with main

* Add erc20 abi json

* Add send erc20 tokens initial function

* add missing getHeightByDate in Haven

* Allow contacts and wallets from the same tag

* Add Shiba Inu icon

* Add send ERC-20 tokens initial flow

* Add missing import in generated file

* Add initial approach for transaction sending for ERC-20 tokens

* Refactor signing/sending transactions

* Add initial flow for transactions subscription

* Refactor signing/sending transactions

* Add home settings icon

* Fix conflicts with main

* Initial flow for home settings

* Add logic flow for adding erc20 tokens

* Fix initial UI

* Finalize UI for Tokens

* Integrate UI with Ethereum flow

* Add "Enable/Disable" feature for ERC20 tokens

* Add initial Erc20 tokens

* Add Sorting and Pin Native Token features

* Fix price sorting

* Sort tokens list as well when Sort criteria changes

* - Improve sorting balances flow
- Add initial add token from search bar flow

* Fix Accounts Popup UI

* Fix Pin native token

* Fix Enabling/Disabling tokens
Fix sorting by fiat once app is opened
Improve token availability mechanism

* Fix deleting token
Fix renaming tokens

* Fix issue with search

* Add more tokens

* - Fix scroll issue
- Add ERC20 tokens placeholder image in picker

* - Separate and organize default erc20 tokens
- Fix scrolling
- Add token placeholder images in picker
- Sort disabled tokens alphabetically

* Change BNB token initial availability

* Fix Conflicts with main

* Fix Conflicts with main

* Add Verse ERC20 token to the initial tokens list

* Add rename wallet to Ethereum

* Integrate EtherScan API for fetching address transactions
Generate Ethereum specific secrets in Ethereum package

* Adjust transactions fiat price for ERC20 tokens

* Free Up GitHub Actions Ubuntu Runner Disk Space

* Free Up GitHub Actions Ubuntu Runner Disk space (trial 2)

* Fix Transaction Fee display

* Save transaction history

* Enhance loading time for erc20 tokens transactions

* Minor Fixes and Enhancements

* Fix sending erc20
fix block explorer issue

* Fix int overflow

* Fix transaction amount conversions

* Minor: `slow` -> `Slow` 

* Update build guide

* Fix fetching fiat rate taking a lot of time by only fetching enabled tokens only and making the API calls in parallel not sequential

* Update transactions on a periodic basis

* For fee, use ETH spot price, not ERC-20 spot price

* Add Etherscan History privacy option to enable/disable Etherscan API

* Show estimated fee amounts in the send screen

* fix send fiat fields parsing issue

* Fix transactions estimated fee less than actual fee

* handle balance sorting when balance is disabled
Handle empty transactions list

* Fix Delete Ethereum wallet
Fix balance < 0.01

* Fix Decimal place for Ethereum amount
Fix sending amount issue

* Change words count

* Remove balance hint and Full balance row from Ethereum wallets

* support changing the asset type in send templates

* Fix Templates for ERC tokens issues

* Fix conflicts in send templates

* Disable batch sending in Ethereum

* Fix Fee calculation with different priorities

* Fix Conflicts with main

* Add offline error to ignored exceptions

---------

Co-authored-by: Justin Ehrenhofer <justin.ehrenhofer@gmail.com>
This commit is contained in:
Omar Hatem
2023-08-04 20:01:49 +03:00
committed by GitHub
co-authored by Justin Ehrenhofer
parent 4120394121
commit 3ce4000dcf
137 changed files with 7164 additions and 1492 deletions
+13 -1
View File
@@ -2,6 +2,7 @@ import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
import 'package:cake_wallet/entities/parsed_address.dart';
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/haven/haven.dart';
import 'package:cake_wallet/src/screens/send/widgets/extract_address_from_parsed.dart';
import 'package:cw_core/crypto_currency.dart';
@@ -90,6 +91,9 @@ abstract class OutputBase with Store {
case WalletType.haven:
_amount = haven!.formatterMoneroParseAmount(amount: _cryptoAmount);
break;
case WalletType.ethereum:
_amount = ethereum!.formatterEthereumParseAmount(_cryptoAmount);
break;
default:
break;
}
@@ -123,6 +127,10 @@ abstract class OutputBase with Store {
if (_wallet.type == WalletType.haven) {
return haven!.formatterMoneroAmountToDouble(amount: fee);
}
if (_wallet.type == WalletType.ethereum) {
return ethereum!.formatterEthereumAmountToDouble(amount: BigInt.from(fee));
}
} catch (e) {
print(e.toString());
}
@@ -133,8 +141,9 @@ abstract class OutputBase with Store {
@computed
String get estimatedFeeFiatAmount {
try {
final currency = _wallet.type == WalletType.ethereum ? _wallet.currency : cryptoCurrencyHandler();
final fiat = calculateFiatAmountRaw(
price: _fiatConversationStore.prices[cryptoCurrencyHandler()]!,
price: _fiatConversationStore.prices[currency]!,
cryptoAmount: estimatedFee);
return fiat;
} catch (_) {
@@ -228,6 +237,9 @@ abstract class OutputBase with Store {
case WalletType.haven:
maximumFractionDigits = 12;
break;
case WalletType.ethereum:
maximumFractionDigits = 12;
break;
default:
break;
}
@@ -13,8 +13,7 @@ import 'package:cake_wallet/store/settings_store.dart';
part 'send_template_view_model.g.dart';
class SendTemplateViewModel = SendTemplateViewModelBase
with _$SendTemplateViewModel;
class SendTemplateViewModel = SendTemplateViewModelBase with _$SendTemplateViewModel;
abstract class SendTemplateViewModelBase with Store {
final WalletBase _wallet;
@@ -22,8 +21,8 @@ abstract class SendTemplateViewModelBase with Store {
final SendTemplateStore _sendTemplateStore;
final FiatConversionStore _fiatConversationStore;
SendTemplateViewModelBase(this._wallet, this._settingsStore,
this._sendTemplateStore, this._fiatConversationStore)
SendTemplateViewModelBase(
this._wallet, this._settingsStore, this._sendTemplateStore, this._fiatConversationStore)
: recipients = ObservableList<TemplateViewModel>() {
addRecipient();
}
@@ -33,7 +32,6 @@ abstract class SendTemplateViewModelBase with Store {
@action
void addRecipient() {
recipients.add(TemplateViewModel(
cryptoCurrency: cryptoCurrency,
wallet: _wallet,
settingsStore: _settingsStore,
fiatConversationStore: _fiatConversationStore));
@@ -47,11 +45,13 @@ abstract class SendTemplateViewModelBase with Store {
AmountValidator get amountValidator =>
AmountValidator(currency: walletTypeToCryptoCurrency(_wallet.type));
AddressValidator get addressValidator =>
AddressValidator(type: _wallet.currency);
AddressValidator get addressValidator => AddressValidator(type: _wallet.currency);
TemplateValidator get templateValidator => TemplateValidator();
bool get hasMultiRecipient =>
_wallet.type != WalletType.haven && _wallet.type != WalletType.ethereum;
@computed
CryptoCurrency get cryptoCurrency => _wallet.currency;
@@ -68,6 +68,7 @@ abstract class SendTemplateViewModelBase with Store {
void addTemplate(
{required String name,
required bool isCurrencySelected,
required String cryptoCurrency,
required String address,
required String amount,
required String amountFiat,
@@ -76,7 +77,7 @@ abstract class SendTemplateViewModelBase with Store {
name: name,
isCurrencySelected: isCurrencySelected,
address: address,
cryptoCurrency: cryptoCurrency.title,
cryptoCurrency: cryptoCurrency,
fiatCurrency: fiatCurrency,
amount: amount,
amountFiat: amountFiat,
@@ -89,4 +90,7 @@ abstract class SendTemplateViewModelBase with Store {
_sendTemplateStore.remove(template: template);
updateTemplate();
}
@computed
List<CryptoCurrency> get walletCurrencies => _wallet.balance.keys.toList();
}
+37 -12
View File
@@ -3,6 +3,7 @@ import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:cake_wallet/entities/wallet_contact.dart';
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cake_wallet/view_model/send/output.dart';
@@ -45,6 +46,7 @@ abstract class SendViewModelBase with Store {
: state = InitialExecutionState(),
currencies = _wallet.balance.keys.toList(),
selectedCryptoCurrency = _wallet.currency,
hasMultipleTokens = _wallet.type == WalletType.ethereum,
outputs = ObservableList<Output>(),
fiatFromSettings = _settingsStore.fiatCurrency {
final priority = _settingsStore.priority[_wallet.type];
@@ -105,8 +107,11 @@ abstract class SendViewModelBase with Store {
String get pendingTransactionFeeFiatAmount {
try {
if (pendingTransaction != null) {
final currency = walletType == WalletType.ethereum
? _wallet.currency
: selectedCryptoCurrency;
final fiat = calculateFiatAmount(
price: _fiatConversationStore.prices[selectedCryptoCurrency]!,
price: _fiatConversationStore.prices[currency]!,
cryptoAmount: pendingTransaction!.feeFormatted);
return fiat;
} else {
@@ -131,14 +136,14 @@ abstract class SendViewModelBase with Store {
CryptoCurrency get currency => _wallet.currency;
Validator get amountValidator =>
Validator<String> get amountValidator =>
AmountValidator(currency: walletTypeToCryptoCurrency(_wallet.type));
Validator get allAmountValidator => AllAmountValidator();
Validator<String> get allAmountValidator => AllAmountValidator();
Validator get addressValidator => AddressValidator(type: selectedCryptoCurrency);
Validator<String> get addressValidator => AddressValidator(type: selectedCryptoCurrency);
Validator get textValidator => TextValidator();
Validator<String> get textValidator => TextValidator();
final FiatCurrency fiatFromSettings;
@@ -146,7 +151,7 @@ abstract class SendViewModelBase with Store {
PendingTransaction? pendingTransaction;
@computed
String get balance => balanceViewModel.availableBalance;
String get balance => _wallet.balance[selectedCryptoCurrency]!.formattedAvailableBalance;
@computed
bool get isFiatDisabled => balanceViewModel.isFiatDisabled;
@@ -176,10 +181,9 @@ abstract class SendViewModelBase with Store {
List<CryptoCurrency> currencies;
bool get hasMultiRecipient => _wallet.type != WalletType.haven;
bool get hasYat => outputs
.any((out) => out.isParsedAddress && out.parsedAddress.parseFrom == ParseFrom.yatRecord);
bool get hasYat => outputs.any((out) =>
out.isParsedAddress &&
out.parsedAddress.parseFrom == ParseFrom.yatRecord);
WalletType get walletType => _wallet.type;
@@ -198,6 +202,7 @@ abstract class SendViewModelBase with Store {
final ContactListViewModel contactListViewModel;
final FiatConversionStore _fiatConversationStore;
final Box<TransactionDescription> transactionDescriptionBox;
final bool hasMultipleTokens;
@computed
List<ContactRecord> get contactsToShow => contactListViewModel.contacts
@@ -351,6 +356,15 @@ abstract class SendViewModelBase with Store {
return haven!.createHavenTransactionCreationCredentials(
outputs: outputs, priority: priority, assetType: selectedCryptoCurrency.title);
case WalletType.ethereum:
final priority = _settingsStore.priority[_wallet.type];
if (priority == null) {
throw Exception('Priority is null for wallet type: ${_wallet.type}');
}
return ethereum!.createEthereumTransactionCredentials(
outputs, priority: priority, currency: selectedCryptoCurrency);
default:
throw Exception('Unexpected wallet type: ${_wallet.type}');
}
@@ -369,11 +383,22 @@ abstract class SendViewModelBase with Store {
}
bool _isEqualCurrency(String currency) =>
currency.toLowerCase() == _wallet.currency.title.toLowerCase();
_wallet.balance.keys.any((e) => currency.toLowerCase() == e.title.toLowerCase());
@action
void onClose() => _settingsStore.fiatCurrency = fiatFromSettings;
@action
void setFiatCurrency(FiatCurrency fiat) => _settingsStore.fiatCurrency = fiat;
void setFiatCurrency(FiatCurrency fiat) =>
_settingsStore.fiatCurrency = fiat;
@action
void setSelectedCryptoCurrency(String cryptoCurrency) {
try {
selectedCryptoCurrency = _wallet.balance.keys
.firstWhere((e) => cryptoCurrency.toLowerCase() == e.title.toLowerCase());
} catch (e) {
selectedCryptoCurrency = _wallet.currency;
}
}
}
+21 -13
View File
@@ -11,23 +11,20 @@ part 'template_view_model.g.dart';
class TemplateViewModel = TemplateViewModelBase with _$TemplateViewModel;
abstract class TemplateViewModelBase with Store {
final CryptoCurrency cryptoCurrency;
final WalletBase _wallet;
final SettingsStore _settingsStore;
final FiatConversionStore _fiatConversationStore;
TemplateViewModelBase(
{required this.cryptoCurrency,
required WalletBase wallet,
required SettingsStore settingsStore,
required FiatConversionStore fiatConversationStore})
: _wallet = wallet,
TemplateViewModelBase({
required WalletBase wallet,
required SettingsStore settingsStore,
required FiatConversionStore fiatConversationStore,
}) : _wallet = wallet,
_settingsStore = settingsStore,
_fiatConversationStore = fiatConversationStore,
output = Output(wallet, settingsStore, fiatConversationStore,
() => wallet.currency) {
output = Output(
_wallet, _settingsStore, _fiatConversationStore, () => cryptoCurrency);
_currency = wallet.currency,
output = Output(wallet, settingsStore, fiatConversationStore, () => wallet.currency) {
output = Output(_wallet, _settingsStore, _fiatConversationStore, () => _currency);
}
@observable
@@ -39,6 +36,9 @@ abstract class TemplateViewModelBase with Store {
@observable
String address = '';
@observable
CryptoCurrency _currency;
@observable
bool isCurrencySelected = true;
@@ -66,8 +66,7 @@ abstract class TemplateViewModelBase with Store {
output.reset();
}
Template toTemplate(
{required String cryptoCurrency, required String fiatCurrency}) {
Template toTemplate({required String cryptoCurrency, required String fiatCurrency}) {
return Template(
isCurrencySelectedRaw: isCurrencySelected,
nameRaw: name,
@@ -77,4 +76,13 @@ abstract class TemplateViewModelBase with Store {
amountRaw: output.cryptoAmount,
amountFiatRaw: output.fiatAmount);
}
@action
void changeSelectedCurrency(CryptoCurrency currency) {
isCurrencySelected = true;
_currency = currency;
}
@computed
CryptoCurrency get selectedCurrency => _currency;
}