mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-10 15:55:50 +00:00
Compare commits
1 Commits
ripple-bin
...
gw/more-li
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0aad4e7d31 |
@@ -34,18 +34,7 @@ module.exports = {
|
|||||||
// monorepo. They need to actually be addressed!
|
// monorepo. They need to actually be addressed!
|
||||||
// **
|
// **
|
||||||
'@typescript-eslint/consistent-type-assertions': 'off',
|
'@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/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/check-param-names': 'off',
|
||||||
'jsdoc/require-throws': 'off',
|
'jsdoc/require-throws': 'off',
|
||||||
'jsdoc/require-jsdoc': 'off',
|
'jsdoc/require-jsdoc': 'off',
|
||||||
|
|||||||
@@ -13,12 +13,15 @@ import {
|
|||||||
isValidClassicAddress,
|
isValidClassicAddress,
|
||||||
} from './xrp-codec'
|
} from './xrp-codec'
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/naming-convention --
|
||||||
|
* there are just sub constants */
|
||||||
const PREFIX_BYTES = {
|
const PREFIX_BYTES = {
|
||||||
// 5, 68
|
// 5, 68
|
||||||
MAIN: Buffer.from([0x05, 0x44]),
|
MAIN: Buffer.from([0x05, 0x44]),
|
||||||
// 4, 147
|
// 4, 147
|
||||||
TEST: Buffer.from([0x04, 0x93]),
|
TEST: Buffer.from([0x04, 0x93]),
|
||||||
}
|
}
|
||||||
|
/* eslint-enable @typescript-eslint/naming-convention */
|
||||||
|
|
||||||
const MAX_32_BIT_UNSIGNED_INT = 4294967295
|
const MAX_32_BIT_UNSIGNED_INT = 4294967295
|
||||||
|
|
||||||
@@ -72,6 +75,8 @@ function encodeXAddress(
|
|||||||
return codec.encodeChecked(bytes)
|
return codec.encodeChecked(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/naming-convention --
|
||||||
|
* not a big deal on these old param names */
|
||||||
function xAddressToClassicAddress(xAddress: string): {
|
function xAddressToClassicAddress(xAddress: string): {
|
||||||
classicAddress: string
|
classicAddress: string
|
||||||
tag: number | false
|
tag: number | false
|
||||||
@@ -85,7 +90,10 @@ function xAddressToClassicAddress(xAddress: string): {
|
|||||||
test,
|
test,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* eslint-enable @typescript-eslint/naming-convention */
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/naming-convention --
|
||||||
|
* not a big deal on these old param names */
|
||||||
function decodeXAddress(xAddress: string): {
|
function decodeXAddress(xAddress: string): {
|
||||||
accountId: Buffer
|
accountId: Buffer
|
||||||
tag: number | false
|
tag: number | false
|
||||||
@@ -101,6 +109,7 @@ function decodeXAddress(xAddress: string): {
|
|||||||
test,
|
test,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* eslint-enable @typescript-eslint/naming-convention */
|
||||||
|
|
||||||
function isBufferForTestAddress(buf: Buffer): boolean {
|
function isBufferForTestAddress(buf: Buffer): boolean {
|
||||||
const decodedPrefix = buf.slice(0, 2)
|
const decodedPrefix = buf.slice(0, 2)
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ type Sequence = number[] | Buffer | Uint8Array
|
|||||||
*
|
*
|
||||||
* @param arr1 - One of the arrays to compare.
|
* @param arr1 - One of the arrays to compare.
|
||||||
* @param arr2 - The other array to compare.
|
* @param arr2 - The other array to compare.
|
||||||
|
*
|
||||||
|
* @returns true if arguments are equal; false otherwise.
|
||||||
*/
|
*/
|
||||||
export function seqEqual(arr1: Sequence, arr2: Sequence): boolean {
|
export function seqEqual(arr1: Sequence, arr2: Sequence): boolean {
|
||||||
if (arr1.length !== arr2.length) {
|
if (arr1.length !== arr2.length) {
|
||||||
@@ -23,9 +25,11 @@ export function seqEqual(arr1: Sequence, arr2: Sequence): boolean {
|
|||||||
* Check whether a value is a sequence (e.g. Array of numbers).
|
* Check whether a value is a sequence (e.g. Array of numbers).
|
||||||
*
|
*
|
||||||
* @param val - The value to check.
|
* @param val - The value to check.
|
||||||
|
*
|
||||||
|
* @returns true if value is a Sequence; false otherwise.
|
||||||
*/
|
*/
|
||||||
function isSequence(val: Sequence | number): val is Sequence {
|
function isSequence(val: Sequence | number): val is Sequence {
|
||||||
return (val as Sequence).length !== undefined
|
return typeof val === 'object' && val.length !== undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,20 +7,24 @@ import * as createHash from 'create-hash'
|
|||||||
|
|
||||||
import { seqEqual, concatArgs } from './utils'
|
import { seqEqual, concatArgs } from './utils'
|
||||||
|
|
||||||
class Codec {
|
interface Decoded {
|
||||||
sha256: (bytes: Uint8Array) => Buffer
|
version: number[]
|
||||||
alphabet: string
|
bytes: Buffer
|
||||||
codec: baseCodec.BaseConverter
|
type: string | null
|
||||||
base: number
|
}
|
||||||
|
|
||||||
constructor(options: {
|
class Codec {
|
||||||
|
private readonly _sha256: (bytes: Uint8Array) => Buffer
|
||||||
|
private readonly _alphabet: string
|
||||||
|
private readonly _codec: baseCodec.BaseConverter
|
||||||
|
|
||||||
|
public constructor(options: {
|
||||||
sha256: (bytes: Uint8Array) => Buffer
|
sha256: (bytes: Uint8Array) => Buffer
|
||||||
alphabet: string
|
alphabet: string
|
||||||
}) {
|
}) {
|
||||||
this.sha256 = options.sha256
|
this._sha256 = options.sha256
|
||||||
this.alphabet = options.alphabet
|
this._alphabet = options.alphabet
|
||||||
this.codec = baseCodec(this.alphabet)
|
this._codec = baseCodec(this._alphabet)
|
||||||
this.base = this.alphabet.length
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,8 +32,10 @@ class Codec {
|
|||||||
*
|
*
|
||||||
* @param bytes - Buffer of data to encode.
|
* @param bytes - Buffer of data to encode.
|
||||||
* @param opts - Options object including the version bytes and the expected length of the data to encode.
|
* @param opts - Options object including the version bytes and the expected length of the data to encode.
|
||||||
|
*
|
||||||
|
* @returns bytes encoded using options
|
||||||
*/
|
*/
|
||||||
encode(
|
public encode(
|
||||||
bytes: Buffer,
|
bytes: Buffer,
|
||||||
opts: {
|
opts: {
|
||||||
versions: number[]
|
versions: number[]
|
||||||
@@ -40,29 +46,11 @@ class Codec {
|
|||||||
return this.encodeVersioned(bytes, versions, opts.expectedLength)
|
return this.encodeVersioned(bytes, versions, opts.expectedLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
encodeVersioned(
|
public encodeChecked(buffer: Buffer): string {
|
||||||
bytes: Buffer,
|
const check = this._sha256(this._sha256(buffer)).slice(0, 4)
|
||||||
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)))
|
return this.encodeRaw(Buffer.from(concatArgs(buffer, check)))
|
||||||
}
|
}
|
||||||
|
|
||||||
encodeRaw(bytes: Buffer): string {
|
|
||||||
return this.codec.encode(bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decoder.
|
* Decoder.
|
||||||
*
|
*
|
||||||
@@ -71,18 +59,14 @@ class Codec {
|
|||||||
*/
|
*/
|
||||||
/* eslint-disable max-lines-per-function --
|
/* eslint-disable max-lines-per-function --
|
||||||
* TODO refactor */
|
* TODO refactor */
|
||||||
decode(
|
public decode(
|
||||||
base58string: string,
|
base58string: string,
|
||||||
opts: {
|
opts: {
|
||||||
versions: Array<number | number[]>
|
versions: Array<number | number[]>
|
||||||
expectedLength?: number
|
expectedLength?: number
|
||||||
versionTypes?: ['ed25519', 'secp256k1']
|
versionTypes?: ['ed25519', 'secp256k1']
|
||||||
},
|
},
|
||||||
): {
|
): Decoded {
|
||||||
version: number[]
|
|
||||||
bytes: Buffer
|
|
||||||
type: string | null
|
|
||||||
} {
|
|
||||||
const versions = opts.versions
|
const versions = opts.versions
|
||||||
const types = opts.versionTypes
|
const types = opts.versionTypes
|
||||||
|
|
||||||
@@ -96,7 +80,7 @@ class Codec {
|
|||||||
const versionLengthGuess =
|
const versionLengthGuess =
|
||||||
typeof versions[0] === 'number' ? 1 : versions[0].length
|
typeof versions[0] === 'number' ? 1 : versions[0].length
|
||||||
const payloadLength =
|
const payloadLength =
|
||||||
opts.expectedLength || withoutSum.length - versionLengthGuess
|
opts.expectedLength ?? withoutSum.length - versionLengthGuess
|
||||||
const versionBytes = withoutSum.slice(0, -payloadLength)
|
const versionBytes = withoutSum.slice(0, -payloadLength)
|
||||||
const payload = withoutSum.slice(-payloadLength)
|
const payload = withoutSum.slice(-payloadLength)
|
||||||
|
|
||||||
@@ -119,7 +103,7 @@ class Codec {
|
|||||||
}
|
}
|
||||||
/* eslint-enable max-lines-per-function */
|
/* eslint-enable max-lines-per-function */
|
||||||
|
|
||||||
decodeChecked(base58string: string): Buffer {
|
public decodeChecked(base58string: string): Buffer {
|
||||||
const buffer = this.decodeRaw(base58string)
|
const buffer = this.decodeRaw(base58string)
|
||||||
if (buffer.length < 5) {
|
if (buffer.length < 5) {
|
||||||
throw new Error('invalid_input_size: decoded data must have length >= 5')
|
throw new Error('invalid_input_size: decoded data must have length >= 5')
|
||||||
@@ -130,12 +114,30 @@ class Codec {
|
|||||||
return buffer.slice(0, -4)
|
return buffer.slice(0, -4)
|
||||||
}
|
}
|
||||||
|
|
||||||
decodeRaw(base58string: string): Buffer {
|
private encodeVersioned(
|
||||||
return this.codec.decode(base58string)
|
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 {
|
private encodeRaw(bytes: Buffer): string {
|
||||||
const computed = this.sha256(this.sha256(bytes.slice(0, -4))).slice(0, 4)
|
return this._codec.encode(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
const checksum = bytes.slice(-4)
|
||||||
return seqEqual(computed, checksum)
|
return seqEqual(computed, checksum)
|
||||||
}
|
}
|
||||||
@@ -159,7 +161,7 @@ const NODE_PUBLIC = 0x1c
|
|||||||
const ED25519_SEED = [0x01, 0xe1, 0x4b]
|
const ED25519_SEED = [0x01, 0xe1, 0x4b]
|
||||||
|
|
||||||
const codecOptions = {
|
const codecOptions = {
|
||||||
sha256(bytes: Uint8Array) {
|
sha256(bytes: Uint8Array): Buffer {
|
||||||
return createHash('sha256').update(Buffer.from(bytes)).digest()
|
return createHash('sha256').update(Buffer.from(bytes)).digest()
|
||||||
},
|
},
|
||||||
alphabet: 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz',
|
alphabet: 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz',
|
||||||
@@ -200,7 +202,7 @@ export function decodeSeed(
|
|||||||
versions: [ED25519_SEED, FAMILY_SEED],
|
versions: [ED25519_SEED, FAMILY_SEED],
|
||||||
expectedLength: 16,
|
expectedLength: 16,
|
||||||
},
|
},
|
||||||
) {
|
): Decoded {
|
||||||
return codecWithXrpAlphabet.decode(seed, opts)
|
return codecWithXrpAlphabet.decode(seed, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user