@fidacy/openclaw-plugin 0.2.10 → 0.2.11

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/dist/index.js CHANGED
@@ -4308,10 +4308,23 @@ function lookalikePayee(payee, allowed) {
4308
4308
  }
4309
4309
  return null;
4310
4310
  }
4311
+ function validateMandateCaps(mandate) {
4312
+ const bad = (v) => typeof v !== "number" || !Number.isFinite(v) || v <= 0;
4313
+ if (!mandate.allow || typeof mandate.allow !== "object")
4314
+ return "invalid_mandate:missing_allow";
4315
+ if (bad(mandate.allow.perTxMax))
4316
+ return `invalid_mandate_cap:perTxMax=${String(mandate.allow.perTxMax)}`;
4317
+ if (bad(mandate.allow.maxTotal))
4318
+ return `invalid_mandate_cap:maxTotal=${String(mandate.allow.maxTotal)}`;
4319
+ return null;
4320
+ }
4311
4321
  function evaluate(mandate, req, spentSoFar) {
4312
4322
  const now = Date.now();
4313
4323
  if (mandate.revoked)
4314
4324
  return "mandate_revoked";
4325
+ const badCap = validateMandateCaps(mandate);
4326
+ if (badCap)
4327
+ return badCap;
4315
4328
  if (now < Date.parse(mandate.window.notBefore))
4316
4329
  return "before_mandate_window";
4317
4330
  if (now > Date.parse(mandate.window.notAfter))
@@ -4638,6 +4651,9 @@ import {
4638
4651
  readFileSync,
4639
4652
  writeFileSync
4640
4653
  } from "node:fs";
4654
+ function hasEngineKey(keyOverride) {
4655
+ return Boolean((keyOverride ?? process.env.FIDACY_ENGINE_API_KEY ?? "").trim());
4656
+ }
4641
4657
  function configDir() {
4642
4658
  return process.env.FIDACY_CONFIG_DIR ?? join(homedir(), ".fidacy");
4643
4659
  }
@@ -4698,18 +4714,29 @@ function ensureState() {
4698
4714
  function resolveMandateRules(cfg) {
4699
4715
  const m = cfg?.mandate ?? {};
4700
4716
  const envList = (v) => v === void 0 ? void 0 : v.split(",").map((s) => s.trim()).filter(Boolean);
4701
- const envNum = (v) => v === void 0 || v === "" ? void 0 : Number(v);
4717
+ const envNum = (name, v) => {
4718
+ if (v === void 0 || v.trim() === "") return void 0;
4719
+ const n = Number(v);
4720
+ if (!Number.isFinite(n) || n <= 0) {
4721
+ console.error(
4722
+ `[fidacy] ${name}="${v}" is not a positive number, so it cannot be enforced as a cap. Ignoring it and using the safe default. Write digits only, with no thousands separator, currency symbol or unit (e.g. ${name}=2500).`
4723
+ );
4724
+ return void 0;
4725
+ }
4726
+ return n;
4727
+ };
4728
+ const fileNum = (v) => typeof v === "number" && Number.isFinite(v) && v > 0 ? v : void 0;
4702
4729
  return {
4703
4730
  payees: envList(process.env.FIDACY_ALLOW_PAYEES) ?? m.payees ?? [],
4704
4731
  categories: envList(process.env.FIDACY_ALLOW_CATEGORIES) ?? m.categories ?? ["*"],
4705
4732
  currency: process.env.FIDACY_CURRENCY ?? m.currency ?? "USD",
4706
- perTxMax: envNum(process.env.FIDACY_PER_TX_MAX) ?? m.perTxMax ?? 2500,
4707
- maxTotal: envNum(process.env.FIDACY_MAX_TOTAL) ?? m.maxTotal ?? 1e4
4733
+ perTxMax: envNum("FIDACY_PER_TX_MAX", process.env.FIDACY_PER_TX_MAX) ?? fileNum(m.perTxMax) ?? 2500,
4734
+ maxTotal: envNum("FIDACY_MAX_TOTAL", process.env.FIDACY_MAX_TOTAL) ?? fileNum(m.maxTotal) ?? 1e4
4708
4735
  };
4709
4736
  }
4710
4737
 
4711
4738
  // ../mcp/src/telemetry.ts
4712
- var CLIENT_VERSION = true ? "0.2.10" : "dev";
4739
+ var CLIENT_VERSION = true ? "0.2.11" : "dev";
4713
4740
  function bandOf(amount) {
4714
4741
  if (typeof amount !== "number" || !Number.isFinite(amount) || amount <= 0) return void 0;
4715
4742
  if (amount < 10) return "lt10";
@@ -4897,7 +4924,7 @@ function requestUpgrade() {
4897
4924
  }
4898
4925
 
4899
4926
  // ../mcp/src/provision.ts
4900
- var CLIENT_VERSION2 = true ? "0.2.10" : "dev";
4927
+ var CLIENT_VERSION2 = true ? "0.2.11" : "dev";
4901
4928
  function provisionEnabled() {
4902
4929
  const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
4903
4930
  return !(v === "1" || v === "true" || v === "yes");
@@ -4994,9 +5021,6 @@ function noKeyCta() {
4994
5021
 
4995
5022
  // ../mcp/src/activation.ts
4996
5023
  var FREE_DECISIONS = 20;
4997
- function hasEngineKey(keyOverride) {
4998
- return Boolean((keyOverride ?? process.env.FIDACY_ENGINE_API_KEY ?? "").trim());
4999
- }
5000
5024
  function decisionsUsed() {
5001
5025
  return Math.max(readConfig()?.decisions_count ?? 0, sessionDecisionCount());
5002
5026
  }
@@ -5229,6 +5253,7 @@ var AssessError = class extends Error {
5229
5253
  status;
5230
5254
  details;
5231
5255
  rejection_reasons;
5256
+ billing;
5232
5257
  constructor(opts) {
5233
5258
  super(`Fidacy assess error (${opts.type}, HTTP ${opts.status})`);
5234
5259
  this.name = "AssessError";
@@ -5236,6 +5261,7 @@ var AssessError = class extends Error {
5236
5261
  this.status = opts.status;
5237
5262
  this.details = opts.details;
5238
5263
  this.rejection_reasons = opts.rejection_reasons;
5264
+ this.billing = opts.billing;
5239
5265
  }
5240
5266
  };
5241
5267
  var DEFAULT_TIMEOUT = 1e4;
@@ -5331,7 +5357,12 @@ async function postOnce(fetchImpl, url, headers, payload, timeoutMs) {
5331
5357
  const type = isRecord(parsed) && typeof parsed.error === "string" && parsed.error || `http_${res.status}`;
5332
5358
  const details = isRecord(parsed) ? parsed.details : void 0;
5333
5359
  const rejection_reasons = isRecord(parsed) && Array.isArray(parsed.rejection_reasons) ? parsed.rejection_reasons : void 0;
5334
- throw new AssessError({ type, status: res.status, details, rejection_reasons });
5360
+ const billing = res.status === 402 && isRecord(parsed) ? {
5361
+ reason: typeof parsed.reason === "string" ? parsed.reason : void 0,
5362
+ detail: typeof parsed.detail === "string" ? parsed.detail : void 0,
5363
+ billingUrl: typeof parsed.billing_url === "string" ? parsed.billing_url : void 0
5364
+ } : void 0;
5365
+ throw new AssessError({ type, status: res.status, details, rejection_reasons, billing });
5335
5366
  }
5336
5367
  if (!isRecord(parsed)) {
5337
5368
  throw new AssessError({ type: "invalid_response", status: res.status });
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "id": "fidacy",
3
- "name": "Fidacy Payment Firewall",
3
+ "name": "Fidacy AI Agent Firewall",
4
4
  "description": "A signed, independently-verifiable verdict on every money-moving agent action. Blocks wrong/lookalike payee, over-cap, and duplicate-invoice fraud before money moves. Non-custodial, local-first, deny-by-default.",
5
5
  "icon": "https://fidacy.com/logo.png",
6
- "version": "0.2.10",
6
+ "version": "0.2.11",
7
7
  "contracts": {
8
8
  "tools": [
9
9
  "request_payment",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fidacy/openclaw-plugin",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "description": "Fidacy payment firewall as a native OpenClaw plugin: signed, verifiable verdicts on every money-moving agent action, in-process (no MCP subprocess).",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Fidacy (ZeepCode Group Technology LLC) <hello@fidacy.com> (https://fidacy.com)",
@@ -57,7 +57,7 @@
57
57
  "typebox": "1.1.39",
58
58
  "typescript": "^5.6.3",
59
59
  "@fidacy/firewall": "0.1.1",
60
- "@fidacy/mcp": "0.3.1"
60
+ "@fidacy/mcp": "0.3.3"
61
61
  },
62
62
  "scripts": {
63
63
  "build": "node scripts/bundle.mjs",