Skip to content

Commit

Permalink
Use new render function in the CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
mat-if committed Apr 9, 2024
1 parent d6856bc commit e1f4dd5
Show file tree
Hide file tree
Showing 16 changed files with 242 additions and 119 deletions.
89 changes: 50 additions & 39 deletions ironfish-cli/src/commands/wallet/balance.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { CurrencyUtils, GetBalanceResponse, isNativeIdentifier } from '@ironfish/sdk'
import { CurrencyUtils, GetBalanceResponse, isNativeIdentifier, RpcAsset } from '@ironfish/sdk'
import { Flags } from '@oclif/core'
import { IronfishCommand } from '../../command'
import { RemoteFlags } from '../../flags'
Expand Down Expand Up @@ -54,60 +54,56 @@ export class BalanceCommand extends IronfishCommand {
confirmations: flags.confirmations,
})

const assetId = response.content.assetId

const asset = (
await client.wallet.getAsset({
account,
id: response.content.assetId,
id: assetId,
confirmations: flags.confirmations,
})
).content

const assetId = response.content.assetId
const assetName = renderAssetName(isNativeIdentifier(assetId) ? '$IRON' : assetId, {
let nameToRender
if (isNativeIdentifier(assetId)) {
nameToRender = '$IRON'
} else if (asset.symbol) {
nameToRender = asset.symbol
} else {
nameToRender = assetId
}

const assetName = renderAssetName(nameToRender, {
verification: asset.verification,
verbose: !!flags.verbose,
logWarn: this.warn.bind(this),
})

if (flags.explain) {
this.explainBalance(response.content, assetName)
this.explainBalance(response.content, asset, assetName)
return
}

const renderedAvailable = renderValue(response.content.available, asset, assetName)
const renderedConfirmed = renderValue(response.content.confirmed, asset, assetName)
const renderedUnconfirmed = renderValue(response.content.unconfirmed, asset, assetName)
const renderedPending = renderValue(response.content.pending, asset, assetName)
if (flags.all) {
this.log(`Account: ${response.content.account}`)
this.log(`Head Hash: ${response.content.blockHash || 'NULL'}`)
this.log(`Head Sequence: ${response.content.sequence || 'NULL'}`)
this.log(
`Available: ${CurrencyUtils.renderIron(response.content.available, true, assetName)}`,
)
this.log(
`Confirmed: ${CurrencyUtils.renderIron(response.content.confirmed, true, assetName)}`,
)
this.log(
`Unconfirmed: ${CurrencyUtils.renderIron(
response.content.unconfirmed,
true,
assetName,
)}`,
)
this.log(
`Pending: ${CurrencyUtils.renderIron(response.content.pending, true, assetName)}`,
)
this.log(`Available: ${renderedAvailable}`)
this.log(`Confirmed: ${renderedConfirmed}`)
this.log(`Unconfirmed: ${renderedUnconfirmed}`)
this.log(`Pending: ${renderedPending}`)
return
}

this.log(`Account: ${response.content.account}`)
this.log(
`Available Balance: ${CurrencyUtils.renderIron(
response.content.available,
true,
assetName,
)}`,
)
this.log(`Available Balance: ${renderedAvailable}`)
}

explainBalance(response: GetBalanceResponse, assetId: string): void {
explainBalance(response: GetBalanceResponse, asset: RpcAsset, assetName: string): void {
const unconfirmed = CurrencyUtils.decode(response.unconfirmed)
const confirmed = CurrencyUtils.decode(response.confirmed)
const pending = CurrencyUtils.decode(response.pending)
Expand All @@ -116,6 +112,13 @@ export class BalanceCommand extends IronfishCommand {
const unconfirmedDelta = unconfirmed - confirmed
const pendingDelta = pending - unconfirmed

const renderedUnconfirmed = renderValue(unconfirmed, asset, assetName)
const renderedUnconfirmedDelta = renderValue(unconfirmedDelta, asset, assetName)
const renderedConfirmed = renderValue(confirmed, asset, assetName)
const renderedPending = renderValue(pending, asset, assetName)
const renderedPendingDelta = renderValue(pendingDelta, asset, assetName)
const renderedAvailable = renderValue(available, asset, assetName)

this.log(`Account: ${response.account}`)

this.log(
Expand All @@ -126,26 +129,34 @@ export class BalanceCommand extends IronfishCommand {
this.log('')

this.log(`Your available balance is made of notes on the chain that are safe to spend`)
this.log(`Available: ${CurrencyUtils.renderIron(available, true, assetId)}`)
this.log(`Available: ${renderedAvailable}`)
this.log('')

this.log('Your confirmed balance includes all notes from transactions on the chain')
this.log(`Confirmed: ${CurrencyUtils.renderIron(confirmed, true, assetId)}`)
this.log(`Confirmed: ${renderedConfirmed}`)
this.log('')

this.log(
`${response.unconfirmedCount} transactions worth ${CurrencyUtils.renderIron(
unconfirmedDelta,
)} are on the chain within ${response.confirmations} blocks of the head`,
`${response.unconfirmedCount} transactions worth ${renderedUnconfirmedDelta} are on the chain within ${response.confirmations} blocks of the head`,
)
this.log(`Unconfirmed: ${CurrencyUtils.renderIron(unconfirmed, true, assetId)}`)
this.log(`Unconfirmed: ${renderedUnconfirmed}`)
this.log('')

this.log(
`${response.pendingCount} transactions worth ${CurrencyUtils.renderIron(
pendingDelta,
)} are pending and have not been added to the chain`,
`${response.pendingCount} transactions worth ${renderedPendingDelta} are pending and have not been added to the chain`,
)
this.log(`Pending: ${CurrencyUtils.renderIron(pending, true, assetId)}`)
this.log(`Pending: ${renderedPending}`)
}
}

// TODO(mat): Eventually this logic should probably be rolled into
// CurrencyUtils.render() via additional options
function renderValue(amount: string | bigint, asset: RpcAsset, assetName: string): string {
const renderNameManually = asset.verification.status === 'verified'

if (renderNameManually) {
return `${assetName} ${CurrencyUtils.render(amount, false, asset)}`
} else {
return CurrencyUtils.render(amount, true, asset)
}
}
8 changes: 4 additions & 4 deletions ironfish-cli/src/commands/wallet/balances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class BalancesCommand extends IronfishCommand {
},
available: {
header: 'Available Balance',
get: ({ balance }) => CurrencyUtils.renderIron(balance.available),
get: ({ asset, balance }) => CurrencyUtils.render(balance.available, false, asset),
},
}

Expand All @@ -85,15 +85,15 @@ export class BalancesCommand extends IronfishCommand {
...columns,
confirmed: {
header: 'Confirmed Balance',
get: ({ balance }) => CurrencyUtils.renderIron(balance.confirmed),
get: ({ asset, balance }) => CurrencyUtils.render(balance.confirmed, false, asset),
},
unconfirmed: {
header: 'Unconfirmed Balance',
get: ({ balance }) => CurrencyUtils.renderIron(balance.unconfirmed),
get: ({ asset, balance }) => CurrencyUtils.render(balance.unconfirmed, false, asset),
},
pending: {
header: 'Pending Balance',
get: ({ balance }) => CurrencyUtils.renderIron(balance.pending),
get: ({ asset, balance }) => CurrencyUtils.render(balance.pending, false, asset),
},
blockHash: {
header: 'Head Hash',
Expand Down
38 changes: 19 additions & 19 deletions ironfish-cli/src/commands/wallet/burn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
CurrencyUtils,
RawTransaction,
RawTransactionSerde,
RpcAsset,
Transaction,
} from '@ironfish/sdk'
import { CliUx, Flags } from '@oclif/core'
Expand Down Expand Up @@ -130,6 +131,14 @@ export class Burn extends IronfishCommand {
this.error(`You must have a custom asset in order to burn.`)
}

const assetData = (
await client.wallet.getAsset({
account,
id: assetId,
confirmations: flags.confirmations,
})
).content

let amount = flags.amount
if (!amount) {
amount = await promptCurrency({
Expand All @@ -141,7 +150,7 @@ export class Burn extends IronfishCommand {
balance: {
account,
confirmations: flags.confirmations,
assetId,
asset: assetData,
},
})
}
Expand Down Expand Up @@ -183,7 +192,7 @@ export class Burn extends IronfishCommand {
this.exit(0)
}

if (!flags.confirm && !(await this.confirm(assetId, amount, raw.fee, account))) {
if (!flags.confirm && !(await this.confirm(assetData, amount, raw.fee, account))) {
this.error('Transaction aborted.')
}

Expand All @@ -209,18 +218,14 @@ export class Burn extends IronfishCommand {
this.warn(`Transaction '${transaction.hash().toString('hex')}' failed to broadcast`)
}

const assetResponse = await client.wallet.getAsset({
account,
id: assetId,
confirmations: flags.confirmations,
})
const assetName = BufferUtils.toHuman(Buffer.from(assetResponse.content.name, 'hex'))
const assetName = BufferUtils.toHuman(Buffer.from(assetData.name, 'hex'))
const renderedAmount = CurrencyUtils.render(amount, false, assetData)

this.log(`Burned asset ${assetName} from ${account}`)
this.log(`Asset Identifier: ${assetId}`)
this.log(`Amount: ${CurrencyUtils.renderIron(amount)}`)
this.log(`Amount: ${renderedAmount}`)
this.log(`Hash: ${transaction.hash().toString('hex')}`)
this.log(`Fee: ${CurrencyUtils.renderIron(transaction.fee(), true)}`)
this.log(`Fee: ${CurrencyUtils.render(transaction.fee(), true)}`)

const networkId = (await client.chain.getNetworkInfo()).content.networkId
const transactionUrl = getExplorer(networkId)?.getTransactionUrl(
Expand All @@ -244,20 +249,15 @@ export class Burn extends IronfishCommand {
}

async confirm(
assetId: string,
asset: RpcAsset,
amount: bigint,
fee: bigint,
account: string,
): Promise<boolean> {
const renderedAmount = CurrencyUtils.render(amount, true, asset)
const renderedFee = CurrencyUtils.render(fee, true)
this.log(
`You are about to burn: ${CurrencyUtils.renderIron(
amount,
true,
assetId,
)} plus a transaction fee of ${CurrencyUtils.renderIron(
fee,
true,
)} with the account ${account}`,
`You are about to burn: ${renderedAmount} plus a transaction fee of ${renderedFee} with the account ${account}`,
)

return CliUx.ux.confirm('Do you confirm (Y/N)?')
Expand Down
46 changes: 27 additions & 19 deletions ironfish-cli/src/commands/wallet/mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
isValidPublicAddress,
RawTransaction,
RawTransactionSerde,
RpcClient,
RpcAsset,
Transaction,
} from '@ironfish/sdk'
import { CliUx, Flags } from '@oclif/core'
Expand Down Expand Up @@ -180,8 +180,10 @@ export class Mint extends IronfishCommand {
assetId = asset.id
}

let assetData
if (assetId) {
const isAssetOwner = await this.isAssetOwner(client, assetId, accountPublicKey)
assetData = (await client.chain.getAsset({ id: assetId })).content
const isAssetOwner = this.isAssetOwner(assetData, accountPublicKey)
if (!isAssetOwner) {
this.error(`The account '${account}' does not own this asset.`)
}
Expand All @@ -195,6 +197,9 @@ export class Mint extends IronfishCommand {
text: 'Enter the amount',
minimum: 0n,
logger: this.logger,
balance: {
asset: assetData,
},
})
}

Expand Down Expand Up @@ -254,6 +259,7 @@ export class Mint extends IronfishCommand {
name,
metadata,
flags.transferOwnershipTo,
assetData,
))
) {
this.error('Transaction aborted.')
Expand Down Expand Up @@ -283,16 +289,15 @@ export class Mint extends IronfishCommand {
this.warn(`Transaction '${transaction.hash().toString('hex')}' failed to broadcast`)
}

const renderedValue = CurrencyUtils.render(minted.value, true, {
id: minted.asset.id().toString('hex'),
...assetData,
})
const renderedFee = CurrencyUtils.render(transaction.fee(), true)
this.log(`Minted asset ${BufferUtils.toHuman(minted.asset.name())} from ${account}`)
this.log(`Asset Identifier: ${minted.asset.id().toString('hex')}`)
this.log(
`Value: ${CurrencyUtils.renderIron(
minted.value,
true,
minted.asset.id().toString('hex'),
)}`,
)
this.log(`Fee: ${CurrencyUtils.renderIron(transaction.fee(), true)}`)
this.log(`Value: ${renderedValue}`)
this.log(`Fee: ${renderedFee}`)
this.log(`Hash: ${transaction.hash().toString('hex')}`)

const networkId = (await client.chain.getNetworkInfo()).content.networkId
Expand Down Expand Up @@ -324,14 +329,22 @@ export class Mint extends IronfishCommand {
name?: string,
metadata?: string,
transferOwnershipTo?: string,
assetData?: RpcAsset,
): Promise<boolean> {
const nameString = name ? `\nName: ${name}` : ''
const metadataString = metadata ? `\nMetadata: ${metadata}` : ''

const renderedAmount = CurrencyUtils.render(amount, !!assetId, {
id: assetId,
...assetData,
})
const renderedFee = CurrencyUtils.render(fee, true)

this.log(
`You are about to mint an asset with the account ${account}:${nameString}${metadataString}`,
)
this.log(`Amount: ${CurrencyUtils.renderIron(amount, !!assetId, assetId)}`)
this.log(`Fee: ${CurrencyUtils.renderIron(fee, true)}`)
this.log(`Amount: ${renderedAmount}`)
this.log(`Fee: ${renderedFee}`)

if (transferOwnershipTo) {
this.log(
Expand All @@ -342,14 +355,9 @@ export class Mint extends IronfishCommand {
return CliUx.ux.confirm('Do you confirm (Y/N)?')
}

async isAssetOwner(
client: RpcClient,
assetId: string,
ownerPublicKey: string,
): Promise<boolean> {
isAssetOwner(asset: RpcAsset, ownerPublicKey: string): boolean {
try {
const assetResponse = await client.chain.getAsset({ id: assetId })
if (assetResponse.content.owner === ownerPublicKey) {
if (asset.owner === ownerPublicKey) {
return true
}
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class MultisigSign extends IronfishCommand {

this.log(`Transaction: ${response.content.transaction}`)
this.log(`Hash: ${transaction.hash().toString('hex')}`)
this.log(`Fee: ${CurrencyUtils.renderIron(transaction.fee(), true)}`)
this.log(`Fee: ${CurrencyUtils.render(transaction.fee(), true)}`)

if (flags.watch) {
this.log('')
Expand Down
Loading

0 comments on commit e1f4dd5

Please sign in to comment.