diff --git a/src/interactions/signTx.ts b/src/interactions/signTx.ts index ea16700a..3ae49044 100644 --- a/src/interactions/signTx.ts +++ b/src/interactions/signTx.ts @@ -10,8 +10,8 @@ import type { } from "../Ada"; import { Errors, } from "../Ada" import cardano, { SignTxIncluded } from "../cardano"; -import type { ParsedCertificate, ParsedOutput, ParsedWithdrawal } from "../parsing"; -import { CertificateType, parseCertificates, parseTxOutput, parseWithdrawal, validateTransaction } from "../parsing"; +import type { ParsedCertificate, ParsedInput, ParsedOutput, ParsedWithdrawal } from "../parsing"; +import { CertificateType, parseCertificates, parseTxInput, parseTxOutput, parseWithdrawal, validateTransaction } from "../parsing"; import utils, { Assert, invariant, Precondition, unreachable } from "../utils"; import { INS } from "./common/ins"; import { wrapRetryStillInCall } from "./common/retry"; @@ -131,7 +131,7 @@ const signTx_init = async ( const signTx_addInput = async ( _send: SendFn, - input: InputTypeUTxO + input: ParsedInput ): Promise => { const enum P2 { UNUSED = 0x00, @@ -593,7 +593,7 @@ export async function signTransaction( ); // inputs - for (const input of inputs) { + for (const input of inputs.map(i => parseTxInput(i))) { await signTx_addInput(_send, input); } diff --git a/src/parsing.ts b/src/parsing.ts index d9188f54..4928fe43 100644 --- a/src/parsing.ts +++ b/src/parsing.ts @@ -178,18 +178,11 @@ export function validateTransaction( // inputs Precondition.checkIsArray(inputs, TxErrors.INPUTS_NOT_ARRAY); - for (const input of inputs) { - Precondition.checkIsHexStringOfLength( - input.txHashHex, - TX_HASH_LENGTH, - TxErrors.INPUT_INVALID_TX_HASH - ); - - if (isSigningPoolRegistrationAsOwner) { - // input should not be given with a path - // the path is not used, but we check just to avoid potential confusion of developers using this - Precondition.check(!input.path, TxErrors.INPUT_WITH_PATH); - } + const _inputs = inputs.map(inp => parseTxInput(inp)) + if (isSigningPoolRegistrationAsOwner) { + // input should not be given with a path + // the path is not used, but we check just to avoid potential confusion of developers using this + Precondition.check(_inputs.every(inp => inp == null), TxErrors.INPUT_WITH_PATH_WHEN_SIGNING_AS_POOL_OWNER); } // outputs @@ -252,6 +245,22 @@ export function validateTransaction( } } +export type ParsedInput = { + txHashHex: FixlenHexString + outputIndex: Uint32_t + path: BIP32Path | null +} + +export function parseTxInput(input: InputTypeUTxO): ParsedInput { + const txHashHex = parseHexStringOfLength(input.txHashHex, TX_HASH_LENGTH, TxErrors.INPUT_INVALID_TX_HASH) + const outputIndex = parseUint32_t(input.outputIndex, TxErrors.INPUT_INVALID_UTXO_INDEX) + return { + txHashHex, + outputIndex, + path: input.path != null ? parseBIP32Path(input.path, TxErrors.INPUT_INVALID_PATH) : null + } +} + export type ParsedWithdrawal = { amountStr: Uint64_str path: ValidBIP32Path diff --git a/src/txErrors.ts b/src/txErrors.ts index 92711e4f..12e52ce1 100644 --- a/src/txErrors.ts +++ b/src/txErrors.ts @@ -4,9 +4,11 @@ export enum TxErrors { INVALID_NETWORK_ID = "invalid network id", INPUTS_NOT_ARRAY = "inputs not an array", - INPUT_WITH_PATH = - "stake pool registration= inputs should not contain the witness path", + INPUT_WITH_PATH_WHEN_SIGNING_AS_POOL_OWNER = + "inputs should not contain the witness path if signing stake pool certificate as owner", INPUT_INVALID_TX_HASH = "invalid tx hash in an input", + INPUT_INVALID_PATH = "invalid input path", + INPUT_INVALID_UTXO_INDEX = "invalid input utxo index", OUTPUTS_NOT_ARRAY = "outputs not an array", OUTPUT_INVALID_AMOUNT = "invalid amount in an output",