From e8a172a4cecd9dcab27d25957237284a2a3eaddb Mon Sep 17 00:00:00 2001 From: Joaquim Verges Date: Fri, 23 May 2025 11:30:33 -0700 Subject: [PATCH] [thirdweb] Ensure bigints are stringified before usage with server wallets --- .changeset/whole-pears-stay.md | 5 +++ packages/engine/src/configure.ts | 19 +++++++++++ packages/thirdweb/src/engine/get-status.ts | 1 + .../thirdweb/src/engine/server-wallet.test.ts | 32 +++++++++---------- packages/thirdweb/src/engine/server-wallet.ts | 5 ++- 5 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 .changeset/whole-pears-stay.md diff --git a/.changeset/whole-pears-stay.md b/.changeset/whole-pears-stay.md new file mode 100644 index 00000000000..3ba27696711 --- /dev/null +++ b/.changeset/whole-pears-stay.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Ensure bigints are stringified before usage with server wallets diff --git a/packages/engine/src/configure.ts b/packages/engine/src/configure.ts index 6bd913d8f52..4906cbe85b1 100644 --- a/packages/engine/src/configure.ts +++ b/packages/engine/src/configure.ts @@ -14,6 +14,25 @@ export function configure( ...(options.clientId && { "x-client-id": options.clientId }), ...(options.secretKey && { "x-secret-key": options.secretKey }), }, + bodySerializer: stringify, ...(options.override ?? {}), }); } + +function stringify( + // biome-ignore lint/suspicious/noExplicitAny: JSON.stringify signature + value: any, + // biome-ignore lint/suspicious/noExplicitAny: JSON.stringify signature + replacer?: ((this: any, key: string, value: any) => any) | null, + space?: string | number, +) { + const res = JSON.stringify( + value, + (key, value_) => { + const value__ = typeof value_ === "bigint" ? value_.toString() : value_; + return typeof replacer === "function" ? replacer(key, value__) : value__; + }, + space, + ); + return res; +} diff --git a/packages/thirdweb/src/engine/get-status.ts b/packages/thirdweb/src/engine/get-status.ts index c2a042014d0..7f84315c743 100644 --- a/packages/thirdweb/src/engine/get-status.ts +++ b/packages/thirdweb/src/engine/get-status.ts @@ -79,6 +79,7 @@ export async function getTransactionStatus(args: { const { client, transactionId } = args; const searchResult = await searchTransactions({ baseUrl: getThirdwebBaseUrl("engineCloud"), + bodySerializer: stringify, fetch: getClientFetch(client), body: { filters: [ diff --git a/packages/thirdweb/src/engine/server-wallet.test.ts b/packages/thirdweb/src/engine/server-wallet.test.ts index f5eb8fd8699..eeb059eff69 100644 --- a/packages/thirdweb/src/engine/server-wallet.test.ts +++ b/packages/thirdweb/src/engine/server-wallet.test.ts @@ -3,13 +3,14 @@ import { TEST_CLIENT } from "../../test/src/test-clients.js"; import { TEST_ACCOUNT_B } from "../../test/src/test-wallets.js"; import { typedData } from "../../test/src/typed-data.js"; import { arbitrumSepolia } from "../chains/chain-definitions/arbitrum-sepolia.js"; +import { baseSepolia } from "../chains/chain-definitions/base-sepolia.js"; import { sepolia } from "../chains/chain-definitions/sepolia.js"; import { getContract } from "../contract/contract.js"; import { setContractURI } from "../extensions/common/__generated__/IContractMetadata/write/setContractURI.js"; +import { mintTo } from "../extensions/erc20/write/mintTo.js"; import { claimTo } from "../extensions/erc1155/drops/write/claimTo.js"; import { getAllActiveSigners } from "../extensions/erc4337/__generated__/IAccountPermissions/read/getAllActiveSigners.js"; import { sendTransaction } from "../transaction/actions/send-transaction.js"; -import { setThirdwebDomains } from "../utils/domains.js"; import { DEFAULT_ACCOUNT_FACTORY_V0_6, ENTRYPOINT_ADDRESS_v0_6, @@ -32,12 +33,12 @@ describe.runIf( let serverWallet: Engine.ServerWallet; beforeAll(async () => { - setThirdwebDomains({ - rpc: "rpc.thirdweb-dev.com", - storage: "storage.thirdweb-dev.com", - bundler: "bundler.thirdweb-dev.com", - engineCloud: "engine.thirdweb-dev.com", - }); + // setThirdwebDomains({ + // rpc: "rpc.thirdweb-dev.com", + // storage: "storage.thirdweb-dev.com", + // bundler: "bundler.thirdweb-dev.com", + // engineCloud: "engine.thirdweb-dev.com", + // }); serverWallet = Engine.serverWallet({ client: TEST_CLIENT, vaultAccessToken: process.env.VAULT_TOKEN as string, @@ -81,7 +82,7 @@ describe.runIf( }); const claimTx = claimTo({ contract: nftContract, - to: TEST_ACCOUNT_B.address, + to: serverWallet.address, tokenId: 0n, quantity: 1n, }); @@ -97,16 +98,15 @@ describe.runIf( }); it("should send a extension tx", async () => { - const nftContract = getContract({ + const tokenContract = getContract({ client: TEST_CLIENT, - chain: sepolia, - address: "0xe2cb0eb5147b42095c2FfA6F7ec953bb0bE347D8", + chain: baseSepolia, + address: "0x87C52295891f208459F334975a3beE198fE75244", }); - const claimTx = claimTo({ - contract: nftContract, - to: TEST_ACCOUNT_B.address, - tokenId: 0n, - quantity: 1n, + const claimTx = mintTo({ + contract: tokenContract, + to: serverWallet.address, + amount: "0.001", }); const tx = await sendTransaction({ account: serverWallet, diff --git a/packages/thirdweb/src/engine/server-wallet.ts b/packages/thirdweb/src/engine/server-wallet.ts index f036ca55e84..5ce2041d7b0 100644 --- a/packages/thirdweb/src/engine/server-wallet.ts +++ b/packages/thirdweb/src/engine/server-wallet.ts @@ -144,13 +144,14 @@ export function serverWallet(options: ServerWalletOptions): ServerWallet { const result = await sendTransaction({ baseUrl: getThirdwebBaseUrl("engineCloud"), + bodySerializer: stringify, fetch: getClientFetch(client), headers, body, }); if (result.error) { - throw new Error(`Error sending transaction: ${result.error}`); + throw new Error(`Error sending transaction: ${stringify(result.error)}`); } const data = result.data?.result; @@ -220,6 +221,7 @@ export function serverWallet(options: ServerWalletOptions): ServerWallet { const signResult = await signMessage({ baseUrl: getThirdwebBaseUrl("engineCloud"), + bodySerializer: stringify, fetch: getClientFetch(client), headers, body: { @@ -256,6 +258,7 @@ export function serverWallet(options: ServerWalletOptions): ServerWallet { const signResult = await signTypedData({ baseUrl: getThirdwebBaseUrl("engineCloud"), + bodySerializer: stringify, fetch: getClientFetch(client), headers, body: {