Refactor nla cli app

This commit is contained in:
ngoc 2025-12-12 16:20:43 +07:00
parent 0d99b7521b
commit 0d5abc519c
No known key found for this signature in database
GPG Key ID: 51FE6110113A5C32
14 changed files with 476 additions and 72 deletions

View File

@ -61,12 +61,12 @@ bun test tests/nlaOracle.test.ts
```bash
# Get Sepolia ETH from faucet first
export DEPLOYER_PRIVATE_KEY=0x...
bun run setups/deploy.ts --network sepolia --rpc-url https://sepolia.infura.io/v3/YOUR-KEY
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 setups/oracle.ts sepolia
bun run cli/server/oracle.ts sepolia
```
## Need Help?

View File

@ -2,19 +2,72 @@
User-friendly command-line tools to interact with Natural Language Agreement escrows.
## Installation
First, install the CLI globally:
```bash
bun link
```
Now you can use `nla` from anywhere in your terminal!
## Unified CLI
The `nla` command provides a unified interface for all escrow operations:
```bash
nla <command> [options]
```
**Available Commands:**
- `dev` - Start local development environment (Anvil + Deploy + Oracle)
- `escrow:create` - Create a new escrow with natural language demand
- `escrow:fulfill` - Fulfill an existing escrow
- `escrow:collect` - Collect an approved escrow
- `escrow:status` - Check the status of an escrow
- `help` - Display help message
## Quick Start
### Start Development Environment
The easiest way to get started is with the `dev` command:
```bash
nla dev
```
This will:
1. Start Anvil (local Ethereum node)
2. Deploy all contracts
3. Deploy mock ERC20 tokens and distribute them
4. Start the oracle listening for arbitration requests
**Note:** Keep this terminal open - it runs the oracle. Open a new terminal for creating escrows.
### Prerequisites
Before running `nla dev`, set your OpenAI API key:
```bash
export OPENAI_API_KEY=sk-your-key-here
```
For creating escrows, also set:
```bash
export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
```
### 1. Create an Escrow
Create an escrow with a natural language demand:
```bash
bun run escrow:create \
nla escrow:create \
--demand "The sky is blue" \
--amount 10 \
--token <TOKEN_ADDRESS_FROM_DEPLOYMENT> \
--oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 \
--private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
--token 0xa513e6e4b8f2a923d98304ec87f64353c4d5c853 \
--oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
```
> **Note:** Get the token address from the deployment output. The deployment creates 3 test tokens (TSTA, TSTB, TSTC) and distributes 10,000 of each to all test accounts.
@ -23,31 +76,42 @@ bun run escrow:create \
### 2. Fulfill the Escrow
Someone else (or you with a different key) can fulfill it:
Switch to a different account:
```bash
bun run escrow:fulfill \
export PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
nla escrow:fulfill \
--escrow-uid 0x... \
--fulfillment "The sky appears blue today" \
--oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 \
--private-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
--oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
```
**Save the Fulfillment UID** from the output!
### 3. Wait for Oracle
### 3. Check Status
The oracle will automatically arbitrate the fulfillment (a few seconds).
Monitor the escrow and arbitration progress:
```bash
nla escrow:status \
--escrow-uid 0x... \
--deployment ./cli/deployments/localhost.json
```
This will show:
- Escrow details (demand, oracle, recipient)
- All fulfillments
- Arbitration decisions (approved/rejected)
### 4. Collect the Escrow
If approved, collect the escrowed tokens:
```bash
bun run escrow:collect \
nla escrow:collect \
--escrow-uid 0x... \
--fulfillment-uid 0x... \
--private-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
--fulfillment-uid 0x...
```
## Commands
@ -55,15 +119,15 @@ bun run escrow:collect \
### Create Escrow
```bash
bun run escrow:create [options]
nla escrow:create [options]
Options:
--demand <text> Natural language demand (required)
--amount <number> Amount of tokens to escrow (required)
--token <address> ERC20 token address (required)
--oracle <address> Oracle address (required)
--private-key <key> Your private key (required)
--deployment <path> Deployment file (default: ./deployments/localhost.json)
--private-key <key> Your private key (or set PRIVATE_KEY env var)
--deployment <path> Deployment file (default: ./cli/deployments/localhost.json)
--rpc-url <url> RPC URL (default: from deployment)
--help, -h Show help
```
@ -71,14 +135,14 @@ Options:
### Fulfill Escrow
```bash
bun run escrow:fulfill [options]
nla escrow:fulfill [options]
Options:
--escrow-uid <uid> Escrow UID to fulfill (required)
--fulfillment <text> Your fulfillment text (required)
--oracle <address> Oracle address (required)
--private-key <key> Your private key (required)
--deployment <path> Deployment file (default: ./deployments/localhost.json)
--private-key <key> Your private key (or set PRIVATE_KEY env var)
--deployment <path> Deployment file (default: ./cli/deployments/localhost.json)
--rpc-url <url> RPC URL (default: from deployment)
--help, -h Show help
```
@ -86,13 +150,25 @@ Options:
### Collect Escrow
```bash
bun run escrow:collect [options]
nla escrow:collect [options]
Options:
--escrow-uid <uid> Escrow UID (required)
--fulfillment-uid <uid> Approved fulfillment UID (required)
--private-key <key> Your private key (required)
--deployment <path> Deployment file (default: ./deployments/localhost.json)
--private-key <key> Your private key (or set PRIVATE_KEY env var)
--deployment <path> Deployment file (default: ./cli/deployments/localhost.json)
--rpc-url <url> RPC URL (default: from deployment)
--help, -h Show help
```
### Check Status
```bash
nla escrow:status [options]
Options:
--escrow-uid <uid> Escrow UID to check (required)
--deployment <path> Deployment file (default: ./cli/deployments/localhost.json)
--rpc-url <url> RPC URL (default: from deployment)
--help, -h Show help
```
@ -127,37 +203,44 @@ export OPENAI_API_KEY=sk-... # Required for oracle
## Example Workflow
```bash
# Terminal 1: Start the system
bun run setup
# Terminal 1: Start the development environment
nla dev
# Note the token addresses from the deployment output!
# Example: Token A (TSTA): 0x5FbDB...
# Example: Token A (TSTA): 0xa513e6e4b8f2a923d98304ec87f64353c4d5c853
# Terminal 2: Create an escrow (as Alice)
# Terminal 2: Set your private key and create an escrow (as Alice)
export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
bun run escrow:create \
nla escrow:create \
--demand "Deliver package by Friday" \
--amount 100 \
--token 0x5FbDB... \ # Use Token A address from deployment
--token 0xa513e6e4b8f2a923d98304ec87f64353c4d5c853 \
--oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
# Save the escrow UID, e.g.: 0x1234...
# Save the escrow UID, e.g.: 0xd9e1402e96c2f7a64e60bf53a45445f7254e9b72389f6ede25181bff542d7b65
# Terminal 2: Fulfill the escrow (as Bob)
export PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
bun run escrow:fulfill \
--escrow-uid 0x1234... \
nla escrow:fulfill \
--escrow-uid 0xd9e1402e96c2f7a64e60bf53a45445f7254e9b72389f6ede25181bff542d7b65 \
--fulfillment "Package delivered on Thursday" \
--oracle 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
# Save the fulfillment UID, e.g.: 0x5678...
# Save the fulfillment UID, e.g.: 0xd124b274d5fb87e3d63b38fd2f6158730b73b53166898aa692b15f5a44178809
# Watch Terminal 1 - oracle will arbitrate automatically!
# Terminal 2: Check the status
nla escrow:status \
--escrow-uid 0xd9e1402e96c2f7a64e60bf53a45445f7254e9b72389f6ede25181bff542d7b65 \
--deployment ./cli/deployments/localhost.json
# Terminal 2: Collect the escrow (as Bob)
bun run escrow:collect \
--escrow-uid 0x1234... \
--fulfillment-uid 0x5678...
nla escrow:collect \
--escrow-uid 0xd9e1402e96c2f7a64e60bf53a45445f7254e9b72389f6ede25181bff542d7b65 \
--fulfillment-uid 0xd124b274d5fb87e3d63b38fd2f6158730b73b53166898aa692b15f5a44178809
```
## Troubleshooting

View File

@ -26,7 +26,7 @@ Options:
--escrow-uid <uid> Escrow UID to collect (required)
--fulfillment-uid <uid> Fulfillment UID that was approved (required)
--private-key <key> Your private key (required)
--deployment <path> Path to deployment file (default: ./deployments/localhost.json)
--deployment <path> Path to deployment file (default: ./cli/deployments/localhost.json)
--rpc-url <url> RPC URL (default: from deployment file)
--help, -h Display this help message
@ -79,7 +79,7 @@ async function main() {
const escrowUid = args["escrow-uid"];
const fulfillmentUid = args["fulfillment-uid"];
const privateKey = args["private-key"] || process.env.PRIVATE_KEY;
const deploymentPath = args.deployment || "./deployments/localhost.json";
const deploymentPath = args.deployment || "./cli/deployments/localhost.json";
// Validate required parameters
if (!escrowUid) {
@ -117,7 +117,7 @@ async function main() {
console.log(` 🌐 RPC URL: ${rpcUrl}\n`);
// Import alkahest client
const { makeClient } = await import("../../alkahest/sdks/ts/src/index.ts");
const { makeClient } = await import("../../../alkahest/sdks/ts/src/index.ts");
// Create account and wallet
const account = privateKeyToAccount(privateKey as `0x${string}`);

View File

@ -29,7 +29,7 @@ Options:
--token <address> ERC20 token address (required)
--oracle <address> Oracle address that will arbitrate (required)
--private-key <key> Your private key (required)
--deployment <path> Path to deployment file (default: ./deployments/localhost.json)
--deployment <path> Path to deployment file (default: ./cli/deployments/localhost.json)
--rpc-url <url> RPC URL (default: from deployment file)
--help, -h Display this help message
@ -88,7 +88,7 @@ async function main() {
const tokenAddress = args.token;
const oracleAddress = args.oracle;
const privateKey = args["private-key"] || process.env.PRIVATE_KEY;
const deploymentPath = args.deployment || "./deployments/localhost.json";
const deploymentPath = args.deployment || "./cli/deployments/localhost.json";
// Validate required parameters
if (!demand) {
@ -140,8 +140,8 @@ async function main() {
console.log(` 🌐 RPC URL: ${rpcUrl}\n`);
// Import alkahest client
const { makeClient } = await import("../../alkahest/sdks/ts/src/index.ts");
const { makeLLMClient } = await import("../clients/nla.ts");
const { makeClient } = await import("../../../alkahest/sdks/ts/src/index.ts");
const { makeLLMClient } = await import("../../clients/nla.ts");
// Create account and wallet
const account = privateKeyToAccount(privateKey as `0x${string}`);
@ -180,7 +180,7 @@ async function main() {
});
// Check token balance
const MockERC20Permit = await import("../../alkahest/sdks/ts/tests/fixtures/MockERC20Permit.json");
const MockERC20Permit = await import("../../../alkahest/sdks/ts/tests/fixtures/MockERC20Permit.json");
const tokenBalance = await walletClient.readContract({
address: tokenAddress as `0x${string}`,
abi: MockERC20Permit.abi,

View File

@ -28,7 +28,7 @@ Options:
--fulfillment <text> Your fulfillment text (required)
--oracle <address> Oracle address that will arbitrate (required)
--private-key <key> Your private key (required)
--deployment <path> Path to deployment file (default: ./deployments/localhost.json)
--deployment <path> Path to deployment file (default: ./cli/deployments/localhost.json)
--rpc-url <url> RPC URL (default: from deployment file)
--help, -h Display this help message
@ -84,7 +84,7 @@ async function main() {
const fulfillment = args.fulfillment;
const oracleAddress = args.oracle;
const privateKey = args["private-key"] || process.env.PRIVATE_KEY;
const deploymentPath = args.deployment || "./deployments/localhost.json";
const deploymentPath = args.deployment || "./cli/deployments/localhost.json";
// Validate required parameters
if (!escrowUid) {
@ -129,7 +129,7 @@ async function main() {
console.log(` 🌐 RPC URL: ${rpcUrl}\n`);
// Import alkahest client
const { makeClient } = await import("../../alkahest/sdks/ts/src/index.ts");
const { makeClient } = await import("../../../alkahest/sdks/ts/src/index.ts");
// Create account and wallet
const account = privateKeyToAccount(privateKey as `0x${string}`);

View File

@ -2,7 +2,7 @@
"network": "localhost",
"chainId": 31337,
"rpcUrl": "http://localhost:8545",
"deployedAt": "2025-12-12T05:50:31.992Z",
"deployedAt": "2025-12-12T09:19:50.255Z",
"deployer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
"addresses": {
"easSchemaRegistry": "0x5fbdb2315678afecb367f032d93f642f64180aa3",

315
cli/index.ts Executable file
View File

@ -0,0 +1,315 @@
#!/usr/bin/env bun
import { parseArgs } from "util";
// Helper function to display usage
function displayHelp() {
console.log(`
Natural Language Agreement CLI
Usage:
nla <command> [options]
Commands:
dev Start local development environment (Anvil + Deploy + Oracle)
escrow:create Create a new escrow with natural language demand
escrow:fulfill Fulfill an existing escrow
escrow:collect Collect an approved escrow
escrow:status Check the status of an escrow
help Display this help message
Options (vary by command):
--demand <text> Natural language demand (create)
--amount <number> Amount of tokens to escrow (create)
--token <address> ERC20 token contract address (create)
--oracle <address> Oracle address (create, fulfill)
--escrow-uid <uid> Escrow UID (fulfill, collect, status)
--fulfillment <text> Fulfillment text (fulfill)
--fulfillment-uid <uid> Fulfillment UID (collect)
--private-key <key> Private key (all commands)
--rpc-url <url> RPC URL (default: http://localhost:8545)
--deployment <file> Load addresses from deployment file
Environment Variables:
PRIVATE_KEY Private key for transactions
RPC_URL RPC URL for blockchain network
OPENAI_API_KEY OpenAI API key (for create command)
Examples:
# Start development environment
nla dev
# 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
# Collect an escrow
nla escrow:collect \\
--escrow-uid 0x... \\
--fulfillment-uid 0x...
# Check escrow status
nla escrow:status --escrow-uid 0x...
`);
}
// Parse command line arguments
function parseCliArgs() {
const args = Bun.argv.slice(2);
if (args.length === 0) {
displayHelp();
process.exit(0);
}
const command = args[0];
if (command === "help" || command === "--help" || command === "-h") {
displayHelp();
process.exit(0);
}
const { values } = parseArgs({
args: args.slice(1),
options: {
"demand": { type: "string" },
"amount": { type: "string" },
"token": { type: "string" },
"oracle": { type: "string" },
"escrow-uid": { type: "string" },
"fulfillment": { type: "string" },
"fulfillment-uid": { type: "string" },
"private-key": { type: "string" },
"rpc-url": { type: "string" },
"deployment": { type: "string" },
},
strict: true,
});
return { command, ...values };
}
// Main function
async function main() {
try {
const args = parseCliArgs();
const command = args.command;
// Handle dev command separately (runs shell script)
if (command === "dev") {
await runDevCommand();
return;
}
// Get the script path based on command
let scriptPath: string;
switch (command) {
case "escrow:create":
scriptPath = "./client/create-escrow.ts";
break;
case "escrow:fulfill":
scriptPath = "./client/fulfill-escrow.ts";
break;
case "escrow:collect":
scriptPath = "./client/collect-escrow.ts";
break;
case "escrow:status":
await runStatusCommand(args);
return;
default:
console.error(`❌ Unknown command: ${command}`);
console.error("Run 'nla help' for usage information.");
process.exit(1);
}
// Run the command as a subprocess with the args (excluding the command name)
const { spawnSync } = await import("child_process");
const scriptDir = import.meta.dir;
const fullScriptPath = `${scriptDir}/${scriptPath}`;
// Build args array without the command name
const commandArgs = Bun.argv.slice(3); // Skip bun, script, and command
const result = spawnSync("bun", ["run", fullScriptPath, ...commandArgs], {
stdio: "inherit",
cwd: process.cwd(),
});
process.exit(result.status || 0);
} catch (error) {
console.error("❌ Error:", error);
process.exit(1);
}
}
// 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"];
const rpcUrl = args["rpc-url"] || process.env.RPC_URL || "http://localhost:8545";
const deploymentFile = args["deployment"];
if (!escrowUid) {
console.error("❌ Error: --escrow-uid is required for status command");
process.exit(1);
}
console.log("🔍 Checking Escrow Status\n");
console.log(`Configuration:`);
console.log(` 📦 Escrow UID: ${escrowUid}`);
console.log(` 🌐 RPC URL: ${rpcUrl}\n`);
// Import required modules
const { createPublicClient, http, parseAbiParameters } = await import("viem");
const { foundry } = await import("viem/chains");
const { existsSync, readFileSync } = await import("fs");
// Load deployment addresses
let addresses: any = {};
if (deploymentFile && existsSync(deploymentFile)) {
const deployment = JSON.parse(readFileSync(deploymentFile, "utf-8"));
addresses = deployment.addresses;
}
// Create public client
const publicClient = createPublicClient({
chain: foundry,
transport: http(rpcUrl),
});
// Load EAS ABI
const { default: EAS } = await import("../../alkahest/contracts/out/EAS.sol/EAS.json");
if (!addresses.eas) {
console.error("❌ Error: EAS address not found. Use --deployment to specify deployment file.");
process.exit(1);
}
// Get escrow attestation
console.log("📋 Fetching escrow details...\n");
const escrow = await publicClient.readContract({
address: addresses.eas,
abi: EAS.abi,
functionName: "getAttestation",
args: [escrowUid],
}) as any;
console.log("📦 Escrow Information:");
console.log(` UID: ${escrow.uid}`);
console.log(` Schema: ${escrow.schema}`);
console.log(` Attester: ${escrow.attester}`);
console.log(` Recipient: ${escrow.recipient}`);
console.log(` Revoked: ${escrow.revocationTime > 0n ? "Yes ❌" : "No ✅"}`);
// Try to decode the data
try {
const llmAbi = parseAbiParameters("(string demand, string arbitrationModel, address arbitrator)");
const decoded = await import("viem").then(m =>
m.decodeAbiParameters(llmAbi, escrow.data)
);
console.log(`\n📝 Escrow Details:`);
console.log(` Demand: "${decoded[0].demand}"`);
console.log(` Model: ${decoded[0].arbitrationModel}`);
console.log(` Arbitrator: ${decoded[0].arbitrator}`);
} catch (e) {
console.log(`\n📝 Raw Data: ${escrow.data}`);
}
// Check for fulfillments
console.log(`\n🔎 Checking for fulfillments...`);
const filter = await publicClient.createContractEventFilter({
address: addresses.eas,
abi: EAS.abi,
eventName: "Attested",
fromBlock: 0n,
});
const events = await publicClient.getFilterLogs({ filter });
// Find fulfillments that reference this escrow
const fulfillments = events.filter((event: any) => {
return (event as any).args?.refUID === escrowUid;
});
if (fulfillments.length === 0) {
console.log(` No fulfillments found yet`);
} else {
console.log(` Found ${fulfillments.length} fulfillment(s):\n`);
for (const fulfillment of fulfillments) {
const fulfillmentUid = (fulfillment as any).args?.uid;
const fulfillmentAttestation = await publicClient.readContract({
address: addresses.eas,
abi: EAS.abi,
functionName: "getAttestation",
args: [fulfillmentUid],
}) as any;
console.log(` 📨 Fulfillment UID: ${fulfillmentUid}`);
console.log(` Attester: ${fulfillmentAttestation.attester}`);
console.log(` Revoked: ${fulfillmentAttestation.revocationTime > 0n ? "Yes ❌" : "No ✅"}`);
// Check for arbitration decision
const decisions = events.filter((e: any) => (e as any).args?.refUID === fulfillmentUid);
if (decisions.length > 0) {
console.log(` ⚖️ Arbitration: Decision recorded`);
for (const decision of decisions) {
const decisionUid = (decision as any).args?.uid;
const decisionAttestation = await publicClient.readContract({
address: addresses.eas,
abi: EAS.abi,
functionName: "getAttestation",
args: [decisionUid],
}) as any;
try {
const decisionAbi = parseAbiParameters("(bool item)");
const decisionData = await import("viem").then(m =>
m.decodeAbiParameters(decisionAbi, decisionAttestation.data)
);
console.log(` Result: ${decisionData[0].item ? "✅ APPROVED" : "❌ REJECTED"}`);
} catch (e) {
console.log(` Result: Unknown`);
}
}
} else {
console.log(` ⚖️ Arbitration: Pending...`);
}
console.log();
}
}
console.log("✨ Status check complete!\n");
}
// Run the CLI
main();

View File

@ -42,22 +42,22 @@ echo -e "${GREEN}✅ Contract artifacts found${NC}\n"
# Run deployment
echo -e "${BLUE}📝 Deploying to ${NETWORK}...${NC}"
bun run setups/deploy.ts --network "$NETWORK" --rpc-url "$RPC_URL"
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: deployments/${NETWORK}.json${NC}\n"
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 " ./scripts/start-oracle.sh $NETWORK"
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 setups/oracle.ts --deployment ./deployments/${NETWORK}.json"
echo " bun run cli/server/oracle.ts --deployment ./cli/deployments/${NETWORK}.json"
else
echo -e "\n${RED}❌ Deployment failed${NC}"
exit 1

View File

@ -103,12 +103,12 @@ fi
# Deploy contracts
echo -e "\n${BLUE}📝 Deploying contracts...${NC}\n"
export DEPLOYER_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
./scripts/deploy.sh localhost http://localhost:8545
./cli/scripts/deploy.sh localhost http://localhost:8545
# Start oracle
echo -e "\n${BLUE}🚀 Starting oracle...${NC}\n"
export ORACLE_PRIVATE_KEY="0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
./scripts/start-oracle.sh localhost
./cli/scripts/start-oracle.sh localhost
# Cleanup function
cleanup() {

View File

@ -19,7 +19,7 @@ fi
# Default network
NETWORK=${1:-localhost}
DEPLOYMENT_FILE="./deployments/${NETWORK}.json"
DEPLOYMENT_FILE="./cli/deployments/${NETWORK}.json"
echo -e "${BLUE}🚀 Starting Natural Language Agreement Oracle${NC}\n"
@ -27,7 +27,7 @@ echo -e "${BLUE}🚀 Starting Natural Language Agreement Oracle${NC}\n"
if [ ! -f "$DEPLOYMENT_FILE" ]; then
echo -e "${RED}❌ Error: Deployment file not found: $DEPLOYMENT_FILE${NC}"
echo "Please deploy contracts first:"
echo " ./scripts/deploy.sh $NETWORK"
echo " ./cli/scripts/deploy.sh $NETWORK"
exit 1
fi
@ -54,7 +54,7 @@ echo ""
# Start oracle
echo -e "${BLUE}👂 Starting oracle (Press Ctrl+C to stop)...${NC}\n"
bun run setups/oracle.ts \
bun run cli/server/oracle.ts \
--deployment "$DEPLOYMENT_FILE" \
--openai-api-key "$OPENAI_API_KEY" \
--private-key "$ORACLE_PRIVATE_KEY"

View File

@ -25,7 +25,7 @@ Options:
--network <name> Network to deploy to: mainnet, sepolia, localhost (required)
--rpc-url <url> Custom RPC URL (overrides network default)
--private-key <key> Deployer's private key (required)
--output <path> Output file for deployment addresses (default: ./deployments/<network>.json)
--output <path> Output file for deployment addresses (default: ./cli/deployments/<network>.json)
--help, -h Display this help message
Environment Variables (alternative to CLI options):
@ -152,7 +152,7 @@ async function main() {
console.log("📦 Loading contract artifacts...\n");
// This requires alkahest to be properly set up
const alkahestPath = "../../alkahest/sdks/ts";
const alkahestPath = "../../../alkahest/sdks/ts";
const contractsPath = `${alkahestPath}/src/contracts`;
// Import necessary artifacts
@ -329,7 +329,10 @@ async function main() {
}
// Save deployment addresses
const outputPath = args.output || resolve(`./deployments/${network}.json`);
// Get the script directory and go up to project root, then into cli/deployments
const scriptDir = import.meta.dir;
const projectRoot = resolve(scriptDir, "../..");
const outputPath = args.output || resolve(projectRoot, `cli/deployments/${network}.json`);
const outputDir = resolve(outputPath, "..");
if (!existsSync(outputDir)) {

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bun
import { parseArgs } from "util";
import { parseAbiParameters } from "viem";
import { makeLLMClient } from "../clients/nla";
import { makeLLMClient } from "../../clients/nla";
import { existsSync, readFileSync } from "fs";
import { resolve } from "path";
@ -127,7 +127,7 @@ async function main() {
}
// Import alkahest client
const { makeClient } = await import("../../alkahest/sdks/ts/src/index.ts");
const { makeClient } = await import("../../../alkahest/sdks/ts/src/index.ts");
const { createWalletClient, http, publicActions } = await import("viem");
const { privateKeyToAccount } = await import("viem/accounts");
const { foundry } = await import("viem/chains");

View File

@ -5,18 +5,21 @@
"private": true,
"devDependencies": {
"@types/bun": "latest"
},
"bin": {
"nla": "cli/index.ts"
},
"scripts": {
"dev": "bun run index.ts",
"start": "bun run index.ts",
"test": "bun test ./tests --exclude alkahest-ts/** ",
"setup": "./scripts/dev.sh",
"deploy": "./scripts/deploy.sh",
"oracle": "./scripts/start-oracle.sh",
"stop": "./scripts/stop.sh",
"escrow:create": "bun run cli/create-escrow.ts",
"escrow:fulfill": "bun run cli/fulfill-escrow.ts",
"escrow:collect": "bun run cli/collect-escrow.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"
},
"peerDependencies": {
"typescript": "^5.9.3"