wallet_getCallsStatus doesn't return per-call receipts (transactionHash) for EIP-5792 batched wallet_sendCalls
- Dominant language
- TypeScript
- Stars
- 172
- Forks
- 207
- Avg merge
- 49m
- Merged PRs (30d)
- 1
Description
### Description
When batching multiple calls (e.g. an ERC-20 `approve` + a contract deposit
call) into one signature via `wallet_sendCalls` through the Base Account
(Coinbase Smart Wallet) connector, the returned batch `id` is — per
EIP-5792 — an opaque identifier, not a transaction hash. The documented way
to recover the real per-call transaction hash is via `wallet_getCallsStatus`,
whose response should include a `receipts` array with each call's
`transactionHash`.
In practice, `wallet_getCallsStatus` consistently returns without that
`receipts` field populated, even once the batch has genuinely confirmed
on-chain — leaving no way to recover a real, explorer-linkable transaction
hash for the individual calls from the wallet's own RPC responses.
### Steps to Reproduce
1. Connect via the `baseAccount` wagmi connector (Base Account / Coinbase
Smart Wallet), on Base Mainnet.
2. Call `wallet_sendCalls` with 2+ calls (e.g. `approve` then a `deposit`).
3. Poll `wallet_getCallsStatus` with the returned `id` until `status:
"success"`.
4. Inspect the response's `receipts` field.
### Observed
`receipts` is empty/undefined, even though the batch genuinely landed
on-chain successfully (confirmed independently by locating the real
transaction via the smart wallet's own address activity on Basescan, and
decoding its `UserOperationEvent` log — `success: true`).
### Expected
`receipts` should contain one entry per call with a real `transactionHash`,
per EIP-5792 and viem's `GetCallsStatusReturnType`, so a dApp can link to /
verify the resulting transaction(s) without independently searching for them.
### Impact
Any dApp batching calls via this wallet has no way to show the user a
working reference to "the transaction" that just happened. The `id`
returned by `wallet_sendCalls` isn't a valid transaction hash format at all
— in our testing it decodes as a 32-byte value followed by the chain ID
padded to another 32 bytes (`<64 hex><64 hex chainId>`), clearly not meant
to be used as an explorer-linkable hash directly.
### Example
Real transaction confirmed successful during testing (routed as a
UserOperation, `UserOperationEvent.success = true`):
https://basescan.org/tx/0x477a9a91619447b5b8980a20ad88772dfdeda3e271daee8494eddc5282e808b6
`wallet_getCallsStatus` for this batch never supplied a `receipts` entry
relating to it — we only recovered this real hash by searching the smart
wallet's own address history, not from any SDK response.
### Context
Possibly related to #251 — different call-submission path
(`eth_sendTransaction` there vs. `wallet_sendCalls`/`wallet_getCallsStatus`
here), but the same broader pattern: the wallet's RPC responses not
reliably surfacing a real, standard on-chain transaction hash back to the
calling dApp.
### Versions
- `@base-org/account`: 2.5.10 (via `wagmi` 3.7.6 / `@wagmi/connectors` 8.1.0)
- Wallet: Base Account (Coinbase Smart Wallet), browser popup flow
- Network: Base Mainnet
Contributor guide
Research direction
Start by reproducing the Base Account connector flow with wallet_sendCalls for two calls on Base Mainnet, then poll wallet_getCallsStatus until status is success. Compare the response with EIP-5792 and viem's GetCallsStatusReturnType; done means the confirmed batch exposes a receipts entry with a real transactionHash for each call.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, blockchain
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100