Skip to main content

Performing transactions

Overview

In order to be able to perform transactions you need to do the following steps:

  1. create a Signer instance
  2. create a DesmosClient instance with the connectWithSigner function
  3. build the messages that you want to include inside the transaction
  4. sign and broadcast the messages with the signAndBroadcast method

Here is an example of code that showcases all the steps:

import { DesmosClient, OfflineSignerAdapter, SigningMode, GasPrice } from "@desmoslabs/desmjs";


// Generate a signer with a random mnemonic. To see the available signer go to the Signers section.
const signer = await OfflineSignerAdapter.generate(SigningMode.DIRECT, 24);

const client = await DesmosClient.connectWithSigner('https://rpc.mainnet.desmos.network', signer, {
// Common gas price in the Desmos mainnet.
gasPrice: GasPrice.fromString("0.01udsm"),
});

// Get the signer address from the signer.
const [signerAddress] = await signer.getAccounts();

// Save profile message
const saveProfile: MsgSaveProfileEncodeObject = {
typeUrl: "/desmos.profiles.v3.MsgSaveProfile",
value: {
creator: signerAddress,
bio: "The price of all saiyans",
dtag: "vegeta",
nickname: "Vegeta",
coverPicture: "https://ipfs.io/ipfs/<CID>",
profilePicture: "https://ipfs.io/ipfs/<CID>",
}
};

// Message to create a post inside a subspace
const createPost: MsgCreatePostEncodeObject = {
typeUrl: "/desmos.posts.v3.MsgCreatePost",
value: MsgCreatePost.fromPartial({
subspaceId: Long.fromNumber(1),
author: signerAddress,
text: "post content",
replySettings: ReplySetting.REPLY_SETTING_EVERYONE
})
};

// Message to be sent to the chain, they will be executed sequentially from first to last.
const messages: EncodeObject[] = [saveProfile, createPost];

// Fee paid to perform the operations.
const fees: number | StdFee | "auto" = "auto";

// Optional memo that can be attached to the transaction, max length 256 characters.
const memo: string | undefined = undefined;

await client.signandbroadcast(signerAddress, messages, fees, memo);

Automatic fees estimation

The DesmosClient class can estimate the fees for you before broadcasting the messages.
To enable this feature you must provide the gasPrice through the options param of connectWithSigner.

To compute the fees the DesmosClient will first estimate the amount of gas required asking the chain to simulate an execution with the messages that you want to execute and then will multiply that value for gasPrice. The resulting fees then will be gasPrice * estimated gas.

When you enable this feature you can pass one of the following values as a fee param of signandbroadcast:

  • "auto": To automatically estimated the fees based on the messages that you want to broadcast;
  • a number: Multiplication factor used to estimate the gas and fees from the provided messages. When using "auto" this value is 1.3 so the gas used to compute the fees is equal to 1.3 * estimated gas.

Signers

The @desmoslabs/desmjs provides a set of signers that can be used, here you can find the list:

  1. OfflineSignerAdapter: This can be used to create a signer from a 12/24 words mnemonic or any signer that implements the @cosmjs/OfflineAminoSigner or @cosmjs/OfflineDirectSigner;
  2. PrivateKeySigner: This can be used to create a signer from a private key.

If none of this signer meet your needs you can implement a custom signer by extending the Signer class.
For references on how to implement a custom Signer you can take a look inside the demsjs GitHub repo.
Some worth to take a look are:

  1. @desmoslabs/desmjs-walletconnect-v2: Signer that use WalletConnect to sign transactions;
  2. @desmoslabs/desmjs-web3auth-web: Signer that receive a Secp256k1 private key from Web3Auth.

Messages

Here is the list of messages that can be sent divided by module:

Profiles

v3

Relationships

v1

Subspaces

v3

Posts

v3

Reactions

v1

Reports

v1

Examples

Here are some examples that showcase how to interact with the various Desmos modules.

Create a profile

Here is an example that showcases how to create a Desmos profile:

import { DesmosClient, GasPrice, Profiles } from "@desmoslabs/desmjs";


const signer = ...; // Your signer
const client = await DesmosClient.connectWithSigner('https://rpc.mainnet.desmos.network', signer, {
// Common gas price in the Desmos mainnet.
gasPrice: GasPrice.fromString("0.01udsm"),
});

const saveProfile: Profiles.v3.MsgSaveProfileEncodeObject = {
typeUrl: Profiles.v3.MsgSaveProfileTypeUrl,
value: {
creator: "desmos...",
bio: "The price of all saiyans",
dtag: "vegeta",
nickname: "Vegeta",
coverPicture: "https://ipfs.io/ipfs/<CID>",
profilePicture: "https://ipfs.io/ipfs/<CID>",
}
};

await client.signAndBroadcast(saveProfile.value.creator, [saveProfile], "auto");

Create a relationship

Here is an example that showcases how to create a relationship:

import Long from "long";
import { DesmosClient, GasPrice, Relationships } from "@desmoslabs/desmjs";


const signer = ...; // Your signer
const client = await DesmosClient.connectWithSigner('https://rpc.mainnet.desmos.network', signer, {
// Common gas price in the Desmos mainnet.
gasPrice: GasPrice.fromString("0.01udsm"),
});

const createRelationship: Relationships.v1.MsgCreateRelationshipEncodeObject = {
typeUrl: Relationships.v1.MsgCreateRelationshipTypeUrl,
value: {
signer: "desmos...",
subspaceId: Long.fromNumber(1),
counterparty: "desmos..."
}
};

await client.signAndBroadcast(createRelationship.value.signer, [createRelationship], "auto");

Create a subspace

Here is an example that showcases how to create a subspace:

import { DesmosClient, GasPrice, Subspaces } from "@desmoslabs/desmjs";


const signer = ...; // Your signer
const client = await DesmosClient.connectWithSigner('https://rpc.mainnet.desmos.network', signer, {
// Common gas price in the Desmos mainnet.
gasPrice: GasPrice.fromString("0.01udsm"),
});

const createSubspace: Subspaces.v3.MsgCreateSubspaceEncodeObject = {
typeUrl: Subspaces.v3.MsgCreateSubspaceTypeUrl,
value: {
creator: "desmos...",
name: "Desmos subspace",
owner: "desmos...",
treasury: "desmos...",
description: "Subspace where to store my app content"
}
};

await client.signAndBroadcast(createSubspace.value.creator, [createSubspace], "auto");

Create a post

Here is an example that showcases how to create a post:

import Long from "long";
import { ReplySetting } from "@desmoslabs/desmjs-types/desmos/posts/v3/models";
import { MsgCreatePost } from "@desmoslabs/desmjs-types/desmos/posts/v3/msgs";
import { DesmosClient, GasPrice, Posts } from "@desmoslabs/desmjs";

const signer = ...; // Your signer
const client = await DesmosClient.connectWithSigner('https://rpc.mainnet.desmos.network', signer, {
// Common gas price in the Desmos mainnet.
gasPrice: GasPrice.fromString("0.01udsm"),
});

const createPost: Posts.v3.MsgCreatePostEncodeObject = {
typeUrl: Posts.v3.MsgCreatePostTypeUrl,
value: MsgCreatePost.fromPartial({
subspaceId: Long.fromNumber(1),
author: "desmos...",
text: "post content",
replySettings: ReplySetting.REPLY_SETTING_EVERYONE
})
};

await client.signAndBroadcast(createPost.value.author, [createPost], "auto");

React to a post with some text

Here is an example that showcases how to react to a post:

import Long from "long";
import { FreeTextValue } from "@desmoslabs/desmjs-types/desmos/reactions/v1/models";
import { DesmosClient, GasPrice, Reactions } from "@desmoslabs/desmjs";

const signer = ...; // Your signer
const client = await DesmosClient.connectWithSigner('https://rpc.mainnet.desmos.network', signer, {
// Common gas price in the Desmos mainnet.
gasPrice: GasPrice.fromString("0.01udsm"),
});

const addReaction: Reactions.v1.MsgAddReactionEncodeObject = {
typeUrl: Reactions.v1.MsgAddReactionTypeUrl,
value: {
user: "desmos...",
postId: Long.fromNumber(1),
subspaceId: Long.fromNumber(1),
value: {
typeUrl: "/desmos.reactions.v1.FreeTextValue",
value: FreeTextValue.encode({
text: "nice post",
}).finish()
}
}
};

await client.signAndBroadcast(addReaction.value.user, [addReaction], "auto");

React to a post with a registered reaction

Here is an example that showcases how to react to a post:

import Long from "long";
import { RegisteredReactionValue } from "@desmoslabs/desmjs-types/desmos/reactions/v1/models";
import { DesmosClient, GasPrice, Reactions } from "@desmoslabs/desmjs";

const signer = ...; // Your signer
const client = await DesmosClient.connectWithSigner('https://rpc.mainnet.desmos.network', signer, {
// Common gas price in the Desmos mainnet.
gasPrice: GasPrice.fromString("0.01udsm"),
});

const addReaction: Reactions.v1.MsgAddReactionEncodeObject = {
typeUrl: Reactions.v1.MsgAddReactionTypeUrl,
value: {
user: "desmos...",
postId: Long.fromNumber(1),
subspaceId: Long.fromNumber(1),
value: {
typeUrl: "/desmos.reactions.v1.RegisteredReactionValue",
value: RegisteredReactionValue.encode({
registeredReactionId: 1,
}).finish()
}
}
};

await client.signAndBroadcast(addReaction.value.user, [addReaction], "auto");

Report a user

Here is an example that showcases how to report a user inside a subspace:

import Long from "long";
import { DesmosClient, GasPrice, Reports } from "@desmoslabs/desmjs";
import { UserTarget } from "@desmoslabs/desmjs-types/desmos/reports/v1/models";

const signer =...; // Your signer
const client = await DesmosClient.connectWithSigner("https://rpc.mainnet.desmos.network", signer, {
// Common gas price in the Desmos mainnet.
gasPrice: GasPrice.fromString("0.01udsm")
});

const reportUser: Reports.v1.MsgCreateReportEncodeObject = {
typeUrl: Reports.v1.MsgCreateReportTypeUrl,
value: {
reporter: "desmos...",
subspaceId: Long.fromNumber(1),
message: "This user have a bad behaviour",
reasonsIds: [1],
target: {
typeUrl: Reports.v1.UserTargetTypeUrl,
value: UserTarget.encode({
user: "desmos..."
}).finish()
}
}
};

await client.signAndBroadcast(reportUser.value.reporter, [reportUser], "auto");

Report another user post

Here is an example that showcases how to report another user post:

import Long from "long";
import { DesmosClient, GasPrice, Reports } from "@desmoslabs/desmjs";
import { PostTarget } from "@desmoslabs/desmjs-types/desmos/reports/v1/models";

const signer =...; // Your signer
const client = await DesmosClient.connectWithSigner("https://rpc.mainnet.desmos.network", signer, {
// Common gas price in the Desmos mainnet.
gasPrice: GasPrice.fromString("0.01udsm")
});

const reportPost: Reports.v1.MsgCreateReportEncodeObject = {
typeUrl: Reports.v1.MsgCreateReportTypeUrl,
value: {
reporter: "desmos...",
subspaceId: Long.fromNumber(1),
message: "This user have a bad behaviour",
reasonsIds: [1],
target: {
typeUrl: Reports.v1.PostTargetTypeUrl,
value: PostTarget.encode({
postId: Long.fromNumber(1)
}).finish()
}
}
};

await client.signAndBroadcast(reportPost.value.reporter, [reportPost], "auto");