Across is now live on BNB Smart Chain!
Bridge Now!
Across Documentation
V3 Developer Docs
V3 Developer Docs
  • 👋Introduction
    • Welcome to Across
    • What is Across?
    • Technical FAQ
    • Migration Guides
      • Migration from V2 to V3
      • Migration to CCTP
        • Migration Guide for Relayers
        • Migration Guide for API Users
      • Migration Guide for Non-EVM and Prefills
        • Breaking Changes for Indexers
        • Breaking Changes for API Users
        • Breaking Changes for Relayers
        • Testnet Environment for Migration
      • Solana Migration Guide
      • BNB Smart Chain Migration Guide
  • 🌟EXCLUSIVE
    • Integrate BNB Smart Chain
  • 🔗QUICKSTART
    • Instant Bridging in your Application
      • Bridge Integration Guide
      • Multichain Bridge UI Guide
      • Single Chain Bridge UI Guide
    • Embedded Crosschain Actions
      • Crosschain Actions Integration Guide
        • Using the Generic Multicaller Handler Contract
        • Using a Custom Handler Contract
      • Crosschain Actions UI Guide
    • Settle Crosschain Intents
    • ERC-7683 in Production
  • 🧠Concepts
    • What are Crosschain Intents?
    • Intents Architecture in Across
    • Intent Lifecycle in Across
    • Canonical Asset Maximalism
  • 🛠️Reference
    • API Reference
    • App SDK Reference
    • Contracts
      • Aleph Zero
      • Arbitrum
      • Base
      • BNB Smart Chain
      • Blast
      • Ethereum
      • Linea
      • Ink
      • Lens
      • Lisk
      • Mode
      • Optimism
      • Polygon
      • Redstone
      • Scroll
      • Soneium
      • Unichain
      • World Chain
      • zkSync
      • Zora
    • Selected Contract Functions
    • Supported Chains
    • Fees in the System
    • Actors in the System
    • Security Model and Verification
      • Disputing Root Bundles
      • Validating Root Bundles
    • Tracking Events
  • 🔁Relayers
    • Running a Relayer
    • Relayer Nomination
  • 📚Resources
    • Release Notes
    • Developer Support
    • Bug Bounty
    • Audits
Powered by GitBook
On this page
  • Executing Destination Actions
  • Append Unique Identifier to CallData
  • UI Guide
  1. 🔗QUICKSTART
  2. Embedded Crosschain Actions

Crosschain Actions Integration Guide

PreviousEmbedded Crosschain ActionsNextUsing the Generic Multicaller Handler Contract

Last updated 6 months ago

LogoLogo

Products

  • Across Bridge
  • Across+
  • Across Settlement

Socials

  • Discord
  • Twitter
  • Medium
  • Forum

Resources

  • Blog
  • Across Brand Assets
  • Github

Routes

  • Bridge to Unichain
  • Bridge to Arbitrum
  • Bridge to Optimism
  • Bridge to Linea
  • Bridge to Polygon
  • Bridge to Base
  • Bridge to World Chain
  • Bridge to zkSync

This guide provides technical instructions for bundling a bridge with user actions. The integration process is simple and consists of three steps:

  1. Craft the message that is the set of transactions to execute on the destination

  2. Request quotes from Across GET /suggested-fees API, passing in the message parameter defined above

  3. Initiate a deposit by using data returned from Across API to call functions on Across smart contracts, specifying a message (set of transactions to execute on the destination) and appending your integration ID in calldata.

Executing Destination Actions

At a high level, the system works as follows:

  • End-user (or intermediate contract) includes a message field in the deposit transaction.

  • To be repaid for the fill, the relayer is required to include the same message field in their fill.

  • When this message field is non-empty and the recipient is a contract, the SpokePool calls a special handler function on the recipient handler contract with the message (and a few other fields).

  • This function can do anything, meaning application-specific actions can be executed atomically

This integration requires a handler contract on the destination to "handle" (execute) the transactions specified in the message. There are two approaches to implementing this functionality with respect to handler contract.

  1. (recommended) Use our already-deployed and audited generic "multicall" handler contract

  2. Build and implement your own custom handler contract

Each of the below guides provide instruction and examples for the 3 integration steps above.

Using the Generic Multicaller Handler Contract

The recommended way is to use our already-deployed and audited generic "multicall" handler contract. When this contract is set as the recipient address, this contract will atomically execute all contract calls specified in the deposit's message. This guide walks through four examples:

Using a Custom Handler Contract

If your use case requires additional customization or complexity, you can build your own custom handler contract to execute the contents provided in the deposit's message. This guide walks through two examples:

How to Decide

The tradeoff of using the generic multicall handler contract is that the complexity is encountered when crafting the message, which must be a correctly-encoded Instructions object. Once the message is formed correctly, you don't need to write any more code.

On the other hand, when using a custom handler contract, you'll need to implement a custom handleV3AcrossMessage function and deploy a new contract, but creating the deposit message is trivial.

If you have further questions or suggestions for this guide, please send a message to the #developer-questions channel in the Across Discord.

Append Unique Identifier to CallData

In order to track the origination source for deposits for analytics, debugging and support purposes we request all integrators to append a delimiter of 1dc0de and a unique identifier provided by our team to the deposit transaction call data.

Here is an example of depositV3 call data with 1dc0de delimiter and f001 unique identifier appended.

Do NOT pass delimiter + identifier to any depositV3 param, including the message param. Only append to call data of the transaction.

Do NOT use f001 identifier in your implementation, see below on how to request your unique ID.

Function: depositV3(address depositor,address recipient,address inputToken,address outputToken,uint256 inputAmount,uint256 outputAmount,uint256 destinationChainId,address exclusiveRelayer,uint32 quoteTimestamp,uint32 fillDeadline,uint32 exclusivityDeadline,bytes message)

0x7b939232000000000000000000000000c30c7ea910a71ce06ae840868b0c7e47616ba4c9000000000000000000000000c30c7ea910a71ce06ae840868b0c7e47616ba4c9000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831000000000000000000000000000000000000000000000000000000009502f9000000000000000000000000000000000000000000000000000000000094fd2f84000000000000000000000000000000000000000000000000000000000000a4b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066799bfb000000000000000000000000000000000000000000000000000000006679f0f40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000001dc0def001

Request your unique identifier in our shared communication channel (TG, Slack, etc), if already set up, or reach out to [email protected]. Please do not use any other identifier other than the one provided to you.

UI Guide

See Crosschain Actions Integration Guide for recommended UI and UX patterns.

Creating an Transaction for an Aave Deposit (Example #1)
Creating a Transaction for WrapChoice (Example #2)
Creating a Transaction for an Aave Deposit (Example #1)
Creating a Transaction for WrapChoice (Example #2)
Charging Protocol Fees (Example #3)
Creating a Transaction for a Uniswap Swap (Example #4)