brainblast 0.6.4 → 0.7.0

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.
@@ -0,0 +1,100 @@
1
+ import {
2
+ base58Encode,
3
+ isValidSolanaAddress
4
+ } from "./chunk-VG5FMOLW.js";
5
+
6
+ // src/trustGraph/rpc.ts
7
+ var BPF_UPGRADEABLE_LOADER = "BPFLoaderUpgradeab1e11111111111111111111111";
8
+ var BPF_LOADER_2 = "BPFLoader2111111111111111111111111111111111";
9
+ var NATIVE_LOADER = "NativeLoader1111111111111111111111111111111";
10
+ var DEFAULT_RPC = "https://api.mainnet-beta.solana.com";
11
+ async function rpc(method, params, opts) {
12
+ const url = opts.rpcUrl ?? DEFAULT_RPC;
13
+ const fetchImpl = opts.fetchImpl ?? fetch;
14
+ const ac = new AbortController();
15
+ const t = setTimeout(() => ac.abort(), opts.timeoutMs ?? 1e4);
16
+ try {
17
+ const res = await fetchImpl(url, {
18
+ method: "POST",
19
+ headers: { "content-type": "application/json" },
20
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
21
+ signal: ac.signal
22
+ });
23
+ if (!res.ok) throw new Error(`rpc ${method}: HTTP ${res.status}`);
24
+ const body = await res.json();
25
+ if (body.error) throw new Error(`rpc ${method}: ${body.error.message}`);
26
+ if (body.result === void 0) throw new Error(`rpc ${method}: empty result`);
27
+ return body.result;
28
+ } finally {
29
+ clearTimeout(t);
30
+ }
31
+ }
32
+ async function getAccountInfo(address, opts = {}) {
33
+ if (!isValidSolanaAddress(address)) throw new Error(`invalid Solana address: ${address}`);
34
+ const result = await rpc(
35
+ "getAccountInfo",
36
+ [address, { encoding: "base64", commitment: "confirmed" }],
37
+ opts
38
+ );
39
+ if (!result || !result.value) return null;
40
+ const v = result.value;
41
+ const [b64] = v.data;
42
+ return {
43
+ owner: v.owner,
44
+ data: Buffer.from(b64, "base64"),
45
+ executable: v.executable,
46
+ lamports: v.lamports
47
+ };
48
+ }
49
+ async function probeUpgradeAuthority(programId, opts = {}) {
50
+ const acct = await getAccountInfo(programId, opts);
51
+ if (!acct) {
52
+ return {
53
+ kind: "unknown",
54
+ address: null,
55
+ source: "rpc",
56
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString()
57
+ };
58
+ }
59
+ if (acct.owner === BPF_LOADER_2 || acct.owner === NATIVE_LOADER) {
60
+ return {
61
+ kind: "renounced",
62
+ address: null,
63
+ source: "rpc",
64
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString()
65
+ };
66
+ }
67
+ if (acct.owner !== BPF_UPGRADEABLE_LOADER) {
68
+ throw new Error(
69
+ `program ${programId} is owned by ${acct.owner}, not a known loader; not a deployed program?`
70
+ );
71
+ }
72
+ if (acct.data.length < 36) throw new Error(`program account too small: ${acct.data.length}`);
73
+ const tag = acct.data[0] | acct.data[1] << 8 | acct.data[2] << 16 | acct.data[3] << 24;
74
+ if (tag !== 2) throw new Error(`expected Program (tag=2) state, got tag=${tag}`);
75
+ const programDataAddr = base58Encode(acct.data.subarray(4, 36));
76
+ const pd = await getAccountInfo(programDataAddr, opts);
77
+ if (!pd) {
78
+ throw new Error(`program ${programId} ProgramData ${programDataAddr} not found`);
79
+ }
80
+ if (pd.data.length < 45) throw new Error(`ProgramData account too small: ${pd.data.length}`);
81
+ const pdTag = pd.data[0] | pd.data[1] << 8 | pd.data[2] << 16 | pd.data[3] << 24;
82
+ if (pdTag !== 3) throw new Error(`expected ProgramData (tag=3), got tag=${pdTag}`);
83
+ const optionTag = pd.data[12];
84
+ const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
85
+ if (optionTag === 0) {
86
+ return { kind: "renounced", address: null, source: "rpc", checkedAt };
87
+ }
88
+ if (optionTag !== 1) throw new Error(`unexpected Option tag in ProgramData: ${optionTag}`);
89
+ const authority = base58Encode(pd.data.subarray(13, 45));
90
+ return { kind: "unknown", address: authority, source: "rpc", checkedAt };
91
+ }
92
+
93
+ export {
94
+ BPF_UPGRADEABLE_LOADER,
95
+ BPF_LOADER_2,
96
+ NATIVE_LOADER,
97
+ DEFAULT_RPC,
98
+ getAccountInfo,
99
+ probeUpgradeAuthority
100
+ };
package/dist/cli.js CHANGED
@@ -2,28 +2,36 @@
2
2
  import {
3
3
  analyzeCosts,
4
4
  applyDiffToFile,
5
- buildTrustGraph,
6
- cacheSize,
7
- defaultCachePath,
8
5
  initPack,
9
6
  isTelemetryEnabled,
10
- isValidSolanaAddress,
11
- loadProgramCache,
12
7
  parseDiff,
13
8
  recordGraduationEvents,
14
9
  renderCostReportMd,
15
- renderTrustGraphMd,
16
10
  startWatch,
17
11
  submitTelemetry,
18
12
  telemetryFilePath,
19
13
  validatePack
20
- } from "./chunk-HXQNNGSC.js";
14
+ } from "./chunk-34VXOLJF.js";
15
+ import {
16
+ renderTrustGraphMd
17
+ } from "./chunk-2UZGWXIX.js";
18
+ import {
19
+ buildTrustGraph,
20
+ cacheSize,
21
+ defaultCachePath,
22
+ loadProgramCache
23
+ } from "./chunk-SVSVVW6U.js";
21
24
  import {
22
25
  audit,
23
26
  getChangedRanges,
24
27
  resolveRules
25
- } from "./chunk-2Y6UILTZ.js";
28
+ } from "./chunk-CRYFCQYM.js";
26
29
  import "./chunk-2XJORJPQ.js";
30
+ import "./chunk-O5Z4ZJHC.js";
31
+ import "./chunk-XSVQSK53.js";
32
+ import {
33
+ isValidSolanaAddress
34
+ } from "./chunk-VG5FMOLW.js";
27
35
  import "./chunk-3RG5ZIWI.js";
28
36
 
29
37
  // src/cli.ts
@@ -120,7 +128,7 @@ if (args[0] === "drift") {
120
128
  process.exit(0);
121
129
  }
122
130
  if (args[0] === "mcp") {
123
- const { startMcpServer } = await import("./mcp-FCKMS2MQ.js");
131
+ const { startMcpServer } = await import("./mcp-ML2X44WE.js");
124
132
  await startMcpServer();
125
133
  process.exit(0);
126
134
  }
@@ -144,10 +152,57 @@ if (args[0] === "watch") {
144
152
  await new Promise(() => {
145
153
  });
146
154
  }
155
+ if (args[0] === "watch-chain") {
156
+ const rest = args.slice(1);
157
+ const programId = rest.find((a) => !a.startsWith("--"));
158
+ if (!programId) {
159
+ console.error("usage: brainblast watch-chain <program-id> [--rpc URL] [--interval <seconds>] [--limit N]");
160
+ console.error(" Poll a deployed program for new activity and upgrade-authority changes. Emits NDJSON.");
161
+ process.exit(2);
162
+ }
163
+ const { startChainWatch } = await import("./watchChain-F6INXAPA.js");
164
+ const rpcIdx = rest.indexOf("--rpc");
165
+ const rpcUrl = rpcIdx >= 0 ? rest[rpcIdx + 1] : void 0;
166
+ const intIdx = rest.indexOf("--interval");
167
+ const intervalMs = intIdx >= 0 ? parseInt(rest[intIdx + 1], 10) * 1e3 : void 0;
168
+ const limIdx = rest.indexOf("--limit");
169
+ const limit = limIdx >= 0 ? parseInt(rest[limIdx + 1], 10) : void 0;
170
+ const handle = startChainWatch(programId, { rpcUrl, intervalMs, limit });
171
+ process.on("SIGINT", () => {
172
+ handle.stop();
173
+ process.exit(0);
174
+ });
175
+ process.on("SIGTERM", () => {
176
+ handle.stop();
177
+ process.exit(0);
178
+ });
179
+ await new Promise(() => {
180
+ });
181
+ }
147
182
  if (args[0] === "rico") {
148
183
  await runRico(args.slice(1));
149
184
  process.exit(0);
150
185
  }
186
+ if (args[0] === "firewall") {
187
+ await runFirewall(args.slice(1));
188
+ process.exit(0);
189
+ }
190
+ if (args[0] === "idl-rules") {
191
+ await runIdlRules(args.slice(1));
192
+ process.exit(0);
193
+ }
194
+ if (args[0] === "score") {
195
+ await runScore(args.slice(1));
196
+ process.exit(0);
197
+ }
198
+ if (args[0] === "pump-check") {
199
+ await runPumpCheck(args.slice(1));
200
+ process.exit(0);
201
+ }
202
+ if (args[0] === "batch") {
203
+ await runBatch(args.slice(1));
204
+ process.exit(0);
205
+ }
151
206
  if (args[0] === "fix") {
152
207
  await runFix(args.slice(1));
153
208
  process.exit(0);
@@ -620,3 +675,177 @@ ${renderRicoText(ricoResult.result)}`);
620
675
  process.exit(1);
621
676
  }
622
677
  }
678
+ async function runFirewall(argv) {
679
+ const { inspectTransaction, renderFirewallText } = await import("./firewall-HN5XJLGC.js");
680
+ const tx = argv.find((a) => !a.startsWith("--"));
681
+ if (!tx) {
682
+ console.error("usage: brainblast firewall <base64-tx> [--rpc URL] [--no-simulate] [--message-only] [--strict] [--json]");
683
+ console.error(" Inspect a serialized Solana transaction before an agent signs it.");
684
+ console.error(" Exit 1 on BLOCK verdict (or any WARN with --strict).");
685
+ process.exit(2);
686
+ }
687
+ const rpcIdx = argv.indexOf("--rpc");
688
+ const rpcUrl = rpcIdx >= 0 ? argv[rpcIdx + 1] : void 0;
689
+ const noSimulate = argv.includes("--no-simulate");
690
+ const messageOnly = argv.includes("--message-only");
691
+ const strict2 = argv.includes("--strict");
692
+ const jsonOut = argv.includes("--json");
693
+ let report2;
694
+ try {
695
+ report2 = await inspectTransaction(tx, { rpcUrl, simulate: !noSimulate, messageOnly });
696
+ } catch (e) {
697
+ console.error(`brainblast firewall: ${e?.message ?? String(e)}`);
698
+ process.exit(2);
699
+ }
700
+ if (jsonOut) {
701
+ console.log(JSON.stringify(report2, null, 2));
702
+ } else {
703
+ console.log(renderFirewallText(report2));
704
+ }
705
+ if (report2.verdict === "block" || strict2 && report2.verdict === "warn") {
706
+ process.exit(1);
707
+ }
708
+ }
709
+ async function runIdlRules(argv) {
710
+ const { readFileSync: readFileSync2, writeFileSync: writeFileSync3, mkdirSync: mkdirSync3 } = await import("fs");
711
+ const { join: join3 } = await import("path");
712
+ const { parseIdl, generateRulesFromIdl, renderRulesYaml } = await import("./idlRules-3KZML4NL.js");
713
+ const idlPath = argv.find((a) => !a.startsWith("--"));
714
+ if (!idlPath) {
715
+ console.error("usage: brainblast idl-rules <idl.json> [--out <dir>] [--json]");
716
+ console.error(" Generate brainblast rules from an Anchor IDL's account constraints.");
717
+ process.exit(2);
718
+ }
719
+ const outIdx = argv.indexOf("--out");
720
+ const outDir2 = outIdx >= 0 ? argv[outIdx + 1] : void 0;
721
+ const jsonOut = argv.includes("--json");
722
+ let idl;
723
+ try {
724
+ idl = parseIdl(JSON.parse(readFileSync2(idlPath, "utf8")));
725
+ } catch (e) {
726
+ console.error(`brainblast idl-rules: ${e?.message ?? String(e)}`);
727
+ process.exit(2);
728
+ }
729
+ const rules2 = generateRulesFromIdl(idl);
730
+ if (rules2.length === 0) {
731
+ console.error("brainblast idl-rules: IDL produced no rules (no instructions?)");
732
+ process.exit(1);
733
+ }
734
+ if (jsonOut) {
735
+ console.log(JSON.stringify(rules2, null, 2));
736
+ return;
737
+ }
738
+ const yaml = renderRulesYaml(rules2);
739
+ if (outDir2) {
740
+ mkdirSync3(outDir2, { recursive: true });
741
+ const file = join3(outDir2, `${rules2[0].id}.yaml`);
742
+ writeFileSync3(file, yaml);
743
+ console.log(`Generated ${rules2.length} rule(s) \u2192 ${file}`);
744
+ console.log(` Run against your program: npx brainblast <program-dir> --packs <pack-with-this-rule>`);
745
+ } else {
746
+ console.log(yaml);
747
+ }
748
+ }
749
+ async function runScore(argv) {
750
+ const { scoreProgram, renderScoreText, gradeAtLeast } = await import("./score-VLKER37D.js");
751
+ const { isValidSolanaAddress: isValidSolanaAddress2 } = await import("./trustGraph-4SSJOQKT.js");
752
+ const programId = argv.find((a) => !a.startsWith("--"));
753
+ if (!programId) {
754
+ console.error("usage: brainblast score <program-id> [--rpc URL] [--no-probe] [--min A|B|C|D|F] [--json]");
755
+ console.error(" Compute a 0-100 trust score + A-F grade for a deployed Solana program.");
756
+ process.exit(2);
757
+ }
758
+ if (!isValidSolanaAddress2(programId)) {
759
+ console.error(`brainblast score: not a valid Solana address: ${programId}`);
760
+ process.exit(2);
761
+ }
762
+ const rpcIdx = argv.indexOf("--rpc");
763
+ const rpcUrl = rpcIdx >= 0 ? argv[rpcIdx + 1] : void 0;
764
+ const noProbe = argv.includes("--no-probe");
765
+ const minIdx = argv.indexOf("--min");
766
+ const min = minIdx >= 0 ? argv[minIdx + 1] : void 0;
767
+ const jsonOut = argv.includes("--json");
768
+ let result;
769
+ try {
770
+ result = await scoreProgram(programId, { rpcUrl, probeRpc: !noProbe });
771
+ } catch (e) {
772
+ console.error(`brainblast score: ${e?.message ?? String(e)}`);
773
+ process.exit(1);
774
+ }
775
+ if (jsonOut) {
776
+ console.log(JSON.stringify(result, null, 2));
777
+ } else {
778
+ console.log(renderScoreText(result));
779
+ }
780
+ if (min && !gradeAtLeast(result.grade, min)) {
781
+ process.exit(1);
782
+ }
783
+ }
784
+ async function runPumpCheck(argv) {
785
+ const { pumpPreflight, renderPreflightText } = await import("./pumpCheck-K2ESOBNU.js");
786
+ const mint = argv.find((a) => !a.startsWith("--"));
787
+ if (!mint) {
788
+ console.error("usage: brainblast pump-check <mint> [--rpc URL] [--api-key KEY] [--fail-on SCORE] [--offline] [--json]");
789
+ console.error(" Launch pre-flight: mint/freeze authority, identity, and Rico Maps forensics \u2192 GO/CAUTION/NO-GO.");
790
+ process.exit(2);
791
+ }
792
+ const rpcIdx = argv.indexOf("--rpc");
793
+ const rpcUrl = rpcIdx >= 0 ? argv[rpcIdx + 1] : void 0;
794
+ const keyIdx = argv.indexOf("--api-key");
795
+ const apiKey = keyIdx >= 0 ? argv[keyIdx + 1] : void 0;
796
+ const failIdx = argv.indexOf("--fail-on");
797
+ const failOnRisk = failIdx >= 0 ? parseInt(argv[failIdx + 1], 10) : void 0;
798
+ const offline = argv.includes("--offline");
799
+ const jsonOut = argv.includes("--json");
800
+ let report2;
801
+ try {
802
+ report2 = await pumpPreflight(mint, { rpcUrl, apiKey, failOnRisk, offline });
803
+ } catch (e) {
804
+ console.error(`brainblast pump-check: ${e?.message ?? String(e)}`);
805
+ process.exit(2);
806
+ }
807
+ if (jsonOut) {
808
+ console.log(JSON.stringify(report2, null, 2));
809
+ } else {
810
+ console.log(renderPreflightText(report2));
811
+ }
812
+ if (report2.verdict === "NO-GO") process.exit(1);
813
+ }
814
+ async function runBatch(argv) {
815
+ const { readFileSync: readFileSync2 } = await import("fs");
816
+ const { batchScan, parseMintList, renderBatchText } = await import("./batchScan-JR2G5JCF.js");
817
+ const file = argv.find((a) => !a.startsWith("--"));
818
+ if (!file) {
819
+ console.error("usage: brainblast batch <file> [--concurrency N] [--api-key KEY] [--fail-on SCORE] [--offline] [--json]");
820
+ console.error(" Risk-rank a list of contract addresses (newline-separated or JSON array).");
821
+ process.exit(2);
822
+ }
823
+ let mints;
824
+ try {
825
+ mints = parseMintList(readFileSync2(file, "utf8"));
826
+ } catch (e) {
827
+ console.error(`brainblast batch: ${e?.message ?? String(e)}`);
828
+ process.exit(2);
829
+ }
830
+ if (mints.length === 0) {
831
+ console.error("brainblast batch: no addresses found in file");
832
+ process.exit(2);
833
+ }
834
+ const concIdx = argv.indexOf("--concurrency");
835
+ const concurrency = concIdx >= 0 ? parseInt(argv[concIdx + 1], 10) : void 0;
836
+ const keyIdx = argv.indexOf("--api-key");
837
+ const apiKey = keyIdx >= 0 ? argv[keyIdx + 1] : void 0;
838
+ const failIdx = argv.indexOf("--fail-on");
839
+ const failOnRisk = failIdx >= 0 ? parseInt(argv[failIdx + 1], 10) : void 0;
840
+ const offline = argv.includes("--offline");
841
+ const jsonOut = argv.includes("--json");
842
+ const result = await batchScan(mints, { concurrency, apiKey, failOnRisk, offline });
843
+ if (jsonOut) {
844
+ console.log(JSON.stringify(result, null, 2));
845
+ } else {
846
+ console.log(renderBatchText(result));
847
+ }
848
+ if (result.summary.impersonators > 0 || result.summary.highRisk > 0) {
849
+ process.exit(1);
850
+ }
851
+ }
@@ -0,0 +1,18 @@
1
+ import {
2
+ KNOWN_PROGRAMS,
3
+ analyzeInstructions,
4
+ decodeTransaction,
5
+ inspectTransaction,
6
+ parseCpiPrograms,
7
+ renderFirewallText
8
+ } from "./chunk-HL7NVANZ.js";
9
+ import "./chunk-VG5FMOLW.js";
10
+ import "./chunk-3RG5ZIWI.js";
11
+ export {
12
+ KNOWN_PROGRAMS,
13
+ analyzeInstructions,
14
+ decodeTransaction,
15
+ inspectTransaction,
16
+ parseCpiPrograms,
17
+ renderFirewallText
18
+ };
@@ -0,0 +1,17 @@
1
+ import {
2
+ buildConstraintParams,
3
+ generateRulesFromIdl,
4
+ idlProgramName,
5
+ parseIdl,
6
+ renderRulesYaml,
7
+ toSnakeCase
8
+ } from "./chunk-O5Z4ZJHC.js";
9
+ import "./chunk-3RG5ZIWI.js";
10
+ export {
11
+ buildConstraintParams,
12
+ generateRulesFromIdl,
13
+ idlProgramName,
14
+ parseIdl,
15
+ renderRulesYaml,
16
+ toSnakeCase
17
+ };
package/dist/index.d.ts CHANGED
@@ -624,4 +624,241 @@ declare function analyzeToken(mint: string, opts?: {
624
624
  baseUrl?: string;
625
625
  }): Promise<RicoOutcome>;
626
626
 
627
- export { type AccountFlow, type AuditRef, type BuildOpts, CANONICAL_BY_MINT, CANONICAL_MINTS, type Candidate, type CanonicalMint, type ChangedRanges, type CheckOutcome, type CheckResult, type CheckResultKind, type Checker, type ConfigCandidate, type ConfigChecker, type CostReport, DEFAULT_REGISTRY_URL, DEFAULT_TTL_HOURS, type DiffResult, type DriftAdvisory, type DriftBaseline, type DriftPackage, type DriftResult, type GraduationEvent, type IdentityStatus, type OnChainProgram, type OsvAdvisory, PACK_MANIFEST_FILE, type PackInitOptions, type PackManifest, type PackRuleValidation, type PackValidateResult, type ParityNote, type ParsedDiff, type PriorityFeePosture, type ProgramCache, type ProgramCacheEntry, type Recoverability, type RicoOutcome, type RicoResult, type RicoTokenSecurity, type Rule, type RustAccountField, type RustCandidate, type RustChecker, type Severity, type TelemetrySubmitResult, type TokenIdentity, type TrustGraph, type UpgradeAuthority, type UpgradeAuthorityKind, type UpgradeAuthoritySource, type VerifiedBuildState, type VerifyOpts, type WatchEvent, type WatchOptions, analyzeCosts, analyzeToken, applyDiffToFile, audit, auditWithRule, base58Decode, base58Encode, buildTrustGraph, rules as bundledRules, cacheSize, canonicalMintForSymbol, checkDrift, checkerKinds, defaultCachePath, deployerFlagsFrom, diffVersions, fileChanged, findCandidates, findConfigCandidates, generateTestForResult, getCacheEntry, getCacheEntryMeta, getChangedRanges, getRepoHash, getUserHash, getWorkingTreeChanges, initPack, isCanonicalMint, isEntryExpired, isTelemetryEnabled, isValidSolanaAddress, lamportsToSol, loadDirectory, loadPack, loadPacksFromDir, loadProgramCache, loadRules, parseDiff, putCacheEntry, queryOsv, rangeChanged, recordGraduationEvents, renderCostReportMd, renderDiffMd, renderDiffText, renderDriftText, renderRicoText, renderTest, renderTrustGraphMd, rentExemptMinimum, resolveRules, riskScore, runChecker, runIncrementalScan, saveProgramCache, seedPackages, startWatch, submitTelemetry, telemetryFilePath, testKinds, validatePack, validatePackManifest, verifyTokenIdentity };
627
+ declare const KNOWN_PROGRAMS: Record<string, string>;
628
+ type FirewallSeverity = "info" | "warn" | "critical";
629
+ type FirewallVerdict = "allow" | "warn" | "block";
630
+ interface FirewallFinding {
631
+ severity: FirewallSeverity;
632
+ kind: string;
633
+ detail: string;
634
+ }
635
+ interface FirewallProgram {
636
+ id: string;
637
+ label: string | null;
638
+ known: boolean;
639
+ topLevel: boolean;
640
+ }
641
+ interface DecodedInstruction {
642
+ programIdIndex: number;
643
+ programId: string;
644
+ accountIndexes: number[];
645
+ data: Uint8Array;
646
+ }
647
+ interface DecodedTx {
648
+ version: "legacy" | number;
649
+ numRequiredSignatures: number;
650
+ numReadonlySigned: number;
651
+ numReadonlyUnsigned: number;
652
+ staticAccountKeys: string[];
653
+ recentBlockhash: string;
654
+ instructions: DecodedInstruction[];
655
+ addressTableLookups: {
656
+ accountKey: string;
657
+ writableCount: number;
658
+ readonlyCount: number;
659
+ }[];
660
+ }
661
+ interface FirewallReport {
662
+ version: "legacy" | number;
663
+ feePayer: string;
664
+ numSigners: number;
665
+ staticAccounts: number;
666
+ programs: FirewallProgram[];
667
+ usesAddressLookupTables: boolean;
668
+ simulation: {
669
+ ran: boolean;
670
+ ok?: boolean;
671
+ err?: unknown;
672
+ unitsConsumed?: number;
673
+ logsCount?: number;
674
+ cpiPrograms?: string[];
675
+ };
676
+ findings: FirewallFinding[];
677
+ verdict: FirewallVerdict;
678
+ }
679
+ declare function decodeTransaction(base64: string, opts?: {
680
+ messageOnly?: boolean;
681
+ }): DecodedTx;
682
+ declare function analyzeInstructions(decoded: DecodedTx, known: Record<string, string>): FirewallFinding[];
683
+ declare function parseCpiPrograms(logs: string[]): string[];
684
+ interface FirewallOpts extends RpcOpts {
685
+ simulate?: boolean;
686
+ messageOnly?: boolean;
687
+ knownPrograms?: Record<string, string>;
688
+ }
689
+ declare function inspectTransaction(base64: string, opts?: FirewallOpts): Promise<FirewallReport>;
690
+ declare function renderFirewallText(r: FirewallReport): string;
691
+
692
+ interface IdlAccount {
693
+ name: string;
694
+ isMut?: boolean;
695
+ isSigner?: boolean;
696
+ accounts?: IdlAccount[];
697
+ }
698
+ interface IdlInstruction {
699
+ name: string;
700
+ accounts: IdlAccount[];
701
+ }
702
+ interface AnchorIdl {
703
+ name?: string;
704
+ metadata?: {
705
+ name?: string;
706
+ version?: string;
707
+ };
708
+ version?: string;
709
+ instructions: IdlInstruction[];
710
+ }
711
+ declare function toSnakeCase(s: string): string;
712
+ declare function idlProgramName(idl: AnchorIdl): string;
713
+ declare function parseIdl(json: unknown): AnchorIdl;
714
+ interface IdlConstraintParams {
715
+ idlName: string;
716
+ instructions: {
717
+ name: string;
718
+ signers: string[];
719
+ mutable: string[];
720
+ }[];
721
+ }
722
+ declare function buildConstraintParams(idl: AnchorIdl): IdlConstraintParams;
723
+ declare function generateRulesFromIdl(idl: AnchorIdl): Rule[];
724
+ declare function renderRulesYaml(rules: Rule[]): string;
725
+
726
+ type Grade = "A" | "B" | "C" | "D" | "F";
727
+ interface ScoreFactor {
728
+ name: string;
729
+ weight: number;
730
+ points: number;
731
+ detail: string;
732
+ }
733
+ interface TrustScore {
734
+ programId: string;
735
+ resolved: boolean;
736
+ score: number | null;
737
+ grade: Grade | "unrated";
738
+ factors: ScoreFactor[];
739
+ summary: string;
740
+ program?: OnChainProgram;
741
+ unresolvedReason?: string;
742
+ }
743
+ declare function gradeForScore(score: number): Grade;
744
+ declare function scoreFromProgram(program: OnChainProgram): TrustScore;
745
+ declare function scoreProgram(programId: string, opts?: BuildOpts): Promise<TrustScore>;
746
+ declare function renderScoreText(s: TrustScore): string;
747
+ declare function gradeAtLeast(grade: Grade | "unrated", min: Grade): boolean;
748
+
749
+ type ChainEvent = {
750
+ type: "watch_started";
751
+ programId: string;
752
+ headSignature: string | null;
753
+ baselineAuthority: string | null;
754
+ ts: string;
755
+ } | {
756
+ type: "new_activity";
757
+ programId: string;
758
+ newCount: number;
759
+ signatures: string[];
760
+ ts: string;
761
+ } | {
762
+ type: "authority_changed";
763
+ programId: string;
764
+ from: string | null;
765
+ to: string | null;
766
+ ts: string;
767
+ } | {
768
+ type: "poll_error";
769
+ programId: string;
770
+ message: string;
771
+ ts: string;
772
+ };
773
+ interface ChainWatchState {
774
+ lastSignature: string | null;
775
+ baselineAuthority: string | null;
776
+ initialized: boolean;
777
+ }
778
+ interface ChainWatchOpts extends RpcOpts {
779
+ limit?: number;
780
+ intervalMs?: number;
781
+ emit?: (e: ChainEvent) => void;
782
+ probeAuthority?: (programId: string, opts: RpcOpts) => Promise<{
783
+ address: string | null;
784
+ }>;
785
+ }
786
+ declare function pollChainOnce(programId: string, state: ChainWatchState, opts?: ChainWatchOpts): Promise<{
787
+ events: ChainEvent[];
788
+ state: ChainWatchState;
789
+ }>;
790
+ declare function initialChainWatchState(): ChainWatchState;
791
+ declare function startChainWatch(programId: string, opts?: ChainWatchOpts): {
792
+ stop: () => void;
793
+ };
794
+
795
+ type PreflightStatus = "pass" | "warn" | "fail" | "skip";
796
+ type PreflightVerdict = "GO" | "CAUTION" | "NO-GO";
797
+ interface PreflightCheck {
798
+ id: string;
799
+ label: string;
800
+ status: PreflightStatus;
801
+ detail: string;
802
+ }
803
+ interface MintInfo {
804
+ mintAuthorityRevoked: boolean;
805
+ freezeAuthorityRevoked: boolean;
806
+ mintAuthority: string | null;
807
+ freezeAuthority: string | null;
808
+ supply: string;
809
+ decimals: number;
810
+ isInitialized: boolean;
811
+ }
812
+ interface PreflightReport {
813
+ mint: string;
814
+ verdict: PreflightVerdict;
815
+ checks: PreflightCheck[];
816
+ mintInfo?: MintInfo;
817
+ identity?: TokenIdentity;
818
+ quality?: RicoResult;
819
+ }
820
+ declare function parseMintAccount(data: Uint8Array): MintInfo;
821
+ interface PreflightOpts extends RpcOpts {
822
+ apiKey?: string;
823
+ ricoBaseUrl?: string;
824
+ jupBaseUrl?: string;
825
+ offline?: boolean;
826
+ failOnRisk?: number;
827
+ }
828
+ declare function pumpPreflight(mint: string, opts?: PreflightOpts): Promise<PreflightReport>;
829
+ declare function renderPreflightText(r: PreflightReport): string;
830
+
831
+ interface BatchRow {
832
+ mint: string;
833
+ identityStatus: IdentityStatus | "error";
834
+ impersonation: boolean;
835
+ symbol?: string;
836
+ riskScore?: number;
837
+ snipers?: boolean;
838
+ bundleClusters?: boolean;
839
+ deployerFlags?: string[];
840
+ error?: string;
841
+ rank: number;
842
+ }
843
+ interface BatchResult {
844
+ rows: BatchRow[];
845
+ summary: {
846
+ total: number;
847
+ impersonators: number;
848
+ highRisk: number;
849
+ errored: number;
850
+ };
851
+ }
852
+ interface BatchScanOpts {
853
+ apiKey?: string;
854
+ ricoBaseUrl?: string;
855
+ jupBaseUrl?: string;
856
+ offline?: boolean;
857
+ concurrency?: number;
858
+ failOnRisk?: number;
859
+ }
860
+ declare function batchScan(mints: string[], opts?: BatchScanOpts): Promise<BatchResult>;
861
+ declare function parseMintList(content: string): string[];
862
+ declare function renderBatchText(result: BatchResult): string;
863
+
864
+ export { type AccountFlow, type AnchorIdl, type AuditRef, type BatchResult, type BatchRow, type BatchScanOpts, type BuildOpts, CANONICAL_BY_MINT, CANONICAL_MINTS, type Candidate, type CanonicalMint, type ChainEvent, type ChainWatchOpts, type ChainWatchState, type ChangedRanges, type CheckOutcome, type CheckResult, type CheckResultKind, type Checker, type ConfigCandidate, type ConfigChecker, type CostReport, DEFAULT_REGISTRY_URL, DEFAULT_TTL_HOURS, type DecodedInstruction, type DecodedTx, type DiffResult, type DriftAdvisory, type DriftBaseline, type DriftPackage, type DriftResult, type FirewallFinding, type FirewallOpts, type FirewallProgram, type FirewallReport, type FirewallSeverity, type FirewallVerdict, type Grade, type GraduationEvent, type IdentityStatus, type IdlAccount, type IdlConstraintParams, type IdlInstruction, KNOWN_PROGRAMS, type MintInfo, type OnChainProgram, type OsvAdvisory, PACK_MANIFEST_FILE, type PackInitOptions, type PackManifest, type PackRuleValidation, type PackValidateResult, type ParityNote, type ParsedDiff, type PreflightCheck, type PreflightOpts, type PreflightReport, type PreflightStatus, type PreflightVerdict, type PriorityFeePosture, type ProgramCache, type ProgramCacheEntry, type Recoverability, type RicoOutcome, type RicoResult, type RicoTokenSecurity, type Rule, type RustAccountField, type RustCandidate, type RustChecker, type ScoreFactor, type Severity, type TelemetrySubmitResult, type TokenIdentity, type TrustGraph, type TrustScore, type UpgradeAuthority, type UpgradeAuthorityKind, type UpgradeAuthoritySource, type VerifiedBuildState, type VerifyOpts, type WatchEvent, type WatchOptions, analyzeCosts, analyzeInstructions, analyzeToken, applyDiffToFile, audit, auditWithRule, base58Decode, base58Encode, batchScan, buildConstraintParams, buildTrustGraph, rules as bundledRules, cacheSize, canonicalMintForSymbol, checkDrift, checkerKinds, decodeTransaction, defaultCachePath, deployerFlagsFrom, diffVersions, fileChanged, findCandidates, findConfigCandidates, generateRulesFromIdl, generateTestForResult, getCacheEntry, getCacheEntryMeta, getChangedRanges, getRepoHash, getUserHash, getWorkingTreeChanges, gradeAtLeast, gradeForScore, idlProgramName, initPack, initialChainWatchState, inspectTransaction, isCanonicalMint, isEntryExpired, isTelemetryEnabled, isValidSolanaAddress, lamportsToSol, loadDirectory, loadPack, loadPacksFromDir, loadProgramCache, loadRules, parseCpiPrograms, parseDiff, parseIdl, parseMintAccount, parseMintList, pollChainOnce, pumpPreflight, putCacheEntry, queryOsv, rangeChanged, recordGraduationEvents, renderBatchText, renderCostReportMd, renderDiffMd, renderDiffText, renderDriftText, renderFirewallText, renderPreflightText, renderRicoText, renderRulesYaml, renderScoreText, renderTest, renderTrustGraphMd, rentExemptMinimum, resolveRules, riskScore, runChecker, runIncrementalScan, saveProgramCache, scoreFromProgram, scoreProgram, seedPackages, startChainWatch, startWatch, submitTelemetry, telemetryFilePath, testKinds, toSnakeCase, validatePack, validatePackManifest, verifyTokenIdentity };