npm.io
2.0.0 • Published 11h ago

legichain

Licence
MIT
Version
2.0.0
Deps
0
Size
131 kB
Vulns
0
Weekly
0

Legichain node SDK v2

Official SDK for the existing Legichain API. KYC v2 integration and migration contains the current wire contract, check flags, asynchronous evidence and submission behavior. Version: 2.0.0; publication status is tracked separately.

import { Legichain } from "legichain";
const client = new Legichain({ apiKey: process.env.LEGICHAIN_API_KEY! });
const flow = await client.kyc.start({ subject_external_id: "customer-42" }, { idem: "customer-42-application" });
const receipt = await flow.evidence("documents", body, "customer-42-front-capture-1");
await flow.wait(receipt.operation_id);
// Upload remaining configured evidence, then:
const submission = await flow.submit();

Legichain Node.js / TypeScript SDK

Official client for the Legichain AML, KYC and Travel Rule API.

npm install legichain
# or
pnpm add legichain
# or
yarn add legichain

npm types License

  • TypeScript-first with full types for every response
  • Native fetch (Node 18+) — zero runtime dependencies
  • Dual ESM + CommonJS build
  • HMAC webhook verification helper

Get an API key

Sign up at https://legichain.com — the Free plan ships with 1 RPS and 300 monthly credits, no card required. Once signed in:

panel.legichain.com → Settings → API Keys → New key

Keys look like lc_live_<22>.sk_live_<44> (production) or lc_test_<22>.sk_test_<44> (test mode, never spends credits). Store them in your secret manager — the secret half is shown once and can't be recovered. See the full API guide for plans, rate limits and reference docs.


Quick start

import { Legichain } from "legichain";

const lc = new Legichain({
  apiKey: process.env.LEGICHAIN_API_KEY!,
  // baseUrl: "https://api.legichain.com",   // override for staging
});

// Screen a person — every response carries summary.recommendation
// so banks can branch in one line.
const r = await lc.screen.person({
  name: "Vladimir Putin",
  country: "RU",
  dob: "1952-10-07",
});

if (r.summary.recommendation === "block") {
  await denyOnboarding(customerId);
} else if (r.summary.recommendation === "review") {
  await queueForCompliance(customerId, r.screening_id);
} else {
  await approveOnboarding(customerId);
}

console.log(`${r.cost_credits} credits spent; ${r.credits_remaining} remaining`);
Company + crypto wallet
const company = await lc.screen.company({
  name: "Rosneft Oil Company",
  country: "RU",
});

const wallet = await lc.screen.crypto({
  address: "0x098B716B8Aaf21512996dC57EB0615e2383E2f96",
});
Batch (sync + async)
// Up to 200 items synchronously
const out = await lc.screen.batch([
  { name: "Acme Trading GmbH" },
  { address: "TVj7RNVH…", chain: "tron" },
  { name: "Maria Lopez", country: "ES" },
]);

// Async batch → result delivered to your webhook
const job = await lc.screen.batchAsync(items);
console.log(job.job_id);             // 01HXYZ…
// later …
console.log(await lc.screen.job(job.job_id));
PDF reports
import { writeFile } from "node:fs/promises";

const pdf = await lc.reports.wallet({
  address: "0x6c0bD2BB04Fda9CBfeBb8DC1208Db32a0F8a4Edd",
  chain: "eth",
});
await writeFile("wallet.pdf", pdf);   // Uint8Array

await writeFile(
  "putin.pdf",
  await lc.reports.person({ name: "Vladimir Putin", country: "RU" }),
);
Idempotency
await lc.screen.person(
  { name: "Maria Lopez" },
  { idem: "onboarding-2026-05-20-7f3c" },
);
// Re-running with the same `idem` within 24 h returns the cached
// response and the `Idempotent-Replay: true` header.
Error handling
import { LegichainError } from "legichain";

try {
  await lc.screen.person({ name: "x" });
} catch (err) {
  if (err instanceof LegichainError) {
    console.log(err.status, err.code, err.detail);
    // err.errors[] for field-level validation problems
  } else {
    throw err;
  }
}

LegichainError.code enumerates everything in the API guide (AUTH_002_INVALID_TOKEN, BIL_001_INSUFFICIENT_CREDITS, RL_001_RATE_LIMITED, …).

Webhook verification
import express from "express";
import { verifyWebhookSignature } from "legichain/webhooks";

const app = express();
app.post(
  "/webhooks/legichain",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const ok = verifyWebhookSignature({
      body:      req.body,
      signature: String(req.headers["legichain-signature"] ?? ""),
      secret:    process.env.LEGICHAIN_WEBHOOK_SECRET!,
    });
    if (!ok) return res.status(401).end();

    const evt = JSON.parse(req.body.toString("utf8"));
    if (evt.event === "screen.batch.completed") {
      // …
    }
    res.json({ ok: true });
  },
);

TypeScript types

Every public response is fully typed — start with ScreeningResponse:

import type {
  Legichain, ScreeningResponse, Hit, HitFlags, ScreeningSummary,
  Recommendation, RiskLevel, ProblemDetails,
} from "legichain";

hit.flags.is_sanctioned, summary.recommendation, summary.top_risk_level, hits[].risk_score — typed everywhere.


Reference

Method Endpoint
lc.screen.person(q) POST /v1/screen/person
lc.screen.company(q) POST /v1/screen/company
lc.screen.crypto(q) POST /v1/screen/crypto
lc.screen.batch(items) POST /v1/screen/batch
lc.screen.batchAsync(items) POST /v1/screen/batch/async
lc.screen.job(jobId) GET /v1/screen/jobs/{id}
lc.reports.wallet(q) POST /v1/reports/wallet (PDF)
lc.reports.person(q) POST /v1/reports/person (PDF)
lc.reports.company(q) POST /v1/reports/company (PDF)
lc.status() GET /v1/status

Versioning & support

Keywords