@haven_ai/cli 0.2.0-alpha.0 → 0.3.0-alpha.0
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 +1 -1
- package/dist/cli.cjs +40 -44
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +40 -44
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +40 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +40 -44
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -600,9 +600,9 @@ async function runConnector(connectorCommand, spawner, onStderr) {
|
|
|
600
600
|
|
|
601
601
|
// src/commands.ts
|
|
602
602
|
var DEFAULT_API = "https://havenbackend-production-8a00.up.railway.app";
|
|
603
|
-
var CLI_VERSION = "0.
|
|
603
|
+
var CLI_VERSION = "0.3.0-alpha.0";
|
|
604
604
|
function accountAddressOf(s) {
|
|
605
|
-
return s.account_address ??
|
|
605
|
+
return s.account_address ?? "";
|
|
606
606
|
}
|
|
607
607
|
async function run(argv, deps = {}) {
|
|
608
608
|
const out = deps.out ?? ((l) => process.stdout.write(`${l}
|
|
@@ -872,24 +872,32 @@ async function cmdWhoami(args, d) {
|
|
|
872
872
|
);
|
|
873
873
|
return EXIT.ok;
|
|
874
874
|
}
|
|
875
|
+
function accountsEnvelope(body) {
|
|
876
|
+
if (!Array.isArray(body.accounts)) {
|
|
877
|
+
throw new Error(
|
|
878
|
+
"GET /user/accounts did not return an `accounts` array. This CLI needs a Haven backend from the release that carries #2914 or later; an older server returns the retired `safes` envelope. Upgrade the backend, or pin an older @haven_ai/cli."
|
|
879
|
+
);
|
|
880
|
+
}
|
|
881
|
+
return body.accounts;
|
|
882
|
+
}
|
|
875
883
|
async function cmdWalletsList(args, d) {
|
|
876
884
|
const { api } = await authed(args, d);
|
|
877
|
-
const
|
|
885
|
+
const accounts = accountsEnvelope(await api.get("/user/accounts"));
|
|
878
886
|
emit(
|
|
879
887
|
d,
|
|
880
888
|
args.flags.json,
|
|
881
|
-
|
|
882
|
-
() =>
|
|
889
|
+
accounts,
|
|
890
|
+
() => accounts.length === 0 ? "No Haven wallets yet." : table(
|
|
883
891
|
["NAME", "NETWORK", "ADDRESS", "DEFAULT"],
|
|
884
|
-
|
|
892
|
+
accounts.map((s) => [s.name, chainName(s.chain_id), truncateAddress(accountAddressOf(s)), s.is_default ? "\u2713" : ""])
|
|
885
893
|
)
|
|
886
894
|
);
|
|
887
895
|
return EXIT.ok;
|
|
888
896
|
}
|
|
889
897
|
async function cmdWalletsBalances(args, d) {
|
|
890
898
|
const { api } = await authed(args, d);
|
|
891
|
-
const
|
|
892
|
-
const safe = pickSafe(
|
|
899
|
+
const accounts = accountsEnvelope(await api.get("/user/accounts"));
|
|
900
|
+
const safe = pickSafe(accounts, args.flags.safe);
|
|
893
901
|
if (!safe) {
|
|
894
902
|
if (args.flags.safe) throw new UsageError(`No wallet matches "${args.flags.safe}".`);
|
|
895
903
|
throw new CliApiError("No Haven wallet found.", 404);
|
|
@@ -900,7 +908,7 @@ async function cmdWalletsBalances(args, d) {
|
|
|
900
908
|
emit(
|
|
901
909
|
d,
|
|
902
910
|
args.flags.json,
|
|
903
|
-
{ account: safe.name,
|
|
911
|
+
{ account: safe.name, chainId: safe.chain_id, balances },
|
|
904
912
|
() => [
|
|
905
913
|
`${safe.name} \xB7 ${chainName(safe.chain_id)} \xB7 ${truncateAddress(accountAddressOf(safe))}`,
|
|
906
914
|
balances.length === 0 ? " (no balances)" : table(["TOKEN", "BALANCE"], balances.map((b) => [b.symbol, b.formatted]))
|
|
@@ -908,15 +916,15 @@ async function cmdWalletsBalances(args, d) {
|
|
|
908
916
|
);
|
|
909
917
|
return EXIT.ok;
|
|
910
918
|
}
|
|
911
|
-
function pickSafe(
|
|
912
|
-
if (!ref) return
|
|
919
|
+
function pickSafe(accounts, ref) {
|
|
920
|
+
if (!ref) return accounts.find((s) => s.is_default) ?? accounts[0];
|
|
913
921
|
const lower = ref.toLowerCase();
|
|
914
|
-
return
|
|
922
|
+
return accounts.find((s) => s.id === ref || accountAddressOf(s).toLowerCase() === lower);
|
|
915
923
|
}
|
|
916
924
|
async function cmdWalletsFunding(args, d) {
|
|
917
925
|
const { api } = await authed(args, d);
|
|
918
|
-
const
|
|
919
|
-
const safe = pickSafe(
|
|
926
|
+
const accounts = accountsEnvelope(await api.get("/user/accounts"));
|
|
927
|
+
const safe = pickSafe(accounts, args.flags.safe);
|
|
920
928
|
if (!safe) {
|
|
921
929
|
if (args.flags.safe) throw new UsageError(`No wallet matches "${args.flags.safe}".`);
|
|
922
930
|
throw new CliApiError("No Haven wallet found.", 404);
|
|
@@ -1059,8 +1067,8 @@ async function cmdBudgetGrant(args, d) {
|
|
|
1059
1067
|
EXIT.refused
|
|
1060
1068
|
);
|
|
1061
1069
|
}
|
|
1062
|
-
const accountAddress = agent.account_address
|
|
1063
|
-
const accountChainId = agent.account_chain_id
|
|
1070
|
+
const accountAddress = agent.account_address;
|
|
1071
|
+
const accountChainId = agent.account_chain_id;
|
|
1064
1072
|
if (!accountAddress || !accountChainId) {
|
|
1065
1073
|
throw new HavenCliError(`Agent ${id} has no wallet assigned yet \u2014 connect it first.`, EXIT.refused);
|
|
1066
1074
|
}
|
|
@@ -1235,27 +1243,24 @@ async function cmdWalletRename(args, d) {
|
|
|
1235
1243
|
if (!id || !name) throw new UsageError("Usage: haven wallets rename <id> <name>");
|
|
1236
1244
|
const { api } = await authed(args, d);
|
|
1237
1245
|
await api.put(`/user/accounts/${id}`, { name });
|
|
1238
|
-
emit(d, args.flags.json, { ok: true, account_id: id,
|
|
1246
|
+
emit(d, args.flags.json, { ok: true, account_id: id, name }, () => `Wallet ${id} renamed to "${name}".`);
|
|
1239
1247
|
return EXIT.ok;
|
|
1240
1248
|
}
|
|
1241
|
-
async function
|
|
1249
|
+
async function resolveAccountId(args, api) {
|
|
1242
1250
|
if (!args.flags.safe) return void 0;
|
|
1243
|
-
const
|
|
1244
|
-
const safe = pickSafe(
|
|
1251
|
+
const accounts = accountsEnvelope(await api.get("/user/accounts"));
|
|
1252
|
+
const safe = pickSafe(accounts, args.flags.safe);
|
|
1245
1253
|
if (!safe) throw new UsageError(`No wallet matches "${args.flags.safe}".`);
|
|
1246
1254
|
return safe.id;
|
|
1247
1255
|
}
|
|
1248
1256
|
async function cmdActivityList(args, d) {
|
|
1249
1257
|
const { api } = await authed(args, d);
|
|
1250
|
-
const
|
|
1258
|
+
const accountId = await resolveAccountId(args, api);
|
|
1251
1259
|
const params = new URLSearchParams({
|
|
1252
1260
|
offset: String(args.flags.offset ?? 0),
|
|
1253
1261
|
limit: String(args.flags.limit ?? 25)
|
|
1254
1262
|
});
|
|
1255
|
-
if (
|
|
1256
|
-
params.set("accountId", safeId);
|
|
1257
|
-
params.set("safeId", safeId);
|
|
1258
|
-
}
|
|
1263
|
+
if (accountId) params.set("accountId", accountId);
|
|
1259
1264
|
if (args.flags.agent) params.set("agentId", args.flags.agent);
|
|
1260
1265
|
const { transactions } = await api.get(`/transactions?${params.toString()}`);
|
|
1261
1266
|
const visible = args.flags.direction ? transactions.filter((t) => t.direction === args.flags.direction) : transactions;
|
|
@@ -1270,7 +1275,7 @@ async function cmdActivityList(args, d) {
|
|
|
1270
1275
|
t.direction === "in" ? "in" : "out",
|
|
1271
1276
|
`${t.direction === "in" ? "+" : "-"}${t.valueFormatted} ${t.asset}`,
|
|
1272
1277
|
t.source ?? "transfer",
|
|
1273
|
-
t.
|
|
1278
|
+
t.accountName ?? ""
|
|
1274
1279
|
])
|
|
1275
1280
|
)
|
|
1276
1281
|
);
|
|
@@ -1279,15 +1284,12 @@ async function cmdActivityList(args, d) {
|
|
|
1279
1284
|
async function cmdActivityExport(args, d) {
|
|
1280
1285
|
if (args.flags.format === "sie") return exportSie(args, d);
|
|
1281
1286
|
const { api } = await authed(args, d);
|
|
1282
|
-
const
|
|
1287
|
+
const accountId = await resolveAccountId(args, api);
|
|
1283
1288
|
const params = new URLSearchParams({
|
|
1284
1289
|
offset: String(args.flags.offset ?? 0),
|
|
1285
1290
|
limit: String(args.flags.limit ?? 1e3)
|
|
1286
1291
|
});
|
|
1287
|
-
if (
|
|
1288
|
-
params.set("accountId", safeId);
|
|
1289
|
-
params.set("safeId", safeId);
|
|
1290
|
-
}
|
|
1292
|
+
if (accountId) params.set("accountId", accountId);
|
|
1291
1293
|
if (args.flags.agent) params.set("agentId", args.flags.agent);
|
|
1292
1294
|
const { transactions } = await api.get(`/transactions?${params.toString()}`);
|
|
1293
1295
|
const visible = args.flags.direction ? transactions.filter((t) => t.direction === args.flags.direction) : transactions;
|
|
@@ -1300,7 +1302,6 @@ async function cmdActivityExport(args, d) {
|
|
|
1300
1302
|
"token_symbol",
|
|
1301
1303
|
"token_address",
|
|
1302
1304
|
"counterparty_address",
|
|
1303
|
-
"safe_address",
|
|
1304
1305
|
"agent_name",
|
|
1305
1306
|
"tx_hash",
|
|
1306
1307
|
"chain_id",
|
|
@@ -1315,11 +1316,10 @@ async function cmdActivityExport(args, d) {
|
|
|
1315
1316
|
t.tokenSymbol ?? t.asset ?? "",
|
|
1316
1317
|
t.tokenAddress ?? "",
|
|
1317
1318
|
(t.direction === "in" ? t.from : t.to) ?? "",
|
|
1318
|
-
t.accountAddress ?? t.safeAddress ?? "",
|
|
1319
1319
|
t.agentName ?? "",
|
|
1320
1320
|
t.hash,
|
|
1321
1321
|
t.chainId != null ? String(t.chainId) : "",
|
|
1322
|
-
t.accountAddress ??
|
|
1322
|
+
t.accountAddress ?? ""
|
|
1323
1323
|
]);
|
|
1324
1324
|
d.o.text(toCsv(headers, rows), { format: "csv", rows: rows.length });
|
|
1325
1325
|
return EXIT.ok;
|
|
@@ -1360,11 +1360,11 @@ async function cmdCatalogList(args, d) {
|
|
|
1360
1360
|
return EXIT.ok;
|
|
1361
1361
|
}
|
|
1362
1362
|
async function resolveWalletAndToken(args, api, symbol) {
|
|
1363
|
-
const
|
|
1364
|
-
if (
|
|
1363
|
+
const accounts = accountsEnvelope(await api.get("/user/accounts"));
|
|
1364
|
+
if (accounts.length === 0) {
|
|
1365
1365
|
throw new HavenCliError("No wallet on this account yet \u2014 finish onboarding first.", EXIT.refused);
|
|
1366
1366
|
}
|
|
1367
|
-
const safe = args.flags.safe ?
|
|
1367
|
+
const safe = args.flags.safe ? accounts.find((s) => s.id === args.flags.safe || accountAddressOf(s) === args.flags.safe) : accounts.find((s) => s.is_default) ?? accounts[0];
|
|
1368
1368
|
if (!safe) throw new UsageError(`No wallet matches --safe ${args.flags.safe}`);
|
|
1369
1369
|
const { balances } = await api.get(
|
|
1370
1370
|
`/balances/${accountAddressOf(safe)}?chain_id=${safe.chain_id}`
|
|
@@ -1375,7 +1375,7 @@ async function resolveWalletAndToken(args, api, symbol) {
|
|
|
1375
1375
|
const known = balances.map((b) => b.symbol).join(", ");
|
|
1376
1376
|
throw new UsageError(`Unknown token ${symbol} on this wallet's chain. Available: ${known || "none"}`);
|
|
1377
1377
|
}
|
|
1378
|
-
return {
|
|
1378
|
+
return { accountId: safe.id, token };
|
|
1379
1379
|
}
|
|
1380
1380
|
var SETTLED = /* @__PURE__ */ new Set(["active", "expired", "cancelled", "failed"]);
|
|
1381
1381
|
async function pollSetup(api, setupId, d, wait) {
|
|
@@ -1409,16 +1409,12 @@ async function cmdAgentsConnect(args, d) {
|
|
|
1409
1409
|
if (!args.flags.budget || !args.flags.token || args.flags.period === void 0) {
|
|
1410
1410
|
throw new UsageError("--budget, --token and --period are required (period is whole minutes; 0 means one-time)");
|
|
1411
1411
|
}
|
|
1412
|
-
const {
|
|
1412
|
+
const { accountId, token } = await resolveWalletAndToken(args, api, args.flags.token);
|
|
1413
1413
|
const amount = parseTokenAmount(args.flags.budget, token.decimals, token.symbol);
|
|
1414
1414
|
if (!amount.ok) throw new UsageError(amount.message);
|
|
1415
1415
|
const setup = await api.post("/agent-connection-setups", {
|
|
1416
1416
|
name,
|
|
1417
|
-
|
|
1418
|
-
// (landing in P0's second round), `safe_id` is what a server without it
|
|
1419
|
-
// reads; the request works against either.
|
|
1420
|
-
account_id: safeId,
|
|
1421
|
-
safe_id: safeId,
|
|
1417
|
+
account_id: accountId,
|
|
1422
1418
|
allowances: [
|
|
1423
1419
|
{
|
|
1424
1420
|
token_address: token.address ?? "0x0000000000000000000000000000000000000000",
|