-
Custom Address

Move assets and execute on arrival.

Send an asset across chains and optionally attach destination logic in one transaction. Use the same Omnisea entrypoint for a simple transfer, a Morpho borrow, or your own cross-chain action.

Illustration of a dense, many-coloured forest canopy
Omnisea.sol · transfer
// sendOriginal pulls the token into OmniseaVault
IERC20(token).approve(address(omnisea), amt);

// A plain transfer: no composer, no compose gas
ComposeParams memory compose = ComposeParams({
    composer: address(0),
    gasLimit: 0,
    message: ""
});

// Quote and send must stay byte-identical
uint256 fee = omnisea.quoteSendOriginal(
    dstEid, token, amt, to, false, compose, opts
);

// EndpointV2 chains require exact msg.value
omnisea.sendOriginal{value: fee}(
    dstEid, token, amt, to, false, compose, opts
);

Bring Omniassets into your app.

Use wagmi and viem to transfer Omniassets or attach Omnihooks—composers that run application logic after an asset arrives. Connect to destination protocols without operating a relayer or backend.

Illustration of a wildflower meadow under a bright blue sky
viem · route discovery
// Canonical token, or an Omniasset already?
const identity = await client.readContract({
  address: omnisea,
  abi: omniseaAbi,
  functionName: "oftToOriginal",
  args: [token],
});
const isRepresentation = identity[3];

// A zero address means this deploys the token
const representation = await client.readContract({
  address: omnisea,
  abi: omniseaAbi,
  functionName: "representationFor",
  args: [originalChainId, 1, pad(token)],
});
const isFirst = representation === zeroAddress;

// Canonical → sendOriginal, representation → sendOFT
const fn = isRepresentation
  ? "sendOFT" : "sendOriginal";
Experimental Beta is Live-Learn more about the Pilot