| 1 | import 'dart:io'; |
| 2 | |
| 3 | const bitcoinOutputPath = 'lib/bitcoin/bitcoin.dart'; |
| 4 | const moneroOutputPath = 'lib/monero/monero.dart'; |
| 5 | const bitcoinCashOutputPath = 'lib/bitcoin_cash/bitcoin_cash.dart'; |
| 6 | const nanoOutputPath = 'lib/nano/nano.dart'; |
| 7 | const solanaOutputPath = 'lib/solana/solana.dart'; |
| 8 | const tronOutputPath = 'lib/tron/tron.dart'; |
| 9 | const wowneroOutputPath = 'lib/wownero/wownero.dart'; |
| 10 | const zanoOutputPath = 'lib/zano/zano.dart'; |
| 11 | const decredOutputPath = 'lib/decred/decred.dart'; |
| 12 | const dogecoinOutputPath = 'lib/dogecoin/dogecoin.dart'; |
| 13 | const evmOutputPath = 'lib/evm/evm.dart'; |
| 14 | const zcashOutputPath = 'lib/zcash/zcash.dart'; |
| 15 | const walletTypesPath = 'lib/wallet_types.g.dart'; |
| 16 | const secureStoragePath = 'lib/core/secure_storage.dart'; |
| 17 | const pubspecDefaultPath = 'pubspec_default.yaml'; |
| 18 | const pubspecOutputPath = 'pubspec.yaml'; |
| 19 | |
| 20 | Future<void> main(List<String> args) async { |
| 21 | const prefix = '--'; |
| 22 | final hasBitcoin = args.contains('${prefix}bitcoin'); |
| 23 | final hasMonero = args.contains('${prefix}monero'); |
| 24 | final hasEthereum = args.contains('${prefix}ethereum'); |
| 25 | final hasBitcoinCash = args.contains('${prefix}bitcoinCash'); |
| 26 | final hasNano = args.contains('${prefix}nano'); |
| 27 | final hasBanano = args.contains('${prefix}banano'); |
| 28 | final hasPolygon = args.contains('${prefix}polygon'); |
| 29 | final hasSolana = args.contains('${prefix}solana'); |
| 30 | final hasTron = args.contains('${prefix}tron'); |
| 31 | final hasWownero = args.contains('${prefix}wownero'); |
| 32 | final hasZano = args.contains('${prefix}zano'); |
| 33 | final hasDecred = args.contains('${prefix}decred'); |
| 34 | final hasDogecoin = args.contains('${prefix}dogecoin'); |
| 35 | final hasBase = args.contains('${prefix}base'); |
| 36 | final hasArbitrum = args.contains('${prefix}arbitrum'); |
| 37 | final hasBsc = args.contains('${prefix}bsc'); |
| 38 | final hasZcash = args.contains('${prefix}zcash'); |
| 39 | final hasEVM = hasEthereum || hasPolygon || hasBase || hasArbitrum || hasBsc; |
| 40 | final excludeFlutterSecureStorage = args.contains('${prefix}excludeFlutterSecureStorage'); |
| 41 | |
| 42 | await generateBitcoin(hasBitcoin); |
| 43 | await generateMonero(hasMonero); |
| 44 | await generateBitcoinCash(hasBitcoinCash); |
| 45 | await generateNano(hasNano); |
| 46 | await generateSolana(hasSolana); |
| 47 | await generateTron(hasTron); |
| 48 | await generateWownero(hasWownero); |
| 49 | await generateZano(hasZano); |
| 50 | // await generateBanano(hasEthereum); |
| 51 | await generateDecred(hasDecred); |
| 52 | await generateDogecoin(hasDogecoin); |
| 53 | await generateEVM(hasEVM); |
| 54 | await generateZcash(hasZcash); |
| 55 | |
| 56 | await generatePubspec( |
| 57 | hasMonero: hasMonero, |
| 58 | hasBitcoin: hasBitcoin, |
| 59 | hasEthereum: hasEthereum, |
| 60 | hasNano: hasNano, |
| 61 | hasBanano: hasBanano, |
| 62 | hasBitcoinCash: hasBitcoinCash, |
| 63 | hasFlutterSecureStorage: !excludeFlutterSecureStorage, |
| 64 | hasPolygon: hasPolygon, |
| 65 | hasSolana: hasSolana, |
| 66 | hasTron: hasTron, |
| 67 | hasWownero: hasWownero, |
| 68 | hasZano: hasZano, |
| 69 | hasDecred: hasDecred, |
| 70 | hasDogecoin: hasDogecoin, |
| 71 | hasBase: hasBase, |
| 72 | hasArbitrum: hasArbitrum, |
| 73 | hasBsc: hasBsc, |
| 74 | hasZcash: hasZcash, |
| 75 | ); |
| 76 | await generateWalletTypes( |
| 77 | hasMonero: hasMonero, |
| 78 | hasBitcoin: hasBitcoin, |
| 79 | hasEthereum: hasEthereum, |
| 80 | hasNano: hasNano, |
| 81 | hasBanano: hasBanano, |
| 82 | hasBitcoinCash: hasBitcoinCash, |
| 83 | hasPolygon: hasPolygon, |
| 84 | hasSolana: hasSolana, |
| 85 | hasTron: hasTron, |
| 86 | hasWownero: hasWownero, |
| 87 | hasZano: hasZano, |
| 88 | hasDecred: hasDecred, |
| 89 | hasDogecoin: hasDogecoin, |
| 90 | hasBase: hasBase, |
| 91 | hasArbitrum: hasArbitrum, |
| 92 | hasBsc: hasBsc, |
| 93 | hasZcash: hasZcash, |
| 94 | ); |
| 95 | await injectSecureStorage(!excludeFlutterSecureStorage); |
| 96 | } |
| 97 | |
| 98 | Future<void> generateBitcoin(bool hasImplementation) async { |
| 99 | final outputFile = File(bitcoinOutputPath); |
| 100 | const bitcoinCommonHeaders = """ |
| 101 | import 'dart:io' show Platform; |
| 102 | import 'dart:typed_data'; |
| 103 | import 'package:bitcoin_base/bitcoin_base.dart'; |
| 104 | import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart'; |
| 105 | import 'package:cake_wallet/view_model/send/output.dart'; |
| 106 | import 'package:cw_core/amount/money.dart'; |
| 107 | import 'package:cw_core/hardware/hardware_account_data.dart'; |
| 108 | import 'package:cw_core/hardware/hardware_wallet_service.dart'; |
| 109 | import 'package:cw_core/node.dart'; |
| 110 | import 'package:cw_core/payjoin_session.dart'; |
| 111 | import 'package:cw_core/output_info.dart'; |
| 112 | import 'package:cw_core/pending_transaction.dart'; |
| 113 | import 'package:cw_core/receive_page_option.dart'; |
| 114 | import 'package:cw_core/transaction_info.dart'; |
| 115 | import 'package:cw_core/transaction_priority.dart'; |
| 116 | import 'package:cw_core/unspent_coin_type.dart'; |
| 117 | import 'package:cw_core/unspent_coins_info.dart'; |
| 118 | import 'package:cw_core/unspent_transaction_output.dart'; |
| 119 | import 'package:cw_core/wallet_base.dart'; |
| 120 | import 'package:cw_core/wallet_credentials.dart'; |
| 121 | import 'package:cw_core/wallet_info.dart'; |
| 122 | import 'package:cw_core/wallet_service.dart'; |
| 123 | import 'package:cw_core/wallet_type.dart'; |
| 124 | import 'package:cw_core/utils/print_verbose.dart'; |
| 125 | import 'package:cw_core/get_height_by_date.dart'; |
| 126 | import 'package:hive/hive.dart'; |
| 127 | import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger; |
| 128 | import 'package:bitbox_flutter/bitbox_flutter.dart' as bitbox; |
| 129 | import 'package:trezor_connect/trezor_connect.dart' as trezor; |
| 130 | import 'package:blockchain_utils/blockchain_utils.dart'; |
| 131 | import 'package:bip39/bip39.dart' as bip39; |
| 132 | import 'package:collection/collection.dart'; |
| 133 | """; |
| 134 | const bitcoinCWHeaders = """ |
| 135 | import 'package:cw_bitcoin/utils.dart'; |
| 136 | import 'package:cw_bitcoin/electrum_derivations.dart'; |
| 137 | import 'package:cw_bitcoin/electrum.dart'; |
| 138 | import 'package:cw_bitcoin/electrum_transaction_info.dart'; |
| 139 | import 'package:cw_bitcoin/pending_bitcoin_transaction.dart'; |
| 140 | import 'package:cw_bitcoin/bitcoin_receive_page_option.dart'; |
| 141 | import 'package:cw_bitcoin/electrum_wallet.dart'; |
| 142 | import 'package:cw_bitcoin/bitcoin_unspent.dart'; |
| 143 | import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; |
| 144 | import 'package:cw_bitcoin/bitcoin_transaction_priority.dart'; |
| 145 | import 'package:cw_bitcoin/bitcoin_wallet.dart'; |
| 146 | import 'package:cw_bitcoin/bitcoin_wallet_service.dart'; |
| 147 | import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart'; |
| 148 | import 'package:cw_bitcoin/bitcoin_amount_format.dart'; |
| 149 | import 'package:cw_bitcoin/bitcoin_address_record.dart'; |
| 150 | import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart'; |
| 151 | import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart'; |
| 152 | import 'package:cw_bitcoin/lightning/lightning_addres_type.dart'; |
| 153 | import 'package:cw_bitcoin/lightning/pending_lightning_transaction.dart'; |
| 154 | import 'package:cw_bitcoin/litecoin_wallet_service.dart'; |
| 155 | import 'package:cw_bitcoin/litecoin_wallet.dart'; |
| 156 | import 'package:cw_bitcoin/hardware/bitcoin_ledger_service.dart'; |
| 157 | import 'package:cw_bitcoin/hardware/litecoin_ledger_service.dart'; |
| 158 | import 'package:cw_bitcoin/hardware/bitbox_service.dart'; |
| 159 | import 'package:cw_bitcoin/hardware/trezor_service.dart'; |
| 160 | import 'package:mobx/mobx.dart'; |
| 161 | import "package:breez_sdk_spark_flutter/src/rust/errors.dart"; |
| 162 | """; |
| 163 | const bitcoinCwPart = "part 'cw_bitcoin.dart';"; |
| 164 | const bitcoinContent = """ |
| 165 | |
| 166 | class ElectrumSubAddress { |
| 167 | ElectrumSubAddress({ |
| 168 | required this.id, |
| 169 | required this.name, |
| 170 | required this.address, |
| 171 | required this.txCount, |
| 172 | required this.balance, |
| 173 | required this.isChange, |
| 174 | this.derivationPath, |
| 175 | this.isLegacyDerivation = false |
| 176 | }); |
| 177 | final int id; |
| 178 | final String name; |
| 179 | final String address; |
| 180 | final int txCount; |
| 181 | final int balance; |
| 182 | final bool isChange; |
| 183 | final String? derivationPath; |
| 184 | final bool isLegacyDerivation; |
| 185 | } |
| 186 | |
| 187 | abstract class Bitcoin { |
| 188 | TransactionPriority getMediumTransactionPriority(); |
| 189 | |
| 190 | WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({ |
| 191 | required String name, |
| 192 | required String mnemonic, |
| 193 | required String password, |
| 194 | required DerivationType derivationType, |
| 195 | required String derivationPath, |
| 196 | String? passphrase, |
| 197 | }); |
| 198 | WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo}); |
| 199 | WalletCredentials createBitcoinWalletFromKeys({required String name, required String password, required String xpub, HardwareWalletType? hardwareWalletType}); |
| 200 | WalletCredentials createLitecoinWalletFromKeys({required String name, required String password, required String xpub, required String scanSecret, required String spendPubkey, HardwareWalletType? hardwareWalletType}); |
| 201 | WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic}); |
| 202 | WalletCredentials createBitcoinHardwareWalletCredentials({required String name, required HardwareAccountData accountData, WalletInfo? walletInfo}); |
| 203 | List<String> getWordList(); |
| 204 | Map<String, String> getWalletKeys(Object wallet); |
| 205 | List<TransactionPriority> getTransactionPriorities(); |
| 206 | List<TransactionPriority> getLitecoinTransactionPriorities(); |
| 207 | TransactionPriority deserializeBitcoinTransactionPriority(int raw); |
| 208 | TransactionPriority deserializeLitecoinTransactionPriority(int raw); |
| 209 | int getFeeRate(Object wallet, TransactionPriority priority); |
| 210 | Future<void> generateNewAddress(Object wallet, String label); |
| 211 | Future<void> updateAddress(Object wallet,String address, String label); |
| 212 | Object createBitcoinTransactionCredentials(List<Output> outputs, {required TransactionPriority priority, int? feeRate, UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any, String? payjoinUri}); |
| 213 | |
| 214 | String getAddress(Object wallet); |
| 215 | List<ElectrumSubAddress> getSilentPaymentAddresses(Object wallet); |
| 216 | List<ElectrumSubAddress> getSilentPaymentReceivedAddresses(Object wallet); |
| 217 | |
| 218 | Future<Money> estimateFakeSendAllTxAmount(WalletBase wallet, TransactionPriority priority, |
| 219 | {UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any}); |
| 220 | List<ElectrumSubAddress> getSubAddresses(Object wallet); |
| 221 | |
| 222 | String formatterBitcoinAmountToString({required int amount}); |
| 223 | int formatterStringDoubleToBitcoinAmount(String amount); |
| 224 | String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate, {int? customRate}); |
| 225 | |
| 226 | List<Unspent> getUnspents(Object wallet, {UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any}); |
| 227 | Future<void> updateUnspents(Object wallet); |
| 228 | WalletService createBitcoinWalletService( |
| 229 | Box<UnspentCoinsInfo> unspentCoinSource, Box<PayjoinSession> payjoinSessionSource, bool isDirect); |
| 230 | WalletService createLitecoinWalletService(Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect); |
| 231 | TransactionPriority getBitcoinTransactionPriorityMedium(); |
| 232 | TransactionPriority getBitcoinTransactionPriorityCustom(); |
| 233 | TransactionPriority getLitecoinTransactionPriorityMedium(); |
| 234 | TransactionPriority getBitcoinTransactionPrioritySlow(); |
| 235 | TransactionPriority getLitecoinTransactionPrioritySlow(); |
| 236 | Future<List<DerivationType>> compareDerivationMethods( |
| 237 | {required String mnemonic, required Node node}); |
| 238 | Future<List<DerivationInfo>> getDerivationsFromMnemonic( |
| 239 | {required String mnemonic, required Node node, String? passphrase}); |
| 240 | Map<DerivationType, List<DerivationInfo>> getElectrumDerivations(); |
| 241 | Future<void> setAddressType(Object wallet, dynamic option); |
| 242 | ReceivePageOption getSelectedAddressType(Object wallet); |
| 243 | BitcoinAddressType getBitcoinAddressType(ReceivePageOption option); |
| 244 | ReceivePageOption getBitcoinLightningReceivePageOption(); |
| 245 | ReceivePageOption getBitcoinSegwitPageOption(); |
| 246 | ReceivePageOption getLitecoinMwebReceivePageOption(); |
| 247 | bool isPayjoinAvailable(Object wallet); |
| 248 | bool hasSelectedSilentPayments(Object wallet); |
| 249 | bool hasSelectedLightning(Object wallet); |
| 250 | bool isBitcoinReceivePageOption(ReceivePageOption option); |
| 251 | BitcoinAddressType getOptionToType(ReceivePageOption option); |
| 252 | bool hasTaprootInput(PendingTransaction pendingTransaction); |
| 253 | bool getScanningActive(Object wallet); |
| 254 | Future<void> setScanningActive(Object wallet, bool active); |
| 255 | Future<void> setIsAlwaysScanningSP(Object wallet, bool active); |
| 256 | bool getIsAlwaysScanningSP(Object wallet); |
| 257 | bool isTestnet(Object wallet); |
| 258 | |
| 259 | Future<PendingTransaction> replaceByFee(Object wallet, String transactionHash, String fee); |
| 260 | Future<String?> canReplaceByFee(Object wallet, Object tx); |
| 261 | int getTransactionVSize(Object wallet, String txHex); |
| 262 | Future<bool> isChangeSufficientForFee(Object wallet, String txId, String newFee); |
| 263 | int getFeeAmountForPriority(Object wallet, TransactionPriority priority, int inputsCount, int outputsCount, {int? size}); |
| 264 | int getEstimatedFeeWithFeeRate(Object wallet, int feeRate, int? amount, |
| 265 | {int? outputsCount, int? size}); |
| 266 | int feeAmountWithFeeRate(Object wallet, int feeRate, int inputsCount, int outputsCount, {int? size}); |
| 267 | Future<bool> checkIfMempoolAPIIsEnabled(Object wallet); |
| 268 | Future<int> getHeightByDate({required DateTime date, bool? bitcoinMempoolAPIEnabled}); |
| 269 | int getLitecoinHeightByDate({required DateTime date}); |
| 270 | Future<void> rescan(Object wallet, {required int height, bool? doSingleScan}); |
| 271 | Future<bool> getNodeIsElectrsSPEnabled(Object wallet); |
| 272 | void deleteSilentPaymentAddress(Object wallet, String address); |
| 273 | Future<void> updateFeeRates(Object wallet); |
| 274 | int getMaxCustomFeeRate(Object wallet); |
| 275 | Future<void> setHardwareWalletService(WalletBase wallet, HardwareWalletService service); |
| 276 | HardwareWalletService getLedgerHardwareWalletService(ledger.LedgerConnection connection, bool isBitcoin); |
| 277 | HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxManager manager, bool isBitcoin); |
| 278 | HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect connect, bool isBitcoin); |
| 279 | List<Output> updateOutputs(PendingTransaction pendingTransaction, List<Output> outputs); |
| 280 | bool txIsReceivedSilentPayment(TransactionInfo txInfo); |
| 281 | bool txIsMweb(TransactionInfo txInfo); |
| 282 | Future<void> setMwebEnabled(Object wallet, bool enabled); |
| 283 | bool getMwebEnabled(Object wallet); |
| 284 | String? getUnusedMwebAddress(Object wallet); |
| 285 | String? getUnusedSegwitAddress(Object wallet); |
| 286 | Future<String?> getUnusedSpakDepositAddress(Object wallet); |
| 287 | Future<void> commitPsbtUR(Object wallet, List<String> urCodes); |
| 288 | |
| 289 | void updatePayjoinState(Object wallet, bool state); |
| 290 | String getPayjoinEndpoint(Object wallet); |
| 291 | void resumePayjoinSessions(Object wallet); |
| 292 | void stopPayjoinSessions(Object wallet); |
| 293 | Map<String, String> getSilentPaymentKeys(Object wallet); |
| 294 | List<String>? getTransactionAddresses(Object wallet, TransactionInfo tx); |
| 295 | String getNetworkName(Object wallet); |
| 296 | bool useLightning(Object wallet); |
| 297 | void updateUseLightning(Object wallet, bool value); |
| 298 | Future<void> setLightningUsername(Object wallet, String username); |
| 299 | Future<String?> getLightningUsername(Object wallet); |
| 300 | Future<String?> getLightningInvoice(Object wallet, BigInt amount); |
| 301 | String? getBreezSdkError(Object exception); |
| 302 | } |
| 303 | """; |
| 304 | |
| 305 | const bitcoinEmptyDefinition = 'Bitcoin? bitcoin;\n'; |
| 306 | const bitcoinCWDefinition = 'Bitcoin? bitcoin = CWBitcoin();\n'; |
| 307 | |
| 308 | final output = '$bitcoinCommonHeaders\n' + |
| 309 | (hasImplementation ? '$bitcoinCWHeaders\n' : '\n') + |
| 310 | (hasImplementation ? '$bitcoinCwPart\n\n' : '\n') + |
| 311 | (hasImplementation ? bitcoinCWDefinition : bitcoinEmptyDefinition) + |
| 312 | '\n' + |
| 313 | bitcoinContent; |
| 314 | |
| 315 | if (outputFile.existsSync()) { |
| 316 | await outputFile.delete(); |
| 317 | } |
| 318 | |
| 319 | await outputFile.writeAsString(output); |
| 320 | } |
| 321 | |
| 322 | Future<void> generateMonero(bool hasImplementation) async { |
| 323 | final outputFile = File(moneroOutputPath); |
| 324 | const moneroCommonHeaders = """ |
| 325 | import 'package:cw_core/amount/money.dart'; |
| 326 | import 'package:cw_core/crypto_currency.dart'; |
| 327 | import 'package:cw_core/unspent_transaction_output.dart'; |
| 328 | import 'package:cw_core/unspent_coins_info.dart'; |
| 329 | import 'package:mobx/mobx.dart'; |
| 330 | import 'package:cw_core/wallet_credentials.dart'; |
| 331 | import 'package:cw_core/wallet_info.dart'; |
| 332 | import 'package:cw_core/transaction_priority.dart'; |
| 333 | import 'package:cw_core/transaction_history.dart'; |
| 334 | import 'package:cw_core/transaction_info.dart'; |
| 335 | import 'package:cw_core/balance.dart'; |
| 336 | import 'package:cw_core/output_info.dart'; |
| 337 | import 'package:cake_wallet/view_model/send/output.dart'; |
| 338 | import 'package:cw_core/wallet_service.dart'; |
| 339 | import 'package:hive/hive.dart'; |
| 340 | import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger; |
| 341 | import 'package:trezor_flutter/trezor_flutter.dart' as trezor; |
| 342 | import 'package:polyseed/polyseed.dart';"""; |
| 343 | const moneroCWHeaders = """ |
| 344 | import 'package:cw_core/hardware/hardware_wallet_service.dart'; |
| 345 | import 'package:cw_core/account.dart' as monero_account; |
| 346 | import 'package:cw_core/get_height_by_date.dart'; |
| 347 | import 'package:cw_core/monero_amount_format.dart'; |
| 348 | import 'package:cw_core/monero_transaction_priority.dart'; |
| 349 | import 'package:cw_monero/api/wallet_manager.dart'; |
| 350 | import 'package:cw_monero/api/wallet.dart' as monero_wallet_api; |
| 351 | import 'package:cw_monero/ledger.dart'; |
| 352 | import 'package:cw_monero/monero_unspent.dart'; |
| 353 | import 'package:cw_monero/api/account_list.dart'; |
| 354 | import 'package:cw_monero/trezor.dart'; |
| 355 | import 'package:cw_monero/monero_wallet_service.dart'; |
| 356 | import 'package:cw_monero/monero_wallet.dart'; |
| 357 | import 'package:cw_monero/monero_transaction_info.dart'; |
| 358 | import 'package:cw_monero/monero_transaction_creation_credentials.dart'; |
| 359 | import 'package:cw_monero/mnemonics/english.dart'; |
| 360 | import 'package:cw_monero/mnemonics/chinese_simplified.dart'; |
| 361 | import 'package:cw_monero/mnemonics/dutch.dart'; |
| 362 | import 'package:cw_monero/mnemonics/german.dart'; |
| 363 | import 'package:cw_monero/mnemonics/japanese.dart'; |
| 364 | import 'package:cw_monero/mnemonics/russian.dart'; |
| 365 | import 'package:cw_monero/mnemonics/spanish.dart'; |
| 366 | import 'package:cw_monero/mnemonics/portuguese.dart'; |
| 367 | import 'package:cw_monero/mnemonics/french.dart'; |
| 368 | import 'package:cw_monero/mnemonics/italian.dart'; |
| 369 | import 'package:cw_monero/pending_monero_transaction.dart'; |
| 370 | """; |
| 371 | const moneroCwPart = "part 'cw_monero.dart';"; |
| 372 | const moneroContent = """ |
| 373 | class Account { |
| 374 | Account({required this.id, required this.label, this.balance}); |
| 375 | final int id; |
| 376 | final String label; |
| 377 | final String? balance; |
| 378 | } |
| 379 | |
| 380 | class Subaddress { |
| 381 | Subaddress({ |
| 382 | required this.id, |
| 383 | required this.label, |
| 384 | required this.address, |
| 385 | required this.received, |
| 386 | required this.txCount}); |
| 387 | final int id; |
| 388 | final String label; |
| 389 | final String address; |
| 390 | final String? received; |
| 391 | final int txCount; |
| 392 | } |
| 393 | |
| 394 | class MoneroBalance extends Balance { |
| 395 | MoneroBalance({ |
| 396 | required this.fullBalance, |
| 397 | required Money unlockedBalance, |
| 398 | Money? frozen, |
| 399 | }) : super( |
| 400 | unlockedBalance, |
| 401 | fullBalance - unlockedBalance, |
| 402 | frozen: frozen ?? Money.zero(CryptoCurrency.xmr), |
| 403 | ); |
| 404 | |
| 405 | final Money fullBalance; |
| 406 | } |
| 407 | |
| 408 | abstract class MoneroWalletDetails { |
| 409 | @observable |
| 410 | late Account account; |
| 411 | |
| 412 | @observable |
| 413 | late MoneroBalance balance; |
| 414 | } |
| 415 | |
| 416 | abstract class Monero { |
| 417 | MoneroAccountList getAccountList(Object wallet); |
| 418 | |
| 419 | MoneroSubaddressList getSubaddressList(Object wallet); |
| 420 | |
| 421 | TransactionHistoryBase getTransactionHistory(Object wallet); |
| 422 | |
| 423 | MoneroWalletDetails getMoneroWalletDetails(Object wallet); |
| 424 | |
| 425 | String getTransactionAddress(Object wallet, int accountIndex, int addressIndex); |
| 426 | |
| 427 | String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex); |
| 428 | |
| 429 | int getHeightByDate({required DateTime date}); |
| 430 | TransactionPriority getDefaultTransactionPriority(); |
| 431 | TransactionPriority getMoneroTransactionPrioritySlow(); |
| 432 | TransactionPriority getMoneroTransactionPriorityAutomatic(); |
| 433 | TransactionPriority deserializeMoneroTransactionPriority({required int raw}); |
| 434 | List<TransactionPriority> getTransactionPriorities(); |
| 435 | List<String> getMoneroWordList(String language); |
| 436 | |
| 437 | List<Unspent> getUnspents(Object wallet); |
| 438 | Future<void> updateUnspents(Object wallet); |
| 439 | |
| 440 | Future<int> getCurrentHeight(); |
| 441 | |
| 442 | Future<bool> commitTransactionUR(Object wallet, String ur); |
| 443 | |
| 444 | Map<String, String> exportOutputsUR(Object wallet); |
| 445 | |
| 446 | bool needExportOutputs(Object wallet, Money amount); |
| 447 | |
| 448 | bool hasUnknownKeyImages(Object wallet); |
| 449 | |
| 450 | bool importKeyImagesUR(Object wallet, String ur); |
| 451 | |
| 452 | WalletCredentials createMoneroRestoreWalletFromKeysCredentials({ |
| 453 | required String name, |
| 454 | required String spendKey, |
| 455 | required String viewKey, |
| 456 | required String address, |
| 457 | required String password, |
| 458 | required String language, |
| 459 | HardwareWalletType? hardwareWalletType, |
| 460 | required int height}); |
| 461 | WalletCredentials createMoneroRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic}); |
| 462 | WalletCredentials createMoneroRestoreWalletFromHardwareCredentials({required String name, required String password, required int height, required HardwareWalletService hardwareWalletService, required String? passphrase}); |
| 463 | WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, required int seedType, required String? passphrase, String? password, String? mnemonic}); |
| 464 | Map<String, String> getKeys(Object wallet); |
| 465 | int? getRestoreHeight(Object wallet); |
| 466 | Object createMoneroTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority}); |
| 467 | Object createMoneroTransactionCreationCredentialsRaw({required List<OutputInfo> outputs, required TransactionPriority priority}); |
| 468 | String formatterMoneroAmountToString({required int amount}); |
| 469 | double formatterMoneroAmountToDouble({required int amount}); |
| 470 | int formatterMoneroParseAmount({required String amount}); |
| 471 | Account getCurrentAccount(Object wallet); |
| 472 | void monerocCheck(); |
| 473 | bool isViewOnly(); |
| 474 | void setCurrentAccount(Object wallet, int id, String label, String? balance); |
| 475 | void onStartup(); |
| 476 | int getTransactionInfoAccountId(TransactionInfo tx); |
| 477 | WalletService createMoneroWalletService(Box<UnspentCoinsInfo> unspentCoinSource); |
| 478 | Map<String, String> pendingTransactionInfo(Object transaction); |
| 479 | Future<void> setLedgerConnection(Object wallet, ledger.LedgerConnection connection); |
| 480 | void resetLedgerConnection(); |
| 481 | void setGlobalLedgerConnection(ledger.LedgerConnection connection); |
| 482 | bool hasGlobalLedgerConnection(); |
| 483 | String? getLastLedgerCommand(); |
| 484 | void setHardwareWalletService(Object wallet, HardwareWalletService service); |
| 485 | HardwareWalletService getLedgerHardwareWalletService(ledger.LedgerConnection connection); |
| 486 | HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorClient client); |
| 487 | Future<void> syncTrezor(Object wallet); |
| 488 | Map<String, List<int>> debugCallLength(); |
| 489 | Map<String, dynamic> getWalletCacheDebug(); |
| 490 | } |
| 491 | |
| 492 | abstract class MoneroSubaddressList { |
| 493 | ObservableList<Subaddress> get subaddresses; |
| 494 | Future<void> update(Object wallet, {required int accountIndex}); |
| 495 | void refresh(Object wallet, {required int accountIndex}); |
| 496 | Future<List<Subaddress>> getAll(Object wallet); |
| 497 | Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label}); |
| 498 | Future<void> setLabelSubaddress(Object wallet, |
| 499 | {required int accountIndex, required int addressIndex, required String label}); |
| 500 | } |
| 501 | |
| 502 | abstract class MoneroAccountList { |
| 503 | ObservableList<Account> get accounts; |
| 504 | void update(Object wallet); |
| 505 | void refresh(Object wallet); |
| 506 | List<Account> getAll(Object wallet); |
| 507 | Future<void> addAccount(Object wallet, {required String label}); |
| 508 | Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}); |
| 509 | } |
| 510 | """; |
| 511 | |
| 512 | const moneroEmptyDefinition = 'Monero? monero;\n'; |
| 513 | const moneroCWDefinition = 'Monero? monero = CWMonero();\n'; |
| 514 | |
| 515 | final output = '$moneroCommonHeaders\n' + |
| 516 | (hasImplementation ? '$moneroCWHeaders\n' : '\n') + |
| 517 | (hasImplementation ? '$moneroCwPart\n\n' : '\n') + |
| 518 | (hasImplementation ? moneroCWDefinition : moneroEmptyDefinition) + |
| 519 | '\n' + |
| 520 | moneroContent; |
| 521 | |
| 522 | if (outputFile.existsSync()) { |
| 523 | await outputFile.delete(); |
| 524 | } |
| 525 | |
| 526 | await outputFile.writeAsString(output); |
| 527 | } |
| 528 | |
| 529 | Future<void> generateWownero(bool hasImplementation) async { |
| 530 | final outputFile = File(wowneroOutputPath); |
| 531 | const wowneroCommonHeaders = """ |
| 532 | import 'package:cw_core/amount/money.dart'; |
| 533 | import 'package:cw_core/crypto_currency.dart'; |
| 534 | import 'package:cw_core/unspent_transaction_output.dart'; |
| 535 | import 'package:cw_core/unspent_coins_info.dart'; |
| 536 | import 'package:mobx/mobx.dart'; |
| 537 | import 'package:cw_core/wallet_credentials.dart'; |
| 538 | import 'package:cw_core/wallet_info.dart'; |
| 539 | import 'package:cw_core/transaction_priority.dart'; |
| 540 | import 'package:cw_core/transaction_history.dart'; |
| 541 | import 'package:cw_core/transaction_info.dart'; |
| 542 | import 'package:cw_core/balance.dart'; |
| 543 | import 'package:cw_core/output_info.dart'; |
| 544 | import 'package:cake_wallet/view_model/send/output.dart'; |
| 545 | import 'package:cw_core/crypto_currency.dart'; |
| 546 | import 'package:cake_wallet/core/key_service.dart'; |
| 547 | import 'package:cake_wallet/core/secure_storage.dart'; |
| 548 | import 'package:cake_wallet/entities/haven_seed_store.dart'; |
| 549 | import 'package:cw_core/cake_hive.dart'; |
| 550 | import 'package:cw_core/wallet_info.dart'; |
| 551 | import 'package:cw_core/wallet_type.dart'; |
| 552 | import 'package:cw_core/wallet_service.dart'; |
| 553 | import 'package:hive/hive.dart'; |
| 554 | import 'package:polyseed/polyseed.dart';"""; |
| 555 | const wowneroCWHeaders = """ |
| 556 | import 'package:cw_core/get_height_by_date.dart'; |
| 557 | import 'package:cw_core/wownero_amount_format.dart'; |
| 558 | import 'package:cw_core/monero_transaction_priority.dart'; |
| 559 | import 'package:cw_wownero/wownero_unspent.dart'; |
| 560 | import 'package:cw_wownero/wownero_wallet_service.dart'; |
| 561 | import 'package:cw_wownero/wownero_wallet.dart'; |
| 562 | import 'package:cw_wownero/wownero_transaction_info.dart'; |
| 563 | import 'package:cw_wownero/wownero_transaction_creation_credentials.dart'; |
| 564 | import 'package:cw_core/account.dart' as wownero_account; |
| 565 | import 'package:cw_wownero/api/wallet.dart' as wownero_wallet_api; |
| 566 | import 'package:cw_wownero/api/wallet_manager.dart'; |
| 567 | import 'package:cw_wownero/mnemonics/english.dart'; |
| 568 | import 'package:cw_wownero/mnemonics/chinese_simplified.dart'; |
| 569 | import 'package:cw_wownero/mnemonics/dutch.dart'; |
| 570 | import 'package:cw_wownero/mnemonics/german.dart'; |
| 571 | import 'package:cw_wownero/mnemonics/japanese.dart'; |
| 572 | import 'package:cw_wownero/mnemonics/russian.dart'; |
| 573 | import 'package:cw_wownero/mnemonics/spanish.dart'; |
| 574 | import 'package:cw_wownero/mnemonics/portuguese.dart'; |
| 575 | import 'package:cw_wownero/mnemonics/french.dart'; |
| 576 | import 'package:cw_wownero/mnemonics/italian.dart'; |
| 577 | import 'package:cw_wownero/pending_wownero_transaction.dart'; |
| 578 | """; |
| 579 | const wowneroCwPart = "part 'cw_wownero.dart';"; |
| 580 | const wowneroContent = """ |
| 581 | class Account { |
| 582 | Account({required this.id, required this.label, this.balance}); |
| 583 | final int id; |
| 584 | final String label; |
| 585 | final String? balance; |
| 586 | } |
| 587 | |
| 588 | class Subaddress { |
| 589 | Subaddress({ |
| 590 | required this.id, |
| 591 | required this.label, |
| 592 | required this.address}); |
| 593 | final int id; |
| 594 | final String label; |
| 595 | final String address; |
| 596 | } |
| 597 | |
| 598 | class WowneroBalance extends Balance { |
| 599 | WowneroBalance({ |
| 600 | required this.fullBalance, |
| 601 | required Money unlockedBalance, |
| 602 | Money? frozen, |
| 603 | }) : super( |
| 604 | unlockedBalance, |
| 605 | fullBalance - unlockedBalance, |
| 606 | frozen: frozen ?? Money.zero(CryptoCurrency.wow), |
| 607 | ); |
| 608 | |
| 609 | final Money fullBalance; |
| 610 | } |
| 611 | |
| 612 | abstract class WowneroWalletDetails { |
| 613 | @observable |
| 614 | late Account account; |
| 615 | |
| 616 | @observable |
| 617 | late WowneroBalance balance; |
| 618 | } |
| 619 | |
| 620 | abstract class Wownero { |
| 621 | WowneroAccountList getAccountList(Object wallet); |
| 622 | |
| 623 | WowneroSubaddressList getSubaddressList(Object wallet); |
| 624 | |
| 625 | TransactionHistoryBase getTransactionHistory(Object wallet); |
| 626 | |
| 627 | WowneroWalletDetails getWowneroWalletDetails(Object wallet); |
| 628 | |
| 629 | String getTransactionAddress(Object wallet, int accountIndex, int addressIndex); |
| 630 | |
| 631 | String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex); |
| 632 | |
| 633 | int getHeightByDate({required DateTime date}); |
| 634 | TransactionPriority getDefaultTransactionPriority(); |
| 635 | TransactionPriority getWowneroTransactionPrioritySlow(); |
| 636 | TransactionPriority getWowneroTransactionPriorityAutomatic(); |
| 637 | TransactionPriority deserializeWowneroTransactionPriority({required int raw}); |
| 638 | List<TransactionPriority> getTransactionPriorities(); |
| 639 | List<String> getWowneroWordList(String language); |
| 640 | |
| 641 | List<Unspent> getUnspents(Object wallet); |
| 642 | Future<void> updateUnspents(Object wallet); |
| 643 | |
| 644 | Future<int> getCurrentHeight(); |
| 645 | void wownerocCheck(); |
| 646 | |
| 647 | WalletCredentials createWowneroRestoreWalletFromKeysCredentials({ |
| 648 | required String name, |
| 649 | required String spendKey, |
| 650 | required String viewKey, |
| 651 | required String address, |
| 652 | required String password, |
| 653 | required String language, |
| 654 | required int height}); |
| 655 | WalletCredentials createWowneroRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic}); |
| 656 | WalletCredentials createWowneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String? password, String? passphrase}); |
| 657 | int? getRestoreHeight(Object wallet); |
| 658 | Map<String, String> getKeys(Object wallet); |
| 659 | Object createWowneroTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority}); |
| 660 | Object createWowneroTransactionCreationCredentialsRaw({required List<OutputInfo> outputs, required TransactionPriority priority}); |
| 661 | String formatterWowneroAmountToString({required int amount}); |
| 662 | double formatterWowneroAmountToDouble({required int amount}); |
| 663 | int formatterWowneroParseAmount({required String amount}); |
| 664 | Account getCurrentAccount(Object wallet); |
| 665 | void setCurrentAccount(Object wallet, int id, String label, String? balance); |
| 666 | void onStartup(); |
| 667 | int getTransactionInfoAccountId(TransactionInfo tx); |
| 668 | WalletService createWowneroWalletService(Box<UnspentCoinsInfo> unspentCoinSource); |
| 669 | Map<String, String> pendingTransactionInfo(Object transaction); |
| 670 | String getLegacySeed(Object wallet, String langName); |
| 671 | Map<String, List<int>> debugCallLength(); |
| 672 | Future<void> backupSeeds(Box<HavenSeedStore> havenSeedStore); |
| 673 | } |
| 674 | |
| 675 | abstract class WowneroSubaddressList { |
| 676 | ObservableList<Subaddress> get subaddresses; |
| 677 | void update(Object wallet, {required int accountIndex}); |
| 678 | void refresh(Object wallet, {required int accountIndex}); |
| 679 | List<Subaddress> getAll(Object wallet); |
| 680 | Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label}); |
| 681 | Future<void> setLabelSubaddress(Object wallet, |
| 682 | {required int accountIndex, required int addressIndex, required String label}); |
| 683 | } |
| 684 | |
| 685 | abstract class WowneroAccountList { |
| 686 | ObservableList<Account> get accounts; |
| 687 | void update(Object wallet); |
| 688 | void refresh(Object wallet); |
| 689 | List<Account> getAll(Object wallet); |
| 690 | Future<void> addAccount(Object wallet, {required String label}); |
| 691 | Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}); |
| 692 | } |
| 693 | """; |
| 694 | |
| 695 | const wowneroEmptyDefinition = 'Wownero? wownero;\n'; |
| 696 | const wowneroCWDefinition = 'Wownero? wownero = CWWownero();\n'; |
| 697 | |
| 698 | final output = '$wowneroCommonHeaders\n' + |
| 699 | (hasImplementation ? '$wowneroCWHeaders\n' : '\n') + |
| 700 | (hasImplementation ? '$wowneroCwPart\n\n' : '\n') + |
| 701 | (hasImplementation ? wowneroCWDefinition : wowneroEmptyDefinition) + |
| 702 | '\n' + |
| 703 | wowneroContent; |
| 704 | |
| 705 | if (outputFile.existsSync()) { |
| 706 | await outputFile.delete(); |
| 707 | } |
| 708 | |
| 709 | await outputFile.writeAsString(output); |
| 710 | } |
| 711 | |
| 712 | Future<void> generateBitcoinCash(bool hasImplementation) async { |
| 713 | final outputFile = File(bitcoinCashOutputPath); |
| 714 | const bitcoinCashCommonHeaders = """ |
| 715 | import 'dart:typed_data'; |
| 716 | |
| 717 | import 'package:cw_core/unspent_transaction_output.dart'; |
| 718 | import 'package:cw_core/transaction_priority.dart'; |
| 719 | import 'package:cw_core/unspent_coins_info.dart'; |
| 720 | import 'package:cw_core/wallet_credentials.dart'; |
| 721 | import 'package:cw_core/wallet_info.dart'; |
| 722 | import 'package:cw_core/wallet_service.dart'; |
| 723 | import 'package:hive/hive.dart'; |
| 724 | """; |
| 725 | const bitcoinCashCWHeaders = """ |
| 726 | import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart'; |
| 727 | import 'package:cw_bitcoin/bitcoin_transaction_priority.dart'; |
| 728 | """; |
| 729 | const bitcoinCashCwPart = "part 'cw_bitcoin_cash.dart';"; |
| 730 | const bitcoinCashContent = """ |
| 731 | abstract class BitcoinCash { |
| 732 | String getCashAddrFormat(String address); |
| 733 | |
| 734 | WalletService createBitcoinCashWalletService( |
| 735 | Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect); |
| 736 | |
| 737 | WalletCredentials createBitcoinCashNewWalletCredentials( |
| 738 | {required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic}); |
| 739 | |
| 740 | WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials( |
| 741 | {required String name, required String mnemonic, required String password, String? passphrase}); |
| 742 | |
| 743 | TransactionPriority deserializeBitcoinCashTransactionPriority(int raw); |
| 744 | |
| 745 | TransactionPriority getDefaultTransactionPriority(); |
| 746 | |
| 747 | List<TransactionPriority> getTransactionPriorities(); |
| 748 | |
| 749 | TransactionPriority getBitcoinCashTransactionPrioritySlow(); |
| 750 | } |
| 751 | """; |
| 752 | |
| 753 | const bitcoinCashEmptyDefinition = 'BitcoinCash? bitcoinCash;\n'; |
| 754 | const bitcoinCashCWDefinition = 'BitcoinCash? bitcoinCash = CWBitcoinCash();\n'; |
| 755 | |
| 756 | final output = '$bitcoinCashCommonHeaders\n' + |
| 757 | (hasImplementation ? '$bitcoinCashCWHeaders\n' : '\n') + |
| 758 | (hasImplementation ? '$bitcoinCashCwPart\n\n' : '\n') + |
| 759 | (hasImplementation ? bitcoinCashCWDefinition : bitcoinCashEmptyDefinition) + |
| 760 | '\n' + |
| 761 | bitcoinCashContent; |
| 762 | |
| 763 | if (outputFile.existsSync()) { |
| 764 | await outputFile.delete(); |
| 765 | } |
| 766 | |
| 767 | await outputFile.writeAsString(output); |
| 768 | } |
| 769 | |
| 770 | Future<void> generateNano(bool hasImplementation) async { |
| 771 | final outputFile = File(nanoOutputPath); |
| 772 | const nanoCommonHeaders = """ |
| 773 | import 'package:cw_core/cake_hive.dart'; |
| 774 | import 'package:cw_core/nano_account.dart'; |
| 775 | import 'package:cw_core/account.dart'; |
| 776 | import 'package:cw_core/node.dart'; |
| 777 | import 'package:cw_core/wallet_credentials.dart'; |
| 778 | import 'package:cw_core/wallet_info.dart'; |
| 779 | import 'package:cw_core/transaction_info.dart'; |
| 780 | import 'package:cw_core/transaction_history.dart'; |
| 781 | import 'package:cw_core/wallet_service.dart'; |
| 782 | import 'package:cw_core/output_info.dart'; |
| 783 | import 'package:cw_core/nano_account_info_response.dart'; |
| 784 | import 'package:cw_core/n2_node.dart'; |
| 785 | import 'package:cw_core/utils/print_verbose.dart'; |
| 786 | import 'package:mobx/mobx.dart'; |
| 787 | import 'package:hive/hive.dart'; |
| 788 | import 'package:cake_wallet/view_model/send/output.dart'; |
| 789 | """; |
| 790 | const nanoCWHeaders = """ |
| 791 | import 'package:cw_nano/nano_client.dart'; |
| 792 | import 'package:cw_nano/nano_mnemonic.dart'; |
| 793 | import 'package:cw_nano/nano_wallet.dart'; |
| 794 | import 'package:cw_nano/nano_wallet_service.dart'; |
| 795 | import 'package:cw_nano/nano_transaction_info.dart'; |
| 796 | import 'package:cw_nano/nano_transaction_credentials.dart'; |
| 797 | import 'package:cw_nano/nano_wallet_creation_credentials.dart'; |
| 798 | // needed for nano_util: |
| 799 | import 'dart:convert'; |
| 800 | import 'dart:typed_data'; |
| 801 | import 'package:convert/convert.dart'; |
| 802 | import "package:ed25519_hd_key/ed25519_hd_key.dart"; |
| 803 | import 'package:libcrypto/libcrypto.dart'; |
| 804 | import 'package:nanodart/nanodart.dart' as ND; |
| 805 | import 'package:nanoutil/nanoutil.dart'; |
| 806 | """; |
| 807 | const nanoCwPart = "part 'cw_nano.dart';"; |
| 808 | const nanoContent = """ |
| 809 | abstract class Nano { |
| 810 | NanoAccountList getAccountList(Object wallet); |
| 811 | |
| 812 | Account getCurrentAccount(Object wallet); |
| 813 | |
| 814 | void setCurrentAccount(Object wallet, int id, String label, String? balance); |
| 815 | |
| 816 | WalletService createNanoWalletService(bool isDirect); |
| 817 | |
| 818 | WalletCredentials createNanoNewWalletCredentials({ |
| 819 | required String name, |
| 820 | String? password, |
| 821 | String? mnemonic, |
| 822 | WalletInfo? walletInfo, |
| 823 | String? passphrase, |
| 824 | }); |
| 825 | |
| 826 | WalletCredentials createNanoRestoreWalletFromSeedCredentials({ |
| 827 | required String name, |
| 828 | required String password, |
| 829 | required String mnemonic, |
| 830 | required DerivationType derivationType, |
| 831 | String? passphrase, |
| 832 | }); |
| 833 | |
| 834 | WalletCredentials createNanoRestoreWalletFromKeysCredentials({ |
| 835 | required String name, |
| 836 | required String password, |
| 837 | required String seedKey, |
| 838 | required DerivationType derivationType, |
| 839 | }); |
| 840 | |
| 841 | List<String> getNanoWordList(String language); |
| 842 | Map<String, String> getKeys(Object wallet); |
| 843 | Object createNanoTransactionCredentials(List<Output> outputs); |
| 844 | Future<void> changeRep(Object wallet, String address); |
| 845 | Future<bool> updateTransactions(Object wallet); |
| 846 | String getRepresentative(Object wallet); |
| 847 | Future<List<N2Node>> getN2Reps(Object wallet); |
| 848 | bool isRepOk(Object wallet); |
| 849 | } |
| 850 | |
| 851 | abstract class NanoAccountList { |
| 852 | ObservableList<NanoAccount> get accounts; |
| 853 | void update(Object wallet); |
| 854 | void refresh(Object wallet); |
| 855 | Future<List<NanoAccount>> getAll(Object wallet); |
| 856 | Future<void> addAccount(Object wallet, {required String label}); |
| 857 | Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}); |
| 858 | } |
| 859 | |
| 860 | abstract class NanoUtil { |
| 861 | bool isValidBip39Seed(String seed); |
| 862 | static const int maxDecimalDigits = 6; // Max digits after decimal |
| 863 | BigInt rawPerNano = BigInt.parse("1000000000000000000000000000000"); |
| 864 | BigInt rawPerNyano = BigInt.parse("1000000000000000000000000"); |
| 865 | BigInt rawPerBanano = BigInt.parse("100000000000000000000000000000"); |
| 866 | BigInt rawPerXMR = BigInt.parse("1000000000000"); |
| 867 | BigInt convertXMRtoNano = BigInt.parse("1000000000000000000"); |
| 868 | String getRawAsUsableString(String? raw, BigInt rawPerCur); |
| 869 | String getRawAccuracy(String? raw, BigInt rawPerCur); |
| 870 | String getAmountAsRaw(String amount, BigInt rawPerCur); |
| 871 | |
| 872 | // derivationInfo: |
| 873 | Future<AccountInfoResponse?> getInfoFromSeedOrMnemonic( |
| 874 | DerivationType derivationType, { |
| 875 | String? seedKey, |
| 876 | String? mnemonic, |
| 877 | required Node node, |
| 878 | }); |
| 879 | Future<List<DerivationType>> compareDerivationMethods({ |
| 880 | String? mnemonic, |
| 881 | String? privateKey, |
| 882 | required Node node, |
| 883 | }); |
| 884 | Future<List<DerivationInfo>> getDerivationsFromMnemonic({ |
| 885 | String? mnemonic, |
| 886 | String? seedKey, |
| 887 | required Node node, |
| 888 | }); |
| 889 | } |
| 890 | """; |
| 891 | |
| 892 | const nanoEmptyDefinition = 'Nano? nano;\nNanoUtil? nanoUtil;\n'; |
| 893 | const nanoCWDefinition = 'Nano? nano = CWNano();\nNanoUtil? nanoUtil = CWNanoUtil();\n'; |
| 894 | |
| 895 | final output = '$nanoCommonHeaders\n' + |
| 896 | (hasImplementation ? '$nanoCWHeaders\n' : '\n') + |
| 897 | (hasImplementation ? '$nanoCwPart\n\n' : '\n') + |
| 898 | (hasImplementation ? nanoCWDefinition : nanoEmptyDefinition) + |
| 899 | '\n' + |
| 900 | nanoContent; |
| 901 | |
| 902 | if (outputFile.existsSync()) { |
| 903 | await outputFile.delete(); |
| 904 | } |
| 905 | |
| 906 | await outputFile.writeAsString(output); |
| 907 | } |
| 908 | |
| 909 | Future<void> generateSolana(bool hasImplementation) async { |
| 910 | final outputFile = File(solanaOutputPath); |
| 911 | const solanaCommonHeaders = """ |
| 912 | import 'package:cake_wallet/view_model/send/output.dart'; |
| 913 | import 'package:cake_wallet/exchange/provider/jupiter_exchange_provider.dart'; |
| 914 | import 'package:cw_core/amount/money.dart'; |
| 915 | import 'package:cw_core/crypto_currency.dart'; |
| 916 | import 'package:cw_core/output_info.dart'; |
| 917 | import 'package:cw_core/pending_transaction.dart'; |
| 918 | import 'package:cw_core/transaction_info.dart'; |
| 919 | import 'package:cw_core/wallet_base.dart'; |
| 920 | import 'package:cw_core/wallet_credentials.dart'; |
| 921 | import 'package:cw_core/wallet_info.dart'; |
| 922 | import 'package:cw_core/wallet_service.dart'; |
| 923 | import 'package:cw_core/spl_token.dart'; |
| 924 | import 'package:cw_core/transaction_direction.dart'; |
| 925 | import 'package:cw_core/utils/print_verbose.dart'; |
| 926 | |
| 927 | """; |
| 928 | const solanaCWHeaders = """ |
| 929 | import 'package:cw_solana/solana_wallet.dart'; |
| 930 | import 'package:cw_solana/solana_mnemonics.dart'; |
| 931 | import 'package:cw_solana/solana_wallet_service.dart'; |
| 932 | import 'package:cw_solana/solana_transaction_info.dart'; |
| 933 | import 'package:cw_solana/pending_solana_transaction.dart'; |
| 934 | import 'package:cw_solana/solana_transaction_credentials.dart'; |
| 935 | import 'package:cw_solana/solana_wallet_creation_credentials.dart'; |
| 936 | import 'package:cw_solana/default_spl_tokens.dart'; |
| 937 | import 'package:cake_wallet/core/fiat_conversion_service.dart'; |
| 938 | import 'package:cake_wallet/di.dart'; |
| 939 | import 'package:cake_wallet/entities/fiat_api_mode.dart'; |
| 940 | import 'package:cake_wallet/entities/fiat_currency.dart'; |
| 941 | import 'package:cake_wallet/store/settings_store.dart'; |
| 942 | |
| 943 | import 'dart:convert'; |
| 944 | import 'dart:typed_data'; |
| 945 | import 'package:on_chain/solana/solana.dart' hide Store; |
| 946 | """; |
| 947 | const solanaCwPart = "part 'cw_solana.dart';"; |
| 948 | const solanaContent = """ |
| 949 | abstract class Solana { |
| 950 | List<String> getSolanaWordList(String language); |
| 951 | WalletService createSolanaWalletService(bool isDirect); |
| 952 | WalletCredentials createSolanaNewWalletCredentials( |
| 953 | {required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? passphrase}); |
| 954 | WalletCredentials createSolanaRestoreWalletFromSeedCredentials( |
| 955 | {required String name, required String mnemonic, required String password, String? passphrase}); |
| 956 | WalletCredentials createSolanaRestoreWalletFromPrivateKey( |
| 957 | {required String name, required String privateKey, required String password}); |
| 958 | |
| 959 | String getAddress(WalletBase wallet); |
| 960 | String getPrivateKey(WalletBase wallet); |
| 961 | String getPublicKey(WalletBase wallet); |
| 962 | |
| 963 | Object createSolanaTransactionCredentials( |
| 964 | List<Output> outputs, { |
| 965 | required CryptoCurrency currency, |
| 966 | }); |
| 967 | |
| 968 | Object createSolanaTransactionCredentialsRaw( |
| 969 | List<OutputInfo> outputs, { |
| 970 | required CryptoCurrency currency, |
| 971 | }); |
| 972 | List<CryptoCurrency> getSPLTokenCurrencies(WalletBase wallet); |
| 973 | Future<void> addSPLToken( |
| 974 | WalletBase wallet, |
| 975 | CryptoCurrency token, |
| 976 | String contractAddress, |
| 977 | ); |
| 978 | Future<void> deleteSPLToken(WalletBase wallet, CryptoCurrency token); |
| 979 | Future<CryptoCurrency?> getSPLToken(WalletBase wallet, String contractAddress); |
| 980 | |
| 981 | CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction); |
| 982 | String getTokenAddress(CryptoCurrency asset); |
| 983 | List<int>? getValidationLength(CryptoCurrency type); |
| 984 | Money? getEstimateFees(WalletBase wallet); |
| 985 | List<SPLToken> getDefaultSPLTokens(); |
| 986 | List<String> getDefaultTokenContractAddresses(); |
| 987 | List<String> getDefaultTokenSymbols(); |
| 988 | bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress); |
| 989 | Future<bool?> isTokenVerifiedOnJupiter(WalletBase wallet, String mintAddress); |
| 990 | |
| 991 | // Jupiter swap transaction handling |
| 992 | // Signs and prepares a base64-encoded unsigned transaction for sending |
| 993 | Future<PendingTransaction> signAndPrepareJupiterSwapTransaction( |
| 994 | WalletBase wallet, |
| 995 | String base64Transaction, |
| 996 | String requestId, |
| 997 | String destinationAddress, |
| 998 | Money amount, |
| 999 | Money fee, |
| 1000 | ); |
| 1001 | |
| 1002 | // Fast transaction update after sending |
| 1003 | // Polls for a specific transaction by signature with exponential backoff |
| 1004 | // Falls back to full refresh if transaction is not found after max retries |
| 1005 | Future<void> pollForTransaction( |
| 1006 | WalletBase wallet, |
| 1007 | String signature, { |
| 1008 | Duration initialDelay = const Duration(seconds: 1), |
| 1009 | int maxRetries = 5, |
| 1010 | }); |
| 1011 | |
| 1012 | // Updates balances for specific tokens by mint addresses |
| 1013 | // Also updates native SOL balance |
| 1014 | // If tokenMints is null or empty, updates all tokens (full refresh) |
| 1015 | Future<void> updateTokenBalances( |
| 1016 | WalletBase wallet, { |
| 1017 | List<String>? tokenMints, |
| 1018 | }); |
| 1019 | |
| 1020 | Future<void> discoverAndAddWalletTokens(WalletBase wallet); |
| 1021 | |
| 1022 | TransactionInfo getTransactionInfo({ |
| 1023 | required String id, |
| 1024 | required DateTime blockTime, |
| 1025 | required String to, |
| 1026 | required String from, |
| 1027 | required TransactionDirection direction, |
| 1028 | required Money amount, |
| 1029 | required bool isPending, |
| 1030 | required Money fee, |
| 1031 | }); |
| 1032 | } |
| 1033 | |
| 1034 | class JupiterSwapFailedException implements Exception { |
| 1035 | final String message; |
| 1036 | final String signature; |
| 1037 | final num? errorCode; |
| 1038 | final String? errorMessage; |
| 1039 | |
| 1040 | JupiterSwapFailedException({ |
| 1041 | required this.message, |
| 1042 | required this.signature, |
| 1043 | this.errorCode, |
| 1044 | this.errorMessage, |
| 1045 | }); |
| 1046 | |
| 1047 | @override |
| 1048 | String toString() => message; |
| 1049 | } |
| 1050 | |
| 1051 | """; |
| 1052 | |
| 1053 | const solanaEmptyDefinition = 'Solana? solana;\n'; |
| 1054 | const solanaCWDefinition = 'Solana? solana = CWSolana();\n'; |
| 1055 | |
| 1056 | final output = '$solanaCommonHeaders\n' + |
| 1057 | (hasImplementation ? '$solanaCWHeaders\n' : '\n') + |
| 1058 | (hasImplementation ? '$solanaCwPart\n\n' : '\n') + |
| 1059 | (hasImplementation ? solanaCWDefinition : solanaEmptyDefinition) + |
| 1060 | '\n' + |
| 1061 | solanaContent; |
| 1062 | |
| 1063 | if (outputFile.existsSync()) { |
| 1064 | await outputFile.delete(); |
| 1065 | } |
| 1066 | |
| 1067 | await outputFile.writeAsString(output); |
| 1068 | } |
| 1069 | |
| 1070 | Future<void> generateTron(bool hasImplementation) async { |
| 1071 | final outputFile = File(tronOutputPath); |
| 1072 | const tronCommonHeaders = """ |
| 1073 | import 'package:cake_wallet/view_model/send/output.dart'; |
| 1074 | import 'package:cw_core/amount/money.dart'; |
| 1075 | import 'package:cw_core/crypto_currency.dart'; |
| 1076 | import 'package:cw_core/pending_transaction.dart'; |
| 1077 | import 'package:cw_core/output_info.dart'; |
| 1078 | import 'package:cw_core/transaction_info.dart'; |
| 1079 | import 'package:cw_core/wallet_base.dart'; |
| 1080 | import 'package:cw_core/wallet_credentials.dart'; |
| 1081 | import 'package:cw_core/wallet_info.dart'; |
| 1082 | import 'package:cw_core/wallet_service.dart'; |
| 1083 | import 'package:cw_core/tron_token.dart'; |
| 1084 | import 'package:cw_core/transaction_direction.dart'; |
| 1085 | |
| 1086 | """; |
| 1087 | const tronCWHeaders = """ |
| 1088 | import 'package:cw_evm/evm_chain_mnemonics.dart'; |
| 1089 | import 'package:cw_tron/tron_transaction_credentials.dart'; |
| 1090 | import 'package:cw_tron/tron_transaction_info.dart'; |
| 1091 | import 'package:cw_tron/tron_wallet_creation_credentials.dart'; |
| 1092 | |
| 1093 | import 'package:cw_tron/tron_client.dart'; |
| 1094 | import 'package:cw_tron/tron_wallet.dart'; |
| 1095 | import 'package:cw_tron/tron_wallet_service.dart'; |
| 1096 | import 'package:cw_tron/default_tron_tokens.dart'; |
| 1097 | |
| 1098 | """; |
| 1099 | const tronCwPart = "part 'cw_tron.dart';"; |
| 1100 | const tronContent = """ |
| 1101 | abstract class Tron { |
| 1102 | List<String> getTronWordList(String language); |
| 1103 | WalletService createTronWalletService(bool isDirect); |
| 1104 | WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? passphrase}); |
| 1105 | WalletCredentials createTronRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase}); |
| 1106 | WalletCredentials createTronRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password}); |
| 1107 | String getAddress(WalletBase wallet); |
| 1108 | |
| 1109 | Object createTronTransactionCredentials( |
| 1110 | List<Output> outputs, { |
| 1111 | required CryptoCurrency currency, |
| 1112 | }); |
| 1113 | |
| 1114 | List<CryptoCurrency> getTronTokenCurrencies(WalletBase wallet); |
| 1115 | Future<void> addTronToken(WalletBase wallet, CryptoCurrency token, String contractAddress); |
| 1116 | Future<void> deleteTronToken(WalletBase wallet, CryptoCurrency token); |
| 1117 | Future<CryptoCurrency?> getTronToken(WalletBase wallet, String contractAddress); |
| 1118 | |
| 1119 | CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction); |
| 1120 | String getTokenAddress(CryptoCurrency asset); |
| 1121 | String getTronBase58Address(String hexAddress, WalletBase wallet); |
| 1122 | |
| 1123 | Money? getTronNativeEstimatedFee(WalletBase wallet); |
| 1124 | Money? getTronTRC20EstimatedFee(WalletBase wallet); |
| 1125 | |
| 1126 | void updateTronGridUsageState(WalletBase wallet, bool isEnabled); |
| 1127 | List<TronToken> getDefaultTronTokens(); |
| 1128 | List<String> getDefaultTokenContractAddresses(); |
| 1129 | List<String> getDefaultTokenSymbols(); |
| 1130 | bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress); |
| 1131 | TransactionInfo getTransactionInfo({ |
| 1132 | required String id, |
| 1133 | required Money amount, |
| 1134 | Money? fee, |
| 1135 | required TransactionDirection direction, |
| 1136 | required DateTime blockTime, |
| 1137 | String? to, |
| 1138 | String? from, |
| 1139 | required bool isPending, |
| 1140 | }); |
| 1141 | } |
| 1142 | """; |
| 1143 | |
| 1144 | const tronEmptyDefinition = 'Tron? tron;\n'; |
| 1145 | const tronCWDefinition = 'Tron? tron = CWTron();\n'; |
| 1146 | |
| 1147 | final output = '$tronCommonHeaders\n' + |
| 1148 | (hasImplementation ? '$tronCWHeaders\n' : '\n') + |
| 1149 | (hasImplementation ? '$tronCwPart\n\n' : '\n') + |
| 1150 | (hasImplementation ? tronCWDefinition : tronEmptyDefinition) + |
| 1151 | '\n' + |
| 1152 | tronContent; |
| 1153 | |
| 1154 | if (outputFile.existsSync()) { |
| 1155 | await outputFile.delete(); |
| 1156 | } |
| 1157 | |
| 1158 | await outputFile.writeAsString(output); |
| 1159 | } |
| 1160 | |
| 1161 | Future<void> generateZano(bool hasImplementation) async { |
| 1162 | final outputFile = File(zanoOutputPath); |
| 1163 | const zanoCommonHeaders = """ |
| 1164 | import 'package:cake_wallet/utils/language_list.dart'; |
| 1165 | import 'package:cake_wallet/view_model/send/output.dart'; |
| 1166 | import 'package:collection/collection.dart'; |
| 1167 | import 'package:cw_core/crypto_currency.dart'; |
| 1168 | import 'package:cw_core/monero_transaction_priority.dart'; |
| 1169 | import 'package:cw_core/output_info.dart'; |
| 1170 | import 'package:cw_core/transaction_history.dart'; |
| 1171 | import 'package:cw_core/transaction_info.dart'; |
| 1172 | import 'package:cw_core/transaction_priority.dart'; |
| 1173 | import 'package:cw_core/wallet_base.dart'; |
| 1174 | import 'package:cw_core/wallet_credentials.dart'; |
| 1175 | import 'package:cw_core/wallet_info.dart'; |
| 1176 | import 'package:cw_core/wallet_service.dart'; |
| 1177 | import 'package:cw_core/zano_asset.dart'; |
| 1178 | import 'package:hive/hive.dart'; |
| 1179 | """; |
| 1180 | const zanoCWHeaders = """ |
| 1181 | import 'package:cw_zano/mnemonics/english.dart'; |
| 1182 | import 'package:cw_zano/model/zano_transaction_credentials.dart'; |
| 1183 | import 'package:cw_zano/model/zano_transaction_info.dart'; |
| 1184 | import 'package:cw_zano/zano_formatter.dart'; |
| 1185 | import 'package:cw_zano/zano_wallet.dart'; |
| 1186 | import 'package:cw_zano/zano_wallet_service.dart'; |
| 1187 | import 'package:cw_zano/zano_wallet_api.dart' as api; |
| 1188 | import 'package:cw_zano/zano_utils.dart'; |
| 1189 | """; |
| 1190 | const zanoCwPart = "part 'cw_zano.dart';"; |
| 1191 | const zanoContent = """ |
| 1192 | abstract class Zano { |
| 1193 | TransactionPriority getDefaultTransactionPriority(); |
| 1194 | TransactionPriority deserializeMoneroTransactionPriority({required int raw}); |
| 1195 | List<TransactionPriority> getTransactionPriorities(); |
| 1196 | List<String> getWordList(String language); |
| 1197 | |
| 1198 | WalletCredentials createZanoRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic}); |
| 1199 | WalletCredentials createZanoNewWalletCredentials({required String name, required String? password, required String? passphrase}); |
| 1200 | Map<String, String> getKeys(Object wallet); |
| 1201 | Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency}); |
| 1202 | double formatterIntAmountToDouble({required int amount, required CryptoCurrency currency, required bool forFee}); |
| 1203 | int formatterParseAmount({required String amount, required CryptoCurrency currency}); |
| 1204 | WalletService createZanoWalletService(); |
| 1205 | CryptoCurrency? assetOfTransaction(WalletBase wallet, TransactionInfo tx); |
| 1206 | List<ZanoAsset> getZanoAssets(WalletBase wallet); |
| 1207 | String getZanoAssetAddress(CryptoCurrency asset); |
| 1208 | Future<void> changeZanoAssetAvailability(WalletBase wallet, CryptoCurrency token); |
| 1209 | Future<CryptoCurrency> addZanoAssetById(WalletBase wallet, String assetId); |
| 1210 | Future<void> deleteZanoAsset(WalletBase wallet, CryptoCurrency token); |
| 1211 | Future<CryptoCurrency?> getZanoAsset(WalletBase wallet, String contractAddress); |
| 1212 | String getAddress(WalletBase wallet); |
| 1213 | bool validateAddress(String address); |
| 1214 | Map<String, List<int>> debugCallLength(); |
| 1215 | bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress); |
| 1216 | } |
| 1217 | """; |
| 1218 | const zanoEmptyDefinition = 'Zano? zano;\n'; |
| 1219 | const zanoCWDefinition = 'Zano? zano = CWZano();\n'; |
| 1220 | |
| 1221 | final output = '$zanoCommonHeaders\n' + |
| 1222 | (hasImplementation ? '$zanoCWHeaders\n' : '\n') + |
| 1223 | (hasImplementation ? '$zanoCwPart\n\n' : '\n') + |
| 1224 | (hasImplementation ? zanoCWDefinition : zanoEmptyDefinition) + |
| 1225 | '\n' + |
| 1226 | zanoContent; |
| 1227 | |
| 1228 | if (outputFile.existsSync()) { |
| 1229 | await outputFile.delete(); |
| 1230 | } |
| 1231 | |
| 1232 | await outputFile.writeAsString(output); |
| 1233 | } |
| 1234 | |
| 1235 | Future<void> generateDecred(bool hasImplementation) async { |
| 1236 | final outputFile = File(decredOutputPath); |
| 1237 | const decredCommonHeaders = """ |
| 1238 | import 'package:cw_core/wallet_credentials.dart'; |
| 1239 | import 'package:cw_core/address_info.dart'; |
| 1240 | import 'package:cw_core/wallet_info.dart'; |
| 1241 | import 'package:cw_core/transaction_priority.dart'; |
| 1242 | import 'package:cw_core/output_info.dart'; |
| 1243 | import 'package:cw_core/wallet_service.dart'; |
| 1244 | import 'package:cw_core/unspent_transaction_output.dart'; |
| 1245 | import 'package:cw_core/unspent_coins_info.dart'; |
| 1246 | import 'package:cake_wallet/view_model/send/output.dart'; |
| 1247 | import 'package:hive/hive.dart'; |
| 1248 | """; |
| 1249 | const decredCWHeaders = """ |
| 1250 | import 'package:cw_decred/transaction_priority.dart'; |
| 1251 | import 'package:cw_decred/wallet.dart'; |
| 1252 | import 'package:cw_decred/wallet_service.dart'; |
| 1253 | import 'package:cw_decred/wallet_creation_credentials.dart'; |
| 1254 | import 'package:cw_decred/transaction_credentials.dart'; |
| 1255 | import 'package:cw_decred/mnemonic.dart'; |
| 1256 | """; |
| 1257 | const decredCwPart = "part 'cw_decred.dart';"; |
| 1258 | const decredContent = """ |
| 1259 | |
| 1260 | abstract class Decred { |
| 1261 | WalletCredentials createDecredNewWalletCredentials( |
| 1262 | {required String name, String? password, String? passphrase, String? mnemonic, WalletInfo? walletInfo}); |
| 1263 | WalletCredentials createDecredRestoreWalletFromSeedCredentials( |
| 1264 | {required String name, required String mnemonic, required String password, String? passphrase}); |
| 1265 | WalletCredentials createDecredRestoreWalletFromPubkeyCredentials( |
| 1266 | {required String name, required String pubkey, required String password}); |
| 1267 | WalletService createDecredWalletService(Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect); |
| 1268 | |
| 1269 | List<TransactionPriority> getTransactionPriorities(); |
| 1270 | TransactionPriority getDecredTransactionPriorityMedium(); |
| 1271 | TransactionPriority getDecredTransactionPrioritySlow(); |
| 1272 | TransactionPriority deserializeDecredTransactionPriority(int raw); |
| 1273 | |
| 1274 | Object createDecredTransactionCredentials(List<Output> outputs, TransactionPriority priority); |
| 1275 | |
| 1276 | List<WalletInfoAddressInfo> getAddressInfos(Object wallet); |
| 1277 | Future<void> updateAddress(Object wallet, String address, String label); |
| 1278 | Future<void> generateNewAddress(Object wallet, String label); |
| 1279 | |
| 1280 | List<Unspent> getUnspents(Object wallet); |
| 1281 | void updateUnspents(Object wallet); |
| 1282 | |
| 1283 | int heightByDate(DateTime date); |
| 1284 | |
| 1285 | List<String> getDecredWordList(); |
| 1286 | |
| 1287 | String pubkey(Object wallet); |
| 1288 | } |
| 1289 | """; |
| 1290 | |
| 1291 | const decredEmptyDefinition = 'Decred? decred;\n'; |
| 1292 | const decredCWDefinition = 'Decred? decred = CWDecred();\n'; |
| 1293 | |
| 1294 | final output = '$decredCommonHeaders\n' + |
| 1295 | (hasImplementation ? '$decredCWHeaders\n' : '\n') + |
| 1296 | (hasImplementation ? '$decredCwPart\n\n' : '\n') + |
| 1297 | (hasImplementation ? decredCWDefinition : decredEmptyDefinition) + |
| 1298 | '\n' + |
| 1299 | decredContent; |
| 1300 | |
| 1301 | if (outputFile.existsSync()) { |
| 1302 | await outputFile.delete(); |
| 1303 | } |
| 1304 | |
| 1305 | await outputFile.writeAsString(output); |
| 1306 | } |
| 1307 | |
| 1308 | Future<void> generateDogecoin(bool hasImplementation) async { |
| 1309 | final outputFile = File(dogecoinOutputPath); |
| 1310 | const dogecoinCommonHeaders = """ |
| 1311 | import 'package:cw_core/transaction_priority.dart'; |
| 1312 | import 'package:cw_core/unspent_coins_info.dart'; |
| 1313 | import 'package:cw_core/wallet_credentials.dart'; |
| 1314 | import 'package:cw_core/wallet_info.dart'; |
| 1315 | import 'package:cw_core/wallet_service.dart'; |
| 1316 | import 'package:hive/hive.dart'; |
| 1317 | """; |
| 1318 | const dogecoinCWHeaders = """ |
| 1319 | import 'package:cw_dogecoin/cw_dogecoin.dart'; |
| 1320 | """; |
| 1321 | const dogecoinCwPart = "part 'cw_dogecoin.dart';"; |
| 1322 | const dogecoinContent = """ |
| 1323 | abstract class DogeCoin { |
| 1324 | |
| 1325 | WalletService createDogeCoinWalletService(Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect); |
| 1326 | |
| 1327 | WalletCredentials createDogeCoinNewWalletCredentials( |
| 1328 | {required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic}); |
| 1329 | |
| 1330 | WalletCredentials createDogeCoinRestoreWalletFromSeedCredentials( |
| 1331 | {required String name, required String mnemonic, required String password, String? passphrase}); |
| 1332 | |
| 1333 | TransactionPriority deserializeDogeCoinTransactionPriority(int raw); |
| 1334 | |
| 1335 | TransactionPriority getDefaultTransactionPriority(); |
| 1336 | |
| 1337 | List<TransactionPriority> getTransactionPriorities(); |
| 1338 | |
| 1339 | TransactionPriority getDogeCoinTransactionPrioritySlow(); |
| 1340 | } |
| 1341 | """; |
| 1342 | |
| 1343 | const dogecoinEmptyDefinition = 'DogeCoin? dogecoin;\n'; |
| 1344 | const dogecoinCWDefinition = 'DogeCoin? dogecoin = CWDogeCoin();\n'; |
| 1345 | |
| 1346 | final output = '$dogecoinCommonHeaders\n' + |
| 1347 | (hasImplementation ? '$dogecoinCWHeaders\n' : '\n') + |
| 1348 | (hasImplementation ? '$dogecoinCwPart\n\n' : '\n') + |
| 1349 | (hasImplementation ? dogecoinCWDefinition : dogecoinEmptyDefinition) + |
| 1350 | '\n' + |
| 1351 | dogecoinContent; |
| 1352 | |
| 1353 | if (outputFile.existsSync()) { |
| 1354 | await outputFile.delete(); |
| 1355 | } |
| 1356 | |
| 1357 | await outputFile.writeAsString(output); |
| 1358 | } |
| 1359 | |
| 1360 | Future<void> generateEVM(bool hasImplementation) async { |
| 1361 | final outputFile = File(evmOutputPath); |
| 1362 | const evmCommonHeaders = """ |
| 1363 | import 'dart:math' as math; |
| 1364 | import 'package:cake_wallet/core/utilities.dart'; |
| 1365 | import 'package:cake_wallet/view_model/send/output.dart'; |
| 1366 | import 'package:cw_core/amount/money.dart'; |
| 1367 | import 'package:cw_core/pending_transaction.dart'; |
| 1368 | import 'package:cw_core/crypto_currency.dart'; |
| 1369 | import 'package:cw_core/erc20_token.dart'; |
| 1370 | import 'package:cw_core/hardware/hardware_account_data.dart'; |
| 1371 | import 'package:cw_core/hardware/hardware_wallet_service.dart'; |
| 1372 | import 'package:cw_core/output_info.dart'; |
| 1373 | import 'package:cw_core/pending_transaction.dart'; |
| 1374 | import 'package:cw_core/transaction_info.dart'; |
| 1375 | import 'package:cw_core/transaction_priority.dart'; |
| 1376 | import 'package:cw_core/wallet_base.dart'; |
| 1377 | import 'package:cw_core/wallet_credentials.dart'; |
| 1378 | import 'package:cw_core/wallet_info.dart'; |
| 1379 | import 'package:cw_core/wallet_service.dart'; |
| 1380 | import 'package:cw_core/wallet_type.dart'; |
| 1381 | import 'package:cw_core/node.dart'; |
| 1382 | import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger; |
| 1383 | import 'package:bitbox_flutter/bitbox_flutter.dart' as bitbox; |
| 1384 | import 'package:trezor_connect/trezor_connect.dart' as trezor; |
| 1385 | import 'package:web3dart/web3dart.dart'; |
| 1386 | import 'package:cw_core/transaction_direction.dart'; |
| 1387 | |
| 1388 | """; |
| 1389 | const evmCWHeaders = """ |
| 1390 | import 'package:cake_wallet/core/fiat_conversion_service.dart'; |
| 1391 | import 'package:cake_wallet/di.dart'; |
| 1392 | import 'package:cake_wallet/entities/fiat_api_mode.dart'; |
| 1393 | import 'package:cake_wallet/entities/fiat_currency.dart'; |
| 1394 | import 'package:cake_wallet/store/settings_store.dart'; |
| 1395 | import 'package:cw_evm/utils/evm_chain_formatter.dart'; |
| 1396 | import 'package:cw_evm/evm_chain_mnemonics.dart'; |
| 1397 | import 'package:cw_evm/pending_evm_chain_transaction.dart'; |
| 1398 | import 'package:cw_evm/evm_chain_registry.dart'; |
| 1399 | import 'package:cw_evm/evm_erc20_balance.dart'; |
| 1400 | import 'package:cw_evm/evm_chain_transaction_credentials.dart'; |
| 1401 | import 'package:cw_evm/evm_chain_transaction_info.dart'; |
| 1402 | import 'package:cw_evm/evm_chain_transaction_priority.dart'; |
| 1403 | import 'package:cw_evm/hardware/evm_chain_bitbox_credentials.dart'; |
| 1404 | import 'package:cw_evm/hardware/evm_chain_ledger_credentials.dart'; |
| 1405 | import 'package:cw_evm/hardware/evm_chain_trezor_credentials.dart'; |
| 1406 | import 'package:cw_evm/evm_chain_wallet.dart'; |
| 1407 | import 'package:cw_evm/hardware/evm_chain_bitbox_service.dart'; |
| 1408 | import 'package:cw_evm/hardware/evm_chain_ledger_service.dart'; |
| 1409 | import 'package:cw_evm/hardware/evm_chain_trezor_service.dart'; |
| 1410 | import 'package:cw_evm/evm_chain_wallet_service.dart'; |
| 1411 | import 'package:cw_evm/evm_chain_wallet_creation_credentials.dart'; |
| 1412 | import 'package:cw_evm/utils/evm_chain_utils.dart'; |
| 1413 | import 'package:cw_evm/evm_chain_default_tokens.dart'; |
| 1414 | import 'package:cw_evm/deuro/deuro_savings.dart'; |
| 1415 | import 'package:cw_evm/usdt0/usdt0_config.dart'; |
| 1416 | import 'package:cw_evm/usdt0/usdt0_quote.dart'; |
| 1417 | import 'package:cw_evm/usdt0/usdt0_service.dart'; |
| 1418 | import 'package:eth_sig_util/util/utils.dart'; |
| 1419 | export 'package:cw_evm/evm_chain_transaction_priority.dart'; |
| 1420 | export 'package:cw_evm/evm_erc20_balance.dart'; |
| 1421 | export 'package:cw_evm/usdt0/usdt0_quote.dart'; |
| 1422 | |
| 1423 | """; |
| 1424 | const evmCwPart = "part 'cw_evm.dart';"; |
| 1425 | const evmContent = """ |
| 1426 | /// Unified abstract class for all EVM chains |
| 1427 | /// |
| 1428 | /// This replaces separate proxy classes (Ethereum, Polygon, Base, Arbitrum) |
| 1429 | /// with a single unified interface that works for all EVM chains. |
| 1430 | /// Methods take WalletType parameter to determine chain-specific behavior. |
| 1431 | abstract class EVM { |
| 1432 | List<String> getEVMWordList(String language); |
| 1433 | |
| 1434 | /// Create unified wallet service for any EVM chain |
| 1435 | WalletService createEVMWalletService(WalletType walletType, bool isDirect); |
| 1436 | |
| 1437 | /// Generic credential creation - uses WalletType |
| 1438 | WalletCredentials createEVMNewWalletCredentials({ |
| 1439 | required String name, |
| 1440 | WalletInfo? walletInfo, |
| 1441 | String? password, |
| 1442 | String? mnemonic, |
| 1443 | String? passphrase, |
| 1444 | }); |
| 1445 | |
| 1446 | WalletCredentials createEVMRestoreWalletFromSeedCredentials({ |
| 1447 | required String name, |
| 1448 | required String mnemonic, |
| 1449 | required String password, |
| 1450 | String? passphrase, |
| 1451 | }); |
| 1452 | |
| 1453 | WalletCredentials createEVMRestoreWalletFromPrivateKey({ |
| 1454 | required String name, |
| 1455 | required String privateKey, |
| 1456 | required String password, |
| 1457 | }); |
| 1458 | |
| 1459 | WalletCredentials createEVMHardwareWalletCredentials({ |
| 1460 | required String name, |
| 1461 | required HardwareAccountData hwAccountData, |
| 1462 | WalletInfo? walletInfo, |
| 1463 | }); |
| 1464 | |
| 1465 | // Generic methods that work for all EVM chains |
| 1466 | String getAddress(WalletBase wallet); |
| 1467 | String getPrivateKey(WalletBase wallet); |
| 1468 | String getPublicKey(WalletBase wallet); |
| 1469 | TransactionPriority getDefaultTransactionPriority(); |
| 1470 | TransactionPriority getEVMTransactionPrioritySlow(); |
| 1471 | List<TransactionPriority> getTransactionPriorities(); |
| 1472 | TransactionPriority deserializeEVMTransactionPriority(int raw); |
| 1473 | |
| 1474 | Object createEVMTransactionCredentials( |
| 1475 | List<Output> outputs, { |
| 1476 | required TransactionPriority? priority, |
| 1477 | required CryptoCurrency currency, |
| 1478 | int? feeRate, |
| 1479 | bool useBlinkProtection = true, |
| 1480 | }); |
| 1481 | |
| 1482 | Object createEVMTransactionCredentialsRaw( |
| 1483 | List<OutputInfo> outputs, { |
| 1484 | TransactionPriority? priority, |
| 1485 | required CryptoCurrency currency, |
| 1486 | required int feeRate, |
| 1487 | bool useBlinkProtection = true, |
| 1488 | }); |
| 1489 | |
| 1490 | int formatterEVMParseAmount(String amount); |
| 1491 | |
| 1492 | List<Erc20Token> getERC20Currencies(WalletBase wallet); |
| 1493 | Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token); |
| 1494 | Future<void> deleteErc20Token(WalletBase wallet, CryptoCurrency token); |
| 1495 | Future<void> removeTokenTransactionsInHistory(WalletBase wallet, CryptoCurrency token); |
| 1496 | Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress); |
| 1497 | |
| 1498 | CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction); |
| 1499 | void updateScanProviderUsageState(WalletBase wallet, bool isEnabled); |
| 1500 | Web3Client? getWeb3Client(WalletBase wallet); |
| 1501 | String getTokenAddress(CryptoCurrency asset); |
| 1502 | |
| 1503 | Future<bool> isApprovalRequired( |
| 1504 | WalletBase wallet, |
| 1505 | String tokenContract, |
| 1506 | String spender, |
| 1507 | BigInt requiredAmount, |
| 1508 | ); |
| 1509 | |
| 1510 | Future<BigInt?> getAllowance( |
| 1511 | WalletBase wallet, |
| 1512 | String tokenContract, |
| 1513 | String spender); |
| 1514 | |
| 1515 | Future<PendingTransaction> createTokenApproval( |
| 1516 | WalletBase wallet, |
| 1517 | Money amount, |
| 1518 | String spender, |
| 1519 | TransactionPriority? priority, |
| 1520 | {bool useBlinkProtection = true} |
| 1521 | ); |
| 1522 | |
| 1523 | Future<PendingTransaction> createRawCallDataTransaction( |
| 1524 | WalletBase wallet, |
| 1525 | String to, |
| 1526 | String dataHex, |
| 1527 | Money valueWei, |
| 1528 | TransactionPriority? priority, |
| 1529 | {bool useBlinkProtection = true, |
| 1530 | String? sourceTokenAddress, |
| 1531 | BigInt? sourceTokenAmount} |
| 1532 | ); |
| 1533 | |
| 1534 | // Hardware wallet methods |
| 1535 | Future<void> setHardwareWalletService(WalletBase wallet, HardwareWalletService service); |
| 1536 | HardwareWalletService getLedgerHardwareWalletService(ledger.LedgerConnection connection); |
| 1537 | HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxManager manager); |
| 1538 | HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect connect); |
| 1539 | |
| 1540 | // Utility methods |
| 1541 | List<Erc20Token> getDefaultTokensByChainId(int chainId); |
| 1542 | List<String> getDefaultTokenContractAddresses(WalletBase wallet); |
| 1543 | List<String> getDefaultTokenSymbols(WalletBase wallet); |
| 1544 | bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress); |
| 1545 | String? getEVMNativeEstimatedFee(WalletBase wallet); |
| 1546 | String? getEVMERC20EstimatedFee(WalletBase wallet); |
| 1547 | |
| 1548 | // Chain-specific integrations (optional, can be null for non-Ethereum chains) |
| 1549 | Future<Money>? getDEuroSavingsBalance(WalletBase wallet) => null; |
| 1550 | Future<Money>? getDEuroSavingsV1Balance(WalletBase wallet) => null; |
| 1551 | Future<Money>? getDEuroAccruedInterest(WalletBase wallet) => null; |
| 1552 | Future<BigInt>? getDEuroInterestRate(WalletBase wallet) => null; |
| 1553 | Future<BigInt>? getDEuroSavingsApproved(WalletBase wallet) => null; |
| 1554 | Future<PendingTransaction>? withdrawDEuroSavingV1(WalletBase wallet, TransactionPriority priority) => null; |
| 1555 | Future<PendingTransaction>? addDEuroSaving(WalletBase wallet, BigInt amount, TransactionPriority priority) => null; |
| 1556 | Future<PendingTransaction>? removeDEuroSaving(WalletBase wallet, BigInt amount, TransactionPriority priority) => null; |
| 1557 | Future<PendingTransaction>? reinvestDEuroInterest(WalletBase wallet, TransactionPriority priority) => null; |
| 1558 | Future<PendingTransaction>? enableDEuroSaving(WalletBase wallet, TransactionPriority priority) => null; |
| 1559 | |
| 1560 | // Registry helper methods (for backward compatibility helpers) |
| 1561 | int getChainIdByWalletType(WalletType walletType); |
| 1562 | String getChainNameByWalletType(WalletType walletType); |
| 1563 | String getTokenNameByWalletType(WalletType walletType); |
| 1564 | String getCaip2ByChainId(int chainId); |
| 1565 | int? getChainIdByTag(String tag); |
| 1566 | int? getChainIdByTitle(String title); |
| 1567 | WalletType? getWalletTypeByChainId(int chainId); |
| 1568 | String getChainNameByChainId(int chainId); |
| 1569 | String getTokenNameByChainId(int chainId); |
| 1570 | // Chain selection methods |
| 1571 | List<ChainInfo> getAllChains(); |
| 1572 | ChainInfo? getCurrentChain(WalletBase wallet); |
| 1573 | ChainInfo? getChainInfoByChainId(int chainId); |
| 1574 | |
| 1575 | |
| 1576 | int? getSelectedChainId(WalletBase wallet); |
| 1577 | Future<void> selectChain(WalletBase wallet, int chainId, {required Node node}); |
| 1578 | |
| 1579 | String? getExplorerUrlForChainId(int chainId, {bool showProtocol = true}); |
| 1580 | |
| 1581 | Future<bool?> getTransactionReceipt(WalletBase wallet, String txHash); |
| 1582 | |
| 1583 | bool hasPriorityFee(int chainId); |
| 1584 | |
| 1585 | bool isUSDT0Token(WalletBase wallet, CryptoCurrency token); |
| 1586 | List<ChainInfo> getUSDT0DestinationChains(WalletBase wallet); |
| 1587 | |
| 1588 | Future<BridgeQuote> quoteUSDT0Transfer({ |
| 1589 | required WalletBase wallet, |
| 1590 | required int sourceChainId, |
| 1591 | required int destinationChainId, |
| 1592 | required BigInt amount, |
| 1593 | required String recipientAddress, |
| 1594 | }); |
| 1595 | |
| 1596 | Future<PendingTransaction> executeUSDT0Transfer({ |
| 1597 | required WalletBase wallet, |
| 1598 | required CryptoCurrency token, |
| 1599 | required int sourceChainId, |
| 1600 | required int destinationChainId, |
| 1601 | required BigInt amount, |
| 1602 | required String recipientAddress, |
| 1603 | required BridgeQuote quote, |
| 1604 | required TransactionPriority priority, |
| 1605 | bool useBlinkProtection = true, |
| 1606 | }); |
| 1607 | |
| 1608 | Future<EvmWalletConnectFeeQuote?> getWCBufferedFeeQuote( |
| 1609 | WalletBase wallet, |
| 1610 | TransactionPriority priority, |
| 1611 | ); |
| 1612 | |
| 1613 | TransactionInfo getTransactionInfo({ |
| 1614 | required String id, |
| 1615 | required int height, |
| 1616 | required Money amount, |
| 1617 | required Money fee, |
| 1618 | required String tokenSymbol, |
| 1619 | int exponent = 18, |
| 1620 | required TransactionDirection direction, |
| 1621 | required bool isPending, |
| 1622 | required DateTime date, |
| 1623 | required int confirmations, |
| 1624 | String? to, |
| 1625 | String? from, |
| 1626 | String? evmSignatureName, |
| 1627 | String? contractAddress, |
| 1628 | required int chainId, |
| 1629 | }); |
| 1630 | |
| 1631 | Future<void> discoverAndAddWalletTokens(WalletBase wallet); |
| 1632 | } |
| 1633 | |
| 1634 | class ChainInfo { |
| 1635 | const ChainInfo({ |
| 1636 | required this.chainId, |
| 1637 | required this.name, |
| 1638 | required this.shortCode, |
| 1639 | required this.currency, |
| 1640 | }); |
| 1641 | |
| 1642 | final int chainId; |
| 1643 | final String name; |
| 1644 | final String shortCode; |
| 1645 | final CryptoCurrency currency; |
| 1646 | |
| 1647 | @override |
| 1648 | bool operator ==(Object other) => |
| 1649 | identical(this, other) || |
| 1650 | other is ChainInfo && runtimeType == other.runtimeType && chainId == other.chainId; |
| 1651 | |
| 1652 | @override |
| 1653 | int get hashCode => chainId.hashCode; |
| 1654 | } |
| 1655 | |
| 1656 | class EvmWalletConnectFeeQuote { |
| 1657 | const EvmWalletConnectFeeQuote({ |
| 1658 | required this.maxFeePerGasWei, |
| 1659 | required this.maxPriorityFeePerGasWei, |
| 1660 | this.latestBaseFeeWei, |
| 1661 | }); |
| 1662 | |
| 1663 | final int maxFeePerGasWei; |
| 1664 | final int maxPriorityFeePerGasWei; |
| 1665 | final int? latestBaseFeeWei; |
| 1666 | } |
| 1667 | |
| 1668 | class BridgeQuote { |
| 1669 | const BridgeQuote({ |
| 1670 | required this.nativeFee, |
| 1671 | required this.lzTokenFee, |
| 1672 | }); |
| 1673 | |
| 1674 | final BigInt nativeFee; |
| 1675 | final BigInt lzTokenFee; |
| 1676 | } |
| 1677 | """; |
| 1678 | |
| 1679 | const evmEmptyDefinition = 'EVM? evm;\n'; |
| 1680 | const evmCWDefinition = 'EVM? evm = CWEVM();\n'; |
| 1681 | |
| 1682 | final output = '$evmCommonHeaders\n' + |
| 1683 | (hasImplementation ? '$evmCWHeaders\n' : '\n') + |
| 1684 | (hasImplementation ? '$evmCwPart\n\n' : '\n') + |
| 1685 | (hasImplementation ? evmCWDefinition : evmEmptyDefinition) + |
| 1686 | '\n' + |
| 1687 | evmContent; |
| 1688 | |
| 1689 | if (outputFile.existsSync()) { |
| 1690 | await outputFile.delete(); |
| 1691 | } |
| 1692 | |
| 1693 | await outputFile.writeAsString(output); |
| 1694 | } |
| 1695 | |
| 1696 | Future<void> generateZcash(bool hasImplementation) async { |
| 1697 | final outputFile = File(zcashOutputPath); |
| 1698 | const zcashCommonHeaders = """ |
| 1699 | import 'package:cake_wallet/view_model/send/output.dart'; |
| 1700 | import 'package:cw_core/balance.dart'; |
| 1701 | import 'package:cw_core/crypto_amount_format.dart'; |
| 1702 | import 'package:cw_core/crypto_currency.dart'; |
| 1703 | import 'package:cw_core/output_info.dart'; |
| 1704 | import 'package:cw_core/transaction_history.dart'; |
| 1705 | import 'package:cw_core/transaction_info.dart'; |
| 1706 | import 'package:cw_core/transaction_priority.dart'; |
| 1707 | import 'package:cw_core/monero_transaction_priority.dart'; |
| 1708 | import 'package:cw_core/wallet_base.dart'; |
| 1709 | import 'package:cw_core/wallet_credentials.dart'; |
| 1710 | import 'package:cw_core/wallet_info.dart'; |
| 1711 | import 'package:cw_core/wallet_service.dart'; |
| 1712 | import 'package:cw_core/receive_page_option.dart'; |
| 1713 | import 'package:cw_core/wallet_addresses.dart'; |
| 1714 | |
| 1715 | """; |
| 1716 | const zcashCWHeaders = """ |
| 1717 | import 'package:cw_zcash/cw_zcash.dart'; |
| 1718 | import 'package:cw_zcash/src/zcash_wallet_addresses.dart'; |
| 1719 | |
| 1720 | """; |
| 1721 | const zcashCwPart = "part 'cw_zcash.dart';"; |
| 1722 | const zcashContent = """ |
| 1723 | abstract class Zcash { |
| 1724 | List<String> getZcashWordList(String language); |
| 1725 | WalletService createZcashWalletService(bool isDirect); |
| 1726 | WalletCredentials createZcashNewWalletCredentials( |
| 1727 | {required String name, |
| 1728 | WalletInfo? walletInfo, |
| 1729 | String? password, |
| 1730 | String? mnemonic, |
| 1731 | required String? passphrase, |
| 1732 | int network = 0}); |
| 1733 | WalletCredentials createZcashRestoreWalletFromSeedCredentials( |
| 1734 | {required String name, |
| 1735 | required String mnemonic, |
| 1736 | required String password, |
| 1737 | String? passphrase, |
| 1738 | required int? height, |
| 1739 | int network = 0}); |
| 1740 | WalletCredentials createZcashRestoreWalletFromPrivateKey( |
| 1741 | {required String name, required String privateKey, required String password, required int height}); |
| 1742 | String getAddress(WalletBase wallet); |
| 1743 | String getPrivateKey(WalletBase wallet); |
| 1744 | String getPublicKey(WalletBase wallet); |
| 1745 | Map<String, String> getKeys(Object wallet); |
| 1746 | |
| 1747 | Object createZcashTransactionCredentials( |
| 1748 | List<Output> outputs, { |
| 1749 | required CryptoCurrency currency, |
| 1750 | int? feeRate, |
| 1751 | }); |
| 1752 | |
| 1753 | Object createZcashTransactionCredentialsRaw( |
| 1754 | List<OutputInfo> outputs, { |
| 1755 | required CryptoCurrency currency, |
| 1756 | required int feeRate, |
| 1757 | }); |
| 1758 | |
| 1759 | int formatterZcashParseAmount(String amount); |
| 1760 | double formatterZcashAmountToDouble({TransactionInfo? transaction, BigInt? amount}); |
| 1761 | String formatterZcashAmountToString({required int amount}); |
| 1762 | |
| 1763 | List<WalletInfoAddressInfo> getAddressInfos(Object wallet); |
| 1764 | |
| 1765 | TransactionPriority getDefaultTransactionPriority(); |
| 1766 | TransactionPriority getZcashTransactionPriorityAutomatic(); |
| 1767 | TransactionPriority deserializeZcashTransactionPriority({required int raw}); |
| 1768 | List<TransactionPriority> getTransactionPriorities(); |
| 1769 | ReceivePageOption getSelectedAddressType(Object wallet); |
| 1770 | dynamic getZcashAddressType(ReceivePageOption option); |
| 1771 | bool hasSelectedTransparentAddress(Object wallet); |
| 1772 | bool isRotatingAddressOption(ReceivePageOption option); |
| 1773 | Future<void> setAddressType(Object wallet, dynamic option); |
| 1774 | dynamic getOptionToType(ReceivePageOption option); |
| 1775 | void unlockDatabase(String password); |
| 1776 | Future<int> getHeightByDate(DateTime date); |
| 1777 | bool showMissingFundsCard(WalletBase wallet); |
| 1778 | Future<void> rescanInternalChange(WalletBase wallet); |
| 1779 | bool ironwoodActive(WalletAddresses walletAddresses); |
| 1780 | Future<bool> hasOrchardMigratableBalance(WalletBase wallet); |
| 1781 | } |
| 1782 | """; |
| 1783 | |
| 1784 | const zcashEmptyDefinition = 'Zcash? zcash;\n'; |
| 1785 | const zcashCWDefinition = 'Zcash? zcash = CWZcash();\n'; |
| 1786 | |
| 1787 | final output = '$zcashCommonHeaders\n' + |
| 1788 | (hasImplementation ? '$zcashCWHeaders\n' : '\n') + |
| 1789 | (hasImplementation ? '$zcashCwPart\n\n' : '\n') + |
| 1790 | (hasImplementation ? zcashCWDefinition : zcashEmptyDefinition) + |
| 1791 | '\n' + |
| 1792 | zcashContent; |
| 1793 | |
| 1794 | if (outputFile.existsSync()) { |
| 1795 | await outputFile.delete(); |
| 1796 | } |
| 1797 | |
| 1798 | await outputFile.writeAsString(output); |
| 1799 | } |
| 1800 | |
| 1801 | Future<void> generatePubspec({ |
| 1802 | required bool hasMonero, |
| 1803 | required bool hasBitcoin, |
| 1804 | required bool hasEthereum, |
| 1805 | required bool hasNano, |
| 1806 | required bool hasBanano, |
| 1807 | required bool hasBitcoinCash, |
| 1808 | required bool hasFlutterSecureStorage, |
| 1809 | required bool hasPolygon, |
| 1810 | required bool hasSolana, |
| 1811 | required bool hasTron, |
| 1812 | required bool hasWownero, |
| 1813 | required bool hasZano, |
| 1814 | required bool hasDecred, |
| 1815 | required bool hasDogecoin, |
| 1816 | required bool hasBase, |
| 1817 | required bool hasArbitrum, |
| 1818 | required bool hasBsc, |
| 1819 | required bool hasZcash, |
| 1820 | }) async { |
| 1821 | const cwCore = """ |
| 1822 | cw_core: |
| 1823 | path: ./cw_core |
| 1824 | """; |
| 1825 | const cwMonero = """ |
| 1826 | cw_monero: |
| 1827 | path: ./cw_monero |
| 1828 | """; |
| 1829 | const cwBitcoin = """ |
| 1830 | cw_bitcoin: |
| 1831 | path: ./cw_bitcoin |
| 1832 | """; |
| 1833 | const flutterSecureStorage = """ |
| 1834 | flutter_secure_storage: |
| 1835 | git: |
| 1836 | url: https://github.com/cake-tech/flutter_secure_storage.git |
| 1837 | path: flutter_secure_storage |
| 1838 | ref: ca897a08677edb443b366352dd7412735e098e7b |
| 1839 | """; |
| 1840 | const cwBitcoinCash = """ |
| 1841 | cw_bitcoin_cash: |
| 1842 | path: ./cw_bitcoin_cash |
| 1843 | """; |
| 1844 | const cwNano = """ |
| 1845 | cw_nano: |
| 1846 | path: ./cw_nano |
| 1847 | """; |
| 1848 | const cwBanano = """ |
| 1849 | cw_banano: |
| 1850 | path: ./cw_banano |
| 1851 | """; |
| 1852 | const cwSolana = """ |
| 1853 | cw_solana: |
| 1854 | path: ./cw_solana |
| 1855 | """; |
| 1856 | const cwEVM = """ |
| 1857 | cw_evm: |
| 1858 | path: ./cw_evm |
| 1859 | """; |
| 1860 | const cwTron = """ |
| 1861 | cw_tron: |
| 1862 | path: ./cw_tron |
| 1863 | """; |
| 1864 | const cwWownero = """ |
| 1865 | cw_wownero: |
| 1866 | path: ./cw_wownero |
| 1867 | """; |
| 1868 | const cwZano = """ |
| 1869 | cw_zano: |
| 1870 | path: ./cw_zano |
| 1871 | """; |
| 1872 | const cwDecred = """ |
| 1873 | cw_decred: |
| 1874 | path: ./cw_decred |
| 1875 | """; |
| 1876 | const cwDogecoin = """ |
| 1877 | cw_dogecoin: |
| 1878 | path: ./cw_dogecoin |
| 1879 | """; |
| 1880 | const cwZcash = """ |
| 1881 | cw_zcash: |
| 1882 | path: ./cw_zcash |
| 1883 | """; |
| 1884 | |
| 1885 | final inputFile = File(pubspecOutputPath); |
| 1886 | final inputText = await inputFile.readAsString(); |
| 1887 | final inputLines = inputText.split('\n'); |
| 1888 | final dependenciesIndex = inputLines.indexWhere((line) => Platform.isWindows |
| 1889 | // On Windows it could contains `\r` (Carriage Return). It could be fixed in newer dart versions. |
| 1890 | ? line.toLowerCase() == 'dependencies:\r' || line.toLowerCase() == 'dependencies:' |
| 1891 | : line.toLowerCase() == 'dependencies:'); |
| 1892 | var output = cwCore; |
| 1893 | |
| 1894 | if (hasMonero) { |
| 1895 | output += '\n$cwMonero'; |
| 1896 | } |
| 1897 | |
| 1898 | if (hasBitcoin) { |
| 1899 | output += '\n$cwBitcoin'; |
| 1900 | } |
| 1901 | |
| 1902 | if (hasNano) { |
| 1903 | output += '\n$cwNano'; |
| 1904 | } |
| 1905 | |
| 1906 | if (hasBanano) { |
| 1907 | output += '\n$cwBanano'; |
| 1908 | } |
| 1909 | |
| 1910 | if (hasBitcoinCash) { |
| 1911 | output += '\n$cwBitcoinCash'; |
| 1912 | } |
| 1913 | |
| 1914 | if (hasSolana) { |
| 1915 | output += '\n$cwSolana'; |
| 1916 | } |
| 1917 | |
| 1918 | if (hasTron) { |
| 1919 | output += '\n$cwTron'; |
| 1920 | } |
| 1921 | |
| 1922 | if (hasDecred) { |
| 1923 | output += '\n$cwDecred'; |
| 1924 | } |
| 1925 | |
| 1926 | if (hasFlutterSecureStorage) { |
| 1927 | output += '\n$flutterSecureStorage\n'; |
| 1928 | } |
| 1929 | |
| 1930 | if (hasEthereum || hasPolygon || hasBase || hasArbitrum || hasBsc) { |
| 1931 | output += '\n$cwEVM'; |
| 1932 | } |
| 1933 | |
| 1934 | if (hasWownero) { |
| 1935 | output += '\n$cwWownero'; |
| 1936 | } |
| 1937 | |
| 1938 | if (hasZano) { |
| 1939 | output += '\n$cwZano'; |
| 1940 | } |
| 1941 | |
| 1942 | if (hasDogecoin) { |
| 1943 | output += '\n$cwDogecoin'; |
| 1944 | } |
| 1945 | |
| 1946 | if (hasZcash) { |
| 1947 | output += '\n$cwZcash'; |
| 1948 | } |
| 1949 | |
| 1950 | final outputLines = output.split('\n'); |
| 1951 | inputLines.insertAll(dependenciesIndex + 1, outputLines); |
| 1952 | final outputContent = inputLines.join('\n'); |
| 1953 | final outputFile = File(pubspecOutputPath); |
| 1954 | |
| 1955 | if (outputFile.existsSync()) { |
| 1956 | await outputFile.delete(); |
| 1957 | } |
| 1958 | |
| 1959 | await outputFile.writeAsString(outputContent); |
| 1960 | } |
| 1961 | |
| 1962 | Future<void> generateWalletTypes({ |
| 1963 | required bool hasMonero, |
| 1964 | required bool hasBitcoin, |
| 1965 | required bool hasEthereum, |
| 1966 | required bool hasNano, |
| 1967 | required bool hasBanano, |
| 1968 | required bool hasBitcoinCash, |
| 1969 | required bool hasPolygon, |
| 1970 | required bool hasSolana, |
| 1971 | required bool hasTron, |
| 1972 | required bool hasWownero, |
| 1973 | required bool hasZano, |
| 1974 | required bool hasDecred, |
| 1975 | required bool hasDogecoin, |
| 1976 | required bool hasBase, |
| 1977 | required bool hasArbitrum, |
| 1978 | required bool hasBsc, |
| 1979 | required bool hasZcash, |
| 1980 | }) async { |
| 1981 | final walletTypesFile = File(walletTypesPath); |
| 1982 | |
| 1983 | if (walletTypesFile.existsSync()) { |
| 1984 | await walletTypesFile.delete(); |
| 1985 | } |
| 1986 | |
| 1987 | const outputHeader = "import 'package:cw_core/wallet_type.dart';"; |
| 1988 | const outputDefinition = 'final availableWalletTypes = <WalletType>['; |
| 1989 | var outputContent = outputHeader + '\n\n' + outputDefinition + '\n'; |
| 1990 | |
| 1991 | if (hasMonero) { |
| 1992 | outputContent += '\tWalletType.monero,\n'; |
| 1993 | } |
| 1994 | |
| 1995 | if (hasBitcoin) { |
| 1996 | outputContent += '\tWalletType.bitcoin,\n'; |
| 1997 | } |
| 1998 | |
| 1999 | if (hasEthereum) { |
| 2000 | outputContent += '\tWalletType.ethereum,\n'; |
| 2001 | } |
| 2002 | |
| 2003 | if (hasBsc) { |
| 2004 | outputContent += '\tWalletType.bsc,\n'; |
| 2005 | } |
| 2006 | |
| 2007 | if (hasSolana) { |
| 2008 | outputContent += '\tWalletType.solana,\n'; |
| 2009 | } |
| 2010 | |
| 2011 | if (hasZcash) { |
| 2012 | outputContent += '\tWalletType.zcash,\n'; |
| 2013 | } |
| 2014 | |
| 2015 | if (hasTron) { |
| 2016 | outputContent += '\tWalletType.tron,\n'; |
| 2017 | } |
| 2018 | |
| 2019 | if (hasDogecoin) { |
| 2020 | outputContent += '\tWalletType.dogecoin,\n'; |
| 2021 | } |
| 2022 | |
| 2023 | if (hasBitcoinCash) { |
| 2024 | outputContent += '\tWalletType.bitcoinCash,\n'; |
| 2025 | } |
| 2026 | |
| 2027 | if (hasBitcoin) { |
| 2028 | outputContent += '\tWalletType.litecoin,\n'; |
| 2029 | } |
| 2030 | |
| 2031 | if (hasBase) { |
| 2032 | outputContent += '\tWalletType.base,\n'; |
| 2033 | } |
| 2034 | |
| 2035 | if (hasArbitrum) { |
| 2036 | outputContent += '\tWalletType.arbitrum,\n'; |
| 2037 | } |
| 2038 | |
| 2039 | if (hasPolygon) { |
| 2040 | outputContent += '\tWalletType.polygon,\n'; |
| 2041 | } |
| 2042 | |
| 2043 | if (hasNano) { |
| 2044 | outputContent += '\tWalletType.nano,\n'; |
| 2045 | } |
| 2046 | |
| 2047 | if (hasDecred) { |
| 2048 | outputContent += '\tWalletType.decred,\n'; |
| 2049 | } |
| 2050 | |
| 2051 | if (hasZano) { |
| 2052 | outputContent += '\tWalletType.zano,\n'; |
| 2053 | } |
| 2054 | |
| 2055 | if (hasBanano) { |
| 2056 | outputContent += '\tWalletType.banano,\n'; |
| 2057 | } |
| 2058 | |
| 2059 | // if (hasWownero) { |
| 2060 | // outputContent += '\tWalletType.wownero,\n'; |
| 2061 | // } |
| 2062 | |
| 2063 | outputContent += '];\n'; |
| 2064 | await walletTypesFile.writeAsString(outputContent); |
| 2065 | } |
| 2066 | |
| 2067 | Future<void> injectSecureStorage(bool hasFlutterSecureStorage) async { |
| 2068 | const flutterSecureStorageHeader = """ |
| 2069 | import 'dart:async'; |
| 2070 | import 'dart:io'; |
| 2071 | import 'package:flutter_secure_storage/flutter_secure_storage.dart'; |
| 2072 | """; |
| 2073 | const abstractSecureStorage = """ |
| 2074 | abstract class SecureStorage { |
| 2075 | Future<String?> read({required String key}); |
| 2076 | Future<void> write({required String key, required String? value}); |
| 2077 | Future<void> delete({required String key}); |
| 2078 | Future<void> deleteAll(); |
| 2079 | // Legacy |
| 2080 | Future<String?> readNoIOptions({required String key}); |
| 2081 | Future<Map<String, String>> readAll(); |
| 2082 | }"""; |
| 2083 | const defaultSecureStorage = """ |
| 2084 | class DefaultSecureStorage extends SecureStorage { |
| 2085 | DefaultSecureStorage._(this._secureStorage); |
| 2086 | |
| 2087 | factory DefaultSecureStorage() => _instance; |
| 2088 | |
| 2089 | static final _instance = DefaultSecureStorage._(FlutterSecureStorage( |
| 2090 | iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock), |
| 2091 | aOptions: AndroidOptions(encryptedSharedPreferences: true), |
| 2092 | )); |
| 2093 | |
| 2094 | final FlutterSecureStorage _secureStorage; |
| 2095 | |
| 2096 | @override |
| 2097 | Future<String?> read({required String key}) async => await _readInternal(key, false); |
| 2098 | |
| 2099 | @override |
| 2100 | Future<void> write({required String key, required String? value}) async { |
| 2101 | // delete the value before writing on macOS because of a weird bug |
| 2102 | // https://github.com/mogol/flutter_secure_storage/issues/581 |
| 2103 | if (Platform.isMacOS) { |
| 2104 | await _secureStorage.delete(key: key); |
| 2105 | } |
| 2106 | await _secureStorage.write(key: key, value: value); |
| 2107 | } |
| 2108 | |
| 2109 | @override |
| 2110 | Future<void> delete({required String key}) async => _secureStorage.delete(key: key); |
| 2111 | |
| 2112 | @override |
| 2113 | Future<void> deleteAll() async => _secureStorage.deleteAll(); |
| 2114 | |
| 2115 | @override |
| 2116 | Future<String?> readNoIOptions({required String key}) async => await _readInternal(key, true); |
| 2117 | |
| 2118 | Future<String?> _readInternal(String key, bool useNoIOptions) async { |
| 2119 | return await _secureStorage.read( |
| 2120 | key: key, |
| 2121 | iOptions: useNoIOptions ? IOSOptions() : null, |
| 2122 | ); |
| 2123 | } |
| 2124 | |
| 2125 | @override |
| 2126 | Future<Map<String, String>> readAll() async { |
| 2127 | return await _secureStorage.readAll(); |
| 2128 | } |
| 2129 | }"""; |
| 2130 | const fakeSecureStorage = """ |
| 2131 | class FakeSecureStorage extends SecureStorage { |
| 2132 | @override |
| 2133 | Future<String?> read({required String key}) async => null; |
| 2134 | @override |
| 2135 | Future<void> write({required String key, required String? value}) async {} |
| 2136 | @override |
| 2137 | Future<void> delete({required String key}) async {} |
| 2138 | @override |
| 2139 | Future<void> deleteAll() async {} |
| 2140 | @override |
| 2141 | Future<String?> readNoIOptions({required String key}) async => null; |
| 2142 | @override |
| 2143 | Future<Map<String, String>> readAll() async => {}; |
| 2144 | }"""; |
| 2145 | final outputFile = File(secureStoragePath); |
| 2146 | final header = hasFlutterSecureStorage |
| 2147 | ? '${flutterSecureStorageHeader}\n\nfinal SecureStorage secureStorageShared = DefaultSecureStorage();\n' |
| 2148 | : 'final SecureStorage secureStorageShared = FakeSecureStorage();\n'; |
| 2149 | var output = ''; |
| 2150 | if (outputFile.existsSync()) { |
| 2151 | await outputFile.delete(); |
| 2152 | } |
| 2153 | |
| 2154 | output += '${header}\n${abstractSecureStorage}\n\n'; |
| 2155 | |
| 2156 | if (hasFlutterSecureStorage) { |
| 2157 | output += '${defaultSecureStorage}\n'; |
| 2158 | } else { |
| 2159 | output += '${fakeSecureStorage}\n'; |
| 2160 | } |
| 2161 | |
| 2162 | await outputFile.writeAsString(output); |
| 2163 | } |