79694810

Date: 2025-07-08 20:52:58
Score: 1
Natty:
Report link

The py3cw library likely follows this logic (based on community reports and reverse-engineering the source):

  1. Send the POST /v2/smart_trades request.

  2. Receive 204 No Content response.

  3. Immediately fetch the latest trades using:

    GET /v2/smart_trades?account_id=XXX&limit=1

    or

    GET /v2/smart_trades?account_id=XXX&pair=YYY

  4. Optionally filter by status=created or check timestamps to get the most recent.

    The trade ID is then extracted from that result.

    Recommended Solution in Your Node.js Code

    After receiving the 204, immediately fetch the latest smart trades and extract the newest one:

    const axios = require('axios');
    const crypto = require('crypto');
    
    class ThreeCommasClient {
      constructor(apiKey, apiSecret) {
        this.apiKey = apiKey;
        this.apiSecret = apiSecret;
        this.baseUrl = 'https://api.3commas.io/v2';
      }
    
      _generateSignature(timestamp, path, data = '') {
        return crypto
          .createHmac('sha256', this.apiSecret)
          .update(timestamp + path + data)
          .digest('hex');
      }
    
      _buildPath(entity, actionId = null, subId = null) {
        let path = `/${entity}`;
        if (actionId) path += `/${actionId}`;
        if (subId) path += `/${subId}`;
        return path;
      }
    
      async _sendRequest(method, path, payload = null, query = '') {
        const timestamp = Date.now().toString();
        const dataStr = payload ? JSON.stringify(payload) : '';
        const fullPath = path + query;
        const signature = this._generateSignature(timestamp, fullPath, dataStr);
    
        try {
          const response = await axios({
            method,
            url: `${this.baseUrl}${path}${query}`,
            headers: {
              'APIKEY': this.apiKey,
              'Signature': signature,
              'Nonce': timestamp,
              'Content-Type': 'application/json'
            },
            ...(payload && ['POST', 'PUT'].includes(method) && { data: dataStr }),
            validateStatus: status => status === 204 || status < 400
          });
    
          return [null, response.status === 204 ? null : response.data];
        } catch (error) {
          const message = error.response?.data || error.message;
          return [{ error: true, msg: message }, {}];
        }
      }
    
      async request(entity, action, actionId = null, subId = null, payload = null) {
        const path = this._buildPath(entity, actionId, subId);
    
        // Special case: smart_trades new (204 response handling)
        if (entity === 'smart_trades' && action === 'new') {
          const [postErr] = await this._sendRequest('POST', path, payload);
          if (postErr) return [postErr, {}];
    
          // Immediately fetch the latest smart trade to get the ID
          const query = `?account_id=${payload.account_id}&limit=1`;
          const [getErr, getData] = await this._sendRequest('GET', '/smart_trades', null, query);
    
          if (getErr) return [getErr, {}];
          return getData?.length ? [null, getData[0]] : [null, { success: true, message: 'Trade created, but ID not retrieved' }];
        }
    
        // Generic handler
        const methodMap = {
          get: 'GET',
          post: 'POST',
          put: 'PUT',
          delete: 'DELETE',
          new: 'POST',
          update: 'PUT'
        };
    
        const method = methodMap[action.toLowerCase()] || 'GET';
        return this._sendRequest(method, path, payload);
      }
    }
    
    // Usage Example
    const client = new ThreeCommasClient('my_api_key', 'my_api_secret');
    
    async function createSmartTrade() {
      const payload = {
        account_id: 12345678,
        pair: 'ADA_USDT',
        instant: true,
        position: {
          type: 'buy',
          units: { value: '10' },
          order_type: 'market'
        },
        take_profit: { enabled: false },
        stop_loss: { enabled: false },
        demo: true
      };
    
      const [error, data] = await client.request('smart_trades', 'new', null, null, payload);
    
      if (error) {
        console.error('❌ Failed to create smart trade:', error.msg);
      } else {
        console.log('✅ Smart trade created:', data);
      }
    }
    
    

    Optional Improvement: Add Retry with Delay

    Since the trade may take a few hundred milliseconds to appear, you can add a short retry delay loop (e.g., check up to 3 times with 500ms intervals) if your app needs better reliability.

    Answers to Your Specific Questions

    1. How does py3cw get the trade ID when the API returns a 204?
    By immediately querying /v2/smart_trades for the most recent trade.

    2. Is there a way to get the trade ID immediately in Node.js?
    Yes — use the same workaround: fetch latest smart trade after 204 response.

    3. Are there special headers or parameters I should be including?
    No extra headers required beyond what's already there. Just make the follow-up GET request.

    4. Is there an alternative endpoint or approach?
    Not really. 3Commas chose 204 for smart trade creation. The only workaround is fetching the most recent trade from /v2/smart_trades.

Reasons:
  • Blacklisted phrase (1): Is there a way
  • Long answer (-1):
  • Has code block (-0.5):
  • Contains question mark (0.5):
  • Low reputation (1):
Posted by: Hiren Patel