Skip to content

Commit

Permalink
fix equality operators and version printing
Browse files Browse the repository at this point in the history
  • Loading branch information
janmazak committed Oct 27, 2021
1 parent a959b38 commit 6049e75
Show file tree
Hide file tree
Showing 13 changed files with 51 additions and 42 deletions.
3 changes: 2 additions & 1 deletion src/interactions/deriveNativeScriptHash.ts
Expand Up @@ -3,6 +3,7 @@ import type { ParsedComplexNativeScript, ParsedNativeScript, ParsedSimpleNativeS
import { NATIVE_SCRIPT_HASH_LENGTH } from "../types/internal"
import type { NativeScriptHash, NativeScriptHashDisplayFormat, Version } from "../types/public"
import { NativeScriptType } from "../types/public"
import { getVersionString } from "../utils"
import { INS } from "./common/ins"
import type { Interaction, SendParams } from "./common/types"
import { ensureLedgerAppVersionCompatible, getCompatibility } from "./getVersion"
Expand Down Expand Up @@ -92,7 +93,7 @@ function ensureScriptHashDerivationSupportedByAppVersion(
version: Version
): void {
if (!getCompatibility(version).supportsNativeScriptHashDerivation) {
throw new DeviceVersionUnsupported(`Native script hash derivation not supported by Ledger app version ${version}.`)
throw new DeviceVersionUnsupported(`Native script hash derivation not supported by Ledger app version ${getVersionString(version)}.`)
}
}

Expand Down
11 changes: 6 additions & 5 deletions src/interactions/serialization/addressParams.ts
Expand Up @@ -3,6 +3,7 @@ import { InvalidDataReason } from "../../errors/invalidDataReason"
import type { ParsedAddressParams, SpendingDataSource, StakingDataSource, Uint8_t, Version } from "../../types/internal"
import { SpendingDataSourceType } from "../../types/internal"
import { AddressType, StakingDataSourceType } from "../../types/internal"
import { getVersionString } from "../../utils"
import { assert } from "../../utils/assert"
import { hex_to_buf, path_to_buf, uint8_to_buf, uint32_to_buf } from "../../utils/serialize"
import { getCompatibility } from "../getVersion"
Expand Down Expand Up @@ -69,17 +70,17 @@ export function serializeAddressParams(
let spending: SpendingDataSource = params.spendingDataSource
let staking: StakingDataSource = params.stakingDataSource
if (!getCompatibility(version).supportsMultisigTransaction) {
if (params.type == AddressType.REWARD_KEY) {
assert(staking.type == StakingDataSourceType.KEY_PATH, InvalidDataReason.ADDRESS_INVALID_STAKING_INFO)
if (params.type === AddressType.REWARD_KEY) {
assert(staking.type === StakingDataSourceType.KEY_PATH, InvalidDataReason.ADDRESS_INVALID_STAKING_INFO)
spending = {
type: SpendingDataSourceType.PATH,
path: staking.path,
}
staking = {
type: StakingDataSourceType.NONE,
}
} else if (params.type == AddressType.REWARD_SCRIPT) {
throw new DeviceVersionUnsupported(`Scripthash based address derivation not supported by Ledger app version ${version}.`)
} else if (params.type === AddressType.REWARD_SCRIPT) {
throw new DeviceVersionUnsupported(`Scripthash based address derivation not supported by Ledger app version ${getVersionString(version)}.`)
}
}
return Buffer.concat([
Expand All @@ -90,4 +91,4 @@ export function serializeAddressParams(
serializeSpendingDataSource(spending),
serializeStakingDataSource(staking),
])
}
}
4 changes: 2 additions & 2 deletions src/interactions/serialization/txCertificate.ts
Expand Up @@ -12,14 +12,14 @@ export function serializeTxCertificatePreMultisig(
switch (certificate.type) {
case CertificateType.STAKE_REGISTRATION:
case CertificateType.STAKE_DEREGISTRATION: {
assert(certificate.stakeCredential.type == StakeCredentialType.KEY_PATH, InvalidDataReason.CERTIFICATE_INVALID_STAKE_CREDENTIAL)
assert(certificate.stakeCredential.type === StakeCredentialType.KEY_PATH, InvalidDataReason.CERTIFICATE_INVALID_STAKE_CREDENTIAL)
return Buffer.concat([
uint8_to_buf(certificate.type as Uint8_t),
path_to_buf(certificate.stakeCredential.path),
])
}
case CertificateType.STAKE_DELEGATION: {
assert(certificate.stakeCredential.type == StakeCredentialType.KEY_PATH, InvalidDataReason.CERTIFICATE_INVALID_STAKE_CREDENTIAL)
assert(certificate.stakeCredential.type === StakeCredentialType.KEY_PATH, InvalidDataReason.CERTIFICATE_INVALID_STAKE_CREDENTIAL)
return Buffer.concat([
uint8_to_buf(certificate.type as Uint8_t),
path_to_buf(certificate.stakeCredential.path),
Expand Down
2 changes: 1 addition & 1 deletion src/interactions/serialization/txOther.ts
Expand Up @@ -26,7 +26,7 @@ export function serializeTxWithdrawal(
])
} else {
// pre-multisig
assert(withdrawal.stakeCredential.type == StakeCredentialType.KEY_PATH, InvalidDataReason.WITHDRAWAL_INVALID_STAKE_CREDENTIAL)
assert(withdrawal.stakeCredential.type === StakeCredentialType.KEY_PATH, InvalidDataReason.WITHDRAWAL_INVALID_STAKE_CREDENTIAL)
return Buffer.concat([
uint64_to_buf(withdrawal.amount),
path_to_buf(withdrawal.stakeCredential.path),
Expand Down
3 changes: 2 additions & 1 deletion src/interactions/signOperationalCertificate.ts
Expand Up @@ -2,6 +2,7 @@ import { DeviceVersionUnsupported } from "../errors"
import type { ParsedOperationalCertificate, Version } from "../types/internal"
import { ED25519_SIGNATURE_LENGTH } from "../types/internal"
import type { OperationalCertificateSignature } from '../types/public'
import { getVersionString } from "../utils"
import { INS } from "./common/ins"
import type { Interaction, SendParams } from "./common/types"
import { getCompatibility } from "./getVersion"
Expand All @@ -19,7 +20,7 @@ export function* signOperationalCertificate(
operationalCertificate: ParsedOperationalCertificate,
): Interaction<OperationalCertificateSignature> {
if (!getCompatibility(version).supportsPoolRegistrationAsOperator) {
throw new DeviceVersionUnsupported(`Operational certificate signing not supported by Ledger app version ${version}.`)
throw new DeviceVersionUnsupported(`Operational certificate signing not supported by Ledger app version ${getVersionString(version)}.`)
}

const P1_UNUSED = 0x00
Expand Down
27 changes: 14 additions & 13 deletions src/interactions/signTx.ts
Expand Up @@ -5,6 +5,7 @@ import { CertificateType, ED25519_SIGNATURE_LENGTH, PoolOwnerType, TX_HASH_LENGT
import type { SignedTransactionData, TxAuxiliaryDataSupplement} from "../types/public"
import { AddressType, TxOutputDestinationType } from "../types/public"
import { PoolKeyType, TransactionSigningMode, TxAuxiliaryDataSupplementType, TxAuxiliaryDataType } from "../types/public"
import { getVersionString } from "../utils"
import { assert } from "../utils/assert"
import { buf_to_hex, hex_to_buf, int64_to_buf, uint64_to_buf } from "../utils/serialize"
import { INS } from "./common/ins"
Expand Down Expand Up @@ -537,14 +538,14 @@ function generateWitnessPaths(request: ParsedSigningRequest): ValidBIP32Path[] {
} else if (cert.type === CertificateType.STAKE_POOL_RETIREMENT) {
witnessPaths.push(cert.path)
} else {
if (cert.stakeCredential.type == StakeCredentialType.KEY_PATH) {
if (cert.stakeCredential.type === StakeCredentialType.KEY_PATH) {
witnessPaths.push(cert.stakeCredential.path)
}
}
}

for (const withdrawal of tx.withdrawals) {
if (withdrawal.stakeCredential.type == StakeCredentialType.KEY_PATH) {
if (withdrawal.stakeCredential.type === StakeCredentialType.KEY_PATH) {
witnessPaths.push(withdrawal.stakeCredential.path)
}
}
Expand All @@ -554,30 +555,30 @@ function generateWitnessPaths(request: ParsedSigningRequest): ValidBIP32Path[] {

function ensureRequestSupportedByAppVersion(version: Version, request: ParsedSigningRequest): void {
const auxiliaryData = request?.tx?.auxiliaryData
const hasCatalystRegistration = auxiliaryData?.type == TxAuxiliaryDataType.CATALYST_REGISTRATION
const hasCatalystRegistration = auxiliaryData?.type === TxAuxiliaryDataType.CATALYST_REGISTRATION

if (hasCatalystRegistration && !getCompatibility(version).supportsCatalystRegistration) {
throw new DeviceVersionUnsupported(`Catalyst registration not supported by Ledger app version ${version}.`)
throw new DeviceVersionUnsupported(`Catalyst registration not supported by Ledger app version ${getVersionString(version)}.`)
}

if (request?.tx?.ttl === "0" && !getCompatibility(version).supportsZeroTtl) {
throw new DeviceVersionUnsupported(`Zero TTL not supported by Ledger app version ${version}.`)
throw new DeviceVersionUnsupported(`Zero TTL not supported by Ledger app version ${getVersionString(version)}.`)
}

if (request?.signingMode === TransactionSigningMode.POOL_REGISTRATION_AS_OPERATOR && !getCompatibility(version).supportsPoolRegistrationAsOperator) {
throw new DeviceVersionUnsupported(`Pool registration as operator not supported by Ledger app version ${version}.`)
throw new DeviceVersionUnsupported(`Pool registration as operator not supported by Ledger app version ${getVersionString(version)}.`)
}


const certificates = request?.tx?.certificates
const hasPoolRetirement = certificates && certificates.some(c => c.type === CertificateType.STAKE_POOL_RETIREMENT)

if (hasPoolRetirement && !getCompatibility(version).supportsPoolRetirement) {
throw new DeviceVersionUnsupported(`Pool retirement certificate not supported by Ledger app version ${version}.`)
throw new DeviceVersionUnsupported(`Pool retirement certificate not supported by Ledger app version ${getVersionString(version)}.`)
}

if (request?.tx?.mint && !getCompatibility(version).supportsMint) {
throw new DeviceVersionUnsupported(`Mint not supported by Ledger app version ${version}.`)
throw new DeviceVersionUnsupported(`Mint not supported by Ledger app version ${getVersionString(version)}.`)
}

if (!getCompatibility(version).supportsMultisigTransaction) {
Expand All @@ -591,10 +592,10 @@ function ensureRequestSupportedByAppVersion(version: Version, request: ParsedSig
AddressType.REWARD_SCRIPT,
]
const hasScripthashOutputs = request?.tx?.outputs && request.tx.outputs.some(o =>
o.destination.type == TxOutputDestinationType.DEVICE_OWNED &&
o.destination.type === TxOutputDestinationType.DEVICE_OWNED &&
scriptAddressTypes.includes(o.destination.addressParams.type))
if (hasScripthashOutputs) {
throw new DeviceVersionUnsupported(`Scripthash based address not supported by Ledger app version ${version}.`)
throw new DeviceVersionUnsupported(`Script hash in address parameters in output not supported by Ledger app version ${getVersionString(version)}.`)
}
}
{
Expand All @@ -604,14 +605,14 @@ function ensureRequestSupportedByAppVersion(version: Version, request: ParsedSig
c.type === CertificateType.STAKE_REGISTRATION) &&
c.stakeCredential.type === StakeCredentialType.SCRIPT_HASH)
if (hasScripthashStakeCredentials) {
throw new DeviceVersionUnsupported(`Scripthash based certificate not supported by Ledger app version ${version}.`)
throw new DeviceVersionUnsupported(`Script hash in certificate stake credential not supported by Ledger app version ${getVersionString(version)}.`)
}
}
{
const withdrawals = request?.tx?.withdrawals
const hasScripthashWithdrawals = withdrawals && withdrawals.some(w => w.stakeCredential.type == StakeCredentialType.SCRIPT_HASH)
const hasScripthashWithdrawals = withdrawals && withdrawals.some(w => w.stakeCredential.type === StakeCredentialType.SCRIPT_HASH)
if (hasScripthashWithdrawals) {
throw new DeviceVersionUnsupported(`Scripthash based withdrawal not supported by Ledger app version ${version}.`)
throw new DeviceVersionUnsupported(`Script hash in withdrawal not supported by Ledger app version ${getVersionString(version)}.`)
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions src/parsing/address.ts
Expand Up @@ -95,17 +95,17 @@ function validateSpendingDataSource(
case AddressType.POINTER_KEY:
case AddressType.ENTERPRISE_KEY:
case AddressType.BYRON:
validate(spending.type == SpendingDataSourceType.PATH, InvalidDataReason.ADDRESS_INVALID_SPENDING_INFO)
validate(spending.type === SpendingDataSourceType.PATH, InvalidDataReason.ADDRESS_INVALID_SPENDING_INFO)
break
case AddressType.BASE_PAYMENT_SCRIPT_STAKE_KEY:
case AddressType.BASE_PAYMENT_SCRIPT_STAKE_SCRIPT:
case AddressType.POINTER_SCRIPT:
case AddressType.ENTERPRISE_SCRIPT:
validate(spending.type == SpendingDataSourceType.SCRIPT_HASH, InvalidDataReason.ADDRESS_INVALID_SPENDING_INFO)
validate(spending.type === SpendingDataSourceType.SCRIPT_HASH, InvalidDataReason.ADDRESS_INVALID_SPENDING_INFO)
break
case AddressType.REWARD_KEY:
case AddressType.REWARD_SCRIPT:
validate(spending.type == SpendingDataSourceType.NONE, InvalidDataReason.ADDRESS_INVALID_SPENDING_INFO)
validate(spending.type === SpendingDataSourceType.NONE, InvalidDataReason.ADDRESS_INVALID_SPENDING_INFO)
break
default:
throw new InvalidData(InvalidDataReason.ADDRESS_UNKNOWN_TYPE)
Expand All @@ -120,22 +120,22 @@ function validateStakingDataSource(
case AddressType.BASE_PAYMENT_KEY_STAKE_KEY:
case AddressType.BASE_PAYMENT_SCRIPT_STAKE_KEY:
case AddressType.REWARD_KEY:
validate(staking.type == StakingDataSourceType.KEY_PATH ||
staking.type == StakingDataSourceType.KEY_HASH, InvalidDataReason.ADDRESS_INVALID_STAKING_INFO)
validate(staking.type === StakingDataSourceType.KEY_PATH ||
staking.type === StakingDataSourceType.KEY_HASH, InvalidDataReason.ADDRESS_INVALID_STAKING_INFO)
break
case AddressType.BASE_PAYMENT_SCRIPT_STAKE_SCRIPT:
case AddressType.BASE_PAYMENT_KEY_STAKE_SCRIPT:
case AddressType.REWARD_SCRIPT:
validate(staking.type == StakingDataSourceType.SCRIPT_HASH, InvalidDataReason.ADDRESS_INVALID_STAKING_INFO)
validate(staking.type === StakingDataSourceType.SCRIPT_HASH, InvalidDataReason.ADDRESS_INVALID_STAKING_INFO)
break
case AddressType.POINTER_KEY:
case AddressType.POINTER_SCRIPT:
validate(staking.type == StakingDataSourceType.BLOCKCHAIN_POINTER, InvalidDataReason.ADDRESS_INVALID_STAKING_INFO)
validate(staking.type === StakingDataSourceType.BLOCKCHAIN_POINTER, InvalidDataReason.ADDRESS_INVALID_STAKING_INFO)
break
case AddressType.BYRON:
case AddressType.ENTERPRISE_KEY:
case AddressType.ENTERPRISE_SCRIPT:
validate(staking.type == StakingDataSourceType.NONE, InvalidDataReason.ADDRESS_INVALID_STAKING_INFO)
validate(staking.type === StakingDataSourceType.NONE, InvalidDataReason.ADDRESS_INVALID_STAKING_INFO)
break
default:
throw new InvalidData(InvalidDataReason.ADDRESS_UNKNOWN_TYPE)
Expand Down
10 changes: 5 additions & 5 deletions src/parsing/transaction.ts
Expand Up @@ -69,13 +69,13 @@ function parseAssetGroup<T>(assetGroup: AssetGroup, parseTokenAmountFn: ParseTok
}

const assetNamesHex = parsedAssetGroup.tokens.map(t => t.assetNameHex)
validate(assetNamesHex.length == new Set(assetNamesHex).size, InvalidDataReason.MULTIASSET_INVALID_ASSET_GROUP_NOT_UNIQUE)
validate(assetNamesHex.length === new Set(assetNamesHex).size, InvalidDataReason.MULTIASSET_INVALID_ASSET_GROUP_NOT_UNIQUE)

const sortedAssetNames = [...assetNamesHex].sort( (n1, n2) => {
if (n1.length == n2.length) return n1.localeCompare(n2)
if (n1.length === n2.length) return n1.localeCompare(n2)
else return n1.length - n2.length
})
validate(JSON.stringify(assetNamesHex) == JSON.stringify(sortedAssetNames), InvalidDataReason.MULTIASSET_INVALID_ASSET_GROUP_ORDERING)
validate(JSON.stringify(assetNamesHex) === JSON.stringify(sortedAssetNames), InvalidDataReason.MULTIASSET_INVALID_ASSET_GROUP_ORDERING)

return parsedAssetGroup
}
Expand All @@ -87,10 +87,10 @@ function parseTokenBundle<T>(tokenBundle: AssetGroup[], emptyTokenBundleAllowed:
const parsedTokenBundle = tokenBundle.map(ag => parseAssetGroup(ag, parseTokenAmountFn))

const policyIds = parsedTokenBundle.map(ag => ag.policyIdHex)
validate(policyIds.length == new Set(policyIds).size, InvalidDataReason.MULTIASSET_INVALID_TOKEN_BUNDLE_NOT_UNIQUE)
validate(policyIds.length === new Set(policyIds).size, InvalidDataReason.MULTIASSET_INVALID_TOKEN_BUNDLE_NOT_UNIQUE)

const sortedPolicyIds = [...policyIds].sort()
validate(JSON.stringify(policyIds) == JSON.stringify(sortedPolicyIds), InvalidDataReason.MULTIASSET_INVALID_TOKEN_BUNDLE_ORDERING)
validate(JSON.stringify(policyIds) === JSON.stringify(sortedPolicyIds), InvalidDataReason.MULTIASSET_INVALID_TOKEN_BUNDLE_ORDERING)

return parsedTokenBundle
}
Expand Down
2 changes: 1 addition & 1 deletion src/types/public.ts
Expand Up @@ -1016,7 +1016,7 @@ export type Transaction = {
outputs: Array<TxOutput>,
/**
* Transaction fee (in Lovelace).
* Note that transaction is valid only if inputs + fee == outputs.
* Note that transaction is valid only if inputs + fee === outputs.
*/
fee: bigint_like,
/**
Expand Down
5 changes: 5 additions & 0 deletions src/utils.ts
Expand Up @@ -3,6 +3,7 @@ import bech32 from "bech32"

import { InvalidDataReason } from "./errors"
import { AddressType } from "./types/internal"
import type { Version } from "./types/public"
import { HARDENED } from "./types/public"
import { assert } from "./utils/assert"
import { isArray, isBuffer, isInteger, isString, parseIntFromStr, validate } from "./utils/parse"
Expand Down Expand Up @@ -147,3 +148,7 @@ export default {
chunkBy,
stripRetcodeFromResponse,
}

export function getVersionString(version: Version): string {
return `${version.major}.${version.minor}.${version.patch}`
}
2 changes: 1 addition & 1 deletion src/utils/parse.ts
Expand Up @@ -182,7 +182,7 @@ export function parseBIP32Path(value: unknown, errMsg: InvalidDataReason): Valid
}

export function parseStakeCredential(stakeCredential: StakeCredentialParams, errMsg: InvalidDataReason): ParsedStakeCredential {
if (stakeCredential.type == StakeCredentialParamsType.KEY_PATH) {
if (stakeCredential.type === StakeCredentialParamsType.KEY_PATH) {
return {
type: StakeCredentialType.KEY_PATH,
path: parseBIP32Path(stakeCredential.keyPath, errMsg),
Expand Down
6 changes: 3 additions & 3 deletions src/utils/serialize.ts
Expand Up @@ -44,7 +44,7 @@ export function uint64_to_buf(value: Uint64_str): Buffer {
assert(isUint64str(value), 'invalid uint64_str')

const data = new Uint64BE(value, 10).toBuffer()
assert(data.length == 8, "invalid data length")
assert(data.length === 8, "invalid data length")

return data
}
Expand All @@ -53,7 +53,7 @@ export function int64_to_buf(value: Int64_str): Buffer {
assert(isInt64str(value), 'invalid int64_str')

const data = new Int64BE(value, 10).toBuffer()
assert(data.length == 8, "invalid data length")
assert(data.length === 8, "invalid data length")

return data
}
Expand Down Expand Up @@ -82,7 +82,7 @@ export function path_to_buf(path: Array<number>): Buffer {
}

export function stake_credential_to_buf(stakeCredential: ParsedStakeCredential): Buffer {
if (stakeCredential.type == StakeCredentialType.KEY_PATH) {
if (stakeCredential.type === StakeCredentialType.KEY_PATH) {
return Buffer.concat([
uint8_to_buf(stakeCredential.type as Uint8_t),
path_to_buf(stakeCredential.path),
Expand Down
2 changes: 1 addition & 1 deletion test/unit/parse.test.ts
Expand Up @@ -47,7 +47,7 @@ describe("basicParseTest", async () => {
const objectRepresentation = (signed ? new Int64BE(numberString, 10) : new Uint64BE(numberString, 10))
const bufferRep = objectRepresentation.toBuffer()

assert(bufferRep.length == 8, "invalid binary length")
assert(bufferRep.length === 8, "invalid binary length")

expect(objectRepresentation.toString()).to.equal(numberString)
}
Expand Down

0 comments on commit 6049e75

Please sign in to comment.