@blockrun/clawrouter 0.12.256 → 0.12.257
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/cli.js +943 -609
- package/dist/index.d.ts +235 -113
- package/dist/index.js +929 -595
- package/docs/configuration.md +81 -0
- package/package.json +1 -1
package/docs/configuration.md
CHANGED
|
@@ -12,6 +12,7 @@ Complete reference for ClawRouter configuration options.
|
|
|
12
12
|
- [Routing Configuration](#routing-configuration)
|
|
13
13
|
- [Tier Overrides](#tier-overrides)
|
|
14
14
|
- [Scoring Weights](#scoring-weights)
|
|
15
|
+
- [Spend Control & Counterparty Policy](#spend-control--counterparty-policy)
|
|
15
16
|
- [Testing Configuration](#testing-configuration)
|
|
16
17
|
|
|
17
18
|
---
|
|
@@ -540,6 +541,86 @@ routing:
|
|
|
540
541
|
|
|
541
542
|
---
|
|
542
543
|
|
|
544
|
+
## Spend Control & Counterparty Policy
|
|
545
|
+
|
|
546
|
+
Amount caps bound **how much** the agent may pay. Counterparty policy bounds
|
|
547
|
+
**whom** it may pay, and on which network and asset. Both are evaluated before
|
|
548
|
+
the wallet signs anything: a refusal aborts the payment at the x402 pre-sign
|
|
549
|
+
hook, so no authorization is ever produced.
|
|
550
|
+
|
|
551
|
+
Everything here is **off by default**. An unconfigured list is not consulted.
|
|
552
|
+
|
|
553
|
+
State lives in `~/.openclaw/blockrun/spending.json` (mode 0600), read once at
|
|
554
|
+
proxy startup — **edit it, then restart the proxy** for changes to take effect.
|
|
555
|
+
|
|
556
|
+
```json
|
|
557
|
+
{
|
|
558
|
+
"limits": {
|
|
559
|
+
"perRequest": 0.05,
|
|
560
|
+
"hourly": 2.0,
|
|
561
|
+
"daily": 20.0,
|
|
562
|
+
"session": 5.0,
|
|
563
|
+
"allowedPayees": ["0x1111111111111111111111111111111111111111"],
|
|
564
|
+
"blockedPayees": ["0x2222222222222222222222222222222222222222"],
|
|
565
|
+
"allowedNetworks": ["eip155:8453"],
|
|
566
|
+
"allowedAssets": ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"]
|
|
567
|
+
},
|
|
568
|
+
"history": []
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
| Field | Meaning |
|
|
573
|
+
| --------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
574
|
+
| `perRequest` / `hourly` / `daily` / `session` | USD caps. Rolling 1h and 24h windows; session resets on restart. |
|
|
575
|
+
| `allowedPayees` | Only these `payTo` addresses may be paid. |
|
|
576
|
+
| `blockedPayees` | These may never be paid. **Wins over `allowedPayees`** when an address is on both. |
|
|
577
|
+
| `allowedNetworks` | CAIP-2 ids only. |
|
|
578
|
+
| `allowedAssets` | Token contract addresses of the asset being paid in. |
|
|
579
|
+
|
|
580
|
+
**Networks are CAIP-2, not nicknames.** `base` does not match `eip155:8453`
|
|
581
|
+
and fails closed. Use `eip155:8453` for Base and
|
|
582
|
+
`solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d` for Solana mainnet; both
|
|
583
|
+
are exported as `CAIP2_BASE` and `CAIP2_SOLANA_MAINNET`.
|
|
584
|
+
|
|
585
|
+
EVM addresses in `allowedPayees`, `blockedPayees` and `allowedAssets` are
|
|
586
|
+
compared case-insensitively, so checksummed and lowercase forms both match.
|
|
587
|
+
Solana base58 addresses are case-sensitive and compared exactly.
|
|
588
|
+
|
|
589
|
+
### Fail-closed behavior
|
|
590
|
+
|
|
591
|
+
- A configured list with **no matching value on the payment** refuses, rather
|
|
592
|
+
than skipping the check.
|
|
593
|
+
- A payment quote whose amount is not a canonical decimal integer refuses
|
|
594
|
+
whenever an amount cap is set. (`parseInt` and the signer's `BigInt` disagree
|
|
595
|
+
on `0x`-style values, so an unparseable quote is never treated as $0.)
|
|
596
|
+
- A **malformed** policy list in `spending.json` refuses every paid request
|
|
597
|
+
until the file is repaired. The proxy still starts and free models keep
|
|
598
|
+
working; the error names the offending field. An empty array (`[]`) is not
|
|
599
|
+
malformed — it means "not configured", and is how you clear a list by hand.
|
|
600
|
+
|
|
601
|
+
### Programmatic use
|
|
602
|
+
|
|
603
|
+
```ts
|
|
604
|
+
import { SpendControl, registerSpendPolicyHook, CAIP2_BASE } from "@blockrun/clawrouter";
|
|
605
|
+
|
|
606
|
+
const control = new SpendControl();
|
|
607
|
+
control.setLimit("daily", 20);
|
|
608
|
+
control.setPolicy("allowedNetworks", [CAIP2_BASE]);
|
|
609
|
+
|
|
610
|
+
// startProxy does this for you; only needed on your own x402 client.
|
|
611
|
+
registerSpendPolicyHook(x402, control);
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
A refusal reaches the caller as HTTP 403 with
|
|
615
|
+
`{"error": {"type": "spend_policy_denied", ...}}`. It is deliberately **not**
|
|
616
|
+
retried against other models: a policy denial is a decision, not an outage.
|
|
617
|
+
|
|
618
|
+
**Scope:** this governs payments made by the proxy. Local tools that sign with
|
|
619
|
+
the same wallet outside the proxy's x402 client (Polymarket funding and order
|
|
620
|
+
placement, `clawrouter doctor`'s probe) are not covered.
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
543
624
|
## Testing Configuration
|
|
544
625
|
|
|
545
626
|
### Dry Run (No Payments)
|
package/package.json
CHANGED