@@ -83,6 +83,12 @@ func (g *ArtifactGenerator) GenerateArtifacts(
8383 return err
8484 }
8585
86+ // 6b. Generate ready-to-use .env file
87+ envFile := GenerateEnv (config , result )
88+ if err := g .saveTextArtifact (ctx , deploymentID , "env_file" , envFile ); err != nil {
89+ return err
90+ }
91+
8692 // 7. Generate README.md
8793 readme := GenerateReadme (config , result )
8894 if err := g .saveTextArtifact (ctx , deploymentID , "readme" , readme ); err != nil {
@@ -255,7 +261,7 @@ func buildChainConfig(config *DeployConfig) map[string]interface{} {
255261 // true = AnyTrust DAC mode
256262 // For Celestia, we use external-provider flags with DAC=false
257263 "DataAvailabilityCommittee" : config .DataAvailability == "anytrust" ,
258- "InitialArbOSVersion" : 20 ,
264+ "InitialArbOSVersion" : 51 , // ArbOS 51 - Nitro consensus-v51
259265 "InitialChainOwner" : config .Owner ,
260266 "GenesisBlockNum" : 0 ,
261267 },
@@ -614,6 +620,13 @@ services:
614620 - POPSIGNER_API_KEY=${POPSIGNER_CELESTIA_API_KEY}
615621 # Parent chain RPC for Blobstream validation (fraud proofs)
616622 - ETH_RPC_URL=${L1_RPC_URL}
623+ # Healthcheck ensures celestia-das-server is ready before nitro-sequencer starts
624+ healthcheck:
625+ test: ["CMD", "wget", "-q", "--spider", "http://localhost:9876/health"]
626+ interval: 5s
627+ timeout: 3s
628+ retries: 5
629+ start_period: 10s
617630 networks:
618631 - nitro-network
619632
@@ -635,7 +648,7 @@ services:
635648 restart: unless-stopped
636649 depends_on:
637650 celestia-das-server:
638- condition: service_started
651+ condition: service_healthy # Wait for healthcheck to pass, not just container start
639652 ports:
640653 - "8547:8547" # HTTP RPC
641654 - "8548:8548" # WebSocket RPC
@@ -651,6 +664,9 @@ services:
651664 - L1_RPC_URL=${L1_RPC_URL} # Can be HTTP or WSS (e.g., wss://sepolia.infura.io/ws/v3/KEY)
652665 - L1_BEACON_URL=${L1_BEACON_URL} # Beacon Chain API (HTTP)
653666 - POPSIGNER_MTLS_URL=${POPSIGNER_MTLS_URL}
667+ # External signer addresses (managed by PopSigner)
668+ - BATCH_POSTER_ADDRESS=${BATCH_POSTER_ADDRESS}
669+ - STAKER_ADDRESS=${STAKER_ADDRESS}
654670 command:
655671 # -------------------------------------------------------------------------
656672 # Core Chain Configuration
@@ -699,18 +715,27 @@ services:
699715 # -------------------------------------------------------------------------
700716 - --node.batch-poster.enable=true
701717 - --node.batch-poster.data-poster.external-signer.url=${POPSIGNER_MTLS_URL}
718+ - --node.batch-poster.data-poster.external-signer.address=${BATCH_POSTER_ADDRESS}
702719 - --node.batch-poster.data-poster.external-signer.method=eth_signTransaction
703720 - --node.batch-poster.data-poster.external-signer.client-cert=/certs/client.crt
704721 - --node.batch-poster.data-poster.external-signer.client-private-key=/certs/client.key
722+ - --node.batch-poster.data-poster.external-signer.root-ca=/certs/ca.crt
705723 # -------------------------------------------------------------------------
706- # Staker/Validator Configuration (uses PopSigner for L1 tx signing)
724+ # Staker/Validator Configuration (BOLD Protocol)
725+ # IMPORTANT: BOLD requires WETH (not native ETH) for staking!
726+ # Before starting, ensure your STAKER_ADDRESS has:
727+ # 1. WETH tokens (wrap ETH via WETH.deposit())
728+ # 2. Approved ChallengeManager to spend WETH
729+ # Stake amount: ~0.1 ETH equivalent per assertion level
707730 # -------------------------------------------------------------------------
708731 - --node.staker.enable=true
709732 - --node.staker.strategy=MakeNodes
710733 - --node.staker.data-poster.external-signer.url=${POPSIGNER_MTLS_URL}
734+ - --node.staker.data-poster.external-signer.address=${STAKER_ADDRESS}
711735 - --node.staker.data-poster.external-signer.method=eth_signTransaction
712736 - --node.staker.data-poster.external-signer.client-cert=/certs/client.crt
713737 - --node.staker.data-poster.external-signer.client-private-key=/certs/client.key
738+ - --node.staker.data-poster.external-signer.root-ca=/certs/ca.crt
714739 # -------------------------------------------------------------------------
715740 # Feed Output (for full nodes to subscribe)
716741 # -------------------------------------------------------------------------
@@ -908,6 +933,24 @@ func GenerateEnvExample(config *DeployConfig, result *DeployResult) string {
908933 rpcExample = "wss://mainnet.infura.io/ws/v3/YOUR_KEY"
909934 }
910935
936+ // Get the batch poster address from config.BatchPosters
937+ batchPosterAddress := ""
938+ if len (config .BatchPosters ) > 0 {
939+ batchPosterAddress = config .BatchPosters [0 ]
940+ }
941+ if batchPosterAddress == "" {
942+ batchPosterAddress = "REPLACE_WITH_YOUR_BATCH_POSTER_ADDRESS"
943+ }
944+
945+ // Get staker address from config.Validators (NOT same as batch poster!)
946+ stakerAddress := ""
947+ if len (config .Validators ) > 0 {
948+ stakerAddress = config .Validators [0 ]
949+ }
950+ if stakerAddress == "" {
951+ stakerAddress = "REPLACE_WITH_YOUR_STAKER_ADDRESS"
952+ }
953+
911954 return fmt .Sprintf (`# =============================================================================
912955# %s Nitro + Celestia DA Environment Configuration
913956# Chain ID: %d | Parent Chain: %s (%d)
@@ -938,13 +981,26 @@ L1_BEACON_URL=%s
938981# =============================================================================
939982
940983# PopSigner mTLS endpoint for transaction signing
941- POPSIGNER_MTLS_URL=https://rpc-mtls.popsigner.com
984+ POPSIGNER_MTLS_URL=https://rpc-mtls.popsigner.com:8546
942985
943986# Note: mTLS certificates are included in ./certs/
944987# - ./certs/client.crt (auto-generated during deployment)
945988# - ./certs/client.key (auto-generated during deployment)
946989# - ./certs/ca.crt (CA certificate for verification)
947990
991+ # =============================================================================
992+ # EXTERNAL SIGNER ADDRESSES
993+ # These are the Ethereum addresses that PopSigner will sign transactions for
994+ # =============================================================================
995+
996+ # Batch Poster Address - the address used to submit batches to L1
997+ # This should be the address associated with your PopSigner key
998+ BATCH_POSTER_ADDRESS=%s
999+
1000+ # Staker Address - the address used for staking/validation (if staker enabled)
1001+ # Can be same as batch poster or a different address
1002+ STAKER_ADDRESS=%s
1003+
9481004# =============================================================================
9491005# POPSIGNER FOR CELESTIA - Blob Submission Signing
9501006# Used for signing Celestia blob transactions (SEPARATE from L1 signer!)
@@ -981,7 +1037,106 @@ NITRO_DAS_IMAGE=ghcr.io/celestiaorg/nitro-das-celestia:v0.7.0
9811037` , config .ChainName , config .ChainID , parentChainName , config .ParentChainID ,
9821038 parentChainName ,
9831039 strings .ToLower (parentChainName ), strings .ToLower (parentChainName ), strings .ToLower (parentChainName ),
984- rpcExample , beaconURL , beaconURL , parentChainName )
1040+ rpcExample , beaconURL , beaconURL , parentChainName ,
1041+ batchPosterAddress , stakerAddress )
1042+ }
1043+
1044+ // GenerateEnv creates a ready-to-use .env file with actual values.
1045+ // This removes the need for users to manually copy/edit .env.example.
1046+ func GenerateEnv (config * DeployConfig , result * DeployResult ) string {
1047+ // Determine parent chain name and beacon URL
1048+ parentChainName := "Sepolia"
1049+ beaconURL := "https://ethereum-sepolia-beacon-api.publicnode.com"
1050+ if config .ParentChainID == 1 {
1051+ parentChainName = "Mainnet"
1052+ beaconURL = "https://ethereum-mainnet-beacon-api.publicnode.com"
1053+ }
1054+
1055+ // Use actual RPC URL from config, or default to public endpoint
1056+ rpcURL := config .ParentChainRpc
1057+ if rpcURL == "" {
1058+ if config .ParentChainID == 1 {
1059+ rpcURL = "https://ethereum-rpc.publicnode.com"
1060+ } else {
1061+ rpcURL = "https://ethereum-sepolia-rpc.publicnode.com"
1062+ }
1063+ }
1064+
1065+ // Get the batch poster address from config.BatchPosters
1066+ batchPosterAddress := ""
1067+ if len (config .BatchPosters ) > 0 {
1068+ batchPosterAddress = config .BatchPosters [0 ]
1069+ }
1070+ if batchPosterAddress == "" {
1071+ batchPosterAddress = "REPLACE_WITH_YOUR_BATCH_POSTER_ADDRESS"
1072+ }
1073+
1074+ // Get staker address from config.Validators (NOT same as batch poster!)
1075+ stakerAddress := ""
1076+ if len (config .Validators ) > 0 {
1077+ stakerAddress = config .Validators [0 ]
1078+ }
1079+ if stakerAddress == "" {
1080+ stakerAddress = "REPLACE_WITH_YOUR_STAKER_ADDRESS"
1081+ }
1082+
1083+ // Celestia config - these would come from the deployment config if set
1084+ celestiaAPIKey := "REPLACE_WITH_YOUR_CELESTIA_API_KEY"
1085+ celestiaKeyID := "REPLACE_WITH_YOUR_CELESTIA_KEY_ID"
1086+
1087+ return fmt .Sprintf (`# =============================================================================
1088+ # %s Nitro + Celestia DA Environment Configuration
1089+ # Chain ID: %d | Parent Chain: %s (%d)
1090+ # Generated by PopSigner - Ready to use!
1091+ # =============================================================================
1092+
1093+ # =============================================================================
1094+ # PARENT CHAIN (%s) - L1 CONNECTIONS
1095+ # =============================================================================
1096+
1097+ # Main L1 RPC endpoint (configured during deployment)
1098+ L1_RPC_URL=%s
1099+
1100+ # Beacon Chain API for EIP-4844 blob data
1101+ L1_BEACON_URL=%s
1102+
1103+ # =============================================================================
1104+ # POPSIGNER FOR L1 (%s) - Batch Poster & Validator Signing
1105+ # =============================================================================
1106+
1107+ # PopSigner mTLS endpoint for transaction signing
1108+ POPSIGNER_MTLS_URL=https://rpc-mtls.popsigner.com:8546
1109+
1110+ # =============================================================================
1111+ # EXTERNAL SIGNER ADDRESSES (configured during deployment)
1112+ # =============================================================================
1113+
1114+ # Batch Poster Address - the address used to submit batches to L1
1115+ BATCH_POSTER_ADDRESS=%s
1116+
1117+ # Staker Address - the address used for staking/validation
1118+ STAKER_ADDRESS=%s
1119+
1120+ # =============================================================================
1121+ # POPSIGNER FOR CELESTIA - Blob Submission Signing
1122+ # =============================================================================
1123+
1124+ # PopSigner API key for Celestia (get from PopSigner dashboard)
1125+ POPSIGNER_CELESTIA_API_KEY=%s
1126+
1127+ # PopSigner Key ID for your Celestia signing key
1128+ POPSIGNER_CELESTIA_KEY_ID=%s
1129+
1130+ # =============================================================================
1131+ # NITRO IMAGE
1132+ # =============================================================================
1133+
1134+ NITRO_IMAGE=nitro-node-dev:latest
1135+ NITRO_DAS_IMAGE=ghcr.io/celestiaorg/nitro-das-celestia:v0.7.0
1136+ ` , config .ChainName , config .ChainID , parentChainName , config .ParentChainID ,
1137+ parentChainName , rpcURL , beaconURL , parentChainName ,
1138+ batchPosterAddress , stakerAddress ,
1139+ celestiaAPIKey , celestiaKeyID )
9851140}
9861141
9871142// ============================================================================
0 commit comments