Summary
Tempo's keychain precompile rejects transactions containing keyAuthorization field when the agent's signing key is already registered, returning KeyAlreadyExists. This breaks any MPP service that accepts payments from passkey (wallet.tempo.xyz) wallets after their first transaction.
Reproduction
- Service: https://honeypot.ivan-tempo.xyz/api/check ($0.02 endpoint, paid in USDC.e)
- Pay from any passkey wallet that has previously made a Tempo transaction
- Server-side
mppx.verify fails on eth_call simulation with Revm error: keychain precompile error: Account keychain error: KeyAlreadyExists(KeyAlreadyExists)
- Same call succeeds for EOA wallets (no
keyAuthorization field in tx)
Root Cause Analysis
keyAuthorization is included in the transaction sign payload (encodeForSigning → TxEnvelopeTempo.serialize line 725) — cannot be stripped server-side without invalidating the agent signature
- Tempo's keychain precompile rejects re-submission instead of treating it as a no-op
- Affects all 4 paid endpoints in our service except
/api/check/batch (tested with EOA-only agents during development)
Decoded transaction confirms the structure: 1 payment call to USDC.e, plus keyAuthorization with a secp256k1 spending key address and a WebAuthn signature. No keychain registration call exists in the calls array — the precompile is triggered by the keyAuthorization field itself.
Suggested Fix (one of)
- Make keychain precompile idempotent — re-submission of already-registered key returns success instead of
KeyAlreadyExists
- OR: wallet SDK detects that key is already registered and emits tx WITHOUT
keyAuthorization field for subsequent transactions
Impact
Critical for any MPP service receiving payments from passkey wallets. The KeyAlreadyExists error fires both on eth_call simulation and on eth_sendRawTransactionSync, so bypassing simulation does not help — the broadcast is also rejected.
99% of Tempo wallets are passkey-based (wallet.tempo.xyz default UX). This means any MPP service is effectively broken for the vast majority of users.
Logs
Full RPC error from Vercel logs:
mppx: internal verification error Error [InvalidInputRpcError]: Missing or invalid parameters.
URL: https://rpc.tempo.xyz
Request body: {"method":"eth_sendRawTransactionSync","params":["0x76..."]}
Details: keychain precompile error: Account keychain error: KeyAlreadyExists(KeyAlreadyExists)
Full decoded transaction and additional logs available on request.
Summary
Tempo's keychain precompile rejects transactions containing
keyAuthorizationfield when the agent's signing key is already registered, returningKeyAlreadyExists. This breaks any MPP service that accepts payments from passkey (wallet.tempo.xyz) wallets after their first transaction.Reproduction
mppx.verifyfails oneth_callsimulation withRevm error: keychain precompile error: Account keychain error: KeyAlreadyExists(KeyAlreadyExists)keyAuthorizationfield in tx)Root Cause Analysis
keyAuthorizationis included in the transaction sign payload (encodeForSigning→TxEnvelopeTempo.serializeline 725) — cannot be stripped server-side without invalidating the agent signature/api/check/batch(tested with EOA-only agents during development)Decoded transaction confirms the structure: 1 payment call to USDC.e, plus
keyAuthorizationwith a secp256k1 spending key address and a WebAuthn signature. No keychain registration call exists in thecallsarray — the precompile is triggered by thekeyAuthorizationfield itself.Suggested Fix (one of)
KeyAlreadyExistskeyAuthorizationfield for subsequent transactionsImpact
Critical for any MPP service receiving payments from passkey wallets. The
KeyAlreadyExistserror fires both oneth_callsimulation and oneth_sendRawTransactionSync, so bypassing simulation does not help — the broadcast is also rejected.99% of Tempo wallets are passkey-based (wallet.tempo.xyz default UX). This means any MPP service is effectively broken for the vast majority of users.
Logs
Full RPC error from Vercel logs:
Full decoded transaction and additional logs available on request.