@elisym/sdk 0.1.2 → 0.2.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/node.cjs ADDED
@@ -0,0 +1,172 @@
1
+ 'use strict';
2
+
3
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
+ }) : x)(function(x) {
6
+ if (typeof require !== "undefined") return require.apply(this, arguments);
7
+ throw Error('Dynamic require of "' + x + '" is not supported');
8
+ });
9
+
10
+ // src/primitives/encryption.ts
11
+ var PREFIX = "encrypted:v1:";
12
+ var SALT_LENGTH = 16;
13
+ var IV_LENGTH = 12;
14
+ var TAG_LENGTH = 16;
15
+ var KEY_LENGTH = 32;
16
+ var SCRYPT_N = 2 ** 17;
17
+ var SCRYPT_R = 8;
18
+ var SCRYPT_P = 1;
19
+ var SCRYPT_MAXMEM = 128 * SCRYPT_N * SCRYPT_R * 2;
20
+ function isEncrypted(value) {
21
+ return value.startsWith(PREFIX);
22
+ }
23
+ function encryptSecret(plaintext, passphrase) {
24
+ if (!passphrase) {
25
+ throw new Error("Passphrase must not be empty.");
26
+ }
27
+ const { scryptSync, randomBytes, createCipheriv } = __require("crypto");
28
+ const { Buffer: Buffer2 } = __require("buffer");
29
+ const salt = randomBytes(SALT_LENGTH);
30
+ const key = scryptSync(passphrase, salt, KEY_LENGTH, {
31
+ N: SCRYPT_N,
32
+ r: SCRYPT_R,
33
+ p: SCRYPT_P,
34
+ maxmem: SCRYPT_MAXMEM
35
+ });
36
+ const iv = randomBytes(IV_LENGTH);
37
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
38
+ const encrypted = Buffer2.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
39
+ const tag = cipher.getAuthTag();
40
+ const payload = Buffer2.concat([salt, iv, encrypted, tag]);
41
+ return PREFIX + payload.toString("base64");
42
+ }
43
+ function decryptSecret(encrypted, passphrase) {
44
+ if (!isEncrypted(encrypted)) {
45
+ throw new Error("Value is not encrypted (missing encrypted:v1: prefix).");
46
+ }
47
+ if (!passphrase) {
48
+ throw new Error("Passphrase must not be empty.");
49
+ }
50
+ const { scryptSync, createDecipheriv } = __require("crypto");
51
+ const { Buffer: Buffer2 } = __require("buffer");
52
+ const payload = Buffer2.from(encrypted.slice(PREFIX.length), "base64");
53
+ if (payload.length < SALT_LENGTH + IV_LENGTH + TAG_LENGTH) {
54
+ throw new Error("Encrypted payload is too short.");
55
+ }
56
+ const salt = payload.subarray(0, SALT_LENGTH);
57
+ const iv = payload.subarray(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);
58
+ const tag = payload.subarray(payload.length - TAG_LENGTH);
59
+ const ciphertext = payload.subarray(SALT_LENGTH + IV_LENGTH, payload.length - TAG_LENGTH);
60
+ const key = scryptSync(passphrase, salt, KEY_LENGTH, {
61
+ N: SCRYPT_N,
62
+ r: SCRYPT_R,
63
+ p: SCRYPT_P,
64
+ maxmem: SCRYPT_MAXMEM
65
+ });
66
+ const decipher = createDecipheriv("aes-256-gcm", key, iv);
67
+ decipher.setAuthTag(tag);
68
+ try {
69
+ const decrypted = Buffer2.concat([decipher.update(ciphertext), decipher.final()]);
70
+ return decrypted.toString("utf8");
71
+ } catch {
72
+ throw new Error("Decryption failed. Wrong passphrase or corrupted data.");
73
+ }
74
+ }
75
+
76
+ // src/primitives/config-node.ts
77
+ function parseConfig(json, passphrase) {
78
+ const config = JSON.parse(json);
79
+ if (!config || typeof config !== "object" || Array.isArray(config)) {
80
+ throw new Error("Invalid config: expected JSON object.");
81
+ }
82
+ if (!config.identity?.secret_key || typeof config.identity.secret_key !== "string") {
83
+ throw new Error("Invalid config: missing or non-string identity.secret_key.");
84
+ }
85
+ if (typeof config.identity.name !== "string" || !config.identity.name) {
86
+ throw new Error("Invalid config: missing or non-string identity.name.");
87
+ }
88
+ if (!Array.isArray(config.relays) || !config.relays.every((r) => typeof r === "string")) {
89
+ throw new Error("Invalid config: relays must be an array of strings.");
90
+ }
91
+ if (config.capabilities !== void 0) {
92
+ if (!Array.isArray(config.capabilities)) {
93
+ throw new Error("Invalid config: capabilities must be an array.");
94
+ }
95
+ for (const cap of config.capabilities) {
96
+ if (!cap || typeof cap !== "object" || typeof cap.name !== "string" || typeof cap.description !== "string" || typeof cap.price !== "number") {
97
+ throw new Error(
98
+ "Invalid config: each capability must have name (string), description (string), and price (number)."
99
+ );
100
+ }
101
+ if (!Array.isArray(cap.tags) || !cap.tags.every((t) => typeof t === "string")) {
102
+ throw new Error("Invalid config: each capability must have tags (array of strings).");
103
+ }
104
+ if (!Number.isInteger(cap.price) || cap.price < 0) {
105
+ throw new Error(
106
+ "Invalid config: capability price must be a non-negative integer (lamports)."
107
+ );
108
+ }
109
+ }
110
+ }
111
+ if (config.payments !== void 0) {
112
+ if (!Array.isArray(config.payments)) {
113
+ throw new Error("Invalid config: payments must be an array.");
114
+ }
115
+ for (const p of config.payments) {
116
+ if (!p || typeof p !== "object" || typeof p.chain !== "string" || typeof p.network !== "string" || typeof p.address !== "string") {
117
+ throw new Error(
118
+ "Invalid config: each payment entry must have chain, network, and address (all strings)."
119
+ );
120
+ }
121
+ }
122
+ }
123
+ if (config.wallet !== void 0) {
124
+ if (!config.wallet || typeof config.wallet !== "object" || typeof config.wallet.chain !== "string" || typeof config.wallet.network !== "string" || typeof config.wallet.secret_key !== "string") {
125
+ throw new Error(
126
+ "Invalid config: wallet must have chain, network, and secret_key (all strings)."
127
+ );
128
+ }
129
+ }
130
+ if (config.llm !== void 0) {
131
+ if (!config.llm || typeof config.llm !== "object" || typeof config.llm.provider !== "string" || typeof config.llm.model !== "string" || typeof config.llm.api_key !== "string" || typeof config.llm.max_tokens !== "number" || !Number.isInteger(config.llm.max_tokens) || config.llm.max_tokens <= 0) {
132
+ throw new Error(
133
+ "Invalid config: llm must have provider, model, api_key (strings) and max_tokens (positive integer)."
134
+ );
135
+ }
136
+ }
137
+ if (!passphrase) {
138
+ const encrypted = [];
139
+ if (config.identity?.secret_key && isEncrypted(config.identity.secret_key)) {
140
+ encrypted.push("identity.secret_key");
141
+ }
142
+ if (config.wallet?.secret_key && isEncrypted(config.wallet.secret_key)) {
143
+ encrypted.push("wallet.secret_key");
144
+ }
145
+ if (config.llm?.api_key && isEncrypted(config.llm.api_key)) {
146
+ encrypted.push("llm.api_key");
147
+ }
148
+ if (encrypted.length > 0) {
149
+ throw new Error(
150
+ `Fields [${encrypted.join(", ")}] are encrypted but no passphrase provided. Set ELISYM_PASSPHRASE env var.`
151
+ );
152
+ }
153
+ return config;
154
+ }
155
+ if (config.identity?.secret_key && isEncrypted(config.identity.secret_key)) {
156
+ config.identity.secret_key = decryptSecret(config.identity.secret_key, passphrase);
157
+ }
158
+ if (config.wallet?.secret_key && isEncrypted(config.wallet.secret_key)) {
159
+ config.wallet.secret_key = decryptSecret(config.wallet.secret_key, passphrase);
160
+ }
161
+ if (config.llm?.api_key && isEncrypted(config.llm.api_key)) {
162
+ config.llm.api_key = decryptSecret(config.llm.api_key, passphrase);
163
+ }
164
+ return config;
165
+ }
166
+
167
+ exports.decryptSecret = decryptSecret;
168
+ exports.encryptSecret = encryptSecret;
169
+ exports.isEncrypted = isEncrypted;
170
+ exports.parseConfig = parseConfig;
171
+ //# sourceMappingURL=node.cjs.map
172
+ //# sourceMappingURL=node.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/primitives/encryption.ts","../src/primitives/config-node.ts"],"names":["Buffer"],"mappings":"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","file":"node.cjs","sourcesContent":["/**\n * Secret encryption/decryption for agent config files.\n * Uses scrypt (KDF) + AES-256-GCM (cipher).\n * Format: \"encrypted:v1:\" + base64(salt[16] + iv[12] + ciphertext + tag[16])\n *\n * scrypt params: N=2^17, r=8, p=1 (~128 MB RAM per derivation).\n *\n * Node.js/Bun only - not available in browsers.\n * All Node.js APIs are lazy-imported to avoid polluting browser bundles.\n */\n\nconst PREFIX = 'encrypted:v1:';\nconst SALT_LENGTH = 16;\nconst IV_LENGTH = 12;\nconst TAG_LENGTH = 16;\nconst KEY_LENGTH = 32; // AES-256\n// v1: N=2^17 (OWASP minimum). v2 will use N=2^20 with format migration.\nconst SCRYPT_N = 2 ** 17;\nconst SCRYPT_R = 8;\nconst SCRYPT_P = 1;\nconst SCRYPT_MAXMEM = 128 * SCRYPT_N * SCRYPT_R * 2; // 2x the minimum required memory\n\n/** Check if a value is encrypted (has the encrypted:v1: prefix). */\nexport function isEncrypted(value: string): boolean {\n return value.startsWith(PREFIX);\n}\n\n/** Encrypt a plaintext secret with a passphrase. Returns \"encrypted:v1:base64...\". Node.js/Bun only. */\nexport function encryptSecret(plaintext: string, passphrase: string): string {\n if (!passphrase) {\n throw new Error('Passphrase must not be empty.');\n }\n const { scryptSync, randomBytes, createCipheriv } =\n require('node:crypto') as typeof import('node:crypto');\n const { Buffer } = require('node:buffer') as typeof import('node:buffer');\n\n const salt = randomBytes(SALT_LENGTH);\n const key = scryptSync(passphrase, salt, KEY_LENGTH, {\n N: SCRYPT_N,\n r: SCRYPT_R,\n p: SCRYPT_P,\n maxmem: SCRYPT_MAXMEM,\n });\n const iv = randomBytes(IV_LENGTH);\n\n const cipher = createCipheriv('aes-256-gcm', key, iv);\n const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\n const tag = cipher.getAuthTag();\n\n const payload = Buffer.concat([salt, iv, encrypted, tag]);\n return PREFIX + payload.toString('base64');\n}\n\n/** Decrypt an encrypted secret with a passphrase. Throws on wrong passphrase or corrupted data. Node.js/Bun only. */\nexport function decryptSecret(encrypted: string, passphrase: string): string {\n if (!isEncrypted(encrypted)) {\n throw new Error('Value is not encrypted (missing encrypted:v1: prefix).');\n }\n if (!passphrase) {\n throw new Error('Passphrase must not be empty.');\n }\n\n const { scryptSync, createDecipheriv } = require('node:crypto') as typeof import('node:crypto');\n const { Buffer } = require('node:buffer') as typeof import('node:buffer');\n\n const payload = Buffer.from(encrypted.slice(PREFIX.length), 'base64');\n if (payload.length < SALT_LENGTH + IV_LENGTH + TAG_LENGTH) {\n throw new Error('Encrypted payload is too short.');\n }\n\n const salt = payload.subarray(0, SALT_LENGTH);\n const iv = payload.subarray(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);\n const tag = payload.subarray(payload.length - TAG_LENGTH);\n const ciphertext = payload.subarray(SALT_LENGTH + IV_LENGTH, payload.length - TAG_LENGTH);\n\n const key = scryptSync(passphrase, salt, KEY_LENGTH, {\n N: SCRYPT_N,\n r: SCRYPT_R,\n p: SCRYPT_P,\n maxmem: SCRYPT_MAXMEM,\n });\n\n const decipher = createDecipheriv('aes-256-gcm', key, iv);\n decipher.setAuthTag(tag);\n\n try {\n const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);\n return decrypted.toString('utf8');\n } catch {\n throw new Error('Decryption failed. Wrong passphrase or corrupted data.');\n }\n}\n","/**\n * Node.js-only config parsing with secret decryption.\n * Exported from '@elisym/sdk/node'.\n */\n\nimport type { AgentConfig } from '../types';\nimport { isEncrypted, decryptSecret } from './encryption';\n\n/**\n * Parse a JSON string into an AgentConfig.\n * If passphrase is provided, decrypts all encrypted fields (requires Node.js/Bun).\n * If passphrase is not provided and encrypted fields exist, throws.\n */\nexport function parseConfig(json: string, passphrase?: string): AgentConfig {\n const config = JSON.parse(json) as AgentConfig;\n\n if (!config || typeof config !== 'object' || Array.isArray(config)) {\n throw new Error('Invalid config: expected JSON object.');\n }\n if (!config.identity?.secret_key || typeof config.identity.secret_key !== 'string') {\n throw new Error('Invalid config: missing or non-string identity.secret_key.');\n }\n if (typeof config.identity.name !== 'string' || !config.identity.name) {\n throw new Error('Invalid config: missing or non-string identity.name.');\n }\n if (\n !Array.isArray(config.relays) ||\n !config.relays.every((r: unknown) => typeof r === 'string')\n ) {\n throw new Error('Invalid config: relays must be an array of strings.');\n }\n\n if (config.capabilities !== undefined) {\n if (!Array.isArray(config.capabilities)) {\n throw new Error('Invalid config: capabilities must be an array.');\n }\n for (const cap of config.capabilities) {\n if (\n !cap ||\n typeof cap !== 'object' ||\n typeof cap.name !== 'string' ||\n typeof cap.description !== 'string' ||\n typeof cap.price !== 'number'\n ) {\n throw new Error(\n 'Invalid config: each capability must have name (string), description (string), and price (number).',\n );\n }\n if (!Array.isArray(cap.tags) || !cap.tags.every((t: unknown) => typeof t === 'string')) {\n throw new Error('Invalid config: each capability must have tags (array of strings).');\n }\n if (!Number.isInteger(cap.price) || cap.price < 0) {\n throw new Error(\n 'Invalid config: capability price must be a non-negative integer (lamports).',\n );\n }\n }\n }\n if (config.payments !== undefined) {\n if (!Array.isArray(config.payments)) {\n throw new Error('Invalid config: payments must be an array.');\n }\n for (const p of config.payments) {\n if (\n !p ||\n typeof p !== 'object' ||\n typeof p.chain !== 'string' ||\n typeof p.network !== 'string' ||\n typeof p.address !== 'string'\n ) {\n throw new Error(\n 'Invalid config: each payment entry must have chain, network, and address (all strings).',\n );\n }\n }\n }\n if (config.wallet !== undefined) {\n if (\n !config.wallet ||\n typeof config.wallet !== 'object' ||\n typeof config.wallet.chain !== 'string' ||\n typeof config.wallet.network !== 'string' ||\n typeof config.wallet.secret_key !== 'string'\n ) {\n throw new Error(\n 'Invalid config: wallet must have chain, network, and secret_key (all strings).',\n );\n }\n }\n if (config.llm !== undefined) {\n if (\n !config.llm ||\n typeof config.llm !== 'object' ||\n typeof config.llm.provider !== 'string' ||\n typeof config.llm.model !== 'string' ||\n typeof config.llm.api_key !== 'string' ||\n typeof config.llm.max_tokens !== 'number' ||\n !Number.isInteger(config.llm.max_tokens) ||\n config.llm.max_tokens <= 0\n ) {\n throw new Error(\n 'Invalid config: llm must have provider, model, api_key (strings) and max_tokens (positive integer).',\n );\n }\n }\n\n if (!passphrase) {\n const encrypted: string[] = [];\n if (config.identity?.secret_key && isEncrypted(config.identity.secret_key)) {\n encrypted.push('identity.secret_key');\n }\n if (config.wallet?.secret_key && isEncrypted(config.wallet.secret_key)) {\n encrypted.push('wallet.secret_key');\n }\n if (config.llm?.api_key && isEncrypted(config.llm.api_key)) {\n encrypted.push('llm.api_key');\n }\n if (encrypted.length > 0) {\n throw new Error(\n `Fields [${encrypted.join(', ')}] are encrypted but no passphrase provided. Set ELISYM_PASSPHRASE env var.`,\n );\n }\n return config;\n }\n\n if (config.identity?.secret_key && isEncrypted(config.identity.secret_key)) {\n config.identity.secret_key = decryptSecret(config.identity.secret_key, passphrase);\n }\n if (config.wallet?.secret_key && isEncrypted(config.wallet.secret_key)) {\n config.wallet.secret_key = decryptSecret(config.wallet.secret_key, passphrase);\n }\n if (config.llm?.api_key && isEncrypted(config.llm.api_key)) {\n config.llm.api_key = decryptSecret(config.llm.api_key, passphrase);\n }\n\n return config;\n}\n"]}
@@ -0,0 +1,32 @@
1
+ import { g as AgentConfig } from './types-CII4k_8d.cjs';
2
+
3
+ /**
4
+ * Secret encryption/decryption for agent config files.
5
+ * Uses scrypt (KDF) + AES-256-GCM (cipher).
6
+ * Format: "encrypted:v1:" + base64(salt[16] + iv[12] + ciphertext + tag[16])
7
+ *
8
+ * scrypt params: N=2^17, r=8, p=1 (~128 MB RAM per derivation).
9
+ *
10
+ * Node.js/Bun only - not available in browsers.
11
+ * All Node.js APIs are lazy-imported to avoid polluting browser bundles.
12
+ */
13
+ /** Check if a value is encrypted (has the encrypted:v1: prefix). */
14
+ declare function isEncrypted(value: string): boolean;
15
+ /** Encrypt a plaintext secret with a passphrase. Returns "encrypted:v1:base64...". Node.js/Bun only. */
16
+ declare function encryptSecret(plaintext: string, passphrase: string): string;
17
+ /** Decrypt an encrypted secret with a passphrase. Throws on wrong passphrase or corrupted data. Node.js/Bun only. */
18
+ declare function decryptSecret(encrypted: string, passphrase: string): string;
19
+
20
+ /**
21
+ * Node.js-only config parsing with secret decryption.
22
+ * Exported from '@elisym/sdk/node'.
23
+ */
24
+
25
+ /**
26
+ * Parse a JSON string into an AgentConfig.
27
+ * If passphrase is provided, decrypts all encrypted fields (requires Node.js/Bun).
28
+ * If passphrase is not provided and encrypted fields exist, throws.
29
+ */
30
+ declare function parseConfig(json: string, passphrase?: string): AgentConfig;
31
+
32
+ export { decryptSecret, encryptSecret, isEncrypted, parseConfig };
package/dist/node.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { g as AgentConfig } from './types-CII4k_8d.js';
2
+
3
+ /**
4
+ * Secret encryption/decryption for agent config files.
5
+ * Uses scrypt (KDF) + AES-256-GCM (cipher).
6
+ * Format: "encrypted:v1:" + base64(salt[16] + iv[12] + ciphertext + tag[16])
7
+ *
8
+ * scrypt params: N=2^17, r=8, p=1 (~128 MB RAM per derivation).
9
+ *
10
+ * Node.js/Bun only - not available in browsers.
11
+ * All Node.js APIs are lazy-imported to avoid polluting browser bundles.
12
+ */
13
+ /** Check if a value is encrypted (has the encrypted:v1: prefix). */
14
+ declare function isEncrypted(value: string): boolean;
15
+ /** Encrypt a plaintext secret with a passphrase. Returns "encrypted:v1:base64...". Node.js/Bun only. */
16
+ declare function encryptSecret(plaintext: string, passphrase: string): string;
17
+ /** Decrypt an encrypted secret with a passphrase. Throws on wrong passphrase or corrupted data. Node.js/Bun only. */
18
+ declare function decryptSecret(encrypted: string, passphrase: string): string;
19
+
20
+ /**
21
+ * Node.js-only config parsing with secret decryption.
22
+ * Exported from '@elisym/sdk/node'.
23
+ */
24
+
25
+ /**
26
+ * Parse a JSON string into an AgentConfig.
27
+ * If passphrase is provided, decrypts all encrypted fields (requires Node.js/Bun).
28
+ * If passphrase is not provided and encrypted fields exist, throws.
29
+ */
30
+ declare function parseConfig(json: string, passphrase?: string): AgentConfig;
31
+
32
+ export { decryptSecret, encryptSecret, isEncrypted, parseConfig };
package/dist/node.js ADDED
@@ -0,0 +1,167 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/primitives/encryption.ts
9
+ var PREFIX = "encrypted:v1:";
10
+ var SALT_LENGTH = 16;
11
+ var IV_LENGTH = 12;
12
+ var TAG_LENGTH = 16;
13
+ var KEY_LENGTH = 32;
14
+ var SCRYPT_N = 2 ** 17;
15
+ var SCRYPT_R = 8;
16
+ var SCRYPT_P = 1;
17
+ var SCRYPT_MAXMEM = 128 * SCRYPT_N * SCRYPT_R * 2;
18
+ function isEncrypted(value) {
19
+ return value.startsWith(PREFIX);
20
+ }
21
+ function encryptSecret(plaintext, passphrase) {
22
+ if (!passphrase) {
23
+ throw new Error("Passphrase must not be empty.");
24
+ }
25
+ const { scryptSync, randomBytes, createCipheriv } = __require("node:crypto");
26
+ const { Buffer: Buffer2 } = __require("node:buffer");
27
+ const salt = randomBytes(SALT_LENGTH);
28
+ const key = scryptSync(passphrase, salt, KEY_LENGTH, {
29
+ N: SCRYPT_N,
30
+ r: SCRYPT_R,
31
+ p: SCRYPT_P,
32
+ maxmem: SCRYPT_MAXMEM
33
+ });
34
+ const iv = randomBytes(IV_LENGTH);
35
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
36
+ const encrypted = Buffer2.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
37
+ const tag = cipher.getAuthTag();
38
+ const payload = Buffer2.concat([salt, iv, encrypted, tag]);
39
+ return PREFIX + payload.toString("base64");
40
+ }
41
+ function decryptSecret(encrypted, passphrase) {
42
+ if (!isEncrypted(encrypted)) {
43
+ throw new Error("Value is not encrypted (missing encrypted:v1: prefix).");
44
+ }
45
+ if (!passphrase) {
46
+ throw new Error("Passphrase must not be empty.");
47
+ }
48
+ const { scryptSync, createDecipheriv } = __require("node:crypto");
49
+ const { Buffer: Buffer2 } = __require("node:buffer");
50
+ const payload = Buffer2.from(encrypted.slice(PREFIX.length), "base64");
51
+ if (payload.length < SALT_LENGTH + IV_LENGTH + TAG_LENGTH) {
52
+ throw new Error("Encrypted payload is too short.");
53
+ }
54
+ const salt = payload.subarray(0, SALT_LENGTH);
55
+ const iv = payload.subarray(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);
56
+ const tag = payload.subarray(payload.length - TAG_LENGTH);
57
+ const ciphertext = payload.subarray(SALT_LENGTH + IV_LENGTH, payload.length - TAG_LENGTH);
58
+ const key = scryptSync(passphrase, salt, KEY_LENGTH, {
59
+ N: SCRYPT_N,
60
+ r: SCRYPT_R,
61
+ p: SCRYPT_P,
62
+ maxmem: SCRYPT_MAXMEM
63
+ });
64
+ const decipher = createDecipheriv("aes-256-gcm", key, iv);
65
+ decipher.setAuthTag(tag);
66
+ try {
67
+ const decrypted = Buffer2.concat([decipher.update(ciphertext), decipher.final()]);
68
+ return decrypted.toString("utf8");
69
+ } catch {
70
+ throw new Error("Decryption failed. Wrong passphrase or corrupted data.");
71
+ }
72
+ }
73
+
74
+ // src/primitives/config-node.ts
75
+ function parseConfig(json, passphrase) {
76
+ const config = JSON.parse(json);
77
+ if (!config || typeof config !== "object" || Array.isArray(config)) {
78
+ throw new Error("Invalid config: expected JSON object.");
79
+ }
80
+ if (!config.identity?.secret_key || typeof config.identity.secret_key !== "string") {
81
+ throw new Error("Invalid config: missing or non-string identity.secret_key.");
82
+ }
83
+ if (typeof config.identity.name !== "string" || !config.identity.name) {
84
+ throw new Error("Invalid config: missing or non-string identity.name.");
85
+ }
86
+ if (!Array.isArray(config.relays) || !config.relays.every((r) => typeof r === "string")) {
87
+ throw new Error("Invalid config: relays must be an array of strings.");
88
+ }
89
+ if (config.capabilities !== void 0) {
90
+ if (!Array.isArray(config.capabilities)) {
91
+ throw new Error("Invalid config: capabilities must be an array.");
92
+ }
93
+ for (const cap of config.capabilities) {
94
+ if (!cap || typeof cap !== "object" || typeof cap.name !== "string" || typeof cap.description !== "string" || typeof cap.price !== "number") {
95
+ throw new Error(
96
+ "Invalid config: each capability must have name (string), description (string), and price (number)."
97
+ );
98
+ }
99
+ if (!Array.isArray(cap.tags) || !cap.tags.every((t) => typeof t === "string")) {
100
+ throw new Error("Invalid config: each capability must have tags (array of strings).");
101
+ }
102
+ if (!Number.isInteger(cap.price) || cap.price < 0) {
103
+ throw new Error(
104
+ "Invalid config: capability price must be a non-negative integer (lamports)."
105
+ );
106
+ }
107
+ }
108
+ }
109
+ if (config.payments !== void 0) {
110
+ if (!Array.isArray(config.payments)) {
111
+ throw new Error("Invalid config: payments must be an array.");
112
+ }
113
+ for (const p of config.payments) {
114
+ if (!p || typeof p !== "object" || typeof p.chain !== "string" || typeof p.network !== "string" || typeof p.address !== "string") {
115
+ throw new Error(
116
+ "Invalid config: each payment entry must have chain, network, and address (all strings)."
117
+ );
118
+ }
119
+ }
120
+ }
121
+ if (config.wallet !== void 0) {
122
+ if (!config.wallet || typeof config.wallet !== "object" || typeof config.wallet.chain !== "string" || typeof config.wallet.network !== "string" || typeof config.wallet.secret_key !== "string") {
123
+ throw new Error(
124
+ "Invalid config: wallet must have chain, network, and secret_key (all strings)."
125
+ );
126
+ }
127
+ }
128
+ if (config.llm !== void 0) {
129
+ if (!config.llm || typeof config.llm !== "object" || typeof config.llm.provider !== "string" || typeof config.llm.model !== "string" || typeof config.llm.api_key !== "string" || typeof config.llm.max_tokens !== "number" || !Number.isInteger(config.llm.max_tokens) || config.llm.max_tokens <= 0) {
130
+ throw new Error(
131
+ "Invalid config: llm must have provider, model, api_key (strings) and max_tokens (positive integer)."
132
+ );
133
+ }
134
+ }
135
+ if (!passphrase) {
136
+ const encrypted = [];
137
+ if (config.identity?.secret_key && isEncrypted(config.identity.secret_key)) {
138
+ encrypted.push("identity.secret_key");
139
+ }
140
+ if (config.wallet?.secret_key && isEncrypted(config.wallet.secret_key)) {
141
+ encrypted.push("wallet.secret_key");
142
+ }
143
+ if (config.llm?.api_key && isEncrypted(config.llm.api_key)) {
144
+ encrypted.push("llm.api_key");
145
+ }
146
+ if (encrypted.length > 0) {
147
+ throw new Error(
148
+ `Fields [${encrypted.join(", ")}] are encrypted but no passphrase provided. Set ELISYM_PASSPHRASE env var.`
149
+ );
150
+ }
151
+ return config;
152
+ }
153
+ if (config.identity?.secret_key && isEncrypted(config.identity.secret_key)) {
154
+ config.identity.secret_key = decryptSecret(config.identity.secret_key, passphrase);
155
+ }
156
+ if (config.wallet?.secret_key && isEncrypted(config.wallet.secret_key)) {
157
+ config.wallet.secret_key = decryptSecret(config.wallet.secret_key, passphrase);
158
+ }
159
+ if (config.llm?.api_key && isEncrypted(config.llm.api_key)) {
160
+ config.llm.api_key = decryptSecret(config.llm.api_key, passphrase);
161
+ }
162
+ return config;
163
+ }
164
+
165
+ export { decryptSecret, encryptSecret, isEncrypted, parseConfig };
166
+ //# sourceMappingURL=node.js.map
167
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/primitives/encryption.ts","../src/primitives/config-node.ts"],"names":["Buffer"],"mappings":"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","file":"node.js","sourcesContent":["/**\n * Secret encryption/decryption for agent config files.\n * Uses scrypt (KDF) + AES-256-GCM (cipher).\n * Format: \"encrypted:v1:\" + base64(salt[16] + iv[12] + ciphertext + tag[16])\n *\n * scrypt params: N=2^17, r=8, p=1 (~128 MB RAM per derivation).\n *\n * Node.js/Bun only - not available in browsers.\n * All Node.js APIs are lazy-imported to avoid polluting browser bundles.\n */\n\nconst PREFIX = 'encrypted:v1:';\nconst SALT_LENGTH = 16;\nconst IV_LENGTH = 12;\nconst TAG_LENGTH = 16;\nconst KEY_LENGTH = 32; // AES-256\n// v1: N=2^17 (OWASP minimum). v2 will use N=2^20 with format migration.\nconst SCRYPT_N = 2 ** 17;\nconst SCRYPT_R = 8;\nconst SCRYPT_P = 1;\nconst SCRYPT_MAXMEM = 128 * SCRYPT_N * SCRYPT_R * 2; // 2x the minimum required memory\n\n/** Check if a value is encrypted (has the encrypted:v1: prefix). */\nexport function isEncrypted(value: string): boolean {\n return value.startsWith(PREFIX);\n}\n\n/** Encrypt a plaintext secret with a passphrase. Returns \"encrypted:v1:base64...\". Node.js/Bun only. */\nexport function encryptSecret(plaintext: string, passphrase: string): string {\n if (!passphrase) {\n throw new Error('Passphrase must not be empty.');\n }\n const { scryptSync, randomBytes, createCipheriv } =\n require('node:crypto') as typeof import('node:crypto');\n const { Buffer } = require('node:buffer') as typeof import('node:buffer');\n\n const salt = randomBytes(SALT_LENGTH);\n const key = scryptSync(passphrase, salt, KEY_LENGTH, {\n N: SCRYPT_N,\n r: SCRYPT_R,\n p: SCRYPT_P,\n maxmem: SCRYPT_MAXMEM,\n });\n const iv = randomBytes(IV_LENGTH);\n\n const cipher = createCipheriv('aes-256-gcm', key, iv);\n const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);\n const tag = cipher.getAuthTag();\n\n const payload = Buffer.concat([salt, iv, encrypted, tag]);\n return PREFIX + payload.toString('base64');\n}\n\n/** Decrypt an encrypted secret with a passphrase. Throws on wrong passphrase or corrupted data. Node.js/Bun only. */\nexport function decryptSecret(encrypted: string, passphrase: string): string {\n if (!isEncrypted(encrypted)) {\n throw new Error('Value is not encrypted (missing encrypted:v1: prefix).');\n }\n if (!passphrase) {\n throw new Error('Passphrase must not be empty.');\n }\n\n const { scryptSync, createDecipheriv } = require('node:crypto') as typeof import('node:crypto');\n const { Buffer } = require('node:buffer') as typeof import('node:buffer');\n\n const payload = Buffer.from(encrypted.slice(PREFIX.length), 'base64');\n if (payload.length < SALT_LENGTH + IV_LENGTH + TAG_LENGTH) {\n throw new Error('Encrypted payload is too short.');\n }\n\n const salt = payload.subarray(0, SALT_LENGTH);\n const iv = payload.subarray(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);\n const tag = payload.subarray(payload.length - TAG_LENGTH);\n const ciphertext = payload.subarray(SALT_LENGTH + IV_LENGTH, payload.length - TAG_LENGTH);\n\n const key = scryptSync(passphrase, salt, KEY_LENGTH, {\n N: SCRYPT_N,\n r: SCRYPT_R,\n p: SCRYPT_P,\n maxmem: SCRYPT_MAXMEM,\n });\n\n const decipher = createDecipheriv('aes-256-gcm', key, iv);\n decipher.setAuthTag(tag);\n\n try {\n const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);\n return decrypted.toString('utf8');\n } catch {\n throw new Error('Decryption failed. Wrong passphrase or corrupted data.');\n }\n}\n","/**\n * Node.js-only config parsing with secret decryption.\n * Exported from '@elisym/sdk/node'.\n */\n\nimport type { AgentConfig } from '../types';\nimport { isEncrypted, decryptSecret } from './encryption';\n\n/**\n * Parse a JSON string into an AgentConfig.\n * If passphrase is provided, decrypts all encrypted fields (requires Node.js/Bun).\n * If passphrase is not provided and encrypted fields exist, throws.\n */\nexport function parseConfig(json: string, passphrase?: string): AgentConfig {\n const config = JSON.parse(json) as AgentConfig;\n\n if (!config || typeof config !== 'object' || Array.isArray(config)) {\n throw new Error('Invalid config: expected JSON object.');\n }\n if (!config.identity?.secret_key || typeof config.identity.secret_key !== 'string') {\n throw new Error('Invalid config: missing or non-string identity.secret_key.');\n }\n if (typeof config.identity.name !== 'string' || !config.identity.name) {\n throw new Error('Invalid config: missing or non-string identity.name.');\n }\n if (\n !Array.isArray(config.relays) ||\n !config.relays.every((r: unknown) => typeof r === 'string')\n ) {\n throw new Error('Invalid config: relays must be an array of strings.');\n }\n\n if (config.capabilities !== undefined) {\n if (!Array.isArray(config.capabilities)) {\n throw new Error('Invalid config: capabilities must be an array.');\n }\n for (const cap of config.capabilities) {\n if (\n !cap ||\n typeof cap !== 'object' ||\n typeof cap.name !== 'string' ||\n typeof cap.description !== 'string' ||\n typeof cap.price !== 'number'\n ) {\n throw new Error(\n 'Invalid config: each capability must have name (string), description (string), and price (number).',\n );\n }\n if (!Array.isArray(cap.tags) || !cap.tags.every((t: unknown) => typeof t === 'string')) {\n throw new Error('Invalid config: each capability must have tags (array of strings).');\n }\n if (!Number.isInteger(cap.price) || cap.price < 0) {\n throw new Error(\n 'Invalid config: capability price must be a non-negative integer (lamports).',\n );\n }\n }\n }\n if (config.payments !== undefined) {\n if (!Array.isArray(config.payments)) {\n throw new Error('Invalid config: payments must be an array.');\n }\n for (const p of config.payments) {\n if (\n !p ||\n typeof p !== 'object' ||\n typeof p.chain !== 'string' ||\n typeof p.network !== 'string' ||\n typeof p.address !== 'string'\n ) {\n throw new Error(\n 'Invalid config: each payment entry must have chain, network, and address (all strings).',\n );\n }\n }\n }\n if (config.wallet !== undefined) {\n if (\n !config.wallet ||\n typeof config.wallet !== 'object' ||\n typeof config.wallet.chain !== 'string' ||\n typeof config.wallet.network !== 'string' ||\n typeof config.wallet.secret_key !== 'string'\n ) {\n throw new Error(\n 'Invalid config: wallet must have chain, network, and secret_key (all strings).',\n );\n }\n }\n if (config.llm !== undefined) {\n if (\n !config.llm ||\n typeof config.llm !== 'object' ||\n typeof config.llm.provider !== 'string' ||\n typeof config.llm.model !== 'string' ||\n typeof config.llm.api_key !== 'string' ||\n typeof config.llm.max_tokens !== 'number' ||\n !Number.isInteger(config.llm.max_tokens) ||\n config.llm.max_tokens <= 0\n ) {\n throw new Error(\n 'Invalid config: llm must have provider, model, api_key (strings) and max_tokens (positive integer).',\n );\n }\n }\n\n if (!passphrase) {\n const encrypted: string[] = [];\n if (config.identity?.secret_key && isEncrypted(config.identity.secret_key)) {\n encrypted.push('identity.secret_key');\n }\n if (config.wallet?.secret_key && isEncrypted(config.wallet.secret_key)) {\n encrypted.push('wallet.secret_key');\n }\n if (config.llm?.api_key && isEncrypted(config.llm.api_key)) {\n encrypted.push('llm.api_key');\n }\n if (encrypted.length > 0) {\n throw new Error(\n `Fields [${encrypted.join(', ')}] are encrypted but no passphrase provided. Set ELISYM_PASSPHRASE env var.`,\n );\n }\n return config;\n }\n\n if (config.identity?.secret_key && isEncrypted(config.identity.secret_key)) {\n config.identity.secret_key = decryptSecret(config.identity.secret_key, passphrase);\n }\n if (config.wallet?.secret_key && isEncrypted(config.wallet.secret_key)) {\n config.wallet.secret_key = decryptSecret(config.wallet.secret_key, passphrase);\n }\n if (config.llm?.api_key && isEncrypted(config.llm.api_key)) {\n config.llm.api_key = decryptSecret(config.llm.api_key, passphrase);\n }\n\n return config;\n}\n"]}
@@ -0,0 +1,181 @@
1
+ declare class ElisymIdentity {
2
+ private _secretKey;
3
+ readonly publicKey: string;
4
+ readonly npub: string;
5
+ get secretKey(): Uint8Array;
6
+ private constructor();
7
+ static generate(): ElisymIdentity;
8
+ static fromSecretKey(sk: Uint8Array): ElisymIdentity;
9
+ toJSON(): {
10
+ publicKey: string;
11
+ npub: string;
12
+ };
13
+ /** Best-effort scrub of the secret key bytes in memory. */
14
+ scrub(): void;
15
+ static fromHex(hex: string): ElisymIdentity;
16
+ }
17
+
18
+ interface SubCloser {
19
+ close: (reason?: string) => void;
20
+ }
21
+ /** Capability card published to Nostr (NIP-89). */
22
+ interface CapabilityCard {
23
+ name: string;
24
+ description: string;
25
+ capabilities: string[];
26
+ payment?: PaymentInfo;
27
+ image?: string;
28
+ static?: boolean;
29
+ }
30
+ /** Payment info embedded in capability card (legacy format for on-network events). */
31
+ interface PaymentInfo {
32
+ chain: string;
33
+ network: string;
34
+ address: string;
35
+ /** Price in lamports (must be non-negative integer). */
36
+ job_price?: number;
37
+ }
38
+ /** Agent discovered from the network. */
39
+ interface Agent {
40
+ pubkey: string;
41
+ npub: string;
42
+ cards: CapabilityCard[];
43
+ eventId: string;
44
+ supportedKinds: number[];
45
+ lastSeen: number;
46
+ picture?: string;
47
+ name?: string;
48
+ about?: string;
49
+ }
50
+ type Network = 'mainnet' | 'devnet';
51
+ /**
52
+ * Job lifecycle status.
53
+ * Note: for broadcast jobs (no providerPubkey, no bid), fetchRecentJobs() keeps
54
+ * status as 'processing' even if a provider sent 'payment-required' feedback,
55
+ * because the customer hasn't committed to that provider yet. The real-time
56
+ * payment-required transition is handled by subscribeToJobUpdates().
57
+ */
58
+ type JobStatus = 'payment-required' | 'payment-completed' | 'processing' | 'error' | 'success' | 'partial' | 'unknown';
59
+ interface Job {
60
+ eventId: string;
61
+ customer: string;
62
+ agentPubkey?: string;
63
+ capability?: string;
64
+ bid?: number;
65
+ status: JobStatus;
66
+ result?: string;
67
+ resultEventId?: string;
68
+ amount?: number;
69
+ txHash?: string;
70
+ createdAt: number;
71
+ }
72
+ interface SubmitJobOptions {
73
+ /** Job input text. Sent unencrypted if providerPubkey is not set. */
74
+ input: string;
75
+ capability: string;
76
+ /** Target provider pubkey. If omitted, job is broadcast unencrypted and visible to all relays. */
77
+ providerPubkey?: string;
78
+ /** Kind offset (default 100 - kind 5100). */
79
+ kindOffset?: number;
80
+ }
81
+ interface JobUpdateCallbacks {
82
+ onFeedback?: (status: string, amount?: number, paymentRequest?: string, senderPubkey?: string) => void;
83
+ onResult?: (content: string, eventId: string) => void;
84
+ onError?: (error: string) => void;
85
+ }
86
+ interface JobSubscriptionOptions {
87
+ jobEventId: string;
88
+ providerPubkey?: string;
89
+ customerPublicKey: string;
90
+ callbacks: JobUpdateCallbacks;
91
+ timeoutMs?: number;
92
+ customerSecretKey?: Uint8Array;
93
+ kindOffsets?: number[];
94
+ sinceOverride?: number;
95
+ }
96
+ interface PingResult {
97
+ online: boolean;
98
+ /** The identity used for the ping session - reuse for job submission so pubkeys match. */
99
+ identity: ElisymIdentity | null;
100
+ }
101
+ interface PaymentRequestData {
102
+ recipient: string;
103
+ /** Total amount in lamports (must be positive integer). */
104
+ amount: number;
105
+ reference: string;
106
+ description?: string;
107
+ fee_address?: string;
108
+ fee_amount?: number;
109
+ /** Creation timestamp (Unix seconds). */
110
+ created_at: number;
111
+ /** Expiry duration in seconds. */
112
+ expiry_secs: number;
113
+ }
114
+ interface VerifyResult {
115
+ verified: boolean;
116
+ txSignature?: string;
117
+ error?: string;
118
+ }
119
+ interface VerifyOptions {
120
+ retries?: number;
121
+ intervalMs?: number;
122
+ txSignature?: string;
123
+ }
124
+ type PaymentValidationCode = 'invalid_json' | 'invalid_amount' | 'missing_recipient' | 'invalid_recipient_address' | 'missing_reference' | 'invalid_reference_address' | 'recipient_mismatch' | 'expired' | 'future_timestamp' | 'fee_address_mismatch' | 'fee_amount_mismatch' | 'missing_fee' | 'invalid_fee_params';
125
+ interface PaymentValidationError {
126
+ code: PaymentValidationCode;
127
+ message: string;
128
+ }
129
+ interface NetworkStats {
130
+ totalAgentCount: number;
131
+ agentCount: number;
132
+ jobCount: number;
133
+ totalLamports: number;
134
+ }
135
+ interface ElisymClientConfig {
136
+ relays?: string[];
137
+ }
138
+ interface Identity {
139
+ secret_key: string;
140
+ name: string;
141
+ description?: string;
142
+ picture?: string;
143
+ banner?: string;
144
+ }
145
+ interface Capability {
146
+ name: string;
147
+ description: string;
148
+ tags: string[];
149
+ /** Price in smallest unit (lamports for Solana). */
150
+ price: number;
151
+ /** Hero image URL for app display. */
152
+ image?: string;
153
+ }
154
+ interface PaymentAddress {
155
+ chain: string;
156
+ network: string;
157
+ address: string;
158
+ /** Token mint/contract address. Absent = native coin. */
159
+ token?: string;
160
+ }
161
+ interface WalletConfig {
162
+ chain: string;
163
+ network: string;
164
+ secret_key: string;
165
+ }
166
+ interface LlmConfig {
167
+ provider: string;
168
+ api_key: string;
169
+ model: string;
170
+ max_tokens: number;
171
+ }
172
+ interface AgentConfig {
173
+ identity: Identity;
174
+ relays: string[];
175
+ capabilities?: Capability[];
176
+ payments?: PaymentAddress[];
177
+ wallet?: WalletConfig;
178
+ llm?: LlmConfig;
179
+ }
180
+
181
+ export { type Agent as A, type CapabilityCard as C, ElisymIdentity as E, type Identity as I, type JobSubscriptionOptions as J, type LlmConfig as L, type Network as N, type PaymentRequestData as P, type SubCloser as S, type VerifyOptions as V, type WalletConfig as W, type PaymentValidationError as a, type VerifyResult as b, type SubmitJobOptions as c, type Job as d, type PingResult as e, type ElisymClientConfig as f, type AgentConfig as g, type Capability as h, type JobStatus as i, type JobUpdateCallbacks as j, type NetworkStats as k, type PaymentAddress as l, type PaymentInfo as m, type PaymentValidationCode as n };