Compare commits

..

1 Commits

Author SHA1 Message Date
b9af9f3b8d Add CI for publishing docker image (#3)
All checks were successful
Publish zenith-faucet docker image on release / Run docker build and publish (release) Successful in 1m4s
Part of https://www.notion.so/Implement-stacks-1b5a6b22d472806a82f5dafed6955138

Reviewed-on: #3
Co-authored-by: Nabarun <nabarun@deepstacksoft.com>
Co-committed-by: Nabarun <nabarun@deepstacksoft.com>
2025-07-14 14:51:58 +00:00
8 changed files with 140 additions and 18 deletions

View File

@ -1,3 +0,0 @@
node_modules
dist
db

29
.github/workflows/docker-image.yml vendored Normal file
View File

@ -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}}

30
.github/workflows/lint-and-build.yml vendored Normal file
View File

@ -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

1
.npmrc
View File

@ -1 +0,0 @@
@laconic-network:registry=https://git.vdb.to/api/packages/LaconicNetwork/npm/

78
CLAUDE.md Normal file
View File

@ -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

View File

@ -1,6 +1,6 @@
{
"name": "zenith-faucet",
"version": "0.1.0",
"version": "0.1.2",
"main": "dist/index.js",
"license": "UNLICENSED",
"private": true,
@ -23,7 +23,6 @@
"@cosmjs/encoding": "^0.33.1",
"@cosmjs/proto-signing": "^0.33.1",
"@cosmjs/stargate": "^0.33.1",
"@laconic-network/cosmjs-util": "^0.1.0",
"@keyv/sqlite": "^3.6.7",
"cors": "^2.8.5",
"express": "^4.19.2",

View File

@ -6,13 +6,11 @@ import toml from 'toml';
import cors from 'cors';
import { DirectSecp256k1Wallet } from '@cosmjs/proto-signing';
import { SigningStargateClient } from '@cosmjs/stargate';
import { GasPrice, SigningStargateClient } from '@cosmjs/stargate';
import { Comet38Client } from '@cosmjs/tendermint-rpc';
import { fromBech32 } from '@cosmjs/encoding';
import KeyvSqlite from '@keyv/sqlite';
import { parseCustomGasPrice } from '@laconic-network/cosmjs-util';
const CONFIG_PATH = 'environments/local.toml';
const FAUCET_DATA_FILE = 'faucet_data.sqlite';
const FAUCET_DATA_TTL = 86400000; // 24 hrs
@ -125,7 +123,7 @@ async function sendTokens (config: Config, recipientAddress: string, amount: str
const client = await SigningStargateClient.createWithSigner(
cometClient,
wallet,
{ gasPrice: parseCustomGasPrice(`${config.upstream.gasPrice}${config.upstream.denom}`) }
{ gasPrice: GasPrice.fromString(`${config.upstream.gasPrice}${config.upstream.denom}`) }
);
const result = await client.sendTokens(

View File

@ -201,14 +201,6 @@
dependencies:
sqlite3 "^5.1.7"
"@laconic-network/cosmjs-util@^0.1.0":
version "0.1.0"
resolved "https://git.vdb.to/api/packages/LaconicNetwork/npm/%40laconic-network%2Fcosmjs-util/-/0.1.0/cosmjs-util-0.1.0.tgz#899af1de6101834e42c68aa684a00f51f7b913ed"
integrity sha512-18Gez/2FwDkLf/de1x6httgtwrj+9jldc7V6Or0KGGtboQgKPUC6G5RebowpeWR/d9GVORV3ha8H2PpCtH4XMQ==
dependencies:
"@cosmjs/math" "^0.33.1"
"@cosmjs/stargate" "^0.33.1"
"@noble/hashes@^1":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426"