merge: reconcile with feature/trc20-tron-send into one combined branch

Bitcoin was branched off main independently instead of continuing on top
of the Tron send branch, which caused real divergence: both branches touch
the same shared signing/DI code (multiChainEncryptionFor, getMetaAccountKeypair,
NodeHealthStateTesterFactory, AssetsModule/TypeBasedAssetSourceRegistry,
CloudBackup schema, Fee model), and both need to ship together in one
coordinated release once wallet-util's master is unblocked. Merging now
reconciles that before it gets any harder, and gives one branch/versionCode
history for device testing instead of two that silently diverge.

Conflict resolutions of note:
- SecretStoreV2/SecretsSigner: getKeypair and multiChainEncryptionFor now
  recognize Tron AND Bitcoin accounts (isTronBased/isBitcoinBased both
  threaded through, checked before the Ethereum fallback).
- AccountDataSourceImpl: both address-backfill migrations now run
  sequentially in one coroutine (Tron's fix for a race against the legacy
  migration applies equally to Bitcoin's backfill).
- CloudBackup: kept Tron's forward-looking Solana schema reservation
  alongside Tron's and Bitcoin's now-real fields.
- ChainRegistryModule/NodeHealthStateTesterFactory: adopted Tron's
  self-contained short-lived OkHttpClient (simpler than threading the
  shared app-wide client through RuntimeDependencies, which is reverted).
- RealSecretsMetaAccount: extended Tron's chain-account MultiChainEncryption
  fix to also cover Bitcoin, for the same underlying reason.
- ChainExt.isValidAddress: Tron's branch independently closed the
  pre-existing Tron validation gap; kept alongside Bitcoin's own check.
This commit is contained in:
2026-07-12 19:02:08 -07:00
62 changed files with 2851 additions and 265 deletions
@@ -164,7 +164,12 @@ abstract class ChainDao {
// ------- Queries ------
@Query("SELECT * FROM chains")
// ORDER BY rowid: without an explicit order, SQLite gives no guarantee about row order for `SELECT *`.
// The merged chains.json lists Pezkuwi's own chains first (see wallet-utils' merge_chains()), and that
// order is what gets inserted first on initial sync - rowid tracks insertion order, so ordering by it
// means Pezkuwi's chains reliably register/connect first instead of being interleaved unpredictably
// among the ~90+ Nova-inherited chains, where they could otherwise end up processed last.
@Query("SELECT * FROM chains ORDER BY rowid")
@Transaction
abstract suspend fun getJoinChainInfo(): List<JoinedChainInfo>
@@ -172,7 +177,7 @@ abstract class ChainDao {
@Transaction
abstract suspend fun getAllChainIds(): List<String>
@Query("SELECT * FROM chains")
@Query("SELECT * FROM chains ORDER BY rowid")
@Transaction
abstract fun joinChainInfoFlow(): Flow<List<JoinedChainInfo>>
@@ -131,6 +131,32 @@ class MetaAccountLocal(
}
}
// We do not use copy as we need explicitly set id
fun addTronAccount(
tronPublicKey: ByteArray,
tronAddress: ByteArray,
): MetaAccountLocal {
return MetaAccountLocal(
substratePublicKey = substratePublicKey,
substrateCryptoType = substrateCryptoType,
substrateAccountId = substrateAccountId,
ethereumPublicKey = ethereumPublicKey,
ethereumAddress = ethereumAddress,
name = name,
parentMetaId = parentMetaId,
isSelected = isSelected,
position = position,
type = type,
status = status,
globallyUniqueId = globallyUniqueId,
typeExtras = typeExtras,
tronPublicKey = tronPublicKey,
tronAddress = tronAddress
).also {
it.id = id
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is MetaAccountLocal) return false