gate: add fetchLeverage and fetchLeverages
diff --git a/ts/src/gate.ts b/ts/src/gate.ts
index 17ccb0d49f72..0aa5b3f4102e 100644
--- a/ts/src/gate.ts
+++ b/ts/src/gate.ts
@@ -5,7 +5,7 @@ import { Precise } from './base/Precise.js';
 import { TICK_SIZE } from './base/functions/number.js';
 import { ExchangeError, BadRequest, ArgumentsRequired, AuthenticationError, PermissionDenied, AccountSuspended, InsufficientFunds, RateLimitExceeded, ExchangeNotAvailable, BadSymbol, InvalidOrder, OrderNotFound, NotSupported, AccountNotEnabled, OrderImmediatelyFillable, BadResponse } from './base/errors.js';
 import { sha512 } from './static_dependencies/noble-hashes/sha512.js';
-import type { Int, OrderSide, OrderType, OHLCV, Trade, FundingRateHistory, OpenInterest, Order, Balances, OrderRequest, FundingHistory, Str, Transaction, Ticker, OrderBook, Tickers, Greeks, Strings, Market, Currency, MarketInterface, TransferEntry } from './base/types.js';
+import type { Int, OrderSide, OrderType, OHLCV, Trade, FundingRateHistory, OpenInterest, Order, Balances, OrderRequest, FundingHistory, Str, Transaction, Ticker, OrderBook, Tickers, Greeks, Strings, Market, Currency, MarketInterface, TransferEntry, Leverage, Leverages } from './base/types.js';
 
 /**
  * @class gate
@@ -115,7 +115,8 @@ export default class gate extends Exchange {
                 'fetchIsolatedBorrowRate': false,
                 'fetchIsolatedBorrowRates': false,
                 'fetchLedger': true,
-                'fetchLeverage': false,
+                'fetchLeverage': true,
+                'fetchLeverages': true,
                 'fetchLeverageTiers': true,
                 'fetchLiquidations': true,
                 'fetchMarginMode': false,
@@ -6988,6 +6989,177 @@ export default class gate extends Exchange {
         return await this.createOrder (symbol, 'market', side, 0, undefined, params);
     }
 
+    async fetchLeverage (symbol: string, params = {}): Promise<Leverage> {
+        /**
+         * @method
+         * @name gate#fetchLeverage
+         * @description fetch the set leverage for a market
+         * @see https://www.gate.io/docs/developers/apiv4/en/#get-unified-account-information
+         * @see https://www.gate.io/docs/developers/apiv4/en/#get-detail-of-lending-market
+         * @see https://www.gate.io/docs/developers/apiv4/en/#query-one-single-margin-currency-pair-deprecated
+         * @param {string} symbol unified market symbol
+         * @param {object} [params] extra parameters specific to the exchange API endpoint
+         * @param {boolean} [params.unified] default false, set to true for fetching the unified accounts leverage
+         * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
+         */
+        await this.loadMarkets ();
+        let market = undefined;
+        if (symbol !== undefined) {
+            // unified account does not require a symbol
+            market = this.market (symbol);
+        }
+        const request = {};
+        let response = undefined;
+        const isUnified = this.safeBool (params, 'unified');
+        params = this.omit (params, 'unified');
+        if (market['spot']) {
+            request['currency_pair'] = market['id'];
+            if (isUnified) {
+                response = await this.publicMarginGetUniCurrencyPairsCurrencyPair (this.extend (request, params));
+                //
+                //     {
+                //         "currency_pair": "BTC_USDT",
+                //         "base_min_borrow_amount": "0.0001",
+                //         "quote_min_borrow_amount": "1",
+                //         "leverage": "10"
+                //     }
+                //
+            } else {
+                response = await this.publicMarginGetCurrencyPairsCurrencyPair (this.extend (request, params));
+                //
+                //     {
+                //         "id": "BTC_USDT",
+                //         "base": "BTC",
+                //         "quote": "USDT",
+                //         "leverage": 10,
+                //         "min_base_amount": "0.0001",
+                //         "min_quote_amount": "1",
+                //         "max_quote_amount": "40000000",
+                //         "status": 1
+                //     }
+                //
+            }
+        } else if (isUnified) {
+            response = await this.privateUnifiedGetAccounts (this.extend (request, params));
+            //
+            //     {
+            //         "user_id": 10001,
+            //         "locked": false,
+            //         "balances": {
+            //             "ETH": {
+            //                 "available": "0",
+            //                 "freeze": "0",
+            //                 "borrowed": "0.075393666654",
+            //                 "negative_liab": "0",
+            //                 "futures_pos_liab": "0",
+            //                 "equity": "1016.1",
+            //                 "total_freeze": "0",
+            //                 "total_liab": "0"
+            //             },
+            //             "POINT": {
+            //                 "available": "9999999999.017023138734",
+            //                 "freeze": "0",
+            //                 "borrowed": "0",
+            //                 "negative_liab": "0",
+            //                 "futures_pos_liab": "0",
+            //                 "equity": "12016.1",
+            //                 "total_freeze": "0",
+            //                 "total_liab": "0"
+            //             },
+            //             "USDT": {
+            //                 "available": "0.00000062023",
+            //                 "freeze": "0",
+            //                 "borrowed": "0",
+            //                 "negative_liab": "0",
+            //                 "futures_pos_liab": "0",
+            //                 "equity": "16.1",
+            //                 "total_freeze": "0",
+            //                 "total_liab": "0"
+            //             }
+            //         },
+            //         "total": "230.94621713",
+            //         "borrowed": "161.66395521",
+            //         "total_initial_margin": "1025.0524665088",
+            //         "total_margin_balance": "3382495.944473949183",
+            //         "total_maintenance_margin": "205.01049330176",
+            //         "total_initial_margin_rate": "3299.827135672679",
+            //         "total_maintenance_margin_rate": "16499.135678363399",
+            //         "total_available_margin": "3381470.892007440383",
+            //         "unified_account_total": "3381470.892007440383",
+            //         "unified_account_total_liab": "0",
+            //         "unified_account_total_equity": "100016.1",
+            //         "leverage": "2"
+            //     }
+            //
+        } else {
+            throw new NotSupported (this.id + ' fetchLeverage() does not support ' + market['type'] + ' markets');
+        }
+        return this.parseLeverage (response, market);
+    }
+
+    async fetchLeverages (symbols: string[] = undefined, params = {}): Promise<Leverages> {
+        /**
+         * @method
+         * @name gate#fetchLeverages
+         * @description fetch the set leverage for all leverage markets, only spot margin is supported on gate
+         * @see https://www.gate.io/docs/developers/apiv4/en/#list-lending-markets
+         * @see https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading-deprecated
+         * @param {string[]} symbols a list of unified market symbols
+         * @param {object} [params] extra parameters specific to the exchange API endpoint
+         * @param {boolean} [params.unified] default false, set to true for fetching unified account leverages
+         * @returns {object} a list of [leverage structures]{@link https://docs.ccxt.com/#/?id=leverage-structure}
+         */
+        await this.loadMarkets ();
+        symbols = this.marketSymbols (symbols);
+        let response = undefined;
+        const isUnified = this.safeBool (params, 'unified');
+        params = this.omit (params, 'unified');
+        let marketIdRequest = 'id';
+        if (isUnified) {
+            marketIdRequest = 'currency_pair';
+            response = await this.publicMarginGetUniCurrencyPairs (params);
+            //
+            //     [
+            //         {
+            //             "currency_pair": "1INCH_USDT",
+            //             "base_min_borrow_amount": "8",
+            //             "quote_min_borrow_amount": "1",
+            //             "leverage": "3"
+            //         },
+            //     ]
+            //
+        } else {
+            response = await this.publicMarginGetCurrencyPairs (params);
+            //
+            //     [
+            //         {
+            //             "id": "1CAT_USDT",
+            //             "base": "1CAT",
+            //             "quote": "USDT",
+            //             "leverage": 3,
+            //             "min_base_amount": "71",
+            //             "min_quote_amount": "1",
+            //             "max_quote_amount": "10000",
+            //             "status": 1
+            //         },
+            //     ]
+            //
+        }
+        return this.parseLeverages (response, symbols, marketIdRequest, 'spot');
+    }
+
+    parseLeverage (leverage, market = undefined): Leverage {
+        const marketId = this.safeString2 (leverage, 'currency_pair', 'id');
+        const leverageValue = this.safeInteger (leverage, 'leverage');
+        return {
+            'info': leverage,
+            'symbol': this.safeSymbol (marketId, market, '_', 'spot'),
+            'marginMode': undefined,
+            'longLeverage': leverageValue,
+            'shortLeverage': leverageValue,
+        } as Leverage;
+    }
+
     handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
         if (response === undefined) {
             return undefined;
diff --git a/ts/src/test/static/request/gate.json b/ts/src/test/static/request/gate.json
index 8d0155221809..9dce44e6d6b0 100644
--- a/ts/src/test/static/request/gate.json
+++ b/ts/src/test/static/request/gate.json
@@ -1106,6 +1106,46 @@
                     "BTC/USDT:USDT"
                 ]
             }
+        ],
+        "fetchLeverage": [
+            {
+                "description": "Spot margin unified fetch leverage",
+                "method": "fetchLeverage",
+                "url": "https://api.gateio.ws/api/v4/margin/uni/currency_pairs/BTC_USDT",
+                "input": [
+                  "BTC/USDT",
+                  {
+                    "unified": true
+                  }
+                ]
+            },
+            {
+                "description": "Spot margin fetch leverage",
+                "method": "fetchLeverage",
+                "url": "https://api.gateio.ws/api/v4/margin/currency_pairs/BTC_USDT",
+                "input": [
+                  "BTC/USDT"
+                ]
+            }
+        ],
+        "fetchLeverages": [
+            {
+                "description": "Spot margin unified fetch all leverages",
+                "method": "fetchLeverages",
+                "url": "https://api.gateio.ws/api/v4/margin/uni/currency_pairs",
+                "input": [
+                  null,
+                  {
+                    "unified": true
+                  }
+                ]
+            },
+            {
+                "description": "Spot margin fetch all leverages",
+                "method": "fetchLeverages",
+                "url": "https://api.gateio.ws/api/v4/margin/currency_pairs",
+                "input": []
+            }
         ]
     }
 }
\ No newline at end of file

Added fetchLeverage and fetchLeverages to gate:

```
gate fetchLeverage BTC/USDT '{"unified":true}'

gate.fetchLeverage (BTC/USDT, [object Object])
2024-03-13T05:33:11.066Z iteration 0 passed in 250 ms

{
  info: {
    currency_pair: 'BTC_USDT',
    base_min_borrow_amount: '0.0001',
    quote_min_borrow_amount: '1',
    leverage: '10'
  },
  symbol: 'BTC/USDT',
  longLeverage: 10,
  shortLeverage: 10
}
```
```
gate fetchLeverage BTC/USDT

gate.fetchLeverage (BTC/USDT)
2024-03-13T05:33:42.867Z iteration 0 passed in 245 ms

{
  info: {
    id: 'BTC_USDT',
    base: 'BTC',
    quote: 'USDT',
    leverage: '10',
    min_base_amount: '0.0001',
    min_quote_amount: '1',
    max_quote_amount: '40000000',
    status: '1'
  },
  symbol: 'BTC/USDT',
  longLeverage: 10,
  shortLeverage: 10
}
```