Skip to content

Thorchain integration#9403

Open
rafaelekol wants to merge 5 commits into
version/0.50from
thorchain-integration
Open

Thorchain integration#9403
rafaelekol wants to merge 5 commits into
version/0.50from
thorchain-integration

Conversation

@rafaelekol

@rafaelekol rafaelekol commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

#9402

Summary by CodeRabbit

  • New Features
    • Added Thorchain support across wallets: balances, transfers, deposits, address validation, and transaction history.
    • Enabled Thorchain tokens throughout token variants, fees, rates, and multiswap sending flows.
    • Added dedicated Thorchain send + confirmation screens (fee, memo, and address risk handling) and RuneScan transaction links.
    • Display Thorchain in app status and transaction detail screens (including memos and fees).
  • Bug Fixes
    • Improved balance sorting/emission to avoid stale balance rows overwriting newer adapter state.

Implement end-to-end THORChain support in multiswap sending flow. This adds THORChain-specific send data/settings/result types, a dedicated send transaction service, and adapter `deposit()` support for native THOR swaps (with MsgDeposit when no inbound vault, or MsgSend when inbound exists). It also updates quote parsing for nullable inbound/gas fields, improves THOR asset mapping (including RUNE and cache version bump), wires THOR tx hash into swap confirmation, and updates marketkit/thorchainkit versions.
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: dab9bdd2-d854-406d-8941-099c8c25fdb7

📥 Commits

Reviewing files that changed from the base of the PR and between 998e2e5 and b82ac69.

📒 Files selected for processing (10)
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainAdapter.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainTransactionConverter.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AdapterFactory.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/ThorchainKitManager.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/balance/BalanceService.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/SendPage.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainModule.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainScreen.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainViewModel.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/settings/appstatus/AppStatusViewModel.kt
🚧 Files skipped from review as they are similar to previous changes (10)
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/balance/BalanceService.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainModule.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/settings/appstatus/AppStatusViewModel.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/SendPage.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainScreen.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AdapterFactory.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainTransactionConverter.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/ThorchainKitManager.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainViewModel.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainAdapter.kt

📝 Walkthrough

Walkthrough

Adds Thorchain support across dependency configuration, blockchain metadata, kit lifecycle management, wallet and transaction adapters, multiswap flows, send screens, transaction presentation, app status, balance handling, and address derivation validation.

Changes

Thorchain integration

Layer / File(s) Summary
Contracts, blockchain metadata, and address handling
gradle/libs.versions.toml, walletkit/build.gradle.kts, walletkit/src/main/java/io/horizontalsystems/walletkit/core/*, walletkit/src/main/java/io/horizontalsystems/walletkit/modules/address/*, walletkit/src/main/java/io/horizontalsystems/walletkit/entities/transactionrecords/thorchain/*
Adds the Thorchain kit dependency, blockchain and token mappings, address parsing and validation support, send adapter contracts, and incoming/outgoing transaction record types.
Kit lifecycle and wallet adapters
walletkit/src/main/java/io/horizontalsystems/walletkit/core/App.kt, walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/*, walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/*, walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/*
Adds ref-counted ThorchainKit lifecycle management, balance and send adapters, transaction conversion/filtering, adapter creation, refresh, unlinking, and atomic adapter-map replacement.
Swap asset and transaction integration
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/*, walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/*, walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/{SwapConfirmViewModel.kt,history/SwapInfoViewModel.kt}
Maps Thorchain assets, supports deposit versus vault-send transaction data, adds Thorchain send transaction services/results, and stores RuneScan transaction hashes and URLs.
Thorchain send experience
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/*
Adds Thorchain send routing, address validation, amount and fee setup, Compose entry and confirmation screens, view-model state, memo handling, and send-result processing.
Transaction and status presentation
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/{transactionInfo,transactions,settings/appstatus}/*, walletkit/src/main/java/io/horizontalsystems/walletkit/ui/compose/components/TransactionInfoCells.kt
Renders Thorchain incoming and outgoing records, includes fees and memos, supports wallet grouping and transaction navigation, and reports Thorchain kit status.
Balance handling and validation coverage
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/balance/*, walletkit/src/main/java/io/horizontalsystems/walletkit/modules/coin/*, walletkit/src/main/java/io/horizontalsystems/walletkit/modules/configuredtoken/*, walletkit/src/test/java/io/horizontalsystems/walletkit/ThorchainAddressDerivationTest.kt
Preserves the unsorted balance source during asynchronous sorting, adds Thorchain asset display metadata and syncing progress, and tests deterministic mainnet address derivation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SendPage
  participant SendThorchainViewModel
  participant ThorchainAdapter
  participant ThorchainKit
  SendPage->>SendThorchainViewModel: collect amount and address state
  SendThorchainViewModel->>ThorchainAdapter: send(amount, address, memo)
  ThorchainAdapter->>ThorchainKit: submit Thorchain transaction
  ThorchainKit-->>ThorchainAdapter: transaction id
  ThorchainAdapter-->>SendThorchainViewModel: transaction id
Loading

Possibly related PRs

Suggested reviewers: abdrasulov

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding Thorchain support to the wallet.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch thorchain-integration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds THORChain (RUNE + THORChain assets) support across walletkit, including address handling, send flow, transaction parsing/display, and multiswap integration; also includes a couple of concurrency/race-condition fixes in adapter/balance update flows.

Changes:

  • Introduce THORChain kit manager + adapters (balance/receive/send + transactions) and wire them into App, adapter factories/managers, and UI.
  • Add THORChain send screens + confirmation flow, address validation/handling, and transaction record/view-item support (list + details).
  • Update multiswap Thorchain-provider logic for THORChain-native inputs, plus dependency bumps to bring in thorchain-kit-android.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
walletkit/src/test/java/io/horizontalsystems/walletkit/ThorchainAddressDerivationTest.kt Adds deterministic THORChain address derivation test.
walletkit/src/main/java/io/horizontalsystems/walletkit/ui/compose/components/TransactionInfoCells.kt Enables transaction options UI for THORChain.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/watchaddress/WatchAddressViewModel.kt Marks THORChain as unsupported for watch-address flow.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/transactions/TransactionViewItemFactory.kt Adds list-item mapping for THORChain incoming/outgoing records.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/transactions/TransactionRecordRepository.kt Includes THORChain in supported transaction repository blockchains.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/transactionInfo/TransactionViewItemFactoryHelper.kt Adds THORChain fee section handling for outgoing tx info.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/transactionInfo/TransactionInfoViewItemFactory.kt Adds THORChain transaction info sections + memo item.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/transactionInfo/TransactionInfoService.kt Includes THORChain coin UIDs for rate lookups in tx info.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/settings/appstatus/AppStatusViewModel.kt Displays THORChain kit status in app status screen.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/settings/appstatus/AppStatusModule.kt Injects THORChain manager into app status VM.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainViewModel.kt Implements THORChain send ViewModel + confirmation data + send action.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainScreen.kt Adds THORChain send Compose screen UI.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainModule.kt Adds DI factory/wiring for THORChain send flow.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainConfirmationScreen.kt Adds THORChain send confirmation Compose screen.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainAddressService.kt Adds THORChain send address validation service.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/SendPage.kt Routes THORChain to new send screen/module.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/SendConfirmationPage.kt Adds THORChain confirmation page type and routing.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/address/EnterAddressValidator.kt Adds THORChain address validator using ISendThorchainAdapter.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/SwapConfirmViewModel.kt Supports THORChain tx hash extraction from send results.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionSettings.kt Adds THORChain send-transaction settings type.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionServiceThorchain.kt Implements THORChain send-transaction service (swap/deposit/send).
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionServiceFactory.kt Creates THORChain send-transaction service via Thorchain adapter.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionResult.kt Adds THORChain send-transaction result type.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionData.kt Adds THORChain send data models (Deposit/Send).
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/USwapProvider.kt Adds THORChain-native token asset mapping for provider assets map.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/SwapHelper.kt Resolves THORChain receive address via THORChain kit manager.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/MayaProvider.kt Tightens null handling for inbound address in Maya quote conversion.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/BaseThorChainProvider.kt Adds THORChain-native swap send-data path + versioned cache for asset mapping.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/history/SwapInfoViewModel.kt Adds RuneScan tx explorer URL for THORChain.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/configuredtoken/ConfiguredTokenInfoViewModel.kt Displays THORChain asset denom in configured token info.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/coin/overview/CoinOverviewViewModel.kt Adds THORChain asset variants for coin overview.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/balance/BalanceViewItemFactory.kt Assigns sorting weight for THORChain balances.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/balance/BalanceService.kt Fixes race by avoiding writing sorted results back to shared list.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/address/IAddressHandler.kt Adds THORChain address handler + UDN code mapping.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/address/AddressInputModule.kt Registers THORChain handler in address parser chain.
walletkit/src/main/java/io/horizontalsystems/walletkit/modules/address/AddressHandlerFactory.kt Adds THORChain handler to handler factory.
walletkit/src/main/java/io/horizontalsystems/walletkit/entities/transactionrecords/thorchain/ThorchainTransactionRecord.kt Introduces base THORChain transaction record.
walletkit/src/main/java/io/horizontalsystems/walletkit/entities/transactionrecords/thorchain/ThorchainOutgoingTransactionRecord.kt Adds THORChain outgoing record model.
walletkit/src/main/java/io/horizontalsystems/walletkit/entities/transactionrecords/thorchain/ThorchainIncomingTransactionRecord.kt Adds THORChain incoming record model.
walletkit/src/main/java/io/horizontalsystems/walletkit/entities/Address.kt Adds THORChain support in address→tokenType mapping.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/providers/FeeTokenProvider.kt Ensures THORChain assets use native fee token query.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/MarketKitExtensions.kt Adds THORChain support metadata (supported token types, titles, ordering, etc.).
walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/TransactionAdapterManager.kt Wires THORChain transactions adapter creation.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/ThorchainKitManager.kt Adds THORChain kit lifecycle manager + signer/address helpers.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/AdapterManager.kt Adds THORChain refresh + fixes init adapter-map rebuild race.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/Interfaces.kt Adds ISendThorchainAdapter interface.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AddressValidatorFactory.kt Registers THORChain validator in factory.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AdapterFactory.kt Creates THORChain adapters + THORChain transactions adapter.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/App.kt Adds THORChain kit manager wiring into app singleton graph.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainTransactionsAdapter.kt Implements THORChain ITransactionsAdapter.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainTransactionConverter.kt Converts Midgard transactions into wallet transaction records.
walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainAdapter.kt Implements THORChain balance/receive/send adapter.
walletkit/build.gradle.kts Adds thorchain kit dependency to walletkit module.
gradle/libs.versions.toml Adds thorchainKit version + bumps marketKit version.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

abdrasulov
abdrasulov previously approved these changes Jul 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 13

🧹 Nitpick comments (1)
walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AdapterFactory.kt (1)

188-190: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated ThorchainAdapter construction.

The exact same ThorchainAdapter(thorchainKitManager.getThorchainKitWrapper(wallet.account), wallet) expression appears at both the TokenType.Native/BlockchainType.Thorchain branch and the TokenType.ThorchainAsset branch. Extracting a small private helper (e.g. getThorchainAdapter(wallet)) avoids the two call sites drifting apart later.

♻️ Proposed refactor
+    private fun getThorchainAdapter(wallet: Wallet): IAdapter =
+        ThorchainAdapter(thorchainKitManager.getThorchainKitWrapper(wallet.account), wallet)
+
             BlockchainType.Thorchain -> {
-                ThorchainAdapter(thorchainKitManager.getThorchainKitWrapper(wallet.account), wallet)
+                getThorchainAdapter(wallet)
             }
...
        is TokenType.ThorchainAsset -> when (wallet.token.blockchainType) {
-            BlockchainType.Thorchain -> ThorchainAdapter(thorchainKitManager.getThorchainKitWrapper(wallet.account), wallet)
+            BlockchainType.Thorchain -> getThorchainAdapter(wallet)
             else -> null
        }

Also applies to: 226-229

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AdapterFactory.kt`
around lines 188 - 190, Extract the duplicated ThorchainAdapter construction
from the TokenType.Native/BlockchainType.Thorchain and TokenType.ThorchainAsset
branches into a private helper such as getThorchainAdapter(wallet). Replace both
call sites with the helper while preserving the existing
thorchainKitManager.getThorchainKitWrapper(wallet.account) and wallet arguments.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainAdapter.kt`:
- Line 34: Update the coroutine collectors launched from ThorchainAdapter around
coroutineScope, including the getDenomBalanceFlow(denom) and syncStateFlow
collectors, to handle uncaught flow exceptions with catch or surrounding
try-catch. Ensure one collector’s failure does not cancel sibling coroutines or
silently stop balance and sync updates, while preserving the existing
estimateFee handling.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainTransactionConverter.kt`:
- Around line 39-54: Update the transaction conversion loop around userSpends
and ThorchainOutgoingTransactionRecord so to is resolved from the current
transfer’s asset-specific counterparty rather than
transaction.outgoing.firstOrNull(). Preserve first-entry fallback only if the
model guarantees one counterparty per asset, and ensure each generated record is
attributed to the correct address in multi-transfer actions.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/ThorchainKitManager.kt`:
- Around line 22-29: Update ThorchainKitManager to implement the Clearable
interface and add an override clear() method that cancels the manager’s scope
using coroutineScope.cancel(). Preserve the existing job cancellation behavior
in stop(), and ensure the scope property is the one cleaned up.
- Around line 102-123: Protect the backgroundManager.stateFlow collector in
start() with exception handling so failures from thorchainKit.pause(), the
delayed resume path, or related state handling do not silently terminate the
launch coroutine. Catch and visibly report exceptions using the project’s
established logging mechanism while preserving the existing
background/foreground transition behavior.
- Around line 44-82: Update ThorchainKitManager’s getThorchainKitWrapper,
getSigner, and getAddress seed-derived operations so cryptographic work executes
on Dispatchers.IO within runCatching (or equivalent manager-level background
dispatch), while preserving their existing results and
UnsupportedAccountException behavior.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/modules/balance/BalanceService.kt`:
- Around line 99-109: Update the balance refresh flow around ensureActive() and
_balanceItemsFlow.update so cancellation validation and emission are serialized
with the source update. Use the existing mutex or generation/token mechanism to
revalidate the sort job while holding the synchronization guard immediately
before publishing, preventing a cancelled job from emitting stale sorted rows.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/USwapProvider.kt`:
- Around line 223-229: Update the provider’s blockchainTypes registration to
include Thorchain so discovery reaches the existing BlockchainType.Thorchain
branch. In start(), version the cached provider identifier and invalidate or
replace the unversioned cache entry so existing clients refresh stale or missing
data while preserving current discovery behavior.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionServiceThorchain.kt`:
- Around line 60-68: Update SendTransactionServiceThorchain.sendTransaction so
the adapter.deposit and adapter.send calls execute inside
withContext(Dispatchers.IO), including the surrounding signing and broadcast
operations while preserving the existing transaction-result flow.
- Around line 23-57: Serialize access to sendData and cautions in
SendTransactionServiceThorchain using the existing mutex withLock, including
updates in setSendTransactionData and the snapshot read in createState. Ensure
the confirmation/quote refresh flow cannot observe partially updated state,
while preserving the current caution calculation and emitted state behavior.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/SendPage.kt`:
- Around line 187-200: Propagate the prefilled input.memo through the Thorchain
send flow: pass it from SendPage’s SendThorchainModule.Factory and
SendThorchainScreen construction, add the corresponding Factory/ViewModel
parameters, and initialize the Thorchain memo field with it. Preserve existing
behavior when no memo is provided.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainAddressService.kt`:
- Around line 12-62: Refactor SendThorchainAddressService to extend ServiceState
and replace the hand-rolled MutableStateFlow/State setup with override fun
createState(). Move address validation and updates into mutex.withLock, derive
all state from the state passed to the update operation, and call emitState()
after mutations; preserve the existing validAddress, invalid-address error, and
canBeSend behavior.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainViewModel.kt`:
- Around line 64-87: Wrap each of the four collectors in
init—amountService.stateFlow, addressService.stateFlow, and both
xRateService.getRateFlow calls—with the project’s established coroutine
exception-handling pattern, using try-catch or a Flow catch operator. Ensure
exceptions from handleUpdatedAmountState, handleUpdatedAddressState, and rate
updates are handled without silently terminating the viewModelScope launches.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/modules/settings/appstatus/AppStatusViewModel.kt`:
- Around line 229-231: Update getBlockchainStatusBlock() to add a Thorchain
branch that reads thorchainKitManager.statusInfo and includes it in the
block-based App Status UI, matching the existing getBlockchainStatus() behavior
and formatting used for other blockchains.

---

Nitpick comments:
In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AdapterFactory.kt`:
- Around line 188-190: Extract the duplicated ThorchainAdapter construction from
the TokenType.Native/BlockchainType.Thorchain and TokenType.ThorchainAsset
branches into a private helper such as getThorchainAdapter(wallet). Replace both
call sites with the helper while preserving the existing
thorchainKitManager.getThorchainKitWrapper(wallet.account) and wallet arguments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5dad10aa-38d4-4bc5-8315-a64e3df289a0

📥 Commits

Reviewing files that changed from the base of the PR and between f8eabb0 and 998e2e5.

📒 Files selected for processing (54)
  • gradle/libs.versions.toml
  • walletkit/build.gradle.kts
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/App.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/Interfaces.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/MarketKitExtensions.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainAdapter.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainTransactionConverter.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainTransactionsAdapter.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AdapterFactory.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AddressValidatorFactory.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/AdapterManager.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/ThorchainKitManager.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/TransactionAdapterManager.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/core/providers/FeeTokenProvider.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/entities/Address.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/entities/transactionrecords/thorchain/ThorchainIncomingTransactionRecord.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/entities/transactionrecords/thorchain/ThorchainOutgoingTransactionRecord.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/entities/transactionrecords/thorchain/ThorchainTransactionRecord.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/address/AddressHandlerFactory.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/address/AddressInputModule.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/address/IAddressHandler.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/balance/BalanceService.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/balance/BalanceViewItemFactory.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/coin/overview/CoinOverviewViewModel.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/configuredtoken/ConfiguredTokenInfoViewModel.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/SwapConfirmViewModel.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/history/SwapInfoViewModel.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/BaseThorChainProvider.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/MayaProvider.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/SwapHelper.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/USwapProvider.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionData.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionResult.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionServiceFactory.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionServiceThorchain.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionSettings.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/SendConfirmationPage.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/SendPage.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/address/EnterAddressValidator.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainAddressService.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainConfirmationScreen.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainModule.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainScreen.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainViewModel.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/settings/appstatus/AppStatusModule.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/settings/appstatus/AppStatusViewModel.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/transactionInfo/TransactionInfoService.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/transactionInfo/TransactionInfoViewItemFactory.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/transactionInfo/TransactionViewItemFactoryHelper.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/transactions/TransactionRecordRepository.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/transactions/TransactionViewItemFactory.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/modules/watchaddress/WatchAddressViewModel.kt
  • walletkit/src/main/java/io/horizontalsystems/walletkit/ui/compose/components/TransactionInfoCells.kt
  • walletkit/src/test/java/io/horizontalsystems/walletkit/ThorchainAddressDerivationTest.kt

Comment on lines +44 to +82
@Synchronized
fun getThorchainKitWrapper(account: Account): ThorchainKitWrapper {
if (this.thorchainKitWrapper != null && currentAccount != account) {
stop()
}

if (this.thorchainKitWrapper == null) {
val accountType = account.type
this.thorchainKitWrapper = when (accountType) {
is AccountType.Mnemonic -> {
createKitInstance(accountType, account)
}

else -> throw UnsupportedAccountException()
}
start()
useCount = 0
currentAccount = account
}

useCount++
return this.thorchainKitWrapper!!
}

private fun createKitInstance(accountType: AccountType.Mnemonic, account: Account): ThorchainKitWrapper {
val kit = ThorchainKit.getInstance(App.instance, accountType.seed, Network.Mainnet, account.id)

return ThorchainKitWrapper(kit)
}

fun getSigner(accountType: AccountType): Signer = when (accountType) {
is AccountType.Mnemonic -> Signer.getInstance(accountType.seed, Network.Mainnet)
else -> throw UnsupportedAccountException()
}

fun getAddress(accountType: AccountType): String = when (accountType) {
is AccountType.Mnemonic -> ThorchainKit.getAddress(accountType.seed, Network.Mainnet).toString()
else -> throw UnsupportedAccountException()
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm all call sites of these ThorchainKitManager methods run on Dispatchers.IO (or a background context) rather than Main.
rg -n --type=kt 'thorchainKitManager\.(getThorchainKitWrapper|getSigner|getAddress)' -B5 -A2

Repository: horizontalsystems/unstoppable-wallet-android

Length of output: 209


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Kotlin files matching ThorchainKitManager/Adapter:"
git ls-files | rg '(^|/)Thorchain|ThorchainKitManager\.kt|ThorchainAdapter\.kt|WalletKit' || true

echo
echo "Direct method references:"
rg -n 'thorchainKitManager\.(getThorchainKitWrapper|getSigner|getAddress)' || true

echo
echo "Manager declarations/imports/usages:"
rg -n 'ThorchainKitManager|ThorchainAdapter|getThorchainKitWrapper|getSigner\(|getAddress\(' .

Repository: horizontalsystems/unstoppable-wallet-android

Length of output: 1118


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re, subprocess

files = subprocess.check_output(['git','ls-files','--', '*.kt'], text=True).splitlines()
queries = ['getThorchainKitWrapper', 'getSigner', 'getAddress']
# also include ThorchainKitManager.getThorchainKitWrapper for direct qualifier form
queries += ['ThorchainKitManager']

target_pat = re.compile(r'ThorchainKitManager\.(?:getThorchainKitWrapper|getSigner|getAddress)\b|thorchainKitManager\.(?:getThorchainKitWrapper|getSigner|getAddress)\b|getThorchainKitWrapper\s*\(|getSigner\s*\(|getAddress\s*\(')
for fpath in files:
    if fpath.startswith('walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/ThorchainKitManager.kt'):
        continue
    try:
        txt = Path(fpath).read_text(errors='ignore')
    except Exception:
        continue
    if target_pat.search(txt):
        print(f'--- {fpath}')
        lines = txt.splitlines()
        for i,l in enumerate(lines,1):
            if target_pat.search(l):
                lo=max(1,i-8); hi=min(len(lines),i+6)
                for j in range(lo,hi+1):
                    marker='>> ' if j==i else '   '
                    print(f'{marker}{j:4}\t{lines[j-1]}')
PY

Repository: horizontalsystems/unstoppable-wallet-android

Length of output: 14917


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repository root:"
pwd
echo
git ls-files | wc -l
echo
echo "Top-level files:"
git ls-files | sed 's#/.*##' | sort -u | head -100
echo
echo "Root tree-ish entries (tree equivalent):"
git ls-tree --name-only -d HEAD | sort -u | head -200

Repository: horizontalsystems/unstoppable-wallet-android

Length of output: 892


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "All Kotlin files matching ThorchainKitManager/thorchainKitManager/address:"
git ls-files '*.kt' '\*.kt' | xargs rg -n 'ThorchainKitManager|thorchainKitManager|App\.thorchainKitManager|getThorchainKitWrapper\(|getSigner\(|getAddress\(' -g '*.kt' || true

echo
echo "Search all files for Thorchain address/signing method references:"
rg -n 'ThorchainKit\.getAddress|ThorchainKit\.getInstance|Signer\.(getInstance|address)|ThorchainAdapter|ThorchainTransactionsAdapter|thorchainKitManager' . || true

echo
echo "Candidate adapter contexts:"
for f in \
  walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainAdapter.kt \
  walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AdapterFactory.kt \
  walletkit/src/main/java/io/horizontalsystems/walletkit/modules/address/IAddressHandler.kt \
  walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/SwapHelper.kt \
  walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/ThorchainKitManager.kt
do
  if [ -f "$f" ]; then
    echo "===== $f ====="
    wc -l "$f"
    ast-grep outline "$f" || true
  fi
done

Repository: horizontalsystems/unstoppable-wallet-android

Length of output: 22476


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "All matches using git-tracked .kt files:"
git ls-files '*.kt' | while IFS= read -r f; do
  rg -n 'ThorchainKitManager|thorchainKitManager|App\.thorchainKitManager|getThorchainKitWrapper\(|getSigner\(|getAddress\(' "$f" || true
done

echo
echo "Search all checked-out files for related Thorchain references:"
rg -n 'ThorchainKit\.getAddress|ThorchainKit\.getInstance|Signer\.(getInstance|address)|ThorchainAdapter|ThorchainTransactionsAdapter|thorchainKitManager' --glob '*.kt' --glob '*.java' --glob '*.kts' --glob '*.gradle' --glob '*.xml' . || true

echo
echo "Candidate file contexts:"
for f in \
  walletkit/src/main/java/io/horizontalsystems/walletkit/core/adapters/ThorchainAdapter.kt \
  walletkit/src/main/java/io/horizontalsystems/walletkit/core/factories/AdapterFactory.kt \
  walletkit/src/main/java/io/horizontalsystems/walletkit/modules/address/IAddressHandler.kt \
  walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/providers/SwapHelper.kt \
  walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/ThorchainKitManager.kt
do
  if [ -f "$f" ]; then
    echo "===== $f ====="
    wc -l "$f"
    ast-grep outline "$f" || true
  fi
done

Repository: horizontalsystems/unstoppable-wallet-android

Length of output: 18679


Dispatch Thorchain seed operations off the main thread.

getThorchainKitWrapper, getSigner, and getAddress derive from the raw seed synchronously. Current Kotlin call sites include AdapterFactory and SwapHelper, but those caller contexts don’t establish a background dispatcher; move the seed operations into runCatching { withContext(Dispatchers.IO) { ... } } or otherwise ensure the manager itself runs the cryptographic work off the main thread.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/core/managers/ThorchainKitManager.kt`
around lines 44 - 82, Update ThorchainKitManager’s getThorchainKitWrapper,
getSigner, and getAddress seed-derived operations so cryptographic work executes
on Dispatchers.IO within runCatching (or equivalent manager-level background
dispatch), while preserving their existing results and
UnsupportedAccountException behavior.

Source: Path instructions

Comment on lines +60 to +68
override suspend fun sendTransaction(mevProtectionEnabled: Boolean): SendTransactionResult {
val txHash = when (val data = sendData!!) {
is SendTransactionData.Thorchain.Deposit -> {
adapter.deposit(data.asset, data.amount, data.memo)
}

is SendTransactionData.Thorchain.Send -> {
adapter.send(data.amount, data.address, data.memo)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Confine signing and broadcast to Dispatchers.IO.

SwapConfirmViewModel.swap() invokes this path from Dispatchers.Default; this service does not switch dispatchers before adapter.deposit() or adapter.send(). Enforce withContext(Dispatchers.IO) around those operations.

As per path instructions, “Cryptographic operations must run on Dispatchers.IO or a dedicated executor, never Dispatchers.Main.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/modules/multiswap/sendtransaction/SendTransactionServiceThorchain.kt`
around lines 60 - 68, Update SendTransactionServiceThorchain.sendTransaction so
the adapter.deposit and adapter.send calls execute inside
withContext(Dispatchers.IO), including the surrounding signing and broadcast
operations while preserving the existing transaction-result flow.

Source: Path instructions

Comment on lines +12 to +62
class SendThorchainAddressService {
private var address: Address? = null
private var addressError: Throwable? = null

private val _stateFlow = MutableStateFlow(
State(
address = address,
addressError = addressError,
canBeSend = addressError == null,
)
)
val stateFlow = _stateFlow.asStateFlow()

fun setAddress(address: Address?) {
this.address = address

validateAddress()

emitState()
}

private fun validateAddress() {
addressError = null
val address = this.address ?: return

try {
ThorchainAddress.fromString(address.hex, Network.Mainnet)
} catch (e: Exception) {
addressError = Throwable(Translator.getString(R.string.SwapSettings_Error_InvalidAddress))
}
}

private fun emitState() {
_stateFlow.update {
State(
address = address,
addressError = addressError,
canBeSend = addressError == null
)
}
}

data class State(
val address: Address?,
val addressError: Throwable?,
val canBeSend: Boolean
) {
val validAddress: Address?
get() = if (addressError == null) address else null
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Doesn't follow the required Service pattern (ServiceState + mutex-guarded updates).

Per repo guidelines for **/*Service.kt, Services should extend a ServiceState base class with override fun createState() and guard state mutations with mutex.withLock. This class instead manages a hand-rolled data class State and mutates plain address/addressError vars directly, then rebuilds state in emitState() from those external vars rather than from the it passed into _stateFlow.update, which defeats the atomicity update provides.

As per coding guidelines, "Use ServiceState base class for Services with override fun createState() and call emitState() after state changes" and "Use mutex.withLock for thread-safe state updates in Services."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainAddressService.kt`
around lines 12 - 62, Refactor SendThorchainAddressService to extend
ServiceState and replace the hand-rolled MutableStateFlow/State setup with
override fun createState(). Move address validation and updates into
mutex.withLock, derive all state from the state passed to the update operation,
and call emitState() after mutations; preserve the existing validAddress,
invalid-address error, and canBeSend behavior.

Source: Coding guidelines

Comment on lines +64 to +87
init {
viewModelScope.launch(Dispatchers.Default) {
amountService.stateFlow.collect {
handleUpdatedAmountState(it)
}
}
viewModelScope.launch(Dispatchers.Default) {
addressService.stateFlow.collect {
handleUpdatedAddressState(it)
}
}
viewModelScope.launch(Dispatchers.Default) {
xRateService.getRateFlow(sendToken.coin.uid).collect {
coinRate = it
}
}
viewModelScope.launch(Dispatchers.Default) {
xRateService.getRateFlow(feeToken.coin.uid).collect {
feeCoinRate = it
}
}

addressService.setAddress(address)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Unguarded launch blocks in init can silently crash on an uncaught exception.

The four viewModelScope.launch(Dispatchers.Default) { ... } collectors (amount state, address state, two rate flows) have no try-catch/catch operator. An exception inside any collector (e.g. from handleUpdatedAmountState/handleUpdatedAddressState) propagates uncaught.

As per coding guidelines, "Wrap uncaught exceptions in launch blocks with try-catch or use the catch operator to prevent silent termination."

🛡️ Example fix pattern
         viewModelScope.launch(Dispatchers.Default) {
-            amountService.stateFlow.collect {
-                handleUpdatedAmountState(it)
-            }
+            amountService.stateFlow
+                .catch { logger.warning("amount state collection failed", it) }
+                .collect { handleUpdatedAmountState(it) }
         }

Apply the same pattern to the other three collectors.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@walletkit/src/main/java/io/horizontalsystems/walletkit/modules/send/thorchain/SendThorchainViewModel.kt`
around lines 64 - 87, Wrap each of the four collectors in
init—amountService.stateFlow, addressService.stateFlow, and both
xRateService.getRateFlow calls—with the project’s established coroutine
exception-handling pattern, using try-catch or a Flow catch operator. Ensure
exceptions from handleUpdatedAmountState, handleUpdatedAddressState, and rate
updates are handled without silently terminating the viewModelScope launches.

Source: Coding guidelines

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants