createGroup (52)
The createGroup message is sent by the group creator to each initial participant to establish a new peer-to-peer group chat. Upon receiving this message, each participant derives the deterministic group address, adds it to their contact list, and begins participating in the group.
This message is sent within a SpixiMessage envelope with code 52. Unlike most group messages, createGroup does not set the groupAddress field on the SpixiMessage envelope - it is sent directly to each participant's address as a standard peer-to-peer message.
Core Data Types
IxiBytes: See IxiBytes Encoding.IxiVarUInt: See IxiVarInt Encoding.string: A standard UTF-8 encoded string, serialized asIxiBytes(length-prefixed byte array).
Payload Structure
The data field of the SpixiMessage is a serialized CreateGroupMessage with the following fields, in order:
| Field | Data Type | Min | Max | Description |
|---|---|---|---|---|
randomId | IxiBytes | 16 bytes | 16 bytes | A cryptographically random identifier generated by the group creator. Used together with the creator's address to deterministically derive the group address via GroupChat.DeriveGroupAddress(). |
groupName | IxiBytes (UTF-8) | 1 | * | The human-readable display name of the group. |
hideParticipantAddresses | byte | 0 | 1 | A boolean flag (1 = enabled, 0 = disabled). When enabled, participant addresses are hidden from each other by deriving pseudonymous group-scoped addresses using DeriveGroupAddress(participantAddress, randomId). |
participantCount | IxiVarUInt | 0 | 10 | The number of participant entries that follow. Limited to a maximum of 10. |
participants[] | repeated | A list of participantCount entries, each consisting of: | ||
↳ address | IxiBytes | * | * | The participant's address. If hideParticipantAddresses is enabled, this is the derived group-scoped address. Otherwise, it is the participant's real address. |
↳ name | IxiBytes (UTF-8) | 0 | * | The participant's display name. May be empty (null / zero-length bytes). |
channelCount | IxiVarUInt | 0 | 10 | The number of channel entries that follow. Limited to a maximum of 10. |
channels[] | repeated | A list of channelCount entries, each consisting of: | ||
↳ channelName | IxiBytes (UTF-8) | * | * | The name of the channel (e.g., "general"). |
↳ channelData | IxiBytes | * | * | A serialized BotChannel object containing index (int32) and channelName (string). |
Group Address Derivation
The group address is deterministically derived from the creator's address and the randomId:
derivationBytes = creator.addressNoChecksum || randomId
hash = SHA3-512-SQ-Trunc(derivationBytes, addressVersionLength - 1)
groupAddress = [version_byte=1] || hash
This ensures a unique, collision-resistant address that all participants can independently compute using only the creator's public key (from which the address is derived) and the randomId.
Behavioral Notes
- Sending: The creator calls
GroupChat.CreateGroup()to generate the group locally (includingrandomId, friend entry, user list, and metadata). The creator then wraps theCreateGroupMessagein aSpixiMessageof typecreateGroupand sends it to each participant individually. ThegroupAddressfield on theSpixiMessageis intentionally not set for this message type. - Receiving: Upon receiving a
createGroupmessage, the recipient callsGroupChat.JoinGroup(), which derives the group address from the sender's public key and therandomId, adds the group as aFriendType.Groupcontact, registers all participants, and saves the metadata. It then requests the group's avatar. - Replay Protection: If the recipient has already joined the group, the message's
StreamMessage.timestampis compared against the storedlastReceivedHandshakeMessageTimestamp. If the new message is older, the join is rejected. - Participant Limit: The participant list is hard-limited to 10 entries. Deserialization throws an exception if this limit is exceeded.
- Channel Limit: The channel list is hard-limited to 10 entries, with the same overflow protection.
- Hidden Addresses Mode: When
hideParticipantAddressesis enabled, all group messages are routed exclusively through the group owner. Each participant's real address is replaced with a derived group-scoped address, providing address-level anonymity within the group.