docs: def gpg_app_put_key( blockchain_id, appname, keyname, key_data, txid=None, immutable=False, proxy=None, wallet_keys=None, config_dir=None ):
      """
      Put an application GPG key.
      Stash the private key locally to an app-specific keyring.
  
      Return {'status': True, 'key_url': ..., 'key_data': ...} on success
      Return {'error': ...} on error
      
      If immutable is True, then store the data as an immutable entry (e.g. update the zonefile with the key hash)
      This is a time-consuming operation (on the order of an hour), and you will get back the transaction ID
      on a successful execution.  It is up to you to wait until the transaction is confirmed before using the key.
  
      Otherwise, the key is stored to mutable storage.
      """
  
      assert is_valid_appname(appname)
      assert is_valid_keyname(keyname)
  
      try:
          keydir = make_gpg_home( appname, config_dir=config_dir )
          key_id = gpg_stash_key( appname, key_data, config_dir=config_dir, gpghome=keydir )
          assert key_id is not None, "Failed to stash key"
          log.debug("Stashed app key '%s:%s' (%s) under '%s'" % (appname, keyname, key_id, keydir))
      except Exception, e:
          log.exception(e)
          log.error("Failed to store GPG key '%s'" % keyname)
          return {'error': "Failed to store GPG key locally"}
  
      # get public key... 
      assert is_valid_appname(appname)
      try:
          pubkey_data = gpg_export_key( appname, key_id, config_dir=config_dir ) 
      except:
          return {'error': 'Failed to load key'}
  
      fq_key_name = "gpg.%s.%s" % (appname, keyname)
      key_url = None
  
      if not immutable:
          res = client.put_mutable( blockchain_id, fq_key_name, {fq_key_name: pubkey_data}, txid=txid, proxy=proxy, wallet_keys=wallet_keys )
          if 'error' in res:
              return res
  
          key_url = client.make_mutable_data_url( blockchain_id, fq_key_name, res['version'] )
      
      else:
          res = client.put_immutable( blockchain_id, fq_key_name, {fq_key_name: pubkey_data}, txid=txid, proxy=proxy, wallet_keys=wallet_keys )
          if 'error' in res:
              return res 
  
          key_url = client.make_immutable_data_url( blockchain_id, fq_key_name, res['immutable_data_hash'] )
  
      res['key_url'] = key_url
      res['key_data'] = pubkey_data
      res['key_id'] = gpg_key_fingerprint( pubkey_data, config_dir=config_dir )
      log.debug("Put key %s:%s (%s) to %s" % (appname, keyname, res['key_id'], key_url))
      return res