npmguard-cli 0.5.6 → 1.0.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.
package/dist/render.js ADDED
@@ -0,0 +1,47 @@
1
+ import chalk from "chalk";
2
+ export function renderVerdict(verdict, capabilities, proofCount) {
3
+ const isSafe = verdict.toUpperCase() === "SAFE";
4
+ const color = isSafe ? chalk.green : chalk.red;
5
+ const bgColor = isSafe ? chalk.bgGreen.white.bold : chalk.bgRed.white.bold;
6
+ console.log();
7
+ console.log(bgColor(` ${verdict.toUpperCase()} `));
8
+ console.log();
9
+ if (capabilities.length > 0) {
10
+ console.log(color("Capabilities: ") + capabilities.map((c) => chalk.yellow(c)).join(", "));
11
+ }
12
+ console.log(color(`Findings: ${proofCount}`));
13
+ console.log();
14
+ }
15
+ export function renderFinding(finding) {
16
+ console.log();
17
+ console.log(chalk.red.bold("! ") + chalk.white.bold(finding.problem));
18
+ if (finding.evidence) {
19
+ console.log(chalk.gray(" Evidence: ") + chalk.white(finding.evidence));
20
+ }
21
+ if (finding.capabilities && finding.capabilities.length > 0) {
22
+ const tags = finding.capabilities
23
+ .map((c) => chalk.bgYellow.black(` ${c} `))
24
+ .join(" ");
25
+ console.log(" " + tags);
26
+ }
27
+ if (finding.severity) {
28
+ const severityColor = finding.severity === "critical"
29
+ ? chalk.red
30
+ : finding.severity === "high"
31
+ ? chalk.yellow
32
+ : chalk.white;
33
+ console.log(chalk.gray(" Severity: ") + severityColor(finding.severity));
34
+ }
35
+ }
36
+ export function renderPhase(phase) {
37
+ const phaseLabels = {
38
+ downloading: "Downloading package...",
39
+ unpacking: "Unpacking archive...",
40
+ static_analysis: "Running static analysis...",
41
+ dynamic_analysis: "Running dynamic analysis...",
42
+ ai_review: "AI reviewing code...",
43
+ scoring: "Calculating score...",
44
+ finalizing: "Finalizing report...",
45
+ };
46
+ return phaseLabels[phase] ?? `Phase: ${phase}...`;
47
+ }
package/package.json CHANGED
@@ -1,39 +1,32 @@
1
1
  {
2
2
  "name": "npmguard-cli",
3
- "version": "0.5.6",
3
+ "version": "1.0.0",
4
4
  "type": "module",
5
- "description": "Check npm packages against NpmGuard security audits on ENS before installing",
6
- "bin": "./dist/index.js",
7
- "files": [
8
- "dist"
9
- ],
5
+ "description": "NpmGuard CLI — check npm packages against NpmGuard security audits",
6
+ "main": "dist/index.js",
7
+ "files": ["dist"],
8
+ "bin": {
9
+ "npmguard": "./dist/index.js"
10
+ },
10
11
  "scripts": {
11
- "build": "tsc",
12
- "prepublishOnly": "npm run build",
13
- "dev": "tsx src/index.ts"
12
+ "build": "tsc"
14
13
  },
15
14
  "keywords": [
16
15
  "npm",
17
16
  "security",
18
17
  "audit",
19
- "ens",
20
- "ipfs",
21
18
  "supply-chain"
22
19
  ],
23
20
  "license": "MIT",
24
21
  "dependencies": {
25
- "@walletconnect/sign-client": "^2.23.9",
26
- "chalk": "^5.4.0",
27
- "cli-table3": "^0.6.5",
28
- "commander": "^13.1.0",
29
- "dotenv": "^17.4.0",
30
- "ora": "^8.2.0",
31
- "qrcode-terminal": "^0.12.0",
32
- "viem": "^2.34.0"
22
+ "chalk": "^5.3.0",
23
+ "commander": "^12.1.0",
24
+ "eventsource": "^2.0.2",
25
+ "ora": "^8.1.0",
26
+ "qrcode-terminal": "^0.12.0"
33
27
  },
34
28
  "devDependencies": {
35
29
  "@types/node": "^22.0.0",
36
- "tsx": "^4.19.0",
37
- "typescript": "^5.9.0"
30
+ "typescript": "^5.6.0"
38
31
  }
39
32
  }
@@ -1,12 +0,0 @@
1
- export interface AuditResult {
2
- packageName: string;
3
- version: string;
4
- verdict: "SAFE" | "WARNING" | "CRITICAL" | "DANGEROUS";
5
- score: number;
6
- capabilities: string[];
7
- reportCid?: string;
8
- sourceCid?: string;
9
- }
10
- export interface AuditSource {
11
- getAudit(packageName: string, version: string): Promise<AuditResult | null>;
12
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- import type { AuditSource } from "../audit-source.js";
2
- export declare function checkCommand(projectPath: string, auditSource: AuditSource): Promise<void>;
@@ -1,2 +0,0 @@
1
- import type { AuditSource } from "../audit-source.js";
2
- export declare function installCommand(packageSpec: string, auditSource: AuditSource, force?: boolean): Promise<void>;
@@ -1,424 +0,0 @@
1
- import chalk from "chalk";
2
- import ora from "ora";
3
- import qrcode from "qrcode-terminal";
4
- import { createInterface } from "node:readline";
5
- import { execSync } from "node:child_process";
6
- import { createPublicClient, createWalletClient, http, formatEther, encodeFunctionData, } from "viem";
7
- import { privateKeyToAccount } from "viem/accounts";
8
- import { defineChain } from "viem";
9
- import { SignClient } from "@walletconnect/sign-client";
10
- import { AUDIT_REQUEST_ADDRESS_0G, AUDIT_REQUEST_ABI, } from "../contract.js";
11
- const ogGalileo = defineChain({
12
- id: 16602,
13
- name: "0G-Galileo-Testnet",
14
- nativeCurrency: { name: "0G", symbol: "0G", decimals: 18 },
15
- rpcUrls: { default: { http: ["https://evmrpc-testnet.0g.ai"] } },
16
- blockExplorers: { default: { name: "0G Explorer", url: "https://chainscan-galileo.0g.ai" } },
17
- testnet: true,
18
- });
19
- const IPFS_GATEWAY = "https://gateway.pinata.cloud/ipfs";
20
- const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
21
- const DEFAULT_ENGINE_URL = "http://209.38.42.28:8000";
22
- const WALLETCONNECT_PROJECT_ID = process.env.WALLETCONNECT_PROJECT_ID ?? "d5eb170c427570e15ac00ae53acc93ba";
23
- const OG_RPC = "https://evmrpc-testnet.0g.ai";
24
- const BLOCK_EXPLORER = "https://chainscan-galileo.0g.ai";
25
- function prompt(question) {
26
- const rl = createInterface({ input: process.stdin, output: process.stdout });
27
- return new Promise((resolve) => {
28
- rl.question(question, (answer) => {
29
- rl.close();
30
- resolve(answer.trim().toLowerCase());
31
- });
32
- });
33
- }
34
- function generateQrCode(text) {
35
- return new Promise((resolve) => {
36
- qrcode.generate(text, { small: true }, (code) => {
37
- console.log(code);
38
- resolve();
39
- });
40
- });
41
- }
42
- async function askInstallWithoutAudit(packageSpec) {
43
- const answer = await prompt(chalk.white(` Install from npm without audit? (y/n) `));
44
- if (answer === "y" || answer === "yes") {
45
- console.log();
46
- execSync(`npm install ${packageSpec}`, { stdio: "inherit" });
47
- }
48
- }
49
- async function requestAuditOnChain(packageName, version, privateKey) {
50
- const account = privateKeyToAccount(privateKey);
51
- const rpcUrl = OG_RPC;
52
- const publicClient = createPublicClient({
53
- chain: ogGalileo,
54
- transport: http(rpcUrl),
55
- });
56
- const walletClient = createWalletClient({
57
- account,
58
- chain: ogGalileo,
59
- transport: http(rpcUrl),
60
- });
61
- const auditFee = await publicClient.readContract({
62
- address: AUDIT_REQUEST_ADDRESS_0G,
63
- abi: AUDIT_REQUEST_ABI,
64
- functionName: "auditFee",
65
- });
66
- const hash = await walletClient.writeContract({
67
- address: AUDIT_REQUEST_ADDRESS_0G,
68
- abi: AUDIT_REQUEST_ABI,
69
- functionName: "requestAudit",
70
- args: [packageName, version],
71
- value: auditFee,
72
- });
73
- await publicClient.waitForTransactionReceipt({ hash });
74
- return hash;
75
- }
76
- async function payViaWalletConnect(packageName, version, feeWei, feeDisplay) {
77
- const calldata = encodeFunctionData({
78
- abi: AUDIT_REQUEST_ABI,
79
- functionName: "requestAudit",
80
- args: [packageName, version],
81
- });
82
- let signClient = null;
83
- // WalletConnect throws unhandled errors when MetaMask sends
84
- // session events after the session is cleaned up — suppress them
85
- const wcErrorHandler = (err) => {
86
- if (err?.message?.includes("No matching key"))
87
- return;
88
- console.error(err);
89
- process.exit(1);
90
- };
91
- process.on("uncaughtException", wcErrorHandler);
92
- try {
93
- const initSpinner = ora(" Connecting to WalletConnect...").start();
94
- signClient = await SignClient.init({
95
- projectId: WALLETCONNECT_PROJECT_ID,
96
- metadata: {
97
- name: "NpmGuard",
98
- description: "NPM package security audit",
99
- url: "https://npmguard.dev",
100
- icons: [],
101
- },
102
- });
103
- initSpinner.stop();
104
- const { uri, approval } = await signClient.connect({
105
- requiredNamespaces: {
106
- eip155: {
107
- methods: ["eth_sendTransaction"],
108
- chains: ["eip155:16602"],
109
- events: ["chainChanged", "accountsChanged"],
110
- },
111
- },
112
- });
113
- if (!uri) {
114
- console.log(chalk.red(" Failed to generate WalletConnect URI"));
115
- return false;
116
- }
117
- console.log();
118
- console.log(chalk.cyan(` Scan with your wallet to connect:`));
119
- console.log();
120
- await generateQrCode(uri);
121
- console.log();
122
- const pairSpinner = ora(" Waiting for wallet connection...").start();
123
- const session = await approval();
124
- // Find the 0G Galileo account in approved namespaces
125
- const accounts = session.namespaces.eip155?.accounts ?? [];
126
- const ogAccount = accounts.find((a) => a.startsWith("eip155:16602:"));
127
- const account = ogAccount
128
- ? ogAccount.split(":")[2]
129
- : accounts[0]?.split(":")[2];
130
- if (!account) {
131
- pairSpinner.fail("Wallet did not approve any accounts");
132
- return false;
133
- }
134
- pairSpinner.succeed(`Connected: ${account.slice(0, 6)}...${account.slice(-4)}`);
135
- console.log(chalk.cyan(` Confirm the ${feeDisplay} transaction in your wallet...`));
136
- const txHash = await signClient.request({
137
- topic: session.topic,
138
- chainId: "eip155:16602",
139
- request: {
140
- method: "eth_sendTransaction",
141
- params: [
142
- {
143
- from: account,
144
- to: AUDIT_REQUEST_ADDRESS_0G,
145
- data: calldata,
146
- value: "0x" + feeWei.toString(16),
147
- },
148
- ],
149
- },
150
- });
151
- const confirmSpinner = ora(" Waiting for on-chain confirmation...").start();
152
- const ogClient = createPublicClient({
153
- chain: ogGalileo,
154
- transport: http(OG_RPC),
155
- });
156
- const receipt = await ogClient.waitForTransactionReceipt({
157
- hash: txHash,
158
- });
159
- if (receipt.status === "success") {
160
- confirmSpinner.succeed("Payment confirmed on-chain!");
161
- console.log(chalk.gray(` Tx: ${BLOCK_EXPLORER}/tx/${txHash}`));
162
- console.log();
163
- return true;
164
- }
165
- else {
166
- confirmSpinner.fail("Transaction reverted");
167
- return false;
168
- }
169
- }
170
- catch (err) {
171
- const msg = err.message ?? String(err);
172
- if (msg.includes("rejected") || msg.includes("denied")) {
173
- console.log(chalk.yellow(" Transaction rejected by user."));
174
- }
175
- else {
176
- console.log(chalk.red(` WalletConnect error: ${msg}`));
177
- }
178
- console.log();
179
- return false;
180
- }
181
- finally {
182
- signClient = null;
183
- // Remove handler after a delay to catch late WC events
184
- setTimeout(() => process.off("uncaughtException", wcErrorHandler), 5000);
185
- }
186
- }
187
- export async function installCommand(packageSpec, auditSource, force = false) {
188
- const atIndex = packageSpec.lastIndexOf("@");
189
- let packageName;
190
- let requestedVersion = null;
191
- if (atIndex > 0) {
192
- packageName = packageSpec.slice(0, atIndex);
193
- requestedVersion = packageSpec.slice(atIndex + 1);
194
- }
195
- else {
196
- packageName = packageSpec;
197
- }
198
- const spinner = ora(`Checking audit for ${packageName}...`).start();
199
- if (!requestedVersion) {
200
- try {
201
- const resp = await fetch(`https://registry.npmjs.org/${packageName}/latest`);
202
- if (resp.ok) {
203
- const data = await resp.json();
204
- requestedVersion = data.version;
205
- }
206
- }
207
- catch {
208
- // continue
209
- }
210
- }
211
- if (!requestedVersion) {
212
- spinner.fail("Could not determine package version.");
213
- return;
214
- }
215
- const audit = await auditSource.getAudit(packageName, requestedVersion);
216
- spinner.stop();
217
- console.log();
218
- console.log(chalk.bold(` ${packageName}@${requestedVersion}`));
219
- console.log();
220
- // ─── No audit found ───────────────────────────────────────────────
221
- if (!audit) {
222
- console.log(chalk.gray(` NOT AUDITED — no NpmGuard record found for this version.`));
223
- console.log();
224
- const privateKey = process.env.NPMGUARD_PRIVATE_KEY;
225
- const contractDeployed = AUDIT_REQUEST_ADDRESS_0G !== ZERO_ADDRESS;
226
- if (contractDeployed) {
227
- const publicClient = createPublicClient({
228
- chain: ogGalileo,
229
- transport: http(OG_RPC),
230
- });
231
- // Check if user already paid (previous attempt where audit engine failed)
232
- let alreadyPaid = false;
233
- try {
234
- alreadyPaid = (await publicClient.readContract({
235
- address: AUDIT_REQUEST_ADDRESS_0G,
236
- abi: AUDIT_REQUEST_ABI,
237
- functionName: "isRequested",
238
- args: [packageName, requestedVersion],
239
- }));
240
- }
241
- catch {
242
- // can't read — assume not paid
243
- }
244
- if (alreadyPaid) {
245
- console.log(chalk.cyan(` Already paid on-chain — re-triggering audit...`));
246
- console.log();
247
- }
248
- else {
249
- // Read fee for display
250
- let feeDisplay = "0.01 0G";
251
- let feeWei = 10000000000000000n;
252
- try {
253
- feeWei = (await publicClient.readContract({
254
- address: AUDIT_REQUEST_ADDRESS_0G,
255
- abi: AUDIT_REQUEST_ABI,
256
- functionName: "auditFee",
257
- }));
258
- feeDisplay = `${formatEther(feeWei)} 0G`;
259
- }
260
- catch { }
261
- const wantAudit = await prompt(chalk.yellow(` Request on-chain audit for ${feeDisplay}? (y/n) `));
262
- if (wantAudit !== "y" && wantAudit !== "yes") {
263
- return askInstallWithoutAudit(packageSpec);
264
- }
265
- // Ask how to pay
266
- console.log();
267
- console.log(chalk.bold(` How to pay?`));
268
- if (privateKey) {
269
- console.log(` 1) Wallet (NPMGUARD_PRIVATE_KEY)`);
270
- console.log(` 2) WalletConnect (mobile wallet)`);
271
- console.log(` 3) Back`);
272
- }
273
- else {
274
- console.log(` 1) WalletConnect (mobile wallet)`);
275
- console.log(` 2) Back`);
276
- }
277
- console.log();
278
- const choice = await prompt(` Choice: `);
279
- const backChoice = privateKey ? "3" : "2";
280
- if (choice === backChoice) {
281
- return askInstallWithoutAudit(packageSpec);
282
- }
283
- if (privateKey && choice === "1") {
284
- const txSpinner = ora(" Sending payment transaction...").start();
285
- try {
286
- const txHash = await requestAuditOnChain(packageName, requestedVersion, privateKey);
287
- txSpinner.succeed("Payment confirmed on-chain!");
288
- console.log(chalk.gray(` Tx: ${BLOCK_EXPLORER}/tx/${txHash}`));
289
- console.log();
290
- }
291
- catch (err) {
292
- txSpinner.fail("Transaction failed");
293
- console.log(chalk.red(` ${err.shortMessage ?? err.message}`));
294
- console.log();
295
- return askInstallWithoutAudit(packageSpec);
296
- }
297
- }
298
- else if ((privateKey && choice === "2") || (!privateKey && choice === "1")) {
299
- const paid = await payViaWalletConnect(packageName, requestedVersion, feeWei, feeDisplay);
300
- if (!paid)
301
- return askInstallWithoutAudit(packageSpec);
302
- }
303
- else {
304
- return askInstallWithoutAudit(packageSpec);
305
- }
306
- }
307
- // Trigger audit engine (streaming endpoint)
308
- const rawApiUrl = process.env.NPMGUARD_AUDIT_API_URL ?? DEFAULT_ENGINE_URL;
309
- const engineBaseUrl = rawApiUrl.replace(/\/audit\/?$/, "");
310
- const frontendUrl = process.env.NPMGUARD_FRONTEND_URL ?? engineBaseUrl.replace(":8000", ":3000");
311
- const auditSpinner = ora(" Running security audit...").start();
312
- try {
313
- const streamResp = await fetch(`${engineBaseUrl}/audit/stream`, {
314
- method: "POST",
315
- headers: { "Content-Type": "application/json" },
316
- body: JSON.stringify({ packageName, version: requestedVersion }),
317
- });
318
- if (!streamResp.ok)
319
- throw new Error(`Audit engine returned ${streamResp.status}`);
320
- const { auditId } = await streamResp.json();
321
- auditSpinner.text = " Running security audit...";
322
- console.log();
323
- console.log(chalk.cyan(` Live audit: ${frontendUrl}/audit/${auditId}`));
324
- console.log();
325
- // Poll for completion
326
- let result;
327
- const POLL_INTERVAL = 2000;
328
- const POLL_TIMEOUT = 5 * 60_000;
329
- const start = Date.now();
330
- while (Date.now() - start < POLL_TIMEOUT) {
331
- const reportResp = await fetch(`${engineBaseUrl}/audit/${auditId}/report`);
332
- if (reportResp.status === 202) {
333
- await new Promise((r) => setTimeout(r, POLL_INTERVAL));
334
- continue;
335
- }
336
- if (!reportResp.ok)
337
- throw new Error(`Audit engine returned ${reportResp.status}`);
338
- result = await reportResp.json();
339
- break;
340
- }
341
- auditSpinner.stop();
342
- if (!result) {
343
- throw new Error("Audit timed out");
344
- }
345
- console.log();
346
- const verdict = (result.verdict ?? "UNKNOWN").toUpperCase();
347
- const capabilities = result.capabilities ?? [];
348
- if (verdict === "SAFE") {
349
- console.log(chalk.green(` Verdict: SAFE`));
350
- }
351
- else if (verdict === "DANGEROUS") {
352
- console.log(chalk.red(` Verdict: DANGEROUS`));
353
- }
354
- else {
355
- console.log(chalk.yellow(` Verdict: ${verdict}`));
356
- }
357
- if (capabilities.length > 0) {
358
- console.log(chalk.gray(` Capabilities: ${capabilities.join(", ")}`));
359
- }
360
- console.log();
361
- if (verdict === "DANGEROUS" && !force) {
362
- console.log(chalk.red.bold(" Installation blocked. This package is dangerous."));
363
- console.log(chalk.gray(" Use --force to install anyway."));
364
- console.log();
365
- return;
366
- }
367
- console.log(chalk.gray(" Installing from npm..."));
368
- console.log();
369
- execSync(`npm install ${packageSpec}`, { stdio: "inherit" });
370
- }
371
- catch (err) {
372
- auditSpinner.fail("Audit engine unreachable");
373
- console.log(chalk.gray(` ${err.message ?? err}`));
374
- console.log();
375
- return askInstallWithoutAudit(packageSpec);
376
- }
377
- return;
378
- }
379
- // Contract not deployed
380
- return askInstallWithoutAudit(packageSpec);
381
- }
382
- // ─── Audit found — show verdict ───────────────────────────────────
383
- if (audit.verdict === "SAFE") {
384
- console.log(chalk.green(` SAFE (score: ${audit.score})`));
385
- }
386
- else if (audit.verdict === "WARNING") {
387
- console.log(chalk.yellow(` WARNING (score: ${audit.score})`));
388
- }
389
- else if (audit.verdict === "CRITICAL" || audit.verdict === "DANGEROUS") {
390
- console.log(chalk.red(` DANGEROUS (score: ${audit.score})`));
391
- }
392
- if (audit.capabilities.length > 0) {
393
- console.log(chalk.gray(` Capabilities: ${audit.capabilities.join(", ")}`));
394
- }
395
- if (audit.reportCid) {
396
- console.log(chalk.gray(` Report: ${IPFS_GATEWAY}/${audit.reportCid}`));
397
- }
398
- console.log();
399
- // Block CRITICAL/DANGEROUS unless --force
400
- if ((audit.verdict === "CRITICAL" || audit.verdict === "DANGEROUS") && !force) {
401
- console.log(chalk.red.bold(" Installation blocked. This package has critical security issues."));
402
- console.log(chalk.gray(" Use --force to install anyway."));
403
- console.log();
404
- return;
405
- }
406
- // Install from IPFS if sourceCid is available
407
- if (audit.sourceCid) {
408
- const ipfsUrl = `${IPFS_GATEWAY}/${audit.sourceCid}`;
409
- console.log(chalk.green(` Installing from verified IPFS source...`));
410
- console.log();
411
- try {
412
- execSync(`npm install ${ipfsUrl}`, { stdio: "inherit" });
413
- }
414
- catch {
415
- console.log(chalk.yellow(" IPFS install failed, falling back to npm..."));
416
- execSync(`npm install ${packageSpec}`, { stdio: "inherit" });
417
- }
418
- }
419
- else {
420
- console.log(chalk.gray(" No IPFS source available, installing from npm..."));
421
- console.log();
422
- execSync(`npm install ${packageSpec}`, { stdio: "inherit" });
423
- }
424
- }
@@ -1,121 +0,0 @@
1
- export declare const AUDIT_REQUEST_ADDRESS: `0x${string}`;
2
- export declare const AUDIT_REQUEST_ADDRESS_0G: `0x${string}`;
3
- export declare const AUDIT_REQUEST_ABI: readonly [{
4
- readonly inputs: readonly [{
5
- readonly name: "_auditFee";
6
- readonly type: "uint256";
7
- }];
8
- readonly stateMutability: "nonpayable";
9
- readonly type: "constructor";
10
- }, {
11
- readonly anonymous: false;
12
- readonly inputs: readonly [{
13
- readonly indexed: false;
14
- readonly name: "packageName";
15
- readonly type: "string";
16
- }, {
17
- readonly indexed: false;
18
- readonly name: "version";
19
- readonly type: "string";
20
- }, {
21
- readonly indexed: true;
22
- readonly name: "requester";
23
- readonly type: "address";
24
- }];
25
- readonly name: "AuditRequested";
26
- readonly type: "event";
27
- }, {
28
- readonly anonymous: false;
29
- readonly inputs: readonly [{
30
- readonly indexed: true;
31
- readonly name: "key";
32
- readonly type: "bytes32";
33
- }, {
34
- readonly indexed: true;
35
- readonly name: "requester";
36
- readonly type: "address";
37
- }];
38
- readonly name: "AuditRequestedByKey";
39
- readonly type: "event";
40
- }, {
41
- readonly inputs: readonly [{
42
- readonly name: "packageName";
43
- readonly type: "string";
44
- }, {
45
- readonly name: "version";
46
- readonly type: "string";
47
- }];
48
- readonly name: "requestAudit";
49
- readonly outputs: readonly [];
50
- readonly stateMutability: "payable";
51
- readonly type: "function";
52
- }, {
53
- readonly inputs: readonly [{
54
- readonly name: "key";
55
- readonly type: "bytes32";
56
- }];
57
- readonly name: "requestAuditByKey";
58
- readonly outputs: readonly [];
59
- readonly stateMutability: "payable";
60
- readonly type: "function";
61
- }, {
62
- readonly inputs: readonly [];
63
- readonly name: "auditFee";
64
- readonly outputs: readonly [{
65
- readonly name: "";
66
- readonly type: "uint256";
67
- }];
68
- readonly stateMutability: "view";
69
- readonly type: "function";
70
- }, {
71
- readonly inputs: readonly [];
72
- readonly name: "owner";
73
- readonly outputs: readonly [{
74
- readonly name: "";
75
- readonly type: "address";
76
- }];
77
- readonly stateMutability: "view";
78
- readonly type: "function";
79
- }, {
80
- readonly inputs: readonly [{
81
- readonly name: "packageName";
82
- readonly type: "string";
83
- }, {
84
- readonly name: "version";
85
- readonly type: "string";
86
- }];
87
- readonly name: "isRequested";
88
- readonly outputs: readonly [{
89
- readonly name: "";
90
- readonly type: "bool";
91
- }];
92
- readonly stateMutability: "view";
93
- readonly type: "function";
94
- }, {
95
- readonly inputs: readonly [{
96
- readonly name: "";
97
- readonly type: "bytes32";
98
- }];
99
- readonly name: "requested";
100
- readonly outputs: readonly [{
101
- readonly name: "";
102
- readonly type: "bool";
103
- }];
104
- readonly stateMutability: "view";
105
- readonly type: "function";
106
- }, {
107
- readonly inputs: readonly [{
108
- readonly name: "_fee";
109
- readonly type: "uint256";
110
- }];
111
- readonly name: "setFee";
112
- readonly outputs: readonly [];
113
- readonly stateMutability: "nonpayable";
114
- readonly type: "function";
115
- }, {
116
- readonly inputs: readonly [];
117
- readonly name: "withdraw";
118
- readonly outputs: readonly [];
119
- readonly stateMutability: "nonpayable";
120
- readonly type: "function";
121
- }];