1
1
import { Type } from "@sinclair/typebox" ;
2
2
import type { FastifyInstance } from "fastify" ;
3
3
import { 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 , resolveMethod } from "thirdweb" ;
6
+ import { parseAbiParams } from "thirdweb/utils" ;
7
+ import type { AbiFunction } from "thirdweb/utils" ;
8
+ import { getContractV5 } from "../../../../shared/utils/cache/get-contractv5" ;
5
9
import { prettifyError } from "../../../../shared/utils/error" ;
6
10
import { createCustomError } from "../../../middleware/error" ;
7
11
import {
@@ -12,6 +16,8 @@ import {
12
16
partialRouteSchema ,
13
17
standardResponseSchema ,
14
18
} from "../../../schemas/shared-api-schemas" ;
19
+ import { sanitizeFunctionName } from "../../../utils/abi" ;
20
+ import { sanitizeAbi } from "../../../utils/abi" ;
15
21
import { getChainIdFromChain } from "../../../utils/chain" ;
16
22
import { bigNumberReplacer } from "../../../utils/convertor" ;
17
23
@@ -37,12 +43,13 @@ export async function readContract(fastify: FastifyInstance) {
37
43
} ,
38
44
handler : async ( request , reply ) => {
39
45
const { chain, contractAddress } = request . params ;
40
- const { functionName, args } = request . query ;
46
+ const { functionName, args, abi } = request . query ;
41
47
42
48
const chainId = await getChainIdFromChain ( chain ) ;
43
- const contract = await getContract ( {
49
+ const contract = await getContractV5 ( {
44
50
chainId,
45
51
contractAddress,
52
+ abi : sanitizeAbi ( abi ) ,
46
53
} ) ;
47
54
48
55
let parsedArgs : unknown [ ] | undefined ;
@@ -54,19 +61,33 @@ export async function readContract(fastify: FastifyInstance) {
54
61
// fallback to string split
55
62
}
56
63
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
- } ) ;
64
+ parsedArgs ??= args ?. split ( "," ) ;
65
+
66
+ // 3 possible ways to get function from abi:
67
+ // 1. functionName passed as solidity signature
68
+ // 2. functionName passed as function name + passed in ABI
69
+ // 3. functionName passed as function name + inferred ABI (fetched at encode time)
70
+ // this is all handled inside the `resolveMethod` function
71
+ let method : AbiFunction ;
72
+ let params : Array < string | bigint | boolean | object > ;
73
+ try {
74
+ const functionNameOrSignature = sanitizeFunctionName ( functionName ) ;
75
+ method = await resolveMethod ( functionNameOrSignature ) ( contract ) ;
76
+ params = parseAbiParams (
77
+ method . inputs . map ( ( i : AbiParameters . Parameter ) => i . type ) ,
78
+ parsedArgs ?? [ ] ,
79
+ ) ;
80
+ } catch ( e ) {
81
+ throw createCustomError (
82
+ prettifyError ( e ) ,
83
+ StatusCodes . BAD_REQUEST ,
84
+ "BAD_REQUEST" ,
85
+ ) ;
86
+ }
66
87
67
88
let returnData : unknown ;
68
89
try {
69
- returnData = await contract . call ( functionName , parsedArgs ?? [ ] ) ;
90
+ returnData = await readContractV5 ( { contract , method , params } ) ;
70
91
} catch ( e ) {
71
92
throw createCustomError (
72
93
prettifyError ( e ) ,
0 commit comments