rsoft-trust
v0.2.0
Published
RSoft Trust SDK — on-chain trust scores, policy gates and trust-based pricing for AI agents (AgentTrust-8004 on Base). Zero runtime dependencies.
Downloads
222
Maintainers
Readme
rsoft-trust (TypeScript)
On-chain trust scores, policy gates and trust-based pricing for AI agents — the RSoft Trust API (AgentTrust-8004 on Base mainnet) as a zero-dependency SDK. Node 20+, edge runtimes, anything with
fetch.
npm install rsoft-trust # not published yet — build from source, see belowimport { TrustClient } from "rsoft-trust";
const trust = new TrustClient(); // public deployment by default
const r = await trust.evaluate({ wallet: "0xB684…2B13", policy: "financial", includePricing: true, basePriceUsdc: 0.10 });
r.trust_score; // 24
r.trust_tier; // "untrusted" | "limited" | "verified" | "trusted" | "blocked"
r.all_passed; // false
r.gate_results; // [{ gate: "established", passed: false, value: 4.06, threshold: 30 }, …]
r.pricing?.price_multiplier; // 1.64 → suggested_price_usdc 0.164What the score is made of (and what it is not)
Every gate is derived from signals the API reads on-chain, today:
ERC-8004 identity (registered), identity age (established), reputation
clients (active), census coherence (coherent) and the 0–100 score.
There is no KYC, sanctions or off-chain gate — the model does not have one.
Full gate/tier/pricing tables: API README.
Policies
await trust.evaluate({ wallet, policy: "quick" }); // registered
await trust.evaluate({ wallet, policy: "basic" }); // + coherent
await trust.evaluate({ wallet, policy: "standard" }); // + score ≥ 40 (default)
await trust.evaluate({ wallet, policy: "strict" }); // + 90 d, 5 clients, score ≥ 75
await trust.evaluate({ wallet, policy: "financial" }); // + 30 d, 3 clients, score ≥ 50
await trust.evaluate({ wallet, policy: "reputation" }); // weighted vote ≥ 0.60
// custom
await trust.evaluate({
wallet,
policy: { gates: ["registered", { gate: "score", threshold: 60 }], operator: "AND" },
});Express middleware — rsoft-trust/express
import express from "express";
import { trustGate } from "rsoft-trust/express";
app.use("/paid", trustGate({
policy: "financial",
walletFrom: (req) => req.headers["x-wallet"] as string, // or defaultWalletFrom
}));
// on pass: req.trust = EvaluateResponse, X-Trust-Tier header set
// on fail: 403 { error: "trust_gate_failed", trust_score, trust_tier, failed_gates, gate_results }
// no wallet → 401 · bad wallet → 400 · Trust API down → 502 (or next() with failOpen: true)Typed structurally (no @types/express needed); works with any
(req, res, next) framework that has res.status().json().
Fetch helper — rsoft-trust/fetch (edge / Workers / Next route handlers)
import { trustGuard, score, evaluate, pricing } from "rsoft-trust/fetch";
export async function GET(req: Request) {
const g = await trustGuard(req, { policy: "standard" }); // reads X-Wallet or ?wallet=
if (!g.ok) return g.response; // 401 / 400 / 403 / 502 JSON
return Response.json({ tier: g.result.trust_tier });
}
await score("0x…"); // GET /score
await pricing("0x…", 0.10); // GET /pricing → price_multiplier, suggested_price_usdcPricing
includePricing: true (or client.pricing(wallet, base)) returns:
price_multiplier∈ [0.5, 2.0] —2.0 − 1.5·score/100; anomaly or unregistered → 2.0.suggested_interest_rate— indicative annual rate on the RSoft Bank's own scale (its formula in the zero-exposure limit);nullfor CCC/D. The Bank quotes its own rate; this is a hint, not a quote.
Client options
new TrustClient({
baseUrl?: string, // default: public RSoft Trust deployment
apiKey?: string, // sent as X-API-Key; reserved — the public API is unauthenticated today
timeoutMs?: number, // default 45 000 (cold on-chain reads take ~10–30 s)
fetch?: typeof fetch,
});Errors: TrustApiError (.status, .body) for non-2xx / network / timeout;
TypeError for a malformed wallet (checked before any request).
Build from source
cd packages/rsoft-trust-js
npm install && npm run build && npm test
npm publish --dry-runRSoft Bank: payment authorization
The same package ships BankClient for the Bank's POST /authorize — "may this agent
move this money?" — which applies ERC-8004 identity, a bound human sponsor, the sponsor's
kill switch and caps to an action that settles on your rails. Needs a Bank API key.
import { BankClient } from "rsoft-trust";
const bank = new BankClient({ apiKey: process.env.BANK_API_KEY! });
const a = await bank.authorize({ wallet, amount: 42.5, action: "payment", counterparty: "acme.com", reference: "inv-7" });
if (a.decision !== "allow") refuse(a.reason_code, a.next_action); // identity_required | sponsor_required | agent_paused | …
settleWith(a.authorization_jwt); // Bank-signed, 10 minutes
// or: throws TrustApiError(status 200, body = the deny) on deny
await bank.require({ wallet, amount: 42.5 });
const ledger = await bank.authorizations(wallet); // append-only decision logDocs: https://rsoft-agentic-bank.com/docs#authorize
