diff --git a/.changeset/funny-bobcats-explode.md b/.changeset/funny-bobcats-explode.md new file mode 100644 index 00000000000..44a1ca89c7a --- /dev/null +++ b/.changeset/funny-bobcats-explode.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Custom create2 factory deployment for skale chains diff --git a/packages/thirdweb/src/contract/deployment/utils/create-2-factory.test.ts b/packages/thirdweb/src/contract/deployment/utils/create-2-factory.test.ts new file mode 100644 index 00000000000..ad5d95d5830 --- /dev/null +++ b/packages/thirdweb/src/contract/deployment/utils/create-2-factory.test.ts @@ -0,0 +1,44 @@ +import { describe, expect, it } from "vitest"; +import { ANVIL_CHAIN } from "../../../../test/src/chains.js"; +import { TEST_CLIENT } from "../../../../test/src/test-clients.js"; +import { TEST_ACCOUNT_A } from "../../../../test/src/test-wallets.js"; +import { defineChain } from "../../../chains/utils.js"; +import { + computeCreate2FactoryAddress, + deployCreate2Factory, + getDeployedCreate2Factory, +} from "./create-2-factory.js"; + +describe.runIf(process.env.TW_SECRET_KEY)("create2 factory tests", () => { + it("should compute create2 factory address", async () => { + const addr = await computeCreate2FactoryAddress({ + client: TEST_CLIENT, + chain: defineChain(1), + }); + + expect(addr).to.eq("0x4e59b44847b379578588920cA78FbF26c0B4956C"); + }); + + it("should compute create2 factory address with custom gas", async () => { + const addr = await computeCreate2FactoryAddress({ + client: TEST_CLIENT, + chain: defineChain(1564830818), + }); + + expect(addr).to.eq("0x50620b64D9524aC7dC8c967123E87e5b6dB98f0c"); + }); + + it("should deploy create2 factory", async () => { + await deployCreate2Factory({ + client: TEST_CLIENT, + account: TEST_ACCOUNT_A, + chain: ANVIL_CHAIN, + }); + + const create2Factory = await getDeployedCreate2Factory({ + chain: ANVIL_CHAIN, + client: TEST_CLIENT, + }); + expect(create2Factory).not.toBeNull(); + }); +}); diff --git a/packages/thirdweb/src/contract/deployment/utils/create-2-factory.ts b/packages/thirdweb/src/contract/deployment/utils/create-2-factory.ts index 118d907d6a5..8a6f2d7c7d1 100644 --- a/packages/thirdweb/src/contract/deployment/utils/create-2-factory.ts +++ b/packages/thirdweb/src/contract/deployment/utils/create-2-factory.ts @@ -32,6 +32,13 @@ const SIGNATURE = { s: "0x2222222222222222222222222222222222222222222222222222222222222222", } as const; +type Create2FactoryDeploymentInfo = { + valueToSend: bigint; + predictedAddress: `0x${string}`; + signerAddress: string; + transaction: `0x${string}`; +}; + /** * Computes the address of the Create2 factory contract and checks if it is deployed. * @param options - The options for retrieving the Create2 factory address. @@ -155,15 +162,26 @@ export async function deployCreate2Factory(options: ClientAndChainAndAccount) { chain, }); - const gasPriceFetched = await getGasPrice(options); - const bin = _getNearestGasPriceBin(gasPriceFetched); + let gasPrice: bigint | undefined; + let gasLimit: bigint | undefined; + + if (CUSTOM_GAS_FOR_CHAIN[chainId]) { + gasPrice = CUSTOM_GAS_FOR_CHAIN[chainId.toString()]?.gasPrice; + gasLimit = CUSTOM_GAS_FOR_CHAIN[chainId.toString()]?.gasLimit; + } else { + const gasPriceFetched = await getGasPrice(options); + gasPrice = _getNearestGasPriceBin(gasPriceFetched); + } + const deploymentInfo = await _getCreate2FactoryDeploymentInfo(eipChain, { - gasPrice: bin, + gasPrice, + gasLimit, }); const balance = await eth_getBalance(rpcRequest, { address: deploymentInfo.signerAddress, }); + if (balance < deploymentInfo.valueToSend) { const transaction = prepareTransaction({ chain, @@ -193,7 +211,7 @@ export async function deployCreate2Factory(options: ClientAndChainAndAccount) { async function _getCreate2FactoryDeploymentInfo( chainId: number, gasOptions: { gasPrice?: bigint; gasLimit?: bigint }, -) { +): Promise { // 100000 is default deployment gas limit and 100 gwei is default gas price for create2 factory deployment // (See: https://github.com/Arachnid/deterministic-deployment-proxy?tab=readme-ov-file#deployment-gas-limit) const gasPrice = gasOptions.gasPrice ? gasOptions.gasPrice : 100n * 10n ** 9n; @@ -278,6 +296,23 @@ const CUSTOM_GAS_FOR_CHAIN: Record = { gasPrice: 2500n * 10n ** 9n, gasLimit: 200000n, }, + // SKALE chains + "1350216234": { + name: "Titan", + gasPrice: 110000n, + }, + "1482601649": { + name: "Nebula", + gasPrice: 110000n, + }, + "1564830818": { + name: "Calypso", + gasPrice: 110000n, + }, + "2046399126": { + name: "Europa", + gasPrice: 110000n, + }, }; const CUSTOM_GAS_BINS = [