Skip to content

Commit 121b72a

Browse files
authored
Merge pull request #512 from algorandfoundation/generator-ts-integration
Generator ts integration
2 parents 1acfdf8 + a0ffdca commit 121b72a

File tree

3 files changed

+69
-45
lines changed

3 files changed

+69
-45
lines changed

packages/abi/src/abi-type.ts

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import type { ABIStructValue, ABIValue } from './abi-value'
1010
import { StructField } from './arc56-contract'
1111
import { bigIntToBytes, bytesToBigInt } from './bigint'
12+
import { getStructValueFromTupleValue, getTupleValueFromStructValue } from './utils'
1213

1314
const STATIC_ARRAY_REGEX = /^([a-z\d[\](),]+)\[(0|[1-9][\d]*)]$/
1415
const UFIXED_REGEX = /^ufixed([1-9][\d]*)x([1-9][\d]*)$/
@@ -841,56 +842,14 @@ export class ABIStructType extends ABIType {
841842
return tupleType.encode(value)
842843
}
843844

844-
const tupleValue = this.getTupleValueFromStructValue(value)
845+
const tupleValue = getTupleValueFromStructValue(this, value)
845846
return tupleType.encode(tupleValue)
846847
}
847848

848849
decode(bytes: Uint8Array): ABIStructValue {
849850
const tupleType = this.toABITupleType()
850851
const tupleValue = tupleType.decode(bytes)
851-
return this.getStructValueFromTupleValue(tupleValue)
852-
}
853-
854-
private getTupleValueFromStructValue(structValue: ABIStructValue): ABIValue[] {
855-
const getTupleValueFromStructFields = (structFields: ABIStructField[], values: ABIValue[]): ABIValue[] => {
856-
return structFields.map(({ type }, index) => {
857-
// if type is an array of fields, treat as unnamed struct
858-
if (Array.isArray(type)) {
859-
const value = values[index] as ABIStructValue
860-
return getTupleValueFromStructFields(type, Object.values(value))
861-
}
862-
// if type is struct, treat as struct
863-
if (type instanceof ABIStructType) {
864-
const value = values[index] as ABIStructValue
865-
return getTupleValueFromStructFields(type.structFields, Object.values(value))
866-
}
867-
return values[index]
868-
})
869-
}
870-
871-
return getTupleValueFromStructFields(this.structFields, Object.values(structValue))
872-
}
873-
874-
private getStructValueFromTupleValue(tupleValue: ABIValue[]): ABIStructValue {
875-
const getStructFieldValues = (structFields: ABIStructField[], values: ABIValue[]): ABIStructValue => {
876-
return Object.fromEntries(
877-
structFields.map(({ name, type }, index) => {
878-
// When the type is an array of fields, the value must be tuple
879-
if (Array.isArray(type)) {
880-
const value = values[index] as ABIValue[]
881-
return [name, getStructFieldValues(type, value)]
882-
}
883-
// When the type is a struct, the value must be tuple
884-
if (type instanceof ABIStructType) {
885-
const value = values[index] as ABIValue[]
886-
return [name, getStructFieldValues(type.structFields, value)]
887-
}
888-
return [name, values[index]]
889-
}),
890-
)
891-
}
892-
893-
return getStructFieldValues(this.structFields, tupleValue)
852+
return getStructValueFromTupleValue(this, tupleValue)
894853
}
895854
}
896855

packages/abi/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export {
22
ABIMethod,
3+
ABIReferenceType,
4+
ABITransactionType,
35
arc56MethodToABIMethod,
46
argTypeIsAbiType,
57
argTypeIsReference,
@@ -19,7 +21,6 @@ export type {
1921
ABIReturn,
2022
DefaultValueSource,
2123
} from './abi-method'
22-
export { ABIReferenceType, ABITransactionType } from './abi-method'
2324
export {
2425
ABIAddressType,
2526
ABIArrayDynamicType,
@@ -67,3 +68,4 @@ export type {
6768
StructField,
6869
StructName,
6970
} from './arc56-contract'
71+
export { getStructValueFromTupleValue, getTupleValueFromStructValue } from './utils'

packages/abi/src/utils.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import type { ABIStructField, ABIStructType, ABIType } from './abi-type'
2+
import type { ABIStructValue, ABIValue } from './abi-value'
3+
4+
/**
5+
* Checks if a type is an ABIStructType by checking for the structFields property.
6+
*/
7+
function isABIStructType(type: ABIType | ABIStructField[]): type is ABIStructType {
8+
return !Array.isArray(type) && 'structFields' in type
9+
}
10+
11+
/**
12+
* Converts a struct value (object with named fields) to a tuple value (array).
13+
* @param structType The struct type definition
14+
* @param structValue The struct value to convert
15+
* @returns The equivalent tuple value
16+
*/
17+
export function getTupleValueFromStructValue(structType: ABIStructType, structValue: ABIStructValue): ABIValue[] {
18+
const getTupleValueFromStructFields = (structFields: ABIStructField[], values: ABIValue[]): ABIValue[] => {
19+
return structFields.map(({ type }, index) => {
20+
// if type is an array of fields, treat as unnamed struct
21+
if (Array.isArray(type)) {
22+
const value = values[index] as ABIStructValue
23+
return getTupleValueFromStructFields(type, Object.values(value))
24+
}
25+
// if type is struct, treat as struct
26+
if (isABIStructType(type)) {
27+
const value = values[index] as ABIStructValue
28+
return getTupleValueFromStructFields(type.structFields, Object.values(value))
29+
}
30+
return values[index]
31+
})
32+
}
33+
34+
return getTupleValueFromStructFields(structType.structFields, Object.values(structValue))
35+
}
36+
37+
/**
38+
* Converts a tuple value (array) to a struct value (object with named fields).
39+
* @param structType The struct type definition
40+
* @param tupleValue The tuple value to convert
41+
* @returns The equivalent struct value
42+
*/
43+
export function getStructValueFromTupleValue(structType: ABIStructType, tupleValue: ABIValue[]): ABIStructValue {
44+
const getStructFieldValues = (structFields: ABIStructField[], values: ABIValue[]): ABIStructValue => {
45+
return Object.fromEntries(
46+
structFields.map(({ name, type }, index) => {
47+
// When the type is an array of fields, the value must be tuple
48+
if (Array.isArray(type)) {
49+
const value = values[index] as ABIValue[]
50+
return [name, getStructFieldValues(type, value)]
51+
}
52+
// When the type is a struct, the value must be tuple
53+
if (isABIStructType(type)) {
54+
const value = values[index] as ABIValue[]
55+
return [name, getStructFieldValues(type.structFields, value)]
56+
}
57+
return [name, values[index]]
58+
}),
59+
)
60+
}
61+
62+
return getStructFieldValues(structType.structFields, tupleValue)
63+
}

0 commit comments

Comments
 (0)