/// <summary> /// Casts the message to <see cref="NetMQMessage"/> with given <paramref name="key"/>, /// <paramref name="peer"/> and <paramref name="version"/>. /// </summary> /// <param name="key">A <see cref="PrivateKey"/> to sign message.</param> /// <param name="peer"><see cref="Peer"/>-typed representation of the /// sender's transport layer. /// <seealso cref="ITransport.AsPeer"/></param> /// <param name="timestamp">The <see cref="DateTimeOffset"/> of the message is created. /// </param> /// <param name="version"><see cref="AppProtocolVersion"/>-typed version of the /// transport layer.</param> /// <returns>A <see cref="NetMQMessage"/> containing the signed <see cref="Message"/>. /// </returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="peer"/> is /// <c>null</c>.</exception> public NetMQMessage ToNetMQMessage( PrivateKey key, Peer peer, DateTimeOffset timestamp, AppProtocolVersion version) { if (peer is null) { throw new ArgumentNullException(nameof(peer)); } var message = new NetMQMessage(); // Write body (by concrete class) foreach (NetMQFrame frame in DataFrames) { message.Append(frame); } // Write headers. (inverse order) message.Push(timestamp.Ticks); message.Push(SerializePeer(peer)); message.Push((byte)Type); message.Push(version.Token); // Make and insert signature byte[] signature = key.Sign(message.ToByteArray()); List <NetMQFrame> frames = message.ToList(); frames.Insert((int)MessageFrame.Sign, new NetMQFrame(signature)); message = new NetMQMessage(frames); if (Identity is byte[] to) { message.Push(to); } return(message); }