class BybitDigest extends BaseParamsDigest {

  public static final String X_BAPI_API_KEY = "X-BAPI-API-KEY";
  public static final String X_BAPI_SIGN = "X-BAPI-SIGN";
  public static final String X_BAPI_TIMESTAMP = "X-BAPI-TIMESTAMP";
  public static final String X_BAPI_RECV_WINDOW = "X-BAPI-RECV-WINDOW";

  public BybitDigest(String secretKeyBase64) {
    super(secretKeyBase64, HMAC_SHA_256);
  }

  public static ParamsDigest createInstance(String secretKeyBase64) {
    if (secretKeyBase64 != null) {
      return new BybitDigest(secretKeyBase64);
    } else {
      return null;
    }
  }

  @SneakyThrows
  @Override
  public String digestParams(RestInvocation restInvocation) {
    Map<String, String> headers = getHeaders(restInvocation);
    Map<String, String> params = getInputParams(restInvocation);
    Map<String, String> sortedParams = new TreeMap<>(params);

    // timestamp + API key + (recv_window) + (queryString | jsonBodyString)
    String plainText = getPlainText(restInvocation, sortedParams);
    String input =
        headers.get(X_BAPI_TIMESTAMP)
            + headers.get(X_BAPI_API_KEY)
            + headers.getOrDefault(X_BAPI_RECV_WINDOW, "")
            + plainText;

    Mac mac = getMac();
    mac.update(input.getBytes(StandardCharsets.UTF_8));
    return bytesToHex(mac.doFinal());
  }

  private static String getPlainText(
      RestInvocation restInvocation, Map<String, String> sortedParams) {
    if ("GET".equals(restInvocation.getHttpMethod())) {
      Params p = Params.of();
      sortedParams.forEach(p::add);
      return p.asQueryString();
    }
    if ("POST".equals(restInvocation.getHttpMethod())) {
      return restInvocation.getRequestBody();
    }
    throw new NotYetImplementedForExchangeException(
        "Only GET and POST are supported for plain text");
  }

  private Map<String, String> getHeaders(RestInvocation restInvocation) {
    return restInvocation.getParamsMap().get(HeaderParam.class).asHttpHeaders();
  }

  private Map<String, String> getInputParams(RestInvocation restInvocation) {<FILL_FUNCTION_BODY>}
}

    if ("GET".equals(restInvocation.getHttpMethod())) {
      return restInvocation.getParamsMap().get(QueryParam.class).asHttpHeaders();
    }
    if ("POST".equals(restInvocation.getHttpMethod())) {
      return restInvocation.getParamsMap().get(FormParam.class).asHttpHeaders();
    }
    throw new NotYetImplementedForExchangeException("Only GET and POST are supported in digest");
  
<methods>public javax.crypto.Mac getMac() <variables>public static final java.lang.String HMAC_MD5,public static final java.lang.String HMAC_SHA_1,public static final java.lang.String HMAC_SHA_256,public static final java.lang.String HMAC_SHA_384,public static final java.lang.String HMAC_SHA_512,private final non-sealed javax.crypto.Mac mac