Docs
IntegrationsSui

Overview

Send and receive GMP messages from Move packages on Sui.

Sui is connected to Axelar through Amplifier. Move packages on Sui can exchange messages with every connected chain, and send tokens with the Interchain Token Service.

The packages are in axelar-cgp-sui.

💡

Using an AI agent?

Copy this page with Copy Markdown at the top and give it to your agent, with what you want to build or the package you want to make cross-chain. The copied page links to the Markdown of the other pages it refers to, so the agent can read them too. Review what it writes, and test on testnet before mainnet.

Message flow

Sending, in one transaction:

  1. Your package calls prepare_message on the gateway with its channel, which returns a MessageTicket.
  2. The transaction pays gas for the ticket to the gas service (pay_gas).
  3. The transaction passes the ticket to send_message on the gateway, which emits a ContractCall event.
  4. Axelar verifies the event and routes the message to the destination chain.

Receiving:

  1. Once, before the first message, you register the call that delivers messages to your package with the relayer discovery (register_transaction).
  2. Axelar approves the message on the Sui gateway.
  3. A relayer takes the message from the gateway as an ApprovedMessage (take_approved_message) and calls your registered function with it, in the same transaction.
  4. Your function consumes the ApprovedMessage with your channel (consume_approved_message), then runs your code.

Addresses

MainnetTestnet
Chain namesuisui
Gateway package0xeb055ffc3237c24e305a2bb760fe6551f6ff7c5fdb68735169c0f528fccab3730x6ddfcdd14a1019d13485a724db892fa0defe580f19c991eaabd690140abb21e4
Gateway object0xde761b85a85477bba0ca6b4a09bcde7da33db2f64c392f806f24f433971514f50x6fc18d39a9d7bf46c438bdb66ac9e90e902abffca15b846b32570538982fb3db
Gas service package0x695f612a1ee9268d25ca5c03e705819a285ff0c5b4f7720fc75a00cb8c6f3b630xddf711b99aec5c72594e5cf2da4014b2d30909850a759d2e8090add1088dbbc9
GasService object0x0a3a8e08d156595e5a097964d5d294fcfc9ff75f736b55f44470a93e48bdeb8f0xac1a4ad12d781c2f31edc2aa398154d53dbda0d50cb39a4319093e3b357bc27d
Relayer discovery package0x2b839b25c7133e5e0f8f585cb2e89bf430a6585a88c4a0343ae3b246372d431c0x2f871726329f555bc3fa6eec129f259a8bce3cb3989b39dd75a627a1a0961bc2
RelayerDiscovery object0x310144e74e9a73d750ff17e62ed597681f519d799fea491d61740f6dd1e8c6560xac080ff19b7d44c9362b83628253a4b55747779096034a72ca62ce89a188305e
ExplorerSuiscanSuiscan

Call functions on the package, e.g. <gateway package>::gateway::send_message, and pass the objects as arguments. The current IDs are always in the deployment configs, under chains.sui.contracts: mainnet | testnet.

Setup

You need:

  • The Sui CLI. This page was tested with version 1.83.
  • A testnet address with SUI: sui client faucet, or see Get SUI tokens.

Add the Axelar packages to your package's Move.toml:

[dependencies]
axelar_gateway = { git = "https://github.com/axelarnetwork/axelar-cgp-sui.git", subdir = "move/axelar_gateway", rev = "b35227a82f7ca6f941a7e729e1a3b3d48a64b982" }
relayer_discovery = { git = "https://github.com/axelarnetwork/axelar-cgp-sui.git", subdir = "move/relayer_discovery", rev = "b35227a82f7ca6f941a7e729e1a3b3d48a64b982" }

If your package pays gas itself, add gas_service the same way, with subdir = "move/gas_service". The Sui framework is included automatically.

The manifests at this commit record the testnet IDs of the Axelar packages, so your package links to the deployed packages when you publish it. Don't depend on main: its manifests have placeholder addresses (0xa1, …), and publishing fails.

⚠️

Mainnet

The commit above records only the testnet IDs. For mainnet, copy move/axelar_gateway, move/relayer_discovery, move/utils and move/version_control from the v1.2.0 tag into your repository, and depend on them with { local = "<path>" }. In each copy's Move.toml, add published-at = "<mainnet ID>" under [package], and set the package's own address in [addresses] to the same ID. The gateway and relayer discovery IDs are in the table above; utils is 0x5920750d9804267493c958bffb7fcc1aa534705fffefbeaab0314418d631550c and version_control is 0x647a3b34b3a16f5f00443bdafd13d281983b2280703ab4f416cf706e6d739087.

From TypeScript, use @mysten/sui v2 with its gRPC or GraphQL client: public fullnodes no longer serve JSON-RPC.

Sui concepts

  • Packages and objects. A package holds code and no state. State lives in objects, which callers pass into each call. An app that sends and receives messages is a package plus a shared object that holds its state.
  • Channels. Packages have no msg.sender. Your app creates a Channel object and keeps it, usually inside its shared object. The channel's ID is your app's address: the source address of the messages it sends, and the destination address of the messages it receives. Only code that holds the channel can send or consume messages as that address.
  • Relayer discovery. A relayer can't know which of your functions to call, or with which objects. You register that call for your channel in the relayer discovery.
  • Hot potatoes. MessageTicket and ApprovedMessage can't be stored or dropped, so the transaction that creates one must consume it.
  • Programmable transaction blocks. A transaction can chain calls to several packages and pass results between them. Sending a message is one: your package returns the ticket, and the next calls pay gas for it and send it.
  • Addresses and amounts. Sui addresses and object IDs are 0x followed by 64 lowercase hex characters. SUI has 9 decimals, and amounts are in MIST: 1 SUI is 1000000000.

Next steps

Resources

On this page