@three-ws/agent-guards
Advanced tools
+14
-15
@@ -1,21 +0,20 @@ | ||
| MIT License | ||
| Copyright 2026 nirholas | ||
| Copyright (c) 2026 three.ws | ||
| All rights reserved. | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| This software is proprietary and may not be used, copied, modified, distributed, | ||
| translated, or made available to any third party without the express written | ||
| permission of the copyright owner. | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| No rights are granted by implication, estoppel, or otherwise. Use of this | ||
| software is subject to the terms of a separate license agreement with the | ||
| copyright owner. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. | ||
| FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. | ||
| IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY CLAIM, DAMAGES, OR | ||
| OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, | ||
| ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| DEALINGS IN THE SOFTWARE. |
+2
-2
| { | ||
| "name": "@three-ws/agent-guards", | ||
| "version": "0.1.0", | ||
| "version": "0.1.1", | ||
| "description": "Safety rails for autonomous agents — per-agent spend policies and trade guards that cap what an agent can spend or trade before a transaction is signed. The three.ws agent custody SDK.", | ||
@@ -38,3 +38,3 @@ "type": "module", | ||
| "author": "nirholas <support@three.ws>", | ||
| "license": "MIT", | ||
| "license": "SEE LICENSE IN LICENSE", | ||
| "homepage": "https://three.ws", | ||
@@ -41,0 +41,0 @@ "repository": { |
+41
-0
@@ -112,2 +112,43 @@ <p align="center"> | ||
| ## Local guards (no network, no token) | ||
| The package ships the guard pipeline itself as pure functions, not just a client | ||
| for the hosted one. `policy()` normalizes a loose patch into the same bounded | ||
| leash the server would store, and `guard()` runs a proposed movement through | ||
| every predicate in the server's order. Nothing is fetched and nothing is signed, | ||
| so this half needs no token and runs in a browser, a test, or a simulator: | ||
| ```js | ||
| import { policy, guard } from '@three-ws/agent-guards'; | ||
| const p = policy({ per_trade_sol: 0.5, daily_budget_sol: 2, max_concurrent: 3 }); | ||
| guard({ side: 'buy', amountSol: 0.9, priceImpactPct: 2 }, p); | ||
| // { | ||
| // allow: false, | ||
| // reason: 'per_trade_cap', | ||
| // message: 'This trade of 0.9 SOL is over the per-trade cap of 0.5 SOL. Lower the | ||
| // amount or raise the cap under Limits & Safety.', | ||
| // detail: { amount_lamports: '900000000', cap_lamports: '500000000' }, | ||
| // } | ||
| ``` | ||
| You supply the live numbers the guards compare against, exactly as the server | ||
| does: `amountSol` (or `amountLamports`), `priceImpactPct`, `openCount`, | ||
| `spentLamports` (rolling 24h SOL), `walletLamports`, `usdValue`, `spentUsd`, and | ||
| `destination` for a withdraw. Omit one and the guard that needs it is skipped | ||
| rather than guessing, so feed it everything you want enforced. | ||
| | Export | Purpose | | ||
| |---|---| | ||
| | `policy(patch)` | Normalize + bound a patch. Clamps `max_price_impact_pct` to 0-100, `max_slippage_bps` to 0-10000, `max_concurrent` to 1-10000; booleans coerce strictly to `=== true`. | | ||
| | `guard(tx, policy)` | Run every predicate in server order. Returns `{ allow, reason, message, detail }`. | | ||
| | `checkKillSwitch` · `checkFrozen` · `checkPriceImpact` · `checkPerTradeCap` · `checkConcurrency` · `checkDailyBudgetLamports` · `checkPerTxUsd` · `checkDailyUsd` · `checkSolHeadroom` · `checkAllowlist` | The individual predicates. Each returns `null` when the trade clears, or `{ reason, detail }` when it blocks. | | ||
| | `TRADE_LIMIT_DEFAULTS` · `SPEND_LIMIT_DEFAULTS` | The platform defaults applied when an owner has set no policy. | | ||
| | `LAMPORTS_PER_SOL` · `SOL_FEE_HEADROOM_LAMPORTS` | The lamport constants the caps are denominated in (headroom is ~0.003 SOL). | | ||
| Note the shape difference: the local `guard()` returns `allow`, while the hosted | ||
| `checkTrade()` below returns `allowed`. The `reason` codes are identical across | ||
| both, so a UI can share one renderer. | ||
| ## API | ||
@@ -114,0 +155,0 @@ |
Non-permissive License
LicenseA license not known to be considered permissive was found.
Unidentified License
LicenseSomething that seems like a license was found, but its contents could not be matched with a known license.
55068
4.2%341
13.67%2
Infinity%80
-20%