Comment on page

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: `` // (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 (
// 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("")
if err != nil {
log.Fatal(http.ListenAndServe(":8080", handler))
const Web3 = require('web3');
const DappAuth = require('@blocto/dappauth');
const dappAuth = new DappAuth(new Web3.providers.HttpProvider(''));
async function debug() {
const challenge = 'foo';
const signature =
const address = '0x86aa354fc865925f945b803ceae0b3f9d856b269';
try {
const isAuthorizedSigner = await dappAuth.isAuthorizedSigner(
console.log(isAuthorizedSigner); // true
} catch (e) {


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]

Sample Code