Skip to content

Commit

Permalink
Merge pull request #3309 from iron-fish/staging
Browse files Browse the repository at this point in the history
STAGING -> MASTER
  • Loading branch information
danield9tqh authored Feb 6, 2023
2 parents aaba8cb + 94c1bed commit f3fdfa1
Show file tree
Hide file tree
Showing 14 changed files with 641 additions and 146 deletions.
4 changes: 2 additions & 2 deletions ironfish-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ironfish",
"version": "0.1.64",
"version": "0.1.65",
"description": "CLI for running and interacting with an Iron Fish node",
"author": "Iron Fish <[email protected]> (https://ironfish.network)",
"main": "build/src/index.js",
Expand Down Expand Up @@ -60,7 +60,7 @@
"@aws-sdk/client-cognito-identity": "3.215.0",
"@aws-sdk/client-s3": "3.127.0",
"@ironfish/rust-nodejs": "0.1.25",
"@ironfish/sdk": "0.0.41",
"@ironfish/sdk": "0.0.42",
"@oclif/core": "1.23.1",
"@oclif/plugin-help": "5.1.12",
"@oclif/plugin-not-found": "2.3.1",
Expand Down
146 changes: 120 additions & 26 deletions ironfish-cli/src/commands/wallet/burn.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
/* 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 } from '@ironfish/sdk'
import {
CreateTransactionRequest,
CreateTransactionResponse,
CurrencyUtils,
RawTransactionSerde,
RpcResponseEnded,
Transaction,
} from '@ironfish/sdk'
import { CliUx, Flags } from '@oclif/core'
import inquirer from 'inquirer'
import { IronfishCommand } from '../../command'
import { IronFlag, parseIron, RemoteFlags } from '../../flags'
import { ProgressBar } from '../../types'
Expand Down Expand Up @@ -48,6 +56,16 @@ export class Burn extends IronfishCommand {
'Minimum number of block confirmations needed to include a note. Set to 0 to include all blocks.',
required: false,
}),
rawTransaction: Flags.boolean({
default: false,
description:
'Return raw transaction. Use it to create a transaction but not post to the network',
}),
expiration: Flags.integer({
char: 'e',
description:
'The block sequence that the transaction can not be mined after. Set to 0 for no expiration.',
}),
}

async start(): Promise<void> {
Expand Down Expand Up @@ -108,41 +126,114 @@ export class Burn extends IronfishCommand {
}

let fee
let rawTransactionResponse: string
if (flags.fee) {
fee = flags.fee
fee = CurrencyUtils.encode(flags.fee)
const createResponse = await client.createTransaction({
sender: account,
receives: [],
burns: [
{
assetId,
value: CurrencyUtils.encode(amount),
},
],
fee: fee,
expiration: flags.expiration,
confirmations: confirmations,
})
rawTransactionResponse = createResponse.content.transaction
} else {
const input = await CliUx.ux.prompt(
`Enter the fee amount in $IRON (min: ${CurrencyUtils.renderIron(1n)})`,
const feeRatesResponse = await client.estimateFeeRates()
const feeRates = new Set([
feeRatesResponse.content.low ?? '1',
feeRatesResponse.content.medium ?? '1',
feeRatesResponse.content.high ?? '1',
])

const feeRateNames = Object.getOwnPropertyNames(feeRatesResponse.content)

const feeRateOptions: { value: number; name: string }[] = []

const createTransactionRequest: CreateTransactionRequest = {
sender: account,
receives: [],
burns: [
{
assetId,
value: CurrencyUtils.encode(amount),
},
],
expiration: flags.expiration,
confirmations: confirmations,
}

const allPromises: Promise<RpcResponseEnded<CreateTransactionResponse>>[] = []
feeRates.forEach((feeRate) => {
allPromises.push(
client.createTransaction({
...createTransactionRequest,
feeRate: feeRate,
}),
)
})

const createResponses = await Promise.all(allPromises)
createResponses.forEach((createResponse, index) => {
const rawTransactionBytes = Buffer.from(createResponse.content.transaction, 'hex')
const rawTransaction = RawTransactionSerde.deserialize(rawTransactionBytes)

feeRateOptions.push({
value: index,
name: `${feeRateNames[index]}: ${CurrencyUtils.renderIron(rawTransaction.fee)} IRON`,
})
})

const input: { selection: number } = await inquirer.prompt<{ selection: number }>([
{
default: CurrencyUtils.renderIron(1n),
required: true,
name: 'selection',
message: `Select the fee you wish to use for this transaction`,
type: 'list',
choices: feeRateOptions,
},
)
])

fee = await parseIron(input, { largerThan: 0n, flagName: 'fee' }).catch((error: Error) =>
this.error(error.message),
)
rawTransactionResponse = createResponses[input.selection].content.transaction
}

const rawTransactionBytes = Buffer.from(rawTransactionResponse, 'hex')
const rawTransaction = RawTransactionSerde.deserialize(rawTransactionBytes)

if (!flags.confirm) {
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}
* This action is NOT reversible *
)} plus a transaction fee of ${CurrencyUtils.renderIron(
rawTransaction.fee,
true,
)} with the account ${account}
`)

if (!flags.rawTransaction) {
this.log(`* This action is NOT reversible *\n`)
}

const confirm = await CliUx.ux.confirm('Do you confirm (Y/N)?')
if (!confirm) {
this.log('Transaction aborted.')
this.exit(0)
}
}

if (flags.rawTransaction) {
this.log(`Raw transaction: ${rawTransactionResponse}`)
this.log(`\nRun "ironfish wallet:post" to post the raw transaction. `)
this.exit(0)
}

const bar = CliUx.ux.progress({
barCompleteChar: '\u2588',
barIncompleteChar: '\u2591',
Expand All @@ -166,27 +257,30 @@ ${CurrencyUtils.renderIron(
bar.stop()
}

let transaction

try {
const result = await client.burnAsset({
account,
assetId,
fee: CurrencyUtils.encode(fee),
value: CurrencyUtils.encode(amount),
confirmations,
const result = await client.postTransaction({
transaction: rawTransactionResponse,
sender: account,
})

stopProgressBar()

const response = result.content
const transactionBytes = Buffer.from(result.content.transaction, 'hex')
transaction = new Transaction(transactionBytes)

this.log(`
Burned asset ${response.assetId} from ${account}
Value: ${CurrencyUtils.renderIron(response.value)}
Burned asset ${assetId} from ${account}
Value: ${CurrencyUtils.renderIron(amount)}
Transaction Hash: ${response.hash}
Transaction Hash: ${transaction.hash().toString('hex')}
Find the transaction on https://explorer.ironfish.network/transaction/${
response.hash
} (it can take a few minutes before the transaction appears in the Explorer)`)
Find the transaction on https://explorer.ironfish.network/transaction/${transaction
.hash()
.toString(
'hex',
)}(it can take a few minutes before the transaction appears in the Explorer)`)
} catch (error: unknown) {
stopProgressBar()
this.log(`An error occurred while burning the asset.`)
Expand Down
18 changes: 15 additions & 3 deletions ironfish-cli/src/commands/wallet/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import jsonColorizer from 'json-colorizer'
import path from 'path'
import { IronfishCommand } from '../../command'
import { ColorFlag, ColorFlagKey, RemoteFlags } from '../../flags'
import { LANGUAGE_KEYS, LANGUAGES, selectLanguage } from '../../utils/language'
import {
inferLanguageCode,
LANGUAGE_KEYS,
languageCodeToKey,
LANGUAGES,
selectLanguage,
} from '../../utils/language'

export class ExportCommand extends IronfishCommand {
static description = `Export an account`
Expand Down Expand Up @@ -69,8 +75,14 @@ export class ExportCommand extends IronfishCommand {
LANGUAGES[flags.language],
)
} else if (flags.mnemonic) {
const language = await selectLanguage()
output = spendingKeyToWords(response.content.account.spendingKey, language)
let languageCode = inferLanguageCode()
if (languageCode !== null) {
CliUx.ux.info(`Detected Language as '${languageCodeToKey(languageCode)}', exporting:`)
} else {
CliUx.ux.info(`Could not detect your language, please select language for export`)
languageCode = await selectLanguage()
}
output = spendingKeyToWords(response.content.account.spendingKey, languageCode)
} else if (flags.json) {
output = exportPath
? JSON.stringify(response.content.account, undefined, ' ')
Expand Down
Loading

0 comments on commit f3fdfa1

Please sign in to comment.