Skip to content
Information Circle

The Spanning Demo App is live! Check it out here:

We have also published the open-source demo code and related JavaScript utilities.

Off-Chain / Web App Spanning Requests

Sending messages (including raw data and contract execution requests) across chains is fundamental to any multichain Dapp.

To do so, we can use the makeRequest function of the Spanning Delegate on your current chain. This can be made directly to the Delegate contract from an EOA (Externally Owned Account) via a web app by following the guide below.

This function takes in two arguments:


The programAddress is the Spanning Address of the contract you want to reach. This can be a contract on the same network or any deployable chain on the Spanning Network. The programAddress' domain information tells the Spanning Network what network to send the request to, the local network address information tells the Spanning Network where to give the request on that network, and the buffer information can include additional routing information (like how many block confirmations to wait before sending the request to the destination chain).


The payload is the encoded ABI function call to execute at the programAddress. This can be any generic function call on any contract.

Example Request

Here is some sample code for how to make a Spanning Request from your web app.

First, we have to define the Spanning Delegate contract instances we want to talk to. We can look at how this is done in one of the Spanning Labs demo apps in the constants file.

We then have to create an instance of the Spanning Delegate contract to act on based on the smart contract ABI.

The contract instance can now be created with:

import { ethers } from "ethers";
import { useContractFunction } from "@usedapp/core";
import {
} from "@spanning/utils";
import {
  networkIds, // network IDs are from
} from "../constants/chains"; // Update your path here
import delegateAbi from "../constants/delegateAbi.json"; // Update your path here

const delegateContract = new ethers.Contract(
      getDelegateAddress(networkIds.get(“Avalanche Fuji”)!), // Update your desired network ID here

Now that the contract instance is created, we want to create a hook for calling the Delegate's makeRequest function:

const { state, makeRequest } = useContractFunction(delegateContract, “makeRequest”, {
    transactionName: “makeRequest”,

Finally, we can send a request with:

// Get data for the transaction
const payload = toAbi(
  “foo”, // Replace with your desired function header
  [“bytes32”, “uint256"], // Replace with your desired argument types
  [bar, baz] // Replace with your desired function arguments
// Execute the transaction
makeRequest(programAddress, payload); // Update to your desired programAddress here