Skip to main content

Integrate Web3Auth with the Moonbeam Blockchain in Android

While using the Web3Auth Android SDK, you get the private key and sessionId within the user scope. This private key can interact with Moonbeam to make any blockchain calls, like getting the user's account, fetching balance, sign transaction, send transaction, read from and write to the smart contract, etc. We have highlighted a few here to get you started quickly on that.

Installation

To interact with the Ethereum blockchain in Android, you can use any EIP1193 compatible package available for Android. Here we're using web3j to demonstrate how to make blockchain calls using it with Web3Auth.

In your app-level build.gradle's dependencies section, add the following:

dependencies {
// ...
implementation 'org.web3j:core:4.8.7-android'
}

Chain Details for Moonbeam

Initialize

class MainActivity : AppCompatActivity() {
private lateinit var web3Auth: Web3Auth
private lateinit var web3: Web3j
private lateinit var credentials: Credentials
private val rpcUrl = "" // RPC URL of EVM Chain

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

web3Auth = Web3Auth(
Web3AuthOptions(context = this,
clientId = getString(R.string.web3auth_project_id),
network = Network.MAINNET,
redirectUrl = Uri.parse("{YOUR_APP_PACKAGE_NAME}://auth")
)
)

// Handle user signing in when app is not alive
web3Auth.setResultUrl(intent?.data)

// Call initialize() in onCreate() to check for any existing session.
val sessionResponse: CompletableFuture<Void> = web3Auth.initialize()
sessionResponse.whenComplete { _, error ->
if (error == null) {
reRender()
println("PrivKey: " + web3Auth.getPrivkey())
println("ed25519PrivKey: " + web3Auth.getEd25519PrivKey())
println("Web3Auth UserInfo" + web3Auth.getUserInfo())
credentials = Credentials.create(web3Auth.getPrivkey())
web3 = Web3j.build(HttpService(rpcUrl))
} else {
Log.d("MainActivity_Web3Auth", error.message ?: "Something went wrong")
// Ideally, you should initiate the login function here.
}
}


// Setup UI and event handlers
val signInButton = findViewById<Button>(R.id.signInButton)
signInButton.setOnClickListener { signIn() }
}

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)

// Handle user signing in when app is active
web3Auth.setResultUrl(intent?.data)
}

private fun signIn() {
val selectedLoginProvider = Provider.GOOGLE // Can be GOOGLE, FACEBOOK, TWITCH etc.
val loginCompletableFuture: CompletableFuture<Web3AuthResponse> =
web3Auth.login(LoginParams(selectedLoginProvider))

loginCompletableFuture.whenComplete { loginResponse, error ->
if (error == null) {
// render logged in UI
println(loginResponse)
// Set the sessionId from Web3Auth in App State
credentials = Credentials.create(web3Auth.getPrivkey())
web3 = Web3j.build(HttpService(rpcUrl))
} else {
// render error UI
}
}
}
//...
}

Get User Info

You get the user information after a successful login returned from the login method. The userInfo object contains the user information, whereas the privKey object contains the private key that can be used to make blockchain calls.


private fun signIn() {
val selectedLoginProvider = Provider.GOOGLE // Can be GOOGLE, FACEBOOK, TWITCH etc.
val loginCompletableFuture: CompletableFuture<Web3AuthResponse> =
web3Auth.login(LoginParams(selectedLoginProvider))

loginCompletableFuture.whenComplete { _, error ->
if (error == null) {
// render logged in UI with User's Info
credentials = Credentials.create(web3Auth.getPrivkey())
web3 = Web3j.build(HttpService(rpcUrl))
} else {
// render error UI
}
}
}

Get Account

private fun getAddress(): String {
println("Address:, ${credentials.address}")
return credentials.address
}

// Setup UI and event handlers
val getAccountButton = findViewById<Button>(R.id.getAccountButton)
getAccountButton.setOnClickListener { getAddress() }

Get Balance

private fun getBalance(): BigInteger? {
val publicAddress = credentials.address
val ethBalance: EthGetBalance = web3.ethGetBalance(publicAddress, DefaultBlockParameterName.LATEST).sendAsync().get()
println("Balance: ${ethBalance.balance}")
return ethBalance.balance
}

// Setup UI and event handlers
val getBalanceButton = findViewById<Button>(R.id.getBalanceButton)
getBalanceButton.setOnClickListener { getBalance() }

Send Transaction

private fun sendTransaction(amount: Double, recipientAddress: String): String? {
val ethGetTransactionCount: EthGetTransactionCount = web3.ethGetTransactionCount(credentials.address, DefaultBlockParameterName.LATEST).sendAsync().get()
val nonce: BigInteger = ethGetTransactionCount.transactionCount
val value: BigInteger = Convert.toWei(amount.toString(), Convert.Unit.ETHER).toBigInteger()
val gasLimit: BigInteger = BigInteger.valueOf(21000)
val chainId: EthChainId = web3.ethChainId().sendAsync().get()

// Raw Transaction
val rawTransaction: RawTransaction = RawTransaction.createTransaction(
chainId.chainId.toLong(),
nonce,
gasLimit,
recipientAddress,
value,
"",
BigInteger.valueOf(5000000000),
BigInteger.valueOf(6000000000000)
)

val signedMessage: ByteArray = TransactionEncoder.signMessage(rawTransaction, credentials)
val hexValue: String = Numeric.toHexString(signedMessage)
val ethSendTransaction: EthSendTransaction = web3.ethSendRawTransaction(hexValue).sendAsync().get()
return if(ethSendTransaction.error != null) {
println("Tx Error: ${ethSendTransaction.error.message}")
ethSendTransaction.error.message
} else {
println("Tx Hash: ${ethSendTransaction.transactionHash}")
ethSendTransaction.transactionHash
}
}

// Setup UI and event handlers
val sendTransactionButton = findViewById<Button>(R.id.sendTransactionButton)
sendTransactionButton.setOnClickListener { sendTransaction() }

Sign a message

private fun signMessage(message: String): String {
val hashedData = Hash.sha3(message.toByteArray(StandardCharsets.UTF_8))
val signature = Sign.signMessage(hashedData, credentials.ecKeyPair)
val r = Numeric.toHexString(signature.r)
val s = Numeric.toHexString(signature.s).substring(2)
val v = Numeric.toHexString(signature.v).substring(2)
val signHash = StringBuilder(r).append(s).append(v).toString()
println("Signed Hash: $signHash")
return signHash
}

// Setup UI and event handlers
val signMessageButton = findViewById<Button>(R.id.signMessageButton)
signMessageButton.setOnClickListener { signMessage() }