AI Security Review
scanned 8d ago · by lpm-firewall-aiNo confirmed malicious attack surface. The package provides a Solana wallet API with explicit user-invoked transfer and swap methods aligned with its stated purpose.
Static reason
High-risk behavior combination matched malicious policy.
Trigger
Runtime calls to exported wallet methods such as sendCirc, sendSol, swap, or walletTradeExecutor.execute.
Impact
Funds can move only through explicit API calls using the configured wallet keypair; no hidden install-time or import-time drain was found.
Mechanism
User-invoked self-custody Solana transaction signing and broadcast
Rationale
The scanner's wallet-drain label matches package-aligned wallet functionality, not hidden attack behavior: transfers and swaps are exported APIs requiring explicit invocation and a local/user-provided keypair. There are no lifecycle hooks, import-time sends, exfiltration, shell execution, persistence, or broad AI-agent control-surface writes.
Evidence
package.jsondist/index.jsdist/index.d.tsREADME.md
Network endpoints4
lite-api.jup.ag/swap/v1api.jup.ag/swap/v1api.mainnet-beta.solana.comrpc.ankr.com/solana
Decision evidence
public snapshotAI called this Clean at 95.0% confidence as Benign with low false-positive risk.
Evidence for block
- dist/index.js exports wallet methods that can sign/send SOL, CIRC transfers, and Jupiter swaps when called with a keypair.
- dist/index.js reads CIRCUIT_WALLET and JUPITER_API_KEY from process.env.
- dist/index.js uses Solana RPC and Jupiter swap endpoints.
Evidence against
- package.json has no preinstall/install/postinstall lifecycle hooks; only test/typecheck/build/prepack scripts.
- No import-time transfer or swap execution; makeWallet only loads a keypair and constructs a Wallet.
- Transfers require explicit sendCirc/sendSol/swap/walletTradeExecutor.execute calls and caller-provided recipients or trade intents.
- No child_process, eval, dynamic require/import, filesystem harvesting, persistence, or AI-agent config mutation found.
- README.md and dist/index.d.ts document the same self-custody wallet/payment functionality.
Behavioral surface
EnvironmentVarsNetwork
UrlStrings
Source & flagged code
2 flagged · loading sourcedist/index.jsView file
4function keypairFromSecret(input) {
L5: if (input instanceof Uint8Array) return Keypair.fromSecretKey(input);
L6: if (Array.isArray(input)) return Keypair.fromSecretKey(Uint8Array.from(input));
L7: const s = String(input).trim();
L8: if (s.startsWith("[")) return Keypair.fromSecretKey(Uint8Array.from(JSON.parse(s)));
L9: return Keypair.fromSecretKey(bs58.decode(s));
L10: }
L11: function loadKeypairFromEnv(env = process.env) {
L12: const v = env.CIRCUIT_WALLET;
...
L86: if (!usesDefaultPublicRpc(opts)) return;
L87: if (process.env.CIRCUIT_SUPPRESS_RPC_WARNING === "1") return;
L88: warned = true;
Critical
Wallet Drain
Source uses private key material to transfer cryptocurrency funds.
dist/index.jsView on unpkg · L44Trigger-reachable chain: manifest.main -> dist/index.js
L4: function keypairFromSecret(input) {
L5: if (input instanceof Uint8Array) return Keypair.fromSecretKey(input);
L6: if (Array.isArray(input)) return Keypair.fromSecretKey(Uint8Array.from(input));
L7: const s = String(input).trim();
L8: if (s.startsWith("[")) return Keypair.fromSecretKey(Uint8Array.from(JSON.parse(s)));
L9: return Keypair.fromSecretKey(bs58.decode(s));
L10: }
L11: function loadKeypairFromEnv(env = process.env) {
L12: const v = env.CIRCUIT_WALLET;
...
L86: if (!usesDefaultPublicRpc(opts)) return;
L87: if (process.env.CIRCUIT_SUPPRESS_RPC_WARNING === "1") return;
L88: warned = true;
Critical
Trigger Reachable Dangerous Capability
A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.
dist/index.jsView on unpkg · L4Findings
2 Critical2 Medium2 Low
CriticalWallet Draindist/index.js
CriticalTrigger Reachable Dangerous Capabilitydist/index.js
MediumNetwork
MediumEnvironment Vars
LowScripts Present
LowUrl Strings