@fidacy/openclaw-plugin 0.1.1 → 0.1.3
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/CHANGELOG.md +12 -0
- package/dist/index.js +63 -7
- package/openclaw.plugin.json +3 -3
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -18,3 +18,15 @@ First release. Fidacy payment firewall as a native OpenClaw plugin:
|
|
|
18
18
|
fallback; `engineApiKey` enables signed verdicts from the live engine.
|
|
19
19
|
- Built against `openclaw@2026.6.11` plugin-sdk types; bundle is self-contained
|
|
20
20
|
(`openclaw/plugin-sdk/*` external, engine inlined).
|
|
21
|
+
|
|
22
|
+
## 0.1.2 — 2026-07-02
|
|
23
|
+
|
|
24
|
+
- Telemetry: reports `shell: "openclaw-plugin"` + the plugin's own version, so
|
|
25
|
+
ClawHub-native adoption is attributable (was indistinguishable from MCP).
|
|
26
|
+
- DENY responses now point to the `fidacy_upgrade` tool.
|
|
27
|
+
- Inherits the self-documenting first-run config + friendlier boot line.
|
|
28
|
+
|
|
29
|
+
## 0.1.3 — 2026-07-02
|
|
30
|
+
|
|
31
|
+
- Same upgrade micro-trigger system as @fidacy/mcp 0.1.11 (once-per-install,
|
|
32
|
+
value-proven moments only), routed through the fidacy_upgrade tool.
|
package/dist/index.js
CHANGED
|
@@ -4439,7 +4439,7 @@ var DevFidacyCore = class {
|
|
|
4439
4439
|
this.priv = kp.privateKey;
|
|
4440
4440
|
this.pubPem = publicKeyPem(kp.publicKey);
|
|
4441
4441
|
if (kp.ephemeral)
|
|
4442
|
-
console.error("[fidacy]
|
|
4442
|
+
console.error("[fidacy] local firewall active, deny-by-default. Grants are signed with a per-session key (fine for local use); set FIDACY_SIGNING_KEY_B64 for a stable key, or FIDACY_MODE=http to use the hosted core.");
|
|
4443
4443
|
this.mandate = opts.mandate;
|
|
4444
4444
|
this.store = new FileAuditStore(opts.auditLogPath ?? "./fidacy-audit.log");
|
|
4445
4445
|
this.onDecision = opts.onDecision;
|
|
@@ -4564,7 +4564,12 @@ function readConfig() {
|
|
|
4564
4564
|
anon_id: raw.anon_id,
|
|
4565
4565
|
tier: raw.tier === "paid" ? "paid" : "free",
|
|
4566
4566
|
api_key: typeof raw.api_key === "string" ? raw.api_key : null,
|
|
4567
|
-
mandate: raw.mandate
|
|
4567
|
+
mandate: raw.mandate,
|
|
4568
|
+
// Install-state passthrough: dropping these on a read→write cycle would
|
|
4569
|
+
// reset every once-per-install nudge into an every-time nag.
|
|
4570
|
+
created_at: typeof raw.created_at === "string" ? raw.created_at : void 0,
|
|
4571
|
+
nudges: raw.nudges && typeof raw.nudges === "object" ? raw.nudges : void 0,
|
|
4572
|
+
decisions_count: typeof raw.decisions_count === "number" ? raw.decisions_count : void 0
|
|
4568
4573
|
};
|
|
4569
4574
|
} catch {
|
|
4570
4575
|
return null;
|
|
@@ -4578,7 +4583,13 @@ function writeConfig(cfg) {
|
|
|
4578
4583
|
function ensureState() {
|
|
4579
4584
|
const existing = readConfig();
|
|
4580
4585
|
if (existing) return { config: existing, firstRun: false };
|
|
4581
|
-
const config = {
|
|
4586
|
+
const config = {
|
|
4587
|
+
anon_id: randomUUID2(),
|
|
4588
|
+
tier: "free",
|
|
4589
|
+
api_key: null,
|
|
4590
|
+
mandate: { payees: [], categories: ["*"], currency: "USD", perTxMax: 2500, maxTotal: 1e4 },
|
|
4591
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
4592
|
+
};
|
|
4582
4593
|
try {
|
|
4583
4594
|
writeConfig(config);
|
|
4584
4595
|
} catch {
|
|
@@ -4599,7 +4610,11 @@ function resolveMandateRules(cfg) {
|
|
|
4599
4610
|
}
|
|
4600
4611
|
|
|
4601
4612
|
// ../mcp/src/telemetry.ts
|
|
4602
|
-
var CLIENT_VERSION = "0.1.
|
|
4613
|
+
var CLIENT_VERSION = true ? "0.1.3" : "dev";
|
|
4614
|
+
var currentShell = "mcp";
|
|
4615
|
+
function setTelemetryShell(shell) {
|
|
4616
|
+
currentShell = shell;
|
|
4617
|
+
}
|
|
4603
4618
|
function telemetryEnabled() {
|
|
4604
4619
|
const v = (process.env.FIDACY_DISABLE_TELEMETRY ?? "").trim().toLowerCase();
|
|
4605
4620
|
return !(v === "1" || v === "true" || v === "yes");
|
|
@@ -4625,7 +4640,7 @@ function resultOf(status, violatedRule) {
|
|
|
4625
4640
|
}
|
|
4626
4641
|
function record(type, result) {
|
|
4627
4642
|
if (!telemetryEnabled()) return;
|
|
4628
|
-
buffer.push({ type, ts: (/* @__PURE__ */ new Date()).toISOString(), client_version: CLIENT_VERSION, ...result ? { result } : {} });
|
|
4643
|
+
buffer.push({ type, ts: (/* @__PURE__ */ new Date()).toISOString(), client_version: CLIENT_VERSION, shell: currentShell, ...result ? { result } : {} });
|
|
4629
4644
|
if (!flushTimer) {
|
|
4630
4645
|
flushTimer = setTimeout(() => {
|
|
4631
4646
|
void flush();
|
|
@@ -4718,7 +4733,7 @@ function requestUpgrade() {
|
|
|
4718
4733
|
}
|
|
4719
4734
|
|
|
4720
4735
|
// ../mcp/src/provision.ts
|
|
4721
|
-
var CLIENT_VERSION2 = "0.1.
|
|
4736
|
+
var CLIENT_VERSION2 = true ? "0.1.3" : "dev";
|
|
4722
4737
|
function provisionEnabled() {
|
|
4723
4738
|
const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
|
|
4724
4739
|
return !(v === "1" || v === "true" || v === "yes");
|
|
@@ -4753,6 +4768,44 @@ async function autoProvision() {
|
|
|
4753
4768
|
}
|
|
4754
4769
|
}
|
|
4755
4770
|
|
|
4771
|
+
// ../mcp/src/nudges.ts
|
|
4772
|
+
function nudgeOnce(key) {
|
|
4773
|
+
const cfg = readConfig();
|
|
4774
|
+
if (!cfg) return false;
|
|
4775
|
+
if (cfg.nudges?.[key]) return false;
|
|
4776
|
+
cfg.nudges = { ...cfg.nudges ?? {}, [key]: true };
|
|
4777
|
+
try {
|
|
4778
|
+
writeConfig(cfg);
|
|
4779
|
+
} catch {
|
|
4780
|
+
return false;
|
|
4781
|
+
}
|
|
4782
|
+
return true;
|
|
4783
|
+
}
|
|
4784
|
+
function bumpDecisionCount() {
|
|
4785
|
+
const cfg = readConfig();
|
|
4786
|
+
if (!cfg) return 0;
|
|
4787
|
+
const n = (cfg.decisions_count ?? 0) + 1;
|
|
4788
|
+
cfg.decisions_count = n;
|
|
4789
|
+
try {
|
|
4790
|
+
writeConfig(cfg);
|
|
4791
|
+
} catch {
|
|
4792
|
+
}
|
|
4793
|
+
return n;
|
|
4794
|
+
}
|
|
4795
|
+
function decisionNudge(status, violatedRule, upgradeToolName) {
|
|
4796
|
+
const count = bumpDecisionCount();
|
|
4797
|
+
if (status === "DENY" && violatedRule?.startsWith("duplicate_invoice") && nudgeOnce("bec_catch")) {
|
|
4798
|
+
return `That was a duplicate-invoice (BEC) catch \u2014 the #1 payment fraud. On a free account every block like this is server-signed and anchored to Bitcoin: court-grade evidence. Call the ${upgradeToolName} tool to start.`;
|
|
4799
|
+
}
|
|
4800
|
+
if (status === "DENY" && nudgeOnce("first_deny")) {
|
|
4801
|
+
return `Fidacy just blocked this for you \u2014 for server-signed, anchored proof of every block (free account, local history migrates), call the ${upgradeToolName} tool.`;
|
|
4802
|
+
}
|
|
4803
|
+
if (count === 10 && nudgeOnce("milestone_10")) {
|
|
4804
|
+
return `That's 10 actions gated on this install. For a signed, Bitcoin-anchored history of all of them (free account), call the ${upgradeToolName} tool.`;
|
|
4805
|
+
}
|
|
4806
|
+
return null;
|
|
4807
|
+
}
|
|
4808
|
+
|
|
4756
4809
|
// ../mcp/src/assess.ts
|
|
4757
4810
|
var AssessError = class extends Error {
|
|
4758
4811
|
type;
|
|
@@ -4873,6 +4926,7 @@ async function postOnce(fetchImpl, url, headers, payload, timeoutMs) {
|
|
|
4873
4926
|
var core;
|
|
4874
4927
|
function boot() {
|
|
4875
4928
|
if (!core) {
|
|
4929
|
+
setTelemetryShell("openclaw-plugin");
|
|
4876
4930
|
const state = ensureState();
|
|
4877
4931
|
core = makeCore();
|
|
4878
4932
|
if (state.firstRun) recordInstall();
|
|
@@ -4932,8 +4986,10 @@ var index_default = defineToolPlugin({
|
|
|
4932
4986
|
}),
|
|
4933
4987
|
async execute(params, config) {
|
|
4934
4988
|
const d = await boot().decide(params, subjectOf(config));
|
|
4935
|
-
const
|
|
4989
|
+
const base = d.status === "ALLOW" ? `ALLOW (decision ${d.decisionId})${params.invoiceRef ? ` for invoice ${params.invoiceRef}` : ""}. To settle, call the executor with the SAME payee, amount, currency, and idempotencyKey, and set "grant" to EXACTLY this signed value:
|
|
4936
4990
|
${d.grant}` : `DENY (decision ${d.decisionId}). Rule violated: ${d.violatedRule}. No grant issued, this payment cannot proceed. The denial itself is recorded in the tamper-evident, hash-chained audit: call get_audit_proof with decisionId ${d.decisionId} for the proof of what was blocked.`;
|
|
4991
|
+
const nudge = decisionNudge(d.status, d.violatedRule, "fidacy_upgrade");
|
|
4992
|
+
const message = nudge ? `${base} ${nudge}` : base;
|
|
4937
4993
|
return { status: d.status, decisionId: d.decisionId, grant: d.grant, violatedRule: d.violatedRule, message };
|
|
4938
4994
|
}
|
|
4939
4995
|
}),
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "fidacy",
|
|
3
|
-
"name": "Fidacy
|
|
3
|
+
"name": "Fidacy \u2014 Payment 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
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.3",
|
|
6
6
|
"contracts": {
|
|
7
7
|
"tools": [
|
|
8
8
|
"request_payment",
|
|
@@ -48,4 +48,4 @@
|
|
|
48
48
|
"advanced": true
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
}
|
|
51
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fidacy/openclaw-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
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
|
"homepage": "https://fidacy.com",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"openclaw": "2026.6.11",
|
|
56
56
|
"typebox": "1.1.39",
|
|
57
57
|
"typescript": "^5.6.3",
|
|
58
|
-
"@fidacy/
|
|
59
|
-
"@fidacy/
|
|
58
|
+
"@fidacy/firewall": "0.1.0",
|
|
59
|
+
"@fidacy/mcp": "0.1.11"
|
|
60
60
|
},
|
|
61
61
|
"scripts": {
|
|
62
62
|
"build": "node scripts/bundle.mjs",
|