mirror of https://gitlab.com/ecentrics/concordia
Apostolos Fanakis
4 years ago
73 changed files with 1393 additions and 345 deletions
@ -1,14 +1,2 @@ |
|||||
export const WEB3_HOST_DEFAULT = '127.0.0.1'; |
export const CONCORDIA_HOST_DEFAULT = '127.0.0.1'; |
||||
export const WEB3_PORT_DEFAULT = '8545'; |
export const CONCORDIA_PORT_DEFAULT = '7000'; |
||||
export const WEB3_PORT_SOCKET_TIMEOUT_DEFAULT = 30000; |
|
||||
export const WEB3_PORT_SOCKET_CONNECT_MAX_ATTEMPTS_DEFAULT = 3; |
|
||||
|
|
||||
export const REACT_APP_CONCORDIA_HOST_DEFAULT = '127.0.0.1'; |
|
||||
export const REACT_APP_CONCORDIA_PORT_DEFAULT = '7000'; |
|
||||
|
|
||||
export const REACT_APP_RENDEZVOUS_HOST_DEFAULT = '127.0.0.1'; |
|
||||
export const REACT_APP_RENDEZVOUS_PORT_DEFAULT = '9090'; |
|
||||
|
|
||||
export const REACT_APP_CONTRACTS_SUPPLIER_HOST_DEFAULT = '127.0.0.1'; |
|
||||
export const REACT_APP_CONTRACTS_SUPPLIER_PORT_DEFAULT = '8400'; |
|
||||
export const REACT_APP_CONTRACTS_VERSION_HASH_DEFAULT = 'latest'; |
|
||||
|
@ -1,11 +0,0 @@ |
|||||
export const FORUM_CONTRACT = 'Forum'; |
|
||||
export const POST_VOTING_CONTRACT = 'PostVoting'; |
|
||||
export const VOTING_CONTRACT = 'Voting'; |
|
||||
|
|
||||
const CONTRACTS = [ |
|
||||
FORUM_CONTRACT, |
|
||||
POST_VOTING_CONTRACT, |
|
||||
VOTING_CONTRACT, |
|
||||
]; |
|
||||
|
|
||||
export default CONTRACTS; |
|
@ -1,13 +0,0 @@ |
|||||
export const USER_SIGNED_UP_EVENT = 'UserSignedUp'; |
|
||||
export const USERNAME_UPDATED_EVENT = 'UsernameUpdated'; |
|
||||
export const TOPIC_CREATED_EVENT = 'TopicCreated'; |
|
||||
export const POST_CREATED_EVENT = 'PostCreated'; |
|
||||
|
|
||||
const forumContractEvents = [ |
|
||||
USER_SIGNED_UP_EVENT, |
|
||||
USERNAME_UPDATED_EVENT, |
|
||||
TOPIC_CREATED_EVENT, |
|
||||
POST_CREATED_EVENT, |
|
||||
]; |
|
||||
|
|
||||
export default forumContractEvents; |
|
@ -1,8 +0,0 @@ |
|||||
import { FORUM_CONTRACT } from '../ContractNames'; |
|
||||
import forumContractEvents from './ForumContractEvents'; |
|
||||
|
|
||||
const appEvents = { |
|
||||
[FORUM_CONTRACT]: forumContractEvents, |
|
||||
}; |
|
||||
|
|
||||
export default appEvents; |
|
@ -1,40 +0,0 @@ |
|||||
import { EthereumContractIdentityProvider } from '@ezerous/eth-identity-provider'; |
|
||||
import databases from '../constants/orbit/OrbitDatabases'; |
|
||||
import { |
|
||||
REACT_APP_RENDEZVOUS_HOST_DEFAULT, |
|
||||
REACT_APP_RENDEZVOUS_PORT_DEFAULT, |
|
||||
} from '../constants/configuration/defaults'; |
|
||||
|
|
||||
const REACT_APP_RENDEZVOUS_HOST = process.env.REACT_APP_RENDEZVOUS_HOST || REACT_APP_RENDEZVOUS_HOST_DEFAULT; |
|
||||
const REACT_APP_RENDEZVOUS_PORT = process.env.REACT_APP_RENDEZVOUS_PORT || REACT_APP_RENDEZVOUS_PORT_DEFAULT; |
|
||||
|
|
||||
const breezeOptions = { |
|
||||
ipfs: { |
|
||||
repo: 'concordia', |
|
||||
config: { |
|
||||
Addresses: { |
|
||||
Swarm: [ |
|
||||
// Use local signaling server (see also rendezvous script in package.json)
|
|
||||
// For more information: https://github.com/libp2p/js-libp2p-webrtc-star
|
|
||||
`/ip4/${REACT_APP_RENDEZVOUS_HOST}/tcp/${REACT_APP_RENDEZVOUS_PORT}/wss/p2p-webrtc-star`, |
|
||||
|
|
||||
// Use the following public servers if needed
|
|
||||
// '/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star',
|
|
||||
// '/dns4/ wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star'
|
|
||||
], |
|
||||
}, |
|
||||
}, |
|
||||
preload: { |
|
||||
enabled: false, |
|
||||
}, |
|
||||
init: { |
|
||||
emptyRepo: true, |
|
||||
}, |
|
||||
}, |
|
||||
orbit: { |
|
||||
identityProvider: EthereumContractIdentityProvider, |
|
||||
databases, |
|
||||
}, |
|
||||
}; |
|
||||
|
|
||||
export default breezeOptions; |
|
@ -1,29 +0,0 @@ |
|||||
import Web3 from 'web3'; |
|
||||
import { |
|
||||
WEB3_HOST_DEFAULT, |
|
||||
WEB3_PORT_DEFAULT, |
|
||||
WEB3_PORT_SOCKET_CONNECT_MAX_ATTEMPTS_DEFAULT, |
|
||||
WEB3_PORT_SOCKET_TIMEOUT_DEFAULT, |
|
||||
} from '../constants/configuration/defaults'; |
|
||||
|
|
||||
const { WEB3_HOST, WEB3_PORT, WEBSOCKET_TIMEOUT } = process.env; |
|
||||
|
|
||||
const web3WebsocketOptions = { |
|
||||
keepAlive: true, |
|
||||
timeout: WEBSOCKET_TIMEOUT !== undefined ? WEBSOCKET_TIMEOUT : WEB3_PORT_SOCKET_TIMEOUT_DEFAULT, |
|
||||
reconnect: { |
|
||||
maxAttempts: WEB3_PORT_SOCKET_CONNECT_MAX_ATTEMPTS_DEFAULT, |
|
||||
}, |
|
||||
}; |
|
||||
|
|
||||
const web3 = (WEB3_HOST !== undefined && WEB3_PORT !== undefined) |
|
||||
? new Web3(new Web3.providers.WebsocketProvider(`ws://${WEB3_HOST}:${WEB3_PORT}`)) |
|
||||
: new Web3(Web3.givenProvider || new Web3.providers.WebsocketProvider( |
|
||||
`ws://${WEB3_HOST_DEFAULT}:${WEB3_PORT_DEFAULT}`, web3WebsocketOptions, |
|
||||
)); |
|
||||
|
|
||||
const web3Options = { |
|
||||
customProvider: web3, |
|
||||
}; |
|
||||
|
|
||||
export default web3Options; |
|
@ -1,11 +1,9 @@ |
|||||
import path from 'path'; |
import path from 'path'; |
||||
|
|
||||
const PROVIDER_PORT = '8400'; |
|
||||
const UPLOAD_CONTRACTS_DIRECTORY = path.join(__dirname, '..', 'contracts-uploads'); |
const UPLOAD_CONTRACTS_DIRECTORY = path.join(__dirname, '..', 'contracts-uploads'); |
||||
const CORS_ALLOWED_ORIGINS = ['http://127.0.0.1:7000', 'http://localhost:7000']; |
const CORS_ALLOWED_ORIGINS = ['http://127.0.0.1:7000', 'http://localhost:7000']; |
||||
|
|
||||
export default { |
export default { |
||||
port: PROVIDER_PORT, |
|
||||
uploadsDirectory: UPLOAD_CONTRACTS_DIRECTORY, |
uploadsDirectory: UPLOAD_CONTRACTS_DIRECTORY, |
||||
corsAllowedOrigins: CORS_ALLOWED_ORIGINS, |
corsAllowedOrigins: CORS_ALLOWED_ORIGINS, |
||||
}; |
}; |
||||
|
@ -1,21 +0,0 @@ |
|||||
const DEVELOP_CHAIN_HOST_DEFAULT = '127.0.0.1'; |
|
||||
const DEVELOP_CHAIN_PORT_DEFAULT = '8545'; |
|
||||
|
|
||||
const TEST_CHAIN_HOST_DEFAULT = '127.0.0.1'; |
|
||||
const TEST_CHAIN_PORT_DEFAULT = '8546'; |
|
||||
|
|
||||
const CONTRACTS_PROVIDER_HOST_DEFAULT = '127.0.0.1'; |
|
||||
const CONTRACTS_PROVIDER_PORT_DEFAULT = '8400'; |
|
||||
|
|
||||
module.exports = { |
|
||||
develop: { |
|
||||
chainHost: DEVELOP_CHAIN_HOST_DEFAULT, |
|
||||
chainPort: DEVELOP_CHAIN_PORT_DEFAULT, |
|
||||
}, |
|
||||
test: { |
|
||||
chainHost: TEST_CHAIN_HOST_DEFAULT, |
|
||||
chainPort: TEST_CHAIN_PORT_DEFAULT, |
|
||||
}, |
|
||||
contractsProviderHost: CONTRACTS_PROVIDER_HOST_DEFAULT, |
|
||||
contractsProviderPort: CONTRACTS_PROVIDER_PORT_DEFAULT, |
|
||||
}; |
|
@ -0,0 +1,60 @@ |
|||||
|
module.exports = { |
||||
|
env: { |
||||
|
browser: true, |
||||
|
es6: true, |
||||
|
jest: true, |
||||
|
}, |
||||
|
extends: [ |
||||
|
'plugin:react/recommended', |
||||
|
'airbnb', |
||||
|
], |
||||
|
globals: { |
||||
|
Atomics: 'readonly', |
||||
|
SharedArrayBuffer: 'readonly', |
||||
|
}, |
||||
|
parser: 'babel-eslint', |
||||
|
parserOptions: { |
||||
|
ecmaFeatures: { |
||||
|
jsx: true, |
||||
|
}, |
||||
|
ecmaVersion: 2018, |
||||
|
sourceType: 'module', |
||||
|
}, |
||||
|
plugins: [ |
||||
|
'react', |
||||
|
'react-hooks', |
||||
|
], |
||||
|
rules: { |
||||
|
'react/jsx-props-no-spreading': 'off', |
||||
|
'import/extensions': 'off', |
||||
|
'react/jsx-indent': [ |
||||
|
'error', |
||||
|
4, |
||||
|
{ |
||||
|
checkAttributes: true, |
||||
|
indentLogicalExpressions: true, |
||||
|
}, |
||||
|
], |
||||
|
'react/require-default-props': 'off', |
||||
|
'react/prop-types': 'off', |
||||
|
'react-hooks/rules-of-hooks': 'error', |
||||
|
'react-hooks/exhaustive-deps': 'error', |
||||
|
'max-len': ['warn', { code: 120, tabWidth: 4 }], |
||||
|
'no-unused-vars': 'warn', |
||||
|
'no-console': 'off', |
||||
|
'no-shadow': 'warn', |
||||
|
'no-multi-str': 'warn', |
||||
|
'jsx-a11y/label-has-associated-control': [2, { |
||||
|
labelAttributes: ['label'], |
||||
|
controlComponents: ['Input'], |
||||
|
depth: 3, |
||||
|
}], |
||||
|
}, |
||||
|
settings: { |
||||
|
'import/resolver': { |
||||
|
node: { |
||||
|
extensions: ['.js', '.jsx'], |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,10 @@ |
|||||
|
# Set the default behavior, in case people don't have core.autocrlf set. |
||||
|
* text=auto eol=lf |
||||
|
|
||||
|
# Denote all files that are truly binary and should not be modified. |
||||
|
*.png binary |
||||
|
*.jpg binary |
||||
|
*.ico binary |
||||
|
|
||||
|
# Solidity |
||||
|
*.sol linguist-language=Solidity |
@ -0,0 +1,40 @@ |
|||||
|
# Node |
||||
|
/node_modules |
||||
|
packages/*/node_modules |
||||
|
packages/concordia-contracts/build |
||||
|
|
||||
|
# IDE |
||||
|
.DS_Store |
||||
|
.idea |
||||
|
|
||||
|
# Build Directories |
||||
|
/build |
||||
|
/src/build |
||||
|
/packages/concordia-app/build |
||||
|
/packages/concordia-contracts/build |
||||
|
|
||||
|
# Logs |
||||
|
/log |
||||
|
npm-debug.log* |
||||
|
yarn-debug.log* |
||||
|
yarn-error.log* |
||||
|
|
||||
|
# Docker volumes |
||||
|
docker/volumes |
||||
|
docker/ganache/volumes |
||||
|
docker/reports |
||||
|
|
||||
|
# Env var files |
||||
|
docker/env/concordia.env |
||||
|
docker/env/contracts.env |
||||
|
|
||||
|
# Misc |
||||
|
.env.local |
||||
|
.env.development.local |
||||
|
.env.test.local |
||||
|
.env.production.local |
||||
|
|
||||
|
# IPFS & OrbitDB Storage |
||||
|
ipfs |
||||
|
orbitdb |
||||
|
|
@ -0,0 +1,39 @@ |
|||||
|
{ |
||||
|
"name": "concordia-pinner", |
||||
|
"description": "An OrbitDB pinning service for Concordia.", |
||||
|
"version": "0.1.0", |
||||
|
"private": true, |
||||
|
"main": "src/index.js", |
||||
|
"scripts": { |
||||
|
"start": "node -r esm src/index.js", |
||||
|
"clean": "rimraf ipfs orbitdb", |
||||
|
"lint": "eslint --ext js,jsx . --format table" |
||||
|
}, |
||||
|
"license": "MIT", |
||||
|
"dependencies": { |
||||
|
"@ezerous/eth-identity-provider": "~0.1.2", |
||||
|
"concordia-contracts": "~0.1.0", |
||||
|
"concordia-shared": "~0.1.0", |
||||
|
"esm": "~3.2.25", |
||||
|
"express": "^4.17.1", |
||||
|
"ipfs": "~0.52.1", |
||||
|
"is-reachable": "^5.0.0", |
||||
|
"level": "~6.0.1", |
||||
|
"libp2p": "~0.30.0", |
||||
|
"libp2p-bootstrap": "~0.12.1", |
||||
|
"libp2p-gossipsub": "~0.8.0", |
||||
|
"libp2p-kad-dht": "~0.20.1", |
||||
|
"libp2p-mdns": "~0.15.0", |
||||
|
"libp2p-mplex": "~0.10.0", |
||||
|
"libp2p-noise": "~2.0.1", |
||||
|
"libp2p-tcp": "~0.15.1", |
||||
|
"libp2p-webrtc-star": "~0.20.2", |
||||
|
"lodash": "^4.17.20", |
||||
|
"orbit-db": "~0.26.0", |
||||
|
"orbit-db-identity-provider": "~0.3.1", |
||||
|
"rimraf": "~3.0.2", |
||||
|
"web3": "~1.3.0", |
||||
|
"web3-eth-contract": "^1.3.1", |
||||
|
"wrtc": "~0.4.6" |
||||
|
} |
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
import express from 'express'; |
||||
|
import _ from 'lodash'; |
||||
|
import isReachable from 'is-reachable'; |
||||
|
import { pinnerApiPort } from 'concordia-shared/src/environment/interpolated/pinner'; |
||||
|
import getWeb3ProviderUrl from 'concordia-shared/src/utils/web3'; |
||||
|
import getRendezvousUrl from 'concordia-shared/src/utils/rendezvous'; |
||||
|
|
||||
|
const POLLING_INTERVAL = 1000; |
||||
|
|
||||
|
const responseBody = { |
||||
|
ipfs: { |
||||
|
id: '', localAddresses: [], peers: [], totalPeers: 0, repoStats: {}, |
||||
|
}, |
||||
|
orbit: { identity: {}, databases: [] }, |
||||
|
web3: { url: getWeb3ProviderUrl(), reachable: false }, |
||||
|
rendezvous: { url: getRendezvousUrl(), reachable: false }, |
||||
|
timestamp: 0, |
||||
|
}; |
||||
|
|
||||
|
async function getStats(orbit) { |
||||
|
try { |
||||
|
// eslint-disable-next-line no-underscore-dangle
|
||||
|
const ipfs = orbit._ipfs; |
||||
|
const { id } = await ipfs.id(); |
||||
|
const peers = await ipfs.swarm.peers(); |
||||
|
const localAddresses = await ipfs.swarm.localAddrs(); |
||||
|
const repoStats = await ipfs.stats.repo(); |
||||
|
const uniquePeers = _.uniqBy(peers, 'peer'); |
||||
|
const orbitIdentity = orbit.identity; |
||||
|
const databases = Object.keys(orbit.stores); |
||||
|
const isWeb3Reachable = await isReachable(getWeb3ProviderUrl()); |
||||
|
const isRendezvousReachable = await isReachable(getRendezvousUrl()); |
||||
|
const timestamp = +new Date(); |
||||
|
|
||||
|
responseBody.ipfs.id = id; |
||||
|
responseBody.ipfs.peers = uniquePeers; |
||||
|
responseBody.ipfs.totalPeers = uniquePeers.length; |
||||
|
responseBody.ipfs.localAddresses = localAddresses; |
||||
|
responseBody.ipfs.repoStats = repoStats; |
||||
|
responseBody.orbit.identity = orbitIdentity; |
||||
|
responseBody.orbit.databases = databases; |
||||
|
responseBody.web3.reachable = isWeb3Reachable; |
||||
|
responseBody.rendezvous.reachable = isRendezvousReachable; |
||||
|
responseBody.timestamp = timestamp; |
||||
|
} catch (err) { |
||||
|
console.error('Error while getting stats:', err); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const startAPI = (orbit) => { |
||||
|
const app = express(); |
||||
|
app.get('/', async (req, res) => { |
||||
|
res.send(responseBody); |
||||
|
}); |
||||
|
|
||||
|
app.listen(pinnerApiPort, () => { |
||||
|
console.log(`Pinner API at http://localhost:${pinnerApiPort}!`); |
||||
|
}); |
||||
|
|
||||
|
setInterval(getStats, POLLING_INTERVAL, orbit); |
||||
|
}; |
||||
|
|
||||
|
export default startAPI; |
@ -0,0 +1,6 @@ |
|||||
|
import path from 'path'; |
||||
|
import getBreezeConfiguration from 'concordia-shared/src/configuration/breezeConfiguration'; |
||||
|
|
||||
|
export const swarmAddresses = getBreezeConfiguration().ipfs.config.Addresses.Swarm; |
||||
|
|
||||
|
export const ORBIT_DIRECTORY_DEFAULT = path.join(__dirname, '..', 'orbitdb'); |
@ -0,0 +1,80 @@ |
|||||
|
import Web3 from 'web3'; |
||||
|
import Contract from 'web3-eth-contract'; |
||||
|
import IPFS from 'ipfs'; |
||||
|
import { contracts } from 'concordia-contracts'; |
||||
|
import { FORUM_CONTRACT } from 'concordia-shared/src/constants/contracts/ContractNames'; |
||||
|
import getWeb3ProviderUrl from 'concordia-shared/src/utils/web3'; |
||||
|
import { createOrbitInstance, getPeerDatabases, openKVDBs } from './utils/orbitUtils'; |
||||
|
import ipfsOptions from './options/ipfsOptions'; |
||||
|
import startAPI from './app'; |
||||
|
|
||||
|
process.on('unhandledRejection', (error) => { |
||||
|
// This happens when attempting to initialize without any available Swarm addresses (e.g. Rendezvous)
|
||||
|
if (error.code === 'ERR_NO_VALID_ADDRESSES') { |
||||
|
console.error('unhandledRejection', error.message); |
||||
|
process.exit(1); |
||||
|
} |
||||
|
|
||||
|
// Don't swallow other errors
|
||||
|
console.error(error); |
||||
|
throw error; |
||||
|
}); |
||||
|
|
||||
|
const getDeployedContract = async (web3) => { |
||||
|
const forumContract = contracts.find((contract) => contract.contractName === FORUM_CONTRACT); |
||||
|
|
||||
|
return web3.eth.net.getId() |
||||
|
.then((networkId) => forumContract.networks[networkId].address) |
||||
|
.then((contractAddress) => { |
||||
|
Contract.setProvider(getWeb3ProviderUrl()); |
||||
|
const contract = new Contract(forumContract.abi, contractAddress); |
||||
|
|
||||
|
return { contract, contractAddress }; |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
// Open & replicate databases of existing users
|
||||
|
const openExistingUsersDatabases = async (contract, orbit) => contract.methods.getUserAddresses().call() |
||||
|
.then((userAddresses) => getPeerDatabases(orbit, userAddresses)) |
||||
|
.then((peerDBs) => openKVDBs(orbit, peerDBs)); |
||||
|
|
||||
|
const handleWeb3LogEvent = (web3, eventJsonInterface, orbit) => (error, result) => { |
||||
|
if (!error) { |
||||
|
const eventObj = web3.eth.abi.decodeLog( |
||||
|
eventJsonInterface.inputs, |
||||
|
result.data, |
||||
|
result.topics.slice(1), |
||||
|
); |
||||
|
const userAddress = eventObj[1]; |
||||
|
console.log('User signed up:', userAddress); |
||||
|
getPeerDatabases(orbit, [userAddress]) |
||||
|
.then((peerDBs) => openKVDBs(orbit, peerDBs)); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const main = async () => { |
||||
|
console.log('Initializing...'); |
||||
|
const web3 = new Web3(new Web3.providers.WebsocketProvider(getWeb3ProviderUrl())); |
||||
|
|
||||
|
getDeployedContract(web3) |
||||
|
.then(({ contract, contractAddress }) => IPFS.create(ipfsOptions) |
||||
|
.then((ipfs) => createOrbitInstance(ipfs, contractAddress)) |
||||
|
.then((orbit) => openExistingUsersDatabases(contract, orbit) |
||||
|
.then(() => { |
||||
|
// Listen for new users and subscribe to their databases
|
||||
|
const eventJsonInterface = web3.utils._.find( |
||||
|
// eslint-disable-next-line no-underscore-dangle
|
||||
|
contract._jsonInterface, |
||||
|
(obj) => obj.name === 'UserSignedUp' && obj.type === 'event', |
||||
|
); |
||||
|
|
||||
|
web3.eth.subscribe('logs', { |
||||
|
address: contractAddress, |
||||
|
topics: [eventJsonInterface.signature], |
||||
|
}, handleWeb3LogEvent(web3, eventJsonInterface, orbit)); |
||||
|
|
||||
|
startAPI(orbit); |
||||
|
}))); |
||||
|
}; |
||||
|
|
||||
|
main(); |
@ -0,0 +1,22 @@ |
|||||
|
import libp2pBundle from './libp2pBundle'; |
||||
|
import { swarmAddresses } from '../constants'; |
||||
|
|
||||
|
export default { |
||||
|
repo: 'ipfs', |
||||
|
config: { |
||||
|
Profile: 'server', |
||||
|
Addresses: { |
||||
|
Swarm: swarmAddresses, |
||||
|
}, |
||||
|
}, |
||||
|
libp2p: libp2pBundle, |
||||
|
EXPERIMENTAL: { |
||||
|
pubsub: true, |
||||
|
}, |
||||
|
preload: { |
||||
|
enabled: false, |
||||
|
}, |
||||
|
init: { |
||||
|
emptyRepo: true, |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,90 @@ |
|||||
|
import Libp2p from 'libp2p'; |
||||
|
import wrtc from 'wrtc'; |
||||
|
import MulticastDNS from 'libp2p-mdns'; |
||||
|
import WebrtcStar from 'libp2p-webrtc-star'; |
||||
|
import Bootstrap from 'libp2p-bootstrap'; |
||||
|
import Gossipsub from 'libp2p-gossipsub'; |
||||
|
import KadDHT from 'libp2p-kad-dht'; |
||||
|
import MPLEX from 'libp2p-mplex'; |
||||
|
import { NOISE } from 'libp2p-noise'; |
||||
|
import { swarmAddresses } from '../constants'; |
||||
|
|
||||
|
// See also: https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md
|
||||
|
export default (opts) => new Libp2p({ |
||||
|
peerId: opts.peerId, |
||||
|
addresses: { |
||||
|
listen: swarmAddresses, |
||||
|
}, |
||||
|
connectionManager: { |
||||
|
minPeers: 25, |
||||
|
maxPeers: 100, |
||||
|
pollInterval: 5000, |
||||
|
}, |
||||
|
modules: { |
||||
|
transport: [ |
||||
|
WebrtcStar, |
||||
|
], |
||||
|
streamMuxer: [ |
||||
|
MPLEX, |
||||
|
], |
||||
|
connEncryption: [ |
||||
|
NOISE, |
||||
|
], |
||||
|
peerDiscovery: [ |
||||
|
MulticastDNS, |
||||
|
Bootstrap, |
||||
|
], |
||||
|
dht: KadDHT, |
||||
|
pubsub: Gossipsub, |
||||
|
}, |
||||
|
config: { |
||||
|
transport: { |
||||
|
[WebrtcStar.prototype[Symbol.toStringTag]]: { |
||||
|
wrtc, |
||||
|
}, |
||||
|
}, |
||||
|
peerDiscovery: { |
||||
|
autoDial: true, |
||||
|
mdns: { |
||||
|
enabled: true, |
||||
|
interval: 10000, |
||||
|
}, |
||||
|
bootstrap: { |
||||
|
enabled: true, |
||||
|
interval: 30e3, |
||||
|
list: opts.config.Bootstrap, |
||||
|
}, |
||||
|
}, |
||||
|
relay: { |
||||
|
enabled: true, |
||||
|
hop: { |
||||
|
enabled: true, |
||||
|
active: true, |
||||
|
}, |
||||
|
}, |
||||
|
dht: { |
||||
|
enabled: true, |
||||
|
kBucketSize: 20, |
||||
|
randomWalk: { |
||||
|
enabled: true, |
||||
|
interval: 10e3, |
||||
|
timeout: 2e3, |
||||
|
}, |
||||
|
}, |
||||
|
pubsub: { |
||||
|
enabled: true, |
||||
|
emitself: true, |
||||
|
}, |
||||
|
}, |
||||
|
metrics: { |
||||
|
enabled: true, |
||||
|
computeThrottleMaxQueueSize: 1000, |
||||
|
computeThrottleTimeout: 2000, |
||||
|
movingAverageIntervals: [ |
||||
|
60 * 1000, // 1 minute
|
||||
|
5 * 60 * 1000, // 5 minutes
|
||||
|
15 * 60 * 1000, // 15 minutes
|
||||
|
], |
||||
|
maxOldPeersRetention: 50, |
||||
|
}, |
||||
|
}); |
@ -0,0 +1,46 @@ |
|||||
|
import OrbitDB from 'orbit-db'; |
||||
|
import Identities from 'orbit-db-identity-provider'; |
||||
|
import { EthereumContractIdentityProvider } from '@ezerous/eth-identity-provider'; |
||||
|
import Web3 from 'web3'; |
||||
|
import { ORBIT_DIRECTORY_DEFAULT } from '../constants'; |
||||
|
|
||||
|
// TODO: share code below with frontend (?)
|
||||
|
const determineDBAddress = async ({ |
||||
|
orbit, dbName, type, identityId, |
||||
|
}) => orbit.determineAddress(dbName, type, { accessController: { write: [identityId] } }) |
||||
|
.then((orbitAddress) => { |
||||
|
const ipfsMultihash = orbitAddress.root; |
||||
|
return `/orbitdb/${ipfsMultihash}/${dbName}`; |
||||
|
}); |
||||
|
|
||||
|
const determineKVAddress = async ({ orbit, dbName, userAddress }) => determineDBAddress({ |
||||
|
orbit, dbName, type: 'keyvalue', identityId: userAddress + EthereumContractIdentityProvider.contractAddress, |
||||
|
}); |
||||
|
|
||||
|
export const createOrbitInstance = async (ipfs, contractAddress) => { |
||||
|
Identities.addIdentityProvider(EthereumContractIdentityProvider); |
||||
|
|
||||
|
EthereumContractIdentityProvider.setWeb3(new Web3()); // We need a fully-featured new Web3 for signature verification
|
||||
|
EthereumContractIdentityProvider.setContractAddress(contractAddress); |
||||
|
|
||||
|
const ORBIT_DIRECTORY = process.env.ORBIT_DIRECTORY || ORBIT_DIRECTORY_DEFAULT; |
||||
|
|
||||
|
return OrbitDB.createInstance(ipfs, { directory: ORBIT_DIRECTORY }); |
||||
|
}; |
||||
|
|
||||
|
export const getPeerDatabases = async (orbit, userAddresses) => Promise.all(userAddresses |
||||
|
.flatMap((userAddress) => [ |
||||
|
determineKVAddress({ orbit, dbName: 'user', userAddress }), |
||||
|
determineKVAddress({ orbit, dbName: 'posts', userAddress }), |
||||
|
determineKVAddress({ orbit, dbName: 'topics', userAddress }), |
||||
|
])); |
||||
|
|
||||
|
export const openKVDBs = async (orbit, databases) => { |
||||
|
databases |
||||
|
.forEach((database) => { |
||||
|
orbit |
||||
|
.keyvalue(database) |
||||
|
.then((store) => store.events.on('replicated', (address) => console.log(`Replicated ${address}`))); |
||||
|
console.log(`Opened ${database}`); |
||||
|
}); |
||||
|
}; |
@ -0,0 +1,60 @@ |
|||||
|
module.exports = { |
||||
|
'env': { |
||||
|
'browser': true, |
||||
|
'es6': true, |
||||
|
'jest': true |
||||
|
}, |
||||
|
'extends': [ |
||||
|
'plugin:react/recommended', |
||||
|
'airbnb' |
||||
|
], |
||||
|
'globals': { |
||||
|
'Atomics': 'readonly', |
||||
|
'SharedArrayBuffer': 'readonly' |
||||
|
}, |
||||
|
parser: 'babel-eslint', |
||||
|
'parserOptions': { |
||||
|
'ecmaFeatures': { |
||||
|
'jsx': true |
||||
|
}, |
||||
|
'ecmaVersion': 2018, |
||||
|
'sourceType': 'module' |
||||
|
}, |
||||
|
'plugins': [ |
||||
|
'react', |
||||
|
'react-hooks', |
||||
|
], |
||||
|
'rules': { |
||||
|
'react/jsx-props-no-spreading': 'off', |
||||
|
'import/extensions': 'off', |
||||
|
"react/jsx-indent": [ |
||||
|
'error', |
||||
|
4, |
||||
|
{ |
||||
|
checkAttributes: true, |
||||
|
indentLogicalExpressions: true |
||||
|
} |
||||
|
], |
||||
|
'react/require-default-props': 'off', |
||||
|
'react/prop-types': 'off', |
||||
|
'react-hooks/rules-of-hooks': 'error', |
||||
|
'react-hooks/exhaustive-deps': 'error', |
||||
|
'max-len': ['warn', {'code': 120, 'tabWidth': 4}], |
||||
|
'no-unused-vars': 'warn', |
||||
|
'no-console': 'warn', |
||||
|
'no-shadow': 'warn', |
||||
|
"no-multi-str": "warn", |
||||
|
"jsx-a11y/label-has-associated-control": [ 2, { |
||||
|
"labelAttributes": ["label"], |
||||
|
"controlComponents": ["Input"], |
||||
|
"depth": 3, |
||||
|
}], |
||||
|
}, |
||||
|
'settings': { |
||||
|
'import/resolver': { |
||||
|
'node': { |
||||
|
'extensions': ['.js', '.jsx'] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,16 @@ |
|||||
|
{ |
||||
|
"name": "concordia-shared", |
||||
|
"version": "0.1.0", |
||||
|
"private": true, |
||||
|
"scripts": { |
||||
|
"lint": "eslint --ext js,jsx . --format table" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"eslint": "^6.8.0", |
||||
|
"eslint-config-airbnb": "^18.1.0", |
||||
|
"eslint-plugin-import": "^2.20.2", |
||||
|
"eslint-plugin-jsx-a11y": "^6.2.3", |
||||
|
"eslint-plugin-react": "^7.19.0", |
||||
|
"eslint-plugin-react-hooks": "^4.2.0" |
||||
|
} |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
const { databases } = require('../constants/orbit/OrbitDatabases'); |
||||
|
const { rendezvousHost, rendezvousPort } = require('../environment/interpolated/rendezvous'); |
||||
|
|
||||
|
const getBreezeConfiguration = (identityProvider) => ({ |
||||
|
ipfs: { |
||||
|
repo: 'concordia', |
||||
|
config: { |
||||
|
Addresses: { |
||||
|
Swarm: [ |
||||
|
// Use local signaling server (see also rendezvous script in package.json)
|
||||
|
// For more information: https://github.com/libp2p/js-libp2p-webrtc-star
|
||||
|
`/ip4/${rendezvousHost}/tcp/${rendezvousPort}/wss/p2p-webrtc-star`, |
||||
|
|
||||
|
// Use the following public servers if needed
|
||||
|
// '/dns4/wrtc-star1.par.dwebops.pub/tcp/443/wss/p2p-webrtc-star',
|
||||
|
// '/dns4/ wrtc-star2.sjc.dwebops.pub/tcp/443/wss/p2p-webrtc-star'
|
||||
|
], |
||||
|
}, |
||||
|
}, |
||||
|
preload: { |
||||
|
enabled: false, |
||||
|
}, |
||||
|
init: { |
||||
|
emptyRepo: true, |
||||
|
}, |
||||
|
}, |
||||
|
orbit: { |
||||
|
identityProvider, |
||||
|
databases, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
module.exports = getBreezeConfiguration; |
@ -0,0 +1,25 @@ |
|||||
|
const getWeb3ProviderUrl = require('../utils/web3'); |
||||
|
const { web3PortSocketConnectMaxAttempts, web3PortSocketTimeout } = require('../environment/interpolated/web3'); |
||||
|
const { web3HostEnv, web3PortEnv } = require('../environment/web3Env'); |
||||
|
|
||||
|
const getWeb3Configuration = (Web3) => { |
||||
|
const web3WebsocketOptions = { |
||||
|
keepAlive: true, |
||||
|
timeout: web3PortSocketTimeout, |
||||
|
reconnect: { |
||||
|
maxAttempts: web3PortSocketConnectMaxAttempts, |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
const web3 = (web3HostEnv !== undefined && web3PortEnv !== undefined) |
||||
|
? new Web3(new Web3.providers.WebsocketProvider(getWeb3ProviderUrl())) |
||||
|
: new Web3(Web3.givenProvider || new Web3.providers.WebsocketProvider(getWeb3ProviderUrl(), web3WebsocketOptions)); |
||||
|
|
||||
|
return { |
||||
|
customProvider: web3, |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
module.exports = { |
||||
|
getWeb3Configuration, |
||||
|
}; |
@ -0,0 +1,46 @@ |
|||||
|
// Contracts provider
|
||||
|
const CONTRACTS_PROVIDER_HOST_DEFAULT = '127.0.0.1'; |
||||
|
const CONTRACTS_PROVIDER_PORT_DEFAULT = '8400'; |
||||
|
const CONTRACTS_VERSION_HASH_DEFAULT = 'latest'; |
||||
|
|
||||
|
// Pinner
|
||||
|
const PINNER_API_PORT_DEFAULT = 4444; |
||||
|
|
||||
|
// Rendezvous
|
||||
|
const RENDEZVOUS_HOST_DEFAULT = '127.0.0.1'; |
||||
|
const RENDEZVOUS_PORT_DEFAULT = '9090'; |
||||
|
|
||||
|
// Web3 (probably ganache)
|
||||
|
const WEB3_HOST_DEFAULT = '127.0.0.1'; |
||||
|
const WEB3_PORT_DEFAULT = '8545'; |
||||
|
const WEB3_HOST_TEST_DEFAULT = '127.0.0.1'; |
||||
|
const WEB3_PORT_TEST_DEFAULT = '8546'; |
||||
|
const WEB3_PORT_SOCKET_TIMEOUT_DEFAULT = 30000; |
||||
|
const WEB3_PORT_SOCKET_CONNECT_MAX_ATTEMPTS_DEFAULT = 3; |
||||
|
|
||||
|
module.exports = Object.freeze({ |
||||
|
contractsProvider: { |
||||
|
host: CONTRACTS_PROVIDER_HOST_DEFAULT, |
||||
|
port: CONTRACTS_PROVIDER_PORT_DEFAULT, |
||||
|
hash: CONTRACTS_VERSION_HASH_DEFAULT, |
||||
|
}, |
||||
|
pinner: { |
||||
|
port: PINNER_API_PORT_DEFAULT, |
||||
|
}, |
||||
|
rendezvous: { |
||||
|
host: RENDEZVOUS_HOST_DEFAULT, |
||||
|
port: RENDEZVOUS_PORT_DEFAULT, |
||||
|
}, |
||||
|
web3: { |
||||
|
develop: { |
||||
|
chainHost: WEB3_HOST_DEFAULT, |
||||
|
chainPort: WEB3_PORT_DEFAULT, |
||||
|
}, |
||||
|
test: { |
||||
|
chainHost: WEB3_HOST_TEST_DEFAULT, |
||||
|
chainPort: WEB3_PORT_TEST_DEFAULT, |
||||
|
}, |
||||
|
socketTimeout: WEB3_PORT_SOCKET_TIMEOUT_DEFAULT, |
||||
|
socketConnectMaxAttempts: WEB3_PORT_SOCKET_CONNECT_MAX_ATTEMPTS_DEFAULT, |
||||
|
}, |
||||
|
}); |
@ -0,0 +1,16 @@ |
|||||
|
const FORUM_CONTRACT = 'Forum'; |
||||
|
const POST_VOTING_CONTRACT = 'PostVoting'; |
||||
|
const VOTING_CONTRACT = 'Voting'; |
||||
|
|
||||
|
const CONTRACTS = [ |
||||
|
FORUM_CONTRACT, |
||||
|
POST_VOTING_CONTRACT, |
||||
|
VOTING_CONTRACT, |
||||
|
]; |
||||
|
|
||||
|
module.exports = Object.freeze({ |
||||
|
FORUM_CONTRACT, |
||||
|
POST_VOTING_CONTRACT, |
||||
|
VOTING_CONTRACT, |
||||
|
CONTRACTS, |
||||
|
}); |
@ -0,0 +1,19 @@ |
|||||
|
const USER_SIGNED_UP_EVENT = 'UserSignedUp'; |
||||
|
const USERNAME_UPDATED_EVENT = 'UsernameUpdated'; |
||||
|
const TOPIC_CREATED_EVENT = 'TopicCreated'; |
||||
|
const POST_CREATED_EVENT = 'PostCreated'; |
||||
|
|
||||
|
const forumContractEvents = Object.freeze([ |
||||
|
USER_SIGNED_UP_EVENT, |
||||
|
USERNAME_UPDATED_EVENT, |
||||
|
TOPIC_CREATED_EVENT, |
||||
|
POST_CREATED_EVENT, |
||||
|
]); |
||||
|
|
||||
|
module.exports = { |
||||
|
USER_SIGNED_UP_EVENT, |
||||
|
USERNAME_UPDATED_EVENT, |
||||
|
TOPIC_CREATED_EVENT, |
||||
|
POST_CREATED_EVENT, |
||||
|
forumContractEvents, |
||||
|
}; |
@ -0,0 +1,8 @@ |
|||||
|
const forumContractEvents = require('./ForumContractEvents'); |
||||
|
const { FORUM_CONTRACT } = require('../ContractNames'); |
||||
|
|
||||
|
const appEvents = Object.freeze({ |
||||
|
[FORUM_CONTRACT]: forumContractEvents, |
||||
|
}); |
||||
|
|
||||
|
module.exports = appEvents; |
@ -0,0 +1,14 @@ |
|||||
|
// Depending on the package user (app in contrast to any of the other packages) the env var names should either include
|
||||
|
// the REACT_APP_ prefix or not
|
||||
|
const contractsProviderHostEnv = process.env.REACT_APP_CONTRACTS_PROVIDER_HOST |
||||
|
|| process.env.CONTRACTS_PROVIDER_HOST; |
||||
|
const contractsProviderPortEnv = process.env.REACT_APP_CONTRACTS_PROVIDER_PORT |
||||
|
|| process.env.CONTRACTS_PROVIDER_PORT; |
||||
|
const contractsVersionHashEnv = process.env.REACT_APP_CONTRACTS_VERSION_HASH |
||||
|
|| process.env.CONTRACTS_VERSION_HASH; |
||||
|
|
||||
|
module.exports = { |
||||
|
contractsProviderHostEnv, |
||||
|
contractsProviderPortEnv, |
||||
|
contractsVersionHashEnv, |
||||
|
}; |
@ -0,0 +1,21 @@ |
|||||
|
const { |
||||
|
contractsProviderHostEnv, contractsProviderPortEnv, contractsVersionHashEnv, |
||||
|
} = require('../contractsProviderEnv'); |
||||
|
|
||||
|
const { |
||||
|
contractsProvider: { |
||||
|
host: CONTRACTS_PROVIDER_HOST_DEFAULT, |
||||
|
port: CONTRACTS_PROVIDER_PORT_DEFAULT, |
||||
|
hash: CONTRACTS_VERSION_HASH_DEFAULT, |
||||
|
}, |
||||
|
} = require('../../constants/configuration/defaults'); |
||||
|
|
||||
|
const contractsProviderHost = contractsProviderHostEnv || CONTRACTS_PROVIDER_HOST_DEFAULT; |
||||
|
const contractsProviderPort = contractsProviderPortEnv || CONTRACTS_PROVIDER_PORT_DEFAULT; |
||||
|
const contractsVersionHash = contractsVersionHashEnv || CONTRACTS_VERSION_HASH_DEFAULT; |
||||
|
|
||||
|
module.exports = { |
||||
|
contractsProviderHost, |
||||
|
contractsProviderPort, |
||||
|
contractsVersionHash, |
||||
|
}; |
@ -0,0 +1,12 @@ |
|||||
|
const { |
||||
|
pinner: { |
||||
|
port: PINNER_API_PORT_DEFAULT, |
||||
|
}, |
||||
|
} = require('../../constants/configuration/defaults'); |
||||
|
const { pinnerApiPortEnv } = require('../pinnerEnv'); |
||||
|
|
||||
|
const pinnerApiPort = pinnerApiPortEnv || PINNER_API_PORT_DEFAULT; |
||||
|
|
||||
|
module.exports = { |
||||
|
pinnerApiPort, |
||||
|
}; |
@ -0,0 +1,15 @@ |
|||||
|
const { rendezvousHostEnv, rendezvousPortEnv } = require('../rendezvousEnv'); |
||||
|
const { |
||||
|
rendezvous: { |
||||
|
host: RENDEZVOUS_HOST_DEFAULT, |
||||
|
port: RENDEZVOUS_PORT_DEFAULT, |
||||
|
}, |
||||
|
} = require('../../constants/configuration/defaults'); |
||||
|
|
||||
|
const rendezvousHost = rendezvousHostEnv || RENDEZVOUS_HOST_DEFAULT; |
||||
|
const rendezvousPort = rendezvousPortEnv || RENDEZVOUS_PORT_DEFAULT; |
||||
|
|
||||
|
module.exports = { |
||||
|
rendezvousHost, |
||||
|
rendezvousPort, |
||||
|
}; |
@ -0,0 +1,9 @@ |
|||||
|
const contractsProvider = require('./contractsProvider'); |
||||
|
const rendezvous = require('./rendezvous'); |
||||
|
const web3 = require('./web3'); |
||||
|
|
||||
|
module.exports = { |
||||
|
contractsProvider, |
||||
|
rendezvous, |
||||
|
web3, |
||||
|
}; |
@ -0,0 +1,37 @@ |
|||||
|
const { |
||||
|
web3: { |
||||
|
develop: { |
||||
|
chainHost: WEB3_HOST_DEFAULT, |
||||
|
chainPort: WEB3_PORT_DEFAULT, |
||||
|
}, |
||||
|
test: { |
||||
|
chainHost: WEB3_HOST_TEST_DEFAULT, |
||||
|
chainPort: WEB3_PORT_TEST_DEFAULT, |
||||
|
}, |
||||
|
socketConnectMaxAttempts: WEB3_PORT_SOCKET_CONNECT_MAX_ATTEMPTS_DEFAULT, |
||||
|
socketTimeout: WEB3_PORT_SOCKET_TIMEOUT_DEFAULT, |
||||
|
}, |
||||
|
} = require('../../constants/configuration/defaults'); |
||||
|
const { |
||||
|
web3HostEnv, web3HostTestEnv, web3PortEnv, web3PortSocketConnectMaxAttemptsEnv, web3PortSocketTimeoutEnv, |
||||
|
web3PortTestEnv, |
||||
|
} = require('../web3Env'); |
||||
|
|
||||
|
const web3Host = web3HostEnv || WEB3_HOST_DEFAULT; |
||||
|
const web3Port = web3PortEnv || WEB3_PORT_DEFAULT; |
||||
|
|
||||
|
const web3HostTest = web3HostTestEnv || WEB3_HOST_TEST_DEFAULT; |
||||
|
const web3PortTest = web3PortTestEnv || WEB3_PORT_TEST_DEFAULT; |
||||
|
|
||||
|
const web3PortSocketTimeout = web3PortSocketTimeoutEnv || WEB3_PORT_SOCKET_TIMEOUT_DEFAULT; |
||||
|
const web3PortSocketConnectMaxAttempts = web3PortSocketConnectMaxAttemptsEnv |
||||
|
|| WEB3_PORT_SOCKET_CONNECT_MAX_ATTEMPTS_DEFAULT; |
||||
|
|
||||
|
module.exports = { |
||||
|
web3Host, |
||||
|
web3Port, |
||||
|
web3HostTest, |
||||
|
web3PortTest, |
||||
|
web3PortSocketTimeout, |
||||
|
web3PortSocketConnectMaxAttempts, |
||||
|
}; |
@ -0,0 +1,7 @@ |
|||||
|
// Depending on the package user (app in contrast to any of the other packages) the env var names should either include
|
||||
|
// the REACT_APP_ prefix or not
|
||||
|
const pinnerApiPortEnv = process.env.REACT_APP_PINNER_API_PORT || process.env.PINNER_API_PORT; |
||||
|
|
||||
|
module.exports = { |
||||
|
pinnerApiPortEnv, |
||||
|
}; |
@ -0,0 +1,9 @@ |
|||||
|
// Depending on the package user (app in contrast to any of the other packages) the env var names should either include
|
||||
|
// the REACT_APP_ prefix or not
|
||||
|
const rendezvousHostEnv = process.env.REACT_APP_RENDEZVOUS_HOST || process.env.RENDEZVOUS_HOST; |
||||
|
const rendezvousPortEnv = process.env.REACT_APP_RENDEZVOUS_PORT || process.env.RENDEZVOUS_PORT; |
||||
|
|
||||
|
module.exports = { |
||||
|
rendezvousHostEnv, |
||||
|
rendezvousPortEnv, |
||||
|
}; |
@ -0,0 +1,9 @@ |
|||||
|
const contractsProvider = require('./contractsProviderEnv'); |
||||
|
const rendezvous = require('./rendezvousEnv'); |
||||
|
const web3 = require('./web3Env'); |
||||
|
|
||||
|
module.exports = { |
||||
|
contractsProvider, |
||||
|
rendezvous, |
||||
|
web3, |
||||
|
}; |
@ -0,0 +1,24 @@ |
|||||
|
// Depending on the package user (app in contrast to any of the other packages) the env var names should either include
|
||||
|
// the REACT_APP_ prefix or not
|
||||
|
const web3HostEnv = process.env.REACT_APP_WEB3_HOST |
||||
|
|| process.env.WEB3_HOST; |
||||
|
const web3PortEnv = process.env.REACT_APP_WEB3_PORT |
||||
|
|| process.env.WEB3_PORT; |
||||
|
|
||||
|
// Web3 test environment shouldn't be available to the react app
|
||||
|
const web3HostTestEnv = process.env.WEB3_HOST_TEST; |
||||
|
const web3PortTestEnv = process.env.WEB3_PORT_TEST; |
||||
|
|
||||
|
const web3PortSocketTimeoutEnv = process.env.REACT_APP_WEB3_PORT_SOCKET_TIMEOUT |
||||
|
|| process.env.WEB3_PORT_SOCKET_TIMEOUT; |
||||
|
const web3PortSocketConnectMaxAttemptsEnv = process.env.REACT_APP_WEB3_PORT_SOCKET_CONNECT_MAX_ATTEMPTS |
||||
|
|| process.env.WEB3_PORT_SOCKET_CONNECT_MAX_ATTEMPTS; |
||||
|
|
||||
|
module.exports = { |
||||
|
web3HostEnv, |
||||
|
web3PortEnv, |
||||
|
web3HostTestEnv, |
||||
|
web3PortTestEnv, |
||||
|
web3PortSocketTimeoutEnv, |
||||
|
web3PortSocketConnectMaxAttemptsEnv, |
||||
|
}; |
@ -0,0 +1,5 @@ |
|||||
|
const { rendezvousHost, rendezvousPort } = require('../environment/interpolated/rendezvous'); |
||||
|
|
||||
|
const getRendezvousUrl = () => `http://${rendezvousHost}:${rendezvousPort}`; |
||||
|
|
||||
|
module.exports = getRendezvousUrl; |
@ -0,0 +1,6 @@ |
|||||
|
const { web3Port } = require('../environment/interpolated/web3'); |
||||
|
const { web3Host } = require('../environment/interpolated/web3'); |
||||
|
|
||||
|
const getWeb3ProviderUrl = () => `ws://${web3Host}:${web3Port}`; |
||||
|
|
||||
|
module.exports = getWeb3ProviderUrl; |
File diff suppressed because it is too large
Loading…
Reference in new issue