# Configuration File Usage

`pysubnet` allows you to define your network configuration using a file instead of command-line arguments for each node. This is particularly useful for managing larger or more complex network setups.

The main purpose of this file is to define your nodes and additionally, specify the balances the generated validatorId keys would get as it's a very common operation to specify balances for your authority set.

Additionally, this file can also do some chainspec customizations for you if you're not passing in `--chainspec` which declares that you intend to override the chainspec defined in the `network` section of this file.

Supported items are `tokenSymbol`, `tokenDecimals`, `ss58Format` (via `network.chain.number`), and additionally `frontier.evm.accounts` and `frontier.evm.chainId` for frontier-based chains. Take a look at [frontier-nodes](../config-examples/frontier-nodes.json) for an example. 

See [config-examples](../config-examples/nodes.toml) for what's possible

## Using the `--config` Flag

To use a configuration file, pass the path to the file using the `--config` or `-f` flag:

```bash
pysubnet --config path/to/your/config.<toml | json>
```

or

```bash
pysubnet -f path/to/your/config.<toml | json>
```

## Configuration File Format

The configuration file can be in either **TOML** or **JSON** format.

### TOML Example (`nodes.toml`)

```toml
# filepath: ./nodes.toml
[network]
token-symbol = "TST" # customizations such as this don't take effect if you use --chainspec
token-decimal = 12 
remove-existing-balances = true # Removes existing balances in the genesis block, if any present

[network.chain]
name = "My Awesome Network" # Name for your network
chain-id = "my_local"             # machine identifiable identifier for the chain
chain-type = "Live"               # ChainType, one of Live, Development, Local or Custom(String) https://docs.rs/sp-chain-spec/3.0.0/sp_chain_spec/enum.ChainType.html
number = 42                       # SS58 format number (0+) - sets ss58Format in chainspec properties

[[nodes]]
name = "elizabeth"
p2p-port = 30333
rpc-port = 9943
prometheus-port = 9613
balance = 4000 # x units multiplied by 10**token-decimal - populates pallet-balances balance

[[nodes]]
name = "rachel"
p2p-port = 30334
rpc-port = 9944
prometheus-port = 9614
balance = 5000 # balances get put into the validator-id pubkey generated by pysubnet    

[[nodes]]
name = "skyler"
p2p-port = 30336
rpc-port = 9946
prometheus-port = 9616
# balance not specified, so will get 0 balance
```

### JSON Example (`nodes.json`)

```json
// filepath: ./nodes.json
{
    "network": {
      "token-symbol": "TST",
      "token-decimal": 12,
      "remove-existing-balances": true,
      "chain": {
        "name": "My Awesome Network",
        "chain-id": "my_local",
        "chain-type": "Live",
        "number": 42
      }
    },
    "nodes": [
      {
        "name": "elizabeth",
        "p2p-port": 30333,
        "rpc-port": 9943,
        "prometheus-port": 9613,
        "balance": 4000
      },
      {
        "name": "rachel",
        "p2p-port": 30334,
        "rpc-port": 9944,
        "prometheus-port": 9614,
        "balance": 5000
      },
      {
        "name": "skyler",
        "p2p-port": 30336,
        "rpc-port": 9946,
        "prometheus-port": 9616
      }
    ]
  }
```

# Balance Injection Configuration

This feature allows you to inject custom balances for specific addresses into your chainspec through the configuration file. This is useful for funding specific accounts, smart contracts, or testing scenarios.

## Configuration Format

### TOML Format

```toml
[network.balances]

# Hex addresses (ECDSA) - both with and without 0x prefix work
[network.balances.hex]
"f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac" = 1000
"0x25451a4de12dccc2d166922fa938e900fcc4ed24" = 2000

# SS58 addresses (SR25519)
[network.balances.ss58]
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" = 5000
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty" = 3000
```

### JSON Format

```json
{
  "network": {
    "balances": {
      "hex": {
        "f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac": 1000,
        "0x25451a4de12dccc2d166922fa938e900fcc4ed24": 2000
      },
      "ss58": {
        "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY": 5000,
        "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty": 3000
      }
    }
  }
}
```

## Address Types

### Hex Addresses (ECDSA)
- Used for Ethereum-compatible accounts
- Can be specified with or without the `0x` prefix
- Must be exactly 40 hexadecimal characters (20 bytes)
- Examples: `f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac` or `0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac`

### SS58 Addresses (SR25519)
- Used for Substrate-native accounts
- Standard Substrate address format
- Typically 47-48 characters long using base58 encoding
- Example: `5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY`


Balance amounts are specified in token units (not the smallest denomination). The system automatically multiplies by the token decimals specified in your configuration.

For example:
- If `token-decimal = 18` and you specify `1000` tokens
- The actual balance will be `1000 * 10^18` in the smallest unit


You can set the SS58 format for your chainspec using the `number` field in the chain configuration:

```toml
[network.chain]
number = 42  # Sets ss58Format to 42 in chainspec properties
```

```json
{
  "network": {
    "chain": {
      "number": 42
    }
  }
}
```
- Common examples:
  - `0`: Polkadot
  - `2`: Kusama  
  - `42`: Generic Substrate (commonly used for testing)
  - `5`: Astar

When specified, this will set the `ss58Format` property in your chainspec's `properties` section:

```json
{
  "properties": {
    "ss58Format": 42,
    "tokenSymbol": "TST",
    "tokenDecimals": 12
  }
}
```


## Frontier Configuration (Experimental)

Configuration files like `frontier-nodes.toml` and `frontier-nodes.json` demonstrate how you might structure genesis data for Frontier-based chains, specifically for setting initial EVM account balances and the EVM chain ID.

```toml
# filepath: ./frontier-nodes.toml
[network]
name = "testnet"
chain = "local"
token-symbol = "TST"
token-decimal = 12

# For bootstrapping frontier-based chains
[frontier.evm.accounts]
"0x1000000000000000000000000000000000000001" = { balance = "0xd3c21bcecceda1000000", code = [
    0,
], nonce = "0x1", storage = {} }
"0x6be02d1d3665660d22ff9624b7be0551ee1ac91b" = { balance = "0xffffffffffffffffffffffffffffffff", code = [
], nonce = "0x0", storage = {} }
"0xd43593c715fdd31c61141abd04a99fd6822c8558" = { balance = "0xffffffffffffffffffffffffffffffff", code = [
], nonce = "0x0", storage = {} }

[frontier.evmChainId]
chainId = 42

# ... node definitions ...
```

**Note:** Direct injection of Frontier genesis storage (`frontier.evm.accounts`) via the config file is currently **experimental** and primarily for reference. In many Frontier-based runtimes, the `pallet-evm` might be configured to use `pallet-balances` as its currency type (`type Currency = Balances`). If this is the case, you don't need to explicitly set balances under `frontier.evm.accounts`. Instead, the balances defined under each `[[nodes]]` section will automatically be associated with the generated validator account IDs, which can also hold EVM balances if the runtime maps Substrate accounts to EVM addresses (e.g., using H160 mapping).