"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.apiToBigInt = apiToBigInt;
exports.apiToSmallInt = apiToSmallInt;
exports.decodeBlockResults = exports.createJsonRpcRequest = void 0;
exports.decodeEvent = decodeEvent;
exports.encodeHeightParam = void 0;
exports.may = may;
exports.smallIntToApi = smallIntToApi;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _math = require("@cosmjs/math");
var _encoding = require("@cosmjs/encoding");
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var numbersWithoutZero = "123456789";

/** generates a random numeric character  */
function randomNumericChar() {
  return numbersWithoutZero[Math.floor(Math.random() * numbersWithoutZero.length)];
}

/**
 * An (absolutely not cryptographically secure) random integer > 0.
 */
function randomId() {
  return parseInt(Array.from({
    length: 12
  }).map(function () {
    return randomNumericChar();
  }).join(""), 10);
}

/** Creates a JSON-RPC request with random ID */
// eslint-disable-next-line @typescript-eslint/ban-types
var createJsonRpcRequest = exports.createJsonRpcRequest = function createJsonRpcRequest(method, params) {
  var paramsCopy = params ? _objectSpread({}, params) : {};
  return {
    jsonrpc: "2.0",
    id: randomId(),
    method: method,
    params: paramsCopy
  };
};

// may will run the transform if value is defined, otherwise returns undefined
function may(transform, value) {
  return value === undefined || value === null ? undefined : transform(value);
}
var encodeHeightParam = exports.encodeHeightParam = function encodeHeightParam(param) {
  return {
    height: may(smallIntToApi, param.height)
  };
};

/**
 * Takes an integer in the safe integer range and returns
 * a string representation to be used in the Tendermint RPC API.
 */
function smallIntToApi(num) {
  return new _math.Int53(num).toString();
}

/**
 * Takes an integer value from the Tendermint RPC API and
 * returns it as number.
 *
 * Only works within the safe integer range.
 */
function apiToSmallInt(input) {
  var asInt = typeof input === "number" ? new _math.Int53(input) : _math.Int53.fromString(input);
  return asInt.toNumber();
}
var decodeBlockResults = exports.decodeBlockResults = function decodeBlockResults(data) {
  var includeResults = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  return {
    height: apiToSmallInt(data.height),
    results: includeResults ? (data.txs_results || []).map(decodeTxData) : [],
    // remove below as not needed for blocksync-core
    // validatorUpdates: (data.validator_updates || []).map(decodeValidatorUpdate),
    // consensusUpdates: may(decodeConsensusParams, data.consensus_param_updates),
    beginBlockEvents: decodeEvents(data.begin_block_events || []),
    endBlockEvents: decodeEvents(data.end_block_events || []),
    // Add finalize_block_events as cosmos v0.50 has this
    finalizeBlockEvents: decodeEvents(data.finalize_block_events || [])
  };
};
function decodeEvent(event) {
  return {
    type: event.type,
    attributes: event.attributes ? decodeAttributes(event.attributes) : []
  };
}

/**
 * EventAttribute from Tendermint. In 0.35 the type of key and value was changed
 * from bytes to string, such that no base64 encoding is used anymore.
 */

function decodeEvents(events) {
  return events.map(decodeEvent);
}
function decodeAttributes(attributes) {
  return attributes.map(decodeEventAttribute);
}
function decodeEventAttribute(attribute) {
  var _attribute$value;
  return {
    key: attribute.key,
    value: (_attribute$value = attribute.value) !== null && _attribute$value !== void 0 ? _attribute$value : ""
  };
}
function decodeTxData(data) {
  var _data$code, _data$gas_wanted, _data$gas_used;
  return {
    code: apiToSmallInt((_data$code = data.code) !== null && _data$code !== void 0 ? _data$code : 0),
    codespace: data.codespace,
    log: data.log,
    data: may(_encoding.fromBase64, data.data),
    events: data.events ? decodeEvents(data.events) : [],
    gasWanted: apiToBigInt((_data$gas_wanted = data.gas_wanted) !== null && _data$gas_wanted !== void 0 ? _data$gas_wanted : "0"),
    gasUsed: apiToBigInt((_data$gas_used = data.gas_used) !== null && _data$gas_used !== void 0 ? _data$gas_used : "0")
  };
}

/**
 * Takes an integer value from the Tendermint RPC API and
 * returns it as BigInt.
 *
 * This supports the full uint64 and int64 ranges.
 */
function apiToBigInt(input) {
  if (!input.match(/^-?[0-9]+$/)) {
    throw new Error("Invalid string format");
  }
  return BigInt(input);
}