def test_builder_xdr(self): cold_account = self.cold.address().decode() hot_account = self.hot.address().decode() fund(cold_account) fund(hot_account) cold = Builder(self.cold.seed().decode()) cold.append_trust_op(cold_account, 'BEER', 1000, hot_account) cold.append_payment_op(hot_account, 100, 'BEER', cold_account) cold.append_payment_op(cold_account, 2.222, 'BEER', cold_account, hot_account) xdr = cold.gen_xdr() hot = Builder(self.hot.seed().decode()) hot.import_from_xdr(xdr) # hot.sign() try: response = hot.submit() except: assert False
def trust_asset(setup, secret_key, memo_text=None): """A helper to establish a trustline""" builder = Builder( secret=secret_key, horizon_uri=setup.horizon_endpoint_uri, network=setup.network) builder.append_trust_op(setup.test_asset.issuer, setup.test_asset.code) if memo_text: builder.add_text_memo(memo_text[:28]) # max memo length is 28 builder.sign() reply = builder.submit() return reply.get('hash')
def issue_asset(issuer_private_key, distributor_private_key, asset_code, limit, network): issuer_address = Keypair.from_seed(issuer_private_key).address().decode() distributor_address = Keypair.from_seed( distributor_private_key).address().decode() builder = Builder(secret=distributor_private_key, network=network) builder.append_trust_op(destination=issuer_address, code=asset_code, limit=limit) builder.sign() builder.submit() builder = Builder(secret=issuer_private_key, network=network) builder.append_payment_op(destination=distributor_address, amount=limit, asset_type=asset_code, asset_issuer=issuer_address) builder.sign() result = builder.submit() return result
def test_builder(self): cold_account = self.cold.address().decode() hot_account = self.hot.address().decode() fund(cold_account) cold = Builder(self.cold.seed().decode()) cold.append_create_account_op(hot_account, 200) cold.append_set_options_op( inflation_dest=cold_account, set_flags=1, home_domain='256kw.com', master_weight=10, low_threshold=5, ) cold.append_trust_op(cold_account, 'BEER', 1000, source=hot_account) cold.append_allow_trust_op(hot_account, 'BEER', True) # append twice for test cold.append_payment_op(hot_account, 50.123, 'BEER', cold_account) cold.append_payment_op(hot_account, 50.123, 'BEER', cold_account) cold.sign(self.hot.seed().decode()) try: # sign twice cold.sign(self.hot.seed().decode()) except SignatureExistError: assert True except: assert False cold.sign() assert len(cold.te.signatures) == 2 assert len(cold.ops) == 5 try: response = cold.submit() print(response) except: assert False
async def build_unsigned_add_trust_and_hot( source_address: str, transaction_source_address: str, hot_amount: Decimal, sequence: str = None) -> Tuple[str, str]: """"Build unsigned transfer transaction return unsigned XDR and transaction hash. Args: source_address: address need to be trust HOT and address for getting HOT """ builder = Builder( address=transaction_source_address, horizon=settings['HORIZON_URL'], network=settings['PASSPHRASE'], sequence=sequence, ) builder.append_trust_op(settings['ISSUER'], settings['ASSET_CODE'], source=source_address, limit=settings['LIMIT_ASSET']) if hot_amount > 0: builder.append_payment_op( source=transaction_source_address, destination=source_address, asset_code=settings['ASSET_CODE'], asset_issuer=settings['ISSUER'], amount=hot_amount, ) try: unsigned_xdr = builder.gen_xdr() tx_hash = builder.te.hash_meta() except Exception as ex: raise web.HTTPNotFound(text=str(ex)) return unsigned_xdr.decode('utf8'), binascii.hexlify(tx_hash).decode()
def test_builder(self): cold_account = self.cold.address().decode() hot_account = self.hot.address().decode() fund(cold_account) cold = Builder(self.cold.seed().decode()) cold.append_create_account_op(hot_account, 200) cold.append_set_options_op(inflation_dest=cold_account, set_flags=1, home_domain='256kw.com',master_weight=10, low_threshold=5,) cold.append_trust_op(cold_account, 'BEER', 1000, source=hot_account) cold.append_allow_trust_op(hot_account,'BEER', True) # append twice for test cold.append_payment_op(hot_account, 50.123, 'BEER', cold_account) cold.append_payment_op(hot_account, 50.123, 'BEER', cold_account) cold.sign(self.hot.seed().decode()) try: # sign twice cold.sign(self.hot.seed().decode()) except SignatureExistError: assert True except: assert False cold.sign() assert len(cold.te.signatures) == 2 assert len(cold.ops) == 5 try: response = cold.submit() print(response) except: assert False
async def build_generate_escrow_wallet_transaction( escrow_address: str, transaction_source_address: str, creator_address: str, destination_address: str, provider_address: str, cost_per_transaction: Decimal, starting_native_asset: Decimal, starting_custom_asset: Decimal, expiration_date: str = None, sequence: str = None, ) -> Tuple[Any, str]: '''Building transaction for generating escrow wallet with minimum balance of lumens and return unsigned XDR and transaction hash. Args: * escrow_address: an address of new wallet * destination_address: an address of wallet which is target * transaction_source_address an address from wallet pool * provider_address: an address which provides custom_asset to new wallet * creator_address: an address of source wallet which is owner of the transaction. * cost_per_transaction: cost for each promotion deals. * starting_native_asset: starting amount of XLM. * starting_custom_asset: starting amount of custom asset(HOT). * expiration_date: a date when escrow address is terminated. ''' builder = Builder( address=transaction_source_address, horizon=settings['HORIZON_URL'], network=settings['PASSPHRASE'], sequence=sequence, ) builder.append_create_account_op(source=creator_address, destination=escrow_address, starting_balance=starting_native_asset) try: builder.append_trust_op( source=escrow_address, destination=settings['ISSUER'], code=settings['ASSET_CODE'], limit=settings['LIMIT_ASSET'], ) except DecodeError: raise web.HTTPBadRequest( reason='Parameter escrow_address or issuer address are not valid.') except Exception as e: msg = str(e) raise web.HTTPInternalServerError(reason=msg) builder.append_manage_data_op(source=escrow_address, data_name='creator_address', data_value=creator_address) builder.append_manage_data_op(source=escrow_address, data_name='destination_address', data_value=destination_address) builder.append_manage_data_op(source=escrow_address, data_name='provider_address', data_value=provider_address) if expiration_date: builder.append_manage_data_op(source=escrow_address, data_name='expiration_date', data_value=expiration_date) builder.append_manage_data_op(source=escrow_address, data_name='cost_per_transaction', data_value=str(cost_per_transaction)) builder.append_set_options_op(source=escrow_address, signer_address=creator_address, signer_type='ed25519PublicKey', signer_weight=1) builder.append_set_options_op(source=escrow_address, signer_address=provider_address, signer_type='ed25519PublicKey', signer_weight=1) builder.append_set_options_op(source=escrow_address, master_weight=0, low_threshold=2, med_threshold=2, high_threshold=2) builder.append_payment_op( source=provider_address, destination=escrow_address, asset_code=settings['ASSET_CODE'], asset_issuer=settings['ISSUER'], amount=starting_custom_asset, ) try: xdr = builder.gen_xdr() except Exception as e: raise web.HTTPBadRequest( reason='Bad request, Please ensure parameters are valid.') tx_hash = builder.te.hash_meta() return xdr.decode(), binascii.hexlify(tx_hash).decode()
#coding: utf-8 from stellar_base.builder import Builder import sys if len(sys.argv) > 3: builder = Builder(secret=sys.argv[1]) builder.append_trust_op(sys.argv[2], sys.argv[3]) builder.sign() print(builder.submit()) else: print(sys.argv[0] + " privkey address_of_issuer asset_code")
class Interface: """ Interface to handle all API calls to third-party account. """ def __init__(self, account): self.account = account if account.secret: self.builder = Builder(secret=account.secret, network=account.network) self.address = Address(address=account.account_id, network=account.network) def _get_new_receives(self): # Get all stored transactions for account transactions = ReceiveTransaction.filter(admin_account=self.account) # Set the cursor according to latest stored transaction: if not transactions: cursor = None else: cursor = int(transactions.latest().data['paging_token']) + 1 # Get new transactions from the stellar network: new_transactions = self._get_receives(cursor=cursor) return new_transactions def _get_receives(self, cursor=None): # If cursor was specified, get all transactions after the cursor: if cursor: transactions = self.address.payments(cursor=cursor)['_embedded']['records'] print(transactions) for i, tx in enumerate(transactions): if tx.get('to') != self.account.account_id: transactions.pop(i) # remove sends # else just get all the transactions: else: transactions = self.address.payments()['_embedded']['records'] for i, tx in enumerate(transactions): if tx.get('from') == self.account.account_id: transactions.pop(i) # remove sends return transactions def _process_receive(self, tx): # Get memo: details = requests.get(url=tx['_links']['transaction']['href']).json() memo = details.get('memo') print('memo: ' + str(memo)) if memo: account_id = memo + '*rehive.com' user_account = UserAccount.objects.get(account_id=account_id) user_email = user_account.user_id # for this implementation, user_id is the user's email amount = to_cents(Decimal(tx['amount']), 7) if tx['asset_type'] == 'native': currency = 'XLM' issuer = '' else: currency = tx['asset_code'] issuer_address = tx['asset_issuer'] issuer = Asset.objects.get(account_id=issuer_address, code=currency).issuer # Create Transaction: tx = ReceiveTransaction.objects.create(user_account=user_account, external_id=tx['hash'], recipient=user_email, amount=amount, currency=currency, issuer=issuer, status='Waiting', data=tx, metadata={'type': 'stellar'} ) # TODO: Move tx.upload_to_rehive() to a signal to auto-run after Transaction creation. tx.upload_to_rehive() return True @staticmethod def _is_valid_address(address: str) -> bool: # TODO: Replace with real address check. if len(address) == 56 and '*' not in address: return True else: return False # This function should always be included if transactions are received to admin account and not added via webhooks: def process_receives(self): # Get new receive transactions new_transactions = self._get_new_receives() # Add each transaction to Rehive and log in transaction table: for tx in new_transactions: self._process_receive(tx) # This function should always be included. def process_send(self, tx): if self._is_valid_address(tx.recipient): address = tx.recipient else: federation = get_federation_details(tx.recipient) if federation['memo_type'] == 'text': self.builder.add_text_memo(federation['memo']) elif federation['memo_type'] == 'id': self.builder.add_id_memo(federation['memo']) elif federation['memo_type'] == 'hash': self.builder.add_hash_memo(federation['memo']) else: raise NotImplementedAPIError('Invalid memo type specified.') address = federation['account_id'] # Create account or create payment: if tx.currency == 'XLM': try: address_obj = self.address address_obj.get() self.builder.append_payment_op(address, tx.amount, 'XLM') except APIException as exc: if exc.status_code == 404: self.builder.append_create_account_op(address, tx.amount) else: # Get issuer address details: issuer_address = get_issuer_address(tx.issuer, tx.currency) address_obj = self.address address_obj.get() self.builder.append_payment_op(address, tx.amount, tx.currency, issuer_address) try: self.builder.sign() self.builder.submit() except Exception as exc: print(exc.payload) def get_balance(self): address = self.address address.get() for balance in address.balances: if balance['asset_type'] == 'native': return to_cents(Decimal(balance['balance']), 7) def get_issuer_address(self, issuer, asset_code): if self._is_valid_address(issuer): address = issuer else: if '*' in issuer: address = get_federation_details(issuer)['account_id'] else: # assume it is an anchor domain address = address_from_domain(issuer, asset_code) return address def trust_issuer(self, asset_code, issuer): logger.info('Trusting issuer: %s %s' % (issuer, asset_code)) address = self.get_issuer_address(issuer, asset_code) self.builder.append_trust_op(address, asset_code) try: self.builder.sign() self.builder.submit() except Exception as exc: print(exc.payload) # Generate new crypto address/ account id @staticmethod def new_account_id(**kwargs): metadata = kwargs.get('metadata') account_id = metadata['username'] + '*' + getattr(settings, 'STELLAR_WALLET_DOMAIN') return account_id def get_account_details(self): address = self.account.account_id qr_code = create_qr_code_url('stellar:' + str(address)) return {'account_id': address, 'metadata': {'qr_code': qr_code}}
async def build_joint_wallet( transaction_source_address: str, deal_address: str, parties: List, creator: str, starting_xlm: Decimal, meta: str = None, sequence: str = None, ): """Build transaction for create joint wallet, trust HOT and set option signer.""" def _add_signer(builder: Builder, deal_address: str, party: str, amount: Decimal): """Set permission of parties can signed transaction that generate from joint account""" builder.append_set_options_op(source=deal_address, signer_address=party, signer_type='ed25519PublicKey', signer_weight=1) builder.append_payment_op( source=party, destination=deal_address, asset_code=settings['ASSET_CODE'], asset_issuer=settings['ISSUER'], amount=amount, ) builder = Builder( address=transaction_source_address, horizon=settings['HORIZON_URL'], network=settings['PASSPHRASE'], sequence=sequence, ) builder.append_create_account_op(source=creator, destination=deal_address, starting_balance=starting_xlm) builder.append_trust_op(source=deal_address, destination=settings['ISSUER'], code=settings['ASSET_CODE'], limit=settings['LIMIT_ASSET']) builder.append_set_options_op(source=deal_address, signer_address=creator, signer_type='ed25519PublicKey', signer_weight=1) for party in parties: _add_signer(builder, deal_address, party['address'], party['amount']) if meta and isinstance(meta, dict): for key, value in meta.items(): builder.append_manage_data_op(source=deal_address, data_name=key, data_value=value) builder.append_manage_data_op(source=deal_address, data_name='creator_address', data_value=creator) weight = len(parties) + 1 builder.append_set_options_op(source=deal_address, master_weight=0, low_threshold=weight, med_threshold=weight, high_threshold=weight) xdr = builder.gen_xdr() tx_hash = builder.te.hash_meta() return xdr.decode(), binascii.hexlify(tx_hash).decode()
async def add_trust(seed): builder = Builder(secret=seed) builder.append_trust_op(destination=sys.argv[3], code="HOT") builder.sign() result = builder.submit() return result
print("Please provide a correct quantity as second argument") sys.exit(0) # We need to accounts, one for the issuer, the other for the distributer kp_issuer = Keypair.random() kp_distrib = Keypair.random() # Then we need to fund them with testnet's Lumens bot_url = "https://friendbot.stellar.org" requests.get(bot_url, params={'addr': kp_issuer.address().decode()}) requests.get(bot_url, params={'addr': kp_distrib.address().decode()}) # And we create a trust line between the distributor and the issuer # In order to do that, we build a transaction. I'll use the Builder class, for simplicity. builder = Builder(secret=kp_distrib.seed().decode()) builder.append_trust_op(kp_issuer.address().decode(), sys.argv[1], sys.argv[2], kp_distrib.address().decode()) builder.sign() builder.submit() # We finally send these tokens from issuer to distributer builder = Builder(secret=kp_issuer.seed().decode()) builder.append_payment_op(kp_distrib.address().decode(), sys.argv[2], sys.argv[1], kp_issuer.address().decode()) builder.sign() builder.submit() # To make sure there will not be anymore creation of this token, we make it unavailable by setting the permission of the master key to 0, and the minimum permission for any operation to 1 builder = Builder(secret=kp_distrib.seed().decode()) builder.append_set_options_op(master_weight=0, low_threshold=1, med_threshold=1, high_threshold=1) builder.sign() builder.submit()
async def build_remove_trustlines_operation(builder: Builder, source: str): builder.append_trust_op(settings['ISSUER'], settings['ASSET_CODE'], limit=0, source=source)