Quote
Always quote from the source-chain Omnisea contract immediately before sending. The returned value already includes the LayerZero fee and the flat Omnisea protocol fee.
Quote functions
function quoteSendOriginal(
uint32 dstEid,
address originalToken,
uint256 amount,
address recipient,
bool isFirstTransfer,
ComposeParams compose,
bytes options
) external view returns (uint256);
function quoteSendOFT(
uint32 dstEid,
address representation,
uint256 amount,
address recipient,
bool isFirstTransfer,
ComposeParams compose,
bytes options
) external view returns (uint256);Use quoteSendOriginal for an original ERC-20 and quoteSendOFT for an Omniasset. See Transfer for token-role detection.
Arguments must match
The quote depends on the encoded message and its LayerZero execution options. Keep these values byte-identical between quote and send:
- destination endpoint ID;
- token address and amount;
- recipient;
isFirstTransfer;- composition values;
- LayerZero options.
const args = [dstEid, token, amount, recipient, isFirstTransfer, compose, options] as const;
const totalFee = await publicClient.readContract({
address: omnisea,
abi: omniseaAbi,
functionName: isRepresentation ? "quoteSendOFT" : "quoteSendOriginal",
args,
});Do not add fixedProtocolFee() to this value. It is already included.
First-transfer quotes
The first transfer of an asset to a destination includes enough execution gas to deploy its Omniasset. Determine this on the destination chain:
const representation =
dstEid === originalEid
? zeroAddress
: await destinationClient.readContract({
address: omnisea,
abi: omniseaAbi,
functionName: "representationFor",
args: [originalEid, originalToken],
});
const isFirstTransfer =
dstEid !== originalEid && representation === zeroAddress;Use minCreationGas() when isFirstTransfer is true and minTransferGas() otherwise. Returning to the original chain never needs creation gas.
isFirstTransfer is only a source-side LayerZero gas-profile flag. It is not part of the payload and does not control destination deployment. A destination with no representation still attempts deployment even if the caller passes false; the risk is insufficient execution gas, not different settlement logic.
Quotes are time-sensitive
LayerZero pricing can change between a read and a submitted transaction. Re-quote when any input changes and again immediately before the wallet confirmation. If the write reverts with InvalidFee, refresh the quote and let the user retry.
Represent quoted fees as bigint in JavaScript. Format them only for display; never convert the transaction value through a floating-point number.