Shared Go library for the Zif platform. Provides database models, GraphQL client, and exchange integrations.
- Go 1.21+
- Git
# Clone the repository
git clone git@github.com:zif-terminal/lib.git
cd lib
# Setup git hooks (enforces conventional commits)
./.githooks/setup.sh
# Run tests
go test ./...Run this once after cloning:
./.githooks/setup.shThis installs three hooks:
- pre-commit - Auto-updates coverage badge when baseline changes
- commit-msg - Validates conventional commit format
- pre-push - Runs tests and blocks direct pushes to
main
Create a branch and make your changes:
git checkout -b feat/my-feature
# ... make changes ...
go test ./...git commit -m "feat: add new exchange client"If your commit message doesn't follow the format, the hook will reject it:
❌ Invalid commit message format!
Expected: <type>[scope][!]: <description>
Types: feat, fix, docs, style, refactor, perf, test, chore, ci, build
git push origin feat/my-feature
# Create PR on GitHubThe CI will validate your commits and run tests.
When your PR is merged to main, the CI automatically:
- Determines version bump from commit messages
- Creates and pushes a new version tag
This repo uses Conventional Commits for automatic semantic versioning.
<type>[optional scope][!]: <description>
[optional body]
[optional footer(s)]
| Type | Description | Version Bump |
|---|---|---|
feat |
New feature | MINOR (1.0.0 → 1.1.0) |
fix |
Bug fix | PATCH (1.0.0 → 1.0.1) |
feat! or fix! |
Breaking change | MAJOR (1.0.0 → 2.0.0) |
docs |
Documentation | PATCH |
style |
Code style (formatting) | PATCH |
refactor |
Code refactoring | PATCH |
perf |
Performance improvement | PATCH |
test |
Adding/updating tests | PATCH |
chore |
Maintenance | PATCH |
ci |
CI/CD changes | PATCH |
build |
Build system changes | PATCH |
# New feature (MINOR bump: v1.5.0 → v1.6.0)
git commit -m "feat: add drift exchange client"
# Bug fix (PATCH bump: v1.5.0 → v1.5.1)
git commit -m "fix: correct funding payment calculation"
# Feature with scope
git commit -m "feat(db): add batch insert for trades"
# Breaking change (MAJOR bump: v1.5.0 → v2.0.0)
git commit -m "feat!: redesign exchange client interface"
# Documentation (PATCH bump)
git commit -m "docs: update API examples in README"┌───────────────────────────────────────────────────────────┐
│ Pull Request │
├───────────────────────────────────────────────────────────┤
│ ✓ test - Runs tests + checks coverage │
│ ✓ validate-commits - Checks conventional commit format │
└───────────────────────────────────────────────────────────┘
│
▼ merge
┌───────────────────────────────────────────────────────────┐
│ Main Branch │
├───────────────────────────────────────────────────────────┤
│ ✓ test - Runs tests + checks coverage │
│ ✓ release - Creates version tag from commits │
└───────────────────────────────────────────────────────────┘
Go structs matching the database schema:
Exchange- Exchange entityExchangeAccount- User's exchange accountTrade- Individual trade recordPosition- Aggregated positionFundingPayment- Funding payment record
GraphQL client for Hasura with CRUD operations:
import "github.com/zif-terminal/lib/db"
client := db.NewClient(db.ClientConfig{
URL: "http://localhost:8080/v1/graphql",
AdminSecret: "your-admin-secret",
})
// Create an account
account, err := client.CreateAccount(ctx, &db.ExchangeAccountInput{
ExchangeID: exchangeID,
AccountIdentifier: "0x123...",
AccountType: "main",
})Unified interface for fetching data from exchanges:
import (
"github.com/zif-terminal/lib/exchange"
"github.com/zif-terminal/lib/exchange/iface"
)
// Get a client for an exchange
client, err := exchange.GetClient("hyperliquid")
// Fetch trades
trades, err := client.FetchTrades(ctx, account, &iface.FetchOptions{
Since: time.Now().Add(-24 * time.Hour),
})Supported Exchanges:
- Hyperliquid
- Drift
- Lighter
Simple structured logger for consistent output across services.
lib/
├── .github/
│ └── workflows/
│ └── ci.yml # CI pipeline + auto-release
├── .githooks/
│ ├── commit-msg # Conventional commit validation
│ ├── pre-push # Runs tests, blocks push to main
│ └── setup.sh # Hook installation script
├── db/ # Database client
│ ├── client.go
│ ├── accounts.go
│ ├── exchanges.go
│ ├── trades.go
│ ├── funding_payment.go
│ └── *_test.go
├── exchange/ # Exchange integrations
│ ├── client.go # Factory for exchange clients
│ ├── iface/ # Interfaces
│ ├── hyperliquid/
│ ├── drift/
│ └── lighter/
├── models/ # Data structures
│ ├── account.go
│ ├── exchange.go
│ ├── trade.go
│ ├── position.go
│ └── funding_payment.go
├── logger/ # Structured logging
├── .coverage-baseline # Coverage ratchet baseline
├── go.mod
└── README.md
# All tests
go test ./...
# Verbose output
go test -v ./...
# Specific package
go test -v ./db/...
go test -v ./exchange/hyperliquid/...
# With coverage
go test -cover ./...
# Detailed coverage report
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out # Summary
go tool cover -html=coverage.out # HTML report in browserThis repo uses coverage ratcheting - coverage can only go up, never down.
- Baseline is stored in
.coverage-baseline - PRs that reduce coverage are blocked
- When you improve coverage, update the baseline in your PR
PR reduces coverage: 60.5% → 58% ❌ Blocked
PR maintains coverage: 60.5% → 60.5% ✓ Allowed
PR improves coverage: 60.5% → 65% ✓ Update baseline in PR
Check and update coverage:
# Check current coverage
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out | grep total
# If coverage improved, update the baseline
echo "70.0" > .coverage-baselineThe coverage badge in this README is automatically updated by a pre-commit hook when you commit changes to .coverage-baseline.
Add to your Go module:
go get github.com/zif-terminal/lib@latestOr pin to a specific version:
go get github.com/zif-terminal/lib@v1.5.0github.com/machinebox/graphql- GraphQL clientgithub.com/google/uuid- UUID generationgithub.com/stretchr/testify- Test assertions