diff --git a/src/consts.ts b/src/consts.ts index 713291e..4e9f853 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -15,3 +15,4 @@ export const KEY_LENGTH = 32 export const REDJUBJUB_SIGNATURE_LEN = 64 export const ED25519_SIGNATURE_LEN = 64 export const IDENTITY_LEN = VERSION + KEY_LENGTH + KEY_LENGTH + ED25519_SIGNATURE_LEN +export const TX_HASH_LEN = 32 diff --git a/src/deserialize.ts b/src/deserialize.ts index 457f4a9..936fb7b 100644 --- a/src/deserialize.ts +++ b/src/deserialize.ts @@ -1,3 +1,5 @@ +import { TX_HASH_LEN } from './consts' + export const deserializeDkgRound1 = (data?: Buffer) => { if (!data) throw new Error('unexpected empty data') @@ -35,3 +37,14 @@ export const deserializeDkgRound2 = (data?: Buffer) => { publicPackage, } } + +export const deserializeReviewTx = (data?: Buffer) => { + if (!data) throw new Error('unexpected empty data') + + // We expect a hash of 32 bytes + const hash = data.subarray(0, TX_HASH_LEN) + + return { + hash, + } +} diff --git a/src/index.ts b/src/index.ts index 2682610..ab2a5ae 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,7 +18,7 @@ import GenericApp, { ConstructorParams, LedgerError, Transport, processErrorResp import { ResponsePayload } from '@zondax/ledger-js/dist/payload' import { P2_VALUES } from './consts' -import { deserializeDkgRound1, deserializeDkgRound2 } from './deserialize' +import { deserializeDkgRound1, deserializeDkgRound2, deserializeReviewTx } from './deserialize' import { processGetIdentityResponse, processGetKeysResponse } from './helper' import { serializeDkgGetCommitments, serializeDkgRound1, serializeDkgRound2, serializeDkgRound3Min, serializeDkgSign } from './serialize' import { @@ -32,6 +32,7 @@ import { ResponseDkgRound2, ResponseDkgSign, ResponseIdentity, + ResponseReviewTransaction, ResponseSign, } from './types' @@ -63,6 +64,7 @@ export default class IronfishApp extends GenericApp { DKG_BACKUP_KEYS: 0x19, DKG_RESTORE_KEYS: 0x1a, GET_RESULT: 0x1b, + REVIEW_TX: 0x1c, }, p1Values: { ONLY_RETRIEVE: 0x00, @@ -248,6 +250,23 @@ export default class IronfishApp extends GenericApp { } } + async reviewTransaction(tx: string): Promise { + try { + const blob = Buffer.from(tx, 'hex') + const chunks = this.prepareChunks(DUMMY_PATH, blob) + + let rawResponse: any + for (let i = 0; i < chunks.length; i += 1) { + rawResponse = await this.sendGenericChunk(this.INS.REVIEW_TX, P2_VALUES.DEFAULT, 1 + i, chunks.length, chunks[i]) + } + + let result = await this.getResult(rawResponse) + return deserializeReviewTx(result) + } catch (e) { + throw processErrorResponse(e) + } + } + async getResult(rawResponse: ResponsePayload): Promise { let data = Buffer.alloc(0) diff --git a/src/types.ts b/src/types.ts index db0ec2f..fa48120 100644 --- a/src/types.ts +++ b/src/types.ts @@ -15,6 +15,7 @@ export interface IronfishIns extends INSGeneric { DKG_BACKUP_KEYS: 0x19 DKG_RESTORE_KEYS: 0x1a GET_RESULT: 0x1b + REVIEW_TX: 0x1c } export type KeyResponse = ResponseAddress | ResponseViewKey | ResponseProofGenKey @@ -70,3 +71,6 @@ export interface ResponseDkgGetPublicPackage { export interface ResponseDkgBackupKeys { encryptedKeys: Buffer } +export interface ResponseReviewTransaction { + hash: Buffer +}