@haven_ai/cli 0.2.1-alpha.0 → 0.4.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/README.md
CHANGED
|
@@ -210,7 +210,7 @@ Approving the budget stays with the human, in the browser, every time.
|
|
|
210
210
|
Prints the funding instruction a human acts on: what to send (each token's
|
|
211
211
|
documented minimum-useful amount), to which address, on which chain, plus the
|
|
212
212
|
explorer link and a faucet link on testnets. It reads
|
|
213
|
-
`GET /user/
|
|
213
|
+
`GET /user/accounts/:accountId/funding` — the same facts the dashboard's funding
|
|
214
214
|
card shows — and composes nothing locally, so the printed sentence and the
|
|
215
215
|
dashboard can never disagree about the amount.
|
|
216
216
|
|
package/dist/cli.cjs
CHANGED
|
@@ -604,9 +604,9 @@ async function runConnector(connectorCommand, spawner, onStderr) {
|
|
|
604
604
|
|
|
605
605
|
// src/commands.ts
|
|
606
606
|
var DEFAULT_API = "https://havenbackend-production-8a00.up.railway.app";
|
|
607
|
-
var CLI_VERSION = "0.
|
|
607
|
+
var CLI_VERSION = "0.4.0-alpha.0";
|
|
608
608
|
function accountAddressOf(s) {
|
|
609
|
-
return s.account_address ??
|
|
609
|
+
return s.account_address ?? "";
|
|
610
610
|
}
|
|
611
611
|
async function run(argv, deps = {}) {
|
|
612
612
|
const out = deps.out ?? ((l) => process.stdout.write(`${l}
|
|
@@ -876,24 +876,32 @@ async function cmdWhoami(args, d) {
|
|
|
876
876
|
);
|
|
877
877
|
return EXIT.ok;
|
|
878
878
|
}
|
|
879
|
+
function accountsEnvelope(body) {
|
|
880
|
+
if (!Array.isArray(body.accounts)) {
|
|
881
|
+
throw new Error(
|
|
882
|
+
"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."
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
return body.accounts;
|
|
886
|
+
}
|
|
879
887
|
async function cmdWalletsList(args, d) {
|
|
880
888
|
const { api } = await authed(args, d);
|
|
881
|
-
const
|
|
889
|
+
const accounts = accountsEnvelope(await api.get("/user/accounts"));
|
|
882
890
|
emit(
|
|
883
891
|
d,
|
|
884
892
|
args.flags.json,
|
|
885
|
-
|
|
886
|
-
() =>
|
|
893
|
+
accounts,
|
|
894
|
+
() => accounts.length === 0 ? "No Haven wallets yet." : table(
|
|
887
895
|
["NAME", "NETWORK", "ADDRESS", "DEFAULT"],
|
|
888
|
-
|
|
896
|
+
accounts.map((s) => [s.name, chainName(s.chain_id), truncateAddress(accountAddressOf(s)), s.is_default ? "\u2713" : ""])
|
|
889
897
|
)
|
|
890
898
|
);
|
|
891
899
|
return EXIT.ok;
|
|
892
900
|
}
|
|
893
901
|
async function cmdWalletsBalances(args, d) {
|
|
894
902
|
const { api } = await authed(args, d);
|
|
895
|
-
const
|
|
896
|
-
const safe = pickSafe(
|
|
903
|
+
const accounts = accountsEnvelope(await api.get("/user/accounts"));
|
|
904
|
+
const safe = pickSafe(accounts, args.flags.safe);
|
|
897
905
|
if (!safe) {
|
|
898
906
|
if (args.flags.safe) throw new UsageError(`No wallet matches "${args.flags.safe}".`);
|
|
899
907
|
throw new CliApiError("No Haven wallet found.", 404);
|
|
@@ -904,7 +912,7 @@ async function cmdWalletsBalances(args, d) {
|
|
|
904
912
|
emit(
|
|
905
913
|
d,
|
|
906
914
|
args.flags.json,
|
|
907
|
-
{ account: safe.name,
|
|
915
|
+
{ account: safe.name, chainId: safe.chain_id, balances },
|
|
908
916
|
() => [
|
|
909
917
|
`${safe.name} \xB7 ${chainName(safe.chain_id)} \xB7 ${truncateAddress(accountAddressOf(safe))}`,
|
|
910
918
|
balances.length === 0 ? " (no balances)" : table(["TOKEN", "BALANCE"], balances.map((b) => [b.symbol, b.formatted]))
|
|
@@ -912,15 +920,15 @@ async function cmdWalletsBalances(args, d) {
|
|
|
912
920
|
);
|
|
913
921
|
return EXIT.ok;
|
|
914
922
|
}
|
|
915
|
-
function pickSafe(
|
|
916
|
-
if (!ref) return
|
|
923
|
+
function pickSafe(accounts, ref) {
|
|
924
|
+
if (!ref) return accounts.find((s) => s.is_default) ?? accounts[0];
|
|
917
925
|
const lower = ref.toLowerCase();
|
|
918
|
-
return
|
|
926
|
+
return accounts.find((s) => s.id === ref || accountAddressOf(s).toLowerCase() === lower);
|
|
919
927
|
}
|
|
920
928
|
async function cmdWalletsFunding(args, d) {
|
|
921
929
|
const { api } = await authed(args, d);
|
|
922
|
-
const
|
|
923
|
-
const safe = pickSafe(
|
|
930
|
+
const accounts = accountsEnvelope(await api.get("/user/accounts"));
|
|
931
|
+
const safe = pickSafe(accounts, args.flags.safe);
|
|
924
932
|
if (!safe) {
|
|
925
933
|
if (args.flags.safe) throw new UsageError(`No wallet matches "${args.flags.safe}".`);
|
|
926
934
|
throw new CliApiError("No Haven wallet found.", 404);
|
|
@@ -1063,8 +1071,8 @@ async function cmdBudgetGrant(args, d) {
|
|
|
1063
1071
|
EXIT.refused
|
|
1064
1072
|
);
|
|
1065
1073
|
}
|
|
1066
|
-
const accountAddress = agent.account_address
|
|
1067
|
-
const accountChainId = agent.account_chain_id
|
|
1074
|
+
const accountAddress = agent.account_address;
|
|
1075
|
+
const accountChainId = agent.account_chain_id;
|
|
1068
1076
|
if (!accountAddress || !accountChainId) {
|
|
1069
1077
|
throw new HavenCliError(`Agent ${id} has no wallet assigned yet \u2014 connect it first.`, EXIT.refused);
|
|
1070
1078
|
}
|
|
@@ -1239,27 +1247,24 @@ async function cmdWalletRename(args, d) {
|
|
|
1239
1247
|
if (!id || !name) throw new UsageError("Usage: haven wallets rename <id> <name>");
|
|
1240
1248
|
const { api } = await authed(args, d);
|
|
1241
1249
|
await api.put(`/user/accounts/${id}`, { name });
|
|
1242
|
-
emit(d, args.flags.json, { ok: true, account_id: id,
|
|
1250
|
+
emit(d, args.flags.json, { ok: true, account_id: id, name }, () => `Wallet ${id} renamed to "${name}".`);
|
|
1243
1251
|
return EXIT.ok;
|
|
1244
1252
|
}
|
|
1245
|
-
async function
|
|
1253
|
+
async function resolveAccountId(args, api) {
|
|
1246
1254
|
if (!args.flags.safe) return void 0;
|
|
1247
|
-
const
|
|
1248
|
-
const safe = pickSafe(
|
|
1255
|
+
const accounts = accountsEnvelope(await api.get("/user/accounts"));
|
|
1256
|
+
const safe = pickSafe(accounts, args.flags.safe);
|
|
1249
1257
|
if (!safe) throw new UsageError(`No wallet matches "${args.flags.safe}".`);
|
|
1250
1258
|
return safe.id;
|
|
1251
1259
|
}
|
|
1252
1260
|
async function cmdActivityList(args, d) {
|
|
1253
1261
|
const { api } = await authed(args, d);
|
|
1254
|
-
const
|
|
1262
|
+
const accountId = await resolveAccountId(args, api);
|
|
1255
1263
|
const params = new URLSearchParams({
|
|
1256
1264
|
offset: String(args.flags.offset ?? 0),
|
|
1257
1265
|
limit: String(args.flags.limit ?? 25)
|
|
1258
1266
|
});
|
|
1259
|
-
if (
|
|
1260
|
-
params.set("accountId", safeId);
|
|
1261
|
-
params.set("safeId", safeId);
|
|
1262
|
-
}
|
|
1267
|
+
if (accountId) params.set("accountId", accountId);
|
|
1263
1268
|
if (args.flags.agent) params.set("agentId", args.flags.agent);
|
|
1264
1269
|
const { transactions } = await api.get(`/transactions?${params.toString()}`);
|
|
1265
1270
|
const visible = args.flags.direction ? transactions.filter((t) => t.direction === args.flags.direction) : transactions;
|
|
@@ -1274,7 +1279,7 @@ async function cmdActivityList(args, d) {
|
|
|
1274
1279
|
t.direction === "in" ? "in" : "out",
|
|
1275
1280
|
`${t.direction === "in" ? "+" : "-"}${t.valueFormatted} ${t.asset}`,
|
|
1276
1281
|
t.source ?? "transfer",
|
|
1277
|
-
t.
|
|
1282
|
+
t.accountName ?? ""
|
|
1278
1283
|
])
|
|
1279
1284
|
)
|
|
1280
1285
|
);
|
|
@@ -1283,15 +1288,12 @@ async function cmdActivityList(args, d) {
|
|
|
1283
1288
|
async function cmdActivityExport(args, d) {
|
|
1284
1289
|
if (args.flags.format === "sie") return exportSie(args, d);
|
|
1285
1290
|
const { api } = await authed(args, d);
|
|
1286
|
-
const
|
|
1291
|
+
const accountId = await resolveAccountId(args, api);
|
|
1287
1292
|
const params = new URLSearchParams({
|
|
1288
1293
|
offset: String(args.flags.offset ?? 0),
|
|
1289
1294
|
limit: String(args.flags.limit ?? 1e3)
|
|
1290
1295
|
});
|
|
1291
|
-
if (
|
|
1292
|
-
params.set("accountId", safeId);
|
|
1293
|
-
params.set("safeId", safeId);
|
|
1294
|
-
}
|
|
1296
|
+
if (accountId) params.set("accountId", accountId);
|
|
1295
1297
|
if (args.flags.agent) params.set("agentId", args.flags.agent);
|
|
1296
1298
|
const { transactions } = await api.get(`/transactions?${params.toString()}`);
|
|
1297
1299
|
const visible = args.flags.direction ? transactions.filter((t) => t.direction === args.flags.direction) : transactions;
|
|
@@ -1304,7 +1306,6 @@ async function cmdActivityExport(args, d) {
|
|
|
1304
1306
|
"token_symbol",
|
|
1305
1307
|
"token_address",
|
|
1306
1308
|
"counterparty_address",
|
|
1307
|
-
"safe_address",
|
|
1308
1309
|
"agent_name",
|
|
1309
1310
|
"tx_hash",
|
|
1310
1311
|
"chain_id",
|
|
@@ -1319,11 +1320,10 @@ async function cmdActivityExport(args, d) {
|
|
|
1319
1320
|
t.tokenSymbol ?? t.asset ?? "",
|
|
1320
1321
|
t.tokenAddress ?? "",
|
|
1321
1322
|
(t.direction === "in" ? t.from : t.to) ?? "",
|
|
1322
|
-
t.accountAddress ?? t.safeAddress ?? "",
|
|
1323
1323
|
t.agentName ?? "",
|
|
1324
1324
|
t.hash,
|
|
1325
1325
|
t.chainId != null ? String(t.chainId) : "",
|
|
1326
|
-
t.accountAddress ??
|
|
1326
|
+
t.accountAddress ?? ""
|
|
1327
1327
|
]);
|
|
1328
1328
|
d.o.text(toCsv(headers, rows), { format: "csv", rows: rows.length });
|
|
1329
1329
|
return EXIT.ok;
|
|
@@ -1364,11 +1364,11 @@ async function cmdCatalogList(args, d) {
|
|
|
1364
1364
|
return EXIT.ok;
|
|
1365
1365
|
}
|
|
1366
1366
|
async function resolveWalletAndToken(args, api, symbol) {
|
|
1367
|
-
const
|
|
1368
|
-
if (
|
|
1367
|
+
const accounts = accountsEnvelope(await api.get("/user/accounts"));
|
|
1368
|
+
if (accounts.length === 0) {
|
|
1369
1369
|
throw new HavenCliError("No wallet on this account yet \u2014 finish onboarding first.", EXIT.refused);
|
|
1370
1370
|
}
|
|
1371
|
-
const safe = args.flags.safe ?
|
|
1371
|
+
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];
|
|
1372
1372
|
if (!safe) throw new UsageError(`No wallet matches --safe ${args.flags.safe}`);
|
|
1373
1373
|
const { balances } = await api.get(
|
|
1374
1374
|
`/balances/${accountAddressOf(safe)}?chain_id=${safe.chain_id}`
|
|
@@ -1379,7 +1379,7 @@ async function resolveWalletAndToken(args, api, symbol) {
|
|
|
1379
1379
|
const known = balances.map((b) => b.symbol).join(", ");
|
|
1380
1380
|
throw new UsageError(`Unknown token ${symbol} on this wallet's chain. Available: ${known || "none"}`);
|
|
1381
1381
|
}
|
|
1382
|
-
return {
|
|
1382
|
+
return { accountId: safe.id, token };
|
|
1383
1383
|
}
|
|
1384
1384
|
var SETTLED = /* @__PURE__ */ new Set(["active", "expired", "cancelled", "failed"]);
|
|
1385
1385
|
async function pollSetup(api, setupId, d, wait) {
|
|
@@ -1413,16 +1413,12 @@ async function cmdAgentsConnect(args, d) {
|
|
|
1413
1413
|
if (!args.flags.budget || !args.flags.token || args.flags.period === void 0) {
|
|
1414
1414
|
throw new UsageError("--budget, --token and --period are required (period is whole minutes; 0 means one-time)");
|
|
1415
1415
|
}
|
|
1416
|
-
const {
|
|
1416
|
+
const { accountId, token } = await resolveWalletAndToken(args, api, args.flags.token);
|
|
1417
1417
|
const amount = parseTokenAmount(args.flags.budget, token.decimals, token.symbol);
|
|
1418
1418
|
if (!amount.ok) throw new UsageError(amount.message);
|
|
1419
1419
|
const setup = await api.post("/agent-connection-setups", {
|
|
1420
1420
|
name,
|
|
1421
|
-
|
|
1422
|
-
// (landing in P0's second round), `safe_id` is what a server without it
|
|
1423
|
-
// reads; the request works against either.
|
|
1424
|
-
account_id: safeId,
|
|
1425
|
-
safe_id: safeId,
|
|
1421
|
+
account_id: accountId,
|
|
1426
1422
|
allowances: [
|
|
1427
1423
|
{
|
|
1428
1424
|
token_address: token.address ?? "0x0000000000000000000000000000000000000000",
|