registry  /  @blockrun/franklin  /  3.30.0

@blockrun/franklin@3.30.0

Franklin Agent — The AI agent with a wallet. Spends USDC autonomously to get real work done. Pay per action, no subscriptions.

AI Security Review

scanned 2d ago · by lpm-firewall-ai

Review flagged AI-agent configuration or capability changes. This remains warn-only unless evidence shows foreign-agent hijack through preinstall/install/postinstall, hidden persistence, exfiltration, remote code execution, or other concrete malicious behavior.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
Explicit `franklin init` or runtime agent invocation of Surf tools.
Impact
Changes an AI-agent client control surface and can spend funds from the configured wallet during enabled tool use.
Mechanism
explicit agent-proxy persistence and wallet-backed paid API requests
Rationale
No concrete malicious chain was established by source inspection, but explicit AI-agent configuration mutation, login persistence, dynamic user-plugin loading, and automatic wallet payment signing create real high-impact capability risk.
Evidence
package.jsondist/index.jsdist/commands/init.jsdist/tools/surf.jsdist/plugins/registry.js

Decision evidence

public snapshot
AI called this Suspicious at 88.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • `dist/commands/init.js` explicitly writes `~/.claude/settings.json`.
  • `init` installs a macOS `LaunchAgent` that starts its proxy on login.
  • `dist/tools/surf.js` signs x402 payment payloads with the configured wallet key.
  • `dist/plugins/registry.js` dynamically imports user plugins from `~/.blockrun/plugins`.
Evidence against
  • `package.json` has no preinstall, install, postinstall, or prepare hook.
  • The Claude and LaunchAgent changes require explicit `franklin init` execution.
  • Wallet signing is part of documented paid-request handling, not credential exfiltration.
  • No source evidence found of private-key transmission, hidden payload download, or destructive install-time behavior.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 236 file(s), 2.39 MB of source, external domains: 127.0.0.1, 1rpc.io, api.blockrun.ai, api.coingecko.com, api.telegram.org, base.meowrpc.com, base.publicnode.com, basescan.org, blockrun.ai, bridge.polymarket.com, data-api.polymarket.com, docs.polymarket.com, example.com, fonts.googleapis.com, fonts.gstatic.com, franklin.run, github.com, html.duckduckgo.com, lite-api.jup.ag, mainnet.base.org, nodejs.org, pay.coinbase.com, pm-egress-vbsbhh7lea-an.a.run.app, polygon-rpc.com, polygon.llamarpc.com, polygonscan.com, polymarket.com, registry.npmjs.org, relayer-v2.polymarket.com, sol.blockrun.ai, solscan.io, www.apple.com, www.w3.org, www.youtube.com, x.com

Source & flagged code

3 flagged · loading source
dist/plugins/registry.jsView file
96// Dynamic import — works for both ESM and CJS L97: const mod = await import(entryPath); L98: const plugin = mod.default ?? mod.plugin ?? mod;
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/plugins/registry.jsView on unpkg · L96
dist/agent/context.jsView file
6import path from 'node:path'; L7: import { execSync } from 'node:child_process'; L8: import { BLOCKRUN_DIR } from '../config.js'; ... L95: L96: **No internal-language leakage.** Always write your visible response in the same language the user is using. If your private reasoning happens in a different language than the user... L97: ... L146: 2. If SearchX returns empty, tell the user "No posts found" and suggest a different keyword. Do NOT fall back to WebSearch/WebFetch — they will return non-X content that you must N... L147: 3. NEVER fabricate X post URLs. Every link you show MUST come from SearchX results. If a URL doesn't start with "https://x.com/", do NOT present it as an X post. L148: 4. Present results as a numbered list. Each item: author, snippet, URL from SearchX, and a 1-2 sentence suggested reply. ... L197: - Chain selection: ~/.blockrun/payment-chain ("base" or "solana"). Legacy file ~/.blockrun/.chain may also exist on installs that haven't migrated; canonical is payment-chain. L198: - Spending data: L199: - ~/.blockrun/franklin-stats.json — rolling totals + per-model breakdown (what \`franklin stats\` reads).
Critical
Wallet Drain

Source uses private key material to transfer cryptocurrency funds.

dist/agent/context.jsView on unpkg · L6
6Trigger-reachable chain: manifest.exports -> dist/index.js -> dist/commands/telegram.js -> dist/agent/context.js L6: import path from 'node:path'; L7: import { execSync } from 'node:child_process'; L8: import { BLOCKRUN_DIR } from '../config.js'; ... L95: L96: **No internal-language leakage.** Always write your visible response in the same language the user is using. If your private reasoning happens in a different language than the user... L97: ... L146: 2. If SearchX returns empty, tell the user "No posts found" and suggest a different keyword. Do NOT fall back to WebSearch/WebFetch — they will return non-X content that you must N... L147: 3. NEVER fabricate X post URLs. Every link you show MUST come from SearchX results. If a URL doesn't start with "https://x.com/", do NOT present it as an X post. L148: 4. Present results as a numbered list. Each item: author, snippet, URL from SearchX, and a 1-2 sentence suggested reply. ... L197: - Chain selection: ~/.blockrun/payment-chain ("base" or "solana"). Legacy file ~/.blockrun/.chain may also exist on installs that haven't migrated; canonical is payment-chain. L198: - Spending data: L199: - ~/.blockrun/franklin-stats.json — rolling…
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

dist/agent/context.jsView on unpkg · L6

Findings

2 Critical4 Medium4 Low
CriticalWallet Draindist/agent/context.js
CriticalTrigger Reachable Dangerous Capabilitydist/agent/context.js
MediumDynamic Requiredist/plugins/registry.js
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings