Skip to content
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
18 changes: 11 additions & 7 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}

android {
compileSdkVersion 32
namespace 'io.horizontalsystems.ethereumkit.sample'
compileSdkVersion 33
defaultConfig {
applicationId "io.horizontalsystems.ethereumkit"
minSdkVersion 26
targetSdkVersion 32
targetSdkVersion 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildFeatures {
viewBinding true
}

buildFeatures {
compose true
}
Expand All @@ -33,16 +37,16 @@ android {


compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = "11"
jvmTarget = "17"
}

composeOptions {
kotlinCompilerExtensionVersion '1.3.0'
kotlinCompilerExtensionVersion '1.5.8'
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,42 @@ package io.horizontalsystems.ethereumkit.sample.modules.addresswatch

import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.horizontalsystems.ethereumkit.sample.R
import io.horizontalsystems.ethereumkit.sample.modules.main.ShowTxType
import io.horizontalsystems.ethereumkit.sample.modules.main.TransactionsAdapter
import kotlinx.android.synthetic.main.activity_address_watch.*
import kotlinx.android.synthetic.main.activity_address_watch.ethFilter
import kotlinx.android.synthetic.main.activity_address_watch.tokenFilter
import kotlinx.android.synthetic.main.activity_address_watch.transactionsRecyclerView

class AddressWatchActivity : AppCompatActivity() {

private lateinit var viewModel: AddressWatchViewModel

private lateinit var addressInput: EditText
private lateinit var watchButton: Button
private lateinit var ethFilter: Button
private lateinit var tokenFilter: Button
private lateinit var transactionsRecyclerView: RecyclerView
private lateinit var transactionSyncProgress: ProgressBar


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

viewModel = ViewModelProvider(this).get(AddressWatchViewModel::class.java)

addressInput = findViewById(R.id.addressInput)
watchButton = findViewById(R.id.watchButton)
ethFilter = findViewById(R.id.ethFilter)
tokenFilter = findViewById(R.id.tokenFilter)
transactionsRecyclerView = findViewById(R.id.transactionsRecyclerView)
transactionSyncProgress = findViewById(R.id.transactionSyncProgress)

setContentView(R.layout.activity_address_watch)

watchButton.setOnClickListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ class AddressWatchViewModel : ViewModel() {

when (Configuration.chain) {
Chain.BinanceSmartChain -> {
transactionSource = TransactionSource.etherscanApi(Configuration.etherscanKey.split(","))
transactionSource = TransactionSource.binance(Configuration.etherscanKey.split(","))
rpcSource = RpcSource.binanceSmartChainHttp()
}
Chain.Ethereum -> {
transactionSource = TransactionSource.etherscanApi(Configuration.etherscanKey.split(","))
transactionSource = TransactionSource.ethereum(Configuration.etherscanKey.split(","))
rpcSource = RpcSource.Http(listOf(URI(Configuration.ethereumRpc)), null)
}
else -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import io.horizontalsystems.ethereumkit.core.EthereumKit
import io.horizontalsystems.ethereumkit.sample.R
import kotlinx.android.synthetic.main.fragment_balance.*
import io.horizontalsystems.ethereumkit.sample.databinding.FragmentBalanceBinding

class BalanceFragment : Fragment() {

private lateinit var viewModel: MainViewModel

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_balance, container, false)
private var _binding: FragmentBalanceBinding? = null // 2. Add binding property
private val binding get() = _binding!!

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentBalanceBinding.inflate(inflater, container, false) // 3. Inflate with ViewBinding
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Expand All @@ -25,52 +28,52 @@ class BalanceFragment : Fragment() {
viewModel = ViewModelProvider(requireActivity()).get(MainViewModel::class.java)

viewModel.balance.observe(viewLifecycleOwner, Observer { balance ->
balanceValue.text = (balance ?: 0).toString()
binding.balanceValue.text = (balance ?: 0).toString()
})

viewModel.erc20TokenBalance.observe(viewLifecycleOwner, Observer { balance ->
tokenBalanceValue.text = (balance ?: 0).toString()
binding. tokenBalanceValue.text = (balance ?: 0).toString()
})

viewModel.lastBlockHeight.observe(viewLifecycleOwner, Observer { lbh ->
lbhValue.text = (lbh ?: 0).toString()
binding.lbhValue.text = (lbh ?: 0).toString()
})

viewModel.syncState.observe(viewLifecycleOwner, Observer { state ->
val syncStateInfo = getSynStateInfo(state)
syncStateValue.text = syncStateInfo.description
binding.syncStateValue.text = syncStateInfo.description
if (syncStateInfo.error == null) {
syncStateError.visibility = View.GONE
binding.syncStateError.visibility = View.GONE
} else {
syncStateError.text = syncStateInfo.error.message
syncStateError.visibility = View.VISIBLE
binding.syncStateError.text = syncStateInfo.error.message
binding.syncStateError.visibility = View.VISIBLE
}
})

viewModel.transactionsSyncState.observe(viewLifecycleOwner, Observer { state ->
txSyncStateValue.text = getSynStateInfo(state).description
binding.txSyncStateValue.text = getSynStateInfo(state).description
})

viewModel.erc20SyncState.observe(viewLifecycleOwner, Observer { state ->
val syncStateInfo = getSynStateInfo(state)
erc20SyncStateValue.text = syncStateInfo.description
binding.erc20SyncStateValue.text = syncStateInfo.description
if (syncStateInfo.error == null) {
erc20SyncStateError.visibility = View.GONE
binding.erc20SyncStateError.visibility = View.GONE
} else {
erc20SyncStateError.text = syncStateInfo.error.message
erc20SyncStateError.visibility = View.VISIBLE
binding.erc20SyncStateError.text = syncStateInfo.error.message
binding.erc20SyncStateError.visibility = View.VISIBLE
}
})

viewModel.erc20TransactionsSyncState.observe(viewLifecycleOwner, Observer { state ->
erc20TxSyncStateValue.text = getSynStateInfo(state).description
binding.erc20TxSyncStateValue.text = getSynStateInfo(state).description
})

buttonRefresh.setOnClickListener {
binding.buttonRefresh.setOnClickListener {
viewModel.refresh()
}

buttonClear.setOnClickListener {
binding.buttonClear.setOnClickListener {
viewModel.clear()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.bottomnavigation.BottomNavigationView
import io.horizontalsystems.ethereumkit.sample.R
import io.horizontalsystems.ethereumkit.sample.databinding.ActivityMainBinding
import io.horizontalsystems.ethereumkit.sample.modules.addresswatch.AddressWatchActivity
import io.horizontalsystems.ethereumkit.sample.modules.uniswapV3.UniswapV3Fragment
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener {

private lateinit var binding: ActivityMainBinding

private val balanceFragment = BalanceFragment()
private val transactionsFragment = TransactionsFragment()
private val sendReceiveFragment = SendReceiveFragment()
Expand All @@ -28,9 +30,10 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(R.layout.activity_main)

toolbar.setOnMenuItemClickListener { item ->
binding.toolbar.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.menuAddressWatch -> {
val intent = Intent(this, AddressWatchActivity::class.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,17 +193,17 @@ class MainViewModel : ViewModel() {
private fun createKit(): EthereumKit {
when (Configuration.chain) {
Chain.BinanceSmartChain -> {
transactionSource = TransactionSource.etherscanApi(Configuration.etherscanKey.split(","))
transactionSource = TransactionSource.binance(Configuration.etherscanKey.split(","))
rpcSource = RpcSource.binanceSmartChainHttp()
}

Chain.Ethereum -> {
transactionSource = TransactionSource.etherscanApi(Configuration.etherscanKey.split(","))
transactionSource = TransactionSource.ethereum(Configuration.etherscanKey.split(","))
rpcSource = RpcSource.Http(listOf(URI(Configuration.ethereumRpc)), null)
}

Chain.ArbitrumOne -> {
transactionSource = TransactionSource.etherscanApi(Configuration.etherscanKey.split(","))
transactionSource = TransactionSource.arbitrumOne(Configuration.etherscanKey.split(","))
rpcSource = RpcSource.arbitrumOneRpcHttp()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.selection.SelectionContainer
Expand All @@ -20,12 +21,13 @@ import androidx.compose.ui.unit.dp
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.compose.viewModel
import kotlinx.android.synthetic.main.activity_main.*
import io.horizontalsystems.ethereumkit.sample.R

class NftsFragment : Fragment() {
private lateinit var mainViewModel: MainViewModel

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val toolbar = activity?.findViewById<Toolbar>(R.id.toolbar) // <-- FIND THE VIEW
toolbar?.title = "Nfts"

mainViewModel = activity?.let { ViewModelProvider(it)[MainViewModel::class.java] } ?: return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,22 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import io.horizontalsystems.ethereumkit.sample.R
import kotlinx.android.synthetic.main.fragment_send_receive.*
import io.horizontalsystems.ethereumkit.sample.databinding.FragmentSendReceiveBinding
import java.math.BigDecimal

class SendReceiveFragment : Fragment() {

private lateinit var viewModel: MainViewModel

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_send_receive, container, false)
private var _binding: FragmentSendReceiveBinding? = null
private val binding get() = _binding!!

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentSendReceiveBinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Expand All @@ -26,46 +32,46 @@ class SendReceiveFragment : Fragment() {
viewModel = activity?.let { ViewModelProvider(it).get(MainViewModel::class.java) } ?: return

viewModel.estimatedGas.observe(viewLifecycleOwner, Observer { estimatedGas ->
estimateGasText.text = estimatedGas
binding.estimateGasText.text = estimatedGas
})

viewModel.sendStatus.observe(viewLifecycleOwner, Observer { sendError ->
val msg = if (sendError != null) sendError.localizedMessage else " Successfully sent!"
Toast.makeText(context, msg, Toast.LENGTH_LONG).show()
})

receiveAddressButton.setOnClickListener {
receiveAddressText.text = viewModel.receiveAddress()
binding.receiveAddressButton.setOnClickListener {
binding.receiveAddressText.text = viewModel.receiveAddress()
}

estimateGasButton.setOnClickListener {
binding.estimateGasButton.setOnClickListener {
onTapEstimateGas(false)
}

estimateErc20GasButton.setOnClickListener {
binding.estimateErc20GasButton.setOnClickListener {
onTapEstimateGas(true)
}

sendButton.setOnClickListener {
binding.sendButton.setOnClickListener {
when {
sendAddress.text.isEmpty() -> sendAddress.error = "Send address cannot be blank"
sendAmount.text.isEmpty() -> sendAmount.error = "Send amount cannot be blank"
else -> viewModel.send(sendAddress.text.toString(), sendAmount.text.toString().toBigDecimal())
binding.sendAddress.text.isEmpty() -> binding.sendAddress.error = "Send address cannot be blank"
binding.sendAmount.text.isEmpty() -> binding.sendAmount.error = "Send amount cannot be blank"
else -> viewModel.send(binding.sendAddress.text.toString(), binding.sendAmount.text.toString().toBigDecimal())
}
}

sendErc20.setOnClickListener {
binding.sendErc20.setOnClickListener {
when {
sendAmount.text.isEmpty() -> sendAmount.error = "Send amount cannot be blank"
else -> viewModel.sendERC20(sendAddress.text.toString(), sendAmount.text.toString().toBigDecimal())
binding.sendAmount.text.isEmpty() -> binding.sendAmount.error = "Send amount cannot be blank"
else -> viewModel.sendERC20(binding.sendAddress.text.toString(), binding.sendAmount.text.toString().toBigDecimal())
}
}
}

private fun onTapEstimateGas(isErc20: Boolean) {
val toAddress = sendAddress.text.toString()
val toAddress = binding.sendAddress.text.toString()
val resolvedToAddress = if (toAddress.isNotBlank()) toAddress else null
val resolvedAmount = sendAmount.text.toString().toBigDecimalOrNull() ?: BigDecimal.ZERO
val resolvedAmount = binding.sendAmount.text.toString().toBigDecimalOrNull() ?: BigDecimal.ZERO

viewModel.estimateGas(resolvedToAddress, resolvedAmount, isErc20)
}
Expand Down
Loading