@zhieldcash/agent 0.0.0-stage → 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zhield Cash
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,65 @@
1
- # Temporary Holding Version
1
+ # @zhieldcash/agent
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A shielded wallet for AI agents. An [MCP](https://modelcontextprotocol.io) server that gives an agent (Claude, Cursor, any MCP client) its own wallet on Robinhood Chain, funded through [Zhield Cash](https://zhield.cash) so nothing on-chain links it to the person who runs it.
4
+
5
+ **The model never sees a note or a key.** Notes move through files on your machine; the tools only show a note's id, pool and state.
6
+
7
+ ```bash
8
+ npx @zhieldcash/agent init
9
+ ```
10
+
11
+ That creates `~/.zhield-agent` with the agent's key, prints its address and the config for your MCP client:
12
+
13
+ ```json
14
+ { "mcpServers": { "zhield": { "command": "npx", "args": ["-y", "@zhieldcash/agent"] } } }
15
+ ```
16
+
17
+ ## How it works
18
+
19
+ 1. **Fund it privately.** Shield ETH at [zhield.cash/app](https://zhield.cash/app) (or with `@zhieldcash/sdk`) and paste the notes into `~/.zhield-agent/inbox.txt`, one per line.
20
+ 2. **The agent withdraws them to itself.** `zhield_redeem` builds the zero-knowledge proof on your machine and withdraws through the relayer, which pays the gas, so the agent's wallet needs no ETH to start. It waits for good cover first: 10+ approved deposits in the pool and 3+ after yours.
21
+ 3. **It works with its own wallet.** Whatever it pays for, nothing on-chain points back to your main wallet.
22
+ 4. **It can send funds back privately.** `zhield_shield` deposits from the agent wallet as fixed-size notes and leaves them in `outbox.txt` for you to unshield wherever you like.
23
+
24
+ ## Tools
25
+
26
+ | Tool | What it does |
27
+ |---|---|
28
+ | `zhield_wallet` | The agent's address, ETH balance, and every inbox and outbox note by id, with its state and cover. Read only. |
29
+ | `zhield_pools` | The 0.001, 0.01 and 0.1 ETH pools: deposits, approved deposits, whether a withdrawal would have good cover. Read only. |
30
+ | `zhield_redeem` | Withdraws ready inbox notes to the agent. `ids` to pick some; `force` to skip the cover wait. |
31
+ | `zhield_shield` | Shields an amount from the agent wallet, split into pool sizes, notes to the outbox. Capped per call. |
32
+ | `zhield_send` | Sends ETH from the agent wallet. Capped per call. |
33
+
34
+ ## Settings
35
+
36
+ | Variable | Default | |
37
+ |---|---|---|
38
+ | `ZHIELD_AGENT_HOME` | `~/.zhield-agent` | The folder with the key and the note files. |
39
+ | `ZHIELD_AGENT_MAX_SHIELD` | `0.5` | Most ETH one `zhield_shield` call may deposit. |
40
+ | `ZHIELD_AGENT_MAX_SEND` | `0.05` | Most ETH one `zhield_send` call may transfer. |
41
+ | `ZHIELD_AGENT_RPC` | Robinhood Chain public RPC | |
42
+ | `ZHIELD_AGENT_RELAYER` | `https://zhield.cash/api/relay` | `none` makes the agent pay withdrawal gas itself. |
43
+ | `ZHIELD_AGENT_ARTIFACTS` | fetched from zhield.cash | A folder with `withdraw.wasm` and `withdraw.zkey`. |
44
+
45
+ ## Safety
46
+
47
+ - `~/.zhield-agent/key` **is** the agent's wallet. Back it up, and never paste it into a chat.
48
+ - Keep the agent's balance to what it needs. The per-call caps limit a single mistake, not a determined one.
49
+ - Most MCP clients ask before running a tool that spends; leave that on for `zhield_shield` and `zhield_send`.
50
+ - A note in `inbox.txt` can be withdrawn by whoever reads that file. Keep the folder on a machine you trust.
51
+
52
+ ## Tests
53
+
54
+ ```bash
55
+ npm test # offline: the folder, the key, the note files
56
+ npm run test:fork # end to end through a real MCP client on an anvil fork of mainnet
57
+ ```
58
+
59
+ ```bash
60
+ anvil --fork-url https://rpc.mainnet.chain.robinhood.com --chain-id 4663
61
+ ```
62
+
63
+ ## License
64
+
65
+ MIT
@@ -0,0 +1,105 @@
1
+ import { Zhield } from "@zhieldcash/sdk";
2
+ import { type Home } from "./store.js";
3
+ export type AgentOptions = {
4
+ /** Folder with the key and the note files (default ~/.zhield-agent or ZHIELD_AGENT_HOME). */
5
+ home?: string;
6
+ rpcUrl?: string;
7
+ /** null turns the relayer off; then the agent pays withdrawal gas itself. */
8
+ relayerUrl?: string | null;
9
+ /** A folder with withdraw.wasm (or withdraw_js/withdraw.wasm) and withdraw.zkey, instead of fetching them. */
10
+ artifactsDir?: string;
11
+ /** Most ETH one shield call may deposit (default 0.5). */
12
+ maxShieldEth?: string;
13
+ /** Most ETH one send call may transfer (default 0.05). */
14
+ maxSendEth?: string;
15
+ };
16
+ export type NoteState = "not deposited" | "screening" | "ready" | "spent";
17
+ export type NoteInfo = {
18
+ id: string;
19
+ pool: string;
20
+ state: NoteState;
21
+ cover?: {
22
+ crowd: number;
23
+ after: number;
24
+ good: boolean;
25
+ };
26
+ };
27
+ /** Good cover, as in the app: enough approved deposits to hide among and a few after this one. */
28
+ export declare const COVER: {
29
+ readonly crowd: 10;
30
+ readonly after: 3;
31
+ };
32
+ export declare function optionsFromEnv(): AgentOptions;
33
+ export declare class Agent {
34
+ readonly h: Home;
35
+ readonly address: `0x${string}`;
36
+ readonly z: Zhield;
37
+ private readonly wallet;
38
+ private readonly limits;
39
+ private cache;
40
+ private constructor();
41
+ static open(o?: AgentOptions): Promise<Agent>;
42
+ close(): Promise<void>;
43
+ balance(): Promise<bigint>;
44
+ private state;
45
+ /** Where a note stands, and how well it would hide if withdrawn now. */
46
+ info(note: string): Promise<NoteInfo>;
47
+ /** The agent's wallet and both note files, by id. */
48
+ overview(): Promise<{
49
+ address: `0x${string}`;
50
+ balanceEth: string;
51
+ chain: string;
52
+ inbox: NoteInfo[];
53
+ outbox: NoteInfo[];
54
+ folder: string;
55
+ }>;
56
+ pools(): Promise<{
57
+ pool: string;
58
+ name: string;
59
+ deposits: number;
60
+ approved: number;
61
+ goodCover: boolean;
62
+ }[]>;
63
+ /**
64
+ * Withdraws ready notes from the inbox to the agent's own address. Without
65
+ * `force`, a note waits until it has good cover.
66
+ */
67
+ redeem(o?: {
68
+ ids?: string[];
69
+ force?: boolean;
70
+ }): Promise<{
71
+ id: string;
72
+ pool: string;
73
+ done: boolean;
74
+ detail: string;
75
+ tx?: string;
76
+ receivedEth?: string;
77
+ via?: string;
78
+ }[]>;
79
+ /**
80
+ * Shields ETH from the agent wallet as fixed-size notes, biggest pool first, and
81
+ * leaves the notes in the outbox for the owner. Returns ids only.
82
+ */
83
+ shield(o: {
84
+ amountEth: string;
85
+ }): Promise<{
86
+ shieldedEth: string;
87
+ keptEth: string;
88
+ notes: {
89
+ id: string;
90
+ pool: string;
91
+ tx: string;
92
+ }[];
93
+ outbox: string;
94
+ }>;
95
+ /** A plain ETH transfer from the agent wallet, capped per call. */
96
+ send(o: {
97
+ to: string;
98
+ amountEth: string;
99
+ }): Promise<{
100
+ tx: `0x${string}`;
101
+ sentEth: string;
102
+ to: string;
103
+ }>;
104
+ }
105
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4C,MAAM,EAA0D,MAAM,iBAAiB,CAAC;AAG3I,OAAO,EAA0D,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAa/F,MAAM,MAAM,YAAY,GAAG;IACzB,6FAA6F;IAC7F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,8GAA8G;IAC9G,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC;AAC1E,MAAM,MAAM,QAAQ,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,CAAC;AAE/H,kGAAkG;AAClG,eAAO,MAAM,KAAK;;;CAAmC,CAAC;AAGtD,wBAAgB,cAAc,IAAI,YAAY,CAU7C;AAgBD,qBAAa,KAAK;IAId,QAAQ,CAAC,CAAC,EAAE,IAAI;IAChB,QAAQ,CAAC,OAAO,EAAE,KAAK,MAAM,EAAE;IAC/B,QAAQ,CAAC,CAAC,EAAE,MAAM;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,OAAO,CAAC,KAAK,CAAyC;IAEtD,OAAO;WAQM,IAAI,CAAC,CAAC,GAAE,YAAiB;IAuBtC,KAAK;IAIC,OAAO;IAIb,OAAO,CAAC,KAAK;IAKb,wEAAwE;IAClE,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAa3C,qDAAqD;IAC/C,QAAQ;;;;;;;;IAUR,KAAK;;;;;;;IAUX;;;OAGG;IACG,MAAM,CAAC,CAAC,GAAE;QAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;YAIjC,MAAM;cAAQ,MAAM;cAAQ,OAAO;gBAAU,MAAM;aAAO,MAAM;sBAAgB,MAAM;cAAQ,MAAM;;IAmC3H;;;OAGG;IACG,MAAM,CAAC,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE;;;;gBAWlB,MAAM;kBAAQ,MAAM;gBAAM,MAAM;;;;IAUnD,mEAAmE;IAC7D,IAAI,CAAC,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;;;;;CAShD"}
package/dist/agent.js ADDED
@@ -0,0 +1,198 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { commitmentOf, parseNote, ROBINHOOD_CHAIN, Zhield, ZhieldError } from "@zhieldcash/sdk";
4
+ import { createWalletClient, defineChain, formatEther, http, parseEther } from "viem";
5
+ import { privateKeyToAccount } from "viem/accounts";
6
+ import { addNotes, home, noteId, readKey, readNotes, writeNotes } from "./store.js";
7
+ /** Good cover, as in the app: enough approved deposits to hide among and a few after this one. */
8
+ export const COVER = { crowd: 10, after: 3 };
9
+ const GAS_MARGIN = parseEther("0.0002");
10
+ export function optionsFromEnv() {
11
+ const e = process.env;
12
+ return {
13
+ home: e.ZHIELD_AGENT_HOME || undefined,
14
+ rpcUrl: e.ZHIELD_AGENT_RPC || undefined,
15
+ relayerUrl: e.ZHIELD_AGENT_RELAYER === "none" ? null : e.ZHIELD_AGENT_RELAYER || undefined,
16
+ artifactsDir: e.ZHIELD_AGENT_ARTIFACTS || undefined,
17
+ maxShieldEth: e.ZHIELD_AGENT_MAX_SHIELD || undefined,
18
+ maxSendEth: e.ZHIELD_AGENT_MAX_SEND || undefined,
19
+ };
20
+ }
21
+ function artifacts(dir) {
22
+ if (!dir)
23
+ return undefined;
24
+ const wasm = [join(dir, "withdraw.wasm"), join(dir, "withdraw_js", "withdraw.wasm")].find((p) => {
25
+ try {
26
+ readFileSync(p, { flag: "r" });
27
+ return true;
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ });
33
+ if (!wasm)
34
+ throw new ZhieldError(`No withdraw.wasm in ${dir}.`);
35
+ return { wasm: readFileSync(wasm), zkey: readFileSync(join(dir, "withdraw.zkey")) };
36
+ }
37
+ export class Agent {
38
+ constructor(h, address, z, wallet, limits) {
39
+ this.h = h;
40
+ this.address = address;
41
+ this.z = z;
42
+ this.wallet = wallet;
43
+ this.limits = limits;
44
+ this.cache = new Map();
45
+ }
46
+ static async open(o = {}) {
47
+ const h = home(o.home);
48
+ const key = readKey(h);
49
+ if (!key)
50
+ throw new ZhieldError(`No agent key in ${h.dir}. Run \`npx @zhieldcash/agent init\` first.`);
51
+ const account = privateKeyToAccount(key);
52
+ const rpcUrl = o.rpcUrl ?? ROBINHOOD_CHAIN.rpcUrl;
53
+ const chain = defineChain({
54
+ id: ROBINHOOD_CHAIN.id,
55
+ name: ROBINHOOD_CHAIN.name,
56
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
57
+ rpcUrls: { default: { http: [rpcUrl] } },
58
+ });
59
+ const wallet = createWalletClient({ account, chain, transport: http(rpcUrl) });
60
+ // The SDK takes any signer with an address and sendTransaction; viem's typed `0x` strings need this adapter.
61
+ const signer = {
62
+ account: { address: account.address },
63
+ sendTransaction: (tx) => wallet.sendTransaction({ to: tx.to, data: tx.data, value: tx.value, account, chain }),
64
+ };
65
+ const z = await Zhield.connect({ rpcUrl, signer, relayerUrl: o.relayerUrl, artifacts: artifacts(o.artifactsDir) });
66
+ return new Agent(h, account.address, z, wallet, { shield: parseEther(o.maxShieldEth ?? "0.5"), send: parseEther(o.maxSendEth ?? "0.05") });
67
+ }
68
+ close() {
69
+ return this.z.close();
70
+ }
71
+ async balance() {
72
+ return BigInt(await this.z.rpc.call("eth_getBalance", [this.address, "latest"]));
73
+ }
74
+ state(pool) {
75
+ if (!this.cache.has(pool.id))
76
+ this.cache.set(pool.id, this.z.poolState(pool));
77
+ return this.cache.get(pool.id);
78
+ }
79
+ /** Where a note stands, and how well it would hide if withdrawn now. */
80
+ async info(note) {
81
+ const n = parseNote(note);
82
+ const pool = this.z.pool(n.pool);
83
+ const [s, st] = await Promise.all([this.state(pool), this.z.status(note)]);
84
+ const base = { id: noteId(note), pool: `${pool.id} ETH` };
85
+ if (st.spent || st.ragequit)
86
+ return { ...base, state: "spent" };
87
+ if (!st.deposited)
88
+ return { ...base, state: "not deposited" };
89
+ const c = commitmentOf(n);
90
+ const after = s.leaves.length - 1 - s.leaves.indexOf(c);
91
+ const cover = { crowd: s.approved.length, after, good: s.approved.length >= COVER.crowd && after >= COVER.after };
92
+ return { ...base, state: st.approved ? "ready" : "screening", cover };
93
+ }
94
+ /** The agent's wallet and both note files, by id. */
95
+ async overview() {
96
+ this.cache.clear();
97
+ const [bal, inbox, outbox] = await Promise.all([
98
+ this.balance(),
99
+ Promise.all(readNotes(this.h.inbox).map((n) => this.info(n))),
100
+ Promise.all(readNotes(this.h.outbox).map((n) => this.info(n))),
101
+ ]);
102
+ return { address: this.address, balanceEth: formatEther(bal), chain: `${ROBINHOOD_CHAIN.name} (${ROBINHOOD_CHAIN.id})`, inbox, outbox, folder: this.h.dir };
103
+ }
104
+ async pools() {
105
+ this.cache.clear();
106
+ return Promise.all(this.z.pools.map(async (p) => {
107
+ const s = await this.state(p);
108
+ return { pool: `${p.id} ETH`, name: p.name, deposits: s.leaves.length, approved: s.approved.length, goodCover: s.approved.length >= COVER.crowd };
109
+ }));
110
+ }
111
+ /**
112
+ * Withdraws ready notes from the inbox to the agent's own address. Without
113
+ * `force`, a note waits until it has good cover.
114
+ */
115
+ async redeem(o = {}) {
116
+ this.cache.clear();
117
+ const inbox = readNotes(this.h.inbox);
118
+ const picked = o.ids?.length ? inbox.filter((n) => o.ids.includes(noteId(n))) : inbox;
119
+ const results = [];
120
+ for (const note of picked) {
121
+ const i = await this.info(note);
122
+ const skip = (detail) => results.push({ id: i.id, pool: i.pool, done: false, detail });
123
+ if (i.state === "spent") {
124
+ addNotes(this.h.spent, [note]);
125
+ writeNotes(this.h.inbox, readNotes(this.h.inbox).filter((n) => n !== note));
126
+ skip("Already spent; moved to spent.txt.");
127
+ continue;
128
+ }
129
+ if (i.state === "not deposited") {
130
+ skip("Not in the pool yet. If the owner just deposited, try again in a moment.");
131
+ continue;
132
+ }
133
+ if (i.state === "screening") {
134
+ skip("Waiting for screening, usually a few minutes.");
135
+ continue;
136
+ }
137
+ if (!o.force && !i.cover?.good) {
138
+ skip(`Cover still building: ${i.cover?.crowd} approved deposits (want ${COVER.crowd}+), ${i.cover?.after} after this one (want ${COVER.after}+). Withdrawing now makes it easier to link. Pass force to withdraw anyway.`);
139
+ continue;
140
+ }
141
+ try {
142
+ const r = await this.z.unshield({ note, to: this.address, relayer: "auto" });
143
+ addNotes(this.h.spent, [note]);
144
+ writeNotes(this.h.inbox, readNotes(this.h.inbox).filter((n) => n !== note));
145
+ results.push({ id: i.id, pool: i.pool, done: true, detail: "Withdrawn to the agent wallet.", tx: r.hash, receivedEth: formatEther(r.received), via: r.via });
146
+ }
147
+ catch (e) {
148
+ skip(e instanceof Error ? e.message : String(e));
149
+ }
150
+ this.cache.clear();
151
+ }
152
+ return results;
153
+ }
154
+ /**
155
+ * Shields ETH from the agent wallet as fixed-size notes, biggest pool first, and
156
+ * leaves the notes in the outbox for the owner. Returns ids only.
157
+ */
158
+ async shield(o) {
159
+ const wei = parseEther(o.amountEth);
160
+ if (wei <= 0n)
161
+ throw new ZhieldError("The amount must be above zero.");
162
+ if (wei > this.limits.shield)
163
+ throw new ZhieldError(`Above this agent's shield limit of ${formatEther(this.limits.shield)} ETH per call (ZHIELD_AGENT_MAX_SHIELD).`);
164
+ const pools = [...this.z.pools].sort((a, b) => (b.wei > a.wei ? 1 : -1));
165
+ let rest = wei;
166
+ const plan = [];
167
+ for (const p of pools)
168
+ while (rest >= p.wei)
169
+ (plan.push(p), (rest -= p.wei));
170
+ if (!plan.length)
171
+ throw new ZhieldError(`The smallest pool is ${formatEther(pools[pools.length - 1].wei)} ETH.`);
172
+ const total = wei - rest;
173
+ if ((await this.balance()) < total + GAS_MARGIN)
174
+ throw new ZhieldError(`The agent wallet holds less than ${formatEther(total)} ETH plus gas.`);
175
+ const out = [];
176
+ for (const p of plan) {
177
+ const r = await this.z.shield({ pool: p.id });
178
+ // Saved at once, so a later failure never loses a note that already went in.
179
+ addNotes(this.h.outbox, [r.note]);
180
+ out.push({ id: noteId(r.note), pool: `${p.id} ETH`, tx: r.hash });
181
+ }
182
+ return { shieldedEth: formatEther(total), keptEth: formatEther(rest), notes: out, outbox: this.h.outbox };
183
+ }
184
+ /** A plain ETH transfer from the agent wallet, capped per call. */
185
+ async send(o) {
186
+ if (!/^0x[0-9a-fA-F]{40}$/.test(o.to))
187
+ throw new ZhieldError("`to` must be an address: 0x followed by 40 hex characters.");
188
+ const wei = parseEther(o.amountEth);
189
+ if (wei <= 0n)
190
+ throw new ZhieldError("The amount must be above zero.");
191
+ if (wei > this.limits.send)
192
+ throw new ZhieldError(`Above this agent's send limit of ${formatEther(this.limits.send)} ETH per call (ZHIELD_AGENT_MAX_SEND).`);
193
+ const hash = await this.wallet.sendTransaction({ to: o.to, value: wei, account: this.wallet.account, chain: this.wallet.chain });
194
+ await this.z.rpc.waitForReceipt(hash);
195
+ return { tx: hash, sentEth: formatEther(wei), to: o.to };
196
+ }
197
+ }
198
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ import { privateKeyToAccount } from "viem/accounts";
3
+ import { home, init, readKey } from "./store.js";
4
+ /*
5
+ zhield-agent init make the agent folder and wallet key, print the MCP config
6
+ zhield-agent address print the agent wallet's address
7
+ zhield-agent run the MCP server on stdio (what an MCP client starts)
8
+ */
9
+ const HELP = `zhield-agent: a shielded wallet for AI agents (MCP server)
10
+
11
+ npx @zhieldcash/agent init create the agent wallet and folder, print the config
12
+ npx @zhieldcash/agent address print the agent's address
13
+ npx @zhieldcash/agent run the MCP server (your MCP client starts this)
14
+
15
+ Environment: ZHIELD_AGENT_HOME, ZHIELD_AGENT_RPC, ZHIELD_AGENT_RELAYER (url or "none"),
16
+ ZHIELD_AGENT_MAX_SHIELD (default 0.5 ETH), ZHIELD_AGENT_MAX_SEND (default 0.05 ETH).
17
+ Docs: https://zhield.cash/docs#agents`;
18
+ const cmd = process.argv[2];
19
+ const h = home();
20
+ if (cmd === "init") {
21
+ const { created } = init(h);
22
+ const address = privateKeyToAccount(readKey(h)).address;
23
+ console.log(`${created ? "Created" : "Already set up"}: ${h.dir}
24
+
25
+ Agent address ${address}
26
+ Inbox ${h.inbox}
27
+ Outbox ${h.outbox}
28
+
29
+ Fund it privately: shield ETH at zhield.cash/app and paste the notes into inbox.txt,
30
+ one per line. The agent withdraws them to its own address through the relayer, so it
31
+ needs no ETH to start and nothing on-chain links it to your wallet.
32
+
33
+ The key file is the agent's wallet. Back it up and never paste it into a chat.
34
+
35
+ Add to your MCP client (Claude Desktop, Claude Code, Cursor):
36
+ ${JSON.stringify({ mcpServers: { zhield: { command: "npx", args: ["-y", "@zhieldcash/agent"] } } }, null, 2)}`);
37
+ }
38
+ else if (cmd === "address") {
39
+ const k = readKey(h);
40
+ if (!k) {
41
+ console.error(`No agent key in ${h.dir}. Run: npx @zhieldcash/agent init`);
42
+ process.exit(1);
43
+ }
44
+ console.log(privateKeyToAccount(k).address);
45
+ }
46
+ else if (cmd === "help" || cmd === "--help" || cmd === "-h") {
47
+ console.log(HELP);
48
+ }
49
+ else if (!cmd || cmd === "serve") {
50
+ const { serve } = await import("./server.js");
51
+ serve().catch((e) => {
52
+ console.error(e instanceof Error ? e.message : e);
53
+ process.exit(1);
54
+ });
55
+ }
56
+ else {
57
+ console.error(`Unknown command "${cmd}".\n\n${HELP}`);
58
+ process.exit(1);
59
+ }
60
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;EAIE;AAEF,MAAM,IAAI,GAAG;;;;;;;;sCAQyB,CAAC;AAEvC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC5B,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;AAEjB,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,OAAO,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,KAAK,CAAC,CAAC,GAAG;;iBAEhD,OAAO;iBACP,CAAC,CAAC,KAAK;iBACP,CAAC,CAAC,MAAM;;;;;;;;;EASvB,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AAChH,CAAC;KAAM,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;IAC7B,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,GAAG,mCAAmC,CAAC,CAAC;QAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC9C,CAAC;KAAM,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;KAAM,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;IACnC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IAC9C,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;QAClB,OAAO,CAAC,KAAK,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,KAAK,CAAC,oBAAoB,GAAG,SAAS,IAAI,EAAE,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function serve(): Promise<void>;
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAeA,wBAAsB,KAAK,kBAuF1B"}
package/dist/server.js ADDED
@@ -0,0 +1,68 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { z } from "zod";
4
+ import { Agent, COVER, optionsFromEnv } from "./agent.js";
5
+ /*
6
+ The MCP server: five tools over stdio. Results are JSON text. No tool ever
7
+ returns a note or the key; notes move through the files in the agent folder.
8
+ */
9
+ const VERSION = "0.1.0";
10
+ const ok = (v) => ({ content: [{ type: "text", text: JSON.stringify(v, null, 2) }] });
11
+ const fail = (e) => ({ isError: true, content: [{ type: "text", text: e instanceof Error ? e.message : String(e) }] });
12
+ export async function serve() {
13
+ const agent = await Agent.open(optionsFromEnv());
14
+ const server = new McpServer({ name: "zhield-agent", version: VERSION }, {
15
+ instructions: "A shielded wallet on Robinhood Chain, funded through Zhield Cash so nothing on-chain links it to its owner. " +
16
+ "Notes and the key never appear in tool results; notes are referred to by id. " +
17
+ "The owner funds the agent by putting notes in inbox.txt; zhield_redeem withdraws them to the agent's own address. " +
18
+ "zhield_shield sends ETH back privately as notes in outbox.txt for the owner. Ask before spending.",
19
+ });
20
+ const run = (fn) => fn().then(ok, fail);
21
+ server.registerTool("zhield_wallet", {
22
+ title: "Agent wallet",
23
+ description: "The agent's own address and ETH balance on Robinhood Chain, plus every note in its inbox (from the owner) and outbox (for the owner) with its state and cover. Notes are shown by id only.",
24
+ annotations: { readOnlyHint: true },
25
+ }, () => run(() => agent.overview()));
26
+ server.registerTool("zhield_pools", {
27
+ title: "Zhield pools",
28
+ description: `The three fixed-size pools (0.001, 0.01 and 0.1 ETH): deposits, approved deposits, and whether a withdrawal from each would have good cover (${COVER.crowd}+ approved deposits).`,
29
+ annotations: { readOnlyHint: true },
30
+ }, () => run(() => agent.pools()));
31
+ server.registerTool("zhield_redeem", {
32
+ title: "Withdraw notes to the agent",
33
+ description: "Withdraws ready notes from the inbox to the agent's own address, through the relayer (it pays the gas, so the agent needs no ETH first). " +
34
+ `By default a note waits for good cover: ${COVER.crowd}+ approved deposits and ${COVER.after}+ after it. A proof is built locally; this takes a few seconds per note.`,
35
+ inputSchema: {
36
+ ids: z.array(z.string()).optional().describe("Only these note ids; default every note in the inbox."),
37
+ force: z.boolean().optional().describe("Withdraw even without good cover. Easier to link; only when the owner asks."),
38
+ },
39
+ annotations: { destructiveHint: false, openWorldHint: true },
40
+ }, (a) => run(() => agent.redeem(a)));
41
+ server.registerTool("zhield_shield", {
42
+ title: "Shield ETH for the owner",
43
+ description: "Deposits ETH from the agent wallet into the pools as fixed-size notes, biggest first (0.25 becomes 2 × 0.1 + 5 × 0.01), and saves the notes to outbox.txt for the owner. " +
44
+ "Returns ids and transactions only. Capped per call. Spends funds: confirm with the user first.",
45
+ inputSchema: { amountEth: z.string().describe('Amount in ETH, e.g. "0.25".') },
46
+ annotations: { destructiveHint: true, openWorldHint: true },
47
+ }, (a) => run(() => agent.shield(a)));
48
+ server.registerTool("zhield_send", {
49
+ title: "Send ETH",
50
+ description: "Sends ETH from the agent wallet to an address, capped per call. Spends funds: confirm the address and amount with the user first.",
51
+ inputSchema: {
52
+ to: z.string().describe("0x address"),
53
+ amountEth: z.string().describe('Amount in ETH, e.g. "0.01".'),
54
+ },
55
+ annotations: { destructiveHint: true, openWorldHint: true },
56
+ }, (a) => run(() => agent.send(a)));
57
+ const transport = new StdioServerTransport();
58
+ await server.connect(transport);
59
+ const stop = async () => {
60
+ await agent.close();
61
+ process.exit(0);
62
+ };
63
+ process.on("SIGINT", stop);
64
+ process.on("SIGTERM", stop);
65
+ // stdout belongs to the protocol; status goes to stderr.
66
+ console.error(`zhield-agent ${VERSION}: ${agent.address} on Robinhood Chain`);
67
+ }
68
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export type Home = {
2
+ dir: string;
3
+ key: string;
4
+ inbox: string;
5
+ outbox: string;
6
+ spent: string;
7
+ };
8
+ export declare function home(dir?: string): Home;
9
+ /** A note's public handle: enough to tell notes apart, useless for withdrawing. */
10
+ export declare const noteId: (note: string) => string;
11
+ /** The valid notes in a file, once each, in order. */
12
+ export declare function readNotes(file: string): string[];
13
+ export declare function writeNotes(file: string, notes: string[]): void;
14
+ export declare function addNotes(file: string, notes: string[]): void;
15
+ export declare function readKey(h: Home): `0x${string}` | null;
16
+ /** Makes the folder and a key if there is none yet; never replaces an existing key. */
17
+ export declare function init(h: Home): {
18
+ created: boolean;
19
+ };
20
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,IAAI,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9F,wBAAgB,IAAI,CAAC,GAAG,SAAoE,GAAG,IAAI,CAElG;AAED,mFAAmF;AACnF,eAAO,MAAM,MAAM,GAAI,MAAM,MAAM,WAAsF,CAAC;AAE1H,sDAAsD;AACtD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAQhD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAEvD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAErD;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,GAAG,KAAK,MAAM,EAAE,GAAG,IAAI,CAIrD;AAED,uFAAuF;AACvF,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI;;EAY3B"}
package/dist/store.js ADDED
@@ -0,0 +1,53 @@
1
+ import { createHash } from "node:crypto";
2
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { parseNote } from "@zhieldcash/sdk";
6
+ import { generatePrivateKey } from "viem/accounts";
7
+ export function home(dir = process.env.ZHIELD_AGENT_HOME || join(homedir(), ".zhield-agent")) {
8
+ return { dir, key: join(dir, "key"), inbox: join(dir, "inbox.txt"), outbox: join(dir, "outbox.txt"), spent: join(dir, "spent.txt") };
9
+ }
10
+ /** A note's public handle: enough to tell notes apart, useless for withdrawing. */
11
+ export const noteId = (note) => createHash("sha256").update(note.trim().toLowerCase()).digest("hex").slice(0, 10);
12
+ /** The valid notes in a file, once each, in order. */
13
+ export function readNotes(file) {
14
+ if (!existsSync(file))
15
+ return [];
16
+ const seen = new Set();
17
+ for (const line of readFileSync(file, "utf8").split(/\r?\n/)) {
18
+ const n = line.trim().toLowerCase();
19
+ if (parseNote(n) && !seen.has(n))
20
+ seen.add(n);
21
+ }
22
+ return [...seen];
23
+ }
24
+ export function writeNotes(file, notes) {
25
+ writeFileSync(file, notes.length ? notes.join("\n") + "\n" : "", { mode: 0o600 });
26
+ }
27
+ export function addNotes(file, notes) {
28
+ writeNotes(file, [...new Set([...readNotes(file), ...notes])]);
29
+ }
30
+ export function readKey(h) {
31
+ if (!existsSync(h.key))
32
+ return null;
33
+ const k = readFileSync(h.key, "utf8").trim();
34
+ return /^0x[0-9a-fA-F]{64}$/.test(k) ? k : null;
35
+ }
36
+ /** Makes the folder and a key if there is none yet; never replaces an existing key. */
37
+ export function init(h) {
38
+ mkdirSync(h.dir, { recursive: true, mode: 0o700 });
39
+ let created = false;
40
+ if (!readKey(h)) {
41
+ writeFileSync(h.key, generatePrivateKey() + "\n", { mode: 0o600 });
42
+ created = true;
43
+ }
44
+ try {
45
+ chmodSync(h.key, 0o600);
46
+ }
47
+ catch { }
48
+ for (const f of [h.inbox, h.outbox, h.spent])
49
+ if (!existsSync(f))
50
+ writeNotes(f, []);
51
+ return { created };
52
+ }
53
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,53 @@
1
1
  {
2
2
  "name": "@zhieldcash/agent",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "A shielded wallet for AI agents: an MCP server that funds an agent through Zhield Cash on Robinhood Chain, so nothing on-chain links it to its owner. The model never sees a note or a key.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "zhield-agent": "dist/cli.js"
9
+ },
10
+ "main": "./dist/agent.js",
11
+ "types": "./dist/agent.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/agent.d.ts",
15
+ "import": "./dist/agent.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "keywords": [
27
+ "zhield",
28
+ "mcp",
29
+ "model context protocol",
30
+ "ai agent",
31
+ "agent wallet",
32
+ "privacy",
33
+ "robinhood chain"
34
+ ],
35
+ "homepage": "https://zhield.cash/docs#agents",
36
+ "scripts": {
37
+ "build": "tsc -p tsconfig.json",
38
+ "typecheck": "tsc -p tsconfig.json --noEmit",
39
+ "test": "node --test test/unit.test.mjs",
40
+ "test:fork": "node test/fork.mjs",
41
+ "prepublishOnly": "npm run build && npm test"
42
+ },
43
+ "dependencies": {
44
+ "@modelcontextprotocol/sdk": "1.32.1",
45
+ "@zhieldcash/sdk": "^0.1.0",
46
+ "viem": "2.57.4",
47
+ "zod": "^4.1.0"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20",
51
+ "typescript": "^5"
52
+ }
53
+ }