-
Notifications
You must be signed in to change notification settings - Fork 652
fix(spend-control): one process-wide ledger shared by proxy, Polymarket, doctor and /policy #322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5a853ed
5a9d561
5dd8b3c
61fc425
acf3e30
3811435
d405603
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -96,10 +96,10 @@ import { privateKeyToAccount } from "viem/accounts"; | |
| import { getStats } from "./stats.js"; | ||
| import { buildPartnerTools, PARTNER_SERVICES } from "./partners/index.js"; | ||
| import { buildPolymarketTool } from "./polymarket/tool.js"; | ||
| import { getSharedSpendControl } from "./spend-control.js"; | ||
| import { createStatsCommand } from "./commands/stats.js"; | ||
| import { createExcludeCommand } from "./commands/exclude.js"; | ||
| import { createPolicyCommand } from "./commands/policy.js"; | ||
| import { SpendControl } from "./spend-control.js"; | ||
| import { BLOCKRUN_MCP_SERVER_NAME, removeManagedBlockrunMcpServerConfig } from "./mcp-config.js"; | ||
| import { BLOCKRUN_PLUGIN_ID, prepareBlockRunPluginConfig } from "./openclaw-plugin-config.js"; | ||
|
|
||
|
|
@@ -752,14 +752,6 @@ function removeInjectedAuthPlaceholder( | |
|
|
||
| // Store active proxy handle for cleanup on gateway_stop | ||
| let activeProxyHandle: Awaited<ReturnType<typeof startProxy>> | null = null; | ||
| /** | ||
| * The SpendControl handed to the most recent startProxy(). Only meaningful | ||
| * while activeProxyHandle is set: it is created before startup so it can be | ||
| * passed in, so a failed or superseded start, or a stopped proxy, must not | ||
| * let /policy claim "applied to the running proxy" — the getter below gates | ||
| * on the handle, which every stop/reset path already clears. | ||
| */ | ||
| let liveSpendControl: SpendControl | null = null; | ||
| let pendingConfiguredStartupApi: OpenClawPluginApi | null = null; | ||
| type ProcessWithClawRouterState = NodeJS.Process & { | ||
| __clawrouterProxyStarted?: boolean; | ||
|
|
@@ -958,12 +950,19 @@ async function startProxyInBackground( | |
| ); | ||
| } | ||
|
|
||
| // Restart semantics for the process-wide ledger: history and rolling | ||
| // windows survive an in-process proxy restart, but limits are re-read so a | ||
| // hand-edit to spending.json made while the proxy was up still applies. | ||
| getSharedSpendControl().reloadLimits(); | ||
| const proxy = await startProxy({ | ||
| ...(apiKey ? { apiKey } : { wallet: wallet! }), | ||
| routingConfig, | ||
| maxCostPerRunUsd, | ||
| maxCostPerRunMode, | ||
| spendControl: (liveSpendControl = new SpendControl()), | ||
| // The process-wide ledger: the polymarket tool and the /policy command | ||
| // registered below use the same instance, so hourly/daily/session windows | ||
| // cover every surface and a /policy write reaches the live signer. | ||
| spendControl: getSharedSpendControl(), | ||
| onReady: (port) => { | ||
| api.logger.info(`BlockRun ${apiKey ? "API-key" : "x402"} proxy listening on port ${port}`); | ||
| }, | ||
|
|
@@ -2042,7 +2041,7 @@ const plugin: OpenClawPluginDefinition = { | |
| // blockrun_polymarket is a LOCAL trading tool (signs CLOB orders with the | ||
| // ClawRouter wallet key), not an HTTP-proxy partner tool — register it | ||
| // separately so real-money betting works out of the box. | ||
| api.registerTool(buildPolymarketTool()); | ||
| api.registerTool(buildPolymarketTool({ spendControl: getSharedSpendControl() })); | ||
| if (partnerTools.length > 0 && shouldLogRegistration) { | ||
| api.logger.info( | ||
| `Registered ${partnerTools.length} partner tool(s): ${partnerTools.map((t) => t.name).join(", ")}, blockrun_polymarket`, | ||
|
|
@@ -2307,7 +2306,10 @@ const plugin: OpenClawPluginDefinition = { | |
| api.registerCommand(createExcludeCommand()); | ||
| api.registerCommand( | ||
| createPolicyCommand({ | ||
| liveControl: () => (activeProxyHandle ? (liveSpendControl ?? undefined) : undefined), | ||
| liveControl: () => | ||
| (process as ProcessWithClawRouterState).__clawrouterProxyStarted | ||
| ? getSharedSpendControl() | ||
| : undefined, | ||
|
Comment on lines
+2309
to
+2312
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- target hunk ---'
sed -n '2180,2290p' src/index.ts
printf '%s\n' '--- startup symbols ---'
rg -n -C 10 '__clawrouterProxyStarted|beginProxyStartupAttempt|activeProxyHandle|startProxy|createPolicyCommand|liveControl' src/index.ts
printf '%s\n' '--- relevant tests ---'
rg -n -C 8 'occupied|port|startup|policy|__clawrouterProxyStarted|activeProxyHandle' --glob '*.{test,spec}.{ts,tsx,js}' .Repository: BlockRunAI/ClawRouter Length of output: 50378 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- liveControl and startup flow ---'
rg -n -C 18 '__clawrouterProxyStarted|beginProxyStartupAttempt|activeProxyHandle|liveControl|startProxy' src/index.ts
printf '%s\n' '--- policy command contract ---'
rg -n -C 18 'createPolicyCommand|liveControl|openControl' src/commands/policy.ts
printf '%s\n' '--- focused policy/startup test files ---'
find src -maxdepth 2 -type f \( -name '*policy*.test.*' -o -name '*startup*.test.*' -o -name '*index*.test.*' \) -printRepository: BlockRunAI/ClawRouter Length of output: 37958 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- lifecycle tests ---'
sed -n '1,280p' src/index.lifecycle.test.ts
printf '%s\n' '--- shared control definition and uses ---'
rg -n -C 12 'getSharedSpendControl|class SpendControl|__clawrouterStartupPhase' src/spend-control.ts src/index.ts
printf '%s\n' '--- startup failure handling ---'
sed -n '1035,1095p' src/index.tsRepository: BlockRunAI/ClawRouter Length of output: 30358 Gate
Use 🤖 Prompt for AI Agents |
||
| }), | ||
| ); | ||
| if (shouldLogRegistration) { | ||
|
|
@@ -2615,6 +2617,7 @@ export { | |
| registerSpendPolicyHook, | ||
| SpendPolicyError, | ||
| MalformedSpendPolicyError, | ||
| UnreadableSpendPolicyError, | ||
| CAIP2_BASE, | ||
| CAIP2_SOLANA_MAINNET, | ||
| PAYABLE_NETWORKS, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.