我使用R与Gemini (https://docs.gemini.com/rest-api/)进行私人端点交互。我已经能够将我的问题减少到端点,在有效负载中需要超过2个参数。特别是,我试图查询/v1/mytrade端点(https://docs.gemini.com/rest-api/#get-past-trades),我认为它至少需要“request”、“nonce”和“符号”参数。我收到的错误代码是HTTP 400,Gemini将其描述为:
拍卖不开放或暂停,不符合时间,市场不开放,或请求格式错误;在私人API请求的情况下,丢失或格式错误的Gemini专用API身份验证标头。
对于只需要“请求”和“无”参数的其他端点,我没有问题,所以我很难理解哪一步是问题,因为这些查询需要类似的步骤来创建有效负载的base64编码、使用API机密的编码的签名以及带有该数据和API键的头部。
下面是我的示例代码,其中MY_API_SECRET和MY_API_KEY是实际秘密字符串和键字符串的占位符。
# Set variable for the gemini api URL
geminiHost <- "https://api.gemini.com"
# Set variable for the gemini endpoint
geminiEndpoint <- "/v1/mytrades"
# Create the symbol parameter
symbol <- 'btcusd'
# Create nonce parameter
currentTimeNonce <- round(as.numeric(Sys.time()) * 1000, 0)
# Create JSON payload
payload <-
toJSON(data.frame(
request = geminiEndpoint,
nonce = currentTimeNonce,
symbol = symbol
)) %>% gsub("\\[|\\]", "", .)
# Convert payload to base64
payloadBase64Enc <- base64_enc(payload)
# Create signature
signatureString <- sha384(payloadBase64Enc, key = 'MY_API_SECRET')
# Construct the complete URL
completeURL <- paste0(geminiHost, geminiEndpoint)
# Create header
hdr = c(
"Content-Type" = "text/plain",
"Content-Length" = "0",
"Cache-Control" = "no-cache",
"X-GEMINI-APIKEY" = "MY_API_KEY",
"X-GEMINI-PAYLOAD" = payloadBase64Enc,
"X-GEMINI-SIGNATURE" = signatureString
)
# Request API using the complete URL and the required headers
mytradesAPIResult <- fromJSON(httpPOST(completeURL,
httpheader = hdr,
verbose = TRUE))作为比较,请求/v1/orders端点(https://docs.gemini.com/rest-api/#get-active-orders)的以下代码确实返回了一个响应:
# Set variable for the gemini api URL
geminiHost <- "https://api.gemini.com"
# Set variable for the gemini endpoint
geminiEndpoint <- "/v1/orders"
# Create nonce parameter
currentTimeNonce <- round(as.numeric(Sys.time()) * 1000, 0)
# Create JSON payload
payload <-
toJSON(data.frame(request = geminiEndpoint, nonce = currentTimeNonce)) %>%
gsub("\\[|\\]", "", .)
# Convert payload to base64
payloadBase64Enc <- base64_enc(payload)
# Create signature
signatureString <- sha384(payloadBase64Enc, key = 'MY_API_SECRET')
# Construct the complete URL
completeURL <- paste0(geminiHost, geminiEndpoint)
# Create header
hdr = c(
"Content-Type" = "text/plain",
"Content-Length" = "0",
"Cache-Control" = "no-cache",
"X-GEMINI-APIKEY" = "MY_API_KEY",
"X-GEMINI-PAYLOAD" = payloadBase64Enc,
"X-GEMINI-SIGNATURE" = signatureString
)
# Request API using the complete URL and the required headers
mytradesAPIResult <- fromJSON(httpPOST(completeURL,
httpheader = hdr,
verbose = TRUE))因此,在后一种代码中,唯一的区别是geminiEndpoint和有效负载结构,正如上面提到的,它们只有两个必需的参数(请求和当前)。为了进一步扩展,我成功地命中了其他端点,如/v1/trade音量、/v1/心搏和/v1/balances,这些端点也只需要这两个参数,而/v1/order/status是另一个需要至少3个对我不起作用的参数的端点。
我很感激你能帮我弄清楚这件事出了什么问题。提前谢谢你!
发布于 2018-02-16 21:47:55
正如评论中提到的,当我发现我的问题时,我开始根据r2evans的回复编写一个等效的bash脚本。是R中的base64编码步骤导致了一些不寻常的输出。从我的原始脚本中可以看到,我使用的是"base64_enc()“函数,它是jsonlite包的一部分。作为一个简单的检查,我试图确认来自R的编码等于在shell中使用base64进行的等效编码,所以我首先尝试解码R结果。
在R中,3参数示例的有效载荷编码中出现了一个反斜杠字符'\‘,这是无效的Base64,并指出了我对base64_enc函数正在做什么的误解。我用base64_encode替换了openssl包,现在我的3个参数查询返回了结果。
https://stackoverflow.com/questions/48834067
复制相似问题