Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate ton kit android #7679

Merged
merged 9 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ android {
substitute module('com.tinder.scarlet:message-adapter-gson:0.1.12') using module('com.github.WalletConnect.Scarlet:message-adapter-gson:1.0.0')
substitute module('com.tinder.scarlet:lifecycle-android:0.1.12') using module('com.github.WalletConnect.Scarlet:lifecycle-android:1.0.0')
}

resolutionStrategy.eachDependency { details ->
if (details.requested.group == 'com.squareup.okhttp3') {
details.useVersion "4.12.0"
}
}
}

}
Expand Down Expand Up @@ -232,7 +238,7 @@ dependencies {
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.11.0'
implementation 'com.squareup.retrofit2:converter-gson:2.11.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.11.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'
implementation 'com.google.code.gson:gson:2.10.1'
implementation "androidx.biometric:biometric:$biometric_version"

Expand Down Expand Up @@ -269,12 +275,12 @@ dependencies {
debugImplementation leakCanary

// Wallet kits
implementation 'com.github.horizontalsystems:ton-kit-kmm:f1fd301'
implementation 'com.github.horizontalsystems:ton-kit-android:e907480'
implementation 'com.github.horizontalsystems:bitcoin-kit-android:47db768'
implementation 'com.github.horizontalsystems:ethereum-kit-android:3d83900'
implementation 'com.github.horizontalsystems:blockchain-fee-rate-kit-android:1d3bd49'
implementation 'com.github.horizontalsystems:binance-chain-kit-android:c1509a2'
implementation 'com.github.horizontalsystems:market-kit-android:636ca4d'
implementation 'com.github.horizontalsystems:market-kit-android:55dde9c'
implementation 'com.github.horizontalsystems:solana-kit-android:ce738d8'
implementation 'com.github.horizontalsystems:tron-kit-android:dc3dca7'
// Zcash SDK
Expand Down
19 changes: 18 additions & 1 deletion app/src/main/java/io/horizontalsystems/bankwallet/core/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ import io.horizontalsystems.bankwallet.core.managers.SubscriptionManager
import io.horizontalsystems.bankwallet.core.managers.SystemInfoManager
import io.horizontalsystems.bankwallet.core.managers.TermsManager
import io.horizontalsystems.bankwallet.core.managers.TokenAutoEnableManager
import io.horizontalsystems.bankwallet.core.managers.TonAccountManager
import io.horizontalsystems.bankwallet.core.managers.TonKitManager
import io.horizontalsystems.bankwallet.core.managers.TorManager
import io.horizontalsystems.bankwallet.core.managers.TransactionAdapterManager
import io.horizontalsystems.bankwallet.core.managers.TronAccountManager
Expand Down Expand Up @@ -162,6 +164,7 @@ class App : CoreApp(), WorkConfiguration.Provider, ImageLoaderFactory {
lateinit var binanceKitManager: BinanceKitManager
lateinit var solanaKitManager: SolanaKitManager
lateinit var tronKitManager: TronKitManager
lateinit var tonKitManager: TonKitManager
lateinit var numberFormatter: IAppNumberFormatter
lateinit var feeCoinProvider: FeeTokenProvider
lateinit var accountCleaner: IAccountCleaner
Expand Down Expand Up @@ -274,6 +277,7 @@ class App : CoreApp(), WorkConfiguration.Provider, ImageLoaderFactory {
solanaKitManager = SolanaKitManager(appConfigProvider, solanaRpcSourceManager, solanaWalletManager, backgroundManager)

tronKitManager = TronKitManager(appConfigProvider, backgroundManager)
tonKitManager = TonKitManager(backgroundManager)

wordsManager = WordsManager(Mnemonic())
networkManager = NetworkManager()
Expand Down Expand Up @@ -317,6 +321,9 @@ class App : CoreApp(), WorkConfiguration.Provider, ImageLoaderFactory {
)
tronAccountManager.start()

val tonAccountManager = TonAccountManager(accountManager, walletManager, tonKitManager, tokenAutoEnableManager)
tonAccountManager.start()

systemInfoManager = SystemInfoManager(appConfigProvider)

languageManager = LanguageManager()
Expand All @@ -343,13 +350,23 @@ class App : CoreApp(), WorkConfiguration.Provider, ImageLoaderFactory {
binanceKitManager = binanceKitManager,
solanaKitManager = solanaKitManager,
tronKitManager = tronKitManager,
tonKitManager = tonKitManager,
backgroundManager = backgroundManager,
restoreSettingsManager = restoreSettingsManager,
coinManager = coinManager,
evmLabelManager = evmLabelManager,
localStorage = localStorage
)
adapterManager = AdapterManager(walletManager, adapterFactory, btcBlockchainManager, evmBlockchainManager, binanceKitManager, solanaKitManager, tronKitManager)
adapterManager = AdapterManager(
walletManager,
adapterFactory,
btcBlockchainManager,
evmBlockchainManager,
binanceKitManager,
solanaKitManager,
tronKitManager,
tonKitManager,
)
transactionAdapterManager = TransactionAdapterManager(adapterManager, adapterFactory)

feeCoinProvider = FeeTokenProvider(marketKit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import io.horizontalsystems.marketkit.models.BlockchainType
import io.horizontalsystems.marketkit.models.Token
import io.horizontalsystems.marketkit.models.TokenQuery
import io.horizontalsystems.solanakit.models.FullTransaction
import io.horizontalsystems.tonkit.FriendlyAddress
import io.horizontalsystems.tronkit.transaction.Fee
import io.reactivex.Flowable
import io.reactivex.Observable
Expand All @@ -62,7 +63,7 @@ import io.horizontalsystems.tronkit.models.Address as TronAddress
interface IAdapterManager {
val adaptersReadyObservable: Flowable<Map<Wallet, IAdapter>>
fun startAdapterManager()
fun refresh()
suspend fun refresh()
fun getAdapterForWallet(wallet: Wallet): IAdapter?
fun getAdapterForToken(token: Token): IAdapter?
fun getBalanceAdapterForWallet(wallet: Wallet): IBalanceAdapter?
Expand Down Expand Up @@ -399,8 +400,8 @@ interface ISendSolanaAdapter {

interface ISendTonAdapter {
val availableBalance: BigDecimal
suspend fun send(amount: BigDecimal, address: String, memo: String?)
suspend fun estimateFee() : BigDecimal
suspend fun send(amount: BigDecimal, address: FriendlyAddress, memo: String?)
suspend fun estimateFee(amount: BigDecimal, address: FriendlyAddress, memo: String?) : BigDecimal
}

interface ISendTronAdapter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ val Token.protocolInfo: String
}
is TokenType.Eip20,
is TokenType.Bep2,
is TokenType.Spl -> protocolType ?: ""
is TokenType.Spl,
is TokenType.Jetton -> protocolType ?: ""
else -> ""
}

Expand All @@ -82,6 +83,7 @@ val Token.typeInfo: String
is TokenType.Eip20 -> type.address.shorten()
is TokenType.Bep2 -> type.symbol
is TokenType.Spl -> type.address.shorten()
is TokenType.Jetton -> type.address.shorten()
is TokenType.Unsupported -> ""
}

Expand All @@ -90,6 +92,7 @@ val Token.copyableTypeInfo: String?
is TokenType.Eip20 -> type.address
is TokenType.Bep2 -> type.symbol
is TokenType.Spl -> type.address
is TokenType.Jetton -> type.address
else -> null
}

Expand Down Expand Up @@ -118,6 +121,7 @@ val TokenQuery.protocolType: String?
}

is TokenType.Bep2 -> "BEP2"
is TokenType.Jetton -> "JETTON"
else -> blockchainType.title
}

Expand Down Expand Up @@ -161,7 +165,7 @@ val TokenQuery.isSupported: Boolean
tokenType is TokenType.Native || tokenType is TokenType.Eip20
}
BlockchainType.Ton -> {
tokenType is TokenType.Native
tokenType is TokenType.Native || tokenType is TokenType.Jetton
}
is BlockchainType.Unsupported -> false
}
Expand Down Expand Up @@ -191,6 +195,8 @@ val Blockchain.description: String

fun Blockchain.eip20TokenUrl(address: String) = eip3091url?.replace("\$ref", address)

fun Blockchain.jettonUrl(address: String) = "https://tonviewer.com/$address"

fun Blockchain.bep2TokenUrl(symbol: String) = "https://explorer.binance.org/asset/$symbol"

val BlockchainType.imageUrl: String
Expand Down Expand Up @@ -244,6 +250,7 @@ val BlockchainType.tokenIconPlaceholder: Int
BlockchainType.Gnosis -> R.drawable.gnosis_erc20
BlockchainType.Fantom -> R.drawable.fantom_erc20
BlockchainType.Tron -> R.drawable.tron_trc20
BlockchainType.Ton -> R.drawable.the_open_network_jetton
else -> R.drawable.coin_placeholder
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.horizontalsystems.bankwallet.core.adapters

import io.horizontalsystems.bankwallet.core.IAdapter
import io.horizontalsystems.bankwallet.core.IBalanceAdapter
import io.horizontalsystems.bankwallet.core.IReceiveAdapter
import io.horizontalsystems.bankwallet.core.managers.TonKitWrapper
import io.horizontalsystems.bankwallet.core.managers.statusInfo
import io.horizontalsystems.tonkit.models.Network

abstract class BaseTonAdapter(
tonKitWrapper: TonKitWrapper,
val decimals: Int
) : IAdapter, IBalanceAdapter, IReceiveAdapter {

val tonKit = tonKitWrapper.tonKit

override val debugInfo: String
get() = ""

val statusInfo: Map<String, Any>
get() = tonKit.statusInfo()

// IReceiveAdapter

override val receiveAddress: String
get() = tonKit.receiveAddress.toUserFriendly(false)

override val isMainNet: Boolean
get() = tonKit.network == Network.MainNet

// ISendTronAdapter
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package io.horizontalsystems.bankwallet.core.adapters

import io.horizontalsystems.bankwallet.core.AdapterState
import io.horizontalsystems.bankwallet.core.BalanceData
import io.horizontalsystems.bankwallet.core.ISendTonAdapter
import io.horizontalsystems.bankwallet.core.managers.TonKitWrapper
import io.horizontalsystems.bankwallet.core.managers.toAdapterState
import io.horizontalsystems.bankwallet.entities.Wallet
import io.horizontalsystems.tonkit.Address
import io.horizontalsystems.tonkit.FriendlyAddress
import io.reactivex.BackpressureStrategy
import io.reactivex.Flowable
import io.reactivex.subjects.PublishSubject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import java.math.BigDecimal

class JettonAdapter(
tonKitWrapper: TonKitWrapper,
addressStr: String,
wallet: Wallet,
) : BaseTonAdapter(tonKitWrapper, wallet.decimal), ISendTonAdapter {

private val address = Address.parse(addressStr)
private var jettonBalance = tonKit.jettonBalanceMap[address]

private val balanceUpdatedSubject: PublishSubject<Unit> = PublishSubject.create()
private val balanceStateUpdatedSubject: PublishSubject<Unit> = PublishSubject.create()

private val balance: BigDecimal
get() = jettonBalance?.balance?.toBigDecimal()?.movePointLeft(decimals)
?: BigDecimal.ZERO

override var balanceState: AdapterState = AdapterState.Syncing()
override val balanceStateUpdatedFlowable: Flowable<Unit>
get() = balanceStateUpdatedSubject.toFlowable(BackpressureStrategy.BUFFER)
override val balanceData: BalanceData
get() = BalanceData(balance)
override val balanceUpdatedFlowable: Flowable<Unit>
get() = balanceUpdatedSubject.toFlowable(BackpressureStrategy.BUFFER)

private val coroutineScope = CoroutineScope(Dispatchers.Default)

override fun start() {
coroutineScope.launch {
tonKit.jettonBalanceMapFlow.collect { jettonBalanceMap ->
jettonBalance = jettonBalanceMap[address]
balanceUpdatedSubject.onNext(Unit)
}
}
coroutineScope.launch {
tonKit.jettonSyncStateFlow.collect {
balanceState = it.toAdapterState()
balanceStateUpdatedSubject.onNext(Unit)
}
}
}

override fun stop() {
coroutineScope.cancel()
}

override fun refresh() {
}

override val availableBalance: BigDecimal
get() = balance

override suspend fun send(amount: BigDecimal, address: FriendlyAddress, memo: String?) {
tonKit.send(
jettonBalance?.walletAddress!!,
address,
amount.movePointRight(decimals).toBigInteger(),
memo
)
}

override suspend fun estimateFee(
amount: BigDecimal,
address: FriendlyAddress,
memo: String?,
): BigDecimal {
val estimateFee = tonKit.estimateFee(
jettonBalance?.walletAddress!!,
address,
amount.movePointRight(decimals).toBigInteger(),
memo
)

return estimateFee.toBigDecimal(decimals).stripTrailingZeros()
}
}
Loading
Loading