@agenc/sdk 1.0.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.mjs ADDED
@@ -0,0 +1,372 @@
1
+ import {
2
+ DEVNET_RPC,
3
+ MAINNET_RPC,
4
+ PRIVACY_CASH_PROGRAM_ID,
5
+ PROGRAM_ID,
6
+ TaskState,
7
+ VERIFIER_PROGRAM_ID,
8
+ claimTask,
9
+ completeTask,
10
+ completeTaskPrivate,
11
+ createTask,
12
+ generateProof,
13
+ getTask,
14
+ verifyProofLocally
15
+ } from "./chunk-QRZGQS77.mjs";
16
+
17
+ // src/client.ts
18
+ import { Connection as Connection2, LAMPORTS_PER_SOL as LAMPORTS_PER_SOL2 } from "@solana/web3.js";
19
+ import { AnchorProvider, Wallet } from "@coral-xyz/anchor";
20
+
21
+ // src/privacy.ts
22
+ import { PublicKey, Transaction, LAMPORTS_PER_SOL } from "@solana/web3.js";
23
+ import * as fs from "fs";
24
+ import * as path from "path";
25
+ import { execSync } from "child_process";
26
+ var AgenCPrivacyClient = class {
27
+ connection;
28
+ program;
29
+ circuitPath;
30
+ privacyCash = null;
31
+ rpcUrl;
32
+ constructor(connection, program, circuitPath = "./circuits/task_completion", rpcUrl) {
33
+ this.connection = connection;
34
+ this.program = program;
35
+ this.circuitPath = circuitPath;
36
+ this.rpcUrl = rpcUrl || connection.rpcEndpoint;
37
+ }
38
+ /**
39
+ * Set Privacy Cash client instance
40
+ * Users should create their own Privacy Cash instance and pass it here
41
+ */
42
+ setPrivacyCash(privacyCash) {
43
+ this.privacyCash = privacyCash;
44
+ console.log("Privacy Cash client set for:", privacyCash.publicKey.toBase58());
45
+ }
46
+ /**
47
+ * Initialize Privacy Cash client for a specific wallet
48
+ * Requires privacycash package to be installed separately
49
+ */
50
+ async initPrivacyCash(owner) {
51
+ try {
52
+ const { PrivacyCash } = await import("privacycash");
53
+ this.privacyCash = new PrivacyCash({
54
+ RPC_url: this.rpcUrl,
55
+ owner,
56
+ enableDebug: true
57
+ });
58
+ console.log("Privacy Cash client initialized for:", owner.publicKey.toBase58());
59
+ } catch (error) {
60
+ console.warn("Privacy Cash SDK not available. Install with: npm install privacycash");
61
+ console.warn("Or use setPrivacyCash() to provide your own instance.");
62
+ }
63
+ }
64
+ /**
65
+ * Check if Privacy Cash is initialized
66
+ */
67
+ hasPrivacyCash() {
68
+ return this.privacyCash !== null;
69
+ }
70
+ /**
71
+ * Shield escrow funds into Privacy Cash pool
72
+ * Called by task creator when creating a private task
73
+ */
74
+ async shieldEscrow(creator, lamports) {
75
+ if (!this.privacyCash) {
76
+ await this.initPrivacyCash(creator);
77
+ }
78
+ if (!this.privacyCash) {
79
+ throw new Error("Privacy Cash not available. Install privacycash or use setPrivacyCash().");
80
+ }
81
+ console.log(`Shielding ${lamports / LAMPORTS_PER_SOL} SOL into privacy pool...`);
82
+ const result = await this.privacyCash.deposit({ lamports });
83
+ console.log("Escrow shielded successfully");
84
+ return {
85
+ txSignature: result?.signature || result?.tx || "deposited",
86
+ shieldedAmount: lamports
87
+ };
88
+ }
89
+ /**
90
+ * Get shielded balance for current wallet
91
+ */
92
+ async getShieldedBalance() {
93
+ if (!this.privacyCash) {
94
+ throw new Error("Privacy Cash not initialized. Call initPrivacyCash first.");
95
+ }
96
+ return await this.privacyCash.getPrivateBalance();
97
+ }
98
+ /**
99
+ * Complete a task privately using ZK proofs and Privacy Cash withdrawal
100
+ *
101
+ * Flow:
102
+ * 1. Generate ZK proof that worker completed task correctly (Noir/Sunspot)
103
+ * 2. Submit proof on-chain for verification
104
+ * 3. Upon verification, withdraw shielded escrow to worker via Privacy Cash
105
+ */
106
+ async completeTaskPrivate(params, worker) {
107
+ const { taskId, output, salt, recipientWallet, escrowLamports } = params;
108
+ await this.initPrivacyCash(worker);
109
+ const task = await this.fetchTask(taskId);
110
+ const constraintHash = task.constraintHash;
111
+ const outputCommitment = await this.computeCommitment(output, salt);
112
+ console.log("Step 1/3: Generating ZK proof of task completion...");
113
+ const { zkProof, publicWitness } = await this.generateTaskCompletionProof({
114
+ taskId,
115
+ agentPubkey: worker.publicKey,
116
+ constraintHash,
117
+ outputCommitment,
118
+ output,
119
+ salt
120
+ });
121
+ console.log("ZK proof generated:", zkProof.length, "bytes");
122
+ console.log("Step 2/3: Submitting proof to on-chain verifier...");
123
+ const tx = await this.buildCompleteTaskPrivateTx({
124
+ taskId,
125
+ zkProof,
126
+ publicWitness,
127
+ worker: worker.publicKey
128
+ });
129
+ const proofTxSignature = await this.connection.sendTransaction(tx, [worker]);
130
+ await this.connection.confirmTransaction(proofTxSignature);
131
+ console.log("Proof verified on-chain:", proofTxSignature);
132
+ console.log("Step 3/3: Withdrawing shielded escrow via Privacy Cash...");
133
+ if (!this.privacyCash) {
134
+ throw new Error("Privacy Cash not initialized");
135
+ }
136
+ const withdrawResult = await this.privacyCash.withdraw({
137
+ lamports: escrowLamports,
138
+ recipientAddress: recipientWallet.toBase58()
139
+ });
140
+ console.log("Private payment completed!");
141
+ return {
142
+ proofTxSignature,
143
+ withdrawResult
144
+ };
145
+ }
146
+ /**
147
+ * Generate ZK proof for task completion using Noir/Sunspot
148
+ */
149
+ async generateTaskCompletionProof(params) {
150
+ const { taskId, agentPubkey, constraintHash, outputCommitment, output, salt } = params;
151
+ const proverToml = this.generateProverToml({
152
+ taskId,
153
+ agentPubkey: Array.from(agentPubkey.toBytes()),
154
+ constraintHash: "0x" + constraintHash.toString("hex"),
155
+ outputCommitment: "0x" + outputCommitment.toString(16),
156
+ output: output.map((o) => o.toString()),
157
+ salt: salt.toString()
158
+ });
159
+ const proverPath = path.join(this.circuitPath, "Prover.toml");
160
+ fs.writeFileSync(proverPath, proverToml);
161
+ execSync("nargo execute", { cwd: this.circuitPath });
162
+ execSync(
163
+ "sunspot prove target/task_completion.ccs target/task_completion.pk target/task_completion.gz -o target/task_completion.proof",
164
+ { cwd: this.circuitPath }
165
+ );
166
+ const zkProof = fs.readFileSync(
167
+ path.join(this.circuitPath, "target/task_completion.proof")
168
+ );
169
+ const publicWitness = fs.readFileSync(
170
+ path.join(this.circuitPath, "target/task_completion.pw")
171
+ );
172
+ return { zkProof, publicWitness };
173
+ }
174
+ /**
175
+ * Build the complete_task_private transaction
176
+ * This submits the ZK proof for on-chain verification
177
+ */
178
+ async buildCompleteTaskPrivateTx(params) {
179
+ const { taskId, zkProof, publicWitness, worker } = params;
180
+ if (!this.program) {
181
+ throw new Error("Program not initialized");
182
+ }
183
+ const [taskPda] = PublicKey.findProgramAddressSync(
184
+ [Buffer.from("task"), Buffer.from(new Uint8Array(new BigUint64Array([BigInt(taskId)]).buffer))],
185
+ this.program.programId
186
+ );
187
+ const [claimPda] = PublicKey.findProgramAddressSync(
188
+ [Buffer.from("claim"), taskPda.toBuffer(), worker.toBuffer()],
189
+ this.program.programId
190
+ );
191
+ const verifierProgramId = await this.getVerifierProgramId();
192
+ const ix = await this.program.methods.completeTaskPrivate(taskId, {
193
+ zkProof: Array.from(zkProof),
194
+ publicWitness: Array.from(publicWitness)
195
+ }).accounts({
196
+ worker,
197
+ task: taskPda,
198
+ taskClaim: claimPda,
199
+ zkVerifier: verifierProgramId,
200
+ systemProgram: PublicKey.default
201
+ }).instruction();
202
+ const tx = new Transaction().add(ix);
203
+ tx.feePayer = worker;
204
+ tx.recentBlockhash = (await this.connection.getLatestBlockhash()).blockhash;
205
+ return tx;
206
+ }
207
+ /**
208
+ * Compute Poseidon commitment for output
209
+ */
210
+ async computeCommitment(output, salt) {
211
+ console.log("Computing commitment...");
212
+ return BigInt(0);
213
+ }
214
+ /**
215
+ * Generate Prover.toml content
216
+ */
217
+ generateProverToml(params) {
218
+ return `# Auto-generated Prover.toml
219
+ task_id = "${params.taskId}"
220
+ agent_pubkey = [${params.agentPubkey.join(", ")}]
221
+ constraint_hash = "${params.constraintHash}"
222
+ output_commitment = "${params.outputCommitment}"
223
+ output = [${params.output.map((o) => `"${o}"`).join(", ")}]
224
+ salt = "${params.salt}"
225
+ `;
226
+ }
227
+ async fetchTask(taskId) {
228
+ if (!this.program) {
229
+ throw new Error("Program not initialized");
230
+ }
231
+ const [taskPda] = PublicKey.findProgramAddressSync(
232
+ [Buffer.from("task"), Buffer.from(new Uint8Array(new BigUint64Array([BigInt(taskId)]).buffer))],
233
+ this.program.programId
234
+ );
235
+ return await this.program.account.task.fetch(taskPda);
236
+ }
237
+ async getVerifierProgramId() {
238
+ return new PublicKey("8fHUGmjNzSh76r78v1rPt7BhWmAu2gXrvW9A2XXonwQQ");
239
+ }
240
+ };
241
+
242
+ // src/client.ts
243
+ var PrivacyClient = class {
244
+ connection;
245
+ program = null;
246
+ privacyClient = null;
247
+ config;
248
+ wallet = null;
249
+ constructor(config = {}) {
250
+ this.config = {
251
+ devnet: false,
252
+ circuitPath: "./circuits/task_completion",
253
+ debug: false,
254
+ ...config
255
+ };
256
+ const rpcUrl = config.rpcUrl || (this.config.devnet ? DEVNET_RPC : MAINNET_RPC);
257
+ this.connection = new Connection2(rpcUrl, "confirmed");
258
+ if (config.wallet) {
259
+ this.wallet = config.wallet;
260
+ }
261
+ if (this.config.debug) {
262
+ console.log("PrivacyClient initialized");
263
+ console.log(" RPC:", rpcUrl);
264
+ console.log(" Circuit:", this.config.circuitPath);
265
+ }
266
+ }
267
+ /**
268
+ * Initialize the client with a wallet
269
+ */
270
+ async init(wallet) {
271
+ this.wallet = wallet;
272
+ const anchorWallet = new Wallet(wallet);
273
+ const provider = new AnchorProvider(
274
+ this.connection,
275
+ anchorWallet,
276
+ { commitment: "confirmed" }
277
+ );
278
+ if (this.config.debug) {
279
+ console.log("Wallet initialized:", wallet.publicKey.toBase58());
280
+ }
281
+ this.privacyClient = new AgenCPrivacyClient(
282
+ this.connection,
283
+ this.program,
284
+ this.config.circuitPath,
285
+ this.connection.rpcEndpoint
286
+ );
287
+ await this.privacyClient.initPrivacyCash(wallet);
288
+ }
289
+ /**
290
+ * Get connection instance
291
+ */
292
+ getConnection() {
293
+ return this.connection;
294
+ }
295
+ /**
296
+ * Get wallet public key
297
+ */
298
+ getPublicKey() {
299
+ return this.wallet?.publicKey || null;
300
+ }
301
+ /**
302
+ * Shield SOL into the privacy pool
303
+ */
304
+ async shield(lamports) {
305
+ if (!this.wallet || !this.privacyClient) {
306
+ throw new Error("Client not initialized. Call init() first.");
307
+ }
308
+ const result = await this.privacyClient.shieldEscrow(this.wallet, lamports);
309
+ return {
310
+ txSignature: result.txSignature,
311
+ amount: result.shieldedAmount
312
+ };
313
+ }
314
+ /**
315
+ * Get shielded balance
316
+ */
317
+ async getShieldedBalance() {
318
+ if (!this.privacyClient) {
319
+ throw new Error("Client not initialized. Call init() first.");
320
+ }
321
+ const { lamports } = await this.privacyClient.getShieldedBalance();
322
+ return lamports;
323
+ }
324
+ /**
325
+ * Complete a task privately with ZK proof
326
+ */
327
+ async completeTaskPrivate(params) {
328
+ if (!this.wallet || !this.privacyClient) {
329
+ throw new Error("Client not initialized. Call init() first.");
330
+ }
331
+ return await this.privacyClient.completeTaskPrivate(params, this.wallet);
332
+ }
333
+ /**
334
+ * Get the underlying AgenCPrivacyClient for advanced operations
335
+ */
336
+ getPrivacyClient() {
337
+ return this.privacyClient;
338
+ }
339
+ /**
340
+ * Format lamports as SOL string
341
+ */
342
+ static formatSol(lamports) {
343
+ return (lamports / LAMPORTS_PER_SOL2).toFixed(9) + " SOL";
344
+ }
345
+ /**
346
+ * Parse SOL string to lamports
347
+ */
348
+ static parseSol(sol) {
349
+ const value = typeof sol === "string" ? parseFloat(sol) : sol;
350
+ return Math.floor(value * LAMPORTS_PER_SOL2);
351
+ }
352
+ };
353
+
354
+ // src/index.ts
355
+ var VERSION = "1.0.0";
356
+ export {
357
+ DEVNET_RPC,
358
+ MAINNET_RPC,
359
+ PRIVACY_CASH_PROGRAM_ID,
360
+ PROGRAM_ID,
361
+ PrivacyClient,
362
+ TaskState,
363
+ VERIFIER_PROGRAM_ID,
364
+ VERSION,
365
+ claimTask,
366
+ completeTask,
367
+ completeTaskPrivate,
368
+ createTask,
369
+ generateProof,
370
+ getTask,
371
+ verifyProofLocally
372
+ };
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@agenc/sdk",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript SDK for AgenC - Privacy-preserving agent coordination on Solana",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.mjs",
10
+ "require": "./dist/index.js"
11
+ }
12
+ },
13
+ "bin": {
14
+ "agenc": "./dist/bin/agenc.js"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsup src/index.ts src/bin/agenc.ts --format cjs,esm --clean --external privacycash",
22
+ "prepublishOnly": "npm run build",
23
+ "typecheck": "tsc --noEmit"
24
+ },
25
+ "keywords": [
26
+ "solana",
27
+ "privacy",
28
+ "zk",
29
+ "zero-knowledge",
30
+ "noir",
31
+ "agents",
32
+ "coordination",
33
+ "escrow",
34
+ "privacy-cash"
35
+ ],
36
+ "author": "Tetsuo AI",
37
+ "license": "MIT",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/tetsuo-ai/AgenC"
41
+ },
42
+ "homepage": "https://github.com/tetsuo-ai/AgenC#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/tetsuo-ai/AgenC/issues"
45
+ },
46
+ "dependencies": {
47
+ "@coral-xyz/anchor": "^0.30.1",
48
+ "@solana/web3.js": "^1.95.0",
49
+ "chalk": "^5.3.0",
50
+ "commander": "^12.0.0",
51
+ "ora": "^8.0.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^20.0.0",
55
+ "tsup": "^8.0.0",
56
+ "typescript": "^5.0.0"
57
+ },
58
+ "peerDependencies": {
59
+ "@coral-xyz/anchor": ">=0.29.0",
60
+ "@solana/web3.js": ">=1.90.0"
61
+ },
62
+ "engines": {
63
+ "node": ">=18.0.0"
64
+ }
65
+ }