diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/entity/Account.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/entity/Account.kt index 15ec399..fd5056f 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/entity/Account.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/entity/Account.kt @@ -26,10 +26,10 @@ data class Account( val apiKey: String? = null, // Polymarket API Key(可选,明文存储) @Column(name = "api_secret", length = 500) - val apiSecret: String? = null, // Polymarket API Secret(可选,明文存储) + val apiSecret: String? = null, // Polymarket API Secret(可选,AES 加密存储) @Column(name = "api_passphrase", length = 500) - val apiPassphrase: String? = null, // Polymarket API Passphrase(可选,明文存储) + val apiPassphrase: String? = null, // Polymarket API Passphrase(可选,AES 加密存储) @Column(name = "account_name", length = 100) val accountName: String? = null, diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/AccountService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/AccountService.kt index 8eb9c60..3b1b96e 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/AccountService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/AccountService.kt @@ -30,7 +30,7 @@ class AccountService( ) { private val logger = LoggerFactory.getLogger(AccountService::class.java) - + // 市价单价格调整系数(在最优价基础上调整,确保更快成交) // 市价买单:bestAsk + BUY_PRICE_ADJUSTMENT(加价,确保能立即成交) // 市价卖单:bestBid - SELL_PRICE_ADJUSTMENT(减价,确保能立即成交) @@ -109,17 +109,19 @@ class AccountService( } } - // 7. 加密私钥 + // 7. 加密敏感信息 val encryptedPrivateKey = cryptoUtils.encrypt(request.privateKey) - + val encryptedApiSecret = apiKeyCreds.secret?.let { cryptoUtils.encrypt(it) } + val encryptedApiPassphrase = apiKeyCreds.passphrase?.let { cryptoUtils.encrypt(it) } + // 8. 创建账户 val account = Account( privateKey = encryptedPrivateKey, // 存储加密后的私钥 walletAddress = request.walletAddress, proxyAddress = proxyAddress, apiKey = apiKeyCreds.apiKey, - apiSecret = apiKeyCreds.secret, - apiPassphrase = apiKeyCreds.passphrase, + apiSecret = encryptedApiSecret, // 存储加密后的 API Secret + apiPassphrase = encryptedApiPassphrase, // 存储加密后的 API Passphrase accountName = request.accountName, isDefault = request.isDefault, isEnabled = request.isEnabled, @@ -420,10 +422,10 @@ class AccountService( ) } - // 使用 API 凭证(直接使用,无需解密) + // 解密 API 凭证 val apiKey = account.apiKey - val apiSecret = account.apiSecret - val apiPassphrase = account.apiPassphrase + val apiSecret = decryptApiSecret(account) + val apiPassphrase = decryptApiPassphrase(account) // 创建带认证的 API 客户端(需要钱包地址用于 POLY_ADDRESS 请求头) val clobApi = retrofitFactory.createClobApi(apiKey, apiSecret, apiPassphrase, account.walletAddress) @@ -573,26 +575,46 @@ class AccountService( val cleanKey = if (privateKey.startsWith("0x")) privateKey.substring(2) else privateKey return cleanKey.length == 64 && cleanKey.matches(Regex("^[0-9a-fA-F]{64}$")) } - + /** * 解密账户私钥 - * 支持向后兼容:如果私钥未加密(明文),直接返回 */ fun decryptPrivateKey(account: Account): String { return try { - // 尝试解密(如果已加密) - if (cryptoUtils.isEncrypted(account.privateKey)) { - cryptoUtils.decrypt(account.privateKey) - } else { - // 向后兼容:如果私钥未加密(可能是旧数据),直接返回 - logger.warn("账户 ${account.id} 的私钥未加密,建议重新导入账户以加密私钥") - account.privateKey - } + cryptoUtils.decrypt(account.privateKey) } catch (e: Exception) { logger.error("解密私钥失败: accountId=${account.id}", e) throw RuntimeException("解密私钥失败: ${e.message}", e) } } + + /** + * 解密账户 API Secret + */ + private fun decryptApiSecret(account: Account): String { + return account.apiSecret?.let { secret -> + try { + cryptoUtils.decrypt(secret) + } catch (e: Exception) { + logger.error("解密 API Secret 失败: accountId=${account.id}", e) + throw RuntimeException("解密 API Secret 失败: ${e.message}", e) + } + } ?: throw IllegalStateException("账户未配置 API Secret") + } + + /** + * 解密账户 API Passphrase + */ + private fun decryptApiPassphrase(account: Account): String { + return account.apiPassphrase?.let { passphrase -> + try { + cryptoUtils.decrypt(passphrase) + } catch (e: Exception) { + logger.error("解密 API Passphrase 失败: accountId=${account.id}", e) + throw RuntimeException("解密 API Passphrase 失败: ${e.message}", e) + } + } ?: throw IllegalStateException("账户未配置 API Passphrase") + } /** * 查询所有账户的仓位列表 @@ -683,32 +705,32 @@ class AccountService( // 1. 验证账户是否存在且已配置API凭证 val account = accountRepository.findById(request.accountId).orElse(null) ?: return Result.failure(IllegalArgumentException("账户不存在")) - + if (account.apiKey == null || account.apiSecret == null || account.apiPassphrase == null) { return Result.failure(IllegalStateException("账户未配置API凭证,无法创建订单")) } - + // 2. 验证仓位是否存在且数量足够 val positionsResult = getAllPositions() positionsResult.fold( onSuccess = { positionListResponse -> - val position = positionListResponse.currentPositions.find { - it.accountId == request.accountId && - it.marketId == request.marketId && - it.side == request.side + val position = positionListResponse.currentPositions.find { + it.accountId == request.accountId && + it.marketId == request.marketId && + it.side == request.side } - + if (position == null) { return Result.failure(IllegalArgumentException("仓位不存在")) } - + val positionQuantity = position.quantity.toSafeBigDecimal() val sellQuantity = request.quantity.toSafeBigDecimal() - + if (sellQuantity <= BigDecimal.ZERO) { return Result.failure(IllegalArgumentException("卖出数量必须大于0")) } - + if (sellQuantity > positionQuantity) { return Result.failure(IllegalArgumentException("卖出数量不能超过持仓数量")) } @@ -717,7 +739,7 @@ class AccountService( return Result.failure(Exception("查询仓位失败: ${e.message}")) } ) - + // 3. 获取 tokenId(从 conditionId 和 outcomeIndex 计算) // 需要先获取 tokenId,以便后续通过 CLOB API 获取三元及以上市场的价格 // 优先使用 outcomeIndex,如果没有则尝试从 side 推断(仅支持 YES/NO) @@ -735,16 +757,16 @@ class AccountService( } } val tokenId = tokenIdResult.getOrNull() - + if (tokenId == null) { logger.warn("无法获取 tokenId,将使用 market 参数: conditionId=${request.marketId}, side=${request.side}, outcomeIndex=${request.outcomeIndex}, error=${tokenIdResult.exceptionOrNull()?.message}") } - + // 4. 验证 tokenId if (tokenId == null) { return Result.failure(IllegalStateException("无法获取 tokenId,无法创建订单。请确保已配置 Ethereum RPC URL 或提供 outcomeIndex 参数")) } - + // 5. 确定卖出价格 // 市价单:从订单表获取最优价(通过 tokenId 获取对应 outcome 的订单表) // - 市价卖单:从订单表获取 bestBid(最高买入价),然后减去 SELL_PRICE_ADJUSTMENT @@ -765,13 +787,13 @@ class AccountService( // 限价订单:使用用户输入的价格 request.price ?: return Result.failure(IllegalArgumentException("限价订单必须提供价格")) } - + // 6. 验证价格 val priceDecimal = sellPrice.toSafeBigDecimal() if (priceDecimal <= BigDecimal.ZERO) { return Result.failure(IllegalArgumentException("价格必须大于0")) } - + // 7. 确定订单类型和过期时间 // 根据官方文档: // - GTC (Good-Til-Cancelled): expiration 必须为 "0" @@ -783,14 +805,14 @@ class AccountService( "LIMIT" -> "GTC" // Good-Til-Cancelled else -> "GTC" } - + // GTC 和 FOK 订单的 expiration 必须为 "0" // 只有 GTD 订单才需要设置具体的过期时间 val expiration = "0" - + // 7. 解密私钥 val decryptedPrivateKey = decryptPrivateKey(account) - + // 8. 创建并签名订单 val signedOrder = try { orderSigningService.createAndSignOrder( @@ -809,27 +831,40 @@ class AccountService( logger.error("创建并签名订单失败", e) return Result.failure(Exception("创建并签名订单失败: ${e.message}")) } - + // 8. 构建订单请求 - + val newOrderRequest = com.wrbug.polymarketbot.api.NewOrderRequest( order = signedOrder, owner = account.apiKey!!, // API Key orderType = orderType, deferExec = false ) - - // 9. 使用账户的API凭证创建订单 + + // 9. 解密 API 凭证并使用账户的API凭证创建订单 + val apiSecret = try { + decryptApiSecret(account) + } catch (e: Exception) { + logger.error("解密 API 凭证失败: accountId=${account.id}", e) + return Result.failure(IllegalStateException("解密 API 凭证失败: ${e.message}")) + } + val apiPassphrase = try { + decryptApiPassphrase(account) + } catch (e: Exception) { + logger.error("解密 API 凭证失败: accountId=${account.id}", e) + return Result.failure(IllegalStateException("解密 API 凭证失败: ${e.message}")) + } + val clobApi = retrofitFactory.createClobApi( account.apiKey!!, - account.apiSecret!!, - account.apiPassphrase!!, + apiSecret, + apiPassphrase, account.walletAddress ) - - + + val orderResponse = clobApi.createOrder(newOrderRequest) - + if (orderResponse.isSuccessful && orderResponse.body() != null) { val response = orderResponse.body()!! if (response.success) { @@ -864,12 +899,12 @@ class AccountService( Result.failure(e) } } - + /** * 从订单表获取最优价(用于市价单) * 支持多元市场(二元、三元及以上) * 委托给 PolymarketClobService.getOptimalPrice 方法 - * + * * @param tokenId token ID(通过 marketId 和 outcomeIndex 计算得出) * @param isSellOrder 是否为卖出订单(true: 卖单,需要 bestBid;false: 买单,需要 bestAsk) * @return 最优价格(已应用调整系数) @@ -883,7 +918,7 @@ class AccountService( sellPriceAdjustment = SELL_PRICE_ADJUSTMENT ) } - + /** * 获取市场价格 * 使用 Gamma API 获取价格信息,因为 Gamma API 支持 condition_ids 参数 @@ -893,17 +928,17 @@ class AccountService( // 使用 Gamma API 获取市场信息(支持 condition_ids 参数) val gammaApi = retrofitFactory.createGammaApi() val response = gammaApi.listMarkets(conditionIds = listOf(marketId)) - + if (response.isSuccessful && response.body() != null) { val markets = response.body()!! val market = markets.firstOrNull() - + if (market != null) { // 从 Gamma API 响应中提取价格信息 val bestBid = market.bestBid?.toString() val bestAsk = market.bestAsk?.toString() val lastPrice = market.lastTradePrice?.toString() - + // 计算中间价 = (bestBid + bestAsk) / 2 val midpoint = if (bestBid != null && bestAsk != null) { val bid = bestBid.toSafeBigDecimal() @@ -912,7 +947,7 @@ class AccountService( } else { null } - + Result.success( MarketPriceResponse( marketId = marketId, @@ -933,7 +968,7 @@ class AccountService( Result.failure(e) } } - + /** * 获取可赎回仓位统计 */ @@ -944,19 +979,19 @@ class AccountService( onSuccess = { positionListResponse -> // 筛选可赎回的仓位 val redeemablePositions = positionListResponse.currentPositions.filter { it.redeemable } - + // 如果指定了账户ID,进一步筛选 val filteredPositions = if (accountId != null) { redeemablePositions.filter { it.accountId == accountId } } else { redeemablePositions } - + // 计算总价值(赎回是1:1,所以价值等于数量) val totalValue = filteredPositions.fold(BigDecimal.ZERO) { sum, pos -> sum.add(pos.quantity.toSafeBigDecimal()) } - + // 转换为可赎回仓位信息列表 val redeemableInfoList = filteredPositions.map { pos -> com.wrbug.polymarketbot.dto.RedeemablePositionInfo( @@ -970,7 +1005,7 @@ class AccountService( value = pos.quantity // 赎回价值等于数量(1:1) ) } - + Result.success( com.wrbug.polymarketbot.dto.RedeemablePositionsSummary( totalCount = redeemableInfoList.size, @@ -988,7 +1023,7 @@ class AccountService( Result.failure(e) } } - + /** * 赎回仓位 * 支持多账户、多仓位赎回(自动按账户和市场分组) @@ -998,16 +1033,16 @@ class AccountService( if (request.positions.isEmpty()) { return Result.failure(IllegalArgumentException("赎回仓位列表不能为空")) } - + // 1. 验证仓位是否存在且可赎回 val positionsResult = getAllPositions() val allPositions = positionsResult.getOrElse { return Result.failure(Exception("查询仓位失败: ${it.message}")) } - + // 2. 按账户分组 val positionsByAccount = request.positions.groupBy { it.accountId } - + // 3. 验证所有账户是否存在 val accounts = mutableMapOf() for (accountId in positionsByAccount.keys) { @@ -1015,34 +1050,35 @@ class AccountService( ?: return Result.failure(IllegalArgumentException("账户不存在: $accountId")) accounts[accountId] = account } - + // 4. 验证并收集要赎回的仓位信息(按账户分组) val accountRedeemData = mutableMapOf>>() - val accountRedeemedInfo = mutableMapOf>() - + val accountRedeemedInfo = + mutableMapOf>() + for ((accountId, requestItems) in positionsByAccount) { val accountPositions = mutableListOf>() val accountInfo = mutableListOf() - + for (requestItem in requestItems) { val position = allPositions.currentPositions.find { it.accountId == accountId && - it.marketId == requestItem.marketId && - it.outcomeIndex == requestItem.outcomeIndex + it.marketId == requestItem.marketId && + it.outcomeIndex == requestItem.outcomeIndex } - + if (position == null) { return Result.failure(IllegalArgumentException("仓位不存在: accountId=$accountId, marketId=${requestItem.marketId}, outcomeIndex=${requestItem.outcomeIndex}")) } - + if (!position.redeemable) { return Result.failure(IllegalStateException("仓位不可赎回: accountId=$accountId, marketId=${requestItem.marketId}, outcomeIndex=${requestItem.outcomeIndex}")) } - + // 计算 indexSet = 2^outcomeIndex val indexSet = BigInteger.TWO.pow(requestItem.outcomeIndex) accountPositions.add(Pair(position, indexSet)) - + accountInfo.add( com.wrbug.polymarketbot.dto.RedeemedPositionInfo( marketId = position.marketId, @@ -1053,30 +1089,30 @@ class AccountService( ) ) } - + accountRedeemData[accountId] = accountPositions accountRedeemedInfo[accountId] = accountInfo } - + // 5. 对每个账户执行赎回 val accountTransactions = mutableListOf() var totalRedeemedValue = BigDecimal.ZERO - + for ((accountId, positions) in accountRedeemData) { val account = accounts[accountId]!! val redeemedInfo = accountRedeemedInfo[accountId]!! - + // 按市场分组(同一市场的仓位可以批量赎回) val positionsByMarket = positions.groupBy { it.first.marketId } - + // 对每个市场执行赎回 var lastTxHash: String? = null for ((marketId, marketPositions) in positionsByMarket) { val indexSets = marketPositions.map { it.second } - + // 解密私钥 val decryptedPrivateKey = decryptPrivateKey(account) - + // 调用区块链服务赎回仓位 val redeemResult = blockchainService.redeemPositions( privateKey = decryptedPrivateKey, @@ -1084,7 +1120,7 @@ class AccountService( conditionId = marketId, indexSets = indexSets ) - + redeemResult.fold( onSuccess = { txHash -> lastTxHash = txHash @@ -1095,13 +1131,13 @@ class AccountService( } ) } - + // 计算该账户的赎回总价值 val accountTotalValue = redeemedInfo.fold(BigDecimal.ZERO) { sum, info -> sum.add(info.value.toSafeBigDecimal()) } totalRedeemedValue = totalRedeemedValue.add(accountTotalValue) - + // 添加到交易列表 accountTransactions.add( com.wrbug.polymarketbot.dto.AccountRedeemTransaction( @@ -1112,7 +1148,7 @@ class AccountService( ) ) } - + // 6. 返回结果 Result.success( com.wrbug.polymarketbot.dto.PositionRedeemResponse( @@ -1126,7 +1162,7 @@ class AccountService( Result.failure(e) } } - + /** * 检查账户是否有活跃订单 * 使用账户的 API Key 查询该账户的活跃订单 @@ -1138,10 +1174,10 @@ class AccountService( return false } - // 使用 API 凭证(直接使用,无需解密) + // 解密 API 凭证 val apiKey = account.apiKey - val apiSecret = account.apiSecret - val apiPassphrase = account.apiPassphrase + val apiSecret = decryptApiSecret(account) + val apiPassphrase = decryptApiPassphrase(account) // 创建带认证的 API 客户端(需要钱包地址用于 POLY_ADDRESS 请求头) val clobApi = retrofitFactory.createClobApi(apiKey, apiSecret, apiPassphrase, account.walletAddress) diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyOrderTrackingService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyOrderTrackingService.kt index 9eb34be..9e8991f 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyOrderTrackingService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/CopyOrderTrackingService.kt @@ -41,24 +41,44 @@ class CopyOrderTrackingService( /** * 解密账户私钥 - * 支持向后兼容:如果私钥未加密(明文),直接返回 */ private fun decryptPrivateKey(account: Account): String { return try { - // 尝试解密(如果已加密) - if (cryptoUtils.isEncrypted(account.privateKey)) { - cryptoUtils.decrypt(account.privateKey) - } else { - // 向后兼容:如果私钥未加密(可能是旧数据),直接返回 - logger.warn("账户 ${account.id} 的私钥未加密,建议重新导入账户以加密私钥") - account.privateKey - } + cryptoUtils.decrypt(account.privateKey) } catch (e: Exception) { logger.error("解密私钥失败: accountId=${account.id}", e) throw RuntimeException("解密私钥失败: ${e.message}", e) } } + /** + * 解密账户 API Secret + */ + private fun decryptApiSecret(account: Account): String { + return account.apiSecret?.let { secret -> + try { + cryptoUtils.decrypt(secret) + } catch (e: Exception) { + logger.error("解密 API Secret 失败: accountId=${account.id}", e) + throw RuntimeException("解密 API Secret 失败: ${e.message}", e) + } + } ?: throw IllegalStateException("账户未配置 API Secret") + } + + /** + * 解密账户 API Passphrase + */ + private fun decryptApiPassphrase(account: Account): String { + return account.apiPassphrase?.let { passphrase -> + try { + cryptoUtils.decrypt(passphrase) + } catch (e: Exception) { + logger.error("解密 API Passphrase 失败: accountId=${account.id}", e) + throw RuntimeException("解密 API Passphrase 失败: ${e.message}", e) + } + } ?: throw IllegalStateException("账户未配置 API Passphrase") + } + /** * 处理交易事件(WebSocket 或轮询) * 根据交易方向调用相应的处理方法 @@ -227,11 +247,25 @@ class CopyOrderTrackingService( // 计算价格(应用价格容忍度) val buyPrice = calculateAdjustedPrice(trade.price.toSafeBigDecimal(), template, isBuy = true) + // 解密 API 凭证 + val apiSecret = try { + decryptApiSecret(account) + } catch (e: Exception) { + logger.warn("解密 API 凭证失败,跳过创建订单: accountId=${account.id}, error=${e.message}") + continue + } + val apiPassphrase = try { + decryptApiPassphrase(account) + } catch (e: Exception) { + logger.warn("解密 API 凭证失败,跳过创建订单: accountId=${account.id}, error=${e.message}") + continue + } + // 创建带认证的CLOB API客户端 val clobApi = retrofitFactory.createClobApi( account.apiKey!!, - account.apiSecret!!, - account.apiPassphrase!!, + apiSecret, + apiPassphrase, account.walletAddress ) @@ -467,7 +501,6 @@ class CopyOrderTrackingService( // 7. 解密私钥(在方法开始时解密一次,后续复用) val decryptedPrivateKey = decryptPrivateKey(account) - // 8. 创建并签名卖出订单 val signedOrder = try { orderSigningService.createAndSignOrder( diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/OrderPushService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/OrderPushService.kt index 97f3f57..138680e 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/OrderPushService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/OrderPushService.kt @@ -25,7 +25,8 @@ class OrderPushService( private val accountRepository: AccountRepository, private val objectMapper: ObjectMapper, private val clobService: PolymarketClobService, - private val retrofitFactory: RetrofitFactory // 用于创建 Gamma API 客户端(不需要认证) + private val retrofitFactory: RetrofitFactory, // 用于创建 Gamma API 客户端(不需要认证) + private val cryptoUtils: com.wrbug.polymarketbot.util.CryptoUtils ) { private val logger = LoggerFactory.getLogger(OrderPushService::class.java) @@ -152,6 +153,34 @@ class OrderPushService( account.apiSecret!!.isNotBlank() && account.apiPassphrase!!.isNotBlank() } + + /** + * 解密账户 API Secret + */ + private fun decryptApiSecret(account: Account): String { + return account.apiSecret?.let { secret -> + try { + cryptoUtils.decrypt(secret) + } catch (e: Exception) { + logger.error("解密 API Secret 失败: accountId=${account.id}", e) + throw RuntimeException("解密 API Secret 失败: ${e.message}", e) + } + } ?: throw IllegalStateException("账户未配置 API Secret") + } + + /** + * 解密账户 API Passphrase + */ + private fun decryptApiPassphrase(account: Account): String { + return account.apiPassphrase?.let { passphrase -> + try { + cryptoUtils.decrypt(passphrase) + } catch (e: Exception) { + logger.error("解密 API Passphrase 失败: accountId=${account.id}", e) + throw RuntimeException("解密 API Passphrase 失败: ${e.message}", e) + } + } ?: throw IllegalStateException("账户未配置 API Passphrase") + } /** * 为指定账户建立 User Channel 连接 @@ -236,11 +265,25 @@ class OrderPushService( */ private fun sendSubscribeMessage(client: PolymarketWebSocketClient, account: Account) { try { + // 解密 API 凭证 + val apiSecret = try { + decryptApiSecret(account) + } catch (e: Exception) { + logger.error("解密 API 凭证失败,无法发送订阅消息: accountId=${account.id}, error=${e.message}") + return + } + val apiPassphrase = try { + decryptApiPassphrase(account) + } catch (e: Exception) { + logger.error("解密 API 凭证失败,无法发送订阅消息: accountId=${account.id}, error=${e.message}") + return + } + val subscribeMessage = mapOf( "auth" to mapOf( "apiKey" to account.apiKey, - "secret" to account.apiSecret, - "passphrase" to account.apiPassphrase + "secret" to apiSecret, + "passphrase" to apiPassphrase ), "type" to "user", "markets" to emptyList(), // 空数组表示订阅所有市场 @@ -321,11 +364,25 @@ class OrderPushService( } // 通过 PolymarketClobService 获取订单详情(需要 L2 认证) + // 解密 API 凭证 + val apiSecret = try { + decryptApiSecret(account) + } catch (e: Exception) { + logger.error("解密 API 凭证失败,无法获取订单详情: accountId=${account.id}, error=${e.message}") + return null + } + val apiPassphrase = try { + decryptApiPassphrase(account) + } catch (e: Exception) { + logger.error("解密 API 凭证失败,无法获取订单详情: accountId=${account.id}, error=${e.message}") + return null + } + val result = clobService.getOrder( orderId = orderId, apiKey = account.apiKey!!, - apiSecret = account.apiSecret!!, - apiPassphrase = account.apiPassphrase!!, + apiSecret = apiSecret, + apiPassphrase = apiPassphrase, walletAddress = account.walletAddress )