naracli 1.0.63 → 1.0.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -13
- package/bin/nara-cli.ts +3 -2
- package/dist/nara-cli-bundle.cjs +42276 -6043
- package/package.json +2 -2
- package/src/cli/commands/agent.ts +231 -139
- package/src/cli/commands/quest.ts +1 -1
- package/src/cli/utils/agent-config.ts +91 -25
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
import { homedir } from "node:os";
|
|
15
15
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
16
|
-
import {
|
|
16
|
+
import { Connection } from "@solana/web3.js";
|
|
17
|
+
import { DEFAULT_RPC_URL, getAgentInfo } from "nara-sdk";
|
|
17
18
|
|
|
18
19
|
const CONFIG_DIR = join(homedir(), ".config", "nara");
|
|
19
20
|
const GLOBAL_CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
@@ -76,47 +77,112 @@ export interface NetworkConfig {
|
|
|
76
77
|
|
|
77
78
|
const DEFAULT_NETWORK_CONFIG: NetworkConfig = { agent_id: "", zk_ids: [] };
|
|
78
79
|
|
|
79
|
-
/**
|
|
80
|
-
|
|
81
|
-
* @param rpcUrl - effective RPC URL (determines which file to load)
|
|
82
|
-
*/
|
|
83
|
-
export function loadNetworkConfig(rpcUrl?: string): NetworkConfig {
|
|
80
|
+
/** Read raw JSON from network config file. */
|
|
81
|
+
function loadRawNetworkConfig(rpcUrl?: string): Record<string, any> {
|
|
84
82
|
const url = rpcUrl || getConfiguredRpcUrl();
|
|
85
83
|
const path = networkConfigPath(url);
|
|
86
84
|
try {
|
|
87
|
-
|
|
88
|
-
const parsed = JSON.parse(raw);
|
|
89
|
-
return {
|
|
90
|
-
agent_id: typeof parsed.agent_id === "string" ? parsed.agent_id : "",
|
|
91
|
-
zk_ids: Array.isArray(parsed.zk_ids) ? parsed.zk_ids : [],
|
|
92
|
-
};
|
|
85
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
93
86
|
} catch {
|
|
94
|
-
return {
|
|
87
|
+
return {};
|
|
95
88
|
}
|
|
96
89
|
}
|
|
97
90
|
|
|
91
|
+
/** Write raw JSON to network config file. */
|
|
92
|
+
function saveRawNetworkConfig(data: Record<string, any>, rpcUrl?: string): void {
|
|
93
|
+
const url = rpcUrl || getConfiguredRpcUrl();
|
|
94
|
+
const path = networkConfigPath(url);
|
|
95
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
96
|
+
writeFileSync(path, JSON.stringify(data, null, 2) + "\n");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Load network-specific config.
|
|
101
|
+
* @param rpcUrl - effective RPC URL (determines which file to load)
|
|
102
|
+
* @param walletPubkey - wallet public key to look up agent_id (optional)
|
|
103
|
+
*/
|
|
104
|
+
export function loadNetworkConfig(rpcUrl?: string, walletPubkey?: string): NetworkConfig {
|
|
105
|
+
const raw = loadRawNetworkConfig(rpcUrl);
|
|
106
|
+
|
|
107
|
+
// Resolve agent_id: new format uses wallet pubkey as key
|
|
108
|
+
let agent_id = "";
|
|
109
|
+
if (walletPubkey && typeof raw[walletPubkey] === "string") {
|
|
110
|
+
agent_id = raw[walletPubkey];
|
|
111
|
+
} else if (typeof raw.agent_id === "string" && raw.agent_id) {
|
|
112
|
+
// Legacy format: { "agent_id": "xxx" } — return value but don't migrate here
|
|
113
|
+
// Call migrateAgentIdFormat() to migrate with on-chain authority check
|
|
114
|
+
agent_id = raw.agent_id;
|
|
115
|
+
} else if (!walletPubkey) {
|
|
116
|
+
// No wallet provided — find first agent_id from any key (best-effort)
|
|
117
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
118
|
+
if (k !== "zk_ids" && typeof v === "string" && v) {
|
|
119
|
+
agent_id = v;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
agent_id,
|
|
127
|
+
zk_ids: Array.isArray(raw.zk_ids) ? raw.zk_ids : [],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
98
131
|
/**
|
|
99
132
|
* Save network-specific config.
|
|
100
133
|
*/
|
|
101
134
|
export function saveNetworkConfig(config: NetworkConfig, rpcUrl?: string): void {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
135
|
+
const raw = loadRawNetworkConfig(rpcUrl);
|
|
136
|
+
// Preserve existing wallet->agentId mappings, update zk_ids
|
|
137
|
+
raw.zk_ids = config.zk_ids;
|
|
138
|
+
saveRawNetworkConfig(raw, rpcUrl);
|
|
106
139
|
}
|
|
107
140
|
|
|
108
141
|
// ─── Convenience helpers ─────────────────────────────────────────
|
|
109
142
|
|
|
110
|
-
export function setAgentId(id: string, rpcUrl?: string): void {
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
143
|
+
export function setAgentId(id: string, rpcUrl?: string, walletPubkey?: string): void {
|
|
144
|
+
const raw = loadRawNetworkConfig(rpcUrl);
|
|
145
|
+
if (walletPubkey) {
|
|
146
|
+
raw[walletPubkey] = id;
|
|
147
|
+
// Clean up legacy field if present
|
|
148
|
+
delete raw.agent_id;
|
|
149
|
+
} else {
|
|
150
|
+
raw.agent_id = id;
|
|
151
|
+
}
|
|
152
|
+
saveRawNetworkConfig(raw, rpcUrl);
|
|
114
153
|
}
|
|
115
154
|
|
|
116
|
-
export function clearAgentId(rpcUrl?: string): void {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
155
|
+
export function clearAgentId(rpcUrl?: string, walletPubkey?: string): void {
|
|
156
|
+
const raw = loadRawNetworkConfig(rpcUrl);
|
|
157
|
+
if (walletPubkey) {
|
|
158
|
+
delete raw[walletPubkey];
|
|
159
|
+
}
|
|
160
|
+
// Also clean up legacy field
|
|
161
|
+
delete raw.agent_id;
|
|
162
|
+
saveRawNetworkConfig(raw, rpcUrl);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Migrate legacy { "agent_id": "xxx" } to { "<authority-pubkey>": "xxx" }.
|
|
167
|
+
* Queries on-chain agent info to determine the authority.
|
|
168
|
+
* No-op if no legacy agent_id field exists.
|
|
169
|
+
*/
|
|
170
|
+
export async function migrateAgentIdFormat(rpcUrl?: string): Promise<void> {
|
|
171
|
+
const url = rpcUrl || getConfiguredRpcUrl();
|
|
172
|
+
const raw = loadRawNetworkConfig(url);
|
|
173
|
+
if (typeof raw.agent_id !== "string" || !raw.agent_id) return;
|
|
174
|
+
|
|
175
|
+
const agentId = raw.agent_id;
|
|
176
|
+
try {
|
|
177
|
+
const connection = new Connection(url, "confirmed");
|
|
178
|
+
const info = await getAgentInfo(connection, agentId);
|
|
179
|
+
const authority = info.record.authority.toBase58();
|
|
180
|
+
raw[authority] = agentId;
|
|
181
|
+
delete raw.agent_id;
|
|
182
|
+
saveRawNetworkConfig(raw, url);
|
|
183
|
+
} catch {
|
|
184
|
+
// Agent not found on-chain or RPC error — keep legacy format for now
|
|
185
|
+
}
|
|
120
186
|
}
|
|
121
187
|
|
|
122
188
|
export function addZkId(name: string, rpcUrl?: string): void {
|