From 36060b4173082f56affde2e430a839ead34184ad Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Fri, 29 Aug 2025 00:27:36 -0700 Subject: [PATCH 01/16] Update core --- .../com/gemwallet/android/di/DataModule.kt | 8 +++ .../features/bridge/request/RequestScene.kt | 2 +- .../bridge/request/RequestViewModel.kt | 46 ++++++------- .../confirm/viewmodels/ConfirmViewModel.kt | 2 + .../clients/cosmos/CosmosFeeCalculator.kt | 2 + .../clients/hyper/HyperCoreBalanceClient.kt | 18 +++++ .../clients/hyper/HyperCoreBroadcatClient.kt | 21 ++++++ .../clients/hyper/HyperCoreGetTokenClient.kt | 19 ++++++ .../hyper/HyperCoreNodeStatusClient.kt | 18 +++++ .../clients/hyper/HyperCoreSignClient.kt | 10 +++ .../hyper/HyperCoreSignerPreloaderClient.kt | 26 ++++++++ .../clients/hyper/HyperCoreStakeClient.kt | 27 ++++++++ .../HyperCoreTransactionsStatusClient.kt | 16 +++++ .../hyper/services/HyperCoreServices.kt | 4 ++ .../operators/walletcore/WCChainTypeProxy.kt | 1 + core | 2 +- .../repositoreis/banners/BannersRepository.kt | 1 + .../repositoreis/bridge/BridgesRepository.kt | 8 +-- .../data/repositoreis/bridge/Namespace.kt | 24 +++---- .../data/repositoreis/di/AssetsModule.kt | 2 + .../data/repositoreis/di/StakeModule.kt | 2 + .../data/repositoreis/di/TokensModule.kt | 2 + .../repositoreis/di/TransactionsModule.kt | 2 + .../data/services/gemapi/di/ClientsModule.kt | 3 + .../presents/details/TransactionDetails.kt | 6 ++ .../presents/chart/components/PeriodsPanel.kt | 1 - .../banner/presents/views/BannersScene.kt | 2 + .../presents/views/AmountScene.kt | 2 + .../viewmodels/AmountViewModel.kt | 8 ++- .../kotlin/com/gemwallet/android/ext/Chain.kt | 4 +- .../com/gemwallet/android/ext/StakeChain.kt | 5 +- .../gemwallet/android/model/Transaction.kt | 6 +- .../com/wallet/core/primitives/AssetPrice.kt | 2 - .../com/wallet/core/primitives/AssetType.kt | 2 + .../com/wallet/core/primitives/Banner.kt | 2 + .../core/primitives/BroadcastOptions.kt | 14 ++++ .../com/wallet/core/primitives/Chain.kt | 2 + .../com/wallet/core/primitives/ChainStake.kt | 2 + .../com/wallet/core/primitives/ChainType.kt | 2 + .../com/wallet/core/primitives/Chart.kt | 25 +++++++ .../com/wallet/core/primitives/Delegation.kt | 2 +- .../kotlin/com/wallet/core/primitives/Name.kt | 2 + .../core/primitives/PerpetualPosition.kt | 45 +++++++++++++ .../core/primitives/PerpetualProvider.kt | 15 +++++ .../kotlin/com/wallet/core/primitives/Scan.kt | 21 ++++++ .../com/wallet/core/primitives/SolanaTypes.kt | 23 +++++++ .../wallet/core/primitives/SwapProvider.kt | 2 - .../com/wallet/core/primitives/Transaction.kt | 4 +- .../primitives/TransactionMetadataTypes.kt | 6 ++ .../wallet/core/primitives/TransactionType.kt | 4 ++ .../wallet/core/primitives/TransactionUtxo.kt | 2 +- .../core/primitives/TransactionWallet.kt | 15 +++++ .../WalletConnectBlockchainMethods.kt | 45 +++++++++++++ .../wallet/core/primitives/WalletConnector.kt | 36 +++++----- .../wallet/core/primitives/swap/Approval.kt | 13 ++++ .../components/list_item/TransactionItem.kt | 24 ++++--- ui/src/main/res/values-ar/strings.xml | 14 +++- ui/src/main/res/values-bn/strings.xml | 14 +++- ui/src/main/res/values-cs/strings.xml | 14 +++- ui/src/main/res/values-da/strings.xml | 14 +++- ui/src/main/res/values-de/strings.xml | 16 ++++- ui/src/main/res/values-es/strings.xml | 14 +++- ui/src/main/res/values-fa/strings.xml | 14 +++- ui/src/main/res/values-fil/strings.xml | 14 +++- ui/src/main/res/values-fr/strings.xml | 14 +++- ui/src/main/res/values-hi/strings.xml | 16 ++++- ui/src/main/res/values-id/strings.xml | 16 ++++- ui/src/main/res/values-it/strings.xml | 14 +++- ui/src/main/res/values-iw/strings.xml | 14 +++- ui/src/main/res/values-ja/strings.xml | 62 +++++++++-------- ui/src/main/res/values-ko/strings.xml | 14 +++- ui/src/main/res/values-ms/strings.xml | 14 +++- ui/src/main/res/values-nl/strings.xml | 14 +++- ui/src/main/res/values-pl/strings.xml | 16 ++++- ui/src/main/res/values-pt-rBR/strings.xml | 14 +++- ui/src/main/res/values-ro/strings.xml | 14 +++- ui/src/main/res/values-ru/strings.xml | 16 ++++- ui/src/main/res/values-sw/strings.xml | 14 +++- ui/src/main/res/values-th/strings.xml | 16 ++++- ui/src/main/res/values-tr/strings.xml | 14 +++- ui/src/main/res/values-uk/strings.xml | 16 ++++- ui/src/main/res/values-ur/strings.xml | 14 +++- ui/src/main/res/values-vi/strings.xml | 16 ++++- ui/src/main/res/values-zh-rCN/strings.xml | 66 +++++++++++-------- ui/src/main/res/values-zh-rTW/strings.xml | 64 ++++++++++-------- ui/src/main/res/values/strings.xml | 14 +++- 86 files changed, 971 insertions(+), 225 deletions(-) create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBalanceClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBroadcatClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreGetTokenClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreNodeStatusClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignerPreloaderClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreStakeClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreTransactionsStatusClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/services/HyperCoreServices.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/BroadcastOptions.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/Chart.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualProvider.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/SolanaTypes.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionWallet.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/WalletConnectBlockchainMethods.kt diff --git a/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt b/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt index 7c3d026c9..dca733293 100644 --- a/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt +++ b/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt @@ -35,6 +35,10 @@ import com.gemwallet.android.blockchain.clients.ethereum.EvmBroadcastClient import com.gemwallet.android.blockchain.clients.ethereum.EvmNodeStatusClient import com.gemwallet.android.blockchain.clients.ethereum.EvmSignClient import com.gemwallet.android.blockchain.clients.ethereum.EvmSignerPreloader +import com.gemwallet.android.blockchain.clients.hyper.HyperCoreBroadcatClient +import com.gemwallet.android.blockchain.clients.hyper.HyperCoreNodeStatusClient +import com.gemwallet.android.blockchain.clients.hyper.HyperCoreSignClient +import com.gemwallet.android.blockchain.clients.hyper.HyperCoreSignerPreloaderClient import com.gemwallet.android.blockchain.clients.near.NearBroadcastClient import com.gemwallet.android.blockchain.clients.near.NearNodeStatusClient import com.gemwallet.android.blockchain.clients.near.NearSignClient @@ -112,6 +116,7 @@ object DataModule { ChainType.Stellar -> StellarBroadcastClient(it, rpcClients.getClient(it)) ChainType.Polkadot -> PolkadotBroadcastClient(it, rpcClients.getClient(it)) ChainType.Cardano -> CardanoBroadcastClient(it, rpcClients.getClient(it)) + ChainType.HyperCore -> HyperCoreBroadcatClient(it) } }, ) @@ -140,6 +145,7 @@ object DataModule { ChainType.Stellar -> StellarSignPreloadClient(it, rpcClients.getClient(it), rpcClients.getClient(it)) ChainType.Polkadot -> PolkadotSignerPreloaderClient(it, rpcClients.getClient(it), rpcClients.getClient(it), rpcClients.getClient(it)) ChainType.Cardano -> CardanoSignerPreloaderClient(it, rpcClients.getClient(it)) + ChainType.HyperCore -> HyperCoreSignerPreloaderClient(it) } } return SignerPreloaderProxy( @@ -178,6 +184,7 @@ object DataModule { ChainType.Stellar -> StellarSignClient(it) ChainType.Polkadot -> PolkadotSignClient(it) ChainType.Cardano -> CardanoSignClient(it) + ChainType.HyperCore -> HyperCoreSignClient(it) } }, ) @@ -204,6 +211,7 @@ object DataModule { ChainType.Stellar -> StellarNodeStatusClient(it, rpcClients.getClient(it)) ChainType.Polkadot -> PolkadotNodeStatusClient(it, rpcClients.getClient(it)) ChainType.Cardano -> CardanoNodeStatusClient(it, rpcClients.getClient(it)) + ChainType.HyperCore -> HyperCoreNodeStatusClient(it) } } ) diff --git a/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestScene.kt b/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestScene.kt index 573174388..74bd404d5 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestScene.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestScene.kt @@ -126,7 +126,7 @@ private fun Render( } item { PropertyItem("Method", request.method) } when (request.method) { - WalletConnectionMethods.solana_sign_transaction.string -> {} + WalletConnectionMethods.SolanaSignTransaction.string -> {} else -> item { Spacer(modifier = Modifier.size(24.dp)) Surface(shadowElevation = 16.dp, color = MaterialTheme.colorScheme.background) { diff --git a/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt b/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt index a794dc4e6..ae8ed3069 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt @@ -68,26 +68,26 @@ class RequestViewModel @Inject constructor( } val params = when (request.request.method) { - WalletConnectionMethods.solana_sign_message.string, - WalletConnectionMethods.eth_sign.string -> { + WalletConnectionMethods.SolanaSignMessage.string, + WalletConnectionMethods.EthSign.string -> { val data = JSONArray(request.request.params).getString(1) String(data.decodeHex()) } - WalletConnectionMethods.eth_sign_typed_data_v4.string, - WalletConnectionMethods.eth_sign_typed_data.string -> { + WalletConnectionMethods.EthSignTypedDataV4.string, + WalletConnectionMethods.EthSignTypedData.string -> { JSONArray(request.request.params).getString(1) } - WalletConnectionMethods.personal_sign.string -> { + WalletConnectionMethods.PersonalSign.string -> { val data = JSONArray(request.request.params).getString(0) String(data.decodeHex()) // TODO: Crashed with IllegalArgumentException } - WalletConnectionMethods.eth_send_transaction.string -> request.request.params - WalletConnectionMethods.solana_sign_and_send_transaction.string, - WalletConnectionMethods.solana_sign_transaction.string -> { + WalletConnectionMethods.EthSendTransaction.string -> request.request.params + WalletConnectionMethods.SolanaSignAndSendTransaction.string, + WalletConnectionMethods.SolanaSignTransaction.string -> { val params = JSONObject(request.request.params).getString("transaction") params } - WalletConnectionMethods.wallet_switch_ethereum_chain.string -> { + WalletConnectionMethods.WalletSwitchEthereumChain.string -> { WalletKit.respondSessionRequest( params = Wallet.Params.SessionRequestResponse( sessionTopic = request.topic, @@ -113,7 +113,7 @@ class RequestViewModel @Inject constructor( fun onSent(hash: String) { val sessionRequest = state.value.sessionRequest ?: return val data = when (state.value.sessionRequest?.request?.method) { - WalletConnectionMethods.solana_sign_transaction.string -> jsonEncoder.encodeToString(WCSolanaSignMessageResult(signature = hash)) + WalletConnectionMethods.SolanaSignTransaction.string -> jsonEncoder.encodeToString(WCSolanaSignMessageResult(signature = hash)) else -> hash } @@ -142,19 +142,19 @@ class RequestViewModel @Inject constructor( val sign = try { when (method) { - WalletConnectionMethods.eth_sign, - WalletConnectionMethods.personal_sign -> { + WalletConnectionMethods.EthSign, + WalletConnectionMethods.PersonalSign -> { val data = state.value.params.toByteArray() val messagePrefix = "\u0019Ethereum Signed Message:\n${data.size}" val prefix = messagePrefix.toByteArray() val param = Hash.keccak256(prefix + data) signClient.signMessage(chain, param, privateKey).toHexString() } - WalletConnectionMethods.eth_sign_typed_data, - WalletConnectionMethods.eth_sign_typed_data_v4 -> { + WalletConnectionMethods.EthSignTypedData, + WalletConnectionMethods.EthSignTypedDataV4 -> { signClient.signTypedMessage(chain, state.value.params.toByteArray(), privateKey).toHexString() } - WalletConnectionMethods.solana_sign_message -> { + WalletConnectionMethods.SolanaSignMessage -> { val param = state.value.params.toByteArray() signClient.signMessage(chain, param, privateKey).toHexString() } @@ -224,11 +224,11 @@ private data class RequestViewModelState( } val account = wallet?.getAccount(chain!!)!! return when (sessionRequest.request.method) { - WalletConnectionMethods.eth_sign.string, - WalletConnectionMethods.personal_sign.string, - WalletConnectionMethods.eth_sign_typed_data_v4.string, - WalletConnectionMethods.solana_sign_message.string, - WalletConnectionMethods.eth_sign_typed_data.string -> RequestSceneState.SignMessage( + WalletConnectionMethods.EthSign.string, + WalletConnectionMethods.PersonalSign.string, + WalletConnectionMethods.EthSignTypedDataV4.string, + WalletConnectionMethods.SolanaSignMessage.string, + WalletConnectionMethods.EthSignTypedData.string -> RequestSceneState.SignMessage( account = account, walletName = wallet.name, chain = chain, @@ -242,7 +242,7 @@ private data class RequestViewModelState( ), params = params, ) - WalletConnectionMethods.eth_send_transaction.string -> { + WalletConnectionMethods.EthSendTransaction.string -> { try { val jObj = JSONArray(params).getJSONObject(0) val to = jObj.getString("to") @@ -258,7 +258,7 @@ private data class RequestViewModelState( RequestSceneState.Error("Argument error: ${err.message}") } } - WalletConnectionMethods.solana_sign_transaction.string -> RequestSceneState.SignGeneric( + WalletConnectionMethods.SolanaSignTransaction.string -> RequestSceneState.SignGeneric( ConfirmParams.TransferParams.Generic( asset = chain.asset(), from = account, @@ -266,7 +266,7 @@ private data class RequestViewModelState( inputType = ConfirmParams.TransferParams.InputType.Signature ) ) - WalletConnectionMethods.solana_sign_and_send_transaction.string -> RequestSceneState.SignGeneric( + WalletConnectionMethods.SolanaSignAndSendTransaction.string -> RequestSceneState.SignGeneric( ConfirmParams.TransferParams.Generic( asset = chain.asset(), from = account, diff --git a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt index d6ef1a14c..6dbc36166 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt @@ -523,6 +523,8 @@ class ConfirmViewModel @Inject constructor( TransactionType.StakeWithdraw, TransactionType.TransferNFT -> amount TransactionType.SmartContractCall -> TODO() + TransactionType.PerpetualOpenPosition -> TODO() + TransactionType.PerpetualClosePosition -> TODO() } if (assetBalance < totalAmount) { diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosFeeCalculator.kt index a544a6a93..6f9d15414 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosFeeCalculator.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosFeeCalculator.kt @@ -49,6 +49,8 @@ class CosmosFeeCalculator( TransactionType.AssetActivation, TransactionType.TransferNFT, TransactionType.SmartContractCall, + TransactionType.PerpetualOpenPosition, + TransactionType.PerpetualClosePosition, TransactionType.TokenApproval -> throw IllegalArgumentException("Chain not available: no limit fee") } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBalanceClient.kt new file mode 100644 index 000000000..92c6c53f1 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBalanceClient.kt @@ -0,0 +1,18 @@ +package com.gemwallet.android.blockchain.clients.hyper + +import com.gemwallet.android.blockchain.clients.BalanceClient +import com.gemwallet.android.model.AssetBalance +import com.wallet.core.primitives.Chain + +class HyperCoreBalanceClient( + private val chain: Chain, +) : BalanceClient { + override suspend fun getNativeBalance( + chain: Chain, + address: String + ): AssetBalance? { + TODO("Not yet implemented") + } + + override fun supported(chain: Chain): Boolean = this.chain == chain +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBroadcatClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBroadcatClient.kt new file mode 100644 index 000000000..8a7aa1586 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBroadcatClient.kt @@ -0,0 +1,21 @@ +package com.gemwallet.android.blockchain.clients.hyper + +import com.gemwallet.android.blockchain.clients.BroadcastClient +import com.gemwallet.android.blockchain.clients.BroadcastClientProxy +import com.wallet.core.primitives.Account +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.TransactionType + +class HyperCoreBroadcatClient( + private val chain: Chain, +) : BroadcastClient { + override suspend fun send( + account: Account, + signedMessage: ByteArray, + type: TransactionType + ): String { + TODO("Not yet implemented") + } + + override fun supported(chain: Chain): Boolean = this.chain == chain +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreGetTokenClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreGetTokenClient.kt new file mode 100644 index 000000000..74845bcf3 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreGetTokenClient.kt @@ -0,0 +1,19 @@ +package com.gemwallet.android.blockchain.clients.hyper + +import com.gemwallet.android.blockchain.clients.GetTokenClient +import com.wallet.core.primitives.Asset +import com.wallet.core.primitives.Chain + +class HyperCoreGetTokenClient( + private val chain: Chain, +) : GetTokenClient { + override suspend fun getTokenData(tokenId: String): Asset? { + TODO("Not yet implemented") + } + + override suspend fun isTokenQuery(query: String): Boolean { + TODO("Not yet implemented") + } + + override fun supported(chain: Chain): Boolean = this.chain == chain +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreNodeStatusClient.kt new file mode 100644 index 000000000..9f4d7fb5a --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreNodeStatusClient.kt @@ -0,0 +1,18 @@ +package com.gemwallet.android.blockchain.clients.hyper + +import com.gemwallet.android.blockchain.clients.NodeStatusClient +import com.gemwallet.android.model.NodeStatus +import com.wallet.core.primitives.Chain + +class HyperCoreNodeStatusClient( + val chain: Chain, +) : NodeStatusClient { + override suspend fun getNodeStatus( + chain: Chain, + url: String + ): NodeStatus? { + TODO("Not yet implemented") + } + + override fun supported(chain: Chain): Boolean = this.chain == chain +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignClient.kt new file mode 100644 index 000000000..611d174e0 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignClient.kt @@ -0,0 +1,10 @@ +package com.gemwallet.android.blockchain.clients.hyper + +import com.gemwallet.android.blockchain.clients.SignClient +import com.wallet.core.primitives.Chain + +class HyperCoreSignClient( + val chain: Chain, +) : SignClient { + override fun supported(chain: Chain): Boolean = this.chain == chain +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignerPreloaderClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignerPreloaderClient.kt new file mode 100644 index 000000000..a5f0909cb --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignerPreloaderClient.kt @@ -0,0 +1,26 @@ +package com.gemwallet.android.blockchain.clients.hyper + +import com.gemwallet.android.blockchain.clients.NativeTransferPreloader +import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader +import com.gemwallet.android.blockchain.clients.TokenTransferPreloader +import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.SignerParams +import com.wallet.core.primitives.Chain + +class HyperCoreSignerPreloaderClient( + private val chain: Chain, +) : NativeTransferPreloader, TokenTransferPreloader, StakeTransactionPreloader { + override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { + TODO("Not yet implemented") + } + + override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { + TODO("Not yet implemented") + } + + override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams { + TODO("Not yet implemented") + } + + override fun supported(chain: Chain): Boolean = this.chain == chain +} diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreStakeClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreStakeClient.kt new file mode 100644 index 000000000..6de888b38 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreStakeClient.kt @@ -0,0 +1,27 @@ +package com.gemwallet.android.blockchain.clients.hyper + +import com.gemwallet.android.blockchain.clients.StakeClient +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.DelegationBase +import com.wallet.core.primitives.DelegationValidator + +class HyperCoreStakeClient( + private val chain: Chain +) : StakeClient { + override suspend fun getValidators( + chain: Chain, + apr: Double + ): List { + TODO("Not yet implemented") + } + + override suspend fun getStakeDelegations( + chain: Chain, + address: String, + apr: Double + ): List { + TODO("Not yet implemented") + } + + override fun supported(chain: Chain): Boolean = this.chain == chain +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreTransactionsStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreTransactionsStatusClient.kt new file mode 100644 index 000000000..fc6b8b2c3 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreTransactionsStatusClient.kt @@ -0,0 +1,16 @@ +package com.gemwallet.android.blockchain.clients.hyper + +import com.gemwallet.android.blockchain.clients.TransactionStateRequest +import com.gemwallet.android.blockchain.clients.TransactionStatusClient +import com.gemwallet.android.model.TransactionChanges +import com.wallet.core.primitives.Chain + +class HyperCoreTransactionsStatusClient( + private val chain: Chain, +) : TransactionStatusClient { + override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { + TODO("Not yet implemented") + } + + override fun supported(chain: Chain): Boolean = this.chain == chain +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/services/HyperCoreServices.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/services/HyperCoreServices.kt new file mode 100644 index 000000000..ba62bb520 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/services/HyperCoreServices.kt @@ -0,0 +1,4 @@ +package com.gemwallet.android.blockchain.clients.hyper.services + +interface HyperCoreServices { +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/operators/walletcore/WCChainTypeProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/operators/walletcore/WCChainTypeProxy.kt index ce149cac8..53102e170 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/operators/walletcore/WCChainTypeProxy.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/operators/walletcore/WCChainTypeProxy.kt @@ -52,5 +52,6 @@ class WCChainTypeProxy : ChainTypeProxy { Chain.Stellar -> CoinType.STELLAR Chain.Polkadot -> CoinType.POLKADOT Chain.Cardano -> CoinType.CARDANO + Chain.HyperCore -> CoinType.ETHEREUM // TODO: HyperCore } } \ No newline at end of file diff --git a/core b/core index 954c53d40..cc13a4ee7 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 954c53d40dfd57f5ee311413fbd630313e2cb577 +Subproject commit cc13a4ee73a70efb649e2b37f4a91b0f896f79aa diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/banners/BannersRepository.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/banners/BannersRepository.kt index e458333d8..1b9b67b22 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/banners/BannersRepository.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/banners/BannersRepository.kt @@ -81,6 +81,7 @@ class BannersRepository( BannerEvent.EnableNotifications, BannerEvent.AccountBlockedMultiSignature -> BannerState.Active BannerEvent.ActivateAsset -> BannerState.AlwaysActive + BannerEvent.SuspiciousAsset -> throw IllegalArgumentException() // TODO: HyperCore }, event = event, ) diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/BridgesRepository.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/BridgesRepository.kt index d941d8bd7..d50594cc8 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/BridgesRepository.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/BridgesRepository.kt @@ -223,10 +223,10 @@ class BridgesRepository( chains = chain.value.map { "${it.namespace}:${it.reference}" }, methods = chain.value.map { it.methods }.toSet().flatten().toList(), events = if (chain.key == Chain.Solana.string) emptyList() else listOf( - WalletConnectionEvents.connect.string, - WalletConnectionEvents.disconnect.string, - WalletConnectionEvents.chain_changed.string, - WalletConnectionEvents.accounts_changed.string + WalletConnectionEvents.Connect.string, + WalletConnectionEvents.Disconnect.string, + WalletConnectionEvents.ChainChanged.string, + WalletConnectionEvents.AccountsChanged.string ), accounts = chain.value.map { "${it.namespace}:${it.reference}:${it.address}" }, ) diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/Namespace.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/Namespace.kt index d70996719..478494e6e 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/Namespace.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/Namespace.kt @@ -10,23 +10,23 @@ enum class ChainNamespace(val string: String, val methods: List StellarBalanceClient(it, rpcClients.getClient(it)) ChainType.Polkadot -> PolkadotBalancesClient(it, rpcClients.getClient(it)) ChainType.Cardano -> CardanoBalanceClient(it, rpcClients.getClient(it)) + ChainType.HyperCore -> HyperCoreBalanceClient(it) } } ) diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt index a728c224a..651844ed8 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt @@ -3,6 +3,7 @@ package com.gemwallet.android.data.repositoreis.di import com.gemwallet.android.blockchain.RpcClientAdapter import com.gemwallet.android.blockchain.clients.cosmos.CosmosStakeClient import com.gemwallet.android.blockchain.clients.ethereum.SmartchainStakeClient +import com.gemwallet.android.blockchain.clients.hyper.HyperCoreStakeClient import com.gemwallet.android.blockchain.clients.solana.SolanaStakeClient import com.gemwallet.android.blockchain.clients.sui.SuiStakeClient import com.gemwallet.android.blockchain.clients.tron.TronStakeClient @@ -49,6 +50,7 @@ object StakeModule { } ChainType.Sui -> SuiStakeClient(it, rpcClients.getClient(it)) ChainType.Tron -> TronStakeClient(it, rpcClients.getClient(it), rpcClients.getClient(it)) + ChainType.HyperCore -> HyperCoreStakeClient(it) ChainType.Bitcoin, ChainType.Ton, ChainType.Tron, diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt index 31391fd49..21052757a 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt @@ -3,6 +3,7 @@ package com.gemwallet.android.data.repositoreis.di import com.gemwallet.android.blockchain.RpcClientAdapter import com.gemwallet.android.blockchain.clients.aptos.AptosGetTokenClient import com.gemwallet.android.blockchain.clients.ethereum.EvmGetTokenClient +import com.gemwallet.android.blockchain.clients.hyper.HyperCoreGetTokenClient import com.gemwallet.android.blockchain.clients.solana.SolanaTokenClient import com.gemwallet.android.blockchain.clients.sui.SuiGetTokenClient import com.gemwallet.android.blockchain.clients.ton.TonGetTokenClient @@ -51,6 +52,7 @@ object TokensModule { ChainType.Stellar, ChainType.Polkadot, ChainType.Cardano, + ChainType.HyperCore -> HyperCoreGetTokenClient(chain) ChainType.Near -> null } } diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt index 190ad9f0b..13e014a35 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt @@ -7,6 +7,7 @@ import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinTransactionStatus import com.gemwallet.android.blockchain.clients.cardano.CardanoTransactionStatusClient import com.gemwallet.android.blockchain.clients.cosmos.CosmosTransactionStatusClient import com.gemwallet.android.blockchain.clients.ethereum.EvmTransactionStatusClient +import com.gemwallet.android.blockchain.clients.hyper.HyperCoreTransactionsStatusClient import com.gemwallet.android.blockchain.clients.near.NearTransactionStatusClient import com.gemwallet.android.blockchain.clients.polkadot.PolkadotTransactionStatusClient import com.gemwallet.android.blockchain.clients.solana.SolanaTransactionStatusClient @@ -69,6 +70,7 @@ object TransactionsModule { ChainType.Stellar -> StellarTransactionStatusClient(it, rpcClients.getClient(it)) ChainType.Polkadot -> PolkadotTransactionStatusClient(it, rpcClients.getClient(it)) ChainType.Cardano -> CardanoTransactionStatusClient(it, rpcClients.getClient(it)) + ChainType.HyperCore -> HyperCoreTransactionsStatusClient(it) } }, ) diff --git a/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt b/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt index 97a8e9cc2..876742c03 100644 --- a/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt +++ b/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt @@ -9,6 +9,7 @@ import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinRpcClien import com.gemwallet.android.blockchain.clients.cardano.services.CardanoServices import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosRpcClient import com.gemwallet.android.blockchain.clients.ethereum.services.EvmRpcClient +import com.gemwallet.android.blockchain.clients.hyper.services.HyperCoreServices import com.gemwallet.android.blockchain.clients.near.NearRpcClient import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotServices import com.gemwallet.android.blockchain.clients.solana.services.SolanaRpcClient @@ -46,6 +47,7 @@ import retrofit2.converter.kotlinx.serialization.asConverterFactory import java.util.concurrent.TimeUnit import javax.inject.Qualifier import javax.inject.Singleton +import kotlin.collections.map @Qualifier annotation class NodeHttpClient @@ -159,6 +161,7 @@ object ClientsModule { ChainType.Stellar -> buildClient(url, StellarService::class.java, converter, httpClient) ChainType.Polkadot -> buildClient(url, PolkadotServices::class.java, converter, httpClient) ChainType.Cardano -> buildClient(url, CardanoServices::class.java, converter, httpClient) + ChainType.HyperCore -> buildClient(url, HyperCoreServices::class.java, converter, httpClient) } adapter.add(it, rpc) } diff --git a/features/activities/presents/src/main/kotlin/com/gemwallet/android/features/activities/presents/details/TransactionDetails.kt b/features/activities/presents/src/main/kotlin/com/gemwallet/android/features/activities/presents/details/TransactionDetails.kt index 6aa9f9bb7..a3a7f8f59 100644 --- a/features/activities/presents/src/main/kotlin/com/gemwallet/android/features/activities/presents/details/TransactionDetails.kt +++ b/features/activities/presents/src/main/kotlin/com/gemwallet/android/features/activities/presents/details/TransactionDetails.kt @@ -113,6 +113,8 @@ private fun LazyListScope.transactionItemHead(model: TxDetailsScreenModel) { TransactionType.AssetActivation, TransactionType.TokenApproval -> model.asset.symbol TransactionType.SmartContractCall -> TODO() + TransactionType.PerpetualOpenPosition -> TODO() + TransactionType.PerpetualClosePosition -> TODO() }, equivalent = when (model.type) { TransactionType.StakeDelegate, @@ -126,6 +128,8 @@ private fun LazyListScope.transactionItemHead(model: TxDetailsScreenModel) { TransactionType.TransferNFT, TransactionType.TokenApproval -> null TransactionType.SmartContractCall -> TODO() + TransactionType.PerpetualOpenPosition -> TODO() + TransactionType.PerpetualClosePosition -> TODO() }, ) } @@ -181,6 +185,8 @@ private fun LazyListScope.transactionRecipientItem(model: TxDetailsScreenModel) TransactionType.StakeRedelegate, TransactionType.AssetActivation, TransactionType.SmartContractCall, + TransactionType.PerpetualOpenPosition, + TransactionType.PerpetualClosePosition, TransactionType.StakeWithdraw -> return TransactionType.Transfer, diff --git a/features/asset/presents/src/main/kotlin/com/gemwallet/features/asset/presents/chart/components/PeriodsPanel.kt b/features/asset/presents/src/main/kotlin/com/gemwallet/features/asset/presents/chart/components/PeriodsPanel.kt index 2442b4410..0632bddf3 100644 --- a/features/asset/presents/src/main/kotlin/com/gemwallet/features/asset/presents/chart/components/PeriodsPanel.kt +++ b/features/asset/presents/src/main/kotlin/com/gemwallet/features/asset/presents/chart/components/PeriodsPanel.kt @@ -77,7 +77,6 @@ private fun ChartPeriod.getLabel(): String? { ChartPeriod.Month -> R.string.charts_month ChartPeriod.Year -> R.string.charts_year ChartPeriod.All -> R.string.charts_all - ChartPeriod.Quarter -> return null } return stringResource(id = strId) } \ No newline at end of file diff --git a/features/banner/presents/src/main/kotlin/com/gemwallet/features/banner/presents/views/BannersScene.kt b/features/banner/presents/src/main/kotlin/com/gemwallet/features/banner/presents/views/BannersScene.kt index 462df6219..4eae47c7d 100644 --- a/features/banner/presents/src/main/kotlin/com/gemwallet/features/banner/presents/views/BannersScene.kt +++ b/features/banner/presents/src/main/kotlin/com/gemwallet/features/banner/presents/views/BannersScene.kt @@ -83,6 +83,8 @@ fun BannersScene( stringResource(R.string.transfer_activate_asset_title), stringResource(R.string.banner_activate_asset_description, asset?.name ?: "", asset?.id?.chain?.asset()?.name ?: ""), ) + + BannerEvent.SuspiciousAsset -> TODO() } BannerText( title = title, diff --git a/features/transfer_amount/presents/src/main/kotlin/com/gemwallet/features/transfer_amount/presents/views/AmountScene.kt b/features/transfer_amount/presents/src/main/kotlin/com/gemwallet/features/transfer_amount/presents/views/AmountScene.kt index 0b741dc2f..263120215 100644 --- a/features/transfer_amount/presents/src/main/kotlin/com/gemwallet/features/transfer_amount/presents/views/AmountScene.kt +++ b/features/transfer_amount/presents/src/main/kotlin/com/gemwallet/features/transfer_amount/presents/views/AmountScene.kt @@ -155,4 +155,6 @@ private fun getTitle(txType: TransactionType) = when (txType) { TransactionType.StakeRewards -> stringResource(id = R.string.transfer_rewards_title) TransactionType.AssetActivation -> stringResource(id = R.string.transfer_activate_asset_title) TransactionType.SmartContractCall -> stringResource(id = R.string.transfer_amount_title) + TransactionType.PerpetualOpenPosition -> stringResource(R.string.perpetual_position) + TransactionType.PerpetualClosePosition -> stringResource(R.string.perpetual_close_position) } \ No newline at end of file diff --git a/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt b/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt index 5e933b914..726cd52d7 100644 --- a/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt +++ b/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt @@ -133,6 +133,8 @@ class AmountViewModel @Inject constructor( TransactionType.TransferNFT, TransactionType.SmartContractCall, TransactionType.TokenApproval, + TransactionType.PerpetualOpenPosition -> throw IllegalArgumentException() // TODO: HyperCore + TransactionType.PerpetualClosePosition -> throw IllegalArgumentException() // TODO: HyperCore null -> Crypto(BigInteger.ZERO) } assetInfo.asset.format(value, 8) @@ -260,7 +262,9 @@ class AmountViewModel @Inject constructor( TransactionType.Swap, TransactionType.TransferNFT, TransactionType.SmartContractCall, - TransactionType.TokenApproval -> throw IllegalArgumentException() + TransactionType.TokenApproval, + TransactionType.PerpetualOpenPosition, + TransactionType.PerpetualClosePosition -> throw IllegalArgumentException() } onConfirm(nextParams) } @@ -335,6 +339,8 @@ class AmountViewModel @Inject constructor( TransactionType.StakeWithdraw -> Crypto(BigInteger(delegation?.base?.balance ?: "0")) TransactionType.AssetActivation, TransactionType.TransferNFT, + TransactionType.PerpetualOpenPosition, + TransactionType.PerpetualClosePosition, TransactionType.SmartContractCall -> throw IllegalArgumentException() } if (amount.atomicValue > availableAmount.atomicValue) { diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/ext/Chain.kt b/gemcore/src/main/kotlin/com/gemwallet/android/ext/Chain.kt index b388631fc..991835ad9 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/ext/Chain.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/ext/Chain.kt @@ -47,6 +47,7 @@ fun Chain.assetType(): AssetType? { Chain.Monad, Chain.World -> AssetType.ERC20 + Chain.HyperCore, Chain.Cosmos, Chain.Osmosis, Chain.Celestia, @@ -103,7 +104,7 @@ fun Chain.Companion.findByString(value: String): Chain? { return Chain.entries.firstOrNull{ it.string == value} } -fun Chain.Companion.exclude() = setOf(Chain.Celo) +fun Chain.Companion.exclude() = setOf(Chain.Celo, Chain.HyperCore) fun Chain.Companion.available() = (Chain.entries.toSet() - exclude()) @@ -118,6 +119,7 @@ fun List.filter(query: String): List { fun Chain.toChainType(): ChainType { return when (this) { + Chain.HyperCore -> ChainType.HyperCore Chain.Solana -> ChainType.Solana Chain.Ton -> ChainType.Ton Chain.Tron -> ChainType.Tron diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/ext/StakeChain.kt b/gemcore/src/main/kotlin/com/gemwallet/android/ext/StakeChain.kt index cf9d436b3..6cb448d6b 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/ext/StakeChain.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/ext/StakeChain.kt @@ -17,7 +17,8 @@ fun StakeChain.redelegated(): Boolean = when (this) { StakeChain.Solana, StakeChain.Sui, StakeChain.SmartChain, - StakeChain.Tron -> false + StakeChain.Tron, + StakeChain.HyperCore -> false } fun StakeChain.withdraw(): Boolean = when (this) { @@ -28,6 +29,7 @@ fun StakeChain.withdraw(): Boolean = when (this) { StakeChain.Osmosis, StakeChain.SmartChain, StakeChain.Tron, + StakeChain.HyperCore, StakeChain.Sui-> false StakeChain.Solana -> true } @@ -41,5 +43,6 @@ fun StakeChain.claimed(): Boolean = when (this) { StakeChain.Solana, StakeChain.Sui, StakeChain.SmartChain, + StakeChain.HyperCore, StakeChain.Tron -> false } \ No newline at end of file diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/model/Transaction.kt b/gemcore/src/main/kotlin/com/gemwallet/android/model/Transaction.kt index 50b8730b2..2ff005dc5 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/model/Transaction.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/model/Transaction.kt @@ -3,9 +3,9 @@ package com.gemwallet.android.model import com.gemwallet.android.serializer.DateSerializer import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.TransactionDirection -import com.wallet.core.primitives.TransactionInput import com.wallet.core.primitives.TransactionState import com.wallet.core.primitives.TransactionType +import com.wallet.core.primitives.TransactionUtxoInput import kotlinx.serialization.Serializable @Serializable @@ -25,8 +25,8 @@ data class Transaction ( val value: String, val memo: String? = null, val direction: TransactionDirection, - val utxoInputs: List, - val utxoOutputs: List, + val utxoInputs: List, + val utxoOutputs: List, val metadata: String? = null, @Serializable(with = DateSerializer::class) val createdAt: Long, diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetPrice.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetPrice.kt index 91b22b229..9715388db 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetPrice.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetPrice.kt @@ -63,8 +63,6 @@ enum class ChartPeriod(val string: String) { Week("week"), @SerialName("month") Month("month"), - @SerialName("quarter") - Quarter("quarter"), @SerialName("year") Year("year"), @SerialName("all") diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetType.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetType.kt index db5364d0f..6fc4d3cf2 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetType.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetType.kt @@ -37,5 +37,7 @@ enum class AssetType(val string: String) { SYNTH("SYNTH"), @SerialName("ASA") ASA("ASA"), + @SerialName("PERPETUAL") + PERPETUAL("PERPETUAL"), } diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/Banner.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/Banner.kt index 8e360a4d5..7e2e0b1fd 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/Banner.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/Banner.kt @@ -19,6 +19,8 @@ enum class BannerEvent(val string: String) { AccountBlockedMultiSignature("accountBlockedMultiSignature"), @SerialName("activateAsset") ActivateAsset("activateAsset"), + @SerialName("suspiciousAsset") + SuspiciousAsset("suspiciousAsset"), } @Serializable diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/BroadcastOptions.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/BroadcastOptions.kt new file mode 100644 index 000000000..e3463a928 --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/BroadcastOptions.kt @@ -0,0 +1,14 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +data class BroadcastOptions ( + val skipPreflight: Boolean +) + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/Chain.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/Chain.kt index 9148e7ba1..1416ae3e3 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/Chain.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/Chain.kt @@ -99,6 +99,8 @@ enum class Chain(val string: String) { Unichain("unichain"), @SerialName("hyperliquid") Hyperliquid("hyperliquid"), + @SerialName("hypercore") + HyperCore("hypercore"), @SerialName("monad") Monad("monad"), } diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/ChainStake.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/ChainStake.kt index 4f06438d7..8a9169e44 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/ChainStake.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/ChainStake.kt @@ -27,5 +27,7 @@ enum class StakeChain(val string: String) { SmartChain("smartchain"), @SerialName("tron") Tron("tron"), + @SerialName("hypercore") + HyperCore("hypercore"), } diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/ChainType.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/ChainType.kt index eee96900f..149f7a6db 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/ChainType.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/ChainType.kt @@ -37,5 +37,7 @@ enum class ChainType(val string: String) { Polkadot("polkadot"), @SerialName("cardano") Cardano("cardano"), + @SerialName("hypercore") + HyperCore("hypercore"), } diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/Chart.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/Chart.kt new file mode 100644 index 000000000..65ee782e3 --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/Chart.kt @@ -0,0 +1,25 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +data class ChartCandleStick ( + val date: SerializedDate, + val open: Double, + val high: Double, + val low: Double, + val close: Double, + val volume: Double +) + +@Serializable +data class ChartDateValue ( + val date: SerializedDate, + val value: Double +) + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/Delegation.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/Delegation.kt index a1db1b533..27960c3f3 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/Delegation.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/Delegation.kt @@ -32,7 +32,7 @@ data class DelegationBase ( val balance: String, val shares: String, val rewards: String, - val completionDate: Long? = null, + val completionDate: SerializedDate? = null, val delegationId: String, val validatorId: String ) diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/Name.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/Name.kt index 884041681..795683343 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/Name.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/Name.kt @@ -47,5 +47,7 @@ enum class NameProvider(val string: String) { Basenames("basenames"), @SerialName("hyperliquid") Hyperliquid("hyperliquid"), + @SerialName("alldomains") + AllDomains("alldomains"), } diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt new file mode 100644 index 000000000..380dbed32 --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt @@ -0,0 +1,45 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +enum class PerpetualMarginType(val string: String) { + @SerialName("cross") + Cross("cross"), + @SerialName("isolated") + Isolated("isolated"), +} + +@Serializable +enum class PerpetualDirection + +@Serializable +data class PriceTarget ( + val price: Double? = null, + val percentage: Double? = null +) + +@Serializable +data class PerpetualPosition ( + val id: String, + val perpetualId: String, + val assetId: AssetId, + val size: Double, + val sizeValue: Double, + val leverage: UByte, + val entryPrice: Double? = null, + val liquidationPrice: Double? = null, + val marginType: PerpetualMarginType, + val direction: PerpetualDirection, + val marginAmount: Double, + val takeProfit: PriceTarget? = null, + val stopLoss: PriceTarget? = null, + val pnl: Double, + val funding: Float? = null +) + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualProvider.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualProvider.kt new file mode 100644 index 000000000..c71a9fcf6 --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualProvider.kt @@ -0,0 +1,15 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +enum class PerpetualProvider(val string: String) { + @SerialName("hypercore") + Hypercore("hypercore"), +} + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/Scan.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/Scan.kt index f8ffa3c4d..0be6ab12c 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/Scan.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/Scan.kt @@ -7,6 +7,27 @@ package com.wallet.core.primitives import kotlinx.serialization.Serializable import kotlinx.serialization.SerialName +@Serializable +enum class AddressType(val string: String) { + @SerialName("address") + Address("address"), + @SerialName("contract") + Contract("contract"), + @SerialName("validator") + Validator("validator"), +} + +@Serializable +data class ScanAddress ( + val chain: Chain, + val address: String, + val name: String? = null, + val type: AddressType? = null, + val isMalicious: Boolean? = null, + val isMemoRequired: Boolean? = null, + val isVerified: Boolean? = null +) + @Serializable data class ScanAddressTarget ( val chain: Chain, diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/SolanaTypes.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/SolanaTypes.kt new file mode 100644 index 000000000..760fe2eac --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/SolanaTypes.kt @@ -0,0 +1,23 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +data class SolanaAccountMeta ( + val pubkey: String, + val isSigner: Boolean, + val isWritable: Boolean +) + +@Serializable +data class SolanaInstruction ( + val programId: String, + val accounts: List, + val data: String +) + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/SwapProvider.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/SwapProvider.kt index 773cd04d3..b7cd2edea 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/SwapProvider.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/SwapProvider.kt @@ -21,8 +21,6 @@ enum class SwapProvider(val string: String) { PancakeswapAptosV2("pancakeswap_aptos_v2"), @SerialName("thorchain") Thorchain("thorchain"), - @SerialName("orca") - Orca("orca"), @SerialName("jupiter") Jupiter("jupiter"), @SerialName("across") diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/Transaction.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/Transaction.kt index 0da44f0d5..71f82ac90 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/Transaction.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/Transaction.kt @@ -24,8 +24,8 @@ data class Transaction ( val value: String, val memo: String? = null, val direction: TransactionDirection, - val utxoInputs: List, - val utxoOutputs: List, + val utxoInputs: List, + val utxoOutputs: List, val metadata: String?? = null, val createdAt: SerializedDate ) diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionMetadataTypes.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionMetadataTypes.kt index 162d45a23..9499b5fc2 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionMetadataTypes.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionMetadataTypes.kt @@ -13,6 +13,12 @@ data class TransactionNFTTransferMetadata ( val name: String? = null ) +@Serializable +data class TransactionPerpetualMetadata ( + val pnl: Double, + val price: Double +) + @Serializable data class TransactionSwapMetadata ( val fromAsset: AssetId, diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionType.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionType.kt index 607a298fb..6a002002b 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionType.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionType.kt @@ -31,5 +31,9 @@ enum class TransactionType(val string: String) { AssetActivation("assetActivation"), @SerialName("smartContractCall") SmartContractCall("smartContractCall"), + @SerialName("perpetualOpenPosition") + PerpetualOpenPosition("perpetualOpenPosition"), + @SerialName("perpetualClosePosition") + PerpetualClosePosition("perpetualClosePosition"), } diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionUtxo.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionUtxo.kt index 2ecbe2439..d93ebb2f0 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionUtxo.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionUtxo.kt @@ -8,7 +8,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.SerialName @Serializable -data class TransactionInput ( +data class TransactionUtxoInput ( val address: String, val value: String ) diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionWallet.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionWallet.kt new file mode 100644 index 000000000..494040467 --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionWallet.kt @@ -0,0 +1,15 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +data class TransactionWallet ( + val transaction: Transaction, + val wallet: Wallet +) + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/WalletConnectBlockchainMethods.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/WalletConnectBlockchainMethods.kt new file mode 100644 index 000000000..ccde447f7 --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/WalletConnectBlockchainMethods.kt @@ -0,0 +1,45 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +enum class WalletConnectEthereumMethods(val string: String) { + @SerialName("chainId") + chain_id("chainId"), + @SerialName("sign") + sign("sign"), + @SerialName("personalSign") + personal_sign("personalSign"), + @SerialName("signTypedData") + sign_typed_data("signTypedData"), + @SerialName("signTypedDataV4") + sign_typed_data_v4("signTypedDataV4"), + @SerialName("signTransaction") + sign_transaction("signTransaction"), + @SerialName("sendTransaction") + send_transaction("sendTransaction"), + @SerialName("sendRawTransaction") + send_raw_transaction("sendRawTransaction"), + @SerialName("switchChain") + switch_chain("switchChain"), + @SerialName("addChain") + add_chain("addChain"), +} + +@Serializable +enum class WalletConnectSolanaMethods(val string: String) { + @SerialName("signMessage") + sign_message("signMessage"), + @SerialName("signTransaction") + sign_transaction("signTransaction"), + @SerialName("signAndSendTransaction") + sign_and_send_transaction("signAndSendTransaction"), + @SerialName("signAllTransactions") + sign_all_transactions("signAllTransactions"), +} + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/WalletConnector.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/WalletConnector.kt index 899065a2c..e96802040 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/WalletConnector.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/WalletConnector.kt @@ -54,44 +54,44 @@ data class WalletConnectionSessionProposal ( @Serializable enum class WalletConnectionEvents(val string: String) { @SerialName("connect") - connect("connect"), + Connect("connect"), @SerialName("disconnect") - disconnect("disconnect"), + Disconnect("disconnect"), @SerialName("accountsChanged") - accounts_changed("accountsChanged"), + AccountsChanged("accountsChanged"), @SerialName("chainChanged") - chain_changed("chainChanged"), + ChainChanged("chainChanged"), } @Serializable enum class WalletConnectionMethods(val string: String) { @SerialName("eth_chainId") - eth_chain_id("eth_chainId"), + EthChainId("eth_chainId"), @SerialName("eth_sign") - eth_sign("eth_sign"), + EthSign("eth_sign"), @SerialName("personal_sign") - personal_sign("personal_sign"), + PersonalSign("personal_sign"), @SerialName("eth_signTypedData") - eth_sign_typed_data("eth_signTypedData"), + EthSignTypedData("eth_signTypedData"), @SerialName("eth_signTypedData_v4") - eth_sign_typed_data_v4("eth_signTypedData_v4"), + EthSignTypedDataV4("eth_signTypedData_v4"), @SerialName("eth_signTransaction") - eth_sign_transaction("eth_signTransaction"), + EthSignTransaction("eth_signTransaction"), @SerialName("eth_sendTransaction") - eth_send_transaction("eth_sendTransaction"), + EthSendTransaction("eth_sendTransaction"), @SerialName("eth_sendRawTransaction") - eth_send_raw_transaction("eth_sendRawTransaction"), + EthSendRawTransaction("eth_sendRawTransaction"), @SerialName("wallet_switchEthereumChain") - wallet_switch_ethereum_chain("wallet_switchEthereumChain"), + WalletSwitchEthereumChain("wallet_switchEthereumChain"), @SerialName("wallet_addEthereumChain") - wallet_add_ethereum_chain("wallet_addEthereumChain"), + WalletAddEthereumChain("wallet_addEthereumChain"), @SerialName("solana_signMessage") - solana_sign_message("solana_signMessage"), + SolanaSignMessage("solana_signMessage"), @SerialName("solana_signTransaction") - solana_sign_transaction("solana_signTransaction"), + SolanaSignTransaction("solana_signTransaction"), @SerialName("solana_signAndSendTransaction") - solana_sign_and_send_transaction("solana_signAndSendTransaction"), + SolanaSignAndSendTransaction("solana_signAndSendTransaction"), @SerialName("solana_signAllTransactions") - solana_sign_all_transactions("solana_signAllTransactions"), + SolanaSignAllTransactions("solana_signAllTransactions"), } diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/swap/Approval.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/swap/Approval.kt index cfd694416..edd529d9d 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/swap/Approval.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/swap/Approval.kt @@ -5,6 +5,7 @@ package com.wallet.core.primitives.swap import com.wallet.core.primitives.SwapProvider +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable @@ -53,3 +54,15 @@ data class SwapData ( val data: SwapQuoteData ) +@Serializable +enum class SwapStatus(val string: String) { + @SerialName("pending") + Pending("pending"), + @SerialName("completed") + Completed("completed"), + @SerialName("failed") + Failed("failed"), + @SerialName("refunded") + Refunded("refunded"), +} + diff --git a/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/TransactionItem.kt b/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/TransactionItem.kt index 1b7c7a1e1..2c95ac02a 100644 --- a/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/TransactionItem.kt +++ b/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/TransactionItem.kt @@ -229,7 +229,9 @@ fun TransactionType.getTitle(direction: TransactionDirection? = null, state: Tra TransactionType.StakeWithdraw -> R.string.transfer_withdraw_title TransactionType.AssetActivation -> R.string.transfer_activate_asset_title TransactionType.TransferNFT -> R.string.transfer_title - TransactionType.SmartContractCall -> TODO() + TransactionType.SmartContractCall -> R.string.transfer_smart_contract_title + TransactionType.PerpetualOpenPosition -> R.string.perpetual_position + TransactionType.PerpetualClosePosition -> R.string.perpetual_close_position } } @@ -246,7 +248,9 @@ fun TransactionType.getTransactionTitle(direction: TransactionDirection, state: TransactionType.TokenApproval -> stringResource(id = R.string.transfer_approve_title) TransactionType.AssetActivation -> stringResource(R.string.transfer_activate_asset_title) TransactionType.TransferNFT -> "${stringResource(R.string.transfer_title)} NFT" - TransactionType.SmartContractCall -> TODO() + TransactionType.SmartContractCall -> stringResource(R.string.transfer_smart_contract_title) + TransactionType.PerpetualOpenPosition -> stringResource(R.string.perpetual_position) + TransactionType.PerpetualClosePosition -> stringResource(R.string.perpetual_close_position) } } @@ -255,8 +259,10 @@ fun TransactionType.getValue(direction: TransactionDirection, value: String): St TransactionType.StakeUndelegate, TransactionType.StakeRewards, TransactionType.StakeRedelegate, - TransactionType.StakeWithdraw -> value - TransactionType.StakeDelegate -> value + TransactionType.StakeWithdraw, + TransactionType.StakeDelegate, + TransactionType.PerpetualOpenPosition, + TransactionType.PerpetualClosePosition -> value TransactionType.Transfer, TransactionType.Swap -> when (direction) { TransactionDirection.SelfTransfer, @@ -265,8 +271,8 @@ fun TransactionType.getValue(direction: TransactionDirection, value: String): St } TransactionType.TokenApproval, TransactionType.TransferNFT, - TransactionType.AssetActivation -> "" - TransactionType.SmartContractCall -> TODO() + TransactionType.AssetActivation, + TransactionType.SmartContractCall -> "" } } @@ -286,8 +292,10 @@ fun TransactionType.getAddress(direction: TransactionDirection, from: String, to TransactionType.StakeRedelegate, TransactionType.StakeWithdraw, TransactionType.AssetActivation, - TransactionType.StakeRewards -> "" - TransactionType.SmartContractCall -> TODO() + TransactionType.StakeRewards, + TransactionType.SmartContractCall, + TransactionType.PerpetualOpenPosition, + TransactionType.PerpetualClosePosition -> "" } } diff --git a/ui/src/main/res/values-ar/strings.xml b/ui/src/main/res/values-ar/strings.xml index 7ccde6214..ed4ac0866 100644 --- a/ui/src/main/res/values-ar/strings.xml +++ b/ui/src/main/res/values-ar/strings.xml @@ -444,7 +444,7 @@ يتطلب عنوان %s علامة وجهة/مذكرة معلومات Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short حجم 24 ساعة سعر الدخول - الستيكينج الخاص بك + سعر البيتكوين + تتبع سعر البيتكوين + أعلى سعر للعملات المشفرة + تتبع أسعار العملات المشفرة الرائدة + متاح: %s + حماية الوصول إلى هذا التطبيق على جهازك + تم الوصول إلى حد المحفظة + لقد وصلت إلى الحد الأقصى لعدد المحافظ المسموح به ( %d ). يُرجى إزالة محفظة موجودة لإضافة محفظة جديدة أو إنشائها. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-bn/strings.xml b/ui/src/main/res/values-bn/strings.xml index 23ba2f066..1c56ec8a5 100644 --- a/ui/src/main/res/values-bn/strings.xml +++ b/ui/src/main/res/values-bn/strings.xml @@ -444,7 +444,7 @@ %s ঠিকানার জন্য একটি গন্তব্য ট্যাগ / মেমো প্রয়োজন। তথ্য Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short ২৪ ঘন্টা ভলিউম প্রবেশ মূল্য - ততোমার স্টেকিং + বিটকয়েনের দাম + বিটকয়েনের দাম ট্র্যাক করুন + শীর্ষ ক্রিপ্টো মূল্য + শীর্ষ ক্রিপ্টোকারেন্সির দাম ট্র্যাক করুন + উপলব্ধ: %s + আপনার ডিভাইসে এই অ্যাপের অ্যাক্সেস সুরক্ষিত করুন + ওয়ালেটের সীমা পৌঁছে গেছে + আপনি সর্বাধিক অনুমোদিত ওয়ালেটের সংখ্যা ( %d ) এ পৌঁছে গেছেন। নতুন একটি ওয়ালেট যোগ করতে বা তৈরি করতে অনুগ্রহ করে বিদ্যমান একটি ওয়ালেট সরিয়ে ফেলুন। + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-cs/strings.xml b/ui/src/main/res/values-cs/strings.xml index 94d9311c0..b24bd9a28 100644 --- a/ui/src/main/res/values-cs/strings.xml +++ b/ui/src/main/res/values-cs/strings.xml @@ -444,7 +444,7 @@ Adresa %s vyžaduje tag / poznámku cíle Informace Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24hodinový objem Vstupní cena - Vaše sázka + Cena bitcoinu + Sledování ceny Bitcoinu + Nejlepší cena kryptoměn + Sledujte ceny nejoblíbenějších kryptoměn + Dostupné: %s + Chraňte přístup k této aplikaci na svém zařízení + Dosažen limit peněženek + Dosáhli jste maximálního povoleného počtu peněženek ( %d ). Chcete-li přidat nebo vytvořit novou peněženku, odeberte existující peněženku. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-da/strings.xml b/ui/src/main/res/values-da/strings.xml index 8f8cbd8ac..4cffe17a7 100644 --- a/ui/src/main/res/values-da/strings.xml +++ b/ui/src/main/res/values-da/strings.xml @@ -444,7 +444,7 @@ %s adresse kræver et destinationstag / memo Info Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24-timers volumen Indgangspris - Din indsats + Bitcoin-pris + Spor Bitcoin-prisen + Top Kryptopris + Spor priserne på de bedste kryptovalutaer + Tilgængelig: %s + Beskyt adgangen til denne app på din enhed + Grænsen for tegnebøger er nået + Du har nået det maksimale antal tilladte tegnebøger ( %d ). Fjern venligst en eksisterende tegnebog for at tilføje eller oprette en ny. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-de/strings.xml b/ui/src/main/res/values-de/strings.xml index 568f0f920..d853aa954 100644 --- a/ui/src/main/res/values-de/strings.xml +++ b/ui/src/main/res/values-de/strings.xml @@ -427,7 +427,7 @@ Verdächtige oder Spam-Token werden als potenzieller Betrug oder schädliche Vermögenswerte identifiziert. Sie können aufgrund von Airdrops, Transfers oder manuellen Importen in Ihrer Wallet erscheinen. Unzureichende Mittel %s erforderlich - Für diese Transaktion werden %s benötigt, um die an %s Miner gezahlte Netzwerkgebühr zu decken, nicht Gem Wallet. Stellen Sie sicher, dass Sie über genügend %s verfügen. + Für diese Transaktion sind %s erforderlich, um die an %s Miner gezahlte Netzwerkgebühr zu decken, nicht Gem Wallet. Stellen Sie sicher, dass Sie über genügend %s verfügen. Gem Wallet Unzureichendes Guthaben Sie haben nicht genügend %s, um diese Transaktion abzuschließen. Bitte laden Sie Ihr Wallet auf, empfangen Sie es oder tauschen Sie es um und versuchen Sie es erneut. @@ -444,7 +444,7 @@ %s Adresse erfordert ein Ziel-Tag/Memo Info Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24-Stunden-Volumen Eintrittspreis - Ihr Einsatz + Bitcoin-Preis + Bitcoin-Preis verfolgen + Top-Krypto-Preis + Verfolgen Sie die Preise der wichtigsten Kryptowährungen + Verfügbar: %s + Schützen Sie den Zugriff auf diese App auf Ihrem Gerät + Wallet-Limit erreicht + Sie haben die maximal zulässige Anzahl an Wallets erreicht ( %d ). Bitte entfernen Sie ein vorhandenes Wallet, um ein neues hinzuzufügen oder zu erstellen. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-es/strings.xml b/ui/src/main/res/values-es/strings.xml index 66fc4f23f..648bc962a 100644 --- a/ui/src/main/res/values-es/strings.xml +++ b/ui/src/main/res/values-es/strings.xml @@ -444,7 +444,7 @@ La dirección %s requiere una etiqueta/memo de destino Información Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short Volumen de 24 horas Precio de entrada - Su participación + Precio de Bitcoin + Seguimiento del precio de Bitcoin + Precio máximo de las criptomonedas + Seguimiento de los precios de las principales criptomonedas + Disponible: %s + Proteger el acceso a esta aplicación en su dispositivo + Límite de billeteras alcanzado + Has alcanzado el número máximo de billeteras permitidas ( %d ). Elimina una billetera existente para agregar o crear una nueva. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-fa/strings.xml b/ui/src/main/res/values-fa/strings.xml index cedb522cb..0778ec213 100644 --- a/ui/src/main/res/values-fa/strings.xml +++ b/ui/src/main/res/values-fa/strings.xml @@ -444,7 +444,7 @@ آدرس %s به یک برچسب / یادداشت مقصد نیاز دارد. اطلاعات Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short حجم ۲۴ ساعته قیمت ورودی - استیکینگ شما + قیمت بیت کوین + قیمت بیت کوین را پیگیری کنید + بالاترین قیمت کریپتو + قیمت ارزهای دیجیتال برتر را پیگیری کنید + موجود: %s + دسترسی به این برنامه را در دستگاه خود محافظت کنید + محدودیت کیف پول‌ها تکمیل شد + شما به حداکثر تعداد کیف پول مجاز ( %d ) رسیده‌اید. لطفاً برای اضافه کردن یا ایجاد کیف پول جدید، کیف پول موجود را حذف کنید. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-fil/strings.xml b/ui/src/main/res/values-fil/strings.xml index 0c430832d..866fad46c 100644 --- a/ui/src/main/res/values-fil/strings.xml +++ b/ui/src/main/res/values-fil/strings.xml @@ -444,7 +444,7 @@ Nangangailangan ang %s address ng patutunguhang tag / memo Impormasyon Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24h Volume Entry Price - Ang iyong Staking + Presyo ng Bitcoin + Subaybayan ang presyo ng Bitcoin + Nangungunang Presyo ng Crypto + Subaybayan ang mga presyo ng mga nangungunang cryptocurrencies + Available: %s + Protektahan ang access sa app na ito sa iyong device + Naabot na ang Limitasyon ng Wallets + Naabot mo na ang maximum na bilang ng mga wallet na pinapayagan ( %d ). Mangyaring alisin ang isang umiiral na wallet upang magdagdag o gumawa ng bago. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-fr/strings.xml b/ui/src/main/res/values-fr/strings.xml index 115830486..85e3134ff 100644 --- a/ui/src/main/res/values-fr/strings.xml +++ b/ui/src/main/res/values-fr/strings.xml @@ -444,7 +444,7 @@ L\'adresse %s nécessite une balise de destination / un mémo Informations Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short Volume 24h Prix d\'entrée - Votre jalonnement + Prix du Bitcoin + Suivre le prix du Bitcoin + Meilleur prix des cryptomonnaies + Suivez les prix des principales crypto-monnaies + Disponible : %s + Protégez l\'accès à cette application sur votre appareil + Limite de portefeuilles atteinte + Vous avez atteint le nombre maximal de portefeuilles autorisés ( %d ). Veuillez supprimer un portefeuille existant pour en ajouter ou en créer un nouveau. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-hi/strings.xml b/ui/src/main/res/values-hi/strings.xml index b8e35ed34..9338ebf0a 100644 --- a/ui/src/main/res/values-hi/strings.xml +++ b/ui/src/main/res/values-hi/strings.xml @@ -427,7 +427,7 @@ संदिग्ध या स्पैम टोकन को संभावित घोटाले या हानिकारक संपत्ति के रूप में पहचाना जाता है। वे एयरड्रॉप, ट्रांसफ़र या मैन्युअल आयात के कारण आपके वॉलेट में दिखाई दे सकते हैं। अपर्याप्त कोष %s आवश्यक - इस लेनदेन के लिए %s माइनर्स को भुगतान किए गए नेटवर्क शुल्क को कवर करने के लिए %s की आवश्यकता है, न कि Gem Wallet । सुनिश्चित करें कि आपके पास पर्याप्त %s है। + इस लेन-देन के लिए %s माइनर्स को दिए गए नेटवर्क शुल्क को कवर करने के लिए %s की आवश्यकता है, न कि Gem Wallet । सुनिश्चित करें कि आपके पास पर्याप्त %s हैं। Gem Wallet अपर्याप्त शेषराशि इस लेनदेन को पूरा करने के लिए आपके पास पर्याप्त %s नहीं है। कृपया अपने वॉलेट में टॉप अप करें, प्राप्त करें या स्वैप करें और फिर से प्रयास करें। @@ -444,7 +444,7 @@ %s पते के लिए गंतव्य टैग / मेमो आवश्यक है जानकारी Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24 घंटे की मात्रा प्रवेश मूल्य - आपका दांव + बिटकॉइन की कीमत + बिटकॉइन की कीमत पर नज़र रखें + शीर्ष क्रिप्टो मूल्य + शीर्ष क्रिप्टोकरेंसी की कीमतों पर नज़र रखें + उपलब्ध: %s + अपने डिवाइस पर इस ऐप तक पहुंच सुरक्षित रखें + वॉलेट की सीमा पूरी हो गई + आप अनुमत वॉलेट की अधिकतम संख्या ( %d ) तक पहुँच गए हैं। कृपया नया वॉलेट जोड़ने या बनाने के लिए मौजूदा वॉलेट हटाएँ। + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-id/strings.xml b/ui/src/main/res/values-id/strings.xml index 2495ce40c..a913642dd 100644 --- a/ui/src/main/res/values-id/strings.xml +++ b/ui/src/main/res/values-id/strings.xml @@ -427,7 +427,7 @@ Token yang mencurigakan atau spam diidentifikasi sebagai potensi penipuan atau aset berbahaya. Token tersebut mungkin muncul di dompet Anda karena airdrop, transfer, atau impor manual. Dana tidak mencukupi %s diperlukan - Transaksi ini memerlukan %s untuk menutupi biaya jaringan yang dibayarkan kepada %s penambang, bukan Gem Wallet. Pastikan Anda memiliki cukup %s. + Transaksi ini membutuhkan %s untuk menutupi biaya jaringan yang dibayarkan kepada %s penambang, bukan Gem Wallet. Pastikan Anda memiliki %s yang cukup. Gem Wallet Saldo Tidak Cukup Anda tidak memiliki cukup %s untuk menyelesaikan transaksi ini. Harap isi ulang, terima, atau tukarkan di dompet Anda dan coba lagi. @@ -444,7 +444,7 @@ Alamat %s memerlukan tag / memo tujuan Informasi Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short Volume 24 jam Harga Masuk - Taruhan Anda + Harga Bitcoin + Lacak harga Bitcoin + Harga Kripto Teratas + Lacak harga mata uang kripto teratas + Tersedia: %s + Lindungi akses ke aplikasi ini di perangkat Anda + Batas Dompet Tercapai + Anda telah mencapai jumlah maksimum dompet yang diizinkan ( %d ). Silakan hapus dompet yang ada untuk menambahkan atau membuat dompet baru. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-it/strings.xml b/ui/src/main/res/values-it/strings.xml index b503c0815..887e73b51 100644 --- a/ui/src/main/res/values-it/strings.xml +++ b/ui/src/main/res/values-it/strings.xml @@ -444,7 +444,7 @@ L\'indirizzo %s richiede un tag di destinazione / promemoria Informazioni Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short Volume 24 ore Prezzo d\'ingresso - Il tuo staking + Prezzo del Bitcoin + Tieni traccia del prezzo del Bitcoin + Prezzo massimo delle criptovalute + Tieni traccia dei prezzi delle principali criptovalute + Disponibile: %s + Proteggi l\'accesso a questa app sul tuo dispositivo + Limite di portafogli raggiunto + Hai raggiunto il numero massimo di portafogli consentiti ( %d ). Rimuovi un portafoglio esistente per aggiungerne uno nuovo o creane uno nuovo. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-iw/strings.xml b/ui/src/main/res/values-iw/strings.xml index 9e88fd2da..dba27e502 100644 --- a/ui/src/main/res/values-iw/strings.xml +++ b/ui/src/main/res/values-iw/strings.xml @@ -444,7 +444,7 @@ כתובת %s דורשת תגית יעד / תזכיר מידע Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short נפח של 24 שעות מחיר כניסה - ההימור שלך + מחיר ביטקוין + מעקב אחר מחיר הביטקוין + מחיר הקריפטו הגבוה ביותר + מעקב אחר מחירי מטבעות קריפטוגרפיים מובילים + זמין: %s + הגן על הגישה לאפליקציה הזו במכשיר שלך + הגעת למגבלת הארנקים + הגעת למספר הארנקים המרבי המותר ( %d ). אנא הסר ארנק קיים כדי להוסיף או ליצור ארנק חדש. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-ja/strings.xml b/ui/src/main/res/values-ja/strings.xml index 44ee58db6..54b345d22 100644 --- a/ui/src/main/res/values-ja/strings.xml +++ b/ui/src/main/res/values-ja/strings.xml @@ -288,7 +288,7 @@ ネットワーク料金 ウォッチ アクセス権はありませんが、取引や動きを監視できるウォレットです。 - Every transaction on the %s network requires a fee in %s paid to miners to process your transaction, not Gem Wallet. Network fees varies based on network usage. + %s ネットワーク上のすべての取引には、取引処理のためにマイナーに支払われる %s の手数料が必要であり、Gem Wallet には支払われません。ネットワーク手数料はネットワークの使用状況により変動します。 残高不足、無効な入力、ネットワークによる拒否などのエラーにより、取引を完了できませんでした。詳細をご確認の上、再度お試しください。 取引は送信済みで、ネットワーク上での確認を待っています。処理時間は異なる場合があります。最新情報を再度ご確認ください。 取引は完了し、ネットワーク上で確認されました。詳細を確認してステータスをご確認ください。 @@ -410,18 +410,18 @@ ウォレットへのアクセスを失った場合、Gemは責任を負わず、支援もできないことを理解しています。 理解しました。続行します。 %sは必須です - Allow installation + インストールを許可 設定に移動して外部ソースからのインストールを許可します 設定に移動 - Downloading... - Unverified + ダウンロード中... + 未検証 疑わしい - Know What You’re Adding - Anyone can create one - including fake or malicious tokens. - Smart Contract - Other + 追加内容を確認 + 誰でも作成可能で、偽トークンや悪意のあるトークンも含まれます。 + スマートコントラクト + その他 バランスがある - Estimated Time + 推定時間 契約またはトークンID 未検証トークンは、信頼できるサードパーティサービスによって十分に検証されていません。エアドロップ、送金、または手動インポートによってウォレットに表示される場合があります。 疑わしいトークンやスパムトークンは、詐欺や有害な資産の可能性があると判断されます。エアドロップ、送金、または手動インポートによってウォレットに表示される場合があります。 @@ -438,31 +438,41 @@ %sネットワークでは、最小ステーキング要件は ** %s ** です。 ウォレットに追加 財布から隠す - 詳細 - 再び交換 + ディテール + 再度スワップ 疑わしい取引として特定された %sアドレスには宛先タグ/メモが必要です 情報 - Deposit - - Funding Payments - Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. - Funding - The funding rate determines the cost of holding a perpetual position. It is calculated hourly and helps maintain price equilibrium between the perpetual contract and the underlying asset\'s spot price. - Liquidation Price - The liquidation price is the price level at which your position will be automatically closed to prevent further losses. When the market price reaches this level, your position is liquidated and you lose your margin. - Open Interest - Open interest represents the total value of all outstanding perpetual contracts that have not been settled. It provides insight into market activity and liquidity. + 入金 + 出金 + ファンディングペイメント + ファンディングペイメントは、永久契約の価格を基礎資産のスポット価格に近づけるためにトレーダー間で定期的に行われる支払いです。プラスのファンディングではロングポジションがショートポジションに支払い、マイナスのファンディングではショートポジションがロングポジションに支払います。 + ファンディングレート + ファンディングレートは永久ポジションの保有コストを決定します。これは毎時計算され、永久契約と基礎資産のスポット価格の価格均衡を維持するのに役立ちます。 + 清算価格 + 清算価格は、損失拡大を防ぐためにポジションが自動的に決済される価格水準です。市場価格がこの水準に達するとポジションは清算され、証拠金を失います。 + オープンインタレスト + オープンインタレストは、未決済のすべての永久契約の合計価値を表します。市場の活動状況や流動性の指標となります。 選択したトークン ペアの見積もりを返すことができません。金額が少ない、流動性がない、または技術的な制限がある可能性があります。 ポジション サイズ マージン - 位置 + ポジション クローズポジション - PnL - Long - Short + 損益 + ロング + ショート 24時間取引量 入場料 - あなたのステーキング + ビットコイン価格 + ビットコインの価格を追跡する + トップ暗号通貨価格 + 主要暗号通貨の価格を追跡する + 利用可能: %s + デバイス上のこのアプリへのアクセスを保護する + ウォレットの上限に達しました + ウォレットの上限数( %d )に達しました。既存のウォレットを削除して、新しいウォレットを追加するか作成してください。 + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-ko/strings.xml b/ui/src/main/res/values-ko/strings.xml index 6228f9d15..13c6872cd 100644 --- a/ui/src/main/res/values-ko/strings.xml +++ b/ui/src/main/res/values-ko/strings.xml @@ -444,7 +444,7 @@ %s 주소에는 목적지 태그/메모가 필요합니다. 정보 Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24시간 볼륨 입장료 - 귀하의 스테이킹 + 비트코인 가격 + 비트코인 가격 추적 + 최고 암호화폐 가격 + 주요 암호화폐 가격 추적 + 사용 가능: %s + 기기에서 이 앱에 대한 액세스를 보호하세요 + 지갑 한도에 도달했습니다 + 허용된 최대 지갑 수( %d )에 도달했습니다. 기존 지갑을 제거한 후 추가하거나 새 지갑을 만드세요. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-ms/strings.xml b/ui/src/main/res/values-ms/strings.xml index 2d15241b3..f98688216 100644 --- a/ui/src/main/res/values-ms/strings.xml +++ b/ui/src/main/res/values-ms/strings.xml @@ -444,7 +444,7 @@ Alamat %s memerlukan teg / memo destinasi info Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short Kelantangan 24j Harga Kemasukan - Staking Anda + Harga Bitcoin + Jejaki harga Bitcoin + Harga Kripto Tertinggi + Jejaki harga mata wang kripto teratas + Tersedia: %s + Lindungi akses kepada apl ini pada peranti anda + Had Dompet Dicapai + Anda telah mencapai bilangan maksimum dompet yang dibenarkan ( %d ). Sila alih keluar dompet sedia ada untuk menambah atau membuat yang baharu. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-nl/strings.xml b/ui/src/main/res/values-nl/strings.xml index 9e3aaf8fb..88269c826 100644 --- a/ui/src/main/res/values-nl/strings.xml +++ b/ui/src/main/res/values-nl/strings.xml @@ -444,7 +444,7 @@ %s adres vereist een bestemmingslabel / memo Informatie Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24-uurs volume Toegangsprijs - Uw inzet + Bitcoin-prijs + Volg de Bitcoin-prijs + Top Crypto-prijs + Volg de prijzen van de beste cryptovaluta\'s + Beschikbaar: %s + Beveilig de toegang tot deze app op uw apparaat + Portemonneelimiet bereikt + Je hebt het maximale aantal toegestane wallets bereikt ( %d ). Verwijder een bestaande wallet om er een toe te voegen of een nieuwe aan te maken. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-pl/strings.xml b/ui/src/main/res/values-pl/strings.xml index 2fbf9d3f2..bed4dbb77 100644 --- a/ui/src/main/res/values-pl/strings.xml +++ b/ui/src/main/res/values-pl/strings.xml @@ -427,7 +427,7 @@ Podejrzane lub spamowe tokeny są identyfikowane jako potencjalne oszustwa lub szkodliwe aktywa. Mogą pojawić się w Twoim portfelu z powodu airdropów, transferów lub ręcznych importów. Niewystarczające fundusze %s wymagane - Ta transakcja wymaga %s do pokrycia opłaty sieciowej uiszczanej na rzecz %s górników, a nie Gem Wallet. Upewnij się, że masz wystarczająco dużo %s. + Ta transakcja wymaga %s do pokrycia opłaty sieciowej płaconej %s górnikom, a nie Gem Wallet. Upewnij się, że masz wystarczającą ilość %s. Gem Wallet Niewystarczające saldo Nie masz wystarczająco %s aby ukończyć tę transakcję. Doładuj, odbierz lub wymień w swoim portfelu i spróbuj ponownie. @@ -444,7 +444,7 @@ Adres %s wymaga znacznika/notatki docelowej Informacje Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short Objętość 24h Cena wejścia - Twoje stakowanie + Cena Bitcoina + Śledź cenę Bitcoina + Najwyższa cena kryptowaluty + Śledź ceny najlepszych kryptowalut + Dostępne: %s + Chroń dostęp do tej aplikacji na swoim urządzeniu + Osiągnięto limit portfeli + Osiągnięto maksymalną liczbę dozwolonych portfeli ( %d ). Usuń istniejący portfel, aby dodać lub utworzyć nowy. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-pt-rBR/strings.xml b/ui/src/main/res/values-pt-rBR/strings.xml index 62158b85a..76669f02e 100644 --- a/ui/src/main/res/values-pt-rBR/strings.xml +++ b/ui/src/main/res/values-pt-rBR/strings.xml @@ -444,7 +444,7 @@ O endereço %s requer uma tag/memorando de destino Informações Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short Volume 24h Preço de entrada - Sua participação + Preço do Bitcoin + Acompanhe o preço do Bitcoin + Preço máximo de criptomoedas + Acompanhe os preços das principais criptomoedas + Disponível: %s + Proteja o acesso a este aplicativo no seu dispositivo + Limite de carteiras atingido + Você atingiu o número máximo de carteiras permitidas ( %d ). Remova uma carteira existente para adicionar ou criar uma nova. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-ro/strings.xml b/ui/src/main/res/values-ro/strings.xml index 0ce4d72dd..fff3e32a8 100644 --- a/ui/src/main/res/values-ro/strings.xml +++ b/ui/src/main/res/values-ro/strings.xml @@ -444,7 +444,7 @@ Adresa %s necesită o etichetă/notă de destinație Informații Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short Volum 24h Preț de intrare - Staking-ul tău + Prețul Bitcoinului + Urmărește prețul Bitcoinului + Preț maxim al criptomonedelor + Urmărește prețurile criptomonedelor de top + Disponibil: %s + Protejați accesul la această aplicație pe dispozitivul dvs. + Limita de portofele a fost atinsă + Ați atins numărul maxim de portofele permise ( %d ). Vă rugăm să eliminați un portofel existent pentru a adăuga sau a crea unul nou. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-ru/strings.xml b/ui/src/main/res/values-ru/strings.xml index 671054c7e..1b6b53171 100644 --- a/ui/src/main/res/values-ru/strings.xml +++ b/ui/src/main/res/values-ru/strings.xml @@ -427,7 +427,7 @@ Подозрительные или спам‑токены помечаются как потенциальные мошеннические или вредоносные активы. Они могут появиться в вашем кошельке в результате airdrop‑раздач, переводов или ручного добавления. Недостаточно средств Требуется %s - Эта транзакция требует %s для покрытия сетевой комиссии, выплачиваемой майнерам %s, а не Кошелек Gem. Убедитесь, что у вас достаточно %s. + Для этой транзакции требуется %s для покрытия сетевой комиссии, выплачиваемой майнерам %s, а не Кошелек Gem. Убедитесь, что у вас достаточно %s. Кошелек Gem Недостаточный баланс У вас недостаточно %s для завершения этой транзакции. Пожалуйста, пополните, получите или обменяйте ваш кошелек и попробуйте еще раз. @@ -444,7 +444,7 @@ %s адрес требует тега назначения / заметки Информация Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24-часовой объем Цена входа - Ваш Стейкинг + Цена Bitcoin + Отслеживайте цену Bitcoin + Цены топ криптовалют + Отслеживайте цены топ криптовалют + Доступно: %s + Защитите доступ к этому приложению на вашем устройстве + Достигнут лимит кошельков + Достигнуто максимально допустимое количество кошельков ( %d ). Чтобы добавить или создать новый, удалите существующий кошелёк. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-sw/strings.xml b/ui/src/main/res/values-sw/strings.xml index 8b4b85cce..2dd0529f1 100644 --- a/ui/src/main/res/values-sw/strings.xml +++ b/ui/src/main/res/values-sw/strings.xml @@ -444,7 +444,7 @@ %s anwani inahitaji lebo/memo lengwa Habari Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short Sauti ya 24h Bei ya Kuingia - Staking yako + Bei ya Bitcoin + Fuatilia bei ya Bitcoin + Bei ya Juu ya Crypto + Fuatilia bei za sarafu-fiche za juu + Inapatikana: %s + Linda ufikiaji wa programu hii kwenye kifaa chako + Kikomo cha Wallet Kimefikiwa + Umefikia idadi ya juu zaidi ya pochi inayoruhusiwa ( %d ). Tafadhali ondoa pochi iliyopo ili kuongeza au kuunda mpya. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-th/strings.xml b/ui/src/main/res/values-th/strings.xml index 1fdd474ac..6c7a24c95 100644 --- a/ui/src/main/res/values-th/strings.xml +++ b/ui/src/main/res/values-th/strings.xml @@ -427,7 +427,7 @@ โทเค็นที่น่าสงสัยหรือเป็นสแปมจะถูกระบุว่าเป็นการหลอกลวงหรือทรัพย์สินที่เป็นอันตราย โทเค็นเหล่านี้อาจปรากฏในกระเป๋าเงินของคุณเนื่องจากการส่งทางอากาศ การโอน หรือการนำเข้าด้วยตนเอง เงินไม่เพียงพอ %s จำเป็น - ธุรกรรมนี้จำเป็นต้อง %s ครอบคลุมค่าธรรมเนียมเครือข่ายที่จ่ายให้กับนักขุด %s คน ไม่ใช่ Gem Wallet โปรดตรวจสอบให้แน่ใจว่าคุณมี %s เพียงพอ + ธุรกรรมนี้ต้องการให้ %s ครอบคลุมค่าธรรมเนียมเครือข่ายที่จ่ายให้กับนักขุด %s คน ไม่ใช่ Gem Wallet โปรดตรวจสอบให้แน่ใจว่าคุณมี %s เพียงพอ Gem Wallet ยอดเงินคงเหลือไม่เพียงพอ คุณมี %s ไม่เพียงพอสำหรับการทำธุรกรรมนี้ โปรดเติมเงิน รับ หรือแลกเปลี่ยนในกระเป๋าสตางค์ของคุณแล้วลองอีกครั้ง @@ -444,7 +444,7 @@ ที่อยู่ %s ต้องมีแท็กปลายทาง / บันทึกช่วยจำ ข้อมูล Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short ปริมาณ 24 ชั่วโมง ราคาเข้าชม - การเดิมพันของคุณ + ราคา Bitcoin + ติดตามราคา Bitcoin + ราคาคริปโตสูงสุด + ติดตามราคาของสกุลเงินดิจิทัลชั้นนำ + พร้อมใช้งาน: %s + ป้องกันการเข้าถึงแอปนี้บนอุปกรณ์ของคุณ + ถึงขีดจำกัดของกระเป๋าเงินแล้ว + คุณมีจำนวนกระเป๋าสตางค์ถึงจำนวนสูงสุดที่อนุญาตแล้ว ( %d ) กรุณาลบกระเป๋าสตางค์ที่มีอยู่เพื่อเพิ่มหรือสร้างใหม่ + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-tr/strings.xml b/ui/src/main/res/values-tr/strings.xml index a485c1e21..7e30834aa 100644 --- a/ui/src/main/res/values-tr/strings.xml +++ b/ui/src/main/res/values-tr/strings.xml @@ -444,7 +444,7 @@ %s adresi bir hedef etiketi / notu gerektiriyor Bilgi Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24 saatlik Hacim Giriş Fiyatı - Staking’iniz + Bitcoin Fiyatı + Bitcoin fiyatını takip edin + En İyi Kripto Fiyatı + En iyi kripto para birimlerinin fiyatlarını takip edin + Mevcut: %s + Cihazınızda bu uygulamaya erişimi koruyun + Cüzdan Limiti Doldu + İzin verilen maksimum cüzdan sayısına ulaştınız ( %d ). Lütfen yeni bir cüzdan eklemek veya oluşturmak için mevcut bir cüzdanı kaldırın. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-uk/strings.xml b/ui/src/main/res/values-uk/strings.xml index f52bd8053..c7f3573a3 100644 --- a/ui/src/main/res/values-uk/strings.xml +++ b/ui/src/main/res/values-uk/strings.xml @@ -427,7 +427,7 @@ Підозрілі або спам-токени ідентифікуються як потенційні шахрайські або шкідливі активи. Вони можуть з\'явитися у вашому гаманці через аїрдропи, перекази або ручний імпорт. Недостатньо коштів Потрібно %s - Для цієї транзакції потрібно %s для покриття мережевої комісії, сплаченої %s майнерам, а не Гаманець Gem. Переконайтеся, що у вас достатньо %s. + Для цієї транзакції потрібно %s для покриття мережевої плати, сплаченої %s майнерам, а не Гаманець Gem. Переконайтеся, що у вас достатньо %s. Гаманець Gem Недостатній баланс У вас недостатньо %s для завершення цієї транзакції. Будь ласка, поповніть, отримайте або обміняйте свій гаманець і спробуйте ще раз. @@ -444,7 +444,7 @@ Адреса %s потребує тегу / примітки призначення Інформація Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24-годинний обсяг Вхідна ціна - Ваш стейкінг + Ціна Bitcoin + Відстежуйте ціну Bitcoin + Найвища ціна криптовалюти + Відстежуйте ціни на провідні криптовалюти + Доступно: %s + Захистіть доступ до цієї програми на своєму пристрої + Досягнуто ліміту гаманців + Ви досягли максимальної дозволеної кількості гаманців ( %d ). Будь ласка, видаліть існуючий гаманець, щоб додати або створити новий. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-ur/strings.xml b/ui/src/main/res/values-ur/strings.xml index 5b36d7cce..e6c19dbcb 100644 --- a/ui/src/main/res/values-ur/strings.xml +++ b/ui/src/main/res/values-ur/strings.xml @@ -444,7 +444,7 @@ %s ایڈریس کے لیے منزل کا ٹیگ / میمو درکار ہے۔ معلومات Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24h والیوم داخلے کی قیمت - آپ کا Staking + بٹ کوائن کی قیمت + بٹ کوائن کی قیمت کو ٹریک کریں۔ + ٹاپ کریپٹو قیمت + سرفہرست کریپٹو کرنسیوں کی قیمتوں کو ٹریک کریں۔ + دستیاب: %s + اپنے آلے پر اس ایپ تک رسائی کی حفاظت کریں۔ + بٹوے کی حد تک پہنچ گئی۔ + آپ بٹوے کی اجازت کی زیادہ سے زیادہ تعداد تک پہنچ گئے ہیں ( %d )۔ ایک نیا شامل کرنے یا بنانے کے لیے براہ کرم موجودہ پرس کو ہٹا دیں۔ + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-vi/strings.xml b/ui/src/main/res/values-vi/strings.xml index 0eca3005a..bb3da6425 100644 --- a/ui/src/main/res/values-vi/strings.xml +++ b/ui/src/main/res/values-vi/strings.xml @@ -427,7 +427,7 @@ Mã thông báo đáng ngờ hoặc thư rác được xác định là lừa đảo tiềm ẩn hoặc tài sản có hại. Chúng có thể xuất hiện trong ví của bạn do airdrop, chuyển khoản hoặc nhập thủ công. Không đủ tiền %s bắt buộc - Giao dịch này yêu cầu %s phải trả phí mạng cho %s thợ đào, không phải Gem Wallet. Đảm bảo bạn có đủ %s. + Giao dịch này yêu cầu %s phải trả phí mạng lưới cho %s thợ đào, chứ không phải Gem Wallet. Hãy đảm bảo bạn có đủ %s. Gem Wallet Số dư không đủ Bạn không có đủ %s để hoàn tất giao dịch này. Vui lòng nạp tiền, nhận hoặc đổi trong ví của bạn và thử lại. @@ -444,7 +444,7 @@ %s địa chỉ yêu cầu thẻ đích / ghi nhớ Thông tin Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short Khối lượng 24 giờ Giá nhập cảnh - Staking của bạn + Giá Bitcoin + Theo dõi giá Bitcoin + Giá tiền điện tử hàng đầu + Theo dõi giá của các loại tiền điện tử hàng đầu + Có sẵn: %s + Bảo vệ quyền truy cập vào ứng dụng này trên thiết bị của bạn + Đã đạt đến giới hạn ví + Bạn đã đạt đến số lượng ví tối đa được phép ( %d ). Vui lòng xóa ví hiện có để thêm hoặc tạo ví mới. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s diff --git a/ui/src/main/res/values-zh-rCN/strings.xml b/ui/src/main/res/values-zh-rCN/strings.xml index 31c839de2..cc64fbb5a 100644 --- a/ui/src/main/res/values-zh-rCN/strings.xml +++ b/ui/src/main/res/values-zh-rCN/strings.xml @@ -288,7 +288,7 @@ 网络费用 观察钱包 这是一个您无法操作的钱包,但可以查看它的交易和资产变动。 - Every transaction on the %s network requires a fee in %s paid to miners to process your transaction, not Gem Wallet. Network fees varies based on network usage. + 在 %s 网络上的每笔交易都需要以 %s 支付给矿工的手续费,以处理您的交易,Gem Wallet 不收取此费用。网络手续费根据网络使用情况而变化。 由于资金不足、输入无效或网络拒绝等错误,交易无法完成。请检查详情并重试。 交易已提交,正在等待网络确认。处理时间可能有所不同。请稍后查看更新。 交易已完成并已在网络上确认。可查看详情以核实状态。 @@ -410,18 +410,18 @@ 我明白如果丢失钱包访问权限,Gem 不承担任何责任,也无法提供帮助。 我已了解,继续 %s为必填项 - Allow installation + 允许安装 转到设置并允许从外部来源安装 前往设置 - Downloading... - Unverified + 下载中... + 未验证 可疑的 - Know What You’re Adding - Anyone can create one - including fake or malicious tokens. - Smart Contract - Other + 了解您正在添加的内容 + 任何人都可以创建,包括假冒或恶意代币。 + 智能合约 + 其他 有余额 - Estimated Time + 预计时间 合约或代币ID 未验证代币是指未经可信第三方服务充分验证的代币。它们可能因空投、转账或手动导入而出现在您的钱包中。 可疑或垃圾代币会被识别为潜在的诈骗或有害资产。它们可能因空投、转账或手动导入而出现在您的钱包中。 @@ -438,31 +438,41 @@ 在%s网络上,最低质押要求为 ** %s **。 添加到钱包 隐藏钱包 - 细节 - 再次交换 + 详情 + 再次兑换 交易被认定为可疑 %s地址需要目的地标签/备忘录 信息 - Deposit - - Funding Payments - Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. - Funding - The funding rate determines the cost of holding a perpetual position. It is calculated hourly and helps maintain price equilibrium between the perpetual contract and the underlying asset\'s spot price. - Liquidation Price - The liquidation price is the price level at which your position will be automatically closed to prevent further losses. When the market price reaches this level, your position is liquidated and you lose your margin. - Open Interest - Open interest represents the total value of all outstanding perpetual contracts that have not been settled. It provides insight into market activity and liquidity. + 充值 + 提现 + 资金费用 + 资金费用是交易者之间的定期支付,用于使永续合约价格接近标的资产现货价格。正资金费用表示多头支付空头,负资金费用表示空头支付多头。 + 资金費率 + 资金费率决定持有永续仓位的成本。它按小时计算,有助于维持永续合约与标的资产现货价格之间的价格平衡。 + 强平价格 + 强平价格是当市场价格达到该水平时,您的仓位将被自动平仓以防止进一步亏损的价格。当市场价触及此价位,仓位被强制平仓,保证金将被扣除。 + 未平仓合约 + 未平仓合约代表所有尚未结算的永续合约的总价值,反映市场活动和流动性。 无法返回所选代币对的报价,可能是由于数量少、缺乏流动性或技术限制。 - 职位 - 尺寸 + 仓位 + 持仓量 利润 - 位置 + 仓位 平仓 - PnL - Long - Short + 盈亏 + 做多 + 做空 24小时交易量 入场价格 - 您的质押 + 比特币价格 + 追踪比特币价格 + 最高加密货币价格 + 追踪顶级加密货币的价格 + 可用: %s + 保护您设备上对此应用的访问 + 钱包已达上限 + 您已达到允许的最大钱包数量( %d )。请移除现有钱包以添加或创建新钱包。 + 可疑资产 + 代币可能不安全或具有误导性。请仅在完全信任的情况下继续操作。 + Maximum Amount is %s diff --git a/ui/src/main/res/values-zh-rTW/strings.xml b/ui/src/main/res/values-zh-rTW/strings.xml index 89bf3e2a2..9034025d5 100644 --- a/ui/src/main/res/values-zh-rTW/strings.xml +++ b/ui/src/main/res/values-zh-rTW/strings.xml @@ -288,7 +288,7 @@ 網絡費用 觀察錢包 這是一個您無法操作的錢包,但可以查看它的交易和資產變動。 - Every transaction on the %s network requires a fee in %s paid to miners to process your transaction, not Gem Wallet. Network fees varies based on network usage. + 在 %s 網路上的每筆交易都需要以 %s 支付給礦工的手續費,以處理您的交易,Gem Wallet 不收取此費用。網路手續費會根據網路使用情況而有所不同。 由於錯誤(例如資金不足、輸入無效或網路拒絕)導致交易無法完成。請查看詳細資訊並重試。 交易已提交並正在等待網路確認。處理時間可能有所不同。請回來查看更新。 交易已完成並在網路上確認。您可以查看詳細資訊來驗證其狀態。 @@ -410,18 +410,18 @@ 我了解若遺失錢包存取權限,Gem 不負任何責任且無法提供協助。 我了解,繼續 %s為必填項 - Allow installation + 允許安裝 轉到設定並允許從外部來源安裝 前往設定 - Downloading... - Unverified + 下載中... + 未驗證 可疑的 - Know What You’re Adding - Anyone can create one - including fake or malicious tokens. - Smart Contract - Other + 了解您正在新增的內容 + 任何人都可以創建,包括假冒或惡意代幣。 + 智能合約 + 其他 有餘額 - Estimated Time + 預估時間 合約或代幣ID 未驗證代幣是指未經可信任第三方服務充分驗證的代幣。它們可能因空投、轉帳或手動匯入而出現在您的錢包中。 可疑或垃圾代幣會被識別為潛在的詐騙或有害資產。它們可能因空投、轉帳或手動匯入而出現在您的錢包中。 @@ -438,31 +438,41 @@ 在%s網路上,最低質押要求為 ** %s **。 加入錢包 隱藏錢包 - 細節 + 詳情 再次交換 交易被認定為可疑 %s地址需要目的地標籤/備忘錄 資訊 - Deposit - - Funding Payments - Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. - Funding - The funding rate determines the cost of holding a perpetual position. It is calculated hourly and helps maintain price equilibrium between the perpetual contract and the underlying asset\'s spot price. - Liquidation Price - The liquidation price is the price level at which your position will be automatically closed to prevent further losses. When the market price reaches this level, your position is liquidated and you lose your margin. - Open Interest - Open interest represents the total value of all outstanding perpetual contracts that have not been settled. It provides insight into market activity and liquidity. + 轉入 + 提領 + 資金費用 + 資金費用是交易者之間的定期支付,用以使永續合約價格接近標的資產的現貨價格。正向資金費用表示多頭支付空頭,負向資金費用則表示空頭支付多頭。 + 資金費率 + 資金費率決定持有永續合約的成本,按小時計算,有助於維持永續合約與標的資產現貨價格之間的價格平衡。 + 強制平倉價格 + 強制平倉價格是當您的持倉價格達到此水平時,系統會自動平倉以防止進一步損失。當市場價格觸及此價格,您的持倉將被清算,並損失保證金。 + 未平倉合約量 + 未平倉合約量代表所有尚未結算的永續合約總價值,提供市場活動和流動性的參考。 無法返回所選代幣對的報價,可能是由於數量少、缺乏流動性或技術限制。 - 職位 - 尺寸 + 倉位 + 倉位大小 利潤 - 位置 + 倉位 平倉 - PnL - Long - Short + 損益 + 做多 + 做空 24小時交易量 入場價格 - 您的質押 + 比特幣價格 + 追蹤比特幣價格 + 最高加密貨幣價格 + 追蹤頂級加密貨幣的價格 + 可用: %s + 保護您設備上對此應用的訪問 + 錢包已達上限 + 您已達到允許的最大錢包數量( %d )。請移除現有錢包以新增或建立新錢包。 + 可疑資產 + 代幣可能不安全或具有誤導性。請僅在完全信任的情況下繼續操作。 + Maximum Amount is %s diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index b4e57f9cd..ebfe7614c 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -444,7 +444,7 @@ %s address requires a destination tag / memo Info Deposit - + Withdraw Funding Payments Funding payments are periodic payments between traders to keep the perpetual contract price close to the underlying asset\'s spot price. Positive funding means long positions pay short positions, while negative funding means short positions pay long positions. Funding @@ -464,5 +464,15 @@ Short 24h Volume Entry Price - Your Staking + Bitcoin Price + Track Bitcoin price + Top Crypto Price + Track prices of top cryptocurrencies + Available: %s + Protect access to this app on your device + Wallets Limit Reached + You’ve reached the maximum number of wallets allowed (%d). Please remove an existing wallet to add or create a new one. + Suspicious Asset + Token may be unsafe or misleading. Proceed only if you fully trust it. + Maximum Amount is %s From 0a22b9a9a2b4e889b169aafedce0281f1a5e4a7a Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Fri, 29 Aug 2025 22:25:17 -0700 Subject: [PATCH 02/16] Bump gemstone --- gradle/libs.versions.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4ff296a97..ed27bff17 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ core = "3.5.3" coreKtx = "1.17.0" espressoCore = "3.7.0" firebaseMessaging = "25.0.0" -gradle = "8.12.1" +gradle = "8.12.2" gson = "2.13.1" hiltAndroid = "2.57.1" hiltNavigationCompose = "1.2.0" @@ -24,7 +24,7 @@ kotlinSerialization = "2.2.10" kotlinxSerializationJson = "1.9.0" kotlinxCollectionsImmutable = "0.4.0" kotlinxCoroutinesAndroid = "1.10.2" -lifecycleRuntimeCompose = "2.9.2" +lifecycleRuntimeCompose = "2.9.3" loggingInterceptor = "5.1.0" retrofit = "3.0.0" review = "2.0.2" @@ -32,12 +32,12 @@ room = "2.7.2" securityCrypto = "1.1.0" compose = "1.9.0" materialIcons = "1.7.8" -material3 = "1.4.0-beta02" +material3 = "1.4.0-beta03" navigationCompose = "2.9.3" uiTestJunit4 = "1.9.0" testRunner = "1.7.0" ksp = "2.1.21-2.0.1" -android-lib = "8.12.1" +android-lib = "8.12.2" kotlin = "2.2.10" google-services = "4.4.3" material3AdaptiveAndroid = "1.0.0-alpha06" @@ -46,7 +46,7 @@ reorderable = "3.0.0" mockkVersion = "1.14.5" datastore = "1.1.7" wallet-core = "4.3.5" -gemstone = "0.32.0" +gemstone = "0.33.0" ktor = "3.1.3" appcompat = "1.7.1" material = "1.12.0" From 127677ed6ad2202e41917a113ef886a940958c9e Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Mon, 1 Sep 2025 22:39:16 -0700 Subject: [PATCH 03/16] Clean codebase --- .../app/tokens/TestValidateTokenAddress.kt | 5 - app/src/main/assets/swap/orca.svg | 13 - .../com/gemwallet/android/di/DataModule.kt | 102 ++---- .../bridge/request/RequestViewModel.kt | 2 +- .../confirm/viewmodels/ConfirmViewModel.kt | 6 +- .../navigation/ImportWalletNavigation.kt | 4 +- .../android/services/SignerPreloaderProxy.kt | 156 --------- .../clients/aptos/TestAptosBalance.kt | 161 --------- .../clients/aptos/TestAptosBalancesService.kt | 51 --- .../clients/bitcoin/TestBitcoinBalance.kt | 146 -------- .../bitcoin/TestBitcoinSIgnerPreloader.kt | 108 ------ .../clients/cosmos/TestCosmosBalances.kt | 328 ------------------ .../solana/TestSolanaAccountsService.kt | 86 ----- .../clients/solana/TestSolanaBalances.kt | 299 ---------------- .../solana/TestSolanaFeeCalculation.kt | 103 ------ .../clients/solana/TestSolanaFeeService.kt | 15 - .../clients/solana/TestSolanaSignPreloader.kt | 124 ------- .../clients/solana/TestSolanaSigner.kt | 7 +- .../clients/tron/FakeTronAccountService.kt | 31 -- .../clients/tron/FakeTronCallService.kt | 16 - .../clients/tron/FakeTronNodeStatusService.kt | 48 --- .../clients/tron/FakeTronStakeService.kt | 21 -- .../clients/tron/TestTronBalance.kt | 197 ----------- .../clients/tron/TestTronFeeCalculator.kt | 43 --- .../clients/xrp/TestXrpAccountsService.kt | 40 --- .../clients/xrp/TestXrpBalanceClient.kt | 48 --- .../clients/BroadcastClientProxy.kt | 23 -- .../clients/NodeStatusClientProxy.kt | 21 -- .../blockchain/clients/StakeClientProxy.kt | 28 -- .../clients/TransactionStatusClient.kt | 6 +- .../clients/algorand/AlgorandBalanceClient.kt | 36 -- .../algorand/AlgorandBroadcastClient.kt | 31 -- .../algorand/AlgorandNodeStatusClient.kt | 34 -- .../clients/algorand/AlgorandSignClient.kt | 3 +- .../algorand/AlgorandSignPreloadClient.kt | 4 +- .../AlgorandTransactionStatusClient.kt | 22 -- .../services/AlgorandAccountService.kt | 10 - .../services/AlgorandBroadcastService.kt | 13 - .../services/AlgorandNodeStatusService.kt | 14 - .../algorand/services/AlgorandService.kt | 11 +- .../services/AlgorandTxStatusService.kt | 10 - .../clients/aptos/AptosBalanceClient.kt | 51 --- .../clients/aptos/AptosBroadcastClient.kt | 22 -- .../clients/aptos/AptosFeeCalculator.kt | 8 +- .../clients/aptos/AptosGetTokenClient.kt | 38 -- .../clients/aptos/AptosNodeStatusClient.kt | 30 -- .../clients/aptos/AptosSignerPreloader.kt | 10 +- .../aptos/AptosTransactionStatusClient.kt | 26 -- .../clients/aptos/models/AptosAccount.kt | 4 +- .../aptos/services/AptosAccountsService.kt | 10 - .../aptos/services/AptosBalancesService.kt | 12 - .../aptos/services/AptosBroadcastService.kt | 13 - .../clients/aptos/services/AptosFeeService.kt | 18 - .../aptos/services/AptosNodeStatusService.kt | 19 - .../clients/aptos/services/AptosServices.kt | 29 +- .../aptos/services/AptosTokensService.kt | 12 - .../services/AptosTransactionsService.kt | 10 - .../clients/bitcoin/BitcoinBalanceClient.kt | 27 -- .../clients/bitcoin/BitcoinBroadcastClient.kt | 25 -- .../clients/bitcoin/BitcoinFeeCalculator.kt | 6 +- .../bitcoin/BitcoinNodeStatusClient.kt | 35 -- .../clients/bitcoin/BitcoinSignClient.kt | 4 +- .../clients/bitcoin/BitcoinSignerPreloader.kt | 10 +- .../bitcoin/BitcoinTransactionStatusClient.kt | 22 -- .../services/BitcoinBalancesService.kt | 10 - .../services/BitcoinBroadcastService.kt | 11 - .../bitcoin/services/BitcoinFeeService.kt | 10 - .../services/BitcoinNodeStatusService.kt | 15 - .../bitcoin/services/BitcoinRpcClient.kt | 22 +- .../services/BitcoinTransactionsService.kt | 10 - .../bitcoin/services/BitcoinUTXOService.kt | 10 - .../clients/cardano/CardanoBalanceClient.kt | 28 -- .../clients/cardano/CardanoBroadcastClient.kt | 27 -- .../cardano/CardanoNodeStatusClient.kt | 37 -- .../clients/cardano/CardanoSignClient.kt | 3 +- .../cardano/CardanoTransactionStatusClient.kt | 27 -- .../cardano/services/CardanoBalanceService.kt | 27 -- .../services/CardanoBroadcastService.kt | 25 -- .../cardano/services/CardanoFeeService.kt | 30 -- .../services/CardanoNodeStatusService.kt | 36 -- .../cardano/services/CardanoServices.kt | 33 +- .../services/CardanoTransactionService.kt | 25 -- .../clients/cosmos/CosmosBalanceClient.kt | 135 ------- .../clients/cosmos/CosmosBroadcastClient.kt | 28 -- .../blockchain/clients/cosmos/CosmosDenom.kt | 15 + .../clients/cosmos/CosmosNodeStatusClient.kt | 33 -- .../clients/cosmos/CosmosSignerPreloader.kt | 10 +- .../clients/cosmos/CosmosStakeClient.kt | 97 ------ .../cosmos/CosmosTransactionStatusClient.kt | 26 -- .../cosmos/services/CosmosAccountsService.kt | 19 - .../cosmos/services/CosmosBalancesService.kt | 10 - .../cosmos/services/CosmosBroadcastService.kt | 11 - .../services/CosmosNodeStatusService.kt | 15 - .../cosmos/services/CosmosRpcClient.kt | 24 +- .../cosmos/services/CosmosStakeService.kt | 23 -- .../services/CosmosTransactionsService.kt | 10 - .../clients/ethereum/EvmNodeStatusClient.kt | 2 +- .../clients/hyper/HyperCoreBalanceClient.kt | 18 - .../clients/hyper/HyperCoreBroadcatClient.kt | 21 -- .../clients/hyper/HyperCoreGetTokenClient.kt | 19 - .../hyper/HyperCoreNodeStatusClient.kt | 18 - .../clients/hyper/HyperCoreStakeClient.kt | 27 -- .../HyperCoreTransactionsStatusClient.kt | 16 - .../clients/near/NearBalanceClient.kt | 38 -- .../clients/near/NearBroadcastClient.kt | 29 -- .../blockchain/clients/near/NearMethod.kt | 3 - .../clients/near/NearNodeStatusClient.kt | 38 -- .../blockchain/clients/near/NearRpcClient.kt | 19 - .../near/NearTransactionStatusClient.kt | 37 -- .../polkadot/PolkadotBalancesClient.kt | 35 -- .../polkadot/PolkadotBroadcastClient.kt | 30 -- .../clients/polkadot/PolkadotFeeCalculator.kt | 11 - .../polkadot/PolkadotNodeStatusClient.kt | 37 -- .../clients/polkadot/PolkadotSignClient.kt | 2 +- .../polkadot/PolkadotSignerPreloaderClient.kt | 16 +- .../PolkadotTransactionStatusClient.kt | 41 --- .../models/PolkadotTransactionBroadcast.kt | 10 - .../services/PolkadotBalancesService.kt | 10 - .../services/PolkadotBroadcastService.kt | 11 - .../polkadot/services/PolkadotFeeService.kt | 11 - .../services/PolkadotNodeStatusService.kt | 15 - .../polkadot/services/PolkadotServices.kt | 24 +- .../services/PolkadotTransactionService.kt | 17 - .../clients/solana/SolanaBalanceClient.kt | 62 ---- .../clients/solana/SolanaBroadcastClient.kt | 42 --- .../clients/solana/SolanaFeeCalculator.kt | 94 ----- .../blockchain/clients/solana/SolanaMethod.kt | 24 -- .../clients/solana/SolanaNodeStatusClient.kt | 37 -- .../clients/solana/SolanaRawTxDecoder.kt | 19 - .../clients/solana/SolanaSignClient.kt | 12 +- .../clients/solana/SolanaSignerPreloader.kt | 105 ------ .../clients/solana/SolanaStakeClient.kt | 86 ----- .../clients/solana/SolanaTokenClient.kt | 81 ----- .../solana/SolanaTransactionStatusClient.kt | 33 -- .../clients/solana/models/SolanaChainData.kt | 19 + .../clients/solana/models/SolanaParsed.kt | 30 -- .../clients/solana/models/SolanaTokenOwner.kt | 3 - .../solana/services/SolanaAccountsService.kt | 57 --- .../solana/services/SolanaBalancesService.kt | 41 --- .../solana/services/SolanaBroadcastService.kt | 11 - .../solana/services/SolanaFeeService.kt | 18 - .../services/SolanaNetworkInfoService.kt | 23 -- .../services/SolanaNodeStatusService.kt | 33 -- .../solana/services/SolanaRpcClient.kt | 17 - .../solana/services/SolanaStakeService.kt | 67 ---- .../services/SolanaTransactionsService.kt | 28 -- .../clients/stellar/StellarBalanceClient.kt | 34 -- .../clients/stellar/StellarBroadcastClient.kt | 45 --- .../clients/stellar/StellarFeeCalculator.kt | 6 +- .../stellar/StellarNodeStatusClient.kt | 30 -- .../stellar/StellarSignPreloadClient.kt | 12 +- .../stellar/StellarTransactionStatusClient.kt | 26 -- .../stellar/services/StellarAccountService.kt | 16 - .../services/StellarBroadcastService.kt | 11 - .../stellar/services/StellarFeeService.kt | 9 - .../services/StellarNodeStatusService.kt | 11 - .../stellar/services/StellarService.kt | 23 +- .../services/StellarTxStatusService.kt | 10 - .../clients/sui/SuiBalanceClient.kt | 53 --- .../clients/sui/SuiBroadcastClient.kt | 23 -- .../clients/sui/SuiGetTokenClient.kt | 40 --- .../blockchain/clients/sui/SuiMethod.kt | 12 - .../clients/sui/SuiNodeStatusClient.kt | 33 -- .../blockchain/clients/sui/SuiRpcClient.kt | 78 ----- .../blockchain/clients/sui/SuiStakeClient.kt | 69 ---- .../clients/sui/SuiTransactionStatusClient.kt | 26 -- .../clients/ton/TonBalanceClient.kt | 49 --- .../clients/ton/TonBroadcastClient.kt | 30 -- .../blockchain/clients/ton/TonCalls.kt | 37 +- .../clients/ton/TonGetTokenClient.kt | 33 -- .../clients/ton/TonNodeStatusClient.kt | 26 -- .../blockchain/clients/ton/TonRpcClient.kt | 28 -- .../clients/ton/TonTransactionStatusClient.kt | 28 -- .../clients/tron/TronAddressStatusClient.kt | 6 +- .../clients/tron/TronBalanceClient.kt | 76 ---- .../clients/tron/TronBroadcastClient.kt | 31 -- .../clients/tron/TronFeeCalculator.kt | 13 +- .../clients/tron/TronGetTokenClient.kt | 96 ----- .../clients/tron/TronNodeStatusClient.kt | 26 -- .../blockchain/clients/tron/TronRpcClient.kt | 92 ++++- .../clients/tron/TronSignerPreloader.kt | 17 +- .../clients/tron/TronStakeClient.kt | 123 ------- .../tron/TronTransactionStatusClient.kt | 29 -- .../tron/services/TronAccountsService.kt | 42 --- .../tron/services/TronBalanceService.kt | 12 - .../tron/services/TronBroadcastService.kt | 16 - .../clients/tron/services/TronCallService.kt | 31 -- .../tron/services/TronNodeStatusService.kt | 19 - .../clients/tron/services/TronStakeService.kt | 16 - .../clients/xrp/XrpBalanceClient.kt | 52 --- .../clients/xrp/XrpBroadcastClient.kt | 30 -- .../blockchain/clients/xrp/XrpMethod.kt | 4 - .../clients/xrp/XrpNodeStatusClient.kt | 27 -- .../blockchain/clients/xrp/XrpRpcClient.kt | 42 +-- .../blockchain/clients/xrp/XrpSignClient.kt | 2 +- .../clients/xrp/XrpSignerPreloader.kt | 1 - .../clients/xrp/XrpTransactionStatusClient.kt | 26 -- .../xrp/services/XrpAccountsService.kt | 43 --- .../android/blockchain/rpc/Response.kt | 2 +- .../blockchain/services/BalancesService.kt | 122 +++++++ .../services/BroadcastClientProxy.kt | 44 +++ .../services/NodeStatusClientProxy.kt | 39 +++ .../{clients => services}/SignClientProxy.kt | 4 +- .../services/SignerPreloaderProxy.kt | 252 ++++++++++++++ .../blockchain/services/StakeClientProxy.kt | 81 +++++ .../blockchain/services/TokenService.kt | 77 ++++ .../services/TransactionStatusService.kt | 52 +++ .../blockchain/services/mapper/Asset.kt | 23 ++ .../clients/aptos/TestAptosBroadcast.kt | 77 ---- .../clients/aptos/TestAptosFeeCalculator.kt | 2 - .../clients/aptos/TestAptosSignerPreloader.kt | 2 - .../clients/aptos/TestAptosTransactions.kt | 81 ----- .../clients/bitcoin/TestBitcoinBroadcast.kt | 54 --- .../bitcoin/TestBitcoinTransactions.kt | 67 ---- .../clients/cosmos/TestCosmosBroadcast.kt | 109 ------ .../clients/cosmos/TestCosmosPreload.kt | 1 - .../clients/cosmos/TestCosmosStake.kt | 179 ---------- .../clients/cosmos/TestCosmosTransactions.kt | 94 ----- .../repositoreis/assets/AssetsRepository.kt | 9 +- .../assets/BalancesRemoteSource.kt | 48 --- .../data/repositoreis/bridge/Namespace.kt | 5 +- .../data/repositoreis/di/AssetsModule.kt | 78 +++-- .../data/repositoreis/di/StakeModule.kt | 30 +- .../data/repositoreis/di/SwapModule.kt | 19 +- .../data/repositoreis/di/TokensModule.kt | 36 +- .../repositoreis/di/TransactionsModule.kt | 43 +-- .../repositoreis/stake/StakeRepository.kt | 25 +- .../data/repositoreis/swap/NativeProvider.kt | 12 +- .../data/repositoreis/swap/SwapRepository.kt | 2 +- .../repositoreis/tokens/TokensRepository.kt | 35 +- .../transactions/TransactionsRepository.kt | 21 +- .../data/services/gemapi/di/ClientsModule.kt | 5 +- .../data/services/gemapi/http/GetNodeUrl.kt | 26 ++ .../gemapi/http/NodeSelectorInterceptor.kt | 15 +- .../settings/networks/presents/NodeItem.kt | 12 +- .../networks/viewmodels/AddNodeViewModel.kt | 2 +- .../networks/viewmodels/NetworksViewModel.kt | 8 +- .../swap/viewmodels/SwapSelectViewModel.kt | 3 +- .../kotlin/com/gemwallet/android/ext/Chain.kt | 6 +- .../gemwallet/android/model/AssetBalance.kt | 2 +- .../com/gemwallet/android/model/NodeStatus.kt | 4 +- .../core/primitives/PerpetualPosition.kt | 2 +- gradle/libs.versions.toml | 2 +- .../ui/components/image/IconUrlGeneration.kt | 1 - 244 files changed, 1239 insertions(+), 7450 deletions(-) delete mode 100644 app/src/main/assets/swap/orca.svg delete mode 100644 app/src/main/kotlin/com/gemwallet/android/services/SignerPreloaderProxy.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBalance.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBalancesService.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinBalance.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSIgnerPreloader.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosBalances.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaAccountsService.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaBalances.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaFeeCalculation.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaFeeService.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSignPreloader.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronAccountService.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronCallService.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronNodeStatusService.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronStakeService.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronBalance.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronFeeCalculator.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpAccountsService.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BroadcastClientProxy.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/NodeStatusClientProxy.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/StakeClientProxy.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandAccountService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandBroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandNodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandTxStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosGetTokenClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosAccountsService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosBalancesService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosBroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosFeeService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosNodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosTokensService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosTransactionsService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinBalancesService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinBroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinFeeService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinNodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinTransactionsService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinUTXOService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoBalanceService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoBroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoFeeService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoNodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoTransactionService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosBroadcastClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosDenom.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosStakeClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosAccountsService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosBalancesService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosBroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosNodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosStakeService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosTransactionsService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBroadcatClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreGetTokenClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreStakeClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreTransactionsStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotBalancesClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/models/PolkadotTransactionBroadcast.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotBalancesService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotBroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotFeeService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotNodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotTransactionService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaMethod.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignerPreloader.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaStakeClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaTokenClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaTransactionStatusClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaChainData.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaParsed.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaTokenOwner.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaAccountsService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaBalancesService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaBroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaFeeService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaNetworkInfoService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaNodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaRpcClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaStakeService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaTransactionsService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarAccountService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarBroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarFeeService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarNodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarTxStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiGetTokenClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiStakeClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonGetTokenClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronGetTokenClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronStakeClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronAccountsService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronBalanceService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronBroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronCallService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronNodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronStakeService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/services/XrpAccountsService.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastClientProxy.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusClientProxy.kt rename blockchain/src/main/kotlin/com/gemwallet/android/blockchain/{clients => services}/SignClientProxy.kt (94%) create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeClientProxy.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBroadcast.kt delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosTransactions.kt delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinBroadcast.kt delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinTransactions.kt delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosBroadcast.kt delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosStake.kt delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosTransactions.kt delete mode 100644 data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/BalancesRemoteSource.kt create mode 100644 data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/http/GetNodeUrl.kt diff --git a/app/src/androidTest/kotlin/wallet/android/app/tokens/TestValidateTokenAddress.kt b/app/src/androidTest/kotlin/wallet/android/app/tokens/TestValidateTokenAddress.kt index cecc6e3fe..69e6c1cc3 100644 --- a/app/src/androidTest/kotlin/wallet/android/app/tokens/TestValidateTokenAddress.kt +++ b/app/src/androidTest/kotlin/wallet/android/app/tokens/TestValidateTokenAddress.kt @@ -1,11 +1,6 @@ package wallet.android.app.tokens -import com.gemwallet.android.blockchain.clients.aptos.AptosGetTokenClient import com.gemwallet.android.blockchain.clients.ethereum.EvmGetTokenClient -import com.gemwallet.android.blockchain.clients.solana.SolanaTokenClient -import com.gemwallet.android.blockchain.clients.sui.SuiGetTokenClient -import com.gemwallet.android.blockchain.clients.ton.TonGetTokenClient -import com.gemwallet.android.blockchain.clients.tron.TronGetTokenClient import junit.framework.TestCase.assertFalse import junit.framework.TestCase.assertTrue import org.junit.Test diff --git a/app/src/main/assets/swap/orca.svg b/app/src/main/assets/swap/orca.svg deleted file mode 100644 index 21fcf7fdd..000000000 --- a/app/src/main/assets/swap/orca.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt b/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt index dca733293..a224aceab 100644 --- a/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt +++ b/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt @@ -3,85 +3,54 @@ package com.gemwallet.android.di import com.gemwallet.android.blockchain.RpcClientAdapter import com.gemwallet.android.blockchain.clients.ActivationTransactionPreloader import com.gemwallet.android.blockchain.clients.ApprovalTransactionPreloader -import com.gemwallet.android.blockchain.clients.BroadcastClientProxy import com.gemwallet.android.blockchain.clients.GenericTransferPreloader import com.gemwallet.android.blockchain.clients.NftTransactionPreloader -import com.gemwallet.android.blockchain.clients.NodeStatusClientProxy -import com.gemwallet.android.blockchain.clients.SignClientProxy import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.clients.algorand.AlgorandBroadcastClient -import com.gemwallet.android.blockchain.clients.algorand.AlgorandNodeStatusClient import com.gemwallet.android.blockchain.clients.algorand.AlgorandSignClient import com.gemwallet.android.blockchain.clients.algorand.AlgorandSignPreloadClient -import com.gemwallet.android.blockchain.clients.aptos.AptosBroadcastClient -import com.gemwallet.android.blockchain.clients.aptos.AptosNodeStatusClient import com.gemwallet.android.blockchain.clients.aptos.AptosSignClient import com.gemwallet.android.blockchain.clients.aptos.AptosSignerPreloader -import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinBroadcastClient -import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinNodeStatusClient import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinSignClient import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinSignerPreloader -import com.gemwallet.android.blockchain.clients.cardano.CardanoBroadcastClient -import com.gemwallet.android.blockchain.clients.cardano.CardanoNodeStatusClient import com.gemwallet.android.blockchain.clients.cardano.CardanoSignClient import com.gemwallet.android.blockchain.clients.cardano.CardanoSignerPreloaderClient -import com.gemwallet.android.blockchain.clients.cosmos.CosmosBroadcastClient -import com.gemwallet.android.blockchain.clients.cosmos.CosmosNodeStatusClient import com.gemwallet.android.blockchain.clients.cosmos.CosmosSignClient import com.gemwallet.android.blockchain.clients.cosmos.CosmosSignerPreloader import com.gemwallet.android.blockchain.clients.ethereum.EvmBroadcastClient import com.gemwallet.android.blockchain.clients.ethereum.EvmNodeStatusClient import com.gemwallet.android.blockchain.clients.ethereum.EvmSignClient import com.gemwallet.android.blockchain.clients.ethereum.EvmSignerPreloader -import com.gemwallet.android.blockchain.clients.hyper.HyperCoreBroadcatClient -import com.gemwallet.android.blockchain.clients.hyper.HyperCoreNodeStatusClient import com.gemwallet.android.blockchain.clients.hyper.HyperCoreSignClient import com.gemwallet.android.blockchain.clients.hyper.HyperCoreSignerPreloaderClient -import com.gemwallet.android.blockchain.clients.near.NearBroadcastClient -import com.gemwallet.android.blockchain.clients.near.NearNodeStatusClient import com.gemwallet.android.blockchain.clients.near.NearSignClient import com.gemwallet.android.blockchain.clients.near.NearSignerPreloader -import com.gemwallet.android.blockchain.clients.polkadot.PolkadotBroadcastClient -import com.gemwallet.android.blockchain.clients.polkadot.PolkadotNodeStatusClient import com.gemwallet.android.blockchain.clients.polkadot.PolkadotSignClient import com.gemwallet.android.blockchain.clients.polkadot.PolkadotSignerPreloaderClient -import com.gemwallet.android.blockchain.clients.solana.SolanaBroadcastClient -import com.gemwallet.android.blockchain.clients.solana.SolanaNodeStatusClient import com.gemwallet.android.blockchain.clients.solana.SolanaSignClient -import com.gemwallet.android.blockchain.clients.solana.SolanaSignerPreloader -import com.gemwallet.android.blockchain.clients.stellar.StellarBroadcastClient -import com.gemwallet.android.blockchain.clients.stellar.StellarNodeStatusClient import com.gemwallet.android.blockchain.clients.stellar.StellarSignClient import com.gemwallet.android.blockchain.clients.stellar.StellarSignPreloadClient -import com.gemwallet.android.blockchain.clients.sui.SuiBroadcastClient -import com.gemwallet.android.blockchain.clients.sui.SuiNodeStatusClient import com.gemwallet.android.blockchain.clients.sui.SuiSignClient import com.gemwallet.android.blockchain.clients.sui.SuiSignerPreloader -import com.gemwallet.android.blockchain.clients.ton.TonBroadcastClient -import com.gemwallet.android.blockchain.clients.ton.TonNodeStatusClient import com.gemwallet.android.blockchain.clients.ton.TonSignClient import com.gemwallet.android.blockchain.clients.ton.TonSignerPreloader -import com.gemwallet.android.blockchain.clients.tron.TronBroadcastClient -import com.gemwallet.android.blockchain.clients.tron.TronNodeStatusClient import com.gemwallet.android.blockchain.clients.tron.TronSignClient import com.gemwallet.android.blockchain.clients.tron.TronSignerPreloader -import com.gemwallet.android.blockchain.clients.xrp.XrpBroadcastClient -import com.gemwallet.android.blockchain.clients.xrp.XrpNodeStatusClient import com.gemwallet.android.blockchain.clients.xrp.XrpSignClient import com.gemwallet.android.blockchain.clients.xrp.XrpSignerPreloader -import com.gemwallet.android.cases.device.GetDeviceIdCase +import com.gemwallet.android.blockchain.services.BroadcastClientProxy +import com.gemwallet.android.blockchain.services.NodeStatusClientProxy +import com.gemwallet.android.blockchain.services.SignClientProxy +import com.gemwallet.android.blockchain.services.SignerPreloaderProxy import com.gemwallet.android.cases.device.SyncSubscription import com.gemwallet.android.cases.transactions.SyncTransactions import com.gemwallet.android.data.repositoreis.assets.AssetsRepository import com.gemwallet.android.data.repositoreis.buy.BuyRepository import com.gemwallet.android.data.repositoreis.session.SessionRepository import com.gemwallet.android.data.repositoreis.wallets.WalletsRepository -import com.gemwallet.android.data.services.gemapi.GemApiClient import com.gemwallet.android.ext.available import com.gemwallet.android.ext.toChainType -import com.gemwallet.android.services.SignerPreloaderProxy import com.gemwallet.android.services.SyncService import com.wallet.core.primitives.Chain import com.wallet.core.primitives.ChainType @@ -89,6 +58,7 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import uniffi.gemstone.GemGateway import javax.inject.Singleton @InstallIn(SingletonComponent::class) @@ -98,25 +68,26 @@ object DataModule { @Provides @Singleton fun providesBroadcastProxy( + gateway: GemGateway, rpcClients: RpcClientAdapter, ): BroadcastClientProxy = BroadcastClientProxy( - Chain.available().map { + gateway = gateway, + clients = Chain.available().mapNotNull { when (it.toChainType()) { - ChainType.Bitcoin -> BitcoinBroadcastClient(it, rpcClients.getClient(it)) ChainType.Ethereum -> EvmBroadcastClient(it, rpcClients.getClient(it)) - ChainType.Solana -> SolanaBroadcastClient(it, rpcClients.getClient(Chain.Solana)) - ChainType.Cosmos -> CosmosBroadcastClient(it, rpcClients.getClient(it)) - ChainType.Ton -> TonBroadcastClient(it, rpcClients.getClient(it)) - ChainType.Tron -> TronBroadcastClient(it, rpcClients.getClient(Chain.Tron)) - ChainType.Aptos -> AptosBroadcastClient(it, rpcClients.getClient(it)) - ChainType.Sui -> SuiBroadcastClient(it, rpcClients.getClient(it)) - ChainType.Xrp -> XrpBroadcastClient(it, rpcClients.getClient(it)) - ChainType.Near -> NearBroadcastClient(it, rpcClients.getClient(it)) - ChainType.Algorand -> AlgorandBroadcastClient(it, rpcClients.getClient(it)) - ChainType.Stellar -> StellarBroadcastClient(it, rpcClients.getClient(it)) - ChainType.Polkadot -> PolkadotBroadcastClient(it, rpcClients.getClient(it)) - ChainType.Cardano -> CardanoBroadcastClient(it, rpcClients.getClient(it)) - ChainType.HyperCore -> HyperCoreBroadcatClient(it) + else -> null +// ChainType.Bitcoin -> BitcoinBroadcastClient(it, rpcClients.getClient(it)) +// ChainType.Cosmos -> CosmosBroadcastClient(it, rpcClients.getClient(it)) +// ChainType.Ton -> TonBroadcastClient(it, rpcClients.getClient(it)) +// ChainType.Tron -> TronBroadcastClient(it, rpcClients.getClient(Chain.Tron)) +// ChainType.Aptos -> AptosBroadcastClient(it, rpcClients.getClient(it)) +// ChainType.Sui -> SuiBroadcastClient(it, rpcClients.getClient(it)) +// ChainType.Xrp -> XrpBroadcastClient(it, rpcClients.getClient(it)) +// ChainType.Near -> NearBroadcastClient(it, rpcClients.getClient(it)) +// ChainType.Algorand -> AlgorandBroadcastClient(it, rpcClients.getClient(it)) +// ChainType.Stellar -> StellarBroadcastClient(it, rpcClients.getClient(it)) +// ChainType.Polkadot -> PolkadotBroadcastClient(it, rpcClients.getClient(it)) +// ChainType.Cardano -> CardanoBroadcastClient(it, rpcClients.getClient(it)) } }, ) @@ -124,16 +95,14 @@ object DataModule { @Provides @Singleton fun provideSignerPreloader( + gateway: GemGateway, rpcClients: RpcClientAdapter, - gemApiClient: GemApiClient, - sessionRepository: SessionRepository, - getDeviceIdCase: GetDeviceIdCase, ): SignerPreloaderProxy { - val preloaders = Chain.available().map { + val preloaders = Chain.available().mapNotNull { when (it.toChainType()) { ChainType.Bitcoin -> BitcoinSignerPreloader(it, rpcClients.getClient(it), rpcClients.getClient(it)) ChainType.Ethereum -> EvmSignerPreloader(it, rpcClients.getClient(it), rpcClients.getClient(it)) - ChainType.Solana -> SolanaSignerPreloader(it, rpcClients.getClient(Chain.Solana), rpcClients.getClient(Chain.Solana), rpcClients.getClient(Chain.Solana)) + ChainType.Solana -> null ChainType.Cosmos -> CosmosSignerPreloader(it, rpcClients.getClient(it)) ChainType.Ton -> TonSignerPreloader(it, rpcClients.getClient(it)) ChainType.Tron -> TronSignerPreloader(it, rpcClients.getClient(it), rpcClients.getClient(it), rpcClients.getClient(it)) @@ -149,9 +118,7 @@ object DataModule { } } return SignerPreloaderProxy( - gemApiClient = gemApiClient, - sessionRepository = sessionRepository, - getDeviceIdCase = getDeviceIdCase, + gateway = gateway, nativeTransferClients = preloaders, tokenTransferClients = preloaders.mapNotNull { it as? TokenTransferPreloader }, stakeTransactionClients = preloaders.mapNotNull { it as? StakeTransactionPreloader }, @@ -192,26 +159,15 @@ object DataModule { @Singleton @Provides fun provideNodeStatusClient( + gateway: GemGateway, rpcClients: RpcClientAdapter, ): NodeStatusClientProxy { return NodeStatusClientProxy( - Chain.available().map { + gateway = gateway, + clients = Chain.available().mapNotNull { when (it.toChainType()) { ChainType.Ethereum -> EvmNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Bitcoin -> BitcoinNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Solana -> SolanaNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Cosmos -> CosmosNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Ton -> TonNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Tron -> TronNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Aptos -> AptosNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Sui -> SuiNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Xrp -> XrpNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Near -> NearNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Algorand -> AlgorandNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Stellar -> StellarNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Polkadot -> PolkadotNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.Cardano -> CardanoNodeStatusClient(it, rpcClients.getClient(it)) - ChainType.HyperCore -> HyperCoreNodeStatusClient(it) + else -> null } } ) diff --git a/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt b/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt index ae8ed3069..381aa5070 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt @@ -3,7 +3,7 @@ package com.gemwallet.android.features.bridge.request import androidx.core.net.toUri import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.gemwallet.android.blockchain.clients.SignClientProxy +import com.gemwallet.android.blockchain.services.SignClientProxy import com.gemwallet.android.blockchain.operators.LoadPrivateKeyOperator import com.gemwallet.android.blockchain.operators.PasswordStore import com.gemwallet.android.data.repositoreis.bridge.BridgesRepository diff --git a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt index 6dbc36166..0bcdc2660 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt @@ -3,8 +3,8 @@ package com.gemwallet.android.features.confirm.viewmodels import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.gemwallet.android.blockchain.clients.BroadcastClientProxy -import com.gemwallet.android.blockchain.clients.SignClientProxy +import com.gemwallet.android.blockchain.services.BroadcastClientProxy +import com.gemwallet.android.blockchain.services.SignClientProxy import com.gemwallet.android.blockchain.operators.LoadPrivateKeyOperator import com.gemwallet.android.blockchain.operators.PasswordStore import com.gemwallet.android.cases.transactions.CreateTransaction @@ -28,7 +28,7 @@ import com.gemwallet.android.model.Session import com.gemwallet.android.model.SignerParams import com.gemwallet.android.model.format import com.gemwallet.android.serializer.jsonEncoder -import com.gemwallet.android.services.SignerPreloaderProxy +import com.gemwallet.android.blockchain.services.SignerPreloaderProxy import com.gemwallet.android.ui.R import com.gemwallet.android.ui.components.CellEntity import com.gemwallet.android.ui.components.InfoSheetEntity diff --git a/app/src/main/kotlin/com/gemwallet/android/features/import_wallet/navigation/ImportWalletNavigation.kt b/app/src/main/kotlin/com/gemwallet/android/features/import_wallet/navigation/ImportWalletNavigation.kt index 9717b6b81..8f37f12ee 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/import_wallet/navigation/ImportWalletNavigation.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/import_wallet/navigation/ImportWalletNavigation.kt @@ -8,10 +8,10 @@ import androidx.navigation.compose.composable import androidx.navigation.navArgument import androidx.navigation.navOptions import androidx.navigation.navigation +import com.gemwallet.android.ext.toChain import com.gemwallet.android.features.import_wallet.views.ImportScreen import com.gemwallet.android.features.import_wallet.views.SelectImportTypeScreen import com.gemwallet.android.model.ImportType -import com.wallet.core.primitives.Chain import com.wallet.core.primitives.WalletType internal const val walletTypeArg = "wallet_type" @@ -56,7 +56,7 @@ fun NavGraphBuilder.importWalletScreen( val walletTypeString = entry.arguments?.getString(walletTypeArg) val chainString = entry.arguments?.getString(chainArg) val walletType = WalletType.entries.firstOrNull { it.string == walletTypeString } - val chain = Chain.entries.firstOrNull { it.string == chainString } + val chain = chainString?.toChain() if (walletType == null || (walletType != WalletType.multicoin && chain == null)) { onSelectType(null) } else { diff --git a/app/src/main/kotlin/com/gemwallet/android/services/SignerPreloaderProxy.kt b/app/src/main/kotlin/com/gemwallet/android/services/SignerPreloaderProxy.kt deleted file mode 100644 index cc0ec6d92..000000000 --- a/app/src/main/kotlin/com/gemwallet/android/services/SignerPreloaderProxy.kt +++ /dev/null @@ -1,156 +0,0 @@ -package com.gemwallet.android.services - -import com.gemwallet.android.blockchain.clients.ActivationTransactionPreloader -import com.gemwallet.android.blockchain.clients.ApprovalTransactionPreloader -import com.gemwallet.android.blockchain.clients.GenericTransferPreloader -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.NftTransactionPreloader -import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.clients.getClient -import com.gemwallet.android.cases.device.GetDeviceIdCase -import com.gemwallet.android.data.repositoreis.session.SessionRepository -import com.gemwallet.android.data.services.gemapi.GemApiClient -import com.gemwallet.android.ext.getAccount -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.ScanAddressTarget -import com.wallet.core.primitives.ScanTransaction -import com.wallet.core.primitives.ScanTransactionPayload -import com.wallet.core.primitives.Wallet -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class SignerPreloaderProxy( - private val gemApiClient: GemApiClient, - private val sessionRepository: SessionRepository, - private val getDeviceIdCase: GetDeviceIdCase, - private val nativeTransferClients: List, - private val tokenTransferClients: List, - private val stakeTransactionClients: List, - private val swapTransactionClients: List, - private val approvalTransactionClients: List, - private val activatePreloaderClients: List, - private val genericPreloaderClients: List, - private val nftPreloadClients: List, -) : GenericTransferPreloader, NativeTransferPreloader, TokenTransferPreloader, StakeTransactionPreloader, - SwapTransactionPreloader, ApprovalTransactionPreloader, ActivationTransactionPreloader, NftTransactionPreloader { - - suspend fun preload(params: ConfirmParams): SignerParams = withContext(Dispatchers.IO) { - - val isValidTransactionJob = async { - isValidTransaction( - getScanTransactionPayload( - params, - sessionRepository.getSession()?.wallet ?: throw IllegalStateException("Session isn't available"), - getDeviceIdCase.getDeviceId() - ) - ) - } - - val preloadJob = async { - when (params) { - is ConfirmParams.Stake -> preloadStake(params) - is ConfirmParams.SwapParams -> preloadSwap(params) - is ConfirmParams.TokenApprovalParams -> preloadApproval(params) - is ConfirmParams.TransferParams.Native -> preloadNativeTransfer(params) - is ConfirmParams.TransferParams.Token -> preloadTokenTransfer(params) - is ConfirmParams.Activate -> preloadActivate(params) - is ConfirmParams.TransferParams.Generic -> preloadGeneric(params) - is ConfirmParams.NftParams -> preloadNft(params) - } - } - - val isValidTransaction = isValidTransactionJob.await() - val preload = preloadJob.await() - preload.copy(scanTransaction = isValidTransaction) - } - - override fun supported(chain: Chain): Boolean { - return (nativeTransferClients - + tokenTransferClients - + stakeTransactionClients - + swapTransactionClients - + approvalTransactionClients).getClient(chain) != null - } - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - return nativeTransferClients.getClient(params.from.chain)?.preloadNativeTransfer(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { - return tokenTransferClients.getClient(params.from.chain)?.preloadTokenTransfer(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams { - return stakeTransactionClients.getClient(params.from.chain)?.preloadStake(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - return swapTransactionClients.getClient(params.from.chain)?.preloadSwap(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadApproval(params: ConfirmParams.TokenApprovalParams): SignerParams { - return approvalTransactionClients.getClient(params.from.chain)?.preloadApproval(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadActivate(params: ConfirmParams.Activate): SignerParams { - return activatePreloaderClients.getClient(params.from.chain)?.preloadActivate(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadGeneric(params: ConfirmParams.TransferParams.Generic): SignerParams { - return genericPreloaderClients.getClient(params.from.chain)?.preloadGeneric(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadNft(params: ConfirmParams.NftParams): SignerParams { - return nftPreloadClients.getClient(params.from.chain)?.preloadNft(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - private suspend fun isValidTransaction(payload: ScanTransactionPayload): ScanTransaction? { - return try { - gemApiClient.getScanTransaction(payload).data - } catch (_: Throwable) { - null - } - } - - private fun getScanTransactionPayload(params: ConfirmParams, wallet: Wallet, deviceId: String): ScanTransactionPayload { - val chain = params.assetId.chain - val origin = ScanAddressTarget( - chain = chain, - address = params.from.address, - ) - val target = when (params) { - is ConfirmParams.SwapParams -> ScanAddressTarget( - params.toAssetId.chain, - address = wallet.getAccount(params.toAssetId.chain)?.address ?: throw IllegalArgumentException("Account isn't available") - ) - is ConfirmParams.Stake -> ScanAddressTarget(chain, params.validatorId) - is ConfirmParams.TokenApprovalParams -> ScanAddressTarget(chain, params.contract) - is ConfirmParams.TransferParams.Native, - is ConfirmParams.TransferParams.Generic, - is ConfirmParams.TransferParams.Token -> ScanAddressTarget(chain, params.destination().address) - is ConfirmParams.Activate -> ScanAddressTarget(chain, params.from.address) - is ConfirmParams.NftParams -> ScanAddressTarget(chain, params.from.address) - } - - return ScanTransactionPayload( - deviceId = deviceId, - walletIndex = wallet.index.toUInt(), - origin = origin, - target = target, - type = params.getTxType(), - ) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBalance.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBalance.kt deleted file mode 100644 index 13c47e1b4..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBalance.kt +++ /dev/null @@ -1,161 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.ext.toIdentifier -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertNotNull -import junit.framework.TestCase.assertNull -import junit.framework.TestCase.assertTrue -import kotlinx.coroutines.runBlocking -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class TestAptosBalance { - - companion object { - init { - includeLibs() - } - } - - @Test - fun testAptosBalance() { - val balancesService = TestAptosBalancesService(nativeBalance = "100000000") - val client = AptosBalanceClient( - chain = Chain.Aptos, - balanceService = balancesService - ) - - val result = runBlocking { - client.getNativeBalance(Chain.Aptos, "0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f") - } - assertNotNull(result) - assertEquals("0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f", balancesService.nativeRequest) - assertEquals("100000000", result!!.balance.available) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.staked) - assertEquals("0", result.balance.rewards) - assertEquals("0", result.balance.reserved) - assertEquals("0", result.balance.pending) - assertEquals(1.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(0.0, result.balanceAmount.reserved) - assertEquals(0.0, result.balanceAmount.pending) - assertEquals(1.0, result.totalAmount) - assertEquals(AssetId(Chain.Aptos).toIdentifier(), result.asset.id.toIdentifier()) - } - - @Test - fun testAptosBalanceFail() { - val balanceService = TestAptosBalancesService() - val client = AptosBalanceClient( - chain = Chain.Aptos, - balanceService = balanceService - ) - - runBlocking { - val result = client.getNativeBalance(Chain.Aptos, "0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f") - assertNull(result) - } - } - - @Test - fun testAptosBalanceBadValue() { - val balanceService = TestAptosBalancesService(nativeBalance = "0abcde") - val client = AptosBalanceClient( - chain = Chain.Aptos, - balanceService = balanceService - ) - - runBlocking { - val result = client.getNativeBalance(Chain.Aptos, "0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f") - assertNull(result) - } - } - - @Test - fun testAptosBalanceEmpty() { - val balanceService = TestAptosBalancesService(nativeBalance = "0") - val client = AptosBalanceClient( - chain = Chain.Aptos, - balanceService = balanceService - ) - - val result = runBlocking { - client.getNativeBalance( - Chain.Aptos, - "0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f" - ) - } - 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("0", 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(0.0, result.balanceAmount.reserved) - assertEquals(0.0, result.balanceAmount.pending) - assertEquals(0.0, result.totalAmount) - assertEquals(AssetId(Chain.Aptos).toIdentifier(), result.asset.id.toIdentifier()) - } - - @Test - fun testAptos_tokens_balance() { - val balanceService = TestAptosBalancesService( - nativeBalance = "0", - ) - val assets = listOf( - Asset( - AssetId(Chain.Aptos, "0xe4ccb6d39136469f376242c31b34d10515c8eaaa38092f804db8e08a8f53c5b2::assets_v1::EchoCoin002"), - decimals = 6, - name = "Gui Inu", - symbol = "GUI", - type = AssetType.TOKEN - ), - Asset( - AssetId(Chain.Aptos, "0x159df6b7689437016108a019fd5bef736bac692b6d4a1f10c941f6fbb9a74ca6::oft::CakeOFT"), - decimals = 8, - name = "PancakeSwap Token", - symbol = "CAKE", - type = AssetType.TOKEN - ), - ) - val client = AptosBalanceClient( - chain = Chain.Aptos, - balanceService = balanceService - ) - - val result = runBlocking { - client.getTokenBalances( - Chain.Aptos, - "0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f", - assets, - ) - } - assertNotNull(result) - assertTrue(result.isNotEmpty()) - assertEquals(assets[0].id.toIdentifier(), result[0].asset.id.toIdentifier()) - assertEquals("30000000", result[0].balance.available) - assertEquals(30.0, result[0].balanceAmount.available) - assertEquals(assets[1].id.toIdentifier(), result[1].asset.id.toIdentifier()) - assertEquals("50000000", result[1].balance.available) - assertEquals(0.5, result[1].balanceAmount.available) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBalancesService.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBalancesService.kt deleted file mode 100644 index cf5c78cb2..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBalancesService.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.aptos.services.AptosBalancesService -import com.wallet.core.blockchain.aptos.AptosResource -import com.wallet.core.blockchain.aptos.AptosResourceBalanceOptional -import com.wallet.core.blockchain.aptos.AptosResourceCoin -import okhttp3.ResponseBody -import okhttp3.ResponseBody.Companion.toResponseBody - -class TestAptosBalancesService( - val nativeBalance: String? = null, -) : AptosBalancesService { - - var nativeRequest: String? = null - var tokenRequest: String? = null - - override suspend fun balance(address: String, assetType: String): ResponseBody { - nativeRequest = address - nativeBalance ?: throw Exception() - return nativeBalance.toResponseBody() - } - override suspend fun resources(address: String): List> { - tokenRequest = address - return listOf( - AptosResource( - type = "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", - AptosResourceBalanceOptional( - AptosResourceCoin( - "10000000" - ) - ) - ), - AptosResource( - type = "0x1::coin::CoinStore<0xe4ccb6d39136469f376242c31b34d10515c8eaaa38092f804db8e08a8f53c5b2::assets_v1::EchoCoin002>", - AptosResourceBalanceOptional( - AptosResourceCoin( - "30000000" - ) - ) - ), - AptosResource( - type = "0x1::coin::CoinStore<0x159df6b7689437016108a019fd5bef736bac692b6d4a1f10c941f6fbb9a74ca6::oft::CakeOFT>", - AptosResourceBalanceOptional( - AptosResourceCoin( - "50000000" - ) - ) - ), - ) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinBalance.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinBalance.kt deleted file mode 100644 index f6437ae33..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinBalance.kt +++ /dev/null @@ -1,146 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinBalancesService -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.ext.toIdentifier -import com.wallet.core.blockchain.bitcoin.BitcoinAccount -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertNotNull -import junit.framework.TestCase.assertNull -import kotlinx.coroutines.runBlocking -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class TestBitcoinBalance { - - companion object { - init { - includeLibs() - } - } - - @Test - fun testBitcoinBalance() { - val client = BitcoinBalanceClient( - chain = Chain.Bitcoin, - balanceService = object : BitcoinBalancesService { - override suspend fun balance(address: String): Result { - assertEquals("bc1qqypy0q4uwk8h845j8qc5r76zyk2fwdtvqy4s4x", address) - return Result.success(BitcoinAccount(balance = "100000000")) - } - } - ) - - val result = runBlocking { - client.getNativeBalance(Chain.Bitcoin, "bc1qqypy0q4uwk8h845j8qc5r76zyk2fwdtvqy4s4x") - } - assertNotNull(result) - assertEquals("100000000", result!!.balance.available) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.staked) - assertEquals("0", result.balance.rewards) - assertEquals("0", result.balance.reserved) - assertEquals("0", result.balance.pending) - assertEquals(1.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(0.0, result.balanceAmount.reserved) - assertEquals(0.0, result.balanceAmount.pending) - assertEquals(1.0, result.totalAmount) - assertEquals(AssetId(Chain.Bitcoin).toIdentifier(), result.asset.id.toIdentifier()) - } - - @Test - fun testBitcoincacheBalance() { - var requestAddress: String? = null - val client = BitcoinBalanceClient( - chain = Chain.Bitcoin, - balanceService = object : BitcoinBalancesService { - override suspend fun balance(address: String): Result { - requestAddress = address - return Result.success(BitcoinAccount(balance = "100000000")) - } - } - ) - - runBlocking { - client.getNativeBalance(Chain.BitcoinCash, "qq29xrkkd68alnrca375qlfyhwdqdkevsvmgkq9cmw") - } - assertEquals("bitcoincash:qq29xrkkd68alnrca375qlfyhwdqdkevsvmgkq9cmw", requestAddress) - } - - @Test - fun testBitcoinBalanceFail() { - val client = BitcoinBalanceClient( - chain = Chain.Bitcoin, - balanceService = object : BitcoinBalancesService { - override suspend fun balance(address: String): Result { - return Result.failure(Exception()) - } - } - ) - - runBlocking { - val result = client.getNativeBalance(Chain.Bitcoin, "bc1qqypy0q4uwk8h845j8qc5r76zyk2fwdtvqy4s4x") - assertNull(result) - } - } - - @Test - fun testBitcoinBalanceBadValue() { - val client = BitcoinBalanceClient( - chain = Chain.Bitcoin, - balanceService = object : BitcoinBalancesService { - override suspend fun balance(address: String): Result { - return Result.success(BitcoinAccount("0abcdesdf")) - } - } - ) - - runBlocking { - val result = client.getNativeBalance(Chain.Bitcoin, "bc1qqypy0q4uwk8h845j8qc5r76zyk2fwdtvqy4s4x") - assertNull(result) - } - } - - @Test - fun testBitcoinBalanceEmpty() { - val client = BitcoinBalanceClient( - chain = Chain.Bitcoin, - balanceService = object : BitcoinBalancesService { - override suspend fun balance(address: String): Result { - return Result.success(BitcoinAccount("0")) - } - - } - ) - - runBlocking { - val result = client.getNativeBalance(Chain.Bitcoin, "bc1qqypy0q4uwk8h845j8qc5r76zyk2fwdtvqy4s4x") - 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("0", 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(0.0, result.balanceAmount.reserved) - assertEquals(0.0, result.balanceAmount.pending) - assertEquals(0.0, result.totalAmount) - assertEquals(AssetId(Chain.Bitcoin).toIdentifier(), result.asset.id.toIdentifier()) - } - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSIgnerPreloader.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSIgnerPreloader.kt deleted file mode 100644 index 27f7ed693..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSIgnerPreloader.kt +++ /dev/null @@ -1,108 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin - -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinFeeService -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinUTXOService -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.ext.asset -import com.gemwallet.android.ext.toIdentifier -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.DestinationAddress -import com.wallet.core.blockchain.bitcoin.BitcoinFeeResult -import com.wallet.core.blockchain.bitcoin.BitcoinUTXO -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import junit.framework.TestCase.assertEquals -import kotlinx.coroutines.runBlocking -import org.junit.Test -import java.math.BigInteger - -class TestBitcoinSignerPreloader { - - companion object { - init { - includeLibs() - } - } - - @Test - fun testBitcoinMinimumByteFee() { - assertEquals(BitcoinFeeCalculator.getMinimumByteFee(Chain.Bitcoin), BigInteger.ONE) - assertEquals(BitcoinFeeCalculator.getMinimumByteFee(Chain.Litecoin), BigInteger.valueOf(5)) - assertEquals(BitcoinFeeCalculator.getMinimumByteFee(Chain.Doge), BigInteger.valueOf(1000)) - } - - @Test - fun testBitcoinPreloader() { - var requestAddress = "" - val preloader = BitcoinSignerPreloader( - Chain.Bitcoin, - object : BitcoinUTXOService { - override suspend fun getUTXO(address: String): Result> { - requestAddress = address - - return Result.success( - listOf( - BitcoinUTXO( - txid = "9f47e5d5ae3dac0662766f95d0cdda9c242c08d6baac4ce5d82464cf948abd53", - vout = 1, - value = "86055170", - ) - ) - ) - } - - }, - object : BitcoinFeeService { - override suspend fun estimateFee(priority: String): Result { - val value = when (priority) { - "8" -> "0.17457567" - "4" -> "0.17457567" - "2" -> "0.60356369" - else -> return Result.failure(Exception("Incorrect priority")) - } - return Result.success(BitcoinFeeResult(value)) - } - } - ) - val result = runBlocking { - preloader.preloadNativeTransfer( - params = ConfirmParams.TransferParams.Native( - asset = Chain.Bitcoin.asset(), - from = Account( - Chain.Doge, - "DDyZeg24eU3csLa7LMWrZEoqnHXccz6c94", - "", - "dgub8rNuTi8ofZu1jVDKpBxW9VFo62kjjx3b6CcameEZnrNNHJ3sKCnWBxQSv6qAP6jrwZEpfT1ZdKsrcBFKGTMV8zgBtjZmvQt29VPnLzbHjjD" - ), - amount = BigInteger.valueOf(10_000_000_000), - destination = DestinationAddress("D8UBj4EfNfNWNCdnCSgpY48yZDqPdTZXWW"), - isMaxAmount = false - ) - ) - } - assertEquals("DDyZeg24eU3csLa7LMWrZEoqnHXccz6c94", requestAddress) - assertEquals(BigInteger.valueOf(10_000_000_000), result.input.amount) - assertEquals("DDyZeg24eU3csLa7LMWrZEoqnHXccz6c94", result.input.from.address) - assertEquals(AssetId(Chain.Bitcoin).toIdentifier(), result.input.assetId.toIdentifier()) - assertEquals(false, result.input.isMax()) - assertEquals("D8UBj4EfNfNWNCdnCSgpY48yZDqPdTZXWW", result.input.destination()?.address) - assertEquals(null, result.input.memo()) - assertEquals(BigInteger.valueOf(3351936), result.chainData.fee().amount) - assertEquals(BigInteger.valueOf(17458), result.chainData.gasFee().maxGasPrice) - assertEquals(BigInteger.valueOf(192), result.chainData.gasFee().limit) - assertEquals(AssetId(Chain.Doge).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) - assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals("9f47e5d5ae3dac0662766f95d0cdda9c242c08d6baac4ce5d82464cf948abd53", (result.chainData as BitcoinSignerPreloader.BitcoinChainData).utxo[0].txid) - assertEquals(1, (result.chainData as BitcoinSignerPreloader.BitcoinChainData).utxo[0].vout) - assertEquals("86055170", (result.chainData as BitcoinSignerPreloader.BitcoinChainData).utxo[0].value) - assertEquals(3, result.chainData.allFee().size) - assertEquals(BigInteger.valueOf(192), result.chainData.gasFee(FeePriority.Fast).limit) - assertEquals(BigInteger.valueOf(60357), result.chainData.gasFee(FeePriority.Fast).maxGasPrice) - assertEquals(BigInteger.valueOf(11588544), result.chainData.gasFee(FeePriority.Fast).amount) - assertEquals(BigInteger.valueOf(192), result.chainData.gasFee(FeePriority.Slow).limit) - assertEquals(BigInteger.valueOf(17458), result.chainData.gasFee(FeePriority.Slow).maxGasPrice) - assertEquals(BigInteger.valueOf(3351936), result.chainData.gasFee(FeePriority.Slow).amount) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosBalances.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosBalances.kt deleted file mode 100644 index 8b93e4f3d..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosBalances.kt +++ /dev/null @@ -1,328 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosBalancesService -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosStakeService -import com.gemwallet.android.ext.toIdentifier -import com.wallet.core.blockchain.cosmos.CosmosBalance -import com.wallet.core.blockchain.cosmos.CosmosBalances -import com.wallet.core.blockchain.cosmos.CosmosDelegation -import com.wallet.core.blockchain.cosmos.CosmosDelegationData -import com.wallet.core.blockchain.cosmos.CosmosDelegations -import com.wallet.core.blockchain.cosmos.CosmosReward -import com.wallet.core.blockchain.cosmos.CosmosRewards -import com.wallet.core.blockchain.cosmos.CosmosUnboudingDelegationEntry -import com.wallet.core.blockchain.cosmos.CosmosUnboundingDelegation -import com.wallet.core.blockchain.cosmos.CosmosUnboundingDelegations -import com.wallet.core.blockchain.cosmos.CosmosValidators -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 -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class TestCosmosBalances { - - private class TestCosmosStakeService( - val delegations: List = emptyList(), - val unboundings: List = emptyList(), - val rewards: List = emptyList(), - ) : CosmosStakeService { - - var delegationsAddressRequest: String = "" - var unboundingAddressRequest: String = "" - var rewardsAddressRequest: String = "" - - override suspend fun validators(): Result { - return Result.success(CosmosValidators(emptyList())) - } - - override suspend fun delegations(address: String): Result { - delegationsAddressRequest = address - return Result.success(CosmosDelegations(delegations)) - } - - override suspend fun undelegations(address: String): Result { - unboundingAddressRequest = address - return Result.success(CosmosUnboundingDelegations(unboundings)) - } - - override suspend fun rewards(address: String): Result { - rewardsAddressRequest = address - return Result.success(CosmosRewards(rewards)) - } - - } - - @Test - fun testCosmosBalance() { - var ownerRequest: String = "" - val balanceService = object : CosmosBalancesService { - override suspend fun getBalance(owner: String): Result { - ownerRequest = owner - return Result.success( - CosmosBalances( - listOf( - CosmosBalance(denom = "uosmo", amount = "5272821") - ) - ) - ) - } - } - - val result = runBlocking { - CosmosBalanceClient( - Chain.Osmosis, - balancesService = balanceService, - stakeService = TestCosmosStakeService(), - ).getNativeBalance(Chain.Osmosis, "osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v") - } - assertEquals("osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v", ownerRequest) - assertNotNull(result) - assertEquals("5272821", result!!.balance.available) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.staked) - assertEquals("0", result.balance.rewards) - assertEquals("0", result.balance.reserved) - assertEquals("0", result.balance.pending) - assertEquals(5.272821, 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(0.0, result.balanceAmount.reserved) - assertEquals(0.0, result.balanceAmount.pending) - assertEquals(5.272821, result.totalAmount) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.asset.id.toIdentifier()) - } - - @Test - fun testCosmosBalanceStakeOnly() { - var ownerRequest: String = "" - val balanceService = object : CosmosBalancesService { - override suspend fun getBalance(owner: String): Result { - ownerRequest = owner - return Result.success(CosmosBalances(listOf())) - } - } - - val stakeService = TestCosmosStakeService( - delegations = listOf( - CosmosDelegation( - CosmosDelegationData("osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm"), - CosmosBalance("uosmo", "1000000") - ), - CosmosDelegation( - CosmosDelegationData("osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2"), - CosmosBalance("uosmo", "1000000") - ), - CosmosDelegation( - CosmosDelegationData("osmovaloper1wgmdcxzp49vjgrqusgcagq6qefk4mtjv5c0k7q"), - CosmosBalance("uosmo", "721000000") - ) - ) - ) - - val result = runBlocking { - CosmosBalanceClient( - Chain.Osmosis, - balancesService = balanceService, - stakeService = stakeService, - ).getNativeBalance(Chain.Osmosis, "osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v") - } - assertEquals("osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v", ownerRequest) - assertNotNull(result) - assertEquals("0", result!!.balance.available) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.locked) - assertEquals("723000000", result.balance.staked) - assertEquals("0", result.balance.rewards) - assertEquals("0", 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(723.0, result.balanceAmount.staked) - assertEquals(0.0, result.balanceAmount.rewards) - assertEquals(0.0, result.balanceAmount.reserved) - assertEquals(0.0, result.balanceAmount.pending) - assertEquals(723.0, result.totalAmount) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.asset.id.toIdentifier()) - } - - @Test - fun testCosmosBalanceUnboundingOnly() { - var ownerRequest: String = "" - val balanceService = object : CosmosBalancesService { - override suspend fun getBalance(owner: String): Result { - ownerRequest = owner - return Result.success(CosmosBalances(listOf())) - } - } - val stakeService = TestCosmosStakeService( - unboundings = listOf( - CosmosUnboundingDelegation( - "osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", - entries = listOf( - CosmosUnboudingDelegationEntry( - creation_height = "25053096", - completion_time = "2024-12-18T02:11:27.650773866Z", - balance = "2000000", - ) - ) - ), - ) - ) - - val result = runBlocking { - CosmosBalanceClient( - Chain.Osmosis, - balancesService = balanceService, - stakeService = stakeService, - ).getNativeBalance(Chain.Osmosis, "osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v") - } - assertEquals("osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v", ownerRequest) - 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("0", result.balance.reserved) - assertEquals("2000000", 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(0.0, result.balanceAmount.reserved) - assertEquals(2.0, result.balanceAmount.pending) - assertEquals(2.0, result.totalAmount) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.asset.id.toIdentifier()) - } - - @Test - fun testCosmosBalanceRewardsOnly() { - var ownerRequest: String = "" - val balanceService = object : CosmosBalancesService { - override suspend fun getBalance(owner: String): Result { - ownerRequest = owner - return Result.success(CosmosBalances(listOf())) - } - } - val stakeService = TestCosmosStakeService( - rewards = listOf( - CosmosReward("osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", listOf(CosmosBalance(denom = "uosmo", amount = "808.015913259210000000"))), - CosmosReward("osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2", listOf(CosmosBalance(denom = "uosmo", amount = "808.009961413523000000"))), - CosmosReward("osmovaloper1wgmdcxzp49vjgrqusgcagq6qefk4mtjv5c0k7q", listOf(CosmosBalance(denom = "uosmo", amount = "582579.692713670953000000"))), - ) - ) - - val result = runBlocking { - CosmosBalanceClient( - Chain.Osmosis, - balancesService = balanceService, - stakeService = stakeService, - ).getNativeBalance(Chain.Osmosis, "osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v") - } - assertEquals("osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v", ownerRequest) - assertNotNull(result) - assertEquals("0", result!!.balance.available) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.staked) - assertEquals("584195", result.balance.rewards) - assertEquals("0", 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.584195, result.balanceAmount.rewards) - assertEquals(0.0, result.balanceAmount.reserved) - assertEquals(0.0, result.balanceAmount.pending) - assertEquals(0.584195, result.totalAmount) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.asset.id.toIdentifier()) - } - - @Test - fun testCosmosBalanceFull() { - var ownerRequest: String = "" - val balanceService = object : CosmosBalancesService { - override suspend fun getBalance(owner: String): Result { - ownerRequest = owner - return Result.success( - CosmosBalances( - listOf( - CosmosBalance(denom = "uosmo", amount = "5272821") - ) - ) - ) - } - } - - val stakeService = TestCosmosStakeService( - delegations = listOf( - CosmosDelegation( - CosmosDelegationData("osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm"), - CosmosBalance("uosmo", "1000000") - ), - CosmosDelegation( - CosmosDelegationData("osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2"), - CosmosBalance("uosmo", "1000000") - ), - CosmosDelegation( - CosmosDelegationData("osmovaloper1wgmdcxzp49vjgrqusgcagq6qefk4mtjv5c0k7q"), - CosmosBalance("uosmo", "721000000") - ) - ), - unboundings = listOf( - CosmosUnboundingDelegation( - "osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", - entries = listOf( - CosmosUnboudingDelegationEntry( - creation_height = "25053096", - completion_time = "2024-12-18T02:11:27.650773866Z", - balance = "2000000", - ) - ) - ), - ), - rewards = listOf( - CosmosReward("osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", listOf(CosmosBalance(denom = "uosmo", amount = "808.015913259210000000"))), - CosmosReward("osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2", listOf(CosmosBalance(denom = "uosmo", amount = "808.009961413523000000"))), - CosmosReward("osmovaloper1wgmdcxzp49vjgrqusgcagq6qefk4mtjv5c0k7q", listOf(CosmosBalance(denom = "uosmo", amount = "582579.692713670953000000"))), - ) - ) - - val result = runBlocking { - CosmosBalanceClient( - Chain.Osmosis, - balancesService = balanceService, - stakeService = stakeService, - ).getNativeBalance(Chain.Osmosis, "osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v") - } - assertEquals("osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v", ownerRequest) - assertNotNull(result) - assertEquals("5272821", result!!.balance.available) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.locked) - assertEquals("723000000", result.balance.staked) - assertEquals("584195", result.balance.rewards) - assertEquals("0", result.balance.reserved) - assertEquals("2000000", result.balance.pending) - assertEquals(5.272821, result.balanceAmount.available) - assertEquals(0.0, result.balanceAmount.frozen) - assertEquals(0.0, result.balanceAmount.locked) - assertEquals(723.0, result.balanceAmount.staked) - assertEquals(0.584195, result.balanceAmount.rewards) - assertEquals(0.0, result.balanceAmount.reserved) - assertEquals(2.0, result.balanceAmount.pending) - assertEquals(730.857016, result.totalAmount) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.asset.id.toIdentifier()) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaAccountsService.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaAccountsService.kt deleted file mode 100644 index 5399f416e..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaAccountsService.kt +++ /dev/null @@ -1,86 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.solana.models.SolanaArrayData -import com.gemwallet.android.blockchain.clients.solana.models.SolanaInfo -import com.gemwallet.android.blockchain.clients.solana.models.SolanaParsedData -import com.gemwallet.android.blockchain.clients.solana.models.SolanaParsedSplTokenInfo -import com.gemwallet.android.blockchain.clients.solana.services.SolanaAccountsService -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.solana.SolanaAccount -import com.wallet.core.blockchain.solana.SolanaAccountParsed -import com.wallet.core.blockchain.solana.SolanaAccountParsedInfo -import com.wallet.core.blockchain.solana.SolanaTokenAccount -import com.wallet.core.blockchain.solana.SolanaTokenAmount -import com.wallet.core.blockchain.solana.SolanaTokenInfo -import com.wallet.core.blockchain.solana.SolanaValue - -internal class TestSolanaAccountsService( - private val tokenAddress: String? = null, - private val owner: String = "", -) : SolanaAccountsService { - var tokenAccountRequest: JSONRpcRequest>? = null - - override suspend fun getTokenAccountByOwner(request: JSONRpcRequest>): JSONRpcResponse>> { - tokenAccountRequest = request - return JSONRpcResponse( - SolanaValue( - listOf( - SolanaTokenAccount( - pubkey = tokenAddress ?: "", - account = SolanaAccount( - lamports = 100000, - space = 10, - owner = owner, - SolanaAccountParsed( - SolanaAccountParsedInfo( - SolanaTokenInfo( - SolanaTokenAmount(tokenAddress ?: (request.params[1] as Map<*, *>)["mint"].toString()) - ) - ) - ) - ) - ), - ) - ) - ) - } - - override suspend fun batchAccount(request: List>>): List>>> { - return request.mapIndexed { index, request -> - JSONRpcResponse( - SolanaValue( - listOf( - SolanaTokenAccount( - pubkey = tokenAddress ?: "", - account = SolanaAccount( - lamports = 100000, - space = 10, - owner = owner, - data = SolanaAccountParsed( - SolanaAccountParsedInfo( - SolanaTokenInfo( - SolanaTokenAmount(((index + 1) * 10000000).toString()) - ) - ) - ) - ) - ) - ) - ) - ) - } - } - - override suspend fun getAccountInfoSpl(request: JSONRpcRequest>): JSONRpcResponse>>> { - TODO("Not yet implemented") - } - - override suspend fun getAccountInfoMpl(request: JSONRpcRequest>): JSONRpcResponse>> { - TODO("Not yet implemented") - } - - override suspend fun getTokenInfo(request: JSONRpcRequest>): JSONRpcResponse> { - TODO("Not yet implemented") - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaBalances.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaBalances.kt deleted file mode 100644 index cec76dad0..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaBalances.kt +++ /dev/null @@ -1,299 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.solana.services.SolanaBalancesService -import com.gemwallet.android.blockchain.clients.solana.services.SolanaStakeService -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.gemwallet.android.model.getTotalAmount -import com.wallet.core.blockchain.solana.SolanaAccount -import com.wallet.core.blockchain.solana.SolanaAccountParsed -import com.wallet.core.blockchain.solana.SolanaAccountParsedInfo -import com.wallet.core.blockchain.solana.SolanaBalance -import com.wallet.core.blockchain.solana.SolanaBalanceValue -import com.wallet.core.blockchain.solana.SolanaEpoch -import com.wallet.core.blockchain.solana.SolanaRentExemptReserve -import com.wallet.core.blockchain.solana.SolanaStake -import com.wallet.core.blockchain.solana.SolanaStakeAccount -import com.wallet.core.blockchain.solana.SolanaStakeDelegation -import com.wallet.core.blockchain.solana.SolanaStakeInfo -import com.wallet.core.blockchain.solana.SolanaValidator -import com.wallet.core.blockchain.solana.SolanaValidators -import com.wallet.core.blockchain.solana.SolanaValue -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -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 TestSolanaBalances { - - companion object { - init { - includeLibs() - } - } - - private class TestBalancesService : SolanaBalancesService { - var nativeRequest: JSONRpcRequest>? = null - var tokenRequest: JSONRpcRequest>? = null - - override suspend fun getBalance(request: JSONRpcRequest>): Result> { - nativeRequest = request - return Result.success( - JSONRpcResponse( - SolanaBalance(1_000_000) - ) - ) - } - - override suspend fun getTokenBalance(request: JSONRpcRequest>): Result>> { - tokenRequest = request - return Result.success( - JSONRpcResponse( - SolanaValue( - SolanaBalanceValue( - when (request.params[0]) { - "HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3" -> "5000000" - else -> "300000" - } - ) - ) - ) - ) - } - } - - private class TestStakeService( - private val delegationsResponse: JSONRpcResponse> = JSONRpcResponse(emptyList()) - ) : SolanaStakeService { - var validatorsRequest: JSONRpcRequest>? = null - var delegationsRequest: JSONRpcRequest>? = null - - override suspend fun validators(request: JSONRpcRequest>): Result> { - validatorsRequest = request - return Result.success( - JSONRpcResponse( - SolanaValidators( - listOf( - SolanaValidator("validatorPubKey", 10, true) - ) - ) - ) - ) - } - - override suspend fun delegations(request: JSONRpcRequest>): Result>> { - delegationsRequest = request - - return Result.success(delegationsResponse) - } - - override suspend fun epoch(request: JSONRpcRequest>): Result> { - return Result.success( - JSONRpcResponse( - SolanaEpoch( - epoch = 10, - slotsInEpoch = 1, - slotIndex = 1, - ) - ) - ) - } - } - - @Test - fun testSolana_balance_native() { - val accountsService = TestSolanaAccountsService() - val balancesService = TestBalancesService() - val stakeService = TestStakeService() - - val balanceClient = SolanaBalanceClient( - chain = Chain.Solana, - accountsService = accountsService, - balancesService = balancesService, - stakeService = stakeService, - ) - val result = runBlocking { - balanceClient.getNativeBalance(Chain.Solana, "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh") - } - assertEquals("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh", balancesService.nativeRequest!!.params[0]) - assertNotNull(result) - assertEquals(AssetId(Chain.Solana), result!!.asset.id) - assertEquals("1000000", result.balance.available) - assertEquals("0", result.balance.staked) - assertEquals("0", result.balance.pending) - assertEquals("0", result.balance.reserved) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.rewards) - } - - @Test - fun testSolana_balance_token() { - val accountsService = TestSolanaAccountsService() - val balancesService = TestBalancesService() - val stakeService = TestStakeService() - - val balanceClient = SolanaBalanceClient( - chain = Chain.Solana, - accountsService = accountsService, - balancesService = balancesService, - stakeService = stakeService, - ) - val result = runBlocking { - balanceClient.getTokenBalances( - Chain.Solana, - "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh", - listOf( - Asset( - id = AssetId(Chain.Solana, "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"), - name = "Jupiter", - symbol = "JUP", - decimals = 6, - type = AssetType.TOKEN, - ), - Asset( - id = AssetId(Chain.Solana, "HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3"), - name = "Pyth Network ", - symbol = "PYTH", - decimals = 6, - type = AssetType.TOKEN, - ), - ) - ) - } - assertNotNull(result) - assertEquals(2, result.size) - assertEquals(AssetId(Chain.Solana, "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"), result[0].asset.id) - assertEquals(AssetId(Chain.Solana, "HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3"), result[1].asset.id) - assertEquals("10000000", result[0].balance.available) - assertEquals("20000000", result[1].balance.available) - } - - @Test - fun testSolana_balance_native_width_single_stake() { - val accountsService = TestSolanaAccountsService() - val balancesService = TestBalancesService() - val stakeService = TestStakeService( - delegationsResponse = JSONRpcResponse( - listOf( - SolanaStakeAccount( - pubkey = "", - account = SolanaAccount( - lamports = 1000000L, - space = 10, - owner = "", - data = SolanaAccountParsed( - SolanaAccountParsedInfo( - SolanaStakeInfo( - SolanaStake( - SolanaStakeDelegation("", "", "", ""), - ), - SolanaRentExemptReserve("") - ) - ) - ) - ) - ) - ) - - ) - ) - - val balanceClient = SolanaBalanceClient( - chain = Chain.Solana, - accountsService = accountsService, - balancesService = balancesService, - stakeService = stakeService, - ) - val result = runBlocking { - balanceClient.getDelegationBalances(Chain.Solana, "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh") - } - assertNotNull(result) - assertEquals(AssetId(Chain.Solana), result!!.asset.id) - assertEquals("0", result.balance.available) - assertEquals("1000000", result.balance.staked) - assertEquals("0", result.balance.pending) - assertEquals("0", result.balance.reserved) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.rewards) - assertEquals(0.0, result.balanceAmount.available) - assertEquals(0.001, result.balanceAmount.staked) - assertEquals(0.001, result.balanceAmount.getTotalAmount()) - } - - @Test - fun testSolana_balance_native_width_multi_stake() { - val accountsService = TestSolanaAccountsService() - val balancesService = TestBalancesService() - val stakeService = TestStakeService( - delegationsResponse = JSONRpcResponse( - listOf( - SolanaStakeAccount( - pubkey = "", - account = SolanaAccount( - lamports = 1000000L, - space = 10, - owner = "", - data = SolanaAccountParsed( - SolanaAccountParsedInfo( - SolanaStakeInfo( - SolanaStake( - SolanaStakeDelegation("", "", "", ""), - ), - SolanaRentExemptReserve("") - ) - ) - ) - ) - ), - SolanaStakeAccount( - pubkey = "", - account = SolanaAccount( - lamports = 2000000, - space = 20, - owner = "", - data = SolanaAccountParsed( - SolanaAccountParsedInfo( - SolanaStakeInfo( - SolanaStake( - SolanaStakeDelegation("", "", "", ""), - ), - SolanaRentExemptReserve("") - ) - ) - ) - ) - ) - ) - ) - ) - - val balanceClient = SolanaBalanceClient( - chain = Chain.Solana, - accountsService = accountsService, - balancesService = balancesService, - stakeService = stakeService, - ) - val result = runBlocking { - balanceClient.getDelegationBalances(Chain.Solana, "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh") - } - assertNotNull(result) - assertEquals(AssetId(Chain.Solana), result!!.asset.id) - assertEquals("0", result.balance.available) - assertEquals("3000000", result.balance.staked) - assertEquals("0", result.balance.pending) - assertEquals("0", result.balance.reserved) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.rewards) - assertEquals(0.0, result.balanceAmount.available) - assertEquals(0.003, result.balanceAmount.staked) - assertEquals(0.003, result.balanceAmount.getTotalAmount()) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaFeeCalculation.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaFeeCalculation.kt deleted file mode 100644 index 0c2dc7496..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaFeeCalculation.kt +++ /dev/null @@ -1,103 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.DestinationAddress -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain -import junit.framework.TestCase.assertEquals -import kotlinx.coroutines.runBlocking -import org.junit.Test -import java.math.BigInteger - -class TestSolanaFeeCalculation { - companion object { - init { - includeLibs() - } - } - - @Test - fun testSolana_calculate_native_fee() { - val feeCalculator = SolanaFeeCalculator(TestSolanaFeeService()) - - val result = runBlocking { - feeCalculator.calculate( - ConfirmParams.Builder( - asset = Chain.Solana.asset(), - from = Account(Chain.Solana, "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh", ""), - amount = BigInteger.valueOf(10_000_000) - ).transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) - ) - } - assertEquals(BigInteger("100005000"), result[1].amount) - assertEquals(BigInteger("1000000000"), result[1].minerFee) - assertEquals(BigInteger("5000"), result[1].maxGasPrice) - assertEquals(BigInteger("100000"), result[1].limit) - assertEquals(BigInteger("30"), result[1].options["tokenAccountCreation"]) - } - - @Test - fun testSolana_calculate_native_fee_without_priority_fee() { - val feeCalculator = SolanaFeeCalculator(TestSolanaFeeService(fees = emptyList())) - - val result = runBlocking { - feeCalculator.calculate( - ConfirmParams.Builder( - asset = Chain.Solana.asset(), - from = Account(Chain.Solana, "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh", ""), - amount = BigInteger.valueOf(10_000_000) - ).transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) - ) - } - assertEquals(BigInteger("10000"), result[1].amount) - assertEquals(BigInteger("50000"), result[1].minerFee) - assertEquals(BigInteger("5000"), result[1].maxGasPrice) - assertEquals(BigInteger("100000"), result[1].limit) - assertEquals(BigInteger("30"), result[1].options["tokenAccountCreation"]) - } - - @Test - fun testSolana_calculate_native_fee_without_create() { - val feeCalculator = SolanaFeeCalculator(TestSolanaFeeService(fees = emptyList())) - - val result = runBlocking { - feeCalculator.calculate( - ConfirmParams.Builder( - asset = Chain.Solana.asset(), - from = Account(Chain.Solana, "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh", ""), - amount = BigInteger.valueOf(10_000_000) - ).transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) - ) - } - assertEquals(BigInteger("10000"), result[1].amount) - assertEquals(BigInteger("50000"), result[1].minerFee) - assertEquals(BigInteger("5000"), result[1].maxGasPrice) - assertEquals(BigInteger("100000"), result[1].limit) - assertEquals(BigInteger("0"), result[1].options["tokenAccountCreation"]) - } - - @Test - fun testSolana_calculate_token_fee_without_create() { - val feeCalculator = SolanaFeeCalculator(TestSolanaFeeService(listOf(100, 200))) - - val result = runBlocking { - feeCalculator.calculate( - ConfirmParams.Builder( - asset = Asset(AssetId(Chain.Solana, "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"), name = "usdt", symbol = "usdt", decimals = 8, type = AssetType.TOKEN), - from = Account(Chain.Solana, "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh", ""), - amount = BigInteger.valueOf(10_000_000) - ).transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) - ) - } - assertEquals(BigInteger("15000"), result[1].amount) - assertEquals(BigInteger("100000"), result[1].minerFee) - assertEquals(BigInteger("5000"), result[1].maxGasPrice) - assertEquals(BigInteger("100000"), result[1].limit) - assertEquals(BigInteger("30"), result[1].options["tokenAccountCreation"]) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaFeeService.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaFeeService.kt deleted file mode 100644 index 5ce88aea8..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaFeeService.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.solana.services.SolanaFeeService -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.solana.SolanaPrioritizationFee - -internal class TestSolanaFeeService( - private val fees: List = listOf(100000000, 2000000000), -) : SolanaFeeService { - - override suspend fun getPriorityFees(request: JSONRpcRequest>): Result>> { - return Result.success(JSONRpcResponse(fees.map { SolanaPrioritizationFee(it) })) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSignPreloader.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSignPreloader.kt deleted file mode 100644 index 225f9dfcf..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSignPreloader.kt +++ /dev/null @@ -1,124 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.solana.services.SolanaNetworkInfoService -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.DestinationAddress -import com.wallet.core.blockchain.solana.SolanaBlockhash -import com.wallet.core.blockchain.solana.SolanaBlockhashResult -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.SolanaTokenProgramId -import junit.framework.TestCase.assertEquals -import kotlinx.coroutines.runBlocking -import org.junit.Test -import java.math.BigInteger - -class TestSolanaSignPreloader { - - companion object { - init { - includeLibs() - } - } - - private class TestSolanaNetworkInfoService( - val blockhash: String = "", - ) : SolanaNetworkInfoService { - - override suspend fun getBlockhash(request: JSONRpcRequest>): Result> { - return Result.success(JSONRpcResponse(SolanaBlockhashResult(SolanaBlockhash(blockhash)))) - } - - } - - @Test - fun testSolana_netive_transfer_preload() { - val preloader = SolanaSignerPreloader( - chain = Chain.Solana, - feeService = TestSolanaFeeService(), - networkInfoService = TestSolanaNetworkInfoService(blockhash = "123"), - accountsService = TestSolanaAccountsService(), - ) - - val result = runBlocking { - preloader.preloadNativeTransfer( - ConfirmParams.Builder( - asset = Chain.Solana.asset(), - from = Account(Chain.Solana, "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh", ""), - amount = BigInteger.valueOf(10_000_000) - ) - .transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) as ConfirmParams.TransferParams.Native - ) - } - assertEquals(BigInteger("100005000"), result.chainData.gasFee().amount) - assertEquals("123", (result.chainData as SolanaSignerPreloader.SolanaChainData).blockhash) - assertEquals(SolanaTokenProgramId.Token, (result.chainData as SolanaSignerPreloader.SolanaChainData).tokenProgram) - assertEquals(null, (result.chainData as SolanaSignerPreloader.SolanaChainData).recipientTokenAddress) - assertEquals("", (result.chainData as SolanaSignerPreloader.SolanaChainData).senderTokenAddress) - } - - @Test - fun testSolana_transfer_token_preload() { - val preloader = SolanaSignerPreloader( - chain = Chain.Solana, - feeService = TestSolanaFeeService(), - networkInfoService = TestSolanaNetworkInfoService(blockhash = "123"), - accountsService = TestSolanaAccountsService( - "DVWPV7brSbPDkA7a3qdn6UJsVc3J3DyhQhjNaZeZqwzo", - "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", - ), - ) - - val result = runBlocking { - preloader.preloadTokenTransfer( - ConfirmParams.Builder( - asset = Asset(AssetId(Chain.Solana, "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"), name = "usdt", symbol = "usdt", decimals = 8, type = AssetType.TOKEN), - from = Account(Chain.Solana, "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh", ""), - amount = BigInteger.valueOf(10_000_000) - ) - .transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) as ConfirmParams.TransferParams.Token - ) - } - assertEquals(BigInteger("100005000"), result.chainData.gasFee().amount) - assertEquals("123", (result.chainData as SolanaSignerPreloader.SolanaChainData).blockhash) - assertEquals(SolanaTokenProgramId.Token, (result.chainData as SolanaSignerPreloader.SolanaChainData).tokenProgram) - assertEquals("DVWPV7brSbPDkA7a3qdn6UJsVc3J3DyhQhjNaZeZqwzo", (result.chainData as SolanaSignerPreloader.SolanaChainData).recipientTokenAddress) - assertEquals("DVWPV7brSbPDkA7a3qdn6UJsVc3J3DyhQhjNaZeZqwzo", (result.chainData as SolanaSignerPreloader.SolanaChainData).senderTokenAddress) - } - - @Test - fun testSolana_transfer_token2022_preload() { - val preloader = SolanaSignerPreloader( - chain = Chain.Solana, - feeService = TestSolanaFeeService(), - networkInfoService = TestSolanaNetworkInfoService(blockhash = "123"), - accountsService = TestSolanaAccountsService( - "87vTugUvkkepa84mBRfENnvkPQRj5EZSkiG8XyFAhbQQ", - "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" - ), - ) - - val result = runBlocking { - preloader.preloadTokenTransfer( - ConfirmParams.Builder( - asset = Asset(AssetId(Chain.Solana, "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo"), name = "smt", symbol = "", decimals = 8, type = AssetType.TOKEN), - from = Account(Chain.Solana, "AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh", ""), - amount = BigInteger.valueOf(10_000_000) - ) - .transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) as ConfirmParams.TransferParams.Token - ) - } - assertEquals(BigInteger("100005000"), result.chainData.gasFee().amount) - assertEquals("123", (result.chainData as SolanaSignerPreloader.SolanaChainData).blockhash) - assertEquals(SolanaTokenProgramId.Token2022, (result.chainData as SolanaSignerPreloader.SolanaChainData).tokenProgram) - assertEquals("87vTugUvkkepa84mBRfENnvkPQRj5EZSkiG8XyFAhbQQ", (result.chainData as SolanaSignerPreloader.SolanaChainData).recipientTokenAddress) - assertEquals("87vTugUvkkepa84mBRfENnvkPQRj5EZSkiG8XyFAhbQQ", (result.chainData as SolanaSignerPreloader.SolanaChainData).senderTokenAddress) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt index 144dae779..517ea254b 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt @@ -1,5 +1,6 @@ package com.gemwallet.android.blockchain.clients.solana +import com.gemwallet.android.blockchain.clients.solana.models.SolanaChainData import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset @@ -51,7 +52,7 @@ class TestSolanaSigner { amount = BigInteger.valueOf(10_000_000) ) .transfer(destination = DestinationAddress("4Yu2e1Wz5T1Ci2hAPswDqvMgSnJ1Ftw7ZZh8x7xKLx7S")) as ConfirmParams.TransferParams.Native - val chainData = SolanaSignerPreloader.SolanaChainData( + val chainData = SolanaChainData( blockhash = "kiEPF6aKvEsj5nbi4FBvgRRm9ha36Y3cgDU9qnUKt32", fees = listOf( GasFee( @@ -100,7 +101,7 @@ class TestSolanaSigner { amount = BigInteger.valueOf(10_000_000) ) .transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) as ConfirmParams.TransferParams.Token - val chainData = SolanaSignerPreloader.SolanaChainData( + val chainData = SolanaChainData( blockhash = "kiEPF6aKvEsj5nbi4FBvgRRm9ha36Y3cgDU9qnUKt32", fees = listOf( GasFee( @@ -150,7 +151,7 @@ class TestSolanaSigner { amount = BigInteger.valueOf(10_000_000) ) .transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) as ConfirmParams.TransferParams.Token - val chainData = SolanaSignerPreloader.SolanaChainData( + val chainData = SolanaChainData( blockhash = "kiEPF6aKvEsj5nbi4FBvgRRm9ha36Y3cgDU9qnUKt32", fees = listOf( GasFee( diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronAccountService.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronAccountService.kt deleted file mode 100644 index 68094d89b..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronAccountService.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.clients.tron.services.TronAccountsService -import com.wallet.core.blockchain.tron.TronAccount -import com.wallet.core.blockchain.tron.TronAccountRequest -import com.wallet.core.blockchain.tron.TronAccountUsage - -class FakeTronAccountService( - private val tronAccount: TronAccount? = null -) : TronAccountsService { - var accountRequest: TronAccountRequest? = null - var usageRequest: TronAccountRequest? = null - - override suspend fun getAccount(addressRequest: TronAccountRequest): Result { - this.accountRequest = addressRequest - return Result.success(tronAccount ?: return Result.failure(Exception())) - } - - override suspend fun getAccountUsage(addressRequest: TronAccountRequest): Result { - this.usageRequest = addressRequest - - return Result.success( - TronAccountUsage( - freeNetUsed = 1, - freeNetLimit = 2, - ) - ) - } - - -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronCallService.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronCallService.kt deleted file mode 100644 index daa6a7a0b..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronCallService.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.clients.tron.services.TronCallService -import com.wallet.core.blockchain.tron.TronSmartContractResult - -class FakeTronCallService( - val responses: Map = emptyMap() -) : TronCallService { - val requests = mutableListOf>() - - override suspend fun triggerSmartContract(request: Any): Result { - requests.add(request as Map) - return Result.success(responses[request["contract_address"] ?: throw Exception()] - ?: return Result.failure(Exception())) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronNodeStatusService.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronNodeStatusService.kt deleted file mode 100644 index 9afc7fe6f..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronNodeStatusService.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.clients.tron.services.TronNodeStatusService -import com.wallet.core.blockchain.tron.TronBlock -import com.wallet.core.blockchain.tron.TronChainParameter -import com.wallet.core.blockchain.tron.TronChainParameters -import com.wallet.core.blockchain.tron.TronHeader -import com.wallet.core.blockchain.tron.TronHeaderRawData -import retrofit2.Response - -private val chainParamters = TronChainParameters( - listOf( - TronChainParameter("getCreateNewAccountFeeInSystemContract", 1000000), - TronChainParameter("getCreateAccountFee", 100000), - TronChainParameter("getEnergyFee", 210), - ) -) - -class FakeTronNodeStatusService( - private val chainParameters: TronChainParameters? = chainParamters, - private val tronBlock: TronBlock? = TronBlock( - TronHeaderRawData( - TronHeader( - number = 67978303, - version = 31, - txTrieRoot = "e02c6d0bab5f0c6d1f61051646535ed76f6e1ef0db5c32069cf612123ce976b3", - witness_address = "41c05142fd1ca1e03688a43585096866ae658f2cb2", - parentHash = "00000000040d443e37c9fcdfb11ba6fb9ed08682f0f492b3b4ab6639b9198694", - timestamp = 1734585603000, - ) - ) - ), -) : TronNodeStatusService { - - override suspend fun getChainParameters(): Result { - return Result.success(chainParameters ?: return Result.failure(Exception())) - } - - override suspend fun nowBlock(): Result { - return Result.success(tronBlock ?: return Result.failure(Exception())) - } - - override suspend fun nowBlock(url: String): Response { - TODO("Not yet implemented") - } - - -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronStakeService.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronStakeService.kt deleted file mode 100644 index c84a3f286..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/FakeTronStakeService.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.clients.tron.services.TronStakeService -import com.wallet.core.blockchain.tron.TronReward -import com.wallet.core.blockchain.tron.WitnessesList - -class FakeTronStakeService( - private val reward: Long? = null -) : TronStakeService { - var addressRequest: String? = null - - - override suspend fun listwitnesses(): Result { - TODO("Not yet implemented") - } - - override suspend fun getReward(address: String): Result { - addressRequest = address - return Result.success(TronReward(reward ?: return Result.failure(Exception()))) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronBalance.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronBalance.kt deleted file mode 100644 index 642d0fa79..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronBalance.kt +++ /dev/null @@ -1,197 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.includeLibs -import com.wallet.core.blockchain.tron.TronAccount -import com.wallet.core.blockchain.tron.TronFrozen -import com.wallet.core.blockchain.tron.TronSmartContractResult -import com.wallet.core.blockchain.tron.TronSmartContractResultMessage -import com.wallet.core.blockchain.tron.TronUnfrozen -import com.wallet.core.blockchain.tron.TronVote -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertNotNull -import junit.framework.TestCase.assertNull -import junit.framework.TestCase.assertTrue -import kotlinx.coroutines.runBlocking -import org.junit.Test - -class TestTronBalance { - companion object { - init { - includeLibs() - } - } - - val stakeService = FakeTronStakeService(0xF4240) - - @Test - fun testTron_native_balance_success_and_not_empty() { - val accountService = FakeTronAccountService( - TronAccount( - balance = 1_000_000, - ) - ) - val callService = FakeTronCallService() - val balanceClient = TronBalanceClient(Chain.Tron, accountService, callService, FakeTronStakeService()) - val result = runBlocking { balanceClient.getNativeBalance(Chain.Tron, "TNLmo9j9AuGnnxibQUT13xoMGuUmNwxtkU") } - assertEquals("TNLmo9j9AuGnnxibQUT13xoMGuUmNwxtkU", accountService.accountRequest?.address) - assertTrue(accountService.accountRequest!!.visible) - assertNotNull(result) - assertEquals(AssetId(Chain.Tron), result!!.asset.id) - assertEquals("1000000", result.balance.available) - assertEquals("0", result.balance.staked) - assertEquals("0", result.balance.pending) - assertEquals("0", result.balance.reserved) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.rewards) - assertEquals(1.0, result.balanceAmount.available) - assertEquals(1.0, result.totalAmount) - } - - @Test - fun testTron_native_balance_success_and_empty() { - val accountService = FakeTronAccountService( - TronAccount() - ) - val callService = FakeTronCallService() - val balanceClient = TronBalanceClient(Chain.Tron, accountService, callService, FakeTronStakeService()) - val result = runBlocking { balanceClient.getNativeBalance(Chain.Tron, "TNLmo9j9AuGnnxibQUT13xoMGuUmNwxtkU") } - assertNull(result) - } - - @Test - fun testTron_native_balance_fail() { - val accountService = FakeTronAccountService() - val callService = FakeTronCallService() - val balanceClient = TronBalanceClient(Chain.Tron, accountService, callService, stakeService) - val result = runBlocking { balanceClient.getNativeBalance(Chain.Tron, "") } - assertNull(result) - } - - @Test - fun testTron_token_balance_success() { - val assets = listOf( - Asset( - id = AssetId(Chain.Tron, "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"), - decimals = 6, - name = "Tether USD", - symbol = "USDT", - type = AssetType.TRC20, - ), - Asset( - id = AssetId(Chain.Tron, "TAFjULxiVgT4qWk6UZwjqwZXTSaGaqnVp4"), - decimals = 18, - name = "BitTorrent", - symbol = "BTT", - type = AssetType.TRC20, - ), - Asset( - id = AssetId(Chain.Tron, "TG6jUMfwpwR9QNFsSwCGtLaV2TR2gV8yru"), - decimals = 6, - name = "Wrapped TRX", - symbol = "WTRX", - type = AssetType.TRC20, - ), - ) - val accountService = FakeTronAccountService(TronAccount(balance = 1_000_000)) - val callService = FakeTronCallService( - mapOf( - "41a614f803b6fd780986a42c78ec9c7f77e6ded13c" to TronSmartContractResult( - result = TronSmartContractResultMessage(true), - constant_result = listOf("F4240"), - energy_used = 1, - ), - "41032017411f4663b317fe77c257d28d5cd1b26e3d" to TronSmartContractResult( - result = TronSmartContractResultMessage(true), - constant_result = listOf("DE0B6B3A7640000"), - energy_used = 1, - ), - "41433d1a20a144c3b064e9371bca739f960900f409" to TronSmartContractResult( - result = TronSmartContractResultMessage(true), - constant_result = listOf("3000000"), - energy_used = 1, - ), - ) - ) - val balanceClient = TronBalanceClient(Chain.Tron, accountService, callService, stakeService) - val result = runBlocking { balanceClient.getTokenBalances(Chain.Tron, "TNLmo9j9AuGnnxibQUT13xoMGuUmNwxtkU", assets) } - assertEquals("41a614f803b6fd780986a42c78ec9c7f77e6ded13c", callService.requests[0]["contract_address"]) - assertEquals("41032017411f4663b317fe77c257d28d5cd1b26e3d", callService.requests[1]["contract_address"]) - assertEquals("41433d1a20a144c3b064e9371bca739f960900f409", callService.requests[2]["contract_address"]) - assertEquals(false, callService.requests[0]["visible"]) - assertEquals(0L, callService.requests[0]["call_value"]) - assertEquals("4187b59ec7bb58250533fb8235f9a3f8eec9c1bfe8", callService.requests[0]["owner_address"]) - assertEquals(1_000_000L, callService.requests[0]["fee_limit"]) - assertEquals("balanceOf(address)", callService.requests[0]["function_selector"]) - assertEquals("00000000000000000000004187b59ec7bb58250533fb8235f9a3f8eec9c1bfe8", callService.requests[0]["parameter"]) - - assertNotNull(result) - assertEquals(3, result.size) - assertEquals("1000000", result[0].balance.available) - assertEquals(1.0, result[0].balanceAmount.available) - assertEquals("1000000000000000000", result[1].balance.available) - assertEquals(1.0, result[1].balanceAmount.available) - assertEquals("50331648", result[2].balance.available) - assertEquals(50.331648, result[2].balanceAmount.available) - } - - @Test - fun testTron_stake_balance_success() { - val accountService = FakeTronAccountService( - TronAccount( - balance = 1_000_000, - frozenV2 = listOf( - TronFrozen( - amount = 0xF4240, - ), - TronFrozen( - amount = 0x1E8480, - ), - ), - unfrozenV2 = listOf( - TronUnfrozen( - unfreeze_amount = 0x2DC6C0 - ), - TronUnfrozen( - unfreeze_amount = 0x3D0900 - ), - ), - votes = listOf( - TronVote( - vote_address = "", - vote_count = 1, - ), - TronVote( - vote_address = "", - vote_count = 2, - ), - TronVote( - vote_address = "", - vote_count = 3, - ), - ) - ) - ) - val callService = FakeTronCallService() - val balanceClient = TronBalanceClient(Chain.Tron, accountService, callService, stakeService) - val result = runBlocking { balanceClient.getNativeBalance(Chain.Tron, "TNLmo9j9AuGnnxibQUT13xoMGuUmNwxtkU") } - assertNotNull(result) - assertEquals(AssetId(Chain.Tron), result!!.asset.id) - assertEquals("1000000", result.balance.available) - assertEquals("6000000", result.balance.staked) - assertEquals("7000000", result.balance.pending) - assertEquals("0", result.balance.reserved) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.frozen) - assertEquals("1000000", result.balance.rewards) - assertEquals(1.0, result.balanceAmount.available) - assertEquals(6.0, result.balanceAmount.staked) - assertEquals(7.0, result.balanceAmount.pending) - assertEquals(1.0, result.balanceAmount.rewards) - assertEquals(15.0, result.totalAmount) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronFeeCalculator.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronFeeCalculator.kt deleted file mode 100644 index 6066fdc3b..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronFeeCalculator.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.DestinationAddress -import com.wallet.core.blockchain.tron.TronAccount -import com.wallet.core.blockchain.tron.TronAccountUsage -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.runBlocking -import org.junit.Test -import java.math.BigInteger - -class TestTronFeeCalculator { - companion object { - init { - includeLibs() - } - } - - @Test - fun testTron_native_transfer_fee() { - val feeCalculator = TronFeeCalculator( - chain = Chain.Tron, - nodeStatusService = FakeTronNodeStatusService(), - callService = FakeTronCallService() - ) - - val params: ConfirmParams.TransferParams.Native = ConfirmParams.Builder( - Chain.Tron.asset(), - Account(Chain.Tron, "TNLmo9j9AuGnnxibQUT13xoMGuUmNwxtkU", ""), - BigInteger.valueOf(1_000_000) - ).transfer(destination = DestinationAddress("THdHCD2miVcUdqAt32168a6wiyG5CE6WRY")) as ConfirmParams.TransferParams.Native - val result = runBlocking { - feeCalculator.calculate( - params, - TronAccount(address = "TNLmo9j9AuGnnxibQUT13xoMGuUmNwxtkU"), - TronAccountUsage() - ) - } - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpAccountsService.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpAccountsService.kt deleted file mode 100644 index 66956d129..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpAccountsService.kt +++ /dev/null @@ -1,40 +0,0 @@ -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.XRPAccount -import com.wallet.core.blockchain.xrp.XRPAccountLinesResult -import com.wallet.core.blockchain.xrp.XRPAccountResult -import com.wallet.core.blockchain.xrp.XRPResult - -internal class TestXrpAccountsService( - val balance: String = "", -) : XrpAccountsService { - var requestAccount: String? = "" - - override suspend fun account(request: JSONRpcRequest>>): Result> { - requestAccount = request.params[0]["account"] - return Result.success( - XRPResult( - XRPAccountResult( - XRPAccount( - Balance = balance, - Sequence = 92788459, - OwnerCount = 1, - ), - ledger_current_index = 1 - ) - ) - ) - } - - override suspend fun accountLines(request: JSONRpcRequest>>): Result> { - return Result.success( - XRPResult( - XRPAccountLinesResult( - listOf() - ) - ) - ) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpBalanceClient.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpBalanceClient.kt deleted file mode 100644 index f1147aa8c..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpBalanceClient.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.gemwallet.android.blockchain.clients.xrp - -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.ext.toIdentifier -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()) - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BroadcastClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BroadcastClientProxy.kt deleted file mode 100644 index 13aed8501..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BroadcastClientProxy.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.gemwallet.android.blockchain.clients - -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType - -class BroadcastClientProxy( - private val clients: List, -) : BroadcastClient { - - override suspend fun send( - account: Account, - signedMessage: ByteArray, - type: TransactionType - ): String { - return clients.getClient(account.chain)?.send(account, signedMessage, type) - ?: throw Exception("Chain isn't support") - } - - override fun supported(chain: Chain): Boolean { - return clients.getClient(chain) != null - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/NodeStatusClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/NodeStatusClientProxy.kt deleted file mode 100644 index 0fb3559eb..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/NodeStatusClientProxy.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.gemwallet.android.blockchain.clients - -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain - -class NodeStatusClientProxy( - private val clients: List, -): NodeStatusClient { - - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? { - return try { - clients.getClient(chain)?.getNodeStatus(chain, url) - } catch (_: Throwable) { - null - } - } - - override fun supported(chain: Chain): Boolean { - return clients.getClient(chain) != null - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/StakeClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/StakeClientProxy.kt deleted file mode 100644 index 28e038b01..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/StakeClientProxy.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.gemwallet.android.blockchain.clients - -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.DelegationBase -import com.wallet.core.primitives.DelegationValidator - -class StakeClientProxy( - private val clients: List -) : StakeClient { - override suspend fun getValidators( - chain: Chain, - apr: Double - ): List { - return clients.getClient(chain)?.getValidators(chain, apr) ?: emptyList() - } - - override suspend fun getStakeDelegations( - chain: Chain, - address: String, - apr: Double - ): List { - return clients.getClient(chain)?.getStakeDelegations(chain, address, apr) ?: emptyList() - } - - override fun supported(chain: Chain): Boolean { - return clients.getClient(chain) != null - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/TransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/TransactionStatusClient.kt index d33d5db7c..c39217c02 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/TransactionStatusClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/TransactionStatusClient.kt @@ -17,8 +17,4 @@ class TransactionStateRequest( sealed class TransactionStatusError(message: String? = null) : Exception(message) -data object ServiceUnavailable : TransactionStatusError() - -class TransactionError(message: String) : TransactionStatusError(message) - -class TransactionNotFound(message: String? = null) : TransactionStatusError(message) \ No newline at end of file +object ServiceUnavailable : TransactionStatusError() \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandBalanceClient.kt deleted file mode 100644 index 11fbe981e..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandBalanceClient.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.gemwallet.android.blockchain.clients.algorand - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.algorand.services.AlgorandAccountService -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Chain -import kotlin.math.max - -class AlgorandBalanceClient( - private val chain: Chain, - private val accountService: AlgorandAccountService, -) : BalanceClient { - - override suspend fun getNativeBalance( - chain: Chain, - address: String - ): AssetBalance? { - val response = accountService.accounts(address).getOrNull() ?: return null - val amount = response.amount - - val available = if (amount > 0L) { - max(amount - response.min_balance, 0L).toString() - } else { - "0" - } - val reserved = if (response.amount > 0L) { - response.min_balance.toString() - } else { - "0" - } - return AssetBalance.create(chain.asset(), available = available, reserved = reserved.toString()) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandBroadcastClient.kt deleted file mode 100644 index c84b8e2d1..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandBroadcastClient.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.gemwallet.android.blockchain.clients.algorand - -import com.gemwallet.android.blockchain.Mime -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.algorand.services.AlgorandBroadcastService -import com.gemwallet.android.blockchain.rpc.ServiceError -import com.gemwallet.android.blockchain.rpc.handleError -import com.wallet.core.blockchain.algorand.AlgorandTransactionBroadcast -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import okhttp3.RequestBody.Companion.toRequestBody - -class AlgorandBroadcastClient( - private val chain: Chain, - private val broadcastService: AlgorandBroadcastService, -) : BroadcastClient { - - override suspend fun send( - account: Account, - signedMessage: ByteArray, - type: TransactionType - ): String { - val result = broadcastService.broadcast(signedMessage.toRequestBody(Mime.Binary.value)) - return result.getOrNull()?.txId ?: throw - result.handleError()?.message?.let { Exception(it) } - ?: ServiceError.BroadCastError() - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandNodeStatusClient.kt deleted file mode 100644 index 6e93ab94d..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandNodeStatusClient.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.gemwallet.android.blockchain.clients.algorand - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.clients.algorand.services.AlgorandNodeStatusService -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain - -class AlgorandNodeStatusClient( - private val chain: Chain, - private val nodeStatusService: AlgorandNodeStatusService, -) : NodeStatusClient { - - override suspend fun getNodeStatus( - chain: Chain, - url: String - ): NodeStatus? { - val resp = try { - nodeStatusService.transactionsParams("$url/v2/transactions/params") - } catch (err: Throwable) { - throw err - } - val result = resp.body() - return NodeStatus( - url = url, - blockNumber = result?.last_round?.toString() ?: return null, - inSync = true, - chainId = result.genesis_id, - latency = resp.getLatency() - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignClient.kt index 195e16ce2..a804220dd 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignClient.kt @@ -2,6 +2,7 @@ package com.gemwallet.android.blockchain.clients.algorand import com.gemwallet.android.blockchain.clients.SignClient import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy +import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.google.protobuf.ByteString @@ -44,7 +45,7 @@ class AlgorandSignClient( if (!output.errorMessage.isNullOrEmpty()) { throw Exception(output.errorMessage) } - return listOf(output.encoded.toByteArray()) + return listOf(output.encoded.toByteArray().toHexString("").toByteArray()) } override fun supported(chain: Chain): Boolean = this.chain == chain diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt index 9bce5cada..62ad0eb61 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt @@ -1,7 +1,7 @@ package com.gemwallet.android.blockchain.clients.algorand import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.algorand.services.AlgorandNodeStatusService +import com.gemwallet.android.blockchain.clients.algorand.services.AlgorandService import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee @@ -12,7 +12,7 @@ import com.wallet.core.primitives.FeePriority class AlgorandSignPreloadClient( private val chain: Chain, - private val feeService: AlgorandNodeStatusService, + private val feeService: AlgorandService, ) : NativeTransferPreloader { override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandTransactionStatusClient.kt deleted file mode 100644 index 7579e968d..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandTransactionStatusClient.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.gemwallet.android.blockchain.clients.algorand - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.blockchain.clients.algorand.services.AlgorandTxStatusService -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState - -class AlgorandTransactionStatusClient( - private val chain: Chain, - private val txStatusService: AlgorandTxStatusService, -) : TransactionStatusClient { - - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val round = txStatusService.transaction(request.hash).getOrNull()?.confirmed_round ?: throw ServiceUnavailable - return TransactionChanges(if (round > 0) TransactionState.Confirmed else TransactionState.Failed) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandAccountService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandAccountService.kt deleted file mode 100644 index 3cf7b0c0b..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandAccountService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.algorand.services - -import com.wallet.core.blockchain.algorand.AlgorandAccount -import retrofit2.http.GET -import retrofit2.http.Path - -interface AlgorandAccountService { - @GET("/v2/accounts/{address}") - suspend fun accounts(@Path("address") address: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandBroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandBroadcastService.kt deleted file mode 100644 index db63e7699..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandBroadcastService.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.gemwallet.android.blockchain.clients.algorand.services - -import com.wallet.core.blockchain.algorand.AlgorandTransactionBroadcast -import okhttp3.RequestBody -import retrofit2.http.Body -import retrofit2.http.POST - -interface AlgorandBroadcastService { - - @POST("/v2/transactions") - suspend fun broadcast(@Body body: RequestBody): Result - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandNodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandNodeStatusService.kt deleted file mode 100644 index 573df27e9..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandNodeStatusService.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.gemwallet.android.blockchain.clients.algorand.services - -import com.wallet.core.blockchain.algorand.AlgorandTransactionParams -import retrofit2.Response -import retrofit2.http.GET -import retrofit2.http.Url - -interface AlgorandNodeStatusService { - @GET("/v2/transactions/params") - suspend fun transactionsParams(): Result - - @GET//("/v2/transactions/params") - suspend fun transactionsParams(@Url url: String): Response -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandService.kt index 92d639c7b..64cb2e970 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandService.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandService.kt @@ -1,6 +1,9 @@ package com.gemwallet.android.blockchain.clients.algorand.services -interface AlgorandService : AlgorandAccountService, - AlgorandBroadcastService, - AlgorandTxStatusService, - AlgorandNodeStatusService \ No newline at end of file +import com.wallet.core.blockchain.algorand.AlgorandTransactionParams +import retrofit2.http.GET + +interface AlgorandService { + @GET("/v2/transactions/params") + suspend fun transactionsParams(): Result +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandTxStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandTxStatusService.kt deleted file mode 100644 index b80e8a23d..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandTxStatusService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.algorand.services - -import com.wallet.core.blockchain.algorand.AlgorandTransactionStatus -import retrofit2.http.GET -import retrofit2.http.Path - -interface AlgorandTxStatusService { - @GET("/v2/transactions/pending/{id}") - suspend fun transaction(@Path("id") id: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosBalanceClient.kt deleted file mode 100644 index 63d9530c2..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosBalanceClient.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.aptos.services.AptosBalancesService -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.withContext - -class AptosBalanceClient( - private val chain: Chain, - private val balanceService: AptosBalancesService, -) : BalanceClient { - private val aptosCoin = "0x1::aptos_coin::AptosCoin" - - override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? { - return try { - val result = balanceService.balance(address, aptosCoin).string() - AssetBalance.create(chain.asset(), available = result) - } catch (_: Throwable) { - null - } - } - - override suspend fun getTokenBalances(chain: Chain, address: String, tokens: List): List { - if (tokens.isEmpty()) { - return emptyList() - } - return withContext(Dispatchers.IO) { - tokens.map { token -> - async { - val tokenId = token.id.tokenId ?: return@async null - try { - val result = balanceService.balance(address, tokenId).string() - AssetBalance.create(token, available = result) - } catch (_: Throwable) { - null - } - } - } - .awaitAll() - .filterNotNull() - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosBroadcastClient.kt deleted file mode 100644 index 0fe9910c0..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosBroadcastClient.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.Mime -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.aptos.services.AptosBroadcastService -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import okhttp3.RequestBody.Companion.toRequestBody - -class AptosBroadcastClient( - private val chain: Chain, - private val broadcastService: AptosBroadcastService, -) : BroadcastClient { - override suspend fun send(account: Account, signedMessage: ByteArray, type: TransactionType): String { - return broadcastService.broadcast(String(signedMessage).toRequestBody(Mime.Json.value)) - .getOrThrow() - .hash - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt index 61a77e3b1..eaa58d066 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt @@ -1,6 +1,6 @@ package com.gemwallet.android.blockchain.clients.aptos -import com.gemwallet.android.blockchain.clients.aptos.services.AptosFeeService +import com.gemwallet.android.blockchain.clients.aptos.services.AptosServices import com.gemwallet.android.ext.type import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee @@ -21,12 +21,12 @@ import java.math.BigInteger internal class AptosFeeCalculator( private val chain: Chain, - private val feeRpcClient: AptosFeeService, + private val aptosServices: AptosServices, ) { private val maxGasAmount = BigInteger.valueOf(1_500) suspend fun calculate(params: ConfirmParams, sequence: Long): List = withContext(Dispatchers.IO) { - val feePrice = feeRpcClient.feePrice().getOrThrow() + val feePrice = aptosServices.feePrice().getOrThrow() FeePriority.entries.map { async(Dispatchers.IO) { @@ -95,7 +95,7 @@ internal class AptosFeeCalculator( signature = null, ), ) - val response = feeRpcClient.simulate(transaction) + val response = aptosServices.simulate(transaction) val simulated = response.getOrNull()?.firstOrNull() return simulated ?: throw Exception("No aptos transaction") } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosGetTokenClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosGetTokenClient.kt deleted file mode 100644 index 1e160a794..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosGetTokenClient.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.GetTokenClient -import com.gemwallet.android.blockchain.clients.aptos.services.AptosTokensService -import com.gemwallet.android.math.has0xPrefix -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain - -class AptosGetTokenClient( - private val chain: Chain, - private val tokensService: AptosTokensService, -) : GetTokenClient { - - override suspend fun getTokenData(tokenId: String): Asset? { - val address = tokenId.split("::").firstOrNull() ?: return null - val resource = "0x1::coin::CoinInfo<$tokenId>" - val tokenInfo = tokensService.resource(address, resource).getOrNull()?.data ?: return null - return Asset( - id = AssetId(chain, tokenId), - name = tokenInfo.name, - symbol = tokenInfo.symbol, - decimals = tokenInfo.decimals, - type = AssetType.TOKEN - ) - } - - override suspend fun isTokenQuery(query: String): Boolean = isTokenAddress(query) - - override fun supported(chain: Chain): Boolean = chain == this.chain - - companion object { - fun isTokenAddress(tokenId: String): Boolean { - return tokenId.has0xPrefix() && tokenId.contains("::") - } - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosNodeStatusClient.kt deleted file mode 100644 index 56480f75c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosNodeStatusClient.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.clients.aptos.services.AptosNodeStatusService -import com.gemwallet.android.blockchain.clients.aptos.services.getLedger -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext - -class AptosNodeStatusClient( - private val chain: Chain, - private val nodeStatusService: AptosNodeStatusService, -) : NodeStatusClient { - - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? = withContext(Dispatchers.IO) { - val response = nodeStatusService.getLedger(url) - val ledger = response.body() ?: return@withContext null - NodeStatus( - url = url, - chainId = ledger.chain_id.toString(), - blockNumber = ledger.ledger_version, - inSync = true, - latency = response.getLatency(), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt index a396aa9cc..55d594e3b 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt @@ -3,8 +3,7 @@ package com.gemwallet.android.blockchain.clients.aptos import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.clients.aptos.services.AptosAccountsService -import com.gemwallet.android.blockchain.clients.aptos.services.AptosFeeService +import com.gemwallet.android.blockchain.clients.aptos.services.AptosServices import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee @@ -14,11 +13,10 @@ import com.wallet.core.primitives.FeePriority class AptosSignerPreloader( private val chain: Chain, - private val accountsService: AptosAccountsService, - feeService: AptosFeeService, + private val aptosServices: AptosServices, ) : NativeTransferPreloader, TokenTransferPreloader, SwapTransactionPreloader { - private val feeCalculator = AptosFeeCalculator(chain, feeService) + private val feeCalculator = AptosFeeCalculator(chain, aptosServices) override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { return preloadTransfer(params) @@ -34,7 +32,7 @@ class AptosSignerPreloader( private suspend fun preloadTransfer(params: ConfirmParams): SignerParams { val sequence = try { - val response = accountsService.accounts(params.from.address).getOrThrow() + val response = aptosServices.accounts(params.from.address).getOrThrow() response.sequence_number?.toLong() ?: 0L } catch (_: Throwable) { 0L diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosTransactionStatusClient.kt deleted file mode 100644 index 3de240ca2..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosTransactionStatusClient.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.blockchain.clients.aptos.services.AptosTransactionsService -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState -import java.math.BigInteger - -class AptosTransactionStatusClient( - private val chain: Chain, - private val rpcClient: AptosTransactionsService, -) : TransactionStatusClient { - - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val transaction = rpcClient.transactions(request.hash).getOrNull() ?: throw ServiceUnavailable - - val status = if (transaction.success) TransactionState.Confirmed else TransactionState.Reverted - val fee = BigInteger(transaction.gas_used) * BigInteger(transaction.gas_unit_price) - return TransactionChanges(status, fee) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/models/AptosAccount.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/models/AptosAccount.kt index e452a2b1a..2e392a49e 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/models/AptosAccount.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/models/AptosAccount.kt @@ -7,6 +7,4 @@ data class AptosAccount( val sequence_number: String?, val message: String?, val error_code: String?, -) - -const val aptosErrorCode = "account_not_found" \ No newline at end of file +) \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosAccountsService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosAccountsService.kt deleted file mode 100644 index f29d5d56b..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosAccountsService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos.services - -import com.gemwallet.android.blockchain.clients.aptos.models.AptosAccount -import retrofit2.http.GET -import retrofit2.http.Path - -interface AptosAccountsService { - @GET("/v1/accounts/{address}") - suspend fun accounts(@Path("address") address: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosBalancesService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosBalancesService.kt deleted file mode 100644 index 13d09c5b0..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosBalancesService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos.services - -import com.wallet.core.blockchain.aptos.AptosResource -import com.wallet.core.blockchain.aptos.AptosResourceBalanceOptional -import okhttp3.ResponseBody -import retrofit2.http.GET -import retrofit2.http.Path - -interface AptosBalancesService { - @GET("/v1/accounts/{address}/balance/{assetType}") - suspend fun balance(@Path("address") address: String, @Path("assetType") assetType: String): ResponseBody -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosBroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosBroadcastService.kt deleted file mode 100644 index fe936ad70..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosBroadcastService.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos.services - -import com.wallet.core.blockchain.aptos.AptosTransactionBroacast -import okhttp3.RequestBody -import retrofit2.http.Body -import retrofit2.http.Headers -import retrofit2.http.POST - -interface AptosBroadcastService { - @Headers("Content-type: application/json") - @POST("/v1/transactions") - suspend fun broadcast(@Body request: RequestBody): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosFeeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosFeeService.kt deleted file mode 100644 index 67b981baf..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosFeeService.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos.services - -import com.wallet.core.blockchain.aptos.AptosGasFee -import com.wallet.core.blockchain.aptos.AptosTransaction -import com.wallet.core.blockchain.aptos.AptosTransactionSimulation -import retrofit2.http.Body -import retrofit2.http.GET -import retrofit2.http.Headers -import retrofit2.http.POST - -interface AptosFeeService { - @GET("/v1/estimate_gas_price") - suspend fun feePrice(): Result - - @Headers("Content-type: application/json") - @POST("/v1/transactions/simulate?estimate_max_gas_amount=true") - suspend fun simulate(@Body data: AptosTransactionSimulation): Result> -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosNodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosNodeStatusService.kt deleted file mode 100644 index 11f0f319c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosNodeStatusService.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos.services - -import com.wallet.core.blockchain.aptos.AptosLedger -import retrofit2.Response -import retrofit2.http.GET -import retrofit2.http.Url - -interface AptosNodeStatusService { - @GET - suspend fun ledger(@Url url: String): Response - - suspend fun AptosServices.getLedger(url: String): Response { - return ledger("$url/v1") - } -} - -suspend fun AptosNodeStatusService.getLedger(url: String): Response { - return ledger("$url/v1") -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosServices.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosServices.kt index cce33bcce..701eebe77 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosServices.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosServices.kt @@ -1,10 +1,23 @@ package com.gemwallet.android.blockchain.clients.aptos.services -interface AptosServices : - AptosAccountsService, - AptosBalancesService, - AptosBroadcastService, - AptosFeeService, - AptosNodeStatusService, - AptosTransactionsService, - AptosTokensService \ No newline at end of file +import com.gemwallet.android.blockchain.clients.aptos.models.AptosAccount +import com.wallet.core.blockchain.aptos.AptosGasFee +import com.wallet.core.blockchain.aptos.AptosTransaction +import com.wallet.core.blockchain.aptos.AptosTransactionSimulation +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.Headers +import retrofit2.http.POST +import retrofit2.http.Path + +interface AptosServices { + @GET("/v1/accounts/{address}") + suspend fun accounts(@Path("address") address: String): Result + + @GET("/v1/estimate_gas_price") + suspend fun feePrice(): Result + + @Headers("Content-type: application/json") + @POST("/v1/transactions/simulate?estimate_max_gas_amount=true") + suspend fun simulate(@Body data: AptosTransactionSimulation): Result> +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosTokensService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosTokensService.kt deleted file mode 100644 index 29d3199cd..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosTokensService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos.services - -import com.wallet.core.blockchain.aptos.AptosCoinInfo -import com.wallet.core.blockchain.aptos.AptosResource -import retrofit2.http.GET -import retrofit2.http.Path - -interface AptosTokensService { - - @GET("/v1/accounts/{address}/resource/{resource}") - suspend fun resource(@Path("address") address: String, @Path("resource") resource: String): Result> -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosTransactionsService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosTransactionsService.kt deleted file mode 100644 index 4a1ee5ae5..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosTransactionsService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos.services - -import com.wallet.core.blockchain.aptos.AptosTransaction -import retrofit2.http.GET -import retrofit2.http.Path - -interface AptosTransactionsService { - @GET("/v1/transactions/by_hash/{id}") - suspend fun transactions(@Path("id") txId: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinBalanceClient.kt deleted file mode 100644 index f4a02d601..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinBalanceClient.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinBalancesService -import com.gemwallet.android.ext.asset -import com.gemwallet.android.ext.fullAddress -import com.gemwallet.android.ext.toBitcoinChain -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Chain - -class BitcoinBalanceClient( - private val chain: Chain, - private val balanceService: BitcoinBalancesService, -) : BalanceClient { - - override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? { - val address = chain.toBitcoinChain().fullAddress(address) - val result = balanceService.balance(address).getOrNull() - return try { - AssetBalance.create(chain.asset(), available = result?.balance ?: return null) - } catch (_: Throwable) { - null - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinBroadcastClient.kt deleted file mode 100644 index 75eb9dcc5..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinBroadcastClient.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin - -import com.gemwallet.android.blockchain.Mime -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinBroadcastService -import com.gemwallet.android.blockchain.rpc.RpcError -import com.gemwallet.android.math.toHexString -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import okhttp3.RequestBody.Companion.toRequestBody - -class BitcoinBroadcastClient( - private val chain: Chain, - private val broadcastService: BitcoinBroadcastService, -) : BroadcastClient { - - override suspend fun send(account: Account, signedMessage: ByteArray, type: TransactionType): String { - val requestBody = signedMessage.toHexString("").toRequestBody(Mime.Plain.value) - return broadcastService.broadcast(requestBody).getOrThrow().result - ?: throw RpcError.BroadcastFail("Unknown error") - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt index 78062299a..7ec5557d1 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt @@ -1,6 +1,6 @@ package com.gemwallet.android.blockchain.clients.bitcoin -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinFeeService +import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinRpcClient import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy import com.gemwallet.android.ext.toBitcoinChain import com.gemwallet.android.model.Crypto @@ -27,7 +27,7 @@ import java.math.BigInteger import java.math.RoundingMode class BitcoinFeeCalculator( - private val feeService: BitcoinFeeService, + private val client: BitcoinRpcClient, ) { suspend fun calculate( utxos: List, @@ -62,7 +62,7 @@ class BitcoinFeeCalculator( FeePriority.Fast -> it.fast } }.toString() - return feeService.estimateFee(priority).fold( + return client.estimateFee(priority).fold( { val networkFeePerKb = Crypto(it.result, decimals).atomicValue val feePerByte = networkFeePerKb.toBigDecimal().divide(BigDecimal(1000), RoundingMode.CEILING).toBigInteger() diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinNodeStatusClient.kt deleted file mode 100644 index d329d8a1f..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinNodeStatusClient.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinNodeStatusService -import com.gemwallet.android.blockchain.clients.bitcoin.services.getBlock -import com.gemwallet.android.blockchain.clients.bitcoin.services.getNodeInfo -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class BitcoinNodeStatusClient( - private val chain: Chain, - private val nodeStatusService: BitcoinNodeStatusService, -) : NodeStatusClient { - - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? = withContext(Dispatchers.IO) { - val nodeInfoJob = async { nodeStatusService.getNodeInfo(url).getOrNull() } - val chainIdJob = async { nodeStatusService.getBlock(url) } - val nodeInfo = nodeInfoJob.await() ?: return@withContext null - val chainId = chainIdJob.await() - - NodeStatus( - url = url, - chainId = chainId.body()?.previousBlockHash ?: return@withContext null, - blockNumber = nodeInfo.blockbook.bestHeight.toString(), - inSync = nodeInfo.blockbook.inSync, - latency = chainId.getLatency() - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignClient.kt index 416b53cd0..4cb8a3ef9 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignClient.kt @@ -102,7 +102,7 @@ class BitcoinSignClient( this.useMaxAmount = params.isMax() this.addPrivateKey(ByteString.copyFrom(privateKey)) this.addAllUtxo(chainData.utxo.getUtxoTransactions(params.from.address, coinType)) - chainData.utxo.forEach { + chainData.utxo.forEach { _ -> val redeemScript = BitcoinScript.lockScriptForAddress(params.from.address, coinType) val scriptData = redeemScript.data() if (coinType == CoinType.BITCOIN || scriptData?.isNotEmpty() == true) { @@ -126,7 +126,7 @@ class BitcoinSignClient( if (output.errorMessage.isNotEmpty()) { throw IllegalStateException(output.errorMessage) } - return listOf(output.encoded.toByteArray()) + return listOf(output.encoded.toByteArray().toHexString("").toByteArray()) } override fun supported(chain: Chain): Boolean = this.chain == chain diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt index c3f14356c..cc59060c4 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt @@ -2,8 +2,7 @@ package com.gemwallet.android.blockchain.clients.bitcoin import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinFeeService -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinUTXOService +import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinRpcClient import com.gemwallet.android.ext.fullAddress import com.gemwallet.android.ext.toBitcoinChain import com.gemwallet.android.model.ChainSignData @@ -18,11 +17,10 @@ import java.math.BigInteger class BitcoinSignerPreloader( private val chain: Chain, - private val utxoService: BitcoinUTXOService, - feeService: BitcoinFeeService, + private val client: BitcoinRpcClient, ) : NativeTransferPreloader, SwapTransactionPreloader { - private val feeCalculator = BitcoinFeeCalculator(feeService) + private val feeCalculator = BitcoinFeeCalculator(client) override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { val data = preload(params.from, params.destination().address, params.amount) @@ -38,7 +36,7 @@ class BitcoinSignerPreloader( private suspend fun preload(fromAccount: Account, destinationAddress: String, amount: BigInteger): BitcoinChainData { val address = chain.toBitcoinChain().fullAddress(fromAccount.address) - val utxo = utxoService.getUTXO(address).getOrNull() ?: throw Exception("Can't load UTXO") + val utxo = client.getUTXO(address).getOrNull() ?: throw Exception("Can't load UTXO") val fee = feeCalculator.calculate(utxo, fromAccount, destinationAddress, amount) return BitcoinChainData(utxo, fee) } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinTransactionStatusClient.kt deleted file mode 100644 index 7b249c976..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinTransactionStatusClient.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinTransactionsService -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState - -class BitcoinTransactionStatusClient( - private val chain: Chain, - private val rpcClient: BitcoinTransactionsService -) : TransactionStatusClient { - - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val tx = rpcClient.transaction(request.hash).getOrNull() ?: throw ServiceUnavailable - return TransactionChanges(if (tx.blockHeight > 0) TransactionState.Confirmed else TransactionState.Pending) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinBalancesService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinBalancesService.kt deleted file mode 100644 index 420d69535..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinBalancesService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin.services - -import com.wallet.core.blockchain.bitcoin.BitcoinAccount -import retrofit2.http.GET -import retrofit2.http.Path - -interface BitcoinBalancesService { - @GET("/api/v2/address/{address}") - suspend fun balance(@Path("address") address: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinBroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinBroadcastService.kt deleted file mode 100644 index 2bbe5af21..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinBroadcastService.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin.services - -import com.wallet.core.blockchain.bitcoin.BitcoinTransactionBroacastResult -import okhttp3.RequestBody -import retrofit2.http.Body -import retrofit2.http.POST - -interface BitcoinBroadcastService { - @POST("/api/v2/sendtx/") - suspend fun broadcast(@Body body: RequestBody): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinFeeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinFeeService.kt deleted file mode 100644 index 6bdf049ef..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinFeeService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin.services - -import com.wallet.core.blockchain.bitcoin.BitcoinFeeResult -import retrofit2.http.GET -import retrofit2.http.Path - -interface BitcoinFeeService { - @GET("/api/v2/estimatefee/{priority}") - suspend fun estimateFee(@Path("priority") priority: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinNodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinNodeStatusService.kt deleted file mode 100644 index ac26fc3a3..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinNodeStatusService.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin.services - -import com.wallet.core.blockchain.bitcoin.BitcoinBlock -import com.wallet.core.blockchain.bitcoin.BitcoinNodeInfo -import retrofit2.Response -import retrofit2.http.GET -import retrofit2.http.Url - -interface BitcoinNodeStatusService { - @GET//("/api/v2/") - suspend fun nodeInfo(@Url url: String): Result - - @GET//("/api/v2/block/{block}") - suspend fun block(@Url url: String): Response -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt index 6b790990b..8d22fc902 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt @@ -1,21 +1,17 @@ package com.gemwallet.android.blockchain.clients.bitcoin.services import com.wallet.core.blockchain.bitcoin.BitcoinBlock +import com.wallet.core.blockchain.bitcoin.BitcoinFeeResult import com.wallet.core.blockchain.bitcoin.BitcoinNodeInfo +import com.wallet.core.blockchain.bitcoin.BitcoinUTXO import retrofit2.Response +import retrofit2.http.GET +import retrofit2.http.Path -interface BitcoinRpcClient : - BitcoinBalancesService, - BitcoinUTXOService, - BitcoinFeeService, - BitcoinBroadcastService, - BitcoinTransactionsService, - BitcoinNodeStatusService +interface BitcoinRpcClient { + @GET("/api/v2/estimatefee/{priority}") + suspend fun estimateFee(@Path("priority") priority: String): Result -suspend fun BitcoinNodeStatusService.getBlock(url: String): Response { - return block("$url/api/v2/block/1") -} - -suspend fun BitcoinNodeStatusService.getNodeInfo(url: String): Result { - return nodeInfo("$url/api/v2") + @GET("/api/v2/utxo/{address}") + suspend fun getUTXO(@Path("address") address: String): Result> } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinTransactionsService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinTransactionsService.kt deleted file mode 100644 index 14a18b601..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinTransactionsService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin.services - -import com.wallet.core.blockchain.bitcoin.BitcoinTransaction -import retrofit2.http.GET -import retrofit2.http.Path - -interface BitcoinTransactionsService { - @GET("/api/v2/tx/{txId}") - suspend fun transaction(@Path("txId") txId: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinUTXOService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinUTXOService.kt deleted file mode 100644 index b11ad9f60..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinUTXOService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin.services - -import com.wallet.core.blockchain.bitcoin.BitcoinUTXO -import retrofit2.http.GET -import retrofit2.http.Path - -interface BitcoinUTXOService { - @GET("/api/v2/utxo/{address}") - suspend fun getUTXO(@Path("address") address: String): Result> -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoBalanceClient.kt deleted file mode 100644 index 536afbbd4..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoBalanceClient.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.cardano.services.CardanoBalanceService -import com.gemwallet.android.blockchain.clients.cardano.services.balance -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Chain - -class CardanoBalanceClient( - private val chain: Chain, - private val balanceService: CardanoBalanceService, -) : BalanceClient { - - override suspend fun getNativeBalance( - chain: Chain, - address: String - ): AssetBalance? { - val amount = try { - balanceService.balance(address) - } catch (_: Throwable) { - null - } ?: return null - return AssetBalance.create(chain.asset(), available = amount.toString()) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoBroadcastClient.kt deleted file mode 100644 index a147bd71c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoBroadcastClient.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano - -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.cardano.services.CardanoBroadcastService -import com.gemwallet.android.blockchain.clients.cardano.services.broadcast -import com.gemwallet.android.blockchain.rpc.ServiceError -import com.gemwallet.android.math.toHexString -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType - -class CardanoBroadcastClient( - private val chain: Chain, - private val broadcastService: CardanoBroadcastService -) : BroadcastClient { - override suspend fun send( - account: Account, - signedMessage: ByteArray, - type: TransactionType - ): String { - return broadcastService.broadcast(signedMessage.toHexString(prefix = ""))?.submitTransaction?.hash - ?: throw ServiceError.EmptyHash - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoNodeStatusClient.kt deleted file mode 100644 index 4daa5a0fb..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoNodeStatusClient.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.clients.cardano.services.CardanoNodeStatusService -import com.gemwallet.android.blockchain.clients.cardano.services.latestBlock -import com.gemwallet.android.blockchain.clients.cardano.services.networkMagic -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class CardanoNodeStatusClient( - private val chain: Chain, - private val nodeStatusService: CardanoNodeStatusService -) : NodeStatusClient { - - override suspend fun getNodeStatus( - chain: Chain, - url: String - ): NodeStatus? = withContext(Dispatchers.IO) { - val getLatestBlock = async { nodeStatusService.latestBlock(url) } - val getNetworkMagic = async { nodeStatusService.networkMagic(url) } - val latestBlock = getLatestBlock.await() - val networkMagic = getNetworkMagic.await() - NodeStatus( - url = url, - chainId = networkMagic.body()?.data?.genesis?.shelley?.networkMagic?.toString() ?: "-", - blockNumber = latestBlock.body()?.data?.cardano?.tip?.number?.toString() ?: return@withContext null, - inSync = true, - latency = latestBlock.getLatency(), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignClient.kt index 9ee08b2cc..0e5b550b0 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignClient.kt @@ -2,6 +2,7 @@ package com.gemwallet.android.blockchain.clients.cardano import com.gemwallet.android.blockchain.clients.SignClient import com.gemwallet.android.math.decodeHex +import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.google.protobuf.ByteString @@ -51,7 +52,7 @@ class CardanoSignClient( if (!output.errorMessage.isNullOrEmpty()) { throw Exception(output.errorMessage) } - return listOf(output.encoded.toByteArray()) + return listOf(output.encoded.toByteArray().toHexString("").toByteArray()) } override fun supported(chain: Chain): Boolean = this.chain == chain diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoTransactionStatusClient.kt deleted file mode 100644 index 763f0b90a..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoTransactionStatusClient.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.blockchain.clients.cardano.services.CardanoTransactionService -import com.gemwallet.android.blockchain.clients.cardano.services.transaction -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState - -class CardanoTransactionStatusClient( - private val chain: Chain, - private val transactionsService: CardanoTransactionService, -) : TransactionStatusClient { - - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val transaction = transactionsService.transaction(request.hash) ?: throw ServiceUnavailable - return TransactionChanges( - state = TransactionState.Confirmed, - fee = transaction.fee.toBigInteger(), - ) -// TODO: transaction.block.number - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoBalanceService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoBalanceService.kt deleted file mode 100644 index 01e463f72..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoBalanceService.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano.services - -import com.wallet.core.blockchain.cardano.CardanoAggregateBalance -import com.wallet.core.blockchain.cardano.CardanoUTXOS -import com.wallet.core.primitives.GraphqlData -import com.wallet.core.primitives.GraphqlRequest -import retrofit2.http.Body -import retrofit2.http.POST -import java.math.BigInteger - -interface CardanoBalanceService { - - @POST("/") - suspend fun balance(@Body request: GraphqlRequest): Result>> - -} - -suspend fun CardanoBalanceService.balance(address: String): BigInteger? { - val request = GraphqlRequest( - operationName = "GetBalance", - variables = hashMapOf( - "address" to address - ), - query = "query GetBalance(\$address: String!) { utxos: utxos_aggregate(where: { address: { _eq: \$address } } ) { aggregate { sum { value } } } }" - ) - return balance(request).getOrNull()?.data?.utxos?.aggregate?.sum?.value?.toBigInteger() -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoBroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoBroadcastService.kt deleted file mode 100644 index 13910ef06..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoBroadcastService.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano.services - -import com.wallet.core.blockchain.cardano.CardanoTransactionBroadcast -import com.wallet.core.primitives.GraphqlData -import com.wallet.core.primitives.GraphqlRequest -import retrofit2.http.Body -import retrofit2.http.POST - -interface CardanoBroadcastService { - @POST("/") - suspend fun broadcast(@Body request: GraphqlRequest): Result> -} - -suspend fun CardanoBroadcastService.broadcast(data: String): CardanoTransactionBroadcast? { - val request = GraphqlRequest( - operationName = "SubmitTransaction", - variables = hashMapOf("transaction" to data), - query = "mutation SubmitTransaction(\$transaction: String!) { submitTransaction(transaction: \$transaction) { hash } }" - ) - val result = broadcast(request) - val data = result.getOrNull() - return data?.errors?.firstOrNull()?.let { - throw Exception(it.message) - } ?: data?.data -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoFeeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoFeeService.kt deleted file mode 100644 index c051c380f..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoFeeService.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano.services - -import com.wallet.core.blockchain.cardano.CardanoUTXO -import com.wallet.core.blockchain.cardano.CardanoUTXOS -import com.wallet.core.primitives.GraphqlData -import com.wallet.core.primitives.GraphqlRequest -import com.wallet.core.primitives.UTXO -import retrofit2.http.Body -import retrofit2.http.POST - -interface CardanoFeeService { - @POST("/") - suspend fun utxos(@Body request: GraphqlRequest): Result>>> -} - -suspend fun CardanoFeeService.utxos(address: String): List { - val request = GraphqlRequest( - operationName = "UtxoSetForAddress", - variables = hashMapOf("address" to address), - query = "query UtxoSetForAddress(\$address: String!) { utxos(order_by: { value: desc } , where: { address: { _eq: \$address } } ) { address value txHash index tokens { quantity asset { fingerprint policyId assetName } } } }" - ) - return utxos(request).getOrNull()?.data?.utxos?.map { - UTXO( - transaction_id = it.txHash, - vout = it.index, - value = it.value, - address = it.address, - ) - } ?: emptyList() -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoNodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoNodeStatusService.kt deleted file mode 100644 index c12d04581..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoNodeStatusService.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano.services - -import com.wallet.core.blockchain.cardano.CardanoBlockData -import com.wallet.core.blockchain.cardano.CardanoGenesisData -import com.wallet.core.primitives.GraphqlData -import com.wallet.core.primitives.GraphqlRequest -import retrofit2.Response -import retrofit2.http.Body -import retrofit2.http.POST -import retrofit2.http.Url - -interface CardanoNodeStatusService { - @POST - suspend fun latestBlock(@Url url: String, @Body request: GraphqlRequest): Response> - - @POST - suspend fun networkMagic(@Url url: String, @Body request: GraphqlRequest): Response> -} - -suspend fun CardanoNodeStatusService.latestBlock(url: String): Response> { - val request = GraphqlRequest( - operationName = "GetBlockNumber", - variables = hashMapOf(), - query = "query GetBlockNumber { cardano { tip { number } } }" - ) - return latestBlock(url, request) -} - -suspend fun CardanoNodeStatusService.networkMagic(url: String): Response> { - val request = GraphqlRequest( - operationName = "GetNetworkMagic", - variables = hashMapOf(), - query = "query GetNetworkMagic { genesis { shelley { networkMagic } } }" - ) - return networkMagic(url, request) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoServices.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoServices.kt index 78be5b297..c93f0cda2 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoServices.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoServices.kt @@ -1,7 +1,30 @@ package com.gemwallet.android.blockchain.clients.cardano.services -interface CardanoServices : CardanoBalanceService, - CardanoTransactionService, - CardanoFeeService, - CardanoBroadcastService, - CardanoNodeStatusService \ No newline at end of file +import com.wallet.core.blockchain.cardano.CardanoUTXO +import com.wallet.core.blockchain.cardano.CardanoUTXOS +import com.wallet.core.primitives.GraphqlData +import com.wallet.core.primitives.GraphqlRequest +import com.wallet.core.primitives.UTXO +import retrofit2.http.Body +import retrofit2.http.POST + +interface CardanoServices { + @POST("/") + suspend fun utxos(@Body request: GraphqlRequest): Result>>> +} + +suspend fun CardanoServices.utxos(address: String): List { + val request = GraphqlRequest( + operationName = "UtxoSetForAddress", + variables = hashMapOf("address" to address), + query = "query UtxoSetForAddress(\$address: String!) { utxos(order_by: { value: desc } , where: { address: { _eq: \$address } } ) { address value txHash index tokens { quantity asset { fingerprint policyId assetName } } } }" + ) + return utxos(request).getOrNull()?.data?.utxos?.map { + UTXO( + transaction_id = it.txHash, + vout = it.index, + value = it.value, + address = it.address, + ) + } ?: emptyList() +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoTransactionService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoTransactionService.kt deleted file mode 100644 index 34cf13111..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoTransactionService.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano.services - -import com.wallet.core.blockchain.cardano.CardanoTransaction -import com.wallet.core.blockchain.cardano.CardanoTransactions -import com.wallet.core.primitives.GraphqlData -import com.wallet.core.primitives.GraphqlRequest -import retrofit2.http.Body -import retrofit2.http.POST - -interface CardanoTransactionService { - - @POST("/") - suspend fun transaction(@Body request: GraphqlRequest): Result> -} - -suspend fun CardanoTransactionService.transaction(hash: String): CardanoTransaction? { - val request = GraphqlRequest( - operationName = "TransactionsByHash", - variables = hashMapOf( - "hash" to hash, - ), - query = "query TransactionsByHash(\$hash: Hash32Hex!) { transactions(where: { hash: { _eq: \$hash } } ) { block { number } fee } }" - ) - return transaction(request).getOrNull()?.data?.transactions?.firstOrNull() -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosBalanceClient.kt deleted file mode 100644 index b17f873d8..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosBalanceClient.kt +++ /dev/null @@ -1,135 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosBalancesService -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosStakeService -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.CosmosDenom -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import java.math.BigInteger - -class CosmosBalanceClient( - private val chain: Chain, - private val balancesService: CosmosBalancesService, - private val stakeService: CosmosStakeService, -) : BalanceClient { - - override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? = withContext(Dispatchers.IO) { - val denom = CosmosDenom.from(chain) - - val getBalances = async { balancesService.getBalance(address).getOrNull()?.balances } - val response = getBalances.await() - val balance = response?.filter { it.denom == denom } - ?.map { it.amount.toBigDecimal().toBigInteger() } - ?.fold(BigInteger.ZERO) { acc, value -> acc + value} ?: return@withContext null - - when (chain) { - Chain.Thorchain, - Chain.Noble -> AssetBalance.create(chain.asset(), available = balance.toString()) - else -> { - val getDelegations = async { stakeService.delegations(address).getOrNull()?.delegation_responses } - val getUnboundingDelegations = async { stakeService.undelegations(address).getOrNull()?.unbonding_responses } - val getRewards = async { stakeService.rewards(address).getOrNull()?.rewards } - - val delegations = getDelegations.await() - ?.filter { it.balance.denom == denom } - ?.map { it.balance.amount.toBigDecimal().toBigInteger() } - ?.fold(BigInteger.ZERO) { acc, value -> acc + value} ?: return@withContext null - val undelegations = getUnboundingDelegations.await() - ?.mapNotNull { entry -> - entry.entries.map { it.balance.toBigDecimal().toBigInteger() } - .reduceOrNull { acc, value -> acc + value } - } - ?.fold(BigInteger.ZERO) { acc, value -> acc + value } ?: return@withContext null - val rewards = getRewards.await() - ?.mapNotNull { reward -> - reward.reward - .filter { it.denom == denom } - .map { it.amount.toBigDecimal().toBigInteger() } - .reduceOrNull { acc, value -> acc + value} - }?.fold(BigInteger.ZERO) { acc, value -> acc + value } ?: return@withContext null - AssetBalance.create( - asset = chain.asset(), - available = balance.toString(), - staked = delegations.toString(), - pending = undelegations.toString(), - rewards = rewards.toString(), - ) - } - } - } - - override suspend fun getDelegationBalances(chain: Chain, address: String): AssetBalance? = withContext(Dispatchers.IO) { - when (chain) { - Chain.Thorchain, - Chain.Noble -> return@withContext null - else -> {} - } - val denom = CosmosDenom.from(chain) - - val getDelegations = async { stakeService.delegations(address).getOrNull()?.delegation_responses } - val getUnboundingDelegations = async { stakeService.undelegations(address).getOrNull()?.unbonding_responses } - val getRewards = async { stakeService.rewards(address).getOrNull()?.rewards } - - val delegations = getDelegations.await() - ?.filter { it.balance.denom == denom } - ?.map { it.balance.amount.toBigDecimal().toBigInteger() } - ?.fold(BigInteger.ZERO) { acc, value -> acc + value} ?: return@withContext null - val undelegations = getUnboundingDelegations.await() - ?.mapNotNull { entry -> - entry.entries.map { it.balance.toBigDecimal().toBigInteger() } - .reduceOrNull { acc, value -> acc + value } - } - ?.fold(BigInteger.ZERO) { acc, value -> acc + value } ?: return@withContext null - val rewards = getRewards.await() - ?.mapNotNull { reward -> - reward.reward - .filter { it.denom == denom } - .map { it.amount.toBigDecimal().toBigInteger() } - .reduceOrNull { acc, value -> acc + value} - }?.fold(BigInteger.ZERO) { acc, value -> acc + value } ?: return@withContext null - AssetBalance.create( - asset = chain.asset(), - staked = delegations.toString(), - pending = undelegations.toString(), - rewards = rewards.toString(), - ) - } - - override suspend fun getTokenBalances(chain: Chain, address: String, tokens: List): List { - val balances = try { - balancesService.getBalance(address).getOrNull() ?: return emptyList() - } catch (_: Throwable) { - return emptyList() - } - return tokens.map { asset -> - val amount = balances.balances.firstOrNull { it.denom == asset.id.tokenId }?.amount ?: "0" - AssetBalance.create( - asset, - available = try { - amount - } catch (_: Throwable) { - return@map null - } - ) - }.mapNotNull { it } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} - -fun CosmosDenom.Companion.from(chain: Chain): String = when (chain) { - Chain.Cosmos -> CosmosDenom.Uatom.string - Chain.Osmosis -> CosmosDenom.Uosmo.string - Chain.Thorchain -> CosmosDenom.Rune.string - Chain.Celestia -> CosmosDenom.Utia.string - Chain.Injective -> CosmosDenom.Inj.string - Chain.Sei -> CosmosDenom.Usei.string - Chain.Noble -> CosmosDenom.Uusdc.string - else -> throw IllegalArgumentException("Coin is not supported") -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosBroadcastClient.kt deleted file mode 100644 index 757a39f70..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosBroadcastClient.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import com.gemwallet.android.blockchain.Mime -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosBroadcastService -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import okhttp3.RequestBody.Companion.toRequestBody - -class CosmosBroadcastClient( - private val chain: Chain, - private val broadcastService: CosmosBroadcastService, -) : BroadcastClient { - - override suspend fun send(account: Account, signedMessage: ByteArray, type: TransactionType): String { - val requestData = signedMessage.toString(Charsets.UTF_8) - val requestBody = requestData.toRequestBody(Mime.Json.value) - val result = broadcastService.broadcast(requestBody) - val data = result.getOrNull() ?: throw Exception(result.exceptionOrNull()?.message ?: "Broadcast error") - if (data.tx_response.code != 0) { - throw Exception(data.tx_response.raw_log) - } - return data.tx_response.txhash - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosDenom.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosDenom.kt new file mode 100644 index 000000000..f9e22173c --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosDenom.kt @@ -0,0 +1,15 @@ +package com.gemwallet.android.blockchain.clients.cosmos + +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.CosmosDenom + +fun CosmosDenom.Companion.from(chain: Chain): String = when (chain) { + Chain.Cosmos -> CosmosDenom.Uatom.string + Chain.Osmosis -> CosmosDenom.Uosmo.string + Chain.Thorchain -> CosmosDenom.Rune.string + Chain.Celestia -> CosmosDenom.Utia.string + Chain.Injective -> CosmosDenom.Inj.string + Chain.Sei -> CosmosDenom.Usei.string + Chain.Noble -> CosmosDenom.Uusdc.string + else -> throw IllegalArgumentException("Coin is not supported") +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosNodeStatusClient.kt deleted file mode 100644 index 1c3e55fd2..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosNodeStatusClient.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosNodeStatusService -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class CosmosNodeStatusClient( - private val chain: Chain, - private val nodeStatusService: CosmosNodeStatusService, -) : NodeStatusClient { - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? = withContext(Dispatchers.IO) { - val inSyncJob = async { nodeStatusService.syncing("$url/cosmos/base/tendermint/v1beta1/syncing") } - val nodeInfoJob = async { nodeStatusService.getNodeInfo("$url/cosmos/base/tendermint/v1beta1/blocks/latest").getOrNull()?.block?.header } - - val inSync = inSyncJob.await() - val nodeInfo = nodeInfoJob.await() ?: return@withContext null - - NodeStatus( - url = url, - inSync = !(inSync.body()?.syncing ?: return@withContext null), - blockNumber = nodeInfo.height, - chainId = nodeInfo.chain_id, - latency = inSync.getLatency() - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt index 030bd6a0f..0c4d6094f 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt @@ -4,7 +4,7 @@ import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosAccountsService +import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosRpcClient import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee @@ -17,7 +17,7 @@ import kotlinx.coroutines.withContext class CosmosSignerPreloader( private val chain: Chain, - private val accountsService: CosmosAccountsService, + private val client: CosmosRpcClient, ) : NativeTransferPreloader, TokenTransferPreloader, StakeTransactionPreloader, SwapTransactionPreloader { private val feeCalculator = CosmosFeeCalculator(chain) @@ -42,11 +42,11 @@ class CosmosSignerPreloader( private suspend fun preload(params: ConfirmParams) = withContext(Dispatchers.IO) { val accountJob = async { when (chain) { - Chain.Injective -> accountsService.getInjectiveAccountData(params.from.address).getOrNull()?.account?.base_account - else -> accountsService.getAccountData(params.from.address).getOrNull()?.account + Chain.Injective -> client.getInjectiveAccountData(params.from.address).getOrNull()?.account?.base_account + else -> client.getAccountData(params.from.address).getOrNull()?.account } } - val nodeInfoJob = async { accountsService.getNodeInfo().getOrNull()?.block?.header?.chain_id } + val nodeInfoJob = async { client.getNodeInfo().getOrNull()?.block?.header?.chain_id } val fee = feeCalculator.calculate(params.getTxType()) val (account, nodeInfo) = Pair( diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosStakeClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosStakeClient.kt deleted file mode 100644 index c13647cd1..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosStakeClient.kt +++ /dev/null @@ -1,97 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import android.annotation.SuppressLint -import com.gemwallet.android.blockchain.clients.StakeClient -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosStakeService -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.CosmosDenom -import com.wallet.core.primitives.DelegationBase -import com.wallet.core.primitives.DelegationState -import com.wallet.core.primitives.DelegationValidator -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import java.math.BigInteger -import java.text.SimpleDateFormat - -class CosmosStakeClient( - private val chain: Chain, - private val stakeService: CosmosStakeService, -) : StakeClient { - - @SuppressLint("SimpleDateFormat") - private val completionDateFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX") - - override suspend fun getValidators(chain: Chain, apr: Double): List { - return stakeService.validators().getOrNull()?.validators?.map { - val commission = it.commission.commission_rates.rate.toDouble() - val isActive = !it.jailed && it.status == "BOND_STATUS_BONDED" - DelegationValidator( - chain = chain, - id = it.operator_address, - name = it.description.moniker, - isActive = isActive, - commision = commission, - apr = if (isActive) apr - (apr * commission) else 0.0, - ) - } ?: emptyList() - } - - override suspend fun getStakeDelegations(chain: Chain, address: String, apr: Double): List = withContext(Dispatchers.IO) { - val getDelegations = async { stakeService.delegations(address).getOrNull()?.delegation_responses } - val getUnboundingDelegations = async { stakeService.undelegations(address).getOrNull()?.unbonding_responses } - val getRewards = async { - stakeService.rewards(address).getOrNull()?.rewards - ?.associateBy { it.validator_address } - ?.mapValues { entry -> - entry.value.reward - .filter { it.denom == CosmosDenom.from(chain) } - .mapNotNull { - try { - BigInteger(it.amount.split(".")[0]) - } catch (_: Throwable) { - BigInteger.ZERO - } - } - .reduceOrNull { acc, value -> acc + value } - ?.toString() - } ?: emptyMap() - } - val delegations = getDelegations.await() - val undelegations = getUnboundingDelegations.await() - val rewards = getRewards.await() - - val baseDelegations = delegations?.map { - DelegationBase( - assetId = AssetId(chain), - state = DelegationState.Active, - balance = it.balance.amount, - completionDate = null, - delegationId = "", - validatorId = it.delegation.validator_address, - rewards = rewards[it.delegation.validator_address] ?: "0", - shares = "", - ) - } ?: emptyList() - - val baseUndelegations: List = undelegations?.map { undelegation -> - undelegation.entries.map { entry -> - DelegationBase( - assetId = AssetId(chain), - state = DelegationState.Pending, - balance = entry.balance, - completionDate = completionDateFormatter.parse(entry.completion_time)?.time, //2024-02-28T08:12:56.376120563Z - delegationId = entry.creation_height, - validatorId = undelegation.validator_address, - rewards = rewards[undelegation.validator_address] ?: "0", - shares = "", - ) - } - }?.flatten() ?: emptyList() - - (baseDelegations + baseUndelegations) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosTransactionStatusClient.kt deleted file mode 100644 index fdbdc35a3..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosTransactionStatusClient.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosTransactionsService -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState - -class CosmosTransactionStatusClient( - private val chain: Chain, - private val transactionsService: CosmosTransactionsService, -) : TransactionStatusClient { - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val tx = transactionsService.transaction(request.hash).getOrNull() ?: throw ServiceUnavailable - val state = when { - tx.tx_response == null || tx.tx_response.txhash.isEmpty() -> TransactionState.Pending - tx.tx_response.code == 0 -> TransactionState.Confirmed - else -> TransactionState.Reverted - } - return TransactionChanges(state) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosAccountsService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosAccountsService.kt deleted file mode 100644 index 9ccbb2e0b..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosAccountsService.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos.services - -import com.wallet.core.blockchain.cosmos.CosmosAccount -import com.wallet.core.blockchain.cosmos.CosmosAccountResponse -import com.wallet.core.blockchain.cosmos.CosmosBlockResponse -import com.wallet.core.blockchain.cosmos.CosmosInjectiveAccount -import retrofit2.http.GET -import retrofit2.http.Path - -interface CosmosAccountsService { - @GET("/cosmos/auth/v1beta1/accounts/{owner}") - suspend fun getAccountData(@Path("owner") owner: String): Result> - - @GET("/cosmos/auth/v1beta1/accounts/{owner}") - suspend fun getInjectiveAccountData(@Path("owner") owner: String): Result> - - @GET("/cosmos/base/tendermint/v1beta1/blocks/latest") - suspend fun getNodeInfo(): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosBalancesService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosBalancesService.kt deleted file mode 100644 index 4e62720ee..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosBalancesService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos.services - -import com.wallet.core.blockchain.cosmos.CosmosBalances -import retrofit2.http.GET -import retrofit2.http.Path - -interface CosmosBalancesService { - @GET("/cosmos/bank/v1beta1/balances/{owner}") - suspend fun getBalance(@Path("owner") owner: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosBroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosBroadcastService.kt deleted file mode 100644 index b1f013e18..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosBroadcastService.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos.services - -import com.wallet.core.blockchain.cosmos.CosmosBroadcastResponse -import okhttp3.RequestBody -import retrofit2.http.Body -import retrofit2.http.POST - -interface CosmosBroadcastService { - @POST("/cosmos/tx/v1beta1/txs") - suspend fun broadcast(@Body body: RequestBody): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosNodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosNodeStatusService.kt deleted file mode 100644 index 2497c8c7a..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosNodeStatusService.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos.services - -import com.wallet.core.blockchain.cosmos.CosmosBlockResponse -import com.wallet.core.blockchain.cosmos.CosmosSyncing -import retrofit2.Response -import retrofit2.http.GET -import retrofit2.http.Url - -interface CosmosNodeStatusService { - @GET//("/cosmos/base/tendermint/v1beta1/syncing") - suspend fun syncing(@Url url: String): Response - - @GET//("/cosmos/base/tendermint/v1beta1/blocks/latest") - suspend fun getNodeInfo(@Url url: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosRpcClient.kt index 81914b9d9..050d14233 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosRpcClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosRpcClient.kt @@ -1,9 +1,19 @@ package com.gemwallet.android.blockchain.clients.cosmos.services -interface CosmosRpcClient : - CosmosBalancesService, - CosmosAccountsService, - CosmosStakeService, - CosmosTransactionsService, - CosmosBroadcastService, - CosmosNodeStatusService \ No newline at end of file +import com.wallet.core.blockchain.cosmos.CosmosAccount +import com.wallet.core.blockchain.cosmos.CosmosAccountResponse +import com.wallet.core.blockchain.cosmos.CosmosBlockResponse +import com.wallet.core.blockchain.cosmos.CosmosInjectiveAccount +import retrofit2.http.GET +import retrofit2.http.Path + +interface CosmosRpcClient { + @GET("/cosmos/auth/v1beta1/accounts/{owner}") + suspend fun getAccountData(@Path("owner") owner: String): Result> + + @GET("/cosmos/auth/v1beta1/accounts/{owner}") + suspend fun getInjectiveAccountData(@Path("owner") owner: String): Result> + + @GET("/cosmos/base/tendermint/v1beta1/blocks/latest") + suspend fun getNodeInfo(): Result +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosStakeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosStakeService.kt deleted file mode 100644 index ba39a7326..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosStakeService.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos.services - -import com.wallet.core.blockchain.cosmos.CosmosDelegations -import com.wallet.core.blockchain.cosmos.CosmosRewards -import com.wallet.core.blockchain.cosmos.CosmosUnboundingDelegations -import com.wallet.core.blockchain.cosmos.CosmosValidators -import retrofit2.http.GET -import retrofit2.http.Path - -interface CosmosStakeService { - - @GET("/cosmos/staking/v1beta1/validators?pagination.limit=1000") - suspend fun validators(): Result - - @GET("/cosmos/staking/v1beta1/delegations/{address}") - suspend fun delegations(@Path("address") address: String): Result - - @GET("/cosmos/staking/v1beta1/delegators/{address}/unbonding_delegations") - suspend fun undelegations(@Path("address") address: String): Result - - @GET("/cosmos/distribution/v1beta1/delegators/{address}/rewards") - suspend fun rewards(@Path("address") address: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosTransactionsService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosTransactionsService.kt deleted file mode 100644 index be1c4e5ba..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosTransactionsService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos.services - -import com.wallet.core.blockchain.cosmos.CosmosTransactionResponse -import retrofit2.http.GET -import retrofit2.http.Path - -interface CosmosTransactionsService { - @GET("/cosmos/tx/v1beta1/txs/{txId}") - suspend fun transaction(@Path("txId") txId: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmNodeStatusClient.kt index c61a4d94a..60399f64b 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmNodeStatusClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmNodeStatusClient.kt @@ -29,7 +29,7 @@ class EvmNodeStatusClient( NodeStatus( url = url, chainId = chainId.body()?.result?.value?.toString() ?: return@withContext null, - blockNumber = blockNumber, + blockNumber = blockNumber.toULong(), inSync = !inSync, latency = chainId.getLatency(), ) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBalanceClient.kt deleted file mode 100644 index 92c6c53f1..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBalanceClient.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.gemwallet.android.blockchain.clients.hyper - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Chain - -class HyperCoreBalanceClient( - private val chain: Chain, -) : BalanceClient { - override suspend fun getNativeBalance( - chain: Chain, - address: String - ): AssetBalance? { - TODO("Not yet implemented") - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBroadcatClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBroadcatClient.kt deleted file mode 100644 index 8a7aa1586..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreBroadcatClient.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.gemwallet.android.blockchain.clients.hyper - -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.BroadcastClientProxy -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType - -class HyperCoreBroadcatClient( - private val chain: Chain, -) : BroadcastClient { - override suspend fun send( - account: Account, - signedMessage: ByteArray, - type: TransactionType - ): String { - TODO("Not yet implemented") - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreGetTokenClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreGetTokenClient.kt deleted file mode 100644 index 74845bcf3..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreGetTokenClient.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.gemwallet.android.blockchain.clients.hyper - -import com.gemwallet.android.blockchain.clients.GetTokenClient -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.Chain - -class HyperCoreGetTokenClient( - private val chain: Chain, -) : GetTokenClient { - override suspend fun getTokenData(tokenId: String): Asset? { - TODO("Not yet implemented") - } - - override suspend fun isTokenQuery(query: String): Boolean { - TODO("Not yet implemented") - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreNodeStatusClient.kt deleted file mode 100644 index 9f4d7fb5a..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreNodeStatusClient.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.gemwallet.android.blockchain.clients.hyper - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain - -class HyperCoreNodeStatusClient( - val chain: Chain, -) : NodeStatusClient { - override suspend fun getNodeStatus( - chain: Chain, - url: String - ): NodeStatus? { - TODO("Not yet implemented") - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreStakeClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreStakeClient.kt deleted file mode 100644 index 6de888b38..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreStakeClient.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.gemwallet.android.blockchain.clients.hyper - -import com.gemwallet.android.blockchain.clients.StakeClient -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.DelegationBase -import com.wallet.core.primitives.DelegationValidator - -class HyperCoreStakeClient( - private val chain: Chain -) : StakeClient { - override suspend fun getValidators( - chain: Chain, - apr: Double - ): List { - TODO("Not yet implemented") - } - - override suspend fun getStakeDelegations( - chain: Chain, - address: String, - apr: Double - ): List { - TODO("Not yet implemented") - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreTransactionsStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreTransactionsStatusClient.kt deleted file mode 100644 index fc6b8b2c3..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreTransactionsStatusClient.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.gemwallet.android.blockchain.clients.hyper - -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain - -class HyperCoreTransactionsStatusClient( - private val chain: Chain, -) : TransactionStatusClient { - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - TODO("Not yet implemented") - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearBalanceClient.kt deleted file mode 100644 index b23ecb7e6..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearBalanceClient.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.gemwallet.android.blockchain.clients.near - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Chain - -class NearBalanceClient( - private val chain: Chain, - private val rpcClient: NearRpcClient, -) : BalanceClient { - - override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? { - return rpcClient.account( - JSONRpcRequest( - method = NearMethod.Query.value, - params = mapOf( - "request_type" to "view_account", - "finality" to "final", - "account_id" to address, - ) - ) - ).fold( - { - if (it.error == null) { - AssetBalance.create(chain.asset(), it.result.amount) - } else { - null - } - } - ) { - null - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearBroadcastClient.kt deleted file mode 100644 index 000bc5b18..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearBroadcastClient.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.gemwallet.android.blockchain.clients.near - -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType - -class NearBroadcastClient( - private val chain: Chain, - private val rpcClient: NearRpcClient, -) : BroadcastClient { - override suspend fun send( - account: Account, - signedMessage: ByteArray, - type: TransactionType - ): String { - return rpcClient.broadcast( - JSONRpcRequest( - NearMethod.Broadcast.value, - params = mapOf( - "signed_tx_base64" to String(signedMessage) - ) - ) - ).getOrThrow().result.transaction.hash - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearMethod.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearMethod.kt index ef0e1f9cf..362b5f60a 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearMethod.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearMethod.kt @@ -1,9 +1,6 @@ package com.gemwallet.android.blockchain.clients.near enum class NearMethod(val value: String) { - GasPrice("gas_price"), Query("query"), LatestBlock("block"), - Transaction("tx"), - Broadcast("send_tx"), } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearNodeStatusClient.kt deleted file mode 100644 index 630fb9b4a..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearNodeStatusClient.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.gemwallet.android.blockchain.clients.near - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class NearNodeStatusClient( - private val chain: Chain, - private val rpcClient: NearRpcClient, -) : NodeStatusClient { - - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? = withContext(Dispatchers.IO) { - val getBlock = async { - rpcClient.latestBlock( - url, - JSONRpcRequest( - NearMethod.LatestBlock.value, - mapOf("finality" to "final") - ) - ) - } - val block = getBlock.await() - NodeStatus( - url = url, - blockNumber = block.body()?.result?.header?.height?.toString() ?: return@withContext null, - chainId = "", - inSync = true, - latency = block.getLatency(), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt index 477b12c69..fa949c30b 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt @@ -15,8 +15,6 @@ import retrofit2.http.Url import wallet.core.jni.Base58 interface NearRpcClient { - @POST("/") - suspend fun getGasPrice(@Body params: JSONRpcRequest>): Result> @POST("/") suspend fun account(@Body params: JSONRpcRequest): Result> @@ -27,14 +25,6 @@ interface NearRpcClient { @POST("/") suspend fun latestBlock(@Body params: JSONRpcRequest): Result> - @POST("/") - suspend fun transaction(@Body params: JSONRpcRequest): Result> - - @POST("/") - suspend fun broadcast(@Body params: JSONRpcRequest): Result> - - @POST - suspend fun latestBlock(@Url url: String, @Body params: JSONRpcRequest): Response> } suspend fun NearRpcClient.accountAccessKey(from: String, ): NearAccountAccessKey { @@ -61,13 +51,4 @@ suspend fun NearRpcClient.latestBlock(): NearBlock { ) ) ).getOrNull()?.result ?: throw IllegalStateException("Can't get block") -} - -suspend fun NearRpcClient.getGasPrice(): NearGasPrice { - return getGasPrice( - JSONRpcRequest( - method = NearMethod.GasPrice.value, - params = listOf(null), - ) - ).getOrNull()?.result ?: throw IllegalStateException("Can't get gas price") } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearTransactionStatusClient.kt deleted file mode 100644 index d504f7d29..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearTransactionStatusClient.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.gemwallet.android.blockchain.clients.near - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionError -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState - -class NearTransactionStatusClient( - private val chain: Chain, - private val rpcClient: NearRpcClient, -) : TransactionStatusClient { - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val resp = rpcClient.transaction( - JSONRpcRequest( - method = NearMethod.Transaction.value, - params = mapOf( - "tx_hash" to request.hash, - "sender_account_id" to request.sender, - "wait_until" to "EXECUTED", - ), - ) - ).getOrNull() ?: throw ServiceUnavailable - if (resp.error != null) { - throw TransactionError(resp.error.message) - } - return when (resp.result.final_execution_status) { - "FINAL" -> TransactionChanges(state = TransactionState.Confirmed) - else -> TransactionChanges(state = TransactionState.Pending) - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotBalancesClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotBalancesClient.kt deleted file mode 100644 index 43599591d..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotBalancesClient.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotBalancesService -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Chain -import java.math.BigInteger - -class PolkadotBalancesClient( - private val chain: Chain, - private val balancesService: PolkadotBalancesService -) : BalanceClient { - - override suspend fun getNativeBalance( - chain: Chain, - address: String - ): AssetBalance? { - try { - val resp = balancesService.balance(address).getOrNull() ?: return null - val free = resp.free.toBigInteger() - val reserved = resp.reserved.toBigInteger() - val available = (free - reserved).max(BigInteger.ZERO) - return AssetBalance.create( - chain.asset(), - available = available.toString(), - reserved = reserved.toString(), - ) - } catch (_: Throwable) { - return null - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotBroadcastClient.kt deleted file mode 100644 index 27dd8c411..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotBroadcastClient.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot - -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotBroadcastService -import com.gemwallet.android.math.toHexString -import com.wallet.core.blockchain.polkadot.PolkadotTransactionPayload -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType - -class PolkadotBroadcastClient( - private val chain: Chain, - private val broadcastService: PolkadotBroadcastService, -) : BroadcastClient { - override suspend fun send( - account: Account, - signedMessage: ByteArray, - type: TransactionType - ): String { - val resp = broadcastService.broadcast(PolkadotTransactionPayload(signedMessage.toHexString())).getOrNull() - ?: throw Exception("Polkadot service unavailable") - return if (resp.hash.isNullOrEmpty()) { - throw Exception(resp.cause ?: resp.error ?: "Broadcast error") - } else { - resp.hash - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotFeeCalculator.kt deleted file mode 100644 index 94055e461..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotFeeCalculator.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot - -import com.gemwallet.android.model.Fee -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import java.math.BigInteger - -class PolkadotFeeCalculator { - fun calculate(): Fee = Fee(priority = FeePriority.Normal, feeAssetId = AssetId(Chain.Polkadot), amount = BigInteger.ONE) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotNodeStatusClient.kt deleted file mode 100644 index 5cf623209..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotNodeStatusClient.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotNodeStatusService -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class PolkadotNodeStatusClient( - private val chain: Chain, - private val nodeStatusService: PolkadotNodeStatusService, -) : NodeStatusClient { - - override suspend fun getNodeStatus( - chain: Chain, - url: String - ): NodeStatus? = withContext(Dispatchers.IO) { - val getBlock = async { nodeStatusService.blockHead("$url/blocks/head") } - val getVersion = async { nodeStatusService.nodeVersion("$url/node/version") } - - val version = getVersion.await() - val block = getBlock.await() - - NodeStatus( - url = url, - chainId = version.body()?.chain ?: return@withContext null, - blockNumber = block.body()?.number ?: return@withContext null, - inSync = true, - latency = version.getLatency() - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt index a34f99d8c..ce21fc83d 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt @@ -49,7 +49,7 @@ class PolkadotSignClient( }.build() }.build() val output = AnySigner.sign(input, CoinType.POLKADOT, Polkadot.SigningOutput.parser()) - return listOf(output.encoded.toByteArray()) + return listOf(output.encoded.toByteArray().toHexString().toByteArray()) } override fun supported(chain: Chain): Boolean = this.chain == chain diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt index 0bc191960..12b4234b5 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt @@ -2,9 +2,7 @@ package com.gemwallet.android.blockchain.clients.polkadot import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.polkadot.models.PolkadotSigningData -import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotBalancesService -import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotFeeService -import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotTransactionService +import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotServices import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee @@ -19,15 +17,13 @@ import kotlinx.coroutines.withContext class PolkadotSignerPreloaderClient( private val chain: Chain, - private val transactionService: PolkadotTransactionService, - private val feeService: PolkadotFeeService, - private val balancesService: PolkadotBalancesService, + private val client: PolkadotServices, ) : NativeTransferPreloader { override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams = withContext(Dispatchers.IO) { - val getTransactionMaterial = async { transactionService.transactionMaterial().getOrNull() } - val getBalance = async { balancesService.balance(params.destination.address).getOrNull() } - val getNonce = async { balancesService.balance(params.from.address).getOrNull()?.nonce?.toLong() } + val getTransactionMaterial = async { client.transactionMaterial().getOrNull() } + val getBalance = async { client.balance(params.destination.address).getOrNull() } + val getNonce = async { client.balance(params.from.address).getOrNull()?.nonce?.toLong() } val transactionMaterial = getTransactionMaterial.await() ?: throw Exception("Can't load chain data") val balance = getBalance.await() ?: throw Exception("Can't load chain data") @@ -53,7 +49,7 @@ class PolkadotSignerPreloaderClient( nonce = nonce, data = signData, ) - val feeAmount = feeService.fee(PolkadotTransactionPayload(transactionData)).getOrNull()?.partialFee?.toBigInteger() + val feeAmount = client.fee(PolkadotTransactionPayload(transactionData)).getOrNull()?.partialFee?.toBigInteger() ?: throw java.lang.Exception("Can't estimate fee") val fee = Fee( priority = FeePriority.Normal, diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotTransactionStatusClient.kt deleted file mode 100644 index d1870c149..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotTransactionStatusClient.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotTransactionService -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState -import java.math.BigInteger - -class PolkadotTransactionStatusClient( - private val chain: Chain, - private val transactionService: PolkadotTransactionService, -) : TransactionStatusClient { - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val blockNumber = try { - request.block.toBigInteger() - } catch (_: Throwable) { - BigInteger.ZERO - } - if (blockNumber < BigInteger.ZERO) { - throw Exception("Invalid block number") - } - val blockHead = transactionService.blockHead().getOrNull()?.number?.toBigInteger() ?: throw ServiceUnavailable - val fromBlock = request.block - val toBlock = blockHead.min(blockNumber + BigInteger.valueOf(PolkadotSignerPreloaderClient.periodLength)) - val blocks = transactionService.blocks("$fromBlock-$toBlock").getOrNull() ?: emptyList() - for (block in blocks) { - for (extr in block.extrinsics) { - if (extr.hash == request.hash) { - val state = if (extr.success) TransactionState.Confirmed else TransactionState.Failed - return TransactionChanges(state) - } - } - } - return TransactionChanges(TransactionState.Pending) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/models/PolkadotTransactionBroadcast.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/models/PolkadotTransactionBroadcast.kt deleted file mode 100644 index 40928a698..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/models/PolkadotTransactionBroadcast.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot.models - -import kotlinx.serialization.Serializable - -@Serializable -data class PolkadotTransactionBroadcast( - val hash: String?, - val error: String?, - val cause: String?, -) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotBalancesService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotBalancesService.kt deleted file mode 100644 index 1675e586b..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotBalancesService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot.services - -import com.wallet.core.blockchain.polkadot.PolkadotAccountBalance -import retrofit2.http.GET -import retrofit2.http.Path - -interface PolkadotBalancesService { - @GET("/accounts/{address}/balance-info") - suspend fun balance(@Path("address") address: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotBroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotBroadcastService.kt deleted file mode 100644 index 17053d2f8..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotBroadcastService.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot.services - -import com.gemwallet.android.blockchain.clients.polkadot.models.PolkadotTransactionBroadcast -import com.wallet.core.blockchain.polkadot.PolkadotTransactionPayload -import retrofit2.http.Body -import retrofit2.http.POST - -interface PolkadotBroadcastService { - @POST("/transaction") - suspend fun broadcast(@Body data: PolkadotTransactionPayload): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotFeeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotFeeService.kt deleted file mode 100644 index 9e918f33a..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotFeeService.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot.services - -import com.wallet.core.blockchain.polkadot.PolkadotEstimateFee -import com.wallet.core.blockchain.polkadot.PolkadotTransactionPayload -import retrofit2.http.Body -import retrofit2.http.POST - -interface PolkadotFeeService { - @POST("/transaction/fee-estimate") - suspend fun fee(@Body data: PolkadotTransactionPayload): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotNodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotNodeStatusService.kt deleted file mode 100644 index df5bc9bde..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotNodeStatusService.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot.services - -import com.wallet.core.blockchain.polkadot.PolkadotBlock -import com.wallet.core.blockchain.polkadot.PolkadotNodeVersion -import retrofit2.Response -import retrofit2.http.GET -import retrofit2.http.Url - -interface PolkadotNodeStatusService { - @GET//(/node/version) - suspend fun nodeVersion(@Url url: String): Response - - @GET//("/blocks/head") - suspend fun blockHead(@Url url: String): Response -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotServices.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotServices.kt index c1dfdb69d..e91bb4d0c 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotServices.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotServices.kt @@ -1,7 +1,21 @@ package com.gemwallet.android.blockchain.clients.polkadot.services -interface PolkadotServices : PolkadotBalancesService, - PolkadotBroadcastService, - PolkadotFeeService, - PolkadotNodeStatusService, - PolkadotTransactionService \ No newline at end of file +import com.wallet.core.blockchain.polkadot.PolkadotAccountBalance +import com.wallet.core.blockchain.polkadot.PolkadotEstimateFee +import com.wallet.core.blockchain.polkadot.PolkadotTransactionMaterial +import com.wallet.core.blockchain.polkadot.PolkadotTransactionPayload +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.Path + +interface PolkadotServices { + @POST("/transaction/fee-estimate") + suspend fun fee(@Body data: PolkadotTransactionPayload): Result + + @GET("/accounts/{address}/balance-info") + suspend fun balance(@Path("address") address: String): Result + + @GET("/transaction/material?noMeta=true") + suspend fun transactionMaterial(): Result +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotTransactionService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotTransactionService.kt deleted file mode 100644 index 843ab7dc1..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotTransactionService.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot.services - -import com.wallet.core.blockchain.polkadot.PolkadotBlock -import com.wallet.core.blockchain.polkadot.PolkadotTransactionMaterial -import retrofit2.http.GET -import retrofit2.http.Query - -interface PolkadotTransactionService { - @GET("/transaction/material?noMeta=true") - suspend fun transactionMaterial(): Result - - @GET("/blocks/head") - suspend fun blockHead(): Result - - @GET("/blocks?noFees=true") - suspend fun blocks(@Query("range") range: String): Result> -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaBalanceClient.kt deleted file mode 100644 index ae1f82ff6..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaBalanceClient.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.solana.services.SolanaAccountsService -import com.gemwallet.android.blockchain.clients.solana.services.SolanaBalancesService -import com.gemwallet.android.blockchain.clients.solana.services.SolanaStakeService -import com.gemwallet.android.blockchain.clients.solana.services.getBalance -import com.gemwallet.android.blockchain.clients.solana.services.getDelegationsBalance -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import java.math.BigInteger - -class SolanaBalanceClient( - val chain: Chain, - val accountsService: SolanaAccountsService, - val balancesService: SolanaBalancesService, - val stakeService: SolanaStakeService, -) : BalanceClient { - - override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? = withContext(Dispatchers.IO) { - val available = balancesService.getBalance(address) ?: return@withContext null - AssetBalance.create(chain.asset(), available.toString()) - } - - override suspend fun getDelegationBalances(chain: Chain, address: String): AssetBalance? { - val staked = stakeService.getDelegationsBalance(address) - return AssetBalance.create(chain.asset(), staked = staked.toString()) - } - - override suspend fun getTokenBalances(chain: Chain, address: String, tokens: List): List { - val accountsRequests = tokens.map { - JSONRpcRequest.create( - method = SolanaMethod.GetTokenAccountByOwner, - params = listOf( - address, - mapOf("mint" to it.id.tokenId!!), - mapOf("encoding" to "jsonParsed"), - ) - ) - } - - val responseAccountOwner = try { - accountsService.batchAccount(accountsRequests) - } catch (err: Throwable) { - throw err - } - val balances = responseAccountOwner.mapIndexed { index, value -> - val balance = value.result.value.firstOrNull()?.let { account -> - account.account.data.parsed.info.tokenAmount.amount.toBigIntegerOrNull() - } ?: BigInteger.ZERO - AssetBalance.create(tokens[index], available = balance.toString()) - } - return balances - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaBroadcastClient.kt deleted file mode 100644 index abe5ebf8f..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaBroadcastClient.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.solana.services.SolanaBroadcastService -import com.gemwallet.android.blockchain.rpc.ServiceError -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import java.nio.charset.StandardCharsets - -class SolanaBroadcastClient( - private val chain: Chain, - private val rpcClient: SolanaBroadcastService, -) : BroadcastClient { - override suspend fun send(account: Account, signedMessage: ByteArray, type: TransactionType): String { - val encodedMessage = signedMessage.toString(StandardCharsets.UTF_8) - val params = if (type == TransactionType.Swap) { - listOf( - encodedMessage, - mapOf( - "encoding" to "base64", - "skipPreflight" to true, - ), - ) - } else { - listOf( - encodedMessage, - mapOf("encoding" to "base64"), - ) - } - val request = JSONRpcRequest.create(SolanaMethod.SendTransaction, params) - val response = rpcClient.broadcast(request).getOrNull() ?: throw ServiceError.NetworkError - return if (response.error == null) { - response.result - } else { - throw Exception(response.error.message) - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaFeeCalculator.kt deleted file mode 100644 index 8552ddf66..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaFeeCalculator.kt +++ /dev/null @@ -1,94 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.solana.services.SolanaFeeService -import com.gemwallet.android.blockchain.clients.solana.services.getPriorityFees -import com.gemwallet.android.ext.type -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.GasFee -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetSubtype -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import uniffi.gemstone.Config -import java.math.BigInteger -import kotlin.math.max -import kotlin.math.min - -class SolanaFeeCalculator( - private val feeService: SolanaFeeService -) { - - private val staticBaseFee = 5_000L - private val tokenAccountSize = 165 - - suspend fun calculate(params: ConfirmParams): List = when (params) { - is ConfirmParams.Stake -> calculate(params) - is ConfirmParams.SwapParams -> calculate(params) - is ConfirmParams.TokenApprovalParams -> throw IllegalArgumentException("Token approval doesn't support") - is ConfirmParams.TransferParams.Generic -> calculate(params) - is ConfirmParams.TransferParams -> calculate(params) - is ConfirmParams.NftParams, - is ConfirmParams.Activate -> throw IllegalArgumentException() - } - - suspend fun calculate(params: ConfirmParams.Stake): List { - return calculate( - gasLimit = 100_000L, - multipleOf = 50_000, - ) - } - - suspend fun calculate(params: ConfirmParams.TransferParams.Generic): List { - return calculate( - gasLimit = 420_000L, - multipleOf = 250_000, - ) - } - - suspend fun calculate(params: ConfirmParams.TransferParams): List { - return calculate( - gasLimit = 100_000L, - multipleOf = if (params.assetId.type() == AssetSubtype.NATIVE) 50_000 else 100_000, - ) - } - - suspend fun calculate(params: ConfirmParams.SwapParams): List { - return calculate( - gasLimit = 420_000L, - multipleOf = 250_000, - ) - } - - private suspend fun calculate(gasLimit: Long, multipleOf: Long): List { - val priorityFees = feeService.getPriorityFees() - - return FeePriority.entries.map { speed -> - val speedCoefficient = when (speed) { - FeePriority.Slow -> 0.5f - FeePriority.Normal -> 1f - FeePriority.Fast -> 3f - } - val minerFee = if (priorityFees.isEmpty()) { - multipleOf - } else { - val averagePriorityFee = priorityFees.map { it.prioritizationFee }.sortedDescending() - .subList(0, min(5, priorityFees.size - 1)) - .fold(0L) { acc, i -> acc + i } / priorityFees.size - max(((averagePriorityFee + multipleOf - 1) / multipleOf) * multipleOf, multipleOf) - } * speedCoefficient - val tokenAccountCreation = Config().getChainConfig(Chain.Solana.string).tokenActivationFee?.toBigInteger() ?: BigInteger.ZERO - val totalFee = staticBaseFee + (minerFee * gasLimit / 1_000_000) - - GasFee( - feeAssetId = AssetId(Chain.Solana), - priority = speed, - minerFee = minerFee.toLong().toBigInteger(), - maxGasPrice = staticBaseFee.toBigInteger(), - limit = gasLimit.toBigInteger(), - amount = totalFee.toLong().toBigInteger(), - options = mapOf("tokenAccountCreation" to tokenAccountCreation) - ) - } - } - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaMethod.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaMethod.kt deleted file mode 100644 index 5b2d947d7..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaMethod.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcMethod - -enum class SolanaMethod(val value: String) : JSONRpcMethod { - GetBalance("getBalance"), - GetTokenBalance("getTokenAccountBalance"), - GetTokenAccountByOwner("getTokenAccountsByOwner"), - RentExemption("getMinimumBalanceForRentExemption"), - GetLatestBlockhash("getLatestBlockhash"), - GetPriorityFee("getRecentPrioritizationFees"), - SendTransaction("sendTransaction"), - GetTransaction("getTransaction"), - GetValidators("getVoteAccounts"), - GetDelegations("getProgramAccounts"), - GetEpoch("getEpochInfo"), - GetAccountInfo("getAccountInfo"), - GetHealth("getHealth"), - GetSlot("getSlot"), - GetGenesisHash("getGenesisHash") - ; - - override fun value(): String = value -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaNodeStatusClient.kt deleted file mode 100644 index 099fdd61c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaNodeStatusClient.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.clients.solana.services.SolanaNodeStatusService -import com.gemwallet.android.blockchain.clients.solana.services.genesisHash -import com.gemwallet.android.blockchain.clients.solana.services.health -import com.gemwallet.android.blockchain.clients.solana.services.slot -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class SolanaNodeStatusClient( - private val chain: Chain, - private val rpcClient: SolanaNodeStatusService, -) : NodeStatusClient { - - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? = withContext(Dispatchers.IO) { - val inSyncJob = async { rpcClient.health(url) } - val slotJob = async { rpcClient.slot(url).getOrNull()?.result } - val chainIdJob = async { rpcClient.genesisHash(url).getOrNull()?.result } - - val inSync = inSyncJob.await() - - NodeStatus( - url = url, - inSync = inSync.body()?.result == "ok", - blockNumber = slotJob.await().toString(), - chainId = chainIdJob.await() ?: return@withContext null, - latency = inSync.getLatency(), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaRawTxDecoder.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaRawTxDecoder.kt index 9b33c0994..a1aab962c 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaRawTxDecoder.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaRawTxDecoder.kt @@ -13,23 +13,4 @@ class SolanaRawTxDecoder( fun signatureCount(): Byte { return decodeShortVecLength(offset = 0) } - - fun signatures(): ByteArray { - var offset = 0 - val count = decodeShortVecLength(offset = offset) - - var result: ByteArray = byteArrayOf() - for (i in 0 ..< count) { - val sig = rawData.sliceArray(offset ..< (offset + 64)) - result += sig - offset += 64 - } - return result - } - - fun messageData(): List { - val sigCount = decodeShortVecLength(offset = 0).toInt() - val offset = 1 + sigCount * 64 - return rawData.slice(offset ..< rawData.size) - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt index 3c542c7c0..864e251a0 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt @@ -1,6 +1,7 @@ package com.gemwallet.android.blockchain.clients.solana import com.gemwallet.android.blockchain.clients.SignClient +import com.gemwallet.android.blockchain.clients.solana.models.SolanaChainData import com.gemwallet.android.blockchain.operators.GetAsset import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams @@ -80,7 +81,7 @@ class SolanaSignClient( feePriority: FeePriority, privateKey: ByteArray ): List { - val blockhash = (chainData as SolanaSignerPreloader.SolanaChainData).blockhash + val blockhash = (chainData as SolanaChainData).blockhash val input = Solana.SigningInput.newBuilder().apply { this.transferTransaction = Solana.Transfer.newBuilder().apply { this.recipient = params.destination().address @@ -106,10 +107,11 @@ class SolanaSignClient( val tokenId = params.assetId.tokenId val amount = finalAmount.toLong() val recipient = params.destination().address - val metadata = chainData as SolanaSignerPreloader.SolanaChainData + val metadata = chainData as SolanaChainData val tokenProgramId = when (metadata.tokenProgram) { SolanaTokenProgramId.Token -> Solana.TokenProgramId.TokenProgram SolanaTokenProgramId.Token2022 -> Solana.TokenProgramId.Token2022Program + null -> throw IllegalArgumentException("Not token program id") } val input = Solana.SigningInput.newBuilder().apply { this.recentBlockhash = metadata.blockhash @@ -194,7 +196,7 @@ class SolanaSignClient( ) val data = jsonEncoder.encodeToString(instruction) - val recentBlockhash = (chainData as SolanaSignerPreloader.SolanaChainData).blockhash + val recentBlockhash = (chainData as SolanaChainData).blockhash val signInput = Solana.SigningInput.newBuilder().apply { this.recentBlockhash = recentBlockhash this.delegateStakeTransaction = Solana.DelegateStake.newBuilder().apply { @@ -215,7 +217,7 @@ class SolanaSignClient( feePriority: FeePriority, privateKey: ByteArray ): List { - val recentBlockhash = (chainData as SolanaSignerPreloader.SolanaChainData).blockhash + val recentBlockhash = (chainData as SolanaChainData).blockhash val signInput = Solana.SigningInput.newBuilder().apply { this.recentBlockhash = recentBlockhash this.deactivateStakeTransaction = Solana.DeactivateStake.newBuilder().apply { @@ -233,7 +235,7 @@ class SolanaSignClient( feePriority: FeePriority, privateKey: ByteArray ): List { - val recentBlockhash = (chainData as SolanaSignerPreloader.SolanaChainData).blockhash + val recentBlockhash = (chainData as SolanaChainData).blockhash val signInput = Solana.SigningInput.newBuilder().apply { this.recentBlockhash = recentBlockhash this.withdrawTransaction = Solana.WithdrawStake.newBuilder().apply { diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignerPreloader.kt deleted file mode 100644 index 1e1b0459c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignerPreloader.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.GenericTransferPreloader -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.clients.solana.services.SolanaAccountsService -import com.gemwallet.android.blockchain.clients.solana.services.SolanaFeeService -import com.gemwallet.android.blockchain.clients.solana.services.SolanaNetworkInfoService -import com.gemwallet.android.blockchain.clients.solana.services.createAccountByOwnerRequest -import com.gemwallet.android.blockchain.clients.solana.services.getBlockhash -import com.gemwallet.android.model.ChainSignData -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.GasFee -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import com.wallet.core.primitives.SolanaTokenProgramId -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import uniffi.gemstone.Config - -class SolanaSignerPreloader( - private val chain: Chain, - feeService: SolanaFeeService, - private val networkInfoService: SolanaNetworkInfoService, - private val accountsService: SolanaAccountsService, -) : GenericTransferPreloader, NativeTransferPreloader, TokenTransferPreloader, SwapTransactionPreloader, StakeTransactionPreloader { - - private val feeCalculator = SolanaFeeCalculator(feeService) - - override suspend fun preloadGeneric(params: ConfirmParams.TransferParams.Generic): SignerParams { - return preload(params) - } - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - return preload(params, "", null, SolanaTokenProgramId.Token) - } - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams = withContext(Dispatchers.IO) { - val tokenId = params.assetId.tokenId!! - val owner = params.from.address - - val requests = listOf( - accountsService.createAccountByOwnerRequest(owner, tokenId), - accountsService.createAccountByOwnerRequest(params.destination.address, tokenId), - ) - val accounts = try { - accountsService.batchAccount(requests) - } catch (_: Throwable) { - throw Exception("Can't load account info") - } - val senderToken = accounts.getOrNull(0)?.result?.value?.firstOrNull() ?: throw Exception("Sender token address is empty") - val recipientTokenAccounts = accounts.getOrNull(1)?.result?.value?.firstOrNull()?.pubkey - val senderTokenAddress = senderToken.pubkey - val tokenProgram = Config().getSolanaTokenProgramId(senderToken.account.owner)?.let { - when (it) { - SolanaTokenProgramId.Token.string -> SolanaTokenProgramId.Token - SolanaTokenProgramId.Token2022.string -> SolanaTokenProgramId.Token2022 - else -> null - } - } ?: throw Exception("Unknow token program id") - preload(params, senderTokenAddress, recipientTokenAccounts, tokenProgram) - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - return preload(params, "", null, SolanaTokenProgramId.Token) - } - - override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams { - return preload(params, "", null, SolanaTokenProgramId.Token) - } - - private suspend fun preload( - params: ConfirmParams, - senderTokenAddress: String = "", - recipientTokenAddress: String? = null, - tokenProgram: SolanaTokenProgramId = SolanaTokenProgramId.Token - ): SignerParams = withContext(Dispatchers.IO) { - val blockHashJob = async { networkInfoService.getBlockhash() } - val feeJob = async { feeCalculator.calculate(params) } - - val (fee, blockHash) = Pair(feeJob.await(), blockHashJob.await()) - - val chainData = SolanaChainData(blockHash, senderTokenAddress, recipientTokenAddress, tokenProgram, fee) - SignerParams(params, chainData) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - - data class SolanaChainData( - val blockhash: String, - val senderTokenAddress: String, - val recipientTokenAddress: String?, - val tokenProgram: SolanaTokenProgramId, - val fees: List, - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fees.firstOrNull { it.priority == speed } ?: fees.first() - - override fun allFee(): List = fees - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaStakeClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaStakeClient.kt deleted file mode 100644 index 8e81ada32..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaStakeClient.kt +++ /dev/null @@ -1,86 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.StakeClient -import com.gemwallet.android.blockchain.clients.solana.services.SolanaStakeService -import com.gemwallet.android.blockchain.clients.solana.services.delegations -import com.gemwallet.android.blockchain.clients.solana.services.epoch -import com.gemwallet.android.blockchain.clients.solana.services.validators -import com.gemwallet.android.ext.asset -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.DelegationBase -import com.wallet.core.primitives.DelegationState -import com.wallet.core.primitives.DelegationValidator -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import java.math.BigInteger - -class SolanaStakeClient( - private val chain: Chain, - private val stakeService: SolanaStakeService, -): StakeClient { - override suspend fun getValidators(chain: Chain, apr: Double): List { - return stakeService.validators()?.map { - val isActive = it.epochVoteAccount - DelegationValidator( - chain = chain, - id = it.votePubkey, - name = "", - isActive = isActive, - commision = it.commission.toDouble(), - apr = if (isActive) apr - apr * (it.commission.toDouble() / 100) else 0.0, - ) - } ?: emptyList() - } - - override suspend fun getStakeDelegations(chain: Chain, address: String, apr: Double): List = withContext(Dispatchers.IO) { - val getEpoch = async { stakeService.epoch() } - val getDelegations = async { stakeService.delegations(address) } - val epoch = getEpoch.await() ?: return@withContext emptyList() - val delegations = getDelegations.await() ?: return@withContext emptyList() - val nextEpoch = System.currentTimeMillis() + ((epoch.slotsInEpoch - epoch.slotIndex) * 420) - - delegations.map { delegation -> - val info = delegation.account.data.parsed.info - val deactivateEpoch = try { - info.stake.delegation.deactivationEpoch.toLong() - } catch (_: Throwable) { - null - } - val activationEpoch = try { - info.stake.delegation.activationEpoch.toLong() - } catch (_: Throwable) { - null - } - val state = fun(): DelegationState { - if (deactivateEpoch != null) { - if (deactivateEpoch == epoch.epoch) { - return DelegationState.Deactivating - } else if (deactivateEpoch < epoch.epoch) { - return DelegationState.AwaitingWithdrawal - } - } else if (activationEpoch != null) { - if (activationEpoch == epoch.epoch) { - return DelegationState.Activating - } else if (activationEpoch <= epoch.epoch) { - return DelegationState.Active - } - } - return DelegationState.Pending - }() - val balance = delegation.account.lamports.toString() - DelegationBase( - assetId = chain.asset().id, - state = state, - balance = balance, - rewards = (BigInteger(balance) - BigInteger(info.stake.delegation.stake)).toString(), - delegationId = delegation.pubkey, - completionDate = nextEpoch, - validatorId = info.stake.delegation.voter, - shares = "", - ) - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaTokenClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaTokenClient.kt deleted file mode 100644 index 2e311ab44..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaTokenClient.kt +++ /dev/null @@ -1,81 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.GetTokenClient -import com.gemwallet.android.blockchain.clients.solana.services.SolanaAccountsService -import com.gemwallet.android.blockchain.clients.solana.services.createAccountInfoRequest -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import wallet.core.jni.Base58 - -class SolanaTokenClient( - private val chain: Chain, - private val accountsService: SolanaAccountsService, -) : GetTokenClient { - - override suspend fun getTokenData(tokenId: String): Asset? = withContext(Dispatchers.IO) { - val tokenInfo = try { - accountsService.getAccountInfoSpl(accountsService.createAccountInfoRequest(tokenId)) - .result.value.data.parsed.info - } catch (_: Throwable) { - return@withContext null - } - // spl 2022 - if (tokenInfo.extensions != null) { - val extension = tokenInfo.extensions.firstOrNull { it.extension == "tokenMetadata" } - ?: throw Exception("no tokenMetadata") - Asset( - id = AssetId(chain = chain, tokenId = tokenId), - name = extension.state.name ?: return@withContext null, - symbol = extension.state.symbol ?: return@withContext null, - decimals = tokenInfo.decimals, - type = AssetType.SPL, - ) - } - - val metadataKey = try { - uniffi.gemstone.solanaDeriveMetadataPda(tokenId) - } catch (_: Throwable) { - return@withContext null - } - - val base64Job = async { - try { - accountsService.getAccountInfoMpl(accountsService.createAccountInfoRequest(metadataKey)) - .result.value.data.first() - } catch (_: Throwable) { - null - } - - } - val base64 = base64Job.await() ?: return@withContext null - - val metadata = try { - uniffi.gemstone.solanaDecodeMetadata(base64) - } catch (_: Throwable) { - return@withContext null - } - - Asset( - id = AssetId(chain = chain, tokenId = tokenId), - name = metadata.name, - symbol = metadata.symbol, - decimals = tokenInfo.decimals, - type = AssetType.SPL, - ) - } - - override suspend fun isTokenQuery(query: String): Boolean = isTokenAddress(query) - - override fun supported(chain: Chain): Boolean = this.chain == chain - - companion object { - fun isTokenAddress(tokenId: String): Boolean { - return tokenId.length in 40..60 && Base58.decodeNoCheck(tokenId)?.isNotEmpty() == true - } - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaTransactionStatusClient.kt deleted file mode 100644 index 504e8f02f..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaTransactionStatusClient.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.blockchain.clients.solana.services.SolanaTransactionsService -import com.gemwallet.android.blockchain.clients.solana.services.transaction -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState - -class SolanaTransactionStatusClient( - private val chain: Chain, - private val transactionService: SolanaTransactionsService, -) : TransactionStatusClient { - - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val resp = transactionService.transaction(request.hash).getOrNull() ?: throw ServiceUnavailable - if (resp.error != null) return TransactionChanges(TransactionState.Failed) - val state = if (resp.result.slot > 0L) { - if (resp.result.meta.err != null) { - TransactionState.Failed - } else { - TransactionState.Confirmed - } - } else { - TransactionState.Pending - } - return TransactionChanges(state) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaChainData.kt new file mode 100644 index 000000000..da48d2166 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaChainData.kt @@ -0,0 +1,19 @@ +package com.gemwallet.android.blockchain.clients.solana.models + +import com.gemwallet.android.model.ChainSignData +import com.gemwallet.android.model.Fee +import com.gemwallet.android.model.GasFee +import com.wallet.core.primitives.FeePriority +import com.wallet.core.primitives.SolanaTokenProgramId + +data class SolanaChainData( + val blockhash: String, + val senderTokenAddress: String?, + val recipientTokenAddress: String?, + val tokenProgram: SolanaTokenProgramId?, + val fees: List, +) : ChainSignData { + override fun fee(speed: FeePriority): Fee = fees.firstOrNull { it.priority == speed } ?: fees.first() + + override fun allFee(): List = fees +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaParsed.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaParsed.kt deleted file mode 100644 index 82f863093..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaParsed.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.models - -class SolanaParsedData( - val data: SolanaParsed -) - -class SolanaParsed( - val parsed: T -) - -class SolanaInfo( - val info: T -) - -class SolanaParsedSplTokenInfo( - val decimals: Int, - val extensions: List? = null, -) - -class SolanaArrayData(val data: List) - -data class Extension ( - val extension: String, - val state: ExtensionState -) - -data class ExtensionState ( - val name: String?, - val symbol: String?, -) \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaTokenOwner.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaTokenOwner.kt deleted file mode 100644 index 955023de8..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaTokenOwner.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.models - -class SolanaTokenOwner(val owner: String) \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaAccountsService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaAccountsService.kt deleted file mode 100644 index 1e35b672c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaAccountsService.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.services - -import com.gemwallet.android.blockchain.clients.solana.SolanaMethod -import com.gemwallet.android.blockchain.clients.solana.models.SolanaArrayData -import com.gemwallet.android.blockchain.clients.solana.models.SolanaInfo -import com.gemwallet.android.blockchain.clients.solana.models.SolanaParsedData -import com.gemwallet.android.blockchain.clients.solana.models.SolanaParsedSplTokenInfo -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.solana.SolanaTokenAccount -import com.wallet.core.blockchain.solana.SolanaValue -import retrofit2.http.Body -import retrofit2.http.POST - -interface SolanaAccountsService { - @POST("/") - suspend fun getTokenAccountByOwner(@Body request: JSONRpcRequest>): JSONRpcResponse>> - - @POST("/") - suspend fun batchAccount(@Body request: List>>): List>>> - - @POST("/") - suspend fun getAccountInfoSpl(@Body request: JSONRpcRequest>): JSONRpcResponse>>> - - @POST("/") - suspend fun getAccountInfoMpl(@Body request: JSONRpcRequest>): JSONRpcResponse>> - - @POST("/") - suspend fun getTokenInfo(@Body request: JSONRpcRequest>): JSONRpcResponse> -} - -fun SolanaAccountsService.createAccountInfoRequest(tokenId: String): JSONRpcRequest> { - return JSONRpcRequest.create( - SolanaMethod.GetAccountInfo, - params = listOf( - tokenId, - mapOf( - "encoding" to "jsonParsed", - SolanaRpcClient.commitmentKey to SolanaRpcClient.commitmentValue, - ), - ) - ) -} - -fun SolanaAccountsService.createAccountByOwnerRequest(owner: String, tokenId: String): JSONRpcRequest> { - return JSONRpcRequest.create( - method = SolanaMethod.GetTokenAccountByOwner, - params = listOf( - owner, - mapOf("mint" to tokenId), - mapOf( - "encoding" to "jsonParsed", - SolanaRpcClient.commitmentKey to SolanaRpcClient.commitmentValue, - ), - ), - ) -} diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaBalancesService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaBalancesService.kt deleted file mode 100644 index c91a911b4..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaBalancesService.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.services - -import com.gemwallet.android.blockchain.clients.solana.SolanaMethod -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.solana.SolanaBalance -import com.wallet.core.blockchain.solana.SolanaBalanceValue -import com.wallet.core.blockchain.solana.SolanaValue -import retrofit2.http.Body -import retrofit2.http.POST -import java.math.BigInteger - -interface SolanaBalancesService { - @POST("/") - suspend fun getBalance(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun getTokenBalance(@Body request: JSONRpcRequest>): Result>> -} - -suspend fun SolanaBalancesService.getBalance(address: String): Long? { - return getBalance( - JSONRpcRequest.create( - SolanaMethod.GetBalance, - listOf( - address, - mapOf(SolanaRpcClient.commitmentValue to SolanaRpcClient.commitmentValue) - ) - ) - ) - .getOrNull()?.result?.value -} - -suspend fun SolanaBalancesService.getTokenBalance(tokenAccount: String): BigInteger? { - val balanceRequest = JSONRpcRequest.create(SolanaMethod.GetTokenBalance, listOf(tokenAccount)) - return try { - getTokenBalance(balanceRequest).getOrNull()?.result?.value?.amount?.toBigInteger() - } catch (_: Throwable) { - null - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaBroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaBroadcastService.kt deleted file mode 100644 index e2156fe12..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaBroadcastService.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.services - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import retrofit2.http.Body -import retrofit2.http.POST - -interface SolanaBroadcastService { - @POST("/") - suspend fun broadcast(@Body request: JSONRpcRequest>): Result> -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaFeeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaFeeService.kt deleted file mode 100644 index e13a08fb6..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaFeeService.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.services - -import com.gemwallet.android.blockchain.clients.solana.SolanaMethod -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.solana.SolanaPrioritizationFee -import retrofit2.http.Body -import retrofit2.http.POST - -interface SolanaFeeService { - @POST("/") - suspend fun getPriorityFees(@Body request: JSONRpcRequest>): Result>> -} - -suspend fun SolanaFeeService.getPriorityFees(): List { - val request = JSONRpcRequest.create(SolanaMethod.GetPriorityFee, listOf()) - return getPriorityFees(request).getOrNull()?.result ?: throw Exception("Can't load fee price") -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaNetworkInfoService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaNetworkInfoService.kt deleted file mode 100644 index 7dca4fc0d..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaNetworkInfoService.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.services - -import com.gemwallet.android.blockchain.clients.solana.SolanaMethod -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.solana.SolanaBlockhashResult -import retrofit2.http.Body -import retrofit2.http.POST - -interface SolanaNetworkInfoService { - - @POST("/") - suspend fun getBlockhash(@Body request: JSONRpcRequest>): Result> -} - -suspend fun SolanaNetworkInfoService.getBlockhash(): String { - val blockhash = getBlockhash(JSONRpcRequest.create(SolanaMethod.GetLatestBlockhash, emptyList())) - .getOrNull()?.result?.value?.blockhash - if (blockhash.isNullOrEmpty()) { - throw Exception("Can't get latest blockhash") - } - return blockhash -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaNodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaNodeStatusService.kt deleted file mode 100644 index 0e052a6e2..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaNodeStatusService.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.services - -import com.gemwallet.android.blockchain.clients.solana.SolanaMethod -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import retrofit2.Response -import retrofit2.http.Body -import retrofit2.http.POST -import retrofit2.http.Url - -interface SolanaNodeStatusService { - - @POST - suspend fun health(@Url url: String,@Body request: JSONRpcRequest>): Response> - - @POST - suspend fun slot(@Url url: String, @Body request: JSONRpcRequest>): Result> - - @POST - suspend fun genesisHash(@Url url: String, @Body request: JSONRpcRequest>): Result> -} - -suspend fun SolanaNodeStatusService.health(url: String): Response> { - return health(url, JSONRpcRequest.create(SolanaMethod.GetHealth, emptyList())) -} - -suspend fun SolanaNodeStatusService.slot(url: String): Result> { - return slot(url, JSONRpcRequest.create(SolanaMethod.GetSlot, emptyList())) -} - -suspend fun SolanaNodeStatusService.genesisHash(url: String): Result> { - return genesisHash(url, JSONRpcRequest.create(SolanaMethod.GetGenesisHash, emptyList())) -} diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaRpcClient.kt deleted file mode 100644 index becad2507..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaRpcClient.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.services - -interface SolanaRpcClient : - SolanaAccountsService, - SolanaBalancesService, - SolanaStakeService, - SolanaFeeService, - SolanaNetworkInfoService, - SolanaBroadcastService, - SolanaTransactionsService, - SolanaNodeStatusService { - - companion object { - val commitmentKey: String = "commitment" - val commitmentValue: String = "confirmed" - } -} diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaStakeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaStakeService.kt deleted file mode 100644 index dce95a4df..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaStakeService.kt +++ /dev/null @@ -1,67 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.services - -import com.gemwallet.android.blockchain.clients.solana.SolanaMethod -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.solana.SolanaEpoch -import com.wallet.core.blockchain.solana.SolanaStakeAccount -import com.wallet.core.blockchain.solana.SolanaValidator -import com.wallet.core.blockchain.solana.SolanaValidators -import retrofit2.http.Body -import retrofit2.http.POST - -interface SolanaStakeService { - @POST("/") - suspend fun validators(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun delegations(@Body request: JSONRpcRequest>): Result>> - - @POST("/") - suspend fun epoch(@Body request: JSONRpcRequest>): Result> -} - -suspend fun SolanaStakeService.delegations( - owner: String, -): List? { - val request = JSONRpcRequest.create( - SolanaMethod.GetDelegations, - listOf( - "Stake11111111111111111111111111111111111111", - mapOf( - "encoding" to "jsonParsed", - SolanaRpcClient.commitmentKey to SolanaRpcClient.commitmentValue, - "filters" to listOf( - mapOf( - "memcmp" to mapOf( - "bytes" to owner, - "offset" to 44, - ) - ) - ) - ) - ) - ) - return delegations(request).getOrNull()?.result -} - -suspend fun SolanaStakeService.getDelegationsBalance(owner: String): Long { - return delegations(owner)?.map { it.account.lamports }?.fold(0L) { acc, v -> acc + v } ?: 0L -} - -suspend fun SolanaStakeService.validators(): List? { - val request = JSONRpcRequest.create( - SolanaMethod.GetValidators, - listOf( - mapOf( - SolanaRpcClient.commitmentKey to SolanaRpcClient.commitmentValue, - "keepUnstakedDelinquents" to false - ) - ) - ) - return validators(request).getOrNull()?.result?.current -} - -suspend fun SolanaStakeService.epoch(): SolanaEpoch? { - return epoch(JSONRpcRequest.create(SolanaMethod.GetEpoch, emptyList())).getOrNull()?.result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaTransactionsService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaTransactionsService.kt deleted file mode 100644 index 57c8b0a26..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/services/SolanaTransactionsService.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.services - -import com.gemwallet.android.blockchain.clients.solana.SolanaMethod -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.solana.SolanaTransaction -import retrofit2.http.Body -import retrofit2.http.POST - -interface SolanaTransactionsService { - @POST("/") - suspend fun transaction(@Body request: JSONRpcRequest>): Result> -} - -suspend fun SolanaTransactionsService.transaction(hash: String): Result> { - val request = JSONRpcRequest.create( - SolanaMethod.GetTransaction, - listOf( - hash, - mapOf( - "encoding" to "jsonParsed", - SolanaRpcClient.commitmentKey to SolanaRpcClient.commitmentValue, - "maxSupportedTransactionVersion" to 0, - ), - ) - ) - return transaction(request) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarBalanceClient.kt deleted file mode 100644 index f010db09d..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarBalanceClient.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.stellar.services.StellarAccountService -import com.gemwallet.android.blockchain.clients.stellar.services.accounts -import com.gemwallet.android.ext.asset -import com.gemwallet.android.ext.getReserveBalance -import com.gemwallet.android.model.AssetBalance -import com.gemwallet.android.model.Crypto -import com.wallet.core.primitives.Chain - -class StellarBalanceClient( - private val chain: Chain, - private val accountService: StellarAccountService, -) : BalanceClient { - - override suspend fun getNativeBalance( - chain: Chain, - address: String - ): AssetBalance? { - val reserved = chain.getReserveBalance() - val balance = try { - val result = accountService.accounts(address)?.balances - ?.firstOrNull { it.asset_type == "native" }?.balance ?: return null - val value = Crypto(result, chain.asset().decimals).atomicValue - (value - reserved).max(reserved) - } catch (_: Throwable) { - return null - } - return AssetBalance.create(chain.asset(), available = balance.toString(), reserved = reserved.toString()) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarBroadcastClient.kt deleted file mode 100644 index c0478ab8f..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarBroadcastClient.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar - -import com.gemwallet.android.blockchain.Mime -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.stellar.services.StellarBroadcastService -import com.gemwallet.android.blockchain.rpc.ServiceError -import com.gemwallet.android.blockchain.rpc.responseFold -import com.wallet.core.blockchain.stellar.StellarTransactionBroadcast -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import okhttp3.RequestBody.Companion.toRequestBody -import java.net.URLEncoder - -class StellarBroadcastClient( - private val chain: Chain, - private val broadcastService: StellarBroadcastService -) : BroadcastClient { - - override suspend fun send( - account: Account, - signedMessage: ByteArray, - type: TransactionType - ): String { - val encoded = "tx=${URLEncoder.encode(String(signedMessage), "utf-8")}" - val resp = broadcastService.broadcast(encoded.toRequestBody(Mime.Form.value)) - - return resp.responseFold( - onSuccess = { - it?.hash ?: throw ServiceError.EmptyHash - }, - onError = { err: StellarTransactionBroadcast -> - throw Exception(err.title) - }, - onFailure = { cause -> - val error = cause.message?.let { ServiceError.BroadCastError(it) } - ?: ServiceError.ServerError(err = cause) - throw error - } - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} - diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarFeeCalculator.kt index 83aa26c36..47fa40643 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarFeeCalculator.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarFeeCalculator.kt @@ -1,6 +1,6 @@ package com.gemwallet.android.blockchain.clients.stellar -import com.gemwallet.android.blockchain.clients.stellar.services.StellarFeeService +import com.gemwallet.android.blockchain.clients.stellar.services.StellarService import com.gemwallet.android.model.Fee import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.Chain @@ -9,10 +9,10 @@ import java.math.BigInteger class StellarFeeCalculator( private val chain: Chain, - private val feeService: StellarFeeService, + private val client: StellarService, ) { suspend fun calculate(): List { - val fees = feeService.fee().getOrNull() ?: throw Exception("fee load error") + val fees = client.fee().getOrNull() ?: throw Exception("fee load error") val min = BigInteger(fees.fee_charged.min).max(BigInteger(fees.last_ledger_base_fee)) val assetId = AssetId(chain) return listOf( diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarNodeStatusClient.kt deleted file mode 100644 index 1779ad028..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarNodeStatusClient.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.clients.stellar.services.StellarNodeStatusService -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain - -class StellarNodeStatusClient( - private val chain: Chain, - private val nodeStatusService: StellarNodeStatusService, -) : NodeStatusClient { - - override suspend fun getNodeStatus( - chain: Chain, - url: String - ): NodeStatus? { - val resp = nodeStatusService.node("$url") - val result = resp.body() - return NodeStatus( - url = url, - blockNumber = result?.ingest_latest_ledger?.toString() ?: return null, - inSync = true, - chainId = result.network_passphrase, - latency = resp.getLatency() - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt index 1310888e9..81f43d532 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt @@ -1,8 +1,7 @@ package com.gemwallet.android.blockchain.clients.stellar import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.stellar.services.StellarAccountService -import com.gemwallet.android.blockchain.clients.stellar.services.StellarFeeService +import com.gemwallet.android.blockchain.clients.stellar.services.StellarService import com.gemwallet.android.blockchain.clients.stellar.services.accounts import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams @@ -17,19 +16,18 @@ import java.math.BigInteger class StellarSignPreloadClient( private val chain: Chain, - private val accountService: StellarAccountService, - feeService: StellarFeeService, + private val client: StellarService, ) : NativeTransferPreloader { - private val feeCalculator = StellarFeeCalculator(chain, feeService) + private val feeCalculator = StellarFeeCalculator(chain, client) override suspend fun preloadNativeTransfer( params: ConfirmParams.TransferParams.Native ): SignerParams = withContext(Dispatchers.IO) { - val getAccount = async { accountService.accounts(params.from.address) } + val getAccount = async { client.accounts(params.from.address) } val getIsDestinationAccountExist = async { try { - accountService.accounts(params.destination.address) != null + client.accounts(params.destination.address) != null } catch (_: Throwable) { false } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarTransactionStatusClient.kt deleted file mode 100644 index 4e2f4c9be..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarTransactionStatusClient.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.blockchain.clients.stellar.services.StellarTxStatusService -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState - -class StellarTransactionStatusClient( - private val chain: Chain, - private val txStatusService: StellarTxStatusService, -) : TransactionStatusClient { - - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val tx = txStatusService.transaction(request.hash).getOrNull() ?: throw ServiceUnavailable - val state = if (tx.successful == true) TransactionState.Confirmed else TransactionState.Failed - return TransactionChanges( - state = state, - fee = try { tx.fee_charged.toBigInteger() } catch (_: Throwable) { null } - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarAccountService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarAccountService.kt deleted file mode 100644 index c2b6b764b..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarAccountService.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar.services - -import com.wallet.core.blockchain.stellar.StellarAccount -import retrofit2.http.GET -import retrofit2.http.Path - -interface StellarAccountService { - @GET("/accounts/{address}") - suspend fun loadAccounts(@Path("address") address: String): Result -} - -suspend fun StellarAccountService.accounts(address: String): StellarAccount? { - val result = loadAccounts(address) - - return result.getOrNull() -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarBroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarBroadcastService.kt deleted file mode 100644 index d8f8daaca..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarBroadcastService.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar.services - -import com.wallet.core.blockchain.stellar.StellarTransactionBroadcast -import okhttp3.RequestBody -import retrofit2.http.Body -import retrofit2.http.POST - -interface StellarBroadcastService { - @POST("/transactions") - suspend fun broadcast(@Body body: RequestBody): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarFeeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarFeeService.kt deleted file mode 100644 index bd6d6d967..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarFeeService.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar.services - -import com.wallet.core.blockchain.stellar.StellarFees -import retrofit2.http.GET - -interface StellarFeeService { - @GET("/fee_stats") - suspend fun fee(): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarNodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarNodeStatusService.kt deleted file mode 100644 index ab6072a44..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarNodeStatusService.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar.services - -import com.wallet.core.blockchain.stellar.StellarNodeStatus -import retrofit2.Response -import retrofit2.http.GET -import retrofit2.http.Url - -interface StellarNodeStatusService { - @GET//("/") - suspend fun node(@Url url: String): Response -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarService.kt index 3fa24ff30..4e7e8e201 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarService.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarService.kt @@ -1,7 +1,20 @@ package com.gemwallet.android.blockchain.clients.stellar.services -interface StellarService : StellarAccountService, - StellarBroadcastService, - StellarFeeService, - StellarTxStatusService, - StellarNodeStatusService \ No newline at end of file +import com.wallet.core.blockchain.stellar.StellarAccount +import com.wallet.core.blockchain.stellar.StellarFees +import retrofit2.http.GET +import retrofit2.http.Path + +interface StellarService { + @GET("/accounts/{address}") + suspend fun loadAccounts(@Path("address") address: String): Result + + @GET("/fee_stats") + suspend fun fee(): Result +} + +suspend fun StellarService.accounts(address: String): StellarAccount? { + val result = loadAccounts(address) + + return result.getOrNull() +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarTxStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarTxStatusService.kt deleted file mode 100644 index 33b50f6b8..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarTxStatusService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar.services - -import com.wallet.core.blockchain.stellar.StellarTransactionStatus -import retrofit2.http.GET -import retrofit2.http.Path - -interface StellarTxStatusService { - @GET("/transactions/{id}") - suspend fun transaction(@Path("id") id: String): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiBalanceClient.kt deleted file mode 100644 index c350f58fe..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiBalanceClient.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.ext.asset -import com.gemwallet.android.ext.total -import com.gemwallet.android.math.clean0xPrefix -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.blockchain.sui.SuiCoinBalance -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.Chain -import java.math.BigInteger - -class SuiBalanceClient( - private val chain: Chain, - private val rpcClient: SuiRpcClient, -) : BalanceClient { - override fun supported(chain: Chain): Boolean = this.chain == chain - - override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? { - val amount = rpcClient.balance(address) - .mapCatching { it.result.totalBalance.toBigInteger() } - .getOrNull() ?: return null - return AssetBalance.create(chain.asset(), available = amount.toString()) - } - - override suspend fun getDelegationBalances(chain: Chain, address: String): AssetBalance? { - val delegations = rpcClient.delegations(JSONRpcRequest.create(SuiMethod.Delegations, listOf(address))) - .getOrNull()?.result ?: emptyList() - - val staked = delegations.map { - it.stakes.map { stake -> stake.total() }.fold(BigInteger.ZERO) { acc, value -> acc + value} - }.fold(BigInteger.ZERO) {acc, value -> acc + value} - - return AssetBalance.create(chain.asset(), staked = staked.toString()) - } - - override suspend fun getTokenBalances(chain: Chain, address: String, tokens: List): List { - return rpcClient.balances(address).mapCatching { response -> - val balances = response.result - tokens.mapNotNull { token -> - AssetBalance.create( - token, - balances.firstOrNull { it.isCoinType(token.id.tokenId) }?.totalBalance ?: return@mapNotNull null, - ) - } - }.getOrNull() ?: emptyList() - } - - fun SuiCoinBalance.isCoinType(tokenId: String?): Boolean { - return coinType.clean0xPrefix() == tokenId?.clean0xPrefix()?.removePrefix("0") - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiBroadcastClient.kt deleted file mode 100644 index d74f913ec..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiBroadcastClient.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui - -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.rpc.ServiceError -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType - -class SuiBroadcastClient( - private val chain: Chain, - private val rpcClient: SuiRpcClient, -) : BroadcastClient { - - override suspend fun send(account: Account, signedMessage: ByteArray, type: TransactionType): String { - val parts = String(signedMessage).split("_") - val data = parts.first() - val sign = parts[1] - return rpcClient.broadcast(data, sign).getOrNull()?.result?.digest ?: throw ServiceError.NetworkError - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiGetTokenClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiGetTokenClient.kt deleted file mode 100644 index 9e43a6aef..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiGetTokenClient.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui - -import com.gemwallet.android.blockchain.clients.GetTokenClient -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain - -class SuiGetTokenClient( - private val chain: Chain, - private val rpcClient: SuiRpcClient, -) : GetTokenClient { - override suspend fun getTokenData(tokenId: String): Asset? { - val metadata = rpcClient.getCoinMetadata(JSONRpcRequest.create(SuiMethod.CoinMetadata, listOf(tokenId))) - .getOrNull() - val result = if (metadata?.result == null) { - return null - } else { - metadata.result - } - return Asset( - id = AssetId(chain, tokenId), - name = result.name, - symbol = result.symbol, - decimals = result.decimals, - type = AssetType.TOKEN, - ) - } - - override suspend fun isTokenQuery(query: String): Boolean = isTokenAddress(query) - - override fun supported(chain: Chain): Boolean = this.chain == chain - - companion object { - fun isTokenAddress(tokenId: String): Boolean { - return tokenId.startsWith("0x") && tokenId.length in 66..100 - } - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt index 7ba757d3b..91f88b8e8 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt @@ -4,22 +4,10 @@ import com.gemwallet.android.blockchain.rpc.model.JSONRpcMethod enum class SuiMethod(val value: String) : JSONRpcMethod { Coins("suix_getCoins"), - Balance("suix_getBalance"), - Balances("suix_getAllBalances"), GasPrice("suix_getReferenceGasPrice"), - Pay("unsafe_pay"), - PaySui("unsafe_paySui"), - PayAllSui("unsafe_payAllSui"), DryRun("sui_dryRunTransactionBlock"), Transaction("sui_getTransactionBlock"), - Broadcast("sui_executeTransactionBlock"), - Validators("suix_getValidatorsApy"), - Delegations("suix_getStakes"), GetObject("sui_getObject"), - CoinMetadata("suix_getCoinMetadata"), - SystemState("suix_getLatestSuiSystemState"), - ChainId("sui_getChainIdentifier"), - LatestCheckpoint("sui_getLatestCheckpointSequenceNumber"), ; override fun value(): String = value diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiNodeStatusClient.kt deleted file mode 100644 index 71776be2e..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiNodeStatusClient.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class SuiNodeStatusClient( - private val chain: Chain, - private val rpcClient: SuiRpcClient, -) : NodeStatusClient { - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? = withContext(Dispatchers.IO) { - val chainIdJob = async { rpcClient.chainId(url) } - val blockJob = async { rpcClient.latestBlock(url).getOrNull() } - - val chainIdResp = chainIdJob.await() - val block = blockJob.await() - val chainId = chainIdResp.body()?.result - - NodeStatus( - url = url, - inSync = true, - blockNumber = block?.result?.toString() ?: return@withContext null, - chainId = chainId ?: return@withContext null, - latency = chainIdResp.getLatency(), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiRpcClient.kt index ff6d3219b..850af0a8e 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiRpcClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiRpcClient.kt @@ -23,98 +23,20 @@ interface SuiRpcClient { @POST("/") suspend fun coins(@Body request: JSONRpcRequest>): Result>>> - @POST("/") - suspend fun balance(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun balances(@Body request: JSONRpcRequest>): Result>> - @POST("/") suspend fun gasPrice(@Body request: JSONRpcRequest>): Result> @POST("/") suspend fun dryRun(@Body request: JSONRpcRequest>):Result> - @POST("/") - suspend fun transaction(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun broadcast(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun validators(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun delegations(@Body request: JSONRpcRequest>): Result>> - @POST("/") suspend fun getObject(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun getCoinMetadata(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun systemState(@Body request: JSONRpcRequest>): Result> - - @POST - suspend fun chainId(@Url url: String, @Body request: JSONRpcRequest>): Response> - - @POST - suspend fun latestBlock(@Url url: String, @Body request: JSONRpcRequest>): Result> } internal suspend fun SuiRpcClient.coins(address: String, coinType: String): Result>>> { return coins(JSONRpcRequest.create(SuiMethod.Coins, listOf(address, coinType))) } -internal suspend fun SuiRpcClient.balance(address: String): Result> { - return balance(JSONRpcRequest.create(SuiMethod.Balance, listOf(address))) -} - -internal suspend fun SuiRpcClient.balances(address: String): Result>> { - return balances(JSONRpcRequest.create(SuiMethod.Balances, listOf(address))) -} - -internal suspend fun SuiRpcClient.broadcast(data: String, sign: String): Result> { - val request = JSONRpcRequest.create( - SuiMethod.Broadcast, - listOf( - data, - listOf(sign), - null, - "WaitForLocalExecution", - ) - ) - return broadcast(request) -} - -internal suspend fun SuiRpcClient.transaction(txId: String): Result> { - val request = JSONRpcRequest.create( - SuiMethod.Transaction, - listOf( - txId, - mapOf("showEffects" to true) - ) - ) - return transaction(request) -} - -internal suspend fun SuiRpcClient.systemState(): Result> { - val request = JSONRpcRequest.create( - SuiMethod.SystemState, - emptyList(), - ) - return systemState(request) -} - -internal suspend fun SuiRpcClient.chainId(url: String): Response> { - return chainId(url, JSONRpcRequest.create(SuiMethod.ChainId, emptyList())) -} - -internal suspend fun SuiRpcClient.latestBlock(url: String): Result> { - return latestBlock(url, JSONRpcRequest.create(SuiMethod.LatestCheckpoint, emptyList())) -} - internal suspend fun SuiRpcClient.dryRun(data: String): SuiGasUsed { return dryRun(JSONRpcRequest.create(SuiMethod.DryRun, listOf(data))).getOrNull()?.result?.effects?.gasUsed ?: throw Exception("Can't load SUI gas") diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiStakeClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiStakeClient.kt deleted file mode 100644 index 7a759480b..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiStakeClient.kt +++ /dev/null @@ -1,69 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui - -import com.gemwallet.android.blockchain.clients.StakeClient -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.ext.asset -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.DelegationBase -import com.wallet.core.primitives.DelegationState -import com.wallet.core.primitives.DelegationValidator -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class SuiStakeClient( - private val chain: Chain, - private val rpcClient: SuiRpcClient -): StakeClient { - override suspend fun getValidators(chain: Chain, apr: Double): List { - val validators = rpcClient.validators(JSONRpcRequest.create(SuiMethod.Validators, listOf())) - .getOrNull()?.result?.apys ?: return emptyList() - return validators.map { - DelegationValidator( - chain = chain, - id = it.address, - name = "", - isActive = true, - commision = 0.0, - apr = apr, - ) - - } - } - - override suspend fun getStakeDelegations(chain: Chain, address: String, apr: Double): List = withContext(Dispatchers.IO) { - val getDelegations = async { - rpcClient.delegations(JSONRpcRequest.create(SuiMethod.Delegations, listOf(address))) - .getOrNull()?.result - } - val getSystemState = async { rpcClient.systemState().getOrNull() } - - val delegations = getDelegations.await() ?: return@withContext emptyList() - val systemState = getSystemState.await() ?: return@withContext emptyList() - val nextEpoch = (systemState.result.epochStartTimestampMs.toLongOrNull() ?: 0L) + - (systemState.result.epochDurationMs.toLongOrNull() ?: 0L) - - delegations.map { delegation -> - delegation.stakes.map { stake -> - val state = when (stake.status) { - "Active" -> DelegationState.Active - "Pending" -> DelegationState.Activating - else -> DelegationState.Pending - } - - DelegationBase( - assetId = chain.asset().id, - state = state, - rewards = stake.estimatedReward ?: "0", - delegationId = stake.stakedSuiId, - validatorId = delegation.validatorAddress, - balance = stake.principal, - completionDate = nextEpoch, - shares = "", - ) - } - }.flatten() - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiTransactionStatusClient.kt deleted file mode 100644 index c0d34a8ff..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiTransactionStatusClient.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState - -class SuiTransactionStatusClient( - private val chain: Chain, - private val rpcClient: SuiRpcClient, -) : TransactionStatusClient { - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val resp = rpcClient.transaction(request.hash).getOrNull() ?: throw ServiceUnavailable - return TransactionChanges( - when (resp.result.effects.status.status) { - "success" -> TransactionState.Confirmed - "failure" -> TransactionState.Reverted - else -> TransactionState.Pending - } - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonBalanceClient.kt deleted file mode 100644 index edf3c0ce7..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonBalanceClient.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ton - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.mapNotNull -import kotlinx.coroutines.flow.toList -import java.math.BigInteger - -class TonBalanceClient( - private val chain: Chain, - private val rpcClient: TonRpcClient, -) : BalanceClient { - - override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? { - return rpcClient.balance(address) - .fold( { AssetBalance.create(chain.asset(), it.result) } ) { null } - } - - override suspend fun getTokenBalances(chain: Chain, address: String, tokens: List): List { - return tokens.asFlow() - .mapNotNull { - val tokenId = it.id.tokenId ?: return@mapNotNull null - val jettonAddress = jettonAddress(rpcClient, tokenId, address) ?: return@mapNotNull null - val isActive = rpcClient.addressState(jettonAddress).getOrNull()?.result == "active" - - if (isActive) { - AssetBalance.create(it, available = tokenBalance(jettonAddress).toString()) - } else { - AssetBalance.create(it) - } - } - .flowOn(Dispatchers.IO) - .toList() - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - - private suspend fun tokenBalance(jettonAddress: String): BigInteger { - return BigInteger.valueOf( - rpcClient.tokenBalance(jettonAddress).getOrNull()?.result?.balance ?: 0L - ) - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonBroadcastClient.kt deleted file mode 100644 index 6bb2b5c5a..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonBroadcastClient.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ton - -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.rpc.ServiceError -import com.gemwallet.android.blockchain.rpc.ServiceError.EmptyHash -import com.gemwallet.android.math.toHexString -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import wallet.core.jni.Base64 -import java.nio.charset.StandardCharsets - -class TonBroadcastClient( - private val chain: Chain, - private val rpcClient: TonRpcClient, -) : BroadcastClient { - override suspend fun send(account: Account, signedMessage: ByteArray, type: TransactionType): String { - val encodedMessage = signedMessage.toString(StandardCharsets.UTF_8) - val response = rpcClient.broadcast(TonRpcClient.Boc(encodedMessage)).getOrNull() - ?: throw ServiceError.NetworkError - val hash = try { - Base64.decode(response.result.hash).toHexString("") - } catch (_: Throwable) { - throw EmptyHash - } - return hash - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonCalls.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonCalls.kt index effa380c8..a83fb2b9c 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonCalls.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonCalls.kt @@ -3,22 +3,23 @@ package com.gemwallet.android.blockchain.clients.ton import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest internal suspend fun jettonAddress(rpcClient: TonRpcClient, tokenId: String, address: String): String? { - val data = uniffi.gemstone.tonEncodeGetWalletAddress(address) - val response = rpcClient.getJetonAddress( - JSONRpcRequest( - method = "runGetMethod", - params = mapOf( - "address" to tokenId, - "method" to "get_wallet_address", - "stack" to listOf( - listOf( - "tvm.Slice", - data, - ) - ), - ) - ) - ) - val result = response.getOrNull() ?: return null - return uniffi.gemstone.tonDecodeJettonAddress(result.b64, result.len.toULong()) +// val data = uniffi.gemstone.tonEncodeGetWalletAddress(address) +// val response = rpcClient.getJetonAddress( +// JSONRpcRequest( +// method = "runGetMethod", +// params = mapOf( +// "address" to tokenId, +// "method" to "get_wallet_address", +// "stack" to listOf( +// listOf( +// "tvm.Slice", +// data, +// ) +// ), +// ) +// ) +// ) +// val result = response.getOrNull() ?: return null +// return uniffi.gemstone.tonDecodeJettonAddress(result.b64, result.len.toULong()) + return null } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonGetTokenClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonGetTokenClient.kt deleted file mode 100644 index 1021703ad..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonGetTokenClient.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ton - -import com.gemwallet.android.blockchain.clients.GetTokenClient -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain - -class TonGetTokenClient( - val chain: Chain, - val rpcClient: TonRpcClient, -) : GetTokenClient { - override suspend fun getTokenData(tokenId: String): Asset? { - val data = rpcClient.tokenData(tokenId).getOrNull()?.result?.jetton_content?.data ?: return null - return Asset( - id = AssetId(chain, tokenId), - name = data.name ?: return null, - symbol = data.symbol ?: return null, - decimals = data.decimals?.toIntOrNull() ?: return null, - type = AssetType.JETTON, - ) - } - - override suspend fun isTokenQuery(query: String): Boolean = isTokenAddress(query) - - override fun supported(chain: Chain): Boolean = this.chain == chain - - companion object { - fun isTokenAddress(tokenId: String): Boolean { - return tokenId.startsWith("EQ") && tokenId.length in 40..60 - } - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonNodeStatusClient.kt deleted file mode 100644 index 61d2b3d06..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonNodeStatusClient.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ton - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext - -class TonNodeStatusClient( - private val chain: Chain, - private val rpcClient: TonRpcClient, -) : NodeStatusClient { - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? = withContext(Dispatchers.IO) { - val resp = rpcClient.masterChainInfo("$url/api/v2/getMasterchainInfo") - NodeStatus( - url = url, - blockNumber = resp.body()?.result?.last?.seqno?.toString() ?: return@withContext null, - inSync = true, - chainId = "", - latency = resp.getLatency(), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonRpcClient.kt index 0f2827ca0..22d32591c 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonRpcClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonRpcClient.kt @@ -21,40 +21,12 @@ import java.lang.reflect.Type interface TonRpcClient { - @GET("/api/v2/getAddressBalance") - suspend fun balance(@Query("address") address: String): Result> - @GET("/api/v2/getWalletInformation") suspend fun walletInfo(@Query("address") address: String): Result> - @POST("/api/v2/sendBocReturnHash") - suspend fun broadcast(@Body boc: Boc): Result> - -// @GET("/api/index/v1/getTransactionsByInMessageHash") -// suspend fun transaction(@Query("msg_hash") hash: String): Result> - - @GET("/api/v3/transactionsByMessage") - suspend fun transaction(@Query("msg_hash") hash: String): Result - - @GET("/api/v2/getTokenData") - suspend fun tokenData(@Query("address") address: String): Result> - - @POST("/api/v2/jsonRPC") - suspend fun getJetonAddress(@Body request: JSONRpcRequest): Result - - @GET("/api/v2/getTokenData") - suspend fun tokenBalance(@Query("address") address: String): Result> - @GET("/api/v2/getAddressState") suspend fun addressState(@Query("address") address: String): Result> - @GET//("/api/v2/getMasterchainInfo") - suspend fun masterChainInfo(@Url string: String): Response> - - data class Boc( - val boc: String - ) - data class JetonAddress( val b64: String, val len: Long, diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonTransactionStatusClient.kt deleted file mode 100644 index a0a086330..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonTransactionStatusClient.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ton - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionNotFound -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState - -class TonTransactionStatusClient( - private val chain: Chain, - private val rpcClient: TonRpcClient, -) : TransactionStatusClient { - - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val resp = rpcClient.transaction(request.hash).getOrNull() ?: throw ServiceUnavailable - - val transaction = resp.transactions.firstOrNull() ?: throw TransactionNotFound() - val transactionState = when { - transaction.out_msgs.firstOrNull()?.let { it.bounce && it.bounced } != false -> TransactionState.Failed - else -> TransactionState.Confirmed - } - return TransactionChanges(state = transactionState) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronAddressStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronAddressStatusClient.kt index a35f96d42..cac0df6df 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronAddressStatusClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronAddressStatusClient.kt @@ -1,18 +1,16 @@ package com.gemwallet.android.blockchain.clients.tron import com.gemwallet.android.blockchain.clients.AddressStatusClient -import com.gemwallet.android.blockchain.clients.tron.services.TronAccountsService -import com.gemwallet.android.blockchain.clients.tron.services.getAccount import com.gemwallet.android.model.AddressStatus import com.wallet.core.primitives.Chain class TronAddressStatusClient( private val chain: Chain, - private val tronAccountsService: TronAccountsService, + private val client: TronRpcClient, ) : AddressStatusClient { override suspend fun getAddressStatus(chain: Chain, address: String): List { - val activePermission = tronAccountsService.getAccount(address, true) + val activePermission = client.getAccount(address, true) ?.active_permission ?: emptyList() return if (activePermission.filter { it.threshold > 1 }.isNotEmpty()) { listOf(AddressStatus.MultiSignature) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronBalanceClient.kt deleted file mode 100644 index de3521120..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronBalanceClient.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.tron.services.TronAccountsService -import com.gemwallet.android.blockchain.clients.tron.services.TronCallService -import com.gemwallet.android.blockchain.clients.tron.services.TronStakeService -import com.gemwallet.android.blockchain.clients.tron.services.getAccount -import com.gemwallet.android.blockchain.clients.tron.services.staked -import com.gemwallet.android.blockchain.clients.tron.services.triggerSmartContract -import com.gemwallet.android.ext.asset -import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import wallet.core.jni.Base58 -import java.math.BigInteger - -class TronBalanceClient( - private val chain: Chain, - private val accountsService: TronAccountsService, - private val tronCallService: TronCallService, - private val stakeService: TronStakeService, -) : BalanceClient { - - override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? = withContext(Dispatchers.IO) { - val getAaccount = async { accountsService.getAccount(address, true) } - val getRewards = async { stakeService.getReward(address).getOrNull()?.reward?.toString() ?: "0" } - val account = getAaccount.await() ?: return@withContext null - val available = account.balance?.toString() ?: "0" - val pending = account.unfrozenV2?.mapNotNull { unfroze -> - unfroze.unfreeze_amount ?: return@mapNotNull null - }?.fold(0L) { acc, amount -> acc + amount }?.toString() ?: "0" - val rewards = getRewards.await() - val staked = account.staked(chain).toString() - - if (available == "0" && staked == "0" && rewards == "0" && pending == "0") { - return@withContext null - } - - AssetBalance.create( - chain.asset(), - available = available.toString(), - staked = staked, - pending = pending, - rewards = rewards - ) - } - - override suspend fun getTokenBalances(chain: Chain, address: String, tokens: List): List { - return tokens.mapNotNull { token -> - val tokenId = token.id.tokenId ?: return@mapNotNull null - val owner = Base58.decode(address).toHexString("") - tronCallService.triggerSmartContract( - contractAddress = Base58.decode(tokenId).toHexString(""), - functionSelector = "balanceOf(address)", - parameter = owner.padStart(64, '0'), - feeLimit = 1_000_000L, - callValue = 0L, - ownerAddress = owner, - visible = false, - ).fold( - { - val amount = BigInteger(it.constant_result?.firstOrNull() ?: "0", 16) - AssetBalance.create(token, amount.toString()) - } - ) { - null - } - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronBroadcastClient.kt deleted file mode 100644 index 2a968c754..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronBroadcastClient.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.Mime -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.tron.services.TronBroadcastService -import com.gemwallet.android.blockchain.rpc.RpcError -import com.gemwallet.android.blockchain.rpc.ServiceError -import com.gemwallet.android.math.decodeHex -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import okhttp3.RequestBody.Companion.toRequestBody - -class TronBroadcastClient( - private val chain: Chain, - private val rpcClient: TronBroadcastService, -) : BroadcastClient { - - override suspend fun send(account: Account, signedMessage: ByteArray, type: TransactionType): String { - val requestData = signedMessage.toRequestBody(Mime.Json.value) - val data = rpcClient.broadcast(requestData).getOrNull() ?: throw ServiceError.NetworkError - if (data.result == true) { - return data.txid - } else { - throw RpcError.BroadcastFail(String(data.message.decodeHex())) - } - throw RpcError.TransactionSendError - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronFeeCalculator.kt index b5ba70307..f04db53fb 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronFeeCalculator.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronFeeCalculator.kt @@ -1,9 +1,5 @@ package com.gemwallet.android.blockchain.clients.tron -import com.gemwallet.android.blockchain.clients.tron.services.TronCallService -import com.gemwallet.android.blockchain.clients.tron.services.TronNodeStatusService -import com.gemwallet.android.blockchain.clients.tron.services.staked -import com.gemwallet.android.blockchain.clients.tron.services.triggerSmartContract import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee @@ -21,8 +17,7 @@ import java.math.BigInteger class TronFeeCalculator( private val chain: Chain, - private val nodeStatusService: TronNodeStatusService, - private val callService: TronCallService, + private val client: TronRpcClient, ) { val baseFee = BigInteger.valueOf(280_000) @@ -47,7 +42,7 @@ class TronFeeCalculator( } suspend fun calculate(inParams: ConfirmParams.TransferParams.Native, account: TronAccount?, accountUsage: TronAccountUsage?) = withContext(Dispatchers.IO) { - val getParams = async { nodeStatusService.getChainParameters().fold({ it.chainParameter }) { null } } + val getParams = async { client.getChainParameters().fold({ it.chainParameter }) { null } } val params = getParams.await() val isNewAccount = account?.address.isNullOrEmpty() @@ -70,7 +65,7 @@ class TronFeeCalculator( } suspend fun calculate(inParams: ConfirmParams.TransferParams.Token, account: TronAccount?, accountUsage: TronAccountUsage?) = withContext(Dispatchers.IO) { - val getParams = async { nodeStatusService.getChainParameters().fold({ it.chainParameter }) { null } } + val getParams = async { client.getChainParameters().fold({ it.chainParameter }) { null } } // https://developers.tron.network/docs/set-feelimit#how-to-estimate-energy-consumption val gasLimit = estimateTRC20Transfer( @@ -112,7 +107,7 @@ class TronFeeCalculator( address, value.toByteArray().toHexString("") ).joinToString(separator = "") { it.padStart(64, '0') } - val response = callService.triggerSmartContract( + val response = client.triggerSmartContract( contractAddress = contractAddress, functionSelector = "transfer(address,uint256)", parameter = parameter, diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronGetTokenClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronGetTokenClient.kt deleted file mode 100644 index 2033bce4d..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronGetTokenClient.kt +++ /dev/null @@ -1,96 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.clients.GetTokenClient -import com.gemwallet.android.blockchain.clients.tron.services.triggerSmartContract -import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy -import com.gemwallet.android.math.decodeHex -import com.gemwallet.android.math.toHexString -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import wallet.core.jni.AnyAddress -import wallet.core.jni.Base58 -import wallet.core.jni.EthereumAbiValue -import java.math.BigInteger - -class TronGetTokenClient( - private val chain: Chain, - private val rpcClient: TronRpcClient, -) : GetTokenClient { - override suspend fun getTokenData(tokenId: String): Asset? = withContext(Dispatchers.IO) { - val coinType = WCChainTypeProxy().invoke(chain) - if (!AnyAddress.isValid(tokenId, coinType)) { - return@withContext null - } - val contract = AnyAddress(tokenId, coinType).description() - val getName = async { getName(contract) } - val getSymbol = async { getSymbol(contract) } - val getDecimals = async { getDecimals(contract) } - val name = getName.await() ?: return@withContext null - val symbol = getSymbol.await() ?: return@withContext null - val decimals = getDecimals.await() ?: return@withContext null - - Asset( - id = AssetId(chain, tokenId), - name = name, - symbol = symbol, - decimals = decimals, - type = AssetType.TRC20, - ) - } - - override suspend fun isTokenQuery(query: String): Boolean = isTokenAddress(query) - - override fun supported(chain: Chain): Boolean = this.chain == chain - - private suspend fun getName(contract: String): String? { - return getTokenString(contract, "name()") - } - - private suspend fun getSymbol(contract: String): String? { - return getTokenString(contract, "symbol()") - } - - private suspend fun getDecimals(contract: String): Int? { - val result = smartContractCallFunction(contract, "decimals()") ?: return null - val decimal = BigInteger(result, 16) - return decimal.toInt() - } - - private suspend fun getTokenString(contract: String, function: String): String? { - val result = smartContractCallFunction(contract, function) ?: return null - return decodeAbi(result) - } - - private suspend fun smartContractCallFunction(contract: String, function: String): String? { - val contract = "41" + Base58.decode(contract).toHexString("").drop(2) - val result = rpcClient.triggerSmartContract( - contractAddress = contract, - functionSelector = function, - parameter = null, - feeLimit = null, - callValue = null, - ownerAddress = contract, - visible = null, - ).getOrNull() - return result?.constant_result?.firstOrNull() - } - - private fun decodeAbi(hexString: String): String? { - val data = hexString.decodeHex() - if (data.size < 32) { - return null - } - return EthereumAbiValue.decodeValue(data.drop(32).toByteArray(), "string") - } - - companion object { - fun isTokenAddress(tokenId: String): Boolean { - return tokenId.startsWith("T") && tokenId.length in 30..50 - } - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronNodeStatusClient.kt deleted file mode 100644 index 2fe520197..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronNodeStatusClient.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext - -class TronNodeStatusClient( - private val chain: Chain, - private val rpcClient: TronRpcClient, -) : NodeStatusClient { - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? = withContext(Dispatchers.IO) { - val resp = rpcClient.nowBlock("$url/wallet/getnowblock") - NodeStatus( - url = url, - blockNumber = resp.body()?.block_header?.raw_data?.number?.toString() ?: return@withContext null, - inSync = true, - chainId = "", - latency = resp.getLatency(), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronRpcClient.kt index c1e295da2..85fb47b0c 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronRpcClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronRpcClient.kt @@ -1,24 +1,86 @@ package com.gemwallet.android.blockchain.clients.tron -import com.gemwallet.android.blockchain.clients.tron.services.TronAccountsService -import com.gemwallet.android.blockchain.clients.tron.services.TronBroadcastService -import com.gemwallet.android.blockchain.clients.tron.services.TronCallService -import com.gemwallet.android.blockchain.clients.tron.services.TronNodeStatusService -import com.gemwallet.android.blockchain.clients.tron.services.TronStakeService +import android.util.Log +import com.gemwallet.android.ext.asset +import com.gemwallet.android.math.toHexString +import com.wallet.core.blockchain.tron.TronAccount +import com.wallet.core.blockchain.tron.TronAccountRequest +import com.wallet.core.blockchain.tron.TronAccountUsage +import com.wallet.core.blockchain.tron.TronBlock +import com.wallet.core.blockchain.tron.TronChainParameters +import com.wallet.core.blockchain.tron.TronSmartContractResult import com.wallet.core.blockchain.tron.TronTransactionReceipt +import com.wallet.core.primitives.Chain import retrofit2.http.Body +import retrofit2.http.GET import retrofit2.http.POST +import wallet.core.jni.Base58 +import java.math.BigInteger -interface TronRpcClient : - TronAccountsService, - TronCallService, - TronStakeService, - TronNodeStatusService, - TronBroadcastService -{ +interface TronRpcClient { + @GET("/wallet/getchainparameters") + suspend fun getChainParameters(): Result - @POST("/wallet/gettransactioninfobyid") - suspend fun transaction(@Body value: TronValue): Result + @POST("/wallet/getnowblock") + suspend fun nowBlock(): Result - class TronValue(val value: String) + @POST("/wallet/triggerconstantcontract") + suspend fun triggerSmartContract(@Body addressRequest: Any): Result + + @POST("/wallet/getaccount") + suspend fun getAccount(@Body addressRequest: TronAccountRequest): Result + + @POST("/wallet/getaccountnet") + suspend fun getAccountUsage(@Body addressRequest: TronAccountRequest): Result +} + +fun TronAccount.staked(chain: Chain): BigInteger { + val votes = votes ?: emptyList() + val totalVotes = votes.fold(0L) { acc, item -> acc + item.vote_count } + return BigInteger.valueOf(totalVotes) * BigInteger.TEN.pow(chain.asset().decimals) +} + +suspend fun TronRpcClient.triggerSmartContract( + contractAddress: String, + functionSelector: String, + parameter: String? = null, + feeLimit: Long? = null, + callValue: Long? = null, + ownerAddress: String, + visible: Boolean? = null, +): Result { + val call = mapOf( + "contract_address" to contractAddress, + "function_selector" to functionSelector, + "parameter" to parameter, + "fee_limit" to feeLimit, + "call_value" to callValue, + "owner_address" to ownerAddress, + "visible" to visible, + ) + return triggerSmartContract(call) +} + +suspend fun TronRpcClient.getAccount(address: String, visible: Boolean = false): TronAccount? { + return try { + val result = getAccount( + TronAccountRequest( + address = address, + visible = visible + ) + ) + result.getOrThrow() + } catch (err: Throwable) { + Log.d("TRON-ACCOUNT", "Error: ", err) + null + } +} + +suspend fun TronRpcClient.getAccountUsage(address: String): TronAccountUsage? { + return getAccountUsage( + TronAccountRequest( + address = Base58.decode(address).toHexString(""), + visible = false + ) + ).getOrNull() } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt index 91f3b727d..126467893 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt @@ -4,11 +4,6 @@ import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.clients.tron.services.TronAccountsService -import com.gemwallet.android.blockchain.clients.tron.services.TronCallService -import com.gemwallet.android.blockchain.clients.tron.services.TronNodeStatusService -import com.gemwallet.android.blockchain.clients.tron.services.getAccount -import com.gemwallet.android.blockchain.clients.tron.services.getAccountUsage import com.gemwallet.android.ext.asset import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams @@ -25,11 +20,9 @@ import java.math.BigInteger class TronSignerPreloader( private val chain: Chain, - private val nodeStatusService: TronNodeStatusService, - private val accountsService: TronAccountsService, - callService: TronCallService, + private val client: TronRpcClient, ) : NativeTransferPreloader, TokenTransferPreloader, StakeTransactionPreloader, SwapTransactionPreloader { - val feeCalculator = TronFeeCalculator(chain, nodeStatusService, callService) + val feeCalculator = TronFeeCalculator(chain, client) override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { return preload( @@ -83,9 +76,9 @@ class TronSignerPreloader( feeCalc: suspend (TronAccount?, TronAccountUsage?) -> Fee, votes: suspend (TronAccount?) -> Map, ): SignerParams = withContext(Dispatchers.IO) { - val getAccountUsage = async { accountsService.getAccountUsage(params.from.address) } - val getAccount = async { accountsService.getAccount(params.from.address, true) } - val nowBlockJob = async { nodeStatusService.nowBlock() } + val getAccountUsage = async { client.getAccountUsage(params.from.address) } + val getAccount = async { client.getAccount(params.from.address, true) } + val nowBlockJob = async { client.nowBlock() } val nowBlock = nowBlockJob.await().getOrThrow() val account = getAccount.await() diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronStakeClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronStakeClient.kt deleted file mode 100644 index c2b792798..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronStakeClient.kt +++ /dev/null @@ -1,123 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.clients.StakeClient -import com.gemwallet.android.blockchain.clients.tron.services.TronAccountsService -import com.gemwallet.android.blockchain.clients.tron.services.TronStakeService -import com.gemwallet.android.blockchain.clients.tron.services.getAccount -import com.gemwallet.android.ext.asset -import com.gemwallet.android.math.decodeHex -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.DelegationBase -import com.wallet.core.primitives.DelegationState -import com.wallet.core.primitives.DelegationValidator -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import wallet.core.jni.Base58 -import java.math.BigInteger -import kotlin.math.roundToLong - -class TronStakeClient( - private val chain: Chain, - private val stakeService: TronStakeService, - private val accountsService: TronAccountsService, -) : StakeClient { - override suspend fun getValidators( - chain: Chain, - apr: Double - ): List { - val validators = stakeService.listwitnesses().getOrNull()?.witnesses - ?.mapNotNull { - DelegationValidator( - id = addressBase58(it.address) ?: return@mapNotNull null, - chain = chain, - name = "", - isActive = it.isJobs == true, - commision = 0.0, - apr = apr, - ) - } ?: emptyList() - return validators + getSystem() - } - - - override suspend fun getStakeDelegations( - chain: Chain, - address: String, - apr: Double - ): List = withContext(Dispatchers.IO) { - val getAccount = async { accountsService.getAccount(address, true) } - val getValidators = async { getValidators(chain, apr = 0.0) } - val getReward = async { stakeService.getReward(address).getOrNull()?.reward ?: 0L } - - val account = getAccount.await() - val validators = getValidators.await() - val reward = getReward.await() - - val pendingDelegations = (account?.unfrozenV2 ?: emptyList()).mapNotNull { unfrozen -> - val expireTime = unfrozen.unfreeze_expire_time ?: return@mapNotNull null - val amount = unfrozen.unfreeze_amount ?: return@mapNotNull null - val completionDate = expireTime - val state = if (System.currentTimeMillis() < expireTime) DelegationState.Pending else DelegationState.AwaitingWithdrawal - val balance = BigInteger.valueOf(amount) - - DelegationBase( - assetId = AssetId(chain), - state = state, - balance = balance.toString(), - shares = "", - rewards = "0", - completionDate = completionDate, - delegationId = completionDate.toString(), - validatorId = getSystem().id, - ) - } - - val votes = account?.votes ?: emptyList() - val delegations = votes.mapNotNull { vote -> - val validator = validators.firstOrNull { it.id == vote.vote_address } ?: return@mapNotNull null - val balance = BigInteger.valueOf(vote.vote_count) * BigInteger.TEN.pow(chain.asset().decimals) - val totalVotes = votes.fold(0L) { acc, item -> acc + item.vote_count } - val rewards = if (totalVotes <= 0) { - BigInteger.valueOf(reward) - } else { - val proportion = vote.vote_count.toDouble() / totalVotes.toDouble() - val rewardForVote = reward.toDouble() * proportion - val roundedRewardForVote = rewardForVote.roundToLong() - BigInteger.valueOf(roundedRewardForVote) - } - - DelegationBase( - assetId = AssetId(chain), - state = DelegationState.Active, - balance = balance.toString(), - shares = "", - rewards = rewards.toString(), - completionDate = null, - delegationId = "${balance}_${reward}".toString(), - validatorId = validator.id, - ) - } - pendingDelegations + delegations - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - - private fun getSystem() = DelegationValidator( - id = "unstaking", - chain = chain, - name = "Unstaking", - isActive = true, - commision = 0.0, - apr = 0.0, - ) - - private fun addressBase58(hex: String): String? { - try { - return Base58.encode(hex.decodeHex()) - } catch (_: Throwable) { - return null - } - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronTransactionStatusClient.kt deleted file mode 100644 index 3343875c1..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronTransactionStatusClient.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState -import java.math.BigInteger - -class TronTransactionStatusClient( - private val chain: Chain, - private val rpcClient: TronRpcClient -) : TransactionStatusClient { - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val resp = rpcClient.transaction(TronRpcClient.TronValue(request.hash)).getOrNull() ?: throw ServiceUnavailable - return when { - resp.receipt != null && resp.receipt?.result == "OUT_OF_ENERGY" -> TransactionChanges(TransactionState.Reverted) - resp.result == "FAILED" -> TransactionChanges(TransactionState.Reverted) - resp.blockNumber > 0 -> { - val fee = resp.fee ?: 0 - return TransactionChanges(TransactionState.Confirmed, BigInteger.valueOf(fee.toLong())) - } - else -> TransactionChanges(TransactionState.Pending) - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronAccountsService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronAccountsService.kt deleted file mode 100644 index 91ace2664..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronAccountsService.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron.services - -import android.util.Log -import com.gemwallet.android.math.toHexString -import com.wallet.core.blockchain.tron.TronAccount -import com.wallet.core.blockchain.tron.TronAccountRequest -import com.wallet.core.blockchain.tron.TronAccountUsage -import retrofit2.http.Body -import retrofit2.http.POST -import wallet.core.jni.Base58 - -interface TronAccountsService { - @POST("/wallet/getaccount") - suspend fun getAccount(@Body addressRequest: TronAccountRequest): Result - - @POST("/wallet/getaccountnet") - suspend fun getAccountUsage(@Body addressRequest: TronAccountRequest): Result -} - -suspend fun TronAccountsService.getAccount(address: String, visible: Boolean = false): TronAccount? { - return try { - val result = getAccount( - TronAccountRequest( - address = address, - visible = visible - ) - ) - result.getOrThrow() - } catch (err: Throwable) { - Log.d("TRON-ACCOUNT", "Error: ", err) - null - } -} - -suspend fun TronAccountsService.getAccountUsage(address: String): TronAccountUsage? { - return getAccountUsage( - TronAccountRequest( - address = Base58.decode(address).toHexString(""), - visible = false - ) - ).getOrNull() -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronBalanceService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronBalanceService.kt deleted file mode 100644 index 2872fef27..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronBalanceService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron.services - -import com.gemwallet.android.ext.asset -import com.wallet.core.blockchain.tron.TronAccount -import com.wallet.core.primitives.Chain -import java.math.BigInteger - -fun TronAccount.staked(chain: Chain): BigInteger { - val votes = votes ?: emptyList() - val totalVotes = votes.fold(0L) { acc, item -> acc + item.vote_count } - return BigInteger.valueOf(totalVotes) * BigInteger.TEN.pow(chain.asset().decimals) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronBroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronBroadcastService.kt deleted file mode 100644 index d0174ac80..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronBroadcastService.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron.services - -import okhttp3.RequestBody -import retrofit2.http.Body -import retrofit2.http.POST - -interface TronBroadcastService { - @POST("/wallet/broadcasttransaction") - suspend fun broadcast(@Body body: RequestBody): Result -} - -data class TronTransactionBroadcast( - val result: Boolean, - val txid: String, - val message: String, -) \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronCallService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronCallService.kt deleted file mode 100644 index 241df8ae6..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronCallService.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron.services - -import com.wallet.core.blockchain.tron.TronSmartContractResult -import retrofit2.http.Body -import retrofit2.http.POST - -interface TronCallService { - @POST("/wallet/triggerconstantcontract") - suspend fun triggerSmartContract(@Body addressRequest: Any): Result -} - -suspend fun TronCallService.triggerSmartContract( - contractAddress: String, - functionSelector: String, - parameter: String? = null, - feeLimit: Long? = null, - callValue: Long? = null, - ownerAddress: String, - visible: Boolean? = null, -): Result { - val call = mapOf( - "contract_address" to contractAddress, - "function_selector" to functionSelector, - "parameter" to parameter, - "fee_limit" to feeLimit, - "call_value" to callValue, - "owner_address" to ownerAddress, - "visible" to visible, - ) - return triggerSmartContract(call) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronNodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronNodeStatusService.kt deleted file mode 100644 index 0b35b6fba..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronNodeStatusService.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron.services - -import com.wallet.core.blockchain.tron.TronBlock -import com.wallet.core.blockchain.tron.TronChainParameters -import retrofit2.Response -import retrofit2.http.GET -import retrofit2.http.POST -import retrofit2.http.Url - -interface TronNodeStatusService { - @GET("/wallet/getchainparameters") - suspend fun getChainParameters(): Result - - @POST("/wallet/getnowblock") - suspend fun nowBlock(): Result - - @POST//("/wallet/getnowblock") - suspend fun nowBlock(@Url url: String): Response -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronStakeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronStakeService.kt deleted file mode 100644 index 6d5e77f74..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/services/TronStakeService.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron.services - -import com.wallet.core.blockchain.tron.TronReward -import com.wallet.core.blockchain.tron.WitnessesList -import retrofit2.http.Body -import retrofit2.http.GET -import retrofit2.http.POST - -interface TronStakeService { - @GET("/wallet/listwitnesses") - suspend fun listwitnesses(): Result - - @POST("/wallet/getReward") - suspend fun getReward(@Body address: String): Result - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpBalanceClient.kt deleted file mode 100644 index f7b7c85e8..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpBalanceClient.kt +++ /dev/null @@ -1,52 +0,0 @@ -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.blockchain.clients.xrp.services.accountLines -import com.gemwallet.android.ext.asset -import com.gemwallet.android.ext.getReserveBalance -import com.gemwallet.android.ext.getTokenActivationFee -import com.gemwallet.android.model.AssetBalance -import com.gemwallet.android.model.Crypto -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.Chain -import java.math.BigInteger - -class XrpBalanceClient( - private val chain: Chain, - private val accountsService: XrpAccountsService, -) : BalanceClient { - - override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? { - val account = accountsService.account(address).getOrNull()?.result?.account_data ?: return null - val amount = account.Balance.toBigInteger() - val reserved = chain.getReserveBalance() + (account.OwnerCount.toBigInteger() * chain.getTokenActivationFee()) - return AssetBalance.create( - chain.asset(), - available = BigInteger.ZERO.max(amount - reserved).toString(), - reserved = reserved.toString() - ) - } - - override suspend fun getTokenBalances( - chain: Chain, - address: String, - tokens: List - ): List { - val lines = accountsService.accountLines(address).getOrNull()?.result?.lines ?: emptyList() - return tokens.map { token -> - val line = lines.firstOrNull { it.account == token.id.tokenId && it.currency.length == 40 } - - if (line == null) { - AssetBalance.create(token, available = "0", isActive = false) - } else { - val value = Crypto(line.balance.toBigDecimal(), token.decimals).atomicValue.toString() - AssetBalance.create(token, available = value, isActive = true) - } - } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpBroadcastClient.kt deleted file mode 100644 index 60c05a4c1..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpBroadcastClient.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.gemwallet.android.blockchain.clients.xrp - -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.rpc.ServiceError -import com.gemwallet.android.math.toHexString -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType - -class XrpBroadcastClient( - private val chain: Chain, - private val rpcClient: XrpRpcClient, -) : BroadcastClient { - override suspend fun send(account: Account, signedMessage: ByteArray, type: TransactionType): String { - val request = signedMessage.toHexString("") - val response = rpcClient.broadcast(request).getOrNull() - ?: throw ServiceError.NetworkError - - if (response.result.accepted != true && !response.result.engine_result_message.isNullOrEmpty()) { - throw Exception(response.result.engine_result_message) - } - if (response.result.tx_json?.hash.isNullOrEmpty()) { - throw Exception("Unable to get hash") - } - return response.result.tx_json?.hash!! - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpMethod.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpMethod.kt index 173f62457..366170ada 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpMethod.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpMethod.kt @@ -5,10 +5,6 @@ import com.gemwallet.android.blockchain.rpc.model.JSONRpcMethod enum class XrpMethod(val value: String) : JSONRpcMethod { Account("account_info"), Fee("fee"), - Transaction("tx"), - Broadcast("submit"), - LatestBlock("ledger_current"), - AccountLines("account_lines"), ; override fun value(): String = value diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpNodeStatusClient.kt deleted file mode 100644 index d0099debf..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpNodeStatusClient.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.gemwallet.android.blockchain.clients.xrp - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext - -class XrpNodeStatusClient( - private val chain: Chain, - private val rpcClient: XrpRpcClient, -) : NodeStatusClient { - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? = withContext(Dispatchers.IO) { - val resp = rpcClient.latestBlock(url) - - NodeStatus( - url = url, - blockNumber = resp.body()?.result?.ledger_current_index?.toString() ?: return@withContext null, - inSync = true, - chainId = "", - latency = resp.getLatency(), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpRpcClient.kt index 2f4038b56..cb651f408 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpRpcClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpRpcClient.kt @@ -1,7 +1,7 @@ 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.XRPAccountResult import com.wallet.core.blockchain.xrp.XRPFee import com.wallet.core.blockchain.xrp.XRPLatestBlock import com.wallet.core.blockchain.xrp.XRPResult @@ -12,50 +12,28 @@ import retrofit2.http.Body import retrofit2.http.POST import retrofit2.http.Url -interface XrpRpcClient : XrpAccountsService { +interface XrpRpcClient { @POST("/") suspend fun fee(@Body request: JSONRpcRequest>>): Result> @POST("/") - suspend fun transaction(@Body request: JSONRpcRequest>>): Result> - - @POST("/") - suspend fun broadcast(@Body request: JSONRpcRequest>>): Result> - - @POST//("/") - suspend fun latestBlock(@Url url: String, @Body request: JSONRpcRequest>>): Response> + suspend fun account(@Body request: JSONRpcRequest>>): Result> } -internal suspend fun XrpRpcClient.fee(): Result> { - return fee(JSONRpcRequest.create(XrpMethod.Fee, listOf(mapOf()))) -} - -internal suspend fun XrpRpcClient.transaction(txId: String): Result> { +internal suspend fun XrpRpcClient.account(address: String): Result> { val request = JSONRpcRequest.create( - XrpMethod.Transaction, + XrpMethod.Account, listOf( mapOf( - "transaction" to txId, + "account" to address, + "ledger_index" to "current", ) ) ) - return transaction(request) + return account(request) } -internal suspend fun XrpRpcClient.broadcast(data: String): Result> { - val request = JSONRpcRequest.create( - XrpMethod.Broadcast, - listOf( - mapOf( - "tx_blob" to data, - "fail_hard" to "true" - ) - ) - ) - return broadcast(request) -} - -internal suspend fun XrpRpcClient.latestBlock(url: String): Response> { - return latestBlock(url, JSONRpcRequest.create(XrpMethod.LatestBlock, emptyList())) +internal suspend fun XrpRpcClient.fee(): Result> { + return fee(JSONRpcRequest.create(XrpMethod.Fee, listOf(mapOf()))) } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt index babc3a448..8f8476cee 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt @@ -120,7 +120,7 @@ class XrpSignClient( } }.build() val output = AnySigner.sign(signInput, WCChainTypeProxy().invoke(chain), Ripple.SigningOutput.parser()) - return listOf(output.encoded.toByteArray()) + return listOf(output.encoded.toByteArray().toHexString().toByteArray()) } override fun supported(chain: Chain): Boolean = this.chain == chain diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt index 0b8665bad..7607a08fe 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt @@ -5,7 +5,6 @@ import com.gemwallet.android.blockchain.clients.BlockchainError import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.clients.xrp.services.account import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpTransactionStatusClient.kt deleted file mode 100644 index 6b8d54244..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpTransactionStatusClient.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.gemwallet.android.blockchain.clients.xrp - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState - -class XrpTransactionStatusClient( - private val chain: Chain, - private val rpcClient: XrpRpcClient, -) : TransactionStatusClient { - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - val resp = rpcClient.transaction(request.hash).getOrNull() ?: throw ServiceUnavailable - return TransactionChanges( - if (resp.result.status == "success") { - TransactionState.Confirmed - } else { - TransactionState.Pending - } - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/services/XrpAccountsService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/services/XrpAccountsService.kt deleted file mode 100644 index 1ccd88c62..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/services/XrpAccountsService.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.gemwallet.android.blockchain.clients.xrp.services - -import com.gemwallet.android.blockchain.clients.xrp.XrpMethod -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.wallet.core.blockchain.xrp.XRPAccountLinesResult -import com.wallet.core.blockchain.xrp.XRPAccountResult -import com.wallet.core.blockchain.xrp.XRPResult -import retrofit2.http.Body -import retrofit2.http.POST - -interface XrpAccountsService { - @POST("/") - suspend fun account(@Body request: JSONRpcRequest>>): Result> - - @POST("/") - suspend fun accountLines(@Body request: JSONRpcRequest>>): Result> -} - -internal suspend fun XrpAccountsService.account(address: String): Result> { - val request = JSONRpcRequest.create( - XrpMethod.Account, - listOf( - mapOf( - "account" to address, - "ledger_index" to "current", - ) - ) - ) - return account(request) -} - -internal suspend fun XrpAccountsService.accountLines(address: String): Result> { - val request = JSONRpcRequest.create( - XrpMethod.AccountLines, - listOf( - mapOf( - "account" to address, - "ledger_index" to "current", - ) - ) - ) - return accountLines(request) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/rpc/Response.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/rpc/Response.kt index f82bfec93..486167e43 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/rpc/Response.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/rpc/Response.kt @@ -2,4 +2,4 @@ package com.gemwallet.android.blockchain.rpc import retrofit2.Response -fun Response.getLatency() = raw().receivedResponseAtMillis - raw().sentRequestAtMillis \ No newline at end of file +fun Response.getLatency(): ULong = (raw().receivedResponseAtMillis - raw().sentRequestAtMillis).toULong() \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt new file mode 100644 index 000000000..1da280212 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt @@ -0,0 +1,122 @@ +package com.gemwallet.android.blockchain.services + +import com.gemwallet.android.blockchain.clients.BalanceClient +import com.gemwallet.android.blockchain.clients.getClient +import com.gemwallet.android.ext.asset +import com.gemwallet.android.ext.toChainType +import com.gemwallet.android.ext.toIdentifier +import com.gemwallet.android.ext.type +import com.gemwallet.android.model.AssetBalance +import com.wallet.core.primitives.Account +import com.wallet.core.primitives.Asset +import com.wallet.core.primitives.AssetSubtype +import com.wallet.core.primitives.ChainType +import uniffi.gemstone.GatewayException +import uniffi.gemstone.GemGateway + +class BalancesService( + private val balanceClients: List, + private val gateway: GemGateway, +) { + + suspend fun getNativeBalances(account: Account): AssetBalance? { + return if (account.chain.toChainType() == ChainType.Ethereum) { + val client = balanceClients.getClient(account.chain) ?: return null + try { + client.getNativeBalance(account.chain, account.address) + } catch (_: Throwable) { + null + } + } else { + callNativeBalanceGateWay(account) + } + } + + suspend fun getDelegationBalances(account: Account): AssetBalance? { + return if (account.chain.toChainType() == ChainType.Ethereum) { + val client = balanceClients.getClient(account.chain) ?: return null + try { + client.getDelegationBalances(account.chain, account.address) + } catch (_: Throwable) { + null + } + } else { + callDelegationBalanceGateWay(account) + } + } + + suspend fun getTokensBalances(account: Account, tokens: List): List { + val tokens = tokens.filter { it.id.type() == AssetSubtype.TOKEN && account.chain == it.id.chain } + .ifEmpty { return emptyList() } + + return if (account.chain.toChainType() == ChainType.Ethereum) { + val client = balanceClients.getClient(account.chain) ?: return emptyList() + val tokensBalances = try { + client.getTokenBalances(account.chain, account.address, tokens) + } catch (_: Throwable) { + emptyList() + } + tokensBalances + } else { + callTokenBalancesGateWay(account, tokens) + } + } + + private suspend fun callNativeBalanceGateWay(account: Account): AssetBalance? { + return try { + val result = gateway.getBalanceCoin(account.chain.string, account.address) + AssetBalance.Companion.create( + asset = account.chain.asset(), + available = result.balance.available, + reserved = result.balance.reserved, + isActive = result.isActive, + ) + } catch (_: GatewayException) { + null + } catch (_: Throwable) { + null + } + } + + private suspend fun callTokenBalancesGateWay(account: Account, tokens: List): List { + return try { + val ids = tokens.mapNotNull { it.id.tokenId } + val result = gateway.getBalanceTokens( + account.chain.string, + account.address, + ids + ) + val assetIndex = tokens.groupBy { it.id.toIdentifier() } + val balances = result.mapNotNull { + AssetBalance.Companion.create( + asset = assetIndex[it.assetId]?.firstOrNull() ?: return@mapNotNull null, + available = it.balance.available, + ) + } + balances + } catch (_: GatewayException) { + emptyList() + } catch (_: Throwable) { + emptyList() + } + } + + private suspend fun callDelegationBalanceGateWay(account: Account): AssetBalance? { + return try { + val result = gateway.getBalanceStaking(account.chain.string, account.address) + ?: return null + AssetBalance.Companion.create( + asset = account.chain.asset(), + frozen = result.balance.frozen, + locked = result.balance.locked, + staked = result.balance.staked, + pending = result.balance.pending, + rewards = result.balance.rewards, + ) + } catch (_: GatewayException) { + null + } catch (_: Throwable) { + null + } + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastClientProxy.kt new file mode 100644 index 000000000..479ab348c --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastClientProxy.kt @@ -0,0 +1,44 @@ +package com.gemwallet.android.blockchain.services + +import com.gemwallet.android.blockchain.clients.BroadcastClient +import com.gemwallet.android.blockchain.clients.getClient +import com.gemwallet.android.ext.toChainType +import com.wallet.core.primitives.Account +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.ChainType +import com.wallet.core.primitives.TransactionType +import uniffi.gemstone.GemBroadcastOptions +import uniffi.gemstone.GemGateway + +class BroadcastClientProxy( + private val gateway: GemGateway, + private val clients: List, +) : BroadcastClient { + + override suspend fun send( + account: Account, + signedMessage: ByteArray, + type: TransactionType + ): String { + return if (account.chain.toChainType() == ChainType.Ethereum) { + clients.getClient(account.chain)?.send(account, signedMessage, type) + ?: throw Exception("Chain isn't support") + } else { + val hash = gateway.transactionBroadcast( + chain = account.chain.string, + data = String(signedMessage), + options = GemBroadcastOptions( + when (account.chain) { + Chain.Solana -> type == TransactionType.Swap + else -> false + } + ) + ) + hash + } + } + + override fun supported(chain: Chain): Boolean { + return clients.getClient(chain) != null + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusClientProxy.kt new file mode 100644 index 000000000..b90c38765 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusClientProxy.kt @@ -0,0 +1,39 @@ +package com.gemwallet.android.blockchain.services + +import com.gemwallet.android.blockchain.clients.NodeStatusClient +import com.gemwallet.android.blockchain.clients.getClient +import com.gemwallet.android.ext.toChainType +import com.gemwallet.android.model.NodeStatus +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.ChainType +import uniffi.gemstone.GemGateway + +class NodeStatusClientProxy( + private val gateway: GemGateway, + private val clients: List, +): NodeStatusClient { + + override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? { + return try { + if (chain.toChainType() == ChainType.Ethereum) { + clients.getClient(chain)?.getNodeStatus(chain, url) + } else { + val result = gateway.getNodeStatus(chain.string, url) + NodeStatus( + url = url, + chainId = result.chainId, + blockNumber = result.latestBlockNumber, + inSync = true, + latency = result.latencyMs, + loading = false + ) + } + } catch (_: Throwable) { + null + } + } + + override fun supported(chain: Chain): Boolean { + return clients.getClient(chain) != null + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt similarity index 94% rename from blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClientProxy.kt rename to blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt index d7596db2a..facaf8024 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClientProxy.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt @@ -1,5 +1,7 @@ -package com.gemwallet.android.blockchain.clients +package com.gemwallet.android.blockchain.services +import com.gemwallet.android.blockchain.clients.SignClient +import com.gemwallet.android.blockchain.clients.getClient import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.SignerParams import com.wallet.core.primitives.Chain diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt new file mode 100644 index 000000000..fd749311b --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt @@ -0,0 +1,252 @@ +package com.gemwallet.android.blockchain.services + +import com.gemwallet.android.blockchain.clients.ActivationTransactionPreloader +import com.gemwallet.android.blockchain.clients.ApprovalTransactionPreloader +import com.gemwallet.android.blockchain.clients.GenericTransferPreloader +import com.gemwallet.android.blockchain.clients.NativeTransferPreloader +import com.gemwallet.android.blockchain.clients.NftTransactionPreloader +import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader +import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader +import com.gemwallet.android.blockchain.clients.TokenTransferPreloader +import com.gemwallet.android.blockchain.clients.getClient +import com.gemwallet.android.blockchain.clients.solana.models.SolanaChainData +import com.gemwallet.android.blockchain.services.mapper.toGem +import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.GasFee +import com.gemwallet.android.model.SignerParams +import com.wallet.core.primitives.AssetId +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.FeePriority +import com.wallet.core.primitives.SolanaTokenProgramId +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.withContext +import uniffi.gemstone.GemGasPriceType +import uniffi.gemstone.GemGateway +import uniffi.gemstone.GemGatewayEstimateFee +import uniffi.gemstone.GemSolanaTokenProgramId +import uniffi.gemstone.GemTransactionInputType +import uniffi.gemstone.GemTransactionLoadFee +import uniffi.gemstone.GemTransactionLoadInput +import uniffi.gemstone.GemTransactionLoadMetadata +import uniffi.gemstone.GemTransactionPreloadInput + +class SignerPreloaderProxy( +// private val gemApiClient: GemApiClient, +// private val sessionRepository: SessionRepository, +// private val getDeviceIdCase: GetDeviceIdCase, + private val gateway: GemGateway, + private val nativeTransferClients: List, + private val tokenTransferClients: List, + private val stakeTransactionClients: List, + private val swapTransactionClients: List, + private val approvalTransactionClients: List, + private val activatePreloaderClients: List, + private val genericPreloaderClients: List, + private val nftPreloadClients: List, +) : GenericTransferPreloader, NativeTransferPreloader, TokenTransferPreloader, + StakeTransactionPreloader, + SwapTransactionPreloader, ApprovalTransactionPreloader, ActivationTransactionPreloader, + NftTransactionPreloader { + + suspend fun preload(params: ConfirmParams): SignerParams = withContext(Dispatchers.IO) { +// val isValidTransactionJob = async { +// isValidTransaction( +// getScanTransactionPayload( +// params, +// sessionRepository.getSession()?.wallet +// ?: throw IllegalStateException("Session isn't available"), +// getDeviceIdCase.getDeviceId() +// ) +// ) +// } + + val preloadJob = async { + when (params) { + is ConfirmParams.Stake -> preloadStake(params) + is ConfirmParams.SwapParams -> preloadSwap(params) + is ConfirmParams.TokenApprovalParams -> preloadApproval(params) + is ConfirmParams.TransferParams.Native -> preloadNativeTransfer(params) + is ConfirmParams.TransferParams.Token -> preloadTokenTransfer(params) + is ConfirmParams.Activate -> preloadActivate(params) + is ConfirmParams.TransferParams.Generic -> preloadGeneric(params) + is ConfirmParams.NftParams -> preloadNft(params) + } + } + +// val isValidTransaction = isValidTransactionJob.await() + val preload = preloadJob.await() +// preload.copy(scanTransaction = isValidTransaction) + preload + } + + override fun supported(chain: Chain): Boolean { + return (nativeTransferClients + + tokenTransferClients + + stakeTransactionClients + + swapTransactionClients + + approvalTransactionClients).getClient(chain) != null + } + + override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { + return nativeTransferClients.getClient(params.from.chain)?.preloadNativeTransfer(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { + return tokenTransferClients.getClient(params.from.chain)?.preloadTokenTransfer(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams { + return stakeTransactionClients.getClient(params.from.chain)?.preloadStake(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { + return swapTransactionClients.getClient(params.from.chain)?.preloadSwap(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadApproval(params: ConfirmParams.TokenApprovalParams): SignerParams { + return approvalTransactionClients.getClient(params.from.chain)?.preloadApproval(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadActivate(params: ConfirmParams.Activate): SignerParams { + return activatePreloaderClients.getClient(params.from.chain)?.preloadActivate(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadGeneric(params: ConfirmParams.TransferParams.Generic): SignerParams { + when (params.assetId.chain) { + Chain.Solana -> { + val gemAsset = params.asset.toGem() + val assetId = params.assetId + val chain = assetId.chain + val gemChain = assetId.chain.string + return try { + val result = gateway.getTransactionPreload( + chain = gemChain, + input = GemTransactionPreloadInput( + inputType = GemTransactionInputType.Transfer(gemAsset), + senderAddress = params.from.address, + destinationAddress = params.destination.address, + ) + ) + val feeRates = gateway.getFeeRates( + chain = gemChain, + input = GemTransactionInputType.Transfer(gemAsset), + ) + + val fees = feeRates.map { feeRate -> + val feeRegular = feeRate.gasPriceType as GemGasPriceType.Solana + when (chain) { + Chain.Solana -> { + val metadata = result as? GemTransactionLoadMetadata.Solana + val result = gateway.getTransactionLoad( + chain = gemChain, + input = GemTransactionLoadInput( + inputType = GemTransactionInputType.Transfer(gemAsset), + senderAddress = params.from.address, + destinationAddress = params.destination.address, + value = params.amount.toString(), + gasPrice = feeRegular, + memo = params.memo, + isMaxValue = params.isMax(), + metadata = metadata!!, + ), + provider = object : GemGatewayEstimateFee { + override suspend fun getFee( + chain: uniffi.gemstone.Chain, + input: GemTransactionLoadInput + ): GemTransactionLoadFee? = null + + override suspend fun getFeeData( + chain: uniffi.gemstone.Chain, + input: GemTransactionLoadInput + ): String? = null + } + ) + GasFee( + feeAssetId = AssetId(chain), + priority = FeePriority.entries.firstOrNull { it.string == feeRate.priority } ?: return@map null, + limit = result.fee.gasLimit.toBigInteger(), + maxGasPrice = result.fee.fee.toBigInteger(), + options = result.fee.options.options.mapKeys { it.key.name }.mapValues { it.value.toBigInteger() } + ) + } + else -> null + } + }.filterNotNull() + val metadata = result as GemTransactionLoadMetadata.Solana + SignerParams( + input = params, + chainData = SolanaChainData( + blockhash = metadata.blockHash, + senderTokenAddress = metadata.senderTokenAddress, + recipientTokenAddress = metadata.recipientTokenAddress, + tokenProgram = when (metadata.tokenProgram) { + GemSolanaTokenProgramId.TOKEN -> SolanaTokenProgramId.Token + GemSolanaTokenProgramId.TOKEN2022 -> SolanaTokenProgramId.Token2022 + null -> null + }, + fees = fees + ) + ) + } catch (err: Throwable) { + throw err + } + } + else -> {} + } + return genericPreloaderClients.getClient(params.from.chain)?.preloadGeneric(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadNft(params: ConfirmParams.NftParams): SignerParams { + return nftPreloadClients.getClient(params.from.chain)?.preloadNft(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + +// private suspend fun isValidTransaction(payload: ScanTransactionPayload): ScanTransaction? { +// return try { +// gemApiClient.getScanTransaction(payload).data +// } catch (_: Throwable) { +// null +// } +// } + +// private fun getScanTransactionPayload(params: ConfirmParams, wallet: Wallet, deviceId: String): ScanTransactionPayload { +// val chain = params.assetId.chain +// val origin = ScanAddressTarget( +// chain = chain, +// address = params.from.address, +// ) +// val target = when (params) { +// is ConfirmParams.SwapParams -> ScanAddressTarget( +// params.toAssetId.chain, +// address = wallet.getAccount(params.toAssetId.chain)?.address +// ?: throw IllegalArgumentException("Account isn't available") +// ) +// is ConfirmParams.Stake -> ScanAddressTarget(chain, params.validatorId) +// is ConfirmParams.TokenApprovalParams -> ScanAddressTarget(chain, params.contract) +// is ConfirmParams.TransferParams.Native, +// is ConfirmParams.TransferParams.Generic, +// is ConfirmParams.TransferParams.Token -> ScanAddressTarget( +// chain, +// params.destination().address +// ) +// is ConfirmParams.Activate -> ScanAddressTarget(chain, params.from.address) +// is ConfirmParams.NftParams -> ScanAddressTarget(chain, params.from.address) +// } +// +// return ScanTransactionPayload( +// deviceId = deviceId, +// walletIndex = wallet.index.toUInt(), +// origin = origin, +// target = target, +// type = params.getTxType(), +// ) +// } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeClientProxy.kt new file mode 100644 index 000000000..1eec211dd --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeClientProxy.kt @@ -0,0 +1,81 @@ +package com.gemwallet.android.blockchain.services + +import com.gemwallet.android.blockchain.clients.StakeClient +import com.gemwallet.android.blockchain.clients.getClient +import com.gemwallet.android.ext.toAssetId +import com.gemwallet.android.ext.toChain +import com.gemwallet.android.ext.toChainType +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.ChainType +import com.wallet.core.primitives.DelegationBase +import com.wallet.core.primitives.DelegationState +import com.wallet.core.primitives.DelegationValidator +import uniffi.gemstone.GemGateway + +class StakeClientProxy( + private val gateway: GemGateway, + private val clients: List +) : StakeClient { + override suspend fun getValidators( + chain: Chain, + apr: Double + ): List { + return try { + if (chain.toChainType() == ChainType.Ethereum) { + clients.getClient(chain)?.getValidators(chain, apr) ?: emptyList() + } else { + val result = gateway.getStakingValidators( + chain = chain.string, + apr, + ) + result.mapNotNull { item -> + DelegationValidator( + chain = item.chain.toChain() ?: return@mapNotNull null, + id = item.id, + name = item.name, + isActive = item.isActive, + commision = item.commission, + apr = item.apr, + ) + } + } + } catch (_: Throwable) { + emptyList() + } + } + + override suspend fun getStakeDelegations( + chain: Chain, + address: String, + apr: Double + ): List { + return try { + if (chain.toChainType() == ChainType.Ethereum) { + clients.getClient(chain)?.getStakeDelegations(chain, address, apr) ?: emptyList() + } else { + val result = gateway.getStakingDelegations( + chain = chain.string, + address, + ) + result.mapNotNull { item -> + DelegationBase( + assetId = item.assetId.toAssetId() ?: return@mapNotNull null, + state = DelegationState.entries.firstOrNull { it.string == item.delegationState } ?: return@mapNotNull null, + balance = item.balance, + rewards = item.rewards, + completionDate = item.completionDate?.toLong(), + delegationId = item.delegationId, + validatorId = item.validatorId, + shares = item.shares, + ) + } + } + } catch (_: Throwable) { + emptyList() + } + } + + override fun supported(chain: Chain): Boolean { + return clients.getClient(chain) != null + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt new file mode 100644 index 000000000..e61e7c46a --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt @@ -0,0 +1,77 @@ +package com.gemwallet.android.blockchain.services + +import com.gemwallet.android.blockchain.clients.GetTokenClient +import com.gemwallet.android.blockchain.services.mapper.toApp +import com.gemwallet.android.ext.toAssetId +import com.gemwallet.android.ext.toChainType +import com.wallet.core.primitives.Asset +import com.wallet.core.primitives.AssetBasic +import com.wallet.core.primitives.AssetId +import com.wallet.core.primitives.AssetProperties +import com.wallet.core.primitives.AssetScore +import com.wallet.core.primitives.AssetType +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.ChainType +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.withContext +import uniffi.gemstone.GemGateway + +class TokenService( + private val getTokenClients: List, + private val gateway: GemGateway, +) { + suspend fun search(query: String) = withContext(Dispatchers.IO) { + getTokenClients.map { + async { + try { + if (it.isTokenQuery(query)) { + it.getTokenData(query) + } else { + null + } + } catch (_: Throwable) { + null + } + } + } + .awaitAll() + .filterNotNull() + .map { + AssetBasic( + asset = it, + score = AssetScore(0), + properties = AssetProperties( + isEnabled = false, + isBuyable = false, + isSellable = false, + isSwapable = false, + isStakeable = false + ) + ) + } + } + + suspend fun getTokenData(assetId: AssetId): Asset? { + val tokenId = assetId.tokenId ?: return null + val chain = assetId.chain + return try { + if (chain.toChainType() == ChainType.Ethereum) { + getTokenClients + .firstOrNull { it.supported(assetId.chain) && it.isTokenQuery(tokenId) } + ?.getTokenData(tokenId) + } else { + if (gateway.getIsTokenAddress(chain.string, tokenId)) { + val result = gateway.getTokenData(chain.string, tokenId) + result.toApp() + } else { + null + } + } + } catch (_: Throwable) { + null + } + + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt new file mode 100644 index 000000000..802cb549f --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt @@ -0,0 +1,52 @@ +package com.gemwallet.android.blockchain.services + +import com.gemwallet.android.blockchain.clients.ServiceUnavailable +import com.gemwallet.android.blockchain.clients.TransactionStateRequest +import com.gemwallet.android.blockchain.clients.TransactionStatusClient +import com.gemwallet.android.ext.toAssetId +import com.gemwallet.android.ext.toChainType +import com.gemwallet.android.model.HashChanges +import com.gemwallet.android.model.TransactionChanges +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.ChainType +import com.wallet.core.primitives.TransactionState +import okhttp3.internal.toLongOrDefault +import uniffi.gemstone.GemGateway +import uniffi.gemstone.GemTransactionChange +import uniffi.gemstone.GemTransactionStateRequest +import java.lang.IllegalArgumentException + +class TransactionStatusService( + private val gateway: GemGateway, + private val stateClients: List, +) { + suspend fun getStatus(request: TransactionStateRequest): TransactionChanges? { + return try { + if (request.chain.toChainType() == ChainType.Ethereum) { + stateClients.firstOrNull { it.supported(request.chain) } + ?.getStatus(request) + } else { + val result = gateway.getTransactionStatus( + chain = request.chain.string, + GemTransactionStateRequest( + id = request.hash, + senderAddress = request.sender, + createdAt = 0L, /// TODO: Add created at for HyperCore, + blockNumber = request.block.toLongOrDefault(0L) , + ) + ) + val fee = result.changes.firstNotNullOfOrNull { it as? GemTransactionChange.NetworkFee } + ?.v1?.toBigIntegerOrNull() + val hashChanges = result.changes.firstNotNullOfOrNull { it as? GemTransactionChange.HashChange } + + return TransactionChanges( + state = TransactionState.entries.firstOrNull { it.string == result.state } ?: throw ServiceUnavailable, + fee = fee, + hashChanges = hashChanges?.let { HashChanges(it.old, it.new) } + ) + } + } catch (_: Throwable) { + throw ServiceUnavailable + } + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt new file mode 100644 index 000000000..d56ee41fa --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt @@ -0,0 +1,23 @@ +package com.gemwallet.android.blockchain.services.mapper + +import com.gemwallet.android.ext.toAssetId +import com.gemwallet.android.ext.toIdentifier +import com.wallet.core.primitives.Asset +import com.wallet.core.primitives.AssetType +import uniffi.gemstone.GemAsset + +fun Asset.toGem() = GemAsset( + id = id.toIdentifier(), + name = name, + symbol = symbol, + decimals = decimals, + assetType = type.string, +) + +fun GemAsset.toApp() = Asset( + id = id.toAssetId()!!, + name = name, + symbol = symbol, + decimals = decimals, + type = AssetType.entries.firstOrNull { it.string == assetType }!! +) \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBroadcast.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBroadcast.kt deleted file mode 100644 index 97dda3026..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosBroadcast.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.Mime -import com.gemwallet.android.blockchain.clients.aptos.services.AptosBroadcastService -import com.gemwallet.android.math.decodeHex -import com.wallet.core.blockchain.aptos.AptosTransactionBroacast -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import junit.framework.TestCase.assertEquals -import kotlinx.coroutines.runBlocking -import okhttp3.RequestBody -import okio.Buffer -import org.junit.Test - -class TestAptosBroadcast { - - val sign: ByteArray = ("0x7b2265787069726174696f6e5f74696d657374616d705f73656373223a223336363" + - "4333930303832222c226761735f756e69745f7072696365223a22313530222c226d61785f6761735f616" + - "d6f756e74223a223138222c227061796c6f6164223a7b22617267756d656e7473223a5b2230783832313" + - "131663239373561306636303830643137383233363336396237343739663661656431323033656634613" + - "2336638323035653462393137313662373833222c223130303030303030303030225d2c2266756e63746" + - "96f6e223a223078313a3a6170746f735f6163636f756e743a3a7472616e73666572222c2274797065223" + - "a22656e7472795f66756e6374696f6e5f7061796c6f6164222c22747970655f617267756d656e7473223" + - "a5b5d7d2c2273656e646572223a223078396231646238313138306333316231623432383537326265313" + - "03565323039623561363232326237222c2273657175656e63655f6e756d626572223a2238222c2273696" + - "76e6174757265223a7b227075626c69635f6b6579223a223078633163343364356164646665316332333" + - "761646164363937326435663338663762393631353661636663366637656664386662346435333037653" + - "06365383861222c227369676e6174757265223a223078663063666439373630396263656639636661646" + - "239306264386566363565313432643862393039666537306137383539393434323330656234306566353" + - "061623236306130623931663935633632326364636537636637313835323365356565623532366433666" + - "1356438393635646431333966333637303930653562303031222c2274797065223a22656432353531395" + - "f7369676e6174757265227d7d").decodeHex() - val actualSendingData = "{" + - "\"expiration_timestamp_secs\":\"3664390082\"," + - "\"gas_unit_price\":\"150\"," + - "\"max_gas_amount\":\"18\"," + - "\"payload\":{" + - "\"arguments\":[\"0x82111f2975a0f6080d178236369b7479f6aed1203ef4a23f8205e4b91716b783\",\"10000000000\"]," + - "\"function\":\"0x1::aptos_account::transfer\",\"type\":\"entry_function_payload\",\"type_arguments\":[]}," + - "\"sender\":\"0x9b1db81180c31b1b428572be105e209b5a6222b7\"," + - "\"sequence_number\":\"8\"," + - "\"signature\":{" + - "\"public_key\":\"0xc1c43d5addfe1c237adad6972d5f38f7b96156acfc6f7efd8fb4d5307e0ce88a\"," + - "\"signature\":\"0xf0cfd97609bcef9cfadb90bd8ef65e142d8b909fe70a7859944230eb40ef50ab260a0b91f95c622cdce7cf718523e5eeb526d3fa5d8965dd139f367090e5b001\"," + - "\"type\":\"ed25519_signature\"}}" - - @Test - fun testAptosBroadcast() { - var sendingData: String = "" - val broadcastClient = AptosBroadcastClient( - Chain.Aptos, - object : AptosBroadcastService { - override suspend fun broadcast(request: RequestBody): Result { - assertEquals(Mime.Json.value, request.contentType()) - val buffer = Buffer() - request.writeTo(buffer) - sendingData = String(buffer.inputStream().readAllBytes()) - return Result.success( - AptosTransactionBroacast(hash = "some hash") - ) - } - } - - ) - val result = runBlocking { - broadcastClient.send( - Account(Chain.Aptos, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), - sign, - TransactionType.Transfer, - ) - } - - assertEquals(actualSendingData, sendingData) - assertEquals("some hash", result) - } -} \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosFeeCalculator.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosFeeCalculator.kt index bdfedfa74..d0150d688 100644 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosFeeCalculator.kt +++ b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosFeeCalculator.kt @@ -1,8 +1,6 @@ package com.gemwallet.android.blockchain.clients.aptos import com.gemwallet.android.blockchain.clients.aptos.models.AptosAccount -import com.gemwallet.android.blockchain.clients.aptos.services.AptosAccountsService -import com.gemwallet.android.blockchain.clients.aptos.services.AptosFeeService import com.gemwallet.android.ext.asset import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.DestinationAddress diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt index 19c554353..455ce4896 100644 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt +++ b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt @@ -1,8 +1,6 @@ package com.gemwallet.android.blockchain.clients.aptos import com.gemwallet.android.blockchain.clients.aptos.models.AptosAccount -import com.gemwallet.android.blockchain.clients.aptos.services.AptosAccountsService -import com.gemwallet.android.blockchain.clients.aptos.services.AptosFeeService import com.gemwallet.android.ext.asset import com.gemwallet.android.ext.toIdentifier import com.gemwallet.android.model.ConfirmParams diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosTransactions.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosTransactions.kt deleted file mode 100644 index fabcdd6e2..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosTransactions.kt +++ /dev/null @@ -1,81 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.aptos.services.AptosTransactionsService -import com.wallet.core.blockchain.aptos.AptosTransaction -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertNotNull -import kotlinx.coroutines.runBlocking -import org.junit.Test -import java.math.BigInteger - -class TestAptosTransactions { - - @Test - fun testAptosTransaction() { - var requestId: String = "" - val transactionsClient = AptosTransactionStatusClient( - Chain.Aptos, - object : AptosTransactionsService { - override suspend fun transactions(txId: String): Result { - requestId = txId - return Result.success( - AptosTransaction( - success = true, - gas_used = "100", - gas_unit_price = "10" - ) - ) - } - } - ) - val result = runBlocking { - transactionsClient.getStatus( - TransactionStateRequest( - Chain.Aptos, - "some_id", - "", - "some_address", - ) - ) - } - assertNotNull(result) - assertEquals("some_id", requestId) - assertEquals(TransactionState.Confirmed, result.state) - assertEquals(BigInteger("1000"), result.fee) - } - - @Test - fun testAptosTransactionFail() { - var requestId: String = "" - val transactionsClient = AptosTransactionStatusClient( - Chain.Aptos, - object : AptosTransactionsService { - override suspend fun transactions(txId: String): Result { - requestId = txId - return Result.success( - AptosTransaction( - success = false, - gas_used = "100", - gas_unit_price = "10" - ) - ) - } - } - ) - val result = runBlocking { - transactionsClient.getStatus( - TransactionStateRequest( - Chain.Aptos, - "some_id", - "", - "some_address", - ) - ) - } - assertNotNull(result) - assertEquals(TransactionState.Reverted, result.state) - } -} \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinBroadcast.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinBroadcast.kt deleted file mode 100644 index 09965e574..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinBroadcast.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin - -import com.gemwallet.android.blockchain.Mime -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinBroadcastService -import com.gemwallet.android.math.decodeHex -import com.wallet.core.blockchain.bitcoin.BitcoinTransactionBroacastResult -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import junit.framework.TestCase.assertEquals -import kotlinx.coroutines.runBlocking -import okhttp3.RequestBody -import okio.Buffer -import org.junit.Test - -class TestBitcoinBroadcast { - - val sign = "010000000153bd8a94cf6424d8e54cacbad6082c249cdacdd0956f766206a" + - "c3daed5e5479f010000006b483045022100ead2b7637532b167e66ddf76eafd032ada898c8719a" + - "680de8183b71fb3086a3e022055a073be9148cb8b9dc71de04755dbf11f140fee167ed0d4b44d6" + - "a54a829e75e012102fd6585adc0e86019abf00e83552d054cb5f4359ad4db8ca338099381f43e2" + - "5a5000000000182a82005000000001976a91424849c1d94eb9e6e002dd75fdcbce0a9673daba78" + - "8ac00000000" - - @Test - fun testBitcoinBroadcast() { - var sendingData: String = "" - val broadcastClient = BitcoinBroadcastClient( - Chain.Bitcoin, - object : BitcoinBroadcastService { - override suspend fun broadcast(request: RequestBody): Result { - assertEquals(Mime.Plain.value, request.contentType()) - val buffer = Buffer() - request.writeTo(buffer) - sendingData = String(buffer.inputStream().readAllBytes()) - return Result.success( - BitcoinTransactionBroacastResult(result = "some hash") - ) - } - } - - ) - val result = runBlocking { - broadcastClient.send( - Account(Chain.Bitcoin, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), - sign.decodeHex(), - TransactionType.Transfer, - ) - } - - assertEquals(sign, sendingData) - assertEquals("some hash", result) - } -} \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinTransactions.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinTransactions.kt deleted file mode 100644 index 8936c33cc..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinTransactions.kt +++ /dev/null @@ -1,67 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin - -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinTransactionsService -import com.wallet.core.blockchain.bitcoin.BitcoinTransaction -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertNotNull -import kotlinx.coroutines.runBlocking -import org.junit.Test - -class TestBitcoinTransactions { - - @Test - fun testBitcoinTransaction() { - var requestId = "" - val transactionsClient = BitcoinTransactionStatusClient( - Chain.Bitcoin, - object : BitcoinTransactionsService { - override suspend fun transaction(txId: String): Result { - requestId = txId - return Result.success(BitcoinTransaction(0)) - } - } - ) - val result = runBlocking { - transactionsClient.getStatus( - TransactionStateRequest( - Chain.Bitcoin, - "some_id", - "", - "some_address", - ) - ) - } - assertNotNull(result) - assertEquals("some_id", requestId) - assertEquals(TransactionState.Pending, result.state) - } - - @Test - fun testBitcoinTransactionConfirm() { - var requestId = "" - val transactionsClient = BitcoinTransactionStatusClient( - Chain.Bitcoin, - object : BitcoinTransactionsService { - override suspend fun transaction(txId: String): Result { - requestId = txId - return Result.success(BitcoinTransaction(1)) - } - } - ) - val result = runBlocking { - transactionsClient.getStatus( - TransactionStateRequest( - Chain.Bitcoin, - "some_id", - "", - "some_address", - ) - ) - } - assertNotNull(result) - assertEquals(TransactionState.Confirmed, result.state) - } -} \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosBroadcast.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosBroadcast.kt deleted file mode 100644 index 37f1e242f..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosBroadcast.kt +++ /dev/null @@ -1,109 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import com.gemwallet.android.blockchain.Mime -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosBroadcastService -import com.gemwallet.android.math.decodeHex -import com.wallet.core.blockchain.cosmos.CosmosBroadcastResponse -import com.wallet.core.blockchain.cosmos.CosmosBroadcastResult -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertTrue -import kotlinx.coroutines.runBlocking -import okhttp3.RequestBody -import okio.Buffer -import org.junit.Test - -class TestCosmosBroadcast { - - val sign = "0x7b226d6f6465223a2242524f4144434153545f4d4f44455f53594e43222c2274785f6279746573223" + - "a22436f6f42436f6342436877765932397a6257397a4c6d4a68626d7375646a46695a585268" + - "4d53354e633264545a57356b456d634b4b32397a62573878613264735a57313162585534625" + - "734324e5468714e6d6330656a6c71656d347a656d566d4d6e466b65586c326132783359544d" + - "534b32397a62573878636d4e71646e70364f486436613352785a6e6f346357706d4d4777356" + - "354513161337034646d5177656a42754e3277315932596143776f466457397a62573853416a" + - "4577456d674b55417047436838765932397a6257397a4c6d4e79655842306279357a5a574e7" + - "74d6a5532617a4575554856695332563545694d4b49514d736c63596e374468506535622f38" + - "6c4d33466e50586847426a3553644331352b584931685a31675962424249454367494941526" + - "74b4568514b44676f466457397a62573853425445774d444177454d436144427041564a6b44" + - "786153355a6167686d4a365a7470433979696d374a413864754f384d774f4f44644a6548454" + - "87373483350514e2b34596c2b5356794c744e4557362b4944554b666b4731646649594f7670" + - "5269466c4f79673d3d227d" - - @Test - fun testCosmosBroadcast() { - var sendingData: String = "" - val broadcastClient = CosmosBroadcastClient( - Chain.Cosmos, - object : CosmosBroadcastService { - override suspend fun broadcast(request: RequestBody): Result { - assertEquals(Mime.Json.value, request.contentType()) - val buffer = Buffer() - request.writeTo(buffer) - sendingData = String(buffer.inputStream().readAllBytes()) - return Result.success( - CosmosBroadcastResponse( - CosmosBroadcastResult( - txhash = "some hash", - code = 0, - raw_log = "" - ) - ) - ) - } - } - - ) - val result = runBlocking { - broadcastClient.send( - Account(Chain.Cosmos, "cosmos1kglemumu8mn658j6g4z9jzn3zef2qdyyydv7tr", ""), - sign.decodeHex(), - TransactionType.Transfer, - ) - } - - assertEquals( - "{\"mode\":\"BROADCAST_MODE_SYNC\",\"tx_bytes\":\"CooBCocBChwvY29zbW9zLmJhb" + - "msudjFiZXRhMS5Nc2dTZW5kEmcKK29zbW8xa2dsZW11bXU4bW42NThqNmc0ejlqem4zemVmMnFkeXl2" + - "a2x3YTMSK29zbW8xcmNqdnp6OHd6a3RxZno4cWpmMGw5cTQ1a3p4dmQwejBuN2w1Y2YaCwoFdW9zbW8" + - "SAjEwEmgKUApGCh8vY29zbW9zLmNyeXB0by5zZWNwMjU2azEuUHViS2V5EiMKIQMslcYn7DhPe5b/8l" + - "M3FnPXhGBj5SdC15+XI1hZ1gYbBBIECgIIARgKEhQKDgoFdW9zbW8SBTEwMDAwEMCaDBpAVJkDxaS5Z" + - "aghmJ6ZtpC9yim7JA8duO8MwOODdJeHEHssH3PQN+4Yl+SVyLtNEW6+IDUKfkG1dfIYOvpRiFlOyg==\"}", - sendingData - ) - assertEquals("some hash", result) - } - - @Test - fun testCosmosBroadcastFail() { - var sendingData: String = "" - val broadcastClient = CosmosBroadcastClient( - Chain.Cosmos, - object : CosmosBroadcastService { - override suspend fun broadcast(request: RequestBody): Result { - assertEquals(Mime.Json.value, request.contentType()) - val buffer = Buffer() - request.writeTo(buffer) - sendingData = String(buffer.inputStream().readAllBytes()) - return Result.success( - CosmosBroadcastResponse(CosmosBroadcastResult(txhash = "some hash", code = 1, raw_log = "Some error")) - ) - } - } - - ) - try { - val result = runBlocking { - broadcastClient.send( - Account(Chain.Cosmos, "cosmos1kglemumu8mn658j6g4z9jzn3zef2qdyyydv7tr", ""), - sign.decodeHex(), - TransactionType.Transfer, - ) - } - assertTrue(false) - } catch (err: Throwable) { - assertEquals("Some error", err.message) - } - } -} \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt index 42dc452d3..f8d3f07e7 100644 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt +++ b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt @@ -1,6 +1,5 @@ package com.gemwallet.android.blockchain.clients.cosmos -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosAccountsService import com.gemwallet.android.ext.asset import com.gemwallet.android.ext.toIdentifier import com.gemwallet.android.model.ConfirmParams diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosStake.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosStake.kt deleted file mode 100644 index 2086d86f6..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosStake.kt +++ /dev/null @@ -1,179 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosStakeService -import com.wallet.core.blockchain.cosmos.CosmosBalance -import com.wallet.core.blockchain.cosmos.CosmosDelegation -import com.wallet.core.blockchain.cosmos.CosmosDelegationData -import com.wallet.core.blockchain.cosmos.CosmosDelegations -import com.wallet.core.blockchain.cosmos.CosmosReward -import com.wallet.core.blockchain.cosmos.CosmosRewards -import com.wallet.core.blockchain.cosmos.CosmosUnboudingDelegationEntry -import com.wallet.core.blockchain.cosmos.CosmosUnboundingDelegation -import com.wallet.core.blockchain.cosmos.CosmosUnboundingDelegations -import com.wallet.core.blockchain.cosmos.CosmosValidator -import com.wallet.core.blockchain.cosmos.CosmosValidatorCommission -import com.wallet.core.blockchain.cosmos.CosmosValidatorCommissionRates -import com.wallet.core.blockchain.cosmos.CosmosValidatorMoniker -import com.wallet.core.blockchain.cosmos.CosmosValidators -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.DelegationState -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertFalse -import junit.framework.TestCase.assertNull -import junit.framework.TestCase.assertTrue -import kotlinx.coroutines.runBlocking -import org.junit.Test - -class TestCosmosStake { - - private class TestCosmosStakeService( - val validators: List = listOf( - CosmosValidator( - operator_address = "osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", - jailed = false, - status = "BOND_STATUS_BONDED", - description = CosmosValidatorMoniker("stakebeast"), - commission = CosmosValidatorCommission(CosmosValidatorCommissionRates(rate = "0.050000000000000000")) - ), - CosmosValidator( - operator_address = "osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2", - jailed = false, - status = "BOND_STATUS_UBONDED", - description = CosmosValidatorMoniker("Redline Validation"), - commission = CosmosValidatorCommission(CosmosValidatorCommissionRates(rate = "1.000000000000000000")) - ), - CosmosValidator( - operator_address = "osmovaloper1wgmdcxzp49vjgrqusgcagq6qefk4mtjv5c0k7q", - jailed = true, - status = "BOND_STATUS_UNBONDED", - description = CosmosValidatorMoniker("Dystopia Labs Validator"), - commission = CosmosValidatorCommission(CosmosValidatorCommissionRates(rate = "0.040000000000000000")) - ), - CosmosValidator( - operator_address = "osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", - jailed = false, - status = "BOND_STATUS_BONDED", - description = CosmosValidatorMoniker("Cypher Core"), - commission = CosmosValidatorCommission(CosmosValidatorCommissionRates(rate = "0.100000000000000000")) - ), - ), - val delegations: List = emptyList(), - val unboundings: List = emptyList(), - val rewards: List = emptyList(), - ) : CosmosStakeService { - - var delegationsAddressRequest: String = "" - var unboundingAddressRequest: String = "" - var rewardsAddressRequest: String = "" - - override suspend fun validators(): Result { - return Result.success(CosmosValidators(validators)) - } - - override suspend fun delegations(address: String): Result { - delegationsAddressRequest = address - return Result.success(CosmosDelegations(delegations)) - } - - override suspend fun undelegations(address: String): Result { - unboundingAddressRequest = address - return Result.success(CosmosUnboundingDelegations(unboundings)) - } - - override suspend fun rewards(address: String): Result { - rewardsAddressRequest = address - return Result.success(CosmosRewards(rewards)) - } - - } - - @Test - fun testGetValidators() { - val client = CosmosStakeClient( - chain = Chain.Osmosis, - stakeService = TestCosmosStakeService() - ) - val result = runBlocking { client.getValidators(Chain.Osmosis, 5.68) } - assertFalse(result.isEmpty()) - assertEquals(4, result.size) - for (validator in result) { - assertEquals(Chain.Osmosis, validator.chain) - } - assertTrue(result[0].isActive) - assertFalse(result[1].isActive) - assertFalse(result[2].isActive) - assertTrue(result[3].isActive) - assertEquals("osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", result[0].id) - assertEquals("osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2", result[1].id) - assertEquals("Redline Validation", result[1].name) - assertEquals("Cypher Core", result[3].name) - assertEquals(0.05, result[0].commision) - assertEquals(0.04, result[2].commision) - assertEquals(5.396, result[0].apr) - assertEquals(5.112, result[3].apr) - } - - @Test - fun testGetValidatorsEmpty() { - val client = CosmosStakeClient( - chain = Chain.Osmosis, - stakeService = TestCosmosStakeService(emptyList()) - ) - val result = runBlocking { client.getValidators(Chain.Osmosis, 5.68) } - assertTrue(result.isEmpty()) - } - - @Test - fun testGetDelegations() { - val client = CosmosStakeClient( - Chain.Osmosis, - TestCosmosStakeService( - delegations = listOf( - CosmosDelegation( - CosmosDelegationData("osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm"), - CosmosBalance("uosmo", "1000000") - ), - CosmosDelegation( - CosmosDelegationData("osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2"), - CosmosBalance("uosmo", "1000000") - ), - CosmosDelegation( - CosmosDelegationData("osmovaloper1wgmdcxzp49vjgrqusgcagq6qefk4mtjv5c0k7q"), - CosmosBalance("uosmo", "721000000") - ) - ), - unboundings = listOf( - CosmosUnboundingDelegation( - "osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", - entries = listOf( - CosmosUnboudingDelegationEntry( - creation_height = "25053096", - completion_time = "2024-12-18T02:11:27.650773866Z", - balance = "2000000", - ) - ) - ), - ), - rewards = listOf( - CosmosReward("osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", listOf(CosmosBalance(denom = "uosmo", amount = "808.015913259210000000"))), - CosmosReward("osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2", listOf(CosmosBalance(denom = "uosmo", amount = "808.009961413523000000"))), - CosmosReward("osmovaloper1wgmdcxzp49vjgrqusgcagq6qefk4mtjv5c0k7q", listOf(CosmosBalance(denom = "uosmo", amount = "582579.692713670953000000"))), - ) - ) - ) - val result = runBlocking { client.getStakeDelegations(Chain.Osmosis, "osmo1ac4ns740p4v78n4wr7j3t3s79jjjre6udx7n2v", 5.68) } - assertEquals(4, result.size) - assertEquals(AssetId(Chain.Osmosis), result[0].assetId) - assertEquals(DelegationState.Active, result[0].state) - assertEquals(DelegationState.Pending, result[3].state) - assertEquals("1000000", result[0].balance) - assertEquals("2000000", result[3].balance) - assertEquals("808", result[0].rewards) - assertEquals("808", result[3].rewards) - assertNull(result[0].completionDate) - assertEquals(1735138660866, result[3].completionDate) - assertEquals("", result[0].delegationId) - assertEquals("osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", result[0].validatorId) - } -} \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosTransactions.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosTransactions.kt deleted file mode 100644 index facf07fc9..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosTransactions.kt +++ /dev/null @@ -1,94 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosTransactionsService -import com.wallet.core.blockchain.cosmos.CosmosTransactionDataResponse -import com.wallet.core.blockchain.cosmos.CosmosTransactionResponse -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertNotNull -import kotlinx.coroutines.runBlocking -import org.junit.Test - -class TestCosmosTransactions { - - @Test - fun testCosmosTransaction() { - var requestId = "" - val transactionsService = object : CosmosTransactionsService { - override suspend fun transaction(txId: String): Result { - requestId = txId - return Result.success( - CosmosTransactionResponse( - CosmosTransactionDataResponse( - txId, - 0 - ) - ) - ) - } - - } - val transactionsClient = CosmosTransactionStatusClient(Chain.Osmosis, transactionsService) - val result = runBlocking { - transactionsClient.getStatus( - TransactionStateRequest( - Chain.Cosmos, - "some_id", - "", - "some_address", - ) - ) - } - assertNotNull(result) - assertEquals("some_id", requestId) - assertEquals(TransactionState.Confirmed, result.state) - } - - @Test - fun testCosmosTransactionPending() { - val transactionsService = object : CosmosTransactionsService { - override suspend fun transaction(txId: String): Result { - return Result.success(CosmosTransactionResponse(CosmosTransactionDataResponse("", 0))) - } - - } - val transactionsClient = CosmosTransactionStatusClient(Chain.Osmosis, transactionsService) - val result = runBlocking { - transactionsClient.getStatus( - TransactionStateRequest( - Chain.Cosmos, - "some_id", - "", - "some_address", - ) - ) - } - assertNotNull(result) - assertEquals(TransactionState.Pending, result.state) - } - - @Test - fun testCosmosTransactionReverted() { - val transactionsService = object : CosmosTransactionsService { - override suspend fun transaction(txId: String): Result { - return Result.success(CosmosTransactionResponse(CosmosTransactionDataResponse(txId, 1))) - } - - } - val transactionsClient = CosmosTransactionStatusClient(Chain.Osmosis, transactionsService) - val result = runBlocking { - transactionsClient.getStatus( - TransactionStateRequest( - Chain.Cosmos, - "some_id", - "", - "some_address", - ) - ) - } - assertNotNull(result) - assertEquals(TransactionState.Reverted, result.state) - } -} \ No newline at end of file diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/AssetsRepository.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/AssetsRepository.kt index 642a1eca8..2b512840d 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/AssetsRepository.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/AssetsRepository.kt @@ -1,6 +1,7 @@ package com.gemwallet.android.data.repositoreis.assets import com.gemwallet.android.blockchain.operators.GetAsset +import com.gemwallet.android.blockchain.services.BalancesService import com.gemwallet.android.cases.device.GetDeviceIdCase import com.gemwallet.android.cases.tokens.SearchTokensCase import com.gemwallet.android.cases.transactions.GetTransactions @@ -71,7 +72,7 @@ class AssetsRepository @Inject constructor( private val pricesDao: PricesDao, private val gemApi: GemApiClient, private val sessionRepository: SessionRepository, - private val balancesRemoteSource: BalancesRemoteSource, + private val balancesService: BalancesService, getTransactions: GetTransactions, private val searchTokensCase: SearchTokensCase, private val getDeviceIdCase: GetDeviceIdCase, @@ -453,14 +454,14 @@ class AssetsRepository @Inject constructor( val getNative = async { val prevBalance = balancesDao.getByAccount(walletId, account.address, account.chain.string) - val nativeBalance = balancesRemoteSource.getNativeBalances(account) + val nativeBalance = balancesService.getNativeBalances(account) val dbNativeBalance = DbBalance.mergeNative( prevBalance, nativeBalance?.toRecord(walletId, account.address, updatedAt), ) dbNativeBalance?.let { runCatching { balancesDao.insert(it) } } - val delegationBalances = balancesRemoteSource.getDelegationBalances(account) + val delegationBalances = balancesService.getDelegationBalances(account) val dbFullBalance = DbBalance.mergeDelegation(dbNativeBalance, delegationBalances ?.toRecord(walletId, account.address, updatedAt)) dbFullBalance?.let { runCatching { balancesDao.insert(it) } } @@ -468,7 +469,7 @@ class AssetsRepository @Inject constructor( } val getTokens = async { - val balances = balancesRemoteSource.getTokensBalances(account, tokens) + val balances = balancesService.getTokensBalances(account, tokens) runCatching { balancesDao.insert( balances.map { diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/BalancesRemoteSource.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/BalancesRemoteSource.kt deleted file mode 100644 index 036a03cc5..000000000 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/BalancesRemoteSource.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.gemwallet.android.data.repositoreis.assets - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.getClient -import com.gemwallet.android.ext.type -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetSubtype -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class BalancesRemoteSource @Inject constructor( - private val balanceClients: List, -) { - - suspend fun getNativeBalances(account: Account): AssetBalance? { - val client = balanceClients.getClient(account.chain) ?: return null - return try { - client.getNativeBalance(account.chain, account.address) - } catch (_: Throwable) { - null - } - } - - suspend fun getDelegationBalances(account: Account): AssetBalance? { - val client = balanceClients.getClient(account.chain) ?: return null - return try { - client.getDelegationBalances(account.chain, account.address) - } catch (_: Throwable) { - null - } - } - - suspend fun getTokensBalances(account: Account, tokens: List): List { - val client = balanceClients.getClient(account.chain) ?: return emptyList() - - val tokens = tokens.filter { it.id.type() == AssetSubtype.TOKEN && account.chain == it.id.chain } - .ifEmpty { return emptyList() } - val tokensBalances = try { - client.getTokenBalances(account.chain, account.address, tokens) - } catch (_: Throwable) { - emptyList() - } - return tokensBalances - } -} \ No newline at end of file diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/Namespace.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/Namespace.kt index 478494e6e..4c4c3e111 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/Namespace.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/bridge/Namespace.kt @@ -1,5 +1,6 @@ package com.gemwallet.android.data.repositoreis.bridge +import com.gemwallet.android.ext.toChain import com.gemwallet.android.ext.toChainType import com.wallet.core.primitives.Chain import com.wallet.core.primitives.ChainType @@ -50,9 +51,7 @@ fun Chain.getReference(): String? { fun Chain.Companion.getNamespace(walletConnectChainId: String?): Chain? { // TODO: Use Reown call for parse val chainId = walletConnectChainId?.split(":") return if (!chainId.isNullOrEmpty() && chainId.size >= 2) { - WalletConnectNamespace().getChain(chainId[0], chainId[1])?.let { namespace -> - Chain.entries.firstOrNull { it.string == namespace } - } + WalletConnectNamespace().getChain(chainId[0], chainId[1])?.toChain() } else { null } diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt index 7a3ebb211..63a9e53b2 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt @@ -1,27 +1,13 @@ package com.gemwallet.android.data.repositoreis.di import com.gemwallet.android.blockchain.RpcClientAdapter -import com.gemwallet.android.blockchain.clients.algorand.AlgorandBalanceClient -import com.gemwallet.android.blockchain.clients.aptos.AptosBalanceClient -import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinBalanceClient -import com.gemwallet.android.blockchain.clients.cardano.CardanoBalanceClient -import com.gemwallet.android.blockchain.clients.cosmos.CosmosBalanceClient import com.gemwallet.android.blockchain.clients.ethereum.EvmBalanceClient import com.gemwallet.android.blockchain.clients.ethereum.SmartchainStakeClient -import com.gemwallet.android.blockchain.clients.hyper.HyperCoreBalanceClient -import com.gemwallet.android.blockchain.clients.near.NearBalanceClient -import com.gemwallet.android.blockchain.clients.polkadot.PolkadotBalancesClient -import com.gemwallet.android.blockchain.clients.solana.SolanaBalanceClient -import com.gemwallet.android.blockchain.clients.stellar.StellarBalanceClient -import com.gemwallet.android.blockchain.clients.sui.SuiBalanceClient -import com.gemwallet.android.blockchain.clients.ton.TonBalanceClient -import com.gemwallet.android.blockchain.clients.tron.TronBalanceClient -import com.gemwallet.android.blockchain.clients.xrp.XrpBalanceClient import com.gemwallet.android.cases.device.GetDeviceIdCase import com.gemwallet.android.cases.tokens.SearchTokensCase import com.gemwallet.android.cases.transactions.GetTransactions import com.gemwallet.android.data.repositoreis.assets.AssetsRepository -import com.gemwallet.android.data.repositoreis.assets.BalancesRemoteSource +import com.gemwallet.android.blockchain.services.BalancesService import com.gemwallet.android.data.repositoreis.assets.PriceWebSocketClient import com.gemwallet.android.data.repositoreis.session.SessionRepository import com.gemwallet.android.data.service.store.database.AssetsDao @@ -38,6 +24,9 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import uniffi.gemstone.AlienProvider +import uniffi.gemstone.GemGateway +import uniffi.gemstone.GemPreferences import javax.inject.Singleton @InstallIn(SingletonComponent::class) @@ -52,7 +41,7 @@ object AssetsModule { balancesDao: BalancesDao, pricesDao: PricesDao, sessionRepository: SessionRepository, - balancesRemoteSource: BalancesRemoteSource, + balancesService: BalancesService, getTransactions: GetTransactions, searchTokensCase: SearchTokensCase, getDeviceIdCase: GetDeviceIdCase, @@ -65,34 +54,57 @@ object AssetsModule { pricesDao = pricesDao, sessionRepository = sessionRepository, getTransactions = getTransactions, - balancesRemoteSource = balancesRemoteSource, + balancesService = balancesService, searchTokensCase = searchTokensCase, getDeviceIdCase = getDeviceIdCase, priceClient = priceClient ) + @Provides + @Singleton + fun provideGateway(alienProvider: AlienProvider): GemGateway { + return GemGateway( + alienProvider, + object : GemPreferences { + override fun get(key: String): String? { + TODO("Not yet implemented") + } + + override fun set(key: String, value: String) { + TODO("Not yet implemented") + } + + override fun remove(key: String) { + TODO("Not yet implemented") + } + }, + object : GemPreferences { + override fun get(key: String): String? { + TODO("Not yet implemented") + } + + override fun set(key: String, value: String) { + TODO("Not yet implemented") + } + + override fun remove(key: String) { + TODO("Not yet implemented") + } + }, + ) + } + @Provides @Singleton fun provideBalanceRemoteSource( rpcClients: RpcClientAdapter, - ): BalancesRemoteSource = BalancesRemoteSource( - Chain.available().map { + gateway: GemGateway, + ): BalancesService = BalancesService( + gateway = gateway, + balanceClients = Chain.available().mapNotNull { when (it.toChainType()) { - ChainType.Bitcoin -> BitcoinBalanceClient(it, rpcClients.getClient(it)) ChainType.Ethereum -> EvmBalanceClient(it, rpcClients.getClient(it), rpcClients.getClient(it), SmartchainStakeClient(it, rpcClients.getClient(it))) - ChainType.Solana -> SolanaBalanceClient(it, rpcClients.getClient(Chain.Solana), rpcClients.getClient(Chain.Solana), rpcClients.getClient(Chain.Solana)) - ChainType.Cosmos -> CosmosBalanceClient(it, rpcClients.getClient(it), rpcClients.getClient(it)) - ChainType.Ton -> TonBalanceClient(it, rpcClients.getClient(Chain.Ton)) - ChainType.Tron -> TronBalanceClient(it, rpcClients.getClient(Chain.Tron), rpcClients.getClient(Chain.Tron), rpcClients.getClient(Chain.Tron)) - ChainType.Aptos -> AptosBalanceClient(it, rpcClients.getClient(it)) - ChainType.Sui -> SuiBalanceClient(it, rpcClients.getClient(it)) - ChainType.Xrp -> XrpBalanceClient(it, rpcClients.getClient(it)) - ChainType.Near -> NearBalanceClient(it, rpcClients.getClient(it)) - ChainType.Algorand -> AlgorandBalanceClient(it, rpcClients.getClient(it)) - ChainType.Stellar -> StellarBalanceClient(it, rpcClients.getClient(it)) - ChainType.Polkadot -> PolkadotBalancesClient(it, rpcClients.getClient(it)) - ChainType.Cardano -> CardanoBalanceClient(it, rpcClients.getClient(it)) - ChainType.HyperCore -> HyperCoreBalanceClient(it) + else -> null } } ) diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt index 651844ed8..a667d1545 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt @@ -1,12 +1,7 @@ package com.gemwallet.android.data.repositoreis.di import com.gemwallet.android.blockchain.RpcClientAdapter -import com.gemwallet.android.blockchain.clients.cosmos.CosmosStakeClient import com.gemwallet.android.blockchain.clients.ethereum.SmartchainStakeClient -import com.gemwallet.android.blockchain.clients.hyper.HyperCoreStakeClient -import com.gemwallet.android.blockchain.clients.solana.SolanaStakeClient -import com.gemwallet.android.blockchain.clients.sui.SuiStakeClient -import com.gemwallet.android.blockchain.clients.tron.TronStakeClient import com.gemwallet.android.data.repositoreis.stake.StakeRepository import com.gemwallet.android.data.service.store.database.StakeDao import com.gemwallet.android.data.services.gemapi.GemApiClient @@ -19,6 +14,7 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import uniffi.gemstone.GemGateway import javax.inject.Singleton @InstallIn(SingletonComponent::class) @@ -28,6 +24,7 @@ object StakeModule { @Provides fun provideStakeRepository( stakeDao: StakeDao, + gateway: GemGateway, rpcClients: RpcClientAdapter, gemApiStaticClient: GemApiStaticClient, gemApiClient: GemApiClient, @@ -35,32 +32,15 @@ object StakeModule { stakeDao = stakeDao, gemApiStaticClient = gemApiStaticClient, gemApiClient = gemApiClient, + gateway = gateway, stakeClients = Chain.available().mapNotNull { when (it.toChainType()) { ChainType.Ethereum -> when (it) { Chain.SmartChain -> SmartchainStakeClient(it, rpcClients.getClient(it)) else -> null } - ChainType.Solana -> SolanaStakeClient(it, rpcClients.getClient(it)) - ChainType.Cosmos -> { - when (it) { - Chain.Noble, Chain.Thorchain -> null - else -> CosmosStakeClient(it, rpcClients.getClient(it)) - } - } - ChainType.Sui -> SuiStakeClient(it, rpcClients.getClient(it)) - ChainType.Tron -> TronStakeClient(it, rpcClients.getClient(it), rpcClients.getClient(it)) - ChainType.HyperCore -> HyperCoreStakeClient(it) - ChainType.Bitcoin, - ChainType.Ton, - ChainType.Tron, - ChainType.Aptos, - ChainType.Xrp, - ChainType.Algorand, - ChainType.Stellar, - ChainType.Polkadot, - ChainType.Cardano, - ChainType.Near -> null + else -> null +// ChainType.Tron -> TronStakeClient(it, rpcClients.getClient(it), rpcClients.getClient(it)) } } ) diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/SwapModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/SwapModule.kt index 5479e4ee9..6fa3879be 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/SwapModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/SwapModule.kt @@ -1,9 +1,11 @@ package com.gemwallet.android.data.repositoreis.di -import com.gemwallet.android.blockchain.clients.SignClientProxy +import com.gemwallet.android.blockchain.services.SignClientProxy import com.gemwallet.android.blockchain.operators.LoadPrivateKeyOperator import com.gemwallet.android.blockchain.operators.PasswordStore import com.gemwallet.android.cases.nodes.GetCurrentNodeCase +import com.gemwallet.android.cases.nodes.GetNodesCase +import com.gemwallet.android.cases.nodes.SetCurrentNodeCase import com.gemwallet.android.cases.swap.GetSwapQuotes import com.gemwallet.android.cases.swap.GetSwapSupported import com.gemwallet.android.data.repositoreis.swap.NativeProvider @@ -12,6 +14,7 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import uniffi.gemstone.AlienProvider import uniffi.gemstone.GemSwapper import javax.inject.Singleton @@ -21,9 +24,19 @@ object SwapModule { @Singleton @Provides - fun provideGemSwapper( + fun provideAlienProvider( + getNodesCase: GetNodesCase, getCurrentNodeCase: GetCurrentNodeCase, - ) = GemSwapper(NativeProvider(getCurrentNodeCase)) + setCurrentNodeCase: SetCurrentNodeCase, + ): AlienProvider { + return NativeProvider(getNodesCase, getCurrentNodeCase, setCurrentNodeCase) + } + + @Singleton + @Provides + fun provideGemSwapper( + alienProvider: AlienProvider, + ) = GemSwapper(alienProvider) @Singleton @Provides diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt index 21052757a..e18ee577f 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt @@ -1,13 +1,8 @@ package com.gemwallet.android.data.repositoreis.di import com.gemwallet.android.blockchain.RpcClientAdapter -import com.gemwallet.android.blockchain.clients.aptos.AptosGetTokenClient import com.gemwallet.android.blockchain.clients.ethereum.EvmGetTokenClient -import com.gemwallet.android.blockchain.clients.hyper.HyperCoreGetTokenClient -import com.gemwallet.android.blockchain.clients.solana.SolanaTokenClient -import com.gemwallet.android.blockchain.clients.sui.SuiGetTokenClient -import com.gemwallet.android.blockchain.clients.ton.TonGetTokenClient -import com.gemwallet.android.blockchain.clients.tron.TronGetTokenClient +import com.gemwallet.android.blockchain.services.TokenService import com.gemwallet.android.cases.tokens.SearchTokensCase import com.gemwallet.android.data.repositoreis.tokens.TokensRepository import com.gemwallet.android.data.service.store.database.AssetsDao @@ -21,6 +16,7 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import uniffi.gemstone.GemGateway import javax.inject.Singleton @InstallIn(SingletonComponent::class) @@ -31,31 +27,23 @@ object TokensModule { fun provideTokensRepository( assetsDao: AssetsDao, assetsPriorityDao: AssetsPriorityDao, + gateway: GemGateway, gemApiClient: GemApiClient, rpcClients: RpcClientAdapter, ): TokensRepository = TokensRepository( assetsDao = assetsDao, assetsPriorityDao = assetsPriorityDao, gemApiClient = gemApiClient, - getTokenClients = Chain.available().mapNotNull { chain -> - when (chain.toChainType()) { - ChainType.Ethereum -> EvmGetTokenClient(chain, rpcClients.getClient(chain)) - ChainType.Solana -> SolanaTokenClient(chain, rpcClients.getClient(chain)) - ChainType.Ton -> TonGetTokenClient(chain, rpcClients.getClient(chain)) - ChainType.Tron -> TronGetTokenClient(chain, rpcClients.getClient(chain)) - ChainType.Sui -> SuiGetTokenClient(chain, rpcClients.getClient(chain)) - ChainType.Aptos -> AptosGetTokenClient(chain, rpcClients.getClient(chain)) - ChainType.Bitcoin, - ChainType.Cosmos, - ChainType.Xrp, - ChainType.Algorand, - ChainType.Stellar, - ChainType.Polkadot, - ChainType.Cardano, - ChainType.HyperCore -> HyperCoreGetTokenClient(chain) - ChainType.Near -> null + tokenService = TokenService( + gateway = gateway, + getTokenClients = Chain.available().mapNotNull { chain -> + when (chain.toChainType()) { + ChainType.Ethereum -> EvmGetTokenClient(chain, rpcClients.getClient(chain)) + else -> null + } } - } + ), + ) @Provides diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt index 13e014a35..d261a651e 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt @@ -1,21 +1,8 @@ package com.gemwallet.android.data.repositoreis.di import com.gemwallet.android.blockchain.RpcClientAdapter -import com.gemwallet.android.blockchain.clients.algorand.AlgorandTransactionStatusClient -import com.gemwallet.android.blockchain.clients.aptos.AptosTransactionStatusClient -import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinTransactionStatusClient -import com.gemwallet.android.blockchain.clients.cardano.CardanoTransactionStatusClient -import com.gemwallet.android.blockchain.clients.cosmos.CosmosTransactionStatusClient import com.gemwallet.android.blockchain.clients.ethereum.EvmTransactionStatusClient -import com.gemwallet.android.blockchain.clients.hyper.HyperCoreTransactionsStatusClient -import com.gemwallet.android.blockchain.clients.near.NearTransactionStatusClient -import com.gemwallet.android.blockchain.clients.polkadot.PolkadotTransactionStatusClient -import com.gemwallet.android.blockchain.clients.solana.SolanaTransactionStatusClient -import com.gemwallet.android.blockchain.clients.stellar.StellarTransactionStatusClient -import com.gemwallet.android.blockchain.clients.sui.SuiTransactionStatusClient -import com.gemwallet.android.blockchain.clients.ton.TonTransactionStatusClient -import com.gemwallet.android.blockchain.clients.tron.TronTransactionStatusClient -import com.gemwallet.android.blockchain.clients.xrp.XrpTransactionStatusClient +import com.gemwallet.android.blockchain.services.TransactionStatusService import com.gemwallet.android.cases.device.GetDeviceIdCase import com.gemwallet.android.cases.transactions.ClearPendingTransactions import com.gemwallet.android.cases.transactions.CreateTransaction @@ -39,6 +26,7 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import uniffi.gemstone.GemGateway import javax.inject.Singleton @InstallIn(SingletonComponent::class) @@ -50,29 +38,20 @@ object TransactionsModule { fun provideTransactionsRepository( transactionsDao: TransactionsDao, assetsDao: AssetsDao, + gateway: GemGateway, rpcClients: RpcClientAdapter, ): TransactionsRepository = TransactionsRepository( transactionsDao = transactionsDao, assetsDao = assetsDao, - stateClients = Chain.available().map { - when (it.toChainType()) { - ChainType.Bitcoin -> BitcoinTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Ethereum -> EvmTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Solana -> SolanaTransactionStatusClient(it, rpcClients.getClient(Chain.Solana)) - ChainType.Cosmos -> CosmosTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Ton -> TonTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Tron -> TronTransactionStatusClient(it, rpcClients.getClient(Chain.Tron)) - ChainType.Aptos -> AptosTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Sui -> SuiTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Xrp -> XrpTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Near -> NearTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Algorand -> AlgorandTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Stellar -> StellarTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Polkadot -> PolkadotTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.Cardano -> CardanoTransactionStatusClient(it, rpcClients.getClient(it)) - ChainType.HyperCore -> HyperCoreTransactionsStatusClient(it) + transactionStatusService = TransactionStatusService( + gateway = gateway, + stateClients = Chain.available().mapNotNull { + when (it.toChainType()) { + ChainType.Ethereum -> EvmTransactionStatusClient(it, rpcClients.getClient(it)) + else -> null + } } - }, + ), ) @Singleton diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/stake/StakeRepository.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/stake/StakeRepository.kt index 193a7b971..98822e128 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/stake/StakeRepository.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/stake/StakeRepository.kt @@ -1,6 +1,7 @@ package com.gemwallet.android.data.repositoreis.stake import com.gemwallet.android.blockchain.clients.StakeClient +import com.gemwallet.android.blockchain.services.StakeClientProxy import com.gemwallet.android.data.service.store.database.StakeDao import com.gemwallet.android.data.service.store.database.entities.toModel import com.gemwallet.android.data.service.store.database.entities.toRecord @@ -15,24 +16,24 @@ import com.wallet.core.primitives.DelegationBase import com.wallet.core.primitives.DelegationValidator import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.mapNotNull -import kotlinx.coroutines.flow.toList import kotlinx.coroutines.withContext import uniffi.gemstone.Config +import uniffi.gemstone.GemGateway import java.math.BigInteger class StakeRepository( private val gemApiStaticClient: GemApiStaticClient, private val gemApiClient: GemApiClient, + private val gateway: GemGateway, private val stakeClients: List, private val stakeDao: StakeDao, ) { private val recommendedValidators = Config().getValidators() + private val stakeClientsProxy = StakeClientProxy(gateway, stakeClients) + suspend fun sync(chain: Chain, address: String) = withContext(Dispatchers.IO) { val apr = try { gemApiClient.getAsset(chain.string, Currency.USD.string).properties.stakingApr ?: return@withContext @@ -45,7 +46,8 @@ class StakeRepository( private suspend fun syncDelegations(chain: Chain, address: String, apr: Double) = withContext(Dispatchers.IO) { val delegations = try { - stakeClients.firstOrNull { it.supported(chain) }?.getStakeDelegations(chain, address, apr) ?: return@withContext + stakeClientsProxy.getStakeDelegations(chain, address, apr) +// stakeClients.firstOrNull { it.supported(chain) }?.getStakeDelegations(chain, address, apr) ?: return@withContext } catch (_: Throwable) { return@withContext } @@ -61,18 +63,7 @@ class StakeRepository( } catch (_: Throwable) { emptyMap() } - val validators = stakeClients.filter { it.supported(chain) } - .asFlow() - .mapNotNull { - try { - it.getValidators(chain, apr) - } catch (_: Throwable) { - null - } - } - .flowOn(Dispatchers.IO) - .toList() - .flatten() + val validators = stakeClientsProxy.getValidators(chain, apr) .map { if (it.name.isEmpty()) { it.copy(name = validatorsInfo[it.id]?.name ?: "") diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/swap/NativeProvider.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/swap/NativeProvider.kt index c7b6bbe7d..1fcda227e 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/swap/NativeProvider.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/swap/NativeProvider.kt @@ -1,7 +1,10 @@ package com.gemwallet.android.data.repositoreis.swap import com.gemwallet.android.cases.nodes.GetCurrentNodeCase -import com.wallet.core.primitives.Chain +import com.gemwallet.android.cases.nodes.GetNodesCase +import com.gemwallet.android.cases.nodes.SetCurrentNodeCase +import com.gemwallet.android.data.services.gemapi.http.getNodeUrl +import com.gemwallet.android.ext.toChain import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -13,14 +16,15 @@ import uniffi.gemstone.AlienProvider import uniffi.gemstone.AlienTarget class NativeProvider( + private val getNodesCase: GetNodesCase, private val getCurrentNodeCase: GetCurrentNodeCase, + private val setCurrentNodeCase: SetCurrentNodeCase, private val httpClient: OkHttpClient = OkHttpClient(), ): AlienProvider { override fun getEndpoint(chain: uniffi.gemstone.Chain): String { - return Chain.entries.firstOrNull { it.string == chain }?.let { - getCurrentNodeCase.getCurrentNode(it)?.url - } ?: throw IllegalArgumentException("Can't found node url for chain: $chain") + return chain.toChain()?.getNodeUrl(getNodesCase, getCurrentNodeCase, setCurrentNodeCase) + ?: throw IllegalArgumentException("Can't found node url for chain: $chain") } override suspend fun batchRequest(targets: List): List = withContext(Dispatchers.IO) { diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/swap/SwapRepository.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/swap/SwapRepository.kt index e418a8367..811a058e1 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/swap/SwapRepository.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/swap/SwapRepository.kt @@ -1,6 +1,6 @@ package com.gemwallet.android.data.repositoreis.swap -import com.gemwallet.android.blockchain.clients.SignClientProxy +import com.gemwallet.android.blockchain.services.SignClientProxy import com.gemwallet.android.blockchain.operators.LoadPrivateKeyOperator import com.gemwallet.android.blockchain.operators.PasswordStore import com.gemwallet.android.cases.swap.GetSwapQuotes diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/tokens/TokensRepository.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/tokens/TokensRepository.kt index 79ec3a285..eea9e4cd4 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/tokens/TokensRepository.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/tokens/TokensRepository.kt @@ -1,6 +1,6 @@ package com.gemwallet.android.data.repositoreis.tokens -import com.gemwallet.android.blockchain.clients.GetTokenClient +import com.gemwallet.android.blockchain.services.TokenService import com.gemwallet.android.cases.tokens.SearchTokensCase import com.gemwallet.android.data.service.store.database.AssetsDao import com.gemwallet.android.data.service.store.database.AssetsPriorityDao @@ -12,15 +12,13 @@ import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.AssetProperties import com.wallet.core.primitives.AssetScore import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll import kotlinx.coroutines.withContext class TokensRepository ( private val assetsDao: AssetsDao, private val assetsPriorityDao: AssetsPriorityDao, private val gemApiClient: GemApiClient, - private val getTokenClients: List, + private val tokenService: TokenService, ) : SearchTokensCase { override suspend fun search(query: String): Boolean = withContext(Dispatchers.IO) { @@ -33,28 +31,7 @@ class TokensRepository ( return@withContext false } val assets = if (tokens.isEmpty()) { - val assets = getTokenClients.map { - async { - try { - if (it.isTokenQuery(query)) { - it.getTokenData(query) - } else { - null - } - } catch (_: Throwable) { - null - } - } - } - .awaitAll() - .mapNotNull { it } - .map { AssetBasic(asset = it, score = AssetScore(0), properties = AssetProperties( - isEnabled = false, - isBuyable = false, - isSellable = false, - isSwapable = false, - isStakeable = false - )) } + val assets = tokenService.search(query) runCatching { assetsDao.insert(assets.map { it.toRecord() }) } assets } else { @@ -67,9 +44,7 @@ class TokensRepository ( override suspend fun search(assetId: AssetId): Boolean { val tokenId = assetId.tokenId ?: return false - val asset = getTokenClients - .firstOrNull { it.supported(assetId.chain) && it.isTokenQuery(tokenId) } - ?.getTokenData(tokenId) + val asset = tokenService.getTokenData(assetId) if (asset == null) { return search(tokenId) } @@ -80,7 +55,7 @@ class TokensRepository ( isSwapable = false, isStakeable = false )) - .toRecord() + .toRecord() runCatching { assetsDao.insert(record) } return true } diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/transactions/TransactionsRepository.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/transactions/TransactionsRepository.kt index c63e8333a..c9c806121 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/transactions/TransactionsRepository.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/transactions/TransactionsRepository.kt @@ -5,6 +5,7 @@ import android.util.Log import com.gemwallet.android.blockchain.clients.ServiceUnavailable import com.gemwallet.android.blockchain.clients.TransactionStateRequest import com.gemwallet.android.blockchain.clients.TransactionStatusClient +import com.gemwallet.android.blockchain.services.TransactionStatusService import com.gemwallet.android.cases.transactions.ClearPendingTransactions import com.gemwallet.android.cases.transactions.CreateTransaction import com.gemwallet.android.cases.transactions.GetTransaction @@ -51,9 +52,9 @@ import java.util.concurrent.ConcurrentHashMap @OptIn(ExperimentalCoroutinesApi::class) class TransactionsRepository( private val transactionsDao: TransactionsDao, - assetsDao: AssetsDao, - private val stateClients: List, + private val transactionStatusService: TransactionStatusService, private val scope: CoroutineScope = CoroutineScope(Dispatchers.IO), + assetsDao: AssetsDao, ) : GetTransactions, GetTransaction, @@ -246,16 +247,14 @@ class TransactionsRepository( private suspend fun checkTx(tx: DbTransactionExtended): DbTransactionExtended? { val assetId = tx.assetId.toAssetId() ?: return null - val stateClient = stateClients.firstOrNull { it.supported(assetId.chain) } ?: return null + val request = TransactionStateRequest( + chain = assetId.chain, + sender = tx.owner, + hash = tx.hash, + block = tx.blockNumber, + ) val state = try { - stateClient.getStatus( - TransactionStateRequest( - chain = assetId.chain, - sender = tx.owner, - hash = tx.hash, - block = tx.blockNumber, - ) - ) + transactionStatusService.getStatus(request) ?: TransactionChanges(tx.state) } catch (_: ServiceUnavailable) { return tx.copy(updatedAt = System.currentTimeMillis()) } catch (_: Throwable) { diff --git a/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt b/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt index 876742c03..e864da7e2 100644 --- a/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt +++ b/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt @@ -12,7 +12,6 @@ import com.gemwallet.android.blockchain.clients.ethereum.services.EvmRpcClient import com.gemwallet.android.blockchain.clients.hyper.services.HyperCoreServices import com.gemwallet.android.blockchain.clients.near.NearRpcClient import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotServices -import com.gemwallet.android.blockchain.clients.solana.services.SolanaRpcClient import com.gemwallet.android.blockchain.clients.stellar.services.StellarService import com.gemwallet.android.blockchain.clients.sui.SuiRpcClient import com.gemwallet.android.blockchain.clients.ton.TonRpcClient @@ -144,12 +143,12 @@ object ClientsModule { ) val gsonConverter = GsonConverterFactory.create(gson) val adapter = RpcClientAdapter() - Chain.available().map { + Chain.available().forEach { val url = "https://${it.string}" val rpc: Any = when (it.toChainType()) { ChainType.Bitcoin -> buildClient(url, BitcoinRpcClient::class.java, converter, httpClient) ChainType.Ethereum -> buildClient(url, EvmRpcClient::class.java, ethConverter, httpClient) - ChainType.Solana -> buildClient(url, SolanaRpcClient::class.java, gsonConverter, httpClient) + ChainType.Solana -> return@forEach ChainType.Cosmos -> buildClient(url, CosmosRpcClient::class.java, converter, httpClient) ChainType.Ton -> buildClient(url, TonRpcClient::class.java, tonConverter, httpClient) ChainType.Tron -> buildClient(url, TronRpcClient::class.java, gsonConverter, httpClient) diff --git a/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/http/GetNodeUrl.kt b/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/http/GetNodeUrl.kt new file mode 100644 index 000000000..37c741fb9 --- /dev/null +++ b/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/http/GetNodeUrl.kt @@ -0,0 +1,26 @@ +package com.gemwallet.android.data.services.gemapi.http + +import com.gemwallet.android.cases.nodes.GetCurrentNodeCase +import com.gemwallet.android.cases.nodes.GetNodesCase +import com.gemwallet.android.cases.nodes.SetCurrentNodeCase +import com.wallet.core.primitives.Chain +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.runBlocking + +fun Chain.getNodeUrl( + getNodesCase: GetNodesCase, + getCurrentNodeCase: GetCurrentNodeCase, + setCurrentNodeCase: SetCurrentNodeCase +): String? { + val currentNode = getCurrentNodeCase.getCurrentNode(this) + val url = if (currentNode == null) { + val node = runBlocking { getNodesCase.getNodes(this@getNodeUrl).firstOrNull()?.firstOrNull() } + if (node != null) { + setCurrentNodeCase.setCurrentNode(this, node) + } + node + } else { + currentNode + }?.url + return url +} \ No newline at end of file diff --git a/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/http/NodeSelectorInterceptor.kt b/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/http/NodeSelectorInterceptor.kt index 00363ffd1..2c653595c 100644 --- a/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/http/NodeSelectorInterceptor.kt +++ b/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/http/NodeSelectorInterceptor.kt @@ -4,6 +4,7 @@ import android.util.Log import com.gemwallet.android.cases.nodes.GetCurrentNodeCase import com.gemwallet.android.cases.nodes.GetNodesCase import com.gemwallet.android.cases.nodes.SetCurrentNodeCase +import com.gemwallet.android.ext.toChain import com.wallet.core.primitives.Chain import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.runBlocking @@ -21,18 +22,8 @@ class NodeSelectorInterceptor( override fun intercept(chain: Interceptor.Chain): Response { val originalRequest = chain.request() - val blockchain = Chain.entries.firstOrNull { it.string == originalRequest.url.host } - ?: return chain.proceed(originalRequest) - val currentNode = getCurrentNodeCase.getCurrentNode(blockchain) - val url = if (currentNode == null) { - val node = runBlocking { getNodesCase.getNodes(blockchain).firstOrNull()?.firstOrNull() } - if (node != null) { - setCurrentNodeCase.setCurrentNode(blockchain, node) - } - node - } else { - currentNode - }?.url + val blockchain = originalRequest.url.host.toChain() ?: return chain.proceed(originalRequest) + val url = blockchain.getNodeUrl(getNodesCase, getCurrentNodeCase, setCurrentNodeCase) if (url != null) { val httpUrl = url.toHttpUrlOrNull()!! diff --git a/features/settings/networks/presents/src/main/kotlin/com/gemwallet/features/settings/networks/presents/NodeItem.kt b/features/settings/networks/presents/src/main/kotlin/com/gemwallet/features/settings/networks/presents/NodeItem.kt index b1a9630e8..8441f24d3 100644 --- a/features/settings/networks/presents/src/main/kotlin/com/gemwallet/features/settings/networks/presents/NodeItem.kt +++ b/features/settings/networks/presents/src/main/kotlin/com/gemwallet/features/settings/networks/presents/NodeItem.kt @@ -55,7 +55,7 @@ internal fun NodeItem( ) }, subtitle = { - val blockNumber = nodeStatus?.blockNumber?.takeIf { !it.isEmpty() }?.let { + val blockNumber = nodeStatus?.blockNumber?.takeIf { it > 0UL }?.let { DecimalFormat.getInstance().format(nodeStatus.blockNumber.toLong()) } ?: "" @@ -89,8 +89,8 @@ private fun NodeItemStatus(nodeStatus: NodeStatus?) { val color = when { nodeStatus?.loading == true -> Color.Transparent nodeStatus?.inSync == true -> when { - nodeStatus.latency < 1024 -> MaterialTheme.colorScheme.tertiary - nodeStatus.latency < 2048 -> Color(0xffff9314) + nodeStatus.latency < 1024UL -> MaterialTheme.colorScheme.tertiary + nodeStatus.latency < 2048UL -> Color(0xffff9314) else -> MaterialTheme.colorScheme.error } else -> MaterialTheme.colorScheme.error @@ -102,7 +102,7 @@ private fun NodeItemStatus(nodeStatus: NodeStatus?) { verticalAlignment = Alignment.CenterVertically, ) { val text = if (nodeStatus?.inSync == true) { - stringResource(R.string.common_latency_in_ms, nodeStatus.latency) + stringResource(R.string.common_latency_in_ms, nodeStatus.latency.toLong()) } else { stringResource(R.string.errors_error) } @@ -132,9 +132,9 @@ fun NodeItemPreview() { nodeStatus = NodeStatus( url = "", chainId = Chain.Ethereum.string, - blockNumber = "123902302938", + blockNumber = 123902302938UL, inSync = true, - latency = 440, + latency = 440UL, loading = false, ) ) { } diff --git a/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/AddNodeViewModel.kt b/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/AddNodeViewModel.kt index 1981b993f..b86692230 100644 --- a/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/AddNodeViewModel.kt +++ b/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/AddNodeViewModel.kt @@ -5,7 +5,7 @@ import android.webkit.URLUtil import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.gemwallet.android.blockchain.clients.NodeStatusClientProxy +import com.gemwallet.android.blockchain.services.NodeStatusClientProxy import com.gemwallet.android.cases.nodes.AddNodeCase import com.gemwallet.android.cases.nodes.SetCurrentNodeCase import com.gemwallet.features.settings.networks.viewmodels.models.AddNodeUIModel diff --git a/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/NetworksViewModel.kt b/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/NetworksViewModel.kt index 446e21206..d71b1171f 100644 --- a/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/NetworksViewModel.kt +++ b/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/NetworksViewModel.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.snapshotFlow import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.gemwallet.android.blockchain.clients.NodeStatusClientProxy +import com.gemwallet.android.blockchain.services.NodeStatusClientProxy import com.gemwallet.android.cases.nodes.GetBlockExplorers import com.gemwallet.android.cases.nodes.GetCurrentBlockExplorer import com.gemwallet.android.cases.nodes.GetCurrentNodeCase @@ -13,9 +13,9 @@ import com.gemwallet.android.cases.nodes.SetBlockExplorerCase import com.gemwallet.android.cases.nodes.SetCurrentNodeCase import com.gemwallet.android.data.repositoreis.chains.ChainInfoRepository import com.gemwallet.android.ext.filter +import com.gemwallet.android.model.NodeStatus import com.gemwallet.features.settings.networks.viewmodels.models.AddSourceType import com.gemwallet.features.settings.networks.viewmodels.models.NetworksUIState -import com.gemwallet.android.model.NodeStatus import com.wallet.core.primitives.Chain import com.wallet.core.primitives.Node import dagger.hilt.android.lifecycle.HiltViewModel @@ -82,9 +82,9 @@ class NetworksViewModel @Inject constructor( statuses[url] = NodeStatus( url = url, chainId = "", - blockNumber = "", + blockNumber = 0UL, inSync = false, - latency = 0, + latency = 0UL, loading = true, ) } diff --git a/features/swap/viewmodels/src/main/kotlin/com/gemwallet/features/swap/viewmodels/SwapSelectViewModel.kt b/features/swap/viewmodels/src/main/kotlin/com/gemwallet/features/swap/viewmodels/SwapSelectViewModel.kt index 41cc5b6c6..5f18fd4f4 100644 --- a/features/swap/viewmodels/src/main/kotlin/com/gemwallet/features/swap/viewmodels/SwapSelectViewModel.kt +++ b/features/swap/viewmodels/src/main/kotlin/com/gemwallet/features/swap/viewmodels/SwapSelectViewModel.kt @@ -6,6 +6,7 @@ import com.gemwallet.android.cases.tokens.SearchTokensCase import com.gemwallet.android.data.repositoreis.assets.AssetsRepository import com.gemwallet.android.data.repositoreis.session.SessionRepository import com.gemwallet.android.ext.toAssetId +import com.gemwallet.android.ext.toChain import com.gemwallet.android.ext.toIdentifier import com.gemwallet.android.model.AssetInfo import com.gemwallet.android.model.Session @@ -75,7 +76,7 @@ class SwapSelectSearch( assetsRepository.swapSearch( params.wallet, params.query, - supported.chains.mapNotNull { item -> Chain.entries.firstOrNull { it.string == item } }, + supported.chains.mapNotNull { item -> item.toChain() }, supported.assetIds.mapNotNull { it.toAssetId() } ) } diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/ext/Chain.kt b/gemcore/src/main/kotlin/com/gemwallet/android/ext/Chain.kt index 991835ad9..b61065bf3 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/ext/Chain.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/ext/Chain.kt @@ -207,4 +207,8 @@ val Chain.keyEncodingTypes: List Chain.Solana -> listOf(EncodingType.Base58, EncodingType.Hex) Chain.Stellar -> listOf(EncodingType.Base32, EncodingType.Hex) else -> listOf(EncodingType.Hex) - } \ No newline at end of file + } + +fun uniffi.gemstone.Chain.toChain(): Chain? { + return Chain.entries.firstOrNull { it.string == this } +} \ No newline at end of file diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/model/AssetBalance.kt b/gemcore/src/main/kotlin/com/gemwallet/android/model/AssetBalance.kt index dcbcfcdfd..156071044 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/model/AssetBalance.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/model/AssetBalance.kt @@ -42,7 +42,7 @@ data class AssetBalance( reserved: String = "0", isActive: Boolean = true, ): AssetBalance { - val balance = Balance( + val balance = Balance( // TODO: Check number is correct available = available, frozen = frozen, locked = locked, diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/model/NodeStatus.kt b/gemcore/src/main/kotlin/com/gemwallet/android/model/NodeStatus.kt index 7e38b6b4f..171f76945 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/model/NodeStatus.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/model/NodeStatus.kt @@ -3,8 +3,8 @@ package com.gemwallet.android.model data class NodeStatus( val url: String, val chainId: String, - val blockNumber: String, + val blockNumber: ULong, val inSync: Boolean, - val latency: Long, + val latency: ULong, val loading: Boolean = false, ) \ No newline at end of file diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt index 380dbed32..a4a4fb69f 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt @@ -16,7 +16,7 @@ enum class PerpetualMarginType(val string: String) { } @Serializable -enum class PerpetualDirection +enum class PerpetualDirection // TODO: It's stub wait fix @Serializable data class PriceTarget ( diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ed27bff17..df53d82a5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,7 +46,7 @@ reorderable = "3.0.0" mockkVersion = "1.14.5" datastore = "1.1.7" wallet-core = "4.3.5" -gemstone = "0.33.0" +gemstone = "0.33.1" ktor = "3.1.3" appcompat = "1.7.1" material = "1.12.0" diff --git a/ui/src/main/kotlin/com/gemwallet/android/ui/components/image/IconUrlGeneration.kt b/ui/src/main/kotlin/com/gemwallet/android/ui/components/image/IconUrlGeneration.kt index 6bcb28da8..b3fc994db 100644 --- a/ui/src/main/kotlin/com/gemwallet/android/ui/components/image/IconUrlGeneration.kt +++ b/ui/src/main/kotlin/com/gemwallet/android/ui/components/image/IconUrlGeneration.kt @@ -63,7 +63,6 @@ fun SwapperProvider.getSwapProviderIcon(): String { SwapperProvider.PANCAKESWAP_V3, SwapperProvider.PANCAKESWAP_APTOS_V2 -> "pancakeswap" SwapperProvider.THORCHAIN -> "thorchain" - SwapperProvider.ORCA -> "orca" SwapperProvider.JUPITER -> "jupiter" SwapperProvider.ACROSS -> "across" SwapperProvider.OKU -> "oku" From c152d8b88675824ea46d46894c3d19767155fc7e Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Wed, 3 Sep 2025 20:58:28 -0700 Subject: [PATCH 04/16] Prepare to integrate gateway preload --- .../com/gemwallet/android/di/DataModule.kt | 22 +- .../confirm/viewmodels/ConfirmViewModel.kt | 48 ++-- .../clients/algorand/TestAlgorandSigner.kt | 2 +- .../clients/aptos/TestAptosSigner.kt | 32 ++- .../clients/bitcoin/TestBitcoinSigner.kt | 2 +- .../clients/cardano/TestCardanoSigner.kt | 1 - .../clients/cosmos/TestCosmosSigner.kt | 10 +- .../blockchain/clients/evm/TestEthSign.kt | 14 +- .../blockchain/clients/near/TestNearSigner.kt | 1 - .../clients/polkadot/TestPolkadotSigner.kt | 2 +- .../clients/solana/TestSolanaSigner.kt | 2 +- .../clients/stellar/TestStellarSigner.kt | 4 +- .../blockchain/clients/sui/TestSuiSigner.kt | 4 +- .../blockchain/clients/ton/TestTonSigner.kt | 4 +- .../blockchain/clients/tron/TestTronSigner.kt | 24 +- .../blockchain/clients/xrp/TestXrpSigner.kt | 2 +- .../android/blockchain/clients/SignClient.kt | 25 +- .../clients/algorand/AlgorandChainData.kt | 18 ++ .../clients/algorand/AlgorandSignClient.kt | 8 +- .../algorand/AlgorandSignPreloadClient.kt | 16 +- .../clients/aptos/AptosChainData.kt | 14 + .../clients/aptos/AptosFeeCalculator.kt | 4 +- .../clients/aptos/AptosSignClient.kt | 22 +- .../clients/aptos/AptosSignerPreloader.kt | 18 +- .../clients/bitcoin/BitcoinChainData.kt | 16 ++ .../clients/bitcoin/BitcoinFeeCalculator.kt | 8 +- .../clients/bitcoin/BitcoinSignClient.kt | 22 +- .../clients/bitcoin/BitcoinSignerPreloader.kt | 38 +-- .../bitcoin/services/BitcoinRpcClient.kt | 3 - .../clients/cardano/CardanoChainData.kt | 16 ++ .../clients/cardano/CardanoSignClient.kt | 6 +- .../cardano/CardanoSignerPreloaderClient.kt | 19 +- .../clients/cosmos/CosmosChainData.kt | 18 ++ .../clients/cosmos/CosmosSignClient.kt | 43 ++-- .../clients/cosmos/CosmosSignerPreloader.kt | 19 +- .../clients/ethereum/EvmChainData.kt | 18 ++ .../clients/ethereum/EvmSignClient.kt | 63 ++--- .../clients/ethereum/EvmSignerPreloader.kt | 22 +- .../blockchain/clients/near/NearChainData.kt | 16 ++ .../blockchain/clients/near/NearRpcClient.kt | 4 - .../blockchain/clients/near/NearSignClient.kt | 8 +- .../clients/near/NearSignerPreloader.kt | 14 +- .../clients/polkadot/PolkadotChainData.kt | 26 ++ .../clients/polkadot/PolkadotSignClient.kt | 23 +- .../polkadot/PolkadotSignerPreloaderClient.kt | 28 +- .../clients/solana/SolanaChainData.kt | 26 ++ .../clients/solana/SolanaSignClient.kt | 31 +-- .../clients/solana/models/SolanaChainData.kt | 19 -- .../clients/stellar/StellarChainData.kt | 20 ++ .../clients/stellar/StellarSignClient.kt | 12 +- .../stellar/StellarSignPreloadClient.kt | 21 +- .../blockchain/clients/sui/SuiChainData.kt | 15 ++ .../blockchain/clients/sui/SuiMethod.kt | 1 - .../blockchain/clients/sui/SuiSignClient.kt | 22 +- .../clients/sui/SuiSignerPreloader.kt | 14 +- .../blockchain/clients/ton/TonChainData.kt | 17 ++ .../blockchain/clients/ton/TonSignClient.kt | 22 +- .../clients/ton/TonSignerPreloader.kt | 20 +- .../blockchain/clients/tron/TronChainData.kt | 26 ++ .../blockchain/clients/tron/TronSignClient.kt | 91 +++---- .../clients/tron/TronSignerPreloader.kt | 28 +- .../blockchain/clients/xrp/XrpChainData.kt | 16 ++ .../blockchain/clients/xrp/XrpSignClient.kt | 24 +- .../clients/xrp/XrpSignerPreloader.kt | 16 +- .../blockchain/services/BalancesService.kt | 98 +++---- .../blockchain/services/SignClientProxy.kt | 25 +- .../services/SignerPreloaderProxy.kt | 241 +++++++----------- .../blockchain/services/mapper/Asset.kt | 14 +- .../clients/aptos/TestAptosSignerPreloader.kt | 4 +- .../clients/cosmos/TestCosmosPreload.kt | 30 +-- .../data/repositoreis/di/AssetsModule.kt | 8 +- .../gemwallet/android/model/SignerParams.kt | 21 +- gradle/libs.versions.toml | 10 +- 73 files changed, 836 insertions(+), 785 deletions(-) create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaChainData.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronChainData.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpChainData.kt diff --git a/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt b/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt index a224aceab..a1ccc3730 100644 --- a/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt +++ b/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt @@ -76,18 +76,6 @@ object DataModule { when (it.toChainType()) { ChainType.Ethereum -> EvmBroadcastClient(it, rpcClients.getClient(it)) else -> null -// ChainType.Bitcoin -> BitcoinBroadcastClient(it, rpcClients.getClient(it)) -// ChainType.Cosmos -> CosmosBroadcastClient(it, rpcClients.getClient(it)) -// ChainType.Ton -> TonBroadcastClient(it, rpcClients.getClient(it)) -// ChainType.Tron -> TronBroadcastClient(it, rpcClients.getClient(Chain.Tron)) -// ChainType.Aptos -> AptosBroadcastClient(it, rpcClients.getClient(it)) -// ChainType.Sui -> SuiBroadcastClient(it, rpcClients.getClient(it)) -// ChainType.Xrp -> XrpBroadcastClient(it, rpcClients.getClient(it)) -// ChainType.Near -> NearBroadcastClient(it, rpcClients.getClient(it)) -// ChainType.Algorand -> AlgorandBroadcastClient(it, rpcClients.getClient(it)) -// ChainType.Stellar -> StellarBroadcastClient(it, rpcClients.getClient(it)) -// ChainType.Polkadot -> PolkadotBroadcastClient(it, rpcClients.getClient(it)) -// ChainType.Cardano -> CardanoBroadcastClient(it, rpcClients.getClient(it)) } }, ) @@ -100,19 +88,19 @@ object DataModule { ): SignerPreloaderProxy { val preloaders = Chain.available().mapNotNull { when (it.toChainType()) { - ChainType.Bitcoin -> BitcoinSignerPreloader(it, rpcClients.getClient(it), rpcClients.getClient(it)) + ChainType.Bitcoin -> BitcoinSignerPreloader(it, rpcClients.getClient(it)) ChainType.Ethereum -> EvmSignerPreloader(it, rpcClients.getClient(it), rpcClients.getClient(it)) ChainType.Solana -> null ChainType.Cosmos -> CosmosSignerPreloader(it, rpcClients.getClient(it)) ChainType.Ton -> TonSignerPreloader(it, rpcClients.getClient(it)) - ChainType.Tron -> TronSignerPreloader(it, rpcClients.getClient(it), rpcClients.getClient(it), rpcClients.getClient(it)) - ChainType.Aptos -> AptosSignerPreloader(it, rpcClients.getClient(it), rpcClients.getClient(it)) + ChainType.Tron -> TronSignerPreloader(it, rpcClients.getClient(it)) + ChainType.Aptos -> AptosSignerPreloader(it, rpcClients.getClient(it)) ChainType.Sui -> SuiSignerPreloader(it, rpcClients.getClient(it)) ChainType.Xrp -> XrpSignerPreloader(it, rpcClients.getClient(it)) ChainType.Near -> NearSignerPreloader(it, rpcClients.getClient(it)) ChainType.Algorand -> AlgorandSignPreloadClient(it, rpcClients.getClient(it)) - ChainType.Stellar -> StellarSignPreloadClient(it, rpcClients.getClient(it), rpcClients.getClient(it)) - ChainType.Polkadot -> PolkadotSignerPreloaderClient(it, rpcClients.getClient(it), rpcClients.getClient(it), rpcClients.getClient(it)) + ChainType.Stellar -> StellarSignPreloadClient(it, rpcClients.getClient(it)) + ChainType.Polkadot -> PolkadotSignerPreloaderClient(it, rpcClients.getClient(it)) ChainType.Cardano -> CardanoSignerPreloaderClient(it, rpcClients.getClient(it)) ChainType.HyperCore -> HyperCoreSignerPreloaderClient(it) } diff --git a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt index 0bcdc2660..6f81dc8ed 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt @@ -3,10 +3,11 @@ package com.gemwallet.android.features.confirm.viewmodels import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.gemwallet.android.blockchain.services.BroadcastClientProxy -import com.gemwallet.android.blockchain.services.SignClientProxy import com.gemwallet.android.blockchain.operators.LoadPrivateKeyOperator import com.gemwallet.android.blockchain.operators.PasswordStore +import com.gemwallet.android.blockchain.services.BroadcastClientProxy +import com.gemwallet.android.blockchain.services.SignClientProxy +import com.gemwallet.android.blockchain.services.SignerPreloaderProxy import com.gemwallet.android.cases.transactions.CreateTransaction import com.gemwallet.android.data.repositoreis.assets.AssetsRepository import com.gemwallet.android.data.repositoreis.session.SessionRepository @@ -28,7 +29,6 @@ import com.gemwallet.android.model.Session import com.gemwallet.android.model.SignerParams import com.gemwallet.android.model.format import com.gemwallet.android.serializer.jsonEncoder -import com.gemwallet.android.blockchain.services.SignerPreloaderProxy import com.gemwallet.android.ui.R import com.gemwallet.android.ui.components.CellEntity import com.gemwallet.android.ui.components.InfoSheetEntity @@ -42,7 +42,6 @@ import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.Currency import com.wallet.core.primitives.DelegationValidator import com.wallet.core.primitives.FeePriority -import com.wallet.core.primitives.SwapProvider import com.wallet.core.primitives.TransactionDirection import com.wallet.core.primitives.TransactionState import com.wallet.core.primitives.TransactionSwapMetadata @@ -112,14 +111,7 @@ class ConfirmViewModel @Inject constructor( } val preload = try { - val result = signerPreload.preload(params = request) - when (request) { - is ConfirmParams.SwapParams -> if (result.scanTransaction?.isMalicious != false) { - throw Exception("Transaction payload error") - } - else -> {} - } - result + signerPreload.preload(params = request) } catch (err: Throwable) { state.update { ConfirmState.Error(ConfirmError.PreloadError(err.message ?: "Preload error")) } return@map null @@ -130,8 +122,8 @@ class ConfirmViewModel @Inject constructor( params.input is ConfirmParams.Stake.RewardsParams -> stakeRepository.getRewards(params.input.assetId, params.input.from.address) .map { BigInteger(it.base.rewards) } .fold(BigInteger.ZERO) { acc, value -> acc + value } - params.input.isMax() && params.input.assetId == params.chainData.fee(feePriority).feeAssetId -> - params.input.amount - params.chainData.fee(feePriority).amount + params.input.isMax() && params.input.assetId == params.fee(feePriority).feeAssetId -> + params.input.amount - params.fee(feePriority).amount else -> params.input.amount } state.update { ConfirmState.Ready } @@ -146,7 +138,7 @@ class ConfirmViewModel @Inject constructor( .stateIn(viewModelScope, SharingStarted.Eagerly, null) private val feeAssetInfo = preloadData.filterNotNull().flatMapLatest { signerParams -> - assetsRepository.getAssetInfo(signerParams.chainData.fee().feeAssetId) + assetsRepository.getAssetInfo(signerParams.fee().feeAssetId) } .stateIn(viewModelScope, SharingStarted.Eagerly, null) @@ -193,8 +185,8 @@ class ConfirmViewModel @Inject constructor( .flowOn(Dispatchers.Default) .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) - val feeValue = combine(preloadData, feeAssetInfo, state, feePriority) { signerParams, feeAssetInfo, state, speed -> - val amount = signerParams?.chainData?.fee(speed)?.amount + val feeValue = combine(preloadData, feeAssetInfo, state, feePriority) { signerParams, feeAssetInfo, state, feePriority -> + val amount = signerParams?.fee(feePriority)?.amount if (amount == null || feeAssetInfo == null) { return@combine "" } @@ -204,8 +196,8 @@ class ConfirmViewModel @Inject constructor( .flowOn(Dispatchers.Default) .stateIn(viewModelScope, SharingStarted.Eagerly, "") - val feeUIModel = combine(preloadData, feeAssetInfo, state, feePriority) { signerParams, feeAssetInfo, state, speed -> - val amount = signerParams?.chainData?.fee(speed)?.amount + val feeUIModel = combine(preloadData, feeAssetInfo, state, feePriority) { signerParams, feeAssetInfo, state, priority -> + val amount = signerParams?.fee(priority)?.amount val result = if (amount == null || feeAssetInfo == null) { CellEntity( label = R.string.transfer_network_fee, @@ -256,7 +248,7 @@ class ConfirmViewModel @Inject constructor( .flowOn(Dispatchers.Default) .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) - val allFee = preloadData.filterNotNull().map { it.chainData.allFee() } + val allFee = preloadData.filterNotNull().map { it.allFee() } .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList()) fun init(params: ConfirmParams) { @@ -286,7 +278,7 @@ class ConfirmViewModel @Inject constructor( val account = assetInfo?.owner val feeAssetInfo = feeAssetInfo.value val session = sessionRepository.getSession() - val txSpeed = feePriority.value + val feePriority = this@ConfirmViewModel.feePriority.value try { if (assetInfo == null || account == null || session == null || feeAssetInfo == null) { @@ -294,12 +286,12 @@ class ConfirmViewModel @Inject constructor( } validateBalance( signerParams, - txSpeed, + feePriority, assetInfo, feeAssetInfo, getBalance(assetInfo, signerParams.input), ) - val signs = sign(signerParams, session, assetInfo, txSpeed) + val signs = sign(signerParams, session, assetInfo, feePriority) when (signerParams.input) { is ConfirmParams.TransferParams.Generic -> { when ((signerParams.input as ConfirmParams.TransferParams.Generic).inputType) { @@ -318,7 +310,7 @@ class ConfirmViewModel @Inject constructor( } for (sign in signs) { val txHash = broadcastClientProxy.send(account, sign, signerParams.input.getTxType()) - if (sign != signs.last()) { + if (!sign.contentEquals(signs.last())) { delay(500) } else { addTransaction(txHash) @@ -406,7 +398,6 @@ class ConfirmViewModel @Inject constructor( is ConfirmParams.Stake.UndelegateParams, is ConfirmParams.Stake.WithdrawParams -> CellEntity(label = R.string.stake_validator, data = validator?.name ?: "") is ConfirmParams.SwapParams -> { - val swapProvider = SwapProvider.entries.firstOrNull { it.string == protocolId } CellEntity( label = R.string.common_provider, data = provider, @@ -477,7 +468,7 @@ class ConfirmViewModel @Inject constructor( val assetInfo = assetsInfo.value?.getByAssetId(signerParams?.input?.assetId ?: return) ?: return val session = sessionRepository.getSession() val destinationAddress = signerParams.input.destination()?.address ?: "" - val txSpeed = feePriority.value + val priority = feePriority.value createTransactionsCase.createTransaction( hash = txHash, @@ -486,7 +477,7 @@ class ConfirmViewModel @Inject constructor( owner = assetInfo.owner!!, to = destinationAddress, state = TransactionState.Pending, - fee = signerParams.chainData.fee(txSpeed), + fee = signerParams.fee(priority), amount = signerParams.finalAmount, memo = signerParams.input.memo() ?: "", type = signerParams.input.getTxType(), @@ -509,7 +500,7 @@ class ConfirmViewModel @Inject constructor( assetBalance: BigInteger, ) { val amount = signerParams.finalAmount - val feeAmount = signerParams.chainData.fee(feePriority).amount + val feeAmount = signerParams.fee(feePriority).amount val totalAmount = when (signerParams.input.getTxType()) { TransactionType.Transfer, @@ -532,7 +523,6 @@ class ConfirmViewModel @Inject constructor( throw ConfirmError.InsufficientBalance(label) } if (feeAssetInfo.balance.balance.available.toBigInteger() < feeAmount) { - val label = "${feeAssetInfo.id().chain.asset().name} (${feeAssetInfo.asset.symbol})" throw ConfirmError.InsufficientFee(chain = feeAssetInfo.asset.chain) } } diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt index 9dbb4ccf3..94ef2a348 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt @@ -39,7 +39,7 @@ class TestAlgorandSigner { BigInteger.valueOf(10_000_000), DestinationAddress("GOZOAE6SH6XGGDRBQLZEDRITKMF5OLVJNACVRQBUEGFLBBR5I64A7QN63E"), ), - chainData = AlgorandSignPreloadClient.AlgorandChainData( + chainData = AlgorandChainData( sequence = 46932581, block = "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=", chainId = "mainnet-v1.0", diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSigner.kt index 14e9dce40..7b6d22739 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSigner.kt @@ -44,14 +44,16 @@ class TestAptosSigner { BigInteger.valueOf(10_000_000_000), DestinationAddress("0x82111f2975a0f6080d178236369b7479f6aed1203ef4a23f8205e4b91716b783"), ), - chainData = AptosSignerPreloader.AptosChainData( + chainData = AptosChainData( 8L, - listOf(GasFee( - AssetId(Chain.Aptos), - priority = FeePriority.Normal, - maxGasPrice = BigInteger.valueOf(150L), - limit = BigInteger.valueOf(18L) - )) + listOf( + GasFee( + AssetId(Chain.Aptos), + priority = FeePriority.Normal, + maxGasPrice = BigInteger.valueOf(150L), + limit = BigInteger.valueOf(18L) + ) + ) ), finalAmount = BigInteger.valueOf(10_000_000_000), FeePriority.Normal, @@ -91,14 +93,16 @@ class TestAptosSigner { BigInteger.valueOf(10_000_000_000), DestinationAddress("0x82111f2975a0f6080d178236369b7479f6aed1203ef4a23f8205e4b91716b783"), ), - chainData = AptosSignerPreloader.AptosChainData( + chainData = AptosChainData( 8L, - listOf(GasFee( - AssetId(Chain.Aptos), - priority = FeePriority.Normal, - maxGasPrice = BigInteger.valueOf(150L), - limit = BigInteger.valueOf(18L) - )) + listOf( + GasFee( + AssetId(Chain.Aptos), + priority = FeePriority.Normal, + maxGasPrice = BigInteger.valueOf(150L), + limit = BigInteger.valueOf(18L) + ) + ) ), finalAmount = BigInteger.valueOf(10_000_000_000), FeePriority.Normal, diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt index 0a55fb97b..865902875 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt @@ -49,7 +49,7 @@ class TestBitcoinSigner { BigInteger.valueOf(10_000_000_000), DestinationAddress("D8UBj4EfNfNWNCdnCSgpY48yZDqPdTZXWW"), ), - chainData = BitcoinSignerPreloader.BitcoinChainData( + chainData = BitcoinChainData( listOf( BitcoinUTXO( txid = "9f47e5d5ae3dac0662766f95d0cdda9c242c08d6baac4ce5d82464cf948abd53", diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt index 750f21742..fcfe5ed3a 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt @@ -1,6 +1,5 @@ package com.gemwallet.android.blockchain.clients.cardano -import com.gemwallet.android.blockchain.clients.cardano.CardanoSignerPreloaderClient.CardanoChainData import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosSigner.kt index 1105ba766..e4414bbf9 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosSigner.kt @@ -39,7 +39,7 @@ class TestCosmosSigner { fun testSignNativeTransfer() { val transfer = ConfirmParams.Builder(Chain.Osmosis.asset(), osmoAccount, BigInteger.TEN) .transfer(DestinationAddress("osmo1rcjvzz8wzktqfz8qjf0l9q45kzxvd0z0n7l5cf")) as ConfirmParams.TransferParams.Native - val chainData = CosmosSignerPreloader.CosmosChainData( + val chainData = CosmosChainData( chainId = "osmosis-1", accountNumber = 2913388L, sequence = 10L, @@ -77,7 +77,7 @@ class TestCosmosSigner { fun testSignStake() { val transfer = ConfirmParams.Builder(Chain.Osmosis.asset(), osmoAccount, BigInteger.TEN) .delegate("osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm") - val chainData = CosmosSignerPreloader.CosmosChainData( + val chainData = CosmosChainData( chainId = "osmosis-1", accountNumber = 2913388L, sequence = 10L, @@ -137,7 +137,7 @@ class TestCosmosSigner { ) ) ) - val chainData = CosmosSignerPreloader.CosmosChainData( + val chainData = CosmosChainData( chainId = "osmosis-1", accountNumber = 2913388L, sequence = 10L, @@ -199,7 +199,7 @@ class TestCosmosSigner { ) ) ) - val chainData = CosmosSignerPreloader.CosmosChainData( + val chainData = CosmosChainData( chainId = "osmosis-1", accountNumber = 2913388L, sequence = 10L, @@ -245,7 +245,7 @@ class TestCosmosSigner { "osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", ), ) - val chainData = CosmosSignerPreloader.CosmosChainData( + val chainData = CosmosChainData( chainId = "osmosis-1", accountNumber = 2913388L, sequence = 10L, diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEthSign.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEthSign.kt index 4a15d3ad9..aa6224386 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEthSign.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEthSign.kt @@ -1,8 +1,8 @@ package com.gemwallet.android.blockchain.clients.evm import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.gemwallet.android.blockchain.clients.ethereum.EvmChainData import com.gemwallet.android.blockchain.clients.ethereum.EvmSignClient -import com.gemwallet.android.blockchain.clients.ethereum.EvmSignerPreloader import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset @@ -46,7 +46,7 @@ class TestEthSign { destination = DestinationAddress("0x9b1DB81180c31B1b428572Be105E209b5A6222b7"), from = Account(Chain.Ethereum, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", "") ), - chainData = EvmSignerPreloader.EvmChainData( + chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, fees = listOf( @@ -89,7 +89,7 @@ class TestEthSign { destination = DestinationAddress("0x9b1DB81180c31B1b428572Be105E209b5A6222b7"), from = Account(Chain.Ethereum, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", "") ), - chainData = EvmSignerPreloader.EvmChainData( + chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, fees = listOf( @@ -140,7 +140,7 @@ class TestEthSign { value = "10", from = Account(Chain.Ethereum, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", "") ), - chainData = EvmSignerPreloader.EvmChainData( + chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, fees = listOf( @@ -177,7 +177,7 @@ class TestEthSign { from = Account(Chain.Ethereum, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), validatorId = "0x9941BCe2601fC93478DF9f5F6Cc83F4FFC1D71d8" ), - chainData = EvmSignerPreloader.EvmChainData( + chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, fees = listOf( @@ -220,7 +220,7 @@ class TestEthSign { share = "991645728829172501", balance = "1002901689671695193", ), - chainData = EvmSignerPreloader.EvmChainData( + chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, fees = listOf( @@ -268,7 +268,7 @@ class TestEthSign { provider = "Uniswap v3", contract = "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ), - chainData = EvmSignerPreloader.EvmChainData( + chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, fees = listOf( diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/near/TestNearSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/near/TestNearSigner.kt index 1db53eab5..44b7422e7 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/near/TestNearSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/near/TestNearSigner.kt @@ -1,6 +1,5 @@ package com.gemwallet.android.blockchain.clients.near -import com.gemwallet.android.blockchain.clients.near.NearSignerPreloader.NearChainData import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt index 8f77cd239..f9f88a95d 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt @@ -41,7 +41,7 @@ class TestPolkadotSigner { BigInteger.valueOf(10_000), DestinationAddress(from), ), - chainData = PolkadotSignerPreloaderClient.PolkadotChainData( + chainData = PolkadotChainData( sequence = 0, data = PolkadotSigningData( genesisHash = "0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3", diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt index 517ea254b..d1e5629b7 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt @@ -1,6 +1,6 @@ package com.gemwallet.android.blockchain.clients.solana -import com.gemwallet.android.blockchain.clients.solana.models.SolanaChainData +import com.gemwallet.android.blockchain.clients.solana.SolanaChainData import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/stellar/TestStellarSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/stellar/TestStellarSigner.kt index 3c85574ae..c7f8686e2 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/stellar/TestStellarSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/stellar/TestStellarSigner.kt @@ -1,7 +1,7 @@ package com.gemwallet.android.blockchain.clients.Stellar +import com.gemwallet.android.blockchain.clients.stellar.StellarChainData import com.gemwallet.android.blockchain.clients.stellar.StellarSignClient -import com.gemwallet.android.blockchain.clients.stellar.StellarSignPreloadClient import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset @@ -42,7 +42,7 @@ class TestStellarSigner { BigInteger.valueOf(10_000), DestinationAddress(from), ), - chainData = StellarSignPreloadClient.StellarChainData( + chainData = StellarChainData( sequence = 1, fees = listOf( Fee( diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/sui/TestSuiSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/sui/TestSuiSigner.kt index 11fd6eee3..ce307a8c8 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/sui/TestSuiSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/sui/TestSuiSigner.kt @@ -42,7 +42,7 @@ class TestSuiSigner { BigInteger.valueOf(10_000), DestinationAddress(from), ), - chainData = SuiSignerPreloader.SuiChainData( + chainData = SuiChainData( messageBytes = "AAACAAgAypo7AAAAAAAgLuHnHoVlKe7YHnpDy6mnmWueg/fpbWoPf2pUAO0b" + "wWgCAgABAQAAAQEDAAAAAAEBAC7h5x6FZSnu2B56Q8upp5lrnoP36W1qD39qVADtG8F" + "oAS2bHegcizOpgucdlh7PdMz4cCyV89Xv8+pSQHYdUVM07UIbGgAAAAAgbiAG3TMqRi" + @@ -89,7 +89,7 @@ class TestSuiSigner { BigInteger.valueOf(10_000), DestinationAddress(from), ), - chainData = SuiSignerPreloader.SuiChainData( + chainData = SuiChainData( messageBytes = "AAAEAQA+cu/kqxz/pp3Qmo6eoLJz+so76TaSloB1SmEUVhWCaUYoGhwAAAAAI" + "BtZ+Y3WbB+PQtHrS7YgMDZGLzVxrT20trS/6hpbAEmBAQC01EdV46fEpnMdgod7BT2jJ" + "F0uO3bB4vxKQwUM5D5LgUYoGhwAAAAAIG7IzS1+nt9AlH/Ky7M7uvu/hnOkXUjbo13FT" + diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/ton/TestTonSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/ton/TestTonSigner.kt index d2dab1666..f925d361d 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/ton/TestTonSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/ton/TestTonSigner.kt @@ -42,7 +42,7 @@ class TestTonSigner { BigInteger.valueOf(10_000), DestinationAddress(from), ), - chainData = TonSignerPreloader.TonChainData( + chainData = TonChainData( sequence = 1, fee = Fee( priority = FeePriority.Normal, @@ -81,7 +81,7 @@ class TestTonSigner { BigInteger.valueOf(10_000), DestinationAddress(from), ), - chainData = TonSignerPreloader.TonChainData( + chainData = TonChainData( sequence = 1, jettonAddress = "EQAlgB03OjJKdXrlwZiGJD5snSzPKF2VL5bErJn_cqJANGH9", expireAt = 1000000000, diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronSigner.kt index 96a31d1c6..7b5a046e4 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronSigner.kt @@ -42,13 +42,13 @@ class TestTronSigner { BigInteger.valueOf(10_000), DestinationAddress(from), ), - chainData = TronSignerPreloader.TronChainData( - number = 69501435, - version = 31, + chainData = TronChainData( + blockNumber = 69501435, + blockVersion = 31, txTrieRoot = "fe35cfe51299075978398390271d3f09bdc34e6f43fe8b76eb469314b32ceaff", witnessAddress = "41456798cb4ab28109d8cc643cd7da7bd6069ceae9", parentHash = "00000000042481fa52ef745a31aa66fc2acf8d156b6116bc5b3ede2aebbb894c", - timestamp = 1739156280000, + blockTimestamp = 1739156280000, votes = emptyMap(), fee = Fee( priority = FeePriority.Normal, @@ -96,13 +96,13 @@ class TestTronSigner { BigInteger.valueOf(10_000), DestinationAddress(from), ), - chainData = TronSignerPreloader.TronChainData( - number = 69501435, - version = 31, + chainData = TronChainData( + blockNumber = 69501435, + blockVersion = 31, txTrieRoot = "fe35cfe51299075978398390271d3f09bdc34e6f43fe8b76eb469314b32ceaff", witnessAddress = "41456798cb4ab28109d8cc643cd7da7bd6069ceae9", parentHash = "00000000042481fa52ef745a31aa66fc2acf8d156b6116bc5b3ede2aebbb894c", - timestamp = 1739156280000, + blockTimestamp = 1739156280000, votes = emptyMap(), fee = Fee( priority = FeePriority.Normal, @@ -154,13 +154,13 @@ class TestTronSigner { BigInteger.valueOf(10_000), validatorId = "TCEo1hMAdaJrQmvnGTCcGT2LqrGU4N7Jqf", ), - chainData = TronSignerPreloader.TronChainData( - number = 69501435, - version = 31, + chainData = TronChainData( + blockNumber = 69501435, + blockVersion = 31, txTrieRoot = "fe35cfe51299075978398390271d3f09bdc34e6f43fe8b76eb469314b32ceaff", witnessAddress = "41456798cb4ab28109d8cc643cd7da7bd6069ceae9", parentHash = "00000000042481fa52ef745a31aa66fc2acf8d156b6116bc5b3ede2aebbb894c", - timestamp = 1739156280000, + blockTimestamp = 1739156280000, votes = mapOf( "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH" to 1, "TCEo1hMAdaJrQmvnGTCcGT2LqrGU4N7Jqf" to 1, diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt index a7ffac955..2a34f9365 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt @@ -40,7 +40,7 @@ class TestXrpSigner { BigInteger.valueOf(10_000), DestinationAddress(from), ), - chainData = XrpSignerPreloader.XrpChainData( + chainData = XrpChainData( sequence = 1, blockNumber = 1, fees = listOf( diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClient.kt index 6e596e0c5..3d1634641 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClient.kt @@ -2,6 +2,7 @@ package com.gemwallet.android.blockchain.clients import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.wallet.core.primitives.Chain import com.wallet.core.primitives.FeePriority import java.math.BigInteger @@ -20,7 +21,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.TransferParams.Generic, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -28,7 +29,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -36,7 +37,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.TransferParams.Token, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -44,7 +45,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.SwapParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -52,7 +53,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.TokenApprovalParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -60,7 +61,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.Stake.DelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -68,7 +69,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.Stake.UndelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -76,7 +77,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.Stake.RedelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -84,7 +85,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.Stake.RewardsParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -92,7 +93,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.Stake.WithdrawParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -100,7 +101,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.Activate, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() @@ -108,7 +109,7 @@ interface SignClient : BlockchainClient { params: ConfirmParams.NftParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray, ): List = emptyList() } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandChainData.kt new file mode 100644 index 000000000..da07ecd8d --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandChainData.kt @@ -0,0 +1,18 @@ +package com.gemwallet.android.blockchain.clients.algorand + +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata + +data class AlgorandChainData( + val sequence: ULong, + val block: String, + val chainId: String, +) : ChainSignData + +fun GemTransactionLoadMetadata.Algorand.toChainData(): AlgorandChainData { + return AlgorandChainData( + sequence = sequence, + block = blockHash, + chainId = chainId, + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignClient.kt index a804220dd..c90649380 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignClient.kt @@ -5,9 +5,9 @@ import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import wallet.core.java.AnySigner import wallet.core.jni.Base64 import wallet.core.jni.proto.Algorand @@ -21,10 +21,10 @@ class AlgorandSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = (chainData as? AlgorandSignPreloadClient.AlgorandChainData) + val chainData = (chainData as? AlgorandChainData) ?: throw Exception("bad params") val input = Algorand.SigningInput.newBuilder().apply { this.genesisId = chainData.chainId @@ -34,7 +34,7 @@ class AlgorandSignClient( } this.firstRound = chainData.sequence.toLong() this.lastRound = chainData.sequence.toLong() + 1000 - this.fee = chainData.fee().amount.toLong() + this.fee = fee.amount.toLong() this.privateKey = ByteString.copyFrom(privateKey) this.transfer = Algorand.Transfer.newBuilder().apply { this.toAddress = params.destination().address diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt index 62ad0eb61..a828994ed 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt @@ -2,7 +2,6 @@ package com.gemwallet.android.blockchain.clients.algorand import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.algorand.services.AlgorandService -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams @@ -25,22 +24,13 @@ class AlgorandSignPreloadClient( return SignerParams( input = params, chainData = AlgorandChainData( - sequence = txParams.last_round.toInt(), + sequence = txParams.last_round.toULong(), block = txParams.genesis_hash, chainId = txParams.genesis_id, - fee = fee - ) + ), + fee = listOf(fee) ) } override fun supported(chain: Chain): Boolean = this.chain == chain - - data class AlgorandChainData( - val sequence: Int, - val block: String, - val chainId: String, - val fee: Fee, - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fee - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosChainData.kt new file mode 100644 index 000000000..827ad1636 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosChainData.kt @@ -0,0 +1,14 @@ +package com.gemwallet.android.blockchain.clients.aptos + +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata + +data class AptosChainData( + val sequence: ULong, +) : ChainSignData + +fun GemTransactionLoadMetadata.Aptos.toChainData(): AptosChainData { + return AptosChainData( + sequence = sequence, + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt index eaa58d066..55c9d7017 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt @@ -25,7 +25,7 @@ internal class AptosFeeCalculator( ) { private val maxGasAmount = BigInteger.valueOf(1_500) - suspend fun calculate(params: ConfirmParams, sequence: Long): List = withContext(Dispatchers.IO) { + suspend fun calculate(params: ConfirmParams, sequence: ULong): List = withContext(Dispatchers.IO) { val feePrice = aptosServices.feePrice().getOrThrow() FeePriority.entries.map { @@ -69,7 +69,7 @@ internal class AptosFeeCalculator( private suspend fun simulateTransactions( sender: String, recipient: String, - sequence: Long, + sequence: ULong, value: BigInteger, gasPrice: BigInteger, maxGasAmount: BigInteger diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignClient.kt index 621dea295..ef5f8cd4d 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignClient.kt @@ -4,9 +4,10 @@ import com.gemwallet.android.blockchain.clients.SignClient import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee +import com.gemwallet.android.model.GasFee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import wallet.core.java.AnySigner import wallet.core.jni.proto.Aptos import wallet.core.jni.proto.Aptos.TokenTransferCoinsMessage @@ -23,35 +24,34 @@ class AptosSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - return sign(params, chainData, privateKey, buildTransferMessage(params, finalAmount)) + return sign(params, chainData, fee as GasFee, privateKey, buildTransferMessage(params, finalAmount)) } override suspend fun signTokenTransfer( params: ConfirmParams.TransferParams.Token, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - return sign(params, chainData, privateKey, buildTokenCoinMessage(params, finalAmount)) + return sign(params, chainData, fee as GasFee, privateKey, buildTokenCoinMessage(params, finalAmount)) } override suspend fun signSwap( params: ConfirmParams.SwapParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - return sign(params, chainData, privateKey, params.swapData) + return sign(params, chainData, fee as GasFee, privateKey, params.swapData) } - private fun sign(params: ConfirmParams, chainData: ChainSignData, privateKey: ByteArray, message: Any): List { - val metadata = chainData as AptosSignerPreloader.AptosChainData - val fee = metadata.gasFee() + private fun sign(params: ConfirmParams, chainData: ChainSignData, fee: GasFee, privateKey: ByteArray, message: Any): List { + val metadata = chainData as AptosChainData val signInput = Aptos.SigningInput.newBuilder().apply { this.chainId = 1 when (message) { @@ -63,7 +63,7 @@ class AptosSignClient( this.expirationTimestampSecs = 3664390082 this.gasUnitPrice = fee.maxGasPrice.toLong() this.maxGasAmount = fee.limit.toLong() - this.sequenceNumber = metadata.sequence + this.sequenceNumber = metadata.sequence.toLong() this.sender = params.from.address this.privateKey = ByteString.copyFrom(privateKey) }.build() diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt index 55d594e3b..9d73c9cb3 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt @@ -4,12 +4,9 @@ import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader import com.gemwallet.android.blockchain.clients.aptos.services.AptosServices -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority class AptosSignerPreloader( private val chain: Chain, @@ -33,23 +30,14 @@ class AptosSignerPreloader( private suspend fun preloadTransfer(params: ConfirmParams): SignerParams { val sequence = try { val response = aptosServices.accounts(params.from.address).getOrThrow() - response.sequence_number?.toLong() ?: 0L + response.sequence_number?.toULong() ?: 0UL } catch (_: Throwable) { - 0L + 0UL } val fee = feeCalculator.calculate(params, sequence) - val input = SignerParams(params, AptosChainData(sequence, fee)) + val input = SignerParams(params, AptosChainData(sequence), fee = fee) return input } override fun supported(chain: Chain): Boolean = this.chain == chain - - data class AptosChainData( - val sequence: Long, - val fees: List, - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fees.firstOrNull { it.priority == speed } ?: fees.first() - - override fun allFee(): List = fees - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinChainData.kt new file mode 100644 index 000000000..aa6cf5ef0 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinChainData.kt @@ -0,0 +1,16 @@ +package com.gemwallet.android.blockchain.clients.bitcoin + +import com.gemwallet.android.blockchain.services.mapper.toUtxo +import com.gemwallet.android.model.ChainSignData +import com.wallet.core.primitives.UTXO +import uniffi.gemstone.GemTransactionLoadMetadata + +data class BitcoinChainData( + val utxo: List, +) : ChainSignData + +fun GemTransactionLoadMetadata.Bitcoin.toChainData(): BitcoinChainData { + return BitcoinChainData( + utxo = utxos.toUtxo() + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt index 7ec5557d1..b05ca0304 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt @@ -6,12 +6,12 @@ import com.gemwallet.android.ext.toBitcoinChain import com.gemwallet.android.model.Crypto import com.gemwallet.android.model.Fee import com.gemwallet.android.model.GasFee -import com.wallet.core.blockchain.bitcoin.BitcoinUTXO import com.wallet.core.primitives.Account import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.BitcoinChain import com.wallet.core.primitives.Chain import com.wallet.core.primitives.FeePriority +import com.wallet.core.primitives.UTXO import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -30,7 +30,7 @@ class BitcoinFeeCalculator( private val client: BitcoinRpcClient, ) { suspend fun calculate( - utxos: List, + utxos: List, account: Account, recipient: String, amount: BigInteger, @@ -79,7 +79,7 @@ class BitcoinFeeCalculator( to: String, amount: Long, bytePrice: Long, - utxos: List, + utxos: List, ): BigInteger { val coinType = WCChainTypeProxy().invoke(chain) val total = utxos.map { it.value.toLong() }.fold(0L) { x, y -> x + y } @@ -106,7 +106,7 @@ class BitcoinFeeCalculator( else -> throw IllegalStateException(plan.error.name) } - val selectedUtxos: MutableList = mutableListOf() + val selectedUtxos: MutableList = mutableListOf() for (raw in plan.utxosList) { input.utxoList?.indexOfFirst { it == raw }?.let { selectedUtxos.add(utxos[it]) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignClient.kt index 4cb8a3ef9..c95675836 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignClient.kt @@ -6,12 +6,12 @@ import com.gemwallet.android.math.decodeHex import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.gemwallet.android.model.GasFee import com.google.protobuf.ByteString -import com.wallet.core.blockchain.bitcoin.BitcoinUTXO import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import com.wallet.core.primitives.SwapProvider +import com.wallet.core.primitives.UTXO import wallet.core.java.AnySigner import wallet.core.jni.BitcoinScript import wallet.core.jni.CoinType @@ -29,14 +29,14 @@ class BitcoinSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val signingInput = getSigningInput( params, chainData, finalAmount, - feePriority, + fee, privateKey ) return sign(signingInput.build()) @@ -46,7 +46,7 @@ class BitcoinSignClient( params: ConfirmParams.SwapParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val providers = setOf(SwapProvider.Thorchain, SwapProvider.Chainflip) @@ -61,7 +61,7 @@ class BitcoinSignClient( params, chainData, finalAmount, - feePriority, + fee, privateKey, ) when(params.protocolId) { @@ -85,11 +85,11 @@ class BitcoinSignClient( params: ConfirmParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): Bitcoin.SigningInput.Builder { - val chainData = chainData as BitcoinSignerPreloader.BitcoinChainData - val gasFee = chainData.fee(feePriority) as GasFee + val chainData = chainData as BitcoinChainData + val gasFee = fee as GasFee val coinType = coinType return Bitcoin.SigningInput.newBuilder().apply { @@ -132,10 +132,10 @@ class BitcoinSignClient( override fun supported(chain: Chain): Boolean = this.chain == chain } -fun List.getUtxoTransactions(address: String, coinType: CoinType): List { +fun List.getUtxoTransactions(address: String, coinType: CoinType): List { return map { utxo -> Bitcoin.UnspentTransaction.newBuilder().apply { - val hash = utxo.txid.decodeHex() + val hash = utxo.transaction_id.decodeHex() hash.reverse() this.outPoint = Bitcoin.OutPoint.newBuilder().apply { this.hash = ByteString.copyFrom(hash) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt index cc59060c4..d4d45b78b 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt @@ -5,14 +5,11 @@ import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinRpcClient import com.gemwallet.android.ext.fullAddress import com.gemwallet.android.ext.toBitcoinChain -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams -import com.wallet.core.blockchain.bitcoin.BitcoinUTXO import com.wallet.core.primitives.Account import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority +import com.wallet.core.primitives.UTXO import java.math.BigInteger class BitcoinSignerPreloader( @@ -23,30 +20,33 @@ class BitcoinSignerPreloader( private val feeCalculator = BitcoinFeeCalculator(client) override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - val data = preload(params.from, params.destination().address, params.amount) - return SignerParams(params, data) + val data = preload(params, params.from, params.destination().address, params.amount) + return data } override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - val data = preload(params.from, params.destination().address, params.amount) - return SignerParams(params, data) + val data = preload(params, params.from, params.destination().address, params.amount) + return data } override fun supported(chain: Chain): Boolean = this.chain == chain - private suspend fun preload(fromAccount: Account, destinationAddress: String, amount: BigInteger): BitcoinChainData { + private suspend fun preload(params: ConfirmParams, fromAccount: Account, destinationAddress: String, amount: BigInteger): SignerParams { val address = chain.toBitcoinChain().fullAddress(fromAccount.address) - val utxo = client.getUTXO(address).getOrNull() ?: throw Exception("Can't load UTXO") + val utxo = client.getUTXO(address).getOrNull()?.map { + UTXO( + it.txid, + it.vout, + it.value, + "" + ) + } ?: throw Exception("Can't load UTXO") val fee = feeCalculator.calculate(utxo, fromAccount, destinationAddress, amount) - return BitcoinChainData(utxo, fee) + return SignerParams( + params, + BitcoinChainData(utxo), + fee, + ) } - data class BitcoinChainData( - val utxo: List, - val fee: List, - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fee.firstOrNull { it.priority == speed } ?: fee.first() - - override fun allFee(): List = fee - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt index 8d22fc902..e1de1675c 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt @@ -1,10 +1,7 @@ package com.gemwallet.android.blockchain.clients.bitcoin.services -import com.wallet.core.blockchain.bitcoin.BitcoinBlock import com.wallet.core.blockchain.bitcoin.BitcoinFeeResult -import com.wallet.core.blockchain.bitcoin.BitcoinNodeInfo import com.wallet.core.blockchain.bitcoin.BitcoinUTXO -import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Path diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoChainData.kt new file mode 100644 index 000000000..55f8e369d --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoChainData.kt @@ -0,0 +1,16 @@ +package com.gemwallet.android.blockchain.clients.cardano + +import com.gemwallet.android.blockchain.services.mapper.toUtxo +import com.gemwallet.android.model.ChainSignData +import com.wallet.core.primitives.UTXO +import uniffi.gemstone.GemTransactionLoadMetadata + +data class CardanoChainData( + val utxos: List, +) : ChainSignData + +fun GemTransactionLoadMetadata.Cardano.toChainData(): CardanoChainData { + return CardanoChainData( + utxos = utxos.toUtxo(), + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignClient.kt index 0e5b550b0..4fe8223e0 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignClient.kt @@ -5,9 +5,9 @@ import com.gemwallet.android.math.decodeHex import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import wallet.core.java.AnySigner import wallet.core.jni.CoinType import wallet.core.jni.proto.Cardano @@ -21,10 +21,10 @@ class CardanoSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = (chainData as? CardanoSignerPreloaderClient.CardanoChainData) + val chainData = (chainData as? CardanoChainData) ?: throw IllegalArgumentException() val signingInput = Cardano.SigningInput.newBuilder().apply { this.addPrivateKey(ByteString.copyFrom(privateKey)) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignerPreloaderClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignerPreloaderClient.kt index 6b1011198..a19cf458f 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignerPreloaderClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignerPreloaderClient.kt @@ -4,7 +4,6 @@ import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.cardano.services.CardanoServices import com.gemwallet.android.blockchain.clients.cardano.services.utxos import com.gemwallet.android.math.decodeHex -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams @@ -29,13 +28,15 @@ class CardanoSignerPreloaderClient( return SignerParams( input = params, chainData = CardanoChainData( - fee = Fee( + utxos = utxos, + ), + fee = listOf( + Fee( feeAssetId = AssetId(chain), priority = FeePriority.Normal, amount = fee.toBigInteger(), - ), - utxos = utxos, - ) + ) + ), ) } @@ -67,12 +68,4 @@ class CardanoSignerPreloaderClient( return plan.fee } - data class CardanoChainData( - val fee: Fee, - val utxos: List, - ) : ChainSignData { - - override fun fee(speed: FeePriority): Fee = fee - - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosChainData.kt new file mode 100644 index 000000000..4eb3c3e83 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosChainData.kt @@ -0,0 +1,18 @@ +package com.gemwallet.android.blockchain.clients.cosmos + +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata + +data class CosmosChainData( + val chainId: String, + val accountNumber: ULong, + val sequence: ULong, +) : ChainSignData + +fun GemTransactionLoadMetadata.Cosmos.toChainData(): CosmosChainData { + return CosmosChainData( + chainId = chainId, + accountNumber = accountNumber, + sequence = sequence + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignClient.kt index 48eed6d79..0ac566642 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignClient.kt @@ -4,11 +4,11 @@ import com.gemwallet.android.blockchain.clients.SignClient import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.gemwallet.android.model.GasFee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain import com.wallet.core.primitives.CosmosDenom -import com.wallet.core.primitives.FeePriority import wallet.core.java.AnySigner import wallet.core.jni.AnyAddress import wallet.core.jni.CoinType @@ -30,7 +30,7 @@ class CosmosSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val denom = CosmosDenom.from(chain) @@ -40,7 +40,7 @@ class CosmosSignClient( coin = coin, amount = getAmount(finalAmount, denom = denom) ) - return sign(chainData, message, params.memo() ?: "", privateKey) + return sign(chainData, fee, message, params.memo() ?: "", privateKey) } @@ -48,7 +48,7 @@ class CosmosSignClient( params: ConfirmParams.TransferParams.Token, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val denom = params.asset.id.tokenId!! @@ -59,14 +59,14 @@ class CosmosSignClient( coin = coin, amount = getAmount(finalAmount, denom = denom) ) - return sign(chainData, message, params.memo() ?: "", privateKey) + return sign(chainData, fee, message, params.memo() ?: "", privateKey) } override suspend fun signSwap( params: ConfirmParams.SwapParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val denom = CosmosDenom.from(chain) @@ -80,14 +80,14 @@ class CosmosSignClient( ) } val memo = params.swapData ?: throw IllegalArgumentException("No swap data") - return sign(chainData, message, memo, privateKey) + return sign(chainData, fee, message, memo, privateKey) } override suspend fun signTokenApproval( params: ConfirmParams.TokenApprovalParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { throw IllegalArgumentException() @@ -97,19 +97,19 @@ class CosmosSignClient( params: ConfirmParams.Stake.DelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val denom = CosmosDenom.from(chain) val message = getStakeMessage(params.from.address, params.validatorId, getAmount(finalAmount, denom)) - return sign(chainData, message, "Stake via Gem Wallet", privateKey) + return sign(chainData, fee, message, "Stake via Gem Wallet", privateKey) } override suspend fun signRedelegate( params: ConfirmParams.Stake.RedelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val denom = CosmosDenom.from(chain) @@ -119,37 +119,37 @@ class CosmosSignClient( validatorDstAddress = params.dstValidatorId, amount = getAmount(params.amount, denom), ) - return sign(chainData, message, "Stake via Gem Wallet", privateKey) + return sign(chainData, fee, message, "Stake via Gem Wallet", privateKey) } override suspend fun signRewards( params: ConfirmParams.Stake.RewardsParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val message = getRewardsMessage(params.from.address, params.validatorsId) - return sign(chainData, message, "Stake via Gem Wallet", privateKey) + return sign(chainData, fee, message, "Stake via Gem Wallet", privateKey) } override suspend fun signUndelegate( params: ConfirmParams.Stake.UndelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val denom = CosmosDenom.from(chain) val message = getUnstakeMessage(params.from.address, params.validatorId, getAmount(params.amount, denom)) - return sign(chainData, message, "Stake via Gem Wallet", privateKey) + return sign(chainData, fee, message, "Stake via Gem Wallet", privateKey) } override suspend fun signWithdraw( params: ConfirmParams.Stake.WithdrawParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { throw IllegalArgumentException() @@ -268,12 +268,13 @@ class CosmosSignClient( private fun sign( chainData: ChainSignData, + fee: Fee, messages: List, memo: String, privateKey: ByteArray ): List { - val meta = chainData as CosmosSignerPreloader.CosmosChainData - val fee = meta.fee() as GasFee + val meta = chainData as CosmosChainData + val fee = fee as GasFee val feeAmount = fee.amount val gas = fee.limit.toLong() * messages.size val coin = WCChainTypeProxy().invoke(chain) @@ -295,8 +296,8 @@ class CosmosSignClient( this.mode = Cosmos.BroadcastMode.SYNC this.signingMode = Cosmos.SigningMode.Protobuf this.chainId = meta.chainId - this.accountNumber = meta.accountNumber - this.sequence = meta.sequence + this.accountNumber = meta.accountNumber.toLong() + this.sequence = meta.sequence.toLong() this.fee = cosmosFee this.memo = memo this.privateKey = ByteString.copyFrom(privateKey) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt index 0c4d6094f..dab00f4fa 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt @@ -5,12 +5,9 @@ import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosRpcClient -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.withContext @@ -57,19 +54,11 @@ class CosmosSignerPreloader( input = params, chainData = CosmosChainData( chainId = nodeInfo, - accountNumber = account.account_number.toLong(), - sequence = account.sequence.toLong(), - fee = fee, - ) + accountNumber = account.account_number.toULong(), + sequence = account.sequence.toULong(), + ), + fee = listOf(fee), ) } - data class CosmosChainData( - val chainId: String, - val accountNumber: Long, - val sequence: Long, - val fee: Fee, - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fee - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainData.kt new file mode 100644 index 000000000..6a15c80b7 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainData.kt @@ -0,0 +1,18 @@ +package com.gemwallet.android.blockchain.clients.ethereum + +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata +import java.math.BigInteger + +data class EvmChainData( + val chainId: Int, + val nonce: BigInteger, +) : ChainSignData + + +fun GemTransactionLoadMetadata.Evm.toChainData(): EvmChainData { + return EvmChainData( + chainId = chainId.toInt(), + nonce = BigInteger.valueOf(nonce.toLong()), + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt index 20d6a86ca..7035478a6 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt @@ -6,12 +6,12 @@ import com.gemwallet.android.math.decodeHex import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.gemwallet.android.model.GasFee import com.google.protobuf.ByteString import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.Chain import com.wallet.core.primitives.EVMChain -import com.wallet.core.primitives.FeePriority import com.wallet.core.primitives.NFTType import wallet.core.java.AnySigner import wallet.core.jni.AnyAddress @@ -46,14 +46,14 @@ class EvmSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val meta = chainData as EvmSignerPreloader.EvmChainData + val meta = chainData as EvmChainData val transfer = buildTransfer(finalAmount, finalAmount, params) val input = buildSignInput( assetId = params.assetId, - fee = meta.gasFee(feePriority), + fee = fee as GasFee, chainId = meta.chainId.toBigInteger(), nonce = meta.nonce, destinationAddress = params.destination().address, @@ -67,15 +67,15 @@ class EvmSignClient( params: ConfirmParams.TransferParams.Token, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val meta = chainData as EvmSignerPreloader.EvmChainData + val meta = chainData as EvmChainData val amount = BigInteger.ZERO val transfer = buildTransfer(amount, finalAmount, params) val input = buildSignInput( assetId = params.assetId, - fee = meta.gasFee(feePriority), + fee = fee as GasFee, chainId = meta.chainId.toBigInteger(), nonce = meta.nonce, destinationAddress = params.destination().address, @@ -89,15 +89,15 @@ class EvmSignClient( params: ConfirmParams.TokenApprovalParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val meta = chainData as EvmSignerPreloader.EvmChainData + val meta = chainData as EvmChainData val amount = BigInteger.ZERO val transfer = buildTransfer(amount, finalAmount, params) val input = buildSignInput( assetId = params.assetId, - fee = meta.gasFee(feePriority), + fee = fee as GasFee, chainId = meta.chainId.toBigInteger(), nonce = meta.nonce, destinationAddress = params.destination()?.address ?: "", @@ -111,11 +111,12 @@ class EvmSignClient( params: ConfirmParams.SwapParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { + val fee = fee as GasFee val approvalData = params.approval - val chainData = chainData as EvmSignerPreloader.EvmChainData + val chainData = chainData as EvmChainData val amount = BigInteger(params.value) val approvalSign = if (approvalData != null) { @@ -128,12 +129,12 @@ class EvmSignClient( ), chainData = chainData, finalAmount = BigInteger.ZERO, - feePriority = feePriority, + fee = fee, privateKey = privateKey ) } else emptyList() - val fee = chainData.gasFee(feePriority).let { + val transferFee = fee.let { if (approvalData == null) { it } else { @@ -150,7 +151,7 @@ class EvmSignClient( val transfer = buildTransfer(amount, finalAmount, params) val swapInput = buildSignInput( assetId = AssetId(params.assetId.chain), - fee = fee, + fee = transferFee, chainId = chainData.chainId.toBigInteger(), nonce = chainData.nonce + if (approvalSign.isEmpty()) BigInteger.ZERO else BigInteger.ONE, destinationAddress = params.destination().address, @@ -166,60 +167,60 @@ class EvmSignClient( params: ConfirmParams.Stake.DelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - return stakeSmartchain(params, chainData, finalAmount, feePriority, privateKey) + return stakeSmartchain(params, chainData, finalAmount, fee, privateKey) } override suspend fun signRedelegate( params: ConfirmParams.Stake.RedelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - return stakeSmartchain(params, chainData, finalAmount, feePriority, privateKey) + return stakeSmartchain(params, chainData, finalAmount, fee, privateKey) } override suspend fun signRewards( params: ConfirmParams.Stake.RewardsParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - return stakeSmartchain(params, chainData, finalAmount, feePriority, privateKey) + return stakeSmartchain(params, chainData, finalAmount, fee, privateKey) } override suspend fun signUndelegate( params: ConfirmParams.Stake.UndelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - return stakeSmartchain(params, chainData, finalAmount, feePriority, privateKey) + return stakeSmartchain(params, chainData, finalAmount, fee, privateKey) } override suspend fun signWithdraw( params: ConfirmParams.Stake.WithdrawParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - return stakeSmartchain(params, chainData, finalAmount, feePriority, privateKey) + return stakeSmartchain(params, chainData, finalAmount, fee, privateKey) } override suspend fun signNft( params: ConfirmParams.NftParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val meta = chainData as EvmSignerPreloader.EvmChainData + val meta = chainData as EvmChainData val transfer = when (params.nftAsset.tokenType) { NFTType.ERC721 -> ERC721Transfer.newBuilder().apply { this.from = params.from.address @@ -237,7 +238,7 @@ class EvmSignClient( val input = buildSignInput( assetId = AssetId(chain, params.nftAsset.contractAddress), - fee = meta.gasFee(feePriority), + fee = fee as GasFee, chainId = meta.chainId.toBigInteger(), nonce = meta.nonce, destinationAddress = params.destination.address, @@ -251,14 +252,14 @@ class EvmSignClient( params: ConfirmParams.Stake, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { if (params.assetId.chain != Chain.SmartChain) { throw Exception("Doesn't support") } - val meta = chainData as EvmSignerPreloader.EvmChainData - val fee = meta.gasFee(feePriority) + val meta = chainData as EvmChainData + val fee = fee as GasFee val valueData = when (params) { is ConfirmParams.Stake.DelegateParams -> finalAmount.toByteArray() else -> BigInteger.ZERO.toByteArray() diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignerPreloader.kt index 12c598f04..7b6195322 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignerPreloader.kt @@ -12,16 +12,13 @@ import com.gemwallet.android.blockchain.clients.ethereum.services.getNonce import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy import com.gemwallet.android.ext.getNetworkId import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee import com.gemwallet.android.model.GasFee import com.gemwallet.android.model.SignerParams import com.wallet.core.primitives.Account import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.Chain import com.wallet.core.primitives.EVMChain -import com.wallet.core.primitives.FeePriority import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import wallet.core.jni.AnyAddress @@ -95,7 +92,7 @@ class EvmSignerPreloader( } else { // Add approval fee val chainData = (approvalData.chainData as EvmChainData) - val fees = chainData.fees.map { + val fees = approvalData.allFee().map { it as GasFee }.map { GasFee( feeAssetId = it.feeAssetId, priority = it.priority, @@ -107,7 +104,8 @@ class EvmSignerPreloader( } SignerParams( input = params, - chainData = chainData.copy(fees = fees), + chainData = chainData, + fee = fees ) } return data @@ -136,18 +134,8 @@ class EvmSignerPreloader( nonce = nonce ) - SignerParams(params, EvmChainData(chainId, nonce, fees)) + SignerParams(params, EvmChainData(chainId, nonce), fees) } override fun supported(chain: Chain): Boolean = this.chain == chain - - data class EvmChainData( - val chainId: Int, - val nonce: BigInteger, - val fees: List, - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fees.firstOrNull { it.priority == speed } ?: fees.first() - - override fun allFee(): List = fees - } -} \ No newline at end of file + } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearChainData.kt new file mode 100644 index 000000000..c9420ce58 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearChainData.kt @@ -0,0 +1,16 @@ +package com.gemwallet.android.blockchain.clients.near + +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata + +data class NearChainData( + val block: String, + val sequence: ULong, +) : ChainSignData + +fun GemTransactionLoadMetadata.Near.toChainData(): NearChainData { + return NearChainData( + block = blockHash, + sequence = sequence + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt index fa949c30b..68edcbdab 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt @@ -6,12 +6,8 @@ import com.gemwallet.android.math.decodeHex import com.wallet.core.blockchain.near.NearAccount import com.wallet.core.blockchain.near.NearAccountAccessKey import com.wallet.core.blockchain.near.NearBlock -import com.wallet.core.blockchain.near.NearBroadcastResult -import com.wallet.core.blockchain.near.NearGasPrice -import retrofit2.Response import retrofit2.http.Body import retrofit2.http.POST -import retrofit2.http.Url import wallet.core.jni.Base58 interface NearRpcClient { diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignClient.kt index 120b21394..a487a962f 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignClient.kt @@ -4,9 +4,9 @@ import com.gemwallet.android.blockchain.clients.SignClient import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import wallet.core.java.AnySigner import wallet.core.jni.Base58 import wallet.core.jni.Base64 @@ -21,14 +21,14 @@ class NearSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val metadata = chainData as NearSignerPreloader.NearChainData + val metadata = chainData as NearChainData val input = NEAR.SigningInput.newBuilder().apply { this.signerId = params.from.address - this.nonce = metadata.sequence + this.nonce = metadata.sequence.toLong() this.receiverId = params.destination().address this.addAllActions( listOf( diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignerPreloader.kt index 6aed5bfc6..80bca264b 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignerPreloader.kt @@ -1,7 +1,6 @@ package com.gemwallet.android.blockchain.clients.near import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams @@ -30,9 +29,11 @@ class NearSignerPreloader( SignerParams( input = params, chainData = NearChainData( - sequence = account.nonce + 1L, + sequence = account.nonce.toULong() + 1UL, block = block.header.hash, - fee = Fee( + ), + fee = listOf( + Fee( feeAssetId = AssetId(chain), priority = FeePriority.Normal, amount = fee, @@ -43,11 +44,4 @@ class NearSignerPreloader( override fun supported(chain: Chain): Boolean = this.chain == chain - data class NearChainData( - val block: String, - val sequence: Long, - val fee: Fee, - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fee - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotChainData.kt new file mode 100644 index 000000000..bc4112f4e --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotChainData.kt @@ -0,0 +1,26 @@ +package com.gemwallet.android.blockchain.clients.polkadot + +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata + +data class PolkadotChainData( + val sequence: ULong, + val genesisHash: String, + val blockHash: String, + val blockNumber: ULong, + val specVersion: ULong, + val transactionVersion: ULong, + val period: Long, +) : ChainSignData + +fun GemTransactionLoadMetadata.Polkadot.toChainData(): PolkadotChainData { + return PolkadotChainData( + sequence = sequence, + genesisHash = genesisHash, + blockHash = blockHash, + blockNumber = blockNumber, + specVersion = specVersion, + transactionVersion = transactionVersion, + period = period.toLong(), + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt index ce21fc83d..daa82a83d 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt @@ -7,9 +7,9 @@ import com.gemwallet.android.math.decodeHex import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import wallet.core.java.AnySigner import wallet.core.jni.CoinType import wallet.core.jni.PrivateKey @@ -24,22 +24,21 @@ class PolkadotSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = (chainData as? PolkadotSignerPreloaderClient.PolkadotChainData) ?: throw Exception("incomplete data") - val data = chainData.data + val chainData = (chainData as? PolkadotChainData) ?: throw Exception("incomplete data") val input = Polkadot.SigningInput.newBuilder().apply { - this.genesisHash = ByteString.copyFrom(data.genesisHash.decodeHex()) - this.blockHash = ByteString.copyFrom(data.blockHash.decodeHex()) + this.genesisHash = ByteString.copyFrom(chainData.genesisHash.decodeHex()) + this.blockHash = ByteString.copyFrom(chainData.blockHash.decodeHex()) this.nonce = chainData.sequence.toLong() - this.specVersion = data.specVersion.toInt() + this.specVersion = chainData.specVersion.toInt() this.network = CoinType.POLKADOT.ss58Prefix() - this.transactionVersion = data.transactionVersion.toInt() + this.transactionVersion = chainData.transactionVersion.toInt() this.privateKey = ByteString.copyFrom(privateKey) this.era = Polkadot.Era.newBuilder().apply { - this.blockNumber = data.blockNumber.toLong() - this.period = data.period + this.blockNumber = chainData.blockNumber.toLong() + this.period = chainData.period }.build() this.balanceCall = Polkadot.Balance.newBuilder().apply { transfer = Polkadot.Balance.Transfer.newBuilder().apply { @@ -55,11 +54,11 @@ class PolkadotSignClient( override fun supported(chain: Chain): Boolean = this.chain == chain companion object { - fun transactionPayload(toAdresss: String, value: BigInteger, nonce: Long, data: PolkadotSigningData): String { + fun transactionPayload(toAdresss: String, value: BigInteger, nonce: ULong, data: PolkadotSigningData): String { val input = Polkadot.SigningInput.newBuilder().apply { this.genesisHash = ByteString.copyFrom(data.genesisHash.toByteArray()) this.blockHash = ByteString.copyFrom(data.blockHash.toByteArray()) - this.nonce = nonce + this.nonce = nonce.toLong() this.specVersion = data.specVersion.toInt() this.network = CoinType.POLKADOT.ss58Prefix() this.transactionVersion = data.transactionVersion.toInt() diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt index 12b4234b5..71ea83e98 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt @@ -3,7 +3,6 @@ package com.gemwallet.android.blockchain.clients.polkadot import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.polkadot.models.PolkadotSigningData import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotServices -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams @@ -23,7 +22,7 @@ class PolkadotSignerPreloaderClient( override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams = withContext(Dispatchers.IO) { val getTransactionMaterial = async { client.transactionMaterial().getOrNull() } val getBalance = async { client.balance(params.destination.address).getOrNull() } - val getNonce = async { client.balance(params.from.address).getOrNull()?.nonce?.toLong() } + val getNonce = async { client.balance(params.from.address).getOrNull()?.nonce?.toULong() } val transactionMaterial = getTransactionMaterial.await() ?: throw Exception("Can't load chain data") val balance = getBalance.await() ?: throw Exception("Can't load chain data") @@ -59,27 +58,20 @@ class PolkadotSignerPreloaderClient( SignerParams( input = params, chainData = PolkadotChainData( - sequence = nonce.toInt(), - data = signData, - blockNumber = signData.blockNumber.toInt(), - fee = fee - ) + sequence = nonce, + genesisHash = transactionMaterial.genesisHash, + blockHash = transactionMaterial.at.hash, + blockNumber = transactionMaterial.at.height.toULong(), + specVersion = transactionMaterial.specVersion.toULong(), + transactionVersion = transactionMaterial.txVersion.toULong(), + period = periodLength + ), + fee = listOf(fee) ) } override fun supported(chain: Chain): Boolean = this.chain == chain - data class PolkadotChainData( - val sequence: Int, - val data: PolkadotSigningData, - val blockNumber: Int, - val fee: Fee - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fee - - override fun blockNumber(): String = blockNumber.toString() - } - companion object { const val periodLength: Long = 64 } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaChainData.kt new file mode 100644 index 000000000..862eb00df --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaChainData.kt @@ -0,0 +1,26 @@ +package com.gemwallet.android.blockchain.clients.solana + +import com.gemwallet.android.model.ChainSignData +import com.wallet.core.primitives.SolanaTokenProgramId +import uniffi.gemstone.GemSolanaTokenProgramId +import uniffi.gemstone.GemTransactionLoadMetadata + +data class SolanaChainData( + val blockhash: String, + val senderTokenAddress: String?, + val recipientTokenAddress: String?, + val tokenProgram: SolanaTokenProgramId?, +) : ChainSignData + +fun GemTransactionLoadMetadata.Solana.toChainData(): SolanaChainData { + return SolanaChainData( + blockhash = blockHash, + senderTokenAddress = senderTokenAddress, + recipientTokenAddress = recipientTokenAddress, + tokenProgram = when (tokenProgram) { + GemSolanaTokenProgramId.TOKEN -> SolanaTokenProgramId.Token + GemSolanaTokenProgramId.TOKEN2022 -> SolanaTokenProgramId.Token2022 + null -> null + }, + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt index 864e251a0..c86af2d31 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt @@ -1,17 +1,17 @@ package com.gemwallet.android.blockchain.clients.solana import com.gemwallet.android.blockchain.clients.SignClient -import com.gemwallet.android.blockchain.clients.solana.models.SolanaChainData +import com.gemwallet.android.blockchain.clients.solana.SolanaChainData import com.gemwallet.android.blockchain.operators.GetAsset import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.gemwallet.android.model.GasFee import com.gemwallet.android.serializer.jsonEncoder import com.google.protobuf.ByteString import com.wallet.core.blockchain.solana.SolanaAccountMeta import com.wallet.core.blockchain.solana.SolanaInstruction import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import com.wallet.core.primitives.SolanaTokenProgramId import wallet.core.java.AnySigner import wallet.core.jni.Base58 @@ -47,7 +47,7 @@ class SolanaSignClient( params: ConfirmParams.TransferParams.Generic, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val input = params.memo ?: throw java.lang.IllegalArgumentException("No data") @@ -78,7 +78,7 @@ class SolanaSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val blockhash = (chainData as SolanaChainData).blockhash @@ -93,14 +93,14 @@ class SolanaSignClient( this.recentBlockhash = blockhash this.privateKey = ByteString.copyFrom(privateKey) } - return sign(input = input, fee = chainData.gasFee()) + return sign(input = input, fee = fee as GasFee) } override suspend fun signTokenTransfer( params: ConfirmParams.TransferParams.Token, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val decimals = getAsset.getAsset(params.assetId)?.decimals ?: throw IllegalArgumentException("Asset not found") @@ -147,17 +147,17 @@ class SolanaSignClient( }.build() } } - return sign(input, chainData.gasFee()) + return sign(input, fee as GasFee) } override suspend fun signSwap( params: ConfirmParams.SwapParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val fee = chainData.gasFee(feePriority) + val fee = fee as GasFee val feePrice = fee.minerFee val feeLimit = fee.limit val encodedTx = params.swapData @@ -184,7 +184,7 @@ class SolanaSignClient( params: ConfirmParams.Stake.DelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val instruction = SolanaInstruction( @@ -205,7 +205,7 @@ class SolanaSignClient( }.build() this.privateKey = ByteString.copyFrom(privateKey) } - val encoded = sign(input = signInput, fee = chainData.gasFee()) + val encoded = sign(input = signInput, fee = fee as GasFee) val transaction = SolanaTransaction.insertInstruction(String(encoded.firstOrNull() ?: throw Exception()), -1, data) return signRawTransaction(transaction, privateKey) } @@ -214,7 +214,7 @@ class SolanaSignClient( params: ConfirmParams.Stake.UndelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val recentBlockhash = (chainData as SolanaChainData).blockhash @@ -225,14 +225,14 @@ class SolanaSignClient( }.build() this.privateKey = ByteString.copyFrom(privateKey) } - return sign(input = signInput, fee = chainData.gasFee()) + return sign(input = signInput, fee = fee as GasFee) } override suspend fun signWithdraw( params: ConfirmParams.Stake.WithdrawParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val recentBlockhash = (chainData as SolanaChainData).blockhash @@ -244,7 +244,7 @@ class SolanaSignClient( }.build() this.privateKey = ByteString.copyFrom(privateKey) } - return sign(input = signInput, fee = chainData.gasFee()) + return sign(input = signInput, fee = fee as GasFee) } private fun sign(input: Solana.SigningInput.Builder, fee: GasFee): List { @@ -286,6 +286,7 @@ class SolanaSignClient( override fun supported(chain: Chain): Boolean = this.chain == chain } + //public struct SolanaRawTxDecoder { // let rawData: Data // diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaChainData.kt deleted file mode 100644 index da48d2166..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/models/SolanaChainData.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.gemwallet.android.blockchain.clients.solana.models - -import com.gemwallet.android.model.ChainSignData -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.GasFee -import com.wallet.core.primitives.FeePriority -import com.wallet.core.primitives.SolanaTokenProgramId - -data class SolanaChainData( - val blockhash: String, - val senderTokenAddress: String?, - val recipientTokenAddress: String?, - val tokenProgram: SolanaTokenProgramId?, - val fees: List, -) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fees.firstOrNull { it.priority == speed } ?: fees.first() - - override fun allFee(): List = fees -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarChainData.kt new file mode 100644 index 000000000..f672fb6e4 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarChainData.kt @@ -0,0 +1,20 @@ +package com.gemwallet.android.blockchain.clients.stellar + +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata + +data class StellarChainData( + val sequence: ULong, + val isDestinationAddressExist: Boolean, +) : ChainSignData { + companion object { + const val tokenAccountCreation = "tokenAccountCreation" + } +} + +fun GemTransactionLoadMetadata.Stellar.toChainData(): StellarChainData { + return StellarChainData( + sequence = sequence, + isDestinationAddressExist = isDestinationAddressExist, + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignClient.kt index 4128c3c8c..de233f94c 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignClient.kt @@ -4,9 +4,9 @@ import com.gemwallet.android.blockchain.clients.SignClient import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import wallet.core.java.AnySigner import wallet.core.jni.StellarPassphrase import wallet.core.jni.proto.Stellar @@ -20,22 +20,22 @@ class StellarSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = (chainData as? StellarSignPreloadClient.StellarChainData) + val chainData = (chainData as? StellarChainData) ?: throw Exception("bad params") val input = Stellar.SigningInput.newBuilder().apply { this.passphrase = StellarPassphrase.STELLAR.toString() - this.fee = chainData.fee(feePriority).amount.toInt() - this.sequence = chainData.sequence + this.fee = fee.amount.toInt() + this.sequence = chainData.sequence.toLong() this.account = params.from.address if (!params.memo().isNullOrEmpty()) { this.memoText = Stellar.MemoText.newBuilder().apply { this.text = params.memo()!! }.build() } - if (chainData.fee(feePriority).options.contains(StellarSignPreloadClient.StellarChainData.tokenAccountCreation)) { + if (fee.options.contains(StellarChainData.tokenAccountCreation)) { this.opCreateAccount = Stellar.OperationCreateAccount.newBuilder().apply { this.destination = params.destination().address this.amount = finalAmount.toLong() diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt index 81f43d532..a423a814d 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt @@ -3,12 +3,10 @@ package com.gemwallet.android.blockchain.clients.stellar import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.stellar.services.StellarService import com.gemwallet.android.blockchain.clients.stellar.services.accounts -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.withContext @@ -56,24 +54,13 @@ class StellarSignPreloadClient( SignerParams( input = params, chainData = StellarChainData( - fees = fees, - sequence = account.sequence.toLong() + 1 - ) + sequence = account.sequence.toULong() + 1UL, + isDestinationAddressExist = true, + ), + fee = fees, ) } override fun supported(chain: Chain): Boolean = this.chain == chain - data class StellarChainData( - val fees: List, - val sequence: Long, - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fees.firstOrNull { it.priority == speed } ?: fees.first() - - override fun allFee(): List = fees - - companion object { - const val tokenAccountCreation = "tokenAccountCreation" - } - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiChainData.kt new file mode 100644 index 000000000..3348ec4ae --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiChainData.kt @@ -0,0 +1,15 @@ +package com.gemwallet.android.blockchain.clients.sui + +import com.gemwallet.android.blockchain.clients.aptos.AptosChainData +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata + +data class SuiChainData( + val messageBytes: String, +) : ChainSignData + +fun GemTransactionLoadMetadata.Sui.toChainData(): SuiChainData { + return SuiChainData( + messageBytes = messageBytes, + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt index 91f88b8e8..ce88ed7a7 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt @@ -6,7 +6,6 @@ enum class SuiMethod(val value: String) : JSONRpcMethod { Coins("suix_getCoins"), GasPrice("suix_getReferenceGasPrice"), DryRun("sui_dryRunTransactionBlock"), - Transaction("sui_getTransactionBlock"), GetObject("sui_getObject"), ; diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignClient.kt index 239a74396..426f6f082 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignClient.kt @@ -4,8 +4,8 @@ import com.gemwallet.android.blockchain.clients.SignClient import com.gemwallet.android.math.decodeHex import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import wallet.core.jni.Base64 import wallet.core.jni.Curve import wallet.core.jni.PrivateKey @@ -19,10 +19,10 @@ class SuiSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val metadata = chainData as SuiSignerPreloader.SuiChainData + val metadata = chainData as SuiChainData return signTxDataDigest(metadata.messageBytes, privateKey) } @@ -30,10 +30,10 @@ class SuiSignClient( params: ConfirmParams.TransferParams.Token, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val metadata = chainData as SuiSignerPreloader.SuiChainData + val metadata = chainData as SuiChainData return signTxDataDigest(metadata.messageBytes, privateKey) } @@ -41,10 +41,10 @@ class SuiSignClient( params: ConfirmParams.Stake.DelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val metadata = chainData as SuiSignerPreloader.SuiChainData + val metadata = chainData as SuiChainData return signTxDataDigest(metadata.messageBytes, privateKey) } @@ -52,10 +52,10 @@ class SuiSignClient( params: ConfirmParams.Stake.UndelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val metadata = chainData as SuiSignerPreloader.SuiChainData + val metadata = chainData as SuiChainData return signTxDataDigest(metadata.messageBytes, privateKey) } @@ -63,10 +63,10 @@ class SuiSignClient( params: ConfirmParams.SwapParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val metadata = chainData as SuiSignerPreloader.SuiChainData + val metadata = chainData as SuiChainData return signTxDataDigest(metadata.messageBytes, privateKey) } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignerPreloader.kt index 9c9a21cdb..7ef8ab543 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignerPreloader.kt @@ -6,12 +6,9 @@ import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.withContext @@ -121,8 +118,8 @@ class SuiSignerPreloader( input = params, chainData = SuiChainData( messageBytes = "${Base64.encode(data.txData)}_${data.hash.toHexString()}", - fee = fee, - ) + ), + fee = listOf(fee), ) } @@ -181,13 +178,6 @@ class SuiSignerPreloader( suiEncodeUnstake(input) } - data class SuiChainData( - val messageBytes: String, - val fee: Fee, - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fee - } - private fun com.wallet.core.blockchain.sui.SuiCoin.togemstone() = SuiCoin( coinType = coinType, balance = balance.toULong(), diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonChainData.kt new file mode 100644 index 000000000..36a1f04e0 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonChainData.kt @@ -0,0 +1,17 @@ +package com.gemwallet.android.blockchain.clients.ton + +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata + +data class TonChainData( + val sequence: ULong, + val jettonAddress: String? = null, + val expireAt: Int? = null +) : ChainSignData + +fun GemTransactionLoadMetadata.Ton.toChainData(): TonChainData { + return TonChainData( + sequence = sequence, + jettonAddress = recipientTokenAddress, + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignClient.kt index 14f2e69bd..273d6430e 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignClient.kt @@ -3,9 +3,9 @@ package com.gemwallet.android.blockchain.clients.ton import com.gemwallet.android.blockchain.clients.SignClient import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import wallet.core.java.AnySigner import wallet.core.jni.CoinType import wallet.core.jni.proto.TheOpenNetwork @@ -23,10 +23,10 @@ class TonSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = (chainData as TonSignerPreloader.TonChainData) + val chainData = (chainData as TonChainData) val message = TheOpenNetwork.Transfer.newBuilder().apply { this.dest = params.destination().address this.amount = ByteString.copyFrom(finalAmount.toByteArray()) @@ -39,7 +39,7 @@ class TonSignClient( this.bounceable = false }.build() return sign( - sequence = chainData.sequence, + sequence = chainData.sequence.toInt(), expireAt = chainData.expireAt, message = message, privateKey = privateKey @@ -50,10 +50,10 @@ class TonSignClient( params: ConfirmParams.TransferParams.Token, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val meta = chainData as TonSignerPreloader.TonChainData + val meta = chainData as TonChainData val jettonTransfer = TheOpenNetwork.JettonTransfer.newBuilder().apply { this.jettonAmount = ByteString.copyFrom(finalAmount.toByteArray()) @@ -64,7 +64,7 @@ class TonSignClient( val message = TheOpenNetwork.Transfer.newBuilder().apply { this.dest = meta.jettonAddress - this.amount = ByteString.copyFrom((meta.fee().options[tokenAccountCreationKey] ?: BigInteger.ZERO).toByteArray()) + this.amount = ByteString.copyFrom((fee.options[tokenAccountCreationKey] ?: BigInteger.ZERO).toByteArray()) if (!params.memo().isNullOrEmpty()) { this.comment = params.memo() } @@ -73,7 +73,7 @@ class TonSignClient( this.bounceable = true }.build() return sign( - sequence = chainData.sequence, + sequence = chainData.sequence.toInt(), expireAt = chainData.expireAt, message = message, privateKey = privateKey @@ -84,11 +84,11 @@ class TonSignClient( params: ConfirmParams.SwapParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val data = params.swapData - val chainData = (chainData as TonSignerPreloader.TonChainData) + val chainData = (chainData as TonChainData) val message = TheOpenNetwork.Transfer.newBuilder().apply { this.dest = params.destination().address this.amount = ByteString.copyFrom(params.fromAmount.toByteArray()) @@ -98,7 +98,7 @@ class TonSignClient( this.customPayload = data }.build() return sign( - sequence = chainData.sequence, + sequence = chainData.sequence.toInt(), expireAt = chainData.expireAt, message = message, privateKey = privateKey diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignerPreloader.kt index f25b09937..37e761c62 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignerPreloader.kt @@ -3,12 +3,9 @@ package com.gemwallet.android.blockchain.clients.ton import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.withContext @@ -27,7 +24,8 @@ class TonSignerPreloader( val seqno = rpcClient.walletInfo(params.from.address).getOrNull()?.result?.seqno ?: 0 return SignerParams( input = params, - chainData = TonChainData(seqno, fee) + chainData = TonChainData(seqno.toULong()), + fee = listOf(fee), ) } @@ -42,7 +40,8 @@ class TonSignerPreloader( SignerParams( input = params, - chainData = TonChainData(seqno, fee, jettonAddress) + chainData = TonChainData(seqno.toULong(), jettonAddress), + fee = listOf(fee), ) } @@ -51,18 +50,11 @@ class TonSignerPreloader( val seqno = rpcClient.walletInfo(params.from.address).getOrNull()?.result?.seqno ?: 0 return SignerParams( input = params, - chainData = TonChainData(seqno, fee) + chainData = TonChainData(seqno.toULong()), + fee = listOf(fee), ) } override fun supported(chain: Chain): Boolean = this.chain == chain - data class TonChainData( - val sequence: Int, - val fee: Fee, - val jettonAddress: String? = null, - val expireAt: Int? = null - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fee - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronChainData.kt new file mode 100644 index 000000000..ff6b7f975 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronChainData.kt @@ -0,0 +1,26 @@ +package com.gemwallet.android.blockchain.clients.tron + +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata + +data class TronChainData( + val blockNumber: ULong, + val blockVersion: ULong, + val txTrieRoot: String, + val witnessAddress: String, + val parentHash: String, + val blockTimestamp: ULong, + val votes: Map = emptyMap() +) : ChainSignData + +fun GemTransactionLoadMetadata.Tron.toChainData(): TronChainData { + return TronChainData( + blockNumber = blockNumber, + blockVersion = blockVersion, + blockTimestamp = blockTimestamp, + txTrieRoot = transactionTreeRoot, + witnessAddress = witnessAddress, + parentHash = parentHash, + votes = votes + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignClient.kt index 589f0758b..e96747708 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignClient.kt @@ -7,9 +7,9 @@ import com.gemwallet.android.math.decodeHex import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import wallet.core.java.AnySigner import wallet.core.jni.AnyAddress import wallet.core.jni.Base58 @@ -29,46 +29,47 @@ class TronSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = chainData as TronSignerPreloader.TronChainData + val chainData = chainData as TronChainData val contract = TransferContract.newBuilder().apply { this.amount = finalAmount.toLong() this.ownerAddress = params.from.address this.toAddress = params.destination().address }.build() - return signTransfer(chainData, contract, privateKey) + return signTransfer(chainData, contract, fee, privateKey) } override suspend fun signTokenTransfer( params: ConfirmParams.TransferParams.Token, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = chainData as TronSignerPreloader.TronChainData + val chainData = chainData as TronChainData val contract = TransferTRC20Contract.newBuilder().apply { this.contractAddress = params.assetId.tokenId!! this.ownerAddress = params.from.address this.toAddress = params.destination().address this.amount = ByteString.copyFrom(finalAmount.toByteArray()) }.build() - return signTransfer(chainData, contract, privateKey) + return signTransfer(chainData, contract, fee, privateKey) } private fun signTransfer( - chainData: TronSignerPreloader.TronChainData, + chainData: TronChainData, contract: Any, + fee: Fee, privateKey: ByteArray, ): List { val transaction = Tron.Transaction.newBuilder().apply { this.blockHeader = Tron.BlockHeader.newBuilder().apply { - this.number = chainData.number + this.number = chainData.blockNumber.toLong() this.parentHash = ByteString.copyFrom(chainData.parentHash.decodeHex()) - this.timestamp = chainData.timestamp - this.version = chainData.version.toInt() + this.timestamp = chainData.blockTimestamp.toLong() + this.version = chainData.blockVersion.toInt() this.witnessAddress = ByteString.copyFrom(chainData.witnessAddress.decodeHex()) this.txTrieRoot = ByteString.copyFrom(chainData.txTrieRoot.decodeHex()) }.build() @@ -76,9 +77,9 @@ class TronSignClient( is TransferTRC20Contract -> this.transferTrc20Contract = contract is TransferContract -> this.transfer = contract } - this.expiration = chainData.timestamp + 10 * DateUtils.HOUR_IN_MILLIS - this.timestamp = chainData.timestamp - this.feeLimit = chainData.fee().amount.toLong() + this.expiration = chainData.blockTimestamp.toLong() + 10 * DateUtils.HOUR_IN_MILLIS + this.timestamp = chainData.blockTimestamp.toLong() + this.feeLimit = fee.amount.toLong() } val signInput = Tron.SigningInput.newBuilder().apply { this.transaction = transaction.build() @@ -92,10 +93,10 @@ class TronSignClient( params: ConfirmParams.Stake.DelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = chainData as TronSignerPreloader.TronChainData + val chainData = chainData as TronChainData val freezContract = Tron.FreezeBalanceV2Contract.newBuilder().apply { this.ownerAddress = params.from.address this.frozenBalance = params.amount.toLong() @@ -103,8 +104,8 @@ class TronSignClient( }.build() val voteContract = createVoteContract(chainData, params.from.address) return listOf( - sign(chainData, freezContract, privateKey), - sign(chainData, voteContract, privateKey), + sign(chainData, freezContract, fee, privateKey), + sign(chainData, voteContract, fee, privateKey), ) } @@ -112,10 +113,10 @@ class TronSignClient( params: ConfirmParams.Stake.UndelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = chainData as TronSignerPreloader.TronChainData + val chainData = chainData as TronChainData val votes = chainData.votes return listOfNotNull( Tron.UnfreezeBalanceV2Contract.newBuilder().apply { @@ -126,7 +127,7 @@ class TronSignClient( if (votes.isEmpty()) null else createVoteContract(chainData, params.from.address), ) .map { - sign(chainData, it, privateKey) + sign(chainData, it, fee, privateKey) } } @@ -134,27 +135,27 @@ class TronSignClient( params: ConfirmParams.Stake.RedelegateParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = chainData as TronSignerPreloader.TronChainData + val chainData = chainData as TronChainData val voteContract = createVoteContract(chainData, params.from.address) - return listOf(sign(chainData, voteContract, privateKey)) + return listOf(sign(chainData, voteContract, fee, privateKey)) } override suspend fun signRewards( params: ConfirmParams.Stake.RewardsParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = chainData as TronSignerPreloader.TronChainData + val chainData = chainData as TronChainData val contract = Tron.WithdrawBalanceContract.newBuilder().apply { this.ownerAddress = params.from.address }.build() return listOf( - sign(chainData, contract, privateKey) + sign(chainData, contract, fee, privateKey) ) } @@ -162,15 +163,15 @@ class TronSignClient( params: ConfirmParams.Stake.WithdrawParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = chainData as TronSignerPreloader.TronChainData + val chainData = chainData as TronChainData val contract = Tron.WithdrawExpireUnfreezeContract.newBuilder().apply { this.ownerAddress = params.from.address }.build() return listOf( - sign(chainData, contract, privateKey) + sign(chainData, contract, fee, privateKey) ) } @@ -178,7 +179,7 @@ class TronSignClient( params: ConfirmParams.TokenApprovalParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val spender = Base58.decodeNoCheck(params.data).drop(0).toByteArray() @@ -188,17 +189,17 @@ class TronSignClient( contractAddress = params.contract data = ByteString.copyFrom(callData) } - return listOf(sign(chainData as TronSignerPreloader.TronChainData, approvalContract, privateKey)) + return listOf(sign(chainData as TronChainData, approvalContract, fee, privateKey)) } override suspend fun signSwap( params: ConfirmParams.SwapParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { - val chainData = chainData as TronSignerPreloader.TronChainData + val chainData = chainData as TronChainData val data = params.swapData val callValue = params.value.toLong() val contract = Tron.TriggerSmartContract.newBuilder().apply { @@ -218,27 +219,27 @@ class TronSignClient( ), chainData = chainData, finalAmount = BigInteger.ZERO, - feePriority = feePriority, + fee = fee, privateKey = privateKey ) } ?: emptyList() - return listOf(sign(chainData, contract, privateKey)) + approval + return listOf(sign(chainData, contract, fee, privateKey)) + approval } - private fun createVoteContract(chainData: TronSignerPreloader.TronChainData, owner: String) = Tron.VoteWitnessContract.newBuilder().apply { + private fun createVoteContract(chainData: TronChainData, owner: String) = Tron.VoteWitnessContract.newBuilder().apply { this.ownerAddress = owner this.support = true this.addAllVotes( chainData.votes.map { Tron.VoteWitnessContract.Vote.newBuilder().apply { this.voteAddress = it.key - this.voteCount = it.value + this.voteCount = it.value.toLong() }.build() } ) }.build() - private fun sign(chainData: TronSignerPreloader.TronChainData, contract: Any, privateKey: ByteArray): ByteArray { + private fun sign(chainData: TronChainData, contract: Any, fee: Fee, privateKey: ByteArray): ByteArray { val transaction = Tron.Transaction.newBuilder().apply { when (contract) { is TransferContract -> this.transfer = contract @@ -251,17 +252,17 @@ class TronSignClient( is Tron.TriggerSmartContract -> this.triggerSmartContract = contract } this.blockHeader = Tron.BlockHeader.newBuilder().apply { - this.number = chainData.number + this.number = chainData.blockNumber.toLong() this.parentHash = ByteString.copyFrom(chainData.parentHash.decodeHex()) - this.timestamp = chainData.timestamp - this.version = chainData.version.toInt() + this.timestamp = chainData.blockTimestamp.toLong() + this.version = chainData.blockVersion.toInt() this.witnessAddress = ByteString.copyFrom(chainData.witnessAddress.decodeHex()) this.txTrieRoot = ByteString.copyFrom(chainData.txTrieRoot.decodeHex()) }.build() - this.expiration = chainData.timestamp + 10 * DateUtils.HOUR_IN_MILLIS - this.timestamp = chainData.timestamp - this.feeLimit = chainData.fee().amount.toLong() + this.expiration = chainData.blockTimestamp.toLong() + 10 * DateUtils.HOUR_IN_MILLIS + this.timestamp = chainData.blockTimestamp.toLong() + this.feeLimit = fee.amount.toLong() } val signInput = Tron.SigningInput.newBuilder().apply { this.transaction = transaction.build() diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt index 126467893..8a3e940d3 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt @@ -5,14 +5,12 @@ import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams import com.wallet.core.blockchain.tron.TronAccount import com.wallet.core.blockchain.tron.TronAccountUsage import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.withContext @@ -63,7 +61,7 @@ class TronSignerPreloader( is ConfirmParams.Stake.RewardsParams, is ConfirmParams.Stake.WithdrawParams -> {} } - votes.filter { it.value > 0 } + votes.filter { it.value > 0 }.mapValues { it.value.toULong() } } } @@ -74,7 +72,7 @@ class TronSignerPreloader( private suspend fun preload( params: ConfirmParams, feeCalc: suspend (TronAccount?, TronAccountUsage?) -> Fee, - votes: suspend (TronAccount?) -> Map, + votes: suspend (TronAccount?) -> Map, ): SignerParams = withContext(Dispatchers.IO) { val getAccountUsage = async { client.getAccountUsage(params.from.address) } val getAccount = async { client.getAccount(params.from.address, true) } @@ -89,28 +87,16 @@ class TronSignerPreloader( SignerParams( input = params, chainData = TronChainData( - number = nowBlock.block_header.raw_data.number, - version = nowBlock.block_header.raw_data.version, + blockNumber = nowBlock.block_header.raw_data.number.toULong(), + blockVersion = nowBlock.block_header.raw_data.version.toULong(), txTrieRoot = nowBlock.block_header.raw_data.txTrieRoot, witnessAddress = nowBlock.block_header.raw_data.witness_address, parentHash = nowBlock.block_header.raw_data.parentHash, - timestamp = nowBlock.block_header.raw_data.timestamp, - fee = fee, + blockTimestamp = nowBlock.block_header.raw_data.timestamp.toULong(), votes = votes(account) - ) + ), + fee = listOf(fee), ) } - data class TronChainData( - val number: Long, - val version: Long, - val txTrieRoot: String, - val witnessAddress: String, - val parentHash: String, - val timestamp: Long, - val fee: Fee, - val votes: Map = emptyMap() - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fee - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpChainData.kt new file mode 100644 index 000000000..472961d7f --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpChainData.kt @@ -0,0 +1,16 @@ +package com.gemwallet.android.blockchain.clients.xrp + +import com.gemwallet.android.model.ChainSignData +import uniffi.gemstone.GemTransactionLoadMetadata + +data class XrpChainData( + val sequence: Int, + val blockNumber: Int, +) : ChainSignData + +fun GemTransactionLoadMetadata.Xrp.toChainData(): XrpChainData { + return XrpChainData( + sequence = sequence.toInt(), + blockNumber = sequence.toInt(), + ) +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt index 8f8476cee..2497b439d 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt @@ -6,9 +6,9 @@ import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Crypto +import com.gemwallet.android.model.Fee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import com.wallet.core.primitives.SwapProvider import wallet.core.java.AnySigner import wallet.core.jni.proto.Ripple @@ -23,7 +23,7 @@ class XrpSignClient( params: ConfirmParams.TransferParams.Native, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val operation = OperationPayment.newBuilder().apply { @@ -31,14 +31,14 @@ class XrpSignClient( this.amount = finalAmount.toLong() this.destinationTag = try { params.memo()?.toLong() ?: 0 } catch (_: Throwable) { 0 } }.build() - return sign(params, chainData, feePriority, operation, privateKey) + return sign(params, chainData, fee, operation, privateKey) } override suspend fun signTokenTransfer( params: ConfirmParams.TransferParams.Token, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val operation = OperationPayment.newBuilder().apply { @@ -50,14 +50,14 @@ class XrpSignClient( }.build() this.destinationTag = try { params.memo()?.toLong() ?: 0 } catch (_: Throwable) { 0L } }.build() - return sign(params, chainData, feePriority, operation, privateKey) + return sign(params, chainData, fee, operation, privateKey) } override suspend fun signActivate( params: ConfirmParams.Activate, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { val operation = OperationTrustSet.newBuilder().apply { @@ -67,14 +67,14 @@ class XrpSignClient( this.issuer = params.assetId.tokenId!! }.build() }.build() - return sign(params, chainData, feePriority, operation, privateKey) + return sign(params, chainData, fee, operation, privateKey) } override suspend fun signSwap( params: ConfirmParams.SwapParams, chainData: ChainSignData, finalAmount: BigInteger, - feePriority: FeePriority, + fee: Fee, privateKey: ByteArray ): List { when (params.protocolId) { @@ -93,7 +93,7 @@ class XrpSignClient( ] } """ - return sign(params, chainData, feePriority, json, privateKey) + return sign(params, chainData, fee, json, privateKey) } else -> throw Exception("Provider doesn't support") } @@ -102,13 +102,13 @@ class XrpSignClient( private fun sign( params: ConfirmParams, chainData: ChainSignData, - feePriority: FeePriority, + fee: Fee, operation: Any, privateKey: ByteArray, ): List { - val metadata = chainData as XrpSignerPreloader.XrpChainData + val metadata = chainData as XrpChainData val signInput = Ripple.SigningInput.newBuilder().apply { - this.fee = metadata.fee(feePriority).amount.toLong() + this.fee = fee.amount.toLong() this.sequence = metadata.sequence this.account = params.from.address this.privateKey = ByteString.copyFrom(privateKey) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt index 7607a08fe..e5cb10bb6 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt @@ -5,12 +5,9 @@ import com.gemwallet.android.blockchain.clients.BlockchainError import com.gemwallet.android.blockchain.clients.NativeTransferPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee import com.gemwallet.android.model.SignerParams import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.withContext @@ -51,20 +48,11 @@ class XrpSignerPreloader( XrpChainData( account.account_data?.Sequence ?: 0, account.ledger_current_index, - fee, - ) + ), + fee = fee, ) } override fun supported(chain: Chain): Boolean = this.chain == chain - data class XrpChainData( - val sequence: Int, - val blockNumber: Int, - val fees: List, - ) : ChainSignData { - override fun fee(speed: FeePriority): Fee = fees.firstOrNull { it.priority == speed } ?: fees.first() - - override fun allFee(): List = fees - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt index 1da280212..65a508ca1 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt @@ -20,49 +20,6 @@ class BalancesService( ) { suspend fun getNativeBalances(account: Account): AssetBalance? { - return if (account.chain.toChainType() == ChainType.Ethereum) { - val client = balanceClients.getClient(account.chain) ?: return null - try { - client.getNativeBalance(account.chain, account.address) - } catch (_: Throwable) { - null - } - } else { - callNativeBalanceGateWay(account) - } - } - - suspend fun getDelegationBalances(account: Account): AssetBalance? { - return if (account.chain.toChainType() == ChainType.Ethereum) { - val client = balanceClients.getClient(account.chain) ?: return null - try { - client.getDelegationBalances(account.chain, account.address) - } catch (_: Throwable) { - null - } - } else { - callDelegationBalanceGateWay(account) - } - } - - suspend fun getTokensBalances(account: Account, tokens: List): List { - val tokens = tokens.filter { it.id.type() == AssetSubtype.TOKEN && account.chain == it.id.chain } - .ifEmpty { return emptyList() } - - return if (account.chain.toChainType() == ChainType.Ethereum) { - val client = balanceClients.getClient(account.chain) ?: return emptyList() - val tokensBalances = try { - client.getTokenBalances(account.chain, account.address, tokens) - } catch (_: Throwable) { - emptyList() - } - tokensBalances - } else { - callTokenBalancesGateWay(account, tokens) - } - } - - private suspend fun callNativeBalanceGateWay(account: Account): AssetBalance? { return try { val result = gateway.getBalanceCoin(account.chain.string, account.address) AssetBalance.Companion.create( @@ -78,6 +35,42 @@ class BalancesService( } } + suspend fun getDelegationBalances(account: Account): AssetBalance? { + return try { + val result = gateway.getBalanceStaking(account.chain.string, account.address) + ?: return null + AssetBalance.Companion.create( + asset = account.chain.asset(), + frozen = result.balance.frozen, + locked = result.balance.locked, + staked = result.balance.staked, + pending = result.balance.pending, + rewards = result.balance.rewards, + ) + } catch (_: GatewayException) { + null + } catch (_: Throwable) { + null + } + } + + suspend fun getTokensBalances(account: Account, tokens: List): List { +// val tokens = tokens.filter { it.id.type() == AssetSubtype.TOKEN && account.chain == it.id.chain } +// .ifEmpty { return emptyList() } +// +// return if (account.chain.toChainType() == ChainType.Ethereum) { +// val client = balanceClients.getClient(account.chain) ?: return emptyList() +// val tokensBalances = try { +// client.getTokenBalances(account.chain, account.address, tokens) +// } catch (_: Throwable) { +// emptyList() +// } +// tokensBalances +// } else { + return callTokenBalancesGateWay(account, tokens) +// } + } + private suspend fun callTokenBalancesGateWay(account: Account, tokens: List): List { return try { val ids = tokens.mapNotNull { it.id.tokenId } @@ -100,23 +93,4 @@ class BalancesService( emptyList() } } - - private suspend fun callDelegationBalanceGateWay(account: Account): AssetBalance? { - return try { - val result = gateway.getBalanceStaking(account.chain.string, account.address) - ?: return null - AssetBalance.Companion.create( - asset = account.chain.asset(), - frozen = result.balance.frozen, - locked = result.balance.locked, - staked = result.balance.staked, - pending = result.balance.pending, - rewards = result.balance.rewards, - ) - } catch (_: GatewayException) { - null - } catch (_: Throwable) { - null - } - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt index facaf8024..d3d7f36e4 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt @@ -37,19 +37,20 @@ class SignClientProxy( val chain = params.input.asset.id.chain val client = clients.getClient(chain) ?: throw Exception("Chain isn't support") val input = params.input + val fee = params.fee(feePriority) return when (input) { - is ConfirmParams.Stake.DelegateParams -> client.signDelegate(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.Stake.RedelegateParams -> client.signRedelegate(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.Stake.RewardsParams -> client.signRewards(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.Stake.UndelegateParams -> client.signUndelegate(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.Stake.WithdrawParams -> client.signWithdraw(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.SwapParams -> client.signSwap(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.TokenApprovalParams -> client.signTokenApproval(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.TransferParams.Generic -> client.signGenericTransfer(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.TransferParams.Native -> client.signNativeTransfer(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.TransferParams.Token -> client.signTokenTransfer(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.Activate -> client.signActivate(input, params.chainData, params.finalAmount, feePriority, privateKey) - is ConfirmParams.NftParams -> client.signNft(input, params.chainData, params.finalAmount, feePriority, privateKey) + is ConfirmParams.Stake.DelegateParams -> client.signDelegate(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Stake.RedelegateParams -> client.signRedelegate(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Stake.RewardsParams -> client.signRewards(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Stake.UndelegateParams -> client.signUndelegate(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Stake.WithdrawParams -> client.signWithdraw(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.SwapParams -> client.signSwap(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.TokenApprovalParams -> client.signTokenApproval(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.TransferParams.Generic -> client.signGenericTransfer(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.TransferParams.Native -> client.signNativeTransfer(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.TransferParams.Token -> client.signTokenTransfer(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Activate -> client.signActivate(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.NftParams -> client.signNft(input, params.chainData, params.finalAmount, fee, privateKey) } } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt index fd749311b..4cad84435 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt @@ -8,8 +8,21 @@ import com.gemwallet.android.blockchain.clients.NftTransactionPreloader import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader +import com.gemwallet.android.blockchain.clients.algorand.toChainData +import com.gemwallet.android.blockchain.clients.aptos.toChainData +import com.gemwallet.android.blockchain.clients.bitcoin.toChainData +import com.gemwallet.android.blockchain.clients.cardano.toChainData +import com.gemwallet.android.blockchain.clients.cosmos.toChainData +import com.gemwallet.android.blockchain.clients.ethereum.toChainData import com.gemwallet.android.blockchain.clients.getClient -import com.gemwallet.android.blockchain.clients.solana.models.SolanaChainData +import com.gemwallet.android.blockchain.clients.near.toChainData +import com.gemwallet.android.blockchain.clients.polkadot.toChainData +import com.gemwallet.android.blockchain.clients.solana.toChainData +import com.gemwallet.android.blockchain.clients.stellar.toChainData +import com.gemwallet.android.blockchain.clients.sui.toChainData +import com.gemwallet.android.blockchain.clients.ton.toChainData +import com.gemwallet.android.blockchain.clients.tron.toChainData +import com.gemwallet.android.blockchain.clients.xrp.toChainData import com.gemwallet.android.blockchain.services.mapper.toGem import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.GasFee @@ -17,24 +30,19 @@ import com.gemwallet.android.model.SignerParams import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.Chain import com.wallet.core.primitives.FeePriority -import com.wallet.core.primitives.SolanaTokenProgramId import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.withContext -import uniffi.gemstone.GemGasPriceType import uniffi.gemstone.GemGateway import uniffi.gemstone.GemGatewayEstimateFee -import uniffi.gemstone.GemSolanaTokenProgramId import uniffi.gemstone.GemTransactionInputType import uniffi.gemstone.GemTransactionLoadFee import uniffi.gemstone.GemTransactionLoadInput import uniffi.gemstone.GemTransactionLoadMetadata import uniffi.gemstone.GemTransactionPreloadInput +import uniffi.gemstone.SwapperException class SignerPreloaderProxy( -// private val gemApiClient: GemApiClient, -// private val sessionRepository: SessionRepository, -// private val getDeviceIdCase: GetDeviceIdCase, private val gateway: GemGateway, private val nativeTransferClients: List, private val tokenTransferClients: List, @@ -50,17 +58,6 @@ class SignerPreloaderProxy( NftTransactionPreloader { suspend fun preload(params: ConfirmParams): SignerParams = withContext(Dispatchers.IO) { -// val isValidTransactionJob = async { -// isValidTransaction( -// getScanTransactionPayload( -// params, -// sessionRepository.getSession()?.wallet -// ?: throw IllegalStateException("Session isn't available"), -// getDeviceIdCase.getDeviceId() -// ) -// ) -// } - val preloadJob = async { when (params) { is ConfirmParams.Stake -> preloadStake(params) @@ -74,10 +71,7 @@ class SignerPreloaderProxy( } } -// val isValidTransaction = isValidTransactionJob.await() - val preload = preloadJob.await() -// preload.copy(scanTransaction = isValidTransaction) - preload + preloadJob.await() } override fun supported(chain: Chain): Boolean { @@ -89,36 +83,6 @@ class SignerPreloaderProxy( } override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - return nativeTransferClients.getClient(params.from.chain)?.preloadNativeTransfer(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { - return tokenTransferClients.getClient(params.from.chain)?.preloadTokenTransfer(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams { - return stakeTransactionClients.getClient(params.from.chain)?.preloadStake(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - return swapTransactionClients.getClient(params.from.chain)?.preloadSwap(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadApproval(params: ConfirmParams.TokenApprovalParams): SignerParams { - return approvalTransactionClients.getClient(params.from.chain)?.preloadApproval(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadActivate(params: ConfirmParams.Activate): SignerParams { - return activatePreloaderClients.getClient(params.from.chain)?.preloadActivate(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadGeneric(params: ConfirmParams.TransferParams.Generic): SignerParams { when (params.assetId.chain) { Chain.Solana -> { val gemAsset = params.asset.toGem() @@ -126,7 +90,7 @@ class SignerPreloaderProxy( val chain = assetId.chain val gemChain = assetId.chain.string return try { - val result = gateway.getTransactionPreload( + val metadata = gateway.getTransactionPreload( chain = gemChain, input = GemTransactionPreloadInput( inputType = GemTransactionInputType.Transfer(gemAsset), @@ -140,59 +104,61 @@ class SignerPreloaderProxy( ) val fees = feeRates.map { feeRate -> - val feeRegular = feeRate.gasPriceType as GemGasPriceType.Solana - when (chain) { - Chain.Solana -> { - val metadata = result as? GemTransactionLoadMetadata.Solana - val result = gateway.getTransactionLoad( - chain = gemChain, - input = GemTransactionLoadInput( - inputType = GemTransactionInputType.Transfer(gemAsset), - senderAddress = params.from.address, - destinationAddress = params.destination.address, - value = params.amount.toString(), - gasPrice = feeRegular, - memo = params.memo, - isMaxValue = params.isMax(), - metadata = metadata!!, - ), - provider = object : GemGatewayEstimateFee { - override suspend fun getFee( - chain: uniffi.gemstone.Chain, - input: GemTransactionLoadInput - ): GemTransactionLoadFee? = null - - override suspend fun getFeeData( - chain: uniffi.gemstone.Chain, - input: GemTransactionLoadInput - ): String? = null - } - ) - GasFee( - feeAssetId = AssetId(chain), - priority = FeePriority.entries.firstOrNull { it.string == feeRate.priority } ?: return@map null, - limit = result.fee.gasLimit.toBigInteger(), - maxGasPrice = result.fee.fee.toBigInteger(), - options = result.fee.options.options.mapKeys { it.key.name }.mapValues { it.value.toBigInteger() } - ) + val feeRegular = feeRate.gasPriceType + val result = gateway.getTransactionLoad( + chain = gemChain, + input = GemTransactionLoadInput( + inputType = GemTransactionInputType.Transfer(gemAsset), + senderAddress = params.from.address, + destinationAddress = params.destination.address, + value = params.amount.toString(), + gasPrice = feeRegular, + memo = params.memo, + isMaxValue = params.isMax(), + metadata = metadata, + ), + provider = object : GemGatewayEstimateFee { + override suspend fun getFee( + chain: uniffi.gemstone.Chain, + input: GemTransactionLoadInput + ): GemTransactionLoadFee? = null + + override suspend fun getFeeData( + chain: uniffi.gemstone.Chain, + input: GemTransactionLoadInput + ): String? = null } - else -> null - } + ) + GasFee( + feeAssetId = AssetId(chain), + priority = FeePriority.entries.firstOrNull { it.string == feeRate.priority } ?: return@map null, + limit = result.fee.gasLimit.toBigInteger(), + maxGasPrice = result.fee.fee.toBigInteger(), + options = result.fee.options.options.mapKeys { it.key.name }.mapValues { it.value.toBigInteger() } + ) }.filterNotNull() - val metadata = result as GemTransactionLoadMetadata.Solana + val chainData = when (metadata) { + is GemTransactionLoadMetadata.Algorand -> metadata.toChainData() + is GemTransactionLoadMetadata.Aptos -> metadata.toChainData() + is GemTransactionLoadMetadata.Bitcoin -> metadata.toChainData() + is GemTransactionLoadMetadata.Cardano -> metadata.toChainData() + is GemTransactionLoadMetadata.Cosmos -> metadata.toChainData() + is GemTransactionLoadMetadata.Evm -> metadata.toChainData() + is GemTransactionLoadMetadata.Near -> metadata.toChainData() + is GemTransactionLoadMetadata.Polkadot -> metadata.toChainData() + is GemTransactionLoadMetadata.Solana -> metadata.toChainData() + is GemTransactionLoadMetadata.Stellar -> metadata.toChainData() + is GemTransactionLoadMetadata.Sui -> metadata.toChainData() + is GemTransactionLoadMetadata.Ton -> metadata.toChainData() + is GemTransactionLoadMetadata.Tron -> metadata.toChainData() + is GemTransactionLoadMetadata.Xrp -> metadata.toChainData() + is GemTransactionLoadMetadata.Hyperliquid -> throw SwapperException.NotSupportedChain()// metadata.toChainData() + GemTransactionLoadMetadata.None -> throw SwapperException.NotSupportedChain() + } SignerParams( input = params, - chainData = SolanaChainData( - blockhash = metadata.blockHash, - senderTokenAddress = metadata.senderTokenAddress, - recipientTokenAddress = metadata.recipientTokenAddress, - tokenProgram = when (metadata.tokenProgram) { - GemSolanaTokenProgramId.TOKEN -> SolanaTokenProgramId.Token - GemSolanaTokenProgramId.TOKEN2022 -> SolanaTokenProgramId.Token2022 - null -> null - }, - fees = fees - ) + chainData = chainData, + fee = fees ) } catch (err: Throwable) { throw err @@ -200,6 +166,36 @@ class SignerPreloaderProxy( } else -> {} } + return nativeTransferClients.getClient(params.from.chain)?.preloadNativeTransfer(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { + return tokenTransferClients.getClient(params.from.chain)?.preloadTokenTransfer(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams { + return stakeTransactionClients.getClient(params.from.chain)?.preloadStake(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { + return swapTransactionClients.getClient(params.from.chain)?.preloadSwap(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadApproval(params: ConfirmParams.TokenApprovalParams): SignerParams { + return approvalTransactionClients.getClient(params.from.chain)?.preloadApproval(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadActivate(params: ConfirmParams.Activate): SignerParams { + return activatePreloaderClients.getClient(params.from.chain)?.preloadActivate(params = params) + ?: throw IllegalArgumentException("Chain isn't support") + } + + override suspend fun preloadGeneric(params: ConfirmParams.TransferParams.Generic): SignerParams { return genericPreloaderClients.getClient(params.from.chain)?.preloadGeneric(params = params) ?: throw IllegalArgumentException("Chain isn't support") } @@ -208,45 +204,4 @@ class SignerPreloaderProxy( return nftPreloadClients.getClient(params.from.chain)?.preloadNft(params = params) ?: throw IllegalArgumentException("Chain isn't support") } - -// private suspend fun isValidTransaction(payload: ScanTransactionPayload): ScanTransaction? { -// return try { -// gemApiClient.getScanTransaction(payload).data -// } catch (_: Throwable) { -// null -// } -// } - -// private fun getScanTransactionPayload(params: ConfirmParams, wallet: Wallet, deviceId: String): ScanTransactionPayload { -// val chain = params.assetId.chain -// val origin = ScanAddressTarget( -// chain = chain, -// address = params.from.address, -// ) -// val target = when (params) { -// is ConfirmParams.SwapParams -> ScanAddressTarget( -// params.toAssetId.chain, -// address = wallet.getAccount(params.toAssetId.chain)?.address -// ?: throw IllegalArgumentException("Account isn't available") -// ) -// is ConfirmParams.Stake -> ScanAddressTarget(chain, params.validatorId) -// is ConfirmParams.TokenApprovalParams -> ScanAddressTarget(chain, params.contract) -// is ConfirmParams.TransferParams.Native, -// is ConfirmParams.TransferParams.Generic, -// is ConfirmParams.TransferParams.Token -> ScanAddressTarget( -// chain, -// params.destination().address -// ) -// is ConfirmParams.Activate -> ScanAddressTarget(chain, params.from.address) -// is ConfirmParams.NftParams -> ScanAddressTarget(chain, params.from.address) -// } -// -// return ScanTransactionPayload( -// deviceId = deviceId, -// walletIndex = wallet.index.toUInt(), -// origin = origin, -// target = target, -// type = params.getTxType(), -// ) -// } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt index d56ee41fa..b2eb0e03e 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt @@ -2,9 +2,12 @@ package com.gemwallet.android.blockchain.services.mapper import com.gemwallet.android.ext.toAssetId import com.gemwallet.android.ext.toIdentifier +import com.wallet.core.blockchain.bitcoin.BitcoinUTXO import com.wallet.core.primitives.Asset import com.wallet.core.primitives.AssetType +import com.wallet.core.primitives.UTXO import uniffi.gemstone.GemAsset +import uniffi.gemstone.GemUtxo fun Asset.toGem() = GemAsset( id = id.toIdentifier(), @@ -20,4 +23,13 @@ fun GemAsset.toApp() = Asset( symbol = symbol, decimals = decimals, type = AssetType.entries.firstOrNull { it.string == assetType }!! -) \ No newline at end of file +) + +fun GemUtxo.toUtxo(): UTXO = UTXO( + transactionId, + vout.toInt(), + value, + address +) + +fun List.toUtxo() = map { it.toUtxo() } \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt index 455ce4896..858b5b08f 100644 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt +++ b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt @@ -67,7 +67,7 @@ class TestAptosSignerPreloader { assertEquals(BigInteger.valueOf(9), (result.chainData.fee() as GasFee).limit) assertEquals(AssetId(Chain.Aptos).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(8L, (result.chainData as AptosSignerPreloader.AptosChainData).sequence) + assertEquals(8L, (result.chainData as AptosChainData).sequence) } @Test @@ -106,7 +106,7 @@ class TestAptosSignerPreloader { assertEquals(BigInteger.valueOf(9L), (result.chainData.fee() as GasFee).limit) assertEquals(AssetId(Chain.Aptos).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(0L, (result.chainData as AptosSignerPreloader.AptosChainData).sequence) + assertEquals(0L, (result.chainData as AptosChainData).sequence) } @Test diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt index f8d3f07e7..bbf4fd8a2 100644 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt +++ b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt @@ -75,9 +75,9 @@ class TestCosmosPreload { assertEquals(BigInteger.valueOf(200000L), (result.chainData.fee() as GasFee).limit) assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(10L, (result.chainData as CosmosSignerPreloader.CosmosChainData).sequence) - assertEquals(2913388L, (result.chainData as CosmosSignerPreloader.CosmosChainData).accountNumber) - assertEquals("osmosis-1", (result.chainData as CosmosSignerPreloader.CosmosChainData).chainId) + assertEquals(10L, (result.chainData as CosmosChainData).sequence) + assertEquals(2913388L, (result.chainData as CosmosChainData).accountNumber) + assertEquals("osmosis-1", (result.chainData as CosmosChainData).chainId) } @Test @@ -100,9 +100,9 @@ class TestCosmosPreload { assertEquals(BigInteger.valueOf(1000000L), (result.chainData.fee() as GasFee).limit) assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(10L, (result.chainData as CosmosSignerPreloader.CosmosChainData).sequence) - assertEquals(2913388L, (result.chainData as CosmosSignerPreloader.CosmosChainData).accountNumber) - assertEquals("osmosis-1", (result.chainData as CosmosSignerPreloader.CosmosChainData).chainId) + assertEquals(10L, (result.chainData as CosmosChainData).sequence) + assertEquals(2913388L, (result.chainData as CosmosChainData).accountNumber) + assertEquals("osmosis-1", (result.chainData as CosmosChainData).chainId) } @Test @@ -127,9 +127,9 @@ class TestCosmosPreload { assertEquals(BigInteger.valueOf(1000000L), (result.chainData.fee() as GasFee).limit) assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(10L, (result.chainData as CosmosSignerPreloader.CosmosChainData).sequence) - assertEquals(2913388L, (result.chainData as CosmosSignerPreloader.CosmosChainData).accountNumber) - assertEquals("osmosis-1", (result.chainData as CosmosSignerPreloader.CosmosChainData).chainId) + assertEquals(10L, (result.chainData as CosmosChainData).sequence) + assertEquals(2913388L, (result.chainData as CosmosChainData).accountNumber) + assertEquals("osmosis-1", (result.chainData as CosmosChainData).chainId) } @Test @@ -154,9 +154,9 @@ class TestCosmosPreload { assertEquals(BigInteger.valueOf(1250000L), (result.chainData.fee() as GasFee).limit) assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(10L, (result.chainData as CosmosSignerPreloader.CosmosChainData).sequence) - assertEquals(2913388L, (result.chainData as CosmosSignerPreloader.CosmosChainData).accountNumber) - assertEquals("osmosis-1", (result.chainData as CosmosSignerPreloader.CosmosChainData).chainId) + assertEquals(10L, (result.chainData as CosmosChainData).sequence) + assertEquals(2913388L, (result.chainData as CosmosChainData).accountNumber) + assertEquals("osmosis-1", (result.chainData as CosmosChainData).chainId) } @Test @@ -181,8 +181,8 @@ class TestCosmosPreload { assertEquals(BigInteger.valueOf(900000L), (result.chainData.fee() as GasFee).limit) assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(10L, (result.chainData as CosmosSignerPreloader.CosmosChainData).sequence) - assertEquals(2913388L, (result.chainData as CosmosSignerPreloader.CosmosChainData).accountNumber) - assertEquals("osmosis-1", (result.chainData as CosmosSignerPreloader.CosmosChainData).chainId) + assertEquals(10L, (result.chainData as CosmosChainData).sequence) + assertEquals(2913388L, (result.chainData as CosmosChainData).accountNumber) + assertEquals("osmosis-1", (result.chainData as CosmosChainData).chainId) } } \ No newline at end of file diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt index 63a9e53b2..3c3cdfb0c 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt @@ -2,6 +2,7 @@ package com.gemwallet.android.data.repositoreis.di import com.gemwallet.android.blockchain.RpcClientAdapter import com.gemwallet.android.blockchain.clients.ethereum.EvmBalanceClient +//import com.gemwallet.android.blockchain.clients.ethereum.EvmBalanceClient import com.gemwallet.android.blockchain.clients.ethereum.SmartchainStakeClient import com.gemwallet.android.cases.device.GetDeviceIdCase import com.gemwallet.android.cases.tokens.SearchTokensCase @@ -103,7 +104,12 @@ object AssetsModule { gateway = gateway, balanceClients = Chain.available().mapNotNull { when (it.toChainType()) { - ChainType.Ethereum -> EvmBalanceClient(it, rpcClients.getClient(it), rpcClients.getClient(it), SmartchainStakeClient(it, rpcClients.getClient(it))) + ChainType.Ethereum -> EvmBalanceClient( + it, + rpcClients.getClient(it), + rpcClients.getClient(it), + SmartchainStakeClient(it, rpcClients.getClient(it)) + ) else -> null } } diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/model/SignerParams.kt b/gemcore/src/main/kotlin/com/gemwallet/android/model/SignerParams.kt index 0c6984617..d94122b69 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/model/SignerParams.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/model/SignerParams.kt @@ -1,22 +1,29 @@ package com.gemwallet.android.model import com.wallet.core.primitives.FeePriority -import com.wallet.core.primitives.ScanTransaction import java.math.BigInteger data class SignerParams( val input: ConfirmParams, val chainData: ChainSignData, + private val fee: List, val finalAmount: BigInteger = BigInteger.ZERO, - val scanTransaction: ScanTransaction? = null, -) - -interface ChainSignData { - fun fee(speed: FeePriority = FeePriority.Normal): Fee +) { + fun fee(priority: FeePriority = FeePriority.Normal): Fee { + return fee.firstOrNull { it.priority == priority } ?: fee.first() + } fun gasFee(feePriority: FeePriority = FeePriority.Normal): GasFee = (fee(feePriority) as? GasFee) ?: throw Exception("Fee error: wait gas fee") - fun allFee(): List = emptyList() + fun allFee(): List = fee +} + +interface ChainSignData { +// fun fee(speed: FeePriority = FeePriority.Normal): Fee +// +// fun gasFee(feePriority: FeePriority = FeePriority.Normal): GasFee = (fee(feePriority) as? GasFee) ?: throw Exception("Fee error: wait gas fee") +// +// fun allFee(): List = emptyList() fun blockNumber(): String = "" } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index df53d82a5..4451575d1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ accompanistPermissions = "0.37.3" activityCompose = "1.10.1" browser = "1.9.0" uiautomator = "2.3.0" -walletconnect = "1.4.8" +walletconnect = "1.4.9" barcodeScanning = "17.3.0" biometric = "1.2.0-alpha05" cameraCamera2 = "1.4.2" @@ -13,7 +13,7 @@ core = "3.5.3" coreKtx = "1.17.0" espressoCore = "3.7.0" firebaseMessaging = "25.0.0" -gradle = "8.12.2" +gradle = "8.13.0" gson = "2.13.1" hiltAndroid = "2.57.1" hiltNavigationCompose = "1.2.0" @@ -37,7 +37,7 @@ navigationCompose = "2.9.3" uiTestJunit4 = "1.9.0" testRunner = "1.7.0" ksp = "2.1.21-2.0.1" -android-lib = "8.12.2" +android-lib = "8.13.0" kotlin = "2.2.10" google-services = "4.4.3" material3AdaptiveAndroid = "1.0.0-alpha06" @@ -46,10 +46,10 @@ reorderable = "3.0.0" mockkVersion = "1.14.5" datastore = "1.1.7" wallet-core = "4.3.5" -gemstone = "0.33.1" +gemstone = "0.33.2" ktor = "3.1.3" appcompat = "1.7.1" -material = "1.12.0" +material = "1.13.0" [libraries] gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" } From 6a984bd335e4b122cfdc0eba4de24f40de389b46 Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Wed, 3 Sep 2025 21:21:48 -0700 Subject: [PATCH 05/16] Clean code base --- .../com/gemwallet/android/di/DataModule.kt | 28 +-- .../confirm/viewmodels/ConfirmViewModel.kt | 6 +- .../blockchain/clients/evm/TestEvmBalance.kt | 1 - .../clients/ethereum/EvmBalanceClient.kt | 58 ------ .../clients/ethereum/EvmFeeCalculator.kt | 175 +++++++++--------- .../clients/ethereum/OptimismGasOracle.kt | 124 ++++++------- .../blockchain/services/BalancesService.kt | 23 --- .../services/BroadcastClientProxy.kt | 44 ----- .../blockchain/services/BroadcastService.kt | 30 +++ .../services/NodeStatusClientProxy.kt | 39 ---- .../blockchain/services/NodeStatusService.kt | 26 +++ .../blockchain/services/StakeClientProxy.kt | 81 -------- .../blockchain/services/StakeService.kt | 63 +++++++ .../blockchain/services/TokenService.kt | 19 +- .../services/TransactionStatusService.kt | 38 ++-- .../data/repositoreis/di/AssetsModule.kt | 13 -- .../data/repositoreis/di/StakeModule.kt | 20 +- .../repositoreis/di/TransactionsModule.kt | 11 -- .../repositoreis/stake/StakeRepository.kt | 17 +- .../networks/viewmodels/AddNodeViewModel.kt | 4 +- .../networks/viewmodels/NetworksViewModel.kt | 6 +- gradle/libs.versions.toml | 2 +- 22 files changed, 303 insertions(+), 525 deletions(-) delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmBalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastClientProxy.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusClientProxy.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeClientProxy.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeService.kt diff --git a/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt b/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt index a1ccc3730..0c27324ce 100644 --- a/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt +++ b/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt @@ -18,8 +18,6 @@ import com.gemwallet.android.blockchain.clients.cardano.CardanoSignClient import com.gemwallet.android.blockchain.clients.cardano.CardanoSignerPreloaderClient import com.gemwallet.android.blockchain.clients.cosmos.CosmosSignClient import com.gemwallet.android.blockchain.clients.cosmos.CosmosSignerPreloader -import com.gemwallet.android.blockchain.clients.ethereum.EvmBroadcastClient -import com.gemwallet.android.blockchain.clients.ethereum.EvmNodeStatusClient import com.gemwallet.android.blockchain.clients.ethereum.EvmSignClient import com.gemwallet.android.blockchain.clients.ethereum.EvmSignerPreloader import com.gemwallet.android.blockchain.clients.hyper.HyperCoreSignClient @@ -39,8 +37,8 @@ import com.gemwallet.android.blockchain.clients.tron.TronSignClient import com.gemwallet.android.blockchain.clients.tron.TronSignerPreloader import com.gemwallet.android.blockchain.clients.xrp.XrpSignClient import com.gemwallet.android.blockchain.clients.xrp.XrpSignerPreloader -import com.gemwallet.android.blockchain.services.BroadcastClientProxy -import com.gemwallet.android.blockchain.services.NodeStatusClientProxy +import com.gemwallet.android.blockchain.services.BroadcastService +import com.gemwallet.android.blockchain.services.NodeStatusService import com.gemwallet.android.blockchain.services.SignClientProxy import com.gemwallet.android.blockchain.services.SignerPreloaderProxy import com.gemwallet.android.cases.device.SyncSubscription @@ -69,15 +67,8 @@ object DataModule { @Singleton fun providesBroadcastProxy( gateway: GemGateway, - rpcClients: RpcClientAdapter, - ): BroadcastClientProxy = BroadcastClientProxy( + ): BroadcastService = BroadcastService( gateway = gateway, - clients = Chain.available().mapNotNull { - when (it.toChainType()) { - ChainType.Ethereum -> EvmBroadcastClient(it, rpcClients.getClient(it)) - else -> null - } - }, ) @Provides @@ -148,17 +139,8 @@ object DataModule { @Provides fun provideNodeStatusClient( gateway: GemGateway, - rpcClients: RpcClientAdapter, - ): NodeStatusClientProxy { - return NodeStatusClientProxy( - gateway = gateway, - clients = Chain.available().mapNotNull { - when (it.toChainType()) { - ChainType.Ethereum -> EvmNodeStatusClient(it, rpcClients.getClient(it)) - else -> null - } - } - ) + ): NodeStatusService { + return NodeStatusService(gateway) } @Singleton diff --git a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt index 6f81dc8ed..7cf40f1f4 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt @@ -5,7 +5,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.gemwallet.android.blockchain.operators.LoadPrivateKeyOperator import com.gemwallet.android.blockchain.operators.PasswordStore -import com.gemwallet.android.blockchain.services.BroadcastClientProxy +import com.gemwallet.android.blockchain.services.BroadcastService import com.gemwallet.android.blockchain.services.SignClientProxy import com.gemwallet.android.blockchain.services.SignerPreloaderProxy import com.gemwallet.android.cases.transactions.CreateTransaction @@ -74,7 +74,7 @@ class ConfirmViewModel @Inject constructor( private val passwordStore: PasswordStore, private val loadPrivateKeyOperator: LoadPrivateKeyOperator, private val signClient: SignClientProxy, - private val broadcastClientProxy: BroadcastClientProxy, + private val broadcastService: BroadcastService, private val createTransactionsCase: CreateTransaction, private val stakeRepository: StakeRepository, private val savedStateHandle: SavedStateHandle, @@ -309,7 +309,7 @@ class ConfirmViewModel @Inject constructor( else -> {} } for (sign in signs) { - val txHash = broadcastClientProxy.send(account, sign, signerParams.input.getTxType()) + val txHash = broadcastService.send(account, sign, signerParams.input.getTxType()) if (!sign.contentEquals(signs.last())) { delay(500) } else { diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt index 7cd17da45..e230631aa 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt @@ -1,6 +1,5 @@ package com.gemwallet.android.blockchain.clients.evm -import com.gemwallet.android.blockchain.clients.ethereum.EvmBalanceClient import com.gemwallet.android.blockchain.clients.ethereum.SmartchainStakeClient import com.gemwallet.android.blockchain.clients.ethereum.services.EvmBalancesService import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmBalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmBalanceClient.kt deleted file mode 100644 index b6409ec4d..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmBalanceClient.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmBalancesService -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService -import com.gemwallet.android.blockchain.clients.ethereum.services.batch -import com.gemwallet.android.blockchain.clients.ethereum.services.createCallRequest -import com.gemwallet.android.blockchain.clients.ethereum.services.getBalance -import com.gemwallet.android.ext.asset -import com.gemwallet.android.math.hexToBigInteger -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.Chain - -class EvmBalanceClient( - private val chain: Chain, - private val callService: EvmCallService, - private val balancesService: EvmBalancesService, - private val smartChainStakeClient: SmartchainStakeClient, -) : BalanceClient { - - override suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? { - val availableValue = balancesService.getBalance(address) - .getOrNull()?.result?.value?.toString() - return AssetBalance.create(chain.asset(), available = availableValue ?: return null) - } - - override suspend fun getDelegationBalances(chain: Chain, address: String): AssetBalance? { - return when (chain) { - Chain.SmartChain -> smartChainStakeClient.getBalance(address) - else -> null - } - } - - override suspend fun getTokenBalances(chain: Chain, address: String, tokens: List): List { - if (tokens.isEmpty()) { - return emptyList() - } - val result = mutableListOf() - val tokens = tokens.filter { it.id.tokenId != null } - val requests = tokens.map { token -> - callService.createCallRequest( - to = token.id.tokenId!!, - data = "0x70a08231000000000000000000000000${address.removePrefix("0x")}", - tag = "latest", - ) - } - val response = callService.batch(requests) - response.mapIndexedNotNull { index, data -> - val balance = data.hexToBigInteger() ?: return@mapIndexedNotNull null - val token = tokens[index] - result.add(AssetBalance.create(token, available = balance.toString())) - } - return result - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmFeeCalculator.kt index aacd47360..729eab3c3 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmFeeCalculator.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmFeeCalculator.kt @@ -2,26 +2,16 @@ package com.gemwallet.android.blockchain.clients.ethereum import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService import com.gemwallet.android.blockchain.clients.ethereum.services.EvmFeeService -import com.gemwallet.android.blockchain.clients.ethereum.services.getFeeHistory import com.gemwallet.android.blockchain.clients.ethereum.services.getGasLimit -import com.gemwallet.android.ext.toEVM import com.gemwallet.android.ext.type -import com.gemwallet.android.math.hexToBigInteger import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.GasFee import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.AssetSubtype -import com.wallet.core.primitives.Chain import com.wallet.core.primitives.EVMChain -import com.wallet.core.primitives.FeePriority import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async import kotlinx.coroutines.withContext -import uniffi.gemstone.Config -import uniffi.gemstone.GemEthereumFeeHistory -import uniffi.gemstone.GemFeeCalculator -import uniffi.gemstone.GemPriorityFeeRecord import wallet.core.jni.CoinType import java.math.BigDecimal import java.math.BigInteger @@ -46,55 +36,56 @@ class EvmFeeCalculator( chainId: Int, nonce: BigInteger, ): List = withContext(Dispatchers.IO) { - val getGasLimit = async { getGasLimit(assetId, params.from.address, recipient, outputAmount, payload) } - val getBasePriorityFees = async { getBasePriorityFees(params) } - val gasLimit = getGasLimit.await() - val (baseFee, priorityFees) = getBasePriorityFees.await() - - if (params.assetId.chain.toEVM()?.isOpStack() == true) { - return@withContext priorityFees.mapIndexed { index, priorityFee -> - optimismGasOracle.estimate( - params = params, - chainId = chainId, - nonce = nonce, - gasLimit = gasLimit, - baseFee = baseFee, - priorityFee = priorityFee, - txSpeed = when (index) { - 0 -> FeePriority.Slow - 1 -> FeePriority.Normal - 2 -> FeePriority.Fast - else -> FeePriority.Normal - } - ) - } - } - - priorityFees.map { priorityFee -> - val value = priorityFee.value.toBigInteger() - val maxGasPrice: BigInteger = baseFee.plus(value) - val minerFee: BigInteger = when (params) { - is ConfirmParams.Stake, - is ConfirmParams.SwapParams, - is ConfirmParams.NftParams, - is ConfirmParams.TokenApprovalParams -> value - is ConfirmParams.TransferParams -> if (params.assetId.type() == AssetSubtype.NATIVE && params.isMax()) { - maxGasPrice - } else { - value - } - - is ConfirmParams.Activate -> throw IllegalArgumentException() - } - GasFee( - feeAssetId = AssetId(params.assetId.chain), - priority = FeePriority.entries.firstOrNull { it.string == priorityFee.priority.name.lowercase() } - ?: FeePriority.Normal, - limit = gasLimit, - maxGasPrice = maxGasPrice, - minerFee = minerFee, - ) - } +// val getGasLimit = async { getGasLimit(assetId, params.from.address, recipient, outputAmount, payload) } +// val getBasePriorityFees = async { getBasePriorityFees(params) } +// val gasLimit = getGasLimit.await() +// val (baseFee, priorityFees) = getBasePriorityFees.await() +// +// if (params.assetId.chain.toEVM()?.isOpStack() == true) { +// return@withContext priorityFees.mapIndexed { index, priorityFee -> +// optimismGasOracle.estimate( +// params = params, +// chainId = chainId, +// nonce = nonce, +// gasLimit = gasLimit, +// baseFee = baseFee, +// priorityFee = priorityFee, +// txSpeed = when (index) { +// 0 -> FeePriority.Slow +// 1 -> FeePriority.Normal +// 2 -> FeePriority.Fast +// else -> FeePriority.Normal +// } +// ) +// } +// } +// +// priorityFees.map { priorityFee -> +// val value = priorityFee.value.toBigInteger() +// val maxGasPrice: BigInteger = baseFee.plus(value) +// val minerFee: BigInteger = when (params) { +// is ConfirmParams.Stake, +// is ConfirmParams.SwapParams, +// is ConfirmParams.NftParams, +// is ConfirmParams.TokenApprovalParams -> value +// is ConfirmParams.TransferParams -> if (params.assetId.type() == AssetSubtype.NATIVE && params.isMax()) { +// maxGasPrice +// } else { +// value +// } +// +// is ConfirmParams.Activate -> throw IllegalArgumentException() +// } +// GasFee( +// feeAssetId = AssetId(params.assetId.chain), +// priority = FeePriority.entries.firstOrNull { it.string == priorityFee.priority.name.lowercase() } +// ?: FeePriority.Normal, +// limit = gasLimit, +// maxGasPrice = maxGasPrice, +// minerFee = minerFee, +// ) +// } + emptyList() } private suspend fun getGasLimit( @@ -124,37 +115,37 @@ class EvmFeeCalculator( gasLimit.add(gasLimit.toBigDecimal().multiply(BigDecimal.valueOf(0.5)).toBigInteger()) } } - - internal suspend fun getHistory(chain: Chain, feeService: EvmFeeService): Pair { - val config = Config().getEvmChainConfig(chain.toEVM()?.string ?: throw IllegalArgumentException()) - val rewardsPercentiles = config.rewardsPercentiles - val feeHistory = feeService.getFeeHistory( - listOf(rewardsPercentiles.slow, rewardsPercentiles.normal, rewardsPercentiles.fast) - .map { it.toInt() } - ) ?: throw Exception("Unable to calculate base fee") - val baseFee = feeHistory.baseFeePerGas.mapNotNull { it.hexToBigInteger() }.maxOrNull() - ?: throw Exception("Unable to calculate base fee") - - return Pair( - baseFee, - GemEthereumFeeHistory( - reward = feeHistory.reward, - baseFeePerGas = feeHistory.baseFeePerGas, - gasUsedRatio = feeHistory.gasUsedRatio, - oldestBlock = feeHistory.oldestBlock, - ) - ) - } - - internal suspend fun getBasePriorityFees( - params: ConfirmParams, - ): Pair> { - val history = getHistory(params.asset.id.chain, feeService) - val calculator = GemFeeCalculator() - val priority = calculator.calculateBasePriorityFees( - chain = params.from.chain.string, - history = history.second - ) - return Pair(history.first, priority) - } +// +// internal suspend fun getHistory(chain: Chain, feeService: EvmFeeService): Pair { +// val config = Config().getEvmChainConfig(chain.toEVM()?.string ?: throw IllegalArgumentException()) +// val rewardsPercentiles = config.rewardsPercentiles +// val feeHistory = feeService.getFeeHistory( +// listOf(rewardsPercentiles.slow, rewardsPercentiles.normal, rewardsPercentiles.fast) +// .map { it.toInt() } +// ) ?: throw Exception("Unable to calculate base fee") +// val baseFee = feeHistory.baseFeePerGas.mapNotNull { it.hexToBigInteger() }.maxOrNull() +// ?: throw Exception("Unable to calculate base fee") +// +// return Pair( +// baseFee, +// GemEthereumFeeHistory( +// reward = feeHistory.reward, +// baseFeePerGas = feeHistory.baseFeePerGas, +// gasUsedRatio = feeHistory.gasUsedRatio, +// oldestBlock = feeHistory.oldestBlock, +// ) +// ) +// } +// +// internal suspend fun getBasePriorityFees( +// params: ConfirmParams, +// ): Pair> { +// val history = getHistory(params.asset.id.chain, feeService) +// val calculator = GemFeeCalculator() +// val priority = calculator.calculateBasePriorityFees( +// chain = params.from.chain.string, +// history = history.second +// ) +// return Pair(history.first, priority) +// } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/OptimismGasOracle.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/OptimismGasOracle.kt index a6e2b1834..e364f068f 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/OptimismGasOracle.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/OptimismGasOracle.kt @@ -4,17 +4,11 @@ import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest import com.gemwallet.android.ext.type import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.GasFee import com.google.protobuf.ByteString import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.AssetSubtype import com.wallet.core.primitives.EVMChain -import com.wallet.core.primitives.FeePriority -import com.wallet.core.primitives.TransactionType -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import uniffi.gemstone.GemPriorityFeeRecord import wallet.core.java.AnySigner import wallet.core.jni.CoinType import wallet.core.jni.EthereumAbi @@ -29,65 +23,65 @@ class OptimismGasOracle( private val coinType: CoinType, ) { - suspend fun estimate( - params: ConfirmParams, - chainId: Int, - nonce: BigInteger, - baseFee: BigInteger, - priorityFee: GemPriorityFeeRecord, - gasLimit: BigInteger, - txSpeed: FeePriority, - ): GasFee = withContext(Dispatchers.IO) { - val priorityFeeValue = priorityFee.value.toBigInteger() - val assetId = params.assetId - val feeAssetId = AssetId(assetId.chain) - val gasPrice = baseFee + priorityFeeValue - val minerFee = when (params.getTxType()) { - TransactionType.Transfer -> if (assetId.type() == AssetSubtype.NATIVE && params.isMax()) gasPrice else priorityFeeValue - TransactionType.Swap, TransactionType.TokenApproval -> priorityFeeValue - else -> throw IllegalAccessException("Operation doesn't available") - } - val amount = when (params.getTxType()) { - TransactionType.Transfer -> if (params.isMax()) params.amount - gasLimit * gasPrice else params.amount - TransactionType.TokenApproval, TransactionType.Swap -> params.amount - else -> throw IllegalAccessException("Operation doesn't available") - } - val encoded = encode( - assetId = assetId, - coin = coinType, - amount = amount, - destinationAddress = when (params) { - is ConfirmParams.SwapParams -> params.to - is ConfirmParams.TokenApprovalParams -> params.contract - is ConfirmParams.TransferParams -> params.destination.address - else -> throw IllegalArgumentException() - }, - meta = when (params) { - is ConfirmParams.SwapParams -> params.swapData - is ConfirmParams.TokenApprovalParams -> params.data - else -> params.memo() - }, - chainId = chainId, - nonce = nonce, - gasFee = GasFee( - feeAssetId = feeAssetId, - priority = FeePriority.Normal, - limit = gasLimit, - maxGasPrice = gasPrice, - minerFee = minerFee, - ), - ) - val l2Fee = gasPrice * gasLimit - val l1Fee = getL1Fee(encoded) ?: throw IllegalStateException("Can't get L1 Fee") - GasFee( - feeAssetId = feeAssetId, - priority = txSpeed, - maxGasPrice = gasPrice, - minerFee = minerFee, - limit = gasLimit, - amount = l1Fee + l2Fee, - ) - } +// suspend fun estimate( +// params: ConfirmParams, +// chainId: Int, +// nonce: BigInteger, +// baseFee: BigInteger, +// priorityFee: GemPriorityFeeRecord, +// gasLimit: BigInteger, +// txSpeed: FeePriority, +// ): GasFee = withContext(Dispatchers.IO) { +// val priorityFeeValue = priorityFee.value.toBigInteger() +// val assetId = params.assetId +// val feeAssetId = AssetId(assetId.chain) +// val gasPrice = baseFee + priorityFeeValue +// val minerFee = when (params.getTxType()) { +// TransactionType.Transfer -> if (assetId.type() == AssetSubtype.NATIVE && params.isMax()) gasPrice else priorityFeeValue +// TransactionType.Swap, TransactionType.TokenApproval -> priorityFeeValue +// else -> throw IllegalAccessException("Operation doesn't available") +// } +// val amount = when (params.getTxType()) { +// TransactionType.Transfer -> if (params.isMax()) params.amount - gasLimit * gasPrice else params.amount +// TransactionType.TokenApproval, TransactionType.Swap -> params.amount +// else -> throw IllegalAccessException("Operation doesn't available") +// } +// val encoded = encode( +// assetId = assetId, +// coin = coinType, +// amount = amount, +// destinationAddress = when (params) { +// is ConfirmParams.SwapParams -> params.to +// is ConfirmParams.TokenApprovalParams -> params.contract +// is ConfirmParams.TransferParams -> params.destination.address +// else -> throw IllegalArgumentException() +// }, +// meta = when (params) { +// is ConfirmParams.SwapParams -> params.swapData +// is ConfirmParams.TokenApprovalParams -> params.data +// else -> params.memo() +// }, +// chainId = chainId, +// nonce = nonce, +// gasFee = GasFee( +// feeAssetId = feeAssetId, +// priority = FeePriority.Normal, +// limit = gasLimit, +// maxGasPrice = gasPrice, +// minerFee = minerFee, +// ), +// ) +// val l2Fee = gasPrice * gasLimit +// val l1Fee = getL1Fee(encoded) ?: throw IllegalStateException("Can't get L1 Fee") +// GasFee( +// feeAssetId = feeAssetId, +// priority = txSpeed, +// maxGasPrice = gasPrice, +// minerFee = minerFee, +// limit = gasLimit, +// amount = l1Fee + l2Fee, +// ) +// } private suspend fun getL1Fee(data: ByteArray): BigInteger? { val abiFn = EthereumAbiFunction("getL1Fee").apply { diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt index 65a508ca1..e07d136f0 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt @@ -1,21 +1,15 @@ package com.gemwallet.android.blockchain.services import com.gemwallet.android.blockchain.clients.BalanceClient -import com.gemwallet.android.blockchain.clients.getClient import com.gemwallet.android.ext.asset -import com.gemwallet.android.ext.toChainType import com.gemwallet.android.ext.toIdentifier -import com.gemwallet.android.ext.type import com.gemwallet.android.model.AssetBalance import com.wallet.core.primitives.Account import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetSubtype -import com.wallet.core.primitives.ChainType import uniffi.gemstone.GatewayException import uniffi.gemstone.GemGateway class BalancesService( - private val balanceClients: List, private val gateway: GemGateway, ) { @@ -55,23 +49,6 @@ class BalancesService( } suspend fun getTokensBalances(account: Account, tokens: List): List { -// val tokens = tokens.filter { it.id.type() == AssetSubtype.TOKEN && account.chain == it.id.chain } -// .ifEmpty { return emptyList() } -// -// return if (account.chain.toChainType() == ChainType.Ethereum) { -// val client = balanceClients.getClient(account.chain) ?: return emptyList() -// val tokensBalances = try { -// client.getTokenBalances(account.chain, account.address, tokens) -// } catch (_: Throwable) { -// emptyList() -// } -// tokensBalances -// } else { - return callTokenBalancesGateWay(account, tokens) -// } - } - - private suspend fun callTokenBalancesGateWay(account: Account, tokens: List): List { return try { val ids = tokens.mapNotNull { it.id.tokenId } val result = gateway.getBalanceTokens( diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastClientProxy.kt deleted file mode 100644 index 479ab348c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastClientProxy.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.gemwallet.android.blockchain.services - -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.getClient -import com.gemwallet.android.ext.toChainType -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.ChainType -import com.wallet.core.primitives.TransactionType -import uniffi.gemstone.GemBroadcastOptions -import uniffi.gemstone.GemGateway - -class BroadcastClientProxy( - private val gateway: GemGateway, - private val clients: List, -) : BroadcastClient { - - override suspend fun send( - account: Account, - signedMessage: ByteArray, - type: TransactionType - ): String { - return if (account.chain.toChainType() == ChainType.Ethereum) { - clients.getClient(account.chain)?.send(account, signedMessage, type) - ?: throw Exception("Chain isn't support") - } else { - val hash = gateway.transactionBroadcast( - chain = account.chain.string, - data = String(signedMessage), - options = GemBroadcastOptions( - when (account.chain) { - Chain.Solana -> type == TransactionType.Swap - else -> false - } - ) - ) - hash - } - } - - override fun supported(chain: Chain): Boolean { - return clients.getClient(chain) != null - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastService.kt new file mode 100644 index 000000000..597710916 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BroadcastService.kt @@ -0,0 +1,30 @@ +package com.gemwallet.android.blockchain.services + +import com.wallet.core.primitives.Account +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.TransactionType +import uniffi.gemstone.GemBroadcastOptions +import uniffi.gemstone.GemGateway + +class BroadcastService( + private val gateway: GemGateway, +) { + + suspend fun send( + account: Account, + signedMessage: ByteArray, + type: TransactionType + ): String { + val hash = gateway.transactionBroadcast( + chain = account.chain.string, + data = String(signedMessage), + options = GemBroadcastOptions( + when (account.chain) { + Chain.Solana -> type == TransactionType.Swap + else -> false + } + ) + ) + return hash + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusClientProxy.kt deleted file mode 100644 index b90c38765..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusClientProxy.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.gemwallet.android.blockchain.services - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.clients.getClient -import com.gemwallet.android.ext.toChainType -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.ChainType -import uniffi.gemstone.GemGateway - -class NodeStatusClientProxy( - private val gateway: GemGateway, - private val clients: List, -): NodeStatusClient { - - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? { - return try { - if (chain.toChainType() == ChainType.Ethereum) { - clients.getClient(chain)?.getNodeStatus(chain, url) - } else { - val result = gateway.getNodeStatus(chain.string, url) - NodeStatus( - url = url, - chainId = result.chainId, - blockNumber = result.latestBlockNumber, - inSync = true, - latency = result.latencyMs, - loading = false - ) - } - } catch (_: Throwable) { - null - } - } - - override fun supported(chain: Chain): Boolean { - return clients.getClient(chain) != null - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusService.kt new file mode 100644 index 000000000..987cbd06b --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/NodeStatusService.kt @@ -0,0 +1,26 @@ +package com.gemwallet.android.blockchain.services + +import com.gemwallet.android.model.NodeStatus +import com.wallet.core.primitives.Chain +import uniffi.gemstone.GemGateway + +class NodeStatusService( + private val gateway: GemGateway, +) { + + suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? { + return try { + val result = gateway.getNodeStatus(chain.string, url) + NodeStatus( + url = url, + chainId = result.chainId, + blockNumber = result.latestBlockNumber, + inSync = true, + latency = result.latencyMs, + loading = false + ) + } catch (_: Throwable) { + null + } + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeClientProxy.kt deleted file mode 100644 index 1eec211dd..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeClientProxy.kt +++ /dev/null @@ -1,81 +0,0 @@ -package com.gemwallet.android.blockchain.services - -import com.gemwallet.android.blockchain.clients.StakeClient -import com.gemwallet.android.blockchain.clients.getClient -import com.gemwallet.android.ext.toAssetId -import com.gemwallet.android.ext.toChain -import com.gemwallet.android.ext.toChainType -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.ChainType -import com.wallet.core.primitives.DelegationBase -import com.wallet.core.primitives.DelegationState -import com.wallet.core.primitives.DelegationValidator -import uniffi.gemstone.GemGateway - -class StakeClientProxy( - private val gateway: GemGateway, - private val clients: List -) : StakeClient { - override suspend fun getValidators( - chain: Chain, - apr: Double - ): List { - return try { - if (chain.toChainType() == ChainType.Ethereum) { - clients.getClient(chain)?.getValidators(chain, apr) ?: emptyList() - } else { - val result = gateway.getStakingValidators( - chain = chain.string, - apr, - ) - result.mapNotNull { item -> - DelegationValidator( - chain = item.chain.toChain() ?: return@mapNotNull null, - id = item.id, - name = item.name, - isActive = item.isActive, - commision = item.commission, - apr = item.apr, - ) - } - } - } catch (_: Throwable) { - emptyList() - } - } - - override suspend fun getStakeDelegations( - chain: Chain, - address: String, - apr: Double - ): List { - return try { - if (chain.toChainType() == ChainType.Ethereum) { - clients.getClient(chain)?.getStakeDelegations(chain, address, apr) ?: emptyList() - } else { - val result = gateway.getStakingDelegations( - chain = chain.string, - address, - ) - result.mapNotNull { item -> - DelegationBase( - assetId = item.assetId.toAssetId() ?: return@mapNotNull null, - state = DelegationState.entries.firstOrNull { it.string == item.delegationState } ?: return@mapNotNull null, - balance = item.balance, - rewards = item.rewards, - completionDate = item.completionDate?.toLong(), - delegationId = item.delegationId, - validatorId = item.validatorId, - shares = item.shares, - ) - } - } - } catch (_: Throwable) { - emptyList() - } - } - - override fun supported(chain: Chain): Boolean { - return clients.getClient(chain) != null - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeService.kt new file mode 100644 index 000000000..e6f670ff0 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/StakeService.kt @@ -0,0 +1,63 @@ +package com.gemwallet.android.blockchain.services + +import com.gemwallet.android.ext.toAssetId +import com.gemwallet.android.ext.toChain +import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.DelegationBase +import com.wallet.core.primitives.DelegationState +import com.wallet.core.primitives.DelegationValidator +import uniffi.gemstone.GemGateway + +class StakeService( + private val gateway: GemGateway, +) { + suspend fun getValidators( + chain: Chain, + apr: Double + ): List { + return try { + val result = gateway.getStakingValidators( + chain = chain.string, + apr, + ) + result.mapNotNull { item -> + DelegationValidator( + chain = item.chain.toChain() ?: return@mapNotNull null, + id = item.id, + name = item.name, + isActive = item.isActive, + commision = item.commission, + apr = item.apr, + ) + } + } catch (_: Throwable) { + emptyList() + } + } + + suspend fun getStakeDelegations( + chain: Chain, + address: String, + ): List { + return try { + val result = gateway.getStakingDelegations( + chain = chain.string, + address, + ) + result.mapNotNull { item -> + DelegationBase( + assetId = item.assetId.toAssetId() ?: return@mapNotNull null, + state = DelegationState.entries.firstOrNull { it.string == item.delegationState } ?: return@mapNotNull null, + balance = item.balance, + rewards = item.rewards, + completionDate = item.completionDate?.toLong(), + delegationId = item.delegationId, + validatorId = item.validatorId, + shares = item.shares, + ) + } + } catch (_: Throwable) { + emptyList() + } + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt index e61e7c46a..9c35fe160 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt @@ -2,16 +2,11 @@ package com.gemwallet.android.blockchain.services import com.gemwallet.android.blockchain.clients.GetTokenClient import com.gemwallet.android.blockchain.services.mapper.toApp -import com.gemwallet.android.ext.toAssetId -import com.gemwallet.android.ext.toChainType import com.wallet.core.primitives.Asset import com.wallet.core.primitives.AssetBasic import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.AssetProperties import com.wallet.core.primitives.AssetScore -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.ChainType import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -57,17 +52,11 @@ class TokenService( val tokenId = assetId.tokenId ?: return null val chain = assetId.chain return try { - if (chain.toChainType() == ChainType.Ethereum) { - getTokenClients - .firstOrNull { it.supported(assetId.chain) && it.isTokenQuery(tokenId) } - ?.getTokenData(tokenId) + if (gateway.getIsTokenAddress(chain.string, tokenId)) { + val result = gateway.getTokenData(chain.string, tokenId) + result.toApp() } else { - if (gateway.getIsTokenAddress(chain.string, tokenId)) { - val result = gateway.getTokenData(chain.string, tokenId) - result.toApp() - } else { - null - } + null } } catch (_: Throwable) { null diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt index 802cb549f..a890e9d7e 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt @@ -18,33 +18,27 @@ import java.lang.IllegalArgumentException class TransactionStatusService( private val gateway: GemGateway, - private val stateClients: List, ) { suspend fun getStatus(request: TransactionStateRequest): TransactionChanges? { return try { - if (request.chain.toChainType() == ChainType.Ethereum) { - stateClients.firstOrNull { it.supported(request.chain) } - ?.getStatus(request) - } else { - val result = gateway.getTransactionStatus( - chain = request.chain.string, - GemTransactionStateRequest( - id = request.hash, - senderAddress = request.sender, - createdAt = 0L, /// TODO: Add created at for HyperCore, - blockNumber = request.block.toLongOrDefault(0L) , - ) + val result = gateway.getTransactionStatus( + chain = request.chain.string, + GemTransactionStateRequest( + id = request.hash, + senderAddress = request.sender, + createdAt = 0L, /// TODO: Add created at for HyperCore, + blockNumber = request.block.toLongOrDefault(0L) , ) - val fee = result.changes.firstNotNullOfOrNull { it as? GemTransactionChange.NetworkFee } - ?.v1?.toBigIntegerOrNull() - val hashChanges = result.changes.firstNotNullOfOrNull { it as? GemTransactionChange.HashChange } + ) + val fee = result.changes.firstNotNullOfOrNull { it as? GemTransactionChange.NetworkFee } + ?.v1?.toBigIntegerOrNull() + val hashChanges = result.changes.firstNotNullOfOrNull { it as? GemTransactionChange.HashChange } - return TransactionChanges( - state = TransactionState.entries.firstOrNull { it.string == result.state } ?: throw ServiceUnavailable, - fee = fee, - hashChanges = hashChanges?.let { HashChanges(it.old, it.new) } - ) - } + TransactionChanges( + state = TransactionState.entries.firstOrNull { it.string == result.state } ?: throw ServiceUnavailable, + fee = fee, + hashChanges = hashChanges?.let { HashChanges(it.old, it.new) } + ) } catch (_: Throwable) { throw ServiceUnavailable } diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt index 3c3cdfb0c..07b223063 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt @@ -1,7 +1,6 @@ package com.gemwallet.android.data.repositoreis.di import com.gemwallet.android.blockchain.RpcClientAdapter -import com.gemwallet.android.blockchain.clients.ethereum.EvmBalanceClient //import com.gemwallet.android.blockchain.clients.ethereum.EvmBalanceClient import com.gemwallet.android.blockchain.clients.ethereum.SmartchainStakeClient import com.gemwallet.android.cases.device.GetDeviceIdCase @@ -98,21 +97,9 @@ object AssetsModule { @Provides @Singleton fun provideBalanceRemoteSource( - rpcClients: RpcClientAdapter, gateway: GemGateway, ): BalancesService = BalancesService( gateway = gateway, - balanceClients = Chain.available().mapNotNull { - when (it.toChainType()) { - ChainType.Ethereum -> EvmBalanceClient( - it, - rpcClients.getClient(it), - rpcClients.getClient(it), - SmartchainStakeClient(it, rpcClients.getClient(it)) - ) - else -> null - } - } ) @Provides diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt index a667d1545..33f61441e 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/StakeModule.kt @@ -1,15 +1,10 @@ package com.gemwallet.android.data.repositoreis.di -import com.gemwallet.android.blockchain.RpcClientAdapter -import com.gemwallet.android.blockchain.clients.ethereum.SmartchainStakeClient +import com.gemwallet.android.blockchain.services.StakeService import com.gemwallet.android.data.repositoreis.stake.StakeRepository import com.gemwallet.android.data.service.store.database.StakeDao import com.gemwallet.android.data.services.gemapi.GemApiClient import com.gemwallet.android.data.services.gemapi.GemApiStaticClient -import com.gemwallet.android.ext.available -import com.gemwallet.android.ext.toChainType -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.ChainType import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -25,24 +20,13 @@ object StakeModule { fun provideStakeRepository( stakeDao: StakeDao, gateway: GemGateway, - rpcClients: RpcClientAdapter, gemApiStaticClient: GemApiStaticClient, gemApiClient: GemApiClient, ): StakeRepository = StakeRepository( stakeDao = stakeDao, gemApiStaticClient = gemApiStaticClient, gemApiClient = gemApiClient, - gateway = gateway, - stakeClients = Chain.available().mapNotNull { - when (it.toChainType()) { - ChainType.Ethereum -> when (it) { - Chain.SmartChain -> SmartchainStakeClient(it, rpcClients.getClient(it)) - else -> null - } - else -> null -// ChainType.Tron -> TronStakeClient(it, rpcClients.getClient(it), rpcClients.getClient(it)) - } - } + stakeService = StakeService(gateway), ) } diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt index d261a651e..c6fabc3fd 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TransactionsModule.kt @@ -1,7 +1,6 @@ package com.gemwallet.android.data.repositoreis.di import com.gemwallet.android.blockchain.RpcClientAdapter -import com.gemwallet.android.blockchain.clients.ethereum.EvmTransactionStatusClient import com.gemwallet.android.blockchain.services.TransactionStatusService import com.gemwallet.android.cases.device.GetDeviceIdCase import com.gemwallet.android.cases.transactions.ClearPendingTransactions @@ -18,10 +17,6 @@ import com.gemwallet.android.data.repositoreis.transactions.TransactionsReposito import com.gemwallet.android.data.service.store.database.AssetsDao import com.gemwallet.android.data.service.store.database.TransactionsDao import com.gemwallet.android.data.services.gemapi.GemApiClient -import com.gemwallet.android.ext.available -import com.gemwallet.android.ext.toChainType -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.ChainType import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -45,12 +40,6 @@ object TransactionsModule { assetsDao = assetsDao, transactionStatusService = TransactionStatusService( gateway = gateway, - stateClients = Chain.available().mapNotNull { - when (it.toChainType()) { - ChainType.Ethereum -> EvmTransactionStatusClient(it, rpcClients.getClient(it)) - else -> null - } - } ), ) diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/stake/StakeRepository.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/stake/StakeRepository.kt index 98822e128..70a481575 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/stake/StakeRepository.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/stake/StakeRepository.kt @@ -1,7 +1,6 @@ package com.gemwallet.android.data.repositoreis.stake -import com.gemwallet.android.blockchain.clients.StakeClient -import com.gemwallet.android.blockchain.services.StakeClientProxy +import com.gemwallet.android.blockchain.services.StakeService import com.gemwallet.android.data.service.store.database.StakeDao import com.gemwallet.android.data.service.store.database.entities.toModel import com.gemwallet.android.data.service.store.database.entities.toRecord @@ -20,19 +19,16 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.withContext import uniffi.gemstone.Config -import uniffi.gemstone.GemGateway import java.math.BigInteger class StakeRepository( private val gemApiStaticClient: GemApiStaticClient, private val gemApiClient: GemApiClient, - private val gateway: GemGateway, - private val stakeClients: List, + private val stakeService: StakeService, private val stakeDao: StakeDao, ) { private val recommendedValidators = Config().getValidators() - private val stakeClientsProxy = StakeClientProxy(gateway, stakeClients) suspend fun sync(chain: Chain, address: String) = withContext(Dispatchers.IO) { val apr = try { @@ -41,13 +37,12 @@ class StakeRepository( return@withContext } syncValidators(chain, apr) - syncDelegations(chain, address, apr) + syncDelegations(chain, address) } - private suspend fun syncDelegations(chain: Chain, address: String, apr: Double) = withContext(Dispatchers.IO) { + private suspend fun syncDelegations(chain: Chain, address: String) = withContext(Dispatchers.IO) { val delegations = try { - stakeClientsProxy.getStakeDelegations(chain, address, apr) -// stakeClients.firstOrNull { it.supported(chain) }?.getStakeDelegations(chain, address, apr) ?: return@withContext + stakeService.getStakeDelegations(chain, address) } catch (_: Throwable) { return@withContext } @@ -63,7 +58,7 @@ class StakeRepository( } catch (_: Throwable) { emptyMap() } - val validators = stakeClientsProxy.getValidators(chain, apr) + val validators = stakeService.getValidators(chain, apr) .map { if (it.name.isEmpty()) { it.copy(name = validatorsInfo[it.id]?.name ?: "") diff --git a/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/AddNodeViewModel.kt b/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/AddNodeViewModel.kt index b86692230..7fb2ca72a 100644 --- a/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/AddNodeViewModel.kt +++ b/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/AddNodeViewModel.kt @@ -5,7 +5,7 @@ import android.webkit.URLUtil import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.gemwallet.android.blockchain.services.NodeStatusClientProxy +import com.gemwallet.android.blockchain.services.NodeStatusService import com.gemwallet.android.cases.nodes.AddNodeCase import com.gemwallet.android.cases.nodes.SetCurrentNodeCase import com.gemwallet.features.settings.networks.viewmodels.models.AddNodeUIModel @@ -24,7 +24,7 @@ import javax.inject.Inject @HiltViewModel class AddNodeViewModel @Inject constructor( - private val nodeStatusClient: NodeStatusClientProxy, + private val nodeStatusClient: NodeStatusService, private val addNodeCase: AddNodeCase, private val setCurrentNodeCase: SetCurrentNodeCase, ) : ViewModel() { diff --git a/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/NetworksViewModel.kt b/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/NetworksViewModel.kt index d71b1171f..1c6947088 100644 --- a/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/NetworksViewModel.kt +++ b/features/settings/networks/viewmodels/src/main/kotlin/com/gemwallet/features/settings/networks/viewmodels/NetworksViewModel.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.snapshotFlow import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.gemwallet.android.blockchain.services.NodeStatusClientProxy +import com.gemwallet.android.blockchain.services.NodeStatusService import com.gemwallet.android.cases.nodes.GetBlockExplorers import com.gemwallet.android.cases.nodes.GetCurrentBlockExplorer import com.gemwallet.android.cases.nodes.GetCurrentNodeCase @@ -51,7 +51,7 @@ class NetworksViewModel @Inject constructor( private val setBlockExplorerCase: SetBlockExplorerCase, private val getCurrentNodeCase: GetCurrentNodeCase, private val setCurrentNodeCase: SetCurrentNodeCase, - private val nodeStatusClient: NodeStatusClientProxy, + private val nodeStatusClient: NodeStatusService, ) : ViewModel() { private val state = MutableStateFlow(State()) @@ -126,7 +126,7 @@ class NetworksViewModel @Inject constructor( explorers = getBlockExplorers.getBlockExplorers(chain), currentNode = getCurrentNodeCase.getCurrentNode(chain), currentExplorer = getCurrentBlockExplorer.getCurrentBlockExplorer(chain), - availableAddNode = nodeStatusClient.supported(chain), + availableAddNode = true, ) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4451575d1..d869d9a7d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,7 +46,7 @@ reorderable = "3.0.0" mockkVersion = "1.14.5" datastore = "1.1.7" wallet-core = "4.3.5" -gemstone = "0.33.2" +gemstone = "0.33.3" ktor = "3.1.3" appcompat = "1.7.1" material = "1.13.0" From 827c2c8d1d49005f3c606f3358e2a61b93bb4398 Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Wed, 3 Sep 2025 21:37:05 -0700 Subject: [PATCH 06/16] Clear codebase --- .../app/tokens/TestValidateTokenAddress.kt | 1 - .../blockchain/clients/evm/TestEvmBalance.kt | 1 - .../evm/TestEvmTransactionStatusClient.kt | 3 +- .../blockchain/clients/BalanceClient.kt | 13 ---- .../blockchain/clients/BroadcastClient.kt | 8 -- .../blockchain/clients/GetTokenClient.kt | 9 --- .../blockchain/clients/NodeStatusClient.kt | 8 -- .../android/blockchain/clients/StakeClient.kt | 11 --- .../clients/TransactionStatusClient.kt | 20 ----- .../clients/ethereum/EvmBroadcastClient.kt | 26 ------- .../clients/ethereum/EvmGetTokenClient.kt | 66 ---------------- .../clients/ethereum/EvmNodeStatusClient.kt | 39 ---------- .../ethereum/EvmTransactionStatusClient.kt | 48 ------------ .../clients/ethereum/SmartchainStakeClient.kt | 75 ------------------- .../model/TransactionStateRequest.kt | 10 +++ .../model/TransactionStatusError.kt | 5 ++ .../blockchain/services/BalancesService.kt | 1 - .../blockchain/services/TokenService.kt | 9 +-- .../services/TransactionStatusService.kt | 10 +-- .../data/repositoreis/di/AssetsModule.kt | 1 - .../data/repositoreis/di/TokensModule.kt | 13 ---- .../transactions/TransactionsRepository.kt | 5 +- 22 files changed, 24 insertions(+), 358 deletions(-) delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BalanceClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/GetTokenClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/NodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/StakeClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/TransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmBroadcastClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGetTokenClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmNodeStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmTransactionStatusClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/SmartchainStakeClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/model/TransactionStateRequest.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/model/TransactionStatusError.kt diff --git a/app/src/androidTest/kotlin/wallet/android/app/tokens/TestValidateTokenAddress.kt b/app/src/androidTest/kotlin/wallet/android/app/tokens/TestValidateTokenAddress.kt index 69e6c1cc3..60cf99fe8 100644 --- a/app/src/androidTest/kotlin/wallet/android/app/tokens/TestValidateTokenAddress.kt +++ b/app/src/androidTest/kotlin/wallet/android/app/tokens/TestValidateTokenAddress.kt @@ -1,6 +1,5 @@ package wallet.android.app.tokens -import com.gemwallet.android.blockchain.clients.ethereum.EvmGetTokenClient import junit.framework.TestCase.assertFalse import junit.framework.TestCase.assertTrue import org.junit.Test diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt index e230631aa..69acc9fc0 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt @@ -1,6 +1,5 @@ package com.gemwallet.android.blockchain.clients.evm -import com.gemwallet.android.blockchain.clients.ethereum.SmartchainStakeClient import com.gemwallet.android.blockchain.clients.ethereum.services.EvmBalancesService import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService import com.gemwallet.android.blockchain.clients.ethereum.services.EvmRpcClient diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmTransactionStatusClient.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmTransactionStatusClient.kt index ef02627be..cba71e4ee 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmTransactionStatusClient.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmTransactionStatusClient.kt @@ -1,7 +1,6 @@ package com.gemwallet.android.blockchain.clients.evm -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.ethereum.EvmTransactionStatusClient +import com.gemwallet.android.blockchain.model.TransactionStateRequest import com.gemwallet.android.blockchain.clients.ethereum.services.EvmTransactionsService import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BalanceClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BalanceClient.kt deleted file mode 100644 index c051d4970..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BalanceClient.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.gemwallet.android.blockchain.clients - -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.Chain - -interface BalanceClient : BlockchainClient { - suspend fun getNativeBalance(chain: Chain, address: String): AssetBalance? - - suspend fun getDelegationBalances(chain: Chain, address: String): AssetBalance? = null - - suspend fun getTokenBalances(chain: Chain, address: String, tokens: List): List = emptyList() -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BroadcastClient.kt deleted file mode 100644 index 7420741e2..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/BroadcastClient.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.gemwallet.android.blockchain.clients - -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.TransactionType - -interface BroadcastClient : BlockchainClient { - suspend fun send(account: Account, signedMessage: ByteArray, type: TransactionType): String -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/GetTokenClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/GetTokenClient.kt deleted file mode 100644 index f4ce113ba..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/GetTokenClient.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.gemwallet.android.blockchain.clients - -import com.wallet.core.primitives.Asset - -interface GetTokenClient : BlockchainClient { - suspend fun getTokenData(tokenId: String): Asset? - - suspend fun isTokenQuery(query: String): Boolean -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/NodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/NodeStatusClient.kt deleted file mode 100644 index fe6bd81c7..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/NodeStatusClient.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.gemwallet.android.blockchain.clients - -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain - -interface NodeStatusClient : BlockchainClient { - suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/StakeClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/StakeClient.kt deleted file mode 100644 index 7c9ad7795..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/StakeClient.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients - -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.DelegationBase -import com.wallet.core.primitives.DelegationValidator - -interface StakeClient : BlockchainClient { - suspend fun getValidators(chain: Chain, apr: Double): List - - suspend fun getStakeDelegations(chain: Chain, address: String, apr: Double): List -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/TransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/TransactionStatusClient.kt deleted file mode 100644 index c39217c02..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/TransactionStatusClient.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.gemwallet.android.blockchain.clients - -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain - -interface TransactionStatusClient : BlockchainClient { - - suspend fun getStatus(request: TransactionStateRequest): TransactionChanges -} - -class TransactionStateRequest( - val chain: Chain, - val hash: String, - val block: String, - val sender: String, -) - -sealed class TransactionStatusError(message: String? = null) : Exception(message) - -object ServiceUnavailable : TransactionStatusError() \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmBroadcastClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmBroadcastClient.kt deleted file mode 100644 index 2d3e0a184..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmBroadcastClient.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.blockchain.clients.BroadcastClient -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmBroadcastService -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.math.toHexString -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionType - -class EvmBroadcastClient( - private val chain: Chain, - private val broadcastService: EvmBroadcastService, -) : BroadcastClient { - override suspend fun send(account: Account, signedMessage: ByteArray, type: TransactionType): String { - val request = JSONRpcRequest.create(EvmMethod.Broadcast, listOf(signedMessage.toHexString())) - val result = broadcastService.broadcast(request) - val data = result.getOrNull() ?: throw Exception(result.exceptionOrNull()?.message ?: "Network error") - if (data.error != null) { - throw Exception(data.error.message) - } - return data.result - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGetTokenClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGetTokenClient.kt deleted file mode 100644 index 61a7223ae..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGetTokenClient.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.blockchain.clients.GetTokenClient -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService -import com.gemwallet.android.blockchain.clients.ethereum.services.batch -import com.gemwallet.android.blockchain.clients.ethereum.services.createCallRequest -import com.gemwallet.android.math.decodeHex -import com.gemwallet.android.math.has0xPrefix -import com.gemwallet.android.math.hexToBigInteger -import com.gemwallet.android.math.toHexString -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import wallet.core.jni.EthereumAbi -import wallet.core.jni.EthereumAbiFunction -import wallet.core.jni.EthereumAbiValue - -class EvmGetTokenClient( - private val chain: Chain, - private val callService: EvmCallService, -) : GetTokenClient { - override suspend fun getTokenData(tokenId: String): Asset? = withContext(Dispatchers.IO) { - val params = listOf( - callService.createCallRequest(tokenId, EthereumAbi.encode(EthereumAbiFunction("name")).toHexString(), "latest"), - callService.createCallRequest(tokenId, EthereumAbi.encode(EthereumAbiFunction("symbol")).toHexString(), "latest"), - callService.createCallRequest(tokenId, EthereumAbi.encode(EthereumAbiFunction("decimals")).toHexString(), "latest"), - ) - val result = callService.batch(params) - val name = result.getOrNull(0)?.let { decodeAbi(it) } - val symbol = result.getOrNull(1)?.let { decodeAbi(it) } - val decimals = result.getOrNull(2)?.let { it.hexToBigInteger()?.toInt() } - - if (name.isNullOrEmpty() || symbol.isNullOrEmpty() || decimals == null) { - null - } else { - Asset( - id = AssetId(chain, tokenId), - name = name, - symbol = symbol, - decimals = decimals, - type = AssetType.ERC20, - ) - } - } - - override suspend fun isTokenQuery(query: String): Boolean = isTokenAddress(query) - - override fun supported(chain: Chain): Boolean = this.chain == chain - - private fun decodeAbi(hexString: String): String? { - val data = hexString.decodeHex() - if (data.size < 32) { - return null - } - return EthereumAbiValue.decodeValue(data.drop(32).toByteArray(), "string") - } - - companion object { - fun isTokenAddress(tokenId: String): Boolean { - return tokenId.has0xPrefix() && tokenId.isNotEmpty() && tokenId.length == 42 - } - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmNodeStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmNodeStatusClient.kt deleted file mode 100644 index 60399f64b..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmNodeStatusClient.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.blockchain.clients.NodeStatusClient -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmNodeStatusService -import com.gemwallet.android.blockchain.clients.ethereum.services.getChainId -import com.gemwallet.android.blockchain.clients.ethereum.services.latestBlock -import com.gemwallet.android.blockchain.clients.ethereum.services.sync -import com.gemwallet.android.blockchain.rpc.getLatency -import com.gemwallet.android.model.NodeStatus -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class EvmNodeStatusClient( - private val chain: Chain, - private val nodeStatusService: EvmNodeStatusService, -) : NodeStatusClient { - - override suspend fun getNodeStatus(chain: Chain, url: String): NodeStatus? = withContext(Dispatchers.IO) { - val getChainId = async { nodeStatusService.getChainId(url) } - val getLatestBlock = async { nodeStatusService.latestBlock(url).getOrNull()?.result?.value?.toString() } - val getSync = async { nodeStatusService.sync(url).getOrNull()?.result } - - val chainId = getChainId.await() - val blockNumber = getLatestBlock.await() ?: return@withContext null - val inSync = getSync.await() ?: return@withContext null - - NodeStatus( - url = url, - chainId = chainId.body()?.result?.value?.toString() ?: return@withContext null, - blockNumber = blockNumber.toULong(), - inSync = !inSync, - latency = chainId.getLatency(), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmTransactionStatusClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmTransactionStatusClient.kt deleted file mode 100644 index 6cdc7681f..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmTransactionStatusClient.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmTransactionsService -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.math.hexToBigInteger -import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState -import java.math.BigInteger - -class EvmTransactionStatusClient( - private val chain: Chain, - private val transactionsService: EvmTransactionsService, -) : TransactionStatusClient { - - override suspend fun getStatus(request: TransactionStateRequest): TransactionChanges { - return getStatus(request.hash) - } - - private suspend fun getStatus(txId: String): TransactionChanges { - val request = JSONRpcRequest.create(EvmMethod.GetTransaction, listOf(txId)) - val resp = try { - transactionsService.transaction(request).result - } catch (_: Throwable) { - throw ServiceUnavailable - } - - if (resp.status != "0x0" && resp.status != "0x1") { - return TransactionChanges(TransactionState.Pending) - } - val state = when (resp.status) { - "0x0" -> TransactionState.Reverted - "0x1" -> TransactionState.Confirmed - else -> TransactionState.Confirmed - } - val gasUsed = resp.gasUsed.hexToBigInteger() ?: return TransactionChanges(TransactionState.Pending) - val effectiveGas = resp.effectiveGasPrice.hexToBigInteger() ?: return TransactionChanges(TransactionState.Pending) - val l1Fee = resp.l1Fee?.hexToBigInteger() ?: BigInteger.ZERO - val fee = gasUsed.multiply(effectiveGas) + l1Fee - - return TransactionChanges(state, fee) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/SmartchainStakeClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/SmartchainStakeClient.kt deleted file mode 100644 index ef290d015..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/SmartchainStakeClient.kt +++ /dev/null @@ -1,75 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.blockchain.clients.StakeClient -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService -import com.gemwallet.android.blockchain.clients.ethereum.services.batch -import com.gemwallet.android.blockchain.clients.ethereum.services.callString -import com.gemwallet.android.blockchain.clients.ethereum.services.createCallRequest -import com.gemwallet.android.ext.asset -import com.gemwallet.android.math.decodeHex -import com.gemwallet.android.model.AssetBalance -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.DelegationBase -import com.wallet.core.primitives.DelegationState -import com.wallet.core.primitives.DelegationValidator -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import wallet.core.jni.EthereumAbiValue -import java.math.BigInteger - -class SmartchainStakeClient( - private val chain: Chain, - private val callService: EvmCallService, -) : StakeClient { - - override suspend fun getValidators(chain: Chain, apr: Double): List { - val limit = getMaxElectedValidators() - val data = StakeHub.encodeValidatorsCall(0, limit) - val result = callService.callString(StakeHub.reader, data) ?: return emptyList() - val validators = StakeHub.decodeValidatorsReturn(result) - return validators - } - - override suspend fun getStakeDelegations(chain: Chain, address: String, apr: Double): List = withContext(Dispatchers.IO) { - val limit = 128 - val delegationDataRequest = StakeHub.encodeDelegationsCall(address, limit) - val undelegationDataRequest = StakeHub.encodeUndelegationsCall(address, limit) - val requests = listOf( - callService.createCallRequest(StakeHub.reader, delegationDataRequest, "latest"), - callService.createCallRequest(StakeHub.reader, undelegationDataRequest, "latest"), - ) - val result = callService.batch(requests) - val delegations = StakeHub.decodeDelegationsResult(result[0]) - val undelegations = StakeHub.decodeUnelegationsResult(result[1]) - - delegations + undelegations - } - - suspend fun getBalance(address: String): AssetBalance? = withContext(Dispatchers.IO) { - val delegations = getStakeDelegations(chain, address, 0.0) - - val staked = delegations.filter { it.state == DelegationState.Active }.sumBalances() - - val pending = delegations.filter { - it.state == DelegationState.Undelegating || it.state == DelegationState.AwaitingWithdrawal - }.sumBalances() - - AssetBalance.create( - asset = Chain.SmartChain.asset(), - staked = staked.toString(), - pending = pending.toString() - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - - private suspend fun getMaxElectedValidators(): Int { - val result = callService.callString(StakeHub.address, StakeHub.encodeMaxElectedValidators()) - ?: throw IllegalStateException("Unable to get validators") - return EthereumAbiValue.decodeUInt256(result.decodeHex()).toUShort().toInt() - } - - private fun List.sumBalances(): BigInteger = - map { it.balance.toBigIntegerOrNull() ?: BigInteger.ZERO } - .fold(BigInteger.ZERO) {acc, value -> acc + value } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/model/TransactionStateRequest.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/model/TransactionStateRequest.kt new file mode 100644 index 000000000..14f8e34e5 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/model/TransactionStateRequest.kt @@ -0,0 +1,10 @@ +package com.gemwallet.android.blockchain.model + +import com.wallet.core.primitives.Chain + +class TransactionStateRequest( + val chain: Chain, + val hash: String, + val block: String, + val sender: String, +) \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/model/TransactionStatusError.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/model/TransactionStatusError.kt new file mode 100644 index 000000000..44e874d72 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/model/TransactionStatusError.kt @@ -0,0 +1,5 @@ +package com.gemwallet.android.blockchain.model + +sealed class TransactionStatusError(message: String? = null) : Exception(message) + +object ServiceUnavailable : TransactionStatusError() \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt index e07d136f0..1381121f5 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/BalancesService.kt @@ -1,6 +1,5 @@ package com.gemwallet.android.blockchain.services -import com.gemwallet.android.blockchain.clients.BalanceClient import com.gemwallet.android.ext.asset import com.gemwallet.android.ext.toIdentifier import com.gemwallet.android.model.AssetBalance diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt index 9c35fe160..5600bcf09 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TokenService.kt @@ -1,12 +1,12 @@ package com.gemwallet.android.blockchain.services -import com.gemwallet.android.blockchain.clients.GetTokenClient import com.gemwallet.android.blockchain.services.mapper.toApp import com.wallet.core.primitives.Asset import com.wallet.core.primitives.AssetBasic import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.AssetProperties import com.wallet.core.primitives.AssetScore +import com.wallet.core.primitives.Chain import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -14,15 +14,14 @@ import kotlinx.coroutines.withContext import uniffi.gemstone.GemGateway class TokenService( - private val getTokenClients: List, private val gateway: GemGateway, ) { suspend fun search(query: String) = withContext(Dispatchers.IO) { - getTokenClients.map { + Chain.entries.map { async { try { - if (it.isTokenQuery(query)) { - it.getTokenData(query) + if (gateway.getIsTokenAddress(it.string, query)) { + getTokenData(AssetId(it, query)) } else { null } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt index a890e9d7e..ec0c89a38 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/TransactionStatusService.kt @@ -1,20 +1,14 @@ package com.gemwallet.android.blockchain.services -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient -import com.gemwallet.android.ext.toAssetId -import com.gemwallet.android.ext.toChainType +import com.gemwallet.android.blockchain.model.ServiceUnavailable +import com.gemwallet.android.blockchain.model.TransactionStateRequest import com.gemwallet.android.model.HashChanges import com.gemwallet.android.model.TransactionChanges -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.ChainType import com.wallet.core.primitives.TransactionState import okhttp3.internal.toLongOrDefault import uniffi.gemstone.GemGateway import uniffi.gemstone.GemTransactionChange import uniffi.gemstone.GemTransactionStateRequest -import java.lang.IllegalArgumentException class TransactionStatusService( private val gateway: GemGateway, diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt index 07b223063..a82da42f0 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt @@ -2,7 +2,6 @@ package com.gemwallet.android.data.repositoreis.di import com.gemwallet.android.blockchain.RpcClientAdapter //import com.gemwallet.android.blockchain.clients.ethereum.EvmBalanceClient -import com.gemwallet.android.blockchain.clients.ethereum.SmartchainStakeClient import com.gemwallet.android.cases.device.GetDeviceIdCase import com.gemwallet.android.cases.tokens.SearchTokensCase import com.gemwallet.android.cases.transactions.GetTransactions diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt index e18ee577f..c67547ec5 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/TokensModule.kt @@ -1,17 +1,11 @@ package com.gemwallet.android.data.repositoreis.di -import com.gemwallet.android.blockchain.RpcClientAdapter -import com.gemwallet.android.blockchain.clients.ethereum.EvmGetTokenClient import com.gemwallet.android.blockchain.services.TokenService import com.gemwallet.android.cases.tokens.SearchTokensCase import com.gemwallet.android.data.repositoreis.tokens.TokensRepository import com.gemwallet.android.data.service.store.database.AssetsDao import com.gemwallet.android.data.service.store.database.AssetsPriorityDao import com.gemwallet.android.data.services.gemapi.GemApiClient -import com.gemwallet.android.ext.available -import com.gemwallet.android.ext.toChainType -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.ChainType import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -29,19 +23,12 @@ object TokensModule { assetsPriorityDao: AssetsPriorityDao, gateway: GemGateway, gemApiClient: GemApiClient, - rpcClients: RpcClientAdapter, ): TokensRepository = TokensRepository( assetsDao = assetsDao, assetsPriorityDao = assetsPriorityDao, gemApiClient = gemApiClient, tokenService = TokenService( gateway = gateway, - getTokenClients = Chain.available().mapNotNull { chain -> - when (chain.toChainType()) { - ChainType.Ethereum -> EvmGetTokenClient(chain, rpcClients.getClient(chain)) - else -> null - } - } ), ) diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/transactions/TransactionsRepository.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/transactions/TransactionsRepository.kt index c9c806121..4b11ba3cc 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/transactions/TransactionsRepository.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/transactions/TransactionsRepository.kt @@ -2,9 +2,8 @@ package com.gemwallet.android.data.repositoreis.transactions import android.text.format.DateUtils import android.util.Log -import com.gemwallet.android.blockchain.clients.ServiceUnavailable -import com.gemwallet.android.blockchain.clients.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.TransactionStatusClient +import com.gemwallet.android.blockchain.model.ServiceUnavailable +import com.gemwallet.android.blockchain.model.TransactionStateRequest import com.gemwallet.android.blockchain.services.TransactionStatusService import com.gemwallet.android.cases.transactions.ClearPendingTransactions import com.gemwallet.android.cases.transactions.CreateTransaction From b7f4812ddf462a61be29b87651039b5bdba8f2f5 Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Thu, 4 Sep 2025 18:37:31 -0700 Subject: [PATCH 07/16] Update tests --- .../android/blockchain/TestFormatter.kt | 4 +- .../clients/algorand/TestAlgorandSigner.kt | 17 +- .../clients/aptos/TestAptosSigner.kt | 36 +- .../clients/bitcoin/TestBitcoinSigner.kt | 25 +- .../clients/cardano/TestCardanoSigner.kt | 15 +- .../clients/cosmos/TestCosmosSigner.kt | 125 +++--- .../blockchain/clients/evm/TestEthSign.kt | 114 ++--- .../blockchain/clients/evm/TestEvmBalance.kt | 246 ---------- .../clients/evm/TestEvmEncodeApprove.kt | 29 -- .../clients/evm/TestEvmExtentions.kt | 64 --- .../evm/TestEvmTransactionStatusClient.kt | 123 ----- .../clients/evm/TestFeeCalculator.kt | 421 ------------------ .../blockchain/clients/near/TestNearSigner.kt | 13 +- .../clients/polkadot/TestPolkadotSigner.kt | 35 +- .../clients/solana/TestSolanaSigner.kt | 160 ++++--- .../clients/stellar/TestStellarSigner.kt | 16 +- .../blockchain/clients/sui/TestSuiSigner.kt | 22 +- .../blockchain/clients/ton/TestTonSigner.kt | 26 +- .../blockchain/clients/tron/TestTronSigner.kt | 55 ++- .../blockchain/clients/xrp/TestXrpSigner.kt | 15 +- .../repositoreis/assets/AssetsRepository.kt | 8 +- 21 files changed, 353 insertions(+), 1216 deletions(-) delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmEncodeApprove.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmExtentions.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmTransactionStatusClient.kt delete mode 100644 blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestFeeCalculator.kt diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/TestFormatter.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/TestFormatter.kt index 4facd9ddf..e735af02c 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/TestFormatter.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/TestFormatter.kt @@ -9,8 +9,8 @@ import java.util.Locale class TestFormatter { @Test fun testCompactFormat_Italy() { - assertEquals("5,00 Mio €", Currency.EUR.compactFormatter(5_000_000.0, Locale.ITALY)) - assertEquals("7,89 Mrd €", Currency.EUR.compactFormatter(7_890_000_000.0, Locale.ITALY)) + assertEquals("5,00 Mln €", Currency.EUR.compactFormatter(5_000_000.0, Locale.ITALY)) + assertEquals("7,89 Mld €", Currency.EUR.compactFormatter(7_890_000_000.0, Locale.ITALY)) assertEquals("1,20 Bln €", Currency.EUR.compactFormatter(1_200_000_000_000.0, Locale.ITALY)) } diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt index 94ef2a348..eb64b974d 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt @@ -40,27 +40,26 @@ class TestAlgorandSigner { DestinationAddress("GOZOAE6SH6XGGDRBQLZEDRITKMF5OLVJNACVRQBUEGFLBBR5I64A7QN63E"), ), chainData = AlgorandChainData( - sequence = 46932581, + sequence = 46932581UL, block = "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=", chainId = "mainnet-v1.0", - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Algorand), - amount = BigInteger.TEN - ) ), finalAmount = BigInteger.valueOf(10_000_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Algorand), + amount = BigInteger.TEN + ), privateKey.data(), ) } - assertEquals("0x82a3736967c44049c1faef9ca28e835bb980e84e2d6f6eaf866828abf8ce51f1820d04ea" + + assertEquals("82a3736967c44049c1faef9ca28e835bb980e84e2d6f6eaf866828abf8ce51f1820d04ea" + "87623069603104aaadcdea598dd6e77f8dbe40c7f9638485cfeda1609b810e23ce1604a374786e8" + "9a3616d74ce00989680a36665650aa26676ce02cc2265a367656eac6d61696e6e65742d76312e30" + "a26768c420c061c4d8fc1dbdded2d7604be4568e3f6d041987ac37bde4b620b5ab39248adfa26c7" + "6ce02cc264da3726376c42033b2e013d23fae630e2182f241c513530bd72ea9680558c034218ab0" + "863d47b8a3736e64c42033b2e013d23fae630e2182f241c513530bd72ea9680558c034218ab0863" + - "d47b8a474797065a3706179", sign.first().toHexString()) + "d47b8a474797065a3706179", String(sign.first())) } } \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSigner.kt index 7b6d22739..9ebc45f8a 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSigner.kt @@ -45,18 +45,15 @@ class TestAptosSigner { DestinationAddress("0x82111f2975a0f6080d178236369b7479f6aed1203ef4a23f8205e4b91716b783"), ), chainData = AptosChainData( - 8L, - listOf( - GasFee( - AssetId(Chain.Aptos), - priority = FeePriority.Normal, - maxGasPrice = BigInteger.valueOf(150L), - limit = BigInteger.valueOf(18L) - ) - ) + 8UL, ), finalAmount = BigInteger.valueOf(10_000_000_000), - FeePriority.Normal, + GasFee( + AssetId(Chain.Aptos), + priority = FeePriority.Normal, + maxGasPrice = BigInteger.valueOf(150L), + limit = BigInteger.valueOf(18L) + ), privateKey.data(), ) } @@ -94,19 +91,16 @@ class TestAptosSigner { DestinationAddress("0x82111f2975a0f6080d178236369b7479f6aed1203ef4a23f8205e4b91716b783"), ), chainData = AptosChainData( - 8L, - listOf( - GasFee( - AssetId(Chain.Aptos), - priority = FeePriority.Normal, - maxGasPrice = BigInteger.valueOf(150L), - limit = BigInteger.valueOf(18L) - ) - ) + 8UL, + ), + fee = GasFee( + AssetId(Chain.Aptos), + priority = FeePriority.Normal, + maxGasPrice = BigInteger.valueOf(150L), + limit = BigInteger.valueOf(18L) ), finalAmount = BigInteger.valueOf(10_000_000_000), - FeePriority.Normal, - privateKey.data(), + privateKey = privateKey.data(), ) } diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt index 865902875..918e8f06e 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt @@ -13,6 +13,7 @@ import com.wallet.core.primitives.Account import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.Chain import com.wallet.core.primitives.FeePriority +import com.wallet.core.primitives.UTXO import junit.framework.TestCase.assertEquals import kotlinx.coroutines.runBlocking import org.junit.Test @@ -25,7 +26,7 @@ import java.math.BigInteger class TestBitcoinSigner { companion object { - const val SIGN_RESULT = "0x010000000153bd8a94cf6424d8e54cacbad6082c249cdacdd0956f766206a" + + const val SIGN_RESULT = "010000000153bd8a94cf6424d8e54cacbad6082c249cdacdd0956f766206a" + "c3daed5e5479f010000006b483045022100ead2b7637532b167e66ddf76eafd032ada898c8719a" + "680de8183b71fb3086a3e022055a073be9148cb8b9dc71de04755dbf11f140fee167ed0d4b44d6" + "a54a829e75e012102fd6585adc0e86019abf00e83552d054cb5f4359ad4db8ca338099381f43e2" + @@ -51,27 +52,25 @@ class TestBitcoinSigner { ), chainData = BitcoinChainData( listOf( - BitcoinUTXO( - txid = "9f47e5d5ae3dac0662766f95d0cdda9c242c08d6baac4ce5d82464cf948abd53", + UTXO( + transaction_id = "9f47e5d5ae3dac0662766f95d0cdda9c242c08d6baac4ce5d82464cf948abd53", vout = 1, value = "86055170", + address = "" ) ), - listOf( - GasFee( - AssetId(Chain.Doge), - priority = FeePriority.Normal, - maxGasPrice = BigInteger.valueOf(150L), - limit = BigInteger.valueOf(18L) - ) - ) ), finalAmount = BigInteger.valueOf(10_000_000_000), - FeePriority.Normal, + fee = GasFee( + AssetId(Chain.Doge), + priority = FeePriority.Normal, + maxGasPrice = BigInteger.valueOf(150L), + limit = BigInteger.valueOf(18L) + ), privateKey.data() ) } - assertEquals(SIGN_RESULT, sign.first().toHexString()) + assertEquals(SIGN_RESULT, String(sign.first())) } } \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt index fcfe5ed3a..2bcfe0084 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt @@ -40,11 +40,6 @@ class TestCardanoSigner { DestinationAddress("addr1q9d2dxen8ywvs9yzxxn2w4mvffn797fquauvugt2ug7mfsuqj3lzdq9h0rsketzszrnfm930658swmpe7kpq53c2tmwql4rvtq"), ), chainData = CardanoChainData( - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Cardano), - amount = BigInteger.TEN - ), utxos = listOf( UTXO( address = "addr1q9d2dxen8ywvs9yzxxn2w4mvffn797fquauvugt2ug7mfsuqj3lzdq9h0rsketzszrnfm930658swmpe7kpq53c2tmwql4rvtq", @@ -55,18 +50,22 @@ class TestCardanoSigner { ) ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Cardano), + amount = BigInteger.TEN + ), privateKey.data(), ) } - assertEquals("0x83a40081825820412c5a964cf4515210bf4b82f45df6521c38e1e5381f27638fc509bef66" + + assertEquals("83a40081825820412c5a964cf4515210bf4b82f45df6521c38e1e5381f27638fc509bef66" + "79378010182825839015aa69b33391cc8148231a6a7576c4a67e2f920e778ce216ae23db4c380947" + "e2680b778e16cac5010e69d962fd50f076c39f5820a470a5edc192710825839015aa69b33391cc81" + "48231a6a7576c4a67e2f920e778ce216ae23db4c380947e2680b778e16cac5010e69d962fd50f076" + "c39f5820a470a5edc1a0076859c021a0002924b031a0b532b80a10081825820878150b7cb71f9406" + "e36dcdd250e22dc943ec4525233581536497acb4f13e670584004bf4935e4dcc7f54947c4eb0b9cd" + "d24880b168138af31b394ee0e7fe935900383822f432a1c2b533ea54f8ef12f1758b30a045f3918e" + - "f25a51dad762d071b0af6", sign.first().toHexString()) + "f25a51dad762d071b0af6", String(sign.first())) } } \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosSigner.kt index e4414bbf9..14b8da275 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosSigner.kt @@ -41,19 +41,24 @@ class TestCosmosSigner { .transfer(DestinationAddress("osmo1rcjvzz8wzktqfz8qjf0l9q45kzxvd0z0n7l5cf")) as ConfirmParams.TransferParams.Native val chainData = CosmosChainData( chainId = "osmosis-1", - accountNumber = 2913388L, - sequence = 10L, - fee = GasFee( - feeAssetId = AssetId(Chain.Osmosis), - maxGasPrice = BigInteger.valueOf(10000L), - limit = BigInteger.valueOf(200000L), - amount = BigInteger.valueOf(10000L), - priority = FeePriority.Normal, - ) + accountNumber = 2913388UL, + sequence = 10UL, ) val finalAmount = BigInteger.TEN val result = runBlocking { - signer.signNativeTransfer(transfer, chainData, finalAmount, FeePriority.Normal, privateKey) + signer.signNativeTransfer( + transfer, + chainData, + finalAmount, + fee = GasFee( + feeAssetId = AssetId(Chain.Osmosis), + maxGasPrice = BigInteger.valueOf(10000L), + limit = BigInteger.valueOf(200000L), + amount = BigInteger.valueOf(10000L), + priority = FeePriority.Normal, + ), + privateKey + ) }.first().toHexString() assertEquals( "0x7b226d6f6465223a2242524f4144434153545f4d4f44455f53594e43222c2274785f6279746573223" + @@ -79,19 +84,24 @@ class TestCosmosSigner { .delegate("osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm") val chainData = CosmosChainData( chainId = "osmosis-1", - accountNumber = 2913388L, - sequence = 10L, - fee = GasFee( - feeAssetId = AssetId(Chain.Osmosis), - maxGasPrice = BigInteger.valueOf(10000L), - limit = BigInteger.valueOf(200000L), - amount = BigInteger.valueOf(10000L), - priority = FeePriority.Normal, - ) + accountNumber = 2913388UL, + sequence = 10UL, ) val finalAmount = BigInteger.TEN val result = runBlocking { - signer.signDelegate(transfer, chainData, finalAmount, FeePriority.Normal, privateKey) + signer.signDelegate( + transfer, + chainData, + finalAmount, + fee = GasFee( + feeAssetId = AssetId(Chain.Osmosis), + maxGasPrice = BigInteger.valueOf(10000L), + limit = BigInteger.valueOf(200000L), + amount = BigInteger.valueOf(10000L), + priority = FeePriority.Normal, + ), + privateKey + ) }.first().toHexString() assertEquals( "0x7b226d6f6465223a2242524f4144434153545f4d4f44455f53594e43222c2274785f6279746573223" + @@ -139,19 +149,24 @@ class TestCosmosSigner { ) val chainData = CosmosChainData( chainId = "osmosis-1", - accountNumber = 2913388L, - sequence = 10L, - fee = GasFee( - feeAssetId = AssetId(Chain.Osmosis), - maxGasPrice = BigInteger.valueOf(10000L), - limit = BigInteger.valueOf(200000L), - amount = BigInteger.valueOf(10000L), - priority = FeePriority.Normal, - ) + accountNumber = 2913388UL, + sequence = 10UL, ) val finalAmount = BigInteger.TEN val result = runBlocking { - signer.signUndelegate(transfer, chainData, finalAmount, FeePriority.Normal, privateKey) + signer.signUndelegate( + transfer, + chainData, + finalAmount, + fee = GasFee( + feeAssetId = AssetId(Chain.Osmosis), + maxGasPrice = BigInteger.valueOf(10000L), + limit = BigInteger.valueOf(200000L), + amount = BigInteger.valueOf(10000L), + priority = FeePriority.Normal, + ), + privateKey + ) }.first().toHexString() assertEquals( "0x7b226d6f6465223a2242524f4144434153545f4d4f44455f53594e43222c2274785f6279746573223" + @@ -201,19 +216,24 @@ class TestCosmosSigner { ) val chainData = CosmosChainData( chainId = "osmosis-1", - accountNumber = 2913388L, - sequence = 10L, - fee = GasFee( - feeAssetId = AssetId(Chain.Osmosis), - maxGasPrice = BigInteger.valueOf(10000L), - limit = BigInteger.valueOf(200000L), - amount = BigInteger.valueOf(10000L), - priority = FeePriority.Normal, - ) + accountNumber = 2913388UL, + sequence = 10UL, ) val finalAmount = BigInteger.TEN val result = runBlocking { - signer.signRedelegate(transfer, chainData, finalAmount, FeePriority.Normal, privateKey) + signer.signRedelegate( + transfer, + chainData, + finalAmount, + fee = GasFee( + feeAssetId = AssetId(Chain.Osmosis), + maxGasPrice = BigInteger.valueOf(10000L), + limit = BigInteger.valueOf(200000L), + amount = BigInteger.valueOf(10000L), + priority = FeePriority.Normal, + ), + privateKey + ) }.first().toHexString() assertEquals( "0x7b226d6f6465223a2242524f4144434153545f4d4f44455f53594e43222c2274785f6279746573223" + @@ -247,19 +267,24 @@ class TestCosmosSigner { ) val chainData = CosmosChainData( chainId = "osmosis-1", - accountNumber = 2913388L, - sequence = 10L, - fee = GasFee( - feeAssetId = AssetId(Chain.Osmosis), - maxGasPrice = BigInteger.valueOf(10000L), - limit = BigInteger.valueOf(200000L), - amount = BigInteger.valueOf(10000L), - priority = FeePriority.Normal, - ) + accountNumber = 2913388UL, + sequence = 10UL, ) val finalAmount = BigInteger.TEN val result = runBlocking { - signer.signRewards(transfer, chainData, finalAmount, FeePriority.Normal, privateKey) + signer.signRewards( + transfer, + chainData, + finalAmount, + fee = GasFee( + feeAssetId = AssetId(Chain.Osmosis), + maxGasPrice = BigInteger.valueOf(10000L), + limit = BigInteger.valueOf(200000L), + amount = BigInteger.valueOf(10000L), + priority = FeePriority.Normal, + ), + privateKey + ) }.first().toHexString() assertEquals( "0x7b226d6f6465223a2242524f4144434153545f4d4f44455f53594e43222c2274785f6279746573223" + diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEthSign.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEthSign.kt index aa6224386..ee7b98019 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEthSign.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEthSign.kt @@ -49,19 +49,16 @@ class TestEthSign { chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, - fees = listOf( - GasFee( - maxGasPrice = BigInteger.TEN, - limit = BigInteger("21000"), - minerFee = BigInteger.TEN, - relay = BigInteger.TEN, - priority = FeePriority.Normal, - feeAssetId = Chain.Ethereum.asset().id, - ) - ) ), finalAmount = BigInteger.TEN.pow(Chain.Ethereum.asset().decimals), - feePriority = FeePriority.Normal, + fee = GasFee( + maxGasPrice = BigInteger.TEN, + limit = BigInteger("21000"), + minerFee = BigInteger.TEN, + relay = BigInteger.TEN, + priority = FeePriority.Normal, + feeAssetId = Chain.Ethereum.asset().id, + ), privateKey, ) } @@ -92,19 +89,16 @@ class TestEthSign { chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, - fees = listOf( - GasFee( - maxGasPrice = BigInteger.TEN, - limit = BigInteger("91000"), - minerFee = BigInteger.TEN, - relay = BigInteger.TEN, - priority = FeePriority.Normal, - feeAssetId = Chain.Ethereum.asset().id, - ) - ) ), finalAmount = BigInteger.TEN.pow(Chain.Ethereum.asset().decimals), - feePriority = FeePriority.Normal, + fee = GasFee( + maxGasPrice = BigInteger.TEN, + limit = BigInteger("91000"), + minerFee = BigInteger.TEN, + relay = BigInteger.TEN, + priority = FeePriority.Normal, + feeAssetId = Chain.Ethereum.asset().id, + ), privateKey, ) } @@ -143,19 +137,16 @@ class TestEthSign { chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, - fees = listOf( - GasFee( - maxGasPrice = BigInteger.TEN, - limit = BigInteger("91000"), - minerFee = BigInteger.TEN, - relay = BigInteger.TEN, - priority = FeePriority.Normal, - feeAssetId = Chain.Ethereum.asset().id, - ) - ) ), finalAmount = BigInteger.TEN.pow(Chain.Ethereum.asset().decimals), - feePriority = FeePriority.Normal, + fee = GasFee( + maxGasPrice = BigInteger.TEN, + limit = BigInteger("91000"), + minerFee = BigInteger.TEN, + relay = BigInteger.TEN, + priority = FeePriority.Normal, + feeAssetId = Chain.Ethereum.asset().id, + ), privateKey, ) } @@ -180,19 +171,16 @@ class TestEthSign { chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, - fees = listOf( - GasFee( - maxGasPrice = BigInteger.TEN, - limit = BigInteger("91000"), - minerFee = BigInteger.TEN, - relay = BigInteger.TEN, - priority = FeePriority.Normal, - feeAssetId = Chain.Ethereum.asset().id, - ) - ) ), finalAmount = BigInteger.TEN.pow(Chain.Ethereum.asset().decimals), - feePriority = FeePriority.Normal, + fee = GasFee( + maxGasPrice = BigInteger.TEN, + limit = BigInteger("91000"), + minerFee = BigInteger.TEN, + relay = BigInteger.TEN, + priority = FeePriority.Normal, + feeAssetId = Chain.Ethereum.asset().id, + ), privateKey, ) } @@ -223,19 +211,16 @@ class TestEthSign { chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, - fees = listOf( - GasFee( - maxGasPrice = BigInteger.TEN, - limit = BigInteger("91000"), - minerFee = BigInteger.TEN, - relay = BigInteger.TEN, - priority = FeePriority.Normal, - feeAssetId = Chain.Ethereum.asset().id, - ) - ) ), finalAmount = BigInteger.TEN.pow(Chain.Ethereum.asset().decimals), - feePriority = FeePriority.Normal, + fee = GasFee( + maxGasPrice = BigInteger.TEN, + limit = BigInteger("91000"), + minerFee = BigInteger.TEN, + relay = BigInteger.TEN, + priority = FeePriority.Normal, + feeAssetId = Chain.Ethereum.asset().id, + ), privateKey, ) } @@ -271,19 +256,16 @@ class TestEthSign { chainData = EvmChainData( chainId = 1, nonce = BigInteger.ONE, - fees = listOf( - GasFee( - maxGasPrice = BigInteger.TEN, - limit = BigInteger("91000"), - minerFee = BigInteger.TEN, - relay = BigInteger.TEN, - priority = FeePriority.Normal, - feeAssetId = Chain.SmartChain.asset().id, - ) - ) ), finalAmount = BigInteger.ZERO, - feePriority = FeePriority.Normal, + fee = GasFee( + maxGasPrice = BigInteger.TEN, + limit = BigInteger("91000"), + minerFee = BigInteger.TEN, + relay = BigInteger.TEN, + priority = FeePriority.Normal, + feeAssetId = Chain.SmartChain.asset().id, + ), privateKey, ) } diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt deleted file mode 100644 index 69acc9fc0..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmBalance.kt +++ /dev/null @@ -1,246 +0,0 @@ -package com.gemwallet.android.blockchain.clients.evm - -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmBalancesService -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmRpcClient -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.gemwallet.android.model.getTotalAmount -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertNotNull -import junit.framework.TestCase.assertNull -import kotlinx.coroutines.runBlocking -import org.junit.Test -import java.math.BigInteger - -class TestEvmBalance { - - companion object { - init { - includeLibs() - } - } - - class CallService : EvmCallService { - override suspend fun callString(request: JSONRpcRequest>): Result> { - return Result.success(JSONRpcResponse("0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000")) - } - - override suspend fun callNumber(request: JSONRpcRequest>): Result> { - return Result.success(JSONRpcResponse(null)) - } - - override suspend fun callBatch(request: List>>): Result>> { - return Result.success( - listOf( - JSONRpcResponse( - result = "0x00000000000000000000000000000000000000000000000000000000001fdcf1", - ) - ) - ) - } - - } - class BalanceService : EvmBalancesService { - var nativeBalanceParam: String = "" - - override suspend fun getBalance(request: JSONRpcRequest>): Result> { - nativeBalanceParam = request.params[0] - return Result.success(JSONRpcResponse(EvmRpcClient.EvmNumber(BigInteger.TEN.pow(16)))) - } - - } - - @Test - fun testNativeBalance() { - val balanceService = BalanceService() - val balanceClient = EvmBalanceClient(Chain.Ethereum, CallService(), balanceService, SmartchainStakeClient(Chain.Ethereum, CallService())) - - val result = runBlocking { - balanceClient.getNativeBalance(Chain.Ethereum, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7") - } - assertEquals("0x9b1DB81180c31B1b428572Be105E209b5A6222b7", balanceService.nativeBalanceParam) - assertNotNull(result) - assertEquals("10000000000000000", result!!.balance.available) - assertEquals("0", result.balance.rewards) - assertEquals("0", result.balance.staked) - assertEquals("0", result.balance.pending) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.reserved) - assertEquals(BigInteger.valueOf(10_000_000_000_000_000), result.balance.getTotalAmount()) - assertEquals(0.01, result.balanceAmount.available) - assertEquals(0.0, result.balanceAmount.rewards) - assertEquals(0.0, result.balanceAmount.staked) - assertEquals(0.0, result.balanceAmount.pending) - assertEquals(0.0, result.balanceAmount.frozen) - assertEquals(0.0, result.balanceAmount.locked) - assertEquals(0.0, result.balanceAmount.reserved) - assertEquals(0.01, result.balanceAmount.getTotalAmount()) - } - - @Test - fun testNativeBalanceBadResponse() { - var nativeBalanceParam: String = "" - val balancesService = object : EvmBalancesService { - override suspend fun getBalance(request: JSONRpcRequest>): Result> { - nativeBalanceParam = request.params[0] - return Result.success(JSONRpcResponse(EvmRpcClient.EvmNumber(null))) - } - - } - val balanceClient = EvmBalanceClient(Chain.Ethereum, CallService(), balancesService, SmartchainStakeClient(Chain.Ethereum, CallService())) - - val result = runBlocking { - balanceClient.getNativeBalance(Chain.Ethereum, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7") - } - assertEquals("0x9b1DB81180c31B1b428572Be105E209b5A6222b7", nativeBalanceParam) - assertNull(result) - } - - @Test - fun test_native_balance_on_SmartChain_without_delegations() { - val balanceService = BalanceService() - val balanceClient = EvmBalanceClient(Chain.SmartChain, CallService(), balanceService, SmartchainStakeClient(Chain.SmartChain, CallService())) - - val result = runBlocking { - balanceClient.getNativeBalance(Chain.SmartChain, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7") - } - assertNotNull(result) - assertEquals("10000000000000000", result!!.balance.available) - assertEquals("0", result.balance.rewards) - assertEquals("0", result.balance.staked) - assertEquals("0", result.balance.pending) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.reserved) - assertEquals(BigInteger.valueOf(10_000_000_000_000_000), result.balance.getTotalAmount()) - } - - @Test - fun test_native_balance_on_SmartChain_with_delegations() { - val balanceService = BalanceService() - val callService = object : EvmCallService { - override suspend fun callString(request: JSONRpcRequest>): Result> { - val data = when ((request.params[0] as Map<*, *>)["data"]) { - "0xced0e70e000000000000000000000000ee7e9ccfb529f2c1cc02c0aea8aced7ec7e98b5e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d" -> { - "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ee7e9ccfb529f2c1cc02c0aea8aced7ec7e98b5e0000000000000000000000009941bce2601fc93478df9f5f6cc83f4ffc1d71d80000000000000000000000000000000000000000000000000deacafbb23d1ee90000000000000000000000000000000000000000000000000dc3088951e56b15" - } - "0xd9d4c020000000000000000000000000ee7e9ccfb529f2c1cc02c0aea8aced7ec7e98b5e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d" -> { - "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000" - } - "0xc473318f" -> "0x000000000000000000000000000000000000000000000000000000000000002d" - else -> "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000" - } - return Result.success(JSONRpcResponse(data)) - } - - override suspend fun callNumber(request: JSONRpcRequest>): Result> { - TODO("Not yet implemented") - } - - override suspend fun callBatch(request: List>>): Result>> { - return Result.success( - listOf( - JSONRpcResponse( - result = "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ee7e9ccfb529f2c1cc02c0aea8aced7ec7e98b5e0000000000000000000000009941bce2601fc93478df9f5f6cc83f4ffc1d71d80000000000000000000000000000000000000000000000000deacafbb23d1ee90000000000000000000000000000000000000000000000000dc3088951e56b15", - ), - JSONRpcResponse( - result = "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - ), - ) - ) - } - } - val balanceClient = EvmBalanceClient( - Chain.SmartChain, - callService, - balanceService, - SmartchainStakeClient(Chain.SmartChain, callService) - ) - - val result = runBlocking { - balanceClient.getDelegationBalances(Chain.SmartChain, "0xEe7E9CcFb529f2c1Cc02C0Aea8aCed7Ec7e98B5e") - } - assertNotNull(result) - assertEquals("0", result!!.balance.available) - assertEquals("0", result.balance.rewards) - assertEquals("1002837049419308777", result.balance.staked) - assertEquals("0", result.balance.pending) - assertEquals("0", result.balance.frozen) - assertEquals("0", result.balance.locked) - assertEquals("0", result.balance.reserved) - assertEquals(BigInteger.valueOf(1002837049419308777), result.balance.getTotalAmount()) - } - - @Test - fun testTokenBalance() { - val balanceService = BalanceService() - val callService = object : EvmCallService { - override suspend fun callString(request: JSONRpcRequest>): Result> { - TODO("Not yet implemented") - } - - override suspend fun callNumber(request: JSONRpcRequest>): Result> { - val result = when ((request.params[0] as Map<*, *>)["to"]) { - "0x76A797A59Ba2C17726896976B7B3747BfD1d220f" -> "0x00000000000000000000000000000000000000000000000000000002eedef652" - "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" -> "0x000000000000000000000000000000000000000000000000006a94d74f430000" - else -> "0x" - } - return Result.success(JSONRpcResponse(EvmRpcClient.EvmNumber(BigInteger(result.removePrefix("0x"), 16)))) - } - - override suspend fun callBatch(request: List>>): Result>> { - return Result.success( - listOf( - JSONRpcResponse( - result = "0x00000000000000000000000000000000000000000000000000000002eedef652", - ), - JSONRpcResponse( - result = "0x000000000000000000000000000000000000000000000000006a94d74f430000", - ), - ) - ) - } - } - val balanceClient = EvmBalanceClient(Chain.SmartChain, callService, balanceService, SmartchainStakeClient(Chain.SmartChain, CallService())) - - val result = runBlocking { - balanceClient.getTokenBalances( - Chain.SmartChain, - "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", - listOf( - Asset( - AssetId(Chain.SmartChain, "0x76A797A59Ba2C17726896976B7B3747BfD1d220f"), - name = "ton", - symbol = "ton", - decimals = 9, - type = AssetType.ERC20 - ), - Asset( - AssetId(Chain.SmartChain, "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"), - name = "Wrapped BNB", - symbol = "WBNB", - decimals = 18, - type = AssetType.ERC20 - ), - ) - ) - } - assertNotNull(result) - assertEquals("12597524050", result[0].balance.available) - assertEquals("0", result[0].balance.rewards) - assertEquals("0", result[0].balance.staked) - assertEquals("0", result[0].balance.pending) - assertEquals("0", result[0].balance.frozen) - assertEquals("0", result[0].balance.locked) - assertEquals("0", result[0].balance.reserved) - assertEquals(BigInteger.valueOf(12597524050), result[0].balance.getTotalAmount()) - assertEquals("30000000000000000", result[1].balance.available) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmEncodeApprove.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmEncodeApprove.kt deleted file mode 100644 index e84ee2cab..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmEncodeApprove.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.gemwallet.android.blockchain.clients.evm - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.gemwallet.android.blockchain.clients.ethereum.encodeApprove -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.math.toHexString -import junit.framework.TestCase.assertEquals -import org.junit.Test -import org.junit.runner.RunWith -import wallet.core.jni.AnyAddress -import wallet.core.jni.CoinType - -@RunWith(AndroidJUnit4::class) -class TestEvmEncodeApprove { - - companion object { - init { - includeLibs() - } - } - - @Test - fun testEncodeApprove() { - assertEquals( - "0x095ea7b30000000000000000000000009b1db81180c31b1b428572be105e209b5a6222b77fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - encodeApprove(AnyAddress("0x9b1DB81180c31B1b428572Be105E209b5A6222b7", CoinType.ETHEREUM).data()).toHexString() - ) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmExtentions.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmExtentions.kt deleted file mode 100644 index 993bbc677..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmExtentions.kt +++ /dev/null @@ -1,64 +0,0 @@ -package com.gemwallet.android.blockchain.clients.evm - -import com.gemwallet.android.blockchain.clients.ethereum.encodeTransactionData -import com.gemwallet.android.blockchain.clients.ethereum.getDestinationAddress -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.math.toHexString -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.EVMChain -import junit.framework.TestCase.assertEquals -import org.junit.Test -import java.math.BigInteger - -class TestEvmExtentions { - companion object { - init { - includeLibs() - } - } - - @Test - fun testEncodeTransactionData() { - val result = EVMChain.encodeTransactionData( - AssetId(Chain.SmartChain, "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"), - null, - BigInteger.TEN, - "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", - ) - assertEquals( - "0xa9059cbb0000000000000000000000009b1db81180c31b1b428572be105e209b5a6222b7000000000" + - "000000000000000000000000000000000000000000000000000000a", - result.toHexString() - ) - } - - @Test - fun testEncodeTransactionData_with_memo() { - val result = EVMChain.encodeTransactionData( - AssetId(Chain.SmartChain, "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"), - "0x00000000000000000000000000000000000000000000000000000002eedef652", - BigInteger.TEN, - "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", - ) - assertEquals("0x00000000000000000000000000000000000000000000000000000002eedef652", result.toHexString()) - } - - @Test - fun testGetDestinationAddress_token() { - val result = EVMChain.getDestinationAddress( - AssetId(Chain.SmartChain, "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"), - "0x9b1DB81180c31B1b428572Be105E209b5A6222b7" - ) - assertEquals(result, "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c") - } - - @Test - fun testGetDestinationAddress_native() { - val result = EVMChain.getDestinationAddress( - AssetId(Chain.SmartChain), - "0x9b1DB81180c31B1b428572Be105E209b5A6222b7" - ) - assertEquals(result, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7") - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmTransactionStatusClient.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmTransactionStatusClient.kt deleted file mode 100644 index cba71e4ee..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestEvmTransactionStatusClient.kt +++ /dev/null @@ -1,123 +0,0 @@ -package com.gemwallet.android.blockchain.clients.evm - -import com.gemwallet.android.blockchain.model.TransactionStateRequest -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmTransactionsService -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.ethereum.EthereumTransactionReciept -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.TransactionState -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertNotNull -import junit.framework.TestCase.assertNull -import kotlinx.coroutines.runBlocking -import org.junit.Test -import java.math.BigInteger - -class TestEvmTransactionStatusClient { - companion object { - init { - includeLibs() - } - } - - @Test - fun testEvm_transaction_tastus_confirm() { - val client = EvmTransactionStatusClient( - chain = Chain.SmartChain, - transactionsService = object : EvmTransactionsService { - override suspend fun transaction(request: JSONRpcRequest>): JSONRpcResponse { - return JSONRpcResponse( - EthereumTransactionReciept( - status = "0x1", - gasUsed = "10", - effectiveGasPrice = "2", - l1Fee = "1" - ) - ) - } - - } - ) - val resullt = runBlocking { - client.getStatus( - TransactionStateRequest( - Chain.SmartChain, - "0xe84b29d6f06aeb00ba071a409ff057649f19ebbc209114a6a8135a68af589e22", - "", - "0x502aECFE253E6AA0e8D2A06E12438FFeD0Fe16a0", - ) - ) - } - assertNotNull(resullt) - assertEquals(TransactionState.Confirmed, resullt.state) - assertEquals(BigInteger("21"), resullt.fee) - } - - @Test - fun testEvm_transaction_tastus_fail() { - val client = EvmTransactionStatusClient( - chain = Chain.SmartChain, - transactionsService = object : EvmTransactionsService { - override suspend fun transaction(request: JSONRpcRequest>): JSONRpcResponse { - return JSONRpcResponse( - EthereumTransactionReciept( - status = "0x0", - gasUsed = "10", - effectiveGasPrice = "2", - l1Fee = "1" - ) - ) - } - } - ) - val resullt = runBlocking { - client.getStatus( - TransactionStateRequest( - Chain.SmartChain, - "0xe84b29d6f06aeb00ba071a409ff057649f19ebbc209114a6a8135a68af589e22", - "", - "0x502aECFE253E6AA0e8D2A06E12438FFeD0Fe16a0", - ) - - ) - } - assertNotNull(resullt) - assertEquals(TransactionState.Reverted, resullt.state) - assertEquals(BigInteger("21"), resullt.fee) - } - - @Test - fun testEvm_transaction_tastus_pending() { - val client = EvmTransactionStatusClient( - chain = Chain.SmartChain, - transactionsService = object : EvmTransactionsService { - override suspend fun transaction(request: JSONRpcRequest>): JSONRpcResponse { - return JSONRpcResponse( - EthereumTransactionReciept( - status = "0x2", - gasUsed = "10", - effectiveGasPrice = "2", - l1Fee = "1" - ) - ) - } - - } - ) - val resullt = runBlocking { - client.getStatus( - TransactionStateRequest( - Chain.SmartChain, - "0xe84b29d6f06aeb00ba071a409ff057649f19ebbc209114a6a8135a68af589e22", - "", - "0x502aECFE253E6AA0e8D2A06E12438FFeD0Fe16a0", - ) - ) - } - assertNotNull(resullt) - assertEquals(TransactionState.Pending, resullt.state) - assertNull(resullt.fee) - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestFeeCalculator.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestFeeCalculator.kt deleted file mode 100644 index 2023c7f38..000000000 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/evm/TestFeeCalculator.kt +++ /dev/null @@ -1,421 +0,0 @@ -package com.gemwallet.android.blockchain.clients.evm - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.gemwallet.android.blockchain.clients.ethereum.EvmFeeCalculator -import com.gemwallet.android.blockchain.clients.ethereum.StakeHub -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmFeeService -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmRpcClient -import com.gemwallet.android.blockchain.includeLibs -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.DestinationAddress -import com.wallet.core.blockchain.ethereum.EthereumFeeHistory -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Asset -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetType -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertTrue -import kotlinx.coroutines.runBlocking -import org.junit.Test -import org.junit.runner.RunWith -import uniffi.gemstone.Config -import wallet.core.jni.CoinType -import java.math.BigInteger - -@RunWith(AndroidJUnit4::class) -class TestFeeCalculator { - companion object { - init { - includeLibs() - } - } - - private class FeeService( - private val feeHistory: EthereumFeeHistory? = null, - private val gasLimit: BigInteger = BigInteger.valueOf(21_000), - ) : EvmFeeService { - - var feeHistoryRequest: List = emptyList() - var gasLimitRequest: List = emptyList() - - override suspend fun getFeeHistory(request: JSONRpcRequest>): Result> { - feeHistoryRequest = request.params - return Result.success(JSONRpcResponse(feeHistory ?: throw Exception("Fee history fail"))) - } - - override suspend fun getGasLimit(request: JSONRpcRequest>): Result> { - gasLimitRequest = request.params - return Result.success(JSONRpcResponse(EvmRpcClient.EvmNumber(gasLimit))) - } - - override suspend fun getNonce(request: JSONRpcRequest>): Result> { - return Result.success(JSONRpcResponse(EvmRpcClient.EvmNumber(BigInteger.ZERO))) - } - } - - private class CallService : EvmCallService { - override suspend fun callString(request: JSONRpcRequest>): Result> { - throw Exception("Call string fail") - } - - override suspend fun callNumber(request: JSONRpcRequest>): Result> { - return Result.success(JSONRpcResponse(EvmRpcClient.EvmNumber(BigInteger.ONE))) - } - - override suspend fun callBatch(request: List>>): Result>> { - TODO("Not yet implemented") - } - } - - @Test - fun testEvm_transfer_fee_calculation_network_fail_gas_limit() { - val feeService = object : EvmFeeService { - override suspend fun getFeeHistory(request: JSONRpcRequest>): Result> { - return Result.failure(Exception("Fee history fail")) - } - - override suspend fun getGasLimit(request: JSONRpcRequest>): Result> { - return Result.failure(Exception("Gas limit fail")) - } - - override suspend fun getNonce(request: JSONRpcRequest>): Result> { - return Result.failure(Exception("Nonce fail")) - } - } - val callService = object : EvmCallService { - override suspend fun callString(request: JSONRpcRequest>): Result> { - throw Exception("Call string fail") - } - - override suspend fun callNumber(request: JSONRpcRequest>): Result> { - throw Exception("Call number fail") - } - - override suspend fun callBatch(request: List>>): Result>> { - throw Exception("Call number fail") - } - } - try { - runBlocking { - EvmFeeCalculator( - feeService = feeService, - callService = callService, - coinType = CoinType.SMARTCHAIN, - ).calculate( - ConfirmParams.Builder( - Chain.SmartChain.asset(), - Account(Chain.SmartChain, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), - amount = BigInteger.TEN, - ).transfer( - DestinationAddress("0x9b1DB81180c31B1b428572Be105E209b5A6222b7") - ), - AssetId(Chain.SmartChain), - "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", - outputAmount = BigInteger.TEN, - null, - chainId = Config().getChainConfig(Chain.SmartChain.string).networkId.toInt(), - BigInteger.ZERO, - ) - } - assertTrue(false) - } catch (err: Throwable) { - assertTrue("Unable to calculate base fee" == err.message || "Fail calculate gas limit" == err.message) - } - } - - @Test - fun test_Evm_fee_transfer_calculation() { - val feeService = FeeService( - EthereumFeeHistory( - reward = listOf(listOf("0x3b9aca00")), - baseFeePerGas = listOf("0xa", "0xc"), - oldestBlock = "", - gasUsedRatio = emptyList() - ), - gasLimit = BigInteger.valueOf(25_000) - ) - val feeCalculator = EvmFeeCalculator( - feeService = feeService, - callService = CallService(), - coinType = CoinType.SMARTCHAIN, - ) - val result = runBlocking { - feeCalculator.calculate( - ConfirmParams.Builder( - Chain.SmartChain.asset(), - Account(Chain.SmartChain, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), - amount = BigInteger.TEN, - ).transfer( - DestinationAddress("0x9b1DB81180c31B1b428572Be105E209b5A6222b7") - ), - AssetId(Chain.SmartChain), - "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", - outputAmount = BigInteger.TEN, - null, - chainId = Config().getChainConfig(Chain.SmartChain.string).networkId.toInt(), - BigInteger.ZERO, - ) - } - assertEquals(FeePriority.Normal, result[1].priority) - assertEquals(BigInteger("37500000450000"), result[1].amount) - assertEquals(BigInteger("1000000000"), result[1].minerFee) - assertEquals(BigInteger("1000000012"), result[1].maxGasPrice) - assertEquals(BigInteger("37500"), result[1].limit) - } - - @Test - fun test_Evm_fee_transfer_max_amount_calculation() { - val feeService = FeeService( - EthereumFeeHistory( - reward = listOf(listOf("0x3b9aca00")), - baseFeePerGas = listOf("0xa", "0xc"), - oldestBlock = "", - gasUsedRatio = emptyList() - ), - gasLimit = BigInteger.valueOf(25_000) - ) - val feeCalculator = EvmFeeCalculator( - feeService = feeService, - callService = CallService(), - coinType = CoinType.SMARTCHAIN, - ) - val result = runBlocking { - feeCalculator.calculate( - ConfirmParams.Builder( - Chain.SmartChain.asset(), - Account(Chain.SmartChain, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), - amount = BigInteger.TEN, - ).transfer( - destination = DestinationAddress("0x9b1DB81180c31B1b428572Be105E209b5A6222b7"), - isMax = true - ), - AssetId(Chain.SmartChain), - "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", - outputAmount = BigInteger.TEN, - null, - chainId = Config().getChainConfig(Chain.SmartChain.string).networkId.toInt(), - BigInteger.ZERO, - ) - } - assertEquals(FeePriority.Normal, result[1].priority) - assertEquals(BigInteger("37500000450000"), result[1].amount) - assertEquals(BigInteger("1000000012"), result[1].minerFee) - assertEquals(BigInteger("1000000012"), result[1].maxGasPrice) - assertEquals(BigInteger("37500"), result[1].limit) - } - - - @Test - fun test_Evm_gas_limit_native_transfer_calculation() { - val feeService = FeeService( - EthereumFeeHistory( - reward = listOf(listOf("0x3b9aca00")), - baseFeePerGas = listOf("0x0", "0x0"), - oldestBlock = "", - gasUsedRatio = emptyList() - ), - gasLimit = BigInteger.valueOf(21_000) - ) - val feeCalculator = EvmFeeCalculator( - feeService = feeService, - callService = CallService(), - coinType = CoinType.SMARTCHAIN, - ) - val result = runBlocking { - feeCalculator.calculate( - ConfirmParams.Builder( - Chain.SmartChain.asset(), - Account(Chain.SmartChain, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), - amount = BigInteger.TEN, - ).transfer( - DestinationAddress("0xa857a4E4B3f7C0eb7e132A7A4abcA287225dDB2A") - ), - AssetId(Chain.SmartChain), - "0xa857a4E4B3f7C0eb7e132A7A4abcA287225dDB2A", - outputAmount = BigInteger.TEN, - null, - chainId = Config().getChainConfig(Chain.SmartChain.string).networkId.toInt(), - BigInteger.ZERO, - ) - } - assertEquals(FeePriority.Normal, result[1].priority) - assertEquals(BigInteger("21000000000000"), result[1].amount) - assertEquals(BigInteger.valueOf(21_000), result[1].limit) - assertEquals("0x9b1DB81180c31B1b428572Be105E209b5A6222b7", (feeService.gasLimitRequest[0] as Map<*, *>)["from"]) - assertEquals("0xa857a4E4B3f7C0eb7e132A7A4abcA287225dDB2A", (feeService.gasLimitRequest[0] as Map<*, *>)["to"]) - assertEquals("0xa", (feeService.gasLimitRequest[0] as Map<*, *>)["value"]) - assertEquals("0x", (feeService.gasLimitRequest[0] as Map<*, *>)["data"]) - } - - @Test - fun test_Evm_Oracle() { - val feeService = FeeService( - EthereumFeeHistory( - reward = listOf(listOf("0x3b9aca00")), - baseFeePerGas = listOf("0x0", "0x0"), - oldestBlock = "", - gasUsedRatio = emptyList() - ), - gasLimit = BigInteger.valueOf(21_000) - ) - val feeCalculator = EvmFeeCalculator( - feeService = feeService, - callService = CallService(), - coinType = CoinType.SMARTCHAIN, - ) - val result = runBlocking { - feeCalculator.calculate( - ConfirmParams.Builder( - Chain.OpBNB.asset(), - Account(Chain.OpBNB, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), - amount = BigInteger.TEN, - ).transfer( - DestinationAddress("0xa857a4E4B3f7C0eb7e132A7A4abcA287225dDB2A") - ), - AssetId(Chain.OpBNB), - "0xa857a4E4B3f7C0eb7e132A7A4abcA287225dDB2A", - outputAmount = BigInteger.TEN, - null, - chainId = Config().getChainConfig(Chain.OpBNB.string).networkId.toInt(), - BigInteger.ZERO, - ) - } - assertEquals(FeePriority.Normal, result[1].priority) - assertEquals(BigInteger("21000000001"), result[1].amount) - assertEquals(BigInteger.valueOf(21_000), result[1].limit) - assertEquals("0x9b1DB81180c31B1b428572Be105E209b5A6222b7", (feeService.gasLimitRequest[0] as Map<*, *>)["from"]) - assertEquals("0xa857a4E4B3f7C0eb7e132A7A4abcA287225dDB2A", (feeService.gasLimitRequest[0] as Map<*, *>)["to"]) - assertEquals("0xa", (feeService.gasLimitRequest[0] as Map<*, *>)["value"]) - assertEquals("0x", (feeService.gasLimitRequest[0] as Map<*, *>)["data"]) - } - - @Test - fun test_Evm_gas_limit_token_transfer_calculation() { - val feeService = FeeService( - EthereumFeeHistory( - reward = listOf(listOf("0x3b9aca00")), - baseFeePerGas = listOf("0x0", "0x0"), - oldestBlock = "", - gasUsedRatio = emptyList() - ), - gasLimit = BigInteger.valueOf(21_000) - ) - val feeCalculator = EvmFeeCalculator( - feeService = feeService, - callService = CallService(), - coinType = CoinType.SMARTCHAIN, - ) - val result = runBlocking { - feeCalculator.calculate( - ConfirmParams.Builder( - Asset(AssetId(Chain.SmartChain, "0x2170Ed0880ac9A755fd29B2688956BD959F933F8"), name = "usdt", symbol = "usdt", decimals = 8, type = AssetType.TOKEN), - Account(Chain.SmartChain, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), - amount = BigInteger.TEN, - ).transfer( - DestinationAddress("0xa857a4E4B3f7C0eb7e132A7A4abcA287225dDB2A") - ), - AssetId(Chain.SmartChain, "0x2170Ed0880ac9A755fd29B2688956BD959F933F8"), - "0xa857a4E4B3f7C0eb7e132A7A4abcA287225dDB2A", - outputAmount = BigInteger.TEN, - null, - chainId = Config().getChainConfig(Chain.SmartChain.string).networkId.toInt(), - BigInteger.ZERO, - ) - } - assertEquals(FeePriority.Normal, result[1].priority) - assertEquals(BigInteger("21000000000000"), result[1].amount) - assertEquals(BigInteger.valueOf(21_000), result[1].limit) - assertEquals("0x9b1DB81180c31B1b428572Be105E209b5A6222b7", (feeService.gasLimitRequest[0] as Map<*, *>)["from"]) - assertEquals("0x2170ed0880ac9a755fd29b2688956bd959f933f8", (feeService.gasLimitRequest[0] as Map<*, *>)["to"]) - assertEquals("0x0", (feeService.gasLimitRequest[0] as Map<*, *>)["value"]) - assertEquals( - "0xa9059cbb000000000000000000000000a857a4e4b3f7c0eb7e132a7a4abca287225ddb2a000000000000000000000000000000000000000000000000000000000000000a", - (feeService.gasLimitRequest[0] as Map<*, *>)["data"] - ) - } - - @Test - fun test_Evm_gas_limit_delegate_calculation() { - val feeService = FeeService( - EthereumFeeHistory( - reward = listOf(listOf("0x3b9aca00")), - baseFeePerGas = listOf("0x0", "0x0"), - oldestBlock = "", - gasUsedRatio = emptyList() - ), - gasLimit = BigInteger.valueOf(21_000) - ) - val feeCalculator = EvmFeeCalculator( - feeService = feeService, - callService = CallService(), - coinType = CoinType.SMARTCHAIN, - ) - val params = ConfirmParams.Builder( - Chain.SmartChain.asset(), - Account(Chain.SmartChain, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), - amount = BigInteger.TEN, - ).delegate("0xa857a4E4B3f7C0eb7e132A7A4abcA287225dDB2A") - val result = runBlocking { - feeCalculator.calculate( - params = params, - assetId = AssetId(Chain.SmartChain), - recipient = StakeHub.address, - outputAmount = BigInteger.TEN, - payload = "0xb", - chainId = Config().getChainConfig(Chain.SmartChain.string).networkId.toInt(), - BigInteger.ZERO, - ) - } - assertEquals(FeePriority.Normal, result[1].priority) - assertEquals(BigInteger("21000000000000"), result[1].amount) - assertEquals(BigInteger.valueOf(21_000), result[1].limit) - assertEquals("0x9b1DB81180c31B1b428572Be105E209b5A6222b7", (feeService.gasLimitRequest[0] as Map<*, *>)["from"]) - assertEquals("0x0000000000000000000000000000000000002002", (feeService.gasLimitRequest[0] as Map<*, *>)["to"]) - assertEquals("0xa", (feeService.gasLimitRequest[0] as Map<*, *>)["value"]) - assertEquals("0xb", (feeService.gasLimitRequest[0] as Map<*, *>)["data"]) - } - - @Test - fun testEvm_transfer_fee_calculation_network_fail_fee_history() { - val feeService = FeeService( - gasLimit = BigInteger.valueOf(21_000) - ) - try { - runBlocking { - EvmFeeCalculator( - feeService = feeService, - callService = CallService(), - coinType = CoinType.SMARTCHAIN, - ).calculate( - ConfirmParams.Builder( - Chain.SmartChain.asset(), - Account(Chain.SmartChain, "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", ""), - amount = BigInteger.TEN, - ).transfer( - DestinationAddress("0x9b1DB81180c31B1b428572Be105E209b5A6222b7") - ), - AssetId(Chain.SmartChain), - "0x9b1DB81180c31B1b428572Be105E209b5A6222b7", - outputAmount = BigInteger.TEN, - null, - chainId = Config().getChainConfig(Chain.SmartChain.string).networkId.toInt(), - BigInteger.ZERO, - ) - } - assertTrue(false) - } catch (err: Throwable) { - assertEquals("Fee history fail", err.message) - } - } - - @Test - fun testEvm_transfer_fee_calculation_network_fail_L1Fee() { - - } -} \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/near/TestNearSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/near/TestNearSigner.kt index 44b7422e7..599bf0690 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/near/TestNearSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/near/TestNearSigner.kt @@ -42,15 +42,14 @@ class TestNearSigner { ), chainData = NearChainData( block = "2ADR7pgpkd2uFFkQcAyCxL5YB4d9SewALTLEuFbUUJLe", - sequence = 134180900000002, - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Near), - amount = BigInteger.TEN - ), + sequence = 134180900000002UL, ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Near), + amount = BigInteger.TEN + ), privateKey.data(), ) } diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt index f9f88a95d..a49e2ebb4 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt @@ -1,6 +1,5 @@ package com.gemwallet.android.blockchain.clients.polkadot -import com.gemwallet.android.blockchain.clients.polkadot.models.PolkadotSigningData import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset @@ -42,32 +41,30 @@ class TestPolkadotSigner { DestinationAddress(from), ), chainData = PolkadotChainData( - sequence = 0, - data = PolkadotSigningData( - genesisHash = "0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3", - blockHash = "0x6e3ffeaa3be9d19bd110e5b6e7cbbc92cceed0d2ec557276c296bf7970ace2e5", - blockNumber = BigInteger.valueOf(24666537), - specVersion = BigInteger.valueOf(1003004), - transactionVersion = BigInteger.valueOf(26), - period = 64, - ), - blockNumber = 24666537, - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Polkadot), - amount = BigInteger.TEN - ), + sequence = 0UL, + genesisHash = "0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3", + blockHash = "0x6e3ffeaa3be9d19bd110e5b6e7cbbc92cceed0d2ec557276c296bf7970ace2e5", + blockNumber = 24666537UL, + specVersion = 1003004UL, + transactionVersion = 26UL, + period = 64, ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Polkadot), + amount = BigInteger.TEN + ), privateKey.data(), ) } - assertEquals("0x35028400cd3cfbbaa8f217c2a29ceae4b4063b597b629861916bad98f9826e03d1ab120e0" + + assertEquals( + "0x35028400cd3cfbbaa8f217c2a29ceae4b4063b597b629861916bad98f9826e03d1ab120e0" + "0c094fad2608116257a997619a48d172340c69bca386c9f6b352903ee09a349b4ac90bff77872773" + "1dac78a56b6c5d901af843ca9c9a69b9e46cca042c4f70c099502000000050000cd3cfbbaa8f217c" + - "2a29ceae4b4063b597b629861916bad98f9826e03d1ab120e419c", sign.first().toHexString() + "2a29ceae4b4063b597b629861916bad98f9826e03d1ab120e419c", + String(sign.first()) ) } } \ No newline at end of file diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt index d1e5629b7..643bd066d 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/solana/TestSolanaSigner.kt @@ -1,6 +1,5 @@ package com.gemwallet.android.blockchain.clients.solana -import com.gemwallet.android.blockchain.clients.solana.SolanaChainData import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset @@ -47,14 +46,22 @@ class TestSolanaSigner { } ) val params = ConfirmParams.Builder( - asset = Chain.Solana.asset(), - from = Account(Chain.Solana, "4Yu2e1Wz5T1Ci2hAPswDqvMgSnJ1Ftw7ZZh8x7xKLx7S", ""), - amount = BigInteger.valueOf(10_000_000) - ) + asset = Chain.Solana.asset(), + from = Account(Chain.Solana, "4Yu2e1Wz5T1Ci2hAPswDqvMgSnJ1Ftw7ZZh8x7xKLx7S", ""), + amount = BigInteger.valueOf(10_000_000) + ) .transfer(destination = DestinationAddress("4Yu2e1Wz5T1Ci2hAPswDqvMgSnJ1Ftw7ZZh8x7xKLx7S")) as ConfirmParams.TransferParams.Native val chainData = SolanaChainData( blockhash = "kiEPF6aKvEsj5nbi4FBvgRRm9ha36Y3cgDU9qnUKt32", - fees = listOf( + recipientTokenAddress = null, + senderTokenAddress = "", + tokenProgram = SolanaTokenProgramId.Token + ) + val result = runBlocking { + signer.signNativeTransfer( + params, + chainData, + BigInteger.ZERO, GasFee( amount = BigInteger("105005000"), minerFee = BigInteger("1050000000"), @@ -63,22 +70,21 @@ class TestSolanaSigner { feeAssetId = AssetId(Chain.Solana), priority = FeePriority.Normal, ), - ), - recipientTokenAddress = null, - senderTokenAddress = "", - tokenProgram = SolanaTokenProgramId.Token + privateKey + ) + } + assertEquals( + "0x4159436b734f696556323339774436566c6841614a41464844544a647a632f61577a3331" + + "6f693676686e783978676d4c544a5372643165504634454e73734a704867667575424e6e55556b3" + + "159304a52784e504a59513442414149455365626b44466a2b415242396b4b486b394f4167745057" + + "456e614370426a475a3869707a61372f4e43577330767554324f647746546758414767305a61753" + + "17474703157354f7153437a77434c53384e5738357a71514d47526d2f6c495263792f2b7974756e" + + "4c446d2b65386a4f573778666353617978446d7a704141414141414141414141414141414141414" + + "141414141414141414141414141414141414141414141414141414141414c4d706730536d427863" + + "684e486e756872566468464259677863634c722b5370616932436959444a4b51514d4341416b446" + + "74c71565067414141414143414155436f49594241414d434141454d416741414141414141414141" + + "41414141", result.first().toHexString() ) - val result = runBlocking { signer.signNativeTransfer(params, chainData, BigInteger.ZERO, FeePriority.Normal, privateKey) } - assertEquals("0x4159436b734f696556323339774436566c6841614a41464844544a647a632f61577a3331" + - "6f693676686e783978676d4c544a5372643165504634454e73734a704867667575424e6e55556b3" + - "159304a52784e504a59513442414149455365626b44466a2b415242396b4b486b394f4167745057" + - "456e614370426a475a3869707a61372f4e43577330767554324f647746546758414767305a61753" + - "17474703157354f7153437a77434c53384e5738357a71514d47526d2f6c495263792f2b7974756e" + - "4c446d2b65386a4f573778666353617978446d7a704141414141414141414141414141414141414" + - "141414141414141414141414141414141414141414141414141414141414c4d706730536d427863" + - "684e486e756872566468464259677863634c722b5370616932436959444a4b51514d4341416b446" + - "74c71565067414141414143414155436f49594241414d434141454d416741414141414141414141" + - "41414141", result.first().toHexString()) } @Test @@ -96,14 +102,28 @@ class TestSolanaSigner { } ) val params = ConfirmParams.Builder( - asset = Asset(AssetId(Chain.Solana, "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"), "", "", 8, AssetType.TOKEN), - from = Account(Chain.Solana, "4Yu2e1Wz5T1Ci2hAPswDqvMgSnJ1Ftw7ZZh8x7xKLx7S", ""), - amount = BigInteger.valueOf(10_000_000) - ) + asset = Asset( + AssetId(Chain.Solana, "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"), + "", + "", + 8, + AssetType.TOKEN + ), + from = Account(Chain.Solana, "4Yu2e1Wz5T1Ci2hAPswDqvMgSnJ1Ftw7ZZh8x7xKLx7S", ""), + amount = BigInteger.valueOf(10_000_000) + ) .transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) as ConfirmParams.TransferParams.Token val chainData = SolanaChainData( blockhash = "kiEPF6aKvEsj5nbi4FBvgRRm9ha36Y3cgDU9qnUKt32", - fees = listOf( + recipientTokenAddress = "DVWPV7brSbPDkA7a3qdn6UJsVc3J3DyhQhjNaZeZqwzo", + senderTokenAddress = "DVWPV7brSbPDkA7a3qdn6UJsVc3J3DyhQhjNaZeZqwzo", + tokenProgram = SolanaTokenProgramId.Token + ) + val result = runBlocking { + signer.signTokenTransfer( + params, + chainData, + BigInteger.ZERO, GasFee( amount = BigInteger("105005000"), minerFee = BigInteger("1050000000"), @@ -111,24 +131,23 @@ class TestSolanaSigner { limit = BigInteger("100000"), feeAssetId = AssetId(Chain.Solana), priority = FeePriority.Normal, - ) - ), - recipientTokenAddress = "DVWPV7brSbPDkA7a3qdn6UJsVc3J3DyhQhjNaZeZqwzo", - senderTokenAddress = "DVWPV7brSbPDkA7a3qdn6UJsVc3J3DyhQhjNaZeZqwzo", - tokenProgram = SolanaTokenProgramId.Token + ), + privateKey + ) + } + assertEquals( + "0x416238786c7268464374766e72677357477874416f6b6852423654737057545862643066" + + "6e31557835466c736b734b317838714d6668326e313662454d384d6b6a4a4d467450664b7046684" + + "25a376576716557713051514241414d465365626b44466a2b415242396b4b486b394f4167745057" + + "456e614370426a475a3869707a61372f4e435775356d6277492b744e3454586473757149654b725" + + "254647a734b644444707a385843635179334a766a50304d3442446d43763762496e4637316a4753" + + "395546466f2f6c6c6f7a75344c5378774b657373346549494a6b41775a47622b5568467a4c2f374" + + "b323663734f623537794d3562764639784a724c454f624f6b41414141414733666268313257686b" + + "396e4c3455624f36336d73484c5346375639624e3545366a50574666763841715173796d44524b5" + + "948467945306565364774563245554669444678777576354b6c714c594b4a674d6b704241774d41" + + "43514f417570552b4141414141414d4142514b67686745414241514241674541436777414141414" + + "1414141414141593d", result.first().toHexString() ) - val result = runBlocking { signer.signTokenTransfer(params, chainData, BigInteger.ZERO, FeePriority.Normal, privateKey) } - assertEquals("0x416238786c7268464374766e72677357477874416f6b6852423654737057545862643066" + - "6e31557835466c736b734b317838714d6668326e313662454d384d6b6a4a4d467450664b7046684" + - "25a376576716557713051514241414d465365626b44466a2b415242396b4b486b394f4167745057" + - "456e614370426a475a3869707a61372f4e435775356d6277492b744e3454586473757149654b725" + - "254647a734b644444707a385843635179334a766a50304d3442446d43763762496e4637316a4753" + - "395546466f2f6c6c6f7a75344c5378774b657373346549494a6b41775a47622b5568467a4c2f374" + - "b323663734f623537794d3562764639784a724c454f624f6b41414141414733666268313257686b" + - "396e4c3455624f36336d73484c5346375639624e3545366a50574666763841715173796d44524b5" + - "948467945306565364774563245554669444678777576354b6c714c594b4a674d6b704241774d41" + - "43514f417570552b4141414141414d4142514b67686745414241514241674541436777414141414" + - "1414141414141593d", result.first().toHexString()) } @Test @@ -146,14 +165,28 @@ class TestSolanaSigner { } ) val params = ConfirmParams.Builder( - asset = Asset(AssetId(Chain.Solana, "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo"), "", "", 8, AssetType.TOKEN), - from = Account(Chain.Solana, "4Yu2e1Wz5T1Ci2hAPswDqvMgSnJ1Ftw7ZZh8x7xKLx7S", ""), - amount = BigInteger.valueOf(10_000_000) - ) + asset = Asset( + AssetId(Chain.Solana, "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo"), + "", + "", + 8, + AssetType.TOKEN + ), + from = Account(Chain.Solana, "4Yu2e1Wz5T1Ci2hAPswDqvMgSnJ1Ftw7ZZh8x7xKLx7S", ""), + amount = BigInteger.valueOf(10_000_000) + ) .transfer(destination = DestinationAddress("AGkXQZ9qm99xukisDUHvspWHESrcjs8Y4AmQQgef3BRh")) as ConfirmParams.TransferParams.Token val chainData = SolanaChainData( blockhash = "kiEPF6aKvEsj5nbi4FBvgRRm9ha36Y3cgDU9qnUKt32", - fees = listOf( + recipientTokenAddress = "87vTugUvkkepa84mBRfENnvkPQRj5EZSkiG8XyFAhbQQ", + senderTokenAddress = "87vTugUvkkepa84mBRfENnvkPQRj5EZSkiG8XyFAhbQQ", + tokenProgram = SolanaTokenProgramId.Token2022 + ) + val result = runBlocking { + signer.signTokenTransfer( + params, + chainData, + BigInteger.ZERO, GasFee( amount = BigInteger("105005000"), minerFee = BigInteger("1050000000"), @@ -162,23 +195,22 @@ class TestSolanaSigner { feeAssetId = AssetId(Chain.Solana), priority = FeePriority.Normal, ), - ), - recipientTokenAddress = "87vTugUvkkepa84mBRfENnvkPQRj5EZSkiG8XyFAhbQQ", - senderTokenAddress = "87vTugUvkkepa84mBRfENnvkPQRj5EZSkiG8XyFAhbQQ", - tokenProgram = SolanaTokenProgramId.Token2022 + privateKey + ) + } + assertEquals( + "0x4152744d346e59365642416d427563754c675a7759623165304764516d6b782b6251764f" + + "6241657558466e6a4b5a4744507930653972305249444f384757705056384439453345754b33416" + + "e492b354b6b6d72485667414241414d465365626b44466a2b415242396b4b486b394f4167745057" + + "456e614370426a475a3869707a61372f4e43577470783737467363375a7773776d4234324a65393" + + "04538487a622b59486131534a74465451777a385351705265535344747369697148743063646755" + + "2b566b666b355849514b6e4f505a394e57366654704c696e536541775a47622b5568467a4c2f374" + + "b323663734f623537794d3562764639784a724c454f624f6b41414141414733666268376e575033" + + "68684358627a6b624d33617468723854594f354453662b76666b6f324b474c2f4173796d44524b5" + + "948467945306565364774563245554669444678777576354b6c714c594b4a674d6b704241774d41" + + "43514f417570552b4141414141414d4142514b67686745414241514241674541436777414141414" + + "1414141414141593d", result.first().toHexString() ) - val result = runBlocking { signer.signTokenTransfer(params, chainData, BigInteger.ZERO, FeePriority.Normal, privateKey) } - assertEquals("0x4152744d346e59365642416d427563754c675a7759623165304764516d6b782b6251764f" + - "6241657558466e6a4b5a4744507930653972305249444f384757705056384439453345754b33416" + - "e492b354b6b6d72485667414241414d465365626b44466a2b415242396b4b486b394f4167745057" + - "456e614370426a475a3869707a61372f4e43577470783737467363375a7773776d4234324a65393" + - "04538487a622b59486131534a74465451777a385351705265535344747369697148743063646755" + - "2b566b666b355849514b6e4f505a394e57366654704c696e536541775a47622b5568467a4c2f374" + - "b323663734f623537794d3562764639784a724c454f624f6b41414141414733666268376e575033" + - "68684358627a6b624d33617468723854594f354453662b76666b6f324b474c2f4173796d44524b5" + - "948467945306565364774563245554669444678777576354b6c714c594b4a674d6b704241774d41" + - "43514f417570552b4141414141414d4142514b67686745414241514241674541436777414141414" + - "1414141414141593d", result.first().toHexString()) } @Test diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/stellar/TestStellarSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/stellar/TestStellarSigner.kt index c7f8686e2..0949c1649 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/stellar/TestStellarSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/stellar/TestStellarSigner.kt @@ -43,17 +43,15 @@ class TestStellarSigner { DestinationAddress(from), ), chainData = StellarChainData( - sequence = 1, - fees = listOf( - Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Stellar), - amount = BigInteger.TEN - ), - ), + sequence = 1UL, + isDestinationAddressExist = true, ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Stellar), + amount = BigInteger.TEN + ), privateKey.data(), ) } diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/sui/TestSuiSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/sui/TestSuiSigner.kt index ce307a8c8..cbf25edf0 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/sui/TestSuiSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/sui/TestSuiSigner.kt @@ -49,14 +49,13 @@ class TestSuiSigner { "5eRLenwRl5FY6EUk6/RG4a4cjnsc8KNU0u4ecehWUp7tgeekPLqaeZa56D9+ltag9/a" + "lQA7RvBaO4CAAAAAAAAQHh9AQAAAAAA_0xc6af5cd37f2bab89411aff2a642522f88" + "6e3a8bdfea1d0549729e99f3a241bd5", - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Sui), - amount = BigInteger.TEN - ), ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Sui), + amount = BigInteger.TEN + ), privateKey.data(), ) } @@ -99,14 +98,13 @@ class TestSuiSigner { "+S2gTgAQzNMurZ1aIQOw24OKmyO5LC3mt0mBR+cLuHnHoVlKe7YHnpDy6mnmWueg/fpb" + "WoPf2pUAO0bwWjuAgAAAAAAAEB4fQEAAAAAAA==_0xd3877ebdd9f50a6d7d919d6e28" + "a26dd62ec43db0986466a35fa78c84394d3046", - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Sui), - amount = BigInteger.TEN - ), ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Sui), + amount = BigInteger.TEN + ), privateKey.data(), ) } diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/ton/TestTonSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/ton/TestTonSigner.kt index f925d361d..530953017 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/ton/TestTonSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/ton/TestTonSigner.kt @@ -43,16 +43,15 @@ class TestTonSigner { DestinationAddress(from), ), chainData = TonChainData( - sequence = 1, - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Ton), - amount = BigInteger.TEN - ), + sequence = 1UL, expireAt = 1000000000, ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Ton), + amount = BigInteger.TEN + ), privateKey.data(), ) } @@ -82,17 +81,16 @@ class TestTonSigner { DestinationAddress(from), ), chainData = TonChainData( - sequence = 1, + sequence = 1UL, jettonAddress = "EQAlgB03OjJKdXrlwZiGJD5snSzPKF2VL5bErJn_cqJANGH9", expireAt = 1000000000, - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Ton), - amount = BigInteger.TEN - ), ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Ton), + amount = BigInteger.TEN + ), privateKey.data(), ) } diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronSigner.kt index 7b5a046e4..7764ae8f0 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/tron/TestTronSigner.kt @@ -43,21 +43,20 @@ class TestTronSigner { DestinationAddress(from), ), chainData = TronChainData( - blockNumber = 69501435, - blockVersion = 31, + blockNumber = 69501435UL, + blockVersion = 31UL, txTrieRoot = "fe35cfe51299075978398390271d3f09bdc34e6f43fe8b76eb469314b32ceaff", witnessAddress = "41456798cb4ab28109d8cc643cd7da7bd6069ceae9", parentHash = "00000000042481fa52ef745a31aa66fc2acf8d156b6116bc5b3ede2aebbb894c", - blockTimestamp = 1739156280000, + blockTimestamp = 1739156280000UL, votes = emptyMap(), - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Tron), - amount = BigInteger.TEN - ), ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Tron), + amount = BigInteger.TEN + ), privateKey.data(), ) } @@ -97,21 +96,20 @@ class TestTronSigner { DestinationAddress(from), ), chainData = TronChainData( - blockNumber = 69501435, - blockVersion = 31, + blockNumber = 69501435UL, + blockVersion = 31UL, txTrieRoot = "fe35cfe51299075978398390271d3f09bdc34e6f43fe8b76eb469314b32ceaff", witnessAddress = "41456798cb4ab28109d8cc643cd7da7bd6069ceae9", parentHash = "00000000042481fa52ef745a31aa66fc2acf8d156b6116bc5b3ede2aebbb894c", - blockTimestamp = 1739156280000, + blockTimestamp = 1739156280000UL, votes = emptyMap(), - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Tron), - amount = BigInteger.TEN - ), ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Tron), + amount = BigInteger.TEN + ), privateKey.data(), ) } @@ -155,24 +153,23 @@ class TestTronSigner { validatorId = "TCEo1hMAdaJrQmvnGTCcGT2LqrGU4N7Jqf", ), chainData = TronChainData( - blockNumber = 69501435, - blockVersion = 31, + blockNumber = 69501435UL, + blockVersion = 31UL, txTrieRoot = "fe35cfe51299075978398390271d3f09bdc34e6f43fe8b76eb469314b32ceaff", witnessAddress = "41456798cb4ab28109d8cc643cd7da7bd6069ceae9", parentHash = "00000000042481fa52ef745a31aa66fc2acf8d156b6116bc5b3ede2aebbb894c", - blockTimestamp = 1739156280000, + blockTimestamp = 1739156280000UL, votes = mapOf( - "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH" to 1, - "TCEo1hMAdaJrQmvnGTCcGT2LqrGU4N7Jqf" to 1, - ), - fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Tron), - amount = BigInteger.TEN + "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH" to 1UL, + "TCEo1hMAdaJrQmvnGTCcGT2LqrGU4N7Jqf" to 1UL, ), ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Tron), + amount = BigInteger.TEN + ), privateKey.data(), ) } diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt index 2a34f9365..50c45ffa0 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt @@ -43,16 +43,13 @@ class TestXrpSigner { chainData = XrpChainData( sequence = 1, blockNumber = 1, - fees = listOf( - Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(Chain.Xrp), - amount = BigInteger.TEN, - ) - ), ), finalAmount = BigInteger.valueOf(10_000), - FeePriority.Normal, + fee = Fee( + priority = FeePriority.Normal, + feeAssetId = AssetId(Chain.Xrp), + amount = BigInteger.TEN, + ), privateKey.data(), ) } @@ -63,7 +60,7 @@ class TestXrpSigner { "d5b18dd75818a07d4b4ed5846b07604e48607789d393691334f59d3761f6874c02205ac35c8b" + "cadb9fdbd81022f3629bfa0aac0b80afa655628c8ddbfee030f1bb178114dd10693e412bff78" + "9ebf6baa9714036c9ae214bb8314dd10693e412bff789ebf6baa9714036c9ae214bb", - sign.first().toHexString() + String(sign.first()) ) } } \ No newline at end of file diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/AssetsRepository.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/AssetsRepository.kt index 2b512840d..18b1e387c 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/AssetsRepository.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/assets/AssetsRepository.kt @@ -80,7 +80,13 @@ class AssetsRepository @Inject constructor( private val scope: CoroutineScope = CoroutineScope(Dispatchers.IO), ) : GetAsset { - private val visibleByDefault = listOf(Chain.Ethereum, Chain.Bitcoin, Chain.SmartChain, Chain.Solana) + private val visibleByDefault = listOf( + Chain.Ethereum, + Chain.Bitcoin, + Chain.SmartChain, + Chain.Solana, + Chain.Tron, + ) init { scope.launch(Dispatchers.IO) { From 602cbe8a866fa362881e0b6990b18faaaf02caa9 Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Thu, 4 Sep 2025 22:03:59 -0700 Subject: [PATCH 08/16] Integrate gateway preload --- .../data/password/PreferencePasswordStore.kt | 8 +- .../com/gemwallet/android/di/GatewayModule.kt | 32 ++ .../bitcoin/BitcoinGatewayEstimateFee.kt | 22 ++ .../clients/ethereum/EvmGatewayEstimateFee.kt | 22 ++ .../services/SignerPreloaderProxy.kt | 320 ++++++++++++------ .../config/SecurityGemPreferences.kt | 42 +++ .../config/SharedGemPreferences.kt | 22 ++ .../data/repositoreis/di/AssetsModule.kt | 34 -- .../gemwallet/android/model/ConfirmParams.kt | 20 +- 9 files changed, 386 insertions(+), 136 deletions(-) create mode 100644 app/src/main/kotlin/com/gemwallet/android/di/GatewayModule.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGatewayEstimateFee.kt create mode 100644 data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/config/SecurityGemPreferences.kt create mode 100644 data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/config/SharedGemPreferences.kt diff --git a/app/src/main/kotlin/com/gemwallet/android/data/password/PreferencePasswordStore.kt b/app/src/main/kotlin/com/gemwallet/android/data/password/PreferencePasswordStore.kt index a558e23f5..69091f677 100644 --- a/app/src/main/kotlin/com/gemwallet/android/data/password/PreferencePasswordStore.kt +++ b/app/src/main/kotlin/com/gemwallet/android/data/password/PreferencePasswordStore.kt @@ -8,6 +8,7 @@ import androidx.security.crypto.MasterKey import com.gemwallet.android.blockchain.operators.PasswordStore import com.gemwallet.android.math.toHexString import java.security.SecureRandom +import androidx.core.content.edit class PreferencePasswordStore( private val context: Context, @@ -18,10 +19,9 @@ class PreferencePasswordStore( override fun createPassword(walletId: String): String { val key = ByteArray(16) random.nextBytes(key) - getStore() - .edit() - .putString(walletId, key.toHexString()) - .commit() + getStore().edit(commit = true) { + putString(walletId, key.toHexString()) + } return key.toHexString() } diff --git a/app/src/main/kotlin/com/gemwallet/android/di/GatewayModule.kt b/app/src/main/kotlin/com/gemwallet/android/di/GatewayModule.kt new file mode 100644 index 000000000..2b0299cb8 --- /dev/null +++ b/app/src/main/kotlin/com/gemwallet/android/di/GatewayModule.kt @@ -0,0 +1,32 @@ +package com.gemwallet.android.di + +import android.content.Context +import com.gemwallet.android.data.repositoreis.config.SecurityGemPreferences +import com.gemwallet.android.data.repositoreis.config.SharedGemPreferences +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import uniffi.gemstone.AlienProvider +import uniffi.gemstone.GemGateway +import javax.inject.Singleton + +@InstallIn(SingletonComponent::class) +@Module +object GatewayModule { + @Provides + @Singleton + fun provideGateway( + alienProvider: AlienProvider, + @ApplicationContext context: Context, + ): GemGateway { + return GemGateway( + alienProvider, + SharedGemPreferences( + context.getSharedPreferences("gateway_preferences", Context.MODE_PRIVATE) + ), + SecurityGemPreferences(context) + ) + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt new file mode 100644 index 000000000..7e3eca85f --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt @@ -0,0 +1,22 @@ +package com.gemwallet.android.blockchain.clients.bitcoin + +import uniffi.gemstone.Chain +import uniffi.gemstone.GemGatewayEstimateFee +import uniffi.gemstone.GemTransactionLoadFee +import uniffi.gemstone.GemTransactionLoadInput + +class BitcoinGatewayEstimateFee : GemGatewayEstimateFee { + override suspend fun getFee( + chain: Chain, + input: GemTransactionLoadInput + ): GemTransactionLoadFee? { + return null + } + + override suspend fun getFeeData( + chain: Chain, + input: GemTransactionLoadInput + ): String? { + return null + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGatewayEstimateFee.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGatewayEstimateFee.kt new file mode 100644 index 000000000..393a7b01d --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGatewayEstimateFee.kt @@ -0,0 +1,22 @@ +package com.gemwallet.android.blockchain.clients.ethereum + +import uniffi.gemstone.Chain +import uniffi.gemstone.GemGatewayEstimateFee +import uniffi.gemstone.GemTransactionLoadFee +import uniffi.gemstone.GemTransactionLoadInput + +class EvmGatewayEstimateFee : GemGatewayEstimateFee { + override suspend fun getFee( + chain: Chain, + input: GemTransactionLoadInput + ): GemTransactionLoadFee? { + return null + } + + override suspend fun getFeeData( + chain: Chain, + input: GemTransactionLoadInput + ): String? { + return null + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt index 4cad84435..2309a005c 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt @@ -10,9 +10,11 @@ import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader import com.gemwallet.android.blockchain.clients.TokenTransferPreloader import com.gemwallet.android.blockchain.clients.algorand.toChainData import com.gemwallet.android.blockchain.clients.aptos.toChainData +import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinGatewayEstimateFee import com.gemwallet.android.blockchain.clients.bitcoin.toChainData import com.gemwallet.android.blockchain.clients.cardano.toChainData import com.gemwallet.android.blockchain.clients.cosmos.toChainData +import com.gemwallet.android.blockchain.clients.ethereum.EvmGatewayEstimateFee import com.gemwallet.android.blockchain.clients.ethereum.toChainData import com.gemwallet.android.blockchain.clients.getClient import com.gemwallet.android.blockchain.clients.near.toChainData @@ -24,23 +26,29 @@ import com.gemwallet.android.blockchain.clients.ton.toChainData import com.gemwallet.android.blockchain.clients.tron.toChainData import com.gemwallet.android.blockchain.clients.xrp.toChainData import com.gemwallet.android.blockchain.services.mapper.toGem +import com.gemwallet.android.ext.toChainType import com.gemwallet.android.model.ConfirmParams +import com.gemwallet.android.model.Fee import com.gemwallet.android.model.GasFee import com.gemwallet.android.model.SignerParams import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.Chain +import com.wallet.core.primitives.ChainType import com.wallet.core.primitives.FeePriority import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async import kotlinx.coroutines.withContext +import uniffi.gemstone.GemGasPriceType import uniffi.gemstone.GemGateway import uniffi.gemstone.GemGatewayEstimateFee +import uniffi.gemstone.GemGatewayEstimateFeeImpl import uniffi.gemstone.GemTransactionInputType import uniffi.gemstone.GemTransactionLoadFee import uniffi.gemstone.GemTransactionLoadInput import uniffi.gemstone.GemTransactionLoadMetadata import uniffi.gemstone.GemTransactionPreloadInput import uniffi.gemstone.SwapperException +import java.math.BigInteger +import kotlin.collections.mapValues class SignerPreloaderProxy( private val gateway: GemGateway, @@ -58,20 +66,70 @@ class SignerPreloaderProxy( NftTransactionPreloader { suspend fun preload(params: ConfirmParams): SignerParams = withContext(Dispatchers.IO) { - val preloadJob = async { - when (params) { - is ConfirmParams.Stake -> preloadStake(params) - is ConfirmParams.SwapParams -> preloadSwap(params) - is ConfirmParams.TokenApprovalParams -> preloadApproval(params) - is ConfirmParams.TransferParams.Native -> preloadNativeTransfer(params) - is ConfirmParams.TransferParams.Token -> preloadTokenTransfer(params) - is ConfirmParams.Activate -> preloadActivate(params) - is ConfirmParams.TransferParams.Generic -> preloadGeneric(params) - is ConfirmParams.NftParams -> preloadNft(params) - } + val gemAsset = params.asset.toGem() + val assetId = params.assetId + val chain = assetId.chain + val gemChain = assetId.chain.string + val destination = params.destination()?.address ?: throw java.lang.IllegalArgumentException() + try { + val metadata = gateway.getTransactionPreload( + chain = gemChain, + input = GemTransactionPreloadInput( + inputType = GemTransactionInputType.Transfer(gemAsset), + senderAddress = params.from.address, + destinationAddress = destination + ) + ) + val feeRates = gateway.getFeeRates( + chain = gemChain, + input = GemTransactionInputType.Transfer(gemAsset), + ) + + val fees = feeRates.map { feeRate -> + val feeAssetId = AssetId(chain) + val priority = FeePriority.entries.firstOrNull { it.string == feeRate.priority } ?: return@map null + + val result = gateway.getTransactionLoad( + chain = gemChain, + input = GemTransactionLoadInput( + inputType = GemTransactionInputType.Transfer(gemAsset), + senderAddress = params.from.address, + destinationAddress = destination, + value = params.amount.toString(), + gasPrice = feeRate.gasPriceType, + memo = params.memo(), + isMaxValue = params.isMax(), + metadata = metadata, + ), + provider = getEstimateFee(chain) + ) + chain.toFeeType().convertFee(feeAssetId, priority, result.fee) + }.filterNotNull() + + val chainData = metadata.toChainData() + + SignerParams( + input = params, + chainData = chainData, + fee = fees + ) + } catch (err: Throwable) { + throw err } +// val preloadJob = async { +// when (params) { +// is ConfirmParams.Stake -> preloadStake(params) +// is ConfirmParams.SwapParams -> preloadSwap(params) +// is ConfirmParams.TokenApprovalParams -> preloadApproval(params) +// is ConfirmParams.TransferParams.Native -> preloadNativeTransfer(params) +// is ConfirmParams.TransferParams.Token -> preloadTokenTransfer(params) +// is ConfirmParams.Activate -> preloadActivate(params) +// is ConfirmParams.TransferParams.Generic -> preloadGeneric(params) +// is ConfirmParams.NftParams -> preloadNft(params) +// } +// } - preloadJob.await() +// preloadJob.await() } override fun supported(chain: Chain): Boolean { @@ -83,89 +141,6 @@ class SignerPreloaderProxy( } override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - when (params.assetId.chain) { - Chain.Solana -> { - val gemAsset = params.asset.toGem() - val assetId = params.assetId - val chain = assetId.chain - val gemChain = assetId.chain.string - return try { - val metadata = gateway.getTransactionPreload( - chain = gemChain, - input = GemTransactionPreloadInput( - inputType = GemTransactionInputType.Transfer(gemAsset), - senderAddress = params.from.address, - destinationAddress = params.destination.address, - ) - ) - val feeRates = gateway.getFeeRates( - chain = gemChain, - input = GemTransactionInputType.Transfer(gemAsset), - ) - - val fees = feeRates.map { feeRate -> - val feeRegular = feeRate.gasPriceType - val result = gateway.getTransactionLoad( - chain = gemChain, - input = GemTransactionLoadInput( - inputType = GemTransactionInputType.Transfer(gemAsset), - senderAddress = params.from.address, - destinationAddress = params.destination.address, - value = params.amount.toString(), - gasPrice = feeRegular, - memo = params.memo, - isMaxValue = params.isMax(), - metadata = metadata, - ), - provider = object : GemGatewayEstimateFee { - override suspend fun getFee( - chain: uniffi.gemstone.Chain, - input: GemTransactionLoadInput - ): GemTransactionLoadFee? = null - - override suspend fun getFeeData( - chain: uniffi.gemstone.Chain, - input: GemTransactionLoadInput - ): String? = null - } - ) - GasFee( - feeAssetId = AssetId(chain), - priority = FeePriority.entries.firstOrNull { it.string == feeRate.priority } ?: return@map null, - limit = result.fee.gasLimit.toBigInteger(), - maxGasPrice = result.fee.fee.toBigInteger(), - options = result.fee.options.options.mapKeys { it.key.name }.mapValues { it.value.toBigInteger() } - ) - }.filterNotNull() - val chainData = when (metadata) { - is GemTransactionLoadMetadata.Algorand -> metadata.toChainData() - is GemTransactionLoadMetadata.Aptos -> metadata.toChainData() - is GemTransactionLoadMetadata.Bitcoin -> metadata.toChainData() - is GemTransactionLoadMetadata.Cardano -> metadata.toChainData() - is GemTransactionLoadMetadata.Cosmos -> metadata.toChainData() - is GemTransactionLoadMetadata.Evm -> metadata.toChainData() - is GemTransactionLoadMetadata.Near -> metadata.toChainData() - is GemTransactionLoadMetadata.Polkadot -> metadata.toChainData() - is GemTransactionLoadMetadata.Solana -> metadata.toChainData() - is GemTransactionLoadMetadata.Stellar -> metadata.toChainData() - is GemTransactionLoadMetadata.Sui -> metadata.toChainData() - is GemTransactionLoadMetadata.Ton -> metadata.toChainData() - is GemTransactionLoadMetadata.Tron -> metadata.toChainData() - is GemTransactionLoadMetadata.Xrp -> metadata.toChainData() - is GemTransactionLoadMetadata.Hyperliquid -> throw SwapperException.NotSupportedChain()// metadata.toChainData() - GemTransactionLoadMetadata.None -> throw SwapperException.NotSupportedChain() - } - SignerParams( - input = params, - chainData = chainData, - fee = fees - ) - } catch (err: Throwable) { - throw err - } - } - else -> {} - } return nativeTransferClients.getClient(params.from.chain)?.preloadNativeTransfer(params = params) ?: throw IllegalArgumentException("Chain isn't support") } @@ -204,4 +179,157 @@ class SignerPreloaderProxy( return nftPreloadClients.getClient(params.from.chain)?.preloadNft(params = params) ?: throw IllegalArgumentException("Chain isn't support") } + + private fun getEstimateFee(chain: Chain): GemGatewayEstimateFee { + return when (chain.toChainType()) { + ChainType.Bitcoin -> BitcoinGatewayEstimateFee() + ChainType.Ethereum -> EvmGatewayEstimateFee() + ChainType.Solana, + ChainType.Cosmos, + ChainType.Ton, + ChainType.Tron, + ChainType.Aptos, + ChainType.Sui, + ChainType.Xrp, + ChainType.Near, + ChainType.Stellar, + ChainType.Algorand, + ChainType.Polkadot, + ChainType.Cardano, + ChainType.HyperCore -> StubGatewayEstimateFee + } + } + + private object StubGatewayEstimateFee : GemGatewayEstimateFee { + override suspend fun getFee( + chain: uniffi.gemstone.Chain, + input: GemTransactionLoadInput + ): GemTransactionLoadFee? = null + + override suspend fun getFeeData( + chain: uniffi.gemstone.Chain, + input: GemTransactionLoadInput + ): String? = null + + } +} + +private sealed interface FeeType { + + fun convertFee(feeAssetId: AssetId, priority: FeePriority, gemFee: GemTransactionLoadFee): Fee + + object Plain : FeeType { + + override fun convertFee( + feeAssetId: AssetId, + priority: FeePriority, + gemFee: GemTransactionLoadFee + ): Fee { + return Fee( + feeAssetId = feeAssetId, + priority = priority, + amount = gemFee.fee.toBigInteger(), + options = gemFee.options.options.mapKeys { it.key.name }.mapValues { it.value.toBigInteger() } // TODO: Review keys + ) + } + + } + object Regular : FeeType { + + override fun convertFee( + feeAssetId: AssetId, + priority: FeePriority, + gemFee: GemTransactionLoadFee + ): Fee { + return GasFee( + feeAssetId = feeAssetId, + priority = priority, + maxGasPrice = (gemFee.gasPriceType as GemGasPriceType.Regular).gasPrice.toBigInteger(), + limit = gemFee.gasLimit.toBigInteger(), + amount = gemFee.fee.toBigInteger(), + options = gemFee.options.options.mapKeys { it.key.name }.mapValues { it.value.toBigInteger() } // TODO: Review keys + ) + } + + } + object Eip1559 : FeeType { + + override fun convertFee( + feeAssetId: AssetId, + priority: FeePriority, + gemFee: GemTransactionLoadFee + ): Fee { + return (gemFee.gasPriceType as GemGasPriceType.Eip1559).let { price -> + GasFee( + feeAssetId = feeAssetId, + priority = priority, + maxGasPrice = price.gasPrice.toBigInteger(), + minerFee = price.priorityFee.toBigInteger(), + limit = gemFee.gasLimit.toBigInteger(), + amount = gemFee.fee.toBigInteger(), + options = gemFee.options.options.mapKeys { it.key.name }.mapValues { it.value.toBigInteger() } // TODO: Change keys + ) + } + } + } + + object Solana : FeeType { + + override fun convertFee( + feeAssetId: AssetId, + priority: FeePriority, + gemFee: GemTransactionLoadFee + ): Fee { + return (gemFee.gasPriceType as GemGasPriceType.Solana).let { price -> + GasFee( + feeAssetId = feeAssetId, + priority = priority, + maxGasPrice = price.gasPrice.toBigInteger(), + minerFee = price.priorityFee.toBigInteger(), +// unitFee = price.unitPrice.toBigInteger(), + limit = gemFee.gasLimit.toBigInteger(), + amount = gemFee.fee.toBigInteger(), + options = gemFee.options.options.mapKeys { it.key.name }.mapValues { it.value.toBigInteger() } // TODO: Change keys + ) + } + } + + } +} + +private fun Chain.toFeeType() = when (this.toChainType()) { + ChainType.Solana -> FeeType.Solana + ChainType.Bitcoin, + ChainType.Cosmos, + ChainType.Aptos -> FeeType.Regular + ChainType.Ethereum -> FeeType.Eip1559 + ChainType.HyperCore, + ChainType.Ton, + ChainType.Tron, + ChainType.Sui, + ChainType.Xrp, + ChainType.Near, + ChainType.Stellar, + ChainType.Algorand, + ChainType.Polkadot, + ChainType.Cardano -> FeeType.Plain +} + +private fun GemTransactionLoadMetadata.toChainData() = when (this) { + is GemTransactionLoadMetadata.Algorand -> toChainData() + is GemTransactionLoadMetadata.Aptos -> toChainData() + is GemTransactionLoadMetadata.Bitcoin -> toChainData() + is GemTransactionLoadMetadata.Cardano -> toChainData() + is GemTransactionLoadMetadata.Cosmos -> toChainData() + is GemTransactionLoadMetadata.Evm -> toChainData() + is GemTransactionLoadMetadata.Near -> toChainData() + is GemTransactionLoadMetadata.Polkadot -> toChainData() + is GemTransactionLoadMetadata.Solana -> toChainData() + is GemTransactionLoadMetadata.Stellar -> toChainData() + is GemTransactionLoadMetadata.Sui -> toChainData() + is GemTransactionLoadMetadata.Ton -> toChainData() + is GemTransactionLoadMetadata.Tron -> toChainData() + is GemTransactionLoadMetadata.Xrp -> toChainData() + is GemTransactionLoadMetadata.Hyperliquid -> throw SwapperException.NotSupportedChain() + GemTransactionLoadMetadata.None -> throw SwapperException.NotSupportedChain() } \ No newline at end of file diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/config/SecurityGemPreferences.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/config/SecurityGemPreferences.kt new file mode 100644 index 000000000..053075749 --- /dev/null +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/config/SecurityGemPreferences.kt @@ -0,0 +1,42 @@ +package com.gemwallet.android.data.repositoreis.config + +import android.content.Context +import android.content.SharedPreferences +import androidx.core.content.edit +import androidx.security.crypto.EncryptedSharedPreferences +import androidx.security.crypto.MasterKey +import uniffi.gemstone.GemPreferences + +class SecurityGemPreferences( + private val context: Context, +) : GemPreferences { + + override fun get(key: String): String? { + return getStore().getString(key, null) + } + + override fun set(key: String, value: String) { + getStore().edit(commit = true) { + putString(key, value) + } + } + + override fun remove(key: String) { + getStore().edit(commit = true) { + remove(key) + } + } + + private fun getStore(): SharedPreferences { + val masterKey = MasterKey.Builder(context) + .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) + .build() + return EncryptedSharedPreferences.create( + context, + "pwd", + masterKey, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM, + ) + } +} \ No newline at end of file diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/config/SharedGemPreferences.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/config/SharedGemPreferences.kt new file mode 100644 index 000000000..68fdcab60 --- /dev/null +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/config/SharedGemPreferences.kt @@ -0,0 +1,22 @@ +package com.gemwallet.android.data.repositoreis.config + +import android.content.SharedPreferences +import uniffi.gemstone.GemPreferences +import androidx.core.content.edit + +class SharedGemPreferences( + private val sharedPreferences: SharedPreferences +) : GemPreferences { + + override fun get(key: String): String? { + return sharedPreferences.getString(key, null) + } + + override fun set(key: String, value: String) { + sharedPreferences.edit(commit = true) { putString(key, value) } + } + + override fun remove(key: String) { + sharedPreferences.edit(commit = true) { remove(key) } + } +} \ No newline at end of file diff --git a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt index a82da42f0..877c3e93c 100644 --- a/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt +++ b/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositoreis/di/AssetsModule.kt @@ -59,40 +59,6 @@ object AssetsModule { priceClient = priceClient ) - @Provides - @Singleton - fun provideGateway(alienProvider: AlienProvider): GemGateway { - return GemGateway( - alienProvider, - object : GemPreferences { - override fun get(key: String): String? { - TODO("Not yet implemented") - } - - override fun set(key: String, value: String) { - TODO("Not yet implemented") - } - - override fun remove(key: String) { - TODO("Not yet implemented") - } - }, - object : GemPreferences { - override fun get(key: String): String? { - TODO("Not yet implemented") - } - - override fun set(key: String, value: String) { - TODO("Not yet implemented") - } - - override fun remove(key: String) { - TODO("Not yet implemented") - } - }, - ) - } - @Provides @Singleton fun provideBalanceRemoteSource( diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/model/ConfirmParams.kt b/gemcore/src/main/kotlin/com/gemwallet/android/model/ConfirmParams.kt index 801ef9bc4..291cc0558 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/model/ConfirmParams.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/model/ConfirmParams.kt @@ -172,6 +172,10 @@ sealed class ConfirmParams { get() = BigInteger.ZERO override fun memo(): String? = data + + override fun destination(): DestinationAddress? { + return DestinationAddress(contract) + } } @Serializable @@ -193,12 +197,16 @@ sealed class ConfirmParams { override val asset: Asset get() = fromAsset + override val amount: BigInteger get() = fromAmount + override fun destination(): DestinationAddress = DestinationAddress(to) override fun isMax(): Boolean = maxFrom + override fun memo(): String? = swapData + @Serializable data class ApprovalData( val token: String, @@ -212,7 +220,11 @@ sealed class ConfirmParams { override val asset: Asset, override val from: Account, @Serializable(BigIntegerSerializer::class) override val amount: BigInteger = BigInteger.ZERO, - ) : ConfirmParams() + ) : ConfirmParams() { + override fun destination(): DestinationAddress? { + return DestinationAddress(from.address) + } + } @Serializable class NftParams( @@ -282,6 +294,10 @@ sealed class ConfirmParams { ) : Stake() { override val validatorId: String = "" } + + override fun destination(): DestinationAddress? { + return DestinationAddress(validatorId) + } } fun pack(): String? { @@ -305,7 +321,7 @@ sealed class ConfirmParams { } } - open fun destination(): DestinationAddress? = null + open fun destination(): DestinationAddress? = null open fun memo(): String? = null From c0f4f1b7a25e463ff73b1a7a5614e24124ad3566 Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Sun, 7 Sep 2025 20:34:27 -0700 Subject: [PATCH 09/16] Implement BitcoinGatewayEstimateFee, bump ktor --- .../bitcoin/BitcoinGatewayEstimateFee.kt | 78 ++++++++++++++++++- .../services/SignerPreloaderProxy.kt | 5 +- gradle/libs.versions.toml | 2 +- 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt index 7e3eca85f..6dd3923d1 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt @@ -1,16 +1,47 @@ package com.gemwallet.android.blockchain.clients.bitcoin +import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy +import com.gemwallet.android.blockchain.services.mapper.toUtxo +import com.gemwallet.android.ext.toChain +import com.wallet.core.primitives.UTXO import uniffi.gemstone.Chain +import uniffi.gemstone.GemFeeOptions +import uniffi.gemstone.GemGasPriceType import uniffi.gemstone.GemGatewayEstimateFee import uniffi.gemstone.GemTransactionLoadFee import uniffi.gemstone.GemTransactionLoadInput +import uniffi.gemstone.GemTransactionLoadMetadata +import wallet.core.java.AnySigner +import wallet.core.jni.BitcoinSigHashType +import wallet.core.jni.proto.Bitcoin +import wallet.core.jni.proto.Common +import java.math.BigInteger class BitcoinGatewayEstimateFee : GemGatewayEstimateFee { override suspend fun getFee( chain: Chain, input: GemTransactionLoadInput ): GemTransactionLoadFee? { - return null + val chain = chain.toChain() ?: throw IllegalArgumentException("Incorrect chain") + + val utxos = (input.metadata as? GemTransactionLoadMetadata.Bitcoin)?.utxos?.toUtxo() + ?: throw IllegalArgumentException("Incorrect UTXO") + + val bytePrice = (input.gasPrice as? GemGasPriceType.Regular)?.gasPrice?.toLongOrNull() + ?: throw IllegalArgumentException("Incorrect Byte Price") + val amount = input.value.toLongOrNull() ?: return null + + val destination = input.destinationAddress + val from = input.senderAddress + + val fee = calcFee(chain, from, destination, amount, bytePrice, utxos) + + return GemTransactionLoadFee( + fee = fee.toString(), + gasPriceType = input.gasPrice, + gasLimit = "1", + options = GemFeeOptions(emptyMap()) + ) } override suspend fun getFeeData( @@ -19,4 +50,49 @@ class BitcoinGatewayEstimateFee : GemGatewayEstimateFee { ): String? { return null } + + private fun calcFee( + chain: com.wallet.core.primitives.Chain, + from: String, + to: String, + amount: Long, + bytePrice: Long, + utxos: List, + ): BigInteger { + val coinType = WCChainTypeProxy().invoke(chain) + val total = utxos.map { it.value.toLong() }.fold(0L) { x, y -> x + y } + if (total == 0L) { + return BigInteger.ZERO // empty balance + } + val input = Bitcoin.SigningInput.newBuilder().apply { + this.hashType = BitcoinSigHashType.ALL.value() + this.byteFee = bytePrice + this.amount = amount + this.useMaxAmount = total == amount + this.coinType = coinType.value() + this.toAddress = to + this.changeAddress = from + this.addAllUtxo(utxos.getUtxoTransactions(from, coinType)) + }.build() + + val plan = AnySigner.plan(input, coinType, Bitcoin.TransactionPlan.parser()) + when (plan.error) { + Common.SigningError.OK -> { /* continue */ } + Common.SigningError.Error_not_enough_utxos, + Common.SigningError.Error_dust_amount_requested, + Common.SigningError.Error_missing_input_utxos -> throw IllegalStateException("Dust Error: $bytePrice") + else -> throw IllegalStateException(plan.error.name) + } + + val selectedUtxos: MutableList = mutableListOf() + for (raw in plan.utxosList) { + input.utxoList?.indexOfFirst { it == raw }?.let { + selectedUtxos.add(utxos[it]) + } + } + if (utxos.isNotEmpty() && selectedUtxos.isEmpty() && amount != total && amount <= total) { + return calcFee(chain, from, to, total, bytePrice, utxos) + } + return BigInteger.valueOf(plan.fee / bytePrice) + } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt index 2309a005c..7ab9bf185 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt @@ -40,15 +40,12 @@ import kotlinx.coroutines.withContext import uniffi.gemstone.GemGasPriceType import uniffi.gemstone.GemGateway import uniffi.gemstone.GemGatewayEstimateFee -import uniffi.gemstone.GemGatewayEstimateFeeImpl import uniffi.gemstone.GemTransactionInputType import uniffi.gemstone.GemTransactionLoadFee import uniffi.gemstone.GemTransactionLoadInput import uniffi.gemstone.GemTransactionLoadMetadata import uniffi.gemstone.GemTransactionPreloadInput import uniffi.gemstone.SwapperException -import java.math.BigInteger -import kotlin.collections.mapValues class SignerPreloaderProxy( private val gateway: GemGateway, @@ -184,6 +181,7 @@ class SignerPreloaderProxy( return when (chain.toChainType()) { ChainType.Bitcoin -> BitcoinGatewayEstimateFee() ChainType.Ethereum -> EvmGatewayEstimateFee() + ChainType.Cardano, ChainType.Solana, ChainType.Cosmos, ChainType.Ton, @@ -195,7 +193,6 @@ class SignerPreloaderProxy( ChainType.Stellar, ChainType.Algorand, ChainType.Polkadot, - ChainType.Cardano, ChainType.HyperCore -> StubGatewayEstimateFee } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d869d9a7d..3adda803c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -47,7 +47,7 @@ mockkVersion = "1.14.5" datastore = "1.1.7" wallet-core = "4.3.5" gemstone = "0.33.3" -ktor = "3.1.3" +ktor = "3.2.3" appcompat = "1.7.1" material = "1.13.0" From dfc893f8ddde2aa5bd28cdba2bd5d9f1c5a42f75 Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Tue, 16 Sep 2025 19:24:04 -0700 Subject: [PATCH 10/16] Clean code --- .../com/gemwallet/android/di/DataModule.kt | 50 ---- .../algorand/AlgorandSignPreloadClient.kt | 36 --- .../algorand/services/AlgorandService.kt | 9 - .../clients/aptos/AptosFeeCalculator.kt | 102 -------- .../clients/aptos/AptosSignerPreloader.kt | 43 --- .../clients/aptos/models/AptosAccount.kt | 10 - .../clients/aptos/services/AptosServices.kt | 23 -- .../clients/bitcoin/BitcoinFeeCalculator.kt | 129 --------- .../bitcoin/BitcoinGatewayEstimateFee.kt | 27 +- .../clients/bitcoin/BitcoinSignerPreloader.kt | 52 ---- .../bitcoin/services/BitcoinRpcClient.kt | 14 - .../cardano/CardanoGatewayEstimateFee.kt | 83 ++++++ .../cardano/CardanoSignerPreloaderClient.kt | 71 ----- .../cardano/services/CardanoServices.kt | 30 --- .../clients/cosmos/CosmosFeeCalculator.kt | 65 ----- .../clients/cosmos/CosmosSignerPreloader.kt | 64 ----- .../cosmos/services/CosmosRpcClient.kt | 19 -- .../blockchain/clients/ethereum/StakeHub.kt | 247 +++++++++--------- .../hyper/HyperCoreSignerPreloaderClient.kt | 26 -- .../hyper/services/HyperCoreServices.kt | 4 - .../blockchain/clients/near/NearMethod.kt | 6 - .../blockchain/clients/near/NearRpcClient.kt | 50 ---- .../clients/near/NearSignerPreloader.kt | 47 ---- .../polkadot/PolkadotGatewayEstimateFee.kt | 68 +++++ .../clients/polkadot/PolkadotSignClient.kt | 29 -- .../polkadot/PolkadotSignerPreloaderClient.kt | 78 ------ .../polkadot/models/PolkadotSigningData.kt | 15 -- .../polkadot/services/PolkadotServices.kt | 21 -- .../clients/stellar/StellarFeeCalculator.kt | 36 --- .../stellar/StellarSignPreloadClient.kt | 66 ----- .../stellar/services/StellarService.kt | 20 -- .../clients/sui/SuiFeeCalculator.kt | 20 -- .../blockchain/clients/sui/SuiMethod.kt | 13 - .../blockchain/clients/sui/SuiRpcClient.kt | 43 --- .../clients/sui/SuiSignerPreloader.kt | 190 -------------- .../blockchain/clients/sui/model/SuiObject.kt | 15 -- .../blockchain/clients/ton/TonCalls.kt | 25 -- .../clients/ton/TonFeeCalculator.kt | 51 ---- .../blockchain/clients/ton/TonRpcClient.kt | 57 ---- .../blockchain/clients/ton/TonSignClient.kt | 3 +- .../clients/ton/TonSignerPreloader.kt | 60 ----- .../clients/tron/TronFeeCalculator.kt | 125 --------- .../clients/tron/TronSignerPreloader.kt | 102 -------- .../clients/xrp/XrpFeeCalculator.kt | 27 -- .../blockchain/clients/xrp/XrpMethod.kt | 11 - .../blockchain/clients/xrp/XrpRpcClient.kt | 39 --- .../clients/xrp/XrpSignerPreloader.kt | 58 ---- .../services/SignerPreloaderProxy.kt | 77 +----- core | 2 +- .../data/services/gemapi/di/ClientsModule.kt | 90 +++---- .../com/gemwallet/android/flavors/FCM.kt | 1 + .../wallet/core/primitives/AddressStatus.kt | 15 ++ .../com/wallet/core/primitives/AssetType.kt | 2 + .../com/wallet/core/primitives/Device.kt | 2 + .../core/primitives/FeePriorityValue.kt | 15 ++ .../core/primitives/FiatQuoteRequest.kt | 2 +- .../com/wallet/core/primitives/LatencyType.kt | 25 ++ .../com/wallet/core/primitives/PaymentType.kt | 19 ++ .../core/primitives/PerpetualPosition.kt | 6 +- .../core/primitives/PushNotification.kt | 5 + .../com/wallet/core/primitives/Support.kt | 15 ++ .../wallet/core/primitives/swap/Approval.kt | 2 +- gradle/libs.versions.toml | 2 +- 63 files changed, 452 insertions(+), 2207 deletions(-) delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/models/AptosAccount.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosServices.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoGatewayEstimateFee.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignerPreloaderClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoServices.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosRpcClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignerPreloaderClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/services/HyperCoreServices.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearMethod.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignerPreloader.kt create mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/models/PolkadotSigningData.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotServices.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiRpcClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignerPreloader.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/model/SuiObject.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonCalls.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonRpcClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignerPreloader.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpMethod.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpRpcClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/AddressStatus.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/FeePriorityValue.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/LatencyType.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/PaymentType.kt create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/Support.kt diff --git a/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt b/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt index 0c27324ce..55d662bc0 100644 --- a/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt +++ b/app/src/main/kotlin/com/gemwallet/android/di/DataModule.kt @@ -1,42 +1,20 @@ package com.gemwallet.android.di -import com.gemwallet.android.blockchain.RpcClientAdapter -import com.gemwallet.android.blockchain.clients.ActivationTransactionPreloader -import com.gemwallet.android.blockchain.clients.ApprovalTransactionPreloader -import com.gemwallet.android.blockchain.clients.GenericTransferPreloader -import com.gemwallet.android.blockchain.clients.NftTransactionPreloader -import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader import com.gemwallet.android.blockchain.clients.algorand.AlgorandSignClient -import com.gemwallet.android.blockchain.clients.algorand.AlgorandSignPreloadClient import com.gemwallet.android.blockchain.clients.aptos.AptosSignClient -import com.gemwallet.android.blockchain.clients.aptos.AptosSignerPreloader import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinSignClient -import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinSignerPreloader import com.gemwallet.android.blockchain.clients.cardano.CardanoSignClient -import com.gemwallet.android.blockchain.clients.cardano.CardanoSignerPreloaderClient import com.gemwallet.android.blockchain.clients.cosmos.CosmosSignClient -import com.gemwallet.android.blockchain.clients.cosmos.CosmosSignerPreloader import com.gemwallet.android.blockchain.clients.ethereum.EvmSignClient -import com.gemwallet.android.blockchain.clients.ethereum.EvmSignerPreloader import com.gemwallet.android.blockchain.clients.hyper.HyperCoreSignClient -import com.gemwallet.android.blockchain.clients.hyper.HyperCoreSignerPreloaderClient import com.gemwallet.android.blockchain.clients.near.NearSignClient -import com.gemwallet.android.blockchain.clients.near.NearSignerPreloader import com.gemwallet.android.blockchain.clients.polkadot.PolkadotSignClient -import com.gemwallet.android.blockchain.clients.polkadot.PolkadotSignerPreloaderClient import com.gemwallet.android.blockchain.clients.solana.SolanaSignClient import com.gemwallet.android.blockchain.clients.stellar.StellarSignClient -import com.gemwallet.android.blockchain.clients.stellar.StellarSignPreloadClient import com.gemwallet.android.blockchain.clients.sui.SuiSignClient -import com.gemwallet.android.blockchain.clients.sui.SuiSignerPreloader import com.gemwallet.android.blockchain.clients.ton.TonSignClient -import com.gemwallet.android.blockchain.clients.ton.TonSignerPreloader import com.gemwallet.android.blockchain.clients.tron.TronSignClient -import com.gemwallet.android.blockchain.clients.tron.TronSignerPreloader import com.gemwallet.android.blockchain.clients.xrp.XrpSignClient -import com.gemwallet.android.blockchain.clients.xrp.XrpSignerPreloader import com.gemwallet.android.blockchain.services.BroadcastService import com.gemwallet.android.blockchain.services.NodeStatusService import com.gemwallet.android.blockchain.services.SignClientProxy @@ -75,37 +53,9 @@ object DataModule { @Singleton fun provideSignerPreloader( gateway: GemGateway, - rpcClients: RpcClientAdapter, ): SignerPreloaderProxy { - val preloaders = Chain.available().mapNotNull { - when (it.toChainType()) { - ChainType.Bitcoin -> BitcoinSignerPreloader(it, rpcClients.getClient(it)) - ChainType.Ethereum -> EvmSignerPreloader(it, rpcClients.getClient(it), rpcClients.getClient(it)) - ChainType.Solana -> null - ChainType.Cosmos -> CosmosSignerPreloader(it, rpcClients.getClient(it)) - ChainType.Ton -> TonSignerPreloader(it, rpcClients.getClient(it)) - ChainType.Tron -> TronSignerPreloader(it, rpcClients.getClient(it)) - ChainType.Aptos -> AptosSignerPreloader(it, rpcClients.getClient(it)) - ChainType.Sui -> SuiSignerPreloader(it, rpcClients.getClient(it)) - ChainType.Xrp -> XrpSignerPreloader(it, rpcClients.getClient(it)) - ChainType.Near -> NearSignerPreloader(it, rpcClients.getClient(it)) - ChainType.Algorand -> AlgorandSignPreloadClient(it, rpcClients.getClient(it)) - ChainType.Stellar -> StellarSignPreloadClient(it, rpcClients.getClient(it)) - ChainType.Polkadot -> PolkadotSignerPreloaderClient(it, rpcClients.getClient(it)) - ChainType.Cardano -> CardanoSignerPreloaderClient(it, rpcClients.getClient(it)) - ChainType.HyperCore -> HyperCoreSignerPreloaderClient(it) - } - } return SignerPreloaderProxy( gateway = gateway, - nativeTransferClients = preloaders, - tokenTransferClients = preloaders.mapNotNull { it as? TokenTransferPreloader }, - stakeTransactionClients = preloaders.mapNotNull { it as? StakeTransactionPreloader }, - swapTransactionClients = preloaders.mapNotNull { it as? SwapTransactionPreloader }, - approvalTransactionClients = preloaders.mapNotNull { it as? ApprovalTransactionPreloader }, - activatePreloaderClients = preloaders.mapNotNull { it as? ActivationTransactionPreloader }, - genericPreloaderClients = preloaders.mapNotNull { it as? GenericTransferPreloader }, - nftPreloadClients = preloaders.mapNotNull { it as? NftTransactionPreloader }, ) } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt deleted file mode 100644 index a828994ed..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/AlgorandSignPreloadClient.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.gemwallet.android.blockchain.clients.algorand - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.algorand.services.AlgorandService -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority - -class AlgorandSignPreloadClient( - private val chain: Chain, - private val feeService: AlgorandService, -) : NativeTransferPreloader { - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - val txParams = feeService.transactionsParams().getOrNull() ?: throw Exception("fee load error") - val fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(chain), - amount = txParams.min_fee.toBigInteger(), - ) - return SignerParams( - input = params, - chainData = AlgorandChainData( - sequence = txParams.last_round.toULong(), - block = txParams.genesis_hash, - chainId = txParams.genesis_id, - ), - fee = listOf(fee) - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandService.kt deleted file mode 100644 index 64cb2e970..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/algorand/services/AlgorandService.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.gemwallet.android.blockchain.clients.algorand.services - -import com.wallet.core.blockchain.algorand.AlgorandTransactionParams -import retrofit2.http.GET - -interface AlgorandService { - @GET("/v2/transactions/params") - suspend fun transactionsParams(): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt deleted file mode 100644 index 55c9d7017..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosFeeCalculator.kt +++ /dev/null @@ -1,102 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.aptos.services.AptosServices -import com.gemwallet.android.ext.type -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.GasFee -import com.wallet.core.blockchain.aptos.AptosSignature -import com.wallet.core.blockchain.aptos.AptosTransaction -import com.wallet.core.blockchain.aptos.AptosTransactionPayload -import com.wallet.core.blockchain.aptos.AptosTransactionSimulation -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetSubtype -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.withContext -import java.math.BigInteger - -internal class AptosFeeCalculator( - private val chain: Chain, - private val aptosServices: AptosServices, -) { - private val maxGasAmount = BigInteger.valueOf(1_500) - - suspend fun calculate(params: ConfirmParams, sequence: ULong): List = withContext(Dispatchers.IO) { - val feePrice = aptosServices.feePrice().getOrThrow() - - FeePriority.entries.map { - async(Dispatchers.IO) { - val price = when (it) { - FeePriority.Slow -> feePrice.gas_estimate - FeePriority.Normal -> feePrice.prioritized_gas_estimate - FeePriority.Fast -> feePrice.prioritized_gas_estimate * 2 - }.toBigInteger() - - val gasLimit = when (params) { - is ConfirmParams.TransferParams -> { - val recipient = params.destination().address - when (params.asset.id.type()) { - AssetSubtype.NATIVE -> simulateTransactions( - sender = params.from.address, - recipient = recipient, - sequence = sequence, - value = params.amount, - gasPrice = price, - maxGasAmount = maxGasAmount - ).gas_used.toBigInteger() - - AssetSubtype.TOKEN -> maxGasAmount - } - } - is ConfirmParams.SwapParams -> maxGasAmount - else -> throw IllegalArgumentException("not supported operation") - } - - GasFee( - feeAssetId = AssetId(chain), - priority = it, - maxGasPrice = price, - limit = gasLimit, - ) - } - }.awaitAll() - } - - private suspend fun simulateTransactions( - sender: String, - recipient: String, - sequence: ULong, - value: BigInteger, - gasPrice: BigInteger, - maxGasAmount: BigInteger - ): AptosTransaction { - val transaction = AptosTransactionSimulation( - expiration_timestamp_secs = (System.currentTimeMillis() / 1_000 + 1_000_000).toString(), - gas_unit_price = gasPrice.toString(), - max_gas_amount = maxGasAmount.toString(), - payload = AptosTransactionPayload( - arguments = listOf( - recipient, - value.toString(), - ), - function = "0x1::aptos_account::transfer", - type = "entry_function_payload", - type_arguments = emptyList(), - ), - sender = sender, - sequence_number = sequence.toString(), - signature = AptosSignature( - type = "no_account_signature", - public_key = null, - signature = null, - ), - ) - val response = aptosServices.simulate(transaction) - val simulated = response.getOrNull()?.firstOrNull() - return simulated ?: throw Exception("No aptos transaction") - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt deleted file mode 100644 index 9d73c9cb3..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/AptosSignerPreloader.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.clients.aptos.services.AptosServices -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Chain - -class AptosSignerPreloader( - private val chain: Chain, - private val aptosServices: AptosServices, -) : NativeTransferPreloader, TokenTransferPreloader, SwapTransactionPreloader { - - private val feeCalculator = AptosFeeCalculator(chain, aptosServices) - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - return preloadTransfer(params) - } - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { - return preloadTransfer(params) - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - return preloadTransfer(params) - } - - private suspend fun preloadTransfer(params: ConfirmParams): SignerParams { - val sequence = try { - val response = aptosServices.accounts(params.from.address).getOrThrow() - response.sequence_number?.toULong() ?: 0UL - } catch (_: Throwable) { - 0UL - } - val fee = feeCalculator.calculate(params, sequence) - val input = SignerParams(params, AptosChainData(sequence), fee = fee) - return input - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/models/AptosAccount.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/models/AptosAccount.kt deleted file mode 100644 index 2e392a49e..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/models/AptosAccount.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos.models - -import kotlinx.serialization.Serializable - -@Serializable -data class AptosAccount( - val sequence_number: String?, - val message: String?, - val error_code: String?, -) \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosServices.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosServices.kt deleted file mode 100644 index 701eebe77..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/aptos/services/AptosServices.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos.services - -import com.gemwallet.android.blockchain.clients.aptos.models.AptosAccount -import com.wallet.core.blockchain.aptos.AptosGasFee -import com.wallet.core.blockchain.aptos.AptosTransaction -import com.wallet.core.blockchain.aptos.AptosTransactionSimulation -import retrofit2.http.Body -import retrofit2.http.GET -import retrofit2.http.Headers -import retrofit2.http.POST -import retrofit2.http.Path - -interface AptosServices { - @GET("/v1/accounts/{address}") - suspend fun accounts(@Path("address") address: String): Result - - @GET("/v1/estimate_gas_price") - suspend fun feePrice(): Result - - @Headers("Content-type: application/json") - @POST("/v1/transactions/simulate?estimate_max_gas_amount=true") - suspend fun simulate(@Body data: AptosTransactionSimulation): Result> -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt deleted file mode 100644 index b05ca0304..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinFeeCalculator.kt +++ /dev/null @@ -1,129 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin - -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinRpcClient -import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy -import com.gemwallet.android.ext.toBitcoinChain -import com.gemwallet.android.model.Crypto -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.GasFee -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.BitcoinChain -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import com.wallet.core.primitives.UTXO -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.withContext -import uniffi.gemstone.Config -import wallet.core.java.AnySigner -import wallet.core.jni.BitcoinSigHashType -import wallet.core.jni.CoinTypeConfiguration -import wallet.core.jni.proto.Bitcoin -import wallet.core.jni.proto.Common -import java.math.BigDecimal -import java.math.BigInteger -import java.math.RoundingMode - -class BitcoinFeeCalculator( - private val client: BitcoinRpcClient, -) { - suspend fun calculate( - utxos: List, - account: Account, - recipient: String, - amount: BigInteger, - ): List = withContext(Dispatchers.IO) { - val ownerAddress = account.address - val chain = account.chain - FeePriority.entries.map { - async { - val price = estimateFeePrice(chain, it) - val limit = - calcFee(chain, ownerAddress, recipient, amount.toLong(), price.toLong(), utxos) - GasFee( - feeAssetId = AssetId(chain), - priority = it, - maxGasPrice = price, - limit = limit - ) - } - }.awaitAll() - } - - private suspend fun estimateFeePrice(chain: Chain, speed: FeePriority): BigInteger { - val decimals = CoinTypeConfiguration.getDecimals(WCChainTypeProxy().invoke(chain)) - val minimumByteFee = getMinimumByteFee(chain) - val priority = Config().getBitcoinChainConfig(chain.toBitcoinChain().string).blocksFeePriority.let { - when (speed) { - FeePriority.Slow -> it.slow - FeePriority.Normal -> it.normal - FeePriority.Fast -> it.fast - } - }.toString() - return client.estimateFee(priority).fold( - { - val networkFeePerKb = Crypto(it.result, decimals).atomicValue - val feePerByte = networkFeePerKb.toBigDecimal().divide(BigDecimal(1000), RoundingMode.CEILING).toBigInteger() - return minimumByteFee.max(feePerByte) - } - ) { - minimumByteFee - } - } - - private fun calcFee( - chain: Chain, - from: String, - to: String, - amount: Long, - bytePrice: Long, - utxos: List, - ): BigInteger { - val coinType = WCChainTypeProxy().invoke(chain) - val total = utxos.map { it.value.toLong() }.fold(0L) { x, y -> x + y } - if (total == 0L) { - return BigInteger.ZERO // empty balance - } - val input = Bitcoin.SigningInput.newBuilder().apply { - this.hashType = BitcoinSigHashType.ALL.value() - this.byteFee = bytePrice - this.amount = amount - this.useMaxAmount = total == amount - this.coinType = coinType.value() - this.toAddress = to - this.changeAddress = from - this.addAllUtxo(utxos.getUtxoTransactions(from, coinType)) - }.build() - - val plan = AnySigner.plan(input, coinType, Bitcoin.TransactionPlan.parser()) - when (plan.error) { - Common.SigningError.OK -> { /* continue */ } - Common.SigningError.Error_not_enough_utxos, - Common.SigningError.Error_dust_amount_requested, - Common.SigningError.Error_missing_input_utxos -> throw IllegalStateException("Dust Error: $bytePrice") - else -> throw IllegalStateException(plan.error.name) - } - - val selectedUtxos: MutableList = mutableListOf() - for (raw in plan.utxosList) { - input.utxoList?.indexOfFirst { it == raw }?.let { - selectedUtxos.add(utxos[it]) - } - } - if (utxos.isNotEmpty() && selectedUtxos.isEmpty() && amount != total && amount <= total) { - return calcFee(chain, from, to, total, bytePrice, utxos) - } - return BigInteger.valueOf(plan.fee / bytePrice) - } - - companion object { - fun getMinimumByteFee(chain: Chain) = when (chain.toBitcoinChain()) { - BitcoinChain.Litecoin -> BigInteger("5") - BitcoinChain.Doge -> BigInteger("1000") - BitcoinChain.BitcoinCash, - BitcoinChain.Bitcoin -> BigInteger.ONE - } - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt index 6dd3923d1..e06168b5f 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinGatewayEstimateFee.kt @@ -31,10 +31,17 @@ class BitcoinGatewayEstimateFee : GemGatewayEstimateFee { ?: throw IllegalArgumentException("Incorrect Byte Price") val amount = input.value.toLongOrNull() ?: return null - val destination = input.destinationAddress - val from = input.senderAddress + val destinationAddress = input.destinationAddress + val senderAddress = input.senderAddress - val fee = calcFee(chain, from, destination, amount, bytePrice, utxos) + val fee = calcFee( + chain = chain, + senderAddress = senderAddress, + destinationAddress = destinationAddress, + amount = amount, + bytePrice = bytePrice, + utxos = utxos + ) return GemTransactionLoadFee( fee = fee.toString(), @@ -53,8 +60,8 @@ class BitcoinGatewayEstimateFee : GemGatewayEstimateFee { private fun calcFee( chain: com.wallet.core.primitives.Chain, - from: String, - to: String, + senderAddress: String, + destinationAddress: String, amount: Long, bytePrice: Long, utxos: List, @@ -70,9 +77,9 @@ class BitcoinGatewayEstimateFee : GemGatewayEstimateFee { this.amount = amount this.useMaxAmount = total == amount this.coinType = coinType.value() - this.toAddress = to - this.changeAddress = from - this.addAllUtxo(utxos.getUtxoTransactions(from, coinType)) + this.toAddress = destinationAddress + this.changeAddress = senderAddress + this.addAllUtxo(utxos.getUtxoTransactions(senderAddress, coinType)) }.build() val plan = AnySigner.plan(input, coinType, Bitcoin.TransactionPlan.parser()) @@ -91,8 +98,8 @@ class BitcoinGatewayEstimateFee : GemGatewayEstimateFee { } } if (utxos.isNotEmpty() && selectedUtxos.isEmpty() && amount != total && amount <= total) { - return calcFee(chain, from, to, total, bytePrice, utxos) + return calcFee(chain, senderAddress, destinationAddress, total, bytePrice, utxos) } - return BigInteger.valueOf(plan.fee / bytePrice) + return BigInteger.valueOf(plan.fee/* / bytePrice*/) // } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt deleted file mode 100644 index d4d45b78b..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/BitcoinSignerPreloader.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinRpcClient -import com.gemwallet.android.ext.fullAddress -import com.gemwallet.android.ext.toBitcoinChain -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.UTXO -import java.math.BigInteger - -class BitcoinSignerPreloader( - private val chain: Chain, - private val client: BitcoinRpcClient, -) : NativeTransferPreloader, SwapTransactionPreloader { - - private val feeCalculator = BitcoinFeeCalculator(client) - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - val data = preload(params, params.from, params.destination().address, params.amount) - return data - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - val data = preload(params, params.from, params.destination().address, params.amount) - return data - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - - private suspend fun preload(params: ConfirmParams, fromAccount: Account, destinationAddress: String, amount: BigInteger): SignerParams { - val address = chain.toBitcoinChain().fullAddress(fromAccount.address) - val utxo = client.getUTXO(address).getOrNull()?.map { - UTXO( - it.txid, - it.vout, - it.value, - "" - ) - } ?: throw Exception("Can't load UTXO") - val fee = feeCalculator.calculate(utxo, fromAccount, destinationAddress, amount) - return SignerParams( - params, - BitcoinChainData(utxo), - fee, - ) - } - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt deleted file mode 100644 index e1de1675c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/services/BitcoinRpcClient.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.gemwallet.android.blockchain.clients.bitcoin.services - -import com.wallet.core.blockchain.bitcoin.BitcoinFeeResult -import com.wallet.core.blockchain.bitcoin.BitcoinUTXO -import retrofit2.http.GET -import retrofit2.http.Path - -interface BitcoinRpcClient { - @GET("/api/v2/estimatefee/{priority}") - suspend fun estimateFee(@Path("priority") priority: String): Result - - @GET("/api/v2/utxo/{address}") - suspend fun getUTXO(@Path("address") address: String): Result> -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoGatewayEstimateFee.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoGatewayEstimateFee.kt new file mode 100644 index 000000000..89a22338e --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoGatewayEstimateFee.kt @@ -0,0 +1,83 @@ +package com.gemwallet.android.blockchain.clients.cardano + +import com.gemwallet.android.blockchain.services.mapper.toUtxo +import com.gemwallet.android.math.decodeHex +import com.google.protobuf.ByteString +import com.wallet.core.primitives.UTXO +import uniffi.gemstone.Chain +import uniffi.gemstone.GemFeeOptions +import uniffi.gemstone.GemGatewayEstimateFee +import uniffi.gemstone.GemTransactionLoadFee +import uniffi.gemstone.GemTransactionLoadInput +import uniffi.gemstone.GemTransactionLoadMetadata +import wallet.core.java.AnySigner +import wallet.core.jni.CoinType +import wallet.core.jni.proto.Cardano +import java.math.BigInteger + +class CardanoGatewayEstimateFee : GemGatewayEstimateFee { + override suspend fun getFee( + chain: Chain, + input: GemTransactionLoadInput + ): GemTransactionLoadFee? { + val utxos = (input.metadata as? GemTransactionLoadMetadata.Bitcoin)?.utxos?.toUtxo() + ?: throw IllegalArgumentException("Incorrect UTXO") + + val amount = input.value.toLongOrNull() ?: return null + + val destination = input.destinationAddress + val from = input.senderAddress + + val fee = calcFee( + from = from, + to = destination, amount, + useMaxAmount = input.isMaxValue, + utxos + ) + + return GemTransactionLoadFee( + fee = fee.toString(), + gasPriceType = input.gasPrice, + gasLimit = "1", + options = GemFeeOptions(emptyMap()) + ) + } + + override suspend fun getFeeData( + chain: Chain, + input: GemTransactionLoadInput + ): String? { + return null + } + + private fun calcFee( + from: String, + to: String, + amount: Long, + useMaxAmount: Boolean, + utxos: List, + ): BigInteger { + val signingInput = Cardano.SigningInput.newBuilder().apply { + this.addAllUtxos( + utxos.map { utxo -> + Cardano.TxInput.newBuilder().apply { + this.address = utxo.address + this.amount = utxo.value.toLong() + this.outPoint = Cardano.OutPoint.newBuilder().apply { + this.txHash = ByteString.copyFrom(utxo.transaction_id.decodeHex()) + this.outputIndex = utxo.vout.toLong() + }.build() + }.build() + } + ) + this.transferMessage = Cardano.Transfer.newBuilder().apply { + this.toAddress = to + this.changeAddress = from + this.amount = amount + this.useMaxAmount = useMaxAmount + }.build() + }.build() + val plan: Cardano.TransactionPlan = AnySigner.plan(signingInput, CoinType.CARDANO, Cardano.TransactionPlan.parser()) + return plan.fee.toBigInteger() + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignerPreloaderClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignerPreloaderClient.kt deleted file mode 100644 index a19cf458f..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoSignerPreloaderClient.kt +++ /dev/null @@ -1,71 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.cardano.services.CardanoServices -import com.gemwallet.android.blockchain.clients.cardano.services.utxos -import com.gemwallet.android.math.decodeHex -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.SignerParams -import com.google.protobuf.ByteString -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import com.wallet.core.primitives.UTXO -import wallet.core.java.AnySigner -import wallet.core.jni.CoinType -import wallet.core.jni.proto.Cardano - -class CardanoSignerPreloaderClient( - private val chain: Chain, - private val feeServices: CardanoServices -) : NativeTransferPreloader { - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - val utxos = feeServices.utxos(params.from.address) - val fee = calculateFee(params, utxos) - - return SignerParams( - input = params, - chainData = CardanoChainData( - utxos = utxos, - ), - fee = listOf( - Fee( - feeAssetId = AssetId(chain), - priority = FeePriority.Normal, - amount = fee.toBigInteger(), - ) - ), - ) - } - - - override fun supported(chain: Chain): Boolean = this.chain == chain - - private fun calculateFee(params: ConfirmParams.TransferParams.Native, utxos: List): Long { - val signingInput = Cardano.SigningInput.newBuilder().apply { - this.addAllUtxos( - utxos.map { utxo -> - Cardano.TxInput.newBuilder().apply { - this.address = utxo.address - this.amount = utxo.value.toLong() - this.outPoint = Cardano.OutPoint.newBuilder().apply { - this.txHash = ByteString.copyFrom(utxo.transaction_id.decodeHex()) - this.outputIndex = utxo.vout.toLong() - }.build() - }.build() - } - ) - this.transferMessage = Cardano.Transfer.newBuilder().apply { - this.toAddress = params.destination.address - this.changeAddress = params.from.address - this.amount = params.amount.toLong() - this.useMaxAmount = params.isMaxAmount - }.build() - }.build() - val plan: Cardano.TransactionPlan = AnySigner.plan(signingInput, CoinType.CARDANO, Cardano.TransactionPlan.parser()) - return plan.fee - } - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoServices.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoServices.kt deleted file mode 100644 index c93f0cda2..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/services/CardanoServices.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cardano.services - -import com.wallet.core.blockchain.cardano.CardanoUTXO -import com.wallet.core.blockchain.cardano.CardanoUTXOS -import com.wallet.core.primitives.GraphqlData -import com.wallet.core.primitives.GraphqlRequest -import com.wallet.core.primitives.UTXO -import retrofit2.http.Body -import retrofit2.http.POST - -interface CardanoServices { - @POST("/") - suspend fun utxos(@Body request: GraphqlRequest): Result>>> -} - -suspend fun CardanoServices.utxos(address: String): List { - val request = GraphqlRequest( - operationName = "UtxoSetForAddress", - variables = hashMapOf("address" to address), - query = "query UtxoSetForAddress(\$address: String!) { utxos(order_by: { value: desc } , where: { address: { _eq: \$address } } ) { address value txHash index tokens { quantity asset { fingerprint policyId assetName } } } }" - ) - return utxos(request).getOrNull()?.data?.utxos?.map { - UTXO( - transaction_id = it.txHash, - vout = it.index, - value = it.value, - address = it.address, - ) - } ?: emptyList() -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosFeeCalculator.kt deleted file mode 100644 index 6f9d15414..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosFeeCalculator.kt +++ /dev/null @@ -1,65 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.GasFee -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import com.wallet.core.primitives.TransactionType -import java.math.BigInteger - -class CosmosFeeCalculator( - private val chain: Chain, -) { - fun calculate(txType: TransactionType): Fee { - val assetId = AssetId(chain) - val maxGasFee = when (chain) { - Chain.Cosmos -> when (txType) { - TransactionType.Transfer, TransactionType.Swap -> BigInteger.valueOf(3_000L) - else -> BigInteger.valueOf(25_000L) - } - Chain.Osmosis -> when (txType) { - TransactionType.Transfer, TransactionType.Swap -> BigInteger.valueOf(10_000L) - else -> BigInteger.valueOf(100_000L) - } - - Chain.Thorchain -> BigInteger.valueOf(2_000_000) - Chain.Celestia -> when (txType){ - TransactionType.Transfer, TransactionType.Swap -> BigInteger.valueOf(3_000L) - else -> BigInteger.valueOf(10_000L) - } - Chain.Injective -> when (txType){ - TransactionType.Transfer, TransactionType.Swap -> BigInteger.valueOf(100_000_000_000_000L) - else -> BigInteger.valueOf(1_000_000_000_000_000L) - } - Chain.Sei -> when (txType){ - TransactionType.Transfer, TransactionType.Swap -> BigInteger.valueOf(100_000L) - else -> BigInteger.valueOf(200_000L) - } - Chain.Noble -> BigInteger.valueOf(25_000) - else -> throw IllegalArgumentException("Unsupported chain") - } - val limit = when (txType) { - TransactionType.Transfer, TransactionType.Swap -> BigInteger.valueOf(200_000L) - TransactionType.StakeDelegate, - TransactionType.StakeUndelegate -> BigInteger.valueOf(1_000_000) - TransactionType.StakeRewards -> BigInteger.valueOf(900_000) - TransactionType.StakeRedelegate -> BigInteger.valueOf(1_250_000) - TransactionType.StakeWithdraw, - TransactionType.AssetActivation, - TransactionType.TransferNFT, - TransactionType.SmartContractCall, - TransactionType.PerpetualOpenPosition, - TransactionType.PerpetualClosePosition, - TransactionType.TokenApproval -> throw IllegalArgumentException("Chain not available: no limit fee") - - } - return GasFee( - feeAssetId = assetId, - priority = FeePriority.Normal, - maxGasPrice = maxGasFee, - amount = maxGasFee, - limit = limit, - ) - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt deleted file mode 100644 index dab00f4fa..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignerPreloader.kt +++ /dev/null @@ -1,64 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosRpcClient -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class CosmosSignerPreloader( - private val chain: Chain, - private val client: CosmosRpcClient, -) : NativeTransferPreloader, TokenTransferPreloader, StakeTransactionPreloader, SwapTransactionPreloader { - - private val feeCalculator = CosmosFeeCalculator(chain) - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { - return preload(params) - } - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - return preload(params) - } - override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams { - return preload(params) - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - return preload(params) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - - private suspend fun preload(params: ConfirmParams) = withContext(Dispatchers.IO) { - val accountJob = async { - when (chain) { - Chain.Injective -> client.getInjectiveAccountData(params.from.address).getOrNull()?.account?.base_account - else -> client.getAccountData(params.from.address).getOrNull()?.account - } - } - val nodeInfoJob = async { client.getNodeInfo().getOrNull()?.block?.header?.chain_id } - val fee = feeCalculator.calculate(params.getTxType()) - - val (account, nodeInfo) = Pair( - accountJob.await() ?: throw Exception("Can't get data (account) for sign"), - nodeInfoJob.await() ?: throw Exception("Can't get data (node info) for sign") - ) - SignerParams( - input = params, - chainData = CosmosChainData( - chainId = nodeInfo, - accountNumber = account.account_number.toULong(), - sequence = account.sequence.toULong(), - ), - fee = listOf(fee), - ) - } - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosRpcClient.kt deleted file mode 100644 index 050d14233..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/services/CosmosRpcClient.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos.services - -import com.wallet.core.blockchain.cosmos.CosmosAccount -import com.wallet.core.blockchain.cosmos.CosmosAccountResponse -import com.wallet.core.blockchain.cosmos.CosmosBlockResponse -import com.wallet.core.blockchain.cosmos.CosmosInjectiveAccount -import retrofit2.http.GET -import retrofit2.http.Path - -interface CosmosRpcClient { - @GET("/cosmos/auth/v1beta1/accounts/{owner}") - suspend fun getAccountData(@Path("owner") owner: String): Result> - - @GET("/cosmos/auth/v1beta1/accounts/{owner}") - suspend fun getInjectiveAccountData(@Path("owner") owner: String): Result> - - @GET("/cosmos/base/tendermint/v1beta1/blocks/latest") - suspend fun getNodeInfo(): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/StakeHub.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/StakeHub.kt index 3479269d8..13c37a184 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/StakeHub.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/StakeHub.kt @@ -8,133 +8,134 @@ import com.wallet.core.primitives.Chain import com.wallet.core.primitives.DelegationBase import com.wallet.core.primitives.DelegationState import com.wallet.core.primitives.DelegationValidator -import uniffi.gemstone.BscDelegation -import uniffi.gemstone.BscDelegationStatus +//import uniffi.gemstone.BscDelegation +//import uniffi.gemstone.BscDelegationStatus object StakeHub { val offset: UShort = (0).toUShort() const val address = "0x0000000000000000000000000000000000002002" - const val reader = "0x830295c0abe7358f7e24bc38408095621474280b" - - fun encodeMaxElectedValidators(): String { - // cast calldata "maxElectedValidators()" - return "0xc473318f" - } - +// const val reader = "0x830295c0abe7358f7e24bc38408095621474280b" +// +// fun encodeMaxElectedValidators(): String { +// // cast calldata "maxElectedValidators()" +// return "0xc473318f" +// } +// fun encodeStake(params: ConfirmParams): String { - return when (params) { - is ConfirmParams.Stake.DelegateParams -> encodeDelegateCall(params.validatorId, false) - - is ConfirmParams.Stake.RedelegateParams -> encodeRedelegateCall(params, false) - is ConfirmParams.Stake.UndelegateParams -> encodeUndelegateCall(params) - is ConfirmParams.Stake.WithdrawParams -> encodeClaim(params, (0).toULong()) - else -> throw IllegalArgumentException() - }.toHexString() - } - - fun encodeDelegateCall(validator: String, delegateVote: Boolean): ByteArray { - return uniffi.gemstone.bscEncodeDelegateCall(validator, delegateVote) - } - - fun encodeValidatorsCall(offset: Int, limit: Int): String { - return uniffi.gemstone.bscEncodeValidatorsCall(offset.toUShort(), limit.toUShort()) - .toHexString() - } - - fun decodeValidatorsReturn(hexData: String): List { - return uniffi.gemstone.bscDecodeValidatorsReturn(hexData.decodeHex()).map { - DelegationValidator( - chain = Chain.SmartChain, - id = it.operatorAddress, - name = it.moniker, - isActive = !it.jailed, - commision = it.commission.toDouble() / 100, - apr = it.apy.toDouble() / 100, - ) - } - } - - fun encodeDelegationsCall(address: String, limit: Int): String { - return uniffi.gemstone.bscEncodeDelegationsCall(address, offset, limit.toUShort()) - .toHexString() - } - - fun decodeDelegationsResult(data: String): List { - return uniffi.gemstone.bscDecodeDelegationsReturn(data.decodeHex()).map { it.into() } - } - - fun encodeUndelegationsCall(address: String, limit: Int): String { - return uniffi.gemstone.bscEncodeUndelegationsCall(address, offset, limit.toUShort()) - .toHexString() - } - - fun decodeUnelegationsResult(data: String): List { - return uniffi.gemstone.bscDecodeUndelegationsReturn(data.decodeHex()).map { it.into() } - } - - fun encodeUndelegateCall(params: ConfirmParams.Stake.UndelegateParams): ByteArray { - val amountShare = - params.amount * params.share!!.toBigInteger() / params.balance!!.toBigInteger() - return uniffi.gemstone.bscEncodeUndelegateCall( - operatorAddress = params.validatorId, - shares = amountShare.toString() - ) - } - - fun encodeRedelegateCall( - params: ConfirmParams.Stake.RedelegateParams, - votePower: Boolean - ): ByteArray { - val amountShare = - params.amount * params.share!!.toBigInteger() / params.balance!!.toBigInteger() - return uniffi.gemstone.bscEncodeRedelegateCall( - srcValidator = params.srcValidatorId, - dstValidator = params.dstValidatorId, - shares = amountShare.toString(), - delegateVotePower = votePower, - ) - } - - fun encodeClaim( - params: ConfirmParams.Stake.WithdrawParams, - requestNumber: ULong - ): ByteArray { - return uniffi.gemstone.bscEncodeClaimCall( - operatorAddress = params.validatorId, - requestNumber = requestNumber - ) - } -} - -fun BscDelegation.into(): DelegationBase { - val completion = when (status) { - BscDelegationStatus.ACTIVE -> null - BscDelegationStatus.UNDELEGATING -> unlockTime?.toLong() - }?.toLong() - val state = when (status) { - BscDelegationStatus.ACTIVE -> DelegationState.Active - BscDelegationStatus.UNDELEGATING -> { - if (completion == null) { - DelegationState.Undelegating - } else if (System.currentTimeMillis() <= completion * 1000) { - DelegationState.Undelegating - } else { - DelegationState.AwaitingWithdrawal - } - } - } - val delegationId = when (status) { - BscDelegationStatus.ACTIVE -> "" - BscDelegationStatus.UNDELEGATING -> "$validatorAddress--${unlockTime ?: 0}" + return "" +// return when (params) { +// is ConfirmParams.Stake.DelegateParams -> encodeDelegateCall(params.validatorId, false) +// +// is ConfirmParams.Stake.RedelegateParams -> encodeRedelegateCall(params, false) +// is ConfirmParams.Stake.UndelegateParams -> encodeUndelegateCall(params) +// is ConfirmParams.Stake.WithdrawParams -> encodeClaim(params, (0).toULong()) +// else -> throw IllegalArgumentException() +// }.toHexString() } - return DelegationBase( - assetId = Chain.SmartChain.asset().id, - state = state, - balance = amount, - shares = shares, - rewards = "0", - completionDate = completion, - delegationId = delegationId, - validatorId = validatorAddress, - ) +// +// fun encodeDelegateCall(validator: String, delegateVote: Boolean): ByteArray { +// return uniffi.gemstone.bscEncodeDelegateCall(validator, delegateVote) +// } +// +// fun encodeValidatorsCall(offset: Int, limit: Int): String { +// return uniffi.gemstone.bscEncodeValidatorsCall(offset.toUShort(), limit.toUShort()) +// .toHexString() +// } +// +// fun decodeValidatorsReturn(hexData: String): List { +// return uniffi.gemstone.bscDecodeValidatorsReturn(hexData.decodeHex()).map { +// DelegationValidator( +// chain = Chain.SmartChain, +// id = it.operatorAddress, +// name = it.moniker, +// isActive = !it.jailed, +// commision = it.commission.toDouble() / 100, +// apr = it.apy.toDouble() / 100, +// ) +// } +// } +// +// fun encodeDelegationsCall(address: String, limit: Int): String { +// return uniffi.gemstone.bscEncodeDelegationsCall(address, offset, limit.toUShort()) +// .toHexString() +// } +// +// fun decodeDelegationsResult(data: String): List { +// return uniffi.gemstone.bscDecodeDelegationsReturn(data.decodeHex()).map { it.into() } +// } +// +// fun encodeUndelegationsCall(address: String, limit: Int): String { +// return uniffi.gemstone.bscEncodeUndelegationsCall(address, offset, limit.toUShort()) +// .toHexString() +// } +// +// fun decodeUnelegationsResult(data: String): List { +// return uniffi.gemstone.bscDecodeUndelegationsReturn(data.decodeHex()).map { it.into() } +// } +// +// fun encodeUndelegateCall(params: ConfirmParams.Stake.UndelegateParams): ByteArray { +// val amountShare = +// params.amount * params.share!!.toBigInteger() / params.balance!!.toBigInteger() +// return uniffi.gemstone.bscEncodeUndelegateCall( +// operatorAddress = params.validatorId, +// shares = amountShare.toString() +// ) +// } +// +// fun encodeRedelegateCall( +// params: ConfirmParams.Stake.RedelegateParams, +// votePower: Boolean +// ): ByteArray { +// val amountShare = +// params.amount * params.share!!.toBigInteger() / params.balance!!.toBigInteger() +// return uniffi.gemstone.bscEncodeRedelegateCall( +// srcValidator = params.srcValidatorId, +// dstValidator = params.dstValidatorId, +// shares = amountShare.toString(), +// delegateVotePower = votePower, +// ) +// } +// +// fun encodeClaim( +// params: ConfirmParams.Stake.WithdrawParams, +// requestNumber: ULong +// ): ByteArray { +// return uniffi.gemstone.bscEncodeClaimCall( +// operatorAddress = params.validatorId, +// requestNumber = requestNumber +// ) +// } +//} +// +//fun BscDelegation.into(): DelegationBase { +// val completion = when (status) { +// BscDelegationStatus.ACTIVE -> null +// BscDelegationStatus.UNDELEGATING -> unlockTime?.toLong() +// }?.toLong() +// val state = when (status) { +// BscDelegationStatus.ACTIVE -> DelegationState.Active +// BscDelegationStatus.UNDELEGATING -> { +// if (completion == null) { +// DelegationState.Undelegating +// } else if (System.currentTimeMillis() <= completion * 1000) { +// DelegationState.Undelegating +// } else { +// DelegationState.AwaitingWithdrawal +// } +// } +// } +// val delegationId = when (status) { +// BscDelegationStatus.ACTIVE -> "" +// BscDelegationStatus.UNDELEGATING -> "$validatorAddress--${unlockTime ?: 0}" +// } +// return DelegationBase( +// assetId = Chain.SmartChain.asset().id, +// state = state, +// balance = amount, +// shares = shares, +// rewards = "0", +// completionDate = completion, +// delegationId = delegationId, +// validatorId = validatorAddress, +// ) } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignerPreloaderClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignerPreloaderClient.kt deleted file mode 100644 index a5f0909cb..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/HyperCoreSignerPreloaderClient.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.gemwallet.android.blockchain.clients.hyper - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Chain - -class HyperCoreSignerPreloaderClient( - private val chain: Chain, -) : NativeTransferPreloader, TokenTransferPreloader, StakeTransactionPreloader { - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - TODO("Not yet implemented") - } - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { - TODO("Not yet implemented") - } - - override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams { - TODO("Not yet implemented") - } - - override fun supported(chain: Chain): Boolean = this.chain == chain -} diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/services/HyperCoreServices.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/services/HyperCoreServices.kt deleted file mode 100644 index ba62bb520..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/hyper/services/HyperCoreServices.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.gemwallet.android.blockchain.clients.hyper.services - -interface HyperCoreServices { -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearMethod.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearMethod.kt deleted file mode 100644 index 362b5f60a..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearMethod.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.gemwallet.android.blockchain.clients.near - -enum class NearMethod(val value: String) { - Query("query"), - LatestBlock("block"), -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt deleted file mode 100644 index 68edcbdab..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearRpcClient.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.gemwallet.android.blockchain.clients.near - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.gemwallet.android.math.decodeHex -import com.wallet.core.blockchain.near.NearAccount -import com.wallet.core.blockchain.near.NearAccountAccessKey -import com.wallet.core.blockchain.near.NearBlock -import retrofit2.http.Body -import retrofit2.http.POST -import wallet.core.jni.Base58 - -interface NearRpcClient { - - @POST("/") - suspend fun account(@Body params: JSONRpcRequest): Result> - - @POST("/") - suspend fun accountAccessKey(@Body params: JSONRpcRequest): Result> - - @POST("/") - suspend fun latestBlock(@Body params: JSONRpcRequest): Result> - -} - -suspend fun NearRpcClient.accountAccessKey(from: String, ): NearAccountAccessKey { - val publicKey = "ed25519:" + Base58.encodeNoCheck(from.decodeHex()) - return accountAccessKey( - JSONRpcRequest( - method = NearMethod.Query.value, - params = mapOf( - "request_type" to "view_access_key", - "finality" to "final", - "account_id" to from, - "public_key" to publicKey, - ) - ) - ).getOrNull()?.result ?: throw IllegalStateException("Can't get account") -} - -suspend fun NearRpcClient.latestBlock(): NearBlock { - return latestBlock( - JSONRpcRequest( - method = NearMethod.LatestBlock.value, - params = mapOf( - "finality" to "final", - ) - ) - ).getOrNull()?.result ?: throw IllegalStateException("Can't get block") -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignerPreloader.kt deleted file mode 100644 index 80bca264b..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/near/NearSignerPreloader.kt +++ /dev/null @@ -1,47 +0,0 @@ -package com.gemwallet.android.blockchain.clients.near - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import java.math.BigInteger - -class NearSignerPreloader( - private val chain: Chain, - private val rpcClient: NearRpcClient, -) : NativeTransferPreloader { - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams = withContext(Dispatchers.IO) { - val getAccountJob = async { rpcClient.accountAccessKey(params.from.address) } - val blockJob = async { rpcClient.latestBlock() } - - val account = getAccountJob.await() - val block = blockJob.await() - - val fee = BigInteger("900000000000000000000") - - SignerParams( - input = params, - chainData = NearChainData( - sequence = account.nonce.toULong() + 1UL, - block = block.header.hash, - ), - fee = listOf( - Fee( - feeAssetId = AssetId(chain), - priority = FeePriority.Normal, - amount = fee, - ) - ) - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt new file mode 100644 index 000000000..5e9cc41e4 --- /dev/null +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt @@ -0,0 +1,68 @@ +package com.gemwallet.android.blockchain.clients.polkadot + +import com.gemwallet.android.blockchain.services.mapper.toUtxo +import com.gemwallet.android.math.append0x +import com.gemwallet.android.math.decodeHex +import com.gemwallet.android.math.toHexString +import com.google.protobuf.ByteString +import com.wallet.core.blockchain.polkadot.PolkadotTransactionPayload +import com.wallet.core.primitives.UTXO +import uniffi.gemstone.Chain +import uniffi.gemstone.GemFeeOptions +import uniffi.gemstone.GemGatewayEstimateFee +import uniffi.gemstone.GemTransactionLoadFee +import uniffi.gemstone.GemTransactionLoadInput +import uniffi.gemstone.GemTransactionLoadMetadata +import wallet.core.java.AnySigner +import wallet.core.jni.CoinType +import wallet.core.jni.PrivateKey +import wallet.core.jni.proto.Cardano +import wallet.core.jni.proto.Polkadot +import java.math.BigInteger + +class PolkadotGatewayEstimateFee : GemGatewayEstimateFee { + override suspend fun getFee( + chain: Chain, + input: GemTransactionLoadInput + ): GemTransactionLoadFee? = null + + override suspend fun getFeeData( + chain: Chain, + input: GemTransactionLoadInput + ): String? { + val metadata = (input.metadata as? GemTransactionLoadMetadata.Polkadot) + ?.toChainData() + ?: throw IllegalArgumentException("Incorrect metadata: wait polkadot") + + val transactionData = transactionPayload( + toAdresss = input.destinationAddress, + value = input.value.toBigInteger(), + data = metadata, + ) + return transactionData + } + + fun transactionPayload(toAdresss: String, value: BigInteger, data: PolkadotChainData): String { + val input = Polkadot.SigningInput.newBuilder().apply { + this.genesisHash = ByteString.copyFrom(data.genesisHash.toByteArray()) + this.blockHash = ByteString.copyFrom(data.blockHash.toByteArray()) + this.nonce = data.sequence.toLong() + this.specVersion = data.specVersion.toInt() + this.network = CoinType.POLKADOT.ss58Prefix() + this.transactionVersion = data.transactionVersion.toInt() + this.privateKey = ByteString.copyFrom(PrivateKey().data()) + this.era = Polkadot.Era.newBuilder().apply { + this.blockNumber = data.blockNumber.toLong() + this.period = data.period + }.build() + this.balanceCall = Polkadot.Balance.newBuilder().apply { + transfer = Polkadot.Balance.Transfer.newBuilder().apply { + this.toAddress = toAdresss + this.value = ByteString.copyFrom(value.toByteArray()) + }.build() + }.build() + }.build() + + val output = AnySigner.sign(input, CoinType.POLKADOT, Polkadot.SigningOutput.parser()) + return output.encoded.toByteArray().toHexString().append0x() + } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt index daa82a83d..bb648fde1 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt @@ -1,7 +1,6 @@ package com.gemwallet.android.blockchain.clients.polkadot import com.gemwallet.android.blockchain.clients.SignClient -import com.gemwallet.android.blockchain.clients.polkadot.models.PolkadotSigningData import com.gemwallet.android.math.append0x import com.gemwallet.android.math.decodeHex import com.gemwallet.android.math.toHexString @@ -52,32 +51,4 @@ class PolkadotSignClient( } override fun supported(chain: Chain): Boolean = this.chain == chain - - companion object { - fun transactionPayload(toAdresss: String, value: BigInteger, nonce: ULong, data: PolkadotSigningData): String { - val input = Polkadot.SigningInput.newBuilder().apply { - this.genesisHash = ByteString.copyFrom(data.genesisHash.toByteArray()) - this.blockHash = ByteString.copyFrom(data.blockHash.toByteArray()) - this.nonce = nonce.toLong() - this.specVersion = data.specVersion.toInt() - this.network = CoinType.POLKADOT.ss58Prefix() - this.transactionVersion = data.transactionVersion.toInt() - this.privateKey = ByteString.copyFrom(PrivateKey().data()) - this.era = Polkadot.Era.newBuilder().apply { - this.blockNumber = data.blockNumber.toLong() - this.period = data.period - }.build() - this.balanceCall = Polkadot.Balance.newBuilder().apply { - transfer = Polkadot.Balance.Transfer.newBuilder().apply { - this.toAddress = toAdresss - this.value = ByteString.copyFrom(value.toByteArray()) - }.build() - }.build() - }.build() - - val output = AnySigner.sign(input, CoinType.POLKADOT, Polkadot.SigningOutput.parser()) - return output.encoded.toByteArray().toHexString().append0x() - } - - } } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt deleted file mode 100644 index 71ea83e98..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignerPreloaderClient.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.polkadot.models.PolkadotSigningData -import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotServices -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.SignerParams -import com.wallet.core.blockchain.polkadot.PolkadotTransactionPayload -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class PolkadotSignerPreloaderClient( - private val chain: Chain, - private val client: PolkadotServices, -) : NativeTransferPreloader { - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams = withContext(Dispatchers.IO) { - val getTransactionMaterial = async { client.transactionMaterial().getOrNull() } - val getBalance = async { client.balance(params.destination.address).getOrNull() } - val getNonce = async { client.balance(params.from.address).getOrNull()?.nonce?.toULong() } - - val transactionMaterial = getTransactionMaterial.await() ?: throw Exception("Can't load chain data") - val balance = getBalance.await() ?: throw Exception("Can't load chain data") - val nonce = getNonce.await() ?: throw Exception("Can't load nonce") - -// TODO: Check reserved 1DOT -// if (Crypto(balance.reserved).value(chain.asset().decimals) < BigDecimal.ONE) { -// throw IllegalStateException("Doesn't active recipient") -// } - - val signData = PolkadotSigningData( - genesisHash = transactionMaterial.genesisHash, - blockHash = transactionMaterial.at.hash, - blockNumber = transactionMaterial.at.height.toBigInteger(), - specVersion = transactionMaterial.specVersion.toBigInteger(), - transactionVersion = transactionMaterial.txVersion.toBigInteger(), - period = periodLength - ) - - val transactionData = PolkadotSignClient.transactionPayload( - params.destination.address, - params.amount, - nonce = nonce, - data = signData, - ) - val feeAmount = client.fee(PolkadotTransactionPayload(transactionData)).getOrNull()?.partialFee?.toBigInteger() - ?: throw java.lang.Exception("Can't estimate fee") - val fee = Fee( - priority = FeePriority.Normal, - feeAssetId = AssetId(chain), - amount = feeAmount - ) - SignerParams( - input = params, - chainData = PolkadotChainData( - sequence = nonce, - genesisHash = transactionMaterial.genesisHash, - blockHash = transactionMaterial.at.hash, - blockNumber = transactionMaterial.at.height.toULong(), - specVersion = transactionMaterial.specVersion.toULong(), - transactionVersion = transactionMaterial.txVersion.toULong(), - period = periodLength - ), - fee = listOf(fee) - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - - companion object { - const val periodLength: Long = 64 - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/models/PolkadotSigningData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/models/PolkadotSigningData.kt deleted file mode 100644 index da417bbe9..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/models/PolkadotSigningData.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot.models - -import com.gemwallet.android.serializer.BigIntegerSerializer -import kotlinx.serialization.Serializable -import java.math.BigInteger - -@Serializable -data class PolkadotSigningData( - val genesisHash: String, - val blockHash: String, - @Serializable(BigIntegerSerializer::class) val blockNumber: BigInteger, - @Serializable(BigIntegerSerializer::class) val specVersion: BigInteger, - @Serializable(BigIntegerSerializer::class) val transactionVersion: BigInteger, - val period: Long, -) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotServices.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotServices.kt deleted file mode 100644 index e91bb4d0c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/services/PolkadotServices.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.gemwallet.android.blockchain.clients.polkadot.services - -import com.wallet.core.blockchain.polkadot.PolkadotAccountBalance -import com.wallet.core.blockchain.polkadot.PolkadotEstimateFee -import com.wallet.core.blockchain.polkadot.PolkadotTransactionMaterial -import com.wallet.core.blockchain.polkadot.PolkadotTransactionPayload -import retrofit2.http.Body -import retrofit2.http.GET -import retrofit2.http.POST -import retrofit2.http.Path - -interface PolkadotServices { - @POST("/transaction/fee-estimate") - suspend fun fee(@Body data: PolkadotTransactionPayload): Result - - @GET("/accounts/{address}/balance-info") - suspend fun balance(@Path("address") address: String): Result - - @GET("/transaction/material?noMeta=true") - suspend fun transactionMaterial(): Result -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarFeeCalculator.kt deleted file mode 100644 index 47fa40643..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarFeeCalculator.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar - -import com.gemwallet.android.blockchain.clients.stellar.services.StellarService -import com.gemwallet.android.model.Fee -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import java.math.BigInteger - -class StellarFeeCalculator( - private val chain: Chain, - private val client: StellarService, -) { - suspend fun calculate(): List { - val fees = client.fee().getOrNull() ?: throw Exception("fee load error") - val min = BigInteger(fees.fee_charged.min).max(BigInteger(fees.last_ledger_base_fee)) - val assetId = AssetId(chain) - return listOf( - Fee( - priority = FeePriority.Slow, - feeAssetId = assetId, - amount = min, - ), - Fee( - priority = FeePriority.Normal, - feeAssetId = assetId, - amount = min, - ), - Fee( - priority = FeePriority.Fast, - feeAssetId = assetId, - amount = BigInteger(fees.fee_charged.p95) * BigInteger("2"), - ), - ) - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt deleted file mode 100644 index a423a814d..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignPreloadClient.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.stellar.services.StellarService -import com.gemwallet.android.blockchain.clients.stellar.services.accounts -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import java.math.BigInteger - -class StellarSignPreloadClient( - private val chain: Chain, - private val client: StellarService, -) : NativeTransferPreloader { - - private val feeCalculator = StellarFeeCalculator(chain, client) - - override suspend fun preloadNativeTransfer( - params: ConfirmParams.TransferParams.Native - ): SignerParams = withContext(Dispatchers.IO) { - val getAccount = async { client.accounts(params.from.address) } - val getIsDestinationAccountExist = async { - try { - client.accounts(params.destination.address) != null - } catch (_: Throwable) { - false - } - } - val getDefaultFees = async { feeCalculator.calculate() } - - val account = getAccount.await() - val isDestinationAccountExist = getIsDestinationAccountExist.await() - val defaultFees = getDefaultFees.await() - - if (account?.sequence == null) { - throw Exception("invalid sequence") - } - val fees = if (isDestinationAccountExist) { - defaultFees - } else { - defaultFees.map { - Fee( - priority = it.priority, - feeAssetId = it.feeAssetId, - amount = it.amount, - options = mapOf(StellarChainData.tokenAccountCreation to BigInteger.ZERO) - ) - } - } - SignerParams( - input = params, - chainData = StellarChainData( - sequence = account.sequence.toULong() + 1UL, - isDestinationAddressExist = true, - ), - fee = fees, - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarService.kt deleted file mode 100644 index 4e7e8e201..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/services/StellarService.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.gemwallet.android.blockchain.clients.stellar.services - -import com.wallet.core.blockchain.stellar.StellarAccount -import com.wallet.core.blockchain.stellar.StellarFees -import retrofit2.http.GET -import retrofit2.http.Path - -interface StellarService { - @GET("/accounts/{address}") - suspend fun loadAccounts(@Path("address") address: String): Result - - @GET("/fee_stats") - suspend fun fee(): Result -} - -suspend fun StellarService.accounts(address: String): StellarAccount? { - val result = loadAccounts(address) - - return result.getOrNull() -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiFeeCalculator.kt deleted file mode 100644 index d7fe6fb73..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiFeeCalculator.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui - -import com.gemwallet.android.model.Fee -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.FeePriority - -class SuiFeeCalculator( - private val rpcClient: SuiRpcClient, -) { - suspend fun calculate(account: Account, data: String): Fee { - val chain = account.chain - val gasUsed = rpcClient.dryRun(data) - val computationCost = gasUsed.computationCost.toBigInteger() - val storageCost = gasUsed.storageCost.toBigInteger() - val storageRebate = gasUsed.storageRebate.toBigInteger() - val fee = computationCost.max(computationCost + storageCost - storageRebate) - return Fee(feeAssetId = AssetId(chain), priority = FeePriority.Normal, amount = fee.abs()) - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt deleted file mode 100644 index ce88ed7a7..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiMethod.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcMethod - -enum class SuiMethod(val value: String) : JSONRpcMethod { - Coins("suix_getCoins"), - GasPrice("suix_getReferenceGasPrice"), - DryRun("sui_dryRunTransactionBlock"), - GetObject("sui_getObject"), - ; - - override fun value(): String = value -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiRpcClient.kt deleted file mode 100644 index 850af0a8e..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiRpcClient.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui - -import com.gemwallet.android.blockchain.clients.sui.model.SuiObject -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.sui.SuiBroadcastTransaction -import com.wallet.core.blockchain.sui.SuiCoin -import com.wallet.core.blockchain.sui.SuiCoinBalance -import com.wallet.core.blockchain.sui.SuiCoinMetadata -import com.wallet.core.blockchain.sui.SuiData -import com.wallet.core.blockchain.sui.SuiGasUsed -import com.wallet.core.blockchain.sui.SuiStakeDelegation -import com.wallet.core.blockchain.sui.SuiSystemState -import com.wallet.core.blockchain.sui.SuiTransaction -import com.wallet.core.blockchain.sui.SuiValidators -import retrofit2.Response -import retrofit2.http.Body -import retrofit2.http.POST -import retrofit2.http.Url - -interface SuiRpcClient { - - @POST("/") - suspend fun coins(@Body request: JSONRpcRequest>): Result>>> - - @POST("/") - suspend fun gasPrice(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun dryRun(@Body request: JSONRpcRequest>):Result> - - @POST("/") - suspend fun getObject(@Body request: JSONRpcRequest>): Result> -} - -internal suspend fun SuiRpcClient.coins(address: String, coinType: String): Result>>> { - return coins(JSONRpcRequest.create(SuiMethod.Coins, listOf(address, coinType))) -} - -internal suspend fun SuiRpcClient.dryRun(data: String): SuiGasUsed { - return dryRun(JSONRpcRequest.create(SuiMethod.DryRun, listOf(data))).getOrNull()?.result?.effects?.gasUsed - ?: throw Exception("Can't load SUI gas") -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignerPreloader.kt deleted file mode 100644 index 7ef8ab543..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiSignerPreloader.kt +++ /dev/null @@ -1,190 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import uniffi.gemstone.SuiCoin -import uniffi.gemstone.SuiGas -import uniffi.gemstone.SuiObjectRef -import uniffi.gemstone.SuiStakeInput -import uniffi.gemstone.SuiTokenTransferInput -import uniffi.gemstone.SuiTransferInput -import uniffi.gemstone.SuiTxOutput -import uniffi.gemstone.SuiUnstakeInput -import uniffi.gemstone.suiEncodeSplitStake -import uniffi.gemstone.suiEncodeTokenTransfer -import uniffi.gemstone.suiEncodeTransfer -import uniffi.gemstone.suiEncodeUnstake -import uniffi.gemstone.suiValidateAndHash -import wallet.core.jni.Base64 -import java.math.BigInteger - -class SuiSignerPreloader( - private val chain: Chain, - private val rpcClient: SuiRpcClient, -) : NativeTransferPreloader, TokenTransferPreloader, StakeTransactionPreloader, SwapTransactionPreloader { - - private val feeCalculator = SuiFeeCalculator(rpcClient) - - private val coinId = "0x2::sui::SUI" - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams = withContext(Dispatchers.IO) { - val sender = params.from.address - val getCoins = async { rpcClient.coins(sender, coinId).getOrThrow().result.data } - val getGasPrice = async { rpcClient.gasPrice(JSONRpcRequest.create(SuiMethod.GasPrice, emptyList())).getOrNull()?.result ?: "750" } - val coins = getCoins.await() - val gasPrice = getGasPrice.await() - val input = SuiTransferInput( - sender = sender, - recipient = params.destination.address, - amount = params.amount.toLong().toULong(), - coins = coins.map { it.togemstone() }, - sendMax = params.isMax(), - gas = SuiGas( - budget = gasBudget(coinId).toLong().toULong(), - price = gasPrice.toULong(), - ) - ) - val data = suiEncodeTransfer(input) - build(params, data) - } - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams = withContext(Dispatchers.IO) { - val sender = params.from.address - val getCoins = async { - rpcClient.coins(sender, params.assetId.tokenId!!).getOrThrow().result.data - } - val getGasCoins = async { - rpcClient.coins(sender, coinId).getOrThrow().result.data - } - val getGasPrice = async { rpcClient.gasPrice(JSONRpcRequest.create(SuiMethod.GasPrice, emptyList())).getOrNull()?.result ?: "750" } - val coins = getCoins.await() - val gasPrice = getGasPrice.await() - val gasCoins = getGasCoins.await() - val gas = gasCoins.firstOrNull() ?: throw IllegalStateException("no gas coin") - val input = SuiTokenTransferInput( - sender = sender, - recipient = params.destination.address, - amount = params.amount.toLong().toULong(), - tokens = coins.map { it.togemstone() }, - gas = SuiGas( - budget = gasBudget(coinId).toLong().toULong(), - price = gasPrice.toULong(), - ), - gasCoin = gas.togemstone(), - ) - val data = suiEncodeTokenTransfer(input) - build(params, data) - } - - override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams { - val data = when (params) { - is ConfirmParams.Stake.DelegateParams -> encodeStake( - sender = params.from.address, - validator = params.validatorId, - coinType = coinId, - value = params.amount, - ) - is ConfirmParams.Stake.UndelegateParams -> encodeUnstake( - sender = params.from.address, - coinType = coinId, - stakeId = params.delegationId, - ) - is ConfirmParams.Stake.RewardsParams, - is ConfirmParams.Stake.RedelegateParams, - is ConfirmParams.Stake.WithdrawParams -> throw IllegalArgumentException("Not supported") - } - return build(params, data) - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - val data = suiValidateAndHash(params.swapData) - return build(params, data) - } - - private suspend fun build(params: ConfirmParams, data: SuiTxOutput): SignerParams { - val fee = feeCalculator.calculate(params.from, Base64.encode(data.txData)) - - return SignerParams( - input = params, - chainData = SuiChainData( - messageBytes = "${Base64.encode(data.txData)}_${data.hash.toHexString()}", - ), - fee = listOf(fee), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - - private fun gasBudget(coinType: String): BigInteger = BigInteger.valueOf(25_000_000) - - private suspend fun encodeStake( - sender: String, - coinType: String, - value: BigInteger, - validator: String, - ) = withContext(Dispatchers.IO) { - val getCoins = async { rpcClient.coins(sender, coinType).getOrThrow().result.data } - val getGasPrice = async { rpcClient.gasPrice(JSONRpcRequest.create(SuiMethod.GasPrice, emptyList())).getOrNull()?.result ?: "750" } - val coins = getCoins.await() - val gasPrice = getGasPrice.await() - val input = SuiStakeInput( - sender = sender, - validator = validator, - stakeAmount = value.toLong().toULong(), - coins = coins.map { it.togemstone() }, - gas = SuiGas( - budget = gasBudget(coinType).toLong().toULong(), - price = gasPrice.toULong(), - ) - ) - suiEncodeSplitStake(input) - } - - private suspend fun encodeUnstake( - sender: String, - coinType: String, - stakeId: String, - ) = withContext(Dispatchers.IO) { - val getCoins = async { rpcClient.coins(sender, coinType).getOrThrow().result.data } - val getGasPrice = async { rpcClient.gasPrice(JSONRpcRequest.create(SuiMethod.GasPrice, emptyList())).getOrNull()?.result ?: "750" } - val getObject = async { rpcClient.getObject(JSONRpcRequest.create(SuiMethod.GetObject, listOf(stakeId))).getOrNull()?.result ?: throw IllegalStateException() } - val coins = getCoins.await() - val gasPrice = getGasPrice.await() - val suiObject = getObject.await() - - val input = SuiUnstakeInput( - sender = sender, - stakedSui = SuiObjectRef( - objectId = suiObject.data.objectId, - digest = suiObject.data.digest, - version = suiObject.data.version.toULong(), - ), - gasCoin = coins.map { it.togemstone() }.first(), - gas = SuiGas( - budget = gasBudget(coinType).toLong().toULong(), - price = gasPrice.toULong(), - ) - ) - suiEncodeUnstake(input) - } - - private fun com.wallet.core.blockchain.sui.SuiCoin.togemstone() = SuiCoin( - coinType = coinType, - balance = balance.toULong(), - objectRef = SuiObjectRef( - objectId = coinObjectId, - digest = digest, - version = version.toULong(), - ) - ) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/model/SuiObject.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/model/SuiObject.kt deleted file mode 100644 index 1e04a7405..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/model/SuiObject.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.gemwallet.android.blockchain.clients.sui.model - -import kotlinx.serialization.Serializable - -@Serializable -data class SuiObject( - val data: Data, -) { - @Serializable - data class Data( - val objectId: String, - val version: String, - val digest: String, - ) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonCalls.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonCalls.kt deleted file mode 100644 index a83fb2b9c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonCalls.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ton - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest - -internal suspend fun jettonAddress(rpcClient: TonRpcClient, tokenId: String, address: String): String? { -// val data = uniffi.gemstone.tonEncodeGetWalletAddress(address) -// val response = rpcClient.getJetonAddress( -// JSONRpcRequest( -// method = "runGetMethod", -// params = mapOf( -// "address" to tokenId, -// "method" to "get_wallet_address", -// "stack" to listOf( -// listOf( -// "tvm.Slice", -// data, -// ) -// ), -// ) -// ) -// ) -// val result = response.getOrNull() ?: return null -// return uniffi.gemstone.tonDecodeJettonAddress(result.b64, result.len.toULong()) - return null -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonFeeCalculator.kt deleted file mode 100644 index b30da296b..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonFeeCalculator.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ton - -import com.gemwallet.android.model.Fee -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import java.math.BigInteger - -class TonFeeCalculator( - private val chain: Chain, - private val rpcClient: TonRpcClient, -) { - val baseFee = BigInteger.valueOf(10_000_000L) - val jettonTokenAccountCreation = BigInteger.valueOf(300_000_000L) - - fun calculateNative() = Fee(FeePriority.Normal, AssetId(chain), baseFee) - - suspend fun calculateToken(assetId: AssetId, destinationAddress: String, memo: String?): Fee = withContext(Dispatchers.IO) { - val tokenId = assetId.tokenId!! - val jetonAddress = jettonAddress(rpcClient, tokenId, destinationAddress) - ?: throw Exception("can't get jetton address") - val state = rpcClient.addressState(jetonAddress).getOrNull()?.result == "active" - val tokenAccountFee = if (state) { - if (memo.isNullOrEmpty()) { - BigInteger.valueOf(100_000_000) - } else { - BigInteger.valueOf(60_000_000) // 0.06 - } - } else { - jettonTokenAccountCreation - } - Fee( - FeePriority.Normal, - AssetId(assetId.chain), - baseFee, - options = mapOf(tokenAccountCreationKey to tokenAccountFee) - ).withOptions(tokenAccountCreationKey) - } - - fun calculateSwap(): Fee { -// val fee = baseFee + jettonTokenAccountCreation - return Fee( - FeePriority.Normal, - AssetId(chain), - baseFee, - options = mapOf(tokenAccountCreationKey to jettonTokenAccountCreation) - ).withOptions(tokenAccountCreationKey) - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonRpcClient.kt deleted file mode 100644 index 22d32591c..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonRpcClient.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ton - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.google.gson.JsonDeserializationContext -import com.google.gson.JsonDeserializer -import com.google.gson.JsonElement -import com.wallet.core.blockchain.ton.TonBroadcastTransaction -import com.wallet.core.blockchain.ton.TonJettonBalance -import com.wallet.core.blockchain.ton.TonJettonToken -import com.wallet.core.blockchain.ton.TonMasterchainInfo -import com.wallet.core.blockchain.ton.TonMessageTransactions -import com.wallet.core.blockchain.ton.TonResult -import com.wallet.core.blockchain.ton.TonWalletInfo -import retrofit2.Response -import retrofit2.http.Body -import retrofit2.http.GET -import retrofit2.http.POST -import retrofit2.http.Query -import retrofit2.http.Url -import java.lang.reflect.Type - -interface TonRpcClient { - - @GET("/api/v2/getWalletInformation") - suspend fun walletInfo(@Query("address") address: String): Result> - - @GET("/api/v2/getAddressState") - suspend fun addressState(@Query("address") address: String): Result> - - data class JetonAddress( - val b64: String, - val len: Long, - ) - - class JetonAddressSerializer : JsonDeserializer { - - override fun deserialize( - json: JsonElement?, - typeOfT: Type?, - context: JsonDeserializationContext? - ): JetonAddress? { - val jObj = json?.asJsonObject ?: return null - val data = jObj - .getAsJsonObject("result") - .getAsJsonArray("stack") - .get(0).asJsonArray[1]?.asJsonObject - ?.getAsJsonObject("object") - ?.getAsJsonObject("data") ?: return null - return JetonAddress( - b64 = data.get("b64")?.asString ?: return null, - len = data.get("len")?.asLong ?: return null, - ) - } - - } - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignClient.kt index 273d6430e..43e925c98 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignClient.kt @@ -6,6 +6,7 @@ import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain +import uniffi.gemstone.GemFeeOption import wallet.core.java.AnySigner import wallet.core.jni.CoinType import wallet.core.jni.proto.TheOpenNetwork @@ -64,7 +65,7 @@ class TonSignClient( val message = TheOpenNetwork.Transfer.newBuilder().apply { this.dest = meta.jettonAddress - this.amount = ByteString.copyFrom((fee.options[tokenAccountCreationKey] ?: BigInteger.ZERO).toByteArray()) + this.amount = ByteString.copyFrom((fee.options[GemFeeOption.TOKEN_ACCOUNT_CREATION.name] ?: BigInteger.ZERO).toByteArray()) if (!params.memo().isNullOrEmpty()) { this.comment = params.memo() } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignerPreloader.kt deleted file mode 100644 index 37e761c62..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ton/TonSignerPreloader.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ton - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -internal const val tokenAccountCreationKey: String = "tokenAccountCreation" - -class TonSignerPreloader( - private val chain: Chain, - private val rpcClient: TonRpcClient, -) : NativeTransferPreloader, TokenTransferPreloader, SwapTransactionPreloader { - - private val feeCalculator = TonFeeCalculator(chain, rpcClient) - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - val fee = feeCalculator.calculateNative() - val seqno = rpcClient.walletInfo(params.from.address).getOrNull()?.result?.seqno ?: 0 - return SignerParams( - input = params, - chainData = TonChainData(seqno.toULong()), - fee = listOf(fee), - ) - } - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams = withContext(Dispatchers.IO) { - val getWalletInfo = async { rpcClient.walletInfo(params.from.address).getOrNull() } - val getJettonAddress = async { jettonAddress(rpcClient, params.assetId.tokenId!!, params.from.address) } - val getFee = async { feeCalculator.calculateToken(params.assetId, params.destination().address, params.memo()) } - - val seqno = getWalletInfo.await()?.result?.seqno ?: 0 - val jettonAddress = getJettonAddress.await() ?: throw Exception("can't get jetton address. check internet.") - val fee = getFee.await() - - SignerParams( - input = params, - chainData = TonChainData(seqno.toULong(), jettonAddress), - fee = listOf(fee), - ) - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - val fee = feeCalculator.calculateSwap() - val seqno = rpcClient.walletInfo(params.from.address).getOrNull()?.result?.seqno ?: 0 - return SignerParams( - input = params, - chainData = TonChainData(seqno.toULong()), - fee = listOf(fee), - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronFeeCalculator.kt deleted file mode 100644 index f04db53fb..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronFeeCalculator.kt +++ /dev/null @@ -1,125 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee -import com.wallet.core.blockchain.tron.TronAccount -import com.wallet.core.blockchain.tron.TronAccountUsage -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import wallet.core.jni.Base58 -import java.math.BigDecimal -import java.math.BigInteger - -class TronFeeCalculator( - private val chain: Chain, - private val client: TronRpcClient, -) { - val baseFee = BigInteger.valueOf(280_000) - - suspend fun calculate(inParams: ConfirmParams.Stake, account: TronAccount?, accountUsage: TronAccountUsage?) = withContext(Dispatchers.IO) { - if (accountUsage == null || account == null) { - throw Exception("Account doesn't available (empty balance?)") - } - - val availableBandwidth = (accountUsage.freeNetLimit ?: 0) - (accountUsage.freeNetUsed ?: 0) - val fee = when (inParams) { - is ConfirmParams.Stake.DelegateParams -> if (availableBandwidth >= 580) BigInteger.ZERO else baseFee - is ConfirmParams.Stake.UndelegateParams -> if (account.staked(chain) > inParams.amount) { - if (availableBandwidth >= 580) BigInteger.ZERO else baseFee * BigInteger.valueOf(2) - } else { - if (availableBandwidth >= 300) BigInteger.ZERO else baseFee - } - is ConfirmParams.Stake.RedelegateParams, - is ConfirmParams.Stake.RewardsParams, - is ConfirmParams.Stake.WithdrawParams -> if (availableBandwidth >= 300) BigInteger.ZERO else baseFee - } - Fee(FeePriority.Normal, AssetId(chain), fee) - } - - suspend fun calculate(inParams: ConfirmParams.TransferParams.Native, account: TronAccount?, accountUsage: TronAccountUsage?) = withContext(Dispatchers.IO) { - val getParams = async { client.getChainParameters().fold({ it.chainParameter }) { null } } - val params = getParams.await() - - val isNewAccount = account?.address.isNullOrEmpty() - - val newAccountFee = params?.firstOrNull{ it.key == "getCreateAccountFee" }?.value - val newAccountFeeInSmartContract = params?.firstOrNull { it.key == "getCreateNewAccountFeeInSystemContract" }?.value - val availableBandwidth = (accountUsage?.freeNetLimit ?: 0) - (accountUsage?.freeNetUsed ?: 0) - val coinTransferFee = if (availableBandwidth >= 300) BigInteger.ZERO else baseFee - - if (newAccountFeeInSmartContract == null || newAccountFee == null) { - throw Exception("Tron unknown key") - } - - val fee = if (isNewAccount) { - coinTransferFee + BigInteger.valueOf(newAccountFee + newAccountFeeInSmartContract) - } else { - coinTransferFee - } - Fee(FeePriority.Normal, AssetId(chain), fee) - } - - suspend fun calculate(inParams: ConfirmParams.TransferParams.Token, account: TronAccount?, accountUsage: TronAccountUsage?) = withContext(Dispatchers.IO) { - val getParams = async { client.getChainParameters().fold({ it.chainParameter }) { null } } - - // https://developers.tron.network/docs/set-feelimit#how-to-estimate-energy-consumption - val gasLimit = estimateTRC20Transfer( - ownerAddress = inParams.from.address, - recipientAddress = inParams.destination.address, - contractAddress = inParams.assetId.tokenId ?: throw IllegalArgumentException("Incorrect contract on fee calculation"), - value = inParams.amount, - ) - - val isNewAccount = account?.address.isNullOrEmpty() - val params = getParams.await() - val newAccountFeeInSmartContract = params?.firstOrNull { it.key == "getCreateNewAccountFeeInSystemContract" }?.value - val energyFee = params?.firstOrNull { it.key == "getEnergyFee" }?.value - val availableEnergy = BigInteger.valueOf(accountUsage?.EnergyLimit ?: 0L) - BigInteger.valueOf(accountUsage?.EnergyUsed ?: 0L) - val energyShortfall = BigInteger.ZERO.max(gasLimit.let { it.add(it.multiply(BigDecimal(0.2))).toBigInteger() } - availableEnergy) - - if (newAccountFeeInSmartContract == null || energyFee == null) { - throw Exception("Tron unknown key") - } - - val tokenTransferFee = BigInteger.valueOf(energyFee) * energyShortfall - val fee = if (isNewAccount) { - tokenTransferFee + BigInteger.valueOf(newAccountFeeInSmartContract) - } else { - tokenTransferFee - } - Fee(FeePriority.Normal, AssetId(chain), fee) - } - - // https://developers.tron.network/docs/set-feelimit#how-to-estimate-energy-consumption - private suspend fun estimateTRC20Transfer( - ownerAddress: String, - recipientAddress: String, - contractAddress: String, - value: BigInteger - ): BigDecimal { - val address = Base58.decode(recipientAddress).toHexString("") - val parameter = arrayOf( - address, - value.toByteArray().toHexString("") - ).joinToString(separator = "") { it.padStart(64, '0') } - val response = client.triggerSmartContract( - contractAddress = contractAddress, - functionSelector = "transfer(address,uint256)", - parameter = parameter, - feeLimit = 0L, - callValue = 0L, - ownerAddress = ownerAddress, - visible = true - ) - val result = response.getOrNull() - if (result == null || !result.result.message.isNullOrEmpty()) { - throw IllegalStateException("Can't get gas limit") - } - return BigDecimal.valueOf(result.energy_used.toLong()) - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt deleted file mode 100644 index 8a3e940d3..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronSignerPreloader.kt +++ /dev/null @@ -1,102 +0,0 @@ -package com.gemwallet.android.blockchain.clients.tron - -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.Fee -import com.gemwallet.android.model.SignerParams -import com.wallet.core.blockchain.tron.TronAccount -import com.wallet.core.blockchain.tron.TronAccountUsage -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext -import java.math.BigInteger - -class TronSignerPreloader( - private val chain: Chain, - private val client: TronRpcClient, -) : NativeTransferPreloader, TokenTransferPreloader, StakeTransactionPreloader, SwapTransactionPreloader { - val feeCalculator = TronFeeCalculator(chain, client) - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - return preload( - params, { account, usage -> - feeCalculator.calculate(params, account, usage) - } - ) { emptyMap() } - } - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { - return preload( - params, { account, usage -> - feeCalculator.calculate(params, account, usage) - } - ) { emptyMap() } - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - - override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams = withContext(Dispatchers.IO) { - preload( - params = params, - feeCalc = { account, usage -> - feeCalculator.calculate(params, account, usage) - } - ) { account -> - val newVote = (params.amount / BigInteger.TEN.pow(chain.asset().decimals)).toLong() - val votes = (account?.votes ?: emptyList()).groupBy { it.vote_address }.mapValues { - it.value.fold(0L) { acc, v -> acc + v.vote_count} - }.toMutableMap() - when (params) { - is ConfirmParams.Stake.DelegateParams -> votes[params.validatorId] = (votes[params.validatorId] ?: 0L) + newVote - is ConfirmParams.Stake.UndelegateParams -> votes[params.validatorId] = (votes[params.validatorId] ?: 0L) - newVote - is ConfirmParams.Stake.RedelegateParams -> { - votes[params.srcValidatorId] = (votes[params.srcValidatorId] ?: 0L) - newVote - votes[params.dstValidatorId] = (votes[params.dstValidatorId] ?: 0L) + newVote - } - is ConfirmParams.Stake.RewardsParams, - is ConfirmParams.Stake.WithdrawParams -> {} - } - votes.filter { it.value > 0 }.mapValues { it.value.toULong() } - } - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - TODO("Not yet implemented") - } - - private suspend fun preload( - params: ConfirmParams, - feeCalc: suspend (TronAccount?, TronAccountUsage?) -> Fee, - votes: suspend (TronAccount?) -> Map, - ): SignerParams = withContext(Dispatchers.IO) { - val getAccountUsage = async { client.getAccountUsage(params.from.address) } - val getAccount = async { client.getAccount(params.from.address, true) } - val nowBlockJob = async { client.nowBlock() } - - val nowBlock = nowBlockJob.await().getOrThrow() - val account = getAccount.await() - val accountUsage = getAccountUsage.await() - - val fee = feeCalc(account, accountUsage) - - SignerParams( - input = params, - chainData = TronChainData( - blockNumber = nowBlock.block_header.raw_data.number.toULong(), - blockVersion = nowBlock.block_header.raw_data.version.toULong(), - txTrieRoot = nowBlock.block_header.raw_data.txTrieRoot, - witnessAddress = nowBlock.block_header.raw_data.witness_address, - parentHash = nowBlock.block_header.raw_data.parentHash, - blockTimestamp = nowBlock.block_header.raw_data.timestamp.toULong(), - votes = votes(account) - ), - fee = listOf(fee), - ) - } - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpFeeCalculator.kt deleted file mode 100644 index ab8bc1236..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpFeeCalculator.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.gemwallet.android.blockchain.clients.xrp - -import com.gemwallet.android.model.Fee -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import java.math.BigInteger - -class XrpFeeCalculator( - private val chain: Chain, - private val rpcClient: XrpRpcClient, -) { - suspend fun calculate(): List { - val drops = rpcClient.fee().getOrThrow().result.drops - val minimum = drops.minimum_fee.toBigInteger() - val median = drops.median_fee.toBigInteger() - - return FeePriority.entries.map { - val amount = when (it) { - FeePriority.Slow -> (median / BigInteger.TEN).max(minimum) - FeePriority.Normal -> median - FeePriority.Fast -> median * BigInteger.valueOf(2) - } - Fee(feeAssetId = AssetId(chain), priority = it, amount = amount) - } - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpMethod.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpMethod.kt deleted file mode 100644 index 366170ada..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpMethod.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients.xrp - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcMethod - -enum class XrpMethod(val value: String) : JSONRpcMethod { - Account("account_info"), - Fee("fee"), - ; - - override fun value(): String = value -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpRpcClient.kt deleted file mode 100644 index cb651f408..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpRpcClient.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.gemwallet.android.blockchain.clients.xrp - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.wallet.core.blockchain.xrp.XRPAccountResult -import com.wallet.core.blockchain.xrp.XRPFee -import com.wallet.core.blockchain.xrp.XRPLatestBlock -import com.wallet.core.blockchain.xrp.XRPResult -import com.wallet.core.blockchain.xrp.XRPTransactionBroadcast -import com.wallet.core.blockchain.xrp.XRPTransactionStatus -import retrofit2.Response -import retrofit2.http.Body -import retrofit2.http.POST -import retrofit2.http.Url - -interface XrpRpcClient { - - @POST("/") - suspend fun fee(@Body request: JSONRpcRequest>>): Result> - - @POST("/") - suspend fun account(@Body request: JSONRpcRequest>>): Result> -} - -internal suspend fun XrpRpcClient.account(address: String): Result> { - val request = JSONRpcRequest.create( - XrpMethod.Account, - listOf( - mapOf( - "account" to address, - "ledger_index" to "current", - ) - ) - ) - return account(request) -} - -internal suspend fun XrpRpcClient.fee(): Result> { - return fee(JSONRpcRequest.create(XrpMethod.Fee, listOf(mapOf()))) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt deleted file mode 100644 index e5cb10bb6..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignerPreloader.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.gemwallet.android.blockchain.clients.xrp - -import com.gemwallet.android.blockchain.clients.ActivationTransactionPreloader -import com.gemwallet.android.blockchain.clients.BlockchainError -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Chain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.withContext - -class XrpSignerPreloader( - private val chain: Chain, - private val rpcClient: XrpRpcClient, -) : NativeTransferPreloader, TokenTransferPreloader, ActivationTransactionPreloader, SwapTransactionPreloader { - - private val feeCalculator = XrpFeeCalculator(chain, rpcClient) - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - return preload(params) - } - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { - return preload(params) - } - - override suspend fun preloadActivate(params: ConfirmParams.Activate): SignerParams { - return preload(params) - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - return preload(params) - } - - private suspend fun preload(params: ConfirmParams) = withContext(Dispatchers.IO) { - val (getSequence, getFee) = Pair ( - async { rpcClient.account(params.from.address).getOrNull()?.result }, - async { feeCalculator.calculate() } - ) - val account = getSequence.await() ?: throw BlockchainError.AccountNotActive - val fee = getFee.await() - - SignerParams( - params, - XrpChainData( - account.account_data?.Sequence ?: 0, - account.ledger_current_index, - ), - fee = fee, - ) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt index 7ab9bf185..4ebc1a6db 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt @@ -1,23 +1,16 @@ package com.gemwallet.android.blockchain.services -import com.gemwallet.android.blockchain.clients.ActivationTransactionPreloader -import com.gemwallet.android.blockchain.clients.ApprovalTransactionPreloader -import com.gemwallet.android.blockchain.clients.GenericTransferPreloader -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.NftTransactionPreloader -import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader import com.gemwallet.android.blockchain.clients.algorand.toChainData import com.gemwallet.android.blockchain.clients.aptos.toChainData import com.gemwallet.android.blockchain.clients.bitcoin.BitcoinGatewayEstimateFee import com.gemwallet.android.blockchain.clients.bitcoin.toChainData +import com.gemwallet.android.blockchain.clients.cardano.CardanoGatewayEstimateFee import com.gemwallet.android.blockchain.clients.cardano.toChainData import com.gemwallet.android.blockchain.clients.cosmos.toChainData import com.gemwallet.android.blockchain.clients.ethereum.EvmGatewayEstimateFee import com.gemwallet.android.blockchain.clients.ethereum.toChainData -import com.gemwallet.android.blockchain.clients.getClient import com.gemwallet.android.blockchain.clients.near.toChainData +import com.gemwallet.android.blockchain.clients.polkadot.PolkadotGatewayEstimateFee import com.gemwallet.android.blockchain.clients.polkadot.toChainData import com.gemwallet.android.blockchain.clients.solana.toChainData import com.gemwallet.android.blockchain.clients.stellar.toChainData @@ -49,18 +42,7 @@ import uniffi.gemstone.SwapperException class SignerPreloaderProxy( private val gateway: GemGateway, - private val nativeTransferClients: List, - private val tokenTransferClients: List, - private val stakeTransactionClients: List, - private val swapTransactionClients: List, - private val approvalTransactionClients: List, - private val activatePreloaderClients: List, - private val genericPreloaderClients: List, - private val nftPreloadClients: List, -) : GenericTransferPreloader, NativeTransferPreloader, TokenTransferPreloader, - StakeTransactionPreloader, - SwapTransactionPreloader, ApprovalTransactionPreloader, ActivationTransactionPreloader, - NftTransactionPreloader { +) { suspend fun preload(params: ConfirmParams): SignerParams = withContext(Dispatchers.IO) { val gemAsset = params.asset.toGem() @@ -68,6 +50,7 @@ class SignerPreloaderProxy( val chain = assetId.chain val gemChain = assetId.chain.string val destination = params.destination()?.address ?: throw java.lang.IllegalArgumentException() + try { val metadata = gateway.getTransactionPreload( chain = gemChain, @@ -129,59 +112,12 @@ class SignerPreloaderProxy( // preloadJob.await() } - override fun supported(chain: Chain): Boolean { - return (nativeTransferClients - + tokenTransferClients - + stakeTransactionClients - + swapTransactionClients - + approvalTransactionClients).getClient(chain) != null - } - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams { - return nativeTransferClients.getClient(params.from.chain)?.preloadNativeTransfer(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams { - return tokenTransferClients.getClient(params.from.chain)?.preloadTokenTransfer(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams { - return stakeTransactionClients.getClient(params.from.chain)?.preloadStake(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - return swapTransactionClients.getClient(params.from.chain)?.preloadSwap(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadApproval(params: ConfirmParams.TokenApprovalParams): SignerParams { - return approvalTransactionClients.getClient(params.from.chain)?.preloadApproval(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadActivate(params: ConfirmParams.Activate): SignerParams { - return activatePreloaderClients.getClient(params.from.chain)?.preloadActivate(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadGeneric(params: ConfirmParams.TransferParams.Generic): SignerParams { - return genericPreloaderClients.getClient(params.from.chain)?.preloadGeneric(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - - override suspend fun preloadNft(params: ConfirmParams.NftParams): SignerParams { - return nftPreloadClients.getClient(params.from.chain)?.preloadNft(params = params) - ?: throw IllegalArgumentException("Chain isn't support") - } - private fun getEstimateFee(chain: Chain): GemGatewayEstimateFee { return when (chain.toChainType()) { ChainType.Bitcoin -> BitcoinGatewayEstimateFee() ChainType.Ethereum -> EvmGatewayEstimateFee() - ChainType.Cardano, + ChainType.Cardano -> CardanoGatewayEstimateFee() + ChainType.Polkadot -> PolkadotGatewayEstimateFee() ChainType.Solana, ChainType.Cosmos, ChainType.Ton, @@ -192,7 +128,6 @@ class SignerPreloaderProxy( ChainType.Near, ChainType.Stellar, ChainType.Algorand, - ChainType.Polkadot, ChainType.HyperCore -> StubGatewayEstimateFee } } diff --git a/core b/core index cc13a4ee7..9576845c6 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit cc13a4ee73a70efb649e2b37f4a91b0f896f79aa +Subproject commit 9576845c620a5ddad8a2b0368b1ff8cfdefc27a7 diff --git a/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt b/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt index e864da7e2..194b2de7e 100644 --- a/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt +++ b/data/services/remote-gem/src/main/kotlin/com/gemwallet/android/data/services/gemapi/di/ClientsModule.kt @@ -3,20 +3,7 @@ package com.gemwallet.android.data.services.gemapi.di import android.content.Context import com.gemwallet.android.blockchain.Mime import com.gemwallet.android.blockchain.RpcClientAdapter -import com.gemwallet.android.blockchain.clients.algorand.services.AlgorandService -import com.gemwallet.android.blockchain.clients.aptos.services.AptosServices -import com.gemwallet.android.blockchain.clients.bitcoin.services.BitcoinRpcClient -import com.gemwallet.android.blockchain.clients.cardano.services.CardanoServices -import com.gemwallet.android.blockchain.clients.cosmos.services.CosmosRpcClient -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmRpcClient -import com.gemwallet.android.blockchain.clients.hyper.services.HyperCoreServices -import com.gemwallet.android.blockchain.clients.near.NearRpcClient -import com.gemwallet.android.blockchain.clients.polkadot.services.PolkadotServices -import com.gemwallet.android.blockchain.clients.stellar.services.StellarService -import com.gemwallet.android.blockchain.clients.sui.SuiRpcClient -import com.gemwallet.android.blockchain.clients.ton.TonRpcClient import com.gemwallet.android.blockchain.clients.tron.TronRpcClient -import com.gemwallet.android.blockchain.clients.xrp.XrpRpcClient import com.gemwallet.android.cases.nodes.GetCurrentNodeCase import com.gemwallet.android.cases.nodes.GetNodesCase import com.gemwallet.android.cases.nodes.SetCurrentNodeCase @@ -46,7 +33,6 @@ import retrofit2.converter.kotlinx.serialization.asConverterFactory import java.util.concurrent.TimeUnit import javax.inject.Qualifier import javax.inject.Singleton -import kotlin.collections.map @Qualifier annotation class NodeHttpClient @@ -129,40 +115,56 @@ object ClientsModule { @NodeHttpClient httpClient: OkHttpClient, ): RpcClientAdapter { val gson = Gson() - val converter = jsonEncoder.asConverterFactory(Mime.Json.value) - val ethConverter = GsonConverterFactory.create( - gson.newBuilder() - .registerTypeAdapter(EvmRpcClient.EvmNumber::class.java, EvmRpcClient.BalanceDeserializer()) - .registerTypeAdapter(EvmRpcClient.TokenBalance::class.java, EvmRpcClient.TokenBalanceDeserializer()) - .create() - ) - val tonConverter = GsonConverterFactory.create( - gson.newBuilder() - .registerTypeAdapter(TonRpcClient.JetonAddress::class.java, TonRpcClient.JetonAddressSerializer()) - .create() - ) +// val converter = jsonEncoder.asConverterFactory(Mime.Json.value) +// val ethConverter = GsonConverterFactory.create( +// gson.newBuilder() +// .registerTypeAdapter(EvmRpcClient.EvmNumber::class.java, EvmRpcClient.BalanceDeserializer()) +// .registerTypeAdapter(EvmRpcClient.TokenBalance::class.java, EvmRpcClient.TokenBalanceDeserializer()) +// .create() +// ) +// val tonConverter = GsonConverterFactory.create( +// gson.newBuilder() +// .registerTypeAdapter(TonRpcClient.JetonAddress::class.java, TonRpcClient.JetonAddressSerializer()) +// .create() +// ) val gsonConverter = GsonConverterFactory.create(gson) val adapter = RpcClientAdapter() - Chain.available().forEach { - val url = "https://${it.string}" - val rpc: Any = when (it.toChainType()) { - ChainType.Bitcoin -> buildClient(url, BitcoinRpcClient::class.java, converter, httpClient) - ChainType.Ethereum -> buildClient(url, EvmRpcClient::class.java, ethConverter, httpClient) - ChainType.Solana -> return@forEach - ChainType.Cosmos -> buildClient(url, CosmosRpcClient::class.java, converter, httpClient) - ChainType.Ton -> buildClient(url, TonRpcClient::class.java, tonConverter, httpClient) + Chain.available().forEach { chain -> + val url = "https://${chain.string}" + when (chain.toChainType()) { ChainType.Tron -> buildClient(url, TronRpcClient::class.java, gsonConverter, httpClient) - ChainType.Aptos -> buildClient(url, AptosServices::class.java, converter, httpClient) - ChainType.Sui -> buildClient(url, SuiRpcClient::class.java, gsonConverter, httpClient) - ChainType.Xrp -> buildClient(url, XrpRpcClient::class.java, gsonConverter, httpClient) - ChainType.Near -> buildClient(url, NearRpcClient::class.java, gsonConverter, httpClient) - ChainType.Algorand -> buildClient(url, AlgorandService::class.java, converter, httpClient) - ChainType.Stellar -> buildClient(url, StellarService::class.java, converter, httpClient) - ChainType.Polkadot -> buildClient(url, PolkadotServices::class.java, converter, httpClient) - ChainType.Cardano -> buildClient(url, CardanoServices::class.java, converter, httpClient) - ChainType.HyperCore -> buildClient(url, HyperCoreServices::class.java, converter, httpClient) +// ChainType.Bitcoin -> buildClient(url, BitcoinRpcClient::class.java, converter, httpClient) +// ChainType.Ethereum -> buildClient(url, EvmRpcClient::class.java, ethConverter, httpClient) +// ChainType.Solana -> return@forEach +// ChainType.Cosmos -> buildClient(url, CosmosRpcClient::class.java, converter, httpClient) +// ChainType.Ton -> buildClient(url, TonRpcClient::class.java, tonConverter, httpClient) + +// ChainType.Aptos -> buildClient(url, AptosServices::class.java, converter, httpClient) +// ChainType.Sui -> buildClient(url, SuiRpcClient::class.java, gsonConverter, httpClient) +// ChainType.Xrp -> buildClient(url, XrpRpcClient::class.java, gsonConverter, httpClient) +// ChainType.Near -> buildClient(url, NearRpcClient::class.java, gsonConverter, httpClient) +// ChainType.Algorand -> buildClient(url, AlgorandService::class.java, converter, httpClient) +// ChainType.Stellar -> buildClient(url, StellarService::class.java, converter, httpClient) +// ChainType.Polkadot -> buildClient(url, PolkadotServices::class.java, converter, httpClient) +// ChainType.Cardano -> buildClient(url, CardanoServices::class.java, converter, httpClient) +// ChainType.HyperCore -> null + ChainType.Ethereum, + ChainType.Bitcoin, + ChainType.Solana, + ChainType.Cosmos, + ChainType.Ton, + ChainType.Aptos, + ChainType.Sui, + ChainType.Xrp, + ChainType.Near, + ChainType.Stellar, + ChainType.Algorand, + ChainType.Polkadot, + ChainType.Cardano, + ChainType.HyperCore -> null + }?.let { rpc -> + adapter.add(chain, rpc) } - adapter.add(it, rpc) } return adapter } diff --git a/flavors/fcm/src/main/kotlin/com/gemwallet/android/flavors/FCM.kt b/flavors/fcm/src/main/kotlin/com/gemwallet/android/flavors/FCM.kt index 3c1df6e6f..8f6f1f971 100644 --- a/flavors/fcm/src/main/kotlin/com/gemwallet/android/flavors/FCM.kt +++ b/flavors/fcm/src/main/kotlin/com/gemwallet/android/flavors/FCM.kt @@ -69,6 +69,7 @@ class FCM : FirebaseMessagingService() { PushNotificationTypes.BuyAsset, PushNotificationTypes.Asset -> jsonEncoder.decodeFromString(rawData).assetId PushNotificationTypes.Test, + PushNotificationTypes.Support, PushNotificationTypes.SwapAsset -> null } } catch (_: Throwable) { diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/AddressStatus.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/AddressStatus.kt new file mode 100644 index 000000000..8a09318f2 --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/AddressStatus.kt @@ -0,0 +1,15 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +enum class AddressStatus(val string: String) { + @SerialName("multiSignature") + MultiSignature("multiSignature"), +} + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetType.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetType.kt index 6fc4d3cf2..2bad07c29 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetType.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/AssetType.kt @@ -25,6 +25,8 @@ enum class AssetType(val string: String) { BEP20("BEP20"), @SerialName("SPL") SPL("SPL"), + @SerialName("SPL2022") + SPL2022("SPL2022"), @SerialName("TRC20") TRC20("TRC20"), @SerialName("TOKEN") diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/Device.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/Device.kt index d86016413..b0930fd5f 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/Device.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/Device.kt @@ -11,6 +11,8 @@ import kotlinx.serialization.SerialName data class Device ( val id: String, val platform: Platform, + val os: String? = null, + val model: String? = null, val platformStore: PlatformStore? = null, val token: String, val locale: String, diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/FeePriorityValue.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/FeePriorityValue.kt new file mode 100644 index 000000000..398e220f3 --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/FeePriorityValue.kt @@ -0,0 +1,15 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +data class PriorityFeeValue ( + val priority: FeePriority, + val value: String +) + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/FiatQuoteRequest.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/FiatQuoteRequest.kt index c68494cad..98d4224ba 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/FiatQuoteRequest.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/FiatQuoteRequest.kt @@ -11,7 +11,7 @@ import kotlinx.serialization.SerialName data class FiatQuoteRequest ( val assetId: String, val type: FiatQuoteType, - val fiatCurrency: String, + val fiatCurrency: Currency, val fiatAmount: Double? = null, val cryptoValue: String? = null, val walletAddress: String diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/LatencyType.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/LatencyType.kt new file mode 100644 index 000000000..992162d28 --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/LatencyType.kt @@ -0,0 +1,25 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +enum class LatencyType(val string: String) { + @SerialName("Fast") + Fast("Fast"), + @SerialName("Normal") + Normal("Normal"), + @SerialName("Slow") + Slow("Slow"), +} + +@Serializable +data class Latency ( + val latency_type: LatencyType, + val value: Double +) + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/PaymentType.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/PaymentType.kt new file mode 100644 index 000000000..bf812d06d --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/PaymentType.kt @@ -0,0 +1,19 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +enum class PaymentType(val string: String) { + @SerialName("card") + Card("card"), + @SerialName("google_pay") + GooglePay("google_pay"), + @SerialName("apple_pay") + ApplePay("apple_pay"), +} + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt index a4a4fb69f..a5b39fde7 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/PerpetualPosition.kt @@ -15,15 +15,15 @@ enum class PerpetualMarginType(val string: String) { Isolated("isolated"), } -@Serializable -enum class PerpetualDirection // TODO: It's stub wait fix - @Serializable data class PriceTarget ( val price: Double? = null, val percentage: Double? = null ) +@Serializable +enum class PerpetualDirection // TODO: It's stub wait fix + @Serializable data class PerpetualPosition ( val id: String, diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/PushNotification.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/PushNotification.kt index 82e1c415f..8f1f691fd 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/PushNotification.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/PushNotification.kt @@ -26,6 +26,8 @@ enum class PushNotificationTypes(val string: String) { BuyAsset("buyAsset"), @SerialName("swapAsset") SwapAsset("swapAsset"), + @SerialName("support") + Support("support"), } @Serializable @@ -33,6 +35,9 @@ data class PushNotificationPayloadType ( val type: PushNotificationTypes ) +@Serializable +object PushNotificationSupport + @Serializable data class PushNotificationSwapAsset ( val fromAssetId: String, diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/Support.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/Support.kt new file mode 100644 index 000000000..abb915265 --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/Support.kt @@ -0,0 +1,15 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +data class SupportDevice ( + val supportId: String, + val deviceId: String +) + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/swap/Approval.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/swap/Approval.kt index edd529d9d..398ead729 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/swap/Approval.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/swap/Approval.kt @@ -5,8 +5,8 @@ package com.wallet.core.primitives.swap import com.wallet.core.primitives.SwapProvider -import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName @Serializable data class ApprovalData ( diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fe3bfa646..459da60e4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,7 +46,7 @@ reorderable = "3.0.0" mockkVersion = "1.14.5" datastore = "1.1.7" wallet-core = "4.3.5" -gemstone = "0.33.3" +gemstone = "0.33.4" ktor = "3.3.0" appcompat = "1.7.1" material = "1.13.0" From aa3e83aa932806ac16428753eb455a299d59e9cb Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Thu, 18 Sep 2025 20:40:55 -0700 Subject: [PATCH 11/16] Fix gateway preload --- .../bridge/request/RequestViewModel.kt | 18 ++- .../confirm/viewmodels/ConfirmViewModel.kt | 26 +-- .../cardano/CardanoGatewayEstimateFee.kt | 2 +- .../clients/cosmos/CosmosSignClient.kt | 15 +- .../clients/ethereum/EvmFeeCalculator.kt | 151 ------------------ .../clients/ethereum/EvmGatewayEstimateFee.kt | 22 --- .../blockchain/clients/ethereum/EvmMethod.kt | 19 --- .../clients/ethereum/EvmSignClient.kt | 2 +- .../clients/ethereum/EvmSignerPreloader.kt | 141 ---------------- .../clients/ethereum/OptimismGasOracle.kt | 138 ---------------- .../ethereum/services/EvmBalancesService.kt | 22 --- .../ethereum/services/EvmBroadcastService.kt | 11 -- .../ethereum/services/EvmCallService.kt | 53 ------ .../ethereum/services/EvmFeeService.kt | 46 ------ .../ethereum/services/EvmNodeStatusService.kt | 33 ---- .../clients/ethereum/services/EvmRpcClient.kt | 60 ------- .../services/EvmTransactionsService.kt | 12 -- .../polkadot/PolkadotGatewayEstimateFee.kt | 3 +- .../clients/solana/SolanaSignClient.kt | 7 +- .../blockchain/clients/xrp/XrpSignClient.kt | 2 +- .../blockchain/services/SignClientProxy.kt | 28 ++-- .../services/SignerPreloaderProxy.kt | 116 +++++++++++--- .../stake/viewmodels/StakeViewModel.kt | 6 +- .../features/swap/viewmodels/SwapViewModel.kt | 9 +- .../viewmodels/AmountViewModel.kt | 6 +- .../domains/confirm/ConfirmParamsExt.kt | 38 +++++ .../android/domains/stake/DelegationExt.kt | 23 +++ .../domains/stake/DelegationValidatorExt.kt | 15 ++ .../gemwallet/android/model/ConfirmParams.kt | 80 ++++++---- .../gemwallet/android/model/SignerParams.kt | 24 +-- gradle/libs.versions.toml | 10 +- 31 files changed, 307 insertions(+), 831 deletions(-) delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmFeeCalculator.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGatewayEstimateFee.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmMethod.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignerPreloader.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/OptimismGasOracle.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmBalancesService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmBroadcastService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmCallService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmFeeService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmNodeStatusService.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmRpcClient.kt delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmTransactionsService.kt create mode 100644 gemcore/src/main/kotlin/com/gemwallet/android/domains/confirm/ConfirmParamsExt.kt create mode 100644 gemcore/src/main/kotlin/com/gemwallet/android/domains/stake/DelegationExt.kt create mode 100644 gemcore/src/main/kotlin/com/gemwallet/android/domains/stake/DelegationValidatorExt.kt diff --git a/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt b/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt index ddc2118d0..b81bdf7b9 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/bridge/request/RequestViewModel.kt @@ -3,9 +3,9 @@ package com.gemwallet.android.features.bridge.request import androidx.core.net.toUri import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.gemwallet.android.blockchain.services.SignClientProxy import com.gemwallet.android.blockchain.operators.LoadPrivateKeyOperator import com.gemwallet.android.blockchain.operators.PasswordStore +import com.gemwallet.android.blockchain.services.SignClientProxy import com.gemwallet.android.data.repositoreis.bridge.BridgesRepository import com.gemwallet.android.data.repositoreis.bridge.getNamespace import com.gemwallet.android.data.repositoreis.wallets.WalletsRepository @@ -263,6 +263,14 @@ private data class RequestViewModelState( asset = chain.asset(), from = account, memo = params, + name = sessionRequest.peerMetaData?.name ?: "", + description = sessionRequest.peerMetaData?.description ?: "", + url = sessionRequest.peerMetaData?.url ?: "", + icon = sessionRequest.peerMetaData?.icons?.firstOrNull() ?: "", + redirectNative = sessionRequest.peerMetaData?.icons?.firstOrNull() ?: "", + redirectUniversal = sessionRequest.peerMetaData?.icons?.firstOrNull() ?: "", + gasLimit = "", + gasPrice = "", inputType = ConfirmParams.TransferParams.InputType.Signature ) ) @@ -271,6 +279,14 @@ private data class RequestViewModelState( asset = chain.asset(), from = account, memo = params, + name = sessionRequest.peerMetaData?.name ?: "", + description = sessionRequest.peerMetaData?.description ?: "", + url = sessionRequest.peerMetaData?.url ?: "", + icon = sessionRequest.peerMetaData?.icons?.firstOrNull() ?: "", + redirectNative = sessionRequest.peerMetaData?.icons?.firstOrNull() ?: "", + redirectUniversal = sessionRequest.peerMetaData?.icons?.firstOrNull() ?: "", + gasLimit = "", + gasPrice = "", inputType = ConfirmParams.TransferParams.InputType.EncodeTransaction ) ) diff --git a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt index e1bc11323..03358362b 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt @@ -21,8 +21,6 @@ import com.gemwallet.android.ext.toIdentifier import com.gemwallet.android.features.confirm.models.AmountUIModel import com.gemwallet.android.features.confirm.models.ConfirmError import com.gemwallet.android.features.confirm.models.ConfirmState -import com.gemwallet.android.ui.navigation.routes.paramsArg -import com.gemwallet.android.ui.navigation.routes.txTypeArg import com.gemwallet.android.model.AssetInfo import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Crypto @@ -37,8 +35,10 @@ import com.gemwallet.android.ui.components.image.getIconUrl import com.gemwallet.android.ui.components.progress.CircularProgressIndicator16 import com.gemwallet.android.ui.models.actions.FinishConfirmAction import com.gemwallet.android.ui.navigation.routes.assetRoutePath +import com.gemwallet.android.ui.navigation.routes.paramsArg import com.gemwallet.android.ui.navigation.routes.stakeRoute import com.gemwallet.android.ui.navigation.routes.swapRoute +import com.gemwallet.android.ui.navigation.routes.txTypeArg import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.Currency import com.wallet.core.primitives.DelegationValidator @@ -96,7 +96,7 @@ class ConfirmViewModel @Inject constructor( private val assetsInfo = request.filterNotNull().mapNotNull { if (it is ConfirmParams.SwapParams) { - listOf(it.fromAsset.id, it.toAssetId) + listOf(it.fromAsset.id, it.toAsset.id) } else { listOf(it.assetId) } @@ -147,7 +147,7 @@ class ConfirmViewModel @Inject constructor( val fromAssetId = request?.assetId ?: return@combine null val assetInfo = assetsInfo?.getByAssetId(fromAssetId) ?: return@combine null val toAssetInfo = if (request is ConfirmParams.SwapParams) { - assetsInfo.getByAssetId(request.toAssetId) ?: return@combine null + assetsInfo.getByAssetId(request.toAsset.id) ?: return@combine null } else { null } @@ -361,9 +361,9 @@ class ConfirmViewModel @Inject constructor( is ConfirmParams.Activate, is ConfirmParams.NftParams, is ConfirmParams.Stake.DelegateParams -> assetInfo.balance.balance.available.toBigInteger() - is ConfirmParams.Stake.RedelegateParams -> BigInteger(stakeRepository.getDelegation(params.srcValidatorId).firstOrNull()?.base?.balance ?: "0") - is ConfirmParams.Stake.UndelegateParams -> BigInteger(stakeRepository.getDelegation(params.validatorId, params.delegationId).firstOrNull()?.base?.balance ?: "0") - is ConfirmParams.Stake.WithdrawParams -> BigInteger(stakeRepository.getDelegation(params.validatorId, params.delegationId).firstOrNull()?.base?.balance ?: "0") + is ConfirmParams.Stake.RedelegateParams -> BigInteger(stakeRepository.getDelegation(params.delegation.validator.id).firstOrNull()?.base?.balance ?: "0") + is ConfirmParams.Stake.UndelegateParams -> BigInteger(stakeRepository.getDelegation(params.delegation.validator.id, params.delegation.base.delegationId).firstOrNull()?.base?.balance ?: "0") + is ConfirmParams.Stake.WithdrawParams -> BigInteger(stakeRepository.getDelegation(params.delegation.validator.id, params.delegation.base.delegationId).firstOrNull()?.base?.balance ?: "0") is ConfirmParams.Stake.RewardsParams -> stakeRepository.getRewards(assetInfo.asset.id, assetInfo.owner?.address ?: "") .fold(BigInteger.ZERO) { acc, delegation -> acc + BigInteger(delegation.base.balance) } } @@ -371,10 +371,10 @@ class ConfirmViewModel @Inject constructor( private suspend fun getValidator(params: ConfirmParams): DelegationValidator? { val validatorId = when (params) { - is ConfirmParams.Stake.DelegateParams -> params.validatorId - is ConfirmParams.Stake.RedelegateParams -> params.dstValidatorId - is ConfirmParams.Stake.UndelegateParams -> params.validatorId - is ConfirmParams.Stake.WithdrawParams -> params.validatorId + is ConfirmParams.Stake.DelegateParams -> params.validator.id + is ConfirmParams.Stake.RedelegateParams -> params.dstValidator.id + is ConfirmParams.Stake.UndelegateParams -> params.delegation.base.validatorId + is ConfirmParams.Stake.WithdrawParams -> params.delegation.base.validatorId is ConfirmParams.Activate, is ConfirmParams.Stake.RewardsParams, is ConfirmParams.SwapParams, @@ -454,7 +454,7 @@ class ConfirmViewModel @Inject constructor( jsonEncoder.encodeToString( TransactionSwapMetadata( fromAsset = input.fromAsset.id, - toAsset = input.toAssetId, + toAsset = input.toAsset.id, fromValue = input.fromAmount.toString(), toValue = input.toAmount.toString(), provider = input.protocolId, @@ -489,7 +489,7 @@ class ConfirmViewModel @Inject constructor( } else { TransactionDirection.Outgoing }, - blockNumber = signerParams.chainData.blockNumber() + blockNumber = signerParams.data(feePriority.value).chainData.blockNumber() ) } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoGatewayEstimateFee.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoGatewayEstimateFee.kt index 89a22338e..9a783da93 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoGatewayEstimateFee.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cardano/CardanoGatewayEstimateFee.kt @@ -20,7 +20,7 @@ class CardanoGatewayEstimateFee : GemGatewayEstimateFee { chain: Chain, input: GemTransactionLoadInput ): GemTransactionLoadFee? { - val utxos = (input.metadata as? GemTransactionLoadMetadata.Bitcoin)?.utxos?.toUtxo() + val utxos = (input.metadata as? GemTransactionLoadMetadata.Cardano)?.utxos?.toUtxo() ?: throw IllegalArgumentException("Incorrect UTXO") val amount = input.value.toLongOrNull() ?: return null diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignClient.kt index 0ac566642..d52c7f49d 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/cosmos/CosmosSignClient.kt @@ -9,6 +9,7 @@ import com.gemwallet.android.model.GasFee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain import com.wallet.core.primitives.CosmosDenom +import com.wallet.core.primitives.DelegationValidator import wallet.core.java.AnySigner import wallet.core.jni.AnyAddress import wallet.core.jni.CoinType @@ -101,7 +102,7 @@ class CosmosSignClient( privateKey: ByteArray ): List { val denom = CosmosDenom.from(chain) - val message = getStakeMessage(params.from.address, params.validatorId, getAmount(finalAmount, denom)) + val message = getStakeMessage(params.from.address, params.validator.id, getAmount(finalAmount, denom)) return sign(chainData, fee, message, "Stake via Gem Wallet", privateKey) } @@ -115,8 +116,8 @@ class CosmosSignClient( val denom = CosmosDenom.from(chain) val message = getRedelegateMessage( delegatorAddress = params.from.address, - validatorSrcAddress = params.srcValidatorId, - validatorDstAddress = params.dstValidatorId, + validatorSrcAddress = params.delegation.validator.id, + validatorDstAddress = params.dstValidator.id, amount = getAmount(params.amount, denom), ) return sign(chainData, fee, message, "Stake via Gem Wallet", privateKey) @@ -129,7 +130,7 @@ class CosmosSignClient( fee: Fee, privateKey: ByteArray ): List { - val message = getRewardsMessage(params.from.address, params.validatorsId) + val message = getRewardsMessage(params.from.address, params.validators) return sign(chainData, fee, message, "Stake via Gem Wallet", privateKey) } @@ -141,7 +142,7 @@ class CosmosSignClient( privateKey: ByteArray ): List { val denom = CosmosDenom.from(chain) - val message = getUnstakeMessage(params.from.address, params.validatorId, getAmount(params.amount, denom)) + val message = getUnstakeMessage(params.from.address, params.delegation.validator.id, getAmount(params.amount, denom)) return sign(chainData, fee, message, "Stake via Gem Wallet", privateKey) } @@ -220,12 +221,12 @@ class CosmosSignClient( return listOf(message) } - fun getRewardsMessage(delegatorAddress: String, validators: List): List { + fun getRewardsMessage(delegatorAddress: String, validators: List): List { return validators.map { validator -> Message.newBuilder().apply { withdrawStakeRewardMessage = WithdrawDelegationReward.newBuilder().apply { this.delegatorAddress = delegatorAddress - this.validatorAddress = validator + this.validatorAddress = validator.id }.build() }.build() } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmFeeCalculator.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmFeeCalculator.kt deleted file mode 100644 index 729eab3c3..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmFeeCalculator.kt +++ /dev/null @@ -1,151 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmFeeService -import com.gemwallet.android.blockchain.clients.ethereum.services.getGasLimit -import com.gemwallet.android.ext.type -import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.GasFee -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetSubtype -import com.wallet.core.primitives.EVMChain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import wallet.core.jni.CoinType -import java.math.BigDecimal -import java.math.BigInteger -import java.util.Locale - -class EvmFeeCalculator( - private val feeService: EvmFeeService, - callService: EvmCallService, - coinType: CoinType -) { - - private val optimismGasOracle = OptimismGasOracle(callService, coinType) - - private val nativeGasLimit = BigInteger.valueOf(21_000L) - - suspend fun calculate( - params: ConfirmParams, // TODO: Outpack - assetId: AssetId, - recipient: String, - outputAmount: BigInteger, - payload: String?, - chainId: Int, - nonce: BigInteger, - ): List = withContext(Dispatchers.IO) { -// val getGasLimit = async { getGasLimit(assetId, params.from.address, recipient, outputAmount, payload) } -// val getBasePriorityFees = async { getBasePriorityFees(params) } -// val gasLimit = getGasLimit.await() -// val (baseFee, priorityFees) = getBasePriorityFees.await() -// -// if (params.assetId.chain.toEVM()?.isOpStack() == true) { -// return@withContext priorityFees.mapIndexed { index, priorityFee -> -// optimismGasOracle.estimate( -// params = params, -// chainId = chainId, -// nonce = nonce, -// gasLimit = gasLimit, -// baseFee = baseFee, -// priorityFee = priorityFee, -// txSpeed = when (index) { -// 0 -> FeePriority.Slow -// 1 -> FeePriority.Normal -// 2 -> FeePriority.Fast -// else -> FeePriority.Normal -// } -// ) -// } -// } -// -// priorityFees.map { priorityFee -> -// val value = priorityFee.value.toBigInteger() -// val maxGasPrice: BigInteger = baseFee.plus(value) -// val minerFee: BigInteger = when (params) { -// is ConfirmParams.Stake, -// is ConfirmParams.SwapParams, -// is ConfirmParams.NftParams, -// is ConfirmParams.TokenApprovalParams -> value -// is ConfirmParams.TransferParams -> if (params.assetId.type() == AssetSubtype.NATIVE && params.isMax()) { -// maxGasPrice -// } else { -// value -// } -// -// is ConfirmParams.Activate -> throw IllegalArgumentException() -// } -// GasFee( -// feeAssetId = AssetId(params.assetId.chain), -// priority = FeePriority.entries.firstOrNull { it.string == priorityFee.priority.name.lowercase() } -// ?: FeePriority.Normal, -// limit = gasLimit, -// maxGasPrice = maxGasPrice, -// minerFee = minerFee, -// ) -// } - emptyList() - } - - private suspend fun getGasLimit( - assetId: AssetId, - from: String, - recipient: String, - outputAmount: BigInteger, - payload: String?, - ): BigInteger { - val (amount, to, data) = when (assetId.type()) { - AssetSubtype.NATIVE -> Triple(outputAmount, recipient, payload) - AssetSubtype.TOKEN -> Triple( - BigInteger.ZERO, // Amount - assetId.tokenId!!.lowercase(Locale.ROOT), // token - EVMChain.encodeTransactionData(assetId, payload, outputAmount, recipient).toHexString() - ) - } - - val gasLimit = try { - feeService.getGasLimit(from, to, amount, data) - } catch (err: Throwable) { - throw err - } - return if (gasLimit == nativeGasLimit) { - gasLimit - } else { - gasLimit.add(gasLimit.toBigDecimal().multiply(BigDecimal.valueOf(0.5)).toBigInteger()) - } - } -// -// internal suspend fun getHistory(chain: Chain, feeService: EvmFeeService): Pair { -// val config = Config().getEvmChainConfig(chain.toEVM()?.string ?: throw IllegalArgumentException()) -// val rewardsPercentiles = config.rewardsPercentiles -// val feeHistory = feeService.getFeeHistory( -// listOf(rewardsPercentiles.slow, rewardsPercentiles.normal, rewardsPercentiles.fast) -// .map { it.toInt() } -// ) ?: throw Exception("Unable to calculate base fee") -// val baseFee = feeHistory.baseFeePerGas.mapNotNull { it.hexToBigInteger() }.maxOrNull() -// ?: throw Exception("Unable to calculate base fee") -// -// return Pair( -// baseFee, -// GemEthereumFeeHistory( -// reward = feeHistory.reward, -// baseFeePerGas = feeHistory.baseFeePerGas, -// gasUsedRatio = feeHistory.gasUsedRatio, -// oldestBlock = feeHistory.oldestBlock, -// ) -// ) -// } -// -// internal suspend fun getBasePriorityFees( -// params: ConfirmParams, -// ): Pair> { -// val history = getHistory(params.asset.id.chain, feeService) -// val calculator = GemFeeCalculator() -// val priority = calculator.calculateBasePriorityFees( -// chain = params.from.chain.string, -// history = history.second -// ) -// return Pair(history.first, priority) -// } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGatewayEstimateFee.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGatewayEstimateFee.kt deleted file mode 100644 index 393a7b01d..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmGatewayEstimateFee.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import uniffi.gemstone.Chain -import uniffi.gemstone.GemGatewayEstimateFee -import uniffi.gemstone.GemTransactionLoadFee -import uniffi.gemstone.GemTransactionLoadInput - -class EvmGatewayEstimateFee : GemGatewayEstimateFee { - override suspend fun getFee( - chain: Chain, - input: GemTransactionLoadInput - ): GemTransactionLoadFee? { - return null - } - - override suspend fun getFeeData( - chain: Chain, - input: GemTransactionLoadInput - ): String? { - return null - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmMethod.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmMethod.kt deleted file mode 100644 index 676b41804..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmMethod.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcMethod - -enum class EvmMethod(val value: String) : JSONRpcMethod { - GetBalance("eth_getBalance"), - GetGasLimit("eth_estimateGas"), - GetFeeHistory("eth_feeHistory"), - GetChainId("eth_chainId"), - GetNonce("eth_getTransactionCount"), - Broadcast("eth_sendRawTransaction"), - Call("eth_call"), - GetTransaction("eth_getTransactionReceipt"), - Sync("eth_syncing"), - GetBlockNumber("eth_blockNumber"), - ; - - override fun value(): String = value -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt index 7035478a6..de8b0bf37 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt @@ -319,7 +319,7 @@ class EvmSignClient( val output = AnySigner.sign(input, coinType, Ethereum.SigningOutput.parser()) .encoded .toByteArray() - return listOf(output) + return listOf(output.toHexString("").toByteArray()) } override fun supported(chain: Chain): Boolean = this.chain == chain diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignerPreloader.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignerPreloader.kt deleted file mode 100644 index 7b6195322..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignerPreloader.kt +++ /dev/null @@ -1,141 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.blockchain.clients.ApprovalTransactionPreloader -import com.gemwallet.android.blockchain.clients.NativeTransferPreloader -import com.gemwallet.android.blockchain.clients.NftTransactionPreloader -import com.gemwallet.android.blockchain.clients.StakeTransactionPreloader -import com.gemwallet.android.blockchain.clients.SwapTransactionPreloader -import com.gemwallet.android.blockchain.clients.TokenTransferPreloader -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmFeeService -import com.gemwallet.android.blockchain.clients.ethereum.services.getNonce -import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy -import com.gemwallet.android.ext.getNetworkId -import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.GasFee -import com.gemwallet.android.model.SignerParams -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.EVMChain -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import wallet.core.jni.AnyAddress -import wallet.core.jni.CoinType -import java.math.BigInteger - -class EvmSignerPreloader( - private val chain: Chain, - private val feeService: EvmFeeService, - callService: EvmCallService, -) : NativeTransferPreloader, - TokenTransferPreloader, - SwapTransactionPreloader, - StakeTransactionPreloader, - ApprovalTransactionPreloader, - NftTransactionPreloader { - - private val wcCoinType = WCChainTypeProxy().invoke(chain) - private val feeCalculator = EvmFeeCalculator(feeService, callService, wcCoinType) - - override suspend fun preloadNativeTransfer(params: ConfirmParams.TransferParams.Native): SignerParams = - preload(params.assetId, params.from, params.destination().address, params.amount, params.memo, params) - - override suspend fun preloadTokenTransfer(params: ConfirmParams.TransferParams.Token): SignerParams = - preload(params.assetId, params.from, params.destination().address, params.amount, params.memo, params) - - override suspend fun preloadNft(params: ConfirmParams.NftParams): SignerParams { - val memo = EVMChain.encodeNFT(params) - return preload(AssetId(params.assetId.chain, params.nftAsset.contractAddress), params.from, params.destination.address, params.amount, memo, params) - } - - override suspend fun preloadStake(params: ConfirmParams.Stake): SignerParams = - preload( - assetId = params.assetId, - from = params.from, - recipient = StakeHub.address, - outputAmount = when (params) { - is ConfirmParams.Stake.DelegateParams -> params.amount - else -> BigInteger.ZERO - }, - payload = when (params.assetId.chain) { - Chain.SmartChain -> StakeHub.encodeStake(params) - else -> throw IllegalArgumentException("Stake doesn't suppoted for chain ${params.assetId.chain} ") - }, - params = params, - ) - - override suspend fun preloadSwap(params: ConfirmParams.SwapParams): SignerParams { - val approval = params.approval - val approvalData = if (approval != null) { - preloadApproval( - params = ConfirmParams.Builder(params.asset, params.from).approval( - approvalData = encodeApprove(AnyAddress(approval.spender, CoinType.ETHEREUM).data()).toHexString(), - provider = "", - contract = approval.token, - ), - ) - } else { - null - } - - val data = if (approvalData == null) { - preload( - assetId = AssetId(params.assetId.chain), - from = params.from, - recipient = params.to, - outputAmount = params.value.toBigInteger(), - payload = params.swapData, - params = params - ) - } else { - // Add approval fee - val chainData = (approvalData.chainData as EvmChainData) - val fees = approvalData.allFee().map { it as GasFee }.map { - GasFee( - feeAssetId = it.feeAssetId, - priority = it.priority, - limit = it.limit, - maxGasPrice = it.maxGasPrice, - minerFee = it.minerFee, - amount = it.limit.multiply(it.maxGasPrice).add(params.gasLimit!!.multiply(it.maxGasPrice)) - ) - } - SignerParams( - input = params, - chainData = chainData, - fee = fees - ) - } - return data - } - - override suspend fun preloadApproval(params: ConfirmParams.TokenApprovalParams): SignerParams = - preload(params.assetId, params.from, params.contract, BigInteger.ZERO, params.data, params) - - private suspend fun preload( - assetId: AssetId, - from: Account, - recipient: String, - outputAmount: BigInteger, - payload: String?, - params: ConfirmParams, - ) = withContext(Dispatchers.IO) { - val nonce = feeService.getNonce(from.address) - val chainId = chain.getNetworkId().toIntOrNull() ?: throw Exception("Invalid chain") - val fees = feeCalculator.calculate( - params = params, - assetId = assetId, - recipient = recipient, - outputAmount = outputAmount, - payload = payload, - chainId = chainId, - nonce = nonce - ) - - SignerParams(params, EvmChainData(chainId, nonce), fees) - } - - override fun supported(chain: Chain): Boolean = this.chain == chain - } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/OptimismGasOracle.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/OptimismGasOracle.kt deleted file mode 100644 index e364f068f..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/OptimismGasOracle.kt +++ /dev/null @@ -1,138 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmCallService -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.ext.type -import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.GasFee -import com.google.protobuf.ByteString -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.AssetSubtype -import com.wallet.core.primitives.EVMChain -import wallet.core.java.AnySigner -import wallet.core.jni.CoinType -import wallet.core.jni.EthereumAbi -import wallet.core.jni.EthereumAbiFunction -import wallet.core.jni.PrivateKey -import wallet.core.jni.proto.Ethereum -import wallet.core.jni.proto.Ethereum.Transaction.Transfer -import java.math.BigInteger - -class OptimismGasOracle( - private val callService: EvmCallService, - private val coinType: CoinType, -) { - -// suspend fun estimate( -// params: ConfirmParams, -// chainId: Int, -// nonce: BigInteger, -// baseFee: BigInteger, -// priorityFee: GemPriorityFeeRecord, -// gasLimit: BigInteger, -// txSpeed: FeePriority, -// ): GasFee = withContext(Dispatchers.IO) { -// val priorityFeeValue = priorityFee.value.toBigInteger() -// val assetId = params.assetId -// val feeAssetId = AssetId(assetId.chain) -// val gasPrice = baseFee + priorityFeeValue -// val minerFee = when (params.getTxType()) { -// TransactionType.Transfer -> if (assetId.type() == AssetSubtype.NATIVE && params.isMax()) gasPrice else priorityFeeValue -// TransactionType.Swap, TransactionType.TokenApproval -> priorityFeeValue -// else -> throw IllegalAccessException("Operation doesn't available") -// } -// val amount = when (params.getTxType()) { -// TransactionType.Transfer -> if (params.isMax()) params.amount - gasLimit * gasPrice else params.amount -// TransactionType.TokenApproval, TransactionType.Swap -> params.amount -// else -> throw IllegalAccessException("Operation doesn't available") -// } -// val encoded = encode( -// assetId = assetId, -// coin = coinType, -// amount = amount, -// destinationAddress = when (params) { -// is ConfirmParams.SwapParams -> params.to -// is ConfirmParams.TokenApprovalParams -> params.contract -// is ConfirmParams.TransferParams -> params.destination.address -// else -> throw IllegalArgumentException() -// }, -// meta = when (params) { -// is ConfirmParams.SwapParams -> params.swapData -// is ConfirmParams.TokenApprovalParams -> params.data -// else -> params.memo() -// }, -// chainId = chainId, -// nonce = nonce, -// gasFee = GasFee( -// feeAssetId = feeAssetId, -// priority = FeePriority.Normal, -// limit = gasLimit, -// maxGasPrice = gasPrice, -// minerFee = minerFee, -// ), -// ) -// val l2Fee = gasPrice * gasLimit -// val l1Fee = getL1Fee(encoded) ?: throw IllegalStateException("Can't get L1 Fee") -// GasFee( -// feeAssetId = feeAssetId, -// priority = txSpeed, -// maxGasPrice = gasPrice, -// minerFee = minerFee, -// limit = gasLimit, -// amount = l1Fee + l2Fee, -// ) -// } - - private suspend fun getL1Fee(data: ByteArray): BigInteger? { - val abiFn = EthereumAbiFunction("getL1Fee").apply { - this.addParamBytes(data, false) - } - val encodedFn = EthereumAbi.encode(abiFn) - val request = JSONRpcRequest.create( - EvmMethod.Call, - listOf( - mapOf( - "to" to "0x420000000000000000000000000000000000000F", - "data" to encodedFn.toHexString(), - ), - "latest", - ) - ) - return callService.callNumber(request).getOrNull()?.result?.value - } - - private fun encode( - assetId: AssetId, - coin: CoinType, - destinationAddress: String, - amount: BigInteger, - meta: String?, - chainId: Int, - nonce: BigInteger, - gasFee: GasFee, - ): ByteArray { - val transfer = Transfer.newBuilder().apply { - this.amount = ByteString.copyFrom(amount.toByteArray()) - this.data = ByteString.copyFrom( - EVMChain.encodeTransactionData(assetId, meta, amount, destinationAddress) - ) - }.build() - val signInput = EvmSignClient(assetId.chain).buildSignInput( - assetId = assetId, - fee = gasFee, - chainId = chainId.toBigInteger(), - nonce = nonce, - destinationAddress = destinationAddress, - transfer = transfer, - privateKey = PrivateKey().data(), - ) - val signer = AnySigner.sign(signInput, coin, Ethereum.SigningOutput.parser()) - val signatureLenInRlp = 67 // 1 + 32 + 1 + 32 + 1 - val encoded = signer.encoded.toList().dropLast(signatureLenInRlp).toMutableList() - when (assetId.type()) { - AssetSubtype.NATIVE -> encoded.removeAt(2) - else -> {} - } - return encoded.toByteArray() - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmBalancesService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmBalancesService.kt deleted file mode 100644 index 856a7c419..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmBalancesService.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum.services - -import com.gemwallet.android.blockchain.clients.ethereum.EvmMethod -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmRpcClient.EvmNumber -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import retrofit2.http.Body -import retrofit2.http.POST - -interface EvmBalancesService { - @POST("/") - suspend fun getBalance(@Body request: JSONRpcRequest>): Result> -} - -suspend fun EvmBalancesService.getBalance(address: String): Result> { - return getBalance( - JSONRpcRequest.create( - method = EvmMethod.GetBalance, - params = listOf(address, "latest") - ) - ) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmBroadcastService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmBroadcastService.kt deleted file mode 100644 index 62d14fb71..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmBroadcastService.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum.services - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import retrofit2.http.Body -import retrofit2.http.POST - -interface EvmBroadcastService { - @POST("/") - suspend fun broadcast(@Body request: JSONRpcRequest>): Result> -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmCallService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmCallService.kt deleted file mode 100644 index aa5ffe11a..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmCallService.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum.services - -import com.gemwallet.android.blockchain.clients.ethereum.EvmMethod -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmRpcClient.EvmNumber -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import retrofit2.http.Body -import retrofit2.http.POST - -interface EvmCallService { - @POST("/") - suspend fun callString(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun callNumber(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun callBatch(@Body request: List>>): Result>> -} - -suspend fun EvmCallService.callString(contract: String, hexData: String): String? { - val params = mapOf( - "to" to contract, - "data" to hexData - ) - val request = JSONRpcRequest.create( - EvmMethod.Call, - listOf( - params, - "latest" - ) - ) - return callString(request).getOrNull()?.result -} - -suspend fun EvmCallService.batch(requests: List>>): List { - val result = callBatch(requests) - return result.getOrNull()?.map { it.result } ?: emptyList() -} - -fun EvmCallService.createCallRequest(to: String, data: String, tag: String? = null): JSONRpcRequest> { - val params = mapOf( - "to" to to, - "data" to data - ) - return JSONRpcRequest.create( - EvmMethod.Call, - listOf( - params, - tag - ).filterNotNull() - ) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmFeeService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmFeeService.kt deleted file mode 100644 index 34f53ed53..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmFeeService.kt +++ /dev/null @@ -1,46 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum.services - -import com.gemwallet.android.blockchain.clients.ethereum.EvmMethod -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmRpcClient.EvmNumber -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.gemwallet.android.math.append0x -import com.wallet.core.blockchain.ethereum.EthereumFeeHistory -import retrofit2.http.Body -import retrofit2.http.POST -import java.math.BigInteger - -interface EvmFeeService { - @POST("/") - suspend fun getFeeHistory(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun getGasLimit(@Body request: JSONRpcRequest>): Result> - - @POST("/") - suspend fun getNonce(@Body request: JSONRpcRequest>): Result> -} - -internal suspend fun EvmFeeService.getFeeHistory(rewardPercentiles: List): EthereumFeeHistory? { - return getFeeHistory(JSONRpcRequest.create(EvmMethod.GetFeeHistory, listOf("10", "latest", rewardPercentiles))) - .getOrNull()?.result -} - -internal suspend fun EvmFeeService.getGasLimit(from: String, to: String, amount: BigInteger, data: String?): BigInteger { - val transaction = mapOf( - "from" to from, - "to" to to, - "value" to "0x${amount.toString(16)}", - "data" to if (data.isNullOrEmpty()) "0x" else data.append0x(), - ) - val request = JSONRpcRequest.create(EvmMethod.GetGasLimit, listOf(transaction)) - val result = getGasLimit(request) - return result.getOrNull()?.result?.value - ?: throw Exception("Fail calculate gas limit") -} - -internal suspend fun EvmFeeService.getNonce(fromAddress: String): BigInteger { - val nonceParams = listOf(fromAddress, "latest") - return getNonce(JSONRpcRequest.create(EvmMethod.GetNonce, nonceParams)) - .getOrNull()?.result?.value ?: throw Exception("Fail get current nonce") -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmNodeStatusService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmNodeStatusService.kt deleted file mode 100644 index c76b5a395..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmNodeStatusService.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum.services - -import com.gemwallet.android.blockchain.clients.ethereum.EvmMethod -import com.gemwallet.android.blockchain.clients.ethereum.services.EvmRpcClient.EvmNumber -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import retrofit2.Response -import retrofit2.http.Body -import retrofit2.http.POST -import retrofit2.http.Url - -interface EvmNodeStatusService { - @POST - suspend fun chainId(@Url url: String, @Body request: JSONRpcRequest>): Response> - - @POST - suspend fun sync(@Url url: String, @Body request: JSONRpcRequest>): Result> - - @POST - suspend fun latestBlock(@Url url: String, @Body request: JSONRpcRequest>): Result> -} - -internal suspend fun EvmNodeStatusService.getChainId(url: String): Response> { - return chainId(url, JSONRpcRequest.create(EvmMethod.GetChainId, emptyList())) -} - -internal suspend fun EvmNodeStatusService.latestBlock(url: String): Result> { - return latestBlock(url, JSONRpcRequest.create(EvmMethod.GetBlockNumber, emptyList())) -} - -internal suspend fun EvmNodeStatusService.sync(url: String): Result> { - return sync(url, JSONRpcRequest.create(EvmMethod.Sync, emptyList())) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmRpcClient.kt deleted file mode 100644 index e2ae06d1f..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmRpcClient.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum.services - -import com.gemwallet.android.math.decodeHex -import com.gemwallet.android.math.hexToBigInteger -import com.google.gson.JsonDeserializationContext -import com.google.gson.JsonDeserializer -import com.google.gson.JsonElement -import wallet.core.jni.EthereumAbiValue -import java.lang.reflect.Type -import java.math.BigInteger - -interface EvmRpcClient : - EvmCallService, - EvmBalancesService, - EvmFeeService, - EvmNodeStatusService, - EvmBroadcastService, - EvmTransactionsService -{ - class EvmNumber( - val value: BigInteger?, - ) - - class TokenBalance( - val value: BigInteger?, - ) - - class BalanceDeserializer : JsonDeserializer { - override fun deserialize( - json: JsonElement?, - typeOfT: Type?, - context: JsonDeserializationContext? - ): EvmNumber { - return EvmNumber( - try { - json?.asString?.hexToBigInteger() - } catch (_: Throwable) { - null - } - ) - } - } - - class TokenBalanceDeserializer : JsonDeserializer { - override fun deserialize( - json: JsonElement?, - typeOfT: Type?, - context: JsonDeserializationContext? - ): TokenBalance { - return TokenBalance( - try { - EthereumAbiValue.decodeUInt256(json?.asString?.decodeHex()).toBigIntegerOrNull() - } catch (_: Throwable) { - null - } - ) - } - - } -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmTransactionsService.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmTransactionsService.kt deleted file mode 100644 index 1d9850956..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/services/EvmTransactionsService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum.services - -import com.gemwallet.android.blockchain.rpc.model.JSONRpcRequest -import com.gemwallet.android.blockchain.rpc.model.JSONRpcResponse -import com.wallet.core.blockchain.ethereum.EthereumTransactionReciept -import retrofit2.http.Body -import retrofit2.http.POST - -interface EvmTransactionsService { - @POST("/") - suspend fun transaction(@Body request: JSONRpcRequest>): JSONRpcResponse -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt index 5e9cc41e4..98e0d9886 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt @@ -65,4 +65,5 @@ class PolkadotGatewayEstimateFee : GemGatewayEstimateFee { val output = AnySigner.sign(input, CoinType.POLKADOT, Polkadot.SigningOutput.parser()) return output.encoded.toByteArray().toHexString().append0x() - } } \ No newline at end of file + } +} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt index c86af2d31..211f3fde0 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/solana/SolanaSignClient.kt @@ -1,7 +1,6 @@ package com.gemwallet.android.blockchain.clients.solana import com.gemwallet.android.blockchain.clients.SignClient -import com.gemwallet.android.blockchain.clients.solana.SolanaChainData import com.gemwallet.android.blockchain.operators.GetAsset import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams @@ -200,7 +199,7 @@ class SolanaSignClient( val signInput = Solana.SigningInput.newBuilder().apply { this.recentBlockhash = recentBlockhash this.delegateStakeTransaction = Solana.DelegateStake.newBuilder().apply { - this.validatorPubkey = params.validatorId + this.validatorPubkey = params.validator.id this.value = finalAmount.toLong() }.build() this.privateKey = ByteString.copyFrom(privateKey) @@ -221,7 +220,7 @@ class SolanaSignClient( val signInput = Solana.SigningInput.newBuilder().apply { this.recentBlockhash = recentBlockhash this.deactivateStakeTransaction = Solana.DeactivateStake.newBuilder().apply { - this.stakeAccount = params.delegationId + this.stakeAccount = params.delegation.base.delegationId }.build() this.privateKey = ByteString.copyFrom(privateKey) } @@ -239,7 +238,7 @@ class SolanaSignClient( val signInput = Solana.SigningInput.newBuilder().apply { this.recentBlockhash = recentBlockhash this.withdrawTransaction = Solana.WithdrawStake.newBuilder().apply { - stakeAccount = params.delegationId + stakeAccount = params.delegation.base.delegationId value = finalAmount.toLong() }.build() this.privateKey = ByteString.copyFrom(privateKey) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt index 2497b439d..b7e3d2f3c 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpSignClient.kt @@ -120,7 +120,7 @@ class XrpSignClient( } }.build() val output = AnySigner.sign(signInput, WCChainTypeProxy().invoke(chain), Ripple.SigningOutput.parser()) - return listOf(output.encoded.toByteArray().toHexString().toByteArray()) + return listOf(output.encoded.toByteArray().toHexString("").toByteArray()) } override fun supported(chain: Chain): Boolean = this.chain == chain diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt index d3d7f36e4..814604651 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignClientProxy.kt @@ -37,20 +37,22 @@ class SignClientProxy( val chain = params.input.asset.id.chain val client = clients.getClient(chain) ?: throw Exception("Chain isn't support") val input = params.input - val fee = params.fee(feePriority) + val data = params.data(feePriority) + val fee = data.fee + val chainData = data.chainData return when (input) { - is ConfirmParams.Stake.DelegateParams -> client.signDelegate(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.Stake.RedelegateParams -> client.signRedelegate(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.Stake.RewardsParams -> client.signRewards(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.Stake.UndelegateParams -> client.signUndelegate(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.Stake.WithdrawParams -> client.signWithdraw(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.SwapParams -> client.signSwap(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.TokenApprovalParams -> client.signTokenApproval(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.TransferParams.Generic -> client.signGenericTransfer(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.TransferParams.Native -> client.signNativeTransfer(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.TransferParams.Token -> client.signTokenTransfer(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.Activate -> client.signActivate(input, params.chainData, params.finalAmount, fee, privateKey) - is ConfirmParams.NftParams -> client.signNft(input, params.chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Stake.DelegateParams -> client.signDelegate(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Stake.RedelegateParams -> client.signRedelegate(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Stake.RewardsParams -> client.signRewards(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Stake.UndelegateParams -> client.signUndelegate(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Stake.WithdrawParams -> client.signWithdraw(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.SwapParams -> client.signSwap(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.TokenApprovalParams -> client.signTokenApproval(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.TransferParams.Generic -> client.signGenericTransfer(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.TransferParams.Native -> client.signNativeTransfer(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.TransferParams.Token -> client.signTokenTransfer(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.Activate -> client.signActivate(input, chainData, params.finalAmount, fee, privateKey) + is ConfirmParams.NftParams -> client.signNft(input, chainData, params.finalAmount, fee, privateKey) } } diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt index 4ebc1a6db..a001c91bd 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt @@ -7,7 +7,6 @@ import com.gemwallet.android.blockchain.clients.bitcoin.toChainData import com.gemwallet.android.blockchain.clients.cardano.CardanoGatewayEstimateFee import com.gemwallet.android.blockchain.clients.cardano.toChainData import com.gemwallet.android.blockchain.clients.cosmos.toChainData -import com.gemwallet.android.blockchain.clients.ethereum.EvmGatewayEstimateFee import com.gemwallet.android.blockchain.clients.ethereum.toChainData import com.gemwallet.android.blockchain.clients.near.toChainData import com.gemwallet.android.blockchain.clients.polkadot.PolkadotGatewayEstimateFee @@ -19,6 +18,8 @@ import com.gemwallet.android.blockchain.clients.ton.toChainData import com.gemwallet.android.blockchain.clients.tron.toChainData import com.gemwallet.android.blockchain.clients.xrp.toChainData import com.gemwallet.android.blockchain.services.mapper.toGem +import com.gemwallet.android.domains.confirm.toGem +import com.gemwallet.android.domains.stake.toGem import com.gemwallet.android.ext.toChainType import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee @@ -30,14 +31,19 @@ import com.wallet.core.primitives.ChainType import com.wallet.core.primitives.FeePriority import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import uniffi.gemstone.GemApprovalData import uniffi.gemstone.GemGasPriceType import uniffi.gemstone.GemGateway import uniffi.gemstone.GemGatewayEstimateFee +import uniffi.gemstone.GemStakeType import uniffi.gemstone.GemTransactionInputType import uniffi.gemstone.GemTransactionLoadFee import uniffi.gemstone.GemTransactionLoadInput import uniffi.gemstone.GemTransactionLoadMetadata import uniffi.gemstone.GemTransactionPreloadInput +import uniffi.gemstone.GemTransferDataExtra +import uniffi.gemstone.GemTransferDataOutputType +import uniffi.gemstone.GemWalletConnectionSessionAppMetadata import uniffi.gemstone.SwapperException class SignerPreloaderProxy( @@ -45,34 +51,34 @@ class SignerPreloaderProxy( ) { suspend fun preload(params: ConfirmParams): SignerParams = withContext(Dispatchers.IO) { - val gemAsset = params.asset.toGem() val assetId = params.assetId val chain = assetId.chain + val feeAssetId = AssetId(chain) val gemChain = assetId.chain.string val destination = params.destination()?.address ?: throw java.lang.IllegalArgumentException() try { + val inputType = getInputType(params) val metadata = gateway.getTransactionPreload( chain = gemChain, input = GemTransactionPreloadInput( - inputType = GemTransactionInputType.Transfer(gemAsset), + inputType = inputType, senderAddress = params.from.address, destinationAddress = destination ) ) val feeRates = gateway.getFeeRates( chain = gemChain, - input = GemTransactionInputType.Transfer(gemAsset), + input = inputType ) - val fees = feeRates.map { feeRate -> - val feeAssetId = AssetId(chain) + val transactionData = feeRates.map { feeRate -> val priority = FeePriority.entries.firstOrNull { it.string == feeRate.priority } ?: return@map null val result = gateway.getTransactionLoad( chain = gemChain, input = GemTransactionLoadInput( - inputType = GemTransactionInputType.Transfer(gemAsset), + inputType = inputType, senderAddress = params.from.address, destinationAddress = destination, value = params.amount.toString(), @@ -83,41 +89,99 @@ class SignerPreloaderProxy( ), provider = getEstimateFee(chain) ) - chain.toFeeType().convertFee(feeAssetId, priority, result.fee) + val fee = chain.toFeeType().convertFee(feeAssetId, priority, result.fee) + val chainData = result.metadata.toChainData() + SignerParams.Data(chainData = chainData, fee = fee) }.filterNotNull() - val chainData = metadata.toChainData() - SignerParams( input = params, - chainData = chainData, - fee = fees + data = transactionData, ) } catch (err: Throwable) { throw err } -// val preloadJob = async { -// when (params) { -// is ConfirmParams.Stake -> preloadStake(params) -// is ConfirmParams.SwapParams -> preloadSwap(params) -// is ConfirmParams.TokenApprovalParams -> preloadApproval(params) -// is ConfirmParams.TransferParams.Native -> preloadNativeTransfer(params) -// is ConfirmParams.TransferParams.Token -> preloadTokenTransfer(params) -// is ConfirmParams.Activate -> preloadActivate(params) -// is ConfirmParams.TransferParams.Generic -> preloadGeneric(params) -// is ConfirmParams.NftParams -> preloadNft(params) -// } -// } + } + + private fun getInputType(params: ConfirmParams): GemTransactionInputType { + val gemAsset = params.asset.toGem() + val chain = params.assetId.chain.string -// preloadJob.await() + return when (params) { + is ConfirmParams.Stake.DelegateParams -> GemTransactionInputType.Stake( + asset = gemAsset, + stakeType = GemStakeType.Delegate(params.validator.toGem(chain)) + ) + is ConfirmParams.Stake.RedelegateParams -> GemTransactionInputType.Stake( + asset = gemAsset, + stakeType = GemStakeType.Redelegate( + delegation = params.delegation.toGem(chain), + toValidator = params.dstValidator.toGem(chain) + ) + ) + is ConfirmParams.Stake.RewardsParams -> GemTransactionInputType.Stake( + asset = gemAsset, + stakeType = GemStakeType.WithdrawRewards( + validators = params.validators.map { it.toGem(chain) } + ) + ) + is ConfirmParams.Stake.UndelegateParams -> GemTransactionInputType.Stake( + asset = gemAsset, + stakeType = GemStakeType.Undelegate( + delegation = params.delegation.toGem(chain), + ) + ) + is ConfirmParams.Stake.WithdrawParams -> GemTransactionInputType.Stake( + asset = gemAsset, + stakeType = GemStakeType.Withdraw(params.delegation.toGem(chain)) + ) + is ConfirmParams.SwapParams -> GemTransactionInputType.Swap( + fromAsset = params.fromAsset.toGem(), + toAsset = params.toAsset.toGem(), + swapData = params.toGem() + ) + is ConfirmParams.TokenApprovalParams -> GemTransactionInputType.TokenApprove( + gemAsset, + GemApprovalData( + params.assetId.tokenId!!, + spender = params.contract, + value = params.amount.toString(), + ) + ) + is ConfirmParams.TransferParams.Generic -> GemTransactionInputType.Generic( + asset = gemAsset, + metadata = GemWalletConnectionSessionAppMetadata( + name = params.name, + description = params.description, + url = params.url, + icon = params.icon, + redirectNative = params.redirectNative, + redirectUniversal = params.redirectUniversal, // TODO: Remove not used data + ), + extra = GemTransferDataExtra( + gasLimit = null, + gasPrice = null, + data = params.memo?.toByteArray(), + outputType = when (params.inputType) { + ConfirmParams.TransferParams.InputType.Signature -> GemTransferDataOutputType.SIGNATURE + ConfirmParams.TransferParams.InputType.EncodeTransaction -> GemTransferDataOutputType.ENCODED_TRANSACTION + null -> throw IllegalArgumentException("Not supported ${params.inputType}") + }, + ), + ) + is ConfirmParams.Activate, + is ConfirmParams.NftParams, + is ConfirmParams.TransferParams.Native, + is ConfirmParams.TransferParams.Token -> GemTransactionInputType.Transfer(gemAsset) + } } private fun getEstimateFee(chain: Chain): GemGatewayEstimateFee { return when (chain.toChainType()) { ChainType.Bitcoin -> BitcoinGatewayEstimateFee() - ChainType.Ethereum -> EvmGatewayEstimateFee() ChainType.Cardano -> CardanoGatewayEstimateFee() ChainType.Polkadot -> PolkadotGatewayEstimateFee() + ChainType.Ethereum, ChainType.Solana, ChainType.Cosmos, ChainType.Ton, diff --git a/features/earn/stake/viewmodels/src/main/kotlin/com/gemwallet/features/stake/viewmodels/StakeViewModel.kt b/features/earn/stake/viewmodels/src/main/kotlin/com/gemwallet/features/stake/viewmodels/StakeViewModel.kt index 328470e9b..35c4edfcf 100644 --- a/features/earn/stake/viewmodels/src/main/kotlin/com/gemwallet/features/stake/viewmodels/StakeViewModel.kt +++ b/features/earn/stake/viewmodels/src/main/kotlin/com/gemwallet/features/stake/viewmodels/StakeViewModel.kt @@ -98,15 +98,15 @@ class StakeViewModel @Inject constructor( fun onRewards(onConfirm: (ConfirmParams) -> Unit) { val assetInfo = assetInfo.value ?: return val account = account.value ?: return - val validatorsId = delegations.value.filter { BigInteger(it.base.rewards) > BigInteger.ZERO } - .map { it.base.validatorId } + val validators = delegations.value.filter { BigInteger(it.base.rewards) > BigInteger.ZERO } + .map { it.validator } .toSet() .toList() onConfirm( ConfirmParams.Stake.RewardsParams( asset = assetInfo.asset, from = account, - validatorsId = validatorsId, + validators = validators, amount = rewardsAmount.value ) ) diff --git a/features/swap/viewmodels/src/main/kotlin/com/gemwallet/features/swap/viewmodels/SwapViewModel.kt b/features/swap/viewmodels/src/main/kotlin/com/gemwallet/features/swap/viewmodels/SwapViewModel.kt index a8fbe415a..259c998e4 100644 --- a/features/swap/viewmodels/src/main/kotlin/com/gemwallet/features/swap/viewmodels/SwapViewModel.kt +++ b/features/swap/viewmodels/src/main/kotlin/com/gemwallet/features/swap/viewmodels/SwapViewModel.kt @@ -249,17 +249,22 @@ class SwapViewModel @Inject constructor( return ConfirmParams.SwapParams( from = quote.pay.owner!!, fromAsset = quote.pay.asset, - toAssetId = quote.receive.id(), + toAsset = quote.receive.asset, fromAmount = Crypto(fromAmount, quote.pay.asset.decimals).atomicValue, toAmount = BigInteger(quote.quote.toValue), swapData = swapData.data, provider = quote.quote.data.provider.protocol, + providerName = quote.quote.data.provider.name, protocolId = quote.quote.data.provider.protocolId, to = swapData.to, value = swapData.value, approval = swapData.approval?.toModel(), gasLimit = swapData.gasLimit?.toBigIntegerOrNull(), - maxFrom = BigInteger(quote.pay.balance.balance.available) == Crypto(fromAmount, quote.pay.asset.decimals).atomicValue + maxFrom = BigInteger(quote.pay.balance.balance.available) == Crypto(fromAmount, quote.pay.asset.decimals).atomicValue, + etaInSeconds = quote.quote.etaInSeconds, + slippageBps = quote.quote.data.slippageBps, + walletAddress = quote.pay.owner?.address!!, + ) } diff --git a/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt b/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt index 726cd52d7..173a240b2 100644 --- a/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt +++ b/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt @@ -249,14 +249,14 @@ class AmountViewModel @Inject constructor( val builder = ConfirmParams.Builder(asset, owner, amount.atomicValue) val nextParams = when (params.txType) { TransactionType.Transfer -> builder.transfer(destination!!, memo, maxAmount.value,) - TransactionType.StakeDelegate -> builder.delegate(validator?.id ?: return) + TransactionType.StakeDelegate -> builder.delegate(validator ?: return) TransactionType.StakeUndelegate -> builder.undelegate(delegation ?: return) TransactionType.StakeRewards -> { val validators = stakeRepository.getRewards(asset.id, owner.address) - .map { it.validator.id } + .map { it.validator } builder.rewards(validators) } - TransactionType.StakeRedelegate -> builder.redelegate(validator?.id!!, delegation!!) + TransactionType.StakeRedelegate -> builder.redelegate(validator!!, delegation!!) TransactionType.StakeWithdraw -> builder.withdraw(delegation!!) TransactionType.AssetActivation -> builder.activate() TransactionType.Swap, diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/domains/confirm/ConfirmParamsExt.kt b/gemcore/src/main/kotlin/com/gemwallet/android/domains/confirm/ConfirmParamsExt.kt new file mode 100644 index 000000000..3d24439d3 --- /dev/null +++ b/gemcore/src/main/kotlin/com/gemwallet/android/domains/confirm/ConfirmParamsExt.kt @@ -0,0 +1,38 @@ +package com.gemwallet.android.domains.confirm + +import com.gemwallet.android.model.ConfirmParams +import uniffi.gemstone.GemApprovalData +import uniffi.gemstone.GemSwapData +import uniffi.gemstone.GemSwapProviderData +import uniffi.gemstone.GemSwapQuote +import uniffi.gemstone.GemSwapQuoteData + +fun ConfirmParams.SwapParams.toGem(): GemSwapData { + return GemSwapData( + quote = GemSwapQuote( + fromValue = fromAmount.toString(), + toValue = toAmount.toString(), + providerData = GemSwapProviderData( + provider = provider, + protocolName = protocolId, + name = providerName, + ), + walletAddress = walletAddress, + slippageBps = slippageBps, + etaInSeconds = etaInSeconds, + ), + data = GemSwapQuoteData( + to = to, + data = swapData, + approval = approval?.let { + GemApprovalData( + token = it.token, + spender = it.spender, + value = it.value + ) + }, + value = value, + gasLimit = gasLimit?.toString() + ) + ) +} \ No newline at end of file diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/domains/stake/DelegationExt.kt b/gemcore/src/main/kotlin/com/gemwallet/android/domains/stake/DelegationExt.kt new file mode 100644 index 000000000..99a4e3013 --- /dev/null +++ b/gemcore/src/main/kotlin/com/gemwallet/android/domains/stake/DelegationExt.kt @@ -0,0 +1,23 @@ +package com.gemwallet.android.domains.stake + +import com.gemwallet.android.ext.toIdentifier +import com.gemwallet.android.model.ConfirmParams +import com.wallet.core.primitives.Delegation +import uniffi.gemstone.GemDelegation +import uniffi.gemstone.GemDelegationBase + +fun Delegation.toGem(chain: uniffi.gemstone.Chain): GemDelegation { + return GemDelegation( + base = GemDelegationBase( + assetId = base.assetId.toIdentifier(), + delegationId = base.delegationId, + validatorId = base.validatorId, + balance = base.balance, + shares = base.shares, + completionDate = base.completionDate?.toULong(), + delegationState = base.state.string, + rewards = base.rewards, + ), + validator = validator.toGem(chain) + ) +} \ No newline at end of file diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/domains/stake/DelegationValidatorExt.kt b/gemcore/src/main/kotlin/com/gemwallet/android/domains/stake/DelegationValidatorExt.kt new file mode 100644 index 000000000..f6f9b5445 --- /dev/null +++ b/gemcore/src/main/kotlin/com/gemwallet/android/domains/stake/DelegationValidatorExt.kt @@ -0,0 +1,15 @@ +package com.gemwallet.android.domains.stake + +import com.wallet.core.primitives.DelegationValidator +import uniffi.gemstone.GemDelegationValidator + +fun DelegationValidator.toGem(chain: uniffi.gemstone.Chain): GemDelegationValidator { + return GemDelegationValidator( + chain = chain, + id = id, + name = name, + isActive = isActive, + commission = commision, + apr = apr, + ) +} \ No newline at end of file diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/model/ConfirmParams.kt b/gemcore/src/main/kotlin/com/gemwallet/android/model/ConfirmParams.kt index 291cc0558..251e9c875 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/model/ConfirmParams.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/model/ConfirmParams.kt @@ -11,6 +11,7 @@ import com.wallet.core.primitives.Asset import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.AssetSubtype import com.wallet.core.primitives.Delegation +import com.wallet.core.primitives.DelegationValidator import com.wallet.core.primitives.NFTAsset import com.wallet.core.primitives.TransactionType import kotlinx.serialization.Serializable @@ -60,16 +61,15 @@ sealed class ConfirmParams { return TokenApprovalParams(asset, from, approvalData, provider, contract) } - fun delegate(validatorId: String) = Stake.DelegateParams(asset, from, amount, validatorId) + fun delegate(validator: DelegationValidator) = Stake.DelegateParams(asset, from, amount, validator) - fun rewards(validatorsId: List) = Stake.RewardsParams(asset, from, validatorsId, amount) + fun rewards(validators: List) = Stake.RewardsParams(asset, from, validators, amount) fun withdraw(delegation: Delegation) = Stake.WithdrawParams( asset = asset, from = from, amount = amount, - validatorId = delegation.validator.id, - delegationId = delegation.base.delegationId, + delegation = delegation, ) fun undelegate(delegation: Delegation): Stake.UndelegateParams { @@ -77,20 +77,17 @@ sealed class ConfirmParams { asset, from, amount, - delegation.validator.id, - delegation.base.delegationId, - delegation.base.shares, - delegation.base.balance + delegation, ) } - fun redelegate(dstValidatorId: String, delegation: Delegation): Stake.RedelegateParams { + fun redelegate(dstValidator: DelegationValidator, delegation: Delegation): Stake.RedelegateParams { return Stake.RedelegateParams( asset, from = from, amount, - delegation.validator.id, - dstValidatorId, + delegation, + dstValidator, delegation.base.shares, delegation.base.balance, ) @@ -129,6 +126,14 @@ sealed class ConfirmParams { override val memo: String? = null, override val isMaxAmount: Boolean = false, override val inputType: InputType? = null, + val name: String, + val description: String, + val url: String, + val icon: String, + val redirectNative: String?, + val redirectUniversal: String?, + val gasLimit: String?, + val gasPrice: String?, ) : TransferParams() @Serializable @@ -183,14 +188,18 @@ sealed class ConfirmParams { override val from: Account, val fromAsset: Asset, @Serializable(BigIntegerSerializer::class) val fromAmount: BigInteger, - val toAssetId: AssetId, + val toAsset: Asset, @Serializable(BigIntegerSerializer::class) val toAmount: BigInteger, val swapData: String, val provider: String, + val providerName: String, val protocolId: String, val to: String, val value: String, val approval: ApprovalData? = null, + val slippageBps: UInt, + val etaInSeconds: UInt?, + val walletAddress: String, @Serializable(BigIntegerSerializer::class) val gasLimit: BigInteger? = null, val maxFrom: Boolean = false, ) : ConfirmParams() { @@ -242,61 +251,68 @@ sealed class ConfirmParams { @Serializable sealed class Stake : ConfirmParams() { - abstract val validatorId: String @Serializable class DelegateParams( override val asset: Asset, override val from: Account, @Serializable(BigIntegerSerializer::class) override val amount: BigInteger, - override val validatorId: String, - ) : Stake() + val validator: DelegationValidator, + ) : Stake() { + override fun destination(): DestinationAddress? { + return DestinationAddress(validator.id) + } + } @Serializable class WithdrawParams( override val asset: Asset, override val from: Account, @Serializable(BigIntegerSerializer::class) override val amount: BigInteger, - override val validatorId: String, - val delegationId: String, - ) : Stake() + val delegation: Delegation, + ) : Stake() { + override fun destination(): DestinationAddress? { + return DestinationAddress(delegation.validator.id) + } + } @Serializable class UndelegateParams( override val asset: Asset, override val from: Account, @Serializable(BigIntegerSerializer::class) override val amount: BigInteger, - override val validatorId: String, - val delegationId: String, - val share: String?, - val balance: String? - ) : Stake() + val delegation: Delegation, + ) : Stake() { + override fun destination(): DestinationAddress? { + return DestinationAddress(delegation.validator.id) + } + } @Serializable class RedelegateParams( override val asset: Asset, override val from: Account, @Serializable(BigIntegerSerializer::class) override val amount: BigInteger, - val srcValidatorId: String, - val dstValidatorId: String, + val delegation: Delegation, + val dstValidator: DelegationValidator, val share: String?, val balance: String?, ) : Stake() { - override val validatorId: String = "" + override fun destination(): DestinationAddress? { + return DestinationAddress("") + } } @Serializable class RewardsParams( override val asset: Asset, override val from: Account, - val validatorsId: List, + val validators: List, @Serializable(BigIntegerSerializer::class) override val amount: BigInteger, ) : Stake() { - override val validatorId: String = "" - } - - override fun destination(): DestinationAddress? { - return DestinationAddress(validatorId) + override fun destination(): DestinationAddress? { + return DestinationAddress("") + } } } diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/model/SignerParams.kt b/gemcore/src/main/kotlin/com/gemwallet/android/model/SignerParams.kt index d94122b69..9645c7075 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/model/SignerParams.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/model/SignerParams.kt @@ -5,25 +5,29 @@ import java.math.BigInteger data class SignerParams( val input: ConfirmParams, - val chainData: ChainSignData, - private val fee: List, +// val chainData: ChainSignData, +// private val fee: List, + val data: List, val finalAmount: BigInteger = BigInteger.ZERO, ) { fun fee(priority: FeePriority = FeePriority.Normal): Fee { - return fee.firstOrNull { it.priority == priority } ?: fee.first() + return data.firstOrNull { it.fee.priority == priority }?.fee ?: data.first().fee + } + + fun data(priority: FeePriority = FeePriority.Normal): Data { + return data.firstOrNull { it.fee.priority == priority } ?: data.first() } fun gasFee(feePriority: FeePriority = FeePriority.Normal): GasFee = (fee(feePriority) as? GasFee) ?: throw Exception("Fee error: wait gas fee") - fun allFee(): List = fee + fun allFee(): List = data.map { it.fee } + + data class Data( + val fee: Fee, + val chainData: ChainSignData, + ) } interface ChainSignData { -// fun fee(speed: FeePriority = FeePriority.Normal): Fee -// -// fun gasFee(feePriority: FeePriority = FeePriority.Normal): GasFee = (fee(feePriority) as? GasFee) ?: throw Exception("Fee error: wait gas fee") -// -// fun allFee(): List = emptyList() - fun blockNumber(): String = "" } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 459da60e4..e75bafcd1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,16 +3,16 @@ accompanistPermissions = "0.37.3" activityCompose = "1.11.0" browser = "1.9.0" uiautomator = "2.3.0" -walletconnect = "1.4.10" +walletconnect = "1.4.11" barcodeScanning = "17.3.0" biometric = "1.2.0-alpha05" cameraCamera2 = "1.5.0" coilCompose = "3.3.0" -vico = "2.1.3" +vico = "2.2.0" core = "3.5.3" coreKtx = "1.17.0" espressoCore = "3.7.0" -firebaseMessaging = "25.0.0" +firebaseMessaging = "25.0.1" gradle = "8.13.0" gson = "2.13.2" hiltAndroid = "2.57.1" @@ -24,7 +24,7 @@ kotlinSerialization = "2.2.20" kotlinxSerializationJson = "1.9.0" kotlinxCollectionsImmutable = "0.4.0" kotlinxCoroutinesAndroid = "1.10.2" -lifecycleRuntimeCompose = "2.9.3" +lifecycleRuntimeCompose = "2.9.4" loggingInterceptor = "5.1.0" retrofit = "3.0.0" review = "2.0.2" @@ -46,7 +46,7 @@ reorderable = "3.0.0" mockkVersion = "1.14.5" datastore = "1.1.7" wallet-core = "4.3.5" -gemstone = "0.33.4" +gemstone = "0.33.5" ktor = "3.3.0" appcompat = "1.7.1" material = "1.13.0" From 5e4d6e155a913228fba7d00e988c35484648c1af Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Thu, 18 Sep 2025 20:53:35 -0700 Subject: [PATCH 12/16] Update --- .../confirm/viewmodels/ConfirmViewModel.kt | 2 + core | 2 +- .../presents/details/TransactionDetails.kt | 20 ++++-- .../presents/views/AmountScene.kt | 2 + .../viewmodels/AmountViewModel.kt | 10 ++- .../gemwallet/android/model/Transaction.kt | 4 +- .../com/wallet/core/primitives/StakeType.kt | 65 +++++++++++++++++++ .../com/wallet/core/primitives/Support.kt | 3 +- .../wallet/core/primitives/TransactionType.kt | 4 ++ .../components/list_item/TransactionItem.kt | 8 +++ ui/src/main/res/values-ar/strings.xml | 12 +++- ui/src/main/res/values-bn/strings.xml | 14 +++- ui/src/main/res/values-cs/strings.xml | 14 +++- ui/src/main/res/values-da/strings.xml | 14 +++- ui/src/main/res/values-de/strings.xml | 10 +++ ui/src/main/res/values-es/strings.xml | 12 +++- ui/src/main/res/values-fa/strings.xml | 10 +++ ui/src/main/res/values-fil/strings.xml | 14 +++- ui/src/main/res/values-fr/strings.xml | 12 +++- ui/src/main/res/values-hi/strings.xml | 14 +++- ui/src/main/res/values-id/strings.xml | 10 +++ ui/src/main/res/values-it/strings.xml | 14 +++- ui/src/main/res/values-iw/strings.xml | 14 +++- ui/src/main/res/values-ja/strings.xml | 16 ++++- ui/src/main/res/values-ko/strings.xml | 12 +++- ui/src/main/res/values-ms/strings.xml | 14 +++- ui/src/main/res/values-nl/strings.xml | 14 +++- ui/src/main/res/values-pl/strings.xml | 12 +++- ui/src/main/res/values-pt-rBR/strings.xml | 12 +++- ui/src/main/res/values-ro/strings.xml | 14 +++- ui/src/main/res/values-ru/strings.xml | 10 +++ ui/src/main/res/values-sw/strings.xml | 14 +++- ui/src/main/res/values-th/strings.xml | 14 +++- ui/src/main/res/values-tr/strings.xml | 10 +++ ui/src/main/res/values-uk/strings.xml | 10 +++ ui/src/main/res/values-ur/strings.xml | 14 +++- ui/src/main/res/values-vi/strings.xml | 12 +++- ui/src/main/res/values-zh-rCN/strings.xml | 14 +++- ui/src/main/res/values-zh-rTW/strings.xml | 12 +++- ui/src/main/res/values/strings.xml | 10 +++ 40 files changed, 447 insertions(+), 51 deletions(-) create mode 100644 gemcore/src/main/kotlin/com/wallet/core/primitives/StakeType.kt diff --git a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt index 03358362b..cc2463454 100644 --- a/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt +++ b/app/src/main/kotlin/com/gemwallet/android/features/confirm/viewmodels/ConfirmViewModel.kt @@ -518,6 +518,8 @@ class ConfirmViewModel @Inject constructor( TransactionType.SmartContractCall -> TODO() TransactionType.PerpetualOpenPosition -> TODO() TransactionType.PerpetualClosePosition -> TODO() + TransactionType.StakeFreeze -> TODO() + TransactionType.StakeUnfreeze -> TODO() } if (assetBalance < totalAmount) { diff --git a/core b/core index 9576845c6..e4c7e6686 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 9576845c620a5ddad8a2b0368b1ff8cfdefc27a7 +Subproject commit e4c7e6686a9e3b60559eb474ad809bb8acb6b3d0 diff --git a/features/activities/presents/src/main/kotlin/com/gemwallet/android/features/activities/presents/details/TransactionDetails.kt b/features/activities/presents/src/main/kotlin/com/gemwallet/android/features/activities/presents/details/TransactionDetails.kt index c831c3383..07b108676 100644 --- a/features/activities/presents/src/main/kotlin/com/gemwallet/android/features/activities/presents/details/TransactionDetails.kt +++ b/features/activities/presents/src/main/kotlin/com/gemwallet/android/features/activities/presents/details/TransactionDetails.kt @@ -111,10 +111,13 @@ private fun LazyListScope.transactionItemHead(model: TxDetailsScreenModel) { TransactionType.TransferNFT, TransactionType.Transfer -> model.cryptoAmount TransactionType.AssetActivation, + TransactionType.SmartContractCall, + TransactionType.PerpetualOpenPosition, + TransactionType.PerpetualClosePosition, + TransactionType.StakeFreeze, + TransactionType.StakeUnfreeze, TransactionType.TokenApproval -> model.asset.symbol - TransactionType.SmartContractCall -> TODO() - TransactionType.PerpetualOpenPosition -> TODO() - TransactionType.PerpetualClosePosition -> TODO() + }, equivalent = when (model.type) { TransactionType.StakeDelegate, @@ -126,10 +129,13 @@ private fun LazyListScope.transactionItemHead(model: TxDetailsScreenModel) { TransactionType.Transfer -> model.fiatAmount TransactionType.AssetActivation, TransactionType.TransferNFT, + TransactionType.SmartContractCall, + TransactionType.PerpetualOpenPosition, + TransactionType.PerpetualClosePosition, + TransactionType.StakeFreeze, + TransactionType.StakeUnfreeze, TransactionType.TokenApproval -> null - TransactionType.SmartContractCall -> TODO() - TransactionType.PerpetualOpenPosition -> TODO() - TransactionType.PerpetualClosePosition -> TODO() + }, ) } @@ -187,6 +193,8 @@ private fun LazyListScope.transactionRecipientItem(model: TxDetailsScreenModel) TransactionType.SmartContractCall, TransactionType.PerpetualOpenPosition, TransactionType.PerpetualClosePosition, + TransactionType.StakeFreeze, + TransactionType.StakeUnfreeze, TransactionType.StakeWithdraw -> return TransactionType.Transfer, diff --git a/features/transfer_amount/presents/src/main/kotlin/com/gemwallet/features/transfer_amount/presents/views/AmountScene.kt b/features/transfer_amount/presents/src/main/kotlin/com/gemwallet/features/transfer_amount/presents/views/AmountScene.kt index 263120215..a46529a43 100644 --- a/features/transfer_amount/presents/src/main/kotlin/com/gemwallet/features/transfer_amount/presents/views/AmountScene.kt +++ b/features/transfer_amount/presents/src/main/kotlin/com/gemwallet/features/transfer_amount/presents/views/AmountScene.kt @@ -157,4 +157,6 @@ private fun getTitle(txType: TransactionType) = when (txType) { TransactionType.SmartContractCall -> stringResource(id = R.string.transfer_amount_title) TransactionType.PerpetualOpenPosition -> stringResource(R.string.perpetual_position) TransactionType.PerpetualClosePosition -> stringResource(R.string.perpetual_close_position) + TransactionType.StakeFreeze -> stringResource(R.string.transfer_freeze_title) + TransactionType.StakeUnfreeze -> stringResource(R.string.transfer_unfreeze_title) } \ No newline at end of file diff --git a/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt b/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt index 173a240b2..42b14f1f5 100644 --- a/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt +++ b/features/transfer_amount/viewmodels/src/main/kotlin/com/gemwallet/features/transfer_amount/viewmodels/AmountViewModel.kt @@ -129,12 +129,14 @@ class AmountViewModel @Inject constructor( TransactionType.StakeUndelegate, TransactionType.StakeRedelegate, TransactionType.StakeWithdraw -> Crypto(BigInteger(delegation?.base?.balance ?: "0")) + TransactionType.PerpetualOpenPosition -> throw IllegalArgumentException() // TODO: HyperCore + TransactionType.PerpetualClosePosition -> throw IllegalArgumentException() // TODO: HyperCore TransactionType.AssetActivation, TransactionType.TransferNFT, TransactionType.SmartContractCall, TransactionType.TokenApproval, - TransactionType.PerpetualOpenPosition -> throw IllegalArgumentException() // TODO: HyperCore - TransactionType.PerpetualClosePosition -> throw IllegalArgumentException() // TODO: HyperCore + TransactionType.StakeFreeze, + TransactionType.StakeUnfreeze, null -> Crypto(BigInteger.ZERO) } assetInfo.asset.format(value, 8) @@ -264,6 +266,8 @@ class AmountViewModel @Inject constructor( TransactionType.SmartContractCall, TransactionType.TokenApproval, TransactionType.PerpetualOpenPosition, + TransactionType.StakeFreeze, + TransactionType.StakeUnfreeze, TransactionType.PerpetualClosePosition -> throw IllegalArgumentException() } onConfirm(nextParams) @@ -341,6 +345,8 @@ class AmountViewModel @Inject constructor( TransactionType.TransferNFT, TransactionType.PerpetualOpenPosition, TransactionType.PerpetualClosePosition, + TransactionType.StakeFreeze, + TransactionType.StakeUnfreeze, TransactionType.SmartContractCall -> throw IllegalArgumentException() } if (amount.atomicValue > availableAmount.atomicValue) { diff --git a/gemcore/src/main/kotlin/com/gemwallet/android/model/Transaction.kt b/gemcore/src/main/kotlin/com/gemwallet/android/model/Transaction.kt index 877ca847c..c1aad7887 100644 --- a/gemcore/src/main/kotlin/com/gemwallet/android/model/Transaction.kt +++ b/gemcore/src/main/kotlin/com/gemwallet/android/model/Transaction.kt @@ -26,8 +26,8 @@ data class Transaction ( val value: String, val memo: String? = null, val direction: TransactionDirection, - val utxoInputs: List, - val utxoOutputs: List, + val utxoInputs: List, + val utxoOutputs: List, @Serializable(with = JsonAsStringSerializer::class) val metadata: String? = null, @Serializable(with = DateSerializer::class) val createdAt: Long, diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/StakeType.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/StakeType.kt new file mode 100644 index 000000000..a193ad0af --- /dev/null +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/StakeType.kt @@ -0,0 +1,65 @@ +/** + * Generated by typeshare 1.13.2 + */ + +package com.wallet.core.primitives + +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerialName + +@Serializable +enum class FreezeType(val string: String) { + @SerialName("Freeze") + Freeze("Freeze"), + @SerialName("Unfreeze") + Unfreeze("Unfreeze"), +} + +@Serializable +enum class Resource(val string: String) { + @SerialName("bandwidth") + Bandwidth("bandwidth"), + @SerialName("energy") + Energy("energy"), +} + +@Serializable +data class FreezeData ( + val freezeType: FreezeType, + val resource: Resource +) + +@Serializable +data class RedelegateData ( + val delegation: Delegation, + val toValidator: DelegationValidator +) + +@Serializable +data class StakeData ( + val data: String? = null, + val to: String? = null +) + +@Serializable +sealed class StakeType { + @Serializable + @SerialName("Stake") + data class Stake(val content: DelegationValidator): StakeType() + @Serializable + @SerialName("Unstake") + data class Unstake(val content: Delegation): StakeType() + @Serializable + @SerialName("Redelegate") + data class Redelegate(val content: RedelegateData): StakeType() + @Serializable + @SerialName("Rewards") + data class Rewards(val content: List): StakeType() + @Serializable + @SerialName("Withdraw") + data class Withdraw(val content: Delegation): StakeType() + @Serializable + @SerialName("Freeze") + data class Freeze(val content: FreezeData): StakeType() +} + diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/Support.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/Support.kt index abb915265..370a53ac8 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/Support.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/Support.kt @@ -10,6 +10,7 @@ import kotlinx.serialization.SerialName @Serializable data class SupportDevice ( val supportId: String, - val deviceId: String + val deviceId: String, + val unread: Int ) diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionType.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionType.kt index 6a002002b..7ffe65332 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionType.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/TransactionType.kt @@ -27,6 +27,10 @@ enum class TransactionType(val string: String) { StakeRedelegate("stakeRedelegate"), @SerialName("stakeWithdraw") StakeWithdraw("stakeWithdraw"), + @SerialName("stakeFreeze") + StakeFreeze("stakeFreeze"), + @SerialName("stakeUnfreeze") + StakeUnfreeze("stakeUnfreeze"), @SerialName("assetActivation") AssetActivation("assetActivation"), @SerialName("smartContractCall") diff --git a/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/TransactionItem.kt b/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/TransactionItem.kt index 2c95ac02a..e4b687293 100644 --- a/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/TransactionItem.kt +++ b/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/TransactionItem.kt @@ -232,6 +232,8 @@ fun TransactionType.getTitle(direction: TransactionDirection? = null, state: Tra TransactionType.SmartContractCall -> R.string.transfer_smart_contract_title TransactionType.PerpetualOpenPosition -> R.string.perpetual_position TransactionType.PerpetualClosePosition -> R.string.perpetual_close_position + TransactionType.StakeFreeze -> R.string.transfer_freeze_title + TransactionType.StakeUnfreeze -> R.string.transfer_unfreeze_title } } @@ -251,6 +253,8 @@ fun TransactionType.getTransactionTitle(direction: TransactionDirection, state: TransactionType.SmartContractCall -> stringResource(R.string.transfer_smart_contract_title) TransactionType.PerpetualOpenPosition -> stringResource(R.string.perpetual_position) TransactionType.PerpetualClosePosition -> stringResource(R.string.perpetual_close_position) + TransactionType.StakeFreeze -> stringResource(R.string.transfer_freeze_title) + TransactionType.StakeUnfreeze -> stringResource(R.string.transfer_unfreeze_title) } } @@ -272,6 +276,8 @@ fun TransactionType.getValue(direction: TransactionDirection, value: String): St TransactionType.TokenApproval, TransactionType.TransferNFT, TransactionType.AssetActivation, + TransactionType.StakeFreeze, + TransactionType.StakeUnfreeze, TransactionType.SmartContractCall -> "" } } @@ -295,6 +301,8 @@ fun TransactionType.getAddress(direction: TransactionDirection, from: String, to TransactionType.StakeRewards, TransactionType.SmartContractCall, TransactionType.PerpetualOpenPosition, + TransactionType.StakeFreeze, + TransactionType.StakeUnfreeze, TransactionType.PerpetualClosePosition -> "" } } diff --git a/ui/src/main/res/values-ar/strings.xml b/ui/src/main/res/values-ar/strings.xml index ed4ac0866..f1cde6e11 100644 --- a/ui/src/main/res/values-ar/strings.xml +++ b/ui/src/main/res/values-ar/strings.xml @@ -159,7 +159,7 @@ Redelegate تفعيل Deactivating - Withdraw + ينسحب Step %d Sign Message رسالة @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + لقد تركنا %s خارجًا حتى تتمكن من دفع رسوم السحب. + يتم تشغيل التنبيهات عند حدوث تحركات كبيرة في الأسعار. + تعيين تنبيه السعر + الحد الأدنى للاستقبال + تجميد + إزالة التجميد + موارد + الموارد + طاقة + عرض النطاق الترددي diff --git a/ui/src/main/res/values-bn/strings.xml b/ui/src/main/res/values-bn/strings.xml index 1c56ec8a5..45eda6d03 100644 --- a/ui/src/main/res/values-bn/strings.xml +++ b/ui/src/main/res/values-bn/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + সংরক্ষিত No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + প্রত্যাহার করুন Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + আমরা %s বাদ দিয়েছি যাতে আপনি টাকা তোলার ফি পরিশোধ করতে পারেন। + উল্লেখযোগ্য মূল্য পরিবর্তনের সময় সতর্কতাগুলি ট্রিগার করে। + মূল্য সতর্কতা সেট করুন + প্রাপ্তির সর্বনিম্ন + জমে যাওয়া + আনফ্রিজ করুন + রিসোর্স + রিসোর্স + শক্তি + ব্যান্ডউইথ diff --git a/ui/src/main/res/values-cs/strings.xml b/ui/src/main/res/values-cs/strings.xml index b24bd9a28..b4770f012 100644 --- a/ui/src/main/res/values-cs/strings.xml +++ b/ui/src/main/res/values-cs/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + Rezervováno No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + Výběr Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Vynechali jsme %s, abyste mohli uhradit poplatky za výběr. + Upozornění se spouštějí při významných cenových pohybech. + Nastavit cenové upozornění + Minimální příjem + Zmrazit + Uvolnit + Zdroje + Zdroj + Energie + Šířka pásma diff --git a/ui/src/main/res/values-da/strings.xml b/ui/src/main/res/values-da/strings.xml index 4cffe17a7..a9275b0fd 100644 --- a/ui/src/main/res/values-da/strings.xml +++ b/ui/src/main/res/values-da/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + Reserveret No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + Hæv Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Vi har udeladt %s så du kan betale for udbetalingsgebyrer. + Advarsler udløses ved betydelige prisbevægelser. + Indstil prisalarm + Minimumsmodtagelse + Fryse + Optø + Ressourcer + Ressource + Energi + Båndbredde diff --git a/ui/src/main/res/values-de/strings.xml b/ui/src/main/res/values-de/strings.xml index d853aa954..92df9a15b 100644 --- a/ui/src/main/res/values-de/strings.xml +++ b/ui/src/main/res/values-de/strings.xml @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Wir haben %s weggelassen, damit Sie die Abhebungsgebühren bezahlen können. + Bei erheblichen Preisbewegungen werden Warnungen ausgelöst. + Preisalarm einstellen + Mindestbetrag erhalten + Einfrieren + Auftauen + Ressourcen + Ressource + Energie + Bandbreite diff --git a/ui/src/main/res/values-es/strings.xml b/ui/src/main/res/values-es/strings.xml index 648bc962a..8afa973a7 100644 --- a/ui/src/main/res/values-es/strings.xml +++ b/ui/src/main/res/values-es/strings.xml @@ -159,7 +159,7 @@ Redelegate Activando Deactivating - Withdraw + Retirar Paso %d Sign Message Mensaje @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Hemos dejado %s afuera para que puedas pagar las tarifas de retiro. + Las alertas se activan ante movimientos de precios significativos. + Establecer alerta de precio + Mínimo a recibir + Congelar + Descongelar + Recursos + Recurso + Energía + Ancho de banda diff --git a/ui/src/main/res/values-fa/strings.xml b/ui/src/main/res/values-fa/strings.xml index 0778ec213..9f5b3c034 100644 --- a/ui/src/main/res/values-fa/strings.xml +++ b/ui/src/main/res/values-fa/strings.xml @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + ما %s را حذف کرده‌ایم تا بتوانید کارمزد برداشت را پرداخت کنید. + هشدارها در صورت حرکت قابل توجه قیمت فعال می‌شوند. + تنظیم هشدار قیمت + حداقل دریافت + فریز کردن + یخ‌زدایی + منابع + منبع + انرژی + پهنای باند diff --git a/ui/src/main/res/values-fil/strings.xml b/ui/src/main/res/values-fil/strings.xml index 866fad46c..c22147de9 100644 --- a/ui/src/main/res/values-fil/strings.xml +++ b/ui/src/main/res/values-fil/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + Nakareserba No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + Mag-withdraw Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Iniwan namin %s upang mabayaran mo ang mga bayarin sa pag-withdraw. + Nagti-trigger ang mga alerto sa mga makabuluhang galaw ng presyo. + Itakda ang Alerto sa Presyo + Pinakamababang Pagtanggap + I-freeze + I-unfreeze + Mga mapagkukunan + mapagkukunan + Enerhiya + Bandwidth diff --git a/ui/src/main/res/values-fr/strings.xml b/ui/src/main/res/values-fr/strings.xml index 85e3134ff..bdda2755d 100644 --- a/ui/src/main/res/values-fr/strings.xml +++ b/ui/src/main/res/values-fr/strings.xml @@ -159,7 +159,7 @@ Redelegate Activation Deactivating - Withdraw + Retirer Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Nous avons laissé %s de côté pour que vous puissiez payer les frais de retrait. + Les alertes se déclenchent en cas de mouvements de prix importants. + Définir une alerte de prix + Minimum à recevoir + Geler + Dégeler + Ressources + Ressource + Énergie + Bande passante diff --git a/ui/src/main/res/values-hi/strings.xml b/ui/src/main/res/values-hi/strings.xml index 9338ebf0a..309fc4716 100644 --- a/ui/src/main/res/values-hi/strings.xml +++ b/ui/src/main/res/values-hi/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + सुरक्षित No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + निकालना Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + हमने %s को छोड़ दिया है ताकि आप निकासी शुल्क का भुगतान कर सकें। + महत्वपूर्ण मूल्य परिवर्तन पर अलर्ट सक्रिय हो जाते हैं। + मूल्य अलर्ट सेट करें + न्यूनतम प्राप्ति राशि + जमाना + अनफ़्रीज़ + संसाधन + संसाधन + ऊर्जा + बैंडविड्थ diff --git a/ui/src/main/res/values-id/strings.xml b/ui/src/main/res/values-id/strings.xml index a913642dd..ead20df05 100644 --- a/ui/src/main/res/values-id/strings.xml +++ b/ui/src/main/res/values-id/strings.xml @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Kami tidak menyertakan %s agar Anda dapat membayar biaya penarikan. + Peringatan dipicu pada pergerakan harga yang signifikan. + Tetapkan Peringatan Harga + Penerimaan Minimum + Membekukan + Cairkan + Sumber daya + Sumber + Energi + Lebar pita diff --git a/ui/src/main/res/values-it/strings.xml b/ui/src/main/res/values-it/strings.xml index 887e73b51..a1788b061 100644 --- a/ui/src/main/res/values-it/strings.xml +++ b/ui/src/main/res/values-it/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + Prenotato No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + Ritirare Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Abbiamo omesso %s per consentirti di pagare le commissioni di prelievo. + Gli avvisi vengono attivati in caso di movimenti significativi dei prezzi. + Imposta avviso prezzo + Minimo da ricevere + Congelare + Scongelare + Risorse + Risorsa + Energia + Larghezza di banda diff --git a/ui/src/main/res/values-iw/strings.xml b/ui/src/main/res/values-iw/strings.xml index dba27e502..645130768 100644 --- a/ui/src/main/res/values-iw/strings.xml +++ b/ui/src/main/res/values-iw/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + שָׁמוּר No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + לָסֶגֶת Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + השמטנו את %s כדי שתוכל לשלם עבור עמלות משיכה. + התראות מופעלות על תנודות משמעותיות במחיר. + הגדר התראת מחיר + סכום מינימום לקבל + הַקפָּאָה + לְהַפְשִׁיר + אֶמְצָעִי + מַשׁאָב + אֵנֶרְגִיָה + רוחב פס diff --git a/ui/src/main/res/values-ja/strings.xml b/ui/src/main/res/values-ja/strings.xml index 54b345d22..76d5a38c1 100644 --- a/ui/src/main/res/values-ja/strings.xml +++ b/ui/src/main/res/values-ja/strings.xml @@ -472,7 +472,17 @@ デバイス上のこのアプリへのアクセスを保護する ウォレットの上限に達しました ウォレットの上限数( %d )に達しました。既存のウォレットを削除して、新しいウォレットを追加するか作成してください。 - Suspicious Asset - Token may be unsafe or misleading. Proceed only if you fully trust it. - Maximum Amount is %s + 不審資産 + トークンは安全でないか、誤解を招く可能性がある。完全に信頼できる場合のみ手続きを行ってください。 + 最大金額は%s + 出金手数料をお支払いいただけるよう、 %sを省略しました。 + 大幅な価格変動が発生するとアラートが発動します。 + 価格アラートを設定する + 最小受取額 + フリーズ + 解凍 + リソース + リソース + エネルギー + 帯域幅 diff --git a/ui/src/main/res/values-ko/strings.xml b/ui/src/main/res/values-ko/strings.xml index 13c6872cd..a04158e71 100644 --- a/ui/src/main/res/values-ko/strings.xml +++ b/ui/src/main/res/values-ko/strings.xml @@ -159,7 +159,7 @@ Redelegate 활성화 Deactivating - Withdraw + 철회하다 Step %d Sign Message 메시지 @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + 출금 수수료를 지불할 수 있도록 %s 제외했습니다. + 가격이 크게 변동하면 알림이 울립니다. + 가격 설정 알림 + 최소 수령 + 꼭 매달리게 하다 + 녹이다 + 자원 + 의지 + 에너지 + 대역폭 diff --git a/ui/src/main/res/values-ms/strings.xml b/ui/src/main/res/values-ms/strings.xml index f98688216..f3146896d 100644 --- a/ui/src/main/res/values-ms/strings.xml +++ b/ui/src/main/res/values-ms/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + Terpelihara No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + Menarik diri Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Kami telah meninggalkan %s supaya anda boleh membayar yuran pengeluaran. + Makluman mencetuskan pergerakan harga yang ketara. + Tetapkan Makluman Harga + Penerimaan Minimum + bekukan + Nyahbekukan + Sumber + sumber + Tenaga + Lebar jalur diff --git a/ui/src/main/res/values-nl/strings.xml b/ui/src/main/res/values-nl/strings.xml index 88269c826..d75b0d0ca 100644 --- a/ui/src/main/res/values-nl/strings.xml +++ b/ui/src/main/res/values-nl/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + Gereserveerd No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + Terugtrekken Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + We hebben %s weggelaten zodat u de opnamekosten kunt betalen. + Waarschuwingen worden geactiveerd bij aanzienlijke prijsbewegingen. + Prijswaarschuwing instellen + Minimale ontvangst + Bevriezen + Ontdooien + Bronnen + Hulpbron + Energie + Bandbreedte diff --git a/ui/src/main/res/values-pl/strings.xml b/ui/src/main/res/values-pl/strings.xml index bed4dbb77..0a673e483 100644 --- a/ui/src/main/res/values-pl/strings.xml +++ b/ui/src/main/res/values-pl/strings.xml @@ -159,7 +159,7 @@ Redelegate Aktywacja Deactivating - Withdraw + Wycofać Step %d Sign Message Wiadomość @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Pozostawiliśmy %s abyś mógł zapłacić opłaty za wypłatę. + Alerty uruchamiają się w przypadku znacznych wahań cen. + Ustaw alert cenowy + Minimalny odbiór + Zamrażać + Odmrozić + Zasoby + Ratunek + Energia + Przepustowość łącza diff --git a/ui/src/main/res/values-pt-rBR/strings.xml b/ui/src/main/res/values-pt-rBR/strings.xml index 76669f02e..21bc0d44a 100644 --- a/ui/src/main/res/values-pt-rBR/strings.xml +++ b/ui/src/main/res/values-pt-rBR/strings.xml @@ -159,7 +159,7 @@ Redelegate Ativando Deactivating - Withdraw + Retirar Step %d Sign Message Mensagem @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Deixamos %s de fora para que você possa pagar as taxas de retirada. + Alertas são acionados em movimentos significativos de preços. + Definir alerta de preço + Recepção mínima + Congelar + Descongelar + Recursos + Recurso + Energia + Largura de banda diff --git a/ui/src/main/res/values-ro/strings.xml b/ui/src/main/res/values-ro/strings.xml index fff3e32a8..4cd720d4e 100644 --- a/ui/src/main/res/values-ro/strings.xml +++ b/ui/src/main/res/values-ro/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + Rezervat No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + Retrage Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Am omis %s pentru a putea plăti comisioanele de retragere. + Alertele se declanșează la mișcări semnificative ale prețurilor. + Setați alertă de preț + Primire minimă + Îngheţa + Dezghețare + Resurse + Resursă + Energie + Lățime de bandă diff --git a/ui/src/main/res/values-ru/strings.xml b/ui/src/main/res/values-ru/strings.xml index 1b6b53171..7eb2dd878 100644 --- a/ui/src/main/res/values-ru/strings.xml +++ b/ui/src/main/res/values-ru/strings.xml @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Мы оставили %s, чтобы вы могли оплатить комиссию за вывод средств. + Оповещения срабатывают при значительных изменениях цены. + Установить оповещение о цене + Минимум к получению + Заморозить + Разморозить + Ресурсы + Ресурс + Энергия + Пропускная способность diff --git a/ui/src/main/res/values-sw/strings.xml b/ui/src/main/res/values-sw/strings.xml index 2dd0529f1..6c89e0307 100644 --- a/ui/src/main/res/values-sw/strings.xml +++ b/ui/src/main/res/values-sw/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + Imehifadhiwa No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + Ondoa Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Tumeacha %s nje ili uweze kulipia ada za kujiondoa. + Arifa huanzisha hatua muhimu za bei. + Weka Arifa ya Bei + Kiasi cha chini cha kupokea + Kuganda + Ondoa kuganda + Rasilimali + Rasilimali + Nishati + Bandwidth diff --git a/ui/src/main/res/values-th/strings.xml b/ui/src/main/res/values-th/strings.xml index 6c7a24c95..ec1c8d0a7 100644 --- a/ui/src/main/res/values-th/strings.xml +++ b/ui/src/main/res/values-th/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + ที่สงวนไว้ No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + ถอน Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + เราได้เว้น %s ไว้เพื่อให้คุณสามารถชำระค่าธรรมเนียมการถอนเงินได้ + การแจ้งเตือนจะเกิดขึ้นเมื่อราคามีการเปลี่ยนแปลงอย่างมีนัยสำคัญ + ตั้งค่าการแจ้งเตือนราคา + รับขั้นต่ำ + แช่แข็ง + ละลายน้ำแข็ง + ทรัพยากร + ทรัพยากร + พลังงาน + แบนด์วิดท์ diff --git a/ui/src/main/res/values-tr/strings.xml b/ui/src/main/res/values-tr/strings.xml index 7e30834aa..c3d167804 100644 --- a/ui/src/main/res/values-tr/strings.xml +++ b/ui/src/main/res/values-tr/strings.xml @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Çekim ücretlerini ödeyebilmeniz için %s dışarıda bıraktık. + Önemli fiyat hareketlerinde uyarılar tetiklenir. + Fiyat Uyarısı Ayarla + Alınacak minimum + Donmak + Çözmek + Kaynaklar + Kaynak + Enerji + Bant genişliği diff --git a/ui/src/main/res/values-uk/strings.xml b/ui/src/main/res/values-uk/strings.xml index c7f3573a3..d2648d387 100644 --- a/ui/src/main/res/values-uk/strings.xml +++ b/ui/src/main/res/values-uk/strings.xml @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Ми залишили %s, щоб ви могли сплатити комісію за зняття коштів. + Сповіщення спрацьовують у разі значних змін цін. + Встановити сповіщення про ціну + Мінімум до отримання + Заморозити + Розморозити + Ресурси + Ресурс + Енергія + Пропускна здатність diff --git a/ui/src/main/res/values-ur/strings.xml b/ui/src/main/res/values-ur/strings.xml index e6c19dbcb..8549f51f0 100644 --- a/ui/src/main/res/values-ur/strings.xml +++ b/ui/src/main/res/values-ur/strings.xml @@ -149,7 +149,7 @@ Validator Validators APR %s - Reserved + محفوظ No memo required No destination tag required Available In @@ -159,7 +159,7 @@ Redelegate Activating Deactivating - Withdraw + واپس لینا Step %d Sign Message Message @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + ہم نے %s چھوڑ دیا ہے تاکہ آپ واپسی کی فیس ادا کر سکیں۔ + انتباہات اہم قیمت کی چالوں پر متحرک ہوتے ہیں۔ + قیمت کا الرٹ سیٹ کریں۔ + کم از کم وصولی + جمنا + انجماد + وسائل + وسیلہ + توانائی + بینڈوتھ diff --git a/ui/src/main/res/values-vi/strings.xml b/ui/src/main/res/values-vi/strings.xml index bb3da6425..1d2d2d2ed 100644 --- a/ui/src/main/res/values-vi/strings.xml +++ b/ui/src/main/res/values-vi/strings.xml @@ -159,7 +159,7 @@ Redelegate Kích hoạt Deactivating - Withdraw + Rút Step %d Sign Message Tin nhắn @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + Chúng tôi đã bỏ %s ra để bạn có thể trả phí rút tiền. + Cảnh báo sẽ được kích hoạt khi giá biến động đáng kể. + Đặt cảnh báo giá + Nhận tối thiểu + Đông cứng + Giải đông + Tài nguyên + Tài nguyên + Năng lượng + Băng thông diff --git a/ui/src/main/res/values-zh-rCN/strings.xml b/ui/src/main/res/values-zh-rCN/strings.xml index cc64fbb5a..64dfcc92d 100644 --- a/ui/src/main/res/values-zh-rCN/strings.xml +++ b/ui/src/main/res/values-zh-rCN/strings.xml @@ -447,7 +447,7 @@ 提现 资金费用 资金费用是交易者之间的定期支付,用于使永续合约价格接近标的资产现货价格。正资金费用表示多头支付空头,负资金费用表示空头支付多头。 - 资金費率 + 资金费率 资金费率决定持有永续仓位的成本。它按小时计算,有助于维持永续合约与标的资产现货价格之间的价格平衡。 强平价格 强平价格是当市场价格达到该水平时,您的仓位将被自动平仓以防止进一步亏损的价格。当市场价触及此价位,仓位被强制平仓,保证金将被扣除。 @@ -474,5 +474,15 @@ 您已达到允许的最大钱包数量( %d )。请移除现有钱包以添加或创建新钱包。 可疑资产 代币可能不安全或具有误导性。请仅在完全信任的情况下继续操作。 - Maximum Amount is %s + 最高金额为%s + 我们省略了%s以便您可以支付提款费用。 + 当价格发生重大变动时,警报就会触发。 + 设置价格提醒 + 最少接收 + 冻结 + 解冻 + 资源 + 资源 + 活力 + 带宽 diff --git a/ui/src/main/res/values-zh-rTW/strings.xml b/ui/src/main/res/values-zh-rTW/strings.xml index 9034025d5..6830ad0f4 100644 --- a/ui/src/main/res/values-zh-rTW/strings.xml +++ b/ui/src/main/res/values-zh-rTW/strings.xml @@ -474,5 +474,15 @@ 您已達到允許的最大錢包數量( %d )。請移除現有錢包以新增或建立新錢包。 可疑資產 代幣可能不安全或具有誤導性。請僅在完全信任的情況下繼續操作。 - Maximum Amount is %s + 最高金額為 %s + 我們省略了%s以便您可以支付提款費用。 + 當價格發生重大變動時,警報就會觸發。 + 設定價格提醒 + 最少接收 + 凍結 + 解凍 + 資源 + 資源 + 活力 + 頻寬 diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index ebfe7614c..fc0b57b57 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -475,4 +475,14 @@ Suspicious Asset Token may be unsafe or misleading. Proceed only if you fully trust it. Maximum Amount is %s + We\'ve left %s out so you can pay for withdrawal fees. + Alerts trigger on significant price moves. + Set Price Alert + Minimum Receive + Freeze + Unfreeze + Resources + Resource + Energy + Bandwidth From 1df098d09898019946e49a3a6f8118ce7fe84475 Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Fri, 19 Sep 2025 21:22:59 -0700 Subject: [PATCH 13/16] Finish evm --- .../clients/ethereum/EvmChainData.kt | 8 + .../clients/ethereum/EvmChainExt.kt | 50 +++---- .../clients/ethereum/EvmSignClient.kt | 7 +- .../blockchain/clients/ethereum/StakeHub.kt | 141 ------------------ .../services/SignerPreloaderProxy.kt | 2 +- .../com/wallet/core/primitives/StakeType.kt | 2 +- 6 files changed, 35 insertions(+), 175 deletions(-) delete mode 100644 blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/StakeHub.kt diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainData.kt index 6a15c80b7..b6ee803f7 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainData.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainData.kt @@ -1,12 +1,14 @@ package com.gemwallet.android.blockchain.clients.ethereum import com.gemwallet.android.model.ChainSignData +import com.wallet.core.primitives.StakeData import uniffi.gemstone.GemTransactionLoadMetadata import java.math.BigInteger data class EvmChainData( val chainId: Int, val nonce: BigInteger, + val stakeData: StakeData?, ) : ChainSignData @@ -14,5 +16,11 @@ fun GemTransactionLoadMetadata.Evm.toChainData(): EvmChainData { return EvmChainData( chainId = chainId.toInt(), nonce = BigInteger.valueOf(nonce.toLong()), + stakeData = stakeData?.let { + StakeData( + data = it.data, + to = it.to + ) + } ) } \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainExt.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainExt.kt index 93593ef92..5fd344822 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainExt.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainExt.kt @@ -3,13 +3,9 @@ package com.gemwallet.android.blockchain.clients.ethereum import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy import com.gemwallet.android.ext.type import com.gemwallet.android.math.decodeHex -import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.ConfirmParams import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.AssetSubtype import com.wallet.core.primitives.EVMChain -import com.wallet.core.primitives.NFTType -import uniffi.gemstone.Config import wallet.core.jni.AnyAddress import wallet.core.jni.EthereumAbi import wallet.core.jni.EthereumAbiFunction @@ -42,28 +38,24 @@ fun EVMChain.Companion.getDestinationAddress( } } -fun EVMChain.isOpStack(): Boolean { - return Config().getEvmChainConfig(string).isOpstack -} - -fun EVMChain.Companion.encodeNFT(params: ConfirmParams.NftParams): String { - return when (params.nftAsset.tokenType) { - NFTType.ERC721 -> { - val function = EthereumAbiFunction("safeTransferFrom") - function.addParamAddress(params.from.address.decodeHex(), false) - function.addParamAddress(params.destination.address.decodeHex(), false) - function.addParamUInt256(params.nftAsset.tokenId.toBigInteger().abs().toByteArray(), false) - EthereumAbi.encode(function) - } - NFTType.ERC1155 -> { - val function = EthereumAbiFunction("safeTransferFrom") - function.addParamAddress(params.from.address.decodeHex(), false) - function.addParamAddress(params.destination.address.decodeHex(), false) - function.addParamUInt256(params.nftAsset.tokenId.toBigInteger().abs().toByteArray(), false) - function.addParamUInt256(BigInteger.ONE.toByteArray(), false) - function.addParamBytes(byteArrayOf(), false) - EthereumAbi.encode(function) - } - else -> throw IllegalArgumentException("Not supported") - }.toHexString() -} \ No newline at end of file +//fun EVMChain.Companion.encodeNFT(params: ConfirmParams.NftParams): String { +// return when (params.nftAsset.tokenType) { +// NFTType.ERC721 -> { +// val function = EthereumAbiFunction("safeTransferFrom") +// function.addParamAddress(params.from.address.decodeHex(), false) +// function.addParamAddress(params.destination.address.decodeHex(), false) +// function.addParamUInt256(params.nftAsset.tokenId.toBigInteger().abs().toByteArray(), false) +// EthereumAbi.encode(function) +// } +// NFTType.ERC1155 -> { +// val function = EthereumAbiFunction("safeTransferFrom") +// function.addParamAddress(params.from.address.decodeHex(), false) +// function.addParamAddress(params.destination.address.decodeHex(), false) +// function.addParamUInt256(params.nftAsset.tokenId.toBigInteger().abs().toByteArray(), false) +// function.addParamUInt256(BigInteger.ONE.toByteArray(), false) +// function.addParamBytes(byteArrayOf(), false) +// EthereumAbi.encode(function) +// } +// else -> throw IllegalArgumentException("Not supported") +// }.toHexString() +//} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt index de8b0bf37..25378779e 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmSignClient.kt @@ -259,12 +259,13 @@ class EvmSignClient( throw Exception("Doesn't support") } val meta = chainData as EvmChainData + val toAddress = meta.stakeData?.to ?: throw java.lang.IllegalArgumentException("No stake data") + val stakeData = meta.stakeData.data?.decodeHex() ?: throw java.lang.IllegalArgumentException("No stake data") val fee = fee as GasFee val valueData = when (params) { is ConfirmParams.Stake.DelegateParams -> finalAmount.toByteArray() else -> BigInteger.ZERO.toByteArray() } - val callData = StakeHub.encodeStake(params) val input = Ethereum.SigningInput.newBuilder().apply { this.txMode = Ethereum.TransactionMode.Enveloped this.maxFeePerGas = ByteString.copyFrom(fee.maxGasPrice.toByteArray()) @@ -272,12 +273,12 @@ class EvmSignClient( this.gasLimit = ByteString.copyFrom(fee.limit.toByteArray()) this.chainId = ByteString.copyFrom(meta.chainId.toBigInteger().toByteArray()) this.nonce = ByteString.copyFrom(meta.nonce.toByteArray()) - this.toAddress = StakeHub.address + this.toAddress = toAddress this.privateKey = ByteString.copyFrom(privateKey) this.transaction = Ethereum.Transaction.newBuilder().apply { contractGeneric = ContractGeneric.newBuilder().apply { amount = ByteString.copyFrom(valueData) - data = ByteString.copyFrom(callData.decodeHex()) + data = ByteString.copyFrom(stakeData) }.build() }.build() }.build() diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/StakeHub.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/StakeHub.kt deleted file mode 100644 index 13c37a184..000000000 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/StakeHub.kt +++ /dev/null @@ -1,141 +0,0 @@ -package com.gemwallet.android.blockchain.clients.ethereum - -import com.gemwallet.android.ext.asset -import com.gemwallet.android.math.decodeHex -import com.gemwallet.android.math.toHexString -import com.gemwallet.android.model.ConfirmParams -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.DelegationBase -import com.wallet.core.primitives.DelegationState -import com.wallet.core.primitives.DelegationValidator -//import uniffi.gemstone.BscDelegation -//import uniffi.gemstone.BscDelegationStatus - -object StakeHub { - val offset: UShort = (0).toUShort() - const val address = "0x0000000000000000000000000000000000002002" -// const val reader = "0x830295c0abe7358f7e24bc38408095621474280b" -// -// fun encodeMaxElectedValidators(): String { -// // cast calldata "maxElectedValidators()" -// return "0xc473318f" -// } -// - fun encodeStake(params: ConfirmParams): String { - return "" -// return when (params) { -// is ConfirmParams.Stake.DelegateParams -> encodeDelegateCall(params.validatorId, false) -// -// is ConfirmParams.Stake.RedelegateParams -> encodeRedelegateCall(params, false) -// is ConfirmParams.Stake.UndelegateParams -> encodeUndelegateCall(params) -// is ConfirmParams.Stake.WithdrawParams -> encodeClaim(params, (0).toULong()) -// else -> throw IllegalArgumentException() -// }.toHexString() - } -// -// fun encodeDelegateCall(validator: String, delegateVote: Boolean): ByteArray { -// return uniffi.gemstone.bscEncodeDelegateCall(validator, delegateVote) -// } -// -// fun encodeValidatorsCall(offset: Int, limit: Int): String { -// return uniffi.gemstone.bscEncodeValidatorsCall(offset.toUShort(), limit.toUShort()) -// .toHexString() -// } -// -// fun decodeValidatorsReturn(hexData: String): List { -// return uniffi.gemstone.bscDecodeValidatorsReturn(hexData.decodeHex()).map { -// DelegationValidator( -// chain = Chain.SmartChain, -// id = it.operatorAddress, -// name = it.moniker, -// isActive = !it.jailed, -// commision = it.commission.toDouble() / 100, -// apr = it.apy.toDouble() / 100, -// ) -// } -// } -// -// fun encodeDelegationsCall(address: String, limit: Int): String { -// return uniffi.gemstone.bscEncodeDelegationsCall(address, offset, limit.toUShort()) -// .toHexString() -// } -// -// fun decodeDelegationsResult(data: String): List { -// return uniffi.gemstone.bscDecodeDelegationsReturn(data.decodeHex()).map { it.into() } -// } -// -// fun encodeUndelegationsCall(address: String, limit: Int): String { -// return uniffi.gemstone.bscEncodeUndelegationsCall(address, offset, limit.toUShort()) -// .toHexString() -// } -// -// fun decodeUnelegationsResult(data: String): List { -// return uniffi.gemstone.bscDecodeUndelegationsReturn(data.decodeHex()).map { it.into() } -// } -// -// fun encodeUndelegateCall(params: ConfirmParams.Stake.UndelegateParams): ByteArray { -// val amountShare = -// params.amount * params.share!!.toBigInteger() / params.balance!!.toBigInteger() -// return uniffi.gemstone.bscEncodeUndelegateCall( -// operatorAddress = params.validatorId, -// shares = amountShare.toString() -// ) -// } -// -// fun encodeRedelegateCall( -// params: ConfirmParams.Stake.RedelegateParams, -// votePower: Boolean -// ): ByteArray { -// val amountShare = -// params.amount * params.share!!.toBigInteger() / params.balance!!.toBigInteger() -// return uniffi.gemstone.bscEncodeRedelegateCall( -// srcValidator = params.srcValidatorId, -// dstValidator = params.dstValidatorId, -// shares = amountShare.toString(), -// delegateVotePower = votePower, -// ) -// } -// -// fun encodeClaim( -// params: ConfirmParams.Stake.WithdrawParams, -// requestNumber: ULong -// ): ByteArray { -// return uniffi.gemstone.bscEncodeClaimCall( -// operatorAddress = params.validatorId, -// requestNumber = requestNumber -// ) -// } -//} -// -//fun BscDelegation.into(): DelegationBase { -// val completion = when (status) { -// BscDelegationStatus.ACTIVE -> null -// BscDelegationStatus.UNDELEGATING -> unlockTime?.toLong() -// }?.toLong() -// val state = when (status) { -// BscDelegationStatus.ACTIVE -> DelegationState.Active -// BscDelegationStatus.UNDELEGATING -> { -// if (completion == null) { -// DelegationState.Undelegating -// } else if (System.currentTimeMillis() <= completion * 1000) { -// DelegationState.Undelegating -// } else { -// DelegationState.AwaitingWithdrawal -// } -// } -// } -// val delegationId = when (status) { -// BscDelegationStatus.ACTIVE -> "" -// BscDelegationStatus.UNDELEGATING -> "$validatorAddress--${unlockTime ?: 0}" -// } -// return DelegationBase( -// assetId = Chain.SmartChain.asset().id, -// state = state, -// balance = amount, -// shares = shares, -// rewards = "0", -// completionDate = completion, -// delegationId = delegationId, -// validatorId = validatorAddress, -// ) -} \ No newline at end of file diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt index a001c91bd..2b646f5ca 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/SignerPreloaderProxy.kt @@ -138,7 +138,7 @@ class SignerPreloaderProxy( is ConfirmParams.SwapParams -> GemTransactionInputType.Swap( fromAsset = params.fromAsset.toGem(), toAsset = params.toAsset.toGem(), - swapData = params.toGem() + swapData = params.toGem(), ) is ConfirmParams.TokenApprovalParams -> GemTransactionInputType.TokenApprove( gemAsset, diff --git a/gemcore/src/main/kotlin/com/wallet/core/primitives/StakeType.kt b/gemcore/src/main/kotlin/com/wallet/core/primitives/StakeType.kt index a193ad0af..6e3d706bd 100644 --- a/gemcore/src/main/kotlin/com/wallet/core/primitives/StakeType.kt +++ b/gemcore/src/main/kotlin/com/wallet/core/primitives/StakeType.kt @@ -38,7 +38,7 @@ data class RedelegateData ( @Serializable data class StakeData ( val data: String? = null, - val to: String? = null + val to: String? = null, ) @Serializable From bb65627fcf352d1a8eac17f6b3300e15ae067b05 Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Fri, 19 Sep 2025 21:46:03 -0700 Subject: [PATCH 14/16] Restore NFT encode --- .../clients/ethereum/EvmChainExt.kt | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainExt.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainExt.kt index 5fd344822..1a46bf30f 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainExt.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/ethereum/EvmChainExt.kt @@ -3,9 +3,11 @@ package com.gemwallet.android.blockchain.clients.ethereum import com.gemwallet.android.blockchain.operators.walletcore.WCChainTypeProxy import com.gemwallet.android.ext.type import com.gemwallet.android.math.decodeHex +import com.gemwallet.android.model.ConfirmParams import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.AssetSubtype import com.wallet.core.primitives.EVMChain +import com.wallet.core.primitives.NFTType import wallet.core.jni.AnyAddress import wallet.core.jni.EthereumAbi import wallet.core.jni.EthereumAbiFunction @@ -38,24 +40,24 @@ fun EVMChain.Companion.getDestinationAddress( } } -//fun EVMChain.Companion.encodeNFT(params: ConfirmParams.NftParams): String { -// return when (params.nftAsset.tokenType) { -// NFTType.ERC721 -> { -// val function = EthereumAbiFunction("safeTransferFrom") -// function.addParamAddress(params.from.address.decodeHex(), false) -// function.addParamAddress(params.destination.address.decodeHex(), false) -// function.addParamUInt256(params.nftAsset.tokenId.toBigInteger().abs().toByteArray(), false) -// EthereumAbi.encode(function) -// } -// NFTType.ERC1155 -> { -// val function = EthereumAbiFunction("safeTransferFrom") -// function.addParamAddress(params.from.address.decodeHex(), false) -// function.addParamAddress(params.destination.address.decodeHex(), false) -// function.addParamUInt256(params.nftAsset.tokenId.toBigInteger().abs().toByteArray(), false) -// function.addParamUInt256(BigInteger.ONE.toByteArray(), false) -// function.addParamBytes(byteArrayOf(), false) -// EthereumAbi.encode(function) -// } -// else -> throw IllegalArgumentException("Not supported") -// }.toHexString() -//} \ No newline at end of file +fun EVMChain.Companion.encodeNFT(params: ConfirmParams.NftParams): String { + return when (params.nftAsset.tokenType) { + NFTType.ERC721 -> { + val function = EthereumAbiFunction("safeTransferFrom") + function.addParamAddress(params.from.address.decodeHex(), false) + function.addParamAddress(params.destination.address.decodeHex(), false) + function.addParamUInt256(params.nftAsset.tokenId.toBigInteger().abs().toByteArray(), false) + EthereumAbi.encode(function) + } + NFTType.ERC1155 -> { + val function = EthereumAbiFunction("safeTransferFrom") + function.addParamAddress(params.from.address.decodeHex(), false) + function.addParamAddress(params.destination.address.decodeHex(), false) + function.addParamUInt256(params.nftAsset.tokenId.toBigInteger().abs().toByteArray(), false) + function.addParamUInt256(BigInteger.ONE.toByteArray(), false) + function.addParamBytes(byteArrayOf(), false) + EthereumAbi.encode(function) + } + else -> throw IllegalArgumentException("Not supported") + }.toHexString() +} \ No newline at end of file From a68b9f6e2f42f0bff91190a3c2868aea610914ad Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Fri, 19 Sep 2025 21:56:41 -0700 Subject: [PATCH 15/16] Fix xrp and stellar --- .../android/blockchain/clients/stellar/StellarChainData.kt | 6 +----- .../android/blockchain/clients/stellar/StellarSignClient.kt | 3 ++- .../android/blockchain/clients/xrp/XrpChainData.kt | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarChainData.kt index f672fb6e4..82eebfdfe 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarChainData.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarChainData.kt @@ -6,11 +6,7 @@ import uniffi.gemstone.GemTransactionLoadMetadata data class StellarChainData( val sequence: ULong, val isDestinationAddressExist: Boolean, -) : ChainSignData { - companion object { - const val tokenAccountCreation = "tokenAccountCreation" - } -} +) : ChainSignData fun GemTransactionLoadMetadata.Stellar.toChainData(): StellarChainData { return StellarChainData( diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignClient.kt index de233f94c..5f9270325 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/stellar/StellarSignClient.kt @@ -7,6 +7,7 @@ import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain +import uniffi.gemstone.GemFeeOption import wallet.core.java.AnySigner import wallet.core.jni.StellarPassphrase import wallet.core.jni.proto.Stellar @@ -35,7 +36,7 @@ class StellarSignClient( this.text = params.memo()!! }.build() } - if (fee.options.contains(StellarChainData.tokenAccountCreation)) { + if (fee.options.contains(GemFeeOption.TOKEN_ACCOUNT_CREATION.name)) { this.opCreateAccount = Stellar.OperationCreateAccount.newBuilder().apply { this.destination = params.destination().address this.amount = finalAmount.toLong() diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpChainData.kt index 472961d7f..998a79eb6 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpChainData.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/xrp/XrpChainData.kt @@ -11,6 +11,6 @@ data class XrpChainData( fun GemTransactionLoadMetadata.Xrp.toChainData(): XrpChainData { return XrpChainData( sequence = sequence.toInt(), - blockNumber = sequence.toInt(), + blockNumber = blockNumber.toInt(), ) } \ No newline at end of file From 8917d7b2c456b32a302aec2e8449082fe506da53 Mon Sep 17 00:00:00 2001 From: furenster <123000419+furenster@users.noreply.github.com> Date: Mon, 22 Sep 2025 18:03:55 -0700 Subject: [PATCH 16/16] Clean tests --- .../clients/algorand/TestAlgorandSigner.kt | 1 - .../clients/bitcoin/TestBitcoinSigner.kt | 2 - .../clients/cardano/TestCardanoSigner.kt | 1 - .../clients/polkadot/TestPolkadotSigner.kt | 1 - .../blockchain/clients/xrp/TestXrpSigner.kt | 1 - .../android/blockchain/clients/SignClient.kt | 1 - .../polkadot/PolkadotGatewayEstimateFee.kt | 6 - .../clients/polkadot/PolkadotSignClient.kt | 2 - .../blockchain/clients/sui/SuiChainData.kt | 1 - .../blockchain/clients/tron/TronRpcClient.kt | 1 - .../blockchain/services/mapper/Asset.kt | 1 - .../android/blockchain/clients/aptos/Data.kt | 16 -- .../clients/aptos/TestAptosFeeCalculator.kt | 57 ------ .../clients/aptos/TestAptosSignerPreloader.kt | 149 -------------- .../clients/cosmos/TestCosmosPreload.kt | 188 ------------------ 15 files changed, 428 deletions(-) delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/Data.kt delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosFeeCalculator.kt delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt delete mode 100644 blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt index eb64b974d..7e6c8cff4 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/algorand/TestAlgorandSigner.kt @@ -3,7 +3,6 @@ package com.gemwallet.android.blockchain.clients.algorand import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset -import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.DestinationAddress import com.gemwallet.android.model.Fee diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt index 918e8f06e..1ace606fa 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/bitcoin/TestBitcoinSigner.kt @@ -4,11 +4,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset -import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.DestinationAddress import com.gemwallet.android.model.GasFee -import com.wallet.core.blockchain.bitcoin.BitcoinUTXO import com.wallet.core.primitives.Account import com.wallet.core.primitives.AssetId import com.wallet.core.primitives.Chain diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt index 2bcfe0084..8119071e8 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/cardano/TestCardanoSigner.kt @@ -3,7 +3,6 @@ package com.gemwallet.android.blockchain.clients.cardano import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset -import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.DestinationAddress import com.gemwallet.android.model.Fee diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt index a49e2ebb4..5c9a4faad 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/polkadot/TestPolkadotSigner.kt @@ -3,7 +3,6 @@ package com.gemwallet.android.blockchain.clients.polkadot import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset -import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.DestinationAddress import com.gemwallet.android.model.Fee diff --git a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt index 50c45ffa0..b5f4b1eb8 100644 --- a/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt +++ b/blockchain/src/androidTest/kotlin/com/gemwallet/android/blockchain/clients/xrp/TestXrpSigner.kt @@ -3,7 +3,6 @@ package com.gemwallet.android.blockchain.clients.xrp import com.gemwallet.android.blockchain.includeLibs import com.gemwallet.android.blockchain.testPhrase import com.gemwallet.android.ext.asset -import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.DestinationAddress import com.gemwallet.android.model.Fee diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClient.kt index 3d1634641..c3ed56192 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/SignClient.kt @@ -4,7 +4,6 @@ import com.gemwallet.android.model.ChainSignData import com.gemwallet.android.model.ConfirmParams import com.gemwallet.android.model.Fee import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority import java.math.BigInteger interface SignClient : BlockchainClient { diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt index 98e0d9886..762823397 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotGatewayEstimateFee.kt @@ -1,14 +1,9 @@ package com.gemwallet.android.blockchain.clients.polkadot -import com.gemwallet.android.blockchain.services.mapper.toUtxo import com.gemwallet.android.math.append0x -import com.gemwallet.android.math.decodeHex import com.gemwallet.android.math.toHexString import com.google.protobuf.ByteString -import com.wallet.core.blockchain.polkadot.PolkadotTransactionPayload -import com.wallet.core.primitives.UTXO import uniffi.gemstone.Chain -import uniffi.gemstone.GemFeeOptions import uniffi.gemstone.GemGatewayEstimateFee import uniffi.gemstone.GemTransactionLoadFee import uniffi.gemstone.GemTransactionLoadInput @@ -16,7 +11,6 @@ import uniffi.gemstone.GemTransactionLoadMetadata import wallet.core.java.AnySigner import wallet.core.jni.CoinType import wallet.core.jni.PrivateKey -import wallet.core.jni.proto.Cardano import wallet.core.jni.proto.Polkadot import java.math.BigInteger diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt index bb648fde1..df902c3df 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/polkadot/PolkadotSignClient.kt @@ -1,7 +1,6 @@ package com.gemwallet.android.blockchain.clients.polkadot import com.gemwallet.android.blockchain.clients.SignClient -import com.gemwallet.android.math.append0x import com.gemwallet.android.math.decodeHex import com.gemwallet.android.math.toHexString import com.gemwallet.android.model.ChainSignData @@ -11,7 +10,6 @@ import com.google.protobuf.ByteString import com.wallet.core.primitives.Chain import wallet.core.java.AnySigner import wallet.core.jni.CoinType -import wallet.core.jni.PrivateKey import wallet.core.jni.proto.Polkadot import java.math.BigInteger diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiChainData.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiChainData.kt index 3348ec4ae..67119a30a 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiChainData.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/sui/SuiChainData.kt @@ -1,6 +1,5 @@ package com.gemwallet.android.blockchain.clients.sui -import com.gemwallet.android.blockchain.clients.aptos.AptosChainData import com.gemwallet.android.model.ChainSignData import uniffi.gemstone.GemTransactionLoadMetadata diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronRpcClient.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronRpcClient.kt index 85fb47b0c..8035d9c2d 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronRpcClient.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/clients/tron/TronRpcClient.kt @@ -9,7 +9,6 @@ import com.wallet.core.blockchain.tron.TronAccountUsage import com.wallet.core.blockchain.tron.TronBlock import com.wallet.core.blockchain.tron.TronChainParameters import com.wallet.core.blockchain.tron.TronSmartContractResult -import com.wallet.core.blockchain.tron.TronTransactionReceipt import com.wallet.core.primitives.Chain import retrofit2.http.Body import retrofit2.http.GET diff --git a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt index b2eb0e03e..9d7e9db5e 100644 --- a/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt +++ b/blockchain/src/main/kotlin/com/gemwallet/android/blockchain/services/mapper/Asset.kt @@ -2,7 +2,6 @@ package com.gemwallet.android.blockchain.services.mapper import com.gemwallet.android.ext.toAssetId import com.gemwallet.android.ext.toIdentifier -import com.wallet.core.blockchain.bitcoin.BitcoinUTXO import com.wallet.core.primitives.Asset import com.wallet.core.primitives.AssetType import com.wallet.core.primitives.UTXO diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/Data.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/Data.kt deleted file mode 100644 index 28d099d92..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/Data.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.aptos.models.AptosAccount -import com.wallet.core.blockchain.aptos.AptosGasFee - -internal val aptosAccountResponse = AptosAccount( - sequence_number = "8", - message = null, - error_code = null, -) - -internal val aptosFeeResponse = AptosGasFee( - gas_estimate = 100, - prioritized_gas_estimate = 150, - deprioritized_gas_estimate = 250, -) \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosFeeCalculator.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosFeeCalculator.kt deleted file mode 100644 index d0150d688..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosFeeCalculator.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.aptos.models.AptosAccount -import com.gemwallet.android.ext.asset -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.DestinationAddress -import com.wallet.core.blockchain.aptos.AptosGasFee -import com.wallet.core.blockchain.aptos.AptosTransaction -import com.wallet.core.blockchain.aptos.AptosTransactionSimulation -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertTrue -import kotlinx.coroutines.runBlocking -import org.junit.Test -import java.math.BigInteger - -class TestAptosFeeCalculator { - @Test - fun testAptosFeeAccountError() { - val preloader = AptosSignerPreloader( - chain = Chain.Aptos, - accountsService = object : AptosAccountsService { - override suspend fun accounts(address: String): Result { - return Result.success(aptosAccountResponse.copy(sequence_number = null, error_code = null, message = "Error message")) - } - - }, - feeService = object : AptosFeeService { - override suspend fun feePrice(): Result { - return Result.success(aptosFeeResponse) - } - - override suspend fun simulate(data: AptosTransactionSimulation): Result> { - return Result.success(listOf(AptosTransaction(true, "69", "0"))) - } - } - ) - try { - runBlocking { - preloader.preloadNativeTransfer( - params = ConfirmParams.TransferParams.Native( - asset = Chain.Aptos.asset(), - from = Account(Chain.Aptos, "0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f", ""), - amount = BigInteger.valueOf(10_000_000_000), - destination = DestinationAddress("0xd7257c62806cea85fc8eaf947377b672fe062b81e6c0b19b6d8a3f408e59cf8c"), - isMaxAmount = false - ) - ) - } - assertTrue(false) - } catch (err: Throwable) { - assertEquals(null, err.message) - } - } -} \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt deleted file mode 100644 index 858b5b08f..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/aptos/TestAptosSignerPreloader.kt +++ /dev/null @@ -1,149 +0,0 @@ -package com.gemwallet.android.blockchain.clients.aptos - -import com.gemwallet.android.blockchain.clients.aptos.models.AptosAccount -import com.gemwallet.android.ext.asset -import com.gemwallet.android.ext.toIdentifier -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.DestinationAddress -import com.gemwallet.android.model.GasFee -import com.wallet.core.blockchain.aptos.AptosGasFee -import com.wallet.core.blockchain.aptos.AptosTransaction -import com.wallet.core.blockchain.aptos.AptosTransactionSimulation -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import junit.framework.TestCase.assertEquals -import junit.framework.TestCase.assertTrue -import kotlinx.coroutines.runBlocking -import org.junit.Test -import java.math.BigInteger - -class TestAptosSignerPreloader { - - @Test - fun testAptosPreload() { - var serviceAddressParam = mutableListOf() - val preloader = AptosSignerPreloader( - chain = Chain.Aptos, - accountsService = object : AptosAccountsService { - override suspend fun accounts(address: String): Result { - serviceAddressParam.add(address) - return Result.success(aptosAccountResponse) - } - - }, - feeService = object : AptosFeeService { - override suspend fun feePrice(): Result { - return Result.success(aptosFeeResponse) - } - - override suspend fun simulate(data: AptosTransactionSimulation): Result> { - return Result.success(listOf(AptosTransaction(true, "9", "0"))) - } - } - ) - val result = runBlocking { - preloader.preloadNativeTransfer( - params = ConfirmParams.TransferParams.Native( - asset = Chain.Aptos.asset(), - from = Account(Chain.Aptos, "0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f", ""), - amount = BigInteger.valueOf(10_000_000_000), - destination = DestinationAddress("0xd7257c62806cea85fc8eaf947377b672fe062b81e6c0b19b6d8a3f408e59cf8c"), - isMaxAmount = false - ) - ) - } - assertEquals("0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f", serviceAddressParam[0]) -// assertEquals("0xd7257c62806cea85fc8eaf947377b672fe062b81e6c0b19b6d8a3f408e59cf8c", serviceAddressParam[1]) - assertEquals(BigInteger.valueOf(10_000_000_000), result.input.amount) - assertEquals("0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f", result.input.from.address) - assertEquals(AssetId(Chain.Aptos).toIdentifier(), result.input.assetId.toIdentifier()) - assertEquals(false, result.input.isMax()) - assertEquals("0xd7257c62806cea85fc8eaf947377b672fe062b81e6c0b19b6d8a3f408e59cf8c", result.input.destination()?.address) - assertEquals(null, result.input.memo()) - assertEquals(BigInteger.valueOf(1350L), result.chainData.fee().amount) - assertEquals(BigInteger.valueOf(150L), (result.chainData.fee() as GasFee).maxGasPrice) - assertEquals(BigInteger.valueOf(9), (result.chainData.fee() as GasFee).limit) - assertEquals(AssetId(Chain.Aptos).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) - assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(8L, (result.chainData as AptosChainData).sequence) - } - - @Test - fun testAptosEmptyAccountPreload() { - val preloader = AptosSignerPreloader( - chain = Chain.Aptos, - accountsService = object : AptosAccountsService { - override suspend fun accounts(address: String): Result { - return Result.success(aptosAccountResponse.copy(sequence_number = null, error_code = "account_not_found")) - } - - }, - feeService = object : AptosFeeService { - override suspend fun feePrice(): Result { - return Result.success(aptosFeeResponse) - } - - override suspend fun simulate(data: AptosTransactionSimulation): Result> { - return Result.success(listOf(AptosTransaction(true, "9", "0"))) - } - } - ) - val result = runBlocking { - preloader.preloadNativeTransfer( - params = ConfirmParams.TransferParams.Native( - asset = Chain.Aptos.asset(), - from = Account(Chain.Aptos, "0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f", ""), - amount = BigInteger.valueOf(10_000_000_000), - destination = DestinationAddress("0xd7257c62806cea85fc8eaf947377b672fe062b81e6c0b19b6d8a3f408e59cf8c"), - isMaxAmount = false - ) - ) - } - assertEquals(BigInteger.valueOf(1350L), result.chainData.fee().amount) - assertEquals(BigInteger.valueOf(150L), (result.chainData.fee() as GasFee).maxGasPrice) - assertEquals(BigInteger.valueOf(9L), (result.chainData.fee() as GasFee).limit) - assertEquals(AssetId(Chain.Aptos).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) - assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(0L, (result.chainData as AptosChainData).sequence) - } - - @Test - fun testAptosFeeFail() { - val preloader = AptosSignerPreloader( - chain = Chain.Aptos, - accountsService = object : AptosAccountsService { - override suspend fun accounts(address: String): Result { - return Result.success(aptosAccountResponse.copy(sequence_number = null, error_code = null, message = "Message")) - } - - }, - feeService = object : AptosFeeService { - override suspend fun feePrice(): Result { - return Result.success(aptosFeeResponse) - } - - override suspend fun simulate(data: AptosTransactionSimulation): Result> { - return Result.success(listOf(AptosTransaction(true, "0", "69"))) - } - } - ) - try { - runBlocking { - preloader.preloadNativeTransfer( - params = ConfirmParams.TransferParams.Native( - asset = Chain.Aptos.asset(), - from = Account(Chain.Aptos, "0x80c3cca35602e4568a7ac88d4d91110f8efa6c45c659439c2b4ed04033059c6f", ""), - amount = BigInteger.valueOf(10_000_000_000), - destination = DestinationAddress("0xd7257c62806cea85fc8eaf947377b672fe062b81e6c0b19b6d8a3f408e59cf8c"), - isMaxAmount = false - ) - ) - } - assertTrue(false) - } catch (err: Throwable) { - assertEquals(null, err.message) - } - } -} \ No newline at end of file diff --git a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt b/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt deleted file mode 100644 index bbf4fd8a2..000000000 --- a/blockchain/src/test/kotlin/com/gemwallet/android/blockchain/clients/cosmos/TestCosmosPreload.kt +++ /dev/null @@ -1,188 +0,0 @@ -package com.gemwallet.android.blockchain.clients.cosmos - -import com.gemwallet.android.ext.asset -import com.gemwallet.android.ext.toIdentifier -import com.gemwallet.android.model.ConfirmParams -import com.gemwallet.android.model.DestinationAddress -import com.gemwallet.android.model.GasFee -import com.wallet.core.blockchain.cosmos.CosmosAccount -import com.wallet.core.blockchain.cosmos.CosmosAccountResponse -import com.wallet.core.blockchain.cosmos.CosmosBlock -import com.wallet.core.blockchain.cosmos.CosmosBlockResponse -import com.wallet.core.blockchain.cosmos.CosmosHeader -import com.wallet.core.blockchain.cosmos.CosmosInjectiveAccount -import com.wallet.core.primitives.Account -import com.wallet.core.primitives.AssetId -import com.wallet.core.primitives.Chain -import com.wallet.core.primitives.FeePriority -import junit.framework.TestCase.assertEquals -import kotlinx.coroutines.runBlocking -import org.junit.Test -import java.math.BigInteger - -class TestCosmosPreload { - - private val accountsService = object : CosmosAccountsService { - - var addressRequest: String = "" - - override suspend fun getAccountData(owner: String): Result> { - addressRequest = owner - return Result.success(CosmosAccountResponse(CosmosAccount(account_number = "2913388", sequence = "10"))) - } - - override suspend fun getInjectiveAccountData(owner: String): Result> { - throw Exception() - } - - override suspend fun getNodeInfo(): Result { - return Result.success(CosmosBlockResponse( - CosmosBlock( - CosmosHeader( - chain_id = "osmosis-1", - height = "25181150" - ) - ) - )) - } - } - - - @Test - fun testCosmosPreload() { - val preload = CosmosSignerPreloader(Chain.Osmosis, accountsService) - val result = runBlocking { - preload.preloadNativeTransfer( - ConfirmParams.TransferParams.Native( - from = Account(Chain.Osmosis, "osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", ""), - amount = BigInteger.ONE, - asset = Chain.Osmosis.asset(), - destination = DestinationAddress("osmo1rcjvzz8wzktqfz8qjf0l9q45kzxvd0z0n7l5cf"), - ) - ) - } - assertEquals("osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", accountsService.addressRequest) - - assertEquals(BigInteger.valueOf(1), result.input.amount) - assertEquals("osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", result.input.from.address) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.input.assetId.toIdentifier()) - assertEquals(false, result.input.isMax()) - assertEquals("osmo1rcjvzz8wzktqfz8qjf0l9q45kzxvd0z0n7l5cf", result.input.destination()?.address) - assertEquals(null, result.input.memo()) - - assertEquals(BigInteger.valueOf(10000L), result.chainData.fee().amount) - assertEquals(BigInteger.valueOf(10000L), (result.chainData.fee() as GasFee).maxGasPrice) - assertEquals(BigInteger.valueOf(200000L), (result.chainData.fee() as GasFee).limit) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) - assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(10L, (result.chainData as CosmosChainData).sequence) - assertEquals(2913388L, (result.chainData as CosmosChainData).accountNumber) - assertEquals("osmosis-1", (result.chainData as CosmosChainData).chainId) - } - - @Test - fun testCosmosDelegatePreload() { - val preload = CosmosSignerPreloader(Chain.Osmosis, accountsService) - val result = runBlocking { - preload.preloadStake( - ConfirmParams.Stake.DelegateParams( - from = Account(Chain.Osmosis, "osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", ""), - amount = BigInteger.ONE, - asset = Chain.Osmosis.asset(), - validatorId = "osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm" - ) - ) - } - - assertEquals("osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", accountsService.addressRequest) - assertEquals(BigInteger.valueOf(100000L), result.chainData.fee().amount) - assertEquals(BigInteger.valueOf(100000L), (result.chainData.fee() as GasFee).maxGasPrice) - assertEquals(BigInteger.valueOf(1000000L), (result.chainData.fee() as GasFee).limit) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) - assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(10L, (result.chainData as CosmosChainData).sequence) - assertEquals(2913388L, (result.chainData as CosmosChainData).accountNumber) - assertEquals("osmosis-1", (result.chainData as CosmosChainData).chainId) - } - - @Test - fun testCosmosUndelegatePreload() { - val preload = CosmosSignerPreloader(Chain.Osmosis, accountsService) - val result = runBlocking { - preload.preloadStake( - ConfirmParams.Stake.UndelegateParams( - from = Account(Chain.Osmosis, "osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", ""), - amount = BigInteger.ONE, - asset = Chain.Osmosis.asset(), - validatorId = "osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", - delegationId = "25053096", - share = "", - balance = "2000000", - ) - ) - } - assertEquals("osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", accountsService.addressRequest) - assertEquals(BigInteger.valueOf(100000L), result.chainData.fee().amount) - assertEquals(BigInteger.valueOf(100000L), (result.chainData.fee() as GasFee).maxGasPrice) - assertEquals(BigInteger.valueOf(1000000L), (result.chainData.fee() as GasFee).limit) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) - assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(10L, (result.chainData as CosmosChainData).sequence) - assertEquals(2913388L, (result.chainData as CosmosChainData).accountNumber) - assertEquals("osmosis-1", (result.chainData as CosmosChainData).chainId) - } - - @Test - fun testCosmosRedelegatePreload() { - val preload = CosmosSignerPreloader(Chain.Osmosis, accountsService) - val result = runBlocking { - preload.preloadStake( - ConfirmParams.Stake.RedelegateParams( - from = Account(Chain.Osmosis, "osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", ""), - amount = BigInteger.ONE, - asset = Chain.Osmosis.asset(), - srcValidatorId = "osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", - dstValidatorId = "osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2", - share = "", - balance = "2000000", - ) - ) - } - assertEquals("osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", accountsService.addressRequest) - assertEquals(BigInteger.valueOf(100000L), result.chainData.fee().amount) - assertEquals(BigInteger.valueOf(100000L), (result.chainData.fee() as GasFee).maxGasPrice) - assertEquals(BigInteger.valueOf(1250000L), (result.chainData.fee() as GasFee).limit) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) - assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(10L, (result.chainData as CosmosChainData).sequence) - assertEquals(2913388L, (result.chainData as CosmosChainData).accountNumber) - assertEquals("osmosis-1", (result.chainData as CosmosChainData).chainId) - } - - @Test - fun testCosmosRewardsPreload() { - val preload = CosmosSignerPreloader(Chain.Osmosis, accountsService) - val result = runBlocking { - preload.preloadStake( - ConfirmParams.Stake.RewardsParams( - from = Account(Chain.Osmosis, "osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", ""), - amount = BigInteger.ONE, - asset = Chain.Osmosis.asset(), - validatorsId = listOf( - "osmovaloper1pxphtfhqnx9ny27d53z4052e3r76e7qq495ehm", - "osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2", - ), - ) - ) - } - assertEquals("osmo1q0d0q8w8y8t6h4l9w5u8p8s8h8f8e8r8t8y8u8i8o8p8", accountsService.addressRequest) - assertEquals(BigInteger.valueOf(100000L), result.chainData.fee().amount) - assertEquals(BigInteger.valueOf(100000L), (result.chainData.fee() as GasFee).maxGasPrice) - assertEquals(BigInteger.valueOf(900000L), (result.chainData.fee() as GasFee).limit) - assertEquals(AssetId(Chain.Osmosis).toIdentifier(), result.chainData.fee().feeAssetId.toIdentifier()) - assertEquals(FeePriority.Normal, result.chainData.fee().priority) - assertEquals(10L, (result.chainData as CosmosChainData).sequence) - assertEquals(2913388L, (result.chainData as CosmosChainData).accountNumber) - assertEquals("osmosis-1", (result.chainData as CosmosChainData).chainId) - } -} \ No newline at end of file