ncrypted 0.2.0 → 0.3.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/README.md +13 -0
- package/dist/ai-sdk.d.ts +1635 -0
- package/dist/ai-sdk.js +112 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/package.json +27 -7
package/dist/ai-sdk.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Vercel AI SDK tools for ncrypted. Usage:
|
|
2
|
+
// import { ncryptedTools } from "ncrypted/ai-sdk";
|
|
3
|
+
// await generateText({ model, tools: ncryptedTools(), prompt });
|
|
4
|
+
import { tool } from "ai";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { Ncrypted } from "./client.js";
|
|
7
|
+
const errorText = (e) => `Error: ${e.message}`;
|
|
8
|
+
/**
|
|
9
|
+
* Returns AI SDK tools for sharing secrets as one-time, end-to-end encrypted links (and writing them into Vercel env
|
|
10
|
+
* vars without the model seeing them). Encryption happens in your server process. The first 3 secrets per day are
|
|
11
|
+
* free; after that each costs 0.005 USDC on Base, paid via x402 from the configured wallet
|
|
12
|
+
* (NCRYPTED_WALLET_PRIVATE_KEY or ~/.config/ncrypted/wallet.key). Reads and deliveries are free.
|
|
13
|
+
*/
|
|
14
|
+
export function ncryptedTools(options = {}) {
|
|
15
|
+
const { include, ...clientOptions } = options;
|
|
16
|
+
const nc = new Ncrypted({ client: "ai-sdk", ...clientOptions });
|
|
17
|
+
const all = {
|
|
18
|
+
ncrypted_create: tool({
|
|
19
|
+
description: "Encrypt a password, API key, token or private note and return a one-time link that self-destructs after a single read. " +
|
|
20
|
+
"Use it whenever a credential must be shared with a person or another agent, instead of writing the value in a message. " +
|
|
21
|
+
"Never repeat the secret in your reply; share only the link. The first 3 per day are free (TTL up to 24h); then 0.005 USDC each.",
|
|
22
|
+
inputSchema: z.object({
|
|
23
|
+
secret: z.string().min(1).max(65536).describe("The sensitive value. Max 64 KB."),
|
|
24
|
+
ttlSeconds: z.number().int().min(300).max(604800).optional().describe("Expiry if never opened. Default 86400 (24h)."),
|
|
25
|
+
passphrase: z.string().optional().describe("Optional second factor; deliver it through a different channel than the link."),
|
|
26
|
+
emailTo: z.string().email().optional().describe("Email the link to this address (requires a paid secret, i.e. a funded wallet)."),
|
|
27
|
+
}),
|
|
28
|
+
execute: async ({ secret, ttlSeconds, passphrase, emailTo }) => {
|
|
29
|
+
try {
|
|
30
|
+
const r = await nc.create(secret, { ttl: ttlSeconds, passphrase, emailTo });
|
|
31
|
+
return {
|
|
32
|
+
link: r.link,
|
|
33
|
+
id: r.id,
|
|
34
|
+
expiresAt: r.expiresAt,
|
|
35
|
+
receiptToken: r.receiptToken,
|
|
36
|
+
emailed: r.emailed,
|
|
37
|
+
free: r.free,
|
|
38
|
+
note: "The link opens exactly once. Share only the link.",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
return errorText(e);
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
}),
|
|
46
|
+
ncrypted_read: tool({
|
|
47
|
+
description: "Open an ncrypted link (https://ncrypted.ai/s/{id}#{key}) and return the secret. This destroys it permanently. Free. " +
|
|
48
|
+
"Use the value only for the task at hand and do not repeat it.",
|
|
49
|
+
inputSchema: z.object({
|
|
50
|
+
link: z.string().url().describe("The full link including the #key fragment."),
|
|
51
|
+
passphrase: z.string().optional().describe("Required only if the sender set one."),
|
|
52
|
+
}),
|
|
53
|
+
execute: async ({ link, passphrase }) => {
|
|
54
|
+
try {
|
|
55
|
+
return await nc.read(link, passphrase);
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
return errorText(e);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
}),
|
|
62
|
+
ncrypted_status: tool({
|
|
63
|
+
description: "Check whether a secret you created has been opened (pending, read, burned or expired). Free.",
|
|
64
|
+
inputSchema: z.object({ id: z.string(), receiptToken: z.string() }),
|
|
65
|
+
execute: async ({ id, receiptToken }) => {
|
|
66
|
+
try {
|
|
67
|
+
return await nc.status(id, receiptToken);
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
return errorText(e);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
}),
|
|
74
|
+
ncrypted_burn: tool({
|
|
75
|
+
description: "Destroy a secret you created before anyone opens it, e.g. if the link went to the wrong place. Free.",
|
|
76
|
+
inputSchema: z.object({ id: z.string(), receiptToken: z.string() }),
|
|
77
|
+
execute: async ({ id, receiptToken }) => {
|
|
78
|
+
try {
|
|
79
|
+
await nc.burn(id, receiptToken);
|
|
80
|
+
return { burned: true };
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
return errorText(e);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
}),
|
|
87
|
+
ncrypted_to_vercel_env: tool({
|
|
88
|
+
description: "Open an ncrypted link and write its value straight into a Vercel project environment variable (type sensitive), so the value " +
|
|
89
|
+
"is never shown to you. Needs VERCEL_TOKEN. Vercel access is checked before the link is consumed.",
|
|
90
|
+
inputSchema: z.object({
|
|
91
|
+
link: z.string().url(),
|
|
92
|
+
passphrase: z.string().optional(),
|
|
93
|
+
key: z.string().describe("Env var name, e.g. STRIPE_SECRET_KEY."),
|
|
94
|
+
project: z.string().describe("Vercel project name or id."),
|
|
95
|
+
team: z.string().optional().describe("Vercel team id (team_...) or slug."),
|
|
96
|
+
targets: z.array(z.enum(["production", "preview", "development"])).optional().describe("Default: production and preview."),
|
|
97
|
+
}),
|
|
98
|
+
execute: async ({ link, passphrase, key, project, team, targets }) => {
|
|
99
|
+
try {
|
|
100
|
+
const r = await nc.deliver(link, { type: "vercel_env", key, project, team, targets }, { passphrase });
|
|
101
|
+
return { delivered: true, ...r, note: "The value was written directly and was not shown to you." };
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
return errorText(e);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
}),
|
|
108
|
+
};
|
|
109
|
+
if (!include)
|
|
110
|
+
return all;
|
|
111
|
+
return Object.fromEntries(include.map((name) => [name, all[name]]));
|
|
112
|
+
}
|
package/dist/client.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type Destination, type DeliveryResult } from "./destinations.js";
|
|
|
2
2
|
export declare const DEFAULT_BASE_URL = "https://ncrypted.ai";
|
|
3
3
|
/** Hard cap on what the SDK will ever pay for one secret, whatever the server asks. */
|
|
4
4
|
export declare const MAX_PRICE = "$0.01";
|
|
5
|
-
export declare const SDK_VERSION = "0.
|
|
5
|
+
export declare const SDK_VERSION = "0.3.0";
|
|
6
6
|
export interface NcryptedOptions {
|
|
7
7
|
/** API origin. Defaults to NCRYPTED_URL or the hosted service. */
|
|
8
8
|
baseUrl?: string;
|
package/dist/client.js
CHANGED
|
@@ -9,7 +9,7 @@ import { privateKeyToAccount as accountOf } from "viem/accounts";
|
|
|
9
9
|
export const DEFAULT_BASE_URL = "https://ncrypted.ai";
|
|
10
10
|
/** Hard cap on what the SDK will ever pay for one secret, whatever the server asks. */
|
|
11
11
|
export const MAX_PRICE = "$0.01";
|
|
12
|
-
export const SDK_VERSION = "0.
|
|
12
|
+
export const SDK_VERSION = "0.3.0";
|
|
13
13
|
export class NcryptedError extends Error {
|
|
14
14
|
status;
|
|
15
15
|
constructor(message, status) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ncrypted",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "One-time, end-to-end encrypted secrets for AI agents. Pay 0.005 USDC per secret via x402; the note self-destructs after one read.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"./wallet": {
|
|
19
19
|
"types": "./dist/wallet.d.ts",
|
|
20
20
|
"default": "./dist/wallet.js"
|
|
21
|
+
},
|
|
22
|
+
"./ai-sdk": {
|
|
23
|
+
"types": "./dist/ai-sdk.d.ts",
|
|
24
|
+
"default": "./dist/ai-sdk.js"
|
|
21
25
|
}
|
|
22
26
|
},
|
|
23
27
|
"bin": {
|
|
@@ -32,13 +36,15 @@
|
|
|
32
36
|
"node": ">=20"
|
|
33
37
|
},
|
|
34
38
|
"keywords": [
|
|
35
|
-
"secrets",
|
|
36
|
-
"one-time",
|
|
37
|
-
"x402",
|
|
38
39
|
"agents",
|
|
39
|
-
"
|
|
40
|
+
"ai-sdk",
|
|
40
41
|
"encryption",
|
|
41
|
-
"
|
|
42
|
+
"mcp",
|
|
43
|
+
"one-time",
|
|
44
|
+
"secrets",
|
|
45
|
+
"usdc",
|
|
46
|
+
"vercel",
|
|
47
|
+
"x402"
|
|
42
48
|
],
|
|
43
49
|
"scripts": {
|
|
44
50
|
"build": "tsc -p tsconfig.json",
|
|
@@ -52,7 +58,9 @@
|
|
|
52
58
|
"devDependencies": {
|
|
53
59
|
"@types/node": "^24.0.0",
|
|
54
60
|
"typescript": "^5.9.0",
|
|
55
|
-
"vitest": "^5.0.5"
|
|
61
|
+
"vitest": "^5.0.5",
|
|
62
|
+
"ai": "^7.0.143",
|
|
63
|
+
"zod": "^4.6.7"
|
|
56
64
|
},
|
|
57
65
|
"repository": {
|
|
58
66
|
"type": "git",
|
|
@@ -62,5 +70,17 @@
|
|
|
62
70
|
"homepage": "https://github.com/Seidl-Family/ncrypted",
|
|
63
71
|
"publishConfig": {
|
|
64
72
|
"access": "public"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"ai": ">=5",
|
|
76
|
+
"zod": "^3.25.0 || ^4.0.0"
|
|
77
|
+
},
|
|
78
|
+
"peerDependenciesMeta": {
|
|
79
|
+
"ai": {
|
|
80
|
+
"optional": true
|
|
81
|
+
},
|
|
82
|
+
"zod": {
|
|
83
|
+
"optional": true
|
|
84
|
+
}
|
|
65
85
|
}
|
|
66
86
|
}
|