Module jmwallet.wallet.models

Wallet data models.

Classes

class AddressInfo (*args: Any, **kwargs: Any)
Expand source code
@dataclass
class AddressInfo:
    """Information about a wallet address for display."""

    address: str
    index: int
    balance: int  # satoshis
    status: AddressStatus
    path: str
    is_external: bool  # True for receive (external), False for change (internal)
    is_bond: bool = False
    locktime: int | None = None  # For fidelity bond addresses
    has_unconfirmed: bool = False  # True if any UTXOs at this address are unconfirmed

    @property
    def short_path(self) -> str:
        """Get shortened path for display (e.g., m/84'/0'/0'/0/5 -> 0/5)."""
        parts = self.path.split("/")
        if len(parts) >= 2:
            return f"{parts[-2]}/{parts[-1]}"
        return self.path

Information about a wallet address for display.

Instance variables

var address : str

The type of the None singleton.

var balance : int

The type of the None singleton.

var has_unconfirmed : bool

The type of the None singleton.

var index : int

The type of the None singleton.

var is_bond : bool

The type of the None singleton.

var is_external : bool

The type of the None singleton.

var locktime : int | None

The type of the None singleton.

var path : str

The type of the None singleton.

prop short_path : str
Expand source code
@property
def short_path(self) -> str:
    """Get shortened path for display (e.g., m/84'/0'/0'/0/5 -> 0/5)."""
    parts = self.path.split("/")
    if len(parts) >= 2:
        return f"{parts[-2]}/{parts[-1]}"
    return self.path

Get shortened path for display (e.g., m/84'/0'/0'/0/5 -> 0/5).

var status : Literal['deposit', 'cj-out', 'non-cj-change', 'new', 'reused', 'used-empty', 'bond', 'flagged']

The type of the None singleton.

class CoinSelection (*args: Any, **kwargs: Any)
Expand source code
@dataclass
class CoinSelection:
    """Result of coin selection"""

    utxos: list[UTXOInfo]
    total_value: int
    change_value: int
    fee: int

Result of coin selection

Instance variables

var change_value : int

The type of the None singleton.

var fee : int

The type of the None singleton.

var total_value : int

The type of the None singleton.

var utxos : list[UTXOInfo]

The type of the None singleton.

class UTXOInfo (*args: Any, **kwargs: Any)
Expand source code
@dataclass
class UTXOInfo:
    """Extended UTXO information with wallet context"""

    txid: str
    vout: int
    value: int
    address: str
    confirmations: int
    scriptpubkey: str
    path: str
    mixdepth: int
    height: int | None = None  # Block height where UTXO was confirmed (for Neutrino)
    locktime: int | None = None  # Locktime for fidelity bond UTXOs (None for regular UTXOs)
    label: str | None = None  # Human-readable label/note (e.g., "cj-out", "deposit", "change")

    @property
    def is_timelocked(self) -> bool:
        """Check if this is a timelocked (fidelity bond) UTXO."""
        return self.locktime is not None

    @property
    def is_p2wsh(self) -> bool:
        """Check if this UTXO is P2WSH based on scriptpubkey."""
        # P2WSH scriptpubkey: OP_0 (0x00) + PUSH32 (0x20) + 32-byte hash = 34 bytes (68 hex chars)
        if len(self.scriptpubkey) != 68:
            return False
        return self.scriptpubkey.startswith("0020")

    @property
    def is_p2wpkh(self) -> bool:
        """Check if this UTXO is P2WPKH based on scriptpubkey."""
        # P2WPKH scriptpubkey: OP_0 (0x00) + PUSH20 (0x14) + 20-byte hash = 22 bytes (44 hex chars)
        if len(self.scriptpubkey) != 44:
            return False
        return self.scriptpubkey.startswith("0014")

Extended UTXO information with wallet context

Instance variables

var address : str

The type of the None singleton.

var confirmations : int

The type of the None singleton.

var height : int | None

The type of the None singleton.

prop is_p2wpkh : bool
Expand source code
@property
def is_p2wpkh(self) -> bool:
    """Check if this UTXO is P2WPKH based on scriptpubkey."""
    # P2WPKH scriptpubkey: OP_0 (0x00) + PUSH20 (0x14) + 20-byte hash = 22 bytes (44 hex chars)
    if len(self.scriptpubkey) != 44:
        return False
    return self.scriptpubkey.startswith("0014")

Check if this UTXO is P2WPKH based on scriptpubkey.

prop is_p2wsh : bool
Expand source code
@property
def is_p2wsh(self) -> bool:
    """Check if this UTXO is P2WSH based on scriptpubkey."""
    # P2WSH scriptpubkey: OP_0 (0x00) + PUSH32 (0x20) + 32-byte hash = 34 bytes (68 hex chars)
    if len(self.scriptpubkey) != 68:
        return False
    return self.scriptpubkey.startswith("0020")

Check if this UTXO is P2WSH based on scriptpubkey.

prop is_timelocked : bool
Expand source code
@property
def is_timelocked(self) -> bool:
    """Check if this is a timelocked (fidelity bond) UTXO."""
    return self.locktime is not None

Check if this is a timelocked (fidelity bond) UTXO.

var label : str | None

The type of the None singleton.

var locktime : int | None

The type of the None singleton.

var mixdepth : int

The type of the None singleton.

var path : str

The type of the None singleton.

var scriptpubkey : str

The type of the None singleton.

var txid : str

The type of the None singleton.

var value : int

The type of the None singleton.

var vout : int

The type of the None singleton.