Я пытаюсь подключиться к API poloniex.com https://poloniex.com/support/api/ который говорит:

(Все вызовы торгового API отправляются через HTTP POST на https://poloniex.com/tradingApi и должны содержат следующие заголовки:

  • Ключ - Ваш ключ API.
  • Знак - POST-данные запроса, подписанные «секретом» вашего ключа в соответствии с методом HMAC-SHA512.

Кроме того, все запросы должны включать параметр POST "nonce". Параметр nonce - это целое число, которое всегда должно быть больше, чем использованный ранее одноразовый номер.)

Но я всегда получаю

{"error":"Invalid
API key\/secret pair."}

У меня hmac512Digest работает нормально, проверял.

В моем коде должно быть что-то не так.

Может кто-нибудь помочь?

   public class Pol2 {

    public static String POLONIEX_SECRET_KEY = "12345"; 
    public static String POLONIEX_API_KEY = "ABX"; 


    public static void main(String[] args) {
        try {
            accessPoloniex();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static final void accessPoloniex() throws IOException {

        final String nonce = String.valueOf(System.currentTimeMillis());

        String connectionString = "https://poloniex.com/tradingApi";

        String queryArgs = "command=returnBalances";

        String hmac512 = hmac512Digest(queryArgs, POLONIEX_SECRET_KEY);

        // Produce the output
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Writer writer = new OutputStreamWriter(out, "UTF-8");
        writer.append(queryArgs);
        writer.flush();

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(connectionString);
        post.addHeader("Key", POLONIEX_API_KEY); //or setHeader?
        post.addHeader("Sign", hmac512);  //or setHeader?

        post.setEntity(new ByteArrayEntity(out.toByteArray()));
        List<NameValuePair> params = new ArrayList<>();

        params.add(new BasicNameValuePair("command", "returnBalances"));
        params.add(new BasicNameValuePair("nonce", nonce));

        CloseableHttpResponse response = null;
        Scanner in = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(params));
            response = httpClient.execute(post);
            HttpEntity entity = response.getEntity();
            in = new Scanner(entity.getContent());
            while (in.hasNext()) {
                System.out.println(in.next());
            }
            EntityUtils.consume(entity);
        } finally {
            in.close();
            response.close();
        }
    }
}
3
PowerFlower 7 Сен 2016 в 15:12

3 ответа

Лучший ответ

Я просмотрел пример Python, на который они ссылались на своей странице. Параметр nonce должен быть добавлен к MAC вместе с командой, а окончательный MAC должен быть добавлен в формате с шестнадцатеричным кодированием:

String queryArgs = "command=returnBalances&nonce=" + nonce;
String hmac512 = hmac512Digest(queryArgs, POLONIEX_SECRET_KEY);

Также следующие

ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
writer.append(queryArgs);
writer.flush();
//...
post.setEntity(new ByteArrayEntity(out.toByteArray()));

Может быть уменьшен до

post.setEntity(new ByteArrayEntity(queryArgs.getBytes("UTF-8")));
2
Artjom B. 7 Сен 2016 в 19:39

Я боролся с этим сам и, наконец, заставил это работать. Вот очень простой рабочий пример:

public class PoloTest {

  public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, ClientProtocolException, IOException {

    String key = "YOUR API KEY HERE";
    String secret = "YOUR API SECRET HERE";
    String url = "https://poloniex.com/tradingApi";
    String nonce = String.valueOf(System.currentTimeMillis());
    String queryArgs = "command=returnBalances&nonce=" + nonce;

    Mac shaMac = Mac.getInstance("HmacSHA512");
    SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(), "HmacSHA512");
    shaMac.init(keySpec);
    final byte[] macData = shaMac.doFinal(queryArgs.getBytes());
    String sign = Hex.encodeHexString(macData);

    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpPost post = new HttpPost(url);
    post.addHeader("Key", key); 
    post.addHeader("Sign", sign);

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("command", "returnBalances"));
    params.add(new BasicNameValuePair("nonce", nonce));
    post.setEntity(new UrlEncodedFormEntity(params));

    CloseableHttpResponse response = httpClient.execute(post);
    HttpEntity responseEntity = response.getEntity();
    System.out.println(response.getStatusLine());
    System.out.println(EntityUtils.toString(responseEntity));
  }

}
4
helmy 29 Сен 2016 в 14:29

Параметр nonce должен иметь MAC-адрес вместе с командой ... Если хэш - это односторонняя функция, и Polo не знает, какой nonce я могу выбрать (или когда, если я использую UTC), как Polo извлекать что-нибудь значимое из того, что я им посылаю.

1
Adrian 8 Фев 2017 в 14:52