Skip to content

Commit 3ced7ef

Browse files
MHHukiewitzPsycojokerhoh
committed
feat: add aleph.sdk.security module
Co-authored-by: Laurent Peuch <[email protected]> Co-authored-by: Hugo Herter <[email protected]>
1 parent 9c5ec6e commit 3ced7ef

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

src/aleph/sdk/security.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from importlib import import_module
2+
from typing import Any, Union, Dict, Callable
3+
4+
from aleph_message.models import AlephMessage, Chain
5+
6+
from aleph.sdk.chains.common import get_verification_buffer
7+
from aleph.sdk.query.responses import Post
8+
9+
10+
def _try_import_verify_signature(chain: str) -> Any:
11+
"""Try to import a chain signature validator."""
12+
try:
13+
return import_module(f"aleph.sdk.chains.{chain}").verify_signature
14+
except (ImportError, AttributeError):
15+
return None
16+
17+
18+
# This is a dict containing all currently available signature validators,
19+
# indexed by their Chain abbreviation.
20+
#
21+
# Ex.: validators["SOL"] -> aleph.sdk.chains.solana.verify_signature()
22+
VALIDATORS: Dict[Chain, Callable[[Union[bytes, str], Union[bytes, str], Union[bytes, str]], None]] = {
23+
key: _try_import_verify_signature(value)
24+
for key, value in {
25+
# TODO: Add AVAX
26+
Chain.ETH: "ethereum",
27+
Chain.SOL: "sol",
28+
Chain.CSDK: "cosmos",
29+
Chain.DOT: "substrate",
30+
Chain.NULS2: "nuls2",
31+
Chain.TEZOS: "tezos",
32+
}.items()
33+
}
34+
35+
36+
def verify_message_signature(message: Union[AlephMessage, Post]) -> None:
37+
"""Verify the signature of a message, raise an error if invalid or unsupported.
38+
A BadSignatureError is raised when the signature is incorrect.
39+
A ValueError is raised when the chain is not supported or required dependencies are missing.
40+
"""
41+
if message.chain not in VALIDATORS:
42+
raise ValueError(f"Chain {message.chain} is not supported.")
43+
44+
validator = VALIDATORS[message.chain]
45+
if validator is None:
46+
raise ValueError(
47+
f"Chain {message.chain} is not installed. Install it with `aleph-sdk-python[{message.chain}]`."
48+
)
49+
50+
signature = message.signature
51+
public_key = message.sender
52+
message = get_verification_buffer(message.dict())
53+
54+
# to please mypy
55+
assert isinstance(signature, (str, bytes))
56+
57+
validator(signature, public_key, message)

tests/unit/test_security.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
def test_validators_loaded():
2+
import aleph.sdk.security as security
3+
4+
assert any([validator is not None for validator in security.validators.values()])

0 commit comments

Comments
 (0)