diff --git a/QUICKSTART.md b/QUICKSTART.md deleted file mode 100644 index f2748e8..0000000 --- a/QUICKSTART.md +++ /dev/null @@ -1,75 +0,0 @@ -# Quick Start Guide - -Get your Natural Language Agreement Oracle running in **under 2 minutes**! - -## Prerequisites - -- [Bun](https://bun.sh) installed -- [Foundry](https://book.getfoundry.sh/getting-started/installation) installed -- Both `alkahest` and `natural-language-agreements` repos cloned in same parent directory -- OpenAI API key - -## One-Command Setup - -```bash -export OPENAI_API_KEY=sk-your-key-here -./scripts/dev.sh -``` - -Done! The oracle is now running and listening for arbitration requests. - -**To stop:** -```bash -./scripts/stop.sh -``` - -## What Just Happened? - -The script: -1. ✅ Checked prerequisites -2. ✅ Started Anvil (local blockchain) -3. ✅ Deployed all contracts -4. ✅ Started the oracle - -## Test It - -In another terminal: -```bash -bun test tests/nlaOracle.test.ts -``` - -Watch the oracle terminal to see it process the arbitration! - -## Manual Steps (Optional) - -If you want more control: - -```bash -# Terminal 1: Blockchain -anvil - -# Terminal 2: Deploy and start oracle -bun run deploy -bun run oracle - -# Terminal 3: Test -bun test tests/nlaOracle.test.ts -``` - -## Deploy to Testnet - -```bash -# Get Sepolia ETH from faucet first -export DEPLOYER_PRIVATE_KEY=0x... -bun run cli/server/deploy.ts --network sepolia --rpc-url https://sepolia.infura.io/v3/YOUR-KEY - -# Start oracle -export ORACLE_PRIVATE_KEY=0x... -export OPENAI_API_KEY=sk-... -bun run cli/server/oracle.ts sepolia -``` - -## Need Help? - -- Full docs: [README.md](README.md) -- Example test: `tests/nlaOracle.test.ts` diff --git a/README.md b/README.md index e7fe346..44fed1a 100644 --- a/README.md +++ b/README.md @@ -49,21 +49,24 @@ Set your OpenAI API key and run everything: ```bash export OPENAI_API_KEY=sk-your-key-here -./scripts/dev.sh +nla dev ``` This will: - ✅ Check all prerequisites - ✅ Start Anvil (local blockchain) - ✅ Deploy all contracts +- ✅ Deploy and distribute mock ERC20 tokens - ✅ Start the oracle - ✅ Ready to test! To stop everything: ```bash -./scripts/stop.sh +nla stop ``` +> **Note:** If you haven't installed the CLI globally yet, run `bun link` first, or use `bun run cli/index.ts dev` instead. + ### Option 2: Manual Setup (Step by Step) #### 1. Start Local Blockchain @@ -78,16 +81,16 @@ anvil ```bash # Terminal 2: Deploy to localhost export OPENAI_API_KEY=sk-your-key-here -./scripts/deploy.sh localhost +nla deploy ``` -This creates `deployments/localhost.json` with all contract addresses. +This creates `cli/deployments/localhost.json` with all contract addresses. #### 3. Start Oracle ```bash # Terminal 2 (or 3): Start oracle -./scripts/start-oracle.sh localhost +nla start-oracle ``` #### 4. Test It @@ -99,6 +102,35 @@ bun test tests/nlaOracle.test.ts Watch the oracle terminal - you'll see it process arbitration requests in real-time! +## CLI Tools + +For a complete guide to the CLI commands, see [CLI Documentation](cli/README.md). + +### Quick CLI Examples + +```bash +# Create an escrow +nla escrow:create \ + --demand "The sky is blue" \ + --amount 10 \ + --token 0xa513e6e4b8f2a923d98304ec87f64353c4d5c853 \ + --oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 + +# Fulfill an escrow +nla escrow:fulfill \ + --escrow-uid 0x... \ + --fulfillment "The sky appears blue today" \ + --oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 + +# Check escrow status +nla escrow:status --escrow-uid 0x... + +# Collect approved escrow +nla escrow:collect \ + --escrow-uid 0x... \ + --fulfillment-uid 0x... +``` + ## Deployment to Other Networks ### Sepolia Testnet @@ -111,10 +143,10 @@ export ORACLE_PRIVATE_KEY=0x... export OPENAI_API_KEY=sk-... # 3. Deploy -./scripts/deploy.sh sepolia https://sepolia.infura.io/v3/YOUR-KEY +nla deploy sepolia https://sepolia.infura.io/v3/YOUR-KEY # 4. Start oracle -./scripts/start-oracle.sh sepolia +nla start-oracle sepolia ``` ### Mainnet @@ -126,19 +158,36 @@ export ORACLE_PRIVATE_KEY=0x... export OPENAI_API_KEY=sk-... # Deploy -./scripts/deploy.sh mainnet https://mainnet.infura.io/v3/YOUR-KEY +nla deploy mainnet https://mainnet.infura.io/v3/YOUR-KEY # Start oracle (consider running as a service) -./scripts/start-oracle.sh mainnet +nla start-oracle mainnet ``` -## Available Scripts +## Available Commands + +The `nla` CLI provides unified access to all functionality: ```bash -./scripts/dev.sh # Complete local setup (all-in-one) -./scripts/deploy.sh [network] # Deploy contracts to network -./scripts/start-oracle.sh [network] # Start oracle for network -./scripts/stop.sh # Stop all services +nla dev # Complete local setup (all-in-one) +nla deploy [network] [rpc] # Deploy contracts to network +nla start-oracle [network] # Start oracle for network +nla stop # Stop all services + +nla escrow:create [options] # Create a new escrow +nla escrow:fulfill [options] # Fulfill an existing escrow +nla escrow:collect [options] # Collect an approved escrow +nla escrow:status [options] # Check escrow status + +nla help # Show help +``` + +**NPM Scripts (alternative):** +```bash +bun run setup # Same as: nla dev +bun run deploy # Same as: nla deploy +bun run oracle # Same as: nla start-oracle +bun run stop # Same as: nla stop ``` ## Production Deployment @@ -166,7 +215,7 @@ sudo journalctl -u nla-oracle -f ```bash # Start in background -nohup ./scripts/start-oracle.sh mainnet > oracle.log 2>&1 & +nohup nla start-oracle mainnet > oracle.log 2>&1 & # Save PID echo $! > oracle.pid @@ -182,7 +231,7 @@ kill $(cat oracle.pid) screen -S oracle # Run oracle -./scripts/start-oracle.sh mainnet +nla start-oracle mainnet # Detach: Ctrl+A, then D # Reattach: screen -r oracle @@ -237,18 +286,31 @@ This project was created using `bun init` in bun v1.2.20. [Bun](https://bun.com) ``` natural-language-agreements/ -├── oracle.ts # Oracle CLI application -├── deploy.ts # Contract deployment script -├── index.ts # Development entry point +├── cli/ # CLI tools and server components +│ ├── index.ts # Main CLI entry point (nla command) +│ ├── README.md # CLI documentation +│ ├── client/ # User-facing escrow tools +│ │ ├── create-escrow.ts # Create escrow CLI +│ │ ├── fulfill-escrow.ts # Fulfill escrow CLI +│ │ └── collect-escrow.ts # Collect escrow CLI +│ ├── server/ # Server-side components +│ │ ├── deploy.ts # Contract deployment script +│ │ └── oracle.ts # Oracle service +│ ├── scripts/ # Shell scripts for orchestration +│ │ ├── dev.sh # Development environment setup +│ │ ├── deploy.sh # Deployment wrapper +│ │ ├── start-oracle.sh # Oracle starter +│ │ └── stop.sh # Cleanup script +│ └── deployments/ # Deployment addresses (generated) +│ ├── localhost.json +│ ├── sepolia.json +│ └── mainnet.json ├── clients/ -│ └── nla.ts # Natural Language Agreement client +│ └── nla.ts # Natural Language Agreement client library ├── tests/ -│ ├── nla.test.ts # Basic tests -│ └── nlaOracle.test.ts # Oracle arbitration tests -├── deployments/ # Deployment addresses (generated) -│ ├── localhost.json -│ ├── sepolia.json -│ └── mainnet.json +│ ├── nla.test.ts # Basic tests +│ └── nlaOracle.test.ts # Oracle arbitration tests +├── index.ts # Development entry point ├── package.json └── README.md ``` diff --git a/cli/README.md b/cli/README.md index 1f3e6a1..5a1a2bb 100644 --- a/cli/README.md +++ b/cli/README.md @@ -22,6 +22,9 @@ nla [options] **Available Commands:** - `dev` - Start local development environment (Anvil + Deploy + Oracle) +- `deploy` - Deploy contracts to blockchain +- `start-oracle` - Start the oracle service +- `stop` - Stop all services (Anvil + Oracle) - `escrow:create` - Create a new escrow with natural language demand - `escrow:fulfill` - Fulfill an existing escrow - `escrow:collect` - Collect an approved escrow @@ -116,6 +119,61 @@ nla escrow:collect \ ## Commands +### Development Commands + +#### Start Development Environment + +```bash +nla dev +``` + +Starts the complete local development environment: +1. Starts Anvil (local Ethereum node on port 8545) +2. Deploys all contracts +3. Deploys and distributes mock ERC20 tokens +4. Starts the oracle service + +**Keep this terminal open** - it runs the oracle! + +#### Deploy Contracts + +```bash +nla deploy [network] [rpc-url] + +# Examples: +nla deploy # Deploy to localhost +nla deploy localhost http://localhost:8545 # Specify network and RPC +``` + +Deploys all Alkahest contracts and mock tokens to the blockchain. Creates a deployment file at `cli/deployments/{network}.json`. + +#### Start Oracle + +```bash +nla start-oracle [network] + +# Examples: +nla start-oracle # Start oracle for localhost +nla start-oracle mainnet # Start oracle for mainnet +``` + +Starts the oracle service that listens for arbitration requests. Requires: +- `OPENAI_API_KEY` environment variable +- `ORACLE_PRIVATE_KEY` environment variable (defaults to Anvil account #1) +- Deployment file at `cli/deployments/{network}.json` + +#### Stop Services + +```bash +nla stop +``` + +Stops all running services: +- Anvil (local blockchain) +- Oracle processes + +### Escrow Commands + ### Create Escrow ```bash diff --git a/cli/deployments/localhost.json b/cli/deployments/localhost.json index 73d9362..89a0616 100644 --- a/cli/deployments/localhost.json +++ b/cli/deployments/localhost.json @@ -2,7 +2,7 @@ "network": "localhost", "chainId": 31337, "rpcUrl": "http://localhost:8545", - "deployedAt": "2025-12-12T09:19:50.255Z", + "deployedAt": "2025-12-12T09:34:49.631Z", "deployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "addresses": { "easSchemaRegistry": "0x5fbdb2315678afecb367f032d93f642f64180aa3", diff --git a/cli/index.ts b/cli/index.ts index f982508..623e553 100755 --- a/cli/index.ts +++ b/cli/index.ts @@ -11,6 +11,9 @@ Usage: Commands: dev Start local development environment (Anvil + Deploy + Oracle) + deploy Deploy contracts to blockchain + start-oracle Start the oracle service + stop Stop all services (Anvil + Oracle) escrow:create Create a new escrow with natural language demand escrow:fulfill Fulfill an existing escrow escrow:collect Collect an approved escrow @@ -38,6 +41,15 @@ Examples: # Start development environment nla dev + # Deploy contracts + nla deploy + + # Start oracle + nla start-oracle + + # Stop all services + nla stop + # Create an escrow nla escrow:create \\ --demand "The sky is blue" \\ @@ -97,15 +109,62 @@ function parseCliArgs() { return { command, ...values }; } +// Shell command handler +async function runShellCommand(scriptName: string, args: string[] = []) { + const { spawnSync } = await import("child_process"); + const scriptDir = import.meta.dir; + const scriptPath = `${scriptDir}/scripts/${scriptName}`; + + // Run the shell script + const result = spawnSync(scriptPath, args, { + stdio: "inherit", + cwd: process.cwd(), + shell: true, + }); + + process.exit(result.status || 0); +} + +// Server command handler (for deploy.ts, oracle.ts) +async function runServerCommand(scriptName: string, args: string[] = []) { + const { spawnSync } = await import("child_process"); + const scriptDir = import.meta.dir; + const scriptPath = `${scriptDir}/server/${scriptName}`; + + // Run the TypeScript file directly + const result = spawnSync("bun", ["run", scriptPath, ...args], { + stdio: "inherit", + cwd: process.cwd(), + }); + + process.exit(result.status || 0); +} + // Main function async function main() { try { const args = parseCliArgs(); const command = args.command; - // Handle dev command separately (runs shell script) + // Handle shell script commands (dev and stop need shell for process management) if (command === "dev") { - await runDevCommand(); + await runShellCommand("dev.sh"); + return; + } + + if (command === "stop") { + await runShellCommand("stop.sh"); + return; + } + + // Handle TypeScript commands that can run directly + if (command === "deploy") { + await runServerCommand("deploy.ts", Bun.argv.slice(3)); + return; + } + + if (command === "start-oracle") { + await runServerCommand("oracle.ts", Bun.argv.slice(3)); return; } @@ -152,24 +211,6 @@ async function main() { } } -// Dev command handler -async function runDevCommand() { - console.log("🚀 Starting development environment...\n"); - - const { spawnSync } = await import("child_process"); - const scriptDir = import.meta.dir; - const devScriptPath = `${scriptDir}/scripts/dev.sh`; - - // Run the dev.sh script - const result = spawnSync(devScriptPath, [], { - stdio: "inherit", - cwd: process.cwd(), - shell: true, - }); - - process.exit(result.status || 0); -} - // Status command handler async function runStatusCommand(args: any) { const escrowUid = args["escrow-uid"]; diff --git a/cli/scripts/deploy.sh b/cli/scripts/deploy.sh deleted file mode 100755 index 7441206..0000000 --- a/cli/scripts/deploy.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - -# Deploy Alkahest contracts to blockchain -# Usage: ./deploy.sh [network] [rpc-url] - -set -e # Exit on error - -# Colors for output -GREEN='\033[0;32m' -BLUE='\033[0;34m' -RED='\033[0;31m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# Default values -NETWORK=${1:-localhost} -RPC_URL=${2:-http://localhost:8545} - -echo -e "${BLUE}🚀 Deploying Alkahest Contracts${NC}\n" - -# Check if deployer private key is set -if [ -z "$DEPLOYER_PRIVATE_KEY" ]; then - echo -e "${YELLOW}⚠️ DEPLOYER_PRIVATE_KEY not set, using default Anvil key${NC}" - export DEPLOYER_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -fi - -# Check if alkahest exists -if [ ! -d "../alkahest" ]; then - echo -e "${RED}❌ Error: alkahest repository not found in parent directory${NC}" - echo "Please clone it first: git clone https://github.com/arkhai-io/alkahest.git" - exit 1 -fi - -# Check if contract artifacts exist -if [ ! -d "../alkahest/sdks/ts/src/contracts" ]; then - echo -e "${RED}❌ Error: Contract artifacts not found${NC}" - echo "Expected path: ../alkahest/sdks/ts/src/contracts" - exit 1 -fi - -echo -e "${GREEN}✅ Contract artifacts found${NC}\n" - -# Run deployment -echo -e "${BLUE}📝 Deploying to ${NETWORK}...${NC}" -bun run cli/server/deploy.ts --network "$NETWORK" --rpc-url "$RPC_URL" - -# Check if deployment was successful -if [ $? -eq 0 ]; then - echo -e "\n${GREEN}✨ Deployment complete!${NC}" - echo -e "${BLUE}Deployment file saved to: cli/deployments/${NETWORK}.json${NC}\n" - - echo -e "${YELLOW}Next steps:${NC}" - echo "1. Start the oracle with:" - echo " ./cli/scripts/start-oracle.sh $NETWORK" - echo "" - echo "2. Or using npm script:" - echo " bun run oracle" - echo "" - echo "3. Or manually:" - echo " bun run cli/server/oracle.ts --deployment ./cli/deployments/${NETWORK}.json" -else - echo -e "\n${RED}❌ Deployment failed${NC}" - exit 1 -fi diff --git a/cli/scripts/dev.sh b/cli/scripts/dev.sh index 6bbbf2c..2bbe694 100755 --- a/cli/scripts/dev.sh +++ b/cli/scripts/dev.sh @@ -103,12 +103,12 @@ fi # Deploy contracts echo -e "\n${BLUE}📝 Deploying contracts...${NC}\n" export DEPLOYER_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -./cli/scripts/deploy.sh localhost http://localhost:8545 +bun run cli/server/deploy.ts --network localhost --rpc-url http://localhost:8545 # Start oracle echo -e "\n${BLUE}🚀 Starting oracle...${NC}\n" export ORACLE_PRIVATE_KEY="0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" -./cli/scripts/start-oracle.sh localhost +bun run cli/server/oracle.ts --deployment ./cli/deployments/localhost.json --openai-api-key "$OPENAI_API_KEY" --private-key "$ORACLE_PRIVATE_KEY" # Cleanup function cleanup() { diff --git a/cli/scripts/start-oracle.sh b/cli/scripts/start-oracle.sh deleted file mode 100755 index a39c1b2..0000000 --- a/cli/scripts/start-oracle.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash - -# Start the Natural Language Agreement Oracle -# Usage: ./start-oracle.sh [network] - -set -e # Exit on error - -# Colors for output -GREEN='\033[0;32m' -BLUE='\033[0;34m' -RED='\033[0;31m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# Load .env file if it exists -if [ -f ".env" ]; then - export $(cat .env | grep -v '^#' | xargs) -fi - -# Default network -NETWORK=${1:-localhost} -DEPLOYMENT_FILE="./cli/deployments/${NETWORK}.json" - -echo -e "${BLUE}🚀 Starting Natural Language Agreement Oracle${NC}\n" - -# Check if deployment file exists -if [ ! -f "$DEPLOYMENT_FILE" ]; then - echo -e "${RED}❌ Error: Deployment file not found: $DEPLOYMENT_FILE${NC}" - echo "Please deploy contracts first:" - echo " ./cli/scripts/deploy.sh $NETWORK" - exit 1 -fi - -# Check if OpenAI API key is set -if [ -z "$OPENAI_API_KEY" ]; then - echo -e "${RED}❌ Error: OPENAI_API_KEY environment variable is not set${NC}" - echo "Please set it:" - echo " export OPENAI_API_KEY=sk-your-key-here" - exit 1 -fi - -# Check if Oracle private key is set -if [ -z "$ORACLE_PRIVATE_KEY" ]; then - echo -e "${YELLOW}⚠️ ORACLE_PRIVATE_KEY not set, using default Anvil key${NC}" - export ORACLE_PRIVATE_KEY="0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" -fi - -# Display configuration -echo -e "${GREEN}Configuration:${NC}" -echo " Network: $NETWORK" -echo " Deployment: $DEPLOYMENT_FILE" -echo " Oracle Key: ${ORACLE_PRIVATE_KEY:0:6}...${ORACLE_PRIVATE_KEY: -4}" -echo "" - -# Start oracle -echo -e "${BLUE}👂 Starting oracle (Press Ctrl+C to stop)...${NC}\n" -bun run cli/server/oracle.ts \ - --deployment "$DEPLOYMENT_FILE" \ - --openai-api-key "$OPENAI_API_KEY" \ - --private-key "$ORACLE_PRIVATE_KEY" diff --git a/package.json b/package.json index f760a1d..2f0a9e8 100644 --- a/package.json +++ b/package.json @@ -13,13 +13,13 @@ "dev": "bun run index.ts", "start": "bun run index.ts", "test": "bun test ./tests --exclude alkahest-ts/** ", - "setup": "./cli/scripts/dev.sh", - "deploy": "./cli/scripts/deploy.sh", - "oracle": "./cli/scripts/start-oracle.sh", - "stop": "./cli/scripts/stop.sh", - "escrow:create": "bun run cli/client/create-escrow.ts", - "escrow:fulfill": "bun run cli/client/fulfill-escrow.ts", - "escrow:collect": "bun run cli/client/collect-escrow.ts" + "setup": "bun run cli/index.ts dev", + "deploy": "bun run cli/index.ts deploy", + "oracle": "bun run cli/index.ts start-oracle", + "stop": "bun run cli/index.ts stop", + "escrow:create": "bun run cli/index.ts escrow:create", + "escrow:fulfill": "bun run cli/index.ts escrow:fulfill", + "escrow:collect": "bun run cli/index.ts escrow:collect" }, "peerDependencies": { "typescript": "^5.9.3"