跳到主要内容

签署

这里演示如何通过 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);
}
}