text: "use strict";
  
  //  ---------------------------------------------------------------------------
  
  const Exchange = require ('./base/Exchange')
  const { ExchangeError, NotSupported } = require ('./base/errors')
  
  //  ---------------------------------------------------------------------------
  
  module.exports = class coincheck extends Exchange {
  
      describe () {
          return this.deepExtend (super.describe (), {
              'id': 'coincheck',
              'name': 'coincheck',
              'countries': [ 'JP', 'ID' ],
              'rateLimit': 1500,
              'hasCORS': false,
              'urls': {
                  'logo': 'https://user-images.githubusercontent.com/1294454/27766464-3b5c3c74-5ed9-11e7-840e-31b32968e1da.jpg',
                  'api': 'https://coincheck.com/api',
                  'www': 'https://coincheck.com',
                  'doc': 'https://coincheck.com/documents/exchange/api',
              },
              'api': {
                  'public': {
                      'get': [
                          'exchange/orders/rate',
                          'order_books',
                          'rate/{pair}',
                          'ticker',
                          'trades',
                      ],
                  },
                  'private': {
                      'get': [
                          'accounts',
                          'accounts/balance',
                          'accounts/leverage_balance',
                          'bank_accounts',
                          'deposit_money',
                          'exchange/orders/opens',
                          'exchange/orders/transactions',
                          'exchange/orders/transactions_pagination',
                          'exchange/leverage/positions',
                          'lending/borrows/matches',
                          'send_money',
                          'withdraws',
                      ],
                      'post': [
                          'bank_accounts',
                          'deposit_money/{id}/fast',
                          'exchange/orders',
                          'exchange/transfers/to_leverage',
                          'exchange/transfers/from_leverage',
                          'lending/borrows',
                          'lending/borrows/{id}/repay',
                          'send_money',
                          'withdraws',
                      ],
                      'delete': [
                          'bank_accounts/{id}',
                          'exchange/orders/{id}',
                          'withdraws/{id}',
                      ],
                  },
              },
              'markets': {
                  'BTC/JPY': { 'id': 'btc_jpy', 'symbol': 'BTC/JPY', 'base': 'BTC', 'quote': 'JPY' }, // the only real pair
                  // 'ETH/JPY': { 'id': 'eth_jpy', 'symbol': 'ETH/JPY', 'base': 'ETH', 'quote': 'JPY' },
                  // 'ETC/JPY': { 'id': 'etc_jpy', 'symbol': 'ETC/JPY', 'base': 'ETC', 'quote': 'JPY' },
                  // 'DAO/JPY': { 'id': 'dao_jpy', 'symbol': 'DAO/JPY', 'base': 'DAO', 'quote': 'JPY' },
                  // 'LSK/JPY': { 'id': 'lsk_jpy', 'symbol': 'LSK/JPY', 'base': 'LSK', 'quote': 'JPY' },
                  // 'FCT/JPY': { 'id': 'fct_jpy', 'symbol': 'FCT/JPY', 'base': 'FCT', 'quote': 'JPY' },
                  // 'XMR/JPY': { 'id': 'xmr_jpy', 'symbol': 'XMR/JPY', 'base': 'XMR', 'quote': 'JPY' },
                  // 'REP/JPY': { 'id': 'rep_jpy', 'symbol': 'REP/JPY', 'base': 'REP', 'quote': 'JPY' },
                  // 'XRP/JPY': { 'id': 'xrp_jpy', 'symbol': 'XRP/JPY', 'base': 'XRP', 'quote': 'JPY' },
                  // 'ZEC/JPY': { 'id': 'zec_jpy', 'symbol': 'ZEC/JPY', 'base': 'ZEC', 'quote': 'JPY' },
                  // 'XEM/JPY': { 'id': 'xem_jpy', 'symbol': 'XEM/JPY', 'base': 'XEM', 'quote': 'JPY' },
                  // 'LTC/JPY': { 'id': 'ltc_jpy', 'symbol': 'LTC/JPY', 'base': 'LTC', 'quote': 'JPY' },
                  // 'DASH/JPY': { 'id': 'dash_jpy', 'symbol': 'DASH/JPY', 'base': 'DASH', 'quote': 'JPY' },
                  // 'ETH/BTC': { 'id': 'eth_btc', 'symbol': 'ETH/BTC', 'base': 'ETH', 'quote': 'BTC' },
                  // 'ETC/BTC': { 'id': 'etc_btc', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC' },
                  // 'LSK/BTC': { 'id': 'lsk_btc', 'symbol': 'LSK/BTC', 'base': 'LSK', 'quote': 'BTC' },
                  // 'FCT/BTC': { 'id': 'fct_btc', 'symbol': 'FCT/BTC', 'base': 'FCT', 'quote': 'BTC' },
                  // 'XMR/BTC': { 'id': 'xmr_btc', 'symbol': 'XMR/BTC', 'base': 'XMR', 'quote': 'BTC' },
                  // 'REP/BTC': { 'id': 'rep_btc', 'symbol': 'REP/BTC', 'base': 'REP', 'quote': 'BTC' },
                  // 'XRP/BTC': { 'id': 'xrp_btc', 'symbol': 'XRP/BTC', 'base': 'XRP', 'quote': 'BTC' },
                  // 'ZEC/BTC': { 'id': 'zec_btc', 'symbol': 'ZEC/BTC', 'base': 'ZEC', 'quote': 'BTC' },
                  // 'XEM/BTC': { 'id': 'xem_btc', 'symbol': 'XEM/BTC', 'base': 'XEM', 'quote': 'BTC' },
                  // 'LTC/BTC': { 'id': 'ltc_btc', 'symbol': 'LTC/BTC', 'base': 'LTC', 'quote': 'BTC' },
                  // 'DASH/BTC': { 'id': 'dash_btc', 'symbol': 'DASH/BTC', 'base': 'DASH', 'quote': 'BTC' },
              },
          });
      }
  
      async fetchBalance (params = {}) {
          let balances = await this.privateGetAccountsBalance ();
          let result = { 'info': balances };
          let currencies = Object.keys (this.currencies);
          for (let i = 0; i < currencies.length; i++) {
              let currency = currencies[i];
              let lowercase = currency.toLowerCase ();
              let account = this.account ();
              if (lowercase in balances)
                  account['free'] = parseFloat (balances[lowercase]);
              let reserved = lowercase + '_reserved';
              if (reserved in balances)
                  account['used'] = parseFloat (balances[reserved]);
              account['total'] = this.sum (account['free'], account['used']);
              result[currency] = account;
          }
          return this.parseBalance (result);
      }
  
      async fetchOrderBook (symbol, params = {}) {
          if (symbol != 'BTC/JPY')
              throw new NotSupported (this.id + ' fetchOrderBook () supports BTC/JPY only');
          let orderbook = await this.publicGetOrderBooks (params);
          return this.parseOrderBook (orderbook);
      }
  
      async fetchTicker (symbol, params = {}) {
          if (symbol != 'BTC/JPY')
              throw new NotSupported (this.id + ' fetchTicker () supports BTC/JPY only');
          let ticker = await this.publicGetTicker (params);
          let timestamp = ticker['timestamp'] * 1000;
          return {
              'symbol': symbol,
              'timestamp': timestamp,
              'datetime': this.iso8601 (timestamp),
              'high': parseFloat (ticker['high']),
              'low': parseFloat (ticker['low']),
              'bid': parseFloat (ticker['bid']),
              'ask': parseFloat (ticker['ask']),
              'vwap': undefined,
              'open': undefined,
              'close': undefined,
              'first': undefined,
              'last': parseFloat (ticker['last']),
              'change': undefined,
              'percentage': undefined,
              'average': undefined,
              'baseVolume': parseFloat (ticker['volume']),
              'quoteVolume': undefined,
              'info': ticker,
          };
      }
  
      parseTrade (trade, market) {
          let timestamp = this.parse8601 (trade['created_at']);
          return {
              'id': trade['id'].toString (),
              'timestamp': timestamp,
              'datetime': this.iso8601 (timestamp),
              'symbol': market['symbol'],
              'type': undefined,
              'side': trade['order_type'],
              'price': parseFloat (trade['rate']),
              'amount': parseFloat (trade['amount']),
              'info': trade,
          };
      }
  
      async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
          if (symbol != 'BTC/JPY')
              throw new NotSupported (this.id + ' fetchTrades () supports BTC/JPY only');
          let market = this.market (symbol);
          let response = await this.publicGetTrades (this.extend ({
              'pair': market['id'],
          }, params));
          if ('success' in response)
              if (response['success'])
                  if (typeof response['data'] !== 'undefined')
                      return this.parseTrades (response['data'], market, since, limit);
          throw new ExchangeError (this.id + ' ' + this.json (response));
      }
  
      async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
          let prefix = '';
          let order = {
              'pair': this.marketId (symbol),
          };
          if (type == 'market') {
              let order_type = type + '_' + side;
              order['order_type'] = order_type;
              let prefix = (side == 'buy') ? (order_type + '_') : '';
              order[prefix + 'amount'] = amount;
          } else {
              order['order_type'] = side;
              order['rate'] = price;
              order['amount'] = amount;
          }
          let response = await this.privatePostExchangeOrders (this.extend (order, params));
          return {
              'info': response,
              'id': response['id'].toString (),
          };
      }
  
      async cancelOrder (id, symbol = undefined, params = {}) {
          return await this.privateDeleteExchangeOrdersId ({ 'id': id });
      }
  
      sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
          let url = this.urls['api'] + '/' + this.implodeParams (path, params);
          let query = this.omit (params, this.extractParams (path));
          if (api == 'public') {
              if (Object.keys (query).length)
                  url += '?' + this.urlencode (query);
          } else {
              this.checkRequiredCredentials ();
              let nonce = this.nonce ().toString ();
              let queryString = '';
              if (method == 'GET') {
                  if (Object.keys (query).length)
                      url += '?' + this.urlencode (this.keysort (query));
              } else {
                  if (Object.keys (query).length) {
                      body = this.urlencode (this.keysort (query));
                      queryString = body;
                  }
              }
              let auth = nonce + url + queryString;
              headers = {
                  'Content-Type': 'application/x-www-form-urlencoded',
                  'ACCESS-KEY': this.apiKey,
                  'ACCESS-NONCE': nonce,
                  'ACCESS-SIGNATURE': this.hmac (this.encode (auth), this.encode (this.secret)),
              };
          }
          return { 'url': url, 'method': method, 'body': body, 'headers': headers };
      }
  
      async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
          let response = await this.fetch2 (path, api, method, params, headers, body);
          if (api == 'public')
              return response;
          if ('success' in response)
              if (response['success'])
                  return response;
          throw new ExchangeError (this.id + ' ' + this.json (response));
      }
  }
  