generate_orbit_deployment
Generate deployment code for Orbit chains to configure rollups, token bridges, or full deployments with validators and batch posters.
Instructions
Generate deployment code for Orbit chains. Supports rollup deployment, token bridge deployment, and full deployment with validators and batch posters.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | Description of the deployment requirements | |
| deployment_type | No | Type of deployment to generate | rollup |
| validators | No | Validator addresses for the rollup | |
| batch_posters | No | Batch poster addresses | |
| native_token | No | Custom gas token address | |
| parent_chain | No | Parent chain for deployment | arbitrum-sepolia |
| rollup_version | No | Rollup version to deploy | v3.1 |
| chain_id | No | Chain ID for the new Orbit chain | |
| is_anytrust | No | Whether to deploy as AnyTrust chain | |
| rollup_address | No | Existing rollup address (for token_bridge deployment) |
Implementation Reference
- The GenerateOrbitDeploymentTool class handles the logic for generating Orbit chain deployment scripts using templates.
class GenerateOrbitDeploymentTool(BaseTool): """Generate Orbit chain deployment scripts.""" name = "generate_orbit_deployment" description = """Generate deployment code for Orbit chains. Supports: - Rollup deployment with createRollup() - Token bridge deployment with createTokenBridge() - Full deployment (rollup + token bridge in sequence) Configures validators, batch posters, native tokens, and rollup versions. Generates TypeScript scripts using @arbitrum/orbit-sdk.""" input_schema = { "type": "object", "properties": { "prompt": { "type": "string", "description": "Description of the deployment requirements", }, "deployment_type": { "type": "string", "enum": ["rollup", "token_bridge", "full"], "description": "Type of deployment to generate", "default": "rollup", }, "validators": { "type": "array", "items": {"type": "string"}, "description": "Validator addresses for the rollup", }, "batch_posters": { "type": "array", "items": {"type": "string"}, "description": "Batch poster addresses", }, "native_token": { "type": "string", "description": "Custom gas token address (for custom gas token chains)", }, "parent_chain": { "type": "string", "enum": [ "arbitrum-one", "arbitrum-sepolia", "ethereum-mainnet", "ethereum-sepolia", ], "description": "Parent chain for deployment", "default": "arbitrum-sepolia", }, "rollup_version": { "type": "string", "enum": ["v2.1", "v3.1"], "description": "Rollup version to deploy", "default": "v3.1", }, "chain_id": { "type": "integer", "description": "Chain ID for the new Orbit chain", "default": 412346, }, "is_anytrust": { "type": "boolean", "description": "Whether to deploy as AnyTrust chain", "default": False, }, "rollup_address": { "type": "string", "description": "Existing rollup address (for token_bridge deployment)", }, }, "required": ["prompt"], } def __init__(self, vectordb=None): """Initialize with optional vector database.""" self.vectordb = vectordb def execute(self, **kwargs) -> dict[str, Any]: """Generate Orbit chain deployment code.""" prompt = kwargs.get("prompt", "") deployment_type = kwargs.get("deployment_type", "rollup") validators = kwargs.get("validators", []) batch_posters = kwargs.get("batch_posters", []) native_token = kwargs.get("native_token") parent_chain = kwargs.get("parent_chain", "arbitrum-sepolia") rollup_version = kwargs.get("rollup_version", "v3.1") chain_id = kwargs.get("chain_id", 412346) is_anytrust = kwargs.get("is_anytrust", False) rollup_address = kwargs.get("rollup_address", "0x0000000000000000000000000000000000000000") if not prompt: return {"error": "prompt is required"} # Get parent chain info parent_rpc = PARENT_CHAIN_RPCS.get(parent_chain, PARENT_CHAIN_RPCS["arbitrum-sepolia"]) parent_chain_id = self._get_parent_chain_id(parent_chain) parent_chain_name = parent_chain.replace("-", " ").title() # Format validator/batch poster arrays validators_str = self._format_address_array(validators) batch_posters_str = self._format_address_array(batch_posters) files = {} # Generate rollup deployment if deployment_type in ("rollup", "full"): rollup_template = get_orbit_template("deploy_rollup") if rollup_template: code = rollup_template.code code = self._substitute_params( code, chain_id=chain_id, parent_chain_id=parent_chain_id, parent_chain_name=parent_chain_name, is_anytrust=is_anytrust, validators_str=validators_str, batch_posters_str=batch_posters_str, native_token=native_token, ) # Look up the known RollupCreator address for this version + parent chain version_addresses = ROLLUP_CREATOR_ADDRESSES.get( rollup_version, ROLLUP_CREATOR_ADDRESSES["v3.1"] ) rollup_creator_address = version_addresses.get( parent_chain_id, "0x0000000000000000000000000000000000000000" ) # Apply version-specific modifications version_label = "v2.1 / classic" if rollup_version == "v2.1" else "v3.1 / BoLD" code = code.replace( "console.log('Deploying Orbit chain...');", f"console.log('Deploying Orbit chain ({version_label})...');\n" f" console.log(' RollupCreator: {rollup_creator_address}');", ) if rollup_version == "v2.1": code = code.replace( " // Deploy rollup\n", f" // Deploy rollup — v2.1 uses classic challenge protocol\n" f" // RollupCreator: {rollup_creator_address}\n" " // baseStake = 0.1 ETH, stakeToken = ETH (default)\n", ) code = code.replace( " walletClient,\n }});", " parentChainPublicClient: publicClient,\n" " // v2.1: classic challenge protocol (stable, non-BoLD)\n" " rollupCreatorVersion: 'v2.1',\n" " }});", ) code = code.replace( "console.log('\\nRollup deployed successfully!');", "console.log('\\nRollup deployed successfully! (v2.1 classic)');\n" " console.log('\\nv2.1 validator config:');\n" " console.log(' Base stake: 0.1 ETH (default)');\n" " console.log(' Stake token: ETH');", ) else: code = code.replace( " // Deploy rollup\n", f" // Deploy rollup — v3.1 uses BoLD challenge protocol\n" f" // RollupCreator: {rollup_creator_address}\n", ) code = code.replace( " walletClient,\n }});", " parentChainPublicClient: publicClient,\n" " // v3.1: BoLD challenge protocol (default)\n" " rollupCreatorVersion: 'v3.1',\n" " }});", ) code = code.replace( "console.log('\\nRollup deployed successfully!');", "console.log('\\nRollup deployed successfully! (v3.1 BoLD)');", ) files["scripts/deploy-rollup.ts"] = validate_template_output( code, "deploy-rollup" ) # Generate standalone approve-token.ts when using custom gas token if native_token: approve_code = APPROVE_TOKEN_TEMPLATE approve_code = approve_code.replace( "{parent_chain_id}", str(parent_chain_id) ) approve_code = approve_code.replace( "{parent_chain_name}", parent_chain_name ) approve_code = approve_code.replace( "{native_token}", native_token ) files["scripts/approve-token.ts"] = validate_template_output( approve_code, "approve-token" ) # Generate token bridge deployment if deployment_type in ("token_bridge", "full"): bridge_template = get_orbit_template("deploy_token_bridge") if bridge_template: code = bridge_template.code code = code.replace("{chain_id}", str(chain_id)) code = code.replace("{chain_name}", f"orbit-chain-{chain_id}") code = code.replace("{parent_chain_id}", str(parent_chain_id)) code = code.replace("{parent_chain_name}", parent_chain_name) code = code.replace("{rollup_address}", rollup_address) # Inject token approval for TokenBridgeCreator when using custom gas token if native_token: tbc_address = TOKEN_BRIDGE_CREATOR_ADDRESSES.get( parent_chain_id, "0x0000000000000000000000000000000000000000" ) # Add maxUint256 to the viem import code = code.replace( " createWalletClient,\n http,\n Chain,\n} from 'viem';", " createWalletClient,\n http,\n maxUint256,\n Chain,\n} from 'viem';", ) # Add ERC20 ABI after the chain-sdk import erc20_abi_block = ( "\n// ERC20 ABI for token approval\n" "const erc20Abi = [\n" " {\n" " name: 'approve',\n" " type: 'function',\n" " stateMutability: 'nonpayable',\n" " inputs: [\n" " { name: 'spender', type: 'address' },\n" " { name: 'amount', type: 'uint256' },\n" " ],\n" " outputs: [{ name: '', type: 'bool' }],\n" " },\n" " {\n" " name: 'allowance',\n" " type: 'function',\n" " stateMutability: 'view',\n" " inputs: [\n" " { name: 'owner', type: 'address' },\n" " { name: 'spender', type: 'address' },\n" " ],\n" " outputs: [{ name: '', type: 'uint256' }],\n" " },\n" "] as const;\n" ) code = code.replace( "import { createTokenBridge } from '@arbitrum/chain-sdk';", "import { createTokenBridge } from '@arbitrum/chain-sdk';\n" + erc20_abi_block, ) # Inject approval block right before "console.log('Deploying token bridge...')" approval_block = ( " // --- Approve native token for TokenBridgeCreator ---\n" " // Custom gas token chains require the TokenBridgeCreator to spend the native token\n" " if (nativeToken) {\n" f" const tokenBridgeCreator = '{tbc_address}' as `0x${{string}}`;\n" " console.log('Approving native token for TokenBridgeCreator...');\n" " console.log(' Token:', nativeToken);\n" " console.log(' TokenBridgeCreator:', tokenBridgeCreator);\n" "\n" " const currentAllowance = await parentPublicClient.readContract({\n" " address: nativeToken,\n" " abi: erc20Abi,\n" " functionName: 'allowance',\n" " args: [account.address, tokenBridgeCreator],\n" " });\n" "\n" " if (currentAllowance === 0n) {\n" " const approveTx = await parentWalletClient.writeContract({\n" " address: nativeToken,\n" " abi: erc20Abi,\n" " functionName: 'approve',\n" " args: [tokenBridgeCreator, maxUint256],\n" " });\n" " await parentPublicClient.waitForTransactionReceipt({ hash: approveTx });\n" " console.log(' Token approved for TokenBridgeCreator');\n" " } else {\n" " console.log(' Token already approved for TokenBridgeCreator');\n" " }\n" " }\n" "\n" ) # Also read nativeToken from deployment.json — add after the existing deployment.json read code = code.replace( " console.log('Loaded deployment.json — rollup:', rollupAddress);", " nativeToken = deployment.nativeToken as `0x${string}` | undefined;\n" " console.log('Loaded deployment.json — rollup:', rollupAddress);\n" " if (nativeToken) console.log(' Native token:', nativeToken);", ) # Add nativeToken variable declaration after orbitChainId # Note: {chain_id} was already replaced above, so match the actual value code = code.replace( f" let orbitChainId = {chain_id};", f" let orbitChainId = {chain_id};\n" " let nativeToken: `0x${string}` | undefined;", ) code = code.replace( " console.log('Deploying token bridge...');", approval_block + " console.log('Deploying token bridge...');", ) files["scripts/deploy-token-bridge.ts"] = validate_template_output( code, "deploy-token-bridge" ) # Add .env.example env_vars = [ "DEPLOYER_PRIVATE_KEY=0x...", f"PARENT_CHAIN_RPC={parent_rpc}", ] if rollup_version == "v2.1": env_vars.append("# Using v2.1 RollupCreator (classic challenge protocol)") if deployment_type in ("token_bridge", "full"): env_vars.append("ORBIT_CHAIN_RPC=http://localhost:8449") files[".env.example"] = "\n".join(env_vars) + "\n" # Build response result = { "template_used": f"deploy_{deployment_type}", "deployment_type": deployment_type, "rollup_version": rollup_version, "files": files, "dependencies": ORBIT_DEPENDENCIES, "parent_chain": { "name": parent_chain, "chain_id": parent_chain_id, "rpc": parent_rpc, }, "chain_config": { "chain_id": chain_id, "is_anytrust": is_anytrust, "native_token": native_token, "validators": validators, "batch_posters": batch_posters, }, "setup_instructions": self._get_setup_instructions(deployment_type, native_token), "notes": self._get_notes(deployment_type, native_token, is_anytrust, rollup_version), "disclaimer": TEMPLATE_DISCLAIMER, } return result