Source code for stellar_base.asset

# coding: utf-8

import base64
import re

from stellar_base.exceptions import AssetCodeInvalidError, StellarAddressInvalidError
from .utils import account_xdr_object, encode_check, is_valid_address
from .stellarxdr import Xdr


[docs]class Asset(object): """The :class:`Asset` object, which represents an asset and its corresponding issuer on the Stellar network. For more information about the formats used for asset codes and how issuers work on Stellar's network, see `Stellar's guide on assets`_. :param str code: The asset code, in the formats specified in `Stellar's guide on assets`_. :param issuer: The strkey encoded issuer of the asset. Note if the currency is the native currency (XLM (Lumens)), no issuer is necessary. :type issuer: str, None .. _Stellar's guide on assets: https://www.stellar.org/developers/guides/concepts/assets.html """ _ASSET_CODE_RE = re.compile(r'^[a-zA-Z0-9]{1,12}$') def __init__(self, code, issuer=None): if not self._ASSET_CODE_RE.match(code): raise AssetCodeInvalidError("Asset code is invalid (alphanumeric, 12 " "characters max).") if issuer is not None: try: assert is_valid_address(issuer) except StellarAddressInvalidError: raise StellarAddressInvalidError('Invalid issuer account: {}'.format(issuer)) if code.lower() != 'xlm' and issuer is None: raise StellarAddressInvalidError("Issuer cannot be `None` except native asset.") self.code = code self.issuer = issuer self.type = self.guess_asset_type() def __eq__(self, other): return self.xdr() == other.xdr() def guess_asset_type(self): if self.code.lower() == 'xlm' and self.issuer is None: asset_type = 'native' elif len(self.code) > 4: asset_type = 'credit_alphanum12' else: asset_type = 'credit_alphanum4' return asset_type
[docs] def to_dict(self): """Generate a dict for this object's attributes. :return: A dict representing an :class:`Asset` """ rv = {'code': self.code} if not self.is_native(): rv['issuer'] = self.issuer rv['type'] = self.type else: rv['type'] = 'native' return rv
[docs] @staticmethod def native(): """Create a :class:`Asset` with the native currency. Currently, the native currency is Stellar Lumens (XLM) :return: A new :class:`Asset` representing the native currency on the Stellar network. """ return Asset("XLM")
[docs] def is_native(self): """Return true if the :class:`Asset` is the native asset. :return: True if the Asset is native, False otherwise. """ return self.issuer is None
[docs] def to_xdr_object(self): """Create an XDR object for this :class:`Asset`. :return: An XDR Asset object """ if self.is_native(): xdr_type = Xdr.const.ASSET_TYPE_NATIVE return Xdr.types.Asset(type=xdr_type) else: x = Xdr.nullclass() length = len(self.code) pad_length = 4 - length if length <= 4 else 12 - length x.assetCode = bytearray(self.code, 'ascii') + b'\x00' * pad_length x.issuer = account_xdr_object(self.issuer) if length <= 4: xdr_type = Xdr.const.ASSET_TYPE_CREDIT_ALPHANUM4 return Xdr.types.Asset(type=xdr_type, alphaNum4=x) else: xdr_type = Xdr.const.ASSET_TYPE_CREDIT_ALPHANUM12 return Xdr.types.Asset(type=xdr_type, alphaNum12=x)
[docs] def xdr(self): """Create an base64 encoded XDR string for this :class:`Asset`. :return str: A base64 encoded XDR object representing this :class:`Asset`. """ asset = Xdr.StellarXDRPacker() asset.pack_Asset(self.to_xdr_object()) return base64.b64encode(asset.get_buffer())
[docs] @classmethod def from_xdr_object(cls, asset_xdr_object): """Create a :class:`Asset` from an XDR Asset object. :param asset_xdr_object: The XDR Asset object. :return: A new :class:`Asset` object from the given XDR Asset object. """ if asset_xdr_object.type == Xdr.const.ASSET_TYPE_NATIVE: return Asset.native() elif asset_xdr_object.type == Xdr.const.ASSET_TYPE_CREDIT_ALPHANUM4: issuer = encode_check( 'account', asset_xdr_object.alphaNum4.issuer.ed25519).decode() code = asset_xdr_object.alphaNum4.assetCode.decode().rstrip('\x00') else: issuer = encode_check( 'account', asset_xdr_object.alphaNum12.issuer.ed25519).decode() code = ( asset_xdr_object.alphaNum12.assetCode.decode().rstrip('\x00')) return cls(code, issuer)
[docs] @classmethod def from_xdr(cls, xdr): """Create an :class:`Asset` object from its base64 encoded XDR representation. :param bytes xdr: The base64 encoded XDR Asset object. :return: A new :class:`Asset` object from its encoded XDR representation. """ xdr_decoded = base64.b64decode(xdr) asset = Xdr.StellarXDRUnpacker(xdr_decoded) asset_xdr_object = asset.unpack_Asset() asset = Asset.from_xdr_object(asset_xdr_object) return asset