Skip to content
Merged
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
2 changes: 1 addition & 1 deletion packages/config/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ test: ## Run tests
lint: ## Run lint
$(call npm, run lint)

build: NODE_ENV = "production"
.PHONY: build
build: NODE_ENV = "production"
build: ## Run build
$(call npm, run build)

Expand Down
4 changes: 2 additions & 2 deletions packages/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ npm install --save @streamr/config
## Examples
Import DATA token production Ethereum address as a variable in a Typescript project:
```typescript
import { Chains, loadConfig } from "index"
import { Chains } from "index"

const config: Chains = loadConfig("production")
const config: Chains = Chains.load("production")
const contractAddress: string = config.ethereum.contracts["DATA-token"]
const chainId: number = config.ethereum.id
const rpcHttpUrl: string = config.ethereum.rpcHttpUrl
Expand Down
106 changes: 91 additions & 15 deletions packages/config/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,104 @@
import networksAsJSON from "./networks.json"

export interface Contracts {
[name: string]: string
interface ContractsJSON {
readonly [name: string]: string
}
export class Contracts implements ContractsJSON {
[name: string]: string
}

export enum RPCProtocol {
HTTP,
WEBSOCKET
}

export interface Chain {
id: number
rpcHttpUrl: string
rpcWsUrl: string
contracts: Contracts
interface RPCEndpointJSON {
readonly url: string
}

export interface Chains {
[name: string]: Chain
export class RPCEndpoint implements RPCEndpointJSON {
constructor(
readonly url: string,
//readonly readTimeoutSecond: int,
//readonly writeTimeoutSecond: int,
) {}
}

interface ChainJSON {
readonly id: number
readonly rpcEndpoints: RPCEndpointJSON[]
readonly contracts: ContractsJSON
}

export class Chain implements ChainJSON {
constructor(
public readonly id: number,
public rpcEndpoints: RPCEndpoint[],
public contracts: Contracts,
) {
this.id = id
this.rpcEndpoints = new Array<RPCEndpoint>()
for (const rpcEndpoint of rpcEndpoints) {
this.rpcEndpoints.push(new RPCEndpoint(rpcEndpoint.url))
}
this.contracts = new Contracts()
for (const key of Object.keys(contracts)) {
this.contracts[key] = contracts[key]
}
}
getRPCEndpointsByProtocol(protocol: RPCProtocol): RPCEndpoint[] {
const endpoints = new Array<RPCEndpoint>()
for (const rpcEndpoint of this.rpcEndpoints) {
if (protocol === RPCProtocol.HTTP) {
if (rpcEndpoint.url.startsWith("https://") || rpcEndpoint.url.startsWith("http://")) {
endpoints.push(new RPCEndpoint(rpcEndpoint.url))
}
} else if (protocol === RPCProtocol.WEBSOCKET) {
if (rpcEndpoint.url.startsWith("wss://") || rpcEndpoint.url.startsWith("ws://")) {
endpoints.push(new RPCEndpoint(rpcEndpoint.url))
}
}
}
return endpoints
}
}

export type Environment = "development" | "production"

export type Networks = {
[env in Environment]: Chains
type NetworksJSON = {
readonly [env in Environment]: ChainsJSON
}

interface ChainsJSON {
readonly [name: string]: ChainJSON
}

export class Chains implements ChainsJSON {
[name: string]: Chain
public static load(env: Environment): Chains {
const networks: NetworksJSON = networksAsJSON
const chainsJson: ChainsJSON = networks[env]
const chains: Chains = ChainsFactory.create(chainsJson)
return chains
}
}

export const loadConfig = (env: Environment): Chains => {
const networks: Networks = networksAsJSON
const chain: Chains = networks[env]
return chain
class ChainsFactory {
private constructor() {}
static create(chainsJson: ChainsJSON): Chains {
const chains = new Chains()
for (const key in chainsJson) {
const chainJson: ChainJSON = chainsJson[key]
const rpcEndpoints = new Array<RPCEndpoint>()
for (const rpcEndpoint of chainJson.rpcEndpoints) {
rpcEndpoints.push(new RPCEndpoint(rpcEndpoint.url))
}
const contracts = new Contracts()
for (const key of Object.keys(chainJson.contracts)) {
contracts[key] = chainJson.contracts[key]
}
chains[key] = new Chain(chainJson.id, rpcEndpoints, contracts)
}
return chains
}
}
55 changes: 43 additions & 12 deletions packages/config/src/networks.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
"development": {
"ethereum": {
"id": 8995,
"rpcHttpUrl": "http://10.200.10.1:8545",
"rpcWsUrl": "ws://10.200.10.1:8545",
"rpcEndpoints": [
{
"url": "http://10.200.10.1:8545"
},
{
"url": "ws://10.200.10.1:8545"
}
],
"contracts": {
"DATA-token": "0xbAA81A0179015bE47Ad439566374F2Bae098686F",
"XDATA-token": "0x6d0F3bF9aD2455b4F62f22fFD21317e1E3eEFE5C",
Expand All @@ -24,8 +30,14 @@
},
"streamr": {
"id": 8997,
"rpcHttpUrl": "http://10.200.10.1:8546",
"rpcWsUrl": "ws://10.200.10.1:8546",
"rpcEndpoints": [
{
"url": "http://10.200.10.1:8546"
},
{
"url": "ws://10.200.10.1:8546"
}
],
"contracts": {
"Token": "0x73Be21733CC5D08e1a14Ea9a399fb27DB3BEf8fF",
"Mediator": "0xedD2aa644a6843F2e5133Fe3d6BD3F4080d97D9F",
Expand All @@ -42,8 +54,7 @@
"production": {
"ethereum": {
"id": 1,
"rpcHttpUrl": "",
"rpcWsUrl": "",
"rpcEndpoints": [],
"contracts": {
"DATA-token": "0x8f693ca8D21b157107184d29D398A8D082b38b76",
"XDATA-token": "0x0cf0ee63788a0849fe5297f3407f701e122cc023",
Expand All @@ -62,8 +73,14 @@
},
"gnosis": {
"id": 100,
"rpcHttpUrl": "https://rpc.gnosischain.com",
"rpcWsUrl": "wss://rpc.gnosischain.com/wss",
"rpcEndpoints": [
{
"url": "https://rpc.gnosischain.com"
},
{
"url": "wss://rpc.gnosischain.com/wss"
}
],
"contracts": {
"XDATA-token": "0xE4a2620edE1058D61BEe5F45F6414314fdf10548",
"DATA-token": "0x256eb8a51f382650B2A1e946b8811953640ee47D",
Expand All @@ -80,17 +97,31 @@
},
"binance": {
"id": 56,
"rpcHttpUrl": "https://bsc-dataseed.binance.org",
"rpcWsUrl": "wss://bsc-dataseed.binance.org",
"rpcHttpUrl": "",
"rpcWsUrl": "",
"rpcEndpoints": [
{
"url": "https://bsc-dataseed.binance.org"
},
{
"url": "wss://bsc-dataseed.binance.org"
}
],
"contracts": {
"DATA-token": "0x0864c156b3c5f69824564dec60c629ae6401bf2a",
"xdaiBridge": "0xa93ee7b4a7215f7e725437a6b6d7a4e7fe1dd8f0"
}
},
"polygon": {
"id": 137,
"rpcHttpUrl": "https://polygon-rpc.com",
"rpcWsUrl": "wss://polygon-rpc.com",
"rpcEndpoints": [
{
"url": "https://polygon-rpc.com"
},
{
"url": "wss://polygon-rpc.com"
}
],
"contracts": {
"DATA-token": "0x3a9A81d576d83FF21f26f325066054540720fC34",
"StorageNodeRegistry": "0x080F34fec2bc33928999Ea9e39ADc798bEF3E0d6",
Expand Down
24 changes: 15 additions & 9 deletions packages/config/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
import { describe, it } from "mocha"
import { assert } from "chai"
import { Chains, loadConfig } from "../src/index"
import { Chains, RPCProtocol } from "../src/index"

describe("Load configuration from JSON file", () => {
it("ethereum chain id is 1", () => {
const config: Chains = loadConfig("production")
const chainId: number = config.ethereum.id
const chains: Chains = Chains.load("production")
const chainId: number = chains.ethereum.id
const expected = 1
assert.equal(chainId, expected, `Expecting ethereum prod chain id to equal ${expected}, got '${chainId}'`)
})
it("development chain id is 8995", () => {
const config: Chains = loadConfig("development")
const chainId: number = config.ethereum.id
const chains: Chains = Chains.load("development")
const chainId: number = chains.ethereum.id
const expected = 8995
assert.equal(chainId, expected, `Expecting ethereum dev chain id to equal ${expected}, got '${chainId}'`)
})
it("reads DATA token dev address from JSON", () => {
const config: Chains = loadConfig("development")
const address = config.ethereum.contracts["DATA-token"]
const chains: Chains = Chains.load("development")
const address = chains.ethereum.contracts["DATA-token"]
const expected = "0xbAA81A0179015bE47Ad439566374F2Bae098686F"
assert.equal(address, expected, `Expecting ethereum DATA token to equal ${expected}, got '${address}'`)
})
it("reads prod Polygon RPC URL", () => {
const config: Chains = loadConfig("production")
const rpcHttpUrl = config.polygon.rpcHttpUrl
const chains: Chains = Chains.load("production")
const rpcHttpUrl = chains.polygon.rpcEndpoints[0].url
const expected = "https://polygon-rpc.com"
assert.equal(rpcHttpUrl, expected, `Expecting prod polygon RPC URL to equal ${expected}, got '${rpcHttpUrl}'`)
})
it("finds RPC endpoints by protocol", () => {
const chains: Chains = Chains.load("production")
const endpoints = chains.binance.getRPCEndpointsByProtocol(RPCProtocol.HTTP)
assert.equal(endpoints.length, 1)
assert.equal(endpoints[0].url, "https://bsc-dataseed.binance.org")
})
})