Skip to content

Bug: Keychain precompile KeyAlreadyExists rejects re-submission of keyAuthorization, breaking MPP services for passkey wallets #657

@Vanya13917

Description

@Vanya13917

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 (encodeForSigningTxEnvelopeTempo.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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions