2019-09-06 17:43:24 +00:00
|
|
|
import React from 'react';
|
2019-09-10 14:48:54 +00:00
|
|
|
import Address from "./Address";
|
2019-09-19 14:27:01 +00:00
|
|
|
import Window from "./Window";
|
2019-10-25 12:44:53 +00:00
|
|
|
import Fil from "./Fil";
|
2019-09-10 14:48:54 +00:00
|
|
|
|
|
|
|
const dealStates = [
|
|
|
|
"Unknown",
|
|
|
|
"Rejected",
|
|
|
|
"Accepted",
|
|
|
|
"Staged",
|
|
|
|
"Sealing",
|
2019-10-24 14:22:30 +00:00
|
|
|
"Failed",
|
2019-09-10 14:48:54 +00:00
|
|
|
"Complete",
|
2019-09-13 19:43:33 +00:00
|
|
|
"Error",
|
2019-09-10 14:48:54 +00:00
|
|
|
]
|
|
|
|
|
2019-09-06 17:43:24 +00:00
|
|
|
|
|
|
|
class Client extends React.Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props)
|
|
|
|
|
|
|
|
this.state = {
|
2019-10-25 12:44:53 +00:00
|
|
|
miners: ["t0101"],
|
2019-11-06 19:00:04 +00:00
|
|
|
ask: {Price: "1000000000"}, // 2x min default ask to account for bin packing (could also do the math correctly below, but..)
|
2019-10-25 12:44:53 +00:00
|
|
|
|
2019-09-06 17:43:24 +00:00
|
|
|
kbs: 1,
|
|
|
|
blocks: 12,
|
2019-09-06 22:35:31 +00:00
|
|
|
total: 36000,
|
2019-09-10 14:48:54 +00:00
|
|
|
miner: "t0101",
|
|
|
|
|
2019-10-25 12:44:53 +00:00
|
|
|
deals: [],
|
|
|
|
|
|
|
|
blockDelay: 10,
|
2019-09-06 17:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-25 12:44:53 +00:00
|
|
|
async componentDidMount() {
|
|
|
|
let ver = await this.props.client.call('Filecoin.Version', [])
|
|
|
|
this.setState({blockDelay: ver.BlockDelay})
|
|
|
|
|
2019-09-10 14:48:54 +00:00
|
|
|
this.getDeals()
|
|
|
|
setInterval(this.getDeals, 1325)
|
|
|
|
}
|
|
|
|
|
|
|
|
getDeals = async () => {
|
2019-10-25 12:44:53 +00:00
|
|
|
let miners = await this.props.client.call('Filecoin.StateListMiners', [null])
|
2019-09-10 14:48:54 +00:00
|
|
|
let deals = await this.props.client.call('Filecoin.ClientListDeals', [])
|
2019-10-25 12:44:53 +00:00
|
|
|
miners.sort()
|
|
|
|
this.setState({deals, miners})
|
2019-09-10 14:48:54 +00:00
|
|
|
}
|
|
|
|
|
2019-09-06 17:43:24 +00:00
|
|
|
update = (name) => (e) => this.setState({ [name]: e.target.value });
|
|
|
|
|
|
|
|
makeDeal = async () => {
|
2019-11-06 19:00:04 +00:00
|
|
|
let perBlk = this.state.ask.Price * this.state.kbs * 1000 / (1 << 30) * 2
|
2019-10-25 12:44:53 +00:00
|
|
|
|
2019-09-06 22:35:31 +00:00
|
|
|
let file = await this.props.pondClient.call('Pond.CreateRandomFile', [this.state.kbs * 1000]) // 1024 won't fit in 1k blocks :(
|
2019-09-06 17:43:24 +00:00
|
|
|
let cid = await this.props.client.call('Filecoin.ClientImport', [file])
|
2019-10-25 12:44:53 +00:00
|
|
|
let dealcid = await this.props.client.call('Filecoin.ClientStartDeal', [cid, this.state.miner, `${Math.round(perBlk)}`, Number(this.state.blocks)])
|
2019-09-06 17:43:24 +00:00
|
|
|
console.log("deal cid: ", dealcid)
|
|
|
|
}
|
|
|
|
|
2019-09-16 20:11:17 +00:00
|
|
|
retrieve = (deal) => async () => {
|
|
|
|
console.log(deal)
|
|
|
|
let client = await this.props.client.call('Filecoin.WalletDefaultAddress', [])
|
|
|
|
|
|
|
|
let order = {
|
|
|
|
Root: deal.PieceRef,
|
|
|
|
Size: deal.Size,
|
|
|
|
// TODO: support offset
|
2019-09-16 21:25:23 +00:00
|
|
|
Total: String(deal.Size * 2),
|
2019-09-16 20:11:17 +00:00
|
|
|
|
|
|
|
Client: client,
|
|
|
|
Miner: deal.Miner
|
|
|
|
}
|
|
|
|
|
|
|
|
await this.props.client.call('Filecoin.ClientRetrieve', [order, '/dev/null'])
|
|
|
|
}
|
|
|
|
|
2019-09-06 17:43:24 +00:00
|
|
|
render() {
|
2019-10-25 12:44:53 +00:00
|
|
|
let perBlk = this.state.ask.Price * this.state.kbs * 1000
|
|
|
|
let total = perBlk * this.state.blocks
|
|
|
|
let days = (this.state.blocks * this.state.blockDelay) / 60 / 60 / 24
|
2019-09-06 17:43:24 +00:00
|
|
|
|
2019-09-18 17:53:48 +00:00
|
|
|
let dealMaker = <div hidden={!this.props.pondClient}>
|
2019-10-25 12:44:53 +00:00
|
|
|
<div>
|
|
|
|
<span>Make Deal: </span>
|
|
|
|
<select>{this.state.miners.map(m => <option key={m} value={m}>{m}</option>)}</select>
|
|
|
|
<span> Ask: <b><Fil>{this.state.ask.Price}</Fil></b> Fil/Byte/Block</span>
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
Data Size: <input type="text" placeholder="KBs" defaultValue={1} onChange={this.update("kbs")} style={{width: "5em"}}/>KB;
|
|
|
|
Duration:<input type="text" placeholder="blocks" defaultValue={12} onChange={this.update("blocks")} style={{width: "5em"}}/>Blocks
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
Total: <Fil>{total}</Fil>; {days} Days
|
|
|
|
</div>
|
2019-09-06 17:43:24 +00:00
|
|
|
<button onClick={this.makeDeal}>Deal!</button>
|
|
|
|
</div>
|
|
|
|
|
2019-09-10 14:48:54 +00:00
|
|
|
let deals = this.state.deals.map((deal, i) => <div key={i}>
|
|
|
|
<ul>
|
2019-10-24 14:22:30 +00:00
|
|
|
<li>{i}. Proposal: {deal.ProposalCid['/'].substr(0, 18)}... <Address nobalance={true} client={this.props.client} addr={deal.Provider} mountWindow={this.props.mountWindow}/>: <b>{dealStates[deal.State]}</b>
|
2019-09-16 20:11:17 +00:00
|
|
|
{dealStates[deal.State] === 'Complete' ? <span> <a href="#" onClick={this.retrieve(deal)}>[Retrieve]</a></span> : <span/> }
|
2019-09-10 14:48:54 +00:00
|
|
|
<ul>
|
|
|
|
<li>Data: {deal.PieceRef['/']}, <b>{deal.Size}</b>B; Duration: <b>{deal.Duration}</b>Blocks</li>
|
|
|
|
<li>Total: <b>{deal.TotalPrice}</b>FIL; Per Block: <b>{Math.round(deal.TotalPrice / deal.Duration * 100) / 100}</b>FIL; PerMbyteByteBlock: <b>{Math.round(deal.TotalPrice / deal.Duration / (deal.Size / 1000000) * 100) / 100}</b>FIL</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
</div>)
|
|
|
|
|
2019-10-25 12:44:53 +00:00
|
|
|
return <Window title={"Client - Node " + this.props.node.ID} onClose={this.props.onClose} initialSize={{width: 600, height: 400}}>
|
2019-09-10 14:48:54 +00:00
|
|
|
<div className="Client">
|
|
|
|
<div>{dealMaker}</div>
|
|
|
|
<div>{deals}</div>
|
|
|
|
</div>
|
2019-09-19 14:27:01 +00:00
|
|
|
</Window>
|
2019-09-06 17:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default Client
|