import React from 'react'; import { Client } from 'rpc-websockets' import Cristal from 'react-cristal' import { BlockLinks } from "./BlockLink"; import StorageNodeInit from "./StorageNodeInit"; const stateConnected = 'connected' const stateConnecting = 'connecting' const stateGettingToken = 'getting-token' async function awaitListReducer(prev, c) { return [...await prev, await c] } function truncAddr(addr) { if (addr.length > 41) { return {addr.substr(0, 38) + '...'} } return addr } class FullNode extends React.Component { constructor(props) { super(props) this.state = { state: stateGettingToken, id: "~", mining: false, } this.loadInfo = this.loadInfo.bind(this) this.startMining = this.startMining.bind(this) this.newScepAddr = this.newScepAddr.bind(this) this.startStorageMiner = this.startStorageMiner.bind(this) this.connect() } async connect() { console.log("gettok") const token = await this.props.pondClient.call('Pond.TokenFor', [this.props.node.ID]) this.setState(() => ({ state: stateConnecting, token: token, })) const client = new Client(`ws://127.0.0.1:${this.props.node.ApiPort}/rpc/v0?token=${token}`) client.on('open', async () => { this.setState(() => ({ state: stateConnected, client: client, version: {Version: "~version~"}, id: "~peerid~", peers: -1, balances: [] })) const id = await this.state.client.call("Filecoin.ID", []) this.setState(() => ({id: id})) this.props.onConnect(client, id) this.loadInfo() setInterval(this.loadInfo, 2050) }) console.log(token) // todo: use } async loadInfo() { const version = await this.state.client.call("Filecoin.Version", []) this.setState(() => ({version: version})) const peers = await this.state.client.call("Filecoin.NetPeers", []) this.setState(() => ({peers: peers.length})) const tipset = await this.state.client.call("Filecoin.ChainHead", []) this.setState(() => ({tipset: tipset})) const addrss = await this.state.client.call('Filecoin.WalletList', []) let defaultAddr = "" if (addrss.length > 0) { defaultAddr = await this.state.client.call('Filecoin.WalletDefaultAddress', []) } const balances = await addrss.map(async addr => { let balance = 0 try { balance = await this.state.client.call('Filecoin.WalletBalance', [addr]) } catch { balance = -1 } return [addr, balance] }).reduce(awaitListReducer, Promise.resolve([])) this.setState(() => ({balances: balances, defaultAddr: defaultAddr})) } async startMining() { // TODO: Use actual miner address // see cli/miner.go this.setState({mining: true}) let addr = "t0523423423" // in case we have no wallets if (this.state.defaultAddr) { addr = this.state.defaultAddr } this.setState({mining: true}) await this.state.client.call("Filecoin.MinerStart", [addr]) } async newScepAddr() { const t = "secp256k1" await this.state.client.call("Filecoin.WalletNew", [t]) this.loadInfo() } async startStorageMiner() { this.props.mountWindow((onClose) => ) } render() { let runtime = if (this.state.state === stateConnected) { let chainInfo = if (this.state.tipset !== undefined) { chainInfo = ( Head: { } H:{this.state.tipset.Height} ) } let mine = [Mine] if (this.state.mining) { mine = "[Mining]" } let storageMine = [Spawn Storage Miner] let balances = this.state.balances.map(([addr, balance]) => { let line = {truncAddr(addr)}: {balance} (ActTyp) if (this.state.defaultAddr === addr) { line = {line} } return {line} }) runtime = ( v{this.state.version.Version}, {this.state.id.substr(-8)}, {this.state.peers} peers Repo: LOTUS_PATH={this.props.node.Repo} {chainInfo} {mine} {storageMine} Balances: [New [Secp256k1]] {balances} ) } return ( {this.props.node.ID} - {this.state.state} {runtime} ) } } export default FullNode