9f5f70a93f
adds option on client file import and client retrieval to read/write to CAR file
229 lines
5.5 KiB
JavaScript
229 lines
5.5 KiB
JavaScript
import React from 'react'
|
|
import Address from './Address'
|
|
import Window from './Window'
|
|
import Fil from './Fil'
|
|
|
|
const dealStates = [
|
|
'Unknown',
|
|
'ProposalNotFound',
|
|
'ProposalRejected',
|
|
'ProposalAccepted',
|
|
'Staged',
|
|
'Sealing',
|
|
'ProposalSigned',
|
|
'Published',
|
|
'Committed',
|
|
'Active',
|
|
'Failing',
|
|
'Recovering',
|
|
'Expired',
|
|
'NotFound',
|
|
|
|
'Validating',
|
|
'Transferring',
|
|
'VerifyData',
|
|
'Publishing',
|
|
'Error'
|
|
]
|
|
|
|
class Client extends React.Component {
|
|
constructor(props) {
|
|
super(props)
|
|
|
|
this.state = {
|
|
miners: ['t0101'],
|
|
ask: { Price: '1000000000' }, // 2x min default ask to account for bin packing (could also do the math correctly below, but..)
|
|
|
|
kbs: 1,
|
|
blocks: 12,
|
|
total: 36000,
|
|
miner: 't0101',
|
|
|
|
deals: [],
|
|
|
|
blockDelay: 10
|
|
}
|
|
}
|
|
|
|
async componentDidMount() {
|
|
let ver = await this.props.client.call('Filecoin.Version', [])
|
|
this.setState({ blockDelay: ver.BlockDelay })
|
|
|
|
this.getDeals()
|
|
setInterval(this.getDeals, 1325)
|
|
}
|
|
|
|
getDeals = async () => {
|
|
let miners = await this.props.client.call('Filecoin.StateListMiners', [
|
|
null
|
|
])
|
|
let deals = await this.props.client.call('Filecoin.ClientListDeals', [])
|
|
miners.sort()
|
|
this.setState({ deals, miners })
|
|
}
|
|
|
|
update = name => e => this.setState({ [name]: e.target.value })
|
|
|
|
makeDeal = async () => {
|
|
let perBlk =
|
|
((this.state.ask.Price * this.state.kbs * 1000) / (1 << 30)) * 2
|
|
|
|
let file = await this.props.pondClient.call('Pond.CreateRandomFile', [
|
|
this.state.kbs * 1000
|
|
]) // 1024 won't fit in 1k blocks :(
|
|
let cid = await this.props.client.call('Filecoin.ClientImport', [
|
|
{
|
|
Path: file,
|
|
IsCar: false
|
|
}
|
|
])
|
|
let dealcid = await this.props.client.call('Filecoin.ClientStartDeal', [
|
|
cid,
|
|
this.state.miner,
|
|
`${Math.round(perBlk)}`,
|
|
Number(this.state.blocks)
|
|
])
|
|
console.log('deal cid: ', dealcid)
|
|
}
|
|
|
|
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
|
|
Total: String(deal.Size * 2),
|
|
|
|
Client: client,
|
|
Miner: deal.Miner
|
|
}
|
|
|
|
await this.props.client.call('Filecoin.ClientRetrieve', [
|
|
order,
|
|
{
|
|
Path: '/dev/null',
|
|
IsCAR: false
|
|
}
|
|
])
|
|
}
|
|
|
|
render() {
|
|
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
|
|
|
|
let dealMaker = (
|
|
<div hidden={!this.props.pondClient}>
|
|
<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>
|
|
<button onClick={this.makeDeal}>Deal!</button>
|
|
</div>
|
|
)
|
|
|
|
let deals = this.state.deals.map((deal, i) => (
|
|
<div key={i}>
|
|
<ul>
|
|
<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>
|
|
{dealStates[deal.State] === 'Complete' ? (
|
|
<span>
|
|
|
|
<a href="#" onClick={this.retrieve(deal)}>
|
|
[Retrieve]
|
|
</a>
|
|
</span>
|
|
) : (
|
|
<span />
|
|
)}
|
|
<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>
|
|
))
|
|
|
|
return (
|
|
<Window
|
|
title={'Client - Node ' + this.props.node.ID}
|
|
onClose={this.props.onClose}
|
|
initialSize={{ width: 600, height: 400 }}
|
|
>
|
|
<div className="Client">
|
|
<div>{dealMaker}</div>
|
|
<div>{deals}</div>
|
|
</div>
|
|
</Window>
|
|
)
|
|
}
|
|
}
|
|
|
|
export default Client
|