195 lines
5.9 KiB
TypeScript
195 lines
5.9 KiB
TypeScript
import { IWalletSDK } from "../core/IWalletSDK";
|
|
import { ITransactionCap } from "../core/ITransactionCap";
|
|
import { logger } from "db://assets/Scripts/Main/Common/Logger";
|
|
|
|
export class LuffaWalletSDK implements IWalletSDK, ITransactionCap {
|
|
// 运行环境,endless 为主网, eds 为测试网
|
|
private network: string;
|
|
// 自己的钱包地址
|
|
private address: string | null = null;
|
|
// Luffa ID
|
|
private luffaId: any = null;
|
|
|
|
constructor() {
|
|
this.network = "eds";
|
|
}
|
|
|
|
// 初始化
|
|
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: this.network, // endless 为主网, eds 为测试网
|
|
},
|
|
metadata: {
|
|
superBox: true,
|
|
url: "https://xchat188.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 signTransaction(rawTx: any): Promise<{ signedData: string }> {
|
|
logger.log("签名交易:", rawTx);
|
|
if ("contract" in rawTx) {
|
|
return this.signTransactionV2(rawTx);
|
|
} else {
|
|
return this.signTransactionV1(rawTx);
|
|
}
|
|
}
|
|
|
|
// 签名交易,方法一
|
|
async signTransactionV1(rawTx: any): Promise<{ signedData: string }> {
|
|
return new Promise((resolve, reject) => {
|
|
// DATA
|
|
const DATA = {
|
|
module: "0x1", // 固定写死
|
|
moduleName: "endless_account", // 固定写死
|
|
functionName: "transfer", // 固定写死
|
|
data: JSON.stringify({
|
|
"1_address_address": rawTx.toAddress, // 对方钱包地址
|
|
"2_u128_amount": String(rawTx.amount * 100000000), // 金额 * 10^8
|
|
}),
|
|
argsData: [],
|
|
};
|
|
|
|
const opts = {
|
|
api_name: "luffaWebRequest",
|
|
data: {
|
|
uuid: this.create16String(), // 生成随机16位字符串
|
|
from: this.address ?? "", // 自己的钱包地址
|
|
methodName: "packageTransaction",
|
|
initData: {
|
|
network: this.network, // endless 为主网, eds 为测试网
|
|
},
|
|
data: DATA, // 传入构造好的 DATA
|
|
},
|
|
success: (res) => {
|
|
logger.log("packageTransactionV1 success:", res);
|
|
resolve({ signedData: res.data?.rawData });
|
|
},
|
|
fail: (err) => {
|
|
logger.error("packageTransactionV1 fail:", err);
|
|
reject(err);
|
|
},
|
|
};
|
|
wx.invokeNativePlugin(opts);
|
|
});
|
|
}
|
|
|
|
// 签名交易,方法二
|
|
async signTransactionV2(rawTx: any): Promise<{ signedData: string }> {
|
|
const payload = {
|
|
function: rawTx.contract, // 合约地址::合约名::函数名
|
|
functionArguments: rawTx.args ?? [],
|
|
typeArguments: rawTx.typeArgs ?? [],
|
|
typeEnum: []
|
|
};
|
|
|
|
const allData = {
|
|
payload,
|
|
secondarySignerAddresses: rawTx.secondarySigners ?? [], //多签地址集合 非多签可以不用
|
|
feePayer: rawTx.feePayer ?? "" //手续费
|
|
};
|
|
return new Promise((resolve, reject) => {
|
|
const opts = {
|
|
api_name: "luffaWebRequest",
|
|
data: {
|
|
uuid: this.create16String(),
|
|
from: this.address ?? "", //自己的钱包地址
|
|
methodName: "packageTransactionV2",
|
|
initData: { network: this.network },
|
|
data: {
|
|
data: JSON.stringify(allData),
|
|
},
|
|
},
|
|
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: this.network },
|
|
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;
|
|
}
|
|
}
|