UNPKG

astro-perp-ccxt-dev

Version:

A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges

1,234 lines (1,212 loc) 17.9 MB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var WebSocket = require('ws'); // ---------------------------------------------------------------------------- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code // EDIT THE CORRESPONDENT .ts FILE INSTEAD // @ts-nocheck // ---------------------------------------------------------------------------- // There's been a lot of messing with this code... // The problem is to satisfy the following requirements: // - properly detect isNode == true on server side and isNode == false in the browser (on client side) // - make sure create-react-app, react-starter-kit and other react frameworks work // - make sure it does not break the browserified version (when linked into a html from a cdn) // - make sure it does not break the webpacking and babel-transpiled scripts // - make sure it works in Electron // - make sure it works with Angular.js // - make sure it does not break other possible usage scenarios const isBrowser = typeof window !== 'undefined'; const isElectron = typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined'; const isWebWorker = typeof WorkerGlobalScope !== 'undefined' && (self instanceof WorkerGlobalScope); const isWindows = typeof process !== 'undefined' && process.platform === "win32"; const isDeno = typeof Deno !== 'undefined'; const isNode$1 = !(isBrowser || isWebWorker || isDeno); // ---------------------------------------------------------------------------- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code // EDIT THE CORRESPONDENT .ts FILE INSTEAD /* ------------------------------------------------------------------------ */ const isNumber$1 = Number.isFinite; const isInteger = Number.isInteger; const isArray = Array.isArray; const hasProps = (o) => ((o !== undefined) && (o !== null)); const isString$1 = (s) => (typeof s === 'string'); const isObject = (o) => ((o !== null) && (typeof o === 'object')); const isRegExp = (o) => (o instanceof RegExp); const isDictionary = (o) => (isObject(o) && (Object.getPrototypeOf(o) === Object.prototype) && !isArray(o) && !isRegExp(o)); const isStringCoercible = (x) => ((hasProps(x) && x.toString) || isNumber$1(x)); /* ............................................. */ const prop = (o, k) => (isObject(o) && o[k] !== '' && o[k] !== null ? o[k] : undefined); const prop2 = (o, k1, k2) => (!isObject(o) ? undefined : (o[k1] !== undefined && o[k1] !== '' && o[k1] !== null ? o[k1] : (o[k2] !== '' && o[k2] !== null ? o[k2] : undefined))); const getValueFromKeysInArray = (object, array) => isObject(object) ? object[array.find((k) => prop(object, k) !== undefined)] : undefined; /* ............................................. */ const asFloat = (x) => ((isNumber$1(x) || (isString$1(x) && x.length !== 0)) ? parseFloat(x) : NaN); const asInteger = (x) => ((isNumber$1(x) || (isString$1(x) && x.length !== 0)) ? Math.trunc(Number(x)) : NaN); /* ............................................. */ const safeFloat$1 = (o, k, $default) => { const n = asFloat(prop(o, k)); return isNumber$1(n) ? n : $default; }; const safeInteger$1 = (o, k, $default) => { const n = asInteger(prop(o, k)); return isNumber$1(n) ? n : $default; }; const safeIntegerProduct$1 = (o, k, $factor, $default) => { const n = asFloat(prop(o, k)); return isNumber$1(n) ? parseInt(n * $factor) : $default; }; const safeTimestamp$1 = (o, k, $default) => { const n = asFloat(prop(o, k)); return isNumber$1(n) ? parseInt(n * 1000) : $default; }; const safeValue$1 = (o, k, $default) => { const x = prop(o, k); return hasProps(x) ? x : $default; }; const safeString$1 = (o, k, $default) => { const x = prop(o, k); return isStringCoercible(x) ? String(x) : $default; }; const safeStringLower$1 = (o, k, $default) => { const x = prop(o, k); if (isStringCoercible(x)) { return String(x).toLowerCase(); } else if (isStringCoercible($default)) { return String($default).toLowerCase(); } return $default; }; const safeStringUpper$1 = (o, k, $default) => { const x = prop(o, k); if (isStringCoercible(x)) { return String(x).toUpperCase(); } else if (isStringCoercible($default)) { return String($default).toUpperCase(); } return $default; }; /* ............................................. */ const safeFloat2$1 = (o, k1, k2, $default) => { const n = asFloat(prop2(o, k1, k2)); return isNumber$1(n) ? n : $default; }; const safeInteger2$1 = (o, k1, k2, $default) => { const n = asInteger(prop2(o, k1, k2)); return isNumber$1(n) ? n : $default; }; const safeIntegerProduct2$1 = (o, k1, k2, $factor, $default) => { const n = asFloat(prop2(o, k1, k2)); return isNumber$1(n) ? parseInt(n * $factor) : $default; }; const safeTimestamp2$1 = (o, k1, k2, $default) => { const n = asFloat(prop2(o, k1, k2)); return isNumber$1(n) ? parseInt(n * 1000) : $default; }; const safeValue2$1 = (o, k1, k2, $default) => { const x = prop2(o, k1, k2); return hasProps(x) ? x : $default; }; const safeString2$1 = (o, k1, k2, $default) => { const x = prop2(o, k1, k2); return isStringCoercible(x) ? String(x) : $default; }; const safeStringLower2$1 = (o, k1, k2, $default) => { const x = prop2(o, k1, k2); if (isStringCoercible(x)) { return String(x).toLowerCase(); } else if (isStringCoercible($default)) { return String($default).toLowerCase(); } return $default; }; const safeStringUpper2$1 = (o, k1, k2, $default) => { const x = prop2(o, k1, k2); if (isStringCoercible(x)) { return String(x).toUpperCase(); } else if (isStringCoercible($default)) { return String($default).toUpperCase(); } return $default; }; const safeFloatN$1 = (o, k, $default) => { const n = asFloat(getValueFromKeysInArray(o, k)); return isNumber$1(n) ? n : $default; }; const safeIntegerN$1 = (o, k, $default) => { if (o === undefined) { return $default; } const n = asInteger(getValueFromKeysInArray(o, k)); return isNumber$1(n) ? n : $default; }; const safeIntegerProductN$1 = (o, k, $factor, $default) => { const n = asFloat(getValueFromKeysInArray(o, k)); return isNumber$1(n) ? parseInt(n * $factor) : $default; }; const safeTimestampN$1 = (o, k, $default) => { const n = asFloat(getValueFromKeysInArray(o, k)); return isNumber$1(n) ? parseInt(n * 1000) : $default; }; const safeValueN$1 = (o, k, $default) => { if (o === undefined) { return $default; } const x = getValueFromKeysInArray(o, k); return hasProps(x) ? x : $default; }; const safeStringN$1 = (o, k, $default) => { if (o === undefined) { return $default; } const x = getValueFromKeysInArray(o, k); return isStringCoercible(x) ? String(x) : $default; }; const safeStringLowerN$1 = (o, k, $default) => { const x = getValueFromKeysInArray(o, k); if (isStringCoercible(x)) { return String(x).toLowerCase(); } else if (isStringCoercible($default)) { return String($default).toLowerCase(); } return $default; }; const safeStringUpperN$1 = (o, k, $default) => { const x = getValueFromKeysInArray(o, k); if (isStringCoercible(x)) { return String(x).toUpperCase(); } else if (isStringCoercible($default)) { return String($default).toUpperCase(); } return $default; }; /* ------------------------------------------------------------------------ */ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- const keys = Object.keys; // eslint-disable-line padding-line-between-statements const values = (x) => ((!isArray(x)) ? Object.values(x) : x); // don't copy arrays if they're already arrays const index = (x) => new Set(values(x)); const extend$1 = (...args) => Object.assign({}, ...args); // NB: side-effect free const clone$1 = (x) => (isArray(x) ? Array.from(x) : extend$1(x)); // clone arrays or objects // ---------------------------------------------------------------------------- const ordered$1 = (x) => x; // a stub to keep assoc keys in order (in JS it does nothing, it's mostly for Python) const unique$1 = (x) => Array.from(index(x)); const arrayConcat$1 = (a, b) => a.concat(b); // ------------------------------------------------------------------------ const inArray$1 = (needle, haystack) => haystack.includes(needle); const toArray$1 = (object) => Object.values(object); const isEmpty$1 = (object) => { if (!object) { return true; } return (Array.isArray(object) ? object : Object.keys(object)).length < 1; }; const keysort$1 = (x, out = {}) => { for (const k of keys(x).sort()) { out[k] = x[k]; } return out; }; const sort$1 = (array) => { const newArray = array.slice(); newArray.sort(); return newArray; }; /* Accepts a map/array of objects and a key name to be used as an index: array = [ { someKey: 'value1', anotherKey: 'anotherValue1' }, { someKey: 'value2', anotherKey: 'anotherValue2' }, { someKey: 'value3', anotherKey: 'anotherValue3' }, ] key = 'someKey' Returns a map: { value1: { someKey: 'value1', anotherKey: 'anotherValue1' }, value2: { someKey: 'value2', anotherKey: 'anotherValue2' }, value3: { someKey: 'value3', anotherKey: 'anotherValue3' }, } */ const groupBy$1 = (x, k, out = {}) => { for (const v of values(x)) { if (k in v) { const p = v[k]; out[p] = out[p] || []; out[p].push(v); } } return out; }; const indexBy$1 = (x, k, out = {}) => { for (const v of values(x)) { if (k in v) { out[v[k]] = v; } } return out; }; const filterBy$1 = (x, k, value = undefined, out = []) => { for (const v of values(x)) { if (v[k] === value) { out.push(v); } } return out; }; const sortBy$1 = (array, key, descending = false, defaultValue = 0, direction = descending ? -1 : 1) => array.sort((a, b) => { const first = (key in a) ? a[key] : defaultValue; const second = (key in b) ? b[key] : defaultValue; if (first < second) { return -direction; } else if (first > second) { return direction; } else { return 0; } }); const sortBy2$1 = (array, key1, key2, descending = false, direction = descending ? -1 : 1) => array.sort((a, b) => { if (a[key1] < b[key1]) { return -direction; } else if (a[key1] > b[key1]) { return direction; } else { if (a[key2] < b[key2]) { return -direction; } else if (a[key2] > b[key2]) { return direction; } else { return 0; } } }); const flatten$1 = function flatten(x, out = []) { for (const v of x) { if (isArray(v)) { flatten(v, out); } else { out.push(v); } } return out; }; const pluck = (x, k) => values(x).filter((v) => k in v).map((v) => v[k]); const omit$1 = (x, ...args) => { if (!Array.isArray(x)) { const out = clone$1(x); for (const k of args) { if (isArray(k)) { // omit (x, ['a', 'b']) for (const kk of k) { delete out[kk]; } } else { delete out[k]; // omit (x, 'a', 'b') } } return out; } return x; }; const sum$1 = (...xs) => { const ns = xs.filter(isNumber$1); // leave only numbers return (ns.length > 0) ? ns.reduce((a, b) => a + b, 0) : undefined; }; const deepExtend$1 = function deepExtend(...xs) { let out = undefined; for (const x of xs) { if (isDictionary(x)) { if (!isDictionary(out)) { out = {}; } for (const k in x) { out[k] = deepExtend(out[k], x[k]); } } else { out = x; } } return out; }; const merge$1 = (target, ...args) => { // doesn't overwrite defined keys with undefined const overwrite = {}; const merged = Object.assign({}, ...args); const keys = Object.keys(merged); for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (target[key] === undefined) { overwrite[key] = merged[key]; } } // eslint-disable-next-line return Object.assign({}, target, overwrite); }; // ---------------------------------------------------------------------------- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code // EDIT THE CORRESPONDENT .ts FILE INSTEAD // ---------------------------------------------------------------------------- // unCamelCase has to work with the following edge cases // // parseOHLCVs > parse_ohlcvs // safeString2 > safe_string_2 // safeStringN > safe_string_n // convertOHLCVToTradingView > convert_ohlcv_to_trading_view // fetchL2OrderBook > fetch_l2_order_book // stringToBase64 > string_to_base64 // base64ToString > base64_to_string // parseHTTPResponse > parse_http_response // hasFetchOHLCV > has_fetch_ohlcv // // @ts-nocheck const unCamelCase$1 = (s) => { const exceptions = { 'fetchOHLCVWs': 'fetch_ohlcv_ws', // ws = websocket }; if (exceptions[s]) { return exceptions[s]; } return s.match(/[A-Z]/) ? s.replace(/[a-z0-9][A-Z]/g, (x) => x[0] + '_' + x[1]).replace(/[A-Z0-9][A-Z0-9][a-z][^$]/g, (x) => x[0] + '_' + x[1] + x[2] + x[3]).replace(/[a-z][0-9]$/g, (x) => x[0] + '_' + x[1]).toLowerCase() : s; }; const capitalize$1 = (s) => { return s.length ? (s.charAt(0).toUpperCase() + s.slice(1)) : s; }; const strip$1 = (s) => s.replace(/^\s+|\s+$/g, ''); // ---------------------------------------------------------------------------- const uuid$1 = (a) => { return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid$1); }; const uuid16$1 = (a) => { return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([1e5] + 1e2 + 4e2 + 8e3).replace(/[018]/g, uuid16$1); }; const uuid22$1 = (a) => { return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([1e7] + 1e3 + 4e3 + 8e5).replace(/[018]/g, uuid22$1); }; // ---------------------------------------------------------------------------- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code // EDIT THE CORRESPONDENT .ts FILE INSTEAD // ------------------------------------------------------------------------ // // NB: initially, I used objects for options passing: // // decimalToPrecision ('123.456', { digits: 2, round: true, afterPoint: true }) // // ...but it turns out it's hard to port that across different languages and it is also // probably has a performance penalty -- while it's a performance critical code! So // I switched to using named constants instead, as it is actually more readable and // succinct, and surely doesn't come with any inherent performance downside: // // decimalToPrecision ('123.456', ROUND, 2, DECIMAL_PLACES) const TRUNCATE$1 = 0; // rounding mode const ROUND$1 = 1; const ROUND_UP = 2; const ROUND_DOWN = 3; const DECIMAL_PLACES$1 = 2; // digits counting mode const SIGNIFICANT_DIGITS$1 = 3; const TICK_SIZE$1 = 4; const NO_PADDING$1 = 5; // zero-padding mode const PAD_WITH_ZERO = 6; const precisionConstants = { ROUND: ROUND$1, TRUNCATE: TRUNCATE$1, ROUND_UP, ROUND_DOWN, DECIMAL_PLACES: DECIMAL_PLACES$1, SIGNIFICANT_DIGITS: SIGNIFICANT_DIGITS$1, TICK_SIZE: TICK_SIZE$1, NO_PADDING: NO_PADDING$1, PAD_WITH_ZERO, }; /* ------------------------------------------------------------------------ */ // See https://stackoverflow.com/questions/1685680/how-to-avoid-scientific-notation-for-large-numbers-in-javascript for discussion function numberToString$1(x) { if (x === undefined) return undefined; if (typeof x !== 'number') return x.toString(); const s = x.toString(); if (Math.abs(x) < 1.0) { const n_e = s.split('e-'); const n = n_e[0].replace('.', ''); const e = parseInt(n_e[1]); const neg = (s[0] === '-'); if (e) { x = (neg ? '-' : '') + '0.' + (new Array(e)).join('0') + n.substring(neg); return x; } } else { const parts = s.split('e'); if (parts[1]) { let e = parseInt(parts[1]); const m = parts[0].split('.'); let part = ''; if (m[1]) { e -= m[1].length; part = m[1]; } return m[0] + part + (new Array(e + 1)).join('0'); } } return s; } //----------------------------------------------------------------------------- // expects non-scientific notation const truncate_regExpCache = []; const truncate_to_string = (num, precision = 0) => { num = numberToString$1(num); if (precision > 0) { const re = truncate_regExpCache[precision] || (truncate_regExpCache[precision] = new RegExp('([-]*\\d+\\.\\d{' + precision + '})(\\d)')); const [, result] = num.toString().match(re) || [null, num]; return result.toString(); } return parseInt(num).toString(); }; const truncate = (num, precision = 0) => parseFloat(truncate_to_string(num, precision)); function precisionFromString$1(str) { // support string formats like '1e-4' if (str.indexOf('e') > -1 || str.indexOf('E') > -1) { const numStr = str.replace(/\d\.?\d*[eE]/, ''); return parseInt(numStr) * -1; } // support integer formats (without dot) like '1', '10' etc [Note: bug in decimalToPrecision, so this should not be used atm] // if (str.indexOf ('.') === -1) { // return str.length * -1 // } // default strings like '0.0001' const split = str.replace(/0+$/g, '').split('.'); return (split.length > 1) ? (split[1].length) : 0; } /* ------------------------------------------------------------------------ */ const decimalToPrecision$1 = (x, roundingMode, numPrecisionDigits, countingMode = DECIMAL_PLACES$1, paddingMode = NO_PADDING$1) => { return _decimalToPrecision(x, roundingMode, numPrecisionDigits, countingMode, paddingMode); }; const _decimalToPrecision = (x, roundingMode, numPrecisionDigits, countingMode = DECIMAL_PLACES$1, paddingMode = NO_PADDING$1) => { if (countingMode === TICK_SIZE$1) { if (typeof numPrecisionDigits === 'string') { numPrecisionDigits = parseFloat(numPrecisionDigits); } if (numPrecisionDigits <= 0) { throw new Error('TICK_SIZE cant be used with negative or zero numPrecisionDigits'); } } if (numPrecisionDigits < 0) { const toNearest = Math.pow(10, -numPrecisionDigits); if (roundingMode === ROUND$1) { return (toNearest * _decimalToPrecision(x / toNearest, roundingMode, 0, countingMode, paddingMode)).toString(); } if (roundingMode === TRUNCATE$1) { return (x - (x % toNearest)).toString(); } } /* handle tick size */ if (countingMode === TICK_SIZE$1) { const precisionDigitsString = _decimalToPrecision(numPrecisionDigits, ROUND$1, 22, DECIMAL_PLACES$1, NO_PADDING$1); const newNumPrecisionDigits = precisionFromString$1(precisionDigitsString); let missing = x % numPrecisionDigits; // See: https://github.com/ccxt/ccxt/pull/6486 missing = Number(_decimalToPrecision(missing, ROUND$1, 8, DECIMAL_PLACES$1, NO_PADDING$1)); const fpError = _decimalToPrecision(missing / numPrecisionDigits, ROUND$1, Math.max(newNumPrecisionDigits, 8), DECIMAL_PLACES$1, NO_PADDING$1); if (precisionFromString$1(fpError) !== 0) { if (roundingMode === ROUND$1) { if (x > 0) { if (missing >= numPrecisionDigits / 2) { x = x - missing + numPrecisionDigits; } else { x = x - missing; } } else { if (missing >= numPrecisionDigits / 2) { x = Number(x) - missing; } else { x = Number(x) - missing - numPrecisionDigits; } } } else if (roundingMode === TRUNCATE$1) { x = x - missing; } } return _decimalToPrecision(x, ROUND$1, newNumPrecisionDigits, DECIMAL_PLACES$1, paddingMode); } /* Convert to a string (if needed), skip leading minus sign (if any) */ const str = numberToString$1(x); const isNegative = str[0] === '-'; const strStart = isNegative ? 1 : 0; const strEnd = str.length; /* Find the dot position in the source buffer */ for (var strDot = 0; strDot < strEnd; strDot++) { if (str[strDot] === '.') break; } const hasDot = strDot < str.length; /* Char code constants */ const MINUS = 45; const DOT = 46; const ZERO = 48; const ONE = (ZERO + 1); const FIVE = (ZERO + 5); const NINE = (ZERO + 9); /* For -123.4567 the `chars` array will hold 01234567 (leading zero is reserved for rounding cases when 099 → 100) */ const chars = new Uint8Array((strEnd - strStart) + (hasDot ? 0 : 1)); chars[0] = ZERO; /* Validate & copy digits, determine certain locations in the resulting buffer */ let afterDot = chars.length; let digitsStart = -1; // significant digits let digitsEnd = -1; for (var i = 1, j = strStart; j < strEnd; j++, i++) { const c = str.charCodeAt(j); if (c === DOT) { afterDot = i--; } else if ((c < ZERO) || (c > NINE)) { throw new Error(`${str}: invalid number (contains an illegal character '${str[i - 1]}')`); } else { chars[i] = c; if ((c !== ZERO) && (digitsStart < 0)) digitsStart = i; } } if (digitsStart < 0) digitsStart = 1; /* Determine the range to cut */ let precisionStart = (countingMode === DECIMAL_PLACES$1) ? afterDot // 0.(0)001234567 : digitsStart; // 0.00(1)234567 let precisionEnd = precisionStart + numPrecisionDigits; /* Reset the last significant digit index, as it will change during the rounding/truncation. */ digitsEnd = -1; // Perform rounding/truncation per digit, from digitsEnd to digitsStart, by using the following // algorithm (rounding 999 → 1000, as an example): // // step = i=3 i=2 i=1 i=0 // // chars = 0999 0999 0900 1000 // memo = ---0 --1- -1-- 0--- let allZeros = true; let signNeeded = isNegative; for (let i = chars.length - 1, memo = 0; i >= 0; i--) { let c = chars[i]; if (i !== 0) { c += memo; if (i >= (precisionStart + numPrecisionDigits)) { const ceil = (roundingMode === ROUND$1) && (c >= FIVE) && !((c === FIVE) && memo); // prevents rounding of 1.45 to 2 c = ceil ? (NINE + 1) : ZERO; } if (c > NINE) { c = ZERO; memo = 1; } else memo = 0; } else if (memo) c = ONE; // leading extra digit (0900 → 1000) chars[i] = c; if (c !== ZERO) { allZeros = false; digitsStart = i; digitsEnd = (digitsEnd < 0) ? (i + 1) : digitsEnd; } } /* Update the precision range, as `digitsStart` may have changed... & the need for a negative sign if it is only 0 */ if (countingMode === SIGNIFICANT_DIGITS$1) { precisionStart = digitsStart; precisionEnd = precisionStart + numPrecisionDigits; } if (allZeros) { signNeeded = false; } /* Determine the input character range */ const readStart = ((digitsStart >= afterDot) || allZeros) ? (afterDot - 1) : digitsStart; // 0.000(1)234 ----> (0).0001234 const readEnd = (digitsEnd < afterDot) ? (afterDot) : digitsEnd; // 12(3)000 ----> 123000( ) /* Compute various sub-ranges */ const nSign = (signNeeded ? 1 : 0); // (-)123.456 const nBeforeDot = (nSign + (afterDot - readStart)); // (-123).456 const nAfterDot = Math.max(readEnd - afterDot, 0); // -123.(456) const actualLength = (readEnd - readStart); // -(123.456) const desiredLength = (paddingMode === NO_PADDING$1) ? (actualLength) // -(123.456) : (precisionEnd - readStart); // -(123.456 ) const pad = Math.max(desiredLength - actualLength, 0); // -123.456( ) const padStart = (nBeforeDot + 1 + nAfterDot); // -123.456( ) const padEnd = (padStart + pad); // -123.456 ( ) const isInteger = (nAfterDot + pad) === 0; // -123 /* Fill the output buffer with characters */ const out = new Uint8Array(nBeforeDot + (isInteger ? 0 : 1) + nAfterDot + pad); // ------------------------------------------------------------------------------------------ // --------------------- if (signNeeded) out[0] = MINUS; // - minus sign for (i = nSign, j = readStart; i < nBeforeDot; i++, j++) out[i] = chars[j]; // 123 before dot if (!isInteger) out[nBeforeDot] = DOT; // . dot for (i = nBeforeDot + 1, j = afterDot; i < padStart; i++, j++) out[i] = chars[j]; // 456 after dot for (i = padStart; i < padEnd; i++) out[i] = ZERO; // 000 padding /* Build a string from the output buffer */ return String.fromCharCode(...out); }; function omitZero$1(stringNumber) { try { if (stringNumber === undefined || stringNumber === '') { return undefined; } if (parseFloat(stringNumber) === 0) { return undefined; } return stringNumber; } catch (e) { return stringNumber; } } /* ------------------------------------------------------------------------ */ // ---------------------------------------------------------------------------- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code // EDIT THE CORRESPONDENT .ts FILE INSTEAD /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */ // Utilities function assertNumber(n) { if (!Number.isSafeInteger(n)) throw new Error(`Wrong integer: ${n}`); } function chain(...args) { // Wrap call in closure so JIT can inline calls const wrap = (a, b) => (c) => a(b(c)); // Construct chain of args[-1].encode(args[-2].encode([...])) const encode = Array.from(args) .reverse() .reduce((acc, i) => (acc ? wrap(acc, i.encode) : i.encode), undefined); // Construct chain of args[0].decode(args[1].decode(...)) const decode = args.reduce((acc, i) => (acc ? wrap(acc, i.decode) : i.decode), undefined); return { encode, decode }; } // Encodes integer radix representation to array of strings using alphabet and back function alphabet(alphabet) { return { encode: (digits) => { if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number')) throw new Error('alphabet.encode input should be an array of numbers'); return digits.map((i) => { assertNumber(i); if (i < 0 || i >= alphabet.length) throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`); return alphabet[i]; }); }, decode: (input) => { if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string')) throw new Error('alphabet.decode input should be array of strings'); return input.map((letter) => { if (typeof letter !== 'string') throw new Error(`alphabet.decode: not string element=${letter}`); const index = alphabet.indexOf(letter); if (index === -1) throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`); return index; }); }, }; } function join(separator = '') { if (typeof separator !== 'string') throw new Error('join separator should be string'); return { encode: (from) => { if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string')) throw new Error('join.encode input should be array of strings'); for (let i of from) if (typeof i !== 'string') throw new Error(`join.encode: non-string input=${i}`); return from.join(separator); }, decode: (to) => { if (typeof to !== 'string') throw new Error('join.decode input should be string'); return to.split(separator); }, }; } // Pad strings array so it has integer number of bits function padding$1(bits, chr = '=') { assertNumber(bits); if (typeof chr !== 'string') throw new Error('padding chr should be string'); return { encode(data) { if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string')) throw new Error('padding.encode input should be array of strings'); for (let i of data) if (typeof i !== 'string') throw new Error(`padding.encode: non-string input=${i}`); while ((data.length * bits) % 8) data.push(chr); return data; }, decode(input) { if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string')) throw new Error('padding.encode input should be array of strings'); for (let i of input) if (typeof i !== 'string') throw new Error(`padding.decode: non-string input=${i}`); let end = input.length; if ((end * bits) % 8) throw new Error('Invalid padding: string should have whole number of bytes'); for (; end > 0 && input[end - 1] === chr; end--) { if (!(((end - 1) * bits) % 8)) throw new Error('Invalid padding: string has too much padding'); } return input.slice(0, end); }, }; } function normalize(fn) { if (typeof fn !== 'function') throw new Error('normalize fn should be function'); return { encode: (from) => from, decode: (to) => fn(to) }; } // NOTE: it has quadratic time complexity function convertRadix(data, from, to) { // base 1 is impossible if (from < 2) throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`); if (to < 2) throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`); if (!Array.isArray(data)) throw new Error('convertRadix: data should be array'); if (!data.length) return []; let pos = 0; const res = []; const digits = Array.from(data); digits.forEach((d) => { assertNumber(d); if (d < 0 || d >= from) throw new Error(`Wrong integer: ${d}`); }); while (true) { let carry = 0; let done = true; for (let i = pos; i < digits.length; i++) { const digit = digits[i]; const digitBase = from * carry + digit; if (!Number.isSafeInteger(digitBase) || (from * carry) / from !== carry || digitBase - digit !== from * carry) { throw new Error('convertRadix: carry overflow'); } carry = digitBase % to; digits[i] = Math.floor(digitBase / to); if (!Number.isSafeInteger(digits[i]) || digits[i] * to + carry !== digitBase) throw new Error('convertRadix: carry overflow'); if (!done) continue; else if (!digits[i]) pos = i; else done = false; } res.push(carry); if (done) break; } for (let i = 0; i < data.length - 1 && data[i] === 0; i++) res.push(0); return res.reverse(); } const gcd = (a, b) => (!b ? a : gcd(b, a % b)); const radix2carry = (from, to) => from + (to - gcd(from, to)); // BigInt is 5x slower function convertRadix2(data, from, to, padding) { if (!Array.isArray(data)) throw new Error('convertRadix2: data should be array'); if (from <= 0 || from > 32) throw new Error(`convertRadix2: wrong from=${from}`); if (to <= 0 || to > 32) throw new Error(`convertRadix2: wrong to=${to}`); if (radix2carry(from, to) > 32) { throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`); } let carry = 0; let pos = 0; // bitwise position in current element const mask = 2 ** to - 1; const res = []; for (const n of data) { assertNumber(n); if (n >= 2 ** from) throw new Error(`convertRadix2: invalid data word=${n} from=${from}`); carry = (carry << from) | n; if (pos + from > 32) throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`); pos += from; for (; pos >= to; pos -= to) res.push(((carry >> (pos - to)) & mask) >>> 0); carry &= 2 ** pos - 1; // clean carry, otherwise it will cause overflow } carry = (carry << (to - pos)) & mask; if (!padding && pos >= from) throw new Error('Excess padding'); if (!padding && carry) throw new Error(`Non-zero padding: ${carry}`); if (padding && pos > 0) res.push(carry >>> 0); return res; } function radix(num) { assertNumber(num); return { encode: (bytes) => { if (!(bytes instanceof Uint8Array)) throw new Error('radix.encode input should be Uint8Array'); return convertRadix(Array.from(bytes), 2 ** 8, num); }, decode: (digits) => { if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number')) throw new Error('radix.decode input should be array of strings'); return Uint8Array.from(convertRadix(digits, num, 2 ** 8)); }, }; } // If both bases are power of same number (like `2**8 <-> 2**64`), // there is a linear algorithm. For now we have implementation for power-of-two bases only function radix2(bits, revPadding = false) { assertNumber(bits); if (bits <= 0 || bits > 32) throw new Error('radix2: bits should be in (0..32]'); if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32) throw new Error('radix2: carry overflow'); return { encode: (bytes) => { if (!(bytes instanceof Uint8Array)) throw new Error('radix2.encode input should be Uint8Array'); return convertRadix2(Array.from(bytes), 8, bits, !revPadding); }, decode: (digits) => { if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number')) throw new Error('radix2.decode input should be array of strings'); return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding)); }, }; } function unsafeWrapper(fn) { if (typeof fn !== 'function') throw new Error('unsafeWrapper fn should be function'); return function (...args) { try { return fn.apply(null, args); } catch (e) { } }; } // RFC 4648 aka RFC 3548 // --------------------- const base16 = chain(radix2(4), alphabet('0123456789abcdef'), join('')); const base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding$1(5), join('')); chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding$1(5), join('')); chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1'))); const base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding$1(6), join('')); const base64url = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding$1(6), join('')); // base58 code // ----------- const genBase58 = (abc) => chain(radix(58), alphabet(abc), join('')); const base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'); genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'); genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'); // xmr ver is done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN. // Block encoding significantly reduces quadratic complexity of base58. // Data len (index) -> encoded block len const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11]; const base58xmr = { encode(data) { let res = ''; for (let i = 0; i < data.length; i += 8) { const block = data.subarray(i, i + 8); res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1'); } return res; }, decode(str) { let res = []; for (let i = 0; i < str.length; i += 11) { const slice = str.slice(i, i + 11); const blockLen = XMR_BLOCK_LEN.indexOf(slice.length); const block = base58.decode(slice); for (let j = 0; j < block.length - blockLen; j++) { if (block[j] !== 0) throw new Error('base58xmr: wrong padding'); } res = res.concat(Array.from(block.slice(block.length - blockLen))); } return Uint8Array.from(res); }, }; const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join('')); const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]; function bech32Polymod(pre) { const b = pre >> 25; let chk = (pre & 0x1ffffff) << 5; for (let i = 0; i < POLYMOD_GENERATORS.length; i++) { if (((b >> i) & 1) === 1) chk ^= POLYMOD_GENERATORS[i]; } return chk; } function bechChecksum(prefix, words, encodingConst = 1) { const len = prefix.length; let chk = 1; for (let i = 0; i < len; i++) { const c = prefix.charCodeAt(i); if (c < 33 || c > 126) throw new Error(`Invalid prefix (${prefix})`); chk = bech32Polymod(chk) ^ (c >> 5); } chk = bech32Polymod(chk); for (let i = 0; i < len; i++) chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f); for (let v of words) chk = bech32Polymod(chk) ^ v; for (let i = 0; i < 6; i++) chk = bech32Polymod(chk); chk ^= encodingConst; return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false)); } function genBech32(encoding) { const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3; const _words = radix2(5); const fromWords = _words.decode; const toWords = _words.encode; const fromWordsUnsafe = unsafeWrapper(fromWords); function encode(prefix, words, limit = 90) { if (typeof prefix !== 'string') throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`); if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number')) throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`); const actualLength = prefix.length + 7 + words.length; if (limit !== false && actualLength > limit) throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`); prefix = prefix.toLowerCase(); return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`; } function decode(str, limit = 90) { if (typeof str !== 'string') throw new Error(`bech32.decode input should be string, not ${typeof str}`); if (str.length < 8 || (limit !== false && str.length > limit)) throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`); // don't allow mixed case const lowered = str.toLowerCase(); if (str !== lowered && str !== str.toUpperCase()) throw new Error(`String must be lowercase or uppercase`); str = lowered; const sepIndex = str.lastIndexOf('1'); if (sepIndex === 0 || sepIndex === -1) throw new Error(`Letter "1" must be present between prefix and data only`); const prefix = str.slice(0, sepIndex); const _words = str.slice(sepIndex + 1); if (_words.length < 6) throw new Error('Data must be at least 6 characters long'); const words = BECH_ALPHABET.decode(_words).slice(0, -6); const sum = bechChecksum(prefix, words, ENCODING_CONST); if (!_words.endsWith(sum)) throw new Error(`Invalid checksum in ${str}: expected "${sum}"`); return { prefix, words }; } const decodeUnsafe = unsafeWrapper(decode); function decodeToBytes(str) { const { prefix, words } = decode(str, false); return { prefix, words, bytes: fromWords(words) }; } return { encode, decode, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords }; } genBech32('bech32'); genBech32('bech32m'); const utf8 = { encode: (data) => new TextDecoder().decode(data), decode: (str) => new TextEncoder().encode(str), }; const hex = chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => { if (typeof s !== 'string' || s.length % 2) throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`); return s.toLowerCase(); })); // prettier-ignore const CODERS = { utf8, hex, base16, base32, base64, base64url, base58, base58xmr }; `Invalid encoding type. Available types: ${Object.keys(CODERS).join(', ')}`; // ---------------------------------------------------------------------------- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code // EDIT THE CORRESPONDENT .ts FILE INSTEAD /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */ const _0n$7 = BigInt(0); const _1n$8 = BigInt(1); const _2n$5 = BigInt(2); const u8a = (a) => a instanceof Uint8Array; const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0')); function bytesToHex(bytes) { if (!u8a(bytes)) throw new Error('Uint8Array expected'); // pre-caching improves the speed 6x let hex = ''; for (let i = 0; i < bytes.length; i++) { hex += hexes[bytes[i]]; } return hex; } function numberToHexUnpadded(num) { const hex = num.toString(16); return hex.length & 1 ? `0${hex}` : hex; } function hexToNumber(hex) { if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex); // Big Endian return BigInt(hex === '' ? '0' : `0x${hex}`); } // Caching slows it down 2-3x function hexToBytes(hex) { if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex); if (hex.length % 2) throw new Error('hex string is invalid: unpadded ' + hex.length); const array = new Uint8Array(hex.length / 2); for (let i = 0; i < array.length; i++) { const j = i * 2; const hexByte = hex.slice(j, j + 2); const byte = Number.parseInt(hexByte, 16); if (Number.isNaN(byte) || byte < 0) throw new Error('invalid byte sequence'); array[i] = byte; } return array; } // Big Endian function bytesToNumberBE(bytes) { return hexToNumber(bytesToHex(bytes)); } function bytesToNumberLE(bytes) { if (!u8a(bytes)) throw new Error('Uint8Array expected'); return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse())); } const numberToBytesBE = (n, len) => hexToBytes(n.toString(16).padStart(len * 2, '0')); const numberToBytesLE = (n, len) => numberToBytesBE(n, len).reverse(); // Returns variable number bytes (minimal bigint encoding?) const numberToVarBytesBE = (n) => hexToBytes(numberToHexUnpadded(n)); function ensureBytes$1(title, hex, expectedLength) { let res; if (typeof hex === 'string') { try { res = hexToBytes(hex); } catch (e) { throw new Error(`${title} must be valid hex string, got "${hex}". Cause: ${e}`); } } else if (u8a(hex)) { // Uint8Array.from() instead of hash.slice() because node.js Buffer // is instance of Uint8Array, and its slice() creates **mutable** copy res = Uint8Array.from(hex); } else { throw new Error(`${title} must be hex string or Uint8Array`); } const len = res.length; if (typeof expectedLength === 'number' && len !== expectedLength) throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`); return res; } // Copies several Uint8Arrays into one. function concatBytes$1(...arrs) { const r = new Uint8Array(arrs.reduce((sum, a) => sum + a.length, 0)); let pad = 0; // walk through each item, ensure they have proper type arrs.forEach((a) => { if (!u8a(a)) throw new Error('Uint8Array expected'); r.set(a, pad); pad += a.length; }); return r; } function equalBytes(b1, b2) { // We don't care about timing attacks here if (b1.length !== b2.length) return false; for (let i = 0; i < b1.length; i++) if (b1[i] !== b2[i]) return false; return true; } function utf8ToBytes$1(str) { if (typeof str !== 'string') { throw new Error(`utf8ToBytes expected string, got ${typeof str}`); } return new TextEncoder().encode(str); } // Bit operations // Amount of bits inside bigint (Same as n.toString(2).length) function bitLen(n) { let len; for (len = 0; n > 0n; n >>= _1n$8, len += 1) ; return len; } // Gets single bit at position. NOTE: first bit position is 0 (same as arrays) // Same as !!+Array.from(n.toString(2)).reverse()[pos] const bitGet = (n, pos) => (n >> BigInt(pos)) & 1n; // Sets single bit at position const bitSet = (n, pos, value) => n | ((value ? _1n$8 : _0n$7) << BigInt(pos)); // Return mask for N bits (Same as BigInt(`0b${Array(i).fill('1').join('')}`)) // Not using ** operator with bigints for old engines. const bitMask = (n) => (_2n$5 << BigInt(n - 1)) - _1n$8; // DRBG const u8n = (data) => new Uint8Array(data); // creates Uint8Array const u8fr = (arr) => Uint8Array.from(arr); // another shortcut /** * Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs. * @returns function that will call DRBG until 2nd arg returns something meaningful * @example * const drbg = createHmacDRBG<Key>(32, 32, hmac); * drbg(seed, bytesToKey); // bytesToKey must return Key or undefined */ function createHmacDrbg(hashLen, qByteLen, hmacFn) { if (typeof hashLen !== 'number' || hashLen < 2) throw new Error('hashLen must be a number'); if (typeof qByteLen !== 'number' || qByteLen < 2) throw new Error('qByteLen must be a number'); if (typeof hmacFn !== 'function') throw new Error('hmacFn must be a function'); // Step B, Step C: set hashLen to 8*ceil(hlen/8) let v = u8n(h