v2

Bine Auth protocol based on SIWE (Sign In With Ethereum)

Introduction

Bine API provides a SIWE (Sign In With Ethereum) authentication mechanism, allowing users to authenticate using their Ethereum wallets. This authentication method is secure, decentralized, and does away with traditional usernames and passwords.

Prerequisites

Ensure you have an Ethereum wallet, such as MetaMask or WalletConnect.

Login

All other documentation (User API and Developer API) assumes that the user is authorized and the cookie is provided.

Step 1: Retrieve the nonce

To initiate the authentication process, clients should first request a nonce value.

Query:

query AuthNonce {
  authNonce {
    __typename
    ... on AuthNonceOk {
      result
    }
    ... on Error {
      message
    }
  }
}

Response:

{
    "__typename": "NonceResponse"
    "result": "ghQwRYCzcpt"
}

Upon calling this query, the server will also set an auth_token cookie in the response. You should keep that cookie and send it in every GraphQL request.

Errors:

Two possible errors may occure:

{
    "__typename": "AuthError"
    "message": "Invalid or expired session cookie"
}
{
    "__typename": "AuthError"
    "message": "Already authenticated"
}

Step 2: Sign the nonce using your Ethereum wallet

Once you have the nonce, use your Ethereum wallet to sign a message containing the nonce. The exact method will vary based on your wallet's interface. Check Siwe Github Page for more information. Example of the message object:

{
    "domain": "app.bine.games",
    "address": "<address>",
    "statement": "Bine Games wants you to sign in with your wallet.",
    "uri": "https://app.bine.games",
    "version": "1",
    "chainId": 1,
    "nonce": "kjNBEqFTkPc",
    "issuedAt": "2023-08-09T11:48:36.694Z"
}

Step 3: Send the signed message for verification

After signing the message, send both the message string and the signature to Bine API for verification.

Mutation:

mutation Login($message: SiweMessageInput!, $signature: String!) {
  login(message: $message, signature: $signature) {
    __typename
    ... on LoginOk {
      result
    }
    ... on Error {
      message
    }
  }
}

Variables:

{
    "message": {
        "domain": "app.bine.games",
        "address": "<address>",
        "statement": "Bine Games wants you to sign in with your wallet.",
        "uri": "app.bine.games",
        "version": "1",
        "chainId": 1,
        "nonce": "kjNBEqFTkPc",
        "issuedAt": "2023-08-09T11:48:36.694Z"
    },
    "signature": "<signature in hex>"
}

Headers:

Cookie: auth_token=<your_cookie_value>

Response:

{
    "__typename": "LoginOk",
    "result": "Logged in"
}

Additionally to success response, an auth_token cookie will be provided in Set-Cookie response header. It should be set to Cookie response header. Read more on how HTTP cookies work here.

Errors:

Four possible errors may occure:

Reason for Invalid signature could be:

InvalidSignature
ExpiredMessage
NotYetValidMessage
DomainMismatch
NonceMismatch
{
    "__typename": "ValidationError"
    "message": "Invalid signature (<reason>)"
}
{
    "__typename": "ValidationError"
    "message": "Should provide a session cookie"
}
{
    "__typename": "AuthError"
    "message": "Invalid or expired session cookie"
}
{
    "__typename": "AuthError"
    "message": "Already authenticated"
}

Logout

Mutation:

mutation Logout {
  logout {
    __typename
    ... on LogoutOk {
      result
    }
    ... on Error {
      message
    }
  }
}

Headers:

Cookie: auth_token=<your_cookie_value>

Response:

{
    "__typename": "SiweLogoutOk",
    "result": "Logged out"
}

Errors:

Three possible errors may occure:

{
    "__typename": "ValidationError"
    "message": "Should provide a session cookie"
}
{
    "__typename": "AuthError"
    "message": "Invalid or expired session cookie"
}
{
    "__typename": "AuthError"
    "message": "Not authenticated"
}

Further Reading & Resources

Last updated