@agentxv2/sdk 0.3.0 → 0.3.1

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.
Files changed (107) hide show
  1. package/README.md +11 -11
  2. package/dist/core.d.mts +64 -0
  3. package/dist/core.d.ts +64 -0
  4. package/dist/core.js +275 -0
  5. package/dist/core.js.map +1 -0
  6. package/dist/core.mjs +240 -0
  7. package/dist/core.mjs.map +1 -0
  8. package/dist/{agent/agent-runner.d.ts → index-DhXVi_ub.d.ts} +94 -10
  9. package/dist/index-eQO4iaOr.d.mts +208 -0
  10. package/dist/index.d.mts +269 -0
  11. package/dist/index.d.ts +269 -10
  12. package/dist/index.js +2398 -31
  13. package/dist/index.js.map +1 -1
  14. package/dist/index.mjs +2345 -0
  15. package/dist/index.mjs.map +1 -0
  16. package/dist/react.d.mts +3 -0
  17. package/dist/react.d.ts +3 -0
  18. package/dist/react.js +737 -0
  19. package/dist/react.js.map +1 -0
  20. package/dist/react.mjs +717 -0
  21. package/dist/react.mjs.map +1 -0
  22. package/dist/{core/types.d.ts → types-2aHUvS4M.d.mts} +34 -33
  23. package/dist/types-2aHUvS4M.d.ts +297 -0
  24. package/package.json +12 -11
  25. package/dist/a2a/a2a.d.ts +0 -37
  26. package/dist/a2a/a2a.d.ts.map +0 -1
  27. package/dist/a2a/a2a.js +0 -252
  28. package/dist/a2a/a2a.js.map +0 -1
  29. package/dist/a2a/index.d.ts +0 -4
  30. package/dist/a2a/index.d.ts.map +0 -1
  31. package/dist/a2a/index.js +0 -4
  32. package/dist/a2a/index.js.map +0 -1
  33. package/dist/agent/agent-runner.d.ts.map +0 -1
  34. package/dist/agent/agent-runner.js +0 -249
  35. package/dist/agent/agent-runner.js.map +0 -1
  36. package/dist/agent/index.d.ts +0 -3
  37. package/dist/agent/index.d.ts.map +0 -1
  38. package/dist/agent/index.js +0 -3
  39. package/dist/agent/index.js.map +0 -1
  40. package/dist/config/config.d.ts +0 -31
  41. package/dist/config/config.d.ts.map +0 -1
  42. package/dist/config/config.js +0 -95
  43. package/dist/config/config.js.map +0 -1
  44. package/dist/config/index.d.ts +0 -4
  45. package/dist/config/index.d.ts.map +0 -1
  46. package/dist/config/index.js +0 -4
  47. package/dist/config/index.js.map +0 -1
  48. package/dist/core/crypto.d.ts +0 -62
  49. package/dist/core/crypto.d.ts.map +0 -1
  50. package/dist/core/crypto.js +0 -291
  51. package/dist/core/crypto.js.map +0 -1
  52. package/dist/core/index.d.ts +0 -3
  53. package/dist/core/index.d.ts.map +0 -1
  54. package/dist/core/index.js +0 -4
  55. package/dist/core/index.js.map +0 -1
  56. package/dist/core/types.d.ts.map +0 -1
  57. package/dist/core/types.js +0 -30
  58. package/dist/core/types.js.map +0 -1
  59. package/dist/index.d.ts.map +0 -1
  60. package/dist/mcp/connector.d.ts +0 -43
  61. package/dist/mcp/connector.d.ts.map +0 -1
  62. package/dist/mcp/connector.js +0 -79
  63. package/dist/mcp/connector.js.map +0 -1
  64. package/dist/mcp/index.d.ts +0 -4
  65. package/dist/mcp/index.d.ts.map +0 -1
  66. package/dist/mcp/index.js +0 -4
  67. package/dist/mcp/index.js.map +0 -1
  68. package/dist/react/index.d.ts +0 -4
  69. package/dist/react/index.d.ts.map +0 -1
  70. package/dist/react/index.js +0 -3
  71. package/dist/react/index.js.map +0 -1
  72. package/dist/react/useAgentRunner.d.ts +0 -16
  73. package/dist/react/useAgentRunner.d.ts.map +0 -1
  74. package/dist/react/useAgentRunner.js +0 -204
  75. package/dist/react/useAgentRunner.js.map +0 -1
  76. package/dist/registry/agent-registry.d.ts +0 -52
  77. package/dist/registry/agent-registry.d.ts.map +0 -1
  78. package/dist/registry/agent-registry.js +0 -221
  79. package/dist/registry/agent-registry.js.map +0 -1
  80. package/dist/registry/index.d.ts +0 -7
  81. package/dist/registry/index.d.ts.map +0 -1
  82. package/dist/registry/index.js +0 -6
  83. package/dist/registry/index.js.map +0 -1
  84. package/dist/registry/ipfs-fetcher.d.ts +0 -39
  85. package/dist/registry/ipfs-fetcher.d.ts.map +0 -1
  86. package/dist/registry/ipfs-fetcher.js +0 -139
  87. package/dist/registry/ipfs-fetcher.js.map +0 -1
  88. package/dist/reputation/index.d.ts +0 -4
  89. package/dist/reputation/index.d.ts.map +0 -1
  90. package/dist/reputation/index.js +0 -4
  91. package/dist/reputation/index.js.map +0 -1
  92. package/dist/reputation/reputation.d.ts +0 -26
  93. package/dist/reputation/reputation.d.ts.map +0 -1
  94. package/dist/reputation/reputation.js +0 -113
  95. package/dist/reputation/reputation.js.map +0 -1
  96. package/dist/subscription/agent-x402.d.ts +0 -33
  97. package/dist/subscription/agent-x402.d.ts.map +0 -1
  98. package/dist/subscription/agent-x402.js +0 -144
  99. package/dist/subscription/agent-x402.js.map +0 -1
  100. package/dist/subscription/index.d.ts +0 -6
  101. package/dist/subscription/index.d.ts.map +0 -1
  102. package/dist/subscription/index.js +0 -5
  103. package/dist/subscription/index.js.map +0 -1
  104. package/dist/subscription/subscription.d.ts +0 -67
  105. package/dist/subscription/subscription.d.ts.map +0 -1
  106. package/dist/subscription/subscription.js +0 -346
  107. package/dist/subscription/subscription.js.map +0 -1
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @agentx/sdk v0.2.0
1
+ # @agentxv2/sdk v0.2.0
2
2
 
3
3
  **Decentralized AI Agent Platform SDK** — E2E encryption, on-chain subscriptions, MCP tool execution.
4
4
 
@@ -9,9 +9,9 @@ Agent = Prompt + Skills[] + MCP
9
9
  ## Installation
10
10
 
11
11
  ```bash
12
- npm install @agentx/sdk
12
+ npm install @agentxv2/sdk
13
13
  # or
14
- pnpm add @agentx/sdk
14
+ pnpm add @agentxv2/sdk
15
15
  ```
16
16
 
17
17
  ### Peer Dependencies
@@ -28,8 +28,8 @@ pnpm add @agentx/sdk
28
28
  ### 1. Use an Agent (End-to-End Encrypted)
29
29
 
30
30
  ```ts
31
- import { AgentRunner } from '@agentx/sdk'
32
- import type { OnChainReader, WalletSigner } from '@agentx/sdk'
31
+ import { AgentRunner } from '@agentxv2/sdk'
32
+ import type { OnChainReader, WalletSigner } from '@agentxv2/sdk'
33
33
 
34
34
  // Implement these interfaces with your viem/wagmi setup
35
35
  const reader: OnChainReader = { /* ... */ }
@@ -47,7 +47,7 @@ const ctx = await runner.useAgent(42)
47
47
  ### 2. React Hook (with wagmi)
48
48
 
49
49
  ```tsx
50
- import { useAgentRunner } from '@agentx/sdk/react'
50
+ import { useAgentRunner } from '@agentxv2/sdk/react'
51
51
 
52
52
  function ChatPage({ agentId }: { agentId: number }) {
53
53
  const { ctx, isLoading, error, refetch } = useAgentRunner({ agentId })
@@ -64,7 +64,7 @@ function ChatPage({ agentId }: { agentId: number }) {
64
64
  ### 3. Publish an Agent
65
65
 
66
66
  ```ts
67
- import { generateAesKey, encryptPayload, packAgentForPublish } from '@agentx/sdk'
67
+ import { generateAesKey, encryptPayload, packAgentForPublish } from '@agentxv2/sdk'
68
68
 
69
69
  const privatePayload = { prompt: '...', skills: [...], mcp: { type: 'http', url: '' } }
70
70
 
@@ -83,7 +83,7 @@ const packResult = packAgentForPublish(agentPayload, publicKey, aesKey)
83
83
 
84
84
  ```
85
85
  ┌────────────────────────────────────────────────────┐
86
- │ @agentx/sdk │
86
+ │ @agentxv2/sdk │
87
87
  ├──────────┬──────────┬──────────┬──────────────────┤
88
88
  │ Core │ Agent │ MCP │ React │
89
89
  │ crypto │ Runner │ Connector│ useAgentRunner │
@@ -97,7 +97,7 @@ const packResult = packAgentForPublish(agentPayload, publicKey, aesKey)
97
97
 
98
98
  ## API Reference
99
99
 
100
- ### `@agentx/sdk` (Core)
100
+ ### `@agentxv2/sdk` (Core)
101
101
 
102
102
  | Export | Description |
103
103
  |--------|-------------|
@@ -132,13 +132,13 @@ When executed, the SDK loads Agent #42's prompt + skills, decrypts them,
132
132
  and returns the full sub-Agent context to the calling LLM.
133
133
  | `ReputationRegistry` | Give feedback + query reputation |
134
134
 
135
- ### `@agentx/sdk/react`
135
+ ### `@agentxv2/sdk/react`
136
136
 
137
137
  | Export | Description |
138
138
  |--------|-------------|
139
139
  | `useAgentRunner({ agentId })` | React hook: load + decrypt Agent |
140
140
 
141
- ### `@agentx/sdk/core`
141
+ ### `@agentxv2/sdk/core`
142
142
 
143
143
  | Export | Description |
144
144
  |--------|-------------|
@@ -0,0 +1,64 @@
1
+ import { E as EncryptedPayload, i as AgentPrivatePayload, g as AgentPayload, P as PackResult } from '../types-2aHUvS4M.mjs';
2
+ export { a as A2AAgentCard, e as A2ASkillExecution, b as A2ATask, f as A2ATaskStatus, h as AgentPricing, j as AgentPublicPayload, d as AgentReputation, c as AgentReview, k as AgentSearchQuery, l as AgentSearchResult, A as AgentSubscription, m as AgentXConfig, n as AgentXContracts, o as AgentXError, p as AgentXErrorCode, J as JSONSchema, q as JSONSchemaProperty, M as McpConnection, r as McpTransport, O as OnChainAgentMetadata, s as PricingType, R as RegisteredAgent, S as SkillDef, t as SkillExecutionMode, u as SkillExecutionRemote, v as SubscriptionRequired, w as SubscriptionStatus, U as UnpackResult } from '../types-2aHUvS4M.mjs';
3
+ export { bytesToHex, hexToBytes } from '@noble/ciphers/utils.js';
4
+
5
+ declare function randomBytes(length: number): Uint8Array;
6
+
7
+ /**
8
+ * Encrypt with AES-256-GCM.
9
+ * Wire format (same as aihunter-saas): base64( IV[12] || ciphertext || authTag[16] )
10
+ */
11
+ declare function aesEncrypt(plaintext: string, keyHex: string): string;
12
+ /**
13
+ * Decrypt AES-256-GCM (same wire format as aihunter-saas).
14
+ */
15
+ declare function aesDecrypt(encryptedBase64: string, keyHex: string): string;
16
+ /**
17
+ * Generate a cryptographically random AES-256 key (hex, 64 chars).
18
+ */
19
+ declare function generateAesKey(): string;
20
+ /**
21
+ * Encrypt data with recipient's secp256k1 public key (ECIES).
22
+ *
23
+ * @param dataHex The data to encrypt (hex, e.g. AES key)
24
+ * @param publicKey Recipient's public key (hex, 04-prefixed uncompressed or 02/03 compressed)
25
+ */
26
+ declare function eciesEncrypt(dataHex: string, publicKey: string): string;
27
+ /**
28
+ * Decrypt ECIES ciphertext with recipient's secp256k1 private key.
29
+ */
30
+ declare function eciesDecrypt(dataHex: string, privateKey: string): string;
31
+ /**
32
+ * Encrypt an Agent's private payload with AES-256-GCM.
33
+ */
34
+ declare function encryptPayload(payload: AgentPrivatePayload, keyHex?: string): EncryptedPayload;
35
+ /**
36
+ * Decrypt an EncryptedPayload.
37
+ */
38
+ declare function decryptPayload(encrypted: EncryptedPayload, keyHex: string): AgentPrivatePayload;
39
+ /**
40
+ * Pack an AgentPayload for publishing.
41
+ * 1. Split public/private
42
+ * 2. AES-256-GCM encrypt private part
43
+ * 3. ECIES wrap AES key with creator's public key
44
+ */
45
+ declare function packAgentForPublish(agent: AgentPayload, publicKey: string, aesKeyHex?: string): PackResult;
46
+ /**
47
+ * Unpack an Agent:
48
+ * 1. ECIES decrypt the AES key (private key)
49
+ * 2. AES-256-GCM decrypt the payload
50
+ */
51
+ declare function unpackAgent(encryptedPayload: EncryptedPayload, eciesEncryptedKey: string, privateKey: string): AgentPrivatePayload;
52
+ /**
53
+ * Generate a secp256k1 keypair compatible with Ethereum wallets.
54
+ */
55
+ declare function generateKeyPair(): {
56
+ privateKey: string;
57
+ publicKey: string;
58
+ };
59
+ /**
60
+ * Derive public key from private key (hex).
61
+ */
62
+ declare function getPublicKey(privateKey: string): string;
63
+
64
+ export { AgentPayload, AgentPrivatePayload, EncryptedPayload, PackResult, aesDecrypt, aesEncrypt, decryptPayload, eciesDecrypt, eciesEncrypt, encryptPayload, generateAesKey, generateKeyPair, getPublicKey, packAgentForPublish, randomBytes, unpackAgent };
package/dist/core.d.ts ADDED
@@ -0,0 +1,64 @@
1
+ import { E as EncryptedPayload, i as AgentPrivatePayload, g as AgentPayload, P as PackResult } from '../types-2aHUvS4M.js';
2
+ export { a as A2AAgentCard, e as A2ASkillExecution, b as A2ATask, f as A2ATaskStatus, h as AgentPricing, j as AgentPublicPayload, d as AgentReputation, c as AgentReview, k as AgentSearchQuery, l as AgentSearchResult, A as AgentSubscription, m as AgentXConfig, n as AgentXContracts, o as AgentXError, p as AgentXErrorCode, J as JSONSchema, q as JSONSchemaProperty, M as McpConnection, r as McpTransport, O as OnChainAgentMetadata, s as PricingType, R as RegisteredAgent, S as SkillDef, t as SkillExecutionMode, u as SkillExecutionRemote, v as SubscriptionRequired, w as SubscriptionStatus, U as UnpackResult } from '../types-2aHUvS4M.js';
3
+ export { bytesToHex, hexToBytes } from '@noble/ciphers/utils.js';
4
+
5
+ declare function randomBytes(length: number): Uint8Array;
6
+
7
+ /**
8
+ * Encrypt with AES-256-GCM.
9
+ * Wire format (same as aihunter-saas): base64( IV[12] || ciphertext || authTag[16] )
10
+ */
11
+ declare function aesEncrypt(plaintext: string, keyHex: string): string;
12
+ /**
13
+ * Decrypt AES-256-GCM (same wire format as aihunter-saas).
14
+ */
15
+ declare function aesDecrypt(encryptedBase64: string, keyHex: string): string;
16
+ /**
17
+ * Generate a cryptographically random AES-256 key (hex, 64 chars).
18
+ */
19
+ declare function generateAesKey(): string;
20
+ /**
21
+ * Encrypt data with recipient's secp256k1 public key (ECIES).
22
+ *
23
+ * @param dataHex The data to encrypt (hex, e.g. AES key)
24
+ * @param publicKey Recipient's public key (hex, 04-prefixed uncompressed or 02/03 compressed)
25
+ */
26
+ declare function eciesEncrypt(dataHex: string, publicKey: string): string;
27
+ /**
28
+ * Decrypt ECIES ciphertext with recipient's secp256k1 private key.
29
+ */
30
+ declare function eciesDecrypt(dataHex: string, privateKey: string): string;
31
+ /**
32
+ * Encrypt an Agent's private payload with AES-256-GCM.
33
+ */
34
+ declare function encryptPayload(payload: AgentPrivatePayload, keyHex?: string): EncryptedPayload;
35
+ /**
36
+ * Decrypt an EncryptedPayload.
37
+ */
38
+ declare function decryptPayload(encrypted: EncryptedPayload, keyHex: string): AgentPrivatePayload;
39
+ /**
40
+ * Pack an AgentPayload for publishing.
41
+ * 1. Split public/private
42
+ * 2. AES-256-GCM encrypt private part
43
+ * 3. ECIES wrap AES key with creator's public key
44
+ */
45
+ declare function packAgentForPublish(agent: AgentPayload, publicKey: string, aesKeyHex?: string): PackResult;
46
+ /**
47
+ * Unpack an Agent:
48
+ * 1. ECIES decrypt the AES key (private key)
49
+ * 2. AES-256-GCM decrypt the payload
50
+ */
51
+ declare function unpackAgent(encryptedPayload: EncryptedPayload, eciesEncryptedKey: string, privateKey: string): AgentPrivatePayload;
52
+ /**
53
+ * Generate a secp256k1 keypair compatible with Ethereum wallets.
54
+ */
55
+ declare function generateKeyPair(): {
56
+ privateKey: string;
57
+ publicKey: string;
58
+ };
59
+ /**
60
+ * Derive public key from private key (hex).
61
+ */
62
+ declare function getPublicKey(privateKey: string): string;
63
+
64
+ export { AgentPayload, AgentPrivatePayload, EncryptedPayload, PackResult, aesDecrypt, aesEncrypt, decryptPayload, eciesDecrypt, eciesEncrypt, encryptPayload, generateAesKey, generateKeyPair, getPublicKey, packAgentForPublish, randomBytes, unpackAgent };
package/dist/core.js ADDED
@@ -0,0 +1,275 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/core/index.ts
21
+ var core_exports = {};
22
+ __export(core_exports, {
23
+ AgentXError: () => AgentXError,
24
+ AgentXErrorCode: () => AgentXErrorCode,
25
+ aesDecrypt: () => aesDecrypt,
26
+ aesEncrypt: () => aesEncrypt,
27
+ bytesToHex: () => import_utils.bytesToHex,
28
+ decryptPayload: () => decryptPayload,
29
+ eciesDecrypt: () => eciesDecrypt,
30
+ eciesEncrypt: () => eciesEncrypt,
31
+ encryptPayload: () => encryptPayload,
32
+ generateAesKey: () => generateAesKey,
33
+ generateKeyPair: () => generateKeyPair,
34
+ getPublicKey: () => getPublicKey,
35
+ hexToBytes: () => import_utils.hexToBytes,
36
+ packAgentForPublish: () => packAgentForPublish,
37
+ randomBytes: () => randomBytes,
38
+ unpackAgent: () => unpackAgent
39
+ });
40
+ module.exports = __toCommonJS(core_exports);
41
+
42
+ // src/core/types.ts
43
+ var AgentXErrorCode = /* @__PURE__ */ ((AgentXErrorCode2) => {
44
+ AgentXErrorCode2["NOT_SUBSCRIBED"] = "NOT_SUBSCRIBED";
45
+ AgentXErrorCode2["SUBSCRIPTION_EXPIRED"] = "SUBSCRIPTION_EXPIRED";
46
+ AgentXErrorCode2["DECRYPTION_FAILED"] = "DECRYPTION_FAILED";
47
+ AgentXErrorCode2["IPFS_FETCH_FAILED"] = "IPFS_FETCH_FAILED";
48
+ AgentXErrorCode2["AGENT_NOT_FOUND"] = "AGENT_NOT_FOUND";
49
+ AgentXErrorCode2["INVALID_SCHEMA"] = "INVALID_SCHEMA";
50
+ AgentXErrorCode2["TX_FAILED"] = "TX_FAILED";
51
+ AgentXErrorCode2["WALLET_NOT_CONNECTED"] = "WALLET_NOT_CONNECTED";
52
+ return AgentXErrorCode2;
53
+ })(AgentXErrorCode || {});
54
+ var AgentXError = class extends Error {
55
+ code;
56
+ /** If NOT_SUBSCRIBED, carry enough info for wallet/X402 auto-payment */
57
+ paymentInfo;
58
+ constructor(code, message) {
59
+ super(message);
60
+ this.code = code;
61
+ this.name = "AgentXError";
62
+ }
63
+ };
64
+
65
+ // src/core/crypto.ts
66
+ var import_aes = require("@noble/ciphers/aes.js");
67
+ var import_secp256k1 = require("@noble/curves/secp256k1.js");
68
+ var import_sha2 = require("@noble/hashes/sha2.js");
69
+ var import_hkdf = require("@noble/hashes/hkdf.js");
70
+ var import_hmac = require("@noble/hashes/hmac.js");
71
+ var import_utils = require("@noble/ciphers/utils.js");
72
+ function randomBytes(length) {
73
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
74
+ const buf = new Uint8Array(length);
75
+ crypto.getRandomValues(buf);
76
+ return buf;
77
+ }
78
+ const nodeCrypto = require("crypto");
79
+ return new Uint8Array(nodeCrypto.randomBytes(length));
80
+ }
81
+ var AES_KEY_SIZE = 32;
82
+ var IV_SIZE = 12;
83
+ var TAG_SIZE = 16;
84
+ function toBase64(bytes) {
85
+ if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
86
+ let binary = "";
87
+ for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
88
+ return btoa(binary);
89
+ }
90
+ function fromBase64(b64) {
91
+ if (typeof Buffer !== "undefined") return new Uint8Array(Buffer.from(b64, "base64"));
92
+ const binary = atob(b64);
93
+ const bytes = new Uint8Array(binary.length);
94
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
95
+ return bytes;
96
+ }
97
+ function aesEncrypt(plaintext, keyHex) {
98
+ const key = (0, import_utils.hexToBytes)(keyHex);
99
+ const iv = randomBytes(IV_SIZE);
100
+ const plainBytes = new TextEncoder().encode(plaintext);
101
+ const cipher = (0, import_aes.gcm)(key, iv);
102
+ const encrypted = cipher.encrypt(plainBytes);
103
+ const ciphertext = encrypted.subarray(0, -TAG_SIZE);
104
+ const authTag = encrypted.subarray(-TAG_SIZE);
105
+ const combined = new Uint8Array(IV_SIZE + ciphertext.length + TAG_SIZE);
106
+ combined.set(iv, 0);
107
+ combined.set(ciphertext, IV_SIZE);
108
+ combined.set(authTag, IV_SIZE + ciphertext.length);
109
+ return toBase64(combined);
110
+ }
111
+ function aesDecrypt(encryptedBase64, keyHex) {
112
+ const key = (0, import_utils.hexToBytes)(keyHex);
113
+ const combined = fromBase64(encryptedBase64);
114
+ const iv = combined.subarray(0, IV_SIZE);
115
+ const ciphertext = combined.subarray(IV_SIZE, -TAG_SIZE);
116
+ const authTag = combined.subarray(-TAG_SIZE);
117
+ const cipher = (0, import_aes.gcm)(key, iv);
118
+ const ciphertextWithTag = new Uint8Array(ciphertext.length + TAG_SIZE);
119
+ ciphertextWithTag.set(ciphertext, 0);
120
+ ciphertextWithTag.set(authTag, ciphertext.length);
121
+ const decrypted = cipher.decrypt(ciphertextWithTag);
122
+ return new TextDecoder().decode(decrypted);
123
+ }
124
+ function generateAesKey() {
125
+ return (0, import_utils.bytesToHex)(randomBytes(AES_KEY_SIZE));
126
+ }
127
+ function eciesEncode(ephemeralPub, iv, ciphertext, mac) {
128
+ const out = new Uint8Array(33 + 16 + ciphertext.length + 32);
129
+ out.set(ephemeralPub, 0);
130
+ out.set(iv, 33);
131
+ out.set(ciphertext, 33 + 16);
132
+ out.set(mac, 33 + 16 + ciphertext.length);
133
+ return (0, import_utils.bytesToHex)(out);
134
+ }
135
+ function eciesDecode(dataHex) {
136
+ const d = (0, import_utils.hexToBytes)(dataHex);
137
+ return {
138
+ ephemeralPub: d.subarray(0, 33),
139
+ iv: d.subarray(33, 49),
140
+ ciphertext: d.subarray(49, -32),
141
+ mac: d.subarray(-32)
142
+ };
143
+ }
144
+ function aesCtrEncrypt(key, ctrBytes, data) {
145
+ const blockSize = 16;
146
+ const cipher = (0, import_aes.gcm)(key, ctrBytes);
147
+ const result = new Uint8Array(data.length);
148
+ const counter = new Uint8Array(blockSize);
149
+ counter.set(ctrBytes);
150
+ for (let i = 0; i < data.length; i += blockSize) {
151
+ const keystream = (0, import_aes.gcm)(key, counter).encrypt(new Uint8Array(blockSize));
152
+ for (let j = 0; j < blockSize && i + j < data.length; j++) {
153
+ result[i + j] = keystream[j] ^ data[i + j];
154
+ }
155
+ for (let j = blockSize - 1; j >= 0; j--) {
156
+ const val = counter[j];
157
+ if (val !== void 0) {
158
+ counter[j] = val + 1 & 255;
159
+ if (counter[j] !== 0) break;
160
+ }
161
+ }
162
+ }
163
+ return result;
164
+ }
165
+ function eciesEncrypt(dataHex, publicKey) {
166
+ const ephPriv = randomBytes(32);
167
+ const ephPub = import_secp256k1.secp256k1.getPublicKey(ephPriv, true);
168
+ let recipientPub;
169
+ if (publicKey.startsWith("04") && publicKey.length === 130) {
170
+ recipientPub = (0, import_utils.hexToBytes)(publicKey);
171
+ } else if (publicKey.startsWith("02") || publicKey.startsWith("03")) {
172
+ recipientPub = (0, import_utils.hexToBytes)(publicKey);
173
+ } else {
174
+ throw new Error("Invalid public key format: expected hex with 02/03/04 prefix");
175
+ }
176
+ const shared = import_secp256k1.secp256k1.getSharedSecret(ephPriv, recipientPub);
177
+ const sharedX = shared.subarray(1, 33);
178
+ const sharedKey = (0, import_sha2.sha256)(sharedX);
179
+ const hkdfOut = (0, import_hkdf.hkdf)(import_sha2.sha256, sharedKey, void 0, void 0, 64);
180
+ const encKey = hkdfOut.subarray(0, 32);
181
+ const macKey = hkdfOut.subarray(32, 64);
182
+ const iv = randomBytes(16);
183
+ const plaintext = (0, import_utils.hexToBytes)(dataHex);
184
+ const ciphertext = aesCtrEncrypt(encKey, iv, plaintext);
185
+ const macInput = new Uint8Array(33 + 16 + ciphertext.length);
186
+ macInput.set(ephPub, 0);
187
+ macInput.set(iv, 33);
188
+ macInput.set(ciphertext, 33 + 16);
189
+ const mac = (0, import_hmac.hmac)(import_sha2.sha256, macKey, macInput);
190
+ return eciesEncode(ephPub, iv, ciphertext, mac);
191
+ }
192
+ function eciesDecrypt(dataHex, privateKey) {
193
+ const { ephemeralPub, iv, ciphertext, mac } = eciesDecode(dataHex);
194
+ const privBytes = (0, import_utils.hexToBytes)(privateKey);
195
+ const shared = import_secp256k1.secp256k1.getSharedSecret(privBytes, ephemeralPub);
196
+ const sharedX = shared.subarray(1, 33);
197
+ const sharedKey = (0, import_sha2.sha256)(sharedX);
198
+ const hkdfOut = (0, import_hkdf.hkdf)(import_sha2.sha256, sharedKey, void 0, void 0, 64);
199
+ const encKey = hkdfOut.subarray(0, 32);
200
+ const macKey = hkdfOut.subarray(32, 64);
201
+ const macInput = new Uint8Array(33 + 16 + ciphertext.length);
202
+ macInput.set(ephemeralPub, 0);
203
+ macInput.set(iv, 33);
204
+ macInput.set(ciphertext, 33 + 16);
205
+ const expectedMac = (0, import_hmac.hmac)(import_sha2.sha256, macKey, macInput);
206
+ if (!constantTimeEqual(mac, expectedMac)) {
207
+ throw new Error("ECIES decryption failed: MAC mismatch");
208
+ }
209
+ const plaintext = aesCtrEncrypt(encKey, iv, ciphertext);
210
+ return (0, import_utils.bytesToHex)(plaintext);
211
+ }
212
+ function constantTimeEqual(a, b) {
213
+ if (a.length !== b.length) return false;
214
+ let diff = 0;
215
+ for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];
216
+ return diff === 0;
217
+ }
218
+ function encryptPayload(payload, keyHex) {
219
+ const key = keyHex ?? generateAesKey();
220
+ return {
221
+ encrypted: true,
222
+ algorithm: "AES-256-GCM",
223
+ data: aesEncrypt(JSON.stringify(payload), key)
224
+ };
225
+ }
226
+ function decryptPayload(encrypted, keyHex) {
227
+ if (encrypted.algorithm !== "AES-256-GCM") {
228
+ throw new Error(`Unsupported algorithm: ${encrypted.algorithm}`);
229
+ }
230
+ return JSON.parse(aesDecrypt(encrypted.data, keyHex));
231
+ }
232
+ function packAgentForPublish(agent, publicKey, aesKeyHex) {
233
+ const key = aesKeyHex ?? generateAesKey();
234
+ const eciesEncryptedKeyHex = eciesEncrypt(key, publicKey);
235
+ return {
236
+ encryptedCid: "",
237
+ // filled after IPFS upload
238
+ publicCid: "",
239
+ // filled after IPFS upload
240
+ aesKeyHex: key,
241
+ eciesEncryptedKeyHex
242
+ };
243
+ }
244
+ function unpackAgent(encryptedPayload, eciesEncryptedKey, privateKey) {
245
+ const aesKeyHex = eciesDecrypt(eciesEncryptedKey, privateKey);
246
+ return decryptPayload(encryptedPayload, aesKeyHex);
247
+ }
248
+ function generateKeyPair() {
249
+ const priv = randomBytes(32);
250
+ const pub = import_secp256k1.secp256k1.getPublicKey(priv, false);
251
+ return { privateKey: (0, import_utils.bytesToHex)(priv), publicKey: (0, import_utils.bytesToHex)(pub) };
252
+ }
253
+ function getPublicKey(privateKey) {
254
+ return (0, import_utils.bytesToHex)(import_secp256k1.secp256k1.getPublicKey((0, import_utils.hexToBytes)(privateKey), false));
255
+ }
256
+ // Annotate the CommonJS export names for ESM import in node:
257
+ 0 && (module.exports = {
258
+ AgentXError,
259
+ AgentXErrorCode,
260
+ aesDecrypt,
261
+ aesEncrypt,
262
+ bytesToHex,
263
+ decryptPayload,
264
+ eciesDecrypt,
265
+ eciesEncrypt,
266
+ encryptPayload,
267
+ generateAesKey,
268
+ generateKeyPair,
269
+ getPublicKey,
270
+ hexToBytes,
271
+ packAgentForPublish,
272
+ randomBytes,
273
+ unpackAgent
274
+ });
275
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/index.ts","../../src/core/types.ts","../../src/core/crypto.ts"],"sourcesContent":["// @agentx/sdk — Core module\nexport * from './types'\nexport * from './crypto'\n","// ---------------------------------------------------------------------------\n// @agentx/sdk — Core Type Definitions\n// ---------------------------------------------------------------------------\n// Agent = Prompt + Skills[] + MCP\n// All crypto-related \"wire\" fields (encryptedPayloadCid, eciesEncryptedKey)\n// live in IPFS metadata attributes → existing ERC8004 contracts are unchanged.\n// ---------------------------------------------------------------------------\n\n// ── JSON Schema (MCP standard subset) ──────────────────────────────────────\n\nexport interface JSONSchema {\n type: 'object' | 'array' | 'string' | 'number' | 'boolean' | 'integer' | 'null'\n properties?: Record<string, JSONSchemaProperty>\n required?: string[]\n description?: string\n items?: JSONSchema\n enum?: (string | number | boolean | null)[]\n}\n\nexport interface JSONSchemaProperty {\n type?: JSONSchema['type'] | JSONSchema['type'][]\n description?: string\n properties?: Record<string, JSONSchemaProperty>\n required?: string[]\n items?: JSONSchema\n enum?: (string | number | boolean | null)[]\n format?: string\n default?: unknown\n}\n\n// ── Skill Definition ───────────────────────────────────────────────────────\n\n/**\n * A single skill module that an Agent exposes.\n * `inputSchema` and `outputSchema` follow MCP Tool JSON Schema conventions.\n */\nexport interface SkillDef {\n /** Unique skill name (e.g. \"solidity_audit\") */\n name: string\n /** Human-readable description shown in the marketplace */\n description: string\n /** Semantic version of this skill */\n version: string\n /** JSON Schema for the tool's input parameters */\n inputSchema: JSONSchema\n /** JSON Schema for the tool's output return value */\n outputSchema?: JSONSchema\n /**\n * Execution mode.\n * - undefined / \"open\": Source is in the encrypted payload, runs locally.\n * - { type: \"mcp\", toolName: \"...\" }: Source lives on the publisher's\n * MCP server. Subscriber only gets Schema + remote execution endpoint.\n * MCP server verifies on-chain subscription on every call.\n * - { type: \"a2a\", targetAgentId: 42 }: Delegates to another AgentX Agent.\n * The caller's AgentRunner loads + decrypts the target Agent, injects\n * its prompt into the LLM context, and exposes its skills as callable\n * tools. This is the core Agent Composition primitive.\n */\n execution?: SkillExecutionRemote | A2ASkillExecution\n}\n\n/** Where the skill code actually runs. */\nexport type SkillExecutionMode = 'open' | 'mcp' | 'a2a'\n\nexport interface SkillExecutionRemote {\n type: 'mcp'\n /** MCP tool name on the publisher's server (e.g. \"run_strategy_abc123\") */\n toolName: string\n /** Optional: explicit MCP endpoint override */\n endpoint?: string\n}\n\n/**\n * A2A Skill Execution — delegate to another AgentX Agent.\n *\n * Example: A \"trading\" Agent has a skill:\n * execution: { type: \"a2a\", targetAgentId: 42 }\n * → When LLM calls this skill, AgentRunner loads Agent #42,\n * decrypts its prompt+skills, and the sub-Agent runs in the\n * same LLM conversation with its own system prompt.\n */\nexport interface A2ASkillExecution {\n type: 'a2a'\n /** On-chain Agent ID to delegate to */\n targetAgentId: number\n /** Optional: restrict which of the target Agent's skills are exposed */\n skillFilter?: string[]\n /** Optional: custom system prompt override for the sub-Agent */\n promptOverride?: string\n}\n\n// ── MCP Connection ─────────────────────────────────────────────────────────\n\nexport type McpTransport = 'http' | 'sse' | 'stdio'\n\nexport interface McpConnection {\n /** Transport type */\n type: McpTransport\n /** MCP server URL (required for http/sse) */\n url?: string\n /** Optional: limit which tools the Agent exposes to users */\n toolFilter?: string[]\n /** Optional: MCP server authentication header / key */\n authHeader?: string\n}\n\n// ── Pricing ────────────────────────────────────────────────────────────────\n\nexport type PricingType = 'subscription' | 'pay_per_use' | 'free'\n\nexport interface AgentPricing {\n type: PricingType\n /** Amount in native unit (e.g. \"0.01\" for 0.01 ETH) */\n amount: string\n /** ERC20 token address, or empty for native currency */\n currency: string\n /** Billing period for subscriptions (e.g. \"month\", \"year\", \"day\") */\n period?: string\n}\n\n// ── Agent Payload (the core data model) ────────────────────────────────────\n\n/**\n * The complete Agent definition.\n *\n * - Fields above \"--- private payload ---\" are public (IPFS publicPayloadCid).\n * - Fields below are encrypted with AES-256-GCM and stored at encryptedPayloadCid.\n */\nexport interface AgentPayload {\n // ── Public (visible in marketplace, stored at publicPayloadCid) ─────────\n name: string\n description: string\n image?: string\n version: string\n tags: string[]\n capabilities: string[]\n supportedTasks: string[]\n communicationProtocol: 'mcp' | 'a2a'\n authenticationMethod: 'ecdsa'\n pricing: AgentPricing\n\n // ── Private (AES-256-GCM encrypted, stored at encryptedPayloadCid) ──────\n prompt: string\n skills: SkillDef[]\n mcp: McpConnection\n}\n\n/** Subset of AgentPayload that is publicly visible */\nexport type AgentPublicPayload = Omit<\n AgentPayload,\n 'prompt' | 'skills' | 'mcp'\n>\n\n/** Fields that must be encrypted before IPFS upload */\nexport type AgentPrivatePayload = Pick<\n AgentPayload,\n 'prompt' | 'skills' | 'mcp'\n>\n\n// ── Encrypted Payload (IPFS wire format) ───────────────────────────────────\n\nexport interface EncryptedPayload {\n encrypted: true\n algorithm: 'AES-256-GCM'\n /** base64(iv + ciphertext + authTag) */\n data: string\n}\n\n// ── On-Chain Metadata (stored in ERC-721 tokenURI attributes) ─────────────\n\nexport interface OnChainAgentMetadata {\n tokenURI: string\n attributes: {\n name: string\n description: string\n /** CID of the AES-256-GCM encrypted payload on IPFS */\n encryptedPayloadCid: string\n /** ECIES-encrypted AES key (secp256k1, hex string) */\n eciesEncryptedKey: string\n /** CID of the public metadata on IPFS */\n publicPayloadCid: string\n capabilities: string[]\n skills: string[]\n mcpEndpoint: string\n version: string\n tags: string[]\n pricingType: PricingType\n pricingAmount: string\n }\n}\n\n// ── Agent Registry ─────────────────────────────────────────────────────────\n\nexport interface RegisteredAgent {\n /** ERC-721 token ID (= agentId) */\n agentId: number\n /** Owner wallet address */\n owner: string\n /** Creator wallet address */\n creator: string\n /** Full on-chain metadata */\n metadata: OnChainAgentMetadata\n /** Block number where agent was registered */\n registeredAt: number\n /** IPFS CID of the full public payload (resolved from tokenURI) */\n publicPayloadCid: string\n}\n\n// ── Agent Search ───────────────────────────────────────────────────────────\n\nexport interface AgentSearchQuery {\n keyword?: string\n capabilities?: string[]\n tags?: string[]\n pricingType?: PricingType\n maxPrice?: string\n owner?: string\n sortBy?: 'latest' | 'reputation' | 'price_asc' | 'price_desc'\n page?: number\n pageSize?: number\n}\n\nexport interface AgentSearchResult {\n agents: RegisteredAgent[]\n total: number\n page: number\n pageSize: number\n}\n\n// ── Subscription ───────────────────────────────────────────────────────────\n\nexport type SubscriptionStatus = 'active' | 'expired' | 'cancelled' | 'pending'\n\nexport interface AgentSubscription {\n subscriptionId: number\n subscriber: string\n agentId: number\n status: SubscriptionStatus\n startedAt: number\n expiresAt: number\n period: string\n}\n\n// ── A2A Protocol ───────────────────────────────────────────────────────────\n\nexport type A2ATaskStatus = 'created' | 'accepted' | 'in_progress' | 'completed' | 'failed'\n\nexport interface A2AAgentCard {\n agentId: number\n name: string\n capabilities: string[]\n supportedTasks: string[]\n /** MCP endpoint URL for direct agent-to-agent communication */\n endpoint: string\n /** Public key for ECDSA authentication */\n publicKey: string\n}\n\nexport interface A2ATask {\n taskId: number\n /** Agent that created the task */\n creator: string\n /** Target agent to execute the task */\n targetAgentId: number\n /** Task type (must be in target's supportedTasks) */\n taskType: string\n /** JSON input payload */\n input: string\n status: A2ATaskStatus\n result?: string\n createdAt: number\n completedAt?: number\n}\n\n// ── Reputation ─────────────────────────────────────────────────────────────\n\nexport interface AgentReputation {\n agentId: number\n averageRating: number\n totalRatings: number\n reviews: AgentReview[]\n}\n\nexport interface AgentReview {\n reviewer: string\n rating: number // 1-5\n comment: string\n timestamp: number\n}\n\n// ── AgentX Client Configuration ────────────────────────────────────────────\n\nexport interface AgentXConfig {\n /** Chain ID (e.g. 11155111 for Sepolia) */\n chainId: number\n /** RPC endpoint override (uses viem's default if omitted) */\n rpcUrl?: string\n /** Contract addresses for the current chain */\n contracts: AgentXContracts\n /** IPFS gateway URLs (ordered by priority) */\n ipfsGateways: string[]\n /** Default IPFS pinning service */\n pinningService?: 'pinata'\n pinataJwt?: string\n}\n\nexport interface AgentXContracts {\n identityRegistry: `0x${string}`\n subscriptionManager: `0x${string}`\n paymentGateway: `0x${string}`\n a2aProtocolRegistry: `0x${string}`\n reputationRegistry: `0x${string}`\n configurationRegistry: `0x${string}`\n}\n\n// ── Agent Packing / Unpacking Result ───────────────────────────────────────\n\nexport interface PackResult {\n /** CID of AES-256-GCM encrypted payload on IPFS */\n encryptedCid: string\n /** CID of public metadata on IPFS */\n publicCid: string\n /** Raw AES key (hex) — DO NOT share or upload this */\n aesKeyHex: string\n /** ECIES-encrypted AES key (hex), safe to store on-chain */\n eciesEncryptedKeyHex: string\n}\n\nexport interface UnpackResult {\n /** Decrypted AgentPayload */\n agent: AgentPayload\n /** CID where the encrypted payload was fetched from */\n encryptedCid: string\n /** CID of the public metadata */\n publicCid: string\n}\n\n// ── Error Types ────────────────────────────────────────────────────────────\n\nexport enum AgentXErrorCode {\n NOT_SUBSCRIBED = 'NOT_SUBSCRIBED',\n SUBSCRIPTION_EXPIRED = 'SUBSCRIPTION_EXPIRED',\n DECRYPTION_FAILED = 'DECRYPTION_FAILED',\n IPFS_FETCH_FAILED = 'IPFS_FETCH_FAILED',\n AGENT_NOT_FOUND = 'AGENT_NOT_FOUND',\n INVALID_SCHEMA = 'INVALID_SCHEMA',\n TX_FAILED = 'TX_FAILED',\n WALLET_NOT_CONNECTED = 'WALLET_NOT_CONNECTED',\n}\n\nexport class AgentXError extends Error {\n code: AgentXErrorCode\n /** If NOT_SUBSCRIBED, carry enough info for wallet/X402 auto-payment */\n paymentInfo?: SubscriptionRequired\n constructor(code: AgentXErrorCode, message: string) {\n super(message)\n this.code = code\n this.name = 'AgentXError'\n }\n}\n\n/**\n * Structured info for wallet/X402 auto-subscription.\n * Thrown by AgentRunner.useAgent() when the user/Agent has no\n * active subscription.\n */\nexport interface SubscriptionRequired {\n agentId: number\n /** Plan IDs available for this Agent (on-chain query) */\n plans?: { planId: number; price: bigint; period: string; payToken: string; trialDays: number }[]\n}\n","// ---------------------------------------------------------------------------\n// @agentx/sdk — Crypto Engine\n// ---------------------------------------------------------------------------\n// AES-256-GCM for content encryption (NIST standard, same wire format as\n// aihunter-saas for interop). ECIES (secp256k1) for key wrapping.\n//\n// Wire format (AES-256-GCM):\n// base64( IV[12] || ciphertext || authTag[16] )\n//\n// ECIES wire format (compatible with eciesjs):\n// hex( ephemeralPub[33] || IV[16] || ciphertext || MAC[32] )\n//\n// Pure JS — works in browser, Node, edge. No native deps except @noble/*.\n// ---------------------------------------------------------------------------\n\nimport { gcm } from '@noble/ciphers/aes.js'\nimport { secp256k1 } from '@noble/curves/secp256k1.js'\nimport { sha256 } from '@noble/hashes/sha2.js'\nimport { hkdf } from '@noble/hashes/hkdf.js'\nimport { hmac } from '@noble/hashes/hmac.js'\nimport { bytesToHex, hexToBytes } from '@noble/ciphers/utils.js'\n\n// ── randomBytes implementation (cross-runtime: browser / Node) ────────────\n\nexport function randomBytes(length: number): Uint8Array {\n // browser: crypto.getRandomValues\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const buf = new Uint8Array(length)\n crypto.getRandomValues(buf)\n return buf\n }\n // Node: crypto.randomBytes\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const nodeCrypto = require('crypto')\n return new Uint8Array(nodeCrypto.randomBytes(length))\n}\n\nimport type { EncryptedPayload, AgentPrivatePayload } from './types'\nimport type { PackResult } from './types'\n\n// ── Re-exports for convenience ─────────────────────────────────────────────\n\nexport { bytesToHex, hexToBytes }\n\n// ── Constants ──────────────────────────────────────────────────────────────\n\nconst AES_KEY_SIZE = 32\nconst IV_SIZE = 12 // GCM recommended\nconst TAG_SIZE = 16 // GCM auth tag\n\n// ── Base64 helpers (cross-runtime) ─────────────────────────────────────────\n\nfunction toBase64(bytes: Uint8Array): string {\n // Works in browser (btoa + binary) and Node (Buffer)\n if (typeof Buffer !== 'undefined') return Buffer.from(bytes).toString('base64')\n let binary = ''\n for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]!)\n return btoa(binary)\n}\n\nfunction fromBase64(b64: string): Uint8Array {\n if (typeof Buffer !== 'undefined') return new Uint8Array(Buffer.from(b64, 'base64'))\n const binary = atob(b64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n return bytes\n}\n\n// ── AES-256-GCM ────────────────────────────────────────────────────────────\n\n/**\n * Encrypt with AES-256-GCM.\n * Wire format (same as aihunter-saas): base64( IV[12] || ciphertext || authTag[16] )\n */\nexport function aesEncrypt(plaintext: string, keyHex: string): string {\n const key = hexToBytes(keyHex)\n const iv = randomBytes(IV_SIZE)\n const plainBytes = new TextEncoder().encode(plaintext)\n\n const cipher = gcm(key, iv)\n const encrypted = cipher.encrypt(plainBytes)\n // noble gcm.encrypt returns: ciphertext || authTag(16)\n const ciphertext = encrypted.subarray(0, -TAG_SIZE)\n const authTag = encrypted.subarray(-TAG_SIZE)\n\n // Pack: IV || ciphertext || authTag\n const combined = new Uint8Array(IV_SIZE + ciphertext.length + TAG_SIZE)\n combined.set(iv, 0)\n combined.set(ciphertext, IV_SIZE)\n combined.set(authTag, IV_SIZE + ciphertext.length)\n\n return toBase64(combined)\n}\n\n/**\n * Decrypt AES-256-GCM (same wire format as aihunter-saas).\n */\nexport function aesDecrypt(encryptedBase64: string, keyHex: string): string {\n const key = hexToBytes(keyHex)\n const combined = fromBase64(encryptedBase64)\n\n const iv = combined.subarray(0, IV_SIZE)\n const ciphertext = combined.subarray(IV_SIZE, -TAG_SIZE)\n const authTag = combined.subarray(-TAG_SIZE)\n\n const cipher = gcm(key, iv)\n // noble decrypt expects: ciphertext || authTag\n const ciphertextWithTag = new Uint8Array(ciphertext.length + TAG_SIZE)\n ciphertextWithTag.set(ciphertext, 0)\n ciphertextWithTag.set(authTag, ciphertext.length)\n\n const decrypted = cipher.decrypt(ciphertextWithTag)\n return new TextDecoder().decode(decrypted)\n}\n\n/**\n * Generate a cryptographically random AES-256 key (hex, 64 chars).\n */\nexport function generateAesKey(): string {\n return bytesToHex(randomBytes(AES_KEY_SIZE))\n}\n\n// ── ECIES (secp256k1) ──────────────────────────────────────────────────────\n//\n// eciesjs-compatible wire format:\n// ephemeralPub(33B compressed) || IV(16B) || ciphertext || MAC(32B)\n// Encoding: hex\n//\n// HKDF(SHA-256) derives AES key + HMAC key from ECDH shared secret.\n// ---------------------------------------------------------------------------\n\nfunction eciesEncode(\n ephemeralPub: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n mac: Uint8Array\n): string {\n const out = new Uint8Array(33 + 16 + ciphertext.length + 32)\n out.set(ephemeralPub, 0)\n out.set(iv, 33)\n out.set(ciphertext, 33 + 16)\n out.set(mac, 33 + 16 + ciphertext.length)\n return bytesToHex(out)\n}\n\nfunction eciesDecode(dataHex: string): {\n ephemeralPub: Uint8Array\n iv: Uint8Array\n ciphertext: Uint8Array\n mac: Uint8Array\n} {\n const d = hexToBytes(dataHex)\n return {\n ephemeralPub: d.subarray(0, 33),\n iv: d.subarray(33, 49),\n ciphertext: d.subarray(49, -32),\n mac: d.subarray(-32),\n }\n}\n\n// Simple AES-256-CTR implementation on top of @noble/ciphers AES core\nfunction aesCtrEncrypt(key: Uint8Array, ctrBytes: Uint8Array, data: Uint8Array): Uint8Array {\n const blockSize = 16\n const cipher = gcm(key, ctrBytes) // GCM internally handles CTR\n // Use noble's CTR approach: encrypt the plaintext directly with the derived stream\n // noble uses AES-CTR internally for GCM; simpler: implement CTR with AES-ECB\n const result = new Uint8Array(data.length)\n const counter = new Uint8Array(blockSize)\n counter.set(ctrBytes)\n for (let i = 0; i < data.length; i += blockSize) {\n const keystream = gcm(key, counter).encrypt(new Uint8Array(blockSize))\n for (let j = 0; j < blockSize && i + j < data.length; j++) {\n result[i + j] = keystream[j]! ^ data[i + j]!\n }\n // Increment counter (big-endian)\n for (let j = blockSize - 1; j >= 0; j--) {\n const val = counter[j]\n if (val !== undefined) {\n counter[j] = (val + 1) & 0xff\n if (counter[j] !== 0) break\n }\n }\n }\n return result\n}\n\n/**\n * Encrypt data with recipient's secp256k1 public key (ECIES).\n *\n * @param dataHex The data to encrypt (hex, e.g. AES key)\n * @param publicKey Recipient's public key (hex, 04-prefixed uncompressed or 02/03 compressed)\n */\nexport function eciesEncrypt(dataHex: string, publicKey: string): string {\n // 1. Ephemeral keypair\n const ephPriv = randomBytes(32)\n const ephPub = secp256k1.getPublicKey(ephPriv, true) // 33B compressed\n\n // 2. Parse recipient public key\n let recipientPub: Uint8Array\n if (publicKey.startsWith('04') && publicKey.length === 130) {\n recipientPub = hexToBytes(publicKey)\n } else if (publicKey.startsWith('02') || publicKey.startsWith('03')) {\n recipientPub = hexToBytes(publicKey)\n } else {\n throw new Error('Invalid public key format: expected hex with 02/03/04 prefix')\n }\n\n // 3. ECDH\n const shared = secp256k1.getSharedSecret(ephPriv, recipientPub)\n const sharedX = shared.subarray(1, 33) // x-coordinate only\n const sharedKey = sha256(sharedX)\n\n // 4. HKDF: encKey(32) || macKey(32)\n const hkdfOut = hkdf(sha256, sharedKey, undefined, undefined, 64)\n const encKey = hkdfOut.subarray(0, 32)\n const macKey = hkdfOut.subarray(32, 64)\n\n // 5. AES-256-CTR encrypt\n const iv = randomBytes(16)\n const plaintext = hexToBytes(dataHex)\n const ciphertext = aesCtrEncrypt(encKey, iv, plaintext)\n\n // 6. HMAC: MAC(ephemeralPub || IV || ciphertext)\n const macInput = new Uint8Array(33 + 16 + ciphertext.length)\n macInput.set(ephPub, 0)\n macInput.set(iv, 33)\n macInput.set(ciphertext, 33 + 16)\n const mac = hmac(sha256, macKey, macInput)\n\n return eciesEncode(ephPub, iv, ciphertext, mac)\n}\n\n/**\n * Decrypt ECIES ciphertext with recipient's secp256k1 private key.\n */\nexport function eciesDecrypt(dataHex: string, privateKey: string): string {\n const { ephemeralPub, iv, ciphertext, mac } = eciesDecode(dataHex)\n\n // 1. ECDH\n const privBytes = hexToBytes(privateKey)\n const shared = secp256k1.getSharedSecret(privBytes, ephemeralPub)\n const sharedX = shared.subarray(1, 33)\n const sharedKey = sha256(sharedX)\n\n // 2. HKDF\n const hkdfOut = hkdf(sha256, sharedKey, undefined, undefined, 64)\n const encKey = hkdfOut.subarray(0, 32)\n const macKey = hkdfOut.subarray(32, 64)\n\n // 3. Verify MAC\n const macInput = new Uint8Array(33 + 16 + ciphertext.length)\n macInput.set(ephemeralPub, 0)\n macInput.set(iv, 33)\n macInput.set(ciphertext, 33 + 16)\n const expectedMac = hmac(sha256, macKey, macInput)\n if (!constantTimeEqual(mac, expectedMac)) {\n throw new Error('ECIES decryption failed: MAC mismatch')\n }\n\n // 4. Decrypt\n const plaintext = aesCtrEncrypt(encKey, iv, ciphertext) // CTR encrypt = decrypt\n return bytesToHex(plaintext)\n}\n\nfunction constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false\n let diff = 0\n for (let i = 0; i < a.length; i++) diff |= a[i]! ^ b[i]!\n return diff === 0\n}\n\n// ── High-Level: Agent Pack / Unpack ────────────────────────────────────────\n\n/**\n * Encrypt an Agent's private payload with AES-256-GCM.\n */\nexport function encryptPayload(\n payload: AgentPrivatePayload,\n keyHex?: string\n): EncryptedPayload {\n const key = keyHex ?? generateAesKey()\n return {\n encrypted: true,\n algorithm: 'AES-256-GCM',\n data: aesEncrypt(JSON.stringify(payload), key),\n }\n}\n\n/**\n * Decrypt an EncryptedPayload.\n */\nexport function decryptPayload(\n encrypted: EncryptedPayload,\n keyHex: string\n): AgentPrivatePayload {\n if (encrypted.algorithm !== 'AES-256-GCM') {\n throw new Error(`Unsupported algorithm: ${encrypted.algorithm}`)\n }\n return JSON.parse(aesDecrypt(encrypted.data, keyHex)) as AgentPrivatePayload\n}\n\n/**\n * Pack an AgentPayload for publishing.\n * 1. Split public/private\n * 2. AES-256-GCM encrypt private part\n * 3. ECIES wrap AES key with creator's public key\n */\nexport function packAgentForPublish(\n agent: import('./types').AgentPayload,\n publicKey: string,\n aesKeyHex?: string\n): PackResult {\n const key = aesKeyHex ?? generateAesKey()\n\n const eciesEncryptedKeyHex = eciesEncrypt(key, publicKey)\n\n return {\n encryptedCid: '', // filled after IPFS upload\n publicCid: '', // filled after IPFS upload\n aesKeyHex: key,\n eciesEncryptedKeyHex,\n }\n}\n\n/**\n * Unpack an Agent:\n * 1. ECIES decrypt the AES key (private key)\n * 2. AES-256-GCM decrypt the payload\n */\nexport function unpackAgent(\n encryptedPayload: EncryptedPayload,\n eciesEncryptedKey: string,\n privateKey: string\n): AgentPrivatePayload {\n const aesKeyHex = eciesDecrypt(eciesEncryptedKey, privateKey)\n return decryptPayload(encryptedPayload, aesKeyHex)\n}\n\n// ── Key Pair Utilities ─────────────────────────────────────────────────────\n\n/**\n * Generate a secp256k1 keypair compatible with Ethereum wallets.\n */\nexport function generateKeyPair(): { privateKey: string; publicKey: string } {\n const priv = randomBytes(32)\n const pub = secp256k1.getPublicKey(priv, false) // uncompressed 04-prefixed\n return { privateKey: bytesToHex(priv), publicKey: bytesToHex(pub) }\n}\n\n/**\n * Derive public key from private key (hex).\n */\nexport function getPublicKey(privateKey: string): string {\n return bytesToHex(secp256k1.getPublicKey(hexToBytes(privateKey), false))\n}\n"],"mappings":"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","names":["AgentXErrorCode"]}