Guardian-gated recovery demo:
- Store guardian recovery config on-chain (Polygon) in a
GuardianRegistrycontract. - Store the child Lit Action CID on-chain (Polygon) in a
LitActionRegistrycontract. - Encrypt a recovery private key with Lit on Naga Dev.
- Decrypt via a parent Lit Action that delegates to a child action and a guardian action.
- Node 18+
- Wallet with MATIC for gas (Polygon mainnet) and a Polygon RPC URL
npm installCopy .env.example to .env and fill:
PRIVATE_KEY– deployer wallet for PolygonPOLYGON_RPC_URL– Polygon mainnet RPC (e.g., Alchemy/Infura/public)POLYGONSCAN_API_KEY– optional, for verificationVITE_GUARDIAN_REGISTRY_ADDRESS– set after you deploy the guardian registryVITE_LIT_ACTION_REGISTRY_ADDRESS– set after you deploy the Lit Action registryVITE_PASSWORD_ACTION_CID– set automatically if you runnpm run pinata:upload-all(or fill manually)VITE_CHILD_ACTION_CID– optional fallback for the child Lit Action CIDVITE_PARENT_ACTION_CID– parent Lit Action CIDVITE_POLYGON_RPC_URL– Polygon RPC for client writes and LitAction registry reads
General:
npm run dev– start the Vite dev server.npm run build– typecheck + build the app.npm run lint– run ESLint.npm run preview– preview the production build.npm run hardhat– Hardhat CLI passthrough.npm run compile:contracts– compile Solidity contracts (viaIR enabled in Hardhat config).
Deploy:
npm run deploy:guardian-registry– deploy GuardianRegistry (usesSIGN_ACTION_PUBLIC_KEYorlitActions/public_keys.json).npm run deploy:lit-action-registry– deploy LitActionRegistry.
Lit actions + keys:
npm run pinata:upload– upload a Lit Action to Pinata.npm run pinata:upload-all– upload all Lit Actions (writes.env.local+litActions/cids.json) and regenerateslitActions/public_keys.json.npm run lit:action-pks– derive Lit Action public keys fromlitActions/cids.jsonand writelitActions/public_keys.json.
Set child IPFS CID on LitActionRegistry (uses env or litActions/cids.json, strips ipfs://).
npm run update:child-cid -- --network polygonSet signActionPublicKey on GuardianRegistry using SIGN_ACTION_PUBLIC_KEY or litActions/public_keys.json.
npm run update:sign-action-key -- --network polygonSet setGuardianType (uses env vars).
GUARDIAN_CID=Qm... \
GUARDIAN_TYPE_NAME=wallet \
GUARDIAN_TYPE_UNIQUE=true \
npm run update:guardian-type -- --network polygonnpm run compile:contracts
npm run deploy:guardian-registryCopy the printed contract address into VITE_GUARDIAN_REGISTRY_ADDRESS.
npm run compile:contracts
npm run deploy:lit-action-registryCopy the printed contract address into VITE_LIT_ACTION_REGISTRY_ADDRESS.
litActions/password.js– verifies guardian password hash on-chain.litActions/child-lit-action.js– validates guardians and decrypts.litActions/parent-lit-action.js– fetches config and delegates to the child action.
Use Pinata helper to upload all actions and auto-write CIDs:
npm run pinata:upload-all
# writes .env.local entries:
# VITE_PASSWORD_ACTION_CID, VITE_CHILD_ACTION_CID, VITE_PARENT_ACTION_CID
# and litActions/cids.jsonThe frontend builds a Unified ACC using the child action CID and uses that for encrypt/decrypt.
Run the app:
npm run devIn the UI:
- Connect to Lit (Naga Dev).
- Enter a guardian password and click “Create recovery key” (encrypts a new private key + stores guardian config on Polygon).
- Click “Decrypt” for a saved key – parent action fetches the child CID, child verifies the guardian, and returns the decrypted key.
npm run build