From 7041a0bbd3e3f0d1e7316f85fd791a718cbfdf5d Mon Sep 17 00:00:00 2001 From: ledhed2222 Date: Tue, 4 Jan 2022 09:25:04 -0500 Subject: [PATCH] address codec linting (#1881) --- packages/ripple-address-codec/.eslintrc.js | 11 --- packages/ripple-address-codec/src/index.ts | 18 +++- packages/ripple-address-codec/src/utils.ts | 3 +- .../ripple-address-codec/src/xrp-codec.ts | 97 ++++++++++--------- 4 files changed, 66 insertions(+), 63 deletions(-) diff --git a/packages/ripple-address-codec/.eslintrc.js b/packages/ripple-address-codec/.eslintrc.js index 5b8c6474..ac5ef437 100644 --- a/packages/ripple-address-codec/.eslintrc.js +++ b/packages/ripple-address-codec/.eslintrc.js @@ -33,18 +33,7 @@ module.exports = { // all of the below are turned off for now during the migration to a // monorepo. They need to actually be addressed! // ** - '@typescript-eslint/consistent-type-assertions': 'off', - '@typescript-eslint/no-unnecessary-condition': 'off', - '@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/no-magic-numbers': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/no-unsafe-return': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/explicit-member-accessibility': 'off', - '@typescript-eslint/promise-function-async': 'off', - '@typescript-eslint/prefer-nullish-coalescing': 'off', - '@typescript-eslint/naming-convention': 'off', - '@typescript-eslint/no-explicit-any': 'off', 'jsdoc/require-returns': 'off', 'jsdoc/check-param-names': 'off', 'jsdoc/require-throws': 'off', diff --git a/packages/ripple-address-codec/src/index.ts b/packages/ripple-address-codec/src/index.ts index c37332db..f94ea796 100644 --- a/packages/ripple-address-codec/src/index.ts +++ b/packages/ripple-address-codec/src/index.ts @@ -15,9 +15,9 @@ import { const PREFIX_BYTES = { // 5, 68 - MAIN: Buffer.from([0x05, 0x44]), + main: Buffer.from([0x05, 0x44]), // 4, 147 - TEST: Buffer.from([0x04, 0x93]), + test: Buffer.from([0x04, 0x93]), } const MAX_32_BIT_UNSIGNED_INT = 4294967295 @@ -48,7 +48,7 @@ function encodeXAddress( /* eslint-disable no-bitwise --- * need to use bitwise operations here */ const bytes = Buffer.concat([ - test ? PREFIX_BYTES.TEST : PREFIX_BYTES.MAIN, + test ? PREFIX_BYTES.test : PREFIX_BYTES.main, accountId, Buffer.from([ // 0x00 if no tag, 0x01 if 32-bit tag @@ -77,7 +77,11 @@ function xAddressToClassicAddress(xAddress: string): { tag: number | false test: boolean } { + /* eslint-disable @typescript-eslint/naming-convention -- + * TODO 'test' should be something like 'isTest', do this later + */ const { accountId, tag, test } = decodeXAddress(xAddress) + /* eslint-enable @typescript-eslint/naming-convention */ const classicAddress = encodeAccountID(accountId) return { classicAddress, @@ -92,7 +96,11 @@ function decodeXAddress(xAddress: string): { test: boolean } { const decoded = codec.decodeChecked(xAddress) + /* eslint-disable @typescript-eslint/naming-convention -- + * TODO 'test' should be something like 'isTest', do this later + */ const test = isBufferForTestAddress(decoded) + /* eslint-enable @typescript-eslint/naming-convention */ const accountId = decoded.slice(2, 22) const tag = tagFromBuffer(decoded) return { @@ -104,10 +112,10 @@ function decodeXAddress(xAddress: string): { function isBufferForTestAddress(buf: Buffer): boolean { const decodedPrefix = buf.slice(0, 2) - if (PREFIX_BYTES.MAIN.equals(decodedPrefix)) { + if (PREFIX_BYTES.main.equals(decodedPrefix)) { return false } - if (PREFIX_BYTES.TEST.equals(decodedPrefix)) { + if (PREFIX_BYTES.test.equals(decodedPrefix)) { return true } throw new Error('Invalid X-address: bad prefix') diff --git a/packages/ripple-address-codec/src/utils.ts b/packages/ripple-address-codec/src/utils.ts index f07e6d38..3e33f7ef 100644 --- a/packages/ripple-address-codec/src/utils.ts +++ b/packages/ripple-address-codec/src/utils.ts @@ -25,7 +25,7 @@ export function seqEqual(arr1: Sequence, arr2: Sequence): boolean { * @param val - The value to check. */ function isSequence(val: Sequence | number): val is Sequence { - return (val as Sequence).length !== undefined + return typeof val !== 'number' } /** @@ -36,6 +36,7 @@ function isSequence(val: Sequence | number): val is Sequence { * > concatArgs(1, [2, 3], Buffer.from([4,5]), new Uint8Array([6, 7])); * [1,2,3,4,5,6,7] * + * @param args - Concatenate of these args into a single array. * @returns Array of concatenated arguments */ export function concatArgs(...args: Array): number[] { diff --git a/packages/ripple-address-codec/src/xrp-codec.ts b/packages/ripple-address-codec/src/xrp-codec.ts index 2ffeabd3..ad8ac719 100644 --- a/packages/ripple-address-codec/src/xrp-codec.ts +++ b/packages/ripple-address-codec/src/xrp-codec.ts @@ -8,19 +8,17 @@ import * as createHash from 'create-hash' import { seqEqual, concatArgs } from './utils' class Codec { - sha256: (bytes: Uint8Array) => Buffer - alphabet: string - codec: baseCodec.BaseConverter - base: number + private readonly _sha256: (bytes: Uint8Array) => Buffer + private readonly _alphabet: string + private readonly _codec: baseCodec.BaseConverter - constructor(options: { + public constructor(options: { sha256: (bytes: Uint8Array) => Buffer alphabet: string }) { - this.sha256 = options.sha256 - this.alphabet = options.alphabet - this.codec = baseCodec(this.alphabet) - this.base = this.alphabet.length + this._sha256 = options.sha256 + this._alphabet = options.alphabet + this._codec = baseCodec(this._alphabet) } /** @@ -29,7 +27,7 @@ class Codec { * @param bytes - Buffer of data to encode. * @param opts - Options object including the version bytes and the expected length of the data to encode. */ - encode( + public encode( bytes: Buffer, opts: { versions: number[] @@ -37,30 +35,7 @@ class Codec { }, ): string { const versions = opts.versions - return this.encodeVersioned(bytes, versions, opts.expectedLength) - } - - encodeVersioned( - bytes: Buffer, - versions: number[], - expectedLength: number, - ): string { - if (expectedLength && bytes.length !== expectedLength) { - throw new Error( - 'unexpected_payload_length: bytes.length does not match expectedLength.' + - ' Ensure that the bytes are a Buffer.', - ) - } - return this.encodeChecked(Buffer.from(concatArgs(versions, bytes))) - } - - encodeChecked(buffer: Buffer): string { - const check = this.sha256(this.sha256(buffer)).slice(0, 4) - return this.encodeRaw(Buffer.from(concatArgs(buffer, check))) - } - - encodeRaw(bytes: Buffer): string { - return this.codec.encode(bytes) + return this._encodeVersioned(bytes, versions, opts.expectedLength) } /** @@ -71,7 +46,7 @@ class Codec { */ /* eslint-disable max-lines-per-function -- * TODO refactor */ - decode( + public decode( base58string: string, opts: { versions: Array @@ -96,11 +71,13 @@ class Codec { const versionLengthGuess = typeof versions[0] === 'number' ? 1 : versions[0].length const payloadLength = - opts.expectedLength || withoutSum.length - versionLengthGuess + opts.expectedLength ?? withoutSum.length - versionLengthGuess const versionBytes = withoutSum.slice(0, -payloadLength) const payload = withoutSum.slice(-payloadLength) for (let i = 0; i < versions.length; i++) { + /* eslint-disable @typescript-eslint/consistent-type-assertions -- + * TODO refactor */ const version: number[] = Array.isArray(versions[i]) ? (versions[i] as number[]) : [versions[i] as number] @@ -111,31 +88,55 @@ class Codec { type: types ? types[i] : null, } } + /* eslint-enable @typescript-eslint/consistent-type-assertions */ } throw new Error( 'version_invalid: version bytes do not match any of the provided version(s)', ) } - /* eslint-enable max-lines-per-function */ - decodeChecked(base58string: string): Buffer { - const buffer = this.decodeRaw(base58string) + public encodeChecked(buffer: Buffer): string { + const check = this._sha256(this._sha256(buffer)).slice(0, 4) + return this._encodeRaw(Buffer.from(concatArgs(buffer, check))) + } + + public decodeChecked(base58string: string): Buffer { + const buffer = this._decodeRaw(base58string) if (buffer.length < 5) { throw new Error('invalid_input_size: decoded data must have length >= 5') } - if (!this.verifyCheckSum(buffer)) { + if (!this._verifyCheckSum(buffer)) { throw new Error('checksum_invalid') } return buffer.slice(0, -4) } - decodeRaw(base58string: string): Buffer { - return this.codec.decode(base58string) + private _encodeVersioned( + bytes: Buffer, + versions: number[], + expectedLength: number, + ): string { + if (expectedLength && bytes.length !== expectedLength) { + throw new Error( + 'unexpected_payload_length: bytes.length does not match expectedLength.' + + ' Ensure that the bytes are a Buffer.', + ) + } + return this.encodeChecked(Buffer.from(concatArgs(versions, bytes))) } - verifyCheckSum(bytes: Buffer): boolean { - const computed = this.sha256(this.sha256(bytes.slice(0, -4))).slice(0, 4) + private _encodeRaw(bytes: Buffer): string { + return this._codec.encode(bytes) + } + /* eslint-enable max-lines-per-function */ + + private _decodeRaw(base58string: string): Buffer { + return this._codec.decode(base58string) + } + + private _verifyCheckSum(bytes: Buffer): boolean { + const computed = this._sha256(this._sha256(bytes.slice(0, -4))).slice(0, 4) const checksum = bytes.slice(-4) return seqEqual(computed, checksum) } @@ -159,7 +160,7 @@ const NODE_PUBLIC = 0x1c const ED25519_SEED = [0x01, 0xe1, 0x4b] const codecOptions = { - sha256(bytes: Uint8Array) { + sha256(bytes: Uint8Array): Buffer { return createHash('sha256').update(Buffer.from(bytes)).digest() }, alphabet: 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz', @@ -200,7 +201,11 @@ export function decodeSeed( versions: [ED25519_SEED, FAMILY_SEED], expectedLength: 16, }, -) { +): { + version: number[] + bytes: Buffer + type: string | null +} { return codecWithXrpAlphabet.decode(seed, opts) }