Skip to content

Commit 0373104

Browse files
authored
Script for deploying prebuilts on a network (#424)
* script for deploying prebuilts on a network * update script
1 parent e42fb3c commit 0373104

File tree

6 files changed

+326
-48
lines changed

6 files changed

+326
-48
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"@openzeppelin/contracts": "4.7.3",
1616
"@openzeppelin/contracts-upgradeable": "4.7.3",
1717
"@primitivefi/hardhat-dodoc": "^0.2.0",
18-
"@thirdweb-dev/sdk": "3.10.20",
18+
"@thirdweb-dev/sdk": "3.10.33",
1919
"@typechain/ethers-v5": "^10.0.0",
2020
"@typechain/hardhat": "^4.0.0",
2121
"@types/fs-extra": "^9.0.13",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import "dotenv/config";
2+
import {
3+
ThirdwebSDK,
4+
computeCloneFactoryAddress,
5+
deployContractDeterministic,
6+
deployCreate2Factory,
7+
deployWithThrowawayDeployer,
8+
fetchAndCacheDeployMetadata,
9+
getCreate2FactoryAddress,
10+
getDeploymentInfo,
11+
getThirdwebContractAddress,
12+
isContractDeployed,
13+
resolveAddress,
14+
} from "@thirdweb-dev/sdk";
15+
import { Signer } from "ethers";
16+
import { apiMap, chainIdApiKey, contractsToDeploy } from "./constants";
17+
18+
////// To run this script: `npx ts-node scripts/deploy-prebuilt-deterministic/bootstrap-on-a-chain.ts` //////
19+
///// MAKE SURE TO PUT IN THE RIGHT CONTRACT NAME HERE AFTER PUBLISHING IT /////
20+
//// THE CONTRACT SHOULD BE PUBLISHED WITH THE NEW PUBLISH FLOW ////
21+
22+
const publisherKey: string = process.env.THIRDWEB_PUBLISHER_PRIVATE_KEY as string;
23+
const deployerKey: string = process.env.PRIVATE_KEY as string;
24+
25+
const polygonSDK = ThirdwebSDK.fromPrivateKey(publisherKey, "polygon");
26+
27+
const chainId = "8453"; // update here
28+
const networkName = "base"; // update here
29+
30+
async function main() {
31+
const publisher = await polygonSDK.wallet.getAddress();
32+
33+
const sdk = ThirdwebSDK.fromPrivateKey(deployerKey, chainId); // can also hardcode the chain here
34+
const signer = sdk.getSigner() as Signer;
35+
36+
console.log("balance: ", await sdk.wallet.balance());
37+
38+
// Deploy CREATE2 factory (if not already exists)
39+
const create2FactoryAddress = await getCreate2FactoryAddress(sdk.getProvider());
40+
if (await isContractDeployed(create2FactoryAddress, sdk.getProvider())) {
41+
console.log(`-- Create2 factory already present at ${create2FactoryAddress}\n`);
42+
} else {
43+
console.log(`-- Deploying Create2 factory at ${create2FactoryAddress}\n`);
44+
await deployCreate2Factory(signer, {});
45+
}
46+
47+
// TWStatelessFactory (Clone factory)
48+
const cloneFactoryAddress = await computeCloneFactoryAddress(sdk.getProvider(), sdk.storage, create2FactoryAddress);
49+
if (await isContractDeployed(cloneFactoryAddress, sdk.getProvider())) {
50+
console.log(`-- TWCloneFactory present at ${cloneFactoryAddress}\n`);
51+
}
52+
53+
for (const publishedContractName of contractsToDeploy) {
54+
const latest = await polygonSDK.getPublisher().getLatest(publisher, publishedContractName);
55+
56+
if (latest && latest.metadataUri) {
57+
const { extendedMetadata } = await fetchAndCacheDeployMetadata(latest?.metadataUri, polygonSDK.storage);
58+
59+
const isNetworkEnabled =
60+
extendedMetadata?.networksForDeployment?.networksEnabled.includes(parseInt(chainId)) ||
61+
extendedMetadata?.networksForDeployment?.allNetworks;
62+
63+
if (extendedMetadata?.networksForDeployment && !isNetworkEnabled) {
64+
console.log(`Deployment of ${publishedContractName} disabled on ${networkName}\n`);
65+
continue;
66+
}
67+
68+
console.log(`Deploying ${publishedContractName} on ${networkName}`);
69+
70+
// const chainId = (await sdk.getProvider().getNetwork()).chainId;
71+
72+
try {
73+
const implAddr = await getThirdwebContractAddress(publishedContractName, parseInt(chainId), sdk.storage);
74+
if (implAddr) {
75+
console.log(`implementation ${implAddr} already deployed on chainId: ${chainId}`);
76+
console.log();
77+
continue;
78+
}
79+
} catch (error) {}
80+
81+
try {
82+
// any evm deployment flow
83+
84+
// get deployment info for any evm
85+
const deploymentInfo = await getDeploymentInfo(
86+
latest.metadataUri,
87+
sdk.storage,
88+
sdk.getProvider(),
89+
create2FactoryAddress,
90+
);
91+
92+
const implementationAddress = deploymentInfo.find(i => i.type === "implementation")?.transaction
93+
.predictedAddress as string;
94+
95+
const isDeployed = await isContractDeployed(implementationAddress, sdk.getProvider());
96+
if (isDeployed) {
97+
console.log(`implementation ${implementationAddress} already deployed on chainId: ${chainId}`);
98+
console.log();
99+
continue;
100+
}
101+
102+
console.log("Deploying as", await signer?.getAddress());
103+
// filter out already deployed contracts (data is empty)
104+
const transactionsToSend = deploymentInfo.filter(i => i.transaction.data && i.transaction.data.length > 0);
105+
const transactionsforDirectDeploy = transactionsToSend
106+
.filter(i => {
107+
return i.type !== "infra";
108+
})
109+
.map(i => i.transaction);
110+
const transactionsForThrowawayDeployer = transactionsToSend
111+
.filter(i => {
112+
return i.type === "infra";
113+
})
114+
.map(i => i.transaction);
115+
116+
// deploy via throwaway deployer, multiple infra contracts in one transaction
117+
if (transactionsForThrowawayDeployer.length > 0) {
118+
console.log("-- Deploying Infra");
119+
await deployWithThrowawayDeployer(signer, transactionsForThrowawayDeployer, {});
120+
}
121+
122+
const resolvedImplementationAddress = await resolveAddress(implementationAddress);
123+
124+
console.log(`-- Deploying ${publishedContractName} at ${resolvedImplementationAddress}`);
125+
// send each transaction directly to Create2 factory
126+
await Promise.all(
127+
transactionsforDirectDeploy.map(tx => {
128+
return deployContractDeterministic(signer, tx, {});
129+
}),
130+
);
131+
console.log();
132+
} catch (e) {
133+
console.log("Error while deploying: ", e);
134+
console.log();
135+
continue;
136+
}
137+
} else {
138+
console.log("No previous release found");
139+
return;
140+
}
141+
}
142+
143+
console.log("Deployments done.");
144+
console.log();
145+
146+
console.log("---------- Verification ---------");
147+
console.log();
148+
for (const publishedContractName of contractsToDeploy) {
149+
try {
150+
await sdk.verifier.verifyThirdwebContract(
151+
publishedContractName,
152+
apiMap[parseInt(chainId)],
153+
chainIdApiKey[parseInt(chainId)] as string,
154+
);
155+
console.log();
156+
} catch (error) {
157+
console.log(error);
158+
console.log();
159+
}
160+
}
161+
162+
console.log("All done.");
163+
}
164+
165+
main()
166+
.then(() => process.exit(0))
167+
.catch(e => {
168+
console.error(e);
169+
process.exit(1);
170+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
2+
3+
import { apiMap, chainIdApiKey, contractsToDeploy } from "./constants";
4+
5+
////// To run this script: `npx ts-node scripts/deploy-prebuilt-deterministic/bootstrap-verify.ts` //////
6+
const chainId = "8453"; // update here
7+
8+
async function main() {
9+
console.log("---------- Verification ---------");
10+
console.log();
11+
12+
const sdk = new ThirdwebSDK(chainId);
13+
for (const publishedContractName of contractsToDeploy) {
14+
try {
15+
await sdk.verifier.verifyThirdwebContract(
16+
publishedContractName,
17+
apiMap[parseInt(chainId)],
18+
chainIdApiKey[parseInt(chainId)] as string,
19+
);
20+
console.log();
21+
} catch (error) {
22+
console.log(error);
23+
console.log();
24+
}
25+
}
26+
27+
console.log("All done.");
28+
}
29+
30+
main()
31+
.then(() => process.exit(0))
32+
.catch(e => {
33+
console.error(e);
34+
process.exit(1);
35+
});

scripts/deploy-prebuilt-deterministic/constants.ts

+31
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export const chainIdToName: Record<number, string> = {
1818
[ChainId.AvalancheFujiTestnet]: "avalanche-testnet",
1919
[ChainId.BinanceSmartChainMainnet]: "binance",
2020
[ChainId.BinanceSmartChainTestnet]: "binance-testnet",
21+
[84531]: "base-goerli",
22+
[8453]: "base",
2123
};
2224

2325
export const chainIdApiKey: Record<number, string | undefined> = {
@@ -35,6 +37,8 @@ export const chainIdApiKey: Record<number, string | undefined> = {
3537
[ChainId.AvalancheFujiTestnet]: process.env.SNOWTRACE_API_KEY || process.env.SCAN_API_KEY,
3638
[ChainId.BinanceSmartChainMainnet]: process.env.BINANCE_SCAN_API_KEY || process.env.SCAN_API_KEY,
3739
[ChainId.BinanceSmartChainTestnet]: process.env.BINANCE_SCAN_API_KEY || process.env.SCAN_API_KEY,
40+
[84531]: "" as string,
41+
[8453]: process.env.BASE_SCAN_API_KEY || process.env.SCAN_API_KEY,
3842
};
3943

4044
export const apiMap: Record<number, string> = {
@@ -52,4 +56,31 @@ export const apiMap: Record<number, string> = {
5256
43114: "https://api.snowtrace.io/api",
5357
421613: "https://api-goerli.arbiscan.io/api",
5458
80001: "https://api-testnet.polygonscan.com/api",
59+
84531: "https://api-goerli.basescan.org/api",
60+
8453: "https://api.basescan.org/api",
5561
};
62+
63+
export const contractsToDeploy = [
64+
"OpenEditionERC721",
65+
"DropERC721",
66+
"DropERC1155",
67+
"DropERC20",
68+
"TokenERC20",
69+
"TokenERC721",
70+
"TokenERC1155",
71+
"Split",
72+
"VoteERC20",
73+
"NFTStake",
74+
"TokenStake",
75+
"EditionStake",
76+
"AirdropERC20",
77+
"AirdropERC721",
78+
"AirdropERC1155",
79+
"DirectListingsLogic",
80+
"EnglishAuctionsLogic",
81+
"OffersLogic",
82+
"MarketplaceV3",
83+
// "Forwarder",
84+
// "TWCloneFactory",
85+
// "PluginMap",
86+
];

scripts/deploy-prebuilt-deterministic/verify.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ThirdwebSDK } from "@thirdweb-dev/sdk";
22

33
import { apiMap, chainIdApiKey, chainIdToName } from "./constants";
44

5-
////// To run this script: `npx ts-node scripts/deploy-new-flow/verify.ts` //////
5+
////// To run this script: `npx ts-node scripts/deploy-prebuilt-deterministic/verify.ts` //////
66
const deployedContractName = "VoteERC20";
77

88
async function main() {

0 commit comments

Comments
 (0)