def create_assets_for_distributing(amount): # Keys for accounts to issue and receive the new asset issuing_keypair = Keypair.from_secret(os.getenv("ISSUING_PRIVATE")) issuing_public = issuing_keypair.public_key issuing_account = server.load_account(issuing_public) distributor_keypair = Keypair.from_secret(os.getenv("DISTRIBUTOR_INRX_PRIVATE_KEY")) distributor_public = distributor_keypair.public_key distributor_account = server.load_account(distributor_public) inr_asset = Asset("INRx", issuing_public) payment_transaction = ( TransactionBuilder( source_account=issuing_account, network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE, base_fee=server.fetch_base_fee(), ) .append_change_trust_op(inr_asset.code, inr_asset.issuer, None, distributor_public) .append_payment_op( destination=distributor_public, amount=amount, asset_code=inr_asset.code, asset_issuer=inr_asset.issuer, ) .build() ) payment_transaction.sign(issuing_keypair) payment_transaction.sign(distributor_keypair) resp = server.submit_transaction(payment_transaction) pprint(resp) account_details = server.accounts().account_id(distributor_public).call() print("\n\ndistributor new balance: ", account_details["balances"][0]["balance"], inr_asset.code)
def test_already_signed_raise(self): # GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM source = Keypair.from_secret( "SCCS5ZBI7WVIJ4SW36WGOQQIWJYCL3VOAULSXX3FB57USIO25EDOYQHH") destination = "GDJJRRMBK4IWLEPJGIE6SXD2LP7REGZODU7WDC3I2D6MR37F4XSHBKX2" amount = "1000.0" sequence = 1 memo = IdMemo(100) fee = 200 asset = Asset.native() time_bounds = TimeBounds(12345, 56789) ops = [ Payment(destination, asset, amount), ManageData("hello", "world") ] tx = Transaction(source, sequence, fee, ops, memo, time_bounds) network = Network.public_network() te = TransactionEnvelope(tx, network) assert binascii.hexlify(te.hash()).decode() == te.hash_hex() # te.sign(source) te.sign("SCCS5ZBI7WVIJ4SW36WGOQQIWJYCL3VOAULSXX3FB57USIO25EDOYQHH") hashx = bytes.fromhex( "94e8223a518ac16a8cb110ab1952ef14da2c10b264645c38c8b3d82bd2b20000") te.sign_hashx(hashx) with pytest.raises(SignatureExistError, match="The keypair has already signed."): te.sign(source) with pytest.raises(SignatureExistError, match="The preimage has already signed."): te.sign_hashx(hashx)
def test_good_withdrawal_integration(client, acc1_usd_withdrawal_transaction_factory): withdraw = acc1_usd_withdrawal_transaction_factory( protocol=Transaction.PROTOCOL.sep6) response = client.get( WITHDRAW_PATH, { "asset_code": withdraw.asset.code, "type": "bank_account", "dest": "test bank account number", }, ) content = json.loads(response.content) assert response.status_code == 200 assert content.pop("memo") assert content.pop("memo_type") == Transaction.MEMO_TYPES.hash assert content == { "account_id": Keypair.from_secret(USD_DISTRIBUTION_SEED).public_key, "min_amount": round(withdraw.asset.withdrawal_min_amount, withdraw.asset.significant_decimals), "max_amount": round(withdraw.asset.withdrawal_max_amount, withdraw.asset.significant_decimals), "fee_fixed": round(withdraw.asset.withdrawal_fee_fixed, withdraw.asset.significant_decimals), "fee_percent": withdraw.asset.withdrawal_fee_percent, "extra_info": { "test": "test" }, }
def sign_challenge(content): envelope_xdr = content["transaction"] envelope_object = TransactionEnvelope.from_xdr( envelope_xdr, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE) client_signing_key = Keypair.from_secret(CLIENT_SEED) envelope_object.sign(client_signing_key) return envelope_object.to_xdr()
def test_withdraw_authenticated_success( client, acc1_usd_withdrawal_transaction_factory): """`GET /withdraw` succeeds with the SEP 10 authentication flow.""" client_address = "GDKFNRUATPH4BSZGVFDRBIGZ5QAFILVFRIRYNSQ4UO7V2ZQAPRNL73RI" client_seed = "SDKWSBERDHP3SXW5A3LXSI7FWMMO5H7HG33KNYBKWH2HYOXJG2DXQHQY" acc1_usd_withdrawal_transaction_factory() # SEP 10. response = client.get(f"/auth?account={client_address}", follow=True) content = json.loads(response.content) envelope_xdr = content["transaction"] envelope_object = TransactionEnvelope.from_xdr( envelope_xdr, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE) client_signing_key = Keypair.from_secret(client_seed) envelope_object.sign(client_signing_key) client_signed_envelope_xdr = envelope_object.to_xdr() response = client.post( "/auth", data={"transaction": client_signed_envelope_xdr}, content_type="application/json", ) content = json.loads(response.content) encoded_jwt = content["token"] assert encoded_jwt header = {"HTTP_AUTHORIZATION": f"Bearer {encoded_jwt}"} response = client.post(WITHDRAW_PATH, {"asset_code": "USD"}, follow=True, **header) content = json.loads(response.content) assert content["type"] == "interactive_customer_info_needed"
def test_can_sign(self): can_sign_kp = Keypair.from_secret( "SD7X7LEHBNMUIKQGKPARG5TDJNBHKC346OUARHGZL5ITC6IJPXHILY36") can_not_sign_kp = Keypair.from_public_key( "GAXDYNIBA5E4DXR5TJN522RRYESFQ5UNUXHIPTFGVLLD5O5K552DF5ZH") assert can_sign_kp.can_sign() is True assert can_not_sign_kp.can_sign() is False
def distribution_account(self): """ The Stellar public key derived from `Asset.distribution_seed` """ if not self.distribution_seed: return None return Keypair.from_secret(str(self.distribution_seed)).public_key
def test_create_from_secret(self): secret = "SD7X7LEHBNMUIKQGKPARG5TDJNBHKC346OUARHGZL5ITC6IJPXHILY36" kp = Keypair.from_secret(secret) assert isinstance(kp, Keypair) assert (kp.public_key == "GDFQVQCYYB7GKCGSCUSIQYXTPLV5YJ3XWDMWGQMDNM4EAXAL7LITIBQ7") assert kp.secret == secret
def test_withdrawal_transaction_created( client, acc1_usd_withdrawal_transaction_factory ): withdraw = acc1_usd_withdrawal_transaction_factory( protocol=Transaction.PROTOCOL.sep6 ) distribution_address = Keypair.from_secret(USD_DISTRIBUTION_SEED).public_key response = client.get( WITHDRAW_PATH, {"asset_code": withdraw.asset.code, "type": "good type", "dest": "test",}, ) assert response.status_code == 200 t = ( Transaction.objects.filter(kind=Transaction.KIND.withdrawal) .order_by("-started_at") .first() ) assert t assert t.memo_type == Transaction.MEMO_TYPES.hash assert t.receiving_anchor_account == distribution_address assert t.stellar_account == "test source address" assert not t.amount_in assert t.asset == withdraw.asset assert t.kind == Transaction.KIND.withdrawal assert t.status == Transaction.STATUS.pending_user_transfer_start assert t.protocol == Transaction.PROTOCOL.sep6
def test_to_xdr(self): # GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM source = Keypair.from_secret( "SCCS5ZBI7WVIJ4SW36WGOQQIWJYCL3VOAULSXX3FB57USIO25EDOYQHH") destination = "GDJJRRMBK4IWLEPJGIE6SXD2LP7REGZODU7WDC3I2D6MR37F4XSHBKX2" amount = "1000.0" sequence = 1 memo = IdMemo(100) fee = 200 asset = Asset.native() time_bounds = TimeBounds(12345, 56789) ops = [ Payment(destination, asset, amount), ManageData("hello", "world") ] tx = Transaction(source, sequence, fee, ops, memo, time_bounds) network = Network.public_network() te = TransactionEnvelope(tx, network) assert binascii.hexlify(te.hash()).decode() == te.hash_hex() te.sign(source) hashx = bytes.fromhex( "94e8223a518ac16a8cb110ab1952ef14da2c10b264645c38c8b3d82bd2b20000") te.sign_hashx(hashx) te_xdr = "AAAAAMvXcdYjKhx0qxnsDsczxKuqa/65lZz6sjjHHczyh50JAAAAyAAAAAAAAAABAAAAAQAAAAAAADA5AAAAAAAA3dUAAAACAAAAAAAAAGQAAAACAAAAAAAAAAEAAAAA0pjFgVcRZZHpMgnpXHpb/xIbLh0/YYto0PzI7+Xl5HAAAAAAAAAAAlQL5AAAAAAAAAAACgAAAAVoZWxsbwAAAAAAAAEAAAAFd29ybGQAAAAAAAAAAAAAAvKHnQkAAABAM4dg0J1LEFBmbDESJ5d+60WCuZC8lnA80g45qyEgz2oRBSNw1mOfZETnL/BgrebkG/K03oI2Wqcs9lvDKrDGDE0sOBsAAAAglOgiOlGKwWqMsRCrGVLvFNosELJkZFw4yLPYK9KyAAA=" assert te.to_xdr() == te_xdr restore_te = TransactionEnvelope.from_xdr(te_xdr, network) assert restore_te.to_xdr() == te_xdr
def test_sign_and_verify(self): kp = Keypair.from_secret( "SAQVS3IPN6U3TBMTXQH32ZESY7SUOZGLEFBH6XWMA6DVNPJ4CLO5M54B") data = b"Hello, overcat!" signature = kp.sign(data) assert ( signature.hex() == "ff7c4346977144019e7be0c12c033e99f412e70361924e298e6152dd924c88f2" "725c60c56067f20c35a8ff29c936b983f652b4df2d9de8f2851605df2f680c06") kp.verify(data, signature)
def test_verify_failed_raise(self): kp = Keypair.from_secret( "SAQVS3IPN6U3TBMTXQH32ZESY7SUOZGLEFBH6XWMA6DVNPJ4CLO5M54B") data = b"Hello, Stellar!" signature = kp.sign(data) with pytest.raises(BadSignatureError, match="Signature verification failed."): kp.verify(data, signature + b"failed") with pytest.raises(BadSignatureError, match="Signature verification failed."): kp.verify(b"test_verify_failed", signature)
def test_transaction_authenticated_success( mock_render, client, acc1_usd_deposit_transaction_factory, acc2_eth_withdrawal_transaction_factory, ): """ Succeeds with expected response if authentication required. Though it filters using the stellar transaction ID, the logic should apply in any case. """ del mock_render client_address = "GDKFNRUATPH4BSZGVFDRBIGZ5QAFILVFRIRYNSQ4UO7V2ZQAPRNL73RI" client_seed = "SDKWSBERDHP3SXW5A3LXSI7FWMMO5H7HG33KNYBKWH2HYOXJG2DXQHQY" acc1_usd_deposit_transaction_factory() withdrawal = acc2_eth_withdrawal_transaction_factory() withdrawal.stellar_address = client_address withdrawal.save() # SEP 10. response = client.get(f"/auth?account={client_address}", follow=True) content = json.loads(response.content) envelope_xdr = content["transaction"] envelope_object = TransactionEnvelope.from_xdr( envelope_xdr, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE) client_signing_key = Keypair.from_secret(client_seed) envelope_object.sign(client_signing_key) client_signed_envelope_xdr = envelope_object.to_xdr() response = client.post( "/auth", data={"transaction": client_signed_envelope_xdr}, content_type="application/json", ) content = json.loads(response.content) encoded_jwt = content["token"] assert encoded_jwt # For testing, we make the key `HTTP_AUTHORIZATION`. This is the value that # we expect due to the middleware. header = {"HTTP_AUTHORIZATION": f"Bearer {encoded_jwt}"} response = client.get( f"/transaction?stellar_transaction_id={withdrawal.stellar_transaction_id}", follow=True, **header, ) content = json.loads(response.content) assert response.status_code == 200 withdrawal_transaction = content.get("transaction") assert withdrawal_transaction["kind"] == "withdrawal" assert withdrawal_transaction["status"] == Transaction.STATUS.completed
def rewardUser(uid, amount): """ Reward the user by increasing his karma points via blockchain """ server = Server("https://horizon-testnet.stellar.org") source_key = Keypair.from_secret( "SA6HHDJ5KZKYFZVOOGHENIPVKV2HGKICN4RYQ2UZNZHZP7ZIYSQIQDCI") destination_id = "GA4QPSGBHK7RAJZBBEDCIKFPSYLG3O2UTBT2I56RN4B5KIQF2GFZKSMF" # First, check to make sure that the destination account exists. # You could skip this, but if the account does not exist, you will be charged # the transaction fee when the transaction fails. try: server.load_account(destination_id) except NotFoundError: # If the account is not found, surface an error message for logging. raise Exception("The destination account does not exist!") # If there was no error, load up-to-date information on your account. source_account = server.load_account(source_key.public_key) # Let's fetch base_fee from network base_fee = server.fetch_base_fee() # Start building the transaction. transaction = ( TransactionBuilder( source_account=source_account, network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE, base_fee=base_fee, ) # Because Stellar allows transaction in many currencies, you must specify the asset type. # Here we are sending Lumens. .append_payment_op(destination=destination_id, amount="10", asset_code="XLM") # A memo allows you to add your own metadata to a transaction. It's # optional and does not affect how Stellar treats the transaction. .add_text_memo("Test Transaction") # Wait a maximum of three minutes for the transaction .set_timeout(10).build()) # Sign the transaction to prove you are actually the person sending it. transaction.sign(source_key) try: # And finally, send it off to Stellar! response = server.submit_transaction(transaction) print(f"Response: {response}") except (BadRequestError, BadResponseError) as err: print(f"Something went wrong!\n{err}") return None
def test_transactions_authenticated_success( mock_render, client, acc2_eth_withdrawal_transaction_factory, acc2_eth_deposit_transaction_factory, ): """ Response has correct length and status code, if the SEP 10 authentication token is required. """ del mock_render client_address = "GDKFNRUATPH4BSZGVFDRBIGZ5QAFILVFRIRYNSQ4UO7V2ZQAPRNL73RI" client_seed = "SDKWSBERDHP3SXW5A3LXSI7FWMMO5H7HG33KNYBKWH2HYOXJG2DXQHQY" withdrawal = acc2_eth_withdrawal_transaction_factory() withdrawal.stellar_address = client_address withdrawal.save() acc2_eth_deposit_transaction_factory() # SEP 10. response = client.get(f"/auth?account={client_address}", follow=True) content = json.loads(response.content) envelope_xdr = content["transaction"] envelope_object = TransactionEnvelope.from_xdr( envelope_xdr, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE) client_signing_key = Keypair.from_secret(client_seed) envelope_object.sign(client_signing_key) client_signed_envelope_xdr = envelope_object.to_xdr() response = client.post( "/auth", data={"transaction": client_signed_envelope_xdr}, content_type="application/json", ) content = json.loads(response.content) encoded_jwt = content["token"] assert encoded_jwt # For testing, we make the key `HTTP_AUTHORIZATION`. This is the value that # we expect due to the middleware. header = {"HTTP_AUTHORIZATION": f"Bearer {encoded_jwt}"} response = client.get( f"/transactions?asset_code={withdrawal.asset.code}&account={withdrawal.stellar_account}", follow=True, **header, ) content = json.loads(response.content) assert len(content.get("transactions")) == 2 assert response.status_code == 200
def create_usd_asset(protocols: Optional[List[str]] = None): """ Creates a test USD asset that composes the example /info response, according to https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#response-2 """ if not protocols: protocols = [Transaction.PROTOCOL.sep24] usd_asset = Asset( code="USD", issuer=USD_ISSUER_ACCOUNT, distribution_seed=USD_DISTRIBUTION_SEED, distribution_account_signers=json.dumps({ "key": Keypair.from_secret(USD_DISTRIBUTION_SEED).public_key, "weight": 1, "type": "ed25519_public_key", }), distribution_account_thresholds=json.dumps({ "low_threshold": 0, "med_threshold": 1, "high_threshold": 1 }), significant_decimals=2, # Deposit Info deposit_enabled=True, deposit_fee_fixed=5, deposit_fee_percent=1, deposit_min_amount=0.1, deposit_max_amount=1000, # Withdrawal Info withdrawal_enabled=True, withdrawal_fee_fixed=5, withdrawal_fee_percent=0, withdrawal_min_amount=0.1, withdrawal_max_amount=1000, # Send info send_fee_fixed=5, send_fee_percent=0, send_min_amount=0.1, send_max_amount=1000, ) for p in protocols: setattr(usd_asset, p + "_enabled", True) usd_asset.save() return usd_asset
def test_set_keypair_raise(self): secret = "SD7X7LEHBNMUIKQGKPARG5TDJNBHKC346OUARHGZL5ITC6IJPXHILY36" kp = Keypair.from_secret(secret) with pytest.raises( AttributeError, match= "Please use `Keypair.from_secret` to generate a new Keypair object.", ): kp.secret = "SAMWF63FZ5ZNHY75SNYNAFMWTL5FPBMIV7DLB3UDAVLL7DKPI5ZFS2S6" with pytest.raises( AttributeError, match= "Please use `Keypair.from_public_key` to generate a new Keypair object.", ): kp.public_key = "GAXDYNIBA5E4DXR5TJN522RRYESFQ5UNUXHIPTFGVLLD5O5K552DF5ZH"
def test_withdraw_empty_integration_response(client, usd_asset_factory): asset = usd_asset_factory(protocols=[Transaction.PROTOCOL.sep6]) response = client.get( WITHDRAW_PATH, {"asset_code": asset.code, "type": "good type", "dest": "test"}, ) content = json.loads(response.content) assert response.status_code == 200 assert content.pop("memo") assert content.pop("memo_type") == Transaction.MEMO_TYPES.hash assert content == { "id": str(Transaction.objects.first().id), "account_id": Keypair.from_secret(USD_DISTRIBUTION_SEED).public_key, "min_amount": round(asset.withdrawal_min_amount, asset.significant_decimals), "max_amount": round(asset.withdrawal_max_amount, asset.significant_decimals), "fee_fixed": round(asset.withdrawal_fee_fixed, asset.significant_decimals), "fee_percent": asset.withdrawal_fee_percent, }
def create_eth_asset(protocols: Optional[List[str]] = None): """ Creates a test ETH asset that composes the example /info response, according to https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md#response-2 """ signer = { "key": Keypair.from_secret(ETH_DISTRIBUTION_SEED).public_key, "weight": 1, "type": "ed25519_public_key", } if not protocols: protocols = [Transaction.PROTOCOL.sep24] eth_asset = Asset( code="ETH", issuer=ETH_ISSUER_ACCOUNT, distribution_seed=ETH_DISTRIBUTION_SEED, distribution_account_signers=[signer], distribution_account_thresholds={ "low_threshold": 0, "med_threshold": 1, "high_threshold": 1, }, distribution_account_master_signer=signer, # Deposit Info deposit_enabled=True, deposit_fee_fixed=0.002, deposit_fee_percent=0, deposit_min_amount=0.0, deposit_max_amount=10000000, # Withdrawal Info withdrawal_enabled=False, withdrawal_fee_fixed=0, withdrawal_fee_percent=0, withdrawal_min_amount=0, withdrawal_max_amount=0, # Send info send_fee_fixed=5, send_fee_percent=0, send_min_amount=0.1, send_max_amount=1000, ) for p in protocols: setattr(eth_asset, p + "_enabled", True) eth_asset.save() return eth_asset
def sep10(client, address, seed): response = client.get(f"/auth?account={address}", follow=True) content = json.loads(response.content) envelope_xdr = content["transaction"] envelope_object = TransactionEnvelope.from_xdr( envelope_xdr, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE) client_signing_key = Keypair.from_secret(seed) envelope_object.sign(client_signing_key) client_signed_envelope_xdr = envelope_object.to_xdr() response = client.post( "/auth", data={"transaction": client_signed_envelope_xdr}, headers={"Content-Type": "application/json"}, ) content = json.loads(response.content) encoded_jwt = content["token"] assert encoded_jwt return encoded_jwt
def test_auth_post_urlencode_success(client): """`POST <auth>` succeeds when given a proper URL-encoded transaction.""" response = client.get(f"/auth?account={CLIENT_ADDRESS}", follow=True) content = json.loads(response.content) # Sign the XDR with the client. envelope_xdr = content["transaction"] envelope_object = TransactionEnvelope.from_xdr( envelope_xdr, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE) client_signing_key = Keypair.from_secret(CLIENT_SEED) envelope_object.sign(client_signing_key) client_signed_envelope_xdr = envelope_object.to_xdr() response = client.post( "/auth", data=urlencode({"transaction": client_signed_envelope_xdr}), content_type="application/x-www-form-urlencoded", ) content = json.loads(response.content) assert content["token"]
def test_fee_authenticated_success(client, usd_asset_factory): """Succeeds for a valid fee, with successful authentication.""" from polaris.tests.auth_test import endpoint as auth_endpoint usd_asset_factory() client_address = "GDKFNRUATPH4BSZGVFDRBIGZ5QAFILVFRIRYNSQ4UO7V2ZQAPRNL73RI" client_seed = "SDKWSBERDHP3SXW5A3LXSI7FWMMO5H7HG33KNYBKWH2HYOXJG2DXQHQY" # SEP 10. response = client.get(f"{auth_endpoint}?account={client_address}", follow=True) content = json.loads(response.content) envelope_xdr = content["transaction"] envelope_object = TransactionEnvelope.from_xdr( envelope_xdr, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE) client_signing_key = Keypair.from_secret(client_seed) envelope_object.sign(client_signing_key) client_signed_envelope_xdr = envelope_object.to_xdr() response = client.post( auth_endpoint, data={"transaction": client_signed_envelope_xdr}, content_type="application/json", ) content = json.loads(response.content) encoded_jwt = content["token"] assert encoded_jwt # For testing, we make the key `HTTP_AUTHORIZATION`. This is the value that # we expect due to the middleware. header = {"HTTP_AUTHORIZATION": f"Bearer {encoded_jwt}"} response = client.get( f"{endpoint}?asset_code=USD&operation=withdraw&amount=100.0", follow=True, **header, ) content = json.loads(response.content) assert response.status_code == 200 assert content == {"fee": 5.0}
def test_to_xdr_v1(self): # GDF5O4OWEMVBY5FLDHWA5RZTYSV2U276XGKZZ6VSHDDR3THSQ6OQS7UM source = Keypair.from_secret( "SCCS5ZBI7WVIJ4SW36WGOQQIWJYCL3VOAULSXX3FB57USIO25EDOYQHH") destination = "GDJJRRMBK4IWLEPJGIE6SXD2LP7REGZODU7WDC3I2D6MR37F4XSHBKX2" amount = "1000.0" sequence = 1 memo = IdMemo(100) fee = 200 asset = Asset.native() time_bounds = TimeBounds(12345, 56789) ops = [Payment(destination, asset, amount)] tx = Transaction(source, sequence, fee, ops, memo, time_bounds, True) te = TransactionEnvelope(tx, Network.PUBLIC_NETWORK_PASSPHRASE) assert binascii.hexlify(te.hash()).decode() == te.hash_hex() te.sign(source) te_xdr = "AAAAAgAAAADL13HWIyocdKsZ7A7HM8Srqmv+uZWc+rI4xx3M8oedCQAAAMgAAAAAAAAAAQAAAAEAAAAAAAAwOQAAAAAAAN3VAAAAAgAAAAAAAABkAAAAAQAAAAAAAAABAAAAANKYxYFXEWWR6TIJ6Vx6W/8SGy4dP2GLaND8yO/l5eRwAAAAAAAAAAJUC+QAAAAAAAAAAAHyh50JAAAAQCXOQnmno3he687bKRtDc6+BXRUf8t+RnTuHy+sKf35UjfFiQbIge+txehmg0N61JsFWfwbL0JtgOjzyeZw5JAs=" assert te.to_xdr() == te_xdr restore_te = TransactionEnvelope.from_xdr( te_xdr, Network.PUBLIC_NETWORK_PASSPHRASE) assert restore_te.to_xdr() == te_xdr
) accepted_seps = ["sep-1", "sep-6", "sep-6", "sep-10", "sep-12", "sep-24", "sep-31"] ACTIVE_SEPS = env_or_settings("ACTIVE_SEPS", list=True) for i, sep in enumerate(ACTIVE_SEPS): if sep.lower() not in accepted_seps: raise ImproperlyConfigured( f"Unrecognized value in ACTIVE_SEPS list: {sep}; Accepted values: {accepted_seps}" ) ACTIVE_SEPS[i] = sep.lower() SIGNING_SEED, SIGNING_KEY = None, None if "sep-10" in ACTIVE_SEPS: SIGNING_SEED = env_or_settings("SIGNING_SEED") try: SIGNING_KEY = Keypair.from_secret(SIGNING_SEED).public_key except ValueError: raise ImproperlyConfigured("Invalid SIGNING_SEED") SERVER_JWT_KEY = None if any(sep in ACTIVE_SEPS for sep in ["sep-10", "sep-24"]): SERVER_JWT_KEY = env_or_settings("SERVER_JWT_KEY") STELLAR_NETWORK_PASSPHRASE = ( env_or_settings("STELLAR_NETWORK_PASSPHRASE", required=False) or "Test SDF Network ; September 2015" ) HORIZON_URI = ( env_or_settings("HORIZON_URI", required=False) or "https://horizon-testnet.stellar.org"
from stellar_sdk.account import Account from stellar_sdk.keypair import Keypair from stellar_sdk.network import Network from stellar_sdk.transaction_builder import TransactionBuilder inner_keypair = Keypair.from_secret( "SBKTIFHJSS3JJWEZO2W74DZSA45WZU56LOL3AY7GAW63BXPEJQFYV53E") inner_source = Account(inner_keypair.public_key, 7) destination = "GDQERENWDDSQZS7R7WKHZI3BSOYMV3FSWR7TFUYFTKQ447PIX6NREOJM" amount = "2000" inner_tx = (TransactionBuilder(inner_source, Network.TESTNET_NETWORK_PASSPHRASE, 200, v1=True).append_payment_op( destination=destination, amount=amount, asset_code="XLM").build()) inner_tx.sign(inner_keypair) fee_source = Keypair.from_secret( "SB7ZMPZB3YMMK5CUWENXVLZWBK4KYX4YU5JBXQNZSK2DP2Q7V3LVTO5V") base_fee = 200 fee_bump_tx = TransactionBuilder.build_fee_bump_transaction( fee_source.public_key, base_fee, inner_tx, Network.TESTNET_NETWORK_PASSPHRASE, ) fee_bump_tx.sign(fee_source)
def get_or_create_transaction_destination_account( transaction, ) -> Tuple[Optional[Account], bool, bool]: """ Returns the stellar_sdk.account.Account for which this transaction's payment will be sent to as as well as whether or not the account was created as a result of calling this function. If the account exists, the function simply returns the account and False. If the account doesn't exist, Polaris must create the account using an account provided by the anchor. Polaris can use the distribution account of the anchored asset or a channel account if the asset's distribution account requires non-master signatures. If the transacted asset's distribution account does not require non-master signatures, Polaris can create the destination account using the distribution account. On successful creation, this function will return the account and True. On failure, a RuntimeError exception is raised. If the transacted asset's distribution account does require non-master signatures, the anchor should save a keypair of a pre-existing Stellar account to use as the channel account via DepositIntegration.create_channel_account(). This channel account must only be used as the source account for transactions related to the ``Transaction`` object passed. It also must not be used to submit transactions by any service other than Polaris. If it is, the outstanding transactions will be invalidated due to bad sequence numbers. Finally, the channel accounts must have a master signer with a weight greater than or equal to the medium threshold for the account. After the transaction for creating the destination account has been submitted to the stellar network and the transaction has been created, this function will return the account and True. If the transaction was not submitted successfully, a RuntimeError exception will be raised. """ try: account, json_resp = get_account_obj( Keypair.from_public_key(transaction.stellar_account)) return account, False, has_trustline(transaction, json_resp) except RuntimeError: master_signer = None if transaction.asset.distribution_account_master_signer: master_signer = transaction.asset.distribution_account_master_signer thresholds = transaction.asset.distribution_account_thresholds if master_signer and master_signer["weight"] >= thresholds[ "med_threshold"]: source_account_kp = Keypair.from_secret( transaction.asset.distribution_seed) source_account, _ = get_account_obj(source_account_kp) else: from polaris.integrations import registered_deposit_integration as rdi rdi.create_channel_account(transaction) source_account_kp = Keypair.from_secret(transaction.channel_seed) source_account, _ = get_account_obj(source_account_kp) base_fee = settings.HORIZON_SERVER.fetch_base_fee() builder = TransactionBuilder( source_account=source_account, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE, base_fee=base_fee, ) transaction_envelope = builder.append_create_account_op( destination=transaction.stellar_account, starting_balance=settings.ACCOUNT_STARTING_BALANCE, ).build() transaction_envelope.sign(source_account_kp) try: settings.HORIZON_SERVER.submit_transaction(transaction_envelope) except BaseHorizonError as submit_exc: # pragma: no cover raise RuntimeError( "Horizon error when submitting create account to horizon: " f"{submit_exc.message}") transaction.status = Transaction.STATUS.pending_trust transaction.save() logger.info( f"Transaction {transaction.id} is now pending_trust of destination account" ) account, json_resp = get_account_obj( Keypair.from_public_key(transaction.stellar_account)) return account, True, has_trustline(transaction, json_resp) except BaseHorizonError as e: raise RuntimeError( f"Horizon error when loading stellar account: {e.message}")
def channel_account(self): if not self.channel_seed: return None return Keypair.from_secret(str(self.channel_seed)).public_key
# See: https://www.stellar.org/developers/guides/issuing-assets.html from stellar_sdk.keypair import Keypair from stellar_sdk.asset import Asset from stellar_sdk.transaction_builder import TransactionBuilder from stellar_sdk.server import Server from stellar_sdk.network import Network # Configure StellarSdk to talk to the horizon instance hosted by Stellar.org # To use the live network, set the hostname to 'horizon.stellar.org' server = Server(horizon_url="https://horizon-testnet.stellar.org") # Keys for accounts to issue and receive the new asset issuing_keypair = Keypair.from_secret( "SCBHQEGSNBTT4S7Y73YAF3M3JSVSTSNBGAVU5M4XVFGUF7664EUXQHFU") issuing_public = issuing_keypair.public_key distributor_keypair = Keypair.from_secret( "SB6MJ6M3BPJZUGFP2QCODUIKWQWF6AIN4Z6L3J6PWL3QGDW4L6YR3QIU") distributor_public = distributor_keypair.public_key # Transactions require a valid sequence number that is specific to this account. # We can fetch the current sequence number for the source account from Horizon. distributor_account = server.load_account(distributor_public) # Create an object to represent the new asset hello_asset = Asset("Hello", issuing_public) # First, the receiving account must trust the asset trust_transaction = (TransactionBuilder( source_account=distributor_account,
"memo_type": "hash", "source": "GC6Z5AIAP2IGNXB2QO4P34MQNP776H6LNIFBIP6C3IRGBHU5RQVSQ7XM", "paging_token": "2007270145658880", } SUCCESS_STRICT_SEND_PAYMENT = { "id": "00768d12b1753414316c9760993f3998868583121b5560b52a3bcf7dacf3dfc2", "successful": True, "envelope_xdr": "AAAAAgAAAAC9noEAfpBm3DqDuP3xkGv//x/LagoUP8LaImCenYwrKAAAAGQAByFhAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAh0ZXh0bWVtbwAAAAEAAAAAAAAADQAAAAFURVNUAAAAAL2egQB+kGbcOoO4/fGQa///H8tqChQ/wtoiYJ6djCsoAAAAAlSkeoAAAAAA0QNr+3v9HSAqKJT6bfuS/r+OXa68V5uK9x/kvH0HX54AAAABVEVTVAAAAAC9noEAfpBm3DqDuP3xkGv//x/LagoUP8LaImCenYwrKAAAAAJUC+QAAAAAAAAAAAAAAAABnYwrKAAAAECbS2lOWDZmOxHu4e5z+Ema+71wLtsktlxBnB20SZrteur8hu9cRls/sWR2Klg2Q2jhgL/wslYPzvbBg4La8nUM", "result_xdr": "AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAANAAAAAAAAAAAAAAAA0QNr+3v9HSAqKJT6bfuS/r+OXa68V5uK9x/kvH0HX54AAAABVEVTVAAAAAC9noEAfpBm3DqDuP3xkGv//x/LagoUP8LaImCenYwrKAAAAAJUpHqAAAAAAA==", "memo": "textmemo", "memo_type": "text", "source": "GC6Z5AIAP2IGNXB2QO4P34MQNP776H6LNIFBIP6C3IRGBHU5RQVSQ7XM", "paging_token": "2009348909830144", } TEST_ASSET_ISSUER_SEED = "SADPW3NKRUNSNKXZ3UCNKF5QKXFS3IBNDLIEDV4PEDLIXBXJOGSOQW6J" TEST_ASSET_ISSUER_PUBLIC_KEY = Keypair.from_secret(TEST_ASSET_ISSUER_SEED).public_key TEST_ASSET_DISTRIBUTION_SEED = ( "SBYMIF4ZEVMDF4JTLKLKZNJW4TGO4XBQK6UGLRY4XSWMNIFY4KHG5XKD" ) TEST_ASSET_DISTRIBUTION_PUBLIC_KEY = Keypair.from_secret( TEST_ASSET_DISTRIBUTION_SEED ).public_key @pytest.mark.django_db def test_process_response_success(client): """ Tests successful processing of the SUCCESS_PAYMENT_TRANSACTION_JSON """ asset = Asset.objects.create( code="TEST",
"successful": True, "envelope_xdr": "", "memo": "AAAAAAAAAAAAAAAAAAAAAIDqc+oB00EajZzqIpme754=", "memo_type": "hash", "source": "GCUZ6YLL5RQBTYLTTQLPCM73C5XAIUGK2TIMWQH7HPSGWVS2KJ2F3CHS", "paging_token": "123456789", } mock_envelope = Mock(transaction=Mock( operations=[ Mock( asset=Mock( issuer=USD_ISSUER_ACCOUNT, code="USD", ), amount=50, destination=Keypair.from_secret(USD_DISTRIBUTION_SEED).public_key, type_code=Mock(return_value=1), ) ], source=Keypair.from_public_key( "GCUZ6YLL5RQBTYLTTQLPCM73C5XAIUGK2TIMWQH7HPSGWVS2KJ2F3CHS"), )) @pytest.mark.django_db @patch(f"{test_module}.TransactionEnvelope.from_xdr", return_value=mock_envelope) def test_process_response_success(mock_xdr, client, acc1_usd_withdrawal_transaction_factory): del mock_xdr mock_source_account = mock_envelope.transaction.source.public_key