Developers

Send Transactions

Sign and broadcast transactions on the Crescendo-1 testnet using CosmJS.

This guide shows how to sign and broadcast transactions on the Crescendo-1 testnet using CosmJS.

Prerequisites

Send Tokens

The most common transaction is a simple token transfer.

import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"
import { SigningStargateClient } from "@cosmjs/stargate"

const wallet = await DirectSecp256k1HdWallet.fromMnemonic(
  "your mnemonic here ...",
  { prefix: "bitsong" }
)

const [account] = await wallet.getAccounts()
const client = await SigningStargateClient.connectWithSigner(
  "https://rpc.testnet.bitsong.io",
  wallet
)

const result = await client.sendTokens(
  account.address,
  "bitsong1recipientaddress",
  [{ denom: "ubtsg", amount: "1000000" }],
  {
    amount: [{ denom: "ubtsg", amount: "500" }],
    gas: "200000"
  },
  "testnet transfer"
)

console.log("Tx hash:", result.transactionHash)
1000000 ubtsg = 1 BTSG. See Chain Parameters for denomination details.

Auto-estimate Gas

Instead of hardcoding gas, you can use the auto gas estimation:

const client = await SigningStargateClient.connectWithSigner(
  "https://rpc.testnet.bitsong.io",
  wallet,
  { gasPrice: { amount: "0", denom: "ubtsg" } }
)

const result = await client.sendTokens(
  account.address,
  "bitsong1recipientaddress",
  [{ denom: "ubtsg", amount: "1000000" }],
  "auto",
  "testnet transfer"
)
On the testnet, gas price is 0ubtsg, so transactions are effectively free.

Delegate Tokens

Stake tokens with a validator:

import { SigningStargateClient } from "@cosmjs/stargate"
import { MsgDelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx"

const msg = {
  typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
  value: MsgDelegate.fromPartial({
    delegatorAddress: account.address,
    validatorAddress: "bitsongvaloper1...",
    amount: { denom: "ubtsg", amount: "1000000" }
  })
}

const result = await client.signAndBroadcast(
  account.address,
  [msg],
  "auto",
  "delegate to validator"
)

console.log("Tx hash:", result.transactionHash)

Query Transactions

After broadcasting, you can query the transaction:

import { StargateClient } from "@cosmjs/stargate"

const client = await StargateClient.connect("https://rpc.testnet.bitsong.io")

// Query by hash
const tx = await client.getTx("ABCDEF1234...")
console.log("Height:", tx?.height)
console.log("Code:", tx?.code) // 0 = success

// Query account balance
const balance = await client.getBalance("bitsong1...", "ubtsg")
console.log("Balance:", balance.amount, balance.denom)

Error Handling

Common transaction errors and how to handle them:

ErrorCauseSolution
account not foundAddress has no tokensRequest from faucet
insufficient fundsNot enough balance for amount + gasReduce amount or get more tokens
out of gasGas limit too lowIncrease gas limit or use "auto"
signature verification failedWrong chain ID or account sequenceVerify chain ID is crescendo-1
Copyright © 2026