@@ -181,6 +181,35 @@ function encodeType(name: string, fields: Array<TypedDataField>): string {
181181 return `${ name } (${ fields . map ( ( { name, type } ) => ( type + " " + name ) ) . join ( "," ) } )` ;
182182}
183183
184+ type ArrayResult = {
185+ base : string ; // The base type
186+ index ?: string ; // the full Index (if any)
187+ array ?: { // The Array... (if index)
188+ base : string ; // ...base type (same as above)
189+ prefix : string ; // ...sans the final Index
190+ count : number ; // ...the final Index (-1 for dynamic)
191+ }
192+ } ;
193+
194+ // foo[][3] => { base: "foo", index: "[][3]", array: {
195+ // base: "foo", prefix: "foo[]", count: 3 } }
196+ function splitArray ( type : string ) : ArrayResult {
197+ const match = type . match ( / ^ ( [ ^ \x5b ] * ) ( ( \x5b \d * \x5d ) * ) ( \x5b ( \d * ) \x5d ) $ / ) ;
198+ if ( match ) {
199+ return {
200+ base : match [ 1 ] ,
201+ index : ( match [ 2 ] + match [ 4 ] ) ,
202+ array : {
203+ base : match [ 1 ] ,
204+ prefix : ( match [ 1 ] + match [ 2 ] ) ,
205+ count : ( match [ 5 ] ? parseInt ( match [ 5 ] ) : - 1 ) ,
206+ }
207+ } ;
208+ }
209+
210+ return { base : type } ;
211+ }
212+
184213/**
185214 * A **TypedDataEncode** prepares and encodes [[link-eip-712]] payloads
186215 * for signed typed data.
@@ -235,11 +264,14 @@ export class TypedDataEncoder {
235264
236265 const types : Record < string , Array < TypedDataField > > = { } ;
237266 Object . keys ( _types ) . forEach ( ( type ) => {
238- // Normalize int/uint unless they are a complex type themselves
239267 types [ type ] = _types [ type ] . map ( ( { name, type } ) => {
240- if ( type === "int" && ! _types [ "int" ] ) { type = "int256" ; }
241- if ( type === "uint" && ! _types [ "uint" ] ) { type = "uint256" ; }
242- return { name, type } ;
268+
269+ // Normalize the base type (unless name conflict)
270+ let { base, index } = splitArray ( type ) ;
271+ if ( base === "int" && ! _types [ "int" ] ) { base = "int256" ; }
272+ if ( base === "uint" && ! _types [ "uint" ] ) { base = "uint256" ; }
273+
274+ return { name, type : ( base + ( index || "" ) ) } ;
243275 } ) ;
244276
245277 links . set ( type , new Set ( ) ) ;
@@ -258,7 +290,7 @@ export class TypedDataEncoder {
258290 uniqueNames . add ( field . name ) ;
259291
260292 // Get the base type (drop any array specifiers)
261- const baseType = ( < any > ( field . type . match ( / ^ ( [ ^ \x5b ] * ) ( \x5b | $ ) / ) ) ) [ 1 ] || null ;
293+ const baseType = splitArray ( field . type ) . base ;
262294 assertArgument ( baseType !== name , `circular type reference to ${ JSON . stringify ( baseType ) } ` , "types" , _types ) ;
263295
264296 // Is this a base encoding type?
@@ -331,12 +363,12 @@ export class TypedDataEncoder {
331363 }
332364
333365 // Array
334- const match = type . match ( / ^ ( . * ) ( \x5b ( \d * ) \x5d ) $ / ) ;
335- if ( match ) {
336- const subtype = match [ 1 ] ;
366+ const array = splitArray ( type ) . array ;
367+ if ( array ) {
368+ const subtype = array . prefix ;
337369 const subEncoder = this . getEncoder ( subtype ) ;
338370 return ( value : Array < any > ) => {
339- assertArgument ( ! match [ 3 ] || parseInt ( match [ 3 ] ) === value . length , `array length mismatch; expected length ${ parseInt ( match [ 3 ] ) } ` , "value" , value ) ;
371+ assertArgument ( array . count === - 1 || array . count === value . length , `array length mismatch; expected length ${ array . count } ` , "value" , value ) ;
340372
341373 let result = value . map ( subEncoder ) ;
342374 if ( this . #fullTypes. has ( subtype ) ) {
@@ -413,10 +445,10 @@ export class TypedDataEncoder {
413445 }
414446
415447 // Array
416- const match = type . match ( / ^ ( . * ) ( \x5b ( \d * ) \x5d ) $ / ) ;
417- if ( match ) {
418- assertArgument ( ! match [ 3 ] || parseInt ( match [ 3 ] ) === value . length , `array length mismatch; expected length ${ parseInt ( match [ 3 ] ) } ` , "value" , value ) ;
419- return value . map ( ( v : any ) => this . _visit ( match [ 1 ] , v , callback ) ) ;
448+ const array = splitArray ( type ) . array ;
449+ if ( array ) {
450+ assertArgument ( array . count === - 1 || array . count === value . length , `array length mismatch; expected length ${ array . count } ` , "value" , value ) ;
451+ return value . map ( ( v : any ) => this . _visit ( array . prefix , v , callback ) ) ;
420452 }
421453
422454 // Struct
0 commit comments