@blockrun/clawrouter 0.12.277 → 0.12.278
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 +0 -15
- package/dist/cli.js +2 -148
- package/dist/index.js +2 -147
- package/docs/configuration.md +0 -64
- package/package.json +1 -4
package/README.md
CHANGED
|
@@ -767,24 +767,9 @@ For basic usage, no configuration needed. For advanced options:
|
|
|
767
767
|
| `CLAWROUTER_DISABLED` | `false` | Disable smart routing |
|
|
768
768
|
| `CLAWROUTER_DEBUG_HEADERS` | `on` | Set to `off` to suppress `x-clawrouter-*` debug response headers |
|
|
769
769
|
| `CLAWROUTER_SOLANA_RPC_URL` | `https://api.mainnet-beta.solana.com` | Solana RPC endpoint — balance checks and payment signing |
|
|
770
|
-
| `TWZRD_AUTO_GATE` | unset (off) | Set to `1` to compose TWZRD AutoGate after SpendControl on the x402 pre-sign hook |
|
|
771
770
|
|
|
772
771
|
**Full reference:** [docs/configuration.md](docs/configuration.md)
|
|
773
772
|
|
|
774
|
-
### Pre-spend trust (TWZRD AutoGate, opt-in)
|
|
775
|
-
|
|
776
|
-
Default **off**. Spend limits and counterparty lists (`clawrouter policy`) stay the vendor-neutral path. This is not a default-on vendor lock.
|
|
777
|
-
|
|
778
|
-
To also run TWZRD wash/preflight on the same `onBeforePaymentCreation` chain — after SpendControl, before the wallet signs:
|
|
779
|
-
|
|
780
|
-
```bash
|
|
781
|
-
export TWZRD_AUTO_GATE=1
|
|
782
|
-
```
|
|
783
|
-
|
|
784
|
-
Equivalent flag: `TWZRD_GATE_ENABLED=true`. Requires optional dependency `twzrd-x402-gate@0.9.3` (forks that omit it still install). A refuse stamps `X-Twzrd-Caller: clawrouter/<version>` so it is attributable. Unset the flag to go back to SpendControl only.
|
|
785
|
-
|
|
786
|
-
**It gates Solana, not Base.** The gate scores Solana recipients; Base/EVM classifies as `network_not_scored` and is waved through without a lookup. On Solana it POSTs the resource URL, `payTo`, price and chain to `intel.twzrd.xyz` before each signature — payment metadata leaves your machine when this is on. We bound that call at `TWZRD_GATE_TIMEOUT_MS` (default 2000) and proceed if it does not answer, because SpendControl is the guarantee and a third party must not be able to stop your payments; set `TWZRD_FAIL_OPEN=false` to refuse instead.
|
|
787
|
-
|
|
788
773
|
### Model Exclusion
|
|
789
774
|
|
|
790
775
|
Block specific models from being routed to. Useful if a model doesn't follow your agent instructions or you want to control costs.
|
package/dist/cli.js
CHANGED
|
@@ -60460,149 +60460,6 @@ var init_api_key = __esm({
|
|
|
60460
60460
|
}
|
|
60461
60461
|
});
|
|
60462
60462
|
|
|
60463
|
-
// src/twzrd-autogate.ts
|
|
60464
|
-
import { randomUUID } from "crypto";
|
|
60465
|
-
function normalizeFlag(value) {
|
|
60466
|
-
const trimmed = value?.trim().toLowerCase();
|
|
60467
|
-
return trimmed === "" ? void 0 : trimmed;
|
|
60468
|
-
}
|
|
60469
|
-
function isTwzrdAutoGateEnabled(env = process.env) {
|
|
60470
|
-
const auto = normalizeFlag(env.TWZRD_AUTO_GATE);
|
|
60471
|
-
const gate = normalizeFlag(env.TWZRD_GATE_ENABLED);
|
|
60472
|
-
if (auto !== void 0 && FALSY.has(auto) || gate !== void 0 && FALSY.has(gate)) {
|
|
60473
|
-
return false;
|
|
60474
|
-
}
|
|
60475
|
-
return auto !== void 0 && TRUTHY.has(auto) || gate !== void 0 && TRUTHY.has(gate);
|
|
60476
|
-
}
|
|
60477
|
-
function isMissingTwzrdGateModule(err) {
|
|
60478
|
-
const code = err?.code;
|
|
60479
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
60480
|
-
const missingModule = code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND" || /Cannot find module/i.test(msg) || /Cannot find package/i.test(msg);
|
|
60481
|
-
return missingModule && new RegExp(String.raw`['"]${TWZRD_GATE_PACKAGE}['"]`).test(msg);
|
|
60482
|
-
}
|
|
60483
|
-
function twzrdGateTimeoutMs(env = process.env) {
|
|
60484
|
-
const raw = normalizeFlag(env.TWZRD_GATE_TIMEOUT_MS);
|
|
60485
|
-
if (raw === void 0) return TWZRD_GATE_TIMEOUT_MS;
|
|
60486
|
-
const parsed = Number(raw);
|
|
60487
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : TWZRD_GATE_TIMEOUT_MS;
|
|
60488
|
-
}
|
|
60489
|
-
function twzrdGateFailOpen(env = process.env) {
|
|
60490
|
-
const raw = normalizeFlag(env.TWZRD_FAIL_OPEN);
|
|
60491
|
-
return !(raw !== void 0 && FALSY.has(raw));
|
|
60492
|
-
}
|
|
60493
|
-
function twzrdAutoGateInstallOptions(env = process.env, runId = randomUUID) {
|
|
60494
|
-
return {
|
|
60495
|
-
refuseWashFlagged: true,
|
|
60496
|
-
gateOnCanSpend: false,
|
|
60497
|
-
unsupportedNetworkMode: "observe",
|
|
60498
|
-
failOpen: twzrdGateFailOpen(env),
|
|
60499
|
-
attribution: {
|
|
60500
|
-
integration: `clawrouter/${VERSION}`,
|
|
60501
|
-
runId: runId()
|
|
60502
|
-
}
|
|
60503
|
-
};
|
|
60504
|
-
}
|
|
60505
|
-
async function runTwzrdGateWithTimeout(run, opts) {
|
|
60506
|
-
const log = opts.log ?? console;
|
|
60507
|
-
let timer2;
|
|
60508
|
-
try {
|
|
60509
|
-
const raced = await Promise.race([
|
|
60510
|
-
// Swallow here, not at the race, so a late rejection never goes unhandled.
|
|
60511
|
-
Promise.resolve().then(run).catch((err) => ({ __twzrdError: err })),
|
|
60512
|
-
new Promise((resolve) => {
|
|
60513
|
-
timer2 = setTimeout(() => resolve(TIMED_OUT), opts.timeoutMs);
|
|
60514
|
-
})
|
|
60515
|
-
]);
|
|
60516
|
-
if (raced === TIMED_OUT) {
|
|
60517
|
-
return decideOnGateFailure(`did not answer within ${opts.timeoutMs}ms`, opts.failOpen, log);
|
|
60518
|
-
}
|
|
60519
|
-
if (raced && typeof raced === "object" && "__twzrdError" in raced) {
|
|
60520
|
-
const err = raced.__twzrdError;
|
|
60521
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
60522
|
-
return decideOnGateFailure(`threw: ${msg.slice(0, 120)}`, opts.failOpen, log);
|
|
60523
|
-
}
|
|
60524
|
-
return raced;
|
|
60525
|
-
} finally {
|
|
60526
|
-
if (timer2) clearTimeout(timer2);
|
|
60527
|
-
}
|
|
60528
|
-
}
|
|
60529
|
-
function decideOnGateFailure(what, failOpen, log) {
|
|
60530
|
-
const reason = `twzrd gate ${what}`;
|
|
60531
|
-
if (failOpen) {
|
|
60532
|
-
log.warn(
|
|
60533
|
-
`[ClawRouter] ${reason} \u2014 proceeding. SpendControl still applied. Set TWZRD_FAIL_OPEN=false to refuse instead.`
|
|
60534
|
-
);
|
|
60535
|
-
return void 0;
|
|
60536
|
-
}
|
|
60537
|
-
log.warn(`[ClawRouter] ${reason} \u2014 refusing the payment (TWZRD_FAIL_OPEN=false).`);
|
|
60538
|
-
return { abort: true, reason };
|
|
60539
|
-
}
|
|
60540
|
-
async function defaultLoadTwzrdGate() {
|
|
60541
|
-
const specifier = TWZRD_GATE_PACKAGE;
|
|
60542
|
-
return import(specifier);
|
|
60543
|
-
}
|
|
60544
|
-
async function maybeComposeTwzrdAutoGate(x402, options) {
|
|
60545
|
-
const env = options?.env ?? process.env;
|
|
60546
|
-
const log = options?.log ?? console;
|
|
60547
|
-
if (!isTwzrdAutoGateEnabled(env)) {
|
|
60548
|
-
return { status: "skipped" };
|
|
60549
|
-
}
|
|
60550
|
-
const load = options?.loadGate ?? defaultLoadTwzrdGate;
|
|
60551
|
-
let gate;
|
|
60552
|
-
try {
|
|
60553
|
-
gate = await load();
|
|
60554
|
-
} catch (err) {
|
|
60555
|
-
if (isMissingTwzrdGateModule(err)) {
|
|
60556
|
-
const reason = `${TWZRD_GATE_PACKAGE} is not installed`;
|
|
60557
|
-
log.warn(
|
|
60558
|
-
`[ClawRouter] TWZRD AutoGate opted in but ${reason} \u2014 skipping. npm i ${TWZRD_GATE_PACKAGE}@0.9.3`
|
|
60559
|
-
);
|
|
60560
|
-
return { status: "unavailable", reason };
|
|
60561
|
-
}
|
|
60562
|
-
throw err;
|
|
60563
|
-
}
|
|
60564
|
-
const installOpts = twzrdAutoGateInstallOptions(env);
|
|
60565
|
-
const timeoutMs = twzrdGateTimeoutMs(env);
|
|
60566
|
-
const ready = (via) => log.log(
|
|
60567
|
-
`[ClawRouter] TWZRD AutoGate ON (opt-in, after SpendControl, ${via}; ${timeoutMs}ms budget, failOpen=${installOpts.failOpen}). Unset TWZRD_AUTO_GATE to disable.`
|
|
60568
|
-
);
|
|
60569
|
-
if (typeof gate.createTwzrdBeforePaymentHook === "function") {
|
|
60570
|
-
const hook = gate.createTwzrdBeforePaymentHook(installOpts);
|
|
60571
|
-
x402.onBeforePaymentCreation(
|
|
60572
|
-
async (ctx) => runTwzrdGateWithTimeout(() => hook(ctx.selectedRequirements, ctx), {
|
|
60573
|
-
timeoutMs,
|
|
60574
|
-
failOpen: installOpts.failOpen,
|
|
60575
|
-
log
|
|
60576
|
-
})
|
|
60577
|
-
);
|
|
60578
|
-
ready("createTwzrdBeforePaymentHook");
|
|
60579
|
-
return { status: "composed", via: "createTwzrdBeforePaymentHook" };
|
|
60580
|
-
}
|
|
60581
|
-
if (typeof gate.installTwzrdAutoGate === "function") {
|
|
60582
|
-
gate.installTwzrdAutoGate(x402, installOpts);
|
|
60583
|
-
log.warn(
|
|
60584
|
-
"[ClawRouter] TWZRD AutoGate installed via installTwzrdAutoGate \u2014 that entry point registers its own hook, so the timeout budget does not apply and it replaces onBeforePaymentCreation on this client. Prefer a gate build exporting createTwzrdBeforePaymentHook."
|
|
60585
|
-
);
|
|
60586
|
-
ready("installTwzrdAutoGate");
|
|
60587
|
-
return { status: "composed", via: "installTwzrdAutoGate" };
|
|
60588
|
-
}
|
|
60589
|
-
throw new Error(
|
|
60590
|
-
`[ClawRouter] ${TWZRD_GATE_PACKAGE} is installed but exports neither installTwzrdAutoGate nor createTwzrdBeforePaymentHook`
|
|
60591
|
-
);
|
|
60592
|
-
}
|
|
60593
|
-
var TWZRD_GATE_PACKAGE, TRUTHY, FALSY, TWZRD_GATE_TIMEOUT_MS, TIMED_OUT;
|
|
60594
|
-
var init_twzrd_autogate = __esm({
|
|
60595
|
-
"src/twzrd-autogate.ts"() {
|
|
60596
|
-
"use strict";
|
|
60597
|
-
init_version4();
|
|
60598
|
-
TWZRD_GATE_PACKAGE = "twzrd-x402-gate";
|
|
60599
|
-
TRUTHY = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
|
|
60600
|
-
FALSY = /* @__PURE__ */ new Set(["0", "false", "no", "off"]);
|
|
60601
|
-
TWZRD_GATE_TIMEOUT_MS = 2e3;
|
|
60602
|
-
TIMED_OUT = { __twzrdTimedOut: true };
|
|
60603
|
-
}
|
|
60604
|
-
});
|
|
60605
|
-
|
|
60606
60463
|
// src/compression/types.ts
|
|
60607
60464
|
var DEFAULT_COMPRESSION_CONFIG;
|
|
60608
60465
|
var init_types2 = __esm({
|
|
@@ -92187,7 +92044,6 @@ async function startProxy(options) {
|
|
|
92187
92044
|
const evmSigner = toClientEvmSigner(account, evmPublicClient);
|
|
92188
92045
|
const spendControl = options.spendControl ?? getSharedSpendControl();
|
|
92189
92046
|
registerSpendPolicyHook(x402, spendControl);
|
|
92190
|
-
await maybeComposeTwzrdAutoGate(x402);
|
|
92191
92047
|
registerExactEvmScheme(x402, { signer: evmSigner });
|
|
92192
92048
|
}
|
|
92193
92049
|
let solanaAddress;
|
|
@@ -95773,7 +95629,6 @@ var init_proxy = __esm({
|
|
|
95773
95629
|
init_auth();
|
|
95774
95630
|
init_api_key();
|
|
95775
95631
|
init_spend_control();
|
|
95776
|
-
init_twzrd_autogate();
|
|
95777
95632
|
init_compression();
|
|
95778
95633
|
init_errors5();
|
|
95779
95634
|
init_version4();
|
|
@@ -228831,7 +228686,7 @@ import {
|
|
|
228831
228686
|
} from "fs";
|
|
228832
228687
|
import { readFile as readFileAsync } from "fs/promises";
|
|
228833
228688
|
import { homedir as homedir15 } from "os";
|
|
228834
|
-
import { randomUUID
|
|
228689
|
+
import { randomUUID } from "crypto";
|
|
228835
228690
|
import { join as join18 } from "path";
|
|
228836
228691
|
async function waitForProxyHealth(port, timeoutMs = 3e3) {
|
|
228837
228692
|
const start = Date.now();
|
|
@@ -228846,7 +228701,7 @@ async function waitForProxyHealth(port, timeoutMs = 3e3) {
|
|
|
228846
228701
|
return false;
|
|
228847
228702
|
}
|
|
228848
228703
|
function writePrivateJsonSync(path5, value) {
|
|
228849
|
-
const temporary = `${path5}.tmp.${
|
|
228704
|
+
const temporary = `${path5}.tmp.${randomUUID()}`;
|
|
228850
228705
|
try {
|
|
228851
228706
|
writeFileSync3(temporary, JSON.stringify(value, null, 2), { mode: 384 });
|
|
228852
228707
|
renameSync2(temporary, path5);
|
|
@@ -231337,7 +231192,6 @@ Environment Variables:
|
|
|
231337
231192
|
BLOCKRUN_API_KEY BlockRun API key (brk_...) \u2014 wins over the wallet when set
|
|
231338
231193
|
BLOCKRUN_WALLET_KEY Private key for x402 payments (auto-generated if not set)
|
|
231339
231194
|
BLOCKRUN_PROXY_PORT Default proxy port (default: 8402)
|
|
231340
|
-
TWZRD_AUTO_GATE Set to 1 to compose TWZRD AutoGate after SpendControl (default off)
|
|
231341
231195
|
|
|
231342
231196
|
For more info: https://blockrun.ai/clawrouter.md
|
|
231343
231197
|
`);
|
package/dist/index.js
CHANGED
|
@@ -60213,149 +60213,6 @@ var init_api_key = __esm({
|
|
|
60213
60213
|
}
|
|
60214
60214
|
});
|
|
60215
60215
|
|
|
60216
|
-
// src/twzrd-autogate.ts
|
|
60217
|
-
import { randomUUID } from "crypto";
|
|
60218
|
-
function normalizeFlag(value) {
|
|
60219
|
-
const trimmed = value?.trim().toLowerCase();
|
|
60220
|
-
return trimmed === "" ? void 0 : trimmed;
|
|
60221
|
-
}
|
|
60222
|
-
function isTwzrdAutoGateEnabled(env = process.env) {
|
|
60223
|
-
const auto = normalizeFlag(env.TWZRD_AUTO_GATE);
|
|
60224
|
-
const gate = normalizeFlag(env.TWZRD_GATE_ENABLED);
|
|
60225
|
-
if (auto !== void 0 && FALSY.has(auto) || gate !== void 0 && FALSY.has(gate)) {
|
|
60226
|
-
return false;
|
|
60227
|
-
}
|
|
60228
|
-
return auto !== void 0 && TRUTHY.has(auto) || gate !== void 0 && TRUTHY.has(gate);
|
|
60229
|
-
}
|
|
60230
|
-
function isMissingTwzrdGateModule(err) {
|
|
60231
|
-
const code = err?.code;
|
|
60232
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
60233
|
-
const missingModule = code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND" || /Cannot find module/i.test(msg) || /Cannot find package/i.test(msg);
|
|
60234
|
-
return missingModule && new RegExp(String.raw`['"]${TWZRD_GATE_PACKAGE}['"]`).test(msg);
|
|
60235
|
-
}
|
|
60236
|
-
function twzrdGateTimeoutMs(env = process.env) {
|
|
60237
|
-
const raw = normalizeFlag(env.TWZRD_GATE_TIMEOUT_MS);
|
|
60238
|
-
if (raw === void 0) return TWZRD_GATE_TIMEOUT_MS;
|
|
60239
|
-
const parsed = Number(raw);
|
|
60240
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : TWZRD_GATE_TIMEOUT_MS;
|
|
60241
|
-
}
|
|
60242
|
-
function twzrdGateFailOpen(env = process.env) {
|
|
60243
|
-
const raw = normalizeFlag(env.TWZRD_FAIL_OPEN);
|
|
60244
|
-
return !(raw !== void 0 && FALSY.has(raw));
|
|
60245
|
-
}
|
|
60246
|
-
function twzrdAutoGateInstallOptions(env = process.env, runId = randomUUID) {
|
|
60247
|
-
return {
|
|
60248
|
-
refuseWashFlagged: true,
|
|
60249
|
-
gateOnCanSpend: false,
|
|
60250
|
-
unsupportedNetworkMode: "observe",
|
|
60251
|
-
failOpen: twzrdGateFailOpen(env),
|
|
60252
|
-
attribution: {
|
|
60253
|
-
integration: `clawrouter/${VERSION}`,
|
|
60254
|
-
runId: runId()
|
|
60255
|
-
}
|
|
60256
|
-
};
|
|
60257
|
-
}
|
|
60258
|
-
async function runTwzrdGateWithTimeout(run, opts) {
|
|
60259
|
-
const log = opts.log ?? console;
|
|
60260
|
-
let timer2;
|
|
60261
|
-
try {
|
|
60262
|
-
const raced = await Promise.race([
|
|
60263
|
-
// Swallow here, not at the race, so a late rejection never goes unhandled.
|
|
60264
|
-
Promise.resolve().then(run).catch((err) => ({ __twzrdError: err })),
|
|
60265
|
-
new Promise((resolve) => {
|
|
60266
|
-
timer2 = setTimeout(() => resolve(TIMED_OUT), opts.timeoutMs);
|
|
60267
|
-
})
|
|
60268
|
-
]);
|
|
60269
|
-
if (raced === TIMED_OUT) {
|
|
60270
|
-
return decideOnGateFailure(`did not answer within ${opts.timeoutMs}ms`, opts.failOpen, log);
|
|
60271
|
-
}
|
|
60272
|
-
if (raced && typeof raced === "object" && "__twzrdError" in raced) {
|
|
60273
|
-
const err = raced.__twzrdError;
|
|
60274
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
60275
|
-
return decideOnGateFailure(`threw: ${msg.slice(0, 120)}`, opts.failOpen, log);
|
|
60276
|
-
}
|
|
60277
|
-
return raced;
|
|
60278
|
-
} finally {
|
|
60279
|
-
if (timer2) clearTimeout(timer2);
|
|
60280
|
-
}
|
|
60281
|
-
}
|
|
60282
|
-
function decideOnGateFailure(what, failOpen, log) {
|
|
60283
|
-
const reason = `twzrd gate ${what}`;
|
|
60284
|
-
if (failOpen) {
|
|
60285
|
-
log.warn(
|
|
60286
|
-
`[ClawRouter] ${reason} \u2014 proceeding. SpendControl still applied. Set TWZRD_FAIL_OPEN=false to refuse instead.`
|
|
60287
|
-
);
|
|
60288
|
-
return void 0;
|
|
60289
|
-
}
|
|
60290
|
-
log.warn(`[ClawRouter] ${reason} \u2014 refusing the payment (TWZRD_FAIL_OPEN=false).`);
|
|
60291
|
-
return { abort: true, reason };
|
|
60292
|
-
}
|
|
60293
|
-
async function defaultLoadTwzrdGate() {
|
|
60294
|
-
const specifier = TWZRD_GATE_PACKAGE;
|
|
60295
|
-
return import(specifier);
|
|
60296
|
-
}
|
|
60297
|
-
async function maybeComposeTwzrdAutoGate(x402, options) {
|
|
60298
|
-
const env = options?.env ?? process.env;
|
|
60299
|
-
const log = options?.log ?? console;
|
|
60300
|
-
if (!isTwzrdAutoGateEnabled(env)) {
|
|
60301
|
-
return { status: "skipped" };
|
|
60302
|
-
}
|
|
60303
|
-
const load = options?.loadGate ?? defaultLoadTwzrdGate;
|
|
60304
|
-
let gate;
|
|
60305
|
-
try {
|
|
60306
|
-
gate = await load();
|
|
60307
|
-
} catch (err) {
|
|
60308
|
-
if (isMissingTwzrdGateModule(err)) {
|
|
60309
|
-
const reason = `${TWZRD_GATE_PACKAGE} is not installed`;
|
|
60310
|
-
log.warn(
|
|
60311
|
-
`[ClawRouter] TWZRD AutoGate opted in but ${reason} \u2014 skipping. npm i ${TWZRD_GATE_PACKAGE}@0.9.3`
|
|
60312
|
-
);
|
|
60313
|
-
return { status: "unavailable", reason };
|
|
60314
|
-
}
|
|
60315
|
-
throw err;
|
|
60316
|
-
}
|
|
60317
|
-
const installOpts = twzrdAutoGateInstallOptions(env);
|
|
60318
|
-
const timeoutMs = twzrdGateTimeoutMs(env);
|
|
60319
|
-
const ready = (via) => log.log(
|
|
60320
|
-
`[ClawRouter] TWZRD AutoGate ON (opt-in, after SpendControl, ${via}; ${timeoutMs}ms budget, failOpen=${installOpts.failOpen}). Unset TWZRD_AUTO_GATE to disable.`
|
|
60321
|
-
);
|
|
60322
|
-
if (typeof gate.createTwzrdBeforePaymentHook === "function") {
|
|
60323
|
-
const hook = gate.createTwzrdBeforePaymentHook(installOpts);
|
|
60324
|
-
x402.onBeforePaymentCreation(
|
|
60325
|
-
async (ctx) => runTwzrdGateWithTimeout(() => hook(ctx.selectedRequirements, ctx), {
|
|
60326
|
-
timeoutMs,
|
|
60327
|
-
failOpen: installOpts.failOpen,
|
|
60328
|
-
log
|
|
60329
|
-
})
|
|
60330
|
-
);
|
|
60331
|
-
ready("createTwzrdBeforePaymentHook");
|
|
60332
|
-
return { status: "composed", via: "createTwzrdBeforePaymentHook" };
|
|
60333
|
-
}
|
|
60334
|
-
if (typeof gate.installTwzrdAutoGate === "function") {
|
|
60335
|
-
gate.installTwzrdAutoGate(x402, installOpts);
|
|
60336
|
-
log.warn(
|
|
60337
|
-
"[ClawRouter] TWZRD AutoGate installed via installTwzrdAutoGate \u2014 that entry point registers its own hook, so the timeout budget does not apply and it replaces onBeforePaymentCreation on this client. Prefer a gate build exporting createTwzrdBeforePaymentHook."
|
|
60338
|
-
);
|
|
60339
|
-
ready("installTwzrdAutoGate");
|
|
60340
|
-
return { status: "composed", via: "installTwzrdAutoGate" };
|
|
60341
|
-
}
|
|
60342
|
-
throw new Error(
|
|
60343
|
-
`[ClawRouter] ${TWZRD_GATE_PACKAGE} is installed but exports neither installTwzrdAutoGate nor createTwzrdBeforePaymentHook`
|
|
60344
|
-
);
|
|
60345
|
-
}
|
|
60346
|
-
var TWZRD_GATE_PACKAGE, TRUTHY, FALSY, TWZRD_GATE_TIMEOUT_MS, TIMED_OUT;
|
|
60347
|
-
var init_twzrd_autogate = __esm({
|
|
60348
|
-
"src/twzrd-autogate.ts"() {
|
|
60349
|
-
"use strict";
|
|
60350
|
-
init_version4();
|
|
60351
|
-
TWZRD_GATE_PACKAGE = "twzrd-x402-gate";
|
|
60352
|
-
TRUTHY = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
|
|
60353
|
-
FALSY = /* @__PURE__ */ new Set(["0", "false", "no", "off"]);
|
|
60354
|
-
TWZRD_GATE_TIMEOUT_MS = 2e3;
|
|
60355
|
-
TIMED_OUT = { __twzrdTimedOut: true };
|
|
60356
|
-
}
|
|
60357
|
-
});
|
|
60358
|
-
|
|
60359
60216
|
// src/compression/types.ts
|
|
60360
60217
|
var DEFAULT_COMPRESSION_CONFIG;
|
|
60361
60218
|
var init_types2 = __esm({
|
|
@@ -91940,7 +91797,6 @@ async function startProxy(options) {
|
|
|
91940
91797
|
const evmSigner = toClientEvmSigner(account, evmPublicClient);
|
|
91941
91798
|
const spendControl = options.spendControl ?? getSharedSpendControl();
|
|
91942
91799
|
registerSpendPolicyHook(x402, spendControl);
|
|
91943
|
-
await maybeComposeTwzrdAutoGate(x402);
|
|
91944
91800
|
registerExactEvmScheme(x402, { signer: evmSigner });
|
|
91945
91801
|
}
|
|
91946
91802
|
let solanaAddress;
|
|
@@ -95526,7 +95382,6 @@ var init_proxy = __esm({
|
|
|
95526
95382
|
init_auth();
|
|
95527
95383
|
init_api_key();
|
|
95528
95384
|
init_spend_control();
|
|
95529
|
-
init_twzrd_autogate();
|
|
95530
95385
|
init_compression();
|
|
95531
95386
|
init_errors5();
|
|
95532
95387
|
init_version4();
|
|
@@ -228315,7 +228170,7 @@ import {
|
|
|
228315
228170
|
} from "fs";
|
|
228316
228171
|
import { readFile as readFileAsync } from "fs/promises";
|
|
228317
228172
|
import { homedir as homedir14 } from "os";
|
|
228318
|
-
import { randomUUID
|
|
228173
|
+
import { randomUUID } from "crypto";
|
|
228319
228174
|
import { join as join17 } from "path";
|
|
228320
228175
|
async function waitForProxyHealth(port, timeoutMs = 3e3) {
|
|
228321
228176
|
const start = Date.now();
|
|
@@ -228330,7 +228185,7 @@ async function waitForProxyHealth(port, timeoutMs = 3e3) {
|
|
|
228330
228185
|
return false;
|
|
228331
228186
|
}
|
|
228332
228187
|
function writePrivateJsonSync(path5, value) {
|
|
228333
|
-
const temporary = `${path5}.tmp.${
|
|
228188
|
+
const temporary = `${path5}.tmp.${randomUUID()}`;
|
|
228334
228189
|
try {
|
|
228335
228190
|
writeFileSync3(temporary, JSON.stringify(value, null, 2), { mode: 384 });
|
|
228336
228191
|
renameSync2(temporary, path5);
|
package/docs/configuration.md
CHANGED
|
@@ -15,7 +15,6 @@ Complete reference for ClawRouter configuration options.
|
|
|
15
15
|
- [Tier Overrides](#tier-overrides)
|
|
16
16
|
- [Scoring Weights](#scoring-weights)
|
|
17
17
|
- [Spend Control & Counterparty Policy](#spend-control--counterparty-policy)
|
|
18
|
-
- [TWZRD AutoGate (opt-in)](#twzrd-autogate-opt-in)
|
|
19
18
|
- [Testing Configuration](#testing-configuration)
|
|
20
19
|
|
|
21
20
|
---
|
|
@@ -33,9 +32,6 @@ Complete reference for ClawRouter configuration options.
|
|
|
33
32
|
| `CLAWROUTER_WORKER` | - | Set to `1` to enable Worker Mode (earn USDC by running health checks). |
|
|
34
33
|
| `CLAWROUTER_DEBUG_HEADERS` | (on) | Set to `off`/`false`/`0` to suppress the `x-clawrouter-*` debug response headers. |
|
|
35
34
|
| `BLOCKRUN_WEB_SEARCH` | (auto-enabled) | Set to `off` to disable BlockRun's Exa web search provider registration. |
|
|
36
|
-
| `TWZRD_AUTO_GATE` | unset (off) | Set to `1` to compose TWZRD AutoGate after SpendControl on the x402 pre-sign hook. Also `TWZRD_GATE_ENABLED=true`. |
|
|
37
|
-
| `TWZRD_GATE_TIMEOUT_MS` | `2000` | How long the gate may take to answer before the payment proceeds on its own. Only meaningful with the gate on. |
|
|
38
|
-
| `TWZRD_FAIL_OPEN` | `true` | Set to `false` to refuse payments when the gate is unreachable instead of proceeding. Only meaningful with the gate on. |
|
|
39
35
|
|
|
40
36
|
---
|
|
41
37
|
|
|
@@ -736,66 +732,6 @@ placement, `clawrouter doctor`'s probe) are not covered.
|
|
|
736
732
|
|
|
737
733
|
---
|
|
738
734
|
|
|
739
|
-
## TWZRD AutoGate (opt-in)
|
|
740
|
-
|
|
741
|
-
Default **off**. This is not a re-open of default-on vendor lock. SpendControl
|
|
742
|
-
above remains the vendor-neutral path; TWZRD is composed only when you ask.
|
|
743
|
-
|
|
744
|
-
```bash
|
|
745
|
-
export TWZRD_AUTO_GATE=1
|
|
746
|
-
# equivalent:
|
|
747
|
-
export TWZRD_GATE_ENABLED=true
|
|
748
|
-
```
|
|
749
|
-
|
|
750
|
-
When set, `startProxy` registers the gate's `createTwzrdBeforePaymentHook` on the
|
|
751
|
-
**same** x402 client, **after** `registerSpendPolicyHook`. SpendControl lists
|
|
752
|
-
still run first. A wash `payTo` is refused before `signTransaction`.
|
|
753
|
-
|
|
754
|
-
### What it actually covers
|
|
755
|
-
|
|
756
|
-
**Solana, not Base.** The gate's reputation corpus is Solana. `classifyNetwork`
|
|
757
|
-
returns `network_not_scored` for `base` / `eip155:*`, and under our
|
|
758
|
-
`unsupportedNetworkMode: "observe"` those are waved through with verdict
|
|
759
|
-
`unknown` and no network call. The x402 client is shared between both chains, so
|
|
760
|
-
the hook is registered once and applies to Solana payments; `refuseWashFlagged`
|
|
761
|
-
can only ever fire there.
|
|
762
|
-
|
|
763
|
-
### What leaves your machine
|
|
764
|
-
|
|
765
|
-
On a Solana payment the gate POSTs the resource URL, `payTo`, price and chain to
|
|
766
|
-
`https://intel.twzrd.xyz/v1/intel/preflight`, stamped with
|
|
767
|
-
`X-TWZRD-Integration: clawrouter/<version>` and a per-process run id. Nothing is
|
|
768
|
-
sent when the flag is unset, and nothing is sent for Base.
|
|
769
|
-
|
|
770
|
-
### Availability
|
|
771
|
-
|
|
772
|
-
The gate's own preflight sets no timeout, and the package defaults to
|
|
773
|
-
`failOpen: false` — an outage there would refuse every paid Solana call. That is
|
|
774
|
-
the shape of the v0.12.271 outage, where an unreachable third party made every
|
|
775
|
-
Solana payment fail with a bare `fetch failed`. So:
|
|
776
|
-
|
|
777
|
-
- We bound the answer at `TWZRD_GATE_TIMEOUT_MS` (default `2000`).
|
|
778
|
-
- We pass `failOpen: true`. On timeout, rejection, or outage the payment
|
|
779
|
-
proceeds and a warning names the reason. SpendControl still applies — it is
|
|
780
|
-
the vendor-neutral guarantee and is untouched by any of this.
|
|
781
|
-
- `TWZRD_FAIL_OPEN=false` restores refuse-on-outage if you would rather stop
|
|
782
|
-
paying than pay unscored.
|
|
783
|
-
|
|
784
|
-
### Other notes
|
|
785
|
-
|
|
786
|
-
- Optional dependency: `twzrd-x402-gate@0.9.3`. Forks that omit it still install.
|
|
787
|
-
- Missing gate package (`MODULE_NOT_FOUND` for `twzrd-x402-gate` itself): fail
|
|
788
|
-
open — proxy boots, payments unguarded by TWZRD. Any other load/install error
|
|
789
|
-
fails closed.
|
|
790
|
-
- We register the hook ourselves rather than calling `installTwzrdAutoGate`,
|
|
791
|
-
which replaces `onBeforePaymentCreation` on the client — that would make every
|
|
792
|
-
hook registered afterwards skippable via `TWZRD_AUTO_GATE=0`, including ours.
|
|
793
|
-
- Identity: preflight stamps `X-Twzrd-Caller: clawrouter/<version>` so a refuse
|
|
794
|
-
is attributable.
|
|
795
|
-
- Unset the flag to return to SpendControl only.
|
|
796
|
-
|
|
797
|
-
---
|
|
798
|
-
|
|
799
735
|
## Testing Configuration
|
|
800
736
|
|
|
801
737
|
### Dry Run (No Payments)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blockrun/clawrouter",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.278",
|
|
4
4
|
"description": "Smart LLM router — save 84% on inference costs. 76 models (7 free). Pay by credit card (API key) or USDC (x402 wallet).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -106,9 +106,6 @@
|
|
|
106
106
|
"undici": "^8.10.0",
|
|
107
107
|
"viem": "^2.39.3"
|
|
108
108
|
},
|
|
109
|
-
"optionalDependencies": {
|
|
110
|
-
"twzrd-x402-gate": "0.9.3"
|
|
111
|
-
},
|
|
112
109
|
"peerDependencies": {
|
|
113
110
|
"openclaw": ">=2025.1.0"
|
|
114
111
|
},
|