Skip to content

Commit 6920d5d

Browse files
committed
feat(webrtc):revamp-setup+implement-test-suites
1 parent 0679efb commit 6920d5d

23 files changed

+6082
-0
lines changed

libp2p/transport/webrtc/__init__.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
"""
2+
WebRTC Transport Module for py-libp2p.
3+
4+
Provides both private-to-private and private-to-public WebRTC transport
5+
implementations.
6+
"""
7+
8+
import sys
9+
from .private_to_private.transport import WebRTCTransport
10+
from .private_to_public.transport import WebRTCDirectTransport
11+
from .constants import (
12+
DEFAULT_ICE_SERVERS,
13+
SIGNALING_PROTOCOL,
14+
MUXER_PROTOCOL,
15+
WebRTCError,
16+
SDPHandshakeError,
17+
ConnectionStateError,
18+
CertificateError,
19+
STUNError,
20+
CODEC_WEBRTC,
21+
CODEC_WEBRTC_DIRECT,
22+
CODEC_CERTHASH,
23+
PROTOCOL_WEBRTC,
24+
PROTOCOL_WEBRTC_DIRECT,
25+
PROTOCOL_CERTHASH,
26+
)
27+
from typing import Dict, Any, Protocol as TypingProtocol
28+
from multiaddr import protocols
29+
from multiaddr.protocols import Protocol
30+
from multiaddr import codecs
31+
32+
33+
class WebRTCCodec:
34+
"""Codec for WebRTC protocol (empty protocol with no value)."""
35+
SIZE = 0
36+
IS_PATH = False
37+
38+
@staticmethod
39+
def to_bytes(proto: Any, s: str) -> bytes:
40+
return b""
41+
42+
@staticmethod
43+
def to_string(proto: Any, b: bytes) -> str:
44+
return ""
45+
46+
47+
class WebRTCDirectCodec:
48+
"""Codec for WebRTC-Direct protocol (empty protocol with no value)."""
49+
SIZE = 0
50+
IS_PATH = False
51+
52+
@staticmethod
53+
def to_bytes(proto: Any, s: str) -> bytes:
54+
return b""
55+
56+
@staticmethod
57+
def to_string(proto: Any, b: bytes) -> str:
58+
return ""
59+
60+
61+
class CerthashCodec:
62+
"""Codec for certificate hash protocol (handles certificate hash encoding/decoding)."""
63+
SIZE = -1 # Variable size protocol
64+
LENGTH_PREFIXED_VAR_SIZE = -1
65+
IS_PATH = False
66+
67+
@staticmethod
68+
def to_bytes(proto: Any, s: str) -> bytes:
69+
if not s:
70+
return b""
71+
# Remove multibase prefix if present
72+
if s.startswith('uEi'):
73+
s = s[3:]
74+
elif s.startswith('u'):
75+
s = s[1:]
76+
# Decode base64url encoded hash
77+
try:
78+
import base64
79+
# Ensure s is encoded as bytes for base64 decoding
80+
s_bytes = s.encode('ascii') if isinstance(s, str) else s
81+
padding = 4 - (len(s_bytes) % 4)
82+
if padding != 4:
83+
s_bytes += b'=' * padding
84+
return base64.urlsafe_b64decode(s_bytes)
85+
except Exception:
86+
return s.encode('utf-8')
87+
88+
@staticmethod
89+
def to_string(proto: Any, b: bytes) -> str:
90+
if not b:
91+
return ""
92+
import base64
93+
b64_hash = base64.urlsafe_b64encode(b).decode().rstrip('=')
94+
return f"uEi{b64_hash}"
95+
96+
97+
# Register WebRTC protocols with multiaddr
98+
try:
99+
100+
# Create codec instances
101+
webrtc_codec = WebRTCCodec()
102+
webrtc_direct_codec = WebRTCDirectCodec()
103+
certhash_codec = CerthashCodec()
104+
105+
# Register codec modules for multiaddr
106+
sys.modules['multiaddr.codecs.webrtc'] = webrtc_codec # type: ignore
107+
sys.modules['multiaddr.codecs.webrtc_direct'] = webrtc_direct_codec # type: ignore
108+
sys.modules['multiaddr.codecs.certhash'] = certhash_codec # type: ignore
109+
110+
setattr(codecs, 'webrtc', webrtc_codec)
111+
setattr(codecs, 'webrtc_direct', webrtc_direct_codec)
112+
setattr(codecs, 'certhash', certhash_codec)
113+
114+
# Create Protocol objects with string codec names
115+
webrtc_protocol = Protocol(
116+
code=CODEC_WEBRTC,
117+
name=PROTOCOL_WEBRTC,
118+
codec="webrtc"
119+
)
120+
121+
webrtc_direct_protocol = Protocol(
122+
code=CODEC_WEBRTC_DIRECT,
123+
name=PROTOCOL_WEBRTC_DIRECT,
124+
codec="webrtc_direct"
125+
)
126+
127+
certhash_protocol = Protocol(
128+
code=CODEC_CERTHASH,
129+
name=PROTOCOL_CERTHASH,
130+
codec="certhash"
131+
)
132+
133+
# Register protocols using the add_protocol function
134+
protocols.add_protocol(webrtc_protocol)
135+
protocols.add_protocol(webrtc_direct_protocol)
136+
protocols.add_protocol(certhash_protocol)
137+
138+
print("✅ WebRTC protocols registered with multiaddr")
139+
140+
except ImportError as e:
141+
print(f"⚠️ Failed to register WebRTC protocols: {e}")
142+
except Exception as e:
143+
print(f"⚠️ Error registering WebRTC protocols: {e}")
144+
145+
__all__ = [
146+
"WebRTCTransport",
147+
"WebRTCDirectTransport",
148+
"DEFAULT_ICE_SERVERS",
149+
"SIGNALING_PROTOCOL",
150+
"MUXER_PROTOCOL",
151+
"WebRTCError",
152+
"SDPHandshakeError",
153+
"ConnectionStateError",
154+
"CertificateError",
155+
"STUNError",
156+
"CODEC_WEBRTC",
157+
"CODEC_WEBRTC_DIRECT",
158+
"CODEC_CERTHASH",
159+
]
160+
161+
162+
def webrtc(config: Dict[str, Any] | None = None) -> WebRTCTransport:
163+
"""Create a WebRTC transport instance (private-to-private)."""
164+
return WebRTCTransport(config)
165+
166+
167+
def webrtc_direct(config: Dict[str, Any] | None = None) -> WebRTCDirectTransport:
168+
"""Create a WebRTC-Direct transport instance (private-to-public)."""
169+
return WebRTCDirectTransport(config)

0 commit comments

Comments
 (0)