签署
这里演示如何通过 UKey Wallet Cosmos Provider 签名 Amino 交易、Direct 交易、任意消息以及支持以太坊签名的 Cosmos 生态链数据。
Amino 签名
Amino 适合仍使用传统编码的 Cosmos 交易:
const chainId = "cosmoshub-4";
const signer = "cosmos1demoaccount...";
const signDoc = {
chain_id: chainId,
account_number: "0",
sequence: "0",
fee: {
amount: [{ denom: "uatom", amount: "5000" }],
gas: "200000",
},
msgs: [
{
type: "cosmos-sdk/MsgSend",
value: {
from_address: signer,
to_address: "cosmos1demoaccount...",
amount: [{ denom: "uatom", amount: "1000000" }],
},
},
],
memo: "",
};
const callResult = await provider.signAmino(chainId, signer, signDoc);
console.log({
signed: callResult.signed, // 完成签名后的文档
signature: callResult.signature, // 返回参考:{ pub_key, signature }
});
Direct 签名(Protobuf)
Direct 签名适合现代 Protobuf 编码交易,也是多数新接入更常用的方式:
import { makeSignDoc } from "@cosmjs/proto-signing";
const chainId = "cosmoshub-4";
const signer = "cosmos1demoaccount...";
const signDoc = makeSignDoc(
bodyBytes, // 交易 body
authInfoBytes, // 带手续费信息的 authInfo
chainId,
accountNumber,
);
const callResult = await provider.signDirect(chainId, signer, signDoc);
console.log({
signed: callResult.signed,
signature: callResult.signature,
});
签名任意数据
signArbitrary 可用于登录认证或链下消息验证。建议在消息中加入域名、nonce 和时间戳:
const chainId = "cosmoshub-4";
const signer = "cosmos1demoaccount...";
const data = "登录 MyApp 时间:2024-01-01T00:00:00Z";
const signature = await provider.signArbitrary(chainId, signer, data);
// 校验签名
const isValid = await provider.verifyArbitrary(
chainId,
signer,
data,
signature,
);
console.log("签名校验结果:", isValid);
广播交易
const chainId = 'cosmoshub-4'
const txBytes = new Uint8Array([...]) // 已完成签名的交易字节
// 广播模式可选:'block'、'sync'、'async'
const callResult = await provider.sendTx(chainId, txBytes, 'sync')
console.log('交易哈希值:', callResult)
签名以太坊数据
部分 Cosmos 生态链支持以太坊风格签名,例如 Evmos:
const callResult = await provider.signEthereum(
chainId,
signer,
data, // 待签署的消息内容
"message", // 可选类型:'message' | 'transaction'
);
console.log("生成的签名:", callResult);
处理异常
try {
await provider.enable("cosmoshub-4");
} catch (error) {
if (error.code === 4001) {
console.log("用户已拒绝本次请求");
} else if (error.message.includes("not supported")) {
console.log("这条链暂不支持,请尝试 experimentalSuggestChain");
} else {
console.error("连接未成功:", error);
}
}