CosmJS模块化开发:从基础包到自定义Stargate模块全攻略
CosmJS模块化开发:从基础包到自定义Stargate模块全攻略
【免费下载链接】cosmjsThe Swiss Army knife to power JavaScript based client solutions ranging from Web apps/explorers over browser extensions to server-side clients like faucets/scrapers.项目地址: https://gitcode.com/gh_mirrors/co/cosmjs
CosmJS作为Cosmos生态系统中强大的JavaScript开发工具包,提供了从Web应用、浏览器扩展到服务器端客户端(如水龙头和刮板)的全方位支持。本文将带您深入了解CosmJS的模块化架构,从核心基础包到自定义Stargate模块的完整开发流程,帮助您快速掌握这一瑞士军刀级工具的使用方法。
一、CosmJS模块化架构解析
CosmJS采用了精心设计的模块化架构,通过多个npm包组成的monorepo形式提供功能。这种设计确保了代码质量,并让用户可以精确选择所需功能。
核心包概览
CosmJS生态包含多个核心包,每个包专注于特定功能:
- @cosmjs/stargate(packages/stargate): 用于Cosmos SDK 0.40+(Stargate)的客户端库
- @cosmjs/cosmwasm(packages/cosmwasm): 支持CosmWasm模块的Stargate链客户端
- @cosmjs/crypto(packages/crypto): 区块链项目的加密功能,包括哈希、签名、HD密钥派生等
- @cosmjs/encoding(packages/encoding): 区块链项目的编码辅助工具
- @cosmjs/math(packages/math): 安全整数和金融金额处理的小数运算
模块化依赖关系
CosmJS的模块化设计体现在清晰的依赖关系上。每个包都有明确的职责,右侧包依赖于左侧包:
如果您需要查看包含应用运行时依赖的完整版本,可以查看cosmjs-tree-full.png。
二、开发环境搭建
开始使用CosmJS进行模块化开发前,需要准备以下开发环境:
系统要求
- Node.js 20+
- 现代浏览器(Chromium/Firefox/Safari)
- 浏览器扩展开发环境(如需要)
- TypeScript支持
安装依赖
首先,克隆CosmJS仓库:
git clone https://gitcode.com/gh_mirrors/co/cosmjs cd cosmjs然后安装项目依赖:
yarn install对于特定功能开发,您可能需要安装以下核心包:
"dependencies": { "@cosmjs/proto-signing": "^0.26.4", "@cosmjs/stargate": "^0.26.4", "@cosmjs/tendermint-rpc": "^0.26.4" }同时,安装开发依赖:
yarn add --dev ts-proto您还需要安装protoc(Protocol Buffers编译器),本文基于版本3.17。
三、基础包使用指南
1. 加密功能 (@cosmjs/crypto)
packages/crypto提供了区块链开发所需的各种加密功能:
- 哈希算法(SHA-2, Keccak256, Ripemd160)
- 签名算法(secp256k1, ed25519)
- HD密钥派生(BIP-39, SLIP-0010)
- 密钥存储的KDF和对称加密(PBKDF2, Argon2, XChaCha20Poly1305)
基本使用示例:
import { sha256, secp256k1 } from "@cosmjs/crypto"; // 哈希计算 const hash = sha256(Buffer.from("hello world")); // 密钥对生成 const { privkey, pubkey } = await secp256k1.generateKeyPair(); // 签名 const message = Buffer.from("important message"); const signature = await secp256k1.sign(privkey, message);2. 编码功能 (@cosmjs/encoding)
packages/encoding提供了区块链开发中常用的编码和解码功能:
- Base64编码/解码
- Bech32地址编码
- Hex编码/解码
- UTF8字符串处理
使用示例:
import { bech32, base64, hex } from "@cosmjs/encoding"; // Bech32地址编码 const address = bech32.encode("cosmos", new Uint8Array([0x01, 0x02, 0x03])); // Base64编码 const encoded = base64.encode(Buffer.from("hello")); // Hex编码 const hexString = hex.encode(Buffer.from("hello"));3. 数学功能 (@cosmjs/math)
packages/math提供了安全处理整数和金融金额的功能:
import { Decimal, Int53 } from "@cosmjs/math"; // 安全整数处理 const safeNumber = Int53.fromString("9007199254740991"); // 小数运算(金融金额) const amount = Decimal.fromUserInput("123.456", 6); const doubled = amount.multiply(Decimal.fromAtomics("2", 0));四、Stargate客户端开发
packages/stargate是CosmJS的核心包,提供了与Cosmos SDK 0.40+(Stargate)兼容的客户端功能。
1. 连接到区块链
import { StargateClient } from "@cosmjs/stargate"; async function connect() { const client = await StargateClient.connect("https://rpc.cosmos.network"); console.log("Connected to chain:", await client.getChainId()); console.log("Latest block height:", await client.getHeight()); } connect();2. 创建签名客户端
import { DirectSecp256k1HdWallet, SigningStargateClient } from "@cosmjs/stargate"; async function createSigningClient() { const mnemonic = "economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone"; const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: "cosmos" }); const client = await SigningStargateClient.connectWithSigner( "https://rpc.cosmos.network", wallet ); return client; }3. 发送交易
async function sendTokens() { const client = await createSigningClient(); const [firstAccount] = await client.getAccounts(); const recipient = "cosmos1abcdefghijklmnopqrstuvwxyz"; const amount = [{ denom: "uatom", amount: "100000" }]; const fee = { amount: [{ denom: "uatom", amount: "500" }], gas: "200000", }; const result = await client.sendTokens(firstAccount.address, recipient, amount, fee); console.log("Transaction hash:", result.transactionHash); } sendTokens();五、自定义Stargate模块开发全流程
CosmJS不仅支持标准Cosmos SDK模块,还允许您为自定义模块开发客户端支持。以下是创建自定义Stargate模块客户端的完整流程。
步骤1:获取Protocol Buffer定义文件
首先,您需要获取自定义模块的.proto定义文件。通常有两种方式:
- 从外部源下载副本到项目中,例如使用脚本下载
- 使用Git子模块链接外部仓库
CosmJS使用脚本下载定义文件的示例可参考此脚本。
步骤2:生成TypeScript编解码器
使用ts-proto生成TypeScript编解码器:
protoc \ --plugin="./node_modules/.bin/protoc-gen-ts_proto" \ --ts_proto_out="./path/to/output/directory" \ --proto_path="./path/to/definitions" \ --ts_proto_opt="esModuleInterop=true,forceLong=long,useOptionals=true" \ "./path/to/definitions/file.proto"CosmJS的stargate包使用的生成脚本可参考此处。
步骤3:使用自定义消息类型
创建包含自定义消息的签名客户端
import { DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing"; import { defaultRegistryTypes, SigningStargateClient } from "@cosmjs/stargate"; import { MsgXxx } from "./path/to/generated/codec/my/custom/tx"; // 创建包含自定义类型的注册表 const myRegistry = new Registry(defaultRegistryTypes); myRegistry.register("/my.custom.MsgXxx", MsgXxx); async function createCustomClient() { const mnemonic = "your mnemonic here"; const signer = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: "myprefix" }); const client = await SigningStargateClient.connectWithSigner( "my.endpoint.com", signer, { registry: myRegistry } ); return client; }发送自定义消息
async function sendCustomMessage() { const client = await createCustomClient(); const [firstAccount] = await client.getAccounts(); const message = { typeUrl: "/my.custom.MsgXxx", value: MsgXxx.fromPartial({ foo: "bar", creator: firstAccount.address, }), }; const fee = { amount: [{ denom: "udenom", amount: "120000" }], gas: "100000", }; const response = await client.signAndBroadcast(firstAccount.address, [message], fee); console.log("Custom message sent. Transaction hash:", response.transactionHash); }步骤4:创建自定义查询服务
实例化查询客户端
import { createProtobufRpcClient, QueryClient } from "@cosmjs/stargate"; import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; import { QueryClientImpl } from "./path/to/generated/codec/my/custom/query"; async function createCustomQueryClient() { const tendermintClient = await Tendermint34Client.connect("my.endpoint.com"); const queryClient = new QueryClient(tendermintClient); const rpcClient = createProtobufRpcClient(queryClient); return new QueryClientImpl(rpcClient); }扩展查询客户端
// 定义扩展 function setupXxxExtension(base: QueryClient) { const rpcClient = createProtobufRpcClient(base); const queryService = new QueryClientImpl(rpcClient); return { mymodule: { customQuery: async (foo: string) => queryService.MyCustomQuery({ foo }), anotherQuery: async () => queryService.MyAnotherQuery({}), }, }; } // 使用扩展 async function useExtendedQueryClient() { const tendermintClient = await Tendermint34Client.connect("my.endpoint.com"); const queryClient = QueryClient.withExtensions(tendermintClient, setupXxxExtension); const result = await queryClient.mymodule.customQuery("bar"); console.log("Custom query result:", result); }CosmJS如何为默认查询客户端设置bank扩展的示例可参考此处。
六、Webpack配置
使用Webpack 5时,需要显式配置Node.js类型和模块:
module.exports = { plugins: [ new webpack.ProvidePlugin({ Buffer: ["buffer", "Buffer"], }), ], resolve: { fallback: { buffer: false, crypto: false, events: false, path: false, stream: false, string_decoder: false, }, }, };对于CosmJS < 0.28版本,stream配置有所不同:
resolve: { fallback: { // ...其他配置 stream: require.resolve("stream-browserify"), }, }七、总结与进阶资源
CosmJS的模块化设计为Cosmos生态系统的JavaScript开发提供了强大支持。通过本文介绍的基础包使用和自定义Stargate模块开发流程,您可以构建从简单查询到复杂交易的全方位区块链应用。
进阶学习资源
- 完整API文档:cosmos.github.io/cosmjs
- CosmJS示例:guided tour
- 测试用例:signingstargateclient.spec.ts
- 自定义模块文档:CUSTOM_PROTOBUF_CODECS.md
通过这些资源,您可以进一步探索CosmJS的强大功能,开发出更加复杂和高效的Cosmos生态应用。无论您是构建Web应用、浏览器扩展还是服务器端工具,CosmJS的模块化设计都能满足您的需求,让开发过程更加灵活和高效。
【免费下载链接】cosmjsThe Swiss Army knife to power JavaScript based client solutions ranging from Web apps/explorers over browser extensions to server-side clients like faucets/scrapers.项目地址: https://gitcode.com/gh_mirrors/co/cosmjs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
