Skip to content

Commit

Permalink
Merge pull request #44 from AElfProject/feature/save-gas-fee
Browse files Browse the repository at this point in the history
Feat: save gas fee
  • Loading branch information
AbigailDeng authored Sep 26, 2024
2 parents 40b1c4c + 1c4865d commit d2552a0
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

# misc
.DS_Store
.vscode/
*.pem

# debug
Expand Down
21 changes: 19 additions & 2 deletions components/build-deploy-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 {
Expand All @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion components/file-explorer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const FileExplorer = () => {
});

if (children.length === 0) {
setSearchParams("file", encodeURIComponent(id));
setSearchParams({ file: encodeURIComponent(id) });
}
}}
// @ts-expect-error
Expand Down
51 changes: 35 additions & 16 deletions components/workspace/use-cli-commands.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -36,15 +41,17 @@ export function useCliCommands() {
<li className="ml-8">test - tests the current workspace</li>
<li className="ml-8">deploy - deploys the built smart contract</li>
<li className="ml-8">export - exports the current workspace</li>
<li className="ml-8">share - generates a share link for the current workspace</li>
<li className="ml-8">
share - generates a share link for the current workspace
</li>
<li className="ml-8">
check txID - checks the result of transaction
</li>
</ol>
</div>
);
},
audit: async () => {
audit: async (auditType: AuditType) => {
const start = `${pathname}/`;
terminalContext.setBufferedContent(
<>
Expand All @@ -70,7 +77,7 @@ export function useCliCommands() {
);

try {
const codeHash = await uploadContractCode(files);
const codeHash = await uploadContractCode(auditType, files);

terminalContext.setBufferedContent(
<>
Expand All @@ -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(
<>
<AuditReport codeHash={codeHash} transactionId={TransactionId} />
<AuditReport
auditType={auditType}
codeHash={codeHash}
transactionId={TransactionId}
/>
</>
);
} catch (err) {
Expand Down Expand Up @@ -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);
},
Expand All @@ -281,7 +294,8 @@ export function useCliCommands() {
<>
<p>Loaded files: {files.map((i) => i.path).join(", ")}</p>
<p>
<Loader2 className="h-4 w-4 animate-spin inline" /> Generating share link...
<Loader2 className="h-4 w-4 animate-spin inline" /> Generating share
link...
</p>
</>
);
Expand All @@ -293,9 +307,7 @@ export function useCliCommands() {
});
const { id } = await res.json();

terminalContext.setBufferedContent(
<ShareLink id={id} />
);
terminalContext.setBufferedContent(<ShareLink id={id} />);
} catch (err) {
if (err instanceof Error)
terminalContext.setBufferedContent(<>{err.message}</>);
Expand Down Expand Up @@ -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>Loading report...</Loading>;

return <AuditReportResult codeHash={codeHash} />;
return <AuditReportResult auditType={auditType} codeHash={codeHash} />;
}

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>Loading report...</Loading>;

Expand Down Expand Up @@ -438,4 +458,3 @@ function AuditReportResult({ codeHash }: { codeHash: string }) {
</>
);
}

44 changes: 36 additions & 8 deletions data/audit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -27,7 +48,7 @@ export async function uploadContractCode(files: FileContent[]) {
};

const res = await fetch(
`/api/playground/audit/uploadContractCode`,
URL_CONFIG[auditType].uploadContractCode,
requestInit
);

Expand All @@ -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();
Expand All @@ -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();

Expand All @@ -94,5 +121,6 @@ export function useAuditReport(auditId?: string) {
export function useAuditReportSearchParam() {
const params = useSearchParams();
const auditId = params.get("auditId");
return useAuditReport(auditId || undefined);
}
const auditType = params.get("auditType") as AuditType | null;
return useAuditReport(auditType || undefined, auditId || undefined);
}
15 changes: 10 additions & 5 deletions lib/set-search-params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ export function useSetSearchParams() {
const router = useRouter();

const createQueryString = useCallback(
(key: string, value?: string) => {
(paramsObj: Record<string, string | undefined>) => {
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();

Expand All @@ -24,7 +29,7 @@ export function useSetSearchParams() {
[searchParams]
);

return (key: string, value?: string) => {
router.push(pathname + createQueryString(key, value));
return (paramsObj: Record<string, string | undefined>) => {
router.push(pathname + createQueryString(paramsObj));
};
}
4 changes: 4 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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*`,
},
];
};
}
Expand Down

0 comments on commit d2552a0

Please sign in to comment.