diff --git a/.gitignore b/.gitignore
index fd3dbb5..a14154f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@
# misc
.DS_Store
+.vscode/
*.pem
# debug
diff --git a/components/build-deploy-panel.tsx b/components/build-deploy-panel.tsx
index 9509f7d..99691d2 100644
--- a/components/build-deploy-panel.tsx
+++ b/components/build-deploy-panel.tsx
@@ -6,13 +6,15 @@ import { useCliCommands } from "./workspace/use-cli-commands";
import useSWR, { mutate } from "swr";
import { db } from "@/data/db";
import { useWorkspaceId } from "./workspace/use-workspace-id";
-import { Download, Rocket, ShieldCheck, Wrench, TestTube2, Link2 } from "lucide-react";
+import { Download, Rocket, ShieldCheck, Wrench, TestTube2, Link2, HandCoins } from "lucide-react";
import UploadModal from "./workspace/upload-modal";
import { Tooltip } from "./tooltip";
+import { AuditType } from "@/data/audit";
export function BuildDeployPanel() {
const commands = useCliCommands();
const [isAuditing, setIsAuditing] = useState(false);
+ const [isSaveGasFeeAuditing, setIsSaveGasFeeAuditing] = useState(false);
const [isBuilding, setIsBuilding] = useState(false);
const [isDeploying, setIsDeploying] = useState(false);
const [isTesting, setIsTesting] = useState(false);
@@ -38,7 +40,7 @@ export function BuildDeployPanel() {
onClick: async () => {
setIsAuditing(true);
try {
- await commands.audit();
+ await commands.audit(AuditType.DEFAULT);
} catch (err) {
console.log(err);
} finally {
@@ -47,6 +49,21 @@ export function BuildDeployPanel() {
},
icon: ShieldCheck,
},
+ {
+ disabled: isSaveGasFeeAuditing,
+ title: "Save Gas Fee",
+ onClick: async () => {
+ setIsSaveGasFeeAuditing(true);
+ try {
+ await commands.audit(AuditType.SAVE_GAS_FEE);
+ } catch (err) {
+ console.log(err);
+ } finally {
+ setIsSaveGasFeeAuditing(false);
+ }
+ },
+ icon: HandCoins,
+ },
{
disabled: isBuilding,
title: "Build",
diff --git a/components/file-explorer/index.tsx b/components/file-explorer/index.tsx
index 44c7d23..780544e 100644
--- a/components/file-explorer/index.tsx
+++ b/components/file-explorer/index.tsx
@@ -94,7 +94,7 @@ const FileExplorer = () => {
});
if (children.length === 0) {
- setSearchParams("file", encodeURIComponent(id));
+ setSearchParams({ file: encodeURIComponent(id) });
}
}}
// @ts-expect-error
diff --git a/components/workspace/use-cli-commands.tsx b/components/workspace/use-cli-commands.tsx
index 84d7f65..e98f67f 100644
--- a/components/workspace/use-cli-commands.tsx
+++ b/components/workspace/use-cli-commands.tsx
@@ -7,7 +7,12 @@ import { usePathname } from "next/navigation";
import { PropsWithChildren, useContext, useEffect, useState } from "react";
import { TerminalContext } from "react-terminal";
import { useWorkspaceId } from "./use-workspace-id";
-import { uploadContractCode, useAudit, useAuditReport } from "@/data/audit";
+import {
+ AuditType,
+ uploadContractCode,
+ useAudit,
+ useAuditReport,
+} from "@/data/audit";
import clsx from "clsx";
import { fileContentToZip } from "@/lib/file-content-to-zip";
import { saveAs } from "file-saver";
@@ -36,7 +41,9 @@ export function useCliCommands() {
test - tests the current workspace
deploy - deploys the built smart contract
export - exports the current workspace
- share - generates a share link for the current workspace
+
+ share - generates a share link for the current workspace
+
check txID - checks the result of transaction
@@ -44,7 +51,7 @@ export function useCliCommands() {
);
},
- audit: async () => {
+ audit: async (auditType: AuditType) => {
const start = `${pathname}/`;
terminalContext.setBufferedContent(
<>
@@ -70,7 +77,7 @@ export function useCliCommands() {
);
try {
- const codeHash = await uploadContractCode(files);
+ const codeHash = await uploadContractCode(auditType, files);
terminalContext.setBufferedContent(
<>
@@ -80,13 +87,17 @@ export function useCliCommands() {
if (!wallet) return;
- setSearchParams("auditId", codeHash);
+ setSearchParams({ auditId: codeHash, auditType });
const { TransactionId } = await wallet.auditTransfer(codeHash);
terminalContext.setBufferedContent(
<>
-
+
>
);
} catch (err) {
@@ -258,7 +269,9 @@ export function useCliCommands() {
const file = new File(
[zip],
`${pathname?.split("/")?.pop() || "export"}.zip`,
- { type: "data:application/octet-stream;base64," }
+ {
+ type: "data:application/octet-stream;base64,",
+ }
);
saveAs(file);
},
@@ -281,7 +294,8 @@ export function useCliCommands() {
<>
Loaded files: {files.map((i) => i.path).join(", ")}
- Generating share link...
+ Generating share
+ link...
>
);
@@ -293,9 +307,7 @@ export function useCliCommands() {
});
const { id } = await res.json();
- terminalContext.setBufferedContent(
-
- );
+ terminalContext.setBufferedContent();
} catch (err) {
if (err instanceof Error)
terminalContext.setBufferedContent(<>{err.message}>);
@@ -385,21 +397,29 @@ function DeployedContractDetails({ id }: { id?: string }) {
}
function AuditReport({
+ auditType,
codeHash,
transactionId,
}: {
+ auditType: AuditType;
codeHash: string;
transactionId: string;
}) {
- const { isLoading, error } = useAudit(codeHash, transactionId);
+ const { isLoading, error } = useAudit(auditType, codeHash, transactionId);
if (isLoading || !!error) return Loading report...;
- return ;
+ return ;
}
-function AuditReportResult({ codeHash }: { codeHash: string }) {
- const { data, isLoading } = useAuditReport(codeHash);
+function AuditReportResult({
+ auditType,
+ codeHash,
+}: {
+ auditType: AuditType;
+ codeHash: string;
+}) {
+ const { data, isLoading } = useAuditReport(auditType, codeHash);
if (isLoading || !data) return Loading report...;
@@ -438,4 +458,3 @@ function AuditReportResult({ codeHash }: { codeHash: string }) {
>
);
}
-
diff --git a/data/audit.ts b/data/audit.ts
index fc03e89..7d08bd4 100644
--- a/data/audit.ts
+++ b/data/audit.ts
@@ -7,9 +7,30 @@ import { fileContentToZip } from "@/lib/file-content-to-zip";
import { v4 as uuidv4 } from "uuid";
import { useSearchParams } from "next/navigation";
+export enum AuditType {
+ DEFAULT = "default",
+ SAVE_GAS_FEE = "saveGasFee",
+}
+
+const URL_CONFIG = {
+ [AuditType.DEFAULT]: {
+ uploadContractCode: "/api/playground/audit/uploadContractCode",
+ auditContractCode: "/api/playground/audit/auditContractCode",
+ report: "/api/playground/report",
+ },
+ [AuditType.SAVE_GAS_FEE]: {
+ uploadContractCode: "/api/playground/adjustGasFee/uploadContractCode",
+ auditContractCode: "/api/playground/adjustGasFee/execute",
+ report: "/api/playground/adjustGasFee/report",
+ },
+};
+
const uploadContractCodeSchema = z.object({ codeHash: z.string() });
-export async function uploadContractCode(files: FileContent[]) {
+export async function uploadContractCode(
+ auditType: AuditType,
+ files: FileContent[]
+) {
const zippedData = fileContentToZip(files);
const formData = new FormData();
@@ -27,7 +48,7 @@ export async function uploadContractCode(files: FileContent[]) {
};
const res = await fetch(
- `/api/playground/audit/uploadContractCode`,
+ URL_CONFIG[auditType].uploadContractCode,
requestInit
);
@@ -46,12 +67,16 @@ export async function uploadContractCode(files: FileContent[]) {
const auditSchema = z.object({ reportUrl: z.string() });
-export function useAudit(auditId?: string, transactionId?: string) {
+export function useAudit(
+ auditType: AuditType,
+ auditId?: string,
+ transactionId?: string
+) {
return useSWRImmutable(
auditId && transactionId ? `audit-${auditId}-${transactionId}` : undefined,
async () => {
const res = await fetch(
- `/api/playground/audit/auditContractCode?auditId=${auditId}&transactionId=${transactionId}`
+ `${URL_CONFIG[auditType].auditContractCode}?auditId=${auditId}&transactionId=${transactionId}`
);
const data = await res.json();
@@ -75,11 +100,13 @@ const auditReportSchema = z.record(
)
);
-export function useAuditReport(auditId?: string) {
+export function useAuditReport(auditType?: AuditType, auditId?: string) {
return useSWRImmutable(
auditId ? `audit-report-${auditId}` : undefined,
async () => {
- const res = await fetch(`/api/playground/report/${auditId}`);
+ if (!auditType) return;
+
+ const res = await fetch(`${URL_CONFIG[auditType].report}/${auditId}`);
const data = await res.json();
@@ -94,5 +121,6 @@ export function useAuditReport(auditId?: string) {
export function useAuditReportSearchParam() {
const params = useSearchParams();
const auditId = params.get("auditId");
- return useAuditReport(auditId || undefined);
-}
\ No newline at end of file
+ const auditType = params.get("auditType") as AuditType | null;
+ return useAuditReport(auditType || undefined, auditId || undefined);
+}
diff --git a/lib/set-search-params.ts b/lib/set-search-params.ts
index 239f4a1..a70bc1f 100644
--- a/lib/set-search-params.ts
+++ b/lib/set-search-params.ts
@@ -9,11 +9,16 @@ export function useSetSearchParams() {
const router = useRouter();
const createQueryString = useCallback(
- (key: string, value?: string) => {
+ (paramsObj: Record) => {
const params = new URLSearchParams(searchParams.toString());
- params.delete(key);
- if (value) params.set(key, value);
+ Object.keys(paramsObj).forEach((key) => {
+ params.delete(key);
+ const value = paramsObj[key];
+ if (value) {
+ params.set(key, value);
+ }
+ });
const res = params.toString();
@@ -24,7 +29,7 @@ export function useSetSearchParams() {
[searchParams]
);
- return (key: string, value?: string) => {
- router.push(pathname + createQueryString(key, value));
+ return (paramsObj: Record) => {
+ router.push(pathname + createQueryString(paramsObj));
};
}
diff --git a/next.config.mjs b/next.config.mjs
index e80071f..efbdc6f 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -38,6 +38,10 @@ if (process.env.NODE_ENV === "development") {
source: "/api/playground/report/:path*",
destination: `https://playground-next.test.aelf.dev/api/playground/report/:path*`,
},
+ {
+ source: "/api/playground/adjustGasFee/:path*",
+ destination: `https://playground-next.test.aelf.dev/api/playground/adjustGasFee/:path*`,
+ },
];
};
}