-
Notifications
You must be signed in to change notification settings - Fork 2
Update README with architecture diagram and comprehensive docs #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,49 +1,153 @@ | ||||||
| # LI.FI Intent Demo | ||||||
|
|
||||||
| The LI.FI intent demo is hosted at lintent.org. It demonstrates the entire intent flow from resource lock mangement, intent issuance, and solving intents. | ||||||
|
|
||||||
| ## Project | ||||||
|
|
||||||
| This project uses SvelteKit and `bun`. It is configured for a deployment to Cloudflare workers, to change the deployment target modify [/svelte.config.js](/svelte.config.js) with another [adapter](https://svelte.dev/docs/kit/adapters). | ||||||
|
|
||||||
| ### Development | ||||||
|
|
||||||
| To start development: | ||||||
|
|
||||||
| 1. Copy `.env.example` to `.env`. | ||||||
| 2. Then fill in the `env` variables by creating a [WalletConnect](https://walletconnect.com) project | ||||||
| 3. Also create an [account](https://accounts.polymerlabs.org/) with Polymer to generation [Polymer](https://polymerlabs.org) API keys. | ||||||
| 4. Install dependencies `bun install`. | ||||||
| 5. Start `bun run dev`. | ||||||
|
|
||||||
| ### Testing | ||||||
|
|
||||||
| The project now uses a two-layer automated test suite: | ||||||
|
|
||||||
| 1. Unit and integration tests with `bun test` | ||||||
| 2. Browser UI-state tests with Playwright | ||||||
|
|
||||||
| Run: | ||||||
|
|
||||||
| - `bun run test:unit` for library/unit/integration tests with coverage output | ||||||
| - `bun run test:e2e` for deterministic browser tests | ||||||
| - `bun run test:all` to run both | ||||||
|
|
||||||
| For local Playwright setup: | ||||||
|
|
||||||
| 1. `bun install` | ||||||
| 2. `bunx playwright install chromium` | ||||||
|
|
||||||
| ## Structure | ||||||
|
|
||||||
| Lintent is built around a single page [/src/routes/+page.svelte](/src/routes/+page.svelte). | ||||||
|
|
||||||
| The app consists of a series of screens that are displayed in a scrollable container. Each screen can be found in [/src/lib/screens/](/src/lib/screens/). | ||||||
|
|
||||||
| ### Libraries | ||||||
|
|
||||||
| Several helper classes that acts as wrappers for external endpoints can be found in [/src/lib/libraries/](/src/lib/libraries/). | ||||||
| # Lintent | ||||||
|
|
||||||
| Lintent is LI.FI's interactive demo for the [Open Intents Framework (OIF)](https://openintents.xyz). 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](https://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 | ||||||
|
|
||||||
| ```mermaid | ||||||
| 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 | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as the comment above |
||||||
| - **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 `setAttestation` for 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.) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| libraries/ # core logic (Intent, IntentFactory, OrderServer, Solver, CompactLib) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
to be consistent |
||||||
| screens/ # SvelteKit components for each step in the flow | ||||||
| utils/ # helpers (EIP-712 typed data, order validation, address encoding) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same with the |
||||||
| 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 | ||||||
|
|
||||||
| 1. Copy `.env.example` to `.env` | ||||||
| 2. Create a [WalletConnect](https://walletconnect.com) project and add the project ID | ||||||
| 3. Create an account with [Polymer](https://accounts.polymerlabs.org/) and generate API keys for mainnet and testnet | ||||||
| 4. Install dependencies with `bun install` | ||||||
| 5. Start the dev server with `bun run dev` | ||||||
|
|
||||||
| ## Testing | ||||||
|
|
||||||
| - `bun run test:unit` runs library and unit tests with coverage | ||||||
| - `bun run test:e2e` runs Playwright browser tests (requires `bunx playwright install chromium`) | ||||||
| - `bun run test:all` runs 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](/LICENSE)**. Any contributions to this repository is provided with a MIT License. | ||||||
| This project is licensed under the [MIT License](/LICENSE). | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would call it "Intent Configuration" since we choose here the chain and the input type as well.