@true402.dev/openclaw-swap-guard 1.0.1 → 1.0.2
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 +7 -4
- package/dist/index.js +17 -5
- package/openclaw.plugin.json +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,13 +28,15 @@ It recognises buys in shell commands the way trading skills run them (`--token-o
|
|
|
28
28
|
|
|
29
29
|
No setup is needed for a few checks a day: the guard uses true402's free daily allowance.
|
|
30
30
|
|
|
31
|
-
For more, give it a **
|
|
31
|
+
For more, give it a **dedicated, low-balance** Base wallet holding a little USDC (gas is sponsored):
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
export TRUE402_PAYER_PRIVATE_KEY=0x…
|
|
34
|
+
export TRUE402_PAYER_PRIVATE_KEY=0x…
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
Each check then pays the exact quoted price over [x402](https://x402.org)
|
|
37
|
+
Only this dedicated variable is read — never a generic `PAYER_PRIVATE_KEY` another tool may have set. Each check then pays the exact quoted price over [x402](https://x402.org), no account and no API key. The key stays on your machine (it authorizes each USDC payment locally) and is never written to OpenClaw's config.
|
|
38
|
+
|
|
39
|
+
Spending is bounded twice: **at most $0.02 per check** (`maxAmountUsd`) and **at most 50 paid checks a day** (`maxPaidChecksPerDay`) — so never more than $1.00 a day by default. Past the daily limit, only free checks run, and the guard logs a warning.
|
|
38
40
|
|
|
39
41
|
## Settings
|
|
40
42
|
|
|
@@ -47,7 +49,8 @@ All optional, under the plugin's config (`true402-swap-guard`):
|
|
|
47
49
|
| `onUnchecked` | `allow` | `ask` or `block` when a token could not be checked |
|
|
48
50
|
| `allowTokens` | `[]` | Token addresses never checked |
|
|
49
51
|
| `timeoutMs` | `15000` | Give up on a free check after this long (then it is "unchecked"). A paid check is never abandoned once paid — you get the answer you paid for |
|
|
50
|
-
| `maxAmountUsd` | `0.
|
|
52
|
+
| `maxAmountUsd` | `0.02` | Never pay more than this for one check |
|
|
53
|
+
| `maxPaidChecksPerDay` | `50` | Paid checks per UTC day; after that only free checks run |
|
|
51
54
|
|
|
52
55
|
## What is sent
|
|
53
56
|
|
package/dist/index.js
CHANGED
|
@@ -274,7 +274,7 @@ import { privateKeyToAccount } from "viem/accounts";
|
|
|
274
274
|
import { base } from "viem/chains";
|
|
275
275
|
|
|
276
276
|
// src/client.ts
|
|
277
|
-
var CLIENT = { id: "openclaw-guard", version: "1.0.
|
|
277
|
+
var CLIENT = { id: "openclaw-guard", version: "1.0.2", package: "@true402.dev/openclaw-swap-guard", install: "openclaw plugins install @true402.dev/openclaw-swap-guard" };
|
|
278
278
|
|
|
279
279
|
// src/x402.ts
|
|
280
280
|
var USDC_ABI = [
|
|
@@ -447,6 +447,8 @@ async function payStall(path, payload, opts) {
|
|
|
447
447
|
}
|
|
448
448
|
|
|
449
449
|
// src/check.ts
|
|
450
|
+
var DEFAULT_MAX_PER_CHECK_USD = 0.02;
|
|
451
|
+
var DEFAULT_MAX_PAID_CHECKS_PER_DAY = 50;
|
|
450
452
|
var NOT_A_TOKEN = /* @__PURE__ */ new Set(["not_a_contract", "mint_unreadable", "mint_not_initialized"]);
|
|
451
453
|
var SOL_NEVER_SELLABLE = /* @__PURE__ */ new Set(["non_transferable", "permanent_delegate"]);
|
|
452
454
|
var SOL_SELL_BLOCKABLE = /* @__PURE__ */ new Set(["freeze_authority_active", "pausable", "transfer_hook", "default_frozen"]);
|
|
@@ -490,6 +492,11 @@ function strings(v) {
|
|
|
490
492
|
function createChecker(cfg = {}) {
|
|
491
493
|
const baseUrl = cfg.baseUrl ?? "https://true402.dev/api";
|
|
492
494
|
const timeoutMs = cfg.timeoutMs ?? 15e3;
|
|
495
|
+
const perCheck = cfg.maxAmountUsd ?? DEFAULT_MAX_PER_CHECK_USD;
|
|
496
|
+
const perDay = cfg.maxPaidChecksPerDay ?? DEFAULT_MAX_PAID_CHECKS_PER_DAY;
|
|
497
|
+
const now = cfg.now ?? Date.now;
|
|
498
|
+
let day = "";
|
|
499
|
+
let paidToday = 0;
|
|
493
500
|
async function free(path, token) {
|
|
494
501
|
const res = await fetch(`${baseUrl}${path}`, {
|
|
495
502
|
method: "POST",
|
|
@@ -507,8 +514,12 @@ function createChecker(cfg = {}) {
|
|
|
507
514
|
const toVerdict = (body2) => t.chain === "solana" ? solanaVerdict(body2) : evmVerdict(body2, t.chain);
|
|
508
515
|
const body = await free(path, t.token);
|
|
509
516
|
if (body !== null) return toVerdict(body);
|
|
510
|
-
if (!cfg.payerPrivateKey) throw new Error("the free daily checks are used up \u2014 set
|
|
511
|
-
|
|
517
|
+
if (!cfg.payerPrivateKey) throw new Error("the free daily checks are used up \u2014 set TRUE402_PAYER_PRIVATE_KEY to pay per check");
|
|
518
|
+
const today = new Date(now()).toISOString().slice(0, 10);
|
|
519
|
+
if (today !== day) [day, paidToday] = [today, 0];
|
|
520
|
+
if (paidToday >= perDay) throw new Error(`the daily limit of ${perDay} paid checks is reached (maxPaidChecksPerDay)`);
|
|
521
|
+
paidToday++;
|
|
522
|
+
return toVerdict(await payStall(path, { token: t.token }, { payerPrivateKey: cfg.payerPrivateKey, baseUrl, maxAmountUsd: perCheck }));
|
|
512
523
|
};
|
|
513
524
|
}
|
|
514
525
|
|
|
@@ -524,7 +535,8 @@ function readConfig(raw) {
|
|
|
524
535
|
onUnchecked: pick(c.onUnchecked, ["allow", "ask", "block"]),
|
|
525
536
|
allowTokens: Array.isArray(c.allowTokens) ? c.allowTokens.filter((x) => typeof x === "string") : void 0,
|
|
526
537
|
timeoutMs: num(c.timeoutMs),
|
|
527
|
-
maxAmountUsd: num(c.maxAmountUsd)
|
|
538
|
+
maxAmountUsd: num(c.maxAmountUsd),
|
|
539
|
+
maxPaidChecksPerDay: num(c.maxPaidChecksPerDay)
|
|
528
540
|
};
|
|
529
541
|
}
|
|
530
542
|
var index_default = definePluginEntry({
|
|
@@ -533,7 +545,7 @@ var index_default = definePluginEntry({
|
|
|
533
545
|
description: "Blocks token buys when true402 finds a honeypot or a rug in progress (Base, Ethereum, BSC, Solana).",
|
|
534
546
|
register(api) {
|
|
535
547
|
const cfg = readConfig(api.pluginConfig);
|
|
536
|
-
const payerPrivateKey = process.env.TRUE402_PAYER_PRIVATE_KEY ||
|
|
548
|
+
const payerPrivateKey = process.env.TRUE402_PAYER_PRIVATE_KEY || void 0;
|
|
537
549
|
const warn = (m) => api.logger?.warn ? api.logger.warn(m) : console.warn(m);
|
|
538
550
|
const guard = createGuard(createChecker({ ...cfg, payerPrivateKey }), { ...cfg, warn });
|
|
539
551
|
api.on("before_tool_call", (event, ctx) => guard(event.toolName, event.params ?? {}, ctx?.abortSignal), { priority: 60 });
|
package/openclaw.plugin.json
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"onUnchecked": { "type": "string", "enum": ["allow", "ask", "block"], "description": "When a token could not be checked (API unreachable, free checks used up): allow (default), ask, or block." },
|
|
16
16
|
"allowTokens": { "type": "array", "items": { "type": "string" }, "description": "Token addresses never checked." },
|
|
17
17
|
"timeoutMs": { "type": "number", "description": "Give up on one check after this many ms (default 15000)." },
|
|
18
|
-
"maxAmountUsd": { "type": "number", "description": "Never
|
|
18
|
+
"maxAmountUsd": { "type": "number", "description": "Never pay more than this for one check, in USDC (default 0.02)." },
|
|
19
|
+
"maxPaidChecksPerDay": { "type": "number", "description": "At most this many paid checks per day; beyond it only free checks run (default 50)." }
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@true402.dev/openclaw-swap-guard",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "OpenClaw plugin: before any tool call that buys a token, check it with true402 (executed buy/sell honeypot simulation) and block honeypots and rugs. Base, Ethereum, BSC, Solana. Free daily checks; pay-per-check over x402.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|