@@ -48,12 +48,13 @@ const SOPHIA_TYPES = [
4848 */
4949function transform ( type , value ) {
5050 const { t, generic } = readType ( type )
51-
5251 switch ( t ) {
5352 case SOPHIA_TYPES . string :
5453 return `"${ value } "`
5554 case SOPHIA_TYPES . list :
5655 return `[${ value . map ( el => transform ( generic , el ) ) } ]`
56+ case SOPHIA_TYPES . tuple :
57+ return `(${ value . map ( ( el , i ) => transform ( generic [ i ] , el ) ) } )`
5758 case SOPHIA_TYPES . address :
5859 return `#${ decode ( value , 'ak' ) . toString ( 'hex' ) } `
5960 }
@@ -63,22 +64,19 @@ function transform (type, value) {
6364/**
6465 * Parse sophia type
6566 * @param type
67+ * @param returnType
6668 * @return {* }
6769 */
68- function readType ( type ) {
69- const i = type . indexOf ( '(' )
70-
71- if ( i === - 1 ) return { t : type }
70+ function readType ( type , returnType = false ) {
71+ const [ t ] = Array . isArray ( type ) ? type : [ type ]
72+ // Base types
73+ if ( typeof t === 'string' ) return { t }
7274
73- // Tuple
74- if ( type [ 0 ] === '(' ) {
75- return { t : SOPHIA_TYPES . tuple , generic : type . slice ( 1 ) . slice ( 0 , - 1 ) . split ( ',' ) . map ( e => e . trim ( ) ) }
75+ // Map, Tuple, List
76+ if ( typeof t === 'object' ) {
77+ const [ [ baseType , generic ] ] = Object . entries ( t )
78+ return { t : baseType , generic }
7679 }
77-
78- const baseType = type . split ( '(' ) [ 0 ]
79- const generic = type . slice ( i + 1 , type . length - 1 )
80-
81- return { t : baseType , generic }
8280}
8381
8482/**
@@ -112,29 +110,28 @@ function validate (type, value) {
112110 */
113111function transformDecodedData ( aci , result , { skipTransformDecoded = false } = { } ) {
114112 if ( skipTransformDecoded ) return result
115- const { t, generic } = readType ( aci . type )
116-
113+ const { t, generic } = readType ( aci , true )
117114 switch ( t ) {
118115 case SOPHIA_TYPES . bool :
119116 return ! ! result . value
120117 case SOPHIA_TYPES . address :
121118 return aeEncodeKey ( toBytes ( result . value , true ) )
122119 case SOPHIA_TYPES . map :
123- const [ keyT , ... valueT ] = generic . split ( ',' )
120+ const [ keyT , valueT ] = generic
124121 return result . value
125122 . reduce (
126123 ( acc , { key, val } , i ) => {
127- key = transformDecodedData ( { type : keyT . toString ( ) } , { value : key . value } )
128- val = transformDecodedData ( { type : valueT . toString ( ) } , { value : val . value } )
124+ key = transformDecodedData ( keyT , { value : key . value } )
125+ val = transformDecodedData ( valueT , { value : val . value } )
129126 acc [ i ] = { key, val }
130127 return acc
131128 } ,
132129 { }
133130 )
134131 case SOPHIA_TYPES . list :
135- return result . value . map ( ( { value } ) => transformDecodedData ( { type : generic } , { value } ) )
132+ return result . value . map ( ( { value } ) => transformDecodedData ( generic , { value } ) )
136133 case SOPHIA_TYPES . tuple :
137- return result . value . map ( ( { value } , i ) => { return transformDecodedData ( { type : generic [ i ] } , { value } ) } )
134+ return result . value . map ( ( { value } , i ) => { return transformDecodedData ( generic [ i ] , { value } ) } )
138135 }
139136 return result . value
140137}
@@ -232,6 +229,22 @@ async function getContractInstance (source, { aci, contractAddress } = {}) {
232229 return instance
233230}
234231
232+ function transformReturnType ( returns ) {
233+ if ( typeof returns === 'string' ) return returns
234+ if ( typeof returns === 'object' ) {
235+ const [ [ key , value ] ] = Object . entries ( returns )
236+ return `${ key !== 'tuple' ? key : '' } (${ value
237+ . reduce (
238+ ( acc , el , i ) => {
239+ if ( i !== 0 ) acc += ','
240+ acc += transformReturnType ( el )
241+ return acc
242+ } ,
243+ '' )
244+ } )`
245+ }
246+ }
247+
235248function call ( self ) {
236249 return async function ( fn , params = [ ] , options = { skipArgsConvert : false , skipTransformDecoded : false , callStatic : false } ) {
237250 const fnACI = getFunctionACI ( this . aci , fn )
@@ -245,10 +258,10 @@ function call (self) {
245258 options
246259 } )
247260 : await self . contractCall ( this . source , this . deployInfo . address , fn , params , options )
248-
261+ const returnType = await transformReturnType ( fnACI . returns )
249262 return {
250263 ...result ,
251- decode : async ( ) => transformDecodedData ( fnACI , await self . contractDecodeData ( fnACI . type , result . result . returnValue ) , options )
264+ decode : async ( ) => transformDecodedData ( fnACI . returns , await self . contractDecodeData ( returnType , result . result . returnValue ) , options )
252265 }
253266 }
254267}
@@ -257,7 +270,6 @@ function deploy (self) {
257270 return async function ( init = [ ] , options = { skipArgsConvert : false } ) {
258271 const fnACI = getFunctionACI ( this . aci , 'init' )
259272 if ( ! this . compiled ) await this . compile ( )
260-
261273 init = ! options . skipArgsConvert ? prepareArgsForEncode ( fnACI , init ) : init
262274
263275 const { owner, transaction, address, createdAt, result } = await self . contractDeploy ( this . compiled , this . source , init , options )
0 commit comments