Skip to content

Commit

Permalink
Unsigned transaction napi (#4563)
Browse files Browse the repository at this point in the history
* unsigned transaction napi

* adds unsigned transaction napi binding and test to verify ser/de works on JS side
  • Loading branch information
jowparks authored Jan 23, 2024
1 parent 3969373 commit aa762f8
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 1 deletion.
5 changes: 5 additions & 0 deletions ironfish-rust-nodejs/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ export class Transaction {
build(proofGenerationKeyStr: string, viewKeyStr: string, outgoingViewKeyStr: string, publicAddressStr: string, intendedTransactionFee: bigint, changeGoesTo?: string | undefined | null): Buffer
setExpiration(sequence: number): void
}
export type NativeUnsignedTransaction = UnsignedTransaction
export class UnsignedTransaction {
constructor(jsBytes: Buffer)
serialize(): Buffer
}
export class FoundBlockResult {
randomness: string
miningRequestId: number
Expand Down
3 changes: 2 additions & 1 deletion ironfish-rust-nodejs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}

const { FishHashContext, roundOne, contribute, verifyTransform, KEY_LENGTH, NONCE_LENGTH, BoxKeyPair, randomBytes, boxMessage, unboxMessage, RollingFilter, initSignalHandler, triggerSegfault, ASSET_ID_LENGTH, ASSET_METADATA_LENGTH, ASSET_NAME_LENGTH, ASSET_LENGTH, Asset, NOTE_ENCRYPTION_KEY_LENGTH, MAC_LENGTH, ENCRYPTED_NOTE_PLAINTEXT_LENGTH, ENCRYPTED_NOTE_LENGTH, NoteEncrypted, PUBLIC_ADDRESS_LENGTH, RANDOMNESS_LENGTH, MEMO_LENGTH, AMOUNT_VALUE_LENGTH, DECRYPTED_NOTE_LENGTH, Note, PROOF_LENGTH, TRANSACTION_SIGNATURE_LENGTH, TRANSACTION_PUBLIC_KEY_RANDOMNESS_LENGTH, TRANSACTION_EXPIRATION_LENGTH, TRANSACTION_FEE_LENGTH, LATEST_TRANSACTION_VERSION, TransactionPosted, Transaction, verifyTransactions, LanguageCode, generateKey, spendingKeyToWords, wordsToSpendingKey, generateKeyFromPrivateKey, initializeSapling, FoundBlockResult, ThreadPoolHandler, isValidPublicAddress } = nativeBinding
const { FishHashContext, roundOne, contribute, verifyTransform, KEY_LENGTH, NONCE_LENGTH, BoxKeyPair, randomBytes, boxMessage, unboxMessage, RollingFilter, initSignalHandler, triggerSegfault, ASSET_ID_LENGTH, ASSET_METADATA_LENGTH, ASSET_NAME_LENGTH, ASSET_LENGTH, Asset, NOTE_ENCRYPTION_KEY_LENGTH, MAC_LENGTH, ENCRYPTED_NOTE_PLAINTEXT_LENGTH, ENCRYPTED_NOTE_LENGTH, NoteEncrypted, PUBLIC_ADDRESS_LENGTH, RANDOMNESS_LENGTH, MEMO_LENGTH, AMOUNT_VALUE_LENGTH, DECRYPTED_NOTE_LENGTH, Note, PROOF_LENGTH, TRANSACTION_SIGNATURE_LENGTH, TRANSACTION_PUBLIC_KEY_RANDOMNESS_LENGTH, TRANSACTION_EXPIRATION_LENGTH, TRANSACTION_FEE_LENGTH, LATEST_TRANSACTION_VERSION, TransactionPosted, Transaction, verifyTransactions, UnsignedTransaction, LanguageCode, generateKey, spendingKeyToWords, wordsToSpendingKey, generateKeyFromPrivateKey, initializeSapling, FoundBlockResult, ThreadPoolHandler, isValidPublicAddress } = nativeBinding

module.exports.FishHashContext = FishHashContext
module.exports.roundOne = roundOne
Expand Down Expand Up @@ -292,6 +292,7 @@ module.exports.LATEST_TRANSACTION_VERSION = LATEST_TRANSACTION_VERSION
module.exports.TransactionPosted = TransactionPosted
module.exports.Transaction = Transaction
module.exports.verifyTransactions = verifyTransactions
module.exports.UnsignedTransaction = UnsignedTransaction
module.exports.LanguageCode = LanguageCode
module.exports.generateKey = generateKey
module.exports.spendingKeyToWords = spendingKeyToWords
Expand Down
26 changes: 26 additions & 0 deletions ironfish-rust-nodejs/src/structs/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::cell::RefCell;
use std::convert::TryInto;

use ironfish::assets::asset_identifier::AssetIdentifier;
use ironfish::transaction::unsigned::UnsignedTransaction;
use ironfish::transaction::{
batch_verify_transactions, TransactionVersion, TRANSACTION_EXPIRATION_SIZE,
TRANSACTION_FEE_SIZE, TRANSACTION_PUBLIC_KEY_SIZE, TRANSACTION_SIGNATURE_SIZE,
Expand Down Expand Up @@ -371,3 +372,28 @@ pub fn verify_transactions(serialized_transactions: Vec<JsBuffer>) -> Result<boo

Ok(batch_verify_transactions(transactions.iter()).is_ok())
}

#[napi(js_name = "UnsignedTransaction")]
pub struct NativeUnsignedTransaction {
transaction: UnsignedTransaction,
}

#[napi]
impl NativeUnsignedTransaction {
#[napi(constructor)]
pub fn new(js_bytes: JsBuffer) -> Result<NativeUnsignedTransaction> {
let bytes = js_bytes.into_value()?;

let transaction = UnsignedTransaction::read(bytes.as_ref()).map_err(to_napi_err)?;

Ok(NativeUnsignedTransaction { transaction })
}

#[napi]
pub fn serialize(&self) -> Result<Buffer> {
let mut vec: Vec<u8> = vec![];
self.transaction.write(&mut vec).map_err(to_napi_err)?;

Ok(Buffer::from(vec))
}
}
28 changes: 28 additions & 0 deletions ironfish-rust-nodejs/tests/unsigned.test.slow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* 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 { UnsignedTransaction } from ".."
import { Asset, Transaction, generateKey } from ".."

describe('UnsignedTransaction', () => {
describe('ser/de', () => {
it('can create an unsigned tx and deserialize it', () => {
const key = generateKey()
const asset = new Asset(key.publicAddress, 'testcoin', '')
const proposedTx = new Transaction(2)
proposedTx.mint(asset, 5n)
const unsignedTxBuffer = proposedTx.build(
key.proofGenerationKey,
key.viewKey,
key.outgoingViewKey,
key.publicAddress,
0n,
)

const unsignedTx = new UnsignedTransaction(unsignedTxBuffer)
expect(unsignedTx.serialize()).toEqual(unsignedTxBuffer)

})
})
})

0 comments on commit aa762f8

Please sign in to comment.