-
Custom Address
Send any asset across chains and optionally set your destination hook with custom logic.

// sendOriginalTo pulls the token into OmniseaVault
IERC20(token).approve(address(omnisea), amt);
// Destination addresses stay raw until the destination VM
bytes memory recipient = abi.encodePacked(to);
BytesComposeParams memory compose = BytesComposeParams({
composer: bytes(""),
gasLimit: 0,
message: ""
});
// Quote and send must stay byte-identical
uint256 fee = omnisea.quoteSendOriginalTo(
dstEid, token, amt, recipient, false, compose, opts
);
// EndpointV2 chains require exact msg.value
omnisea.sendOriginalTo{value: fee}(
dstEid, token, amt, recipient, false, compose, opts
);

// Canonical token, or an Omniasset already?
const identity = await client.readContract({
address: omnisea,
abi: omniseaAbi,
functionName: "oftToOriginal",
args: [token],
});
const isRepresentation = identity[2];
// A zero address means this deploys the token
const representation = await client.readContract({
address: omnisea,
abi: omniseaAbi,
functionName: "representationFor",
args: [originalEid, encodePacked(["address"], [token])],
});
const isFirst = representation === zeroAddress;
// Canonical → sendOriginalTo, representation → sendOFTTo
const fn = isRepresentation
? "sendOFTTo" : "sendOriginalTo";