From 748920653746f76caab83dc55a8fb793d0edda11 Mon Sep 17 00:00:00 2001 From: chen wei bo <1025839511@qq.com> Date: Sun, 28 Sep 2025 23:04:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5Luffa=E9=92=B1=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/Scripts/Main/Channel/SDKManager.ts | 4 +- .../Main/Channel/core/ITransactionCap.ts | 6 +- .../Main/Channel/wallet/LuffaWalletSDK.ts | 118 +++++++++++------- .../Scripts/chat18x/payment/LuffaPayFlow.ts | 65 ++++++++-- .../Scripts/chat18x/payment/PaymentService.ts | 2 +- 5 files changed, 134 insertions(+), 61 deletions(-) diff --git a/assets/Scripts/Main/Channel/SDKManager.ts b/assets/Scripts/Main/Channel/SDKManager.ts index c2b1bb95..e8356065 100644 --- a/assets/Scripts/Main/Channel/SDKManager.ts +++ b/assets/Scripts/Main/Channel/SDKManager.ts @@ -154,12 +154,12 @@ export class SDKManager { } // 签名交易 - public async signTransaction(rawData: any): Promise<{ signedData: string }> { + public async signTransaction(rawTx: any): Promise<{ signedData: string }> { if (!this.walletSDK) return; // 判断是否实现交易能力 if ("signTransaction" in this.walletSDK) { const txCap = this.walletSDK as unknown as ITransactionCap; - return txCap.signTransaction(rawData); + return txCap.signTransaction(rawTx); } throw new Error("当前钱包 SDK 不支持 signTransaction 功能"); } diff --git a/assets/Scripts/Main/Channel/core/ITransactionCap.ts b/assets/Scripts/Main/Channel/core/ITransactionCap.ts index 3de565c6..3081fed7 100644 --- a/assets/Scripts/Main/Channel/core/ITransactionCap.ts +++ b/assets/Scripts/Main/Channel/core/ITransactionCap.ts @@ -5,12 +5,12 @@ export interface ITransactionCap { /** - * 签名交易(由 DApp 构造交易对象) + * 签名交易 * - * @param rawData 原始交易对象 + * @param rawTx 原始交易参数 * @returns 已签名交易 */ - signTransaction(rawData: any): Promise<{ signedData: string }>; + signTransaction(rawTx: any): Promise<{ signedData: string }>; /** * 发送交易(广播到链上) diff --git a/assets/Scripts/Main/Channel/wallet/LuffaWalletSDK.ts b/assets/Scripts/Main/Channel/wallet/LuffaWalletSDK.ts index b2a1fc6d..0a70fabe 100644 --- a/assets/Scripts/Main/Channel/wallet/LuffaWalletSDK.ts +++ b/assets/Scripts/Main/Channel/wallet/LuffaWalletSDK.ts @@ -1,12 +1,19 @@ 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 { +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 钱包初始化"); @@ -22,11 +29,11 @@ export class LuffaWalletSDK implements IWalletSDK, ISignCap, ITransactionCap { uuid: this.create16String(), methodName: "connect", initData: { - network: "endless", // endless 为主网, ends 为测试网 + network: this.network, // endless 为主网, eds 为测试网 }, metadata: { superBox: true, - url: "https://your-game-domain.com", // 建议填自己游戏的唯一标识 + url: "https://xchat188.com/", // 建议填自己游戏的唯一标识 // icon: "https://your-game-domain.com/icon.png", }, from: "", @@ -56,54 +63,79 @@ export class LuffaWalletSDK implements IWalletSDK, ISignCap, ITransactionCap { return this.address; } - // 签名消息 (单签) - async signMessage(message: string, options?: any): Promise<{ signature: string; fullMessage?: string }> { - logger.log("调用 Luffa 单签签名"); + // 签名交易 + 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) => { - 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, - }, + // 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 为测试网 }, - 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); + 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 signTransaction(rawData: any): Promise<{ signedData: string }> { - logger.log("签名交易", rawData); + // 签名交易,方法二 + 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 ?? "", + from: this.address ?? "", //自己的钱包地址 methodName: "packageTransactionV2", - initData: { network: "endless" }, + initData: { network: this.network }, data: { - data: JSON.stringify(rawData), + data: JSON.stringify(allData), }, }, success: (res) => { @@ -117,11 +149,11 @@ export class LuffaWalletSDK implements IWalletSDK, ISignCap, ITransactionCap { }; wx.invokeNativePlugin(opts); }); - } + } // 发送交易(广播到链上) async sendTransaction(signedData: string): Promise<{ hash: string }> { - logger.log("发送交易", signedData); + logger.log("发送交易(广播到链上)", signedData); return new Promise((resolve, reject) => { const opts = { api_name: "luffaWebRequest", @@ -129,7 +161,7 @@ export class LuffaWalletSDK implements IWalletSDK, ISignCap, ITransactionCap { uuid: this.create16String(), from: this.address ?? "", methodName: "signAndSubmitTransaction", - initData: { network: "endless" }, + initData: { network: this.network }, data: { serializedTransaction: { data: signedData, diff --git a/assets/Scripts/chat18x/payment/LuffaPayFlow.ts b/assets/Scripts/chat18x/payment/LuffaPayFlow.ts index d3640bc5..769fecac 100644 --- a/assets/Scripts/chat18x/payment/LuffaPayFlow.ts +++ b/assets/Scripts/chat18x/payment/LuffaPayFlow.ts @@ -9,20 +9,61 @@ import { type OpenStrategy } from "./PaymentOpener"; import { DataManager, DataId } from "db://assets/Scripts/chat18x/data/DataManager"; import { OrderData } from "db://assets/Scripts/chat18x/data/OrderData"; import { logger } from "db://assets/Scripts/Main/Common/Logger"; +import { SDKManager } from "db://assets/Scripts/Main/Channel/SDKManager"; export class LuffaPayFlow implements PaymentFlow { - constructor(private delayMs: number = 5000) {} + constructor(private delayMs: number = 10000) {} async run(orderId: string, _payUrl: string, _open: OpenStrategy): Promise { - // 延时 - await this.delay(this.delayMs); - // 开始轮询 - const data = await this.pollOrder(orderId); - // 刷新订单数据 - const orderData = DataManager.I.getDataById(DataId.Order); - orderData.applyQueryOrder(orderId, data); - // 返回结果 - return data; + try { + // 连接钱包(只需一次,如果已连过可以跳过) + const address = SDKManager.I.getWalletAddress(); + if (!address) { + logger.log("钱包未连接,开始连接 Luffa 钱包..."); + await new Promise((resolve, reject) => { + SDKManager.I.connectWallet((addr) => { + if (addr) { + logger.log("已连接 Luffa 钱包:", addr); + resolve(); + } else { + logger.error("Luffa 钱包连接失败"); + reject(new Error("Luffa 钱包连接失败")); + } + }); + }); + } + + // 构造交易参数 + const rawTx = { + toAddress: "Hm3g4xXM4JHt5EwFUcvVZ8RthR4KWUnR51fKHCbnKkiZ", // TODO + amount: 1 // TODO + }; + + // 签名交易 + const signed = await SDKManager.I.signTransaction(rawTx); + logger.log("Luffa 签名结果:", signed); + + // 发送交易 + const sent = await SDKManager.I.sendTransaction(signed.signedData); + logger.log("Luffa 交易已提交,hash:", sent.hash); + + // 等待一会再开始轮询 + await this.delay(this.delayMs); + + // 开始轮询订单状态 + const data = await this.pollOrder(orderId); + + // 刷新订单数据 + const orderData = DataManager.I.getDataById(DataId.Order); + orderData.applyQueryOrder(orderId, data); + + // 返回结果 + return data; + + } catch (e) { + logger.error("Luffa Payment process exception:", e); + return null; + } } async resume(orderId: string, _payUrl: string): Promise { @@ -33,8 +74,8 @@ export class LuffaPayFlow implements PaymentFlow { private async pollOrder(orderId: string) { const poller = new PaymentPoller(); return poller.poll(orderId, { - maxDurationMs: 10 * 60 * 1000, - startIntervalMs: 5000, + maxDurationMs: 2 * 60 * 1000, + startIntervalMs: 3000, maxIntervalMs: 10000, jitter: true, }, (d) => logger.log()); diff --git a/assets/Scripts/chat18x/payment/PaymentService.ts b/assets/Scripts/chat18x/payment/PaymentService.ts index 8b38989b..d9baac96 100644 --- a/assets/Scripts/chat18x/payment/PaymentService.ts +++ b/assets/Scripts/chat18x/payment/PaymentService.ts @@ -28,7 +28,7 @@ export class PaymentService { this.flowMap = new Map(); this.flowMap.set(PaymentMethod.CashPay, new CashInrFlow(this.waitAppResumeIfNeeded.bind(this))); this.flowMap.set(PaymentMethod.Web3, new WebUsdFlow(5000)); - this.flowMap.set(PaymentMethod.Luffa, new LuffaPayFlow(5000)); + this.flowMap.set(PaymentMethod.Luffa, new LuffaPayFlow(10000)); } /** 发起支付:创建订单→打开URL→回到App后开始轮询 */