Developer documentation

Omniassets for developers.

Move existing ERC-20 tokens across supported EVM chains through one contract interface. No token-team deployment is required.

What Omnisea does

An ERC-20 can enter the network without a custom bridge deployment. Omnisea locks the original token, creates a deterministic ERC-20 representation when needed, and burns or unlocks supply as the asset moves between chains.

Choose your path

Start with the client action you need, then use the contract references for exact arguments, events, errors, and LayerZero options.

Programmatic start

This viem example sends an original ERC-20 from BNB Chain to Base. It checks whether Base needs the Omniasset deployed, builds the corresponding receive-gas option, approves the token, and sends with an exact quote.

TypeScript · viem
import { erc20Abi, zeroAddress } from "viem";

const omnisea = "0x0E108CbbD4d783Fea6c07E96be9e2aA5A842D6b4";
const token = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";
const sourceEid = 30102; // BNB Chain
const dstEid = 30184; // Base
const recipient = account.address;

const representation = await destinationClient.readContract({
  address: omnisea,
  abi: omniseaAbi,
  functionName: "representationFor",
  args: [sourceEid, token],
});
const isFirstTransfer = representation === zeroAddress;

const minimumGas = await sourceClient.readContract({
  address: omnisea,
  abi: omniseaAbi,
  functionName: isFirstTransfer ? "minCreationGas" : "minTransferGas",
});
const receiveGas = minimumGas + minimumGas / 5n;
const u128 = (value: bigint) => value.toString(16).padStart(32, "0");
const options = `0x000301002101${u128(receiveGas)}${u128(0n)}` as const;
const compose = { composer: zeroAddress, gasLimit: 0n, message: "0x" } as const;

const approval = await walletClient.writeContract({
  account,
  address: token,
  abi: erc20Abi,
  functionName: "approve",
  args: [omnisea, amount],
});
await sourceClient.waitForTransactionReceipt({ hash: approval });

const args = [dstEid, token, amount, recipient, isFirstTransfer, compose, options] as const;
const fee = await sourceClient.readContract({
  address: omnisea,
  abi: omniseaAbi,
  functionName: "quoteSendOriginal",
  args,
});

await walletClient.writeContract({
  account,
  address: omnisea,
  abi: omniseaAbi,
  functionName: "sendOriginal",
  args,
  value: fee,
});
Open the complete transfer guide

Documentation directory

Contract methods, client integrations, deployment addresses, and the concepts behind Omniassets.

Introducing Omnipad-Launch tokens between chains