diff --git a/wallet_app/android/app/src/main/java/StarknetClient.kt b/wallet_app/android/app/src/main/java/StarknetClient.kt new file mode 100644 index 00000000..22ec2cdf --- /dev/null +++ b/wallet_app/android/app/src/main/java/StarknetClient.kt @@ -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, 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 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) + } +} \ No newline at end of file diff --git a/wallet_app/android/app/src/main/java/com/example/walletapp/MainActivity.kt b/wallet_app/android/app/src/main/java/com/example/walletapp/MainActivity.kt index 4540bc3a..7839aa60 100644 --- a/wallet_app/android/app/src/main/java/com/example/walletapp/MainActivity.kt +++ b/wallet_app/android/app/src/main/java/com/example/walletapp/MainActivity.kt @@ -1,5 +1,6 @@ package com.example.walletapp +import StarknetClient import android.app.Activity import android.content.Intent import android.os.Bundle @@ -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() @@ -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() } diff --git a/wallet_app/android/app/src/main/java/com/example/walletapp/ui/activity/AccountBalanceActivity.kt b/wallet_app/android/app/src/main/java/com/example/walletapp/ui/activity/AccountBalanceActivity.kt index d080a870..a60050a0 100644 --- a/wallet_app/android/app/src/main/java/com/example/walletapp/ui/activity/AccountBalanceActivity.kt +++ b/wallet_app/android/app/src/main/java/com/example/walletapp/ui/activity/AccountBalanceActivity.kt @@ -1,5 +1,6 @@ package com.example.walletapp.ui.activity +import StarknetClient import android.app.Activity import android.os.Bundle import android.util.Log @@ -80,6 +81,8 @@ class AccountBalanceActivity : ComponentActivity() { val scope = CoroutineScope(Dispatchers.IO) + val starknetClient = StarknetClient(BuildConfig.DEMO_RPC_URL) + Column(modifier = Modifier .fillMaxSize() @@ -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) { @@ -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, 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 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) - } - } \ No newline at end of file