Skip to content

Commit

Permalink
move starknet logic to its own class
Browse files Browse the repository at this point in the history
  • Loading branch information
trbutler4 committed Sep 15, 2024
1 parent 86e51ec commit 86106ef
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 54 deletions.
67 changes: 67 additions & 0 deletions wallet_app/android/app/src/main/java/StarknetClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import com.swmansion.starknet.account.StandardAccount
import com.swmansion.starknet.data.types.Call
import com.swmansion.starknet.data.types.Felt
import com.swmansion.starknet.data.types.Uint256
import com.swmansion.starknet.provider.rpc.JsonRpcProvider
import com.swmansion.starknet.signer.StarkCurveSigner
import kotlinx.coroutines.future.await
import java.math.BigDecimal

const val ETH_ERC20_ADDRESS = "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"

class StarknetClient(private val rpcUrl: String) {

private val provider = JsonRpcProvider(rpcUrl)

suspend fun deployAccount() {

// Predefined values for account creation
val privateKey = Felt.fromHex("0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a") // TODO: Replace with an actual private key
val accountAddress = Felt.fromHex("0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca") // TODO: Replace with an actual address

val signer = StarkCurveSigner(privateKey)
val chainId = provider.getChainId().sendAsync().await()
val account = StandardAccount(
address = accountAddress,
signer = signer,
provider = provider,
chainId = chainId,
cairoVersion = Felt.ONE,
)

// TODO: deploy account
}

suspend fun getEthBalance(accountAddress: Felt): Uint256 {
val erc20ContractAddress = Felt.fromHex(ETH_ERC20_ADDRESS)

// Create a call to Starknet ERC-20 ETH contract
val call = Call(
contractAddress = erc20ContractAddress,
entrypoint = "balanceOf", // entrypoint can be passed both as a string name and Felt value
calldata = listOf(accountAddress), // calldata is List<Felt>, so we wrap accountAddress in listOf()
)

// Create a Request object which has to be executed in synchronous or asynchronous way
val request = provider.callContract(call)

// Execute a Request. This operation returns JVM CompletableFuture
val future = request.sendAsync()

// Await the completion of the future without blocking the main thread
// this comes from kotlinx-coroutines-jdk8
// The result of the future is a List<Felt> which represents the output values of the balanceOf function
val response = future.await()

// Output value's type is UInt256 and is represented by two Felt values
return Uint256(
low = response[0],
high = response[1],
)
}

fun weiToEther(wei: Uint256): BigDecimal {
val weiInEther = BigDecimal("1000000000000000000") // 10^18
return BigDecimal(wei.value.toString()).divide(weiInEther)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.walletapp

import StarknetClient
import android.app.Activity
import android.content.Intent
import android.os.Bundle
Expand Down Expand Up @@ -78,11 +79,8 @@ fun StarknetLogo (modifier: Modifier = Modifier) {
fun CreateAccount( modifier: Modifier) {
val context = (LocalContext.current as Activity)
val scope = rememberCoroutineScope()
val starknetClient = StarknetClient(BuildConfig.DEMO_RPC_URL)

// Predefined values for account creation
val privateKey = Felt.fromHex("0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a") // Replace with an actual private key
val accountAddress = Felt.fromHex("0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca") // Replace with an actual address
val provider = JsonRpcProvider("http://10.0.2.2:5050")
Column(
modifier = Modifier
.fillMaxSize()
Expand Down Expand Up @@ -150,18 +148,8 @@ fun CreateAccount( modifier: Modifier) {
onClick = {
scope.launch {
try {
val signer = StarkCurveSigner(privateKey)
val chainId = provider.getChainId().sendAsync().await()
val account = StandardAccount(
address = accountAddress,
signer = signer,
provider = provider,
chainId = chainId,
cairoVersion = Felt.ONE,
)
starknetClient.deployAccount()

// Here you would typically deploy the account
// For now, we'll just show a success message
withContext(Dispatchers.Main) {
Toast.makeText(context, "Account deployed successfully!", Toast.LENGTH_LONG).show()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.walletapp.ui.activity

import StarknetClient
import android.app.Activity
import android.os.Bundle
import android.util.Log
Expand Down Expand Up @@ -80,6 +81,8 @@ class AccountBalanceActivity : ComponentActivity() {

val scope = CoroutineScope(Dispatchers.IO)

val starknetClient = StarknetClient(BuildConfig.DEMO_RPC_URL)


Column(modifier = Modifier
.fillMaxSize()
Expand Down Expand Up @@ -118,9 +121,9 @@ class AccountBalanceActivity : ComponentActivity() {
val accountAddress2 = Felt.fromHex( accountAddress)

// Get the balance of the account
val balancefinal = getBalance(accountAddress2)
val balancefinal = starknetClient.getEthBalance(accountAddress2)
Log.d("balance","${balancefinal}")
withContext(Dispatchers.Main) { balance= "${weiToEther(balancefinal)} ETH" }
withContext(Dispatchers.Main) { balance= "${starknetClient.weiToEther(balancefinal)} ETH" }
} catch (e: RpcRequestFailedException) {
withContext(Dispatchers.Main) { Toast.makeText(applicationContext, "${e.code}: ${e.message}", Toast.LENGTH_LONG).show() }
} catch (e: Exception) {
Expand All @@ -145,41 +148,4 @@ class AccountBalanceActivity : ComponentActivity() {

}
}
private val provider = JsonRpcProvider(
url = BuildConfig.DEMO_RPC_URL,
)

private suspend fun getBalance(accountAddress: Felt): Uint256 {
val erc20ContractAddress = Felt.fromHex("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7")

// Create a call to Starknet ERC-20 ETH contract
val call = Call(
contractAddress = erc20ContractAddress,
entrypoint = "balanceOf", // entrypoint can be passed both as a string name and Felt value
calldata = listOf(accountAddress), // calldata is List<Felt>, so we wrap accountAddress in listOf()
)

// Create a Request object which has to be executed in synchronous or asynchronous way
val request = provider.callContract(call)

// Execute a Request. This operation returns JVM CompletableFuture
val future = request.sendAsync()

// Await the completion of the future without blocking the main thread
// this comes from kotlinx-coroutines-jdk8
// The result of the future is a List<Felt> which represents the output values of the balanceOf function
val response = future.await()

// Output value's type is UInt256 and is represented by two Felt values
return Uint256(
low = response[0],
high = response[1],
)
}

fun weiToEther(wei: Uint256): BigDecimal {
val weiInEther = BigDecimal("1000000000000000000") // 10^18
return BigDecimal(wei.value.toString()).divide(weiInEther)
}

}

0 comments on commit 86106ef

Please sign in to comment.