Algorand
UKey Wallet Algorand Provider 用于在 Web 应用中连接 Algorand 账户、签名交易、广播交易和签名消息。页面中可通过 window.$ukey.algo 访问。
ℹ️
UKey Wallet Algorand Provider 同时支持传统接口和 ARC-0001 兼容接口,便于新旧项目接入。
快捷链接
找 Provider
// 检查 UKey Wallet Algorand provider
const provider = window.$ukey?.algo;
if (!provider) {
throw new Error("未检测到 UKey Wallet Algorand provider");
}
// 确认兼容性
console.log("isUKey:", provider.isUKey); // 布尔参考片段:true
快上手
连接(传统 API)
const { address } = await provider.connect();
console.log("连接结果:", address);
// 确认连接状态
console.log("isConnected:", provider.isConnected);
console.log("解析出的地址:", provider.address);
启用(ARC-0001)
const callResult = await provider.enable({
genesisID: "mainnet-v1.0",
genesisHash: "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=",
});
console.log("当前账户信息:", callResult.accounts);
console.log("网络创世哈希:", callResult.genesisHash);
断连
await provider.disconnect();
console.log("连接已关闭");
交易项
签名交易(ARC-0001)
下面这段参考代码构造一笔支付交易,编码后交给钱包签名:
import algosdk from "algosdk";
// 构建交易
const suggestedParams = await algodClient.getTransactionParams().do();
const txn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
from: senderAddress,
to: recipientAddress,
amount: 1000000, // one ALGO (微 Algos)
suggestedParams,
});
// 准备进行签名
const walletTxns = [
{
txn: Buffer.from(algosdk.encodeUnsignedTransaction(txn)).toString("base64"),
},
];
// 执行签名
const signedTxns = await provider.signTxns(walletTxns);
console.log("签名后的交易数据:", signedTxns);
签名多个交易
// 先做交易分组
const txns = [txn1, txn2, txn3];
algosdk.assignGroupID(txns);
// 准备进行签名
const walletTxns = txns.map((txn) => ({
txn: Buffer.from(algosdk.encodeUnsignedTransaction(txn)).toString("base64"),
}));
// 对所有交易一起签名
const signedTxns = await provider.signTxns(walletTxns);
部分签名(多签)
// 只签指定那几笔交易
const walletTxns = [
{ txn: encodedTxn1 },
{ txn: encodedTxn2, signers: [] }, // 这一笔跳过签名
{ txn: encodedTxn3 },
];
const signedTxns = await provider.signTxns(walletTxns);
// signedTxns[1] 会是 null
广播交易
广播已签名的交易:
const callResult = await provider.postTxns(signedTxns);
console.log("返回的交易 IDs:", callResult.txIDs);
签名并广播
一步完成签名和广播:
const callResult = await provider.signAndPostTxns(walletTxns);
console.log("返回的交易 IDs:", callResult.txIDs);
传统交易 API
签名交易(传统)
// 将交易构造成 Uint8Array
const txnBytes = algosdk.encodeUnsignedTransaction(txn);
// 执行签名
const signedTxnBytes = await provider.signTransaction([txnBytes]);
// 确认提交发送
const { txId } = await algodClient.sendRawTransaction(signedTxnBytes[0]).do();
签名并发送(传统)
const callResult = await provider.signAndSendTransaction([txnBytes]);
console.log("交易 ID 返回值:", callResult.txId);
消息签署
签名任意消息
const message = new TextEncoder().encode("Algorand sample message");
const { signature, address } = await provider.signMessage(
message,
"utf8", // 也可以传 'base64'
);
console.log("生成的签名:", signature);
console.log("恢复出的签名者:", address);
验证签名
import nacl from "tweetnacl";
const message = new TextEncoder().encode("Algorand sample message");
const { signature } = await provider.signMessage(message);
// 根据地址读取公钥
const publicKey = algosdk.decodeAddress(provider.address).publicKey;
const isValid = nacl.sign.detached.verify(message, signature, publicKey);
console.log("校验结果:", isValid);
事件流
看账户变化
provider.on("accountChanged", (address) => {
if (address) {
console.log("当前账户已切换为:", address);
} else {
console.log("连接已关闭");
}
});
监听连接
provider.on("connect", ({ address }) => {
console.log("连接结果:", address);
});
provider.on("disconnect", () => {
console.log("连接已关闭");
});
使用 Algod 客户端
从 Provider 获取客户端
// 读取预配置客户端
const algodClient = await provider.getAlgodv2Client();
const indexerClient = await provider.getIndexerClient();
// 调用方式如下该客户端
const status = await algodClient.status().do();
console.log("网络状态回报:", status);
手动设置客户端
import algosdk from "algosdk";
const algodClient = new algosdk.Algodv2(
"", // Token(公共节点可省略)
"https://mainnet-api.algonode.cloud",
"",
);
const indexerClient = new algosdk.Indexer(
"",
"https://mainnet-idx.algonode.cloud",
"",
);
API说明
方法集
| 方法 | 说明 |
|---|---|
connect() | 连接钱包(传统) |
disconnect() | 断开钱包连接 |
enable(opts?) | 启用钱包 (ARC-0001) |
signTxns(transactions) | 签名交易 (ARC-0001) |
postTxns(signedTxns) | 广播交易 |
signAndPostTxns(transactions) | 签名并广播 |
signTransaction(txns) | 签名交易(传统) |
signAndSendTransaction(txns) | 签名并发送(传统) |
signMessage(message, encoding?) | 签名任意消息 |
getAlgodv2Client() | 获取 Algod 客户端 |
getIndexerClient() | 获取 Indexer 客户端 |
类型集
interface EnableOpts {
genesisID?: string;
genesisHash?: string;
}
interface EnableResult {
genesisID: string;
genesisHash: string;
accounts: string[];
}
interface WalletTransaction {
txn: string; // Base64 形式的未签名交易
signers?: string[]; // 需要签名的地址(留空表示跳过)
stxn?: string; // 已预签名交易
message?: string; // 展示给用户的消息内容
msig?: MultisigMetadata;
authAddr?: string; // rekey 后的认证地址
}
interface SignTxnsResult {
// Base64 格式的已签名交易数组(跳过项为 null)
[index: number]: string | null;
}
interface PostTxnsResult {
txIDs: string[];
}
interface TransactionResult {
txId: string;
}
属性
| 属性 | 类别 | 说明 |
|---|---|---|
isConnected | boolean | 连接状态 |
address | string | null | 已连接地址 |
isUKey | boolean | UKey Wallet 标识 |
事件流
| 事件 | 参数 | 说明 |
|---|---|---|
connect | { address } | 钱包已连接 |
disconnect | - | 钱包连接已关闭 |
accountChanged | address | 当前账户已切换 |
处理异常
try {
const signedTxns = await provider.signTxns(walletTxns);
} catch (error) {
if (error.code === 4001) {
console.log("用户已拒绝本次请求");
} else if (error.code === 4100) {
console.log("钱包当前处于锁定状态");
} else {
console.error("执行报错:", error.message);
}
}
常见错误码
| 错误码 | 说明 |
|---|---|
| 4001 | 用户取消了本次请求 |
| 4100 | 尚未完成授权 |
| 4200 | 当前方法不可用 |
| 4300 | 输入内容不合法 |
整例
import algosdk from "algosdk";
async function submitAlgoTransfer() {
// 建立连接
const provider = window.$ukey?.algo;
const { address } = await provider.connect();
// 配置客户端
const algodClient = new algosdk.Algodv2(
"",
"https://mainnet-api.algonode.cloud",
"",
);
// 读取参数
const suggestedParams = await algodClient.getTransactionParams().do();
// 构建交易
const txn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
from: address,
to: "TARGET_ACCOUNT_ADDRESS",
amount: 1000000, // one ALGO
suggestedParams,
});
// 执行签名
const walletTxns = [
{
txn: Buffer.from(algosdk.encodeUnsignedTransaction(txn)).toString(
"base64",
),
},
];
const signedTxns = await provider.signTxns(walletTxns);
// 确认提交发送
const { txId } = await algodClient
.sendRawTransaction(Buffer.from(signedTxns[0], "base64"))
.do();
console.log("交易 ID 返回值:", txId);
// 等待链上确认
await algosdk.waitForConfirmation(algodClient, txId, 4);
console.log("已收到确认!");
}