Source code for stellar_base.federation
# coding: utf-8
import requests
import toml
from stellar_base.utils import is_valid_address
from .exceptions import FederationError, StellarAddressInvalidError
[docs]def federation(address_or_id, fed_type='name', domain=None, allow_http=False):
"""Send a federation query to a Stellar Federation service.
For more info, see the `complete guide on Stellar Federation.
<https://www.stellar.org/developers/guides/concepts/federation.html>`_.
:param str address_or_id: The address which you expect te retrieve
federation information about.
:param str fed_type: The type of federation query that you are making. Must
be 'name', 'id', 'forward', or 'txid'.
:param str domain: The domain that corresponds to the address or ID;
this is where the stellar.toml file lives (which ultimately points to
the URL of the federation service).
:param bool allow_http: Whether to allow for requests over plain HTTP over
HTTPS. Note - you should *always* use HTTPS outside of testing.
:return dict: The federation query response decoded from JSON as a dict.
"""
if fed_type == 'name':
if '*' not in address_or_id:
raise FederationError('Not a valid federation address.')
param, domain = address_or_id.rsplit('*', 1)
if param == '' or domain == '':
raise FederationError('Not a valid federation address.')
elif fed_type == 'id':
try:
assert is_valid_address(address_or_id)
except StellarAddressInvalidError:
raise FederationError('{} is not a valid account id.'.format(address_or_id))
else:
raise FederationError('Not a valid fed_type.')
if '.' not in domain:
raise FederationError('Not a valid domain name.')
fed_service = get_federation_service(domain, allow_http)
if not fed_service:
raise FederationError('Not a valid federation server.')
return _get_federation_info(address_or_id, fed_service, fed_type)
def _get_federation_info(address_or_id, federation_service, fed_type='name'):
"""Send a federation query to a Stellar Federation service.
Note: The preferred method of making this call is via
:function:`federation`, as it handles error checking and parsing of
arguments.
:param str address_or_id: The address which you expect te retrieve
federation information about.
:param str federation_service: The url of the federation service you're
requesting information from.
:param str fed_type: The type of federation query that you are making. Must
be 'name', 'id', 'forward', or 'txid'.
:return dict: The federation query response decoded from JSON as a dict.
"""
params = {'q': address_or_id, 'type': fed_type}
r = requests.get(federation_service, params=params)
if r.status_code == 200:
return r.json()
else:
return None
[docs]def get_federation_service(domain, allow_http=False):
"""Retrieve the FEDERATION_SERVER config from a domain's stellar.toml.
:param str domain: The domain the .toml file is hosted at.
:param bool allow_http: Specifies whether the request should go over plain
HTTP vs HTTPS. Note it is recommend that you *always* use HTTPS.
:return str: The FEDERATION_SERVER url.
"""
st = get_stellar_toml(domain, allow_http)
if not st:
return None
return st.get('FEDERATION_SERVER')
[docs]def get_auth_server(domain, allow_http=False):
"""Retrieve the AUTH_SERVER config from a domain's stellar.toml.
:param str domain: The domain the .toml file is hosted at.
:param bool allow_http: Specifies whether the request should go over plain
HTTP vs HTTPS. Note it is recommend that you *always* use HTTPS.
:return str: The AUTH_SERVER url.
"""
st = get_stellar_toml(domain, allow_http)
if not st:
return None
return st.get('AUTH_SERVER')
[docs]def get_stellar_toml(domain, allow_http=False):
"""Retrieve the stellar.toml file from a given domain.
Retrieve the stellar.toml file for information about interacting with
Stellar's federation protocol for a given Stellar Anchor (specified by a
domain).
:param str domain: The domain the .toml file is hosted at.
:param bool allow_http: Specifies whether the request should go over plain
HTTP vs HTTPS. Note it is recommend that you *always* use HTTPS.
:return: The stellar.toml file as a an object via :func:`toml.loads`.
"""
toml_link = '/.well-known/stellar.toml'
if allow_http:
protocol = 'http://'
else:
protocol = 'https://'
url_list = ['', 'www.', 'stellar.']
url_list = [protocol + url + domain + toml_link for url in url_list]
for url in url_list:
r = requests.get(url)
if r.status_code == 200:
return toml.loads(r.text)
return None