# Encoding, Signing, and Broadcasting transactions with CosmJS
By default, [CosmJS](https://github.com/cosmos/cosmjs) builds, signs, and broadcasts a transactions in a single function call. Often, it's useful to separate these steps.
This gist explores a simple way of doing so in TypeScript, and may also be useful for those wanting to dive deeper into how Cosmos messages are composed and signed.
## Setup
You will need a few dependencies:
- [cosmwasm](https://www.npmjs.com/package/cosmwasm): which is a wrapper package for all of the [CosmJS packages](https://cosmos.github.io/cosmjs/)
- [cosmjs-types](https://www.npmjs.com/package/cosmjs-types): which contains helpers for encoding and decoding protobuf messages.
You can install these with `npm` or yarn:
```sh
npm i cosmwasm cosmjs-types
# OR
yarn add cosmwasm cosmjs-types
```
## High level overview of steps
##### 1. Creating and encoding protobuf messages
Cosmos messages are encoded as [protobufs](https://protobuf.dev/) so to create a transaction we'll first need to encode a protobuf message.
[Telescope](https://github.com/osmosis-labs/telescope) is a TypeScript Transpiler for Cosmos Protobufs. It can be used to efficiently generate protobuf message and will save you lots of time. However, we'll be doing it the manual way with `cosmjs-types`.
NOTE: Cosmos chains also support an older form of encoding known as [amino](https://cosmos.github.io/cosmjs/latest/amino/index.html) that is used primarily with ledger devices.
### Signing with a signing client
Signing a transaction needs to be done with a private key or signer. To do this we'll create a [SigningStargateClient](https://cosmos.github.io/cosmjs/latest/stargate/classes/SigningStargateClient.html) or [SigningCosmWasmClient](https://cosmos.github.io/cosmjs/latest/cosmwasm-stargate/classes/SigningCosmWasmClient.html) (which is mostly the same plus a great interface for working with [CosmWasm](https://cosmwasm.com) smart contracts on chains like [Juno Network](http://junonetwork.io)).
Note: the signing client doesn't have to be online, the is a `signingClient.offline()` method demonstrated in the code example below.
For CosmJS, signers MUST implement the [OfflineSigner interface](https://cosmos.github.io/cosmjs/latest/proto-signing/interfaces/OfflineDirectSigner.html). For an example of this, see the [DirectSecp256k1HdWallet implementation](https://github.com/cosmos/cosmjs/blob/main/packages/proto-signing/src/directsecp256k1hdwallet.ts) in the [cosmjs repo](https://github.com/cosmos/cosmjs).
Some example signers include:
- Wallets like Keplr which use the [proto-signing](https://cosmos.github.io/cosmjs/latest/proto-signing/index.html)
- Hardware wallets like Ledger (see [@cosmjs/ledger-amino package](https://cosmos.github.io/cosmjs/latest/ledger-amino/index.html))
We'll demonstate creating a wallet purley in code below. See [cosmos-kit](https://github.com/cosmology-tech/cosmos-kit) if you're interested in working with third party wallets.
### Broadcasting
After creating and signing the transaction, we need to broadcast it to the chain via an RPC node, for this we'll use a [CosmwasmClient]()
## TypeScript code example
NOTE: Many more code examples for all sorts of things exist in [CosmJS tests](https://github.com/cosmos/cosmjs) for the various packages.
```typescript
// Import needed dependencies from the cosmwasm package
import { coins, DirectSecp256k1HdWallet, SigningCosmWasmClient } from "cosmwasm";
// Import protobuf helpers from cosmjs-types
// Note: this the manual way of doing this, Telescope provides much
// nicer tooling for working with chain protobufs
import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx";
import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx";
// Create a Secp256k1 wallet manually
// Note: there other ways to create a wallet, such as getting an OfflineDirectSigner from Keplr
// or using the @cosmjs/ledger-amino package. Wallets must implement the OfflineSigner interface.
// See: https://cosmos.github.io/cosmjs/latest/proto-signing/interfaces/OfflineDirectSigner.html
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(
"enlist hip relief stomach skate base shallow young switch frequent cry park",
{ prefix: "juno" }
);
// Create a client connected an RPC endpoint
const client = await SigningCosmWasmClient.connect(
"https://rpc.junonetwork.io",
);
// Create an offline client for signing the transaction
const offline = await SigningCosmWasmClient.offline(wallet);
// Get the account address
const account = await wallet.getAccounts();
// Encode a send message.
const msg = {
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: MsgSend.fromPartial({
fromAddress: account[0].address,
toAddress: "juno1xyz...",
amount: coins(1234, "ujuno"),
}),
};
const fee = {
amount: coins(2000, "ujuno"),
gas: "200000",
};
const memo = "Use your tokens wisely";
// Sign a message
const signed = await offline?.sign(account[0].address, [msg], fee, memo);
// Broadcast the transaction the transaction, note it must be encode as raw protobuf transaction
client
.broadcastTx(Uint8Array.from(TxRaw.encode(signed).finish()))
.then((res) => {
console.log(res);
});
```
## Other tools and resources
- [telescope](https://github.com/osmosis-labs/telescope): awesome tooling for working with Cosmos chain protobufs
- [cosmos-kit](https://github.com/cosmology-tech/cosmos-kit): a library for connecting to multiple wallets and a bunch of other stuff
- [create-cosmos-app](https://github.com/cosmology-tech/create-cosmos-app): Easily create a cosmos frontend application
- [@cosmjs packages](https://cosmos.github.io/cosmjs/): the complete list of `cosmjs` packages