@signet-labs/signet-guardian 0.1.0

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/README.md ADDED
@@ -0,0 +1,146 @@
1
+ # Signet Guardian
2
+
3
+ Payment guard middleware for AI agents. Enforces a single policy layer (payments on/off, per-transaction limit, monthly cap) so any payment-capable skill can route through it before and after spending.
4
+
5
+ - **Preflight** — Check if a payment is allowed (ALLOW / DENY / CONFIRM_REQUIRED).
6
+ - **Record** — Append a completed payment to the ledger (enforces monthly cap under lock).
7
+ - **Report** — View spending for today or month.
8
+ - **Policy** — Show or edit limits and rules.
9
+
10
+ Full behaviour and agent contract: see [SKILL.md](./SKILL.md).
11
+
12
+ ## Requirements
13
+
14
+ - Node.js 18+
15
+ - `tsx` (used via `npx`, or install locally)
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ pnpm install
21
+ # or: npm install
22
+ ```
23
+
24
+ ## Configuration
25
+
26
+ **Source of truth:** The CLI reads policy from **OpenClaw config** first (`signet.policy` in e.g. `~/.openclaw/openclaw.json`), then falls back to `references/policy.json`. So you can edit policy in the **Control UI (Dashboard)** if the extension is installed; see [openclaw-extension/README.md](./openclaw-extension/README.md).
27
+
28
+ Policy shape (file or config `signet.policy`). Example:
29
+
30
+ ```json
31
+ {
32
+ "paymentsEnabled": true,
33
+ "maxPerTransaction": 20,
34
+ "maxPerMonth": 500,
35
+ "currency": "GBP",
36
+ "requireConfirmationAbove": 5,
37
+ "blockedMerchants": [],
38
+ "allowedMerchants": []
39
+ }
40
+ ```
41
+
42
+ Create or edit with:
43
+
44
+ ```bash
45
+ npx tsx scripts/signet-cli.ts signet-policy --edit
46
+ ```
47
+
48
+ Interactive wizard (no JSON editing):
49
+
50
+ ```bash
51
+ npx tsx scripts/signet-cli.ts signet-policy --wizard
52
+ ```
53
+
54
+ Migrate existing file-based policy into OpenClaw config (one-time):
55
+
56
+ ```bash
57
+ npx tsx scripts/signet-cli.ts signet-policy --migrate-file-to-config
58
+ ```
59
+
60
+ ## Seeing Signet in the OpenClaw dashboard
61
+
62
+ ### Install from GitHub (manual)
63
+
64
+ If you cloned this repo, the dashboard will show Signet only after the plugin is in OpenClaw’s extensions path.
65
+
66
+ 1. **Open the dashboard**
67
+
68
+ ```bash
69
+ openclaw dashboard
70
+ ```
71
+
72
+ (or visit <http://127.0.0.1:18789/>)
73
+
74
+ 2. **Install the plugin into the OpenClaw extensions path** (not only inside the skills repo):
75
+
76
+ ```bash
77
+ mkdir -p ~/.openclaw/workspace/.openclaw/extensions
78
+ cp -r ~/.openclaw/workspace/skills/signet-guardian/openclaw-extension/signet-guardian \
79
+ ~/.openclaw/workspace/.openclaw/extensions/
80
+ ```
81
+
82
+ Adjust the source path if your clone lives elsewhere (e.g. `$PWD/openclaw-extension/signet-guardian`).
83
+
84
+ 3. **Restart the gateway**
85
+
86
+ ```bash
87
+ openclaw gateway restart
88
+ ```
89
+
90
+ 4. **In the dashboard** go to **Settings → Config** and look under:
91
+ - `plugins.entries.signet-guardian.config.policy`
92
+ That’s where the Signet policy UI should appear.
93
+
94
+ If it doesn’t, run:
95
+
96
+ ```bash
97
+ openclaw plugins list | grep -i signet
98
+ ```
99
+
100
+ and use the output to verify the plugin is loaded.
101
+
102
+ ### Install via plugin (recommended when published)
103
+
104
+ When Signet is published as an OpenClaw plugin (e.g. on npm), install it with the plugin installer so the dashboard picks it up with no manual copy:
105
+
106
+ ```bash
107
+ openclaw plugins install @signet-labs/signet-guardian
108
+ openclaw gateway restart
109
+ openclaw dashboard
110
+ ```
111
+
112
+ Then you’ll see `plugins.entries.signet-guardian.config.policy` in the config UI automatically. The plugin is installed under `~/.openclaw/extensions/<id>/` and enabled for you.
113
+
114
+ *(Until the package is published, use the “Install from GitHub (manual)” steps above.)*
115
+
116
+ ## Usage
117
+
118
+ Use the project’s `references/` by setting the skill dir:
119
+
120
+ ```bash
121
+ export OPENCLAW_SKILL_DIR="$PWD" # or OPENCLAW_BASE_DIR="$PWD"
122
+ ```
123
+
124
+ | Command | Purpose |
125
+ |--------|--------|
126
+ | `npx tsx scripts/signet-cli.ts signet-policy --show` | Print current policy (config, then file) |
127
+ | `npx tsx scripts/signet-cli.ts signet-policy --edit` | Edit policy file in `$EDITOR` |
128
+ | `npx tsx scripts/signet-cli.ts signet-policy --wizard` | Interactive policy setup |
129
+ | `npx tsx scripts/signet-cli.ts signet-policy --migrate-file-to-config` | Copy file policy into OpenClaw config |
130
+ | `npx tsx scripts/signet-cli.ts signet-preflight --amount 10 --currency GBP --payee "shop.com" --purpose "Order"` | Check if payment is allowed |
131
+ | `npx tsx scripts/signet-cli.ts signet-record --amount 10 --currency GBP --payee "shop.com" --purpose "Order" --idempotency-key "order-123"` | Record a completed payment |
132
+ | `npx tsx scripts/signet-cli.ts signet-report --period month` | Show spending for the month |
133
+
134
+ Preflight returns JSON: `{"result":"ALLOW","reason":"..."}` or `"DENY"` / `"CONFIRM_REQUIRED"`. Exit code is 0 for ALLOW/CONFIRM_REQUIRED and 1 for DENY.
135
+
136
+ ## Testing
137
+
138
+ Run the script that uses the repo’s `references/` and exercises preflight, record, and report:
139
+
140
+ ```bash
141
+ ./test-guardian.sh
142
+ ```
143
+
144
+ ## License
145
+
146
+ See repository.
package/SKILL.md ADDED
@@ -0,0 +1,133 @@
1
+ ---
2
+ name: signet-guardian
3
+ description: "Payment guard middleware for AI agents. Use whenever any skill is about to initiate a payment. Runs a preflight check against the user's policy (payments enabled, per-transaction limit, monthly cap). Returns ALLOW, DENY, or CONFIRM_REQUIRED. Other payment-capable skills must call signet-preflight before proceeding and signet-record after a successful payment."
4
+ metadata: {"openclaw":{"emoji":"🛡️","homepage":"https://getsignet.xyz"}}
5
+ ---
6
+
7
+ # Signet Guardian — Payment Guard Middleware
8
+
9
+ ## Overview
10
+
11
+ Signet Guardian is a **policy firewall** for money actions. It does not intercept payments at runtime by itself; **payment-capable skills must route through it by contract**:
12
+
13
+ 1. Before any payment: call **signet-preflight** (amount, currency, payee, purpose).
14
+ 2. If result is **ALLOW** or **CONFIRM_REQUIRED** (and user has confirmed): the skill may proceed.
15
+ 3. If result is **DENY**: do **not** proceed; tell the user the reason.
16
+ 4. After a successful payment: call **signet-record** to append to the ledger.
17
+
18
+ This gives one place to enforce: master switch (payments on/off), max per transaction (e.g. £20), max per month (e.g. £500), and optional confirmation above a threshold (e.g. £5).
19
+
20
+ **Concurrency:** Preflight is advisory (no lock). **Record enforces the monthly cap under a file lock** (`{baseDir}/references/.ledger.lock`): it re-checks the cap before appending and refuses to record if the month would be exceeded. So the monthly limit is enforced at record time; idempotency and cap are both safe under concurrent calls. Preflight can still be used to fail fast; the definitive check is in record.
21
+
22
+ **Currency:** No FX conversion. The request currency **must match** the policy currency; otherwise preflight returns DENY. Conversion source/rules are not defined.
23
+
24
+ ## Policy (user configuration)
25
+
26
+ **Source of truth:** OpenClaw config first (`signet.policy` in the main config, e.g. editable in the Control UI if the extension is installed), then fallback to `{baseDir}/references/policy.json`. OpenClaw sets `{baseDir}` via `OPENCLAW_SKILL_DIR` or `OPENCLAW_BASE_DIR`.
27
+
28
+ | Field | Meaning |
29
+ |-------|--------|
30
+ | `paymentsEnabled` | Master switch. If `false`, all payments are denied. |
31
+ | `maxPerTransaction` | Max amount allowed for a single transaction (e.g. 20). |
32
+ | `maxPerMonth` | Max total spend in the current calendar month (e.g. 500). |
33
+ | `currency` | ISO currency code (e.g. GBP, USD). Request currency must match. |
34
+ | `requireConfirmationAbove` | Above this amount, return CONFIRM_REQUIRED so the user must explicitly confirm (e.g. 5). |
35
+ | `blockedMerchants` | Optional list of substrings; payee matching any is denied. |
36
+ | `allowedMerchants` | Optional; if non-empty, only payees matching one of these are allowed. |
37
+ | `version` | Optional number for future policy migrations. |
38
+
39
+ **Default behaviour:** If the policy file is missing or invalid, **preflight returns DENY** (default-deny).
40
+
41
+ ## Commands
42
+
43
+ ### `signet-preflight`
44
+
45
+ Run **before** initiating any payment. Validates: payments enabled, currency match, amount > 0 and ≤ max per transaction, (current month spend + amount) ≤ max per month, and optional merchant rules. Optionally requires explicit confirmation above a threshold. Amount must be greater than zero.
46
+
47
+ ```bash
48
+ signet-preflight --amount 15 --currency GBP --payee "shop.example.com" --purpose "Subscription"
49
+ ```
50
+
51
+ Optional:
52
+
53
+ - `--idempotency-key "unique-key"` — Used when recording later to avoid duplicate ledger entries.
54
+ - `--caller-skill "skill-name"` — Name of the skill invoking the guard (for audit).
55
+
56
+ **Output (JSON):**
57
+
58
+ - `{ "result": "ALLOW", "reason": "Within policy" }` — Proceed with the payment.
59
+ - `{ "result": "CONFIRM_REQUIRED", "reason": "..." }` — Ask the user for explicit confirmation; if they agree, proceed then call signet-record. (Confirmation is the caller’s responsibility.)
60
+ - `{ "result": "DENY", "reason": "..." }` — Do **not** proceed. Notify the user.
61
+
62
+ Every DENY is logged to the audit trail.
63
+
64
+ **Exit code:** 0 for ALLOW or CONFIRM_REQUIRED, 1 for DENY.
65
+
66
+ ### `signet-record`
67
+
68
+ Call **after** a payment has successfully been made. Appends one line to the ledger (append-only). If an idempotency key was used in preflight, pass the same key here to avoid double-counting.
69
+
70
+ **Record validation scope:** `signet-record` re-checks only **currency** and **monthly cap** (under lock). It does **not** re-check `paymentsEnabled` or merchant allow/block lists. Policy enforcement (switch, merchants, per-tx limit) is done at **preflight** (and in an optional future authorize phase). Record is the post-success log; the cap check at record time prevents double-counting when concurrent preflights both allowed.
71
+
72
+ ```bash
73
+ signet-record --amount 15 --currency GBP --payee "shop.example.com" --purpose "Subscription" --idempotency-key "sub-123"
74
+ ```
75
+
76
+ Optional: `--caller-skill "skill-name"` for audit.
77
+
78
+ If the same `idempotency-key` was already recorded, the command is a no-op (idempotent).
79
+
80
+ ### `signet-report`
81
+
82
+ Shows spending and transaction history for the user.
83
+
84
+ ```bash
85
+ signet-report --period today
86
+ signet-report --period month
87
+ ```
88
+
89
+ ### `signet-policy`
90
+
91
+ Show, edit, or configure policy via wizard.
92
+
93
+ ```bash
94
+ signet-policy --show # Print current policy (config, then file)
95
+ signet-policy --edit # Open policy.json in $EDITOR
96
+ signet-policy --wizard # Interactive step-by-step setup (no JSON)
97
+ signet-policy --migrate-file-to-config # One-time: copy file policy into OpenClaw config
98
+ ```
99
+
100
+ ## Audit (ledger and deny log)
101
+
102
+ Ledger file: `{baseDir}/references/ledger.jsonl`. Format is **strict JSONL**: one JSON object per line, **newline-separated** (no space between entries). Each line contains:
103
+
104
+ - **ts** — Timestamp UTC (ISO 8601).
105
+ - **callerSkill** — Optional; skill that invoked preflight/record.
106
+ - **idempotencyKey** — Optional; dedupe key for record.
107
+ - **status** — `completed` or `denied`.
108
+ - **reason** — Decision reason (especially for denials).
109
+ - Plus: amount, currency, payee, purpose.
110
+
111
+ All preflight denials are appended to the same ledger with `status: "denied"` and a reason.
112
+
113
+ ## Critical Rules (for the agent)
114
+
115
+ 1. **Never skip preflight** — Any payment from any skill must go through `signet-preflight` first. No exceptions.
116
+ 2. **Respect DENY** — If preflight returns DENY, do not attempt the payment. Tell the user the reason.
117
+ 3. **CONFIRM_REQUIRED** — If preflight returns CONFIRM_REQUIRED, ask the user explicitly (“Allow this payment of £X to Y?”). Only proceed if they confirm, then call `signet-record`.
118
+ 4. **Always record success** — After a successful payment, call `signet-record` with the same amount, currency, payee, purpose, and idempotency key (if used).
119
+ 5. **Idempotency** — For critical flows, use a stable `--idempotency-key` (e.g. order ID or request ID) so retries do not double-count in the monthly total.
120
+ 6. **Default-deny** — If the policy file is missing or corrupt, the skill denies by default.
121
+ 7. **Record is authoritative for cap only** — The monthly cap is enforced when recording (under lock). If `signet-record` fails with a cap error, the payment already happened; do not retry without user confirmation. For cap-safe flows before payment, a future **authorize** (reservation under lock) then **settle** (convert reservation to completed) pattern can reserve budget before the payment is made.
122
+
123
+ ## First Run
124
+
125
+ On first use, the user must have a valid `{baseDir}/references/policy.json`. Run `signet-policy --show` to see current policy; if missing, create it (e.g. via `signet-policy --edit`) with at least:
126
+
127
+ - `paymentsEnabled`: true/false
128
+ - `maxPerTransaction`: number
129
+ - `maxPerMonth`: number
130
+ - `currency`: e.g. "GBP"
131
+ - `requireConfirmationAbove`: number (e.g. 5)
132
+
133
+ Ledger lives at `{baseDir}/references/ledger.jsonl`; no extra setup required.
@@ -0,0 +1,37 @@
1
+ # Signet Guardian — OpenClaw extension
2
+
3
+ This folder registers the **Signet Guardian** policy in the OpenClaw config schema so the **Control UI (Dashboard)** can show editable settings instead of raw JSON.
4
+
5
+ ## What it provides
6
+
7
+ - **Config schema** for `signet.policy` (paymentsEnabled, maxPerTransaction, maxPerMonth, currency, requireConfirmationAbove, blockedMerchants, allowedMerchants).
8
+ - **UI hints** (labels, help text, order, group) so the dashboard renders friendly form fields in Settings.
9
+
10
+ ## Install into OpenClaw workspace
11
+
12
+ Copy or link this folder into your OpenClaw workspace extensions:
13
+
14
+ ```bash
15
+ # From the signet-guardian repo root
16
+ OPENCLAW_EXT=~/.openclaw/workspace/.openclaw/extensions
17
+ mkdir -p "$OPENCLAW_EXT"
18
+ cp -r openclaw-extension/signet-guardian "$OPENCLAW_EXT/"
19
+ # or: ln -s "$PWD/openclaw-extension/signet-guardian" "$OPENCLAW_EXT/signet-guardian"
20
+ ```
21
+
22
+ Exact path may depend on your OpenClaw version; check Gateway docs for where it loads extensions.
23
+
24
+ ## Runtime behavior
25
+
26
+ - **CLI** reads policy from OpenClaw config first (`signet.policy`), then falls back to `references/policy.json`.
27
+ - **Dashboard** edits write to the OpenClaw config; the CLI will pick them up on the next run.
28
+ - To migrate an existing file-based policy into config once:
29
+ `signet-policy --migrate-file-to-config`
30
+
31
+ ## Verifying
32
+
33
+ 1. After installing the extension, open the Control UI Settings.
34
+ 2. Confirm a “Signet Guardian” or “signet.policy” section with toggles and number fields.
35
+ 3. Change a value (e.g. max per transaction) and save.
36
+ 4. Run: `npx tsx scripts/signet-cli.ts signet-policy --show`
37
+ The printed policy should match what you set in the dashboard.
@@ -0,0 +1,138 @@
1
+ /**
2
+ * OpenClaw extension: Signet Guardian policy config schema + UI hints.
3
+ * Register signet.policy in the Gateway config so the Control UI can render
4
+ * editable fields in Settings.
5
+ *
6
+ * Install: copy or link this folder into your OpenClaw workspace:
7
+ * .openclaw/extensions/signet-guardian/
8
+ * (e.g. from this repo: openclaw-extension/signet-guardian/)
9
+ */
10
+
11
+ export const version = 1;
12
+ export const generatedAt = new Date().toISOString();
13
+
14
+ /** Schema fragment for signet.policy. Merge into Gateway config.schema. */
15
+ export const schema = {
16
+ signet: {
17
+ type: 'object',
18
+ description: 'Signet Guardian payment guard',
19
+ properties: {
20
+ policy: {
21
+ type: 'object',
22
+ description: 'Payment policy (limits, switch, merchants)',
23
+ properties: {
24
+ paymentsEnabled: {
25
+ type: 'boolean',
26
+ description: 'Master switch for payments',
27
+ default: false,
28
+ },
29
+ maxPerTransaction: {
30
+ type: 'number',
31
+ minimum: 0,
32
+ description: 'Max amount per single transaction',
33
+ default: 20,
34
+ },
35
+ maxPerMonth: {
36
+ type: 'number',
37
+ minimum: 0,
38
+ description: 'Max total spend in the current calendar month',
39
+ default: 500,
40
+ },
41
+ currency: {
42
+ type: 'string',
43
+ pattern: '^[A-Z]{3}$',
44
+ description: 'ISO 4217 currency code (e.g. GBP, USD)',
45
+ default: 'GBP',
46
+ },
47
+ requireConfirmationAbove: {
48
+ type: 'number',
49
+ minimum: 0,
50
+ description: 'Above this amount, require explicit user confirmation',
51
+ default: 5,
52
+ },
53
+ blockedMerchants: {
54
+ type: 'array',
55
+ items: { type: 'string' },
56
+ description: 'Payee substrings to block',
57
+ default: [],
58
+ },
59
+ allowedMerchants: {
60
+ type: 'array',
61
+ items: { type: 'string' },
62
+ description: 'If non-empty, only these payee substrings are allowed',
63
+ default: [],
64
+ },
65
+ },
66
+ default: {
67
+ paymentsEnabled: false,
68
+ maxPerTransaction: 20,
69
+ maxPerMonth: 500,
70
+ currency: 'GBP',
71
+ requireConfirmationAbove: 5,
72
+ blockedMerchants: [],
73
+ allowedMerchants: [],
74
+ },
75
+ },
76
+ },
77
+ },
78
+ } as const;
79
+
80
+ /** UI hints keyed by config path. Control UI uses these for labels and help. */
81
+ export const uiHints: Record<string, { label?: string; help?: string; group?: string; order?: number; advanced?: boolean; sensitive?: boolean; placeholder?: string }> = {
82
+ 'signet.policy': {
83
+ label: 'Signet Guardian — Payment policy',
84
+ help: 'Payment guard: master switch, per-transaction and monthly limits, currency, confirmation threshold, and merchant allow/block lists.',
85
+ group: 'Skills',
86
+ order: 100,
87
+ },
88
+ 'signet.policy.paymentsEnabled': {
89
+ label: 'Enable payments',
90
+ help: 'Master switch. If off, all payments are denied.',
91
+ order: 1,
92
+ },
93
+ 'signet.policy.maxPerTransaction': {
94
+ label: 'Max per transaction',
95
+ help: 'Maximum amount allowed for a single payment (e.g. 20).',
96
+ placeholder: '20',
97
+ order: 2,
98
+ },
99
+ 'signet.policy.maxPerMonth': {
100
+ label: 'Max per month',
101
+ help: 'Maximum total spend in the current calendar month (e.g. 500).',
102
+ placeholder: '500',
103
+ order: 3,
104
+ },
105
+ 'signet.policy.currency': {
106
+ label: 'Currency',
107
+ help: 'ISO 4217 code, 3 letters uppercase (e.g. GBP, USD).',
108
+ placeholder: 'GBP',
109
+ order: 4,
110
+ },
111
+ 'signet.policy.requireConfirmationAbove': {
112
+ label: 'Require confirmation above',
113
+ help: 'Above this amount, the agent must ask for explicit user confirmation before paying.',
114
+ placeholder: '5',
115
+ order: 5,
116
+ },
117
+ 'signet.policy.blockedMerchants': {
118
+ label: 'Blocked merchants',
119
+ help: 'Comma-separated or list of payee substrings to block (e.g. gambling, adult).',
120
+ order: 6,
121
+ },
122
+ 'signet.policy.allowedMerchants': {
123
+ label: 'Allowed merchants',
124
+ help: 'If set, only payees matching one of these substrings are allowed. Leave empty to allow all (subject to blocked list).',
125
+ order: 7,
126
+ advanced: true,
127
+ },
128
+ };
129
+
130
+ /** Validation: requireConfirmationAbove <= maxPerTransaction (soft warning). */
131
+ export function validateSignetPolicy(p: { requireConfirmationAbove?: number; maxPerTransaction?: number }): string | null {
132
+ const above = Number(p?.requireConfirmationAbove ?? 5);
133
+ const max = Number(p?.maxPerTransaction ?? 20);
134
+ if (above > max) return `Confirmation threshold (${above}) should not exceed max per transaction (${max}).`;
135
+ return null;
136
+ }
137
+
138
+ export default { schema, uiHints, version, generatedAt, validateSignetPolicy };
@@ -0,0 +1,88 @@
1
+ {
2
+ "id": "signet-guardian",
3
+ "name": "Signet Guardian",
4
+ "description": "Payment guard middleware: policy (payments on/off, per-transaction and monthly limits) for AI agent payments.",
5
+ "version": "0.1.0",
6
+ "configSchema": {
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "paymentsEnabled": {
11
+ "type": "boolean",
12
+ "description": "Master switch for payments",
13
+ "default": false
14
+ },
15
+ "maxPerTransaction": {
16
+ "type": "number",
17
+ "minimum": 0,
18
+ "description": "Max amount per single transaction",
19
+ "default": 20
20
+ },
21
+ "maxPerMonth": {
22
+ "type": "number",
23
+ "minimum": 0,
24
+ "description": "Max total spend in the current calendar month",
25
+ "default": 500
26
+ },
27
+ "currency": {
28
+ "type": "string",
29
+ "pattern": "^[A-Z]{3}$",
30
+ "description": "ISO 4217 currency code (e.g. GBP, USD)",
31
+ "default": "GBP"
32
+ },
33
+ "requireConfirmationAbove": {
34
+ "type": "number",
35
+ "minimum": 0,
36
+ "description": "Above this amount, require explicit user confirmation",
37
+ "default": 5
38
+ },
39
+ "blockedMerchants": {
40
+ "type": "array",
41
+ "items": { "type": "string" },
42
+ "description": "Payee substrings to block",
43
+ "default": []
44
+ },
45
+ "allowedMerchants": {
46
+ "type": "array",
47
+ "items": { "type": "string" },
48
+ "description": "If non-empty, only these payee substrings are allowed",
49
+ "default": []
50
+ }
51
+ }
52
+ },
53
+ "uiHints": {
54
+ "paymentsEnabled": {
55
+ "label": "Enable payments",
56
+ "help": "Master switch. If off, all payments are denied."
57
+ },
58
+ "maxPerTransaction": {
59
+ "label": "Max per transaction",
60
+ "help": "Maximum amount allowed for a single payment (e.g. 20).",
61
+ "placeholder": "20"
62
+ },
63
+ "maxPerMonth": {
64
+ "label": "Max per month",
65
+ "help": "Maximum total spend in the current calendar month (e.g. 500).",
66
+ "placeholder": "500"
67
+ },
68
+ "currency": {
69
+ "label": "Currency",
70
+ "help": "ISO 4217 code, 3 letters uppercase (e.g. GBP, USD).",
71
+ "placeholder": "GBP"
72
+ },
73
+ "requireConfirmationAbove": {
74
+ "label": "Require confirmation above",
75
+ "help": "Above this amount, the agent must ask for explicit user confirmation before paying.",
76
+ "placeholder": "5"
77
+ },
78
+ "blockedMerchants": {
79
+ "label": "Blocked merchants",
80
+ "help": "Payee substrings to block (e.g. gambling, adult)."
81
+ },
82
+ "allowedMerchants": {
83
+ "label": "Allowed merchants",
84
+ "help": "If set, only payees matching one of these substrings are allowed. Leave empty to allow all.",
85
+ "advanced": true
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,88 @@
1
+ {
2
+ "id": "signet-guardian",
3
+ "name": "Signet Guardian",
4
+ "description": "Payment guard middleware: policy (payments on/off, per-transaction and monthly limits) for AI agent payments.",
5
+ "version": "0.1.0",
6
+ "configSchema": {
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "paymentsEnabled": {
11
+ "type": "boolean",
12
+ "description": "Master switch for payments",
13
+ "default": false
14
+ },
15
+ "maxPerTransaction": {
16
+ "type": "number",
17
+ "minimum": 0,
18
+ "description": "Max amount per single transaction",
19
+ "default": 20
20
+ },
21
+ "maxPerMonth": {
22
+ "type": "number",
23
+ "minimum": 0,
24
+ "description": "Max total spend in the current calendar month",
25
+ "default": 500
26
+ },
27
+ "currency": {
28
+ "type": "string",
29
+ "pattern": "^[A-Z]{3}$",
30
+ "description": "ISO 4217 currency code (e.g. GBP, USD)",
31
+ "default": "GBP"
32
+ },
33
+ "requireConfirmationAbove": {
34
+ "type": "number",
35
+ "minimum": 0,
36
+ "description": "Above this amount, require explicit user confirmation",
37
+ "default": 5
38
+ },
39
+ "blockedMerchants": {
40
+ "type": "array",
41
+ "items": { "type": "string" },
42
+ "description": "Payee substrings to block",
43
+ "default": []
44
+ },
45
+ "allowedMerchants": {
46
+ "type": "array",
47
+ "items": { "type": "string" },
48
+ "description": "If non-empty, only these payee substrings are allowed",
49
+ "default": []
50
+ }
51
+ }
52
+ },
53
+ "uiHints": {
54
+ "paymentsEnabled": {
55
+ "label": "Enable payments",
56
+ "help": "Master switch. If off, all payments are denied."
57
+ },
58
+ "maxPerTransaction": {
59
+ "label": "Max per transaction",
60
+ "help": "Maximum amount allowed for a single payment (e.g. 20).",
61
+ "placeholder": "20"
62
+ },
63
+ "maxPerMonth": {
64
+ "label": "Max per month",
65
+ "help": "Maximum total spend in the current calendar month (e.g. 500).",
66
+ "placeholder": "500"
67
+ },
68
+ "currency": {
69
+ "label": "Currency",
70
+ "help": "ISO 4217 code, 3 letters uppercase (e.g. GBP, USD).",
71
+ "placeholder": "GBP"
72
+ },
73
+ "requireConfirmationAbove": {
74
+ "label": "Require confirmation above",
75
+ "help": "Above this amount, the agent must ask for explicit user confirmation before paying.",
76
+ "placeholder": "5"
77
+ },
78
+ "blockedMerchants": {
79
+ "label": "Blocked merchants",
80
+ "help": "Payee substrings to block (e.g. gambling, adult)."
81
+ },
82
+ "allowedMerchants": {
83
+ "label": "Allowed merchants",
84
+ "help": "If set, only payees matching one of these substrings are allowed. Leave empty to allow all.",
85
+ "advanced": true
86
+ }
87
+ }
88
+ }
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@signet-labs/signet-guardian",
3
+ "version": "0.1.0",
4
+ "description": "Payment guard middleware for OpenClaw: policy (payments on/off, per-transaction and monthly limits) for AI agent payments.",
5
+ "type": "module",
6
+ "main": "openclaw-extension/signet-guardian/index.ts",
7
+ "scripts": {
8
+ "build": "tsc scripts/signet-cli.ts --outDir dist --module esnext --target es2020 --moduleResolution node"
9
+ },
10
+ "openclaw": {
11
+ "extensions": ["./openclaw-extension/signet-guardian/index.ts"]
12
+ },
13
+ "files": [
14
+ "openclaw.plugin.json",
15
+ "openclaw-extension/",
16
+ "README.md",
17
+ "SKILL.md"
18
+ ],
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/signet-labs/signet-guardian"
22
+ },
23
+ "keywords": ["openclaw", "plugin", "signet", "payment", "guard", "policy"],
24
+ "license": "MIT",
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "dependencies": {
29
+ "prompts": "^2.4.2"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^20.0.0",
33
+ "typescript": "^5.0.0",
34
+ "tsx": "^4.7.0"
35
+ }
36
+ }