Skip to content

Commit a5990d3

Browse files
authored
feat: Demo CLI tool (#132)
* feat: Demo CLI tool * fix: MSRV rust version error * chore: Improvements and formatting * chore: Replace hardcoded orders with StorageKey * chore: Add Nico to authors * chore: Support onchain intents in demo
1 parent e9b2e2c commit a5990d3

44 files changed

Lines changed: 8406 additions & 2856 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ Thumbs.db
1414
# Environment
1515
.env
1616
.env.local
17-
compact.env
1817

1918
# Logs
2019
*.log
@@ -28,6 +27,12 @@ out/
2827
cache/
2928
data/
3029

30+
# Demo output
31+
.pids/
32+
.logs/
33+
demo-output/
34+
snapshots/
35+
3136
# Contracts
3237
oif-contracts/
3338

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ default-members = ["crates/solver-service"]
1919
version = "0.1.0"
2020
edition = "2021"
2121
rust-version = "1.86.0"
22-
authors = ["nahim.terrazas@openzeppelin.com", "nami@openzeppelin.com"]
22+
authors = ["nahim.terrazas@openzeppelin.com", "nami@openzeppelin.com", "nicolas.molina@openzeppelin.com"]
2323
license = "MIT"
2424
repository = "https://github.com/openintentsframework/oif-solver"
2525

README.md

Lines changed: 175 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44

55
A high-performance cross-chain solver implementation for the Open Intents Framework (OIF). This solver enables efficient cross-chain order execution by discovering intents, finding optimal execution paths, and settling transactions across multiple blockchain networks.
66

7+
## Table of Contents
8+
9+
- [Overview](#overview)
10+
- [High-Level Architecture](#high-level-architecture)
11+
- [Architecture](#architecture)
12+
- [Project Structure](#project-structure)
13+
- [Component Responsibilities](#component-responsibilities)
14+
- [Quick Start](#quick-start)
15+
- [Configuration](#configuration)
16+
- [API Reference](#api-reference)
17+
- [OIF Demo CLI Tool](#oif-demo-cli-tool)
18+
- [Development](#development)
19+
- [License](#license)
20+
721
## Overview
822

923
The OIF Solver is designed to:
@@ -46,12 +60,12 @@ sequenceDiagram
4660
Settlement->>Core: PostFill Transaction (if needed)
4761
Core->>Delivery: Submit PostFill
4862
Delivery->>Core: PostFill Confirmed (Status: PostFilled)
49-
63+
5064
Note over Core,Settlement: Settlement Monitoring
5165
Core->>Settlement: Start Monitoring for Claim Readiness
5266
Settlement->>Core: Monitor Fill Proof
5367
Settlement->>Core: Dispute Period Passed
54-
68+
5569
Note over Core,Settlement: Pre-Claim & Claim
5670
Core->>Settlement: Generate PreClaim Transaction
5771
Settlement->>Core: PreClaim Transaction (if needed)
@@ -154,7 +168,7 @@ oif-solver/
154168
- Validates fill transactions
155169
- Extracts and stores fill proofs
156170
- Monitors when orders can be claimed
157-
- Manages dispute periods and oracle interactions
171+
- Manages dispute periods and settlement interactions
158172

159173
### solver-storage
160174

@@ -422,156 +436,218 @@ The `--log-level` flag acts as a fallback when `RUST_LOG` is not set:
422436
cargo run -- --config config/demo.toml --log-level info
423437
```
424438

425-
## Running the Demo
439+
## OIF Demo CLI Tool
426440

427-
The project includes a complete demo setup for testing cross-chain intent execution between two local chains.
441+
The project includes a unified CLI tool (`./oif-demo`) for testing cross-chain intent execution between two local chains. This tool provides a streamlined interface for all demo operations.
428442

429-
**Note:** The demo scripts have been tested on macOS systems only.
443+
**Note:** The demo has been tested on macOS systems only.
430444

431445
### Prerequisites
432446

433447
- [Foundry](https://book.getfoundry.sh/getting-started/installation) (for Anvil, Forge, and Cast)
434448
- Rust toolchain (stable)
449+
- Bash version > 4.0 (for `declare -g` support)
450+
- Additional dependencies: `jq`, `curl`, `bc`, `perl`
435451

436-
### Step 1: Setup Local Test Environment
437-
438-
First, run the setup script to start two local blockchain nodes and deploy all necessary contracts:
452+
### Quick Start
439453

440454
```bash
441-
# Make scripts executable (first time only)
442-
chmod +x scripts/demo/*.sh
455+
# 1. Start local environment and generate configuration
456+
./oif-demo env up
443457

444-
# Setup two local chains with all contracts deployed
445-
./scripts/demo/setup_local_anvil.sh
446-
```
458+
# 2. In another terminal, start the solver
459+
cargo run --bin solver -- --config config/demo.toml
447460

448-
This script will:
461+
# 3. Test a complete quote flow (build → submit → get quote → accept)
462+
./oif-demo quote test escrow permit2 A2B # Using Permit2 authorization
463+
# OR
464+
./oif-demo quote test escrow eip3009 A2B # Using EIP-3009 authorization
465+
# OR for onchain submission (direct to blockchain):
466+
./oif-demo intent test --onchain escrow A2B # Submit directly to InputSettler
449467

450-
1. Start two Anvil instances:
451-
- Origin chain (ID: 31337) on port 8545
452-
- Destination chain (ID: 31338) on port 8546
453-
2. Deploy two test tokens (TokenA and TokenB) on both chains
454-
3. Deploy settler contracts (InputSettler, OutputSettler)
455-
4. Create a `config/demo.toml` configuration file
456-
5. Fund test accounts with both tokens
457-
6. Approve token spending for settler contracts
468+
# 4. Monitor balances in real-time
469+
./oif-demo monitor 3 all
470+
```
458471

459-
### Step 2: Start the Solver Service
472+
### Commands Overview
460473

461-
In a new terminal, build and run the solver:
474+
#### Environment Management
462475

463476
```bash
464-
# Build the project
465-
cargo build
477+
# Start Anvil chains, deploy contracts, generate config
478+
./oif-demo env up
466479

467-
# Run the solver with local configuration
468-
cargo run --bin solver -- --config config/demo.toml
480+
# Check chain status and connectivity
481+
./oif-demo env status
469482

470-
# Or with debug logs for debugging
471-
RUST_LOG=solver_core=debug,solver_delivery=info,info cargo run --bin solver -- --config config/demo.toml
483+
# Stop Anvil chains
484+
./oif-demo env down
485+
486+
# Reset all data and environment
487+
./oif-demo env reset
472488
```
473489

474-
The solver will:
490+
#### Configuration Management
475491

476-
- Connect to both local chains
477-
- Start monitoring for new intents
478-
- Process discovered intents automatically
492+
```bash
493+
./oif-demo init config/demo.toml
494+
```
479495

480-
### Step 3: Run the Demo
496+
#### Intent Operations
481497

482-
In another terminal, execute the send intent script to create and observe a cross-chain intent:
498+
The demo supports two submission modes:
499+
- **Offchain**: Intents are submitted to the solver API (default)
500+
- **Onchain**: Intents are submitted directly to the blockchain via InputSettler.open()
483501

484-
#### On-Chain Intents
502+
##### Offchain Intent Submission (via Solver API)
485503

486504
```bash
487-
# Send with default tokens (TokenA → TokenA)
488-
./scripts/demo/send_onchain_intent.sh
505+
# Build various types of intents for offchain submission
506+
# Format: intent build <lock_type> <auth_type> <origin_chain> <dest_chain> <from_token> <to_token>
507+
./oif-demo intent build escrow permit2 31337 31338 TokenA TokenB # Escrow with Permit2
508+
./oif-demo intent build escrow eip3009 31337 31338 TokenA TokenB # Escrow with EIP-3009
509+
./oif-demo intent build compact permit2 31337 31338 TokenB TokenA # Compact with Permit2 (EIP-3009 not supported)
510+
511+
# Submit intent to solver API
512+
./oif-demo intent submit demo-output/post_intent.req.json
513+
514+
# Test command - builds and submits in one step
515+
# Format: intent test <lock_type> <auth_type> <token_pair>
516+
./oif-demo intent test escrow permit2 A2B # Escrow lock with Permit2 auth
517+
./oif-demo intent test escrow eip3009 A2B # Escrow lock with EIP-3009 auth
518+
./oif-demo intent test compact permit2 B2A # Compact lock with Permit2 auth (EIP-3009 not supported)
519+
```
489520

490-
# Send with specific token routing
491-
./scripts/demo/send_onchain_intent.sh <origin_token> <dest_token>
521+
##### Onchain Intent Submission (Direct to Blockchain)
492522

493-
# Examples of cross-token swaps:
494-
# TokenA on origin → TokenB on destination
495-
./scripts/demo/send_onchain_intent.sh 0x5FbDB2315678afecb367f032d93F642f64180aa3 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
523+
```bash
524+
# Build intent for onchain submission (no auth_type needed)
525+
# Format: intent build --onchain escrow <origin_chain> <dest_chain> <from_token> <to_token>
526+
./oif-demo intent build --onchain escrow 31337 31338 TokenA TokenB
527+
528+
# Submit intent directly to blockchain
529+
./oif-demo intent submit --onchain demo-output/post_intent.req.json
530+
531+
# Test command - builds and submits onchain in one step
532+
# Format: intent test --onchain escrow <token_pair>
533+
./oif-demo intent test --onchain escrow A2B # Submit directly to InputSettler
534+
./oif-demo intent test --onchain escrow B2A # TokenB → TokenA onchain
535+
536+
# Note: Onchain submission:
537+
# - Only supports escrow intents (not compact/resource locks)
538+
# - Requires token approval before submission
539+
# - Submits directly to InputSettler.open() on the blockchain
540+
# - Does not require permit2/eip3009 signatures
541+
```
496542

497-
# TokenB on origin → TokenA on destination
498-
./scripts/demo/send_onchain_intent.sh 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 0x5FbDB2315678afecb367f032d93F642f64180aa3
543+
##### Token Formats Supported
499544

500-
# Check all token balances
501-
./scripts/demo/send_onchain_intent.sh balances
545+
```bash
546+
# Token formats:
547+
# - Symbol names: TokenA, TokenB
548+
# - Direct addresses: 0x5FbDB2315678afecb367f032d93F642f64180aa3
549+
# - Token pairs for test: A2A, A2B, B2A, B2B
502550
```
503551

504-
#### Off-Chain Intents (Gasless)
552+
#### Quote Operations
505553

506554
```bash
507-
# Send with default tokens (TokenA → TokenA)
508-
./scripts/demo/send_offchain_intent.sh
555+
# Get quote for an intent
556+
./oif-demo quote get demo-output/get_quote.req.json
509557

510-
# Send with specific token routing
511-
./scripts/demo/send_offchain_intent.sh <origin_token> <dest_token>
558+
# Accept and execute a quote
559+
./oif-demo quote accept demo-output/get_quote.res.json
512560

513-
# Use direct discovery API
514-
./scripts/demo/send_offchain_intent.sh --direct
561+
# Test command - full flow: build → get quote → accept
562+
# Format: quote test <lock_type> <auth_type> <token_pair>
563+
./oif-demo quote test escrow permit2 A2B # Full flow with escrow lock and Permit2
564+
./oif-demo quote test escrow eip3009 A2B # Full flow with escrow lock and EIP-3009
565+
./oif-demo quote test compact permit2 B2A # Full flow with compact lock and Permit2 (EIP-3009 not supported)
566+
```
515567

516-
# Combine token routing with direct API
517-
./scripts/demo/send_offchain_intent.sh 0x5FbDB2315678afecb367f032d93F642f64180aa3 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 --direct
568+
#### Balance Monitoring
518569

519-
# Check all token balances
520-
./scripts/demo/send_offchain_intent.sh balances
570+
```bash
571+
# Check all balances
572+
./oif-demo balance all
573+
574+
# Check specific balance types
575+
./oif-demo balance user # User wallet balances
576+
./oif-demo balance recipient # Recipient balances
577+
./oif-demo balance solver # Solver balances
578+
./oif-demo balance settlers # All settler contract balances
579+
./oif-demo balance escrow # Escrow settler balances only
580+
./oif-demo balance compact # Compact settler balances only
581+
582+
# Monitor balances with auto-refresh
583+
./oif-demo monitor 5 all # Refresh every 5 seconds, show all
584+
./oif-demo monitor 3 user # Refresh every 3 seconds, user only
585+
./oif-demo monitor 10 settlers # Refresh every 10 seconds, settlers only
521586
```
522587

523-
#### Quote → Sign → Submit (One-shot)
588+
### Output File Naming Conventions
524589

525-
We provide a streamlined flow to request a quote, sign the server-provided EIP-712 digest, encode the StandardOrder, and submit it to the solver in one command.
590+
The demo tool generates files in the `demo-output/` directory following a clear naming convention:
526591

527-
```bash
528-
# Request a quote using defaults from config/demo.toml, then sign and submit
529-
./scripts/demo/send_quote_intent.sh # defaults to http://127.0.0.1:3000
530-
./scripts/demo/send_quote_intent.sh http://localhost:3000
531-
532-
# Alternatively, use a previously saved quote JSON
533-
./scripts/demo/build_transaction.sh scripts/demo/quote.json
534-
# Or via stdin
535-
cat scripts/demo/quote.json | ./scripts/demo/build_transaction.sh
536-
```
592+
- **`.req.json`** - Request payloads sent to the API
593+
- **`.res.json`** - Responses received from the API
537594

538-
What happens:
539-
- The quote API returns a Permit2 EIP-712 final digest and structured fields.
540-
- `build_transaction.sh` signs the digest with `--no-hash`, encodes the StandardOrder bytes, and POSTs to `/api/orders`.
541-
- Logs show nonce, deadlines, oracle, settler, token bytes32, signature, and payload preview.
595+
| File | Description | Generated By |
596+
|------|-------------|--------------|
597+
| `post_intent.req.json` | Intent submission request payload | `intent build` |
598+
| `post_intent.res.json` | Intent submission response | `intent submit` |
599+
| `get_quote.req.json` | Quote request payload | `intent build` |
600+
| `get_quote.res.json` | Quote response with pricing | `quote get` |
601+
| `post_quote.req.json` | Signed quote acceptance request | `quote accept` |
602+
| `post_quote.res.json` | Quote acceptance response | `quote accept` |
542603

543-
The scripts will:
604+
### Environment Setup Details
544605

545-
1. Show initial balances for the relevant tokens
546-
2. Create a cross-chain intent (user deposits tokens on origin chain)
547-
3. Wait for the solver to discover and fill the intent
548-
4. Show final balances demonstrating successful execution
606+
When you run `./oif-demo env up`, the tool will:
549607

550-
### What the Demo Demonstrates
608+
1. **Start Blockchain Networks**:
551609

552-
1. **Intent Creation**: User deposits tokens into the InputSettler contract on the origin chain
553-
2. **Discovery**: The solver detects the new intent through event monitoring
554-
3. **Execution**: The solver fills the intent on the destination chain
555-
4. **Settlement**: The solver claims rewards by providing attestations
556-
5. **Multi-Token Support**: Solver can handle different token pairs (TokenA → TokenA, TokenA → TokenB, etc.)
557-
6. **Cross-Token Swaps**: Demonstrates atomic swaps between different tokens across chains
610+
- Origin chain (ID: 31337) on port 8545
611+
- Destination chain (ID: 31338) on port 8546
558612

559-
### Monitoring the Demo
613+
2. **Deploy Smart Contracts**:
560614

561-
You can monitor the solver's activity through:
615+
- Test tokens (TokenA, TokenB) on both chains
616+
- Escrow settlers (InputSettler, OutputSettler)
617+
- Compact settlers
618+
- Oracle contracts for attestations
562619

563-
- Console logs (with debug level logging enabled)
564-
- Storage files in `./data/storage/` (when using file storage backend)
620+
3. **Generate Configuration**:
565621

566-
### Troubleshooting
622+
- Creates `config/demo.toml` with all contract addresses
623+
- Configures network settings and token mappings
624+
- Sets up account keys and signing configuration
567625

568-
If the demo doesn't work as expected:
626+
4. **Initialize Test Environment**:
627+
- Funds test accounts with tokens
628+
- Approves token spending for settler contracts
629+
- Validates all deployments and connectivity
630+
631+
### Running the Solver
632+
633+
After setting up the environment, start the solver in a separate terminal:
634+
635+
```bash
636+
# Build the project
637+
cargo build
569638

570-
1. Ensure all prerequisites are installed
571-
2. Check that no other processes are using ports 8545, 8546
572-
3. Verify the solver is running and connected to both chains
573-
4. Check solver logs for any error messages
574-
5. Ensure you have sufficient balance in test accounts
639+
# Run the solver with local configuration
640+
cargo run --bin solver -- --config config/demo.toml
641+
642+
# Or with debug logs for debugging
643+
RUST_LOG=solver_core=debug,solver_delivery=info,info cargo run --bin solver -- --config config/demo.toml
644+
```
645+
646+
The solver will:
647+
648+
- Connect to both local chains
649+
- Start monitoring for new intents
650+
- Process discovered intents automatically
575651

576652
## Development
577653

0 commit comments

Comments
 (0)