11import { Type } from "@sinclair/typebox" ;
22import type { FastifyInstance } from "fastify" ;
33import { StatusCodes } from "http-status-codes" ;
4- import { getContract } from "../../../../shared/utils/cache/get-contract" ;
4+ import type { AbiParameters } from "ox" ;
5+ import { readContract as readContractV5 } from "thirdweb" ;
6+ import { resolveMethod } from "thirdweb/dist/types/transaction/resolve-method" ;
7+ import { parseAbiParams } from "thirdweb/utils" ;
8+ import type { AbiFunction } from "thirdweb/utils" ;
9+ import { getContractV5 } from "../../../../shared/utils/cache/get-contractv5" ;
510import { prettifyError } from "../../../../shared/utils/error" ;
611import { createCustomError } from "../../../middleware/error" ;
712import {
@@ -12,6 +17,8 @@ import {
1217 partialRouteSchema ,
1318 standardResponseSchema ,
1419} from "../../../schemas/shared-api-schemas" ;
20+ import { sanitizeFunctionName } from "../../../utils/abi" ;
21+ import { sanitizeAbi } from "../../../utils/abi" ;
1522import { getChainIdFromChain } from "../../../utils/chain" ;
1623import { bigNumberReplacer } from "../../../utils/convertor" ;
1724
@@ -37,12 +44,13 @@ export async function readContract(fastify: FastifyInstance) {
3744 } ,
3845 handler : async ( request , reply ) => {
3946 const { chain, contractAddress } = request . params ;
40- const { functionName, args } = request . query ;
47+ const { functionName, args, abi } = request . query ;
4148
4249 const chainId = await getChainIdFromChain ( chain ) ;
43- const contract = await getContract ( {
50+ const contract = await getContractV5 ( {
4451 chainId,
4552 contractAddress,
53+ abi : sanitizeAbi ( abi ) ,
4654 } ) ;
4755
4856 let parsedArgs : unknown [ ] | undefined ;
@@ -54,19 +62,33 @@ export async function readContract(fastify: FastifyInstance) {
5462 // fallback to string split
5563 }
5664
57- parsedArgs ??= args ?. split ( "," ) . map ( ( arg ) => {
58- if ( arg === "true" ) {
59- return true ;
60- }
61- if ( arg === "false" ) {
62- return false ;
63- }
64- return arg ;
65- } ) ;
65+ parsedArgs ??= args ?. split ( "," ) ;
66+
67+ // 3 possible ways to get function from abi:
68+ // 1. functionName passed as solidity signature
69+ // 2. functionName passed as function name + passed in ABI
70+ // 3. functionName passed as function name + inferred ABI (fetched at encode time)
71+ // this is all handled inside the `resolveMethod` function
72+ let method : AbiFunction ;
73+ let params : Array < string | bigint | boolean | object > ;
74+ try {
75+ const functionNameOrSignature = sanitizeFunctionName ( functionName ) ;
76+ method = await resolveMethod ( functionNameOrSignature ) ( contract ) ;
77+ params = parseAbiParams (
78+ method . inputs . map ( ( i : AbiParameters . Parameter ) => i . type ) ,
79+ parsedArgs ?? [ ] ,
80+ ) ;
81+ } catch ( e ) {
82+ throw createCustomError (
83+ prettifyError ( e ) ,
84+ StatusCodes . BAD_REQUEST ,
85+ "BAD_REQUEST" ,
86+ ) ;
87+ }
6688
6789 let returnData : unknown ;
6890 try {
69- returnData = await contract . call ( functionName , parsedArgs ?? [ ] ) ;
91+ returnData = await readContractV5 ( { contract , method , params } ) ;
7092 } catch ( e ) {
7193 throw createCustomError (
7294 prettifyError ( e ) ,
0 commit comments