@agentis-hq/cli 0.3.1 → 0.4.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/dist/index.js +222 -4
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -97,7 +97,9 @@ var SCOPES = [
|
|
|
97
97
|
"privacy:read",
|
|
98
98
|
"privacy:write",
|
|
99
99
|
"earn:read",
|
|
100
|
-
"earn:write"
|
|
100
|
+
"earn:write",
|
|
101
|
+
"jupiter:read",
|
|
102
|
+
"jupiter:write"
|
|
101
103
|
];
|
|
102
104
|
function base64url(bytes) {
|
|
103
105
|
return Buffer.from(bytes).toString("base64url");
|
|
@@ -131,8 +133,8 @@ async function login() {
|
|
|
131
133
|
const server = Bun.serve({
|
|
132
134
|
hostname: "127.0.0.1",
|
|
133
135
|
port: 0,
|
|
134
|
-
fetch(
|
|
135
|
-
const url = new URL(
|
|
136
|
+
fetch(request2) {
|
|
137
|
+
const url = new URL(request2.url);
|
|
136
138
|
if (url.pathname !== "/callback") return new Response("Not found", { status: 404 });
|
|
137
139
|
if (!handled) {
|
|
138
140
|
handled = true;
|
|
@@ -285,6 +287,9 @@ var DEFAULT_LOCAL_POLICY = {
|
|
|
285
287
|
maxBudget: null,
|
|
286
288
|
maxPerTx: null,
|
|
287
289
|
allowedDomains: [],
|
|
290
|
+
allowedMints: [],
|
|
291
|
+
maxSlippageBps: null,
|
|
292
|
+
maxDailySwapVolume: null,
|
|
288
293
|
killSwitch: false
|
|
289
294
|
};
|
|
290
295
|
function ensureVaultDir() {
|
|
@@ -837,6 +842,9 @@ Policy for ${name} (${scope}):`);
|
|
|
837
842
|
console.log(` Monthly limit: ${p.monthlyLimit !== null ? `$${p.monthlyLimit}` : "unlimited"}`);
|
|
838
843
|
console.log(` Total budget: ${p.maxBudget !== null ? `$${p.maxBudget}` : "unlimited"}`);
|
|
839
844
|
console.log(` Allowed domains: ${p.allowedDomains?.length > 0 ? p.allowedDomains.join(", ") : "all"}`);
|
|
845
|
+
console.log(` Allowed mints: ${p.allowedMints?.length > 0 ? p.allowedMints.join(", ") : "all"}`);
|
|
846
|
+
console.log(` Max slippage: ${p.maxSlippageBps !== null && p.maxSlippageBps !== void 0 ? `${p.maxSlippageBps} bps` : "unlimited"}`);
|
|
847
|
+
console.log(` Daily swaps: ${p.maxDailySwapVolume !== null && p.maxDailySwapVolume !== void 0 ? `$${p.maxDailySwapVolume}` : "unlimited"}`);
|
|
840
848
|
console.log();
|
|
841
849
|
}
|
|
842
850
|
function applyPolicyFlags(existingPolicy, args2) {
|
|
@@ -852,6 +860,8 @@ function applyPolicyFlags(existingPolicy, args2) {
|
|
|
852
860
|
if (get("--daily") !== void 0) policy.dailyLimit = parseFloat(get("--daily"));
|
|
853
861
|
if (get("--monthly") !== void 0) policy.monthlyLimit = parseFloat(get("--monthly"));
|
|
854
862
|
if (get("--budget") !== void 0) policy.maxBudget = parseFloat(get("--budget"));
|
|
863
|
+
if (get("--max-slippage-bps") !== void 0) policy.maxSlippageBps = parseInt(get("--max-slippage-bps"), 10);
|
|
864
|
+
if (get("--daily-swap-volume") !== void 0) policy.maxDailySwapVolume = parseFloat(get("--daily-swap-volume"));
|
|
855
865
|
if (get("--allow")) {
|
|
856
866
|
const domain = get("--allow").replace(/^https?:\/\//, "").toLowerCase();
|
|
857
867
|
policy.allowedDomains = [.../* @__PURE__ */ new Set([...policy.allowedDomains ?? [], domain])];
|
|
@@ -860,6 +870,14 @@ function applyPolicyFlags(existingPolicy, args2) {
|
|
|
860
870
|
const domain = get("--disallow").replace(/^https?:\/\//, "").toLowerCase();
|
|
861
871
|
policy.allowedDomains = (policy.allowedDomains ?? []).filter((d) => d !== domain);
|
|
862
872
|
}
|
|
873
|
+
if (get("--allow-mint")) {
|
|
874
|
+
const mint = get("--allow-mint");
|
|
875
|
+
policy.allowedMints = [.../* @__PURE__ */ new Set([...policy.allowedMints ?? [], mint])];
|
|
876
|
+
}
|
|
877
|
+
if (get("--disallow-mint")) {
|
|
878
|
+
const mint = get("--disallow-mint");
|
|
879
|
+
policy.allowedMints = (policy.allowedMints ?? []).filter((candidate) => candidate !== mint);
|
|
880
|
+
}
|
|
863
881
|
return policy;
|
|
864
882
|
}
|
|
865
883
|
async function policyGet(nameOrId) {
|
|
@@ -890,7 +908,7 @@ async function policySet(nameOrId, args2) {
|
|
|
890
908
|
const hosted = token ? await findHostedAgent2(nameOrId, token) : null;
|
|
891
909
|
if (hosted && token) {
|
|
892
910
|
const policy = applyPolicyFlags(hosted.policy, args2);
|
|
893
|
-
const res = await apiFetch(`/agents/${hosted.id}`, {
|
|
911
|
+
const res = await apiFetch(`/agents/${hosted.id}/policy`, {
|
|
894
912
|
method: "PATCH",
|
|
895
913
|
body: JSON.stringify({ policy })
|
|
896
914
|
}, token);
|
|
@@ -1559,6 +1577,159 @@ async function earnSweep(args2) {
|
|
|
1559
1577
|
await executeSweep(token, plan);
|
|
1560
1578
|
}
|
|
1561
1579
|
|
|
1580
|
+
// src/commands/jupiter.ts
|
|
1581
|
+
function getFlag4(args2, flag2) {
|
|
1582
|
+
const index = args2.indexOf(flag2);
|
|
1583
|
+
return index === -1 ? void 0 : args2[index + 1];
|
|
1584
|
+
}
|
|
1585
|
+
function hasFlag3(args2, flag2) {
|
|
1586
|
+
return args2.includes(flag2);
|
|
1587
|
+
}
|
|
1588
|
+
async function auth() {
|
|
1589
|
+
const token = await getToken();
|
|
1590
|
+
if (!token) {
|
|
1591
|
+
console.error("Not logged in. Run `agentis login` first.");
|
|
1592
|
+
process.exit(1);
|
|
1593
|
+
}
|
|
1594
|
+
return token;
|
|
1595
|
+
}
|
|
1596
|
+
async function request(path, token, init = {}) {
|
|
1597
|
+
const response = await apiFetch(path, init, token);
|
|
1598
|
+
const body = await response.json().catch(() => ({}));
|
|
1599
|
+
if (!response.ok) throw new Error(body.error ?? `Agentis API failed (${response.status})`);
|
|
1600
|
+
return body;
|
|
1601
|
+
}
|
|
1602
|
+
function tradeBody(args2) {
|
|
1603
|
+
const input = getFlag4(args2, "--from");
|
|
1604
|
+
const output = getFlag4(args2, "--to");
|
|
1605
|
+
const amount = getFlag4(args2, "--amount");
|
|
1606
|
+
const slippage = getFlag4(args2, "--slippage-bps");
|
|
1607
|
+
if (!input || !output || !amount) {
|
|
1608
|
+
throw new Error("--from, --to, and --amount are required");
|
|
1609
|
+
}
|
|
1610
|
+
return {
|
|
1611
|
+
input,
|
|
1612
|
+
output,
|
|
1613
|
+
amount,
|
|
1614
|
+
...slippage ? { slippageBps: Number(slippage) } : {}
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
function printToken(token) {
|
|
1618
|
+
const trust = token.audit?.isSus ? "suspicious" : token.isVerified ? "verified" : "unverified";
|
|
1619
|
+
console.log(` ${(token.symbol ?? "?").padEnd(10)} ${token.name ?? ""}`);
|
|
1620
|
+
console.log(` ${token.id}`);
|
|
1621
|
+
console.log(` ${trust} \xB7 decimals=${token.decimals} \xB7 organic=${token.organicScoreLabel ?? "unknown"}`);
|
|
1622
|
+
}
|
|
1623
|
+
async function financialCommand(args2) {
|
|
1624
|
+
const area = args2[0];
|
|
1625
|
+
const action = args2[1];
|
|
1626
|
+
const token = await auth();
|
|
1627
|
+
if (area === "tokens" && action === "search") {
|
|
1628
|
+
const query = args2.slice(2).filter((value) => !value.startsWith("--")).join(" ").trim();
|
|
1629
|
+
if (!query) throw new Error("Usage: agentis tokens search <query>");
|
|
1630
|
+
const data = await request(`/agents/jupiter/tokens?query=${encodeURIComponent(query)}`, token);
|
|
1631
|
+
if (hasFlag3(args2, "--json")) return console.log(JSON.stringify(data, null, 2));
|
|
1632
|
+
console.log(`
|
|
1633
|
+
Jupiter tokens matching "${query}"
|
|
1634
|
+
`);
|
|
1635
|
+
const matches = data.tokens ?? [];
|
|
1636
|
+
for (const item of matches.slice(0, 20)) printToken(item);
|
|
1637
|
+
if (matches.length > 20) console.log(` ...and ${matches.length - 20} more. Use --json for the full result.`);
|
|
1638
|
+
console.log();
|
|
1639
|
+
return;
|
|
1640
|
+
}
|
|
1641
|
+
if (area === "swap" && (action === "quote" || action === "execute")) {
|
|
1642
|
+
const agentName = args2[2];
|
|
1643
|
+
if (!agentName) throw new Error(`Usage: agentis swap ${action} <agent> --from SOL --to USDC --amount 0.1`);
|
|
1644
|
+
const agent = await resolveAccountAgent(agentName, token);
|
|
1645
|
+
const data = await request(
|
|
1646
|
+
`/agents/${agent.id}/jupiter/swap${action === "quote" ? "/quote" : ""}`,
|
|
1647
|
+
token,
|
|
1648
|
+
{ method: "POST", body: JSON.stringify(tradeBody(args2.slice(3))) }
|
|
1649
|
+
);
|
|
1650
|
+
if (hasFlag3(args2, "--json")) return console.log(JSON.stringify(data, null, 2));
|
|
1651
|
+
const quote = data.quote ?? data.order ?? {};
|
|
1652
|
+
console.log(`
|
|
1653
|
+
Jupiter swap ${action === "quote" ? "quote" : "executed"} for ${agent.name}`);
|
|
1654
|
+
console.log(` ${data.amountUi} ${data.inputToken?.symbol ?? data.inputToken?.id} -> ${data.outputToken?.symbol ?? data.outputToken?.id}`);
|
|
1655
|
+
console.log(` Expected out: ${quote.outAmount ?? data.result?.outputAmountResult ?? "unknown"} atomic`);
|
|
1656
|
+
console.log(` Router: ${quote.router ?? "unknown"}`);
|
|
1657
|
+
if (data.result?.signature) console.log(` Signature: ${data.result.signature}`);
|
|
1658
|
+
console.log();
|
|
1659
|
+
return;
|
|
1660
|
+
}
|
|
1661
|
+
if (area === "portfolio") {
|
|
1662
|
+
const agentName = args2[1];
|
|
1663
|
+
if (!agentName) throw new Error("Usage: agentis portfolio <agent> [--json]");
|
|
1664
|
+
const agent = await resolveAccountAgent(agentName, token);
|
|
1665
|
+
const data = await request(`/agents/${agent.id}/jupiter/portfolio`, token);
|
|
1666
|
+
if (hasFlag3(args2, "--json")) return console.log(JSON.stringify(data, null, 2));
|
|
1667
|
+
const elements = data.portfolio?.elements ?? [];
|
|
1668
|
+
console.log(`
|
|
1669
|
+
Jupiter portfolio for ${agent.name}`);
|
|
1670
|
+
console.log(` Positions: ${elements.length}`);
|
|
1671
|
+
for (const item of elements.slice(0, 20)) {
|
|
1672
|
+
console.log(` ${(item.label ?? item.type ?? "position").padEnd(18)} $${Number(item.value ?? 0).toFixed(2)} \xB7 ${item.platformId ?? "jupiter"}`);
|
|
1673
|
+
}
|
|
1674
|
+
console.log();
|
|
1675
|
+
return;
|
|
1676
|
+
}
|
|
1677
|
+
if (area === "recurring" && action === "list") {
|
|
1678
|
+
const agentName = args2[2];
|
|
1679
|
+
if (!agentName) throw new Error("Usage: agentis recurring list <agent> [--history] [--json]");
|
|
1680
|
+
const agent = await resolveAccountAgent(agentName, token);
|
|
1681
|
+
const status = hasFlag3(args2, "--history") ? "history" : "active";
|
|
1682
|
+
const data = await request(`/agents/${agent.id}/jupiter/recurring?status=${status}`, token);
|
|
1683
|
+
if (hasFlag3(args2, "--json")) return console.log(JSON.stringify(data, null, 2));
|
|
1684
|
+
const orders = Array.isArray(data.orders) ? data.orders : data.orders?.orders ?? [];
|
|
1685
|
+
console.log(`
|
|
1686
|
+
${status} Jupiter recurring orders for ${agent.name}`);
|
|
1687
|
+
if (!orders.length) console.log(" None.");
|
|
1688
|
+
for (const order of orders) {
|
|
1689
|
+
console.log(` ${order.orderKey ?? order.publicKey ?? order.id ?? "unknown"} \xB7 ${order.status ?? status}`);
|
|
1690
|
+
}
|
|
1691
|
+
console.log();
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
if (area === "recurring" && action === "create") {
|
|
1695
|
+
const agentName = args2[2];
|
|
1696
|
+
if (!agentName) throw new Error("Usage: agentis recurring create <agent> --from USDC --to SOL --amount 100 --orders 2 --interval 86400");
|
|
1697
|
+
const agent = await resolveAccountAgent(agentName, token);
|
|
1698
|
+
const numberOfOrders = Number(getFlag4(args2, "--orders"));
|
|
1699
|
+
const intervalSeconds = Number(getFlag4(args2, "--interval"));
|
|
1700
|
+
const data = await request(`/agents/${agent.id}/jupiter/recurring`, token, {
|
|
1701
|
+
method: "POST",
|
|
1702
|
+
body: JSON.stringify({
|
|
1703
|
+
...tradeBody(args2.slice(3)),
|
|
1704
|
+
numberOfOrders,
|
|
1705
|
+
intervalSeconds,
|
|
1706
|
+
startAt: getFlag4(args2, "--start-at") ? Number(getFlag4(args2, "--start-at")) : void 0
|
|
1707
|
+
})
|
|
1708
|
+
});
|
|
1709
|
+
if (hasFlag3(args2, "--json")) return console.log(JSON.stringify(data, null, 2));
|
|
1710
|
+
console.log(`
|
|
1711
|
+
Recurring order created for ${agent.name}`);
|
|
1712
|
+
console.log(` Order: ${data.result?.order ?? "submitted"}`);
|
|
1713
|
+
console.log(` Signature: ${data.result?.signature ?? "unknown"}
|
|
1714
|
+
`);
|
|
1715
|
+
return;
|
|
1716
|
+
}
|
|
1717
|
+
if (area === "recurring" && action === "cancel") {
|
|
1718
|
+
const agentName = args2[2];
|
|
1719
|
+
const order = args2[3];
|
|
1720
|
+
if (!agentName || !order) throw new Error("Usage: agentis recurring cancel <agent> <order>");
|
|
1721
|
+
const agent = await resolveAccountAgent(agentName, token);
|
|
1722
|
+
const data = await request(`/agents/${agent.id}/jupiter/recurring/${encodeURIComponent(order)}/cancel`, token, { method: "POST" });
|
|
1723
|
+
if (hasFlag3(args2, "--json")) return console.log(JSON.stringify(data, null, 2));
|
|
1724
|
+
console.log(`
|
|
1725
|
+
Recurring order cancelled for ${agent.name}`);
|
|
1726
|
+
console.log(` Signature: ${data.result?.signature ?? "unknown"}
|
|
1727
|
+
`);
|
|
1728
|
+
return;
|
|
1729
|
+
}
|
|
1730
|
+
console.log("Usage: agentis <tokens|swap|portfolio|recurring> ...");
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1562
1733
|
// src/index.ts
|
|
1563
1734
|
var args = process.argv.slice(2);
|
|
1564
1735
|
var cmd = args[0];
|
|
@@ -1670,6 +1841,31 @@ var helpSpecs = {
|
|
|
1670
1841
|
["sweep [--dry-run|--no-dry-run]", "sweep all hosted agents mainnet USDC into Jupiter Earn"]
|
|
1671
1842
|
]
|
|
1672
1843
|
},
|
|
1844
|
+
swap: {
|
|
1845
|
+
usage: "agentis swap <quote|execute> <agent> --from <token> --to <token> --amount <ui>",
|
|
1846
|
+
description: "Quote or execute policy-controlled swaps through Jupiter.",
|
|
1847
|
+
commands: [
|
|
1848
|
+
["quote <agent> --from <token> --to <token> --amount <ui>", "get a policy-checked quote"],
|
|
1849
|
+
["execute <agent> --from <token> --to <token> --amount <ui>", "execute the swap"]
|
|
1850
|
+
]
|
|
1851
|
+
},
|
|
1852
|
+
tokens: {
|
|
1853
|
+
usage: "agentis tokens search <query> [--json]",
|
|
1854
|
+
description: "Search Jupiter token metadata and safety signals."
|
|
1855
|
+
},
|
|
1856
|
+
portfolio: {
|
|
1857
|
+
usage: "agentis portfolio <agent> [--json]",
|
|
1858
|
+
description: "Show mainnet Jupiter portfolio positions."
|
|
1859
|
+
},
|
|
1860
|
+
recurring: {
|
|
1861
|
+
usage: "agentis recurring <list|create|cancel> ...",
|
|
1862
|
+
description: "Manage Jupiter time-based recurring swaps.",
|
|
1863
|
+
commands: [
|
|
1864
|
+
["list <agent> [--history] [--json]", "list active or historical orders"],
|
|
1865
|
+
["create <agent> --from <token> --to <token> --amount <ui> --orders <n> --interval <seconds>", "create an order"],
|
|
1866
|
+
["cancel <agent> <order>", "cancel an active order"]
|
|
1867
|
+
]
|
|
1868
|
+
},
|
|
1673
1869
|
"earn deposit": {
|
|
1674
1870
|
usage: "agentis earn deposit <agent> --asset USDC --amount <amount> --mainnet",
|
|
1675
1871
|
description: "Deposit mainnet USDC from a hosted agent wallet into Jupiter Earn.",
|
|
@@ -1829,6 +2025,10 @@ var helpSpecs = {
|
|
|
1829
2025
|
["--budget <usd>", "total lifetime budget cap"],
|
|
1830
2026
|
["--allow <domain>", "add domain to whitelist"],
|
|
1831
2027
|
["--disallow <domain>", "remove domain from whitelist"],
|
|
2028
|
+
["--allow-mint <mint>", "add token mint to Jupiter allowlist"],
|
|
2029
|
+
["--disallow-mint <mint>", "remove token mint from Jupiter allowlist"],
|
|
2030
|
+
["--max-slippage-bps <bps>", "maximum Jupiter swap slippage"],
|
|
2031
|
+
["--daily-swap-volume <usd>", "maximum Jupiter volume per 24 hours"],
|
|
1832
2032
|
["-h, --help", "display help for command"]
|
|
1833
2033
|
]
|
|
1834
2034
|
},
|
|
@@ -1878,6 +2078,14 @@ ${green2}${bold}Commands:${reset2}
|
|
|
1878
2078
|
earn positions <agent> --mainnet show Jupiter Earn positions
|
|
1879
2079
|
earn sweep [--dry-run|--no-dry-run] sweep all agents' mainnet USDC into Earn
|
|
1880
2080
|
|
|
2081
|
+
tokens search <query> search token metadata and safety
|
|
2082
|
+
swap quote <agent> quote a mainnet Jupiter swap
|
|
2083
|
+
swap execute <agent> execute a policy-checked swap
|
|
2084
|
+
portfolio <agent> show Jupiter portfolio positions
|
|
2085
|
+
recurring list <agent> list active or historical DCA orders
|
|
2086
|
+
recurring create <agent> create a time-based DCA order
|
|
2087
|
+
recurring cancel <agent> <order> cancel a DCA order
|
|
2088
|
+
|
|
1881
2089
|
facilitator create <name> scaffold a Kora-backed x402 facilitator
|
|
1882
2090
|
--dir <path> output directory
|
|
1883
2091
|
--fee-bps <bps> prepaid seller fee rate (default 500)
|
|
@@ -1909,6 +2117,10 @@ ${green2}${bold}Commands:${reset2}
|
|
|
1909
2117
|
--budget <usd> total lifetime budget cap
|
|
1910
2118
|
--allow <domain> add domain to whitelist
|
|
1911
2119
|
--disallow <domain> remove domain from whitelist
|
|
2120
|
+
--allow-mint <mint> add token mint to Jupiter allowlist
|
|
2121
|
+
--disallow-mint <mint> remove token mint from Jupiter allowlist
|
|
2122
|
+
--max-slippage-bps <bps> maximum Jupiter swap slippage
|
|
2123
|
+
--daily-swap-volume <usd> maximum Jupiter volume per 24 hours
|
|
1912
2124
|
`);
|
|
1913
2125
|
}
|
|
1914
2126
|
function hasHelpFlag(values) {
|
|
@@ -2015,6 +2227,12 @@ async function main() {
|
|
|
2015
2227
|
case "earn":
|
|
2016
2228
|
await earnCommand(args.slice(1));
|
|
2017
2229
|
break;
|
|
2230
|
+
case "tokens":
|
|
2231
|
+
case "swap":
|
|
2232
|
+
case "portfolio":
|
|
2233
|
+
case "recurring":
|
|
2234
|
+
await financialCommand(args);
|
|
2235
|
+
break;
|
|
2018
2236
|
default:
|
|
2019
2237
|
showHelp();
|
|
2020
2238
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentis-hq/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agentis": "dist/index.js"
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"check": "bun --check src/index.ts"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@agentis-hq/core": "^0.
|
|
45
|
-
"@agentis-hq/sdk": "^0.
|
|
44
|
+
"@agentis-hq/core": "^0.2.0",
|
|
45
|
+
"@agentis-hq/sdk": "^0.2.0",
|
|
46
46
|
"@napi-rs/keyring": "^1.2.0",
|
|
47
47
|
"@noble/ciphers": "^2.2.0",
|
|
48
48
|
"@noble/curves": "^2.2.0",
|