UNPKG

bitget-api

Version:

Complete Node.js & JavaScript SDK for Bitget V1-V3 REST APIs & WebSockets, with TypeScript & end-to-end tests.

92 lines (90 loc) 4.04 kB
"use strict"; /* eslint-disable @typescript-eslint/no-unused-vars */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getSignKeyType = getSignKeyType; exports.signMessage = signMessage; exports.checkWebCryptoAPISupported = checkWebCryptoAPISupported; const websocket_util_js_1 = require("./websocket-util.js"); function bufferToB64(buffer) { let binary = ''; const bytes = new Uint8Array(buffer); const len = bytes.byteLength; for (let i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return globalThis.btoa(binary); } function getSignKeyType(secret) { if (secret.includes('PRIVATE KEY')) { // Sometimes, not always, RSA keys include "RSA" in the header. That's a definite RSA key. if (secret.includes('RSA PRIVATE KEY')) { return 'RSASSA-PKCS1-v1_5'; } // RSA keys are significantly longer than Ed25519 keys. 150 accounts for length of header & footer if (secret.length <= 150) { return 'Ed25519'; } return 'RSASSA-PKCS1-v1_5'; } return 'HMAC'; } async function importKey(pem, type, algorithm, encoder) { switch (type) { case 'Ed25519': case 'RSASSA-PKCS1-v1_5': { // const prefixRSA = /-----BEGIN RSA PRIVATE KEY-----/; // const prefixEd25519 = /-----BEGIN PRIVATE KEY-----/; // const suffixRSA = /-----END RSA PRIVATE KEY-----/; // const suffixEd25519 = /-----END PRIVATE KEY-----/; // const base64Key = pem // .replace(prefixEd25519, '') // .replace(prefixRSA, '') // .replace(suffixEd25519, '') // .replace(suffixRSA, '') // .replace(/\s+/g, ''); // Remove spaces and newlines const base64Key = pem.replace(/(?:-----BEGIN RSA PRIVATE KEY-----|-----BEGIN PRIVATE KEY-----|-----END RSA PRIVATE KEY-----|-----END PRIVATE KEY-----|\s+)/g, ''); const binaryKey = Uint8Array.from(atob(base64Key), (c) => c.charCodeAt(0)); return globalThis.crypto.subtle.importKey('pkcs8', binaryKey.buffer, { name: type, hash: { name: algorithm } }, false, ['sign']); } case 'HMAC': { return globalThis.crypto.subtle.importKey('raw', encoder.encode(pem), { name: type, hash: algorithm }, false, ['sign']); } default: { throw (0, websocket_util_js_1.neverGuard)(type, `Unhandled key type: "${type}"`); } } } /** * Sign a message, with a secret, using the Web Crypto API * * Ed25519 is stable as of v23.5.0, but also not available in all browsers */ async function signMessage(message, secret, method, algorithm, _pemEncodeMethod = method) { const encoder = new TextEncoder(); const signKeyType = getSignKeyType(secret); const key = await importKey(secret, signKeyType, algorithm, encoder); const buffer = await globalThis.crypto.subtle.sign({ name: signKeyType }, key, encoder.encode(message)); switch (method) { case 'hex': { return Array.from(new Uint8Array(buffer)) .map((byte) => byte.toString(16).padStart(2, '0')) .join(''); } case 'base64': { return bufferToB64(buffer); } default: { throw (0, websocket_util_js_1.neverGuard)(method, `Unhandled sign method: "${method}"`); } } } function checkWebCryptoAPISupported() { if (!globalThis.crypto) { throw new Error(`Web Crypto API unavailable. Authentication will not work. Are you using an old Node.js release? Refer to the current Node.js LTS version. Node.js v18 reached end of life in April 2025! You should be using Node LTS or newer (v22 or above)! If you prefer to continue using an outdated Node.js version, check github for an example on using the node:crypto module for sign instead: https://github.com/tiagosiebler/bitget-api/blob/master/examples/auth/fasterHmacSign.ts `); } } //# sourceMappingURL=webCryptoAPI.js.map