Backend for Gallery — a Go service that powers user galleries of on-chain assets across Ethereum, Tezos, Base, Optimism, Polygon, Arbitrum, and POAP.
This repository contains the backend services only. It is published as reference for developers interested in multi-chain NFT indexing, social graph APIs, and GraphQL server patterns in Go.
The codebase is a Go monorepo broken into several services that share the same service/, db/, and graphql/ packages:
| Service | Path | Purpose |
|---|---|---|
| Backend API | cmd/server, server/ |
Main GraphQL API server |
| Token processing | cmd/tokenprocessing, tokenprocessing/ |
Fetches metadata and media for NFTs |
| Feed | cmd/feed, feed/ |
Activity feed generation |
| Emails | cmd/emails, emails/ |
Transactional and digest email delivery |
| Push notifications | cmd/pushnotifications, pushnotifications/ |
Mobile push delivery via Expo |
| Rasterizer | rasterizer/ |
Screenshots / thumbnails for non-image NFTs |
Shared packages live under service/ (business logic), db/ (SQL + migrations + sqlc-generated queries), graphql/ (gqlgen schema + resolvers), and platform/ (chain abstractions).
The services were originally designed to run on Google Cloud Platform. If you're running them yourself, you'll need equivalents for:
- PostgreSQL — primary data store (required)
- Google Cloud Tasks — async work queues. Locally emulated via
cloud-tasks-emulatorindocker-compose.yml - Google Cloud Pub/Sub — notification fan-out. Locally emulated via the
google-cloud-cliemulator - Google Cloud Storage — token media and configuration buckets
- Alchemy — EVM RPC and NFT indexing APIs
- Infura IPFS — IPFS gateway
- SendGrid — transactional email
- Sentry — error tracking (optional)
- Expo — push notifications (optional)
You can swap GCP services for alternatives (RabbitMQ for Cloud Tasks, NATS for Pub/Sub, S3 for GCS, etc.) by modifying the relevant clients under service/.
- Go 1.19+
- Docker and Docker Compose
- golang-migrate (
brew install golang-migrate)
git clone <your-fork-url>
cd go-gallery
go mod download
# Start postgres + emulators
make docker-start
# Run migrations
make migrate-coredb
# Build and run the main backend
go build -o ./bin/main ./cmd/server/main.go
./bin/mainHealthcheck:
curl localhost:4000/aliveThe services read configuration through viper and environment variables. Sensible defaults for local development are defined in:
server/server.go→SetDefaults()tokenprocessing/tokenprocessing.go→setDefaults()emails/emails.go→setDefaults()feed/feed.go→setDefaults()pushnotifications/pushnotifications.go→setDefaults()
At minimum you'll want to set:
| Variable | Purpose |
|---|---|
POSTGRES_HOST, POSTGRES_PORT, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB |
Database connection |
RPC_URL |
Ethereum RPC endpoint (Alchemy, Infura, or self-hosted) |
ALCHEMY_API_URL, ALCHEMY_OPTIMISM_API_URL, ALCHEMY_POLYGON_API_URL, etc. |
Per-chain Alchemy endpoints |
TEZOS_API_URL |
Defaults to the public TzKT API |
IPFS_URL, IPFS_API_URL |
IPFS gateway + API |
SENDGRID_API_KEY |
Transactional email |
GOOGLE_CLOUD_PROJECT |
GCP project ID (if using GCP) |
AUTH_JWT_SECRET, REFRESH_JWT_SECRET |
JWT signing secrets (generate your own) |
JWT secrets default to literal test strings — always override these in any environment that handles real users.
Secrets in the original repo were managed with SOPS against GCP KMS. Those encrypted files are not included in this open-source tree; you'll need to supply your own configuration via env vars, .env files (gitignored), or your preferred secret store.
# Create a new migration for the backend db
migrate create -ext sql -dir db/migrations/core -seq <name of migration>
# Run all migrations for the local backend db
make migrate-coredb# All tests
go test ./...
# A single subdirectory
go test ./server/...
# A specific test
go test -run=TestMain/"test GraphQL"/"should get trending" ./graphql
# Skip long-running tests
go test -short ./...Many tests spin up real Postgres containers via ory/dockertest, so Docker must be running locally.
The Makefile contains the deploy recipes that originally targeted Gallery's production Google Cloud Run + Cloud SQL infrastructure. They rely on SOPS-encrypted env files that are not part of this repository. Treat them as reference material; you will need to adapt them (or replace them with your own CI/CD pipeline) to deploy your own fork.
MIT — see LICENSE.
Issues and PRs welcome. Please run go build ./..., go test ./..., and yarn prettier --check graphql/schema/schema.graphql before opening a PR.