Multi-chain intents let you make cross-chain transactions. Those intents specify both the target (destination) and the source chain(s). The actual transaction (fill) happens on the target chain, while the funds are taken on the source chains (claims). Specifying source chains is optional — Rhinestone finds the optimal path automatically. Multi-chain intents work similarly to single-chain intents, but with the introduction of settlement layers. From your perspective, making cross-chain transactions is as simple as making normal Ethereum transactions. The Rhinestone Orchestrator handles path finding, liquidity management, and intent execution for you. Learn more about how Rhinestone intents work here.

Example

We will make a cross-chain token transfer using multi-chain intents.
const amount = parseUnits('100', 6) // 100 USDC

const transferIntent = await rhinestoneAccount.sendTransaction({
  sourceChains: [arbitrum],
  targetChain: base,
  calls: [
    {
      to: 'USDC',
      data: encodeFunctionData({
        abi: erc20Abi,
        functionName: 'transfer',
        args: [recipient, amount],
      }),
    },
  ],
  tokenRequests: [
    {
      address: 'USDC',
      amount,
    },
  ],
})
Under the hood, this will:
  1. Get a quote from the Rhinestone backend
  2. Sign the intent using the account owner(s)
  3. Submit the intent
  4. Execute the claim transaction on Arbitrum
  5. Execute the fill transaction on Base

Monitor Execution

You can wait until the target chain transaction is submitted to the blockchain:
const result = await rhinestoneAccount.waitForExecution(transferIntent)
console.log('Status:', result.status)

Token Requests

tokenRequests is a list of token assets and their amounts that are required on the target chain to make the transaction. It tells the solvers to ensure those assets are present before executing the transaction calls. If you don’t need any assets on the target chain, you can omit this.
Solvers will supply all assets specified in the tokenRequests. If the user already has the required assets, don’t add them into tokenRequests.

Gas Limit

You can override the default gas limit for the target chain execution with gasLimit. Doing this will make the intent better priced, because we can more accurately calculate the fee that a solver needs to be reimbursed with for paying the gas. If this is not provided, we calculate using a gas limit of 1_000_000.
const transaction = await rhinestoneAccount.sendTransaction({
  sourceChains: [baseSepolia],
  targetChain: arbitrumSepolia,
  calls: [
    // …
  ],
  tokenRequests: [
    // …
  ],
  gasLimit: 200_000n,
})

Source Chain

Providing the source chain deploys the account on that chain, as well as uses the funds on that chain to fulfill the intent. If you already have an account deployed on one or more source chains, you can omit the sourceChain. In that case, the orchestrator will use the best chain(s) to source funds.