What you’ll build
- A PKP — a real EVM wallet the network holds for you.
- A Lit Action that signs a message with that PKP.
- A local verification that the signature recovers to the PKP’s address.
1
Create an account
Create an account in the Dashboard (New User tab) or via the API:The response contains your account API key — it is shown exactly once, so store it now, and never ship it in client code. Account creation takes ~15 seconds because it registers your account on-chain (Base).
Admin reference: API Keys · Account Modes (this guide uses the default API mode).
2
3
Mint a PKP (your signing wallet)
wallet_address — that address is your pkpId in the code below, and it’s what signatures will recover to. The private key was generated inside the TEE and will never leave it.Admin reference: Dashboard → Wallets.
4
Sign a message
Run this action with your account key (we’ll scope a production key in step 6):You can also paste the same code into the Dashboard’s Action Runner.
- JavaScript (Core SDK)
- cURL
5
Verify the signature locally
The point of Lit signing is that anyone can check the result without trusting you or Lit’s API. In any Node script or browser console:If it recovers to your PKP’s address, the message was signed by a key that only exists inside the TEE — and only code permitted on-chain could use it. The same check works on-chain via
ecrecover, which is how smart contracts consume Lit signatures.6
Production posture: pin the code, scope the key
For a real app you don’t want “any code, master key.” Two changes:
- Pin your action. Publish the action code to IPFS and register its CID in a group, and add your PKP to the same group. Now only that exact code can sign with that wallet.
- Mint a usage key with
execute_in_groupslimited to that group, and put that key in your app:
Where signing goes from here
The message signature above is the atom; everything else is that atom plus conditions, transactions, or different curves.Sign & send transactions
Construct, sign, and broadcast an ETH transfer from your PKP — it’s a normal wallet, so fund its address first.
Conditional signing
Only sign when a condition holds — an API result, a contract read, a sanctions screen.
Keyless signing (action identity)
Every action has a key derived from its own IPFS CID — sign with code identity, no PKP needed.
Oracles & proofs
Fetch data, aggregate it, and deliver a signature any contract can verify with ecrecover.
Solana & non-EVM
Derive an ed25519 wallet from an action’s identity key and sign Solana transactions.
Non-custodial co-signing (MPC)
Threshold ECDSA/FROST where Lit holds one share and literally cannot sign without you.
Administrative checklist for a signing app
- Account key lives in a secrets manager; only usage keys ship — API Keys
- Usage key scoped with
execute_in_groupsto exactly one group — API Keys - Action published to IPFS and its CID pinned in the group — Dashboard
- Credit balance monitored (metered calls fail with
402when empty) — Pricing · Errors - If the PKP sends transactions, its address holds gas on the target chain
- Decided on an ownership model (API vs. ChainSecured) — Account Modes