@@ -43,7 +43,7 @@ export abstract class ABIType {
4343 // Converts a ABIType object to a string
4444 abstract toString ( ) : string ;
4545 // Checks if two ABIType objects are equal in value
46- abstract equal ( other : ABIType ) : boolean ;
46+ abstract equals ( other : ABIType ) : boolean ;
4747 // Checks if the ABIType object (or any of its child types) have dynamic length
4848 abstract isDynamic ( ) : boolean ;
4949 // Returns the size of the ABIType object in bytes
@@ -139,10 +139,8 @@ export class ABIUintType extends ABIType {
139139 return `uint${ this . bitSize } ` ;
140140 }
141141
142- equal ( other : ABIUintType ) {
143- return (
144- this . constructor === other . constructor && this . bitSize === other . bitSize
145- ) ;
142+ equals ( other : ABIType ) {
143+ return other instanceof ABIUintType && this . bitSize === other . bitSize ;
146144 }
147145
148146 isDynamic ( ) {
@@ -153,12 +151,11 @@ export class ABIUintType extends ABIType {
153151 return this . bitSize / 8 ;
154152 }
155153
156- encode ( value : bigint | number ) {
157- if (
158- ( typeof value !== 'bigint' && typeof value !== 'number' ) ||
159- value >= BigInt ( 2 ** this . bitSize ) ||
160- value < BigInt ( 0 )
161- ) {
154+ encode ( value : ABIValue ) {
155+ if ( typeof value !== 'bigint' && typeof value !== 'number' ) {
156+ throw new Error ( `Cannot encode value as uint${ this . bitSize } : ${ value } ` ) ;
157+ }
158+ if ( value >= BigInt ( 2 ** this . bitSize ) || value < BigInt ( 0 ) ) {
162159 throw new Error (
163160 `${ value } is not a non-negative int or too big to fit in size uint${ this . bitSize } `
164161 ) ;
@@ -171,7 +168,7 @@ export class ABIUintType extends ABIType {
171168 return bigIntToBytes ( value , this . bitSize / 8 ) ;
172169 }
173170
174- decode ( byteString : Uint8Array ) {
171+ decode ( byteString : Uint8Array ) : bigint {
175172 if ( byteString . length !== this . bitSize / 8 ) {
176173 throw new Error ( `byte string must correspond to a uint${ this . bitSize } ` ) ;
177174 }
@@ -199,9 +196,9 @@ export class ABIUfixedType extends ABIType {
199196 return `ufixed${ this . bitSize } x${ this . precision } ` ;
200197 }
201198
202- equal ( other : ABIUfixedType ) {
199+ equals ( other : ABIType ) {
203200 return (
204- this . constructor === other . constructor &&
201+ other instanceof ABIUfixedType &&
205202 this . bitSize === other . bitSize &&
206203 this . precision === other . precision
207204 ) ;
@@ -215,14 +212,13 @@ export class ABIUfixedType extends ABIType {
215212 return this . bitSize / 8 ;
216213 }
217214
218- encode ( value : bigint | number ) {
219- if (
220- ( typeof value !== 'bigint' && typeof value !== 'number' ) ||
221- value >= BigInt ( 2 ** this . bitSize ) ||
222- value < BigInt ( 0 )
223- ) {
215+ encode ( value : ABIValue ) {
216+ if ( typeof value !== 'bigint' && typeof value !== 'number' ) {
217+ throw new Error ( `Cannot encode value as ${ this . toString ( ) } : ${ value } ` ) ;
218+ }
219+ if ( value >= BigInt ( 2 ** this . bitSize ) || value < BigInt ( 0 ) ) {
224220 throw new Error (
225- `${ value } is not a non-negative int or too big to fit in size ufixed ${ this . bitSize } `
221+ `${ value } is not a non-negative int or too big to fit in size ${ this . toString ( ) } `
226222 ) ;
227223 }
228224 if ( typeof value === 'number' && ! Number . isSafeInteger ( value ) ) {
@@ -233,9 +229,9 @@ export class ABIUfixedType extends ABIType {
233229 return bigIntToBytes ( value , this . bitSize / 8 ) ;
234230 }
235231
236- decode ( byteString : Uint8Array ) {
232+ decode ( byteString : Uint8Array ) : bigint {
237233 if ( byteString . length !== this . bitSize / 8 ) {
238- throw new Error ( `byte string must correspond to a ufixed ${ this . bitSize } ` ) ;
234+ throw new Error ( `byte string must correspond to a ${ this . toString ( ) } ` ) ;
239235 }
240236 return bytesToBigInt ( byteString ) ;
241237 }
@@ -246,8 +242,8 @@ export class ABIAddressType extends ABIType {
246242 return 'address' ;
247243 }
248244
249- equal ( other : ABIAddressType ) {
250- return this . constructor === other . constructor ;
245+ equals ( other : ABIType ) {
246+ return other instanceof ABIAddressType ;
251247 }
252248
253249 isDynamic ( ) {
@@ -258,20 +254,23 @@ export class ABIAddressType extends ABIType {
258254 return ADDR_BYTE_SIZE ;
259255 }
260256
261- encode ( value : string | Uint8Array ) {
257+ encode ( value : ABIValue ) {
258+ if ( typeof value !== 'string' && ! ( value instanceof Uint8Array ) ) {
259+ throw new Error ( `Cannot encode value as ${ this . toString ( ) } : ${ value } ` ) ;
260+ }
262261 if ( typeof value === 'string' ) {
263262 const decodedAddress = decodeAddress ( value ) ;
264263 return decodedAddress . publicKey ;
265264 }
266265 // Return the address if it is already in bytes
267- if ( value . length !== 32 ) {
266+ if ( value . byteLength !== 32 ) {
268267 throw new Error ( `byte string must be 32 bytes long for an address` ) ;
269268 }
270269 return value ;
271270 }
272271
273- decode ( byteString : Uint8Array ) {
274- if ( byteString . length !== 32 ) {
272+ decode ( byteString : Uint8Array ) : string {
273+ if ( byteString . byteLength !== 32 ) {
275274 throw new Error ( `byte string must be 32 bytes long for an address` ) ;
276275 }
277276 return encodeAddress ( byteString ) ;
@@ -283,8 +282,8 @@ export class ABIBoolType extends ABIType {
283282 return 'bool' ;
284283 }
285284
286- equal ( other : ABIBoolType ) {
287- return this . constructor === other . constructor ;
285+ equals ( other : ABIType ) {
286+ return other instanceof ABIBoolType ;
288287 }
289288
290289 isDynamic ( ) {
@@ -295,15 +294,18 @@ export class ABIBoolType extends ABIType {
295294 return SINGLE_BOOL_SIZE ;
296295 }
297296
298- encode ( value : boolean ) {
297+ encode ( value : ABIValue ) {
298+ if ( typeof value !== 'boolean' ) {
299+ throw new Error ( `Cannot encode value as bool: ${ value } ` ) ;
300+ }
299301 if ( value ) {
300302 return new Uint8Array ( [ 128 ] ) ;
301303 }
302304 return new Uint8Array ( [ 0 ] ) ;
303305 }
304306
305- decode ( byteString : Uint8Array ) {
306- if ( byteString . length !== 1 ) {
307+ decode ( byteString : Uint8Array ) : boolean {
308+ if ( byteString . byteLength !== 1 ) {
307309 throw new Error ( `bool string must be 1 byte long` ) ;
308310 }
309311 const value = byteString [ 0 ] ;
@@ -322,8 +324,8 @@ export class ABIByteType extends ABIType {
322324 return 'byte' ;
323325 }
324326
325- equal ( other : ABIByteType ) {
326- return this . constructor === other . constructor ;
327+ equals ( other : ABIType ) {
328+ return other instanceof ABIByteType ;
327329 }
328330
329331 isDynamic ( ) {
@@ -334,15 +336,22 @@ export class ABIByteType extends ABIType {
334336 return SINGLE_BYTE_SIZE ;
335337 }
336338
337- encode ( value : number ) {
339+ encode ( value : ABIValue ) {
340+ if ( typeof value !== 'number' && typeof value !== 'bigint' ) {
341+ throw new Error ( `Cannot encode value as byte: ${ value } ` ) ;
342+ }
343+ if ( typeof value === 'bigint' ) {
344+ // eslint-disable-next-line no-param-reassign
345+ value = Number ( value ) ;
346+ }
338347 if ( value < 0 || value > 255 ) {
339348 throw new Error ( `${ value } cannot be encoded into a byte` ) ;
340349 }
341350 return new Uint8Array ( [ value ] ) ;
342351 }
343352
344- decode ( byteString : Uint8Array ) {
345- if ( byteString . length !== 1 ) {
353+ decode ( byteString : Uint8Array ) : number {
354+ if ( byteString . byteLength !== 1 ) {
346355 throw new Error ( `byte string must be 1 byte long` ) ;
347356 }
348357 return byteString [ 0 ] ;
@@ -354,8 +363,8 @@ export class ABIStringType extends ABIType {
354363 return 'string' ;
355364 }
356365
357- equal ( other : ABIStringType ) {
358- return this . constructor === other . constructor ;
366+ equals ( other : ABIType ) {
367+ return other instanceof ABIStringType ;
359368 }
360369
361370 isDynamic ( ) {
@@ -366,7 +375,10 @@ export class ABIStringType extends ABIType {
366375 throw new Error ( `${ this . toString ( ) } is a dynamic type` ) ;
367376 }
368377
369- encode ( value : string ) {
378+ encode ( value : ABIValue ) {
379+ if ( typeof value !== 'string' && ! ( value instanceof Uint8Array ) ) {
380+ throw new Error ( `Cannot encode value as string: ${ value } ` ) ;
381+ }
370382 const encodedBytes = Buffer . from ( value ) ;
371383 const encodedLength = bigIntToBytes ( value . length , LENGTH_ENCODE_BYTE_SIZE ) ;
372384 const mergedBytes = new Uint8Array ( value . length + LENGTH_ENCODE_BYTE_SIZE ) ;
@@ -375,9 +387,11 @@ export class ABIStringType extends ABIType {
375387 return mergedBytes ;
376388 }
377389
378- decode ( byteString : Uint8Array ) {
390+ decode ( byteString : Uint8Array ) : string {
379391 if ( byteString . length < LENGTH_ENCODE_BYTE_SIZE ) {
380- throw new Error ( `byte string is too short to be decoded: ${ byteString } ` ) ;
392+ throw new Error (
393+ `byte string is too short to be decoded. Actual length is ${ byteString . length } , but expected at least ${ LENGTH_ENCODE_BYTE_SIZE } `
394+ ) ;
381395 }
382396 const buf = Buffer . from ( byteString ) ;
383397 const byteLength = buf . readUIntBE ( 0 , LENGTH_ENCODE_BYTE_SIZE ) ;
@@ -387,11 +401,10 @@ export class ABIStringType extends ABIType {
387401 ) ;
388402 if ( byteLength !== byteValue . length ) {
389403 throw new Error (
390- `string length bytes do not match the actual length of string: ${ byteString } `
404+ `string length bytes do not match the actual length of string. Expected ${ byteLength } , got ${ byteValue . length } `
391405 ) ;
392406 }
393- const stringValue = Buffer . from ( byteValue ) . toString ( 'utf-8' ) ;
394- return stringValue ;
407+ return Buffer . from ( byteValue ) . toString ( 'utf-8' ) ;
395408 }
396409}
397410
@@ -414,11 +427,11 @@ export class ABIArrayStaticType extends ABIType {
414427 return `${ this . childType . toString ( ) } [${ this . staticLength } ]` ;
415428 }
416429
417- equal ( other : ABIArrayStaticType ) {
430+ equals ( other : ABIType ) {
418431 return (
419- this . constructor === other . constructor &&
420- this . childType === other . childType &&
421- this . staticLength === other . staticLength
432+ other instanceof ABIArrayStaticType &&
433+ this . staticLength === other . staticLength &&
434+ this . childType . equals ( other . childType )
422435 ) ;
423436 }
424437
@@ -433,15 +446,20 @@ export class ABIArrayStaticType extends ABIType {
433446 return this . staticLength * this . childType . byteLen ( ) ;
434447 }
435448
436- encode ( values : ABIValue [ ] ) {
437- if ( values . length !== this . staticLength ) {
438- throw new Error ( `value array does not match static array length` ) ;
449+ encode ( value : ABIValue ) {
450+ if ( ! Array . isArray ( value ) && ! ( value instanceof Uint8Array ) ) {
451+ throw new Error ( `Cannot encode value as ${ this . toString ( ) } : ${ value } ` ) ;
452+ }
453+ if ( value . length !== this . staticLength ) {
454+ throw new Error (
455+ `Value array does not match static array length. Expected ${ this . staticLength } , got ${ value . length } `
456+ ) ;
439457 }
440458 const convertedTuple = this . toABITupleType ( ) ;
441- return convertedTuple . encode ( values ) ;
459+ return convertedTuple . encode ( value ) ;
442460 }
443461
444- decode ( byteString : Uint8Array ) {
462+ decode ( byteString : Uint8Array ) : ABIValue [ ] {
445463 const convertedTuple = this . toABITupleType ( ) ;
446464 return convertedTuple . decode ( byteString ) ;
447465 }
@@ -463,10 +481,10 @@ export class ABIArrayDynamicType extends ABIType {
463481 return `${ this . childType . toString ( ) } []` ;
464482 }
465483
466- equal ( other : ABIArrayDynamicType ) {
484+ equals ( other : ABIType ) {
467485 return (
468- this . constructor === other . constructor &&
469- this . childType === other . childType
486+ other instanceof ABIArrayDynamicType &&
487+ this . childType . equals ( other . childType )
470488 ) ;
471489 }
472490
@@ -478,9 +496,12 @@ export class ABIArrayDynamicType extends ABIType {
478496 throw new Error ( `${ this . toString ( ) } is a dynamic type` ) ;
479497 }
480498
481- encode ( values : ABIValue [ ] ) {
482- const convertedTuple = this . toABITupleType ( values . length ) ;
483- const encodedTuple = convertedTuple . encode ( values ) ;
499+ encode ( value : ABIValue ) {
500+ if ( ! Array . isArray ( value ) && ! ( value instanceof Uint8Array ) ) {
501+ throw new Error ( `Cannot encode value as ${ this . toString ( ) } : ${ value } ` ) ;
502+ }
503+ const convertedTuple = this . toABITupleType ( value . length ) ;
504+ const encodedTuple = convertedTuple . encode ( value ) ;
484505 const encodedLength = bigIntToBytes (
485506 convertedTuple . childTypes . length ,
486507 LENGTH_ENCODE_BYTE_SIZE
@@ -489,7 +510,7 @@ export class ABIArrayDynamicType extends ABIType {
489510 return mergedBytes ;
490511 }
491512
492- decode ( byteString : Uint8Array ) {
513+ decode ( byteString : Uint8Array ) : ABIValue [ ] {
493514 const buf = Buffer . from ( byteString ) ;
494515 const byteLength = buf . readUIntBE ( 0 , LENGTH_ENCODE_BYTE_SIZE ) ;
495516 const convertedTuple = this . toABITupleType ( byteLength ) ;
@@ -524,10 +545,13 @@ export class ABITupleType extends ABIType {
524545 return `(${ typeStrings . join ( ',' ) } )` ;
525546 }
526547
527- equal ( other : ABITupleType ) {
548+ equals ( other : ABIType ) {
528549 return (
529- this . constructor === other . constructor &&
530- this . childTypes === other . childTypes
550+ other instanceof ABITupleType &&
551+ this . childTypes . length === other . childTypes . length &&
552+ this . childTypes . every ( ( child , index ) =>
553+ child . equals ( other . childTypes [ index ] )
554+ )
531555 ) ;
532556 }
533557
@@ -552,8 +576,12 @@ export class ABITupleType extends ABIType {
552576 return size ;
553577 }
554578
555- encode ( values : ABIValue [ ] ) {
556- if ( values . length > MAX_LEN ) {
579+ encode ( value : ABIValue ) {
580+ if ( ! Array . isArray ( value ) && ! ( value instanceof Uint8Array ) ) {
581+ throw new Error ( `Cannot encode value as ${ this . toString ( ) } : ${ value } ` ) ;
582+ }
583+ const values = Array . from ( value ) ;
584+ if ( value . length > MAX_LEN ) {
557585 throw new Error ( 'length of tuple array should not exceed a uint16' ) ;
558586 }
559587 const tupleTypes = this . childTypes ;
@@ -620,7 +648,7 @@ export class ABITupleType extends ABIType {
620648 return concatArrays ( ...heads , ...tails ) ;
621649 }
622650
623- decode ( byteString : Uint8Array ) {
651+ decode ( byteString : Uint8Array ) : ABIValue [ ] {
624652 const tupleTypes = this . childTypes ;
625653 const dynamicSegments : Segment [ ] = [ ] ;
626654 const valuePartition : Uint8Array [ ] = [ ] ;
0 commit comments