diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..4a2c829 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,29 @@ +name: Publish zenith-faucet docker image on release + +on: + release: + types: [published] + +jobs: + build: + name: Run docker build and publish + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run docker build + run: docker build -t cerc/zenith-faucet -f Dockerfile . + - name: Get the version + id: vars + run: | + echo "sha=$(echo ${GITHUB_SHA:0:7})" >> $GITHUB_OUTPUT + echo "tag=$(echo ${GITHUB_REF#refs/tags/})" >> $GITHUB_OUTPUT + - name: Tag docker image with SHA + run: docker tag cerc/zenith-faucet git.vdb.to/laconicnetwork/cerc/zenith-faucet:${{steps.vars.outputs.sha}} + - name: Tag docker image with release tag + run: docker tag git.vdb.to/laconicnetwork/cerc/zenith-faucet:${{steps.vars.outputs.sha}} git.vdb.to/laconicnetwork/cerc/zenith-faucet:${{steps.vars.outputs.tag}} + - name: Docker Login + run: echo ${{ secrets.CICD_PUBLISH_TOKEN }} | docker login https://git.vdb.to -u laconiccicd --password-stdin + - name: Docker Push SHA + run: docker push git.vdb.to/laconicnetwork/cerc/zenith-faucet:${{steps.vars.outputs.sha}} + - name: Docker Push TAGGED + run: docker push git.vdb.to/laconicnetwork/cerc/zenith-faucet:${{steps.vars.outputs.tag}} diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml new file mode 100644 index 0000000..b53aa3d --- /dev/null +++ b/.github/workflows/lint-and-build.yml @@ -0,0 +1,30 @@ +name: Lint and Build + +on: + pull_request: + branches: [ main, milestone-3 ] + +jobs: + lint-and-build: + name: Run lint and build checks + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Enable corepack and yarn + run: corepack enable + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Run ESLint + run: yarn lint + + - name: Run build + run: yarn build diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..a6686bd --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,78 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a **Cosmos SDK blockchain faucet API** that provides token distribution services for the Zenith blockchain. The application is built with TypeScript, Express.js, and uses CosmJS for blockchain interactions. + +## Key Architecture + +### Core Components +- **Single-file application**: All logic is contained in `src/index.ts` +- **Configuration-driven**: Uses TOML config file (`environments/local.toml`) for blockchain and server settings +- **Rate limiting**: SQLite-based storage with 24-hour TTL for address-based rate limiting +- **Cosmos SDK integration**: Uses CosmJS libraries for wallet management and transaction signing + +### Configuration Structure +The application reads from `environments/local.toml` with two main sections: +- `[upstream]`: Blockchain connection details (RPC endpoint, denom, address prefix, gas price, faucet private key) +- `[server]`: Server settings (port, transfer amounts, rate limits, database directory) + +### Request Flow +1. POST `/faucet` with `{"address": "zenith1..."}` +2. Address validation using bech32 format +3. Rate limit check (daily transfer limit per address) +4. Token transfer via CosmJS SigningStargateClient +5. SQLite storage update for rate limiting + +## Common Commands + +### Development +```bash +# Install dependencies +yarn + +# Build the project +yarn build + +# Lint the code +yarn lint + +# Start the faucet server +yarn start +``` + +### Docker +```bash +# Build and run via Docker +docker build -t zenith-faucet . +docker run -p 3000:3000 zenith-faucet +``` + +## Configuration Requirements + +Before running, you must set the `faucetKey` in `environments/local.toml`: +- Should be a hex-encoded private key (with or without 0x prefix) +- Must correspond to a funded account on the target blockchain +- Example: `faucetKey = "abcdef1234567890..."` + +## Dependencies + +### Production Dependencies +- **CosmJS**: Blockchain interaction (`@cosmjs/stargate`, `@cosmjs/proto-signing`, `@cosmjs/encoding`) +- **Express.js**: Web server framework +- **Keyv + SQLite**: Rate limiting storage (`keyv`, `@keyv/sqlite`) +- **TOML**: Configuration parsing + +### Development Dependencies +- **TypeScript**: Language and build system +- **ESLint**: Code linting with semistandard config + +## Development Notes + +- The application uses strict TypeScript configuration +- All blockchain operations are asynchronous and use modern async/await patterns +- Error handling includes both validation errors (400) and rate limiting (429) +- Database operations use TTL-based expiration for automatic cleanup +- Gas price configuration supports custom values per blockchain \ No newline at end of file diff --git a/package.json b/package.json index b9f783f..7e5d85c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenith-faucet", - "version": "0.1.0", + "version": "0.1.2", "main": "dist/index.js", "license": "UNLICENSED", "private": true,