@ethersphere/swarm-cli
Version:
CLI tool for Bee
141 lines (113 loc) • 4.79 kB
text/typescript
import { BatchId, Utils } from '@ethersphere/bee-js'
import { Dates, Numbers } from 'cafe-utility'
import chalk from 'chalk'
import { BigNumber } from 'ethers'
import { LeafCommand, Option } from 'furious-commander'
import { exit } from 'process'
import { isChainStateReady } from '../../utils/chainsync'
import { createSpinner } from '../../utils/spinner'
import { createKeyValue } from '../../utils/text'
import { VerbosityLevel } from '../root-command/command-log'
import { StampCommand } from './stamp-command'
export class Buy extends StampCommand implements LeafCommand {
public readonly name = 'buy'
public readonly description = 'Buy postage stamp based on depth and amount'
public depth!: number
public amount!: bigint
public gasPrice!: bigint
public immutable!: boolean
public label!: string
public waitUsable!: boolean
// CLASS FIELDS
public postageBatchId!: BatchId
public async run(): Promise<void> {
super.init()
if (!(await isChainStateReady(this.bee))) {
this.console.error('Synchronization with the blockchain is not yet complete.')
this.console.error('Please wait until the Bee is fully synced before buying a postage stamp.')
this.console.error('You can check the synchronization status with the "status" command.')
return
}
const chainState = await this.bee.getChainState()
const minimumAmount = BigNumber.from(chainState.currentPrice).mul(17280)
if (minimumAmount.gte(BigNumber.from(this.amount))) {
this.console.error('The amount is too low. The minimum amount is', minimumAmount.add(1).toString())
return
}
const estimatedCost = Utils.getStampCost(this.depth, BigInt(this.amount))
const { bzzBalance } = await this.bee.getWalletBalance()
if (!this.dev && estimatedCost.gt(bzzBalance)) {
this.console.error('You do not have enough BZZ to create this postage stamp.')
this.console.error(`Estimated cost: ${estimatedCost.toDecimalString()} xBZZ`)
this.console.error(`Available balance: ${bzzBalance.toDecimalString()} xBZZ`)
this.console.log('')
this.console.log('Visit the following link to learn how to fund your Bee node:')
this.console.log(chalk.blue('https://docs.ethswarm.org/docs/bee/installation/fund-your-node/'))
exit(1)
}
const estimatedCapacity = Numbers.convertBytes(Utils.getStampEffectiveBytes(this.depth))
const estimatedTtl = Utils.getStampDuration(BigInt(this.amount), Number(chainState.currentPrice), 5)
this.console.log(createKeyValue('Estimated cost', `${estimatedCost.toDecimalString()} xBZZ`))
this.console.log(createKeyValue('Estimated capacity', estimatedCapacity))
this.console.log(createKeyValue('Estimated TTL', Dates.secondsToHumanTime(estimatedTtl.toSeconds())))
this.console.log(createKeyValue('Type', this.immutable ? 'Immutable' : 'Mutable'))
if (this.immutable) {
this.console.info('At full capacity, an immutable stamp no longer allows new content uploads.')
} else {
this.console.info('At full capacity, a mutable stamp allows new content uploads, but overwrites old content.')
}
if (!this.quiet && !this.yes) {
this.yes = await this.console.confirm('Confirm the purchase')
}
if (!this.yes && !this.quiet) {
return
}
const spinner = createSpinner('Creating postage batch. This may take up to 5 minutes.')
if (this.verbosity !== VerbosityLevel.Quiet && !this.curl) {
spinner.start()
}
try {
const batchId = await this.bee.createPostageBatch(this.amount.toString(), this.depth, {
label: this.label,
gasPrice: this.gasPrice?.toString(),
immutableFlag: this.immutable,
waitForUsable: this.waitUsable === false ? false : true,
})
spinner.stop()
this.console.quiet(batchId.toHex())
this.console.log(createKeyValue('Stamp ID', batchId.toHex()))
this.postageBatchId = batchId
} finally {
spinner.stop()
}
}
}