diff --git a/Dockerfile.Fee.server b/Dockerfile.Fee.server new file mode 100644 index 0000000..1a2e544 --- /dev/null +++ b/Dockerfile.Fee.server @@ -0,0 +1,44 @@ +# Use the official Go image as the base image +FROM golang:1.24 as builder + +# Set the working directory +WORKDIR /app + +# Copy go.mod and go.sum to install dependencies +COPY go.mod go.sum ./ +RUN go mod download + +# Copy the source code +COPY . . + +RUN wget https://github.com/vultisig/go-wrappers/archive/refs/heads/master.tar.gz +RUN tar -xzf master.tar.gz && \ + cd go-wrappers-master && \ + mkdir -p /usr/local/lib/dkls && \ + cp --recursive includes /usr/local/lib/dkls + +ENV LD_LIBRARY_PATH=/usr/local/lib/dkls/includes/linux/:${LD_LIBRARY_PATH:-} + +# Build the application +RUN go build -o server ./cmd/fees/server + +# Use a minimal base image for the final stage +FROM ubuntu:24.04 + +RUN apt-get update && \ + apt-get install -y wget && \ + rm -rf /var/lib/apt/lists/* + +# Set the working directory +WORKDIR /app + +# Copy the built binary from the builder stage +COPY --from=builder /app/server . +COPY --from=builder /usr/local/lib/dkls /usr/local/lib/dkls +COPY fee.server.example.json config.json +COPY ./etc/vultisig/fee.yml /etc/vultisig/fee.yml + +ENV LD_LIBRARY_PATH=/usr/local/lib/dkls/includes/linux/:${LD_LIBRARY_PATH:-} + +# Run the application +CMD ["./server"] \ No newline at end of file diff --git a/Dockerfile.Fee.server.dev b/Dockerfile.Fee.server.dev new file mode 100644 index 0000000..810f7c7 --- /dev/null +++ b/Dockerfile.Fee.server.dev @@ -0,0 +1,41 @@ +# Use the official Go image as the base image +FROM golang:1.24 + +# Install air for hot reloading +RUN go install github.com/air-verse/air@latest + +# Set the working directory +WORKDIR /app + +# Copy go.mod and go.sum to install dependencies +COPY go.mod go.sum ./ +RUN go mod download + +# Download and install DKLS wrappers +RUN wget https://github.com/vultisig/go-wrappers/archive/refs/heads/master.tar.gz +RUN tar -xzf master.tar.gz && \ + cd go-wrappers-master && \ + mkdir -p /usr/local/lib/dkls && \ + cp --recursive includes /usr/local/lib/dkls + +ENV LD_LIBRARY_PATH=/usr/local/lib/dkls/includes/linux/:${LD_LIBRARY_PATH:-} + +# Create tmp directory for air +RUN mkdir -p /app/tmp + +# Create air configuration +RUN echo 'root = "."' > .air.toml && \ + echo '' >> .air.toml && \ + echo '[build]' >> .air.toml && \ + echo ' bin = "./tmp/main"' >> .air.toml && \ + echo ' cmd = "go build -o ./tmp/main ./cmd/fees/server"' >> .air.toml && \ + echo ' delay = 1000' >> .air.toml && \ + echo ' exclude_dir = ["assets", "tmp", "vendor", "testdata"]' >> .air.toml && \ + echo ' exclude_regex = ["_test.go"]' >> .air.toml + +# Copy configuration files +COPY fee.server.example.json config.json +COPY ./etc/vultisig/fee.yml /etc/vultisig/fee.yml + +# Run air for hot reloading +CMD ["air"] \ No newline at end of file diff --git a/Dockerfile.Fee.worker b/Dockerfile.Fee.worker new file mode 100644 index 0000000..fbba8ca --- /dev/null +++ b/Dockerfile.Fee.worker @@ -0,0 +1,44 @@ +# Use the official Go image as the base image +FROM golang:1.24 as builder + +# Set the working directory +WORKDIR /app + +# Copy go.mod and go.sum to install dependencies +COPY go.mod go.sum ./ +RUN go mod download + +# Copy the source code +COPY . . + +RUN wget https://github.com/vultisig/go-wrappers/archive/refs/heads/master.tar.gz +RUN tar -xzf master.tar.gz && \ + cd go-wrappers-master && \ + mkdir -p /usr/local/lib/dkls && \ + cp --recursive includes /usr/local/lib/dkls + +ENV LD_LIBRARY_PATH=/usr/local/lib/dkls/includes/linux/:${LD_LIBRARY_PATH:-} + +# Build the application +RUN go build -o worker ./cmd/fees/worker + +# Use a minimal base image for the final stage +FROM ubuntu:24.04 + +RUN apt-get update && \ + apt-get install -y wget && \ + rm -rf /var/lib/apt/lists/* + +# Set the working directory +WORKDIR /app + +# Copy the built binary from the builder stage +COPY --from=builder /app/worker . +COPY --from=builder /usr/local/lib/dkls /usr/local/lib/dkls +COPY fee.worker.example.json config.json +COPY ./etc/vultisig/fee.yml /etc/vultisig/fee.yml + +ENV LD_LIBRARY_PATH=/usr/local/lib/dkls/includes/linux/:${LD_LIBRARY_PATH:-} + +# Run the application +CMD ["./worker"] \ No newline at end of file diff --git a/Dockerfile.Fee.worker.dev b/Dockerfile.Fee.worker.dev new file mode 100644 index 0000000..e1c8294 --- /dev/null +++ b/Dockerfile.Fee.worker.dev @@ -0,0 +1,41 @@ +# Use the official Go image as the base image +FROM golang:1.24 + +# Install air for hot reloading +RUN go install github.com/air-verse/air@latest + +# Set the working directory +WORKDIR /app + +# Copy go.mod and go.sum to install dependencies +COPY go.mod go.sum ./ +RUN go mod download + +# Download and install DKLS wrappers +RUN wget https://github.com/vultisig/go-wrappers/archive/refs/heads/master.tar.gz +RUN tar -xzf master.tar.gz && \ + cd go-wrappers-master && \ + mkdir -p /usr/local/lib/dkls && \ + cp --recursive includes /usr/local/lib/dkls + +ENV LD_LIBRARY_PATH=/usr/local/lib/dkls/includes/linux/:${LD_LIBRARY_PATH:-} + +# Create tmp directory for air +RUN mkdir -p /app/tmp + +# Create air configuration +RUN echo 'root = "."' > .air.toml && \ + echo '' >> .air.toml && \ + echo '[build]' >> .air.toml && \ + echo ' bin = "./tmp/main"' >> .air.toml && \ + echo ' cmd = "go build -o ./tmp/main ./cmd/fees/worker"' >> .air.toml && \ + echo ' delay = 1000' >> .air.toml && \ + echo ' exclude_dir = ["assets", "tmp", "vendor", "testdata"]' >> .air.toml && \ + echo ' exclude_regex = ["_test.go"]' >> .air.toml + +# Copy configuration files +COPY fee.worker.example.json config.json +COPY ./etc/vultisig/fee.yml /etc/vultisig/fee.yml + +# Run air for hot reloading +CMD ["air"] \ No newline at end of file diff --git a/Makefile b/Makefile index 556ee14..d8b759c 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,28 @@ # adjust to point to your local go-wrappers repo DYLD_LIBRARY=../go-wrappers/includes/darwin/:$LD_LIBRARY_PATH +DYLD_LIBRARY_PATH=../go-wrappers/includes/darwin/:$LD_LIBRARY_PATH + + +.PHONY: up up-dev down down-dev build build-dev dump-schema up: @docker compose up -d --remove-orphans; +up-dev: + @docker compose -f docker-compose.yaml -f docker-compose.dev.yaml up -d --remove-orphans; + down: @docker compose down +down-dev: + @docker compose -f docker-compose.yaml -f docker-compose.dev.yaml down; + +build: + @docker compose build; + +build-dev: + @docker compose -f docker-compose.yaml -f docker-compose.dev.yaml build; + # Dump database schema # Usage: make dump-schema CONFIG=config-plugin.yaml diff --git a/cmd/fees/worker/main.go b/cmd/fees/worker/main.go index af449af..e5b1de1 100644 --- a/cmd/fees/worker/main.go +++ b/cmd/fees/worker/main.go @@ -56,6 +56,9 @@ func main() { ) postgressDB, err := postgres.NewPostgresBackend(cfg.Database.DSN, nil) + if err != nil { + panic(fmt.Errorf("failed to create postgres backend: %w", err)) + } txIndexerStore, err := storage.NewPostgresTxIndexStore(ctx, cfg.Database.DSN) if err != nil { diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml new file mode 100644 index 0000000..742e2d6 --- /dev/null +++ b/docker-compose.dev.yaml @@ -0,0 +1,37 @@ +services: + fee-worker: + build: + context: . + dockerfile: Dockerfile.Fee.worker.dev + volumes: + - ./cmd:/app/cmd + - ./plugin:/app/plugin + - ./internal:/app/internal + - ./api:/app/api + - ./storage:/app/storage + - ./common:/app/common + - ./pkg:/app/pkg + - ./service:/app/service + - ./fee.worker.example.json:/app/config.json + + fee-server: + build: + context: . + dockerfile: Dockerfile.Fee.server.dev + volumes: + - ./cmd:/app/cmd + - ./plugin:/app/plugin + - ./internal:/app/internal + - ./api:/app/api + - ./storage:/app/storage + - ./common:/app/common + - ./pkg:/app/pkg + - ./service:/app/service + - ./fee.server.example.json:/app/config.json + +volumes: + db_data: + minio_data: +networks: + shared_network: + external: true \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 088ee92..e6d940f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,5 +1,5 @@ services: - payroll-db: + plugin-db: # One DB instance for all plugins, which point to different databases image: postgres:15 environment: POSTGRES_USER: myuser @@ -29,6 +29,22 @@ services: interval: 1s timeout: 5s retries: 3 + volumes: + - redis_payroll:/data + + redis-fees: + image: redis:latest + ports: + - "6377:6379" + networks: + - shared_network + healthcheck: + test: [ "CMD", "redis-cli", "ping" ] + interval: 1s + timeout: 5s + retries: 3 + volumes: + - redis_fees:/data asynqmon: platform: linux/amd64 @@ -65,11 +81,11 @@ services: REDIS_HOST: redis-payroll REDIS_PORT: 6379 BLOCK_STORAGE_HOST: http://minio-plugin:9000 - DATABASE_DSN: postgres://myuser:mypassword@payroll-db:5432/vultisig-payroll?sslmode=disable + DATABASE_DSN: postgres://myuser:mypassword@plugin-db:5432/vultisig-payroll?sslmode=disable ports: - - "8081:8080" + - "8081:8080" depends_on: - payroll-db: + plugin-db: condition: service_healthy redis-payroll: condition: service_healthy @@ -77,7 +93,7 @@ services: condition: service_started networks: - shared_network - worker: + payroll-worker: build: context: . dockerfile: Dockerfile.Payroll.worker @@ -87,9 +103,9 @@ services: REDIS_HOST: redis-payroll REDIS_PORT: 6379 BLOCK_STORAGE_HOST: http://minio-plugin:9000 - DATABASE_DSN: postgres://myuser:mypassword@payroll-db:5432/vultisig-payroll?sslmode=disable + DATABASE_DSN: postgres://myuser:mypassword@plugin-db:5432/vultisig-payroll?sslmode=disable depends_on: - payroll-db: + plugin-db: condition: service_healthy redis-payroll: condition: service_healthy @@ -97,10 +113,55 @@ services: condition: service_started networks: - shared_network + + fee-server: + build: + context: . + dockerfile: Dockerfile.Fee.server + platforms: + - linux/amd64 + environment: + REDIS_HOST: redis-fees + REDIS_PORT: 6379 + BLOCK_STORAGE_HOST: http://minio-plugin:9000 + DATABASE_DSN: postgres://myuser:mypassword@plugin-db:5432/vultisig-fee?sslmode=disable + ports: + - "8082:8080" + depends_on: + plugin-db: + condition: service_healthy + redis-fees: + condition: service_healthy + minio-plugin: + condition: service_started + networks: + - shared_network + fee-worker: + build: + context: . + dockerfile: Dockerfile.Fee.worker + platforms: + - linux/amd64 + environment: + REDIS_HOST: redis-fees + REDIS_PORT: 6379 + BLOCK_STORAGE_HOST: http://minio-plugin:9000 + DATABASE_DSN: postgres://myuser:mypassword@plugin-db:5432/vultisig-fee?sslmode=disable + depends_on: + plugin-db: + condition: service_healthy + redis-fees: + condition: service_healthy + minio-plugin: + condition: service_started + networks: + - shared_network + volumes: db_data: - redis_data: - minio_data: + minio_data: + redis_payroll: + redis_fees: networks: shared_network: external: true diff --git a/etc/vultisig/fee.yml b/etc/vultisig/fee.yml new file mode 100644 index 0000000..1e48298 --- /dev/null +++ b/etc/vultisig/fee.yml @@ -0,0 +1,3 @@ +type: fee +version: 0.0.1 +rpc_url: https://eth.llamarpc.com diff --git a/fee.server.example.json b/fee.server.example.json new file mode 100644 index 0000000..0c9c70c --- /dev/null +++ b/fee.server.example.json @@ -0,0 +1,28 @@ +{ + "server": { + "host": "localhost", + "port": 8080, + "encryption_secret": "test123", + "verifier_url": "http://host.docker.internal:8080" + }, + "database": { + "dsn": "postgres://myuser:mypassword@plugin-db:5432/vultisig-fee?sslmode=disable" + }, + "base_config_path": "../../../etc/vultisig", + "redis": { + "host": "redis-fees", + "port": "6379", + "password": "password" + }, + "block_storage": { + "host": "http://localhost:9100", + "region": "us-east-1", + "access_key": "minioadmin", + "secret": "minioadmin", + "bucket": "vultisig-fee" + }, + "datadog": { + "host": "localhost", + "port": 8125 + } +} diff --git a/fee_config.example.json b/fee_config.example.json deleted file mode 100644 index 231e5a1..0000000 --- a/fee_config.example.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "fees", - "version": "1.0.0", - "rpc_url": "https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY", - "usdc_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", - "collector_address": "0x0000000000000000000000000000000000000000", - "gas": { - "limit_multiplier": 1, - "price_multiplier": 1 - }, - "monitoring": { - "timeout_minutes": 30, - "check_interval_seconds": 60 - } -} diff --git a/init-scripts/01_create_vultisig_plugin.sql b/init-scripts/01_create_vultisig_plugin.sql index 9f39f90..bab1f08 100644 --- a/init-scripts/01_create_vultisig_plugin.sql +++ b/init-scripts/01_create_vultisig_plugin.sql @@ -1 +1,3 @@ -CREATE DATABASE "vultisig-payroll"; \ No newline at end of file +CREATE DATABASE "vultisig-payroll"; +CREATE DATABASE "vultisig-fee"; +CREATE DATABASE "vultisig-dca"; \ No newline at end of file diff --git a/payroll.server.example.json b/payroll.server.example.json index 0da9c63..15947b9 100644 --- a/payroll.server.example.json +++ b/payroll.server.example.json @@ -1,27 +1,27 @@ { - "server": { - "host": "localhost", - "port": 8080, - "encryption_secret": "test123" - }, - "database": { - "dsn": "postgres://myuser:mypassword@localhost:5431/vultisig-payroll?sslmode=disable" - }, - "base_config_path": "../../../etc/vultisig", - "redis": { - "host": "localhost", - "port": "6378", - "password": "password" - }, - "block_storage": { - "host": "http://localhost:9100", - "region": "us-east-1", - "access_key": "minioadmin", - "secret": "minioadmin", - "bucket": "vultisig-payroll" - }, - "datadog": { - "host": "localhost", - "port": 8125 - } + "server": { + "host": "localhost", + "port": 8080, + "encryption_secret": "test123" + }, + "database": { + "dsn": "postgres://myuser:mypassword@plugin-db:5432/vultisig-payroll?sslmode=disable" + }, + "base_config_path": "../../../etc/vultisig", + "redis": { + "host": "localhost", + "port": "6378", + "password": "password" + }, + "block_storage": { + "host": "http://localhost:9100", + "region": "us-east-1", + "access_key": "minioadmin", + "secret": "minioadmin", + "bucket": "vultisig-payroll" + }, + "datadog": { + "host": "localhost", + "port": 8125 + } } diff --git a/payroll.worker.example.json b/payroll.worker.example.json index be818a6..5d1e3b2 100644 --- a/payroll.worker.example.json +++ b/payroll.worker.example.json @@ -1,30 +1,30 @@ { - "vault_service": { - "relay": { - "server": "https://api.vultisig.com/router" + "vault_service": { + "relay": { + "server": "https://api.vultisig.com/router" + }, + "local_party_prefix": "payroll-plugin-0000", + "queue_email_task": false, + "encryption_secret": "test123" }, - "local_party_prefix": "payroll-plugin-0000", - "queue_email_task": false, - "encryption_secret": "test123" - }, - "redis": { - "host": "localhost", - "port": "6378", - "password": "password" - }, - "block_storage": { - "host": "http://localhost:9100", - "region": "us-east-1", - "access_key": "minioadmin", - "secret": "minioadmin", - "bucket": "vultisig-payroll" - }, - "datadog": { - "host": "localhost", - "port": 8125 - }, - "base_file_path": "../../../etc/vultisig", - "database": { - "dsn": "postgres://myuser:mypassword@localhost:5431/vultisig-plugin?sslmode=disable" - } + "redis": { + "host": "localhost", + "port": "6378", + "password": "password" + }, + "block_storage": { + "host": "http://localhost:9100", + "region": "us-east-1", + "access_key": "minioadmin", + "secret": "minioadmin", + "bucket": "vultisig-payroll" + }, + "datadog": { + "host": "localhost", + "port": 8125 + }, + "base_file_path": "../../../etc/vultisig", + "database": { + "dsn": "postgres://myuser:mypassword@plugin-db:5432/vultisig-payroll?sslmode=disable" + } }