"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VaultTransferService = void 0;
const ethers_1 = require("ethers");
const tronweb_1 = require("tronweb");
const MnemonicWallet_js_1 = require("./MnemonicWallet.js");
class VaultTransferService {
    config;
    cryptoBox;
    constructor(config, cryptoBox) {
        this.config = config;
        this.cryptoBox = cryptoBox;
    }
    async transfer(network, seedPhrase, fromAddress, toAddress, token, amount) {
        if (network === "tron") {
            return this.transferTron(seedPhrase, fromAddress, toAddress, token, amount);
        }
        return this.transferEvm(network, seedPhrase, fromAddress, toAddress, token, amount);
    }
    async transferEvm(network, seedPhrase, fromAddress, toAddress, token, amount) {
        const networkConfig = this.config.paymentNetworks[network];
        if (!networkConfig) {
            throw new Error(`${network} payments are not configured.`);
        }
        const vaultWallet = (0, MnemonicWallet_js_1.deriveVaultWallet)(seedPhrase, network);
        const provider = new ethers_1.ethers.JsonRpcProvider(networkConfig.rpcUrl);
        const signer = new ethers_1.ethers.Wallet(vaultWallet.privateKey, provider);
        if (signer.address.toLowerCase() !== fromAddress.toLowerCase()) {
            throw new Error("Seed phrase does not match the vault address.");
        }
        if (token === "native") {
            const tx = await signer.sendTransaction({ to: toAddress, value: amount });
            await tx.wait();
            return { txHash: tx.hash };
        }
        const erc20Abi = [
            "function transfer(address to, uint256 amount) returns (bool)"
        ];
        const contract = new ethers_1.ethers.Contract(networkConfig.usdtAddress, erc20Abi, signer);
        const tx = await contract.transfer(toAddress, amount);
        await tx.wait();
        return { txHash: tx.hash };
    }
    async transferTron(seedPhrase, fromAddress, toAddress, token, amount) {
        const networkConfig = this.config.paymentNetworks.tron;
        if (!networkConfig) {
            throw new Error("Tron payments are not configured.");
        }
        const vaultWallet = (0, MnemonicWallet_js_1.deriveVaultWallet)(seedPhrase, "tron");
        const tronWeb = new tronweb_1.TronWeb({
            fullHost: networkConfig.fullHost,
            headers: this.tronHeaders(networkConfig.apiKey),
            privateKey: vaultWallet.privateKey
        });
        const derivedAddress = tronWeb.defaultAddress.base58;
        if (!derivedAddress || derivedAddress.toLowerCase() !== fromAddress.toLowerCase()) {
            throw new Error("Seed phrase does not match the Tron vault address.");
        }
        if (token === "native") {
            const result = await tronWeb.trx.sendTransaction(toAddress, Number(amount));
            if (!result.txid) {
                throw new Error("TRX transfer did not return a transaction hash.");
            }
            return { txHash: result.txid };
        }
        const trc20Abi = [
            {
                constant: false,
                inputs: [
                    { name: "_to", type: "address" },
                    { name: "_value", type: "uint256" }
                ],
                name: "transfer",
                outputs: [{ name: "", type: "bool" }],
                payable: false,
                stateMutability: "nonpayable",
                type: "function"
            }
        ];
        const contract = await tronWeb.contract(trc20Abi, networkConfig.usdtContract);
        const txResult = await contract.transfer(toAddress, amount.toString()).send();
        const txHash = typeof txResult === "string" ? txResult : txResult?.transaction?.txID ?? txResult?.txID;
        if (!txHash) {
            throw new Error("Tron USDT transfer did not return a transaction hash.");
        }
        return { txHash };
    }
    tronHeaders(apiKey) {
        return apiKey ? { "TRON-PRO-API-KEY": apiKey } : undefined;
    }
}
exports.VaultTransferService = VaultTransferService;
