From 5334b5bf1b4e46b8c632e2baa1461d8313e50518 Mon Sep 17 00:00:00 2001 From: ngoc Date: Sun, 1 Feb 2026 13:22:22 +0700 Subject: [PATCH] feat: add base-sepolia --- bun.lock | 14 ++++++--- cli/commands/switch.ts | 14 +++++---- cli/deployments/base-sepolia.json | 50 +++++++++++++++++++++++++++++++ cli/index.ts | 2 +- cli/server/deploy.ts | 9 ++++-- cli/server/oracle.ts | 33 ++++++++++++++++++-- cli/utils.ts | 4 ++- package.json | 2 +- 8 files changed, 111 insertions(+), 17 deletions(-) create mode 100644 cli/deployments/base-sepolia.json diff --git a/bun.lock b/bun.lock index 852a509..684ca24 100644 --- a/bun.lock +++ b/bun.lock @@ -11,13 +11,15 @@ "@perplexity-ai/ai-sdk": "^0.1.2", "@viem/anvil": "^0.0.10", "ai": "^6.0.5", - "alkahest-ts": "github:arkhai-io/alkahest", + "alkahest-ts": "^0.6.1", "arktype": "^2.1.23", "viem": "^2.42.1", "zod": "^3.25.76", }, "devDependencies": { "@types/bun": "latest", + "@types/node": "^20.0.0", + "typescript": "^5.9.3", }, "peerDependencies": { "typescript": "^5.9.3", @@ -65,7 +67,7 @@ "@types/bun": ["@types/bun@1.3.4", "", { "dependencies": { "bun-types": "1.3.4" } }, "sha512-EEPTKXHP+zKGPkhRLv+HI0UEX8/o+65hqARxLy8Ov5rIxMBPNTjeZww00CIihrIQGEQBYg+0roO5qOnS/7boGA=="], - "@types/node": ["@types/node@25.0.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-gWEkeiyYE4vqjON/+Obqcoeffmk0NF15WSBwSs7zwVA2bAbTaE0SJ7P0WNGoJn8uE7fiaV5a7dKYIJriEqOrmA=="], + "@types/node": ["@types/node@20.19.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g=="], "@vercel/oidc": ["@vercel/oidc@3.0.5", "", {}, "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw=="], @@ -75,7 +77,7 @@ "ai": ["ai@6.0.5", "", { "dependencies": { "@ai-sdk/gateway": "3.0.4", "@ai-sdk/provider": "3.0.1", "@ai-sdk/provider-utils": "4.0.2", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-CKL3dDHedWskC6EY67LrULonZBU9vL+Bwa+xQEcprBhJfxpogntG3utjiAkYuy5ZQatyWk+SmWG8HLvcnhvbRg=="], - "alkahest-ts": ["alkahest-ts@github:arkhai-io/alkahest#80a8273", { "dependencies": { "@viem/anvil": "^0.0.10", "arktype": "^2.1.23", "zod": "^3.25.76" }, "peerDependencies": { "typescript": "^5.9.3", "viem": "^2.38.3" } }, "arkhai-io-alkahest-80a8273"], + "alkahest-ts": ["alkahest-ts@0.6.1", "", { "dependencies": { "@viem/anvil": "^0.0.10", "arktype": "^2.1.23", "zod": "^3.25.76" }, "peerDependencies": { "typescript": "^5.9.3", "viem": "^2.38.3" } }, "sha512-0u1xUM9OLca6emKDVzn6ISx4VFg7TGZtA/7hnT3SOHOWVPLk5ruX12tbX5MO7hG1jxVHAO3wgIE2t7vl864/nQ=="], "arkregex": ["arkregex@0.0.5", "", { "dependencies": { "@ark/util": "0.56.0" } }, "sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw=="], @@ -133,7 +135,7 @@ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], - "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], "viem": ["viem@2.42.1", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.1.0", "isows": "1.0.7", "ox": "0.9.6", "ws": "8.18.3" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-NzT/f54jT+b0Um6pYzN/uAGMLg+3twhricAzXS+XH8pVIREzPEh7P25rlhPQnLYiPWzQd9mrFcvnm73Sc8bx+A=="], @@ -143,8 +145,12 @@ "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "bun-types/@types/node": ["@types/node@25.0.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-gWEkeiyYE4vqjON/+Obqcoeffmk0NF15WSBwSs7zwVA2bAbTaE0SJ7P0WNGoJn8uE7fiaV5a7dKYIJriEqOrmA=="], + "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], "ox/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], + + "bun-types/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], } } diff --git a/cli/commands/switch.ts b/cli/commands/switch.ts index 6ae360d..0a61cd5 100644 --- a/cli/commands/switch.ts +++ b/cli/commands/switch.ts @@ -86,19 +86,20 @@ export function runSwitchCommand(env?: string) { const current = getCurrentEnvironment(); console.log(`${colors.blue}Current environment:${colors.reset} ${colors.green}${current}${colors.reset}\n`); console.log('Available environments:'); - console.log(' • devnet (local Anvil blockchain)'); - console.log(' • sepolia (Ethereum Sepolia testnet)'); - console.log(' • mainnet (Ethereum mainnet)\n'); + console.log(' • devnet (local Anvil blockchain)'); + console.log(' • sepolia (Ethereum Sepolia testnet)'); + console.log(' • base-sepolia (Base Sepolia testnet)'); + console.log(' • mainnet (Ethereum mainnet)\n'); console.log(`${colors.yellow}Usage:${colors.reset} nla switch `); console.log(`${colors.yellow}Example:${colors.reset} nla switch sepolia\n`); return; } // Validate environment - const validEnvs = ['devnet', 'sepolia', 'mainnet']; + const validEnvs = ['devnet', 'sepolia', 'base-sepolia', 'mainnet']; if (!validEnvs.includes(env)) { console.error(`${colors.red}❌ Invalid environment: ${env}${colors.reset}`); - console.log('Valid environments: devnet, sepolia, mainnet\n'); + console.log('Valid environments: devnet, sepolia, base-sepolia, mainnet\n'); process.exit(1); } @@ -120,6 +121,9 @@ export function runSwitchCommand(env?: string) { } else if (env === 'sepolia') { console.log('📝 Using Ethereum Sepolia testnet'); console.log(' Make sure you have deployed contracts and updated sepolia.json\n'); + } else if (env === 'base-sepolia') { + console.log('📝 Using Base Sepolia testnet'); + console.log(' Make sure you have deployed contracts and updated base-sepolia.json\n'); } else if (env === 'mainnet') { console.log('📝 Using Ethereum mainnet'); console.log(` ${colors.yellow}⚠️ WARNING: This is production! Use with caution.${colors.reset}\n`); diff --git a/cli/deployments/base-sepolia.json b/cli/deployments/base-sepolia.json new file mode 100644 index 0000000..b7346d1 --- /dev/null +++ b/cli/deployments/base-sepolia.json @@ -0,0 +1,50 @@ +{ + "network": "Base Sepolia", + "chainId": 84532, + "rpcUrl": "https://base-sepolia.infura.io/v3/e8b0c66293ae484083cf9e1d793d68bd", + "addresses": { + "eas": "", + "easSchemaRegistry": "", + "erc20EscrowObligation": "", + "erc20PaymentObligation": "", + "erc20BarterUtils": "", + "erc721EscrowObligation": "", + "erc721PaymentObligation": "", + "erc721BarterUtils": "", + "erc1155EscrowObligation": "", + "erc1155BarterUtils": "", + "erc1155PaymentObligation": "", + "tokenBundleEscrowObligation": "", + "tokenBundlePaymentObligation": "", + "tokenBundleBarterUtils": "", + "attestationEscrowObligation": "", + "attestationEscrowObligation2": "", + "attestationBarterUtils": "", + "stringObligation": "", + "trivialArbiter": "", + "trustedOracleArbiter": "", + "anyArbiter": "", + "allArbiter": "", + "intrinsicsArbiter": "", + "intrinsicsArbiter2": "", + "exclusiveRevocableConfirmationArbiter": "", + "exclusiveUnrevocableConfirmationArbiter": "", + "nonexclusiveRevocableConfirmationArbiter": "", + "nonexclusiveUnrevocableConfirmationArbiter": "", + "nativeTokenEscrowObligation": "", + "nativeTokenPaymentObligation": "", + "nativeTokenBarterUtils": "", + "recipientArbiter": "", + "attesterArbiter": "", + "schemaArbiter": "", + "uidArbiter": "", + "refUidArbiter": "", + "revocableArbiter": "", + "timeAfterArbiter": "", + "timeBeforeArbiter": "", + "timeEqualArbiter": "", + "expirationTimeAfterArbiter": "", + "expirationTimeBeforeArbiter": "", + "expirationTimeEqualArbiter": "" + } +} diff --git a/cli/index.ts b/cli/index.ts index b675be4..de0b697 100755 --- a/cli/index.ts +++ b/cli/index.ts @@ -29,7 +29,7 @@ Commands: deploy Deploy contracts to blockchain start-oracle Start the oracle service stop Stop all services (Anvil + Oracle) - switch [env] Switch between environments (devnet, sepolia, mainnet) + switch [env] Switch between environments (devnet, sepolia, base-sepolia, mainnet) network Show current network/environment escrow:create Create a new escrow with natural language demand escrow:fulfill Fulfill an existing escrow diff --git a/cli/server/deploy.ts b/cli/server/deploy.ts index 66b3b3f..f1395f1 100644 --- a/cli/server/deploy.ts +++ b/cli/server/deploy.ts @@ -9,7 +9,7 @@ import { parseArgs } from "util"; import { createWalletClient, http, publicActions, parseEther } from "viem"; import { privateKeyToAccount } from "viem/accounts"; -import { mainnet, sepolia, foundry } from "viem/chains"; +import { mainnet, sepolia, baseSepolia, foundry } from "viem/chains"; import { writeFileSync, existsSync, mkdirSync } from "fs"; import { resolve } from "path"; import { fixtures, contracts } from "alkahest-ts"; @@ -23,7 +23,7 @@ Usage: bun deploy.ts [options] Options: - --network Network to deploy to: mainnet, sepolia, localhost (required) + --network Network to deploy to: mainnet, sepolia, base-sepolia, localhost (required) --rpc-url Custom RPC URL (overrides network default) --private-key Deployer's private key (required) --output Output file for deployment addresses (default: ./cli/deployments/.json) @@ -36,6 +36,7 @@ Environment Variables (alternative to CLI options): Networks: mainnet Ethereum Mainnet sepolia Ethereum Sepolia Testnet + base-sepolia Base Sepolia Testnet localhost Local development (Anvil/Hardhat) Examples: @@ -75,11 +76,13 @@ function getChain(network: string) { return mainnet; case "sepolia": return sepolia; + case "base-sepolia": + return baseSepolia; case "localhost": case "local": return foundry; default: - throw new Error(`Unknown network: ${network}. Use mainnet, sepolia, or localhost`); + throw new Error(`Unknown network: ${network}. Use mainnet, sepolia, base-sepolia, or localhost`); } } diff --git a/cli/server/oracle.ts b/cli/server/oracle.ts index 92d2cbb..0af6ca3 100644 --- a/cli/server/oracle.ts +++ b/cli/server/oracle.ts @@ -9,7 +9,7 @@ import { resolve } from "path"; import { makeClient } from "alkahest-ts"; import { fixtures } from "alkahest-ts"; import { ProviderName } from "../../nla"; - +import { contractAddresses } from "alkahest-ts"; // Helper function to display usage function displayHelp() { console.log(` @@ -174,8 +174,37 @@ async function main() { transport: http(rpcUrl), }).extend(publicActions) as any; + // Merge deployment addresses with default contract addresses + // Use contractAddresses as fallback for any missing addresses + let finalAddresses = deploymentAddresses || {}; + + if (!deploymentAddresses || Object.keys(deploymentAddresses).length === 0) { + // If no deployment addresses, try to use default contract addresses from the network + const chainId = foundry.id; // You may need to detect this from the RPC + if (contractAddresses[chainId]) { + finalAddresses = { ...contractAddresses[chainId] }; + console.log(`📋 Using default contract addresses for chain ${chainId}\n`); + } else if (easContract) { + finalAddresses = { eas: easContract }; + } + } else { + // Merge with contract addresses to fill in any missing values + const chainId = foundry.id; + if (contractAddresses[chainId]) { + // Start with default addresses + finalAddresses = { ...contractAddresses[chainId] }; + + // Override with deployment addresses, but only if they're not empty strings + for (const [key, value] of Object.entries(deploymentAddresses)) { + if (value && value !== "") { + finalAddresses[key] = value; + } + } + } + } + // Create alkahest client - const client = makeClient(walletClient, deploymentAddresses || { eas: easContract }); + const client = makeClient(walletClient, finalAddresses); console.log(`✅ Oracle initialized with address: ${account.address}\n`); diff --git a/cli/utils.ts b/cli/utils.ts index 0a96f36..bddc8e8 100644 --- a/cli/utils.ts +++ b/cli/utils.ts @@ -2,7 +2,7 @@ * Shared utilities for NLA CLI */ -import { foundry, sepolia, mainnet } from "viem/chains"; +import { foundry, sepolia, mainnet, baseSepolia } from "viem/chains"; import type { Chain } from "viem/chains"; /** @@ -15,6 +15,8 @@ export function getChainFromNetwork(network: string): Chain { return foundry; case "sepolia": return sepolia; + case "base-sepolia": + return baseSepolia; case "mainnet": return mainnet; default: diff --git a/package.json b/package.json index bc44fce..585849e 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@perplexity-ai/ai-sdk": "^0.1.2", "@viem/anvil": "^0.0.10", "ai": "^6.0.5", - "alkahest-ts": "github:arkhai-io/alkahest", + "alkahest-ts": "^0.6.1", "arktype": "^2.1.23", "viem": "^2.42.1", "zod": "^3.25.76"