AsynchronousΒΆ

Now we have supported the use of asynchronous methods to submit transactions, py-stellar-sdk gives you the choice, rather than forcing you into always writing async; sync code is easier to write, generally safer, and has many more libraries to choose from.

Server has one parameter is client, here we need to talk about the client parameter, if you do not specify the client, we will use the RequestsClient instance by default, it is a synchronous HTTPClient, you can also specify an asynchronous HTTP Client, for example: AiohttpClient. If you use a synchronous client, then all requests are synchronous, if you use an asynchronous client, then all requests are asynchronous.

The following is an example of send a payment by an asynchronous method, the same example of using the synchronization method can be found here:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
"""
The effect of this example is the same as `payment.py`, but this example is asynchronous.

Create, sign, and submit a transaction using Python Stellar SDK.

Assumes that you have the following items:
1. Secret key of a funded account to be the source account
2. Public key of an existing account as a recipient
    These two keys can be created and funded by the friendbot at
    https://www.stellar.org/laboratory/ under the heading "Quick Start: Test Account"
3. Access to Python Stellar SDK (https://github.com/StellarCN/py-stellar-base) through Python shell.
"""
import asyncio

from stellar_sdk import Server, Keypair, TransactionBuilder, Network, AiohttpClient

# The source account is the account we will be signing and sending from.
source_secret_key = "SBFZCHU5645DOKRWYBXVOXY2ELGJKFRX6VGGPRYUWHQ7PMXXJNDZFMKD"

# Derive Keypair object and public key (that starts with a G) from the secret
source_keypair = Keypair.from_secret(source_secret_key)
source_public_key = source_keypair.public_key

receiver_public_key = "GA7YNBW5CBTJZ3ZZOWX3ZNBKD6OE7A7IHUQVWMY62W2ZBG2SGZVOOPVH"


async def main():
    # Configure StellarSdk to talk to the horizon instance hosted by Stellar.org
    # To use the live network, set the hostname to 'horizon.stellar.org'
    # When we use the `with` syntax, it automatically releases the resources it occupies.
    async with Server(
            horizon_url="https://horizon-testnet.stellar.org", client=AiohttpClient()
    ) as server:
        # 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.
        source_account = await server.load_account(source_public_key)

        base_fee = await server.fetch_base_fee()
        # we are going to submit the transaction to the test network,
        # so network_passphrase is `Network.TESTNET_NETWORK_PASSPHRASE`,
        # if you want to submit to the public network, please use `Network.PUBLIC_NETWORK_PASSPHRASE`.
        transaction = (
            TransactionBuilder(
                source_account=source_account,
                network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
                base_fee=base_fee,
            )
                .add_text_memo("Hello, Stellar!")  # Add a memo
                # Add a payment operation to the transaction
                # Send 350.1234567 XLM to receiver
                # Specify 350.1234567 lumens. Lumens are divisible to seven digits past the decimal.
                .append_payment_op(receiver_public_key, "350.1234567", "XLM")
                .set_timeout(30)  # Make this transaction valid for the next 30 seconds only
                .build()
        )

        # Sign this transaction with the secret key
        # NOTE: signing is transaction is network specific. Test network transactions
        # won't work in the public network. To switch networks, use the Network object
        # as explained above (look for stellar_sdk.network.Network).
        transaction.sign(source_keypair)

        # Let's see the XDR (encoded in base64) of the transaction we just built
        print(transaction.to_xdr())

        # Submit the transaction to the Horizon server.
        # The Horizon server will then submit the transaction into the network for us.
        response = await server.submit_transaction(transaction)
        print(response)


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()
    # asyncio.run(main())  # Python 3.7+

The following example helps you listen to multiple endpoints asynchronously.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import asyncio

from stellar_sdk import AiohttpClient, Server

HORIZON_URL = "https://horizon.stellar.org"


async def payments():
    async with Server(HORIZON_URL, AiohttpClient()) as server:
        async for payment in server.payments().cursor(cursor="now").stream():
            print(f"Payment: {payment}")


async def effects():
    async with Server(HORIZON_URL, AiohttpClient()) as server:
        async for effect in server.effects().cursor(cursor="now").stream():
            print(f"Effect: {effect}")


async def operations():
    async with Server(HORIZON_URL, AiohttpClient()) as server:
        async for operation in server.operations().cursor(cursor="now").stream():
            print(f"Operation: {operation}")


async def transactions():
    async with Server(HORIZON_URL, AiohttpClient()) as server:
        async for transaction in server.transactions().cursor(cursor="now").stream():
            print(f"Transaction: {transaction}")


async def listen():
    await asyncio.gather(
        payments(),
        effects(),
        operations(),
        transactions()
    )


if __name__ == '__main__':
    asyncio.run(listen())