ripple-binary-codec 1.7.1 → 1.9.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.
Files changed (99) hide show
  1. package/dist/enums/definitions.json +250 -1
  2. package/dist/enums/src/enums/definitions.json +250 -1
  3. package/dist/types/index.js +2 -0
  4. package/dist/types/index.js.map +1 -1
  5. package/dist/types/issue.d.ts +39 -0
  6. package/dist/types/issue.js +81 -0
  7. package/dist/types/issue.js.map +1 -0
  8. package/dist/types/xchain-bridge.d.ts +45 -0
  9. package/dist/types/xchain-bridge.js +102 -0
  10. package/dist/types/xchain-bridge.js.map +1 -0
  11. package/package.json +3 -4
  12. package/src/README.md +3 -0
  13. package/src/binary.ts +188 -0
  14. package/src/coretypes.ts +31 -0
  15. package/src/enums/README.md +144 -0
  16. package/src/enums/bytes.ts +75 -0
  17. package/src/enums/constants.ts +4 -0
  18. package/src/enums/definitions.json +2599 -0
  19. package/src/enums/field.ts +85 -0
  20. package/src/enums/index.ts +34 -0
  21. package/src/enums/utils-renumber.ts +134 -0
  22. package/src/enums/xrpl-definitions-base.ts +111 -0
  23. package/src/enums/xrpl-definitions.ts +32 -0
  24. package/src/hash-prefixes.ts +40 -0
  25. package/src/hashes.ts +76 -0
  26. package/src/index.ts +141 -0
  27. package/src/ledger-hashes.ts +187 -0
  28. package/src/quality.ts +39 -0
  29. package/src/serdes/binary-parser.ts +217 -0
  30. package/src/serdes/binary-serializer.ts +166 -0
  31. package/src/shamap.ts +186 -0
  32. package/src/types/account-id.ts +86 -0
  33. package/src/types/amount.ts +256 -0
  34. package/src/types/blob.ts +43 -0
  35. package/src/types/currency.ts +140 -0
  36. package/src/types/hash-128.ts +33 -0
  37. package/src/types/hash-160.ts +20 -0
  38. package/src/types/hash-256.ts +16 -0
  39. package/src/types/hash.ts +81 -0
  40. package/src/types/index.ts +61 -0
  41. package/src/types/issue.ts +96 -0
  42. package/src/types/path-set.ts +290 -0
  43. package/src/types/serialized-type.ts +120 -0
  44. package/src/types/st-array.ts +107 -0
  45. package/src/types/st-object.ts +192 -0
  46. package/src/types/uint-16.ts +49 -0
  47. package/src/types/uint-32.ts +56 -0
  48. package/src/types/uint-64.ts +105 -0
  49. package/src/types/uint-8.ts +49 -0
  50. package/src/types/uint.ts +57 -0
  51. package/src/types/vector-256.ts +84 -0
  52. package/test/amount.test.js +0 -43
  53. package/test/binary-json.test.js +0 -45
  54. package/test/binary-parser.test.js +0 -396
  55. package/test/binary-serializer.test.js +0 -289
  56. package/test/definitions.test.js +0 -160
  57. package/test/fixtures/account-tx-transactions.db +0 -0
  58. package/test/fixtures/codec-fixtures.json +0 -4466
  59. package/test/fixtures/data-driven-tests.json +0 -2919
  60. package/test/fixtures/delivermin-tx-binary.json +0 -1
  61. package/test/fixtures/delivermin-tx.json +0 -98
  62. package/test/fixtures/deposit-preauth-tx-binary.json +0 -1
  63. package/test/fixtures/deposit-preauth-tx-meta-binary.json +0 -1
  64. package/test/fixtures/deposit-preauth-tx.json +0 -58
  65. package/test/fixtures/escrow-cancel-binary.json +0 -1
  66. package/test/fixtures/escrow-cancel-tx.json +0 -6
  67. package/test/fixtures/escrow-create-binary.json +0 -1
  68. package/test/fixtures/escrow-create-tx.json +0 -10
  69. package/test/fixtures/escrow-finish-binary.json +0 -1
  70. package/test/fixtures/escrow-finish-meta-binary.json +0 -1
  71. package/test/fixtures/escrow-finish-tx.json +0 -95
  72. package/test/fixtures/ledger-full-38129.json +0 -1
  73. package/test/fixtures/ledger-full-40000.json +0 -1
  74. package/test/fixtures/negative-unl.json +0 -12
  75. package/test/fixtures/nf-token.json +0 -547
  76. package/test/fixtures/payment-channel-claim-binary.json +0 -1
  77. package/test/fixtures/payment-channel-claim-tx.json +0 -8
  78. package/test/fixtures/payment-channel-create-binary.json +0 -1
  79. package/test/fixtures/payment-channel-create-tx.json +0 -11
  80. package/test/fixtures/payment-channel-fund-binary.json +0 -1
  81. package/test/fixtures/payment-channel-fund-tx.json +0 -7
  82. package/test/fixtures/signerlistset-tx-binary.json +0 -1
  83. package/test/fixtures/signerlistset-tx-meta-binary.json +0 -1
  84. package/test/fixtures/signerlistset-tx.json +0 -94
  85. package/test/fixtures/ticket-create-binary.json +0 -1
  86. package/test/fixtures/ticket-create-tx.json +0 -7
  87. package/test/fixtures/x-codec-fixtures.json +0 -188
  88. package/test/hash.test.js +0 -135
  89. package/test/ledger.test.js +0 -29
  90. package/test/lower-case-hex.test.js +0 -46
  91. package/test/pseudo-transaction.test.js +0 -38
  92. package/test/quality.test.js +0 -15
  93. package/test/shamap.test.js +0 -89
  94. package/test/signing-data-encoding.test.js +0 -242
  95. package/test/tx-encode-decode.test.js +0 -119
  96. package/test/types.test.js +0 -34
  97. package/test/uint.test.js +0 -148
  98. package/test/utils.js +0 -30
  99. package/test/x-address.test.js +0 -181
@@ -0,0 +1,33 @@
1
+ import { Hash } from './hash'
2
+ import { Buffer } from 'buffer/'
3
+
4
+ /**
5
+ * Hash with a width of 128 bits
6
+ */
7
+ class Hash128 extends Hash {
8
+ static readonly width = 16
9
+ static readonly ZERO_128: Hash128 = new Hash128(Buffer.alloc(Hash128.width))
10
+
11
+ constructor(bytes: Buffer) {
12
+ if (bytes && bytes.byteLength === 0) {
13
+ bytes = Hash128.ZERO_128.bytes
14
+ }
15
+
16
+ super(bytes ?? Hash128.ZERO_128.bytes)
17
+ }
18
+
19
+ /**
20
+ * Get the hex representation of a hash-128 bytes, allowing unset
21
+ *
22
+ * @returns hex String of this.bytes
23
+ */
24
+ toHex(): string {
25
+ const hex = this.toBytes().toString('hex').toUpperCase()
26
+ if (/^0+$/.exec(hex)) {
27
+ return ''
28
+ }
29
+ return hex
30
+ }
31
+ }
32
+
33
+ export { Hash128 }
@@ -0,0 +1,20 @@
1
+ import { Hash } from './hash'
2
+ import { Buffer } from 'buffer/'
3
+
4
+ /**
5
+ * Hash with a width of 160 bits
6
+ */
7
+ class Hash160 extends Hash {
8
+ static readonly width = 20
9
+ static readonly ZERO_160: Hash160 = new Hash160(Buffer.alloc(Hash160.width))
10
+
11
+ constructor(bytes?: Buffer) {
12
+ if (bytes && bytes.byteLength === 0) {
13
+ bytes = Hash160.ZERO_160.bytes
14
+ }
15
+
16
+ super(bytes ?? Hash160.ZERO_160.bytes)
17
+ }
18
+ }
19
+
20
+ export { Hash160 }
@@ -0,0 +1,16 @@
1
+ import { Hash } from './hash'
2
+ import { Buffer } from 'buffer/'
3
+
4
+ /**
5
+ * Hash with a width of 256 bits
6
+ */
7
+ class Hash256 extends Hash {
8
+ static readonly width = 32
9
+ static readonly ZERO_256 = new Hash256(Buffer.alloc(Hash256.width))
10
+
11
+ constructor(bytes: Buffer) {
12
+ super(bytes ?? Hash256.ZERO_256.bytes)
13
+ }
14
+ }
15
+
16
+ export { Hash256 }
@@ -0,0 +1,81 @@
1
+ import { Comparable } from './serialized-type'
2
+ import { BinaryParser } from '../serdes/binary-parser'
3
+ import { Buffer } from 'buffer/'
4
+
5
+ /**
6
+ * Base class defining how to encode and decode hashes
7
+ */
8
+ class Hash extends Comparable {
9
+ static readonly width: number
10
+
11
+ constructor(bytes: Buffer) {
12
+ super(bytes)
13
+ if (this.bytes.byteLength !== (this.constructor as typeof Hash).width) {
14
+ throw new Error(`Invalid Hash length ${this.bytes.byteLength}`)
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Construct a Hash object from an existing Hash object or a hex-string
20
+ *
21
+ * @param value A hash object or hex-string of a hash
22
+ */
23
+ static from<T extends Hash | string>(value: T): Hash {
24
+ if (value instanceof this) {
25
+ return value
26
+ }
27
+
28
+ if (typeof value === 'string') {
29
+ return new this(Buffer.from(value, 'hex'))
30
+ }
31
+
32
+ throw new Error('Cannot construct Hash from given value')
33
+ }
34
+
35
+ /**
36
+ * Read a Hash object from a BinaryParser
37
+ *
38
+ * @param parser BinaryParser to read the hash from
39
+ * @param hint length of the bytes to read, optional
40
+ */
41
+ static fromParser(parser: BinaryParser, hint?: number): Hash {
42
+ return new this(parser.read(hint ?? this.width))
43
+ }
44
+
45
+ /**
46
+ * Overloaded operator for comparing two hash objects
47
+ *
48
+ * @param other The Hash to compare this to
49
+ */
50
+ compareTo(other: Hash): number {
51
+ return this.bytes.compare(
52
+ (this.constructor as typeof Hash).from(other).bytes,
53
+ )
54
+ }
55
+
56
+ /**
57
+ * @returns the hex-string representation of this Hash
58
+ */
59
+ toString(): string {
60
+ return this.toHex()
61
+ }
62
+
63
+ /**
64
+ * Returns four bits at the specified depth within a hash
65
+ *
66
+ * @param depth The depth of the four bits
67
+ * @returns The number represented by the four bits
68
+ */
69
+ nibblet(depth: number): number {
70
+ const byteIx = depth > 0 ? (depth / 2) | 0 : 0
71
+ let b = this.bytes[byteIx]
72
+ if (depth % 2 === 0) {
73
+ b = (b & 0xf0) >>> 4
74
+ } else {
75
+ b = b & 0x0f
76
+ }
77
+ return b
78
+ }
79
+ }
80
+
81
+ export { Hash }
@@ -0,0 +1,61 @@
1
+ import { AccountID } from './account-id'
2
+ import { Amount } from './amount'
3
+ import { Blob } from './blob'
4
+ import { Currency } from './currency'
5
+ import { Hash128 } from './hash-128'
6
+ import { Hash160 } from './hash-160'
7
+ import { Hash256 } from './hash-256'
8
+ import { Issue } from './issue'
9
+ import { PathSet } from './path-set'
10
+ import { STArray } from './st-array'
11
+ import { STObject } from './st-object'
12
+ import { UInt16 } from './uint-16'
13
+ import { UInt32 } from './uint-32'
14
+ import { UInt64 } from './uint-64'
15
+ import { UInt8 } from './uint-8'
16
+ import { Vector256 } from './vector-256'
17
+ import { type SerializedType } from './serialized-type'
18
+ import { DEFAULT_DEFINITIONS } from '../enums'
19
+
20
+ const coreTypes: Record<string, typeof SerializedType> = {
21
+ AccountID,
22
+ Amount,
23
+ Blob,
24
+ Currency,
25
+ Hash128,
26
+ Hash160,
27
+ Hash256,
28
+ Issue,
29
+ PathSet,
30
+ STArray,
31
+ STObject,
32
+ UInt8,
33
+ UInt16,
34
+ UInt32,
35
+ UInt64,
36
+ Vector256,
37
+ }
38
+
39
+ // Ensures that the DEFAULT_DEFINITIONS object connects these types to fields for serializing/deserializing
40
+ // This is done here instead of in enums/index.ts to avoid a circular dependency
41
+ // because some of the above types depend on BinarySerializer which depends on enums/index.ts.
42
+ DEFAULT_DEFINITIONS.associateTypes(coreTypes)
43
+
44
+ export {
45
+ coreTypes,
46
+ AccountID,
47
+ Amount,
48
+ Blob,
49
+ Currency,
50
+ Hash128,
51
+ Hash160,
52
+ Hash256,
53
+ PathSet,
54
+ STArray,
55
+ STObject,
56
+ UInt8,
57
+ UInt16,
58
+ UInt32,
59
+ UInt64,
60
+ Vector256,
61
+ }
@@ -0,0 +1,96 @@
1
+ import { BinaryParser } from '../serdes/binary-parser'
2
+
3
+ import { AccountID } from './account-id'
4
+ import { Currency } from './currency'
5
+ import { JsonObject, SerializedType } from './serialized-type'
6
+ import { Buffer } from 'buffer/'
7
+
8
+ /**
9
+ * Interface for JSON objects that represent amounts
10
+ */
11
+ interface IssueObject extends JsonObject {
12
+ currency: string
13
+ issuer?: string
14
+ }
15
+
16
+ /**
17
+ * Type guard for AmountObject
18
+ */
19
+ function isIssueObject(arg): arg is IssueObject {
20
+ const keys = Object.keys(arg).sort()
21
+ if (keys.length === 1) {
22
+ return keys[0] === 'currency'
23
+ }
24
+ return keys.length === 2 && keys[0] === 'currency' && keys[1] === 'issuer'
25
+ }
26
+
27
+ /**
28
+ * Class for serializing/Deserializing Amounts
29
+ */
30
+ class Issue extends SerializedType {
31
+ static readonly ZERO_ISSUED_CURRENCY: Issue = new Issue(Buffer.alloc(20))
32
+
33
+ constructor(bytes: Buffer) {
34
+ super(bytes ?? Issue.ZERO_ISSUED_CURRENCY.bytes)
35
+ }
36
+
37
+ /**
38
+ * Construct an amount from an IOU or string amount
39
+ *
40
+ * @param value An Amount, object representing an IOU, or a string
41
+ * representing an integer amount
42
+ * @returns An Amount object
43
+ */
44
+ static from<T extends Issue | IssueObject>(value: T): Issue {
45
+ if (value instanceof Issue) {
46
+ return value
47
+ }
48
+
49
+ if (isIssueObject(value)) {
50
+ const currency = Currency.from(value.currency).toBytes()
51
+ if (value.issuer == null) {
52
+ return new Issue(currency)
53
+ }
54
+ const issuer = AccountID.from(value.issuer).toBytes()
55
+ return new Issue(Buffer.concat([currency, issuer]))
56
+ }
57
+
58
+ throw new Error('Invalid type to construct an Amount')
59
+ }
60
+
61
+ /**
62
+ * Read an amount from a BinaryParser
63
+ *
64
+ * @param parser BinaryParser to read the Amount from
65
+ * @returns An Amount object
66
+ */
67
+ static fromParser(parser: BinaryParser): Issue {
68
+ const currency = parser.read(20)
69
+ if (new Currency(currency).toJSON() === 'XRP') {
70
+ return new Issue(currency)
71
+ }
72
+ const currencyAndIssuer = [currency, parser.read(20)]
73
+ return new Issue(Buffer.concat(currencyAndIssuer))
74
+ }
75
+
76
+ /**
77
+ * Get the JSON representation of this Amount
78
+ *
79
+ * @returns the JSON interpretation of this.bytes
80
+ */
81
+ toJSON(): IssueObject {
82
+ const parser = new BinaryParser(this.toString())
83
+ const currency = Currency.fromParser(parser) as Currency
84
+ if (currency.toJSON() === 'XRP') {
85
+ return { currency: currency.toJSON() }
86
+ }
87
+ const issuer = AccountID.fromParser(parser) as AccountID
88
+
89
+ return {
90
+ currency: currency.toJSON(),
91
+ issuer: issuer.toJSON(),
92
+ }
93
+ }
94
+ }
95
+
96
+ export { Issue, IssueObject }
@@ -0,0 +1,290 @@
1
+ import { AccountID } from './account-id'
2
+ import { Currency } from './currency'
3
+ import { BinaryParser } from '../serdes/binary-parser'
4
+ import { SerializedType, JsonObject } from './serialized-type'
5
+ import { Buffer } from 'buffer/'
6
+
7
+ /**
8
+ * Constants for separating Paths in a PathSet
9
+ */
10
+ const PATHSET_END_BYTE = 0x00
11
+ const PATH_SEPARATOR_BYTE = 0xff
12
+
13
+ /**
14
+ * Constant for masking types of a Hop
15
+ */
16
+ const TYPE_ACCOUNT = 0x01
17
+ const TYPE_CURRENCY = 0x10
18
+ const TYPE_ISSUER = 0x20
19
+
20
+ /**
21
+ * The object representation of a Hop, an issuer AccountID, an account AccountID, and a Currency
22
+ */
23
+ interface HopObject extends JsonObject {
24
+ issuer?: string
25
+ account?: string
26
+ currency?: string
27
+ }
28
+
29
+ /**
30
+ * TypeGuard for HopObject
31
+ */
32
+ function isHopObject(arg): arg is HopObject {
33
+ return (
34
+ arg.issuer !== undefined ||
35
+ arg.account !== undefined ||
36
+ arg.currency !== undefined
37
+ )
38
+ }
39
+
40
+ /**
41
+ * TypeGuard for PathSet
42
+ */
43
+ function isPathSet(arg): arg is Array<Array<HopObject>> {
44
+ return (
45
+ (Array.isArray(arg) && arg.length === 0) ||
46
+ (Array.isArray(arg) && Array.isArray(arg[0]) && arg[0].length === 0) ||
47
+ (Array.isArray(arg) && Array.isArray(arg[0]) && isHopObject(arg[0][0]))
48
+ )
49
+ }
50
+
51
+ /**
52
+ * Serialize and Deserialize a Hop
53
+ */
54
+ class Hop extends SerializedType {
55
+ /**
56
+ * Create a Hop from a HopObject
57
+ *
58
+ * @param value Either a hop or HopObject to create a hop with
59
+ * @returns a Hop
60
+ */
61
+ static from(value: Hop | HopObject): Hop {
62
+ if (value instanceof Hop) {
63
+ return value
64
+ }
65
+
66
+ const bytes: Array<Buffer> = [Buffer.from([0])]
67
+
68
+ if (value.account) {
69
+ bytes.push(AccountID.from(value.account).toBytes())
70
+ bytes[0][0] |= TYPE_ACCOUNT
71
+ }
72
+
73
+ if (value.currency) {
74
+ bytes.push(Currency.from(value.currency).toBytes())
75
+ bytes[0][0] |= TYPE_CURRENCY
76
+ }
77
+
78
+ if (value.issuer) {
79
+ bytes.push(AccountID.from(value.issuer).toBytes())
80
+ bytes[0][0] |= TYPE_ISSUER
81
+ }
82
+
83
+ return new Hop(Buffer.concat(bytes))
84
+ }
85
+
86
+ /**
87
+ * Construct a Hop from a BinaryParser
88
+ *
89
+ * @param parser BinaryParser to read the Hop from
90
+ * @returns a Hop
91
+ */
92
+ static fromParser(parser: BinaryParser): Hop {
93
+ const type = parser.readUInt8()
94
+ const bytes: Array<Buffer> = [Buffer.from([type])]
95
+
96
+ if (type & TYPE_ACCOUNT) {
97
+ bytes.push(parser.read(AccountID.width))
98
+ }
99
+
100
+ if (type & TYPE_CURRENCY) {
101
+ bytes.push(parser.read(Currency.width))
102
+ }
103
+
104
+ if (type & TYPE_ISSUER) {
105
+ bytes.push(parser.read(AccountID.width))
106
+ }
107
+
108
+ return new Hop(Buffer.concat(bytes))
109
+ }
110
+
111
+ /**
112
+ * Get the JSON interpretation of this hop
113
+ *
114
+ * @returns a HopObject, an JS object with optional account, issuer, and currency
115
+ */
116
+ toJSON(): HopObject {
117
+ const hopParser = new BinaryParser(this.bytes.toString('hex'))
118
+ const type = hopParser.readUInt8()
119
+
120
+ let account, currency, issuer
121
+ if (type & TYPE_ACCOUNT) {
122
+ account = (AccountID.fromParser(hopParser) as AccountID).toJSON()
123
+ }
124
+
125
+ if (type & TYPE_CURRENCY) {
126
+ currency = (Currency.fromParser(hopParser) as Currency).toJSON()
127
+ }
128
+
129
+ if (type & TYPE_ISSUER) {
130
+ issuer = (AccountID.fromParser(hopParser) as AccountID).toJSON()
131
+ }
132
+
133
+ const result: HopObject = {}
134
+ if (account) {
135
+ result.account = account
136
+ }
137
+
138
+ if (issuer) {
139
+ result.issuer = issuer
140
+ }
141
+
142
+ if (currency) {
143
+ result.currency = currency
144
+ }
145
+
146
+ return result
147
+ }
148
+
149
+ /**
150
+ * get a number representing the type of this hop
151
+ *
152
+ * @returns a number to be bitwise and-ed with TYPE_ constants to describe the types in the hop
153
+ */
154
+ type(): number {
155
+ return this.bytes[0]
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Class for serializing/deserializing Paths
161
+ */
162
+ class Path extends SerializedType {
163
+ /**
164
+ * construct a Path from an array of Hops
165
+ *
166
+ * @param value Path or array of HopObjects to construct a Path
167
+ * @returns the Path
168
+ */
169
+ static from(value: Path | Array<HopObject>): Path {
170
+ if (value instanceof Path) {
171
+ return value
172
+ }
173
+
174
+ const bytes: Array<Buffer> = []
175
+ value.forEach((hop: HopObject) => {
176
+ bytes.push(Hop.from(hop).toBytes())
177
+ })
178
+
179
+ return new Path(Buffer.concat(bytes))
180
+ }
181
+
182
+ /**
183
+ * Read a Path from a BinaryParser
184
+ *
185
+ * @param parser BinaryParser to read Path from
186
+ * @returns the Path represented by the bytes read from the BinaryParser
187
+ */
188
+ static fromParser(parser: BinaryParser): Path {
189
+ const bytes: Array<Buffer> = []
190
+ while (!parser.end()) {
191
+ bytes.push(Hop.fromParser(parser).toBytes())
192
+
193
+ if (
194
+ parser.peek() === PATHSET_END_BYTE ||
195
+ parser.peek() === PATH_SEPARATOR_BYTE
196
+ ) {
197
+ break
198
+ }
199
+ }
200
+ return new Path(Buffer.concat(bytes))
201
+ }
202
+
203
+ /**
204
+ * Get the JSON representation of this Path
205
+ *
206
+ * @returns an Array of HopObject constructed from this.bytes
207
+ */
208
+ toJSON(): Array<HopObject> {
209
+ const json: Array<HopObject> = []
210
+ const pathParser = new BinaryParser(this.toString())
211
+
212
+ while (!pathParser.end()) {
213
+ json.push(Hop.fromParser(pathParser).toJSON())
214
+ }
215
+
216
+ return json
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Deserialize and Serialize the PathSet type
222
+ */
223
+ class PathSet extends SerializedType {
224
+ /**
225
+ * Construct a PathSet from an Array of Arrays representing paths
226
+ *
227
+ * @param value A PathSet or Array of Array of HopObjects
228
+ * @returns the PathSet constructed from value
229
+ */
230
+ static from<T extends PathSet | Array<Array<HopObject>>>(value: T): PathSet {
231
+ if (value instanceof PathSet) {
232
+ return value
233
+ }
234
+
235
+ if (isPathSet(value)) {
236
+ const bytes: Array<Buffer> = []
237
+
238
+ value.forEach((path: Array<HopObject>) => {
239
+ bytes.push(Path.from(path).toBytes())
240
+ bytes.push(Buffer.from([PATH_SEPARATOR_BYTE]))
241
+ })
242
+
243
+ bytes[bytes.length - 1] = Buffer.from([PATHSET_END_BYTE])
244
+
245
+ return new PathSet(Buffer.concat(bytes))
246
+ }
247
+
248
+ throw new Error('Cannot construct PathSet from given value')
249
+ }
250
+
251
+ /**
252
+ * Construct a PathSet from a BinaryParser
253
+ *
254
+ * @param parser A BinaryParser to read PathSet from
255
+ * @returns the PathSet read from parser
256
+ */
257
+ static fromParser(parser: BinaryParser): PathSet {
258
+ const bytes: Array<Buffer> = []
259
+
260
+ while (!parser.end()) {
261
+ bytes.push(Path.fromParser(parser).toBytes())
262
+ bytes.push(parser.read(1))
263
+
264
+ if (bytes[bytes.length - 1][0] == PATHSET_END_BYTE) {
265
+ break
266
+ }
267
+ }
268
+
269
+ return new PathSet(Buffer.concat(bytes))
270
+ }
271
+
272
+ /**
273
+ * Get the JSON representation of this PathSet
274
+ *
275
+ * @returns an Array of Array of HopObjects, representing this PathSet
276
+ */
277
+ toJSON(): Array<Array<HopObject>> {
278
+ const json: Array<Array<HopObject>> = []
279
+ const pathParser = new BinaryParser(this.toString())
280
+
281
+ while (!pathParser.end()) {
282
+ json.push(Path.fromParser(pathParser).toJSON())
283
+ pathParser.skip(1)
284
+ }
285
+
286
+ return json
287
+ }
288
+ }
289
+
290
+ export { PathSet }