OceanAltOceanAlt

INTEGRATION GUIDE

Pre-payment checks for LangChain.js agents

Before an agent pays, ask OceanAlt whether the payee is sanctioned or high-risk and whether the payment page is impersonating someone. Each check returns one of three results: allow (no blocking findings), review (a human has to agree first) or decline (don't pay). If a check can't run, the result is review, never allow. The package holds no keys and moves no funds.

Install

npm install @oceanalt/langchain @langchain/core zod

No API key is needed for the free endpoints. Tested with @langchain/core 1.2 (zod 4) and 0.3 (zod 3). Node 20+, ESM.

1. Tools for the model (advisory)

oceanalt_check_payee screens the payee (POST /api/decide) and oceanalt_check_payment_endpoint screens the payment URL (GET /api/endpoint). Both return a JSON string. The model decides whether to call them and whether to follow the answer, so they are advisory.

import { oceanaltTools } from "@oceanalt/langchain";

const tools = [...oceanaltTools(), ...yourTools];
const modelWithTools = model.bindTools(tools);

2. Guard your payment tool (enforced)

guardPaymentTool returns a new tool with the same name, description and schema. On invoke it parses the arguments with the tool's schema and checks the payee: decline throws OceanAltDeclinedError and the original tool does not run; review runs only if onReview returns true, otherwise it throws OceanAltReviewRequiredError; a failed check is treated as review.

import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { guardPaymentTool } from "@oceanalt/langchain";

const transfer = tool(async ({ recipient, amount }) => sendUsdc(recipient, amount), {
  name: "transfer_usdc",
  description: "Send USDC on Base",
  schema: z.object({ recipient: z.string(), amount: z.number() }),
});

// decline -> OceanAltDeclinedError, the transfer does not run.
// review -> runs only if onReview returns true (after a human agreed).
const guardedTransfer = guardPaymentTool(transfer, {
  getPayment: (args) => ({ to: args.recipient, amountUsdc: args.amount, network: "base" }),
  onReview: async (result, args) => askAHuman(result, args),
});
// use guardedTransfer in place of transfer, e.g. createReactAgent({ llm, tools: [guardedTransfer] })

The guard protects only payments that go through the wrapped tool. Another tool, the unwrapped original, or code that calls your wallet directly is not checked.

What comes back

decision, verdict, reason_code, retry, advice, signal_keys and evidence, plus a one-line instruction for the model. Results are screening conclusions over public data, not a guarantee.

npm: @oceanalt/langchain · API reference · All integration options

Not affiliated with LangChain.