Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# chainconfig — IPI Single Source of Truth (SSOT)

`config.json` jest **jedynym źródłem prawdy** parametrów sieci IPI.
Wszystkie konsumenty (`wallet-core.js`, `ipi-rpc`, portfele Keplr-kompatybilne i aplikacje)
powinny czytać wartości stąd, zamiast trzymać własne kopie chain-id / denom / endpointów.

## Użycie

```js
import config, { getEndpoints, getChainId, validateConfig } from "chain";

validateConfig(); // rzuca wyjątek gdy brakuje wymaganych pól
const { rpc, rest, grpc } = getEndpoints();
const chainId = getChainId("testnet"); // "ipi-testnet-1"
```

Domyślny eksport to sparsowany obiekt `config.json` (import JSON).

## Schemat pól

| Pole | Typ | Opis |
| --- | --- | --- |
| `chainId` | string | Aktywny chain-id sieci głównej (`ipi-mainnet-2`). |
| `chainName` | string | Czytelna nazwa sieci. |
| `bip44.coinType` / `slip44` | number | SLIP-44 coin type (`118`, standard Cosmos). |
| `bech32Config` | object | Pełny zestaw prefiksów bech32 (Keplr). |
| `bech32Prefix` | string | Skrócony prefiks konta (`ipi`) — wygoda dla narzędzi. |
| `currencies[]` | array | Waluty wyświetlane: `coinDenom`, `coinMinimalDenom`, `coinDecimals`. |
| `feeCurrencies[]` | array | Jak wyżej + `gasPriceStep` (`low`/`average`/`high`). |
| `stakeCurrency` | object | Waluta stakingu. |
| `features[]` | array | Włączone moduły łańcucha (`stargate`, `cosmwasm`). |
| `endpoints` | object | `rpc` / `rest` (LCD) / `grpc`. |
| `blockTime` | number | Docelowy czas bloku (sekundy, wartość przybliżona). |
| `explorer` | string | URL eksploratora. |
| `networks` | object | Chain-id per sieć: `mainnet`, `testnet`. |

## Denominacja

Bazowy denom to `nipi` (nano-IPI), display `IPI`, `coinDecimals: 9`
(1 IPI = 1 000 000 000 nipi).

## Uwagi (DRAFT — do review po Fala 1 devnet)

- `endpoints.grpc` (`ipicoin.eu:9090`) oraz `networks.testnet.chainId` (`ipi-testnet-1`)
to wartości robocze do potwierdzenia po uruchomieniu devnet.
- `gasPriceStep` i `blockTime` — wartości domyślne do kalibracji.

## Licencja

Apache 2.0 © IPI DAO 2026. Maintainership: Sett Sarverott.
22 changes: 20 additions & 2 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
"chainName": "IPI Mainnet 2",
"rpc": "https://ipicoin.eu/rpc",
"rest": "https://ipicoin.eu/api",
"grpc": "https://ipicoin.eu:9090",
"bip44": {
"coinType": 118
},
"slip44": 118,
"bech32Config": {
"bech32PrefixAccAddr": "ipi",
"bech32PrefixAccPub": "ipipub",
Expand All @@ -14,6 +16,7 @@
"bech32PrefixConsAddr": "ipivalcons",
"bech32PrefixConsPub": "ipivalconspub"
},
"bech32Prefix": "ipi",
"currencies": [
{
"coinDenom": "IPI",
Expand All @@ -25,13 +28,28 @@
{
"coinDenom": "IPI",
"coinMinimalDenom": "nipi",
"coinDecimals": 9
"coinDecimals": 9,
"gasPriceStep": {
"low": 0.01,
"average": 0.025,
"high": 0.04
}
}
],
"stakeCurrency": {
"coinDenom": "IPI",
"coinMinimalDenom": "nipi",
"coinDecimals": 9
},
"features": ["stargate", "cosmwasm"]
"features": ["stargate", "cosmwasm"],
"blockTime": 6,
"explorer": "https://ipicoin.eu",
"networks": {
"mainnet": {
"chainId": "ipi-mainnet-2"
},
"testnet": {
"chainId": "ipi-testnet-1"
}
}
}
77 changes: 76 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,81 @@
// on Apache license 2.0 @ IPI DAO 2026
// maintainership by Sett Sarverott

import chainConfiguration from "./config.json" with {type: 'json'};
import chainConfiguration from "./config.json" with { type: "json" };

/**
* Single Source of Truth (SSOT) for IPI network parameters.
* Consumed by wallet-core.js, ipi-rpc and downstream apps.
*/
export default chainConfiguration;

export const config = chainConfiguration;

/** Returns the network endpoints (rpc / rest / grpc) from the top-level SSOT fields. */
export function getEndpoints(cfg = chainConfiguration) {
return {
rpc: cfg.rpc,
rest: cfg.rest,
grpc: cfg.grpc,
};
}

/** Returns the chain-id for a given network ("mainnet" | "testnet"). */
export function getChainId(network = "mainnet") {
return chainConfiguration.networks?.[network]?.chainId ?? chainConfiguration.chainId;
}

/** Shape + value validation — throws on missing required fields or non-canonical values. */
export function validateConfig(cfg = chainConfiguration) {
const required = [
"chainId",
"chainName",
"bech32Prefix",
"rpc",
"rest",
"grpc",
"currencies",
"feeCurrencies",
"stakeCurrency",
];
const missing = required.filter((key) => cfg[key] === undefined);
if (missing.length > 0) {
throw new Error(`chainconfig: missing required fields: ${missing.join(", ")}`);
}

// Value validation — enforce canonical IPI network parameters (SSOT invariants).
const errors = [];

if (typeof cfg.chainId !== "string" || cfg.chainId.trim() === "") {
errors.push("chainId must be a non-empty string");
}
if (cfg.bech32Prefix !== "ipi") {
errors.push(`bech32Prefix must be "ipi" (got ${JSON.stringify(cfg.bech32Prefix)})`);
}
if (cfg.bip44?.coinType !== 118) {
errors.push(`bip44.coinType must be 118 (got ${JSON.stringify(cfg.bip44?.coinType)})`);
}

// Every currency list entry must carry the canonical base denom + decimals.
const currencyGroups = {
currencies: cfg.currencies,
feeCurrencies: cfg.feeCurrencies,
stakeCurrency: cfg.stakeCurrency,
};
for (const [name, group] of Object.entries(currencyGroups)) {
const entries = Array.isArray(group) ? group : [group];
for (const entry of entries) {
if (entry?.coinMinimalDenom !== "nipi") {
errors.push(`${name}: coinMinimalDenom must be "nipi" (got ${JSON.stringify(entry?.coinMinimalDenom)})`);
}
if (entry?.coinDecimals !== 9) {
errors.push(`${name}: coinDecimals must be 9 (got ${JSON.stringify(entry?.coinDecimals)})`);
}
}
}

if (errors.length > 0) {
throw new Error(`chainconfig: invalid values: ${errors.join("; ")}`);
}
return true;
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"type": "git",
"url": "git+https://github.com/ipicoin/chainconfig.git"
},
"license": "ISC",
"license": "Apache-2.0",
"author": "IPI DAO",
"type": "module",
"main": "index.js",
Expand Down