diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..62f2a44 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,29 @@ +## What does this PR do? + + + +## Type of change + +- [ ] Bug fix +- [ ] New feature (e.g. a new agent tool or UI) +- [ ] Refactor / cleanup +- [ ] Docs +- [ ] Other: + +## How was it tested? + + + +- [ ] `pnpm lint`, `pnpm typecheck`, `pnpm test` and `pnpm build` pass locally +- [ ] Tried it in the browser (`pnpm dev`) on Ethereum Sepolia +- [ ] Added or updated tests for new logic in `src/lib/` + +## Screenshots + + + +## Safety checklist (if this touches transactions or tools) + +- [ ] No new tool can sign or broadcast transactions +- [ ] The sender still comes from the connected wallet, not from LLM input +- [ ] No API keys or RPC URLs are exposed to the browser or in error messages diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..99011b2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,44 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + check: + name: Lint, typecheck, test & build + runs-on: ubuntu-latest + timeout-minutes: 15 + env: + NEXT_TELEMETRY_DISABLED: "1" + steps: + - uses: actions/checkout@v4 + + # Uses the pnpm version pinned in package.json ("packageManager"). + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install + run: pnpm install --frozen-lockfile + + - name: Lint + run: pnpm lint + + - name: Typecheck + run: pnpm typecheck + + - name: Test + run: pnpm test + + # No API keys needed: the build and tests never call an LLM or RPC. + - name: Build + run: pnpm build diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..c25ee84 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,88 @@ +# Contributing to Chainly + +Thanks for helping build Chainly! This guide covers everything you need to go from zero to a merged pull request. + +## Setup + +You need **Node.js 22+** and **pnpm 10** (`corepack enable` installs the right version automatically). + +```bash +git clone https://github.com/CSEC-Blockchain/Chainly.git +cd Chainly +pnpm install +cp .env.example .env.local # then add ONE LLM key +pnpm dev # http://localhost:3000 +``` + +The app works without RPC or explorer keys (it uses public Sepolia endpoints), but chat needs an LLM key. For a free option, see the Groq / OpenAI-compatible setup in the [README](README.md#quick-start). Get Sepolia test ETH from the [faucet](https://cloud.google.com/application/web3/faucet/ethereum/sepolia) and connect MetaMask on **Ethereum Sepolia**. + +> Never commit `.env.local`, API keys, private keys or seed phrases. `.env*` is git-ignored except for `.env.example`. + +## Workflow + +1. **Pick or open an issue** so others know what you're working on. +2. **Create a branch** from `main`: + ```bash + git checkout main && git pull + git checkout -b feat/token-transfers # or fix/…, docs/…, refactor/… + ``` +3. **Make your change.** Keep PRs small and focused, since one feature or fix per PR is easier to review. +4. **Run the checks** before pushing (CI runs the same ones): + ```bash + pnpm lint && pnpm typecheck && pnpm test && pnpm build + ``` +5. **Open a pull request** against `main` and fill in the template. CI must pass and one teammate must approve before merging. +6. **Keep your branch up to date** by merging `main` into it if there are conflicts. + +## Commit messages + +Write short, imperative messages that say what the commit does: + +``` +Add getTokenAllowance tool +Fix balance card overflow on mobile +Docs: explain Etherscan API key setup +``` + +## Where things live + +| Folder | What goes there | +|---|---| +| `src/lib/blockchain/` | Framework-free onchain logic (viem reads, explorer client, analytics, transfer preparation). **Add tests for anything here.** | +| `src/lib/agent/` | AI tool definitions (`tools.ts`), system instructions (`prompt.ts`), LLM provider config (`model.ts`) | +| `src/app/api/chat/route.ts` | The agent loop endpoint | +| `src/components/cards/` | Result cards rendered for each tool | +| `src/components/chat/` | Chat workspace (sidebar, messages, composer, tool steps) | +| `src/components/landing/` | Landing page | +| `src/components/ui/` | Shared shadcn/ui-style primitives | +| `tests/` | Vitest unit tests | + +## Adding a new agent tool + +1. Write the logic as a plain function in `src/lib/blockchain/` that takes the viem client as a parameter and returns plain JSON (convert `bigint`s to strings). +2. Validate inputs with the helpers in `validation.ts` and throw `BlockchainError` with a user-friendly message. +3. Register it in `src/lib/agent/tools.ts` with a clear `description` and a zod `inputSchema`. +4. Add a label in `src/components/chat/tool-invocation.tsx` and, if useful, a result card in `src/components/cards/`. +5. Add tests in `tests/` using the `fakeClient` helper (no network needed). + +## Safety rules (non-negotiable) + +Chainly handles real wallets, so every PR must keep these guarantees: + +- **No tool may sign or broadcast a transaction.** Tools can only read data or *prepare* a preview. +- **The sender always comes from the connected wallet**, never from LLM-provided arguments. +- **Every transaction needs explicit user approval** in the user's own wallet. +- **Secrets stay server-side.** Only `NEXT_PUBLIC_*` variables may reach the browser, and errors must not leak RPC URLs or keys. + +If your change touches `transfer.ts`, `signing-guard.ts`, `tx-records.ts` or `tools.ts`, mention it in the PR and add tests. + +## Code style + +- TypeScript strict mode; avoid `any`. +- Match the surrounding code's naming, comments and structure. +- Use the design tokens in `src/app/globals.css` (`bg-surface`, `text-muted-foreground`, `border-border`, `text-accent`…) instead of hard-coded colors, and check both dark and light themes. +- Make UI work on mobile (≈390px wide) and keyboard-accessible. + +## Questions? + +Open a [discussion or issue](https://github.com/CSEC-Blockchain/Chainly/issues) or ask in the team channel. diff --git a/README.md b/README.md index 3377ce5..50d40ee 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Chainly is an AI agent for **Ethereum Sepolia** (chain ID `11155111`). You ask questions in plain English. It reads **live onchain data**, analyzes wallet activity, and **prepares** transactions that you approve in your own wallet. It never signs anything for you. -> Built for the **CSEC-ASTU Blockchain Team, Blockchain × AI session**. +> Built by the **CSEC-ASTU Blockchain Team** for the Blockchain × AI session. Contributions welcome. See [CONTRIBUTING.md](CONTRIBUTING.md). | Route | What it is | |---|---| diff --git a/src/components/landing/sections.tsx b/src/components/landing/sections.tsx index c0a9ba6..2eafb4c 100644 --- a/src/components/landing/sections.tsx +++ b/src/components/landing/sections.tsx @@ -26,7 +26,7 @@ import { CHAIN_ID, EXPLORER_URL, FAUCET_URL } from "@/lib/blockchain/chain"; import { cn } from "@/lib/utils"; import { ProductPreview } from "./product-preview"; -const REPO_URL = "https://github.com/lijnati/Chainly"; +const REPO_URL = "https://github.com/CSEC-Blockchain/Chainly"; /* ───────────────────────── Building blocks ───────────────────────── */