diff --git a/packages/account-sdk/src/sign/base-account/Signer.test.ts b/packages/account-sdk/src/sign/base-account/Signer.test.ts index 78570225..a73b4474 100644 --- a/packages/account-sdk/src/sign/base-account/Signer.test.ts +++ b/packages/account-sdk/src/sign/base-account/Signer.test.ts @@ -431,9 +431,14 @@ describe('Signer', () => { params: [], }; + // eth_sendTransaction requires a valid 32-byte tx hash response + const mockValue = method === 'eth_sendTransaction' + ? '0x' + 'a'.repeat(64) // valid 32-byte tx hash + : '0xSignature'; + (decryptContent as Mock).mockResolvedValueOnce({ result: { - value: '0xSignature', + value: mockValue, }, }); diff --git a/packages/account-sdk/src/sign/base-account/Signer.ts b/packages/account-sdk/src/sign/base-account/Signer.ts index 6ccbb8f2..2cc569b1 100644 --- a/packages/account-sdk/src/sign/base-account/Signer.ts +++ b/packages/account-sdk/src/sign/base-account/Signer.ts @@ -428,6 +428,17 @@ export class Signer { this.callback?.('accountsChanged', this.accounts); break; } + case 'eth_sendTransaction': { + const txHash = result.value as string; + // Validate that the response is a 32-byte tx hash (64 hex chars + 0x prefix = 66 chars) + // If the popup returns a 65-byte ECDSA signature instead of a tx hash, throw an error + if (typeof txHash === 'string' && txHash.startsWith('0x') && txHash.length !== 66) { + throw standardErrors.rpc.internal( + `eth_sendTransaction returned invalid response: expected 32-byte tx hash (66 chars) but got ${txHash.length} chars. The popup may have returned a signature instead of a transaction hash.` + ); + } + break; + } default: break; }