|
18 | 18 | from uma.protocol.payer_data import compliance_from_payer_data |
19 | 19 | from uma.nonce_cache import InMemoryNonceCache |
20 | 20 | from uma.protocol.pubkey_response import PubkeyResponse |
21 | | -from uma.public_key_cache import InMemoryPublicKeyCache |
| 21 | +from uma.public_key_cache import InMemoryPublicKeyCache, IAsyncPublicKeyCache |
22 | 22 | from uma.type_utils import none_throws |
23 | 23 | from uma.protocol.post_tx_callback import UtxoWithAmount |
24 | 24 | from uma.protocol.v0.payreq import PayRequest as V0PayRequest |
|
33 | 33 | create_pay_request, |
34 | 34 | create_post_transaction_callback, |
35 | 35 | fetch_public_key_for_vasp, |
| 36 | + fetch_public_key_for_vasp_async, |
36 | 37 | is_uma_lnurlp_query, |
37 | 38 | parse_lnurlp_request, |
38 | 39 | parse_lnurlp_response, |
@@ -77,6 +78,30 @@ def test_fetch_public_key() -> None: |
77 | 78 | assert cache.fetch_public_key_for_vasp(vasp_domain) == expected_pubkey |
78 | 79 |
|
79 | 80 |
|
| 81 | +@pytest.mark.asyncio |
| 82 | +async def test_fetch_public_key_async() -> None: |
| 83 | + cache = TestAsyncPublicKeyCache() |
| 84 | + vasp_domain = "vasp2.com" |
| 85 | + timestamp = int((datetime.now(timezone.utc) + timedelta(hours=1)).timestamp()) |
| 86 | + expected_pubkey = PubkeyResponse( |
| 87 | + signing_pubkey=secrets.token_bytes(16), |
| 88 | + encryption_pubkey=secrets.token_bytes(16), |
| 89 | + expiration_timestamp=datetime.fromtimestamp(timestamp, timezone.utc), |
| 90 | + encryption_cert_chain=None, |
| 91 | + signing_cert_chain=None, |
| 92 | + ) |
| 93 | + url = "https://vasp2.com/.well-known/lnurlpubkey" |
| 94 | + |
| 95 | + with patch( |
| 96 | + "uma.uma._run_http_get_async", |
| 97 | + return_value=json.dumps(expected_pubkey.to_dict()), |
| 98 | + ) as mock: |
| 99 | + pubkey_response = await fetch_public_key_for_vasp_async(vasp_domain, cache) |
| 100 | + mock.assert_called_once_with(url) |
| 101 | + assert pubkey_response == expected_pubkey |
| 102 | + assert await cache.fetch_public_key_for_vasp(vasp_domain) == expected_pubkey |
| 103 | + |
| 104 | + |
80 | 105 | def _create_pubkey_response( |
81 | 106 | signing_private_key: PrivateKey, encryption_private_key: PrivateKey |
82 | 107 | ) -> PubkeyResponse: |
@@ -1218,3 +1243,24 @@ def test_uma_invoice_signature() -> None: |
1218 | 1243 |
|
1219 | 1244 | assert verify_uma_invoice_signature(invoice, pubkey_response) is None |
1220 | 1245 | assert invoice.signature is not None |
| 1246 | + |
| 1247 | + |
| 1248 | +class TestAsyncPublicKeyCache(IAsyncPublicKeyCache): |
| 1249 | + def __init__(self) -> None: |
| 1250 | + self._cache = InMemoryPublicKeyCache() |
| 1251 | + |
| 1252 | + async def fetch_public_key_for_vasp( |
| 1253 | + self, vasp_domain: str |
| 1254 | + ) -> Optional[PubkeyResponse]: |
| 1255 | + return self._cache.fetch_public_key_for_vasp(vasp_domain) |
| 1256 | + |
| 1257 | + async def add_public_key_for_vasp( |
| 1258 | + self, vasp_domain: str, public_key: PubkeyResponse |
| 1259 | + ) -> None: |
| 1260 | + self._cache.add_public_key_for_vasp(vasp_domain, public_key) |
| 1261 | + |
| 1262 | + async def remove_public_key_for_vasp(self, vasp_domain: str) -> None: |
| 1263 | + self._cache.remove_public_key_for_vasp(vasp_domain) |
| 1264 | + |
| 1265 | + async def clear(self) -> None: |
| 1266 | + self._cache.clear() |
0 commit comments