Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/server/routes/contract/write/write.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Type, type Static } from "@sinclair/typebox";
import { type Static, Type } from "@sinclair/typebox";
import type { FastifyInstance } from "fastify";
import { StatusCodes } from "http-status-codes";
import { prepareContractCall, resolveMethod } from "thirdweb";
import type { AbiFunction } from "thirdweb/utils";
import { type AbiFunction, parseAbiParams } from "thirdweb/utils";
import { getContractV5 } from "../../../../utils/cache/getContractv5";
import { prettifyError } from "../../../../utils/error";
import { queueTransaction } from "../../../../utils/transaction/queueTransation";
Expand Down Expand Up @@ -83,8 +83,13 @@ export async function writeToContract(fastify: FastifyInstance) {
// 3. functionName passed as function name + inferred ABI (fetched at encode time)
// this is all handled inside the `resolveMethod` function
let method: AbiFunction;
let params: Array<string | bigint | boolean | object>;
try {
method = await resolveMethod(functionName)(contract);
params = parseAbiParams(
method.inputs.map((i) => i.type),
args,
);
} catch (e) {
throw createCustomError(
prettifyError(e),
Expand All @@ -95,7 +100,7 @@ export async function writeToContract(fastify: FastifyInstance) {
const transaction = prepareContractCall({
contract,
method,
params: args,
params,
...parseTransactionOverrides(txOverrides),
});

Expand Down
94 changes: 93 additions & 1 deletion test/e2e/tests/write.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { beforeAll, describe, expect, test } from "bun:test";
import assert from "node:assert";
import type { Address } from "thirdweb";
import { type Address, stringToHex } from "thirdweb";
import { zeroAddress } from "viem";
import type { ApiError } from "../../../sdk/dist/thirdweb-dev-engine.cjs";
import { CONFIG } from "../config";
Expand Down Expand Up @@ -69,6 +69,98 @@ describe("Write Tests", () => {
expect(writeTransactionStatus.minedAt).toBeDefined();
});

test.only("Write to a contract with untyped args", async () => {
const res = await engine.deploy.deployNftDrop(
CONFIG.CHAIN.id.toString(),
backendWallet,
{
contractMetadata: {
name: "test token",
platform_fee_basis_points: 0,
platform_fee_recipient: zeroAddress,
symbol: "TT",
trusted_forwarders: [],
seller_fee_basis_points: 0,
fee_recipient: zeroAddress,
},
},
);

expect(res.result.queueId).toBeDefined();
assert(res.result.queueId, "queueId must be defined");
expect(res.result.deployedAddress).toBeDefined();
const nftDropContractAddress = res.result.deployedAddress;

if (!nftDropContractAddress) {
throw new Error("nftDropContractAddress must be defined");
}

const transactionStatus = await pollTransactionStatus(
engine,
res.result.queueId,
true,
);

expect(transactionStatus.minedAt).toBeDefined();
const writeRes = await engine.contract.write(
CONFIG.CHAIN.id.toString(),
nftDropContractAddress,
backendWallet,
{
functionName: "setApprovalForAll",
args: [
"0x1234567890123456789012345678901234567890",
"true", // string instead of bool
],
},
);

expect(writeRes.result.queueId).toBeDefined();

const writeTransactionStatus = await pollTransactionStatus(
engine,
writeRes.result.queueId,
true,
);

expect(writeTransactionStatus.minedAt).toBeDefined();

const writeRes2 = await engine.contract.write(
CONFIG.CHAIN.id.toString(),
nftDropContractAddress,
backendWallet,
{
functionName: "setClaimConditions",
args: [
// stringified array of structs
JSON.stringify([
{
startTimestamp: "0",
maxClaimableSupply: "100000",
supplyClaimed: "0",
quantityLimitPerWallet: "10",
merkleRoot: stringToHex("", { size: 32 }),
pricePerToken: "0",
currency: zeroAddress,
metadata: "",
},
]),
"false",
],
},
);

expect(writeRes2.result.queueId).toBeDefined();

const writeTransactionStatus2 = await pollTransactionStatus(
engine,
writeRes2.result.queueId,
true,
);

expect(writeTransactionStatus2.minedAt).toBeDefined();
});

test("Write to a contract with function signature", async () => {
const writeRes = await engine.contract.write(
CONFIG.CHAIN.id.toString(),
Expand Down
Loading