This page documents the internal workflow that Kiro follows when you run the corresponding @prompt. You don't need to read this to use the tool — it's here for transparency and for developers who want to understand or extend the workflows.
Add a New Blockchain Protocol
Blueprint System Overview
Blockchain protocols are delivered as NPM packages called "blueprints". Each blueprint contains protocol-specific configuration, scripts, and sample files. The ConfigurationLoader resolves all blueprints from node_modules/ — there is no distinction between built-in and external blueprints at runtime.
Blueprint packages follow the naming convention: aws-bnr-blueprint-<protocol> (e.g., aws-bnr-blueprint-ethereum, aws-bnr-blueprint-solana).
Built-in blueprints live in blueprints/ and are referenced as file: path dependencies in the root package.json. After npm install, they land in node_modules/ alongside external blueprints. The ConfigurationLoader treats them identically.
The blueprints/dummy/ directory is the canonical reference implementation. Use it as a template when creating new blueprints. See blueprints/dummy/README.md for details.
Who Is This For?
This workflow supports two paths. The generation steps below are shared — what differs is where the blueprint lives and how it is distributed.
- Path A: Core Maintainers — adding a built-in blueprint directly to the
blueprints/directory of the Node Runners repository, wired as afile:path dependency in the rootpackage.json. This is the existing flow documented throughout this file. - Path B: Community Developers (Recommended) — creating an external blueprint as a standalone NPM package in your own repository, published independently and installed into a user's
node_modules/like any other blueprint.
Note: Since the v2 core blueprint lock (Jun 2026), new protocols are added as external community blueprints, not built-in. Path B is the standard contribution model.
Because the ConfigurationLoader resolves all blueprints from node_modules/ identically, the file generation steps (package.json, samples, configuration scripts, user-data, README) are the same for both paths. The "Testing Your External Blueprint Locally" and "Publishing and Listing" sections below cover the Path B specifics.
PREREQUISITES CHECK
Before starting, confirm you have:
- URL to the protocol's official RPC node deployment documentation
- (Optional) Additional resources: GitHub repo, snapshot sources, community guides
IMPORTANT: This workflow is for RPC node deployments only. Validator or consensus nodes have different requirements and are not covered.
At the start, ask the user for:
- Protocol name
- URL to official RPC node documentation
- (Optional) Any special requirements or constraints
- (Optional) Preferred client software if multiple options exist
STEP 1: READ CONTEXT FILES
Read these files to understand the project structure and patterns:
Required:
blueprints/dummy/— Complete working example (primary template)package.json— Configuration structure (in"aws-blockchain-node-runner"field)samples/.env-*— Environment configuration examplesconfigurations/*.sh— Configuration script patternsuser-data/node.sh— Generic initialization patternREADME.md— Documentation template
docs/configuration-reference.md— Environment variable referencedocs/troubleshooting.md— Troubleshooting patterns.kiro/specs/universal-blockchain-node-runner/design.md— Architecture and interfaces.kiro/steering/*.md— Project patterns and conventions
STEP 2: FETCH AND ANALYZE DOCUMENTATION
Using the provided documentation URL:
- Fetch the protocol's official RPC node documentation
- Extract key information:
- Client software name and versions
- Installation methods (binary, Docker, docker-compose)
- System requirements (CPU, memory, storage)
- Network configuration (RPC ports, P2P ports)
- Snapshot availability and sources
If documentation URL is inaccessible, ask the user to provide documentation as a local file or offer to proceed with available information and iterate.
STEP 3: RESEARCH INFRASTRUCTURE REQUIREMENTS
Based on the protocol documentation, research and determine:
-
Instance Type Recommendation:
- CPU and memory requirements from protocol docs
- Recommended EC2 instance types (x86_64 and ARM_64)
- Justification based on protocol specifications
-
Storage Type Selection:
- Block creation time (seconds per block)
- If sub-10 second blocks: Recommend io2 or Instance Store
- If 10+ second blocks: Recommend gp3
- For long-term deployments: Compare Instance Store with Savings Plans vs EBS costs
-
Storage Size Requirements:
- Current blockchain data size
- Growth rate (GB per month)
- Check snapshot size from https://publicnode.com/snapshots
- Space needed for snapshot download and extraction (2-3x compressed size)
- Recommended total storage with 12-month projection
-
Network Traffic Estimation:
- Average peer count
- Block size and block time
- Estimated monthly outgoing P2P traffic in TB
- Monthly data transfer cost ($0.09/GB after 100 GB free tier)
-
Traffic Shaping Assessment:
- If block time <10 seconds: Recommend traffic shaping for cost optimization
- Potential cost savings (up to 85% reduction in data transfer costs)
- See
docs/traffic-shaping.mdfor implementation details
-
Monthly Cost Estimate:
- Compute cost (instance type)
- Storage cost (type and size)
- Network transfer cost (with and without traffic shaping if applicable)
- CloudWatch logs cost (~15% of total or from protocol estimates)
- Total estimated monthly cost
Present this research as a structured summary for review before proceeding.
STEP 4: CREATE PROTOCOL DIRECTORY STRUCTURE
Create the following structure for the blueprint package. If contributing to the core repository, place it in blueprints/{protocol-name}/. If creating an external package, create a standalone directory:
aws-bnr-blueprint-{protocol-name}/
├── package.json
├── README.md
├── samples/
│ ├── .env-{network}-{client}-{type}
│ ├── .env-{network}-{client}-{type}-ha
│ ├── .env-{network}-{client1}-{client2}-{type} (multi-client)
│ └── .env-{network}-{client1}-{client2}-{type}-ha (multi-client HA)
├── configurations/
│ └── {client}-{version}-{type}.sh or .yml
├── user-data/
│ ├── node.sh
│ ├── syncchecker.sh (if traffic shaping recommended)
│ └── common/ (optional, shared helper scripts)
└── monitoring/ (optional)
└── single-node-dashboard-template.json
STEP 5: GENERATE package.json
Create package.json with standard NPM fields and an "aws-blockchain-node-runner" field.
Standard NPM fields:
name:"aws-bnr-blueprint-{protocol}"(naming convention)version:"2.0.0"description: Human-readable descriptionpeerDependencies:{ "aws-blockchain-node-runners": ">=2.0.0" }
The "aws-blockchain-node-runner" field contains protocol-specific configuration:
BLOCKCHAIN_PROTOCOL: Lowercase protocol namesupportedDeploymentModes: Array of supported modesdefaultConfiguration: Default configuration file nameavailableConfigurations: Array of configuration objectsBC_NETWORKS: Array of supported networksdefaultInstanceTypes: x86_64 and ARM_64 recommendationsrequiredPorts: Array of port objects (port, protocol, description, public)monitoring: Health check and metrics configurationstorage: Default data volumes configurationcustomEnvVarsNamePrefix: Prefix for protocol-specific env varssnapshot: Snapshot configuration (optional)trafficShaping: Traffic shaping support (optional)
Follow the structure from blueprints/dummy/package.json exactly.
STEP 6: GENERATE SAMPLE .ENV FILES
Create sample .env files for each supported combination.
Single-client protocols (one client binary, e.g. Solana/Agave):
.env-{network}-{client}-{type}(mainnet, single-node, e.g..env-mainnet-beta-agave-rpc-base).env-{network}-{client}-{type}-ha(mainnet, HA, e.g..env-mainnet-beta-agave-rpc-base-ha).env-{network}-{client}-{type}(testnet, single-node, e.g..env-testnet-agave-rpc-base)
Multi-client protocols (execution + consensus, e.g. Ethereum):
.env-mainnet-{client1}-{client2}-{type}(e.g..env-mainnet-geth-lighthouse-full).env-mainnet-{client1}-{client2}-{type}-ha(e.g..env-mainnet-geth-lighthouse-full-ha).env-testnet-{client1}-{client2}-{type}(e.g..env-sepolia-geth-lighthouse-full)
Only create HA samples if HA is practical for this protocol.
Each file must include:
AWS_ACCOUNT_IDandAWS_REGION(with placeholder values)AWS_AZ(optional, commented-out — override automatic AZ selection for single-node)BLOCKCHAIN_PROTOCOL(protocol name)DEPLOYMENT_MODE("single-node" or "ha-nodes")INSTANCE_TYPE(recommended type)CPU_TYPE("x86_64" or "ARM_64")BC_NETWORK(network name)CLIENT_CONFIG(configuration script name without extension)- Storage configuration (
DATA_VOL_*variables) - Traffic shaping variables (if applicable):
TRAFFIC_SHAPING_ENABLED,TRAFFIC_SHAPING_RATE_MBIT,TRAFFIC_SHAPING_MAX_BLOCKS_BEHIND - HA-specific variables (for HA files only)
Follow patterns from blueprints/solana/samples/ (single-client) or blueprints/ethereum/samples/ (multi-client).
STEP 7: GENERATE CONFIGURATION SCRIPTS
Create configuration scripts in configurations/ directory. There are two patterns depending on how the client runs:
Pattern A: Native binary (.sh) — used by Solana, BNB
For protocols that run as native binaries (not Docker), the configuration script serves dual purpose via an install/run dispatch:
installphase: downloads binary, snapshot, network config, initializes genesisrunphase (no args): exec's the node binary with runtime flags (systemd entrypoint)
The script must implement this dispatch pattern:
install_client() {
# Download binary, snapshot, network config, init genesis
}
run_node() {
exec /path/to/binary --flags...
}
case "${1:-run}" in
install) install_client ;;
run|"") run_node ;;
esac
node.sh calls "$CONFIG_SCRIPT" install during setup, then copies the script to /home/bcuser/bin/start-node.sh as the systemd service entrypoint (called with no args → run phase).
For the install phase:
- Download and verify client binary (checksum verification when available)
- Download snapshot if enabled (use shared helper in
user-data/common/if multiple client configs share the same snapshot mechanism) - Download network configuration files (genesis, config)
- Initialize the chain database (genesis init)
Pattern B: Docker-compose (.yml) — used by Ethereum, Base
For protocols that run via Docker, the configuration file is a docker-compose.yml with ${VARIABLE} placeholders. node.sh copies it to the working directory and substitutes variables with sed before starting via docker compose up -d.
The file must:
- Define services with proper image tags and versions
- Use
${EC2_INTERNAL_IP}for RPC binding (substituted by node.sh) - Mount /data, /secrets, and other required volumes
- Set security options (no-new-privileges, read-only where possible)
- Use host networking mode
File naming:
- Native binary:
{client}-{version}-{type}.sh(e.g.bsc-geth-v1.7.2-full.sh) - Docker-compose:
{client1}-{version1}-{client2}-{version2}-{type}.yml(e.g.geth-1.16.8-lighthouse-8.1.0-full.yml)
For both patterns:
- RPC must bind to
$EC2_INTERNAL_IP:{port}(not 0.0.0.0) - P2P must bind to
0.0.0.0:{port}for external connectivity - authrpc and metrics endpoints should bind to
127.0.0.1or$EC2_INTERNAL_IP(never 0.0.0.0 unless required by a separate consensus client on another host)
STEP 8: GENERATE user-data/node.sh
Create the protocol-level initialization script. This script handles concerns common across all client configurations for the protocol.
For native binary protocols (Pattern A), node.sh must:
- Source
/etc/cdk_environmentand validate required variables - Verify the configuration script exists at
/opt/blueprints/configurations/${CLIENT_CONFIG} - Create directory structure (
/data,/home/bcuser/bin, etc.) - Call the configuration script's install phase:
"$CONFIG_SCRIPT" install - Set ownership (
chown -R bcuser:bcuser /data /home/bcuser) - Copy the configuration script to
/home/bcuser/bin/start-node.sh - Create systemd service named "node" with:
User=bcuser,Group=bcuserEnvironmentFile=/etc/cdk_environmentExecStart=/home/bcuser/bin/start-node.sh
- Enable and start the service
- Touch
/data/init-completedsentinel
For Docker-based protocols (Pattern B), node.sh must:
- Source
/etc/cdk_environmentand validate required variables - Install Docker if not present
- Configure Docker logging (syslog driver)
- Add bcuser to docker group (
usermod -aG docker bcuser) - Create directory structure
- Copy the docker-compose.yml and substitute variables with
sed - Create systemd service that runs
docker compose up/down - Enable and start the service
- Touch
/data/init-completedsentinel
node.sh must NOT contain client-specific logic (binary URLs, version numbers, runtime flags). All of that belongs in the configuration script.
If multiple client configurations share common logic (e.g. snapshot download), extract it into user-data/common/ as a shared helper script.
Snapshot Staging for Large Snapshots: If the protocol has large snapshots where compressed_size + extracted_size > available /data space, the blueprint's download-snapshot.sh should:
- Set
SNAPSHOT_STAGING_VOL_SIZEin sample.envfiles to ~1.1x the compressed archive size - Source the shared staging helper:
source /opt/assets/common/snapshot-staging.sh 2>/dev/null || true - Call
staging_mount()before downloading (falls back to/dataif staging is disabled or fails) - Download to
$STAGING_DOWNLOAD_PATHinstead of/data - Extract from
$STAGING_DOWNLOAD_PATHto/data - Call
staging_cleanup()after successful extraction
See blueprints/base/user-data/common/download-snapshot.sh for a working example and docs/snapshot-staging.md for volume sizing guidance.
Follow the pattern from blueprints/bnb/user-data/node.sh (native binary) or blueprints/ethereum/user-data/node.sh (Docker-based).
STEP 9: GENERATE syncchecker.sh (IF APPLICABLE)
If traffic shaping is recommended (block time <10s):
- Create
user-data/syncchecker.sh - Script must:
- Query node for current sync status
- Calculate blocks/slots behind
- Report
c1_blocks_behindmetric to CloudWatch (namespace: CWAgent) - Control traffic shaping based on sync status
- Log activity for troubleshooting
Follow the pattern from blueprints/dummy/user-data/syncchecker.sh if it exists, or see docs/traffic-shaping.md for implementation guidance.
STEP 10: GENERATE README.md
Create comprehensive README following this exact structure:
- Title and Introduction: Protocol description and purpose
- Overview of Deployment Architectures: Single Node and HA (with diagrams)
- Supported Configurations: Table of available client configurations
- Infrastructure Requirements: Instance types, storage, network traffic tables
- Setup Instructions:
- Note linking to setup instructions — for a built-in blueprint reference the main README (
../../README.md); for an external blueprint link to Getting Started - Prerequisites (with AWS CloudShell tip)
- Step 1: Configure Environment
- Step 2: Choose Configuration (protocol-specific)
- Step 3: Deploy (with AI Alternative note)
- Step 4: Monitor Deployment
- Step 5: Verify Node Operation
- Note linking to setup instructions — for a built-in blueprint reference the main README (
- Configuration Options: Protocol-specific variables and settings
- Troubleshooting: Node Not Starting, Metrics Not Appearing, Health Check Failures, reference to main Troubleshooting Guide
- Upgrades: Upgrading Node Configuration, Rolling Updates (HA Only)
- Cost Optimization: Storage, Compute, Network
- Security Considerations: List of security best practices
- FAQ: Common questions in Q&A format (not collapsible)
- Additional Resources: Links to protocol docs and guides
- Support: Where to get help
Follow the exact structure from blueprints/dummy/README.md.
Critical README requirements:
- Include a note at the top of Setup Instructions linking to setup docs. For a built-in blueprint in
blueprints/, reference the main README (../../README.md). For an external blueprint, link to the website Getting Started page (Getting Started) instead, since../../README.mddoes not resolve outside the core repository. - Add AWS CloudShell tip in Prerequisites
- Add "AI Alternative" note after deploy command mentioning @deploy prompt
- Use CloudWatch Logs as primary diagnostic method in Troubleshooting
- Include proper log viewing commands with filter patterns
- Reference main Troubleshooting Guide at end of Troubleshooting section
- Keep FAQ answers direct (not in collapsible sections)
STEP 11: GENERATE MONITORING DASHBOARD (OPTIONAL)
If protocol has custom metrics or multi-client setup:
- Create
monitoring/single-node-dashboard-template.json - Include widgets for:
c1_block_height,c1_blocks_behindc2_block_height,c2_blocks_behind(if multi-client)- System metrics (CPU, memory, disk, network)
- Storage performance (latency, IOPS, throughput)
- Traffic shaping metrics (if applicable)
Follow the pattern from lib/common/monitoring-dashboards/single-node-dashboard-template.json.
STEP 12: VALIDATE GENERATED FILES
After generating all files:
- Validate package.json syntax:
cat node_modules/aws-bnr-blueprint-{protocol}/package.json | jq . - Ensure the blueprint is installed into
node_modules/(add to rootpackage.jsonand runnpm install) - Run
npx cdk synth— validates that all files referenced inavailableConfigurationsexist and user-data scripts are present - Verify file naming conventions are followed
- Ensure all patterns match dummy protocol
- Confirm bcuser permissions are set correctly
- Verify RPC binds to internal IP, P2P binds to 0.0.0.0
- Check metrics use CWAgent namespace with
c1_/c2_prefixes
Testing Your External Blueprint Locally
For Path B (external blueprints), test the package against a local checkout of Node Runners before publishing:
-
Install your blueprint into a Node Runners checkout:
git clone https://github.com/aws-samples/aws-blockchain-node-runners.gitcd aws-blockchain-node-runnersnpm installnpm install /path/to/your/blueprintPointing
npm installat the local blueprint directory links it intonode_modules/so theConfigurationLoaderresolves it like any published blueprint. -
Synthesize the stack to validate configuration files and user-data scripts resolve:
BLOCKCHAIN_PROTOCOL=<name> npx cdk synth -
Deploy to a test account using the sample
.envshipped with your blueprint:cp node_modules/aws-bnr-blueprint-<name>/samples/.env-testnet-<client>-<type> .env# Edit AWS_ACCOUNT_ID and AWS_REGIONnpx cdk deploy --json --outputs-file deploy-output.json
Verify the node operates correctly (see STEP 13 for verification commands), then clean up with npx cdk destroy.
STEP 13: PROVIDE TESTING INSTRUCTIONS
Guide the user on testing the implementation:
-
Deploy to Testnet:
cp node_modules/aws-bnr-blueprint-{protocol}/samples/.env-testnet-{client}-{type} .env# Edit AWS_ACCOUNT_ID and AWS_REGIONnpx cdk deploy --json --outputs-file deploy-output.json -
Verify Node Operation:
export INSTANCE_ID=$(cat deploy-output.json | jq -r '..|.InstanceId? | select(. != null)')aws ssm start-session --target $INSTANCE_ID --region $AWS_REGIONsudo systemctl status nodesudo journalctl -u node -f -
Check Metrics: View CloudWatch dashboard, verify
c1_block_heightandc1_blocks_behindmetrics appear -
Test Traffic Shaping (if implemented):
sudo systemctl status net-rules.servicesudo journalctl -u syncchecker.service -n 50 -
Clean Up:
npx cdk destroy
ERROR HANDLING
- If documentation URL is inaccessible: Ask the user to provide documentation as a local file, or offer to proceed with available information and iterate
- If infrastructure requirements are unclear: Ask for clarification, provide conservative recommendations with justification
- If protocol has unique requirements: Ask for additional details, explain how to adapt the standard patterns
GUIDELINES
DO:
- Always read
blueprints/dummy/as the primary template - Always read protocol documentation before making recommendations
- Present infrastructure research for review before generating files
- Follow file naming conventions exactly
- Use install/run dispatch for native binaries, docker-compose.yml for Docker
- Extract shared logic into
user-data/common/ - Implement traffic shaping for protocols with block time <10s
- Ensure all scripts pass
shellcheck -S warningwith no findings - Validate with
npx cdk synthbefore declaring success
DO NOT:
- Never use protocol-specific service names (always "node")
- Never run services as root (always bcuser)
- Never bind RPC, authrpc, or metrics to 0.0.0.0
- Never use protocol-specific metrics namespaces (always CWAgent)
- Never guess configuration values
- Never skip bcuser setup or permissions
- Never put client-specific logic (binary URLs, versions, flags) in node.sh
- Never skip the infrastructure research step
CRITICAL PATTERNS
| Pattern | Correct | Wrong |
|---|---|---|
| Service name | node | protocol-specific name |
| Service user | bcuser (UID 1002, GID 1002) | root |
| Systemd EnvironmentFile | /etc/cdk_environment | hardcoded values |
| RPC binding | $EC2_INTERNAL_IP:{port} | 0.0.0.0:{port} |
| P2P binding | 0.0.0.0:{port} | $EC2_INTERNAL_IP:{port} |
| authrpc/metrics binding | 127.0.0.1 or $EC2_INTERNAL_IP | 0.0.0.0 |
| Metrics namespace | CWAgent | custom namespace |
| Metrics naming | c1_block_height, c1_blocks_behind | custom names |
| Multi-client metrics | c2_block_height, c2_blocks_behind | — |
| Native config file | {client}-{version}-{type}.sh | arbitrary naming |
| Docker config file | {client1}-{version1}-{client2}-{version2}-{type}.yml | arbitrary naming |
| Sample naming (single) | .env-{network}-{client}-{type} | arbitrary naming |
| Sample naming (multi) | .env-{network}-{client1}-{client2}-{type} | arbitrary naming |
| HA variant | append -ha | separate directory |
Publishing and Listing
Once an external blueprint (Path B) is tested, distribute it so users can install it into their own Node Runners checkout. Choose one or more of the following:
- NPM Registry: Publish the package with
npm publish. Users then install it withnpm install aws-bnr-blueprint-<protocol>. - GitHub: Push the blueprint to a public repository. Users can install directly from the repo with
npm install github:org/repo. - Community Catalog: Open a pull request to add an entry for your blueprint to the Community Blueprints Catalog page so others can discover it.
After installation by any method, the blueprint lands in node_modules/ and the ConfigurationLoader resolves it identically to a built-in blueprint — users deploy it with BLOCKCHAIN_PROTOCOL=<protocol> npx cdk deploy.