Skip to main content

Sign-In with Ronin

Overview

This guide shows you how to integrate "Sign-In with Ronin" into your dApp. "Sign-In with Ronin" is a standard extended from Sign-In with Ethereum (SIWE) to help users sign in to your dApp easily, providing a better user experience and improved security.

From the end user's perspective, the sign-in process is as follows:

  1. Connect Ronin Wallet: The user connects their Ronin Wallet to your dApp.
  2. Accept terms of service: The user accepts your terms of service by signing a message with their Ronin Wallet.
  3. Solve the challenge: The user solves a security challenge to prove they are human.
1. Connect Ronin Wallet2. Accept terms of service

Prerequisites

npm or yarn for package installation.

Steps

Step 1. Install SIWE

The only dependency is the siwe package. It helps you generate a formatted sign-in message more easily.

  1. Install the package using yarn or npm:
yarn add siwe@1.1.6 ethers@5.6.9
npm i siwe@1.1.6 ethers@5.6.9
  1. Import the package in your component:
import { SiweMessage } from "siwe";

Step 2. Generate a SIWE message

Using the SiweMessage class, you can generate a formatted sign-in message. The message includes the following parameters:

  • domain: The domain of your dApp.
  • address: The user's Ronin address.
  • uri: The URI of your dApp.
  • version: The version of the SIWE message.
  • chainId: The chain ID of the network. For the Ronin mainnet, use 2020. For the Saigon testnet, use 2021.
  • nonce: A unique nonce for the message.
  • statement: The terms of service that the user agrees to.
  • expirationTime: The expiration time of the message.

The following code snippet shows how to generate a SIWE message:

Live Editor
function SIWERequest() {
  const [signature, setSignature] = useState()
  
  async function onClickSignIn() {
    const provider = window.ronin.provider
    const accounts = await provider.request({ method: "eth_requestAccounts" })
    if(!accounts) {
      return
    }
    const currentAccount = accounts[0]
  
    const currentDate = new Date()
    currentDate.setDate(currentDate.getDate() + 1)
    
    const siweMessage = new SiweMessage({
      domain: window.location.hostname,
      address: currentAccount,
      uri: window.location.origin,
      version: "1",
      chainId: 2020,
      nonce: "12345678",
      statement:
        "I accept the dApp's Terms of Service: https://example-dapp.com/terms-of-use",
      expirationTime: currentDate.toISOString(),
    })

    const sig = await provider.request({ method: "personal_sign", params: [siweMessage.toMessage(), currentAccount]})
    setSignature(sig)
  }
  
  if (signature) {
    return (
      <div>
        <div>🎉 Congratulations! You are signed in.</div>
        <button onClick={() => setSignature(undefined)}>Reload</button>
      </div>
    )
  }
  
  return (
    <button onClick={onClickSignIn}>Sign in with Ronin</button>
  )
}
Result
Loading...