Skip to content

Commit 05bb234

Browse files
Add support for untyped contract args in /write (#747)
1 parent 742e590 commit 05bb234

File tree

2 files changed

+101
-4
lines changed

2 files changed

+101
-4
lines changed

src/server/routes/contract/write/write.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { Type, type Static } from "@sinclair/typebox";
1+
import { type Static, Type } from "@sinclair/typebox";
22
import type { FastifyInstance } from "fastify";
33
import { StatusCodes } from "http-status-codes";
44
import { prepareContractCall, resolveMethod } from "thirdweb";
5-
import type { AbiFunction } from "thirdweb/utils";
5+
import { type AbiFunction, parseAbiParams } from "thirdweb/utils";
66
import { getContractV5 } from "../../../../utils/cache/getContractv5";
77
import { prettifyError } from "../../../../utils/error";
88
import { queueTransaction } from "../../../../utils/transaction/queueTransation";
@@ -83,8 +83,13 @@ export async function writeToContract(fastify: FastifyInstance) {
8383
// 3. functionName passed as function name + inferred ABI (fetched at encode time)
8484
// this is all handled inside the `resolveMethod` function
8585
let method: AbiFunction;
86+
let params: Array<string | bigint | boolean | object>;
8687
try {
8788
method = await resolveMethod(functionName)(contract);
89+
params = parseAbiParams(
90+
method.inputs.map((i) => i.type),
91+
args,
92+
);
8893
} catch (e) {
8994
throw createCustomError(
9095
prettifyError(e),
@@ -95,7 +100,7 @@ export async function writeToContract(fastify: FastifyInstance) {
95100
const transaction = prepareContractCall({
96101
contract,
97102
method,
98-
params: args,
103+
params,
99104
...parseTransactionOverrides(txOverrides),
100105
});
101106

test/e2e/tests/write.test.ts

+93-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { beforeAll, describe, expect, test } from "bun:test";
22
import assert from "node:assert";
3-
import type { Address } from "thirdweb";
3+
import { type Address, stringToHex } from "thirdweb";
44
import { zeroAddress } from "viem";
55
import type { ApiError } from "../../../sdk/dist/thirdweb-dev-engine.cjs";
66
import { CONFIG } from "../config";
@@ -69,6 +69,98 @@ describe("Write Tests", () => {
6969
expect(writeTransactionStatus.minedAt).toBeDefined();
7070
});
7171

72+
test.only("Write to a contract with untyped args", async () => {
73+
const res = await engine.deploy.deployNftDrop(
74+
CONFIG.CHAIN.id.toString(),
75+
backendWallet,
76+
{
77+
contractMetadata: {
78+
name: "test token",
79+
platform_fee_basis_points: 0,
80+
platform_fee_recipient: zeroAddress,
81+
symbol: "TT",
82+
trusted_forwarders: [],
83+
seller_fee_basis_points: 0,
84+
fee_recipient: zeroAddress,
85+
},
86+
},
87+
);
88+
89+
expect(res.result.queueId).toBeDefined();
90+
assert(res.result.queueId, "queueId must be defined");
91+
expect(res.result.deployedAddress).toBeDefined();
92+
const nftDropContractAddress = res.result.deployedAddress;
93+
94+
if (!nftDropContractAddress) {
95+
throw new Error("nftDropContractAddress must be defined");
96+
}
97+
98+
const transactionStatus = await pollTransactionStatus(
99+
engine,
100+
res.result.queueId,
101+
true,
102+
);
103+
104+
expect(transactionStatus.minedAt).toBeDefined();
105+
const writeRes = await engine.contract.write(
106+
CONFIG.CHAIN.id.toString(),
107+
nftDropContractAddress,
108+
backendWallet,
109+
{
110+
functionName: "setApprovalForAll",
111+
args: [
112+
"0x1234567890123456789012345678901234567890",
113+
"true", // string instead of bool
114+
],
115+
},
116+
);
117+
118+
expect(writeRes.result.queueId).toBeDefined();
119+
120+
const writeTransactionStatus = await pollTransactionStatus(
121+
engine,
122+
writeRes.result.queueId,
123+
true,
124+
);
125+
126+
expect(writeTransactionStatus.minedAt).toBeDefined();
127+
128+
const writeRes2 = await engine.contract.write(
129+
CONFIG.CHAIN.id.toString(),
130+
nftDropContractAddress,
131+
backendWallet,
132+
{
133+
functionName: "setClaimConditions",
134+
args: [
135+
// stringified array of structs
136+
JSON.stringify([
137+
{
138+
startTimestamp: "0",
139+
maxClaimableSupply: "100000",
140+
supplyClaimed: "0",
141+
quantityLimitPerWallet: "10",
142+
merkleRoot: stringToHex("", { size: 32 }),
143+
pricePerToken: "0",
144+
currency: zeroAddress,
145+
metadata: "",
146+
},
147+
]),
148+
"false",
149+
],
150+
},
151+
);
152+
153+
expect(writeRes2.result.queueId).toBeDefined();
154+
155+
const writeTransactionStatus2 = await pollTransactionStatus(
156+
engine,
157+
writeRes2.result.queueId,
158+
true,
159+
);
160+
161+
expect(writeTransactionStatus2.minedAt).toBeDefined();
162+
});
163+
72164
test("Write to a contract with function signature", async () => {
73165
const writeRes = await engine.contract.write(
74166
CONFIG.CHAIN.id.toString(),

0 commit comments

Comments
 (0)