ripple-binary-codec 2.7.0 → 2.8.0-smartcontract.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/enums/definitions.json +238 -260
- package/dist/enums/src/enums/definitions.json +238 -260
- package/dist/quality.js +15 -3
- package/dist/quality.js.map +1 -1
- package/dist/serdes/binary-parser.js +8 -2
- package/dist/serdes/binary-parser.js.map +1 -1
- package/dist/serdes/binary-serializer.d.ts +1 -1
- package/dist/serdes/binary-serializer.js +2 -2
- package/dist/serdes/binary-serializer.js.map +1 -1
- package/dist/src/enums/definitions.json +238 -260
- package/dist/src/quality.js +15 -3
- package/dist/src/quality.js.map +1 -1
- package/dist/src/serdes/binary-parser.js +8 -2
- package/dist/src/serdes/binary-parser.js.map +1 -1
- package/dist/src/serdes/binary-serializer.d.ts +1 -1
- package/dist/src/serdes/binary-serializer.js +2 -2
- package/dist/src/serdes/binary-serializer.js.map +1 -1
- package/dist/src/types/account-id.d.ts +2 -0
- package/dist/src/types/account-id.js +4 -0
- package/dist/src/types/account-id.js.map +1 -1
- package/dist/src/types/amount.d.ts +2 -1
- package/dist/src/types/amount.js +25 -4
- package/dist/src/types/amount.js.map +1 -1
- package/dist/src/types/blob.d.ts +2 -1
- package/dist/src/types/blob.js +3 -0
- package/dist/src/types/blob.js.map +1 -1
- package/dist/src/types/currency.d.ts +2 -0
- package/dist/src/types/currency.js +4 -0
- package/dist/src/types/currency.js.map +1 -1
- package/dist/src/types/data.d.ts +86 -0
- package/dist/src/types/data.js +252 -0
- package/dist/src/types/data.js.map +1 -0
- package/dist/src/types/dataType.d.ts +94 -0
- package/dist/src/types/dataType.js +145 -0
- package/dist/src/types/dataType.js.map +1 -0
- package/dist/src/types/hash-128.d.ts +2 -0
- package/dist/src/types/hash-128.js +4 -0
- package/dist/src/types/hash-128.js.map +1 -1
- package/dist/src/types/hash-160.d.ts +2 -0
- package/dist/src/types/hash-160.js +4 -0
- package/dist/src/types/hash-160.js.map +1 -1
- package/dist/src/types/hash-192.d.ts +2 -0
- package/dist/src/types/hash-192.js +4 -0
- package/dist/src/types/hash-192.js.map +1 -1
- package/dist/src/types/hash-256.d.ts +2 -0
- package/dist/src/types/hash-256.js +4 -0
- package/dist/src/types/hash-256.js.map +1 -1
- package/dist/src/types/index.d.ts +3 -1
- package/dist/src/types/index.js +7 -1
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/issue.d.ts +2 -1
- package/dist/src/types/issue.js +3 -0
- package/dist/src/types/issue.js.map +1 -1
- package/dist/src/types/json.d.ts +173 -0
- package/dist/src/types/json.js +531 -0
- package/dist/src/types/json.js.map +1 -0
- package/dist/src/types/path-set.d.ts +2 -1
- package/dist/src/types/path-set.js +3 -0
- package/dist/src/types/path-set.js.map +1 -1
- package/dist/src/types/serialized-type.d.ts +43 -0
- package/dist/src/types/serialized-type.js +63 -1
- package/dist/src/types/serialized-type.js.map +1 -1
- package/dist/src/types/st-array.d.ts +2 -1
- package/dist/src/types/st-array.js +3 -0
- package/dist/src/types/st-array.js.map +1 -1
- package/dist/src/types/st-number.d.ts +2 -1
- package/dist/src/types/st-number.js +3 -0
- package/dist/src/types/st-number.js.map +1 -1
- package/dist/src/types/st-object.d.ts +2 -1
- package/dist/src/types/st-object.js +9 -1
- package/dist/src/types/st-object.js.map +1 -1
- package/dist/src/types/uint-16.d.ts +2 -0
- package/dist/src/types/uint-16.js +4 -0
- package/dist/src/types/uint-16.js.map +1 -1
- package/dist/src/types/uint-32.d.ts +2 -0
- package/dist/src/types/uint-32.js +4 -0
- package/dist/src/types/uint-32.js.map +1 -1
- package/dist/src/types/uint-64.d.ts +2 -0
- package/dist/src/types/uint-64.js +4 -0
- package/dist/src/types/uint-64.js.map +1 -1
- package/dist/src/types/uint-8.d.ts +2 -0
- package/dist/src/types/uint-8.js +4 -0
- package/dist/src/types/uint-8.js.map +1 -1
- package/dist/src/types/vector-256.d.ts +2 -1
- package/dist/src/types/vector-256.js +3 -0
- package/dist/src/types/vector-256.js.map +1 -1
- package/dist/src/types/xchain-bridge.d.ts +2 -1
- package/dist/src/types/xchain-bridge.js +3 -0
- package/dist/src/types/xchain-bridge.js.map +1 -1
- package/dist/src/utils.js +1 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/account-id.d.ts +2 -0
- package/dist/types/account-id.js +4 -0
- package/dist/types/account-id.js.map +1 -1
- package/dist/types/amount.d.ts +2 -1
- package/dist/types/amount.js +25 -4
- package/dist/types/amount.js.map +1 -1
- package/dist/types/blob.d.ts +2 -1
- package/dist/types/blob.js +3 -0
- package/dist/types/blob.js.map +1 -1
- package/dist/types/currency.d.ts +2 -0
- package/dist/types/currency.js +4 -0
- package/dist/types/currency.js.map +1 -1
- package/dist/types/data.d.ts +86 -0
- package/dist/types/data.js +252 -0
- package/dist/types/data.js.map +1 -0
- package/dist/types/dataType.d.ts +94 -0
- package/dist/types/dataType.js +145 -0
- package/dist/types/dataType.js.map +1 -0
- package/dist/types/hash-128.d.ts +2 -0
- package/dist/types/hash-128.js +4 -0
- package/dist/types/hash-128.js.map +1 -1
- package/dist/types/hash-160.d.ts +2 -0
- package/dist/types/hash-160.js +4 -0
- package/dist/types/hash-160.js.map +1 -1
- package/dist/types/hash-192.d.ts +2 -0
- package/dist/types/hash-192.js +4 -0
- package/dist/types/hash-192.js.map +1 -1
- package/dist/types/hash-256.d.ts +2 -0
- package/dist/types/hash-256.js +4 -0
- package/dist/types/hash-256.js.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.js +7 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/issue.d.ts +2 -1
- package/dist/types/issue.js +3 -0
- package/dist/types/issue.js.map +1 -1
- package/dist/types/json.d.ts +173 -0
- package/dist/types/json.js +531 -0
- package/dist/types/json.js.map +1 -0
- package/dist/types/path-set.d.ts +2 -1
- package/dist/types/path-set.js +3 -0
- package/dist/types/path-set.js.map +1 -1
- package/dist/types/serialized-type.d.ts +43 -0
- package/dist/types/serialized-type.js +63 -1
- package/dist/types/serialized-type.js.map +1 -1
- package/dist/types/st-array.d.ts +2 -1
- package/dist/types/st-array.js +3 -0
- package/dist/types/st-array.js.map +1 -1
- package/dist/types/st-number.d.ts +2 -1
- package/dist/types/st-number.js +3 -0
- package/dist/types/st-number.js.map +1 -1
- package/dist/types/st-object.d.ts +2 -1
- package/dist/types/st-object.js +9 -1
- package/dist/types/st-object.js.map +1 -1
- package/dist/types/uint-16.d.ts +2 -0
- package/dist/types/uint-16.js +4 -0
- package/dist/types/uint-16.js.map +1 -1
- package/dist/types/uint-32.d.ts +2 -0
- package/dist/types/uint-32.js +4 -0
- package/dist/types/uint-32.js.map +1 -1
- package/dist/types/uint-64.d.ts +2 -0
- package/dist/types/uint-64.js +4 -0
- package/dist/types/uint-64.js.map +1 -1
- package/dist/types/uint-8.d.ts +2 -0
- package/dist/types/uint-8.js +4 -0
- package/dist/types/uint-8.js.map +1 -1
- package/dist/types/vector-256.d.ts +2 -1
- package/dist/types/vector-256.js +3 -0
- package/dist/types/vector-256.js.map +1 -1
- package/dist/types/xchain-bridge.d.ts +2 -1
- package/dist/types/xchain-bridge.js +3 -0
- package/dist/types/xchain-bridge.js.map +1 -1
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/enums/definitions.json +238 -260
- package/src/quality.ts +13 -3
- package/src/serdes/binary-parser.ts +12 -2
- package/src/serdes/binary-serializer.ts +2 -2
- package/src/types/account-id.ts +5 -0
- package/src/types/amount.ts +25 -6
- package/src/types/blob.ts +5 -1
- package/src/types/currency.ts +5 -0
- package/src/types/data.ts +294 -0
- package/src/types/dataType.ts +178 -0
- package/src/types/hash-128.ts +5 -0
- package/src/types/hash-160.ts +5 -0
- package/src/types/hash-192.ts +5 -0
- package/src/types/hash-256.ts +5 -0
- package/src/types/index.ts +6 -0
- package/src/types/issue.ts +5 -1
- package/src/types/json.ts +650 -0
- package/src/types/path-set.ts +5 -1
- package/src/types/serialized-type.ts +67 -0
- package/src/types/st-array.ts +5 -1
- package/src/types/st-number.ts +5 -1
- package/src/types/st-object.ts +12 -2
- package/src/types/uint-16.ts +5 -0
- package/src/types/uint-32.ts +5 -0
- package/src/types/uint-64.ts +6 -1
- package/src/types/uint-8.ts +5 -0
- package/src/types/vector-256.ts +5 -1
- package/src/types/xchain-bridge.ts +5 -1
- package/src/utils.ts +1 -1
package/src/quality.ts
CHANGED
|
@@ -13,8 +13,13 @@ class quality {
|
|
|
13
13
|
* @returns Serialized quality
|
|
14
14
|
*/
|
|
15
15
|
static encode(quality: string): Uint8Array {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
let decimal: BigNumber
|
|
17
|
+
try {
|
|
18
|
+
decimal = new BigNumber(quality)
|
|
19
|
+
} catch (_err) {
|
|
20
|
+
throw new Error(`${quality} is not a valid quality`)
|
|
21
|
+
}
|
|
22
|
+
const exponent = (decimal.e || 0) - 15
|
|
18
23
|
const qualityString = decimal.times(`1e${-exponent}`).abs().toString()
|
|
19
24
|
const bytes = coreTypes.UInt64.from(BigInt(qualityString)).toBytes()
|
|
20
25
|
bytes[0] = exponent + 100
|
|
@@ -30,7 +35,12 @@ class quality {
|
|
|
30
35
|
static decode(quality: string): BigNumber {
|
|
31
36
|
const bytes = hexToBytes(quality).slice(-8)
|
|
32
37
|
const exponent = bytes[0] - 100
|
|
33
|
-
|
|
38
|
+
let mantissa: BigNumber
|
|
39
|
+
try {
|
|
40
|
+
mantissa = new BigNumber(`0x${bytesToHex(bytes.slice(1))}`)
|
|
41
|
+
} catch (_err) {
|
|
42
|
+
throw new Error(`${quality} is not a valid quality`)
|
|
43
|
+
}
|
|
34
44
|
return mantissa.times(`1e${exponent}`)
|
|
35
45
|
}
|
|
36
46
|
}
|
|
@@ -46,8 +46,13 @@ class BinaryParser {
|
|
|
46
46
|
* @param n the number of bytes to skip
|
|
47
47
|
*/
|
|
48
48
|
skip(n: number): void {
|
|
49
|
+
if (n < 0) {
|
|
50
|
+
throw new Error(`skip: negative length ${n}`)
|
|
51
|
+
}
|
|
49
52
|
if (n > this.bytes.byteLength) {
|
|
50
|
-
throw new Error(
|
|
53
|
+
throw new Error(
|
|
54
|
+
`skip: requested ${n} bytes but only ${this.bytes.byteLength} available`,
|
|
55
|
+
)
|
|
51
56
|
}
|
|
52
57
|
this.bytes = this.bytes.slice(n)
|
|
53
58
|
}
|
|
@@ -59,8 +64,13 @@ class BinaryParser {
|
|
|
59
64
|
* @return The bytes
|
|
60
65
|
*/
|
|
61
66
|
read(n: number): Uint8Array {
|
|
67
|
+
if (n < 0) {
|
|
68
|
+
throw new Error(`read: negative length ${n}`)
|
|
69
|
+
}
|
|
62
70
|
if (n > this.bytes.byteLength) {
|
|
63
|
-
throw new Error(
|
|
71
|
+
throw new Error(
|
|
72
|
+
`read: requested ${n} bytes but only ${this.bytes.byteLength} available`,
|
|
73
|
+
)
|
|
64
74
|
}
|
|
65
75
|
|
|
66
76
|
const slice = this.bytes.slice(0, n)
|
|
@@ -99,7 +99,7 @@ class BinarySerializer {
|
|
|
99
99
|
*
|
|
100
100
|
* @param length the length of the bytes
|
|
101
101
|
*/
|
|
102
|
-
|
|
102
|
+
static encodeVariableLength(length: number): Uint8Array {
|
|
103
103
|
const lenBytes = new Uint8Array(3)
|
|
104
104
|
if (length <= 192) {
|
|
105
105
|
lenBytes[0] = length
|
|
@@ -158,7 +158,7 @@ class BinarySerializer {
|
|
|
158
158
|
// this part doesn't happen for the Account field in a UNLModify transaction
|
|
159
159
|
value.toBytesSink(bytes)
|
|
160
160
|
}
|
|
161
|
-
this.put(
|
|
161
|
+
this.put(BinarySerializer.encodeVariableLength(bytes.getLength()))
|
|
162
162
|
this.writeBytesList(bytes)
|
|
163
163
|
}
|
|
164
164
|
}
|
package/src/types/account-id.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from 'ripple-address-codec'
|
|
7
7
|
import { Hash160 } from './hash-160'
|
|
8
8
|
import { hexToBytes } from '@xrplf/isomorphic/utils'
|
|
9
|
+
import { SerializedTypeID } from './serialized-type'
|
|
9
10
|
|
|
10
11
|
const HEX_REGEX = /^[A-F0-9]{40}$/
|
|
11
12
|
|
|
@@ -81,6 +82,10 @@ class AccountID extends Hash160 {
|
|
|
81
82
|
toBase58(): string {
|
|
82
83
|
return encodeAccountID(this.bytes)
|
|
83
84
|
}
|
|
85
|
+
|
|
86
|
+
getSType(): SerializedTypeID {
|
|
87
|
+
return SerializedTypeID.STI_ACCOUNT
|
|
88
|
+
}
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
export { AccountID }
|
package/src/types/amount.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { BinaryParser } from '../serdes/binary-parser'
|
|
|
2
2
|
|
|
3
3
|
import { AccountID } from './account-id'
|
|
4
4
|
import { Currency } from './currency'
|
|
5
|
-
import { JsonObject, SerializedType } from './serialized-type'
|
|
5
|
+
import { JsonObject, SerializedType, SerializedTypeID } from './serialized-type'
|
|
6
6
|
import BigNumber from 'bignumber.js'
|
|
7
7
|
import { bytesToHex, concat, hexToBytes } from '@xrplf/isomorphic/utils'
|
|
8
8
|
import { readUInt32BE, writeUInt32BE } from '../utils'
|
|
@@ -92,7 +92,7 @@ class Amount extends SerializedType {
|
|
|
92
92
|
return value
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
let amount = new Uint8Array(8)
|
|
95
|
+
let amount: Uint8Array = new Uint8Array(8)
|
|
96
96
|
if (typeof value === 'string') {
|
|
97
97
|
Amount.assertXrpIsValid(value)
|
|
98
98
|
|
|
@@ -110,7 +110,12 @@ class Amount extends SerializedType {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
if (isAmountObjectIOU(value)) {
|
|
113
|
-
|
|
113
|
+
let number: BigNumber
|
|
114
|
+
try {
|
|
115
|
+
number = new BigNumber(value.value)
|
|
116
|
+
} catch (_err) {
|
|
117
|
+
throw new Error(`${value.value} is an illegal amount`)
|
|
118
|
+
}
|
|
114
119
|
Amount.assertIouIsValid(number)
|
|
115
120
|
|
|
116
121
|
if (number.isZero()) {
|
|
@@ -189,7 +194,7 @@ class Amount extends SerializedType {
|
|
|
189
194
|
*/
|
|
190
195
|
toJSON(): AmountObject | string {
|
|
191
196
|
if (this.isNative()) {
|
|
192
|
-
const bytes = this.bytes
|
|
197
|
+
const bytes = this.bytes.slice()
|
|
193
198
|
const isPositive = bytes[0] & 0x40
|
|
194
199
|
const sign = isPositive ? '' : '-'
|
|
195
200
|
bytes[0] &= 0x3f
|
|
@@ -261,7 +266,12 @@ class Amount extends SerializedType {
|
|
|
261
266
|
throw new Error(`${amount.toString()} is an illegal amount`)
|
|
262
267
|
}
|
|
263
268
|
|
|
264
|
-
|
|
269
|
+
let decimal: BigNumber
|
|
270
|
+
try {
|
|
271
|
+
decimal = new BigNumber(amount)
|
|
272
|
+
} catch (_err) {
|
|
273
|
+
throw new Error(`${amount.toString()} is an illegal amount`)
|
|
274
|
+
}
|
|
265
275
|
if (!decimal.isZero()) {
|
|
266
276
|
if (decimal.lt(MIN_XRP) || decimal.gt(MAX_DROPS)) {
|
|
267
277
|
throw new Error(`${amount.toString()} is an illegal amount`)
|
|
@@ -301,7 +311,12 @@ class Amount extends SerializedType {
|
|
|
301
311
|
throw new Error(`${amount.toString()} is an illegal amount`)
|
|
302
312
|
}
|
|
303
313
|
|
|
304
|
-
|
|
314
|
+
let decimal: BigNumber
|
|
315
|
+
try {
|
|
316
|
+
decimal = new BigNumber(amount)
|
|
317
|
+
} catch (_err) {
|
|
318
|
+
throw new Error(`${amount.toString()} is an illegal amount`)
|
|
319
|
+
}
|
|
305
320
|
if (!decimal.isZero()) {
|
|
306
321
|
if (decimal < BigNumber(0)) {
|
|
307
322
|
throw new Error(`${amount.toString()} is an illegal amount`)
|
|
@@ -357,6 +372,10 @@ class Amount extends SerializedType {
|
|
|
357
372
|
private isIOU(): boolean {
|
|
358
373
|
return (this.bytes[0] & 0x80) !== 0
|
|
359
374
|
}
|
|
375
|
+
|
|
376
|
+
getSType(): SerializedTypeID {
|
|
377
|
+
return SerializedTypeID.STI_AMOUNT
|
|
378
|
+
}
|
|
360
379
|
}
|
|
361
380
|
|
|
362
381
|
export { Amount, AmountObject }
|
package/src/types/blob.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SerializedType } from './serialized-type'
|
|
1
|
+
import { SerializedType, SerializedTypeID } from './serialized-type'
|
|
2
2
|
import { BinaryParser } from '../serdes/binary-parser'
|
|
3
3
|
import { hexToBytes } from '@xrplf/isomorphic/utils'
|
|
4
4
|
|
|
@@ -41,6 +41,10 @@ class Blob extends SerializedType {
|
|
|
41
41
|
|
|
42
42
|
throw new Error('Cannot construct Blob from value given')
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
getSType(): SerializedTypeID {
|
|
46
|
+
return SerializedTypeID.STI_VL
|
|
47
|
+
}
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
export { Blob }
|
package/src/types/currency.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Hash160 } from './hash-160'
|
|
2
2
|
import { bytesToHex, hexToBytes, hexToString } from '@xrplf/isomorphic/utils'
|
|
3
|
+
import { SerializedTypeID } from './serialized-type'
|
|
3
4
|
|
|
4
5
|
const XRP_HEX_REGEX = /^0{40}$/
|
|
5
6
|
const ISO_REGEX = /^[A-Z0-9a-z?!@#$%^&*(){}[\]|]{3}$/
|
|
@@ -135,6 +136,10 @@ class Currency extends Hash160 {
|
|
|
135
136
|
}
|
|
136
137
|
return bytesToHex(this.bytes)
|
|
137
138
|
}
|
|
139
|
+
|
|
140
|
+
getSType(): SerializedTypeID {
|
|
141
|
+
return SerializedTypeID.STI_CURRENCY
|
|
142
|
+
}
|
|
138
143
|
}
|
|
139
144
|
|
|
140
145
|
export { Currency }
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { BinaryParser } from '../serdes/binary-parser'
|
|
2
|
+
import {
|
|
3
|
+
JsonObject,
|
|
4
|
+
SerializedType,
|
|
5
|
+
SerializedTypeID,
|
|
6
|
+
TYPE_ID_TO_STRING,
|
|
7
|
+
TYPE_STRING_TO_ID,
|
|
8
|
+
TYPE_NUMBER_TO_ID,
|
|
9
|
+
} from './serialized-type'
|
|
10
|
+
import { readUInt16BE, writeUInt16BE } from '../utils'
|
|
11
|
+
import { bytesToHex, concat } from '@xrplf/isomorphic/utils'
|
|
12
|
+
import { Hash128 } from './hash-128'
|
|
13
|
+
import { Hash160 } from './hash-160'
|
|
14
|
+
import { Hash192 } from './hash-192'
|
|
15
|
+
import { Hash256 } from './hash-256'
|
|
16
|
+
import { AccountID } from './account-id'
|
|
17
|
+
import { Amount } from './amount'
|
|
18
|
+
import { Blob } from './blob'
|
|
19
|
+
import { Currency } from './currency'
|
|
20
|
+
import { STNumber } from './st-number'
|
|
21
|
+
import { Issue } from './issue'
|
|
22
|
+
import { UInt8 } from './uint-8'
|
|
23
|
+
import { UInt16 } from './uint-16'
|
|
24
|
+
import { UInt32 } from './uint-32'
|
|
25
|
+
import { UInt64 } from './uint-64'
|
|
26
|
+
import { BinarySerializer } from '../binary'
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Interface for Data JSON representation
|
|
30
|
+
*/
|
|
31
|
+
interface DataJSON extends JsonObject {
|
|
32
|
+
type: string
|
|
33
|
+
value: string | number | JsonObject
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Map from SerializedTypeID to the corresponding type class.
|
|
38
|
+
* Types listed here use standard from()/fromParser()/toBytes() without
|
|
39
|
+
* any extra framing (unlike VL and Account which need length prefixes).
|
|
40
|
+
*/
|
|
41
|
+
const SIMPLE_TYPE_MAP: Partial<
|
|
42
|
+
Record<SerializedTypeID, typeof SerializedType>
|
|
43
|
+
> = {
|
|
44
|
+
[SerializedTypeID.STI_UINT8]: UInt8,
|
|
45
|
+
[SerializedTypeID.STI_UINT16]: UInt16,
|
|
46
|
+
[SerializedTypeID.STI_UINT32]: UInt32,
|
|
47
|
+
[SerializedTypeID.STI_UINT64]: UInt64,
|
|
48
|
+
[SerializedTypeID.STI_UINT128]: Hash128,
|
|
49
|
+
[SerializedTypeID.STI_UINT160]: Hash160,
|
|
50
|
+
[SerializedTypeID.STI_UINT192]: Hash192,
|
|
51
|
+
[SerializedTypeID.STI_UINT256]: Hash256,
|
|
52
|
+
[SerializedTypeID.STI_AMOUNT]: Amount,
|
|
53
|
+
[SerializedTypeID.STI_ISSUE]: Issue,
|
|
54
|
+
[SerializedTypeID.STI_CURRENCY]: Currency,
|
|
55
|
+
[SerializedTypeID.STI_NUMBER]: STNumber,
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Types whose from() method expects a numeric argument.
|
|
60
|
+
* For these, json.value is coerced to a number before calling from().
|
|
61
|
+
*/
|
|
62
|
+
const NUMERIC_TYPES = new Set<SerializedTypeID>([
|
|
63
|
+
SerializedTypeID.STI_UINT8,
|
|
64
|
+
SerializedTypeID.STI_UINT16,
|
|
65
|
+
SerializedTypeID.STI_UINT32,
|
|
66
|
+
])
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* STData: Encodes XRPL's "Data" type.
|
|
70
|
+
*
|
|
71
|
+
* This type wraps both a SerializedTypeID and the actual data value.
|
|
72
|
+
* It's encoded as a 2-byte type ID followed by the serialized data.
|
|
73
|
+
*
|
|
74
|
+
* Usage:
|
|
75
|
+
* Data.from({ type: "Amount", value: "1000000" })
|
|
76
|
+
* Data.from({ type: "UInt64", value: "123456789" })
|
|
77
|
+
* Data.fromParser(parser)
|
|
78
|
+
*/
|
|
79
|
+
class Data extends SerializedType {
|
|
80
|
+
static readonly ZERO_DATA: Data = new Data(
|
|
81
|
+
concat([
|
|
82
|
+
new Uint8Array([0x00, 0x01]), // Type ID for UINT16 (SerializedTypeID.STI_UINT16 = 1) as uint16
|
|
83
|
+
new Uint8Array([0x00, 0x00]), // Value: two zero bytes for UINT16
|
|
84
|
+
]),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Construct Data from bytes
|
|
89
|
+
* @param bytes - Uint8Array containing type ID and data
|
|
90
|
+
*/
|
|
91
|
+
constructor(bytes: Uint8Array) {
|
|
92
|
+
super(bytes ?? Data.ZERO_DATA.bytes)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Create Data from various input types
|
|
97
|
+
*
|
|
98
|
+
* @param value - Can be:
|
|
99
|
+
* - Data instance (returns as-is)
|
|
100
|
+
* - DataJSON object with 'type' and 'value' fields
|
|
101
|
+
* @returns Data instance
|
|
102
|
+
* @throws Error if value type is not supported
|
|
103
|
+
*/
|
|
104
|
+
static from(value: unknown): Data {
|
|
105
|
+
if (value instanceof Data) {
|
|
106
|
+
return value
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (
|
|
110
|
+
typeof value === 'object' &&
|
|
111
|
+
value !== null &&
|
|
112
|
+
'type' in value &&
|
|
113
|
+
'value' in value
|
|
114
|
+
) {
|
|
115
|
+
const json = value as DataJSON
|
|
116
|
+
return Data.fromJSON(json)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
throw new Error('Data.from: value must be Data instance or DataJSON object')
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Create Data from JSON representation
|
|
124
|
+
*
|
|
125
|
+
* @param json - Object with 'type' and 'value' fields
|
|
126
|
+
* @returns Data instance
|
|
127
|
+
* @throws Error if type is not supported
|
|
128
|
+
*/
|
|
129
|
+
static fromJSON(json: DataJSON): Data {
|
|
130
|
+
const typeId = TYPE_STRING_TO_ID[json.type]
|
|
131
|
+
if (typeId === undefined) {
|
|
132
|
+
throw new Error(`Data: unsupported type string: ${json.type}`)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let dataBytes: Uint8Array
|
|
136
|
+
|
|
137
|
+
const TypeClass = SIMPLE_TYPE_MAP[typeId]
|
|
138
|
+
if (TypeClass) {
|
|
139
|
+
// For UInt8/16/32, coerce value to number; all others pass through
|
|
140
|
+
const coercedValue = NUMERIC_TYPES.has(typeId)
|
|
141
|
+
? typeof json.value === 'string'
|
|
142
|
+
? parseInt(json.value, 10)
|
|
143
|
+
: Number(json.value)
|
|
144
|
+
: json.value
|
|
145
|
+
dataBytes = TypeClass.from(coercedValue).toBytes()
|
|
146
|
+
} else if (typeId === SerializedTypeID.STI_VL) {
|
|
147
|
+
const val =
|
|
148
|
+
typeof json.value === 'string' ? json.value : json.value.toString()
|
|
149
|
+
dataBytes = Blob.from(val).toBytes()
|
|
150
|
+
dataBytes = concat([
|
|
151
|
+
BinarySerializer.encodeVariableLength(dataBytes.length),
|
|
152
|
+
dataBytes,
|
|
153
|
+
])
|
|
154
|
+
} else if (typeId === SerializedTypeID.STI_ACCOUNT) {
|
|
155
|
+
const val =
|
|
156
|
+
typeof json.value === 'string' ? json.value : json.value.toString()
|
|
157
|
+
dataBytes = concat([
|
|
158
|
+
new Uint8Array([0x14]),
|
|
159
|
+
AccountID.from(val).toBytes(),
|
|
160
|
+
])
|
|
161
|
+
} else {
|
|
162
|
+
throw new Error(`Data.fromJSON(): unsupported type ID: ${typeId}`)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Combine type header with data bytes
|
|
166
|
+
const typeBytes = new Uint8Array(2)
|
|
167
|
+
writeUInt16BE(typeBytes, typeId, 0)
|
|
168
|
+
return new Data(concat([typeBytes, dataBytes]))
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Read Data from a BinaryParser stream
|
|
173
|
+
*
|
|
174
|
+
* @param parser - BinaryParser positioned at the start of Data
|
|
175
|
+
* @returns Data instance
|
|
176
|
+
*/
|
|
177
|
+
static fromParser(parser: BinaryParser): Data {
|
|
178
|
+
// Read the 2-byte type ID
|
|
179
|
+
const typeBytes = parser.read(2)
|
|
180
|
+
const typeId = TYPE_NUMBER_TO_ID[readUInt16BE(typeBytes, 0)]
|
|
181
|
+
|
|
182
|
+
let dataBytes: Uint8Array
|
|
183
|
+
|
|
184
|
+
const TypeClass = SIMPLE_TYPE_MAP[typeId]
|
|
185
|
+
if (TypeClass) {
|
|
186
|
+
dataBytes = TypeClass.fromParser(parser).toBytes()
|
|
187
|
+
} else if (typeId === SerializedTypeID.STI_VL) {
|
|
188
|
+
const valueVL = parser.readVariableLength()
|
|
189
|
+
dataBytes = concat([
|
|
190
|
+
BinarySerializer.encodeVariableLength(valueVL.length),
|
|
191
|
+
valueVL,
|
|
192
|
+
])
|
|
193
|
+
} else if (typeId === SerializedTypeID.STI_ACCOUNT) {
|
|
194
|
+
parser.skip(1)
|
|
195
|
+
dataBytes = concat([
|
|
196
|
+
new Uint8Array([0x14]),
|
|
197
|
+
AccountID.fromParser(parser).toBytes(),
|
|
198
|
+
])
|
|
199
|
+
} else {
|
|
200
|
+
throw new Error(`Data: unsupported type ID when parsing: ${typeId}`)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return new Data(concat([typeBytes, dataBytes]))
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Get the inner SerializedTypeID
|
|
208
|
+
*
|
|
209
|
+
* @returns The inner type ID
|
|
210
|
+
*/
|
|
211
|
+
getInnerType(): SerializedTypeID {
|
|
212
|
+
return TYPE_NUMBER_TO_ID[readUInt16BE(this.bytes, 0)]
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Get the string representation of the inner type
|
|
217
|
+
*
|
|
218
|
+
* @returns String name of the type
|
|
219
|
+
*/
|
|
220
|
+
getInnerTypeString(): string {
|
|
221
|
+
const innerType = this.getInnerType()
|
|
222
|
+
return TYPE_ID_TO_STRING[innerType] || innerType.toString()
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Get the data value
|
|
227
|
+
*
|
|
228
|
+
* @returns The stored data value
|
|
229
|
+
*/
|
|
230
|
+
getValue(): SerializedType {
|
|
231
|
+
const innerType = this.getInnerType()
|
|
232
|
+
const parser = new BinaryParser(bytesToHex(this.bytes.slice(2)))
|
|
233
|
+
|
|
234
|
+
const TypeClass = SIMPLE_TYPE_MAP[innerType]
|
|
235
|
+
if (TypeClass) {
|
|
236
|
+
return TypeClass.fromParser(parser)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (innerType === SerializedTypeID.STI_VL) {
|
|
240
|
+
const vlLength = parser.readVariableLengthLength()
|
|
241
|
+
return Blob.fromParser(parser, vlLength)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (innerType === SerializedTypeID.STI_ACCOUNT) {
|
|
245
|
+
parser.skip(1)
|
|
246
|
+
return AccountID.fromParser(parser)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
throw new Error(`Data.getValue(): unsupported type ID: ${typeof innerType}`)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Convert to JSON representation
|
|
254
|
+
*
|
|
255
|
+
* @returns JSON object with 'type' and 'value' fields
|
|
256
|
+
*/
|
|
257
|
+
toJSON(): DataJSON {
|
|
258
|
+
return {
|
|
259
|
+
type: this.getInnerTypeString(),
|
|
260
|
+
value: this.getValue().toJSON() as string | number | JsonObject,
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Compare with another Data for equality
|
|
266
|
+
*
|
|
267
|
+
* @param other - Another Data to compare with
|
|
268
|
+
* @returns true if both have the same inner type and data
|
|
269
|
+
*/
|
|
270
|
+
equals(other: Data): boolean {
|
|
271
|
+
if (!(other instanceof Data)) {
|
|
272
|
+
return false
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Compare bytes directly
|
|
276
|
+
if (this.bytes.length !== other.bytes.length) {
|
|
277
|
+
return false
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
for (let i = 0; i < this.bytes.length; i++) {
|
|
281
|
+
if (this.bytes[i] !== other.bytes[i]) {
|
|
282
|
+
return false
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return true
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
getSType(): SerializedTypeID {
|
|
290
|
+
return SerializedTypeID.STI_DATA
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export { Data }
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { BinaryParser } from '../serdes/binary-parser'
|
|
2
|
+
import {
|
|
3
|
+
JsonObject,
|
|
4
|
+
SerializedType,
|
|
5
|
+
SerializedTypeID,
|
|
6
|
+
TYPE_ID_TO_STRING,
|
|
7
|
+
TYPE_STRING_TO_ID,
|
|
8
|
+
} from './serialized-type'
|
|
9
|
+
import { readUInt16BE, writeUInt16BE } from '../utils'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Interface for DataType JSON representation
|
|
13
|
+
*/
|
|
14
|
+
interface DataTypeJSON extends JsonObject {
|
|
15
|
+
type: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* STDataType: Encodes XRPL's "DataType" type.
|
|
20
|
+
*
|
|
21
|
+
* This type wraps an inner SerializedTypeID to indicate what type of data
|
|
22
|
+
* a field contains. It's encoded as a 2-byte unsigned integer representing
|
|
23
|
+
* the inner type.
|
|
24
|
+
*
|
|
25
|
+
* Usage:
|
|
26
|
+
* DataType.from({ type: "Amount" })
|
|
27
|
+
* DataType.from("UInt64")
|
|
28
|
+
* DataType.fromParser(parser)
|
|
29
|
+
*/
|
|
30
|
+
class DataType extends SerializedType {
|
|
31
|
+
private innerType: SerializedTypeID
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Default bytes for DataType (STI_NOTPRESENT)
|
|
35
|
+
*/
|
|
36
|
+
static readonly defaultBytes = new Uint8Array([0x00, 0x01])
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Construct a DataType from bytes
|
|
40
|
+
* @param bytes - 2-byte Uint8Array containing the inner type ID
|
|
41
|
+
* @param innerType - Optional explicit inner type (used when constructing from value)
|
|
42
|
+
* @throws Error if bytes is not a 2-byte Uint8Array
|
|
43
|
+
*/
|
|
44
|
+
constructor(bytes?: Uint8Array, innerType?: SerializedTypeID) {
|
|
45
|
+
const used = bytes ?? DataType.defaultBytes
|
|
46
|
+
if (!(used instanceof Uint8Array) || used.length !== 2) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`DataType must be constructed from a 2-byte Uint8Array, got ${used?.length} bytes`,
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
super(used)
|
|
52
|
+
|
|
53
|
+
// If innerType is explicitly provided, use it; otherwise read from bytes
|
|
54
|
+
if (innerType !== undefined) {
|
|
55
|
+
this.innerType = innerType
|
|
56
|
+
} else {
|
|
57
|
+
this.innerType = readUInt16BE(used, 0) as unknown as SerializedTypeID
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Construct from various input types
|
|
63
|
+
*
|
|
64
|
+
* @param value - Can be:
|
|
65
|
+
* - DataType instance (returns as-is)
|
|
66
|
+
* - DataTypeJSON object with 'type' field
|
|
67
|
+
* - String type name (e.g., "Amount", "UInt64")
|
|
68
|
+
* - SerializedTypeID enum value
|
|
69
|
+
* @returns DataType instance
|
|
70
|
+
* @throws Error if value type is not supported or type string is unknown
|
|
71
|
+
*/
|
|
72
|
+
static from(value: unknown): DataType {
|
|
73
|
+
if (value instanceof DataType) {
|
|
74
|
+
return value
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (typeof value === 'object' && value !== null && 'type' in value) {
|
|
78
|
+
const json = value as DataTypeJSON
|
|
79
|
+
return DataType.fromTypeString(json.type)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (typeof value === 'string') {
|
|
83
|
+
return DataType.fromTypeString(value)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (typeof value === 'number') {
|
|
87
|
+
return DataType.fromTypeId(value as SerializedTypeID)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
throw new Error(
|
|
91
|
+
'DataType.from: value must be DataType, DataTypeJSON, string, or SerializedTypeID',
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Construct from a type string
|
|
97
|
+
*
|
|
98
|
+
* @param typeStr - Type string like "Amount", "UInt64", etc.
|
|
99
|
+
* @returns DataType instance
|
|
100
|
+
* @throws Error if type string is not recognized
|
|
101
|
+
*/
|
|
102
|
+
static fromTypeString(typeStr: string): DataType {
|
|
103
|
+
const typeId = TYPE_STRING_TO_ID[typeStr]
|
|
104
|
+
if (typeId === undefined) {
|
|
105
|
+
throw new Error(`DataType: unsupported type string: ${typeStr}`)
|
|
106
|
+
}
|
|
107
|
+
return DataType.fromTypeId(typeId)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Construct from a SerializedTypeID
|
|
112
|
+
*
|
|
113
|
+
* @param typeId - The SerializedTypeID enum value
|
|
114
|
+
* @returns DataType instance
|
|
115
|
+
*/
|
|
116
|
+
static fromTypeId(typeId: SerializedTypeID): DataType {
|
|
117
|
+
const bytes = new Uint8Array(2)
|
|
118
|
+
writeUInt16BE(bytes, typeId, 0)
|
|
119
|
+
return new DataType(bytes, typeId)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Read a DataType from a BinaryParser stream (2 bytes)
|
|
124
|
+
*
|
|
125
|
+
* @param parser - BinaryParser positioned at the start of a DataType
|
|
126
|
+
* @returns DataType instance
|
|
127
|
+
*/
|
|
128
|
+
static fromParser(parser: BinaryParser): DataType {
|
|
129
|
+
const bytes = parser.read(2)
|
|
130
|
+
return new DataType(bytes)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Get the inner SerializedTypeID
|
|
135
|
+
*
|
|
136
|
+
* @returns The inner type ID
|
|
137
|
+
*/
|
|
138
|
+
getInnerType(): SerializedTypeID {
|
|
139
|
+
return this.innerType
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Set the inner SerializedTypeID
|
|
144
|
+
*
|
|
145
|
+
* @param typeId - The new inner type ID
|
|
146
|
+
*/
|
|
147
|
+
setInnerType(typeId: SerializedTypeID): void {
|
|
148
|
+
this.innerType = typeId
|
|
149
|
+
writeUInt16BE(this.bytes, typeId, 0)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Get the string representation of the inner type
|
|
154
|
+
*
|
|
155
|
+
* @returns String name of the type, or numeric string if unknown
|
|
156
|
+
*/
|
|
157
|
+
getInnerTypeString(): string {
|
|
158
|
+
return TYPE_ID_TO_STRING[this.innerType] || this.innerType.toString()
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Convert to JSON representation
|
|
163
|
+
*
|
|
164
|
+
* @returns JSON object with 'type' field
|
|
165
|
+
*/
|
|
166
|
+
toJSON(): DataTypeJSON {
|
|
167
|
+
return {
|
|
168
|
+
type: this.getInnerTypeString(),
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
getSType(): SerializedTypeID {
|
|
173
|
+
return SerializedTypeID.STI_DATATYPE
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Export the DataType class for external use
|
|
178
|
+
export { DataType }
|
package/src/types/hash-128.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Hash } from './hash'
|
|
2
2
|
import { bytesToHex } from '@xrplf/isomorphic/utils'
|
|
3
|
+
import { SerializedTypeID } from './serialized-type'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Hash with a width of 128 bits
|
|
@@ -28,6 +29,10 @@ class Hash128 extends Hash {
|
|
|
28
29
|
}
|
|
29
30
|
return hex
|
|
30
31
|
}
|
|
32
|
+
|
|
33
|
+
getSType(): SerializedTypeID {
|
|
34
|
+
return SerializedTypeID.STI_UINT128
|
|
35
|
+
}
|
|
31
36
|
}
|
|
32
37
|
|
|
33
38
|
export { Hash128 }
|