twzrd-x402-gate 0.9.5 → 0.9.7
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/QUICKSTART.md +3 -3
- package/README.md +34 -3
- package/bin/twzrd-bounty-preflight.js +63 -0
- package/bin/twzrd-payment-decision.js +0 -0
- package/dist/bounty-preflight-cli.d.ts +25 -0
- package/dist/bounty-preflight-cli.d.ts.map +1 -0
- package/dist/bounty-preflight-cli.js +155 -0
- package/dist/bounty-preflight-cli.js.map +1 -0
- package/dist/bounty-preflight.d.ts +140 -0
- package/dist/bounty-preflight.d.ts.map +1 -0
- package/dist/bounty-preflight.js +208 -0
- package/dist/bounty-preflight.js.map +1 -0
- package/dist/consumer-adjacency.d.ts +79 -0
- package/dist/consumer-adjacency.d.ts.map +1 -0
- package/dist/consumer-adjacency.js +236 -0
- package/dist/consumer-adjacency.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/policy-runtime.d.ts.map +1 -1
- package/dist/policy-runtime.js +34 -20
- package/dist/policy-runtime.js.map +1 -1
- package/dist/spend-control.d.ts.map +1 -1
- package/dist/spend-control.js +6 -3
- package/dist/spend-control.js.map +1 -1
- package/package.json +6 -3
package/QUICKSTART.md
CHANGED
|
@@ -5,13 +5,13 @@ API key, no signup, no config — every `TWZRD_*` env var is an optional overrid
|
|
|
5
5
|
is unreachable the gate never *invents* a wash flag (the wash check fails open); a failed
|
|
6
6
|
preflight blocks the payment by default (`TWZRD_FAIL_OPEN=true` to allow).
|
|
7
7
|
|
|
8
|
-
**Pin:** `twzrd-x402-gate@0.9.
|
|
8
|
+
**Pin:** `twzrd-x402-gate@0.9.7` + stock PayAI client `x402-solana@3.0.0` (official
|
|
9
9
|
`beforePayment` seat). `@x402/core` Path E remains supported; refuse script is fallback.
|
|
10
10
|
|
|
11
11
|
## 1. Stock PayAI client (default seat — copy-paste)
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npm install twzrd-x402-gate@0.9.
|
|
14
|
+
npm install twzrd-x402-gate@0.9.7 x402-solana@3.0.0
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
> **ESM-only.** The package ships `import` conditions only — a CommonJS
|
|
@@ -36,7 +36,7 @@ Then: `await client.fetch("https://merchant.example/paid");`
|
|
|
36
36
|
## 1b. Official `@x402/core` client (Path E)
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
npm install twzrd-x402-gate@0.9.
|
|
39
|
+
npm install twzrd-x402-gate@0.9.7 @x402/core @x402/fetch @x402/svm
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
```typescript
|
package/README.md
CHANGED
|
@@ -80,7 +80,7 @@ transfer on-chain. Wash/sybil edges are primarily discounted in TWZRD scoring, n
|
|
|
80
80
|
revenue refusal.
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
npm install twzrd-x402-gate@0.9.
|
|
83
|
+
npm install twzrd-x402-gate@0.9.7
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
```typescript
|
|
@@ -125,7 +125,7 @@ Fixture-backed SVM extract tests live in `test/seller-hook.test.ts` +
|
|
|
125
125
|
Install the published gate and run against wash fixtures:
|
|
126
126
|
|
|
127
127
|
```bash
|
|
128
|
-
npm install twzrd-x402-gate@0.9.
|
|
128
|
+
npm install twzrd-x402-gate@0.9.7
|
|
129
129
|
# from package root after install, or from a checkout:
|
|
130
130
|
npm run wash-dogfood
|
|
131
131
|
```
|
|
@@ -295,7 +295,7 @@ Dogfood (one public live proof path):
|
|
|
295
295
|
## Install
|
|
296
296
|
|
|
297
297
|
```bash
|
|
298
|
-
npm install twzrd-x402-gate@0.9.
|
|
298
|
+
npm install twzrd-x402-gate@0.9.7
|
|
299
299
|
```
|
|
300
300
|
|
|
301
301
|
Do not hardcode a version in this doc — every past pin here (**0.5.4**, **0.7.1**, **0.8.5**,
|
|
@@ -479,6 +479,37 @@ probe request → TWZRD scores challenge A → (if allowed) AgentCash request
|
|
|
479
479
|
- Exit `0` = passthrough / dry-run allowed / AgentCash returned success (binding unproven).
|
|
480
480
|
- Base/EVM: explicit `decision=unknown` (see Networks).
|
|
481
481
|
|
|
482
|
+
### CLI: `twzrd-bounty-preflight` (worker-side refuse, zero spend)
|
|
483
|
+
|
|
484
|
+
For agents that earn on bounty boards (DeskCrew arena, ClawTasks). Before you pay
|
|
485
|
+
an attempt fee or stake collateral, read the board, read the paid door's unpaid
|
|
486
|
+
402 for its payTo, gate that payTo, and decide each open row. One JSON transcript
|
|
487
|
+
on stdout (`schema: twzrd.bounty_preflight.v1`, `usdc_spent: 0`,
|
|
488
|
+
`signer_invocation_count: 0`). Exit `0` means at least one open row is eligible
|
|
489
|
+
— pay only rows with `proceed: true`. Exit `1` means none are. Nothing signs,
|
|
490
|
+
nothing spends.
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
# DeskCrew: ticket-only attempt cost; the row's entry fee is added separately
|
|
494
|
+
npx twzrd-bounty-preflight --board https://deskcrew.io/api/arena/contests \
|
|
495
|
+
--attempt-cost-usd 0.02 --max-attempt-usd 0.25 --assumed-win-prob 0.2
|
|
496
|
+
|
|
497
|
+
# Any other board: name its paid door explicitly
|
|
498
|
+
npx twzrd-bounty-preflight --board https://clawtasks.com/api/bounties?status=open \
|
|
499
|
+
--paid-endpoint https://clawtasks.com/api/paid --my-networks base --allow-unscored-payee
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Refuse reasons, in order: `gate_block` / `gate_wash_flagged` (TWZRD refused the
|
|
503
|
+
payee), `gate_unscored` (the payee's rail is outside the behavioral corpus, today
|
|
504
|
+
any non-Solana payTo; the gate's "allow" there is a policy pass-through, never a
|
|
505
|
+
trust allow; opt in with `--allow-unscored-payee`, wash still refuses),
|
|
506
|
+
`payout_network_unsupported` / `payout_network_unknown`, `attempt_cost_over_max`
|
|
507
|
+
(attempt fee + board entry fee + stake vs the ceiling), `below_break_even` /
|
|
508
|
+
`assumed_win_prob_missing` (your declared win probability vs
|
|
509
|
+
`at_risk / (agent_share * bounty)`). The board's approval rate and contest size
|
|
510
|
+
are reported as naive and contested EV for context only; they are never
|
|
511
|
+
substituted for `--assumed-win-prob`. Self-serve transcript, not adoption proof.
|
|
512
|
+
|
|
482
513
|
Library: `import { safeFetch } from "twzrd-x402-gate/safe-fetch"`.
|
|
483
514
|
|
|
484
515
|
## Quickstart: `installTwzrdAutoGate` (default-on)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Worker preflight for agent bounty boards — zero spend.
|
|
4
|
+
*
|
|
5
|
+
* Before a bounty-hunting agent pays an attempt fee or stakes collateral, read the
|
|
6
|
+
* board, read the paid door's unpaid 402 for its payTo, run the free TWZRD gate on
|
|
7
|
+
* that payTo, and decide per open row: gate block/wash, payout rail, money at risk
|
|
8
|
+
* vs ceiling, and YOUR declared win probability vs break-even. Prints one JSON
|
|
9
|
+
* report (schema twzrd.bounty_preflight.v1) and exits 1 on refuse.
|
|
10
|
+
*
|
|
11
|
+
* Nothing here signs or spends. The board's approval rate is context only; it is
|
|
12
|
+
* never substituted for --assumed-win-prob. Self-serve transcript, not adoption proof.
|
|
13
|
+
*
|
|
14
|
+
* Usage (after npm run build, or from the published package):
|
|
15
|
+
* node node_modules/twzrd-x402-gate/bin/twzrd-bounty-preflight.js \
|
|
16
|
+
* --board https://deskcrew.io/api/arena/contests --assumed-win-prob 0.2
|
|
17
|
+
*/
|
|
18
|
+
import { dirname, join } from "node:path";
|
|
19
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
20
|
+
import { existsSync } from "node:fs";
|
|
21
|
+
|
|
22
|
+
const pkgRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
23
|
+
|
|
24
|
+
async function loadCli() {
|
|
25
|
+
const dist = join(pkgRoot, "dist", "bounty-preflight-cli.js");
|
|
26
|
+
if (existsSync(dist)) return import(pathToFileURL(dist).href);
|
|
27
|
+
console.error("twzrd-bounty-preflight: run `npm run build` in twzrd-x402-gate or install the published package");
|
|
28
|
+
process.exit(2);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function main() {
|
|
32
|
+
const { parseArgs, runBountyPreflight, USAGE } = await loadCli();
|
|
33
|
+
let args;
|
|
34
|
+
try {
|
|
35
|
+
args = parseArgs(process.argv.slice(2));
|
|
36
|
+
} catch (e) {
|
|
37
|
+
console.error(`twzrd-bounty-preflight: ${e instanceof Error ? e.message : e}`);
|
|
38
|
+
console.error(USAGE);
|
|
39
|
+
process.exit(2);
|
|
40
|
+
}
|
|
41
|
+
// The gate library narrates (e.g. unsupported_network_seen) on stdout; keep stdout a
|
|
42
|
+
// single JSON document by routing that narration to stderr for the duration of the run.
|
|
43
|
+
const { log, info } = console;
|
|
44
|
+
console.log = (...a) => console.error(...a);
|
|
45
|
+
console.info = (...a) => console.error(...a);
|
|
46
|
+
let run;
|
|
47
|
+
try {
|
|
48
|
+
run = await runBountyPreflight(args);
|
|
49
|
+
} finally {
|
|
50
|
+
console.log = log;
|
|
51
|
+
console.info = info;
|
|
52
|
+
}
|
|
53
|
+
const { report, exitCode } = run;
|
|
54
|
+
console.log(JSON.stringify(report, null, 2));
|
|
55
|
+
if (exitCode) console.error(`REFUSE: ${report.refuse_reasons.join(", ")} (nothing signed, nothing spent)`);
|
|
56
|
+
else console.error("OK: proceed — self-serve transcript, not external partner proof; nothing signed, nothing spent");
|
|
57
|
+
process.exit(exitCode);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
main().catch((e) => {
|
|
61
|
+
console.error("twzrd-bounty-preflight FAILED", e instanceof Error ? e.message : e);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestration behind bin/twzrd-bounty-preflight.js, with fetch and the gate
|
|
3
|
+
* injected so it can be tested without a network. Read-only: board GET, unpaid 402
|
|
4
|
+
* GET, and the free TWZRD intel hop inside evaluate — each bounded by 15s. Nothing
|
|
5
|
+
* is signed, nothing is spent.
|
|
6
|
+
*/
|
|
7
|
+
import { type EvaluateX402Options, type EvaluateX402Result } from "./evaluate.js";
|
|
8
|
+
import { type DecideArgs, type PreflightReport } from "./bounty-preflight.js";
|
|
9
|
+
import type { X402PaymentRequirements } from "./types.js";
|
|
10
|
+
export type PreflightArgs = DecideArgs & {
|
|
11
|
+
boardUrl: string;
|
|
12
|
+
paidEndpoint: string;
|
|
13
|
+
};
|
|
14
|
+
export type EvaluateFn = (url: string, req: X402PaymentRequirements, opts: EvaluateX402Options) => Promise<Pick<EvaluateX402Result, "decision" | "approved" | "reason"> & Partial<EvaluateX402Result>>;
|
|
15
|
+
export declare const USAGE = "usage: twzrd-bounty-preflight --board <https url> [--paid-endpoint <https url>]\n [--attempt-cost-usd 0.02] [--max-attempt-usd <usd>] [--assumed-win-prob <0..1>]\n [--my-networks solana,base]\n\n --board board descriptor: DeskCrew arena JSON or a ClawTasks open-bounty list\n --paid-endpoint the board's x402 door; its unpaid 402 names the payTo the gate scores\n (defaults to the paid ping for deskcrew.io)\n --attempt-cost-usd money you spend per attempt BEFORE any board entry fee or stake\n (default 0.02, DeskCrew ticket). at_risk = this + entry_fee + stake\n --max-attempt-usd ceiling on money at risk per attempt (fee + entry fee + stake)\n --assumed-win-prob YOUR declared paid-win probability; the board's approval rate is\n never substituted for it. Without it the tool refuses.\n --my-networks rails your wallet can receive on (default solana,base)\n --allow-unscored-payee\n proceed when the gate cannot score the payee's rail (today: any\n non-Solana payTo). Wash still refuses. Default: refuse (gate_unscored).\n\n Exit 0 means at least one open row is eligible \u2014 pay only rows with proceed:true.\n Exit 1 means none are (see refuse_reasons). Exit 2 is a bad invocation.";
|
|
16
|
+
export declare function parseArgs(argv: string[]): PreflightArgs;
|
|
17
|
+
export declare function runBountyPreflight(args: PreflightArgs, { fetch: doFetch, evaluate, now }?: {
|
|
18
|
+
fetch?: typeof fetch;
|
|
19
|
+
evaluate?: EvaluateFn;
|
|
20
|
+
now?: () => string;
|
|
21
|
+
}): Promise<{
|
|
22
|
+
report: PreflightReport;
|
|
23
|
+
exitCode: 0 | 1;
|
|
24
|
+
}>;
|
|
25
|
+
//# sourceMappingURL=bounty-preflight-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounty-preflight-cli.d.ts","sourceRoot":"","sources":["../src/bounty-preflight-cli.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAA0B,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAE1G,OAAO,EAA8C,KAAK,UAAU,EAAoB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC5I,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,UAAU,GAAG,CACvB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,uBAAuB,EAC5B,IAAI,EAAE,mBAAmB,KACtB,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;AASzG,eAAO,MAAM,KAAK,2zCAkBwD,CAAC;AA8B3E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAgCvD;AAID,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,aAAa,EACnB,EAAE,KAAK,EAAE,OAA0B,EAAE,QAA+C,EAAE,GAAoC,EAAE,GAC1H;IAAE,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAAO,GACzE,OAAO,CAAC;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAA;CAAE,CAAC,CAoCvD"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestration behind bin/twzrd-bounty-preflight.js, with fetch and the gate
|
|
3
|
+
* injected so it can be tested without a network. Read-only: board GET, unpaid 402
|
|
4
|
+
* GET, and the free TWZRD intel hop inside evaluate — each bounded by 15s. Nothing
|
|
5
|
+
* is signed, nothing is spent.
|
|
6
|
+
*/
|
|
7
|
+
import { evaluate_x402_resource } from "./evaluate.js";
|
|
8
|
+
import { paymentRequiredFromResponse, payToFromRequirements, pickRequirements, priceUsdcFromAmountMicro } from "./payto.js";
|
|
9
|
+
import { buildPreflightReport, parseBoardDescriptor } from "./bounty-preflight.js";
|
|
10
|
+
/** Boards whose paid door is known, so `--paid-endpoint` can be omitted. */
|
|
11
|
+
const DEFAULT_PAID_ENDPOINTS = {
|
|
12
|
+
"deskcrew.io": "https://deskcrew.io/api/x402/paid/ping",
|
|
13
|
+
};
|
|
14
|
+
const DEFAULT_ATTEMPT_COST_USD = 0.02; // DeskCrew ticket only; row.entry_fee_usd carries the $0.06 submission
|
|
15
|
+
const DEFAULT_NETWORKS = ["solana", "base"];
|
|
16
|
+
export const USAGE = `usage: twzrd-bounty-preflight --board <https url> [--paid-endpoint <https url>]
|
|
17
|
+
[--attempt-cost-usd 0.02] [--max-attempt-usd <usd>] [--assumed-win-prob <0..1>]
|
|
18
|
+
[--my-networks solana,base]
|
|
19
|
+
|
|
20
|
+
--board board descriptor: DeskCrew arena JSON or a ClawTasks open-bounty list
|
|
21
|
+
--paid-endpoint the board's x402 door; its unpaid 402 names the payTo the gate scores
|
|
22
|
+
(defaults to the paid ping for deskcrew.io)
|
|
23
|
+
--attempt-cost-usd money you spend per attempt BEFORE any board entry fee or stake
|
|
24
|
+
(default 0.02, DeskCrew ticket). at_risk = this + entry_fee + stake
|
|
25
|
+
--max-attempt-usd ceiling on money at risk per attempt (fee + entry fee + stake)
|
|
26
|
+
--assumed-win-prob YOUR declared paid-win probability; the board's approval rate is
|
|
27
|
+
never substituted for it. Without it the tool refuses.
|
|
28
|
+
--my-networks rails your wallet can receive on (default solana,base)
|
|
29
|
+
--allow-unscored-payee
|
|
30
|
+
proceed when the gate cannot score the payee's rail (today: any
|
|
31
|
+
non-Solana payTo). Wash still refuses. Default: refuse (gate_unscored).
|
|
32
|
+
|
|
33
|
+
Exit 0 means at least one open row is eligible — pay only rows with proceed:true.
|
|
34
|
+
Exit 1 means none are (see refuse_reasons). Exit 2 is a bad invocation.`;
|
|
35
|
+
const BOOLEAN_FLAGS = new Set(["--allow-unscored-payee"]);
|
|
36
|
+
const VALUE_FLAGS = new Set(["--board", "--paid-endpoint", "--attempt-cost-usd", "--max-attempt-usd", "--assumed-win-prob", "--my-networks"]);
|
|
37
|
+
/** Bound on every network read: board descriptor, unpaid 402, and the free intel hop inside evaluate. */
|
|
38
|
+
const FETCH_TIMEOUT_MS = 15_000;
|
|
39
|
+
function withTimeout(doFetch) {
|
|
40
|
+
return ((input, init) => {
|
|
41
|
+
const timeout = AbortSignal.timeout(FETCH_TIMEOUT_MS);
|
|
42
|
+
const signal = init?.signal ? AbortSignal.any([init.signal, timeout]) : timeout;
|
|
43
|
+
return doFetch(input, { ...init, signal });
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function httpsUrl(flag, raw) {
|
|
47
|
+
if (!raw)
|
|
48
|
+
throw new Error(`${flag} is required`);
|
|
49
|
+
let u;
|
|
50
|
+
try {
|
|
51
|
+
u = new URL(raw);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
throw new Error(`${flag} must be an https URL`);
|
|
55
|
+
}
|
|
56
|
+
if (u.protocol !== "https:")
|
|
57
|
+
throw new Error(`${flag} must be an https URL`);
|
|
58
|
+
return u.toString();
|
|
59
|
+
}
|
|
60
|
+
function nonNegative(flag, raw, fallback) {
|
|
61
|
+
if (raw === undefined)
|
|
62
|
+
return fallback;
|
|
63
|
+
const n = Number(raw);
|
|
64
|
+
if (!Number.isFinite(n) || n < 0)
|
|
65
|
+
throw new Error(`${flag} must be a non-negative number`);
|
|
66
|
+
return n;
|
|
67
|
+
}
|
|
68
|
+
export function parseArgs(argv) {
|
|
69
|
+
const flags = new Map();
|
|
70
|
+
const switches = new Set();
|
|
71
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
72
|
+
const a = argv[i];
|
|
73
|
+
if (!a.startsWith("--"))
|
|
74
|
+
throw new Error(`unexpected argument ${a}`);
|
|
75
|
+
if (BOOLEAN_FLAGS.has(a)) {
|
|
76
|
+
switches.add(a);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (!VALUE_FLAGS.has(a))
|
|
80
|
+
throw new Error(`unknown flag ${a}`);
|
|
81
|
+
if (flags.has(a))
|
|
82
|
+
throw new Error(`repeated flag ${a}`);
|
|
83
|
+
const v = argv[i + 1];
|
|
84
|
+
if (v === undefined || v.startsWith("--"))
|
|
85
|
+
throw new Error(`${a} needs a value`);
|
|
86
|
+
flags.set(a, v);
|
|
87
|
+
i += 1;
|
|
88
|
+
}
|
|
89
|
+
const boardUrl = httpsUrl("--board", flags.get("--board"));
|
|
90
|
+
const host = new URL(boardUrl).hostname.replace(/^www\./, "");
|
|
91
|
+
const paidEndpoint = flags.has("--paid-endpoint")
|
|
92
|
+
? httpsUrl("--paid-endpoint", flags.get("--paid-endpoint"))
|
|
93
|
+
: DEFAULT_PAID_ENDPOINTS[host];
|
|
94
|
+
if (!paidEndpoint)
|
|
95
|
+
throw new Error("--paid-endpoint is required for this board (no known paid door)");
|
|
96
|
+
const attemptCostUsd = nonNegative("--attempt-cost-usd", flags.get("--attempt-cost-usd"), DEFAULT_ATTEMPT_COST_USD);
|
|
97
|
+
const maxAttemptUsd = nonNegative("--max-attempt-usd", flags.get("--max-attempt-usd"), null);
|
|
98
|
+
let assumedWinProb = null;
|
|
99
|
+
if (flags.has("--assumed-win-prob")) {
|
|
100
|
+
const p = Number(flags.get("--assumed-win-prob"));
|
|
101
|
+
if (!Number.isFinite(p) || p < 0 || p > 1)
|
|
102
|
+
throw new Error("--assumed-win-prob must be between 0 and 1");
|
|
103
|
+
assumedWinProb = p;
|
|
104
|
+
}
|
|
105
|
+
const myNetworks = (flags.get("--my-networks") ?? DEFAULT_NETWORKS.join(","))
|
|
106
|
+
.split(",").map((s) => s.trim()).filter(Boolean);
|
|
107
|
+
if (!myNetworks.length)
|
|
108
|
+
throw new Error("--my-networks must name at least one rail");
|
|
109
|
+
return { boardUrl, paidEndpoint, attemptCostUsd, maxAttemptUsd, assumedWinProb, myNetworks, allowUnscored: switches.has("--allow-unscored-payee") };
|
|
110
|
+
}
|
|
111
|
+
const UNGATED = (reason) => ({ decision: "unknown", approved: false, reason, payTo: null, network: null, priceUsdc: null, reputationScored: false, policyAction: null });
|
|
112
|
+
export async function runBountyPreflight(args, { fetch: doFetch = globalThis.fetch, evaluate = evaluate_x402_resource, now = () => new Date().toISOString() } = {}) {
|
|
113
|
+
const fetchBound = withTimeout(doFetch);
|
|
114
|
+
const jsonGet = { headers: { accept: "application/json" } };
|
|
115
|
+
const boardRes = await fetchBound(args.boardUrl, jsonGet);
|
|
116
|
+
if (!boardRes.ok)
|
|
117
|
+
throw new Error(`board GET ${boardRes.status}`);
|
|
118
|
+
let boardJson;
|
|
119
|
+
try {
|
|
120
|
+
boardJson = JSON.parse(await boardRes.text());
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
throw new Error("board descriptor is not JSON");
|
|
124
|
+
}
|
|
125
|
+
const board = parseBoardDescriptor(boardJson);
|
|
126
|
+
// The unpaid 402 is the only honest source of the payTo the worker is about to pay.
|
|
127
|
+
let gate;
|
|
128
|
+
const paidRes = await fetchBound(args.paidEndpoint, jsonGet);
|
|
129
|
+
if (paidRes.status !== 402)
|
|
130
|
+
gate = UNGATED("paid_endpoint_not_402");
|
|
131
|
+
else {
|
|
132
|
+
const challenge = await paymentRequiredFromResponse(paidRes);
|
|
133
|
+
const req = pickRequirements(challenge?.accepts);
|
|
134
|
+
const { payTo, amountMicro } = payToFromRequirements(req);
|
|
135
|
+
if (!payTo)
|
|
136
|
+
gate = UNGATED("paid_endpoint_no_payto");
|
|
137
|
+
else {
|
|
138
|
+
const result = await evaluate(args.paidEndpoint, req, { gateOnCanSpend: false, refuseWashFlagged: true, failOpen: false, fetch: fetchBound });
|
|
139
|
+
gate = {
|
|
140
|
+
decision: result.decision,
|
|
141
|
+
approved: result.approved,
|
|
142
|
+
reason: result.reason,
|
|
143
|
+
payTo,
|
|
144
|
+
network: req.network ?? null,
|
|
145
|
+
priceUsdc: priceUsdcFromAmountMicro(amountMicro) ?? null,
|
|
146
|
+
reputationScored: result.reputationScored ?? null,
|
|
147
|
+
policyAction: result.policyAction ?? null,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const { boardUrl, paidEndpoint, ...decideArgs } = args;
|
|
152
|
+
const report = buildPreflightReport({ board, boardUrl, paidEndpoint, gate, args: decideArgs, checkedAt: now() });
|
|
153
|
+
return { report, exitCode: report.proceed ? 0 : 1 };
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=bounty-preflight-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounty-preflight-cli.js","sourceRoot":"","sources":["../src/bounty-preflight-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker-side bounty preflight (pure).
|
|
3
|
+
*
|
|
4
|
+
* A bounty-hunting agent pays a small attempt fee (or stakes collateral) before it
|
|
5
|
+
* knows whether a human will accept its work. Before that money moves, this module
|
|
6
|
+
* answers four questions from public board data plus a TWZRD verdict on the board's
|
|
7
|
+
* payTo:
|
|
8
|
+
*
|
|
9
|
+
* 1. Did TWZRD refuse the payee (block / wash)?
|
|
10
|
+
* 2. Can this wallet receive on the row's payout rail?
|
|
11
|
+
* 3. Is the money at risk (attempt fee + entry fee + stake) under the ceiling?
|
|
12
|
+
* 4. Does the OPERATOR'S declared win probability clear break-even?
|
|
13
|
+
*
|
|
14
|
+
* It reports the board's approval rate, contest size, and two EV estimates for
|
|
15
|
+
* context, but it never turns a board-wide approval rate into the caller's own
|
|
16
|
+
* paid-win probability: that number has to be declared. Nothing here signs or spends.
|
|
17
|
+
*/
|
|
18
|
+
export declare const BOUNTY_PREFLIGHT_SCHEMA = "twzrd.bounty_preflight.v1";
|
|
19
|
+
export type BoardSource = "deskcrew" | "clawtasks";
|
|
20
|
+
export type BoardRow = {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string | null;
|
|
23
|
+
bounty_usd: number | null;
|
|
24
|
+
/** Fraction of the bounty the worker receives on acceptance (0..1). */
|
|
25
|
+
agent_share: number | null;
|
|
26
|
+
entrants: number | null;
|
|
27
|
+
payout_network: string | null;
|
|
28
|
+
approval_rate_pct: number | null;
|
|
29
|
+
/** Fee the board charges to enter this row, on top of the caller's attempt cost. */
|
|
30
|
+
entry_fee_usd: number;
|
|
31
|
+
/** Collateral at risk on final rejection (ClawTasks: 10% of the bounty). */
|
|
32
|
+
stake_usd: number;
|
|
33
|
+
source: BoardSource;
|
|
34
|
+
};
|
|
35
|
+
export type BoardEconomics = {
|
|
36
|
+
decided_count?: number | null;
|
|
37
|
+
open_bounties?: number | null;
|
|
38
|
+
payouts_sent?: number | null;
|
|
39
|
+
payouts_usd?: number | null;
|
|
40
|
+
unique_wallets?: number | null;
|
|
41
|
+
median_decision_hours?: number | null;
|
|
42
|
+
};
|
|
43
|
+
export type BoardDescriptor = {
|
|
44
|
+
source: BoardSource;
|
|
45
|
+
agent_share: number | null;
|
|
46
|
+
approval_rate_pct: number | null;
|
|
47
|
+
economics: BoardEconomics;
|
|
48
|
+
open_rows: BoardRow[];
|
|
49
|
+
};
|
|
50
|
+
/** What the TWZRD gate said about the board's payTo (from evaluate_x402_resource).
|
|
51
|
+
* `reputationScored: false` means the rail is outside the behavioral corpus
|
|
52
|
+
* (today: anything but Solana) and `approved` is a policy pass-through with only
|
|
53
|
+
* the wash axis checked. A policy allow is never a trust allow. */
|
|
54
|
+
export type GateVerdict = {
|
|
55
|
+
decision: "allow" | "warn" | "block" | "unknown";
|
|
56
|
+
approved: boolean;
|
|
57
|
+
reason: string;
|
|
58
|
+
payTo?: string | null;
|
|
59
|
+
network?: string | null;
|
|
60
|
+
priceUsdc?: number | null;
|
|
61
|
+
washFlagged?: boolean | null;
|
|
62
|
+
reputationScored?: boolean | null;
|
|
63
|
+
policyAction?: "allow" | "block" | null;
|
|
64
|
+
};
|
|
65
|
+
export type DecideArgs = {
|
|
66
|
+
attemptCostUsd: number;
|
|
67
|
+
maxAttemptUsd: number | null;
|
|
68
|
+
assumedWinProb: number | null;
|
|
69
|
+
myNetworks: string[];
|
|
70
|
+
/** Proceed on a payee the gate could not score (wash still refuses). Default false. */
|
|
71
|
+
allowUnscored: boolean;
|
|
72
|
+
};
|
|
73
|
+
export type DecideInput = DecideArgs & {
|
|
74
|
+
row: BoardRow;
|
|
75
|
+
gate: GateVerdict | null;
|
|
76
|
+
};
|
|
77
|
+
export type Decision = {
|
|
78
|
+
proceed: boolean;
|
|
79
|
+
reasons: string[];
|
|
80
|
+
at_risk_usd: number;
|
|
81
|
+
break_even_win_prob: number | null;
|
|
82
|
+
ev_naive_usd: number | null;
|
|
83
|
+
ev_contested_usd: number | null;
|
|
84
|
+
};
|
|
85
|
+
export declare function normalizeNetwork(raw: unknown): string | null;
|
|
86
|
+
/** Money at risk over the worker's share of the bounty. 0 when nothing is at risk. */
|
|
87
|
+
export declare function breakEvenWinProb(atRiskUsd: number, agentShare: number | null, bountyUsd: number | null): number | null;
|
|
88
|
+
/**
|
|
89
|
+
* GET https://deskcrew.io/api/arena/contests. Board-level economics are read from the
|
|
90
|
+
* live shape (2026-09-10). The board carried no open rows that day, so row keys follow
|
|
91
|
+
* the descriptor's own prose (entrants, payoutNetwork, entry fee) and its bountyCurve
|
|
92
|
+
* (bountyUsd); unknown rows degrade to nulls rather than invented figures.
|
|
93
|
+
*/
|
|
94
|
+
export declare function parseDeskcrewDescriptor(json: unknown): BoardDescriptor;
|
|
95
|
+
/** GET https://clawtasks.com/api/bounties?status=open: Base escrow, worker keeps 95%,
|
|
96
|
+
* 10% of the bounty is staked and lost on final rejection. */
|
|
97
|
+
export declare function parseClawtasksOpen(json: unknown): BoardDescriptor;
|
|
98
|
+
export declare function parseBoardDescriptor(json: unknown): BoardDescriptor;
|
|
99
|
+
export declare function decideBounty({ row, attemptCostUsd, maxAttemptUsd, assumedWinProb, myNetworks, allowUnscored, gate }: DecideInput): Decision;
|
|
100
|
+
export type PreflightReport = {
|
|
101
|
+
schema: typeof BOUNTY_PREFLIGHT_SCHEMA;
|
|
102
|
+
lineage: "self_serve_handoff_command";
|
|
103
|
+
closes_external_adoption_metric: false;
|
|
104
|
+
note: string;
|
|
105
|
+
checked_at: string;
|
|
106
|
+
board_url: string;
|
|
107
|
+
paid_endpoint: string;
|
|
108
|
+
usdc_spent: 0;
|
|
109
|
+
signer_invocation_count: 0;
|
|
110
|
+
args: DecideArgs;
|
|
111
|
+
board: {
|
|
112
|
+
source: BoardSource;
|
|
113
|
+
agent_share: number | null;
|
|
114
|
+
approval_rate_pct: number | null;
|
|
115
|
+
economics: BoardEconomics;
|
|
116
|
+
open_rows: number;
|
|
117
|
+
};
|
|
118
|
+
gate: {
|
|
119
|
+
decision: GateVerdict["decision"];
|
|
120
|
+
approved: boolean;
|
|
121
|
+
reason: string;
|
|
122
|
+
pay_to: string | null;
|
|
123
|
+
network: string | null;
|
|
124
|
+
price_usdc: number | null;
|
|
125
|
+
reputation_scored: boolean;
|
|
126
|
+
policy_action: "allow" | "block" | null;
|
|
127
|
+
} | null;
|
|
128
|
+
rows: Array<BoardRow & Decision>;
|
|
129
|
+
proceed: boolean;
|
|
130
|
+
refuse_reasons: string[];
|
|
131
|
+
};
|
|
132
|
+
export declare function buildPreflightReport({ board, boardUrl, paidEndpoint, gate, args, checkedAt }: {
|
|
133
|
+
board: BoardDescriptor;
|
|
134
|
+
boardUrl: string;
|
|
135
|
+
paidEndpoint: string;
|
|
136
|
+
gate: GateVerdict | null;
|
|
137
|
+
args: DecideArgs;
|
|
138
|
+
checkedAt: string;
|
|
139
|
+
}): PreflightReport;
|
|
140
|
+
//# sourceMappingURL=bounty-preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounty-preflight.d.ts","sourceRoot":"","sources":["../src/bounty-preflight.ts"],"names":[],"mappings":"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"}
|