Skip to content

5afe/safe-transaction-service-api

Repository files navigation

Safe Transaction Service API

A unified API layer for Safe blockchain data, designed to replace the fan-out pattern where Client Gateway queries 50+ Transaction Services.

Features

  • Unified API: Single endpoint for multi-chain Safe data
  • Backwards Compatible: REST API matching existing TX Service format
  • Type-Safe: tRPC + Zod for end-to-end type safety
  • Incremental Adoption: Proxy → Hybrid → Native modes
  • Production Ready: Circuit breakers, caching, structured logging

Tech Stack

Technology Purpose
Bun Fast JS runtime with native TypeScript
Hono Fast, lightweight HTTP framework
tRPC Type-safe RPC
Zod Runtime validation
Pino Structured logging
Redis Caching layer

Quick Start

Local Development

# Install dependencies
bun install

# Start Redis (optional, for caching)
docker compose -f docker-compose.dev.yml up -d

# Start development server
bun run dev

# Chain configurations are fetched from Safe Config Service automatically
# Optionally override specific chains with TX_SERVICE_URLS
TX_SERVICE_URLS='{"1":"https://custom-tx-service.example.com"}' bun run dev

Docker

# Build and run with Docker Compose
docker compose up --build

# Or build image manually
docker build -t safe-transaction-service-api .
docker run -p 3000:3000 safe-transaction-service-api

Test Endpoints

# Health check
curl http://localhost:3000/health

# Get Safe info (requires TX_SERVICE_URLS)
curl http://localhost:3000/api/v1/chains/1/safes/0x0DA0C3e52C977Ed3cBc641fF02DD271c3ED55aFe

# Get Safes by owner
curl http://localhost:3000/api/v1/chains/1/owners/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/safes

# Get balances
curl http://localhost:3000/api/v1/chains/1/safes/0x0DA0C3e52C977Ed3cBc641fF02DD271c3ED55aFe/balances

API Endpoints

REST (Backwards Compatible)

Endpoint Description
GET /health Health check
GET /ready Readiness check
GET /api/v1/chains/:chainId/safes/:address Get Safe info
GET /api/v1/chains/:chainId/owners/:address/safes Get Safes by owner
GET /api/v1/chains/:chainId/safes/:address/balances Get Safe balances
GET /api/v1/chains/:chainId/safes/:address/multisig-transactions Get transactions
GET /api/v1/chains/:chainId/transactions/:safeTxHash Get transaction by hash

tRPC

// Type-safe client
const safe = await client.safe.get({ chainId: 1, address: '0x...' })
const safes = await client.owner.getSafes({ chainId: 1, ownerAddress: '0x...' })
const balances = await client.balance.get({ chainId: 1, safeAddress: '0x...' })

Environment Variables

Variable Description Default
NODE_ENV Environment development
PORT Server port 3000
LOG_LEVEL Logging level info
REDIS_URL Redis connection URL (disabled)
SAFE_CONFIG_BASE_URI Config Service URL for chain configs https://safe-config.safe.global/
USE_TX_SERVICE_VPC_URL Use VPC URLs for transaction services false
TX_SERVICE_URLS (Optional) JSON map override for chainId to URL {}
CORS_ORIGINS Comma-separated allowed origins *
REQUEST_TIMEOUT_MS Request timeout 30000

Scripts

bun run dev          # Development server with hot reload
bun run start        # Start production server
bun run build        # Build for production

bun run test         # Run unit + integration tests
bun run test:unit    # Run unit tests only
bun run test:integration  # Run integration tests only
bun run test:e2e     # Run E2E tests (needs network)
bun run test:coverage     # Run with coverage

bun run lint         # ESLint
bun run lint:fix     # ESLint with auto-fix
bun run format       # Prettier
bun run typecheck    # TypeScript check

Project Structure

src/
├── config/           # Configuration (env, constants)
├── domains/          # Business domains
│   ├── chain/        # Chain configuration
│   ├── safe/         # Safe info
│   ├── owner/        # Owner's safes
│   ├── transaction/  # Transactions
│   └── balance/      # Token balances
├── providers/        # Data access
│   ├── config/       # Config Service client
│   ├── proxy/        # TX Service client
│   ├── cache/        # Redis client
│   └── data-provider.ts  # Abstraction layer
├── infrastructure/   # HTTP, tRPC, middlewares
│   ├── http/         # REST routes
│   ├── trpc/         # tRPC setup
│   ├── middleware/   # Hono middlewares
│   └── health/       # Health endpoints
└── shared/           # Utilities, errors, types

Documentation

Document Description
Overview Documentation structure
Phase 1 Requirements Proxy mode requirements
Phase 1 Architecture Proxy mode architecture
Phase 1 Tasks Implementation checklist
Infrastructure Requirements AWS deployment & circuit breakers
CLAUDE.md Development guidelines

Chain Configuration

The service automatically fetches chain configurations from Safe Config Service. This provides:

  • Dynamic chain support: No manual configuration needed for new chains
  • VPC URL support: Use internal network URLs for better performance (USE_TX_SERVICE_VPC_URL=true)
  • Override capability: Use TX_SERVICE_URLS to override specific chains for testing

URL Resolution Priority

  1. TX_SERVICE_URLS override (if configured)
  2. Config Service (VPC or public URL based on USE_TX_SERVICE_VPC_URL)
  3. Error if chain not found

Example Configurations

# Use Config Service for all chains (recommended)
SAFE_CONFIG_BASE_URI=https://safe-config.safe.global/

# Use VPC URLs for internal network optimization
USE_TX_SERVICE_VPC_URL=true

# Override specific chains for local testing
TX_SERVICE_URLS='{"1":"http://localhost:8000","137":"https://custom-polygon.example.com"}'

Operating Modes

Mode 1: PROXY          Mode 2: HYBRID         Mode 3: NATIVE
─────────────          ──────────────         ─────────────
Forwards to            Reads from unified     Full unified
existing TX            DB, falls back to      database
Services               TX Services

Zero migration         Gradual migration      Final state

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages