From edef2082948d6bbbd232e6650dd3c18690f721c9 Mon Sep 17 00:00:00 2001 From: benesjan Date: Mon, 2 Sep 2024 12:39:26 +0000 Subject: [PATCH] feat: tuple return value typescript decoding --- yarn-project/foundation/src/abi/abi.ts | 19 ++++++++++++++++++- yarn-project/foundation/src/abi/decoder.ts | 7 +++++++ yarn-project/foundation/src/abi/encoder.ts | 2 ++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/yarn-project/foundation/src/abi/abi.ts b/yarn-project/foundation/src/abi/abi.ts index 7f629dc0e2b..8e77fd0f482 100644 --- a/yarn-project/foundation/src/abi/abi.ts +++ b/yarn-project/foundation/src/abi/abi.ts @@ -84,7 +84,14 @@ export interface BasicType { /** * A variable type. */ -export type AbiType = BasicType<'field'> | BasicType<'boolean'> | IntegerType | ArrayType | StringType | StructType; +export type AbiType = + | BasicType<'field'> + | BasicType<'boolean'> + | IntegerType + | ArrayType + | StringType + | StructType + | TupleType; type Sign = 'unsigned' | 'signed'; @@ -116,6 +123,16 @@ export interface ArrayType extends BasicType<'array'> { type: AbiType; } +/** + * A tuple type. + */ +export interface TupleType extends BasicType<'tuple'> { + /** + * The types of the tuple elements. + */ + fields: AbiType[]; +} + /** * A string type. */ diff --git a/yarn-project/foundation/src/abi/decoder.ts b/yarn-project/foundation/src/abi/decoder.ts index 361525fea7a..1749e357fc6 100644 --- a/yarn-project/foundation/src/abi/decoder.ts +++ b/yarn-project/foundation/src/abi/decoder.ts @@ -56,6 +56,13 @@ class ReturnValuesDecoder { } return array; } + case 'tuple': { + const array = []; + for (const tupleAbiType of abiType.fields) { + array.push(this.decodeReturn(tupleAbiType)); + } + return array; + } default: throw new Error(`Unsupported type: ${abiType}`); } diff --git a/yarn-project/foundation/src/abi/encoder.ts b/yarn-project/foundation/src/abi/encoder.ts index 22b31c63144..44376257cc9 100644 --- a/yarn-project/foundation/src/abi/encoder.ts +++ b/yarn-project/foundation/src/abi/encoder.ts @@ -23,6 +23,8 @@ class ArgumentEncoder { return abiType.length * ArgumentEncoder.typeSize(abiType.type); case 'struct': return abiType.fields.reduce((acc, field) => acc + ArgumentEncoder.typeSize(field.type), 0); + case 'tuple': + return abiType.fields.reduce((acc, field) => acc + ArgumentEncoder.typeSize(field), 0); default: { const exhaustiveCheck: never = abiType; throw new Error(`Unhandled abi type: ${exhaustiveCheck}`);