> ## Documentation Index
> Fetch the complete documentation index at: https://docs.near.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Signing Transactions

> Learn how to sign transactions across multiple blockchains.

export const Github = ({url, start, end, fname, withSourceLink = true}) => {
  const [code, setCode] = useState(null);
  function toRaw(ref) {
    const fullUrl = ref.slice(ref.indexOf('https'));
    const [url] = fullUrl.split('#');
    const [org, repo, , branch, ...pathSeg] = new URL(url).pathname.split('/').slice(1);
    return `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${pathSeg.join('/')}`;
  }
  async function fetchCode(url, fromLine, toLine) {
    let res;
    if (typeof window !== 'undefined') {
      const validUntil = localStorage.getItem(`${url}-until`);
      if (validUntil && Number(validUntil) > Date.now()) {
        res = localStorage.getItem(url);
      }
    }
    if (!res) {
      try {
        res = await (await fetch(url)).text();
        if (typeof window !== 'undefined') {
          localStorage.setItem(url, res);
          localStorage.setItem(`${url}-until`, String(Date.now() + 60000));
        }
      } catch {
        return 'Error fetching code, please try reloading';
      }
    }
    let body = res.split('\n');
    const from = fromLine ? Number(fromLine) - 1 : 0;
    const to = toLine ? Number(toLine) : body.length;
    body = body.slice(from, to);
    const precedingSpace = body.reduce((prev, line) => {
      if (line.length === 0) return prev;
      const spaces = line.match(/^\s+/);
      if (spaces) return Math.min(prev, spaces[0].length);
      return 0;
    }, Infinity);
    return body.map(line => line.slice(precedingSpace === Infinity ? 0 : precedingSpace)).join('\n');
  }
  function buildSourceUrl(url, start, end) {
    const base = url.split('#')[0];
    if (start && end) return `${base}#L${start}-L${end}`;
    if (start) return `${base}#L${start}`;
    return base;
  }
  useEffect(() => {
    const rawUrl = toRaw(url);
    fetchCode(rawUrl, start, end).then(res => setCode(res));
  }, [url, start, end]);
  const sourceUrl = buildSourceUrl(url, start, end);
  const startLine = start ? Number(start) : 1;
  const fileName = fname ?? sourceUrl.split('/').pop();
  return <div className="rounded-[0.625rem] border border-[#d0d7de] dark:border-[#30363d] overflow-hidden my-5 text-[0.8125rem] font-mono shadow-sm dark:shadow-[0_4px_24px_rgba(0,0,0,0.18)]">

      {}
      <div className="flex items-center justify-between py-2 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-b border-[#d0d7de] dark:border-[#30363d]">
        <div className="flex items-center gap-2 text-[#656d76] dark:text-[#8b949e]">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor">
            <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z" />
          </svg>
          <span className="text-xs font-medium text-[#1f2328] dark:text-[#e6edf3]">
            {fileName}
          </span>
        </div>
        {start && end && <span className="text-[0.6875rem] text-[#656d76] dark:text-[#8b949e] bg-[#eaeef2] dark:bg-[#21262d] border border-[#d0d7de] dark:border-[#30363d] rounded-full py-0.5 px-2">
            Lines {start}–{end}
          </span>}
      </div>

      {}
      <div className="overflow-auto max-h-[480px] bg-white dark:bg-[#0d1117] [&_tr]:border-b-0 [&_td]:border-b-0">
        {code === null ? <div className="py-5 px-4 text-xs text-[#656d76] dark:text-[#6e7681]">
            Loading...
          </div> : <table className="w-full border-collapse leading-[1.6]">
            <tbody>
              {code.split('\n').map((line, i) => <tr key={i} className="align-top border-0">
                  <td style={{
    minWidth: '60px'
  }} className="select-none pl-2 pr-3 text-right text-[0.7rem] text-[#8c959f] dark:text-[#3d444d] w-[1%] whitespace-nowrap border-r border-0 border-r-[#d0d7de] dark:border-r-[#21262d]">
                    {startLine + i}
                  </td>
                  <td className="pl-4 pr-6 text-[0.8125rem] text-[#1f2328] dark:text-[#e6edf3] whitespace-pre">
                    {line || ' '}
                  </td>
                </tr>)}
            </tbody>
          </table>}
      </div>

      {}
      {withSourceLink && <div className="flex justify-end py-1.5 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-t border-[#d0d7de] dark:border-[#21262d]">
          <a href={sourceUrl} target="_blank" rel="noreferrer noopener" className="text-[0.6875rem] font-medium text-[#656d76] dark:text-[#8b949e] no-underline flex items-center gap-[0.3rem] hover:text-[#1f2328] dark:hover:text-[#e6edf3] transition-colors">
            View on GitHub
            <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
              <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
              <polyline points="15 3 21 3 21 9" />
              <line x1="10" y1="14" x2="21" y2="3" />
            </svg>
          </a>
        </div>}
    </div>;
};

Chain signatures enable NEAR accounts, including smart contracts, to sign and execute transactions across many blockchain protocols.

This unlocks the next level of blockchain interoperability by giving ownership of diverse assets, cross-chain accounts, and data to a single NEAR account.

<Accordion title="Supported Networks">
  While you can sign transactions for any network using Eddsa or Ecdsa keys, each chain signs transactions differently.

  Our example implementation shows you how to sign transactions for: Bitcoin, Solana, Cosmos, XRP, Aptos, Sui and EVM networks (Ethereum, Base, BNB Chain, Avalanche, Polygon, Arbitrum, and more).
</Accordion>

***

## Create a Chain Signature

There are five steps to create a Chain Signature:

1. [Deriving the Foreign Address](#1-deriving-the-foreign-address) - Derive the address that will be controlled on the target blockchain.
2. [Creating a Transaction](#2-creating-the-transaction) - Create the transaction or message to be signed.
3. [Requesting a Signature](#3-requesting-the-signature) - Call the NEAR MPC contract requesting it to sign the transaction.
4. [Formatting the Signature](#4-formatting-the-signature) - Format the signature from the MPC contract and add it to the transaction.
5. [Relaying the Signed Transaction](#5-relaying-the-signed-transaction) - Send the signed transaction to the destination chain for execution.

<img src="https://mintcdn.com/neardocs/qO2GD-gji1aakHqN/assets/docs/welcome-pages/chain-signatures-overview.png?fit=max&auto=format&n=qO2GD-gji1aakHqN&q=85&s=506f121798ea7a7618296f1a1a811dd9" alt="chain-signatures" width="2478" height="523" data-path="assets/docs/welcome-pages/chain-signatures-overview.png" />

*Diagram of a chain signature in NEAR*

The [chainsig.js](https://github.com/NearDeFi/chainsig.js) library provides a convenient interface for completing each of these steps.

<Tip>
  For building transactions inside of NEAR smart contracts written in Rust, you can use the [Omni Transaction](https://github.com/near/omni-transaction-rs) library to easily build transactions for different blockchains (like Bitcoin and Ethereum).
</Tip>

<Info>
  **MPC Contracts**

  There is an [MPC contract](https://github.com/Near-One/mpc/tree/main/libs/chain-signatures/contract) available on both `mainnet` and `testnet`:

  * Mainnet: `v1.signer`
  * Testnet: `v1.signer-prod.testnet`

  The MPC network is made up of 8 nodes.
</Info>

***

## Chain Signatures Contract

To interact with the chain signatures library you first need to instantiate a `ChainSignaturesContract`.

<Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/config.js#L53-L56" start="53" end="56" />

The `networkId` and `contractId` are set to the values specified in the previous section depending which network you are on.

***

## Chain Adapters

To interact with a specific chain, you need to instantiate the relevant `chainAdapter`.

<Tabs>
  <Tab title="Ξ EVM">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/EVM/EVM.jsx#L40-L47" start="40" end="47" />

    The EVM chain adapter takes the `ChainSignaturesContract` as an argument as well as `publicClient` which is constructed from an EVM RPC URL.

    <Tip>
      To use different EVM networks, simply specify the RPC URL for your desired network.
      The example demonstrates compatibility with multiple EVM-compatible networks including Ethereum, Base, BNB Chain, Avalanche, Polygon, Arbitrum, zkSync, and many others.
      You can find RPC URLs for various networks at [ChainList](https://chainlist.org/?testnets=true).
    </Tip>
  </Tab>

  <Tab title="₿ Bitcoin">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Bitcoin.jsx#L10-L18" start="10" end="18" />

    The Bitcoin chain adapter takes the `ChainSignaturesContract` as an argument as well as the `network` ("mainnet", "testnet" or "regtest") and a `btcRpcAdapter` which handles communication with the Bitcoin network.
  </Tab>

  <Tab title="◎ Solana">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Solana.jsx#L12-L17" start="12" end="17" />

    The Solana chain adapter takes the `ChainSignaturesContract` as an argument as well as a `connection` which is constructed from a Solana RPC URL. If you want to use Mainnet, then you need to choose a Mainnet RPC.
  </Tab>

  <Tab title="◉ XRP">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/XRP.jsx#L11-L14" start="11" end="14" />

    The XRP chain adapter takes the `ChainSignaturesContract` as an argument as well as an `rpcUrl` for the XRP Ledger and the `rpcURl` specification. For testnet, use `https://s.altnet.rippletest.net:51234`.
  </Tab>

  <Tab title="◈ SUI">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Sui.jsx#L13-L20" start="13" end="20" />

    The SUI chain adapter takes the `ChainSignaturesContract` as an argument as well as a `connection` which is a SuiClient constructed from a SUI RPC URL.
  </Tab>

  <Tab title="⬟ Aptos">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Aptos.jsx#L12-L21" start="12" end="21" />

    The Aptos chain adapter takes the `ChainSignaturesContract` as an argument as well as a `nodeUrl` for the Aptos network and the `network` specification.
  </Tab>
</Tabs>

***

## 1. Deriving the Foreign Address

Chain Signatures use [`derivation paths`](../chain-signatures#derivation-paths-one-account-multiple-chains) to represent accounts on the target blockchain. The foreign address to be controlled can be deterministically derived from:

* The NEAR account calling the MPC contract (e.g., `example.near`, `example.testnet`, etc.)
* A derivation path (a string such as `ethereum-1`, `ethereum-2`, etc.)
* The MPC service's master public key (we don't need to worry about this as it is defined in the library we're using).

To derive the address call the `deriveAddressAndPublicKey` method passing the near account Id from which the address is being derived and the derivation path.

<Tabs>
  <Tab title="Ξ EVM">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/EVM/EVM.jsx#L98-L101" start="98" end="101" />
  </Tab>

  <Tab title="₿ Bitcoin">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Bitcoin.jsx#L49-L52" start="49" end="52" />
  </Tab>

  <Tab title="◎ Solana">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Solana.jsx#L47-L50" start="47" end="50" />

    On Solana, your address is the same as your public key.
  </Tab>

  <Tab title="◉ XRP">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/XRP.jsx#L45-L48" start="45" end="48" />
  </Tab>

  <Tab title="◈ SUI">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Sui.jsx#L51-L54" start="51" end="54" />
  </Tab>

  <Tab title="⬟ Aptos">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Aptos.jsx#L52-L55" start="52" end="55" />
  </Tab>
</Tabs>

<Info>
  The same NEAR account and path will always produce the same address on the target blockchain.

  * `example.near` + `ethereum-1` = `0x1b48b83a308ea4beb845db088180dc3389f8aa3b`
  * `example.near` + `ethereum-2` = `0x99c5d3025dc736541f2d97c3ef3c90de4d221315`
</Info>

***

## 2. Creating the Transaction

To construct the transaction to be signed use the method `prepareTransactionForSigning`.

<CodeGroup>
  <Tab title="Ξ EVM">
    Constructing a transaction to transfer ETH is very simple. The `value` is the amount of ETH in Wei as type BigInt (1 ETH = 10<sup>18</sup> Wei).

    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/EVM/Transfer.jsx#L17-L21" start="17" end="21" />

    This method returns the `unsigned transaction` and the transaction `hash(es)` (also known as the `payload`).
  </Tab>

  <Tab title="₿ Bitcoin">
    Constructing a transaction to transfer BTC is very simple. The `value` is the amount of BTC in satoshis as a string (1 BTC = 100,000,000 sats).

    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Bitcoin.jsx#L71-L77" start="71" end="77" />

    This method returns the `unsigned transaction` and the transaction `hash(es)` (also known as the `payload`).
  </Tab>

  <Tab title="◎ Solana">
    Constructing a transaction to transfer SOL is very simple. The `value` is the amount of SOL in lamports as type BigInt (1 SOL = 1,000,000,000 lamports).

    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Solana.jsx#L65-L71" start="65" end="71" />

    This method returns the `unsigned transaction`.
  </Tab>

  <Tab title="◉ XRP">
    Constructing a transaction to transfer XRP is straightforward. The `value` is the amount of XRP in drops as a string (1 XRP = 1,000,000 drops).

    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/XRP.jsx#L63-L69" start="63" end="69" />

    This method returns the `unsigned transaction` and the transaction `hash` (also known as the `payload`).
  </Tab>

  <Tab title="◈ SUI">
    Constructing a transaction to transfer SUI is simple. The `value` is the amount of SUI in MIST as type BigInt (1 SUI = 1,000,000,000 MIST).

    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Sui.jsx#L70-L80" start="70" end="80" />

    This method returns the `unsigned transaction` and the transaction `hash` (also known as the `payload`).
  </Tab>

  <Tab title="⬟ Aptos">
    Constructing a transaction to transfer APT is straightforward. The `value` is the amount of APT in octas as type BigInt (1 APT = 100,000,000 octas).

    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Aptos.jsx#L71-L82" start="71" end="82" />

    This method returns the `unsigned transaction` and the transaction `hash` (also known as the `payload`).
  </Tab>
</CodeGroup>

<Accordion title="EVM Function Calls">
  To call a function on a smart contract we need the ABI of the contract, in our repo this is defined in the [config.js](https://github.com/near-examples/near-multichain/blob/main/src/config.js#L23-L63) file (this can be gathered from Remix or using Etherscan).

  Then define a `Contract` object using the `ethers` library

  <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/EVM/FunctionCall.jsx#L18-L18" start="18" end="18" />

  Then to construct the transaction

  <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/EVM/FunctionCall.jsx#L31-L37" start="31" end="37" />

  This approach allows you to call smart contract functions by encoding the function data and including it in the transaction.
</Accordion>

***

## 3. Requesting the Signature

Once the transaction is created and ready to be signed, a signature request is made by calling `sign` on the MPC smart contract.

The method requires four parameters:

1. The `payloads` (or hashes) to be signed for the target blockchain
2. The derivation `path` for the account we want to use to sign the transaction
3. The `keyType`, `Ecdsa` for `Secp256k1` signatures and `Eddsa` for `Ed25519` signatures.
4. The `signerAccount` which contains the `accountId` that is signing and the `signAndSendTransactions` function from [Near Connect](../../web3-apps/tutorials/wallet-login).

<Tabs>
  <Tab title="Ξ EVM">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/EVM/EVM.jsx#L115-L123" start="119" end="127" />
  </Tab>

  <Tab title="₿ Bitcoin">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Bitcoin.jsx#L83-L91" start="83" end="91" />

    For Bitcoin, it is common to have multiple UTXOs to sign when sending a single transaction. We create a NEAR transaction (to call `sign` on the MPC contract) for each UTXO and send them to be signed by the MPC individually. Each signature is then parsed from each transaction outcome to produce an array of signatures.
  </Tab>

  <Tab title="◎ Solana">
    To get the payload, serialize the transaction to a `uint8Array` and then convert it to hex.

    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Solana.jsx#L78-L86" start="78" end="86" />
  </Tab>

  <Tab title="◉ XRP">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/XRP.jsx#L76-L84" start="76" end="84" />
  </Tab>

  <Tab title="◈ SUI">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Sui.jsx#L87-L95" start="87" end="95" />
  </Tab>

  <Tab title="⬟ Aptos">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Aptos.jsx#L88-L96" start="88" end="96" />
  </Tab>
</Tabs>

***

## 4. Formatting the Signature

Once the signature is returned from the MPC it needs to be formatted and added to the transaction to produce a signed transaction.

<Tabs>
  <Tab title="Ξ EVM">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/EVM/EVM.jsx#L125-L128" start="129" end="132" />
  </Tab>

  <Tab title="₿ Bitcoin">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Bitcoin.jsx#L97-L100" start="97" end="100" />

    For Bitcoin, the array of signatures is added to the transaction to produce a complete signed transaction.
  </Tab>

  <Tab title="◎ Solana">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Solana.jsx#L92-L96" start="92" end="96" />
  </Tab>

  <Tab title="◉ XRP">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/XRP.jsx#L90-L93" start="90" end="93" />
  </Tab>

  <Tab title="◈ SUI">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Sui.jsx#L101-105" start="101" end="105" />
  </Tab>

  <Tab title="⬟ Aptos">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Aptos.jsx#L102-L106" start="102" end="106" />
  </Tab>
</Tabs>

***

## 5. Relaying the Signed Transaction

Now that we have a signed transaction, we can relay it to the target network using `broadcastTx`.

<Tabs>
  <Tab title="Ξ EVM">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/EVM/EVM.jsx#L150" start="154" end="154" />
  </Tab>

  <Tab title="₿ Bitcoin">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Bitcoin.jsx#L119" start="119" end="119" />
  </Tab>

  <Tab title="◎ Solana">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Solana.jsx#L115" start="115" end="115" />
  </Tab>

  <Tab title="◉ XRP">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/XRP.jsx#L114" start="114" end="114" />
  </Tab>

  <Tab title="◈ SUI">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Sui.jsx#L124" start="124" end="124" />
  </Tab>

  <Tab title="⬟ Aptos">
    <Github language="js" url="https://github.com/near-examples/near-multichain/blob/main/src/components/Aptos.jsx#L123" start="123" end="123" />
  </Tab>
</Tabs>

The method returns a transaction hash which can be used to locate the transaction on an explorer.

<Info>
  ⭐️ For a deep dive into the concepts of Chain Signatures, see [What are Chain Signatures?](../chain-signatures)

  ⭐️ For a complete example of a NEAR account using chain signatures in a frontend, see our [web app example](https://github.com/near-examples/near-multichain).
</Info>
