Sign Message and Verify

Sign and verify challenges for off-chain authentication

Note that Blocto SDK for EVM-compatible chains is still in Beta. APIs are subject to breaking changes.

Install from npm/yarn

$ yarn add @blocto/sdk

Use web3.js

import Web3 from "web3";
import BloctoSDK from "@blocto/sdk";

const bloctoSDK = new BloctoSDK({
  ethereum: {
    chainId: "0xa4b1", // (required) chainId to be used
    rpc: `https://rpc.ankr.com/arbitrum` // (required for Ethereum) JSON RPC endpoint
  }
});

const web3 = new Web3(bloctoSDK.ethereum);

const handleSignMessage = () => {
  web3.eth.sign(message, address);
};

Verify Signature (personal.sign)

For dApps relying on signMessage for off-chain authentication, Blocto follows ERC-1271 and ERC-191. To verify the signature, you need to call an isValidSignature method on the wallet contract to check if the signature came from the rightful owner of the wallet contract.

We have built the tools to carry out this verification:

Use it in your dApps (usually on backend):

Don't forget to update the RPC URL to current network.

package main

import (
	"log"
	"net/http"

	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/blocto/dappauth"
)

// AuthenticationHandler ..
type AuthenticationHandler struct {
	client *ethclient.Client
}

// NewAuthenticationHandler ..
func NewAuthenticationHandler(rawurl string) (*AuthenticationHandler, error) {
	client, err := ethclient.Dial(rawurl)
	if err != nil {
		return nil, err
	}
	return &AuthenticationHandler{client: client}, nil
}

// ServeHTTP serves just a single route for authentication as an example
func (a *AuthenticationHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

	challenge := r.PostFormValue("challenge")
	signature := r.PostFormValue("signature")
	addrHex := r.PostFormValue("addrHex")

	authenticator := dappauth.NewAuthenticator(r.Context(), a.client)
	isAuthorizedSigner, err := authenticator.IsAuthorizedSigner(challenge, signature, addrHex)
	if err != nil {
		// return a 5XX status code
	}
	if !isAuthorizedSigner{
		// return a 4XX status code
	}

	// create an authenticated session for address
	// return a 2XX status code
}

func main() {
	handler, err := NewAuthenticationHandler("https://arb-mainnet-public.unifra.io")
	if err != nil {
		log.Fatal(err)
	}

	log.Fatal(http.ListenAndServe(":8080", handler))
}

Sample Code

PersonalSign Technical Details

According to ERC-191 and ERC-1271, when receiving personalSign request with message, Blocto will sign:

0x19 + 0x0 + [User’s wallet address] + hash(0x19 + 0x45 (E) + thereum Signed Message: + len(message) + message)

Verify Signature (typed data sign)

According to ERC-191 and ERC-1271, when receiving typeDataSign request, Blocto will sign:

0x19 + 0x0 + [User’s wallet address] + [typed-data-hash]

Last updated