Skip to content

Conversation

@CharlVS
Copy link
Collaborator

@CharlVS CharlVS commented Feb 11, 2025

Komodo Wallet v0.9.0 Release

We are excited to announce Komodo Wallet v0.9.0. This release introduces HD wallet functionality, cross-platform fiat on-ramp improvements, a new feedback provider, and numerous bug fixes and dependency upgrades.

Under the hood, the app has undergone a major rewrite to migrate to our new KDF Flutter SDK. This allows developers to quickly and easily build their own DeFi applications in hours instead of months. See the SDK package for more information.

The codebase is now unified across all web, desktop, and mobile platforms. This change allows for more consistent development and easier maintenance.

🚀 New Features

🎨 UI/UX Improvements

⚡ Performance Enhancements

🐛 Bug Fixes

🔒 Security Updates

💻 Platform-specific Changes

iOS & macOS

Web/Desktop/Mobile

⚠️ Breaking Changes

Full Changelog: 0.8.3...0.9.0

Changelog

TODO

KDF SDK

This app migrates most of our codebase to the new KDF Flutter SDK, which showcases how even hobbyist developers can build their own GUI apps using our simple tools and avoiding the months of headache and time invested in starting from scratch.

Due to this dual benefit, we appreciate your patience with any teething issues or regressions of existing features.

OPSEC

Dependencies Diff Summary

See the generated diff summary in Google Drive for more info and a patch of the code changes.

The directory includes the following:

  • A directory with patches of the packages' changed code, split by package. Link
  • A patch file for the code of all changed packages. Prefer using the split diff above because this file will likely crash your IDE's diff viewer. Link
  • A summary of the changed packages in markdown format. Link
  • A summary of the changed packages in CSV format. Link.
  • A summary of all unchanged packages. Link

The diff summary is generated using our diff-summary-generator.

Package Dependencies Summary (Click to Expand/Collapse)
Package Status Old version New version Dependency Old sha256 New sha256
cli_config Added - 0.2.0 transitive - pub:ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
decimal Added - 3.2.1 direct main - pub:28239b8b929c1bd8618702e6dbc96e2618cf99770bbe9cb040d6cf56a11e4ec3
feedback Added - 3.1.0 direct main - pub:26769f73de6215add72074d24e4a23542e4c02a8fd1a873e7c93da5dc9c1d362
fixnum Added - 1.1.1 transitive - pub:b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
flutter_inappwebview_windows Added - 0.6.0 transitive - pub:8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055
flutter_secure_storage Added - 10.0.0-beta.4 transitive - pub:f7eceb0bc6f4fd0441e29d43cab9ac2a1c5ffd7ea7b64075136b718c46954874
flutter_secure_storage_darwin Added - 0.1.0 transitive - pub:f226f2a572bed96bc6542198ebaec227150786e34311d455a7e2d3d06d951845
flutter_secure_storage_linux Added - 2.0.1 transitive - pub:9b4b73127e857cd3117d43a70fa3dddadb6e0b253be62e6a6ab85caa0742182c
flutter_secure_storage_platform_interface Added - 2.0.1 transitive - pub:8ceea1223bee3c6ac1a22dabd8feefc550e4729b3675de4b5900f55afcb435d6
flutter_secure_storage_web Added - 2.0.0 transitive - pub:4c3f233e739545c6cb09286eeec1cc4744138372b985113acc904f7263bef517
flutter_secure_storage_windows Added - 4.0.0 transitive - pub:ff32af20f70a8d0e59b2938fc92de35b54a74671041c814275afd80e27df9f21
freezed_annotation Added - 3.0.0 transitive - pub:c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b
get_it Added - 8.0.3 direct main - pub:f126a3e286b7f5b578bf436d5592968706c4c1de28a228b870ce375d9f743103
json_annotation Added - 4.9.0 transitive - pub:1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1
komodo_coins Added - 0.2.0+0 transitive - git:f001976b706cbdbf4bd230445a101caf282b5651
komodo_defi_framework Added - 0.2.0 transitive - git:f001976b706cbdbf4bd230445a101caf282b5651
komodo_defi_local_auth Added - 0.2.0+0 transitive - git:f001976b706cbdbf4bd230445a101caf282b5651
komodo_defi_rpc_methods Added - 0.2.0+0 transitive - git:f001976b706cbdbf4bd230445a101caf282b5651
komodo_defi_sdk Added - 0.2.0+0 direct main - git:f001976b706cbdbf4bd230445a101caf282b5651
komodo_defi_types Added - 0.2.0+0 direct main - git:f001976b706cbdbf4bd230445a101caf282b5651
komodo_ui Added - 0.2.0+0 direct main - git:f001976b706cbdbf4bd230445a101caf282b5651
local_auth Added - 2.3.0 transitive - pub:434d854cf478f17f12ab29a76a02b3067f86a63a6d6c4eb8fbfdcfe4879c1b7b
local_auth_android Added - 1.0.48 transitive - pub:0abe4e72f55c785b28900de52a2522c86baba0988838b5dc22241b072ecccd74
local_auth_darwin Added - 1.4.3 transitive - pub:630996cd7b7f28f5ab92432c4b35d055dd03a747bc319e5ffbb3c4806a3e50d2
local_auth_platform_interface Added - 1.0.10 transitive - pub:1b842ff177a7068442eae093b64abe3592f816afd2a533c0ebcdbe40f9d2075a
local_auth_windows Added - 1.0.11 transitive - pub:bc4e66a29b0fdf751aafbec923b5bed7ad6ed3614875d8151afe2578520b2ab5
mutex Added - 3.1.0 transitive - pub:8827da25de792088eb33e572115a5eb0d61d61a3c01acbc8bcbe76ed78f1a1f2
sprintf Added - 7.0.0 transitive - pub:1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23
web_socket Added - 0.1.6 transitive - pub:3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83
bip39 Removed 1.0.6 - direct main git:3633daa2026b98c523ae9a091322be2903f7a8ab -
desktop_webview_window Removed 0.2.3 - direct main pub:57cf20d81689d5cbb1adfd0017e96b669398a669d927906073b0e42fc64111c0 -
hex Removed 0.2.0 - transitive pub:4e7cd54e4b59ba026432a6be2dd9d96e4c5205725194997193bf871703b82c4a -
komodo_coin_updates Removed 1.0.0 - direct main - -
_fe_analyzer_shared Updated 67.0.0 80.0.0 transitive pub:0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7 pub:dc27559385e905ad30838356c5f5d574014ba39872d732111cd07ac0beff4c57
_flutterfire_internals Updated 1.3.33 1.3.54 transitive pub:2350805d7afefb0efe7acd325cb19d3ae8ba4039b906eade3807ffb69938a01f pub:de9ecbb3ddafd446095f7e833c853aff2fa1682b017921fe63a833f9d6f0e422
analyzer Updated 6.4.1 7.3.0 transitive pub:37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d pub:192d1c5b944e7e53b24b5586db760db934b177d4147c42fbca8c8c5f1eb8d11e
args Updated 2.5.0 2.7.0 direct main pub:7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a pub:d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
asn1lib Updated 1.5.3 1.6.2 transitive pub:58082b3f0dca697204dbab0ef9ff208bfaea7767ea771076af9a343488428dda pub:e02d018628c870ef2d7f03e33f9ad179d89ff6ec52ca6c56bcb80bcef979867f
async Updated 2.11.0 2.12.0 transitive pub:947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c pub:d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
badges Updated 3.1.1 3.1.2 direct main git:69958a3a2d6d5dd108393832acde6bda06bd10bc pub:a7b6bbd60dce418df0db3058b53f9d083c22cdb5132a052145dc267494df0b84
bloc Updated 8.1.4 9.0.0 transitive pub:106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e pub:52c10575f4445c61dd9e0cafcc6356fdd827c4c64dd7945ef3c4105f6b6ac189
bloc_concurrency Updated 0.2.5 0.3.0 direct main pub:456b7a3616a7c1ceb975c14441b3f198bf57d81cb95b7c6de5cb0c60201afcd8 pub:86b7b17a0a78f77fca0d7c030632b59b593b22acea2d96972588f40d4ef53a94
boolean_selector Updated 2.1.1 2.1.2 transitive pub:6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66 pub:8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea
characters Updated 1.3.0 1.4.0 transitive pub:04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605 pub:f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
charcode Updated 1.3.1 1.4.0 transitive pub:fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 pub:fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a
clock Updated 1.1.1 1.1.2 transitive pub:cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf pub:fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
collection Updated 1.18.0 1.19.1 transitive pub:ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a pub:2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76
convert Updated 3.1.1 3.1.2 transitive pub:0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592 pub:b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
coverage Updated 1.8.0 1.12.0 transitive pub:3945034e86ea203af7a056d98e98e42a5518fff200d6e8e6647e1886b07e936e pub:9086475ef2da7102a0c0a4e37e1e30707e7fb7b6d28c209f559a9c5f8ce42016
cross_file Updated 0.3.3+4 0.3.4+2 direct main pub:0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9 pub:7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670
crypto Updated 3.0.3 3.0.6 direct main pub:ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab pub:1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855
csslib Updated 0.17.3 1.0.2 transitive pub:831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f pub:09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e
dragon_logs Updated 1.0.3 1.1.0 direct main pub:00bec36566176f7f6c243142530a1abf22416d728a283949b92408a0d1f6a442 pub:e697f25bd0f27b0b85af42aff7f55f003fe045c0e3eeda6164bf97aab1525804
easy_localization Updated 3.0.7 3.0.7+1 direct main pub:fa59bcdbbb911a764aa6acf96bbb6fa7a5cf8234354fc45ec1a43a0349ef0201 pub:0f5239c7b8ab06c66440cfb0e9aa4b4640429c6668d5a42fe389c5de42220b12
encrypt Updated 5.0.2 5.0.3 direct main git:3a42d25b0c356606c26a238384b9f2189572d954 pub:62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2
equatable Updated 2.0.5 2.0.7 direct main git:2117551ff3054f8edb1a58f63ffe1832a8d25623 pub:567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7
fake_async Updated 1.3.1 1.3.2 transitive pub:511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78 pub:6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc
ffi Updated 2.1.2 2.1.4 transitive pub:493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21 pub:289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418
file Updated 7.0.0 7.0.1 transitive pub:5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c pub:a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
file_picker Updated 5.3.1 10.1.2 direct main git:85ecbae83eca8d200f869403928d2bf7e6806c67 pub:8986dec4581b4bcd4b6df5d75a2ea0bede3db802f500635d05fa8be298f9467f
file_system_access_api Updated 1.1.0 2.0.0 transitive pub:bcbf061ce180dffcceed9faefab513e87bff1eef38c3ed99cf7c3bbbc65a34e1 pub:c961c5020ab4e5f05200dbdd9809c5256c3dc4a1fe5746ca7d8cf8e8cc11c47d
firebase_analytics Updated 10.10.5 11.4.5 direct main pub:51afa4751e8d17d1484c193b7e9759abbae324e1b8f5cc93e2a08daac4d55928 pub:2416b9d864412ab7b571dafded801bbcc7e29b5824623c055002d4d0819bea2b
firebase_analytics_platform_interface Updated 3.10.6 4.3.5 transitive pub:ad7f6b70304e2b81c6079a5830355edc87496527d5b104d34c3e50b5b744da83 pub:3ccf5c876a8bea186016de4bcf53fc1bc6fa01236d740fb501d7ef9be356c58e
firebase_analytics_web Updated 0.5.7+5 0.5.10+11 transitive pub:63ed03d229d1c2ec2b1be037cd4760c3516cc8ecf6598a6b2fb8ca29586bf464 pub:5e4e3f001b67c2034b76cb2a42a0eed330fb3a8fb41ad13eceb04e8d9a74f662
firebase_core Updated 2.31.0 3.13.0 direct main pub:372d94ced114b9c40cb85e18c50ac94a7e998c8eec630c50d7aec047847d27bf pub:017d17d9915670e6117497e640b2859e0b868026ea36bf3a57feb28c3b97debe
firebase_core_platform_interface Updated 5.0.0 5.4.0 transitive pub:c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63 pub:d7253d255ff10f85cfd2adaba9ac17bae878fa3ba577462451163bd9f1d1f0bf
firebase_core_web Updated 2.17.0 2.22.0 transitive pub:43d9e951ac52b87ae9cc38ecdcca1e8fa7b52a1dd26a96085ba41ce5108db8e9 pub:129a34d1e0fb62e2b488d988a1fc26cc15636357e50944ffee2862efe8929b23
flutter_bloc Updated 8.1.1 9.1.0 direct main git:32d5002fb8b8a1e548fe8021d8468327680875ff pub:1046d719fbdf230330d3443187cc33cc11963d15c9089f6cc56faa42a4c5f0cc
flutter_inappwebview Updated 6.0.0 6.1.5 direct main pub:3e9a443a18ecef966fb930c3a76ca5ab6a7aafc0c7b5e14a4a850cf107b09959 pub:80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5
flutter_inappwebview_android Updated 1.0.13 1.1.3 transitive pub:d247f6ed417f1f8c364612fa05a2ecba7f775c8d0c044c1d3b9ee33a6515c421 pub:62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba
flutter_inappwebview_internal_annotations Updated 1.1.1 1.2.0 transitive pub:5f80fd30e208ddded7dbbcd0d569e7995f9f63d45ea3f548d8dd4c0b473fb4c8 pub:787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd
flutter_inappwebview_ios Updated 1.0.13 1.1.2 transitive pub:f363577208b97b10b319cd0c428555cd8493e88b468019a8c5635a0e4312bd0f pub:5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d
flutter_inappwebview_macos Updated 1.0.11 1.1.2 transitive pub:b55b9e506c549ce88e26580351d2c71d54f4825901666bd6cfa4be9415bb2636 pub:c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1
flutter_inappwebview_platform_interface Updated 1.0.10 1.3.0+1 transitive pub:545fd4c25a07d2775f7d5af05a979b2cac4fbf79393b0a7f5d33ba39ba4f6187 pub:cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500
flutter_inappwebview_web Updated 1.0.8 1.1.2 transitive pub:d8c680abfb6fec71609a700199635d38a744df0febd5544c5a020bd73de8ee07 pub:55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598
flutter_lints Updated 2.0.3 5.0.0 direct dev pub:a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 pub:5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1
flutter_markdown Updated 0.6.14 0.7.7 direct main pub:7b25c10de1fea883f3c4f9b8389506b54053cd00807beab69fd65c8653a2711f pub:634622a3a826d67cb05c0e3e576d1812c430fa98404e95b60b131775c73d76ec
flutter_plugin_android_lifecycle Updated 2.0.19 2.0.27 transitive pub:8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f pub:5a1e6fb2c0561958d7e4c33574674bda7b77caaca7a33b758876956f2902eea3
flutter_slidable Updated 3.1.0 4.0.0 direct main pub:673403d2eeef1f9e8483bd6d8d92aae73b1d8bd71f382bc3930f699c731bc27c pub:ab7dbb16f783307c9d7762ede2593ce32c220ba2ba0fd540a3db8e9a3acba71a
flutter_svg Updated 2.0.7 2.0.17 direct main git:d7b5c23a79dcb5425548879bdb79a5e7f5097ce5 pub:c200fd79c918a40c5cd50ea0877fa13f81bdaf6f0a5d3dbcc2a13e3285d6aa1b
formz Updated 0.7.0 0.8.0 direct main pub:a58eb48d84685b7ffafac1d143bf47d585bf54c7db89fe81c175dfd6e53201c7 pub:382c7be452ff76833f9efa0b2333fec3a576393f6d2c7801725bed502f3d40c3
glob Updated 2.1.2 2.1.3 transitive pub:0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63 pub:c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
hive Updated 2.2.3 2.2.3 direct main git:470473ffc1ba39f6c90f31ababe0ee63b76b69fe pub:8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941
hive_flutter Updated 1.1.0 1.1.0 direct main git:0cbaab793be77b19b4740bc85d7ea6461b9762b4 pub:dca1da446b1d808a51689fb5d0c6c9510c0a2ba01e22805d492c73b68e33eecc
html Updated 0.15.4 0.15.5+1 transitive pub:3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a pub:9475be233c437f0e3637af55e7702cbbe5c23a68bd56e8a5fa2d426297b7c6c8
http Updated 0.13.6 1.3.0 direct main pub:5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2 pub:fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
http_multi_server Updated 3.2.1 3.2.2 transitive pub:97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b pub:aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
http_parser Updated 4.0.2 4.1.2 transitive pub:2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b pub:178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571
intl Updated 0.19.0 0.20.2 direct main pub:d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf pub:3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5
io Updated 1.0.4 1.0.5 transitive pub:2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e pub:dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
js Updated 0.6.7 0.7.2 direct main pub:f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 pub:53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc
komodo_cex_market_data Updated 0.0.1 0.0.1 direct main - git:f001976b706cbdbf4bd230445a101caf282b5651
komodo_wallet_build_transformer Updated 0.0.1 0.2.0+0 direct dev - git:f001976b706cbdbf4bd230445a101caf282b5651
leak_tracker Updated 10.0.4 10.0.8 transitive pub:7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a pub:c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
leak_tracker_flutter_testing Updated 3.0.3 3.0.9 transitive pub:06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8 pub:f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
lints Updated 2.1.1 5.1.1 transitive pub:0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452 pub:c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
logging Updated 1.2.0 1.3.0 transitive pub:623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340 pub:c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
markdown Updated 7.2.2 7.3.0 transitive pub:ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051 pub:935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1
matcher Updated 0.12.16+1 0.12.17 transitive pub:d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb pub:dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
material_color_utilities Updated 0.8.0 0.11.1 transitive pub:0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a pub:f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
meta Updated 1.12.0 1.16.0 transitive pub:7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136 pub:e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
mime Updated 1.0.5 2.0.0 transitive pub:2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2 pub:41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6
mobile_scanner Updated 5.1.1 6.0.7 direct main pub:b8c0e9afcfd52534f85ec666f3d52156f560b5e6c25b1e3d4fe2087763607926 pub:9cb9e371ee9b5b548714f9ab5fd33b530d799745c83d5729ecd1e8ab2935dbd1
package_config Updated 2.1.0 2.2.0 transitive pub:1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd pub:f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
package_info_plus Updated 4.0.2 8.3.0 direct main git:263469d796d769cb73b655fa8c97d4985bce5029 pub:7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191
package_info_plus_platform_interface Updated 2.0.1 3.2.0 transitive pub:9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6 pub:6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c
path Updated 1.9.0 1.9.1 transitive pub:087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af pub:75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5
path_parsing Updated 1.0.1 1.1.0 transitive pub:e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf pub:883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca
path_provider Updated 2.1.1 2.1.5 direct main pub:a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa pub:50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd
path_provider_android Updated 2.2.4 2.2.16 transitive pub:a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d pub:0ca7359dad67fd7063cb2892ab0c0737b2daafd807cf1acecd62374c8fae6c12
path_provider_foundation Updated 2.4.0 2.4.1 transitive pub:f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 pub:4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942
path_provider_platform_interface Updated 2.1.1 2.1.2 transitive pub:94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c pub:88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334
path_provider_windows Updated 2.2.1 2.3.0 transitive pub:8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170 pub:bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
petitparser Updated 6.0.2 6.1.0 transitive pub:c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 pub:07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646
platform Updated 3.1.4 3.1.6 transitive pub:12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec pub:5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984
process Updated 5.0.2 5.0.3 transitive pub:21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32 pub:107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d
provider Updated 6.1.2 6.1.4 transitive pub:c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c pub:489024f942069c2920c844ee18bb3d467c69e48955a4f32d1677f71be103e310
pub_semver Updated 2.1.4 2.2.0 transitive pub:40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c pub:5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585
qr Updated 2.1.0 3.0.2 transitive pub:5c4208b4dc0d55c3184d10d83ee0ded6212dc2b5e2ba17c5a0c0aab279128d21 pub:5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445
qr_flutter Updated 4.0.0 4.1.0 direct main git:e3f8d3d4bbe8661f6c941acde8c9815a876756a3 pub:5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097
rational Updated 1.2.1 2.2.3 direct main git:84d8fe00e33560405c6d72b22a6e9c5c468db058 pub:cb808fb6f1a839e6fc5f7d8cb3b0a10e1db48b3be102de73938c627f0b636336
share_plus Updated 7.0.2 10.1.4 direct main pub:ed3fcea4f789ed95913328e629c0c53e69e80e08b6c24542f1b3576046c614e8 pub:fce43200aa03ea87b91ce4c3ac79f0cecd52e2a7a56c7a4185023c271fbfa6da
share_plus_platform_interface Updated 3.2.1 5.0.2 transitive pub:0c6e61471bd71b04a138b8b588fa388e66d8b005e6f2deda63371c5c505a0981 pub:cc012a23fc2d479854e6c80150696c4a5f5bb62cb89af4de1c505cf78d0a5d0b
shared_preferences Updated 2.1.1 2.5.3 direct main pub:16d3fb6b3692ad244a695c0183fca18cf81fd4b821664394a781de42386bf022 pub:6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5
shared_preferences_android Updated 2.2.2 2.4.9 transitive pub:1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2 pub:c2c8c46297b5d6a80bed7741ec1f2759742c77d272f1a1698176ae828f8e1a18
shared_preferences_foundation Updated 2.4.0 2.5.4 transitive pub:0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7 pub:6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03
shared_preferences_linux Updated 2.3.2 2.4.1 transitive pub:9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa pub:580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f
shared_preferences_platform_interface Updated 2.3.1 2.4.1 transitive pub:d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a pub:57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80
shared_preferences_web Updated 2.3.0 2.4.3 transitive pub:9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a pub:c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
shared_preferences_windows Updated 2.3.2 2.4.1 transitive pub:841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59 pub:94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1
shelf Updated 1.4.1 1.4.2 transitive pub:ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 pub:e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
shelf_static Updated 1.1.2 1.1.3 transitive pub:a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e pub:c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3
shelf_web_socket Updated 1.0.4 3.0.0 transitive pub:9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1 pub:3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925
sky_engine Updated 0.0.99 0.0.0 transitive - -
source_map_stack_trace Updated 2.1.1 2.1.2 transitive pub:84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae pub:c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
source_maps Updated 0.10.12 0.10.13 transitive pub:708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703 pub:190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812
source_span Updated 1.10.0 1.10.1 transitive pub:53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c pub:254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c
stack_trace Updated 1.11.1 1.12.1 transitive pub:73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b pub:8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1
stream_channel Updated 2.1.2 2.1.4 transitive pub:ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 pub:969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d
stream_transform Updated 2.1.0 2.1.1 transitive pub:14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f pub:ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
string_scanner Updated 1.2.0 1.4.1 transitive pub:556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde pub:921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43
term_glyph Updated 1.2.1 1.2.2 transitive pub:a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 pub:7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e
test Updated 1.25.2 1.25.15 direct dev pub:7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073 pub:301b213cd241ca982e9ba50266bd3f5bd1ea33f1455554c5abb85d1be0e2d87e
test_api Updated 0.7.0 0.7.4 transitive pub:9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f pub:fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
test_core Updated 0.6.0 0.6.8 transitive pub:2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4 pub:84d17c3486c8dfdbe5e12a50c8ae176d15e2a771b96909a9442b40173649ccaa
typed_data Updated 1.3.2 1.4.0 transitive pub:facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c pub:f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
universal_html Updated 2.2.2 2.2.4 direct main git:6a1bc7d9e6ed735ab9f7b319f9eedb138ce8b0e5 pub:56536254004e24d9d8cfdb7dbbf09b74cf8df96729f38a2f5c238163e3d58971
url_launcher Updated 6.1.11 6.3.1 direct main pub:eb1e00ab44303d50dd487aab67ebc575456c146c6af44422f9c13889984c00f3 pub:9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603
url_launcher_android Updated 6.2.2 6.3.15 transitive pub:507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f pub:1d0eae19bd7606ef60fe69ef3b312a437a16549476c42321d5dc1506c9ca3bf4
url_launcher_ios Updated 6.3.0 6.3.3 transitive pub:7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89 pub:7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb
url_launcher_linux Updated 3.1.1 3.2.1 transitive pub:ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 pub:4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935
url_launcher_macos Updated 3.2.0 3.2.2 transitive pub:9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de pub:17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2
url_launcher_platform_interface Updated 2.3.0 2.3.2 transitive pub:4aca1e060978e19b2998ee28503f40b5ba6226819c2b5e3e4d1821e8ccd92198 pub:552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029
url_launcher_web Updated 2.3.1 2.4.0 transitive pub:8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a pub:3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9
url_launcher_windows Updated 3.1.1 3.1.4 transitive pub:ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 pub:3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77
uuid Updated 3.0.6 4.5.1 direct main pub:2469694ad079893e3b434a627970c33f2fa5adc46dfe03c9617546969a9a8afc pub:a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
vector_graphics Updated 1.1.10+1 1.1.18 transitive pub:4ac59808bbfca6da38c99f415ff2d3a5d7ca0a6b4809c71d9cf30fba5daf9752 pub:44cc7104ff32563122a929e4620cf3efd584194eec6d1d913eb5ba593dbcf6de
vector_graphics_codec Updated 1.1.10+1 1.1.13 transitive pub:f3247e7ab0ec77dc759263e68394990edc608fb2b480b80db8aa86ed09279e33 pub:99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146
vector_graphics_compiler Updated 1.1.10+1 1.1.16 transitive pub:18489bdd8850de3dd7ca8a34e0c446f719ec63e2bab2e7a8cc66a9028dd76c5a pub:1b4b9e706a10294258727674a340ae0d6e64a7231980f9f9a3d12e4b42407aad
video_player Updated 2.7.0 2.9.5 direct main pub:3fd106c74da32f336dc7feb65021da9b0207cb3124392935f1552834f7cce822 pub:7d78f0cfaddc8c19d4cb2d3bebe1bfef11f2103b0a03e5398b303a1bf65eeb14
video_player_android Updated 2.4.14 2.8.2 transitive pub:134e1ad410d67e18a19486ed9512c72dfc6d8ffb284d0e8f2e99e903d1ba8fa3 pub:ae7d4f1b41e3ac6d24dd9b9d5d6831b52d74a61bdd90a7a6262a33d8bb97c29a
video_player_avfoundation Updated 2.6.1 2.7.0 transitive pub:d1e9a824f2b324000dc8fb2dcb2a3285b6c1c7c487521c63306cc5b394f68a7c pub:84b4752745eeccb6e75865c9aab39b3d28eb27ba5726d352d45db8297fbd75bc
video_player_platform_interface Updated 6.2.1 6.3.0 transitive pub:be72301bf2c0150ab35a8c34d66e5a99de525f6de1e8d27c0672b836fe48f73a pub:df534476c341ab2c6a835078066fc681b8265048addd853a1e3c78740316a844
video_player_web Updated 2.3.0 2.3.4 transitive pub:41245cef5ef29c4585dbabcbcbe9b209e34376642c7576cabf11b4ad9289d6e4 pub:3ef40ea6d72434edbfdba4624b90fd3a80a0740d260667d91e7ecd2d79e13476
vm_service Updated 14.2.1 14.3.1 transitive pub:3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec pub:0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14
watcher Updated 1.1.0 1.1.1 transitive pub:3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8 pub:69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104
web Updated 0.5.1 1.1.1 transitive pub:97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27 pub:868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a
web_socket_channel Updated 2.4.5 3.0.2 transitive pub:58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42 pub:0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5
webdriver Updated 3.0.3 3.0.4 transitive pub:003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e pub:3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8
win32 Updated 4.1.4 5.12.0 transitive pub:5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c pub:dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f
xdg_directories Updated 1.0.4 1.1.0 transitive pub:faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d pub:7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15
yaml Updated 3.1.2 3.1.3 transitive pub:75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5 pub:b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce

QA

cc @KomodoPlatform/qa

While HD support is the most notable user-facing change, this is an entire rewrite "under the hood", so all features are affected. Please test widely. The follow-up release will focus on any major issues identified after release as well as general performance optimisations (especially those which have regressed since pre-SDK migration).

Please also note that any issues already reported which are not patched will be addressed in a future update.

Auto-reviews:

NB: The CodeRabbit summary below is incomplete and only considers the incremental changes between the commit when the branch was updated and the current commit because it exceeded the max length when opening the PR. In the future, we will always keep a PR open for dev->main to avoid this limit.

Summary by CodeRabbit

  • New Features

    • Introduced new GitHub Actions workflows for code coverage, Flutter dependencies, asset generation, build validation, and environment setup across Android, iOS, Linux, macOS, and Windows.
    • Added custom token import management with CustomTokenImportBloc and repository interface.
    • Added CoinAddressesBloc for managing coin addresses.
    • Introduced FiatFormBloc for fiat on-ramp form management.
    • Launched new workflows for building desktop and mobile applications across multiple platforms.
    • Added FaucetBloc to manage faucet requests.
  • Improvements

    • Streamlined CI/CD workflows using custom actions for modularity and maintainability.
    • Enhanced documentation including Flutter version management, build instructions, and signing processes.
    • Refactored multiple blocs and repositories to integrate KomodoDefiSdk and CoinsRepo for improved architecture and type safety.
    • Updated theming to use Flutter's ThemeExtension for custom dark and light themes.
    • Improved error handling, logging, and state management across various blocs including WithdrawFormBloc, MarketMakerBotBloc, and NftWithdrawBloc.
    • Updated Android and iOS build configurations to support newer SDK and tool versions.
    • Enhanced fiat providers (BanxaFiatProvider, RampFiatProvider) with stronger typing and error handling.
    • Added new exception CacheMissException for portfolio growth repository.
    • Improved translation strings and UI text for better clarity and user experience.
    • Added robust SDK integration for coin activation, balance monitoring, and price updates in CoinsBloc and related repositories.
    • Enhanced authentication flow and state management using KomodoDefiSdk across multiple blocs.
    • Improved asset and coin handling with new extensions and utilities for SDK asset conversions and balance retrieval.
    • Added comprehensive support for fiat payment methods, order tracking, and payment status handling.
    • Improved NFT management with updated event/state naming, error handling, and SDK integration.
    • Enhanced market maker bot event handling with concurrency transformers and improved async control.
    • Added convenient access method for TextThemeExtension in the theme.
    • Improved integration and error handling in coin activation, bridge, taker, and dex-related blocs.
    • Enhanced SDK-based wallet and transaction history management.
    • Refined Docker and development container configurations for updated environments and dependencies.
    • Added script and workflow for automated SDK package version rolling.
    • Integrated detailed analytics event system with modular event classes and logging throughout the app.
    • Added new security advisory and build flags to enforce lockfile usage and improve build security.
  • Fixes

    • Fixed issues related to unsupported coin handling and validation logic.
    • Resolved bugs in coin address management and transaction history retrieval.
    • Enhanced error logging and handling in fiat providers and market maker bot components.
    • Addressed mixed-case address validation and conversion in NFT withdrawal flow.
    • Fixed build and deployment scripts for consistency and updated dependencies.

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]>
* ci(sdk): Create script/action for SDK auto roll

* CI Test 1

* CI Test 2

* CI Test 3
Copy link
Contributor

@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

🧹 Nitpick comments (4)
.github/scripts/roll_sdk_packages.sh (3)

38-96: Separate declaration and assignment to preserve return codes.
ShellCheck flags combining local with command substitution (SC2155), which can mask return statuses. For robustness, declare variables first, then assign:

- local start_line=$(grep -n "^  $package_name:" "$lock_file" | cut -d: -f1)
+ local start_line
+ start_line=$(grep -n "^  $package_name:" "$lock_file" | cut -d: -f1)

- local end_line=$(tail -n +$((start_line+1)) "$lock_file" | grep -n "^[^ ]" | head -1 | cut -d: -f1)
+ local end_line
+ end_line=$(tail -n +$((start_line+1)) "$lock_file" | grep -n "^[^ ]" | head -1 | cut -d: -f1)

- local package_section=$(sed -n "${start_line},${end_line}p" "$lock_file" | sed '$d')
+ local package_section
+ package_section=$(sed -n "${start_line},${end_line}p" "$lock_file" | sed '$d')

- local version=$(echo "$package_section" | grep "    version:" | head -1 | sed 's/.*version: *"\([^"]*\)".*/\1/')
+ local version
+ version=$(echo "$package_section" | grep "    version:" | head -1 | sed 's/.*version: *"\([^"]*\)".*/\1/')

- local source=$(echo "$package_section" | grep "    source:" | head -1 | sed 's/.*source: *\([^ ]*\).*/\1/')
+ local source
+ source=$(echo "$package_section" | grep "    source:" | head -1 | sed 's/.*source: *\([^ ]*\).*/\1/')
🧰 Tools
🪛 Shellcheck (0.10.0)

[warning] 49-49: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 56-56: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 66-66: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 70-70: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 71-71: Declare and assign separately to avoid masking return values.

(SC2155)


109-113: Handle file paths with spaces.
Looping over PUBSPEC_FILES=$(find ...) with a simple for PUBSPEC in $PUBSPEC_FILES can break on paths containing spaces. Consider using find … -print0 and reading with while IFS= read -r -d '' PUBSPEC; do … done.


253-257: Quote output file targets to prevent word splitting.
Redirecting into $GITHUB_OUTPUT without quotes may misbehave if the path contains spaces.

- echo "updates_found=true" >> $GITHUB_OUTPUT
+ echo "updates_found=true" >> "$GITHUB_OUTPUT"

Apply the same quoting wherever $GITHUB_OUTPUT is used as a redirection target.

.github/workflows/roll-sdk-packages.yml (1)

60-62: Quote redirection targets to avoid word splitting.
In the Determine configuration step, the script writes to $GITHUB_ENV without quotes. Wrap the variable in quotes to be safe:

- echo "TARGET_BRANCH=$TARGET_BRANCH" >> $GITHUB_ENV
+ echo "TARGET_BRANCH=$TARGET_BRANCH" >> "$GITHUB_ENV"
- echo "UPGRADE_ALL=$UPGRADE_ALL" >> $GITHUB_ENV
+ echo "UPGRADE_ALL=$UPGRADE_ALL" >> "$GITHUB_ENV"
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9b46ffe and 5a6ad28.

⛔ Files ignored due to path filters (1)
  • docs/assets/sdk-rolls.png is excluded by !**/*.png
📒 Files selected for processing (3)
  • .github/actions/flutter-deps/action.yml (1 hunks)
  • .github/scripts/roll_sdk_packages.sh (1 hunks)
  • .github/workflows/roll-sdk-packages.yml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/actions/flutter-deps/action.yml
🧰 Additional context used
🪛 Shellcheck (0.10.0)
.github/scripts/roll_sdk_packages.sh

[warning] 49-49: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 56-56: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 66-66: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 70-70: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 71-71: Declare and assign separately to avoid masking return values.

(SC2155)

🪛 actionlint (1.7.4)
.github/workflows/roll-sdk-packages.yml

36-36: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


51-51: shellcheck reported issue in this script: SC2086:info:9:40: Double quote to prevent globbing and word splitting

(shellcheck)


51-51: shellcheck reported issue in this script: SC2086:info:17:36: Double quote to prevent globbing and word splitting

(shellcheck)


51-51: shellcheck reported issue in this script: SC2086:info:20:52: Double quote to prevent globbing and word splitting

(shellcheck)


79-79: shellcheck reported issue in this script: SC2086:info:3:30: Double quote to prevent globbing and word splitting

(shellcheck)


79-79: shellcheck reported issue in this script: SC2086:info:5:31: Double quote to prevent globbing and word splitting

(shellcheck)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build Desktop (windows)
  • GitHub Check: Build Mobile (iOS)
🔇 Additional comments (1)
.github/workflows/roll-sdk-packages.yml (1)

36-39: Skip outdated actionlint warning.
actionlint suggests updating actions/checkout@v3, but v3 is the latest stable release and fully supported. No change required.

🧰 Tools
🪛 actionlint (1.7.4)

36-36: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

Comment on lines 1 to 7
#!/usr/bin/env bash

# Script to roll SDK packages in all Flutter/Dart projects
# Designed to handle git-based dependencies and work with the GitHub CI workflow

set -e

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add stricter error handling.
Currently the script uses set -e, which stops on the first error, but pipelines can still mask failures. It's recommended to also enable pipefail (and optionally nounset) to catch errors in piped commands and unset variables.

- set -e
+ set -euo pipefail
📝 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
#!/usr/bin/env bash
# Script to roll SDK packages in all Flutter/Dart projects
# Designed to handle git-based dependencies and work with the GitHub CI workflow
set -e
#!/usr/bin/env bash
# Script to roll SDK packages in all Flutter/Dart projects
# Designed to handle git-based dependencies and work with the GitHub CI workflow
set -euo pipefail

Comment on lines +98 to +105
# Initialize changes file
echo "# SDK Package Rolls" > "$CHANGES_FILE"
echo "" >> "$CHANGES_FILE"
echo "**Date:** $CURRENT_DATE" >> "$CHANGES_FILE"
echo "**Target Branch:** $TARGET_BRANCH" >> "$CHANGES_FILE"
echo "**Upgrade Mode:** $([ "$UPGRADE_ALL_PACKAGES" = "true" ] && echo "All Packages" || echo "SDK Packages Only")" >> "$CHANGES_FILE"
echo "" >> "$CHANGES_FILE"
echo "The following SDK packages were rolled to newer versions:" >> "$CHANGES_FILE"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Prevent generating changelog when no rolls occurred.
The script unconditionally initializes SDK_CHANGELOG.md at the start, so the workflow will always detect a changelog file—even if no SDK packages were rolled. Move the header initialization block inside the if [ "$ROLLS_MADE" = true ] check (after detecting changes), or remove the file when ROLLS_MADE is false.

Suggested adjustment:

- # Initialize changes file
- echo "# SDK Package Rolls" > "$CHANGES_FILE"
- ...
- echo "" >> "$CHANGES_FILE"
+ # Defer initializing the changelog until a roll is detected.

Committable suggestion skipped: line range outside the PR's diff.

…Ls of existing providers (#2611)

* feat(system-health): add NTP and HTTP header time providers

* test(system-health): add unit tests for system clock providers

* chore(deps): add ntp package dependency and reorder imports

* refactor(system-health): rename events & move logging init to bootstrap

* fix(system-health): add binance time provider for web

CORS rules block accessing the `date` header on web from other domains unless it's been explicitly allowed.

* refactor: change method return type and implement ai review suggestions

* fix(system-health): show banner if clock invalid even if peers >= 2

previous check was a regression that wouldn't show the banner for incorrect clock if there were still peers connected

* refactor: simplify datetime parsing and revert exception regression

* refactor: remove shared http client to avoid issues with multiple closes
Copy link
Contributor

@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/app_bloc_root.dart (1)

391-398: ⚠️ Potential issue

Error handling in _precacheCoinIcons still needs to be addressed.

The comment on lines 394-396 acknowledges a known issue where completeError throws an uncaught exception, but the fix is not implemented. This causes UI tests to fail when switching between light and dark theme.

Implement proper error handling when aborting an ongoing precache operation:

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 {
+    // Signal cancellation with a specific error
+    _currentPrecacheOperation!.completeError(
+      StateError('Precache cancelled by a subsequent request')
+    );
+  } catch (e) {
+    log('Error while cancelling previous precache operation: $e');
+  }
}
🧹 Nitpick comments (3)
lib/bloc/app_bloc_root.dart (3)

120-125: Inconsistent transaction history repository implementation.

The code still uses MockTransactionHistoryRepo conditionally while using the new SDK-based SdkTransactionHistoryRepository in production mode. Consider creating a mock that extends the new repository for consistency.

For better consistency with the SDK migration:

final transactionsRepo = performanceMode != null
-    ? MockTransactionHistoryRepo(
-        performanceMode: performanceMode,
-        demoDataGenerator: DemoDataCache.withDefaults(),
-      )
+    ? MockSdkTransactionHistoryRepository(
+        performanceMode: performanceMode,
+        demoDataGenerator: DemoDataCache.withDefaults(),
+        sdk: komodoDefiSdk,
+      )
    : SdkTransactionHistoryRepository(sdk: komodoDefiSdk);

150-153: Document startup behavior changes.

The code now sets MainMenuValue.dex as the initial menu and calls tradingEntitiesBloc.runUpdate() at startup, but lacks documentation explaining this change in behavior.

Add comments explaining the purpose of these startup operations:

-// startup bloc run steps
+// Initialize trading entities and set the default navigation tab to DEX
+// This ensures market data is loaded immediately when the app starts
tradingEntitiesBloc.runUpdate();
routingState.selectedMenu = MainMenuValue.dex;

333-337: Consider refactoring debug initialization to a separate method.

The debug initialization code is embedded directly in the initState method, which reduces readability. Consider extracting it to a dedicated method.

@override
void initState() {
  final coinsBloc = context.read<CoinsBloc>();
  _routeInformationParser = RootRouteInformationParser(coinsBloc);
  _airDexBackButtonDispatcher = AirDexBackButtonDispatcher(_routerDelegate);
  routingState.selectedMenu = MainMenuValue.defaultMenu();

  unawaited(_hideAppLoader());

+  _initDebugDataIfNeeded();

+  super.initState();
+}
+
+void _initDebugDataIfNeeded() {
  if (kDebugMode) {
    final walletsRepo = RepositoryProvider.of<WalletsRepository>(context);
    final authBloc = context.read<AuthBloc>();
    initDebugData(authBloc, walletsRepo).ignore();
  }
-
-  super.initState();
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5a6ad28 and 47300e1.

📒 Files selected for processing (1)
  • lib/bloc/app_bloc_root.dart (11 hunks)
🧰 Additional context used
🧠 Learnings (1)
lib/bloc/app_bloc_root.dart (1)
Learnt from: takenagain
PR: KomodoPlatform/komodo-wallet#2566
File: lib/bloc/coins_bloc/coins_bloc.dart:10-10
Timestamp: 2025-04-01T15:51:37.060Z
Learning: In the Komodo Wallet project, part files share imports with their parent files. The import for `app_config.dart` in `coins_bloc.dart` is necessary because the part file `coins_state.dart` uses `excludedAssetList` from that package.
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: Test web-app-linux-profile
  • GitHub Check: unit_tests
  • GitHub Check: validate_code_guidelines
  • GitHub Check: Build Desktop (linux)
  • GitHub Check: Build Desktop (windows)
  • GitHub Check: build_and_preview
  • GitHub Check: Build Mobile (Android)
  • GitHub Check: Build Mobile (iOS)
  • GitHub Check: build_and_deploy
🔇 Additional comments (1)
lib/bloc/app_bloc_root.dart (1)

72-78: Constructor refactored to use KomodoDefiSdk.

The constructor now requires a KomodoDefiSdk instance instead of runtimeUpdateConfig, aligning with the SDK migration.

final RuntimeUpdateConfig runtimeUpdateConfig;
final KomodoDefiSdk komodoDefiSdk;

// TODO: Refactor to clean up the bloat in this main file
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Address TODO comment regarding bloat in main file.

The TODO comment on line 80 indicates awareness of code bloat in this file, but no action has been taken to address it.

Consider breaking this file into smaller components:

  1. Separate repository providers and bloc providers into dedicated factory methods
  2. Extract initialization logic to separate helper classes
  3. Group related bloc providers by feature domain

This will improve maintainability and testability of the application initialization process.

Comment on lines 403 to 404
final coins = coinsRepo.getKnownCoinsMap().keys;

Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Update coins retrieval method consistently across codebase.

The method to retrieve known coins has changed from getKnownCoins() to getKnownCoinsMap().keys. Ensure this change is applied consistently throughout the codebase.


🏁 Script executed:

#!/bin/bash
# Check for other uses of getKnownCoins() that may need to be updated
rg "getKnownCoins\(\)" --type dart

Length of output: 609


Update all getKnownCoins() calls to getKnownCoinsMap().keys

We’ve introduced getKnownCoinsMap().keys in app_bloc_root.dart; other parts of the code are still using the old getKnownCoins() method. Please replace these call sites to ensure consistency:

• lib/bloc/nft_transactions/nft_txn_repository.dart
• lib/bloc/nfts/nft_main_repo.dart
• lib/bloc/bridge_form/bridge_repository.dart
• lib/views/dex/simple/form/taker/taker_form_content.dart

For example, change:

final coins = _coinsRepo.getKnownCoins();

to:

final coins = _coinsRepo.getKnownCoinsMap().keys;

* fix(dex): crash when clicking on the buy coin dropdown

KDF returns ARRR in the best orders response, which is currently excluded from the state which caused the exception to be thrown in grouped list view

* fix(dex): revert removing ARRR from excluded assets & filter best orders

* fix(dex): filter excluded assets out from add assets and fiat onramp
…n to komodo button (#2608)

* refactor(fiat-onramp): improve json parsing, logging, and doc comments

included coderabbitai suggestions in main release PR

* refactor(webiew-dialog): improve view mode checks, and JS listener

* refactor(fiat-form): move url and webview mode checks to bloc

* fix(fiat-onramp): split initial and pending payment status

* feat(webview): add CSP blockers with trusted domain filters

* fix(fiat-onramp): open banxa in new tab rather than dialog

Banxa "Return to Komodo" button attempts to set `window.parent.location`, which is not allowed in sandboxed iframes, and is not desired behaviour. In doing so, it would require the user to log in again after the redirect

* fix(fiat-onramp): banxa status parsing and normalisation

Use FiatOrderStatus enum, add the missing status, and normalise the remaining strings given that the input string is lowercased

* refactor: implement github and coderabbit ai suggestions

* fix(fiat-onramp): close checkout status redirect

Assumption: redirect occurs in new tab or popup webview dialog, so the desired behaviour is to return to the KW tab rather than navigating back to a home page that requires the user to sign in again

* fix(fiat-onramp): coin ticker abbr/ticker regression

- increases the number of coins available for onramp, mostly from the banxa supported coins list
- revert regression in the `getAbbr` function, although a better approach would be a good idea when migrating to the SDK

* feat(fiat-onramp): show raw provider error message on buy failure

* refactor(fiat-widget): add charset metadata and revert nav in handler

* fix(fiat-onramp): add coin min purchase amount field as validation check

* fix(fiat-onramp): temporarily disable coins with address format errors

* fix(fix-onramp): ramp asset parsing and divide by zero error
Copy link
Contributor

@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: 7

🔭 Outside diff range comments (2)
lib/bloc/fiat/fiat_repository.dart (2)

32-40: ⚠️ Potential issue

Prevent null-dereference when provider is absent

yield* Stream.error(...) does not terminate the generator, so execution continues and provider! is dereferenced, throwing at runtime.
Add an early return (or wrap the rest of the block in an else) to guarantee safety.

-    if (provider == null) yield* Stream.error('Provider not found');
-
-    yield* provider!.watchOrderStatus(orderId);
+    if (provider == null) {
+      yield* Stream.error('Provider not found');
+      return; // stop further execution
+    }
+
+    yield* provider.watchOrderStatus(orderId);

219-233: 🛠️ Refactor suggestion

Shield getPaymentMethodsList against flaky providers

Same fast-fail concern as earlier: one broken provider stops all others. Consider wrapping each provider call:

final paymentMethods = await provider
        .getPaymentMethodsList(source, target, sourceAmount)
        .catchError((e, s) {
          _log.warning('Provider ${provider.getProviderId()} failed', e, s);
          return <FiatPaymentMethod>[];
        });

This improves resilience and end-user experience.

♻️ Duplicate comments (3)
lib/bloc/fiat/fiat_onramp_form/fiat_form_bloc.dart (1)

98-102: Deprecated getFirstPubkey calls have been replaced

The code now properly uses _sdk.pubkeys.getPubkeys() instead of the deprecated getFirstPubkey method, addressing a previously identified issue in the codebase.

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

42-47: 🛠️ Refactor suggestion

Add common synonyms returned by Banxa

Banxa occasionally replies with "completed" (note the “d”). Mapping this
prevents incorrectly downgrading a successful order to in progress.

-      case 'complete':
+      case 'complete':
+      case 'completed':
         return FiatOrderStatus.success;
lib/bloc/fiat/ramp/ramp_fiat_provider.dart (1)

55-58: Decimal → double cast still risks precision loss
This point has been raised in a previous review and remains unresolved.

🧹 Nitpick comments (8)
lib/bloc/coins_manager/coins_manager_bloc.dart (1)

132-143: Updated coin selection logic to use synchronous activation methods

Similar to the batch operation, individual coin selection now uses synchronous activation methods. This code would be more maintainable if the activation/deactivation logic was extracted to a separate method to avoid duplication.

Consider refactoring the repeated activation/deactivation code into a separate method:

- if (state.action == CoinsManagerAction.add) {
-   _coinsRepo.deactivateCoinsSync([event.coin]);
- } else {
-   _coinsRepo.activateCoinsSync([event.coin]);
- }

+ _toggleCoinActivation([event.coin], isActive: !state.action == CoinsManagerAction.add);

Where you would define:

void _toggleCoinActivation(List<Coin> coins, {required bool isActive}) {
  if (isActive) {
    _coinsRepo.activateCoinsSync(coins);
  } else {
    _coinsRepo.deactivateCoinsSync(coins);
  }
}
lib/bloc/fiat/fiat_onramp_form/fiat_form_bloc.dart (3)

66-113: Robust pubkey fetching with proper error handling

The coin selection implementation includes proper error handling for pubkey retrieval with informative logging. However, there's a potential issue when using firstOrNull on the pubkeys map.

When getting the first pubkey with assetPubkeys.keys.firstOrNull, consider checking if the map is empty first, or adding more robust fallback handling. This pattern appears in multiple places throughout the code.

- final address = assetPubkeys.keys.firstOrNull;
+ final address = assetPubkeys.isNotEmpty ? assetPubkeys.keys.first : null;

242-284: Robust pubkey updating with retry mechanism

The _updateAssetPubkeys method implements a good retry mechanism with exponential backoff. However, there's a hardcoded retry delay value.

Consider extracting the retry delay calculation to a constant or configurable parameter:

- await Future<void>.delayed(Duration(milliseconds: 500 * attempts));
+ final baseRetryDelay = const Duration(milliseconds: 500);
+ await Future<void>.delayed(baseRetryDelay * attempts);

545-547: Hardcoded default amount value

The method contains a hardcoded value of '10000' for the source amount when there's no valid fiat amount.

Consider extracting the default amount value to a named constant at the class or file level:

+ static const String defaultSourceAmount = '10000';

  String _getSourceAmount() {
-   return _hasValidFiatAmount() ? state.fiatAmount.value : '10000';
+   return _hasValidFiatAmount() ? state.fiatAmount.value : defaultSourceAmount;
  }
lib/bloc/fiat/fiat_order_status.dart (3)

37-41: Out-of-date docstring – method no longer throws

fromString now returns a fallback status instead of throwing, but the
documentation still warns about an exception. Updating the comment prevents
confusion for future maintainers.

-  /// Parses the fiat order status form string
-  /// Throws [Exception] if the string is not a valid status
+  /// Parses a provider-specific string into a [FiatOrderStatus].
+  ///
+  /// If the value is not recognised the method logs a warning and
+  /// returns [FiatOrderStatus.inProgress] instead of throwing.

28-33: Treat windowCloseRequested as a terminal state

A user-initiated close ends the flow just like a success/failure. Not marking
it as terminal may leave UI components (spinners, buttons) in an indeterminate
state.

 bool get isTerminal =>
-      this == FiatOrderStatus.success || this == FiatOrderStatus.failed;
+      this == FiatOrderStatus.success ||
+      this == FiatOrderStatus.failed  ||
+      this == FiatOrderStatus.windowCloseRequested;

42-44: Normalise with trim() before lowering case

Stray spaces or line-feeds have been observed in webhook payloads. A quick
trim() eliminates this class of bugs.

-    final normalized = status.toLowerCase();
+    final normalized = status.trim().toLowerCase();
lib/bloc/fiat/fiat_onramp_form/fiat_form_state.dart (1)

115-122: canSubmit becomes true after windowCloseRequested

When the provider window is closed (fiatOrderStatus.windowCloseRequested) the
order is effectively aborted, yet canSubmit re-enables the submit button
because isSubmitting is false.

-      !fiatOrderStatus.isSubmitting &&
+      !fiatOrderStatus.isSubmitting &&
+      !fiatOrderStatus.isTerminal &&

Prevents accidental double-submissions.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 47300e1 and 7335ab5.

📒 Files selected for processing (18)
  • assets/web_pages/checkout_status_redirect.html (1 hunks)
  • assets/web_pages/fiat_widget.html (1 hunks)
  • lib/app_config/app_config.dart (7 hunks)
  • lib/bloc/bridge_form/bridge_bloc.dart (7 hunks)
  • lib/bloc/coins_manager/coins_manager_bloc.dart (7 hunks)
  • lib/bloc/fiat/banxa_fiat_provider.dart (9 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_state.dart (1 hunks)
  • lib/bloc/fiat/fiat_order_status.dart (1 hunks)
  • lib/bloc/fiat/fiat_repository.dart (8 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_price_info.dart (1 hunks)
  • lib/bloc/fiat/models/i_currency.dart (1 hunks)
  • lib/bloc/fiat/payment_status_type.dart (1 hunks)
  • lib/bloc/fiat/ramp/models/ramp_asset_info.dart (1 hunks)
  • lib/bloc/fiat/ramp/ramp_fiat_provider.dart (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • lib/bloc/fiat/payment_status_type.dart
  • lib/bloc/bridge_form/bridge_bloc.dart
  • lib/bloc/fiat/models/fiat_price_info.dart
  • lib/bloc/fiat/ramp/models/ramp_asset_info.dart
  • assets/web_pages/fiat_widget.html
  • lib/app_config/app_config.dart
  • lib/bloc/fiat/models/fiat_buy_order_info.dart
  • lib/bloc/fiat/models/i_currency.dart
  • lib/bloc/fiat/base_fiat_provider.dart
  • lib/bloc/fiat/banxa_fiat_provider.dart
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Build Desktop (linux)
  • GitHub Check: Build Desktop (windows)
  • GitHub Check: Build Mobile (Android)
  • GitHub Check: Build Mobile (iOS)
  • GitHub Check: unit_tests
🔇 Additional comments (35)
lib/bloc/coins_manager/coins_manager_bloc.dart (13)

3-7: Updated imports to use the KDF Flutter SDK

The imports have been updated to use the new Komodo DeFi SDK (komodo_defi_sdk.dart) and repository pattern with CoinsRepo instead of direct bloc dependencies. This aligns with the PR objective of migrating to the new KDF Flutter SDK.


11-12: Switched to part files for events and states

The bloc structure has been updated to use the part file pattern, which provides better organization and separation of concerns.


19-24: Modified constructor to use CoinsRepo and KomodoDefiSdk

The constructor now properly requires CoinsRepo and KomodoDefiSdk instances, supporting the SDK migration. The initial state now properly initializes with an empty coin list, with actual coins fetched asynchronously.


35-36: Updated class fields to use SDK dependencies

Fields have been updated to store references to the injected SDK and repository objects.


55-64: Refactored _onCoinsUpdate to use asynchronous SDK methods

The method has been correctly updated to use asynchronous SDK methods, fetching coin lists through the repository and SDK.


77-78: Added explicit action parameter to state update

The state update now includes the current action, which ensures proper state tracking across asynchronous operations.


80-92: Added async _onCoinsListReset method

This new method provides a clean way to reset and reload the coin list asynchronously. The implementation correctly handles state transitions during the async operation.


104-104: Updated event dispatching with current action

Event dispatching has been updated to include the current action state, maintaining consistency throughout the component lifecycle.


162-162: Updated event dispatching to include action parameter

Event dispatching has been updated consistently throughout the class to include the current action state.

Also applies to: 170-170


207-214: Refactored _getOriginalCoinList to use SDK methods

The function now properly integrates with the SDK to fetch the current wallet type, handling the null case correctly.


217-219: Updated coin fetching logic with SDK methods

The code now appropriately delegates to coin fetching methods based on the action type, using repository and SDK methods.


225-234: Implemented _getDeactivatedCoins with SDK asset integration

This method correctly implements the logic to filter disabled coins based on the SDK's enabled coins list and excluded assets list.


237-243: Added support for HD wallets

The code now properly supports both legacy iguana and new hdwallet types with the same coin handling logic, which aligns with the PR objective of adding HD wallet support.

assets/web_pages/checkout_status_redirect.html (4)

3-7: Improved HTML formatting

The HTML document structure has been cleaned up with proper spacing and indentation.


12-18: Refactored params extraction function

The function that extracts URL parameters has been refactored with cleaner variable declarations and consistent formatting.


26-37: Improved conditional logic and commentary

The conditional logic for checking the opener window has been improved with better indentation and explanatory comments about the Banxa checkout temporary workaround.


39-41: Updated window behavior to always close

Instead of redirecting to the home page when the opener is closed or unavailable, the script now always closes the current window. This is explained with a clear comment about how Ramp and Banxa checkouts work.

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

1-9: Well-structured error model class with required properties

The FiatBuyOrderError class is well-designed with required properties for error code, status, and title, extending Equatable for proper value equality comparisons.


11-17: Robust JSON deserialization with null handling

The fromJson factory method properly handles potential null values and type casting with the assertInt utility function.


19-24: Convenient named constructors for common error states

The class provides useful named constructors for common error states (none and parsing) which simplify error creation throughout the codebase.


26-30: Utility getter and clear property definitions

The class includes a helpful isNone utility getter and clearly defined properties.


32-38: Consistent JSON serialization

The toJson method provides consistent serialization matching the deserialization pattern.


40-42: Proper Equatable implementation

The props getter correctly includes all relevant properties for equality comparison.

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

1-28: Well-organized imports and class structure using part files

The imports are properly organized with a clear separation between standard Flutter, third-party, and app-specific imports. The bloc uses part files for clean separation of event and state definitions.


29-65: Comprehensive event handling with proper event transformer usage

The bloc implements a wide range of event handlers with appropriate transformers (like restartable()) to handle concurrent events properly. The class follows best practices by requiring dependencies through constructor injection.


141-206: Thorough form submission logic with proper validation

The form submission implementation includes comprehensive validation, error handling, and state management. The URL construction and web view mode determination are well-implemented.


208-225: Platform-aware WebView mode determination logic

The method for determining the appropriate WebView mode based on platform and provider is well-designed and commented.


442-453: Form validation with TODO comment

The form validation logic includes another TODO comment about UI display and localization of error messages.

This TODO indicates the error messages should be localized and displayed in the UI, rather than just used internally. Consider creating a tracking issue for this enhancement.


455-489: Careful amount input validation with minimum purchase handling

The method for validating and bounding amount input is thorough and handles the complex requirements of minimum purchase amounts across different payment providers.


592-601: Good default state management

The method that sets up default payment methods handles the state updates properly, ensuring a consistent initial state.


430-440:

✅ Verification successful

TODO comment for error handling improvement

There's a TODO comment about Banxa error handling that should be addressed in future updates.

This TODO comment suggests there's potential for better error handling specific to Banxa errors. Consider creating a tracking issue to address this in a future update.


🌐 Web query:

What is the recommended way to handle Banxa error codes in cryptocurrency applications?

💡 Result:

The recommended way to handle Banxa error codes in cryptocurrency applications generally involves the following steps:

  1. Identify Error Codes: Familiarize yourself with the specific error codes that Banxa may return. These codes typically correspond to various issues like validation errors, payment failures, or system errors.

  2. Consult Banxa Documentation: Banxa provides detailed documentation on their API, including error codes and their meanings. Always refer to their official documentation to understand what each error code means and the recommended resolutions.

  3. Implement Robust Error Handling Logic: In your application, implement logic to catch and handle these error codes gracefully. For example:

    • Retry mechanisms for transient errors.
    • User-friendly error messages for validation errors.
    • Logging errors for monitoring and debugging.
  4. User Notifications: Inform users about the error in a clear and helpful manner. If the error is recoverable (e.g., invalid input), guide the user on how to fix it. If it is a system error, advise them to try again later or contact support.

  5. Fallback Procedures: Depending on the severity of the error, consider fallback procedures such as alternative payment methods, or queuing the transaction for later processing.

  6. Security Considerations: Ensure sensitive information is not exposed in error messages.

If you want, I can help you find the latest Banxa error codes and their handling guidelines from their official resources or developer documentation. Would you like me to do that?


Add a tracking issue for Banxa‐specific error handling

The existing TODO is a valid reminder to improve error handling for Banxa’s text‐based error codes. Rather than blocking this PR, let’s:

• Create a GitHub issue (e.g. “Support Banxa error codes in fiat_onramp_form”)
• In that issue, list the known Banxa error codes (validation, payment, system errors) from their API docs
• Define how we’ll handle each (retry logic, user‐friendly messages, fallbacks)

This keeps the code moving and ensures we track a concrete plan for future updates.

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

99-102: firstOrNull requires package:collection

transactionLimit uses the firstOrNull extension.
Ensure that some file in the same library imports:

import 'package:collection/collection.dart';

to avoid a compilation error.


123-165: Value-getter pattern for nullable resets – great!

Using ValueGetter<T?> to let callers intentionally clear optional fields is a
clean solution that avoids extra boolean flags. Nicely done.

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

332-337: Unimplemented watchOrderStatus

The method always throws UnsupportedError, yet higher layers may expect a
stream. Surface this limitation clearly (e.g., via repository capabilities) so
UI code can disable polling for Ramp orders instead of crashing.

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

117-134: decimalPoints argument is ignored

_calculateCoinAmount accepts decimalPoints but never applies it, so callers cannot control rounding / precision.

-      return coinAmount.toDecimal(
-        scaleOnInfinitePrecision: scaleOnInfinitePrecision,
-      );
+      // round/scale to the requested number of decimal places
+      return coinAmount.toDecimal(
+        scaleOnInfinitePrecision: scaleOnInfinitePrecision,
+        precision: decimalPoints,          // <-- ensure argument is honoured
+      );

Please double-check the exact Decimal API; if precision is not available, fall back to coinAmount.round(scale: decimalPoints) or toStringAsFixed(decimalPoints) then parse back.

Comment on lines 114 to +116
final Future<void> switchingFuture = state.action == CoinsManagerAction.add
? _coinsRepo.activateCoins(selectedCoins)
: _coinsRepo.deactivateCoins(selectedCoins);
? _coinsRepo.activateCoinsSync(selectedCoins)
: _coinsRepo.deactivateCoinsSync(selectedCoins);
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Updated to use synchronous coin activation methods

The code now uses synchronous activation methods from CoinsRepo instead of asynchronous calls, which could potentially lead to race conditions if not handled properly.

Please ensure that the synchronous methods in CoinsRepo handle any internal asynchronous operations appropriately and don't block the UI thread.


🏁 Script executed:

#!/bin/bash
# Search for the implementation of activateCoinsSync and deactivateCoinsSync methods
rg -A 10 'activateCoinsSync|deactivateCoinsSync' --type dart

Length of output: 10361


Clarify async behavior and loading‐state handling in CoinsManagerBloc

The methods activateCoinsSync/deactivateCoinsSync in CoinsRepo are asynchronous (Future<void>) and internally await each coin operation, so they won’t block the UI thread. However, in CoinsManagerBloc the UI loading flag (isSwitching) is being cleared before these operations finish, which can prematurely hide loading indicators and lead to race conditions.

Please adjust the emission in lib/bloc/coins_manager/coins_manager_bloc.dart:

• File: lib/bloc/coins_manager/coins_manager_bloc.dart
Lines: around 114–116

Suggested diff:

-    emit(state.copyWith(selectedCoins: [], isSwitching: false));
-    await switchingFuture;
+    await switchingFuture;
+    emit(state.copyWith(selectedCoins: [], isSwitching: false));
📝 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 Future<void> switchingFuture = state.action == CoinsManagerAction.add
? _coinsRepo.activateCoins(selectedCoins)
: _coinsRepo.deactivateCoins(selectedCoins);
? _coinsRepo.activateCoinsSync(selectedCoins)
: _coinsRepo.deactivateCoinsSync(selectedCoins);
final Future<void> switchingFuture = state.action == CoinsManagerAction.add
? _coinsRepo.activateCoinsSync(selectedCoins)
: _coinsRepo.deactivateCoinsSync(selectedCoins);
await switchingFuture;
emit(state.copyWith(selectedCoins: [], isSwitching: false));
🤖 Prompt for AI Agents
In lib/bloc/coins_manager/coins_manager_bloc.dart around lines 114 to 116, the
code calls asynchronous methods activateCoinsSync and deactivateCoinsSync but
clears the isSwitching loading flag before these operations complete, causing
premature hiding of loading indicators. To fix this, await the switchingFuture
before emitting the state that clears isSwitching, ensuring the UI loading state
remains active until the async operations finish.

Comment on lines 323 to 325
final queryString = payload.entries.map((entry) {
return '${Uri.encodeComponent(entry.key)}=${Uri.encodeComponent(entry.value.toString())}';
return '${Uri.encodeComponent(entry.key)}=${Uri.encodeComponent(entry.value)}';
}).join('&');
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Uri.encodeComponent expects String

entry.value is dynamic; passing a non-string (e.g., Decimal) will throw
a TypeError in Dart 3. Convert to String first.

-  return '${Uri.encodeComponent(entry.key)}=${Uri.encodeComponent(entry.value)}';
+  return '${Uri.encodeComponent(entry.key)}=${Uri.encodeComponent(entry.value.toString())}';
🤖 Prompt for AI Agents
In lib/bloc/fiat/ramp/ramp_fiat_provider.dart around lines 323 to 325, the code
passes entry.value directly to Uri.encodeComponent, but entry.value is dynamic
and may not be a String, causing a TypeError in Dart 3. Fix this by converting
entry.value to a String before encoding it, ensuring Uri.encodeComponent always
receives a String argument.

Comment on lines +230 to 233
Decimal _getPaymentMethodFee(FiatPaymentMethod paymentMethod) {
return paymentMethod.transactionFees.first.fees.first.amount;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Guard against empty fee collections

transactionFees.first.fees.first will throw RangeError if either list is
empty. Fail gracefully instead of crashing:

-    return paymentMethod.transactionFees.first.fees.first.amount;
+    if (paymentMethod.transactionFees.isEmpty ||
+        paymentMethod.transactionFees.first.fees.isEmpty) {
+      _log.warning('No fee data for payment method ${paymentMethod.id}');
+      return Decimal.zero;
+    }
+    return paymentMethod.transactionFees.first.fees.first.amount;
📝 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
Decimal _getPaymentMethodFee(FiatPaymentMethod paymentMethod) {
return paymentMethod.transactionFees.first.fees.first.amount;
}
Decimal _getPaymentMethodFee(FiatPaymentMethod paymentMethod) {
if (paymentMethod.transactionFees.isEmpty ||
paymentMethod.transactionFees.first.fees.isEmpty) {
_log.warning('No fee data for payment method ${paymentMethod.id}');
return Decimal.zero;
}
return paymentMethod.transactionFees.first.fees.first.amount;
}
🤖 Prompt for AI Agents
In lib/bloc/fiat/ramp/ramp_fiat_provider.dart around lines 230 to 233, the code
accesses the first elements of transactionFees and fees lists without checking
if they are empty, which can cause a RangeError. Modify the method to first
check if transactionFees and fees are not empty before accessing their first
elements, and return a default value or handle the empty case gracefully to
avoid crashing.

Comment on lines 46 to +49
knownCoinAbbreviations = knownCoins.map((coin) => coin.abbr).toSet();
}
final currencyMap = <String, ICurrency>{};
final knownCoins = _coinsRepo.getKnownCoinsMap();
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Propagate provider-level failures individually

Future.wait(futures) will fail fast if a single provider throws, masking prices from the remaining providers. Wrap each call in try/catch (or use Future.wait(..., eagerError: false)) and log failures instead of aborting the whole request.

🤖 Prompt for AI Agents
In lib/bloc/fiat/fiat_repository.dart around lines 46 to 49, the current use of
Future.wait on the futures list will cause the entire operation to fail if any
single provider throws an error, hiding results from other providers. To fix
this, wrap each call to getList in a try/catch block or use Future.wait with
eagerError set to false to prevent fast failure. Log any individual provider
errors instead of aborting the whole request, ensuring partial results from
successful providers are still processed.

Comment on lines +62 to +66
bool isCoinSegwitKnown(String coinTicker) =>
currency.isCrypto && knownCoins.containsKey('$coinTicker-segwit');
if (isCoinSegwitKnown(currency.getAbbr())) {
final segwitCoin = knownCoins['${currency.getAbbr()}-segwit'];
final segwitCurrency = (currency as CryptoCurrency).copyWith(
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Parameter is unused & shadowed – leads to wrong segwit-ticker check

isCoinSegwitKnown ignores its argument and captures the outer currency, producing false negatives for non-crypto items and confusing future maintainers.

-bool isCoinSegwitKnown(String coinTicker) =>
-    currency.isCrypto && knownCoins.containsKey('$coinTicker-segwit');
-if (isCoinSegwitKnown(currency.getAbbr())) {
+bool _isSegwitVariantKnown(ICurrency c) =>
+    c.isCrypto && knownCoins.containsKey('${c.getAbbr()}-segwit');
+
+if (_isSegwitVariantKnown(currency)) {
📝 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
bool isCoinSegwitKnown(String coinTicker) =>
currency.isCrypto && knownCoins.containsKey('$coinTicker-segwit');
if (isCoinSegwitKnown(currency.getAbbr())) {
final segwitCoin = knownCoins['${currency.getAbbr()}-segwit'];
final segwitCurrency = (currency as CryptoCurrency).copyWith(
// Replace the old, buggy helper:
- bool isCoinSegwitKnown(String coinTicker) =>
- currency.isCrypto && knownCoins.containsKey('$coinTicker-segwit');
- if (isCoinSegwitKnown(currency.getAbbr())) {
+ bool _isSegwitVariantKnown(ICurrency c) =>
+ c.isCrypto && knownCoins.containsKey('${c.getAbbr()}-segwit');
+
+ if (_isSegwitVariantKnown(currency)) {
final segwitCoin = knownCoins['${currency.getAbbr()}-segwit'];
final segwitCurrency = (currency as CryptoCurrency).copyWith(
🤖 Prompt for AI Agents
In lib/bloc/fiat/fiat_repository.dart around lines 62 to 66, the function
isCoinSegwitKnown has a parameter coinTicker that is not used because the
function references the outer variable currency instead. To fix this, modify
isCoinSegwitKnown to use its coinTicker parameter inside the function body
instead of the outer currency variable, ensuring the check is performed
correctly based on the passed argument.

Comment on lines +140 to +148
Decimal _calculateSpotPriceIncludingFee(FiatPaymentMethod paymentMethod) {
// Use the previous coin and fiat amounts to estimate the spot price
// including fee.
final coinAmount =
double.parse(paymentMethod['price_info']['coin_amount'] as String);
final fiatAmount =
double.parse(paymentMethod['price_info']['fiat_amount'] as String);
final coinAmount = paymentMethod.priceInfo.coinAmount;
final fiatAmount = paymentMethod.priceInfo.fiatAmount;
final spotPriceIncludingFee = fiatAmount / coinAmount;
return spotPriceIncludingFee.toString();
return spotPriceIncludingFee.toDecimal(
scaleOnInfinitePrecision: scaleOnInfinitePrecision,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Division-by-zero guard

fiatAmount / coinAmount will throw if coinAmount == 0. Providers occasionally return zero when a quote fails, so add a sanity check.

-    final spotPriceIncludingFee = fiatAmount / coinAmount;
+    if (coinAmount == Decimal.zero) {
+      _log.warning(
+        'Spot-price calculation skipped: coinAmount is zero for '
+        '${paymentMethod.id}',
+      );
+      return Decimal.zero;
+    }
+    final spotPriceIncludingFee = fiatAmount / coinAmount;
📝 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
Decimal _calculateSpotPriceIncludingFee(FiatPaymentMethod paymentMethod) {
// Use the previous coin and fiat amounts to estimate the spot price
// including fee.
final coinAmount =
double.parse(paymentMethod['price_info']['coin_amount'] as String);
final fiatAmount =
double.parse(paymentMethod['price_info']['fiat_amount'] as String);
final coinAmount = paymentMethod.priceInfo.coinAmount;
final fiatAmount = paymentMethod.priceInfo.fiatAmount;
final spotPriceIncludingFee = fiatAmount / coinAmount;
return spotPriceIncludingFee.toString();
return spotPriceIncludingFee.toDecimal(
scaleOnInfinitePrecision: scaleOnInfinitePrecision,
);
Decimal _calculateSpotPriceIncludingFee(FiatPaymentMethod paymentMethod) {
// Use the previous coin and fiat amounts to estimate the spot price
// including fee.
final coinAmount = paymentMethod.priceInfo.coinAmount;
final fiatAmount = paymentMethod.priceInfo.fiatAmount;
if (coinAmount == Decimal.zero) {
_log.warning(
'Spot-price calculation skipped: coinAmount is zero for '
'${paymentMethod.id}',
);
return Decimal.zero;
}
final spotPriceIncludingFee = fiatAmount / coinAmount;
return spotPriceIncludingFee.toDecimal(
scaleOnInfinitePrecision: scaleOnInfinitePrecision,
);
}
🤖 Prompt for AI Agents
In lib/bloc/fiat/fiat_repository.dart around lines 140 to 148, the division
fiatAmount / coinAmount can throw a division-by-zero error if coinAmount is
zero. Add a guard clause to check if coinAmount is zero before performing the
division. If coinAmount is zero, return a default Decimal value or handle the
case gracefully to avoid the exception.

Comment on lines 291 to 306
final coinAmounts = _paymentMethodsList!
.map((method) => double.parse(method['price_info']['coin_amount']))
.map((method) => method.priceInfo.coinAmount)
.toList();
final maxCoinAmount = coinAmounts.reduce((a, b) => a > b ? a : b);
return _paymentMethodsList!.map((method) {
final coinAmount = double.parse(method['price_info']['coin_amount']);
if (coinAmount == 0) {
final coinAmount = method.priceInfo.coinAmount;
if (coinAmount == Decimal.zero) {
return method;
}
if (coinAmount == maxCoinAmount) {
return {
...method,
'relative_percent': null,
};
return method.copyWith(relativePercent: Decimal.zero);
}

final relativeValue =
(coinAmount - maxCoinAmount) / (maxCoinAmount).abs();
(coinAmount - maxCoinAmount) / maxCoinAmount.abs();

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use the passed list instead of the global cache & fix percent sign

_addRelativePercentField ignores its paymentMethodsList parameter and works on _paymentMethodsList!, making the method order-dependent and side-effect prone.

-      final coinAmounts = _paymentMethodsList!
+      final coinAmounts = paymentMethodsList
           .map((method) => method.priceInfo.coinAmount)
           .toList();
 ...
-      return _paymentMethodsList!.map((method) {
+      return paymentMethodsList.map((method) {

Additionally, (coinAmount - max)/max returns negative values (best = 0, others < 0).
If you meant “how much less favourable this offer is”, negate the numerator or document the negative semantics.

🤖 Prompt for AI Agents
In lib/bloc/fiat/fiat_repository.dart around lines 291 to 306, the method
_addRelativePercentField incorrectly uses the global _paymentMethodsList instead
of the passed paymentMethodsList parameter, causing side effects and order
dependency. Fix this by replacing all references to _paymentMethodsList with the
local paymentMethodsList parameter. Also, correct the calculation of
relativeValue so it returns positive percentages by negating the numerator or
adjusting the formula to (maxCoinAmount - coinAmount) / maxCoinAmount.abs(),
ensuring the relativePercent reflects how much less favorable each offer is
compared to the max.

@smk762
Copy link
Collaborator

smk762 commented May 16, 2025

Last issue(s) blocking approval: https://github.com/KomodoPlatform/komodo-wallet/issues?q=is%3Aissue%20state%3Aopen%20label%3AP0
Related: https://github.com/KomodoPlatform/coins/pull/1351

A solution which would accept the updated coins file needs to remove the protocol.protocol_data object from any item with protocol.type == 'ETH' before KDF launches. I've tried twice to achieve this with AI, but unfortunately lack the requisite context to effectively guide it to the right place.

This is a required change to continue allowing rolling coins file updates on app launch, otherwise users will lose the ability to activate EVM coins when https://github.com/KomodoPlatform/coins/pull/1351 is merged.

Related: GLEECBTC/komodo-defi-sdk-flutter#55

Copy link
Contributor

@DeckerSU DeckerSU left a comment

Choose a reason for hiding this comment

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

LGTM.

From a security standpoint, everything generally looks fine. The dependencies have been reviewed — some of them even line by line — and no malicious inclusions or known CVEs were found. The source code itself has also been reviewed for areas that could potentially be targeted by attackers.

The one concern is on the Windows platform: we’re launching the kdf binary with the wallet password (wallet_password) inside a command-line argument. An attacker could easily read that password from the process arguments — for example, using tools like Process Explorer from Sysinternals — decrypt the wallet, and access the seed phrase.

Of course, if an attacker already has access to the system, nothing can truly be considered secure — the system is already compromised. But we should still make such attacks as difficult as possible and avoid transferring plain-text passwords through mechanisms where they can be easily exposed.

p.s. From my point of view, the goal is to operate the "encrypted wallet" under the assumption that the password can't be read from anywhere — whether it's process arguments, memory, text files, or any other easily accessible source.

CharlVS and others added 3 commits May 21, 2025 18:33
* removes redundant readme mentioning remplate.html

* updates meta title, description tags for SEO
* fix: fix SDK roll CI script issues

- Fix SDK roll CI script issues
- Roll SDK version

* CI Test #1

* build: update remaining SDK commit refs in lockfiles

* CI Test 2

* fix(icon-pre-caching): exclude excluded assets to remove NFT_ coins

`NFT_` prefixed coins do not have icons and should not be shown to users, so filter them out from the icon pre-caching

* chore: roll SDK

* chore(deps): upgrade SDK to include fee info fix

GLEECBTC/komodo-defi-sdk-flutter#60

---------

Co-authored-by: Francois <[email protected]>
Copy link
Contributor

@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: 9

🔭 Outside diff range comments (1)
lib/bloc/app_bloc_root.dart (1)

416-419: ⚠️ Potential issue

Replace deprecated CoinIcon with AssetIcon.
The pipeline indicates that CoinIcon is deprecated. Replace it with AssetIcon from the SDK's komodo_ui package.

- await CoinIcon.precacheCoinIcon(context, abbr)
-     .onError((_, __) => debugPrint('Error precaching coin icon $abbr'));
+ await AssetIcon.precacheAssetIcon(context, abbr)
+     .onError((_, __) => debugPrint('Error precaching asset icon $abbr'));
🧰 Tools
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀

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

♻️ Duplicate comments (5)
.github/scripts/roll_sdk_packages.sh (2)

16-16: 🛠️ Refactor suggestion

Add stricter error handling.
Currently the script uses set -e, which stops on the first error, but pipelines can still mask failures. It's recommended to also enable pipefail (and optionally nounset) to catch errors in piped commands and unset variables.

- set -e
+ set -euo pipefail

148-155: 🛠️ Refactor suggestion

Prevent generating changelog when no rolls occurred.
The script unconditionally initializes SDK_CHANGELOG.md at the start, so the workflow will always detect a changelog file—even if no SDK packages were rolled. Move the header initialization block inside the if [ "$ROLLS_MADE" = true ] check (after detecting changes), or remove the file when ROLLS_MADE is false.

Suggested adjustment:

- # Initialize changes file
- echo "# SDK Package Rolls" > "$CHANGES_FILE"
- echo "" >> "$CHANGES_FILE"
- echo "**Date:** $CURRENT_DATE" >> "$CHANGES_FILE"
- echo "**Target Branch:** $TARGET_BRANCH" >> "$CHANGES_FILE"
- echo "**Upgrade Mode:** $([ "$UPGRADE_ALL_PACKAGES" = "true" ] && echo "All Packages" || echo "SDK Packages Only")" >> "$CHANGES_FILE"
- echo "" >> "$CHANGES_FILE"
- echo "The following SDK packages were rolled to newer versions:" >> "$CHANGES_FILE"
- echo "" >> "$CHANGES_FILE"
+ # Defer initializing the changelog until a roll is detected
lib/bloc/app_bloc_root.dart (2)

391-398: 🛠️ Refactor suggestion

Fix race condition when aborting an ongoing precache.
Completing the previous _currentPrecacheOperation without signalling error loses information about why the task was interrupted and may leave upstream awaiters in an inconsistent state.

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 {
+    _currentPrecacheOperation!.completeError(
+      StateError('Precache cancelled by a subsequent request'),
+    );
+  } catch (e) {
+    // Safely handle potential exceptions during cancellation
+    log('Error while cancelling previous precache: $e');
+  }
}

80-80: 🛠️ Refactor suggestion

Address TODO comment regarding bloat in main file.
The TODO comment on line 80 indicates awareness of code bloat in this file, but no action has been taken to address it.

Consider breaking this file into smaller components:

  1. Separate repository providers and bloc providers into dedicated factory methods
  2. Extract initialization logic to separate helper classes
  3. Group related bloc providers by feature domain

This will improve maintainability and testability of the application initialization process.

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

300-307: ⚠️ Potential issue

Incorrect asset passed to activateAsset – only the first coin is activated

Inside the loop you call activateAsset(assets.single) which always
targets the first element of the original list.

-        final progress = await _kdfSdk.assets.activateAsset(assets.single).last;
+        final progress = await _kdfSdk.assets.activateAsset(asset).last;

Without this fix every iteration but the first becomes a no-op.

🧹 Nitpick comments (7)
.github/scripts/roll_sdk_packages.sh (1)

260-260: Remove or use the unused variable.
The PACKAGE_UPDATE_FAILED variable is set but never used. Either use it for proper error handling or remove it.

- PACKAGE_UPDATE_FAILED=true
+ # Either use this variable to track failures:
+ PACKAGE_UPDATE_FAILED=true
+ # Later check and handle the failed packages
+ # Or simply remove it if not needed
🧰 Tools
🪛 Shellcheck (0.10.0)

[warning] 260-260: PACKAGE_UPDATE_FAILED appears unused. Verify use (or export if used externally).

(SC2034)

docs/SDK_DEPENDENCY_MANAGEMENT.md (2)

90-91: Fix list formatting for script parameters.
The bullet points in this list have loose punctuation which affects readability. Add consistent spacing after the bullet points.

-The script accepts the following environment variables:
-
-- `UPGRADE_ALL_PACKAGES`: Set to `true` to upgrade all packages, not just SDK packages. Defaults to `false`.
-- `TARGET_BRANCH`: The target branch for the changelog information. Defaults to `dev`.
+The script accepts the following environment variables:
+
+- `UPGRADE_ALL_PACKAGES`: Set to `true` to upgrade all packages, not just SDK packages. Defaults to `false`.
+- `TARGET_BRANCH`: The target branch for the changelog information. Defaults to `dev`.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~90-~90: Loose punctuation mark.
Context: ...ent variables: - UPGRADE_ALL_PACKAGES: Set to true to upgrade all packages, ...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~91-~91: Loose punctuation mark.
Context: .... Defaults to false. - TARGET_BRANCH: The target branch for the changelog inf...

(UNLIKELY_OPENING_PUNCTUATION)


108-111: Fix list formatting for exit codes.
Similar to the previous issue, the bullet points in this list need consistent spacing.

-The script uses the following exit codes:
-
-- `0`: Success - SDK packages were rolled successfully
-- `100`: No updates needed - the script ran correctly but no packages needed updating
-- Any other code: An error occurred during the execution
+The script uses the following exit codes:
+
+- `0`: Success - SDK packages were rolled successfully
+- `100`: No updates needed - the script ran correctly, but no packages needed updating
+- Any other code: An error occurred during the execution
🧰 Tools
🪛 LanguageTool

[uncategorized] ~108-~108: Loose punctuation mark.
Context: ...pt uses the following exit codes: - 0: Success - SDK packages were rolled succ...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~109-~109: Use a comma before ‘but’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...pdates needed - the script ran correctly but no packages needed updating - Any other...

(COMMA_COMPOUND_SENTENCE_2)

.github/workflows/roll-sdk-packages.yml (2)

91-91: Remove trailing whitespace.
There's a trailing whitespace on this line that should be removed for consistency.

-            
+
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 91-91: trailing spaces

(trailing-spaces)


129-134: Consider using GitHub API for branch deletion.
When dealing with protected branches, the current approach may fail. Using the GitHub API via the gh CLI could be more reliable.

- git push origin --delete ${{ env.PR_BRANCH_NAME }} || {
-   echo "::warning::Failed to delete existing branch ${{ env.PR_BRANCH_NAME }} - it may be protected"
- }
+ # Try to delete with git first
+ git push origin --delete ${{ env.PR_BRANCH_NAME }} 2>/dev/null || {
+   # If git push fails, try using GitHub API via gh CLI
+   echo "::notice::Attempting to delete branch via GitHub API..."
+   gh api -X DELETE repos/{owner}/{repo}/git/refs/heads/${{ env.PR_BRANCH_NAME }} --silent || {
+     echo "::warning::Failed to delete existing branch ${{ env.PR_BRANCH_NAME }} - it may be protected"
+   }
+ }
lib/bloc/coins_bloc/coins_repo.dart (2)

412-421: getUsdPriceByAmount still depends on the deprecated helper

Replace the call to getCoin with the non-deprecated alternatives:

-    final Coin? coin = getCoin(coinAbbr);
+    final Coin? coin = getCoinFromId(AssetId(coinAbbr));

(or inject the coin information from the caller).

This keeps the method usable once getCoin is finally removed.


474-483: Add timeout & retry logic to external price requests

http.get(pricesUrlV3) blocks indefinitely on network stalls.
A short timeout (e.g., 10 s) with exponential back-off would make
the wallet more resilient to connectivity issues.

Example:

-      res = await http.get(pricesUrlV3);
+      res = await http
+          .get(pricesUrlV3)
+          .timeout(const Duration(seconds: 10));

Consider wrapping the call in a retry helper to respect transient failures.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between acd39b6 and 9830a0f.

📒 Files selected for processing (8)
  • .github/actions/flutter-deps/action.yml (1 hunks)
  • .github/scripts/roll_sdk_packages.sh (1 hunks)
  • .github/workflows/roll-sdk-packages.yml (1 hunks)
  • README.md (1 hunks)
  • docs/SDK_DEPENDENCY_MANAGEMENT.md (1 hunks)
  • lib/app_config/app_config.dart (7 hunks)
  • lib/bloc/app_bloc_root.dart (11 hunks)
  • lib/bloc/coins_bloc/coins_repo.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • README.md
  • .github/actions/flutter-deps/action.yml
  • lib/app_config/app_config.dart
🧰 Additional context used
🧠 Learnings (1)
lib/bloc/app_bloc_root.dart (1)
Learnt from: takenagain
PR: KomodoPlatform/komodo-wallet#2566
File: lib/bloc/coins_bloc/coins_bloc.dart:10-10
Timestamp: 2025-04-01T15:51:37.060Z
Learning: In the Komodo Wallet project, part files share imports with their parent files. The import for `app_config.dart` in `coins_bloc.dart` is necessary because the part file `coins_state.dart` uses `excludedAssetList` from that package.
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀
lib/bloc/coins_bloc/coins_repo.dart

[warning] 79-238: 'enabledType', 'getCoin', and 'getFirstPubkey' are deprecated and shouldn't be used. Use SDK WalletManager and pubkeys.getPubkeys.


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


[warning] 394-634: 'call' and 'getCoin' are deprecated and shouldn't be used. Use KomodoDefiSdk.client.rpc or KomodoDefiSdk.client.executeRpc and assets or getCoinFromId.

lib/bloc/app_bloc_root.dart

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

🪛 Shellcheck (0.10.0)
.github/scripts/roll_sdk_packages.sh

[warning] 99-99: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 106-106: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 116-116: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 120-120: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 121-121: Declare and assign separately to avoid masking return values.

(SC2155)


[error] 258-258: Double quote array expansions to avoid re-splitting elements.

(SC2068)


[warning] 260-260: PACKAGE_UPDATE_FAILED appears unused. Verify use (or export if used externally).

(SC2034)

🪛 actionlint (1.7.7)
.github/workflows/roll-sdk-packages.yml

53-53: shellcheck reported issue in this script: SC2086:info:9:40: Double quote to prevent globbing and word splitting

(shellcheck)


53-53: shellcheck reported issue in this script: SC2086:info:17:36: Double quote to prevent globbing and word splitting

(shellcheck)


53-53: shellcheck reported issue in this script: SC2086:info:20:52: Double quote to prevent globbing and word splitting

(shellcheck)


81-81: shellcheck reported issue in this script: SC2086:info:6:30: Double quote to prevent globbing and word splitting

(shellcheck)


81-81: shellcheck reported issue in this script: SC2086:info:9:31: Double quote to prevent globbing and word splitting

(shellcheck)


81-81: shellcheck reported issue in this script: SC2086:info:11:33: Double quote to prevent globbing and word splitting

(shellcheck)

🪛 YAMLlint (1.37.1)
.github/workflows/roll-sdk-packages.yml

[error] 91-91: trailing spaces

(trailing-spaces)

🪛 LanguageTool
docs/SDK_DEPENDENCY_MANAGEMENT.md

[uncategorized] ~90-~90: Loose punctuation mark.
Context: ...ent variables: - UPGRADE_ALL_PACKAGES: Set to true to upgrade all packages, ...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~91-~91: Loose punctuation mark.
Context: .... Defaults to false. - TARGET_BRANCH: The target branch for the changelog inf...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~108-~108: Loose punctuation mark.
Context: ...pt uses the following exit codes: - 0: Success - SDK packages were rolled succ...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~109-~109: Use a comma before ‘but’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...pdates needed - the script ran correctly but no packages needed updating - Any other...

(COMMA_COMPOUND_SENTENCE_2)

⏰ 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 (4)
docs/SDK_DEPENDENCY_MANAGEMENT.md (1)

1-14: Documentation is clear and well-structured.
The documentation provides a comprehensive overview of SDK dependencies and management processes. It clearly identifies the packages from the external repository and their purpose.

lib/bloc/app_bloc_root.dart (3)

72-74: Good SDK integration.
The refactoring to require the KomodoDefiSdk instance in the constructor aligns well with the PR's goal of migrating to the KDF Flutter SDK.


403-404: Good implementation of getKnownCoinsMap.
The switch from getKnownCoins() to getKnownCoinsMap(excludeExcludedAssets: true).keys is correct and consistent with other changes in the codebase.


120-126:

❌ Incorrect review comment

Update MockTransactionHistoryRepo to be compatible with SDK.
The current implementation still uses MockTransactionHistoryRepo for demo mode but uses SdkTransactionHistoryRepository otherwise. Consider updating the MockTransactionHistoryRepo to work with the new SDK architecture for consistency.


🏁 Script executed:

#!/bin/bash
# Check implementation of MockTransactionHistoryRepo
rg -A 10 "class MockTransactionHistoryRepo" --type dart

Length of output: 1187


🏁 Script executed:

#!/bin/bash
# Display the first 200 lines of MockTransactionHistoryRepo implementation to inspect how it generates data
sed -n '1,200p' lib/bloc/cex_market_data/mockup/mock_transaction_history_repository.dart

Length of output: 928


MockTransactionHistoryRepo is intentionally a separate demo implementation
The MockTransactionHistoryRepo implements the same TransactionHistoryRepo interface as SdkTransactionHistoryRepository but uses DemoDataCache to generate mock data in demo/performance mode. This decoupling is by design, so no changes are needed to make it “compatible” with the SDK architecture.

MockTransactionHistoryRepo
– Implements TransactionHistoryRepo
– Uses demoDataGenerator.loadTransactionsDemoData(...) for demo data
SdkTransactionHistoryRepository remains the production implementation

No updates required.

Likely an incorrect or invalid review comment.

# Upgrade all SDK packages at once
if [ ${#SDK_PACKAGES_FOUND[@]} -gt 0 ]; then
log_info "Upgrading packages: ${SDK_PACKAGES_FOUND[*]}"
if ! flutter pub upgrade --unlock-transitive ${SDK_PACKAGES_FOUND[@]}; then
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix potential array splitting issue.
When expanding arrays in bash, it's important to quote them to prevent word splitting and globbing.

- if ! flutter pub upgrade --unlock-transitive ${SDK_PACKAGES_FOUND[@]}; then
+ if ! flutter pub upgrade --unlock-transitive "${SDK_PACKAGES_FOUND[@]}"; then
📝 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
if ! flutter pub upgrade --unlock-transitive ${SDK_PACKAGES_FOUND[@]}; then
if ! flutter pub upgrade --unlock-transitive "${SDK_PACKAGES_FOUND[@]}"; then
🧰 Tools
🪛 Shellcheck (0.10.0)

[error] 258-258: Double quote array expansions to avoid re-splitting elements.

(SC2068)

🤖 Prompt for AI Agents
In .github/scripts/roll_sdk_packages.sh at line 258, the array
SDK_PACKAGES_FOUND is expanded without quotes, which can cause word splitting
and globbing issues. To fix this, enclose the array expansion in double quotes
like "${SDK_PACKAGES_FOUND[@]}" to ensure each element is treated as a separate
argument and prevent unintended splitting or globbing.

id: roll_packages
run: |
# Run the script and capture exit code
UPGRADE_ALL_PACKAGES=${{ env.UPGRADE_ALL }} TARGET_BRANCH=${{ env.TARGET_BRANCH }} .github/scripts/roll_sdk_packages.sh || EXIT_CODE=$?
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve error variable handling.
The current method of capturing exit codes may not reliably capture all failure scenarios. Use a more reliable approach to capture the exit code.

- UPGRADE_ALL_PACKAGES=${{ env.UPGRADE_ALL }} TARGET_BRANCH=${{ env.TARGET_BRANCH }} .github/scripts/roll_sdk_packages.sh || EXIT_CODE=$?
+ UPGRADE_ALL_PACKAGES=${{ env.UPGRADE_ALL }} TARGET_BRANCH=${{ env.TARGET_BRANCH }} .github/scripts/roll_sdk_packages.sh
+ EXIT_CODE=$?
📝 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
UPGRADE_ALL_PACKAGES=${{ env.UPGRADE_ALL }} TARGET_BRANCH=${{ env.TARGET_BRANCH }} .github/scripts/roll_sdk_packages.sh || EXIT_CODE=$?
UPGRADE_ALL_PACKAGES=${{ env.UPGRADE_ALL }} TARGET_BRANCH=${{ env.TARGET_BRANCH }} .github/scripts/roll_sdk_packages.sh
EXIT_CODE=$?
🤖 Prompt for AI Agents
In .github/workflows/roll-sdk-packages.yml at line 83, the current method of
capturing the exit code using '|| EXIT_CODE=$?' may not reliably capture all
failure scenarios. Modify the script execution line to run the script normally,
then immediately capture the exit code in a separate step or command by
assigning '$?' to EXIT_CODE right after the script finishes. This ensures the
exit code is accurately captured regardless of how the script exits.

Comment on lines +401 to 410
@Deprecated('Use SDK pubkeys.getPubkeys instead and let the user '
'select from the available options.')
Future<String?> getFirstPubkey(String coinId) async {
final asset = _kdfSdk.assets.findAssetsByConfigId(coinId).single;
final pubkeys = await _kdfSdk.pubkeys.getPubkeys(asset);
if (pubkeys.keys.isEmpty) {
return null;
}
return pubkeys.keys.first.address;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Delete getFirstPubkey and inline the SDK call

The helper is itself deprecated and only wraps the modern pubkeys.getPubkeys.
Remove the method, migrate callers to:

final pubkeys = await _kdfSdk.pubkeys.getPubkeys(asset);
final firstAddress =
    pubkeys.keys.isNotEmpty ? pubkeys.keys.first.address : null;
🤖 Prompt for AI Agents
In lib/bloc/coins_bloc/coins_repo.dart lines 401 to 410, the getFirstPubkey
method is deprecated and simply wraps the SDK call _kdfSdk.pubkeys.getPubkeys.
Remove this method entirely and update all its callers to directly use the SDK
call by fetching pubkeys with _kdfSdk.pubkeys.getPubkeys(asset) and then
checking if pubkeys.keys is not empty to get the first address or return null.

Comment on lines +77 to 81
final currentUser = await _kdfSdk.auth.currentUser;
if (currentUser != null) {
coin.enabledType = currentUser.wallet.config.type;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Stop mutating the deprecated enabledType field

coin.enabledType has been marked deprecated (see pipeline warnings 79-238).
Persisting this value here locks the model to a legacy API and forces every downstream consumer to keep it alive.

-    if (currentUser != null) {
-      coin.enabledType = currentUser.wallet.config.type;
-    }
+    // ⚠️ `enabledType` is deprecated – remove the mutation and let
+    // callers read the wallet type directly from `currentUser`.

Removing the mutation avoids noise during static-analysis and helps the gradual migration to WalletManager.

📝 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 currentUser = await _kdfSdk.auth.currentUser;
if (currentUser != null) {
coin.enabledType = currentUser.wallet.config.type;
}
final currentUser = await _kdfSdk.auth.currentUser;
// ⚠️ `enabledType` is deprecated – remove the mutation and let
// callers read the wallet type directly from `currentUser`.
🤖 Prompt for AI Agents
In lib/bloc/coins_bloc/coins_repo.dart around lines 77 to 81, the code mutates
the deprecated field `coin.enabledType`. To fix this, remove the assignment to
`coin.enabledType` entirely to avoid using the legacy API and reduce
static-analysis warnings. Instead, rely on the new `WalletManager` for managing
wallet types and related logic.

Comment on lines +324 to +329
CoinIcon.registerCustomIcon(
coin.id.id,
NetworkImage(coin.logoImageUrl!),
);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace deprecated CoinIcon with AssetIcon

CoinIcon is flagged as deprecated by the pipeline.
Switch to the SDK’s AssetIcon.register helper:

-          CoinIcon.registerCustomIcon(
-            coin.id.id,
-            NetworkImage(coin.logoImageUrl!),
-          );
+          AssetIcon.register(
+            id: coin.id,
+            imageProvider: NetworkImage(coin.logoImageUrl!),
+          );
📝 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
CoinIcon.registerCustomIcon(
coin.id.id,
NetworkImage(coin.logoImageUrl!),
);
}
}
AssetIcon.register(
id: coin.id,
imageProvider: NetworkImage(coin.logoImageUrl!),
);
}
}
🧰 Tools
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀

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

🤖 Prompt for AI Agents
In lib/bloc/coins_bloc/coins_repo.dart around lines 324 to 329, replace the
deprecated CoinIcon.registerCustomIcon call with the SDK's AssetIcon.register
method. Update the code to use AssetIcon.register, passing the coin's id and the
NetworkImage of the coin's logo URL accordingly to conform with the new API.

Comment on lines +392 to 399
Future<void> _disableCoin(String coinId) async {
try {
await _mm2.call(DisableCoinReq(coin: coinId));
} catch (e, s) {
_log.shout('Error disabling $coinId', e, s);
return;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use SDK RPC façade instead of deprecated _mm2.call

The direct call on MM2 is deprecated.
Leverage the unified RPC surface that ships with the SDK:

-      await _mm2.call(DisableCoinReq(coin: coinId));
+      await _kdfSdk.client.executeRpc(DisableCoinReq(coin: coinId));

This removes one more deprecation warning and keeps the repo aligned with the new transport layer.

📝 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
Future<void> _disableCoin(String coinId) async {
try {
await _mm2.call(DisableCoinReq(coin: coinId));
} catch (e, s) {
_log.shout('Error disabling $coinId', e, s);
return;
}
}
Future<void> _disableCoin(String coinId) async {
try {
await _kdfSdk.client.executeRpc(DisableCoinReq(coin: coinId));
} catch (e, s) {
_log.shout('Error disabling $coinId', e, s);
return;
}
}
🤖 Prompt for AI Agents
In lib/bloc/coins_bloc/coins_repo.dart around lines 392 to 399, replace the
deprecated direct call to _mm2.call with the new SDK RPC façade method for
disabling a coin. Identify the appropriate RPC method provided by the SDK's
unified RPC surface to disable the coin and use it instead of _mm2.call,
ensuring the code no longer triggers deprecation warnings and aligns with the
updated transport layer.

Comment on lines +155 to 177
Coin? getCoinFromId(AssetId id) {
final asset = _kdfSdk.assets.available[id];
if (asset == null) return null;
return _assetToCoinWithoutAddress(asset);
}

final List<Coin> unmodifiableCoins = List.unmodifiable(coins);
_cachedKnownCoins = unmodifiableCoins;
return unmodifiableCoins;
@Deprecated('Use KomodoDefiSdk assets or getCoinFromId instead.')
Coin? getCoin(String coinId) {
if (coinId.isEmpty) return null;

try {
final assets = _kdfSdk.assets.assetsFromTicker(coinId);
if (assets.isEmpty || assets.length > 1) {
_log.warning(
'Coin "$coinId" not found. ${assets.length} results returned',
);
return null;
}
return _assetToCoinWithoutAddress(assets.single);
} catch (_) {
return null;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Retire the deprecated getCoin() helper

getCoin() still relies on a ticker lookup that:

  1. Collides when several assets share the same ticker (e.g. KMD, KMD-BEP20).
  2. Keeps the deprecated API alive, triggering warnings on every call.

Replace all invocations with getCoinFromId() or direct SDK look-ups and delete this method.

-@Deprecated('Use KomodoDefiSdk assets or getCoinFromId instead.')
-Coin? getCoin(String coinId) { … }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In lib/bloc/coins_bloc/coins_repo.dart between lines 155 and 177, the getCoin()
method is deprecated and causes issues due to ticker collisions and triggers
warnings. Remove the entire getCoin() method and replace all its usages in the
codebase with getCoinFromId() or direct calls to the SDK's asset lookup methods
to ensure consistent and warning-free asset retrieval.

Comment on lines +633 to +637
try {
response = await _mm2.call(request) as Map<String, dynamic>?;
} catch (e, s) {
_log.shout('Error withdrawing ${request.params.coin}', e, s);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Withdraw flow still uses deprecated RPC call

Same recommendation as above – swap _mm2.call for the SDK client:

-      response = await _mm2.call(request) as Map<String, dynamic>?;
+      response =
+          await _kdfSdk.client.executeRpc(request) as Map<String, dynamic>?;
📝 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
try {
response = await _mm2.call(request) as Map<String, dynamic>?;
} catch (e, s) {
_log.shout('Error withdrawing ${request.params.coin}', e, s);
}
try {
response =
await _kdfSdk.client.executeRpc(request) as Map<String, dynamic>?;
} catch (e, s) {
_log.shout('Error withdrawing ${request.params.coin}', e, s);
}
🤖 Prompt for AI Agents
In lib/bloc/coins_bloc/coins_repo.dart around lines 633 to 637, the withdraw
flow uses the deprecated RPC call _mm2.call. Replace this call with the
appropriate method from the SDK client to ensure the code uses the updated and
supported API. Adjust the code to await the SDK client's withdraw method and
handle the response accordingly, maintaining the existing error logging.

* fix: fix SDK roll CI script issues

- Fix SDK roll CI script issues
- Roll SDK version

* CI Test #1

* build: update remaining SDK commit refs in lockfiles

* CI Test 2

* fix(icon-pre-caching): exclude excluded assets to remove NFT_ coins

`NFT_` prefixed coins do not have icons and should not be shown to users, so filter them out from the icon pre-caching

* chore: roll SDK

* docs(analytics): add event implementation plan

* feat(analytics): log onboarding and app lifecycle events

* feat(analytics): add send and swap event callbacks

* feat(analytics): log events for hd address and page metrics

* feat(analytics): add portfolio and asset event logging

* fix(analytics): Fix analytics type errors

* fix(analytics): fix missing import

* chore(deps): upgrade SDK to include fee info fix

GLEECBTC/komodo-defi-sdk-flutter#60

* feat(analytics): add high priority events

* fix: update alpha version warning

* feat(analytics): add cross-chain events and triggers

* feat(analytics): trigger new event logs

* fix: various analytics fixes/enhancements

* refactor(analytics): log events directly

* fix: various analytics fixes

* feat: analytics event queuing

---------

Co-authored-by: Francois <[email protected]>
Copy link
Contributor

@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: 6

🔭 Outside diff range comments (2)
lib/bloc/coins_manager/coins_manager_bloc.dart (2)

127-183: 🛠️ Refactor suggestion

Optimize analytics logging and add error handling

The current implementation has potential performance and reliability issues:

  1. Performance: Multiple await _sdk.auth.currentUser calls during rapid coin selection
  2. Error handling: No try-catch blocks for SDK calls that could fail
  3. Blocking operations: Analytics logging could block the UI thread

Consider this optimization:

+  String? _cachedWalletType;
+
   Future<void> _onCoinSelect(
     CoinsManagerCoinSelect event,
     Emitter<CoinsManagerState> emit,
   ) async {
+    try {
+      _cachedWalletType ??= (await _sdk.auth.currentUser)?.wallet.config.type.name;
+    } catch (e) {
+      // Handle SDK errors gracefully
+      _cachedWalletType = '';
+    }
+
     // ... existing logic ...
     
     if (state.action == CoinsManagerAction.add) {
       _coinsRepo.deactivateCoinsSync([event.coin]);
-      _analyticsBloc.logEvent(
-        AssetDisabledEventData(
-          assetSymbol: coin.abbr,
-          assetNetwork: coin.protocolType,
-          walletType: (await _sdk.auth.currentUser)?.wallet.config.type.name ?? '',
-        ),
-      );
+      // Fire and forget analytics to avoid blocking UI
+      _logAnalyticsEvent(AssetDisabledEventData(
+        assetSymbol: coin.abbr,
+        assetNetwork: coin.protocolType,
+        walletType: _cachedWalletType ?? '',
+      ));
     }
   }
+
+  void _logAnalyticsEvent(dynamic event) {
+    // Non-blocking analytics logging
+    _analyticsBloc.logEvent(event);
+  }

244-284: 💡 Verification agent

🧩 Analysis chain

Add comprehensive error handling for SDK operations

The helper methods lack robust error handling for SDK operations that could fail.

Consider adding proper error handling:

 Future<List<Coin>> _getOriginalCoinList(
   CoinsRepo coinsRepo,
   CoinsManagerAction action,
   KomodoDefiSdk sdk,
 ) async {
+  try {
     final WalletType? walletType = (await sdk.currentWallet())?.config.type;
     if (walletType == null) return [];
+  } catch (e) {
+    // Log error and return empty list to prevent crashes
+    debugPrint('Failed to get wallet type: $e');
+    return [];
+  }

   switch (action) {
     case CoinsManagerAction.add:
       return _getDeactivatedCoins(coinsRepo, sdk, walletType);
     case CoinsManagerAction.remove:
       return coinsRepo.getWalletCoins();
     case CoinsManagerAction.none:
       return [];
   }
 }

Also verify that WalletType.hdwallet (line 274) is the correct enum value for HD wallets in the new SDK.


🏁 Script executed:

#!/bin/bash
# Search for WalletType enum definition
rg "enum WalletType" -A5

# Search for KomodoDefiSdk class declaration
rg "class KomodoDefiSdk" -A5

# Search for currentWallet method signature
rg "currentWallet" -A5

Length of output: 34329


Add comprehensive error handling for SDK operations

Wrap both sdk.currentWallet() and sdk.assets.getEnabledCoins() calls in try/catch to prevent unhandled exceptions and log failures. WalletType.hdwallet is valid per the enum.

– File: lib/bloc/coins_manager/coins_manager_bloc.dart
• In _getOriginalCoinList, catch errors around sdk.currentWallet()
• In _getDeactivatedCoins, catch errors around sdk.assets.getEnabledCoins()

Suggested diff:

 Future<List<Coin>> _getOriginalCoinList(
   CoinsRepo coinsRepo,
   CoinsManagerAction action,
   KomodoDefiSdk sdk,
 ) async {
-  final WalletType? walletType = (await sdk.currentWallet())?.config.type;
-  if (walletType == null) return [];
+  WalletType? walletType;
+  try {
+    walletType = (await sdk.currentWallet())?.config.type;
+    if (walletType == null) return [];
+  } catch (e, st) {
+    debugPrint('Failed to get wallet type: $e\n$st');
+    return [];
+  }

   switch (action) {
     case CoinsManagerAction.add:
       return _getDeactivatedCoins(coinsRepo, sdk, walletType);
@@
 Future<List<Coin>> _getDeactivatedCoins(
   CoinsRepo coinsRepo,
   KomodoDefiSdk sdk,
   WalletType walletType,
 ) async {
-  final Iterable<String> enabledCoins = await sdk.assets.getEnabledCoins();
+  Iterable<String> enabledCoins;
+  try {
+    enabledCoins = await sdk.assets.getEnabledCoins();
+  } catch (e, st) {
+    debugPrint('Failed to fetch enabled coins: $e\n$st');
+    return [];
+  }
   final Map<String, Coin> disabledCoins = coinsRepo.getKnownCoinsMap()
     ..removeWhere((coinId, _) => enabledCoins.contains(coinId))
     ..removeWhere((coinId, _) => excludedAssetList.contains(coinId));
   …
♻️ Duplicate comments (5)
lib/bloc/custom_token_import/bloc/custom_token_import_bloc.dart (1)

78-127: 🛠️ Refactor suggestion

Improve error handling and USD calculation robustness.

  1. The generic exception for missing network asset could be more specific (as noted in previous review).
  2. The USD price calculation using string parsing is fragile.
      if (networkAsset == null) {
-        throw Exception('Network asset ${state.network.formatted} not found');
+        throw AssetNotFoundException('Network asset ${state.network.formatted} not found');
      }

For the USD calculation, consider handling the conversion more robustly:

-      final usdBalance =
-          _coinsRepo.getUsdPriceByAmount(balance.toString(), tokenData.id.id);
+      final usdBalance = _coinsRepo.getUsdPriceByAmount(
+        balance.toString(), 
+        tokenData.id.id,
+      ) ?? Decimal.zero;

      emit(
        state.copyWith(
          formStatus: FormStatus.success,
          tokenData: () => tokenData,
          tokenBalance: balance,
-          tokenBalanceUsd:
-              Decimal.tryParse(usdBalance?.toString() ?? '0.0') ?? Decimal.zero,
+          tokenBalanceUsd: usdBalance,
          formErrorMessage: '',
        ),
      );

This assumes getUsdPriceByAmount returns a Decimal? directly, which would be cleaner than string conversions.

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

107-107: ⚠️ Potential issue

Replace usage of deprecated getCoin method.

This line still uses the deprecated getCoin method that was flagged in a previous review. Please update to use the recommended KomodoDefiSdk.assets or getCoinFromId approach.

-    final Coin? defaultTickerCoin = _coinsRepository.getCoin(event.ticker);
+    final Coin? defaultTickerCoin = _coinsRepository.getCoinFromId(event.ticker);
lib/bloc/app_bloc_root.dart (2)

83-83: Address TODO comment regarding code organization.

The TODO comment indicates awareness of code bloat, but this major migration has added even more complexity to this file.


421-422: Inconsistent coin retrieval method usage.

The method has been updated to use getKnownCoinsMap().keys, but other parts of the codebase still use the old getKnownCoins() method.

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

119-124: ⚠️ Potential issue

Fix loading state race condition (duplicate issue)

The loading state (isSwitching) is still being cleared before the async operations complete, causing premature hiding of loading indicators. This is the same issue identified in previous reviews.

Apply this fix to ensure proper loading state management:

-    emit(state.copyWith(selectedCoins: [], isSwitching: false));
-    await switchingFuture;
+    await switchingFuture;
+    emit(state.copyWith(selectedCoins: [], isSwitching: false));
🧹 Nitpick comments (3)
docs/ANALYTICS.md (3)

26-36: Add language specification to fenced code block.

The code block showing the directory structure should specify a language for proper syntax highlighting.

-```
+```text
 lib/analytics/events/
 ├── user_engagement_events.dart
 ├── user_acquisition_events.dart
 ├── security_events.dart
 ├── portfolio_events.dart
 ├── transaction_events.dart
 ├── data_sync_events.dart
 ├── performance_events.dart
 └── ui_usability_events.dart

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.17.2)</summary>

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

(MD040, fenced-code-language)

</details>

</details>

---

`459-459`: **Add missing period for consistency.**

The list item should end with a period to maintain consistent formatting throughout the document.



```diff
-   - Repository pattern provides a clean API
+   - Repository pattern provides a clean API.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~459-~459: A period might be missing here.
Context: ... - Repository pattern provides a clean API 2. OOP-based Design - Events a...

(AI_EN_LECTOR_MISSING_PUNCTUATION_PERIOD)


473-473: Add missing period for consistency.

The last list item should end with a period to maintain consistent formatting.

-   - Mock implementations are simpler
+   - Mock implementations are simpler.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~473-~473: A period might be missing here.
Context: ...isolation - Mock implementations are simpler

(AI_EN_LECTOR_MISSING_PUNCTUATION_PERIOD)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9830a0f and 713d156.

⛔ Files ignored due to path filters (1)
  • lib/analytics/required_analytics_events.csv is excluded by !**/*.csv
📒 Files selected for processing (25)
  • Fetching (1 hunks)
  • assets/translations/en.json (15 hunks)
  • docs/ANALYTICS.md (1 hunks)
  • docs/ANALYTICS_EVENT_IMPLEMENTATION_PLAN.md (1 hunks)
  • lib/analytics/README.md (1 hunks)
  • lib/analytics/analytics_factory.dart (1 hunks)
  • lib/analytics/events.dart (1 hunks)
  • lib/analytics/events/cross_chain_events.dart (1 hunks)
  • lib/analytics/events/market_bot_events.dart (1 hunks)
  • lib/analytics/events/misc_events.dart (1 hunks)
  • lib/analytics/events/nft_events.dart (1 hunks)
  • lib/analytics/events/portfolio_events.dart (1 hunks)
  • lib/analytics/events/reward_events.dart (1 hunks)
  • lib/analytics/events/security_events.dart (1 hunks)
  • lib/analytics/events/transaction_events.dart (1 hunks)
  • lib/analytics/events/user_acquisition_events.dart (1 hunks)
  • lib/analytics/events/user_engagement_events.dart (1 hunks)
  • lib/analytics/widgets/analytics_lifecycle_handler.dart (1 hunks)
  • lib/bloc/analytics/analytics_bloc.dart (1 hunks)
  • lib/bloc/analytics/analytics_repo.dart (2 hunks)
  • lib/bloc/app_bloc_root.dart (11 hunks)
  • lib/bloc/bridge_form/bridge_bloc.dart (8 hunks)
  • lib/bloc/coin_addresses/bloc/coin_addresses_bloc.dart (1 hunks)
  • lib/bloc/coins_manager/coins_manager_bloc.dart (6 hunks)
  • lib/bloc/custom_token_import/bloc/custom_token_import_bloc.dart (1 hunks)
✅ Files skipped from review due to trivial changes (6)
  • Fetching
  • lib/analytics/README.md
  • lib/analytics/events/reward_events.dart
  • lib/analytics/events/user_acquisition_events.dart
  • lib/analytics/events/nft_events.dart
  • lib/analytics/events/misc_events.dart
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/bloc/coin_addresses/bloc/coin_addresses_bloc.dart
  • lib/bloc/analytics/analytics_repo.dart
🧰 Additional context used
🧠 Learnings (1)
lib/bloc/app_bloc_root.dart (1)
Learnt from: takenagain
PR: KomodoPlatform/komodo-wallet#2566
File: lib/bloc/coins_bloc/coins_bloc.dart:10-10
Timestamp: 2025-04-01T15:51:37.060Z
Learning: In the Komodo Wallet project, part files share imports with their parent files. The import for `app_config.dart` in `coins_bloc.dart` is necessary because the part file `coins_state.dart` uses `excludedAssetList` from that package.
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀
lib/bloc/app_bloc_root.dart

[warning] 17-17: Unused import: 'package:web_dex/bloc/analytics/analytics_event.dart' (unused_import)

🪛 LanguageTool
docs/ANALYTICS.md

[uncategorized] ~459-~459: A period might be missing here.
Context: ... - Repository pattern provides a clean API 2. OOP-based Design - Events a...

(AI_EN_LECTOR_MISSING_PUNCTUATION_PERIOD)


[uncategorized] ~473-~473: A period might be missing here.
Context: ...isolation - Mock implementations are simpler

(AI_EN_LECTOR_MISSING_PUNCTUATION_PERIOD)

docs/ANALYTICS_EVENT_IMPLEMENTATION_PLAN.md

[uncategorized] ~56-~56: It appears that a hyphen is missing (if ‘auto’ is not used in the context of ‘cars’).
Context: ...page | Log when user chooses light/dark/auto theme. | | page_interactive_delay | Page lo...

(AUTO_HYPHEN)

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

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

(MD040, fenced-code-language)

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Build Desktop (linux)
  • GitHub Check: Build Mobile (Android)
  • GitHub Check: Build Desktop (windows)
  • GitHub Check: Build Mobile (iOS)
  • GitHub Check: unit_tests
🔇 Additional comments (30)
lib/bloc/analytics/analytics_bloc.dart (2)

59-62: Good architectural improvement - delegates responsibility appropriately.

The change from conditional sendData to unconditional queueEvent simplifies the bloc and delegates state management to the repository level, which is a cleaner separation of concerns.


65-70: Useful convenience extension for cleaner event logging.

The AnalyticsBlocEventLogger extension provides a clean API for logging events without requiring callers to manually wrap events in AnalyticsSendDataEvent.

lib/analytics/events/user_engagement_events.dart (2)

8-25: Well-structured analytics event data implementation.

The AppOpenedEventData class properly implements the AnalyticsEventData interface with appropriate event name and parameters. The implementation follows consistent patterns for analytics events.


27-38: Clean event wrapper implementation.

The AnalyticsAppOpenedEvent class provides a clean wrapper that properly constructs the data object and passes it to the parent class.

docs/ANALYTICS_EVENT_IMPLEMENTATION_PLAN.md (2)

1-11: Excellent comprehensive documentation for analytics implementation.

This documentation provides clear, actionable guidance for implementing analytics events throughout the application. The structured approach with trigger locations and implementation notes will ensure consistent analytics integration.


56-56: Minor: Static analysis false positive about hyphen.

The static analysis tool flagged "light/dark/auto" as needing a hyphen, but this is a false positive. In UI contexts, "light/dark/auto" (referring to theme options) is commonly written without hyphens and is perfectly clear.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~56-~56: It appears that a hyphen is missing (if ‘auto’ is not used in the context of ‘cars’).
Context: ...page | Log when user chooses light/dark/auto theme. | | page_interactive_delay | Page lo...

(AUTO_HYPHEN)

lib/analytics/widgets/analytics_lifecycle_handler.dart (2)

51-56: Good use of postFrameCallback for initial event logging.

Using addPostFrameCallback ensures the initial app opened event is logged after the widget tree is fully built, which is the correct approach for lifecycle-dependent operations.


59-63: Proper cleanup of lifecycle observer.

The widget correctly removes the observer in the dispose method, preventing memory leaks.

lib/analytics/events/security_events.dart (2)

5-42: LGTM! Well-structured analytics event classes.

The implementation follows a clean pattern for analytics events with proper separation between data and event classes. Parameter naming is consistent with JSON conventions.


44-76: Clean implementation of backup skip tracking.

The event structure is consistent with the backup completion event and properly captures the stage at which backup was skipped.

lib/analytics/events/cross_chain_events.dart (2)

5-47: Well-structured bridge initiation event.

The event properly captures the essential information for tracking bridge transfers with clear parameter names.


98-140: Bridge failure event looks good.

The event structure properly captures bridge failure information. Ensure that error messages are sanitized to avoid exposing sensitive technical details in analytics.

lib/bloc/custom_token_import/bloc/custom_token_import_bloc.dart (2)

36-59: Clean form reset implementation.

The method properly resets all state fields and correctly filters EVM protocols from available coin types.


129-168: Import logic and analytics integration look good.

The method properly handles the import flow and correctly logs the analytics event with appropriate parameters.

lib/analytics/events/market_bot_events.dart (1)

1-136: LGTM! Well-structured market bot analytics events.

The implementation follows excellent practices:

  • Consistent event naming with snake_case
  • Proper separation of event data and wrapper classes
  • Comprehensive coverage of market bot lifecycle (setup, execution, errors)
  • Appropriate parameters for each event type
  • Clean integration with the analytics framework

The event IDs (E27-E30) and parameter choices align well with business analytics needs for market bot feature tracking.

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

521-575: Excellent analytics integration for swap lifecycle tracking.

The comprehensive analytics logging covers all critical swap events:

  • Swap initiation with chain and asset details
  • Success tracking with amount and wallet type
  • Failure tracking with error details

The implementation properly handles async wallet type retrieval and includes appropriate error handling. This provides valuable insights for swap performance and success rates.


269-272: Good defensive programming for unsupported assets.

The filtering of unsupported coins like ARRR prevents downstream errors and aligns with the app configuration. The comment clearly explains the reasoning.

lib/analytics/events.dart (1)

1-181: Well-organized core analytics events with excellent utility function.

The implementation demonstrates strong architectural design:

  • Clear categorization: Events are logically grouped by functional area (HD Wallet, UI, Data Sync, Performance)
  • Consistent patterns: All events follow the established data class + wrapper class pattern
  • Comprehensive documentation: Each event includes business category and insights explanation
  • Useful utility: The parseDerivationPath function provides clean extraction of account/address indices for HD wallet analytics

The event parameters are well-chosen for their respective analytics purposes, especially the performance metrics for UI responsiveness and data sync monitoring.

lib/analytics/events/transaction_events.dart (1)

1-286: Well-structured analytics event system for transactions.

The implementation follows a clean, consistent pattern with data classes and event wrappers. The event naming, parameter structure, and business documentation are well-designed and will provide valuable insights for transaction funnel analysis.

lib/analytics/events/portfolio_events.dart (1)

1-295: Excellent consistency with transaction events architecture.

This file maintains the same clean pattern as transaction_events.dart with well-documented business categories and consistent naming conventions. The portfolio events cover all key user interactions for asset management.

lib/bloc/app_bloc_root.dart (3)

76-81: Approve SDK-centric constructor refactor.

The migration from runtimeUpdateConfig to KomodoDefiSdk aligns well with the overall architectural changes in this PR and establishes a cleaner dependency pattern.


183-312: Comprehensive bloc migration to SDK architecture.

The extensive updates to bloc initialization properly integrate the new KomodoDefiSdk, repository patterns, and analytics system. The migration maintains dependency injection while modernizing the architecture.


441-447: Well-implemented analytics event logging.

The addition of CoinsDataUpdatedEventData with timing and count metrics provides valuable telemetry for monitoring coin data updates.

lib/analytics/analytics_factory.dart (1)

457-871: Event data classes follow good structure.

The individual event data classes are well-structured with consistent naming and proper parameter mapping, even though the overall file architecture differs from other analytics event files.

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

3-28: LGTM - Clean SDK integration

The constructor and import updates properly integrate the new KomodoDefiSdk and AnalyticsBloc dependencies. The changes align well with the architectural migration described in the PR objectives.

assets/translations/en.json (5)

6-11: LGTM - Improved singular/plural translation keys

The separation of "asset" (singular) and "assets" (plural) provides better translation granularity. The addition of "lastTransactions" supports new UI features mentioned in the PR.


117-119: LGTM - Enhanced wallet import messaging

The updated wallet import messages properly clarify seed file handling and password creation. The new HD wallet error message aligns with the multi-address wallet support mentioned in the PR objectives.

Also applies to: 131-131, 205-205


407-415: LGTM - Comprehensive HD wallet mode support

The new translation keys properly support the multi-address wallet functionality mentioned in the PR objectives. The messages clearly explain the implications and requirements of HD wallet mode.


583-592: LGTM - Complete fiat payment flow coverage

The new fiat payment translation keys provide comprehensive coverage for minimum/maximum amounts and all payment status states (success, failure, in-progress). This aligns with the enhanced fiat integration mentioned in the PR objectives.


623-636: LGTM - Custom token import support

The new translation keys properly support the custom token import functionality mentioned in the PR objectives. The messaging includes appropriate warnings and clear instructions for token management.

Comment on lines +81 to +86
_analyticsRepo.queueEvent(
AppOpenedEventData(
platform: platform,
appVersion: appVersion,
),
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider using AnalyticsBloc instead of direct repository access.

The widget bypasses the AnalyticsBloc and calls the repository directly. This breaks the established architecture pattern where the bloc manages analytics events and could lead to inconsistent behavior.

Consider using the bloc extension for consistency:

- _analyticsRepo.queueEvent(
-   AppOpenedEventData(
-     platform: platform,
-     appVersion: appVersion,
-   ),
- );
+ // Get the analytics bloc and use the extension method
+ final analyticsBloc = context.read<AnalyticsBloc>();
+ analyticsBloc.logEvent(
+   AppOpenedEventData(
+     platform: platform,
+     appVersion: appVersion,
+   ),
+ );

This approach maintains architectural consistency and ensures the event goes through the proper bloc pipeline.

📝 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
_analyticsRepo.queueEvent(
AppOpenedEventData(
platform: platform,
appVersion: appVersion,
),
);
// Get the analytics bloc and use the extension method
final analyticsBloc = context.read<AnalyticsBloc>();
analyticsBloc.logEvent(
AppOpenedEventData(
platform: platform,
appVersion: appVersion,
),
);
🤖 Prompt for AI Agents
In lib/analytics/widgets/analytics_lifecycle_handler.dart around lines 81 to 86,
the code directly calls the analytics repository to queue an event, bypassing
the AnalyticsBloc. To maintain architectural consistency and ensure events are
processed correctly, refactor the code to dispatch the AppOpenedEventData event
through the AnalyticsBloc instead of calling the repository directly. Use the
bloc's event dispatching method or extension to send the event, aligning with
the established pattern.

Comment on lines +44 to +50
// Get the analytics repository from GetIt
try {
_analyticsRepo = GetIt.I<AnalyticsRepo>();
} catch (e) {
log('AnalyticsLifecycleHandler: Failed to get AnalyticsRepo - $e');
}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix potential null reference after GetIt exception.

If GetIt.I<AnalyticsRepo>() throws an exception, _analyticsRepo remains uninitialized but the code later attempts to use it in _logAppOpenedEvent(). This will cause a LateInitializationError.

Consider this fix to handle the failure case:

  /// Reference to the analytics repository
- late final AnalyticsRepo _analyticsRepo;
+ AnalyticsRepo? _analyticsRepo;

  @override
  void initState() {
    super.initState();

    // Get the analytics repository from GetIt
    try {
      _analyticsRepo = GetIt.I<AnalyticsRepo>();
    } catch (e) {
      log('AnalyticsLifecycleHandler: Failed to get AnalyticsRepo - $e');
+     return; // Early return if analytics repo is unavailable
    }

And update _logAppOpenedEvent():

  void _logAppOpenedEvent() {
+   if (_analyticsRepo == null) return;
+   
    try {
      final platform = PlatformInfo.getInstance().platform;
      final appVersion = packageInformation.packageVersion ?? 'unknown';

-     _analyticsRepo.queueEvent(
+     _analyticsRepo!.queueEvent(
📝 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
// Get the analytics repository from GetIt
try {
_analyticsRepo = GetIt.I<AnalyticsRepo>();
} catch (e) {
log('AnalyticsLifecycleHandler: Failed to get AnalyticsRepo - $e');
}
/// Reference to the analytics repository
- late final AnalyticsRepo _analyticsRepo;
+ AnalyticsRepo? _analyticsRepo;
@override
void initState() {
super.initState();
// Get the analytics repository from GetIt
try {
_analyticsRepo = GetIt.I<AnalyticsRepo>();
} catch (e) {
log('AnalyticsLifecycleHandler: Failed to get AnalyticsRepo - $e');
+ return; // Early return if analytics repo is unavailable
}
WidgetsBinding.instance.addObserver(this);
WidgetsBinding.instance.addPostFrameCallback((_) {
_logAppOpenedEvent();
});
}
void _logAppOpenedEvent() {
+ if (_analyticsRepo == null) return;
try {
final platform = PlatformInfo.getInstance().platform;
final appVersion = packageInformation.packageVersion ?? 'unknown';
- _analyticsRepo.queueEvent(
+ _analyticsRepo!.queueEvent(
AppOpenedEvent(platform: platform, appVersion: appVersion),
);
} catch (e) {
log('AnalyticsLifecycleHandler: Error logging app opened event - $e');
}
}
🤖 Prompt for AI Agents
In lib/analytics/widgets/analytics_lifecycle_handler.dart around lines 44 to 50,
the code catches exceptions when retrieving AnalyticsRepo from GetIt but does
not initialize _analyticsRepo afterward, leading to a potential
LateInitializationError when _logAppOpenedEvent() uses it. To fix this,
initialize _analyticsRepo to null or a safe default in the catch block and
update _logAppOpenedEvent() to check if _analyticsRepo is null before using it,
avoiding null reference errors.

Comment on lines +49 to +96
/// E21: Bridge completed
/// Business category: Cross-Chain.
class BridgeSucceededEventData implements AnalyticsEventData {
const BridgeSucceededEventData({
required this.fromChain,
required this.toChain,
required this.asset,
required this.amount,
required this.walletType,
});

final String fromChain;
final String toChain;
final String asset;
final double amount;
final String walletType;

@override
String get name => 'bridge_success';

@override
JsonMap get parameters => {
'from_chain': fromChain,
'to_chain': toChain,
'asset': asset,
'amount': amount,
'wallet_type': walletType,
};
}

/// E21: Bridge completed
class AnalyticsBridgeSucceededEvent extends AnalyticsSendDataEvent {
AnalyticsBridgeSucceededEvent({
required String fromChain,
required String toChain,
required String asset,
required double amount,
required String walletType,
}) : super(
BridgeSucceededEventData(
fromChain: fromChain,
toChain: toChain,
asset: asset,
amount: amount,
walletType: walletType,
),
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Consider using Decimal instead of double for amount field.

Using double for financial amounts can lead to precision issues. Consider using Decimal type for accurate representation of cryptocurrency amounts.

-  final double amount;
+  final Decimal amount;

You'll also need to handle the serialization appropriately in the parameters map:

  @override
  JsonMap get parameters => {
        'from_chain': fromChain,
        'to_chain': toChain,
        'asset': asset,
-        'amount': amount,
+        'amount': amount.toDouble(), // or amount.toString() depending on backend requirements
        'wallet_type': walletType,
      };

And update the constructor parameter:

  AnalyticsBridgeSucceededEvent({
    required String fromChain,
    required String toChain,
    required String asset,
-    required double amount,
+    required Decimal amount,
    required String walletType,
  }) : super(

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In lib/analytics/events/cross_chain_events.dart between lines 49 and 96, the
amount field is currently a double, which can cause precision errors for
financial data. Change the amount field type in BridgeSucceededEventData and the
constructor of AnalyticsBridgeSucceededEvent to Decimal. Update the parameters
getter to serialize the Decimal amount properly, for example by converting it to
a string. Ensure all references to amount use the Decimal type consistently.

import 'package:web_dex/app_config/app_config.dart';
import 'package:web_dex/bloc/analytics/analytics_bloc.dart';
import 'package:web_dex/bloc/analytics/analytics_repo.dart';
import 'package:web_dex/bloc/analytics/analytics_event.dart';
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove unused import to fix pipeline warning.

The pipeline indicates this import is unused and should be removed.

-import 'package:web_dex/bloc/analytics/analytics_event.dart';
🧰 Tools
🪛 GitHub Actions: CharlVS is validating code guidelines 🚀

[warning] 17-17: Unused import: 'package:web_dex/bloc/analytics/analytics_event.dart' (unused_import)

🤖 Prompt for AI Agents
In lib/bloc/app_bloc_root.dart at line 17, the import statement for
'package:web_dex/bloc/analytics/analytics_event.dart' is unused and causing a
pipeline warning. Remove this import line entirely to resolve the warning and
clean up the code.

Comment on lines +135 to +455
class AnalyticsEvents {
const AnalyticsEvents._();

/// Portfolio P&L viewed event
static PortfolioPnlViewedEvent portfolioPnlViewed({
required String timeframe,
required double realizedPnl,
required double unrealizedPnl,
}) {
return PortfolioPnlViewedEvent(
timeframe: timeframe,
realizedPnl: realizedPnl,
unrealizedPnl: unrealizedPnl,
);
}

/// App opened / foregrounded event
static AppOpenedEvent appOpened({
required String platform,
required String appVersion,
}) {
return AppOpenedEvent(platform: platform, appVersion: appVersion);
}

/// Onboarding started event
static OnboardingStartedEvent onboardingStarted({
required String method,
String? referralSource,
}) {
return OnboardingStartedEvent(
method: method,
referralSource: referralSource,
);
}

/// Wallet created event
static WalletCreatedEvent walletCreated({
required String source,
required String walletType,
}) {
return WalletCreatedEvent(source: source, walletType: walletType);
}

/// Wallet imported event
static WalletImportedEvent walletImported({
required String source,
required String importType,
required String walletType,
}) {
return WalletImportedEvent(
source: source,
importType: importType,
walletType: walletType,
);
}

/// Seed backup completed event
static BackupCompletedEvent backupCompleted({
required int backupTime,
required String method,
required String walletType,
}) {
return BackupCompletedEvent(
backupTime: backupTime,
method: method,
walletType: walletType,
);
}

/// Backup skipped event
static BackupSkippedEvent backupSkipped({
required String stageSkipped,
required String walletType,
}) {
return BackupSkippedEvent(
stageSkipped: stageSkipped,
walletType: walletType,
);
}

/// Bridge initiated event
static BridgeInitiatedEvent bridgeInitiated({
required String fromChain,
required String toChain,
required String asset,
}) {
return BridgeInitiatedEvent(
fromChain: fromChain,
toChain: toChain,
asset: asset,
);
}

/// Bridge success event
static BridgeSuccessEvent bridgeSuccess({
required String fromChain,
required String toChain,
required String asset,
required double amount,
}) {
return BridgeSuccessEvent(
fromChain: fromChain,
toChain: toChain,
asset: asset,
amount: amount,
);
}

/// Bridge failure event
static BridgeFailureEvent bridgeFailure({
required String fromChain,
required String toChain,
required String failError,
}) {
return BridgeFailureEvent(
fromChain: fromChain,
toChain: toChain,
failError: failError,
);
}

/// NFT gallery opened event
static NftGalleryOpenedEvent nftGalleryOpened({
required int nftCount,
required int loadTimeMs,
}) {
return NftGalleryOpenedEvent(
nftCount: nftCount,
loadTimeMs: loadTimeMs,
);
}

/// NFT transfer initiated
static NftTransferInitiatedEvent nftTransferInitiated({
required String collectionName,
required String tokenId,
required String hdType,
}) {
return NftTransferInitiatedEvent(
collectionName: collectionName,
tokenId: tokenId,
hdType: hdType,
);
}

/// NFT transfer success
static NftTransferSuccessEvent nftTransferSuccess({
required String collectionName,
required String tokenId,
required double fee,
required String hdType,
}) {
return NftTransferSuccessEvent(
collectionName: collectionName,
tokenId: tokenId,
fee: fee,
hdType: hdType,
);
}

/// NFT transfer failure
static NftTransferFailureEvent nftTransferFailure({
required String collectionName,
required String failReason,
required String hdType,
}) {
return NftTransferFailureEvent(
collectionName: collectionName,
failReason: failReason,
hdType: hdType,
);
}

/// Marketbot setup started
static MarketbotSetupStartEvent marketbotSetupStart({
required String strategyType,
required int pairsCount,
}) {
return MarketbotSetupStartEvent(
strategyType: strategyType,
pairsCount: pairsCount,
);
}

/// Marketbot setup complete
static MarketbotSetupCompleteEvent marketbotSetupComplete({
required String strategyType,
required double baseCapital,
}) {
return MarketbotSetupCompleteEvent(
strategyType: strategyType,
baseCapital: baseCapital,
);
}

/// Marketbot trade executed
static MarketbotTradeExecutedEvent marketbotTradeExecuted({
required String pair,
required double tradeSize,
required double profitUsd,
}) {
return MarketbotTradeExecutedEvent(
pair: pair,
tradeSize: tradeSize,
profitUsd: profitUsd,
);
}

/// Marketbot error
static MarketbotErrorEvent marketbotError({
required String errorCode,
required String strategyType,
}) {
return MarketbotErrorEvent(
errorCode: errorCode,
strategyType: strategyType,
);
}

/// Reward claim initiated
static RewardClaimInitiatedEvent rewardClaimInitiated({
required String asset,
required double expectedRewardAmount,
}) {
return RewardClaimInitiatedEvent(
asset: asset,
expectedRewardAmount: expectedRewardAmount,
);
}

/// Reward claim success
static RewardClaimSuccessEvent rewardClaimSuccess({
required String asset,
required double rewardAmount,
}) {
return RewardClaimSuccessEvent(
asset: asset,
rewardAmount: rewardAmount,
);
}

/// Reward claim failure
static RewardClaimFailureEvent rewardClaimFailure({
required String asset,
required String failReason,
}) {
return RewardClaimFailureEvent(
asset: asset,
failReason: failReason,
);
}

/// DApp connected
static DappConnectEvent dappConnect({
required String dappName,
required String network,
}) {
return DappConnectEvent(
dappName: dappName,
network: network,
);
}

/// Settings change
static SettingsChangeEvent settingsChange({
required String settingName,
required String newValue,
}) {
return SettingsChangeEvent(
settingName: settingName,
newValue: newValue,
);
}

/// Error displayed
static ErrorDisplayedEvent errorDisplayed({
required String errorCode,
required String screenContext,
}) {
return ErrorDisplayedEvent(
errorCode: errorCode,
screenContext: screenContext,
);
}

/// App shared
static AppShareEvent appShare({
required String channel,
}) {
return AppShareEvent(channel: channel);
}

/// Scroll attempt outside content
static ScrollAttemptOutsideContentEvent scrollAttemptOutsideContent({
required String screenContext,
required double scrollDelta,
}) {
return ScrollAttemptOutsideContentEvent(
screenContext: screenContext,
scrollDelta: scrollDelta,
);
}

/// Searchbar input
static SearchbarInputEvent searchbarInput({
required int queryLength,
String? assetSymbol,
}) {
return SearchbarInputEvent(
queryLength: queryLength,
assetSymbol: assetSymbol,
);
}

/// Theme selected
static ThemeSelectedEvent themeSelected({
required String themeName,
}) {
return ThemeSelectedEvent(themeName: themeName);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider unifying analytics event patterns across the codebase.

This file uses a factory method pattern with AnalyticsEvents class, while transaction_events.dart and portfolio_events.dart use wrapper classes extending AnalyticsSendDataEvent. This inconsistency could lead to confusion and maintenance issues.

Consider either:

  1. Converting this file to use the wrapper class pattern for consistency
  2. Or updating the other files to use the factory pattern
🤖 Prompt for AI Agents
In lib/analytics/analytics_factory.dart from lines 135 to 455, the
AnalyticsEvents class uses a factory method pattern to create event instances,
which is inconsistent with transaction_events.dart and portfolio_events.dart
that use wrapper classes extending AnalyticsSendDataEvent. To fix this, choose
one pattern for all analytics event definitions: either refactor this file to
use wrapper classes extending AnalyticsSendDataEvent like the others, or
refactor the other files to adopt the factory method pattern used here. This
unification will improve code consistency and maintainability.

Comment on lines +5 to +25
class PortfolioPnlViewedEvent extends AnalyticsEventData {
PortfolioPnlViewedEvent({
required this.timeframe,
required this.realizedPnl,
required this.unrealizedPnl,
});

@override
String get name => 'portfolio_pnl_viewed';

final String timeframe;
final double realizedPnl;
final double unrealizedPnl;

@override
Map<String, Object> get parameters => {
'timeframe': timeframe,
'realized_pnl': realizedPnl,
'unrealized_pnl': unrealizedPnl,
};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Inconsistent return type in parameters getter.

The PortfolioPnlViewedEvent uses Map<String, Object> while other events in the file use JsonMap. This should be consistent.

  @override
- Map<String, Object> get parameters => {
+ JsonMap get parameters => {
🤖 Prompt for AI Agents
In lib/analytics/analytics_factory.dart between lines 5 and 25, the parameters
getter in PortfolioPnlViewedEvent returns Map<String, Object> which is
inconsistent with other events that use JsonMap. Change the return type of the
parameters getter to JsonMap and ensure the returned map matches the expected
JsonMap type for consistency across the file.

* docs: Implement security advisory and changelog template

* docs: add v0.9.0 release notes and blog post

* docs: expand v0.9.0 changelog
Copy link
Contributor

@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 (15)
AGENTS.md (5)

3-3: Use American English for consistency
Change “afterwards” to “afterward” to align with American English usage.

- ... dependencies pre-fetched during setup, but network access is disabled afterwards. ...
+ ... dependencies pre-fetched during setup, but network access is disabled afterward. ...
🧰 Tools
🪛 LanguageTool

[locale-violation] ~3-~3: In American English, ‘afterward’ is the preferred variant. ‘Afterwards’ is more commonly used in British English and other dialects.
Context: ...g setup, but network access is disabled afterwards. Use the commands below to work with th...

(AFTERWARDS_US)


25-25: Add missing period and refine sentence
The sentence ends abruptly; add a period and consider clarifying it.

- Unit tests and integration tests are currently failing. Instead of running tests to validate fixes, do a thorough code review of the changes and static analysis
+ Unit tests and integration tests are currently failing. Instead of running tests to validate fixes, thoroughly review the code changes and rely on static analysis.

31-31: Standardize spelling to American English
Change “Familiarise” to “Familiarize” for consistency.

- Familiarise yourself with the BLoC conventions and Conventional Commits standards included at the end of this document.
+ Familiarize yourself with the BLoC conventions and Conventional Commits standards included at the end of this document.

41-41: Adjust heading level for consistency
Use a second-level heading (##) for “Komodo DeFi Flutter SDK” to match other section levels.

- # Komodo DeFi Flutter SDK
+ ## Komodo DeFi Flutter SDK

45-45: Refine wording for clarity
Consider replacing “make up” with a more precise verb, e.g., “comprise” or “constitute.”

- The repository consists of a suite of packages (in the `packages` directory) which make up a Flutter SDK package `komodo_defi_sdk` used for implementing Komodo DeFi into Flutter apps.
+ The repository comprises a suite of packages in the `packages` directory that constitute the `komodo_defi_sdk` Flutter package for implementing Komodo DeFi into Flutter apps.
🧰 Tools
🪛 LanguageTool

[style] ~45-~45: Try using a synonym here to elevate your writing.
Context: ...ges (in the packages directory) which make up a Flutter SDK package komodo_defi_sdk...

(CONSTITUTE_COMPRISE)

docs/RELEASE_NOTES_TEMPLATE.md (4)

1-9: Consider using YAML frontmatter for metadata
The top-of-file metadata (Tags, Application, Platform, Created, Updated, Version) could be expressed as standard YAML frontmatter for clearer semantics and better support by static site generators. For example:

---
tags: [release-notes, changelog, documentation, versioning]
application: Komodo Wallet
platform: Flutter (Web, Desktop, Mobile)
created: 2025-05-19
updated: 2025-05-19
version: 1.0
---

20-24: Enhance input variables section with a table
Turning the list of input variables into a markdown table can improve readability and maintain consistency with the rest of the docs. For example:

| Variable                    | Description                                                            |
|-----------------------------|------------------------------------------------------------------------|
| **{VERSION_NUMBER}**        | The version being released (e.g., "1.0.0")                             |
| **{PREVIOUS_RELEASE_NOTES}**| Example of previous release notes to match style and format            |
| **{CHANGELOG_CONTENT}**     | Raw changelog entries or commit messages to be organized               |
| **{COMMITS_WITH_AUTHORS}**  | List of commits with author information for attribution                |
| **{REFERENCE_VERSION}**     | A reference version with particularly good release notes format (e.g., "v0.9.0") |

64-64: Convert placeholder emphases to section headings
Using bold emphasis (**...**) for placeholder markers can be confusing and triggers markdownlint’s MD036. Consider replacing these with subheadings, e.g.:

### Previous Release Notes
{PREVIOUS_RELEASE_NOTES}

### Changelog Content
{CHANGELOG_CONTENT}

### Commits with Authors
{COMMITS_WITH_AUTHORS}

Also applies to: 68-68, 72-72

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

64-64: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


155-160: Replace empty or placeholder links with real URLs or clear placeholders
Lines like [migration guide](#), [user guide](#), and [API documentation](#) use # as the href, which may trigger markdownlint’s MD042 “No empty links.” Either provide actual URLs or replace # with a clear placeholder such as <URL> or TBD.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

155-155: No empty links
null

(MD042, no-empty-links)


159-159: No empty links
null

(MD042, no-empty-links)


160-160: No empty links
null

(MD042, no-empty-links)

docs/BUILD_SECURITY_ADVISORY.md (3)

17-17: Nitpick: Add comma for clarity.
Consider adding a comma after “pubspec.lock file” for improved readability:

This flag ensures that dependencies are installed exactly as specified in the `pubspec.lock` file, with no automatic updates.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~17-~17: Possible missing comma found.
Context: ...ly** as specified in the pubspec.lock file with no automatic updates. **Why this ...

(AI_HYDRA_LEO_MISSING_COMMA)


8-11: Optional: Clarify flag usage in context.
Listing standalone flags can be ambiguous. To make this section self-contained, you might show the full commands here:

- --enforce-lockfile  # When running 'flutter pub get'
- --no-pub            # When running 'flutter build'
- --no-web-resources-cdn  # When building for web
+ flutter pub get --enforce-lockfile
+ flutter build apk --no-pub
+ flutter build web --no-web-resources-cdn

41-44: Nitpick: Improve phrasing for regulatory context.
The phrase “operate under regulations restricting external resource loading” is a bit wordy. Consider tightening it, for example:

- **Regulatory restrictions**: Many financial applications must bundle resources locally due to regulatory requirements.
🧰 Tools
🪛 LanguageTool

[style] ~44-~44: ‘under regulations’ might be wordy. Consider a shorter alternative.
Context: ...**: Many financial applications operate under regulations restricting external resource loading. ...

(EN_WORDINESS_PREMIUM_UNDER_REGULATIONS)

CHANGELOG.md (3)

28-28: Nitpick: Add definite article.
In the UI/UX section, consider adding “the” for smoother reading:

- improving experience for international users.
+ improving the experience for international users.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~28-~28: Possible missing article found.
Context: ...ore text is now translatable, improving experience for international users. - **Add Assets...

(AI_HYDRA_LEO_MISSING_THE)


30-31: Optional: Include PR/issue reference.
The Wallet Only Logout Confirmation entry currently has no PR or issue number. Please add the appropriate reference (e.g., [@naezith], #<issue>).


75-80: Optional: Highlight new documentation.
Since you’ve introduced docs/BUILD_SECURITY_ADVISORY.md, consider adding a 📖 Documentation section to this changelog:

## 📖 Documentation
- **Build Security Advisory**: Added security guidelines for enforcing lockfiles and build flags (`docs/BUILD_SECURITY_ADVISORY.md`).
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 713d156 and a83fd14.

📒 Files selected for processing (5)
  • AGENTS.md (1 hunks)
  • CHANGELOG.md (1 hunks)
  • docs/BUILD_RELEASE.md (4 hunks)
  • docs/BUILD_SECURITY_ADVISORY.md (1 hunks)
  • docs/RELEASE_NOTES_TEMPLATE.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/BUILD_RELEASE.md
🧰 Additional context used
🪛 LanguageTool
docs/BUILD_SECURITY_ADVISORY.md

[uncategorized] ~17-~17: Possible missing comma found.
Context: ...ly** as specified in the pubspec.lock file with no automatic updates. **Why this ...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~39-~39: You might be missing the article “the” here.
Context: ... for engine resources when building for web. Why this matters: - **Eliminates...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[style] ~44-~44: ‘under regulations’ might be wordy. Consider a shorter alternative.
Context: ...**: Many financial applications operate under regulations restricting external resource loading. ...

(EN_WORDINESS_PREMIUM_UNDER_REGULATIONS)

CHANGELOG.md

[style] ~13-~13: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...for enhanced security and features. - HD Withdrawals & Portfolio Overview ([@C...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[uncategorized] ~28-~28: Possible missing article found.
Context: ...ore text is now translatable, improving experience for international users. - **Add Assets...

(AI_HYDRA_LEO_MISSING_THE)


[grammar] ~49-~49: Did you mean the noun “reception” (= the act of receiving) or “receipt” (= invoice)?
Context: ...VS]) - Resolved display issues with the receive payment button. - **Coin Balance Calcul...

(PREPOSITION_VERB)

AGENTS.md

[locale-violation] ~3-~3: In American English, ‘afterward’ is the preferred variant. ‘Afterwards’ is more commonly used in British English and other dialects.
Context: ...g setup, but network access is disabled afterwards. Use the commands below to work with th...

(AFTERWARDS_US)


[style] ~45-~45: Try using a synonym here to elevate your writing.
Context: ...ges (in the packages directory) which make up a Flutter SDK package komodo_defi_sdk...

(CONSTITUTE_COMPRISE)

docs/RELEASE_NOTES_TEMPLATE.md

[uncategorized] ~49-~49: Use a comma before “and” if it connects two independent clauses (unless they are closely connected and short).
Context: ...egorized - Changes are described clearly and concisely - Proper attribution is given...

(COMMA_COMPOUND_SENTENCE_2)

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

64-64: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


68-68: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


72-72: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


155-155: No empty links
null

(MD042, no-empty-links)


159-159: No empty links
null

(MD042, no-empty-links)


160-160: No empty links
null

(MD042, no-empty-links)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build Desktop (linux)
  • GitHub Check: Build Desktop (windows)
  • GitHub Check: Build Mobile (Android)
  • GitHub Check: Build Mobile (iOS)
🔇 Additional comments (1)
AGENTS.md (1)

37-37: Verify documentation path
Ensure that docs/BUILD_RUN_APP.md exists and the path matches the repository structure.

…2620)

* fix(auth): wallet password validation in creation and update flows

* feat(auth): allow weak password toggle in settings

* fix(password-validator): use Characters.length for better unicode support

* chore(deps): bump SDK hash

9519157

* fix(auth): revert fallback to legacy validator

do not perform any validation if allow_weak_passwords is toggled
@smk762 smk762 self-requested a review May 23, 2025 10:55
Copy link
Collaborator

@smk762 smk762 left a comment

Choose a reason for hiding this comment

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

Though some cosmetic and esoteric issues remain for v0.9.1, core activation and transaction functionality passes.

Priority Todos for 0.9.1:

Copy link
Contributor

@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: 5

♻️ Duplicate comments (1)
assets/translations/en.json (1)

413-413: Inconsistent withdrawal preview key naming.

You have both "withdrawPreview" (line 413) and "previewWithdrawal" (line 671). This duplication can cause confusion and inconsistent UI text.

Consider standardizing on one naming convention. Since "withdrawPreview" appears first and follows the pattern of other keys, consider removing the duplicate:

-    "previewWithdrawal": "Preview Withdrawal",

Or if both are needed for different contexts, ensure they have distinct, descriptive names.

Also applies to: 671-671

🧹 Nitpick comments (2)
assets/translations/en.json (2)

129-129: Password validation message could be more user-friendly.

The password format error message is quite long and technical. Consider breaking it into smaller, more digestible validation messages that can be shown individually.

The current approach with individual password validation messages (lines 369-376) is much better for UX. Consider using those individual messages instead of the comprehensive one on line 129.


347-347: Alpha version warning could be more concise.

The alpha version warning is quite lengthy and might overwhelm users. Consider shortening it while maintaining the essential legal disclaimers.

Break the warning into smaller, more digestible paragraphs or consider highlighting the key risks more prominently.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a83fd14 and c0cf652.

⛔ Files ignored due to path filters (1)
  • lib/generated/codegen_loader.g.dart is excluded by !**/generated/**
📒 Files selected for processing (2)
  • assets/translations/en.json (16 hunks)
  • lib/bloc/auth_bloc/auth_bloc.dart (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Build Desktop (linux)
  • GitHub Check: Build Mobile (Android)
  • GitHub Check: Build Desktop (windows)
  • GitHub Check: Test web-app-macos
  • GitHub Check: Build Mobile (iOS)
🔇 Additional comments (2)
lib/bloc/auth_bloc/auth_bloc.dart (1)

67-76:

✅ Verification successful

Verify legacy wallet detection logic and security implications.

The legacy wallet detection and seed extraction logic needs careful consideration:

  1. The isLegacyWallet property should be thoroughly validated
  2. getLegacySeed() method exposes sensitive seed data - ensure proper security measures

🏁 Script executed:

#!/bin/bash
# Description: Verify legacy wallet handling and seed security across the codebase

# Search for isLegacyWallet property usage and implementation
ast-grep --pattern 'isLegacyWallet'

# Search for getLegacySeed method implementation and usage
ast-grep --pattern 'getLegacySeed($_)'

# Check for any security measures around seed handling
rg -A 5 -B 5 "getLegacySeed|isLegacyWallet"

Length of output: 5970


Legacy wallet detection and seed handling are implemented correctly

  • isLegacyWallet is a straightforward getter on config.isLegacyWallet, which is reliably set in wallets_repository when loading legacy wallets.
  • getLegacySeed(password) uses EncryptionTool().decryptData to decrypt the stored seed phrase. No seeds are logged or persisted in plaintext.
  • AuthBloc branches on isLegacyWallet and passes the seed only to the restoration flow, then immediately deletes the legacy wallet to avoid duplication.

No changes required in AuthBloc—ensure that the underlying EncryptionTool employs a strong KDF and encryption algorithm, and audit it if necessary.

assets/translations/en.json (1)

669-669:

✅ Verification successful

Potential duplicate "transactionSuccessful" usage.

While the past review comments indicate the duplicate transactionSuccessful keys were addressed, line 669 shows this key again. Verify this isn't a reintroduction of the duplicate.

Also applies to: 51-51


🏁 Script executed:

#!/bin/bash
# Description: Check for any remaining duplicate keys in the translation file

# Search for duplicate keys in the JSON file
cat assets/translations/en.json | jq -r 'keys[]' | sort | uniq -d

# Search specifically for transactionSuccessful occurrences
rg -n "transactionSuccessful" assets/translations/en.json

Length of output: 184


No duplicate “transactionSuccessful” key found

Verified with jq and rg that transactionSuccessful appears only once in assets/translations/en.json (line 669), and no duplicate keys exist. No further action required.

Comment on lines +224 to +229
// Delete legacy wallet on successful restoration & login to avoid
// duplicates in the wallet list
if (event.wallet.isLegacyWallet) {
await _kdfSdk.addActivatedCoins(event.wallet.config.activatedCoins);
await _walletsRepository.deleteWallet(event.wallet);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Legacy wallet deletion after restoration could cause data loss.

Deleting the legacy wallet immediately after successful restoration might be premature. If there are any issues with the SDK wallet or coin activation, the user could lose access to their funds.

Consider a safer approach:

-      // Delete legacy wallet on successful restoration & login to avoid
-      // duplicates in the wallet list
-      if (event.wallet.isLegacyWallet) {
-        await _kdfSdk.addActivatedCoins(event.wallet.config.activatedCoins);
-        await _walletsRepository.deleteWallet(event.wallet);
-      }
+      // Mark legacy wallet for deletion after successful SDK integration
+      if (event.wallet.isLegacyWallet) {
+        await _kdfSdk.addActivatedCoins(event.wallet.config.activatedCoins);
+        // Consider marking as migrated rather than immediate deletion
+        // await _walletsRepository.markWalletMigrated(event.wallet);
+      }
📝 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
// Delete legacy wallet on successful restoration & login to avoid
// duplicates in the wallet list
if (event.wallet.isLegacyWallet) {
await _kdfSdk.addActivatedCoins(event.wallet.config.activatedCoins);
await _walletsRepository.deleteWallet(event.wallet);
}
// Mark legacy wallet for deletion after successful SDK integration
if (event.wallet.isLegacyWallet) {
await _kdfSdk.addActivatedCoins(event.wallet.config.activatedCoins);
// Consider marking as migrated rather than immediate deletion
// await _walletsRepository.markWalletMigrated(event.wallet);
}
🤖 Prompt for AI Agents
In lib/bloc/auth_bloc/auth_bloc.dart around lines 224 to 229, avoid deleting the
legacy wallet immediately after restoration to prevent potential data loss if
SDK wallet or coin activation fails. Instead, implement a verification step to
confirm successful coin activation and wallet functionality before deleting the
legacy wallet. This ensures the user retains access to their funds until the new
wallet is fully operational.

Comment on lines +295 to +302
void _listenToAuthStateChanges() {
_authChangesSubscription?.cancel();
_authChangesSubscription = _kdfSdk.auth.authStateChanges.listen((user) {
final AuthorizeMode event =
user != null ? AuthorizeMode.logIn : AuthorizeMode.noLogin;
add(AuthModeChanged(mode: event, currentUser: user));
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Missing error handling in auth state listener.

The _listenToAuthStateChanges method doesn't handle potential errors in the stream, which could cause the app to miss important auth state changes.

Add error handling to the stream subscription:

  void _listenToAuthStateChanges() {
    _authChangesSubscription?.cancel();
    _authChangesSubscription = _kdfSdk.auth.authStateChanges.listen(
      (user) {
        final AuthorizeMode event =
            user != null ? AuthorizeMode.logIn : AuthorizeMode.noLogin;
        add(AuthModeChanged(mode: event, currentUser: user));
      },
+      onError: (error, stackTrace) {
+        _log.shout('Error in auth state changes stream', error, stackTrace);
+        // Consider emitting an error state or attempting to reconnect
+      },
    );
  }
📝 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
void _listenToAuthStateChanges() {
_authChangesSubscription?.cancel();
_authChangesSubscription = _kdfSdk.auth.authStateChanges.listen((user) {
final AuthorizeMode event =
user != null ? AuthorizeMode.logIn : AuthorizeMode.noLogin;
add(AuthModeChanged(mode: event, currentUser: user));
});
}
void _listenToAuthStateChanges() {
_authChangesSubscription?.cancel();
_authChangesSubscription = _kdfSdk.auth.authStateChanges.listen(
(user) {
final AuthorizeMode event =
user != null ? AuthorizeMode.logIn : AuthorizeMode.noLogin;
add(AuthModeChanged(mode: event, currentUser: user));
},
onError: (error, stackTrace) {
_log.shout('Error in auth state changes stream', error, stackTrace);
// Consider emitting an error state or attempting to reconnect
},
);
}
🤖 Prompt for AI Agents
In lib/bloc/auth_bloc/auth_bloc.dart around lines 295 to 302, the
_listenToAuthStateChanges method subscribes to the authStateChanges stream but
lacks error handling for the stream. Modify the listen call to include an
onError callback that handles errors appropriately, such as logging the error or
dispatching an error event, to ensure the app can respond to stream errors and
maintain reliable auth state updates.

Comment on lines +153 to +162
await _kdfSdk.auth.register(
password: event.password,
walletName: event.wallet.name,
options: AuthOptions(
derivationMethod: event.wallet.config.type == WalletType.hdwallet
? DerivationMethod.hdWallet
: DerivationMethod.iguana,
allowWeakPassword: weakPasswordsAllowed,
),
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Code duplication between register and restore methods.

Both _onRegister and _onRestore have nearly identical SDK registration calls with similar error handling patterns.

Extract the common registration logic into a helper method:

+  Future<void> _performRegistration({
+    required String password,
+    required String walletName,
+    required WalletType walletType,
+    Mnemonic? mnemonic,
+  }) async {
+    final weakPasswordsAllowed = await _areWeakPasswordsAllowed();
+    
+    await _kdfSdk.auth.register(
+      password: password,
+      walletName: walletName,
+      mnemonic: mnemonic,
+      options: AuthOptions(
+        derivationMethod: walletType == WalletType.hdwallet
+            ? DerivationMethod.hdWallet
+            : DerivationMethod.iguana,
+        allowWeakPassword: weakPasswordsAllowed,
+      ),
+    );
+  }

Then use this helper in both register and restore methods to reduce duplication.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In lib/bloc/auth_bloc/auth_bloc.dart around lines 153 to 162, the registration
logic in _onRegister and _onRestore methods is duplicated. Extract the common
SDK registration call and its error handling into a separate private helper
method that accepts necessary parameters like password, wallet name, and
options. Then replace the duplicated code in both _onRegister and _onRestore
with calls to this new helper method to reduce redundancy and improve
maintainability.

Comment on lines +144 to +147
emit(AuthBlocState.loading());
if (await _didSignInExistingWallet(event.wallet, event.password)) {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential infinite recursion in wallet registration.

The _didSignInExistingWallet method dispatches AuthSignInRequested event, which could create an infinite loop if the sign-in process repeatedly fails and triggers registration again.

Consider adding a flag or counter to prevent infinite recursion:

-      if (await _didSignInExistingWallet(event.wallet, event.password)) {
-        return;
-      }
+      if (await _didSignInExistingWallet(event.wallet, event.password)) {
+        _log.info('Existing wallet found, sign-in attempt dispatched');
+        return;
+      }

Also ensure _didSignInExistingWallet has proper error handling to avoid recursive registration attempts.

🤖 Prompt for AI Agents
In lib/bloc/auth_bloc/auth_bloc.dart around lines 144 to 147, the call to
_didSignInExistingWallet can cause infinite recursion because it dispatches
AuthSignInRequested, potentially triggering repeated sign-in attempts and
registration. To fix this, introduce a flag or counter to track the number of
sign-in attempts and prevent repeated retries beyond a safe limit. Additionally,
add proper error handling in _didSignInExistingWallet to catch failures and
avoid triggering recursive registration attempts.

@CharlVS
Copy link
Collaborator Author

CharlVS commented May 23, 2025

secure code reviewed ✅

However, multiple dependencies (outdated / abandoned / not maintained) might negatively impact the overall application (performance / upward-compatibility, etc) - please re-evaluate all dependencies.

@ca333 Acknowledged. I've started with some changes needed in #2642 (localisations) and #2675 (JS). Will look into the rest as well. Some of those packages relate to storage, which we can refactor to KDF. I'll handle all the low-hanging items in time for v0.9.1 RC and then give you feedback on what it will take for the remainder.

@CharlVS CharlVS removed QA Ready for QA Testing SEC review pending Awaiting SEC review labels May 23, 2025
kingwojak

This comment was marked as duplicate.

Copy link
Contributor

@ca333 ca333 left a comment

Choose a reason for hiding this comment

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

@ca333 ca333 merged commit 333c20d into main May 23, 2025
11 of 15 checks passed
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.

10 participants