class RLPxConnectionFactory {

  public static AsyncResult<RLPxConnection> createHandshake(
      KeyPair keyPair,
      PublicKey remotePublicKey,
      Function<Bytes, AsyncResult<Bytes>> initAndResponse) {

    Bytes32 nonce = generateRandomBytes32();
    KeyPair ephemeralKeyPair = KeyPair.random();
    Bytes initHandshakeMessage = init(keyPair, remotePublicKey, ephemeralKeyPair, nonce);
    AsyncResult<Bytes> response = initAndResponse.apply(initHandshakeMessage);

    return response.thenApply(responseBytes -> {
      HandshakeMessage responseMessage = readResponse(responseBytes, keyPair.secretKey());
      return createConnection(
          true,
          initHandshakeMessage,
          responseBytes,
          ephemeralKeyPair.secretKey(),
          responseMessage.ephemeralPublicKey(),
          nonce,
          responseMessage.nonce(),
          keyPair.publicKey(),
          remotePublicKey);
    });
  }

}