- stridejs
npm install stridejsimport { StrideClient, DirectSecp256k1HdWallet, GasPrice } from "stridejs";
// Create a wallet from mnemonic
const signer = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
prefix: "stride",
});
// Get the address from the wallet
const [{ address }] = await signer.getAccounts();
// Create a StrideClient instance
const client = await StrideClient.create(
"http://stride-rpc.example.com:26657",
signer,
address,
{
gasPrice: GasPrice.fromString("0.025ustrd"),
},
);The recommended way of integrating Keplr is by using window.keplr.getOfflineSignerOnlyAmino():
import { StrideClient, sleep, GasPrice } from "stridejs";
while (!window.keplr || !window.keplr?.getOfflineSignerOnlyAmino) {
await sleep(50);
}
const CHAIN_ID = "stride-1";
await window.keplr.enable(CHAIN_ID);
const signer = window.keplr.getOfflineSignerOnlyAmino(CHAIN_ID);
const [{ address }] = await signer.getAccounts();
const stridejs = new StrideClient.create(
"http://stride-rpc.example.com:26657",
signer,
address,
{
gasPrice: GasPrice.fromString("0.025ustrd"),
},
);Links:
TL;DR:
getOfflineSignerOnlyAmino(): The recommended way. Supports Ledger, has a nice UI.getOfflineSigner(): No Ledger support, ugly UI, can send IBC relayer txs and submit IBC gov proposals.getOfflineSignerAuto(): If Ledger alias forgetOfflineSignerOnlyAmino(), otherwise alias forgetOfflineSigner().
Although this is the legacy way of signing transactions on cosmos-sdk chains, it's still the most recommended for connecting to Keplr due to Ledger support & better UI on Keplr.
- đźź© Looks good on Keplr
- đźź© Supports users signing with Ledger
- 🟥 Doesn't support signing these transactions:
- Every tx type under
ibc.client,ibc.connectionandibc.channel(meaning IBC relaying, for example with ts-relayer)
- Every tx type under
Note that ibc.applications.transfer.v1.MessageComposer.withTypeUrl.transfer for sending funds across IBC is supported.
The new way of signing transactions on cosmos-sdk chain, it's more efficient but still doesn't have Ledger support. It's most recommended for usage in apps that don't require signing transactions with Ledger.
- 🟥 Looks bad on Keplr
- 🟥 Doesn't support users signing with Ledger
- đźź© Supports signing transactions with all types of messages
If the connected Keplr account uses Ledger, returns window.keplr.getOfflineSignerOnlyAmino().
Otherwise returns window.keplr.getOfflineSigner().
The recommended way of integrating Leap is by using window.leap.getOfflineSignerAmino():
import { StrideClient, sleep, GasPrice } from "stridejs";
while (!window.leap || !window.leap?.getOfflineSignerOnlyAmino) {
await sleep(50);
}
const CHAIN_ID = "stride-1";
await window.leap.enable(CHAIN_ID);
const signer = window.leap.getOfflineSignerOnlyAmino(CHAIN_ID);
const [{ address }] = await signer.getAccounts();
const stridejs = new StrideClient.create(
"http://stride-rpc.example.com:26657",
signer,
address,
{
gasPrice: GasPrice.fromString("0.025ustrd"),
},
);Links:
LedgerSigner can be used to sign transactions with a Ledger wallet running the Cosmos app.
import { StrideClient, makeCosmoshubPath, LedgerSigner } from "stridejs";
// NodeJS only
import TransportNodeHid from "@ledgerhq/hw-transport-node-hid";
// Browser only
//import TransportNodeHid from "@ledgerhq/hw-transport-webusb";
const interactiveTimeout = 120_000;
const accountIndex = 0;
const cosmosPath = makeCosmoshubPath(accountIndex);
const ledgerTransport = await TransportNodeHid.create(
interactiveTimeout,
interactiveTimeout,
);
const signer = new LedgerSigner(ledgerTransport, {
testModeAllowed: true,
hdPaths: [cosmosPath],
prefix: "stride",
});
const [{ address }] = await signer.getAccounts();
const stridejs = new StrideClient.create(
"http://stride-rpc.example.com:26657",
signer,
address,
{
gasPrice: GasPrice.fromString("0.025ustrd"),
},
);Links:
const client = await StrideClient.create(
rpcUrl: string,
signer: OfflineSigner,
address: string,
options?: StrideClientOptions
)rpcUrl: URL to the CometBFT RPC endpointsigner: Signer for signing transactionsaddress: Account address that can sign transactionsoptions: Optional configuration object:type StrideClientOptions = { gasPrice?: GasPrice; registry?: Registry; aminoTypes?: AminoTypes; broadcastTimeoutMs?: number; // default: 60_000, broadcastPollIntervalMs?: number; // default: 3_000, resolveIbcResponsesTimeoutMs?: number; // default: 180_000 resolveIbcResponsesCheckIntervalMs?: number; // default: 12_000 };
class StrideClient {
readonly rpcEndpoint: string;
readonly signer: OfflineSigner;
readonly address: string;
readonly signingStargateClient: SigningStargateClient;
readonly query: QueryClient & AuthExtension & BankExtension & more;
readonly options?: StrideClientOptions;
}async signAndBroadcast(
messages: readonly EncodeObject[],
fee: StdFee | "auto" | number = "auto", // defaults to "auto" - simulates the tx and uses 1.4 as gas limit multiplier
memo: string = ""
): Promise<DeliverTxResponse & { ibcResponses: Array<Promise<IbcResponse>> }>Signs and broadcasts transaction(s). Returns transaction response with IBC acknowledgements if there are any.
Example:
import { coinsFromString, cosmos, getValueFromEvents, ibc } from "stridejs";
// Send tokens
const sendTx = await client.signAndBroadcast(
[
cosmos.bank.v1beta1.MessageComposer.withTypeUrl.send({
fromAddress: client.address,
toAddress: "stride1...",
amount: coinsFromString("1000000ustrd"),
}),
],
"auto", // automatic gas estimation
);
if (sendTx.code === 0) {
// success
}
// IBC transfer
const ibcTx = await client.signAndBroadcast([
ibc.applications.transfer.v1.MessageComposer.withTypeUrl.transfer({
sourcePort: "transfer",
sourceChannel: "chennel-123",
token: coinFromString("100000ustrd"),
sender: "stride1...",
receiver: "osmo1...",
timeoutHeight: {
revisionNumber: 0n,
revisionHeight: 0n,
},
timeoutTimestamp: `${Math.floor(Date.now() / 1000) + 3 * 60}000000000`, // 3min
memo: "",
}),
// defaults to automatic gas estimation
]);
// Wait for IBC acknowledgements
const ibcAck = await ibcTx.ibcResponses[0];
if (
ibcAck.type === "ack" &&
ibcAck.tx.code === 0 &&
getValueFromEvents(ibcAck.tx.events, "fungible_token_packet.success") ===
"\u0001"
) {
// success
}type IbcResponse = {
type: "ack" | "timeout";
tx: IndexedTx;
};
type IbcTransferPath = {
incomingPortId: string;
incomingChannelId: string;
};function ibcDenom(paths: IbcTransferPath[], coinMinimalDenom: string): string;Computes the IBC denom of a token after being sent through IBC channels.
Example:
// Get STRD denom on Osmosis after transfer through channel-326
const osmoDenom = ibcDenom(
[
{
incomingPortId: "transfer",
incomingChannelId: "channel-326",
},
],
"ustrd",
);
// Get ATOM denom on Stride after transfer through multiple channels
const strideDenom = ibcDenom(
[
{
incomingPortId: "transfer",
incomingChannelId: "channel-0",
},
{
incomingPortId: "transfer",
incomingChannelId: "channel-1",
},
],
"uatom",
);function getTxIbcResponses(
stargateClient: StargateClient,
txResponse: DeliverTxResponse,
resolveResponsesTimeoutMs?: number,
resolveResponsesCheckIntervalMs?: number,
): Array<Promise<IbcResponse>>;Gets IBC acknowledgements or timeouts for an IBC transaction.
Example:
const tx = await client.signAndBroadcast([ibcTransferMsg], "auto");
const ibcResponses = await Promise.all(tx.ibcResponses);
for (const resp of ibcResponses) {
if (resp.type === "ack") {
console.log("IBC transfer succeeded");
} else {
console.log("IBC transfer reverted due to a timeout");
}
}async function findIbcResponse(
stargateClient: StargateClient,
packetSequence: string,
packetSrcChannel: string,
type: "ack" | "timeout" = "ack",
resolveResponsesTimeoutMs: number = 180000,
resolveResponsesCheckIntervalMs: number = 12000,
isDoneObject: { isDone: boolean } = { isDone: false },
): Promise<IbcResponse>;Low-level function to search for a specific IBC response. Usually used through getTxIbcResponses.
function getTxIbcResponses(
stargateClient: StargateClient,
txResponse: DeliverTxResponse,
resolveResponsesTimeoutMs: number = 180000,
resolveResponsesCheckIntervalMs: number = 12000,
): Array<Promise<IbcResponse>>;This function retrieves IBC acknowledgements or timeouts for a transaction that resulted in sending IBC packets. It returns an array of promises that resolve to IbcResponse objects, which can either be acknowledgements (ack) or timeouts (timeout).
This function is automatically used by StrideClient and is intended to be used with a CosmJS StargateClient, which may be connected to another chain.
function convertBech32Prefix(address: string, toPrefix: string): string;Converts a bech32 address from one prefix to another.
Example:
// Convert Stride address to Osmosis address
const osmoAddr = convertBech32Prefix("stride1xyz...", "osmo"); // osmo1xyz...
// Convert Stride address to Cosmos Hub address
const cosmosAddr = convertBech32Prefix("stride1xyz...", "cosmos"); // cosmos1xyz...function pubkeyToAddress(pubkey: Uint8Array, prefix: string = "stride"): string;Converts a secp256k1 compressed public key to a bech32 address.
function base64PubkeyToAddress(
pubkey: string,
prefix: string = "stride",
): string;Converts a base64 encoded secp256k1 compressed public key to a bech32 address.
function selfDelegatorAddressToValidatorAddress(
selfDelegator: string,
prefix: string = "stride",
): string;Converts a self-delegator address to its validator operator address.
Example:
const valoper = selfDelegatorAddressToValidatorAddress(
"stride1xyz...",
"stride",
); // stridevaloper1xyz...function validatorAddressToSelfDelegatorAddress(
validator: string,
prefix: string = "stride",
): string;Converts a validator operator address to its self-delegator address.
function tendermintPubkeyToValconsAddress(
pubkey: Uint8Array,
prefix: string = "stride",
): string;Converts a Tendermint ed25519 public key to a validator consensus address.
function base64TendermintPubkeyToValconsAddress(
pubkey: string,
prefix: string = "stride",
): string;Converts a base64 encoded Tendermint ed25519 public key to a validator consensus address.
function coinFromString(coinAsString: string): Coin;Converts a string representation of a coin to a Coin object.
Example:
coinFromString("1000ustrd"); // { amount: "1000", denom: "ustrd" }
coinFromString("2.5atom"); // { amount: "2.5", denom: "atom" }
coinFromString(
"1000ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2",
);function coinsFromString(coinsAsString: string): Coin[];Converts a comma-separated string of coins to an array of Coin objects.
Example:
coinsFromString("1000ustrd,500uatom");
// [
// { amount: "1000", denom: "ustrd" },
// { amount: "500", denom: "uatom" }
// ]function feeFromGas(gasLimit: number, gasPrice: number = 0.025): StdFee;Creates a StdFee object from gas limit and price.
Example:
feeFromGas(200000);
// {
// amount: [{ amount: "5000", denom: "ustrd" }],
// gas: "200000"
// }function getValueFromEvents(events: readonly Event[], key: string): string;Searches through events to find a specific value based on event type and attribute key.
Example:
const events = [
{
type: "transfer",
attributes: [
{ key: "recipient", value: "stride1..." },
{ key: "amount", value: "1000ustrd" },
],
},
];
getValueFromEvents(events, "transfer.recipient"); // "stride1..."
getValueFromEvents(events, "transfer.amount"); // "1000ustrd"function fromBase64(base64: string): Uint8Array;
function toBase64(data: Uint8Array): string;Convert between base64 strings and Uint8Arrays.
function fromHex(hex: string): Uint8Array;
function toHex(data: Uint8Array): string;Convert between hex strings and Uint8Arrays.
function fromAscii(ascii: string): Uint8Array;
function toAscii(data: Uint8Array): string;Convert between ASCII strings and Uint8Arrays.
function fromUtf8(utf8: string): Uint8Array;
function toUtf8(data: Uint8Array): string;Convert between UTF8 strings and Uint8Arrays.
function fromRfc3339(date: string): Date;
function toRfc3339(date: Date): string;Convert between RFC3339 date strings and Date objects.
function decToString(dec: number): string;Formats a decimal number to Cosmos SDK decimal string format.
Example:
decToString(0.5); // "0.500000000000000000"
decToString(1.23); // "1.230000000000000000"function sleep(ms: number): Promise<void>;Utility function to pause execution.

