Authorize wallet

To ensure the security and integrity of transactions, our API requires to authorize wallet before initiating any bridging operations. This process involves signing a message with wallet, which establishes a protected working session. This step is crucial for maintaining the security of transactions.

Get message to sign

Firstly, message to sign should be requested from our backend.

Returns the message to be signed by a wallet.

GET /api/wallet_auth/message

{​
  "message": "string",​
  "data": {​
    "types": {},​
    "primaryType": "string",​
    "domain": {​
      "name": "string",​
      "version": "string"​
    },​
    "message": {}​
  }​
​}

Sign received message using a wallet

Once message to sign object received, it has to be signed by web3 wallet using a custom code on the caller side. Here is an example of message signing:

import { TypedData } from "starknet";
import axios, { AxiosResponse } from "axios";
import { ethers, JsonRpcProvider } from 'ethers';

interface ApiResponse<T> {
  message: string;
  data: T;
}

type AppTypedData = TypedData & {
  message:{ value: string; }
};

type GetVerifyMessageResponse = ApiResponse<AppTypedData>

//Required variables
const privateKey = 'YOUR_PRIVATE_KEY';
const walletAddress = 'WALLET_ADDRESS_FOR_PRIVATE_KEY'
const rpcUrl = 'SOURCE_NETWORK_RPC_URL';

export const getTypedDataWithAddress = (
  appData: AppTypedData,
  address: string
): AppTypedData => {

  appData.message.value = `${appData.message.value}\n${address}`;
  return appData;
};

const getSignMessage = async (): Promise<AppTypedData> => {
    const url = `/api/wallet_auth/message`;
    const response: AxiosResponse<GetVerifyMessageResponse> = await axios.get(url);

    return response.data.data;
}

const signTypedData = async (
    data: AppTypedData,
    privateKey: string,
    rpcUrl: string,
  ): Promise<ethers.SignatureLike> => {
    const provider = new JsonRpcProvider(rpcUrl);
    const wallet = new ethers.Wallet(privateKey, provider);
    const typedData = getTypedDataWithAddress(data, wallet.address);
    const signature = await wallet.signMessage(typedData.message.value);

    return signature;
}

const getSignedMessage = async (): Promise<ethers.SignatureLike> => {
  const message = await getSignMessage()
  const signature = await signTypedData(message, privateKey, rpcUrl)

  return signature;
}

Establish protected session

Signed message has to be sent to API to validate signature and establish protected session. Upon successful validation, you will receive a response with cookies in the headers. Save them for future use.

Validates signed message and returns session cookies in the header.

POST /api/wallet_auth/message

Request Body

Here is a code sample to showcase how to retrieve and store cookies:

//..

const validateSignedMessage = async (
    wallet_address: string, //your wallet address
    network_type: string, //source network type
    signature: ethers.SignatureLike, //signature from code above
  ) => {
    const url = `/api/wallet_auth/message`;

    const response = await axios.post(url, {
      wallet_address,
      network_type,
      signature: signature,
    });
    const cookie = response.headers['set-cookie'];

    return cookie;
}

const walletCookies: Record<string, string[]> = {};
  
const signMessage = async (
    fromNetwork: string, //source network type
  ) => {
    const message = await getSignMessage();

    const signature = await signTypedData(message, privateKey, rpcUrl);

    const cookies = await validateSignedMessage(
      walletAddress,
      fromNetwork,
      signature,
    );

    if (!cookies) {
      throw new Error(`Cookies don't exist`);
    }

    walletCookies[walletAddress] = cookies;
}

//..

Validate active session

To enhance user convenience and reduce the frequency of signing messages for each bridge operation, the system allows for a verification check to determine if a wallet is already authorized.

Allows to check whether wallet is already authorized via message signature.

GET /api/wallet_auth/wallet/{wallet_address}

Path Parameters

Headers

Here is a code sample of how to use cookies to validate active session:

//..

const checkWallet = async (
    wallet_address: string,
    network_type: string,
    walletCookie?: string[],
  ) => {
    const url = `/api/wallet_auth/wallet/${wallet_address}`;

    await axios.get(url, {
      headers: { ["network-type"]: network_type, cookie: walletCookie },
    });
  }

const isAuthWallet = async (
    address: string,
    network_type: string,
    walletCookies?: string[],
  ): Promise<boolean> => {
    try {
      await checkWallet(
        address,
        network_type,
        walletCookies,
      );
      return true;
    } catch (error) {
      return false;
    }
}

//..

Upon successfully completing the wallet authorization steps, the stage is set to proceed to the next step - Get Supported Networks. This marks the readiness to explore and interact with the variety of networks supported by the service.

Last updated