mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-06-02 23:29:34 +00:00
49 lines
1.4 KiB
Python
49 lines
1.4 KiB
Python
|
|
from functools import wraps
|
||
|
|
from typing import Callable, TypeVar, ParamSpec, cast
|
||
|
|
|
||
|
|
from .exceptions import InvalidStateError
|
||
|
|
from .card_interface import CardInterface
|
||
|
|
|
||
|
|
P = ParamSpec("P")
|
||
|
|
R = TypeVar("R")
|
||
|
|
|
||
|
|
|
||
|
|
def make_precondition(
|
||
|
|
attribute_name: str,
|
||
|
|
display_name: str | None = None
|
||
|
|
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
||
|
|
def decorator(func: Callable[P, R]) -> Callable[P, R]:
|
||
|
|
@wraps(func)
|
||
|
|
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
||
|
|
card = args[0]
|
||
|
|
if not isinstance(card, CardInterface):
|
||
|
|
raise TypeError("First argument must be a CardInterface")
|
||
|
|
if not getattr(card, attribute_name, False):
|
||
|
|
readable = (
|
||
|
|
display_name
|
||
|
|
if display_name is not None
|
||
|
|
else attribute_name.replace('_', ' ').title()
|
||
|
|
)
|
||
|
|
raise InvalidStateError(f"{readable} must be satisfied.")
|
||
|
|
return func(*args, **kwargs)
|
||
|
|
return cast(Callable[P, R], wrapper)
|
||
|
|
return decorator
|
||
|
|
|
||
|
|
|
||
|
|
require_selected = make_precondition(
|
||
|
|
'is_selected',
|
||
|
|
'Card Selection'
|
||
|
|
)
|
||
|
|
require_initialized = make_precondition(
|
||
|
|
'is_initialized',
|
||
|
|
'Card Initialization'
|
||
|
|
)
|
||
|
|
require_secure_channel = make_precondition(
|
||
|
|
'is_secure_channel_open',
|
||
|
|
'Secure Channel'
|
||
|
|
)
|
||
|
|
require_pin_verified = make_precondition(
|
||
|
|
'is_pin_verified',
|
||
|
|
'PIN verification'
|
||
|
|
)
|