@@ -823,6 +823,284 @@ describe('Result Decoder', () => {
823823 } )
824824 } )
825825
826+ describe ( 'Type aliases and hex decoding' , ( ) => {
827+ it ( 'should decode usize as u32' , ( ) => {
828+ const mockABI : ContractABI = {
829+ buildInfo : {
830+ rustc : { version : '1.0' , commitHash : '' , commitDate : '' , channel : 'Stable' , short : '' } ,
831+ contractCrate : { name : 'test' , version : '1.0' } ,
832+ framework : { name : 'klever-sc' , version : '1.0' } ,
833+ } ,
834+ name : 'Test' ,
835+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
836+ upgradeConstructor : { name : 'upgrade' , inputs : [ ] , outputs : [ ] } ,
837+ endpoints : [
838+ {
839+ name : 'getSize' ,
840+ mutability : 'readonly' ,
841+ inputs : [ ] ,
842+ outputs : [ { name : 'value' , type : 'usize' } ] ,
843+ } ,
844+ ] ,
845+ kdaAttributes : [ ] ,
846+ types : { } ,
847+ }
848+
849+ const decoder = new ABIDecoder ( mockABI )
850+
851+ const data = [ encodeBase64 ( new Uint8Array ( [ 0x00 , 0x00 , 0x00 , 0x64 ] ) ) ] // 100
852+ const result = decoder . decodeFunctionResultsWithMetadata ( 'getSize' , data )
853+
854+ expect ( result . values [ 0 ] ?. value ) . toBe ( 100 )
855+ expect ( result . values [ 0 ] ?. type ) . toBe ( 'usize' )
856+ } )
857+
858+ it ( 'should decode isize as i32' , ( ) => {
859+ const mockABI : ContractABI = {
860+ buildInfo : {
861+ rustc : { version : '1.0' , commitHash : '' , commitDate : '' , channel : 'Stable' , short : '' } ,
862+ contractCrate : { name : 'test' , version : '1.0' } ,
863+ framework : { name : 'klever-sc' , version : '1.0' } ,
864+ } ,
865+ name : 'Test' ,
866+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
867+ upgradeConstructor : { name : 'upgrade' , inputs : [ ] , outputs : [ ] } ,
868+ endpoints : [
869+ {
870+ name : 'getIndex' ,
871+ mutability : 'readonly' ,
872+ inputs : [ ] ,
873+ outputs : [ { name : 'value' , type : 'isize' } ] ,
874+ } ,
875+ ] ,
876+ kdaAttributes : [ ] ,
877+ types : { } ,
878+ }
879+
880+ const decoder = new ABIDecoder ( mockABI )
881+
882+ // -100 in two's complement = 0xffffff9c
883+ const data = [ encodeBase64 ( new Uint8Array ( [ 0xff , 0xff , 0xff , 0x9c ] ) ) ]
884+ const result = decoder . decodeFunctionResultsWithMetadata ( 'getIndex' , data )
885+
886+ expect ( result . values [ 0 ] ?. value ) . toBe ( - 100 )
887+ expect ( result . values [ 0 ] ?. type ) . toBe ( 'isize' )
888+ } )
889+
890+ it ( 'should decode boolean as bool' , ( ) => {
891+ const mockABI : ContractABI = {
892+ buildInfo : {
893+ rustc : { version : '1.0' , commitHash : '' , commitDate : '' , channel : 'Stable' , short : '' } ,
894+ contractCrate : { name : 'test' , version : '1.0' } ,
895+ framework : { name : 'klever-sc' , version : '1.0' } ,
896+ } ,
897+ name : 'Test' ,
898+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
899+ upgradeConstructor : { name : 'upgrade' , inputs : [ ] , outputs : [ ] } ,
900+ endpoints : [
901+ {
902+ name : 'getFlag' ,
903+ mutability : 'readonly' ,
904+ inputs : [ ] ,
905+ outputs : [ { name : 'value' , type : 'boolean' } ] ,
906+ } ,
907+ ] ,
908+ kdaAttributes : [ ] ,
909+ types : { } ,
910+ }
911+
912+ const decoder = new ABIDecoder ( mockABI )
913+
914+ const trueData = [ encodeBase64 ( new Uint8Array ( [ 0x01 ] ) ) ]
915+ const trueResult = decoder . decodeFunctionResultsWithMetadata ( 'getFlag' , trueData )
916+ expect ( trueResult . values [ 0 ] ?. value ) . toBe ( true )
917+ expect ( trueResult . values [ 0 ] ?. type ) . toBe ( 'boolean' )
918+
919+ const falseData = [ encodeBase64 ( new Uint8Array ( [ 0x00 ] ) ) ]
920+ const falseResult = decoder . decodeFunctionResultsWithMetadata ( 'getFlag' , falseData )
921+ expect ( falseResult . values [ 0 ] ?. value ) . toBe ( false )
922+ } )
923+
924+ it ( 'should decode hex type as hex string passthrough' , ( ) => {
925+ const mockABI : ContractABI = {
926+ buildInfo : {
927+ rustc : { version : '1.0' , commitHash : '' , commitDate : '' , channel : 'Stable' , short : '' } ,
928+ contractCrate : { name : 'test' , version : '1.0' } ,
929+ framework : { name : 'klever-sc' , version : '1.0' } ,
930+ } ,
931+ name : 'Test' ,
932+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
933+ upgradeConstructor : { name : 'upgrade' , inputs : [ ] , outputs : [ ] } ,
934+ endpoints : [
935+ {
936+ name : 'getRaw' ,
937+ mutability : 'readonly' ,
938+ inputs : [ ] ,
939+ outputs : [ { name : 'value' , type : 'hex' } ] ,
940+ } ,
941+ ] ,
942+ kdaAttributes : [ ] ,
943+ types : { } ,
944+ }
945+
946+ const decoder = new ABIDecoder ( mockABI )
947+
948+ const data = [ encodeBase64 ( new Uint8Array ( [ 0xca , 0xfe , 0xba , 0xbe ] ) ) ]
949+ const result = decoder . decodeFunctionResultsWithMetadata ( 'getRaw' , data )
950+
951+ expect ( result . values [ 0 ] ?. value ) . toBe ( 'cafebabe' )
952+ expect ( result . values [ 0 ] ?. type ) . toBe ( 'hex' )
953+ } )
954+
955+ it ( 'should decode empty hex' , ( ) => {
956+ const mockABI : ContractABI = {
957+ buildInfo : {
958+ rustc : { version : '1.0' , commitHash : '' , commitDate : '' , channel : 'Stable' , short : '' } ,
959+ contractCrate : { name : 'test' , version : '1.0' } ,
960+ framework : { name : 'klever-sc' , version : '1.0' } ,
961+ } ,
962+ name : 'Test' ,
963+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
964+ upgradeConstructor : { name : 'upgrade' , inputs : [ ] , outputs : [ ] } ,
965+ endpoints : [
966+ {
967+ name : 'getRaw' ,
968+ mutability : 'readonly' ,
969+ inputs : [ ] ,
970+ outputs : [ { name : 'value' , type : 'hex' } ] ,
971+ } ,
972+ ] ,
973+ kdaAttributes : [ ] ,
974+ types : { } ,
975+ }
976+
977+ const decoder = new ABIDecoder ( mockABI )
978+
979+ const data = [ encodeBase64 ( new Uint8Array ( [ ] ) ) ]
980+ const result = decoder . decodeFunctionResultsWithMetadata ( 'getRaw' , data )
981+
982+ expect ( result . values [ 0 ] ?. value ) . toBe ( '' )
983+ } )
984+
985+ it ( 'should round-trip usize encode/decode' , async ( ) => {
986+ const { ABIEncoder } = await import ( '../encoder/abi-encoder' )
987+
988+ const mockABI : ContractABI = {
989+ name : 'Test' ,
990+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
991+ endpoints : [ ] ,
992+ types : { } ,
993+ }
994+
995+ const encoder = new ABIEncoder ( mockABI )
996+ const decoder = new ABIDecoder ( mockABI )
997+
998+ const encoded = encoder . encodeValue ( 42 , 'usize' )
999+ const decoded = decoder . decodeValue ( encoded , 'usize' )
1000+ expect ( decoded ) . toBe ( 42 )
1001+ } )
1002+
1003+ it ( 'should round-trip isize encode/decode' , async ( ) => {
1004+ const { ABIEncoder } = await import ( '../encoder/abi-encoder' )
1005+
1006+ const mockABI : ContractABI = {
1007+ name : 'Test' ,
1008+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
1009+ endpoints : [ ] ,
1010+ types : { } ,
1011+ }
1012+
1013+ const encoder = new ABIEncoder ( mockABI )
1014+ const decoder = new ABIDecoder ( mockABI )
1015+
1016+ const encoded = encoder . encodeValue ( - 50 , 'isize' )
1017+ const decoded = decoder . decodeValue ( encoded , 'isize' )
1018+ expect ( decoded ) . toBe ( - 50 )
1019+ } )
1020+
1021+ it ( 'should round-trip hex encode/decode' , async ( ) => {
1022+ const { ABIEncoder } = await import ( '../encoder/abi-encoder' )
1023+
1024+ const mockABI : ContractABI = {
1025+ name : 'Test' ,
1026+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
1027+ endpoints : [ ] ,
1028+ types : { } ,
1029+ }
1030+
1031+ const encoder = new ABIEncoder ( mockABI )
1032+ const decoder = new ABIDecoder ( mockABI )
1033+
1034+ const encoded = encoder . encodeValue ( 'deadbeef' , 'hex' )
1035+ const decoded = decoder . decodeValue ( encoded , 'hex' )
1036+ expect ( decoded ) . toBe ( 'deadbeef' )
1037+ } )
1038+ } )
1039+
1040+ describe ( 'String/Bytes aliases decoding' , ( ) => {
1041+ it ( 'should decode String alias as string' , async ( ) => {
1042+ const { ABIEncoder } = await import ( '../encoder/abi-encoder' )
1043+
1044+ const mockABI : ContractABI = {
1045+ name : 'Test' ,
1046+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
1047+ endpoints : [ ] ,
1048+ types : { } ,
1049+ }
1050+
1051+ const encoder = new ABIEncoder ( mockABI )
1052+ const decoder = new ABIDecoder ( mockABI )
1053+
1054+ for ( const type of [ 'String' , '&str' , 'ManagedBuffer' ] ) {
1055+ const encoded = encoder . encodeValue ( 'hello' , type )
1056+ const decoded = decoder . decodeValue ( encoded , type )
1057+ expect ( decoded ) . toBe ( 'hello' )
1058+ }
1059+ } )
1060+
1061+ it ( 'should decode bytes aliases as bytes' , async ( ) => {
1062+ const { ABIEncoder } = await import ( '../encoder/abi-encoder' )
1063+
1064+ const mockABI : ContractABI = {
1065+ name : 'Test' ,
1066+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
1067+ endpoints : [ ] ,
1068+ types : { } ,
1069+ }
1070+
1071+ const encoder = new ABIEncoder ( mockABI )
1072+ const decoder = new ABIDecoder ( mockABI )
1073+ const data = new Uint8Array ( [ 0x01 , 0x02 , 0x03 ] )
1074+
1075+ for ( const type of [ 'BoxedBytes' , 'Vec<u8>' , '&[u8]' ] ) {
1076+ const encoded = encoder . encodeValue ( data , type )
1077+ const decoded = decoder . decodeValue ( encoded , type ) as Uint8Array
1078+ expect ( Array . from ( decoded ) ) . toEqual ( [ 1 , 2 , 3 ] )
1079+ }
1080+ } )
1081+
1082+ it ( 'should decode Address aliases' , ( ) => {
1083+ const mockABI : ContractABI = {
1084+ name : 'Test' ,
1085+ constructor : { name : 'init' , inputs : [ ] , outputs : [ ] } ,
1086+ endpoints : [ ] ,
1087+ types : { } ,
1088+ }
1089+
1090+ const decoder = new ABIDecoder ( mockABI )
1091+
1092+ // 32-byte zero address
1093+ const bytes = new Uint8Array ( 32 ) . fill ( 0 )
1094+
1095+ const decodedAddress = decoder . decodeValue ( bytes , 'Address' )
1096+ const decodedA = decoder . decodeValue ( bytes , 'a' )
1097+ const decodedBigA = decoder . decodeValue ( bytes , 'A' )
1098+
1099+ expect ( decodedA ) . toBe ( decodedAddress )
1100+ expect ( decodedBigA ) . toBe ( decodedAddress )
1101+ } )
1102+ } )
1103+
8261104 describe ( 'multi-output endpoints (no variadic)' , ( ) => {
8271105 it ( 'should decode multiple separate outputs' , ( ) => {
8281106 const mockABI : ContractABI = {
0 commit comments