Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Ignore files not necessary for the Docker build
.git
.gitignore
*.md
testsheet.md
README.md

# Ignore development files
.vscode
.idea
*.swp
*.swo
*~

# Ignore build and unnecessary binaries
bin/windows/
*.exe

# Ignore Go files not necessary
*.go
go.mod
go.sum
cmd/
internal/

# Ignore test files
*_test.go
*.test

# Ignore local configuration files (if present)
.env
.env.local
.env.*.local

# Ignore other temporary files
*.log
*.tmp
.DS_Store
Thumbs.db

41 changes: 41 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# ====================================== CLI ======================================

# IOTA Rebased testnet RPC
REBASE_RPC=https://api.testnet.iota.cafe:443

# Endpoint for GC info
GC_ENDPOINT=http://...

# User Data
USER_PRIVATE_KEY=iotaprivkey1...
USER_ADDRESS=0x...
USER_GAS_COIN_ID=0x...

# Provider Data
PROVIDER_PRIVATE_KEY=iotaprivkey1...
PROVIDER_ADDRESS=0x...
PROVIDER_GAS_COIN_ID=0x...

# DCS System Data
DCS_PACKAGE_ID=0x6f1171331dd83efac6cecba51a5943d50553c2728554c70cd7d4d37dfa0eccde
DCS_WHITELIST_ID=0x544d411977ea6255686388050b40f5652207ee12e0b3cb6e7d8ce1bea98f0bc7
DCS_CIDLIST_ID=0x17ee700860a8b106b51430839996125a074a609b29a834b24d60404d32753e39
DCS_CLOCK_ID=0x6
WALLET_GAS_BUDGET=10000000
FAUCET_URL=https://faucet.testnet.iota.cafe
IOTA_GRAPHQL_ENDPOINT=https://graphql.testnet.iota.cafe

# Active Wallet (user/provider)
ACTIVE_PRIVATE_KEY=iotaprivkey1...
ACTIVE_ADDRESS=0x...
ACTIVE_GAS_COIN_ID=0x... # optional, if not set, one of the following env vars will be used, according to the expected actor: USER_GAS_COIN_ID, PROVIDER_GAS_COIN_ID


# ====================================== API ======================================

PORT=8080

# GroundControl (GC) Wallet
GC_PRIVATE_KEY=iotaprivkey1...
GC_ADDRESS=0x...
GC_WALLET_GAS_ID=0x...
32 changes: 21 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
name: CI

on: # Trigger the workflow on every push or pull request
pull_request:
branches: [main]
push:
on:
pull_request:
branches: [main]
push:
branches: [main]

jobs:
test:
# Run on major OSes
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
go: ['1.24']
go: ['1.24']
runs-on: ${{ matrix.os }}

defaults:
run:
shell: bash

steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
- run: go vet ./...
- run: go test -v ./... # run tests for every package
- run: go build ./... # build every package

- run: go vet ./...

- name: Run tests (excluding cmd/cli/ipfs)
run: |
set -euo pipefail
PKGS="$(go list ./... | grep -vE '/cmd/cli/ipfs$')"
go test -v $PKGS

- run: go build ./...
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@
go.work
go.work.sum

# env file
.env
# env files
.env*
!.env.example
accounts/
36 changes: 36 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
FROM alpine:latest

# Install dependencies
RUN apk --no-cache add ca-certificates libc6-compat

# Create a non-root user
RUN addgroup -g 1000 dcs && \
adduser -D -u 1000 -G dcs dcs

# Create working directory
WORKDIR /app

# Copy the executable
COPY bin/linux/DCS-API /app/DCS-API

# Verify that the file exists and set permissions
RUN ls -la /app/DCS-API && \
chmod +x /app/DCS-API && \
chown -R dcs:dcs /app

# Pass to the non-root user
USER dcs

# Define port as build argument with default value
ARG PORT=8080

# Set port as environment variable and expose it
ENV PORT=${PORT}
EXPOSE ${PORT}

# Note: Sensitive environment variables (e.g. GC_PRIVATE_KEY, GC_ADDRESS, GC_WALLET_GAS_ID, etc.)
# must be passed at runtime using --env-file or -e flags.

# Entrypoint to execute the application
ENTRYPOINT ["/app/DCS-API"]

47 changes: 47 additions & 0 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package main

import (
"os"

"github.com/gin-gonic/gin"

"github.com/teleconsys/DCS/internal/config"
)

func main() {
// Load environment variables from .env file
config.LoadEnv()

// Initialize router
router := gin.Default()

// Get groundcontrol info enbdpoint
router.GET("/get-groundcontrol-info", func(c *gin.Context) {

privateKey := os.Getenv("GC_PRIVATE_KEY")
address := os.Getenv("GC_ADDRESS")
walletGasId := os.Getenv("GC_WALLET_GAS_ID")

if privateKey == "" || address == "" || walletGasId == "" {
c.JSON(400, gin.H{
"error": "GC_PRIVATE_KEY, GC_ADDRESS, or GC_WALLET_GAS_ID is not set",
})
return
}

c.JSON(200, gin.H{
"privateKey": privateKey,
"address": address,
"walletGasId": walletGasId,
})
})

// Get port from environment variable, default to 8080
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

// Start server
router.Run(":" + port)
};
14 changes: 14 additions & 0 deletions cmd/cli/app/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package app

import "github.com/spf13/cobra"

func NewCmd() *cobra.Command {
appCmd := &cobra.Command{
Use: "app",
Short: "Application-level operations",
}

// leaf commands
appCmd.AddCommand(newStartCmd())
return appCmd
}
29 changes: 29 additions & 0 deletions cmd/cli/app/app_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package app

import (
"bytes"
"strings"
"testing"

"github.com/spf13/cobra"
)

func exec(cmd *cobra.Command, args ...string) (string, error) {
buf := new(bytes.Buffer)
cmd.SetOut(buf)
cmd.SetErr(buf)
cmd.SetArgs(args)
_, err := cmd.ExecuteC()
return buf.String(), err
}

func TestStartCmd(t *testing.T) {
root := NewCmd() // app sub-tree
out, err := exec(root, "start")
if err != nil {
t.Fatalf("start returned error: %v", err)
}
if !strings.Contains(out, "DCS app starting") {
t.Errorf("got %q, want substring %q", out, "DCS app starting")
}
}
14 changes: 14 additions & 0 deletions cmd/cli/app/start.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package app

import "github.com/spf13/cobra"

func newStartCmd() *cobra.Command {
return &cobra.Command{
Use: "start",
Short: "Start the DCS application locally",
Run: func(cmd *cobra.Command, _ []string) {
cmd.Println("DCS app starting …")
// TODO: real start-up logic
},
}
}
Loading