new_contents: import logging
  
  import olm
  from canonicaljson import encode_canonical_json
  
  from matrix_client.checks import check_user_id
  
  logger = logging.getLogger(__name__)
  
  
  class OlmDevice(object):
      """Manages the Olm cryptographic functions.
  
      Has a unique Olm account which holds identity keys.
  
      Args:
          api (MatrixHttpApi): The api object used to make requests.
          user_id (str): Matrix user ID. Must match the one used when logging in.
          device_id (str): Must match the one used when logging in.
      """
  
      def __init__(self, api, user_id, device_id):
          self.api = api
          check_user_id(user_id)
          self.user_id = user_id
          self.device_id = device_id
          self.olm_account = olm.Account()
          logger.info('Initialised Olm Device.')
  
      def sign_json(self, json):
          """Signs a JSON object.
  
          NOTE: The object is modified in-place and the return value can be ignored.
  
          As specified, this is done by encoding the JSON object without ``signatures`` or
          keys grouped as ``unsigned``, using canonical encoding.
  
          Args:
              json (dict): The JSON object to sign.
  
          Returns:
              The same JSON object, with a ``signatures`` key added. It is formatted as
              ``"signatures": ed25519:<device_id>: <base64_signature>``.
          """
          signatures = json.pop('signatures', {})
          unsigned = json.pop('unsigned', None)
  
          signature_base64 = self.olm_account.sign(encode_canonical_json(json))
  
          key_id = 'ed25519:{}'.format(self.device_id)
          signatures.setdefault(self.user_id, {})[key_id] = signature_base64
  
          json['signatures'] = signatures
          if unsigned:
              json['unsigned'] = unsigned
  
          return json
  
subject: add crypto/olm_device.py and sign json