/**
 * Wallet connection and transaction execution utilities
 *
 * Supports two modes:
 * 1. Reown AppKit - unified wallet modal (when reownProjectId is provided)
 * 2. Legacy - direct ethers.js + solana-connect (fallback)
 */
import { ethers } from "ethers";
import { SolanaConnect } from "solana-connect";
import { Connection, VersionedTransaction } from "@solana/web3.js";
import { Buffer } from "buffer";
import { getRPC } from "../chains";
import { NETWORK_SWITCH_DELAY } from "./constants";
import { initReown, isReownInitialized, openReownModal, disconnectReown, getReownAddress, getReownEvmProvider, getReownSolanaProvider, switchReownChain, onReownWalletChange, cleanupReown, } from "./reown";
// Track which mode is active
let useReownMode = false;
// Global Solana connection instance (for legacy mode)
const solConnect = new SolanaConnect();
/**
 * Initialize wallet system
 * If reownProjectId is provided, uses Reown AppKit; otherwise uses legacy mode
 */
export async function initWallet(reownProjectId, options) {
    if (reownProjectId) {
        useReownMode = true;
        await initReown(reownProjectId, options);
    }
    else {
        useReownMode = false;
    }
}
/**
 * Check if using Reown mode
 */
export function isUsingReown() {
    return useReownMode && isReownInitialized();
}
/**
 * Gets the current Solana wallet adapter (legacy mode only)
 */
export function getSolanaWallet() {
    return solConnect.getWallet();
}
/**
 * Sets up a listener for wallet changes (works in both modes)
 */
export function onWalletChange(callback) {
    if (useReownMode) {
        onReownWalletChange(callback);
    }
    else {
        // Legacy mode - listen to both EVM and Solana
        solConnect.onWalletChange((adapter) => {
            callback(adapter?.publicKey?.toString() || null);
        });
    }
}
/**
 * Gets the current connected wallet address (works in both modes)
 */
export function getWalletAddress() {
    if (useReownMode) {
        return getReownAddress();
    }
    else {
        // Legacy mode - check Solana wallet
        const adapter = solConnect.getWallet();
        return adapter?.publicKey?.toString() || null;
    }
}
/**
 * Sets up a listener for Solana wallet changes (legacy mode)
 * @deprecated Use onWalletChange instead
 */
export function onSolanaWalletChange(callback) {
    if (!useReownMode) {
        solConnect.onWalletChange(callback);
    }
}
/**
 * Opens the wallet connection modal
 * In Reown mode, opens the unified modal
 * In legacy mode, opens Solana menu for SVM or connects directly for EVM
 */
export function openWalletModal() {
    if (useReownMode) {
        openReownModal();
    }
    else {
        // Legacy mode - this is called for Solana, EVM uses direct connect
        solConnect.openMenu();
    }
}
/**
 * Opens the Solana wallet connection menu (legacy mode)
 * @deprecated Use openWalletModal instead
 */
export function openSolanaWalletMenu() {
    if (useReownMode) {
        openReownModal();
    }
    else {
        solConnect.openMenu();
    }
}
/**
 * Connects wallet and returns address
 * In Reown mode, opens the modal and returns when connected
 * In legacy mode, connects via window.ethereum for EVM
 */
export async function connectWallet(runtime) {
    if (useReownMode) {
        openReownModal();
        // Address will come via subscription callback
        // Return empty string - actual address comes from state update
        return getReownAddress() || "";
    }
    // Legacy mode
    if (runtime === "svm") {
        openSolanaWalletMenu();
        return ""; // Address comes via callback
    }
    // EVM legacy
    return connectEvmWallet();
}
/**
 * Connects to an EVM wallet (MetaMask) - legacy mode
 */
export async function connectEvmWallet() {
    if (useReownMode) {
        openReownModal();
        return getReownAddress() || "";
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const ethereum = window.ethereum;
    if (!ethereum) {
        throw new Error("No Ethereum wallet found");
    }
    const provider = new ethers.BrowserProvider(ethereum);
    const signer = await provider.getSigner();
    return await signer.getAddress();
}
/**
 * Disconnects the wallet
 */
export async function disconnectWallet() {
    if (useReownMode) {
        await disconnectReown();
    }
    else {
        disconnectEvmWallet();
    }
}
/**
 * Disconnects the EVM wallet (legacy mode)
 */
export function disconnectEvmWallet() {
    if (useReownMode) {
        disconnectReown();
        return;
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const ethereum = window.ethereum;
    if (ethereum) {
        ethereum.selectedAddress = null;
    }
}
/**
 * Switches to a specific EVM chain
 */
export async function switchEvmChain(chainId) {
    if (useReownMode) {
        await switchReownChain(chainId);
        return;
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const ethereum = window.ethereum;
    if (!ethereum) {
        throw new Error("No Ethereum wallet found");
    }
    try {
        await ethereum.request({
            method: "wallet_switchEthereumChain",
            params: [{ chainId: `0x${chainId.toString(16)}` }],
        });
        // Wait for the network switch to complete
        await new Promise((resolve) => setTimeout(resolve, NETWORK_SWITCH_DELAY));
    }
    catch (error) {
        if (error.code === 4902) {
            throw new Error(`Please add chain ${chainId} to your wallet first.`);
        }
        throw error;
    }
}
/**
 * Executes an EVM transaction
 */
export async function executeEvmTransaction(txData) {
    if (useReownMode) {
        return executeEvmTransactionReown(txData);
    }
    // Legacy mode
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const ethereum = window.ethereum;
    const provider = new ethers.BrowserProvider(ethereum);
    const network = await provider.getNetwork();
    const currentChainId = Number(network.chainId);
    const targetChainId = Number(txData.chainId);
    // Switch network if needed
    if (currentChainId !== targetChainId) {
        await switchEvmChain(targetChainId);
    }
    const signer = await provider.getSigner();
    const txResponse = await signer.sendTransaction({
        data: txData.data,
        to: txData.to,
        value: txData.value,
    });
    return txResponse.hash;
}
/**
 * Executes an EVM transaction using Reown provider
 */
async function executeEvmTransactionReown(txData) {
    const evmProvider = await getReownEvmProvider();
    if (!evmProvider) {
        throw new Error("No EVM provider available");
    }
    const targetChainId = Number(txData.chainId);
    // Switch network if needed
    await switchReownChain(targetChainId);
    const provider = new ethers.BrowserProvider(evmProvider);
    const signer = await provider.getSigner();
    const txResponse = await signer.sendTransaction({
        data: txData.data,
        to: txData.to,
        value: txData.value,
    });
    return txResponse.hash;
}
/**
 * Executes a Solana transaction
 */
export async function executeSolanaTransaction(txData, rpcOverrides) {
    if (useReownMode) {
        return executeSolanaTransactionReown(txData, rpcOverrides);
    }
    // Legacy mode
    const wallet = getSolanaWallet();
    if (!wallet) {
        throw new Error("No Solana wallet connected");
    }
    const txnBytes = Buffer.from(txData.transaction, "base64");
    const txn = VersionedTransaction.deserialize(txnBytes);
    const rpc = getRPC(txData.chain, rpcOverrides);
    const connection = new Connection(rpc);
    const signature = await wallet.sendTransaction(txn, connection);
    return signature;
}
/**
 * Executes a Solana transaction using Reown provider
 */
async function executeSolanaTransactionReown(txData, rpcOverrides) {
    const solanaProvider = await getReownSolanaProvider();
    if (!solanaProvider) {
        throw new Error("No Solana provider available - Reown not initialized");
    }
    const txnBytes = Buffer.from(txData.transaction, "base64");
    const txn = VersionedTransaction.deserialize(txnBytes);
    const rpc = getRPC(txData.chain, rpcOverrides);
    const connection = new Connection(rpc);
    // Use the Reown provider's sendTransaction method
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const signature = await solanaProvider.sendTransaction(txn, connection);
    return signature;
}
/**
 * Cleanup wallet resources
 */
export function cleanupWallet() {
    if (useReownMode) {
        cleanupReown();
    }
    useReownMode = false;
}
//# sourceMappingURL=wallet.js.map
