From 788318a3a2cbc822990585974e0377f1a6680c7c Mon Sep 17 00:00:00 2001 From: jwinterm Date: Sat, 24 Oct 2026 22:48:17 -0400 Subject: [PATCH] style: format Dart at 100 columns, as upstream does Upstream reformatted its whole tree in 16ddc0837. Matching it removes formatting from the conflict surface of this and every later sync. --- cw_bitcoin/lib/address_from_output.dart | 15 +- cw_bitcoin/lib/bitcoin_address_record.dart | 12 +- cw_bitcoin/lib/bitcoin_amount_format.dart | 4 +- .../bitcoin_commit_transaction_exception.dart | 1 - .../lib/bitcoin_transaction_priority.dart | 18 +- cw_bitcoin/lib/bitcoin_wallet.dart | 50 +- cw_bitcoin/lib/bitcoin_wallet_addresses.dart | 3 +- .../bitcoin_wallet_creation_credentials.dart | 32 +- cw_bitcoin/lib/bitcoin_wallet_keys.dart | 13 +- cw_bitcoin/lib/bitcoin_wallet_service.dart | 24 +- cw_bitcoin/lib/electrum.dart | 27 +- cw_bitcoin/lib/electrum_balance.dart | 6 +- .../lib/electrum_transaction_history.dart | 1 - cw_bitcoin/lib/electrum_transaction_info.dart | 3 +- cw_bitcoin/lib/electrum_wallet.dart | 116 +- cw_bitcoin/lib/electrum_wallet_addresses.dart | 221 +- cw_bitcoin/lib/exceptions.dart | 2 +- cw_bitcoin/lib/hardware/bitbox_service.dart | 3 +- .../lib/hardware/litecoin_ledger_service.dart | 6 +- cw_bitcoin/lib/hardware/trezor_service.dart | 3 +- .../lib/lightning/lightning_wallet.dart | 35 +- .../pending_lightning_transaction.dart | 2 +- cw_bitcoin/lib/litecoin_wallet.dart | 56 +- cw_bitcoin/lib/litecoin_wallet_addresses.dart | 10 +- cw_bitcoin/lib/litecoin_wallet_service.dart | 17 +- cw_bitcoin/lib/payjoin/manager.dart | 31 +- .../lib/payjoin/payjoin_receive_worker.dart | 25 +- .../lib/payjoin/payjoin_send_worker.dart | 8 +- cw_bitcoin/lib/payjoin/storage.dart | 34 +- .../lib/pending_bitcoin_transaction.dart | 20 +- cw_bitcoin/lib/psbt/signer.dart | 57 +- cw_bitcoin/lib/psbt/transaction_builder.dart | 31 +- cw_bitcoin/lib/psbt/utils.dart | 4 +- cw_bitcoin/lib/psbt/v0_deserialize.dart | 7 +- cw_bitcoin/lib/psbt/v0_finalizer.dart | 7 +- cw_bitcoin/lib/utils.dart | 2 +- .../lib/src/bitcoin_cash_wallet_service.dart | 8 +- .../lib/src/exceptions/exceptions.dart | 2 +- .../src/pending_bitcoin_cash_transaction.dart | 21 +- cw_core/lib/account.dart | 2 +- cw_core/lib/account_list.dart | 1 - cw_core/lib/amount_converter.dart | 16 +- cw_core/lib/balance.dart | 18 +- cw_core/lib/balance_card_style_settings.dart | 14 +- cw_core/lib/card_design.dart | 198 +- cw_core/lib/crypto_amount_format.dart | 1 - cw_core/lib/crypto_currency.dart | 971 ++++- cw_core/lib/currency_for_wallet_type.dart | 3 +- cw_core/lib/db/sqlite.dart | 105 +- cw_core/lib/encryption_file_utils.dart | 55 +- cw_core/lib/exceptions.dart | 3 +- cw_core/lib/format_amount.dart | 6 +- cw_core/lib/format_fixed.dart | 9 +- cw_core/lib/get_height_by_date.dart | 3 +- cw_core/lib/get_height_by_date_xmr.dart | 1 - cw_core/lib/hive_type_ids.dart | 48 +- cw_core/lib/key.dart | 3 +- cw_core/lib/keyable.dart | 2 +- cw_core/lib/lnurl.dart | 12 +- cw_core/lib/mnemonics/chinese_simplified.dart | 2 +- cw_core/lib/mnemonics/dutch.dart | 2 +- cw_core/lib/mnemonics/french.dart | 3258 ++++++++--------- cw_core/lib/mnemonics/german.dart | 2 +- cw_core/lib/mnemonics/italian.dart | 3258 ++++++++--------- cw_core/lib/mnemonics/japanese.dart | 2 +- cw_core/lib/mnemonics/portuguese.dart | 2 +- cw_core/lib/mnemonics/russian.dart | 2 +- cw_core/lib/mnemonics/spanish.dart | 2 +- cw_core/lib/monero_wallet_keys.dart | 12 +- cw_core/lib/node.dart | 13 +- cw_core/lib/output_info.dart | 44 +- cw_core/lib/parseBoolFromString.dart | 2 +- cw_core/lib/pathForWallet.dart | 3 +- cw_core/lib/payjoin_session.dart | 1 - cw_core/lib/payment_uris.dart | 7 +- cw_core/lib/root_dir.dart | 28 +- cw_core/lib/solana_rpc_http_service.dart | 6 +- cw_core/lib/transaction_direction.dart | 8 +- cw_core/lib/transaction_history.dart | 3 +- cw_core/lib/transaction_priority.dart | 6 +- cw_core/lib/utils/file.dart | 4 +- cw_core/lib/utils/proxy_logger/abstract.dart | 6 +- .../proxy_logger/memory_proxy_logger.dart | 22 +- .../lib/utils/proxy_logger/silent_logger.dart | 4 +- cw_core/lib/utils/proxy_socket/abstract.dart | 17 +- cw_core/lib/utils/proxy_socket/insecure.dart | 21 +- cw_core/lib/utils/proxy_socket/secure.dart | 18 +- cw_core/lib/utils/proxy_socket/socks.dart | 12 +- cw_core/lib/utils/proxy_wrapper.dart | 50 +- cw_core/lib/utils/tor/abstract.dart | 2 +- cw_core/lib/utils/tor/disabled.dart | 2 +- cw_core/lib/utils/tor/socks.dart | 2 +- cw_core/lib/utils/tor/torch.dart | 2 +- cw_core/lib/utils/zpub.dart | 22 +- cw_core/lib/wallet_info.dart | 240 +- cw_core/lib/wallet_info_legacy.dart | 2 +- cw_core/lib/wallet_info_legacy.part.dart | 16 +- cw_core/lib/wallet_keys_file.dart | 9 +- cw_core/lib/wallet_type.dart | 4 +- cw_core/lib/wownero_amount_format.dart | 2 +- cw_core/test/crypto_amount_format.dart | 6 +- cw_core/test/format_fixed_test.dart | 12 +- cw_core/test/lnurl_test.dart | 27 +- cw_dogecoin/lib/cw_dogecoin.dart | 1 - .../src/dogecoin_transaction_priority.dart | 7 +- cw_dogecoin/lib/src/dogecoin_wallet.dart | 3 +- .../lib/src/dogecoin_wallet_addresses.dart | 9 +- cw_dogecoin/test/cw_dogecoin_test.dart | 3 +- cw_evm/lib/clients/arbitrum_client.dart | 1 - cw_evm/lib/clients/base_client.dart | 1 - cw_evm/lib/clients/bsc_client.dart | 1 - cw_evm/lib/clients/ethereum_client.dart | 1 - cw_evm/lib/clients/polygon_client.dart | 1 - cw_evm/lib/contract/erc20.dart | 47 +- cw_evm/lib/deuro/deuro_savings.dart | 7 +- cw_evm/lib/deuro/deuro_savings_contract.dart | 110 +- cw_evm/lib/evm_chain_exceptions.dart | 13 +- cw_evm/lib/evm_chain_registry.dart | 3 +- cw_evm/lib/evm_chain_transaction_model.dart | 3 +- cw_evm/lib/evm_chain_wallet.dart | 5 +- cw_evm/lib/evm_chain_wallet_addresses.dart | 1 - cw_evm/lib/evm_erc20_balance.dart | 3 +- .../hardware/evm_chain_bitbox_service.dart | 5 +- .../evm_chain_ledger_credentials.dart | 28 +- .../hardware/evm_chain_ledger_service.dart | 6 +- cw_evm/lib/tokens/base_tokens.dart | 4 +- cw_evm/lib/tokens/polygon_tokens.dart | 4 +- cw_evm/lib/usdt0/usdt0_config.dart | 20 +- cw_evm/lib/utils/network_chain_utils.dart | 1 - cw_monero/lib/api/account_list.dart | 2 +- .../creation_transaction_exception.dart | 4 +- .../exceptions/setup_wallet_exception.dart | 4 +- .../exceptions/wallet_creation_exception.dart | 2 +- .../exceptions/wallet_opening_exception.dart | 2 +- .../wallet_restore_from_keys_exception.dart | 4 +- .../wallet_restore_from_seed_exception.dart | 4 +- cw_monero/lib/api/monero_output.dart | 2 +- .../lib/api/structs/pending_transaction.dart | 15 +- cw_monero/lib/api/subaddress_list.dart | 32 +- cw_monero/lib/api/transaction_history.dart | 120 +- cw_monero/lib/api/wallet.dart | 64 +- cw_monero/lib/api/wallet_manager.dart | 58 +- cw_monero/lib/bip39_seed.dart | 15 +- ...monero_transaction_creation_exception.dart | 2 +- ...onero_transaction_no_inputs_exception.dart | 3 +- cw_monero/lib/ledger.dart | 12 +- cw_monero/lib/monero_account_list.dart | 25 +- cw_monero/lib/monero_subaddress_list.dart | 24 +- cw_monero/lib/monero_transaction_history.dart | 11 +- cw_monero/lib/monero_wallet.dart | 174 +- cw_monero/lib/monero_wallet_addresses.dart | 34 +- cw_monero/lib/monero_wallet_service.dart | 60 +- cw_monero/lib/pending_monero_transaction.dart | 17 +- cw_monero/test/bip39_seed_test.dart | 19 +- .../test/monero_wallet_service_test.dart | 12 +- cw_monero/test/utils/setup_monero_c.dart | 13 +- cw_mweb/lib/cw_mweb.dart | 14 +- cw_mweb/lib/mweb_ffi.dart | 3 +- cw_mweb/lib/mwebd.pb.dart | 1398 ++++--- cw_mweb/lib/mwebd.pbgrpc.dart | 215 +- cw_nano/lib/banano_balance.dart | 6 +- cw_nano/lib/nano_balance.dart | 9 +- cw_nano/lib/nano_client.dart | 12 +- cw_nano/lib/nano_transaction_model.dart | 4 +- cw_nano/lib/nano_wallet_service.dart | 3 +- cw_nano/lib/pending_nano_transaction.dart | 2 +- .../lib/cw_shared_external.dart | 4 +- cw_wownero/lib/api/account_list.dart | 7 +- .../connection_to_node_exception.dart | 2 +- .../creation_transaction_exception.dart | 4 +- .../exceptions/setup_wallet_exception.dart | 4 +- .../exceptions/wallet_creation_exception.dart | 2 +- .../exceptions/wallet_opening_exception.dart | 2 +- .../wallet_restore_from_keys_exception.dart | 4 +- .../wallet_restore_from_seed_exception.dart | 4 +- cw_wownero/lib/api/structs/account_row.dart | 2 +- .../lib/api/structs/pending_transaction.dart | 17 +- .../lib/api/structs/subaddress_row.dart | 6 +- cw_wownero/lib/api/subaddress_list.dart | 28 +- cw_wownero/lib/api/transaction_history.dart | 138 +- cw_wownero/lib/api/wallet.dart | 50 +- cw_wownero/lib/api/wallet_manager.dart | 83 +- cw_wownero/lib/api/wownero_output.dart | 2 +- cw_wownero/lib/cw_wownero.dart | 1 - ...ownero_transaction_creation_exception.dart | 2 +- ...wnero_transaction_no_inputs_exception.dart | 3 +- cw_wownero/lib/mywownero.dart | 9 +- .../lib/pending_wownero_transaction.dart | 5 +- cw_wownero/lib/wownero_subaddress_list.dart | 47 +- .../lib/wownero_transaction_history.dart | 11 +- cw_wownero/lib/wownero_transaction_info.dart | 19 +- cw_wownero/lib/wownero_wallet.dart | 12 +- cw_wownero/lib/wownero_wallet_addresses.dart | 24 +- cw_wownero/lib/wownero_wallet_service.dart | 76 +- integration_test/demo/demo_config.dart | 9 +- integration_test/demo/demo_session.dart | 3 +- integration_test/helpers/mocks.dart | 16 +- .../robots/disclaimer_page_robot.dart | 2 +- .../restore_from_seed_or_key_robot.dart | 2 +- .../security_and_backup_page_robot.dart | 2 +- .../test_suites/confirm_seeds_flow_test.dart | 2 +- .../test_suites/exchange_flow_test.dart | 2 +- lib/anonpay/anonpay_api.dart | 4 +- lib/anonpay/anonpay_donation_link_info.dart | 6 +- lib/anonpay/anonpay_info_base.dart | 2 +- lib/anypay/any_pay_chain.dart | 8 +- lib/anypay/any_pay_payment.dart | 108 +- .../any_pay_payment_committed_info.dart | 24 +- lib/anypay/any_pay_payment_instruction.dart | 49 +- .../any_pay_payment_instruction_output.dart | 14 +- lib/anypay/any_pay_trasnaction.dart | 10 +- lib/anypay/anypay_api.dart | 162 +- lib/bitcoin/cw_bitcoin.dart | 38 +- lib/bitcoin_cash/cw_bitcoin_cash.dart | 8 +- lib/buy/buy_amount.dart | 13 +- lib/buy/buy_exception.dart | 3 +- lib/buy/buy_provider.dart | 17 +- lib/buy/get_buy_provider_icon.dart | 11 +- lib/buy/moonpay/moonpay_provider.dart | 23 +- lib/buy/sell_buy_states.dart | 3 +- lib/core/address_validator.dart | 21 +- lib/core/amount_parsing_proxy.dart | 12 +- lib/core/amount_validator.dart | 6 +- lib/core/auth_state.dart | 1 - lib/core/background_sync.dart | 5 +- lib/core/backup_service.dart | 47 +- lib/core/backup_service_v3.dart | 62 +- lib/core/email_validator.dart | 3 +- lib/core/execution_state.dart | 2 +- lib/core/fiat_conversion_service.dart | 6 +- lib/core/key_service.dart | 6 +- lib/core/mnemonic_length.dart | 2 +- lib/core/monero_account_label_validator.dart | 8 +- .../open_cryptopay_service.dart | 22 +- lib/core/seed_validator.dart | 5 +- lib/core/selectable_option.dart | 3 - .../socks_proxy_node_address_validator.dart | 5 +- lib/core/template_validator.dart | 11 +- lib/core/universal_address_detector.dart | 2 +- lib/core/utilities.dart | 3 +- lib/core/validator.dart | 10 +- lib/core/wallet_creation_service.dart | 3 +- lib/core/wallet_creation_state.dart | 2 +- lib/core/wallet_loading_service.dart | 71 +- lib/di.dart | 457 ++- lib/dogecoin/cw_dogecoin.dart | 5 +- .../auto_generate_subaddress_status.dart | 12 +- lib/entities/balance_display_mode.dart | 9 +- lib/entities/biometric_auth.dart | 2 +- lib/entities/bip_353_record.dart | 3 +- lib/entities/bitcoin_amount_display_mode.dart | 3 +- lib/entities/calculate_fiat_amount.dart | 4 +- lib/entities/calculate_fiat_amount_raw.dart | 2 +- lib/entities/contact.dart | 7 +- lib/entities/contact_base.dart | 2 +- lib/entities/country.dart | 7 +- lib/entities/default_settings_migration.dart | 12 +- lib/entities/demo_mode.dart | 6 +- lib/entities/embedded_node.dart | 9 +- .../evm_transaction_error_fees_handler.dart | 18 +- lib/entities/exchange_api_mode.dart | 2 +- lib/entities/fiat_currency.dart | 30 +- lib/entities/format_amount.dart | 6 +- .../require_hardware_wallet_connection.dart | 7 +- lib/entities/ios_legacy_helper.dart | 18 +- lib/entities/lnurlpay_record.dart | 2 +- .../new_ui_entities/list_item/list_item.dart | 6 +- .../list_item/list_item_regular_row.dart | 31 +- .../list_item/list_item_selector.dart | 2 +- .../list_item/list_item_text_field.dart | 19 +- lib/entities/openalias_record.dart | 7 +- lib/entities/parse_address_from_domain.dart | 12 +- lib/entities/parsed_address.dart | 2 +- lib/entities/pin_code_required_duration.dart | 2 +- lib/entities/preferences_key.dart | 3 +- lib/entities/qr_view_data.dart | 2 +- lib/entities/seed_phrase_length.dart | 3 +- lib/entities/seed_type.dart | 3 +- lib/entities/service_status.dart | 3 +- lib/entities/sort_balance_types.dart | 2 +- .../transaction_creation_credentials.dart | 2 +- lib/entities/transaction_description.dart | 13 +- lib/entities/transaction_history.dart | 3 +- lib/entities/wallet_description.dart | 4 +- lib/entities/wallet_manager.dart | 8 +- lib/entities/wallet_nft_response.dart | 4 +- lib/entities/wellknown_record.dart | 2 +- lib/entities/yat_record.dart | 6 +- .../exchange_provider_description.dart | 118 +- .../near_Intents_exchange_provider.dart | 71 +- lib/exchange/trade_legacy.part.dart | 10 +- lib/locales/hausa_intl.dart | 8 +- lib/locales/yoruba_intl.dart | 6 +- lib/monero/cw_monero.dart | 37 +- lib/new-ui/modal_navigator.dart | 39 +- lib/new-ui/pages/about_page.dart | 5 +- lib/new-ui/pages/account_customizer.dart | 12 +- lib/new-ui/pages/addresses_page.dart | 3 +- .../pages/bridge/bridge_confirm_sheet.dart | 6 +- .../pages/bridge/bridge_network_page.dart | 3 +- .../bridge_receive_address_input_page.dart | 8 +- lib/new-ui/pages/card_customizer.dart | 363 +- lib/new-ui/pages/coin_control_page.dart | 4 +- lib/new-ui/pages/home_page.dart | 173 +- lib/new-ui/pages/lightning_username_page.dart | 16 +- lib/new-ui/pages/receive_page.dart | 7 +- lib/new-ui/pages/send_page.dart | 52 +- lib/new-ui/pages/settings_page.dart | 65 +- lib/new-ui/pages/swap_page.dart | 85 +- .../card_customizer/card_customizer_bloc.dart | 29 +- .../card_customizer_event.dart | 2 - .../card_customizer_state.dart | 48 +- .../lightning_username_bloc.dart | 6 +- .../lightning_username_event.dart | 2 +- .../widgets/addresses_page/address_info.dart | 3 +- .../addresses_page/address_label_input.dart | 3 +- lib/new-ui/widgets/animated_dropdown.dart | 33 +- lib/new-ui/widgets/apps_widget.dart | 8 +- .../widgets/bridge/confirm_details_card.dart | 5 +- lib/new-ui/widgets/changelog_modal.dart | 2 +- .../coin_control_list_item.dart | 131 +- .../action_row/coin_action_row.dart | 29 +- .../coins_page/assets_history/asset_tile.dart | 39 +- .../assets_history_section.dart | 17 +- .../assets_history/assets_section.dart | 102 +- .../assets_history/assets_top_bar.dart | 103 +- .../assets_history/history_order_tile.dart | 24 +- .../assets_history/history_tile.dart | 85 +- .../assets_history/history_tile_base.dart | 49 +- .../assets_history/history_trade_tile.dart | 3 +- .../transaction_details_modal.dart | 5 +- .../coins_page/cards/balance_card.dart | 84 +- .../widgets/coins_page/cards/cards_view.dart | 92 +- lib/new-ui/widgets/coins_page/mweb_ad.dart | 4 +- .../coins_page/top_bar_widget/chain_icon.dart | 6 +- .../top_bar_widget/lightning_switcher.dart | 8 +- .../top_bar_widget/pulsing_dot.dart | 12 +- .../coins_page/top_bar_widget/sync_bar.dart | 25 +- .../coins_page/top_bar_widget/top_bar.dart | 6 +- .../unconfirmed_balance_widget.dart | 126 +- .../widgets/coins_page/wallet_info.dart | 14 +- lib/new-ui/widgets/confirm_swiper.dart | 16 +- lib/new-ui/widgets/dropdown_row.dart | 3 +- lib/new-ui/widgets/keyboard_hide_overlay.dart | 3 +- lib/new-ui/widgets/line_tab_switcher.dart | 43 +- lib/new-ui/widgets/long_press_menu.dart | 3 +- lib/new-ui/widgets/modal_header.dart | 5 +- lib/new-ui/widgets/modal_page_wrapper.dart | 16 +- lib/new-ui/widgets/modern_button.dart | 2 +- lib/new-ui/widgets/new_primary_button.dart | 33 +- lib/new-ui/widgets/picker.dart | 147 +- .../receive_page/payjoin_copy_modal.dart | 2 +- .../receive_page/receive_address_type.dart | 3 +- .../receive_address_type_selector.dart | 11 +- .../receive_page/receive_amount_display.dart | 108 +- .../receive_page/receive_amount_modal.dart | 16 +- .../receive_page/receive_bottom_buttons.dart | 24 +- .../receive_page/receive_info_box.dart | 45 +- .../receive_page/receive_label_modal.dart | 12 +- .../receive_page/receive_label_widget.dart | 3 +- .../receive_large_amount_preview.dart | 3 +- .../widgets/receive_page/receive_qr_code.dart | 11 +- .../receive_page/receive_token_display.dart | 16 +- .../widgets/receive_page/receive_top_bar.dart | 50 +- .../widgets/send_page/fiat_amount_bar.dart | 25 +- .../send_page/floating_icon_button.dart | 16 +- .../send_page/l2_action_wallet_selector.dart | 8 +- .../send_page/l2_send_external_modal.dart | 38 +- .../widgets/send_page/recipient_dot_row.dart | 26 +- .../widgets/send_page/send_address_input.dart | 2 +- .../widgets/send_page/send_amount_input.dart | 12 +- .../send_page/send_confirm_bottom_widget.dart | 8 +- .../widgets/send_page/send_confirm_sheet.dart | 58 +- .../send_page/send_syncing_indicator.dart | 35 +- .../swap_page/provider_options_page.dart | 14 +- .../swap_page/refund_address_modal.dart | 8 +- .../swap_address_selection_modal.dart | 81 +- .../widgets/swap_page/swap_options_page.dart | 16 +- ...wap_provider_initial_preference_modal.dart | 2 +- .../swap_page/swap_send_external_modal.dart | 10 +- .../trocador_providers_settings.dart | 3 +- lib/order/order_provider_description.dart | 4 +- lib/order/order_source_description.dart | 2 +- lib/palette.dart | 60 +- lib/reactions/bootstrap.dart | 2 +- lib/reactions/fiat_rate_update.dart | 3 +- .../on_authentication_state_change.dart | 3 +- .../on_current_fiat_api_mode_change.dart | 17 +- lib/reactions/on_current_fiat_change.dart | 17 +- lib/reactions/wallet_utils.dart | 2 +- lib/router.dart | 34 +- lib/src/screens/Info_page.dart | 5 +- lib/src/screens/auth/auth_page.dart | 8 +- lib/src/screens/backup/backup_page.dart | 11 +- .../backup/edit_backup_password_page.dart | 5 +- lib/src/screens/buy/buy_sell_page.dart | 10 +- lib/src/screens/buy/webview_page.dart | 5 +- .../monero_hardware_wallet_options_page.dart | 2 +- .../select_hardware_wallet_account_page.dart | 4 +- .../connect_device/widgets/device_tile.dart | 6 +- .../screens/contact/contact_list_page.dart | 60 +- lib/src/screens/contact/contact_page.dart | 21 +- lib/src/screens/dashboard/dashboard_page.dart | 8 +- .../dashboard/desktop_dashboard_page.dart | 2 +- .../desktop_action_button.dart | 14 +- .../desktop_dashboard_actions.dart | 114 +- .../desktop_dashboard_navbar.dart | 3 +- .../desktop_sidebar/side_menu.dart | 2 +- .../desktop_wallet_selection_dropdown.dart | 5 +- .../screens/dashboard/edit_token_page.dart | 3 +- .../dashboard/favorite_token_modal.dart | 5 +- .../dashboard/pages/balance/balance_page.dart | 3 +- .../pages/balance/crypto_balance_widget.dart | 3 +- .../dashboard/pages/cake_features_page.dart | 53 +- .../dashboard/pages/navigation_dock.dart | 27 +- .../dashboard/pages/nft_listing_page.dart | 3 +- .../dashboard/pages/transactions_page.dart | 6 +- lib/src/screens/dashboard/sign_page.dart | 14 +- .../dashboard/widgets/action_button.dart | 3 +- .../dashboard/widgets/date_section_raw.dart | 4 +- .../dashboard/widgets/filter_tile.dart | 2 +- .../dashboard/widgets/filter_widget.dart | 19 +- .../screens/dashboard/widgets/header_row.dart | 5 +- .../widgets/new_main_navbar_widget.dart | 193 +- .../screens/dashboard/widgets/order_row.dart | 20 +- .../dashboard/widgets/page_indicator.dart | 64 +- .../screens/dashboard/widgets/sign_form.dart | 10 +- .../widgets/solana_nft_tile_widget.dart | 14 +- .../dashboard/widgets/sync_indicator.dart | 3 +- .../dashboard/widgets/transaction_raw.dart | 17 +- .../dashboard/widgets/verify_form.dart | 2 +- lib/src/screens/dev/moneroc_cache_debug.dart | 45 +- .../screens/dev/moneroc_call_profiler.dart | 25 +- lib/src/screens/dev/network_requests.dart | 58 +- lib/src/screens/dev/qr_tools_page.dart | 17 +- .../screens/dev/secure_preferences_page.dart | 22 +- .../screens/dev/shared_preferences_page.dart | 73 +- .../screens/disclaimer/disclaimer_page.dart | 2 +- .../widgets/currency_picker_widget.dart | 2 +- .../mobile_exchange_cards_section.dart | 4 +- .../screens/exchange/widgets/picker_item.dart | 5 +- .../exchange_trade_external_send_page.dart | 6 +- .../exchange_trade/exchange_trade_item.dart | 2 +- .../exchange_trade/exchange_trade_page.dart | 21 +- .../exchange_trade/widgets/timer_widget.dart | 6 +- .../integrations/deuro/savings_page.dart | 2 +- .../integrations/deuro/widgets/numpad.dart | 14 +- .../monero_accounts/widgets/account_tile.dart | 2 +- .../new_wallet/new_wallet_type_page.dart | 38 +- .../wallet_group_description_page.dart | 2 +- ..._group_existing_seed_description_page.dart | 17 +- .../new_wallet/widgets/select_button.dart | 20 +- .../nodes/node_create_or_edit_page.dart | 36 +- .../nodes/pow_node_create_or_edit_page.dart | 42 +- lib/src/screens/nodes/widgets/node_form.dart | 176 +- .../screens/nodes/widgets/node_list_row.dart | 5 +- lib/src/screens/pin_code/pin_code.dart | 8 +- lib/src/screens/pin_code/pin_code_widget.dart | 6 +- .../widgets/anonpay_status_section.dart | 24 +- .../receive/widgets/copy_link_item.dart | 4 +- lib/src/screens/receive/widgets/qr_image.dart | 4 +- .../release_notes/release_notes_screen.dart | 23 +- lib/src/screens/rescan/rescan_page.dart | 5 +- .../restore/restore_from_backup_page.dart | 16 +- .../screens/restore/restore_options_page.dart | 10 +- .../wallet_restore_choose_derivation.dart | 7 +- .../wallet_restore_from_keys_form.dart | 38 +- .../wallet_restore_from_seed_form.dart | 2 +- .../screens/restore/wallet_restore_page.dart | 8 +- lib/src/screens/root/root.dart | 2 - .../seed_verification_success_view.dart | 12 +- lib/src/screens/seed/wallet_seed_page.dart | 19 +- lib/src/screens/send/send_page.dart | 666 ++-- .../send/transaction_success_info_page.dart | 3 +- .../widgets/choose_yat_address_alert.dart | 11 +- .../widgets/extract_address_from_parsed.dart | 4 +- lib/src/screens/send/widgets/send_card.dart | 14 +- lib/src/screens/settings/attributes.dart | 2 +- .../settings/connection_sync_page.dart | 288 +- .../desktop_settings_page.dart | 12 +- .../settings/display_settings_page.dart | 392 +- .../screens/settings/domain_lookups_page.dart | 6 +- .../screens/settings/items/item_headers.dart | 2 +- .../screens/settings/manage_nodes_page.dart | 53 +- lib/src/screens/settings/mweb_logs_page.dart | 12 +- lib/src/screens/settings/mweb_node_page.dart | 41 +- lib/src/screens/settings/mweb_settings.dart | 2 +- .../screens/settings/other_settings_page.dart | 122 +- lib/src/screens/settings/privacy_page.dart | 90 +- .../settings/security_backup_page.dart | 21 +- .../settings/silent_payments_logs_page.dart | 9 +- .../settings/silent_payments_settings.dart | 25 +- .../widgets/settings_choices_cell.dart | 7 +- .../settings/widgets/settings_picker_row.dart | 2 +- .../widgets/settings_theme_choice.dart | 52 +- .../widgets/wallet_connect_button.dart | 4 +- lib/src/screens/setup_2fa/setup_2fa.dart | 3 +- .../setup_2fa/setup_2fa_enter_code_page.dart | 12 +- .../screens/setup_2fa/setup_2fa_qr_page.dart | 3 +- .../widgets/popup_cancellable_alert.dart | 11 +- .../setup_pin_code/setup_pin_code.dart | 13 +- lib/src/screens/splash/splash_page.dart | 6 +- lib/src/screens/start_tor/start_tor_page.dart | 4 +- .../support_chat/support_chat_page.dart | 24 +- .../support_chat/widgets/chatwoot_widget.dart | 7 +- .../trade_details/track_trade_list_item.dart | 5 +- .../trade_details_list_card.dart | 12 +- .../trade_details/trade_details_page.dart | 8 +- .../trade_details_status_item.dart | 3 +- .../address_list_item.dart | 2 +- .../confirmations_list_item.dart | 6 +- .../transaction_details/rbf_details_page.dart | 3 +- .../textfield_list_item.dart | 2 +- .../transaction_details_page.dart | 32 +- .../transaction_expandable_list_item.dart | 2 +- .../unspent_coins_list_page.dart | 82 +- .../widgets/unspent_coins_list_item.dart | 48 +- lib/src/screens/ur/animated_ur_page.dart | 12 +- .../widgets/qr_format_info_bottom_sheet.dart | 5 +- .../ur/widgets/qr_selection_dialog.dart | 9 +- lib/src/screens/ur/widgets/urqr.dart | 14 +- .../eth/evm_supported_methods.dart | 2 +- .../services/walletkit_service.dart | 1 - .../wc_connections_listing_view.dart | 2 +- .../wc_pairing_detail_page.dart | 7 +- .../widgets/wc_connection_request_widget.dart | 7 +- .../widgets/wc_connection_widget.dart | 5 +- .../screens/wallet_keys/wallet_keys_page.dart | 2 +- .../screens/wallet_list/wallet_list_page.dart | 86 +- .../wallet_unlock_arguments.dart | 5 +- .../welcome/create_pin_welcome_page.dart | 3 +- lib/src/screens/welcome/welcome_page.dart | 10 +- .../yat/widgets/first_introduction.dart | 95 +- .../yat/widgets/second_introduction.dart | 64 +- .../yat/widgets/third_introduction.dart | 22 +- lib/src/screens/yat/widgets/yat_bar.dart | 20 +- .../yat/widgets/yat_page_indicator.dart | 10 +- lib/src/widgets/adaptable_page_view.dart | 3 +- lib/src/widgets/alert_with_picker_option.dart | 1 - lib/src/widgets/base_alert_dialog.dart | 95 +- lib/src/widgets/base_text_form_field.dart | 3 +- lib/src/widgets/blockchain_height_widget.dart | 2 +- .../confirm_sending_bottom_sheet_widget.dart | 6 +- .../info_bottom_sheet_widget.dart | 4 +- .../info_steps_bottom_sheet_widget.dart | 22 +- .../payment_confirmation_bottom_sheet.dart | 3 +- .../swap_confirmation_bottom_sheet.dart | 3 +- .../swap_details_bottom_sheet.dart | 11 +- lib/src/widgets/check_box_picker.dart | 11 +- lib/src/widgets/checkbox_widget.dart | 1 + lib/src/widgets/evm_switcher.dart | 3 +- .../widgets/hash_bag_success_animation.dart | 4 +- lib/src/widgets/hash_image_widget.dart | 14 +- lib/src/widgets/index.dart | 1 + .../new_list_row/list_Item_style_wrapper.dart | 40 +- .../list_item_checkbox_widget.dart | 63 +- .../list_item_regular_row_widget.dart | 52 +- .../list_item_selector_widget.dart | 13 +- .../list_item_text_field_widget.dart | 5 +- .../new_list_row/list_item_toggle_widget.dart | 3 +- .../new_list_row/new_list_section.dart | 17 +- lib/src/widgets/number_text_fild_widget.dart | 10 +- lib/src/widgets/picker.dart | 3 +- .../widgets/picker_inner_wrapper_widget.dart | 10 +- lib/src/widgets/provider_optoin_tile.dart | 4 +- lib/src/widgets/rounded_checkbox.dart | 28 +- lib/src/widgets/rounded_icon_button.dart | 2 +- .../scrollable_with_bottom_section.dart | 2 +- lib/src/widgets/seed_widget.dart | 13 +- lib/src/widgets/seedphrase_grid_widget.dart | 8 +- lib/src/widgets/simple_checkbox.dart | 6 +- lib/src/widgets/standard_checkbox.dart | 11 +- lib/src/widgets/standard_list.dart | 19 +- lib/src/widgets/standard_list_status_row.dart | 6 +- .../widgets/standard_slide_button_widget.dart | 4 +- .../validable_annotated_editable_text.dart | 19 +- lib/src/widgets/vulnerable_seeds_popup.dart | 21 +- lib/store/dashboard/order_filter_store.dart | 5 +- .../dashboard/payjoin_transactions_store.dart | 3 +- lib/store/dashboard/trade_filter_store.dart | 24 +- lib/store/seed_settings_store.dart | 1 - lib/store/settings_store.dart | 41 +- lib/store/templates/send_template_store.dart | 6 +- lib/store/wallet_list_store.dart | 2 +- lib/store/yat/yat_exception.dart | 2 +- lib/store/yat/yat_store.dart | 64 +- lib/themes/core/theme_store.dart | 4 +- .../light_theme_custom_colors.dart | 2 +- lib/utils/address_formatter.dart | 15 +- lib/utils/brightness_util.dart | 2 +- lib/utils/clipboard_util.dart | 3 +- lib/utils/date_picker.dart | 26 +- lib/utils/debounce.dart | 6 +- lib/utils/device_info.dart | 4 +- lib/utils/feature_flag.dart | 3 +- lib/utils/item_cell.dart | 4 +- lib/utils/list_item.dart | 2 +- lib/utils/list_section.dart | 2 +- lib/utils/mobx.dart | 12 +- lib/utils/package_info.dart | 77 +- lib/utils/token_utilities.dart | 2 +- lib/utils/tor.dart | 16 +- lib/utils/totp_utils.dart | 2 +- lib/view_model/animated_ur_model.dart | 5 +- lib/view_model/auth_state.dart | 1 - lib/view_model/auth_view_model.dart | 2 +- lib/view_model/backup_view_model.dart | 6 +- .../bridge/bridge_details_view_model.dart | 4 +- lib/view_model/bridge/bridge_view_model.dart | 29 +- lib/view_model/buy/buy_amount_view_model.dart | 4 +- lib/view_model/buy/buy_item.dart | 5 +- lib/view_model/buy/buy_sell_view_model.dart | 18 +- .../contact_list/contact_list_view_model.dart | 10 +- .../contact_list/contact_view_model.dart | 25 +- .../dashboard/action_list_item.dart | 2 +- .../dashboard/balance_view_model.dart | 37 +- .../dashboard/dashboard_view_model.dart | 27 +- .../dashboard/date_section_item.dart | 4 +- lib/view_model/dashboard/filter_item.dart | 7 +- .../dashboard/formatted_item_list.dart | 2 +- .../dashboard/home_settings_view_model.dart | 24 +- lib/view_model/dashboard/nft_view_model.dart | 3 +- lib/view_model/dashboard/order_list_item.dart | 2 +- .../dashboard/receive_option_view_model.dart | 1 - .../dashboard/transaction_list_item.dart | 3 +- lib/view_model/dashboard/wallet_balance.dart | 2 +- .../dev/background_sync_logs_view_model.dart | 8 +- .../exchange_provider_logs_view_model.dart | 5 +- .../dev/network_requests_view_model.dart | 2 +- lib/view_model/dev/qr_tools_view_model.dart | 26 +- lib/view_model/dev/secure_preferences.dart | 19 +- .../dev/send_network_requests_view_model.dart | 5 +- lib/view_model/dev/shared_preferences.dart | 9 +- .../dev/socket_health_logs_view_model.dart | 1 - .../edit_backup_password_view_model.dart | 9 +- .../exchange/exchange_trade_view_model.dart | 46 +- .../exchange/exchange_view_model.dart | 116 +- .../hardware_wallet/bitbox_view_model.dart | 5 +- .../hardware_wallet_view_model.dart | 1 - .../hardware_wallet/ledger_view_model.dart | 19 +- .../hardware_wallet/trezor_view_model.dart | 3 +- .../integrations/deuro_view_model.dart | 2 +- .../account_list_item.dart | 3 +- ...ero_account_edit_or_create_view_model.dart | 23 +- .../monero_account_list_view_model.dart | 43 +- .../node_create_or_edit_view_model.dart | 27 +- .../payjoin_details_view_model.dart | 6 +- lib/view_model/rescan_view_model.dart | 2 +- lib/view_model/restore/restore_mode.dart | 2 +- .../restore_from_backup_view_model.dart | 3 +- lib/view_model/seed_settings_view_model.dart | 3 +- lib/view_model/send/output.dart | 18 +- .../send/send_template_view_model.dart | 4 +- lib/view_model/send/send_view_model.dart | 29 +- .../send/send_view_model_state.dart | 3 + .../settings/connection_sync_view_model.dart | 1 - .../settings/display_settings_view_model.dart | 5 +- lib/view_model/settings/link_list_item.dart | 12 +- .../settings/other_settings_view_model.dart | 16 +- .../settings/privacy_settings_view_model.dart | 6 +- .../settings/regular_list_item.dart | 2 +- .../security_settings_view_model.dart | 7 +- .../settings/switcher_list_item.dart | 5 +- .../trocador_providers_view_model.dart | 5 +- .../settings/version_list_item.dart | 2 +- lib/view_model/setup_pin_code_view_model.dart | 5 +- lib/view_model/start_tor_view_model.dart | 13 +- lib/view_model/trade_details_view_model.dart | 20 +- .../transaction_details_view_model.dart | 39 +- .../unspent_coins_details_view_model.dart | 3 +- .../unspent_coins/unspent_coins_item.dart | 28 +- .../unspent_coins_list_view_model.dart | 10 +- .../unspent_coins_switch_item.dart | 13 +- .../wallet_account_list_header.dart | 2 +- .../wallet_address_hidden_list_header.dart | 2 +- .../wallet_address_list_item.dart | 30 +- .../wallet_address_list_view_model.dart | 22 +- lib/view_model/wallet_creation_vm.dart | 10 +- .../wallet_groups_display_view_model.dart | 23 +- .../wallet_hardware_restore_view_model.dart | 17 +- lib/view_model/wallet_keys_view_model.dart | 3 +- .../wallet_list/wallet_list_view_model.dart | 7 +- lib/view_model/wallet_new_vm.dart | 3 +- lib/view_model/wallet_restore_view_model.dart | 20 +- lib/view_model/wallet_seed_view_model.dart | 1 - lib/wallet_type_utils.dart | 18 +- lib/wownero/cw_wownero.dart | 12 +- test/brand_assets_match_source_test.dart | 3 +- test/bundled_yaml_valid_test.dart | 3 +- test/core/amount_parsing_proxy_test.dart | 9 +- .../core/universal_address_detector_test.dart | 3 +- .../parse_address_from_domain_test.dart | 29 +- test/legacy_decode_test.dart | 15 +- test/utils/payment_request_test.dart | 3 +- tool/append_translation.dart | 4 +- tool/download_moneroc_prebuilds.dart | 14 +- tool/generate_localization.dart | 40 +- tool/generate_new_secrets.dart | 2 +- tool/generate_pubspec.dart | 4 +- tool/generate_secrets_config.dart | 4 +- tool/import_secrets_config.dart | 4 +- tool/localization/localization_constants.dart | 2 +- tool/print_verbose_dummy.dart | 2 +- tool/translate_changelog.dart | 9 +- tool/translate_using_llm.dart | 18 +- tool/translation_add_lang.dart | 3 +- tool/translation_consistence.dart | 3 +- tool/update_secrets.dart | 6 +- 708 files changed, 12411 insertions(+), 11496 deletions(-) diff --git a/cw_bitcoin/lib/address_from_output.dart b/cw_bitcoin/lib/address_from_output.dart index 0d985b237..072a92dc2 100644 --- a/cw_bitcoin/lib/address_from_output.dart +++ b/cw_bitcoin/lib/address_from_output.dart @@ -17,21 +17,16 @@ BitcoinBaseAddress addressFromScript(Script script, switch (addressType) { case P2pkhAddressType.p2pkh: - return P2pkhAddress.fromScriptPubkey( - script: script, network: BitcoinNetwork.mainnet); + return P2pkhAddress.fromScriptPubkey(script: script, network: BitcoinNetwork.mainnet); case P2shAddressType.p2pkhInP2sh: case P2shAddressType.p2pkInP2sh: - return P2shAddress.fromScriptPubkey( - script: script, network: BitcoinNetwork.mainnet); + return P2shAddress.fromScriptPubkey(script: script, network: BitcoinNetwork.mainnet); case SegwitAddresType.p2wpkh: - return P2wpkhAddress.fromScriptPubkey( - script: script, network: BitcoinNetwork.mainnet); + return P2wpkhAddress.fromScriptPubkey(script: script, network: BitcoinNetwork.mainnet); case SegwitAddresType.p2wsh: - return P2wshAddress.fromScriptPubkey( - script: script, network: BitcoinNetwork.mainnet); + return P2wshAddress.fromScriptPubkey(script: script, network: BitcoinNetwork.mainnet); case SegwitAddresType.p2tr: - return P2trAddress.fromScriptPubkey( - script: script, network: BitcoinNetwork.mainnet); + return P2trAddress.fromScriptPubkey(script: script, network: BitcoinNetwork.mainnet); } throw ArgumentError("Invalid script"); diff --git a/cw_bitcoin/lib/bitcoin_address_record.dart b/cw_bitcoin/lib/bitcoin_address_record.dart index d6de05051..65b728904 100644 --- a/cw_bitcoin/lib/bitcoin_address_record.dart +++ b/cw_bitcoin/lib/bitcoin_address_record.dart @@ -72,17 +72,16 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord { required super.type, String? scriptHash, required super.network, - }) { + }) { try { this.scriptHash = scriptHash ?? - (network != null ? BitcoinAddressUtils.scriptHash(address, network: network!) : null); + (network != null ? BitcoinAddressUtils.scriptHash(address, network: network!) : null); } catch (e) { printV(e); } -} + } static bool _legacyDefaultForType(BitcoinAddressType type) { - // Some address types (p2wpkh, p2wsh) were historically derived from the same account/path as our new standard // but using legacy formats. For these, we default to legacy = false. if (type == SegwitAddresType.p2wpkh || type == SegwitAddresType.p2wsh) return false; @@ -154,6 +153,7 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord { } return scriptHash!; } + @override String get derivationPath { if (type == SegwitAddresType.mweb) { @@ -162,9 +162,7 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord { final coinType = _coinTypeForNetwork(); final purpose = _purposeForType(type); - final accountPath = isLegacyDerivation - ? electrum_path - : "m/$purpose'/$coinType'/0'"; + final accountPath = isLegacyDerivation ? electrum_path : "m/$purpose'/$coinType'/0'"; final chain = isHidden ? 1 : 0; return "$accountPath/$chain/$index"; diff --git a/cw_bitcoin/lib/bitcoin_amount_format.dart b/cw_bitcoin/lib/bitcoin_amount_format.dart index d5a42d984..dd7363569 100644 --- a/cw_bitcoin/lib/bitcoin_amount_format.dart +++ b/cw_bitcoin/lib/bitcoin_amount_format.dart @@ -7,8 +7,8 @@ final bitcoinAmountFormat = NumberFormat() ..maximumFractionDigits = bitcoinAmountLength ..minimumFractionDigits = 1; -String bitcoinAmountToString({required int amount}) => bitcoinAmountFormat.format( - cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider)); +String bitcoinAmountToString({required int amount}) => + bitcoinAmountFormat.format(cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider)); double bitcoinAmountToDouble({required int amount}) => cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider); diff --git a/cw_bitcoin/lib/bitcoin_commit_transaction_exception.dart b/cw_bitcoin/lib/bitcoin_commit_transaction_exception.dart index 7bf488f3f..ffadb65ae 100644 --- a/cw_bitcoin/lib/bitcoin_commit_transaction_exception.dart +++ b/cw_bitcoin/lib/bitcoin_commit_transaction_exception.dart @@ -5,4 +5,3 @@ class BitcoinCommitTransactionException implements Exception { @override String toString() => errorMessage; } - diff --git a/cw_bitcoin/lib/bitcoin_transaction_priority.dart b/cw_bitcoin/lib/bitcoin_transaction_priority.dart index 46e4ca8e4..e38cbce30 100644 --- a/cw_bitcoin/lib/bitcoin_transaction_priority.dart +++ b/cw_bitcoin/lib/bitcoin_transaction_priority.dart @@ -2,7 +2,8 @@ import 'package:cw_core/transaction_priority.dart'; import 'package:flutter/foundation.dart'; class BitcoinTransactionPriority extends TransactionPriority { - const BitcoinTransactionPriority({required String title, required int raw, String? description, String? hint}) + const BitcoinTransactionPriority( + {required String title, required int raw, String? description, String? hint}) : super(title: title, raw: raw, description: description, hint: hint); static const List all = [fast, medium, slow, custom]; @@ -10,10 +11,10 @@ class BitcoinTransactionPriority extends TransactionPriority { BitcoinTransactionPriority(title: 'Slow', description: "2 sat/byte", hint: "~ 24 h", raw: 0); static const BitcoinTransactionPriority medium = BitcoinTransactionPriority(title: 'Medium', description: "3 sat/byte", hint: "~ 1 h", raw: 1); - static const BitcoinTransactionPriority fast = - BitcoinTransactionPriority(title: 'Fast', description: "4 sat/byte", hint: "~ 30 min", raw: 2); + static const BitcoinTransactionPriority fast = BitcoinTransactionPriority( + title: 'Fast', description: "4 sat/byte", hint: "~ 30 min", raw: 2); static const BitcoinTransactionPriority custom = - BitcoinTransactionPriority(title: 'Custom', raw: 3); + BitcoinTransactionPriority(title: 'Custom', raw: 3); static BitcoinTransactionPriority deserialize({required int raw}) { switch (raw) { @@ -116,19 +117,19 @@ class LitecoinTransactionPriority extends BitcoinTransactionPriority { return label; } - } + class BitcoinCashTransactionPriority extends BitcoinTransactionPriority { const BitcoinCashTransactionPriority({required String title, required int raw}) : super(title: title, raw: raw); static const List all = [fast, medium, slow]; static const BitcoinCashTransactionPriority slow = - BitcoinCashTransactionPriority(title: 'Slow', raw: 0); + BitcoinCashTransactionPriority(title: 'Slow', raw: 0); static const BitcoinCashTransactionPriority medium = - BitcoinCashTransactionPriority(title: 'Medium', raw: 1); + BitcoinCashTransactionPriority(title: 'Medium', raw: 1); static const BitcoinCashTransactionPriority fast = - BitcoinCashTransactionPriority(title: 'Fast', raw: 2); + BitcoinCashTransactionPriority(title: 'Fast', raw: 2); static BitcoinCashTransactionPriority deserialize({required int raw}) { switch (raw) { @@ -170,4 +171,3 @@ class BitcoinCashTransactionPriority extends BitcoinTransactionPriority { return label; } } - diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart index 144c2eafd..688cce8fc 100644 --- a/cw_bitcoin/lib/bitcoin_wallet.dart +++ b/cw_bitcoin/lib/bitcoin_wallet.dart @@ -140,7 +140,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { autorun((_) { this.walletAddresses.isEnabledAutoGenerateSubaddress = this.isEnabledAutoGenerateSubaddress; }); - + reaction((_) => this.useLightning, (bool useLightning) { if (useLightning && LightningWallet.isAvailable) { if (mnemonic != null) { @@ -306,28 +306,28 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { } return BitcoinWallet( - mnemonic: mnemonic, - xpub: keysData.xPub != null ? convertZpubToXpub(keysData.xPub!) : null, - password: password, - passphrase: passphrase, - walletInfo: walletInfo, - derivationInfo: derivationInfo, - unspentCoinsInfo: unspentCoinsInfo, - initialAddresses: snp?.addresses, - initialSilentAddresses: snp?.silentAddresses, - initialSilentAddressIndex: snp?.silentAddressIndex ?? 0, - initialBalance: snp?.balance, - initialLightningBalance: snp?.lightningBalance, - encryptionFileUtils: encryptionFileUtils, - seedBytes: seedBytes, - initialRegularAddressIndex: snp?.regularAddressIndex, - initialChangeAddressIndex: snp?.changeAddressIndex, - addressPageType: snp?.addressPageType, - networkParam: network, - alwaysScan: snp?.alwaysScan, - useLightning: snp?.useLightning, - cachedLightningAddress: snp?.cachedLightningAddress, - payjoinBox: payjoinBox, + mnemonic: mnemonic, + xpub: keysData.xPub != null ? convertZpubToXpub(keysData.xPub!) : null, + password: password, + passphrase: passphrase, + walletInfo: walletInfo, + derivationInfo: derivationInfo, + unspentCoinsInfo: unspentCoinsInfo, + initialAddresses: snp?.addresses, + initialSilentAddresses: snp?.silentAddresses, + initialSilentAddressIndex: snp?.silentAddressIndex ?? 0, + initialBalance: snp?.balance, + initialLightningBalance: snp?.lightningBalance, + encryptionFileUtils: encryptionFileUtils, + seedBytes: seedBytes, + initialRegularAddressIndex: snp?.regularAddressIndex, + initialChangeAddressIndex: snp?.changeAddressIndex, + addressPageType: snp?.addressPageType, + networkParam: network, + alwaysScan: snp?.alwaysScan, + useLightning: snp?.useLightning, + cachedLightningAddress: snp?.cachedLightningAddress, + payjoinBox: payjoinBox, ); } @@ -488,7 +488,9 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { @override Future createTransaction(Object credentials) async { credentials = credentials as BitcoinTransactionCredentials; - final lnAddr = credentials.outputs.first.isParsedAddress ? credentials.outputs.first.extractedAddress! : credentials.outputs.first.address; + final lnAddr = credentials.outputs.first.isParsedAddress + ? credentials.outputs.first.extractedAddress! + : credentials.outputs.first.address; final isLNCompatible = await lightningWallet?.isCompatible(lnAddr); if ((credentials.coinTypeToSpendFrom == UnspentCoinType.lightning && lightningWallet != null) || diff --git a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart index be03f26d0..471e09498 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart @@ -137,7 +137,8 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S } @override - bool containsAddress(String address) => super.containsAddress(address) || address == lightningAddress; + bool containsAddress(String address) => + super.containsAddress(address) || address == lightningAddress; @override String get addressForBuy { diff --git a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart index 479cf6416..658969c3e 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart @@ -59,27 +59,27 @@ class BitcoinRestoreWalletFromWIFCredentials extends WalletCredentials { } class BitcoinWalletFromKeysCredentials extends WalletCredentials { - BitcoinWalletFromKeysCredentials({ - required String name, - required String password, - required this.xpub, - WalletInfo? walletInfo, - super.hardwareWalletType - }) : super(name: name, password: password, walletInfo: walletInfo); + BitcoinWalletFromKeysCredentials( + {required String name, + required String password, + required this.xpub, + WalletInfo? walletInfo, + super.hardwareWalletType}) + : super(name: name, password: password, walletInfo: walletInfo); final String xpub; } class LitecoinWalletFromKeysCredentials extends WalletCredentials { - LitecoinWalletFromKeysCredentials({ - required String name, - required String password, - required this.xpub, - required this.scanSecret, - required this.spendPubkey, - WalletInfo? walletInfo, - super.hardwareWalletType - }) : super(name: name, password: password, walletInfo: walletInfo); + LitecoinWalletFromKeysCredentials( + {required String name, + required String password, + required this.xpub, + required this.scanSecret, + required this.spendPubkey, + WalletInfo? walletInfo, + super.hardwareWalletType}) + : super(name: name, password: password, walletInfo: walletInfo); final String xpub; final String scanSecret; diff --git a/cw_bitcoin/lib/bitcoin_wallet_keys.dart b/cw_bitcoin/lib/bitcoin_wallet_keys.dart index 4ed0da49c..9a9bdcba4 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_keys.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_keys.dart @@ -1,15 +1,12 @@ class BitcoinWalletKeys { - const BitcoinWalletKeys({required this.wif, required this.privateKey, required this.publicKey, required this.xpub}); + const BitcoinWalletKeys( + {required this.wif, required this.privateKey, required this.publicKey, required this.xpub}); final String wif; final String privateKey; final String publicKey; final String xpub; - Map toJson() => { - 'wif': wif, - 'privateKey': privateKey, - 'publicKey': publicKey, - 'xpub': xpub - }; -} \ No newline at end of file + Map toJson() => + {'wif': wif, 'privateKey': privateKey, 'publicKey': publicKey, 'xpub': xpub}; +} diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart index 6163a8a82..858adc424 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_service.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart @@ -22,8 +22,7 @@ class BitcoinWalletService extends WalletService< BitcoinRestoreWalletFromSeedCredentials, BitcoinWalletFromKeysCredentials, BitcoinRestoreWalletFromHardware> { - BitcoinWalletService(this.unspentCoinsInfoSource, - this.payjoinSessionSource, this.isDirect); + BitcoinWalletService(this.unspentCoinsInfoSource, this.payjoinSessionSource, this.isDirect); final Box unspentCoinsInfoSource; final Box payjoinSessionSource; @@ -39,9 +38,12 @@ class BitcoinWalletService extends WalletService< final String mnemonic; final derivationInfo = await credentials.walletInfo!.getDerivationInfo(); - derivationInfo.derivationType = credentials.derivationInfo?.derivationType ?? derivationInfo.derivationType; - derivationInfo.derivationPath = credentials.derivationInfo?.derivationPath ?? derivationInfo.derivationPath; - derivationInfo.description = credentials.derivationInfo?.description ?? derivationInfo.description; + derivationInfo.derivationType = + credentials.derivationInfo?.derivationType ?? derivationInfo.derivationType; + derivationInfo.derivationPath = + credentials.derivationInfo?.derivationPath ?? derivationInfo.derivationPath; + derivationInfo.description = + credentials.derivationInfo?.description ?? derivationInfo.description; derivationInfo.scriptType = credentials.derivationInfo?.scriptType ?? derivationInfo.scriptType; await derivationInfo.save(); switch (derivationInfo.derivationType) { @@ -120,8 +122,9 @@ class BitcoinWalletService extends WalletService< } await WalletInfo.delete(walletInfo); - final unspentCoinsToDelete = unspentCoinsInfoSource.values.where( - (unspentCoin) => unspentCoin.walletId == walletInfo.id).toList(); + final unspentCoinsToDelete = unspentCoinsInfoSource.values + .where((unspentCoin) => unspentCoin.walletId == walletInfo.id) + .toList(); final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList(); @@ -161,11 +164,10 @@ class BitcoinWalletService extends WalletService< final network = isTestnet == true ? BitcoinNetwork.testnet : BitcoinNetwork.mainnet; credentials.walletInfo?.network = network.value; final derivationInfo = await credentials.walletInfo!.getDerivationInfo(); - derivationInfo.derivationPath = - credentials.hwAccountData.derivationPath; - + derivationInfo.derivationPath = credentials.hwAccountData.derivationPath; + final xpub = convertAnyToXpub(credentials.hwAccountData.xpub!); - + await credentials.walletInfo!.save(); final wallet = await BitcoinWallet( password: credentials.password!, diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart index 095183426..195e9425f 100644 --- a/cw_bitcoin/lib/electrum.dart +++ b/cw_bitcoin/lib/electrum.dart @@ -303,9 +303,9 @@ class ElectrumClient { }); Future>>> getBatchHistory( - List scriptHashes, { - int timeout = 10000, - }) async { + List scriptHashes, { + int timeout = 10000, + }) async { final paramsList = scriptHashes.map((h) => [h]).toList(growable: false); final batchResults = await callBatchWithTimeout( @@ -341,9 +341,9 @@ class ElectrumClient { } Future>> getBatchTransactionVerbose( - List hashes, { - int timeout = 10000, - }) async { + List hashes, { + int timeout = 10000, + }) async { final result = >{}; if (hashes.isEmpty) return result; @@ -368,9 +368,9 @@ class ElectrumClient { } Future> getBatchTransactionHex( - List hashes, { - int timeout = 10000, - }) async { + List hashes, { + int timeout = 10000, + }) async { final result = {}; if (hashes.isEmpty) return result; @@ -408,12 +408,8 @@ class ElectrumClient { // Build the Batch Array final List> batchPayload = []; for (int i = 0; i < paramsList.length; i++) { - batchPayload.add({ - "jsonrpc": "2.0", - "method": method, - "params": paramsList[i], - "id": "$batchBaseId-$i" - }); + batchPayload.add( + {"jsonrpc": "2.0", "method": method, "params": paramsList[i], "id": "$batchBaseId-$i"}); } // Register the task @@ -700,7 +696,6 @@ class ElectrumClient { } void _handleResponse(dynamic response) { - // Handle batch response if (response is List) { if (response.isEmpty) return; diff --git a/cw_bitcoin/lib/electrum_balance.dart b/cw_bitcoin/lib/electrum_balance.dart index a1529f92f..11a19ce15 100644 --- a/cw_bitcoin/lib/electrum_balance.dart +++ b/cw_bitcoin/lib/electrum_balance.dart @@ -9,7 +9,8 @@ class ElectrumBalance extends Balance { required int frozen, this.secondConfirmed = 0, this.secondUnconfirmed = 0, - }) : this._frozen = frozen, super.fromInt(confirmed, unconfirmed, + }) : this._frozen = frozen, + super.fromInt(confirmed, unconfirmed, secondAvailable: secondConfirmed, secondAdditional: secondUnconfirmed, frozen: frozen); static ElectrumBalance? fromJSON(String? jsonSource) { @@ -37,7 +38,8 @@ class ElectrumBalance extends Balance { int secondUnconfirmed = 0; @override - BigInt get fullAvailableBalance => BigInt.from((confirmed + unconfirmed) + secondConfirmed - _frozen); + BigInt get fullAvailableBalance => + BigInt.from((confirmed + unconfirmed) + secondConfirmed - _frozen); String toJSON() => json.encode({ 'confirmed': confirmed, diff --git a/cw_bitcoin/lib/electrum_transaction_history.dart b/cw_bitcoin/lib/electrum_transaction_history.dart index 6457832ec..5de131c77 100644 --- a/cw_bitcoin/lib/electrum_transaction_history.dart +++ b/cw_bitcoin/lib/electrum_transaction_history.dart @@ -1,6 +1,5 @@ import 'dart:convert'; - import 'package:cw_bitcoin/electrum_transaction_info.dart'; import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/pathForWallet.dart'; diff --git a/cw_bitcoin/lib/electrum_transaction_info.dart b/cw_bitcoin/lib/electrum_transaction_info.dart index cee1f9b9f..da36c8c07 100644 --- a/cw_bitcoin/lib/electrum_transaction_info.dart +++ b/cw_bitcoin/lib/electrum_transaction_info.dart @@ -178,8 +178,7 @@ class ElectrumTransactionInfo extends TransactionInfo { // MWEB HogEx final isHogExTx = (BtcTransaction tx) { - if (tx.inputs.isEmpty || tx.inputs.first.txIndex > 0 || tx.outputs.isEmpty) - return false; + if (tx.inputs.isEmpty || tx.inputs.first.txIndex > 0 || tx.outputs.isEmpty) return false; final b = tx.outputs.first.scriptPubKey.toBytes(); return b.length == 34 && b[0] == 88 && b[1] == 32; }; diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 9b2cc2631..fd320a692 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -148,7 +148,6 @@ abstract class ElectrumWalletBase sideHdByType[type] = sideHd; } } - } int _purposeForType(BitcoinAddressType type) { @@ -187,7 +186,6 @@ abstract class ElectrumWalletBase /// For LEGACY addresses, returns the wallet's legacy derivation base (derivationInfo.derivationPath) /// which is already the account path used historically (e.g. m/0' or m/84'/0'/0'). String _accountDerivationPathForRecord(BaseBitcoinAddressRecord record) { - if (derivationInfo.derivationType == DerivationType.electrum) { return derivationInfo.derivationPath ?? electrum_path; // m/0' } @@ -945,8 +943,7 @@ abstract class ElectrumWalletBase final baseDerivationPath = _accountDerivationPathForRecord(utx.bitcoinAddressRecord); - final derivationPath = - "${_hardenedDerivationPath(baseDerivationPath)}" + final derivationPath = "${_hardenedDerivationPath(baseDerivationPath)}" "/${utx.bitcoinAddressRecord.isHidden ? "1" : "0"}" "/${utx.bitcoinAddressRecord.index}"; publicKeys[address.pubKeyHash()] = PublicKeyWithDerivationPath(pubKeyHex, derivationPath); @@ -1160,11 +1157,9 @@ abstract class ElectrumWalletBase isChange: true, )); - // Must match the address' account root (purpose/coinType) and legacy derivation when applicable. final changeBaseDerivationPath = _accountDerivationPathForRecord(changeAddress); - final changeDerivationPath = - "${_hardenedDerivationPath(changeBaseDerivationPath)}" + final changeDerivationPath = "${_hardenedDerivationPath(changeBaseDerivationPath)}" "/${changeAddress.isHidden ? "1" : "0"}" "/${changeAddress.index}"; utxoDetails.publicKeys[address.pubKeyHash()] = @@ -2058,10 +2053,7 @@ abstract class ElectrumWalletBase final hd = _hdFor(record: addressRecord); - final privkey = generateECPrivate( - hd: hd, - index: addressRecord.index, - network: network); + final privkey = generateECPrivate(hd: hd, index: addressRecord.index, network: network); privateKeys.add(privkey); @@ -2490,16 +2482,15 @@ abstract class ElectrumWalletBase final history = await electrumClient.getHistory(addressRecord.getScriptHash(network)); - if (history.isNotEmpty) { addressRecord.setAsUsed(); walletAddresses.clearLockIfMatches(addressRecord.type, addressRecord.address); - if(this is BitcoinWallet) { + if (this is BitcoinWallet) { //removes transactions no longer returned by the api, presumed replaced/invalid. transactionHistory.transactions.removeWhere( - (hash, tx) => - tx.outputAddresses != null && + (hash, tx) => + tx.outputAddresses != null && tx.outputAddresses!.contains(addressRecord.address) && !history.any((newTransaction) => newTransaction['tx_hash'] == hash), ); @@ -2566,7 +2557,7 @@ abstract class ElectrumWalletBase Future fetchTransactionsForAddressTypeBatch( Map historiesWithDetails, BitcoinAddressType type) async { final addressesByType = - walletAddresses.allAddresses.where((addr) => addr.type == type).toList(); + walletAddresses.allAddresses.where((addr) => addr.type == type).toList(); final hiddenAddresses = addressesByType.where((addr) => addr.isHidden).toList(); final receiveAddresses = addressesByType.where((addr) => !addr.isHidden).toList(); walletAddresses.hiddenAddresses.addAll(hiddenAddresses.map((e) => e.address)); @@ -2574,7 +2565,8 @@ abstract class ElectrumWalletBase final tip = await getCurrentChainTip(); - final addressHistory = await _processChunksToMap( + final addressHistory = + await _processChunksToMap( items: addressesByType, chunkSize: addressHistoryChunkSize, processChunk: (chunk) => _fetchBatchAddressHistory(chunk, tip, addressHistoryChunkSize), @@ -2585,18 +2577,16 @@ abstract class ElectrumWalletBase for (final addressRecord in addressesByType) { final matchedAddresses = addressRecord.isHidden ? hiddenAddresses : receiveAddresses; - final isUsedAddressUnderGap = - matchedAddresses.indexOf(addressRecord) >= - matchedAddresses.length - ElectrumWalletAddressesBase.gap; + final isUsedAddressUnderGap = matchedAddresses.indexOf(addressRecord) >= + matchedAddresses.length - ElectrumWalletAddressesBase.gap; if (isUsedAddressUnderGap && addressRecord.isUsed) { final prevLength = walletAddresses.allAddresses.length; - await walletAddresses.discoverAddressesBatch( matchedAddresses, addressRecord.isHidden, - (newAddresses) async { + (newAddresses) async { await _fetchBatchAddressHistory( newAddresses, tip, @@ -2614,9 +2604,7 @@ abstract class ElectrumWalletBase final newLength = walletAddresses.allAddresses.length; if (newLength > prevLength) { - await fetchTransactionsForAddressTypeBatch( - historiesWithDetails, - type); + await fetchTransactionsForAddressTypeBatch(historiesWithDetails, type); return; } } @@ -2624,9 +2612,7 @@ abstract class ElectrumWalletBase } Future> _fetchBatchAddressHistory( - List addressRecords, - int? currentHeight, - int historyChunkSize) async { + List addressRecords, int? currentHeight, int historyChunkSize) async { String lastTxId = ''; bool didUpdateHistory = false; @@ -2637,11 +2623,8 @@ abstract class ElectrumWalletBase final scriptHashes = addressRecords.map((a) => a.getScriptHash(network)).toList(); final historyByScriptHash = - await _processChunksToMap>>( - items: scriptHashes, - chunkSize: historyChunkSize, - processChunk: _getHistoryBatch - ); + await _processChunksToMap>>( + items: scriptHashes, chunkSize: historyChunkSize, processChunk: _getHistoryBatch); // Map scriptHash -> addressRecord final byScriptHash = {}; @@ -2737,8 +2720,7 @@ abstract class ElectrumWalletBase .toList(growable: false); final heightsByHash = { - for (final e in chunkHistory) - (e['tx_hash'] as String): (e['height'] as int?), + for (final e in chunkHistory) (e['tx_hash'] as String): (e['height'] as int?), }; final infosByHash = await fetchTransactionInfoBatch( @@ -2787,24 +2769,21 @@ abstract class ElectrumWalletBase } } - Future>> _getTransactionVerboseBatch( - List hashes) { + Future>> _getTransactionVerboseBatch(List hashes) { return electrumClient.getBatchTransactionVerbose( hashes, timeout: transactionBatchTimeoutMs, ); } - Future> _getTransactionHexBatch( - List hashes) { + Future> _getTransactionHexBatch(List hashes) { return electrumClient.getBatchTransactionHex( hashes, timeout: transactionBatchTimeoutMs, ); } - Future>>> _getHistoryBatch( - List scriptHashes) { + Future>>> _getHistoryBatch(List scriptHashes) { return electrumClient.getBatchHistory( scriptHashes, timeout: transactionBatchTimeoutMs, @@ -2818,8 +2797,7 @@ abstract class ElectrumWalletBase Duration retryDelay = const Duration(seconds: 2), }) async { final result = {}; - final uniqueHashes = - hashes.map((h) => h.trim()).where((h) => h.isNotEmpty).toSet().toList(); + final uniqueHashes = hashes.map((h) => h.trim()).where((h) => h.isNotEmpty).toSet().toList(); if (uniqueHashes.isEmpty) return result; @@ -2852,9 +2830,8 @@ abstract class ElectrumWalletBase required Map? heightsByHash, }) async { for (var i = 0; i < txIds.length; i += transactionChunkSize) { - final end = (i + transactionChunkSize < txIds.length) - ? i + transactionChunkSize - : txIds.length; + final end = + (i + transactionChunkSize < txIds.length) ? i + transactionChunkSize : txIds.length; final chunk = txIds.sublist(i, end); final bundlesByHash = await getTransactionExpandedBatch( @@ -2886,9 +2863,8 @@ abstract class ElectrumWalletBase } } - Future> getTransactionExpandedBatch({ - required List hashes, - Map? heightsByHash}) async { + Future> getTransactionExpandedBatch( + {required List hashes, Map? heightsByHash}) async { final bundles = {}; if (hashes.isEmpty) return bundles; @@ -2898,8 +2874,7 @@ abstract class ElectrumWalletBase final inputTxIdsByHash = _collectInputTxIdsByHash(originalByHash); - final inputVerboseByTxId = await _fetchInputTransactionVerboseBatch( - inputTxIdsByHash); + final inputVerboseByTxId = await _fetchInputTransactionVerboseBatch(inputTxIdsByHash); final parsedInputTxById = _parseTransactions(inputVerboseByTxId); @@ -2916,8 +2891,8 @@ abstract class ElectrumWalletBase Future>> _fetchTransactionVerboseBatch( List txIds) async { - - final verboseTransactionByHash = await _processChunksToMap>( + final verboseTransactionByHash = + await _processChunksToMap>( items: txIds, chunkSize: transactionChunkSize, processChunk: _getTransactionVerboseBatch, @@ -2954,8 +2929,8 @@ abstract class ElectrumWalletBase } Map _parseTransactions( - Map> verboseByHash, - ) { + Map> verboseByHash, + ) { final result = {}; for (final entry in verboseByHash.entries) { @@ -2970,10 +2945,9 @@ abstract class ElectrumWalletBase return result; } - Map> _collectInputTxIdsByHash( - Map originalByHash, - ) { + Map originalByHash, + ) { final inputTxIdsByHash = >{}; for (final entry in originalByHash.entries) { @@ -2991,7 +2965,6 @@ abstract class ElectrumWalletBase return inputTxIdsByHash; } - Future>> _fetchInputTransactionVerboseBatch( Map> inputTxidsByHash) async { final allInputTxids = {}; @@ -3002,7 +2975,7 @@ abstract class ElectrumWalletBase final inputTxIds = allInputTxids.toList(growable: false); final verboseTransactionByHash = - await _processChunksToMap>( + await _processChunksToMap>( items: inputTxIds, chunkSize: inputTransactionChunkSize, processChunk: _getTransactionVerboseBatch, @@ -3049,7 +3022,6 @@ abstract class ElectrumWalletBase return verboseTransactionByHash; } - Future> _buildTransactionBundlesBatch({ required List unique, required Map? heightsByHash, @@ -3125,8 +3097,8 @@ abstract class ElectrumWalletBase } Future> _fetchBlockTimestampsFromMempoolByHeights( - Set heights, - ) async { + Set heights, + ) async { final out = {}; if (heights.isEmpty) return out; if (!(await checkIfMempoolAPIIsEnabled())) return out; @@ -3136,10 +3108,10 @@ abstract class ElectrumWalletBase try { final blockHashResp = await ProxyWrapper() .get( - clearnetUri: Uri.parse( - 'https://mempool.space/api/block-height/$h', - ), - ) + clearnetUri: Uri.parse( + 'https://mempool.space/api/block-height/$h', + ), + ) .timeout(const Duration(seconds: 15)); if (blockHashResp.statusCode != 200 || blockHashResp.body.isEmpty) return; @@ -3149,10 +3121,10 @@ abstract class ElectrumWalletBase final blockResp = await ProxyWrapper() .get( - clearnetUri: Uri.parse( - 'https://mempool.space/api/block/$blockHash', - ), - ) + clearnetUri: Uri.parse( + 'https://mempool.space/api/block/$blockHash', + ), + ) .timeout(const Duration(seconds: 15)); if (blockResp.statusCode != 200 || blockResp.body.isEmpty) return; @@ -3200,7 +3172,6 @@ abstract class ElectrumWalletBase return result; } - Future updateTransactions() async { printV("updateTransactions() called!"); try { @@ -3413,7 +3384,6 @@ abstract class ElectrumWalletBase } Future _checkIfBatchSupported() async { - if (_isBatchSupported != null) { printV('[BATCH_TEST] Already checked: $_isBatchSupported'); return; diff --git a/cw_bitcoin/lib/electrum_wallet_addresses.dart b/cw_bitcoin/lib/electrum_wallet_addresses.dart index d3763386d..b9058540e 100644 --- a/cw_bitcoin/lib/electrum_wallet_addresses.dart +++ b/cw_bitcoin/lib/electrum_wallet_addresses.dart @@ -182,13 +182,12 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { } if (addressPageType == LightningAddressType.p2l) { - return lightningAddress ?? - "Error: Unable to fetch your Lightning address, please check your network connection."; + return lightningAddress ?? + "Error: Unable to fetch your Lightning address, please check your network connection."; } - final typeMatchingAddressesAll = _addresses - .where((addr) => !addr.isHidden && _isAddressPageTypeMatch(addr)) - .toList(); + final typeMatchingAddressesAll = + _addresses.where((addr) => !addr.isHidden && _isAddressPageTypeMatch(addr)).toList(); // Prefer standard derivation addresses for the current/active address, // but keep legacy addresses present in the overall address lists. @@ -337,34 +336,35 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { return acc; }); - @override - Future init() async { - if (walletInfo.type == WalletType.bitcoinCash) { - await _generateInitialAddresses(type: P2pkhAddressType.p2pkh); - } else if (walletInfo.type == WalletType.litecoin) { - await _generateInitialAddresses(type: SegwitAddresType.p2wpkh); - if ((Platform.isAndroid || Platform.isIOS) && !isHardwareWallet) { - await _generateInitialAddresses(type: SegwitAddresType.mweb); - } - } else if (walletInfo.type == WalletType.dogecoin) { - await _generateInitialAddresses(type: P2pkhAddressType.p2pkh); - } else if (walletInfo.type == WalletType.bitcoin) { - await _generateInitialAddresses(isLegacyDerivation: true); - await _generateInitialAddresses(); - if (!isHardwareWallet) { - await _generateInitialAddresses(type: P2pkhAddressType.p2pkh, isLegacyDerivation: true); - await _generateInitialAddresses(type: P2pkhAddressType.p2pkh); - - await _generateInitialAddresses(type: P2shAddressType.p2wpkhInP2sh, isLegacyDerivation: true); - await _generateInitialAddresses(type: P2shAddressType.p2wpkhInP2sh); - - await _generateInitialAddresses(type: SegwitAddresType.p2tr, isLegacyDerivation: true); - await _generateInitialAddresses(type: SegwitAddresType.p2tr); - - await _generateInitialAddresses(type: SegwitAddresType.p2wsh, isLegacyDerivation: true); - await _generateInitialAddresses(type: SegwitAddresType.p2wsh); - } + @override + Future init() async { + if (walletInfo.type == WalletType.bitcoinCash) { + await _generateInitialAddresses(type: P2pkhAddressType.p2pkh); + } else if (walletInfo.type == WalletType.litecoin) { + await _generateInitialAddresses(type: SegwitAddresType.p2wpkh); + if ((Platform.isAndroid || Platform.isIOS) && !isHardwareWallet) { + await _generateInitialAddresses(type: SegwitAddresType.mweb); } + } else if (walletInfo.type == WalletType.dogecoin) { + await _generateInitialAddresses(type: P2pkhAddressType.p2pkh); + } else if (walletInfo.type == WalletType.bitcoin) { + await _generateInitialAddresses(isLegacyDerivation: true); + await _generateInitialAddresses(); + if (!isHardwareWallet) { + await _generateInitialAddresses(type: P2pkhAddressType.p2pkh, isLegacyDerivation: true); + await _generateInitialAddresses(type: P2pkhAddressType.p2pkh); + + await _generateInitialAddresses( + type: P2shAddressType.p2wpkhInP2sh, isLegacyDerivation: true); + await _generateInitialAddresses(type: P2shAddressType.p2wpkhInP2sh); + + await _generateInitialAddresses(type: SegwitAddresType.p2tr, isLegacyDerivation: true); + await _generateInitialAddresses(type: SegwitAddresType.p2tr); + + await _generateInitialAddresses(type: SegwitAddresType.p2wsh, isLegacyDerivation: true); + await _generateInitialAddresses(type: SegwitAddresType.p2wsh); + } + } updateAddressesByMatch(); updateReceiveAddresses(); @@ -663,9 +663,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { @action void updateReceiveAddresses() { receiveAddresses.removeRange(0, receiveAddresses.length); - final newAddresses = _addresses.where((addressRecord) => - !addressRecord.isHidden && - !addressRecord.isUsed); + final newAddresses = + _addresses.where((addressRecord) => !addressRecord.isHidden && !addressRecord.isUsed); receiveAddresses.addAll(newAddresses); } @@ -682,12 +681,12 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { @action Future discoverAddresses( - List addressList, - bool isHidden, - Future Function(BitcoinAddressRecord) getAddressHistory, { - BitcoinAddressType type = SegwitAddresType.p2wpkh, - required bool isLegacyDerivation, - }) async { + List addressList, + bool isHidden, + Future Function(BitcoinAddressRecord) getAddressHistory, { + BitcoinAddressType type = SegwitAddresType.p2wpkh, + required bool isLegacyDerivation, + }) async { final newAddresses = await _createNewAddresses( gap, startIndex: addressList.length, @@ -699,8 +698,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { addAddresses(newAddresses); addressList.addAll(newAddresses); - final addressesWithHistory = - await Future.wait(newAddresses.map(getAddressHistory)); + final addressesWithHistory = await Future.wait(newAddresses.map(getAddressHistory)); final isLastAddressUsed = addressesWithHistory.last != null; if (isLastAddressUsed) { @@ -716,11 +714,11 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { @action Future discoverAddressesBatch( - List addressList, - bool isHidden, - Future> Function(List) getUsedAddresses, { - BitcoinAddressType type = SegwitAddresType.p2wpkh, - }) async { + List addressList, + bool isHidden, + Future> Function(List) getUsedAddresses, { + BitcoinAddressType type = SegwitAddresType.p2wpkh, + }) async { final newAddresses = await _createNewAddresses( gap, startIndex: addressList.length, @@ -749,64 +747,69 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { return true; } - Future _generateInitialAddresses( - {BitcoinAddressType type = SegwitAddresType.p2wpkh, - bool isLegacyDerivation = false }) async { - - // Legacy derivation produces the same addresses as standard for these types. - // Don't generate a legacy set to avoid duplicates. - if (isLegacyDerivation && (type == SegwitAddresType.p2wpkh || type == SegwitAddresType.p2wsh)) { - return; - } - - var countOfReceiveAddresses = 0; - var countOfHiddenAddresses = 0; - - _addresses.forEach((addr) { - if (addr.type == type && addr.isLegacyDerivation == isLegacyDerivation) { - if (addr.isHidden) { - countOfHiddenAddresses += 1; - } else { - countOfReceiveAddresses += 1; - } - } - }); - - if (countOfReceiveAddresses < defaultReceiveAddressesCount) { - final addressesCount = defaultReceiveAddressesCount - countOfReceiveAddresses; - final newAddresses = await _createNewAddresses(addressesCount, - startIndex: countOfReceiveAddresses, isHidden: false, type: type, isLegacyDerivation: isLegacyDerivation); - addAddresses(newAddresses); - } - - if (countOfHiddenAddresses < defaultChangeAddressesCount) { - final addressesCount = defaultChangeAddressesCount - countOfHiddenAddresses; - final newAddresses = await _createNewAddresses(addressesCount, - startIndex: countOfHiddenAddresses, isHidden: true, type: type, isLegacyDerivation: isLegacyDerivation); - addAddresses(newAddresses); - } + {BitcoinAddressType type = SegwitAddresType.p2wpkh, bool isLegacyDerivation = false}) async { + // Legacy derivation produces the same addresses as standard for these types. + // Don't generate a legacy set to avoid duplicates. + if (isLegacyDerivation && (type == SegwitAddresType.p2wpkh || type == SegwitAddresType.p2wsh)) { + return; } - Future> _createNewAddresses(int count, - {int startIndex = 0, bool isHidden = false, BitcoinAddressType? type, bool isLegacyDerivation = false}) async { - final list = []; + var countOfReceiveAddresses = 0; + var countOfHiddenAddresses = 0; - for (var i = startIndex; i < count + startIndex; i++) { - - final addrType = type ?? addressPageType; - final hd = _hdFor(isHidden: isHidden, type: addrType, isLegacyDerivation: isLegacyDerivation); - - final address = BitcoinAddressRecord( - await getAddressAsync(index: i, hd: hd, addressType: addrType), - index: i, - isHidden: isHidden, - isLegacyDerivation: isLegacyDerivation, - type: addrType, - network: network, - ); - list.add(address); + _addresses.forEach((addr) { + if (addr.type == type && addr.isLegacyDerivation == isLegacyDerivation) { + if (addr.isHidden) { + countOfHiddenAddresses += 1; + } else { + countOfReceiveAddresses += 1; + } } + }); + + if (countOfReceiveAddresses < defaultReceiveAddressesCount) { + final addressesCount = defaultReceiveAddressesCount - countOfReceiveAddresses; + final newAddresses = await _createNewAddresses(addressesCount, + startIndex: countOfReceiveAddresses, + isHidden: false, + type: type, + isLegacyDerivation: isLegacyDerivation); + addAddresses(newAddresses); + } + + if (countOfHiddenAddresses < defaultChangeAddressesCount) { + final addressesCount = defaultChangeAddressesCount - countOfHiddenAddresses; + final newAddresses = await _createNewAddresses(addressesCount, + startIndex: countOfHiddenAddresses, + isHidden: true, + type: type, + isLegacyDerivation: isLegacyDerivation); + addAddresses(newAddresses); + } + } + + Future> _createNewAddresses(int count, + {int startIndex = 0, + bool isHidden = false, + BitcoinAddressType? type, + bool isLegacyDerivation = false}) async { + final list = []; + + for (var i = startIndex; i < count + startIndex; i++) { + final addrType = type ?? addressPageType; + final hd = _hdFor(isHidden: isHidden, type: addrType, isLegacyDerivation: isLegacyDerivation); + + final address = BitcoinAddressRecord( + await getAddressAsync(index: i, hd: hd, addressType: addrType), + index: i, + isHidden: isHidden, + isLegacyDerivation: isLegacyDerivation, + type: addrType, + network: network, + ); + list.add(address); + } return list; } @@ -845,8 +848,10 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { return; } - final mainHd = _hdFor(isHidden: false, type: element.type, isLegacyDerivation: element.isLegacyDerivation); - final sideHd = _hdFor(isHidden: true, type: element.type, isLegacyDerivation: element.isLegacyDerivation); + final mainHd = _hdFor( + isHidden: false, type: element.type, isLegacyDerivation: element.isLegacyDerivation); + final sideHd = _hdFor( + isHidden: true, type: element.type, isLegacyDerivation: element.isLegacyDerivation); if (!element.isHidden && element.address != await getAddressAsync(index: element.index, hd: mainHd, addressType: element.type)) { @@ -874,7 +879,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { return _isAddressByType(addressRecord, addressPageType); } - bool _isAddressByType(BitcoinAddressRecord addr, BitcoinAddressType type) => addr.type == type; + bool _isAddressByType(BitcoinAddressRecord addr, BitcoinAddressType type) => addr.type == type; bool _isUnusedReceiveAddressByType(BitcoinAddressRecord addr, BitcoinAddressType type) => !addr.isHidden && !addr.isUsed && addr.type == type; @@ -884,9 +889,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { final addressRecord = silentAddresses.firstWhere((addressRecord) => addressRecord.type == SilentPaymentsAddresType.p2sp && addressRecord.address == address); - silentAddresses.remove(addressRecord); - updateAddressesByMatch(); - } + silentAddresses.remove(addressRecord); + updateAddressesByMatch(); + } Bip32Slip10Secp256k1 _hdFor({ required bool isHidden, @@ -900,7 +905,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { if (hd == null) throw Exception("HD not found for type $type"); return hd; } - + @action Future setLightningAddress(String walletName, {String newAddress = ""}) async { if (lightningWallet == null) return; diff --git a/cw_bitcoin/lib/exceptions.dart b/cw_bitcoin/lib/exceptions.dart index 9bdb66eef..d43ce823a 100644 --- a/cw_bitcoin/lib/exceptions.dart +++ b/cw_bitcoin/lib/exceptions.dart @@ -30,7 +30,7 @@ class BitcoinTransactionCommitFailed extends TransactionCommitFailed { @override String toString() { - return errorMessage??"unknown error"; + return errorMessage ?? "unknown error"; } } diff --git a/cw_bitcoin/lib/hardware/bitbox_service.dart b/cw_bitcoin/lib/hardware/bitbox_service.dart index 3f47c5c62..a71dcacbc 100644 --- a/cw_bitcoin/lib/hardware/bitbox_service.dart +++ b/cw_bitcoin/lib/hardware/bitbox_service.dart @@ -67,7 +67,8 @@ class BitcoinBitboxService extends HardwareWalletService with BitcoinHardwareWal Future getMasterFingerprint() => manager.getMasterFingerprint(); } -class LitecoinBitboxService extends HardwareWalletService with BitcoinHardwareWalletService, LitecoinHardwareWalletService { +class LitecoinBitboxService extends HardwareWalletService + with BitcoinHardwareWalletService, LitecoinHardwareWalletService { LitecoinBitboxService(this.manager); final BitboxManager manager; diff --git a/cw_bitcoin/lib/hardware/litecoin_ledger_service.dart b/cw_bitcoin/lib/hardware/litecoin_ledger_service.dart index 9ede5714e..aa73fc106 100644 --- a/cw_bitcoin/lib/hardware/litecoin_ledger_service.dart +++ b/cw_bitcoin/lib/hardware/litecoin_ledger_service.dart @@ -12,7 +12,8 @@ import 'package:cw_core/hardware/hardware_wallet_service.dart'; import 'package:ledger_flutter_plus/ledger_flutter_plus.dart'; import 'package:ledger_litecoin/ledger_litecoin.dart'; -class LitecoinLedgerService extends HardwareWalletService with BitcoinHardwareWalletService, LitecoinHardwareWalletService { +class LitecoinLedgerService extends HardwareWalletService + with BitcoinHardwareWalletService, LitecoinHardwareWalletService { LitecoinLedgerService(this.ledgerConnection) : litecoinLedgerApp = LitecoinLedgerApp(ledgerConnection); @@ -53,7 +54,6 @@ class LitecoinLedgerService extends HardwareWalletService with BitcoinHardwareWa required List inputs, required Map publicKeys, }) { - final readyInputs = []; for (final utxo in inputs) { final publicKeyAndDerivationPath = publicKeys[utxo.ownerDetails.address.pubKeyHash()]!; @@ -77,7 +77,7 @@ class LitecoinLedgerService extends HardwareWalletService with BitcoinHardwareWa inputs: readyInputs, outputs: outputs .map((e) => TransactionOutput.fromBigInt((e as BitcoinOutput).value, - Uint8List.fromList(e.address.toScriptPubKey().toBytes()))) + Uint8List.fromList(e.address.toScriptPubKey().toBytes()))) .toList(), changePath: changePath, sigHashType: 0x01, diff --git a/cw_bitcoin/lib/hardware/trezor_service.dart b/cw_bitcoin/lib/hardware/trezor_service.dart index 8c5247a68..8308aa4a8 100644 --- a/cw_bitcoin/lib/hardware/trezor_service.dart +++ b/cw_bitcoin/lib/hardware/trezor_service.dart @@ -90,7 +90,8 @@ class BitcoinTrezorService extends HardwareWalletService with BitcoinHardwareWal } } -class LitecoinTrezorService extends HardwareWalletService with BitcoinHardwareWalletService, LitecoinHardwareWalletService { +class LitecoinTrezorService extends HardwareWalletService + with BitcoinHardwareWalletService, LitecoinHardwareWalletService { LitecoinTrezorService(this.connect); final TrezorConnect connect; diff --git a/cw_bitcoin/lib/lightning/lightning_wallet.dart b/cw_bitcoin/lib/lightning/lightning_wallet.dart index 91890d20f..528ea913f 100644 --- a/cw_bitcoin/lib/lightning/lightning_wallet.dart +++ b/cw_bitcoin/lib/lightning/lightning_wallet.dart @@ -67,8 +67,7 @@ class LightningWallet { lnurlDomain: lnurlDomain, apiKey: apiKey, privateEnabledDefault: true, - maxDepositClaimFee: MaxFee.rate(satPerVbyte: BigInt.from(5)) - ); + maxDepositClaimFee: MaxFee.rate(satPerVbyte: BigInt.from(5))); final connectRequest = ConnectRequest( config: config, @@ -82,8 +81,7 @@ class LightningWallet { _logStream ??= initLogging().asBroadcastStream(); try { - final logFile = File("$appPath/lightning.log") - ..createSync(); + final logFile = File("$appPath/lightning.log")..createSync(); _subscribeToLogStream(logFile); } catch (e) { printV(e); @@ -172,15 +170,17 @@ class LightningWallet { } } - Future createTransaction( - String address, BigInt? amountSats, BitcoinTransactionPriority? priority, bool feesIncluded) async { + Future createTransaction(String address, BigInt? amountSats, + BitcoinTransactionPriority? priority, bool feesIncluded) async { final inputType = await sdk.parse(input: address); final feePolicy = feesIncluded ? FeePolicy.feesIncluded : FeePolicy.feesExcluded; if (inputType is InputType_Bolt11Invoice) { final request = PrepareSendPaymentRequest( - paymentRequest: inputType.field0.invoice.bolt11, amount: amountSats, feePolicy: feePolicy); + paymentRequest: inputType.field0.invoice.bolt11, + amount: amountSats, + feePolicy: feePolicy); final prepareResponse = await sdk.prepareSendPayment(request: request); final paymentMethod = prepareResponse.paymentMethod; @@ -190,7 +190,8 @@ class LightningWallet { return PendingLightningTransaction( id: paymentMethod.invoiceDetails.paymentHash, - amount: request.amount?.toInt() ?? amountSats?.toInt() ?? + amount: request.amount?.toInt() ?? + amountSats?.toInt() ?? ((paymentMethod.invoiceDetails.amountMsat?.toInt() ?? 0) / 1000).round(), fee: lightningFeeSats.toInt() + (sparkTransferFeeSats?.toInt() ?? 0), commitOverride: () async { @@ -361,14 +362,16 @@ class LightningWallet { return _getElectrumTransactionInfoFromPayment(response.payment); } - Future refundDeposit(String txId, int vout, String destinationAddress, - BigInt feeRate) async { - final response = await sdk.refundDeposit(request: RefundDepositRequest( - txid: txId, - vout: vout, - destinationAddress: destinationAddress, - fee: Fee.rate(satPerVbyte: feeRate), - ),); + Future refundDeposit( + String txId, int vout, String destinationAddress, BigInt feeRate) async { + final response = await sdk.refundDeposit( + request: RefundDepositRequest( + txid: txId, + vout: vout, + destinationAddress: destinationAddress, + fee: Fee.rate(satPerVbyte: feeRate), + ), + ); return response.txHex; } diff --git a/cw_bitcoin/lib/lightning/pending_lightning_transaction.dart b/cw_bitcoin/lib/lightning/pending_lightning_transaction.dart index cb75b7d2b..a5ff93884 100644 --- a/cw_bitcoin/lib/lightning/pending_lightning_transaction.dart +++ b/cw_bitcoin/lib/lightning/pending_lightning_transaction.dart @@ -14,7 +14,7 @@ class PendingLightningTransaction with PendingTransaction { final int fee; final bool isSendAll; Future Function() commitOverride; - final List _listeners =[]; + final List _listeners = []; @override final String id; diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index 3cee6c9da..f76a55e96 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -184,7 +184,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { @override bool get hasRescan => true; - final String? scanSecretOverride; final String? spendPubkeyOverride; List get scanSecret => (scanSecretOverride != null && scanSecretOverride?.isNotEmpty == true) @@ -241,8 +240,12 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { } @override - WalletKeysData get walletKeysData => - WalletKeysData(mnemonic: seed, xPub: xpub, passphrase: passphrase, scanSecret: scanSecretOverride, spendPubkey: spendPubkeyOverride); + WalletKeysData get walletKeysData => WalletKeysData( + mnemonic: seed, + xPub: xpub, + passphrase: passphrase, + scanSecret: scanSecretOverride, + spendPubkey: spendPubkeyOverride); static Future open({ required String name, @@ -1115,15 +1118,18 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { for (final utxo in transaction.utxos) { if (utxo.utxo.scriptType != SegwitAddresType.mweb) { inputs.add(utxo.utxo.toInput()); - txouts.add(TxOut(value: Int64(utxo.utxo.value.toInt()), - pkScript: utxo.ownerDetails.address.toScriptPubKey().toBytes())); + txouts.add(TxOut( + value: Int64(utxo.utxo.value.toInt()), + pkScript: utxo.ownerDetails.address.toScriptPubKey().toBytes())); } } var resp = await CwMweb.psbtCreate(PsbtCreateRequest( - rawTx: inputs.isEmpty ? null : BtcTransaction( - inputs: inputs, - outputs: isMweb ? [] : transaction.outputs, - ).toBytes(), + rawTx: inputs.isEmpty + ? null + : BtcTransaction( + inputs: inputs, + outputs: isMweb ? [] : transaction.outputs, + ).toBytes(), witnessUtxo: txouts, )); for (final utxo in transaction.utxos) { @@ -1136,17 +1142,18 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { )); } } - if (isMweb) for (final output in transaction.outputs) { - var address = addressFromOutputScript(output.scriptPubKey, LitecoinNetwork.mainnet); - if (output.scriptPubKey.getAddressType() == SegwitAddresType.mweb) { - address = SegwitBech32Encoder.encode("ltcmweb", 0, output.scriptPubKey.toBytes()); + if (isMweb) + for (final output in transaction.outputs) { + var address = addressFromOutputScript(output.scriptPubKey, LitecoinNetwork.mainnet); + if (output.scriptPubKey.getAddressType() == SegwitAddresType.mweb) { + address = SegwitBech32Encoder.encode("ltcmweb", 0, output.scriptPubKey.toBytes()); + } + resp = await CwMweb.psbtAddRecipient(PsbtAddRecipientRequest( + psbtB64: resp.psbtB64, + recipient: PsbtRecipient(address: address, value: Int64(output.amount.toInt())), + feeRatePerKb: Int64.parseInt(transaction.feeRate) * 1000, + )); } - resp = await CwMweb.psbtAddRecipient(PsbtAddRecipientRequest( - psbtB64: resp.psbtB64, - recipient: PsbtRecipient(address: address, value: Int64(output.amount.toInt())), - feeRatePerKb: Int64.parseInt(transaction.feeRate) * 1000, - )); - } return base64.decode(resp.psbtB64); } @@ -1212,7 +1219,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { for (final utxo in tx.utxos) { if (utxo.utxo.scriptType == SegwitAddresType.mweb) { hasMwebInput = true; - } else { // check if any of the inputs of this transaction are hog-ex: // this list is only non-mweb inputs: @@ -1265,9 +1271,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { final utxo = unspentCoins .firstWhere((utxo) => utxo.hash == e.value.txId && utxo.vout == e.value.txIndex); final key = generateECPrivate( - hd: utxo.bitcoinAddressRecord.isHidden - ? sideHd - : mainHd, + hd: utxo.bitcoinAddressRecord.isHidden ? sideHd : mainHd, index: utxo.bitcoinAddressRecord.index, network: network); final digest = tx2.getTransactionSegwitDigit( @@ -1293,8 +1297,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { } } - void addTransactionListener(PendingBitcoinTransaction tx, - List inputAddresses, bool isPegIn, bool isPegOut) { + void addTransactionListener( + PendingBitcoinTransaction tx, List inputAddresses, bool isPegIn, bool isPegOut) { tx.addListener((transaction) async { final addresses = {}; transaction.inputAddresses?.addAll(inputAddresses); @@ -1584,7 +1588,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store { rawTx: rawTx, ownerDetails: utxo.ownerDetails, ownerDerivationPath: publicKeyAndDerivationPath.derivationPath, - ownerMasterFingerprint:masterFingerprint, + ownerMasterFingerprint: masterFingerprint, ownerPublicKey: publicKeyAndDerivationPath.publicKey, )); } diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart index eee49591a..53128cc9c 100644 --- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart +++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart @@ -59,9 +59,11 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with ? hex.decode(scanSecretOverride!) : mwebHd?.childKey(Bip32KeyIndex(0x80000000)).privateKey.privKey.raw ?? List.filled(32, 0); - List get spendPubkey => (spendPubkeyOverride != null && spendPubkeyOverride?.isNotEmpty == true) - ? hex.decode(spendPubkeyOverride!) - : mwebHd?.childKey(Bip32KeyIndex(0x80000001)).publicKey.pubKey.compressed ?? List.filled(32, 0); + List get spendPubkey => + (spendPubkeyOverride != null && spendPubkeyOverride?.isNotEmpty == true) + ? hex.decode(spendPubkeyOverride!) + : mwebHd?.childKey(Bip32KeyIndex(0x80000001)).publicKey.pubKey.compressed ?? + List.filled(32, 0); @override Future init() async { @@ -81,7 +83,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with return null; } if ((scanSecret.length < 1 || scanSecret.reduce((a, b) => a + b) == 0) && - (spendPubkey.length < 1 || spendPubkey.reduce((a, b) => a + b) == 0)) { + (spendPubkey.length < 1 || spendPubkey.reduce((a, b) => a + b) == 0)) { return null; } diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart index 739602e24..4414c95b7 100644 --- a/cw_bitcoin/lib/litecoin_wallet_service.dart +++ b/cw_bitcoin/lib/litecoin_wallet_service.dart @@ -50,7 +50,8 @@ class LitecoinWalletService extends WalletService< password: credentials.password!, passphrase: credentials.passphrase, walletInfo: credentials.walletInfo!, - derivationInfo: credentials.derivationInfo ?? (await credentials.walletInfo!.getDerivationInfo()), + derivationInfo: + credentials.derivationInfo ?? (await credentials.walletInfo!.getDerivationInfo()), unspentCoinsInfo: unspentCoinsInfoSource, encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); @@ -66,7 +67,6 @@ class LitecoinWalletService extends WalletService< @override Future openWallet(String name, String password) async { - final walletInfo = await WalletInfo.get(name, getType()); if (walletInfo == null) { throw Exception('Wallet not found'); @@ -127,8 +127,9 @@ class LitecoinWalletService extends WalletService< } } - final unspentCoinsToDelete = unspentCoinsInfoSource.values.where( - (unspentCoin) => unspentCoin.walletId == walletInfo.id).toList(); + final unspentCoinsToDelete = unspentCoinsInfoSource.values + .where((unspentCoin) => unspentCoin.walletId == walletInfo.id) + .toList(); final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList(); @@ -167,8 +168,7 @@ class LitecoinWalletService extends WalletService< final network = isTestnet == true ? LitecoinNetwork.testnet : LitecoinNetwork.mainnet; credentials.walletInfo?.network = network.value; final derivationInfo = await credentials.walletInfo!.getDerivationInfo(); - derivationInfo.derivationPath = - credentials.hwAccountData.derivationPath; + derivationInfo.derivationPath = credentials.hwAccountData.derivationPath; await derivationInfo.save(); credentials.walletInfo!.save(); @@ -187,7 +187,7 @@ class LitecoinWalletService extends WalletService< @override Future restoreFromKeys(LitecoinWalletFromKeysCredentials credentials, - {bool? isTestnet}) async { + {bool? isTestnet}) async { final network = isTestnet == true ? LitecoinNetwork.testnet : LitecoinNetwork.mainnet; credentials.walletInfo?.network = network.value; @@ -219,7 +219,8 @@ class LitecoinWalletService extends WalletService< passphrase: credentials.passphrase, mnemonic: credentials.mnemonic, walletInfo: credentials.walletInfo!, - derivationInfo: credentials.derivationInfo ?? (await credentials.walletInfo!.getDerivationInfo()), + derivationInfo: + credentials.derivationInfo ?? (await credentials.walletInfo!.getDerivationInfo()), unspentCoinsInfo: unspentCoinsInfoSource, encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); diff --git a/cw_bitcoin/lib/payjoin/manager.dart b/cw_bitcoin/lib/payjoin/manager.dart index 437fed3ff..00187505d 100644 --- a/cw_bitcoin/lib/payjoin/manager.dart +++ b/cw_bitcoin/lib/payjoin/manager.dart @@ -108,16 +108,14 @@ class PayjoinManager { Future initSender( String pjUriString, String originalPsbt, int networkFeesSatPerVb) async { try { - final pjUri = - (await PayjoinUri.Uri.fromStr(pjUriString)).checkPjSupported(); + final pjUri = (await PayjoinUri.Uri.fromStr(pjUriString)).checkPjSupported(); final minFeeRateSatPerKwu = BigInt.from(networkFeesSatPerVb * 250); final senderBuilder = await SenderBuilder.fromPsbtAndUri( psbtBase64: originalPsbt, pjUri: pjUri, ); final persister = PayjoinSenderPersister.impl(); - final newSender = - await senderBuilder.buildRecommended(minFeeRate: minFeeRateSatPerKwu); + final newSender = await senderBuilder.buildRecommended(minFeeRate: minFeeRateSatPerKwu); final senderToken = await newSender.persist(persister: persister); return Sender.load(token: senderToken, persister: persister); @@ -133,8 +131,7 @@ class PayjoinManager { bool isTestnet = false, }) async { final pjUri = Uri.parse(pjUrl).queryParameters['pj']!; - await _payjoinStorage.insertSenderSession( - sender, pjUri, _wallet.id, amount); + await _payjoinStorage.insertSenderSession(sender, pjUri, _wallet.id, amount); return _spawnSender(isTestnet: isTestnet, sender: sender, pjUri: pjUri); } @@ -207,8 +204,7 @@ class PayjoinManager { return completer.future; } - Future getUnusedReceiver(String address, - [bool isTestnet = false]) async { + Future getUnusedReceiver(String address, [bool isTestnet = false]) async { final session = _payjoinStorage.getUnusedActiveReceiverSession(_wallet.id); if (session != null) { @@ -220,7 +216,8 @@ class PayjoinManager { return initReceiver(address); } - Future initReceiver(String address, [bool isTestnet = false, int retryCount = 0]) async { + Future initReceiver(String address, + [bool isTestnet = false, int retryCount = 0]) async { if (retryCount > 0) writePayjoinLog("Retrying initReceiver ${retryCount + 1} attempt"); try { @@ -245,7 +242,6 @@ class PayjoinManager { } catch (e) { writePayjoinLog(e.toString()); if (e.toString().contains("error sending request for url") && retryCount < 5) { - return initReceiver(address, isTestnet, ++retryCount); } else { rethrow; @@ -273,13 +269,11 @@ class PayjoinManager { rawAmount = getOutputAmountFromTx(tx, _wallet); break; case PayjoinReceiverRequestTypes.checkIsOwned: - (_wallet.walletAddresses as BitcoinWalletAddresses) - .newPayjoinReceiver(); + (_wallet.walletAddresses as BitcoinWalletAddresses).newPayjoinReceiver(); _payjoinStorage.markReceiverSessionInProgress(receiver.id()); final inputScript = message['input_script'] as Uint8List; - final isOwned = - _wallet.isMine(Script.fromRaw(byteData: inputScript)); + final isOwned = _wallet.isMine(Script.fromRaw(byteData: inputScript)); mainToIsolateSendPort?.send({ 'requestId': message['requestId'], 'result': isOwned, @@ -288,8 +282,7 @@ class PayjoinManager { case PayjoinReceiverRequestTypes.checkIsReceiverOutput: final outputScript = message['output_script'] as Uint8List; - final isReceiverOutput = - _wallet.isMine(Script.fromRaw(byteData: outputScript)); + final isReceiverOutput = _wallet.isMine(Script.fromRaw(byteData: outputScript)); mainToIsolateSendPort?.send({ 'requestId': message['requestId'], 'result': isReceiverOutput, @@ -310,7 +303,8 @@ class PayjoinManager { case PayjoinReceiverRequestTypes.processPsbt: final psbt = message['psbt'] as String; - writePayjoinLog("Receiver(${receiver.id()}) PayjoinReceiverRequestTypes.processPsbt: $psbt"); + writePayjoinLog( + "Receiver(${receiver.id()}) PayjoinReceiverRequestTypes.processPsbt: $psbt"); final signedPsbt = await _wallet.signPsbt(psbt, utxos); mainToIsolateSendPort?.send({ @@ -322,7 +316,8 @@ class PayjoinManager { case PayjoinReceiverRequestTypes.proposalSent: _cleanupSession(receiver.id()); final psbt = message['psbt'] as String; - writePayjoinLog("Receiver(${receiver.id()}) PayjoinReceiverRequestTypes.proposalSent: $psbt"); + writePayjoinLog( + "Receiver(${receiver.id()}) PayjoinReceiverRequestTypes.proposalSent: $psbt"); await _payjoinStorage.markReceiverSessionComplete( receiver.id(), getTxIdFromPsbtV0(psbt), rawAmount); diff --git a/cw_bitcoin/lib/payjoin/payjoin_receive_worker.dart b/cw_bitcoin/lib/payjoin/payjoin_receive_worker.dart index ba0d8d0fb..5580e1c08 100644 --- a/cw_bitcoin/lib/payjoin/payjoin_receive_worker.dart +++ b/cw_bitcoin/lib/payjoin/payjoin_receive_worker.dart @@ -47,8 +47,7 @@ class PayjoinReceiverWorker { try { final receiver = Receiver.fromJson(json: receiverJson); - final uncheckedProposal = - await worker.receiveUncheckedProposal(receiver); + final uncheckedProposal = await worker.receiveUncheckedProposal(receiver); final originalTx = await uncheckedProposal.extractTxToScheduleBroadcast(); sendPort.send({ @@ -112,8 +111,7 @@ class PayjoinReceiverWorker { final httpRequest = await client.post(url, headers: {'Content-Type': request.contentType}, body: request.body); - final proposal = await session.processRes( - body: httpRequest.bodyBytes, ctx: extractReq.$2); + final proposal = await session.processRes(body: httpRequest.bodyBytes, ctx: extractReq.$2); if (proposal != null) return proposal; sleep(Duration(seconds: 2)); } @@ -140,8 +138,7 @@ class PayjoinReceiverWorker { return await finalProposal.psbt(); } - Future processPayjoinProposal( - UncheckedProposal proposal) async { + Future processPayjoinProposal(UncheckedProposal proposal) async { await proposal.extractTxToScheduleBroadcast(); // TODO Handle this. send to the main port on a timer? @@ -174,8 +171,7 @@ class PayjoinReceiverWorker { ); final pj5 = await pj4.commitOutputs(); - final listUnspent = - await _sendRequest(PayjoinReceiverRequestTypes.getCandidateInputs); + final listUnspent = await _sendRequest(PayjoinReceiverRequestTypes.getCandidateInputs); final unspent = listUnspent as List; if (unspent.isEmpty) throw RecoverableError('No unspent outputs available'); @@ -186,8 +182,8 @@ class PayjoinReceiverWorker { // Finalize proposal final payjoinProposal = await pj7.finalizeProposal( processPsbt: (String psbt) async { - final result = await _sendRequest( - PayjoinReceiverRequestTypes.processPsbt, {'psbt': psbt}); + final result = + await _sendRequest(PayjoinReceiverRequestTypes.processPsbt, {'psbt': psbt}); return result as String; }, // TODO set maxFeeRateSatPerVb @@ -203,15 +199,12 @@ class PayjoinReceiverWorker { Future _inputPairFromUtxo(UtxoWithPrivateKey utxo) async { final txout = TxOut( value: utxo.utxo.value, - scriptPubkey: Uint8List.fromList( - utxo.ownerDetails.address.toScriptPubKey().toBytes()), + scriptPubkey: Uint8List.fromList(utxo.ownerDetails.address.toScriptPubKey().toBytes()), ); - final psbtin = - PsbtInput(witnessUtxo: txout, redeemScript: null, witnessScript: null); + final psbtin = PsbtInput(witnessUtxo: txout, redeemScript: null, witnessScript: null); - final previousOutput = - OutPoint(txid: utxo.utxo.txHash, vout: utxo.utxo.vout); + final previousOutput = OutPoint(txid: utxo.utxo.txHash, vout: utxo.utxo.vout); final txin = TxIn( previousOutput: previousOutput, diff --git a/cw_bitcoin/lib/payjoin/payjoin_send_worker.dart b/cw_bitcoin/lib/payjoin/payjoin_send_worker.dart index 75f58a4e3..0d46d1f62 100644 --- a/cw_bitcoin/lib/payjoin/payjoin_send_worker.dart +++ b/cw_bitcoin/lib/payjoin/payjoin_send_worker.dart @@ -46,11 +46,11 @@ class PayjoinSenderWorker { sendPort.send(e); } } + final client = ProxyWrapper().getHttpIOClient(); /// Run a payjoin sender (V2 protocol first, fallback to V1). Future runSender(Sender sender) async { - try { return await _runSenderV2(sender); } catch (e) { @@ -70,13 +70,11 @@ class PayjoinSenderWorker { Future _runSenderV2(Sender sender) async { try { final postRequest = await sender.extractV2( - ohttpProxyUrl: - await pj_uri.Url.fromStr(PayjoinManager.randomOhttpRelayUrl()), + ohttpProxyUrl: await pj_uri.Url.fromStr(PayjoinManager.randomOhttpRelayUrl()), ); final postResult = await _postRequest(postRequest.$1); - final getContext = - await postRequest.$2.processResponse(response: postResult); + final getContext = await postRequest.$2.processResponse(response: postResult); sendPort.send({'type': PayjoinSenderRequestTypes.requestPosted, "pj": pjUrl}); diff --git a/cw_bitcoin/lib/payjoin/storage.dart b/cw_bitcoin/lib/payjoin/storage.dart index 5fb9d5716..e4132ebfa 100644 --- a/cw_bitcoin/lib/payjoin/storage.dart +++ b/cw_bitcoin/lib/payjoin/storage.dart @@ -23,16 +23,14 @@ class PayjoinStorage { ), ); - PayjoinSession? getUnusedActiveReceiverSession(String walletId) => - _payjoinSessionSources.values - .where((session) => - session.walletId == walletId && - session.status == PayjoinSessionStatus.created.name && - !session.isSenderSession) - .firstOrNull; + PayjoinSession? getUnusedActiveReceiverSession(String walletId) => _payjoinSessionSources.values + .where((session) => + session.walletId == walletId && + session.status == PayjoinSessionStatus.created.name && + !session.isSenderSession) + .firstOrNull; - Future markReceiverSessionComplete( - String sessionId, String txId, String amount) async { + Future markReceiverSessionComplete(String sessionId, String txId, String amount) async { final session = _payjoinSessionSources.get("$_receiverPrefix${sessionId}")!; session.status = PayjoinSessionStatus.success.name; @@ -41,8 +39,7 @@ class PayjoinStorage { await session.save(); } - Future markReceiverSessionUnrecoverable( - String sessionId, String reason) async { + Future markReceiverSessionUnrecoverable(String sessionId, String reason) async { final session = _payjoinSessionSources.get("$_receiverPrefix${sessionId}")!; session.status = PayjoinSessionStatus.unrecoverable.name; @@ -92,13 +89,10 @@ class PayjoinStorage { await session.save(); } - List readAllOpenSessions(String walletId) => - _payjoinSessionSources.values - .where((session) => - session.walletId == walletId && - ![ - PayjoinSessionStatus.success.name, - PayjoinSessionStatus.unrecoverable.name - ].contains(session.status)) - .toList(); + List readAllOpenSessions(String walletId) => _payjoinSessionSources.values + .where((session) => + session.walletId == walletId && + ![PayjoinSessionStatus.success.name, PayjoinSessionStatus.unrecoverable.name] + .contains(session.status)) + .toList(); } diff --git a/cw_bitcoin/lib/pending_bitcoin_transaction.dart b/cw_bitcoin/lib/pending_bitcoin_transaction.dart index a9b741dc7..f0bebb76b 100644 --- a/cw_bitcoin/lib/pending_bitcoin_transaction.dart +++ b/cw_bitcoin/lib/pending_bitcoin_transaction.dart @@ -74,7 +74,7 @@ class PendingBitcoinTransaction with PendingTransaction { String get feeFormatted => "$feeFormattedValue ${_feeCurrency}"; String get _feeCurrency { - switch(type) { + switch (type) { case WalletType.bitcoin: return "BTC"; case WalletType.litecoin: @@ -86,10 +86,8 @@ class PendingBitcoinTransaction with PendingTransaction { default: return type.name; } - } - @override String get feeFormattedValue => bitcoinAmountToString(amount: fee); @@ -155,14 +153,12 @@ class PendingBitcoinTransaction with PendingTransaction { Future _ltcCommit() async { try { - final resp = await CwMweb.broadcast( - BroadcastRequest(rawTx: BytesUtils.fromHexString(hex))); + final resp = await CwMweb.broadcast(BroadcastRequest(rawTx: BytesUtils.fromHexString(hex))); idOverride = resp.txid; } on GrpcError catch (e) { throw BitcoinTransactionCommitFailed(errorMessage: e.message); } catch (e) { - throw BitcoinTransactionCommitFailed( - errorMessage: "Unknown error: ${e.toString()}"); + throw BitcoinTransactionCommitFailed(errorMessage: "Unknown error: ${e.toString()}"); } } @@ -181,8 +177,7 @@ class PendingBitcoinTransaction with PendingTransaction { _listeners.forEach((listener) => listener(transactionInfo())); } - void addListener( - void Function(ElectrumTransactionInfo transaction) listener) => + void addListener(void Function(ElectrumTransactionInfo transaction) listener) => _listeners.add(listener); ElectrumTransactionInfo transactionInfo() => ElectrumTransactionInfo(type, @@ -207,8 +202,8 @@ class PendingBitcoinTransaction with PendingTransaction { var cborEncoder = CBOREncoder(); cborEncoder.encodeBytes(sourceBytes); var ur = UR("psbt", cborEncoder.getBytes()); - var urLegacy = UR("crypto-psbt", cborEncoder.getBytes()); - // var ur = UR("psbt", Uint8List.fromList(List.generate(64*1024, (int x) => x % 256))); + var urLegacy = UR("crypto-psbt", cborEncoder.getBytes()); + // var ur = UR("psbt", Uint8List.fromList(List.generate(64*1024, (int x) => x % 256))); var encoded = UREncoder(ur, 120); var encodedLegacy = UREncoder(urLegacy, 120); List values = []; @@ -230,8 +225,7 @@ class PendingBitcoinTransaction with PendingTransaction { return Future.value({ "Cupcake bcur": values.join("\n"), "ColdCard bbqr": bbqr.join("\n"), - if (kDebugMode) - "SeedSigner bcur legacy": valuesLegacy.join("\n"), + if (kDebugMode) "SeedSigner bcur legacy": valuesLegacy.join("\n"), }); } } diff --git a/cw_bitcoin/lib/psbt/signer.dart b/cw_bitcoin/lib/psbt/signer.dart index c46517e66..fbd00b842 100644 --- a/cw_bitcoin/lib/psbt/signer.dart +++ b/cw_bitcoin/lib/psbt/signer.dart @@ -40,8 +40,7 @@ extension PsbtSigner on PsbtV2 { return tx.buffer(); } - Future signWithUTXO( - List utxos, UTXOSignerCallBack signer, + Future signWithUTXO(List utxos, UTXOSignerCallBack signer, [UTXOGetterCallBack? getTaprootPair]) async { final raw = BytesUtils.toHexString(extractUnsignedTX(getSegwit: false)); final tx = BtcTransaction.fromRaw(raw); @@ -53,8 +52,8 @@ extension PsbtSigner on PsbtV2 { if (utxos.any((e) => e.utxo.isP2tr())) { for (final input in tx.inputs) { - final utxo = utxos.firstWhereOrNull( - (u) => u.utxo.txHash == input.txId && u.utxo.vout == input.txIndex); + final utxo = utxos + .firstWhereOrNull((u) => u.utxo.txHash == input.txId && u.utxo.vout == input.txIndex); if (utxo == null) { final trPair = await getTaprootPair!.call(input.txId, input.txIndex); @@ -81,8 +80,8 @@ extension PsbtSigner on PsbtV2 { : BitcoinOpCodeConst.SIGHASH_ALL; /// We generate transaction digest for current input - final digest = _generateTransactionDigest( - script, i, utxo.utxo, tx, taprootAmounts, taprootScripts); + final digest = + _generateTransactionDigest(script, i, utxo.utxo, tx, taprootAmounts, taprootScripts); /// now we need sign the transaction digest final sig = signer(digest, utxo, utxo.privateKey, sighash); @@ -90,21 +89,14 @@ extension PsbtSigner on PsbtV2 { if (utxo.utxo.isP2tr()) { setInputTapKeySig(i, Uint8List.fromList(BytesUtils.fromHexString(sig))); } else { - setInputPartialSig( - i, - Uint8List.fromList(BytesUtils.fromHexString(utxo.public().toHex())), + setInputPartialSig(i, Uint8List.fromList(BytesUtils.fromHexString(utxo.public().toHex())), Uint8List.fromList(BytesUtils.fromHexString(sig))); } } } - List _generateTransactionDigest( - Script scriptPubKeys, - int input, - BitcoinUtxo utxo, - BtcTransaction transaction, - List taprootAmounts, - List