diff --git a/package-lock.json b/package-lock.json index 9b907a3..216b877 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,8 +44,8 @@ "react-qr-code": "^2.0.8", "react-router-dom": "^6.4.2", "source-map-explorer": "^2.5.3", - "ton": "^13.4.1", - "ton-core": "^0.49.0", + "ton": "^13.9.0", + "ton-core": "^0.53.0", "tvm-disassembler": "^2.0.2", "web-tree-sitter": "^0.20.7", "zustand": "^4.1.3" @@ -4011,9 +4011,9 @@ } }, "node_modules/ton": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/ton/-/ton-13.5.0.tgz", - "integrity": "sha512-pfuw1HQNurW3OGFTCM2JebLOYIwk8TJEjsbt0aSBUqBmPpayPkfWvkOa4xjJoFdRvb3+q3si2ePOdUfATXsI4g==", + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/ton/-/ton-13.9.0.tgz", + "integrity": "sha512-IjZa4vFsyYHzQFY3kMSK/vw8T9b4zSJlSkZOgD8qeP4AFVxcD6pZ7TxfATwLJnA/4MCbaM9DY0V076oMjluDQg==", "dependencies": { "axios": "^0.25.0", "dataloader": "^2.0.0", @@ -4022,14 +4022,14 @@ "zod": "^3.21.4" }, "peerDependencies": { - "ton-core": ">=0.48.0", + "ton-core": ">=0.53.0", "ton-crypto": ">=3.2.0" } }, "node_modules/ton-core": { - "version": "0.49.1", - "resolved": "https://registry.npmjs.org/ton-core/-/ton-core-0.49.1.tgz", - "integrity": "sha512-qPQdGPGxCYUuF/ZzfaGU4pftbIU6fxkWCzehB2Ipf5yqo5BabZibLAXEQScgFKgjYDLXcMzptt/6DWQo5/LH+w==", + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/ton-core/-/ton-core-0.53.0.tgz", + "integrity": "sha512-uO/U1oVLdEliWWbwfNQQK+61C+KM0ehcTdHQ6cN0WSEH2UzGfdVFpC4Wb0ph+wUYe/5njl7TA0uL9nif9Q6qwA==", "dependencies": { "symbol.inspect": "1.0.1" }, @@ -7240,9 +7240,9 @@ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" }, "ton": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/ton/-/ton-13.5.0.tgz", - "integrity": "sha512-pfuw1HQNurW3OGFTCM2JebLOYIwk8TJEjsbt0aSBUqBmPpayPkfWvkOa4xjJoFdRvb3+q3si2ePOdUfATXsI4g==", + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/ton/-/ton-13.9.0.tgz", + "integrity": "sha512-IjZa4vFsyYHzQFY3kMSK/vw8T9b4zSJlSkZOgD8qeP4AFVxcD6pZ7TxfATwLJnA/4MCbaM9DY0V076oMjluDQg==", "requires": { "axios": "^0.25.0", "dataloader": "^2.0.0", @@ -7252,9 +7252,9 @@ } }, "ton-core": { - "version": "0.49.1", - "resolved": "https://registry.npmjs.org/ton-core/-/ton-core-0.49.1.tgz", - "integrity": "sha512-qPQdGPGxCYUuF/ZzfaGU4pftbIU6fxkWCzehB2Ipf5yqo5BabZibLAXEQScgFKgjYDLXcMzptt/6DWQo5/LH+w==", + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/ton-core/-/ton-core-0.53.0.tgz", + "integrity": "sha512-uO/U1oVLdEliWWbwfNQQK+61C+KM0ehcTdHQ6cN0WSEH2UzGfdVFpC4Wb0ph+wUYe/5njl7TA0uL9nif9Q6qwA==", "requires": { "symbol.inspect": "1.0.1" } diff --git a/package.json b/package.json index 15867f0..c7ca6d5 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,8 @@ "react-qr-code": "^2.0.8", "react-router-dom": "^6.4.2", "source-map-explorer": "^2.5.3", - "ton": "^13.4.1", - "ton-core": "^0.49.0", + "ton": "^13.9.0", + "ton-core": "^0.53.0", "tvm-disassembler": "^2.0.2", "web-tree-sitter": "^0.20.7", "zustand": "^4.1.3" diff --git a/src/components/ContractBlock.tsx b/src/components/ContractBlock.tsx index 8d97f2d..2408990 100644 --- a/src/components/ContractBlock.tsx +++ b/src/components/ContractBlock.tsx @@ -39,6 +39,11 @@ export function ContractBlock() { data?.dataCellHash.hex, ); + const [displayLibraryHash, toggleDisplayLibraryHash] = useToggle( + data?.libraryHash.base64, + data?.libraryHash.hex, + ); + if (data) { dataRows.push({ title: "Address", @@ -72,6 +77,23 @@ export function ContractBlock() { }, tooltip: true, }); + + if (data?.libraryHash.base64) { + dataRows.push({ + title: "Library Code Cell Hash", + value: displayLibraryHash ?? "", + showIcon: true, + onClick: () => { + toggleDisplayLibraryHash(); + }, + tooltip: true, + }); + dataRows.push({ + title: "", + value: "", + showIcon: true, + }); + } } return ( diff --git a/src/lib/useInBrowserCompilation.ts b/src/lib/useInBrowserCompilation.ts index b946791..e170530 100644 --- a/src/lib/useInBrowserCompilation.ts +++ b/src/lib/useInBrowserCompilation.ts @@ -85,7 +85,7 @@ export function useInBrowserCompilation() { const codeCell = Cell.fromBoc(Buffer.from(result.codeBoc, "base64"))[0]; setLoading(false); - contractData?.codeCellHash.base64 === codeCell.hash().toString("base64") && + contractData?.codeCellToCompileBase64 === codeCell.hash().toString("base64") && setHash(codeCell.hash().toString("base64")); sendAnalyticsEvent(AnalyticsAction.IN_BROWSER_COMPILE_SUCCESS); diff --git a/src/lib/useLoadContractInfo.ts b/src/lib/useLoadContractInfo.ts index d42ac6d..d1d74d5 100644 --- a/src/lib/useLoadContractInfo.ts +++ b/src/lib/useLoadContractInfo.ts @@ -1,4 +1,4 @@ -import { Address, fromNano, Cell } from "ton"; +import { Address, fromNano, Cell, CellType, BitReader, beginCell, BitString } from "ton"; import { useQuery } from "@tanstack/react-query"; import { fromCode } from "tvm-disassembler"; @@ -10,6 +10,16 @@ type CellHash = { hex: string; }; +export function tryLoadLibraryCodeCellHash(exoticCodeCell: Cell) { + if (exoticCodeCell.isExotic && exoticCodeCell.type == CellType.Library) { + const br = new BitReader(exoticCodeCell.bits); + br.loadBits(8); + return Buffer.from(br.loadBits(br.remaining).toString(), "hex"); + } + + return null; +} + export function useLoadContractInfo() { const { contractAddress } = useContractAddress(); @@ -24,11 +34,18 @@ export function useLoadContractInfo() { const b = await client.getBalance(_address); + const libraryHash = tryLoadLibraryCodeCellHash(codeCell); + let decompiled; - try { - decompiled = fromCode(codeCell); - } catch (e) { - decompiled = e?.toString(); + + if (libraryHash) { + decompiled = "Library contract"; + } else { + try { + decompiled = fromCode(codeCell); + } catch (e) { + decompiled = e?.toString(); + } } const codeCellHash = codeCell.hash(); @@ -45,6 +62,11 @@ export function useLoadContractInfo() { } as CellHash, decompiled, balance: fromNano(b), + libraryHash: { + base64: libraryHash?.toString("base64"), + hex: libraryHash?.toString("hex"), + }, + codeCellToCompileBase64: (libraryHash ?? codeCellHash).toString("base64"), }; }); diff --git a/src/lib/useLoadContractProof.ts b/src/lib/useLoadContractProof.ts index 35eb3de..eb3b733 100644 --- a/src/lib/useLoadContractProof.ts +++ b/src/lib/useLoadContractProof.ts @@ -36,7 +36,7 @@ export function useLoadContractProof() { }; } - const ipfsLink = await getProofIpfsLink(contractInfo!.codeCellHash.base64); + const ipfsLink = await getProofIpfsLink(contractInfo!.codeCellToCompileBase64); if (!ipfsLink) { return { hasOnchainProof: false, ipfsLink }; @@ -53,7 +53,7 @@ export function useLoadContractProof() { { enabled: !!contractAddress && - !!contractInfo?.codeCellHash.base64 && + !!contractInfo?.codeCellToCompileBase64 && publishProofStatus === "initial", retry: 2, }, diff --git a/src/lib/usePublishProof.ts b/src/lib/usePublishProof.ts index 8186a17..21c0086 100644 --- a/src/lib/usePublishProof.ts +++ b/src/lib/usePublishProof.ts @@ -13,7 +13,7 @@ export function usePublishProof() { const { data: sourcesRegistryData } = useLoadSourcesRegistryInfo(); const { sendTXN, data, clearTXN } = useSendTXN("publishProof", async (count: number) => { - const ipfsLink = await getProofIpfsLink(contractInfo!.codeCellHash.base64); + const ipfsLink = await getProofIpfsLink(contractInfo!.codeCellToCompileBase64); if (count > 20) { return "error"; diff --git a/src/lib/useSubmitSources.ts b/src/lib/useSubmitSources.ts index 82d1d07..64ebd1e 100644 --- a/src/lib/useSubmitSources.ts +++ b/src/lib/useSubmitSources.ts @@ -62,7 +62,7 @@ export function useSubmitSources() { const mutation = useCustomMutation(["submitSources"], async () => { if (!contractAddress) return; - if (!contractInfo?.codeCellHash.base64) return; + if (!contractInfo?.codeCellToCompileBase64) return; if (!hasFiles()) return; if (!verifierRegistryConfig) return; if (!walletAddress) { @@ -90,7 +90,7 @@ export function useSubmitSources() { compiler, compilerSettings, knownContractAddress: contractAddress, - knownContractHash: contractInfo.codeCellHash.base64, + knownContractHash: contractInfo.codeCellToCompileBase64, sources: files.map((u) => ({ includeInCommand: u.includeInCommand, isEntrypoint: u.isEntrypoint,