UNPKG

okx-api

Version:

Complete Node.js SDK for OKX's REST APIs and WebSockets, with TypeScript & end-to-end tests

82 lines (80 loc) 3.5 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 typeGuards_js_1 = require("./typeGuards.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 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, typeGuards_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, typeGuards_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/okx-api/blob/master/examples/fasterHmacSign.ts `); } } //# sourceMappingURL=webCryptoAPI.js.map