Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions app/src/main/java/one/mixin/android/db/web3/Web3AddressDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,25 @@ interface Web3AddressDao : BaseDao<Web3Address> {
@Query("SELECT EXISTS(SELECT 1 FROM addresses WHERE destination = :address)")
suspend fun addressMatch(address: String): Boolean

@Query("""
SELECT w.* FROM (${Web3WalletDao.WALLET_ITEM_QUERY}) w
INNER JOIN addresses a ON w.id = a.wallet_id
WHERE a.destination = :destination LIMIT 1
""")
suspend fun getWalletByDestination(destination: String): WalletItem?

@Query("""
SELECT * FROM (${Web3WalletDao.WALLET_ITEM_QUERY}) w
WHERE w.safeAddress = :destination AND w.safeChainId = :chainId LIMIT 1
""")
suspend fun getWalletByAddress(destination: String, chainId: String): WalletItem?
@Query(
"""
SELECT wallet_id AS id, category, name, created_at AS createdAt, updated_at AS updatedAt,
NULL AS safeRole, NULL AS safeChainId, NULL AS safeAddress, NULL AS safeUrl
FROM wallets
WHERE wallet_id IN (SELECT wallet_id FROM addresses WHERE destination = :destination)
LIMIT 1
""",
)
suspend fun getWalletByDestination(destination: String): WalletItem? // Only find with wallets

@Query(
"""
SELECT wallet_id AS id, 'mixin_safe' AS category, name, created_at AS createdAt, updated_at AS updatedAt,
role AS safeRole, chain_id AS safeChainId, address AS safeAddress, url AS safeUrl
FROM safe_wallets
WHERE address = :destination AND chain_id = :chainId
LIMIT 1
""",
)
suspend fun getSafeWalletByAddress(destination: String, chainId: String): WalletItem? // Only find with safe_wallets
Comment on lines +55 to +66
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

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

The inline comments "Only find with wallets" and "Only find with safe_wallets" describe implementation details rather than the purpose or usage of these methods. Consider updating these comments to describe when each method should be used or what scenarios they handle, which would be more helpful for API consumers.

Copilot uses AI. Check for mistakes.
}
12 changes: 12 additions & 0 deletions app/src/main/java/one/mixin/android/db/web3/Web3TokenDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import one.mixin.android.vo.safe.UnifiedAssetItem
@Dao
interface Web3TokenDao : BaseDao<Web3Token> {

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query(
"""SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t
LEFT JOIN chains c ON c.chain_id = t.chain_id LEFT JOIN tokens_extra te ON te.asset_id = t.asset_id AND te.wallet_id = t.wallet_id
Expand All @@ -25,6 +26,7 @@ interface Web3TokenDao : BaseDao<Web3Token> {
)
fun web3TokenItems(walletId: String): LiveData<List<Web3TokenItem>>

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query(
"""SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t
LEFT JOIN chains c ON c.chain_id = t.chain_id LEFT JOIN tokens_extra te ON te.asset_id = t.asset_id AND te.wallet_id = t.wallet_id
Expand All @@ -34,12 +36,14 @@ interface Web3TokenDao : BaseDao<Web3Token> {
)
fun web3TokenItems(walletId: String, level:Int): LiveData<List<Web3TokenItem>>

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query("SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t LEFT JOIN chains c ON c.chain_id = t.chain_id LEFT JOIN tokens_extra te ON te.asset_id = t.asset_id AND te.wallet_id = t.wallet_id WHERE t.wallet_id = :walletId")
suspend fun findWeb3TokenItems(walletId: String): List<Web3TokenItem>

@Query("SELECT t.symbol, t.icon_url AS iconUrl, t.amount AS balance, t.price_usd AS priceUsd FROM tokens t LEFT JOIN tokens_extra te ON t.asset_id = te.asset_id AND t.wallet_id = te.wallet_id WHERE t.amount * t.price_usd > 0 AND t.wallet_id = :walletId AND (te.hidden IS NULL OR te.hidden = 0) ORDER BY t.amount * t.price_usd")
suspend fun findUnifiedAssetItem(walletId: String): List<UnifiedAssetItem>

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query("SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t LEFT JOIN chains c ON c.chain_id = t.chain_id LEFT JOIN tokens_extra te ON te.asset_id = t.asset_id AND te.wallet_id = t.wallet_id WHERE t.amount > 0 AND t.wallet_id = :walletId")
suspend fun findAssetItemsWithBalance(walletId: String): List<Web3TokenItem>

Expand All @@ -66,9 +70,11 @@ interface Web3TokenDao : BaseDao<Web3Token> {
@Query("SELECT t.symbol, t.icon_url AS iconUrl, t.amount AS balance, t.price_usd AS priceUsd FROM tokens t LEFT JOIN tokens_extra te ON t.asset_id = te.asset_id AND t.wallet_id = te.wallet_id WHERE t.amount * t.price_usd > 0 AND t.wallet_id IN (:walletIds) AND (te.hidden IS NULL OR te.hidden = 0) ORDER BY t.amount * t.price_usd")
suspend fun allWeb3Tokens(walletIds: List<String>): List<UnifiedAssetItem>

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query("SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t LEFT JOIN chains c ON c.chain_id = t.chain_id LEFT JOIN tokens_extra te ON te.asset_id = t.asset_id AND te.wallet_id = t.wallet_id WHERE t.wallet_id = :walletId AND t.asset_id = :assetId")
fun web3TokenItemById(walletId: String, assetId: String): Web3TokenItem?

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query("SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t LEFT JOIN chains c ON c.chain_id = t.chain_id LEFT JOIN tokens_extra te ON te.asset_id = t.asset_id AND te.wallet_id = t.wallet_id WHERE t.asset_key = :address")
suspend fun web3TokenItemByAddress(address: String): Web3TokenItem?

Expand All @@ -84,9 +90,11 @@ interface Web3TokenDao : BaseDao<Web3Token> {
@Query("UPDATE tokens SET amount = '0' WHERE wallet_id = :walletId")
suspend fun updateAllBalancesToZero(walletId: String)

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query("SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t LEFT JOIN chains c ON c.chain_id = t.chain_id LEFT JOIN tokens_extra te ON te.asset_id = t.asset_id AND te.wallet_id = t.wallet_id WHERE t.wallet_id = :walletId AND t.asset_id IN (:assetIds)")
suspend fun findWeb3TokenItemsByIds(walletId: String, assetIds: List<String>): List<Web3TokenItem>

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query("SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t LEFT JOIN chains c ON c.chain_id = t.chain_id LEFT JOIN tokens_extra te ON te.asset_id = t.asset_id AND te.wallet_id = t.wallet_id WHERE t.wallet_id = :walletId AND t.asset_id IN (:assetIds)")
fun findWeb3TokenItemsByIdsSync(walletId: String, assetIds: List<String>): List<Web3TokenItem>

Expand Down Expand Up @@ -123,6 +131,7 @@ interface Web3TokenDao : BaseDao<Web3Token> {
@Query("DELETE FROM tokens WHERE wallet_id = :walletId AND asset_id NOT IN (:assetIds)")
suspend fun deleteNotIn(walletId: String, assetIds: List<String>)

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query(
"""SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t
LEFT JOIN chains c ON c.chain_id = t.chain_id LEFT JOIN tokens_extra te ON te.asset_id = t.asset_id AND te.wallet_id = t.wallet_id
Expand All @@ -133,6 +142,7 @@ interface Web3TokenDao : BaseDao<Web3Token> {
)
fun web3TokenItemsByWalletIds(walletIds: List<String>): LiveData<List<Web3TokenItem>>

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query(
"""SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t
LEFT JOIN chains c ON c.chain_id = t.chain_id
Expand All @@ -143,6 +153,7 @@ interface Web3TokenDao : BaseDao<Web3Token> {
)
fun web3TokenItemsAll(): LiveData<List<Web3TokenItem>>

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query(
"""SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t
LEFT JOIN chains c ON c.chain_id = t.chain_id
Expand All @@ -158,6 +169,7 @@ interface Web3TokenDao : BaseDao<Web3Token> {
)
fun web3TokenItemsFromAllOrders(): LiveData<List<Web3TokenItem>>

@SuppressWarnings(RoomWarnings.QUERY_MISMATCH)
@Query(
"""SELECT t.*, c.icon_url as chain_icon_url, c.name as chain_name, c.symbol as chain_symbol, te.hidden FROM tokens t
LEFT JOIN chains c ON c.chain_id = t.chain_id
Expand Down
93 changes: 72 additions & 21 deletions app/src/main/java/one/mixin/android/db/web3/Web3WalletDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,98 @@ import one.mixin.android.vo.WalletCategory
@Dao
interface Web3WalletDao : BaseDao<Web3Wallet> {

companion object {
const val WALLET_ITEM_QUERY = """
SELECT wallet_id AS id, category, name, created_at AS createdAt, updated_at AS updatedAt,
NULL AS safeRole, NULL AS safeChainId, NULL AS safeAddress, NULL AS safeUrl
FROM wallets
UNION ALL
SELECT wallet_id AS id, 'mixin_safe' AS category, name, created_at AS createdAt, updated_at AS updatedAt,
role AS safeRole, chain_id AS safeChainId, address AS safeAddress, url AS safeUrl
FROM safe_wallets
"""
}

@Query("""
SELECT * FROM ($WALLET_ITEM_QUERY) w WHERE w.id != :excludeWalletId AND w.name LIKE '%' || :query || '%' AND
(EXISTS (SELECT 1 FROM addresses a WHERE a.wallet_id = w.id AND a.chain_id = :chainId) OR w.safeChainId = :chainId)
SELECT wallet_id AS id, category, name, created_at AS createdAt, updated_at AS updatedAt,
NULL AS safeRole, NULL AS safeChainId, NULL AS safeAddress, NULL AS safeUrl
FROM wallets
WHERE wallet_id != :excludeWalletId
AND name LIKE '%' || :query || '%'
AND EXISTS (SELECT 1 FROM addresses a WHERE a.wallet_id = wallets.wallet_id AND a.chain_id = :chainId)
UNION ALL
SELECT wallet_id AS id, 'mixin_safe' AS category, name, created_at AS createdAt, updated_at AS updatedAt,
role AS safeRole, chain_id AS safeChainId, address AS safeAddress, url AS safeUrl
FROM safe_wallets
WHERE wallet_id != :excludeWalletId
AND name LIKE '%' || :query || '%'
AND chain_id = :chainId
ORDER BY createdAt ASC
""")
""")
suspend fun getWalletsExcludingByName(excludeWalletId: String, chainId: String, query: String): List<WalletItem>

@Query("SELECT * FROM ($WALLET_ITEM_QUERY) w WHERE w.id != :excludeWalletId AND w.name LIKE '%' || :query || '%' ORDER BY createdAt ASC")
@Query("""
SELECT wallet_id AS id, category, name, created_at AS createdAt, updated_at AS updatedAt,
NULL AS safeRole, NULL AS safeChainId, NULL AS safeAddress, NULL AS safeUrl
FROM wallets
WHERE wallet_id != :excludeWalletId AND name LIKE '%' || :query || '%'
UNION ALL
SELECT wallet_id AS id, 'mixin_safe' AS category, name, created_at AS createdAt, updated_at AS updatedAt,
role AS safeRole, chain_id AS safeChainId, address AS safeAddress, url AS safeUrl
FROM safe_wallets
WHERE wallet_id != :excludeWalletId AND name LIKE '%' || :query || '%'
ORDER BY createdAt ASC
""")
suspend fun getWalletsExcludingByNameAllChains(excludeWalletId: String, query: String): List<WalletItem>

@Query("SELECT * FROM ($WALLET_ITEM_QUERY) ORDER BY createdAt ASC")
@Query("""
SELECT wallet_id AS id, category, name, created_at AS createdAt, updated_at AS updatedAt,
NULL AS safeRole, NULL AS safeChainId, NULL AS safeAddress, NULL AS safeUrl
FROM wallets
UNION ALL
SELECT wallet_id AS id, 'mixin_safe' AS category, name, created_at AS createdAt, updated_at AS updatedAt,
role AS safeRole, chain_id AS safeChainId, address AS safeAddress, url AS safeUrl
FROM safe_wallets
ORDER BY createdAt ASC
""")
fun getWallets(): Flow<List<WalletItem>>

@Query("SELECT * FROM ($WALLET_ITEM_QUERY) ORDER BY createdAt ASC")
@Query("""
SELECT wallet_id AS id, category, name, created_at AS createdAt, updated_at AS updatedAt,
NULL AS safeRole, NULL AS safeChainId, NULL AS safeAddress, NULL AS safeUrl
FROM wallets
UNION ALL
SELECT wallet_id AS id, 'mixin_safe' AS category, name, created_at AS createdAt, updated_at AS updatedAt,
role AS safeRole, chain_id AS safeChainId, address AS safeAddress, url AS safeUrl
FROM safe_wallets
ORDER BY createdAt ASC
""")
suspend fun getAllWallets(): List<WalletItem>

@Query("SELECT wallet_id FROM wallets WHERE category = 'classic' ORDER BY created_at ASC LIMIT 1 ")
suspend fun getClassicWalletId(): String?

@Query("SELECT * FROM ($WALLET_ITEM_QUERY) WHERE id = :walletId")
@Query("""
SELECT wallet_id AS id, category, name, created_at AS createdAt, updated_at AS updatedAt,
NULL AS safeRole, NULL AS safeChainId, NULL AS safeAddress, NULL AS safeUrl
FROM wallets
WHERE wallet_id = :walletId
UNION ALL
SELECT wallet_id AS id, 'mixin_safe' AS category, name, created_at AS createdAt, updated_at AS updatedAt,
role AS safeRole, chain_id AS safeChainId, address AS safeAddress, url AS safeUrl
FROM safe_wallets
WHERE wallet_id = :walletId
LIMIT 1
""")
suspend fun getWalletById(walletId: String): WalletItem?

@Query("SELECT * FROM ($WALLET_ITEM_QUERY) WHERE category = 'mixin_safe' AND safeChainId = :chainId ORDER BY createdAt ASC")
@Query("""
SELECT wallet_id AS id, 'mixin_safe' AS category, name, created_at AS createdAt, updated_at AS updatedAt,
role AS safeRole, chain_id AS safeChainId, address AS safeAddress, url AS safeUrl
FROM safe_wallets
WHERE chain_id = :chainId
ORDER BY createdAt ASC
""")
suspend fun getSafeWalletsByChainId(chainId: String): List<WalletItem>

@Query("SELECT name FROM wallets WHERE category IN (:categories)")
suspend fun getAllWalletNames(categories: List<String>): List<String>

@Query("SELECT * FROM ($WALLET_ITEM_QUERY) WHERE category = 'classic' ORDER BY createdAt ASC")
@Query("""
SELECT wallet_id AS id, category, name, created_at AS createdAt, updated_at AS updatedAt,
NULL AS safeRole, NULL AS safeChainId, NULL AS safeAddress, NULL AS safeUrl
FROM wallets
WHERE category = 'classic'
ORDER BY createdAt ASC
""")
suspend fun getAllClassicWallets(): List<WalletItem>

@Query("DELETE FROM wallets WHERE wallet_id = :walletId")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ constructor(

suspend fun getWalletByDestination(destination: String) = web3AddressDao.getWalletByDestination(destination)?.updateWithLocalKeyInfo(MixinApplication.appContext)

suspend fun getWalletByAddress(destination: String, chainId: String) = web3AddressDao.getWalletByAddress(destination, chainId)?.updateWithLocalKeyInfo(MixinApplication.appContext)
suspend fun getSafeWalletByAddress(destination: String, chainId: String) = web3AddressDao.getSafeWalletByAddress(destination, chainId)?.updateWithLocalKeyInfo(MixinApplication.appContext)

// Only deposit display
suspend fun getTokenByWalletAndAssetId(walletId: String, assetId: String): Web3TokenItem? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ internal constructor(
if (existsInAddresses) return@withContext Triple(MixinApplication.appContext.getString(R.string.Privacy_Wallet), 1, null)
}

val safeWallet = web3Repository.getWalletByAddress(destination, chainId)
val safeWallet = web3Repository.getSafeWalletByAddress(destination, chainId)
if (safeWallet != null) {
val isOwner: Boolean = safeWallet.isOwner()
return@withContext Triple(safeWallet.name, 2, isOwner)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class SessionRequestViewModel
}

if (chainId != null) {
val wallet = web3Repository.getWalletByAddress(destination, chainId)
val wallet = web3Repository.getSafeWalletByAddress(destination, chainId)
if (wallet != null) {
val isOwner: Boolean = wallet.isOwner()
return@withContext Triple(wallet.name, 2, isOwner) // Safe Wallet
Expand Down
41 changes: 0 additions & 41 deletions app/src/sharedTest/java/one.mixin.android.mock/AccountMock.kt

This file was deleted.

Loading