LayerZero OFT: omnichain SPL tokens logoLayerZero OFT: omnichain SPL tokens
OFT extends OApp for SPL and Token-2022. You own the upgrade authority. Solana mainnet endpoint ID 30168. Shared decimals default 6.
devrels.xyz/a/305LayerZero OFT is the Omnichain Fungible Token standard. On Solana it is an extension of OApp that moves SPL or Token-2022 supply across LayerZero Endpoint V2. A send on one chain burns or locks. The destination mints or unlocks. The same token identity, different VMs.
Every Solana program has an upgrade authority. LayerZero does not run one shared mutable OFT program for everyone. You deploy your own OFT program instance and an OFT Store account. You hold that upgrade authority. The OFT Store is a PDA. It is not the mint. Docs: getting started. The USD.AI piece that mentions a Solana OFT path stays.
Scaffold and SDK
New workspace from the Solana OFT example:
LZ_ENABLE_SOLANA_OFT_EXAMPLE=1 npx create-lz-oapp@latestInteract with @layerzerolabs/oft-v2-solana-sdk at ^3.0.86, plus @layerzerolabs/lz-v2-utilities, @layerzerolabs/lz-definitions, and Umi ^0.9.2. Browser-ready from 3.0.71. Next needs no extra polyfill. Vite needs vite-plugin-node-polyfills for Buffer. Example send lives in tasks/common/sendOFT.ts in a CLI project.
IDs and flow
Solana mainnet: chain ID 101, endpoint ID 30168. Devnet endpoint ID 40168. Deployment folders: solana-mainnet or solana-testnet (that folder is Devnet). A Solana deployment JSON carries programId, mint, mintAuthority, escrow, oftStore.
Typical path: initOft, setPeerConfig for each remote endpoint ID, quoteOft or quoteSend, then send. Inbound is lzReceive on the OFT program, not the Endpoint. Optional: pause, default fee BPS, inbound rate limiter. Do not invent a global OFT program ID. The playground uses PENGU as a sample instance only.
Shared decimals
Each chain has local decimals. Every OFT also declares sharedDecimals, default 6. Amounts on the wire are uint64 shared units. Before send, local amount is floored to the conversion rate so leftover dust stays on source. Conversion rate is 10^(localDecimals - sharedDecimals). EVM 18 local plus 6 shared means 10^12. Putting 18 local decimals on Solana caps whole-token supply near 18. Prefer 6 or 9 locally. Inconsistent shared decimals across chains lose value.
Solana amounts are u64. 9 local decimals maxes around 18 billion whole tokens. 6 local decimals maxes around 18 trillion. Shared-unit overflow is 2^64-1. At 6 shared decimals that is about 18.4 trillion whole tokens. Smaller shared decimals raise that cap and raise dust.
V1 and the list API
Endpoint V1 Solana OFT202 is legacy. New work uses V2. V1 OFT V1 (EVM only) does not talk to Solana. Metadata list: GET https://metadata.layerzero-api.com/v1/metadata/experiment/ofts/list. Early access. Transfer on that API needs a key. Scan: layerzeroscan.com.
Keep reading
min_balance = (128 + data) * lamports_per_byte. Step 1 target 6333. Token instruction WithdrawExcessLamports. Mainnet rent sysvar still 6960.
Bonding-curve internet round, USDC in, SPL out. MCP: npx -y @star-factory/launch-cli mcp serve.
Create a mint with an interface PDA, mint compressed balances, send them, then compress or decompress when you need a normal ATA. Photon RPC required.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
