Skip to content

POST /convert_to_chain_secured_account returns "Simulation failed: Contract error: " — need help decoding selector 0x87241e55 #356

@alextitonis

Description

@alextitonis

Hi Lit team,

We're integrating the ChainSecured account flow per https://developer.litprotocol.com/management/api_direct and POST /convert_to_chain_secured_account keeps failing with a 500 +
opaque contract revert. We can't progress without help decoding the error.

Endpoint: POST https://api.chipotle.litprotocol.com/core/v1/convert_to_chain_secured_account

Response (HTTP 500):
convert_to_chain_secured_account failed: Simulation failed: Contract error: 61126050399125977288105628201662819897698871373326562477104554146597730080802

That U256 decoded as bytes32:
0x87241e5513a0e58ce134e24b962844b7f24a1eea60aad50ec4cb44c0f9f15822

Treating it as selector(4) + data(28):

  • Selector: 0x87241e55
  • Data: 0x13a0e58ce134e24b962844b7f24a1eea60aad50ec4cb44c0f9f15822 (28 bytes, not a standard ABI word — unclear how to interpret)

The selector doesn't match any standard Solidity error or OpenZeppelin AccessControl error we tried (InvalidSignature(), AccessControlUnauthorizedAccount(address,bytes32),
etc.). It does not appear to be a function-of-payload — we've retried with different chainId serializations (string "8453" vs JSON number 8453), different issuedAt
serializations (string vs number), and lowercased vs checksummed address field — the error U256 is identical across all variants. So it's a static error, not a hash mismatch.

Request payload we send (latest variant):
{
"new_admin_wallet_address": "0x625862521777e19ad54ce6c7abed9ca54d6589ea",
"typed_data": {
"types": {
"EIP712Domain": [
{"name": "name", "type": "string"},
{"name": "version", "type": "string"},
{"name": "chainId", "type": "uint256"}
],
"ConvertAccount": [
{"name": "address", "type": "address"},
{"name": "issuedAt", "type": "uint256"}
]
},
"primaryType": "ConvertAccount",
"domain": {
"name": "Lit ChainSecured",
"version": "1",
"chainId": 8453
},
"message": {
"address": "0x625862521777e19ad54ce6c7abed9ca54d6589ea",
"issuedAt": <unix-seconds, signed within last 60s of the call>
}
},
"signature": "0x<65-byte EIP-712 signature from MetaMask via eth_signTypedData_v4>"
}

Auth header: X-Api-Key: <master api_key returned by POST /new_account for this account>

The signature is produced client-side by MetaMask after switching the wallet's active chain to 8453 (since MetaMask refuses to sign EIP-712 if domain.chainId doesn't match the
active chain). signMessage is not used — eth_signTypedData_v4 over the JSON above.

Sequence leading up to the failure (per POST /new_account → setup → convert):

  1. POST /new_account → returns master api_key + wallet_address. ✓
  2. POST /billing/create_payment_intent ($5) + POST /billing/confirm_payment. Balance = $5.00. ✓
  3. GET /create_wallet → PKP minted. ✓
  4. POST /create_group → group id 1. ✓
  5. POST /register_action + POST /add_action_to_group ×N for the agent's Lit Actions. ✓
  6. POST /add_usage_api_key → scoped usage key returned. ✓
  7. POST /convert_to_chain_secured_account ← fails here.

All earlier steps succeed using the same master api_key, so auth is good. The account is funded, has a PKP, has a group with actions, has a usage key.

Questions:

  1. What does selector 0x87241e55 correspond to in your contract source? Is it an access control error, signature-mismatch error, account-state precondition, or something else?
  2. Are there preconditions for convert_to_chain_secured_account we might be missing — e.g., does the account need to be empty (no PKPs/groups yet), or is there a specific order
    of operations?
  3. Is chainId: 8453 actually what your verifier expects, or is there a different ChainSecured chainId we should use? We tried 84532 (Base Sepolia, our actual deployment chain)
    and got "Chain ID mismatch: typed_data says Some(84532), server is on 8453" — so 8453 is the right value, but conversion still reverts after that check passes.
  4. Should EIP712Domain be declared explicitly in types, or omitted (per EIP-712 spec convention)? Same question for the field types — exactly address and uint256, or do you use
    different names/types internally?

Account wallet address (the one we're trying to convert): 0xa99067aa147c3affa84b0fceb01cbfc43ca46c96 (or whichever from the most recent attempt — easy to provide more if
helpful).

Happy to share the master api_key privately if that helps your team reproduce. Thanks.


Let me know if you want the request body in a different format or want me to include a curl one-liner.

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