This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Using Solo

Explore practical applications and integrations for Solo. This section covers using Solo networks with the JavaScript SDK, integrating with external tools, and building applications on Hiero consensus nodes.

1 - Accessing Solo Services

Learn how to locate and connect to ancillary services deployed alongside Solo networks, including Mirror Node Explorer, Block Nodes, and JSON-RPC Relay services.

1.1 - Using Solo with Mirror Node

Add Mirror Node to a Solo network to stream and query transaction records, account history, and token data via the Hiero Mirror Node REST API.

Overview

The Hiero Mirror Node stores the full transaction history of your local Solo network and exposes it through several interfaces:

  • A web-based block explorer (Hiero Mirror Node Explorer) at http://localhost:8080.
  • A REST API via the mirror-ingress service at http://localhost:8081 (recommended entry point-routes to the correct REST implementation).
  • A gRPC endpoint for mirror node subscriptions.

This guide walks you through adding Mirror Node and the Hiero Explorer to a Solo network, and shows you how to query transaction data and create accounts.


Prerequisites

Before proceeding, ensure you have completed the following:

  • System Readiness - your local environment meets all hardware and software requirements, including Docker and Solo.

  • Quickstart - you have a running Solo network deployed using solo one-shot single deploy.

  • To find your deployment name at any time, run:

    cat ~/.solo/cache/last-one-shot-deployment.txt
    

Step 1: Deploy Solo with Mirror Node

Note: If you deployed your network using one-shot, Falcon, or the Task Tool, Mirror Node is already running - skip to Step 2: Access the Mirror Node Explorer.

Fresh manual Deployment

If you are building a custom network or adding the mirror node to an existing deployment, run the following commands in sequence:

# Set environment variables
export SOLO_CLUSTER_NAME=solo-cluster
export SOLO_NAMESPACE=solo-e2e
export SOLO_CLUSTER_SETUP_NAMESPACE=solo-cluster-setup
export SOLO_DEPLOYMENT=solo-deployment

# Reset environment
rm -Rf ~/.solo
kind delete cluster -n "${SOLO_CLUSTER_NAME}"
kind create cluster -n "${SOLO_CLUSTER_NAME}"

# Initialize Solo and configure cluster
solo init
solo cluster-ref config setup \
  --cluster-setup-namespace "${SOLO_CLUSTER_SETUP_NAMESPACE}"
solo cluster-ref config connect \
  --cluster-ref ${SOLO_CLUSTER_NAME} \
  --context kind-${SOLO_CLUSTER_NAME}

# Create deployment
solo deployment config create \
  --namespace "${SOLO_NAMESPACE}" \
  --deployment "${SOLO_DEPLOYMENT}"
solo deployment cluster attach \
  --deployment "${SOLO_DEPLOYMENT}" \
  --cluster-ref ${SOLO_CLUSTER_NAME} \
  --num-consensus-nodes 2

# Generate keys and deploy consensus nodes
solo keys consensus generate \
  --deployment "${SOLO_DEPLOYMENT}" \
  --gossip-keys --tls-keys \
  -i node1,node2
solo consensus network deploy --deployment "${SOLO_DEPLOYMENT}" -i node1,node2
solo consensus node setup --deployment "${SOLO_DEPLOYMENT}" -i node1,node2
solo consensus node start --deployment "${SOLO_DEPLOYMENT}" -i node1,node2

# Add mirror node and explorer
solo mirror node add \
  --deployment "${SOLO_DEPLOYMENT}" \
  --cluster-ref ${SOLO_CLUSTER_NAME} \
  --enable-ingress \
  --pinger
solo explorer node add \
  --deployment "${SOLO_DEPLOYMENT}" \
  --cluster-ref ${SOLO_CLUSTER_NAME}

Note: The --pinger flag in solo mirror node add starts a background service that sends transactions to the network at regular intervals. This is required because mirror node record files are only imported when a new record file is created - without it, the mirror node will appear empty until the next transaction occurs naturally.


Step 2: Access the Mirror Node Explorer

Once Mirror Node is running, open the Hiero Explorer in your browser at:

http://localhost:8080

The Explorer lets you browse accounts, transactions, tokens, and contracts on your Solo network in real time.


Step 3: Create Accounts and View Transactions

Create test accounts and observe them appearing in the Explorer:

solo ledger account create --deployment solo-deployment --hbar-amount 100
solo ledger account create --deployment solo-deployment --hbar-amount 100

Open the Explorer at http://localhost:8080 to see the new accounts and their transactions recorded by the Mirror Node.

You can also use the Hiero JavaScript SDK to create a topic, submit a message, and subscribe to it.


Step 4: Access Mirror Node APIs

Option A: Mirror-Ingress (localhost:8081)

Use localhost:8081 for all Mirror Node REST API access. The mirror-ingress service routes requests to the correct REST implementation automatically. This is important because certain endpoints are only supported in the newer rest-java version.

# List recent transactions
curl -s "http://localhost:8081/api/v1/transactions?limit=5"

# Get account details
curl -s "http://localhost:8081/api/v1/accounts/0.0.2"

Note: localhost:5551 (the legacy Mirror Node REST API) is being phased out. Always use localhost:8081 to ensure compatibility with all endpoints.

If you need to access it directly:

kubectl port-forward svc/mirror-1-rest -n "${SOLO_NAMESPACE}" 5551:80 &
curl -s "http://${REST_IP:-127.0.0.1}:5551/api/v1/transactions?limit=1"

Option B: Mirror Node gRPC

For mirror node gRPC subscriptions (e.g. topic messages, account balance updates), enable port-forwarding manually if not already active:

kubectl port-forward svc/mirror-1-grpc -n "${SOLO_NAMESPACE}" 5600:5600 &

Then verify available services:

grpcurl -plaintext "${GRPC_IP:-127.0.0.1}:5600" list

Option C: Mirror Node REST-Java (Direct Access)

For direct access to the rest-java service (bypassing the ingress):

kubectl port-forward service/mirror-1-restjava -n "${SOLO_NAMESPACE}" 8084:80 &

# Example: NFT allowances
curl -s "http://${REST_IP:-127.0.0.1}:8084/api/v1/accounts/0.0.2/allowances/nfts"

In most cases you should use localhost:8081 instead.


Port Reference

ServiceLocal PortAccess Method
Hiero Explorer8080Browser (--enable-ingress)
Mirror Node (all-in-one)8081HTTP (--enable-ingress)
Mirror Node REST API5551kubectl port-forward
Mirror Node gRPC5600kubectl port-forward
Mirror Node REST Java8084kubectl port-forward

Restoring Port-Forwards

If port-forwards are interrupted-for example after a system restart-restore them without redeploying:

solo deployment refresh port-forwards

Tearing Down

To remove the Mirror Node from a running deployment:

solo mirror node destroy --deployment "${SOLO_DEPLOYMENT}" --force

To remove the Hiero Mirror Node Explorer:

solo explorer node destroy --deployment "${SOLO_DEPLOYMENT}" --force

For full network teardown, see Step-by-Step Manual Deployment-Cleanup.

2 - Using Solo with Hiero JavaScript SDK

Walk through submitting your first transaction to a local Solo network using the Hiero JavaScript SDK.

Overview

The Hiero JavaScript SDK lets you build and test applications on the Hiero network using JavaScript or TypeScript. This guide walks you through launching a local Solo network, creating a funded test account, connecting the SDK, and running example scripts to submit your first transaction.


Prerequisites

Before proceeding, ensure you have completed the following:

  • System Readiness:
    • Your local environment meets all hardware and software requirements, including Docker, kubectl, and Solo.

    • You will need the following tools installed:

      RequirementVersionPurpose
      Docker DesktopLatestRuns the Solo cluster containers
      SoloLatestDeploys and manages the local network
      Node.jsv18 or higherRuns the SDK examples
      TaskfileLatestRuns convenience scripts in the Solo repo

Note: Solo uses Docker Desktop to spin up local Hiero consensus and mirror nodes. Ensure Docker Desktop is running before executing any task commands.


Step 1: Launch a Local Solo Network

Clone the Solo repository and navigate into the scripts directory, then start the network with the mirror node and Hiero Explorer:

# Clone Solo repo
git clone https://github.com/hiero-ledger/solo.git
cd solo
# Launch a local Solo network with mirror node and Hiero Explorer
cd scripts
task default-with-mirror

This command starts:

  • Creates a local Kind Kubernetes cluster.
  • Deploys a local Hiero consensus node.
  • A mirror node for transaction history queries , and Hiero Explorer.

Once complete, the Hiero Explorer is available at: http://localhost:8080/localnet/dashboard.


Step 2: Install the Hiero JavaScript SDK

  • Clone the Hiero JavaScript SDK repository and install its dependencies:

    git clone https://github.com/hiero-ledger/hiero-sdk-js.git
    cd hiero-sdk-js
    npm install
    
  • The SDK provides classes for building and submitting transactions (e.g., AccountCreateTransaction, TopicCreateTransaction) and for reading receipts and query responses from the network.


Step 3: Create a Test Account

  • With your Solo network running, create a funded operator account with 100 HBAR that your scripts will use to sign and pay for transactions.

  • From the solo repository root, run:

    npm run solo-test -- ledger account create \
      --deployment solo-deployment \
      --hbar-amount 100
    
  • Example output:

    *** new account created ***
    -------------------------------------------------------------------------------
    {
    "accountId": "0.0.1007",
    "publicKey": "302a300506032b65700321001d8978e647aca1195c54a4d3d5dc469b95666de14e9b6edde8ed337917b96013",
    "balance": 100
    }
    

Note the accountId value (0.0.1007 in this example). You will use it in the next step.

Retrieve the Private Key

  • To sign transactions you need the account’s private key. Retrieve it with:

    npm run solo-test -- ledger account info \
    --account-id 0.0.1007 \
    --deployment solo-deployment \
    --private-key
    
  • Expected output:

    {
      "accountId": "0.0.1007",
      "privateKey": "302e020100300506032b657004220420411a561013bceabb8cb83e3dc5558d052b9bd6a8977b5a7348bf9653034a29d7",
      "privateKeyRaw": "411a561013bceabb8cb83e3dc5558d052b9bd6a8977b5a7348bf9653034a29d7",
      "publicKey": "302a300506032b65700321001d8978e647aca1195c54a4d3d5dc469b95666de14e9b6edde8ed337917b96013",
      "balance": 100
    }
    
  • Save the accountId and privateKey values - you will configure the SDK with them in the next step.


Step 4: Configure the SDK to Connect to Solo

  • The Hiero JavaScript SDK uses environment variables to locate the network and authenticate the operator account. Create a .env file at the root of the hiero-sdk-js directory:

    # Navigate to the SDK root
    cd hiero-sdk-js
    
    # Create the environment file
    cat > .env <<EOF
    
    # Operator account ID (accountId from Step 3)
    export OPERATOR_ID="0.0.1007"
    
    # Operator private key (not publicKey) from Step 3
    export OPERATOR_KEY="302e020100300506032b657004220420411a561013bceabb8cb83e3dc5558d052b9bd6a8977b5a7348bf9653034a29d7"
    
    # Target the local Solo network
    export HEDERA_NETWORK="local-node"
    EOF
    
    # Load the variables into your current shell session
    source .env
    

    Important: OPERATOR_KEY must be set to the privateKey value, not the publicKey. The private key is the longer DER-encoded string beginning with 302e....

  • When HEDERA_NETWORK is set to "local-node", the SDK automatically connects to the Solo consensus node at localhost:50211 and the mirror node REST API at localhost:5551.


Step 5: Submit Your First Transaction

Example 1: Create an Account (AccountCreateTransaction)

  • This example uses AccountCreateTransaction to create a new account on your local Solo network, waits for consensus, and prints the resulting receipt.

    node examples/create-account.js
    
  • Expected output:

    private key = 302e020100300506032b6570042204208a3c1093c4df779c4aa980d20731899e0b509c7a55733beac41857a9dd3f1193
    public key = 302a300506032b6570032100c55adafae7e85608ea893d0e2c77e2dae3df90ba8ee7af2f16a023ba2258c143
    account id = 0.0.1009
    

What happened:

  1. The SDK built an AccountCreateTransaction signed by your operator key.
  2. The transaction was submitted to the Solo consensus node.
  3. The SDK polled for the transaction receipt until consensus was reached.
  4. The receipt confirmed the new account ID (0.0.1009).

Example 2: Create a Topic (TopicCreateTransaction)

  • The Hiero Consensus Service (HCS) lets you create topics and publish messages to them. Run the topic creation example:

    node examples/create-topic.js
    
  • Expected output:

    topic id = 0.0.1008
    topic sequence number = 1
    

What happened:

  1. The SDK submitted a TopicCreateTransaction.
  2. After consensus, the receipt returned a new topic ID (0.0.1008).
  3. A test message was published and its sequence number confirmed.

Verify both transactions in the Hiero Explorer: http://localhost:8080/localnet/dashboard.


Step 6: Tear Down the Network

When you are finished, stop and remove all Solo containers:

# Run from the solo/scripts directory
cd solo/scripts
task clean

This removes the local consensus node, mirror node, and all associated data volumes.


Read a Transaction Receipt

  • Every transaction submitted via the Hiero JavaScript SDK returns a TransactionReceipt after reaching consensus. A receipt includes:

    FieldDescription
    statusSUCCESS if consensus was reached, otherwise an error code
    accountIdSet when an account was created
    topicIdSet when a topic was created
    fileIdSet when a file was created
    topicSequenceNumberSequence number of an HCS message
  • In your own TypeScript/JavaScript code, the pattern looks like this:

    import {
      Client,
      AccountCreateTransaction,
      PrivateKey,
      Hbar,
    } from "@hashgraph/sdk";
    
    // Configure the client to connect to the local Solo network
    const client = Client.forLocalNode();
    client.setOperator(
      process.env.OPERATOR_ID!,
      process.env.OPERATOR_KEY!
    );
    
    // Build and submit the transaction
    const newKey = PrivateKey.generateED25519();
    const response = await new AccountCreateTransaction()
      .setKey(newKey.publicKey)
      .setInitialBalance(new Hbar(10))
      .execute(client);
    
    // Wait for consensus and read the receipt
    const receipt = await response.getReceipt(client);
    
    console.log(`Transaction status : ${receipt.status}`);
    console.log(`New account ID     : ${receipt.accountId}`);
    

    Tip: If receipt.status is not SUCCESS, the SDK throws a ReceiptStatusError with the error code. Common causes on a fresh Solo network are insufficient HBAR balance or a misconfigured operator key.


Optional: Manage Files on the Network

Solo provides CLI commands to create and update files stored on the Hiero File Service.

Create a New File

npm run solo-test -- ledger file create \
  --deployment solo-deployment \
  --file-path ./config.json

This command:

  • Creates a new file on the network and returns a system-assigned file ID.
  • Automatically splits files larger than 4 KB into chunks using FileAppendTransaction.
  • Verifies that the uploaded content matches the local file.

Example output:

✓ Initialize configuration
  File: config.json
  Size: 2048 bytes

✓ Load node client and treasury keys

✓ Create file on Hiero network
  ✓ Create new file
    Creating file with 2048 bytes...
    ✓ File created with ID: 0.0.1234

✓ Verify uploaded file
  Querying file contents to verify upload...
  Expected size: 2048 bytes
  Retrieved size: 2048 bytes
  ✓ File verification successful
  ✓ Size: 2048 bytes
  ✓ Content matches uploaded file

✅ File created successfully!
📄 File ID: 0.0.1234

Update an existing file

npm run solo-test -- ledger file update \
  --deployment solo-deployment \
  --file-id 0.0.1234 \
  --file-path ./updated-config.json

This command:

  • Verifies the file exists on the network (errors if not found).
  • Replaces the file content and re-verifies the upload.
  • Automatically handles chunking for large files (>4 KB).

Example output:

✓ Initialize configuration
  File: updated-config.json
  Size: 3072 bytes
  File ID: 0.0.1234

✓ Load node client and treasury keys

✓ Check if file exists
  File 0.0.1234 exists. Proceeding with update.
  Current size: 2048 bytes
  Keys: 1

✓ Update file on Hiero network
  ✓ Update existing file
    Updating file with 3072 bytes...
    ✓ File updated successfully

✓ Verify uploaded file
  Querying file contents to verify upload...
  Expected size: 3072 bytes
  Retrieved size: 3072 bytes
  ✓ File verification successful
  ✓ Size: 3072 bytes
  ✓ Content matches uploaded file

✅ File updated successfully!

Note: For files larger than 4 KB, both commands split content into 4 KB chunks and display per-chunk progress during the append phase.

✓ Create file on Hiero network
  ✓ Create new file
    Creating file with first 4096 bytes (multi-part create)...
    ✓ File created with ID: 0.0.1234
  ✓ Append remaining file content (chunk 1/3)
    Appending chunk 1/3 (4096 bytes, 8192 bytes remaining)...
  ✓ Append remaining file content (chunk 2/3)
    Appending chunk 2/3 (4096 bytes, 4096 bytes remaining)...
  ✓ Append remaining file content (chunk 3/3)
    Appending chunk 3/3 (4096 bytes, 0 bytes remaining)...
  ✓ Append remaining file content (3 chunks completed)
    ✓ Appended 3 chunks successfully

Inspect Transactions in Hiero Explorer

While your Solo network is running, open the Hiero Explorer to visually inspect submitted transactions, accounts, topics, and files:

http://localhost:8080/localnet/dashboard

You can search by account ID, transaction ID, or topic ID to confirm that your transactions reached consensus and view their receipts.


Retrieving Logs

Solo writes logs to ~/.solo/logs/:

Log FileContents
solo.logAll Solo CLI command output and lifecycle events
hashgraph-sdk.logSDK-level transaction submissions and responses sent to network nodes

These logs are useful for debugging failed transactions or connectivity issues between the SDK and your local Solo network.


Troubleshooting

SymptomLikely CauseFix
INVALID_SIGNATURE receipt errorOPERATOR_KEY set to public key instead of private keyRe-check your .env - use the privateKey field value
INSUFFICIENT_TX_FEEOperator account has no HBARRe-create the account with --hbar-amount 100
SDK cannot connectSolo network not running or Docker not startedRun task default-with-mirror and wait for full startup
HEDERA_NETWORK not recognized.env not sourcedRun source .env before executing example scripts

3 - Using Solo with EVM Tools

Point your existing Ethereum tooling (Hardhat, ethers.js, and MetaMask) at a local Hiero network via the Hiero JSON-RPC relay. This document covers enabling the relay, creating and configuring a Hardhat project, deploying a Solidity contract, and configuring wallets.

Overview

Hiero is EVM-compatible. The Hiero JSON-RPC relay exposes a standard Ethereum JSON-RPC interface on your local Solo network, letting you use familiar EVM tools without modification.

This guide walks you through:

  • Launching a Solo network with the JSON-RPC relay enabled.
  • Retrieving ECDSA accounts for EVM tooling.
  • Creating and configuring a Hardhat project against the relay.
  • Deploying and interacting with a Solidity contract.
  • Verifying transactions via the Explorer and Mirror Node.
  • Configuring ethers.js and MetaMask.

Prerequisites

Before proceeding, ensure you have completed the following:

  • System Readiness - your local environment meets all hardware and software requirements, including Docker and Solo.
  • Quickstart - you are comfortable running Solo deployments.

You will also need:


Step 1: Launch a Solo Network with the JSON-RPC Relay

The easiest way to start a Solo network with the relay pre-configured is via one-shot single deploy, which provisions the consensus node, mirror node, Hiero Mirror Node Explorer, and the Hiero JSON-RPC relay in a single step:

npx @hashgraph/solo one-shot single deploy

This command:

  • Creates a local Kind Kubernetes cluster.
  • Deploys a Hiero consensus node, mirror node, and Hiero Mirror Node Explorer.
  • Deploys the Hiero JSON-RPC relay and exposes it at http://localhost:7546.
  • Generates three groups of pre-funded accounts, including ECDSA (EVM-compatible) accounts.

Relay endpoint summary:

PropertyValue
RPC URLhttp://localhost:7546
Chain ID298
Currency symbolHBAR

Adding the Relay to an Existing Deployment

If you already have a running Solo network without the relay, see Step 10: Deploy JSON-RPC Relay in the Step-by-Step Manual Deployment guide for full instructions, then return here once your relay is running on http://localhost:7546.

To remove the relay when you no longer need it, see Cleanup Step 1: Destroy JSON-RPC Relay in the same guide.


Step 2: Retrieve Your ECDSA Account and Private Key

one-shot single deploy creates ECDSA alias accounts, which are required for EVM tooling such as Hardhat, ethers.js, and MetaMask. These accounts and their private keys are saved to a cache directory on completion.

Note: ED25519 accounts are not compatible with Hardhat, ethers.js, or MetaMask when used via the JSON-RPC interface. Always use the ECDSA keys from accounts.json for EVM tooling.

  • To find your deployment name, run:

    cat ~/.solo/cache/last-one-shot-deployment.txt
    
  • Then open the accounts file at:

    ~/.solo/cache/one-shot-<deployment-name>/accounts.json
    
  • Open that file to retrieve your ECDSA keys and EVM address. Each account entry contains:

    • An ECDSA private key - 64 hex characters with a 0x prefix (e.g. 0x105d0050...).
    • An ECDSA public key - the corresponding public key.
    • An EVM address - derived from the public key (e.g. 0x70d379d473e2005bb054f50a1d9322f45acb215a). In Hiero terminology, this means the account has an EVM address aliased from its ECDSA public key.
    0x105d0050185ccb907fba04dd92d8de9e32c18305e097ab41dadda21489a211524
    0x2e1d968b041d84dd120a5860cee60cd83f9374ef527ca86996317ada3d0d03e7
    ...
    
  • Export the private key for one account as an environment variable - never hardcode private keys in source files:

    export SOLO_EVM_PRIVATE_KEY="0x105d0050185ccb907fba04dd92d8de9e32c18305e097ab41dadda21489a211524"
    

Step 3: Create and Configure a Hardhat Project

A ready-to-run Hardhat project is provided in the Solo repository. Skip to Step 4 after cloning:

git clone https://github.com/hiero-ledger/solo.git
cd solo/examples/hardhat-with-solo/hardhat-example
npm install

Option B: Create a New Hardhat Project from Scratch

If you want to integrate Solo into your own project:

mkdir solo-hardhat && cd solo-hardhat
npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npx hardhat init

When prompted, choose TypeScript project or JavaScript project based on your preference.

Install dependencies:

npm install

Configure Hardhat to Connect to the Solo Relay

Create or update hardhat.config.ts to point at the Solo JSON-RPC relay. The chainId of 298 is required - Hardhat will reject transactions if it does not match the network:

import type { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";

const config: HardhatUserConfig = {
  solidity: "0.8.28",
  networks: {
    solo: {
      url: "http://127.0.0.1:7546",
      chainId: 298,
      // Load from environment — never commit private keys to source control
      accounts: process.env.SOLO_EVM_PRIVATE_KEY
        ? [process.env.SOLO_EVM_PRIVATE_KEY]
        : [],
    },
  },
};

export default config;

Important: chainId: 298 must be set explicitly. Without it, Hardhat’s network validation will fail when connecting to the Solo relay.


Step 4: Deploy and Interact with a Solidity Contract

The Sample Contract

If using the pre-built Solo example, contracts/SimpleStorage.sol is included. For a new project, create contracts/SimpleStorage.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract SimpleStorage {
    uint256 private value;

    event ValueChanged(
        uint256 indexed oldValue,
        uint256 indexed newValue,
        address indexed changer
    );

    constructor(uint256 initial) {
        value = initial;
    }

    function get() external view returns (uint256) {
        return value;
    }

    function set(uint256 newValue) external {
        uint256 old = value;
        value = newValue;
        emit ValueChanged(old, newValue, msg.sender);
    }
}

Compile the Contract

npx hardhat compile

Expected output:

Compiled 1 Solidity file successfully (evm target: paris).

Run the Tests

npx hardhat test --network solo

For the pre-built example, the test suite covers three scenarios:

  SimpleStorage
    ✔ deploys with initial value
    ✔ updates value and emits ValueChanged event
    ✔ allows other accounts to set value

  3 passing (12s)

Deploy via a Script

To deploy SimpleStorage to your Solo network using a deploy script:

npx hardhat run scripts/deploy.ts --network solo

A minimal scripts/deploy.ts looks like:

import { ethers } from "hardhat";

async function main() {
  const SimpleStorage = await ethers.getContractFactory("SimpleStorage");
  const contract = await SimpleStorage.deploy(42);
  await contract.waitForDeployment();

  console.log("SimpleStorage deployed to:", await contract.getAddress());
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

Step 5: Send a Transaction with ethers.js

To submit a transaction directly from a script using ethers.js via Hardhat:

import { ethers } from "hardhat";

async function main() {
  const [sender] = await ethers.getSigners();
  console.log("Sender:", sender.address);

  const balance = await ethers.provider.getBalance(sender.address);
  console.log("Balance:", ethers.formatEther(balance), "HBAR");

  const tx = await sender.sendTransaction({
    to: sender.address,
    value: 10_000_000_000n,
  });

  await tx.wait();
  console.log("Transaction confirmed. Hash:", tx.hash);
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});

Run it with:

npx hardhat run scripts/send-tx.ts --network solo

Step 6: Verify Transactions

Confirm your transactions reached consensus using any of the following:

Hiero Mirror Node Explorer

http://localhost:8080/localnet/dashboard

Search by account address, transaction hash, or contract address to view transaction details and receipts.

Hiero Mirror Node REST API

http://localhost:8081/api/v1/transactions?limit=5

Returns the five most recent transactions in JSON format. Useful for scripted verification.

Note: localhost:5551 (the legacy Mirror Node REST API) is being phased out. Always use localhost:8081 to ensure compatibility with all endpoints.

Hiero JSON RPC Relay (eth_getTransactionReceipt)

curl -X POST http://localhost:7546 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xYOUR_TX_HASH"],"id":1}'

Step 7: Configure MetaMask

To connect MetaMask to your local Solo network:

  1. Open MetaMask and go to Settings → Networks → Add a network → Add a network manually.

  2. Enter the following values:

    FieldValue
    Network nameSolo Local
    New RPC URLhttp://localhost:7546
    Chain ID298
    Currency symbolHBAR
    Block explorer URLhttp://localhost:8080/localnet/dashboard (optional)
  3. Click Save and switch to the Solo Local network.

  4. Import an account using an ECDSA private key from accounts.json:

    • Click the account icon → Import account.
    • Paste the private key (with 0x prefix).
    • Click Import.

Your MetaMask wallet is now connected to the local Solo network and funded with the pre-allocated HBAR balance.


Step 8: Tear Down the Network

When finished, destroy the Solo deployment and all associated containers:

npx @hashgraph/solo one-shot single destroy

If you added the relay manually to an existing deployment:

solo relay node destroy --deployment "${SOLO_DEPLOYMENT}"

Reference: Running the Full Example Automatically

The hardhat-with-solo example includes a Taskfile.yml that automates all steps - deploy network, install dependencies, compile, and test - in a single command:

cd solo/examples/hardhat-with-solo
task

To tear everything down:

task destroy

This is useful for CI pipelines. See the Solo deployment with Hardhat Example for full details.


Troubleshooting

SymptomLikely CauseFix
connection refused on port 7546Relay not runningRun one-shot single deploy or solo relay node add
invalid sender or signature errorUsing ED25519 key instead of ECDSAUse ECDSA keys from accounts.json
Hardhat chainId mismatch errorMissing or wrong chainId in configSet chainId: 298 in hardhat.config.ts
MetaMask shows wrong networkChain ID mismatchEnsure Chain ID is 298 in MetaMask network settings
INSUFFICIENT_TX_FEE on transactionAccount not fundedUse a pre-funded ECDSA account from accounts.json
Hardhat test timeoutNetwork not fully startedWait for one-shot to fully complete before running tests
Port 7546 already in useAnother process is using the portRun lsof -i :7546 and stop the conflicting process

Further Reading

4 - Using Network Load Generator with Solo

Learn how to run load tests against a Solo network using the Network Load Generator (NLG). Generate realistic transaction flows and stress-test your deployment to verify performance under load.

Using Network Load Generator with Solo

The Network Load Generator (NLG) is a benchmarking tool that stress tests Hiero networks by generating configurable transaction loads. Use it to validate the performance and stability of your Solo network before deploying to production or running integration tests.

Prerequisites

Before proceeding, ensure you have completed the following:

  • System Readiness — your local environment meets all hardware and software requirements.
  • Quickstart — you have a running Solo network and are familiar with the basic Solo workflow.

Step 1: Start a Load Test

Use the rapid-fire load start command to install the NLG Helm chart and begin a load test against your deployment.

   npx @hashgraph/solo@latest rapid-fire load start \
 --deployment <deployment-name> \
 --args '"-c 3 -a 10 -t 60"' \
 --test CryptoTransferLoadTest

Replace <deployment-name> with your deployment name. You can find it by running:

cat ~/.solo/cache/last-one-shot-deployment.txt

The --args flag passes arguments directly to the NLG. In this example:

  • -c 3 — 3 concurrent threads
  • -a 10 — 10 accounts
  • -t 60 — run for 60 seconds

Step 2: Run Multiple Load Tests (Optional)

You can run additional load tests in parallel from a separate terminal. Each test runs independently against the same deployment:

    npx @hashgraph/solo@latest rapid-fire load start \
  --deployment <deployment-name> \
  --args '"-c 3 -a 10 -t 60"' \
  --test NftTransferLoadTest

Step 3: Stop a Specific Load Test

To stop a single running load test before it completes, use the stop command:

    npx @hashgraph/solo@latest rapid-fire load stop \
  --deployment <deployment-name> \
  --test CryptoTransferLoadTest

Step 4: Tear Down All Load Tests

To stop all running load tests and uninstall the NLG Helm chart:

    npx @hashgraph/solo@latest rapid-fire destroy all \
  --deployment <deployment-name>

Complete Example

For an end-to-end walkthrough with a full configuration, see the examples/rapid-fire.

Available Tests and Arguments

A full list of all available rapid-fire commands can be found in Solo CLI Reference.