Skip to content

Commit

Permalink
feat(cli,ironfish,rust-nodejs): Render unsigned transaction details f…
Browse files Browse the repository at this point in the history
…or signature share creation (#4762)

* feat(cli,ironfish,rust-nodejs): Render unsigned transaction for
signature shares

* refactor(cli): Update logging
  • Loading branch information
rohanjadvani authored Feb 21, 2024
1 parent 1a7007a commit 30ec913
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 1 deletion.
114 changes: 113 additions & 1 deletion ironfish-cli/src/commands/wallet/multisig/create-signature-share.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* 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, RpcClient, UnsignedTransaction } from '@ironfish/sdk'
import { CliUx, Flags } from '@oclif/core'
import { IronfishCommand } from '../../../command'
import { RemoteFlags } from '../../../flags'
Expand Down Expand Up @@ -37,14 +38,18 @@ export class CreateSignatureShareCommand extends IronfishCommand {
signingPackage = await longPrompt('Enter the signing package: ')
}

const client = await this.sdk.connectRpc()
const unsignedTransaction = UnsignedTransaction.fromSigningPackage(signingPackage)

await this.renderUnsignedTransactionDetails(client, unsignedTransaction, flags.account)

if (!flags.confirm) {
const confirmed = await CliUx.ux.confirm('Confirm new signature share creation (Y/N)')
if (!confirmed) {
this.error('Creating signature share aborted')
}
}

const client = await this.sdk.connectRpc()
const signatureShareResponse = await client.wallet.multisig.createSignatureShare({
account: flags.account,
signingPackage,
Expand All @@ -53,4 +58,111 @@ export class CreateSignatureShareCommand extends IronfishCommand {
this.log('Signing Share:\n')
this.log(signatureShareResponse.content.signatureShare)
}

private async renderUnsignedTransactionDetails(
client: RpcClient,
unsignedTransaction: UnsignedTransaction,
account?: string,
): Promise<void> {
if (unsignedTransaction.mints.length > 0) {
this.log()
this.log('==================')
this.log('Transaction Mints:')
this.log('==================')

for (const [i, mint] of unsignedTransaction.mints.entries()) {
if (i !== 0) {
this.log('------------------')
}
this.log()

this.log(`Asset ID: ${mint.asset.id().toString('hex')}`)
this.log(`Name: ${mint.asset.name().toString('utf8')}`)
this.log(`Amount: ${CurrencyUtils.renderIron(mint.value, false)}`)

if (mint.transferOwnershipTo) {
this.log(
`Ownership of this asset will be transferred to ${mint.transferOwnershipTo.toString(
'hex',
)}. The current account will no longer have any permission to mint or modify this asset. This cannot be undone.`,
)
}
this.log()
}
}

if (unsignedTransaction.burns.length > 0) {
this.log()
this.log('==================')
this.log('Transaction Burns:')
this.log('==================')

for (const [i, burn] of unsignedTransaction.burns.entries()) {
if (i !== 0) {
this.log('------------------')
}
this.log()

this.log(`Asset ID: ${burn.assetId.toString('hex')}`)
this.log(`Amount: ${CurrencyUtils.renderIron(burn.value, false)}`)
this.log()
}
}

if (unsignedTransaction.notes.length > 0) {
const response = await client.wallet.getUnsignedTransactionNotes({
account,
unsignedTransaction: unsignedTransaction.serialize().toString('hex'),
})

if (response.content.sentNotes.length > 0) {
this.log()
this.log('==================')
this.log('Notes sent:')
this.log('==================')

let logged = false
for (const note of response.content.sentNotes) {
// Skip this since we'll re-render for received notes
if (note.owner === note.sender) {
continue
}

if (logged) {
this.log('------------------')
}
logged = true
this.log()

this.log(`Amount: ${CurrencyUtils.renderIron(note.value, true, note.assetId)}`)
this.log(`Memo: ${note.memo}`)
this.log(`Recipient: ${note.owner}`)
this.log(`Sender: ${note.sender}`)
this.log()
}
}

if (response.content.sentNotes.length > 0) {
this.log()
this.log('==================')
this.log('Notes received:')
this.log('==================')

for (const [i, note] of response.content.receivedNotes.entries()) {
if (i !== 0) {
this.log('------------------')
}
this.log()

this.log(`Amount: ${CurrencyUtils.renderIron(note.value, true, note.assetId)}`)
this.log(`Memo: ${note.memo}`)
this.log(`Recipient: ${note.owner}`)
this.log(`Sender: ${note.sender}`)
this.log()
}
}
}

this.log()
}
}
1 change: 1 addition & 0 deletions ironfish-rust-nodejs/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ export class Transaction {
export type NativeUnsignedTransaction = UnsignedTransaction
export class UnsignedTransaction {
constructor(jsBytes: Buffer)
static fromSigningPackage(signingPackageStr: string): NativeUnsignedTransaction
serialize(): Buffer
publicKeyRandomness(): string
hash(): Buffer
Expand Down
10 changes: 10 additions & 0 deletions ironfish-rust-nodejs/src/structs/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,16 @@ impl NativeUnsignedTransaction {
Ok(NativeUnsignedTransaction { transaction })
}

#[napi(factory)]
pub fn from_signing_package(signing_package_str: String) -> Result<Self> {
let bytes = hex_to_vec_bytes(&signing_package_str).map_err(to_napi_err)?;
let signing_package = SigningPackage::read(&bytes[..]).map_err(to_napi_err)?;

Ok(NativeUnsignedTransaction {
transaction: signing_package.unsigned_transaction,
})
}

#[napi]
pub fn serialize(&self) -> Result<Buffer> {
let mut vec: Vec<u8> = vec![];
Expand Down
5 changes: 5 additions & 0 deletions ironfish/src/primitives/unsignedTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ export class UnsignedTransaction {
reader.seek(TRANSACTION_SIGNATURE_LENGTH)
}

static fromSigningPackage(signingPackage: string): UnsignedTransaction {
const unsigned = new NativeUnsignedTransaction(Buffer.from(signingPackage, 'hex'))
return new UnsignedTransaction(unsigned.serialize())
}

serialize(): Buffer {
return this.unsignedTransactionSerialized
}
Expand Down

0 comments on commit 30ec913

Please sign in to comment.