diff --git a/src/server/routes/contract/read/read.ts b/src/server/routes/contract/read/read.ts index fb6cb9ddd..46dc8fffd 100644 --- a/src/server/routes/contract/read/read.ts +++ b/src/server/routes/contract/read/read.ts @@ -43,7 +43,16 @@ export async function readContract(fastify: FastifyInstance) { contractAddress, }); - const parsedArgs = args?.split(",").map((arg) => { + let parsedArgs: unknown[] | undefined = []; + + try { + const jsonStringArgs = `[${args}]`; + parsedArgs = JSON.parse(jsonStringArgs); + } catch { + // fallback to string split + } + + parsedArgs ??= args?.split(",").map((arg) => { if (arg === "true") { return true; } diff --git a/src/server/utils/convertor.ts b/src/server/utils/convertor.ts index 722ba8fab..7082e53c9 100644 --- a/src/server/utils/convertor.ts +++ b/src/server/utils/convertor.ts @@ -1,6 +1,6 @@ import { BigNumber } from "ethers"; -export const bigNumberReplacer = (value: any): string => { +export const bigNumberReplacer = (value: any): any => { // if we find a BigNumber then make it into a string (since that is safe) if ( BigNumber.isBigNumber(value) || @@ -11,5 +11,10 @@ export const bigNumberReplacer = (value: any): string => { ) { return BigNumber.from(value).toString(); } + + if (Array.isArray(value)) { + return value.map(bigNumberReplacer); + } + return value; }; diff --git a/test/e2e/tests/read.test.ts b/test/e2e/tests/read.test.ts new file mode 100644 index 000000000..b1612b55d --- /dev/null +++ b/test/e2e/tests/read.test.ts @@ -0,0 +1,38 @@ +import { beforeAll, describe, test } from "bun:test"; +import { sepolia } from "thirdweb/chains"; +import { expect } from "vitest"; +import type { setupEngine } from "../utils/engine"; +import { setup } from "./setup"; + +const structContractAddress = "0x83ca896ef0a66d39f0e6fcc1a93c0a09366b85b1"; +const chainIdString = sepolia.id.toString(); + +describe("Read Tests", () => { + let engine: ReturnType; + + beforeAll(async () => { + const { engine: _engine, backendWallet: _backendWallet } = await setup(); + engine = _engine; + }); + + test("Read a contract method with struct and number params", async () => { + const structValues = { + name: "test", + value: 123, + }; + + const structString = JSON.stringify(structValues); + + const { result } = await engine.contract.read( + "readStructAndInts", + chainIdString, + structContractAddress, + `${structString},1,2`, + ); + + expect(result[0]).toEqual("test"); + expect(result[1]).toEqual("123"); + expect(result[2]).toEqual("1"); + expect(result[3]).toEqual("2"); + }); +});