2022-03-15 09:11:53 +00:00
|
|
|
import 'package:cake_wallet/di.dart';
|
2021-07-16 09:32:36 +00:00
|
|
|
import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
|
2021-07-22 16:48:26 +00:00
|
|
|
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
|
|
|
import 'package:cake_wallet/entities/parsed_address.dart';
|
2023-08-04 17:01:49 +00:00
|
|
|
import 'package:cake_wallet/ethereum/ethereum.dart';
|
2022-03-30 15:57:04 +00:00
|
|
|
import 'package:cake_wallet/haven/haven.dart';
|
2023-12-02 02:26:43 +00:00
|
|
|
import 'package:cake_wallet/polygon/polygon.dart';
|
|
|
|
import 'package:cake_wallet/reactions/wallet_connect.dart';
|
2024-03-29 18:55:29 +00:00
|
|
|
import 'package:cake_wallet/solana/solana.dart';
|
2021-09-29 11:38:31 +00:00
|
|
|
import 'package:cake_wallet/src/screens/send/widgets/extract_address_from_parsed.dart';
|
2022-03-30 15:57:04 +00:00
|
|
|
import 'package:cw_core/crypto_currency.dart';
|
2021-07-16 09:32:36 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:intl/intl.dart';
|
|
|
|
import 'package:mobx/mobx.dart';
|
2021-12-24 12:37:24 +00:00
|
|
|
import 'package:cw_core/wallet_base.dart';
|
|
|
|
import 'package:cake_wallet/monero/monero.dart';
|
2021-07-16 09:32:36 +00:00
|
|
|
import 'package:cake_wallet/entities/calculate_fiat_amount.dart';
|
2021-12-24 12:37:24 +00:00
|
|
|
import 'package:cw_core/wallet_type.dart';
|
2021-07-16 09:32:36 +00:00
|
|
|
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
|
|
|
import 'package:cake_wallet/store/settings_store.dart';
|
|
|
|
import 'package:cake_wallet/generated/i18n.dart';
|
2021-12-24 12:37:24 +00:00
|
|
|
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
2021-07-16 09:32:36 +00:00
|
|
|
|
2023-08-01 12:00:00 +00:00
|
|
|
import 'package:cake_wallet/entities/contact_base.dart';
|
|
|
|
|
2021-08-10 14:52:35 +00:00
|
|
|
part 'output.g.dart';
|
2021-07-16 09:32:36 +00:00
|
|
|
|
|
|
|
const String cryptoNumberPattern = '0.0';
|
|
|
|
|
2021-08-10 14:52:35 +00:00
|
|
|
class Output = OutputBase with _$Output;
|
2021-07-16 09:32:36 +00:00
|
|
|
|
2021-08-10 14:52:35 +00:00
|
|
|
abstract class OutputBase with Store {
|
2023-12-02 02:26:43 +00:00
|
|
|
OutputBase(
|
|
|
|
this._wallet, this._settingsStore, this._fiatConversationStore, this.cryptoCurrencyHandler)
|
2022-10-12 17:09:57 +00:00
|
|
|
: _cryptoNumberFormat = NumberFormat(cryptoNumberPattern),
|
|
|
|
key = UniqueKey(),
|
|
|
|
sendAll = false,
|
|
|
|
cryptoAmount = '',
|
|
|
|
fiatAmount = '',
|
|
|
|
address = '',
|
|
|
|
note = '',
|
|
|
|
extractedAddress = '',
|
|
|
|
parsedAddress = ParsedAddress(addresses: []) {
|
2021-07-16 09:32:36 +00:00
|
|
|
_setCryptoNumMaximumFractionDigits();
|
|
|
|
}
|
|
|
|
|
|
|
|
Key key;
|
|
|
|
|
|
|
|
@observable
|
|
|
|
String fiatAmount;
|
|
|
|
|
|
|
|
@observable
|
|
|
|
String cryptoAmount;
|
|
|
|
|
|
|
|
@observable
|
|
|
|
String address;
|
|
|
|
|
|
|
|
@observable
|
|
|
|
String note;
|
|
|
|
|
|
|
|
@observable
|
|
|
|
bool sendAll;
|
|
|
|
|
2021-09-22 13:47:10 +00:00
|
|
|
@observable
|
2021-09-20 14:56:27 +00:00
|
|
|
ParsedAddress parsedAddress;
|
|
|
|
|
2021-09-22 13:47:10 +00:00
|
|
|
@observable
|
|
|
|
String extractedAddress;
|
|
|
|
|
2024-03-28 12:41:11 +00:00
|
|
|
String? memo;
|
|
|
|
|
2021-09-22 13:47:10 +00:00
|
|
|
@computed
|
2022-01-18 07:46:13 +00:00
|
|
|
bool get isParsedAddress =>
|
2023-12-02 02:26:43 +00:00
|
|
|
parsedAddress.parseFrom != ParseFrom.notParsed && parsedAddress.name.isNotEmpty;
|
2021-09-22 13:47:10 +00:00
|
|
|
|
2021-07-16 09:32:36 +00:00
|
|
|
@computed
|
2021-08-10 14:52:35 +00:00
|
|
|
int get formattedCryptoAmount {
|
|
|
|
int amount = 0;
|
2021-07-16 09:32:36 +00:00
|
|
|
|
|
|
|
try {
|
2023-08-01 12:00:00 +00:00
|
|
|
if (cryptoAmount.isNotEmpty) {
|
2021-07-16 09:32:36 +00:00
|
|
|
final _cryptoAmount = cryptoAmount.replaceAll(',', '.');
|
|
|
|
int _amount = 0;
|
|
|
|
switch (walletType) {
|
|
|
|
case WalletType.monero:
|
2022-10-12 17:09:57 +00:00
|
|
|
_amount = monero!.formatterMoneroParseAmount(amount: _cryptoAmount);
|
2021-07-16 09:32:36 +00:00
|
|
|
break;
|
|
|
|
case WalletType.bitcoin:
|
|
|
|
case WalletType.litecoin:
|
2023-10-12 22:50:16 +00:00
|
|
|
case WalletType.bitcoinCash:
|
2023-12-02 02:26:43 +00:00
|
|
|
_amount = bitcoin!.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
|
2021-07-16 09:32:36 +00:00
|
|
|
break;
|
2022-03-30 15:57:04 +00:00
|
|
|
case WalletType.haven:
|
2022-10-12 17:09:57 +00:00
|
|
|
_amount = haven!.formatterMoneroParseAmount(amount: _cryptoAmount);
|
2022-03-30 15:57:04 +00:00
|
|
|
break;
|
2023-08-04 17:01:49 +00:00
|
|
|
case WalletType.ethereum:
|
|
|
|
_amount = ethereum!.formatterEthereumParseAmount(_cryptoAmount);
|
|
|
|
break;
|
2023-12-02 02:26:43 +00:00
|
|
|
case WalletType.polygon:
|
|
|
|
_amount = polygon!.formatterPolygonParseAmount(_cryptoAmount);
|
|
|
|
break;
|
2021-07-16 09:32:36 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_amount > 0) {
|
|
|
|
amount = _amount;
|
|
|
|
}
|
|
|
|
}
|
2022-01-18 07:46:13 +00:00
|
|
|
} catch (e) {
|
2021-08-10 14:52:35 +00:00
|
|
|
amount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return amount;
|
|
|
|
}
|
2021-07-16 09:32:36 +00:00
|
|
|
|
2021-08-10 14:52:35 +00:00
|
|
|
@computed
|
|
|
|
double get estimatedFee {
|
|
|
|
try {
|
2024-03-29 18:55:29 +00:00
|
|
|
if (_wallet.type == WalletType.solana) {
|
|
|
|
return solana!.getEstimateFees(_wallet) ?? 0.0;
|
|
|
|
}
|
|
|
|
|
2024-04-08 14:54:58 +00:00
|
|
|
int? fee = _wallet.calculateEstimatedFee(
|
2022-10-12 17:09:57 +00:00
|
|
|
_settingsStore.priority[_wallet.type]!, formattedCryptoAmount);
|
2021-07-16 09:32:36 +00:00
|
|
|
|
2024-04-08 14:54:58 +00:00
|
|
|
if (_wallet.type == WalletType.bitcoin) {
|
|
|
|
if (_settingsStore.priority[_wallet.type] == bitcoin!.getBitcoinTransactionPriorityCustom()) {
|
|
|
|
fee = bitcoin!.getFeeAmountWithFeeRate(
|
|
|
|
_settingsStore.customBitcoinFeeRate, formattedCryptoAmount, 1, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return bitcoin!.formatterBitcoinAmountToDouble(amount: fee);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_wallet.type == WalletType.litecoin ||
|
2023-10-12 22:50:16 +00:00
|
|
|
_wallet.type == WalletType.bitcoinCash) {
|
2022-10-12 17:09:57 +00:00
|
|
|
return bitcoin!.formatterBitcoinAmountToDouble(amount: fee);
|
2021-07-16 09:32:36 +00:00
|
|
|
}
|
|
|
|
|
2021-12-24 12:37:24 +00:00
|
|
|
if (_wallet.type == WalletType.monero) {
|
2022-10-12 17:09:57 +00:00
|
|
|
return monero!.formatterMoneroAmountToDouble(amount: fee);
|
2021-07-16 09:32:36 +00:00
|
|
|
}
|
2022-03-30 15:57:04 +00:00
|
|
|
|
|
|
|
if (_wallet.type == WalletType.haven) {
|
2022-10-12 17:09:57 +00:00
|
|
|
return haven!.formatterMoneroAmountToDouble(amount: fee);
|
2022-03-30 15:57:04 +00:00
|
|
|
}
|
2023-08-04 17:01:49 +00:00
|
|
|
|
|
|
|
if (_wallet.type == WalletType.ethereum) {
|
|
|
|
return ethereum!.formatterEthereumAmountToDouble(amount: BigInt.from(fee));
|
|
|
|
}
|
2023-12-02 02:26:43 +00:00
|
|
|
|
|
|
|
if (_wallet.type == WalletType.polygon) {
|
|
|
|
return polygon!.formatterPolygonAmountToDouble(amount: BigInt.from(fee));
|
|
|
|
}
|
2021-07-16 09:32:36 +00:00
|
|
|
} catch (e) {
|
|
|
|
print(e.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@computed
|
|
|
|
String get estimatedFeeFiatAmount {
|
|
|
|
try {
|
CW-555-Add-Solana-Wallet (#1272)
* chore: Create cw_solana package and clean up files
* feat: Add Solana Wallet - Create, Restore form seed, restore from Key, Restore from QR, Send, Receive, transaction history, spl tokens
* fix: Make transactions file specific to solana only for solana transactions
* chore: Revert inject app details script
* fix: Fix issue with node and switch current node to main beta instead of testnet
* fix: Fix merge conflicts and adjust migration version
* fix: Fetch spl token error
Signed-off-by: Blazebrain <davidadegoke16@gmail.com>
* fix: Diplay and activate spl tokens bug
* fix: Review and fixes
* fix: reverted formatting for cryptocurrency class
* fix: Review comments, split sending flow into signing and sending separately, fix issues
* fix: Revert throwing unimplenented error
* chore: Fix comment
* chore: Fix comment
* fix: Errors in flow
* Update provider_types.dart [skip ci]
* fix: Issues with solana wallet
* Update solana_wallet.dart [skip ci]
* fix: Review comments
* fix: Date time config
* fix: Revert bash script for app details
* fix: Error with balance, displaying fees, fixing sent or received identifier bug, displaying token symbol with token transaction item in transactions list
* fix: Issues with address validation when sending spl tokens and walletconnect initial setup
* fix: Issues with sending, fetching transactions history, almost wrapping up walletconnect
* fix: Adjust imports that would affect monerocom building successfully
* fix: Refine transaction direction and continue work on walletconnect
* feat: Display SPL token transfers in the transaction history and finally settle the transaction direction
* fix: Delay in transactions history dispaly, show native token transactions first, then process spl token transactions
* feat: Switch node and revert solana chain id to previous id
* fix: Remove print statement
* fix: Remove await for transactions, fetch all transaction histories instantly and adjust solana send success message
* chore: Code refactoring and streamlined wallet type check for solana send success message
* fix: Make timeout error for node silent and add spl token images
---------
Signed-off-by: Blazebrain <davidadegoke16@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
2024-02-23 13:39:19 +00:00
|
|
|
final currency =
|
|
|
|
isEVMCompatibleChain(_wallet.type) ? _wallet.currency : cryptoCurrencyHandler();
|
2021-07-16 09:32:36 +00:00
|
|
|
final fiat = calculateFiatAmountRaw(
|
2023-12-02 02:26:43 +00:00
|
|
|
price: _fiatConversationStore.prices[currency]!, cryptoAmount: estimatedFee);
|
2021-07-16 09:32:36 +00:00
|
|
|
return fiat;
|
|
|
|
} catch (_) {
|
|
|
|
return '0.00';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WalletType get walletType => _wallet.type;
|
2022-03-30 15:57:04 +00:00
|
|
|
final CryptoCurrency Function() cryptoCurrencyHandler;
|
2021-07-16 09:32:36 +00:00
|
|
|
final WalletBase _wallet;
|
|
|
|
final SettingsStore _settingsStore;
|
|
|
|
final FiatConversionStore _fiatConversationStore;
|
|
|
|
final NumberFormat _cryptoNumberFormat;
|
|
|
|
|
|
|
|
@action
|
|
|
|
void setSendAll() => sendAll = true;
|
|
|
|
|
|
|
|
@action
|
|
|
|
void reset() {
|
|
|
|
sendAll = false;
|
|
|
|
cryptoAmount = '';
|
|
|
|
fiatAmount = '';
|
|
|
|
address = '';
|
|
|
|
note = '';
|
2024-03-28 12:41:11 +00:00
|
|
|
memo = null;
|
2021-09-20 14:56:27 +00:00
|
|
|
resetParsedAddress();
|
|
|
|
}
|
|
|
|
|
|
|
|
void resetParsedAddress() {
|
2021-09-22 13:47:10 +00:00
|
|
|
extractedAddress = '';
|
2021-09-20 14:56:27 +00:00
|
|
|
parsedAddress = ParsedAddress(addresses: []);
|
2021-07-16 09:32:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
|
|
|
void setCryptoAmount(String amount) {
|
|
|
|
if (amount.toUpperCase() != S.current.all) {
|
|
|
|
sendAll = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
cryptoAmount = amount;
|
|
|
|
_updateFiatAmount();
|
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
|
|
|
void setFiatAmount(String amount) {
|
|
|
|
fiatAmount = amount;
|
|
|
|
_updateCryptoAmount();
|
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
|
|
|
void _updateFiatAmount() {
|
|
|
|
try {
|
|
|
|
final fiat = calculateFiatAmount(
|
2022-10-12 17:09:57 +00:00
|
|
|
price: _fiatConversationStore.prices[cryptoCurrencyHandler()]!,
|
2021-07-16 09:32:36 +00:00
|
|
|
cryptoAmount: cryptoAmount.replaceAll(',', '.'));
|
|
|
|
if (fiatAmount != fiat) {
|
|
|
|
fiatAmount = fiat;
|
|
|
|
}
|
|
|
|
} catch (_) {
|
|
|
|
fiatAmount = '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
|
|
|
void _updateCryptoAmount() {
|
|
|
|
try {
|
|
|
|
final crypto = double.parse(fiatAmount.replaceAll(',', '.')) /
|
2022-10-12 17:09:57 +00:00
|
|
|
_fiatConversationStore.prices[cryptoCurrencyHandler()]!;
|
2021-07-16 09:32:36 +00:00
|
|
|
final cryptoAmountTmp = _cryptoNumberFormat.format(crypto);
|
|
|
|
if (cryptoAmount != cryptoAmountTmp) {
|
|
|
|
cryptoAmount = cryptoAmountTmp;
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
cryptoAmount = '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void _setCryptoNumMaximumFractionDigits() {
|
|
|
|
var maximumFractionDigits = 0;
|
|
|
|
|
|
|
|
switch (_wallet.type) {
|
|
|
|
case WalletType.monero:
|
|
|
|
maximumFractionDigits = 12;
|
|
|
|
break;
|
|
|
|
case WalletType.bitcoin:
|
|
|
|
maximumFractionDigits = 8;
|
|
|
|
break;
|
|
|
|
case WalletType.litecoin:
|
|
|
|
maximumFractionDigits = 8;
|
|
|
|
break;
|
2023-10-12 22:50:16 +00:00
|
|
|
case WalletType.bitcoinCash:
|
|
|
|
maximumFractionDigits = 8;
|
|
|
|
break;
|
2022-03-30 15:57:04 +00:00
|
|
|
case WalletType.haven:
|
|
|
|
maximumFractionDigits = 12;
|
|
|
|
break;
|
2023-08-04 17:01:49 +00:00
|
|
|
case WalletType.ethereum:
|
2023-12-02 02:26:43 +00:00
|
|
|
case WalletType.polygon:
|
2023-08-04 17:01:49 +00:00
|
|
|
maximumFractionDigits = 12;
|
|
|
|
break;
|
CW-555-Add-Solana-Wallet (#1272)
* chore: Create cw_solana package and clean up files
* feat: Add Solana Wallet - Create, Restore form seed, restore from Key, Restore from QR, Send, Receive, transaction history, spl tokens
* fix: Make transactions file specific to solana only for solana transactions
* chore: Revert inject app details script
* fix: Fix issue with node and switch current node to main beta instead of testnet
* fix: Fix merge conflicts and adjust migration version
* fix: Fetch spl token error
Signed-off-by: Blazebrain <davidadegoke16@gmail.com>
* fix: Diplay and activate spl tokens bug
* fix: Review and fixes
* fix: reverted formatting for cryptocurrency class
* fix: Review comments, split sending flow into signing and sending separately, fix issues
* fix: Revert throwing unimplenented error
* chore: Fix comment
* chore: Fix comment
* fix: Errors in flow
* Update provider_types.dart [skip ci]
* fix: Issues with solana wallet
* Update solana_wallet.dart [skip ci]
* fix: Review comments
* fix: Date time config
* fix: Revert bash script for app details
* fix: Error with balance, displaying fees, fixing sent or received identifier bug, displaying token symbol with token transaction item in transactions list
* fix: Issues with address validation when sending spl tokens and walletconnect initial setup
* fix: Issues with sending, fetching transactions history, almost wrapping up walletconnect
* fix: Adjust imports that would affect monerocom building successfully
* fix: Refine transaction direction and continue work on walletconnect
* feat: Display SPL token transfers in the transaction history and finally settle the transaction direction
* fix: Delay in transactions history dispaly, show native token transactions first, then process spl token transactions
* feat: Switch node and revert solana chain id to previous id
* fix: Remove print statement
* fix: Remove await for transactions, fetch all transaction histories instantly and adjust solana send success message
* chore: Code refactoring and streamlined wallet type check for solana send success message
* fix: Make timeout error for node silent and add spl token images
---------
Signed-off-by: Blazebrain <davidadegoke16@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
2024-02-23 13:39:19 +00:00
|
|
|
case WalletType.solana:
|
|
|
|
maximumFractionDigits = 12;
|
|
|
|
break;
|
2021-07-16 09:32:36 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
_cryptoNumberFormat.maximumFractionDigits = maximumFractionDigits;
|
|
|
|
}
|
|
|
|
|
2021-09-20 14:56:27 +00:00
|
|
|
Future<void> fetchParsedAddress(BuildContext context) async {
|
2021-07-22 16:48:26 +00:00
|
|
|
final domain = address;
|
2022-03-30 15:57:04 +00:00
|
|
|
final ticker = cryptoCurrencyHandler().title.toLowerCase();
|
2024-01-27 02:34:38 +00:00
|
|
|
parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, ticker);
|
2021-09-29 11:38:31 +00:00
|
|
|
extractedAddress = await extractAddressFromParsed(context, parsedAddress);
|
2022-01-18 07:46:13 +00:00
|
|
|
note = parsedAddress.description;
|
2021-07-16 09:32:36 +00:00
|
|
|
}
|
2023-08-01 12:00:00 +00:00
|
|
|
|
|
|
|
void loadContact(ContactBase contact) {
|
|
|
|
address = contact.name;
|
|
|
|
parsedAddress = ParsedAddress.fetchContactAddress(address: contact.address, name: contact.name);
|
|
|
|
extractedAddress = parsedAddress.addresses.first;
|
|
|
|
note = parsedAddress.description;
|
|
|
|
}
|
2022-01-18 07:46:13 +00:00
|
|
|
}
|