Lintent is LI.FI's interactive demo for the Open Intents Framework (OIF). It walks through the full cross-chain intent lifecycle, from resource lock management and intent issuance to solving, proof submission, and finalisation. The live app is hosted at lintent.org.
The app handles both sides of an intent: the user (intent issuer) and the solver. Each step maps to a dedicated screen so you can follow the entire flow in sequence.
Architecture
flowchart TD
subgraph Browser["Browser (SvelteKit SPA)"]
direction TB
Page["+page.svelte"]
S0["Connect Wallet"]
S1["Manage Deposit"]
S2["Issue Intent"]
S3["Intent List"]
S4["Fill Intent"]
S5["Receive Message"]
S6["Finalise"]
Store["Svelte 5 runes store\nbalances, allowances, orders"]
DB["PGlite via IndexedDB\nintents, fills, receipts"]
Page --> S0 & S1 & S2 & S3 & S4 & S5 & S6
Store --> DB
end
subgraph Worker["Cloudflare Worker"]
API_P["POST /polymer\nproof proxy"]
API_A["POST /allocator\nallocator proxy"]
API_H["GET /health"]
end
subgraph External["External Services"]
OS["LI.FI Order Server\nREST + WebSocket"]
POL["Polymer API\ncross-chain proofs"]
RPC["EVM RPC Nodes"]
end
subgraph Contracts["Smart Contracts"]
COMPACT["The Compact\nresource lock registry"]
ESC["Input Settler\nescrow + multichain"]
CSETT["Input Settler\ncompact + multichain"]
CF["CoinFiller\noutput settlement"]
PORACLE["Polymer Oracle\nproof verifier"]
end
S2 -->|"getQuotes / submitOrder"| OS
S3 -->|"WebSocket + REST"| OS
S4 -->|"fillOrderOutputs"| CF
S5 -->|"proof request"| API_P
S5 -->|"receiveMessage"| PORACLE
S5 -->|"setAttestation"| CF
S6 -->|"finalise"| ESC
S6 -->|"finalise"| CSETT
S1 -->|"deposit / withdraw"| COMPACT
S2 -->|"open escrow"| ESC
S2 -->|"sign compact"| COMPACT
API_P -->|"requestProof / queryProof"| POL
API_A -->|"attestCommit"| POL
Store -->|"balance / allowance reads"| RPC
Intent Lifecycle
The app exposes six sequential screens, each representing one step in the OIF flow.
- Connect Wallet connects via Web3-Onboard (injected wallets, Coinbase, WalletConnect, Zeal)
- Manage Deposit lets you choose between escrow and compact locking, then deposit or withdraw tokens from The Compact
- Issue Intent configures the intent (input/output tokens, chains, amounts, verifier), fetches a quote from the LI.FI order server, and submits the order on-chain (escrow) or via EIP-712 signature (compact)
- Intent List shows open intents from the order server WebSocket and local DB, with the option to import by on-chain order ID
- Fill Intent is the solver side, where output tokens are delivered to recipients via the CoinFiller contract on each output chain
- Receive Message fetches a cross-chain proof from Polymer and submits it to the Polymer Oracle on the source chain (or calls
setAttestationfor same-chain fills) - Finalise calls
finalise()on the appropriate input settler, releasing the locked input tokens to the solver
Tech Stack
- Framework SvelteKit 2 with Svelte 5 runes
- Language TypeScript
- Styling Tailwind CSS v4
- EVM viem ~2.45
- Wallet Web3-Onboard
- Local DB PGlite (WASM Postgres) + Drizzle ORM, persisted to IndexedDB
- Deployment Cloudflare Workers via
@sveltejs/adapter-cloudflare - Runtime Bun
- Testing Bun test (unit/integration) and Playwright (E2E)
Supported Chains
Mainnet Ethereum, Base, Arbitrum, Polygon, BSC, MegaETH, Katana
Testnet Sepolia, Base Sepolia, Arbitrum Sepolia, Optimism Sepolia
Smart Contracts
The app interacts with the following deployed contracts (ABIs are inlined in src/lib/abi/).
| Contract | Purpose |
|---|---|
| The Compact | ERC-6909 resource lock registry for compact-based intents |
| Input Settler (Escrow) | Opens and finalises escrow-based intents (single-chain and multichain variants) |
| Input Settler (Compact) | Finalises compact-based intents using combined sponsor and allocator signatures |
| CoinFiller | Output settlement where solvers deliver tokens, also handles same-chain attestations |
| Polymer Oracle | Verifies cross-chain fill proofs submitted via Polymer |
Project Structure
src/
lib/
abi/ # contract ABIs (Compact, Escrow, CoinFiller, Polymer Oracle, etc.)
libraries/ # core logic (Intent, IntentFactory, OrderServer, Solver, CompactLib)
screens/ # SvelteKit components for each step in the flow
utils/ # helpers (EIP-712 typed data, order validation, address encoding)
config.ts # contract addresses, chain config, token lists, RPC clients
state.svelte.ts # global reactive store (Svelte 5 runes)
db.ts # PGlite + Drizzle init with IndexedDB persistence
schema.ts # Drizzle table definitions
routes/
+page.svelte # single-page entry point (renders all six screens)
polymer/ # server route proxying to Polymer API
allocator/ # server route proxying to Polymer Allocator
health/ # liveness check
tests/
unit/ # order validation, intent list, order server parsing, asset selection
e2e/ # Playwright browser tests for issuance flow
db.test.ts # PGlite integration test
Getting Started
- Copy
.env.exampleto.env - Create a WalletConnect project and add the project ID
- Create an account with Polymer and generate API keys for mainnet and testnet
- Install dependencies with
bun install - Start the dev server with
bun run dev
Testing
bun run test:unitruns library and unit tests with coveragebun run test:e2eruns Playwright browser tests (requiresbunx playwright install chromium)bun run test:allruns both suites
Deployment
Production deploys happen on push to main via GitHub Actions. The workflow builds with Bun and deploys to the lintent-worker Cloudflare Worker. PR preview environments are created and cleaned up automatically.
Required secrets for CI: CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, PRIVATE_POLYMER_MAINNET_ZONE_API_KEY, PRIVATE_POLYMER_TESTNET_ZONE_API_KEY, PUBLIC_WALLET_CONNECT_PROJECT_ID.
License
This project is licensed under the MIT License.