Skip to main content

Ronin Waypoint Unity SDK v0.4.0

Overview

The Ronin Waypoint Unity SDK lets developers integrate the account and wallet features of the Ronin Waypoint service into Unity games deployed to mobile platforms (Android and iOS) and desktop platforms (Windows and macOS). After the integration, users can sign in to your game with their Ronin Waypoint account and connect their keyless wallet for instant in-game transactions.

User experience varies depending on the platform:

  • Mobile users interact with Ronin Waypoint through a native WebView.
  • Desktop users interact with Ronin Waypoint through an overlay window in the Mavis Hub app.

Whenever the implementation differs between platforms, this guide specifies the platform-specific steps.

GitHub repository: skymavis/waypoint-unity.

Features

  • Authorize users: let users sign in to your app with Ronin Waypoint to connect their keyless wallet and an optional externally owned account (EOA) wallet.
  • Send transactions: transfer RON, ERC-20 tokens, and make contract calls for in-game transactions.
  • Sign messages and typed data: have users sign messages and structured data to prove ownership of their wallet and authorize transactions.

Prerequisites

Unity version:

For desktop games distributed through Mavis Hub:

  • To distribute your game through Mavis Hub, contact your Sky Mavis point of contact.
  • Install Mavis Hub with latest version.
  • .Net v3.1 or later.

For mobile games:

Setup

Developer Console setup

  1. Register your app in the Developer Console and configure the mandatory Ronin Waypoint settings, including:
    • Redirect URI: the URI to which Ronin Waypoint redirects the user after authorization.
    • Origin URI: the URI from which your app sends requests to Ronin Waypoint.
  2. Copy the Client ID from the Developer Console to use in the initialization step.

For more information about these steps, see Setup and configuration.

Installation

Install a UPM package from the GitHub repository. For more information, refer to the Unity guide.

Platform-specific settings

  1. Go to Project Settings > Player > Settings for Android > Publishing Settings and select the following:

    • Custom Main Manifest
    • Custom Main Gradle Template
    • Custom Gradle Properties Template
  2. In the Assets/Plugins/Android directory of your Unity app, add required dependencies to the mainTemplate.gradle file:

    dependencies {
    implementation ("androidx.browser:browser:1.8.0")
    }

    Your mainTemplate.gradle file should look like this:

    apply plugin: 'com.android.library'
    **APPLY_PLUGINS**

    dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation ("androidx.browser:browser:1.8.0")
    **DEPS**}

    Gradle automatically downloads the required dependencies when building the app.

  3. Instruct Gradle to use the AndroidX libraries by adding the following line to your gradleTemplate.properties file:

    android.useAndroidX=true

    Your gradleTemplate.properties file should look like this:

    org-gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M
    org-gradle-parallel=true
    unityStreamingAssets=**STREAMING_ASSETS**
    android.useAndroidX=true
    **ADDITIONAL_PROPERTIES**

Initialization

Step 1. Initialize Ronin Waypoint

  1. After registering your app in the Developer Console, you receive a Client ID. Use this Client ID at the next step.

  2. Initialize the Ronin Waypoint client:

    Type:

    class WaypointSettings
    {
    string endpoint;
    string clientID;
    string deepLinkCallbackURL;
    struct Network
    {
    string rpcURL;
    int chainID;
    }
    };
    void SetUp(WaypointSettings settings)

    Parameters:

    • endpoint: the base URL of Ronin Waypoint for all API calls as https://waypoint.roninchain.com.
    • clientID: the client ID registered in the Developer Console.
    • deepLinkCallbackURL: the redirect URI registered in the Developer Console.
    • network: the config connection of Ronin network. Default is Mainnet.
      • rpcUrl: the RPC endpoint through which you want to connect to Ronin. In this example, the public RPC for the Saigon testnet https://saigon-testnet.roninchain.com/rpc. For other endpoints, see RPC endpoints.
      • chainId: the ID of the Ronin chain you want to connect to. Use 2021 for the Saigon testnet and 2020 for the Ronin mainnet.

    Example:

    void Start()
    {
    WaypointSettings settings = new WaypointSettings()
    {
    endpoint = "https://waypoint.roninchain.com",
    clientID = "${YOUR_CLIENT_ID}",
    deepLinkCallbackURL = "mydapp://open",
    network = new WaypointSettings.Network()
    {
    rpcURL = "https://saigon-testnet.roninchain.com/rpc",
    chainID = 2021
    }
    // or
    {/* network = WaypointSettings.Network.Testnet */}
    {/* network = WaypointSettings.Network.Mainnet */}
    };
    Waypoint.SetUp(settings)
    }

Step 2. Create a response listener

Ronin Waypoint returns responses to your app through a redirect URI that you registered in the Developer Console. For mobile platforms, the redirect URI is the deep link of your app.

To get response data from Ronin Waypoint, use the following method:

using System.Threading.Tasks;

private Task<string> WaitForResponse(string requestID)
{
var tcs = new TaskCompletionSource<string>();
Waypoint.ResponseReceived += Callback;
return tcs.Task;

void Callback(string state, string data)
{
if (state == requestID)
{
Waypoint.ResponseReceived -= Callback;
tcs.SetResult(data);
}
}
}

Parameters:

  • requestID: a unique random identifier used to manage requests from the client to Ronin Waypoint.

Returns:

  • responseData: the response data of Ronin Waypoint. For more information, see Response types.

Usage

User authorization

Initializes the authorization process, allowing a user to sign in or sign up for a Ronin Waypoint account, and connect their wallet. Returns an ID token and the user's addresses.

Diagrams for sign-in with Ronin Waypoint

Fresh sign-in with Ronin Waypoint:

Full sign-in flow:

  1. Use the Authorize function to log in to a Ronin Waypoint account, connect the user's wallet, and return an ID token and the user's wallet addresses.

    Type:

    string Authorize(string scope = null)

    Parameters:

    • scope: the OAuth 2.0 scope. The openid, profile, email, wallet scopes are available for authorization.
    More about scopes

    This table describes the scopes available for authorization with Ronin Waypoint.

    ScopeTypeDescription
    openidOIDCInforms the authorization server that your app is making an OpenID connect request. This is tied to the subject (sub) in the ID token, typically the user ID in Ronin Waypoint. Without this scope, the user can't authenticate.
    profileOIDCRequests access to the user's profile name. Without this scope, your app can't access this information.
    emailOIDCRequests the user's email address. Without this scope, your app can't access this information.
    walletCustomAn optional scope that allows your app to connect to the user's keyless wallet for blockchain transactions. Without this scope, your app can't access the wallet.

    The wallet scope behavior:

    • If wallet is included, then when the user signs up or signs in, they must create a keyless wallet or connect the existing wallet. Ronin Waypoint returns the ID token and the user's wallet address. The client can access the wallet for blockchain interactions.
    • If wallet is not included, then when the user signs up or signs in, they can skip creating a keyless wallet. Ronin Waypoint returns the ID token that the client can use to verify the user's identity and issue an access token. The client can request the user to create a keyless wallet later.

    Returns:

    Example:

    public async void OnAuthorizeClicked()
    {
    string scope = "email profile openid wallet";
    _responseId = Waypoint.Authorize(scope);
    string responseData = await WaitForResponse(_responseId);
    Debug.Log("Authorize response : " + responseData);
    }
  2. Verify the user with the ID token:

    1. After the user logs in with the Ronin Waypoint service, you need to verify the ID token data in your server. For more information, see Verify programmatically.
    2. Issue a new access token for the client.
    3. Optionally, get the user's profile by following the steps in Get user profile.

Wallet interactions

RON transfer

Use the SendNativeToken function to send RON tokens to a recipient's address. The function returns a transaction response containing the transaction hash.

Type:

string SendNativeToken(string receiverAddress, string value, string from = null)

Parameters:

  • receiverAddress: the recipient address.
  • value: the amount of RON to send, specified in wei (1 RON = 10^18 wei).
  • from (optional): the sender address of the transaction, used to check whether the current address in the game and address in the Ronin Waypoint popup are the same.

Example: transfer 0.1 RON to another address.

public async void OnSendRonClicked()
{
string receiverAddress = "0xD36deD8E1927dCDD76Bfe0CC95a5C1D65c0a807a";
string value = "100000000000000000";

_responseId = Waypoint.SendNativeToken(receiverAddress, value);
string responseData = await WaitForResponse(_responseId);
Debug.Log("Send response data in Unity : " + responseData);
}

Message signing

Use the PersonalSign function to sign plain text messages with the user's wallet. The function returns a transaction response containing the signature.

Type:

string PersonalSign(string message, string from = null)

Parameters:

  • message: the message to sign.
  • from (optional): the sender address of the transaction, used to check whether the current address in the game and address in the Ronin Waypoint popup are the same.

Example: sign the message accepting the terms and conditions.

public async void OnPersonalSignClicked()
{
string message = "Hello Axie Infinity";

_responseId = Waypoint.PersonalSign(message);
string responseData = await WaitForResponse(_responseId);
Debug.Log("Personal sign response: " + responseData);
}

Typed data signing

Use the SignTypedData function to sign typed data structured according to the EIP-712 standard, returning a transaction response containing the signature.

Type:

string SignTypedData(string typedData, string from = null)

Parameters:

  • typedData: a JSON string that specifies the EIP-712 typed structured data to be signed by the user.
  • from (optional): the sender address of the transaction, used to check whether the current address in the game and address in the Ronin Waypoint popup are the same.

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

public async void OnSignTypedDataClicked()
{

string 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""}}";

_responseId = Waypoint.SignTypedData(typedData);
string responseData = await WaitForResponse(_responseId);
Debug.Log("Sign typed data response " + responseData);
}

Contract function calls

Use the WriteContract function to execute a function on a smart contract, returning a transaction response containing the transaction hash.

Type:

string WriteContract(string contractAddress, string humanReadableABI, object functionParameters, string value = "0x0", string from = null)

Parameters:

  • contractAddress: the address of the smart contract on which to execute the transaction.
  • humanReadableABI: the Human-Readable ABI was introduced early by ethers, which allows for a Solidity signatures to be used to describe each method, event and error.
  • functionParameters: the values of the Human-Readable abi functions.
  • value (optional): 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.
  • from (optional): the sender address of the transaction, used to check whether the current address in the game and address in the Ronin Waypoint popup are the same.

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

public async void OnApproveErc20Clicked()
{
// Contract address
string contractAddress = "0x3c4e17b9056272ce1b49f6900d8cfd6171a1869d";
// Readable ABI string for the function
string readableAbi = "function approve(address _spender, uint256 _value)";
// Approve 1 AXS
var approveParams = new { _spender = "0x6B190089ed7F75Fe17B3b0A17F6ebd69f72c3F63", _value = 1000000000000000000 };
try
{
_responseId = Waypoint.WriteContract(contractAddress, readableAbi, approveParams);
string responseData = await WaitForResponse(_responseId);
Debug.Log(responseData);
}
catch (System.Exception e)
{
Debug.Log("Error in call contract: " + e.Message);
}

}

Reading smart contracts

Refer this example to read data from smart contracts using the Skynet REST API.

Important parameters:

  • ApiKey: your app's API key from the Developer Console.
  • ownerAddress: the user's keyless wallet address.

Reference

Function summary

FunctionDescription
AuthorizeSigns user in to Ronin Waypoint and returns their wallet address.
PersonalSignSigns plain text messages with the user's wallet.
SignTypeDataSigns structured data following the EIP-712 standard.
WriteContractExecutes functions on smart contracts.

Response types

Authorization response

For mobile platforms, Ronin Waypoint returns an authorization response directly to your game after a user connects their wallet.

For desktop platforms, Ronin Waypoint returns an authorization response to the Mavis Hub client, then the client returns the response to your game.

Authorization success

Mobile:

{
"state": "1a0c372a-efea-44a0-927f-80fabb8ecc2a",
"method": "auth",
"version": "1.1",
"type": "success",
"data": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjAxOGZjOTE0LWM5NTAtNzg1MS04MDBjLWEwMzZjNDM2ZDg1ZCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lkLnNreW1hdmlzLmNvbSIsInN1YiI6IjFlZjc5NzM1LWYyNjItNmJhNS1iMTQzLTQzMjI1MGJkNzBmOCIsImF1ZCI6WyI3MWMyZjhmZi0wZWJlLTQxOWQtYWNkMy1jOGViZDZkOWU2NzYiXSwiZXhwIjoxNzMyMDAxOTA1LCJuYmYiOjE3MzIwMDEzMDUsImlhdCI6MTczMjAwMTMwNSwianRpIjoiMDE5MzQzNTItOTI1ZS03ZTc0LTlhZjktMTY5ODFjYTRiZWQwIiwic2lkIjoiMDE5MmFlMDMtNmZkMC03NWVmLTgxZTUtZGU3NDJhOTE4MzI4IiwiZW1haWwiOiJkZW1vLXdheXBvaW50QHlvcG1haWwuY29tIiwic2NwIjoicHJvZmlsZSBvcGVuaWQgZW1haWwgd2FsbGV0Iiwicm9sZXMiOlsidXNlciJdfQ.cqbNEQRJG-1A8lcIlKjX7sEB_CckgccQnLgp_shhnnXJX72BLcTaiLWInl5x2gXk3VWsAPc7lmvv6CwMhnNzd_amD0t9vzDjz3hzLxu1ySKYEAIPCLwGRxRmgZvyZHv6I7hbNbVOeQYoE3gw2FrLhwvZWbmpqCRDBe_4BmXcyo9UgwYUP9jtz3OORiaZ3PlK7nP7w_OgAtP1ieEpOmy-fIjeJseytvmvulZhcCcKVzuMQMjDU_ruHG6rnC3NM3uywYso4JUATTEzCPoCliiKLjLAKsDerK_tYaD5eUleiGhhtjHVLXQAEOC7qgpY-9sZXkts2fCq829hxJ_snSUypCPLFZ31Z3mqDjUuTazRfC8LqczP-tjPC248dyxrnfGwWuyw-m3zwcZ5bbr6EuRD1ryiKxm8Xc4leGGDQXDdcJzrx1L5n6Acbpl_PNEVsbj3qN4G6BZRVlrDbdwZ7HlHkG9hM_MFK2uthRIdDaDJDa9ipvZfYz75S39WN1hM-a3w5yeU3N1UFOfxmzmor1Kp1QfjEDLocFMYYhEnI6eHnOtmI7N52xOQa5D4Fbc3XspNwSasXHn8MxKisGzqUXYNwa8fqkrBBfHPn61vdW4n3s9LKoMMUaXvMUZLTvDcRdDw2lcF-zA8-4SpvOL-a4siP6O_b23Bgbidntf0WQQc9ac",
"address": "0xB6679A20926E0F4bB71511AA70a94d2B4F7B6674",
"secondary_address": "0x68a8b3cd8164f3e0e6b0510d97208c518340bf38"
}

Response parameters:

  • state: a unique random identifier used to manage requests from the client to Ronin Waypoint.
  • method: the method used for the request (auth).
  • version: the version of the Ronin Waypoint service.
  • type: the response type (success).
  • data: the ID token that contains encoded user information.
  • address: the user's keyless wallet address.
  • secondary_address: the user's seed-phrase Ronin Wallet address, if linked by the user on the account management page. For more information, see Get user profile.

Desktop:

{
"type": "success",
"data": {
"idToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjAxOGZjOTE0LTJhMjgtNzJjNS04MDBjLTY2YTQyMzJiN2UzOSIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lkLnNreW1hdmlzLmNvbSIsInN1YiI6IjFlZjQyNzlmLTI2MzAtNjFjMi05MzYxLWYxNDVkZDEyOTIyNyIsImF1ZCI6WyJlYzYyYzA2Zi0xZTU2LTQ0ZGEtODY2NS00OTNkMWJiNTY5NWYiXSwiZXhwIjoxNzMyMDAyMjU4LCJuYmYiOjE3MzIwMDE5NTgsImlhdCI6MTczMjAwMTk1OCwianRpIjoiMDE5MzQzNWMtODhiNi03YzlhLTkxMGYtMzY0ODFiMGRiYjQ5Iiwic2lkIjoiYXBwLm1hdmlzaHViLnNlc3Npb24iLCJlbWFpbCI6ImhvYV9uZXdfMUB5b3BtYWlsLmNvbSIsInJvbGVzIjpbInVzZXIiXX0.fcsfGTSpyb1jKPvSi6hHfS13p53tUNHeSi7tncoe4Qodr0nsrz4UqD3KDjgSGjypioUZnZMbwYadT2FPNRea2EPityHNC-i42kYiwcmfpBkt0ePPN7MU2giul1guPoz4b-h-HoqCot9Uof0z07TGTxV63UJJS7N7ZkcHvrjINZ3UeGNgzGZkB6BG_tKEKj-No9mAzz65Ufr8FePzZTpItJl7mxI-HqtmZbVjpE6Ve0uE46YPJYjoXxIwj7nq_eY-nMux7zlBtNvE5Nsq_82WKWPwPw_PkWepOUcTqUmUL8jtWozz8Ic8k7jNQai62FF77ia_Pib0Qx_gYxM7kiZM87C4-5kDvyHVs1Zq-slZfIeujuHgimmdSX2x1YvX1SlqeYeauJuTm5WtZSQvpFaWZMmCUNs-xXT-wMBJzj9mrwjDKBYHS14x36myP9bHVHvDEFR3gvfiUR5GZSSIY0yUmpkMMk41LV6-cNxPJaeMmLIfxmEr1f3_t0Voq0u72V1LxxwWhw0Z9bpMxHUKEMheOrMSBegVG3l7fBjaLAkXygVs7APcESeUHVBhW6Kw78qabjJpGquJ3ALbSmk_R9GKosqOB6_gUxpZLAUqxXwQGKnC8jUpLd20FPmw9SYcIrozaO1tchY1TLcW-Sb942xkMmg6Z7RwjsdfMrBtglhXs1M",
"accountWallet": {
"identity": "0x2a6d85390073026307b91754f791b2abfe25cd28",
"secondary": ""
}
}
}

Response parameters:

  • state: a unique random identifier used to manage requests from the client to Ronin Waypoint.
  • type: the response type (success).
  • idToken: the ID token that contains encoded user information.
  • identity: the user's keyless wallet address.
  • secondary: the user's seed-phrase Ronin Wallet address, if linked by the user on the account management page. For more information, see Get user profile.
Authorization error
{
"state": "84d18549-df10-451f-8235-184b594e3706",
"method": "auth",
"version": "1.1",
"type": "fail",
"code": "1000",
"message": "[WALLET_USER_CANCEL] User rejected"
}

Response parameters:

  • type: the response type (fail).
  • code: the error code.
  • message: a message describing the error. For more information, see Error codes.

Transaction response

Ronin Waypoint returns a transaction response after a user sends a transaction, signs a message, signs typed data, or calls a contract on the blockchain.

Transaction success

Mobile:

{
"state": "35722876-40a7-4cab-98c6-87cb43d633a5",
"method": "send",
"version": "1.1",
"type": "success",
"data": "0xca6c4b5d18cbf1d92ea5caf8de434b70dc1a412a1f23caa8d45aae319d2d84eb"
}

Response parameters:

  • state: a unique random identifier used to manage requests from the client to Ronin Waypoint.
  • method: the method used for the request (send for transactions and sign for signing).
  • version: the version of the Ronin Waypoint service.
  • type: the response type (success).
  • data: the transaction hash.

Desktop:

{
"type": "success",
"data": "0xa27d79e3be21a677c03f6dba0b081ed047055a78aeb9938bb423800f94ddf09c"
}

Response parameters:

  • type: the response type (success).
  • data: the transaction hash.
Transaction error
{
"state": "84d18549-df10-451f-8235-184b594e3706",
"method": "auth",
"version": "1.1",
"type": "fail",
"code": "1000",
"message": "[WALLET_USER_CANCEL] User rejected"
}

Response parameters:

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

See also