Skip to content

Commit 3af5c13

Browse files
committed
submit proof to multiple verifiers, fixed loading state and in-browser compilation (imported all versions)
1 parent 8b8af04 commit 3af5c13

21 files changed

Lines changed: 889 additions & 425 deletions

package-lock.json

Lines changed: 65 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@
3535
"func-js-bin-0.4.2": "npm:@ton-community/func-js-bin@^0.4.2",
3636
"func-js-bin-0.4.3": "npm:@ton-community/func-js-bin@^0.4.3",
3737
"func-js-bin-0.4.4": "npm:@ton-community/func-js-bin@^0.4.4",
38+
"func-js-bin-0.4.4-newops": "npm:@ton-community/func-js-bin@^0.4.4-newops",
39+
"func-js-bin-0.4.4-newops.1": "npm:@ton-community/func-js-bin@^0.4.4-newops.1",
40+
"func-js-bin-0.4.5": "npm:@ton-community/func-js-bin@^0.4.5",
41+
"func-js-bin-0.4.6": "npm:@ton-community/func-js-bin@^0.4.6",
42+
"func-js-bin-0.4.6-wasmfix.0": "npm:@ton-community/func-js-bin@^0.4.6-wasmfix.0",
3843
"immer": "^9.0.17",
3944
"javascript-time-ago": "^2.5.7",
4045
"jszip": "^3.10.1",

src/components/AddSourcesBlock.tsx

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import React from "react";
22
import { CenteringBox, DataBox } from "./Common.styled";
33
import { useFileStore } from "../lib/useFileStore";
4-
import { useSubmitSources } from "../lib/useSubmitSources";
4+
import {
5+
DEFAULT_VERIFIER,
6+
useSubmitSources,
7+
useSubmitSourcesEntries,
8+
} from "../lib/useSubmitSources";
59
import { FileUploaderArea } from "./FileUploaderArea";
610
import { FileTable } from "./FileTable";
711
import CompilerSettings from "./CompilerSettings";
@@ -12,27 +16,97 @@ import { SECTIONS, STEPS, usePublishStore } from "../lib/usePublishSteps";
1216
import { CircularProgress, Fade } from "@mui/material";
1317
import { useTonAddress } from "@tonconnect/ui-react";
1418
import ConnectButton from "./ConnectButton";
19+
import { VerifierWithId } from "../lib/wrappers/verifier-registry";
20+
import { ContractProofData } from "../lib/useLoadContractProof";
1521

1622
const ContentBox = styled(Box)({
1723
padding: "15px 24px",
1824
});
1925

20-
export function AddSourcesBlock({ contractAddress }: { contractAddress: string }) {
26+
const PrefillButtonWrapper = styled(Box)({
27+
position: "absolute",
28+
top: 12,
29+
right: 12,
30+
zIndex: 2,
31+
});
32+
33+
type AddSourcesBlockProps = {
34+
contractAddress: string;
35+
missingVerifiers?: VerifierWithId[];
36+
availableProof?: ContractProofData;
37+
};
38+
39+
export function AddSourcesBlock({
40+
contractAddress,
41+
missingVerifiers = [],
42+
availableProof,
43+
}: AddSourcesBlockProps) {
2144
const walletAddress = useTonAddress();
22-
const { hasFiles } = useFileStore();
45+
const { hasFiles, addFiles, reset: resetFiles } = useFileStore();
2346
const { step, proceedToPublish, toggleSection, currentSection } = usePublishStore();
24-
const { mutate, data, error, isLoading, compileStatus } = useSubmitSources(contractAddress);
47+
const activeVerifierName = missingVerifiers[0]?.name ?? DEFAULT_VERIFIER;
48+
const { mutate, data, error, isLoading } = useSubmitSources(contractAddress, activeVerifierName);
49+
const entries = useSubmitSourcesEntries(contractAddress);
2550

26-
const canPublish = !!data?.result?.msgCell;
51+
const readyPublishCount = missingVerifiers.length
52+
? missingVerifiers.filter((verifier) => entries[verifier.name]?.data?.result?.msgCell).length
53+
: data?.result?.msgCell
54+
? 1
55+
: 0;
56+
const canPublish = readyPublishCount > 0;
2757

2858
const onSectionExpand = () => toggleSection(SECTIONS.SOURCES);
2959

60+
const canPrefill = !!availableProof?.files?.length;
61+
62+
const handlePrefill = async () => {
63+
if (!availableProof?.files?.length) return;
64+
resetFiles();
65+
66+
const generatedFiles = availableProof.files.map((file) => {
67+
const segments = file.name.split("/");
68+
const baseName = segments.pop() ?? file.name;
69+
const generated = new File([file.content], baseName, { type: "text/plain" });
70+
const normalizedPath = segments.length > 0 ? `${segments.join("/")}/${baseName}` : baseName;
71+
Object.defineProperty(generated, "path", {
72+
value: normalizedPath,
73+
configurable: true,
74+
});
75+
return generated;
76+
});
77+
78+
await addFiles(generatedFiles);
79+
};
80+
81+
const compileVerifiers =
82+
missingVerifiers.length > 0 ? missingVerifiers.map((verifier) => verifier.name) : undefined;
83+
3084
return (
3185
<DataBox>
3286
<Box
3387
sx={{ cursor: step === STEPS.PUBLISH && canPublish ? "pointer" : "inherit" }}
3488
onClick={onSectionExpand}>
35-
<FileUploaderArea />
89+
<Box sx={{ position: "relative" }}>
90+
<FileUploaderArea />
91+
{canPrefill && (
92+
<PrefillButtonWrapper
93+
onClick={(event) => {
94+
event.stopPropagation();
95+
}}>
96+
<AppButton
97+
fontSize={12}
98+
fontWeight={600}
99+
textColor="#000"
100+
height={32}
101+
width={180}
102+
background="#fff"
103+
hoverBackground="#F5F5F5"
104+
onClick={handlePrefill}>
105+
Load verified sources
106+
</AppButton>
107+
</PrefillButtonWrapper>
108+
)}
109+
</Box>
36110
</Box>
37111
{currentSection === SECTIONS.SOURCES && (
38112
<Fade in={currentSection === SECTIONS.SOURCES}>
@@ -60,7 +134,13 @@ export function AddSourcesBlock({ contractAddress }: { contractAddress: string }
60134
background="#1976d2"
61135
hoverBackground="#156cc2"
62136
onClick={() => {
63-
mutate(null);
137+
mutate(
138+
compileVerifiers
139+
? {
140+
verifiers: compileVerifiers,
141+
}
142+
: null,
143+
);
64144
}}>
65145
{isLoading && (
66146
<CircularProgress

src/components/ContractBlock.tsx

Lines changed: 80 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { useContractAddress } from "../lib/useContractAddress";
33
import { useLoadContractInfo } from "../lib/useLoadContractInfo";
44
import contractIcon from "../assets/contract.svg";
55
import { DataBlock, DataRowItem } from "./DataBlock";
6-
import { hasAnyOnchainProof, useLoadContractProof } from "../lib/useLoadContractProof";
76
import { workchainForAddress } from "../lib/workchainForAddress";
87
import { formatBalance } from "../utils/numberUtils";
98
import { useEffect } from "react";
9+
import { SkeletonBox } from "./SkeletonBox";
1010

1111
function useToggle<T>(valA: T, valB: T): [T, () => void] {
1212
const [state, setState] = useState(valA);
@@ -25,9 +25,7 @@ function useToggle<T>(valA: T, valB: T): [T, () => void] {
2525

2626
export function ContractBlock() {
2727
const { contractAddress, contractAddressHex } = useContractAddress();
28-
const { data, isLoading } = useLoadContractInfo();
29-
const { data: proofData } = useLoadContractProof();
30-
const dataRows: DataRowItem[] = [];
28+
const { data, isLoading, error } = useLoadContractInfo();
3129

3230
const [displayAddress, toggleDisplayAddress] = useToggle(contractAddress, contractAddressHex);
3331
const [displayCodeCellHash, toggleDisplayCodeCellHash] = useToggle(
@@ -44,56 +42,92 @@ export function ContractBlock() {
4442
data?.libraryHash.hex,
4543
);
4644

47-
if (data) {
48-
dataRows.push({
49-
title: "Address",
50-
value: displayAddress ?? "",
51-
showIcon: true,
52-
onClick: () => {
53-
toggleDisplayAddress();
54-
},
55-
tooltip: true,
56-
subtitle: workchainForAddress(contractAddress || ""),
57-
});
58-
dataRows.push({
59-
title: "Balance",
60-
value: `${formatBalance.format(parseFloat(data.balance))} TON`,
61-
});
62-
dataRows.push({
63-
title: "Code Hash",
64-
value: displayCodeCellHash ?? "",
65-
showIcon: true,
66-
onClick: () => {
67-
toggleDisplayCodeCellHash();
68-
},
69-
tooltip: true,
70-
});
71-
dataRows.push({
72-
title: "Data Hash",
73-
value: displayDataCellHash ?? "",
74-
showIcon: true,
75-
onClick: () => {
76-
toggleDisplayDataCellHash();
45+
const dataRows = React.useMemo(() => {
46+
if (error) {
47+
{
48+
return [
49+
{
50+
title: "Error",
51+
value: String(error),
52+
},
53+
];
54+
}
55+
}
56+
let rows: DataRowItem[] = [
57+
{
58+
title: "Address",
59+
value: displayAddress ?? "",
60+
showIcon: true,
61+
onClick: () => {
62+
toggleDisplayAddress();
63+
},
64+
tooltip: true,
65+
subtitle: workchainForAddress(contractAddress || ""),
7766
},
78-
tooltip: true,
79-
});
67+
];
8068

81-
if (data?.libraryHash.base64) {
82-
dataRows.push({
83-
title: "Library Code Cell Hash",
84-
value: displayLibraryHash ?? "",
69+
if (!data) {
70+
rows.push({
71+
title: "State",
72+
value: "uninitialized",
73+
});
74+
return rows;
75+
}
76+
77+
rows = [
78+
...rows,
79+
{
80+
title: "Balance",
81+
value: `${formatBalance.format(parseFloat(data.balance))} TON`,
82+
},
83+
{
84+
title: "Code Hash",
85+
value: displayCodeCellHash ?? "",
8586
showIcon: true,
8687
onClick: () => {
87-
toggleDisplayLibraryHash();
88+
toggleDisplayCodeCellHash();
8889
},
8990
tooltip: true,
90-
});
91-
dataRows.push({
92-
title: "",
93-
value: "",
91+
},
92+
{
93+
title: "Data Hash",
94+
value: displayDataCellHash ?? "",
9495
showIcon: true,
95-
});
96+
onClick: () => {
97+
toggleDisplayDataCellHash();
98+
},
99+
tooltip: true,
100+
},
101+
];
102+
103+
if (data?.libraryHash.base64) {
104+
rows = [
105+
...rows,
106+
{
107+
title: "Library Code Cell Hash",
108+
value: displayLibraryHash ?? "",
109+
showIcon: true,
110+
onClick: () => {
111+
toggleDisplayLibraryHash();
112+
},
113+
tooltip: true,
114+
},
115+
];
96116
}
117+
118+
return rows;
119+
}, [
120+
data,
121+
error,
122+
displayAddress,
123+
displayCodeCellHash,
124+
displayDataCellHash,
125+
displayLibraryHash,
126+
contractAddress,
127+
]);
128+
129+
if (isLoading) {
130+
return <SkeletonBox content={false} />;
97131
}
98132

99133
return (

0 commit comments

Comments
 (0)