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 test_verify_challenge_tx_source_is_different_to_server_account_id( self): server_kp = Keypair.random() client_kp = Keypair.random() network = 'TESTNET' challenge = Builder(server_kp.seed().decode(), network=network, sequence=-1, fee=100) challenge.sign() challenge_tx_server_signed = challenge.gen_xdr() transaction = Builder(client_kp.seed().decode(), network='TESTNET', sequence=0, fee=100) transaction.import_from_xdr(challenge_tx_server_signed) transaction.sign() challenge_tx = transaction.gen_xdr() with pytest.raises( InvalidSep10ChallengeError, match= "Transaction source account is not equal to server's account." ): Builder.verify_challenge_tx(challenge_tx, Keypair.random().address().decode(), 'TESTNET')
def test_verify_challenge_tx_donot_contain_managedata_operation(self): server_kp = Keypair.random() client_kp = Keypair.random() timeout = 600 network = 'TESTNET' challenge = Builder(server_kp.seed().decode(), network=network, sequence=-1, fee=100) now = int(time.time()) challenge.add_time_bounds({'minTime': now, 'maxTime': now + timeout}) challenge.append_bump_sequence_op(12, source=client_kp.address().decode()) challenge.sign() challenge_tx_server_signed = challenge.gen_xdr() transaction = Builder(client_kp.seed().decode(), network='TESTNET', sequence=0, fee=100) transaction.import_from_xdr(challenge_tx_server_signed) transaction.sign() challenge_tx = transaction.gen_xdr() with pytest.raises(InvalidSep10ChallengeError, match="Operation type should be ManageData."): Builder.verify_challenge_tx(challenge_tx, server_kp.address().decode(), 'TESTNET')
def test_verify_challenge_tx_operation_does_not_contain_the_source_account( self): server_kp = Keypair.random() client_kp = Keypair.random() timeout = 600 network = 'TESTNET' archor_name = 'sdf' challenge = Builder(server_kp.seed().decode(), network=network, sequence=-1, fee=100) now = int(time.time()) challenge.add_time_bounds({'minTime': now, 'maxTime': now + timeout}) nonce = os.urandom(64) challenge.append_manage_data_op( data_name='{} auth'.format(archor_name), data_value=nonce) challenge.sign() challenge_tx_server_signed = challenge.gen_xdr() transaction = Builder(client_kp.seed().decode(), network='TESTNET', sequence=0, fee=100) transaction.import_from_xdr(challenge_tx_server_signed) transaction.sign() challenge_tx = transaction.gen_xdr() with pytest.raises(InvalidSep10ChallengeError, match="Operation should have a source account."): Builder.verify_challenge_tx(challenge_tx, server_kp.address().decode(), 'TESTNET')
def test_builder_xdr(setup, helpers, test_data): hot = Keypair.random() hot_account = hot.address().decode() hot_secret = hot.seed() helpers.fund_account(setup, hot_account) cold = Builder(secret=test_data.cold_secret, horizon=setup.horizon_endpoint_uri, network=setup.network) \ .append_trust_op(test_data.cold_account, 'BEER', '1000', hot_account) \ .append_allow_trust_op(hot_account, 'BEER', True, test_data.cold_account) \ .append_payment_op(hot_account, '100', 'BEER', test_data.cold_account, test_data.cold_account) \ .append_payment_op(test_data.cold_account, '2.222', 'BEER', test_data.cold_account, hot_account) cold.sign() xdr = cold.gen_xdr() hot = Builder(secret=hot_secret, horizon=setup.horizon_endpoint_uri, network=setup.network) hot.import_from_xdr(xdr) hot.sign() assert len(hot.te.signatures) == 2 assert len(hot.ops) == 4 response = hot.submit() assert response.get('hash') == hot.hash_hex()
def build_unsigned_change_trust(source_address: str, transaction_source_address: str, 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 """ 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']) 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_verify_challenge_tx(self): server_kp = Keypair.random() client_kp = Keypair.random() timeout = 600 network = 'Public Global Stellar Network ; September 2015' archor_name = "SDF" challenge = Builder.challenge_tx( server_secret=server_kp.seed().decode(), client_account_id=client_kp.address().decode(), archor_name=archor_name, network=network, timeout=timeout) challenge.sign() challenge_tx_server_signed = challenge.gen_xdr() transaction = Builder( client_kp.seed().decode(), network='Public Global Stellar Network ; September 2015', sequence=0, fee=100) transaction.import_from_xdr(challenge_tx_server_signed) transaction.sign() challenge_tx = transaction.gen_xdr() Builder.verify_challenge_tx( challenge_tx, server_kp.address().decode(), 'Public Global Stellar Network ; September 2015')
def send_asset(text): # send 10 EURT antb123*papayame.com or send 1 XLM PUBKEY memo text if CONF['private_key'] == '': print( 'no private key setup - pls type set to set key or c to create wallet' ) return val = text.split() memo_type = 'text' if len(val) < 3: print( 'invalid syntax please use send amount asset receiver e.g. s 10 EURT antb123*papayame.com' ) return amount, asset, address = val[1], val[2].upper(), val[3] if '*' in address: res = fed(address.split('*')[1], address) sendto = res['account_id'] memo = res['memo'] memo_type = res['memo_type'] else: sendto = address memo = '' # override memo, type if given if len(val) == 6: memo = val[4] memo_type = val[5] if len(val) == 5: memo = val[4] memo_type = 'text' print_formatted_text( HTML("""Are you sure you want to send <ansiyellow>%s</ansiyellow> <ansired>%s %s</ansired> with memo of <ansiblue>%s</ansiblue> (y/n) """ % (sendto, asset, amount, memo))) text = session.prompt(u'> ', default='y') if text != 'y': return ret, asset_issuer = get_balance_issuer(amount, asset) if ret: return retsan = send_sanity(sendto, memo_type, asset) if not retsan: return send = Builder(CONF['private_key'], network=CONF['network']) if asset != 'XLM': send.append_payment_op(sendto, amount, asset, asset_issuer) else: send.append_payment_op(sendto, amount) if memo != '' and memo_type == 'text': send.add_text_memo(memo) if memo != '' and memo_type == 'id': send.add_id_memo(memo) if CONF['multisig'] != '': print( 'You have 2of2 multisig - send this data to the other key to sign when you get it back type signsend data' ) print(send.gen_xdr()) return send.sign() send.submit()
def build_generate_trust_wallet_transaction( transaction_source_address: str, source_address: str, destination_address: str, xlm_amount: Decimal, hot_amount: Decimal = Decimal(0), sequence=None, ) -> Tuple[bytes, bytes]: """"Build transaction return unsigned XDR and transaction hash. Args: transaction_source_address: Owner of a transaction. source_address: Owner of creator address and payment operations. destination_address: wallet id of new wallet. xlm_amount: starting xlm_balance of new wallet. hot_amount: starting hot balance of new wallet. """ builder = Builder( address=transaction_source_address, horizon=settings['HORIZON_URL'], network=settings['PASSPHRASE'], sequence=sequence, ) builder.append_create_account_op(source=source_address, destination=destination_address, starting_balance=xlm_amount) try: builder.append_trust_op( source=destination_address, destination=settings['ISSUER'], code=settings['ASSET_CODE'], limit=settings['LIMIT_ASSET'], ) except DecodeError: raise web.HTTPBadRequest(reason='Parameter values are not valid.') except Exception as e: msg = str(e) raise web.HTTPInternalServerError(reason=msg) if hot_amount > 0: builder.append_payment_op( source=source_address, destination=destination_address, asset_code=settings['ASSET_CODE'], asset_issuer=settings['ISSUER'], amount=hot_amount, ) try: unsigned_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 unsigned_xdr, tx_hash
def test_import_from_xdr(self, setup, test_data): builder = Builder(secret=test_data.cold_secret, sequence=1, horizon_uri=setup.horizon_endpoint_uri, network=setup.network) \ .append_manage_data_op("hello", "world") \ .add_time_bounds({'minTime': 1534392138, 'maxTime': 1534392238}) builder.sign() old_xdr = builder.gen_xdr() old_hash = builder.hash() new_hash = Builder( secret=test_data.cold_secret).import_from_xdr(old_xdr).hash() assert new_hash == old_hash
def test_import_from_xdr_custom_network(self, setup, test_data): builder = Builder(secret=test_data.cold_secret, sequence=1, horizon_uri=setup.horizon_endpoint_uri, network='CUSTOM_NETWORK') \ .append_manage_data_op("hello", "world") builder.sign() old_xdr = builder.gen_xdr() old_hash = builder.hash() new_hash = Builder( secret=test_data.cold_secret, network='CUSTOM_NETWORK').import_from_xdr(old_xdr).hash() assert new_hash == old_hash
def create_signed_tx(private_key, to_address, amount, network='PUBLIC', memo=None): amount = round(amount, 7) builder = Builder(secret=private_key, network=network) builder.append_payment_op(to_address, amount, 'XLM') if memo: builder.add_text_memo(memo) builder.sign() return builder.gen_xdr().decode()
def test_verify_challenge_tx_sequence_not_zero(self): server_kp = Keypair.random() client_kp = Keypair.random() challenge = Builder(server_kp.seed().decode(), sequence=10086, fee=100) challenge.sign() challenge_tx_server_signed = challenge.gen_xdr() transaction = Builder( client_kp.seed().decode(), network='Public Global Stellar Network ; September 2015', sequence=0, fee=100) transaction.import_from_xdr(challenge_tx_server_signed) transaction.sign() challenge_tx = transaction.gen_xdr() with pytest.raises( InvalidSep10ChallengeError, match="The transaction sequence number should be zero."): Builder.verify_challenge_tx( challenge_tx, server_kp.address().decode(), 'Public Global Stellar Network ; September 2015')
def test_verify_challenge_tx_not_within_range_of_the_specified_timebounds( self): server_kp = Keypair.random() client_kp = Keypair.random() timeout = 600 network = 'TESTNET' archor_name = 'sdf' challenge = Builder(server_kp.seed().decode(), network=network, sequence=-1, fee=100) now = int(time.time()) challenge.add_time_bounds({'minTime': now - 100, 'maxTime': now - 20}) nonce = os.urandom(64) challenge.append_manage_data_op( data_name='{} auth'.format(archor_name), data_value=nonce, source=client_kp.address().decode()) challenge.sign() challenge_tx_server_signed = challenge.gen_xdr() transaction = Builder(client_kp.seed().decode(), network='TESTNET', sequence=0, fee=100) transaction.import_from_xdr(challenge_tx_server_signed) transaction.sign() challenge_tx = transaction.gen_xdr() with pytest.raises( InvalidSep10ChallengeError, match= "Transaction is not within range of the specified timebounds." ): Builder.verify_challenge_tx(challenge_tx, server_kp.address().decode(), 'TESTNET')
async def build_generate_merge_transaction( transaction_source_address: str, wallet_detail: Dict, parties_wallet: List = None, sequence: str = None ) -> Tuple[Any, str]: """ Builder transaction close escrow wallet by payment remaining HOT from escrow_wallet to provider_wallet and merge account from escrow_wallet to creator_wallet, Finally, return xdr and transaction_hash Args: escrow_wallet: escrow wallet response from get_escrow_wallet_detail parties_walles : list of provider address and amount for payback """ wallet_address = wallet_detail['escrow_address'] wallet_data = wallet_detail['data'] creator_address = ( wallet_data['creator_address'] if wallet_data and 'creator_address' in wallet_data.keys() else await get_creator_address(wallet_address) ) builder = Builder( address=transaction_source_address, horizon=settings['HORIZON_URL'], network=settings['PASSPHRASE'], sequence=sequence, ) if not parties_wallet: parties_wallet = await generate_parties_wallet(wallet_detail) balance = Decimal(wallet_detail['asset'][settings['ASSET_CODE']]) if not await is_match_balance(parties_wallet, balance): raise web.HTTPBadRequest(reason='Total amount not match wallet balance') await build_payment_operation(builder, wallet_address, parties_wallet) await build_remove_trustlines_operation(builder, wallet_address) await build_remove_manage_data_operation(builder, wallet_address, wallet_data.keys()) await build_account_merge_operation(builder, wallet_address, creator_address) 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()
def signsend(text): cont = session.prompt(u'You want to sign or send? (sign/send) > ') data = text.split()[1] if cont.lower() == 'sign': print(' signing ' + data) sign = Builder(CONF['private_key'], network=CONF['network']) sign.import_from_xdr(data) #key = session.prompt(u'Enter who you sign for? %s > ' % CONF['multisig']) sign.sign() print("send this to the other wallet and ask them to signsend it\n") print(sign.gen_xdr()) return print(' signing and sending ' + data) c = Builder(CONF['private_key'], network=CONF['network']) c.import_from_xdr(data) c.sign() data = c.submit() print(data) return
def test_builder_append_ops(self): alice_secret = 'SDIMY25XL2TDSUZNM42Y2WLA2E2R52EV3GR6MXCPVTBSWJLN6MLX6JZV' bob_account = 'GBZ5VJD6VMQMRDSMCCZAF23K5VIGBHXJQQYLLYQOEIZB4AUJNMFN5R3U' builder = Builder(secret=alice_secret, sequence=938635037769728, fee=100) builder. \ append_create_account_op(destination=bob_account, starting_balance='10'). \ append_change_trust_op(asset_code='BEER', asset_issuer=bob_account, limit='1000'). \ append_payment_op(destination=bob_account, asset_code='XLM', amount='100'). \ append_path_payment_op(destination=bob_account, send_code='BEER', send_issuer=bob_account, send_max='100', dest_code='XLM', dest_issuer=None, dest_amount='100', path=[('HELLO', bob_account)]). \ append_allow_trust_op(trustor=bob_account, asset_code='MOE', authorize=True). \ append_set_options_op(set_flags=7, home_domain='stellar.org'). \ append_hashx_signer( hashx=b"\xe7\xd40j:>pH\xa0\x11\x90(q\x88\xa0IV\xf6\xa9\xc90\x15H&\xeb\xcd\x03\t\x93\x1f'8", signer_weight=1). \ append_pre_auth_tx_signer( pre_auth_tx=b"\x95\xe5\xbb\x95\x15\xd9\x9f\x82\x9d\xf9\x93\xc3'\x8e\xeb\xf1\nj!\xda\xa4\xa1\xe4\xf2<6cG}\x17\x97\xfe", signer_weight=1). \ append_manage_sell_offer_op(selling_code='XLM', selling_issuer=None, buying_code='BEER', buying_issuer=bob_account, amount='1', price='10', offer_id=0). \ append_manage_buy_offer_op(selling_code='XLM', selling_issuer=None, buying_code='BEER', buying_issuer=bob_account, amount='1', price='10', offer_id=0). \ append_create_passive_sell_offer_op(selling_code='XLM', selling_issuer=None, buying_code='BEER', buying_issuer=bob_account, amount='1', price={'n': 10, 'd': 1}). \ append_account_merge_op(destination=bob_account). \ append_inflation_op(). \ append_manage_data_op(data_name='hello', data_value='world'). \ append_bump_sequence_op(bump_to=938635037769749). \ add_text_memo("hello, stellar"). \ add_time_bounds({'minTime': 1534392138, 'maxTime': 1534392238}) assert builder.hash_hex( ) == 'f646a891ed9ecde6f98bf7fb1afcb52acbc73aabd08f9390c61fdfc8f426815f' builder.sign() assert builder.gen_xdr().decode( ) == 'AAAAAP4sA2cn9oggk4cfzPLqZVfpSEhmindW2FQofl5b0SjDAAAF3AADVa8AAAABAAAAAQAAAABbdPdKAAAAAFt0964AAAABAAAADmhlbGxvLCBzdGVsbGFyAAAAAAAPAAAAAAAAAAAAAAAAc9qkfqsgyI5MELIC62rtUGCe6YQwteIOIjIeAolrCt4AAAAABfXhAAAAAAAAAAAGAAAAAUJFRVIAAAAAc9qkfqsgyI5MELIC62rtUGCe6YQwteIOIjIeAolrCt4AAAACVAvkAAAAAAAAAAABAAAAAHPapH6rIMiOTBCyAutq7VBgnumEMLXiDiIyHgKJawreAAAAAAAAAAA7msoAAAAAAAAAAAIAAAABQkVFUgAAAABz2qR+qyDIjkwQsgLrau1QYJ7phDC14g4iMh4CiWsK3gAAAAA7msoAAAAAAHPapH6rIMiOTBCyAutq7VBgnumEMLXiDiIyHgKJawreAAAAAAAAAAA7msoAAAAAAQAAAAJIRUxMTwAAAAAAAAAAAAAAc9qkfqsgyI5MELIC62rtUGCe6YQwteIOIjIeAolrCt4AAAAAAAAABwAAAABz2qR+qyDIjkwQsgLrau1QYJ7phDC14g4iMh4CiWsK3gAAAAFNT0UAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAABAAAABwAAAAAAAAAAAAAAAAAAAAAAAAABAAAAC3N0ZWxsYXIub3JnAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAALn1DBqOj5wSKARkChxiKBJVvapyTAVSCbrzQMJkx8nOAAAAAEAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAGV5buVFdmfgp35k8MnjuvxCmoh2qSh5PI8NmNHfReX/gAAAAEAAAAAAAAAAwAAAAAAAAABQkVFUgAAAABz2qR+qyDIjkwQsgLrau1QYJ7phDC14g4iMh4CiWsK3gAAAAAAmJaAAAAACgAAAAEAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAFCRUVSAAAAAHPapH6rIMiOTBCyAutq7VBgnumEMLXiDiIyHgKJawreAAAAAACYloAAAAAKAAAAAQAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAUJFRVIAAAAAc9qkfqsgyI5MELIC62rtUGCe6YQwteIOIjIeAolrCt4AAAAAAJiWgAAAAAoAAAABAAAAAAAAAAgAAAAAc9qkfqsgyI5MELIC62rtUGCe6YQwteIOIjIeAolrCt4AAAAAAAAACQAAAAAAAAAKAAAABWhlbGxvAAAAAAAAAQAAAAV3b3JsZAAAAAAAAAAAAAALAANVrwAAABUAAAAAAAAAAVvRKMMAAABAM1rhFzh2mbT283+lJsqeckCxnO9vC0m8ADTbyUbFXNJNAfSpI23W/kS69wgeq8qp/1knDpkn72b6e6Eac9coCw=='
def build_generate_wallet_transaction(transaction_source_address: str, source_address: str, destination_address: str, amount: Decimal, sequence=None) -> Tuple[bytes, bytes]: """"Build transaction return unsigned XDR and transaction hash. Args: transaction_source_address: Owner of the transactoin source_address: Owner of creator wallet destination_address: wallet id of new wallet amount: starting balance of new wallet """ builder = Builder( address=transaction_source_address, horizon=settings['HORIZON_URL'], network=settings['PASSPHRASE'], sequence=sequence, ) try: builder.append_create_account_op(source=source_address, destination=destination_address, starting_balance=amount) except DecodeError: raise web.HTTPBadRequest(reason='Parameter values are not valid.') except Exception as e: msg = str(e) raise web.HTTPInternalServerError(reason=msg) try: unsigned_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 unsigned_xdr, tx_hash
def test_builder_append_ops(self): alice_secret = 'SDIMY25XL2TDSUZNM42Y2WLA2E2R52EV3GR6MXCPVTBSWJLN6MLX6JZV' bob_account = 'GBZ5VJD6VMQMRDSMCCZAF23K5VIGBHXJQQYLLYQOEIZB4AUJNMFN5R3U' builder = Builder(secret=alice_secret, sequence=938635037769728, fee=100) builder. \ append_create_account_op(destination=bob_account, starting_balance='10'). \ append_change_trust_op(asset_code='BEER', asset_issuer=bob_account, limit='1000'). \ append_payment_op(destination=bob_account, asset_code='XLM', amount='100'). \ append_path_payment_op(destination=bob_account, send_code='BEER', send_issuer=bob_account, send_max='100', dest_code='XLM', dest_issuer=None, dest_amount='100', path=[('HELLO', bob_account)]). \ append_allow_trust_op(trustor=bob_account, asset_code='MOE', authorize=True). \ append_set_options_op(set_flags=7, home_domain='stellar.org'). \ append_hashx_signer( hashx=b"\xe7\xd40j:>pH\xa0\x11\x90(q\x88\xa0IV\xf6\xa9\xc90\x15H&\xeb\xcd\x03\t\x93\x1f'8", signer_weight=1). \ append_pre_auth_tx_signer( pre_auth_tx=b"\x95\xe5\xbb\x95\x15\xd9\x9f\x82\x9d\xf9\x93\xc3'\x8e\xeb\xf1\nj!\xda\xa4\xa1\xe4\xf2<6cG}\x17\x97\xfe", signer_weight=1). \ append_manage_offer_op(selling_code='XLM', selling_issuer=None, buying_code='BEER', buying_issuer=bob_account, amount='1', price='10', offer_id=0). \ append_create_passive_offer_op(selling_code='XLM', selling_issuer=None, buying_code='BEER', buying_issuer=bob_account, amount='1', price={'n': 10, 'd': 1}). \ append_account_merge_op(destination=bob_account). \ append_inflation_op(). \ append_manage_data_op(data_name='hello', data_value='world'). \ append_bump_sequence_op(bump_to=938635037769749). \ add_text_memo("hello, stellar"). \ add_time_bounds({'minTime': 1534392138, 'maxTime': 1534392238}) assert builder.hash_hex( ) == '82910e59edebeeafc86294372572812a251066ad1f0784e1e38ca63d3b6bdf24' builder.sign() assert builder.gen_xdr().decode( ) == 'AAAAAP4sA2cn9oggk4cfzPLqZVfpSEhmindW2FQofl5b0SjDAAAFeAADVa8AAAABAAAAAQAAAABbdPdKAAAAAFt0964AAAABAAAADmhlbGxvLCBzdGVsbGFyAAAAAAAOAAAAAAAAAAAAAAAAc9qkfqsgyI5MELIC62rtUGCe6YQwteIOIjIeAolrCt4AAAAABfXhAAAAAAAAAAAGAAAAAUJFRVIAAAAAc9qkfqsgyI5MELIC62rtUGCe6YQwteIOIjIeAolrCt4AAAACVAvkAAAAAAAAAAABAAAAAHPapH6rIMiOTBCyAutq7VBgnumEMLXiDiIyHgKJawreAAAAAAAAAAA7msoAAAAAAAAAAAIAAAABQkVFUgAAAABz2qR+qyDIjkwQsgLrau1QYJ7phDC14g4iMh4CiWsK3gAAAAA7msoAAAAAAHPapH6rIMiOTBCyAutq7VBgnumEMLXiDiIyHgKJawreAAAAAAAAAAA7msoAAAAAAQAAAAJIRUxMTwAAAAAAAAAAAAAAc9qkfqsgyI5MELIC62rtUGCe6YQwteIOIjIeAolrCt4AAAAAAAAABwAAAABz2qR+qyDIjkwQsgLrau1QYJ7phDC14g4iMh4CiWsK3gAAAAFNT0UAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAABAAAABwAAAAAAAAAAAAAAAAAAAAAAAAABAAAAC3N0ZWxsYXIub3JnAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAALn1DBqOj5wSKARkChxiKBJVvapyTAVSCbrzQMJkx8nOAAAAAEAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAGV5buVFdmfgp35k8MnjuvxCmoh2qSh5PI8NmNHfReX/gAAAAEAAAAAAAAAAwAAAAAAAAABQkVFUgAAAABz2qR+qyDIjkwQsgLrau1QYJ7phDC14g4iMh4CiWsK3gAAAAAAmJaAAAAACgAAAAEAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAFCRUVSAAAAAHPapH6rIMiOTBCyAutq7VBgnumEMLXiDiIyHgKJawreAAAAAACYloAAAAAKAAAAAQAAAAAAAAAIAAAAAHPapH6rIMiOTBCyAutq7VBgnumEMLXiDiIyHgKJawreAAAAAAAAAAkAAAAAAAAACgAAAAVoZWxsbwAAAAAAAAEAAAAFd29ybGQAAAAAAAAAAAAACwADVa8AAAAVAAAAAAAAAAFb0SjDAAAAQOeOIQNAwscAcVIdCHVou6xILLKBJTqxqmXiOxxtD4pYVsl0G2tLoDrMfcoWkSb7eyj3c68SIWNZRZEvWyusNwM='
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 genptxs( systemdb, timestamp): """generates contract ptxs 1-3 given systemdb, including a contract manifest in production, will add ptxs will be hosted along with manifest on e.g. IPFS """ q = Query() a_sk = systemdb.search(q.name == 'Contract')[0]['sk'] a_pk = systemdb.search(q.name == 'Contract')[0]['pk'] pr_pk = systemdb.search(q.name == 'Printer')[0]['pk'] pi_pk = systemdb.search(q.name == 'Pipe')[0]['pk'] UND = systemdb.search(q.type == 'manifest')[0]['UND'] UND_pk = systemdb.search(q.type == 'manifest')[0]['UND_source'] QUO = systemdb.search(q.type == 'manifest')[0]['QUO'] QUO_pk = systemdb.search(q.type == 'manifest')[0]['QUO_source'] strike = systemdb.search(q.type == 'manifest')[0]['strike'] size = systemdb.search(q.type == 'manifest')[0]['size'] address = Address(address=a_pk, network='TESTNET') address.get() ####2 PREAUTH TX ONE ##### b = Builder( secret = str(a_sk), horizon_uri = 'https://horizon.stellar.org', network = 'TESTNET', sequence = int(address.sequence)+3) """seq incremented by two bc acct will need to add hash signer, data entry, and lock """ strikeXsize = str(int(strike)*int(size)) b.append_payment_op(pr_pk, '0.5', 'OCA', pr_pk) if QUO_pk == None: b.append_payment_op(pi_pk, strikeXsize, QUO, asset_issuer=None) else: b.append_payment_op(pi_pk, strikeXsize, QUO, QUO_pk) b.append_manage_offer_op('SPA', pr_pk, 'OCA', pr_pk, '0.0000001', '5000000', offer_id=0) b.append_manage_offer_op('GTA', pr_pk, 'SPA', pr_pk, '1', '0.0000001', offer_id=0) price = str(float(1)/int(size)) b.append_manage_offer_op(UND, UND_pk, 'GTA', pr_pk, str(size), price, offer_id=0) envelope1 = b.gen_te() hashish1 = envelope1.hash_meta() xdr1 = b.gen_xdr() systemdb.insert({ 'type': 'ptx', 'name': 'ptx1', 'xdr': xdr1 }) ####2 PREAUTH TX TWO ##### b2 = Builder( secret = a_sk, horizon_uri ='https://horizon.stellar.org', network = 'TESTNET', sequence = int(address.sequence)+3) b2.append_payment_op(pi_pk, str(strike), UND, UND_pk) b2.append_set_options_op(master_weight=1, low_threshold=0, med_threshold=0, high_threshold=0) envelope2 = b2.gen_te() hashish2 = envelope2.hash_meta() xdr2 = b2.gen_xdr() systemdb.insert({ 'type': 'ptx', 'name': 'ptx2', 'xdr': xdr2 }) ####2 PREAUTH TX THREE ##### b3 = Builder( secret = a_sk, horizon_uri ='https://horizon.stellar.org', network = 'TESTNET', sequence = int(address.sequence)+4) b3.append_set_options_op(master_weight=1, low_threshold=0, med_threshold=0, high_threshold=0) envelope3 = b3.gen_te() hashish3 = envelope3.hash_meta() xdr3 = b3.gen_xdr() systemdb.insert({ 'type': 'ptx', 'name': 'ptx3', 'xdr': xdr3 }) bX = Builder(secret = a_sk, network='TESTNET') bX.append_pre_auth_tx_signer(hashish1, 1, source=None) bX.append_pre_auth_tx_signer(hashish2, 1, source=None) bX.append_pre_auth_tx_signer(hashish3, 1, source=None) bX.sign() print bX.submit()
async def build_unsigned_transfer( transaction_source_address: str, source_address: str, destination_address: str, amount_hot: Decimal, amount_xlm: Decimal, tax_amount_hot: Decimal = None, sequence: int = None, memo_text: str = None, ) -> Tuple[str, str]: """"Build unsigned transfer transaction return unsigned XDR and transaction hash. Args: source_address: Owner of operation destination_address: wallet id of new wallet amount_hot: amount of hot that would be transfer amount_xlm: amount of xlm that would be transfer sequence: sequence number for generate transaction [optional] memo: memo text [optional] """ builder = Builder( address=transaction_source_address, sequence=sequence, horizon=settings['HORIZON_URL'], network=settings['PASSPHRASE'], ) wallet = await get_wallet_detail(destination_address) if amount_hot and not wallet['asset'].get(settings['ASSET_CODE'], False): raise web.HTTPBadRequest(reason="{} is not trusted {}".format( destination_address, settings['ASSET_CODE'])) if amount_xlm: builder.append_payment_op(destination_address, amount_xlm, source=source_address) if amount_hot and wallet['asset'].get(settings['ASSET_CODE'], False): builder.append_payment_op( destination_address, amount_hot, asset_code=settings['ASSET_CODE'], asset_issuer=settings['ISSUER'], source=source_address, ) if tax_amount_hot and Decimal(tax_amount_hot) > 0: builder.append_payment_op( settings['TAX_COLLECTOR_ADDRESS'], Decimal(tax_amount_hot), asset_code=settings['ASSET_CODE'], asset_issuer=settings['ISSUER'], source=source_address, ) if memo_text: builder.add_text_memo(memo_text) unsigned_xdr = builder.gen_xdr() tx_hash = builder.te.hash_meta() return unsigned_xdr.decode('utf8'), binascii.hexlify(tx_hash).decode()
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()
async def merge_account(main_address, tmp_address, tmp_seed): account = Builder(address=tmp_address, secret=tmp_seed) account.append_account_merge_op(destination=main_address) account.sign() return account.gen_xdr()
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()
network = "TESTNET" transactions_unsigned = [] with open("transactions.json", 'r') as tfile: transactions_unsigned = json.load(tfile) key = input("Signing Key: ") amt_signed = 0 needed = 3 transactions = [] for xdr in transactions_unsigned: builder = Builder(secret=key, network=network) builder.import_from_xdr(xdr) amt_signed = len(builder.te.signatures) + 1 builder.sign() transactions.append(builder.gen_xdr().decode("utf-8")) print("Added signature. Transactions now signed by %s/%s parties." % (str(amt_signed), str(needed))) if amt_signed >= needed: print("Submitting " + str(len(transactions)) + "transactions") i = 1 for xdr in transactions: try: response = horizon.submit(self.gen_xdr()) print("Transaction " + str(i) + " link: ", response["_links"]["transaction"]["href"]) i += 1 except Exception as e: raise e