mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-17 05:41:29 +02:00
* feat(evm): add ChainConfig model and related classes - Add ChainConfig class for immutable EVM chain configuration - Add ChainCapabilities class for chain feature flags - Add FeeType enum and FeeModel class for fee configuration * feat(evm): add EvmChainRegistry for centralized chain management - Add singleton EvmChainRegistry class with chain configuration storage - Initialize with Ethereum, Polygon, Base, and Arbitrum chains - Add mappings for WalletType, tag, and CAIP-2 to chainId lookups - Provide lookup methods for chain configurations by various identifiers - Support for querying available chains and registered chain IDs * feat(evm): add EVMChainClientFactory and consolidate chain clients - Create EVMChainClientFactory for creating chain-specific clients based on chainId - Move all chain clients (EthereumClient, PolygonClient, BaseClient, ArbitrumClient) into cw_evm/lib/clients/ folder - Refactor EVMChainClient from abstract to concrete class with default implementations - Add default implementations for fetchTransactions, fetchInternalTransactions, and prepareSignedTransactionForSending - Update all client classes to use super(chainId: X) constructor pattern - Factory returns EVMChainClient directly for unregistered chains instead of throwing - Remove dependencies on cw_ethereum, cw_polygon, cw_base, cw_arbitrum packages from pubspec.yaml - Consolidate all EVM chain client implementations in one location for easier maintenance * add ui for evm switcher on eth * add inputs for evm network list edit switches * refactor(evm): Make EVMChainWallet concrete and unify transaction classes - Make EVMChainWallet and EVMChainWalletBase concrete classes (removed abstract) - Implement all previously abstract methods in EVMChainWallet - Make EVMChainTransactionInfo and EVMChainTransactionHistory concrete - Reorganize default tokens into tokens/ folder: - Refactor EVMChainDefaultTokens to import and use token classes from tokens/ folder - Move clients to clients/ folder: - Move evm_chain_formatter.dart to utils - Update chain-specific transaction history classes to pass walletType to fromJson - Update old wallet classes (EthereumWallet, PolygonWallet, etc.) to pass walletType - Maintain compatibility with existing per-chain wallet classes This refactoring enables the unified EVMChainWallet architecture while maintaining full backward compatibility with existing per-chain wallet implementations. * feat(evm): Add chain selection capability to EVMChainWallet - Add selectedChainId observable field to track currently selected chain - Add selectChain(chainId) action method to switch between EVM chains - Add selectedChainConfig computed getter for accessing chain configuration - Initialize selectedChainId from client.chainId in constructor - Add _getClientForCurrentChain() helper method for future use This enables chain switching functionality while maintaining full backward compatibility. The selectedChainId is initialized from the existing client, and all existing methods continue to work unchanged. Future increments will update methods to use selectedChainId internally. * refactor(evm): Update client immediately on chain selection - Update selectChain() to immediately create new client for selected chain - Remove _getClientForCurrentChain() helper method - Simplify all methods to use _client directly instead of helper calls - Client is now always in sync with selectedChainId This improves code simplicity and performance by eliminating repeated client checks. The client is updated synchronously when selectChain() is called, ensuring state consistency. * featr(evm): Add unified evm proxy setup and fix chain initialization - Add unified Evm proxy - Add evm.dart to .gitignore for generated proxy - Add generateEVM() to configure.dart for proxy generation - Fix selectedChainId to initialize from registry based on walletInfo.type Ensures selectedChainId always matches wallet type on initialization and adds unified proxy infrastructure. * refactor(evm): Update backward compat helpers to use registry via proxy - Add registry helper methods to unified EVM proxy - Update all lib/ files to use proxy instead of direct cw_evm imports - Enforce proxy pattern: no direct imports from cw_evm in main app - Update configure.dart to include registry methods in generated proxy Maintains backward compatibility while centralizing chain data access through the unified proxy pattern. * feat(evm): Add chain selection UI to dashboard - Add chain selection methods to DashboardViewModel (isEVMWallet, availableChains, currentChain, selectChain) - Add chain dropdown widget to balance page for EVM wallets - Dropdown shows current chain and allows switching between all registered EVM chains - Only visible for EVM-compatible wallets - Add chain selection methods to EVM proxy (getAllChains, getCurrentChain, selectChain) Users can now switch between EVM chains (Ethereum, Polygon, Base, Arbitrum) directly from the dashboard without creating separate wallets. All chain-related code follows the established proxy pattern. * feat(evm): Add persistence for selected chain ID - Add initialChainId parameter to EVMChainWallet constructor - Save selectedChainId to wallet JSON in toJSON() method - Load selectedChainId from JSON in open() method - Handle backward compatibility: wallets without saved chain ID use wallet type's default chain ID - Client is created with saved chain ID when opening wallet Selected chain preference is now persisted across app sessions. Users will see their previously selected chain when reopening wallets. * chore: Minor cleanup * refactor(evm): Remove old per-chain packages, consolidate to unified cw_evm - Delete cw_ethereum, cw_polygon, cw_base, cw_arbitrum packages - Remove old proxy files (lib/ethereum/, lib/polygon/, lib/base/, lib/arbitrum/) - Update all view models to use unified evm! proxy - Move DEuro functionality to cw_evm/lib/deuro/ - Remove dependencies from pubspec.yaml and configure.dart - Remove walletType parameter from EVM proxy methods All EVM chains now use unified cw_evm package through single proxy interface. lib/ only depends on cw_evm, simplifying architecture and enabling easy addition of new L2 chains. BREAKING CHANGE: Old per-chain packages removed * refactor(evm): Update wallet handling to use unified EVM proxy - Replace individual chain imports (Ethereum, Polygon, Base, Arbitrum) with a single EVM proxy import. - Refactor wallet-related methods across various view models to utilize the new evm proxy for various usecases. This change enhances code maintainability and prepares the codebase for the addition of new EVM chains. * refactor(evm): Update model generator and enhance EVM classes - Modify model_generator.sh to remove previous chain folders from the loop. - Change EVMChainTransactionHistoryBase and EVMChainWalletBase classes to be abstract. - Update import paths in configure.dart to reflect the new structure of the cw_evm package. * add evm switcher icons to pubspec_base * change evm switcher to sliding animation * formatting fix * dpi agnostic width * feat(evm): Enhance chain handling and transaction history management - Introduce getCurrentChainId function to EVMChainTransactionHistoryBase for dynamic transaction history file naming based on the current chain ID. - Update EVMChainTransactionInfo to include chainId, ensuring accurate transaction data representation. - Refactor EVMChainWalletBase to support automatic node connection and transaction history loading upon chain selection. - Implement saveBackup and restoreWalletFilesFromBackup methods in EVMChainWalletService to manage wallet backups based on wallet type. - Update various methods across the codebase to accommodate the new chain handling logic, improving overall functionality and user experience. * chore: Cleanups and updates * feat: add WalletType.evm and deprecate individual EVM chain types Add unified WalletType.evm enum value for all EVM-compatible chains. Deprecate old individual EVM types (ethereum, polygon, base, arbitrum) with guidance to use WalletType.evm for new code. Update serialization/deserialization functions to support WalletType.evm: - serializeToInt() returns 18 for WalletType.evm - deserializeFromInt() handles case 18 - walletTypeToString() and walletTypeToDisplayName() return 'EVM' - cryptoCurrencyToWalletType() maps all EVM currencies to WalletType.evm Old EVM types remain functional for backward compatibility with existing wallets. This is the foundation for unifying EVM chain management. * feat: update EVM detection functions to support WalletType.evm Update all EVM detection and chain helper functions to support the unified WalletType.evm while maintaining backward compatibility with old EVM types. All functions require chainId parameter when used with WalletType.evm, ensuring proper chain-specific behavior. Old EVM types continue to work without changes for backward compatibility. * feat: add currency mapping support for unified EVM wallet type - Update currency mapping to support WalletType.evm with chainId-based currency resolution. - Override EVMChainWallet.currency getter to use selectedChainId from registry. - Replace walletTypeToCryptoCurrency calls with wallet.currency in view models. - Add WalletType.evm cases to switch statements and consolidate EVM transaction list item methods. - Add explorer URL method to EVM interface * feat: Update wallet operations with unified WalletType.evm - Update wallet service to always create new wallets and restores with WalletType.evm, defaulting to Ethereum. - Preserve old wallet types when opening existing wallets. Update wallet instance creation and opening logic to handle unified EVM type with chainId-based config lookup. * Add WalletType.evm support across all switch statements - Update all switch statements and conditionals to include WalletType.evm alongside existing EVM types. - Add chainId-based node selection support for unified EVM wallets. - Fix redundant code in exchange view model. - Ensure backward compatibility with old EVM wallet types. * feat(evm): Implement chainId-based node management for WalletType.evm - Add chainId-based node storage for unified EVM wallets, enabling separate node preferences per chain. - Replace unsafe dynamic casts with type-safe getSelectedChainId method. Update all node retrieval and switching logic to support chainId-based selection. * feat: Update UI components to show unified EVM wallet option - Filter out old EVM wallet types (ethereum, polygon, base, arbitrum) from wallet creation and restore UI, showing only unified WalletType.evm option. - Update wallet type generation to include WalletType.evm instead of individual chain types. - Update configure.dart to generate WalletType.evm in availableWalletTypes - Add filtering checks to prevent old EVM types from appearing * fix: Fix WalletType.evm support and complete remaining edge cases Add missing WalletType.evm cases to switch statements to resolve compilation errors. Complete remaining unification items: - Add WalletType.evm support to node, wallet utils, and view models - Update EVMChainDefaultTokens and EVMChainUtils to support chainId - Fix token initialization and priority fee calculations for WalletType.evm - Update payment view model to handle WalletType.evm with chainId All identified edge cases from the unification plan are now complete. * fix: Fix network switching issues for EVM wallets - Fix null check errors when creating and restoring an EVM wallet - Fix null check errors for balance getter when switching networks - Fix fiat amount display for native currencies in transaction history * refactor: Simplify EVM wallet chain selection in CryptoBalanceWidget - Removed the old dropdown for chain selection and replaced it with a more integrated EvmSwitcher dialog. - Updated EvmSwitcher to accept a list of available chains and handle chain selection more efficiently. - Enhanced EvmSwitcherDataItem to include chainId for better identification of chains. - Improved the overall UI flow for EVM wallet interactions. * refactor: Enhance EVM wallet handling and chainId integration - Simplified chainId checks across various components to ensure consistent handling for WalletType.evm. - Updated EVMChainDefaultTokens and EVMChainUtils checks to allow all EVM wallets for chainId operations - Handled backward compatibility for older wallet types in transaction info * refactor: More enhancement and backward compatibility fixes for EVM Wallet - Introduced a new method to retrieve cryptocurrency by chainId, improving the handling of WalletType.evm. - Updated transaction history management to filter transactions based on the current chainId - Refactored EVMChainTransactionInfo to accept chainId directly - Modified utility functions in EVMChainUtils and TokenUtilities for better chainId handling * refactor: Streamline EVM token retrieval and enhance chainId handling * feat: Introduce comprehensive guide for adding new EVM L2 networks - Added a detailed documentation file outlining the steps to integrate new EVM-compatible L2 networks into Cake Wallet. - Included prerequisites, architecture overview, and a step-by-step guide covering chain configuration, native currency addition, default tokens, and node setup. - Emphasized the unified architecture for EVM chains and backward compatibility considerations. - Removed the outdated guide on adding new L2 networks to streamline documentation. * feat: Reposition EVM switcher button on dashboard page * just adding reminders for the refactoring [skip ci] * more todos [skip ci] * feat: enhance wallet functionality with chainId support - Added chainId to `WalletBase` and updated currency method to use it. - Modified EvmChainRegistry to initialize registry on call. - Updated various components to pass chainId where necessary for currency conversions. - Improved handling of chain IDs in wallet-related view models and UI components for better compatibility with EVM networks. * fix: remove default chainId fallback in payment confirmation widget * feat: Adapt anypay to new unified flow WIP * fix: Issues with handling non evm swaps for anypay * fixes to flow structure * Add persistence to hidden chains on switcher * refactor: simplify equality operator in Erc20Token class * feat: add excluded arbutrum tokens for chainflip * chore: Remove print statement [skip ci] * refactor: dispaly QR image display for evm based on selected chain ID * feat: enhance EVM wallet compatibility check for raw address input * chore: Update doc to reflect changes [skip ci] * feat: Integrate Blink for EVM wallets for anti-sandwich attacks. - Add toggle in privacy settings to enable/disable - When enabled, route all evm broadcast rpc calls via Blink * feat: Integrate Blink for EVM wallets for anti-sandwich attacks. - Add toggle in privacy settings to enable/disable - When enabled, route all evm broadcast rpc calls via Blink * feat: Integrate Blink for EVM wallets for anti-sandwich attacks. - Add toggle in privacy settings to enable/disable - When enabled, route all evm broadcast rpc calls via Blink * feat: Handle same chainId scenario for pasted evm addresses * feat: Add Blink Setting to Advanced Settings Page * fix: Handle Blink supported chains * fix: Fixes to evm swap * fix: Add fallback for currency fetch * fix: Add evm to supported list * fix: Better handle balance errors * fix: Update token check to use contract address comparison, resolves the usdt/usdt0 issue * refactor: Simplify checks by cearing all tokens on chain switch, removing unnecessary currency checks * fix: Simplify checks based from feedback on review * fix: Exclude arbitrum from tx priority using chainId * refactor: Handle chains not having transaction priority within refactor * fix: Unified evm wallet fixes - Handle switching networks while on tx history page - Update NFTs when network is switching on listing page - Fix arbitrum tx priority error on swap screen - Switch check to display deuro from wallet type to chainId - Add fallback check for getting token info for evm - Better error message for max fee per gas less than block base fee error * refactor: Update wallet checks from type to chainId for EVM compatibility checks * refactor: Update eth chain utils and remove verified contract criteria in scam detection checks * refactor: Enhance validation for deuro calls * fix : Remove unneeded validation check for savings edit * feat: Hide EVM chain switcher behind feature flag * refactor: Remove EVM wallet type references and update related logic * chore: Clean up wallet type references and remove repeated imports * feat: Add fallback for derivation path and add arbitrum support to app scripts * fix: NFT popup error * fix: Transaction details fee regression * fix: Fixes and improvements - Add nonce parameter to transaction methods in EVM clients - Remove brackets for create swaps - Display contacts for selected wallettype alone - Remove tx priorty switching for arb * feat: Enhance Arbitrum support across swap providers * fix: Add missing secret keys * fix: display sending currency icon in send from external page * refactor: Handle arbitrum edgecase for wallet list display image * fix: Handle more cases of arbitrum image display for contact book * exploring possible issues with tx history * chore: switch to printV * fix: Add an extra check for keys * fix: Filter out eth spam transaction and modify parsing format * fix: Handle contract decimals for sending tokens * fix: Display proper balance error * Update cw_evm/lib/utils/evm_chain_formatter.dart [skip ci] --------- Co-authored-by: Robert Malikowski <malikowskirobert@gmail.com> Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
1843 lines
68 KiB
Dart
1843 lines
68 KiB
Dart
import 'dart:io';
|
|
|
|
const bitcoinOutputPath = 'lib/bitcoin/bitcoin.dart';
|
|
const moneroOutputPath = 'lib/monero/monero.dart';
|
|
const bitcoinCashOutputPath = 'lib/bitcoin_cash/bitcoin_cash.dart';
|
|
const nanoOutputPath = 'lib/nano/nano.dart';
|
|
const solanaOutputPath = 'lib/solana/solana.dart';
|
|
const tronOutputPath = 'lib/tron/tron.dart';
|
|
const wowneroOutputPath = 'lib/wownero/wownero.dart';
|
|
const zanoOutputPath = 'lib/zano/zano.dart';
|
|
const decredOutputPath = 'lib/decred/decred.dart';
|
|
const dogecoinOutputPath = 'lib/dogecoin/dogecoin.dart';
|
|
const evmOutputPath = 'lib/evm/evm.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 hasEthereum = args.contains('${prefix}ethereum');
|
|
final hasBitcoinCash = args.contains('${prefix}bitcoinCash');
|
|
final hasNano = args.contains('${prefix}nano');
|
|
final hasBanano = args.contains('${prefix}banano');
|
|
final hasPolygon = args.contains('${prefix}polygon');
|
|
final hasSolana = args.contains('${prefix}solana');
|
|
final hasTron = args.contains('${prefix}tron');
|
|
final hasWownero = args.contains('${prefix}wownero');
|
|
final hasZano = args.contains('${prefix}zano');
|
|
final hasDecred = args.contains('${prefix}decred');
|
|
final hasDogecoin = args.contains('${prefix}dogecoin');
|
|
final hasBase = args.contains('${prefix}base');
|
|
final hasArbitrum = args.contains('${prefix}arbitrum');
|
|
final hasEVM = hasEthereum || hasPolygon || hasBase || hasArbitrum;
|
|
final excludeFlutterSecureStorage = args.contains('${prefix}excludeFlutterSecureStorage');
|
|
|
|
await generateBitcoin(hasBitcoin);
|
|
await generateMonero(hasMonero);
|
|
await generateBitcoinCash(hasBitcoinCash);
|
|
await generateNano(hasNano);
|
|
await generateSolana(hasSolana);
|
|
await generateTron(hasTron);
|
|
await generateWownero(hasWownero);
|
|
await generateZano(hasZano);
|
|
// await generateBanano(hasEthereum);
|
|
await generateDecred(hasDecred);
|
|
await generateDogecoin(hasDogecoin);
|
|
await generateEVM(hasEVM);
|
|
|
|
await generatePubspec(
|
|
hasMonero: hasMonero,
|
|
hasBitcoin: hasBitcoin,
|
|
hasEthereum: hasEthereum,
|
|
hasNano: hasNano,
|
|
hasBanano: hasBanano,
|
|
hasBitcoinCash: hasBitcoinCash,
|
|
hasFlutterSecureStorage: !excludeFlutterSecureStorage,
|
|
hasPolygon: hasPolygon,
|
|
hasSolana: hasSolana,
|
|
hasTron: hasTron,
|
|
hasWownero: hasWownero,
|
|
hasZano: hasZano,
|
|
hasDecred: hasDecred,
|
|
hasDogecoin: hasDogecoin,
|
|
hasBase: hasBase,
|
|
hasArbitrum: hasArbitrum,
|
|
);
|
|
await generateWalletTypes(
|
|
hasMonero: hasMonero,
|
|
hasBitcoin: hasBitcoin,
|
|
hasEthereum: hasEthereum,
|
|
hasNano: hasNano,
|
|
hasBanano: hasBanano,
|
|
hasBitcoinCash: hasBitcoinCash,
|
|
hasPolygon: hasPolygon,
|
|
hasSolana: hasSolana,
|
|
hasTron: hasTron,
|
|
hasWownero: hasWownero,
|
|
hasZano: hasZano,
|
|
hasDecred: hasDecred,
|
|
hasDogecoin: hasDogecoin,
|
|
hasBase: hasBase,
|
|
hasArbitrum: hasArbitrum,
|
|
);
|
|
await injectSecureStorage(!excludeFlutterSecureStorage);
|
|
}
|
|
|
|
Future<void> generateBitcoin(bool hasImplementation) async {
|
|
final outputFile = File(bitcoinOutputPath);
|
|
const bitcoinCommonHeaders = """
|
|
import 'dart:io' show Platform;
|
|
import 'dart:typed_data';
|
|
import 'package:bitcoin_base/bitcoin_base.dart';
|
|
import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
|
|
import 'package:cake_wallet/view_model/send/output.dart';
|
|
import 'package:cw_core/hardware/hardware_account_data.dart';
|
|
import 'package:cw_core/hardware/hardware_wallet_service.dart';
|
|
import 'package:cw_core/node.dart';
|
|
import 'package:cw_core/payjoin_session.dart';
|
|
import 'package:cw_core/output_info.dart';
|
|
import 'package:cw_core/pending_transaction.dart';
|
|
import 'package:cw_core/receive_page_option.dart';
|
|
import 'package:cw_core/transaction_info.dart';
|
|
import 'package:cw_core/transaction_priority.dart';
|
|
import 'package:cw_core/unspent_coin_type.dart';
|
|
import 'package:cw_core/unspent_coins_info.dart';
|
|
import 'package:cw_core/unspent_transaction_output.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_core/wallet_type.dart';
|
|
import 'package:cw_core/utils/print_verbose.dart';
|
|
import 'package:cw_core/get_height_by_date.dart';
|
|
import 'package:hive/hive.dart';
|
|
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger;
|
|
import 'package:bitbox_flutter/bitbox_flutter.dart' as bitbox;
|
|
import 'package:trezor_connect/trezor_connect.dart' as trezor;
|
|
import 'package:blockchain_utils/blockchain_utils.dart';
|
|
import 'package:bip39/bip39.dart' as bip39;
|
|
""";
|
|
const bitcoinCWHeaders = """
|
|
import 'package:cw_bitcoin/utils.dart';
|
|
import 'package:cw_bitcoin/electrum_derivations.dart';
|
|
import 'package:cw_bitcoin/electrum.dart';
|
|
import 'package:cw_bitcoin/electrum_transaction_info.dart';
|
|
import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
|
|
import 'package:cw_bitcoin/bitcoin_receive_page_option.dart';
|
|
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_wallet_addresses.dart';
|
|
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
|
|
import 'package:cw_bitcoin/litecoin_wallet_service.dart';
|
|
import 'package:cw_bitcoin/litecoin_wallet.dart';
|
|
import 'package:cw_bitcoin/hardware/bitcoin_ledger_service.dart';
|
|
import 'package:cw_bitcoin/hardware/litecoin_ledger_service.dart';
|
|
import 'package:cw_bitcoin/hardware/bitbox_service.dart';
|
|
import 'package:cw_bitcoin/hardware/trezor_service.dart';
|
|
import 'package:mobx/mobx.dart';
|
|
""";
|
|
const bitcoinCwPart = "part 'cw_bitcoin.dart';";
|
|
const bitcoinContent = """
|
|
|
|
class ElectrumSubAddress {
|
|
ElectrumSubAddress({
|
|
required this.id,
|
|
required this.name,
|
|
required this.address,
|
|
required this.txCount,
|
|
required this.balance,
|
|
required this.isChange});
|
|
final int id;
|
|
final String name;
|
|
final String address;
|
|
final int txCount;
|
|
final int balance;
|
|
final bool isChange;
|
|
}
|
|
|
|
abstract class Bitcoin {
|
|
TransactionPriority getMediumTransactionPriority();
|
|
|
|
WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({
|
|
required String name,
|
|
required String mnemonic,
|
|
required String password,
|
|
required DerivationType derivationType,
|
|
required String derivationPath,
|
|
String? passphrase,
|
|
});
|
|
WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
|
|
WalletCredentials createBitcoinWalletFromKeys({required String name, required String password, required String xpub, HardwareWalletType? hardwareWalletType});
|
|
WalletCredentials createLitecoinWalletFromKeys({required String name, required String password, required String xpub, required String scanSecret, required String spendPubkey});
|
|
WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic});
|
|
WalletCredentials createBitcoinHardwareWalletCredentials({required String name, required HardwareAccountData accountData, WalletInfo? walletInfo});
|
|
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, String label);
|
|
Future<void> updateAddress(Object wallet,String address, String label);
|
|
Object createBitcoinTransactionCredentials(List<Output> outputs, {required TransactionPriority priority, int? feeRate, UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any, String? payjoinUri});
|
|
|
|
String getAddress(Object wallet);
|
|
List<ElectrumSubAddress> getSilentPaymentAddresses(Object wallet);
|
|
List<ElectrumSubAddress> getSilentPaymentReceivedAddresses(Object wallet);
|
|
|
|
Future<int> estimateFakeSendAllTxAmount(Object wallet, TransactionPriority priority,
|
|
{UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any});
|
|
List<ElectrumSubAddress> getSubAddresses(Object wallet);
|
|
|
|
String formatterBitcoinAmountToString({required int amount});
|
|
double formatterBitcoinAmountToDouble({required int amount});
|
|
int formatterStringDoubleToBitcoinAmount(String amount);
|
|
String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate, {int? customRate});
|
|
|
|
List<Unspent> getUnspents(Object wallet, {UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any});
|
|
Future<void> updateUnspents(Object wallet);
|
|
WalletService createBitcoinWalletService(
|
|
Box<UnspentCoinsInfo> unspentCoinSource, Box<PayjoinSession> payjoinSessionSource, bool isDirect);
|
|
WalletService createLitecoinWalletService(Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
|
|
TransactionPriority getBitcoinTransactionPriorityMedium();
|
|
TransactionPriority getBitcoinTransactionPriorityCustom();
|
|
TransactionPriority getLitecoinTransactionPriorityMedium();
|
|
TransactionPriority getBitcoinTransactionPrioritySlow();
|
|
TransactionPriority getLitecoinTransactionPrioritySlow();
|
|
Future<List<DerivationType>> compareDerivationMethods(
|
|
{required String mnemonic, required Node node});
|
|
Future<List<DerivationInfo>> getDerivationsFromMnemonic(
|
|
{required String mnemonic, required Node node, String? passphrase});
|
|
Map<DerivationType, List<DerivationInfo>> getElectrumDerivations();
|
|
Future<void> setAddressType(Object wallet, dynamic option);
|
|
ReceivePageOption getSelectedAddressType(Object wallet);
|
|
List<ReceivePageOption> getBitcoinReceivePageOptions(Object wallet);
|
|
List<ReceivePageOption> getLitecoinReceivePageOptions(Object wallet);
|
|
BitcoinAddressType getBitcoinAddressType(ReceivePageOption option);
|
|
bool isPayjoinAvailable(Object wallet);
|
|
bool hasSelectedSilentPayments(Object wallet);
|
|
bool isBitcoinReceivePageOption(ReceivePageOption option);
|
|
BitcoinAddressType getOptionToType(ReceivePageOption option);
|
|
bool hasTaprootInput(PendingTransaction pendingTransaction);
|
|
bool getScanningActive(Object wallet);
|
|
Future<void> setScanningActive(Object wallet, bool active);
|
|
Future<void> setIsAlwaysScanningSP(Object wallet, bool active);
|
|
bool getIsAlwaysScanningSP(Object wallet);
|
|
bool isTestnet(Object wallet);
|
|
|
|
Future<PendingTransaction> replaceByFee(Object wallet, String transactionHash, String fee);
|
|
Future<String?> canReplaceByFee(Object wallet, Object tx);
|
|
int getTransactionVSize(Object wallet, String txHex);
|
|
Future<bool> isChangeSufficientForFee(Object wallet, String txId, String newFee);
|
|
int getFeeAmountForPriority(Object wallet, TransactionPriority priority, int inputsCount, int outputsCount, {int? size});
|
|
int getEstimatedFeeWithFeeRate(Object wallet, int feeRate, int? amount,
|
|
{int? outputsCount, int? size});
|
|
int feeAmountWithFeeRate(Object wallet, int feeRate, int inputsCount, int outputsCount, {int? size});
|
|
Future<bool> checkIfMempoolAPIIsEnabled(Object wallet);
|
|
Future<int> getHeightByDate({required DateTime date, bool? bitcoinMempoolAPIEnabled});
|
|
int getLitecoinHeightByDate({required DateTime date});
|
|
Future<void> rescan(Object wallet, {required int height, bool? doSingleScan});
|
|
Future<bool> getNodeIsElectrsSPEnabled(Object wallet);
|
|
void deleteSilentPaymentAddress(Object wallet, String address);
|
|
Future<void> updateFeeRates(Object wallet);
|
|
int getMaxCustomFeeRate(Object wallet);
|
|
Future<void> setHardwareWalletService(WalletBase wallet, HardwareWalletService service);
|
|
HardwareWalletService getLedgerHardwareWalletService(ledger.LedgerConnection connection, bool isBitcoin);
|
|
HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxManager manager, bool isBitcoin);
|
|
HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect connect, bool isBitcoin);
|
|
List<Output> updateOutputs(PendingTransaction pendingTransaction, List<Output> outputs);
|
|
bool txIsReceivedSilentPayment(TransactionInfo txInfo);
|
|
bool txIsMweb(TransactionInfo txInfo);
|
|
Future<void> setMwebEnabled(Object wallet, bool enabled);
|
|
bool getMwebEnabled(Object wallet);
|
|
String? getUnusedMwebAddress(Object wallet);
|
|
String? getUnusedSegwitAddress(Object wallet);
|
|
Future<void> commitPsbtUR(Object wallet, List<String> urCodes);
|
|
|
|
void updatePayjoinState(Object wallet, bool state);
|
|
String getPayjoinEndpoint(Object wallet);
|
|
void resumePayjoinSessions(Object wallet);
|
|
void stopPayjoinSessions(Object wallet);
|
|
Map<String, String> getSilentPaymentKeys(Object wallet);
|
|
List<String>? getTransactionAddresses(Object wallet, TransactionInfo tx);
|
|
}
|
|
""";
|
|
|
|
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:cw_core/unspent_transaction_output.dart';
|
|
import 'package:cw_core/unspent_coins_info.dart';
|
|
import 'package:mobx/mobx.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:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger;
|
|
import 'package:polyseed/polyseed.dart';""";
|
|
const moneroCWHeaders = """
|
|
import 'package:cw_core/account.dart' as monero_account;
|
|
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/api/wallet_manager.dart';
|
|
import 'package:cw_monero/api/wallet.dart' as monero_wallet_api;
|
|
import 'package:cw_monero/ledger.dart';
|
|
import 'package:cw_monero/monero_unspent.dart';
|
|
import 'package:cw_monero/api/account_list.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_creation_credentials.dart';
|
|
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,
|
|
required this.received,
|
|
required this.txCount});
|
|
final int id;
|
|
final String label;
|
|
final String address;
|
|
final String? received;
|
|
final int txCount;
|
|
}
|
|
|
|
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 getHeightByDate({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);
|
|
Future<void> updateUnspents(Object wallet);
|
|
|
|
Future<int> getCurrentHeight();
|
|
|
|
Future<bool> commitTransactionUR(Object wallet, String ur);
|
|
|
|
Map<String, String> exportOutputsUR(Object wallet);
|
|
|
|
bool needExportOutputs(Object wallet, int amount);
|
|
|
|
bool importKeyImagesUR(Object wallet, String ur);
|
|
|
|
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 String passphrase, required int height, required String mnemonic});
|
|
WalletCredentials createMoneroRestoreWalletFromHardwareCredentials({required String name, required String password, required int height, required ledger.LedgerConnection ledgerConnection});
|
|
WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, required int seedType, required String? passphrase, String? password, String? mnemonic});
|
|
Map<String, String> getKeys(Object wallet);
|
|
int? getRestoreHeight(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 monerocCheck();
|
|
bool isViewOnly();
|
|
void setCurrentAccount(Object wallet, int id, String label, String? balance);
|
|
void onStartup();
|
|
int getTransactionInfoAccountId(TransactionInfo tx);
|
|
WalletService createMoneroWalletService(Box<UnspentCoinsInfo> unspentCoinSource);
|
|
Map<String, String> pendingTransactionInfo(Object transaction);
|
|
Future<void> setLedgerConnection(Object wallet, ledger.LedgerConnection connection);
|
|
void resetLedgerConnection();
|
|
void setGlobalLedgerConnection(ledger.LedgerConnection connection);
|
|
String? getLastLedgerCommand();
|
|
Map<String, List<int>> debugCallLength();
|
|
Map<String, dynamic> getWalletCacheDebug();
|
|
}
|
|
|
|
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> generateWownero(bool hasImplementation) async {
|
|
final outputFile = File(wowneroOutputPath);
|
|
const wowneroCommonHeaders = """
|
|
import 'package:cw_core/unspent_transaction_output.dart';
|
|
import 'package:cw_core/unspent_coins_info.dart';
|
|
import 'package:mobx/mobx.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/crypto_currency.dart';
|
|
import 'package:cake_wallet/core/key_service.dart';
|
|
import 'package:cake_wallet/core/secure_storage.dart';
|
|
import 'package:cake_wallet/entities/haven_seed_store.dart';
|
|
import 'package:cw_core/cake_hive.dart';
|
|
import 'package:cw_core/wallet_info.dart';
|
|
import 'package:cw_core/wallet_type.dart';
|
|
import 'package:cw_core/wallet_service.dart';
|
|
import 'package:hive/hive.dart';
|
|
import 'package:polyseed/polyseed.dart';""";
|
|
const wowneroCWHeaders = """
|
|
import 'package:cw_core/get_height_by_date.dart';
|
|
import 'package:cw_core/wownero_amount_format.dart';
|
|
import 'package:cw_core/monero_transaction_priority.dart';
|
|
import 'package:cw_wownero/wownero_unspent.dart';
|
|
import 'package:cw_wownero/wownero_wallet_service.dart';
|
|
import 'package:cw_wownero/wownero_wallet.dart';
|
|
import 'package:cw_wownero/wownero_transaction_info.dart';
|
|
import 'package:cw_wownero/wownero_transaction_creation_credentials.dart';
|
|
import 'package:cw_core/account.dart' as wownero_account;
|
|
import 'package:cw_wownero/api/wallet.dart' as wownero_wallet_api;
|
|
import 'package:cw_wownero/api/wallet_manager.dart';
|
|
import 'package:cw_wownero/mnemonics/english.dart';
|
|
import 'package:cw_wownero/mnemonics/chinese_simplified.dart';
|
|
import 'package:cw_wownero/mnemonics/dutch.dart';
|
|
import 'package:cw_wownero/mnemonics/german.dart';
|
|
import 'package:cw_wownero/mnemonics/japanese.dart';
|
|
import 'package:cw_wownero/mnemonics/russian.dart';
|
|
import 'package:cw_wownero/mnemonics/spanish.dart';
|
|
import 'package:cw_wownero/mnemonics/portuguese.dart';
|
|
import 'package:cw_wownero/mnemonics/french.dart';
|
|
import 'package:cw_wownero/mnemonics/italian.dart';
|
|
import 'package:cw_wownero/pending_wownero_transaction.dart';
|
|
""";
|
|
const wowneroCwPart = "part 'cw_wownero.dart';";
|
|
const wowneroContent = """
|
|
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 WowneroBalance extends Balance {
|
|
WowneroBalance({required this.fullBalance, required this.unlockedBalance})
|
|
: formattedFullBalance = wownero!.formatterWowneroAmountToString(amount: fullBalance),
|
|
formattedUnlockedBalance =
|
|
wownero!.formatterWowneroAmountToString(amount: unlockedBalance),
|
|
super(unlockedBalance, fullBalance);
|
|
|
|
WowneroBalance.fromString(
|
|
{required this.formattedFullBalance,
|
|
required this.formattedUnlockedBalance})
|
|
: fullBalance = wownero!.formatterWowneroParseAmount(amount: formattedFullBalance),
|
|
unlockedBalance = wownero!.formatterWowneroParseAmount(amount: formattedUnlockedBalance),
|
|
super(wownero!.formatterWowneroParseAmount(amount: formattedUnlockedBalance),
|
|
wownero!.formatterWowneroParseAmount(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 WowneroWalletDetails {
|
|
@observable
|
|
late Account account;
|
|
|
|
@observable
|
|
late WowneroBalance balance;
|
|
}
|
|
|
|
abstract class Wownero {
|
|
WowneroAccountList getAccountList(Object wallet);
|
|
|
|
WowneroSubaddressList getSubaddressList(Object wallet);
|
|
|
|
TransactionHistoryBase getTransactionHistory(Object wallet);
|
|
|
|
WowneroWalletDetails getWowneroWalletDetails(Object wallet);
|
|
|
|
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex);
|
|
|
|
String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex);
|
|
|
|
int getHeightByDate({required DateTime date});
|
|
TransactionPriority getDefaultTransactionPriority();
|
|
TransactionPriority getWowneroTransactionPrioritySlow();
|
|
TransactionPriority getWowneroTransactionPriorityAutomatic();
|
|
TransactionPriority deserializeWowneroTransactionPriority({required int raw});
|
|
List<TransactionPriority> getTransactionPriorities();
|
|
List<String> getWowneroWordList(String language);
|
|
|
|
List<Unspent> getUnspents(Object wallet);
|
|
Future<void> updateUnspents(Object wallet);
|
|
|
|
Future<int> getCurrentHeight();
|
|
void wownerocCheck();
|
|
|
|
WalletCredentials createWowneroRestoreWalletFromKeysCredentials({
|
|
required String name,
|
|
required String spendKey,
|
|
required String viewKey,
|
|
required String address,
|
|
required String password,
|
|
required String language,
|
|
required int height});
|
|
WalletCredentials createWowneroRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic});
|
|
WalletCredentials createWowneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String? password, String? passphrase});
|
|
int? getRestoreHeight(Object wallet);
|
|
Map<String, String> getKeys(Object wallet);
|
|
Object createWowneroTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority});
|
|
Object createWowneroTransactionCreationCredentialsRaw({required List<OutputInfo> outputs, required TransactionPriority priority});
|
|
String formatterWowneroAmountToString({required int amount});
|
|
double formatterWowneroAmountToDouble({required int amount});
|
|
int formatterWowneroParseAmount({required String amount});
|
|
Account getCurrentAccount(Object wallet);
|
|
void setCurrentAccount(Object wallet, int id, String label, String? balance);
|
|
void onStartup();
|
|
int getTransactionInfoAccountId(TransactionInfo tx);
|
|
WalletService createWowneroWalletService(Box<UnspentCoinsInfo> unspentCoinSource);
|
|
Map<String, String> pendingTransactionInfo(Object transaction);
|
|
String getLegacySeed(Object wallet, String langName);
|
|
Map<String, List<int>> debugCallLength();
|
|
Future<void> backupSeeds(Box<HavenSeedStore> havenSeedStore);
|
|
}
|
|
|
|
abstract class WowneroSubaddressList {
|
|
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 WowneroAccountList {
|
|
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 wowneroEmptyDefinition = 'Wownero? wownero;\n';
|
|
const wowneroCWDefinition = 'Wownero? wownero = CWWownero();\n';
|
|
|
|
final output = '$wowneroCommonHeaders\n' +
|
|
(hasImplementation ? '$wowneroCWHeaders\n' : '\n') +
|
|
(hasImplementation ? '$wowneroCwPart\n\n' : '\n') +
|
|
(hasImplementation ? wowneroCWDefinition : wowneroEmptyDefinition) +
|
|
'\n' +
|
|
wowneroContent;
|
|
|
|
if (outputFile.existsSync()) {
|
|
await outputFile.delete();
|
|
}
|
|
|
|
await outputFile.writeAsString(output);
|
|
}
|
|
|
|
Future<void> generateBitcoinCash(bool hasImplementation) async {
|
|
final outputFile = File(bitcoinCashOutputPath);
|
|
const bitcoinCashCommonHeaders = """
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:cw_core/unspent_transaction_output.dart';
|
|
import 'package:cw_core/transaction_priority.dart';
|
|
import 'package:cw_core/unspent_coins_info.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 bitcoinCashCWHeaders = """
|
|
import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart';
|
|
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
|
""";
|
|
const bitcoinCashCwPart = "part 'cw_bitcoin_cash.dart';";
|
|
const bitcoinCashContent = """
|
|
abstract class BitcoinCash {
|
|
String getCashAddrFormat(String address);
|
|
|
|
WalletService createBitcoinCashWalletService(
|
|
Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
|
|
|
|
WalletCredentials createBitcoinCashNewWalletCredentials(
|
|
{required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic});
|
|
|
|
WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
|
|
{required String name, required String mnemonic, required String password, String? passphrase});
|
|
|
|
TransactionPriority deserializeBitcoinCashTransactionPriority(int raw);
|
|
|
|
TransactionPriority getDefaultTransactionPriority();
|
|
|
|
List<TransactionPriority> getTransactionPriorities();
|
|
|
|
TransactionPriority getBitcoinCashTransactionPrioritySlow();
|
|
}
|
|
""";
|
|
|
|
const bitcoinCashEmptyDefinition = 'BitcoinCash? bitcoinCash;\n';
|
|
const bitcoinCashCWDefinition = 'BitcoinCash? bitcoinCash = CWBitcoinCash();\n';
|
|
|
|
final output = '$bitcoinCashCommonHeaders\n' +
|
|
(hasImplementation ? '$bitcoinCashCWHeaders\n' : '\n') +
|
|
(hasImplementation ? '$bitcoinCashCwPart\n\n' : '\n') +
|
|
(hasImplementation ? bitcoinCashCWDefinition : bitcoinCashEmptyDefinition) +
|
|
'\n' +
|
|
bitcoinCashContent;
|
|
|
|
if (outputFile.existsSync()) {
|
|
await outputFile.delete();
|
|
}
|
|
|
|
await outputFile.writeAsString(output);
|
|
}
|
|
|
|
Future<void> generateNano(bool hasImplementation) async {
|
|
final outputFile = File(nanoOutputPath);
|
|
const nanoCommonHeaders = """
|
|
import 'package:cw_core/cake_hive.dart';
|
|
import 'package:cw_core/nano_account.dart';
|
|
import 'package:cw_core/account.dart';
|
|
import 'package:cw_core/node.dart';
|
|
import 'package:cw_core/wallet_credentials.dart';
|
|
import 'package:cw_core/wallet_info.dart';
|
|
import 'package:cw_core/transaction_info.dart';
|
|
import 'package:cw_core/transaction_history.dart';
|
|
import 'package:cw_core/wallet_service.dart';
|
|
import 'package:cw_core/output_info.dart';
|
|
import 'package:cw_core/nano_account_info_response.dart';
|
|
import 'package:cw_core/n2_node.dart';
|
|
import 'package:cw_core/utils/print_verbose.dart';
|
|
import 'package:mobx/mobx.dart';
|
|
import 'package:hive/hive.dart';
|
|
import 'package:cake_wallet/view_model/send/output.dart';
|
|
""";
|
|
const nanoCWHeaders = """
|
|
import 'package:cw_nano/nano_client.dart';
|
|
import 'package:cw_nano/nano_mnemonic.dart';
|
|
import 'package:cw_nano/nano_wallet.dart';
|
|
import 'package:cw_nano/nano_wallet_service.dart';
|
|
import 'package:cw_nano/nano_transaction_info.dart';
|
|
import 'package:cw_nano/nano_transaction_credentials.dart';
|
|
import 'package:cw_nano/nano_wallet_creation_credentials.dart';
|
|
// needed for nano_util:
|
|
import 'dart:convert';
|
|
import 'dart:typed_data';
|
|
import 'package:convert/convert.dart';
|
|
import "package:ed25519_hd_key/ed25519_hd_key.dart";
|
|
import 'package:libcrypto/libcrypto.dart';
|
|
import 'package:nanodart/nanodart.dart' as ND;
|
|
import 'package:nanoutil/nanoutil.dart';
|
|
""";
|
|
const nanoCwPart = "part 'cw_nano.dart';";
|
|
const nanoContent = """
|
|
abstract class Nano {
|
|
NanoAccountList getAccountList(Object wallet);
|
|
|
|
Account getCurrentAccount(Object wallet);
|
|
|
|
void setCurrentAccount(Object wallet, int id, String label, String? balance);
|
|
|
|
WalletService createNanoWalletService(bool isDirect);
|
|
|
|
WalletCredentials createNanoNewWalletCredentials({
|
|
required String name,
|
|
String? password,
|
|
String? mnemonic,
|
|
WalletInfo? walletInfo,
|
|
String? passphrase,
|
|
});
|
|
|
|
WalletCredentials createNanoRestoreWalletFromSeedCredentials({
|
|
required String name,
|
|
required String password,
|
|
required String mnemonic,
|
|
required DerivationType derivationType,
|
|
String? passphrase,
|
|
});
|
|
|
|
WalletCredentials createNanoRestoreWalletFromKeysCredentials({
|
|
required String name,
|
|
required String password,
|
|
required String seedKey,
|
|
required DerivationType derivationType,
|
|
});
|
|
|
|
List<String> getNanoWordList(String language);
|
|
Map<String, String> getKeys(Object wallet);
|
|
Object createNanoTransactionCredentials(List<Output> outputs);
|
|
Future<void> changeRep(Object wallet, String address);
|
|
Future<bool> updateTransactions(Object wallet);
|
|
BigInt getTransactionAmountRaw(TransactionInfo transactionInfo);
|
|
String getRepresentative(Object wallet);
|
|
Future<List<N2Node>> getN2Reps(Object wallet);
|
|
bool isRepOk(Object wallet);
|
|
}
|
|
|
|
abstract class NanoAccountList {
|
|
ObservableList<NanoAccount> get accounts;
|
|
void update(Object wallet);
|
|
void refresh(Object wallet);
|
|
Future<List<NanoAccount>> getAll(Object wallet);
|
|
Future<void> addAccount(Object wallet, {required String label});
|
|
Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label});
|
|
}
|
|
|
|
abstract class NanoUtil {
|
|
bool isValidBip39Seed(String seed);
|
|
static const int maxDecimalDigits = 6; // Max digits after decimal
|
|
BigInt rawPerNano = BigInt.parse("1000000000000000000000000000000");
|
|
BigInt rawPerNyano = BigInt.parse("1000000000000000000000000");
|
|
BigInt rawPerBanano = BigInt.parse("100000000000000000000000000000");
|
|
BigInt rawPerXMR = BigInt.parse("1000000000000");
|
|
BigInt convertXMRtoNano = BigInt.parse("1000000000000000000");
|
|
String getRawAsUsableString(String? raw, BigInt rawPerCur);
|
|
String getRawAccuracy(String? raw, BigInt rawPerCur);
|
|
String getAmountAsRaw(String amount, BigInt rawPerCur);
|
|
|
|
// derivationInfo:
|
|
Future<AccountInfoResponse?> getInfoFromSeedOrMnemonic(
|
|
DerivationType derivationType, {
|
|
String? seedKey,
|
|
String? mnemonic,
|
|
required Node node,
|
|
});
|
|
Future<List<DerivationType>> compareDerivationMethods({
|
|
String? mnemonic,
|
|
String? privateKey,
|
|
required Node node,
|
|
});
|
|
Future<List<DerivationInfo>> getDerivationsFromMnemonic({
|
|
String? mnemonic,
|
|
String? seedKey,
|
|
required Node node,
|
|
});
|
|
}
|
|
""";
|
|
|
|
const nanoEmptyDefinition = 'Nano? nano;\nNanoUtil? nanoUtil;\n';
|
|
const nanoCWDefinition = 'Nano? nano = CWNano();\nNanoUtil? nanoUtil = CWNanoUtil();\n';
|
|
|
|
final output = '$nanoCommonHeaders\n' +
|
|
(hasImplementation ? '$nanoCWHeaders\n' : '\n') +
|
|
(hasImplementation ? '$nanoCwPart\n\n' : '\n') +
|
|
(hasImplementation ? nanoCWDefinition : nanoEmptyDefinition) +
|
|
'\n' +
|
|
nanoContent;
|
|
|
|
if (outputFile.existsSync()) {
|
|
await outputFile.delete();
|
|
}
|
|
|
|
await outputFile.writeAsString(output);
|
|
}
|
|
|
|
Future<void> generateSolana(bool hasImplementation) async {
|
|
final outputFile = File(solanaOutputPath);
|
|
const solanaCommonHeaders = """
|
|
import 'package:cake_wallet/view_model/send/output.dart';
|
|
import 'package:cw_core/crypto_currency.dart';
|
|
import 'package:cw_core/output_info.dart';
|
|
import 'package:cw_core/transaction_info.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_core/spl_token.dart';
|
|
import 'package:hive/hive.dart';
|
|
|
|
""";
|
|
const solanaCWHeaders = """
|
|
import 'package:cw_solana/solana_wallet.dart';
|
|
import 'package:cw_solana/solana_mnemonics.dart';
|
|
import 'package:cw_solana/solana_wallet_service.dart';
|
|
import 'package:cw_solana/solana_transaction_info.dart';
|
|
import 'package:cw_solana/solana_transaction_credentials.dart';
|
|
import 'package:cw_solana/solana_wallet_creation_credentials.dart';
|
|
import 'package:cw_solana/default_spl_tokens.dart';
|
|
""";
|
|
const solanaCwPart = "part 'cw_solana.dart';";
|
|
const solanaContent = """
|
|
abstract class Solana {
|
|
List<String> getSolanaWordList(String language);
|
|
WalletService createSolanaWalletService(bool isDirect);
|
|
WalletCredentials createSolanaNewWalletCredentials(
|
|
{required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? passphrase});
|
|
WalletCredentials createSolanaRestoreWalletFromSeedCredentials(
|
|
{required String name, required String mnemonic, required String password, String? passphrase});
|
|
WalletCredentials createSolanaRestoreWalletFromPrivateKey(
|
|
{required String name, required String privateKey, required String password});
|
|
|
|
String getAddress(WalletBase wallet);
|
|
String getPrivateKey(WalletBase wallet);
|
|
String getPublicKey(WalletBase wallet);
|
|
|
|
Object createSolanaTransactionCredentials(
|
|
List<Output> outputs, {
|
|
required CryptoCurrency currency,
|
|
});
|
|
|
|
Object createSolanaTransactionCredentialsRaw(
|
|
List<OutputInfo> outputs, {
|
|
required CryptoCurrency currency,
|
|
});
|
|
List<CryptoCurrency> getSPLTokenCurrencies(WalletBase wallet);
|
|
Future<void> addSPLToken(
|
|
WalletBase wallet,
|
|
CryptoCurrency token,
|
|
String contractAddress,
|
|
);
|
|
Future<void> deleteSPLToken(WalletBase wallet, CryptoCurrency token);
|
|
Future<CryptoCurrency?> getSPLToken(WalletBase wallet, String contractAddress);
|
|
|
|
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction);
|
|
double getTransactionAmountRaw(TransactionInfo transactionInfo);
|
|
String getTokenAddress(CryptoCurrency asset);
|
|
List<int>? getValidationLength(CryptoCurrency type);
|
|
double? getEstimateFees(WalletBase wallet);
|
|
List<String> getDefaultTokenContractAddresses();
|
|
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress);
|
|
}
|
|
|
|
""";
|
|
|
|
const solanaEmptyDefinition = 'Solana? solana;\n';
|
|
const solanaCWDefinition = 'Solana? solana = CWSolana();\n';
|
|
|
|
final output = '$solanaCommonHeaders\n' +
|
|
(hasImplementation ? '$solanaCWHeaders\n' : '\n') +
|
|
(hasImplementation ? '$solanaCwPart\n\n' : '\n') +
|
|
(hasImplementation ? solanaCWDefinition : solanaEmptyDefinition) +
|
|
'\n' +
|
|
solanaContent;
|
|
|
|
if (outputFile.existsSync()) {
|
|
await outputFile.delete();
|
|
}
|
|
|
|
await outputFile.writeAsString(output);
|
|
}
|
|
|
|
Future<void> generateTron(bool hasImplementation) async {
|
|
final outputFile = File(tronOutputPath);
|
|
const tronCommonHeaders = """
|
|
import 'package:cake_wallet/view_model/send/output.dart';
|
|
import 'package:cw_core/crypto_currency.dart';
|
|
import 'package:cw_core/output_info.dart';
|
|
import 'package:cw_core/transaction_info.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_core/tron_token.dart';
|
|
import 'package:hive/hive.dart';
|
|
|
|
""";
|
|
const tronCWHeaders = """
|
|
import 'package:cw_evm/evm_chain_mnemonics.dart';
|
|
import 'package:cw_tron/tron_transaction_credentials.dart';
|
|
import 'package:cw_tron/tron_transaction_info.dart';
|
|
import 'package:cw_tron/tron_wallet_creation_credentials.dart';
|
|
|
|
import 'package:cw_tron/tron_client.dart';
|
|
import 'package:cw_tron/tron_wallet.dart';
|
|
import 'package:cw_tron/tron_wallet_service.dart';
|
|
import 'package:cw_tron/default_tron_tokens.dart';
|
|
|
|
""";
|
|
const tronCwPart = "part 'cw_tron.dart';";
|
|
const tronContent = """
|
|
abstract class Tron {
|
|
List<String> getTronWordList(String language);
|
|
WalletService createTronWalletService(bool isDirect);
|
|
WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? passphrase});
|
|
WalletCredentials createTronRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
|
|
WalletCredentials createTronRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
|
|
String getAddress(WalletBase wallet);
|
|
|
|
Object createTronTransactionCredentials(
|
|
List<Output> outputs, {
|
|
required CryptoCurrency currency,
|
|
});
|
|
|
|
List<CryptoCurrency> getTronTokenCurrencies(WalletBase wallet);
|
|
Future<void> addTronToken(WalletBase wallet, CryptoCurrency token, String contractAddress);
|
|
Future<void> deleteTronToken(WalletBase wallet, CryptoCurrency token);
|
|
Future<CryptoCurrency?> getTronToken(WalletBase wallet, String contractAddress);
|
|
|
|
double getTransactionAmountRaw(TransactionInfo transactionInfo);
|
|
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction);
|
|
String getTokenAddress(CryptoCurrency asset);
|
|
String getTronBase58Address(String hexAddress, WalletBase wallet);
|
|
|
|
String? getTronNativeEstimatedFee(WalletBase wallet);
|
|
String? getTronTRC20EstimatedFee(WalletBase wallet);
|
|
|
|
void updateTronGridUsageState(WalletBase wallet, bool isEnabled);
|
|
List<String> getDefaultTokenContractAddresses();
|
|
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress);
|
|
}
|
|
""";
|
|
|
|
const tronEmptyDefinition = 'Tron? tron;\n';
|
|
const tronCWDefinition = 'Tron? tron = CWTron();\n';
|
|
|
|
final output = '$tronCommonHeaders\n' +
|
|
(hasImplementation ? '$tronCWHeaders\n' : '\n') +
|
|
(hasImplementation ? '$tronCwPart\n\n' : '\n') +
|
|
(hasImplementation ? tronCWDefinition : tronEmptyDefinition) +
|
|
'\n' +
|
|
tronContent;
|
|
|
|
if (outputFile.existsSync()) {
|
|
await outputFile.delete();
|
|
}
|
|
|
|
await outputFile.writeAsString(output);
|
|
}
|
|
|
|
Future<void> generateZano(bool hasImplementation) async {
|
|
final outputFile = File(zanoOutputPath);
|
|
const zanoCommonHeaders = """
|
|
import 'package:cake_wallet/utils/language_list.dart';
|
|
import 'package:cake_wallet/view_model/send/output.dart';
|
|
import 'package:collection/collection.dart';
|
|
import 'package:cw_core/crypto_currency.dart';
|
|
import 'package:cw_core/monero_transaction_priority.dart';
|
|
import 'package:cw_core/output_info.dart';
|
|
import 'package:cw_core/transaction_history.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_core/zano_asset.dart';
|
|
import 'package:hive/hive.dart';
|
|
""";
|
|
const zanoCWHeaders = """
|
|
import 'package:cw_zano/mnemonics/english.dart';
|
|
import 'package:cw_zano/model/zano_transaction_credentials.dart';
|
|
import 'package:cw_zano/model/zano_transaction_info.dart';
|
|
import 'package:cw_zano/zano_formatter.dart';
|
|
import 'package:cw_zano/zano_wallet.dart';
|
|
import 'package:cw_zano/zano_wallet_service.dart';
|
|
import 'package:cw_zano/zano_wallet_api.dart' as api;
|
|
import 'package:cw_zano/zano_utils.dart';
|
|
""";
|
|
const zanoCwPart = "part 'cw_zano.dart';";
|
|
const zanoContent = """
|
|
abstract class Zano {
|
|
TransactionPriority getDefaultTransactionPriority();
|
|
TransactionPriority deserializeMoneroTransactionPriority({required int raw});
|
|
List<TransactionPriority> getTransactionPriorities();
|
|
List<String> getWordList(String language);
|
|
|
|
WalletCredentials createZanoRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic});
|
|
WalletCredentials createZanoNewWalletCredentials({required String name, required String? password, required String? passphrase});
|
|
Map<String, String> getKeys(Object wallet);
|
|
Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency});
|
|
double formatterIntAmountToDouble({required int amount, required CryptoCurrency currency, required bool forFee});
|
|
int formatterParseAmount({required String amount, required CryptoCurrency currency});
|
|
WalletService createZanoWalletService();
|
|
CryptoCurrency? assetOfTransaction(WalletBase wallet, TransactionInfo tx);
|
|
List<ZanoAsset> getZanoAssets(WalletBase wallet);
|
|
String getZanoAssetAddress(CryptoCurrency asset);
|
|
Future<void> changeZanoAssetAvailability(WalletBase wallet, CryptoCurrency token);
|
|
Future<CryptoCurrency> addZanoAssetById(WalletBase wallet, String assetId);
|
|
Future<void> deleteZanoAsset(WalletBase wallet, CryptoCurrency token);
|
|
Future<CryptoCurrency?> getZanoAsset(WalletBase wallet, String contractAddress);
|
|
String getAddress(WalletBase wallet);
|
|
bool validateAddress(String address);
|
|
Map<String, List<int>> debugCallLength();
|
|
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress);
|
|
}
|
|
""";
|
|
const zanoEmptyDefinition = 'Zano? zano;\n';
|
|
const zanoCWDefinition = 'Zano? zano = CWZano();\n';
|
|
|
|
final output = '$zanoCommonHeaders\n' +
|
|
(hasImplementation ? '$zanoCWHeaders\n' : '\n') +
|
|
(hasImplementation ? '$zanoCwPart\n\n' : '\n') +
|
|
(hasImplementation ? zanoCWDefinition : zanoEmptyDefinition) +
|
|
'\n' +
|
|
zanoContent;
|
|
|
|
if (outputFile.existsSync()) {
|
|
await outputFile.delete();
|
|
}
|
|
|
|
await outputFile.writeAsString(output);
|
|
}
|
|
|
|
Future<void> generateDecred(bool hasImplementation) async {
|
|
final outputFile = File(decredOutputPath);
|
|
const decredCommonHeaders = """
|
|
import 'package:cw_core/wallet_credentials.dart';
|
|
import 'package:cw_core/address_info.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/wallet_service.dart';
|
|
import 'package:cw_core/unspent_transaction_output.dart';
|
|
import 'package:cw_core/unspent_coins_info.dart';
|
|
import 'package:cake_wallet/view_model/send/output.dart';
|
|
import 'package:hive/hive.dart';
|
|
""";
|
|
const decredCWHeaders = """
|
|
import 'package:cw_decred/transaction_priority.dart';
|
|
import 'package:cw_decred/wallet.dart';
|
|
import 'package:cw_decred/wallet_service.dart';
|
|
import 'package:cw_decred/wallet_creation_credentials.dart';
|
|
import 'package:cw_decred/amount_format.dart';
|
|
import 'package:cw_decred/transaction_credentials.dart';
|
|
import 'package:cw_decred/mnemonic.dart';
|
|
""";
|
|
const decredCwPart = "part 'cw_decred.dart';";
|
|
const decredContent = """
|
|
|
|
abstract class Decred {
|
|
WalletCredentials createDecredNewWalletCredentials(
|
|
{required String name, WalletInfo? walletInfo});
|
|
WalletCredentials createDecredRestoreWalletFromSeedCredentials(
|
|
{required String name, required String mnemonic, required String password});
|
|
WalletCredentials createDecredRestoreWalletFromPubkeyCredentials(
|
|
{required String name, required String pubkey, required String password});
|
|
WalletService createDecredWalletService(Box<UnspentCoinsInfo> unspentCoinSource);
|
|
|
|
List<TransactionPriority> getTransactionPriorities();
|
|
TransactionPriority getDecredTransactionPriorityMedium();
|
|
TransactionPriority getDecredTransactionPrioritySlow();
|
|
TransactionPriority deserializeDecredTransactionPriority(int raw);
|
|
|
|
Object createDecredTransactionCredentials(List<Output> outputs, TransactionPriority priority);
|
|
|
|
List<WalletInfoAddressInfo> getAddressInfos(Object wallet);
|
|
Future<void> updateAddress(Object wallet, String address, String label);
|
|
Future<void> generateNewAddress(Object wallet, String label);
|
|
|
|
String formatterDecredAmountToString({required int amount});
|
|
double formatterDecredAmountToDouble({required int amount});
|
|
int formatterStringDoubleToDecredAmount(String amount);
|
|
|
|
List<Unspent> getUnspents(Object wallet);
|
|
void updateUnspents(Object wallet);
|
|
|
|
int heightByDate(DateTime date);
|
|
|
|
List<String> getDecredWordList();
|
|
|
|
String pubkey(Object wallet);
|
|
}
|
|
""";
|
|
|
|
const decredEmptyDefinition = 'Decred? decred;\n';
|
|
const decredCWDefinition = 'Decred? decred = CWDecred();\n';
|
|
|
|
final output = '$decredCommonHeaders\n' +
|
|
(hasImplementation ? '$decredCWHeaders\n' : '\n') +
|
|
(hasImplementation ? '$decredCwPart\n\n' : '\n') +
|
|
(hasImplementation ? decredCWDefinition : decredEmptyDefinition) +
|
|
'\n' +
|
|
decredContent;
|
|
|
|
if (outputFile.existsSync()) {
|
|
await outputFile.delete();
|
|
}
|
|
|
|
await outputFile.writeAsString(output);
|
|
}
|
|
|
|
Future<void> generateDogecoin(bool hasImplementation) async {
|
|
final outputFile = File(dogecoinOutputPath);
|
|
const dogecoinCommonHeaders = """
|
|
import 'package:cw_core/transaction_priority.dart';
|
|
import 'package:cw_core/unspent_coins_info.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 dogecoinCWHeaders = """
|
|
import 'package:cw_dogecoin/cw_dogecoin.dart';
|
|
""";
|
|
const dogecoinCwPart = "part 'cw_dogecoin.dart';";
|
|
const dogecoinContent = """
|
|
abstract class DogeCoin {
|
|
|
|
WalletService createDogeCoinWalletService(Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
|
|
|
|
WalletCredentials createDogeCoinNewWalletCredentials(
|
|
{required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic});
|
|
|
|
WalletCredentials createDogeCoinRestoreWalletFromSeedCredentials(
|
|
{required String name, required String mnemonic, required String password, String? passphrase});
|
|
|
|
TransactionPriority deserializeDogeCoinTransactionPriority(int raw);
|
|
|
|
TransactionPriority getDefaultTransactionPriority();
|
|
|
|
List<TransactionPriority> getTransactionPriorities();
|
|
|
|
TransactionPriority getDogeCoinTransactionPrioritySlow();
|
|
}
|
|
""";
|
|
|
|
const dogecoinEmptyDefinition = 'DogeCoin? dogecoin;\n';
|
|
const dogecoinCWDefinition = 'DogeCoin? dogecoin = CWDogeCoin();\n';
|
|
|
|
final output = '$dogecoinCommonHeaders\n' +
|
|
(hasImplementation ? '$dogecoinCWHeaders\n' : '\n') +
|
|
(hasImplementation ? '$dogecoinCwPart\n\n' : '\n') +
|
|
(hasImplementation ? dogecoinCWDefinition : dogecoinEmptyDefinition) +
|
|
'\n' +
|
|
dogecoinContent;
|
|
|
|
if (outputFile.existsSync()) {
|
|
await outputFile.delete();
|
|
}
|
|
|
|
await outputFile.writeAsString(output);
|
|
}
|
|
|
|
Future<void> generateEVM(bool hasImplementation) async {
|
|
final outputFile = File(evmOutputPath);
|
|
const evmCommonHeaders = """
|
|
import 'package:cake_wallet/core/utilities.dart';
|
|
import 'package:cake_wallet/view_model/send/output.dart';
|
|
import 'package:cw_core/crypto_currency.dart';
|
|
import 'package:cw_core/erc20_token.dart';
|
|
import 'package:cw_core/hardware/hardware_account_data.dart';
|
|
import 'package:cw_core/hardware/hardware_wallet_service.dart';
|
|
import 'package:cw_core/output_info.dart';
|
|
import 'package:cw_core/pending_transaction.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_core/wallet_type.dart';
|
|
import 'package:cw_core/node.dart';
|
|
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger;
|
|
import 'package:bitbox_flutter/bitbox_flutter.dart' as bitbox;
|
|
import 'package:trezor_connect/trezor_connect.dart' as trezor;
|
|
import 'package:web3dart/web3dart.dart';
|
|
|
|
""";
|
|
const evmCWHeaders = """
|
|
import 'package:cw_evm/utils/evm_chain_formatter.dart';
|
|
import 'package:cw_evm/evm_chain_mnemonics.dart';
|
|
import 'package:cw_evm/evm_chain_registry.dart';
|
|
import 'package:cw_evm/evm_chain_transaction_credentials.dart';
|
|
import 'package:cw_evm/evm_chain_transaction_info.dart';
|
|
import 'package:cw_evm/evm_chain_transaction_priority.dart';
|
|
import 'package:cw_evm/hardware/evm_chain_bitbox_credentials.dart';
|
|
import 'package:cw_evm/hardware/evm_chain_ledger_credentials.dart';
|
|
import 'package:cw_evm/hardware/evm_chain_trezor_credentials.dart';
|
|
import 'package:cw_evm/evm_chain_wallet.dart';
|
|
import 'package:cw_evm/hardware/evm_chain_bitbox_service.dart';
|
|
import 'package:cw_evm/hardware/evm_chain_ledger_service.dart';
|
|
import 'package:cw_evm/hardware/evm_chain_trezor_service.dart';
|
|
import 'package:cw_evm/evm_chain_wallet_service.dart';
|
|
import 'package:cw_evm/evm_chain_wallet_creation_credentials.dart';
|
|
import 'package:cw_evm/utils/evm_chain_utils.dart';
|
|
import 'package:cw_evm/evm_chain_default_tokens.dart';
|
|
import 'package:cw_evm/deuro/deuro_savings.dart';
|
|
import 'package:eth_sig_util/util/utils.dart';
|
|
|
|
""";
|
|
const evmCwPart = "part 'cw_evm.dart';";
|
|
const evmContent = """
|
|
/// Unified abstract class for all EVM chains
|
|
///
|
|
/// This replaces separate proxy classes (Ethereum, Polygon, Base, Arbitrum)
|
|
/// with a single unified interface that works for all EVM chains.
|
|
/// Methods take WalletType parameter to determine chain-specific behavior.
|
|
abstract class EVM {
|
|
List<String> getEVMWordList(String language);
|
|
|
|
/// Create unified wallet service for any EVM chain
|
|
WalletService createEVMWalletService(WalletType walletType, bool isDirect);
|
|
|
|
/// Generic credential creation - uses WalletType
|
|
WalletCredentials createEVMNewWalletCredentials({
|
|
required String name,
|
|
WalletInfo? walletInfo,
|
|
String? password,
|
|
String? mnemonic,
|
|
String? passphrase,
|
|
});
|
|
|
|
WalletCredentials createEVMRestoreWalletFromSeedCredentials({
|
|
required String name,
|
|
required String mnemonic,
|
|
required String password,
|
|
String? passphrase,
|
|
});
|
|
|
|
WalletCredentials createEVMRestoreWalletFromPrivateKey({
|
|
required String name,
|
|
required String privateKey,
|
|
required String password,
|
|
});
|
|
|
|
WalletCredentials createEVMHardwareWalletCredentials({
|
|
required String name,
|
|
required HardwareAccountData hwAccountData,
|
|
WalletInfo? walletInfo,
|
|
});
|
|
|
|
// Generic methods that work for all EVM chains
|
|
String getAddress(WalletBase wallet);
|
|
String getPrivateKey(WalletBase wallet);
|
|
String getPublicKey(WalletBase wallet);
|
|
TransactionPriority getDefaultTransactionPriority();
|
|
TransactionPriority getEVMTransactionPrioritySlow();
|
|
List<TransactionPriority> getTransactionPriorities();
|
|
TransactionPriority deserializeEVMTransactionPriority(int raw);
|
|
|
|
Object createEVMTransactionCredentials(
|
|
List<Output> outputs, {
|
|
required TransactionPriority? priority,
|
|
required CryptoCurrency currency,
|
|
int? feeRate,
|
|
bool useBlinkProtection = true,
|
|
});
|
|
|
|
Object createEVMTransactionCredentialsRaw(
|
|
List<OutputInfo> outputs, {
|
|
TransactionPriority? priority,
|
|
required CryptoCurrency currency,
|
|
required int feeRate,
|
|
bool useBlinkProtection = true,
|
|
});
|
|
|
|
int formatterEVMParseAmount(String amount);
|
|
double formatterEVMAmountToDouble({
|
|
TransactionInfo? transaction,
|
|
BigInt? amount,
|
|
int exponent = 18,
|
|
});
|
|
|
|
List<Erc20Token> getERC20Currencies(WalletBase wallet);
|
|
Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token);
|
|
Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token);
|
|
Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token);
|
|
Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress);
|
|
|
|
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction);
|
|
void updateScanProviderUsageState(WalletBase wallet, bool isEnabled);
|
|
Web3Client? getWeb3Client(WalletBase wallet);
|
|
String getTokenAddress(CryptoCurrency asset);
|
|
|
|
Future<bool> isApprovalRequired(
|
|
WalletBase wallet,
|
|
String tokenContract,
|
|
String spender,
|
|
BigInt requiredAmount,
|
|
);
|
|
|
|
Future<PendingTransaction> createTokenApproval(
|
|
WalletBase wallet,
|
|
BigInt amount,
|
|
String spender,
|
|
CryptoCurrency token,
|
|
TransactionPriority? priority,
|
|
{bool useBlinkProtection = true}
|
|
);
|
|
|
|
Future<PendingTransaction> createRawCallDataTransaction(
|
|
WalletBase wallet,
|
|
String to,
|
|
String dataHex,
|
|
BigInt valueWei,
|
|
TransactionPriority? priority,
|
|
{bool useBlinkProtection = true}
|
|
);
|
|
|
|
// Hardware wallet methods
|
|
Future<void> setHardwareWalletService(WalletBase wallet, HardwareWalletService service);
|
|
HardwareWalletService getLedgerHardwareWalletService(ledger.LedgerConnection connection);
|
|
HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxManager manager);
|
|
HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect connect);
|
|
|
|
// Utility methods
|
|
List<String> getDefaultTokenContractAddresses(WalletBase wallet);
|
|
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress);
|
|
String? getEVMNativeEstimatedFee(WalletBase wallet);
|
|
String? getEVMERC20EstimatedFee(WalletBase wallet);
|
|
|
|
// Chain-specific integrations (optional, can be null for non-Ethereum chains)
|
|
Future<BigInt>? getDEuroSavingsBalance(WalletBase wallet) => null;
|
|
Future<BigInt>? getDEuroAccruedInterest(WalletBase wallet) => null;
|
|
Future<BigInt>? getDEuroInterestRate(WalletBase wallet) => null;
|
|
Future<BigInt>? getDEuroSavingsApproved(WalletBase wallet) => null;
|
|
Future<PendingTransaction>? addDEuroSaving(WalletBase wallet, BigInt amount, TransactionPriority priority) => null;
|
|
Future<PendingTransaction>? removeDEuroSaving(WalletBase wallet, BigInt amount, TransactionPriority priority) => null;
|
|
Future<PendingTransaction>? reinvestDEuroInterest(WalletBase wallet, TransactionPriority priority) => null;
|
|
Future<PendingTransaction>? enableDEuroSaving(WalletBase wallet, TransactionPriority priority) => null;
|
|
|
|
// Registry helper methods (for backward compatibility helpers)
|
|
int getChainIdByWalletType(WalletType walletType);
|
|
String getChainNameByWalletType(WalletType walletType);
|
|
String getTokenNameByWalletType(WalletType walletType);
|
|
String getCaip2ByChainId(int chainId);
|
|
int? getChainIdByTag(String tag);
|
|
int? getChainIdByTitle(String title);
|
|
WalletType? getWalletTypeByChainId(int chainId);
|
|
String getChainNameByChainId(int chainId);
|
|
String getTokenNameByChainId(int chainId);
|
|
|
|
// Chain selection methods
|
|
List<ChainInfo> getAllChains();
|
|
ChainInfo? getCurrentChain(WalletBase wallet);
|
|
|
|
int? getSelectedChainId(WalletBase wallet);
|
|
Future<void> selectChain(WalletBase wallet, int chainId, {required Node node});
|
|
|
|
String? getExplorerUrlForChainId(int chainId, {bool showProtocol = true});
|
|
|
|
bool hasPriorityFee(int chainId);
|
|
}
|
|
|
|
class ChainInfo {
|
|
const ChainInfo({
|
|
required this.chainId,
|
|
required this.name,
|
|
required this.shortCode,
|
|
});
|
|
|
|
final int chainId;
|
|
final String name;
|
|
final String shortCode;
|
|
|
|
@override
|
|
bool operator ==(Object other) =>
|
|
identical(this, other) ||
|
|
other is ChainInfo && runtimeType == other.runtimeType && chainId == other.chainId;
|
|
|
|
@override
|
|
int get hashCode => chainId.hashCode;
|
|
}
|
|
""";
|
|
|
|
const evmEmptyDefinition = 'EVM? evm;\n';
|
|
const evmCWDefinition = 'EVM? evm = CWEVM();\n';
|
|
|
|
final output = '$evmCommonHeaders\n' +
|
|
(hasImplementation ? '$evmCWHeaders\n' : '\n') +
|
|
(hasImplementation ? '$evmCwPart\n\n' : '\n') +
|
|
(hasImplementation ? evmCWDefinition : evmEmptyDefinition) +
|
|
'\n' +
|
|
evmContent;
|
|
|
|
if (outputFile.existsSync()) {
|
|
await outputFile.delete();
|
|
}
|
|
|
|
await outputFile.writeAsString(output);
|
|
}
|
|
|
|
Future<void> generatePubspec({
|
|
required bool hasMonero,
|
|
required bool hasBitcoin,
|
|
required bool hasEthereum,
|
|
required bool hasNano,
|
|
required bool hasBanano,
|
|
required bool hasBitcoinCash,
|
|
required bool hasFlutterSecureStorage,
|
|
required bool hasPolygon,
|
|
required bool hasSolana,
|
|
required bool hasTron,
|
|
required bool hasWownero,
|
|
required bool hasZano,
|
|
required bool hasDecred,
|
|
required bool hasDogecoin,
|
|
required bool hasBase,
|
|
required bool hasArbitrum,
|
|
}) async {
|
|
const cwCore = """
|
|
cw_core:
|
|
path: ./cw_core
|
|
""";
|
|
const cwMonero = """
|
|
cw_monero:
|
|
path: ./cw_monero
|
|
""";
|
|
const cwBitcoin = """
|
|
cw_bitcoin:
|
|
path: ./cw_bitcoin
|
|
""";
|
|
const flutterSecureStorage = """
|
|
flutter_secure_storage:
|
|
git:
|
|
url: https://github.com/cake-tech/flutter_secure_storage.git
|
|
path: flutter_secure_storage
|
|
ref: ca897a08677edb443b366352dd7412735e098e7b
|
|
""";
|
|
const cwBitcoinCash = """
|
|
cw_bitcoin_cash:
|
|
path: ./cw_bitcoin_cash
|
|
""";
|
|
const cwNano = """
|
|
cw_nano:
|
|
path: ./cw_nano
|
|
""";
|
|
const cwBanano = """
|
|
cw_banano:
|
|
path: ./cw_banano
|
|
""";
|
|
const cwSolana = """
|
|
cw_solana:
|
|
path: ./cw_solana
|
|
""";
|
|
const cwEVM = """
|
|
cw_evm:
|
|
path: ./cw_evm
|
|
""";
|
|
const cwTron = """
|
|
cw_tron:
|
|
path: ./cw_tron
|
|
""";
|
|
const cwWownero = """
|
|
cw_wownero:
|
|
path: ./cw_wownero
|
|
""";
|
|
const cwZano = """
|
|
cw_zano:
|
|
path: ./cw_zano
|
|
""";
|
|
const cwDecred = """
|
|
cw_decred:
|
|
path: ./cw_decred
|
|
""";
|
|
const cwDogecoin = """
|
|
cw_dogecoin:
|
|
path: ./cw_dogecoin
|
|
""";
|
|
final inputFile = File(pubspecOutputPath);
|
|
final inputText = await inputFile.readAsString();
|
|
final inputLines = inputText.split('\n');
|
|
final dependenciesIndex = inputLines.indexWhere((line) => Platform.isWindows
|
|
// On Windows it could contains `\r` (Carriage Return). It could be fixed in newer dart versions.
|
|
? line.toLowerCase() == 'dependencies:\r' || line.toLowerCase() == 'dependencies:'
|
|
: line.toLowerCase() == 'dependencies:');
|
|
var output = cwCore;
|
|
|
|
if (hasMonero) {
|
|
output += '\n$cwMonero';
|
|
}
|
|
|
|
if (hasBitcoin) {
|
|
output += '\n$cwBitcoin';
|
|
}
|
|
|
|
if (hasNano) {
|
|
output += '\n$cwNano';
|
|
}
|
|
|
|
if (hasBanano) {
|
|
output += '\n$cwBanano';
|
|
}
|
|
|
|
if (hasBitcoinCash) {
|
|
output += '\n$cwBitcoinCash';
|
|
}
|
|
|
|
if (hasSolana) {
|
|
output += '\n$cwSolana';
|
|
}
|
|
|
|
if (hasTron) {
|
|
output += '\n$cwTron';
|
|
}
|
|
|
|
if (hasDecred) {
|
|
output += '\n$cwDecred';
|
|
}
|
|
|
|
if (hasFlutterSecureStorage) {
|
|
output += '\n$flutterSecureStorage\n';
|
|
}
|
|
|
|
if (hasEthereum || hasPolygon || hasBase || hasArbitrum) {
|
|
output += '\n$cwEVM';
|
|
}
|
|
|
|
if (hasWownero) {
|
|
output += '\n$cwWownero';
|
|
}
|
|
|
|
if (hasZano) {
|
|
output += '\n$cwZano';
|
|
}
|
|
|
|
if (hasDogecoin) {
|
|
output += '\n$cwDogecoin';
|
|
}
|
|
|
|
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 hasEthereum,
|
|
required bool hasNano,
|
|
required bool hasBanano,
|
|
required bool hasBitcoinCash,
|
|
required bool hasPolygon,
|
|
required bool hasSolana,
|
|
required bool hasTron,
|
|
required bool hasWownero,
|
|
required bool hasZano,
|
|
required bool hasDecred,
|
|
required bool hasDogecoin,
|
|
required bool hasBase,
|
|
required bool hasArbitrum,
|
|
}) 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 (hasDogecoin) {
|
|
outputContent += '\tWalletType.dogecoin,\n';
|
|
}
|
|
|
|
if (hasBase) {
|
|
outputContent += '\tWalletType.base,\n';
|
|
}
|
|
|
|
if (hasArbitrum) {
|
|
outputContent += '\tWalletType.arbitrum,\n';
|
|
}
|
|
|
|
if (hasBitcoinCash) {
|
|
outputContent += '\tWalletType.bitcoinCash,\n';
|
|
}
|
|
|
|
if (hasPolygon) {
|
|
outputContent += '\tWalletType.polygon,\n';
|
|
}
|
|
|
|
if (hasSolana) {
|
|
outputContent += '\tWalletType.solana,\n';
|
|
}
|
|
|
|
if (hasTron) {
|
|
outputContent += '\tWalletType.tron,\n';
|
|
}
|
|
|
|
if (hasNano) {
|
|
outputContent += '\tWalletType.nano,\n';
|
|
}
|
|
|
|
if (hasZano) {
|
|
outputContent += '\tWalletType.zano,\n';
|
|
}
|
|
|
|
if (hasBanano) {
|
|
outputContent += '\tWalletType.banano,\n';
|
|
}
|
|
|
|
if (hasDecred) {
|
|
outputContent += '\tWalletType.decred,\n';
|
|
}
|
|
|
|
// if (hasWownero) {
|
|
// outputContent += '\tWalletType.wownero,\n';
|
|
// }
|
|
|
|
outputContent += '];\n';
|
|
await walletTypesFile.writeAsString(outputContent);
|
|
}
|
|
|
|
Future<void> injectSecureStorage(bool hasFlutterSecureStorage) async {
|
|
const flutterSecureStorageHeader = """
|
|
import 'dart:async';
|
|
import 'dart:io';
|
|
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});
|
|
Future<void> deleteAll();
|
|
// Legacy
|
|
Future<String?> readNoIOptions({required String key});
|
|
Future<Map<String, String>> readAll();
|
|
}""";
|
|
const defaultSecureStorage = """
|
|
class DefaultSecureStorage extends SecureStorage {
|
|
DefaultSecureStorage._(this._secureStorage);
|
|
|
|
factory DefaultSecureStorage() => _instance;
|
|
|
|
static final _instance = DefaultSecureStorage._(FlutterSecureStorage(
|
|
iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
|
|
aOptions: AndroidOptions(encryptedSharedPreferences: true),
|
|
));
|
|
|
|
final FlutterSecureStorage _secureStorage;
|
|
|
|
@override
|
|
Future<String?> read({required String key}) async => await _readInternal(key, false);
|
|
|
|
@override
|
|
Future<void> write({required String key, required String? value}) async {
|
|
// delete the value before writing on macOS because of a weird bug
|
|
// https://github.com/mogol/flutter_secure_storage/issues/581
|
|
if (Platform.isMacOS) {
|
|
await _secureStorage.delete(key: key);
|
|
}
|
|
await _secureStorage.write(key: key, value: value);
|
|
}
|
|
|
|
@override
|
|
Future<void> delete({required String key}) async => _secureStorage.delete(key: key);
|
|
|
|
@override
|
|
Future<void> deleteAll() async => _secureStorage.deleteAll();
|
|
|
|
@override
|
|
Future<String?> readNoIOptions({required String key}) async => await _readInternal(key, true);
|
|
|
|
Future<String?> _readInternal(String key, bool useNoIOptions) async {
|
|
return await _secureStorage.read(
|
|
key: key,
|
|
iOptions: useNoIOptions ? IOSOptions() : null,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Future<Map<String, String>> readAll() async {
|
|
return await _secureStorage.readAll();
|
|
}
|
|
}""";
|
|
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<void> deleteAll() async {}
|
|
@override
|
|
Future<String?> readNoIOptions({required String key}) async => null;
|
|
@override
|
|
Future<Map<String, String>> readAll() async => {};
|
|
}""";
|
|
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);
|
|
}
|