On this page

Transfer

Create on the origin

function createAsset(address originToken, address compliance)
    external returns (bytes32 assetId, address token);

The caller becomes the permanent creator. Pass the zero compliance address for an asset without an issuer compliance contract. A nonzero address permanently requires issuer compliance checks and must point to a deployed contract. Creating a second asset for the same token and creator reverts.

Enable a new destination

The origin creator calls enableChain(assetId, dstEid, remoteCompliance, extraOptions), paying the Lens quoteSync result. A peer must already exist. Pass bytes32 zero for an asset without an issuer compliance contract. Assets with an issuer compliance contract require the destination compliance contract.

Wait for destination delivery. When a remote source has not learned about another enabled chain, call syncAsset(assetId, sourceEid, extraOptions) on the origin and wait, or have the creator call enableChain(assetId, dstEid, bytes32(0), "0x") directly on the remote source (no native value, no message). Syncing and enabling are both owner-only.

Send through the local facade

struct SendParam {
    uint32 dstEid;
    bytes32 to;
    uint256 amountLD;
    uint256 minAmountLD;
    bytes extraOptions;
    bytes composeMsg;
    bytes oftCmd;
}

On the origin, approve the underlying ERC-20 to getAsset(assetId).token (the OFTAdapter). On a remote chain, use its OFT directly; the OFT send needs no ERC-20 approval.

Call send(sendParam, messagingFee, refundAddress) on that facade with msg.value = messagingFee.nativeFee. Do not call the router's internal-facing send method as a user.

Use quoteOFT to obtain the received amount and set minAmountLD. Set oftCmd = 0x for the default restorer, or exactly 32 bytes naming the destination restorer. Leave composeMsg and extraOptions empty for a plain transfer.

See Quote and Integration.