diff --git a/cw_core/lib/crypto_currency.dart b/cw_core/lib/crypto_currency.dart index 0ece4b8f0..45fb53c60 100644 --- a/cw_core/lib/crypto_currency.dart +++ b/cw_core/lib/crypto_currency.dart @@ -90,6 +90,7 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen CryptoCurrency.zrx, CryptoCurrency.dydx, CryptoCurrency.steth, + CryptoCurrency.banano, ]; static const havenCurrencies = [ diff --git a/cw_core/lib/currency_for_wallet_type.dart b/cw_core/lib/currency_for_wallet_type.dart index 8ac8c1fc6..2db858b30 100644 --- a/cw_core/lib/currency_for_wallet_type.dart +++ b/cw_core/lib/currency_for_wallet_type.dart @@ -13,6 +13,10 @@ CryptoCurrency currencyForWalletType(WalletType type) { return CryptoCurrency.xhv; case WalletType.ethereum: return CryptoCurrency.eth; + case WalletType.nano: + return CryptoCurrency.nano; + case WalletType.banano: + return CryptoCurrency.banano; default: throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType'); } diff --git a/cw_core/lib/wallet_type.dart b/cw_core/lib/wallet_type.dart index d4c22c801..9f3f6520f 100644 --- a/cw_core/lib/wallet_type.dart +++ b/cw_core/lib/wallet_type.dart @@ -10,6 +10,7 @@ const walletTypes = [ WalletType.haven, WalletType.ethereum, WalletType.nano, + WalletType.banano, ]; const walletTypeTypeId = 5; diff --git a/cw_nano/lib/nano_balance.dart b/cw_nano/lib/nano_balance.dart index 57d092bc6..d83bb4eaf 100644 --- a/cw_nano/lib/nano_balance.dart +++ b/cw_nano/lib/nano_balance.dart @@ -12,7 +12,7 @@ class NanoBalance extends Balance { late String formattedCurrentBalance; late String formattedReceivableBalance; - NanoBalance({required this.currentBalance, required this.receivableBalance}) : super(currentBalance.toInt(), receivableBalance.toInt()) { + NanoBalance({required this.currentBalance, required this.receivableBalance}) : super(0, 0) { this.formattedCurrentBalance = ""; this.formattedReceivableBalance = ""; } @@ -23,4 +23,11 @@ class NanoBalance extends Balance { // receivableBalance = moneroParseAmount(amount: formattedReceivableBalance), // super(moneroParseAmount(amount: formattedReceivableBalance), // moneroParseAmount(amount: formattedCurrentBalance)); + + + @override + String get formattedAvailableBalance => "error"; + + @override + String get formattedAdditionalBalance => "error"; } diff --git a/lib/core/address_validator.dart b/lib/core/address_validator.dart index f2a235363..02e50b1ca 100644 --- a/lib/core/address_validator.dart +++ b/lib/core/address_validator.dart @@ -28,6 +28,8 @@ class AddressValidator extends TextValidator { return '^3[0-9a-zA-Z]{32}\$|^3[0-9a-zA-Z]{33}\$|^bc1[0-9a-zA-Z]{59}\$'; case CryptoCurrency.nano: return '[0-9a-zA-Z_]'; + case CryptoCurrency.banano: + return '[0-9a-zA-Z_]'; case CryptoCurrency.usdc: case CryptoCurrency.usdcpoly: case CryptoCurrency.ape: @@ -177,6 +179,8 @@ class AddressValidator extends TextValidator { return [34, 43, 63]; case CryptoCurrency.nano: return [64, 65]; + case CryptoCurrency.banano: + return [64, 65]; case CryptoCurrency.sc: return [76]; case CryptoCurrency.sol: diff --git a/lib/core/seed_validator.dart b/lib/core/seed_validator.dart index eba1bbda4..694620fc6 100644 --- a/lib/core/seed_validator.dart +++ b/lib/core/seed_validator.dart @@ -5,6 +5,7 @@ import 'package:cake_wallet/core/validator.dart'; import 'package:cake_wallet/entities/mnemonic_item.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:cake_wallet/monero/monero.dart'; +import 'package:cake_wallet/nano/nano.dart'; import 'package:cake_wallet/utils/language_list.dart'; class SeedValidator extends Validator { @@ -28,6 +29,9 @@ class SeedValidator extends Validator { return haven!.getMoneroWordList(language); case WalletType.ethereum: return ethereum!.getEthereumWordList(language); + case WalletType.nano: + case WalletType.banano:// the same + return nano!.getNanoWordList(language); default: return []; } diff --git a/lib/di.dart b/lib/di.dart index 2c61e0f43..d596c0ac8 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -8,6 +8,7 @@ import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/parse_address_from_domain.dart'; import 'package:cake_wallet/entities/receive_page_option.dart'; import 'package:cake_wallet/ethereum/ethereum.dart'; +import 'package:cake_wallet/nano/nano.dart'; import 'package:cake_wallet/ionia/ionia_anypay.dart'; import 'package:cake_wallet/ionia/ionia_gift_card.dart'; import 'package:cake_wallet/ionia/ionia_tip.dart'; @@ -744,6 +745,8 @@ Future setup({ return bitcoin!.createLitecoinWalletService(_walletInfoSource, _unspentCoinsInfoSource!); case WalletType.ethereum: return ethereum!.createEthereumWalletService(_walletInfoSource); + case WalletType.nano: + return nano!.createNanoWalletService(_walletInfoSource); default: throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService'); } diff --git a/lib/nano/cw_nano.dart b/lib/nano/cw_nano.dart new file mode 100644 index 000000000..dfd15abaa --- /dev/null +++ b/lib/nano/cw_nano.dart @@ -0,0 +1,121 @@ +part of 'nano.dart'; + +class CWNano extends Nano { + @override + List getNanoWordList(String language) => EthereumMnemonics.englishWordlist; + + WalletService createNanoWalletService(Box walletInfoSource) => + EthereumWalletService(walletInfoSource); + + @override + WalletCredentials createEthereumNewWalletCredentials({ + required String name, + WalletInfo? walletInfo, + }) => + EthereumNewWalletCredentials(name: name, walletInfo: walletInfo); + + @override + WalletCredentials createEthereumRestoreWalletFromSeedCredentials({ + required String name, + required String mnemonic, + required String password, + }) => + EthereumRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic); + + @override + String getAddress(WalletBase wallet) => (wallet as EthereumWallet).walletAddresses.address; + + @override + TransactionPriority getDefaultTransactionPriority() => EthereumTransactionPriority.medium; + + @override + List getTransactionPriorities() => EthereumTransactionPriority.all; + + @override + TransactionPriority deserializeEthereumTransactionPriority(int raw) => + EthereumTransactionPriority.deserialize(raw: raw); + + @override + int getEstimatedFee(Object wallet, TransactionPriority priority) { + final ethereumWallet = wallet as EthereumWallet; + return ethereumWallet.feeRate(priority); + } + + Object createEthereumTransactionCredentials( + List outputs, { + required TransactionPriority priority, + required CryptoCurrency currency, + int? feeRate, + }) => + EthereumTransactionCredentials( + outputs + .map((out) => OutputInfo( + fiatAmount: out.fiatAmount, + cryptoAmount: out.cryptoAmount, + address: out.address, + note: out.note, + sendAll: out.sendAll, + extractedAddress: out.extractedAddress, + isParsedAddress: out.isParsedAddress, + formattedCryptoAmount: out.formattedCryptoAmount)) + .toList(), + priority: priority as EthereumTransactionPriority, + currency: currency, + feeRate: feeRate, + ); + + Object createEthereumTransactionCredentialsRaw( + List outputs, { + TransactionPriority? priority, + required CryptoCurrency currency, + required int feeRate, + }) => + EthereumTransactionCredentials( + outputs, + priority: priority as EthereumTransactionPriority?, + currency: currency, + feeRate: feeRate, + ); + + @override + int formatterEthereumParseAmount(String amount) => EthereumFormatter.parseEthereumAmount(amount); + + @override + double formatterEthereumAmountToDouble({required TransactionInfo transaction}) { + transaction as EthereumTransactionInfo; + return cryptoAmountToDouble( + amount: transaction.amount, divider: BigInt.from(10).pow(transaction.exponent).toInt()); + } + + @override + List getERC20Currencies(WalletBase wallet) { + final ethereumWallet = wallet as EthereumWallet; + return ethereumWallet.erc20Currencies; + } + + @override + Future addErc20Token(WalletBase wallet, Erc20Token token) async => + await (wallet as EthereumWallet).addErc20Token(token); + + @override + Future deleteErc20Token(WalletBase wallet, Erc20Token token) async => + await (wallet as EthereumWallet).deleteErc20Token(token); + + @override + Future getErc20Token(WalletBase wallet, String contractAddress) async { + final ethereumWallet = wallet as EthereumWallet; + return await ethereumWallet.getErc20Token(contractAddress); + } + + @override + CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction) { + transaction as EthereumTransactionInfo; + if (transaction.tokenSymbol == CryptoCurrency.eth.title) { + return CryptoCurrency.eth; + } + + wallet as EthereumWallet; + return wallet.erc20Currencies + .firstWhere((element) => transaction.tokenSymbol == element.symbol); + } +} diff --git a/lib/nano/nano.dart b/lib/nano/nano.dart new file mode 100644 index 000000000..ca043af14 --- /dev/null +++ b/lib/nano/nano.dart @@ -0,0 +1,61 @@ + +import 'package:cake_wallet/view_model/send/output.dart'; +import 'package:cw_core/crypto_amount_format.dart'; +import 'package:cw_core/crypto_currency.dart'; +import 'package:cw_core/erc20_token.dart'; +import 'package:cw_core/output_info.dart'; +import 'package:cw_core/transaction_info.dart'; +import 'package:cw_core/transaction_priority.dart'; +import 'package:cw_core/wallet_base.dart'; +import 'package:cw_core/wallet_credentials.dart'; +import 'package:cw_core/wallet_info.dart'; +import 'package:cw_core/wallet_service.dart'; +import 'package:cw_ethereum/ethereum_formatter.dart'; +import 'package:cw_ethereum/ethereum_mnemonics.dart'; +import 'package:cw_ethereum/ethereum_transaction_credentials.dart'; +import 'package:cw_ethereum/ethereum_transaction_info.dart'; +import 'package:cw_ethereum/ethereum_wallet.dart'; +import 'package:cw_ethereum/ethereum_wallet_creation_credentials.dart'; +import 'package:cw_ethereum/ethereum_wallet_service.dart'; +import 'package:cw_ethereum/ethereum_transaction_priority.dart'; +import 'package:hive/hive.dart'; + +part 'cw_nano.dart'; + +Nano? nano = CWNano(); + +abstract class Nano { + List getNanoWordList(String language); + WalletService createNanoWalletService(Box walletInfoSource); + WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo}); + WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password}); + String getAddress(WalletBase wallet); + TransactionPriority getDefaultTransactionPriority(); + List getTransactionPriorities(); + TransactionPriority deserializeEthereumTransactionPriority(int raw); + int getEstimatedFee(Object wallet, TransactionPriority priority); + + Object createEthereumTransactionCredentials( + List outputs, { + required TransactionPriority priority, + required CryptoCurrency currency, + int? feeRate, + }); + + Object createEthereumTransactionCredentialsRaw( + List outputs, { + TransactionPriority? priority, + required CryptoCurrency currency, + required int feeRate, + }); + + int formatterEthereumParseAmount(String amount); + double formatterEthereumAmountToDouble({required TransactionInfo transaction}); + List getERC20Currencies(WalletBase wallet); + Future addErc20Token(WalletBase wallet, Erc20Token token); + Future deleteErc20Token(WalletBase wallet, Erc20Token token); + Future getErc20Token(WalletBase wallet, String contractAddress); + + CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction); +} + \ No newline at end of file