function initialHandshake (channel, log) {
  return new Promise((resolve, reject) => {
    const handshakeErrorHandler = error => {
      reject(error)
    }

    channel.onerror = handshakeErrorHandler.bind(this)
    if (channel._error) {
      handshakeErrorHandler(channel._error)
    }

    channel.onmessage = buffer => {
      try {
        // read the response buffer and initialize the protocol
        const protocolVersion = parseNegotiatedResponse(buffer, log)
        resolve({
          protocolVersion,
          capabilites: 0,
          buffer,
          consumeRemainingBuffer: consumer => {
            if (buffer.hasRemaining()) {
              consumer(buffer.readSlice(buffer.remaining()))
            }
          }
        })
      } catch (e) {
        reject(e)
      }
    }

    channel.write(newHandshakeBuffer())
  })
}
Shake hands using the channel and return the protocol version, or the improved handshake protocol if communicating with a newer server.

@param {Channel} channel the channel use to shake hands
@param {Logger} log the log object
@returns {Promise<HandshakeResult>} Promise of protocol version and consumeRemainingBuffer