def send_xlm_vault_transaction(user, destination, amount): from stellar_base.transaction import Transaction wallet = VaultWallet.objects.get(username=user, name="xlm") User = Keypair.from_seed(wallet.private) horizon = horizon_testnet() asset = Asset.native() op = Payment({ 'destination': destination, 'asset': asset, 'amount': amount }) msg = TextMemo('From test net !') sequence = horizon.account(User.address().decode('utf-8')).get('sequence') tx = Transaction( source=User.address().decode(), opts={ 'sequence': sequence, 'memo': msg, 'operations': [ op, ], }, ) try: envelope = Te(tx=tx, opts={"network_id": "TESTNET"}) envelope.sign(User) xdr = envelope.xdr() response = horizon.submit(xdr) return response['hash'] except: return {"error": ""}
def transfer_fund(amount, asset_object, customer_account, issuer_account, issuer_seed): horizon = horizon_testnet() print('Transferring fund to {}'.format(customer_account)) op = Payment(destination=customer_account, asset=asset_object, amount=str(amount), source=issuer_account) msg = TextMemo('Your first Payment !') sequence = horizon.account(issuer_account).get('sequence') tx = Transaction( source=issuer_account, sequence=sequence, memo=msg, fee=None, operations=[op], ) issuer_account1 = Keypair.from_seed(issuer_seed) envelope = Te(tx=tx, signatures=None, network_id="TESTNET") envelope.sign(issuer_account1) xdr_envelope = envelope.xdr() response = horizon.submit(xdr_envelope) print(response) if 'result_xdr' in response: print('Successful Transfer') else: print('Things go Fishy')
def opr_change_trust(asset_object, receiver_address, receiver_seed): horizon = horizon_testnet() sequence = horizon.account(receiver_address).get('sequence') print(sequence) op = ChangeTrust( asset=asset_object, limit='5000', source=receiver_address ) # print(op.__dict__) msg = TextMemo('Change Trust Operation') receiving_account = Keypair.from_seed(receiver_seed) tx = Transaction( source=receiving_account.address().decode(), sequence=sequence, time_bounds=None, memo=msg, fee=None, operations=[op], ) envelope = Te(tx=tx, signatures=None, network_id="TESTNET") envelope.sign(receiving_account) xdr_envelope = envelope.xdr() response = horizon.submit(xdr_envelope) print(response) if 'result_xdr' in response: print('Successful') else: print('Things go Fishy')
def create_account(user): # type: (User) -> None # create keypair keypair = Keypair.random() public_key = keypair.address().decode() seed = keypair.seed().decode() # store account StellarAccount.objects.create(seed=seed, address=public_key, user=user, balance=0.0) horizon = horizon_testnet() if settings.DEMO_MODE else horizon_livenet() # fund account if settings.DEMO_MODE: for _ in range(5): # noinspection PyBroadException try: funding_keypair = Keypair.from_seed( settings.FUNDING_ACCOUNT_SEED) # create operation create_account_operation = CreateAccount({ 'destination': public_key, 'starting_balance': '1' }) # create transaction sequence = horizon.account( funding_keypair.address().decode()).get('sequence') tx = Transaction(source=funding_keypair.address().decode(), opts={ 'sequence': sequence, 'memo': TextMemo('Creating new Zendi account.'), 'operations': [create_account_operation] }) # create and sign envelope envelope = TransactionEnvelope(tx=tx, opts={"network_id": "TESTNET"}) envelope.sign(funding_keypair) # Submit the transaction to Horizon te_xdr = envelope.xdr() horizon.submit(te_xdr) break except Exception as ex: logger.error('Error while funding account', ex) time.sleep(1) logger.info('Created Stellar Lumen account {} for {}'.format( public_key, user))
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 test_text_memo_toolong(self): memo_text = "Out, out, brief candle, life is but a walking shadow." length = len(memo_text) with pytest.raises( XdrLengthError, match="Text should be <= 28 bytes \(ascii encoded\). " "Got {}".format(str(length))): TextMemo(memo_text)
def transaction( ): # Performs the transaction from one to another thus providing the current balance. amount = str(request.form['amount']) # Amount taken from the user. memo = TextMemo(request.form['memo']) # Memo entered by user. send = Keypair.from_seed(send_seed) horizon = horizon_testnet() asset = Asset('XLM') op = Payment({ 'destination': receive_publickey, 'asset': asset, 'amount': amount, }) sequence = horizon.account(send.address()).get('sequence') tx = Transaction( source=send.address().decode(), opts={ 'sequence': sequence, 'memo': memo, 'fee': 100, 'operations': [ op, ], }, ) envelope = Te(tx=tx, opts={"network_id": "TESTNET"}) envelope.sign(send) xdr = envelope.xdr() response = horizon.submit(xdr) trans = response['_links'] for values in trans.itervalues(): for confirmation in values.itervalues(): confirm = confirmation address1.get() # Receiving balance info in JSON format address2.get() for a1 in address1.balances: send_current = a1[ 'balance'] # Retrieving the eaxct balance info fron JSON. for a2 in address2.balances: receive_current = a2['balance'] cbalance = { # Current balance. 'send_current': send_current, 'receive_current': receive_current, 'confirm': confirm, # 'amount': amount, } return render_template("transaction.html", cbalance=cbalance)
def perform_transaction(self): send_seed = self.seed1 recieve_address = self.publickey2 amount = str(input("\nEnter the amount to be transferred(0-9998): ")) print("0.0000100 will be charged extra for the transaction") send = Keypair.from_seed(send_seed) horizon = horizon_testnet() asset = Asset('XLM') op = Payment({ 'destination': recieve_address, 'asset': asset, 'amount': amount, }) msg = TextMemo('Transaction Test') print("Transferring the ammount to the Receiver......") sequence = horizon.account(send.address()).get('sequence') tx = Transaction( source=send.address().decode(), opts={ 'sequence': sequence, 'memo': msg, 'fee': 100, 'operations': [ op, ], }, ) envelope = Te(tx=tx, opts={"network_id": "TESTNET"}) envelope.sign(send) xdr = envelope.xdr() response = horizon.submit(xdr) print("Transaction completed successfully.\n") trans = response['_links'] for values in trans.itervalues(): for confirmation in values.itervalues(): print("Confirmation Link: " + confirmation) print( "\n------------------------------------------------------------------------------" ) print("\nChecking the current balance......")
def create_te(self, user_kaykair, sequence, memo, op, FEE=200): """创建te""" tx = Transaction( source=user_kaykair.address().decode(), opts={ 'sequence': sequence, 'memo': TextMemo(memo), 'fee': FEE, 'operations': [op], }, ) envelope = Te(tx=tx, opts=dict(network_id=self._network_id)) envelope.sign(user_kaykair) te = envelope.xdr() tx_hash = hashlib.sha256(envelope.signature_base()).hexdigest() return te, tx_hash
def create_envelope(user_kaykair, sequence, memo, opers, FEE=0): """事务封包""" tx = Transaction( source=user_kaykair.address().decode(), # 事务发起着的公钥 opts={ 'sequence': sequence, # 事务发起着的序列号 'memo': TextMemo(memo), # 备注 'fee': len(opers) * FEE, # 手续费 'operations': opers, }, ) # 操作 envelope = Te(tx=tx, opts=dict(network_id='XIANDA_DEV_NET')) # 操作封包的类Te envelope.sign(user_kaykair) # 事务发起着签名 # te = envelope.xdr() # 转换xdr格式数据 te_hash = hashlib.sha256(envelope.signature_base()).hexdigest() return te_hash
def create_envelope_submits(user_kaykair, sequence, memo, opers, FEE=FEE): """事务封包,并提交""" tx = Transaction( source=user_kaykair[0].address().decode(), # 事务发起着的公钥 opts={ 'sequence': sequence, # 事务发起着的序列号 'memo': TextMemo(memo), # 备注 'fee': len(opers) * FEE, # 手续费 'operations': opers, }, ) # 操作 envelope = Te(tx=tx, opts=dict(network_id='XIANDA_DEV_NET')) # 操作封包的类Te for i in user_kaykair: print 2222, user_kaykair envelope.sign(i) # envelope.sign(user_kaykair) # 事务发起着签名 te = envelope.xdr() # 转换xdr格式数据 return submit(te, envelope)
def create_account(self, old_account_seed, new_account_address, amount, memo): """ 用已有账户创建新账户 """ horizon = self.client account_seed = old_account_seed old_account_keypair = Keypair.from_seed(account_seed) account_addr = new_account_address start_amount = amount # Your new account minimum balance (in XLM) to transfer over # create the CreateAccount operation opts = {'destination': account_addr, 'starting_balance': start_amount} op = CreateAccount(opts) # create a memo txt_memo = TextMemo(memo) # Get the current sequence of the source account by contacting Horizon. You # should also check the response for errors! try: sequence = horizon.account( old_account_keypair.address().decode()).get('sequence') except Exception as e: logger.exception(e) # Create a transaction with our single create account operation, with the # default fee of 100 stroops as of this writing (0.00001 XLM) trans_ops = { 'sequence': sequence, 'memo': txt_memo, 'operations': [op] } tx = Transaction(source=old_account_keypair.address().decode(), opts=trans_ops) env_opts = {'network_id': 'TESTNET'} envelope = TransactionEnvelope(tx=tx, opts=env_opts) # Sign the transaction envelope with the source keypair envelope.sign(old_account_keypair) # Submit the transaction to Horizon te_xdr = envelope.xdr() response = horizon.submit(te_xdr) return response
Alice = Keypair.from_seed(alice_seed) horizon = horizon_testnet() # for TESTNET # horizon = horizon_livenet() # for LIVENET # create op payment_op = Payment( # source=Alice.address().decode(), destination=bob_address, asset=Asset('XLM'), amount='10.5') set_home_domain_op = SetOptions(home_domain='fed.network') # create a memo msg = TextMemo('Buy yourself a beer!') # get sequence of Alice # Python 3 sequence = horizon.account(Alice.address().decode('utf-8')).get('sequence') # Python 2 # sequence = horizon.account(Alice.address()).get('sequence') operations = [payment_op, set_home_domain_op] # construct Tx tx = Transaction( source=Alice.address().decode(), sequence=int(sequence), # time_bounds = {'minTime': 1531000000, 'maxTime': 1531234600}, memo=msg, fee=100 * len(operations),
def test_memo_xdr(self): xdr_string = b'AAAAAQAAAA1oZXksIHN0ZWxsYXIhAAAA' xdr_memo = TextMemo('hey, stellar!').xdr() assert xdr_string == xdr_memo
def test_text_memo_wrong_value(self): memo_text = ("stellar", ) with pytest.raises(TypeError, match='Expects string type got a {}'.format( type(memo_text))): TextMemo(memo_text)
def clean(self): """ Override to verify Stellar account using Data Entry added client-side. Decoded data entry must match request.user.id """ # TODO: HANDLE THE RAISED ERRORS TO OUTPUT A VALIDATION ERROR (WORRY ABOUT TAMPERED WITH SIGNATURE ERROR) # Call the super super(AccountCreateForm, self).clean() # Obtain form input parameters creating_stellar = self.cleaned_data.get("creating_stellar") public_key = self.cleaned_data.get("public_key") if creating_stellar: # Creating a new Stellar account # NOTE: https://stellar-base.readthedocs.io/en/latest/quickstart.html#create-an-account request_user = self.request_user # Check current request user is an admin allowed to approve funding if not request_user.is_superuser: raise ValidationError( _('Invalid request. You must be an admin to approve funding of new accounts.' )) # Check that account for this public key does not already exist elif Account.objects.filter(public_key=public_key).exists(): raise ValidationError( _('Invalid public key. This account has already been funded.' )) # Check that a funding request exists for this public key and fetch it try: funding_request = AccountFundRequest.objects.get( public_key=public_key) except ObjectDoesNotExist: funding_request = None raise ValidationError( _('Funding request for this public key does not exist.')) # Make a call to Horizon to fund new account with Nucleo base account horizon = settings.STELLAR_HORIZON_INITIALIZATION_METHOD() # Assemble the CreateAccount operation amount = settings.STELLAR_CREATE_ACCOUNT_MINIMUM_BALANCE memo = TextMemo('Nucleo Created Account') op_create = CreateAccount({ 'destination': public_key, 'starting_balance': amount, }) # Get the current sequence of the source account by contacting Horizon. # TODO: You should also check the response for errors! sequence = horizon.account( settings.STELLAR_BASE_KEY_PAIR.address()).get('sequence') # Create a transaction with our single create account operation, with the # default fee of 100 stroops as of this writing (0.00001 XLM) tx = Transaction( source=settings.STELLAR_BASE_KEY_PAIR.address().decode(), opts={ 'sequence': sequence, 'memo': memo, 'operations': [op_create], }, ) # Build a transaction envelope, ready to be signed. envelope = Te(tx=tx, opts={"network_id": settings.STELLAR_NETWORK}) # Sign the transaction envelope with the source keypair envelope.sign(settings.STELLAR_BASE_KEY_PAIR) # Submit the transaction to Horizon # TODO: Make sure to look at the response body carefully, as it can be an error or a successful response. te_xdr = envelope.xdr() response = horizon.submit(te_xdr) # Check whether account actually created on ledger if 'hash' not in response: raise ValidationError( _('Nucleo was not able to create a Stellar account at this time' )) # If successful, increment the user's account quota val by one user_funding = funding_request.requester self.account_user = user_funding profile_funding = user_funding.profile profile_funding.accounts_created += 1 profile_funding.save() # Delete the funding request funding_request.delete() # Email the requester to notify them of approved funding for new account profile_path = reverse('nc:user-detail', kwargs={'slug': user_funding.username}) profile_url = build_absolute_uri(self.request, profile_path) current_site = get_current_site(self.request) email_settings_path = reverse('nc:user-settings-redirect') email_settings_url = build_absolute_uri(self.request, email_settings_path) ctx_email = { 'current_site': current_site, 'username': user_funding.username, 'account_public_key': public_key, 'profile_url': profile_url, 'email_settings_url': email_settings_url, } get_adapter(self.request).send_mail('nc/email/account_create', user_funding.email, ctx_email) else: # Verify Stellar public key with the added Data Entry # Get the Stellar account for given public key # NOTE: Need to decouple Address initialization from get() method to work! address = Address(address=public_key, network=settings.STELLAR_NETWORK) try: address.get() except AccountNotExistError: raise ValidationError(_( 'Invalid account. Stellar Account associated with given public key does not exist.' ), code='invalid_account') # Obtain the signed_user data entry signed_user = address.data.get( settings.STELLAR_DATA_VERIFICATION_KEY, None) if not signed_user: raise ValidationError(_( 'Invalid data entry. Decoded Stellar Data Entry does not exist.' ), code='invalid_data_entry') # Now decode and verify data self.loaded_user_id = signing.loads(base64.b64decode(signed_user)) if self.request_user.id != self.loaded_user_id: raise ValidationError(_( 'Invalid user id. Decoded Stellar Data Entry does not match your user id.' ), code='invalid_user') # Associate request user with this account self.account_user = self.request_user # Delete any existing funding request associated with that key AccountFundRequest.objects.filter(public_key=public_key).delete() # TODO: SEND EMAIL IF KEY HAS BEEN COMPROMISED, SOMEHOW ALLOW UNFUNDED ACCOUNTS TO BE SEEN? return self.cleaned_data
def test_text_memo(self): memo_text = "Hello, world!" memo = TextMemo(memo_text) if sys.version_info.major >= 3: memo_text = bytearray(memo_text, encoding='utf-8') self.__asset_memo('text', memo_text, memo)
# coding: utf-8 import sys import os import binascii import pytest from stellar_base.exceptions import NotValidParamError from stellar_base.memo import ( NoneMemo, TextMemo, HashMemo, IdMemo, RetHashMemo, xdr_to_memo ) from stellar_base.stellarxdr import Xdr @pytest.mark.parametrize("memo_obj", [ TextMemo("Hello, Stellar"), NoneMemo(), IdMemo(31415926535), ]) def test_xdr_to_memo(memo_obj): xdr_obj = memo_obj.to_xdr_object() restored_obj = xdr_to_memo(xdr_obj) assert memo_obj == restored_obj class TestMemo: def test_none_memo(self): memo = NoneMemo() self.__asset_memo('none', None, memo) def test_text_memo(self):
def send_payment(sender_seed, tx): # Generate the sender's Keypair for signing and setting as the source sender_kp = Keypair.from_seed(sender_seed) tx = {key.decode("utf-8"): val.decode("utf-8") for key, val in tx.items()} # Address for the destination destination = tx.get("to") # create op amount = tx.get("amount") if tx.get("currency").upper() == "XLM": asset = Asset("XLM") else: raise UnknownIssuerError("Unknown currency and/or issuer.") # TODO: # Issuer's address # ISSUER = tx.get('issuer') # asset = Asset(tx.get('currency').upper(), ISSUER) op = Payment( # Source is also inferred from the transaction source, so it's optional. source=sender_kp.address().decode(), destination=destination, asset=asset, amount=amount, ) # create a memo msg = TextMemo("Stellar-SMS is dope!!!") horizon = horizon_testnet() # horizon = horizon_livenet() for LIVENET # Get the current sequence of sender sequence = horizon.account( sender_kp.address().decode("utf-8")).get("sequence") # TODO: track sequence locally for better accuracy, speed, and robustness # Construct a transaction tx = Transaction( source=sender_kp.address().decode(), sequence=sequence, # time_bounds = {'minTime': 1531000000, 'maxTime': 1531234600}, memo=msg, fee=100, # Can specify a fee or use the default by not specifying it operations=[op], ) # Build transaction envelope envelope = Te(tx=tx, network_id="TESTNET") # or 'PUBLIC' # Sign the envelope envelope.sign(sender_kp) # Submit the transaction to Horizon! xdr = envelope.xdr() response = horizon.submit(xdr) log.debug(str(response)) if response.get("status") not in [None, 200]: log.error( f"Submission unsuccessful. Horizon retured with error: {response.detail}" ) return log.debug("Transaction was successfully submitted to the network.") return True