diff --git a/.changeset/yummy-sloths-live.md b/.changeset/yummy-sloths-live.md new file mode 100644 index 00000000000..f1c6939de1c --- /dev/null +++ b/.changeset/yummy-sloths-live.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Fix getCallStatus via EIP1193 provider diff --git a/apps/wagmi-demo/src/App.tsx b/apps/wagmi-demo/src/App.tsx index 1693c705a44..6009f45deaa 100644 --- a/apps/wagmi-demo/src/App.tsx +++ b/apps/wagmi-demo/src/App.tsx @@ -1,13 +1,14 @@ import type { ConnectionOptions } from "@thirdweb-dev/wagmi-adapter"; import { ConnectButton } from "thirdweb/react"; +import { stringify } from "thirdweb/utils"; import { createWallet } from "thirdweb/wallets"; import { useAccount, - useCallsStatus, useConnect, useDisconnect, useSendCalls, useSendTransaction, + useWaitForCallsStatus, } from "wagmi"; import { chain, client, thirdwebChainForWallet, wallet } from "./wagmi.js"; @@ -28,7 +29,7 @@ function App() { data: callStatus, isLoading: isLoadingCallStatus, error: callStatusError, - } = useCallsStatus({ + } = useWaitForCallsStatus({ id: data?.id || "", query: { enabled: !!data?.id, @@ -42,7 +43,7 @@ function App() {
status: {account.status}
- addresses: {JSON.stringify(account.addresses)} + addresses: {stringify(account.addresses)}
chainId: {account.chainId}
@@ -122,6 +123,12 @@ function App() { calls: [ { to: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + data: "0x1234", + value: 0n, + }, + { + to: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + data: "0x1234", value: 0n, }, ], @@ -145,7 +152,7 @@ function App() {
{callStatus - ? `Success: ${JSON.stringify(callStatus, null, 2)}` + ? `Success: ${stringify(callStatus, null, 2)}` : callStatusError ? callStatusError?.message : ""} diff --git a/packages/thirdweb/src/adapters/eip1193/to-eip1193.ts b/packages/thirdweb/src/adapters/eip1193/to-eip1193.ts index eda69804a4c..1c831b35c1b 100644 --- a/packages/thirdweb/src/adapters/eip1193/to-eip1193.ts +++ b/packages/thirdweb/src/adapters/eip1193/to-eip1193.ts @@ -194,14 +194,15 @@ export function toProvider(options: ToEip1193ProviderOptions): EIP1193Provider { if (!account) { throw new Error("Account not connected"); } - if (!account.getCallsStatus) { + if (!account.getCallsStatusRaw) { throw new Error("Wallet does not support EIP-5792"); } - return account.getCallsStatus({ + const result = await account.getCallsStatusRaw({ id: request.params[0], chain: chain, client: client, }); + return result; } default: return rpcClient(request); diff --git a/packages/thirdweb/src/wallets/coinbase/coinbase-web.ts b/packages/thirdweb/src/wallets/coinbase/coinbase-web.ts index 99f589718d1..a9f2d44d606 100644 --- a/packages/thirdweb/src/wallets/coinbase/coinbase-web.ts +++ b/packages/thirdweb/src/wallets/coinbase/coinbase-web.ts @@ -326,6 +326,22 @@ function createAccount({ throw error; } }, + async getCallsStatusRaw(options) { + try { + const rawResponse = (await provider.request({ + method: "wallet_getCallsStatus", + params: [options.id], + })) as GetCallsStatusRawResponse; + return rawResponse; + } catch (error) { + if (/unsupport|not support/i.test((error as Error).message)) { + throw new Error( + `${COINBASE} does not support wallet_getCallsStatus, reach out to them directly to request EIP-5792 support.`, + ); + } + throw error; + } + }, async getCapabilities(options) { const chainId = options.chainId; try { diff --git a/packages/thirdweb/src/wallets/in-app/core/eip5792/in-app-wallet-calls.ts b/packages/thirdweb/src/wallets/in-app/core/eip5792/in-app-wallet-calls.ts index 45529af57f1..5e966a05dd2 100644 --- a/packages/thirdweb/src/wallets/in-app/core/eip5792/in-app-wallet-calls.ts +++ b/packages/thirdweb/src/wallets/in-app/core/eip5792/in-app-wallet-calls.ts @@ -10,6 +10,7 @@ import type { Hex } from "../../../../utils/encoding/hex.js"; import { randomBytesHex } from "../../../../utils/random.js"; import type { PreparedSendCall } from "../../../eip5792/send-calls.js"; import type { + GetCallsStatusRawResponse, GetCallsStatusResponse, WalletCallReceipt, } from "../../../eip5792/types.js"; @@ -108,3 +109,52 @@ export async function inAppWalletGetCallsStatus(args: { version: "2.0.0", }; } + +/** + * @internal + */ +export async function inAppWalletGetCallsStatusRaw(args: { + chain: Chain; + client: ThirdwebClient; + id: string; +}): Promise { + const { chain, client, id } = args; + + const bundle = bundlesToTransactions.get(id); + if (!bundle) { + throw new Error("Failed to get calls status, unknown bundle id"); + } + + const request = getRpcClient({ chain, client }); + let status = 200; // BATCH_STATE_CONFIRMED + const receipts: GetCallsStatusRawResponse["receipts"] = []; + + for (const hash of bundle) { + try { + const receipt = await eth_getTransactionReceipt(request, { hash }); + receipts.push({ + blockHash: receipt.blockHash, + blockNumber: `0x${receipt.blockNumber.toString(16)}` as `0x${string}`, + gasUsed: `0x${receipt.gasUsed.toString(16)}` as `0x${string}`, + logs: receipt.logs.map((l) => ({ + address: l.address as `0x${string}`, + data: l.data as `0x${string}`, + topics: l.topics as `0x${string}`[], + })), + status: receipt.status === "success" ? "0x1" : "0x0", + transactionHash: receipt.transactionHash as `0x${string}`, + }); + } catch { + status = 100; // BATCH_STATE_PENDING + } + } + + return { + atomic: false, + chainId: `0x${chain.id.toString(16)}` as `0x${string}`, + id: id as `0x${string}`, + receipts, + status, + version: "2.0.0", + }; +} diff --git a/packages/thirdweb/src/wallets/in-app/core/eip7702/minimal-account.ts b/packages/thirdweb/src/wallets/in-app/core/eip7702/minimal-account.ts index efba63ba33a..8a4083fa700 100644 --- a/packages/thirdweb/src/wallets/in-app/core/eip7702/minimal-account.ts +++ b/packages/thirdweb/src/wallets/in-app/core/eip7702/minimal-account.ts @@ -351,6 +351,12 @@ export const create7702MinimalAccount = (args: { ); return inAppWalletGetCallsStatus(options); }, + getCallsStatusRaw: async (options) => { + const { inAppWalletGetCallsStatusRaw } = await import( + "../eip5792/in-app-wallet-calls.js" + ); + return inAppWalletGetCallsStatusRaw(options); + }, getCapabilities: async (options) => { return { [options.chainId ?? 1]: { diff --git a/packages/thirdweb/src/wallets/in-app/core/wallet/enclave-wallet.ts b/packages/thirdweb/src/wallets/in-app/core/wallet/enclave-wallet.ts index 519884e59c7..236f645ddec 100644 --- a/packages/thirdweb/src/wallets/in-app/core/wallet/enclave-wallet.ts +++ b/packages/thirdweb/src/wallets/in-app/core/wallet/enclave-wallet.ts @@ -287,6 +287,12 @@ export class EnclaveWallet implements IWebWallet { ); return inAppWalletGetCallsStatus(options); }, + getCallsStatusRaw: async (options) => { + const { inAppWalletGetCallsStatusRaw } = await import( + "../eip5792/in-app-wallet-calls.js" + ); + return inAppWalletGetCallsStatusRaw(options); + }, getCapabilities: async (options) => { return { [options.chainId ?? 1]: { diff --git a/packages/thirdweb/src/wallets/injected/index.ts b/packages/thirdweb/src/wallets/injected/index.ts index 5652f8d2bd3..a962a36184b 100644 --- a/packages/thirdweb/src/wallets/injected/index.ts +++ b/packages/thirdweb/src/wallets/injected/index.ts @@ -373,6 +373,22 @@ function createAccount({ throw error; } }, + async getCallsStatusRaw(options) { + try { + const rawResponse = (await provider.request({ + method: "wallet_getCallsStatus", + params: [options.id], + })) as GetCallsStatusRawResponse; + return rawResponse; + } catch (error) { + if (/unsupport|not support/i.test((error as Error).message)) { + throw new Error( + `${id} does not support wallet_getCallsStatus, reach out to them directly to request EIP-5792 support.`, + ); + } + throw error; + } + }, async getCapabilities(options) { const chainIdFilter = options.chainId; try { diff --git a/packages/thirdweb/src/wallets/interfaces/wallet.ts b/packages/thirdweb/src/wallets/interfaces/wallet.ts index 9c8225de93b..9aea9f5eb8f 100644 --- a/packages/thirdweb/src/wallets/interfaces/wallet.ts +++ b/packages/thirdweb/src/wallets/interfaces/wallet.ts @@ -19,6 +19,7 @@ import type { SendCallsResult, } from "../eip5792/send-calls.js"; import type { + GetCallsStatusRawResponse, GetCallsStatusResponse, WalletSendCallsId, } from "../eip5792/types.js"; @@ -325,6 +326,14 @@ export type Account = { chain: Chain; client: ThirdwebClient; }) => Promise; + /** + * EIP-5792: Get the raw (unprocessed) status of the given call bundle + */ + getCallsStatusRaw?: (options: { + id: WalletSendCallsId; + chain: Chain; + client: ThirdwebClient; + }) => Promise; /** * EIP-5792: Get the capabilities of the wallet */ diff --git a/packages/thirdweb/src/wallets/smart/index.ts b/packages/thirdweb/src/wallets/smart/index.ts index 76b1645e9c1..b425c38a0a6 100644 --- a/packages/thirdweb/src/wallets/smart/index.ts +++ b/packages/thirdweb/src/wallets/smart/index.ts @@ -389,6 +389,12 @@ async function createSmartAccount( ); return inAppWalletGetCallsStatus(options); }, + getCallsStatusRaw: async (options) => { + const { inAppWalletGetCallsStatusRaw } = await import( + "../in-app/core/eip5792/in-app-wallet-calls.js" + ); + return inAppWalletGetCallsStatusRaw(options); + }, getCapabilities: async (options) => { return { [options.chainId ?? 1]: { @@ -567,6 +573,12 @@ function createZkSyncAccount(args: { ); return inAppWalletGetCallsStatus(options); }, + getCallsStatusRaw: async (options) => { + const { inAppWalletGetCallsStatusRaw } = await import( + "../in-app/core/eip5792/in-app-wallet-calls.js" + ); + return inAppWalletGetCallsStatusRaw(options); + }, getCapabilities: async (options) => { return { [options.chainId ?? 1]: {