From c8e366c5e4fbfeed49a0b3e3230fbec37d5b17f1 Mon Sep 17 00:00:00 2001 From: Lindsay Gilbert Date: Mon, 8 Jun 2026 15:37:29 -0400 Subject: [PATCH 1/2] add shape network support --- packages/contracts/.env.example | 4 +- packages/contracts/INFRASTRUCTURE.md | 44 ++++++++++++++----- packages/contracts/hardhat.config.ts | 19 ++++++++ packages/contracts/package.json | 6 +++ .../contracts/scripts/create2-deploy/index.ts | 5 +++ .../factory/post-engine-factory-deployment.ts | 16 ++++--- .../V3/post-batch-create-engine-contracts.ts | 12 ++--- .../shared-minters-deployer.ts | 11 +++-- .../shared-minter-filter-deployer.ts | 11 +++-- .../shared-randomizer-deployer.ts | 11 +++-- packages/contracts/scripts/util/aws_s3.ts | 2 +- packages/contracts/scripts/util/constants.ts | 21 +++++++-- packages/contracts/scripts/util/utils.ts | 20 +++++++++ 13 files changed, 143 insertions(+), 39 deletions(-) diff --git a/packages/contracts/.env.example b/packages/contracts/.env.example index 074f41b2b..b1fcad970 100644 --- a/packages/contracts/.env.example +++ b/packages/contracts/.env.example @@ -10,7 +10,7 @@ PROD_AWS_ACCESS_KEY_ID= PROD_AWS_SECRET_ACCESS_KEY= # The following are only required if using Art Blocks Deployment Scripts # Three Hasura environments: dev, staging, prod -# prod serves all mainnets (ethereum, base, arbitrum) distinguished by chain_id +# prod serves all mainnets (ethereum, base, arbitrum, shape) distinguished by chain_id GRAPHQL_API_ENDPOINT_DEV= HASURA_ADMIN_SECRET_DEV= GRAPHQL_API_ENDPOINT_STAGING= @@ -27,5 +27,7 @@ ARBITRUM_GOERLI_JSON_RPC_PROVIDER_URL= # The following is only required if deploying on Base BASESCAN_API_KEY= BASE_MAINNET_JSON_RPC_PROVIDER_URL= +# The following is only required if deploying on Shape mainnet (chain ID 360) +SHAPE_MAINNET_JSON_RPC_PROVIDER_URL= # The following is only required if deploying on Hoodi testnet HOODI_JSON_RPC_PROVIDER_URL= \ No newline at end of file diff --git a/packages/contracts/INFRASTRUCTURE.md b/packages/contracts/INFRASTRUCTURE.md index b945c2abc..860b9b132 100644 --- a/packages/contracts/INFRASTRUCTURE.md +++ b/packages/contracts/INFRASTRUCTURE.md @@ -95,6 +95,30 @@ erDiagram } ``` +### Shape + +```mermaid +--- +title: Shape setup (mainnet, chain ID 360) +--- +erDiagram + DeployerMultisig ||--|| EngineFactory : owns + EngineFactory ||--|| CoreRegistry : owns + EngineFactory ||--|| UniversalBytecodeStorageReader : initializes-cores-with + DeployerMultisig { + addr _TBD + } + EngineFactory { + addr _TBD + } + CoreRegistry { + addr _TBD + } + UniversalBytecodeStorageReader { + addr _TBD + } +``` + ### Sepolia (artist staging) ```mermaid @@ -168,14 +192,14 @@ The following contracts were deployed by Art Blocks on various production networ They are included here for reference purposes. -| Contract/Library (network:Contract) | Address | -| --------------------------------------- | -------------------------------------------- | -| mainnet:EngineFactory (v3.2.4, v3.2.5) | `0x00000000D0A0E78e243625Dbb4A5B37286Eac629` | -| arbitrum:EngineFactory (v3.2.4, v3.2.5) | `0x000000D60eeC180eDC00001173dE37ACd269b196` | -| base:EngineFactory (v3.2.4, v3.2.5) | `0x0000000005aBb84fF93f599a6309cA71a6DD4e4E` | +| Contract/Library (network:Contract) | Address | +| ---------------------------------------------- | -------------------------------------------- | +| mainnet:EngineFactory (v3.2.4, v3.2.5) | `0x00000000D0A0E78e243625Dbb4A5B37286Eac629` | +| arbitrum:EngineFactory (v3.2.4, v3.2.5) | `0x000000D60eeC180eDC00001173dE37ACd269b196` | +| base:EngineFactory (v3.2.4, v3.2.5) | `0x0000000005aBb84fF93f599a6309cA71a6DD4e4E` | | sepolia-staging:EngineFactory (v3.2.4, v3.2.5) | `0x000000ab19F142143f03f96E2Bdf068474E50b7D` | -| sepolia-dev:EngineFactory (v3.2.4, v3.2.5) | `0x0000000765f79939e1Abb63C266cE983bd5eF5c0` | -| mainnet:EngineFactory (v3.2.2, v3.2.3) | `0x000000AB1a0786eE8c71516d9AbB8a36fbdDb7CB` | -| arbitrum:EngineFactory (v3.2.2, v3.2.3) | `0x000000da9D51CC51a50Dc296246075859b13ab0B` | -| mainnet:EngineFactory (v3.2.0, v3.2.1) | `0x00000000F82E4e6D5AB22D63050FCb2bF15eE95d` | -| arbitrum:EngineFactory (v3.2.0, v3.2.1) | `0x000000bbAA3E36b60C06A92430D8956459c2Fd51` | +| sepolia-dev:EngineFactory (v3.2.4, v3.2.5) | `0x0000000765f79939e1Abb63C266cE983bd5eF5c0` | +| mainnet:EngineFactory (v3.2.2, v3.2.3) | `0x000000AB1a0786eE8c71516d9AbB8a36fbdDb7CB` | +| arbitrum:EngineFactory (v3.2.2, v3.2.3) | `0x000000da9D51CC51a50Dc296246075859b13ab0B` | +| mainnet:EngineFactory (v3.2.0, v3.2.1) | `0x00000000F82E4e6D5AB22D63050FCb2bF15eE95d` | +| arbitrum:EngineFactory (v3.2.0, v3.2.1) | `0x000000bbAA3E36b60C06A92430D8956459c2Fd51` | diff --git a/packages/contracts/hardhat.config.ts b/packages/contracts/hardhat.config.ts index e7034da3a..ca8498719 100644 --- a/packages/contracts/hardhat.config.ts +++ b/packages/contracts/hardhat.config.ts @@ -46,6 +46,9 @@ const ARBITRUM_MAINNET_JSON_RPC_PROVIDER_URL = const BASE_MAINNET_JSON_RPC_PROVIDER_URL = process.env.BASE_MAINNET_JSON_RPC_PROVIDER_URL || ""; +const SHAPE_MAINNET_JSON_RPC_PROVIDER_URL = + process.env.SHAPE_MAINNET_JSON_RPC_PROVIDER_URL || ""; + const HOODI_JSON_RPC_PROVIDER_URL = process.env.HOODI_JSON_RPC_PROVIDER_URL || ""; @@ -95,6 +98,14 @@ module.exports = { gasMultiplier: 1.5, maxNominalGasPriceGwei: 50, }, + shape: { + url: SHAPE_MAINNET_JSON_RPC_PROVIDER_URL, + accounts: [`${PRIVATE_KEY}`], + // ledgerAccounts: ["0x"], + gasPrice: "auto", + gasMultiplier: 1.5, + maxNominalGasPriceGwei: 50, + }, hoodi: { url: HOODI_JSON_RPC_PROVIDER_URL, accounts: [`${PRIVATE_KEY}`], @@ -127,6 +138,14 @@ module.exports = { browserURL: "https://hoodi.etherscan.io", }, }, + { + network: "shape", + chainId: 360, + urls: { + apiURL: "https://shapescan.xyz/api", + browserURL: "https://shapescan.xyz", + }, + }, ], }, contractSizer: { diff --git a/packages/contracts/package.json b/packages/contracts/package.json index c55d8788b..1449f77c4 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -33,29 +33,35 @@ "deploy:v3-engine:arbitrum:txbuilder": "yarn codegen && yarn require-low-gas arbitrum && NODE_ENV=prod EXPORT_TX_BUILDER=true yarn hardhat run --network arbitrum scripts/engine/V3/batch-create-engine-contracts.ts", "deploy:v3-engine:base": "yarn codegen && yarn require-low-gas base && NODE_ENV=prod yarn hardhat run --network base scripts/engine/V3/batch-create-engine-contracts.ts", "deploy:v3-engine:base:txbuilder": "yarn codegen && yarn require-low-gas base && NODE_ENV=prod EXPORT_TX_BUILDER=true yarn hardhat run --network base scripts/engine/V3/batch-create-engine-contracts.ts", + "deploy:v3-engine:shape": "yarn codegen && yarn require-low-gas shape && NODE_ENV=prod yarn hardhat run --network shape scripts/engine/V3/batch-create-engine-contracts.ts", + "deploy:v3-engine:shape:txbuilder": "yarn codegen && yarn require-low-gas shape && NODE_ENV=prod EXPORT_TX_BUILDER=true yarn hardhat run --network shape scripts/engine/V3/batch-create-engine-contracts.ts", "post-deploy:v3-engine:dev": "yarn codegen && yarn require-low-gas sepolia && NODE_ENV=dev yarn hardhat run --network sepolia scripts/engine/V3/post-batch-create-engine-contracts.ts", "post-deploy:v3-engine:staging": "yarn codegen && yarn require-low-gas sepolia && NODE_ENV=staging yarn hardhat run --network sepolia scripts/engine/V3/post-batch-create-engine-contracts.ts", "post-deploy:v3-engine:mainnet": "yarn codegen && yarn require-low-gas mainnet && NODE_ENV=prod yarn hardhat run --network mainnet scripts/engine/V3/post-batch-create-engine-contracts.ts", "post-deploy:v3-engine:arbitrum": "yarn codegen && yarn require-low-gas arbitrum && NODE_ENV=prod yarn hardhat run --network arbitrum scripts/engine/V3/post-batch-create-engine-contracts.ts", "post-deploy:v3-engine:base": "yarn codegen && yarn require-low-gas base && NODE_ENV=prod yarn hardhat run --network base scripts/engine/V3/post-batch-create-engine-contracts.ts", + "post-deploy:v3-engine:shape": "yarn codegen && yarn require-low-gas shape && NODE_ENV=prod yarn hardhat run --network shape scripts/engine/V3/post-batch-create-engine-contracts.ts", "deploy:shared-randomizer:goerli": "yarn require-low-gas goerli && yarn hardhat run --network goerli scripts/randomizer-deployments/shared-randomizer-deployer.ts", "deploy:shared-randomizer:dev-sepolia": "yarn require-low-gas sepolia && NODE_ENV=dev yarn hardhat run --network sepolia scripts/randomizer-deployments/shared-randomizer-deployer.ts", "deploy:shared-randomizer:mainnet": "yarn require-low-gas mainnet && yarn hardhat run --network mainnet scripts/randomizer-deployments/shared-randomizer-deployer.ts", "deploy:shared-randomizer:arbitrum-goerli": "yarn require-low-gas arbitrum-goerli && yarn hardhat run --network arbitrum-goerli scripts/randomizer-deployments/shared-randomizer-deployer.ts", "deploy:shared-randomizer:arbitrum": "yarn require-low-gas arbitrum && yarn hardhat run --network arbitrum scripts/randomizer-deployments/shared-randomizer-deployer.ts", "deploy:shared-randomizer:base": "yarn require-low-gas base && yarn hardhat run --network base scripts/randomizer-deployments/shared-randomizer-deployer.ts", + "deploy:shared-randomizer:shape": "yarn require-low-gas shape && yarn hardhat run --network shape scripts/randomizer-deployments/shared-randomizer-deployer.ts", "deploy:shared-minter-filter:goerli": "yarn require-low-gas goerli && yarn hardhat run --network goerli scripts/minter-filter-deployments/shared-minter-filter-deployer.ts", "deploy:shared-minter-filter:dev-sepolia": "yarn require-low-gas sepolia && NODE_ENV=dev yarn hardhat run --network sepolia scripts/minter-filter-deployments/shared-minter-filter-deployer.ts", "deploy:shared-minter-filter:mainnet": "yarn require-low-gas mainnet && yarn hardhat run --network mainnet scripts/minter-filter-deployments/shared-minter-filter-deployer.ts", "deploy:shared-minter-filter:arbitrum-goerli": "yarn require-low-gas arbitrum-goerli && yarn hardhat run --network arbitrum-goerli scripts/minter-filter-deployments/shared-minter-filter-deployer.ts", "deploy:shared-minter-filter:arbitrum": "yarn require-low-gas arbitrum && yarn hardhat run --network arbitrum scripts/minter-filter-deployments/shared-minter-filter-deployer.ts", "deploy:shared-minter-filter:base": "yarn require-low-gas base && yarn hardhat run --network base scripts/minter-filter-deployments/shared-minter-filter-deployer.ts", + "deploy:shared-minter-filter:shape": "yarn require-low-gas shape && yarn hardhat run --network shape scripts/minter-filter-deployments/shared-minter-filter-deployer.ts", "deploy:shared-minters:goerli": "yarn require-low-gas goerli && yarn hardhat run --network goerli scripts/minter-deployments/shared-minters-deployer.ts", "deploy:shared-minters:sepolia": "yarn require-low-gas sepolia && yarn hardhat run --network sepolia scripts/minter-deployments/shared-minters-deployer.ts", "deploy:shared-minters:mainnet": "yarn require-low-gas mainnet && yarn hardhat run --network mainnet scripts/minter-deployments/shared-minters-deployer.ts", "deploy:shared-minters:arbitrum-goerli": "yarn require-low-gas arbitrum-goerli && yarn hardhat run --network arbitrum-goerli scripts/minter-deployments/shared-minters-deployer.ts", "deploy:shared-minters:arbitrum": "yarn require-low-gas arbitrum && yarn hardhat run --network arbitrum scripts/minter-deployments/shared-minters-deployer.ts", "deploy:shared-minters:base": "yarn require-low-gas base && yarn hardhat run --network base scripts/minter-deployments/shared-minters-deployer.ts", + "deploy:shared-minters:shape": "yarn require-low-gas shape && yarn hardhat run --network shape scripts/minter-deployments/shared-minters-deployer.ts", "deploy:splits-factory:dev": "yarn require-low-gas sepolia && NODE_ENV=dev yarn hardhat run --network sepolia scripts/splits/splits-factory-deployer.ts", "deploy:splits-factory:staging": "yarn require-low-gas sepolia && NODE_ENV=staging yarn hardhat run --network sepolia scripts/splits/splits-factory-deployer.ts", "deploy:splits-factory:mainnet": "yarn require-low-gas mainnet && NODE_ENV=prod yarn hardhat run --network mainnet scripts/splits/splits-factory-deployer.ts", diff --git a/packages/contracts/scripts/create2-deploy/index.ts b/packages/contracts/scripts/create2-deploy/index.ts index d296a545d..0b47f0998 100644 --- a/packages/contracts/scripts/create2-deploy/index.ts +++ b/packages/contracts/scripts/create2-deploy/index.ts @@ -32,6 +32,11 @@ const CHAIN_CONFIG: Record< network: "base", explorer: "https://basescan.org", }, + 360: { + name: "Shape", + network: "shape", + explorer: "https://shapescan.xyz", + }, 11155111: { name: "Sepolia", network: "sepolia", diff --git a/packages/contracts/scripts/engine/V3/factory/post-engine-factory-deployment.ts b/packages/contracts/scripts/engine/V3/factory/post-engine-factory-deployment.ts index d612ce268..5cb3f2db6 100644 --- a/packages/contracts/scripts/engine/V3/factory/post-engine-factory-deployment.ts +++ b/packages/contracts/scripts/engine/V3/factory/post-engine-factory-deployment.ts @@ -10,7 +10,12 @@ import { Logger } from "@ethersproject/logger"; Logger.setLogLevel(Logger.levels.ERROR); // delay to avoid issues with reorgs and tx failures -import { delay, getAppPath, getNetworkName } from "../../../util/utils"; +import { + delay, + getAppPath, + getNetworkName, + getBlockExplorerAddressUrl, +} from "../../../util/utils"; import { getActiveCoreRegistry, EXTRA_DELAY_BETWEEN_TX, @@ -84,7 +89,6 @@ async function main() { `deployments/engine/V3/studio/${config.environment}` ); const outputSummaryFile = path.join(outputPath, "DEPLOYMENTS.md"); - const etherscanSubdomain = networkName === "mainnet" ? "" : `${networkName}.`; const outputMd = ` # Engine Factory Deployment @@ -94,13 +98,13 @@ Date: ${new Date().toISOString()} ## **Environment:** ${config.environment} -**Engine Implementation:** https://${etherscanSubdomain}etherscan.io/address/${activeEngineImplementationAddress}#code +**Engine Implementation:** ${getBlockExplorerAddressUrl(networkName, activeEngineImplementationAddress)} -**Engine Flex Implementation:** https://${etherscanSubdomain}etherscan.io/address/${activeEngineFlexImplementationAddress}#code +**Engine Flex Implementation:** ${getBlockExplorerAddressUrl(networkName, activeEngineFlexImplementationAddress)} -**Engine Factory:** https://${etherscanSubdomain}etherscan.io/address/${engineFactoryAddress}#code +**Engine Factory:** ${getBlockExplorerAddressUrl(networkName, engineFactoryAddress)} -**Core Registry:** https://${etherscanSubdomain}etherscan.io/address/${coreRegistryAddress}#code +**Core Registry:** ${getBlockExplorerAddressUrl(networkName, coreRegistryAddress)} Ownership on Core Registry transferred to the Engine Factory diff --git a/packages/contracts/scripts/engine/V3/post-batch-create-engine-contracts.ts b/packages/contracts/scripts/engine/V3/post-batch-create-engine-contracts.ts index 8561d3644..40009a379 100644 --- a/packages/contracts/scripts/engine/V3/post-batch-create-engine-contracts.ts +++ b/packages/contracts/scripts/engine/V3/post-batch-create-engine-contracts.ts @@ -17,6 +17,7 @@ import { getConfigInputs, getNetworkName, getChainId, + getBlockExplorerAddressUrl, } from "../../util/utils"; import { EXTRA_DELAY_BETWEEN_TX } from "../../util/constants"; import { syncContractMetadataAfterDeploy } from "../../util/graphql-utils"; @@ -48,7 +49,6 @@ async function main() { const networkName = await getNetworkName(); const chainId = await getChainId(); const outputSummaryFile = path.join(inputFileDirectory, "DEPLOYMENTS.md"); - const etherscanSubdomain = networkName === "mainnet" ? "" : `${networkName}.`; if (!deployNetworkConfiguration?.environment) { throw new Error( @@ -83,13 +83,13 @@ async function main() { ## **Environment:** ${deployNetworkConfiguration.environment} - **Engine Implementation:** https://${etherscanSubdomain}etherscan.io/address/${activeEngineImplementationAddress}#code + **Engine Implementation:** ${getBlockExplorerAddressUrl(networkName, activeEngineImplementationAddress)} - **Engine Flex Implementation:** https://${etherscanSubdomain}etherscan.io/address/${activeEngineFlexImplementationAddress}#code + **Engine Flex Implementation:** ${getBlockExplorerAddressUrl(networkName, activeEngineFlexImplementationAddress)} - **Engine Factory:** https://${etherscanSubdomain}etherscan.io/address/${engineFactoryAddress}#code + **Engine Factory:** ${getBlockExplorerAddressUrl(networkName, engineFactoryAddress)} - **Core Registry:** https://${etherscanSubdomain}etherscan.io/address/${coreRegistryAddress}#code + **Core Registry:** ${getBlockExplorerAddressUrl(networkName, coreRegistryAddress)} --- @@ -224,7 +224,7 @@ async function main() { outputMd += ` ## Deployment: ${engineCoreContractType === 0 ? "Engine" : "Engine Flex"} | ${engineContractAddress} - **Engine Contract:** https://${etherscanSubdomain}etherscan.io/address/${engineContractAddress}#code + **Engine Contract:** ${getBlockExplorerAddressUrl(networkName, engineContractAddress)} **Metadata** - **Starting Project Id:** ${startingProjectId} diff --git a/packages/contracts/scripts/minter-deployments/shared-minters-deployer.ts b/packages/contracts/scripts/minter-deployments/shared-minters-deployer.ts index 519412e55..155adb66e 100644 --- a/packages/contracts/scripts/minter-deployments/shared-minters-deployer.ts +++ b/packages/contracts/scripts/minter-deployments/shared-minters-deployer.ts @@ -11,7 +11,12 @@ import { Logger } from "@ethersproject/logger"; Logger.setLogLevel(Logger.levels.ERROR); // delay to avoid issues with reorgs and tx failures -import { delay, getConfigInputs, getNetworkName } from "../util/utils"; +import { + delay, + getConfigInputs, + getNetworkName, + getBlockExplorerAddressUrl, +} from "../util/utils"; import { DELEGATION_REGISTRY_V1_ADDRESSES, EXTRA_DELAY_BETWEEN_TX, @@ -181,8 +186,6 @@ async function main() { ////////////////////////////////////////////////////////////////////////////// const outputSummaryFile = path.join(inputFileDirectory, "DEPLOYMENTS.md"); - const etherscanSubdomain = - networkName === "mainnet" ? "" : `${networkName}.`; const outputMd = ` # Shared Minter Deployment @@ -196,7 +199,7 @@ Date: ${new Date().toISOString()} **${ deployDetails.minterName - }:** https://${etherscanSubdomain}etherscan.io/address/${minterAddress}#code + }:** ${getBlockExplorerAddressUrl(networkName, minterAddress)} **Associated Minter Filter:** ${deployDetails.minterFilterAddress} diff --git a/packages/contracts/scripts/minter-filter-deployments/shared-minter-filter-deployer.ts b/packages/contracts/scripts/minter-filter-deployments/shared-minter-filter-deployer.ts index 61e67d30d..a0504839d 100644 --- a/packages/contracts/scripts/minter-filter-deployments/shared-minter-filter-deployer.ts +++ b/packages/contracts/scripts/minter-filter-deployments/shared-minter-filter-deployer.ts @@ -11,7 +11,12 @@ import { Logger } from "@ethersproject/logger"; Logger.setLogLevel(Logger.levels.ERROR); // delay to avoid issues with reorgs and tx failures -import { delay, getConfigInputs, getNetworkName } from "../util/utils"; +import { + delay, + getConfigInputs, + getNetworkName, + getBlockExplorerAddressUrl, +} from "../util/utils"; import { EXTRA_DELAY_BETWEEN_TX } from "../util/constants"; /** @@ -202,8 +207,6 @@ async function main() { ////////////////////////////////////////////////////////////////////////////// const outputSummaryFile = path.join(inputFileDirectory, "DEPLOYMENTS.md"); - const etherscanSubdomain = - networkName === "mainnet" ? "" : `${networkName}.`; const outputMd = ` # Shared Minter Filter Deployment @@ -217,7 +220,7 @@ Date: ${new Date().toISOString()} **${ deployDetails.minterFilterName - }:** https://${etherscanSubdomain}etherscan.io/address/${minterFilterAddress}#code + }:** ${getBlockExplorerAddressUrl(networkName, minterFilterAddress)} **Associated AdminACL contract:** ${adminACLContractAddress} diff --git a/packages/contracts/scripts/randomizer-deployments/shared-randomizer-deployer.ts b/packages/contracts/scripts/randomizer-deployments/shared-randomizer-deployer.ts index 495576153..0ae1c0d54 100644 --- a/packages/contracts/scripts/randomizer-deployments/shared-randomizer-deployer.ts +++ b/packages/contracts/scripts/randomizer-deployments/shared-randomizer-deployer.ts @@ -11,7 +11,12 @@ import { Logger } from "@ethersproject/logger"; Logger.setLogLevel(Logger.levels.ERROR); // delay to avoid issues with reorgs and tx failures -import { delay, getConfigInputs, getNetworkName } from "../util/utils"; +import { + delay, + getConfigInputs, + getNetworkName, + getBlockExplorerAddressUrl, +} from "../util/utils"; import { EXTRA_DELAY_BETWEEN_TX } from "../util/constants"; /** @@ -155,8 +160,6 @@ async function main() { ////////////////////////////////////////////////////////////////////////////// const outputSummaryFile = path.join(inputFileDirectory, "DEPLOYMENTS.md"); - const etherscanSubdomain = - networkName === "mainnet" ? "" : `${networkName}.`; const outputMd = ` # Shared Randomizer Deployment @@ -170,7 +173,7 @@ Date: ${new Date().toISOString()} **${ deployDetails.randomizerName - }:** https://${etherscanSubdomain}etherscan.io/address/${randomizerAddress}#code + }:** ${getBlockExplorerAddressUrl(networkName, randomizerAddress)} **Associated pseudorandom atomic contract:** ${ deployDetails.pseudorandomAtomicContractAddress diff --git a/packages/contracts/scripts/util/aws_s3.ts b/packages/contracts/scripts/util/aws_s3.ts index 5a34ae596..6795fb535 100644 --- a/packages/contracts/scripts/util/aws_s3.ts +++ b/packages/contracts/scripts/util/aws_s3.ts @@ -9,7 +9,7 @@ const { // Docs: https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/index.html -const supportedNetworks = ["mainnet", "arbitrum", "sepolia", "base"]; +const supportedNetworks = ["mainnet", "arbitrum", "sepolia", "base", "shape"]; const awsCreds = { accessKeyId: process.env.PROD_AWS_ACCESS_KEY_ID, diff --git a/packages/contracts/scripts/util/constants.ts b/packages/contracts/scripts/util/constants.ts index f85a73442..1ca98fc6d 100644 --- a/packages/contracts/scripts/util/constants.ts +++ b/packages/contracts/scripts/util/constants.ts @@ -24,7 +24,7 @@ export const DELEGATION_REGISTRY_V2_ADDRESSES = { /** * Get active shared minter filter contract address for the given network and * environment. - * @param networkName network name (e.g. "mainnet", "arbitrum", "base", "sepolia") + * @param networkName network name (e.g. "mainnet", "arbitrum", "base", "shape", "sepolia") * @param environment environment (e.g. "dev", "staging", "prod") * @returns active shared minter filter contract address */ @@ -45,7 +45,7 @@ export function getActiveSharedMinterFilter( /** * Get active shared randomizer contract address for the given network and * environment. - * @param networkName network name (e.g. "mainnet", "arbitrum", "base", "sepolia") + * @param networkName network name (e.g. "mainnet", "arbitrum", "base", "shape", "sepolia") * @param environment environment (e.g. "dev", "staging", "prod") * @returns active shared randomizer contract address */ @@ -153,7 +153,7 @@ export enum ProductClassEnum { * Helper function to get the prod render provider payment address for the given * network and environment, if there is a requirement. * Returns undefined if there is no requirement for a specific render provider (e.g. testnet) - * @param networkName network name, e.g. "mainnet", "arbitrum", "base", "sepolia" + * @param networkName network name, e.g. "mainnet", "arbitrum", "base", "shape", "sepolia" * @param environment environment, e.g. "dev", "staging", "prod" * @param productClass product class, "Engine", "Studio" * @returns address if require a specific render provider payment address for the given network and environment, otherwise undefined @@ -237,6 +237,21 @@ export const MAIN_CONFIG: T_MAIN_CONFIG = { }, }, }, + // @dev leave empty until Shape mainnet infrastructure is deployed (chain ID 360). + // See deployments/engine/V3/shape/INFRASTRUCTURE.md for bootstrap order. + shape: { + prod: { + engineFactory: "", + sharedMinterFilter: "", + sharedRandomizer: "", + universalBytecodeStorageReader: "", + scriptyBuilderV2: "", + prodRenderProviderPaymentAddress: { + [ProductClassEnum.Engine]: "", + [ProductClassEnum.Sudio]: "", + }, + }, + }, sepolia: { staging: { engineFactory: "0x00000006741521Ccd80EEd7BfA8bDbe542B425Cf", diff --git a/packages/contracts/scripts/util/utils.ts b/packages/contracts/scripts/util/utils.ts index 55a78f032..dc64d2896 100644 --- a/packages/contracts/scripts/util/utils.ts +++ b/packages/contracts/scripts/util/utils.ts @@ -296,6 +296,9 @@ export async function getNetworkName() { } else if (networkName === "unknown" && network.chainId === 8453) { // base rpc doesn't return name, so handle unknown + chainId networkName = "base"; + } else if (networkName === "unknown" && network.chainId === 360) { + // shape rpc doesn't return name, so handle unknown + chainId + networkName = "shape"; } else if (networkName === "unknown" && network.chainId === 31337) { networkName = "hardhat"; } @@ -308,6 +311,23 @@ export async function getChainId(): Promise { return network.chainId; } +/** + * Block explorer URL for a contract address on the given network. + * Shape uses Shapescan (Blockscout); other networks use Etherscan-family explorers. + */ +export function getBlockExplorerAddressUrl( + networkName: string, + address: string, + withCodeHash = true +): string { + const codeSuffix = withCodeHash ? "#code" : ""; + if (networkName === "shape") { + return `https://shapescan.xyz/address/${address}${codeSuffix}`; + } + const etherscanSubdomain = networkName === "mainnet" ? "" : `${networkName}.`; + return `https://${etherscanSubdomain}etherscan.io/address/${address}${codeSuffix}`; +} + export function chunkArray(array: T[], chunkSize: number): T[][] { const result: T[][] = []; for (let i = 0; i < array.length; i += chunkSize) { From dcc76d8d3ad6094801582042b3c089fa102e1f90 Mon Sep 17 00:00:00 2001 From: Lindsay Gilbert Date: Thu, 11 Jun 2026 14:27:49 -0400 Subject: [PATCH 2/2] add render provider addresses for engine and studio on shape network --- packages/contracts/scripts/util/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts/scripts/util/constants.ts b/packages/contracts/scripts/util/constants.ts index 1ca98fc6d..efdb076df 100644 --- a/packages/contracts/scripts/util/constants.ts +++ b/packages/contracts/scripts/util/constants.ts @@ -247,8 +247,8 @@ export const MAIN_CONFIG: T_MAIN_CONFIG = { universalBytecodeStorageReader: "", scriptyBuilderV2: "", prodRenderProviderPaymentAddress: { - [ProductClassEnum.Engine]: "", - [ProductClassEnum.Sudio]: "", + [ProductClassEnum.Engine]: "0x6b0A560e8b98b1eFbd687Fb4116c4a188c9F8C30", + [ProductClassEnum.Sudio]: "0xD98eEA78a6EE3015a576842236e935E97E56df00", }, }, },