def asset_Identifier(assetName, assetAdd): '''Distinguish lumen between other created assets.''' if assetName=='XLM': asset = Asset('XLM') else: asset = Asset(assetName,assetAdd) return asset
def test_trust_asset(setup, test_sdk, helpers): # failures with pytest.raises(Exception, match='Issuer cannot be null'): test_sdk._trust_asset(Asset('')) with pytest.raises(XdrLengthError, match='Asset code must be 12 characters at max.'): test_sdk._trust_asset(Asset('abcdefghijklmnopqr')) with pytest.raises(Exception, match='Issuer cannot be null'): test_sdk._trust_asset(Asset('TMP')) with pytest.raises(ValueError, match='invalid asset issuer: tmp'): test_sdk._trust_asset(Asset('TMP', 'tmp')) address = Keypair.random().address().decode() with pytest.raises(kin.RequestError) as exc_info: test_sdk._trust_asset(Asset('TMP', address)) assert exc_info.value.error_code == kin.ChangeTrustResultCode.NO_ISSUER # success tx_hash = test_sdk._trust_asset(setup.test_asset, limit=1000, memo_text='foobar') assert tx_hash assert test_sdk._check_asset_trusted(test_sdk.get_address(), setup.test_asset) # TODO: check asset limit # test get_transaction_data for this transaction sleep(1) tx_data = test_sdk.get_transaction_data(tx_hash) assert tx_data assert tx_data.hash == tx_hash assert tx_data.source_account == test_sdk.get_address() assert tx_data.created_at assert tx_data.source_account_sequence assert tx_data.fee_paid == 100 assert tx_data.memo_type == 'text' assert tx_data.memo == 'foobar' assert len(tx_data.signatures) == 1 assert len(tx_data.operations) == 1 op = tx_data.operations[0] assert op.id # assert op.created_at # assert op.transaction_hash == tx_hash assert op.type == 'change_trust' assert op.asset_code == setup.test_asset.code assert op.asset_type == 'credit_alphanum4' assert op.asset_issuer == setup.test_asset.issuer assert op.trustor == test_sdk.get_address() assert op.trustee == setup.test_asset.issuer assert op.limit == Decimal('1000') assert op.from_address is None assert op.to_address is None assert op.amount is None # finally, fund the sdk account with asset assert helpers.fund_asset(setup, test_sdk.get_address(), 1000) assert test_sdk.get_account_kin_balance( test_sdk.get_address()) == Decimal('1000')
def test_manage_offer_dict_price_raises(): msg = "You need pass `price` params as `str` or `{'n': numerator, 'd': denominator}`" with pytest.raises(NotValidParamError, match=msg): ManageOffer( selling=Asset('beer', SOURCE), buying=Asset('beer', DEST), amount="100", price={}, offer_id=1, ).xdr()
def test_changeTrust_min(self): op = ChangeTrust({ 'source': self.source, 'asset': Asset('beer', self.dest), 'limit': '100' }) op_x = Operation.from_xdr(op.xdr()) assert op == op_x assert op_x.source == self.source assert op_x.line == Asset('beer', self.dest) assert op_x.limit == '100'
def append_path_payment_op(self, destination, send_code, send_issuer, send_max, dest_code, dest_issuer, dest_amount, path, source=None): """Append a :class:`PathPayment <stellar_base.operation.PathPayment>` operation to the list of operations. :param str destination: The destination address (Account ID) for the payment. :param str send_code: The asset code for the source asset deducted from the source account. :param str send_issuer: The address of the issuer of the source asset. :param int send_max: The maximum amount of send asset to deduct (excluding fees). :param str dest_code: The asset code for the final destination asset sent to the recipient. :param str dest_issuer: Account address that receives the payment. :param str dest_amount: The amount of destination asset the destination account receives. :param list path: A list of asset tuples, each tuple containing a (code, issuer_address) for each asset in the path. For the native asset, an empty string is used for the issuer address. :param str source: The source address of the path payment. :return: This builder instance. """ # path: a list of asset tuple which contains code and issuer, # [(code,issuer),(code,issuer)] for native asset you can deliver # ('xlm','') send_asset = Asset(send_code, send_issuer) dest_asset = Asset(dest_code, dest_issuer) assets = [] for p in path: assets.append(Asset(p[0], p[1])) opts = { 'source': source, 'destination': destination, 'send_asset': send_asset, 'send_max': str(send_max), 'dest_asset': dest_asset, 'dest_amount': str(dest_amount), 'path': assets } op = operation.PathPayment(opts) return self.append_op(op)
def test_payment_long_asset(self): op = Payment({ 'source': self.source, 'destination': self.dest, 'asset': Asset('SNACKS789ABC', self.source), 'amount': self.amount, }) op_x = Operation.from_xdr(op.xdr()) assert op == op_x assert op_x.source == self.source assert op_x.destination == self.dest assert op_x.asset == Asset('SNACKS789ABC', self.source) assert op_x.amount == self.amount
def __init__(self, config): self.seed = os.environ.get('STELLAR_SEED') or config.get('stellar_seed') self.keypair = Keypair.from_seed(self.seed) self.address = self.keypair.address().decode() self.selling_asset = Asset(config['base_asset']['code'], config['base_asset']['issuer']) self.buying_asset = Asset(config['counter_asset']['code'], config['counter_asset']['issuer']) self.buying_amount = config['buying_amount'] self.buying_rate = config['buying_rate'] self.selling_amount = config['selling_amount'] self.selling_rate = config['selling_rate'] self.horizon_url = config['horizon'] self.horizon = Horizon(config['horizon']) self.network = 'public'
def test_createPassiveOffer_min(self, setup): if setup.type == 'testnet': result = b'AAAAANNSjN1wrdfixw+4w0zmKXvxxikg6EKMi9SW1DnNPhNjAAAAZAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAQAAAABYmVlcgAAAADTUozdcK3X4scPuMNM5il78cYpIOhCjIvUltQ5zT4TYwAAAAFiZWVyAAAAAK2uFogrxa/78nU4lG0kBdB8JKhKz/MHOgVEGr96kkCOAAAAADuaygAABMsvAAGGoAAAAAAAAAABzT4TYwAAAEAm4lQf6g7mpnw05syhOt3ub+OmSADhSfLwn/xg6bD+6qwqlpF/xflNYWKU1uQOy4P9e1+SWIGJdR+KWryykS0M' # TODO else: result = b'AAAAANNSjN1wrdfixw+4w0zmKXvxxikg6EKMi9SW1DnNPhNjAAAAZAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAQAAAABYmVlcgAAAADTUozdcK3X4scPuMNM5il78cYpIOhCjIvUltQ5zT4TYwAAAAFiZWVyAAAAAK2uFogrxa/78nU4lG0kBdB8JKhKz/MHOgVEGr96kkCOAAAAADuaygAABMsvAAGGoAAAAAAAAAABzT4TYwAAAECvQiQXbKoZxYnF4qVL8GNBEzECgKUc0lNLJLYF/ML3mwPYkYRyldfxZ8h04P3iSjBmE+3srS05Ncajuy7+qugL' assert (result == self.do( setup.network, op=CreatePassiveOffer( selling=Asset('beer', self.source), buying=Asset('beer', self.dest), amount="100", price=3.14159, )))
def test_manageOffer_min(self, setup): if setup.type == 'testnet': result = b'AAAAANNSjN1wrdfixw+4w0zmKXvxxikg6EKMi9SW1DnNPhNjAAAAZAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAMAAAABYmVlcgAAAADTUozdcK3X4scPuMNM5il78cYpIOhCjIvUltQ5zT4TYwAAAAFiZWVyAAAAAK2uFogrxa/78nU4lG0kBdB8JKhKz/MHOgVEGr96kkCOAAAAADuaygAABMsvAAGGoAAAAAAAAAABAAAAAAAAAAHNPhNjAAAAQBTg1srmkpv/pFqELvCsSurwRPYRUpH05j1sgDzOZdILCdVpxb3sEvMgim1DXE0VhGXqbgZaQV/Sp2VH5C5RKQI=' # TODO else: result = b'AAAAANNSjN1wrdfixw+4w0zmKXvxxikg6EKMi9SW1DnNPhNjAAAAZAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAMAAAABYmVlcgAAAADTUozdcK3X4scPuMNM5il78cYpIOhCjIvUltQ5zT4TYwAAAAFiZWVyAAAAAK2uFogrxa/78nU4lG0kBdB8JKhKz/MHOgVEGr96kkCOAAAAADuaygAABMsvAAGGoAAAAAAAAAABAAAAAAAAAAHNPhNjAAAAQCvR7B7vbXDy1ShEhYhlNzRIZRJ2DSmVhWe5kCDLWf9GTNhiSEfigaVs7UrPSeDWqPUVyzYx7Igu9JG6OL6WMwM=' assert (result == self.do( setup.network, op=ManageOffer( selling=Asset('beer', self.source), buying=Asset('beer', self.dest), amount="100", price=3.14159, offer_id=1, )))
def test_createPassiveOffer_min(self): op = CreatePassiveOffer({ 'selling': Asset('beer', self.source), 'buying': Asset('beer', self.dest), 'amount': "100", 'price': 3.14159, }) op_x = Operation.from_xdr(op.xdr()) assert op == op_x assert op_x.source == None assert op_x.selling == Asset('beer', self.source) assert op_x.buying == Asset('beer', self.dest) assert op_x.amount == "100" assert op_x.price == 3.14159
def test_changeTrust_min(self, setup): if setup.type == 'testnet': result = b'AAAAANNSjN1wrdfixw+4w0zmKXvxxikg6EKMi9SW1DnNPhNjAAAAZAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABYmVlcgAAAACtrhaIK8Wv+/J1OJRtJAXQfCSoSs/zBzoFRBq/epJAjn//////////AAAAAAAAAAHNPhNjAAAAQL0R9eOS0qesc+HHKQoHMjFUJWvzeQOy+u/7HBHNooo37AOaG85y9jyNoa1D4EduroZmK8vCfCF0V3rn5o9CpgA=' else: result = b'AAAAANNSjN1wrdfixw+4w0zmKXvxxikg6EKMi9SW1DnNPhNjAAAAZAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABYmVlcgAAAACtrhaIK8Wv+/J1OJRtJAXQfCSoSs/zBzoFRBq/epJAjn//////////AAAAAAAAAAHNPhNjAAAAQEMLKLk6BmEehiEqR155eZoHTMf0bFoZcsvTZpv1KDPXkOdyJZlinNR6FHv7Odk/kvxV5pYET+zqrLCJUwhcjgs=' assert (result == self.do( setup.network, op=ChangeTrust(asset=Asset('beer', self.dest), )))
def make_payment_op(account_id, amount): return Payment({ 'destination': account_id, 'source': pool_address, 'amount': str(amount), 'asset': Asset('XLM') })
def post(self, request): source_private_key = request.data.get('sourcePrivateKey') dest_address = request.data.get('destAddress') amount = request.data.get('amount', '0.0000001') source = Keypair.from_seed(source_private_key) source_address = source.address().decode('UTF-8') requests.get(url=friend_bot_url, params={'addr': source_address}) requests.get(url=friend_bot_url, params={'addr': dest_address}) # Create operations for transaction payment = Payment(destination=dest_address, asset=Asset('XLM'), amount=amount) memo = TextMemo('Transaction Memo') sequence = horizon.account(source_address).get('sequence') operations = [payment] try: transaction = Transaction(source=source_address, sequence=sequence, memo=memo, fee=100 * len(operations), operations=operations) envelope = TransactionEnvelope(tx=transaction, network_id="TESTNET") # Sign the sender envelope.sign(source) # Submit it to the network xdr = envelope.xdr() response = horizon.submit(xdr) return Response(response, status=status.HTTP_200_OK) except HorizonError as horizonError: return Response(horizonError.message, status=horizonError.status_code)
def append_payment_op(self, destination, amount, asset_code='XLM', asset_issuer=None, source=None): """Append a :class:`Payment <stellar_base.operation.Payment>` operation to the list of operations. :param str destination: Account address that receives the payment. :param int amount: The amount of the currency to send in the payment. :param str asset_code: The asset code for the asset to send. :param str asset_issuer: The address of the issuer of the asset. :param str source: The source address of the payment. :return: This builder instance. """ asset = Asset(code=asset_code, issuer=asset_issuer) opts = { 'source': source, 'destination': destination, 'asset': asset, 'amount': str(amount) } op = operation.Payment(opts) return self.append_op(op)
def setup(testnet): class Struct: """Handy variable holder""" def __init__(self, **entries): self.__dict__.update(entries) sdk_keypair = Keypair.random() issuer_keypair = Keypair.random() test_asset = Asset('KIN', issuer_keypair.address().decode()) # global testnet if testnet: from stellar_base.horizon import HORIZON_TEST return Struct(type='testnet', network='TESTNET', sdk_keypair=sdk_keypair, issuer_keypair=issuer_keypair, test_asset=test_asset, horizon_endpoint_uri=HORIZON_TEST) # local testnet (zulucrypto docker) # https://github.com/zulucrypto/docker-stellar-integration-test-network from stellar_base.network import NETWORKS NETWORKS['CUSTOM'] = 'Integration Test Network ; zulucrypto' return Struct(type='local', network='CUSTOM', sdk_keypair=sdk_keypair, issuer_keypair=issuer_keypair, test_asset=test_asset, horizon_endpoint_uri='http://localhost:8000')
def test_manageOffer_min(self): op = ManageOffer({ 'selling': Asset('beer', self.source), 'buying': Asset('beer', self.dest), 'amount': "100", 'price': 3.14159, 'offer_id': 1, }) op_x = Operation.from_xdr(op.xdr()) assert op == op_x assert op_x.source == None assert op_x.selling == Asset('beer', self.source) assert op_x.buying == Asset('beer', self.dest) assert op_x.amount == "100" assert op_x.price == 3.14159 assert op_x.offer_id == 1
def test_send_kin(setup, test_sdk, helpers): with pytest.raises(ValueError, match='invalid address: bad'): test_sdk.send_kin('bad', 10) keypair = Keypair.random() address = keypair.address().decode() with pytest.raises(ValueError, match='amount must be positive'): test_sdk.send_kin(address, 0) with pytest.raises(ValueError, match='invalid asset issuer: bad'): test_sdk._send_asset(Asset('TMP', 'bad'), address, 10) # account does not exist yet with pytest.raises(kin.AccountNotFoundError) as exc_info: test_sdk.send_kin(address, 10) assert exc_info.value.error_code == kin.PaymentResultCode.NO_DESTINATION assert test_sdk.create_account(address, starting_balance=100) # no trustline yet with pytest.raises(kin.AccountNotActivatedError) as exc_info: test_sdk.send_kin(address, 10) assert exc_info.value.error_code == kin.PaymentResultCode.NO_TRUST # add trustline from the newly created account to the kin issuer assert helpers.trust_asset(setup, keypair.seed()) # send and check the resulting balance tx_hash = test_sdk.send_kin(address, 10.123, memo_text='foobar') assert tx_hash assert test_sdk.get_account_kin_balance(address) == Decimal('10.123') # test get_transaction_data for this transaction sleep(1) tx_data = test_sdk.get_transaction_data(tx_hash) assert tx_data assert tx_data.hash == tx_hash assert tx_data.source_account == test_sdk.get_address() assert tx_data.created_at assert tx_data.source_account_sequence assert tx_data.fee_paid == 100 assert tx_data.memo_type == 'text' assert tx_data.memo == 'foobar' assert len(tx_data.signatures) == 1 assert len(tx_data.operations) == 1 op = tx_data.operations[0] assert op.id assert op.type == 'payment' assert op.asset_code == setup.test_asset.code assert op.asset_type == 'credit_alphanum4' assert op.asset_issuer == setup.test_asset.issuer assert op.trustor is None assert op.trustee is None assert op.limit is None assert op.from_address == test_sdk.get_address() assert op.to_address == address assert op.amount == Decimal('10.123')
def test_mix_2(self, setup): if setup.type == 'testnet': result = b'AAAAANNSjN1wrdfixw+4w0zmKXvxxikg6EKMi9SW1DnNPhNjAAABkAAAAAAAAAACAAAAAAAAAAAAAAAEAAAAAAAAAAUAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAABRVVSAAAAAADTUozdcK3X4scPuMNM5il78cYpIOhCjIvUltQ5zT4TYwAjhvJvwQAAAAAAAAAAAAcAAAAA01KM3XCt1+LHD7jDTOYpe/HGKSDoQoyL1JbUOc0+E2MAAAABRVVSAAAAAAEAAAAAAAAAAQAAAACUyh6BxJLSIexOsnlc0kfWuLis7Tm5WZEdfp1s6PbZ+AAAAAFFVVIAAAAAANNSjN1wrdfixw+4w0zmKXvxxikg6EKMi9SW1DnNPhNjACOG8m/BAAAAAAAAAAAAAc0+E2MAAABAUDuJuoUdHYxE/AmYKN4x+EvI3NpLtAgs9xYq4AJMFVmC2zDIn1J2+o5uIyqYxQW84SW31laWcrY8YkGWPqkeBA==' else: result = b'AAAAANNSjN1wrdfixw+4w0zmKXvxxikg6EKMi9SW1DnNPhNjAAABkAAAAAAAAAACAAAAAAAAAAAAAAAEAAAAAAAAAAUAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAABRVVSAAAAAADTUozdcK3X4scPuMNM5il78cYpIOhCjIvUltQ5zT4TYwAjhvJvwQAAAAAAAAAAAAcAAAAA01KM3XCt1+LHD7jDTOYpe/HGKSDoQoyL1JbUOc0+E2MAAAABRVVSAAAAAAEAAAAAAAAAAQAAAACUyh6BxJLSIexOsnlc0kfWuLis7Tm5WZEdfp1s6PbZ+AAAAAFFVVIAAAAAANNSjN1wrdfixw+4w0zmKXvxxikg6EKMi9SW1DnNPhNjACOG8m/BAAAAAAAAAAAAAc0+E2MAAABAKHsltQKqjdueu13k7PI7cLg4Tya2aOFH+1Sc9qeK4z0AXxropuRVHhyuriPu/ZXHIRVDvD5xQ0SmMFPVFtU0BA==' assert (result == self.make_envelope( setup.network, SetOptions(set_flags=1), ChangeTrust( asset=Asset('EUR', self.address), limit="1000000000"), AllowTrust( authorize=True, asset_code='EUR', trustor=self.address), Payment( destination=self.accounts[0]['address'], asset=Asset('EUR', self.address), amount="1000000000")))
def append_manage_offer_op(self, selling_code, selling_issuer, buying_code, buying_issuer, amount, price, offer_id=0, source=None): """Append a :class:`ManageOffer <stellar_base.operation.ManageOffer>` operation to the list of operations. :param str selling_code: The asset code for the asset the offer creator is selling. :param str selling_issuer: The issuing address for the asset the offer creator is selling. :param str buying_code: The asset code for the asset the offer creator is buying. :param str buying_issuer: The issuing address for the asset the offer creator is selling. :param int amount: Amount of the asset being sold. Set to 0 if you want to delete an existing offer. :param float price: Decimal representation of the price of 1 unit of selling in terms of buying. For example, if you wanted to sell 30 XLM and buy 5 BTC, the price would be (5 / 30). Note that this does not take a tuple/dict with a numerator/denominator at this time. :param str offer_id: The ID of the offer. 0 for new offer. Set to existing offer ID to update or delete. :param str source: The source address that is managing an offer on Stellar's distributed exchange. :return: This builder instance. """ selling = Asset(selling_code, selling_issuer) buying = Asset(buying_code, buying_issuer) opts = { 'source': source, 'selling': selling, 'buying': buying, 'amount': str(amount), 'price': price, 'offer_id': offer_id, } op = operation.ManageOffer(opts) return self.append_op(op)
def test_sdk_not_configured(setup): sdk = kin.SDK(horizon_endpoint_uri=setup.horizon_endpoint_uri, network=setup.network) with pytest.raises(kin.SdkError, match='address not configured'): sdk.get_address() with pytest.raises(kin.SdkError, match='address not configured'): sdk.get_native_balance() with pytest.raises(kin.SdkError, match='address not configured'): sdk.get_kin_balance() with pytest.raises(kin.SdkError, match='address not configured'): sdk.create_account('address') with pytest.raises(kin.SdkError, match='address not configured'): sdk.monitor_kin_payments(None) with pytest.raises(kin.SdkError, match='address not configured'): sdk._trust_asset(Asset('TMP', 'tmp')) with pytest.raises(kin.SdkError, match='address not configured'): sdk._send_asset(Asset('TMP', 'tmp'), 'address', 1)
def get_stellar_asset(self): if self.stellar_asset: return self.stellar_asset stellar_asset = Asset(self.asset_code, self.get_asset_issuer()) self.stellar_asset = stellar_asset return self.stellar_asset