Skip to content

Commit

Permalink
Add support for untyped contract args in /write (#747)
Browse files Browse the repository at this point in the history
  • Loading branch information
joaquim-verges authored Oct 31, 2024
1 parent 742e590 commit 05bb234
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 4 deletions.
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

0 comments on commit 05bb234

Please sign in to comment.