diff --git a/public/images/cre-templates/aws-icon.webp b/public/images/cre-templates/aws-icon.webp new file mode 100644 index 00000000000..9ae96a68fe9 Binary files /dev/null and b/public/images/cre-templates/aws-icon.webp differ diff --git a/public/images/cre-templates/card-strip.png b/public/images/cre-templates/card-strip.png new file mode 100644 index 00000000000..0c7a27eea63 Binary files /dev/null and b/public/images/cre-templates/card-strip.png differ diff --git a/public/images/cre-templates/chainlink-logo-mark.png b/public/images/cre-templates/chainlink-logo-mark.png new file mode 100644 index 00000000000..4901beb4303 Binary files /dev/null and b/public/images/cre-templates/chainlink-logo-mark.png differ diff --git a/public/images/cre-templates/featured-template.png b/public/images/cre-templates/featured-template.png new file mode 100644 index 00000000000..21adcba3a94 Binary files /dev/null and b/public/images/cre-templates/featured-template.png differ diff --git a/public/images/cre-templates/hero-pattern.webp b/public/images/cre-templates/hero-pattern.webp new file mode 100644 index 00000000000..74186f5d201 Binary files /dev/null and b/public/images/cre-templates/hero-pattern.webp differ diff --git a/public/images/cre-templates/single-template-hero-bg.png b/public/images/cre-templates/single-template-hero-bg.png new file mode 100644 index 00000000000..19a719e6baf Binary files /dev/null and b/public/images/cre-templates/single-template-hero-bg.png differ diff --git a/public/images/cre-templates/templates/aws-architecture.png b/public/images/cre-templates/templates/aws-architecture.png new file mode 100644 index 00000000000..bd46e8c3aa9 Binary files /dev/null and b/public/images/cre-templates/templates/aws-architecture.png differ diff --git a/public/images/cre-templates/templates/x402-minimal-system-flow.webp b/public/images/cre-templates/templates/x402-minimal-system-flow.webp new file mode 100644 index 00000000000..7e98bd3bcd2 Binary files /dev/null and b/public/images/cre-templates/templates/x402-minimal-system-flow.webp differ diff --git a/src/components/CRETemplate/CRETemplate.astro b/src/components/CRETemplate/CRETemplate.astro new file mode 100644 index 00000000000..1e3b37f8c6a --- /dev/null +++ b/src/components/CRETemplate/CRETemplate.astro @@ -0,0 +1,530 @@ +
+ +
+ + + + diff --git a/src/components/CRETemplate/CRETemplateOverview.astro b/src/components/CRETemplate/CRETemplateOverview.astro new file mode 100644 index 00000000000..e8c509ba151 --- /dev/null +++ b/src/components/CRETemplate/CRETemplateOverview.astro @@ -0,0 +1,244 @@ +--- +import { CRETemplatesFrontmatter } from "~/content.config.ts" + +interface Props { + frontmatter: CRETemplatesFrontmatter + templateSlug: string +} +const { frontmatter, templateSlug } = Astro.props +--- + +
+
+ +
+ { + frontmatter.author === "Chainlink Labs" ? ( + + ) : frontmatter.author === "AWS" ? ( + + ) : null + } + CREATED BY {frontmatter.author.toUpperCase()} +
+ + +

{frontmatter.title}

+ + +

{frontmatter.description}

+ + + + + + +
+
+ + + + diff --git a/src/components/CRETemplate/CRETemplatePanel.astro b/src/components/CRETemplate/CRETemplatePanel.astro new file mode 100644 index 00000000000..277737e286a --- /dev/null +++ b/src/components/CRETemplate/CRETemplatePanel.astro @@ -0,0 +1,367 @@ +--- +import { MarkdownHeading } from "astro" +import { CRETemplatesFrontmatter } from "~/content.config.ts" +import TableOfContents from "../Quickstart/TableOfContents/TableOfContents.tsx" +import alertIcon from "../Alert/Assets/alert-icon.svg" + +interface Props { + frontmatter: CRETemplatesFrontmatter + headings: MarkdownHeading[] +} +const { frontmatter, headings } = Astro.props +--- + + + + + + diff --git a/src/components/CRETemplate/TemplateCard.astro b/src/components/CRETemplate/TemplateCard.astro new file mode 100644 index 00000000000..cc100b567a7 --- /dev/null +++ b/src/components/CRETemplate/TemplateCard.astro @@ -0,0 +1,191 @@ +--- +interface Props { + title: string + description: string + image?: string + href: string + author: string + languages: string[] // e.g., ["Go", "TypeScript", "Go (MVR)"] +} + +const { title, description, href, author, languages } = Astro.props + +// Extract unique base languages (e.g., "Go (MVR)" -> "Go") +const baseLanguages = [...new Set(languages.map((lang) => lang.replace(/\s*\([^)]*\)\s*/g, "").trim()))].sort( + (a, b) => { + // TypeScript always comes first + if (a === "TypeScript") return -1 + if (b === "TypeScript") return 1 + return a.localeCompare(b) + } +) +--- + + + +
+ + +
+ +
+ {baseLanguages.map((lang) => {lang})} +
+ + +

{title}

+ + +

{description}

+ + + +
+
+ + diff --git a/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenu.tsx b/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenu.tsx index b13f9e55827..4d1807af510 100644 --- a/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenu.tsx +++ b/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenu.tsx @@ -57,6 +57,10 @@ export const megaMenuSections: MegaMenuSection[] = [ label: "Docs", href: (evmProducts.find((product) => product.title === "CRE") || {})?.docsLandingLink, }, + { + label: "CRE Templates Hub", + href: "/cre-templates", + }, ], }, ], diff --git a/src/components/Quickstart/Accordion/Accordion.astro b/src/components/Quickstart/Accordion/Accordion.astro index a943ec35d0d..8ee98ed0152 100644 --- a/src/components/Quickstart/Accordion/Accordion.astro +++ b/src/components/Quickstart/Accordion/Accordion.astro @@ -3,14 +3,20 @@ interface Props { title: string number?: number contentReference?: string + depth?: 3 | 4 } -const { title, number, contentReference } = Astro.props +const { title, number, contentReference, depth = 3 } = Astro.props const id = title.toLowerCase().split(" ").join("-") +const wrapperClass = `header-wrapper-${depth}` --- -
-
+
+
{number} {title} @@ -39,7 +45,8 @@ const id = title.toLowerCase().split(" ").join("-") padding: var(--space-2x) 0px; } - .header-wrapper-3 { + .header-wrapper-3, + .header-wrapper-4 { scroll-margin-top: calc(var(--theme-navbar-height) + var(--space-16x)); } diff --git a/src/components/Quickstart/TableOfContents/TableOfContents.tsx b/src/components/Quickstart/TableOfContents/TableOfContents.tsx index 025e608f836..5475aec2165 100644 --- a/src/components/Quickstart/TableOfContents/TableOfContents.tsx +++ b/src/components/Quickstart/TableOfContents/TableOfContents.tsx @@ -7,10 +7,11 @@ import { useStore } from "@nanostores/preact" import { shouldUpdateToc } from "./tocStore.ts" import { clsx } from "~/lib/clsx/clsx.ts" -type HeaderWrapperClass = "header-wrapper-2" | "header-wrapper-3" +type HeaderWrapperClass = "header-wrapper-2" | "header-wrapper-3" | "header-wrapper-4" const wrapperDepthMap: Record = { "header-wrapper-2": 2, "header-wrapper-3": 3, + "header-wrapper-4": 4, } const TableOfContents: FunctionalComponent<{ @@ -42,33 +43,29 @@ const TableOfContents: FunctionalComponent<{ }, [$shouldUpdateToc]) useEffect(() => { - const observerCallback: IntersectionObserverCallback = (entries) => { - setActiveIds((activeIds) => { - const newIds = new Set(activeIds) - for (const entry of entries) { - const { isIntersecting, target } = entry - const { id } = target - if (isIntersecting) { - newIds.add(id) - } else { - newIds.delete(id) + // Scroll-based approach: find the last heading that has scrolled past the threshold + const threshold = window.innerHeight * 0.2 + + const handleScroll = () => { + let activeSlug: string | null = null + + for (const h of headings) { + const element = document.getElementById(h.slug) + if (element) { + const top = element.getBoundingClientRect().top + if (top <= threshold) { + activeSlug = h.slug } } - return newIds - }) + } + + setActiveIds(activeSlug ? new Set([activeSlug]) : new Set()) } - const elementObserver = new IntersectionObserver(observerCallback, { - rootMargin: "-20% 0% -80%", - }) + window.addEventListener("scroll", handleScroll, { passive: true }) + handleScroll() // Initial check - headings.forEach((h) => { - const element = document.getElementById(h.slug) - if (element) { - elementObserver.observe(element) - } - }) - return () => elementObserver.disconnect() + return () => window.removeEventListener("scroll", handleScroll) }, [headings]) return ( @@ -89,14 +86,14 @@ const TableOfContents: FunctionalComponent<{ > = { section: "Templates", contents: [ { - title: "Overview", - url: "cre/templates", - }, - { - title: "Custom Data Feed Template", - url: "cre/templates/running-demo-workflow", - highlightAsCurrent: ["cre/templates/running-demo-workflow-ts", "cre/templates/running-demo-workflow-go"], + title: "CRE Templates Hub", + url: "https://docs.chain.link/cre-templates", }, ], }, diff --git a/src/content.config.ts b/src/content.config.ts index 10fa1b090e7..3120ab1d897 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -86,9 +86,31 @@ const quickstartsFrontmatter = z }) .strict() +/** Schema for CRE Templates */ +const creTemplatesFrontmatter = z + .object({ + title: z.string(), + description: z.string(), + excerpt: z.string().optional(), + author: z.string(), + githubUrl: z.string(), + githubRepoLinks: z.array( + z.object({ + label: z.string(), // e.g., "Go", "TypeScript" + url: z.string(), + }) + ), // Links to GitHub folders for each language variant + image: z.string(), + featured: z.boolean().optional(), // Whether this template is featured on the hub page + datePublished: z.string().optional(), // ISO date string + lastModified: z.string().optional(), // ISO date string + }) + .strict() + /** Re-export for convenience */ export type BaseFrontmatter = z.infer export type QuickstartsFrontmatter = z.infer +export type CRETemplatesFrontmatter = z.infer export type Metadata = z.infer /** -------------------------- @@ -200,6 +222,15 @@ const quickstartsCollection = defineCollection({ schema: quickstartsFrontmatter, }) +/** CRE Templates collection */ +const creTemplatesCollection = defineCollection({ + loader: glob({ + base: "./src/content/cre-templates", + pattern: "**/*.md?(x)", + }), + schema: creTemplatesFrontmatter, +}) + const architectureOverviewCollection = defineCollection({ loader: glob({ base: "./src/content/architecture-overview", @@ -250,6 +281,7 @@ export const collections = { vrf: vrfCollection, "chainlink-local": chainlinkLocalCollection, quickstarts: quickstartsCollection, + "cre-templates": creTemplatesCollection, "architecture-overview": architectureOverviewCollection, "getting-started": gettingStartedCollection, "any-api": anyApiCollection, diff --git a/src/content/cre-templates/aws-cre-pricefeeds-por.mdx b/src/content/cre-templates/aws-cre-pricefeeds-por.mdx new file mode 100644 index 00000000000..c6ac17c3007 --- /dev/null +++ b/src/content/cre-templates/aws-cre-pricefeeds-por.mdx @@ -0,0 +1,118 @@ +--- +title: "AWS CRE Price Feeds & Proof of Reserves" +description: "Workflows using Chainlink CRE to fetch data from AWS serverless APIs and write results to Ethereum smart contracts." +excerpt: "Combine AWS reliability with decentralized trust guarantees for digital asset price feeds and proof-of-reserves monitoring." +author: "AWS" +image: "thumbnail.jpg" +githubUrl: "https://github.com/aws-samples/sample-cre-pricefeeds-por" +githubRepoLinks: + - label: "Go" + url: "https://github.com/aws-samples/sample-cre-pricefeeds-por" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion, ClickToZoom } from "@components" + +**Authored by: Simon Goldberg (AWS)** + +## Overview + +This project demonstrates workflows using the Chainlink Runtime Environment to fetch data from AWS serverless APIs and write results to Ethereum smart contracts. + +The system combines AWS reliability with decentralized trust guarantees to support digital asset price feeds and proof-of-reserves monitoring. + +## Architecture + + + +## Use Cases + +- **Price feeds for DeFi protocols**: Low-latency, tamper-resistant pricing data for lending, derivatives, and AMMs with decentralized verification. +- **Proof-of-reserves monitoring**: Continuous verification that stablecoins and wrapped assets are fully backed by underlying reserves. +- **Custom data feeds**: Configurable, multi-source data feeds for tokenized assets. + +## Components + +- **AWS Serverless Backend** - REST API with Lambda and DynamoDB for oracle data storage ([Setup Guide](https://github.com/aws-samples/sample-cre-pricefeeds-por/tree/main/price-feed-por-dynamodb-crud/README.md)) +- **CRE Workflows** - Go-based workflow for data fetching and contract updates ([Setup Guide](https://github.com/aws-samples/sample-cre-pricefeeds-por/tree/main/aws-oracle-cre/README.md)) +- **Smart Contracts** - PriceFeed and CollateralizationMonitor contracts on Ethereum Sepolia ([Contract Guide](https://github.com/aws-samples/sample-cre-pricefeeds-por/tree/main/aws-oracle-cre/contracts/evm/README.md)) + +## Prerequisites + +- **AWS CLI** - Configured with credentials ([Installation](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)) +- **AWS SAM CLI** - For serverless deployment ([Installation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html)) +- **CRE CLI** - v1.0.3+ ([Installation](https://docs.chain.link/cre/getting-started/cli-installation)) + - After installation, authenticate with `cre login` + - Verify authentication with `cre whoami` +- **Node.js** - 20+ for AWS Lambda functions +- **Go** - 1.25.3+ for CRE workflows +- **Sepolia ETH** - For contract deployment and transactions ([Get testnet ETH at a public faucet](https://faucets.chain.link)) + + + +## Quick Start + +### Automated Deployment (Recommended) + +Clone the repository and deploy everything with a single script: + +```bash +git clone https://github.com/aws-samples/sample-cre-pricefeeds-por.git +cd sample-cre-pricefeeds-por +./deploy-all.sh +``` + +This automates: + +- AWS infrastructure deployment (Lambda, API Gateway, DynamoDB) +- Smart contract deployment to Sepolia +- CRE workflow configuration and testing + +See the below for details and deeper dives. + +### Manual Deployment + + + +Deploy the serverless REST API with Lambda and DynamoDB. See [AWS Backend README](https://github.com/aws-samples/sample-cre-pricefeeds-por/tree/main/price-feed-por-dynamodb-crud/README.md) for complete setup instructions. + + + + + +Configure and run the CRE workflow to fetch data from AWS and update smart contracts on Ethereum Sepolia. See [CRE Workflow README](https://github.com/aws-samples/sample-cre-pricefeeds-por/tree/main/aws-oracle-cre/README.md) for complete setup instructions, including smart contract deployment and configuration. + + + + + +## Documentation + +- [AWS Backend Setup](https://github.com/aws-samples/sample-cre-pricefeeds-por/tree/main/price-feed-por-dynamodb-crud/README.md) +- [CRE Workflow Setup](https://github.com/aws-samples/sample-cre-pricefeeds-por/tree/main/aws-oracle-cre/README.md) +- [Smart Contract Deployment](https://github.com/aws-samples/sample-cre-pricefeeds-por/tree/main/aws-oracle-cre/contracts/evm/README.md) + +## Technology Stack + +- **Chainlink CRE** - v1.0.3 (Workflow orchestration) +- **AWS SAM** - Infrastructure as Code +- **Amazon API Gateway** - Managed API service for HTTP/REST endpoints Lambda integation and authorization +- **AWS Lambda** - Serverless compute +- **AWS DynamoDB** - NoSQL database +- **Solidity** - Smart contracts +- **Foundry** - Contract development +- **Go** - Workflow implementation + +## Security + +See [CONTRIBUTING](https://github.com/aws-samples/sample-cre-pricefeeds-por/blob/main/CONTRIBUTING.md#security-issue-notifications) for more information. + +## License + +This library is licensed under the MIT-0 License. See the [LICENSE](https://github.com/aws-samples/sample-cre-pricefeeds-por/blob/main/LICENSE) file. diff --git a/src/content/cre-templates/bring-your-own-data.mdx b/src/content/cre-templates/bring-your-own-data.mdx new file mode 100644 index 00000000000..0dab6a76e5b --- /dev/null +++ b/src/content/cre-templates/bring-your-own-data.mdx @@ -0,0 +1,66 @@ +--- +title: "Bring Your Own Data (NAV & PoR)" +description: "A template for bringing your own off-chain Proof-of-Reserve (PoR) or Net-Asset-Value (NAV) data on-chain with the Chainlink Runtime Environment (CRE)." +author: "Chainlink Labs" +excerpt: "Publish verified financial or reserve data to smart contracts using CRE." +image: "thumbnail.jpg" +githubUrl: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/bring-your-own-data" +githubRepoLinks: + - label: "Go" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/bring-your-own-data/workflow-go" + - label: "TypeScript" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/bring-your-own-data/workflow-ts" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion } from "@components" + +## What This Template Does + +This template provides an end-to-end starting point for bringing your own off-chain Proof-of-Reserve (PoR) or Net-Asset-Value (NAV) data on-chain with the **Chainlink Runtime Environment (CRE)**. + +The template consists of two components: + +- **Contracts** (deployed on multiple chains) + - [DataFeedsCache](https://github.com/smartcontractkit/chainlink-evm/blob/88d90433a15f1c34bb5fabc29be192400fad396c/contracts/src/v0.8/data-feeds/DataFeedsCache.sol) contract that receives data on-chain + - DecimalAggregatorProxy proxy contract for PoR data stored in the DataFeedsCache contract + - [BundleAggregatorProxy](https://github.com/smartcontractkit/chainlink-evm/blob/88d90433a15f1c34bb5fabc29be192400fad396c/contracts/src/v0.8/data-feeds/BundleAggregatorProxy.sol) proxy contract for NAV data stored in the DataFeedsCache contract +- **CRE Workflows** + - **Golang** workflows targeting the Golang CRE SDK + - PoR Workflow (Proof-of-Reserve) + - NAV Workflow (Net-Asset-Value) + - **TypeScript** workflows targeting the TypeScript CRE SDK + - PoR Workflow (Proof-of-Reserve) + - NAV Workflow (Net-Asset-Value) + +**Key Technologies:** + +- **CRE (Chainlink Runtime Environment)** - Orchestrates workflows with DON consensus + +--- + +## Getting Started + +You can build with the **CRE SDK** in either **Golang** or **TypeScript**. + + + +For detailed instructions on getting started with the Go SDK, see the [Go README](https://github.com/smartcontractkit/cre-templates/blob/main/starter-templates/bring-your-own-data/workflow-go/README.md) on GitHub. + + + + + +For detailed instructions on getting started with the TypeScript SDK, see the [TypeScript README](https://github.com/smartcontractkit/cre-templates/blob/main/starter-templates/bring-your-own-data/workflow-ts/README.md) on GitHub. + + + +--- + +## Security Considerations + +1. **This is a demo project** - Not production-ready +2. **DecimalAggregatorProxy contract is demo contract** - Not audited and not production-ready +3. **Use your own RPC for stability** - For stable deployment and chainwrite operations it is advised to use your own private RPCs +4. **Secrets hygiene** – Keep real secrets out of version control; use secure secret managers for `.env` values. diff --git a/src/content/cre-templates/custom-data-feed.mdx b/src/content/cre-templates/custom-data-feed.mdx new file mode 100644 index 00000000000..4deda620a0e --- /dev/null +++ b/src/content/cre-templates/custom-data-feed.mdx @@ -0,0 +1,305 @@ +--- +title: "Custom Data Feed" +description: "A template for bringing your own custom off-chain data feed on-chain with the Chainlink Runtime Environment (CRE)." +author: "Chainlink Labs" +excerpt: "Build data feeds that combine offchain APIs with onchain smart contracts." +image: "thumbnail.jpg" +githubUrl: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/custom-data-feed" +githubRepoLinks: + - label: "TypeScript" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/custom-data-feed/cre-custom-data-feed-ts" + - label: "Go" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/custom-data-feed/cre-custom-data-feed-go" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion } from "@components" + +This template provides an end-to-end starting point for bringing your own **custom data feed** on-chain with the **Chainlink Runtime Environment (CRE)**. It showcases local simulation and the core CRE workflow patterns. + +**Quick navigation:** + +- [TypeScript Implementation](#typescript-implementation) +- [Go Implementation](#go-implementation) + +--- + +## What This Template Does + +**Components:** + +- **Contracts** (Solidity) under `projectRoot/contracts/evm/src` + Example demo contracts used by the workflow: + - `ReserveManager` + - `SimpleERC20` + - `BalanceReader` + - `MessageEmitter` +- **CRE Workflow** that fetches your off-chain data and optionally performs chain writes based on configurable triggers (cron or EVM log). + +**Key Technologies:** + +- **CRE (Chainlink Runtime Environment)** – orchestrates workflows with DON consensus. + +--- + +## TypeScript Implementation + +### Getting Started with TypeScript + + + +You need to add a private key to the `.env` file. This is specifically required if you want to simulate **chain writes** (the key must be valid and funded). +If your workflow does **not** write on-chain, you can keep a dummy key: + +```bash +CRE_ETH_PRIVATE_KEY=0000000000000000000000000000000000000000000000000000000000000001 +``` + + + + + +If **Bun** is not already installed, follow the instructions at: [https://bun.sh/docs/installation](https://bun.sh/docs/installation) + +From your project root, run: + +```bash +bun install --cwd ./my-workflow +``` + + + + + +For local simulation to interact with a chain, specify RPC endpoints for the chains you interact with in `project.yaml`. This is required for submitting transactions and reading blockchain state. + +Supported for local simulation (testnet/mainnet variants): + +- Ethereum (`ethereum-testnet-sepolia`, `ethereum-mainnet`) +- Base (`ethereum-testnet-sepolia-base-1`, `ethereum-mainnet-base-1`) +- Avalanche (`avalanche-testnet-fuji`, `avalanche-mainnet`) +- Polygon (`polygon-testnet-amoy`, `polygon-mainnet`) +- BNB Chain (`binance-smart-chain-testnet`, `binance-smart-chain-mainnet`) +- Arbitrum (`ethereum-testnet-sepolia-arbitrum-1`, `ethereum-mainnet-arbitrum-1`) +- Optimism (`ethereum-testnet-sepolia-optimism-1`, `ethereum-mainnet-optimism-1`) + +Add your RPCs under `rpcs` (example): + +```yaml +rpcs: + - chain-name: ethereum-testnet-sepolia + url: +``` + +> For chain names, see the selectors list: [chain-selectors/selectors.yml](https://github.com/smartcontractkit/chain-selectors/blob/main/selectors.yml) + + + + + +Deploy the demo contracts: **BalanceReader**, **MessageEmitter**, **ReserveManager**, **SimpleERC20**. +You can deploy to a local chain or a testnet using tools like Foundry. + +For a quick start, you can also use the pre-deployed contract addresses on Ethereum Sepolia—no action required if you're just trying things out. + + + + + +Configure `config.json` for the workflow: + +- `schedule`: e.g. `"*/30 * * * * *"` (every 30 seconds), or any cron you prefer +- `url`: your off-chain data endpoint (custom data feed) +- `tokenAddress`: `SimpleERC20` contract address +- `porAddress`: `ReserveManager` contract address +- `proxyAddress`: `UpdateReservesProxySimplified` contract address +- `balanceReaderAddress`: `BalanceReader` contract address +- `messageEmitterAddress`: `MessageEmitter` contract address +- `chainSelectorName`: human-readable chain name (see selectors YAML linked above) +- `gasLimit`: gas limit used for chain writes + +Ensure `workflow.yaml` points to the config: + +```yaml +staging-settings: + user-workflow: + workflow-name: "my-workflow" + workflow-artifacts: + workflow-path: "./main.ts" + config-path: "./config.json" + secrets-path: "" +``` + + + + + +Run the command from the **project root** and pass the **path to the workflow directory**: + +```bash +cre workflow simulate +``` + +Example (for `my-workflow`): + +```bash +cre workflow simulate my-workflow +``` + +You'll see trigger options similar to: + +``` +🚀 Workflow simulation ready. Please select a trigger: +1. cron-trigger@1.0.0 Trigger +2. evm:ChainSelector:16015286601757825753@1.0.0 LogTrigger +``` + +- **Cron Trigger**: choose `1` → the workflow executes on the schedule. +- **Log Trigger**: choose `2`, then provide the example inputs: + +``` +Transaction Hash: 0x420721d7d00130a03c5b525b2dbfd42550906ddb3075e8377f9bb5d1a5992f8e +Log Event Index: 0 +``` + + + +--- + +## Go Implementation + +### Getting Started with Go + + + +Add a private key to `.env`. This is required if your workflow performs **chain writes** (must be valid and funded). +If your workflow does **not** write on-chain, you can use a dummy key: + +```bash +CRE_ETH_PRIVATE_KEY=0000000000000000000000000000000000000000000000000000000000000001 +``` + + + + + +Specify RPC endpoints for chains you interact with in `project.yaml`. This is needed to submit transactions and read state. + +Supported for local simulation (testnet/mainnet variants): + +- Ethereum (`ethereum-testnet-sepolia`, `ethereum-mainnet`) +- Base (`ethereum-testnet-sepolia-base-1`, `ethereum-mainnet-base-1`) +- Avalanche (`avalanche-testnet-fuji`, `avalanche-mainnet`) +- Polygon (`polygon-testnet-amoy`, `polygon-mainnet`) +- BNB Chain (`binance-smart-chain-testnet`, `binance-smart-chain-mainnet`) +- Arbitrum (`ethereum-testnet-sepolia-arbitrum-1`, `ethereum-mainnet-arbitrum-1`) +- Optimism (`ethereum-testnet-sepolia-optimism-1`, `ethereum-mainnet-optimism-1`) + +Add your RPC under `rpcs`: + +```yaml +rpcs: + - chain-name: ethereum-testnet-sepolia + url: +``` + + + + + +Deploy the demo contracts: **BalanceReader**, **MessageEmitter**, **ReserveManager**, **SimpleERC20** (locally or to a testnet using tools like Foundry). + +For quick trials, you can use the pre-deployed addresses on **Ethereum Sepolia**: + +- chain: `ethereum-testnet-sepolia` +- `ReserveManager`: `0x073671aE6EAa2468c203fDE3a79dEe0836adF032` +- `SimpleERC20`: `0x4700A50d858Cb281847ca4Ee0938F80DEfB3F1dd` +- `BalanceReader`: `0x4b0739c94C1389B55481cb7506c62430cA7211Cf` +- `MessageEmitter`: `0x1d598672486ecB50685Da5497390571Ac4E93FDc` + +Source code lives under `projectRoot/contracts/evm/src`. + + + + + +Generate Go bindings from ABIs (located in `projectRoot/contracts/src/abi`). +Run this **from your project root** (where `project.yaml` is): + +```bash +# Generate bindings for all contracts +cre generate-bindings evm +``` + +Bindings will appear under `contracts/evm/src/generated/`, e.g.: + +- `contracts/evm/src/generated/ierc20/IERC20.go` +- `contracts/evm/src/generated/reserve_manager/ReserveManager.go` +- `contracts/evm/src/generated/balance_reader/BalanceReader.go` + +(Template bindings are pre-generated; re-run only if ABIs/contracts change.) + + + + + +Edit `config.json`: + +- `schedule`: e.g. `"*/3 * * * * *"` (every 3 seconds) or your preferred cron +- `url`: your off-chain data endpoint (custom data feed) +- `tokenAddress`: `SimpleERC20` address +- `reserveManagerAddress`: `ReserveManager` address +- `balanceReaderAddress`: `BalanceReader` address +- `messageEmitterAddress`: `MessageEmitter` address +- `chainName`: selected chain name (see selectors YAML linked above) +- `gasLimit`: gas limit used for chain writes + +Ensure `workflow.yaml` points to the config: + +```yaml +staging-settings: + user-workflow: + workflow-name: "my-workflow" + workflow-artifacts: + workflow-path: "." + config-path: "./config.json" + secrets-path: "" +``` + + + + + +From your project root: + +```bash +cre workflow simulate my-workflow +``` + +You'll see trigger options, e.g.: + +``` +🚀 Workflow simulation ready. Please select a trigger: +1. cron-trigger@1.0.0 Trigger +2. evm:ChainSelector:16015286601757825753@1.0.0 LogTrigger +``` + +- **Cron Trigger**: choose `1` → the workflow executes immediately on the schedule. +- **Log Trigger**: choose `2` → provide the example inputs: + +``` +Transaction Hash: 0x420721d7d00130a03c5b525b2dbfd42550906ddb3075e8377f9bb5d1a5992f8e +Log Event Index: 0 +``` + + + +--- + +## Security Considerations + +1. **Demo project** – Not production-ready. +2. **Demo contracts** – Not audited; do not use as-is in production. +3. **Use your own RPCs** – For stability and performance, prefer private RPCs for deployment and chain writes. +4. **Secrets hygiene** – Keep real secrets out of version control; use secure secret managers for `.env` values. diff --git a/src/content/cre-templates/indexer-block-trigger.mdx b/src/content/cre-templates/indexer-block-trigger.mdx new file mode 100644 index 00000000000..1e381148b99 --- /dev/null +++ b/src/content/cre-templates/indexer-block-trigger.mdx @@ -0,0 +1,211 @@ +--- +title: "Indexer Block Trigger" +description: "Workflows for processing new blocks and transactions using block-triggered webhooks from Alchemy Notify." +excerpt: "Learn how to react to block events via HTTP webhook triggers and match transactions to watched addresses." +author: "Chainlink Labs" +image: "thumbnail.jpg" +githubUrl: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/indexer-block-trigger" +githubRepoLinks: + - label: "Go" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/indexer-block-trigger/block-trigger-go" + - label: "TypeScript" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/indexer-block-trigger/block-trigger-ts" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion } from "@components" + +Workflows for processing new blocks and transactions using block-triggered webhooks (from Alchemy Notify) and matching against watched addresses. These workflows demonstrate the **block trigger pattern** where the workflow reacts to incoming block data and extracts relevant transactions. + +## Directory Structure + +``` +building-blocks/indexer-block-trigger/ +├── block-trigger-go/ (Go-based workflow) +│ └── workflow/ +│ ├── main.go +│ ├── config.staging.json +│ ├── config.production.json +│ ├── workflow.yaml +│ └── README.md +├── block-trigger-ts/ (TypeScript-based workflow) + └── workflow/ + ├── main.ts + ├── package.json + ├── config.staging.json (optional) + ├── workflow.yaml + └── README.md +``` + +## Overview + +These workflows demonstrate how to: + +- React to block events via HTTP webhook triggers (We use Alchemy Notify for this workflow) +- Match transactions to a list of watched addresses +- Process and return JSON-formatted block and transaction data +- Implement the same logic in both Go and TypeScript + +Both workflows process incoming block data and extract: + +- Block number, hash, timestamp +- All transactions in the block +- Transactions where the `to` address matches a watched address + +## Workflows + + + +**Language:** Go + +**Features:** + +- Uses `http.Trigger` from CRE Go SDK +- Matches transactions to watched addresses from config +- Returns formatted JSON summary of block and matched transactions + +**Running the workflow:** + +```bash +cd building-blocks/indexer-block-trigger/block-trigger-go +cre workflow simulate workflow --non-interactive --trigger-index 0 --http-payload test-block.json --target staging-settings +``` + + + + + +**Language:** TypeScript + +**Features:** + +- Uses HTTP trigger from CRE TypeScript SDK +- Matches transactions to watched addresses from config +- Returns formatted JSON summary of block and matched transactions + +**Running the workflow:** + +```bash +cd building-blocks/indexer-block-trigger/block-trigger-ts/workflow +bun install +cre workflow simulate workflow --non-interactive --trigger-index 0 --http-payload test-block.json --target staging-settings +``` + + + +## Setup and Testing + + + +**For Go workflow:** + +1. Install CRE CLI +2. Login: `cre login` +3. Install Go + +**For TypeScript workflow:** + +1. Install CRE CLI +2. Login: `cre login` +3. Install Bun (or Node.js) +4. Run `bun install` in the workflow directory + + + + + +**Go Workflow:** + +```bash +cd building-blocks/indexer-block-trigger/block-trigger-go +cre workflow simulate workflow --non-interactive --trigger-index 0 --http-payload test-block.json --target staging-settings +``` + +**TypeScript Workflow:** + +```bash +cd building-blocks/indexer-block-trigger/block-trigger-ts +cre workflow simulate workflow --non-interactive --trigger-index 0 --http-payload test-block.json --target staging-settings +``` + + + + + +Both workflows return JSON output like: + +```json +{ + "blockNumber": 12345678, + "blockHash": "0xabc...", + "timestamp": 1700000000, + "totalLogs": 42, + "uniqueTransactions": 10, + "matchedTransactions": 2, + "transactions": [ + { + "hash": "0xdef...", + "from": "0x...", + "to": "0x73b668d8374ddb42c9e2f46fd5b754ac215495bc", + "value": "1000000000000000000" + } + ] +} +``` + + + +## Setting Up Alchemy Webhooks + + + +To use Alchemy for block-triggered workflows, follow these steps: + +1. Sign up on Alchemy and navigate to their dashboard. +2. Create a new app on the dashboard with your preferred network. +3. Click on your app to open the app dashboard and scroll down to the `services` section. +4. Click on the Webhooks service and in the pane that opens, click on `Real-time Notifications`, then click on `Get Started`. +5. Choose webhook type `Custom` to listen for new blocks or events on every new block. +6. In the custom webhook pane, add other details including webhook name, chain, network, query template, and webhook URL. +7. Click on `Create Webhook` to save the webhook and test the webhook URL. + +**Tips:** + +- Make sure your webhook URL is accessible and correctly configured to receive POST requests. +- You may want to use a tool like [Webhook.site](https://webhook.site/) for initial testing. +- Double-check the network and chain settings to match your workflow requirements. +- The query template should match the data you want to extract from each block/event. + + + +## Example Use Cases + +### 1. Monitoring High-Value Addresses + +Track transactions to specific addresses in real time: + +```json +{ + "watchedAddresses": ["0x...", "0x..."] +} +``` + +### 2. Contract Interaction Tracking + +Detect when contracts of interest receive transactions: + +```json +{ + "watchedAddresses": ["0xContract1", "0xContract2"] +} +``` + +### 3. Block-Level Analytics + +Summarize block activity and matched transactions for analytics dashboards. + +## Reference Documentation + +- [CRE Documentation](/cre) +- [Alchemy Webhooks](https://www.alchemy.com/docs/reference/custom-webhook) diff --git a/src/content/cre-templates/indexer-data-fetch.mdx b/src/content/cre-templates/indexer-data-fetch.mdx new file mode 100644 index 00000000000..01148ab01a2 --- /dev/null +++ b/src/content/cre-templates/indexer-data-fetch.mdx @@ -0,0 +1,236 @@ +--- +title: "Indexer Data Fetch" +description: "Workflows for pulling data from The Graph indexer with scheduled cron triggers using the pull pattern." +excerpt: "Learn how to query The Graph indexer using GraphQL with scheduled cron triggers." +author: "Chainlink Labs" +image: "thumbnail.jpg" +githubUrl: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/indexer-data-fetch" +githubRepoLinks: + - label: "Go" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/indexer-data-fetch/indexer-fetch-go" + - label: "TypeScript" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/indexer-data-fetch/indexer-fetch-ts" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion } from "@components" + +Workflows for pulling data from The Graph indexer with scheduled cron triggers. These workflows demonstrate the **pull pattern** where the workflow initiates and fetches data on a schedule. + +## Directory Structure + +``` +building-blocks/indexer-fetch/ +├── README.md (this file) +├── indexer-fetch-go/ (Go-based workflow) +│ └── my-workflow/ +│ ├── workflow.go +│ ├── main.go +│ ├── config.staging.json +│ ├── config.production.json +│ └── workflow.yaml +└── indexer-fetch-ts/ (TypeScript-based workflow) + └── workflow/ + ├── main.ts + ├── config.staging.json + ├── config.production.json + ├── package.json + └── workflow.yaml +``` + +## Overview + +These workflows demonstrate how to: + +- Query The Graph indexer using GraphQL +- Use cron triggers to schedule periodic data fetching +- Process and return JSON-formatted indexer data +- Implement the same functionality in both Go and TypeScript + +Both workflows query the Uniswap V4 subgraph on The Graph and fetch: + +- Pool manager statistics (pool count, transaction count, total volume) +- ETH price data from bundles + +## Workflows + + + +**Language:** Go + +**Features:** + +- Uses `http.SendRequest` pattern from CRE Go SDK +- Implements `ConsensusIdenticalAggregation` for deterministic data +- Returns formatted JSON with timestamp and endpoint info + +**Running the workflow:** + +```bash +cd building-blocks/indexer-fetch/indexer-fetch-go +cre workflow simulate my-workflow --target staging-settings +``` + + + + + +**Language:** TypeScript + +**Features:** + +- Uses `runInNodeMode` pattern from CRE TypeScript SDK +- Implements custom first-result aggregation for deterministic data +- Returns formatted JSON with timestamp and endpoint info + +**Running the workflow:** + +```bash +cd building-blocks/indexer-fetch/indexer-fetch-ts +cre workflow simulate workflow --target staging-settings +``` + + + +## Configuration + +Both workflows use the same configuration structure in their respective `config.staging.json` files: + +```json +{ + "schedule": "0 * * * * *", + "graphqlEndpoint": "https://gateway.thegraph.com/api/bca58895bc60dcb319e3cbdfd989b964/subgraphs/id/Gqm2b5J85n1bhCyDMpGbtbVn4935EvvdyHdHrx3dibyj", + "query": "{ poolManagers(first: 5) { id poolCount txCount totalVolumeUSD } bundles(first: 5) { id ethPriceUSD } }", + "variables": {} +} +``` + +### Configuration Options + +- **schedule**: Cron expression in 6-field format (second minute hour day month weekday) + - `"0 * * * * *"` - Every minute at second 0 + - `"*/30 * * * * *"` - Every 30 seconds + - `"0 */5 * * * *"` - Every 5 minutes at second 0 + +- **graphqlEndpoint**: The Graph API endpoint URL + - Gateway endpoint: `https://gateway.thegraph.com/api/{api-key}/subgraphs/id/{subgraph-id}` + - Studio endpoint: `https://api.studio.thegraph.com/query/{id}/{name}/version/latest` + +- **query**: GraphQL query string + - Simple queries without variables work best + - See The Graph documentation for query syntax + +- **variables**: Object with variables for the GraphQL query (optional) + +## Setup and Testing + + + +**For Go workflow:** + +1. Install CRE CLI +2. Login: `cre login` +3. Install Go + +**For TypeScript workflow:** + +1. Install CRE CLI +2. Login: `cre login` +3. Install Bun (or Node.js) +4. Run `bun install` in the workflow directory + + + + + +**Go Workflow:** + +```bash +cd building-blocks/indexer-fetch/indexer-fetch-go +cre workflow simulate workflow --target staging-settings +``` + +**TypeScript Workflow:** + +```bash +cd building-blocks/indexer-fetch/indexer-fetch-ts +cre workflow simulate workflow --target staging-settings +``` + + + + + +Both workflows return JSON output like: + +```json +{ + "timestamp": "2025-11-18T18:43:08.452Z", + "endpoint": "https://gateway.thegraph.com/api/.../subgraphs/id/...", + "data": { + "bundles": [ + { + "ethPriceUSD": "3157.000458184067393927942592490315", + "id": "1" + } + ], + "poolManagers": [ + { + "id": "0x498581ff718922c3f8e6a244956af099b2652b2b", + "poolCount": "5123368", + "totalVolumeUSD": "5611562100.854190095192400782985064", + "txCount": "480580367" + } + ] + } +} +``` + + + +## Example Use Cases + +### 1. Monitoring Uniswap V4 Pools + +Query pool statistics every minute: + +```json +{ + "schedule": "0 * * * * *", + "graphqlEndpoint": "https://gateway.thegraph.com/api/{key}/subgraphs/id/{id}", + "query": "{ poolManagers(first: 5) { id poolCount totalVolumeUSD } }", + "variables": {} +} +``` + +### 2. Tracking Token Prices + +Monitor token prices every 30 seconds: + +```json +{ + "schedule": "*/30 * * * * *", + "graphqlEndpoint": "https://gateway.thegraph.com/api/{key}/subgraphs/id/{id}", + "query": "{ tokens(first: 10, orderBy: volumeUSD, orderDirection: desc) { id symbol volumeUSD } }", + "variables": {} +} +``` + +### 3. DeFi Protocol Metrics + +Check protocol statistics every 5 minutes: + +```json +{ + "schedule": "0 */5 * * * *", + "graphqlEndpoint": "https://gateway.thegraph.com/api/{key}/subgraphs/id/{id}", + "query": "{ protocols(first: 1) { totalValueLockedUSD totalVolumeUSD txCount } }", + "variables": {} +} +``` + +## Reference Documentation + +- [CRE Documentation](/cre) +- [The Graph Documentation](https://thegraph.com/docs/) diff --git a/src/content/cre-templates/kv-store.mdx b/src/content/cre-templates/kv-store.mdx new file mode 100644 index 00000000000..e41731ecd8a --- /dev/null +++ b/src/content/cre-templates/kv-store.mdx @@ -0,0 +1,95 @@ +--- +title: "Key-Value Store (AWS S3)" +description: "A minimal example that reads a value from an AWS S3 object, increments it, and writes it back using SigV4-signed HTTP requests." +excerpt: "Learn offchain write patterns with secrets and consensus using AWS S3 as a key-value store." +author: "Chainlink Labs" +image: "thumbnail.jpg" +githubUrl: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/kv-store" +githubRepoLinks: + - label: "Go" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/kv-store/kv-store-go" + - label: "TypeScript" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/kv-store/kv-store-ts" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion } from "@components" + +A minimal example that, on a cron schedule, reads a value from an **AWS S3 object**, increments it, and writes it back—using **CRE (Chainlink Runtime Environment)** with SigV4-signed HTTP requests. + +The workflow: + +- Retrieves `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` from CRE Secrets +- Signs the request with AWS **SigV4** (timestamp sourced from the consensus runtime) +- Reads the S3 object (initializes to `0` if missing) +- Aggregates the **current value** across nodes (median), increments once, and writes the **agreed next value** back + +--- + +## Setup & Run + + + +Add the following secrets to your CRE environment: + +``` +AWS_ACCESS_KEY_ID +AWS_SECRET_ACCESS_KEY +``` + +(For local testing, ensure these are available to the simulator via your environment variables.) + + + + + +Create/update `my-workflow/config.json` with your S3 details: + +```json +{ + "schedule": "* * */1 * * *", + "aws_region": "my-aws-region", + "s3_bucket": "product-release-bucket", + "s3_key": "cre-counter.txt" +} +``` + +- `schedule` uses a **6-field** cron expression with seconds (e.g., `* * */1 * * *` runs every hour). +- `aws_region` is the AWS region of your bucket. +- `s3_bucket` is the bucket name. +- `s3_key` is the object path that stores the counter. + + + + + +From your project root: + +```bash +cre workflow simulate my-workflow +``` + +You should see output similar to: + +``` +Workflow compiled +2025-11-03T16:31:45Z [SIMULATION] Simulator Initialized + +2025-11-03T16:31:45Z [SIMULATION] Running trigger trigger=cron-trigger@1.0.0 +2025-11-03T16:31:45Z [USER LOG] msg="Cron trigger fired. Fetching AWS credentials..." +2025-11-03T16:31:45Z [USER LOG] msg="AWS credentials fetched. Performing consensus read, then write." +2025-11-03T16:31:45Z [USER LOG] msg="Consensus old value computed. Incrementing." old=2 new=3 +2025-11-03T16:31:45Z [USER LOG] msg="Workflow finished successfully." old=2 new=3 + +Workflow Simulation Result: + { + "NewValue": "3", + "OldValue": "2" +} + +2025-11-03T16:31:45Z [SIMULATION] Execution finished signal received +2025-11-03T16:31:45Z [SIMULATION] Skipping WorkflowEngineV2 +``` + + diff --git a/src/content/cre-templates/multi-chain-token-manager.mdx b/src/content/cre-templates/multi-chain-token-manager.mdx new file mode 100644 index 00000000000..6f5ca611e13 --- /dev/null +++ b/src/content/cre-templates/multi-chain-token-manager.mdx @@ -0,0 +1,62 @@ +--- +title: "Multi-Chain Token Manager" +description: "A multi-chain token manager that maximizes lending yields via automated cross-chain rebalancing using CRE integrated with CCIP." +author: "Chainlink Labs" +excerpt: "Manage token operations across different EVM chains with cross-chain coordination patterns." +image: "thumbnail.jpg" +githubUrl: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/multi-chain-token-manager" +githubRepoLinks: + - label: "Go" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/multi-chain-token-manager/workflow-go" + - label: "TypeScript" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/multi-chain-token-manager/workflow-ts" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion } from "@components" + +## What This Template Does + +This template provides an end-to-end starting point for writing your own multi-chain token manager that maximizes supply APY by rebalancing tokens cross-chain with the **Chainlink Runtime Environment (CRE)** via the **Cross-Chain Interoperability Protocol (CCIP)**. + +The template consists of two components: + +- **Contracts** (deployed on multiple chains) + - `MockPool` contract that mimics an AAVE liquidity pool + - `ProtocolSmartWallet` contract that manages lending positions +- **CRE Workflow** that monitors supply APY of a target asset on each chain and automatically rebalances lending positions (to maximize supply APY) + - **Golang** workflow targeting the Golang CRE SDK + - **TypeScript** workflow targeting the TypeScript CRE SDK + +**Key Technologies:** + +- **CRE (Chainlink Runtime Environment)** - Orchestrates workflow with DON consensus +- **CCIP (Cross-Chain Interoperability Protocol)** - Secure token bridging with instructions + +--- + +## Getting Started + +You can build with the **CRE SDK** in either **Golang** or **TypeScript**. + + + +For detailed instructions on getting started with the Go SDK, see the [Go README](https://github.com/smartcontractkit/cre-templates/blob/main/starter-templates/multi-chain-token-manager/workflow-go/README.md) on GitHub. + + + + + +For detailed instructions on getting started with the TypeScript SDK, see the [TypeScript README](https://github.com/smartcontractkit/cre-templates/blob/main/starter-templates/multi-chain-token-manager/workflow-ts/README.md) on GitHub. + + + +--- + +## Security Considerations + +1. **This is a demo project** - Not production-ready +2. **Contracts are examples** - Write your own audited contracts for your use case +3. **Use your own RPC for stability** - For stable deployment and chainwrite operations it is advised to use your own private RPCs +4. **Secrets hygiene** – Keep real secrets out of version control; use secure secret managers for `.env` values. diff --git a/src/content/cre-templates/prediction-market-demo.mdx b/src/content/cre-templates/prediction-market-demo.mdx new file mode 100644 index 00000000000..9914f0d857b --- /dev/null +++ b/src/content/cre-templates/prediction-market-demo.mdx @@ -0,0 +1,392 @@ +--- +title: "Prediction Market Demo" +description: "An end-to-end automated, AI-powered prediction market using CRE integrated with Google's Gemini AI and Firebase." +excerpt: "Build a fully automated prediction market system with CRE, Gemini AI, Solidity smart contracts, and a Next.js frontend." +author: "Chainlink Labs" +image: "thumbnail.jpg" +featured: true +githubUrl: "https://github.com/smartcontractkit/cre-gcp-prediction-market-demo" +githubRepoLinks: + - label: "TypeScript" + url: "https://github.com/smartcontractkit/cre-gcp-prediction-market-demo" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion } from "@components" + +This demo showcases an end-to-end **automated, AI-powered prediction market** using the **Chainlink Runtime Environment (CRE)** integrated with Google's Gemini AI and Firebase. Users create binary (Yes/No) prediction markets on-chain, stake USDC tokens, and CRE automatically settles outcomes using AI-powered fact-checking. + +## What This Demo Does + +This project showcases how to build a fully automated prediction market system where: + +1. Users create markets by asking binary (Yes/No) questions on-chain +2. Users stake ERC-20 tokens (USDC) to make predictions +3. After the market closes, anyone can request settlement +4. **CRE automatically triggers** when it detects the settlement request +5. **Gemini AI** determines the factual outcome using Google search grounding +6. **CRE submits** a cryptographically signed settlement report back on-chain +7. Settlement data is stored in **Firestore** for audit and display +8. Winners claim their proportional share of the total pool + +**Key Technologies:** + +- **Smart Contracts**: Solidity prediction market with CRE receiver integration +- **CRE**: Event-driven workflow orchestration +- **Gemini AI**: Automated fact-checking and outcome determination +- **Firebase/Firestore**: Audit trail and data persistence +- **Next.js Frontend**: User interface for viewing settlement history + +## Security Considerations + +{/* prettier-ignore */} + + +## Repository Structure + +This repository contains three main components: + +``` +. +├── contracts/ # Foundry project: SimpleMarket.sol and deployment scripts +├── cre-workflow/ # CRE TypeScript workflow for AI-powered settlement +├── frontend/ # Next.js app for viewing settlement data from Firestore +├── firebase-setup.md # Firebase/Firestore configuration guide +└── README.md +``` + +### CRE Workflow Directory + +A Chainlink Runtime Environment project containing: + +- TypeScript workflow orchestration +- Gemini AI integration +- EVM settlement logic +- Firestore database integration +- Configuration and secrets management + +### Contracts Directory + +A Foundry project containing: + +- `SimpleMarket.sol` - Binary prediction market smart contract +- Comprehensive test suite +- Deployment and interaction scripts +- CRE receiver template integration + +### Frontend Directory + +A Next.js application that: + +- Connects to Firestore database +- Displays recent market settlements +- Shows AI responses, confidence scores, and transaction hashes +- Provides a simple UI for monitoring the system + +## Prerequisites + +To run this demo, you'll need: + +- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +- [Node.js](https://nodejs.org/en/download) v20+ +- [Bun](https://bun.sh/) (JavaScript runtime and package manager) +- [Foundry/Forge](https://github.com/foundry-rs/foundry) (`forge`, `cast`, `anvil`) +- [Chainlink Runtime Environment CLI](https://docs.chain.link/cre) +- [Gemini API Key](https://aistudio.google.com/api-keys) +- [Firebase Project](https://github.com/smartcontractkit/cre-gcp-prediction-market-demo/blob/main/firebase-setup.md) with Firestore enabled +- [ETH Sepolia funds](https://faucets.chain.link/) for gas +- [USDC on Sepolia](https://faucet.circle.com/) for market participation + +## Quick Start + +### Option 1: Test CRE Workflow Only (Fastest) + +This repo ships with the address of a pre-deployed contract and transaction for immediate testing. + + + +Install the workflow dependencies: + +```bash +cd cre-workflow/prediction-market-demo +bun install +``` + +Configure the RPC endpoint by editing `cre-workflow/project.yaml` and setting your Sepolia RPC URL for `local-simulation`. + + + + + +Navigate back to the `cre-workflow` directory and create your `.env` file: + +```bash +cd .. # Back to cre-workflow directory +cp .env.example .env +``` + +Populate the `.env` file with the following values: + +```bash +CRE_ETH_PRIVATE_KEY=0x... # Private key with Sepolia ETH +CRE_TARGET=local-simulation +GEMINI_API_KEY_VAR=... # From https://aistudio.google.com/api-keys +FIREBASE_API_KEY_VAR=... # From Firebase console +FIREBASE_PROJECT_ID_VAR=... # From Firebase console +``` + +See the [prerequisites](#prerequisites) section for information on obtaining your Gemini and Firebase keys. + + + + + +Run the CRE workflow simulation: + +```bash +cre workflow simulate prediction-market-demo --target local-simulation +``` + +When prompted, use this pre-deployed transaction: + +- **Transaction hash**: `0x24f3ccee54786d754ee07e4b8578ff6916c3cfca6e0f6fd71675aaad0039bc19` +- **Event index**: `0` + + + +### Option 2: Full End-to-End Test + + + +```bash +git clone https://github.com/smartcontractkit/cre-gcp-prediction-market-demo.git +cd cre-gcp-prediction-market-demo +``` + + + + + +Install contract dependencies and set environment variables: + +```bash +cd contracts +forge install +export PRIVATE_KEY=... +export RPC_URL=... +``` + +Deploy a new SimpleMarket contract. The constructor arguments are: (1) the payment token address (USDC on ETH Sepolia) and (2) the CRE forwarder address ([ETH Sepolia CRE Simulation Forwarder](https://docs.chain.link/cre/guides/workflow/using-evm-client/supported-networks-ts#understanding-forwarder-addresses)). + +```bash +forge create src/SimpleMarket.sol:SimpleMarket \ + --broadcast \ + --rpc-url $RPC_URL \ + --private-key $PRIVATE_KEY \ + --constructor-args 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238 0x15fC6ae953E024d975e77382eEeC56A9101f9F88 +``` + +Note down the new contract address and export it: + +```bash +export MARKET_ADDRESS=... +``` + + + + + + + +Get the next available market ID: + +```bash +cast call $MARKET_ADDRESS \ + "nextMarketId()" \ + --rpc-url $RPC_URL +``` + +Convert from hex to decimal: + +```bash +cast to-dec 0x000000000000000000000000000000000000000000000000000000000000001c +# Example output: 28 +# The first market ID for a new contract will be 0. +``` + +Create a new market: + +```bash +cast send $MARKET_ADDRESS \ + "newMarket(string)" \ + "Will the buffalo bills win the 2025 superbowl?" \ + --rpc-url $RPC_URL \ + --private-key $PRIVATE_KEY +``` + + + + + + + +Approve USDC spending: + +```bash +cast send 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238 \ + "approve(address,uint256)" \ + $MARKET_ADDRESS \ + 1000000 \ + --rpc-url $RPC_URL \ + --private-key $PRIVATE_KEY +``` + +Place your prediction (Outcome: 1 = No, 2 = Yes): + +```bash +cast send $MARKET_ADDRESS \ + "makePrediction(uint256,uint8,uint256)" \ + 0 \ + 2 \ + 1000000 \ + --rpc-url $RPC_URL \ + --private-key $PRIVATE_KEY +``` + + + + + +Install workflow dependencies: + +```bash +cd ../cre-workflow/prediction-market-demo +bun install +``` + +Add your market address to `cre-workflow/prediction-market-demo/config.json`: + +```json +{ + "geminiModel": "gemini-2.5-flash", + "evms": [ + { + "marketAddress": "", + "chainSelectorName": "ethereum-testnet-sepolia", + "gasLimit": "1000000" + } + ] +} +``` + +Add ETH Sepolia RPC URL to `cre-workflow/project.yaml`: + +```yaml +local-simulation: + rpcs: + - chain-name: ethereum-testnet-sepolia + url: +``` + +Set up environment variables: + +```bash +cd .. +cp .env.example .env +``` + +Populate `.env` with your keys: + +``` +CRE_ETH_PRIVATE_KEY= +CRE_TARGET=local-simulation +GEMINI_API_KEY_VAR= +FIREBASE_API_KEY_VAR= +FIREBASE_PROJECT_ID_VAR= +``` + + + + + + + +Request settlement: + +```bash +cast send $MARKET_ADDRESS \ + "requestSettlement(uint256)" \ + 0 \ + --rpc-url $RPC_URL \ + --private-key $PRIVATE_KEY +``` + +Note the transaction hash. Then simulate the workflow: + +```bash +cre workflow simulate prediction-market-demo --target local-simulation +``` + +When prompted, enter the transaction hash and log index `0`. + +To broadcast and write results on-chain: + +```bash +cre workflow simulate prediction-market-demo --target local-simulation --broadcast +``` + + + + + +Claim your prediction if you won: + +```bash +cast send $MARKET_ADDRESS \ + "claimPrediction(uint256)" \ + 0 \ + --rpc-url $RPC_URL \ + --private-key $PRIVATE_KEY +``` + +To run the frontend: + +```bash +cd ../frontend +bun install +cp .env.local.example .env.local +``` + +Add your Firebase credentials to `.env.local`: + +``` +NEXT_PUBLIC_FIREBASE_API_KEY="your-api-key" +NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN="your-auth-domain" +NEXT_PUBLIC_FIREBASE_PROJECT_ID="your-project-id" +``` + +Start the development server: + +```bash +bun run dev +``` + +The frontend will be available at `http://localhost:3000`. + + diff --git a/src/content/cre-templates/read-data-feeds.mdx b/src/content/cre-templates/read-data-feeds.mdx new file mode 100644 index 00000000000..b1877a1f621 --- /dev/null +++ b/src/content/cre-templates/read-data-feeds.mdx @@ -0,0 +1,63 @@ +--- +title: "Read Data Feeds" +description: "A set of minimal examples that read from Chainlink Data Feeds using the CRE chain reader on a cron schedule." +excerpt: "Learn how to read onchain data via contract calls using Chainlink Data Feeds." +author: "Chainlink Labs" +image: "thumbnail.jpg" +githubUrl: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/read-data-feeds" +githubRepoLinks: + - label: "Go" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/read-data-feeds/read-data-feeds-go" + - label: "TypeScript" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/read-data-feeds/read-data-feeds-ts" + - label: "Go (MVR)" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/read-data-feeds/read-mvr-data-feeds-go" + - label: "TypeScript (MVR)" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/building-blocks/read-data-feeds/read-mvr-data-feeds-ts" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion } from "@components" + +A set of minimal examples that, on a cron schedule (every 10 minutes), read from Chainlink Data Feeds using the CRE chain reader. + +There are **two types of examples**: + +## 1. Regular (single-value) price feeds + +Reads `decimals()` and `latestAnswer()` from Chainlink Data Feeds (e.g. BTC/USD, ETH/USD), logs the scaled values, and returns a JSON array of results. + +- Example network: **Arbitrum One (mainnet)**. + +Production contracts: + +- BTC/USD on Arbitrum One: [0x6ce185860a4963106506C203335A2910413708e9](https://arbiscan.io/address/0x6ce185860a4963106506C203335A2910413708e9#code) +- ETH/USD on Arbitrum One: [0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612](https://arbiscan.io/address/0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612#code) + +## 2. MVR (Multiple Variable Response) bundle feeds + +Reads `latestBundle()` and `bundleDecimals()` from a Chainlink **BundleAggregatorProxy**, decodes the returned bytes into multiple typed fields, and returns a structured JSON object (including scaled numeric values). + +- Example network: **Base mainnet**. +- Example MVR feed: **S&P Global SSA EURC**. + +References: + +- Production MVR feed overview (S&P Global SSA EURC on Base): [data.chain.link/feeds/base/base/sp-global-ssa-eurc](https://data.chain.link/feeds/base/base/sp-global-ssa-eurc) +- BundleAggregatorProxy contract on Base: [basescan.org/address/0xcF99622B5440a338f45daEE134d531A4BE64251F](https://basescan.org/address/0xcF99622B5440a338f45daEE134d531A4BE64251F#code) +- [MVR decoding guide (Solidity / EVM)](/data-feeds/mvr-feeds/guides/evm-solidity) + +--- + +## Get Started + +Language-specific examples (both regular and MVR) live under the `building-blocks/read-data-feeds` directory. + +- To get started with **Go (regular data feeds)**, see the [Go README](https://github.com/smartcontractkit/cre-templates/blob/main/building-blocks/read-data-feeds/read-data-feeds-go/README.md). + +- To get started with **TypeScript (regular data feeds)**, see the [TypeScript README](https://github.com/smartcontractkit/cre-templates/blob/main/building-blocks/read-data-feeds/read-data-feeds-ts/README.md). + +- To get started with **Go MVR bundle feeds**, use the Go example that reads `latestBundle()` / `bundleDecimals()` from the S&P Global SSA EURC feed on Base (see the corresponding Go README in the MVR example directory). + +- To get started with **TypeScript MVR bundle feeds**, use the TypeScript example that reads and decodes the same MVR feed on Base (see the corresponding TypeScript README in the MVR example directory). diff --git a/src/content/cre-templates/stablecoin-ace-ccip.mdx b/src/content/cre-templates/stablecoin-ace-ccip.mdx new file mode 100644 index 00000000000..f80ad960ac9 --- /dev/null +++ b/src/content/cre-templates/stablecoin-ace-ccip.mdx @@ -0,0 +1,239 @@ +--- +title: "Stablecoin with PoR, ACE & CCIP" +description: "A demo stablecoin issuance system demonstrating CRE integrated with Proof of Reserve (PoR), Automated Compliance Engine (ACE), and Cross-Chain Interoperability Protocol (CCIP)." +author: "Chainlink Labs" +excerpt: "Build a compliant, multi-chain stablecoin using Chainlink's complete service stack." +image: "thumbnail.jpg" +githubUrl: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/stablecoin-ace-ccip" +githubRepoLinks: + - label: "TypeScript" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/stablecoin-ace-ccip" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion } from "@components" + +## What This Template Does + +This repository demonstrates how financial institutions can build a **secure, compliant, multi-chain stablecoin** using Chainlink's complete service stack. The demo progresses through three phases: + +**Phase 1:** Traditional banks trigger stablecoin minting and redemption using SWIFT-style messages via HTTP. CRE orchestrates the workflow, validates messages, and submits cryptographically-signed reports to mint or burn tokens on-chain. + +**Phase 2:** Cross-chain stablecoin transfers using CCIP. Users can transfer tokens between Ethereum Sepolia and Avalanche Fuji testnets with automatic token burning on the source chain and minting on the destination. + +**Phase 3:** Advanced multi-service integration (production requires additional audits and hardening) that combines: + +1. **Proof of Reserve (PoR)** - Validates sufficient off-chain reserves before minting (prevents over-collateralization issues) +2. **Automated Compliance Engine (ACE)** - Enforces on-chain policies like address blacklisting for regulatory compliance +3. **CCIP** - Secure cross-chain transfers with compliance checks at both mint and transfer stages + +**Key Technologies:** + +- **CRE (Chainlink Runtime Environment)** - Orchestrates multi-service workflows with DON consensus +- **PoR (Proof of Reserve)** - External reserve validation +- **ACE (Automated Compliance Engine)** - On-chain policy enforcement +- **CCIP (Cross-Chain Interoperability Protocol)** - Secure token bridging + +--- + +## How It Works + +### Flow 1: Stablecoin Issuance with PoR + ACE + +```mermaid +sequenceDiagram + actor User + participant CRE as CRE Workflow + participant PoR as PoR API + participant Forwarder as CRE Forwarder + participant Consumer as MintingConsumerWithACE + participant Stablecoin as Stablecoin Contract + + User->>CRE: HTTP Trigger (Deposit $1000 USD) + CRE->>PoR: HTTP Capability (Fetch Reserves) + PoR-->>CRE: Reserves: $500,000 + alt Sufficient Reserves + CRE->>Forwarder: On Chain Write (Submit Mint Report) + Forwarder->>Consumer: Call onReport() + Consumer->>Consumer: Run PolicyEngine (BlacklistPolicy) + alt Not Blacklisted + Consumer->>Stablecoin: mint(user, 1000e18) + Stablecoin-->>User: Tokens Minted + else Blacklisted + Consumer-->>User: Minting Failed + end + else Insufficient Reserves + CRE-->>User: PoR Validation Failed + end +``` + +### Flow 2: Cross-Chain Transfer with ACE + +```mermaid +sequenceDiagram + actor Sender + participant CRE as CRE Workflow + participant Consumer as CCIPTransferConsumerWithACE + participant Stablecoin as Stablecoin Contract + participant Router as CCIP Router + participant Destination as Destination Chain + + Sender->>CRE: HTTP Trigger (Transfer 500 tokens to Fuji) + CRE->>Consumer: Call onReport() + Consumer->>Consumer: Run PolicyEngine (VolumePolicy) + alt Amount Within Limit + Consumer->>Router: ccipSend(destinationChain, message) + Router->>Stablecoin: Burn Tokens on Source + Router->>Destination: Send CCIP Message (~10-20 min) + CRE-->>Sender: Transfer Initiated + else Amount Exceeds Limit + CRE-->>Sender: Transfer Failed + end +``` + +--- + +## Repository Structure + +### Workflows Directory + +Three progressive CRE workflows demonstrating increasing complexity: + +- `bank-stablecoin-workflow/` - Phase 1: Basic mint/redeem operations +- `ccip-transfer-workflow/` - Phase 2: Cross-chain CCIP transfers +- `bank-stablecoin-por-ace-ccip-workflow/` - Phase 3: PoR + ACE + CCIP integration + +### Contracts Directory + +Smart contracts for stablecoin and ACE integration: + +- `StablecoinERC20.sol` - Core stablecoin with mint/burn roles +- `MintingConsumer.sol` - Phase 1: Basic CRE consumer +- `CCIPTransferConsumer.sol` - Phase 2: CCIP consumer +- `MintingConsumerWithACE.sol` - Phase 3: ACE-protected mint consumer +- `CCIPTransferConsumerWithACE.sol` - Phase 3: ACE-protected CCIP consumer +- `policies/AddressBlacklistPolicy.sol` - ACE blacklist policy +- `extractors/UnifiedExtractor.sol` - ACE parameter extractor for both mint and CCIP operations + +--- + +## Prerequisites + +To run this demo, you'll need: + +**Tools:** + +- Git +- [Foundry](https://book.getfoundry.sh/getting-started/installation) (`forge`, `cast`, `anvil`) +- [Bun](https://bun.sh/) (JavaScript runtime and package manager) +- [Chainlink Runtime Environment CLI](https://docs.chain.link/cre) + +**Testnet Funds:** + +- ETH on Sepolia testnet ([Chainlink Faucet](https://faucets.chain.link)) +- ETH on Fuji testnet +- LINK tokens + +--- + +## Getting Started + + + +This repo includes pre-deployed Phase 3 contracts on Sepolia for immediate testing. + +**Pre-Deployed Contracts on Sepolia:** + +| Contract | Address | +| ---------------------------- | -------------------------------------------- | +| StablecoinERC20 | `0xF9ec4EE99B992A6AA5C70619092E2c605480dE8e` | +| BurnMintTokenPool | `0x37BeD199bBDCfd86B01989bE271EC022430FE2D6` | +| PolicyEngine | `0x697B79dFdbe5eD6f9d877bBeFac04d7A28be5CA1` | +| AddressBlacklistPolicy | `0xA5Db8159CD4084570FD248A7ec8457B3E348c3A6` | +| VolumePolicy (100-10k range) | `0xfd09CF4Db1eB6e8a75653C29816e56095A3B2b56` | +| MintingConsumerWithACE | `0x24c0f5C1A286Fbd27A730303a1a845b4cf85F0Cc` | +| CCIPTransferConsumerWithACE | `0xFa031de805af3a9A72D37f57a01634ADF4a61cD5` | + +**Quick Test Steps:** + +```bash +# Create configuration files +cp .env.example .env +cp secrets.yaml.example secrets.yaml + +# Set project root +export CRE_PROJECT_ROOT=$(pwd) + +# Install workflow dependencies +cd bank-stablecoin-por-ace-ccip-workflow && bun install && cd .. + +# Dry run test (no wallet/gas needed) +cre workflow simulate bank-stablecoin-por-ace-ccip-workflow \ + --target local-simulation \ + --trigger-index 0 \ + --non-interactive \ + --http-payload @$CRE_PROJECT_ROOT/bank-stablecoin-por-ace-ccip-workflow/http_trigger_payload.json +``` + + + + + +Choose your learning path: + +**Incremental (Recommended for Learning):** + +Build the system step-by-step across 3 progressive phases. Each phase adds new capabilities: + +- [Phase 1: Basic Stablecoin](https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/stablecoin-ace-ccip/bank-stablecoin-workflow) - Deploy stablecoin with mint/redeem +- [Phase 2: Cross-Chain CCIP](https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/stablecoin-ace-ccip/ccip-transfer-workflow) - Add cross-chain transfers +- [Phase 3: PoR + ACE + CCIP](https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/stablecoin-ace-ccip/bank-stablecoin-por-ace-ccip-workflow) - Production-ready setup + + + +--- + +## CRE + PoR + ACE + CCIP Capabilities + +This demo showcases the complete Chainlink service stack working together: + +| Service | Usage in Demo | Benefit | +| ------------------------------- | ------------------------------------------- | ------------------------------------------------ | +| **CRE (Runtime Environment)** | Orchestrates multi-service workflows | Off-chain computation with on-chain verification | +| **PoR (Proof of Reserve)** | Validates off-chain reserves before minting | Prevents over-collateralization | +| **ACE (Compliance Engine)** | Enforces address blacklist policies | Regulatory compliance (sanctions, AML) | +| **CCIP (Cross-Chain Protocol)** | Secure token transfers between chains | Burn-and-mint cross-chain bridging | + +**CRE Capabilities Demonstrated:** + +- ✅ **HTTP Triggers** - Banking system integration via REST API +- ✅ **Node Mode** - Fetch external data (PoR Mock Data) with DON consensus +- ✅ **EVM Capabilities** - Write signed reports on-chain +- ✅ **Multi-Service Orchestration** - Coordinate PoR → ACE → Mint → CCIP flows + +**ACE Capabilities Demonstrated:** + +- ✅ **PolicyEngine** - Central policy registry and execution +- ✅ **Custom Extractors** - Parse CRE's `onReport(bytes,bytes)` function +- ✅ **Address Blacklist Policy** - Block mints/transfers to sanctioned addresses +- ✅ **Upgradeable Proxies** - ERC-1967 pattern for all ACE components + +--- + +## Troubleshooting + +**Quick Tips:** + +- **Workflow won't compile?** → Run `cd && bun install` +- **ACE not blocking?** → See the TROUBLESHOOTING.md in the repository +- **CCIP not arriving?** → Wait 10-20 min, check [CCIP Explorer](https://ccip.chain.link) + +--- + +## Security Considerations + +1. **This is a demo project** - Not production-ready +2. **Verify PoR data sources** - Demo uses mock data; real implementations should use live PoR feeds +3. **ACE policies are examples** - Customize policies for your compliance requirements +4. **Use your own RPC for stability** - For stable deployment and chainwrite operations it is advised to use your own private RPCs diff --git a/src/content/cre-templates/tokenized-asset-servicing.mdx b/src/content/cre-templates/tokenized-asset-servicing.mdx new file mode 100644 index 00000000000..c360345cfe7 --- /dev/null +++ b/src/content/cre-templates/tokenized-asset-servicing.mdx @@ -0,0 +1,271 @@ +--- +title: "Tokenized Asset Servicing" +description: "Demonstrates CRE integration with LogTrigger and HTTP abilities to enable seamless off-chain data orchestration for tokenized assets." +author: "Chainlink Labs" +excerpt: "Track the full lifecycle of tokenized real-world assets using CRE, AWS DynamoDB, and Lambda." +image: "thumbnail.jpg" +githubUrl: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/tokenized-asset-servicing" +githubRepoLinks: + - label: "TypeScript" + url: "https://github.com/smartcontractkit/cre-templates/tree/main/starter-templates/tokenized-asset-servicing" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion } from "@components" + +## What This Template Does + +This project demonstrates the integration of Chainlink Runtime Environment (CRE) with LogTrigger and HTTP abilities to enable seamless off-chain data orchestration for tokenized assets. The project tokenizes various real-world assets (RWAs) using Ethereum Solidity smart contracts and leverages Chainlink CRE, AWS DynamoDB, and Lambda functions to track the full lifecycle of these tokenized assets. + +### Tokenization and Lifecycle Management + +The core of this project is an Ethereum-based Solidity smart contract that facilitates the tokenization of diverse asset classes, including invoices, Treasury bills (T-bills), loans, and carbon credits. Users interact with the contract via specialized functions to manage asset operations, such as: + +- **Register**: Onboard a new asset into the system. +- **Verify**: Validate asset authenticity and compliance. +- **Transfer**: Execute peer-to-peer asset transfers. +- **Redeem**: Liquidate or burn tokens to redeem underlying value. + +To support generalized use cases, regulators, auditors, and investors require robust monitoring and auditing capabilities for these tokenized assets and their associated operations. While on-chain data is immutable and verifiable via the blockchain, querying it directly is inefficient and lacks user-friendly interfaces due to the opaque nature of raw transaction logs. + +This project addresses these challenges by employing Chainlink CRE to bridge on-chain events with off-chain storage and retrieval: + +- **LogTrigger** captures events emitted by the tokenization platform contract. +- Extracted event data is parsed, normalized, and encapsulated into a structured HTTP payload. +- The **HTTP Ability** dispatches this payload as a RESTful API request to an AWS Lambda function. +- The Lambda function persists the processed data into an AWS DynamoDB NoSQL database. + +This architecture decouples on-chain immutability from off-chain accessibility, providing stakeholders with near-real-time visibility into asset lifecycles without compromising blockchain integrity. + +--- + +## Flow Diagram + +```mermaid +sequenceDiagram + participant Contract as Smart Contract
(Ethereum Sepolia) + participant CRE as Chainlink CRE
(LogTrigger/HTTPTrigger) + participant Lambda as AWS Lambda + participant DynamoDB as AWS DynamoDB + + Note over Contract,DynamoDB: Asset Registration Flow + Contract->>Contract: Emit AssetRegistered event + Contract-->>CRE: Event Log (LogTrigger) + CRE->>CRE: Parse event data + CRE->>Lambda: POST /function-url (HTTP Ability) + Lambda->>DynamoDB: PutItem (AssetId, Name, Issuer, Supply) + + Note over Contract,DynamoDB: Asset Verification Flow + Contract->>Contract: Emit AssetVerified event + Contract-->>CRE: Event Log (LogTrigger) + CRE->>Lambda: POST verification data + Lambda->>DynamoDB: UpdateItem (Add Verified: true) + + Note over Contract,DynamoDB: UID Update Flow (Bidirectional) + CRE->>CRE: Receive HTTP Trigger + CRE->>Contract: updateAssetMetadata(assetId, uid) +``` + +--- + +## Prerequisites + +Before proceeding, ensure the following are set up: + +**Tools:** + +- [CRE CLI](https://docs.chain.link/cre/getting-started/cli-installation/macos-linux) +- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +- [Node.js](https://nodejs.org/en) (v18+ recommended) +- [Bun](https://bun.sh/) + +**Blockchain:** + +- Ethereum Sepolia testnet access (e.g., via Alchemy or Infura RPC endpoint) +- Sepolia test tokens (ETH) for gas + +**AWS:** + +- AWS account (Free Tier eligible) with IAM roles for DynamoDB and Lambda + +--- + +## Getting Started + + + +```bash +git clone https://github.com/smartcontractkit/cre-templates.git +cd cre-templates/starter-templates/tokenized-asset-servicing/ +``` + +You can update the Ethereum Sepolia RPC url with yours or use the default one in `project.yaml`: + +```yaml +local-simulation: + rpcs: + - chain-name: ethereum-testnet-sepolia + url: +``` + + + + + +Change to the contracts directory and install dependencies: + +```bash +npm install +``` + +Deploy the contract to Ethereum Sepolia testnet: + +```bash +npx tsx ./1_deploy.ts +``` + +Then create the config file and update it with your deployed contract address: + +```bash +cd ../asset-log-trigger-workflow +cp config.json.example config.json +``` + +Update `assetAddress` in `config.json` with your deployed contract address. + + + + + +1. Go to the [AWS Management Console](https://aws.amazon.com/console/) +2. Search for DynamoDB and create a table named `AssetState` with partition key: `AssetId` (string) +3. Leave other settings as default + + + + + +1. Search for Lambda in AWS dashboard +2. Create a new function named `Asset-lambda-function` with Node.js 22 runtime +3. Copy the Lambda function code from `lambda-function/index.mjs` in the repository +4. Update the `yourAwsRegion` and `TABLE_NAME` variables +5. Deploy the function +6. Under Configuration → Function URL, create a URL with "NONE" auth type +7. Add the function URL to `asset-log-trigger-workflow/config.json` +8. Grant the Lambda function `AmazonDynamoDBFullAccess` permission via IAM + + + + + +```bash +cd asset-log-trigger-workflow +bun install +``` + +Create a `.env` file from the example: + +```bash +cd .. +cp .env.example .env +``` + +Add your private key (without the 0x prefix) to the `.env` file. + + + +--- + +## Usage Examples + + + +From the contracts directory: + +```bash +npx tsx ./2_registerNewAsset.ts +``` + +Then trigger CRE with the event log: + +```bash +cd ../asset-log-trigger-workflow +cre workflow simulate asset-log-trigger-workflow --broadcast --target local-simulation +``` + +Select LogTrigger (option 1) and enter the transaction hash and event index (1 for AssetRegistered). + + + + + +```bash +npx tsx ./3_verifyAsset.ts +``` + +Then trigger CRE with event index 0 for the AssetVerified event. + + + + + +```bash +cre workflow simulate asset-log-trigger-workflow --broadcast --target local-simulation +``` + +Select HttpTrigger (option 2) and enter a JSON payload: + +```json +{ "assetId": 1, "uid": "bca71bc9-d08e-48ef-8ad1-acefe95505a9" } +``` + +Verify the update: + +```bash +npx tsx ./4_readUid.ts +``` + + + + + +```bash +npx tsx ./5_mint.ts +``` + +Then trigger CRE with event index 1 for the TokensMinted event. + + + + + +```bash +npx tsx ./6_redeem.ts +``` + +Then trigger CRE with event index 1 for the TokensRedeemed event. + + + +--- + +## Troubleshooting + +**AWS Lambda Internal Server Error on Invocation:** +Verify that the Lambda execution role has the necessary IAM permissions for DynamoDB operations (e.g., `dynamodb:PutItem`, `dynamodb:UpdateItem`). Check CloudWatch Logs for detailed error traces. + +**Chainlink CRE Fails to Detect Events:** +Transactions may emit multiple events in sequence; ensure the LogTrigger targets the correct event index. Use Etherscan to inspect raw logs and correlate with CRE configuration. + +**Solidity Compilation Errors:** +These often stem from version incompatibilities in OpenZeppelin contracts. Use OpenZeppelin v5.x for ERC-1155 implementations. + +--- + +## Security Considerations + +1. **This is a demo project** - Not production-ready +2. **Lambda function security** - In production, use proper authentication for Function URLs +3. **IAM permissions** - Follow least-privilege principles for production deployments +4. **Secrets hygiene** – Keep real secrets out of version control; use secure secret managers for `.env` values. diff --git a/src/content/cre-templates/x402-price-alerts.mdx b/src/content/cre-templates/x402-price-alerts.mdx new file mode 100644 index 00000000000..24bc2b6d0d6 --- /dev/null +++ b/src/content/cre-templates/x402-price-alerts.mdx @@ -0,0 +1,614 @@ +--- +title: "x402 Crypto Price Alerts" +description: "A crypto price alert system integrating x402 micropayments, Chainlink CRE workflows, and Gemini AI for natural language interaction." +excerpt: "Build a complete crypto price alert system with x402 payments, CRE on-chain automation, Chainlink Price Feeds, and AI-powered chat." +author: "Chainlink Labs" +image: "thumbnail.jpg" +githubUrl: "https://github.com/smartcontractkit/x402-cre-price-alerts" +githubRepoLinks: + - label: "TypeScript" + url: "https://github.com/smartcontractkit/x402-cre-price-alerts" +datePublished: "2026-02-13" +lastModified: "2026-02-13" +--- + +import { Aside, Accordion, ClickToZoom } from "@components" + +## LinkLab Masterclass Book + +The book is available at: https://smartcontractkit.github.io/x402-cre-price-alerts/ + +## Overview + +**x402-cre** is a demonstration project that showcases a complete crypto price alert system integrating three cutting-edge technologies: + +1. **x402 Payment Protocol** - Micropayment system for API access +2. **Chainlink [CRE](https://docs.chain.link/cre) (Chainlink Runtime Environment)** - Decentralized workflow execution for on-chain operations +3. **Gemini AI** - Natural language processing for user interaction. While we used Gemini here you can use any LLM that has an OpenAI-API compatible endpoint. + +This repository serves as a public demo to help developers understand how to build applications that combine AI-powered interfaces, payment-protected APIs, and blockchain-based automation. + +## LiveStreamed LinkLab Walkthrough + +This demo was done live on a Chainlink Linklab Session that was livestreamed. You can [watch the video and follow along here](https://www.youtube.com/live/r7VKS5L47f0). + +## What It Accomplishes + +The system allows users to create cryptocurrency price alerts through natural language conversation. Here's what happens: + +1. **User sends a message** like "Alert me when BTC is greater than 60000" +2. **AI interprets the request** and extracts alert parameters (asset, condition, target price) +3. **User pays $0.01 USDC** via x402 payment protocol to create the alert +4. **CRE workflow HTTP trigger** your x402 gateway server triggers your custom workflow using CRE's HTTP [Capability](https://docs.chain.link/cre/capabilities/http) +5. **Alert is stored on-chain** in a smart contract via Chainlink CRE's On-Chain Write [Capability](https://docs.chain.link/cre/capabilities/evm-read-write) +6. **CRE Cron Triggers monitor on-chain prices** periodically using Chainlink Price Feeds +7. **User receives push notification on phone** when the price condition is met + +This demonstrates a complete flow from user interaction → payment → blockchain storage → automated monitoring → notification delivery. + +## Minimal System Flow + + + +## Prerequisites + +Before starting, ensure you have the following: + +### Required Software + +- **Node.js** (v18 or higher) and npm +- **Bun** for the CRE post install script. [Install here](https://bun.com/docs/installation). +- **Chainlink CRE CLI** installed and configured. [Install here](https://docs.chain.link/cre/getting-started/cli-installation). +- **Git** for cloning the repository + +### Required Accounts & Keys + +- **Gemini API Key**: Get from [Google AI Studio](https://aistudio.google.com/app/apikey) +- **Pushover Account**: + - Sign up at [pushover.net](https://pushover.net) + - Install Pushover app on your mobile device + - [Register](https://pushover.net/apps/build) your pushover app to get the API token and get your User Key from the Pushover [dashboard](https://pushover.net/) +- **Wallet with ETH and USDC on Base Sepolia**: + - Private key for the agent wallet (used for x402 payments) + - add Base Sepolia to your wallet [(go here)](https://chainlist.org/?testnets=true&search=base+sepolia) + - Get ETH on Base Sepolia testnet from [this faucet](https://portal.cdp.coinbase.com/products/faucet) for contract deployment. + - Get 1 USDC token on Base Sepolia testnet from [this faucet](https://faucet.circle.com/) for x402 payments (x402 facilitator covers gas fees) + +## Setup + + + +Deploy `contracts/RuleRegistry.sol` to Base Sepolia. The constructor requires two parameters: + +1. **USDC token address**: `0x036CbD53842c5426634e7929541eC2318f3dCF7e` (Base Sepolia USDC) +2. **Chainlink Forwarder address**: `0x82300bd7c3958625581cc2f77bc6464dcecdf3e5` ([Base Sepolia CRE Simulation Forwarder](https://docs.chain.link/cre/guides/workflow/using-evm-client/supported-networks-ts#understanding-forwarder-addresses)) + + + +You can use this Remix IDE link for this. + + + + + + + +```bash +git clone https://github.com/smartcontractkit/x402-cre-price-alerts.git +cd x402-cre-alerts +``` + +This repository uses npm workspaces. Install all dependencies with a single command: + +```bash +npm install +``` + +This will install dependencies for both the `server` and `cre/alerts` workspaces. The `cre/alerts` post install script will automatically run `bunx cre-setup`. + + + + + +Create a `.env` file in the **project root** (workspace root): + +```bash +cp .env.example .env +``` + + + +**Environment Variables Explained:** + +- `PORT`: Server port (default: 3000) +- `X402_RECEIVER_ADDRESS`: Address that receives x402 payments (Can be an EOA or Deployed RuleRegistry contract `/contracts`) +- `X402_FACILITATOR_URL`: x402 facilitator endpoint (default: `https://x402.org/facilitator`) +- `GEMINI_API_KEY`: Your Gemini API key for natural language processing +- `AGENT_WALLET_PRIVATE_KEY`: Private key of wallet used to make x402 payments (must have USDC on Base Sepolia). You can use the same key in step 4 as your CRE PK. + + + + + +Add CRE-specific environment variables to the **root `.env` file** (same file as Step 3): + +```bash +# Add these to your root .env file +# CRE_ETH_PRIVATE_KEY is used during local simulation when using the EVM Write capability. +# Transactions written will be signed by your PK. In production, a dedicated CRE DON will be the signer. +CRE_ETH_PRIVATE_KEY=your_eth_private_key +CRE_TARGET=staging-settings +PUSHOVER_USER_KEY_VAR=your_pushover_user_key +PUSHOVER_API_KEY_VAR=your_pushover_api_key +``` + + + + + +Edit `cre/alerts/config.staging.json` for staging/testing, or `cre/alerts/config.production.json` for production. + +Update the config with your `ruleRegistryAddress` obtained in Step 1. If you were unable to deploy, you may use `0x9B9fC1EeF6BFC76CD07501Ae81b66f24fAB322B1` (note: this demo contract may be populated with multiple alerts from other developers). + +```json +{ + "schedule": "0 0 * * * *", + "ruleTTL": 1800, + "publicKey": "", + "evms": [ + { + "ruleRegistryAddress": "your_deployed_rule_registry", + "chainSelectorName": "ethereum-testnet-sepolia-base-1", + "gasLimit": "1000000", + "dataFeeds": { + "BTC": "0x0FB99723Aee6f420beAD13e6bBB79b7E6F034298", + "ETH": "0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1", + "LINK": "0xb113F5A928BCfF189C998ab20d753a47F9dE5A61" + } + } + ] +} +``` + +**Configuration Fields:** + +- `schedule`: Cron expression for price checks (default: hourly - `"0 0 * * * *"`) +- `ruleTTL`: Time to live of a created rule (30 minutes by default. Older rules will not receive alerts.) +- `publicKey`: Public key used to verify incoming HTTP Trigger requests. This field is empty for this demo. However, it is required when the full HTTP Trigger is implemented for production. [See Line 64 of `server/src/server.ts`](https://github.com/smartcontractkit/x402-cre-price-alerts/blob/main/server/src/server.ts) +- `ruleRegistryAddress`: Address of your deployed RuleRegistry contract +- `chainSelectorName`: Chain selector for Base Sepolia (`"ethereum-testnet-sepolia-base-1"`) [See the chain selector reference](https://docs.chain.link/cre/reference/sdk/evm-client-ts#chain-selector-reference) +- `gasLimit`: Gas limit for on-chain writes +- `dataFeeds`: Chainlink price feed addresses for BTC, ETH, LINK on Base Sepolia. You can find Base Sepolia Price Feed addresses [here](https://docs.chain.link/data-feeds/price-feeds/addresses?page=1&testnetPage=1&network=base&networkType=testnet&testnetSearch=). + +**Environment Variables Explained:** + +- `CRE_ETH_PRIVATE_KEY`: ETH private key used for local simulation of EVM Write capability +- `CRE_TARGET`: Target profile for CLI commands +- `PUSHOVER_USER_KEY_VAR`: Your Pushover user key +- `PUSHOVER_API_KEY_VAR`: Your Pushover API key + + + +## Execution + + + +From the repository root, run the server: + +```bash +npm run dev:server +``` + +The server will start on `http://localhost:3000` (or your configured PORT). + +You should see: + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Unified API Server + Port: 3000 | Payment: $0.01 USDC +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Server ready + http://localhost:3000 + POST /chat (natural language, no payment) + POST /alerts (requires x402 payment) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +Interactive Chat Enabled +Type your message and press Enter (type 'exit' or 'quit' to leave) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + +This command runs the server with an interactive chat. + + + + + +You can interact with the chat interface in two ways: + +#### Option A: Interactive Chat (Recommended) + +Send a message to create your alert: + +``` +> Create an alert when BTC is greater than 60000 +``` + + + +Type `exit` or `quit` to disable chat (server continues running). + +#### Option B: Direct API Call + +Alternatively, send a POST request to the `/chat` endpoint: + +```bash +curl -X POST http://localhost:3000/chat \ + -H "Content-Type: application/json" \ + -d '{"message":"Create an alert when BTC is greater than 60000"}' +``` + +**What happens:** + +1. Gemini AI interprets your message +2. Extracts alert parameters (asset, condition, target price) +3. Creates a paid alert via `/alerts` endpoint with x402 payment +4. Returns alert details and payment transaction hash + +**Supported Assets:** BTC, ETH, LINK only + + + + + +From the server console output, copy the CRE payload JSON. + +Example output: + +```json +CRE Workflow Payload (copy for HTTP trigger): + +{"id":"42d2ea846d5b5e0ba439b68f8835188e023b74454c504df80ae0a0eb329eccd6","asset":"ETH","condition":"gt","targetPriceUsd":1000,"createdAt":1765324585} +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + + + + + +Open a new terminal window and simulate the CRE HTTP Trigger to write the alert on-chain: + +```bash +cd cre +cre workflow simulate alerts --env ../.env --broadcast +``` + +When prompted: + +1. Select **HTTP trigger** (option 2) +2. Paste the JSON payload from Step 3 +3. The workflow will write the alert to the RuleRegistry contract on-chain + +Example output: + +``` +2025-12-10T17:21:20Z [SIMULATION] Simulator Initialized + +2025-12-10T17:21:20Z [SIMULATION] Running trigger trigger=http-trigger@1.0.0-alpha +2025-12-10T17:21:21Z [USER LOG] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +2025-12-10T17:21:21Z [USER LOG] CRE Workflow: HTTP Trigger +2025-12-10T17:21:21Z [USER LOG] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +2025-12-10T17:21:21Z [USER LOG] [Step 1] Received alert data: {"asset":"BTC","condition":"gt","createdAt":1765416045,"id":"1b381294cc2a9771743d80a3d11380cf4e377b64802a1c728776d2f6defed3cc","targetPriceUsd":10} +2025-12-10T17:21:21Z [USER LOG] [Step 2] Encoding alert data for on-chain write... +2025-12-10T17:21:21Z [USER LOG] [Step 3] Generating CRE report... +2025-12-10T17:21:21Z [USER LOG] [Step 4] Writing to RuleRegistry contract: 0x9B9fC1EeF6BFC76CD07501Ae81b66f24fAB322B1 +2025-12-10T17:21:22Z [USER LOG] [Step 5] [SUCCESS] Transaction successful: 0x66b8b811d6902bfcfc5e5b4890602ec2620084f8dcc2a02e49a2dddc8d9f1a8a +2025-12-10T17:21:22Z [USER LOG] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Workflow Simulation Result: + "0x66b8b811d6902bfcfc5e5b4890602ec2620084f8dcc2a02e49a2dddc8d9f1a8a" + +2025-12-10T17:21:22Z [SIMULATION] Execution finished signal received +2025-12-10T17:21:22Z [SIMULATION] Skipping WorkflowEngineV2 +``` + + + + + +Execute the CRE Cron Trigger to check prices and send notifications: + +```bash +cre workflow simulate alerts --env ../.env +``` + +When prompted: + +1. Select **Cron trigger** (option 1) +2. The workflow will: + - Fetch current prices for BTC, ETH, LINK + - Check all rules stored on-chain + - Send Pushover notifications when conditions are met + +Example output: + +``` +2025-12-10T17:22:53Z [SIMULATION] Simulator Initialized + +2025-12-10T17:22:53Z [SIMULATION] Running trigger trigger=cron-trigger@1.0.0 +2025-12-10T17:22:53Z [USER LOG] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +2025-12-10T17:22:53Z [USER LOG] CRE Workflow: Cron Trigger +2025-12-10T17:22:53Z [USER LOG] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +2025-12-10T17:22:53Z [USER LOG] [Step 1] Fetching price data from Chainlink feeds... +2025-12-10T17:22:53Z [USER LOG] • BTC: $90855.76 +2025-12-10T17:22:53Z [USER LOG] • ETH: $3253.52 +2025-12-10T17:22:53Z [USER LOG] • LINK: $13.76 +2025-12-10T17:22:53Z [USER LOG] [Step 2] Found 2 rules on-chain +2025-12-10T17:22:53Z [USER LOG] [Step 3] Checking 2 rules... +2025-12-10T17:22:53Z [USER LOG] [Rule 1] [SUCCESS] Condition met: BTC $90855 gt $5 +2025-12-10T17:22:53Z [USER LOG] -> Pushover notification sent (Status: 200) +2025-12-10T17:22:53Z [USER LOG] [Rule 2] [SUCCESS] Condition met: BTC $90855 gt $10 +2025-12-10T17:22:54Z [USER LOG] -> Pushover notification sent (Status: 200) +2025-12-10T17:22:54Z [USER LOG] [Step 4] [SUCCESS] Complete: 2 notification(s) sent +2025-12-10T17:22:54Z [USER LOG] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Workflow Simulation Result: + "Processed 2 rules, sent 2 notifications" + +2025-12-10T17:22:54Z [SIMULATION] Execution finished signal received +2025-12-10T17:22:54Z [SIMULATION] Skipping WorkflowEngineV2 +``` + + + + + + + + + + + +**View balance of x402 Receiver:** If you set your x402 Receiver in the root `.env` file (`X402_RECEIVER_ADDRESS`) to your RuleRegistry contract, call the `getUSDCBalance()` to see the USDC received from x402 payments. + +**Withdraw USDC tokens from RuleRegistry:** If you set your x402 Receiver in the root `.env` file (`X402_RECEIVER_ADDRESS`) to your RuleRegistry contract, call the `withdrawUSDC(address, amount)` to withdraw USDC received from x402 payments. Reminder, USDC uses `6` decimal places! + + + +## Directory Structure + +### `server/` + +**Purpose:** Unified API server combining natural language interface and payment-protected endpoints. Endpoints combined into a single server for demo simplicity. + +**Key Components:** + +- **`src/server.ts`**: Main Express.js server with two endpoints: + - `POST /chat`: Natural language interface (no payment required) + - Uses Gemini AI to interpret user messages + - Extracts alert parameters via function calling + - Validates supported assets (BTC, ETH, LINK only) + - Internally calls `/alerts` endpoint with x402 payment + - `POST /alerts`: Direct alert creation (requires x402 payment) + - Protected by x402 payment middleware ($0.01 USDC) + - Creates deterministic alert ID (SHA256 hash) + - Outputs CRE workflow payload for on-chain storage + +- **`src/x402Client.ts`**: x402 payment client + - Wraps HTTP requests with automatic payment handling + - Uses `x402-fetch` library to handle payment challenges + - Automatically retries requests with payment authorization + +- **`src/chat.ts`**: Interactive terminal chat interface + - Provides command-line interface for chatting with the server + - Displays alert details and CRE workflow payloads + - Allows users to create alerts without using curl commands + +**Technologies:** + +- Express.js for REST API +- x402-express middleware for payment protection +- Gemini AI (via OpenAI SDK compatibility) for NLP + +### `cre/` + +**Purpose:** Chainlink CRE workflow for on-chain operations and price monitoring + +**Key Components:** + +- **`alerts/main.ts`**: Workflow entry point that initializes HTTP and Cron triggers +- **`alerts/httpCallback.ts`**: HTTP trigger handler + - Receives alert data from server + - Encodes alert data for CRE report format + - Writes alert to RuleRegistry contract on-chain +- **`alerts/cronCallback.ts`**: Cron trigger handler + - Runs on configured schedule (default: hourly) + - Fetches current prices from Chainlink price feeds (BTC, ETH, LINK) + - Reads all rules from RuleRegistry contract + - Checks price conditions against target prices + - Sends Pushover notifications when conditions are met +- **`alerts/config.staging.json`**: Workflow configuration for staging environment + - Cron schedule expression + - Rule Time To Live + - RuleRegistry contract address + - Chainlink price feed addresses + - Network configuration +- **`alerts/config.production.json`**: Workflow configuration for production environment + - Same structure as staging config + - Use for production deployments +- **`alerts/workflow.yaml`**: Workflow-specific settings + - Maps targets (`staging-settings`, `production-settings`) to their config files + - Defines workflow names and artifact paths for each environment +- **`alerts/types.ts`**: Shared TypeScript type definitions +- **`project.yaml`**: CRE project configuration (RPC endpoints, network settings for each target) +- **`secrets.yaml`**: Secret variable mappings for Pushover credentials + +**Technologies:** + +- Chainlink CRE SDK for workflow execution +- Viem for contract interactions +- Chainlink Price Feeds for price data +- Pushover API for mobile notifications + +### `contracts/` + +**Purpose:** Solidity smart contracts for on-chain alert storage + +**Key Components:** + +- **`RuleRegistry.sol`**: Main contract for storing price alert rules + - Stores rules in a mapping (ruleId → Rule struct) + - Implements `IReceiverTemplate` to receive CRE reports + - Provides functions to write, read, and query rules + - Includes `onlyOwner` functions for USDC withdrawal (x402 payments) + - Rule struct contains: `id`, `asset`, `condition`, `targetPriceUsd`, `createdAt` + +- **`interfaces/`**: Required interfaces for CRE integration + - `IReceiverTemplate.sol`: Interface for receiving CRE reports + - `IReceiver.sol`: Base receiver interface + - `IERC165.sol`: ERC165 interface for contract introspection + - `IERC20.sol`: ERC20 interface for USDC token interactions + +**Technologies:** + +- Solidity ^0.8.0 +- Chainlink CRE receiver interfaces +- OpenZeppelin-style interfaces + +## General Flow + +### 1. Alert Creation Flow + +``` +User → /chat endpoint → Gemini AI → Extract Parameters → /alerts endpoint → x402 Payment → Alert Created +``` + +**Detailed Steps:** + +1. User sends natural language message with interactive chat or `curl` to `POST /chat` +2. Server sends message to Gemini AI with function calling enabled +3. Gemini validates and extracts: `asset`, `condition`, `targetPriceUsd` +4. Server calls internal `/alerts` endpoint using `x402Client` +5. x402 payment handshake occurs: + - Initial request → 402 Payment Required + - Client processes challenge → Creates payment authorization + - Retry with payment → Server validates → 200 OK + settlement +6. Server creates alert with deterministic ID (SHA256 hash) +7. Server outputs CRE payload JSON to console (or calls the HTTP Trigger in production) + +### 2. On-Chain Storage Flow + +``` +Server Output → CRE HTTP Trigger → Encode Report → Write to RuleRegistry Contract +``` + +**Detailed Steps:** + +1. HTTP Trigger fires +2. CRE workflow: + - Decodes alert data + - Encodes as ABI parameters: `(bytes32, string, string, uint256, uint256)` + - Generates CRE report with signature + - Writes report to RuleRegistry contract via `onReport()` function +3. Contract decodes report and stores rule in mapping +4. Transaction hash returned + +### 3. Price Monitoring Flow + +``` +Cron Schedule → CRE Cron Trigger → Fetch Prices → Read Rules → Check Conditions → Send Notifications +``` + +**Detailed Steps:** + +1. Cron trigger fires on schedule (default: hourly) +2. CRE workflow: + - Fetches current prices from Chainlink feeds (BTC, ETH, LINK) + - Reads all rules from RuleRegistry contract + - For each rule: + - Gets current price for rule's asset + - Checks if condition is met (gt, lt, gte, lte) + - Skips rules older than 5 minutes + - If condition met: sends Pushover notification +3. User receives push notification on mobile device + +### 4. x402 Payment Flow + +``` +Client Request → 402 Challenge → Payment Authorization → Settlement → Response +``` + +**Detailed Steps:** + +1. Client makes initial request (no payment header) +2. Server responds with `402 Payment Required` (challenge) +3. Client processes challenge: + - Decodes payment requirements + - Creates payment authorization signature + - Includes authorization in `x-payment` header +4. Client retries request with payment header +5. Server validates payment: + - Verifies authorization signature + - Checks payment amount and recipient + - Processes settlement transaction +6. Server responds with `200 OK` + `x-payment-response` header (settlement details) + +## Key Technologies Integration + +### x402 Payment Protocol + +- **Purpose**: Micropayments for API access +- **Implementation**: `x402-express` middleware + `x402-fetch` client +- **Payment**: $0.01 USDC on Base Sepolia +- **Flow**: Challenge → Authorization → Settlement + +### Chainlink CRE + +- **Purpose**: Decentralized workflow execution for on-chain operations +- **Implementation**: CRE SDK with HTTP and Cron triggers +- **Capabilities**: EVM contract calls, price feed queries, HTTP requests +- **Network**: Base Sepolia testnet + +### Gemini AI + +- **Purpose**: Natural language understanding +- **Implementation**: OpenAI SDK compatibility layer +- **Model**: `gemini-2.0-flash-lite` +- **Function Calling**: Extracts structured data from user messages + +### Chainlink Price Feeds + +- **Purpose**: Reliable on-chain price data +- **Assets**: BTC, ETH, LINK +- **Network**: Base Sepolia +- **Format**: 8 decimals (price x 10^8) + +## Supported Features + +- **Assets**: BTC, ETH, LINK only +- **Conditions**: `gt` (greater than), `lt` (less than), `gte` (greater than or equal), `lte` (less than or equal) +- **Notifications**: Pushover push notifications to mobile devices +- **Payment**: $0.01 USDC per alert creation +- **Storage**: On-chain in RuleRegistry smart contract +- **Monitoring**: Automated hourly price checks diff --git a/src/layouts/CRETemplateLayout.astro b/src/layouts/CRETemplateLayout.astro new file mode 100644 index 00000000000..f3e3a719cb6 --- /dev/null +++ b/src/layouts/CRETemplateLayout.astro @@ -0,0 +1,173 @@ +--- +import type { MarkdownHeading } from "astro" +import BaseLayout from "~/layouts/BaseLayout.astro" +import CRETemplateOverview from "~/components/CRETemplate/CRETemplateOverview.astro" +import CRETemplatePanel from "~/components/CRETemplate/CRETemplatePanel.astro" +import CRETemplate from "~/components/CRETemplate/CRETemplate.astro" +import { CRETemplatesFrontmatter } from "~/content.config.ts" + +interface Props { + frontmatter: CRETemplatesFrontmatter + headings: MarkdownHeading[] + templateSlug: string +} + +const { frontmatter, headings, templateSlug } = Astro.props +--- + + +
+ + + + +
+
+ +
+ + + +
+ + + +
+
+
+ + +
diff --git a/src/pages/cre-templates/[...id].astro b/src/pages/cre-templates/[...id].astro new file mode 100644 index 00000000000..9802d503951 --- /dev/null +++ b/src/pages/cre-templates/[...id].astro @@ -0,0 +1,30 @@ +--- +import { getCollection, render } from "astro:content" +import CRETemplateLayout from "~/layouts/CRETemplateLayout.astro" + +export async function getStaticPaths() { + const creTemplatesEntries = await getCollection("cre-templates") + + return creTemplatesEntries.map((entry) => { + const routeId = entry.id.replace(/\.(md|mdx)$/, "") + + return { + params: { id: routeId }, + props: { entry, templateSlug: routeId }, + } + }) +} + +interface Props { + entry: Awaited>>[number] + templateSlug: string +} + +const { entry, templateSlug } = Astro.props + +const { Content, headings } = await render(entry) +--- + + + + diff --git a/src/pages/cre-templates/index.astro b/src/pages/cre-templates/index.astro new file mode 100644 index 00000000000..d05aea04b88 --- /dev/null +++ b/src/pages/cre-templates/index.astro @@ -0,0 +1,670 @@ +--- +import { getCollection } from "astro:content" +import BaseLayout from "~/layouts/BaseLayout.astro" +import TemplateCard from "~/components/CRETemplate/TemplateCard.astro" + +const templates = await getCollection("cre-templates") +const featuredTemplate = templates.find((t) => t.data.featured) + +const pageTitle = "CRE Templates Hub | Chainlink Documentation" +const pageDescription = + "Explore workflow templates for the Chainlink Runtime Environment. Clone and customize these templates to build your own CRE workflows." +--- + + +
+ +
+
+
+

CRE Templates Hub

+

+ Explore workflow templates for the Chainlink Runtime Environment.
Clone and customize these templates to + build your own CRE workflows. +

+ +
+
+
+ + + { + featuredTemplate && ( + + ) + } + + +
+
+
+

Templates

+
+ + + +
+
+ + +
+ + + +
+ + { + templates.length > 0 && ( +
+ {templates.map((template) => ( + link.label)} + author={template.data.author} + /> + ))} +
+ ) + } + + { + templates.length === 0 && ( +
+

No templates available yet. Check back soon!

+
+ ) + } +
+
+
+
+ + + +