跳到主要内容

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;
}

属性

属性类别说明
isConnectedboolean连接状态
addressstring | null已连接地址
isUKeybooleanUKey Wallet 标识

事件流

事件参数说明
connect{ address }钱包已连接
disconnect-钱包连接已关闭
accountChangedaddress当前账户已切换

处理异常

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("已收到确认!");
}