"""Transaction signing utilities using eth-account.

Handles nonce management, gas estimation, EIP-1559 fee parameters, and
local signing so that private keys never leave the process.
"""

from __future__ import annotations

from typing import Any, Dict, Optional

from eth_account import Account
from eth_account.signers.local import LocalAccount


def get_account(private_key: str) -> LocalAccount:
    """Derive an ``eth_account`` signer from a hex private key."""
    return Account.from_key(private_key)


def build_transaction(
    *,
    to: str,
    data: str,
    chain_id: int,
    nonce: int,
    gas: int = 300_000,
    max_fee_per_gas: Optional[int] = None,
    max_priority_fee_per_gas: Optional[int] = None,
    value: int = 0,
) -> Dict[str, Any]:
    """Build an unsigned EIP-1559 transaction dict."""
    tx: Dict[str, Any] = {
        "to": to,
        "data": data,
        "chainId": chain_id,
        "nonce": nonce,
        "gas": gas,
        "value": value,
        "type": 2,  # EIP-1559
    }
    if max_fee_per_gas is not None:
        tx["maxFeePerGas"] = max_fee_per_gas
    else:
        # sensible default for Base L2
        tx["maxFeePerGas"] = 1_500_000_000  # 1.5 Gwei
    if max_priority_fee_per_gas is not None:
        tx["maxPriorityFeePerGas"] = max_priority_fee_per_gas
    else:
        tx["maxPriorityFeePerGas"] = 1_500_000_000  # 1.5 Gwei
    return tx


def sign_transaction(tx: Dict[str, Any], private_key: str) -> str:
    """Sign *tx* and return the raw transaction hex (``0x``-prefixed)."""
    signed = Account.sign_transaction(tx, private_key)
    return "0x" + signed.raw_transaction.hex()
    # eth-account >=0.10 returns .raw_transaction; older returns .rawTransaction
