Files
18xchat/assets/Scripts/Main/Channel/wallet/LuffaWalletSDK.ts
T
2025-09-27 15:06:21 +08:00

163 lines
4.9 KiB
TypeScript

import { IWalletSDK } from "../core/IWalletSDK";
import { ISignCap } from "../core/ISignCap";
import { ITransactionCap } from "../core/ITransactionCap";
import { logger } from "db://assets/Scripts/Main/Common/Logger";
export class LuffaWalletSDK implements IWalletSDK, ISignCap, ITransactionCap {
private address: string | null = null;
private luffaId: any = null;
// 初始化
init(cb?: Function): void {
logger.log("Luffa 钱包初始化");
cb && cb();
}
// 连接钱包
connectWallet(cb: (address: string, publicKey?: string) => void): void {
logger.log("连接 Luffa 钱包");
const opts = {
api_name: "luffaWebRequest",
data: {
uuid: this.create16String(),
methodName: "connect",
initData: {
network: "endless", // endless 为主网, ends 为测试网
},
metadata: {
superBox: true,
url: "https://your-game-domain.com", // 建议填自己游戏的唯一标识
// icon: "https://your-game-domain.com/icon.png",
},
from: "",
data: {},
},
success: (res) => {
logger.log("Luffa connect success:", res);
this.address = res.data?.address ?? null;
this.luffaId = res.data?.uid ?? null;
cb(this.address ?? "", res.data?.publicKey ?? "");
},
fail: (err) => {
logger.error("Luffa connect fail:", err);
cb("", "");
},
};
wx.invokeNativePlugin(opts);
}
// 断开钱包连接
disconnectWallet(): void {
this.address = null;
}
// 获取当前钱包地址
getWalletAddress(): string | null {
return this.address;
}
// 签名消息 (单签)
async signMessage(message: string, options?: any): Promise<{ signature: string; fullMessage?: string }> {
logger.log("调用 Luffa 单签签名");
return new Promise((resolve, reject) => {
const opts = {
api_name: "luffaWebRequest",
data: {
uuid: this.create16String(),
methodName: "signMessageV2",
initData: { network: "endless" },
from: this.address ?? "",
data: {
message,
nonce: options?.nonce ?? Date.now(), // 默认用时间戳
address: options?.address ?? false,
application: options?.application ?? false,
chainId: options?.chainId ?? false,
},
},
success: (res) => {
logger.log("signMessageV2 success:", res);
resolve({
signature: res.data?.signature,
fullMessage: res.data?.fullMessage,
});
},
fail: (err) => {
logger.error("signMessageV2 fail:", err);
reject(err);
},
};
wx.invokeNativePlugin(opts);
});
}
// 签名交易
async signTransaction(rawData: any): Promise<{ signedData: string }> {
logger.log("签名交易", rawData);
return new Promise((resolve, reject) => {
const opts = {
api_name: "luffaWebRequest",
data: {
uuid: this.create16String(),
from: this.address ?? "",
methodName: "packageTransactionV2",
initData: { network: "endless" },
data: {
data: JSON.stringify(rawData),
},
},
success: (res) => {
logger.log("packageTransactionV2 success:", res);
resolve({ signedData: res.data?.rawData });
},
fail: (err) => {
logger.error("packageTransactionV2 fail:", err);
reject(err);
},
};
wx.invokeNativePlugin(opts);
});
}
// 发送交易(广播到链上)
async sendTransaction(signedData: string): Promise<{ hash: string }> {
logger.log("发送交易", signedData);
return new Promise((resolve, reject) => {
const opts = {
api_name: "luffaWebRequest",
data: {
uuid: this.create16String(),
from: this.address ?? "",
methodName: "signAndSubmitTransaction",
initData: { network: "endless" },
data: {
serializedTransaction: {
data: signedData,
},
},
},
success: (res) => {
logger.log("sendTransaction success:", res);
resolve({ hash: res.data?.hash });
},
fail: (err) => {
logger.error("sendTransaction fail:", err);
reject(err);
},
};
wx.invokeNativePlugin(opts);
});
}
// 工具:生成随机 16 长度字符串
private create16String(): string {
const len = 16;
const strVals = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
let randomStr = "";
for (let i = 0; i < len; i++) {
randomStr += strVals.charAt(Math.floor(Math.random() * strVals.length));
}
return randomStr;
}
}