InterchainAuthJS
Overview
InterchainAuthJS is a JavaScript/TypeScript library that simplifies the process of composing and broadcasting messages for Cosmos and IBC-related modules. This package streamlines interactions with the Interchain Auth module, enabling developers to:
- Compose messages: Easily create Cosmos SDK and IBC-compatible messages with full support for Protobuf and Amino encoding.
- Type safety: Leverages TypeScript for robust type definitions across all supported modules.
- Efficiency: Handles all underlying encoding complexities, letting developers focus on building their applications.
Built using Cosmos Kit Telescope, InterchainAuthJS provides pre-generated types and helper functions, ensuring compatibility with the Cosmos SDK and related ecosystems.
Installation
you can install using npm or yarn
- npm
- yarn
npm install @s16rv/interchainauthjs
yarn install @s16rv/interchainauthjs
Tutorials
Connecting to RPC Client
RPC clients allow you to interact with blockchain modules, such as Cosmos, IBC or Interchain Auth by querying data directly from the blockchain network. With an RPC client, you can retrieve information from various modules, including balances, pools, and more.
Creating Client
import { interchainauth } from '@s16rv/interchainauthjs';
const { createRPCQueryClient } = interchainauth.ClientFactory;
const client = await createRPCQueryClient({ rpcEndpoint: RPC_ENDPOINT });
Now you can query from the Cosmos, IBC or Interchain Auth modules.
Example: Querying Balances
const balance = await client.cosmos.bank.v1beta1
.allBalances({ address: 'your_address' });
/*
return
{
"balances": [
{
"denom": "uatom",
"amount": "145925592"
}
],
"pagination": {
"next_key": null,
"total": "1"
}
}
*/
Example: Querying Transaction
const tx = await client.cosmos.tx.v1beta1.getTx({
txHash: 'your_tx_hash'
});
/*
return
{
"tx": {
"body": {
"messages": [
{
"@type": "/interchainauth.icauth.v1.MsgSubmitTx",
"sender": "cosmos1....",
"channel_id": "channel-1",
"msgs": [
...
}
*/
Connecting with Wallets & Signing Message
In Cosmos-based dApps, connecting to a wallet is essential for signing and broadcasting transactions. You can achieve this using various libraries like:
Here, we focus on how to use Keplr for wallet connection and transaction signing, leveraging InterchainAuthJS for simplified client initialization.
Connecting to Keplr
To interact with a Cosmos wallet, you need an OfflineSigner. This signer allows you to sign transactions securely. The signer can be retrieved from wallet extensions like Keplr.
const {keplr} = window
if (!keplr) {
throw new Error("Keplr extension is not installed.");
}
const chainId= "your-chain-id"
//connecting to keplr
await keplr.enable(chainId);
//getting the signer
const signer = keplr.getOfflineSigner(chainId);
Initializing the Signing Client
Use the getSigningInterchainauthClient method from InterchainAuthJS to create a SigningStargateClient. This client is preloaded with interchain-auth, cosmos, and IBC proto/amino message types, removing the need for manual configurations.
import { getSigningInterchainauthClient } from '@s16rv/interchainauthjs';
const client = await getSigningInterchainauthClient({
rpcEndpoint: "your-rpc-endpoint",
signer, // OfflineSigner retrieved earlier
});
console.log("Signing client initialized!", client);
Sign and Broadcast Message
Once you have the client, you can use it to sign and broadcast transactions.
Cosmos supports two signing methods:
- Direct Signing: Used for Protobuf-based signing (modern and efficient).
- Amino Signing: Used for legacy JSON-based signing (for compatibility with older modules like Authz).
You can initialize both signers and use them depending on the transaction requirements.
-
Step 1: Connect to Wallet
wallet.tsasync function connectWallet(chainId) {
if (!window.keplr) {
throw new Error("Keplr wallet not found!");
}
// Enable Keplr for the specific chain
await window.keplr.enable(chainId);
// Get OfflineDirectSigner and OfflineAminoSigner
const offlineDirectSigner = await window.keplr.getOfflineSigner(chainId);
const offlineAminoSigner = window.keplr.getOfflineSignerOnlyAmino(chainId);
return { offlineDirectSigner, offlineAminoSigner };
} -
Step 2: Initialize Signing Client
wallet.tsasync function getClient(rpcEndpoint, offlineSigner) {
const client = await getSigningInterchainauthClient({
rpcEndpoint,
signer: offlineSigner,
});
return client;
} -
Step 3: Sign and Broadcast Transactions
wallet.tsasync function signAndBroadcast(
chainId,
rpcEndpoint,
txMsg,
fee,
memo,
useAmino = false,
) {
// Connect wallet and get appropriate signer
const { offlineDirectSigner, offlineAminoSigner } = await connectWallet(
chainId,
);
// Choose the signer type
const offlineSigner = useAmino ? offlineAminoSigner : offlineDirectSigner;
// Initialize the client with the selected signer
const client = await getClient(rpcEndpoint, offlineSigner);
// Broadcast the transaction
const result = await client.signAndBroadcast(chainId, [txMsg], fee, memo);
return result;
}
Advanced Usage
Manually composing signing client
import { OfflineSigner, GeneratedType, Registry } from "@cosmjs/proto-signing";
import { AminoTypes, SigningStargateClient } from "@cosmjs/stargate";
import {
cosmosAminoConverters,
cosmosProtoRegistry,
ibcProtoRegistry,
ibcAminoConverters,
interchainauthAminoConverters,
interchainauthProtoRegistry,
} from "@s16rv/interchainauthjs";
const protoRegistry: ReadonlyArray<[string, GeneratedType]> = [
...cosmosProtoRegistry,
...ibcProtoRegistry,
...interchainauthProtoRegistry,
];
const aminoConverters = {
...cosmosAminoConverters,
...ibcAminoConverters,
...interchainauthAminoConverters,
};
const registry = new Registry(protoRegistry);
const aminoTypes = new AminoTypes(aminoConverters);
const stargateClient = await SigningStargateClient.connectWithSigner(
rpcEndpoint,
signer,
{
registry,
aminoTypes,
},
);
Composing Message
Composing messages is a crucial part of interacting with blockchain networks. Messages represent actions such as sending tokens, delegating, or executing smart contracts. With InterchainAuthJS, composing messages is streamlined, supporting Cosmos modules and IBC messages out of the box.
Interchain Auth MsgSubmitTx
The Interchain Auth MsgSubmitTx is used to submit interchain auth transaction.
- Flexible Message Composition: Inside the
msgsarray, users can include any action from the Cosmos or IBC modules. This also supports multiple messages at once, provided the messages use the same channel. - No Extra Dependencies: Users can compose any message from the Cosmos or IBC module directly using InterchainAuthJS. There is no need to install additional packages for message composition.
MsgSubmitTx Interface
{
sender: string; // The address initiating the transaction
channelId: string; // The IBC channel ID from port 'icauth'
msgs: EncodeObject[]; // List of EncodeObject messages
relativeTimeout: bigint; // Timeout in nanoseconds
memo?: string; // (Optional) transaction memo
}
There are two ways to generate this message using InterchainAuthJS.
Composing Message Using MessageComposer
You can utilize the MessageComposer utility provided by InterchainAuthJS to compose a submitTx message easily.
import { interchainauth } from "@s16rv/interchainauthjs";
const { submitTx } = interchainauth.icauth.v1.MessageComposer.withTypeUrl;
const msgSend = "Your-encoded-message-send";
const msg = submitTx({
sender: "cosmos1...",
channelId: "channel-0",
msgs: [msgSend],
relativeTimeout: BigInt(1800000000000),
memo: "Optional memo",
});
Composing Message Using MsgSubmitTx
Alternatively, you can directly use the MsgSubmitTx type to compose your message. This provides a more low-level approach, allowing you to construct or encode messages manually.
-
Using
MsgSubmitTx.fromPartialmessage.tsconst msgSend = "Your-encoded-message-send";
const value = MsgSubmitTx.fromPartial({
sender: "cosmos1...",
channelId: "channel-0",
msgs: [msgSend],
relativeTimeout: BigInt(1800000000000),
memo: "Optional memo",
});
return {
typeUrl: "/interchainauth.icauth.v1.MsgSubmitTx",
value,
}; -
Using
MsgSubmitTx.encodeIf you need the binary-encoded format of the message, you can use the
MsgSubmitTx.encodemethod:message.tsconst msgSend = "Your-encoded-message-send";
const value = MsgSubmitTx.encode({
sender: "cosmos1...",
channelId: "channel-0",
msgs: [msgSend],
relativeTimeout: BigInt(1800000000000),
memo: "Optional memo",
}).finish();
return {
typeUrl: "/interchainauth.icauth.v1.MsgSubmitTx",
value,
};
Example
Send Tokens (Cosmos Bank Module)
import { MsgSend } from "@s16rv/interchainauthjs/dist/codegen/cosmos/bank/v1beta1/tx";
const sendMsg = {
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: MsgSend.encode({
fromAddress: "cosmos1...",
toAddress: "cosmos1recipient...",
amount: [{ denom: "uatom", amount: "1000000" }], // 1 ATOM
}).finish(),
};
IBC Transfer (IBC Transfer Module)
import { MsgTransfer } from '@s16rv/interchainauthjs/dist/codegen/ibc/applications/transfer/v1/tx';
const transferMsg = {
typeUrl: '/ibc.applications.transfer.v1.MsgTransfer'
value: MsgTransfer.encode({
sourcePort: 'transfer',
sourceChannel: 'channel-0',
token: { denom: 'uatom', amount: '1000000' }, // 1 ATOM
sender: 'cosmos1...',
receiver: 'cosmos1recipient...',
timeoutHeight: undefined, // Optional
timeoutTimestamp: Date.now() + 300000000000, // 5 minutes in nanoseconds
}).finish(),
}
Submit Tx (Interchain Auth Module)
The send and transfer messages can be added to the msgs array when composing an Interchain Auth Submit Tx. For example:
const msg = submitTx({
sender: "cosmos1...",
channelId: "channel-0",
msgs: [sendMsg, transferMsg],
relativeTimeout: BigInt(1800000000000),
memo: "Optional memo",
});
The MsgSubmitTx may fail to execute under the following conditions:
- Incorrect Channel ID: The
channelIddoes not match the correct IBC channel for the specified action. - Mismatched Sender Address: The
senderaddress in the message does not match the address of the signing wallet. - Invalid Message Format: The message is not properly encoded or is missing required fields.
- Insufficient Gas or Fees: The transaction does not include enough gas or fees to cover the execution cost.
- Expired Timeout: The
timeoutTimestamphas already elapsed by the time the message is processed.
Related
Checkout these related projects:
- @cosmology/telescope Your Frontend Companion for Building with TypeScript with Cosmos SDK Modules.
- @cosmwasm/ts-codegen Convert your CosmWasm smart contracts into dev-friendly TypeScript classes.
- chain-registry Everything from token symbols, logos, and IBC denominations for all assets you want to support in your application.
- cosmos-kit Experience the convenience of connecting with a variety of web3 wallets through a single, streamlined interface.
- create-cosmos-app Set up a modern Cosmos app by running one command.
- interchain-ui The Interchain Design System, empowering developers with a flexible, easy-to-use UI kit.
- starship Unified Testing and Development for the Interchain.
Credits
🛠 Built by Cosmology — if you like our tools, please consider delegating to our validator ⚛️
Disclaimer
AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED “AS IS”, AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.