- Go 1.23 or later
- Docker 20+ (for local testing)
- Make
# Clone the repository
git clone https://github.com/0g-citizen-claw/agent-wrapper.git
cd agent-wrapper
# Install dependencies
go mod download
# Run tests
make test
# Build locally
make buildagent-wrapper/
├── cmd/
│ └── wrapper/
│ └── main.go # Entry point
├── internal/ # Private packages
│ ├── attest/ # Attestor service client
│ ├── blockchain/ # Blockchain client
│ ├── config/ # Configuration management
│ ├── flow/ # Initialization orchestration
│ ├── framework/ # Dynamic framework installation
│ ├── init/ # HTTP initialization server
│ ├── mock/ # Mock server for testing
│ ├── process/ # Agent process management
│ ├── proxy/ # HTTP proxy with signing
│ └── sealed/ # Sealed state management
├── pkg/ # Public packages (currently empty)
├── docs/ # Documentation
├── examples/ # Example agents
│ └── demo-agent.py # Demo agent for testing
├── Makefile # Build commands
├── Dockerfile # Container build
├── docker-compose.yml # Development compose
├── go.mod # Go module definition
└── README.md # User documentation
HTTP server that receives initialization parameters.
Files:
server.go- HTTP server implementationserver_test.go- Unit tests
Responsibilities:
- Serve
/_internal/initendpoint - Serve
/_internal/healthendpoint - Serve
/_internal/readyendpoint - Track initialization status
Thread-safe state management for sensitive data.
Files:
state.go- State implementationstate_test.go- Unit tests
Responsibilities:
- Store sealId, tempKey, attestorUrl
- Generate and store ECDSA key pair
- Store agentSeal private key
- Store agentId
- Provide thread-safe getters
Client for Attestor service communication.
Files:
client.go- Client implementationclient_test.go- Unit tests with mock
Responsibilities:
- Perform remote attestation
- Retrieve agentSeal private key
- Handle authentication tokens
Client for blockchain queries.
Files:
client.go- Client implementationclient_test.go- Unit tests with mock
Responsibilities:
- Query agentId by sealId
- Query IntelligentData array
- Parse blockchain responses
Client for 0G Storage.
Files:
storage.go- Client implementationstorage_test.go- Unit tests with mock
Responsibilities:
- Fetch encrypted configuration
- Handle storage errors
Configuration management.
Files:
manager.go- Config implementationmanager_test.go- Unit tests
Responsibilities:
- Decrypt encrypted config
- Validate config structure
- Provide default config
Dynamic framework installation.
Files:
installer.go- Installer implementationinstaller_test.go- Unit tests
Responsibilities:
- Install Python packages (pip)
- Install Node.js packages (npm)
- Handle installation timeouts
- Report installation results
Agent process management.
Files:
manager.go- Process managermanager_test.go- Unit tests
Responsibilities:
- Start agent process
- Stop agent process gracefully
- Monitor process health
- Auto-restart on crash
HTTP proxy with ECDSA signing.
Files:
proxy.go- Proxy implementationproxy_test.go- Unit tests
Responsibilities:
- Proxy requests to agent
- Sign responses with ECDSA
- Add signature headers
Initialization flow orchestration.
Files:
orchestrator.go- Orchestrator implementationorchestrator_test.go- Unit testse2e_test.go- End-to-end testsdemo_test.go- Demo mode tests
Responsibilities:
- Coordinate all initialization steps
- Handle demo mode
- Manage state transitions
HTTP mock server for testing.
Files:
mock.go- Mock servermock_test.go- Mock tests
Responsibilities:
- Mock Attestor endpoints
- Mock Blockchain endpoints
- Mock Storage endpoints
git checkout -b feature/your-feature-nameFollowing Test-Driven Development:
// internal/yourmodule/yourmodule_test.go
func TestYourFunction(t *testing.T) {
t.Run("does something expected", func(t *testing.T) {
// Arrange
input := "test"
// Act
result := YourFunction(input)
// Assert
assert.Equal(t, "expected", result)
})
}go test ./internal/yourmodule/... -v// internal/yourmodule/yourmodule.go
func YourFunction(input string) string {
return "expected"
}go test ./internal/yourmodule/... -vgit add .
git commit -m "feat: add your feature"
git push origin feature/your-feature-name# Run all unit tests
make test-unit
# Run specific package tests
go test ./internal/init/... -v
# Run with coverage
go test -cover ./internal/...
# Run with race detector
go test -race ./internal/...# Run E2E tests (requires Docker)
make test-e2e
# Run specific E2E test
go test ./internal/flow/... -v -run E2E# Run demo mode tests
DEMO_MODE=true go test ./internal/flow/... -v -run Demo# Build for current platform
make build
# Output: ./bin/wrapper# Build Docker image
make docker
# Run with demo mode
docker run -p 8080:8080 -e DEMO_MODE=true \
0g-citizen-claw/agent-wrapper:latest# Start all services
make compose-up
# View logs
docker-compose logs -f
# Stop services
make compose-down# Create directory
mkdir -p internal/newmodule
# Create test file
cat > internal/newmodule/newmodule_test.go << 'EOF'
package newmodule
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestNewFunction(t *testing.T) {
t.Run("returns expected result", func(t *testing.T) {
result := NewFunction()
assert.Equal(t, "expected", result)
})
}
EOF
# Create implementation file
cat > internal/newmodule/newmodule.go << 'EOF'
package newmodule
// NewFunction does something.
func NewFunction() string {
return "expected"
}
EOFtype MyClient struct {
baseURL string
httpClient *http.Client
}
func NewMyClient(baseURL string, timeout time.Duration) *MyClient {
if timeout == 0 {
timeout = 30 * time.Second
}
return &MyClient{
baseURL: baseURL,
httpClient: &http.Client{
Timeout: timeout,
},
}
}type MyState struct {
mu sync.RWMutex
value string
}
func (s *MyState) GetValue() string {
s.mu.RLock()
defer s.mu.RUnlock()
return s.value
}
func (s *MyState) SetValue(value string) {
s.mu.Lock()
defer s.mu.Unlock()
s.value = value
}# Run with Delve
dlv debug ./cmd/wrapper
# Run tests with Delve
dlv test ./internal/sealed/...For quick testing without external services:
# Set demo mode
export DEMO_MODE=true
go run ./cmd/wrapper
# Or with Docker
docker run -p 8080:8080 -e DEMO_MODE=true \
0g-citizen-claw/agent-wrapper:latestSet log level for debugging:
export LOG_LEVEL=debug
go run ./cmd/wrapper# Format all Go files
go fmt ./...# Run golangci-lint (if installed)
golangci-lint run- Update version in
cmd/wrapper/main.go - Update documentation
# Build release
make build
# Build Docker image
make docker# Run all checks
make check- Run all tests:
make test - Format code:
go fmt ./... - Test demo mode:
DEMO_MODE=true go test ./... - Update documentation: If adding new features
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Unit tests added/updated
- [ ] E2E tests pass
- [ ] Demo mode tested
## Checklist
- [ ] Code follows project patterns
- [ ] All tests pass
- [ ] Documentation updated- README.md - Project overview
- CLAUDE.md - Claude Code instructions
- architecture.md - Architecture diagrams
- design.md - Design details
- api.md - API documentation