Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(release): v0.9.0 - HD support, Unified codebase, Custom tokens, and SDK migration #2526

Open
wants to merge 57 commits into
base: main
Choose a base branch
from

Conversation

CharlVS
Copy link
Member

@CharlVS CharlVS commented Feb 11, 2025

TODO

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced a new GitHub Actions workflow for code coverage reporting.
    • Added a GitHub Actions workflow for installing Flutter dependencies.
    • Implemented a new GitHub Actions workflow for generating assets.
    • Introduced a GitHub Actions workflow for validating builds.
    • Enhanced Firebase Hosting deployment workflows for better modularity.
    • Added support for generating unit test coverage reports.
    • Introduced a new interface for managing custom token imports.
    • Added a new CoinAddressesBloc for managing coin addresses.
    • Introduced a CustomTokenImportBloc to handle custom token imports.
    • Added a FiatFormBloc for managing fiat on-ramp forms.
  • Improvements

    • Streamlined workflows by utilizing custom actions for asset generation and build validation.
    • Enhanced documentation for build configuration and running instructions.
    • Improved error handling and clarity in various workflows and actions.
    • Updated translation strings for better user experience.
    • Enhanced the WithdrawFormBloc to support new asset and SDK-based operations.
    • Refactored MarketMakerBotBloc for better event handling and integration with new dependencies.
    • Updated Android and iOS build configurations to support newer SDK versions.
  • Fixes

    • Resolved issues related to the handling of unsupported coins and improved validation logic.
    • Fixed bugs related to the management of coin addresses and transaction history retrieval.
    • Improved error handling in the NftWithdrawBloc and MarketMakerBotBloc.
    • Enhanced error logging and handling in the BanxaFiatProvider and RampFiatProvider.

smk762 and others added 30 commits November 8, 2024 23:22
* CI self-hosted config test #1

* Fix incorrect duplicated job ID

* CI test #2

* CI Test #3

Results of test #2: integration tests work when using GitHub-hosted Actions latest ubuntu

* CI Test #4

* Test unit/integration tests on hosted runner

Test unit/integration tests on the hosted runner to determine if the cause of the failing tests is related to differences between self-hosted and hosted environment.

* Update CI conditional statements of self-hosted runners

Update CI conditional statements that referenced variables only applicable to self-hosted runners. Change to the equivalent for hosted runners.

* Remove very_good_analysis linting dependency

Flutter is not fetching dependencies for sub-packages in the `packages` directory, so the very_good_analysis files are missing until `flutter pub get` is ran for each package

* Add composite actions for asset generation and build validation

* Remove chromedriver from unit tests workflow

* Add missing `shell` property to the `generate-assets` action

Also remove the default value, and unset the environment variable if it does not exist

* Delete the `build/` directory between builds to clear AssetManifest.bin

Rebuilds do not appear to consistently update AssetManifest.bin, even if there are new assets generated between builds (icons, coin configs)

* Add code coverage report as artefact upload

Temporary until link with 3rd-party sources like CodeCov is setup

* Only fail the coverage step if the report does not exist

The flutter test command failing or passing should not affect the test coverage step success/failure

* Fix profit/loss unit tests

Binance closing price introduces some variability in the calculated profit/loss that has to be accounted for. The margin of error can be reduced by improved price and timestamp matching, but this should suffice for now

* Fix code coverage generation action

I forgot the spaces in the bash condition :(. It should be "if [ ... ]; then"

* Revert to using `strings` before `grep` to be platform independent

macOS handles binary files differently to Linux, meaning that `grep -i ...` works with binary files on Linux systems, but not macOS

* Remove trailing spaces in zip generation command

Trailing spaces after the backslash in a multi-line command causes it to fail with "command not found"

* Prefix artefact with runner name & move coverage step to end of ui tests

* Update job names and add descriptions

* Switch build_transformer over to the new sdk repo

* Remove old build_transformer package

* Revert changes to web/src/index.html

* Add index.html to .gitignore

* Move webpack JS files out of web/src

* Revert changes to index.html once more :(

* Untrack index.html & update build transformer package

* Use default GITHUB_TOKEN to make authenticated requests

* Add test case for failing binance requests

* demo data generator: check if coin is supported before fetching

* Add validation step for build_config.json

* Fix silently failing asset manifest validation check

* Add json validity checks for coin configs

* Update commit sha of build transformer package

* Use abstract repository class in generate demo data

* Install Chrome alongside chromedriver on linux for UI tests

* Skip generate demo test data unit tests

* Bump build transformer to dev branch

* Switch UI and unit test workflows back to self-hosted runners

* Restrict coverage report to linux-based runners

* Improve npm build cross-platform compatibility

'&&' is invalid in Windows PowerShell. ';' works on Windows, macOS, and Linux

* Move Flutter and NodeJS installation to composite action

* Add github token to UI and unit test steps

Seeing 403 responses on self-hosted runners

* Fix UI integration tests on self-hosted macos

* Export logs for safaridriver in workflows

Use the --diagnose flag when starting safaridriver

* Fix failing restore wallet integration test

* Add verbose flag to integration test runner

* Fix issues with pumpAndSettle timeout

Add pumpNFrames and use that instead. This is based on the recommendation in the docs: https://api.flutter.dev/flutter/flutter_test/WidgetTester/pumpAndSettle.html

* Fix missing balance overview and back button

* Fix wallet & wallet manager integration tests

* Fix maker & taker integration tests

* Fix misc integration tests

* Fix analyse warnings and remove support page test

* Pin chromedriver to the self-hosted runner version

116.0.5845.96 with path /opt/google/chrome/chrome

* Use mock binance repository for unit testing

Using the live Binance endpoints resulted in some variance of the closing price & final calculation that caused the unit tests to fail on occasion.

* Add note about the possibility of 403 error

---------

Co-authored-by: CharlVS <[email protected]>
Co-authored-by: Francois <[email protected]>
* add enable test coins to settings

* test coins hide if toggled off in settings
…uilds (#163)

* Update Flutter to 3.24.3 (stable)

Only web build works with this configuration

* Bump Flutter version in workflows to `3.24.x`

* Remove `desktop_webview_window` dependency

* Switch to in-app webview in popup-window

* Upgrade `file_picker` to 8.1.2 to fix ios&macos build error

win32 v5 removes references to deprecated APIs, which

jonataslaw/get_cli#263

* Upgrade `url_launcher` to 6.3.0 to fix iOS build error

* Skip web defi fetch step if target is iOS

* Bump CI Flutter version to `3.24.x`
* router fix uri query parameters were lost at parse

* router add dexroute parameters

* router dex state notifyListeners for new fields

* router dex process order_type param

* router dex clean params without notifying

* router dex maker process ticker and amount params

* router dex fix typo

* dex TakerSetSellCoin event add setOnlyIfNotSet

* router dex maker consumes only their own params

* router dex allow order_type being maker by default

* router dex taker process from/to currencies

* dex repository waitOrderbookAvailability function

* router dex form wait for orderbooks before process

* router dex taker process from_amount

* router dex code cleanup

* mobile/widget layout taker form dropdown position

* maker form parse error check
* change extension to `.gz` on native platforms

* add single-file zip archive support

credit for zip.dart goes to gpt-4o
* Update Flutter to 3.24.3 (stable)

Only web build works with this configuration

* Bump Flutter version in workflows to `3.24.x`

* Remove `desktop_webview_window` dependency

* Switch to in-app webview in popup-window

* Upgrade `file_picker` to 8.1.2 to fix ios&macos build error

win32 v5 removes references to deprecated APIs, which

jonataslaw/get_cli#263

* Upgrade `url_launcher` to 6.3.0 to fix iOS build error

* Skip web defi fetch step if target is iOS

* Bump CI Flutter version to `3.24.x`

* Fix mobile coin details buttons layout

- Also fix Bitrefill button in preparation for cross-platform fiat onramp in a similar fashion

* Add fullscreen in-app-webview for native platforms

* Close the browser if redirected to web app

This is a failure condition for the `checkout_status_redirect.html` page

* Move payment status events to BLoC

The async onConsole/onMessage callback used by the `flutter_inappwebview` package is incompatible with the previous watcher implementation.

* Migrate bitrefill provider & watcher to package:web

* refactor fullscreen webview to webview dialog

* add fiat onramp html page

fixes issues with reading `onmessage` and `window.console` from an iframe or another window

* apply patch to `web_support.js` to fix web callbacks

from pichillilorenzo/flutter_inappwebview#2058

* migrate remaining fiat & bitrefill html references to package:web

* WIP: add initial fiat onramp bloc implementation

* fix arb merge issue: add arb to currency class

* fix type conversion bugs and add more error logging

add stacktrace to logs when in kDebug mode

* replace onCheckoutComplete callback with BlocListener

* improve form state management

and add default payment methods list for initial user input

* fix cross-platform compilation with conditional imports

package:web and js_interop only work on web, so use conditional exports

* fix cocoapods build warnings

* use url instead of proxy page on native platforms

only web requires the proxy page because of CORS restrictions. onConsole, and onMessage works on native platforms

* fix hive runtime init exception

`Hive.initFlutter` failed on macOS and appears to be a web-specific function that produces an exception on native platforms

* add error parsing for banxa order creation

* localize fiat error and popup messages

* fix status message parsing in wrapper html page

* move getCoinAddress to coins bloc

* update testing and setup docs

add example launch.json and iOS crash logs location
add notes about linux setup

* fix fiat amount injecting decimals

removed unnecessary string `error` field, since the status fields suffice

* fix onramp error on linux & banxa parsing bug

* fix fiat form overlapping issues on mobile

- use autoscrolltext, expand, and align
- fix fiat icon errors when scrolling quickly
- fix webview platform check

* fix flutter analyze warnings

* add fiat onramp form integration test

* bump build transformer package commit

* improve status parsing on native platforms

- parsing errors from escaped json strings on Windows
- re-enable banxa order status watching

* fix coins bloc and Hive init race condition on macos

Runtime updates Hive boxes have to be initialised on native platforms before coins bloc executes, which was not happening consistently across all platforms

* move confirmation prompt behind conditional import

`web` and `js_interop` package imports do not compile on native platforms, so they have to be hidden behind conditional imports to allow for cross-platform support
* kdf show_priv_key api

* display private keys

* private keys QR code dialog

* private keys list title

* private key dialog width

* private key share instead of copy

* Revert "private key share instead of copy"

This reverts commit a623444ea75e4d074419bcc9689585ca819beceb.

* private key clipboard warning
* Fallback to remote images CDN for missing coin icons

* Add coin icon fallback for all references to icons

Add coin icon fallback for other widgets referencing the local image icons. Now all coin icons in the app share the same widget.

* Prevent flicker for fallback coin icons

Prevent flicker for fallback coin icons by caching the status of the existence on the CDN.

* Further coin icon fallback bug fixes
… created (#184)

* fix trading bot tab order

* fix trading bot history onclick event

* show estimate trade volume while creating new order
* add system clock repository with fallback urls

* add directly connected peers rpc as fallback

* improve utc parsing and request exception handling

* revert changes to build_config
* add komodo_defi_sdk to dependencies

update required dependencies, and fix build errors

* WIP: replace mm2 classes with defi sdk

* replace kdf rpc status checks with isSignedIn

The new SDK abstracts away the KDF functionality behind an authentication class, so the previous status checks are not possible, and the isSignedIn is the closest alternative without removing the logic entirely (possibly breaking change)

* bump kdf version

* load coin assets from sdk package

komodo_defi_framework package already downloads the configs and icons, so load them from the external package instead of redownloading and loading the same assets twice

* ci: update paths in validate action

* replace dynamic index.html with static version

the drawbacks of bundling with webpack outweighed the negligible size reduction in the kdf wasm files, so it was dropped in favour of a static index.html in the sdk

* fix failing unit tests

caused by the `rational` and `decimal` package updates

* update docs

remove nodejs, api update script, and add fvm as flutter installation alternative

* fix breaking changes to rpc method return types

sdk returns different types which have to be accounted for, sometimes on a per-rpc basis

* fix validation warnings

* WIP: fix integration tests

temporarily disable suspended assets test. The `coins_config.json` is no longer editable as it is obtained from an external package, so alternative means of invalidating the electrum URLs for an asset are required

* re-enable suspended assets test on chrome

* block electrum urls in chrome for suspended assets test

* update logs location in ui-tests workflow

* fix taker order integration test

* change from sdk to komodo_defi_framework

* fix debug utils & withdraw test

* remove driver start step from ui test workflow

browser driver startup is now handled by integration test runner

* improve driver management & fix `test_withdraw` test

add and refactor integration test utility functions

* add pub get flag

flutter drive runs `flutter pub get` before each test by default, which slows down the current implementation, which runs each set of tests independently

* add profile mode step to ui-tests-on-pr

* add verbose logging to integration tests steps

some errors, like pumpAndSettle timeouts, do not produce useful stacktraces, so adding print statements is necessary unless we run the integration tests in debug mode (not recommended)

* fix cex_prices integration test

* fix theme switching on web

* fix nft and trezor RPC call type errors

type conversions missed during initial migration, but caught by integration tests

* migrate web file_loader to js_interop and package:web

* change file loader to conditional import structure

js_interop causes builds to fail once again

* fix seed file upload & add keep-running flag

safaridriver logs do not include console logs, so we have to keep the browser window open to read console logs in the event of failure

* fix intermittent test failures

* bump sdk version & add debug statements

* increase flutter drive timeout & remove tests.dart

group structure is better suited to the new integration_test format rather than flutter_drive. `await app.main` fails after the second test when in the same group

* fix merge error

* fix validation warnings & flaky dex taker test

* add port option & fix flaky dex ui test steps

* tests: add longer wait after taker/maker confirmation button click

* fix misc integration test errors when switching theme

* fix trading bot order count in tab bar

* fix analyze warnings and increase tab refresh rate

* restore missing error check

throw exception if error response is received from API. Market maker bot was failing to start/stop after this was removed as part of the sdk integration

* fix trading bot & dex order list onClick events

* fix merge issues & trade bot empty list check

list null = empty

* fix best orders and connected peers parsing

v2 uses orderaddress object for address field instead of string
Add coin icon fallback for other widgets referencing the local image icons. Now all coin icons in the app share the same widget.

Fallback to remote images CDN for missing coin icons

Further coin icon fallback bug fixes

Prevent flicker for fallback coin icons

Prevent flicker for fallback coin icons by caching the status of the existence on the CDN.
* fix zero balance issue by fallback to my_balance

* update kdf wasm version

* Remove undefined KDF build configs

* deploy preview on PR to main

* max_taker_vol fallback to my_balance

* ci branches add release/*

* max_taker_vol balance parse rational

---------

Co-authored-by: CharlVS <[email protected]>
Co-authored-by: Francois <[email protected]>
* add support for map in hd balance response

* bump kdf release hash and wasm checksum
* add komodo_defi_sdk to dependencies

update required dependencies, and fix build errors

* WIP: replace mm2 classes with defi sdk

* replace kdf rpc status checks with isSignedIn

The new SDK abstracts away the KDF functionality behind an authentication class, so the previous status checks are not possible, and the isSignedIn is the closest alternative without removing the logic entirely (possibly breaking change)

* bump kdf version

* load coin assets from sdk package

komodo_defi_framework package already downloads the configs and icons, so load them from the external package instead of redownloading and loading the same assets twice

* ci: update paths in validate action

* replace dynamic index.html with static version

the drawbacks of bundling with webpack outweighed the negligible size reduction in the kdf wasm files, so it was dropped in favour of a static index.html in the sdk

* fix failing unit tests

caused by the `rational` and `decimal` package updates

* update docs

remove nodejs, api update script, and add fvm as flutter installation alternative

* fix breaking changes to rpc method return types

sdk returns different types which have to be accounted for, sometimes on a per-rpc basis

* fix validation warnings

* WIP: fix integration tests

temporarily disable suspended assets test. The `coins_config.json` is no longer editable as it is obtained from an external package, so alternative means of invalidating the electrum URLs for an asset are required

* re-enable suspended assets test on chrome

* block electrum urls in chrome for suspended assets test

* update logs location in ui-tests workflow

* fix taker order integration test

* coin addresses bloc init

* coin addresses init list in coin details

* coin addresses separate status for creation

* create addresses cleanup

* change from sdk to komodo_defi_framework

* coin addresses realistic fake address

* coin addresses hide middle part of the address

* fix debug utils & withdraw test

* remove driver start step from ui test workflow

browser driver startup is now handled by integration test runner

* coin addresses improve ui

* coin addresses special exception type

* coin addresses copy button functionality

* coin addresses swap address tag

* coin addresses bloc hide zero balance

* coin addresses styling and hide 0 balance

* improve driver management & fix `test_withdraw` test

add and refactor integration test utility functions

* add pub get flag

flutter drive runs `flutter pub get` before each test by default, which slows down the current implementation, which runs each set of tests independently

* add profile mode step to ui-tests-on-pr

* add verbose logging to integration tests steps

some errors, like pumpAndSettle timeouts, do not produce useful stacktraces, so adding print statements is necessary unless we run the integration tests in debug mode (not recommended)

* coin addresses extract widget to file

* coin addresses QR code

* coin addresses extract widgets

* coin addresses mobile view init

* coin addresses extract widgets

* coin addresses improve mobile view layout

* coin addresses slightly larger swap address text

* coin addresses improve QR dialog

* coin addresses localize texts with existing keys

* coin addresses localize texts

* coin addresses localize texts

* coin addresses polish

* fix cex_prices integration test

* fix theme switching on web

* fix nft and trezor RPC call type errors

type conversions missed during initial migration, but caught by integration tests

* migrate web file_loader to js_interop and package:web

* change file loader to conditional import structure

js_interop causes builds to fail once again

* fix seed file upload & add keep-running flag

safaridriver logs do not include console logs, so we have to keep the browser window open to read console logs in the event of failure

* fix intermittent test failures

* bump sdk version & add debug statements

* increase flutter drive timeout & remove tests.dart

group structure is better suited to the new integration_test format rather than flutter_drive. `await app.main` fails after the second test when in the same group

* fix merge error

* fix validation warnings & flaky dex taker test

* add port option & fix flaky dex ui test steps

* tests: add longer wait after taker/maker confirmation button click

* fix misc integration test errors when switching theme

* fix trading bot order count in tab bar

* fix analyze warnings and increase tab refresh rate

* restore missing error check

throw exception if error response is received from API. Market maker bot was failing to start/stop after this was removed as part of the sdk integration

* fix trading bot & dex order list onClick events

* fix merge issues & trade bot empty list check

list null = empty

* fix best orders and connected peers parsing

v2 uses orderaddress object for address field instead of string

* replace auth methods with KomodoDefiSdk

* fix global variable initialization order and async issues

Migrating away from the global variables in blocs.dart will involve a considerable number of code changes, so leaving as-is for now

* use sdk in current wallet "bloc"

default values used for hasBackup

* move global bloc variables to repositoryprovider

async sdk/kdf initialization does not work with the current global variable structure, so moved the global repositories to repositoryprovider

* revert breaking wallet restore and import changes

* skip orders, and swaps RPCs when not logged in

also bump kdf sdk version

* fix login to existing wallet and remove onlogout deactivate

* catch and log uncaught (or async) errors

* sdk txs disable tests and mock repository

* sdk txs cex market data charts

* sdk txs transactions import change

* fix onlogout balance clearing

throw exceptions with stacktraces

* sdk txs use the new sdk Transaction model

* sdk txs use the new sdk Transaction model

* sdk txs use the new sdk Transaction model

* sdk txs use the new sdk Transaction model

* sdk txs change types import

* tests: use faucet for doc/marty if balance is insufficient

* fix maker form auth state listener

* sdk txs fee coin

* fix validation warnings and remove gha timeout at step

* sdk txs fetch from sdk

* coin details hide addresses if tx is selected

* sdk txs always show transactions if filled

* fix transactions missing one row during loading

* sdk txs getSdkAsset temp helper function

* sdk access added to CoinsRepo

* sdk replace max_maker_vol with sdk

* sdk getSdkPubkeys helper function

* add wallet metadata and disable unsupported features

- add `has_backup` and `WalletType` metadata fields to KdfUser
- disable delete wallet feature
-

* sdk addresses port

* replace current wallet stream with auth bloc

* rename coins "bloc" and move more repos to DI

* use new asset class for trezor coin activation

trezor activation responds to 'UserActionRequired' events, which are not propagated through asset manager

* migrate coins manager from legacy coins bloc

to repository and new coins bloc

* migrate legacy coins bloc to coins repostory

* remove runtime coin updates

`KomodoCoins` fetches coins from github cdn at runtime, so runtime updates are no longer necessary

* remove coin activation rpc models and migrate legacy coins bloc refs

* add activated coins metadata

* refactor: migrate fiat bloc from legacy coins bloc

* migrate remaining legacy coins bloc references to coins repo

* migrate current wallet references to auth bloc

* fix swap page validation issues

* fix market metrics and transaction history loading

* fix trading bot validation errors

coins bloc emits not refreshing the widgets at the bottom of the tree

* fix bridge page missing protocols

* fix coin activation error handling

* fix merge issues

* fix timestamp in unit test transaction generation

* sdk show pubkey addresses for all coins

* sdk addresses active swap address tag

* sdk addresses display balance

* sdk addresses polish balance display

* fix view seed and re-login flow

* fix coin activation via coins manager

activating coins were only displayed on the next balance refresh instead of immediately after activation

* add parent coin to conversion

* sdk addresses hide zero balances checkbox

* sdk addresses reload after create

* sdk remove coin addresses repository

* fix portfolio growth concurrent modification

* fix coin details tab controller error

* sdk getSdkAsset use findAssetsByTicker

* sdk addresses max 3 empty addresses

* sdk addresses split variables

* sdk txs add address

* sdk txs add address mobile

* sdk txs load 200

* fix sporadic activation in coins list

* add legacy wallet migration

* sdk asset getPubkeys

* sdk use assetsFromTicker

* pubspec upgrade

* coin details history -> lastTransactions

* coin details transactions better spacing

* coin details polish transactions section

* upgrade to flutter 3.27.0

* coin details redesign tx history section

* coin details redesign tx history section mobile

* fix new validation warnings from flutter upgrade

* fix trezor login

login does not work in debug mode because of an assert statement in the SDK

* bump flutter version in workflows

* fix macos and ios builds

* decouple balance fetching & coin activation

* sdk addresses use CantCreateNewAddressReason

* coin details remove createAddressAllowed field

* sdk localize CantCreateNewAddressReason texts

* trim unused methods from coin model

* fix coin balances persisting to another wallet login

* fix initial trezor coin activation list

* fix trezor coin add asset page

* call faucet on all addresses

should implement a more robust solution to HD wallet support for faucet

* improve login activated coins metadata storing

* upgrade sdk

---------

Co-authored-by: Francois <[email protected]>
@CharlVS CharlVS changed the title chore(release): v0.9.0 - Unified codebase, HD support, and SDK migration. chore(release): v0.9.0 - HD support, Unified codebase, Custom tokens, and SDK migration Feb 13, 2025
@takenagain
Copy link
Collaborator

@coderabbitai review

Copy link

coderabbitai bot commented Feb 14, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 31

🔭 Outside diff range comments (5)
lib/bloc/bitrefill/bloc/bitrefill_bloc.dart (1)

39-44: ⚠️ Potential issue

Remove empty event handler or document the reason for keeping it.

The _onBitrefillLaunchRequested method is registered as an event handler but contains no implementation. This could lead to silent failures as events will be handled but no action will be taken.

Consider either:

  1. Removing the event handler registration from the constructor if the functionality is no longer needed
  2. Adding documentation explaining why an empty implementation is intentional
class BitrefillBloc extends Bloc<BitrefillEvent, BitrefillState> {
  BitrefillBloc()
      : _bitrefillRepository = BitrefillRepository(),
        super(BitrefillInitial()) {
    on<BitrefillLoadRequested>(_onBitrefillLoadRequested);
-   on<BitrefillLaunchRequested>(_onBitrefillLaunchRequested);
    on<BitrefillPaymentIntentReceived>(_onBitrefillPaymentIntentReceived);
    on<BitrefillPaymentCompleted>(_onBitrefillPaymentCompleted);
  }
lib/bloc/bridge_form/bridge_validator.dart (1)

390-391: ⚠️ Potential issue

Replace deprecated balance property with SDK balance manager.

The balance property is deprecated. Use the balance manager from the SDK instead.

Apply this diff to update the balance checks:

-      if (parentSell.balance == 0.00) return false;
+      if (await _coinsRepo.getBalance(parentSell.abbr) == 0.00) return false;

-    final Coin? buyCoin = _coinsRepo.getCoin(bestOrder.coin);
+    final Coin? buyCoin = _coinsRepo.getCoinFromId(bestOrder.coin);

-      if (parentBuy.balance == 0.00) return false;
+      if (await _coinsRepo.getBalance(parentBuy.abbr) == 0.00) return false;

Note: Since the balance manager is asynchronous, you'll need to update the canRequestPreimage method to be async:

-  bool get canRequestPreimage {
+  Future<bool> get canRequestPreimage async {

Also applies to: 395-396, 403-404

🧰 Tools
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀

[info] 390-390: 'balance' is deprecated and shouldn't be used. Use the balance manager from the SDK.

docs/PROJECT_SETUP.md (1)

18-18: 💡 Verification agent

🧩 Analysis chain

Verify Android Studio version specification.

The Android Studio version "Flamingo | 2024.1.2" seems inconsistent. Flamingo was a 2023 release, while 2024.1.2 appears to be a future version number.


🌐 Web query:

What is the latest version of Android Studio?

💡 Result:

The latest stable version of Android Studio as of February 2025 is Android Studio Ladybug Feature Drop | 2024.2.2[2][5]. This version includes compatibility with Android Gradle Plugin (AGP) versions 3.2-8.8[2] and introduces features like Wear Tiles Animation Preview for debugging tile animations directly in the IDE[2].

To update:

  1. Open Android Studio
  2. Navigate to Help > Check for Updates (or Android Studio > Check for Updates on macOS)
  3. Follow prompts to download and install[1][2]

Key updates in this release:

  • Enhanced Wear OS development tools
  • Improved build performance analysis
  • Live Edit support for Jetpack Compose updates[1][2]
  • Updated JDK and emulator components[1]

For developers targeting Android API level 35 or higher, ensure you're using at least AGP 8.6.0 with Android Studio Koala Feature Drop (2024.1.1) or newer[2]. The next major preview version under development is Android Studio Meerkat (2024.3.1) in beta channels[4][6].

Citations:


Update Android Studio version reference in documentation.

The current entry in docs/PROJECT_SETUP.md at line 18 reads:

- [Android Studio](https://developer.android.com/studio) - Flamingo | 2024.1.2

Given that as of February 2025 the latest stable version is Android Studio Ladybug Feature Drop | 2024.2.2, please update the documentation accordingly to avoid confusion over outdated version names and version numbers.

  • Action: Replace "Flamingo | 2024.1.2" with "Ladybug Feature Drop | 2024.2.2" in the referenced documentation.
ios/Runner.xcodeproj/project.pbxproj (1)

58-58: 🛠️ Refactor suggestion

Remove unused MM2 reference.

The libmm2.a reference should be removed as part of the MM2 cleanup, since the MM2 functionality has been removed from the project.

lib/bloc/app_bloc_root.dart (1)

420-420: ⚠️ Potential issue

Replace deprecated CoinIcon usage.

CoinIcon is deprecated. Use AssetIcon from the SDK's komodo_ui package instead.

-await CoinIcon.precacheCoinIcon(context, abbr)
+await AssetIcon.precacheAssetIcon(context, abbr)
🧰 Tools
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀

[info] 420-420: 'CoinIcon' is deprecated and shouldn't be used. CoinIcon is deprecated. Use AssetIcon from the SDK's komodo_ui package instead.

🧹 Nitpick comments (67)
assets/translations/en.json (1)

569-578: Improve clarity of fiat payment messages.

The fiat payment flow messages could be enhanced for better user experience.

Consider these improvements:

-    "fiatPaymentInProgressMessage": "Congratulations! Your payment has been received and the coins are on the way to your wallet. \n\nYou will receive your coins in 1-60 minutes.",
+    "fiatPaymentInProgressMessage": "Your payment has been received and your coins are being processed. They will be deposited to your wallet within 1-60 minutes.",
docs/INSTALL_FLUTTER.md (1)

54-54: Fix grammatical issues.

There are a few grammatical improvements needed:

  • "logout" should be "log out" (verb form)
  • Remove the comma before "if applicable"
  • Add a comma after "Linux"

Apply these changes:

-You might need to logout and re-login (or source the shell configuration file, if applicable) to make changes apply.
+You might need to log out and log in again (or source the shell configuration file if applicable) to make changes apply.

-On macOS and Linux it should also be possible to confirm it's been added to the PATH correctly by running `which flutter`.
+On macOS and Linux, it should also be possible to confirm it's been added to the PATH correctly by running `which flutter`.

Also applies to: 56-56

🧰 Tools
🪛 LanguageTool

[misspelling] ~54-~54: Did you mean the verb “log out” instead of the noun ‘logout’?
Context: ...er\bin as its value. You might need to logout and re-login (or source the shell confi...

(LOG_IN)


[typographical] ~54-~54: Usually, there’s no comma before “if”.
Context: ... (or source the shell configuration file, if applicable) to make changes apply. On ...

(IF_NO_COMMA)

lib/bloc/market_maker_bot/market_maker_bot/market_maker_bot_bloc.dart (1)

111-124: Consider refactoring duplicated error handling logic.

The error handling code is duplicated between _onOrderUpdateRequested and _onOrderCancelRequested. Consider extracting it into a shared helper method.

+ Future<void> _handleBotError(
+   Object e,
+   Emitter<MarketMakerBotState> emit,
+   String botId,
+ ) async {
+   final isAlreadyStarted =
+       e is RpcException && e.error.errorType == RpcErrorType.alreadyStarted;
+   if (isAlreadyStarted) {
+     emit(const MarketMakerBotState.running());
+     return;
+   }
+
+   final stoppingState =
+       const MarketMakerBotState.stopping().copyWith(error: e.toString());
+   emit(stoppingState);
+   await _botRepository.stop(botId: botId);
+   emit(stoppingState.copyWith(status: MarketMakerBotStatus.stopped));
+ }

  Future<void> _onOrderUpdateRequested(
    MarketMakerBotOrderUpdateRequested event,
    Emitter<MarketMakerBotState> emit,
  ) async {
    // ...
    } catch (e) {
-     final isAlreadyStarted =
-         e is RpcException && e.error.errorType == RpcErrorType.alreadyStarted;
-     if (isAlreadyStarted) {
-       emit(const MarketMakerBotState.running());
-       return;
-     }
-
-     final stoppingState =
-         const MarketMakerBotState.stopping().copyWith(error: e.toString());
-     emit(stoppingState);
-     await _botRepository.stop(botId: event.botId);
-     emit(stoppingState.copyWith(status: MarketMakerBotStatus.stopped));
+     await _handleBotError(e, emit, event.botId);
    }
  }

  Future<void> _onOrderCancelRequested(
    MarketMakerBotOrderCancelRequested event,
    Emitter<MarketMakerBotState> emit,
  ) async {
    // ...
    } catch (e) {
-     final isAlreadyStarted =
-         e is RpcException && e.error.errorType == RpcErrorType.alreadyStarted;
-     if (isAlreadyStarted) {
-       emit(const MarketMakerBotState.running());
-       return;
-     }
-
-     final stoppingState =
-         const MarketMakerBotState.stopping().copyWith(error: e.toString());
-     emit(stoppingState);
-     await _botRepository.stop(botId: event.botId);
-     emit(stoppingState.copyWith(status: MarketMakerBotStatus.stopped));
+     await _handleBotError(e, emit, event.botId);
    }
  }

Also applies to: 149-162

app_theme/lib/src/dark/theme_global_dark.dart (1)

22-22: Address the pending theme implementation TODO

The comment indicates that some light-theme equivalent properties are yet to be implemented.

Would you like me to help identify which light-theme properties are missing and propose implementations?

docs/PROJECT_SETUP.md (1)

51-88: Enhance the troubleshooting documentation.

The new "Possible Issues" section is helpful but could be improved:

  1. Update the example error message date to a current date
  2. Add information about required token scopes

Apply this diff to enhance the documentation:

 Example of the 403 error message (more likely after multiple repeated builds):

 ```bash
-test@test komodo-wallet % flutter build web 
+test@test komodo-wallet % flutter build web
 
 Expected to find fonts for (MaterialIcons, packages/komodo_ui_kit/Custom, packages/cupertino_icons/CupertinoIcons), but found (MaterialIcons, packages/komodo_ui_kit/Custom). This usually means you are referring to font families in an IconData class but not including them in the assets section of your pubspec.yaml, are missing the package that would include
 them, or are missing "uses-material-design: true".
 Font asset "MaterialIcons-Regular.otf" was tree-shaken, reducing it from 1645184 to 13640 bytes (99.2% reduction). Tree-shaking can be disabled by providing the --no-tree-shake-icons flag when building your app.
 Target web_release_bundle failed: Error: User-defined transformation of asset "/Users/test/Repos/komodo/komodo-wallet/app_build/build_config.json" failed.
 Transformer process terminated with non-zero exit code: 1
 Transformer package: komodo_wallet_build_transformer
 Full command: /Users/test/fvm/versions/3.22.3/bin/cache/dart-sdk/bin/dart run komodo_wallet_build_transformer --input=/var/folders/p7/4z261zj174l1hw7q7q7pnc200000gn/T/flutter_tools.2WE4fK/build_config.json-transformOutput0.json --output=/var/folders/p7/4z261zj174l1hw7q7q7pnc200000gn/T/flutter_tools.2WE4fK/build_config.json-transformOutput1.json
 --fetch_defi_api --fetch_coin_assets --copy_platform_assets --artifact_output_package=web_dex --config_output_path=app_build/build_config.json
 stdout:
-SHOUT: 2024-09-30 13:18:58.286118: Error running build steps
+SHOUT: 2025-02-15 13:18:58.286118: Error running build steps
 Exception: Failed to retrieve latest commit hash: master[403]: rate limit exceeded

+When creating a personal access token, ensure it has the following scopes:
+- public_repo - Access public repositories
+- read:packages - Download packages from GitHub Package Registry


</blockquote></details>
<details>
<summary>docs/MANUAL_TESTING_DEBUGGING.md (2)</summary><blockquote>

`130-136`: **Add more details about iOS crash logs.**

The instructions are clear, but consider adding these helpful details:
1. Mention that crash logs are only available after the app has crashed
2. Specify the file extension of crash logs (typically `.ips` or `.crash`)
3. Note how long crash logs are retained


Apply this diff to add more context:

```diff
 ### iOS Crash Logs
 
-Look for entries starting with or containing "Runner" or "Komodo"
+Look for entries starting with or containing "Runner" or "Komodo" with .ips or .crash extensions. Note that crash logs are only available after the app has crashed and are typically retained for up to 28 days.
 
 - On a real device: Go to Settings -> Privacy -> Analytics & Improvements -> Analytics Data
 - In Simulator: ~/Library/Logs/DiagnosticReports/

143-241: Add documentation for launch configurations.

The launch.json configurations lack descriptions explaining their purpose and when to use each one. Consider adding comments to explain:

  1. The differences between debug, profile, and release modes
  2. When to use HTTPS configurations
  3. The purpose of the no-web-security option
  4. Why specific ports were chosen

Add documentation by applying this diff:

 {
     "version": "0.2.0",
     "configurations": [
+        // Debug mode with HTTP - Use for local development
         {
             "name": "KW (debug)",
             "program": "lib/main.dart",
             "request": "launch",
             "type": "dart",
             "args": [
                 "--web-port",
                 "6969"
             ]
         },
+        // Debug mode with HTTPS - Use when testing features requiring secure context
         {
             "name": "KW (debug,https)",
lib/bloc/bridge_form/bridge_repository.dart (1)

13-17: Good use of constructor injection.
Defining dependencies (_mm2Api, _kdfSdk, _coinsRepository) as constructor parameters improves testability and modularity. Consider using abstractions/interfaces to make mocking easier in tests.

lib/bloc/coins_bloc/asset_coin_extension.dart (2)

16-22: Remove redundant null check.

Currently, _getCoinTypeFromProtocol() never returns null, given that the default branch maps to CoinType.utxo. Therefore, the if (type == null) block is effectively unreachable and can be removed to simplify the logic.

15     final CoinType? type = _getCoinTypeFromProtocol(protocol);
-16     if (type == null) {
-17       throw ArgumentError.value(
-18         protocol.subClass,
-19         'protocol type',
-20         'Unsupported protocol type',
-21       );
-22     }

58-60: Address usage of deprecated slp.

As noted by the pipeline, slp is deprecated. Keeping it might be necessary for backward compatibility, but if it’s no longer required, consider removing or replacing all references to slp to avoid confusion.

Please confirm whether slp is still needed or can be safely removed.

Also applies to: 106-107

.github/workflows/validate-code-guidelines.yml (2)

26-26: Remove trailing whitespace

There is unnecessary trailing whitespace on line 26.

-          
+
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 26-26: trailing spaces

(trailing-spaces)


30-31: Consider enabling code formatting check

The code formatting check is currently disabled. Consider creating a follow-up task to enable it after the codebase cleanup.

Would you like me to help create an issue to track the re-enabling of code formatting checks?

app_build/BUILD_CONFIG_README.md (1)

18-21: Consider enhancing the build process documentation.

While the new section provides clear instructions, consider adding:

  1. Example configurations for common scenarios
  2. Troubleshooting guide for common issues
  3. Links to detailed documentation for advanced configurations
.github/workflows/unit-tests-on-pr.yml (1)

24-25: Fix trailing spaces in YAML file.

Remove trailing spaces to maintain consistent formatting.

-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        env: 
+        env:

Also applies to: 33-34

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 25-25: trailing spaces

(trailing-spaces)

.github/actions/generate-assets/action.yml (1)

25-26: Fix trailing spaces in comments.

Remove trailing spaces from comment lines for consistent formatting.

-        # Run flutter build once to download coin icons and config files. 
-        # This step is expected to "fail", since flutter build has to run again 
+        # Run flutter build once to download coin icons and config files.
+        # This step is expected to "fail", since flutter build has to run again
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 25-25: trailing spaces

(trailing-spaces)


[error] 26-26: trailing spaces

(trailing-spaces)

.github/workflows/firebase-hosting-merge.yml (1)

35-35: Fix YAML formatting issues.

Remove trailing spaces and extra blank lines for consistent formatting.

-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-

Also applies to: 58-58

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 35-35: trailing spaces

(trailing-spaces)

.github/workflows/firebase-hosting-pull-request.yml (1)

44-44: Remove trailing whitespace.

There is a trailing whitespace at the end of line 44.

-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 44-44: trailing spaces

(trailing-spaces)

.github/actions/code-coverage/action.yaml (1)

36-46: Remove duplicate error message in coin icon check.

The same error message is printed twice in the coin icon check block. The inner check is redundant since it's identical to the outer check.

 if ! strings build/web/assets/AssetManifest.bin | grep -qi "assets/coin_icons/png/kmd.png"; then
   echo "Error: Coin icon not found in AssetManifest.bin"
   echo "Output of case-invariant grep on build/web/assets/AssetManifest.bin"
   strings build/web/assets/AssetManifest.bin | grep -i "assets/coin_icons/png/kmd.png"
   echo "Listing kmd png files in assets/coin_icons/png"
   ls -R build/web/assets | grep kmd.png
-  if ! strings build/web/assets/AssetManifest.bin | grep -qi "assets/coin_icons/png/kmd.png"; then
-    echo "Error: Coin icon not found in AssetManifest.bin"
-    exit 1
-  fi
+  exit 1
 fi
.github/actions/validate-build/action.yml (1)

13-13: Use more specific path pattern for wasm file check.

The current pattern build/web/kdf/*.wasm might miss nested wasm files. Consider using find command for a more thorough check.

-if [ ! -f build/web/kdf/kdf/bin/*.wasm ]; then
+if [ -z "$(find build/web/kdf -type f -name '*.wasm')" ]; then
docs/INTEGRATION_TESTING.md (1)

45-47: Clarify the automatic chromedriver launch note.

The note about automatic chromedriver launch should specify when manual launch might still be needed.

-NOTE: `chromedriver` is now launched automatically by `run_integration_tests.dart` script, so
-this step is optional if you plan to use Chrome.
+NOTE: `chromedriver` is now launched automatically by `run_integration_tests.dart` script when using Chrome.
+Manual launch is only needed if you want to:
+- Use a different port than the default
+- Enable additional logging options
+- Debug driver-related issues
.github/workflows/ui-tests-on-pr.yml (2)

51-51: Consider using Chrome version matrix instead of hardcoded version.

Using a hardcoded Chrome version might cause issues when new versions are released. Consider using a matrix strategy for Chrome versions.

-          chrome-version: 116.0.5845.96
+          chrome-version: ${{ matrix.chrome-version }}

Then add to the matrix configuration:

matrix:
  chrome-version: ['stable', '116.0.5845.96']  # Test both latest stable and specific version

95-105: Consider adding timeline for re-enabling integration test coverage.

The TODO comment about re-enabling integration test coverage should include a timeline or tracking issue to ensure it's not forgotten.

Would you like me to create an issue to track the re-enabling of integration test coverage with detailed steps for mocking Hive and other storage providers?

docs/BUILD_RUN_APP.md (2)

167-169: Remove duplicate and redundant package dependencies.

The package installation command includes some redundant entries:

  • git is listed twice
  • Basic development tools like curl, unzip, xz-utils, and zip are typically already installed with development environments

Consider simplifying the command:

-sudo apt-get install -y clang cmake git ninja-build pkg-config \
-    libgtk-3-dev liblzma-dev libstdc++-12-dev webkit2gtk-4.1 \
-    curl git unzip xz-utils zip libglu1-mesa
+sudo apt-get install -y clang cmake git ninja-build pkg-config \
+    libgtk-3-dev liblzma-dev libstdc++-12-dev webkit2gtk-4.1 libglu1-mesa

172-172: Enhance documentation clarity for Ubuntu 24.04 requirements.

The instructions would benefit from:

  1. Explaining why these additional dependencies are needed on Ubuntu 24.04
  2. Clarifying when users should consider installing the precautionary xorg-dev package

Consider adding context:

-Users of Ubuntu 24.04 (Noble) or later, might need to install additional dependencies, and add `PKG_CONFIG_PATH` to their bash configuration. If that doesn't work, then try adding it to `/etc/environment` as well.
+Users of Ubuntu 24.04 (Noble) or later need additional X11 development dependencies due to changes in package organization. You'll also need to configure `PKG_CONFIG_PATH` to help the build system locate these dependencies.

-# Install xproto & xorg development libraries (xorg is precautionary, so can be excluded)
+# Install X11 development libraries
 sudo apt-get install -y x11proto-dev xorg-dev libgl1-mesa-dev

Also applies to: 175-176

lib/bloc/cex_market_data/portfolio_growth/portfolio_growth_bloc.dart (4)

75-111: Consider centralizing error handling for improved consistency.

You're handling errors in both .catchError(...) callbacks and the wrapping try/catch. To simplify your code and reduce duplication, consider consolidating these approaches (e.g., by using a single try/catch or well-structured error-handling helpers).


142-148: Slightly unusual removal pattern.

You iterate over event.coins but remove from a copy. This works but may be more readable if you filter instead, for example:

final supportedCoins = event.coins.where((coin) async {
  return await portfolioGrowthRepository.isCoinChartSupported(coin.id, event.fiatCoinId);
}).toList();

193-194: Duplicate filtering could be optimized.

You remove unsupported and inactive coins here and earlier. If repeated calls are necessary, consider a unified filtering function to reduce duplication.


207-207: Log ignored.

Calling log(...).ignore() is intentional here, but ensure important exceptions aren’t silently discarded long-term.

docs/MULTIPLE_FLUTTER_VERSIONS.md (2)

3-12: Enhance FVM installation and usage instructions.

While introducing FVM is a great improvement, consider these enhancements:

  1. Add Windows installation instructions (e.g., via pub global activate fvm).
  2. Use the specific Flutter version instead of stable to match the project requirements.
 curl -fsSL https://fvm.app/install.sh | bash
 
 # Configure the Flutter version to use in the current directory (e.g. ~/komodo-wallet)
-fvm use stable
+fvm use 3.23.4

Also consider adding:

# For Windows (alternative installation)
dart pub global activate fvm

16-16: Improve documentation formatting and grammar.

  1. Fix redundant phrasing:
-### 1. Clone new Flutter instance alongside with the existing one
+### 1. Clone new Flutter instance alongside the existing one
  1. Add language specifications to code blocks:
-```
+```bash
 cd ~
  1. Add missing article:
-### 3. Check if newly installed Flutter version is accessible
+### 3. Check if the newly installed Flutter version is accessible

Also applies to: 18-18, 27-27, 33-33, 41-41

🧰 Tools
🪛 LanguageTool

[style] ~16-~16: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...acOS ### 1. Clone new Flutter instance alongside with the existing one ``` cd ~ git clone ht...

(ALONGSIDE_WITH)

lib/bloc/fiat/base_fiat_provider.dart (3)

10-10: Consider externalizing the domain constant.
Hardcoding 'https://fiat-ramps-proxy.komodo.earth' might reduce flexibility if environment-specific or user-specified configurations become necessary in the future.

-const String domain = 'https://fiat-ramps-proxy.komodo.earth';
+// Example approach: read from an environment variable or config file
+const String domain = String.fromEnvironment(
+  'FIAT_RAMPS_PROXY_DOMAIN',
+  defaultValue: 'https://fiat-ramps-proxy.komodo.earth',
+);

99-99: Use caution when returning raw JSON as an error.
Returning json.decode(response.body) may unintentionally disclose sensitive error response fields. Consider selectively parsing and returning a friendlier error message.

- return Future.error(json.decode(response.body) as Object);
+ final errorData = json.decode(response.body);
+ // Example: surface only the relevant parts of errorData
+ return Future.error('Request failed with status: ${response.statusCode}');

103-103: Rethrow network exceptions more explicitly.
A generic 'Network error: $e' message might hide the underlying cause from upstream exception handlers. Consider using a custom exception class to handle different types of network failures if needed.

lib/bloc/fiat/ramp/ramp_fiat_provider.dart (3)

10-10: Consider externalizing the komodo logo URL.
If future customizations are needed, referencing a config-based value or environment variable may be more flexible.


72-87: Fetching fiat and coin data via _getFiats & _getCoins.
Returning unfiltered JSON is acceptable for internal usage. If building user-facing messages, consider minimal parsing for safety and clarity.


297-303: watchOrderStatus throws UnsupportedError.
Make sure the calling code is aware that Ramp does not provide a standard streaming interface for order status. Document or handle exceptions if attempted.

lib/bloc/fiat/fiat_repository.dart (2)

17-21: Fetching the correct provider based on FiatPaymentMethod.providerId.
This is a neat way to reduce confusion between providers. Log or handle the scenario when providerId is unknown.


127-134: _calculateSpotPriceIncludingFee is straightforward.
This method assumes non-zero amounts. Consider an assertion or log if either coinAmount or fiatAmount is zero to flag potential data anomalies.

lib/bloc/fiat/fiat_onramp_form/fiat_form_bloc.dart (1)

430-434: Provide user feedback for Banxa higher fiat requirement.

The TODO suggests implementing logic to parse or surface the specific “higher fiat amount required” error from Banxa. This can be valuable to guide users toward successful transactions.

I can help incorporate a logic to interpret Banxa’s text-based errors for clearer user messages. Would you like me to open a new issue or draft a snippet?

lib/bloc/fiat/models/fiat_transaction_fee.dart (2)

3-24: Add validation and documentation for FiatTransactionFee class.

The class needs documentation explaining its purpose and validation for the fees list.

+/// Represents the fee structure for a fiat transaction.
+/// Contains a list of individual fee details that make up the total transaction cost.
 class FiatTransactionFee extends Equatable {
   const FiatTransactionFee({required this.fees});
 
   factory FiatTransactionFee.fromJson(Map<String, dynamic> json) {
     final feesJson = json['fees'] as List<dynamic>? ?? [];
+    if (feesJson.isEmpty) {
+      throw FormatException('Fees list cannot be empty');
+    }
     final List<FeeDetail> feesList = feesJson
         .map((e) => FeeDetail.fromJson(e as Map<String, dynamic>))
         .toList();
 
     return FiatTransactionFee(fees: feesList);
   }
+  /// List of individual fee components for the transaction
   final List<FeeDetail> fees;

26-42: Add validation and documentation for FeeDetail class.

The class should validate the amount and include documentation.

+/// Represents an individual fee component with its amount.
 class FeeDetail extends Equatable {
   const FeeDetail({required this.amount});
 
   factory FeeDetail.fromJson(Map<String, dynamic> json) {
+    final amount = (json['amount'] ?? 0.0) as double;
+    if (amount < 0) {
+      throw FormatException('Fee amount cannot be negative');
+    }
-    return FeeDetail(amount: (json['amount'] ?? 0.0) as double);
+    return FeeDetail(amount: amount);
   }
+  /// The monetary value of the fee
   final double amount;
lib/bloc/fiat/fiat_order_status.dart (1)

25-53: Enhance error handling and add toString method.

The status parsing could be more robust and include a toString implementation for consistency.

   static FiatOrderStatus fromString(String status) {
+    final normalizedStatus = status.trim().toLowerCase();
     switch (status) {
       case 'complete':
         return FiatOrderStatus.success;
 
       case 'cancelled':
       case 'declined':
       case 'expired':
       case 'refunded':
+        // TODO: Consider differentiating between these failure types
         return FiatOrderStatus.failed;
 
       case 'extraVerification':
       case 'pendingPayment':
       case 'waitingPayment':
         return FiatOrderStatus.pending;
 
       case 'paymentReceived':
       case 'inProgress':
       case 'coinTransferred':
         return FiatOrderStatus.inProgress;
 
       default:
         throw Exception('Unknown status: $status');
     }
   }
+
+  @override
+  String toString() {
+    return name;
+  }
lib/bloc/fiat/models/i_currency.dart (1)

4-22: Add comprehensive documentation for ICurrency interface.

The base class needs better documentation for its purpose and contract.

-/// Base class for all currencies
+/// Abstract base class representing a currency in the system.
+/// 
+/// This class serves as a contract for both fiat currencies (like USD, EUR)
+/// and cryptocurrencies (like BTC, ETH). It provides basic properties and
+/// methods that all currency implementations must support.
 abstract class ICurrency {
   const ICurrency(this.symbol, this.name);
 
+  /// The symbol/ticker of the currency (e.g., "BTC", "USD")
   final String symbol;
+
+  /// The full name of the currency (e.g., "Bitcoin", "US Dollar")
   final String name;
 
   /// Returns true if the currency is a fiat currency (e.g. USD)
   bool get isFiat;
 
   /// Returns true if the currency is a crypto currency (e.g. BTC)
   bool get isCrypto;
 
   /// Returns the abbreviation of the currency (e.g. BTC, USD).
+  /// This may differ from the symbol in some cases, particularly for
+  /// cryptocurrencies with chain-specific variations.
   String getAbbr() => symbol;
 
   /// Returns the full name of the currency (e.g. Bitcoin).
+  /// This may include additional context such as the chain type for
+  /// cryptocurrencies.
   String formatNameShort() => name;
 }
lib/bloc/bitrefill/models/embedded_bitrefill_url.dart (1)

60-60: Use type-safe boolean serialization.

Instead of string literals 'true'/'false', consider using Dart's built-in toString() on boolean values for consistency and type safety.

Apply this diff:

-      'show_payment_info': showPaymentInfo ? 'true' : 'false',
+      'show_payment_info': showPaymentInfo.toString(),
lib/bloc/fiat/models/fiat_payment_method.dart (1)

119-168: Extract hardcoded values as constants.

The default payment methods contain hardcoded values that should be constants for better maintainability.

Consider extracting values like provider IDs, asset paths, and default currencies as constants:

const _kRampProviderId = 'Ramp';
const _kBanxaProviderId = 'Banxa';
const _kRampIconPath = 'assets/fiat/providers/ramp_icon.svg';
const _kBanxaIconPath = 'assets/fiat/providers/banxa_icon.svg';
const _kDefaultFiatCode = 'USD';
const _kDefaultCoinCode = 'BTC';

Then use these constants in the defaultFiatPaymentMethods list.

lib/bloc/fiat/models/fiat_buy_order_info.dart (1)

59-84: Consider adding validation for required fields.

While the fromJson factory handles null values well, it might be worth adding validation for critical fields that shouldn't be empty strings.

 factory FiatBuyOrderInfo.fromJson(Map<String, dynamic> json) {
   Map<String, dynamic> data = json;
   if (json['data'] != null) {
     final orderData = json['data'] as Map<String, dynamic>? ?? {};
     data = orderData['order'] as Map<String, dynamic>? ?? {};
   }

+  final id = data['id'] as String? ?? '';
+  if (id.isEmpty) {
+    throw FormatException('Order ID is required');
+  }
+
   return FiatBuyOrderInfo(
-    id: data['id'] as String? ?? '',
+    id: id,
     accountId: data['account_id'] as String? ?? '',
     accountReference: data['account_reference'] as String? ?? '',
lib/bloc/fiat/fiat_onramp_form/fiat_form_state.dart (1)

88-104: Consider adding validation for transaction limits.

The computed properties for transaction limits could benefit from additional validation to ensure the min amount is not greater than the max amount.

 double? get minFiatAmount => transactionLimit?.min;
 double? get maxFiatAmount => transactionLimit?.max;
+
+bool get hasValidTransactionLimits {
+  final min = minFiatAmount;
+  final max = maxFiatAmount;
+  return min != null && max != null && min <= max;
+}
+
 bool get isLoadingCurrencies => fiatList.length < 2 || coinList.length < 2;
 bool get isLoading => isLoadingCurrencies || status == FiatFormStatus.loading;
 bool get canSubmit =>
     !isLoading &&
     accountReference.isNotEmpty &&
     status != FiatFormStatus.failure &&
     !fiatOrderStatus.isSubmitting &&
+    hasValidTransactionLimits &&
     isValid;
lib/bloc/fiat/banxa_fiat_provider.dart (2)

136-140: Consider using a more specific error type.

The error handling could be improved by using a custom error type instead of a generic string message.

+class BanxaOrderFetchError implements Exception {
+  final String orderId;
+  final dynamic error;
+  BanxaOrderFetchError(this.orderId, this.error);
+  @override
+  String toString() => 'Failed to fetch order $orderId: $error';
+}
+
 final response = await _getOrder(orderId)
-    .catchError((e) => Future<void>.error('Error fetching order: $e'));
+    .catchError((e) => Future<void>.error(BanxaOrderFetchError(orderId, e)));

299-303: Consider adding structured logging.

The current logging could be improved by using structured logging with consistent fields.

-    await log('Fiat buy coin order payload:');
-    await log(jsonEncode(payload));
+    await log(
+      'Creating fiat buy coin order',
+      data: {
+        'event': 'fiat_buy_coin_order',
+        'payload': payload,
+      },
+    );
     final response = await _createOrder(payload);
-    await log('Fiat buy coin order response:');
-    await log(jsonEncode(response));
+    await log(
+      'Fiat buy coin order created',
+      data: {
+        'event': 'fiat_buy_coin_order_response',
+        'response': response,
+      },
+    );
assets/web_pages/fiat_widget.html (1)

28-29: Consider adding additional sandbox restrictions.

While the current sandbox attributes are good, consider restricting more features for better security.

-    <iframe id="fiat-onramp-iframe" sandbox="allow-same-origin allow-popups allow-scripts allow-forms" src="">
+    <iframe id="fiat-onramp-iframe" sandbox="allow-same-origin allow-popups allow-scripts allow-forms allow-popups-to-escape-sandbox" src="">
lib/bloc/dex_tab_bar/dex_tab_bar_bloc.dart (1)

53-76: _onStartListening sets up concurrent streams.
Implementation is correct, though consider adding error handling for _tradingBotOrdersSubscription in case getTradePairs() throws.

lib/bloc/coins_manager/coins_manager_bloc.dart (3)

78-89: _onCoinsListReset event
Good use of resetting to an initial state before fetching. Consider wrapping the fetch in error handling to avoid partial states if fetching fails.


105-106: Synchronous coin switching
activateCoinsSync and deactivateCoinsSync appear to be synchronous calls. If these are time-consuming or blocking operations, consider asynchronous versions to avoid blocking the Bloc’s event loop.


214-215: Returning wallet coins
When action == CoinsManagerAction.remove, the code fetches all wallet coins. Ensure useless calls are avoided if you already have them in memory.

Also applies to: 217-217

lib/bloc/auth_bloc/auth_bloc.dart (3)

90-97: Error handling in _onLogIn
Catching exceptions logs an error and emits noLogin. Consider whether retries or user feedback might be needed for a better UX.


147-155: Registration error handling
Logging the error details is good. As a further improvement, consider specialized error states to inform the UI.


210-217: Catching errors in _onRestore
Consistent approach with _onLogIn and _onRegister. Errors produce noLogin. Consider user-facing feedback to highlight restore issues.

lib/bloc/coins_bloc/coins_bloc.dart (1)

158-185: Ensure timers are fully canceled
You correctly cancel _updateBalancesTimer and _reActivateSuspendedTimer in _onCoinsBalanceMonitoringStopped. Double-check that there are no other code paths that might leave these timers running (e.g., if an error or early return is triggered), to avoid resource leaks and concurrency issues.

lib/bloc/bridge_form/bridge_bloc.dart (1)

582-582: Avoid deprecated getCoin lookups
Line 582 calls getCoin, which is also deprecated. Use the integrated SDK utilities (e.g., findAssetsByTicker or getCoinFromId) to fetch coin details, ensuring future-proof functionality.

🧰 Tools
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀

[info] 582-582: 'getCoin' is deprecated and shouldn't be used. Use KomodoDefiSdk assets or getCoinFromId instead.

lib/bloc/coins_bloc/coins_state.dart (1)

20-29: Consider adding documentation for edge cases.

The getUsdPriceByAmount method has good null checks, but would benefit from documentation explaining the return value in edge cases.

Add documentation:

  double? getUsdPriceByAmount(String amount, String coinAbbr) {
+   /// Returns null if:
+   /// - The coin is not found in the coins map
+   /// - The coin's USD price is null
+   /// - The amount cannot be parsed as a double
    final Coin? coin = coins[coinAbbr];
lib/bloc/coin_addresses/bloc/coin_addresses_bloc.dart (2)

7-16: Add class-level documentation.

While the implementation is solid, adding class-level documentation would improve maintainability by explaining the bloc's purpose and responsibilities.

Add documentation above the class:

+/// Manages the state and logic for coin addresses, including creation,
+/// loading, and visibility preferences.
+///
+/// Uses [KomodoDefiSdk] for address-related operations and maintains
+/// the state of addresses for a specific asset.
 class CoinAddressesBloc extends Bloc<CoinAddressesEvent, CoinAddressesState> {

73-78: Add method documentation for clarity.

While the method is simple, documenting its purpose would improve code readability.

Add documentation above the method:

+/// Updates the state to reflect user preference for hiding zero balance addresses.
+///
+/// [event.hideZeroBalance] determines whether addresses with zero balance should be hidden.
 void _onUpdateHideZeroBalance(
lib/bloc/coin_addresses/bloc/coin_addresses_state.dart (2)

23-44: Consider using nullable types instead of nullable functions for optional parameters.

The copyWith method uses function types for optional parameters, which adds unnecessary complexity.

Apply this diff to simplify the method:

   CoinAddressesState copyWith({
-    FormStatus Function()? status,
-    FormStatus Function()? createAddressStatus,
-    String? Function()? errorMessage,
-    List<PubkeyInfo> Function()? addresses,
-    bool Function()? hideZeroBalance,
-    Set<CantCreateNewAddressReason>? Function()? cantCreateNewAddressReasons,
+    FormStatus? status,
+    FormStatus? createAddressStatus,
+    String? errorMessage,
+    List<PubkeyInfo>? addresses,
+    bool? hideZeroBalance,
+    Set<CantCreateNewAddressReason>? cantCreateNewAddressReasons,
   }) {
     return CoinAddressesState(
-      status: status == null ? this.status : status(),
-      createAddressStatus: createAddressStatus == null
-          ? this.createAddressStatus
-          : createAddressStatus(),
-      errorMessage: errorMessage == null ? this.errorMessage : errorMessage(),
-      addresses: addresses == null ? this.addresses : addresses(),
-      hideZeroBalance:
-          hideZeroBalance == null ? this.hideZeroBalance : hideZeroBalance(),
-      cantCreateNewAddressReasons: cantCreateNewAddressReasons == null
-          ? this.cantCreateNewAddressReasons
-          : cantCreateNewAddressReasons(),
+      status: status ?? this.status,
+      createAddressStatus: createAddressStatus ?? this.createAddressStatus,
+      errorMessage: errorMessage ?? this.errorMessage,
+      addresses: addresses ?? this.addresses,
+      hideZeroBalance: hideZeroBalance ?? this.hideZeroBalance,
+      cantCreateNewAddressReasons: cantCreateNewAddressReasons ?? this.cantCreateNewAddressReasons,
     );
   }

46-66: Apply the same simplification to the resetWith method.

The resetWith method also uses function types for optional parameters.

Apply this diff to simplify the method:

   CoinAddressesState resetWith({
-    FormStatus Function()? status,
-    FormStatus Function()? createAddressStatus,
-    String? Function()? errorMessage,
-    List<PubkeyInfo> Function()? addresses,
-    bool Function()? hideZeroBalance,
-    Set<CantCreateNewAddressReason>? Function()? cantCreateNewAddressReasons,
+    FormStatus? status,
+    FormStatus? createAddressStatus,
+    String? errorMessage,
+    List<PubkeyInfo>? addresses,
+    bool? hideZeroBalance,
+    Set<CantCreateNewAddressReason>? cantCreateNewAddressReasons,
   }) {
     return CoinAddressesState(
-      status: status == null ? FormStatus.initial : status(),
-      createAddressStatus: createAddressStatus == null
-          ? FormStatus.initial
-          : createAddressStatus(),
-      errorMessage: errorMessage == null ? null : errorMessage(),
-      addresses: addresses == null ? [] : addresses(),
-      hideZeroBalance: hideZeroBalance == null ? false : hideZeroBalance(),
-      cantCreateNewAddressReasons: cantCreateNewAddressReasons == null
-          ? null
-          : cantCreateNewAddressReasons(),
+      status: status ?? FormStatus.initial,
+      createAddressStatus: createAddressStatus ?? FormStatus.initial,
+      errorMessage: errorMessage,
+      addresses: addresses ?? [],
+      hideZeroBalance: hideZeroBalance ?? false,
+      cantCreateNewAddressReasons: cantCreateNewAddressReasons,
     );
   }
lib/bloc/cex_market_data/profit_loss/profit_loss_bloc.dart (1)

152-161: Verify the coin filtering changes.

The coin filtering logic has been updated to use a synchronous loop instead of removeWhereAsync. This change could affect performance for large lists of coins.

Consider using Future.forEach for better performance:

-    for (final coin in event.coins) {
-      final isCoinSupported = await _profitLossRepository.isCoinChartSupported(
-        coin.id,
-        event.fiatCoinId,
-        allowInactiveCoins: allowInactiveCoins,
-      );
-      if (coin.isTestCoin || !isCoinSupported) {
-        coins.remove(coin);
-      }
-    }
+    await Future.forEach(event.coins, (coin) async {
+      final isCoinSupported = await _profitLossRepository.isCoinChartSupported(
+        coin.id,
+        event.fiatCoinId,
+        allowInactiveCoins: allowInactiveCoins,
+      );
+      if (coin.isTestCoin || !isCoinSupported) {
+        coins.remove(coin);
+      }
+    });
lib/bloc/market_maker_bot/market_maker_bot/market_maker_bot_repository.dart (1)

193-193: Consider logging level adjustment instead of ignoring logs.

Using .ignore() on log statements might hide important error information. Consider adjusting the logging level instead.

-log('Market maker bot already started', isError: true).ignore();
+log('Market maker bot already started', level: LogLevel.debug);

Also applies to: 198-198, 208-208

lib/bloc/app_bloc_root.dart (1)

120-129: Remove commented-out code.

The commented-out code for MockTransactionHistoryRepo should be removed since it's no longer needed.

-// TODO: SDK Port needed, not sure about this part
-final transactionsRepo = /*performanceMode != null
-    ? MockTransactionHistoryRepo(
-        api: mm2Api,
-        client: Client(),
-        performanceMode: performanceMode,
-        demoDataGenerator: DemoDataCache.withDefaults(),
-      )
-    : */
+final transactionsRepo =
    SdkTransactionHistoryRepository(sdk: komodoDefiSdk);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 074f82e and 3b24f4b.

⛔ Files ignored due to path filters (3)
  • app_theme/pubspec.lock is excluded by !**/*.lock
  • ios/Podfile.lock is excluded by !**/*.lock
  • lib/generated/codegen_loader.g.dart is excluded by !**/generated/**
📒 Files selected for processing (107)
  • .github/actions/code-coverage/action.yaml (1 hunks)
  • .github/actions/flutter-deps/action.yml (1 hunks)
  • .github/actions/generate-assets/action.yml (1 hunks)
  • .github/actions/validate-build/action.yml (1 hunks)
  • .github/workflows/firebase-hosting-merge.yml (3 hunks)
  • .github/workflows/firebase-hosting-pull-request.yml (2 hunks)
  • .github/workflows/ui-tests-on-pr.yml (1 hunks)
  • .github/workflows/unit-tests-on-pr.yml (1 hunks)
  • .github/workflows/validate-code-guidelines.yml (1 hunks)
  • .gitignore (3 hunks)
  • README.md (0 hunks)
  • app_build/.gitignore (0 hunks)
  • app_build/BUILD_CONFIG_README.md (1 hunks)
  • app_build/build_config.json (1 hunks)
  • app_theme/lib/src/dark/theme_global_dark.dart (6 hunks)
  • app_theme/lib/src/light/theme_global_light.dart (6 hunks)
  • assets/packages/flutter_inappwebview_web/assets/web/web_support.js (1 hunks)
  • assets/translations/en.json (8 hunks)
  • assets/web_pages/fiat_widget.html (1 hunks)
  • docs/BUILD_CONFIG.md (1 hunks)
  • docs/BUILD_RUN_APP.md (1 hunks)
  • docs/INSTALL_FLUTTER.md (2 hunks)
  • docs/INTEGRATION_TESTING.md (4 hunks)
  • docs/MANUAL_TESTING_DEBUGGING.md (3 hunks)
  • docs/MULTIPLE_FLUTTER_VERSIONS.md (1 hunks)
  • docs/PROJECT_SETUP.md (2 hunks)
  • docs/UPDATE_API_MODULE.md (0 hunks)
  • ios/Flutter/AppFrameworkInfo.plist (1 hunks)
  • ios/Flutter/Release.xcconfig (1 hunks)
  • ios/Podfile (1 hunks)
  • ios/Runner.xcodeproj/project.pbxproj (7 hunks)
  • ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (1 hunks)
  • ios/Runner/AppDelegate.swift (1 hunks)
  • ios/Runner/Runner-Bridging-Header.h (0 hunks)
  • ios/Runner/mm2.h (0 hunks)
  • ios/Runner/mm2.m (0 hunks)
  • lib/app_config/app_config.dart (2 hunks)
  • lib/app_config/coins_config_parser.dart (0 hunks)
  • lib/bloc/app_bloc_root.dart (11 hunks)
  • lib/bloc/assets_overview/bloc/asset_overview_bloc.dart (2 hunks)
  • lib/bloc/assets_overview/investment_repository.dart (1 hunks)
  • lib/bloc/auth_bloc/auth_bloc.dart (1 hunks)
  • lib/bloc/auth_bloc/auth_bloc_event.dart (1 hunks)
  • lib/bloc/auth_bloc/auth_bloc_state.dart (1 hunks)
  • lib/bloc/auth_bloc/auth_repository.dart (0 hunks)
  • lib/bloc/bitrefill/bloc/bitrefill_bloc.dart (1 hunks)
  • lib/bloc/bitrefill/data/bitrefill_provider.dart (2 hunks)
  • lib/bloc/bitrefill/data/bitrefill_purchase_watcher.dart (0 hunks)
  • lib/bloc/bitrefill/data/bitrefill_repository.dart (0 hunks)
  • lib/bloc/bitrefill/models/embedded_bitrefill_url.dart (2 hunks)
  • lib/bloc/bridge_form/bridge_bloc.dart (6 hunks)
  • lib/bloc/bridge_form/bridge_repository.dart (7 hunks)
  • lib/bloc/bridge_form/bridge_validator.dart (4 hunks)
  • lib/bloc/cex_market_data/charts.dart (4 hunks)
  • lib/bloc/cex_market_data/mockup/generate_demo_data.dart (6 hunks)
  • lib/bloc/cex_market_data/mockup/generator.dart (1 hunks)
  • lib/bloc/cex_market_data/mockup/mock_portfolio_growth_repository.dart (3 hunks)
  • lib/bloc/cex_market_data/mockup/mock_transaction_history_repository.dart (2 hunks)
  • lib/bloc/cex_market_data/portfolio_growth/portfolio_growth_bloc.dart (7 hunks)
  • lib/bloc/cex_market_data/portfolio_growth/portfolio_growth_repository.dart (12 hunks)
  • lib/bloc/cex_market_data/price_chart/models/price_chart_interval.dart (0 hunks)
  • lib/bloc/cex_market_data/price_chart/models/time_period.dart (0 hunks)
  • lib/bloc/cex_market_data/price_chart/price_chart_bloc.dart (2 hunks)
  • lib/bloc/cex_market_data/profit_loss/demo_profit_loss_repository.dart (3 hunks)
  • lib/bloc/cex_market_data/profit_loss/extensions/profit_loss_transaction_extension.dart (1 hunks)
  • lib/bloc/cex_market_data/profit_loss/models/price_stamped_transaction.dart (2 hunks)
  • lib/bloc/cex_market_data/profit_loss/models/profit_loss.dart (2 hunks)
  • lib/bloc/cex_market_data/profit_loss/profit_loss_bloc.dart (3 hunks)
  • lib/bloc/cex_market_data/profit_loss/profit_loss_calculator.dart (10 hunks)
  • lib/bloc/cex_market_data/profit_loss/profit_loss_repository.dart (9 hunks)
  • lib/bloc/coin_addresses/bloc/coin_addresses_bloc.dart (1 hunks)
  • lib/bloc/coin_addresses/bloc/coin_addresses_event.dart (1 hunks)
  • lib/bloc/coin_addresses/bloc/coin_addresses_state.dart (1 hunks)
  • lib/bloc/coins_bloc/asset_coin_extension.dart (1 hunks)
  • lib/bloc/coins_bloc/coins_bloc.dart (1 hunks)
  • lib/bloc/coins_bloc/coins_event.dart (1 hunks)
  • lib/bloc/coins_bloc/coins_repo.dart (1 hunks)
  • lib/bloc/coins_bloc/coins_state.dart (1 hunks)
  • lib/bloc/coins_manager/coins_manager_bloc.dart (8 hunks)
  • lib/bloc/coins_manager/coins_manager_event.dart (1 hunks)
  • lib/bloc/coins_manager/coins_manager_state.dart (2 hunks)
  • lib/bloc/dex_repository.dart (7 hunks)
  • lib/bloc/dex_tab_bar/dex_tab_bar_bloc.dart (2 hunks)
  • lib/bloc/dex_tab_bar/dex_tab_bar_event.dart (1 hunks)
  • lib/bloc/dex_tab_bar/dex_tab_bar_state.dart (1 hunks)
  • lib/bloc/fiat/banxa_fiat_provider.dart (11 hunks)
  • lib/bloc/fiat/base_fiat_provider.dart (5 hunks)
  • lib/bloc/fiat/fiat_onramp_form/fiat_form_bloc.dart (1 hunks)
  • lib/bloc/fiat/fiat_onramp_form/fiat_form_event.dart (1 hunks)
  • lib/bloc/fiat/fiat_onramp_form/fiat_form_state.dart (1 hunks)
  • lib/bloc/fiat/fiat_order_status.dart (2 hunks)
  • lib/bloc/fiat/fiat_repository.dart (10 hunks)
  • lib/bloc/fiat/models/fiat_buy_order_error.dart (1 hunks)
  • lib/bloc/fiat/models/fiat_buy_order_info.dart (1 hunks)
  • lib/bloc/fiat/models/fiat_mode.dart (1 hunks)
  • lib/bloc/fiat/models/fiat_order.dart (1 hunks)
  • lib/bloc/fiat/models/fiat_payment_method.dart (1 hunks)
  • lib/bloc/fiat/models/fiat_price_info.dart (1 hunks)
  • lib/bloc/fiat/models/fiat_transaction_fee.dart (1 hunks)
  • lib/bloc/fiat/models/fiat_transaction_limit.dart (1 hunks)
  • lib/bloc/fiat/models/i_currency.dart (1 hunks)
  • lib/bloc/fiat/models/models.dart (1 hunks)
  • lib/bloc/fiat/ramp/ramp_fiat_provider.dart (12 hunks)
  • lib/bloc/fiat/ramp/ramp_purchase_watcher.dart (0 hunks)
  • lib/bloc/market_maker_bot/market_maker_bot/market_maker_bot_bloc.dart (7 hunks)
  • lib/bloc/market_maker_bot/market_maker_bot/market_maker_bot_repository.dart (11 hunks)
  • lib/bloc/market_maker_bot/market_maker_order_list/market_maker_bot_order_list_repository.dart (3 hunks)
⛔ Files not processed due to max files limit (69)
  • lib/bloc/market_maker_bot/market_maker_order_list/market_maker_order_list_bloc.dart
  • lib/bloc/market_maker_bot/market_maker_order_list/trade_pair.dart
  • lib/bloc/market_maker_bot/market_maker_trade_form/market_maker_trade_form_bloc.dart
  • lib/bloc/market_maker_bot/market_maker_trade_form/market_maker_trade_form_state.dart
  • lib/bloc/nft_receive/bloc/nft_receive_bloc.dart
  • lib/bloc/nft_transactions/bloc/nft_transactions_bloc.dart
  • lib/bloc/nft_transactions/nft_txn_repository.dart
  • lib/bloc/nft_withdraw/nft_withdraw_bloc.dart
  • lib/bloc/nft_withdraw/nft_withdraw_repo.dart
  • lib/bloc/nfts/nft_main_bloc.dart
  • lib/bloc/nfts/nft_main_repo.dart
  • lib/bloc/runtime_coin_updates/coin_config_bloc.dart
  • lib/bloc/runtime_coin_updates/coin_config_event.dart
  • lib/bloc/runtime_coin_updates/coin_config_state.dart
  • lib/bloc/runtime_coin_updates/runtime_update_config_provider.dart
  • lib/bloc/security_settings/security_settings_bloc.dart
  • lib/bloc/security_settings/security_settings_state.dart
  • lib/bloc/settings/settings_bloc.dart
  • lib/bloc/settings/settings_event.dart
  • lib/bloc/settings/settings_state.dart
  • lib/bloc/system_health/system_clock_repository.dart
  • lib/bloc/system_health/system_health_bloc.dart
  • lib/bloc/taker_form/taker_bloc.dart
  • lib/bloc/taker_form/taker_validator.dart
  • lib/bloc/transaction_history/transaction_history_bloc.dart
  • lib/bloc/transaction_history/transaction_history_event.dart
  • lib/bloc/transaction_history/transaction_history_repo.dart
  • lib/bloc/transaction_history/transaction_history_state.dart
  • lib/bloc/trezor_bloc/trezor_repo.dart
  • lib/bloc/trezor_connection_bloc/trezor_connection_bloc.dart
  • lib/bloc/trezor_init_bloc/trezor_init_bloc.dart
  • lib/bloc/trezor_init_bloc/trezor_init_event.dart
  • lib/bloc/trezor_init_bloc/trezor_init_state.dart
  • lib/bloc/wallets_bloc/wallets_repo.dart
  • lib/bloc/withdraw_form/withdraw_form_bloc.dart
  • lib/bloc/withdraw_form/withdraw_form_event.dart
  • lib/bloc/withdraw_form/withdraw_form_state.dart
  • lib/bloc/withdraw_form/withdraw_form_step.dart
  • lib/blocs/blocs.dart
  • lib/blocs/coins_bloc.dart
  • lib/blocs/current_wallet_bloc.dart
  • lib/blocs/dropdown_dismiss_bloc.dart
  • lib/blocs/kmd_rewards_bloc.dart
  • lib/blocs/maker_form_bloc.dart
  • lib/blocs/startup_bloc.dart
  • lib/blocs/trading_entities_bloc.dart
  • lib/blocs/trezor_coins_bloc.dart
  • lib/blocs/wallets_bloc.dart
  • lib/blocs/wallets_repository.dart
  • lib/main.dart
  • lib/mm2/mm2.dart
  • lib/mm2/mm2_android.dart
  • lib/mm2/mm2_api/mm2_api.dart
  • lib/mm2/mm2_api/mm2_api_nft.dart
  • lib/mm2/mm2_api/mm2_api_trezor.dart
  • lib/mm2/mm2_api/rpc/best_orders/best_orders.dart
  • lib/mm2/mm2_api/rpc/directly_connected_peers/get_directly_connected_peers.dart
  • lib/mm2/mm2_api/rpc/directly_connected_peers/get_directly_connected_peers_response.dart
  • lib/mm2/mm2_api/rpc/electrum/electrum_req.dart
  • lib/mm2/mm2_api/rpc/enable/enable_req.dart
  • lib/mm2/mm2_api/rpc/get_enabled_coins/get_enabled_coins_req.dart
  • lib/mm2/mm2_api/rpc/max_taker_vol/max_taker_vol_response.dart
  • lib/mm2/mm2_api/rpc/my_orders/my_orders_response.dart
  • lib/mm2/mm2_api/rpc/my_recent_swaps/my_recent_swaps_response.dart
  • lib/mm2/mm2_api/rpc/orderbook_depth/orderbook_depth_response.dart
  • lib/mm2/mm2_api/rpc/rpc_error.dart
  • lib/mm2/mm2_api/rpc/trezor/enable_utxo/trezor_enable_utxo/trezor_enable_utxo_request.dart
  • lib/mm2/mm2_api/rpc/withdraw/withdraw_errors.dart
  • lib/mm2/mm2_ios.dart
💤 Files with no reviewable changes (13)
  • lib/bloc/cex_market_data/price_chart/models/price_chart_interval.dart
  • ios/Runner/Runner-Bridging-Header.h
  • lib/bloc/cex_market_data/price_chart/models/time_period.dart
  • app_build/.gitignore
  • lib/bloc/bitrefill/data/bitrefill_purchase_watcher.dart
  • lib/bloc/auth_bloc/auth_repository.dart
  • lib/bloc/bitrefill/data/bitrefill_repository.dart
  • README.md
  • docs/UPDATE_API_MODULE.md
  • ios/Runner/mm2.m
  • lib/bloc/fiat/ramp/ramp_purchase_watcher.dart
  • lib/app_config/coins_config_parser.dart
  • ios/Runner/mm2.h
✅ Files skipped from review due to trivial changes (5)
  • lib/bloc/fiat/models/fiat_order.dart
  • ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  • ios/Flutter/Release.xcconfig
  • docs/BUILD_CONFIG.md
  • lib/bloc/fiat/models/models.dart
🧰 Additional context used
🪛 LanguageTool
docs/INSTALL_FLUTTER.md

[misspelling] ~54-~54: Did you mean the verb “log out” instead of the noun ‘logout’?
Context: ...er\bin as its value. You might need to logout and re-login (or source the shell confi...

(LOG_IN)


[typographical] ~54-~54: Usually, there’s no comma before “if”.
Context: ... (or source the shell configuration file, if applicable) to make changes apply. On ...

(IF_NO_COMMA)


[uncategorized] ~56-~56: A comma might be missing here.
Context: ...e) to make changes apply. On macOS and Linux it should also be possible to confirm i...

(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)

docs/MULTIPLE_FLUTTER_VERSIONS.md

[style] ~16-~16: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...acOS ### 1. Clone new Flutter instance alongside with the existing one ``` cd ~ git clone ht...

(ALONGSIDE_WITH)


[uncategorized] ~39-~39: You might be missing the article “the” here.
Context: ..." ``` Save and close. ### 3. Check if newly installed Flutter version is accessible...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~48-~48: Commas should not be placed before a closing parenthesis. Either move the comma outside of the parentheses, or remove it altogether.
Context: ... Flutter version to VSCode - Settings (⌘,) -> Extensions -> Dart -> SDK -> Flutter...

(COMMA_CLOSING_PARENTHESIS)


[uncategorized] ~54-~54: Commas should not be placed before a closing parenthesis. Either move the comma outside of the parentheses, or remove it altogether.
Context: ...# 5. Add to Android Studio - Settings (⌘,) -> Languages & Frameworks -> Flutter ->...

(COMMA_CLOSING_PARENTHESIS)

🪛 YAMLlint (1.35.1)
.github/workflows/unit-tests-on-pr.yml

[error] 25-25: trailing spaces

(trailing-spaces)


[error] 33-33: trailing spaces

(trailing-spaces)

.github/workflows/firebase-hosting-pull-request.yml

[error] 44-44: trailing spaces

(trailing-spaces)

.github/workflows/validate-code-guidelines.yml

[error] 26-26: trailing spaces

(trailing-spaces)

.github/workflows/firebase-hosting-merge.yml

[error] 35-35: trailing spaces

(trailing-spaces)


[warning] 58-58: too many blank lines

(1 > 0) (empty-lines)

.github/actions/generate-assets/action.yml

[error] 25-25: trailing spaces

(trailing-spaces)


[error] 26-26: trailing spaces

(trailing-spaces)

🪛 GitHub Actions: CharlVS is validating code guidelines 🚀
lib/bloc/coins_bloc/coins_bloc.dart

[info] 47-47: 'CurrentWalletBloc' is deprecated and shouldn't be used. Please use AuthBloc or KomodoDefiSdk instead.

lib/bloc/bridge_form/bridge_validator.dart

[info] 229-229: 'getCoin' is deprecated and shouldn't be used. Use KomodoDefiSdk assets or getCoinFromId instead.


[info] 269-269: 'getCoin' is deprecated and shouldn't be used. Use KomodoDefiSdk assets or getCoinFromId instead.


[info] 390-390: 'balance' is deprecated and shouldn't be used. Use the balance manager from the SDK.


[info] 395-395: 'balance' is deprecated and shouldn't be used. Use the balance manager from the SDK.


[info] 403-403: 'balance' is deprecated and shouldn't be used. Use the balance manager from the SDK.

lib/bloc/cex_market_data/price_chart/price_chart_bloc.dart

[info] 40-40: 'assetsFromTicker' is deprecated and shouldn't be used. This extension/class/method is intended for use while transitioning KW to the KDF SDK.

lib/bloc/coins_bloc/asset_coin_extension.dart

[info] 107-107: 'slp' is deprecated and shouldn't be used. No longer active. Will be removed in the future.

lib/bloc/market_maker_bot/market_maker_order_list/market_maker_bot_order_list_repository.dart

[info] 86-86: 'getCoin' is deprecated and shouldn't be used. Use KomodoDefiSdk assets or getCoinFromId instead.


[info] 86-86: 'balance' is deprecated and shouldn't be used. Use the balance manager from the SDK.


[info] 97-97: 'getCoin' is deprecated and shouldn't be used. Use KomodoDefiSdk assets or getCoinFromId instead.


[info] 99-99: 'getCoin' is deprecated and shouldn't be used. Use KomodoDefiSdk assets or getCoinFromId instead.

lib/bloc/app_bloc_root.dart

[info] 115-115: 'CurrentWalletBloc' is deprecated and shouldn't be used. Please use AuthBloc or KomodoDefiSdk instead.


[info] 264-264: 'CurrentWalletBloc' is deprecated and shouldn't be used. Please use AuthBloc or KomodoDefiSdk instead.


[info] 420-420: 'CoinIcon' is deprecated and shouldn't be used. CoinIcon is deprecated. Use AssetIcon from the SDK's komodo_ui package instead.

lib/bloc/fiat/fiat_onramp_form/fiat_form_bloc.dart

[info] 298-298: 'getFirstPubkey' is deprecated and shouldn't be used. Use SDK pubkeys.getPubkeys instead and let the user select from the available options.


[info] 300-300: 'getFirstPubkey' is deprecated and shouldn't be used. Use SDK pubkeys.getPubkeys instead and let the user select from the available options.


[info] 324-324: 'getFirstPubkey' is deprecated and shouldn't be used. Use SDK pubkeys.getPubkeys instead and let the user select from the available options.

lib/bloc/bridge_form/bridge_bloc.dart

[info] 98-98: 'getCoin' is deprecated and shouldn't be used. Use KomodoDefiSdk assets or getCoinFromId instead.


[info] 582-582: 'getCoin' is deprecated and shouldn't be used. Use KomodoDefiSdk assets or getCoinFromId instead.

lib/bloc/coins_bloc/coins_repo.dart

[info] 150-150: 'getFirstPubkey' is deprecated and shouldn't be used. Use SDK pubkeys.getPubkeys instead and let the user select from the available options.


[info] 299-299: 'getCoin' is deprecated and shouldn't be used. Use KomodoDefiSdk assets or getCoinFromId instead.


[info] 465-465: 'balance' is deprecated and shouldn't be used. Use the balance manager from the SDK.

🪛 markdownlint-cli2 (0.17.2)
docs/MULTIPLE_FLUTTER_VERSIONS.md

18-18: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)


27-27: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)


33-33: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)


41-41: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)

🔇 Additional comments (222)
assets/translations/en.json (6)

10-10: LGTM!

The new translation key "lastTransactions" with value "Last transactions" is clear and consistent with other transaction-related keys.


179-180: LGTM!

The updated disclaimer translations improve readability:

  • "Terms & Conditions" uses proper capitalization and ampersand
  • The acceptance description is clear and concise

200-200: LGTM!

The custom seed warning text effectively communicates the security implications and required user action.


401-409: LGTM!

The new HD wallet and address management translations are technically accurate and user-friendly:

  • Clear error messages for address limits
  • Well-explained HD wallet mode switch
  • Accurate technical terms (derivation path, BIP39)

586-588: LGTM!

The test coins and trading bot translations are clear and consistent with the application's terminology.


609-615: LGTM!

The address management translations are clear and follow good UX writing practices:

  • Clear action verbs ("Create", "Scan")
  • Consistent terminology
  • Helpful instructions for QR code usage
lib/bloc/cex_market_data/mockup/mock_transaction_history_repository.dart (4)

2-2: LGTM! Import changes align with type updates.

The addition of komodo_defi_types.dart import supports the migration from Coin to AssetId type.


8-8: LGTM! Better interface implementation.

Changing from extends to implements is more appropriate for a mock class, as it explicitly declares the contract it needs to fulfill.


19-23: LGTM! Method signature and implementation updated correctly.

The changes properly implement the migration from Coin to AssetId type, with correct usage of assetId.id.


26-29: Verify if completed transactions filtering is needed.

The current implementation assumes all transactions are completed by directly delegating to fetch(). Please verify if this is the intended behavior or if filtering of completed transactions should be implemented.

assets/packages/flutter_inappwebview_web/assets/web/web_support.js (1)

3-9: LGTM! Improved function signature with better type safety.

The updated function signature with JSDoc annotations and direct object parameters is a good improvement that:

  • Reduces unnecessary DOM queries
  • Improves type safety
  • Maintains backward compatibility
.gitignore (1)

1-3: LGTM! Well-organized additions to .gitignore.

The new entries are properly categorized and include necessary ignores for:

  • First-party SDK directory
  • Development tools (devtools_options.yaml)
  • Web-related files
  • Python virtual environment
  • FVM version cache

Also applies to: 41-41, 44-45, 90-93

docs/INSTALL_FLUTTER.md (3)

14-18: LGTM! Improved code block formatting.

The addition of the bash tag to code blocks enhances readability by providing proper syntax highlighting for shell commands.

Also applies to: 34-38, 41-45


49-52: LGTM! Clear Windows setup instructions.

The Windows PATH setup instructions are well-structured and properly sourced from the official Flutter documentation.


58-67: Consider adding security verification for the FVM installation script.

While the FVM section is a valuable addition, executing scripts directly from the internet via curl poses security risks.

Consider adding:

  1. The expected SHA256 hash of the installation script
  2. Alternative installation methods (like package managers)
  3. A note about reviewing the script content before execution
 ## Alternative: FVM

 The recommended method of handling multiple Flutter versions is to use [FVM](https://fvm.app/documentation/getting-started/installation).

+> **Security Note**: Before executing any script from the internet, it's recommended to review its contents. You can download and inspect the script first:
+> ```bash
+> curl -fsSL https://fvm.app/install.sh -o install.sh
+> # Review the script contents
+> cat install.sh
+> # If the script looks safe, execute it
+> bash install.sh
+> ```
+
 ```bash
 curl -fsSL https://fvm.app/install.sh | bash

 # Configure the Flutter version to use in the current directory (e.g. ~/komodo-wallet)
 fvm use stable

</details>
<details>
<summary>lib/bloc/cex_market_data/portfolio_growth/portfolio_growth_repository.dart (3)</summary>

`6-6`: **LGTM! Clean import additions.**

The new imports support the migration to structured types (`komodo_defi_types`) and repository pattern (`coins_repo`).



Also applies to: 13-13

---

`25-29`: **LGTM! Clean dependency injection implementation.**

The addition of `CoinsRepo` as a required dependency follows best practices for dependency injection and maintains consistency across the codebase.



Also applies to: 37-38, 44-45, 55-55

---

`313-313`: **LGTM! Consistent type migration.**

The changes to use `AssetId` and `_coinsRepository` are consistent with the codebase-wide migration to structured types.



Also applies to: 317-317

</details>
<details>
<summary>lib/bloc/market_maker_bot/market_maker_bot/market_maker_bot_bloc.dart (4)</summary>

`4-4`: **LGTM! Good addition of bloc_concurrency.**

The addition of `bloc_concurrency` package is appropriate as it provides the event transformers needed for controlling event processing flow.

---

`28-43`: **Excellent choice of event transformers!**

The transformer selection shows good understanding of concurrency requirements:
- `restartable()` for start/stop events ensures only the latest operation is processed
- `sequential()` for order operations maintains order integrity by processing them sequentially

This prevents race conditions and ensures predictable bot behavior.

---

`49-50`: **LGTM! Improved async method signatures.**

The explicit `Future<void>` return types better communicate the asynchronous nature of these operations.



Also applies to: 72-73, 92-93, 127-128

---

`182-182`: **LGTM! Improved type clarity.**

The explicit `Future<void>` type for `delayed` improves code clarity.

</details>
<details>
<summary>lib/bloc/bitrefill/bloc/bitrefill_bloc.dart (1)</summary>

`12-20`: <details>
<summary>❓ Verification inconclusive</summary>

**Verify the migration of payment intent handling.**

The removal of payment intent subscription handling raises some concerns:
1. The bloc still handles payment intent events but no longer subscribes to them
2. Other parts of the system might expect payment intent updates that are no longer being provided


Please verify:
1. Where the payment intent handling was migrated to
2. That all components depending on payment intent updates have been updated accordingly

---

🏁 Script executed:

```shell
#!/bin/bash
# Search for other files that might have taken over payment intent handling
echo "Searching for payment intent related files..."
rg -l "BitrefillPaymentIntent"

echo "\nSearching for potential subscribers to payment intent events..."
rg -l "BitrefillPaymentIntentEvent"

Length of output: 850


Action Required: Verify Payment Intent Handling Migration

The recent changes removed the local subscription for payment intent updates in BitrefillBloc, yet related event classes (e.g., BitrefillPaymentIntentEvent) and handlers remain in several parts of the codebase. Please ensure that:

  • An alternative mechanism (possibly within BitrefillEventFactory or another component) now manages the subscription and cleanup for payment intent events.
  • All components dependent on payment intent updates (such as those in lib/views/bitrefill/bitrefill_button.dart and related files) are updated to align with the new handling logic.
  • The removal does not inadvertently risk memory leaks or leave stale event streams active.
lib/bloc/bridge_form/bridge_validator.dart (2)

6-6: LGTM! Migration from CoinsBloc to CoinsRepo.

The change from CoinsBloc to CoinsRepo aligns with the broader SDK migration effort.

Also applies to: 24-26, 32-34


272-272:

❓ Verification inconclusive

Verify the address comparison logic change.

The comparison has been updated to use addressData property. Please ensure this change maintains the correct behavior for all address types and formats.


🏁 Script executed:

#!/bin/bash
# Search for other instances of address comparison in the codebase
rg -A 2 "address.*==.*address" --type dart

Length of output: 2364


Review Focus: Validate Address Comparison Consistency

The update to use the addressData property in the comparison at this location should be verified against how addresses are handled throughout the codebase. In other parts of the system (for example, comparisons in lib/model/coin.dart use the address property), similar checks occur. Please ensure that:

  • Both selectedOrderAddress.addressData and ownAddress contain normalized address values compatible across all address types and formats.
  • This change does not introduce discrepancies especially if other parts of the code are still using the address property for comparisons.
  • The updated logic has been thoroughly tested for edge cases (such as differences in format, null values, casing, or extra whitespace).
app_theme/lib/src/dark/theme_global_dark.dart (4)

10-11: LGTM! Improved formatting of SnackBarThemeData

The reformatting enhances code readability while maintaining the same functionality.


36-39: LGTM! Improved TextStyle property formatting

The multi-line formatting of TextStyle properties enhances code readability and maintainability.

Also applies to: 41-44, 46-49, 52-55


28-28: Verify the impact of the updated tertiary color

The tertiary color has been updated. Please ensure this change maintains visual consistency across the app's dark theme.


58-58:

❓ Verification inconclusive

Verify the custom color extension method implementation

The code uses a custom withValues(alpha:) method instead of the standard Flutter withOpacity(). Please ensure that this extension method is properly implemented and tested.

Also applies to: 61-61, 97-98, 114-114, 117-117, 119-119, 136-136, 175-177


🏁 Script executed:

#!/bin/bash
# Search for the implementation of the withValues extension method
rg -l "extension.*on.*Color" --type dart

Length of output: 42


Action Required: Verify the withValues(alpha:) Custom Extension Implementation

It appears that our automated search did not locate a matching implementation for the custom withValues(alpha:) method. Please verify one of the following:

  • Confirm that a custom extension on Color implementing withValues(alpha:) exists in the repository and is correctly imported in all files where it’s used (e.g., at lines 58, 61, 97-98, 114, 117, 119, 136, and 175-177).
  • If no such extension exists, consider either implementing it or reverting to the standard Flutter withOpacity() method.
app_theme/lib/src/light/theme_global_light.dart (3)

97-103: LGTM! Consistent styling across input decoration elements.

Good practice maintaining the same alpha value (0.58) across hint text, label text, and prefix icons, ensuring visual consistency in form elements.


161-161: LGTM! Improved tab indicator alignment.

Good improvement adding horizontal insets to match the card's border radius, enhancing visual consistency.


41-46:

❓ Verification inconclusive

Verify the color opacity migration impact.

The change from withOpacity to withValues(alpha: ...) appears to be part of a broader refactor. While the visual appearance should remain the same, please ensure:

  1. The new method is supported in your minimum Flutter version
  2. There are no performance implications
  3. All instances of withOpacity are consistently migrated

🌐 Web query:

What's the difference between Color.withOpacity and Color.withValues in Flutter?

💡 Result:

In Flutter's color handling system, Color.withOpacity and Color.withValues serve related but distinct purposes, especially after framework updates in Flutter 3.27:

Key Differences

Aspect withOpacity (Deprecated) withValues (Recommended)
Precision Converts opacity to 8-bit alpha (0-255), causing rounding errors (e.g., 0.5128/255 ≈ 0.50196) Uses exact floating-point alpha values (e.g., alpha: 0.50.5) [1][4][5][8]
Color Space Assumes sRGB color space Supports explicit color spaces (ColorSpace.extendedSRGB, etc.) for accurate calculations [4][5][9]
Method Purpose Legacy method for basic opacity adjustments Modern method for precise alpha/color channel control with full gamut support
Data Loss Quantizes values to 8-bit integers Preserves full floating-point precision

Examples

// Before (deprecated)
Color semiTransparent = Colors.black.withOpacity(0.5); // Alpha ≈ 128/255 (~0.50196)

// After (recommended)
Color preciseTransparent = Colors.black.withValues(alpha: 0.5); // Alpha = 0.5 exactly [4][5]

Why Deprecate withOpacity?

  • Precision Issues: The method forced quantization of alpha values into 8-bit integers, leading to subtle inaccuracies[1][4][8].
  • Color Space Limitations: It didn’t account for modern wide-gamut color spaces like Display P3 or Adobe RGB[5][9].
  • Semantic Ambiguity: The term "opacity" conflated floating-point intent with integer storage mechanics[8].

When to Use withValues

  • For animations requiring smooth alpha transitions.
  • When working with HDR/wide-gamut displays.
  • To avoid cumulative rounding errors in color calculations[4][5].

For most use cases, migrating to withValues ensures better color fidelity and future-proofs your code against further framework changes[1][4][8].

Citations:


Verify Color Opacity Migration in Text Styles

The changes in app_theme/lib/src/light/theme_global_light.dart at lines 41–46 replace the deprecated withOpacity method with withValues(alpha: ...). This migration leverages floating-point precision to avoid rounding errors and supports extended color spaces as introduced in Flutter 3.27. Please ensure that:

  • Flutter Version Compatibility: The new withValues method is fully supported in your project's minimum Flutter version.
  • Visual and Performance Consistency: The appearance of text (e.g., in bodyLarge and bodySmall) remains unchanged and no performance regressions are introduced.
  • Consistent Migration: All instances of withOpacity have been correctly and uniformly updated across the codebase.
docs/MANUAL_TESTING_DEBUGGING.md (1)

141-142: Improve cross-platform compatibility of path variables.

The use of $HOME environment variable might not work correctly on Windows. Consider using platform-agnostic paths or providing Windows alternatives.

Please check if the path works on Windows and consider adding Windows-specific instructions if needed.

ios/Runner.xcodeproj/project.pbxproj (4)

267-283: LGTM! Well-configured CocoaPods resource phase.

The new "[CP] Copy Pods Resources" build phase is properly configured with input/output file lists, following CocoaPods best practices.


410-410: LGTM! Proper architecture configuration.

Adding $(inherited) to EXCLUDED_ARCHS across all configurations ensures proper inheritance of architecture exclusions from CocoaPods.

Also applies to: 551-551, 584-584


297-297: LGTM! Improved script formatting.

Adding a newline character to the build script improves readability.


186-186:

❓ Verification inconclusive

Verify Xcode version compatibility.

The project has been upgraded to use Xcode 15.1.0 (LastUpgradeCheck = 1510). Please ensure all team members have compatible Xcode versions installed.


🌐 Web query:

What is the minimum Xcode version required for iOS development with Flutter?

💡 Result:

The minimum required Xcode version for iOS development with Flutter depends on your target environment:

For general Flutter development

  • Xcode 16 is required for compiling native Swift/Objective-C code and debugging according to current Flutter documentation[1]. This includes Git v2.27+ through the Xcode installation.

For App Store submissions

  • Xcode 15 with iOS 17 SDK is mandated as of April 2024 for App Store deployments[9], though newer versions like Xcode 16 are recommended for compatibility with latest Flutter features.

Key supporting details:

  1. Flutter v1.15.3+ requires modern Xcode versions for framework linking[2]
  2. Amplify integration requires minimum Xcode 15 for iOS targets[4]
  3. HERE SDK needs at least Xcode 13.2.1 for iOS development[6]

Recent updates show compatibility issues when using older versions - a GitHub issue demonstrates build failures when using Xcode 16.1 without proper configuration[10]. Developers should always verify their environment against the latest Flutter documentation[1][5] and App Store requirements[9].

Citations:


Action: Verify Xcode Compatibility and Remove Legacy MM2 Reference

  • The project’s upgrade in ios/Runner.xcodeproj/project.pbxproj now sets LastUpgradeCheck = 1510, indicating an update for Xcode 15.1. However, recent Flutter documentation recommends using Xcode 16 for general development (for compiling native Swift/Objective-C code and debugging), while Xcode 15 (with iOS 17 SDK) remains acceptable for App Store submissions. Please double-check that your target environment and team setup align with these requirements.

  • Additionally, the unused reference to libmm2.a remains in the project. As part of the MM2 cleanup, remove this legacy reference to avoid confusion and potential maintenance issues.

  • Other changes (such as the new "[CP] Copy Pods Resources" build phase, the added newline in the build script, and the updated EXCLUDED_ARCHS inheritance) are correctly implemented.

lib/bloc/bridge_form/bridge_repository.dart (8)

3-4: No concerns regarding imports.
These imports are straightforward and appear to be necessary dependencies for the new functionality.


29-33: Verify intended logic for matching source and target tickers.
Using && here restricts matches to orderbook depths where both source and target share the same ticker. Confirm whether you intended to filter pairs with the same ticker or if an || condition would be more appropriate.


55-56: Retrieving coins from the repository looks fine.
No issues found. It’s a clean approach to fetching the known coins.


58-58: Handle potential errors from the sign-in check.
await _kdfSdk.auth.isSignedIn() may fail or throw. Consider adding error handling or verifying that any exceptions won’t break the flow.


71-73: No issues with refactoring to trailing commas.
This is a stylistic improvement that aids readability in Dart.


90-91: Trailing comma usage is standard for Dart.
No issues; this improves formatting consistency.


111-112: Method signature with trailing commas is acceptable.
No concerns; keeps the code style consistent.


114-114: Confirm that _coinsRepository is valid at runtime.
Ensure that _coinsRepository is fully loaded and contains the necessary data before passing it to _mm2Api.getOrderBookDepth(). Consider handling or logging errors if data isn’t ready.

lib/bloc/coins_manager/coins_manager_state.dart (4)

1-1: LGTM! Good architectural change.

Moving to a part file structure improves code organization and reduces import duplication.


3-17: LGTM! Well-structured class implementation.

The class follows Dart best practices with:

  • Proper immutability using final fields
  • Clear parameter requirements
  • Good use of Equatable for value comparison

33-65: LGTM! Well-implemented helper methods.

The helper methods and overrides are properly implemented:

  • copyWith follows the standard immutable update pattern
  • isSelectedAllCoinsEnabled provides clear business logic
  • props correctly implements Equatable

19-31:

✅ Verification successful

Verify the impact of making 'action' parameter optional.

While making the parameter optional with a default value of CoinsManagerAction.add improves API flexibility, please ensure all existing callers are compatible with this change.


🏁 Script executed:

#!/bin/bash
# Search for all calls to CoinsManagerState.initial to verify compatibility
ast-grep --pattern 'CoinsManagerState.initial($$$)'

Length of output: 53


Action Required: Verify backwards compatibility of the optional 'action' parameter

We’ve updated the CoinsManagerState.initial method to make the action parameter optional with a default value of CoinsManagerAction.add to improve API flexibility. However, the initial AST grep did not yield any results, so please manually verify (or re-run the above ripgrep search) that all calls to CoinsManagerState.initial—especially those that might rely on a required parameter—are indeed compatible with this change.

  • Location: lib/bloc/coins_manager/coins_manager_state.dart (lines 19-31)
  • Impact: Ensure that callers passing no action parameter continue to work as expected.

🏁 Script executed:

[run_scripts]
#!/bin/bash
# Use ripgrep to search for all references to CoinsManagerState.initial across the repository for a more comprehensive check
rg "CoinsManagerState\.initial\(" -n .

Length of output: 390


No compatibility issues found with the updated 'action' parameter.

Our ripgrep search revealed two invocations of CoinsManagerState.initial in lib/bloc/coins_manager/coins_manager_bloc.dart:

  • One call (line 22) relies on the default value for action.
  • Another call (line 82) explicitly supplies event.action.

Both usages confirm that the method’s flexibility is maintained without breaking existing functionality. Please verify that the unit tests cover these scenarios to ensure everything works as expected.

ios/Runner/AppDelegate.swift (1)

2-12:

❓ Verification inconclusive

Swift 5.3 entry point and cleanup verification

The updated @main usage for Swift 5.3+ is correct and the streamlined AppDelegate class looks good. However, please ensure that all references to removed MM2 or other stale dependencies are fully cleaned up across the codebase.

You can confirm there's no lingering usage of MM2 or related references by running this script in the repository root:


🏁 Script executed:

#!/bin/bash
rg mm2 -A 5

Length of output: 95356


Swift 5.3 entry point verified – please review MM2 dependency cleanup

The changes in AppDelegate.swift using the new Swift 5.3 entry point look correct. However, a repository-wide search for “mm2” reveals numerous references in Android build files, C/C++ sources, and many Dart modules (including files under lib/mm2/). If the intention was to remove or replace MM2 and other stale dependencies, please verify whether these lingering references are still required. Otherwise, kindly clean up or update them for consistency across the codebase.

ios/Flutter/AppFrameworkInfo.plist (1)

24-24: Dropping iOS 11 support

Raising MinimumOSVersion to 12.0 is a breaking change for users on older iOS devices. Make sure this is intentional and that you’re comfortable removing support for iOS 11.

If needed, you can gather usage metrics or analytics data to confirm the impact.

ios/Podfile (1)

2-2: Synchronize with new OS requirement

Updating platform :ios, '12.0' aligns with the new minimum OS version. This will drop support for iOS 11 and below, so double-check that your user base won’t be adversely impacted.

Suggest confirming any older iOS usage to ensure you’re not excluding critical users.

lib/bloc/bitrefill/data/bitrefill_provider.dart (1)

2-2: LGTM! URL construction simplified using getOriginUrl()

The refactoring improves code maintainability by:

  • Removing platform-specific logic
  • Using a centralized utility for origin URL
  • Maintaining consistent URL construction

Also applies to: 60-61

lib/app_config/app_config.dart (3)

15-15: LGTM! New constant for framework assets path

The addition of coinsAssetsPath improves maintainability by centralizing the path configuration for coin assets from the framework package.


21-28: Important regulatory compliance warning added

The comment block effectively communicates:

  • Trading restrictions
  • Development-only test coin usage
  • Clear liability disclaimer

121-122: Simplified test coins enablement logic

The condition for enabling test coins (DOC, MARTY) now only depends on kDebugMode, making the logic clearer and more straightforward.

.github/actions/flutter-deps/action.yml (1)

1-20:

❓ Verification inconclusive

Verify Flutter version compatibility

The action uses Flutter 3.27.x, which is a very recent version. Ensure this version is compatible with all project dependencies.


🌐 Web query:

What is the latest stable version of Flutter and when was it released?

💡 Result:

The latest stable version of Flutter as of February 14, 2025, is Flutter 3.29, released on February 12, 2025[7]. This update includes enhancements like improved web renderers with WebAssembly (Wasm) support and expanded AI toolkit integration[7]. Documentation for this release was updated two days prior to reflect new features such as architectural guidance for large-scale apps and multi-view web embedding capabilities[7].

For context:

  • Previous versions included Flutter 3.27 (December 11, 2024)[7] and Flutter 3.24 (August 7, 2024)[7].
  • The framework maintains quarterly feature updates for its stable channel[6][4], with hotfixes addressing critical issues like compilation errors and macOS permission problems[6].

Citations:


Action Required: Verify and Consider Upgrading Flutter Version

The composite action currently specifies Flutter 3.27.x. Note that the latest stable release as of February 14, 2025, is Flutter 3.29 (released February 12, 2025). Please ensure that the 3.27.x version is fully compatible with all project dependencies or, if suitable, consider upgrading to leverage the latest features and improvements.

  • File: .github/actions/flutter-deps/action.yml (Lines 1-20)
  • Suggestion: Verify dependency compatibility with Flutter 3.27.x and assess any potential benefits of upgrading to 3.29.
.github/workflows/unit-tests-on-pr.yml (1)

38-44: Great addition of code coverage reporting!

The addition of code coverage reporting will help maintain code quality and identify areas needing more test coverage.

app_build/build_config.json (2)

21-22: Good addition of fetch_at_build_enabled flag.

This change aligns with the build process improvements and ensures consistent coin configurations during builds.


21-25:

✅ Verification successful

Verify the new coins repository URL accessibility.

The coins repository URL has been changed to GitHub Pages. Let's verify its accessibility and content.


🏁 Script executed:

#!/bin/bash
# Check if the new coins repository URL is accessible
curl -I https://komodoplatform.github.io/coins

Length of output: 953


Verified: New Coins Repository URL Accessible

  • The URL "https://komodoplatform.github.io/coins" returns an HTTP 301 redirect to "https://komodoplatform.github.io/coins/", which is expected behavior for GitHub Pages.
  • This confirms that the endpoint is up and reachable. No further changes are necessary.
.github/actions/generate-assets/action.yml (1)

25-31: Well-implemented two-phase build process.

The implementation correctly handles the initial build failure and asset generation process. The comments clearly explain the expected behavior.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 25-25: trailing spaces

(trailing-spaces)


[error] 26-26: trailing spaces

(trailing-spaces)

.github/workflows/firebase-hosting-merge.yml (1)

49-51: Good update of branch reference from master to main.

The change from master to main aligns with current Git naming conventions.

lib/bloc/cex_market_data/portfolio_growth/portfolio_growth_bloc.dart (3)

8-8: Imported coins_repo.dart successfully.

This import is necessary to reference the CoinsRepo class.


21-21: Constructor now explicitly requires coinsRepository.

This helps ensure the PortfolioGrowthBloc has a clear dependency on coinsRepository.


38-38: coinsRepository field declaration is appropriate.

This final field ensures coinsRepository is immutable within the bloc.

lib/bloc/cex_market_data/mockup/mock_portfolio_growth_repository.dart (4)

10-10: Added coins_repo.dart import.

This is needed for the new CoinsRepo constructor argument.


21-21: New coinsRepository parameter in constructor.

Explicitly requiring coinsRepository clarifies dependencies.


24-28: Enhanced withDefaults constructor dependencies.

Including coinsRepository and mm2Api in the mock constructor improves parity with production code.


41-41: Passing coinsRepository to super constructor.

Ensures the parent class will also have consistent access to coin data.

lib/bloc/cex_market_data/profit_loss/demo_profit_loss_repository.dart (4)

10-10: Imported coins_repo.dart for coin management.

This aligns with the broader refactor requiring CoinsRepo.


22-22: Necessary coinsRepository parameter in constructor.

Makes dependencies explicit for MockProfitLossRepository.


27-28: Additional parameters in withDefaults constructor.

Accepting coinsRepository and mm2Api improves correctness for the mock setup.


49-49: Passing coinsRepository to parent constructor.

Facilitates consistent coin-handling logic in the parent ProfitLossRepository.

docs/MULTIPLE_FLUTTER_VERSIONS.md (1)

22-22:

❓ Verification inconclusive

Verify Flutter version compatibility.

The Flutter version has been updated from 3.3.9 to 3.23.4, which is a significant version jump. Please ensure this version is compatible with all project dependencies.


🌐 Web query:

What are the breaking changes between Flutter 3.3.9 and 3.23.4?

💡 Result:

Okay, I need to figure out the breaking changes between Flutter 3.3.9 and 3.23.4. Let me start by looking at the search results provided.

First, I'll check the Flutter changelog in [1]. It lists changes for versions 3.27, 3.24, 3.22, 3.19, and others. But I need to focus on versions between 3.3.9 and 3.23.4. Wait, the user mentioned 3.23.4, but looking at the search results, the versions listed are 3.27, 3.24, 3.22, etc., so maybe there's a typo? Or perhaps the user meant 3.24.x? Let me check.

Looking at result [1], under "Flutter 3.24 Changes", there's version 3.24.5 and 3.24.4, which might be relevant. Also, result [3] from the Flutter documentation lists breaking changes by release, including sections for Flutter 3.24 and 3.22, which are within the range of 3.3.9 to 3.24.x.

Wait, Flutter versioning goes from 3.3.x to higher versions like 3.7.x, 3.10.x, up to 3.27.x as per the changelog in [1]. So between 3.3.9 (which is part of Flutter 3.3) and up to maybe 3.24 (since the user wrote 3.23.4, but perhaps that's a mistake), there are several major releases with breaking changes.

The user's target is to find breaking changes between these two versions: starting at 3.3.9 (which is a hotfix of Flutter 3.3) and ending at a version that might be a typo (since in the search results, there's no mention of 3.23.x; instead, there are versions like 3.22.x and then jumps to 3.24.x). Perhaps the user intended to ask about up to version 3.24.x?

Assuming that the user meant up to version 3.24.x (since that's present in the search results), I'll proceed by checking each major release between Flutter 3.3 and Flutter 3.24.

From [1], looking at each version:

  • Flutter 3.7 changes: version 3.7.x includes some hotfixes.
  • Flutter 3 changes: version up to 3.x.
  • Then moving through versions like Flutter 3.10, 3.13, etc., as per result [10].

But more importantly, result [3] lists breaking changes by release, which includes sections for each major version:

  • Released in Flutter 3.24
  • Released in Flutter 3.22
  • Released in Flutter 3.19
  • ... and so on.

So I need to check all breaking changes from versions after Flutter 3.3 up to and including Flutter 3.24.

Breaking changes in each release:

From [10], Dart's breaking changes are also listed by release.

But focusing on Flutter-specific changes from [1] and [3]:

Starting with Flutter versions after 3.33 (since the user is starting at Flutter v33?), wait no—Flutter version numbers don't go that high; perhaps a typo again.

Wait, original query: "breaking changes between Flutter 33". Oh wait no—the user wrote "Flutter 33" but looking at the actual versions in search results:

In result [1], there's a section for Flutter v33? Wait no: looking back at search result [1], it lists versions like:

  • Flutter v33? No, it starts with "Flutter v327 Changes" (probably a typo for v327?), but actually reading through:

Wait in search result [1], under "Flutter CHANGELOG.md", they have sections like:

Flutter v327 Changes

Wait that must be a typo; likely it's version numbers like "Flutter v327" is supposed to be "Flutter v327"? Or perhaps they meant "Flutter v327" as part of a longer version number? Hmm.

Wait looking more carefully at search result [1]:

The first section is "## Flutter v327 Changes", then subversions like v3274 (probably meaning v3274 as in v3274?), but that doesn't make sense because standard versioning is major.minor.patch.

Wait perhaps it's a formatting error when pasting into this context.

Looking again:

[1] shows:

Flutter v327 Changes

v3274

Then later:

Flutter v324 Changes

v3245

Ah! So likely these are typos where "v327" is supposed to be "v327" as in major.minor.patch?

Wait no—looking carefully:

The actual text from search result [1] is:

Flutter v327 Changes

v3274

But standard versioning would be something like "Flutter v327" would be major=32? That seems off.

Wait perhaps it's a typo for "Flutte rv327", but more likely it's supposed to be "Flutte rv327" as in version numbers with three digits like major.minor.patch: e.g., "Flutte rv327" would be major=32 minor=7 patch=0?

No—that doesn't make sense either.

Alternatively, perhaps it's supposed to be "Flutte rv327" as in version numbers separated by periods: e.g., "Flutte rv327" would be major=32 minor=7 patch= something? No.

Alternatively, maybe it's a mistake and should be "Flutte rv327" as part of a longer version number like "Flutte rv327"?

Wait maybe the actual correct versions are:

In search result [1], under "## Flutte rv327 Changes", they have subversions like ### v3274 which would correspond to version number x.y.z where x=32?, y=7?, z=4? That seems unlikely.

Alternatively, perhaps these are typos where each section header is meant to represent a major.minor version number without periods due to markdown rendering issues when pasted here.

For example:

"## Flutte rv324 Changes" could actually be "## Flutte rv324 Changes", which would correspond to version "324", meaning major=324? No—that can't be right.

Alternatively, perhaps these are typos where the actual intended versions are something else.

Alternatively, given that some of the entries in search result [1] mention versions like "Flutte rv322 Changes", which would correspond to version numbers like "322"? That doesn't align with standard semantic versioning.

Alternatively, perhaps there was an error when copying the text into this context where periods were lost or added incorrectly.

Alternatively, given that other parts of search result [1] mention versions like:

v333 (Dec16,2022)

Which would correspond to December16th releases for hotfixes of earlier versions.

But this is getting confusing because of possible formatting errors in how the changelog was presented here.

Given that this might be causing confusion in interpreting the exact versions mentioned in search result [1], I'll focus on the breaking changes listed in result [10], which lists breaking changes by release for Dart and possibly for Flutte r.

Looking back at result [10], Dart's breaking changes are organized by release date and area.

But since we're dealing with breaking changes between two specific versions of Flutte r (assuming that the user intended from version33x9 up to323x4), but given possible typos or misinterpretations of version numbers due to formatting issues in search results[1], this complicates things.

Alternatively, perhaps focusing on result[10] which lists breaking changes by release for Dart and other components can help identify any relevant Dart SDK changes that could have impacted flutter during those releases.

But given time constraints and possible confusion with version numbers here due to formatting issues in search results[1], I'll proceed by extracting all breaking changes mentioned in search results[10] between releases after33x9 up until323x4 (assuming that323x4 is intended).

Looking back at result[10]:

Under 'Breaking changes by release', they list releases such as 'Released in flutter33', 'Released in flutter37', up through 'Released in flutter324'.

For example:

  • Released in flutter33: Breaking change related to RouteTransitionRecord.markForRemove being deprecated.
  • Released in flutter37: Deprecated API removed after v33.
  • Released in flutter310: Dart39 changes.
  • Released in flutter316: Material39 default theme enabled.
  • Released in flutter319: Deprecated API removed after316.
  • Released in flutter322: Renamed MaterialState to WidgetState.
  • Released in flutter324: Navigator page APIs breaking change.

So between flutter33 and flutter324,there are multiple breaking changes introduced across various releases.

Now compiling all these into a list:

From result[10]:

Released in flutter33:

  • Deprecate RouteTransitionRecord.markForRemovein favor of RouteTransitionRecord.markForComplete.

Released in flutter37:

  • Migrate ofto non-nullable return values,and add maybeOf.
  • Removed RouteSettings.copyWith.
  • ThemeData's toggleableActiveColor property has been deprecated.
  • iOS Flutte rViewController splashScreenView made nullable.
  • Replaced parameters for customizing context menus with generic widget builders.

Released in flutter310:

  • Dart39 null safety enforcement.
  • Deprecated API removed after37.
  • Require one data variant for ClipboardDataconstructor.
  • Deprecated window singleton.
  • Insert content text input client change.

Released in flutter313:

  • Added missing dispose()for some disposable objects.
  • Deprecated API removed after310.
  • Added AppLifecycleState.hidden enum value.
  • Moved ReorderableListView localized strings from material to widgets localizations.
  • Removed ignoringSemanticsproperties.
  • Deprecated RouteInformation.locationand related APIs.
  • Updated EditableText scroll behavior.
  • Updated Checkbox.fillColor behavior.

Released in flutter316:

  • Default Material39 theme (useMaterial39set totrue).
  • Migrate ShortcutActivator and ShortcutManager to KeyEvent system.
  • Deprecated API removed after313.
  • Customize tabs alignment using new TabBar.tabAlignment.
  • Deprecate textScaleFactorin favor of TextScaler.
  • Android14 nonlinear font scaling enabled.
  • Deprecate describeEnumand update EnumProperty type strictness.
  • Predictive Back navigation pop APIs deprecated for Android.
  • Deprecated Paint.enableDithering.
  • Others related to Windows build paths and external windows lifecycle notifications。

Released in flutter319:

  • Migrate RawKeyEvent/RawKeyboard system to KeyEvent/HardwareKeyboard system。
  • Default multitouch scrolling enabled。
  • Other deprecated API removals。

Released in flutter322:

  • Rename MaterialState to WidgetState。
  • Introduce new ColorScheme roles。

Citations:


Flutter Upgrade Compatibility & Documentation Check:

  • The version jump from Flutter 3.3.9 to 3.23.4 spans multiple releases that introduced several breaking changes (e.g., deprecations and removals in routing, theming updates, and changes to input and key-event APIs). Please review the Flutter release notes to ensure that all project dependencies and custom implementations are updated accordingly.
  • Confirm that the new VSCode configuration steps are detailed enough for users, and update the documentation if necessary.
  • Fix the typo in the heading where "pen" should read "Open."
  • Verify that the snippet (git checkout 3.23.4) accurately reflects the repository state, including any removed or replaced code if applicable.
lib/bloc/fiat/base_fiat_provider.dart (7)

6-8: No issues with these new imports.
They correctly reference the new models/utilities, and there's no indication of unused or unnecessary dependencies.


19-21: Switching to ICurrency improves abstraction.
Ensure all callers have been updated to use ICurrency instead of Currency to prevent runtime cast errors.


23-44: Good practice to adopt the new typed signatures.
The transition to returning structured types (FiatPaymentMethod, FiatPriceInfo, FiatBuyOrderInfo) promotes stronger type safety and clarity. Confirm that no legacy invocations assume a different return shape.


107-107: Validate usage of null chain ID.
getCoinChainId can return null if no matching chain is found. Ensure callers handle this possibility to avoid null-related errors downstream.


133-133: Default case usage seems appropriate.
Explicitly ignoring no_default_cases is valid here to handle potential new CoinType extensions. Keep an eye on unhandled enum values if new chain types are introduced.


214-245: Ensure new chain types remain aligned with this switch.
This mapping from string chain IDs to CoinType is consistent, but newly introduced chain names require updates here.


247-281: New static URL builder methods look well-structured.
Base64-encoding the providerUrl and referencing local HTML assets appear to prevent direct injection. Just ensure getOriginUrl() remains correct across different deployment environments.

lib/bloc/fiat/ramp/ramp_fiat_provider.dart (9)

8-8: No concerns with importing models.dart.
This aligns well with the move to typed data classes for fiat interactions.


13-15: Constructor usage is straightforward.
The explicit fields providerId and apiEndpoint simplify the provider’s identity. Keep them updated if your environment changes.


31-32: Validate CryptoCurrency cast.
getFullCoinCode(ICurrency target) forcibly casts target to CryptoCurrency. Ensure all callers pass a valid crypto type to prevent runtime exceptions.


35-71: Refined _getPaymentMethods & _getPricesWithPaymentMethod.
Switching from Currency to ICurrency clarifies the currency abstraction. Double-check that the server API endpoints still align with the new structures.


89-102: Accurate filtering of data in getFiatList.
This function effectively extracts fiat entries from the provider’s list. Log or handle any items missing relevant keys to avoid potential runtime errors.


105-122: Graceful handling of unknown chains in getCoinList.
Skipping coins with coinType == null is sensible. Confirm all internal references to these symbols are properly handled or logged to track missing chain definitions.


134-204: getPaymentMethodsList conversion to FiatPaymentMethod objects.
The structured approach is clearer than untyped maps. Consider more detailed error logging if parsing data from the provider fails, so as to detect API format changes quickly.


228-261: getPaymentMethodPrice with structured response.
Returning a FiatPriceInfo object improves clarity. Verify that edge cases (e.g., missing price fields from the external service) are handled gracefully.


264-295: buyCoin method updates.
Returning a FiatBuyOrderInfo is cleaner than returning raw JSON. This fosters consistent usage of typed data. Confirm no leftover references to the old approach in upper layers.

lib/bloc/fiat/fiat_repository.dart (11)

4-4: Using models.dart fully is consistent.
This ensures the repository references the same typed data structures as providers, reducing serialization pitfalls.


8-11: FiatRepository now receiving _coinsRepo.
This expands its capabilities to confirm coin types with in-repo data. Just ensure cyclical dependencies are not introduced if _coinsRepo also needs fiat data.


14-15: Refined state fields for coin & payment methods.
Maintaining _paymentMethodsCoin as ICurrency? and _paymentMethodsList as a List<FiatPaymentMethod>? clarifies your cached data types.


35-42: watchOrderStatus expects a FiatPaymentMethod.
This method fails fast if no matching provider is found. That's good for discoverability. For better user feedback, consider logging or returning a more descriptive error.


44-76: _getListFromProviders merges multiple provider lists.
Your approach collects results from all providers and merges them by abbr. Good practice. Keep an eye on collisions if two providers define the same symbol differently.


106-125: _calculateCoinAmount gracefully handles numeric parsing.
Returns null if conversion fails. Just ensure the calling code has fallback logic so it doesn't break the flow.


144-186: _getPaymentListEstimate usage of copyWith.
Copying FiatPaymentMethod is safer than mutating a shared object. Thoroughly verify that partial errors or absent data are handled, so we don’t produce invalid estimates.


188-230: getPaymentMethodsList now yields a Stream<List<FiatPaymentMethod>>.
Emitting cached estimates first is a user-friendly approach. Confirm final results get displayed accurately after fresh data arrives.


232-247: getPaymentMethodPrice with typed error checks.
Properly retrieving the provider with _getPaymentMethodProvider avoids confusion. If the provider can’t be found, returning an error is a good fallback.


249-270: buyCoin integration with typed paymentMethod.
The consistent usage of typed data objects removes confusion around map keys. Make sure no references to the old approach remain.


272-316: _addRelativePercentField for method comparisons.
Sorting by relative percent is useful for quickly showing the best methods. Watch out for division by zero if maxCoinAmount is zero or negative.

lib/bloc/fiat/fiat_onramp_form/fiat_form_bloc.dart (1)

1-466: Well-structured and comprehensive BLoC implementation.

The state transitions are clearly defined, concurrency transformers are judiciously used, and error handling is thorough. The approach to form validation and dynamic updates of payment methods appears robust and maintainable.

🧰 Tools
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀

[info] 298-298: 'getFirstPubkey' is deprecated and shouldn't be used. Use SDK pubkeys.getPubkeys instead and let the user select from the available options.


[info] 300-300: 'getFirstPubkey' is deprecated and shouldn't be used. Use SDK pubkeys.getPubkeys instead and let the user select from the available options.


[info] 324-324: 'getFirstPubkey' is deprecated and shouldn't be used. Use SDK pubkeys.getPubkeys instead and let the user select from the available options.

lib/bloc/fiat/models/fiat_mode.dart (1)

1-25: Enum-based TabIndex handling looks clean and concise.

Mapping between indexes and modes is straightforward. This improves readability and reduces the chance of incorrect tab-to-mode mapping.

lib/bloc/fiat/models/fiat_buy_order_error.dart (1)

1-37: Robust error representation.

Leveraging Equatable simplifies comparisons, and the none constructor plus isNone getter neatly handle the default, “no error” scenario. The JSON handling is consistent with the rest of the codebase.

lib/bloc/fiat/fiat_order_status.dart (1)

1-1: Address the TODO comment.

The comment suggests a need to differentiate between error and in-progress statuses.

Would you like me to help implement more granular status handling for different error and in-progress states?

lib/bloc/fiat/fiat_onramp_form/fiat_form_event.dart (1)

3-98: Well-structured event hierarchy!

The event classes are well-designed with:

  • Proper use of sealed class for type safety
  • Consistent implementation of props for equality comparison
  • Clear and descriptive event names
  • Appropriate event properties for each use case
lib/bloc/fiat/models/fiat_buy_order_info.dart (3)

5-21: LGTM! Well-structured class declaration with proper immutability.

The class follows best practices by:

  • Using Equatable for value comparison
  • Making all fields final
  • Using named parameters for better readability

23-57: LGTM! Efficient constructors with const optimization.

The named constructors provide convenient ways to create instances with default values or from a URL, while maintaining immutability through const constructors.


118-139: LGTM! Consistent JSON structure.

The toJson method maintains the same nested structure as the input JSON, which is good for API consistency.

lib/bloc/fiat/fiat_onramp_form/fiat_form_state.dart (1)

3-21: LGTM! Well-structured form state with proper initialization.

Good use of FormzMixin and clear enum states. The constructor properly requires all necessary fields while providing sensible defaults for optional ones.

lib/bloc/fiat/banxa_fiat_provider.dart (1)

267-275: LGTM! Comprehensive error logging.

Good practice of including stack trace and error path in logs while gracefully falling back to a zero price.

lib/bloc/dex_tab_bar/dex_tab_bar_state.dart (6)

4-11: All constructor parameters are suitably made required.
Looks consistent with the rest of the codebase to provide clarity on mandatory parameters.


13-19: Initial state constructor is correctly initializing new fields.
Provides clear defaults for each newly introduced field.


21-26: Introduction of new final fields looks clean.
No issues found with the addition of these final fields.


30-35: copyWith method suitably includes all new fields.
Guarantees state immutability while allowing partial updates.


39-42: copyWith assignments are coherent.
The usage of the null-coalescing operator is properly handled.


46-54: All fields included in props for Equatable.
Ensures equality checks correctly factor in each new field.

lib/bloc/market_maker_bot/market_maker_order_list/market_maker_bot_order_list_repository.dart (6)

1-2: New Rational and CoinsRepo imports appear correct.
No concerns with these import statements.


13-18: Introducing _coinsRepository in the constructor is straightforward.
This dependency injection aligns well with the repository pattern.


34-34: Null-safe check on ordersToCancel is well implemented.
if (ordersToCancel?.isEmpty ?? false) prevents null pointer exceptions.


49-65: Trade pairs map logic looks good.
Iterating through configurations and matching orders with firstOrNull is clear and concise.


70-76: _getRelCoinAmount method.
The fallback usage of _getRelAmountFromBaseAmount maintains clarity if relAmountAvailable is null.


79-82: _getBaseCoinAmount method.
Acceptably retrieves or calculates the base coin amount from either the order or configured max volume.

lib/bloc/dex_tab_bar/dex_tab_bar_bloc.dart (11)

5-11: New imports for SDK and repository references.
These imports are aligned with the introduced changes.


19-23: Revised constructor parameters for additional dependencies.
Shifting to _kdfSdk, _tradingEntitiesBloc, and _tradingBotRepository clarifies the injection of required services.


26-30: New event handlers are properly registered.
They map incoming events to corresponding methods, facilitating better structure.


33-35: Added private fields for new dependencies.
Matches the constructor parameters and follows standard naming conventions.


37-40: StreamSubscription fields introduced.
No immediate issues; they provide a clear mechanism for managing multiple streams.


43-48: close method properly cancels all subscriptions.
Prevents memory leaks by ensuring a clean shutdown.


78-90: _onStopListening unsubscribes quickly and sets fields to null.
Keeps subscription states well-managed.


100-102: _onFilterChanged merges new filters with existing ones correctly.
Ensures immutability by copying the map.


107-110: _onMyOrdersUpdated sets ordersCount from event data.
Straightforward logic for orders tallying.


112-122: _onSwapsUpdated calculates in-progress and completed counts.
No issues; the new fields are updated as expected.


124-133: _onTradeBotOrdersUpdated sets tradeBotOrdersCount.
Completes the state’s coverage for all concurrency streams.

lib/bloc/coins_manager/coins_manager_bloc.dart (16)

3-3: Importing Equatable
The addition of equatable is good for simplifying equality checks on states/events.


5-6: New imports for KomodoDefiSdk and CoinsRepo
These imports reflect the move from the old CoinsBloc to the new repository/SDK integration, aligning with the project’s refactor goals.


13-14: Part directives for event/state classes
Declaring parts ensures clarity in organizing event and state definitions. Keep consistent versioning for the parted files.


18-24: Constructor injection of CoinsRepo and SDK
Injecting CoinsRepo and KomodoDefiSdk into the bloc constructor properly centralizes dependencies. This approach improves testability and maintainability.


33-34: Private fields for the repo and SDK
Storing the repo and SDK in private fields is a clean, idiomatic approach, preventing external modifications.


53-56: _onCoinsUpdate signature
Now async. Confirm that unhandled exceptions (e.g., network issues) are gracefully handled. Consider adding try-catch blocks or an error state if needed.


60-62: Awaiting _getOriginalCoinList
You're merging an asynchronously fetched list with the existing state.coins. Ensure no concurrency issues occur if multiple updates run in parallel.


75-76: Storing 'action' in the state
Tracking the CoinsManagerAction in state is a sensible approach, clarifying the current mode (add/remove/none) for subsequent logic.


113-114: switchingFuture
You're awaiting the synchronous activation/deactivation in a future. Double-check that no heavy blocking occurs; if so, convert to async to avoid UI freeze.


130-133: Logical flow in _onCoinSelect
Removing a coin from selectedCoins leads to deactivation if action == add. This reversed logic might be intentionally correct, but verify the user flow is expected when toggling coin selections.


138-141: Activating or deactivating coin in else block
Activating coins if action == add is logically consistent with the prior block. Implementation clarity is good; just ensure it aligns with end-user expectations.


160-161: Resetting selected coin types
After clearing selectedCoinTypes, your approach of re-triggering _onCoinsUpdate ensures the coin list updates immediately. Nicely done.


163-164: _onSearchUpdate
Emitting the new search phrase then calling _onCoinsUpdate is consistent with filtering logic. Code is straightforward.


168-169: Reusing the action
Reuse of state.action helps maintain consistent filtering logic. This cohesively ties back into the existing add/remove modes.


205-209: _getOriginalCoinList becomes async
Valid approach for fetching coin data. Consider a fallback or error state if _sdk.currentWallet() is null.


223-230: _getDeactivatedCoins
Removing known coins where _sdk.assets.getEnabledCoins() is present is a good approach. Double-check if concurrency or partial data can cause missing coin data.

lib/bloc/auth_bloc/auth_bloc.dart (22)

3-7: Imports for Equatable, KomodoDefiSdk, and additional types
Ensuring your authentication logic has the right references is crucial. These imports align with the refactor to KomodoDefiSdk.


12-13: Part directives
This organizes event/state code in separate files. Looks standard and clear.


15-16: Bloc documentation
Well-documented purpose for AuthBloc. This helps maintain clarity in a complex authentication flow.


18-19: Detailed constructor doc
Documenting the _kdfSdk usage clarifies dependencies.


20-26: AuthBloc constructor & event registrations
A consolidated approach that registers multiple events, each mapped to specific handlers, is a standard & maintainable pattern for BLoC.


29-31: Private fields for SDK and repository
Storing _kdfSdk and _walletsRepository ensures controlled usage. The optional StreamSubscription is also properly placed as a private field.


35-36: Overriding close()
Canceling _authorizationSubscription is essential to avoid leaks. Good catch.


39-40: _onLogout event
Renaming from AuthLogOutEvent to AuthSignOutRequested clarifies the user’s intention to sign out. Good approach.


46-49: Signing out with KdfSdk
Proper usage of _kdfSdk.auth.signOut(). Emitting AuthorizeMode.noLogin state is straightforward.

Also applies to: 52-54


53-53: After sign-out
You’re resetting currentUser to null. Consistent with the “noLogin” mode.


56-58: _onLogIn event
Switching to AuthSignInRequested event is a meaningful rewrite. The delegation to _onRestore event if isLegacyWallet is an elegant fallback strategy.

Also applies to: 60-69


71-82: _kdfSdk signIn usage
Using AuthOptions with a derivation method is a solid approach. Emitting AuthorizeMode.logIn after a successful sign-in clarifies user state changes.

Also applies to: 83-89


100-104: _onAuthChanged
Straightforward approach to update the mode/currentUser upon AuthModeChanged. This ensures the UI reacts quickly.


107-122: _onRegister event
The new registration logic checks for existing wallets first, logs suitably, and delegates to sign-in if the wallet already exists. This is well-structured.


124-133: Register flow
Using _kdfSdk.auth.register(...) is consistent with the rest of the code. Emitting AuthorizeMode.logIn ensures the app transitions to a logged-in state if registration was successful.

Also applies to: 134-137


138-140: Setting wallet type & confirming backup
Post-registration steps for wallet type and backup info are correctly placed here.


141-146: _listenToAuthStateChanges call
Resubscribing after a successful register is key to remain in sync with future auth changes.


158-160: _onRestore event
Checks if wallet exists, otherwise calls _kdfSdk.auth.register with a mnemonic. Interoperability for legacy wallets is nicely handled.

Also applies to: 162-173


175-184: Completing restore logic
Once restored, the code sets the wallet type, confirms seed backup, and logs success. This sequence is cohesive and consistent with the register flow.

Also applies to: 185-188, 189-190


191-203: Activating coins for legacy wallets
If event.wallet.isLegacyWallet, coins are reactivated and the old wallet is removed from the repository. This helps avoid duplicates.


208-209: Re-subscribing after restoration
Again, reattaching _listenToAuthStateChanges() ensures future updates are listened to.


220-227: _listenToAuthStateChanges
The subscription clean and re-assign approach is robust. Emitting an AuthModeChanged event on subscription changes keeps state logic in one place.

lib/bloc/cex_market_data/mockup/generate_demo_data.dart (7)

3-5: Using Decimal and Defi Types
decimal provides precise arithmetic for financial operations, while komodo_defi_types aligns with the broader refactor. Good choice for accuracy.


17-17: Introducing CexRepository
Replacing BinanceRepository with CexRepository unifies your data flow for OHLC data. Verify all relevant methods are implemented in CexRepository.


134-135: Adjustment factor with Decimal
Converting to Decimal before applying ratio-based calculations ensures consistent rounding in financial contexts. Good approach.


138-141: Capturing old balance fields
Storing netChange, received, spent, and totalAmount in local variables improves readability of subsequent adjustments.


144-161: Rebuilding Transaction with adjusted balances
Multiplying each balance field by an adjustmentFactor is a sensible way to re-scale transactions. This approach is clear and maintainable.


170-176: Filtering supported coins
By checking supportedCoin.isEmpty, you ensure no invalid coin pairs are processed. Confirm that the user experience is clear when ignoring unsupported coins.


198-234: fromTradeAmount with Decimal-based BalanceChanges
Using Decimal.parse for net/spent/received computations improves numerical accuracy. The new assetId usage aligns with the refined structure for transactions.

lib/bloc/coins_bloc/coins_bloc.dart (1)

29-30: Confirm concurrency strategies
You are using droppable() for _onCoinsStarted. This will drop subsequent events if one is still processing. Verify that this behavior is correct for your scenario, as it could skip needed state updates when the bloc is busy.

lib/bloc/auth_bloc/auth_bloc_state.dart (1)

4-4: LGTM! Well-structured authentication state management.

The changes effectively integrate user state tracking:

  • Nullable currentUser property with proper type safety
  • Clear isSignedIn computed property
  • Updated props to handle nullable types correctly

Also applies to: 9-9, 12-12, 15-15

lib/bloc/coin_addresses/bloc/coin_addresses_event.dart (3)

3-8: LGTM! Well-structured base event class.

Good use of Equatable for efficient comparison and abstract class for type safety.


10-16: LGTM! Clear and concise event definitions.

Simple events with const constructors follow best practices.


18-25: LGTM! Well-implemented state-carrying event.

Proper implementation with:

  • Final property for immutability
  • Correctly overridden props
lib/bloc/auth_bloc/auth_bloc_event.dart (2)

7-12: LGTM! Clear mode change event with user state.

Good addition of currentUser parameter to track authentication state.


14-42: LGTM! Well-structured authentication events.

Clear separation of concerns between different authentication operations:

  • Sign in/out
  • Registration
  • Restoration with seed
lib/bloc/coins_manager/coins_manager_event.dart (2)

7-10: LGTM! Clear reset event implementation.

Well-structured event carrying the reset action.


12-15: LGTM! Consistent update event structure.

Good addition of action parameter matching the reset event pattern.

lib/bloc/cex_market_data/profit_loss/models/price_stamped_transaction.dart (3)

2-2: LGTM! Import updated to use the new package.

The import has been correctly updated to use the new komodo_defi_types package, aligning with the broader refactoring effort.


11-23: LGTM! Constructor parameters updated for better type safety.

The constructor parameters have been correctly updated to use more specific fields from the Transaction class, improving type safety and data integrity.


29-30: LGTM! Calculations updated to use new properties.

The calculations have been correctly updated to use balanceChanges.totalAmount and amount properties, maintaining consistency with the new data structure.

lib/bloc/coins_bloc/coins_state.dart (3)

3-19: LGTM! Well-structured state class with immutable properties.

The class follows best practices:

  • Uses final for immutability
  • Extends Equatable for value comparison
  • Has clear property declarations

31-42: LGTM! Well-implemented copyWith method.

The copyWith method correctly handles optional parameters and maintains immutability.


44-46: LGTM! Proper Equatable implementation.

The props override correctly includes all state properties for value comparison.

lib/bloc/cex_market_data/profit_loss/extensions/profit_loss_transaction_extension.dart (3)

1-1: LGTM! Import updated to use the new package.

The import has been correctly updated to use the komodo_defi_types package.


6-6: LGTM! Getters updated to use new properties.

The getters have been correctly updated to use the new properties from balanceChanges and amount, maintaining type safety.

Also applies to: 10-10, 14-14, 18-18


21-22: LGTM! Timestamp handling improved.

The timeStampMidnight getter now correctly uses the timestamp property directly.

lib/bloc/dex_tab_bar/dex_tab_bar_event.dart (3)

20-20: LGTM! Type updated to use interface.

The tabType property has been correctly updated to use ITabTypeEnum, improving abstraction.


27-33: LGTM! Simple event classes added.

The ListenToOrdersRequested and StopListeningToOrdersRequested events are correctly implemented as simple events without properties.


35-57: LGTM! Order-related event classes added.

The new event classes (MyOrdersUpdated, SwapsUpdated, TradeBotOrdersUpdated) are well-structured:

  • Each has appropriate properties
  • Properly overrides props
  • Follows consistent naming convention
lib/bloc/cex_market_data/mockup/generator.dart (1)

6-6: LGTM! Import changes align with SDK migration.

The switch from mm2_api/rpc/my_tx_history/transaction.dart to komodo_defi_types package aligns with the PR objective of SDK migration and codebase unification.

lib/bloc/assets_overview/investment_repository.dart (1)

30-34: LGTM! Standardized coin identifier usage.

The change from coin.abbr to coin.id aligns with standardization efforts across the codebase. The error handling ensures that issues with individual coins don't affect the overall calculation.

lib/bloc/coin_addresses/bloc/coin_addresses_bloc.dart (2)

18-42: LGTM! Well-structured error handling in address creation.

The implementation properly manages state transitions and error handling during address creation.


44-71: LGTM! Comprehensive address loading implementation.

The method effectively handles both successful and error cases while loading addresses and their creation constraints.

lib/bloc/coins_bloc/coins_event.dart (1)

3-79: LGTM! Well-structured and documented event hierarchy.

The implementation demonstrates excellent practices:

  • Uses sealed class for type safety
  • Proper documentation for each event
  • Correct implementation of Equatable
  • Comprehensive coverage of coin management scenarios
lib/bloc/coin_addresses/bloc/coin_addresses_state.dart (3)

4-4: LGTM!

The FormStatus enum provides a clear and comprehensive set of states for form processing.


6-21: LGTM!

The CoinAddressesState class is well-structured with immutable properties and a clear constructor. The use of Equatable for value comparison is appropriate.


68-76: LGTM!

The props override correctly includes all properties for value comparison.

lib/bloc/cex_market_data/profit_loss/models/profit_loss.dart (1)

76-93: LGTM!

The changes in the fromTransaction factory method correctly adapt to the new transaction structure:

  • Using assetId.id instead of coin
  • Using amount.toDouble() instead of balanceChange
  • Using timestamp directly
  • Providing a default empty string for txHash
lib/bloc/dex_repository.dart (2)

26-28: LGTM!

Good use of dependency injection by accepting Mm2Api through the constructor and storing it in a private final field.


32-32: LGTM!

All method calls have been correctly updated to use the injected _mm2Api instance.

Also applies to: 57-57, 90-90, 100-100, 115-115, 148-148

lib/bloc/cex_market_data/price_chart/price_chart_bloc.dart (1)

11-12: LGTM!

Good use of dependency injection by accepting KomodoDefiSdk through the constructor and storing it in a final field.

Also applies to: 19-19

lib/bloc/cex_market_data/profit_loss/profit_loss_calculator.dart (2)

174-174: LGTM! Constructor refactoring.

The constructors have been simplified using the super keyword, which is a cleaner approach.

Also applies to: 186-186


206-209: LGTM! Record syntax for state fields.

The state fields are now using record syntax, which provides better type safety and immutability.

lib/bloc/cex_market_data/profit_loss/profit_loss_repository.dart (2)

28-28: LGTM! Added CoinsRepo dependency.

The addition of CoinsRepo dependency improves the repository's capability to interact with coin data.

Also applies to: 32-33, 39-39


42-45: LGTM! Updated Hive registration.

The Hive registration has been updated to use a more concise syntax with method chaining.

lib/bloc/cex_market_data/profit_loss/profit_loss_bloc.dart (1)

110-116: LGTM! Enhanced error logging.

The error logging has been improved to include stack traces, which will help with debugging.

lib/bloc/market_maker_bot/market_maker_bot/market_maker_bot_repository.dart (2)

27-27: LGTM! Improved type safety with Duration.

The change from int to Duration for delay parameters enhances type safety and makes the intent clearer.

Also applies to: 52-52, 80-80, 119-119


36-36: LGTM! Enhanced null safety with null-aware operator.

The use of null-aware operator ?? improves the robustness of empty trade pairs check.

Also applies to: 95-95, 132-132, 176-176

lib/bloc/cex_market_data/charts.dart (2)

3-3: LGTM! Updated import to use komodo_defi_types.

The import change aligns with the broader SDK migration.


252-253: LGTM! Improved timestamp handling consistency.

The changes ensure consistent handling of timestamps by directly using millisecondsSinceEpoch throughout the code.

Also applies to: 267-267, 269-270, 298-299

lib/bloc/app_bloc_root.dart (1)

72-73: LGTM! Clean SDK integration.

The introduction of KomodoDefiSdk as a required parameter improves dependency management.

Also applies to: 77-77

@@ -83,7 +93,7 @@ class PortfolioGrowthRepository {
///
/// Returns the growth [ChartData] for the coin ([List] of [Point]).
Future<ChartData> getCoinGrowthChart(
String coinId, {
AssetId coinId, {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix inconsistent cache key generation.

There's an inconsistency in cache key generation:

  • Line 108: Uses coinId.id for generating the cache key
  • Line 187: Uses coin.abbr for storing in cache

This could lead to cache misses when retrieving data.

Apply this diff to fix the inconsistency:

-        coinId: coin.abbr,
+        coinId: coin.id.id,

Also applies to: 108-108, 124-124, 142-142, 187-187

Comment on lines +248 to 251
// Exception primarily thrown for cache misses
// TODO: create a custom exception for cache misses to avoid catching
// this broad exception type
return Future.value(ChartData.empty());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Implement custom exception for cache misses.

The TODO comment suggests creating a custom exception for cache misses. This would improve error handling by allowing specific handling of cache-related errors.

Create a new exception class:

class CacheMissException implements Exception {
  final String key;
  
  CacheMissException(this.key);
  
  @override
  String toString() => 'Cache miss for key: $key';
}

Then update the error handling:

-        throw Exception('Cache miss for $compoundKey');
+        throw CacheMissException(compoundKey);

// In getPortfolioGrowthChart:
-      } on Exception {
+      } on CacheMissException {
         // Exception primarily thrown for cache misses
         return Future.value(ChartData.empty());

Comment on lines +229 to 230
final Coin? coin = _coinsRepo.getCoin(abbr);

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace deprecated getCoin method with SDK alternatives.

The getCoin method is deprecated. Use KomodoDefiSdk assets or getCoinFromId instead.

Apply this diff to update the code:

-    final Coin? coin = _coinsRepo.getCoin(abbr);
+    final Coin? coin = _coinsRepo.getCoinFromId(abbr);

-    final coin = _coinsRepo.getCoin(selectedOrder.coin);
+    final coin = _coinsRepo.getCoinFromId(selectedOrder.coin);

Also applies to: 269-270

🧰 Tools
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀

[info] 229-229: 'getCoin' is deprecated and shouldn't be used. Use KomodoDefiSdk assets or getCoinFromId instead.

@@ -40,7 +40,7 @@ flutter run -d chrome --web-hostname=0.0.0.0 --web-port=7777
### Generate self-signed certificate with openssl

```bash
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname"
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha512 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=http://localhost.com"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve the Common Name (CN) in the certificate subject.

The CN value "http://localhost.com" is problematic:

  1. It includes the "http://" protocol which is not standard in CN
  2. Using ".com" TLD for localhost is unconventional

Apply this diff to fix the CN value:

-openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha512 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=http://localhost.com"
+openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha512 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=localhost"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha512 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=http://localhost.com"
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha512 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=localhost"

Comment on lines +246 to +253
{
"dart.flutterSdkPath": ".fvm/versions/stable",
"[dart]": {
"editor.defaultFormatter": "Dart-Code.dart-code",
"editor.formatOnSave": true
}
}
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Document FVM prerequisites.

The settings.json assumes Flutter Version Management (FVM) is set up but doesn't mention this requirement.

Add a note about FVM setup requirements and verify the FVM documentation is accessible:


🏁 Script executed:

#!/bin/bash
# Check if FVM documentation exists in the repository
rg -l "fvm" README.md docs/

Length of output: 140


Action Required: Add FVM Prerequisites Note in Manual Testing Documentation

File: docs/MANUAL_TESTING_DEBUGGING.md
Lines: 246-253

The code snippet below assumes that Flutter Version Management (FVM) is properly set up:

{
  "dart.flutterSdkPath": ".fvm/versions/stable",
  "[dart]": {
    "editor.defaultFormatter": "Dart-Code.dart-code",
    "editor.formatOnSave": true
  }
}

Our verification confirms that FVM documentation is available in several locations (e.g., docs/INSTALL_FLUTTER.md, docs/MULTIPLE_FLUTTER_VERSIONS.md, and docs/PROJECT_SETUP.md). However, this file does not alert the user to the requirement that FVM must be configured. Please add a clear note near this configuration snippet to inform users of the FVM prerequisite and provide a reference (for example, linking to docs/INSTALL_FLUTTER.md) for further setup details.

Comment on lines +93 to +100
AssetId coinId,
String fiatCoinId, {
bool allowFiatAsBase = false,
bool allowInactiveCoins = false,
}) async {
if (!allowInactiveCoins) {
final coin = coinsBlocRepository.getCoin(coinId)!;
if (coin.isActivating || !coin.isActive) {
final coin = await _coinsRepository.getEnabledCoin(coinId.id);
if (coin == null || coin.isActivating || !coin.isActive) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

❓ Verification inconclusive

Verify the AssetId migration.

The code has been updated to use AssetId instead of String for coin IDs. This change affects:

  • Method parameters
  • Cache key generation
  • Cache storage
  • Profit/loss calculations

Ensure that all consumers of this API are updated to handle the new AssetId type.

Run the following script to verify the migration:

Also applies to: 133-134, 140-141, 171-172, 184-185, 190-191


🏁 Script executed:

#!/bin/bash
# Description: Check for any remaining uses of String coinId in the codebase.

ast-grep --pattern 'coinId: String'

Length of output: 37


AssetId Migration Verification – Manual Review Required

The recent migration seems to have replaced all occurrences of String coinId with AssetId, as the executed shell script did not return any hits for coinId: String. However, the absence of output from the script necessitates a manual check to ensure that the migration is comprehensive. In particular, please confirm that:

  • All method parameters across the codebase correctly use AssetId instead of String.
  • Cache key generation and cache storage logic have been updated to handle AssetId.
  • Profit/loss calculation logic functions correctly with the new AssetId type.
  • The updates on lines 133-134, 140-141, 171-172, 184-185, and 190-191 have been verified.

This manual review will ensure that all consumers of this API are fully updated to support the new AssetId type.

Comment on lines +211 to +218
final startIndex = profitLosses.indexOf(
profitLosses.firstWhere((element) => element.profitLoss != 0),
);

if (startIndex == -1) {
profitLosses.removeRange(0, startIndex);
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix potential index error in profit/loss calculation.

The code attempts to remove a range from profitLosses when startIndex is -1, which would cause an error.

Apply this diff to fix the issue:

-          if (startIndex == -1) {
-            profitLosses.removeRange(0, startIndex);
-          }
+          if (startIndex > 0) {
+            profitLosses.removeRange(0, startIndex);
+          }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
final startIndex = profitLosses.indexOf(
profitLosses.firstWhere((element) => element.profitLoss != 0),
);
if (startIndex == -1) {
profitLosses.removeRange(0, startIndex);
}
final startIndex = profitLosses.indexOf(
profitLosses.firstWhere((element) => element.profitLoss != 0),
);
if (startIndex > 0) {
profitLosses.removeRange(0, startIndex);
}

@@ -39,7 +39,7 @@ class AssetOverviewBloc extends Bloc<AssetOverviewEvent, AssetOverviewState> {

try {
final profitLosses = await profitLossRepository.getProfitLoss(
event.coin.abbr,
event.coin.id,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

⚠️ Potential issue

🧩 Analysis chain

Verify the coin ID migration.

The code has been updated to use coin.id instead of coin.abbr. However, line 128 still uses coin.abbr for selectedAssetIds. This inconsistency could lead to issues.

Apply this diff to maintain consistency:

-          selectedAssetIds: event.coins.map((coin) => coin.abbr).toList(),
+          selectedAssetIds: event.coins.map((coin) => coin.id.id).toList(),

Run the following script to verify the migration:

Also applies to: 99-99


🏁 Script executed:

#!/bin/bash
# Description: Check for any remaining uses of coin.abbr in the codebase.

rg -A 5 'coin\.abbr'

Length of output: 61234


Critical Update: Ensure Consistent Coin ID Migration

The migration already updated some parts to use coin.id (e.g. see the usage on line 42), but in the asset overview bloc the mapping for selectedAssetIds is still using coin.abbr, which is inconsistent with the new coin ID strategy.

  • In lib/bloc/assets_overview/bloc/asset_overview_bloc.dart, update the following locations:
    • Line 128 (and similarly Line 99) currently use:
        selectedAssetIds: event.coins.map((coin) => coin.abbr).toList(),
      This should be updated to:
        selectedAssetIds: event.coins.map((coin) => coin.id.id).toList(),
  • Additionally, note that the script search shows many other occurrences of coin.abbr in the codebase. Please verify that similar migrations are applied where required.

mm2Api,
myOrdersService,
);
final currentWalletBloc = RepositoryProvider.of<CurrentWalletBloc>(context);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace deprecated CurrentWalletBloc usage.

CurrentWalletBloc is deprecated. As per the pipeline failure, use AuthBloc or KomodoDefiSdk instead.

-final currentWalletBloc = RepositoryProvider.of<CurrentWalletBloc>(context);
+final authBloc = RepositoryProvider.of<AuthBloc>(context);

And:

-walletRepo: RepositoryProvider.of<CurrentWalletBloc>(context),
+authBloc: RepositoryProvider.of<AuthBloc>(context),

Also applies to: 264-264

🧰 Tools
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀

[info] 115-115: 'CurrentWalletBloc' is deprecated and shouldn't be used. Please use AuthBloc or KomodoDefiSdk instead.

Comment on lines +398 to +401
// completeError throws an uncaught exception, which causes the UI
// tests to fail when switching between light and dark theme
log('New request to precache icons started.');
_currentPrecacheOperation!.complete();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling in _precacheCoinIcons.

The comment about completeError throwing an uncaught exception should be addressed with proper error handling.

if (_currentPrecacheOperation != null &&
    !_currentPrecacheOperation!.isCompleted) {
-  // completeError throws an uncaught exception, which causes the UI
-  // tests to fail when switching between light and dark theme
-  log('New request to precache icons started.');
-  _currentPrecacheOperation!.complete();
+  log('Cancelling previous precache operation');
+  try {
+    await _currentPrecacheOperation!.future;
+  } catch (e) {
+    log('Previous precache operation failed: $e');
+  }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// completeError throws an uncaught exception, which causes the UI
// tests to fail when switching between light and dark theme
log('New request to precache icons started.');
_currentPrecacheOperation!.complete();
if (_currentPrecacheOperation != null &&
!_currentPrecacheOperation!.isCompleted) {
log('Cancelling previous precache operation');
try {
await _currentPrecacheOperation!.future;
} catch (e) {
log('Previous precache operation failed: $e');
}
}

takenagain and others added 2 commits February 16, 2025 14:49
* init custom token import feature

* add custom token import warning

* custom token import better state & error handling

* custom token import details page

* custom token import loading status

* custom token import reset form

* custom token import network uses CoinType

* remove unused import

* custom token import buttons

* custom token import redesign

* custom token import dialog close on success

* add cointype to evm platform coin conversion

* custom token import CoinsRepo getTokenInfo

* custom token import KdfCustomTokenImportRepository

* custom token import use real repository

* custom token import remove decimals field

* custom token import activate platform coin

* custom token import fetch and display coin icon

* add logoImageUrl field to Coin

* custom token import tokenData as Coin

* custom token import construct Coin and get balance

* Merge branch 'dev' into feature/custom-token-import

* custom token import remove balance fetch delay

* custom token import use ImageProvider for logo

* custom token import hide unsupported networks

* custom token import fill swap contract addresses

* custom token import EnableErc20Req ProtocolData

* custom token import _getCoin function

* custom token import rename tokenData to coin

* custom token import enable coin

* custom coin icon support by Charl

* custom token import register coin icon

* custom token import remove logoImage field

* custom token import handle known coins

* Merge branch 'dev' into feature/custom-token-import

* custom token import persistence init

* custom token import sync coinsBloc knownCoins

* fiat page fix coin rows network text

* migrate custom token RPCs to the SDK

* add custom token activation via SDK activation manager

* refactor: move SDK metadata extensions to a separate file

* activate and load custom coins in known coins list

* refactor: move custom token storage to SDK

* refactor: migrate mock transaction generation to SDK transaction model

* refactor: add AssetId to legacy Coin model

ease transition to SDK by allowing supporting code to transition to using AssetId rather than Coin or coin ticker / abbreviation

* fix(coins-bloc): use kdf assets if coin is not in state cache

* fix: merge conflict resolution errors

* fix(router): use ValueKey for MainLayout

fixes non-responsive UI due to immutable MainLayout ignoring routing and layout size changes

* fix(price-charts): filter out CEX coins not in known assets list

the use of `.single` in `getSdkAsset` would result in exceptions for coins that were not in the known assets list

* fix: missing custom token icon on hard refresh

add the token icon url to the protocol metadata for extraction from the SDK on refresh

* fix: broken non-ETH support by hardcoding protocol type to ERC20

similar to the previous implementation

* fix: merge conflict regression to slower getEnabledCoins function

* style: apply formatting to modified files

* fix(import-dialog): shrink dead space above button to 24px

* fix(fetch-custom-token): activate network coin before fetching info

---------

Co-authored-by: naezith <[email protected]>
…ease (#2529)

* Upgrade Flutter and all packages

* fix: resolve Flutter 3.29 breaking changes

* chore(deps): Lock package versions for release

Lock package versions for release and upgrade the first party `dragon_logs` package to the latest release.

* fix(macos): Keep pods macos version and xcode version synced

Fix issue with pods macos version not matching the version specified in the xcode build configuration. Now, the pods referencing the value directly.

* chore(macos): Apply macos Flutter upgrade changes

Apply macos Flutter upgrade changes and increase minimum macOS version to `15.0`

* chore(iOS): Apply iOS Flutter upgrade changes

Apply iOS Flutter upgrade changes and increase minimum iOS version to `15.6`

* chore(android): Increase min SDK version for Firebase

* chore(deps): Upgrade to latest SDK packages

* fix(macOS): Make the target macOS version consistent

* chore(rc): Bump release version
@CharlVS CharlVS marked this pull request as ready for review February 17, 2025 01:58
@KomodoPlatform KomodoPlatform deleted a comment from coderabbitai bot Feb 17, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

🧹 Nitpick comments (44)
lib/bloc/fiat/base_fiat_provider.dart (1)

214-214: Track the SDK migration task.

The TODO comment indicates pending work to migrate to SDK's ticker/formatted getters.

Would you like me to create an issue to track this SDK migration task?

lib/mm2/mm2.dart (3)

9-9: Avoid global singletons if multiple instances might be needed.
While having a single global mm2 instance can be convenient, it may reduce flexibility or complicate test scenarios if future needs require multiple instances of MM2 (e.g., multi-wallet contexts). Consider using a provider or a dependency injection approach for more modularity.


39-39: Consider removing or revisiting the 'Hack' comment.
Referencing a “Hack” can create confusion for future maintainers. If this workaround is still necessary, provide context or a TODO comment explaining its purpose and potential resolution path.


77-96: Revisit _assertPass override strategy.
Currently, _assertPass forces userpass to an empty string for all RPC requests. While it may be necessary for “noauth mode,” this could be error-prone if, in the future, any RPC request requires authentication. Consider adding a check or a parameter to conditionally set this.

lib/bloc/trezor_init_bloc/trezor_init_bloc.dart (4)

82-84: Log message references an outdated method name

The log message uses 'trezor_init_bloc => _loginToHiddenMode' but the method is _loginToTrezorWallet. Renaming this reference improves trace clarity and consistency.

-        path: 'trezor_init_bloc => _loginToHiddenMode',
+        path: 'trezor_init_bloc => _loginToTrezorWallet',

150-177: Centralize repeated logout flow for error conditions

Multiple code paths call _logout() upon encountering errors. Consolidating this pattern into a small helper could enhance readability and maintainability. Consider extracting an _onErrorAndLogout() method to handle error updates, emit states, and log out.


272-281: Avoid using hard-coded wallet name and password

Using walletName = 'My Trezor' and password = 'hidden-login' for all Trezor logins can pose security risks and might cause collisions if multiple Trezors share the same identifier. Consider allowing the user to specify or securely generate these values.


320-322: Rename method to indicate a boolean check

_checkAndHandleInvalidPin only returns a boolean rather than "handling" the invalid pin scenario. Rename it to something like _isInvalidPin for clarity, or incorporate actual handling logic for the invalid pin case.

lib/bloc/transaction_history/transaction_history_repo.dart (3)

6-7: Clarify the exception circumstances in doc comments.
Currently, the doc states this exception is thrown if fetching fails, but the method only throws when the asset is null. You might align the documentation with the actual code behavior or throw the exception in other failure scenarios as well.


8-11: Consider returning an empty list instead of null.
Declaring Future<List<Transaction>?> suggests nullable lists. Returning an empty list supports consistent handling downstream, minimizing null checks.


13-19: Use a 'final' class or mark it abstract if unextended.
If you do not intend to subclass or extend SdkTransactionHistoryRepository, consider declaring it final to communicate intent and enable certain compiler optimizations.

lib/blocs/current_wallet_bloc.dart (5)

15-15: Good transition to _kdfSdk.
Switching from local repos to the SDK centralizes wallet operations and aligns with the overarching migration strategy.

Also applies to: 20-20, 22-22


27-27: Check necessity of ignore comment.
The ignore comment for getters and setters might not be needed if you truly require the setter for other code. Consider removing if not essential.


34-34: Consider disposing of internal streams.
If this bloc holds streams or subscriptions from _kdfSdk, ensure they are canceled here to prevent potential memory leaks.


37-40: Unimplemented password update.
Throwing an UnimplementedError is fine as a placeholder. Consider adding a TODO or referencing an issue to ensure this is addressed long-term.


99-100: Confirming backup in _kdfSdk.
If wallet.config.hasBackup is already true, no further action is taken. This is correct, but confirm the new approach is used consistently across the app for clarity.

Also applies to: 104-104

lib/bloc/custom_token_import/bloc/custom_token_import_bloc.dart (2)

26-49: Resetting form status.
Collecting EVM-supported coin types and clearing errors is a good approach. Validate that sorting by name meets all UI/UX expectations.


61-66: Address updates.
Straightforward assignment of address. Consider validating address format to prevent submission errors down the line.

lib/bloc/custom_token_import/data/custom_token_import_repository.dart (3)

13-16: Consider adding method-level documentation for clarity.

While the interface methods are straightforward, adding doc comments clarifying expected behavior, error conditions, and parameter usage can aid future maintainers.


124-147: Handle partial data gracefully in fetchTokenInfoFromApi.

If CoinGecko returns unexpected data structures (or if an error occurs), the function currently logs and returns null. Consider surfacing more context or rethrowing a custom exception to help troubleshoot.


153-179: Consider a map-based lookup instead of a switch.

The getNetworkApiName switch is thorough but verbose. A static map (e.g., Map<CoinSubClass, String>), combined with a fallback, can simplify maintenance.

lib/bloc/withdraw_form/withdraw_form_state.dart (2)

9-35: Document the new fields for better maintainability.

Properties like isMaxAmount, isCustomFee, and isIbcTransfer could benefit from doc comments describing how they’re used or the assumptions behind them.


158-166: Address the TODO placeholders.

The TODOs (usdFeePrice, usdAmountPrice, isFeePriceExpensive) hint at planned features or incomplete logic. Consider adding skeleton implementations or clarifying next steps to avoid shipping partial features.

lib/bloc/trezor_bloc/trezor_repo.dart (2)

39-42: Refactor constructor injection if more dependencies appear.

The constructor is already configuring Mm2ApiTrezor and KomodoDefiSdk. If new dependencies emerge, consider a builder or module-based injection pattern to keep the constructor clean and flexible.


139-142: Broaden isTrezorWallet checks if additional wallet types are introduced.

Currently, it compares against WalletType.trezor. If new Trezor subtypes or multi-wallet configurations appear, consider robust logic to detect Trezor capabilities.

lib/bloc/withdraw_form/withdraw_form_bloc.dart (2)

235-248: Edge case handling in _onMaxAmountEnabled.
Consider clarifying behavior if spendable balance is zero (currently it sets amount to null string if no balance).


426-433: Cancellation is partially implemented.
The TODO hints at a need for actual cancellation if supported by _sdk.

Do you want to implement logic to cancel an in-progress withdrawal? I can help generate a pattern if the SDK supports it.

lib/mm2/mm2_api/mm2_api.dart (2)

80-92: disableCoin function swallows errors.
Consider returning or rethrowing errors if the caller needs to handle them.


173-197: sendRawTransaction
Returns a typed response. Consider including the actual error message in error instead of always 'null response' for more clarity.

lib/bloc/coins_bloc/coins_state.dart (2)

42-42: Address the TODO comment regarding SDK migration.

The comment indicates pending SDK migration work. Consider prioritizing this migration to maintain consistency with the rest of the codebase.

Would you like me to help create an issue to track the SDK migration task?


43-52: Consider refactoring price calculation for better maintainability.

The current implementation could be more concise using null-aware operators.

-  double? getUsdPriceByAmount(String amount, String coinAbbr) {
-    final Coin? coin = coins[coinAbbr];
-    final double? parsedAmount = double.tryParse(amount);
-    final double? usdPrice = coin?.usdPrice?.price;
-
-    if (coin == null || usdPrice == null || parsedAmount == null) {
-      return null;
-    }
-    return parsedAmount * usdPrice;
+  double? getUsdPriceByAmount(String amount, String coinAbbr) {
+    final double? parsedAmount = double.tryParse(amount);
+    final double? usdPrice = coins[coinAbbr]?.usdPrice?.price;
+    return (parsedAmount != null && usdPrice != null) 
+        ? parsedAmount * usdPrice 
+        : null;
   }
lib/bloc/coins_bloc/asset_coin_extension.dart (1)

51-52: Improve null safety in contract address getter.

The nested valueOrNull calls could lead to runtime errors if any intermediate value is null. Consider using a more defensive approach.

Apply this diff to improve null safety:

-  String? get contractAddress => protocol.config
-      .valueOrNull('protocol', 'protocol_data', 'contract_address');
+  String? get contractAddress {
+    final config = protocol.config;
+    if (config == null) return null;
+    final protocolData = config.valueOrNull('protocol', 'protocol_data');
+    if (protocolData == null) return null;
+    return protocolData.valueOrNull('contract_address');
+  }
lib/bloc/cex_market_data/mockup/generate_demo_data.dart (2)

134-135: Improve decimal conversion safety.

The conversion from double to Decimal using toString() could lead to precision loss or overflow. Consider using a safer conversion method.

Apply this diff to improve decimal conversion:

-    final Decimal adjustmentFactor =
-        Decimal.parse((targetFinalBalance / totalBalance).toString());
+    final Decimal adjustmentFactor = targetFinalBalance == 0 || totalBalance == 0
+        ? Decimal.zero
+        : (Decimal.parse(targetFinalBalance.toString()) /
+            Decimal.parse(totalBalance.toString()))
+            .toDecimal(scaleOnInfinitePrecision: 18);

211-212: Optimize wallet type check.

The wallet type check can be optimized by returning early if the wallet type is null.

Apply this diff to improve readability:

-  final WalletType? walletType = (await sdk.currentWallet())?.config.type;
-  if (walletType == null) return [];
+  final wallet = await sdk.currentWallet();
+  if (wallet == null) return [];
+  final walletType = wallet.config.type;
lib/bloc/coins_manager/coins_manager_bloc.dart (2)

113-115: Consider using async coin activation.

The coin activation/deactivation is performed synchronously which could block the UI thread. Consider using async methods instead.

Apply this diff to improve performance:

-        ? _coinsRepo.activateCoinsSync(selectedCoins)
-        : _coinsRepo.deactivateCoinsSync(selectedCoins);
+        ? _coinsRepo.activateCoins(selectedCoins)
+        : _coinsRepo.deactivateCoins(selectedCoins);

83-90: Optimize coin list reset.

The coin list reset could be optimized by avoiding unnecessary state emissions.

Apply this diff to improve performance:

-    emit(CoinsManagerState.initial(coins: [], action: event.action));
-    final List<Coin> coins = await _getOriginalCoinList(
-      _coinsRepo,
-      event.action,
-      _sdk,
-    )
-      ..sort((a, b) => a.abbr.compareTo(b.abbr));
-    emit(state.copyWith(coins: coins, action: event.action));
+    final List<Coin> coins = await _getOriginalCoinList(
+      _coinsRepo,
+      event.action,
+      _sdk,
+    );
+    coins.sort((a, b) => a.abbr.compareTo(b.abbr));
+    emit(CoinsManagerState.initial(coins: coins, action: event.action));
lib/bloc/auth_bloc/auth_bloc.dart (2)

90-98: Extract duplicate error handling logic.

The error handling logic is duplicated across multiple event handlers. Consider extracting it into a reusable method.

Apply this diff to improve code reuse:

+  void _handleError(String operation, String walletName, Object error, StackTrace trace) {
+    log(
+      'Failed to $operation wallet $walletName',
+      isError: true,
+      trace: trace,
+      path: 'auth_bloc -> $operation',
+    ).ignore();
+    emit(const AuthBlocState(mode: AuthorizeMode.noLogin));
+  }

-    } catch (e, s) {
-      log(
-        'Failed to login wallet ${event.wallet.name}',
-        isError: true,
-        trace: s,
-        path: 'auth_bloc -> onLogin',
-      ).ignore();
-      emit(const AuthBlocState(mode: AuthorizeMode.noLogin));
+    } catch (e, s) {
+      _handleError('login', event.wallet.name, e, s);
     }

-    } catch (e, s) {
-      log(
-        'Failed to register wallet ${event.wallet.name}',
-        isError: true,
-        trace: s,
-        path: 'auth_bloc -> onRegister',
-      ).ignore();
-      emit(const AuthBlocState(mode: AuthorizeMode.noLogin));
+    } catch (e, s) {
+      _handleError('register', event.wallet.name, e, s);
     }

-    } catch (e, s) {
-      log(
-        'Failed to restore existing wallet ${event.wallet.name}',
-        isError: true,
-        trace: s,
-        path: 'auth_bloc -> onRestore',
-      ).ignore();
-      emit(const AuthBlocState(mode: AuthorizeMode.noLogin));
+    } catch (e, s) {
+      _handleError('restore', event.wallet.name, e, s);
     }

Also applies to: 148-156, 210-218


221-228: Improve auth state changes subscription management.

The auth state changes subscription could leak if _listenToAuthStateChanges is called multiple times. Consider using a more robust subscription management approach.

Apply this diff to improve subscription management:

   void _listenToAuthStateChanges() {
-    _authorizationSubscription?.cancel();
-    _authorizationSubscription = _kdfSdk.auth.authStateChanges.listen((user) {
+    if (_authorizationSubscription != null) return;
+    _authorizationSubscription = _kdfSdk.auth.authStateChanges.listen(
+      (user) {
       final AuthorizeMode event =
           user != null ? AuthorizeMode.logIn : AuthorizeMode.noLogin;
       add(AuthModeChanged(mode: event, currentUser: user));
-    });
+      },
+      onError: (error, stackTrace) {
+        log(
+          'Auth state changes stream error',
+          isError: true,
+          trace: stackTrace,
+          path: 'auth_bloc -> _listenToAuthStateChanges',
+        ).ignore();
+      },
+    );
   }
lib/bloc/nft_withdraw/nft_withdraw_bloc.dart (3)

43-45: Consider reordering field declarations.

The field declarations could be reordered to group related fields together. Consider placing _kdfSdk and _coinsRepository next to each other since they are both repository/SDK dependencies.

Apply this diff to improve readability:

-  final NftWithdrawRepo _repo;
-  final KomodoDefiSdk _kdfSdk;
-  final CoinsRepo _coinsRepository;
+  final KomodoDefiSdk _kdfSdk;
+  final CoinsRepo _coinsRepository;
+  final NftWithdrawRepo _repo;

258-274: Enhance error handling in address conversion.

The error handling in _onConvertAddress could be more specific. Consider catching specific exceptions and providing more descriptive error messages.

Apply this diff to improve error handling:

   try {
     final subclass = state.nft.parentCoin.type.toCoinSubClass();
     final result = await _kdfSdk.client.rpc.address.convertAddress(
       from: state.address,
       coin: subclass.ticker,
       toFormat: AddressFormat.fromCoinSubClass(subclass),
     );
     add(NftWithdrawAddressChanged(result.address));
-  } catch (e) {
+  } catch (e) when (e is ArgumentError) {
+    emit(
+      state.copyWith(
+        address: () => '',
+        addressError: () => TextError(error: 'Invalid address format: ${e.message}'),
+      ),
+    );
+  } catch (e) when (e is FormatException) {
+    emit(
+      state.copyWith(
+        address: () => '',
+        addressError: () => TextError(error: 'Address conversion failed: ${e.message}'),
+      ),
+    );
+  } catch (e) {
     emit(
       state.copyWith(
         address: () => '',
         addressError: () => TextError(error: e.toString()),
       ),
     );
   }

276-282: Add error handling to coin activation.

The _activateParentCoinIfNeeded method should include error handling to gracefully handle activation failures.

Apply this diff to add error handling:

   Future<void> _activateParentCoinIfNeeded(NftToken nft) async {
     final parentCoin = state.nft.parentCoin;
 
     if (!parentCoin.isActive) {
-      await _coinsRepository.activateCoinsSync([parentCoin]);
+      try {
+        await _coinsRepository.activateCoinsSync([parentCoin]);
+      } catch (e) {
+        log(
+          'Failed to activate parent coin: ${parentCoin.abbr}',
+          isError: true,
+        ).ignore();
+        throw StateError('Failed to activate parent coin: ${e.toString()}');
+      }
     }
   }
lib/bloc/coins_bloc/coins_bloc.dart (2)

59-62: Consider using a single timer for updates.

Multiple timers are used for different update operations. Consider consolidating them into a single timer that handles all periodic updates to reduce resource usage.

Apply this diff to consolidate timers:

-  StreamSubscription<Coin>? _enabledCoinsSubscription;
-  Timer? _updateBalancesTimer;
-  Timer? _updatePricesTimer;
-  Timer? _reActivateSuspendedTimer;
+  StreamSubscription<Coin>? _enabledCoinsSubscription;
+  Timer? _updateTimer;
+
+  static const _updateInterval = Duration(minutes: 1);
+  static const _reactivateInterval = Duration(seconds: 30);
+  DateTime _lastReactivateTime = DateTime.now();

Then update the timer initialization:

-    _updateBalancesTimer?.cancel();
-    _updateBalancesTimer = Timer.periodic(
-      const Duration(minutes: 1),
-      (timer) {
+    _updateTimer?.cancel();
+    _updateTimer = Timer.periodic(
+      _updateInterval,
+      (timer) {
+        final now = DateTime.now();
         add(CoinsBalancesRefreshed());
+        add(CoinsPricesUpdated());
+        
+        if (now.difference(_lastReactivateTime) >= _reactivateInterval) {
+          add(CoinsSuspendedReactivated());
+          _lastReactivateTime = now;
+        }
       },
     );
-
-    _reActivateSuspendedTimer?.cancel();
-    _reActivateSuspendedTimer = Timer.periodic(
-      const Duration(seconds: 30),
-      (_) => add(CoinsSuspendedReactivated()),
-    );

529-547: Improve reactivation retry logic.

The _reActivateSuspended method uses a fixed number of attempts. Consider implementing an exponential backoff strategy for retries.

Apply this diff to implement exponential backoff:

   Stream<List<Coin>> _reActivateSuspended(
     Emitter<CoinsState> emit, {
-    int attempts = 1,
+    int maxAttempts = 3,
+    Duration initialDelay = const Duration(seconds: 1),
   }) async* {
     final List<String> coinsToBeActivated = [];
+    Duration delay = initialDelay;
 
-    for (int i = 0; i < attempts; i++) {
+    for (int i = 0; i < maxAttempts; i++) {
       final List<String> suspended = state.walletCoins.values
           .where((coin) => coin.isSuspended)
           .map((coin) => coin.abbr)
           .toList();
 
       coinsToBeActivated.addAll(suspended);
       coinsToBeActivated.addAll(_getUnactivatedWalletCoins());
 
       if (coinsToBeActivated.isEmpty) return;
+      
+      if (i > 0) {
+        await Future.delayed(delay);
+        delay *= 2; // Exponential backoff
+      }
+      
       yield await _activateCoins(coinsToBeActivated, emit);
     }
   }
ios/Runner.xcodeproj/project.pbxproj (1)

416-416: Verify iOS deployment target compatibility.

The iOS deployment target has been updated to 15.6 across all configurations. This change:

  1. Aligns with the platform version in Podfile (15.5.0)
  2. May restrict the app's availability to older devices

Consider documenting this minimum version requirement in the project's README to inform developers and users.

Also applies to: 559-559, 594-594

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3b24f4b and e9abd03.

⛔ Files ignored due to path filters (4)
  • app_theme/pubspec.lock is excluded by !**/*.lock
  • assets/logo/not_found.png is excluded by !**/*.png
  • ios/Podfile.lock is excluded by !**/*.lock
  • lib/generated/codegen_loader.g.dart is excluded by !**/generated/**
📒 Files selected for processing (32)
  • analysis_options.yaml (1 hunks)
  • android/app/build.gradle (3 hunks)
  • app_theme/lib/src/dark/theme_global_dark.dart (7 hunks)
  • app_theme/lib/src/light/theme_global_light.dart (7 hunks)
  • app_theme/pubspec.yaml (1 hunks)
  • assets/translations/en.json (8 hunks)
  • ios/Podfile (1 hunks)
  • ios/Runner.xcodeproj/project.pbxproj (10 hunks)
  • ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (2 hunks)
  • lib/bloc/analytics/analytics_repo.dart (1 hunks)
  • lib/bloc/auth_bloc/auth_bloc.dart (1 hunks)
  • lib/bloc/cex_market_data/mockup/generate_demo_data.dart (6 hunks)
  • lib/bloc/coins_bloc/asset_coin_extension.dart (1 hunks)
  • lib/bloc/coins_bloc/coins_bloc.dart (1 hunks)
  • lib/bloc/coins_bloc/coins_event.dart (1 hunks)
  • lib/bloc/coins_bloc/coins_repo.dart (1 hunks)
  • lib/bloc/coins_bloc/coins_state.dart (1 hunks)
  • lib/bloc/coins_manager/coins_manager_bloc.dart (8 hunks)
  • lib/bloc/custom_token_import/bloc/custom_token_import_bloc.dart (1 hunks)
  • lib/bloc/custom_token_import/bloc/custom_token_import_event.dart (1 hunks)
  • lib/bloc/custom_token_import/bloc/custom_token_import_state.dart (1 hunks)
  • lib/bloc/custom_token_import/data/custom_token_import_repository.dart (1 hunks)
  • lib/bloc/fiat/base_fiat_provider.dart (5 hunks)
  • lib/bloc/nft_withdraw/nft_withdraw_bloc.dart (10 hunks)
  • lib/bloc/transaction_history/transaction_history_repo.dart (1 hunks)
  • lib/bloc/trezor_bloc/trezor_repo.dart (5 hunks)
  • lib/bloc/trezor_init_bloc/trezor_init_bloc.dart (5 hunks)
  • lib/bloc/withdraw_form/withdraw_form_bloc.dart (1 hunks)
  • lib/bloc/withdraw_form/withdraw_form_state.dart (1 hunks)
  • lib/blocs/current_wallet_bloc.dart (4 hunks)
  • lib/mm2/mm2.dart (1 hunks)
  • lib/mm2/mm2_api/mm2_api.dart (17 hunks)
✅ Files skipped from review due to trivial changes (1)
  • analysis_options.yaml
🚧 Files skipped from review as they are similar to previous changes (3)
  • app_theme/lib/src/dark/theme_global_dark.dart
  • app_theme/lib/src/light/theme_global_light.dart
  • assets/translations/en.json
🔇 Additional comments (105)
app_theme/pubspec.yaml (3)

4-5: Cosmetic Homepage Comment Change
The change on line 4 is a minor formatting update (commenting the homepage key with adjusted spacing). This doesn’t affect functionality, so no further action is required.


7-7: SDK Version Constraint Update
The Dart SDK constraint has been updated to ">=3.6.0 <4.0.0". Please verify that all project dependencies and CI workflows support this updated range to avoid compatibility issues.


8-8: Flutter Version Constraint Update
The Flutter version is now set to "^3.29.0", which aligns with newer Flutter features and improvements. Ensure that all components of the project (and any dependent repositories) are compatible with this upgraded Flutter version.

ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (2)

3-3:

❓ Verification inconclusive

Verify Xcode version compatibility.

The scheme has been upgraded from Xcode 13.0 to Xcode 15.1.0. Please ensure that all team members have compatible Xcode versions and that CI/CD pipelines are updated accordingly.


🌐 Web query:

What is the latest stable version of Xcode and when was Xcode 15.1.0 released?

💡 Result:

The latest stable version of Xcode as of February 17, 2025, is Xcode 16.2 (16C5032a), released on December 11, 2024[3][10]. This information aligns with Apple's typical annual release cycle for major Xcode updates.

Regarding Xcode 15.1, historical records show:

  • Xcode 15.1 (without ".0") was released on December 11, 2023[3][6]
  • The version numbering convention shows subsequent updates as 15.x rather than 15.x.x (e.g., next update was Xcode 15.2)[3][6]

There is no official record of an Xcode 15.1.0 release in Apple's documentation or third-party tracking sources[3][6][8]. The standard release was labeled simply as Xcode 15.1, following Apple's typical versioning pattern where minor updates increment the second digit without additional decimal points[3][6].

Citations:


Recheck Xcode Scheme Settings and GPU Validation Configuration

  • The scheme now sets LastUpgradeVersion to "1510", which appears to represent Xcode 15.1. However, official records indicate that Apple labels this release simply as “Xcode 15.1” (without an extra trailing zero). Please confirm that the version string in the scheme file matches your intended Xcode environment and update any related CI/CD or team configurations if necessary.

  • The addition of enableGPUValidationMode="1" in the LaunchAction is intended to facilitate GPU-related debugging during development. Verify that this setting is applied only in appropriate debug contexts to prevent unintended performance impacts.


51-51:

❓ Verification inconclusive

Document the reason for enabling GPU validation mode.

GPU validation mode has been enabled, which can help catch GPU-related issues during development but may impact performance. Please document:

  1. The specific GPU-related issues this aims to address
  2. Whether this should be enabled only for specific debugging scenarios

🌐 Web query:

What is GPU Frame Capture and Validation mode in Xcode and when should it be enabled?

💡 Result:

GPU Frame Capture in Xcode is a diagnostic tool that captures detailed information about how your Metal-based application interacts with the GPU during a specific frame. This includes recording all Metal API calls, shader executions, and memory operations for analysis[1][2][6]. Validation Mode refers to Metal API Validation, which checks for proper API usage and error conditions during development[10].

Key Features of GPU Frame Capture

  • Frame Analysis: Captures full frame data including draw calls, textures, and buffers[2][4]
  • Performance Insights: Reveals timing breakdowns per command buffer/encoder and shader execution costs[8][9]
  • Dependency Visualization: Shows relationships between rendering passes and resource dependencies[2]
  • Shader Debugging: Allows inspection of compiled shader code and intermediate rendering results[7]

When to Enable These Tools

Scenario GPU Frame Capture Validation Mode
Debugging rendering artifacts Required Recommended
Profiling GPU performance Required Optional
Developing Metal features Recommended Required
Release builds Disabled Disabled
Testing API correctness Optional Required

GPU Frame Capture should be enabled when:

  1. Diagnosing visual glitches or rendering errors[7]
  2. Optimizing GPU-bound applications[2][9]
  3. Analyzing complex render pipelines with multiple passes[2]
  4. Debugging shader-related issues[1][7]

Validation Mode should be enabled during:

  1. Initial development phases[10]
  2. Testing new Metal features
  3. Troubleshooting crashes/errors in Metal API usage
  4. Ensuring resource synchronization correctness

To configure these settings:

1. Edit scheme > Run > Options
2. Set "GPU Frame Capture" to Metal
3. Enable "Metal API Validation"[10][6]

The tools require macOS/iOS devices using Metal graphics and Xcode 12+[1][4]. Captures can be triggered via UI (camera icon) or programmatically using MTLCaptureManager[8]. Note that some advanced features like command-line captures aren't supported on iOS[4][5].

Citations:


Clarify GPU Validation Mode Usage in the Runner Scheme

The current setting enableGPUValidationMode = "1" enables Metal API Validation. This mode is intended to help catch GPU-related issues during development—such as incorrect resource management, synchronization errors, and shader problems—by validating Metal API calls. Because this validation can significantly impact performance, it is recommended only for debugging and development scenarios rather than for production or performance-critical builds.

Please update the documentation (or inline comments) to clearly state:

  • The GPU-related issues (e.g., improper API usage, resource synchronization, shader errors) that this mode helps detect.
  • That GPU validation should be enabled only during development or debugging sessions and disabled in release builds.
lib/bloc/fiat/base_fiat_provider.dart (5)

6-8: LGTM! Import changes enhance type safety.

The addition of dedicated model classes and window utilities improves code organization and type safety.

Also applies to: 10-10


19-44: LGTM! Method signatures enhance type safety and maintainability.

The transition from generic types to specific model classes (ICurrency, FiatPaymentMethod, FiatPriceInfo, FiatBuyOrderInfo) improves type safety and makes the API more explicit.


99-99: LGTM! Error handling improvements.

The error handling is more robust with explicit type casting and descriptive network error messages.

Also applies to: 103-103


107-137: LGTM! Type-safe chain ID mapping.

The update to accept CryptoCurrency instead of Currency improves type safety and makes the method's purpose clearer.


248-281:

❓ Verification inconclusive

Verify security implications of URL handling.

The new URL handling methods look well-implemented, but please verify:

  1. The security of base64-encoded provider URLs
  2. The handling of postMessage events
  3. The potential for URL manipulation in the success callback

Run this script to check for any existing security measures:


🏁 Script executed:

#!/bin/bash
# Search for postMessage event handlers and security checks
rg -A 5 "window\.postMessage|addEventListener.*message" 

# Search for URL validation
rg -A 5 "validateUrl|sanitizeUrl|isValidUrl"

Length of output: 562


Security Verification Needed for URL Handling

The new static URL helper methods look well-documented and generally well-implemented, but please verify the following security aspects:

  • Provider URL Validation:
    In fiatWrapperPageUrl, the provider URL is base64-encoded before being appended to the URL. Ensure that the input provider URL is coming from a trusted source or is validated elsewhere in the codebase to prevent URL injection or unexpected behavior.

  • postMessage Handling:
    The search in lib/views/fiat/webview_dialog.dart shows usage of window.addEventListener("message", …). Confirm that the event listener properly verifies the origin of incoming messages and securely handles the message data.

  • Query Parameter Integrity:
    In successUrl, although Uri.encodeComponent is used for the account reference, double-check that this parameter is sufficiently validated upstream to prevent any potential URL manipulation.

Please perform a manual security review of these aspects in the broader context of the application before merging.

lib/mm2/mm2.dart (4)

11-23: Constructor looks good overall.
Initializing the _kdfSdk in the constructor is straightforward and readable. This design ensures the SDK is always ready for use.


31-50: Ensure concurrency safety in initialize().
The pattern using _initCompleter and _isInitializing is a standard approach to preventing multiple initializations. However, if multiple callers attempt to initialize at once, be sure that the rest of the code is thread-safe, especially regarding _kdfSdk usage in other async operations.


52-57: version() method is concise and clear.
Getting version info from the RPC and returning it as String is straightforward. The conversion from JSON to domain objects is also well-organized.


59-75: Good error handling in call().
Catching & logging the exception, then rethrowing it, allows external layers to decide how to handle the error. This helps maintain a clean separation of concerns.

lib/bloc/trezor_init_bloc/trezor_init_bloc.dart (4)

43-44: Subscription to auth state is well-managed

The subscription to _kdfSdk.auth.authStateChanges is properly canceled in close(), ensuring no memory leaks or unintended updates post-disposal. This is a good practice for reactive streams.


187-192: Guard against missing device details

This block force-unwraps event.status.details.deviceDetails! which might be risky if, for any reason, the response does not include device details. Although the success flow expects them, consider adding a null check or fallback handling to avoid potential runtime exceptions.


283-295: Handle potential errors from setWalletType and confirmSeedBackup

The calls to _kdfSdk.setWalletType(WalletType.trezor) and _kdfSdk.confirmSeedBackup() do not appear to have explicit error handling. If these methods fail, the user experience may degrade silently. Consider handling or logging any exceptions.


328-330: Stream subscription cleanup confirmed

The _authorizationSubscription.cancel() call ensures that no further authentication events propagate once the bloc is closed, preventing potential leaks or exceptions. This finalizes proper resource disposal.

lib/bloc/transaction_history/transaction_history_repo.dart (2)

3-4: Imports appear consistent with the SDK approach.
Good inclusion of komodo_defi_sdk and komodo_defi_types for streamlined transaction handling.


50-59: Check the silent fallback behavior on fetch errors.
fetch may return null on failure, which gets replaced by an empty list in fetchCompletedTransactions. Be sure you intend to silently ignore errors, or consider surfacing them to upstream callers for better troubleshooting.

lib/blocs/current_wallet_bloc.dart (6)

4-4: SDK imports look valid.
These newly added imports properly integrate KomodoDefiSdk and related functionality into the bloc code.

Also applies to: 7-7


12-12: Deprecation annotation is clear.
Informing developers to use AuthBloc or KomodoDefiSdk helps guide them to the new implementation.


57-58: addCoin result confirmation.
Setting wallet before returning true is fine, but confirm that external code checks for success or handles any partial updates if activation fails later.


69-69: removeCoin update looks consistent.
Removing the coin from the wallet config and returning true is straightforward. Ensure the caller re-renders or refreshes the UI if needed.


73-85: Retrieve and encrypt seed.
Nicely integrates with _kdfSdk to fetch mnemonic. Confirm the seedPhrase.isEmpty check is robust enough if user set a custom seed phrase previously.


89-89: Post-save backup confirmation.
Calling confirmBackup after saving helps ensure the wallet is flagged as backed up. This is a good practice for user flows.

lib/bloc/custom_token_import/bloc/custom_token_import_bloc.dart (4)

1-11: New file for custom token importing.
All these imports are relevant for custom token logic, decimal math, events, states, and repositories. They set a solid foundation for EVM-based token import flow.


12-24: Bloc structure initialization.
Creating the bloc with CustomTokenImportState.defaults() is clean. The event handlers are neatly registered, improving readability.


51-59: Conditional exit on event.network == null.
Returning early is fine. Consider logging or throwing if a network is unexpectedly null, or if you intend that scenario to be user-driven.


119-149: Import custom token flow.
Emits success or failure states clearly. Ensure the UI consistently resets or updates its view on either outcome.

lib/bloc/custom_token_import/data/custom_token_import_repository.dart (2)

25-45: Ensure robust null-safety checks.

In fetchCustomToken, consider validating convertAddressResponse and its fields before proceeding, as a null or partial response could break subsequent steps.


119-122: Check for async activation race conditions.

Ensure the synchronous activation in importCustomToken does not conflict with other concurrent asset operations (e.g., if multiple imports occur simultaneously). Consider additional synchronization or waiting for the _coinsRepo to fully finish.

lib/bloc/withdraw_form/withdraw_form_state.dart (1)

81-106: Ensure consistent copyWith usage.

Using ValueGetter<T?> is a neat approach, but it relies on the caller to pass functions. Double-check that the usage within the rest of the codebase matches the intended pattern; accidental direct invocations or forgetting the function calls can introduce subtle bugs.

lib/bloc/trezor_bloc/trezor_repo.dart (2)

90-92: Confirm backward compatibility when migrating from Coin to Asset.

enableUtxo now accepts Asset. Verify that all callers and usage sites have been updated correctly to prevent runtime mismatches.


169-182: Ensure account refresh is correct in getNewAddressStatus.

If new addresses are derived or updated, confirm that the local state (coin.accounts) does not conflict with other concurrency or stale data from _api.

lib/bloc/withdraw_form/withdraw_form_bloc.dart (21)

3-5: Imports look fine.
No immediate concerns regarding versioning or usage.


14-14: Decimal import is appropriate.
Using Decimal for precise arithmetic helps reduce floating-point errors.


17-17: Good approach introducing the _sdk field.
No concurrency or lifecycle issues spotted; usage seems straightforward.


19-48: Constructor logic is consistent.
All event handlers are registered, and initial load is triggered via add(const WithdrawFormSourcesLoadRequested()). Implementation is sound.


50-82: Solid error handling in _onSourcesLoadRequested.
Differentiates between “no addresses found” and general errors. This should help with user feedback.


84-99: Validate default fees.
Returning null for unsupported protocols is acceptable, but consider verifying the fallback fee approach (e.g., protocol.txFee ?? 10000) aligns with real network fees.


101-173: Robust address validation in _onRecipientChanged.
Mixed-case checks and fallback error handling are well-structured.


175-221: Amount parsing in _onAmountChanged is thorough.
Ensures positive amounts, checks balance, and gracefully handles parsing errors.


223-233: Selecting source address is straightforward.
Implementation is concise.


250-262: Custom fee toggle is simple and clear.
No issues found.


264-288: Fee validation logic is appropriate.
Good separation of EVM vs UTXO fees.


290-298: _validateEvmFee method is correct.
Ensures gas price and gas limit are above zero.


299-303: _validateUtxoFee checks the fee is > 0.
Straightforward.


305-310: No issues with memo handling.
Implementation is minimal and effective.


312-323: IBC transfer toggle is well-defined.
Approach is consistent with existing logic.


325-345: Sensible channel ID checks.
Gracefully handles empty channels.


347-381: Preview submission handles loading and errors cleanly.
No concerns found.


383-424: Withdrawal submission flow looks good.
Progress streaming is handled properly, and errors are surfaced clearly.


435-449: Reset logic is clean.
Resets relevant fields without unexpected side effects.


451-456: Mixed-case utility is concise.
Logic is straightforward and consistent with the EVM approach.


458-491: Address conversion routine.
Properly converts to the checksummed format, with clear error handling.

lib/mm2/mm2_api/mm2_api.dart (36)

4-5: New SDK imports appear valid.
No version conflicts evident.


7-7: Importing CoinsRepo.
Usage is consistent across constructor and NFT instantiation.


15-16: Directly connected peers import is clean.
No issues.


44-44: SendRawTransactionResponse import is correct.
Enhances type safety.


55-55: TextError import is used for error reporting.
No concerns.


61-63: Constructor injects CoinsRepo and KomodoDefiSdk.
Aligns with the new architecture.


64-65: Private fields _sdk and _mm2 are properly initialized.
Follows the updated design.


71-74: Comment on bridging to the SDK.
No functional issues.


94-100: Deprecated getBalance adapter.
Safe approach until full migration to the SDK is complete.


102-122: _fallbackToBalanceTaker implementation
Returns a synthetic MaxTakerVolResponse on error. Logical fallback approach.


128-136: Active swaps retrieval
Error logging is consistent; fallback response is minimal.


145-156: validateAddress
Captures exceptions, logs them, and returns null if failing.


161-170: withdraw integration
Graceful fallback to null on exceptions.


203-212: getTransactionsHistory
No issues. Logs errors appropriately.


219-228: getTransactionsHistoryV2
Similar error handling strategy.


235-244: getRewardsInfo
Straightforward retrieval with logging.


249-258: getBestOrders
Returns partial error info in a map. Implementation is acceptable.


263-273: sell
Error handling logs exceptions and returns a map with 'error'.


277-287: setprice
Same pattern of returning 'error': e. Fine for now.


291-301: cancelOrder
Risks are clearly logged, fallback map is returned.


305-315: getSwapStatus
Consistent approach to logging and fallback.


317-338: getMyOrders
Conditional sign-in check and error handling. Implementation is correct.


341-342: getRawSwapData
Encodes response to JSON. Straightforward.


348-362: getMyRecentSwaps
Null check for 'error' key, then returns typed response.


367-381: getOrderStatus
No issues. Follows the same pattern.


385-399: importSwaps
Uses typed response, logs errors. Looks good.


405-423: recoverFundsOfSwap
Captures errors and logs them, returns null if failing.


430-444: getMaxTakerVolume
On error or 'error' key, uses _fallbackToBalanceTaker.


450-464: getMinTradingVol
Returns null if 'error'. No concerns noted.


468-494: getOrderbook
Returns an OrderbookResponse, logs exceptions.


497-515: getOrderBookDepth
Handles 'error' gracefully. No issues.


523-542: getTradePreimage
Uses typed result with fallback. Solid.


557-575: startStopMarketMakerBot
Throws if 'error' is present. Logging is good.


593-594: stop
Simple call to StopReq with no further logic.


600-613: showPrivKey
Ignores errors, returns null if 'error' in response. Suitable for debugging.


616-640: getDirectlyConnectedPeers
Re-throws on failure, returns a typed response if successful. Implementation is consistent.

lib/bloc/custom_token_import/bloc/custom_token_import_event.dart (6)

1-9: Abstract event class is well defined.
Equatable usage ensures efficient equality checks.


11-19: UpdateNetworkEvent:
Nullable CoinSubClass? network is properly exposed in props.


20-27: UpdateAddressEvent:
Straightforward property for address updates.


29-31: SubmitImportCustomTokenEvent:
Placeholder event for the import flow.


33-35: SubmitFetchCustomTokenEvent:
Allows fetching custom token details.


37-39: ResetFormStatusEvent:
Suitable event to reset or clear form state.

lib/bloc/analytics/analytics_repo.dart (1)

53-55: LGTM! Parameter sanitization ensures proper data types.

The implementation correctly handles non-Object values by converting them to strings, preventing potential Firebase Analytics errors.

lib/bloc/coins_bloc/coins_repo.dart (2)

97-116: Remove deprecated method getCoin.

The getCoin method is marked as deprecated. Consider removing it and updating all callers to use KomodoDefiSdk.assets or getCoinFromId instead.


327-329: Remove deprecated method getFirstPubkey.

The getFirstPubkey method is marked as deprecated. Update callers to use pubkeys.getPubkeys from the SDK and let users select from available options.

lib/bloc/coins_bloc/coins_bloc.dart (1)

51-57: Replace deprecated CurrentWalletBloc.

The class uses the deprecated CurrentWalletBloc. Consider migrating to AuthBloc or KomodoDefiSdk for wallet management.

ios/Podfile (1)

2-2:

✅ Verification successful

Verify iOS platform version compatibility.

The platform version has been significantly increased from 11.0 to 15.5.0. This change will restrict the app to only run on iOS 15.5.0 and later devices, potentially reducing the user base.

Consider if this restriction aligns with your target audience and market requirements. If broader device support is needed, you might want to consider a lower minimum version while ensuring it's still compatible with your app's features and dependencies.


🌐 Web query:

What is the current iOS adoption rate for iOS 15.5 and above?

💡 Result:

As of February 2025, iOS adoption rates for versions 15.5 and above can be inferred from recent data trends:

  1. Cumulative Adoption:

    • By October 1, 2024, 95.1% of iPhones had adopted at least iOS 15, including all subsequent updates like iOS 16, 17, and 18[8].
    • This figure represents cumulative usage over time rather than active installations of specific minor versions like iOS 15.
  2. Current Market Share:

    • Data from January 2025 shows that only ~3–4% of active devices run iOS 16 or earlier (including residual installations of iOS 15)[6][7].
    • The vast majority (~96–97%) use iOS 17 or later, implying they also meet the "15.5 or above" threshold due to Apple’s forced update policies[7][9].

Key Notes:

  • Apple’s aggressive update enforcement ensures most compatible devices automatically upgrade beyond older minor releases like iOS 15.
  • Devices stuck on older OS versions are typically legacy models incompatible with newer updates[8].

In summary: While exact figures for iOS 15.x aren’t explicitly reported in early 2025,≥95% of active iPhones likely run iOS 15.x or later due to Apple’s update ecosystem[6][7][8].

Citations:


Attention: iOS Deployment Target Confirmed

Based on current market data, nearly 95% of active iPhone users are running iOS 15.5 or later. Therefore, updating the Podfile to:

platform :ios, '15.5.0'

will have minimal impact on your user base. Please ensure that this threshold still aligns with your target audience—especially if you have any niche segments potentially using older devices.

  • File: ios/Podfile (Line 2)
  • Key Consideration: Adoption trends support this update, but double-check if legacy device support is necessary.
ios/Runner.xcodeproj/project.pbxproj (2)

267-283: LGTM! New CocoaPods resources phase added.

The addition of the [CP] Copy Pods Resources build phase is a standard CocoaPods integration step that ensures proper resource handling.


186-186:

❓ Verification inconclusive

Verify Xcode version compatibility.

The LastUpgradeCheck has been updated to 1510, which corresponds to Xcode 15.1.


🌐 Web query:

What is the latest version of Xcode and what are the minimum system requirements?

💡 Result:

The latest stable version of Xcode as of February 2025 is Xcode 16, released on September 16, 2024[1][4]. The current beta version is Xcode 16.2 beta[1].

Minimum System Requirements

macOS:

  • Requires macOS Sonoma 14.5 or later for all Xcode 16 versions[1][7].
  • Older versions of Xcode have progressively lower macOS requirements (e.g., Xcode 15 requires macOS Ventura 13.5)[3].

Hardware Compatibility:

  • Apple does not specify exact hardware requirements but ties compatibility to macOS versions[2].
  • For macOS Sonoma (required for Xcode 16), supported devices generally include:
    • Macs with Apple Silicon (M1/M2/M3 chips)
    • Intel-based Macs from late 2017 onward[2][8].

Recommended Specifications:

  • RAM: At least 8GB (functional for basic development), though 16GB is recommended for smoother performance[2][8].
  • Storage: Minimum 256GB SSD, with additional space required for simulators and SDKs (~80GB for two Xcode versions)[5].

Key Features in Xcode 16

  • Supports development for iOS 18, macOS 15, visionOS 2, and other Apple platforms[1][4].
  • Includes Swift 6 and backward compatibility with Swift versions as old as Swift 4[1].
  • Architecture support: arm64, arm64e, and legacy Intel (x86_64)[1].

For app store submissions, Apple will stop accepting apps built with Xcode versions older than v15 starting April 2025[7].

Citations:


Action: Confirm Compatibility with Current Xcode Version

  • File: ios/Runner.xcodeproj/project.pbxproj at line 186
  • Observation: The LastUpgradeCheck field is set to 1510, which indicates the project was last upgraded using Xcode 15.1.
  • Context: As of February 2025, the latest stable Xcode release is version 16 (released September 2024), which requires macOS Sonoma 14.5 or later.
  • Recommendation: Please verify that retaining the value 1510 is intentional and that the project remains fully compatible with Xcode 16. If compatibility issues arise, consider updating this field to reflect the current Xcode environment.

Comment on lines +20 to 45
Future<List<Transaction>?> fetch(AssetId assetId, {String? fromId}) async {
final asset = _sdk.assets.available[assetId];
if (asset == null) {
throw TransactionFetchException('Asset $assetId not found');
}
return coin.isErcType
? await fetchErcTransactionHistory(coin)
: await fetchTransactionHistory(
MyTxHistoryRequest(
coin: coin.abbr,
max: true,
),
);
}

Future<List<Transaction>> fetchTransactions(Coin coin) async {
final historyResponse = await fetch(coin);
final TransactionHistoryResponseResult? result = historyResponse.data;

final BaseError? responseError = historyResponse.error;
// TODO: add custom exceptions here?
if (responseError != null) {
throw TransactionFetchException('Transaction fetch error: ${responseError.message}');
} else if (result == null) {
throw TransactionFetchException('Transaction fetch result is null');
try {
final transactionHistory = await _sdk.transactions.getTransactionHistory(
asset,
pagination: fromId == null
? const PagePagination(
pageNumber: 1,
// TODO: Handle cases with more than 2000 transactions and/or
// adopt a pagination strategy. Migrate form
itemsPerPage: 2000,
)
: TransactionBasedPagination(
fromId: fromId,
itemCount: 2000,
),
);
return transactionHistory.transactions;
} catch (e) {
return null;
}

return result.transactions;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Unify exception vs. null returns in fetch.
After throwing an exception for a missing asset, the catch block swallows other errors by returning null. Consider consistently throwing TransactionFetchException here or returning a wrapped error to avoid masking different error states.

Comment on lines +68 to +117
Future<void> _onSubmitFetchCustomToken(
SubmitFetchCustomTokenEvent event,
Emitter<CustomTokenImportState> emit,
) async {
emit(state.copyWith(formStatus: FormStatus.submitting));

try {
final networkAsset = _coinsRepo.getCoin(state.network.ticker);
if (networkAsset == null) {
throw Exception('Network asset ${state.network.formatted} not found');
}

await _coinsRepo.activateCoinsSync([networkAsset]);
final tokenData =
await repository.fetchCustomToken(state.network, state.address);
await _coinsRepo.activateAssetsSync([tokenData]);

final balanceInfo = await _coinsRepo.tryGetBalanceInfo(tokenData.id);
final balance = balanceInfo.spendable;
final usdBalance =
_coinsRepo.getUsdPriceByAmount(balance.toString(), tokenData.id.id);

emit(
state.copyWith(
formStatus: FormStatus.success,
tokenData: () => tokenData,
tokenBalance: balance,
tokenBalanceUsd:
Decimal.tryParse(usdBalance?.toString() ?? '0.0') ?? Decimal.zero,
formErrorMessage: '',
),
);

await _coinsRepo.deactivateCoinsSync([tokenData.toCoin()]);
} catch (e, s) {
log(
'Error fetching custom token: ${e.toString()}',
path: 'CustomTokenImportBloc._onSubmitFetchCustomToken',
isError: true,
trace: s,
);
emit(
state.copyWith(
formStatus: FormStatus.failure,
tokenData: () => null,
formErrorMessage: e.toString(),
),
);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fetch custom token logic.

  1. Activation and deactivation flow for custom token looks robust.
  2. The fallback to Exception might obscure typed errors from the repository.
  3. Consider thorough error handling or typed exceptions for clarity.

Comment on lines +47 to +117
Future<Asset> _createNewCoin(
String contractAddress,
CoinSubClass network,
String address,
) async {
final response = await _kdfSdk.client.rpc.utility.getTokenInfo(
contractAddress: contractAddress,
platform: network.ticker,
protocolType: CoinSubClass.erc20.formatted,
);

final platformAssets = _kdfSdk.assets.findAssetsByTicker(network.ticker);
if (platformAssets.length != 1) {
throw Exception('Platform asset not found. ${platformAssets.length} '
'results returned.');
}
final platformAsset = platformAssets.single;
final platformConfig = platformAsset.protocol.config;
final String ticker = response.info.symbol;
final tokenApi = await fetchTokenInfoFromApi(network, contractAddress);

final coinId = '$ticker-${network.ticker}';
final logoImageUrl = tokenApi?['image']?['large'] ??
tokenApi?['image']?['small'] ??
tokenApi?['image']?['thumb'];
final newCoin = Asset(
id: AssetId(
id: coinId,
name: tokenApi?['name'] ?? ticker,
symbol: AssetSymbol(
assetConfigId: '$ticker-${network.ticker}',
coinGeckoId: tokenApi?['id'],
coinPaprikaId: tokenApi?['id'],
),
chainId: AssetChainId(chainId: 0),
subClass: network,
derivationPath: '',
),
protocol: Erc20Protocol.fromJson({
'type': network.formatted,
'chain_id': 0,
'nodes': [],
'swap_contract_address':
platformConfig.valueOrNull<String>('swap_contract_address'),
'fallback_swap_contract':
platformConfig.valueOrNull<String>('fallback_swap_contract'),
'protocol': {
'protocol_data': {
'platform': network.ticker,
'contract_address': address,
},
},
'logo_image_url': logoImageUrl,
'explorer_url': platformConfig.valueOrNull<String>('explorer_url'),
'explorer_url_tx':
platformConfig.valueOrNull<String>('explorer_url_tx'),
'explorer_url_address':
platformConfig.valueOrNull<String>('explorer_url_address'),
}).copyWith(isCustomToken: true),
);

CoinIcon.registerCustomIcon(
newCoin.id.id,
NetworkImage(
tokenApi?['image']?['large'] ??
'assets/coin_icons/png/${ticker.toLowerCase()}.png',
),
);

return newCoin;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling for token creation.

In _createNewCoin, consider handling potential absent or malformed fields from the RPC response (e.g., response.info). Null checks, combined with descriptive exceptions, can help diagnose issues quickly.

Comment on lines +141 to +156
WithdrawParameters toWithdrawParameters() {
return WithdrawParameters(
asset: asset.id.id,
toAddress: recipientAddress,
amount: isMaxAmount ? null : Decimal.parse(amount),
fee: isCustomFee ? customFee : null,
from: selectedSourceAddress?.derivationPath != null
? WithdrawalSource.hdDerivationPath(
selectedSourceAddress!.derivationPath!,
)
: null,
memo: memo,
ibcTransfer: isIbcTransfer ? true : null,
isMax: isMaxAmount,
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Validate numeric parsing in toWithdrawParameters.

Decimal.parse(amount) can throw an exception if amount is empty or invalid. Ensure that upstream validations always guarantee a valid numeric string.

Comment on lines 60 to 67
Future<void> sendPin(String pin, TrezorTask trezorTask) async {
await _api.pin(TrezorPinRequest(
pin: pin,
task: trezorTask,
));
await _api.pin(
TrezorPinRequest(
pin: pin,
task: trezorTask,
),
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Confirm secure input handling for sendPin.

Pins are potentially sensitive data. Confirm that logging is avoided and ensure no PII or secrets are inadvertently persisted in logs or analytics.

Comment on lines +126 to +167
CoinSubClass toCoinSubClass() {
switch (this) {
case CoinType.ftm20:
return CoinSubClass.ftm20;
case CoinType.arb20:
return CoinSubClass.arbitrum;
case CoinType.slp:
return CoinSubClass.slp;
case CoinType.qrc20:
return CoinSubClass.qrc20;
case CoinType.avx20:
return CoinSubClass.avx20;
case CoinType.smartChain:
return CoinSubClass.smartChain;
case CoinType.mvr20:
return CoinSubClass.moonriver;
case CoinType.etc:
return CoinSubClass.ethereumClassic;
case CoinType.hco20:
return CoinSubClass.hecoChain;
case CoinType.hrc20:
return CoinSubClass.hrc20;
case CoinType.iris:
return CoinSubClass.tendermintToken;
case CoinType.cosmos:
return CoinSubClass.tendermint;
case CoinType.ubiq:
return CoinSubClass.ubiq;
case CoinType.bep20:
return CoinSubClass.bep20;
case CoinType.plg20:
return CoinSubClass.matic;
case CoinType.utxo:
return CoinSubClass.utxo;
case CoinType.sbch:
return CoinSubClass.smartBch;
case CoinType.erc20:
return CoinSubClass.erc20;
case CoinType.krc20:
return CoinSubClass.krc20;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add default case for unsupported coin types.

The toCoinSubClass() method is missing a default case, which could lead to runtime errors when an unsupported coin type is provided.

Apply this diff to improve error handling:

     case CoinType.krc20:
       return CoinSubClass.krc20;
+    default:
+      throw UnsupportedError('Unsupported coin type: $this');
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CoinSubClass toCoinSubClass() {
switch (this) {
case CoinType.ftm20:
return CoinSubClass.ftm20;
case CoinType.arb20:
return CoinSubClass.arbitrum;
case CoinType.slp:
return CoinSubClass.slp;
case CoinType.qrc20:
return CoinSubClass.qrc20;
case CoinType.avx20:
return CoinSubClass.avx20;
case CoinType.smartChain:
return CoinSubClass.smartChain;
case CoinType.mvr20:
return CoinSubClass.moonriver;
case CoinType.etc:
return CoinSubClass.ethereumClassic;
case CoinType.hco20:
return CoinSubClass.hecoChain;
case CoinType.hrc20:
return CoinSubClass.hrc20;
case CoinType.iris:
return CoinSubClass.tendermintToken;
case CoinType.cosmos:
return CoinSubClass.tendermint;
case CoinType.ubiq:
return CoinSubClass.ubiq;
case CoinType.bep20:
return CoinSubClass.bep20;
case CoinType.plg20:
return CoinSubClass.matic;
case CoinType.utxo:
return CoinSubClass.utxo;
case CoinType.sbch:
return CoinSubClass.smartBch;
case CoinType.erc20:
return CoinSubClass.erc20;
case CoinType.krc20:
return CoinSubClass.krc20;
}
}
CoinSubClass toCoinSubClass() {
switch (this) {
case CoinType.ftm20:
return CoinSubClass.ftm20;
case CoinType.arb20:
return CoinSubClass.arbitrum;
case CoinType.slp:
return CoinSubClass.slp;
case CoinType.qrc20:
return CoinSubClass.qrc20;
case CoinType.avx20:
return CoinSubClass.avx20;
case CoinType.smartChain:
return CoinSubClass.smartChain;
case CoinType.mvr20:
return CoinSubClass.moonriver;
case CoinType.etc:
return CoinSubClass.ethereumClassic;
case CoinType.hco20:
return CoinSubClass.hecoChain;
case CoinType.hrc20:
return CoinSubClass.hrc20;
case CoinType.iris:
return CoinSubClass.tendermintToken;
case CoinType.cosmos:
return CoinSubClass.tendermint;
case CoinType.ubiq:
return CoinSubClass.ubiq;
case CoinType.bep20:
return CoinSubClass.bep20;
case CoinType.plg20:
return CoinSubClass.matic;
case CoinType.utxo:
return CoinSubClass.utxo;
case CoinType.sbch:
return CoinSubClass.smartBch;
case CoinType.erc20:
return CoinSubClass.erc20;
case CoinType.krc20:
return CoinSubClass.krc20;
default:
throw UnsupportedError('Unsupported coin type: $this');
}
}

Comment on lines +9 to +13
ProtocolData? protocolData;
protocolData = ProtocolData(
platform: id.parentId?.id ?? '',
contractAddress: '',
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Initialize contract address from protocol data.

The ProtocolData is initialized with an empty contract address, which could cause issues. Consider initializing it with the actual contract address from the protocol data.

Apply this diff to fix the issue:

-    protocolData = ProtocolData(
-      platform: id.parentId?.id ?? '',
-      contractAddress: '',
-    );
+    protocolData = ProtocolData(
+      platform: id.parentId?.id ?? '',
+      contractAddress: protocol.config.valueOrNull('protocol', 'protocol_data', 'contract_address') ?? '',
+    );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ProtocolData? protocolData;
protocolData = ProtocolData(
platform: id.parentId?.id ?? '',
contractAddress: '',
);
ProtocolData? protocolData;
protocolData = ProtocolData(
platform: id.parentId?.id ?? '',
contractAddress: protocol.config.valueOrNull('protocol', 'protocol_data', 'contract_address') ?? '',
);

Comment on lines +96 to +98
default:
return CoinType.utxo;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Throw error for unsupported coin subclasses.

The default case returns CoinType.utxo which might not be appropriate for all unsupported coin subclasses. Consider throwing an error to prevent silent failures.

Apply this diff to improve error handling:

-      default:
-        return CoinType.utxo;
+      default:
+        throw UnsupportedError('Unsupported coin subclass: $this');
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
default:
return CoinType.utxo;
}
default:
throw UnsupportedError('Unsupported coin subclass: $this');
}

* build: fix missing asset error

assets declared by dependency packages appear to be accessible from the calling/parent package

* ci(flutter): upgrade pinned version to 3.29

* docs: upgrade pinned flutter version to 3.29

* build(android): upgrade NDK version to v27 (latest stable)
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
.github/actions/flutter-deps/action.yml (1)

12-20: Prepare Build Directory Step – Consider Adding Strict Error Handling:
The cleanup commands (invoking flutter clean and removing build-related directories) are effective in ensuring a clean environment.
A good-to-have improvement would be to add an set -e at the beginning of the shell script to immediately terminate the step if any command fails. This minimizes the risk of proceeding with a partially cleaned environment. For example:

-      run: |
-        flutter clean
-        rm -rf build/*
-        rm -rf web/src/mm2/*
-        rm -rf web/src/kdfi/*
-        rm -rf web/dist/*
+      run: |
+        set -e
+        flutter clean
+        rm -rf build/*
+        rm -rf web/src/mm2/*
+        rm -rf web/src/kdfi/*
+        rm -rf web/dist/*
docs/FLUTTER_VERSION.md (1)

12-15: Specify Language for Fenced Code Block

The fenced code block starting on line 11 lacks a language specifier, which is triggering markdown lint warnings. Please add an appropriate language identifier (e.g., bash or sh) after the opening triple backticks to improve clarity and lint compliance.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9abd03 and 6b06f15.

📒 Files selected for processing (5)
  • .devcontainer/komodo-wallet-android-dev.dockerfile (1 hunks)
  • .docker/komodo-wallet-android.dockerfile (1 hunks)
  • .github/actions/flutter-deps/action.yml (1 hunks)
  • android/app/build.gradle (3 hunks)
  • docs/FLUTTER_VERSION.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • android/app/build.gradle
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
docs/FLUTTER_VERSION.md

11-11: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build_and_preview
  • GitHub Check: validate_code_guidelines
  • GitHub Check: build_and_deploy
🔇 Additional comments (6)
.github/actions/flutter-deps/action.yml (3)

1-2: Clear Naming and Description:
The action name ("Flutter Dependencies") and description ("Installs Flutter and any other dependencies required for the build") are clear and appropriately describe the purpose of the action.


3-5: Composite Action Declaration:
The use of a composite action with runs: using: "composite" and a proper steps definition is correct. It clearly communicates that multiple steps are executed as part of this action.


6-11: Stable Flutter Installation Step:
The step uses subosito/flutter-action@v2 with the specified flutter-version: "3.29.x" and channel: "stable", which is appropriate for ensuring that the correct version of Flutter is installed. There are no issues seen here.

.docker/komodo-wallet-android.dockerfile (1)

15-15: Update Flutter Version Environment Variable

The Flutter version has been updated successfully from "3.22.3" to "3.29.0". This change aligns with the overall upgrade across the codebase. Please verify that the updated tag exists in the Flutter repository and that the build process works as expected with this version.

.devcontainer/komodo-wallet-android-dev.dockerfile (1)

5-5: Update Flutter Version in Dev Container

The Flutter version environment variable has been correctly updated to "3.29.0". This change is consistent with other repository files and should ensure that development and build environments use the latest stable version.

docs/FLUTTER_VERSION.md (1)

7-7: Update Documented Current Flutter Version

The documented current version has been updated to 3.29.0. This reflects the intended upgrade and ensures that documentation is in sync with the project configuration.

5960abfcc01b067e994504218a7f64a3c142ac08
* fix(asset): add missing segwit flag to coin conversion function

* fix(activation): skip coin activation if not signed in

coin activation fails with an error message if there is no wallet/user signed in

* fix(text-form-field): add a default fill colour to UiTextFormField

fixes the lacking contrast with the input fields, as a lack of fill colour results in an input field with the same colour as the background (dark and light modes)
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
lib/bloc/coins_bloc/coins_repo.dart (1)

342-351: ⚠️ Potential issue

Replace deprecated getFirstPubkey method.

The method is marked as deprecated with a comment suggesting to use SDK pubkeys.getPubkeys instead.

Since this method is still being used in the codebase (e.g., line 141), it needs to be replaced. Here's how to refactor the usage:

-final coinAddress = await getFirstPubkey(coin.abbr);
+final asset = _kdfSdk.assets.findAssetsByTicker(coin.abbr).single;
+final pubkeys = await _kdfSdk.pubkeys.getPubkeys(asset);
+final coinAddress = pubkeys.keys.isNotEmpty ? pubkeys.keys.first.address : null;
🧹 Nitpick comments (3)
lib/bloc/coins_bloc/coins_repo.dart (3)

45-47: Address TODO comment regarding Trezor bloc refactoring.

The TODO comment indicates that the Trezor bloc needs refactoring to handle pin/password input events. This architectural issue should be addressed.

Would you like me to help design a proper repository pattern for handling Trezor-related operations?


364-373: Consider adding retry mechanism for price fetching.

The price fetching logic could benefit from a retry mechanism with exponential backoff for better resilience.

 Future<Map<String, CexPrice>?> fetchCurrentPrices() async {
+  const maxRetries = 3;
+  const initialDelay = Duration(seconds: 1);
+  
+  for (int i = 0; i < maxRetries; i++) {
+    if (i > 0) {
+      await Future.delayed(initialDelay * (1 << i));  // Exponential backoff
+    }
     final Map<String, CexPrice>? prices =
         await _updateFromMain() ?? await _updateFromFallback();
 
     if (prices != null) {
       _pricesCache = prices;
+      return _pricesCache;
     }
+  }
 
-    return _pricesCache;
+  return null;  // Return null after all retries fail
 }

534-570: Enhance error handling in withdraw method.

The withdraw method's error handling could be improved by adding more specific error types and logging.

 Future<BlocResponse<WithdrawDetails, BaseError>> withdraw(
   WithdrawRequest request,
 ) async {
   Map<String, dynamic>? response;
   try {
     response = await _mm2.call(request) as Map<String, dynamic>?;
   } catch (e, s) {
+    final errorMessage = 'Error withdrawing ${request.params.coin}: $e';
     log(
-      'Error withdrawing ${request.params.coin}: $e',
+      errorMessage,
       path: 'api => withdraw',
       trace: s,
       isError: true,
     ).ignore();
+    return BlocResponse(
+      error: TextError(
+        error: e is TimeoutException
+          ? LocaleKeys.withdrawalTimeout.tr()
+          : LocaleKeys.somethingWrong.tr(),
+        details: errorMessage,
+      ),
+    );
   }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b06f15 and 8fa543a.

📒 Files selected for processing (2)
  • lib/bloc/coins_bloc/asset_coin_extension.dart (1 hunks)
  • lib/bloc/coins_bloc/coins_repo.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/bloc/coins_bloc/asset_coin_extension.dart
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build_and_preview
  • GitHub Check: validate_code_guidelines
  • GitHub Check: build_and_deploy
🔇 Additional comments (2)
lib/bloc/coins_bloc/coins_repo.dart (2)

29-41: LGTM! Constructor properly initializes dependencies.

The constructor correctly initializes the required dependencies and sets up the broadcast stream controller with proper listener management.


291-292: Remove duplicate deprecated method usage.

This is another instance of using the deprecated activateAsset method with an ignore comment.

Comment on lines +241 to +242
// ignore: deprecated_member_use
final progress = await _kdfSdk.assets.activateAsset(assets.single).last;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove deprecated method usage.

The code is using a deprecated activateAsset method with an explicit ignore comment.

Consider migrating to the new activation method in the SDK. If you need help with the migration, I can assist with the implementation.

Comment on lines +433 to 492
Future<Map<String, CexPrice>?> _updateFromFallback() async {
final List<String> ids = (await getEnabledCoins())
.map((c) => c.coingeckoId ?? '')
.toList()
..removeWhere((id) => id.isEmpty);
final Uri fallbackUri = Uri.parse(
'https://api.coingecko.com/api/v3/simple/price?ids='
'${ids.join(',')}&vs_currencies=usd',
);

http.Response res;
String body;
try {
res = await http.get(fallbackUri);
body = res.body;
} catch (e, s) {
log(
'Error updating price from fallback: $e',
path: 'cex_services => _updateFromFallback => http.get',
trace: s,
isError: true,
).ignore();
return null;
}

Map<String, dynamic>? json;
try {
json = jsonDecode(body) as Map<String, dynamic>?;
} catch (e, s) {
log(
'Error parsing of update price from fallback response: $e',
path: 'cex_services => _updateFromFallback => jsonDecode',
trace: s,
isError: true,
).ignore();
}

if (json == null) return null;
final Map<String, CexPrice> prices = {};

for (final MapEntry<String, dynamic> entry in json.entries) {
final coingeckoId = entry.key;
final pricesData = entry.value as Map<String, dynamic>? ?? {};
if (coingeckoId == 'test-coin') continue;

// Coins with the same coingeckoId supposedly have same usd price
// (e.g. KMD == KMD-BEP20)
final Iterable<Coin> samePriceCoins =
(getKnownCoins()).where((coin) => coin.coingeckoId == coingeckoId);

for (final Coin coin in samePriceCoins) {
prices[coin.abbr] = CexPrice(
ticker: coin.abbr,
price: double.parse(pricesData['usd'].toString()),
);
}
}

return prices;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add rate limiting for Coingecko API calls.

The fallback price fetching mechanism using Coingecko's API should implement rate limiting to avoid hitting API limits.

+class RateLimiter {
+  final Duration interval;
+  DateTime? _lastCall;
+
+  RateLimiter({this.interval = const Duration(seconds: 1)});
+
+  Future<void> throttle() async {
+    if (_lastCall != null) {
+      final waitTime = interval - DateTime.now().difference(_lastCall!);
+      if (waitTime.isNegative == false) {
+        await Future.delayed(waitTime);
+      }
+    }
+    _lastCall = DateTime.now();
+  }
+}

 Future<Map<String, CexPrice>?> _updateFromFallback() async {
+  static final _rateLimiter = RateLimiter(interval: Duration(seconds: 2));
+  await _rateLimiter.throttle();
+
   final List<String> ids = (await getEnabledCoins())
       .map((c) => c.coingeckoId ?? '')
       .toList()

Committable suggestion skipped: line range outside the PR's diff.

* build(docker): remove kdf build step and download flutter from sdk archive

* build: remove kdf build step from devcontainer and update flutter install

* build: fix devcontainer workspace folder error in CodeSpaces

* build(devcontainer): extract flutter to /opt rather than workspaces
* docs(flutter-setup): update setup steps to match the official guide

Flutter documentation recommends downloading via VSCode or via the SDK Archive (tar/zip files) rather than cloning the git repository

* docs(project-setup): update the referenced IDE and tool versions

* docs: address coderabbitai nitpick comments

* docs(fvm): remove unix-specific instructions, and reduce duplication
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (7)
docs/FLUTTER_VERSION.md (1)

19-21: Clarify Pinning Recommendation
The note advising against pinning the Flutter version is helpful. It might be beneficial to briefly explain why isolation is insufficient when managing multiple Flutter versions.

.devcontainer/Dockerfile (3)

6-7: Merge PATH Environment Variables
The Dockerfile sets the PATH twice—first adding /opt/flutter/bin and then /android-ndk/bin. This may result in the latter overriding the first. Consider merging them into a single statement (e.g., ENV PATH=$PATH:/opt/flutter/bin:/android-ndk/bin) to ensure both paths are preserved.


30-37: Avoid sudo Usage in Dockerfile RUN Commands
The installation step uses sudo (e.g., sudo chown ...), which can lead to unpredictable behavior in Dockerfiles. Since the build is typically executed as root, it is preferable to remove sudo or switch to a tool like gosu when a user change is required.


72-90: Consider Removing sudo in Subsequent RUN Commands
The RUN block starting at line 72 continues to use sudo for commands like apt-get update and chown. Running these commands as root (or using an alternative like gosu) would simplify the build process and improve predictability.

🧰 Tools
🪛 Hadolint (2.12.0)

[error] 72-72: Do not use sudo as it leads to unpredictable behavior. Use a tool like gosu to enforce root

(DL3004)

.docker/komodo-wallet-android.dockerfile (1)

13-18: Flutter SDK Installation Steps:
The RUN command effectively downloads the Flutter SDK, extracts it to the designated home directory, cleans up the archive, and configures Flutter by disabling analytics and accepting Android licenses. For enhanced debuggability, you might consider adding error checking or splitting long chained commands (using &&), so that pinpointing failures is easier.

docs/INSTALL_FLUTTER.md (1)

47-47: Typographical Note:
Consider using “log out” (two words) instead of “logout” for clarity. Additionally, you may want to review the punctuation before “if” to ensure it aligns with standard style conventions.

🧰 Tools
🪛 LanguageTool

[misspelling] ~47-~47: Did you mean the verb “log out” instead of the noun ‘logout’?
Context: ...er\bin as its value. You might need to logout and re-login (or source the shell confi...

(LOG_IN)


[typographical] ~47-~47: Usually, there’s no comma before “if”.
Context: ... (or source the shell configuration file, if applicable) to make changes apply. On ...

(IF_NO_COMMA)

docs/MULTIPLE_FLUTTER_VERSIONS.md (1)

1-4: FVM Section Introduction:
The introduction clearly explains the benefits of using FVM for managing multiple Flutter SDK versions. However, the self-reference (See [MULTIPLE_FLUTTER_VERSIONS.md](MULTIPLE_FLUTTER_VERSIONS.md)) is redundant since the user is already viewing this file. Consider removing it for clarity.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8fa543a and 92cb33e.

📒 Files selected for processing (15)
  • .devcontainer/Dockerfile (1 hunks)
  • .devcontainer/dev-setup.sh (0 hunks)
  • .devcontainer/devcontainer.json (1 hunks)
  • .devcontainer/komodo-wallet-android-dev.dockerfile (0 hunks)
  • .docker/android-sdk.dockerfile (1 hunks)
  • .docker/build.sh (1 hunks)
  • .docker/kdf-android.dockerfile (0 hunks)
  • .docker/komodo-wallet-android.dockerfile (1 hunks)
  • .dockerignore (1 hunks)
  • docs/BUILD_RUN_APP.md (2 hunks)
  • docs/FIREBASE_SETUP.md (1 hunks)
  • docs/FLUTTER_VERSION.md (1 hunks)
  • docs/INSTALL_FLUTTER.md (2 hunks)
  • docs/MULTIPLE_FLUTTER_VERSIONS.md (1 hunks)
  • docs/PROJECT_SETUP.md (2 hunks)
💤 Files with no reviewable changes (3)
  • .devcontainer/dev-setup.sh
  • .docker/kdf-android.dockerfile
  • .devcontainer/komodo-wallet-android-dev.dockerfile
✅ Files skipped from review due to trivial changes (2)
  • docs/FIREBASE_SETUP.md
  • .dockerignore
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/PROJECT_SETUP.md
🧰 Additional context used
🪛 LanguageTool
docs/INSTALL_FLUTTER.md

[misspelling] ~47-~47: Did you mean the verb “log out” instead of the noun ‘logout’?
Context: ...er\bin as its value. You might need to logout and re-login (or source the shell confi...

(LOG_IN)


[typographical] ~47-~47: Usually, there’s no comma before “if”.
Context: ... (or source the shell configuration file, if applicable) to make changes apply. On ...

(IF_NO_COMMA)

🪛 Hadolint (2.12.0)
.devcontainer/Dockerfile

[error] 72-72: Do not use sudo as it leads to unpredictable behavior. Use a tool like gosu to enforce root

(DL3004)

🔇 Additional comments (24)
.devcontainer/devcontainer.json (5)

4-4: Update Dockerfile Reference.
The dockerFile property now references "Dockerfile", which streamlines the build configuration. Ensure that the Dockerfile is appropriately configured at the repository root and includes all necessary instructions for the development environment.


6-8: Refined Workspace and Initialization Commands.
The updated "workspaceFolder" explicitly sets the working directory, and the new "postCreateCommand" applies correct ownership to ensure proper permissions. Additionally, replacing the previous post-attach script with "flutter pub get" in "postAttachCommand" simplifies dependency management. Verify that these changes are compatible across all development setups.


10-13: Enhanced Run Arguments for Device Access.
Adding "--privileged" along with the USB device volume mapping ("-v", "/dev/bus/usb:/dev/bus/usb") facilitates direct hardware access, which is critical for mobile and Flutter development. While useful, please ensure that running with privileged mode in the development container does not introduce unintended security risks.


14-17: Port Forwarding Configuration.
The addition of the forwardPorts property with ports 8081 and 5037 is well-suited for enabling live reload, debugging, and potentially ADB connectivity. Please verify that these forwarded ports do not conflict with host processes.


20-23: Streamlined VSCode Extensions.
The reduction of the VSCode extensions list to only include "Dart-Code.dart-code" and "Dart-Code.flutter" helps focus the development environment on core Flutter tooling. Confirm that any functionality provided by the removed extensions is either unnecessary or provided elsewhere in your workflow.

.docker/build.sh (3)

19-23: OS Check Update for macOS
The updated comparison using = for string equality is POSIX-compliant and works well for detecting macOS.


25-27: Update Android SDK Image Version
The Docker build command for the Android SDK image now tags it as komodo/android-sdk:35, reflecting the upgrade from version 34 to 35. Ensure that all related configurations (e.g., in Gradle files) are updated accordingly.


29-33: Streamline Flutter Build Command
The run command has been simplified by removing the flutter pub get && flutter analyze sequence. Please verify that this streamlined command still triggers all necessary build steps for asset downloads and analysis.

.docker/android-sdk.dockerfile (1)

28-32: Upgrade Android Build Tools and NDK Versions
The environment variables ANDROID_PLATFORM_VERSION, ANDROID_BUILD_TOOLS_VERSION, and ANDROID_NDK_VERSION have been updated to 35, 35.0.1, and 27.2.12479018 respectively. This change aligns with newer Android SDK capabilities.

docs/FLUTTER_VERSION.md (2)

7-8: Update Flutter Version Documentation
The documented current version has been updated from 3.22.3 to 3.29.0, which clearly informs users of the new stable release.


11-13: Update Git Checkout Command
The instructions now recommend using git checkout 3.29.0 to switch to the updated Flutter version. This is clear and consistent with the version bump.

docs/BUILD_RUN_APP.md (2)

110-121: Enhance Windows Desktop Prerequisites Documentation
The added prerequisites for Windows desktop builds—including Visual Studio Community 17.13.0 with the Desktop development with C++ workload and NuGet CLI installation via winget—provide clearer setup instructions for Windows users.


182-210: Improve Robustness of PKG_CONFIG_PATH Setup on Linux
The updated Linux instructions now include installation of additional dependencies and modifications to PKG_CONFIG_PATH. Currently, the snippet checks only if PKG_CONFIG_PATH is empty before appending a fixed value. Consider enhancing this logic by verifying and appending missing paths instead of overwriting partial configurations.

.docker/komodo-wallet-android.dockerfile (1)

1-6: Environment and Base Image Update:
The update to the base image (komodo/android-sdk:35) along with the new environment variables (FLUTTER_VERSION set to "3.29.0", and HOME set to "/home/komodo") is clear and in line with the updated Android SDK requirements. The adjustment of the PATH variable to include Flutter’s binary directory is correctly implemented.

docs/INSTALL_FLUTTER.md (5)

9-10: Enhanced Installation Options:
The introduction of multiple installation options—using VS Code, the SDK Archive, or FVM—provides comprehensive guidance for various user preferences. This clarity is beneficial for new users.


11-14: VS Code Installation Section Clarity:
The new "Use VS Code to install" section effectively recommends the Flutter extension for VS Code (or Android Studio/IntelliJ), streamlining the process for beginners.


15-21: Download and Install Section:
The "Download and install" section is detailed—with links for Windows, Mac, and Linux—and clearly instructs users on how to obtain and set up the Flutter SDK manually. The structured layout aids readability.


40-46: Windows PATH Update Instructions:
The Windows instructions, laid out as a bulleted list, clearly describe the steps to modify the PATH environment variable via the system settings. This approach is user-friendly.


49-51: Verification Reminder:
The tip to verify the PATH setup by running which flutter on macOS and Linux is a helpful addition for troubleshooting.

docs/MULTIPLE_FLUTTER_VERSIONS.md (5)

6-9: macOS and Linux Instructions:
The instructions under the "macOS and Linux" section are clear and informative. The description of FVM’s role and the consolidated approach for local and global SDK management are well presented.


12-17: Bash Code Block for FVM Installation:
The bash code block that installs FVM using the installation script and then configures the Flutter version for the current directory is succinct and directly addresses user needs.


19-21: Section Separator and Windows Introduction:
The use of a separator (----) effectively distinguishes the sections, and the introduction to the Windows section is clear and sets up the following instructions well.


25-29: Chocolatey Installation Instructions:
The instructions for installing Chocolatey via a PowerShell command are detailed and provide a necessary prerequisite for Windows users, ensuring a smoother FVM installation process.


31-37: Windows FVM Installation Instructions:
The PowerShell code block for installing FVM using Chocolatey, followed by commands to configure and check the Flutter setup, is clear and effective.

CharlVS and others added 5 commits February 26, 2025 15:31
…dows (#2549)

* feature: remove `bip39` package and migrate to SDK

Remove `bip39` package and migrate seed validation to SDK

* fix: Remove seed from registration

- Remove the seed parameter from registration since KDF is responsible for generating seeds.
- Update to reference the correct bloc event.
- Change default wallet type to HD.
Upgrade the KDF SDK version for bug fixes.
* Fix some grammar in the EULA/ToC

* rm surplus `-`
* ci: add initial mobile and desktop workflows

* ci: fix apple-actions action name

* fix macos and ios builds

* change xcode version to latest stable

* fix merge issue and job issues

* fix android build

- remove mm2 linking in cpp, build.gradle, and MainActivity

* add debug builds on error & fix ios build order

* docs: add windows dependencies

* upgrade to flutter 3.27.0

* ci: add github token to platform build step

* ci: let flutter pub errors through for debugging

errors at the flutter pub get step currently cause the ci steps to fail with an exit code, but no logs pointing to the cause

* build(windows): add flutter build artefact changes

* ci: fix code validation warnings

* remove unnecessary asset declarations

missing folders result in build "errors" that act like warnings, but cause the builds on windows to fail

* ci: fix missing desktop archives

* ci: remove web validation step for mobile & desktop workflows

validation step only supports web for now

* ci: fix desktop build output path mismatch

* build(desktop): move executable copy step to kdf plugin

* build(android): bump jvm and gradle to latest stable versions

* chore(deps): bump sdk version

* chore(deps): fix iOS build by updating firebase packages

* build(android): upgrade jvm, kotlin, and video_player

* build(android): upgrade gradle plugin and kotlin language versions

gradle v8.8 and kotlin language v2.1.10

* ci: switch ui & unit test workflows to hosted runners

align with changes previously on dev/main, seeing as self-hosted runners are disabled for the time being

* ci(ios): add xcode simulator download to setup script

* ci(desktop): use the default platform for asset fetching/generation

* build: remove api section from build_config as it is not referenced

The build config is now primarily used in the SDK komodo_defi_framework package, and not in this repository

* ci: add repository check to certificate and signing setup steps

Copy over behaviour from komodo-wallet-desktop repository

* ci: fix coderabbitai nitpick comments and split signing documentation

* chore(docs): Clarify/expand Flutter version instructions

* chore(deps): update firebase for ios and macos

* ci(generate-assets): refactor build platform to build command input

reduce ci build time

* ci(ios): fix build error by defaulting to building web first

---------

Co-authored-by: Francois <[email protected]>
Co-authored-by: CharlVS <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (9)
docs/FLUTTER_VERSION.md (1)

13-28: Alternative Pinning Section:
The alternative section is well written. It clearly explains why pinning (i.e. locking to a specific Flutter version) is not recommended, and the command snippet (switching via “git checkout 3.29.0”) is up-to-date. Consider a brief troubleshooting note for users who may still face issues after switching versions.

.github/actions/releases/setup-windows/action.yml (2)

5-11: Input Parameters:
The inputs for the Base64-encoded PFX certificate and its password are descriptive and correctly marked as not required. You might consider adding additional validation or usage examples in the documentation for clarity.


30-38: Windows Code Signing Step:
The conditional step for setting up codesigning is well structured. The script decodes the certificate, converts the provided password to a secure string, imports the certificate, and removes the temporary file. To further improve resilience, you might add error handling (for example, checking if the Import-PfxCertificate command fails) to report issues during the import process.

.github/workflows/mobile-builds.yml (1)

59-65: Asset Generation Step and Trailing Spaces

The step to fetch packages and generate assets via the custom action is well implemented.

Note: Line 63 contains trailing spaces. Although this does not affect functionality, please remove them to comply with YAML linting standards.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 63-63: trailing spaces

(trailing-spaces)

docs/SIGN_RELEASE.md (2)

5-11: Android Keystore Generation

The instructions for generating a keystore with keytool are clear. For added clarity, consider briefly explaining key parameters to help new users.


102-112: Linux Signing Instructions

The Linux section covers GPG key generation and exporting correctly. For completeness, you might consider adding best practices for GPG key storage and usage.

.github/actions/validate-build/action.yml (1)

31-46: AssetManifest.bin and Coin Icon Check.
The script validates the presence of AssetManifest.bin and verifies that it includes the expected coin icon (assets/coin_icons/png/kmd.png). Note that the inner check (lines 42–45) appears redundant; consider streamlining that block to avoid duplication.

.github/actions/generate-assets/action.yml (1)

29-30: Remove Trailing Whitespace.
There are trailing spaces on these lines. For cleaner YAML formatting and to avoid potential linting issues, please remove any trailing spaces.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 29-29: trailing spaces

(trailing-spaces)


[error] 30-30: trailing spaces

(trailing-spaces)

.github/workflows/ui-tests-on-pr.yml (1)

95-105: Coverage Report Generation is Temporarily Disabled with Clear Documentation

The commented-out "Generate coverage report" block (lines 95–105) includes explanatory comments regarding issues with Hive and storage providers. This is helpful for future reference once the integration test coverage is fixed. Consider tracking this in an issue if not already done.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92cb33e and 21b82ba.

⛔ Files ignored due to path filters (1)
  • ios/Podfile.lock is excluded by !**/*.lock
📒 Files selected for processing (25)
  • .github/actions/flutter-deps/action.yml (1 hunks)
  • .github/actions/generate-assets/action.yml (1 hunks)
  • .github/actions/releases/setup-android/action.yml (1 hunks)
  • .github/actions/releases/setup-ios/action.yml (1 hunks)
  • .github/actions/releases/setup-linux/action.yml (1 hunks)
  • .github/actions/releases/setup-macos/action.yml (1 hunks)
  • .github/actions/releases/setup-windows/action.yml (1 hunks)
  • .github/actions/validate-build/action.yml (1 hunks)
  • .github/workflows/desktop-builds.yml (1 hunks)
  • .github/workflows/mobile-builds.yml (1 hunks)
  • .github/workflows/ui-tests-on-pr.yml (1 hunks)
  • .github/workflows/unit-tests-on-pr.yml (1 hunks)
  • .gitignore (3 hunks)
  • android/app/build.gradle (2 hunks)
  • android/app/src/main/cpp/CMakeLists.txt (0 hunks)
  • android/app/src/main/cpp/mm2_native.cpp (0 hunks)
  • android/app/src/main/java/com/komodoplatform/atomicdex/MainActivity.java (0 hunks)
  • android/gradle/wrapper/gradle-wrapper.properties (1 hunks)
  • android/settings.gradle (1 hunks)
  • app_build/build_config.json (1 hunks)
  • docs/BUILD_RELEASE.md (2 hunks)
  • docs/FLUTTER_VERSION.md (1 hunks)
  • docs/MULTIPLE_FLUTTER_VERSIONS.md (1 hunks)
  • docs/SIGN_RELEASE.md (1 hunks)
  • lib/bloc/analytics/analytics_repo.dart (2 hunks)
💤 Files with no reviewable changes (3)
  • android/app/src/main/cpp/mm2_native.cpp
  • android/app/src/main/cpp/CMakeLists.txt
  • android/app/src/main/java/com/komodoplatform/atomicdex/MainActivity.java
✅ Files skipped from review due to trivial changes (1)
  • docs/BUILD_RELEASE.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/bloc/analytics/analytics_repo.dart
🧰 Additional context used
🧠 Learnings (1)
android/app/build.gradle (1)
Learnt from: takenagain
PR: KomodoPlatform/komodo-wallet#2526
File: android/app/build.gradle:28-28
Timestamp: 2025-02-17T06:53:06.737Z
Learning: Android 15 (API Level 35) was released on October 15, 2024, making it a valid target for Android applications.
🪛 YAMLlint (1.35.1)
.github/workflows/mobile-builds.yml

[error] 63-63: trailing spaces

(trailing-spaces)

.github/actions/generate-assets/action.yml

[error] 29-29: trailing spaces

(trailing-spaces)


[error] 30-30: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Build Mobile (Android)
  • GitHub Check: Build Desktop (windows)
  • GitHub Check: Build Mobile (iOS)
🔇 Additional comments (111)
android/settings.gradle (1)

21-24: Update Gradle and Kotlin plugin versions.
The Android application plugin version is updated to “8.8.0” and the Kotlin Android plugin to “2.1.10”, with helpful comments linking to release notes. Please verify that these versions are compatible with all modules (e.g. the corresponding changes in the app’s build files).

android/gradle/wrapper/gradle-wrapper.properties (1)

3-4: Upgrade Gradle distribution version.
The distribution URL has been updated to “gradle-8.12.1-bin.zip” and the checksum adjusted accordingly. Ensure that the new checksum correctly matches the distribution file from Gradle’s release.

app_build/build_config.json (1)

3-7: Update coins configuration for build time fetching and repository URL.
A new property "fetch_at_build_enabled": true has been added under the coins section, and the repository URL for coin assets is updated from the GitHub raw URL to “https://komodoplatform.github.io/coins”. This aligns the configuration with the intended asset hosting location.

.github/actions/releases/setup-linux/action.yml (4)

2-12: Introduce “Setup Linux Build Environment” action.
The action is defined with two optional inputs for GPG key and key ID. The description clearly states the purpose. No issues detected in the input definitions.


16-24: Install system dependencies step looks robust.
The step installs a comprehensive list of Linux packages (including tools like ninja-build, libgtk-3-dev, clang, etc.). Consider verifying that all required libraries (e.g. for Flutter and code signing) are present on your target runners.


25-30: Ensure Flutter tool setup via “Install Linux build dependencies.”
The use of “flutter pub get” and “flutter doctor” is a good minimal check that Flutter is set up correctly.


31-39: Conditional Linux code signing step.
This step conditionally imports a provided GPG key and sets up the GPG agent. The conditional using if: inputs.gpg-key != '' && 'KomodoPlatform/komodo-wallet' == github.repository is clear. Verify that the destination paths (like ~/.devscripts) and configuration (e.g. “allow-preset-passphrase”) meet your security requirements.

.github/actions/releases/setup-macos/action.yml (7)

1-4: New “Setup macOS Build Environment” action header.
The action is introduced with a clear name and description to configure Flutter and its dependencies on macOS.


6-33: Input parameters are comprehensive and well defined.
Inputs for Xcode version, certificate (P12) file and password, bundle ID, provisioning profile type, and App Store Connect credentials are specified. The use of defaults (e.g. "latest-stable" for Xcode version and "com.komodo.wallet" for bundle-id) is appropriate.


37-41: Xcode setup step is correctly implemented.
Using the external action maxim-lobanov/setup-xcode@v1 with an input based on xcode-version ensures that the proper Xcode version is installed.


42-47: Configure Xcode command line tools.
The shell step switches to the proper developer directory and accepts the Xcode license. This is critical for non-interactive build environments.


48-54: Installation of macOS build dependencies.
The step runs flutter pub get and then enters the macos folder to perform a pod install, which is standard for Flutter macOS projects.


55-64: Import macOS certificate action.
This step conditionally invokes the action apple-actions/import-codesign-certs@v3 to import signing certificates. Using the github.run_id as both keychain and keychain-password is an interesting choice; please check that this meets your security and reproducibility standards.


65-73: Download macOS provisioning profile.
The action downloads the provisioning profile using inputs for bundle-id, profile type, and App Store Connect credentials. The condition ensures this only runs when the issuer ID is provided and the repository matches, which is appropriate.

docs/FLUTTER_VERSION.md (1)

1-12: Clarity & Updated Version Information:
The “Flutter Version Management” document now clearly states the supported version (Flutter 3.29.0) and outlines the recommended approach of using a version manager. The section hierarchy and the call to the guide on multiple Flutter versions help guide users to the detailed documentation.

.github/actions/releases/setup-windows/action.yml (4)

1-4: Workflow Metadata & Description:
The workflow name “Setup Windows Build Environment” and its description clearly reflect the purpose of configuring the Flutter environment and dependencies for Windows builds.


16-18: Visual Studio Setup Step:
The step using microsoft/[email protected] is straightforward and is an appropriate method to ensure Visual Studio is ready for builds.


19-23: Windows SDK Installation:
Using GuillaumeFalourd/setup-windows10-sdk-action@v2 with the given sdk-version is correctly implemented to install the required Windows SDK.


24-29: Build Dependencies Installation:
The PowerShell step running flutter pub get and flutter doctor covers the essential dependency checks. It’s concise yet effective in initializing the build environment.

.github/actions/releases/setup-ios/action.yml (6)

1-4: Workflow Metadata & Description:
The workflow “Setup iOS Build Environment” is clearly named and described to configure Xcode and manage iOS signing requirements. This change lays a good foundation for automating iOS build setups.


5-33: Input Parameters:
All inputs—including the Xcode version, certificate details, bundle-id, profile type, and App Store Connect credentials—are clearly defined with appropriate defaults. This will allow users to flexibly configure the iOS build environment.


34-41: Xcode Setup Step:
Using the maxim-lobanov/setup-xcode@v1 action to set up the specified Xcode version (defaulting to “latest-stable”) is an optimal choice. This ensures the build environment meets current Xcode requirements.


42-52: Install iOS Dependencies:
The added step downloads the iOS platform via xcodebuild -downloadPlatform iOS, runs flutter pub get, and then changes directory to ios for pod install. This sequence helps mitigate issues with missing simulator platforms in Xcode 15 and ensures CocoaPods dependencies are correctly installed.


53-59: Import iOS Certificates:
The conditional step for importing iOS certificates using apple-actions/import-codesign-certs@v3 is implemented correctly. The condition ensures that this step runs only if the certificate is provided and if the repository matches “KomodoPlatform/komodo-wallet”.


60-69: Download Provisioning Profile:
This step downloads the provisioning profile using apple-actions/download-provisioning-profiles@v1 conditioned on a provided issuer ID. All necessary inputs (bundle-id, profile-type, issuer-id, api-key-id, api-private-key) are passed correctly. This configuration should streamline provisioning profile management for iOS builds.

.github/workflows/mobile-builds.yml (5)

1-10: Workflow Metadata and Trigger Configuration

The workflow defines its name, run name, and triggers (pull_request, workflow_dispatch, release) clearly. Verify that the branch patterns and release types match your intended deployment strategies.


31-37: Checkout and Dependencies Setup

The checkout step using actions/checkout@v4 and the subsequent installation of Flutter dependencies via the custom action are correctly implemented.


38-49: Platform-specific iOS Environment Setup

The iOS environment is properly configured with secrets for the P12 file, password, bundle ID, and related App Store credentials. Ensure that the values (e.g. "IOS_APP_STORE") match your deployment requirements.


50-58: Platform-specific Android Environment Setup

The Android environment setup correctly references the keystore credentials via secrets. No issues are identified in this segment.


66-77: Build and Artifact Upload Steps

The build step runs using the matrix variable for the build command, and the artifact upload is configured with a five‐day retention period. Everything appears to be in order.

.github/actions/flutter-deps/action.yml (3)

1-5: Action Metadata and Composite Configuration

The action's metadata (name and description) and the composite run configuration are clearly defined.


6-11: Stable Flutter Installation Step

The step uses subosito/flutter-action@v2 with a fixed version ("3.29.x") from the stable channel. This is a robust choice for consistent Flutter installs.


12-20: Prepare Build Directory Step

The bash step cleans previous build artifacts and removes specific directories (e.g. web/src/mm2/*, web/src/kdfi/*, web/dist/*). Verify that these paths correctly reflect your project structure.

.github/workflows/unit-tests-on-pr.yml (8)

1-4: Unit Test Workflow Metadata

The workflow name and personalized run name using ${{ github.actor }} are well configured to trigger on the proper pull request events.


10-12: Job Configuration

The unit_tests job is set to run on ubuntu-latest with an appropriate timeout. This configuration is straightforward and effective.


15-17: Code Checkout Step

The checkout step using actions/checkout@v4 is correctly implemented.


18-20: Flutter Dependencies Installation

The custom action to install Flutter and its dependencies ensures consistency in your test environment.


21-25: Asset Generation Step

The asset generation step uses the custom action with the GitHub token passed securely. The configuration meets the requirements.


26-28: Build Validation Step

The use of the custom action for validating the build encapsulates the necessary checks, contributing to a cleaner workflow.


29-37: Unit Test Execution Step

The testing step uses the provided environment variable and runs the tests on test_units/main.dart. Confirm the file path is correct for your unit tests.


38-44: Unit Test Coverage Report Generation

Generating the coverage report via the custom action is well executed, with an explicit test_file parameter ensuring the proper test run.

android/app/build.gradle (5)

25-27: Android Build Configuration Header

The initial section that sets the namespace and Flutter version details is correctly configured.


28-35: SDK and Language Version Updates

The compileSdk is now updated to 35, and the compileOptions have been shifted to use JavaVersion.VERSION_21 for both source and target compatibility. Similarly, the Kotlin jvmTarget is now set to '21'.

Verification Required: Double-check that all your dependencies and Gradle plugins are compatible with Java 21 since this is an uncommon jump compared to the more standard versions.


36-38: Source Sets Configuration

The modification of the sourceSets (adding src/main/kotlin) improves Kotlin integration; this is standard and acceptable.


40-46: Application Default Configuration

The defaultConfig block properly defines the applicationId, minSdkVersion (28), and updates the targetSdkVersion to 35. Versioning via Flutter properties is handled correctly.


47-52: NDK Version Update

The ndkVersion is updated to 27.2.12479018, aligning with recent stable releases. Ensure your native components remain fully compatible with this version.

docs/SIGN_RELEASE.md (12)

1-4: New Signing Release Documentation

This new file introduces a comprehensive guide for signing builds across platforms. The overall structure—with distinct sections for Android, iOS/macOS, Windows, and Linux—is clear and well organized.


12-16: Convert Keystore to Base64

The provided base64 conversion step is accurate. Ensure that file permissions and security aspects are appropriately managed after conversion.


17-22: Keystore Validation

Using keytool -list to validate the keystore is a solid approach. You might add common troubleshooting hints for potential errors.


32-35: Android Signing Resources

The reference link to the Android Signing Guide is valuable for further details.


36-55: iOS/macOS Signing Instructions

The guide covers the necessary steps—from creating an Apple Developer account to exporting certificates. The instructions are clear and logically ordered.


56-64: iOS/macOS Signing Secrets Example

The YAML snippet for iOS/macOS secrets (IOS_P12_BASE64, IOS_P12_PASSWORD, etc.) is comprehensive. Ensure the private keys and certificates are maintained securely.


65-73: iOS/macOS Signing Documentation

The provided links to external resources enhance this section. They offer good additional guidance for users who may need more details.


74-83: Windows Code Signing Instructions

The Windows section correctly outlines the process to export and convert a PFX certificate for signing. The validation command using signtool is also well explained.


84-95: Windows Signing Secrets Example

The YAML example for Windows signing is clear. As with other secret examples, verify that placeholder values are replaced before production use.


96-101: Windows Signing Resources

The documentation links for Windows code signing provide useful additional context.


113-121: Linux Signing Validation

The validation command using GPG is clear. Confirm that instructions include any prerequisites for installing GPG on various distributions.


122-179: Summary of GitHub Workflow Secrets

The summary tables categorizing secrets for iOS, macOS, Android, Windows, and Linux provide a clear resource for managing CI/CD secrets. This greatly increases the maintainability of your build pipelines.

.github/workflows/desktop-builds.yml (6)

1-10: Workflow Metadata and Triggers.
The workflow is clearly defined with proper triggers (pull requests, manual dispatch, and release creation), and the run‐name provides good context.


18-34: Matrix Strategy and Platform Configuration.
The matrix correctly enumerates macOS, Windows, and Linux configurations with appropriate runner images, build commands, artifact paths, and artifact names. This setup will ensure each desktop build is run under its designated environment.


36-41: Checkout and Dependency Installation.
Using actions/checkout@v4 followed by invoking the local flutter-deps composite action ensures that the repository is checked out and the Flutter environment is properly set up before any platform-specific actions occur.


42-70: Platform-Specific Setup Steps.
The conditional steps for macOS (with signing details), Linux, and Windows are all well implemented. The use of secrets in each platform’s configuration appears secure and meets best practices. Verify that the secret names match what’s expected in your CI/CD settings.


71-76: Asset Generation Action Invocation.
The step that calls the generate-assets action with appropriate inputs (GitHub token and build command) is clear and modular. This promotes reusability in the workflow.


77-88: Build Execution and Artifact Upload.
Running the build command via an environment variable and then uploading artifacts (with a defined retention period) is implemented correctly. This helps ensure that the correct build output is captured and archived.

.github/actions/releases/setup-android/action.yml (5)

1-4: Action Identification and Description.
The action is well named ("Setup Android Build Environment") and includes a concise description to explain its purpose.


5-21: Input Parameters Configuration.
All inputs (including java-version, keystore-base64, key-alias, store-password, and key-password) are clearly defined with appropriate descriptions and a default for the Java version. This makes the action flexible for different Android build scenarios.


23-32: JDK Setup Step.
The step using actions/setup-java@v4 is properly configured with the input variable for Java version, temurin for distribution, and caching enabled for Gradle. This should help reduce build times.


33-35: Android SDK Installation.
Using the android-actions/setup-android@v3 action correctly establishes the Android SDK environment.


36-46: Android Keystore Setup.
The conditional step that decodes the Base64 keystore and writes out the android/key.properties file is clear and robust. Removing any previous version of the file with rm -f helps avoid duplication issues.

.github/actions/validate-build/action.yml (6)

1-3: Action Metadata and Description.
The action is aptly named "Validate build" and the description clearly states its purpose—to check for all necessary build files.


10-23: WebAssembly File Validation.
The script checks for the existence of a wasm file in the expected directory and provides directory listings for debugging when missing. This is valuable for diagnosing build issues with the web target.


25-29: Index.html Comparison.
Using cmp -s to ensure that the generated build/web/index.html matches the source web/index.html is a strict but effective check for build consistency.


48-57: build_config.json Validation.
The action ensures that app_build/build_config.json exists and is valid JSON using jq. This helps catch any formatting errors early in the build process.


59-68: coins.json Validation.
The script confirms the existence and JSON structural integrity of $COIN_ASSETS_DIR/config/coins.json. This is critical for proper coin asset handling.


70-79: coins_config.json Validation.
Similarly, checking for both the presence and valid JSON formatting of $COIN_ASSETS_DIR/config/coins_config.json ensures that the necessary configuration is in place.

.github/actions/generate-assets/action.yml (8)

1-3: Action Definition and Metadata.
The composite action is clearly defined with the name "Generates assets" and a useful description that explains its role in transforming and generating assets.


4-11: Input Parameters Configuration.
The inputs for GITHUB_TOKEN (required) and BUILD_COMMAND (with a default value) are precisely defined. This allows the action to be flexible while ensuring that critical parameters are provided.


12-14: Composite Runner Configuration.
The action correctly sets up the composite runner with the using: "composite" method.


15-19: Environment Variable Setup for Secure Token Usage.
Mapping GITHUB_API_PUBLIC_READONLY_TOKEN directly from the input variable optimizes secure token usage in the subsequent build steps.


20-27: Token Validation Logic.
The run script checks if the GitHub token is provided and prints the appropriate message. The conditional unsetting of the variable when not provided is a good touch to ensure no empty values affect downstream commands.


32-34: Preliminary Flutter Build Execution.
By running flutter pub get and the build command once (and allowing failure via || true), the action pre-downloads coin icons and configuration files. This preliminary step is clever and sets up the second build execution.


36-42: Final Build Execution and Output Capture.
The script captures the output and exit status from running the build command a second time. This is an effective way to halt the process upon encountering genuine errors while allowing known expected failures during the first run.


43-49: Error Handling and Completion Confirmation.
If the build exit status is non-zero, the script prints the output and exits with the given status. The final echo statement confirms successful asset generation.

.gitignore (5)

1-3: Excluding First-Party SDK Files.
Adding the sdk/ entry is a solid change to ensure that generated or bundled SDK artifacts are not committed to version control.


41-42: Ignoring DevTools Configuration Files.
The addition of devtools_options.yaml helps prevent unwanted local configuration files from being tracked.


44-45: Refined Web Ignore Patterns.
Ignoring web/index.html and all files under web/src/ prevents build artifacts or source files that are regenerated during deployment from being committed. Confirm that these files are automatically rebuilt as needed.


81-86: Excluding Environment and Build Caches.
The new ignore entries for venv/, .fvm/, and /macos/build keep development caches and build directories out of version control, which is ideal for maintaining a clean repository.


40-50: Asset Tracking Adjustments.
The removal of ignore rules for asset configuration directories (e.g. assets/config/) and coin icon directories (e.g. assets/coin_icons/) ensures that these critical assets are tracked by Git and available to the project.

docs/MULTIPLE_FLUTTER_VERSIONS.md (12)

1-3: Title & Introduction are Clear and Informative

The updated title "Managing Multiple Flutter Versions" clearly reflects the content, and the introductory paragraph on lines 1–3 concisely describes the purpose of the document.


5-7: List of Recommended Tools is Well-Structured

The list introducing Flutter Sidekick and FVM (Flutter Version Manager) is clear and helps set expectations for readers with different expertise.


8-11: Pre-Installation Instructions Outlined Effectively

The "Before You Begin: Remove Existing Flutter Installations" section (lines 8–11) provides necessary context to avoid conflicts. This sets a good foundation for the subsequent installation steps.


12-22: macOS Uninstallation Steps are Clear

The instructions for macOS (lines 12–22), including removal via Git and Homebrew, are well-explained. The code block format for the commands enhances readability.


24-32: Windows Uninstallation Instructions are Detailed

The Windows section (lines 24–32) efficiently explains both manual uninstallation and the winget approach. This provides users with multiple options depending on their installation method.


34-45: Linux Uninstallation Guidelines are Comprehensive

The Linux instructions (lines 34–45) cover both Git-based and package-manager installations, along with guidance on updating the PATH. These details will help avoid configuration conflicts.


47-67: Flutter Sidekick Section is User-Friendly

The "Option 1: Flutter Sidekick" section (lines 47–67) is well-organized. The step-by-step installation instructions, including setting the default version and updating the PATH, are clear and accessible for beginners.


73-81: FVM Overview Provides Clarity on Advanced Usage

The introductory part of "Option 2: FVM Command Line" (lines 73–81) succinctly explains the advantages of FVM for CI/CD and non-GUI environments.


82-109: macOS & Linux FVM Setup is Accurate and Detailed

The FVM installation and configuration instructions for macOS/Linux (lines 82–109) are comprehensive—from installing via a script to configuring the shell PATH and verifying Flutter. This section should serve as a reliable guide for users on these platforms.


110-137: Windows FVM Setup Provides Clear Guidance

The step-by-step instructions for installing FVM on Windows (lines 110–137) are thorough and include specific commands (e.g., using Chocolatey). The details regarding PATH configuration are particularly helpful.


138-148: Project-Specific Flutter Version Instructions are Straightforward

The section on enforcing a project-specific Flutter version (lines 138–148) is clear. Explaining the purpose of the generated .fvmrc file helps users understand the benefits of this configuration.


150-170: VS Code Integration Section Enhances Developer Experience

The "Using with VS Code" section (lines 150–170) is well-detailed. The instructions for installing the Flutter FVM extension and configuring the .vscode/settings.json file are clear. This ensures that users can seamlessly integrate Flutter version management with their IDE.

.github/workflows/ui-tests-on-pr.yml (11)

1-4: Workflow Header Update is Effective

The updated workflow name "UI Integration tests on PR" and the dynamic run-name (including the GitHub actor) improve clarity and traceability of test runs. These changes set a positive tone for the CI process.


16-29: Matrix Configuration for web-app-linux-profile is Well-Defined

The new matrix entry for "web-app-linux-profile" (lines 16–29) clearly specifies parameters for the Chrome-based tests, including browser, display mode, resolution, and driver log paths. This granularity is beneficial for targeted testing scenarios.


30-40: Matrix Entry for web-app-macos is Clear and Contextualized

The matrix entry for "web-app-macos" (lines 30–40) specifies appropriate settings for Safari, including comments noting that display and resolution settings do not affect safaridriver. This contextual guidance is useful.


45-54: Conditional Setup for Chrome and Chromedriver is Appropriately Scoped

The step "Install Chrome and chromedriver" (lines 45–54) uses a conditional check for Chrome-based tests. The inclusion of parameters like chrome-version and automatic dependency installation is precise and should streamline the test environment setup.


55-62: Safaridriver Enablement Step is Necessary for macOS

The conditional step to enable safaridriver (lines 55–62) is correctly gated for Safari testing. The use of the defaults write commands, along with a fallback echo statement on failure, provides a robust setup for macOS environments.


63-65: Flutter Dependencies Step Modularizes the Setup

The "Install Flutter and dependencies" step (lines 63–65) leverages a dedicated action. This modularity should help maintain the workflow and allows for centralized updates to Flutter dependency handling.


66-70: Separation of Package Fetching and Asset Generation Improves Readability

The "Fetch packages and generate assets" step (lines 66–70) is clearly delineated from the Flutter dependencies installation, which improves the maintainability of the workflow by isolating asset generation logic.


71-73: Build Validation Action Enhances Confidence in the Release Process

The "Validate build" step (lines 71–73) encapsulates build-validation into a reusable action. This abstraction aligns with best practices by decoupling validation logic from testing logic.


74-86: Integration Test Execution is Dynamic and Configurable

The integration tests step (lines 74–86) uses matrix variables effectively to pass dynamic parameters (such as display mode, resolution, browser, and mode) to the test runner. This design supports diverse testing environments and configurations.


88-94: Driver Logs Upload Step is Well-Implemented

The "Upload driver logs" step (lines 88–94) correctly uses an artifact upload action and conditionally warns if no files are found. This ensures that logs are captured for troubleshooting without halting the workflow unnecessarily.


106-109: Fail Workflow Step Ensures Test Reliability

The final step "Fail workflow if tests failed" (lines 106–109) appropriately terminates the workflow when tests do not pass. This explicit check reinforces the reliability of the CI process.

Comment on lines +23 to +30
Example secrets:

```yaml
ANDROID_KEYSTORE_BASE64: "/u3+7QAAAAIAAAABAAAAAQAHa29tb2RvAAABjK6LSU8AAAUBMIIE..."
ANDROID_KEY_ALIAS: "komodo"
ANDROID_STORE_PASSWORD: "your-keystore-password"
ANDROID_KEY_PASSWORD: "your-key-password"
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Android Signing Secrets Example

The YAML example with keys (ANDROID_KEYSTORE_BASE64, ANDROID_KEY_ALIAS, etc.) is informative. Make sure to replace any placeholder values with actual secrets and add a comment to warn against committing sensitive information.

#2556)

Role KDF SDK to` af79b7d09ab3f3b45ff6767b9556c514f09b25ce ` to fix Windows crashes for devices with Nvidia GPUs. Bug report to be filed with Nvidia.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants