cake_wallet/tool/configure.dart
Rafael Saes 0d7fad3610 Linux flutter upgrade (#1054)
* V4.8.1 v1.5.1 (#1038)

* Revert "Cw 397 chatwoot live support (#1011)"

This reverts commit af9b5ff10c.

* Add Version 4.8.1 configs

* Update macos build version [skip ci]

* Re add chatwoot (#1044)

* Revert "Revert "Cw 397 chatwoot live support (#1011)""

This reverts commit ecdc7baa2e.

* Re-add chatwoot
Change chatwoot base url

* Cw 396 additional themes (#962)

* fix: SectionStandardList using BuildContext as param

* refactor: deprecated backgroundColor -> colorScheme.background

* refactor: themeBase and current themes

* refactor: accentTextTheme.titleLarge.color -> dialogTheme.backgroundColor

* refactor: gradient background

* refactor: text themes using the same color as primaryColor

* refactor: accentTextTheme.bodySmall.color -> cardColor

* refactor: text themes using same dialogBackgroundColor

* refactor: scrollbarTheme

* refactor: create SyncIndicatorTheme

* refactor: SectionDivider

* refactor: base_page improvements and simplify

* refactor: collapsible_standart_list improvements

* refactor: accentTextTheme.bodyLarge.backgroundColor -> KeyboardTheme.keyboardBarColor

* refactor: create PinCodeTheme for accentTextTheme.bodyMedium

* refactor: create SupportPageTheme for accentTextTheme.displayLarge.backgroundColor and fix cases that use it

* refactor: accentTextTheme.displayLarge.color -> disabledColor

* refactor: create ExchangePageTheme

* refactor: create DashboardPageTheme and use textColor

* refactor: create NewWalletTheme for accentTextTheme.displayMedium

* refactor: create BalancePageTheme for accentTextTheme.displaySmall.backgroundColor

* refactor: create AddressTheme for accentTextTheme.displaySmall.color

* refactor: create IndicatorDotTheme

* refactor: create CakeMenuTheme

* refactor: create FilterTheme

* refactor: create WalletListTheme

* refactor: accentTextTheme.bodySmall.decorationColor -> InfoTheme.textColor

* refactor: accentTextTheme.titleLarge.backgroundColor -> PickerTheme.dividerColor

* refactor: primaryTextTheme.bodyLarge.backgroundColor -> AlertTheme.leftButtonTextColor

* refactor: primaryTextTheme.displayLarge.backgroundColor -> OrderTheme.iconColor

* refactor: create SendPageTheme

* fix: missing migrated styles

* refactor: primaryTextTheme.labelSmall.decorationColor -> PlaceholderTheme.color

* refactor: create TransactionTradeTheme

* refactor: create CakeTextTheme

* refactor: create AccountListTheme

* refactor: create ReceivePageTheme

* refactor: create QRCodeTheme

* refactor: move remaining items to CakeTextTheme and some missing fixes

* feat(display_settings): add new theme selector

* feat: additional themes

* fix: conflict error

* fix(lag): move colorScheme initialization to constructor

* feat: add backdropColor to alert and picker backdrop filters

* fix: merge fixes

* fix: send template page missing new colors

* fix: anonpay pages title and icon colors

* fix: merge fixes

* fix: unspent coins page

* fix: also fix exchange template

* fix: missing checkbox

* fix: fixes for high contrast theme

* Merge branch 'main' into CW-396-additional-themes

* fix: merge fixes

* fix: .gitignore and rm added files

* Fix review comments

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>

* Flutter update (#1048)

* Update Flutter
Update packages

* Fix localization issues
Fix UI issues
Update old packages
Update workflow
Update how to build guide

* Additional UI fixes for merged conflicts

* Fix Ethereum network for anonpay invoice (#1051)

* build: migrate from wakelock to wakelock_plus

- plus is compatible with package_info_plus ^4.0.0
- plus has implemented Linux support

* fix: theme & support view model merge fixes

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
2023-09-07 15:48:10 -03:00

732 lines
28 KiB
Dart

import 'dart:io';
const bitcoinOutputPath = 'lib/bitcoin/bitcoin.dart';
const moneroOutputPath = 'lib/monero/monero.dart';
const havenOutputPath = 'lib/haven/haven.dart';
const ethereumOutputPath = 'lib/ethereum/ethereum.dart';
const walletTypesPath = 'lib/wallet_types.g.dart';
const secureStoragePath = 'lib/core/secure_storage.dart';
const pubspecDefaultPath = 'pubspec_default.yaml';
const pubspecOutputPath = 'pubspec.yaml';
Future<void> main(List<String> args) async {
const prefix = '--';
final hasBitcoin = args.contains('${prefix}bitcoin');
final hasMonero = args.contains('${prefix}monero');
final hasHaven = args.contains('${prefix}haven');
final hasEthereum = args.contains('${prefix}ethereum');
final excludeFlutterSecureStorage = args.contains('${prefix}excludeFlutterSecureStorage');
await generateBitcoin(hasBitcoin);
await generateMonero(hasMonero);
await generateHaven(hasHaven);
await generateEthereum(hasEthereum);
await generatePubspec(hasMonero: hasMonero, hasBitcoin: hasBitcoin, hasHaven: hasHaven, hasEthereum: hasEthereum, hasFlutterSecureStorage: !excludeFlutterSecureStorage);
await generateWalletTypes(hasMonero: hasMonero, hasBitcoin: hasBitcoin, hasHaven: hasHaven, hasEthereum: hasEthereum);
await injectSecureStorage(!excludeFlutterSecureStorage);
}
Future<void> generateBitcoin(bool hasImplementation) async {
final outputFile = File(bitcoinOutputPath);
const bitcoinCommonHeaders = """
import 'package:cake_wallet/entities/unspent_transaction_output.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/output_info.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cake_wallet/view_model/send/output.dart';
import 'package:hive/hive.dart';""";
const bitcoinCWHeaders = """
import 'package:cw_bitcoin/electrum_wallet.dart';
import 'package:cw_bitcoin/bitcoin_unspent.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
import 'package:cw_bitcoin/bitcoin_wallet.dart';
import 'package:cw_bitcoin/bitcoin_wallet_service.dart';
import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
import 'package:cw_bitcoin/litecoin_wallet_service.dart';
""";
const bitcoinCwPart = "part 'cw_bitcoin.dart';";
const bitcoinContent = """
abstract class Bitcoin {
TransactionPriority getMediumTransactionPriority();
WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
List<String> getWordList();
Map<String, String> getWalletKeys(Object wallet);
List<TransactionPriority> getTransactionPriorities();
List<TransactionPriority> getLitecoinTransactionPriorities();
TransactionPriority deserializeBitcoinTransactionPriority(int raw);
TransactionPriority deserializeLitecoinTransactionPriority(int raw);
int getFeeRate(Object wallet, TransactionPriority priority);
Future<void> generateNewAddress(Object wallet);
Object createBitcoinTransactionCredentials(List<Output> outputs, {required TransactionPriority priority, int? feeRate});
Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority? priority, required int feeRate});
List<String> getAddresses(Object wallet);
String getAddress(Object wallet);
String formatterBitcoinAmountToString({required int amount});
double formatterBitcoinAmountToDouble({required int amount});
int formatterStringDoubleToBitcoinAmount(String amount);
String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate);
List<Unspent> getUnspents(Object wallet);
void updateUnspents(Object wallet);
WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
TransactionPriority getBitcoinTransactionPriorityMedium();
TransactionPriority getLitecoinTransactionPriorityMedium();
TransactionPriority getBitcoinTransactionPrioritySlow();
TransactionPriority getLitecoinTransactionPrioritySlow();
}
""";
const bitcoinEmptyDefinition = 'Bitcoin? bitcoin;\n';
const bitcoinCWDefinition = 'Bitcoin? bitcoin = CWBitcoin();\n';
final output = '$bitcoinCommonHeaders\n'
+ (hasImplementation ? '$bitcoinCWHeaders\n' : '\n')
+ (hasImplementation ? '$bitcoinCwPart\n\n' : '\n')
+ (hasImplementation ? bitcoinCWDefinition : bitcoinEmptyDefinition)
+ '\n'
+ bitcoinContent;
if (outputFile.existsSync()) {
await outputFile.delete();
}
await outputFile.writeAsString(output);
}
Future<void> generateMonero(bool hasImplementation) async {
final outputFile = File(moneroOutputPath);
const moneroCommonHeaders = """
import 'package:cake_wallet/entities/unspent_transaction_output.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_monero/monero_unspent.dart';
import 'package:mobx/mobx.dart';
import 'package:flutter/foundation.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/transaction_history.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/balance.dart';
import 'package:cw_core/output_info.dart';
import 'package:cake_wallet/view_model/send/output.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:hive/hive.dart';""";
const moneroCWHeaders = """
import 'package:cw_core/get_height_by_date.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/monero_transaction_priority.dart';
import 'package:cw_monero/monero_wallet_service.dart';
import 'package:cw_monero/monero_wallet.dart';
import 'package:cw_monero/monero_transaction_info.dart';
import 'package:cw_monero/monero_transaction_history.dart';
import 'package:cw_monero/monero_transaction_creation_credentials.dart';
import 'package:cw_core/account.dart' as monero_account;
import 'package:cw_monero/api/wallet.dart' as monero_wallet_api;
import 'package:cw_monero/mnemonics/english.dart';
import 'package:cw_monero/mnemonics/chinese_simplified.dart';
import 'package:cw_monero/mnemonics/dutch.dart';
import 'package:cw_monero/mnemonics/german.dart';
import 'package:cw_monero/mnemonics/japanese.dart';
import 'package:cw_monero/mnemonics/russian.dart';
import 'package:cw_monero/mnemonics/spanish.dart';
import 'package:cw_monero/mnemonics/portuguese.dart';
import 'package:cw_monero/mnemonics/french.dart';
import 'package:cw_monero/mnemonics/italian.dart';
import 'package:cw_monero/pending_monero_transaction.dart';
""";
const moneroCwPart = "part 'cw_monero.dart';";
const moneroContent = """
class Account {
Account({required this.id, required this.label, this.balance});
final int id;
final String label;
final String? balance;
}
class Subaddress {
Subaddress({
required this.id,
required this.label,
required this.address});
final int id;
final String label;
final String address;
}
class MoneroBalance extends Balance {
MoneroBalance({required this.fullBalance, required this.unlockedBalance})
: formattedFullBalance = monero!.formatterMoneroAmountToString(amount: fullBalance),
formattedUnlockedBalance =
monero!.formatterMoneroAmountToString(amount: unlockedBalance),
super(unlockedBalance, fullBalance);
MoneroBalance.fromString(
{required this.formattedFullBalance,
required this.formattedUnlockedBalance})
: fullBalance = monero!.formatterMoneroParseAmount(amount: formattedFullBalance),
unlockedBalance = monero!.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
super(monero!.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
monero!.formatterMoneroParseAmount(amount: formattedFullBalance));
final int fullBalance;
final int unlockedBalance;
final String formattedFullBalance;
final String formattedUnlockedBalance;
@override
String get formattedAvailableBalance => formattedUnlockedBalance;
@override
String get formattedAdditionalBalance => formattedFullBalance;
}
abstract class MoneroWalletDetails {
@observable
late Account account;
@observable
late MoneroBalance balance;
}
abstract class Monero {
MoneroAccountList getAccountList(Object wallet);
MoneroSubaddressList getSubaddressList(Object wallet);
TransactionHistoryBase getTransactionHistory(Object wallet);
MoneroWalletDetails getMoneroWalletDetails(Object wallet);
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex);
String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex);
int getHeigthByDate({required DateTime date});
TransactionPriority getDefaultTransactionPriority();
TransactionPriority getMoneroTransactionPrioritySlow();
TransactionPriority getMoneroTransactionPriorityAutomatic();
TransactionPriority deserializeMoneroTransactionPriority({required int raw});
List<TransactionPriority> getTransactionPriorities();
List<String> getMoneroWordList(String language);
List<Unspent> getUnspents(Object wallet);
void updateUnspents(Object wallet);
WalletCredentials createMoneroRestoreWalletFromKeysCredentials({
required String name,
required String spendKey,
required String viewKey,
required String address,
required String password,
required String language,
required int height});
WalletCredentials createMoneroRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic});
WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, String? password,});
Map<String, String> getKeys(Object wallet);
Object createMoneroTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority});
Object createMoneroTransactionCreationCredentialsRaw({required List<OutputInfo> outputs, required TransactionPriority priority});
String formatterMoneroAmountToString({required int amount});
double formatterMoneroAmountToDouble({required int amount});
int formatterMoneroParseAmount({required String amount});
Account getCurrentAccount(Object wallet);
void setCurrentAccount(Object wallet, int id, String label, String? balance);
void onStartup();
int getTransactionInfoAccountId(TransactionInfo tx);
WalletService createMoneroWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource);
Map<String, String> pendingTransactionInfo(Object transaction);
}
abstract class MoneroSubaddressList {
ObservableList<Subaddress> get subaddresses;
void update(Object wallet, {required int accountIndex});
void refresh(Object wallet, {required int accountIndex});
List<Subaddress> getAll(Object wallet);
Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label});
Future<void> setLabelSubaddress(Object wallet,
{required int accountIndex, required int addressIndex, required String label});
}
abstract class MoneroAccountList {
ObservableList<Account> get accounts;
void update(Object wallet);
void refresh(Object wallet);
List<Account> getAll(Object wallet);
Future<void> addAccount(Object wallet, {required String label});
Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label});
}
""";
const moneroEmptyDefinition = 'Monero? monero;\n';
const moneroCWDefinition = 'Monero? monero = CWMonero();\n';
final output = '$moneroCommonHeaders\n'
+ (hasImplementation ? '$moneroCWHeaders\n' : '\n')
+ (hasImplementation ? '$moneroCwPart\n\n' : '\n')
+ (hasImplementation ? moneroCWDefinition : moneroEmptyDefinition)
+ '\n'
+ moneroContent;
if (outputFile.existsSync()) {
await outputFile.delete();
}
await outputFile.writeAsString(output);
}
Future<void> generateHaven(bool hasImplementation) async {
final outputFile = File(havenOutputPath);
const havenCommonHeaders = """
import 'package:mobx/mobx.dart';
import 'package:flutter/foundation.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/transaction_history.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/balance.dart';
import 'package:cw_core/output_info.dart';
import 'package:cake_wallet/view_model/send/output.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:hive/hive.dart';
import 'package:cw_core/crypto_currency.dart';""";
const havenCWHeaders = """
import 'package:cw_core/get_height_by_date.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/monero_transaction_priority.dart';
import 'package:cw_haven/haven_wallet_service.dart';
import 'package:cw_haven/haven_wallet.dart';
import 'package:cw_haven/haven_transaction_info.dart';
import 'package:cw_haven/haven_transaction_history.dart';
import 'package:cw_core/account.dart' as monero_account;
import 'package:cw_haven/api/wallet.dart' as monero_wallet_api;
import 'package:cw_haven/mnemonics/english.dart';
import 'package:cw_haven/mnemonics/chinese_simplified.dart';
import 'package:cw_haven/mnemonics/dutch.dart';
import 'package:cw_haven/mnemonics/german.dart';
import 'package:cw_haven/mnemonics/japanese.dart';
import 'package:cw_haven/mnemonics/russian.dart';
import 'package:cw_haven/mnemonics/spanish.dart';
import 'package:cw_haven/mnemonics/portuguese.dart';
import 'package:cw_haven/mnemonics/french.dart';
import 'package:cw_haven/mnemonics/italian.dart';
import 'package:cw_haven/haven_transaction_creation_credentials.dart';
import 'package:cw_haven/api/balance_list.dart';
""";
const havenCwPart = "part 'cw_haven.dart';";
const havenContent = """
class Account {
Account({required this.id, required this.label});
final int id;
final String label;
}
class Subaddress {
Subaddress({
required this.id,
required this.label,
required this.address});
final int id;
final String label;
final String address;
}
class HavenBalance extends Balance {
HavenBalance({required this.fullBalance, required this.unlockedBalance})
: formattedFullBalance = haven!.formatterMoneroAmountToString(amount: fullBalance),
formattedUnlockedBalance =
haven!.formatterMoneroAmountToString(amount: unlockedBalance),
super(unlockedBalance, fullBalance);
HavenBalance.fromString(
{required this.formattedFullBalance,
required this.formattedUnlockedBalance})
: fullBalance = haven!.formatterMoneroParseAmount(amount: formattedFullBalance),
unlockedBalance = haven!.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
super(haven!.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
haven!.formatterMoneroParseAmount(amount: formattedFullBalance));
final int fullBalance;
final int unlockedBalance;
final String formattedFullBalance;
final String formattedUnlockedBalance;
@override
String get formattedAvailableBalance => formattedUnlockedBalance;
@override
String get formattedAdditionalBalance => formattedFullBalance;
}
class AssetRate {
AssetRate(this.asset, this.rate);
final String asset;
final int rate;
}
abstract class HavenWalletDetails {
// FIX-ME: it's abstruct class
@observable
late Account account;
// FIX-ME: it's abstruct class
@observable
late HavenBalance balance;
}
abstract class Haven {
HavenAccountList getAccountList(Object wallet);
MoneroSubaddressList getSubaddressList(Object wallet);
TransactionHistoryBase getTransactionHistory(Object wallet);
HavenWalletDetails getMoneroWalletDetails(Object wallet);
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex);
int getHeightByDate({required DateTime date});
Future<int> getCurrentHeight();
TransactionPriority getDefaultTransactionPriority();
TransactionPriority deserializeMoneroTransactionPriority({required int raw});
List<TransactionPriority> getTransactionPriorities();
List<String> getMoneroWordList(String language);
WalletCredentials createHavenRestoreWalletFromKeysCredentials({
required String name,
required String spendKey,
required String viewKey,
required String address,
required String password,
required String language,
required int height});
WalletCredentials createHavenRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic});
WalletCredentials createHavenNewWalletCredentials({required String name, required String language, String? password});
Map<String, String> getKeys(Object wallet);
Object createHavenTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority, required String assetType});
String formatterMoneroAmountToString({required int amount});
double formatterMoneroAmountToDouble({required int amount});
int formatterMoneroParseAmount({required String amount});
Account getCurrentAccount(Object wallet);
void setCurrentAccount(Object wallet, int id, String label);
void onStartup();
int getTransactionInfoAccountId(TransactionInfo tx);
WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource);
CryptoCurrency assetOfTransaction(TransactionInfo tx);
List<AssetRate> getAssetRate();
}
abstract class MoneroSubaddressList {
ObservableList<Subaddress> get subaddresses;
void update(Object wallet, {required int accountIndex});
void refresh(Object wallet, {required int accountIndex});
List<Subaddress> getAll(Object wallet);
Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label});
Future<void> setLabelSubaddress(Object wallet,
{required int accountIndex, required int addressIndex, required String label});
}
abstract class HavenAccountList {
ObservableList<Account> get accounts;
void update(Object wallet);
void refresh(Object wallet);
List<Account> getAll(Object wallet);
Future<void> addAccount(Object wallet, {required String label});
Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label});
}
""";
const havenEmptyDefinition = 'Haven? haven;\n';
const havenCWDefinition = 'Haven? haven = CWHaven();\n';
final output = '$havenCommonHeaders\n'
+ (hasImplementation ? '$havenCWHeaders\n' : '\n')
+ (hasImplementation ? '$havenCwPart\n\n' : '\n')
+ (hasImplementation ? havenCWDefinition : havenEmptyDefinition)
+ '\n'
+ havenContent;
if (outputFile.existsSync()) {
await outputFile.delete();
}
await outputFile.writeAsString(output);
}
Future<void> generateEthereum(bool hasImplementation) async {
final outputFile = File(ethereumOutputPath);
const ethereumCommonHeaders = """
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:hive/hive.dart';
""";
const ethereumCWHeaders = """
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';
""";
const ethereumCwPart = "part 'cw_ethereum.dart';";
const ethereumContent = """
abstract class Ethereum {
List<String> getEthereumWordList(String language);
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
WalletCredentials createEthereumRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
String getAddress(WalletBase wallet);
TransactionPriority getDefaultTransactionPriority();
List<TransactionPriority> getTransactionPriorities();
TransactionPriority deserializeEthereumTransactionPriority(int raw);
Object createEthereumTransactionCredentials(
List<Output> outputs, {
required TransactionPriority priority,
required CryptoCurrency currency,
int? feeRate,
});
Object createEthereumTransactionCredentialsRaw(
List<OutputInfo> outputs, {
TransactionPriority? priority,
required CryptoCurrency currency,
required int feeRate,
});
int formatterEthereumParseAmount(String amount);
double formatterEthereumAmountToDouble({TransactionInfo? transaction, BigInt? amount, int exponent = 18});
List<Erc20Token> getERC20Currencies(WalletBase wallet);
Future<void> addErc20Token(WalletBase wallet, Erc20Token token);
Future<void> deleteErc20Token(WalletBase wallet, Erc20Token token);
Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress);
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction);
void updateEtherscanUsageState(WalletBase wallet, bool isEnabled);
}
""";
const ethereumEmptyDefinition = 'Ethereum? ethereum;\n';
const ethereumCWDefinition = 'Ethereum? ethereum = CWEthereum();\n';
final output = '$ethereumCommonHeaders\n'
+ (hasImplementation ? '$ethereumCWHeaders\n' : '\n')
+ (hasImplementation ? '$ethereumCwPart\n\n' : '\n')
+ (hasImplementation ? ethereumCWDefinition : ethereumEmptyDefinition)
+ '\n'
+ ethereumContent;
if (outputFile.existsSync()) {
await outputFile.delete();
}
await outputFile.writeAsString(output);
}
Future<void> generatePubspec({
required bool hasMonero,
required bool hasBitcoin,
required bool hasHaven,
required bool hasEthereum,
required bool hasFlutterSecureStorage}) async {
const cwCore = """
cw_core:
path: ./cw_core
""";
const cwMonero = """
cw_monero:
path: ./cw_monero
""";
const cwBitcoin = """
cw_bitcoin:
path: ./cw_bitcoin
""";
const cwHaven = """
cw_haven:
path: ./cw_haven
""";
const cwSharedExternal = """
cw_shared_external:
path: ./cw_shared_external
""";
const cwEthereum = """
cw_ethereum:
path: ./cw_ethereum
""";
const flutterSecureStorage = """
flutter_secure_storage:
git:
url: https://github.com/cake-tech/flutter_secure_storage.git
path: flutter_secure_storage
ref: cake-6.0.0
version: 6.0.0
""";
final inputFile = File(pubspecOutputPath);
final inputText = await inputFile.readAsString();
final inputLines = inputText.split('\n');
final dependenciesIndex = inputLines.indexWhere((line) => line.toLowerCase() == 'dependencies:');
var output = cwCore;
if (hasMonero) {
output += '\n$cwMonero\n$cwSharedExternal';
}
if (hasBitcoin) {
output += '\n$cwBitcoin';
}
if (hasHaven && !hasMonero) {
output += '\n$cwSharedExternal\n$cwHaven';
} else if (hasHaven) {
output += '\n$cwHaven';
}
if (hasEthereum) {
output += '\n$cwEthereum';
}
if (hasFlutterSecureStorage) {
output += '\n$flutterSecureStorage\n';
}
final outputLines = output.split('\n');
inputLines.insertAll(dependenciesIndex + 1, outputLines);
final outputContent = inputLines.join('\n');
final outputFile = File(pubspecOutputPath);
if (outputFile.existsSync()) {
await outputFile.delete();
}
await outputFile.writeAsString(outputContent);
}
Future<void> generateWalletTypes({required bool hasMonero, required bool hasBitcoin, required bool hasHaven, required bool hasEthereum}) async {
final walletTypesFile = File(walletTypesPath);
if (walletTypesFile.existsSync()) {
await walletTypesFile.delete();
}
const outputHeader = "import 'package:cw_core/wallet_type.dart';";
const outputDefinition = 'final availableWalletTypes = <WalletType>[';
var outputContent = outputHeader + '\n\n' + outputDefinition + '\n';
if (hasMonero) {
outputContent += '\tWalletType.monero,\n';
}
if (hasBitcoin) {
outputContent += '\tWalletType.bitcoin,\n';
}
if (hasEthereum) {
outputContent += '\tWalletType.ethereum,\n';
}
if (hasBitcoin) {
outputContent += '\tWalletType.litecoin,\n';
}
if (hasHaven) {
outputContent += '\tWalletType.haven,\n';
}
outputContent += '];\n';
await walletTypesFile.writeAsString(outputContent);
}
Future<void> injectSecureStorage(bool hasFlutterSecureStorage) async {
const flutterSecureStorageHeader = "import 'package:flutter_secure_storage/flutter_secure_storage.dart';";
const abstractSecureStorage = """
abstract class SecureStorage {
Future<String?> read({required String key});
Future<void> write({required String key, required String? value});
Future<void> delete({required String key});
// Legacy
Future<String?> readNoIOptions({required String key});
}""";
const defaultSecureStorage = """
class DefaultSecureStorage extends SecureStorage {
DefaultSecureStorage._(this._secureStorage);
factory DefaultSecureStorage() => _instance;
static final _instance = DefaultSecureStorage._(FlutterSecureStorage());
final FlutterSecureStorage _secureStorage;
@override
Future<String?> read({required String key}) async
=> _secureStorage.read(key: key);
@override
Future<void> write({required String key, required String? value}) async
=> _secureStorage.write(key: key, value: value);
@override
Future<void> delete({required String key}) async
=> _secureStorage.delete(key: key);
@override
Future<String?> readNoIOptions({required String key}) async
=> _secureStorage.read(key: key, iOptions: IOSOptions());
}""";
const fakeSecureStorage = """
class FakeSecureStorage extends SecureStorage {
@override
Future<String?> read({required String key}) async => null;
@override
Future<void> write({required String key, required String? value}) async {}
@override
Future<void> delete({required String key}) async {}
@override
Future<String?> readNoIOptions({required String key}) async => null;
}""";
final outputFile = File(secureStoragePath);
final header = hasFlutterSecureStorage
? '${flutterSecureStorageHeader}\n\nfinal SecureStorage secureStorageShared = DefaultSecureStorage();\n'
: 'final SecureStorage secureStorageShared = FakeSecureStorage();\n';
var output = '';
if (outputFile.existsSync()) {
await outputFile.delete();
}
output += '${header}\n${abstractSecureStorage}\n\n';
if (hasFlutterSecureStorage) {
output += '${defaultSecureStorage}\n';
} else {
output += '${fakeSecureStorage}\n';
}
await outputFile.writeAsString(output);
}