Skip to main content
This guide takes you from nothing to a verified signature: a wallet whose private key lives inside Lit’s TEE, a few lines of JavaScript that sign with it, and a local check that proves the signature is real. At each step, the administrative page that covers it in depth is linked — skim them now, come back when you productionize. If the nouns below (PKP, usage key, group) are new, keep Core Concepts open in a second tab.

What you’ll build

  1. A PKP — a real EVM wallet the network holds for you.
  2. A Lit Action that signs a message with that PKP.
  3. A local verification that the signature recovers to the PKP’s address.
Total cost is a few cents of credits; total time is about five minutes.
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

Add funds

Running actions and write management calls consume credits; reads are free. Click Add Funds in the Dashboard (minimum $5.00, card, crypto, or LITKEY). Unfunded metered calls return 402 Payment Required.
Admin reference: Pricing · Errors.
3

Mint a PKP (your signing wallet)

Note the returned 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.
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:
  1. 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.
  2. Mint a usage key with execute_in_groups limited to that group, and put that key in your app:
Freshly-granted permissions are eventually consistent — the first /lit_action call right after minting a key or adding a grant can fail for a beat. Poll the real call until it succeeds rather than sleeping a fixed amount. Details: run lit-action.
Admin reference: API Keys · Groups · full API walkthrough in Using the API directly.

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.
Want a signature produced on a schedule or in response to an event, with no server of your own? See Lit Triggers.

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_groups to exactly one group — API Keys
  • Action published to IPFS and its CID pinned in the group — Dashboard
  • Credit balance monitored (metered calls fail with 402 when 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