Error signing with Node Crypto (PEM): Invalid digest

i’m code: import axios from ‘axios’;
import crypto from ‘crypto’;
import dotenv from ‘dotenv’;

dotenv.config();

// — CẤU HÌNH API BINANCE FUTURES (Ed25519 với Private Key PEM) —
const API_KEY = process.env.BINANCE_API_KEY;
const PRIVATE_KEY_PEM_RAW = process.env.BINANCE_PRIVATE_KEY_PEM;

// Đảm bảo Private Key PEM được định dạng đúng (thay \n thành \n)
const PRIVATE_KEY_PEM = PRIVATE_KEY_PEM_RAW ? PRIVATE_KEY_PEM_RAW.replace(/\n/g, ‘\n’).trim() : null;

const BASE_URL = ‘https://fapi.binance.com’;
const POSITION_ENDPOINT = ‘/fapi/v2/positionRisk’; // Endpoint để đọc vị thế

// Hàm lấy thời gian định dạng HH:mm:ss
function getFormattedTime() {
return new Date().toLocaleTimeString(‘en-US’, {
hour12: false,
hour: ‘2-digit’,
minute: ‘2-digit’,
second: ‘2-digit’
});
}

// Kiểm tra biến môi trường
if (!API_KEY || !PRIVATE_KEY_PEM) {
console.error([${getFormattedTime()}] ❌ Lỗi: Cần cấu hình đầy đủ BINANCE_API_KEY và BINANCE_PRIVATE_KEY_PEM trong .env);
console.error(Gợi ý: BINANCE_PRIVATE_KEY_PEM nên bao gồm toàn bộ nội dung file PEM, ví dụ: "-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----");
process.exit(1);
}

// Hàm ký payload bằng Ed25519 sử dụng Node.js ‘crypto’
function signWithNodeCrypto(method, path, params) {
const sortedParamKeys = Object.keys(params).sort();
const queryString = sortedParamKeys.map(key => ${key}=${encodeURIComponent(params[key])}).join(‘&’);
const payload = ${params.timestamp}${method}${path}${queryString};
console.log([${getFormattedTime()}] [DEBUG] Payload để ký: "${payload}");

try {
    const signer = crypto.createSign('Ed25519'); // Sử dụng Ed25519
    signer.update(payload);
    const signature = signer.sign(PRIVATE_KEY_PEM, 'hex'); // Ký bằng Private Key PEM
    return signature;
} catch (error) {
    console.error(`[${getFormattedTime()}] ❌ Lỗi khi ký với Node Crypto (PEM): ${error.message}`);
    if (error.code === 'ERR_OSSL_EVP_INVALID_DIGEST') {
        console.error(`Gợi ý: Lỗi 'Invalid digest' thường do Private Key PEM không đúng định dạng hoặc không phải Ed25519.`);
    }
    throw error;
}

}

async function main() {
console.log([${getFormattedTime()}] Đang kết nối Binance Futures và đọc vị thế (Ed25519 với Private Key PEM)...);
console.log([${getFormattedTime()}] [DEBUG] API Key đã tải: ${API_KEY.slice(0, 8)}...);

try {
    const method = 'GET';
    const path = POSITION_ENDPOINT; // /fapi/v2/positionRisk

    const timestamp = Date.now();
    const recvWindow = 5000;

    const positionParams = {
        timestamp: timestamp.toString(),
        recvWindow: recvWindow.toString()
    };

    // Ký payload
    const signature = signWithNodeCrypto(method, path, positionParams);

    // Tạo query string và URL cuối cùng
    const positionQueryString = Object.keys(positionParams)
        .sort()
        .map(key => `${key}=${encodeURIComponent(positionParams[key])}`)
        .join('&');
    const finalUrl = `${BASE_URL}${POSITION_ENDPOINT}?${positionQueryString}`;

    // Cấu hình headers
    const headers = {
        'X-BINANCE-APIKEY': API_KEY,
        'X-BINANCE-TIMESTAMP': timestamp,
        'X-BINANCE-SIGNATURE': signature,
    };

    console.log(`[${getFormattedTime()}] [DEBUG] Gọi URL (GET vị thế): ${finalUrl}`);
    console.log(`[${getFormattedTime()}] [DEBUG] Headers: ${JSON.stringify(headers, null, 2)}`);
    console.log(`[${getFormattedTime()}] [DEBUG] X-BINANCE-SIGNATURE đã gửi: ${signature}`);

    // Gửi yêu cầu GET
    const response = await axios.get(finalUrl, { headers });
    const positions = response.data;

    let hasOpenPosition = false;
    if (positions && positions.length > 0) {
        console.log(`[${getFormattedTime()}] ✅ Các vị thế đang mở:`);
        for (const position of positions) {
            const positionAmt = parseFloat(position.positionAmt);
            if (positionAmt !== 0) {
                hasOpenPosition = true;
                const side = positionAmt > 0 ? 'LONG' : 'SHORT';
                console.log(
                    `  - Symbol: ${position.symbol || 'N/A'}, ` +
                    `Side: ${side}, ` +
                    `Amount: ${positionAmt}, ` +
                    `Entry Price: ${position.entryPrice || 'N/A'}, ` +
                    `Unrealized PNL: ${position.unrealizedProfit || 'N/A'}, ` +
                    `Leverage: ${position.leverage || 'N/A'}`
                );
            }
        }
    }
    if (!hasOpenPosition) {
        console.log(`[${getFormattedTime()}] ✅ Không có vị thế nào đang mở.`);
    }

} catch (error) {
    console.error(`[${getFormattedTime()}] ❌ Lỗi khi đọc vị thế: ${error.response?.data?.msg || error.message}`);
    if (error.response?.data) {
        console.error(`[${getFormattedTime()}] Chi tiết lỗi từ Binance:`, error.response.data);
        if (error.response.data.code === -2014) {
            console.error(`[${getFormattedTime()}] Gợi ý: Lỗi -2014 'API-key format invalid'.`);
            console.error(`  - Đảm bảo BINANCE_API_KEY đúng và khớp với Public Key bạn đã đăng ký trên Binance.`);
            console.error(`  - Kiểm tra quyền API: 'Enable Reading' và 'Enable Futures'.`);
        } else if (error.response.data.code === -1021) {
            console.error(`[${getFormattedTime()}] Gợi ý: Lỗi -1021 'Timestamp lệch'. Đồng bộ thời gian máy hoặc tăng recvWindow.`);
        } else if (error.response.data.code === -1022) {
            console.error(`[${getFormattedTime()}] Gợi ý: Lỗi -1022 'Signature for this request is not valid'.`);
            console.error(`  - Rất có thể Private Key PEM bạn đang dùng không khớp với Public Key trên Binance.`);
            console.error(`  - Đảm bảo nội dung 'BINANCE_PRIVATE_KEY_PEM' trong .env là toàn bộ nội dung file PEM chuẩn.`);
        }
    }
}

}

main().catch(error => console.error([${getFormattedTime()}] ❌ Lỗi không xác định: ${error.message}));
Error signing:
[13:52:18] Đang kết nối Binance Futures và đọc vị thế (Ed25519 với Private Key PEM)…
[13:52:18] [DEBUG] API Key đã tải: IJnYz3D1…
[13:52:18] [DEBUG] Payload để ký: “1748501538210GET/fapi/v2/positionRiskrecvWindow=5000&timestamp=1748501538210”
[13:52:18] :x: Lỗi khi ký với Node Crypto (PEM): Invalid digest
[13:52:18] :x: Lỗi khi đọc vị thế: Invalid digest
how to fix this error??