@x402sentinel/openclaw-sentinel 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 +70 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +65 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.js +8 -0
- package/openclaw.plugin.json +39 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# @x402sentinel/openclaw-sentinel
|
|
2
|
+
|
|
3
|
+
Budget enforcement & audit trails for OpenClaw x402 payments.
|
|
4
|
+
|
|
5
|
+
Wraps every x402 HTTP payment your OpenClaw agent makes with Sentinel's
|
|
6
|
+
spend controls and audit logging. No code changes to your agent — just
|
|
7
|
+
install the plugin and set your limits.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
openclaw plugin install @x402sentinel/openclaw-sentinel
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Configure
|
|
16
|
+
|
|
17
|
+
Add the plugin to your OpenClaw config:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
// ~/.openclaw/openclaw.json
|
|
21
|
+
{
|
|
22
|
+
"plugins": {
|
|
23
|
+
"entries": {
|
|
24
|
+
"sentinel": {
|
|
25
|
+
"enabled": true,
|
|
26
|
+
"config": {
|
|
27
|
+
"apiKey": "sk_sentinel_...",
|
|
28
|
+
"agentId": "my-openclaw-agent",
|
|
29
|
+
"maxPerCall": 1.00,
|
|
30
|
+
"maxPerHour": 25.00,
|
|
31
|
+
"maxPerDay": 200.00
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Config options
|
|
40
|
+
|
|
41
|
+
| Option | Type | Default | Description |
|
|
42
|
+
|--------|------|---------|-------------|
|
|
43
|
+
| `apiKey` | string | *required* | Sentinel API key |
|
|
44
|
+
| `apiUrl` | string | `https://sentinel.valeocash.com` | Sentinel dashboard URL |
|
|
45
|
+
| `agentId` | string | `openclaw-agent` | Agent ID in audit trails |
|
|
46
|
+
| `maxPerCall` | number | `1.00` | Max USDC per single x402 call |
|
|
47
|
+
| `maxPerHour` | number | `25.00` | Max USDC per hour |
|
|
48
|
+
| `maxPerDay` | number | `200.00` | Max USDC per day |
|
|
49
|
+
|
|
50
|
+
## What it does
|
|
51
|
+
|
|
52
|
+
- **Budget enforcement** — blocks payments exceeding per-call, hourly, or daily USDC limits before they execute
|
|
53
|
+
- **Audit logging** — every x402 payment is logged to your Sentinel dashboard with agent ID, endpoint, amount, tx hash, and timing
|
|
54
|
+
- **`sentinel_status` tool** — your agent can check its own budget status and remaining spend at any time
|
|
55
|
+
|
|
56
|
+
## Dashboard
|
|
57
|
+
|
|
58
|
+
View all payments, filter by agent or endpoint, and export CSV reports:
|
|
59
|
+
|
|
60
|
+
https://sentinel.valeocash.com/dashboard
|
|
61
|
+
|
|
62
|
+
## Get API Key
|
|
63
|
+
|
|
64
|
+
1. Sign up at [sentinel.valeocash.com](https://sentinel.valeocash.com)
|
|
65
|
+
2. Go to **Settings** → **Generate API Key**
|
|
66
|
+
3. Add the key to your `openclaw.json` config
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PluginApi, SentinelPluginConfig, PluginExports } from "./types";
|
|
2
|
+
declare function activate(api: PluginApi, config: SentinelPluginConfig): void;
|
|
3
|
+
declare function deactivate(): void;
|
|
4
|
+
declare const plugin: PluginExports;
|
|
5
|
+
export default plugin;
|
|
6
|
+
export { activate, deactivate };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.activate = activate;
|
|
4
|
+
exports.deactivate = deactivate;
|
|
5
|
+
const x402_1 = require("@x402sentinel/x402");
|
|
6
|
+
const ONE_HOUR_MS = 60 * 60 * 1000;
|
|
7
|
+
const ONE_DAY_MS = 24 * ONE_HOUR_MS;
|
|
8
|
+
let active = false;
|
|
9
|
+
function activate(api, config) {
|
|
10
|
+
const storage = new x402_1.ApiStorage({
|
|
11
|
+
baseUrl: `${config.apiUrl}/api/v1`,
|
|
12
|
+
apiKey: config.apiKey,
|
|
13
|
+
});
|
|
14
|
+
api.registerFetchInterceptor((originalFetch) => {
|
|
15
|
+
return (0, x402_1.wrapWithSentinel)(originalFetch, {
|
|
16
|
+
agentId: config.agentId,
|
|
17
|
+
budget: {
|
|
18
|
+
maxPerCall: String(config.maxPerCall),
|
|
19
|
+
maxPerHour: String(config.maxPerHour),
|
|
20
|
+
maxPerDay: String(config.maxPerDay),
|
|
21
|
+
},
|
|
22
|
+
audit: { storage },
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
api.registerTool({
|
|
26
|
+
name: "sentinel_status",
|
|
27
|
+
description: "Check current Sentinel budget status, spend totals, and remaining budget for this agent",
|
|
28
|
+
parameters: {},
|
|
29
|
+
async execute() {
|
|
30
|
+
const now = Date.now();
|
|
31
|
+
const [allTime, lastHour, lastDay] = await Promise.all([
|
|
32
|
+
storage.summarize({}),
|
|
33
|
+
storage.summarize({ startTime: now - ONE_HOUR_MS }),
|
|
34
|
+
storage.summarize({ startTime: now - ONE_DAY_MS }),
|
|
35
|
+
]);
|
|
36
|
+
const hourlySpent = parseFloat(lastHour.total_spend) || 0;
|
|
37
|
+
const dailySpent = parseFloat(lastDay.total_spend) || 0;
|
|
38
|
+
return {
|
|
39
|
+
agentId: config.agentId,
|
|
40
|
+
totalSpent: allTime.total_spend,
|
|
41
|
+
totalTransactions: allTime.total_transactions,
|
|
42
|
+
uniqueEndpoints: allTime.unique_endpoints,
|
|
43
|
+
budgetRemaining: {
|
|
44
|
+
hourly: Math.max(0, config.maxPerHour - hourlySpent).toFixed(2),
|
|
45
|
+
daily: Math.max(0, config.maxPerDay - dailySpent).toFixed(2),
|
|
46
|
+
},
|
|
47
|
+
limits: {
|
|
48
|
+
perCall: config.maxPerCall,
|
|
49
|
+
perHour: config.maxPerHour,
|
|
50
|
+
perDay: config.maxPerDay,
|
|
51
|
+
},
|
|
52
|
+
dashboard: `${config.apiUrl}/dashboard`,
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
active = true;
|
|
57
|
+
console.log(`[sentinel] Budget enforcement active: $${config.maxPerCall}/call, $${config.maxPerHour}/hr, $${config.maxPerDay}/day`);
|
|
58
|
+
console.log(`[sentinel] Audit dashboard: ${config.apiUrl}/dashboard`);
|
|
59
|
+
}
|
|
60
|
+
function deactivate() {
|
|
61
|
+
active = false;
|
|
62
|
+
console.log("[sentinel] Plugin deactivated");
|
|
63
|
+
}
|
|
64
|
+
const plugin = { activate, deactivate };
|
|
65
|
+
exports.default = plugin;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal OpenClaw plugin API type stubs.
|
|
3
|
+
*
|
|
4
|
+
* These describe only the surface area this plugin consumes,
|
|
5
|
+
* so we don't need @openclaw as a dependency.
|
|
6
|
+
*/
|
|
7
|
+
export interface ToolDefinition {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
parameters: Record<string, unknown>;
|
|
11
|
+
execute: () => Promise<unknown>;
|
|
12
|
+
}
|
|
13
|
+
export interface PluginApi {
|
|
14
|
+
/** Wrap the agent's fetch function with a custom interceptor. */
|
|
15
|
+
registerFetchInterceptor(interceptor: (originalFetch: typeof fetch) => typeof fetch): void;
|
|
16
|
+
/** Expose a tool the agent can call during conversations. */
|
|
17
|
+
registerTool(tool: ToolDefinition): void;
|
|
18
|
+
}
|
|
19
|
+
export interface SentinelPluginConfig {
|
|
20
|
+
apiUrl: string;
|
|
21
|
+
apiKey: string;
|
|
22
|
+
agentId: string;
|
|
23
|
+
maxPerCall: number;
|
|
24
|
+
maxPerHour: number;
|
|
25
|
+
maxPerDay: number;
|
|
26
|
+
}
|
|
27
|
+
export interface PluginExports {
|
|
28
|
+
activate(api: PluginApi, config: SentinelPluginConfig): void;
|
|
29
|
+
deactivate(): void;
|
|
30
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sentinel",
|
|
3
|
+
"configSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"additionalProperties": false,
|
|
6
|
+
"properties": {
|
|
7
|
+
"apiUrl": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"default": "https://sentinel.valeocash.com",
|
|
10
|
+
"description": "Sentinel dashboard URL"
|
|
11
|
+
},
|
|
12
|
+
"apiKey": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "Sentinel API key (from sentinel.valeocash.com/dashboard/settings)"
|
|
15
|
+
},
|
|
16
|
+
"agentId": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"default": "openclaw-agent",
|
|
19
|
+
"description": "Agent identifier for audit trails"
|
|
20
|
+
},
|
|
21
|
+
"maxPerCall": {
|
|
22
|
+
"type": "number",
|
|
23
|
+
"default": 1.0,
|
|
24
|
+
"description": "Max USDC per single x402 call"
|
|
25
|
+
},
|
|
26
|
+
"maxPerHour": {
|
|
27
|
+
"type": "number",
|
|
28
|
+
"default": 25.0,
|
|
29
|
+
"description": "Max USDC per hour"
|
|
30
|
+
},
|
|
31
|
+
"maxPerDay": {
|
|
32
|
+
"type": "number",
|
|
33
|
+
"default": 200.0,
|
|
34
|
+
"description": "Max USDC per day"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"required": ["apiKey"]
|
|
38
|
+
}
|
|
39
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@x402sentinel/openclaw-sentinel",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Budget enforcement & audit trails for OpenClaw x402 payments",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"prepublishOnly": "npm run build"
|
|
10
|
+
},
|
|
11
|
+
"peerDependencies": {
|
|
12
|
+
"@x402sentinel/x402": ">=0.1.2"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@x402sentinel/x402": "^0.1.2",
|
|
16
|
+
"typescript": "^5.9.3"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"openclaw.plugin.json"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"openclaw",
|
|
25
|
+
"openclaw-plugin",
|
|
26
|
+
"x402",
|
|
27
|
+
"sentinel",
|
|
28
|
+
"audit",
|
|
29
|
+
"compliance",
|
|
30
|
+
"budget",
|
|
31
|
+
"ai-agents",
|
|
32
|
+
"usdc"
|
|
33
|
+
],
|
|
34
|
+
"author": "Valeo",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/valeo-cash/Sentinel"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://sentinel.valeocash.com"
|
|
41
|
+
}
|