ccxt 4.2.93 → 4.2.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +1055 -366
  3. package/dist/ccxt.browser.min.js +3 -3
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/base/Exchange.js +22 -1
  6. package/dist/cjs/src/base/errors.js +25 -64
  7. package/dist/cjs/src/base/ws/OrderBookSide.js +5 -0
  8. package/dist/cjs/src/binance.js +63 -2
  9. package/dist/cjs/src/bitget.js +139 -0
  10. package/dist/cjs/src/bitstamp.js +6 -0
  11. package/dist/cjs/src/coinex.js +61 -55
  12. package/dist/cjs/src/gemini.js +2 -1
  13. package/dist/cjs/src/htx.js +127 -125
  14. package/dist/cjs/src/okx.js +193 -40
  15. package/dist/cjs/src/pro/coinbase.js +18 -0
  16. package/dist/cjs/src/pro/kraken.js +107 -17
  17. package/dist/cjs/src/pro/krakenfutures.js +117 -40
  18. package/dist/cjs/src/pro/kucoin.js +30 -19
  19. package/dist/cjs/src/woo.js +139 -0
  20. package/examples/js/cli.js +4 -1
  21. package/examples/ts/cli.ts +4 -1
  22. package/js/ccxt.d.ts +4 -4
  23. package/js/ccxt.js +3 -3
  24. package/js/src/abstract/binance.d.ts +1 -0
  25. package/js/src/abstract/binancecoinm.d.ts +1 -0
  26. package/js/src/abstract/binanceus.d.ts +1 -0
  27. package/js/src/abstract/binanceusdm.d.ts +1 -0
  28. package/js/src/abstract/bitstamp.d.ts +6 -0
  29. package/js/src/base/Exchange.d.ts +8 -2
  30. package/js/src/base/Exchange.js +22 -1
  31. package/js/src/base/errorHierarchy.d.ts +1 -1
  32. package/js/src/base/errorHierarchy.js +1 -1
  33. package/js/src/base/errors.d.ts +26 -26
  34. package/js/src/base/errors.js +26 -66
  35. package/js/src/base/types.d.ts +12 -0
  36. package/js/src/base/ws/OrderBook.d.ts +7 -0
  37. package/js/src/base/ws/OrderBook.js +1 -6
  38. package/js/src/base/ws/OrderBookSide.d.ts +9 -3
  39. package/js/src/base/ws/OrderBookSide.js +6 -1
  40. package/js/src/binance.d.ts +1 -0
  41. package/js/src/binance.js +63 -2
  42. package/js/src/bitget.d.ts +4 -1
  43. package/js/src/bitget.js +139 -0
  44. package/js/src/bitstamp.js +6 -0
  45. package/js/src/coinex.js +61 -55
  46. package/js/src/gemini.js +2 -1
  47. package/js/src/htx.d.ts +1 -0
  48. package/js/src/htx.js +128 -126
  49. package/js/src/okx.d.ts +4 -1
  50. package/js/src/okx.js +193 -40
  51. package/js/src/pro/coinbase.js +18 -0
  52. package/js/src/pro/kraken.d.ts +6 -1
  53. package/js/src/pro/kraken.js +107 -17
  54. package/js/src/pro/krakenfutures.d.ts +8 -2
  55. package/js/src/pro/krakenfutures.js +117 -40
  56. package/js/src/pro/kucoin.js +30 -19
  57. package/js/src/woo.d.ts +4 -1
  58. package/js/src/woo.js +139 -0
  59. package/package.json +1 -1
  60. package/skip-tests.json +5 -0
@@ -5,74 +5,37 @@
5
5
  // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
6
 
7
7
  /* eslint-disable max-classes-per-file */
8
- // import { errorHierarchy } from './errorHierarchy.js';
9
- // Commented out since I'm not sure this is mandatory anymore
10
- // and does not work out of the box with esm
11
- // /* ------------------------------------------------------------------------ */
12
- // function subclass (BaseClass, classes, namespace = {}) {
13
- // for (const [className, subclasses] of Object.entries (classes)) {
14
- // const Class = Object.assign (namespace, {
15
- // /* By creating a named property, we trick compiler to assign our class constructor function a name.
16
- // Otherwise, all our error constructors would be shown as [Function: Error] in the debugger! And
17
- // the super-useful `e.constructor.name` magic wouldn't work — we then would have no chance to
18
- // obtain a error type string from an error instance programmatically! */
19
- // [className]: class extends BaseClass {
20
- // constructor (message) {
21
- // super (message)
22
- // /* A workaround to make `instanceof` work on custom Error classes in transpiled ES5.
23
- // See my blog post for the explanation of this hack:
24
- // https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801 */
25
- // this.constructor = Class
26
- // this.__proto__ = Class.prototype
27
- // this.name = className
28
- // this.message = message
29
- // // https://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-extending-built-ins-like-error-array-and-map-work
30
- // Object.setPrototypeOf (this, Class.prototype)
31
- // }
32
- // }
33
- // })[className]
34
- // subclass (Class, subclasses, namespace)
35
- // }
36
- // return namespace
37
- // }
38
8
  class BaseError extends Error {
39
9
  constructor(message) {
40
10
  super(message);
41
11
  this.name = 'BaseError';
42
12
  }
43
13
  }
44
- // Exchange Error errors
45
- class ExchangeError extends Error {
14
+ class ExchangeError extends BaseError {
46
15
  constructor(message) {
47
16
  super(message);
48
17
  this.name = 'ExchangeError';
49
18
  }
50
19
  }
51
- class ExchangeClosedByUser extends Error {
52
- constructor(message) {
53
- super(message);
54
- this.name = 'ExchangeClosedByUser';
55
- }
56
- }
57
20
  class AuthenticationError extends ExchangeError {
58
21
  constructor(message) {
59
22
  super(message);
60
23
  this.name = 'AuthenticationError';
61
24
  }
62
25
  }
63
- class PermissionDenied extends ExchangeError {
26
+ class PermissionDenied extends AuthenticationError {
64
27
  constructor(message) {
65
28
  super(message);
66
29
  this.name = 'PermissionDenied';
67
30
  }
68
31
  }
69
- class AccountNotEnabled extends ExchangeError {
32
+ class AccountNotEnabled extends PermissionDenied {
70
33
  constructor(message) {
71
34
  super(message);
72
35
  this.name = 'AccountNotEnabled';
73
36
  }
74
37
  }
75
- class AccountSuspended extends ExchangeError {
38
+ class AccountSuspended extends AuthenticationError {
76
39
  constructor(message) {
77
40
  super(message);
78
41
  this.name = 'AccountSuspended';
@@ -90,16 +53,16 @@ class BadRequest extends ExchangeError {
90
53
  this.name = 'BadRequest';
91
54
  }
92
55
  }
93
- class OperationRejected extends ExchangeError {
56
+ class BadSymbol extends BadRequest {
94
57
  constructor(message) {
95
58
  super(message);
96
- this.name = 'OperationRejected';
59
+ this.name = 'BadSymbol';
97
60
  }
98
61
  }
99
- class BadSymbol extends BadRequest {
62
+ class OperationRejected extends ExchangeError {
100
63
  constructor(message) {
101
64
  super(message);
102
- this.name = 'BadSymbol';
65
+ this.name = 'OperationRejected';
103
66
  }
104
67
  }
105
68
  class NoChange extends OperationRejected {
@@ -120,7 +83,7 @@ class BadResponse extends ExchangeError {
120
83
  this.name = 'BadResponse';
121
84
  }
122
85
  }
123
- class NullResponse extends ExchangeError {
86
+ class NullResponse extends BadResponse {
124
87
  constructor(message) {
125
88
  super(message);
126
89
  this.name = 'NullResponse';
@@ -150,12 +113,6 @@ class InvalidOrder extends ExchangeError {
150
113
  this.name = 'InvalidOrder';
151
114
  }
152
115
  }
153
- class ContractUnavailable extends InvalidOrder {
154
- constructor(message) {
155
- super(message);
156
- this.name = 'ContractUnavailable';
157
- }
158
- }
159
116
  class OrderNotFound extends InvalidOrder {
160
117
  constructor(message) {
161
118
  super(message);
@@ -192,25 +149,36 @@ class DuplicateOrderId extends InvalidOrder {
192
149
  this.name = 'DuplicateOrderId';
193
150
  }
194
151
  }
152
+ class ContractUnavailable extends InvalidOrder {
153
+ constructor(message) {
154
+ super(message);
155
+ this.name = 'ContractUnavailable';
156
+ }
157
+ }
195
158
  class NotSupported extends ExchangeError {
196
159
  constructor(message) {
197
160
  super(message);
198
161
  this.name = 'NotSupported';
199
162
  }
200
163
  }
201
- class OperationFailed extends BaseError {
164
+ class ProxyError extends ExchangeError {
202
165
  constructor(message) {
203
166
  super(message);
204
- this.name = 'OperationFailed';
167
+ this.name = 'ProxyError';
205
168
  }
206
169
  }
207
- class ProxyError extends ExchangeError {
170
+ class ExchangeClosedByUser extends ExchangeError {
171
+ constructor(message) {
172
+ super(message);
173
+ this.name = 'ExchangeClosedByUser';
174
+ }
175
+ }
176
+ class OperationFailed extends BaseError {
208
177
  constructor(message) {
209
178
  super(message);
210
179
  this.name = 'OperationFailed';
211
180
  }
212
181
  }
213
- // Network error
214
182
  class NetworkError extends OperationFailed {
215
183
  constructor(message) {
216
184
  super(message);
@@ -253,13 +221,5 @@ class RequestTimeout extends NetworkError {
253
221
  this.name = 'RequestTimeout';
254
222
  }
255
223
  }
256
- /* ------------------------------------------------------------------------ */
257
- // export default subclass (
258
- // // Root class
259
- // Error,
260
- // // Derived class hierarchy
261
- // errorHierarchy
262
- // )
263
- const errors = { BaseError, ExchangeClosedByUser, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, ContractUnavailable, NoChange, OperationRejected, OperationFailed, ProxyError };
264
- export { BaseError, ExchangeClosedByUser, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, ContractUnavailable, NoChange, OperationRejected, OperationFailed, ProxyError };
265
- export default errors;
224
+ export { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, ProxyError, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout };
225
+ export default { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, ProxyError, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout };
@@ -427,6 +427,18 @@ export interface Greeks {
427
427
  underlyingPrice: number;
428
428
  info: any;
429
429
  }
430
+ export interface Conversion {
431
+ info: any;
432
+ timestamp?: number;
433
+ datetime?: string;
434
+ id: string;
435
+ fromCurrency: string;
436
+ fromAmount: number;
437
+ toCurrency: string;
438
+ toAmount: number;
439
+ price: number;
440
+ fee: number;
441
+ }
430
442
  export interface Option {
431
443
  info: any;
432
444
  currency: string;
@@ -1,8 +1,15 @@
1
+ import { IOrderBookSide } from './OrderBookSide.js';
2
+ import { Int, Str } from '../types.js';
1
3
  interface CustomOrderBookProp {
2
4
  cache: any[];
3
5
  }
4
6
  declare class OrderBook implements CustomOrderBookProp {
5
7
  cache: any[];
8
+ asks: IOrderBookSide<any>;
9
+ bids: IOrderBookSide<any>;
10
+ timestamp: Int;
11
+ datetime: Str;
12
+ nonce: Int;
6
13
  constructor(snapshot?: {}, depth?: any);
7
14
  limit(): this;
8
15
  update(snapshot: any): this;
@@ -8,12 +8,7 @@
8
8
  // @ts-nocheck
9
9
  import { iso8601 } from '../../base/functions/time.js';
10
10
  import { extend } from '../../base/functions/generic.js';
11
- import { Asks, Bids, CountedAsks, CountedBids, IndexedAsks, IndexedBids,
12
- // IncrementalAsks,
13
- // IncrementalBids,
14
- // IncrementalIndexedAsks,
15
- // IncrementalIndexedBids, // check this
16
- } from './OrderBookSide.js';
11
+ import { Asks, Bids, CountedAsks, CountedBids, IndexedAsks, IndexedBids } from './OrderBookSide.js';
17
12
  class OrderBook {
18
13
  constructor(snapshot = {}, depth = undefined) {
19
14
  this.cache = []; // make prop visible so we use typed OrderBooks
@@ -1,4 +1,10 @@
1
- declare class OrderBookSide extends Array {
1
+ interface IOrderBookSide<T> extends Array<T> {
2
+ store(price: any, size: any): any;
3
+ store(price: any, size: any, index: any): any;
4
+ storeArray(array: any[]): any;
5
+ limit(): any;
6
+ }
7
+ declare class OrderBookSide implements IOrderBookSide extends Array {
2
8
  constructor(deltas?: any[], depth?: any);
3
9
  storeArray(delta: any): void;
4
10
  store(price: any, size: any): void;
@@ -8,7 +14,7 @@ declare class CountedOrderBookSide extends OrderBookSide {
8
14
  store(price: any, size: any, count: any): void;
9
15
  storeArray(delta: any): void;
10
16
  }
11
- declare class IndexedOrderBookSide extends Array {
17
+ declare class IndexedOrderBookSide implements IOrderBookSide extends Array {
12
18
  constructor(deltas?: any[], depth?: number);
13
19
  store(price: any, size: any, id: any): void;
14
20
  storeArray(delta: any): void;
@@ -32,4 +38,4 @@ declare class IndexedAsks extends IndexedOrderBookSide {
32
38
  declare class IndexedBids extends IndexedOrderBookSide {
33
39
  get side(): boolean;
34
40
  }
35
- export { Asks, Bids, OrderBookSide, CountedAsks, CountedBids, CountedOrderBookSide, IndexedAsks, IndexedBids, IndexedOrderBookSide, };
41
+ export { Asks, Bids, OrderBookSide, CountedAsks, CountedBids, CountedOrderBookSide, IndexedAsks, IndexedBids, IndexedOrderBookSide, IOrderBookSide };
@@ -12,6 +12,11 @@
12
12
  // Author: github.com/frosty00
13
13
  // Email: carlo.revelli@berkeley.edu
14
14
  //
15
+ /**
16
+ *
17
+ * @param array
18
+ * @param x
19
+ */
15
20
  function bisectLeft(array, x) {
16
21
  let low = 0;
17
22
  let high = array.length - 1;
@@ -278,4 +283,4 @@ Asks, Bids, OrderBookSide,
278
283
  // count-based
279
284
  CountedAsks, CountedBids, CountedOrderBookSide,
280
285
  // order-id based
281
- IndexedAsks, IndexedBids, IndexedOrderBookSide, };
286
+ IndexedAsks, IndexedBids, IndexedOrderBookSide };
@@ -439,4 +439,5 @@ export default class binance extends Exchange {
439
439
  quoteVolume: any;
440
440
  };
441
441
  fetchMarginAdjustmentHistory(symbol?: Str, type?: Str, since?: Num, limit?: Num, params?: {}): Promise<MarginModification[]>;
442
+ fetchConvertCurrencies(params?: {}): Promise<Currencies>;
442
443
  }
package/js/src/binance.js CHANGED
@@ -74,6 +74,8 @@ export default class binance extends Exchange {
74
74
  'fetchCanceledOrders': 'emulated',
75
75
  'fetchClosedOrder': false,
76
76
  'fetchClosedOrders': 'emulated',
77
+ 'fetchConvertCurrencies': true,
78
+ 'fetchConvertQuote': false,
77
79
  'fetchCrossBorrowRate': true,
78
80
  'fetchCrossBorrowRates': false,
79
81
  'fetchCurrencies': true,
@@ -973,6 +975,7 @@ export default class binance extends Exchange {
973
975
  },
974
976
  'post': {
975
977
  'order/oco': 0.2,
978
+ 'orderList/oco': 0.2,
976
979
  'sor/order': 0.2,
977
980
  'sor/order/test': 0.2,
978
981
  'order': 0.2,
@@ -4240,11 +4243,14 @@ export default class binance extends Exchange {
4240
4243
  'interval': this.safeString(this.timeframes, timeframe, timeframe),
4241
4244
  'limit': limit,
4242
4245
  };
4246
+ const marketId = market['id'];
4243
4247
  if (price === 'index') {
4244
- request['pair'] = market['id']; // Index price takes this argument instead of symbol
4248
+ const parts = marketId.split('_');
4249
+ const pair = this.safeString(parts, 0);
4250
+ request['pair'] = pair; // Index price takes this argument instead of symbol
4245
4251
  }
4246
4252
  else {
4247
- request['symbol'] = market['id'];
4253
+ request['symbol'] = marketId;
4248
4254
  }
4249
4255
  // const duration = this.parseTimeframe (timeframe);
4250
4256
  if (since !== undefined) {
@@ -12589,4 +12595,59 @@ export default class binance extends Exchange {
12589
12595
  const modifications = this.parseMarginModifications(response);
12590
12596
  return this.filterBySymbolSinceLimit(modifications, symbol, since, limit);
12591
12597
  }
12598
+ async fetchConvertCurrencies(params = {}) {
12599
+ /**
12600
+ * @method
12601
+ * @name binance#fetchConvertCurrencies
12602
+ * @description fetches all available currencies that can be converted
12603
+ * @see https://binance-docs.github.io/apidocs/spot/en/#query-order-quantity-precision-per-asset-user_data
12604
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
12605
+ * @returns {object} an associative dictionary of currencies
12606
+ */
12607
+ await this.loadMarkets();
12608
+ const response = await this.sapiGetConvertAssetInfo(params);
12609
+ //
12610
+ // [
12611
+ // {
12612
+ // "asset": "BTC",
12613
+ // "fraction": 8
12614
+ // },
12615
+ // ]
12616
+ //
12617
+ const result = {};
12618
+ for (let i = 0; i < response.length; i++) {
12619
+ const entry = response[i];
12620
+ const id = this.safeString(entry, 'asset');
12621
+ const code = this.safeCurrencyCode(id);
12622
+ result[code] = {
12623
+ 'info': entry,
12624
+ 'id': id,
12625
+ 'code': code,
12626
+ 'networks': undefined,
12627
+ 'type': undefined,
12628
+ 'name': undefined,
12629
+ 'active': undefined,
12630
+ 'deposit': undefined,
12631
+ 'withdraw': undefined,
12632
+ 'fee': undefined,
12633
+ 'precision': this.safeInteger(entry, 'fraction'),
12634
+ 'limits': {
12635
+ 'amount': {
12636
+ 'min': undefined,
12637
+ 'max': undefined,
12638
+ },
12639
+ 'withdraw': {
12640
+ 'min': undefined,
12641
+ 'max': undefined,
12642
+ },
12643
+ 'deposit': {
12644
+ 'min': undefined,
12645
+ 'max': undefined,
12646
+ },
12647
+ },
12648
+ 'created': undefined,
12649
+ };
12650
+ }
12651
+ return result;
12652
+ }
12592
12653
  }
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/bitget.js';
2
- import type { Int, OrderSide, OrderType, Trade, OHLCV, Order, FundingRateHistory, OrderRequest, FundingHistory, Balances, Str, Transaction, Ticker, OrderBook, Tickers, Market, Strings, Currency, Position, Liquidation, TransferEntry, Leverage, MarginMode, Num, MarginModification, TradingFeeInterface, Currencies, TradingFees } from './base/types.js';
2
+ import type { Int, OrderSide, OrderType, Trade, OHLCV, Order, FundingRateHistory, OrderRequest, FundingHistory, Balances, Str, Transaction, Ticker, OrderBook, Tickers, Market, Strings, Currency, Position, Liquidation, TransferEntry, Leverage, MarginMode, Num, MarginModification, TradingFeeInterface, Currencies, TradingFees, Conversion } from './base/types.js';
3
3
  /**
4
4
  * @class bitget
5
5
  * @augments Exchange
@@ -282,6 +282,9 @@ export default class bitget extends Exchange {
282
282
  closeAllPositions(params?: {}): Promise<Position[]>;
283
283
  fetchMarginMode(symbol: string, params?: {}): Promise<MarginMode>;
284
284
  parseMarginMode(marginMode: any, market?: any): MarginMode;
285
+ fetchConvertQuote(fromCode: string, toCode: string, amount?: Num, params?: {}): Promise<Conversion>;
286
+ parseConversion(conversion: any, fromCurrency?: Currency, toCurrency?: Currency): Conversion;
287
+ fetchConvertCurrencies(params?: {}): Promise<Currencies>;
285
288
  handleErrors(code: any, reason: any, url: any, method: any, headers: any, body: any, response: any, requestHeaders: any, requestBody: any): any;
286
289
  sign(path: any, api?: any[], method?: string, params?: {}, headers?: any, body?: any): {
287
290
  url: string;
package/js/src/bitget.js CHANGED
@@ -66,6 +66,8 @@ export default class bitget extends Exchange {
66
66
  'fetchCanceledAndClosedOrders': true,
67
67
  'fetchCanceledOrders': true,
68
68
  'fetchClosedOrders': true,
69
+ 'fetchConvertCurrencies': true,
70
+ 'fetchConvertQuote': true,
69
71
  'fetchCrossBorrowRate': true,
70
72
  'fetchCrossBorrowRates': false,
71
73
  'fetchCurrencies': true,
@@ -8445,6 +8447,143 @@ export default class bitget extends Exchange {
8445
8447
  'marginMode': marginType,
8446
8448
  };
8447
8449
  }
8450
+ async fetchConvertQuote(fromCode, toCode, amount = undefined, params = {}) {
8451
+ /**
8452
+ * @method
8453
+ * @name bitget#fetchConvertQuote
8454
+ * @description fetch a quote for converting from one currency to another
8455
+ * @see https://www.bitget.com/api-doc/common/convert/Get-Quoted-Price
8456
+ * @param {string} fromCode the currency that you want to sell and convert from
8457
+ * @param {string} toCode the currency that you want to buy and convert into
8458
+ * @param {float} [amount] how much you want to trade in units of the from currency
8459
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
8460
+ * @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure}
8461
+ */
8462
+ await this.loadMarkets();
8463
+ const request = {
8464
+ 'fromCoin': fromCode.toUpperCase(),
8465
+ 'toCoin': toCode.toUpperCase(),
8466
+ 'fromCoinSize': this.numberToString(amount),
8467
+ };
8468
+ const response = await this.privateConvertGetV2ConvertQuotedPrice(this.extend(request, params));
8469
+ //
8470
+ // {
8471
+ // "code": "00000",
8472
+ // "msg": "success",
8473
+ // "requestTime": 1712121940158,
8474
+ // "data": {
8475
+ // "fromCoin": "USDT",
8476
+ // "fromCoinSize": "5",
8477
+ // "cnvtPrice": "0.9993007892377704",
8478
+ // "toCoin": "USDC",
8479
+ // "toCoinSize": "4.99650394",
8480
+ // "traceId": "1159288930228187140",
8481
+ // "fee": "0"
8482
+ // }
8483
+ // }
8484
+ //
8485
+ const data = this.safeDict(response, 'data', {});
8486
+ const fromCurrencyId = this.safeString(data, 'fromCoin', fromCode);
8487
+ const fromCurrency = this.currency(fromCurrencyId);
8488
+ const toCurrencyId = this.safeString(data, 'toCoin', toCode);
8489
+ const toCurrency = this.currency(toCurrencyId);
8490
+ return this.parseConversion(data, fromCurrency, toCurrency);
8491
+ }
8492
+ parseConversion(conversion, fromCurrency = undefined, toCurrency = undefined) {
8493
+ //
8494
+ // fetchConvertQuote
8495
+ //
8496
+ // {
8497
+ // "fromCoin": "USDT",
8498
+ // "fromCoinSize": "5",
8499
+ // "cnvtPrice": "0.9993007892377704",
8500
+ // "toCoin": "USDC",
8501
+ // "toCoinSize": "4.99650394",
8502
+ // "traceId": "1159288930228187140",
8503
+ // "fee": "0"
8504
+ // }
8505
+ //
8506
+ const timestamp = this.safeInteger(conversion, 'ts');
8507
+ const fromCoin = this.safeString(conversion, 'fromCoin');
8508
+ const fromCode = this.safeCurrencyCode(fromCoin, fromCurrency);
8509
+ const to = this.safeString(conversion, 'toCoin');
8510
+ const toCode = this.safeCurrencyCode(to, toCurrency);
8511
+ return {
8512
+ 'info': conversion,
8513
+ 'timestamp': timestamp,
8514
+ 'datetime': this.iso8601(timestamp),
8515
+ 'id': this.safeString(conversion, 'traceId'),
8516
+ 'fromCurrency': fromCode,
8517
+ 'fromAmount': this.safeNumber(conversion, 'fromCoinSize'),
8518
+ 'toCurrency': toCode,
8519
+ 'toAmount': this.safeNumber(conversion, 'toCoinSize'),
8520
+ 'price': this.safeNumber(conversion, 'cnvtPrice'),
8521
+ 'fee': this.safeNumber(conversion, 'fee'),
8522
+ };
8523
+ }
8524
+ async fetchConvertCurrencies(params = {}) {
8525
+ /**
8526
+ * @method
8527
+ * @name bitget#fetchConvertCurrencies
8528
+ * @description fetches all available currencies that can be converted
8529
+ * @see https://www.bitget.com/api-doc/common/convert/Get-Convert-Currencies
8530
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
8531
+ * @returns {object} an associative dictionary of currencies
8532
+ */
8533
+ await this.loadMarkets();
8534
+ const response = await this.privateConvertGetV2ConvertCurrencies(params);
8535
+ //
8536
+ // {
8537
+ // "code": "00000",
8538
+ // "msg": "success",
8539
+ // "requestTime": 1712121755897,
8540
+ // "data": [
8541
+ // {
8542
+ // "coin": "BTC",
8543
+ // "available": "0.00009850",
8544
+ // "maxAmount": "0.756266",
8545
+ // "minAmount": "0.00001"
8546
+ // },
8547
+ // ]
8548
+ // }
8549
+ //
8550
+ const result = {};
8551
+ const data = this.safeList(response, 'data', []);
8552
+ for (let i = 0; i < data.length; i++) {
8553
+ const entry = data[i];
8554
+ const id = this.safeString(entry, 'coin');
8555
+ const code = this.safeCurrencyCode(id);
8556
+ result[code] = {
8557
+ 'info': entry,
8558
+ 'id': id,
8559
+ 'code': code,
8560
+ 'networks': undefined,
8561
+ 'type': undefined,
8562
+ 'name': undefined,
8563
+ 'active': undefined,
8564
+ 'deposit': undefined,
8565
+ 'withdraw': this.safeNumber(entry, 'available'),
8566
+ 'fee': undefined,
8567
+ 'precision': undefined,
8568
+ 'limits': {
8569
+ 'amount': {
8570
+ 'min': this.safeNumber(entry, 'minAmount'),
8571
+ 'max': this.safeNumber(entry, 'maxAmount'),
8572
+ },
8573
+ 'withdraw': {
8574
+ 'min': undefined,
8575
+ 'max': undefined,
8576
+ },
8577
+ 'deposit': {
8578
+ 'min': undefined,
8579
+ 'max': undefined,
8580
+ },
8581
+ },
8582
+ 'created': undefined,
8583
+ };
8584
+ }
8585
+ return result;
8586
+ }
8448
8587
  handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
8449
8588
  if (!response) {
8450
8589
  return undefined; // fallback to default error handler
@@ -360,6 +360,12 @@ export default class bitstamp extends Exchange {
360
360
  'blur_address/': 1,
361
361
  'vext_withdrawal/': 1,
362
362
  'vext_address/': 1,
363
+ 'cspr_withdrawal/': 1,
364
+ 'cspr_address/': 1,
365
+ 'vchf_withdrawal/': 1,
366
+ 'vchf_address/': 1,
367
+ 'veur_withdrawal/': 1,
368
+ 'veur_address/': 1,
363
369
  },
364
370
  },
365
371
  },