brainblast 0.7.3 → 0.7.4

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildTrustGraph
3
- } from "./chunk-SVSVVW6U.js";
3
+ } from "./chunk-GF37ANSW.js";
4
4
 
5
5
  // src/score.ts
6
6
  var W_AUTHORITY = 35;
@@ -1,4 +1,5 @@
1
1
  import {
2
+ getAccountInfo,
2
3
  probeUpgradeAuthority
3
4
  } from "./chunk-XSVQSK53.js";
4
5
 
@@ -39,6 +40,41 @@ function loadDirectory(path = bundledPath()) {
39
40
  return m;
40
41
  }
41
42
 
43
+ // src/trustGraph/classifyAuthority.ts
44
+ var SYSTEM_PROGRAM = "11111111111111111111111111111111";
45
+ var KNOWN_AUTHORITY_OWNERS = {
46
+ // Squads — the dominant Solana multisig. v3 ("SMPL") and v4 program ids.
47
+ // https://docs.squads.so/main/development/sdk/program-ids
48
+ SMPLecH534NA9acpos4G6x7uf3LWbCAwZQE9e8ZekMu: { kind: "multisig", label: "Squads v3" },
49
+ SQDS4ep65T869zMMBKyuUq6aD6EgTu8psMjkvj52pCf: { kind: "multisig", label: "Squads v4" },
50
+ // SPL Governance (Realms) — the standard on-chain governance program.
51
+ // https://github.com/solana-labs/solana-program-library/tree/master/governance
52
+ GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw: { kind: "dao", label: "SPL Governance (Realms)" }
53
+ };
54
+ async function classifyUpgradeAuthority(address, opts = {}) {
55
+ const acct = await getAccountInfo(address, opts);
56
+ if (!acct) {
57
+ return { kind: "unknown" };
58
+ }
59
+ if (acct.owner === SYSTEM_PROGRAM) {
60
+ return { kind: "single-key", ownerProgram: SYSTEM_PROGRAM };
61
+ }
62
+ const known = KNOWN_AUTHORITY_OWNERS[acct.owner];
63
+ if (known) {
64
+ return { kind: known.kind, ownerProgram: acct.owner, ownerLabel: known.label };
65
+ }
66
+ return { kind: "unknown", ownerProgram: acct.owner };
67
+ }
68
+ async function enrichAuthorityClassification(authority, opts = {}) {
69
+ if (authority.kind !== "unknown" || !authority.address) return authority;
70
+ const c = await classifyUpgradeAuthority(authority.address, opts);
71
+ return {
72
+ ...authority,
73
+ kind: c.kind,
74
+ ...c.ownerProgram ? { ownerProgram: c.ownerProgram } : {}
75
+ };
76
+ }
77
+
42
78
  // src/trustGraph/programCache.ts
43
79
  import { readFileSync as readFileSync2, writeFileSync, mkdirSync, existsSync as existsSync2 } from "fs";
44
80
  import { join as join2, dirname } from "path";
@@ -146,6 +182,12 @@ async function buildTrustGraph(programIds, opts = {}) {
146
182
  let authority;
147
183
  try {
148
184
  authority = await probeUpgradeAuthority(id, opts);
185
+ if (opts.classifyAuthority !== false) {
186
+ try {
187
+ authority = await enrichAuthorityClassification(authority, opts);
188
+ } catch {
189
+ }
190
+ }
149
191
  } catch (e) {
150
192
  unresolved.push({ programId: id, reason: `rpc_error: ${e?.message ?? String(e)}` });
151
193
  continue;
@@ -174,6 +216,10 @@ async function buildTrustGraph(programIds, opts = {}) {
174
216
 
175
217
  export {
176
218
  loadDirectory,
219
+ SYSTEM_PROGRAM,
220
+ KNOWN_AUTHORITY_OWNERS,
221
+ classifyUpgradeAuthority,
222
+ enrichAuthorityClassification,
177
223
  DEFAULT_TTL_HOURS,
178
224
  defaultCachePath,
179
225
  loadProgramCache,
@@ -1,19 +1,27 @@
1
1
  // src/trustGraph/render.ts
2
2
  function renderAuthority(p) {
3
3
  const a = p.upgradeAuthority;
4
+ const owner = a.ownerProgram ? ` _(owner: \`${a.ownerProgram}\`)_` : "";
4
5
  switch (a.kind) {
5
6
  case "renounced":
6
7
  return "\u{1F512} **Renounced** \u2014 program is frozen; no key can upgrade it.";
7
8
  case "single-key":
8
- return `\u26A0\uFE0F **Single key** \`${a.address}\` \u2014 one private key can replace this program at any time.`;
9
+ return `\u26A0\uFE0F **Single key** \`${a.address}\` \u2014 one private key can replace this program at any time.${owner}`;
9
10
  case "multisig":
10
- return `\u{1F510} **Multisig** \`${a.address}\` \u2014 a threshold of signers can upgrade.`;
11
+ return `\u{1F510} **Multisig** \`${a.address}\` \u2014 a threshold of signers can upgrade.${owner}`;
11
12
  case "dao":
12
- return `\u{1F3DB} **DAO** \`${a.address}\` \u2014 governance program controls upgrades.`;
13
+ return `\u{1F3DB} **DAO** \`${a.address}\` \u2014 governance program controls upgrades.${owner}`;
13
14
  case "unknown":
14
- return a.address ? `\u2753 **Unclassified authority** \`${a.address}\` \u2014 needs research to confirm single-key vs multisig/DAO.` : "\u2753 **Unknown** \u2014 could not determine upgrade authority.";
15
+ return a.address ? `\u2753 **Unclassified authority** \`${a.address}\`${owner} \u2014 needs research to confirm single-key vs multisig/DAO.` : "\u2753 **Unknown** \u2014 could not determine upgrade authority.";
15
16
  }
16
17
  }
18
+ function renderTrustSummary(p) {
19
+ const a = p.upgradeAuthority;
20
+ const authBit = a.kind === "renounced" ? "\u{1F512} immutable" : a.kind === "multisig" ? "\u{1F510} multisig" : a.kind === "dao" ? "\u{1F3DB} DAO-governed" : a.kind === "single-key" ? "\u26A0\uFE0F single-key upgradeable" : "\u2753 authority unclassified";
21
+ const verifiedBit = p.verifiedBuild.state === "verified" ? "\u2705 verified build" : p.verifiedBuild.state === "unverified" ? "\u274C unverified" : "\u2753 build unchecked";
22
+ const auditBit = p.audits.length ? `\u2705 audited (${p.audits.map((x) => x.firm).join(", ")})` : "\u274C no audits on file";
23
+ return `${authBit} \xB7 ${verifiedBit} \xB7 ${auditBit}`;
24
+ }
17
25
  function renderVerified(p) {
18
26
  const v = p.verifiedBuild;
19
27
  switch (v.state) {
@@ -42,6 +50,8 @@ function renderProgram(p) {
42
50
  "",
43
51
  `\`${p.programId}\`${p.kind ? ` \xB7 kind: \`${p.kind}\`` : ""}`,
44
52
  "",
53
+ `**Trust:** ${renderTrustSummary(p)}`,
54
+ "",
45
55
  `- **Upgrade authority:** ${renderAuthority(p)}`,
46
56
  `- **Verified build:** ${renderVerified(p)}`,
47
57
  `- **Parity:** ${renderParity(p)}`,
@@ -0,0 +1,110 @@
1
+ import {
2
+ DEFAULT_RPC
3
+ } from "./chunk-XSVQSK53.js";
4
+ import {
5
+ isValidSolanaAddress
6
+ } from "./chunk-VG5FMOLW.js";
7
+
8
+ // src/oracle.ts
9
+ var SLOT_MS = 400;
10
+ var DEFAULT_STALENESS_SLOTS = 150;
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 checkOracleFreshness(account, opts = {}) {
33
+ if (!isValidSolanaAddress(account)) throw new Error(`invalid Solana address: ${account}`);
34
+ const thresholdSlots = opts.maxStalenessSlots ?? (opts.maxStalenessSeconds != null ? Math.max(1, Math.round(opts.maxStalenessSeconds * 1e3 / SLOT_MS)) : DEFAULT_STALENESS_SLOTS);
35
+ const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
36
+ const currentSlot = await rpc("getSlot", [{ commitment: "confirmed" }], opts);
37
+ const sigs = await rpc(
38
+ "getSignaturesForAddress",
39
+ [account, { limit: 1 }],
40
+ opts
41
+ );
42
+ if (!sigs || sigs.length === 0) {
43
+ return {
44
+ account,
45
+ currentSlot,
46
+ lastSlot: null,
47
+ lastBlockTime: null,
48
+ slotsBehind: null,
49
+ secondsBehind: null,
50
+ thresholdSlots,
51
+ fresh: false,
52
+ verdict: "NO_HISTORY",
53
+ checkedAt
54
+ };
55
+ }
56
+ const last = sigs[0];
57
+ const lastSlot = last.slot;
58
+ const lastBlockTime = last.blockTime ?? null;
59
+ const slotsBehind = Math.max(0, currentSlot - lastSlot);
60
+ const secondsBehind = lastBlockTime != null ? Math.max(0, Math.floor(Date.now() / 1e3) - lastBlockTime) : Math.round(slotsBehind * SLOT_MS / 1e3);
61
+ const fresh = slotsBehind <= thresholdSlots;
62
+ return {
63
+ account,
64
+ currentSlot,
65
+ lastSlot,
66
+ lastBlockTime,
67
+ slotsBehind,
68
+ secondsBehind,
69
+ thresholdSlots,
70
+ fresh,
71
+ verdict: fresh ? "FRESH" : "STALE",
72
+ checkedAt
73
+ };
74
+ }
75
+ function renderOracleText(f) {
76
+ const L = [];
77
+ L.push("\u2500\u2500 Oracle Freshness \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
78
+ L.push(` account: ${f.account}`);
79
+ L.push(` current slot: ${f.currentSlot.toLocaleString()}`);
80
+ if (f.verdict === "NO_HISTORY") {
81
+ L.push(" last write: (no transactions found touching this account)");
82
+ L.push(" verdict: \u2753 NO_HISTORY \u2014 cannot confirm freshness");
83
+ return L.join("\n");
84
+ }
85
+ L.push(` last write: slot ${f.lastSlot.toLocaleString()} (${f.slotsBehind.toLocaleString()} slots / ~${f.secondsBehind}s ago)`);
86
+ L.push(` threshold: ${f.thresholdSlots.toLocaleString()} slots`);
87
+ L.push(` verdict: ${f.fresh ? "\u2705 FRESH" : "\u{1F6A8} STALE \u2014 last update is older than the freshness threshold"}`);
88
+ return L.join("\n");
89
+ }
90
+ function renderOracleMd(f) {
91
+ const L = ["## Oracle Freshness\n"];
92
+ L.push(`**Account:** \`${f.account}\` \xB7 checked ${f.checkedAt}
93
+ `);
94
+ if (f.verdict === "NO_HISTORY") {
95
+ L.push("\u2753 **NO_HISTORY** \u2014 no transactions were found touching this account, so freshness can't be confirmed. Double-check the address.");
96
+ return L.join("\n");
97
+ }
98
+ const badge = f.fresh ? "\u2705 **FRESH**" : "\u{1F6A8} **STALE**";
99
+ L.push(`${badge} \u2014 last written at slot ${f.lastSlot.toLocaleString()}, ${f.slotsBehind.toLocaleString()} slots (~${f.secondsBehind}s) behind the current slot (${f.currentSlot.toLocaleString()}).`);
100
+ L.push("");
101
+ L.push(`Threshold: ${f.thresholdSlots.toLocaleString()} slots. ${f.fresh ? "Within tolerance." : "**Exceeds tolerance \u2014 do not price against this feed until it updates.**"}`);
102
+ return L.join("\n");
103
+ }
104
+
105
+ export {
106
+ DEFAULT_STALENESS_SLOTS,
107
+ checkOracleFreshness,
108
+ renderOracleText,
109
+ renderOracleMd
110
+ };
package/dist/cli.js CHANGED
@@ -21,13 +21,13 @@ import {
21
21
  } from "./chunk-5VYTURTO.js";
22
22
  import {
23
23
  renderTrustGraphMd
24
- } from "./chunk-2UZGWXIX.js";
24
+ } from "./chunk-QMJEZ6NO.js";
25
25
  import {
26
26
  buildTrustGraph,
27
27
  cacheSize,
28
28
  defaultCachePath,
29
29
  loadProgramCache
30
- } from "./chunk-SVSVVW6U.js";
30
+ } from "./chunk-GF37ANSW.js";
31
31
  import {
32
32
  audit,
33
33
  getChangedRanges,
@@ -563,6 +563,10 @@ if (args[0] === "exploits") {
563
563
  runExploits(args.slice(1));
564
564
  process.exit(0);
565
565
  }
566
+ if (args[0] === "oracle") {
567
+ await runOracle(args.slice(1));
568
+ process.exit(0);
569
+ }
566
570
  if (args[0] === "fix") {
567
571
  await runFix(args.slice(1));
568
572
  process.exit(0);
@@ -700,6 +704,48 @@ function runDeployPlan(argv) {
700
704
  writeFileSync2(mdPath, renderDeployPlanMd(plan));
701
705
  console.log(` deploy plan: ${mdPath}`);
702
706
  }
707
+ async function runOracle(argv) {
708
+ if (argv.includes("--help") || argv.includes("-h") || argv.filter((a) => !a.startsWith("--")).length === 0) {
709
+ console.log("usage: brainblast oracle <account> [--rpc URL] [--max-staleness-slots N | --max-staleness-seconds N] [--json]");
710
+ console.log(" Is the oracle fresh? Reports how many slots/seconds ago the price account was");
711
+ console.log(" last written (provider-agnostic) and gates FRESH/STALE. Exit 1 on STALE or");
712
+ console.log(" NO_HISTORY. Pass your own --rpc for reliable results (public RPC is rate-limited).");
713
+ process.exit(argv.length === 0 ? 2 : 0);
714
+ }
715
+ const { checkOracleFreshness, renderOracleText, renderOracleMd } = await import("./oracle-DVZLFJ43.js");
716
+ const num = (name) => {
717
+ const i = argv.indexOf(`--${name}`);
718
+ if (i < 0) return void 0;
719
+ const v = parseInt(argv[i + 1], 10);
720
+ return Number.isFinite(v) ? v : void 0;
721
+ };
722
+ const rpcIdx = argv.indexOf("--rpc");
723
+ const rpcUrl = rpcIdx >= 0 ? argv[rpcIdx + 1] : void 0;
724
+ const account = argv.find(
725
+ (a, i) => !a.startsWith("--") && argv[i - 1] !== "--rpc" && argv[i - 1] !== "--max-staleness-slots" && argv[i - 1] !== "--max-staleness-seconds"
726
+ );
727
+ if (!account) {
728
+ console.error("error: missing <account>. usage: brainblast oracle <account> [--rpc URL] [--json]");
729
+ process.exit(2);
730
+ }
731
+ let f;
732
+ try {
733
+ f = await checkOracleFreshness(account, {
734
+ rpcUrl,
735
+ maxStalenessSlots: num("max-staleness-slots"),
736
+ maxStalenessSeconds: num("max-staleness-seconds")
737
+ });
738
+ } catch (e) {
739
+ console.error(`error: ${e?.message ?? String(e)}`);
740
+ process.exit(2);
741
+ }
742
+ if (argv.includes("--json")) console.log(JSON.stringify(f, null, 2));
743
+ else console.log(renderOracleText(f));
744
+ const outDir2 = join3(process.cwd(), ".agent-research");
745
+ mkdirSync2(outDir2, { recursive: true });
746
+ writeFileSync2(join3(outDir2, "oracle-freshness.md"), renderOracleMd(f));
747
+ process.exit(f.fresh ? 0 : 1);
748
+ }
703
749
  function runExploits(argv) {
704
750
  if (argv.includes("--help") || argv.includes("-h")) {
705
751
  console.log("usage: brainblast exploits [id] [--json]");
@@ -1172,8 +1218,8 @@ async function runIdlRules(argv) {
1172
1218
  }
1173
1219
  }
1174
1220
  async function runScore(argv) {
1175
- const { scoreProgram, renderScoreText, gradeAtLeast } = await import("./score-VLKER37D.js");
1176
- const { isValidSolanaAddress: isValidSolanaAddress2 } = await import("./trustGraph-4SSJOQKT.js");
1221
+ const { scoreProgram, renderScoreText, gradeAtLeast } = await import("./score-YXFXD6QG.js");
1222
+ const { isValidSolanaAddress: isValidSolanaAddress2 } = await import("./trustGraph-K5PWNEL4.js");
1177
1223
  const programId = argv.find((a) => !a.startsWith("--"));
1178
1224
  if (!programId) {
1179
1225
  console.error("usage: brainblast score <program-id> [--rpc URL] [--no-probe] [--min A|B|C|D|F] [--json]");
package/dist/index.d.ts CHANGED
@@ -388,6 +388,7 @@ interface UpgradeAuthority {
388
388
  address: string | null;
389
389
  source: UpgradeAuthoritySource;
390
390
  checkedAt?: string;
391
+ ownerProgram?: string;
391
392
  }
392
393
  type VerifiedBuildState = {
393
394
  state: "verified";
@@ -443,6 +444,7 @@ interface RpcOpts {
443
444
 
444
445
  interface BuildOpts extends RpcOpts {
445
446
  probeRpc?: boolean;
447
+ classifyAuthority?: boolean;
446
448
  directoryPath?: string;
447
449
  cachePath?: string | null;
448
450
  }
@@ -452,6 +454,20 @@ declare function renderTrustGraphMd(g: TrustGraph): string;
452
454
 
453
455
  declare function loadDirectory(path?: string): Map<string, OnChainProgram>;
454
456
 
457
+ declare const SYSTEM_PROGRAM = "11111111111111111111111111111111";
458
+ interface KnownOwner {
459
+ kind: Exclude<UpgradeAuthorityKind, "renounced">;
460
+ label: string;
461
+ }
462
+ declare const KNOWN_AUTHORITY_OWNERS: Record<string, KnownOwner>;
463
+ interface AuthorityClassification {
464
+ kind: UpgradeAuthorityKind;
465
+ ownerProgram?: string;
466
+ ownerLabel?: string;
467
+ }
468
+ declare function classifyUpgradeAuthority(address: string, opts?: RpcOpts): Promise<AuthorityClassification>;
469
+ declare function enrichAuthorityClassification(authority: UpgradeAuthority, opts?: RpcOpts): Promise<UpgradeAuthority>;
470
+
455
471
  declare function base58Encode(bytes: Uint8Array): string;
456
472
  declare function base58Decode(s: string): Uint8Array;
457
473
  declare function isValidSolanaAddress(s: string): boolean;
@@ -876,6 +892,32 @@ declare function batchScan(mints: string[], opts?: BatchScanOpts): Promise<Batch
876
892
  declare function parseMintList(content: string): string[];
877
893
  declare function renderBatchText(result: BatchResult): string;
878
894
 
895
+ declare const DEFAULT_STALENESS_SLOTS = 150;
896
+ type OracleVerdict = "FRESH" | "STALE" | "NO_HISTORY";
897
+ interface OracleFreshness {
898
+ account: string;
899
+ currentSlot: number;
900
+ /** Slot of the most recent signature touching the account; null if none. */
901
+ lastSlot: number | null;
902
+ /** Unix seconds of that signature's block, when the RPC provides it. */
903
+ lastBlockTime: number | null;
904
+ slotsBehind: number | null;
905
+ secondsBehind: number | null;
906
+ thresholdSlots: number;
907
+ fresh: boolean;
908
+ verdict: OracleVerdict;
909
+ checkedAt: string;
910
+ }
911
+ interface OracleOpts extends RpcOpts {
912
+ /** Staleness threshold in slots (default 150 ≈ 60s). */
913
+ maxStalenessSlots?: number;
914
+ /** Staleness threshold in seconds; converted to slots (~400ms each). */
915
+ maxStalenessSeconds?: number;
916
+ }
917
+ declare function checkOracleFreshness(account: string, opts?: OracleOpts): Promise<OracleFreshness>;
918
+ declare function renderOracleText(f: OracleFreshness): string;
919
+ declare function renderOracleMd(f: OracleFreshness): string;
920
+
879
921
  interface ExploitPattern {
880
922
  /** Stable slug, e.g. "wormhole". */
881
923
  id: string;
@@ -905,4 +947,4 @@ declare function renderExploitsMd(patterns?: ExploitPattern[]): string;
905
947
  declare function renderExploitsText(patterns?: ExploitPattern[]): string;
906
948
  declare function renderExploitDetailText(e: ExploitPattern): string;
907
949
 
908
- 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, EXPLOIT_PATTERNS, type ExploitPattern, 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, formatUsd, generateRulesFromIdl, generateTestForResult, getCacheEntry, getCacheEntryMeta, getChangedRanges, getExploitPattern, 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, renderExploitDetailText, renderExploitsMd, renderExploitsText, renderFirewallText, renderPreflightText, renderRicoText, renderRulesYaml, renderScoreText, renderTest, renderTrustGraphMd, rentExemptMinimum, resolveRules, riskScore, runChecker, runIncrementalScan, saveProgramCache, scoreFromProgram, scoreProgram, seedPackages, startChainWatch, startWatch, submitTelemetry, telemetryFilePath, testKinds, toSnakeCase, totalLossUsd, validatePack, validatePackManifest, verifyTokenIdentity };
950
+ export { type AccountFlow, type AnchorIdl, type AuditRef, type AuthorityClassification, 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_STALENESS_SLOTS, DEFAULT_TTL_HOURS, type DecodedInstruction, type DecodedTx, type DiffResult, type DriftAdvisory, type DriftBaseline, type DriftPackage, type DriftResult, EXPLOIT_PATTERNS, type ExploitPattern, 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_AUTHORITY_OWNERS, KNOWN_PROGRAMS, type MintInfo, type OnChainProgram, type OracleFreshness, type OracleOpts, type OracleVerdict, 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, SYSTEM_PROGRAM, 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, checkOracleFreshness, checkerKinds, classifyUpgradeAuthority, decodeTransaction, defaultCachePath, deployerFlagsFrom, diffVersions, enrichAuthorityClassification, fileChanged, findCandidates, findConfigCandidates, formatUsd, generateRulesFromIdl, generateTestForResult, getCacheEntry, getCacheEntryMeta, getChangedRanges, getExploitPattern, 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, renderExploitDetailText, renderExploitsMd, renderExploitsText, renderFirewallText, renderOracleMd, renderOracleText, renderPreflightText, renderRicoText, renderRulesYaml, renderScoreText, renderTest, renderTrustGraphMd, rentExemptMinimum, resolveRules, riskScore, runChecker, runIncrementalScan, saveProgramCache, scoreFromProgram, scoreProgram, seedPackages, startChainWatch, startWatch, submitTelemetry, telemetryFilePath, testKinds, toSnakeCase, totalLossUsd, validatePack, validatePackManifest, verifyTokenIdentity };
package/dist/index.js CHANGED
@@ -1,3 +1,9 @@
1
+ import {
2
+ DEFAULT_STALENESS_SLOTS,
3
+ checkOracleFreshness,
4
+ renderOracleMd,
5
+ renderOracleText
6
+ } from "./chunk-WQFLKWBY.js";
1
7
  import {
2
8
  checkDrift,
3
9
  renderDriftText,
@@ -17,7 +23,7 @@ import {
17
23
  renderScoreText,
18
24
  scoreFromProgram,
19
25
  scoreProgram
20
- } from "./chunk-UWE6HAGS.js";
26
+ } from "./chunk-F7QOW3IM.js";
21
27
  import {
22
28
  parseMintAccount,
23
29
  pumpPreflight,
@@ -64,12 +70,16 @@ import {
64
70
  } from "./chunk-5VYTURTO.js";
65
71
  import {
66
72
  renderTrustGraphMd
67
- } from "./chunk-2UZGWXIX.js";
73
+ } from "./chunk-QMJEZ6NO.js";
68
74
  import {
69
75
  DEFAULT_TTL_HOURS,
76
+ KNOWN_AUTHORITY_OWNERS,
77
+ SYSTEM_PROGRAM,
70
78
  buildTrustGraph,
71
79
  cacheSize,
80
+ classifyUpgradeAuthority,
72
81
  defaultCachePath,
82
+ enrichAuthorityClassification,
73
83
  getCacheEntry,
74
84
  getCacheEntryMeta,
75
85
  isEntryExpired,
@@ -77,7 +87,7 @@ import {
77
87
  loadProgramCache,
78
88
  putCacheEntry,
79
89
  saveProgramCache
80
- } from "./chunk-SVSVVW6U.js";
90
+ } from "./chunk-GF37ANSW.js";
81
91
  import {
82
92
  PACK_MANIFEST_FILE,
83
93
  audit,
@@ -150,10 +160,13 @@ export {
150
160
  CANONICAL_BY_MINT,
151
161
  CANONICAL_MINTS,
152
162
  DEFAULT_REGISTRY_URL,
163
+ DEFAULT_STALENESS_SLOTS,
153
164
  DEFAULT_TTL_HOURS,
154
165
  EXPLOIT_PATTERNS,
166
+ KNOWN_AUTHORITY_OWNERS,
155
167
  KNOWN_PROGRAMS,
156
168
  PACK_MANIFEST_FILE,
169
+ SYSTEM_PROGRAM,
157
170
  analyzeCosts,
158
171
  analyzeInstructions,
159
172
  analyzeToken,
@@ -169,11 +182,14 @@ export {
169
182
  cacheSize,
170
183
  canonicalMintForSymbol,
171
184
  checkDrift,
185
+ checkOracleFreshness,
172
186
  checkerKinds,
187
+ classifyUpgradeAuthority,
173
188
  decodeTransaction,
174
189
  defaultCachePath,
175
190
  deployerFlagsFrom,
176
191
  diffVersions,
192
+ enrichAuthorityClassification,
177
193
  fileChanged,
178
194
  findCandidates,
179
195
  findConfigCandidates,
@@ -223,6 +239,8 @@ export {
223
239
  renderExploitsMd,
224
240
  renderExploitsText,
225
241
  renderFirewallText,
242
+ renderOracleMd,
243
+ renderOracleText,
226
244
  renderPreflightText,
227
245
  renderRicoText,
228
246
  renderRulesYaml,
@@ -0,0 +1,15 @@
1
+ import {
2
+ DEFAULT_STALENESS_SLOTS,
3
+ checkOracleFreshness,
4
+ renderOracleMd,
5
+ renderOracleText
6
+ } from "./chunk-WQFLKWBY.js";
7
+ import "./chunk-XSVQSK53.js";
8
+ import "./chunk-VG5FMOLW.js";
9
+ import "./chunk-3RG5ZIWI.js";
10
+ export {
11
+ DEFAULT_STALENESS_SLOTS,
12
+ checkOracleFreshness,
13
+ renderOracleMd,
14
+ renderOracleText
15
+ };
@@ -4,8 +4,8 @@ import {
4
4
  renderScoreText,
5
5
  scoreFromProgram,
6
6
  scoreProgram
7
- } from "./chunk-UWE6HAGS.js";
8
- import "./chunk-SVSVVW6U.js";
7
+ } from "./chunk-F7QOW3IM.js";
8
+ import "./chunk-GF37ANSW.js";
9
9
  import "./chunk-XSVQSK53.js";
10
10
  import "./chunk-VG5FMOLW.js";
11
11
  import "./chunk-3RG5ZIWI.js";
@@ -1,12 +1,16 @@
1
1
  import {
2
2
  renderProgram,
3
3
  renderTrustGraphMd
4
- } from "./chunk-2UZGWXIX.js";
4
+ } from "./chunk-QMJEZ6NO.js";
5
5
  import {
6
6
  DEFAULT_TTL_HOURS,
7
+ KNOWN_AUTHORITY_OWNERS,
8
+ SYSTEM_PROGRAM,
7
9
  buildTrustGraph,
8
10
  cacheSize,
11
+ classifyUpgradeAuthority,
9
12
  defaultCachePath,
13
+ enrichAuthorityClassification,
10
14
  getCacheEntry,
11
15
  getCacheEntryMeta,
12
16
  isEntryExpired,
@@ -14,7 +18,7 @@ import {
14
18
  loadProgramCache,
15
19
  putCacheEntry,
16
20
  saveProgramCache
17
- } from "./chunk-SVSVVW6U.js";
21
+ } from "./chunk-GF37ANSW.js";
18
22
  import {
19
23
  DEFAULT_RPC,
20
24
  getAccountInfo,
@@ -29,11 +33,15 @@ import "./chunk-3RG5ZIWI.js";
29
33
  export {
30
34
  DEFAULT_RPC,
31
35
  DEFAULT_TTL_HOURS,
36
+ KNOWN_AUTHORITY_OWNERS,
37
+ SYSTEM_PROGRAM,
32
38
  base58Decode,
33
39
  base58Encode,
34
40
  buildTrustGraph,
35
41
  cacheSize,
42
+ classifyUpgradeAuthority,
36
43
  defaultCachePath,
44
+ enrichAuthorityClassification,
37
45
  getAccountInfo,
38
46
  getCacheEntry,
39
47
  getCacheEntryMeta,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainblast",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "type": "module",
5
5
  "description": "Deterministic auditor for catastrophic AI-integration bugs: scan a repo, find the silent money/auth traps, and generate the behavioral test that proves they're fixed.",
6
6
  "keywords": [