Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/hardhat/.env.example
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
DEPLOYER_PRIVATE_KEY=FILL_IN_PRIVATE_KEY

VERIFY=true
IGNORE_FILFOX=false
IGNORE_BLOCKSCOUT=false
6 changes: 6 additions & 0 deletions packages/hardhat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ For contracts deployed on Filecoin mainnet or Filecoin testnet (calibration) usi
```shell
npx hardhat verify-contract --network $networkName --contract-name $contractName
```

### enviroment variables

VERIFY=true // Allows the deployment script to verify
IGNORE_FILFOX=true // Ignores the verification in the filfox explorer
IGNORE_BLOCKSCOUT=true // Ignores the verification on the Blockscout explorer
42 changes: 30 additions & 12 deletions packages/hardhat/deploy/00_deal_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
*
* @param hre HardhatRuntimeEnvironment object.
*/
const deployDealClient: DeployFunction = async function (
hre: HardhatRuntimeEnvironment
) {
const deployDealClient: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
/*
On localhost, the deployer account is the one that comes with Hardhat, which is already funded.

Expand All @@ -25,10 +23,12 @@ const deployDealClient: DeployFunction = async function (

const { deploy } = hre.deployments;

const args = [] as any;

const DealClient = await deploy("DealClient", {
from: deployer,
// Contract constructor arguments
args: [],
args,
log: true,
// autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
// automatically mining the contract deployment transaction. There is no effect on live networks.
Expand All @@ -41,21 +41,39 @@ const deployDealClient: DeployFunction = async function (

// Check if the --verify flag is present
const shouldVerify = process.env.VERIFY === "true";
const ignoreFilfox = process.env.IGNORE_FILFOX === "true";
const ignoreBlockscout = process.env.IGNORE_BLOCKSCOUT === "true";

if (shouldVerify) {
// Wait for 15 seconds to make sure the contract is deployed
console.log("🕵️‍♂️ Waiting for 15 seconds to make sure the contract deployment is reflected on the explorer...");
await new Promise(resolve => setTimeout(resolve, 15000));
console.log("🕵️‍♂️ Verifying the contract on the explorer...");

const filecoinNetworks = ["calibration", "filecoin"];
if (filecoinNetworks.includes(hre.network.name)) {
// Verify the contract on the filfox explorer
await hre.run("verify-contract", {
contractName: "DealClient",
});
} else {
await hre.run("verify:verify", {
address: DealClientAddress,
constructorArguments: [deployer],
});
if (!ignoreFilfox) {
await hre.run("verify-contract", {
contractName: "DealClient",
});
}
}
if (!ignoreBlockscout) {
try {
await hre.run("verify:verify", {
address: DealClientAddress,
constructorArguments: args,
force: true,
});
} catch (error) {
console.error("Error verifying contract with force:", error);
console.log("🕵️‍♂️ Verifying the contract on the explorer without forcing verification...");
await hre.run("verify:verify", {
address: DealClientAddress,
constructorArguments: args,
});
}
}
}
};
Expand Down
45 changes: 29 additions & 16 deletions packages/hardhat/deploy/01_deal_info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
*
* @param hre HardhatRuntimeEnvironment object.
*/
const deployDealInfo: DeployFunction = async function (
hre: HardhatRuntimeEnvironment
) {
const deployDealInfo: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
/*
On localhost, the deployer account is the one that comes with Hardhat, which is already funded.

Expand All @@ -25,10 +23,12 @@ const deployDealInfo: DeployFunction = async function (

const { deploy } = hre.deployments;

const args = [] as any;

const DealInfo = await deploy("DealInfo", {
from: deployer,
// Contract constructor arguments
args: [],
args,
log: true,
// autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
// automatically mining the contract deployment transaction. There is no effect on live networks.
Expand All @@ -40,27 +40,40 @@ const deployDealInfo: DeployFunction = async function (

// Check if the --verify flag is present
const shouldVerify = process.env.VERIFY === "true";
const ignoreFilfox = process.env.IGNORE_FILFOX === "true";
const ignoreBlockscout = process.env.IGNORE_BLOCKSCOUT === "true";

if (shouldVerify) {
// Timeout for 10 Seconds to wait for the contract to be indexed on explorer
console.log(
"⏳ Waiting for 10 seconds for the contract to be indexed on the explorer..."
);
await new Promise((resolve) => setTimeout(resolve, 10000));
console.log("⏳ Waiting for 15 seconds for the contract to be indexed on the explorer...");
await new Promise(resolve => setTimeout(resolve, 15000));

console.log("🕵️‍♂️ Verifying the contract on the explorer...");

const filecoinNetworks = ["calibration", "filecoin"];
if (filecoinNetworks.includes(hre.network.name)) {
// Verify the contract on the filfox explorer
await hre.run("verify-contract", {
contractName: "DealInfo",
});
} else {
await hre.run("verify:verify", {
address: DealInfoAddress,
constructorArguments: [deployer],
});
if (!ignoreFilfox) {
await hre.run("verify-contract", {
contractName: "DealInfo",
});
}
}
if (!ignoreBlockscout) {
try {
await hre.run("verify:verify", {
address: DealInfoAddress,
constructorArguments: args,
force: true,
});
} catch (error) {
console.error("Error verifying contract with force:", error);
console.log("🕵️‍♂️ Verifying the contract on the explorer without forcing verification...");
await hre.run("verify:verify", {
address: DealInfoAddress,
constructorArguments: args,
});
}
}
}
};
Expand Down
76 changes: 21 additions & 55 deletions packages/hardhat/deploy/99_generateTsAbis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
* These definitions are used to derive the types needed in the custom fil-frame hooks, for example.
* This script should run as the last deploy script.
*/

Check warning on line 8 in packages/hardhat/deploy/99_generateTsAbis.ts

View workflow job for this annotation

GitHub Actions / ci (ubuntu-latest, lts/*)

Delete `⏎`

Check warning on line 8 in packages/hardhat/deploy/99_generateTsAbis.ts

View workflow job for this annotation

GitHub Actions / ci (ubuntu-latest, lts/*)

Delete `⏎`
import * as fs from "fs";
import prettier from "prettier";
import { DeployFunction } from "hardhat-deploy/types";
import prettier from "prettier";

const generatedContractComment = `
/**
Expand All @@ -23,21 +23,18 @@
function getDirectories(path: string) {
return fs
.readdirSync(path, { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name);
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name);
}

function getContractNames(path: string) {
return fs
.readdirSync(path, { withFileTypes: true })
.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".json"))
.map((dirent) => dirent.name.split(".")[0]);
.filter(dirent => dirent.isFile() && dirent.name.endsWith(".json"))
.map(dirent => dirent.name.split(".")[0]);
}

function getActualSourcesForContract(
sources: Record<string, any>,
contractName: string
) {
function getActualSourcesForContract(sources: Record<string, any>, contractName: string) {
for (const sourcePath of Object.keys(sources)) {
const sourceName = sourcePath.split("/").pop()?.split(".sol")[0];
if (sourceName === contractName) {
Expand All @@ -48,9 +45,7 @@
if (match) {
const inheritancePart = match[2];
// Split the inherited contracts by commas to get the list of inherited contracts
const inheritedContracts = inheritancePart
.split(",")
.map((contract) => `${contract.trim()}.sol`);
const inheritedContracts = inheritancePart.split(",").map(contract => `${contract.trim()}.sol`);

return inheritedContracts;
}
Expand All @@ -60,24 +55,15 @@
return [];
}

function getInheritedFunctions(
sources: Record<string, any>,
contractName: string
) {
function getInheritedFunctions(sources: Record<string, any>, contractName: string) {
const actualSources = getActualSourcesForContract(sources, contractName);
const inheritedFunctions = {} as Record<string, any>;

for (const sourceContractName of actualSources) {
const sourcePath = Object.keys(sources).find((key) =>
key.includes(`/${sourceContractName}`)
);
const sourcePath = Object.keys(sources).find(key => key.includes(`/${sourceContractName}`));
if (sourcePath) {
const sourceName = sourcePath?.split("/").pop()?.split(".sol")[0];
const { abi } = JSON.parse(
fs
.readFileSync(`${ARTIFACTS_DIR}/${sourcePath}/${sourceName}.json`)
.toString()
);
const { abi } = JSON.parse(fs.readFileSync(`${ARTIFACTS_DIR}/${sourcePath}/${sourceName}.json`).toString());
for (const functionAbi of abi) {
if (functionAbi.type === "function") {
inheritedFunctions[functionAbi.name] = sourcePath;
Expand All @@ -91,28 +77,17 @@

function getContractDataFromDeployments() {
if (!fs.existsSync(DEPLOYMENTS_DIR)) {
throw Error(
"At least one other deployment script should exist to generate an actual contract."
);
throw Error("At least one other deployment script should exist to generate an actual contract.");
}
const output = {} as Record<string, any>;
for (const chainName of getDirectories(DEPLOYMENTS_DIR)) {
const chainId = fs
.readFileSync(`${DEPLOYMENTS_DIR}/${chainName}/.chainId`)
.toString();
const chainId = fs.readFileSync(`${DEPLOYMENTS_DIR}/${chainName}/.chainId`).toString();
const contracts = {} as Record<string, any>;
for (const contractName of getContractNames(
`${DEPLOYMENTS_DIR}/${chainName}`
)) {
for (const contractName of getContractNames(`${DEPLOYMENTS_DIR}/${chainName}`)) {
const { abi, address, metadata } = JSON.parse(
fs
.readFileSync(`${DEPLOYMENTS_DIR}/${chainName}/${contractName}.json`)
.toString()
);
const inheritedFunctions = getInheritedFunctions(
JSON.parse(metadata).sources,
contractName
fs.readFileSync(`${DEPLOYMENTS_DIR}/${chainName}/${contractName}.json`).toString(),
);
const inheritedFunctions = getInheritedFunctions(JSON.parse(metadata).sources, contractName);
contracts[contractName] = { address, abi, inheritedFunctions };
}
output[chainId] = contracts;
Expand All @@ -128,16 +103,9 @@
const TARGET_DIR = "../nextjs/contracts/";
const allContractsData = getContractDataFromDeployments();

const fileContent = Object.entries(allContractsData).reduce(
(content, [chainId, chainConfig]) => {
return `${content}${parseInt(chainId).toFixed(0)}:${JSON.stringify(
chainConfig,
null,
2
)},`;
},
""
);
const fileContent = Object.entries(allContractsData).reduce((content, [chainId, chainConfig]) => {
return `${content}${parseInt(chainId).toFixed(0)}:${JSON.stringify(chainConfig, null, 2)},`;
}, "");

if (!fs.existsSync(TARGET_DIR)) {
fs.mkdirSync(TARGET_DIR);
Expand All @@ -149,13 +117,11 @@
const deployedContracts = {${fileContent}} as const; \n\n export default deployedContracts satisfies GenericContractsDeclaration`,
{
parser: "typescript",
}
)
},
),
);

console.log(
`📝 Updated TypeScript contract definition file on ${TARGET_DIR}deployedContracts.ts`
);
console.log(`📝 Updated TypeScript contract definition file on ${TARGET_DIR}deployedContracts.ts`);
};

export default generateTsAbis;
Expand Down
Loading
Loading