# Compose Complex Transactions - Send Multiple Messages
In Cosmos, a transaction can encapsulate multiple messages.
In this section:
- Send multiple tokens in a single transaction
- Sign and Broadcast
- Assemble multiple messages
# Send multiple tokens using
In the previous exercise, you had Alice send tokens back to the faucet. To refresh your memory, this is what the
sendTokens function takes as input:
Coin (opens new window) allows Alice to send not just
stake but also any number of other coins as long as she owns them. So she can:
However, there are limitations. First, Alice can only target a single recipient per transaction,
faucet in the previous examples. If she wants to send tokens to multiple recipients, then she needs to create as many transactions as there are recipients. Multiple transactions cost slightly more than packing transfers into the array because of transaction overhead. Additionally, in some cases it can be considered a bad user experience to make users sign multiple transactions.
The second limitation is that separate transfers are not atomic. It is possible that Alice wants to send tokens to two recipients and it is important that either they both receive them or neither of them receive anything.
Fortunately, there is a way to atomically send tokens to multiple recipients.
SigningStargateClient has the
The basic components of a transaction are the
messages that it contains, as well as the
fee and an optional
memo. As such, Cosmos transactions can indeed be composed of multiple messages.
# Token transfer messages
In order to use
signAndBroadcast to send tokens, you need to figure out what messages go into the
messages: readonly EncodeObject. Examine the
sendTokens function body:
Therefore, when sending back to the faucet, instead of calling:
Alice can instead call:
You can confirm this by making the change in your
experiment.ts from the previous section, and running it again.
In fact, building a transaction in this way is recommended.
SigningStargateClient offers you convenience methods such as
sendTokens for simple use cases only.
# What is this long string?
As a reminder from the previous tutorial, the
typeUrl: "/cosmos.bank.v1beta1.MsgSend" string comes from the Protobuf definitions and is a mixture of:
MsgSendis initially declared:
And the name of the message itself,
To learn how to make your own types for your own blockchain project, head to Create my own CosmJS objects.
# Multiple token transfer messages
From here, you can add an extra message for a token transfer from Alice to someone else:
Note how the custom fee input was replaced with the
auto input, which simulates the transaction to estimate the fee for you. In order to make that work well, you'll need to define the
gasPrice you're willing to pay and its
prefix when setting up your
signingClient. You can replace your original line of code with:
# Mixing other message types
The above example shows you two token-transfer messages in a single transaction. You can see this with their
Neither Cosmos nor CosmJS limits you to combine messages of the same type. You can decide to combine other message types together with a token transfer. For instance, in one transaction Alice could:
- Send tokens to the faucet.
- Delegate some of her tokens to a validator.
How would Alice create the second message? The
SigningStargateClient contains a predefined list of
typeUrls that are supported by default, because they're considered to be the most commonly used messages in the Cosmos SDK. One of them so happens to be
MsgDelegate, and that's exactly what you'll need. You can click on the source link below to see the rest of the
typeUrls that come with
Click through to the type definition, and the
Now that you know the
typeUrl for delegating some tokens is
/cosmos.staking.v1beta1.MsgDelegate, you'll need to find a validator's address that Alice can delegate to. You can find a list of validators in the testnet explorer (opens new window). Select a validator and use their address in the below script which you can copy to replace your original token transfer:
When you create your own message types in CosmJS, they have to follow this format and be declared in the same fashion.
# Next up
You are now able to send complex transactions. How about you do the same but from a Web-browser, with the help of Keplr? That is the object of the next section.