Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MPT #2661

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open

MPT #2661

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
2f04983
initial commit
shawnxie999 Feb 13, 2024
cd73e1b
wip
shawnxie999 Feb 14, 2024
da51954
revert bad changes
shawnxie999 Feb 15, 2024
0d2af85
definitions
shawnxie999 Feb 15, 2024
2ee5d88
export
shawnxie999 Feb 15, 2024
134b977
MPT create (wip)
shawnxie999 Feb 16, 2024
ba890ca
issuancecreate
shawnxie999 Feb 21, 2024
54648a8
destroy tx
shawnxie999 Feb 21, 2024
05a831c
mptset tx
shawnxie999 Feb 21, 2024
24dc137
authorize tx
shawnxie999 Feb 22, 2024
7ea0aba
payment + clawback (wip)
shawnxie999 Mar 6, 2024
229a0c7
wip
shawnxie999 Mar 7, 2024
cfc7979
fix binary codec test fail
shawnxie999 Mar 7, 2024
d53ef0e
has192 test
shawnxie999 Mar 7, 2024
034bebb
amount simple serialization test
shawnxie999 Mar 7, 2024
8449439
fix test
shawnxie999 Mar 8, 2024
a11a395
some amount tests
shawnxie999 Mar 11, 2024
0ff4169
more tests
shawnxie999 Mar 12, 2024
02d78ee
some hex value tests
shawnxie999 Mar 12, 2024
11ce368
negative amount test
shawnxie999 Mar 13, 2024
3d56868
rename mptDecimalToHex
shawnxie999 Mar 14, 2024
a9d5a9b
history.md
shawnxie999 Apr 22, 2024
3093e38
only apply mptamount for payment and claw
shawnxie999 Apr 22, 2024
58aca14
fix test and update to latest definition
shawnxie999 Jul 8, 2024
5e55b80
Merge remote-tracking branch 'upstream/main' into mpt
shawnxie999 Jul 9, 2024
542c201
update definitoin.json
shawnxie999 Aug 21, 2024
637347c
add object type def and filter by type
shawnxie999 Aug 21, 2024
7d43a14
add mpt payment
shawnxie999 Aug 21, 2024
e885c3a
fix bad comment and improvements
shawnxie999 Aug 21, 2024
613c306
Merge branch 'main' into mpt
shawnxie999 Aug 22, 2024
ca53e51
update definition with ledgerstatefix
shawnxie999 Sep 4, 2024
25ea3d3
wip
shawnxie999 Sep 13, 2024
a6f3738
binary codec test
shawnxie999 Sep 13, 2024
cb92806
tests
shawnxie999 Oct 1, 2024
d367a83
Merge pull request #1 from shawnxie999/mpt-base10
shawnxie999 Oct 1, 2024
f69fc74
update definitions.json
shawnxie999 Oct 9, 2024
6461315
Merge remote-tracking branch 'upstream/main' into mpt
shawnxie999 Oct 9, 2024
458f0b8
fix failed test
shawnxie999 Oct 9, 2024
32ea011
fix lint
shawnxie999 Oct 9, 2024
7529657
fix lint errors
shawnxie999 Oct 9, 2024
46c66e5
fix more lint
shawnxie999 Oct 9, 2024
9bfb200
const to let
shawnxie999 Oct 10, 2024
92efe13
Rename MPTokenHolder to Holder (#2)
shawnxie999 Oct 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,123 changes: 1,094 additions & 1,029 deletions packages/ripple-binary-codec/src/enums/definitions.json

Large diffs are not rendered by default.

131 changes: 119 additions & 12 deletions packages/ripple-binary-codec/src/types/amount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { JsonObject, SerializedType } from './serialized-type'
import BigNumber from 'bignumber.js'
import { bytesToHex, concat, hexToBytes } from '@xrplf/isomorphic/utils'
import { readUInt32BE, writeUInt32BE } from '../utils'
import { Hash192 } from './hash-192'

/**
* Constants for validating amounts
Expand All @@ -16,6 +17,7 @@ const MAX_IOU_PRECISION = 16
const MAX_DROPS = new BigNumber('1e17')
const MIN_XRP = new BigNumber('1e-6')
const mask = BigInt(0x00000000ffffffff)
const mptMask = BigInt(0x8000000000000000)

/**
* BigNumber configuration for Amount IOUs
Expand All @@ -27,20 +29,28 @@ BigNumber.config({
],
})

/**
* Interface for JSON objects that represent amounts
*/
interface AmountObject extends JsonObject {
interface AmountObjectIOU extends JsonObject {
value: string
currency: string
issuer: string
}

interface AmountObjectMPT extends JsonObject {
value: string
mpt_issuance_id: string
}

Comment on lines +38 to +42
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use camelCase for property names in AmountObjectMPT

The property mpt_issuance_id in the AmountObjectMPT interface uses snake_case, which is inconsistent with the standard camelCase naming convention in TypeScript and JavaScript. Consider renaming it to mptIssuanceId to maintain consistency throughout the codebase.

Apply this change:

 interface AmountObjectMPT extends JsonObject {
   value: string
-  mpt_issuance_id: string
+  mptIssuanceId: string
 }

And update all references to mpt_issuance_id accordingly.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
interface AmountObjectMPT extends JsonObject {
value: string
mpt_issuance_id: string
}
interface AmountObjectMPT extends JsonObject {
value: string
mptIssuanceId: string
}

/**
* Interface for JSON objects that represent amounts
*/
type AmountObject = AmountObjectIOU | AmountObjectMPT

/**
* Type guard for AmountObject
* Type guard for AmountObjectIOU
*/
function isAmountObject(arg): arg is AmountObject {
function isAmountObjectIOU(arg): arg is AmountObjectIOU {
const keys = Object.keys(arg).sort()

return (
keys.length === 3 &&
keys[0] === 'currency' &&
Expand All @@ -49,6 +59,17 @@ function isAmountObject(arg): arg is AmountObject {
)
}

/**
* Type guard for AmountObjectMPT
*/
function isAmountObjectMPT(arg): arg is AmountObjectMPT {
const keys = Object.keys(arg).sort()

return (
keys.length === 2 && keys[0] === 'mpt_issuance_id' && keys[1] === 'value'
)
}
Comment on lines +65 to +71
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Specify parameter type and validate property types in isAmountObjectMPT

Similar to isAmountObjectIOU, the isAmountObjectMPT function lacks a parameter type and doesn't validate the types of its properties. To improve type safety and ensure accurate type guarding, consider specifying the parameter type and checking property types.

Apply this change:

-function isAmountObjectMPT(arg): arg is AmountObjectMPT {
+function isAmountObjectMPT(arg: any): arg is AmountObjectMPT {
   const keys = Object.keys(arg).sort()

   return (
     keys.length === 2 &&
     keys[0] === 'mpt_issuance_id' &&
     keys[1] === 'value'
+    && typeof arg.value === 'string'
+    && typeof arg.mpt_issuance_id === 'string'
   )
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function isAmountObjectMPT(arg): arg is AmountObjectMPT {
const keys = Object.keys(arg).sort()
return (
keys.length === 2 && keys[0] === 'mpt_issuance_id' && keys[1] === 'value'
)
}
function isAmountObjectMPT(arg: any): arg is AmountObjectMPT {
const keys = Object.keys(arg).sort()
return (
keys.length === 2 &&
keys[0] === 'mpt_issuance_id' &&
keys[1] === 'value' &&
typeof arg.value === 'string' &&
typeof arg.mpt_issuance_id === 'string'
)
}


/**
* Class for serializing/Deserializing Amounts
*/
Expand All @@ -60,7 +81,7 @@ class Amount extends SerializedType {
}

/**
* Construct an amount from an IOU or string amount
* Construct an amount from an IOU, MPT or string amount
*
* @param value An Amount, object representing an IOU, or a string
* representing an integer amount
Expand Down Expand Up @@ -88,7 +109,7 @@ class Amount extends SerializedType {
return new Amount(amount)
}

if (isAmountObject(value)) {
if (isAmountObjectIOU(value)) {
const number = new BigNumber(value.value)
Amount.assertIouIsValid(number)

Expand Down Expand Up @@ -124,6 +145,24 @@ class Amount extends SerializedType {
return new Amount(concat([amount, currency, issuer]))
}

if (isAmountObjectMPT(value)) {
Amount.assertMptIsValid(value.value)

let leadingByte = new Uint8Array(1)
leadingByte[0] |= 0x60

const num = BigInt(value.value)

const intBuf = [new Uint8Array(4), new Uint8Array(4)]
writeUInt32BE(intBuf[0], Number(num >> BigInt(32)), 0)
writeUInt32BE(intBuf[1], Number(num & BigInt(mask)), 0)

amount = concat(intBuf)

const mptIssuanceID = Hash192.from(value.mpt_issuance_id).toBytes()
return new Amount(concat([leadingByte, amount, mptIssuanceID]))
}

throw new Error('Invalid type to construct an Amount')
}

Expand All @@ -134,8 +173,12 @@ class Amount extends SerializedType {
* @returns An Amount object
*/
static fromParser(parser: BinaryParser): Amount {
const isXRP = parser.peek() & 0x80
const numBytes = isXRP ? 48 : 8
const isIOU = parser.peek() & 0x80
if (isIOU) return new Amount(parser.read(48))

// the amount can be either MPT or XRP at this point
const isMPT = parser.peek() & 0x20
const numBytes = isMPT ? 33 : 8
return new Amount(parser.read(numBytes))
}

Expand All @@ -156,7 +199,9 @@ class Amount extends SerializedType {
const num = (msb << BigInt(32)) | lsb

return `${sign}${num.toString()}`
} else {
}

if (this.isIOU()) {
const parser = new BinaryParser(this.toString())
const mantissa = parser.read(8)
const currency = Currency.fromParser(parser) as Currency
Expand All @@ -182,6 +227,27 @@ class Amount extends SerializedType {
issuer: issuer.toJSON(),
}
}

if (this.isMPT()) {
const parser = new BinaryParser(this.toString())
const leadingByte = parser.read(1)
const amount = parser.read(8)
const mptID = Hash192.fromParser(parser) as Hash192

const isPositive = leadingByte[0] & 0x40
const sign = isPositive ? '' : '-'

const msb = BigInt(readUInt32BE(amount.slice(0, 4), 0))
const lsb = BigInt(readUInt32BE(amount.slice(4), 0))
const num = (msb << BigInt(32)) | lsb

return {
value: `${sign}${num.toString()}`,
mpt_issuance_id: mptID.toString(),
}
}

throw new Error('Invalid amount to construct JSON')
}

/**
Expand Down Expand Up @@ -224,6 +290,29 @@ class Amount extends SerializedType {
}
}

/**
* Validate MPT.value amount
*
* @param decimal BigNumber object representing MPT.value
* @returns void, but will throw if invalid amount
*/
private static assertMptIsValid(amount: string): void {
if (amount.indexOf('.') !== -1) {
throw new Error(`${amount.toString()} is an illegal amount`)
}

const decimal = new BigNumber(amount)
if (!decimal.isZero()) {
if (decimal < BigNumber(0)) {
throw new Error(`${amount.toString()} is an illegal amount`)
}

if (Number(BigInt(amount) & BigInt(mptMask)) != 0) {
throw new Error(`${amount.toString()} is an illegal amount`)
}
}
}

Comment on lines +293 to +315
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct the BigNumber comparison and fix parameter inconsistencies in assertMptIsValid

There are several issues in the assertMptIsValid method:

  1. Incorrect parameter documentation: The @param description mentions decimal: BigNumber, but the method parameter is amount: string.

  2. Incorrect BigNumber comparison: The comparison if (decimal < BigNumber(0)) is invalid. Use decimal.isLessThan(0) instead.

  3. Instantiation of BigNumber(0): Should be new BigNumber(0).

  4. Variable naming inconsistency: The parameter is named amount, but within the method, it's referred to as decimal.

Consider applying the following changes:

- * @param decimal BigNumber object representing MPT.value
+ * @param amount String representing MPT.value

-private static assertMptIsValid(amount: string): void {
+private static assertMptIsValid(value: string): void {
-  if (amount.indexOf('.') !== -1) {
+  if (value.indexOf('.') !== -1) {
     throw new Error(`${value.toString()} is an illegal amount`)
   }

-  const decimal = new BigNumber(amount)
+  const decimal = new BigNumber(value)
   if (!decimal.isZero()) {
-    if (decimal < BigNumber(0)) {
+    if (decimal.isLessThan(0)) {
       throw new Error(`${value.toString()} is an illegal amount`)
     }

-    if (Number(BigInt(amount) & BigInt(mptMask)) != 0) {
+    if ((BigInt(value) & mptMask) !== BigInt(0)) {
       throw new Error(`${value.toString()} is an illegal amount`)
     }
   }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Validate MPT.value amount
*
* @param decimal BigNumber object representing MPT.value
* @returns void, but will throw if invalid amount
*/
private static assertMptIsValid(amount: string): void {
if (amount.indexOf('.') !== -1) {
throw new Error(`${amount.toString()} is an illegal amount`)
}
const decimal = new BigNumber(amount)
if (!decimal.isZero()) {
if (decimal < BigNumber(0)) {
throw new Error(`${amount.toString()} is an illegal amount`)
}
if (Number(BigInt(amount) & BigInt(mptMask)) != 0) {
throw new Error(`${amount.toString()} is an illegal amount`)
}
}
}
/**
* Validate MPT.value amount
*
* @param amount String representing MPT.value
* @returns void, but will throw if invalid amount
*/
private static assertMptIsValid(value: string): void {
if (value.indexOf('.') !== -1) {
throw new Error(`${value.toString()} is an illegal amount`)
}
const decimal = new BigNumber(value)
if (!decimal.isZero()) {
if (decimal.isLessThan(0)) {
throw new Error(`${value.toString()} is an illegal amount`)
}
if ((BigInt(value) & mptMask) !== BigInt(0)) {
throw new Error(`${value.toString()} is an illegal amount`)
}
}
}

/**
* Ensure that the value after being multiplied by the exponent does not
* contain a decimal.
Expand All @@ -248,7 +337,25 @@ class Amount extends SerializedType {
* @returns true if Native (XRP)
*/
private isNative(): boolean {
return (this.bytes[0] & 0x80) === 0
return (this.bytes[0] & 0x80) === 0 && (this.bytes[0] & 0x20) === 0
}

/**
* Test if this amount is in units of MPT
*
* @returns true if MPT
*/
private isMPT(): boolean {
return (this.bytes[0] & 0x80) === 0 && (this.bytes[0] & 0x20) !== 0
}

/**
* Test if this amount is in units of IOU
*
* @returns true if IOU
*/
private isIOU(): boolean {
return (this.bytes[0] & 0x80) !== 0
Comment on lines +340 to +358
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider making amount type check methods public

The methods isNative, isMPT, and isIOU are currently private. If external classes or functions need to determine the type of an Amount instance, consider making these methods public to improve accessibility and facilitate better type handling.

}
}

Expand Down
19 changes: 19 additions & 0 deletions packages/ripple-binary-codec/src/types/hash-192.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Hash } from './hash'

/**
* Hash with a width of 192 bits
*/
class Hash192 extends Hash {
static readonly width = 24
static readonly ZERO_192: Hash192 = new Hash192(new Uint8Array(Hash192.width))

constructor(bytes?: Uint8Array) {
if (bytes && bytes.byteLength === 0) {
bytes = Hash192.ZERO_192.bytes
}

super(bytes ?? Hash192.ZERO_192.bytes)
}
}

export { Hash192 }
3 changes: 3 additions & 0 deletions packages/ripple-binary-codec/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Blob } from './blob'
import { Currency } from './currency'
import { Hash128 } from './hash-128'
import { Hash160 } from './hash-160'
import { Hash192 } from './hash-192'
import { Hash256 } from './hash-256'
import { Issue } from './issue'
import { PathSet } from './path-set'
Expand All @@ -25,6 +26,7 @@ const coreTypes: Record<string, typeof SerializedType> = {
Currency,
Hash128,
Hash160,
Hash192,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Issue: Incomplete implementation of Hash192 class.

  • The Hash192 class in packages/ripple-binary-codec/src/types/hash-192.ts is missing the static readonly width = 24; property.
🔗 Analysis chain

LGTM: Hash192 added to coreTypes correctly.

The Hash192 type has been appropriately added to the coreTypes object, maintaining consistency with other hash types and preserving alphabetical order.

To ensure the Hash192 type is fully implemented, please run the following script:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation of Hash192 type

# Test 1: Check if hash-192.ts file exists
fd -t f "hash-192.ts" packages/ripple-binary-codec/src/types

# Test 2: Verify Hash192 class implementation
ast-grep --lang typescript --pattern $'class Hash192 {
  $$$
  static readonly width = 24;
  $$$
}'

# Test 3: Check for unit tests
fd -t f "hash-192.test.ts" packages/ripple-binary-codec/src/types

Length of output: 375


Script:

#!/bin/bash
# Description: Re-verify the implementation of Hash192 type with corrected commands

# Test 1: Check if hash-192.ts file exists
fd -t f "hash-192.ts" packages/ripple-binary-codec/src/types

# Test 2: Verify Hash192 class implementation
ast-grep --lang typescript --pattern $'class Hash192 {
  $$$
  static readonly width = 24;
  $$$
}'

# Test 3: Check for unit tests
fd -t f "hash-192.test.ts" packages/ripple-binary-codec/src/types

Length of output: 278

Hash256,
Issue,
PathSet,
Expand All @@ -51,6 +53,7 @@ export {
Currency,
Hash128,
Hash160,
Hash192,
Hash256,
PathSet,
STArray,
Expand Down
2 changes: 1 addition & 1 deletion packages/ripple-binary-codec/src/types/serialized-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class SerializedType {
* Can be customized for sidechains and amendments.
* @returns any type, if not overloaded returns hexString representation of bytes
*/
toJSON(_definitions?: XrplDefinitionsBase): JSON {
toJSON(_definitions?: XrplDefinitionsBase, _fieldName?: string): JSON {
return this.toHex()
}

Expand Down
5 changes: 4 additions & 1 deletion packages/ripple-binary-codec/src/types/st-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { BinaryParser } from '../serdes/binary-parser'
import { BinarySerializer, BytesList } from '../serdes/binary-serializer'

import { STArray } from './st-array'
import { UInt64 } from './uint-64'

const OBJECT_END_MARKER_BYTE = Uint8Array.from([0xe1])
const OBJECT_END_MARKER = 'ObjectEndMarker'
Expand Down Expand Up @@ -137,6 +138,8 @@ class STObject extends SerializedType {
? this.from(xAddressDecoded[field.name], undefined, definitions)
: field.type.name === 'STArray'
? STArray.from(xAddressDecoded[field.name], definitions)
: field.type.name === 'UInt64'
? UInt64.from(xAddressDecoded[field.name], field.name)
: field.associatedType.from(xAddressDecoded[field.name])

if (associatedValue == undefined) {
Expand Down Expand Up @@ -182,7 +185,7 @@ class STObject extends SerializedType {

accumulator[field.name] = objectParser
.readFieldValue(field)
.toJSON(definitions)
.toJSON(definitions, field.name)
}

return accumulator
Expand Down
38 changes: 33 additions & 5 deletions packages/ripple-binary-codec/src/types/uint-64.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@ import { UInt } from './uint'
import { BinaryParser } from '../serdes/binary-parser'
import { bytesToHex, concat, hexToBytes } from '@xrplf/isomorphic/utils'
import { readUInt32BE, writeUInt32BE } from '../utils'
import { DEFAULT_DEFINITIONS, XrplDefinitionsBase } from '../enums'

const HEX_REGEX = /^[a-fA-F0-9]{1,16}$/
const BASE10_REGEX = /^[0-9]{1,20}$/
const mask = BigInt(0x00000000ffffffff)

function useBase10(fieldName: string): boolean {
return (
fieldName === 'MaximumAmount' ||
fieldName === 'OutstandingAmount' ||
fieldName === 'MPTAmount'
)
}
Comment on lines +11 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using a Set for field names in useBase10 function.

To enhance scalability and performance, especially if more fields are added in the future, consider using a Set to store field names. This approach simplifies the addition of new fields and improves lookup efficiency.

Apply this refactor:

+const BASE10_FIELDS = new Set(['MaximumAmount', 'OutstandingAmount', 'MPTAmount'])

-function useBase10(fieldName: string): boolean {
-  return (
-    fieldName === 'MaximumAmount' ||
-    fieldName === 'OutstandingAmount' ||
-    fieldName === 'MPTAmount'
-  )
+function useBase10(fieldName: string): boolean {
+  return BASE10_FIELDS.has(fieldName)
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function useBase10(fieldName: string): boolean {
return (
fieldName === 'MaximumAmount' ||
fieldName === 'OutstandingAmount' ||
fieldName === 'MPTAmount'
)
}
const BASE10_FIELDS = new Set(['MaximumAmount', 'OutstandingAmount', 'MPTAmount'])
function useBase10(fieldName: string): boolean {
return BASE10_FIELDS.has(fieldName)
}


/**
* Derived UInt class for serializing/deserializing 64 bit UInt
*/
Expand All @@ -29,7 +39,10 @@ class UInt64 extends UInt {
* @param val A UInt64, hex-string, bigInt, or number
* @returns A UInt64 object
*/
static from<T extends UInt64 | string | bigint | number>(val: T): UInt64 {
static from<T extends UInt64 | string | bigint | number>(
val: T,
fieldName = '',
): UInt64 {
if (val instanceof UInt64) {
return val
}
Expand All @@ -51,11 +64,18 @@ class UInt64 extends UInt {
}

if (typeof val === 'string') {
if (!HEX_REGEX.test(val)) {
if (useBase10(fieldName)) {
if (!BASE10_REGEX.test(val)) {
throw new Error(`${fieldName} ${val} is not a valid base 10 string`)
}
val = BigInt(val).toString(16) as T
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid unnecessary type casting after conversion.

Casting val to type T after converting it to a string may lead to type inconsistencies. Since val is expected to be a string at this point, you can proceed without the cast.

Apply this fix:

-            val = BigInt(val).toString(16) as T
+            val = BigInt(val).toString(16)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
val = BigInt(val).toString(16) as T
val = BigInt(val).toString(16)

}

if (typeof val === 'string' && !HEX_REGEX.test(val)) {
throw new Error(`${val} is not a valid hex-string`)
}

const strBuf = val.padStart(16, '0')
const strBuf = (val as string).padStart(16, '0')
buf = hexToBytes(strBuf)
return new UInt64(buf)
}
Expand All @@ -76,8 +96,16 @@ class UInt64 extends UInt {
*
* @returns a hex-string
*/
toJSON(): string {
return bytesToHex(this.bytes)
toJSON(
_definitions: XrplDefinitionsBase = DEFAULT_DEFINITIONS,
fieldName = '',
): string {
const hexString = bytesToHex(this.bytes)
if (useBase10(fieldName)) {
return BigInt('0x' + hexString).toString(10)
}

return hexString
}

/**
Expand Down
Loading
Loading