ABI Type Parsing
Description
Section titled “Description”This example demonstrates how to parse ABI type strings into type objects using ABIType.from(). It shows parsing of:
- Primitive types: uint8, uint64, uint256, bool, byte, address, string
- Array types: uint64[], byte[32], address[5]
- Tuple types: (uint64,address), (bool,string,uint256) And demonstrates type properties and instanceof checks for type category detection.
Prerequisites
Section titled “Prerequisites”- No LocalNet required
Run This Example
Section titled “Run This Example”From the repository root:
cd examplesnpm run example abi/01-type-parsing.ts/** * Example: ABI Type Parsing * * This example demonstrates how to parse ABI type strings into type objects using ABIType.from(). * It shows parsing of: * - Primitive types: uint8, uint64, uint256, bool, byte, address, string * - Array types: uint64[], byte[32], address[5] * - Tuple types: (uint64,address), (bool,string,uint256) * * And demonstrates type properties and instanceof checks for type category detection. * * Prerequisites: * - No LocalNet required */
import { ABIAddressType, ABIArrayDynamicType, ABIArrayStaticType, ABIBoolType, ABIByteType, ABIStringType, ABITupleType, ABIType, ABIUintType,} from '@algorandfoundation/algokit-utils/abi'import { printHeader, printInfo, printStep, printSuccess } from '../shared/utils.js'
function main() { printHeader('ABI Type Parsing Example')
// Step 1: Parse primitive unsigned integer types printStep(1, 'Parse Unsigned Integer Types')
const uint8Type = ABIType.from('uint8') const uint64Type = ABIType.from('uint64') const uint256Type = ABIType.from('uint256')
printInfo(`Parsed 'uint8': ${uint8Type.toString()}`) printInfo(`Parsed 'uint64': ${uint64Type.toString()}`) printInfo(`Parsed 'uint256': ${uint256Type.toString()}`)
// Show uint-specific properties if (uint8Type instanceof ABIUintType) { printInfo(` uint8 bitSize: ${uint8Type.bitSize}`) printInfo(` uint8 byteLen: ${uint8Type.byteLen()}`) printInfo(` uint8 isDynamic: ${uint8Type.isDynamic()}`) } if (uint64Type instanceof ABIUintType) { printInfo(` uint64 bitSize: ${uint64Type.bitSize}`) printInfo(` uint64 byteLen: ${uint64Type.byteLen()}`) } if (uint256Type instanceof ABIUintType) { printInfo(` uint256 bitSize: ${uint256Type.bitSize}`) printInfo(` uint256 byteLen: ${uint256Type.byteLen()}`) }
// Step 2: Parse other primitive types printStep(2, 'Parse Other Primitive Types')
const boolType = ABIType.from('bool') const byteType = ABIType.from('byte') const addressType = ABIType.from('address') const stringType = ABIType.from('string')
printInfo(`Parsed 'bool': ${boolType.toString()}`) printInfo(` bool byteLen: ${boolType.byteLen()}`) printInfo(` bool isDynamic: ${boolType.isDynamic()}`)
printInfo(`Parsed 'byte': ${byteType.toString()}`) printInfo(` byte byteLen: ${byteType.byteLen()}`) printInfo(` byte isDynamic: ${byteType.isDynamic()}`)
printInfo(`Parsed 'address': ${addressType.toString()}`) printInfo(` address byteLen: ${addressType.byteLen()}`) printInfo(` address isDynamic: ${addressType.isDynamic()}`)
printInfo(`Parsed 'string': ${stringType.toString()}`) printInfo(` string isDynamic: ${stringType.isDynamic()}`)
// Step 3: Parse dynamic array types printStep(3, 'Parse Dynamic Array Types')
const uint64ArrayType = ABIType.from('uint64[]') const addressArrayType = ABIType.from('address[]')
printInfo(`Parsed 'uint64[]': ${uint64ArrayType.toString()}`) if (uint64ArrayType instanceof ABIArrayDynamicType) { printInfo(` childType: ${uint64ArrayType.childType.toString()}`) printInfo(` isDynamic: ${uint64ArrayType.isDynamic()}`) }
printInfo(`Parsed 'address[]': ${addressArrayType.toString()}`) if (addressArrayType instanceof ABIArrayDynamicType) { printInfo(` childType: ${addressArrayType.childType.toString()}`) }
// Step 4: Parse static array types printStep(4, 'Parse Static Array Types')
const byte32Type = ABIType.from('byte[32]') const address5Type = ABIType.from('address[5]')
printInfo(`Parsed 'byte[32]': ${byte32Type.toString()}`) if (byte32Type instanceof ABIArrayStaticType) { printInfo(` childType: ${byte32Type.childType.toString()}`) printInfo(` length: ${byte32Type.length}`) printInfo(` byteLen: ${byte32Type.byteLen()}`) printInfo(` isDynamic: ${byte32Type.isDynamic()}`) }
printInfo(`Parsed 'address[5]': ${address5Type.toString()}`) if (address5Type instanceof ABIArrayStaticType) { printInfo(` childType: ${address5Type.childType.toString()}`) printInfo(` length: ${address5Type.length}`) printInfo(` byteLen: ${address5Type.byteLen()}`) }
// Step 5: Parse tuple types printStep(5, 'Parse Tuple Types')
const simpleTupleType = ABIType.from('(uint64,address)') const complexTupleType = ABIType.from('(bool,string,uint256)')
printInfo(`Parsed '(uint64,address)': ${simpleTupleType.toString()}`) if (simpleTupleType instanceof ABITupleType) { printInfo(` childTypes count: ${simpleTupleType.childTypes.length}`) simpleTupleType.childTypes.forEach((childType, index) => { printInfo(` [${index}]: ${childType.toString()}`) }) printInfo(` isDynamic: ${simpleTupleType.isDynamic()}`) printInfo(` byteLen: ${simpleTupleType.byteLen()}`) }
printInfo(`Parsed '(bool,string,uint256)': ${complexTupleType.toString()}`) if (complexTupleType instanceof ABITupleType) { printInfo(` childTypes count: ${complexTupleType.childTypes.length}`) complexTupleType.childTypes.forEach((childType, index) => { printInfo(` [${index}]: ${childType.toString()}`) }) printInfo(` isDynamic: ${complexTupleType.isDynamic()} (contains 'string' which is dynamic)`) }
// Step 6: Parse nested tuple types printStep(6, 'Parse Nested Tuple Types')
const nestedTupleType = ABIType.from('((uint64,bool),address[])')
printInfo(`Parsed '((uint64,bool),address[])': ${nestedTupleType.toString()}`) if (nestedTupleType instanceof ABITupleType) { printInfo(` childTypes count: ${nestedTupleType.childTypes.length}`) nestedTupleType.childTypes.forEach((childType, index) => { printInfo(` [${index}]: ${childType.toString()}`) if (childType instanceof ABITupleType) { childType.childTypes.forEach((nestedChild, nestedIndex) => { printInfo(` [${nestedIndex}]: ${nestedChild.toString()}`) }) } }) printInfo(` isDynamic: ${nestedTupleType.isDynamic()}`) }
// Step 7: Type category detection using instanceof printStep(7, 'Type Category Detection with instanceof')
const testTypes = ['uint64', 'bool', 'byte', 'address', 'string', 'uint64[]', 'byte[32]', '(uint64,address)']
for (const typeStr of testTypes) { const parsedType = ABIType.from(typeStr) let category = 'Unknown'
if (parsedType instanceof ABIUintType) { category = 'UintType' } else if (parsedType instanceof ABIBoolType) { category = 'BoolType' } else if (parsedType instanceof ABIByteType) { category = 'ByteType' } else if (parsedType instanceof ABIAddressType) { category = 'AddressType' } else if (parsedType instanceof ABIStringType) { category = 'StringType' } else if (parsedType instanceof ABIArrayDynamicType) { category = 'ArrayDynamicType' } else if (parsedType instanceof ABIArrayStaticType) { category = 'ArrayStaticType' } else if (parsedType instanceof ABITupleType) { category = 'TupleType' }
printInfo(`'${typeStr}' -> ${category}`) }
// Step 8: Demonstrate type equality printStep(8, 'Type Equality Comparison')
const type1 = ABIType.from('uint64') const type2 = ABIType.from('uint64') const type3 = ABIType.from('uint32')
printInfo(`ABIType.from('uint64').equals(ABIType.from('uint64')): ${type1.equals(type2)}`) printInfo(`ABIType.from('uint64').equals(ABIType.from('uint32')): ${type1.equals(type3)}`)
const tuple1 = ABIType.from('(uint64,address)') const tuple2 = ABIType.from('(uint64,address)') const tuple3 = ABIType.from('(uint64,bool)')
printInfo(`ABIType.from('(uint64,address)').equals(ABIType.from('(uint64,address)')): ${tuple1.equals(tuple2)}`) printInfo(`ABIType.from('(uint64,address)').equals(ABIType.from('(uint64,bool)')): ${tuple1.equals(tuple3)}`)
printSuccess('ABI Type Parsing example completed successfully!')}
main()