commit
d15bcecd1b
10
.env.example
10
.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
|
||||
ORACLE_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
|
||||
|
||||
# EAS (Ethereum Attestation Service) Contract Address (optional)
|
||||
# If you used the deploy script, get this from deployments/<network>.json
|
||||
# EAS_CONTRACT_ADDRESS=0x...
|
||||
|
|
|
|||
173
INSTALL.md
173
INSTALL.md
|
|
@ -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
|
||||
|
|
@ -179,8 +179,7 @@ nla escrow:collect \
|
|||
```bash
|
||||
# 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
|
||||
|
|
@ -194,8 +193,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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
@ -164,7 +165,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <your-key>");
|
||||
console.error(" 2. Use for this command only: --private-key <your-key>");
|
||||
console.error(" 3. Set PRIVATE_KEY environment variable");
|
||||
console.error("\nRun with --help for usage information.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ Usage:
|
|||
|
||||
Options:
|
||||
--private-key <key> Private key of the oracle operator (optional, loaded from .env)
|
||||
--rpc-url <url> RPC URL to connect to (optional, overrides deployment file)
|
||||
--openai-api-key <key> OpenAI API key (optional, loaded from .env)
|
||||
--anthropic-api-key <key> Anthropic API key (optional, loaded from .env)
|
||||
--openrouter-api-key <key> OpenRouter API key (optional, loaded from .env)
|
||||
|
|
@ -43,7 +44,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
|
||||
|
|
@ -62,11 +63,14 @@ 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
|
||||
|
||||
Example .env file:
|
||||
ORACLE_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
|
||||
PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
|
||||
OPENAI_API_KEY=sk-...
|
||||
ANTHROPIC_API_KEY=sk-ant-...
|
||||
OPENROUTER_API_KEY=sk-or-...
|
||||
|
|
@ -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 <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);
|
||||
}
|
||||
|
|
@ -153,8 +161,7 @@ async function main() {
|
|||
console.error("\n💡 You can either:");
|
||||
console.error(" 1. Set it globally: nla wallet:set --private-key <your-key>");
|
||||
console.error(" 2. Use for this command only: --private-key <your-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);
|
||||
}
|
||||
|
|
@ -172,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
|
||||
|
|
@ -197,7 +204,7 @@ async function main() {
|
|||
const walletClient = createWalletClient({
|
||||
account,
|
||||
chain,
|
||||
transport: http(deployment.rpcUrl),
|
||||
transport: http(rpcUrl),
|
||||
}).extend(publicActions) as any;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "nla",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.8",
|
||||
"description": "Natural Language Agreement Oracle - CLI for creating and managing blockchain agreements using natural language",
|
||||
"type": "module",
|
||||
"private": false,
|
||||
|
|
|
|||
Loading…
Reference in New Issue