Skip to content

Commit

Permalink
Fix xrp balances
Browse files Browse the repository at this point in the history
  • Loading branch information
furenster committed Dec 15, 2024
1 parent 285e85e commit 45f359e
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.gemwallet.android.blockchain.clients.xrp

import com.gemwallet.android.blockchain.clients.xrp.services.XrpAccountsService
import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest
import com.wallet.core.blockchain.xrp.models.XRPAccount
import com.wallet.core.blockchain.xrp.models.XRPAccountResult
import com.wallet.core.blockchain.xrp.models.XRPResult

internal class TestXrpAccountsService(
val balance: String = "",
) : XrpAccountsService {
var requestAccount: String? = ""

override suspend fun account(request: JSONRpcRequest<List<Map<String, String>>>): Result<XRPResult<XRPAccountResult>> {
requestAccount = request.params[0]["account"]
return Result.success(
XRPResult(
XRPAccountResult(
XRPAccount(
Balance = balance,
Sequence = 92788459,
)
)
)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.gemwallet.android.blockchain.clients.xrp

import com.gemwallet.android.blockchain.clients.xrp.services.XrpAccountsService
import com.gemwallet.android.blockchain.includeLibs
import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest
import com.gemwallet.android.ext.toIdentifier
import com.wallet.core.blockchain.xrp.models.XRPAccount
import com.wallet.core.blockchain.xrp.models.XRPAccountResult
import com.wallet.core.blockchain.xrp.models.XRPResult
import com.wallet.core.primitives.AssetId
import com.wallet.core.primitives.Chain
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertNotNull
import kotlinx.coroutines.runBlocking
import org.junit.Test

class TestXrpBalanceClient {
companion object {
init {
includeLibs()
}
}

@Test
fun testXrp_native_balance() {
val accountsService = TestXrpAccountsService("2104374")
val balanceClient = XrpBalanceClient(
chain = Chain.Xrp,
accountsService = accountsService
)
val result = runBlocking {
balanceClient.getNativeBalance(Chain.Xrp, "rwCq6DCHa6HPFyfvabvzcX1y5wABw5KdiN")
}
assertEquals("rwCq6DCHa6HPFyfvabvzcX1y5wABw5KdiN", accountsService.requestAccount)
assertNotNull(result)
assertEquals("1104374", result.balance.available)
assertEquals("0", result.balance.frozen)
assertEquals("0", result.balance.locked)
assertEquals("0", result.balance.staked)
assertEquals("0", result.balance.rewards)
assertEquals("1000000", result.balance.reserved)
assertEquals("0", result.balance.pending)
assertEquals(1.104374, result.balanceAmount.available)
assertEquals(0.0, result.balanceAmount.frozen)
assertEquals(0.0, result.balanceAmount.locked)
assertEquals(0.0, result.balanceAmount.staked)
assertEquals(0.0, result.balanceAmount.rewards)
assertEquals(1.0, result.balanceAmount.reserved)
assertEquals(0.0, result.balanceAmount.pending)
assertEquals(1.104374, result.totalAmount)
assertEquals(AssetId(Chain.Xrp).toIdentifier(), result.asset.id.toIdentifier())
}

@Test
fun testXrp_native_fail_balance() {
val accountsService = TestXrpAccountsService("")
val balanceClient = XrpBalanceClient(
chain = Chain.Xrp,
accountsService = accountsService
)
val result = runBlocking {
balanceClient.getNativeBalance(Chain.Xrp, "rwCq6DCHa6HPFyfvabvzcX1y5wABw5KdiN")
}
assertEquals("rwCq6DCHa6HPFyfvabvzcX1y5wABw5KdiN", accountsService.requestAccount)
assertNotNull(result)
assertEquals("0", result.balance.available)
assertEquals("0", result.balance.frozen)
assertEquals("0", result.balance.locked)
assertEquals("0", result.balance.staked)
assertEquals("0", result.balance.rewards)
assertEquals("1000000", result.balance.reserved)
assertEquals("0", result.balance.pending)
assertEquals(0.0, result.balanceAmount.available)
assertEquals(0.0, result.balanceAmount.frozen)
assertEquals(0.0, result.balanceAmount.locked)
assertEquals(0.0, result.balanceAmount.staked)
assertEquals(0.0, result.balanceAmount.rewards)
assertEquals(1.0, result.balanceAmount.reserved)
assertEquals(0.0, result.balanceAmount.pending)
assertEquals(0.0, result.totalAmount)
assertEquals(AssetId(Chain.Xrp).toIdentifier(), result.asset.id.toIdentifier())
}

@Test
fun testXrp_native_zero_balance() {
val accountsService = TestXrpAccountsService("1000000")
val balanceClient = XrpBalanceClient(
chain = Chain.Xrp,
accountsService = accountsService
)
val result = runBlocking {
balanceClient.getNativeBalance(Chain.Xrp, "rwCq6DCHa6HPFyfvabvzcX1y5wABw5KdiN")
}
assertEquals("rwCq6DCHa6HPFyfvabvzcX1y5wABw5KdiN", accountsService.requestAccount)
assertNotNull(result)
assertEquals("0", result.balance.available)
assertEquals("0", result.balance.frozen)
assertEquals("0", result.balance.locked)
assertEquals("0", result.balance.staked)
assertEquals("0", result.balance.rewards)
assertEquals("1000000", result.balance.reserved)
assertEquals("0", result.balance.pending)
assertEquals(0.0, result.balanceAmount.available)
assertEquals(0.0, result.balanceAmount.frozen)
assertEquals(0.0, result.balanceAmount.locked)
assertEquals(0.0, result.balanceAmount.staked)
assertEquals(0.0, result.balanceAmount.rewards)
assertEquals(1.0, result.balanceAmount.reserved)
assertEquals(0.0, result.balanceAmount.pending)
assertEquals(0.0, result.totalAmount)
assertEquals(AssetId(Chain.Xrp).toIdentifier(), result.asset.id.toIdentifier())
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.gemwallet.android.blockchain.clients.xrp

import com.gemwallet.android.blockchain.clients.BalanceClient
import com.gemwallet.android.blockchain.clients.xrp.services.XrpAccountsService
import com.gemwallet.android.blockchain.clients.xrp.services.account
import com.gemwallet.android.ext.asset
import com.gemwallet.android.ext.getReserveBalance
import com.gemwallet.android.model.AssetBalance
Expand All @@ -10,17 +12,18 @@ import java.math.BigInteger

class XrpBalanceClient(
private val chain: Chain,
private val rpcClient: XrpRpcClient,
private val accountsService: XrpAccountsService,
) : BalanceClient {

override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance {
val amount = rpcClient.account(address).mapCatching {
it.result.account_data.Balance.toBigInteger() - chain.getReserveBalance()
val reserved = chain.getReserveBalance()
val amount = accountsService.account(address).mapCatching {
it.result.account_data.Balance.toBigInteger() - reserved
}.getOrNull() ?: BigInteger.ZERO
return AssetBalance.create(
chain.asset(),
available = amount.toString(),
reserved = (Config().getChainConfig(chain.string).accountActivationFee?.toString() ?: 0).toString()
reserved = reserved.toString()
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.gemwallet.android.blockchain.clients.xrp

import com.gemwallet.android.blockchain.clients.xrp.services.XrpAccountsService
import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest
import com.wallet.core.blockchain.xrp.models.XRPAccountResult
import com.wallet.core.blockchain.xrp.models.XRPFee
Expand All @@ -12,9 +13,7 @@ import retrofit2.http.Body
import retrofit2.http.POST
import retrofit2.http.Url

interface XrpRpcClient {
@POST("/")
suspend fun account(@Body request: JSONRpcRequest<List<Map<String, String>>>): Result<XRPResult<XRPAccountResult>>
interface XrpRpcClient : XrpAccountsService {

@POST("/")
suspend fun fee(@Body request: JSONRpcRequest<List<Map<String, String>>>): Result<XRPResult<XRPFee>>
Expand All @@ -29,19 +28,6 @@ interface XrpRpcClient {
suspend fun latestBlock(@Url url: String, @Body request: JSONRpcRequest<List<Map<String, String>>>): Response<XRPResult<XRPLatestBlock>>
}

internal suspend fun XrpRpcClient.account(address: String): Result<XRPResult<XRPAccountResult>> {
val request = JSONRpcRequest.create(
XrpMethod.Account,
listOf(
mapOf(
"account" to address,
"ledger_index" to "current",
)
)
)
return account(request)
}

internal suspend fun XrpRpcClient.fee(): Result<XRPResult<XRPFee>> {
return fee(JSONRpcRequest.create(XrpMethod.Fee, listOf(mapOf())))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gemwallet.android.blockchain.clients.xrp

import com.gemwallet.android.blockchain.clients.NativeTransferPreloader
import com.gemwallet.android.blockchain.clients.xrp.services.account
import com.gemwallet.android.model.ConfirmParams
import com.gemwallet.android.model.Fee
import com.gemwallet.android.model.ChainSignData
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.gemwallet.android.blockchain.clients.xrp.services

import com.gemwallet.android.blockchain.clients.xrp.XrpMethod
import com.gemwallet.android.blockchain.clients.xrp.XrpRpcClient
import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest
import com.wallet.core.blockchain.xrp.models.XRPAccountResult
import com.wallet.core.blockchain.xrp.models.XRPResult
import retrofit2.http.Body
import retrofit2.http.POST

interface XrpAccountsService {
@POST("/")
suspend fun account(@Body request: JSONRpcRequest<List<Map<String, String>>>): Result<XRPResult<XRPAccountResult>>
}

internal suspend fun XrpAccountsService.account(address: String): Result<XRPResult<XRPAccountResult>> {
val request = JSONRpcRequest.create(
XrpMethod.Account,
listOf(
mapOf(
"account" to address,
"ledger_index" to "current",
)
)
)
return account(request)
}
2 changes: 1 addition & 1 deletion gemcore/src/main/java/com/gemwallet/android/ext/Chain.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fun Chain.assetType(): AssetType? {
}

fun Chain.getReserveBalance(): BigInteger = when (this) {
Chain.Xrp -> BigInteger.valueOf(10_000_000)
Chain.Xrp -> Config().getChainConfig(this.string).accountActivationFee?.toBigInteger() ?: BigInteger.ZERO
else -> BigInteger.ZERO
}

Expand Down

0 comments on commit 45f359e

Please sign in to comment.