C++ implementation of FIX API

Hi there, nice to be in this wonderful community. I have a question regarding the signature generation code in Python on this site about Fix API: Fix API | Binance Open Platform is there a c++ equivalent library? I tried <sodium.h> and it seems the signatures are different solely because of the algorithms in generating signatures or utilizing the ed25519 private keys.

I did many deep-dive into how Python and c++ handle the private key and generate signatures differently and the code in c++ is given below. Can anyone please help verify if this is the correct way of generating signatures in c++? I know it’s not and what’s the right way for doing this then? It would be great if an example can be provided so that c++ developer can benefit greatly from it. Thanks.

#include <iostream>
#include <sodium.h>
#include <stdexcept>

// Function to generate the Ed25519 signature
std::string generateEd25519Signature(const std::string& payload, const std::string& privateKeyBase64) {
    // Decode the private key from Base64
    unsigned char privateKey[crypto_sign_SECRETKEYBYTES];
    if (sodium_base642bin(privateKey, sizeof(privateKey),
                          privateKeyBase64.c_str(), privateKeyBase64.size(),
                          nullptr, nullptr, nullptr, sodium_base64_VARIANT_ORIGINAL) != 0) {
        throw std::runtime_error("Failed to decode private key from Base64.");
    }

    // Debug: Print the decoded private key in hex
    std::cout << "Decoded Private Key (Hex): ";
    for (size_t i = 0; i < crypto_sign_SECRETKEYBYTES; ++i) {
        printf("%02x", privateKey[i]);
    }
    std::cout << std::endl;

    // Generate the Ed25519 signature
    unsigned char signature[crypto_sign_BYTES];
    if (crypto_sign_detached(signature, nullptr,
                             reinterpret_cast<const unsigned char*>(payload.c_str()), payload.size(),
                             privateKey) != 0) {
        throw std::runtime_error("Failed to generate Ed25519 signature.");
    }

    // Debug: Print the raw signature in hex
    std::cout << "Raw Signature (Hex): ";
    for (size_t i = 0; i < crypto_sign_BYTES; ++i) {
        printf("%02x", signature[i]);
    }
    std::cout << std::endl;

    // Convert the signature to Base64
    char base64Signature[crypto_sign_BYTES * 2]; // Ensure buffer is large enough
    sodium_bin2base64(base64Signature, sizeof(base64Signature),
                      signature, crypto_sign_BYTES, sodium_base64_VARIANT_ORIGINAL);

    // Return the signature as a Base64-encoded string
    return std::string(base64Signature);
}

int main() {
    // Initialize libsodium
    if (sodium_init() < 0) {
        std::cerr << "Failed to initialize libsodium" << std::endl;
        return 1;
    }

    // Construct the payload explicitly
    const char SOH = '\x01'; // ASCII Start of Header character
    std::string payload = "A" + std::string(1, SOH) +
                          "5JQmUOsm" + std::string(1, SOH) +
                          "SPOT" + std::string(1, SOH) +
                          "1" + std::string(1, SOH) +
                          "20241121-08:08:35.672";

    // Debug: Print the payload with escaped characters
    std::cout << "Payload (with escaped \\x01): ";
    for (char c : payload) {
        if (c == '\x01') {
            std::cout << "\\x01";
        } else {
            std::cout << c;
        }
    }
    std::cout << std::endl;

    // Replace with your private key in Base64 format
    std::string privateKeyBase64 = "";

    // Generate signature
    try {
        std::string signature = generateEd25519Signature(payload, privateKeyBase64);
        std::cout << "Generated Ed25519 Signature (Base64): " << signature << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}