Skip to main content

Mavis ID Android SDK

Overview

The Mavis ID Android SDK lets developers integrate Mavis ID into Android apps developed with Kotlin. After the integration, users can sign in to your app with Mavis ID and create an embedded Web3 wallet to interact with the blockchain to send and receive tokens, sign messages, and more.

Usage

  • All functions of the SDK return a string in the format of the deep link schema that you registered in the Mavis ID settings in the Developer Console. For example, mydapp://callback.
  • To parse the response, you can use the Result class to extract the response parameters from the deep link, or you can implement your own handler.

Features

  • Authorize users: sign in to your app with Mavis ID.
  • Send transactions: transfer tokens to other addresses.
  • Sign messages: sign plain text messages.
  • Sign typed data: sign data structured according to the EIP-712 standard.
  • Call contracts: execute custom transactions on smart contracts.

Prerequisites

  • Android API level 24 or later.
  • An app created in the Developer Console.
  • Permission to use Mavis ID. Request in Developer Console > your app > App Permission > Sky Mavis Account (OAuth 2.0) > Request Access.
  • A client ID that you can find in Developer Console > Products > ID Service > CLIENT ID (APPLICATION ID).
  • A redirect URI registered in Developer Console > Products > ID Service > REDIRECT URI.

For more information about the initial setup, see Get started.

Steps

Step 1. Install the SDK

Import the library

  1. In your Android project, create a libs directory.
  2. Download the Mavis ID Android SDK release package and extract the contents into libs.
  3. In your app's build.gradle file, add the following dependency:
dependencies {
implementation files("libs/id-0.1.0.aar")
}

Configure Gradle

In settings.gradle, include the Maven repository URL:

maven {
url = uri("https://maven.pkg.github.com/skymavis/mavis-id-android")
}

Add the dependency to build.gradle:

dependencies {
implementation("com.skymavis.sdk:id:0.1.0")
}

Configure Android Manifest

Update your app's AndroidManifest.xml file with the redirect URI that you registered in the Developer Console:

<intent-filter android:label="id.open">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "deeplinkSchema://callback -->
<data android:scheme="${deeplink_Schema}" android:host="callback" />
</intent-filter>

Step 2. Initialize the SDK

Initialize the client:

val redirectUri = "mydapp://callback"
val clientId = "cbabcb00-9c99-404b-a6e4-c76b3b59f0d8"
val idOrigin = "http://id.skymavis.com"
val chainId = 2021
val rpcUrl = "https://saigon-testnet.roninchain.com/rpc"

client = Client(
idOrigin,
clientId,
rpcUrl,
chainId
)

Parameters:

  • redirectUri: the redirect URI registered in the Mavis ID settings in the Developer Console.
  • clientId: the client ID registered in the Mavis ID settings in the Developer Console.
  • idOrigin: the base URL of the Mavis ID service. Use https://id.skymavis.com for production and https://id.skymavis.one for testing.
  • chainId: the ID of the Ronin chain you want to connect to. Use 2021 for the Saigon testnet and 2020 for the Ronin mainnet.
  • rpcUrl: the RPC endpoint through which you want to connect to Ronin. The example uses a public endpoint for the Saigon testnet: https://saigon-testnet.roninchain.com/rpc. For more information, see RPC endpoints.

Step 3. Authorize users

Authorizes a user with an existing Mavis ID account, returning an ID token and the user's wallet address as part of an authorization response. If the user doesn't have an account, they're prompted to create one.

fun authorize(context: Context, redirectUri: String): String

Parameters:

  • context: the Android context of the app.
  • redirectUri: the redirect URI registered in the Mavis ID settings in the Developer Console.

Example:

// Request ID
val state = client.authorize(context, redirectUri)

// Parse the URI and create a Result object containing the response data
var result = Result.from(uri)

println("Is success: ${result.isSuccess}")
println("Method: ${result.method}")
println("Address: ${result.address}")
println("Data: ${result.data}")
println("State: ${result.state}")

Step 4. Validate the ID token

After receiving the ID token, validate it to ensure that the user has successfully authenticated. Then you can issue an access token to allow access to your server's resources. For more information, see Validate ID tokens.

Step 5. Interact with the wallet

Send transactions

Transfers RON tokens to a recipient's address, returning a transaction hash as part of a transaction response.

fun sendTransaction(context: Context, redirectUri: String, to: String, value: String): String

Parameters:

  • context: the Android context of the app.
  • redirectUri: the redirect URI registered in the Mavis ID settings in the Developer Console.
  • to: the recipient's address.
  • value: the amount of RON to send, specified in wei (1 RON = 10^18 wei).

Example: transfer 0.1 RON to the recipient address.

import com.skymavis.sdk.id.Client
import com.skymavis.sdk.id.Result

// Recipient address
val to = "0xD36deD8E1927dCDD76Bfe0CC95a5C1D65c0a807a";

// 0.1 RON in wei
val value = "1000000000000000000";

// Request ID
val state = client.sendTransaction(context, redirectUri, to, value);

// Parse the URI and create a Result object containing the response data
var result = Result.from(uri)

println("Is success: ${result.isSuccess}")
println("Method: ${result.method}")
println("Address: ${result.address}")
println("Data: ${result.data}")
println("State: ${result.state}")

Sign messages

Signs a plain text message, returning a signature in hex format as part of a transaction response.

fun signMessage(context: Context, redirectUri: String, message: String): String

Parameters:

  • context: the Android context of the app.
  • redirectUri: the redirect URI registered in the Mavis ID settings in the Developer Console.
  • message: the message to sign.

Example: sign the message accepting the terms and conditions.

// Message to sign
val message = "I accept the terms and conditions.";

// Request ID
val state = client.personalSign(context, redirectUri, message)

// Parse the URI and create a Result object containing the response data
var result = Result.from(uri)

println("Is success: ${result.isSuccess}")
println("Method: ${result.method}")
println("Address: ${result.address}")
println("Data: ${result.data}")
println("State: ${result.state}")

Sign typed data

Signs typed data structured according to the EIP-712 standard, returning a signature in hex format as part of a transaction response.

fun signTypeData(context: Context, redirectUri: String, typedData: String): String

Parameters:

  • context: the Android context of the app.
  • redirectUri: the redirect URI registered in the Mavis ID settings in the Developer Console.
  • typedData: a JSON string that specifies the EIP-712 typed structured data to be signed by the user.

Example: sign typed data for an order on Axie Marketplace.

// Typed data to sign
val typedData = """{"types":{"Asset":[{"name":"erc","type":"uint8"},{"name":"addr","type":"address"},{"name":"id","type":"uint256"},{"name":"quantity","type":"uint256"}],"Order":[{"name":"maker","type":"address"},{"name":"kind","type":"uint8"},{"name":"assets","type":"Asset[]"},{"name":"expiredAt","type":"uint256"},{"name":"paymentToken","type":"address"},{"name":"startedAt","type":"uint256"},{"name":"basePrice","type":"uint256"},{"name":"endedAt","type":"uint256"},{"name":"endedPrice","type":"uint256"},{"name":"expectedState","type":"uint256"},{"name":"nonce","type":"uint256"},{"name":"marketFeePercentage","type":"uint256"}],"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}]},"domain":{"name":"MarketGateway","version":"1","chainId":2021,"verifyingContract":"0xfff9ce5f71ca6178d3beecedb61e7eff1602950e"},"primaryType":"Order","message":{"maker":"0xd761024b4ef3336becd6e802884d0b986c29b35a","kind":"1","assets":[{"erc":"1","addr":"0x32950db2a7164ae833121501c797d79e7b79d74c","id":"2730069","quantity":"0"}],"expiredAt":"1721709637","paymentToken":"0xc99a6a985ed2cac1ef41640596c5a5f9f4e19ef5","startedAt":"1705984837","basePrice":"500000000000000000","endedAt":"0","endedPrice":"0","expectedState":"0","nonce":"0","marketFeePercentage":"425"}}""";

// Request ID
val state = client.signTypeData(context, redirectUri, typedData)

// Parse the URI and create a Result object containing the response data
var result = Result.from(uri)

println("Is success: ${result.isSuccess}")
println("Method: ${result.method}")
println("Address: ${result.address}")
println("Data: ${result.data}")
println("State: ${result.state}")

Call contracts

Executes a custom transaction on a smart contract, returning a transaction hash as part of a transaction response.

fun callContract(context: Context, redirectUri: String, contractAddress: String, data: String, value: String): String

Parameters:

  • context: the Android context of the app.
  • redirectUri: the redirect URI registered in the Mavis ID settings in the Developer Console.
  • contractAddress: the address of the smart contract on which to execute the transaction.
  • data: the transaction data to send to the smart contract, encoded as a hex string.
  • value: the amount of RON in wei (1 RON = 10^18 wei) to send along with the transaction. For non-payable smart contracts, the value is 0x0.

Example: allow another contract to spend 1 AXS on user's behalf.

// Contract address
val contractAddress = "0x3c4e17b9056272ce1b49f6900d8cfd6171a1869d";
// Data for approving 1 AXS
val data =
"0x095ea7b30000000000000000000000006b190089ed7f75fe17b3b0a17f6ebd69f72c3f630000000000000000000000000000000000000000000000000de0b6b3a7640000";
// No RON is being sent
val value = "0x0"
// Request ID
val state = client.callContract(
context,
redirectUri,
contractAddress,
data,
value
)

// Parse the URI and create a Result object containing the response data
var result = Result.from(uri)

println("Is success: ${result.isSuccess}")
println("Method: ${result.method}")
println("Address: ${result.address}")
println("Data: ${result.data}")
println("State: ${result.state}")

Utilities

Use the Result class to parse the deep links returned by the Mavis ID server and extract the response parameters.

import com.skymavis.sdk.id.Result

var result = Result.from(uri)

println("Is success: ${result.isSuccess}")
println("Method: ${result.method}")
println("Address: ${result.address}")
println("Data: ${result.data}")
println("State: ${result.state}")

Reference

Response types

Authorization response

The authorization response is returned after a user signs in to the app with Mavis ID.

Successful authorization
mydapp://callback?state=2ab49965-249a-48c7-896e-90967778383b&method=auth&version=1.0&type=success&data=ey...&address=0x16...ac

Response parameters:

  • state: a unique random identifier used to manage requests from the client to Mavis ID.
  • method: the method used for the request (auth).
  • version: the version of Mavis ID.
  • type: the response type (success).
  • data: the ID token that contains encoded user information.
  • address: the user's MPC wallet address.
Authorization error
mydapp://callback?state=84d18549-df10-451f-8235-184b594e3706&method=auth&version=1.0&type=fail&code=1000&message=%5BWALLET_USER_CANCEL%5D+User+rejected

Response parameters:

  • type: the response type (fail).
  • code: the error code.
  • message: a message describing the error.

Transaction response

The transaction response is returned after a user sends a transaction, signs a message, signs typed data, or calls a contract.

Successful transaction
mydapp://callback?state=0bccde82-01d5-4403-90fd-f8edcfdd2ed4&method=send&version=1.0&type=success&data=0x3a..0d

Response parameters:

  • state: a unique random identifier used to manage requests from the client to Mavis ID.
  • method: the method used for the request (send for transactions and sign for signing).
  • version: the version of Mavis ID.
  • type: the response type (success).
  • data: the transaction hash.
Transaction error
mydapp://callback?state=84d18549-df10-451f-8235-184b594e3706&method=send&version=1.0&type=fail&code=1000&message=%5BWALLET_USER_CANCEL%5D+User+rejected

Response parameters:

  • type: the response type (fail).
  • code: the error code.
  • message: a message describing the error.

FAQ

Where can I find the client ID?

To find your app's client ID, open the Developer Console, then click ID Service, and then in the Client credentials section, locate the CLIENT ID (APPLICATION ID) field.

Where can I find the chain ID?

The chain ID is 2020 for the Ronin mainnet and 2021 for the Saigon testnet.