Эх сурвалжийг харах

feat: create user with company now creates a wallet for the company, and saves the pubkey, privkey and adress on to the database

EduLascala 1 сар өмнө
parent
commit
ed674275e8

+ 3 - 0
src/main/java/com/platform2easy/genesis/domain/model/Wallet.java

@@ -36,6 +36,9 @@ public class Wallet {
     @Column(name = "wallet_private_key", nullable = false)
     private String privateKey;
 
+    @Column(name = "wallet_address", nullable = false)
+    private String address;
+
     @Column(name = "wallet_flag", nullable = false)
     private String flag;
 

+ 56 - 2
src/main/java/com/platform2easy/genesis/domain/service/CompanyService.java

@@ -2,23 +2,40 @@ package com.platform2easy.genesis.domain.service;
 
 import com.platform2easy.genesis.domain.model.AppUser;
 import com.platform2easy.genesis.domain.model.Company;
+import com.platform2easy.genesis.domain.model.Wallet;
 import com.platform2easy.genesis.domain.repository.AppUserRepository;
 import com.platform2easy.genesis.domain.repository.CompanyRepository;
+import com.platform2easy.genesis.domain.service.WalletService;
 import com.platform2easy.genesis.web.dto.CompanyWithUserDTO;
-import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
+import com.platform2easy.genesis.lib.BashExecutor;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.nio.file.Paths;
 import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
 
 @Service
-@AllArgsConstructor
+@RequiredArgsConstructor
 public class CompanyService {
 
     private final CompanyRepository repository;
     private final AppUserRepository userRepository;
     private final PasswordEncoder passwordEncoder;
+    private final WalletService walletService;
+
+    @Value("${easycli.path:}")
+    private String easycliPath;
+
+    @Value("${chain.polygon.id:137}")
+    private Long defaultChainId;
+
+    @Value("${ROOT_DIR:}")
+    private String rootDir;
 
     @Transactional
     public Company salvar(Company company) {
@@ -63,6 +80,43 @@ public class CompanyService {
         user.setUserFlag("a");
         userRepository.save(user);
 
+        String root = (rootDir == null || rootDir.isBlank()) ? System.getenv("ROOT_DIR") : rootDir;
+        String cliFullPath = (root != null && !root.isBlank())
+                ? Paths.get(root).resolve("bin").resolve("easycli").toString()
+                : ((easycliPath == null || easycliPath.isBlank())
+                    ? Paths.get("").toAbsolutePath().resolve("bin").resolve("easycli").toString()
+                    : easycliPath);
+        String command = cliFullPath + " polygon create-new-address";
+        BashExecutor.Result result = BashExecutor.run(command, 15000);
+        if (result.isTimedOut() || result.getExitCode() != 0) {
+            throw new RuntimeException("Falha ao gerar nova address via CLI: " + result.getOutput());
+        }
+
+        Map<String, String> kv = new HashMap<>();
+        for (String line : result.getOutput().split("\\R")) {
+            int i = line.indexOf('=');
+            if (i > 0) {
+                String k = line.substring(0, i).trim();
+                String v = line.substring(i + 1).trim();
+                kv.put(k, v);
+            }
+        }
+        String privateKey = kv.get("privateKey");
+        String publicKey = kv.get("publicKey");
+        String address = kv.get("address");
+        if (privateKey == null || publicKey == null || address == null) {
+            throw new RuntimeException("Saída da CLI inválida: " + result.getOutput());
+        }
+
+        Wallet wallet = new Wallet();
+        wallet.setCompanyId(company.getId());
+        wallet.setAddress(address);
+        wallet.setPublicKey(publicKey);
+        wallet.setPrivateKey(privateKey);
+        wallet.setFlag("a");
+        wallet.setChainId(defaultChainId);
+        walletService.salvar(wallet);
+
         return company;
     }
 }

+ 82 - 0
src/main/java/com/platform2easy/genesis/lib/BashExecutor.java

@@ -0,0 +1,82 @@
+package com.platform2easy.genesis.lib;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.concurrent.TimeUnit;
+
+public class BashExecutor {
+
+    public static Result run(String command, long timeoutMs) {
+        StringBuilder output = new StringBuilder();
+        int exitCode = -1;
+        boolean timedOut = false;
+
+        try {
+            ProcessBuilder processBuilder = new ProcessBuilder("bash", "-c", command);
+            processBuilder.redirectErrorStream(true);
+            Process process = processBuilder.start();
+            
+            // Read output in a separate thread
+            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            Thread readerThread = new Thread(() -> {
+                try { 
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        output.append(line).append("\n");
+                    }
+                } catch (IOException e) {
+                    output.append("Error reading output: ").append(e.getMessage());
+                }
+            });
+            readerThread.start();
+
+            // Wait for the process to complete or timeout
+            if (!process.waitFor(timeoutMs, TimeUnit.MILLISECONDS)) {
+                // Timeout occurred
+                process.destroyForcibly();
+                timedOut = true;
+                output.append("\nCommand timed out after ").append(timeoutMs).append("ms");
+            }
+
+            // Wait for reader thread to finish
+            readerThread.join(1000);
+            
+            if (!timedOut) {
+                exitCode = process.exitValue();
+            }
+
+        } catch (IOException | InterruptedException e) {
+            output.append("Error executing command: ").append(e.getMessage());
+        }
+
+        return new Result(output.toString().trim(), exitCode, timedOut);
+    }
+
+    /**
+     * Result container for command execution.
+     */
+    public static class Result {
+        private final String output;
+        private final int exitCode;
+        private final boolean timedOut;
+
+        public Result(String output, int exitCode, boolean timedOut) {
+            this.output = output;
+            this.exitCode = exitCode;
+            this.timedOut = timedOut;
+        }
+
+        public String getOutput() {
+            return output;
+        }
+
+        public int getExitCode() {
+            return exitCode;
+        }
+
+        public boolean isTimedOut() {
+            return timedOut;
+        }
+    }
+}

+ 11 - 0
src/test/java/com/platform2easy/genesis/lib/TestBashExecutor.java

@@ -0,0 +1,11 @@
+package com.platform2easy.genesis.lib;
+
+public class TestBashExecutor {
+    public static void main(String[] args) {
+        BashExecutor.Result result = BashExecutor.run("/home/uriri/Projetos/tooeasy/backend/too-easy-genesis/bin/easycli polygon get-new-address", 5000);
+
+        System.out.println("Saída:\n" + result.getOutput());
+        System.out.println("\nCódigo de saída: " + result.getExitCode());
+        System.out.println("Timeout atingido: " + result.isTimedOut());
+    }
+}