22
33from trezor import log , loop
44from trezor .messages import DebugLinkN4W1Read , DebugLinkN4W1Response , DebugLinkN4W1Write
5+ from trezor .ui import Layout
56
67if TYPE_CHECKING :
78 from buffer_types import AnyBytes
8- from typing import Any
9+ from typing import Any , Awaitable , Iterator
910
1011 from trezor .wire .context import Context
1112 from typing_extensions import Self
@@ -28,6 +29,11 @@ def __exit__(self, exc_type: Any, exc_val: Any, tb: Any) -> None:
2829 log .debug (__name__ , "N4W1 exchange done" )
2930 self .tx .put (None )
3031
32+ async def connect (self ) -> None :
33+ """Wait for N4W1 connection notification."""
34+ res = await self .rx
35+ assert res .value is None
36+
3137 async def read (self , key : str ) -> AnyBytes | None :
3238 """Read a specific entry from N4W1."""
3339 log .debug (__name__ , "N4W1 read: %s" , key )
@@ -50,9 +56,51 @@ async def write(self, key: str, value: AnyBytes | None) -> AnyBytes | None:
5056
5157 async def handle (self , ctx : Context ) -> None :
5258 """Called from `apps.debug.dispatch_DebugLinkConnected()`."""
59+ self .rx .put (DebugLinkN4W1Response (value = None )) # notify `self.connect()`
5360 while (req := await self .tx ) is not None :
5461 res = await ctx .call (req , DebugLinkN4W1Response )
5562 self .rx .put (res )
5663
64+ def confirm_connect (
65+ self , * , title : str , description : str , button : str , br_name : str | None
66+ ) -> Awaitable [None ]:
67+ """Show a layout waiting for N4W1 connection, allowing cancellation."""
68+
69+ from trezor import TR
70+ from trezor .ui .layouts .menu import Menu , confirm_with_menu
71+ from trezorui_api import show_info
72+
73+ self_ctx : N4W1Context = self
74+
75+ class _Connect (Layout ):
76+
77+ def create_tasks (self ) -> Iterator [loop .Task [None ]]:
78+ from trezor .ui import Shutdown
79+ from trezorui_api import CONFIRMED
80+
81+ async def _task () -> None :
82+ await self_ctx .connect () # blocks until N4W1 is connected.
83+ try :
84+ # emitting a message raises Shutdown exception
85+ self ._emit_message (CONFIRMED )
86+ except Shutdown :
87+ pass
88+
89+ yield from super ().create_tasks ()
90+ yield _task ()
91+
92+ main = show_info (
93+ title = title ,
94+ description = description ,
95+ button = (button , False ),
96+ external_menu = True ,
97+ )
98+ return confirm_with_menu (
99+ main ,
100+ Menu .root (cancel = TR .buttons__cancel ),
101+ br_name = br_name ,
102+ layout_type = _Connect ,
103+ )
104+
57105
58106ctx = N4W1Context ()
0 commit comments