environments - saltict/Demo-Docs GitHub Wiki

Environment Configuration

This document covers environment-specific configurations, deployment settings, and runtime parameters for the SubWallet Services SDK across different environments.

Quick Navigation

Overview

The SubWallet Services SDK supports multiple deployment environments with specific configurations for each. Environment management ensures optimal performance, security, and reliability across development, staging, and production deployments.

Environment Types

Development Environment

Purpose: Local development and unit testing

// File: src/config/development.ts
export const developmentConfig = {
  environment: 'development',
  apiEndpoints: {
    priceHistory: 'http://localhost:3001/api/price-history',
    balanceDetection: 'http://localhost:3002/api/balance',
    xcm: 'http://localhost:3003/api/xcm',
    cardano: 'http://localhost:3004/api/cardano',
    swap: 'http://localhost:3005/api/swap'
  },
  logging: {
    level: 'debug',
    enableConsole: true,
    enableFile: false
  },
  cache: {
    enabled: false,
    ttl: 60
  },
  security: {
    rateLimiting: false,
    apiKeyRequired: false
  }
};

Staging Environment

Purpose: Integration testing and UAT

// File: src/config/staging.ts
export const stagingConfig = {
  environment: 'staging',
  apiEndpoints: {
    priceHistory: 'https://staging-api.subwallet.io/price-history',
    balanceDetection: 'https://staging-api.subwallet.io/balance',
    xcm: 'https://staging-api.subwallet.io/xcm',
    cardano: 'https://staging-api.subwallet.io/cardano',
    swap: 'https://staging-api.subwallet.io/swap'
  },
  logging: {
    level: 'info',
    enableConsole: true,
    enableFile: true
  },
  cache: {
    enabled: true,
    ttl: 300
  },
  security: {
    rateLimiting: true,
    apiKeyRequired: true
  }
};

Production Environment

Purpose: Live production deployment

// File: src/config/production.ts
export const productionConfig = {
  environment: 'production',
  apiEndpoints: {
    priceHistory: 'https://api.subwallet.io/price-history',
    balanceDetection: 'https://api.subwallet.io/balance',
    xcm: 'https://api.subwallet.io/xcm',
    cardano: 'https://api.subwallet.io/cardano',
    swap: 'https://api.subwallet.io/swap'
  },
  logging: {
    level: 'warn',
    enableConsole: false,
    enableFile: true
  },
  cache: {
    enabled: true,
    ttl: 600
  },
  security: {
    rateLimiting: true,
    apiKeyRequired: true,
    encryption: true
  }
};

Configuration Management

Environment Detection

// File: src/config/index.ts
import { developmentConfig } from './development';
import { stagingConfig } from './staging';
import { productionConfig } from './production';

export interface SDKConfig {
  environment: string;
  apiEndpoints: Record<string, string>;
  logging: {
    level: string;
    enableConsole: boolean;
    enableFile: boolean;
  };
  cache: {
    enabled: boolean;
    ttl: number;
  };
  security: {
    rateLimiting: boolean;
    apiKeyRequired: boolean;
    encryption?: boolean;
  };
}

export function getConfig(): SDKConfig {
  const env = process.env.NODE_ENV || 'development';
  
  switch (env) {
    case 'development':
      return developmentConfig;
    case 'staging':
      return stagingConfig;
    case 'production':
      return productionConfig;
    default:
      console.warn(`Unknown environment: ${env}, falling back to development`);
      return developmentConfig;
  }
}

export const config = getConfig();

Environment Variables

Required Variables

# Core Configuration
NODE_ENV=production
SDK_VERSION=0.1.3-beta.5

# API Configuration
PRICE_HISTORY_API_URL=https://api.subwallet.io/price-history
BALANCE_DETECTION_API_URL=https://api.subwallet.io/balance
XCM_API_URL=https://api.subwallet.io/xcm
CARDANO_API_URL=https://api.subwallet.io/cardano
SWAP_API_URL=https://api.subwallet.io/swap

# Registry Configuration
NPM_REGISTRY=https://registry.konistudio.xyz
NPM_TOKEN=your_npm_token_here

# Security
API_KEY=your_api_key_here
ENCRYPTION_KEY=your_encryption_key_here

# Logging
LOG_LEVEL=info
LOG_FILE_PATH=/var/log/subwallet-sdk.log

# Cache Configuration
CACHE_ENABLED=true
CACHE_TTL=600
CACHE_REDIS_URL=redis://localhost:6379

Optional Variables

# Performance Tuning
REQUEST_TIMEOUT=30000
MAX_CONCURRENT_REQUESTS=10
RETRY_ATTEMPTS=3

# Monitoring
METRICS_ENABLED=true
METRICS_PORT=9090
HEALTH_CHECK_ENABLED=true

# Debug Options
DEBUG_MODE=false
VERBOSE_LOGGING=false
PERFORMANCE_MONITORING=true

Configuration Validation

// File: src/config/validator.ts
import Joi from 'joi';

const configSchema = Joi.object({
  environment: Joi.string().valid('development', 'staging', 'production').required(),
  apiEndpoints: Joi.object({
    priceHistory: Joi.string().uri().required(),
    balanceDetection: Joi.string().uri().required(),
    xcm: Joi.string().uri().required(),
    cardano: Joi.string().uri().required(),
    swap: Joi.string().uri().required()
  }).required(),
  logging: Joi.object({
    level: Joi.string().valid('debug', 'info', 'warn', 'error').required(),
    enableConsole: Joi.boolean().required(),
    enableFile: Joi.boolean().required()
  }).required(),
  cache: Joi.object({
    enabled: Joi.boolean().required(),
    ttl: Joi.number().min(0).required()
  }).required(),
  security: Joi.object({
    rateLimiting: Joi.boolean().required(),
    apiKeyRequired: Joi.boolean().required(),
    encryption: Joi.boolean().optional()
  }).required()
});

export function validateConfig(config: any): void {
  const { error } = configSchema.validate(config);
  if (error) {
    throw new Error(`Configuration validation failed: ${error.message}`);
  }
}

Security & Secrets

Secret Management

%%{init: {'theme':'dark'}}%%
graph TB
    App[Application] --> Vault[Secret Vault]
    Vault --> Env[Environment Variables]
    Vault --> Files[Secret Files]
    Vault --> KMS[Key Management Service]
    
    Env --> Runtime[Runtime Configuration]
    Files --> Runtime
    KMS --> Runtime
    
    Runtime --> Services[SDK Services]
    
    style App fill:#2d3748,stroke:#4a5568,color:#fff
    style Vault fill:#1a202c,stroke:#2d3748,color:#fff
    style Env fill:#553c9a,stroke:#6b46c1,color:#fff
    style Files fill:#553c9a,stroke:#6b46c1,color:#fff
    style KMS fill:#553c9a,stroke:#6b46c1,color:#fff
    style Runtime fill:#2d3748,stroke:#4a5568,color:#fff
    style Services fill:#10b981,stroke:#059669,color:#fff
Loading

API Key Management

// File: src/config/secrets.ts
export class SecretManager {
  private static instance: SecretManager;
  private secrets: Map<string, string> = new Map();

  static getInstance(): SecretManager {
    if (!SecretManager.instance) {
      SecretManager.instance = new SecretManager();
    }
    return SecretManager.instance;
  }

  async loadSecrets(): Promise<void> {
    // Load from environment variables
    this.loadFromEnvironment();
    
    // Load from secret files (in production)
    if (process.env.NODE_ENV === 'production') {
      await this.loadFromFiles();
    }
    
    // Load from external vault (if configured)
    if (process.env.VAULT_URL) {
      await this.loadFromVault();
    }
  }

  private loadFromEnvironment(): void {
    const secretKeys = [
      'API_KEY',
      'ENCRYPTION_KEY',
      'NPM_TOKEN',
      'CACHE_REDIS_URL'
    ];

    secretKeys.forEach(key => {
      const value = process.env[key];
      if (value) {
        this.secrets.set(key, value);
      }
    });
  }

  getSecret(key: string): string | undefined {
    return this.secrets.get(key);
  }

  hasSecret(key: string): boolean {
    return this.secrets.has(key);
  }
}

Encryption Configuration

// File: src/config/encryption.ts
export interface EncryptionConfig {
  algorithm: string;
  keyLength: number;
  ivLength: number;
}

export const encryptionConfig: EncryptionConfig = {
  algorithm: 'aes-256-gcm',
  keyLength: 32,
  ivLength: 16
};

export function createEncryptionKey(): string {
  return crypto.randomBytes(encryptionConfig.keyLength).toString('hex');
}

Registry Configuration

NPM Registry Setup

Public Registry

# Configure for npmjs.org
npm config set registry https://registry.npmjs.org/
npm config set @subwallet-monorepos:registry https://registry.npmjs.org/

Private Registry

# Configure for private registry
npm config set registry https://registry.konistudio.xyz
npm config set @subwallet-monorepos:registry https://registry.konistudio.xyz
npm config set //registry.konistudio.xyz/:_authToken "${NPM_TOKEN}"

Registry Authentication

// File: src/config/registry.ts
export interface RegistryConfig {
  url: string;
  authToken?: string;
  scope?: string;
}

export function getRegistryConfig(): RegistryConfig {
  const registryUrl = process.env.NPM_REGISTRY || 'https://registry.npmjs.org/';
  
  return {
    url: registryUrl,
    authToken: process.env.NPM_TOKEN,
    scope: '@subwallet-monorepos'
  };
}

export async function verifyRegistryAccess(config: RegistryConfig): Promise<boolean> {
  try {
    const response = await fetch(`${config.url}ping`);
    return response.ok;
  } catch (error) {
    console.error('Registry access verification failed:', error);
    return false;
  }
}

Monitoring & Logging

Environment-Specific Logging

// File: src/config/logging.ts
import winston from 'winston';
import { config } from './index';

export function createLogger(): winston.Logger {
  const transports: winston.transport[] = [];

  // Console transport for development
  if (config.logging.enableConsole) {
    transports.push(new winston.transports.Console({
      format: winston.format.combine(
        winston.format.colorize(),
        winston.format.simple()
      )
    }));
  }

  // File transport for staging/production
  if (config.logging.enableFile) {
    transports.push(new winston.transports.File({
      filename: process.env.LOG_FILE_PATH || 'subwallet-sdk.log',
      format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.json()
      )
    }));
  }

  return winston.createLogger({
    level: config.logging.level,
    transports
  });
}

export const logger = createLogger();

Performance Monitoring

// File: src/config/monitoring.ts
export interface PerformanceMetrics {
  requestDuration: number;
  memoryUsage: NodeJS.MemoryUsage;
  cpuUsage: NodeJS.CpuUsage;
  timestamp: Date;
}

export class PerformanceMonitor {
  private metrics: PerformanceMetrics[] = [];

  captureMetrics(): PerformanceMetrics {
    const metric: PerformanceMetrics = {
      requestDuration: 0, // Set by individual services
      memoryUsage: process.memoryUsage(),
      cpuUsage: process.cpuUsage(),
      timestamp: new Date()
    };

    this.metrics.push(metric);
    
    // Keep only last 1000 metrics
    if (this.metrics.length > 1000) {
      this.metrics.shift();
    }

    return metric;
  }

  getAverageMetrics(): Partial<PerformanceMetrics> {
    if (this.metrics.length === 0) return {};

    const totals = this.metrics.reduce((acc, metric) => ({
      requestDuration: acc.requestDuration + metric.requestDuration,
      heapUsed: acc.heapUsed + metric.memoryUsage.heapUsed,
      external: acc.external + metric.memoryUsage.external
    }), { requestDuration: 0, heapUsed: 0, external: 0 });

    return {
      requestDuration: totals.requestDuration / this.metrics.length,
      memoryUsage: {
        ...process.memoryUsage(),
        heapUsed: totals.heapUsed / this.metrics.length,
        external: totals.external / this.metrics.length
      }
    };
  }
}

Environment Deployment Matrix

Feature Development Staging Production
API Endpoints Localhost staging.subwallet.io api.subwallet.io
Logging Level debug info warn
Caching Disabled Enabled (5min) Enabled (10min)
Rate Limiting Disabled Enabled Enabled
API Keys Optional Required Required
Encryption Disabled Enabled Enabled
Monitoring Basic Full Full
Registry Local/Public Private Private

Configuration Examples

Docker Environment

# Dockerfile
FROM node:18-alpine

# Set environment variables
ENV NODE_ENV=production
ENV NPM_REGISTRY=https://registry.konistudio.xyz
ENV LOG_LEVEL=info

# Copy configuration
COPY config/ /app/config/
COPY .env.production /app/.env

WORKDIR /app
CMD ["node", "index.js"]

Kubernetes ConfigMap

# k8s-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: subwallet-sdk-config
data:
  NODE_ENV: "production"
  PRICE_HISTORY_API_URL: "https://api.subwallet.io/price-history"
  BALANCE_DETECTION_API_URL: "https://api.subwallet.io/balance"
  XCM_API_URL: "https://api.subwallet.io/xcm"
  CARDANO_API_URL: "https://api.subwallet.io/cardano"
  SWAP_API_URL: "https://api.subwallet.io/swap"
  LOG_LEVEL: "info"
  CACHE_ENABLED: "true"
  CACHE_TTL: "600"

Next Steps:


Navigation: ← Release Process | Deployment Overview | Development →

⚠️ **GitHub.com Fallback** ⚠️