Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added classHash to debug page #232

Merged
merged 15 commits into from
Aug 9, 2024
5 changes: 5 additions & 0 deletions packages/nextjs/app/debug/_components/contract/ContractUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useTargetNetwork } from "~~/hooks/scaffold-stark/useTargetNetwork";
import { ContractName } from "~~/utils/scaffold-stark/contract";
import { ContractVariables } from "./ContractVariables";
import { ContractWriteMethods } from "./ContractWriteMethods";
import { ClassHash } from "~~/components/scaffold-stark/ClassHash";

type ContractUIProps = {
contractName: ContractName;
Expand Down Expand Up @@ -61,6 +62,10 @@ export const ContractUI = ({
<div className="flex flex-col gap-1">
<span className="font-bold">{contractName}</span>
<Address address={deployedContractData.address} />
<ClassHash
classHash={deployedContractData.classHash}
size="xs"
/>
<div className="flex gap-1 items-center">
<span className="font-bold text-sm">Balance:</span>
<Balance
Expand Down
85 changes: 85 additions & 0 deletions packages/nextjs/components/scaffold-stark/ClassHash.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"use client";

import { useState } from "react";
import Link from "next/link";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { Address as AddressType } from "@starknet-react/chains";
import { devnet } from "@starknet-react/chains";
import {
CheckCircleIcon,
DocumentDuplicateIcon,
} from "@heroicons/react/24/outline";
import { useTargetNetwork } from "~~/hooks/scaffold-stark/useTargetNetwork";
import { getBlockExplorerClasshashLink } from "~~/utils/scaffold-stark";

type ClasshashProps = {
classHash: AddressType;
format?: "short" | "long";
size?: "xs" | "sm" | "base" | "lg" | "xl" | "2xl" | "3xl";
};

/**
* Displays a Classhash and option to copy classHash.
*/
export const ClassHash = ({
classHash,
format,
size = "xs",
}: ClasshashProps) => {
const [addressCopied, setAddressCopied] = useState(false);
const { targetNetwork } = useTargetNetwork();

const blockExplorerAddressLink = getBlockExplorerClasshashLink(
targetNetwork,
classHash,
);

let displayClasshash = classHash?.slice(0, 6) + "..." + classHash?.slice(-4);

if (format === "long") {
displayClasshash = classHash;
}

return (
<div className="flex items-center">
<div className="flex-shrink-0">
<span className={`text-${size} font-normal`}>class hash: </span>
</div>
{targetNetwork.network === devnet.network ? (
<span className={`ml-1.5 text-${size} font-normal`}>
<Link href={blockExplorerAddressLink}>{displayClasshash}</Link>
</span>
) : (
<a
className={`ml-1.5 text-${size} font-normal`}
target="_blank"
href={blockExplorerAddressLink}
rel="noopener noreferrer"
>
{displayClasshash}
</a>
)}
{addressCopied ? (
<CheckCircleIcon
className="ml-1.5 text-xl font-normal text-sky-600 h-5 w-5 cursor-pointer"
aria-hidden="true"
/>
) : (
<CopyToClipboard
text={classHash}
onCopy={() => {
setAddressCopied(true);
setTimeout(() => {
setAddressCopied(false);
}, 800);
}}
>
<DocumentDuplicateIcon
className="ml-1.5 text-xl font-normal text-sky-600 h-5 w-5 cursor-pointer"
aria-hidden="true"
/>
</CopyToClipboard>
)}
</div>
);
};
4 changes: 4 additions & 0 deletions packages/nextjs/contracts/predeployedContracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ const preDeployedContracts = {
],
},
],
classHash: "0x046ded64ae2dead6448e247234bab192a9c483644395b66f2155f2614e5804b0",
},
Strk: {
address: universalStrkAddress,
Expand Down Expand Up @@ -421,6 +422,7 @@ const preDeployedContracts = {
],
},
],
classHash: "0x046ded64ae2dead6448e247234bab192a9c483644395b66f2155f2614e5804b0",
},
},
sepolia: {
Expand Down Expand Up @@ -680,6 +682,7 @@ const preDeployedContracts = {
],
},
],
classHash: "0x07f3777c99f3700505ea966676aac4a0d692c2a9f5e667f4c606b51ca1dd3420",
},
Strk: {
address: universalStrkAddress,
Expand Down Expand Up @@ -937,6 +940,7 @@ const preDeployedContracts = {
],
},
],
classHash: "0x04ad3c1dc8413453db314497945b6903e1c766495a1e60492d44da9c2a986e4b",
},
},
} as const;
Expand Down
2 changes: 2 additions & 0 deletions packages/nextjs/utils/scaffold-stark/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ export enum ContractCodeStatus {
export type GenericContract = {
address: Address;
abi: Abi;
classHash: String;
};

export type GenericContractsDeclaration = {
[network: string]: {
[contractName: string]: GenericContract;
Expand Down
20 changes: 20 additions & 0 deletions packages/nextjs/utils/scaffold-stark/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ export function getBlockExplorerAddressLink(
return `${blockExplorerBaseURL}/contract/${address}`;
}

/**
* Gives the block explorer URL for a given classhash.
* Defaults to Etherscan if no (wagmi) block explorer is configured for the network.
*/
export function getBlockExplorerClasshashLink(
network: chains.Chain,
address: string,
) {
const blockExplorerBaseURL = network.explorers?.starkscan[0];
if (network.network === chains.devnet.network) {
return `/blockexplorer/class/${address}`;
}

if (!blockExplorerBaseURL) {
return `https://starkscan.co/class/${address}`;
}

return `${blockExplorerBaseURL}/class/${address}`;
}

export function getBlockExplorerLink(network: chains.Chain) {
switch (network) {
case chains.mainnet:
Expand Down
8 changes: 3 additions & 5 deletions packages/snfoundry/scripts-ts/deploy-contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
import { DeployContractParams, Network } from "./types";
import { green, red, yellow } from "./helpers/colorize-log";


interface Arguments {
network: string;
reset: boolean;
Expand All @@ -34,7 +33,8 @@ const argv = yargs(process.argv.slice(2))
type: "boolean",
description: "Reset deployments",
default: false,
}).parseSync() as Arguments;;
})
.parseSync() as Arguments;

const networkName: string = argv.network;
const resetDeployments: boolean = argv.reset;
Expand Down Expand Up @@ -263,8 +263,6 @@ const loadExistingDeployments = () => {
return {};
};



const exportDeployments = () => {
const networkPath = path.resolve(
__dirname,
Expand Down Expand Up @@ -294,4 +292,4 @@ export {
exportDeployments,
executeDeployCalls,
resetDeployments,
};
};
3 changes: 1 addition & 2 deletions packages/snfoundry/scripts-ts/helpers/deploy-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ process.env.NETWORK = argv.network || "devnet";

// Set the RESET environment variable based on the --reset flag


// Execute the deploy script
execSync(
"cd contracts && scarb build && ts-node ../scripts-ts/deploy.ts" +
Expand All @@ -31,4 +30,4 @@ execSync(
" && ts-node ../scripts-ts/helpers/parse-deployments.ts" +
" && cd ..",
{ stdio: "inherit" }
);
);
5 changes: 3 additions & 2 deletions packages/snfoundry/scripts-ts/helpers/parse-deployments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ const generatedContractComment = `/**

const getContractDataFromDeployments = (): Record<
string,
Record<string, { address: string; abi: Abi }>
Record<string, { address: string; abi: Abi; classHash: string }>
> => {
const allContractsData: Record<
string,
Record<string, { address: string; abi: Abi }>
Record<string, { address: string; abi: Abi; classHash: string }>
> = {};

files.forEach((file) => {
Expand Down Expand Up @@ -49,6 +49,7 @@ const getContractDataFromDeployments = (): Record<
[contractName]: {
address: contractData.address,
abi: abiContent.abi.filter((item) => item.type !== "l1_handler"),
classHash: contractData.classHash,
},
};
} catch (e) {}
Expand Down
Loading