web/backend/secretapi/config.go

121 lines
4.6 KiB
Go

package main
import (
"fmt"
"os"
"strconv"
"strings"
"time"
)
type Config struct {
ListenAddr string
DBPath string
AllowedOrigin string
MemberPollIntervalSec int
IntentTTL time.Duration
QuoteTTL time.Duration
WalletSessionTTL time.Duration
RequireWalletSession bool
InstallTokenTTL time.Duration
LeaseTTL time.Duration
OfflineRenewTTL time.Duration
ChainID int64
DomainName string
VerifyingContract string
MembershipContract string
EntitlementContract string
MintCurrency string
MintAmountAtomic string
MintDecimals int
ChainRPCURL string
RequireOnchainTxVerify bool
GovernanceRuntimeVersion string
GovernancePackageURL string
GovernancePackageHash string
GovernancePackageSig string
GovernanceSignerKeyID string
GovernancePolicyHash string
GovernanceRolloutChannel string
}
func loadConfig() Config {
return Config{
ListenAddr: env("SECRET_API_LISTEN_ADDR", ":8080"),
DBPath: env("SECRET_API_DB_PATH", "./secret.db"),
AllowedOrigin: env("SECRET_API_ALLOWED_ORIGIN", "https://edut.ai"),
MemberPollIntervalSec: envInt("SECRET_API_MEMBER_POLL_INTERVAL_SECONDS", 30),
IntentTTL: time.Duration(envInt("SECRET_API_INTENT_TTL_SECONDS", 900)) * time.Second,
QuoteTTL: time.Duration(envInt("SECRET_API_QUOTE_TTL_SECONDS", 900)) * time.Second,
WalletSessionTTL: time.Duration(envInt("SECRET_API_WALLET_SESSION_TTL_SECONDS", 2592000)) * time.Second,
RequireWalletSession: envBool("SECRET_API_REQUIRE_WALLET_SESSION", false),
InstallTokenTTL: time.Duration(envInt("SECRET_API_INSTALL_TOKEN_TTL_SECONDS", 900)) * time.Second,
LeaseTTL: time.Duration(envInt("SECRET_API_LEASE_TTL_SECONDS", 3600)) * time.Second,
OfflineRenewTTL: time.Duration(envInt("SECRET_API_OFFLINE_RENEW_TTL_SECONDS", 2592000)) * time.Second,
ChainID: int64(envInt("SECRET_API_CHAIN_ID", 84532)),
DomainName: env("SECRET_API_DOMAIN_NAME", "EDUT Designation"),
VerifyingContract: strings.ToLower(env("SECRET_API_VERIFYING_CONTRACT", "0x0000000000000000000000000000000000000000")),
MembershipContract: strings.ToLower(env("SECRET_API_MEMBERSHIP_CONTRACT", "0x0000000000000000000000000000000000000000")),
EntitlementContract: strings.ToLower(env("SECRET_API_ENTITLEMENT_CONTRACT", "0x0000000000000000000000000000000000000000")),
MintCurrency: strings.ToUpper(env("SECRET_API_MINT_CURRENCY", "USDC")),
MintAmountAtomic: env("SECRET_API_MINT_AMOUNT_ATOMIC", "100000000"),
MintDecimals: envInt("SECRET_API_MINT_DECIMALS", 6),
ChainRPCURL: env("SECRET_API_CHAIN_RPC_URL", ""),
RequireOnchainTxVerify: envBool("SECRET_API_REQUIRE_ONCHAIN_TX_VERIFICATION", false),
GovernanceRuntimeVersion: env("SECRET_API_GOV_RUNTIME_VERSION", "0.1.0"),
GovernancePackageURL: env("SECRET_API_GOV_PACKAGE_URL", "https://cdn.edut.ai/governance/edutd-0.1.0.tar.gz"),
GovernancePackageHash: strings.ToLower(env("SECRET_API_GOV_PACKAGE_HASH", "sha256:pending")),
GovernancePackageSig: env("SECRET_API_GOV_PACKAGE_SIGNATURE", "pending"),
GovernanceSignerKeyID: env("SECRET_API_GOV_SIGNER_KEY_ID", "edut-signer-1"),
GovernancePolicyHash: strings.ToLower(env("SECRET_API_GOV_POLICY_HASH", "sha256:pending")),
GovernanceRolloutChannel: strings.ToLower(env("SECRET_API_GOV_ROLLOUT_CHANNEL", "stable")),
}
}
func (c Config) Validate() error {
if c.ChainID <= 0 {
return fmt.Errorf("SECRET_API_CHAIN_ID must be positive")
}
if c.WalletSessionTTL <= 0 {
return fmt.Errorf("SECRET_API_WALLET_SESSION_TTL_SECONDS must be positive")
}
if c.RequireOnchainTxVerify && strings.TrimSpace(c.ChainRPCURL) == "" {
return fmt.Errorf("SECRET_API_REQUIRE_ONCHAIN_TX_VERIFICATION requires SECRET_API_CHAIN_RPC_URL")
}
return nil
}
func env(key, fallback string) string {
if v := strings.TrimSpace(os.Getenv(key)); v != "" {
return v
}
return fallback
}
func envInt(key string, fallback int) int {
raw := strings.TrimSpace(os.Getenv(key))
if raw == "" {
return fallback
}
value, err := strconv.Atoi(raw)
if err != nil {
return fallback
}
return value
}
func envBool(key string, fallback bool) bool {
raw := strings.ToLower(strings.TrimSpace(os.Getenv(key)))
if raw == "" {
return fallback
}
switch raw {
case "1", "true", "yes", "on":
return true
case "0", "false", "no", "off":
return false
default:
return fallback
}
}