Module jmcore.models

Core data models using Pydantic for validation and serialization.

Functions

def get_default_directory_nodes(network: NetworkType) ‑> list[str]
Expand source code
def get_default_directory_nodes(network: NetworkType) -> list[str]:
    """Get default directory nodes for a given network."""
    if network == NetworkType.MAINNET:
        return DIRECTORY_NODES_MAINNET.copy()
    elif network == NetworkType.SIGNET:
        return DIRECTORY_NODES_SIGNET.copy()
    elif network == NetworkType.TESTNET:
        return DIRECTORY_NODES_TESTNET.copy()
    # Regtest has no default directory nodes - must be configured
    return []

Get default directory nodes for a given network.

def validate_json_nesting_depth(obj: Any, max_depth: int = 10, current_depth: int = 0) ‑> None
Expand source code
def validate_json_nesting_depth(obj: Any, max_depth: int = 10, current_depth: int = 0) -> None:
    """
    Validate that a JSON object does not exceed maximum nesting depth.

    Args:
        obj: The object to validate (dict, list, or primitive)
        max_depth: Maximum allowed nesting depth
        current_depth: Current depth in recursion

    Raises:
        MessageParsingError: If nesting depth exceeds max_depth
    """
    if current_depth > max_depth:
        raise MessageParsingError(f"JSON nesting depth exceeds maximum of {max_depth}")

    if isinstance(obj, dict):
        for value in obj.values():
            validate_json_nesting_depth(value, max_depth, current_depth + 1)
    elif isinstance(obj, list):
        for item in obj:
            validate_json_nesting_depth(item, max_depth, current_depth + 1)

Validate that a JSON object does not exceed maximum nesting depth.

Args

obj
The object to validate (dict, list, or primitive)
max_depth
Maximum allowed nesting depth
current_depth
Current depth in recursion

Raises

MessageParsingError
If nesting depth exceeds max_depth

Classes

class FidelityBond (**data: Any)
Expand source code
class FidelityBond(BaseModel):
    counterparty: str
    utxo_txid: str = Field(..., pattern=r"^[0-9a-fA-F]{64}$")
    utxo_vout: int = Field(..., ge=0)
    bond_value: int | None = Field(default=None, ge=0)
    locktime: int = Field(..., ge=0)
    amount: int = Field(default=0, ge=0)
    script: str
    utxo_confirmations: int = Field(..., ge=0)
    utxo_confirmation_timestamp: int = Field(default=0, ge=0)
    cert_expiry: int = Field(..., ge=0)
    directory_node: str | None = None
    fidelity_bond_data: dict[str, Any] | None = None

Usage Documentation

Models

A base class for creating Pydantic models.

Attributes

__class_vars__
The names of the class variables defined on the model.
__private_attributes__
Metadata about the private attributes of the model.
__signature__
The synthesized __init__ [Signature][inspect.Signature] of the model.
__pydantic_complete__
Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__
The core schema of the model.
__pydantic_custom_init__
Whether the model has a custom __init__ function.
__pydantic_decorators__
Metadata containing the decorators defined on the model. This replaces Model.__validators__ and Model.__root_validators__ from Pydantic V1.
__pydantic_generic_metadata__
Metadata for generic models; contains data used for a similar purpose to args, origin, parameters in typing-module generics. May eventually be replaced by these.
__pydantic_parent_namespace__
Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__
The name of the post-init method for the model, if defined.
__pydantic_root_model__
Whether the model is a [RootModel][pydantic.root_model.RootModel].
__pydantic_serializer__
The pydantic-core SchemaSerializer used to dump instances of the model.
__pydantic_validator__
The pydantic-core SchemaValidator used to validate instances of the model.
__pydantic_fields__
A dictionary of field names and their corresponding [FieldInfo][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__
A dictionary of computed field names and their corresponding [ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects.
__pydantic_extra__
A dictionary containing extra values, if [extra][pydantic.config.ConfigDict.extra] is set to 'allow'.
__pydantic_fields_set__
The names of fields explicitly set during instantiation.
__pydantic_private__
Values of private attributes set on the model instance.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.main.BaseModel

Class variables

var amount : int

The type of the None singleton.

var bond_value : int | None

The type of the None singleton.

var cert_expiry : int

The type of the None singleton.

var counterparty : str

The type of the None singleton.

var directory_node : str | None

The type of the None singleton.

var fidelity_bond_data : dict[str, typing.Any] | None

The type of the None singleton.

var locktime : int

The type of the None singleton.

var model_config

The type of the None singleton.

var script : str

The type of the None singleton.

var utxo_confirmation_timestamp : int

The type of the None singleton.

var utxo_confirmations : int

The type of the None singleton.

var utxo_txid : str

The type of the None singleton.

var utxo_vout : int

The type of the None singleton.

class HandshakeRequest (**data: Any)
Expand source code
class HandshakeRequest(BaseModel):
    app_name: str = "JoinMarket"
    directory: bool = False
    location_string: str
    proto_ver: int
    features: dict[str, Any] = Field(default_factory=dict)
    nick: str = Field(..., min_length=1)
    network: NetworkType

Usage Documentation

Models

A base class for creating Pydantic models.

Attributes

__class_vars__
The names of the class variables defined on the model.
__private_attributes__
Metadata about the private attributes of the model.
__signature__
The synthesized __init__ [Signature][inspect.Signature] of the model.
__pydantic_complete__
Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__
The core schema of the model.
__pydantic_custom_init__
Whether the model has a custom __init__ function.
__pydantic_decorators__
Metadata containing the decorators defined on the model. This replaces Model.__validators__ and Model.__root_validators__ from Pydantic V1.
__pydantic_generic_metadata__
Metadata for generic models; contains data used for a similar purpose to args, origin, parameters in typing-module generics. May eventually be replaced by these.
__pydantic_parent_namespace__
Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__
The name of the post-init method for the model, if defined.
__pydantic_root_model__
Whether the model is a [RootModel][pydantic.root_model.RootModel].
__pydantic_serializer__
The pydantic-core SchemaSerializer used to dump instances of the model.
__pydantic_validator__
The pydantic-core SchemaValidator used to validate instances of the model.
__pydantic_fields__
A dictionary of field names and their corresponding [FieldInfo][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__
A dictionary of computed field names and their corresponding [ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects.
__pydantic_extra__
A dictionary containing extra values, if [extra][pydantic.config.ConfigDict.extra] is set to 'allow'.
__pydantic_fields_set__
The names of fields explicitly set during instantiation.
__pydantic_private__
Values of private attributes set on the model instance.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.main.BaseModel

Class variables

var app_name : str

The type of the None singleton.

var directory : bool

The type of the None singleton.

var features : dict[str, typing.Any]

The type of the None singleton.

var location_string : str

The type of the None singleton.

var model_config

The type of the None singleton.

var networkNetworkType

The type of the None singleton.

var nick : str

The type of the None singleton.

var proto_ver : int

The type of the None singleton.

class HandshakeResponse (**data: Any)
Expand source code
class HandshakeResponse(BaseModel):
    app_name: str = "JoinMarket"
    directory: bool = True
    proto_ver_min: int
    proto_ver_max: int
    features: dict[str, Any] = Field(default_factory=dict)
    accepted: bool
    nick: str = Field(..., min_length=1)
    network: NetworkType
    motd: str = "JoinMarket Directory Server"

Usage Documentation

Models

A base class for creating Pydantic models.

Attributes

__class_vars__
The names of the class variables defined on the model.
__private_attributes__
Metadata about the private attributes of the model.
__signature__
The synthesized __init__ [Signature][inspect.Signature] of the model.
__pydantic_complete__
Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__
The core schema of the model.
__pydantic_custom_init__
Whether the model has a custom __init__ function.
__pydantic_decorators__
Metadata containing the decorators defined on the model. This replaces Model.__validators__ and Model.__root_validators__ from Pydantic V1.
__pydantic_generic_metadata__
Metadata for generic models; contains data used for a similar purpose to args, origin, parameters in typing-module generics. May eventually be replaced by these.
__pydantic_parent_namespace__
Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__
The name of the post-init method for the model, if defined.
__pydantic_root_model__
Whether the model is a [RootModel][pydantic.root_model.RootModel].
__pydantic_serializer__
The pydantic-core SchemaSerializer used to dump instances of the model.
__pydantic_validator__
The pydantic-core SchemaValidator used to validate instances of the model.
__pydantic_fields__
A dictionary of field names and their corresponding [FieldInfo][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__
A dictionary of computed field names and their corresponding [ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects.
__pydantic_extra__
A dictionary containing extra values, if [extra][pydantic.config.ConfigDict.extra] is set to 'allow'.
__pydantic_fields_set__
The names of fields explicitly set during instantiation.
__pydantic_private__
Values of private attributes set on the model instance.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.main.BaseModel

Class variables

var accepted : bool

The type of the None singleton.

var app_name : str

The type of the None singleton.

var directory : bool

The type of the None singleton.

var features : dict[str, typing.Any]

The type of the None singleton.

var model_config

The type of the None singleton.

var motd : str

The type of the None singleton.

var networkNetworkType

The type of the None singleton.

var nick : str

The type of the None singleton.

var proto_ver_max : int

The type of the None singleton.

var proto_ver_min : int

The type of the None singleton.

class MessageEnvelope (**data: Any)
Expand source code
class MessageEnvelope(BaseModel):
    message_type: int = Field(..., ge=0)
    payload: str
    timestamp: datetime = Field(default_factory=lambda: datetime.now(UTC))

    def to_bytes(self) -> bytes:
        import json

        result = json.dumps({"type": self.message_type, "line": self.payload}).encode("utf-8")
        return result

    @classmethod
    def from_bytes(
        cls, data: bytes, max_line_length: int = 65536, max_json_nesting_depth: int = 10
    ) -> MessageEnvelope:
        """
        Parse a message envelope from bytes with security limits.

        Args:
            data: Raw message bytes (without \\r\\n terminator)
            max_line_length: Maximum allowed line length in bytes (default 64KB)
            max_json_nesting_depth: Maximum JSON nesting depth (default 10)

        Returns:
            Parsed MessageEnvelope

        Raises:
            MessageParsingError: If message exceeds security limits
            json.JSONDecodeError: If JSON is malformed
        """
        import json

        # Check line length BEFORE parsing to prevent DoS
        if len(data) > max_line_length:
            raise MessageParsingError(
                f"Message line length {len(data)} exceeds maximum of {max_line_length} bytes"
            )

        # Parse JSON
        obj = json.loads(data)

        # Validate nesting depth BEFORE creating model
        validate_json_nesting_depth(obj, max_json_nesting_depth)

        return cls(message_type=obj["type"], payload=obj["line"])

Usage Documentation

Models

A base class for creating Pydantic models.

Attributes

__class_vars__
The names of the class variables defined on the model.
__private_attributes__
Metadata about the private attributes of the model.
__signature__
The synthesized __init__ [Signature][inspect.Signature] of the model.
__pydantic_complete__
Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__
The core schema of the model.
__pydantic_custom_init__
Whether the model has a custom __init__ function.
__pydantic_decorators__
Metadata containing the decorators defined on the model. This replaces Model.__validators__ and Model.__root_validators__ from Pydantic V1.
__pydantic_generic_metadata__
Metadata for generic models; contains data used for a similar purpose to args, origin, parameters in typing-module generics. May eventually be replaced by these.
__pydantic_parent_namespace__
Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__
The name of the post-init method for the model, if defined.
__pydantic_root_model__
Whether the model is a [RootModel][pydantic.root_model.RootModel].
__pydantic_serializer__
The pydantic-core SchemaSerializer used to dump instances of the model.
__pydantic_validator__
The pydantic-core SchemaValidator used to validate instances of the model.
__pydantic_fields__
A dictionary of field names and their corresponding [FieldInfo][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__
A dictionary of computed field names and their corresponding [ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects.
__pydantic_extra__
A dictionary containing extra values, if [extra][pydantic.config.ConfigDict.extra] is set to 'allow'.
__pydantic_fields_set__
The names of fields explicitly set during instantiation.
__pydantic_private__
Values of private attributes set on the model instance.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.main.BaseModel

Class variables

var message_type : int

The type of the None singleton.

var model_config

The type of the None singleton.

var payload : str

The type of the None singleton.

var timestamp : datetime.datetime

The type of the None singleton.

Static methods

def from_bytes(data: bytes, max_line_length: int = 65536, max_json_nesting_depth: int = 10) ‑> MessageEnvelope

Parse a message envelope from bytes with security limits.

Args

data
Raw message bytes (without \r\n terminator)
max_line_length
Maximum allowed line length in bytes (default 64KB)
max_json_nesting_depth
Maximum JSON nesting depth (default 10)

Returns

Parsed MessageEnvelope

Raises

MessageParsingError
If message exceeds security limits
json.JSONDecodeError
If JSON is malformed

Methods

def to_bytes(self) ‑> bytes
Expand source code
def to_bytes(self) -> bytes:
    import json

    result = json.dumps({"type": self.message_type, "line": self.payload}).encode("utf-8")
    return result
class MessageParsingError (*args, **kwargs)
Expand source code
class MessageParsingError(Exception):
    """Exception raised when message parsing fails due to security limits."""

    pass

Exception raised when message parsing fails due to security limits.

Ancestors

  • builtins.Exception
  • builtins.BaseException
class NetworkType (*values)
Expand source code
class NetworkType(str, Enum):
    MAINNET = "mainnet"
    TESTNET = "testnet"
    SIGNET = "signet"
    REGTEST = "regtest"

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Ancestors

  • builtins.str
  • enum.Enum

Class variables

var MAINNET

The type of the None singleton.

var REGTEST

The type of the None singleton.

var SIGNET

The type of the None singleton.

var TESTNET

The type of the None singleton.

class Offer (**data: Any)
Expand source code
class Offer(BaseModel):
    counterparty: str = Field(..., min_length=1)
    oid: int = Field(..., ge=0)
    ordertype: OfferType
    minsize: int = Field(..., ge=0)
    maxsize: int = Field(..., ge=0)
    txfee: int = Field(..., ge=0)
    cjfee: str | int
    fidelity_bond_value: int = Field(default=0, ge=0)
    directory_node: str | None = None
    fidelity_bond_data: dict[str, Any] | None = None
    neutrino_compat: bool = Field(
        default=False,
        description="Maker requires extended UTXO format (neutrino-compatible backend)",
    )
    features: dict[str, bool] = Field(
        default_factory=dict,
        description="Features supported by this maker (from handshake)",
    )

    @field_validator("cjfee")
    @classmethod
    def validate_cjfee(cls, v: str | int, info) -> str | int:
        ordertype = info.data.get("ordertype")
        if ordertype in (OfferType.SW0_ABSOLUTE, OfferType.SWA_ABSOLUTE):
            return int(v)
        return str(v)

    def is_absolute_fee(self) -> bool:
        return self.ordertype in (OfferType.SW0_ABSOLUTE, OfferType.SWA_ABSOLUTE)

    def calculate_fee(self, amount: int) -> int:
        if self.is_absolute_fee():
            return int(self.cjfee)
        else:
            # cjfee is guaranteed to be str for relative fee types by validation
            return calculate_relative_fee(amount, str(self.cjfee))

Usage Documentation

Models

A base class for creating Pydantic models.

Attributes

__class_vars__
The names of the class variables defined on the model.
__private_attributes__
Metadata about the private attributes of the model.
__signature__
The synthesized __init__ [Signature][inspect.Signature] of the model.
__pydantic_complete__
Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__
The core schema of the model.
__pydantic_custom_init__
Whether the model has a custom __init__ function.
__pydantic_decorators__
Metadata containing the decorators defined on the model. This replaces Model.__validators__ and Model.__root_validators__ from Pydantic V1.
__pydantic_generic_metadata__
Metadata for generic models; contains data used for a similar purpose to args, origin, parameters in typing-module generics. May eventually be replaced by these.
__pydantic_parent_namespace__
Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__
The name of the post-init method for the model, if defined.
__pydantic_root_model__
Whether the model is a [RootModel][pydantic.root_model.RootModel].
__pydantic_serializer__
The pydantic-core SchemaSerializer used to dump instances of the model.
__pydantic_validator__
The pydantic-core SchemaValidator used to validate instances of the model.
__pydantic_fields__
A dictionary of field names and their corresponding [FieldInfo][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__
A dictionary of computed field names and their corresponding [ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects.
__pydantic_extra__
A dictionary containing extra values, if [extra][pydantic.config.ConfigDict.extra] is set to 'allow'.
__pydantic_fields_set__
The names of fields explicitly set during instantiation.
__pydantic_private__
Values of private attributes set on the model instance.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.main.BaseModel

Class variables

var cjfee : str | int

The type of the None singleton.

var counterparty : str

The type of the None singleton.

var directory_node : str | None

The type of the None singleton.

var features : dict[str, bool]

The type of the None singleton.

var fidelity_bond_data : dict[str, typing.Any] | None

The type of the None singleton.

var fidelity_bond_value : int

The type of the None singleton.

var maxsize : int

The type of the None singleton.

var minsize : int

The type of the None singleton.

var model_config

The type of the None singleton.

var neutrino_compat : bool

The type of the None singleton.

var oid : int

The type of the None singleton.

var ordertypeOfferType

The type of the None singleton.

var txfee : int

The type of the None singleton.

Static methods

def validate_cjfee(v: str | int, info) ‑> str | int

Methods

def calculate_fee(self, amount: int) ‑> int
Expand source code
def calculate_fee(self, amount: int) -> int:
    if self.is_absolute_fee():
        return int(self.cjfee)
    else:
        # cjfee is guaranteed to be str for relative fee types by validation
        return calculate_relative_fee(amount, str(self.cjfee))
def is_absolute_fee(self) ‑> bool
Expand source code
def is_absolute_fee(self) -> bool:
    return self.ordertype in (OfferType.SW0_ABSOLUTE, OfferType.SWA_ABSOLUTE)
class OfferType (*values)
Expand source code
class OfferType(str, Enum):
    SW0_ABSOLUTE = "sw0absoffer"
    SW0_RELATIVE = "sw0reloffer"
    SWA_ABSOLUTE = "swabsoffer"
    SWA_RELATIVE = "swreloffer"

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Ancestors

  • builtins.str
  • enum.Enum

Class variables

var SW0_ABSOLUTE

The type of the None singleton.

var SW0_RELATIVE

The type of the None singleton.

var SWA_ABSOLUTE

The type of the None singleton.

var SWA_RELATIVE

The type of the None singleton.

class OrderBook (**data: Any)
Expand source code
class OrderBook(BaseModel):
    offers: list[Offer] = Field(default_factory=list)
    fidelity_bonds: list[FidelityBond] = Field(default_factory=list)
    timestamp: datetime = Field(default_factory=datetime.utcnow)
    directory_nodes: list[str] = Field(default_factory=list)

    def add_offers(self, offers: list[Offer], directory_node: str) -> None:
        for offer in offers:
            offer.directory_node = directory_node
        self.offers.extend(offers)
        if directory_node not in self.directory_nodes:
            self.directory_nodes.append(directory_node)

    def add_fidelity_bonds(self, bonds: list[FidelityBond], directory_node: str) -> None:
        for bond in bonds:
            bond.directory_node = directory_node
        self.fidelity_bonds.extend(bonds)

    def get_offers_by_directory(self) -> dict[str, list[Offer]]:
        result: dict[str, list[Offer]] = {}
        for offer in self.offers:
            node = offer.directory_node or "unknown"
            if node not in result:
                result[node] = []
            result[node].append(offer)
        return result

Usage Documentation

Models

A base class for creating Pydantic models.

Attributes

__class_vars__
The names of the class variables defined on the model.
__private_attributes__
Metadata about the private attributes of the model.
__signature__
The synthesized __init__ [Signature][inspect.Signature] of the model.
__pydantic_complete__
Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__
The core schema of the model.
__pydantic_custom_init__
Whether the model has a custom __init__ function.
__pydantic_decorators__
Metadata containing the decorators defined on the model. This replaces Model.__validators__ and Model.__root_validators__ from Pydantic V1.
__pydantic_generic_metadata__
Metadata for generic models; contains data used for a similar purpose to args, origin, parameters in typing-module generics. May eventually be replaced by these.
__pydantic_parent_namespace__
Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__
The name of the post-init method for the model, if defined.
__pydantic_root_model__
Whether the model is a [RootModel][pydantic.root_model.RootModel].
__pydantic_serializer__
The pydantic-core SchemaSerializer used to dump instances of the model.
__pydantic_validator__
The pydantic-core SchemaValidator used to validate instances of the model.
__pydantic_fields__
A dictionary of field names and their corresponding [FieldInfo][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__
A dictionary of computed field names and their corresponding [ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects.
__pydantic_extra__
A dictionary containing extra values, if [extra][pydantic.config.ConfigDict.extra] is set to 'allow'.
__pydantic_fields_set__
The names of fields explicitly set during instantiation.
__pydantic_private__
Values of private attributes set on the model instance.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.main.BaseModel

Class variables

var directory_nodes : list[str]

The type of the None singleton.

var fidelity_bonds : list[FidelityBond]

The type of the None singleton.

var model_config

The type of the None singleton.

var offers : list[Offer]

The type of the None singleton.

var timestamp : datetime.datetime

The type of the None singleton.

Methods

def add_fidelity_bonds(self,
bonds: list[FidelityBond],
directory_node: str) ‑> None
Expand source code
def add_fidelity_bonds(self, bonds: list[FidelityBond], directory_node: str) -> None:
    for bond in bonds:
        bond.directory_node = directory_node
    self.fidelity_bonds.extend(bonds)
def add_offers(self,
offers: list[Offer],
directory_node: str) ‑> None
Expand source code
def add_offers(self, offers: list[Offer], directory_node: str) -> None:
    for offer in offers:
        offer.directory_node = directory_node
    self.offers.extend(offers)
    if directory_node not in self.directory_nodes:
        self.directory_nodes.append(directory_node)
def get_offers_by_directory(self) ‑> dict[str, list[Offer]]
Expand source code
def get_offers_by_directory(self) -> dict[str, list[Offer]]:
    result: dict[str, list[Offer]] = {}
    for offer in self.offers:
        node = offer.directory_node or "unknown"
        if node not in result:
            result[node] = []
        result[node].append(offer)
    return result
class PeerInfo (**data: Any)
Expand source code
class PeerInfo(BaseModel):
    nick: str = Field(..., min_length=1, max_length=64)
    onion_address: str = Field(..., pattern=r"^[a-z2-7]{56}\.onion$|^NOT-SERVING-ONION$")
    port: int = Field(..., ge=-1, le=65535)
    status: PeerStatus = PeerStatus.UNCONNECTED
    is_directory: bool = False
    network: NetworkType = NetworkType.MAINNET
    last_seen: datetime | None = None
    features: dict[str, Any] = Field(default_factory=dict)
    protocol_version: int = Field(default=5, ge=5, le=10)  # Negotiated protocol version
    neutrino_compat: bool = False  # True if peer supports extended UTXO metadata

    @field_validator("onion_address")
    @classmethod
    def validate_onion(cls, v: str) -> str:
        if v == "NOT-SERVING-ONION":
            return v
        if not v.endswith(".onion"):
            raise ValueError("Invalid onion address")
        return v

    @field_validator("port")
    @classmethod
    def validate_port(cls, v: int, info) -> int:
        if v == -1 and info.data.get("onion_address") == "NOT-SERVING-ONION":
            return v
        if v < 1 or v > 65535:
            raise ValueError("Port must be between 1 and 65535")
        return v

    @cached_property
    def location_string(self) -> str:
        if self.onion_address == "NOT-SERVING-ONION":
            return "NOT-SERVING-ONION"
        return f"{self.onion_address}:{self.port}"

    def supports_extended_utxo(self) -> bool:
        """Check if this peer supports extended UTXO format (neutrino_compat)."""
        # With feature-based detection, we check the neutrino_compat flag
        # which is set from the features dict during handshake
        return self.neutrino_compat

    model_config = {"frozen": False}

Usage Documentation

Models

A base class for creating Pydantic models.

Attributes

__class_vars__
The names of the class variables defined on the model.
__private_attributes__
Metadata about the private attributes of the model.
__signature__
The synthesized __init__ [Signature][inspect.Signature] of the model.
__pydantic_complete__
Whether model building is completed, or if there are still undefined fields.
__pydantic_core_schema__
The core schema of the model.
__pydantic_custom_init__
Whether the model has a custom __init__ function.
__pydantic_decorators__
Metadata containing the decorators defined on the model. This replaces Model.__validators__ and Model.__root_validators__ from Pydantic V1.
__pydantic_generic_metadata__
Metadata for generic models; contains data used for a similar purpose to args, origin, parameters in typing-module generics. May eventually be replaced by these.
__pydantic_parent_namespace__
Parent namespace of the model, used for automatic rebuilding of models.
__pydantic_post_init__
The name of the post-init method for the model, if defined.
__pydantic_root_model__
Whether the model is a [RootModel][pydantic.root_model.RootModel].
__pydantic_serializer__
The pydantic-core SchemaSerializer used to dump instances of the model.
__pydantic_validator__
The pydantic-core SchemaValidator used to validate instances of the model.
__pydantic_fields__
A dictionary of field names and their corresponding [FieldInfo][pydantic.fields.FieldInfo] objects.
__pydantic_computed_fields__
A dictionary of computed field names and their corresponding [ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects.
__pydantic_extra__
A dictionary containing extra values, if [extra][pydantic.config.ConfigDict.extra] is set to 'allow'.
__pydantic_fields_set__
The names of fields explicitly set during instantiation.
__pydantic_private__
Values of private attributes set on the model instance.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.main.BaseModel

Class variables

var features : dict[str, typing.Any]

The type of the None singleton.

var is_directory : bool

The type of the None singleton.

var last_seen : datetime.datetime | None

The type of the None singleton.

var model_config

The type of the None singleton.

var networkNetworkType

The type of the None singleton.

var neutrino_compat : bool

The type of the None singleton.

var nick : str

The type of the None singleton.

var onion_address : str

The type of the None singleton.

var port : int

The type of the None singleton.

var protocol_version : int

The type of the None singleton.

var statusPeerStatus

The type of the None singleton.

Static methods

def validate_onion(v: str) ‑> str
def validate_port(v: int, info) ‑> int

Instance variables

var location_string : str
Expand source code
@cached_property
def location_string(self) -> str:
    if self.onion_address == "NOT-SERVING-ONION":
        return "NOT-SERVING-ONION"
    return f"{self.onion_address}:{self.port}"

Methods

def supports_extended_utxo(self) ‑> bool
Expand source code
def supports_extended_utxo(self) -> bool:
    """Check if this peer supports extended UTXO format (neutrino_compat)."""
    # With feature-based detection, we check the neutrino_compat flag
    # which is set from the features dict during handshake
    return self.neutrino_compat

Check if this peer supports extended UTXO format (neutrino_compat).

class PeerStatus (*values)
Expand source code
class PeerStatus(str, Enum):
    UNCONNECTED = "unconnected"
    CONNECTED = "connected"
    HANDSHAKED = "handshaked"
    DISCONNECTED = "disconnected"

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Ancestors

  • builtins.str
  • enum.Enum

Class variables

var CONNECTED

The type of the None singleton.

var DISCONNECTED

The type of the None singleton.

var HANDSHAKED

The type of the None singleton.

var UNCONNECTED

The type of the None singleton.