diff --git a/cw_ethereum/lib/ethereum_client.dart b/cw_ethereum/lib/ethereum_client.dart index 7e18da46f..158fd99ab 100644 --- a/cw_ethereum/lib/ethereum_client.dart +++ b/cw_ethereum/lib/ethereum_client.dart @@ -97,6 +97,7 @@ class EthereumClient { required int gas, required EthereumTransactionPriority priority, required CryptoCurrency currency, + required int exponent, String? contractAddress, }) async { assert(currency == CryptoCurrency.eth || contractAddress != null); @@ -115,7 +116,7 @@ class EthereumClient { final signedTransaction = await _client!.signTransaction(privateKey, transaction); - final estimatedGas; + final BigInt estimatedGas; final Function _sendTransaction; if (_isEthereum) { @@ -129,14 +130,10 @@ class EthereumClient { address: EthereumAddress.fromHex(contractAddress!), ); - final originalAmount = BigInt.parse(amount) / BigInt.from(pow(10, 18)); - final int exponent = (await erc20.decimals()).toInt(); - final _amount = BigInt.from(originalAmount * pow(10, exponent)); - _sendTransaction = () async { await erc20.transfer( EthereumAddress.fromHex(toAddress), - _amount, + BigInt.parse(amount), credentials: privateKey, ); }; @@ -147,6 +144,7 @@ class EthereumClient { amount: amount, fee: estimatedGas * price.getInWei, sendTransaction: _sendTransaction, + exponent: exponent, ); } diff --git a/cw_ethereum/lib/ethereum_exceptions.dart b/cw_ethereum/lib/ethereum_exceptions.dart index 1cb69608a..518f46275 100644 --- a/cw_ethereum/lib/ethereum_exceptions.dart +++ b/cw_ethereum/lib/ethereum_exceptions.dart @@ -1,8 +1,10 @@ +import 'package:cw_core/crypto_currency.dart'; + class EthereumTransactionCreationException implements Exception { final String exceptionMessage; - EthereumTransactionCreationException( - {this.exceptionMessage = 'Wrong balance. Not enough Ether on your balance.'}); + EthereumTransactionCreationException(CryptoCurrency currency) : + this.exceptionMessage = 'Wrong balance. Not enough ${currency.title} on your balance.'; @override String toString() => exceptionMessage; diff --git a/cw_ethereum/lib/ethereum_formatter.dart b/cw_ethereum/lib/ethereum_formatter.dart index 245e9da50..468c536f8 100644 --- a/cw_ethereum/lib/ethereum_formatter.dart +++ b/cw_ethereum/lib/ethereum_formatter.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:intl/intl.dart'; const ethereumAmountLength = 12; @@ -17,10 +15,9 @@ class EthereumFormatter { } } - static int parseEthereumBigIntAmount(BigInt amount) { + static double parseEthereumAmountToDouble(int amount) { try { - double result = amount / BigInt.from(pow(10, 18 - ethereumAmountLength)); - return result.toInt(); + return amount / ethereumAmountDivider; } catch (_) { return 0; } diff --git a/cw_ethereum/lib/ethereum_wallet.dart b/cw_ethereum/lib/ethereum_wallet.dart index 1faf86e7b..908054fa3 100644 --- a/cw_ethereum/lib/ethereum_wallet.dart +++ b/cw_ethereum/lib/ethereum_wallet.dart @@ -147,30 +147,33 @@ abstract class EthereumWalletBase final hasMultiDestination = outputs.length > 1; final _erc20Balance = balance[_credentials.currency]!; BigInt totalAmount = BigInt.zero; - BigInt amountToEthereumMultiplier = BigInt.from(pow(10, 18 - ethereumAmountLength)); + int exponent = + _credentials.currency is Erc20Token ? (_credentials.currency as Erc20Token).decimal : 18; + BigInt amountToEthereumMultiplier = BigInt.from(pow(10, exponent)); if (hasMultiDestination) { if (outputs.any((item) => item.sendAll || (item.formattedCryptoAmount ?? 0) <= 0)) { - throw EthereumTransactionCreationException(); + throw EthereumTransactionCreationException(_credentials.currency); } - totalAmount = - BigInt.from(outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0))) * - amountToEthereumMultiplier; + final totalOriginalAmount = EthereumFormatter.parseEthereumAmountToDouble( + outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0))); + totalAmount = BigInt.from(totalOriginalAmount) * amountToEthereumMultiplier; if (_erc20Balance.balance < totalAmount) { - throw EthereumTransactionCreationException(); + throw EthereumTransactionCreationException(_credentials.currency); } } else { final output = outputs.first; final BigInt allAmount = _erc20Balance.balance - BigInt.from(feeRate(_credentials.priority!)); + final totalOriginalAmount = + EthereumFormatter.parseEthereumAmountToDouble(output.formattedCryptoAmount ?? 0); totalAmount = output.sendAll ? allAmount - : BigInt.from(output.formattedCryptoAmount ?? 0) * amountToEthereumMultiplier; + : BigInt.from(totalOriginalAmount) * amountToEthereumMultiplier; - if ((output.sendAll && _erc20Balance.balance < totalAmount) || - (!output.sendAll && _erc20Balance.balance <= BigInt.zero)) { - throw EthereumTransactionCreationException(); + if (_erc20Balance.balance < totalAmount) { + throw EthereumTransactionCreationException(_credentials.currency); } } @@ -181,6 +184,7 @@ abstract class EthereumWalletBase gas: _priorityFees[_credentials.priority!.raw], priority: _credentials.priority!, currency: _credentials.currency, + exponent: exponent, contractAddress: _credentials.currency is Erc20Token ? (_credentials.currency as Erc20Token).contractAddress : null, diff --git a/cw_ethereum/lib/pending_ethereum_transaction.dart b/cw_ethereum/lib/pending_ethereum_transaction.dart index f26680ac7..23dfa3b87 100644 --- a/cw_ethereum/lib/pending_ethereum_transaction.dart +++ b/cw_ethereum/lib/pending_ethereum_transaction.dart @@ -1,31 +1,32 @@ +import 'dart:math'; import 'dart:typed_data'; import 'package:cw_core/pending_transaction.dart'; import 'package:web3dart/crypto.dart'; -import 'package:web3dart/web3dart.dart'; class PendingEthereumTransaction with PendingTransaction { final Function sendTransaction; final Uint8List signedTransaction; final BigInt fee; final String amount; + final int exponent; PendingEthereumTransaction({ required this.sendTransaction, required this.signedTransaction, required this.fee, required this.amount, + required this.exponent, }); @override - String get amountFormatted => - EtherAmount.inWei(BigInt.parse(amount)).getValueInUnit(EtherUnit.ether).toString(); + String get amountFormatted => (BigInt.parse(amount) / BigInt.from(pow(10, exponent))).toString(); @override Future commit() async => await sendTransaction(); @override - String get feeFormatted => EtherAmount.inWei(fee).getValueInUnit(EtherUnit.ether).toString(); + String get feeFormatted => (fee / BigInt.from(pow(10, 18))).toString(); @override String get hex => bytesToHex(signedTransaction, include0x: true);