From d1f351108fb1340bef9c59042ea481c62fa40eb3 Mon Sep 17 00:00:00 2001 From: WrBug Date: Fri, 26 Dec 2025 01:50:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=B7=9F=E5=8D=95?= =?UTF-8?q?=E5=8D=96=E5=87=BA=E8=AE=A2=E5=8D=95=E7=9A=84=20API=20=E5=87=AD?= =?UTF-8?q?=E8=AF=81=E8=A7=A3=E5=AF=86=E5=92=8C=E7=B2=BE=E5=BA=A6=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复 processSellTrade 中 API 凭证未解密的问题,与 processBuyTrade 保持一致 - 修复 SELL 订单的 makerAmount 和 takerAmount 精度问题: - makerAmount (shares) 最多 2 位小数(符合 API 要求) - takerAmount (USDC) 最多 4 位小数(符合 API 要求) --- .../copytrading/orders/OrderSigningService.kt | 16 +++++----- .../statistics/CopyOrderTrackingService.kt | 29 ++++++++++++++----- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/orders/OrderSigningService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/orders/OrderSigningService.kt index 90a0dde..9705264 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/orders/OrderSigningService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/orders/OrderSigningService.kt @@ -100,8 +100,9 @@ class OrderSigningService { return OrderAmounts(makerAmount.toString(), takerAmount.toString()) } else { // SELL: makerAmount = size (shares), takerAmount = price * size (USDC) - // makerAmount 是 shares 数量,最多 4 位小数 - // takerAmount 是 USDC 金额,需要使用原始价格计算(与SDK保持一致) + // 根据 Polymarket API 要求: + // - makerAmount (shares) 最多 2 位小数 + // - takerAmount (USDC) 最多 4 位小数 val rawMakerAmt = roundDown(sizeDecimal, roundConfig.size) // takerAmount = price * size,使用原始价格计算(不使用舍入后的价格) @@ -109,16 +110,15 @@ class OrderSigningService { // 例如:0.9596 * 16.09 = 15.439964,而不是 0.96 * 16.09 = 15.4464 val rawTakerAmt = rawMakerAmt.multiply(priceDecimal) - // 确保 makerAmount 精度(shares,最多 4 位小数) - val finalMakerAmt = roundDown(rawMakerAmt, TAKER_AMOUNT_DECIMALS) + // 确保 makerAmount 精度(shares,最多 2 位小数,符合 API 要求) + val finalMakerAmt = roundDown(rawMakerAmt, MAKER_AMOUNT_DECIMALS) - // takerAmount 不进行舍入,直接使用精确计算结果转换为 wei - // parseUnits 会将 BigDecimal 转换为 wei(6 位小数),自动处理精度 - // 使用原始价格计算可以确保与SDK的结果一致 + // 确保 takerAmount 精度(USDC,最多 4 位小数,符合 API 要求) + val finalTakerAmt = roundDown(rawTakerAmt, TAKER_AMOUNT_DECIMALS) // 转换为 wei(6 位小数) val makerAmount = parseUnits(finalMakerAmt, COLLATERAL_TOKEN_DECIMALS) - val takerAmount = parseUnits(rawTakerAmt, COLLATERAL_TOKEN_DECIMALS) + val takerAmount = parseUnits(finalTakerAmt, COLLATERAL_TOKEN_DECIMALS) return OrderAmounts(makerAmount.toString(), takerAmount.toString()) } diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt index efd219c..fade4c3 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt @@ -848,9 +848,24 @@ open class CopyOrderTrackingService( return } - // 7. 解密私钥(在方法开始时解密一次,后续复用) + // 7. 解密 API 凭证 + val apiSecret = try { + decryptApiSecret(account) + } catch (e: Exception) { + logger.warn("解密 API 凭证失败,跳过创建卖出订单: accountId=${account.id}, error=${e.message}") + return + } + val apiPassphrase = try { + decryptApiPassphrase(account) + } catch (e: Exception) { + logger.warn("解密 API 凭证失败,跳过创建卖出订单: accountId=${account.id}, error=${e.message}") + return + } + + // 8. 解密私钥(在方法开始时解密一次,后续复用) val decryptedPrivateKey = decryptPrivateKey(account) - // 8. 创建并签名卖出订单 + + // 9. 创建并签名卖出订单 val signedOrder = try { orderSigningService.createAndSignOrder( privateKey = decryptedPrivateKey, @@ -869,7 +884,7 @@ open class CopyOrderTrackingService( return } - // 9. 构建订单请求 + // 10. 构建订单请求 // 跟单订单使用 FAK (Fill-And-Kill),允许部分成交,未成交部分立即取消 // 这样可以快速响应 Leader 的交易,避免订单长期挂单导致价格不匹配 val orderRequest = NewOrderRequest( @@ -879,15 +894,15 @@ open class CopyOrderTrackingService( deferExec = false ) - // 10. 创建带认证的CLOB API客户端 + // 11. 创建带认证的CLOB API客户端(使用解密后的凭证) val clobApi = retrofitFactory.createClobApi( account.apiKey, - account.apiSecret, - account.apiPassphrase, + apiSecret, + apiPassphrase, account.walletAddress ) - // 11. 调用API创建卖出订单(带重试机制,重试时会重新生成salt并重新签名) + // 12. 调用API创建卖出订单(带重试机制,重试时会重新生成salt并重新签名) val createOrderResult = createOrderWithRetry( clobApi = clobApi,