Add cli commands

This commit is contained in:
ngoc 2025-12-12 16:37:03 +07:00
parent 0d5abc519c
commit b46cb3512a
No known key found for this signature in database
GPG Key ID: 51FE6110113A5C32
9 changed files with 217 additions and 255 deletions

View File

@ -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`

114
README.md
View File

@ -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
```

View File

@ -22,6 +22,9 @@ nla <command> [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

View File

@ -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",

View File

@ -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"];

View File

@ -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

View File

@ -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() {

View File

@ -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"

View File

@ -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"