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):
- POST /new_account → returns master api_key + wallet_address. ✓
- POST /billing/create_payment_intent ($5) + POST /billing/confirm_payment. Balance = $5.00. ✓
- GET /create_wallet → PKP minted. ✓
- POST /create_group → group id 1. ✓
- POST /register_action + POST /add_action_to_group ×N for the agent's Lit Actions. ✓
- POST /add_usage_api_key → scoped usage key returned. ✓
- 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:
- 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?
- 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?
- 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.
- 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.
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):
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):
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:
of operations?
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.
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.