Skip to content

L2 Bridge & Vault Compose

When a payment settles on an L2, Stablecoin Harness bridges the proceeds to a mainnet-path chain and stakes them into sUSDe for the merchant — in one composed delivery. This is an internal part of session settlement, not a public bridge API you call directly; it surfaces as the session’s bridging status.

Source chain (L2) Destination chain
───────────── ─────────────
Forwarder swap → USDe ─► OFT.send() ─► LZ V2 endpoint ─► OFT.receive() ─► VaultComposerSync
(stakes → sUSDe → merchant)

After the session’s Forwarder swaps the customer’s deposit into USDe on the source chain, the backend sends it over LayerZero V2 OFT. The bridge transport and the destination vault deposit are composed: the recipient on the destination chain is VaultComposerSync, which stakes the arriving USDe into sUSDe and credits the merchant — atomically, with no second user action.

  • L2 settlement. Customer pays on an L2; the merchant receives sUSDe on a mainnet-path chain without a manual bridge step.
  • Single confirmation. The merchant doesn’t sign the bridge or the deposit — it’s driven by the platform as the final leg of settlement.

From the merchant’s side this is visible through the session lifecycle, not a separate transfer object:

Session statusMeaning
confirmingDeposit detected; forwarder swap in flight on the source chain.
bridgingsUSDe being bridged + composed to the destination chain.
completedVault deposit credited to the merchant.
failedLayerZero delivery or destination compose did not complete.

There is no public /v1/bridge/* endpoint — track progress via GET /v1/sessions/:id/status and the session.confirming webhook. See Session Payment.

  • Source gas — the platform hot wallet executes the forwarder + OFT.send().
  • Destination gas — covered by the LayerZero relayer fee.
  • VaultComposerSync.sol — receives the OFT message on the destination chain and performs the vault deposit in the same delivery.
  • LayerZero V2 OFT — the cross-chain transport.

Cross-chain settlement runs between the supported chains (Ethereum, Base, Arbitrum) and their testnets; routes are configured per chain in the deployed addresses, not selected by the caller.