Type registry system for managing protobuf message types with encoding and decoding capabilities. The Registry enables registration of custom message types and provides utilities for working with protobuf Any messages.
Central registry for managing protobuf message types and performing encoding/decoding operations.
/**
* A registry to manage protobuf message types for encoding and decoding
* Supports types generated by Telescope, ts-proto, and protobufjs
*/
class Registry {
/**
* Creates a new Registry instance
* @param customTypes - Optional iterable of [typeUrl, GeneratedType] pairs to register initially
*/
constructor(customTypes?: Iterable<[string, GeneratedType]>);
/**
* Registers a protobuf message type with the registry
* @param typeUrl - The type URL (e.g., "/cosmos.bank.v1beta1.MsgSend")
* @param type - The generated message type
*/
register(typeUrl: string, type: GeneratedType): void;
/**
* Looks up a registered message type
* @param typeUrl - The type URL to look up
* @returns The registered type or undefined if not found
*/
lookupType(typeUrl: string): GeneratedType | undefined;
/**
* Encodes an object into serialized protobuf bytes
* @param encodeObject - Object containing typeUrl and value to encode
* @returns Serialized protobuf bytes
*/
encode(encodeObject: EncodeObject): Uint8Array;
/**
* Encodes an object into a protobuf Any message
* @param encodeObject - Object containing typeUrl and value to encode
* @returns Encoded Any message
*/
encodeAsAny(encodeObject: EncodeObject): Any;
/**
* Encodes a transaction body with message encoding
* @param txBodyFields - Transaction body fields with messages to encode
* @returns Serialized TxBody bytes
*/
encodeTxBody(txBodyFields: TxBodyValue): Uint8Array;
/**
* Decodes a protobuf message into an object
* @param decodeObject - Object containing typeUrl and encoded bytes
* @returns Decoded message object
*/
decode(decodeObject: DecodeObject): any;
/**
* Decodes a transaction body with message decoding
* @param txBody - Serialized TxBody bytes
* @returns Decoded TxBody with messages
*/
decodeTxBody(txBody: Uint8Array): TxBody;
}Usage Examples:
import { Registry } from "@cosmjs/proto-signing";
import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx";
import { MsgDelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx";
// Create registry with initial types
const registry = new Registry([
["/cosmos.bank.v1beta1.MsgSend", MsgSend],
["/cosmos.staking.v1beta1.MsgDelegate", MsgDelegate],
]);
// Register additional types
registry.register("/cosmos.bank.v1beta1.MsgMultiSend", MsgMultiSend);
// Encode a message
const sendMsg = {
fromAddress: "cosmos1sender...",
toAddress: "cosmos1recipient...",
amount: [{ denom: "uatom", amount: "1000000" }],
};
const encodedAny = registry.encode({
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: sendMsg,
});
// Decode a message
const decoded = registry.decode({
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: encodedAny.value,
});Support for different protobuf code generation tools.
/**
* Union type for all supported protobuf generated types
*/
type GeneratedType = TelescopeGeneratedType | TsProtoGeneratedType | PbjsGeneratedType;
/**
* A type generated by Telescope 1.0
*/
interface TelescopeGeneratedType {
/** This may or may not exist depending on the code generator settings */
readonly typeUrl?: string;
readonly encode: (
message: any | { [k: string]: any },
writer?: BinaryWriter
) => BinaryWriter;
readonly decode: (input: Uint8Array, length?: number) => any;
readonly fromPartial: (object: any) => any;
}
/**
* A type generated by ts-proto
*/
interface TsProtoGeneratedType {
readonly encode: (message: any | { [k: string]: any }, writer?: protobuf.Writer) => protobuf.Writer;
readonly decode: (input: Uint8Array | protobuf.Reader, length?: number) => any;
readonly fromPartial: (object: any) => any;
}
/**
* A type generated by protobufjs for runtime type creation
*/
interface PbjsGeneratedType {
readonly create: (properties?: { [k: string]: any }) => any;
readonly encode: (message: any | { [k: string]: any }, writer?: protobuf.Writer) => protobuf.Writer;
readonly decode: (reader: protobuf.Reader | Uint8Array, length?: number) => any;
}Utility functions to identify which protobuf generator was used.
/**
* Type guard to check if a type was generated by Telescope
* @param type - The generated type to check
* @returns True if type is TelescopeGeneratedType
*/
function isTelescopeGeneratedType(type: GeneratedType): type is TelescopeGeneratedType;
/**
* Type guard to check if a type was generated by ts-proto
* @param type - The generated type to check
* @returns True if type is TsProtoGeneratedType
*/
function isTsProtoGeneratedType(type: GeneratedType): type is TsProtoGeneratedType;
/**
* Type guard to check if a type was generated by protobufjs
* @param type - The generated type to check
* @returns True if type is PbjsGeneratedType
*/
function isPbjsGeneratedType(type: GeneratedType): type is PbjsGeneratedType;
/**
* Type guard to check if an encode object is a TxBody
* @param encodeObject - The encode object to check
* @returns True if encodeObject is TxBodyEncodeObject
*/
function isTxBodyEncodeObject(encodeObject: EncodeObject): encodeObject is TxBodyEncodeObject;Usage Examples:
import {
Registry,
isTelescopeGeneratedType,
isTsProtoGeneratedType,
isPbjsGeneratedType
} from "@cosmjs/proto-signing";
const registry = new Registry();
const messageType = registry.lookupType("/cosmos.bank.v1beta1.MsgSend");
if (messageType) {
if (isTelescopeGeneratedType(messageType)) {
console.log("Generated by Telescope");
// Access Telescope-specific properties
} else if (isTsProtoGeneratedType(messageType)) {
console.log("Generated by ts-proto");
// Access ts-proto-specific properties
} else if (isPbjsGeneratedType(messageType)) {
console.log("Generated by protobufjs");
// Access protobufjs-specific properties
}
}interface EncodeObject {
/** Type URL identifying the message type */
readonly typeUrl: string;
/** The message value to encode */
readonly value: any;
}
interface DecodeObject {
/** Type URL identifying the message type */
readonly typeUrl: string;
/** Encoded message bytes */
readonly value: Uint8Array;
}
interface TxBodyEncodeObject extends EncodeObject {
/** Must be the TxBody type URL */
readonly typeUrl: "/cosmos.tx.v1beta1.TxBody";
/** TxBody message value */
readonly value: TxBodyValue;
}
interface TxBodyValue {
/** Array of transaction messages */
messages: readonly EncodeObject[];
/** Optional transaction memo */
memo?: string;
/** Optional timeout height */
timeoutHeight?: number | bigint;
/** Optional extension options */
extensionOptions?: readonly Any[];
/** Optional non-critical extension options */
nonCriticalExtensionOptions?: readonly Any[];
}
interface Any {
/** Type URL identifying the message type */
typeUrl: string;
/** Serialized message value */
value: Uint8Array;
}
interface TxBody {
/** Array of transaction messages */
messages: readonly Any[];
/** Optional transaction memo */
memo?: string;
/** Optional timeout height */
timeoutHeight?: bigint;
/** Optional extension options */
extensionOptions?: readonly Any[];
/** Optional non-critical extension options */
nonCriticalExtensionOptions?: readonly Any[];
}import { Registry, TxBodyEncodeObject } from "@cosmjs/proto-signing";
import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx";
import { MsgDelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx";
import { TxBody } from "cosmjs-types/cosmos/tx/v1beta1/tx";
// Create registry with common Cosmos SDK message types
const registry = new Registry([
["/cosmos.bank.v1beta1.MsgSend", MsgSend],
["/cosmos.staking.v1beta1.MsgDelegate", MsgDelegate],
["/cosmos.tx.v1beta1.TxBody", TxBody],
]);
// Create messages
const sendMsg: EncodeObject = {
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: {
fromAddress: "cosmos1sender...",
toAddress: "cosmos1recipient...",
amount: [{ denom: "uatom", amount: "1000000" }],
},
};
const delegateMsg: EncodeObject = {
typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
value: {
delegatorAddress: "cosmos1delegator...",
validatorAddress: "cosmosvaloper1validator...",
amount: { denom: "uatom", amount: "1000000" },
},
};
// Create transaction body
const txBodyValue: TxBodyEncodeObject = {
typeUrl: "/cosmos.tx.v1beta1.TxBody",
value: {
messages: [sendMsg, delegateMsg],
memo: "Multi-message transaction",
timeoutHeight: BigInt(1000000),
},
};
// Encode the transaction body
const txBodyBytes = registry.encode(txBodyValue);
// Later, decode the transaction body
const decodedTxBody = registry.decode({
typeUrl: "/cosmos.tx.v1beta1.TxBody",
value: txBodyBytes,
});
console.log("Decoded messages:", decodedTxBody.messages);