Skip to content

examples: add Lit Triggers examples (release-attestation, uptime-insurance, chainlink-feed-mirror)#408

Open
clawdbot-glitch003 wants to merge 6 commits into
mainfrom
glitch003/example-release-attestation
Open

examples: add Lit Triggers examples (release-attestation, uptime-insurance, chainlink-feed-mirror)#408
clawdbot-glitch003 wants to merge 6 commits into
mainfrom
glitch003/example-release-attestation

Conversation

@clawdbot-glitch003
Copy link
Copy Markdown
Collaborator

@clawdbot-glitch003 clawdbot-glitch003 commented May 29, 2026

Summary

Adds examples/lit-triggers/ — full, runnable Lit Triggers examples, each matching the examples/ convention (hardened action + contract + setup.js + e2e client + README with flow diagram & trust model). They're grouped in a subfolder because they depend on the lit-triggers service (the parent-folder examples call the Lit Action endpoint directly).

Every on-chain example signs with the action's own keyless wallet (derived from its IPFS CID). And because a trigger has no downstream caller, the action broadcasts the tx itself — so setup funds the action wallet.

Example Trigger Shows
release-attestation webhook Verify a GitHub release webhook (HMAC over the raw body) → anchor on-chain in ReleaseRegistry (action wallet pinned as attester).
uptime-insurance schedule Parametric insurance: cron checks a status page, pays ETH to the policyholder from the keyless pool wallet when the service is down. No contract.
chainlink-feed-mirror chain_event Relay a Chainlink AnswerUpdated to a PriceConsumer on a chain Chainlink doesn't serve. Hardened: dest-chainId pin (action) + updater & stale-round guards (contract).

setup.js flow per example: action CID → group → scoped usage key (from your master key) → derive + fund action wallet → deploy contract (where applicable) → interactive lit-triggers browser authorize → create the trigger. call() retries transient 5xx/non-JSON from the Lit API.

Verified end-to-end on Base Sepolia

  • release-attestation — full setup incl. master-key minting + the real browser-authorize (clicked) + attest() e2e; registry reads back. Also exercised the full authorized-token API surface (CRUD, disable→reject→enable, 401 for unauthorized).
  • uptime-insurancesetup + claim: scheduled run paid out, confirmed by the policyholder +0.0002 ETH balance delta.
  • chainlink-feed-mirrorsetup resolved the live Chainlink aggregator + deployed PriceConsumer; mirror --simulate relayed a price (roundId advanced on-chain, run success, tx confirmed).

Notes

🤖 Generated with Claude Code

First full-package Lit Triggers example, matching the examples/ convention
(action + contract + setup.js + deploy.js + e2e client + README):

A webhook trigger receives a GitHub release event, verifies X-Hub-Signature-256
HMAC over the raw body, and — only for genuine published releases — broadcasts
an attest() tx to ReleaseRegistry, signed by the wallet derived from the
action's IPFS CID (pinned as the contract's immutable attester). Unlike the
request/response examples, the action broadcasts itself (a trigger has no
downstream caller), so setup funds the action wallet.

setup.js: action CID -> group -> scoped key -> derive + fund action wallet ->
deploy -> interactive lit-triggers authorize -> create webhook trigger.

Runtime verified end-to-end on Base Sepolia via deploy.js + attest.js.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@clawdbot-glitch003 clawdbot-glitch003 requested a review from a team May 29, 2026 01:21
These depend on the lit-triggers service (the parent-folder examples call the
Lit Action endpoint directly), so group them in a subfolder. Adds a subfolder
index and a Lit Triggers section in the top-level examples README.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@clawdbot-glitch003
Copy link
Copy Markdown
Collaborator Author

✅ Full npm run setup now verified end-to-end on Base Sepolia with a real master LIT_API_KEY — including the previously-unexercised master-key calls:

  • get_lit_action_ipfs_id → CID Qmasj6fp8hkNxK5e3MoncDHhcrkDDR2hZ24B7xzEg3Gq1k
  • add_group → group 46
  • add_usage_api_key → fresh scoped key minted
  • add_action + add_action_to_group
  • action wallet derived (0x2ab7…aac4) + funded
  • ReleaseRegistry deployed (0x66fEC8aD0470A07234385Bc63d88B8c7Eaf707Bf, attester pinned)
  • webhook trigger created

Then npm run attest against the freshly-minted scoped key: signed webhook → run successattest() tx 0xff1880329cf450907e321caf69a7dbfa8e9b5130db9d596effbe4641404e7d2bgetRelease() reads back commitish: main + timestamp.

The browser-authorize step (step 9) used the reuse path; the interactive handshake itself was exercised earlier in development.

Two more full Lit Triggers example packages under examples/lit-triggers/,
built and verified end-to-end on Base Sepolia:

- uptime-insurance (schedule): parametric insurance. A cron trigger checks a
  status page; on a major/critical incident it pays ETH to the policyholder
  from the action's own keyless wallet (the pool). No contract — the pool is
  the wallet balance. Verified: scheduled run paid out, confirmed by balance
  delta.

- chainlink-feed-mirror (chain_event): relays a Chainlink AnswerUpdated on a
  supported source chain to a PriceConsumer on any destination chain, signed by
  a keyless relayer pinned as the consumer's updater. Hardened: dest-chainId
  pin in the action, updater + stale-round guards in the contract. Verified via
  deterministic --simulate (PriceConsumer roundId advanced on-chain).

setup.js call() now retries transient 5xx / non-JSON responses from the Lit
API (hit a flaky HTML error during testing). Updates the examples indexes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@clawdbot-glitch003 clawdbot-glitch003 changed the title examples: add release-attestation (Lit Triggers reference package) examples: add Lit Triggers examples (release-attestation, uptime-insurance, chainlink-feed-mirror) May 29, 2026
Address findings from a codex adversarial pass on the three examples:

- chainlink-feed-mirror [P1]: the action trusted the trigger's decoded log, so
  a usage-key holder could relay an arbitrary price. It now re-fetches the
  receipt by (tx hash, log index) from a hostname-pinned, https-only source RPC,
  verifies the emitter is the baked SOURCE.aggregator with the AnswerUpdated
  topic + confirmations, and decodes the price from the verified log. destChainId
  is now required. setup warns if the proxy's aggregator drifts from the baked
  one. --simulate now replays a real on-chain AnswerUpdated (a forged price is
  ignored / a wrong-emitter tx is rejected). Verified live: real price relayed;
  wrong-emitter tx rejected with consumer unchanged.

- PriceConsumer [P2]: replace the `roundId != 0` first-write sentinel with an
  explicit `initialized` flag, so a roundId==0 write can't bypass stale-round.

- uptime-insurance [P1]: with DEMO_FORCE_DOWN it pays every tick. setup now
  creates the schedule trigger DISABLED; claim enables it, catches one payout,
  and disables it again. Verified live (disabled → +0.0002 ETH payout → disabled).

- release-attestation [P1/P2]: document the real trust boundary — params.secret
  is caller-controllable for direct calls, so the HMAC only gates the public
  webhook path; the usage key is the trust root, and encrypting the secret
  (Lit.Actions.Encrypt, needs a PKP) is the production fix. Note commitish may be
  a branch, not an immutable SHA.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@clawdbot-glitch003
Copy link
Copy Markdown
Collaborator Author

Addressed codex adversarial review

Ran a codex challenge pass; applied + live-verified fixes for the actionable findings.

[P1] feed-mirror trusted unverified trigger data → the action now re-fetches the receipt by (tx hash, log index) from a hostname-pinned, https-only source RPC, verifies the emitter is the baked SOURCE.aggregator with the AnswerUpdated topic + confirmations, and decodes the price from the verified log. destChainId is now required; setup warns on aggregator drift; --simulate replays a real on-chain event.

  • Verified: real price relayed (answer 200157745000, roundId 11972, src tx 0xdbc714…).
  • Verified forgery rejected: a real Base tx whose log is a USDC Transfer → error: "unexpected log emitter", consumer unchanged.

[P1] uptime drains by defaultsetup now creates the schedule trigger disabled; claim enables it, catches one payout, disables it again. Verified: disabled → +0.0002 ETH payout (0xcd149c…) → disabled.

[P2] PriceConsumer round-0 sentinel → replaced roundId != 0 with an explicit initialized flag.

[P1/P2] release-attestation trust model → README now states plainly that params.secret is caller-controllable on a direct call, so the HMAC only gates the public webhook path; the usage key is the trust root, and encrypting the secret (Lit.Actions.Encrypt, needs a PKP) is the production fix. Also noted commitish may be a branch, not a SHA.

Accepted as known/by-design (documented): plaintext keys in gitignored .env (local example config); no nonce coordination for keyless broadcasts (matters only for high-frequency triggers); replay/last-write-wins on (repo,tag).

glitch003 and others added 2 commits May 29, 2026 12:47
Per review feedback: a reader landing on one example shouldn't hit references
to sibling examples.

- _env.js headers no longer point at ../../compliance-transfer-gate (a path
  that was also broken from the deeper lit-triggers/ nesting); each now just
  says it's kept inline so the folder is self-contained, matching #420.
- chainlink-feed-mirror README now names the "hostname-pinned RPC trust-anchor"
  pattern and links to docs/lit-actions/patterns.mdx instead of describing it
  as another example's solution.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants