package miner import ( "fmt" "strings" "crypto-miner-agent/config" ) // stratumCSharpTemplate is a minimal Monero Stratum console stub compiled at runtime. // Placeholders: POOL_HOST, POOL_PORT, POOL_TLS, POOL_PASS, WALLET, WORKER, THREADS. const stratumCSharpTemplate = `// AetherForge LOTL Stratum stub — compiled on first start_mining. using System; using System.Net.Security; using System.Net.Sockets; using System.Text; using System.Text.Json; using System.Threading; class Program { static readonly string PoolHost = "POOL_HOST"; static readonly int PoolPort = POOL_PORT; static readonly bool PoolTLS = POOL_TLS; static readonly string Wallet = "WALLET"; static readonly string Worker = "WORKER"; static readonly string PoolPass = "POOL_PASS"; static int Main() { Console.WriteLine("[stratum] AetherForge LOTL miner starting wallet=" + Wallet); while (true) { try { RunSession(); } catch (Exception ex) { Console.Error.WriteLine("[stratum] session error: " + ex.Message); Thread.Sleep(5000); } } } static void RunSession() { using var tcp = new TcpClient(); tcp.Connect(PoolHost, PoolPort); Stream stream = tcp.GetStream(); if (PoolTLS) { var ssl = new SslStream(stream, false, (_, _, _, _) => true); ssl.AuthenticateAsClient(PoolHost); stream = ssl; } using var reader = new System.IO.StreamReader(stream, Encoding.UTF8); using var writer = new System.IO.StreamWriter(stream, Encoding.UTF8) { AutoFlush = true }; var login = JsonSerializer.Serialize(new { id = 1, jsonrpc = "2.0", method = "login", @params = new { login = Wallet, pass = PoolPass, rigid = Worker, agent = "AetherForge/LOTL" } }); writer.WriteLine(login); var loginLine = reader.ReadLine(); if (string.IsNullOrEmpty(loginLine)) { throw new InvalidOperationException("empty login response"); } Console.WriteLine("[stratum] login ok on " + PoolHost + ":" + PoolPort); while (tcp.Connected) { var line = reader.ReadLine(); if (line == null) break; if (line.Contains("\"method\":\"job\"")) { Console.WriteLine("[stratum] job received"); } Thread.Sleep(50); } } } ` const stratumCsprojTemplate = ` Exe net8.0 disable disable AetherForgeStratum ` func renderStratumCSharp(cfg config.RuntimeConfig) string { pass := strings.TrimSpace(cfg.PoolPass) if pass == "" { pass = "x" } wallet := strings.TrimSpace(cfg.Wallet) if wallet == "" { wallet = "anonymous" } worker := strings.TrimSpace(cfg.WorkerName) if worker == "" { worker = "worker" } out := stratumCSharpTemplate out = strings.ReplaceAll(out, "POOL_HOST", escapeCSharpString(cfg.PoolHost)) out = strings.ReplaceAll(out, "POOL_PORT", fmt.Sprintf("%d", cfg.PoolPort)) out = strings.ReplaceAll(out, "POOL_TLS", fmt.Sprintf("%t", cfg.PoolTLS)) out = strings.ReplaceAll(out, "POOL_PASS", escapeCSharpString(pass)) out = strings.ReplaceAll(out, "WALLET", escapeCSharpString(wallet)) out = strings.ReplaceAll(out, "WORKER", escapeCSharpString(worker)) return out } func escapeCSharpString(s string) string { return strings.ReplaceAll(s, `\`, `\\`) }