mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 20:39:51 +00:00
Merge branch 'main' of https://github.com/cake-tech/cake_wallet into v5.1.0-rc
This commit is contained in:
commit
b91dccaacb
14 changed files with 239 additions and 78 deletions
BIN
assets/images/usdtbsc_icon.png
Normal file
BIN
assets/images/usdtbsc_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 920 B |
|
@ -67,6 +67,8 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
|
||||||
payjoinManager.resumeSessions();
|
payjoinManager.resumeSessions();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
printV(e);
|
printV(e);
|
||||||
|
// Ignore Connectivity errors
|
||||||
|
if (!e.toString().contains("error sending request for url")) rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +81,8 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
|
||||||
payjoinManager.spawnReceiver(receiver: currentPayjoinReceiver!);
|
payjoinManager.spawnReceiver(receiver: currentPayjoinReceiver!);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
printV(e);
|
printV(e);
|
||||||
|
// Ignore Connectivity errors
|
||||||
|
if (!e.toString().contains("error sending request for url")) rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,8 +106,8 @@ class PayjoinSenderWorker {
|
||||||
sendPort.send({'type': PayjoinSenderRequestTypes.requestPosted});
|
sendPort.send({'type': PayjoinSenderRequestTypes.requestPosted});
|
||||||
|
|
||||||
return await postRequest.$2.processResponse(response: response);
|
return await postRequest.$2.processResponse(response: response);
|
||||||
} catch (e) {
|
} catch (e, stack) {
|
||||||
throw PayjoinSessionError.unrecoverable('Send V1 payjoin error: $e');
|
throw PayjoinSessionError.unrecoverable('Send V1 payjoin error: $e, $stack');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
|
||||||
CryptoCurrency.zano,
|
CryptoCurrency.zano,
|
||||||
CryptoCurrency.ton,
|
CryptoCurrency.ton,
|
||||||
CryptoCurrency.flip,
|
CryptoCurrency.flip,
|
||||||
CryptoCurrency.deuro
|
CryptoCurrency.deuro,
|
||||||
|
CryptoCurrency.usdtbsc,
|
||||||
];
|
];
|
||||||
|
|
||||||
static const havenCurrencies = [
|
static const havenCurrencies = [
|
||||||
|
@ -233,6 +234,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
|
||||||
static const zano = CryptoCurrency(title: 'ZANO', tag: 'ZANO', fullName: 'Zano', raw: 96, name: 'zano', iconPath: 'assets/images/zano_icon.png', decimals: 12);
|
static const zano = CryptoCurrency(title: 'ZANO', tag: 'ZANO', fullName: 'Zano', raw: 96, name: 'zano', iconPath: 'assets/images/zano_icon.png', decimals: 12);
|
||||||
static const flip = CryptoCurrency(title: 'FLIP', tag: 'ETH', fullName: 'Chainflip', raw: 97, name: 'flip', iconPath: 'assets/images/flip_icon.png', decimals: 18);
|
static const flip = CryptoCurrency(title: 'FLIP', tag: 'ETH', fullName: 'Chainflip', raw: 97, name: 'flip', iconPath: 'assets/images/flip_icon.png', decimals: 18);
|
||||||
static const deuro = CryptoCurrency(title: 'DEURO', tag: 'ETH', fullName: 'Decentralized Euro', raw: 98, name: 'deuro', iconPath: 'assets/images/deuro_icon.png', decimals: 18);
|
static const deuro = CryptoCurrency(title: 'DEURO', tag: 'ETH', fullName: 'Decentralized Euro', raw: 98, name: 'deuro', iconPath: 'assets/images/deuro_icon.png', decimals: 18);
|
||||||
|
static const usdtbsc = CryptoCurrency(title: 'USDT', tag: 'BSC', fullName: 'USDT Binance coin', raw: 99, name: 'usdtbsc', iconPath: 'assets/images/usdtbsc_icon.png', decimals: 18);
|
||||||
|
|
||||||
static final Map<int, CryptoCurrency> _rawCurrencyMap =
|
static final Map<int, CryptoCurrency> _rawCurrencyMap =
|
||||||
[...all, ...havenCurrencies].fold<Map<int, CryptoCurrency>>(<int, CryptoCurrency>{}, (acc, item) {
|
[...all, ...havenCurrencies].fold<Map<int, CryptoCurrency>>(<int, CryptoCurrency>{}, (acc, item) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_ethereum/deuro/deuro_savings_contract.dart';
|
import 'package:cw_ethereum/deuro/deuro_savings_contract.dart';
|
||||||
import 'package:cw_ethereum/ethereum_wallet.dart';
|
import 'package:cw_ethereum/ethereum_wallet.dart';
|
||||||
import 'package:cw_evm/contract/erc20.dart';
|
import 'package:cw_evm/contract/erc20.dart';
|
||||||
|
import 'package:cw_evm/evm_chain_exceptions.dart';
|
||||||
import 'package:cw_evm/evm_chain_transaction_priority.dart';
|
import 'package:cw_evm/evm_chain_transaction_priority.dart';
|
||||||
import 'package:cw_evm/pending_evm_chain_transaction.dart';
|
import 'package:cw_evm/pending_evm_chain_transaction.dart';
|
||||||
import 'package:web3dart/crypto.dart';
|
import 'package:web3dart/crypto.dart';
|
||||||
|
@ -43,59 +44,111 @@ class DEuro {
|
||||||
|
|
||||||
Future<BigInt> get approvedBalance => _dEuro.allowance(_address, _savingsGateway.self.address);
|
Future<BigInt> get approvedBalance => _dEuro.allowance(_address, _savingsGateway.self.address);
|
||||||
|
|
||||||
Future<PendingEVMChainTransaction> depositSavings(
|
Future<void> _checkEthBalanceForGasFees(EVMChainTransactionPriority priority) async {
|
||||||
BigInt amount, EVMChainTransactionPriority priority) async {
|
final ethBalance = await _wallet.getWeb3Client()!.getBalance(_address);
|
||||||
final signedTransaction = await _savingsGateway.save(
|
final currentBalance = ethBalance.getInWei;
|
||||||
(amount: amount, frontendCode: hexToBytes(frontendCode)),
|
|
||||||
credentials: _wallet.evmChainPrivateKey,
|
|
||||||
);
|
|
||||||
|
|
||||||
final fee = await _wallet.calculateActualEstimatedFeeForCreateTransaction(
|
final gasFeesModel = await _wallet.calculateActualEstimatedFeeForCreateTransaction(
|
||||||
amount: amount,
|
amount: BigInt.zero,
|
||||||
contractAddress: _savingsGateway.self.address.hexEip55,
|
contractAddress: _savingsGateway.self.address.hexEip55,
|
||||||
receivingAddressHex: _savingsGateway.self.address.hexEip55,
|
receivingAddressHex: _savingsGateway.self.address.hexEip55,
|
||||||
priority: priority,
|
priority: priority,
|
||||||
data: _savingsGateway.self.abi.functions[17].encodeCall([amount, hexToBytes(frontendCode)]),
|
data: _savingsGateway.self.abi.functions[17]
|
||||||
|
.encodeCall([BigInt.zero, hexToBytes(frontendCode)]),
|
||||||
);
|
);
|
||||||
|
|
||||||
final sendTransaction = () => _wallet.getWeb3Client()!.sendRawTransaction(signedTransaction);
|
final estimatedGasFee = BigInt.from(gasFeesModel.estimatedGasFee);
|
||||||
|
final requiredBalance = estimatedGasFee;
|
||||||
|
|
||||||
return PendingEVMChainTransaction(
|
if (currentBalance < requiredBalance) {
|
||||||
|
throw DeuroGasFeeException(
|
||||||
|
requiredGasFee: requiredBalance,
|
||||||
|
currentBalance: currentBalance,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<PendingEVMChainTransaction> depositSavings(
|
||||||
|
BigInt amount, EVMChainTransactionPriority priority) async {
|
||||||
|
try {
|
||||||
|
await _checkEthBalanceForGasFees(priority);
|
||||||
|
|
||||||
|
final signedTransaction = await _savingsGateway.save(
|
||||||
|
(amount: amount, frontendCode: hexToBytes(frontendCode)),
|
||||||
|
credentials: _wallet.evmChainPrivateKey,
|
||||||
|
);
|
||||||
|
|
||||||
|
final fee = await _wallet.calculateActualEstimatedFeeForCreateTransaction(
|
||||||
|
amount: amount,
|
||||||
|
contractAddress: _savingsGateway.self.address.hexEip55,
|
||||||
|
receivingAddressHex: _savingsGateway.self.address.hexEip55,
|
||||||
|
priority: priority,
|
||||||
|
data: _savingsGateway.self.abi.functions[17].encodeCall([amount, hexToBytes(frontendCode)]),
|
||||||
|
);
|
||||||
|
|
||||||
|
final sendTransaction = () => _wallet.getWeb3Client()!.sendRawTransaction(signedTransaction);
|
||||||
|
|
||||||
|
return PendingEVMChainTransaction(
|
||||||
sendTransaction: sendTransaction,
|
sendTransaction: sendTransaction,
|
||||||
signedTransaction: signedTransaction,
|
signedTransaction: signedTransaction,
|
||||||
fee: BigInt.from(fee.estimatedGasFee),
|
fee: BigInt.from(fee.estimatedGasFee),
|
||||||
amount: amount.toString(),
|
amount: amount.toString(),
|
||||||
exponent: 18);
|
exponent: 18,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
if (e.toString().contains('insufficient funds for gas')) {
|
||||||
|
final ethBalance = await _wallet.getWeb3Client()!.getBalance(_address);
|
||||||
|
throw DeuroGasFeeException(
|
||||||
|
currentBalance: ethBalance.getInWei,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<PendingEVMChainTransaction> withdrawSavings(
|
Future<PendingEVMChainTransaction> withdrawSavings(
|
||||||
BigInt amount, EVMChainTransactionPriority priority) async {
|
BigInt amount, EVMChainTransactionPriority priority) async {
|
||||||
final signedTransaction = await _savingsGateway.withdraw(
|
try {
|
||||||
(target: _address, amount: amount, frontendCode: hexToBytes(frontendCode)),
|
await _checkEthBalanceForGasFees(priority);
|
||||||
credentials: _wallet.evmChainPrivateKey,
|
|
||||||
);
|
|
||||||
|
|
||||||
final fee = await _wallet.calculateActualEstimatedFeeForCreateTransaction(
|
final signedTransaction = await _savingsGateway.withdraw(
|
||||||
amount: amount,
|
(target: _address, amount: amount, frontendCode: hexToBytes(frontendCode)),
|
||||||
contractAddress: _savingsGateway.self.address.hexEip55,
|
credentials: _wallet.evmChainPrivateKey,
|
||||||
receivingAddressHex: _savingsGateway.self.address.hexEip55,
|
);
|
||||||
priority: priority,
|
|
||||||
data: _savingsGateway.self.abi.functions[17].encodeCall([amount, hexToBytes(frontendCode)]),
|
|
||||||
);
|
|
||||||
|
|
||||||
final sendTransaction = () => _wallet.getWeb3Client()!.sendRawTransaction(signedTransaction);
|
final fee = await _wallet.calculateActualEstimatedFeeForCreateTransaction(
|
||||||
|
amount: amount,
|
||||||
|
contractAddress: _savingsGateway.self.address.hexEip55,
|
||||||
|
receivingAddressHex: _savingsGateway.self.address.hexEip55,
|
||||||
|
priority: priority,
|
||||||
|
data: _savingsGateway.self.abi.functions[17].encodeCall([amount, hexToBytes(frontendCode)]),
|
||||||
|
);
|
||||||
|
|
||||||
return PendingEVMChainTransaction(
|
final sendTransaction = () => _wallet.getWeb3Client()!.sendRawTransaction(signedTransaction);
|
||||||
sendTransaction: sendTransaction,
|
|
||||||
signedTransaction: signedTransaction,
|
return PendingEVMChainTransaction(
|
||||||
fee: BigInt.from(fee.estimatedGasFee),
|
sendTransaction: sendTransaction,
|
||||||
amount: amount.toString(),
|
signedTransaction: signedTransaction,
|
||||||
exponent: 18);
|
fee: BigInt.from(fee.estimatedGasFee),
|
||||||
|
amount: amount.toString(),
|
||||||
|
exponent: 18);
|
||||||
|
} catch (e) {
|
||||||
|
if (e.toString().contains('insufficient funds for gas')) {
|
||||||
|
final ethBalance = await _wallet.getWeb3Client()!.getBalance(_address);
|
||||||
|
throw DeuroGasFeeException(
|
||||||
|
currentBalance: ethBalance.getInWei,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set an infinite approval to save gas in the future
|
// Set an infinite approval to save gas in the future
|
||||||
Future<PendingEVMChainTransaction> enableSavings(EVMChainTransactionPriority priority) async =>
|
Future<PendingEVMChainTransaction> enableSavings(EVMChainTransactionPriority priority) async {
|
||||||
(await _wallet.createApprovalTransaction(
|
try {
|
||||||
|
await _checkEthBalanceForGasFees(priority);
|
||||||
|
|
||||||
|
return (await _wallet.createApprovalTransaction(
|
||||||
BigInt.parse(
|
BigInt.parse(
|
||||||
'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
|
'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
|
||||||
radix: 16,
|
radix: 16,
|
||||||
|
@ -104,4 +157,14 @@ class DEuro {
|
||||||
CryptoCurrency.deuro,
|
CryptoCurrency.deuro,
|
||||||
priority,
|
priority,
|
||||||
)) as PendingEVMChainTransaction;
|
)) as PendingEVMChainTransaction;
|
||||||
|
} catch (e) {
|
||||||
|
if (e.toString().contains('insufficient funds for gas')) {
|
||||||
|
final ethBalance = await _wallet.getWeb3Client()!.getBalance(_address);
|
||||||
|
throw DeuroGasFeeException(
|
||||||
|
currentBalance: ethBalance.getInWei,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,3 +22,32 @@ class EVMChainTransactionFeesException implements Exception {
|
||||||
@override
|
@override
|
||||||
String toString() => exceptionMessage;
|
String toString() => exceptionMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DeuroGasFeeException implements Exception {
|
||||||
|
final String exceptionMessage;
|
||||||
|
final BigInt? requiredGasFee;
|
||||||
|
final BigInt? currentBalance;
|
||||||
|
|
||||||
|
DeuroGasFeeException({
|
||||||
|
this.requiredGasFee,
|
||||||
|
this.currentBalance,
|
||||||
|
}) : exceptionMessage = _buildMessage(requiredGasFee, currentBalance);
|
||||||
|
|
||||||
|
static String _buildMessage(BigInt? requiredGasFee, BigInt? currentBalance) {
|
||||||
|
const baseMessage = 'Insufficient ETH for gas fees.';
|
||||||
|
const addEthMessage = ' Please add ETH to your wallet to cover transaction fees.';
|
||||||
|
|
||||||
|
if (requiredGasFee != null) {
|
||||||
|
final requiredEth = (requiredGasFee / BigInt.from(10).pow(18)).toStringAsFixed(8);
|
||||||
|
final balanceInfo = currentBalance != null
|
||||||
|
? ', Available: ${(currentBalance / BigInt.from(10).pow(18)).toStringAsFixed(8)} ETH'
|
||||||
|
: '';
|
||||||
|
return '$baseMessage Required: ~$requiredEth ETH$balanceInfo.$addEthMessage';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '$baseMessage$addEthMessage';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => exceptionMessage;
|
||||||
|
}
|
||||||
|
|
|
@ -116,12 +116,17 @@ String getSeedLegacy(String? language) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String getPassphrase() {
|
String getPassphrase() {
|
||||||
return currentWallet!.getCacheAttribute(key: "cakewallet.passphrase");
|
return currentWallet?.getCacheAttribute(key: "cakewallet.passphrase") ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<int, Map<int, Map<int, String>>> addressCache = {};
|
Map<int, Map<int, Map<int, String>>> addressCache = {};
|
||||||
|
|
||||||
String getAddress({int accountIndex = 0, int addressIndex = 0}) {
|
String getAddress({int accountIndex = 0, int addressIndex = 0}) {
|
||||||
|
// this is a workaround for when we switch the wallet pointer,
|
||||||
|
// it should never reach UI but should be good enough to prevent gray screen
|
||||||
|
// or other errors because of forced null check.
|
||||||
|
if (currentWallet == null) return "<wallet not ready ($accountIndex:$addressIndex)>";
|
||||||
|
|
||||||
// printV("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}");
|
// printV("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}");
|
||||||
// this could be a while loop, but I'm in favor of making it if to not cause freezes
|
// this could be a while loop, but I'm in favor of making it if to not cause freezes
|
||||||
if (currentWallet!.numSubaddresses(accountIndex: accountIndex)-1 < addressIndex) {
|
if (currentWallet!.numSubaddresses(accountIndex: accountIndex)-1 < addressIndex) {
|
||||||
|
@ -272,13 +277,13 @@ void closeCurrentWallet() {
|
||||||
currentWallet!.stop();
|
currentWallet!.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getSecretViewKey() => currentWallet!.secretViewKey();
|
String getSecretViewKey() => currentWallet?.secretViewKey() ?? "";
|
||||||
|
|
||||||
String getPublicViewKey() => currentWallet!.publicViewKey();
|
String getPublicViewKey() => currentWallet?.publicViewKey() ?? "";
|
||||||
|
|
||||||
String getSecretSpendKey() => currentWallet!.secretSpendKey();
|
String getSecretSpendKey() => currentWallet?.secretSpendKey() ?? "";
|
||||||
|
|
||||||
String getPublicSpendKey() => currentWallet!.publicSpendKey();
|
String getPublicSpendKey() => currentWallet?.publicSpendKey() ?? "";
|
||||||
|
|
||||||
class SyncListener {
|
class SyncListener {
|
||||||
SyncListener(this.onNewBlock, this.onNewTransaction)
|
SyncListener(this.onNewBlock, this.onNewTransaction)
|
||||||
|
|
|
@ -5,8 +5,7 @@ import 'dart:convert';
|
||||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||||
|
|
||||||
const _fiatApiClearNetAuthority = 'fiat-api.cakewallet.com';
|
const _fiatApiClearNetAuthority = 'fiat-api.cakewallet.com';
|
||||||
// const _fiatApiOnionAuthority = 'n4z7bdcmwk2oyddxvzaap3x2peqcplh3pzdy7tpkk5ejz5n4mhfvoxqd.onion';
|
const _fiatApiOnionAuthority = 'kfkyguqtz5vcnbvar5pjgddkaeawbo4j3r4fj3e22k3tzqageplosiid.onion';
|
||||||
const _fiatApiOnionAuthority = _fiatApiClearNetAuthority;
|
|
||||||
const _fiatApiPath = '/v2/rates';
|
const _fiatApiPath = '/v2/rates';
|
||||||
|
|
||||||
Future<double> _fetchPrice(String crypto, String fiat, bool torOnly) async {
|
Future<double> _fetchPrice(String crypto, String fiat, bool torOnly) async {
|
||||||
|
|
|
@ -23,6 +23,7 @@ class ThorChainExchangeProvider extends ExchangeProvider {
|
||||||
// CryptoCurrency.eth,
|
// CryptoCurrency.eth,
|
||||||
CryptoCurrency.ltc,
|
CryptoCurrency.ltc,
|
||||||
CryptoCurrency.bch,
|
CryptoCurrency.bch,
|
||||||
|
CryptoCurrency.usdtbsc,
|
||||||
// CryptoCurrency.aave,
|
// CryptoCurrency.aave,
|
||||||
// CryptoCurrency.dai,
|
// CryptoCurrency.dai,
|
||||||
// CryptoCurrency.gusd,
|
// CryptoCurrency.gusd,
|
||||||
|
@ -259,7 +260,7 @@ class ThorChainExchangeProvider extends ExchangeProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
String _normalizeCurrency(CryptoCurrency currency) {
|
String _normalizeCurrency(CryptoCurrency currency) {
|
||||||
final networkTitle = currency.tag == 'ETH' ? 'ETH' : currency.title;
|
final networkTitle = currency.tag == 'ETH' ? 'ETH' : currency.tag ?? currency.title;
|
||||||
return '$networkTitle.${currency.title}';
|
return '$networkTitle.${currency.title}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -348,6 +348,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
||||||
return 'TRC20';
|
return 'TRC20';
|
||||||
case 'LN':
|
case 'LN':
|
||||||
return 'Lightning';
|
return 'Lightning';
|
||||||
|
case 'BSC':
|
||||||
|
return 'BEP20';
|
||||||
default:
|
default:
|
||||||
return tag.toLowerCase();
|
return tag.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,11 @@ import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/interest_card_widget.dart';
|
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/interest_card_widget.dart';
|
||||||
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/savings_card_widget.dart';
|
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/savings_card_widget.dart';
|
||||||
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/savings_edit_sheet.dart';
|
import 'package:cake_wallet/src/screens/integrations/deuro/widgets/savings_edit_sheet.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||||
import 'package:cake_wallet/src/widgets/bottom_sheet/confirm_sending_bottom_sheet_widget.dart';
|
import 'package:cake_wallet/src/widgets/bottom_sheet/confirm_sending_bottom_sheet_widget.dart';
|
||||||
import 'package:cake_wallet/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart';
|
import 'package:cake_wallet/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart';
|
||||||
import 'package:cake_wallet/src/widgets/gradient_background.dart';
|
import 'package:cake_wallet/src/widgets/gradient_background.dart';
|
||||||
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
import 'package:cake_wallet/view_model/integrations/deuro_view_model.dart';
|
import 'package:cake_wallet/view_model/integrations/deuro_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
|
import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
@ -190,6 +192,24 @@ class DEuroSavingsPage extends BasePage {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state is FailureState) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
if (!context.mounted) return;
|
||||||
|
|
||||||
|
await showPopUp<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext popupContext) {
|
||||||
|
return AlertWithOneAction(
|
||||||
|
alertTitle: S.of(popupContext).error,
|
||||||
|
alertContent: state.error,
|
||||||
|
buttonText: S.of(popupContext).ok,
|
||||||
|
buttonAction: () => Navigator.of(popupContext).pop(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_isReactionsSet = true;
|
_isReactionsSet = true;
|
||||||
|
|
|
@ -1123,13 +1123,18 @@ abstract class DashboardViewModelBase with Store {
|
||||||
Future<ServicesResponse> _getServicesStatus() async {
|
Future<ServicesResponse> _getServicesStatus() async {
|
||||||
try {
|
try {
|
||||||
if (isEnabledBulletinAction) {
|
if (isEnabledBulletinAction) {
|
||||||
final uri = Uri.https(
|
final res = await ProxyWrapper().get(
|
||||||
"service-api.cakewallet.com",
|
clearnetUri: Uri.https(
|
||||||
"/v1/active-notices",
|
"service-api.cakewallet.com",
|
||||||
{'key': secrets.fiatApiKey},
|
"/v1/active-notices",
|
||||||
|
{'key': secrets.fiatApiKey},
|
||||||
|
),
|
||||||
|
onionUri: Uri.http(
|
||||||
|
"jpirgl4lrwzjgdqj2nsv3g7twhp2efzty5d3cnypktyczzqfc5qcwwyd.onion",
|
||||||
|
"/v1/active-notices",
|
||||||
|
{'key': secrets.fiatApiKey},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final res = await ProxyWrapper().get(clearnetUri: uri);
|
|
||||||
if (res.statusCode < 200 || res.statusCode >= 300) {
|
if (res.statusCode < 200 || res.statusCode >= 300) {
|
||||||
throw res.body;
|
throw res.body;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,10 +46,8 @@ abstract class DEuroViewModelBase with Store {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> reloadSavingsUserData() async {
|
Future<void> reloadSavingsUserData() async {
|
||||||
final savingsBalanceRaw =
|
final savingsBalanceRaw = ethereum!.getDEuroSavingsBalance(_appStore.wallet!);
|
||||||
ethereum!.getDEuroSavingsBalance(_appStore.wallet!);
|
final accruedInterestRaw = ethereum!.getDEuroAccruedInterest(_appStore.wallet!);
|
||||||
final accruedInterestRaw =
|
|
||||||
ethereum!.getDEuroAccruedInterest(_appStore.wallet!);
|
|
||||||
|
|
||||||
approvedTokens = await ethereum!.getDEuroSavingsApproved(_appStore.wallet!);
|
approvedTokens = await ethereum!.getDEuroSavingsApproved(_appStore.wallet!);
|
||||||
|
|
||||||
|
@ -63,56 +61,73 @@ abstract class DEuroViewModelBase with Store {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> reloadInterestRate() async {
|
Future<void> reloadInterestRate() async {
|
||||||
final interestRateRaw =
|
final interestRateRaw = await ethereum!.getDEuroInterestRate(_appStore.wallet!);
|
||||||
await ethereum!.getDEuroInterestRate(_appStore.wallet!);
|
|
||||||
|
|
||||||
interestRate = (interestRateRaw / BigInt.from(10000)).toString();
|
interestRate = (interestRateRaw / BigInt.from(10000)).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> prepareApproval() async {
|
Future<void> prepareApproval() async {
|
||||||
final priority = _appStore.settingsStore.priority[WalletType.ethereum]!;
|
try {
|
||||||
approvalTransaction =
|
state = TransactionCommitting();
|
||||||
await ethereum!.enableDEuroSaving(_appStore.wallet!, priority);
|
final priority = _appStore.settingsStore.priority[WalletType.ethereum]!;
|
||||||
|
approvalTransaction = await ethereum!.enableDEuroSaving(_appStore.wallet!, priority);
|
||||||
|
state = InitialExecutionState();
|
||||||
|
} catch (e) {
|
||||||
|
state = FailureState(e.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> prepareSavingsEdit(String amountRaw, bool isAdding) async {
|
Future<void> prepareSavingsEdit(String amountRaw, bool isAdding) async {
|
||||||
final amount = BigInt.from(num.parse(amountRaw) * pow(10, 18));
|
try {
|
||||||
final priority = _appStore.settingsStore.priority[WalletType.ethereum]!;
|
state = TransactionCommitting();
|
||||||
transaction = await (isAdding
|
final amount = BigInt.from(num.parse(amountRaw) * pow(10, 18));
|
||||||
? ethereum!.addDEuroSaving(_appStore.wallet!, amount, priority)
|
final priority = _appStore.settingsStore.priority[WalletType.ethereum]!;
|
||||||
: ethereum!.removeDEuroSaving(_appStore.wallet!, amount, priority));
|
transaction = await (isAdding
|
||||||
|
? ethereum!.addDEuroSaving(_appStore.wallet!, amount, priority)
|
||||||
|
: ethereum!.removeDEuroSaving(_appStore.wallet!, amount, priority));
|
||||||
|
state = InitialExecutionState();
|
||||||
|
} catch (e) {
|
||||||
|
state = FailureState(e.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> prepareCollectInterest() =>
|
Future<void> prepareCollectInterest() => prepareSavingsEdit(accruedInterest, false);
|
||||||
prepareSavingsEdit(accruedInterest, false);
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> commitTransaction() async {
|
Future<void> commitTransaction() async {
|
||||||
if (transaction != null) {
|
if (transaction != null) {
|
||||||
state = TransactionCommitting();
|
try {
|
||||||
await transaction!.commit();
|
state = TransactionCommitting();
|
||||||
transaction = null;
|
await transaction!.commit();
|
||||||
reloadSavingsUserData();
|
transaction = null;
|
||||||
state = TransactionCommitted();
|
reloadSavingsUserData();
|
||||||
|
state = TransactionCommitted();
|
||||||
|
} catch (e) {
|
||||||
|
state = FailureState(e.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> commitApprovalTransaction() async {
|
Future<void> commitApprovalTransaction() async {
|
||||||
if (approvalTransaction != null) {
|
if (approvalTransaction != null) {
|
||||||
state = TransactionCommitting();
|
try {
|
||||||
await approvalTransaction!.commit();
|
state = TransactionCommitting();
|
||||||
approvalTransaction = null;
|
await approvalTransaction!.commit();
|
||||||
reloadSavingsUserData();
|
approvalTransaction = null;
|
||||||
state = TransactionCommitted();
|
reloadSavingsUserData();
|
||||||
|
state = TransactionCommitted();
|
||||||
|
} catch (e) {
|
||||||
|
state = FailureState(e.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void dismissTransaction() {
|
void dismissTransaction() {
|
||||||
transaction == null;
|
transaction = null;
|
||||||
approvalTransaction = null;
|
approvalTransaction = null;
|
||||||
state = InitialExecutionState();
|
state = InitialExecutionState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,9 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/src/screens/trade_details/trade_details_list_card.dart';
|
import 'package:cake_wallet/src/screens/trade_details/trade_details_list_card.dart';
|
||||||
import 'package:cake_wallet/src/screens/trade_details/trade_details_status_item.dart';
|
import 'package:cake_wallet/src/screens/trade_details/trade_details_status_item.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/transaction_details/blockexplorer_list_item.dart';
|
||||||
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
|
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
|
||||||
import 'package:cake_wallet/themes/core/theme_store.dart';
|
import 'package:cake_wallet/themes/core/theme_store.dart';
|
||||||
import 'package:cake_wallet/utils/date_formatter.dart';
|
import 'package:cake_wallet/utils/date_formatter.dart';
|
||||||
import 'package:cw_core/payjoin_session.dart';
|
import 'package:cw_core/payjoin_session.dart';
|
||||||
|
@ -12,6 +14,7 @@ import 'package:cw_core/transaction_info.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
part 'payjoin_details_view_model.g.dart';
|
part 'payjoin_details_view_model.g.dart';
|
||||||
|
|
||||||
|
@ -40,7 +43,7 @@ abstract class PayjoinDetailsViewModelBase with Store {
|
||||||
@observable
|
@observable
|
||||||
late PayjoinSession payjoinSession;
|
late PayjoinSession payjoinSession;
|
||||||
|
|
||||||
final ObservableList<StandartListItem> items;
|
final ObservableList<TransactionDetailsListItem> items;
|
||||||
|
|
||||||
late final StreamSubscription<BoxEvent> listener;
|
late final StreamSubscription<BoxEvent> listener;
|
||||||
|
|
||||||
|
@ -69,12 +72,25 @@ abstract class PayjoinDetailsViewModelBase with Store {
|
||||||
title: S.current.error,
|
title: S.current.error,
|
||||||
value: payjoinSession.error!,
|
value: payjoinSession.error!,
|
||||||
),
|
),
|
||||||
if (payjoinSession.txId?.isNotEmpty == true && transactionInfo != null)
|
if (payjoinSession.txId?.isNotEmpty == true && transactionInfo != null) ...[
|
||||||
StandartListItem(
|
StandartListItem(
|
||||||
title: S.current.transaction_details_transaction_id,
|
title: S.current.transaction_details_transaction_id,
|
||||||
value: payjoinSession.txId!,
|
value: payjoinSession.txId!,
|
||||||
key: ValueKey('standard_list_item_transaction_details_id_key'),
|
key: ValueKey('standard_list_item_transaction_details_id_key'),
|
||||||
|
),
|
||||||
|
BlockExplorerListItem(
|
||||||
|
title: S.current.view_in_block_explorer,
|
||||||
|
value: '${S.current.view_transaction_on}mempool.space',
|
||||||
|
onTap: () async {
|
||||||
|
try {
|
||||||
|
final uri = Uri.parse('https://mempool.cakewallet.com/tx/${payjoinSession.txId!}');
|
||||||
|
if (await canLaunchUrl(uri))
|
||||||
|
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||||
|
} catch (e) {}
|
||||||
|
},
|
||||||
|
key: ValueKey('block_explorer_list_item_wallet_type_key'),
|
||||||
)
|
)
|
||||||
|
]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (transactionInfo != null) {
|
if (transactionInfo != null) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue