fizzl-langchain 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Frits Zwager
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,4 +1,88 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
4
- If no other versions are published within 30 days, this package and version will be deleted.
1
+ # fizzl-langchain
2
+
3
+ Safety checks for [LangChain.js](https://js.langchain.com) and [LangGraph.js](https://langchain-ai.github.io/langgraphjs/) agents that pay. The JavaScript twin of the [official LangChain integration](https://docs.langchain.com/oss/python/integrations/tools) `fizzl` for Python.
4
+
5
+ Five LangChain tools you pass to `createAgent`, `createReactAgent` or `model.bindTools`:
6
+
7
+ | Tool | What the agent checks | Service | Price |
8
+ |---|---|---|---|
9
+ | `check_before_signing` | a transaction, token approval or signature **before signing it**: green / orange / red with reason codes (drainers, unlimited approvals to unknown spenders, look-alike tokens, Permit/Permit2/Seaport signatures that hand over tokens) | [presign-guard](https://presign-guard.fizzl.eu) | $0.01 |
10
+ | `check_xrpl_transaction` | an **XRP Ledger** transaction before signing it: account takeover (SetRegularKey, SignerListSet, master key off), AccountDelete, fake RLUSD (red); partial payments, destinations that refuse or need a tag, risky issuers, DEX orders far below the order book or AMM price (orange) | presign-guard | $0.01 |
11
+ | `check_token` | a token **before buying or accepting it**: honeypot, rug-pull signs, look-alikes (Solana, EVM, and XRPL tokens as `CURRENCY.rIssuer`: clawback, freeze, transfer fee, fake RLUSD) | presign-guard | $0.01 |
12
+ | `check_wallet_approvals` | every open approval of a wallet and which to revoke | presign-guard | $0.02 |
13
+ | `check_endpoint_before_paying` | an x402 or MPP paid API **before paying it**: go / caution / no_go, the cheapest option that settles, budget, track record, bait signs (fake brands, airdrop lures, output that doesn't match) | [x402 Doctor](https://x402-doctor.fizzl.eu) | $0.001 |
14
+
15
+ The tools only check. They never sign, pay or move anything themselves. A failed check comes back to the model as `{ "error", "message" }`, so the agent can tell the user instead of crashing. Each tool returns its answer as a JSON string.
16
+
17
+ ## Install
18
+
19
+ ```sh
20
+ npm install fizzl-langchain @langchain/core zod
21
+ npm install @x402/fetch @x402/evm viem # to pay for the full checks over x402
22
+ ```
23
+
24
+ ## Try it without a wallet
25
+
26
+ ```js
27
+ import { fizzlTools } from "fizzl-langchain";
28
+
29
+ const [checkToken] = fizzlTools({ only: ["check_token"] });
30
+ console.log(await checkToken.invoke({ chain: "base", address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }));
31
+ // {"verdict":"green","grade":"SAFE","free":true,"note":"Free quick check: the verdict only, a few per hour. ..."}
32
+ ```
33
+
34
+ With no paying fetch and no credit keys, `check_token`, `check_before_signing` and `check_endpoint_before_paying` fall back to the free quick checks: the verdict only (green / orange / red, or go / caution / no_go with the problems found), a few per hour, marked `free: true` with a note on what the full check costs. `check_wallet_approvals` and `check_xrpl_transaction` have no free version. Pass `free: false` to get `payment_required` instead.
35
+
36
+ ## Use in an agent
37
+
38
+ ```js
39
+ import { createAgent } from "langchain";
40
+ import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
41
+ import { ExactEvmScheme } from "@x402/evm/exact/client";
42
+ import { privateKeyToAccount } from "viem/accounts";
43
+ import { fizzlTools } from "fizzl-langchain";
44
+
45
+ // Pays for the checks over x402 (USDC on Base). Cap it: a check never costs more than $0.02.
46
+ const payer = new x402Client().setSpendControls({ maxAmountPerPayment: "$0.02" });
47
+ payer.register("eip155:8453", new ExactEvmScheme(privateKeyToAccount(process.env.AGENT_KEY)));
48
+ const pay = wrapFetchWithPayment(fetch, payer);
49
+
50
+ const agent = createAgent({
51
+ model: yourChatModel, // any chat model with tool calling
52
+ tools: [...fizzlTools({ fetch: pay }), ...yourOtherTools],
53
+ systemPrompt: "Before you pay any API, call check_endpoint_before_paying. Before you sign anything, call check_before_signing. Never continue on red or no_go.",
54
+ });
55
+
56
+ const result = await agent.invoke({ messages: [{ role: "user", content: "Buy the BTC funding rate from https://api.example.com/funding for at most $0.05" }] });
57
+ ```
58
+
59
+ With LangGraph: `createReactAgent({ llm, tools: fizzlTools({ fetch: pay }) })` from `@langchain/langgraph/prebuilt`.
60
+
61
+ **Prepaid credits instead of a payment per check:** buy a pack once ([presign-guard](https://presign-guard.fizzl.eu/v1/credits): 100 checks for $0.80; [x402 Doctor](https://x402-doctor.fizzl.eu/api/v1/credits): 1000 preflights for $0.80), then pass the keys and a plain `fetch`:
62
+
63
+ ```js
64
+ fizzlTools({ creditKeys: { presign: process.env.PRESIGN_CREDIT_KEY, doctor: process.env.DOCTOR_CREDIT_KEY } });
65
+ ```
66
+
67
+ **Only some tools:** `fizzlTools({ fetch: pay, only: ["check_endpoint_before_paying", "check_before_signing"] })`.
68
+
69
+ ## Options
70
+
71
+ | Option | Default | |
72
+ |---|---|---|
73
+ | `fetch` | global `fetch` | An x402-paying fetch (`wrapFetchWithPayment` from `@x402/fetch`), or plain fetch with credit keys |
74
+ | `creditKeys` | none | `{ presign, doctor }`, sent as `x-credit-key` |
75
+ | `only` | all five | Tool names to include |
76
+ | `free` | `true` | Fall back to the free quick check (verdict only) when a check can't be paid |
77
+ | `timeoutMs` | 30000 | Per check |
78
+ | `presignUrl`, `doctorUrl` | the fizzl.eu services | For tests or self-hosting |
79
+
80
+ Works with `@langchain/core` 0.3.58+ and 1.x, zod 3.25+ or 4. The checks themselves come from [presign-guard-ai-sdk](https://www.npmjs.com/package/presign-guard-ai-sdk), the same tools for the Vercel AI SDK.
81
+
82
+ ## Want the agent to stop itself, not just be told?
83
+
84
+ The tools inform the model; a model can still ignore them. To make red and over-budget payments impossible, guard the wallet itself with [presign-guard-wallet](https://www.npmjs.com/package/presign-guard-wallet): every signature then goes through presign-guard and your spending limits, with Telegram approval above them. Both together: the agent knows why, and the wallet enforces it.
85
+
86
+ ## License
87
+
88
+ MIT
package/index.d.ts ADDED
@@ -0,0 +1,25 @@
1
+ import type { StructuredToolInterface } from "@langchain/core/tools";
2
+
3
+ export declare const VERSION: string;
4
+ export declare const PRESIGN_URL: string;
5
+ export declare const DOCTOR_URL: string;
6
+ export declare const PRICES: Record<FizzlToolName, string>;
7
+
8
+ export type FizzlToolName = "check_before_signing" | "check_xrpl_transaction" | "check_token" | "check_wallet_approvals" | "check_endpoint_before_paying";
9
+
10
+ export interface FizzlToolsOptions {
11
+ /** fetch that pays x402 (wrapFetchWithPayment from @x402/fetch); plain fetch works with credit keys. */
12
+ fetch?: typeof fetch;
13
+ /** Prepaid credit keys (sent as x-credit-key), per service. */
14
+ creditKeys?: { presign?: string; doctor?: string };
15
+ /** The tools to include (default: all five). */
16
+ only?: FizzlToolName[];
17
+ /** Fall back to the free quick check (verdict only, a few per hour) when a check can't be paid. Default true. */
18
+ free?: boolean;
19
+ presignUrl?: string;
20
+ doctorUrl?: string;
21
+ timeoutMs?: number;
22
+ }
23
+
24
+ /** LangChain tools; each returns the check's answer as a JSON string (or `{ "error", "message" }`). */
25
+ export declare function fizzlTools(options?: FizzlToolsOptions): StructuredToolInterface[];
package/index.js ADDED
@@ -0,0 +1,35 @@
1
+ // Fizzl safety checks as LangChain.js tools, for LangChain and LangGraph agents: check a transaction or
2
+ // signature before signing, a token before buying, a wallet's open approvals, and an x402 endpoint before
3
+ // paying it. Each tool calls a paid Fizzl API (presign-guard or x402 Doctor) through the fetch you pass: an
4
+ // x402-paying fetch (@x402/fetch) or prepaid credit keys. Without either, the free quick check answers
5
+ // (the verdict only, a few per hour).
6
+ //
7
+ // The tools only check; they never sign, pay or move anything themselves. A failed check comes back to the
8
+ // model as { error, message }, never as an exception that ends the run.
9
+ import { tool } from "@langchain/core/tools";
10
+ import { fizzlTools as checks, PRICES, PRESIGN_URL, DOCTOR_URL } from "presign-guard-ai-sdk";
11
+
12
+ export const VERSION = "0.1.0";
13
+ export { PRICES, PRESIGN_URL, DOCTOR_URL };
14
+
15
+ // The same checks as presign-guard-ai-sdk; only the user agent says where the call came from.
16
+ function withUserAgent(fetchImpl) {
17
+ return (url, init = {}) => fetchImpl(url, { ...init, headers: { ...init.headers, "user-agent": `fizzl-langchain/${VERSION}` } });
18
+ }
19
+
20
+ /**
21
+ * The Fizzl checks as LangChain tools: pass them to createAgent, createReactAgent or model.bindTools.
22
+ * @param {object} [options]
23
+ * @param {typeof fetch} [options.fetch] fetch that pays x402 (wrapFetchWithPayment from @x402/fetch); plain fetch works with credit keys
24
+ * @param {{ presign?: string, doctor?: string }} [options.creditKeys] prepaid credit keys (x-credit-key) per service
25
+ * @param {string[]} [options.only] the tool names to include (default: all five)
26
+ * @param {boolean} [options.free] fall back to the free quick checks when a check can't be paid (default true)
27
+ * @param {string} [options.presignUrl] @param {string} [options.doctorUrl] @param {number} [options.timeoutMs]
28
+ */
29
+ export function fizzlTools({ fetch: fetchImpl = globalThis.fetch, ...options } = {}) {
30
+ const defs = checks({ ...options, fetch: withUserAgent(fetchImpl) });
31
+ return Object.entries(defs).map(([name, d]) => tool(
32
+ async (input) => JSON.stringify(await d.execute(input)),
33
+ { name, description: d.description, schema: d.inputSchema },
34
+ ));
35
+ }
package/package.json CHANGED
@@ -1,6 +1,24 @@
1
- {
2
- "name": "fizzl-langchain",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
1
+ {
2
+ "name": "fizzl-langchain",
3
+ "version": "0.1.0",
4
+ "description": "Safety checks for LangChain.js and LangGraph.js agents that pay: tools to check a transaction or signature before signing, a token before buying, a wallet's open approvals, and an x402 endpoint before paying it (presign-guard and x402 Doctor, paid per call over x402, with a free quick check to try them).",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./index.d.ts",
9
+ "default": "./index.js"
10
+ }
11
+ },
12
+ "main": "./index.js",
13
+ "types": "./index.d.ts",
14
+ "files": ["index.js", "index.d.ts", "README.md", "LICENSE"],
15
+ "engines": { "node": ">=20" },
16
+ "scripts": { "test": "node --test test/*.test.mjs", "example": "node example/agent.mjs" },
17
+ "dependencies": { "presign-guard-ai-sdk": "^0.3.0" },
18
+ "peerDependencies": { "@langchain/core": ">=0.3.58 <2.0.0", "zod": "^3.25.0 || ^4.0.0" },
19
+ "devDependencies": { "@langchain/core": "^1.2.0", "@langchain/langgraph": "^1.0.0", "zod": "^4.0.0" },
20
+ "keywords": ["langchain", "langchainjs", "langgraph", "tools", "agents", "x402", "mpp", "wallet", "security", "presign", "token-check", "honeypot", "approvals", "permit2", "usdc", "base", "solana", "xrpl", "rlusd"],
21
+ "repository": { "type": "git", "url": "git+https://github.com/Fizzl13/x402-examples.git", "directory": "fizzl-langchain" },
22
+ "homepage": "https://github.com/Fizzl13/x402-examples/tree/main/fizzl-langchain#readme",
23
+ "license": "MIT"
24
+ }