@agentcamo/cli 0.1.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.
@@ -0,0 +1,129 @@
1
+ import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
2
+ import { registerExactEvmScheme } from "@x402/evm/exact/client";
3
+ import { toClientEvmSigner } from "@x402/evm";
4
+ import { createWalletClient, http, publicActions, } from "viem";
5
+ import { base, baseSepolia } from "viem/chains";
6
+ import { privateKeyToAccount } from "viem/accounts";
7
+ import { registerExactSvmScheme } from "@x402/svm/exact/client";
8
+ import { createKeyPairSignerFromBytes } from "@solana/kit";
9
+ import { base58 } from "@scure/base";
10
+ export const API_URL = process.env.AGENTCAMO_API_URL ?? "https://api.agentcamo.xyz";
11
+ const NETWORK_TO_CHAIN = {
12
+ "eip155:8453": base,
13
+ "eip155:84532": baseSepolia,
14
+ };
15
+ export async function createSession(opts) {
16
+ const { mode, country, chain, privateKey } = opts;
17
+ // Build the request body based on mode (used for both probe and paid request)
18
+ const requestBody = buildRequestBody(mode, country);
19
+ // Probe the API to get 402 payment requirements
20
+ const probeRes = await fetch(`${API_URL}/sessions`, {
21
+ method: "POST",
22
+ headers: { "Content-Type": "application/json" },
23
+ body: JSON.stringify(requestBody),
24
+ });
25
+ if (probeRes.status !== 402) {
26
+ const body = await probeRes.text();
27
+ throw new Error(`Expected 402 from probe request, got ${probeRes.status}: ${body}`);
28
+ }
29
+ let paymentRequired;
30
+ const paymentRequiredHeader = probeRes.headers.get("payment-required");
31
+ if (paymentRequiredHeader) {
32
+ paymentRequired = JSON.parse(Buffer.from(paymentRequiredHeader, "base64").toString());
33
+ }
34
+ else {
35
+ paymentRequired = (await probeRes.json());
36
+ }
37
+ // Register the correct chain scheme on the x402 client
38
+ const client = new x402Client();
39
+ if (chain === "evm") {
40
+ const key = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
41
+ const account = privateKeyToAccount(key);
42
+ const evmAccept = paymentRequired.accepts.find((a) => a.network.startsWith("eip155:"));
43
+ if (!evmAccept) {
44
+ throw new Error("No EVM network found in 402 response accepts array");
45
+ }
46
+ const detectedNetwork = evmAccept.network;
47
+ const viemChain = NETWORK_TO_CHAIN[detectedNetwork];
48
+ if (!viemChain) {
49
+ throw new Error(`Unknown EVM network from 402 response: ${detectedNetwork}`);
50
+ }
51
+ const wallet = createWalletClient({
52
+ account,
53
+ chain: viemChain,
54
+ transport: http(),
55
+ }).extend(publicActions);
56
+ registerExactEvmScheme(client, {
57
+ signer: toClientEvmSigner(account, wallet),
58
+ });
59
+ }
60
+ else {
61
+ const signer = await createKeyPairSignerFromBytes(base58.decode(privateKey));
62
+ registerExactSvmScheme(client, { signer });
63
+ }
64
+ // Make the paid request
65
+ const paidFetch = wrapFetchWithPayment(fetch, client);
66
+ const res = await paidFetch(`${API_URL}/sessions`, {
67
+ method: "POST",
68
+ headers: { "Content-Type": "application/json" },
69
+ body: JSON.stringify(requestBody),
70
+ });
71
+ if (res.status === 402) {
72
+ const header = res.headers.get("payment-required");
73
+ let decoded;
74
+ if (header) {
75
+ decoded = JSON.parse(Buffer.from(header, "base64").toString());
76
+ }
77
+ const payTo = decoded?.accepts?.[0]?.payTo ?? "unknown";
78
+ throw new Error(`Payment failed (402). PayTo: ${payTo}. ` +
79
+ `Ensure your wallet has sufficient USDC and that the payer address differs from the PayTo address ` +
80
+ `(the x402 facilitator rejects self-transfers).`);
81
+ }
82
+ if (res.status !== 201) {
83
+ const body = await res.text();
84
+ throw new Error(`Session creation failed (${res.status}): ${body}`);
85
+ }
86
+ return (await res.json());
87
+ }
88
+ export function buildRequestBody(mode, country) {
89
+ switch (mode) {
90
+ case "residential":
91
+ return { countryCode: country, mode: "http" };
92
+ case "mobile":
93
+ return { countryCode: country, mode: "http", proxyType: "mobile" };
94
+ case "socks5":
95
+ return { countryCode: country, mode: "socks5" };
96
+ case "wireguard":
97
+ return { countryCode: country, mode: "wireguard" };
98
+ }
99
+ }
100
+ export function buildProxyUrl(response, mode) {
101
+ switch (mode) {
102
+ case "residential":
103
+ case "mobile": {
104
+ const proxyHost = new URL(API_URL).hostname;
105
+ return `https://${encodeURIComponent(response.sessionId)}:${encodeURIComponent(response.token)}@${proxyHost}:8080`;
106
+ }
107
+ case "socks5": {
108
+ if (response.mode !== "socks5") {
109
+ throw new Error(`Expected socks5 response, got mode=${response.mode}`);
110
+ }
111
+ const s5 = response.socks5;
112
+ return `socks5h://${encodeURIComponent(s5.username)}:${encodeURIComponent(s5.password)}@${s5.host}:${s5.port}`;
113
+ }
114
+ case "wireguard":
115
+ return "socks5h://localhost:1080";
116
+ }
117
+ }
118
+ export async function deleteSession(sessionId, token) {
119
+ try {
120
+ await fetch(`${API_URL}/sessions/${sessionId}`, {
121
+ method: "DELETE",
122
+ headers: { Authorization: `Bearer ${token}` },
123
+ });
124
+ }
125
+ catch {
126
+ // Best-effort cleanup — swallow errors
127
+ }
128
+ }
129
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,IAAI,EACJ,aAAa,GAEd,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,MAAM,CAAC,MAAM,OAAO,GAClB,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,2BAA2B,CAAC;AAE/D,MAAM,gBAAgB,GAA8B;IAClD,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,WAAW;CAC5B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAKnC;IACC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAElD,8EAA8E;IAC9E,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEpD,gDAAgD;IAChD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,WAAW,EAAE;QAClD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;KAClC,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,wCAAwC,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CACnE,CAAC;IACJ,CAAC;IAED,IAAI,eAAuE,CAAC;IAC5E,MAAM,qBAAqB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACvE,IAAI,qBAAqB,EAAE,CAAC;QAC1B,eAAe,GAAG,IAAI,CAAC,KAAK,CAC1B,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CACxD,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,eAAe,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2B,CAAC;IACtE,CAAC;IAED,uDAAuD;IACvD,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;IAEhC,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;QACzE,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAoB,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACnD,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAChC,CAAC;QACF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAC;QAC1C,MAAM,SAAS,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,0CAA0C,eAAe,EAAE,CAC5D,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,kBAAkB,CAAC;YAChC,OAAO;YACP,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,IAAI,EAAE;SAClB,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACzB,sBAAsB,CAAC,MAAM,EAAE;YAC7B,MAAM,EAAE,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC;SAC3C,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAC/C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAC1B,CAAC;QACF,sBAAsB,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,wBAAwB;IACxB,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,OAAO,WAAW,EAAE;QACjD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;KAClC,CAAC,CAAC;IAEH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACnD,IAAI,OAES,CAAC;QACd,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,SAAS,CAAC;QACxD,MAAM,IAAI,KAAK,CACb,gCAAgC,KAAK,IAAI;YACvC,mGAAmG;YACnG,gDAAgD,CACnD,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0B,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAa,EACb,OAAe;IAEf,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa;YAChB,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAChD,KAAK,QAAQ;YACX,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;QACrE,KAAK,QAAQ;YACX,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAClD,KAAK,WAAW;YACd,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACvD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,QAA+B,EAC/B,IAAa;IAEb,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa,CAAC;QACnB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;YAC5C,OAAO,WAAW,kBAAkB,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,OAAO,CAAC;QACrH,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,sCAAsC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YACzE,CAAC;YACD,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC3B,OAAO,aAAa,kBAAkB,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QACjH,CAAC;QACD,KAAK,WAAW;YACd,OAAO,0BAA0B,CAAC;IACtC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,SAAiB,EACjB,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,GAAG,OAAO,aAAa,SAAS,EAAE,EAAE;YAC9C,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;SAC9C,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,uCAAuC;IACzC,CAAC;AACH,CAAC"}
package/dist/tui.d.ts ADDED
@@ -0,0 +1,47 @@
1
+ import type { SessionState } from "./types.js";
2
+ export declare function formatTtl(seconds: number): string;
3
+ export declare function timerColor(remaining: number, total: number): "green" | "yellow" | "red" | "gray";
4
+ export declare class SessionTUI {
5
+ private session;
6
+ private exitIp;
7
+ private country;
8
+ private statusMsg;
9
+ private errorMsg;
10
+ private expiresAt;
11
+ private ttlTotal;
12
+ private frameIndex;
13
+ private intervalId;
14
+ private totalLines;
15
+ private titlePrinted;
16
+ private inputBuffer;
17
+ private inputEnabled;
18
+ private cooldownUntil;
19
+ private onSwapCallback;
20
+ private swapping;
21
+ private keyHandler;
22
+ constructor();
23
+ /** Called once after session is created */
24
+ setSession(state: SessionState): void;
25
+ /** Register a callback for geo-swap. Called when user types a country code + Enter. */
26
+ onSwap(cb: (country: string) => Promise<{
27
+ country: string;
28
+ exitIp?: string;
29
+ cooldownExpiresAt?: string;
30
+ } | null>): void;
31
+ /** Start the 250ms render loop and enable stdin input */
32
+ start(): void;
33
+ /** Enable inline input (call after session is ready and IP verified) */
34
+ enableInput(): void;
35
+ /** Stop rendering, show cursor, restore stdin */
36
+ stop(): void;
37
+ /** Update exit IP after verification */
38
+ setExitIp(ip: string): void;
39
+ /** Set a status message (e.g. "Creating session...", "Verifying exit IP...") */
40
+ setStatus(msg: string): void;
41
+ /** Set an error message (replaces status line, red) */
42
+ setError(msg: string): void;
43
+ private handleKey;
44
+ private submitSwap;
45
+ private clearRenderedLines;
46
+ private render;
47
+ }
package/dist/tui.js ADDED
@@ -0,0 +1,295 @@
1
+ // cli/src/tui.ts — Single-session TUI renderer (renders to stderr)
2
+ import chalk from "chalk";
3
+ // --- Constants ---
4
+ const SPINNER_FRAMES = [
5
+ "\u280B",
6
+ "\u2819",
7
+ "\u2839",
8
+ "\u2838",
9
+ "\u283C",
10
+ "\u2834",
11
+ "\u2826",
12
+ "\u2827",
13
+ "\u2807",
14
+ "\u280F",
15
+ ];
16
+ const BAR_WIDTH = 20;
17
+ const RENDER_INTERVAL_MS = 250;
18
+ // --- Pure helper functions (exported for testing) ---
19
+ export function formatTtl(seconds) {
20
+ const clamped = Math.max(0, Math.floor(seconds));
21
+ const m = Math.floor(clamped / 60);
22
+ const s = clamped % 60;
23
+ return `${m}:${s.toString().padStart(2, "0")}`;
24
+ }
25
+ export function timerColor(remaining, total) {
26
+ if (remaining <= 0)
27
+ return "gray";
28
+ const pct = remaining / total;
29
+ if (pct > 0.5)
30
+ return "green";
31
+ if (pct > 0.2)
32
+ return "yellow";
33
+ return "red";
34
+ }
35
+ // --- Truecolor banner (#00FF88 bold) ---
36
+ function greenBoldBanner(text) {
37
+ return `\x1b[1;38;2;0;255;136m${text}\x1b[0m`;
38
+ }
39
+ // --- Color lookup ---
40
+ const TIMER_COLOR_FNS = {
41
+ green: chalk.green,
42
+ yellow: chalk.yellow,
43
+ red: chalk.red,
44
+ gray: chalk.dim,
45
+ };
46
+ // --- SessionTUI ---
47
+ export class SessionTUI {
48
+ session = null;
49
+ exitIp = null;
50
+ country = null;
51
+ statusMsg = null;
52
+ errorMsg = null;
53
+ expiresAt = null;
54
+ ttlTotal = 0;
55
+ frameIndex = 0;
56
+ intervalId = null;
57
+ totalLines = 0;
58
+ titlePrinted = false;
59
+ // Inline input state
60
+ inputBuffer = "";
61
+ inputEnabled = false;
62
+ cooldownUntil = null;
63
+ onSwapCallback = null;
64
+ swapping = false;
65
+ // Bound key handler for proper cleanup
66
+ keyHandler = (data) => this.handleKey(data);
67
+ constructor() { }
68
+ /** Called once after session is created */
69
+ setSession(state) {
70
+ this.session = state;
71
+ this.exitIp = state.exitIp;
72
+ this.country = state.country;
73
+ this.ttlTotal = state.ttl;
74
+ this.expiresAt = state.expiresAt;
75
+ }
76
+ /** Register a callback for geo-swap. Called when user types a country code + Enter. */
77
+ onSwap(cb) {
78
+ this.onSwapCallback = cb;
79
+ }
80
+ /** Start the 250ms render loop and enable stdin input */
81
+ start() {
82
+ process.stderr.write("\x1b[?25l"); // hide cursor
83
+ this.render();
84
+ this.intervalId = setInterval(() => {
85
+ this.frameIndex = (this.frameIndex + 1) % SPINNER_FRAMES.length;
86
+ this.render();
87
+ }, RENDER_INTERVAL_MS);
88
+ }
89
+ /** Enable inline input (call after session is ready and IP verified) */
90
+ enableInput() {
91
+ if (this.inputEnabled)
92
+ return;
93
+ this.inputEnabled = true;
94
+ if (process.stdin.isTTY) {
95
+ process.stdin.setRawMode(true);
96
+ process.stdin.resume();
97
+ process.stdin.on("data", this.keyHandler);
98
+ }
99
+ }
100
+ /** Stop rendering, show cursor, restore stdin */
101
+ stop() {
102
+ if (this.intervalId) {
103
+ clearInterval(this.intervalId);
104
+ this.intervalId = null;
105
+ }
106
+ if (this.inputEnabled && process.stdin.isTTY) {
107
+ process.stdin.off("data", this.keyHandler);
108
+ process.stdin.setRawMode(false);
109
+ process.stdin.pause();
110
+ }
111
+ process.stderr.write("\x1b[?25h"); // show cursor
112
+ }
113
+ /** Update exit IP after verification */
114
+ setExitIp(ip) {
115
+ this.exitIp = ip;
116
+ }
117
+ /** Set a status message (e.g. "Creating session...", "Verifying exit IP...") */
118
+ setStatus(msg) {
119
+ this.statusMsg = msg;
120
+ this.errorMsg = null;
121
+ }
122
+ /** Set an error message (replaces status line, red) */
123
+ setError(msg) {
124
+ this.errorMsg = msg;
125
+ this.statusMsg = null;
126
+ }
127
+ // --- Input handling ---
128
+ handleKey(data) {
129
+ const key = data.toString();
130
+ // Ctrl+C
131
+ if (key === "\x03") {
132
+ this.stop();
133
+ process.kill(process.pid, "SIGINT");
134
+ return;
135
+ }
136
+ // Escape — clear input
137
+ if (key === "\x1b") {
138
+ this.inputBuffer = "";
139
+ return;
140
+ }
141
+ // Backspace
142
+ if (key === "\x7f" || key === "\b") {
143
+ this.inputBuffer = this.inputBuffer.slice(0, -1);
144
+ return;
145
+ }
146
+ // Enter — submit
147
+ if (key === "\r" || key === "\n") {
148
+ const input = this.inputBuffer.trim().toLowerCase();
149
+ this.inputBuffer = "";
150
+ if (input.length === 2 && /^[a-z]{2}$/.test(input)) {
151
+ this.submitSwap(input);
152
+ }
153
+ else if (input.length > 0) {
154
+ this.setStatus(`Invalid country code: "${input}" (use 2-letter ISO code)`);
155
+ setTimeout(() => this.setStatus(""), 3000);
156
+ }
157
+ return;
158
+ }
159
+ // Regular character — append if alphabetic and under 2 chars
160
+ if (/^[a-zA-Z]$/.test(key) && this.inputBuffer.length < 2) {
161
+ this.inputBuffer += key;
162
+ }
163
+ }
164
+ async submitSwap(country) {
165
+ if (!this.onSwapCallback || this.swapping)
166
+ return;
167
+ // Check cooldown
168
+ if (this.cooldownUntil && Date.now() < this.cooldownUntil) {
169
+ const secs = Math.ceil((this.cooldownUntil - Date.now()) / 1000);
170
+ this.setStatus(`Cooldown: ${secs}s remaining`);
171
+ return;
172
+ }
173
+ this.swapping = true;
174
+ this.setStatus(`Swapping to ${country.toUpperCase()}...`);
175
+ try {
176
+ const result = await this.onSwapCallback(country);
177
+ if (result) {
178
+ this.country = result.country;
179
+ if (result.exitIp)
180
+ this.exitIp = result.exitIp;
181
+ // Set cooldown from server response (90s cooldown after successful swap)
182
+ if (result.cooldownExpiresAt) {
183
+ this.cooldownUntil = new Date(result.cooldownExpiresAt).getTime();
184
+ }
185
+ this.setStatus(`Swapped to ${result.country.toUpperCase()}`);
186
+ setTimeout(() => this.setStatus(""), 3000);
187
+ }
188
+ }
189
+ catch (err) {
190
+ const msg = err instanceof Error ? err.message : String(err);
191
+ if (msg.includes("cooldown") || msg.includes("Rate limited")) {
192
+ // Parse ISO timestamp from error (e.g., "...until 2026-03-16T19:15:00.000Z")
193
+ const isoMatch = msg.match(/\d{4}-\d{2}-\d{2}T[\d:.]+Z/);
194
+ if (isoMatch) {
195
+ this.cooldownUntil = new Date(isoMatch[0]).getTime();
196
+ }
197
+ else {
198
+ // Fallback: assume 90s cooldown
199
+ this.cooldownUntil = Date.now() + 90_000;
200
+ }
201
+ const secs = Math.ceil(((this.cooldownUntil ?? Date.now()) - Date.now()) / 1000);
202
+ this.setStatus(`Cooldown: ${secs}s remaining`);
203
+ }
204
+ else {
205
+ this.setStatus(`Swap failed: ${msg}`);
206
+ }
207
+ setTimeout(() => this.setStatus(""), 5000);
208
+ }
209
+ finally {
210
+ this.swapping = false;
211
+ }
212
+ }
213
+ // --- Private rendering ---
214
+ clearRenderedLines() {
215
+ if (this.totalLines > 0) {
216
+ process.stderr.write(`\x1b[${this.totalLines}A`);
217
+ for (let i = 0; i < this.totalLines; i++) {
218
+ process.stderr.write("\x1b[2K\n");
219
+ }
220
+ process.stderr.write(`\x1b[${this.totalLines}A`);
221
+ }
222
+ }
223
+ render() {
224
+ this.clearRenderedLines();
225
+ const cols = process.stderr.columns || 80;
226
+ const modeLabel = this.session
227
+ ? this.session.mode.toUpperCase()
228
+ : "SESSION";
229
+ // Title — print once, never re-rendered (avoids drift from line wrapping)
230
+ if (!this.titlePrinted) {
231
+ process.stderr.write(greenBoldBanner(`AGENT CAMO \u2014 ${modeLabel}`) + "\n\n");
232
+ this.titlePrinted = true;
233
+ }
234
+ const lines = [];
235
+ if (this.session) {
236
+ const shortId = this.session.sessionId.slice(0, 8);
237
+ const countryDisplay = (this.country ?? this.session.country).toUpperCase();
238
+ const ipDisplay = this.exitIp ?? "...";
239
+ // Session info line
240
+ lines.push(` Session: ${chalk.white(shortId + "...")} Country: ${chalk.bold(countryDisplay)} Exit IP: ${chalk.cyan(ipDisplay)}`);
241
+ // TTL + progress bar (use server's expiresAt for accurate remaining time)
242
+ const remaining = this.expiresAt
243
+ ? Math.max(0, (this.expiresAt.getTime() - Date.now()) / 1000)
244
+ : 0;
245
+ const color = timerColor(remaining, this.ttlTotal);
246
+ const colorFn = TIMER_COLOR_FNS[color];
247
+ const fraction = this.ttlTotal > 0 ? remaining / this.ttlTotal : 0;
248
+ const filled = Math.round(fraction * BAR_WIDTH);
249
+ const empty = BAR_WIDTH - filled;
250
+ const bar = colorFn("\u2588".repeat(filled)) + chalk.dim("\u2591".repeat(empty));
251
+ lines.push(` ${colorFn(`TTL ${formatTtl(remaining)}`)} ${bar} Mode: ${chalk.white(modeLabel)}`);
252
+ // Proxy URL — truncate to terminal width to prevent wrapping
253
+ const proxyLabel = ` Proxy: `;
254
+ const maxUrlLen = cols - proxyLabel.length - 1;
255
+ const url = this.session.proxyUrl.length > maxUrlLen
256
+ ? this.session.proxyUrl.slice(0, maxUrlLen - 3) + "..."
257
+ : this.session.proxyUrl;
258
+ lines.push(`${proxyLabel}${chalk.dim(url)}`);
259
+ }
260
+ else {
261
+ lines.push(` ${chalk.dim("Waiting for session...")}`);
262
+ }
263
+ lines.push("");
264
+ // Status / error / prompt line
265
+ if (this.errorMsg) {
266
+ lines.push(` ${chalk.red(this.errorMsg)}`);
267
+ }
268
+ else if (this.statusMsg) {
269
+ const spinner = SPINNER_FRAMES[this.frameIndex];
270
+ lines.push(` ${chalk.green(spinner)} ${chalk.dim(this.statusMsg)}`);
271
+ }
272
+ else if (this.inputEnabled &&
273
+ this.cooldownUntil &&
274
+ Date.now() < this.cooldownUntil) {
275
+ const secs = Math.ceil((this.cooldownUntil - Date.now()) / 1000);
276
+ lines.push(` ${chalk.yellow(`Cooldown: ${secs}s`)} ${chalk.dim("(geo-swap)")}`);
277
+ }
278
+ else if (this.inputEnabled) {
279
+ lines.push(` ${chalk.dim(">")} ${this.inputBuffer}${chalk.dim("_")} ${chalk.dim("type country code to geo-swap")}`);
280
+ }
281
+ else {
282
+ lines.push(` ${chalk.dim(">")} _`);
283
+ }
284
+ const output = lines.join("\n") + "\n";
285
+ process.stderr.write(output);
286
+ this.totalLines = lines.length;
287
+ // Auto-stop when TTL expires
288
+ if (this.session && this.expiresAt) {
289
+ if (Date.now() >= this.expiresAt.getTime()) {
290
+ this.stop();
291
+ }
292
+ }
293
+ }
294
+ }
295
+ //# sourceMappingURL=tui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui.js","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ export type SessionMode = "http" | "wireguard" | "socks5";
2
+ export type ProxyType = "residential" | "mobile";
3
+ export type CliMode = "residential" | "mobile" | "socks5" | "wireguard";
4
+ export type Chain = "evm" | "solana";
5
+ interface BaseCreateSessionResponse {
6
+ sessionId: string;
7
+ token: string;
8
+ country: string;
9
+ expiresAt: string;
10
+ ttl: number;
11
+ ttl_remaining: number;
12
+ proxyType?: ProxyType;
13
+ }
14
+ export interface HttpCreateSessionResponse extends BaseCreateSessionResponse {
15
+ mode: "http";
16
+ proxyHost: string;
17
+ proxyPort: number;
18
+ proxyAuth: string;
19
+ }
20
+ export interface WireGuardConfigBlock {
21
+ endpoint: string;
22
+ server_public_key: string;
23
+ client_private_key: string;
24
+ client_address: string;
25
+ dns: string;
26
+ allowed_ips: string;
27
+ persistent_keepalive: number;
28
+ }
29
+ export interface WireGuardCreateSessionResponse extends BaseCreateSessionResponse {
30
+ mode: "wireguard";
31
+ wireguard_config: WireGuardConfigBlock;
32
+ }
33
+ export interface Socks5CreateSessionResponse extends BaseCreateSessionResponse {
34
+ mode: "socks5";
35
+ socks5: {
36
+ host: string;
37
+ port: number;
38
+ username: string;
39
+ password: string;
40
+ };
41
+ }
42
+ export type CreateSessionResponse = HttpCreateSessionResponse | WireGuardCreateSessionResponse | Socks5CreateSessionResponse;
43
+ export interface LocationSwapResponse {
44
+ sessionId: string;
45
+ country: string;
46
+ previousCountry: string;
47
+ switchCount: number;
48
+ cooldownExpiresAt: string;
49
+ }
50
+ export interface SessionState {
51
+ sessionId: string;
52
+ token: string;
53
+ country: string;
54
+ mode: CliMode;
55
+ exitIp: string | null;
56
+ expiresAt: Date;
57
+ ttl: number;
58
+ startedAt: number;
59
+ proxyUrl: string;
60
+ response: CreateSessionResponse;
61
+ }
62
+ export {};
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@agentcamo/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for Agent Camo — residential proxy sessions for AI agents via x402 micropayments",
5
+ "type": "module",
6
+ "bin": {
7
+ "agentcamo": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "dev": "tsx src/cli.ts",
15
+ "test": "vitest run",
16
+ "test:watch": "vitest",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "engines": {
20
+ "node": ">=20"
21
+ },
22
+ "keywords": [
23
+ "proxy",
24
+ "residential",
25
+ "x402",
26
+ "ai-agent",
27
+ "wireguard",
28
+ "socks5",
29
+ "geo-targeting",
30
+ "agent-camo"
31
+ ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/Agent-Camo/agent-camo.git",
35
+ "directory": "cli"
36
+ },
37
+ "homepage": "https://agentcamo.xyz",
38
+ "bugs": "https://github.com/Agent-Camo/agent-camo/issues",
39
+ "author": "Hunter Gemmer",
40
+ "license": "MIT",
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "dependencies": {
45
+ "@scure/base": "^1.2.4",
46
+ "@solana/kit": "^6.1.0",
47
+ "@x402/evm": "^2.5.0",
48
+ "@x402/fetch": "^2.6.0",
49
+ "@x402/svm": "^2.5.0",
50
+ "chalk": "^5.6.0",
51
+ "viem": "^2.46.0",
52
+ "yargs": "^18.0.0"
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^22.0.0",
56
+ "@types/yargs": "^17.0.33",
57
+ "tsx": "^4.21.0",
58
+ "typescript": "^5.9.0",
59
+ "vitest": "^4.1.0"
60
+ }
61
+ }