docs: def gpg_app_get_key( blockchain_id, appname, keyname, immutable=False, key_id=None, key_hash=None, key_version=None, proxy=None, config_dir=None ):
      """
      Get an app-specific GPG key.
      Return {'status': True, 'key_id': ..., 'key': ..., 'app_name': ...} on success
      return {'error': ...} on error
      """
  
      assert is_valid_appname(appname)
      assert is_valid_keyname(keyname)
  
      if config_dir is None:
          config_dir = get_config_dir()
  
      fq_key_name = "gpg.%s.%s" % (appname, keyname)
      key_url = None 
  
      if immutable:
          # try immutable
          key_url = blockstack_client.make_immutable_data_url( blockchain_id, fq_key_name, key_hash )
  
      else:
          # try mutable 
          key_url = blockstack_client.make_mutable_data_url( blockchain_id, fq_key_name, key_version )
  
      log.debug("fetch '%s'" % key_url)
      key_data = gpg_fetch_key( key_url, key_id, config_dir=config_dir )
      if key_data is None:
          return {'error': 'Failed to fetch key'}
  
      if key_id is None:
          key_id = gpg_key_fingerprint( key_data, config_dir=config_dir )
  
      ret = {
          'status': True,
          'key_id': key_id,
          'key_data': key_data,
          'app_name': appname
      }
  
      return ret