package nym import ( "encoding/binary" "fmt" ) // Wire-protocol tags for nym-client's native binary websocket protocol. // See clients/native/websocket-requests/src/{requests,responses}.rs upstream // (pinned to commit f84de25302e886d4bd97a898885c569724c002a7, the exact // nym-client 1.1.76 build embedded in this project). const ( ReqSend byte = 0x00 ReqSelfAddress byte = 0x03 RespError byte = 0x00 RespReceived byte = 0x01 RespSelfAddress byte = 0x02 ) // senderTagSize is AnonymousSenderTag's wire size, only present on a // Received push when the original sender used SendAnonymous/reply SURBs. const senderTagSize = 16 // EncodeSelfAddressRequest builds the binary "self address" request. func EncodeSelfAddressRequest() []byte { return []byte{ReqSelfAddress} } // DecodeSelfAddressResponse parses a binary SelfAddress response // (tag || 96-byte recipient) and formats it back into "id.enc@gw" form. func DecodeSelfAddressResponse(frame []byte) (string, error) { if len(frame) != 1+RecipientLen || frame[0] != RespSelfAddress { return "", fmt.Errorf("not a self-address response (%d bytes, tag 0x%02x)", len(frame), safeTag(frame)) } return FormatRecipient(frame[1:]) } // DecodeReceived extracts the message payload from a binary "Received" push: // // tag(1) || has_sender_tag(1) || [sender_tag(16) if flag=1] || msg_len(8, BE) || msg func DecodeReceived(frame []byte) ([]byte, bool) { if len(frame) < 2 || frame[0] != RespReceived { return nil, false } i := 2 switch frame[1] { case 0: case 1: i += senderTagSize default: return nil, false } if len(frame) < i+8 { return nil, false } msgLen := binary.BigEndian.Uint64(frame[i : i+8]) i += 8 if uint64(len(frame)-i) != msgLen { return nil, false } return frame[i:], true } func safeTag(frame []byte) byte { if len(frame) == 0 { return 0xff } return frame[0] }