From d031389bc3269d6740efdd77016b97c6e26b063a Mon Sep 17 00:00:00 2001 From: ngoc Date: Mon, 2 Feb 2026 16:12:38 +0700 Subject: [PATCH 1/6] fix: nla dev private key --- .env.example | 2 +- INSTALL.md | 173 ------------------------------------------- README.md | 4 +- cli/README.md | 2 +- cli/commands/dev.ts | 20 ++++- cli/index.ts | 2 +- cli/server/oracle.ts | 7 +- 7 files changed, 24 insertions(+), 186 deletions(-) delete mode 100644 INSTALL.md diff --git a/.env.example b/.env.example index cefda76..544d02d 100644 --- a/.env.example +++ b/.env.example @@ -25,7 +25,7 @@ RPC_URL=http://localhost:8545 # This account submits arbitration decisions on-chain # IMPORTANT: Ensure this account has sufficient ETH for gas! # The key below is from Anvil's default accounts - DO NOT USE IN PRODUCTION -ORACLE_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d +PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d # EAS (Ethereum Attestation Service) Contract Address (optional) # If you used the deploy script, get this from deployments/.json diff --git a/INSTALL.md b/INSTALL.md deleted file mode 100644 index e8f4067..0000000 --- a/INSTALL.md +++ /dev/null @@ -1,173 +0,0 @@ -# Installing NLA CLI Globally - -## Prerequisites - -- Node.js >= 18.0.0 -- npm or yarn or pnpm -- A blockchain node (local Anvil or remote RPC URL) -- At least one LLM provider API key (OpenAI, Anthropic, or OpenRouter) - -## Installation - -### Global Installation (Recommended) - -Install the NLA CLI globally to use it from anywhere: - -```bash -npm install -g nla -``` - -Or with yarn: -```bash -yarn global add nla -``` - -Or with pnpm: -```bash -pnpm add -g nla -``` - -### Verify Installation - -```bash -nla --help -``` - -## Configuration - -Create a `.env` file in your project directory: - -```bash -# Copy the example environment file -cp node_modules/nla/.env.example .env - -# Edit with your configuration -nano .env -``` - -Required environment variables: -```bash -# At least one LLM provider API key -OPENAI_API_KEY=sk-... -# OR -ANTHROPIC_API_KEY=sk-ant-... -# OR -OPENROUTER_API_KEY=sk-or-... - -# Oracle configuration -ORACLE_PRIVATE_KEY=0x... -RPC_URL=http://localhost:8545 - -# Optional: For enhanced search -PERPLEXITY_API_KEY=pplx-... -``` - -## Quick Start - -### 1. Start Development Environment - -```bash -nla dev -``` - -This will: -- Start Anvil (local blockchain) -- Deploy all contracts -- Start the oracle - -### 2. Create an Escrow - -```bash -nla escrow:create \ - --demand "The sky is blue" \ - --amount 10 \ - --token 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853 \ - --oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -``` - -### 3. Fulfill an Escrow - -```bash -nla escrow:fulfill \ - --escrow-uid 0x... \ - --fulfillment "The sky appears blue today" \ - --oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 -``` - -### 4. Collect Payment - -```bash -nla escrow:collect \ - --escrow-uid 0x... \ - --fulfillment-uid 0x... -``` - -## Uninstallation - -```bash -npm uninstall -g nla -``` - -## Development - -If you want to contribute or modify the CLI: - -```bash -# Clone the repository -git clone https://github.com/arkhai-io/natural-language-agreements.git -cd natural-language-agreements - -# Install dependencies -npm install - -# Build -npm run build - -# Link locally -npm link -``` - -## Troubleshooting - -### Command not found after installation - -Make sure your npm global bin directory is in your PATH: - -```bash -# Check npm global bin path -npm bin -g - -# Add to PATH (add to ~/.bashrc or ~/.zshrc) -export PATH="$(npm bin -g):$PATH" -``` - -### Permission errors on Linux/Mac - -If you get permission errors, either: - -1. Use a Node version manager (recommended): -```bash -# Install nvm -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash - -# Install and use Node -nvm install 18 -nvm use 18 - -# Now install without sudo -npm install -g nla -``` - -2. Or configure npm to use a different directory: -```bash -mkdir ~/.npm-global -npm config set prefix '~/.npm-global' -echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc -source ~/.bashrc -``` - -## Support - -For issues and questions: -- GitHub: https://github.com/arkhai-io/natural-language-agreements/issues -- Documentation: https://github.com/arkhai-io/natural-language-agreements diff --git a/README.md b/README.md index 801021f..36f7214 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,7 @@ nla escrow:collect \ # 1. Get Sepolia ETH from faucet # 2. Set your keys export DEPLOYER_PRIVATE_KEY=0x... -export ORACLE_PRIVATE_KEY=0x... +export PRIVATE_KEY=0x... export OPENAI_API_KEY=sk-... # 3. Deploy @@ -195,7 +195,7 @@ nla start-oracle sepolia ```bash # ⚠️ PRODUCTION - Be careful! export DEPLOYER_PRIVATE_KEY=0x... -export ORACLE_PRIVATE_KEY=0x... +export PRIVATE_KEY=0x... export OPENAI_API_KEY=sk-... # Deploy diff --git a/cli/README.md b/cli/README.md index 034fd48..5f2fcaf 100644 --- a/cli/README.md +++ b/cli/README.md @@ -159,7 +159,7 @@ 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) +- `PRIVATE_KEY` environment variable (defaults to Anvil account #1) - Deployment file at `cli/deployments/{network}.json` #### Stop Services diff --git a/cli/commands/dev.ts b/cli/commands/dev.ts index 10ddd8b..87a6744 100644 --- a/cli/commands/dev.ts +++ b/cli/commands/dev.ts @@ -1,7 +1,7 @@ import { spawn, spawnSync } from "child_process"; import { existsSync, readFileSync, writeFileSync, createWriteStream, unlinkSync } from "fs"; import { join } from "path"; -import { getCurrentEnvironment, setCurrentEnvironment } from "../utils.js"; +import { getCurrentEnvironment, setCurrentEnvironment, getPrivateKey } from "../utils.js"; // Colors for console output const colors = { @@ -67,7 +67,7 @@ function isPortInUse(port: number): boolean { } // Dev command - Start complete development environment -export async function runDevCommand(cliDir: string, envPath?: string) { +export async function runDevCommand(cliDir: string, envPath?: string, cliPrivateKey?: string) { console.log(`${colors.blue}════════════════════════════════════════════════════════${colors.reset}`); console.log(`${colors.blue} Natural Language Agreement Oracle - Quick Setup${colors.reset}`); console.log(`${colors.blue}════════════════════════════════════════════════════════${colors.reset}\n`); @@ -86,6 +86,9 @@ export async function runDevCommand(cliDir: string, envPath?: string) { loadEnvFile(envPath); console.log(''); + // Get private key from CLI arg, config, or env (same pattern as other commands) + const privateKey = cliPrivateKey || getPrivateKey(); + // Check prerequisites console.log(`${colors.blue}📋 Checking prerequisites...${colors.reset}\n`); @@ -166,7 +169,11 @@ export async function runDevCommand(cliDir: string, envPath?: string) { // Deploy contracts console.log(`\n${colors.blue}📝 Deploying contracts...${colors.reset}\n`); const deployScript = join(cliDir, 'server', 'deploy.js'); - const deployResult = spawnSync('bun', ['run', deployScript, '--network', 'localhost', '--rpc-url', 'http://localhost:8545'], { + const deployArgs = ['run', deployScript, '--network', 'localhost', '--rpc-url', 'http://localhost:8545']; + if (privateKey) { + deployArgs.push('--private-key', privateKey); + } + const deployResult = spawnSync('bun', deployArgs, { stdio: 'inherit', cwd: process.cwd() }); @@ -185,7 +192,12 @@ export async function runDevCommand(cliDir: string, envPath?: string) { const distPath = join(cliDir, 'deployments', 'devnet.json'); const deploymentFile = existsSync(sourcePath) ? sourcePath : distPath; - const oracleProcess = spawn('bun', ['run', oracleScript, '--deployment', deploymentFile], { + const oracleArgs = ['run', oracleScript, '--deployment', deploymentFile]; + if (privateKey) { + oracleArgs.push('--private-key', privateKey); + } + + const oracleProcess = spawn('bun', oracleArgs, { stdio: 'inherit', cwd: process.cwd() }); diff --git a/cli/index.ts b/cli/index.ts index ea8a17c..7b7e4cc 100755 --- a/cli/index.ts +++ b/cli/index.ts @@ -164,7 +164,7 @@ async function main() { // Handle dev and stop commands if (command === "dev") { - await runDevCommand(__dirname, args.env as string | undefined); + await runDevCommand(__dirname, args.env as string | undefined, args["private-key"] as string | undefined); return; } diff --git a/cli/server/oracle.ts b/cli/server/oracle.ts index 1a26355..c0f4ee8 100644 --- a/cli/server/oracle.ts +++ b/cli/server/oracle.ts @@ -43,7 +43,7 @@ Options: --help, -h Display this help message Environment Variables (from .env file or environment): - ORACLE_PRIVATE_KEY Private key of the oracle operator + PRIVATE_KEY Private key of the oracle operator OPENAI_API_KEY OpenAI API key ANTHROPIC_API_KEY Anthropic API key OPENROUTER_API_KEY OpenRouter API key @@ -66,7 +66,7 @@ Examples: bun oracle.ts --openai-api-key sk-... --env .env.local Example .env file: - ORACLE_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 OPENAI_API_KEY=sk-... ANTHROPIC_API_KEY=sk-ant-... OPENROUTER_API_KEY=sk-or-... @@ -153,8 +153,7 @@ async function main() { console.error("\n💡 You can either:"); console.error(" 1. Set it globally: nla wallet:set --private-key "); console.error(" 2. Use for this command only: --private-key "); - console.error(" 3. Set ORACLE_PRIVATE_KEY in .env file"); - console.error(" 4. Set PRIVATE_KEY environment variable"); + console.error(" 3. Set PRIVATE_KEY environment variable"); console.error("\nRun with --help for usage information."); process.exit(1); } From 8fc422b166ca5c059fa384dadc104be3504b34d6 Mon Sep 17 00:00:00 2001 From: ngoc Date: Mon, 2 Feb 2026 16:12:48 +0700 Subject: [PATCH 2/6] 1.0.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fd00b7d..f7c5294 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nla", - "version": "1.0.5", + "version": "1.0.6", "description": "Natural Language Agreement Oracle - CLI for creating and managing blockchain agreements using natural language", "type": "module", "private": false, From 562793312bcf801a2feaf347c55d6fd67933709d Mon Sep 17 00:00:00 2001 From: ngoc Date: Mon, 2 Feb 2026 16:19:07 +0700 Subject: [PATCH 3/6] =?UTF-8?q?chore:=20update=20d=C3=B3c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 10 ++-------- README.md | 2 -- cli/server/deploy.ts | 15 ++++++++++----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/.env.example b/.env.example index 544d02d..ded86c3 100644 --- a/.env.example +++ b/.env.example @@ -4,11 +4,11 @@ # DEPLOYMENT CONFIGURATION # ================================ -# Deployer's private key (used for contract deployment) +# Private key (used for deployment and oracle operations) # IMPORTANT: This should be a funded account with enough ETH for gas # NEVER commit your real private key! # The key below is from Anvil's default accounts - DO NOT USE IN PRODUCTION -DEPLOYER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 # ================================ # ORACLE CONFIGURATION @@ -21,12 +21,6 @@ DEPLOYER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf # Mainnet: https://mainnet.infura.io/v3/YOUR-INFURA-KEY RPC_URL=http://localhost:8545 -# Oracle operator's private key (required for oracle) -# This account submits arbitration decisions on-chain -# IMPORTANT: Ensure this account has sufficient ETH for gas! -# The key below is from Anvil's default accounts - DO NOT USE IN PRODUCTION -PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d - # EAS (Ethereum Attestation Service) Contract Address (optional) # If you used the deploy script, get this from deployments/.json # EAS_CONTRACT_ADDRESS=0x... diff --git a/README.md b/README.md index 36f7214..23c1790 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,6 @@ nla escrow:collect \ ```bash # 1. Get Sepolia ETH from faucet # 2. Set your keys -export DEPLOYER_PRIVATE_KEY=0x... export PRIVATE_KEY=0x... export OPENAI_API_KEY=sk-... @@ -194,7 +193,6 @@ nla start-oracle sepolia ```bash # ⚠️ PRODUCTION - Be careful! -export DEPLOYER_PRIVATE_KEY=0x... export PRIVATE_KEY=0x... export OPENAI_API_KEY=sk-... diff --git a/cli/server/deploy.ts b/cli/server/deploy.ts index 4bca840..5cc57bb 100644 --- a/cli/server/deploy.ts +++ b/cli/server/deploy.ts @@ -13,6 +13,7 @@ import { mainnet, sepolia, baseSepolia, foundry } from "viem/chains"; import { writeFileSync, existsSync, mkdirSync } from "fs"; import { resolve } from "path"; import { fixtures, contracts } from "alkahest-ts"; +import { getPrivateKey } from "../utils.js"; // Helper function to display usage function displayHelp() { @@ -30,7 +31,7 @@ Options: --help, -h Display this help message Environment Variables (alternative to CLI options): - DEPLOYER_PRIVATE_KEY Deployer's private key + PRIVATE_KEY Deployer's private key RPC_URL Custom RPC URL Networks: @@ -47,7 +48,7 @@ Examples: bun deploy.ts --network sepolia --private-key 0x... --rpc-url https://sepolia.infura.io/v3/YOUR-KEY # Using environment variables - export DEPLOYER_PRIVATE_KEY=0x... + export PRIVATE_KEY=0x... bun deploy.ts --network localhost `); } @@ -98,7 +99,7 @@ async function main() { // Get configuration const network = args.network; - const privateKey = args["private-key"] || process.env.DEPLOYER_PRIVATE_KEY; + const privateKey = args["private-key"] || getPrivateKey(); let rpcUrl = args["rpc-url"] || process.env.RPC_URL; // Validate required parameters @@ -109,8 +110,12 @@ async function main() { } if (!privateKey) { - console.error("❌ Error: Private key is required. Use --private-key or set DEPLOYER_PRIVATE_KEY"); - console.error("Run with --help for usage information."); + console.error("❌ Error: Private key is required."); + console.error("\n💡 You can either:"); + console.error(" 1. Set it globally: nla wallet:set --private-key "); + console.error(" 2. Use for this command only: --private-key "); + console.error(" 3. Set PRIVATE_KEY environment variable"); + console.error("\nRun with --help for usage information."); process.exit(1); } From 42677dd0b12dafc0005fbd2fdb1ce4e050f0d919 Mon Sep 17 00:00:00 2001 From: ngoc Date: Mon, 2 Feb 2026 16:24:01 +0700 Subject: [PATCH 4/6] 1.0.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f7c5294..2e5713b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nla", - "version": "1.0.6", + "version": "1.0.7", "description": "Natural Language Agreement Oracle - CLI for creating and managing blockchain agreements using natural language", "type": "module", "private": false, From 8178e6dbdd4a859d6c9aac6fde4918f371c44623 Mon Sep 17 00:00:00 2001 From: ngoc Date: Mon, 2 Feb 2026 16:47:54 +0700 Subject: [PATCH 5/6] fix: start-oracle with custom rpc --- cli/index.ts | 1 + cli/server/oracle.ts | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/cli/index.ts b/cli/index.ts index 7b7e4cc..5c559d3 100755 --- a/cli/index.ts +++ b/cli/index.ts @@ -135,6 +135,7 @@ function parseCliArgs() { "arbitration-prompt": { type: "string" }, "env": { type: "string" }, "environment": { type: "string" }, + "help": { type: "boolean", short: "h" }, }, strict: command !== "switch" && command !== "network", // Allow positional args for switch command allowPositionals: command === "switch" || command === "network", diff --git a/cli/server/oracle.ts b/cli/server/oracle.ts index c0f4ee8..f7947d6 100644 --- a/cli/server/oracle.ts +++ b/cli/server/oracle.ts @@ -33,6 +33,7 @@ Usage: Options: --private-key Private key of the oracle operator (optional, loaded from .env) + --rpc-url RPC URL to connect to (optional, overrides deployment file) --openai-api-key OpenAI API key (optional, loaded from .env) --anthropic-api-key Anthropic API key (optional, loaded from .env) --openrouter-api-key OpenRouter API key (optional, loaded from .env) @@ -62,6 +63,9 @@ Examples: # Using specific deployment file bun oracle.ts --deployment ./deployments/sepolia.json + # Using custom RPC URL + bun oracle.ts --rpc-url https://eth-mainnet.g.alchemy.com/v2/YOUR-KEY + # Mix of .env and command-line parameters bun oracle.ts --openai-api-key sk-... --env .env.local @@ -80,6 +84,7 @@ function parseCliArgs() { args: process.argv.slice(2), options: { "private-key": { type: "string" }, + "rpc-url": { type: "string" }, "openai-api-key": { type: "string" }, "anthropic-api-key": { type: "string" }, "openrouter-api-key": { type: "string" }, @@ -133,6 +138,7 @@ async function main() { console.log(`✅ Loaded deployment (${deployment.network})\n`); const privateKey = args["private-key"] || getPrivateKey(); + const rpcUrl = args["rpc-url"] || deployment.rpcUrl; const openaiApiKey = args["openai-api-key"] || process.env.OPENAI_API_KEY; const anthropicApiKey = args["anthropic-api-key"] || process.env.ANTHROPIC_API_KEY; const openrouterApiKey = args["openrouter-api-key"] || process.env.OPENROUTER_API_KEY; @@ -140,10 +146,12 @@ async function main() { const pollingInterval = parseInt(args["polling-interval"] || "5000"); // Validate required parameters - if (!deployment?.rpcUrl) { - console.error("❌ Error: RPC URL not found in deployment file."); - console.error(" Current environment:", getCurrentEnvironment()); - console.error(" Make sure the deployment file exists for your current network."); + if (!rpcUrl) { + console.error("❌ Error: RPC URL not found."); + console.error(" Please either:"); + console.error(" 1. Use --rpc-url "); + console.error(" 2. Use a deployment file with rpcUrl set"); + console.error(" 3. Set RPC_URL environment variable"); console.error("Run with --help for usage information."); process.exit(1); } @@ -171,7 +179,7 @@ async function main() { console.log("🚀 Starting Natural Language Agreement Oracle...\n"); console.log("Configuration:"); - console.log(` 📡 RPC URL: ${deployment.rpcUrl}`); + console.log(` 📡 RPC URL: ${rpcUrl}`); console.log(` 🔑 Oracle Key: ${privateKey.slice(0, 6)}...${privateKey.slice(-4)}`); // Show available providers @@ -196,7 +204,7 @@ async function main() { const walletClient = createWalletClient({ account, chain, - transport: http(deployment.rpcUrl), + transport: http(rpcUrl), }).extend(publicActions) as any; From 0b65c5e370ce4462cfd0ef5f5f2db43f28ceee27 Mon Sep 17 00:00:00 2001 From: ngoc Date: Mon, 2 Feb 2026 16:48:04 +0700 Subject: [PATCH 6/6] 1.0.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2e5713b..6082040 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nla", - "version": "1.0.7", + "version": "1.0.8", "description": "Natural Language Agreement Oracle - CLI for creating and managing blockchain agreements using natural language", "type": "module", "private": false,