From 1d13164a030bd7054118d2c6aef24d979bf1ab06 Mon Sep 17 00:00:00 2001 From: Celeste Ang Date: Wed, 19 Aug 2026 01:54:57 -0700 Subject: [PATCH] fix(chain): include Solana in `chain list` `chain list` sourced its output solely from EVM_MAINNET_CHAINS / EVM_TESTNET_CHAINS, which are EVM-only by construction. Solana was therefore never listed, even though ACP jobs on it work end to end: a job created with `--chain-id 501` progresses through created -> budget_set -> funded -> submitted -> completed against the Solana ACP program in ACP_CONTRACT_ADDRESSES. The discovery surface disagreed with the supported surface, so anyone using `chain list` to decide where they can transact concluded Solana was unavailable. List the Solana chain alongside the EVM ones, keyed off SOLANA_MAINNET_CHAIN_ID (501) and SOLANA_DEVNET_CHAIN_ID (500) so the mainnet/testnet split stays consistent with IS_TESTNET. Also add a `family` field ("evm" | "solana") to the JSON output and the TTY view, since chain ids alone no longer imply an address format. The non-TTY tab-separated output keeps its two-column CHAIN_ID/NAME contract so existing scripts that parse it are unaffected. --- src/commands/chain.ts | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/commands/chain.ts b/src/commands/chain.ts index 6e66c17..9b300be 100644 --- a/src/commands/chain.ts +++ b/src/commands/chain.ts @@ -2,6 +2,8 @@ import type { Command } from "commander"; import { EVM_MAINNET_CHAINS, EVM_TESTNET_CHAINS, + SOLANA_DEVNET_CHAIN_ID, + SOLANA_MAINNET_CHAIN_ID, } from "@virtuals-protocol/acp-node-v2"; import { isJson, outputResult, outputError, isTTY } from "../lib/output"; import { c } from "../lib/color"; @@ -19,7 +21,24 @@ export function registerChainCommands(program: Command): void { const chains = isTestnet ? EVM_TESTNET_CHAINS : EVM_MAINNET_CHAINS; const env = isTestnet ? "testnet" : "mainnet"; - const items = chains.map((ch) => ({ id: ch.id, name: ch.name })); + // Solana has no entry in EVM_*_CHAINS, so it has to be listed + // explicitly — jobs on it work, they just weren't discoverable here. + const solanaChains = isTestnet + ? [{ id: SOLANA_DEVNET_CHAIN_ID, name: "Solana Devnet" }] + : [{ id: SOLANA_MAINNET_CHAIN_ID, name: "Solana" }]; + + const items = [ + ...chains.map((ch) => ({ + id: ch.id, + name: ch.name, + family: "evm" as const, + })), + ...solanaChains.map((ch) => ({ + id: ch.id, + name: ch.name, + family: "solana" as const, + })), + ]; if (json) { outputResult(json, { environment: env, chains: items }); @@ -29,10 +48,13 @@ export function registerChainCommands(program: Command): void { if (isTTY()) { console.log(`\n${c.bold(`Supported Chains (${env})`)}\n`); for (const ch of items) { - console.log(` ${c.cyan(String(ch.id).padEnd(10))}${ch.name}`); + console.log( + ` ${c.cyan(String(ch.id).padEnd(10))}${ch.name.padEnd(26)}${c.dim(ch.family)}`, + ); } console.log(""); } else { + // Keep the two-column contract stable for anything parsing this. console.log("CHAIN_ID\tNAME"); for (const ch of items) { console.log(`${ch.id}\t${ch.name}`);