fix(MAT-258): fix DeviceStore API for Olm to-device E2EE key delivery
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 40s

matrix-nio's DeviceStore has no .get() method. Use correct API:
DeviceStore[user_id].get(device_id) returns OlmDevice from inner dict.
Also fix keys_claim() to accept Dict[str, List[str]] per nio API.

This was the root cause of Element X silence — bot couldn't deliver
its E2EE key via Olm-encrypted to-device messages, so Element X
couldn't decrypt bot's audio frames.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-03-27 10:51:52 +02:00
parent f57c91589f
commit c2985488c4

14
bot.py
View File

@@ -3759,12 +3759,20 @@ class Bot:
for user_id, device_id in targets:
# Get the device from the device store
device = olm.device_store.get(user_id, device_id) if hasattr(olm, 'device_store') else None
# nio DeviceStore[user_id] returns Dict[str, OlmDevice]
device = None
try:
device = olm.device_store[user_id].get(device_id)
except KeyError:
pass
if not device:
# Need to fetch device keys first
logger.info("Fetching device keys for %s/%s", user_id, device_id)
await self.client.keys_query()
device = olm.device_store.get(user_id, device_id) if hasattr(olm, 'device_store') else None
try:
device = olm.device_store[user_id].get(device_id)
except KeyError:
pass
if not device:
logger.warning("Device %s/%s not found in store, sending unencrypted", user_id, device_id)
@@ -3776,7 +3784,7 @@ class Bot:
if not session:
# Claim one-time key and create session
logger.info("Claiming one-time key for %s/%s", user_id, device_id)
claim_resp = await self.client.keys_claim(user_id, device_id)
await self.client.keys_claim({user_id: [device_id]})
session = olm.session_store.get(device.curve25519)
if session: