Coinbase API 为有效产品 ID 返回 "product not found"

Coinbase API returning "product not found" for valid product ID

我目前正在使用沙盒 API,我可以查询产品,包括单个产品,但如果我尝试下买单,我得到的响应是 { message: 'Product not found' } .

这是我的代码:

async function cb_request( method, path, headers = {}, body = ''){

  var apiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
      apiSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
      apiPass = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';

  //get unix time in seconds
  var timestamp = Math.floor(Date.now() / 1000);

  // set the request message
  var message = timestamp + method + path + body;

  //create a hexedecimal encoded SHA256 signature of the message
  var key = Buffer.from(apiSecret, 'base64');
  var signature = crypto.createHmac('sha256', key).update(message).digest('base64');

  //create the request options object
  var baseUrl = 'https://api-public.sandbox.pro.coinbase.com';

  headers = Object.assign({},headers,{
      'CB-ACCESS-SIGN': signature,
      'CB-ACCESS-TIMESTAMP': timestamp,
      'CB-ACCESS-KEY': apiKey,
      'CB-ACCESS-PASSPHRASE': apiPass,
      'USER-AGENT': 'request'
  });

  // Logging the headers here to ensure they're sent properly
  console.log(headers);

  var options = {
      baseUrl: baseUrl,
      url: path,
      method: method,
      headers: headers
  };

  return new Promise((resolve,reject)=>{
    request( options, function(err, response, body){
      if (err) reject(err);
      resolve(JSON.parse(response.body));
    });
  });

}

async function main() {
  
  // This queries a product by id (successfully)
  try {
     console.log( await cb_request('GET','/products/BTC-USD') );
  }
  catch(e) {
     console.log(e);
  }

  // Trying to place a buy order here (using the same id as above) returns { message: 'Product not found' }
  var buyParams = {
    'type': 'market',
    'side': 'buy',
    'funds': '100',
    'product_id': 'BTC-USD'
  };

  try {
    var buy = await cb_request('POST','/orders',buyParams);
    console.log(buy);
  }
  catch(e) {
     console.log(e);
  }

}

main();

我试过在正文中发送参数,它以 invalid signature 响应,即使在字符串化时也是如此。我也尝试过使用 params shown in the API docs,但它也会响应 product not found

有什么想法吗? TIA

您需要向 /orders 端点发送 POST 请求,并将正文包含在请求负载中。

this question中有一些示例答案。

var options = {
    baseUrl: baseUrl,
    url: path,
    method: method,
    headers: headers
    json: true,
    body: body
}

request.post(options, function(err, response, body){
  if (err) reject(err);
  resolve(JSON.parse(response.body));
});

正如 j-petty 提到的,您需要按照 API documentation 中的描述,将数据作为 POST 操作的请求正文发送,所以这就是您收到“找不到产品”的原因。

这是基于您分享的内容的工作代码:

   var crypto = require('crypto');
    var request = require('request');
    
    async function cb_request( method, path, headers = {}, body = ''){
    
      var apiKey = 'xxxxxx',
          apiSecret = 'xxxxxxx',
          apiPass = 'xxxxxxx';
    
      //get unix time in seconds
      var timestamp = Math.floor(Date.now() / 1000);
    
      // set the request message
      var message = timestamp + method + path + body;
      console.log('######## message=' + message);
    
      //create a hexedecimal encoded SHA256 signature of the message
      var key = Buffer.from(apiSecret, 'base64');
      var signature = crypto.createHmac('sha256', key).update(message).digest('base64');
    
      //create the request options object
      var baseUrl = 'https://api-public.sandbox.pro.coinbase.com';
    
      headers = Object.assign({},headers,{
        'content-type': 'application/json; charset=UTF-8',
          'CB-ACCESS-SIGN': signature,
          'CB-ACCESS-TIMESTAMP': timestamp,
          'CB-ACCESS-KEY': apiKey,
          'CB-ACCESS-PASSPHRASE': apiPass,
          'USER-AGENT': 'request'
      });
    
      // Logging the headers here to ensure they're sent properly
      console.log(headers);
    
      var options = {
          'baseUrl': baseUrl,
          'url': path,
          'method': method,
          'headers': headers,
          'body': body
    
      };
    
      return new Promise((resolve,reject)=>{
        request( options, function(err, response, body){
          console.log(response.statusCode + "  " + response.statusMessage);
          if (err) reject(err);
          resolve(JSON.parse(response.body));
        });
      });
    
    }
    
    async function main() {
      
      // This queries a product by id (successfully)
      try {
        console.log('try to call product------->');
         console.log( await cb_request('GET','/products/BTC-USD') );
         console.log('product------------------->done');
      }
      catch(e) {
         console.log(e);
      }
    
      var buyParams = JSON.stringify({
        'type': 'market',
        'side': 'buy',
        'funds': '10',
        'product_id': 'BTC-USD'
      });
    
      try {
        console.log('try to call orders------->');
        var buy = await cb_request('POST','/orders', {}, buyParams);
        console.log(buy);
        console.log('orders----------------------->done');
    
      }
      catch(e) {
         console.log(e);
      }
    
    }
    
    main();

值得一提的是,沙盒 API 与生产环境 API 的结果不同。考虑以下 CURL。

沙盒API:

❯ curl --request GET \
     --url https://api-public.sandbox.exchange.coinbase.com/products/ETH-USD \
     --header 'Accept: application/json'
{"message":"NotFound"}%

生产 API:

❯ curl --request GET \
     --url https://api.exchange.coinbase.com/products/ETH-USD \
     --header 'Accept: application/json'
{"id":"ETH-USD","base_currency":"ETH","quote_currency":"USD","base_min_size":"0.00029","base_max_size":"2800","quote_increment":"0.01","base_increment":"0.00000001","display_name":"ETH/USD","min_market_funds":"1","max_market_funds":"4000000","margin_enabled":false,"fx_stablecoin":false,"max_slippage_percentage":"0.02000000","post_only":false,"limit_only":false,"cancel_only":false,"trading_disabled":false,"status":"online","status_message":"","auction_mode":false}%

您会注意到路径相同,但得到的结果不同,因此请记住这一点。出于测试目的,可以使用 BTC-USD。