import Web3 from 'web3'; import Contract from 'web3-eth-contract'; import IPFS from 'ipfs'; import express from 'express' import isReachable from 'is-reachable'; //TODO: health checking web3 network and rendezvous import _ from 'lodash'; import { forumContract } from 'concordia-contracts'; import { createOrbitInstance, getPeerDatabases, openKVDBs } from './utils/orbitUtils'; import ipfsOptions from './options/ipfsOptions'; import { web3ProviderUrl } from './constants'; const API_PORT = process.env.PINNER_API_PORT || 4444; 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); } }); let ipfs; async function main () { const web3 = new Web3(new Web3.providers.WebsocketProvider(web3ProviderUrl)); const networkId = await web3.eth.net.getId(); const contractAddress = forumContract.networks[networkId].address; Contract.setProvider(web3ProviderUrl); const contract = new Contract(forumContract.abi, contractAddress); ipfs = await IPFS.create(ipfsOptions); const orbit = await createOrbitInstance(ipfs, contractAddress); // Open & replicate databases of existing users const userAddresses = await contract.methods.getUserAddresses().call(); const peerDBs = await getPeerDatabases(orbit, userAddresses); await openKVDBs(orbit, peerDBs); // Listen for new users and subscribe to their databases const eventJsonInterface = web3.utils._.find( contract._jsonInterface, obj => obj.name === "UserSignedUp" && obj.type === 'event' ); web3.eth.subscribe('logs', { address: contractAddress, topics: [eventJsonInterface.signature] }, function(error, result){ if (!error) { const eventObj = web3.eth.abi.decodeLog( eventJsonInterface.inputs, result.data, result.topics.slice(1) ) console.log(`User signed up:`, eventObj[1]); getPeerDatabases(orbit, userAddresses).then(peerDBs => openKVDBs(orbit, peerDBs)); } }); } main(); const app = express(); app.get('/', async (req, res) => { let responseBody = {peers:[], totalPeers:0}; const peers = await ipfs.swarm.peers(); //TODO: surround with try const uniquePeers = _.uniqBy(peers, 'peer'); responseBody.peers = uniquePeers; responseBody.totalPeers = uniquePeers.length; res.send(responseBody); }); app.listen(API_PORT, () => { console.log(`Pinner API at http://localhost:${API_PORT}!`); });