On this page
Production checklist
Ship an integration that knows which asset it uses, what a transaction costs, and how to handle each settlement state.
Verify the release
- Pin the contract release and ABI; do not reuse old Omniassets addresses with the new asset-router interface.
- Check source and destination deployment addresses, code, endpoint EIDs, permanent peers, and that each route you use is frozen (
routeFrozenAt) with a configuration you accept (routeConfigHash). - Check the API rollout and indexing flags separately from contract deployment.
- Verify the source facade's asset ID, original token and permanent creator. Display enough issuer identity to distinguish official and community assets.
Before every send
- Require a connected wallet on the intended source chain. Preserve form state on rejected network switches.
- Read the source asset, destination enablement, balance and approval. A predicted address is not a deployed source.
- Check compliance readiness on both chains where applicable. Resolve stale remote chain views with an origin sync.
- Parse amounts as integers; account for shared-decimal dust and token fees using quotes.
- Use the final recipient, compose payload, options and restorer in both quote and send. Cap native payment and set a minimum received amount.
- Refresh the quote and simulate immediately before signing; reserve source transaction gas in addition to quoted native payment.
After submission
- Persist source chain, hash, router, asset ID, GUID, recipient and exact parameters. Never automatically rebroadcast after a timeout.
- Distinguish source confirmation, router delivery, compose outcome and restore delivery.
- Show recovery actions only after inspecting the matching router failure or Endpoint state.
- Monitor pending messages per route (
/monitoring/stuck-messages). If one route stops delivering, stop offering it and offer a detour through another chain. See Route outages. - Handle RPC and API outages without treating unavailable state as zero balance, an absent asset or a successful transfer.
Test your integration
- Test creation, origin-to-remote, remote-to-origin and remote-to-remote transfers, including the first destination deployment.
- Test unsupported routes, wrong spender, wallet rejection, fee changes, dust, insufficient native gas and stale quotes.
- Test later peer enablement and the sync needed by an existing remote source.
- Test retry with the exact packet, restore authorization and a delayed return message. Verify that fees are not refunded.
- For composers, test Endpoint/facade/source authentication, replay, slippage, deadline, failure credits and beneficiary-only withdrawal.
- Run forks against the exact token, vault or lending protocol you support. Local mock tests do not validate a live LayerZero route or third-party protocol.
Keep docs and code together
From the web repository, bun run docs:sync refreshes generated ABI references, the deployment snapshot and downloadable examples. bun run docs:check checks drift, links, search, examples and TypeScript. Contract-source verification additionally runs npm run abi:check in solidity-v2, then bun run omnisea:abi:check in web from a workspace with both repositories.
The generated reference lists method, event and error signatures directly from release ABIs; the deployment table comes from the app registry. When editing the vault-composer example, also run its Solidity test suite and sync its downloadable copy before shipping. See Transfer and deposit.
Keep API fields aligned with api/src/explorer.ts. The OpenAPI download is generated from a typed reference in lib/docsApiSchema.ts; contract tests compare its routes and filter names with the API source when that sibling checkout is available. This is not a runtime response validator. Extend both the reference and tests when API behavior changes.