diff --git a/bindings/channels.go b/bindings/channels.go
index fcd8e2d460e599e70d08e78ef39ebbbca744d42e..0fe01321b90ce2e9f0e36f4c77005f43b64db59e 100644
--- a/bindings/channels.go
+++ b/bindings/channels.go
@@ -108,11 +108,11 @@ func (cm *ChannelsManager) GetID() int {
 // via [GetPublicChannelIdentityFromPrivate].
 //
 // Parameters:
-//  - cmixID - The tracked cmix object ID. This can be retrieved using
-//    [Cmix.GetID].
+//   - cmixID - The tracked cmix object ID. This can be retrieved using
+//     [Cmix.GetID].
 //
 // Returns:
-//  - Marshalled bytes of [channel.PrivateIdentity].
+//   - Marshalled bytes of [channel.PrivateIdentity].
 func GenerateChannelIdentity(cmixID int) ([]byte, error) {
 	// Get user from singleton
 	user, err := cmixTrackerSingleton.get(cmixID)
@@ -133,11 +133,11 @@ func GenerateChannelIdentity(cmixID int) ([]byte, error) {
 // and codeset version.
 //
 // Parameters:
-//  - pubKey - The Ed25519 public key.
-//  - codesetVersion - The version of the codeset used to generate the identity.
+//   - pubKey - The Ed25519 public key.
+//   - codesetVersion - The version of the codeset used to generate the identity.
 //
 // Returns:
-//  - JSON of [channel.Identity].
+//   - JSON of [channel.Identity].
 func ConstructIdentity(pubKey []byte, codesetVersion int) ([]byte, error) {
 	identity, err := cryptoChannel.ConstructIdentity(
 		pubKey, uint8(codesetVersion))
@@ -151,11 +151,11 @@ func ConstructIdentity(pubKey []byte, codesetVersion int) ([]byte, error) {
 // data.
 //
 // Parameters:
-//  - password - The password used to encrypt the identity.
-//  - data - The encrypted data.
+//   - password - The password used to encrypt the identity.
+//   - data - The encrypted data.
 //
 // Returns:
-//  - JSON of [channel.PrivateIdentity].
+//   - JSON of [channel.PrivateIdentity].
 func ImportPrivateIdentity(password string, data []byte) ([]byte, error) {
 	pi, err := cryptoChannel.ImportPrivateIdentity(password, data)
 	if err != nil {
@@ -168,10 +168,10 @@ func ImportPrivateIdentity(password string, data []byte) ([]byte, error) {
 // from a bytes version and returns it JSON marshaled.
 //
 // Parameters:
-//  - marshaledPublic - Bytes of the public identity ([channel.Identity]).
+//   - marshaledPublic - Bytes of the public identity ([channel.Identity]).
 //
 // Returns:
-//  - JSON of the constructed [channel.Identity].
+//   - JSON of the constructed [channel.Identity].
 func GetPublicChannelIdentity(marshaledPublic []byte) ([]byte, error) {
 	i, err := cryptoChannel.UnmarshalIdentity(marshaledPublic)
 	if err != nil {
@@ -185,11 +185,11 @@ func GetPublicChannelIdentity(marshaledPublic []byte) ([]byte, error) {
 // ([channel.PrivateIdentity]).
 //
 // Parameters:
-//  - marshaledPrivate - Bytes of the private identity
-//    (channel.PrivateIdentity]).
+//   - marshaledPrivate - Bytes of the private identity
+//     (channel.PrivateIdentity]).
 //
 // Returns:
-//  - JSON of the public [channel.Identity].
+//   - JSON of the public [channel.Identity].
 func GetPublicChannelIdentityFromPrivate(marshaledPrivate []byte) ([]byte, error) {
 	pi, err := cryptoChannel.UnmarshalPrivateIdentity(marshaledPrivate)
 	if err != nil {
@@ -208,12 +208,12 @@ func GetPublicChannelIdentityFromPrivate(marshaledPrivate []byte) ([]byte, error
 // in the storage tag retrieved by [ChannelsManager.GetStorageTag].
 //
 // Parameters:
-//  - cmixID - The tracked Cmix object ID. This can be retrieved using
-//    [Cmix.GetID].
-//  - privateIdentity - Bytes of a private identity ([channel.PrivateIdentity])
-//    that is generated by [GenerateChannelIdentity].
-//  - goEvent - A function that initialises and returns the event model that is
-//    not compatible with GoMobile bindings.
+//   - cmixID - The tracked Cmix object ID. This can be retrieved using
+//     [Cmix.GetID].
+//   - privateIdentity - Bytes of a private identity ([channel.PrivateIdentity])
+//     that is generated by [GenerateChannelIdentity].
+//   - goEvent - A function that initialises and returns the event model that is
+//     not compatible with GoMobile bindings.
 func NewChannelsManagerGoEventModel(cmixID int, privateIdentity []byte,
 	goEventBuilder channels.EventModelBuilder) (*ChannelsManager, error) {
 	pi, err := cryptoChannel.UnmarshalPrivateIdentity(privateIdentity)
@@ -246,11 +246,11 @@ func NewChannelsManagerGoEventModel(cmixID int, privateIdentity []byte,
 // with ChannelsManager.GetStorageTag
 //
 // Parameters:
-//  - cmixID - The tracked cmix object ID. This can be retrieved using
-//    [Cmix.GetID].
-//  - storageTag - retrieved with ChannelsManager.GetStorageTag
-//  - goEvent - A function that initialises and returns the event model that is
-//    not compatible with GoMobile bindings.
+//   - cmixID - The tracked cmix object ID. This can be retrieved using
+//     [Cmix.GetID].
+//   - storageTag - retrieved with ChannelsManager.GetStorageTag
+//   - goEvent - A function that initialises and returns the event model that is
+//     not compatible with GoMobile bindings.
 func LoadChannelsManagerGoEventModel(cmixID int, storageTag string,
 	goEventBuilder channels.EventModelBuilder) (*ChannelsManager, error) {
 
@@ -280,12 +280,12 @@ func LoadChannelsManagerGoEventModel(cmixID int, storageTag string,
 // storage tag retrieved by [ChannelsManager.GetStorageTag].
 //
 // Parameters:
-//  - cmixID - The tracked Cmix object ID. This can be retrieved using
-//    [Cmix.GetID].
-//  - privateIdentity - Bytes of a private identity ([channel.PrivateIdentity])
-//    that is generated by [GenerateChannelIdentity].
-//  - event -  An interface that contains a function that initialises and returns
-//    the event model that is bindings-compatible.
+//   - cmixID - The tracked Cmix object ID. This can be retrieved using
+//     [Cmix.GetID].
+//   - privateIdentity - Bytes of a private identity ([channel.PrivateIdentity])
+//     that is generated by [GenerateChannelIdentity].
+//   - event -  An interface that contains a function that initialises and returns
+//     the event model that is bindings-compatible.
 func NewChannelsManager(cmixID int, privateIdentity []byte,
 	eventBuilder EventModelBuilder) (*ChannelsManager, error) {
 	pi, err := cryptoChannel.UnmarshalPrivateIdentity(privateIdentity)
@@ -322,12 +322,12 @@ func NewChannelsManager(cmixID int, privateIdentity []byte,
 // [ChannelsManager.GetStorageTag].
 //
 // Parameters:
-//  - cmixID - The tracked cmix object ID. This can be retrieved using
-//    [Cmix.GetID].
-//  - storageTag - The storage tag associated with the previously created
-//    channel manager and retrieved with [ChannelsManager.GetStorageTag].
-//  - event - An interface that contains a function that initialises and returns
-//    the event model that is bindings-compatible.
+//   - cmixID - The tracked cmix object ID. This can be retrieved using
+//     [Cmix.GetID].
+//   - storageTag - The storage tag associated with the previously created
+//     channel manager and retrieved with [ChannelsManager.GetStorageTag].
+//   - event - An interface that contains a function that initialises and returns
+//     the event model that is bindings-compatible.
 func LoadChannelsManager(cmixID int, storageTag string,
 	eventBuilder EventModelBuilder) (*ChannelsManager, error) {
 
@@ -357,10 +357,11 @@ func LoadChannelsManager(cmixID int, storageTag string,
 // key for the channel in PEM format.
 //
 // Example JSON:
-//  {
-//    "Channel": "\u003cSpeakeasy-v3:name|description:desc|level:Public|created:1665489600000000000|secrets:zjHmrPPMDQ0tNSANjAmQfKhRpJIdJMU+Hz5hsZ+fVpk=|qozRNkADprqb38lsnU7WxCtGCq9OChlySCEgl4NHjI4=|2|328|7aZQAtuVjE84q4Z09iGytTSXfZj9NyTa6qBp0ueKjCI=\u003e",
-//	  "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMCYCAQACAwDVywIDAQABAgMAlVECAgDvAgIA5QICAJECAgCVAgIA1w==\n-----END RSA PRIVATE KEY-----"
-//  }
+//
+//	 {
+//	   "Channel": "\u003cSpeakeasy-v3:name|description:desc|level:Public|created:1665489600000000000|secrets:zjHmrPPMDQ0tNSANjAmQfKhRpJIdJMU+Hz5hsZ+fVpk=|qozRNkADprqb38lsnU7WxCtGCq9OChlySCEgl4NHjI4=|2|328|7aZQAtuVjE84q4Z09iGytTSXfZj9NyTa6qBp0ueKjCI=\u003e",
+//		  "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMCYCAQACAwDVywIDAQABAgMAlVECAgDvAgIA5QICAJECAgCVAgIA1w==\n-----END RSA PRIVATE KEY-----"
+//	 }
 type ChannelGeneration struct {
 	Channel    string
 	PrivateKey string
@@ -372,33 +373,33 @@ type ChannelGeneration struct {
 // It returns a pretty print of the channel and the private key.
 //
 // Parameters:
-//  - cmixID - The tracked cmix object ID. This can be retrieved using
-//    [Cmix.GetID].
-//  - name - The name of the new channel. The name must be between 3 and 24
-//    characters inclusive. It can only include upper and lowercase unicode
-//    letters, digits 0 through 9, and underscores (_). It cannot be changed
-//    once a channel is created.
-//  - description - The description of a channel. The description is optional
-//    but cannot be longer than 144 characters and can include all unicode
-//    characters. It cannot be changed once a channel is created.
-//  - privacyLevel - The broadcast.PrivacyLevel of the channel. 0 = public,
-//    1 = private, and 2 = secret. Refer to the comment below for more
-//    information.
+//   - cmixID - The tracked cmix object ID. This can be retrieved using
+//     [Cmix.GetID].
+//   - name - The name of the new channel. The name must be between 3 and 24
+//     characters inclusive. It can only include upper and lowercase unicode
+//     letters, digits 0 through 9, and underscores (_). It cannot be changed
+//     once a channel is created.
+//   - description - The description of a channel. The description is optional
+//     but cannot be longer than 144 characters and can include all unicode
+//     characters. It cannot be changed once a channel is created.
+//   - privacyLevel - The broadcast.PrivacyLevel of the channel. 0 = public,
+//     1 = private, and 2 = secret. Refer to the comment below for more
+//     information.
 //
 // Returns:
-//  - []byte - [ChannelGeneration] describes a generated channel. It contains
-//    both the public channel info and the private key for the channel in PEM
-//    format.
+//   - []byte - [ChannelGeneration] describes a generated channel. It contains
+//     both the public channel info and the private key for the channel in PEM
+//     format.
 //
 // The [broadcast.PrivacyLevel] of a channel indicates the level of channel
 // information revealed when sharing it via URL. For any channel besides public
 // channels, the secret information is encrypted and a password is required to
 // share and join a channel.
-//  - A privacy level of [broadcast.Public] reveals all the information
-//    including the name, description, privacy level, public key and salt.
-//  - A privacy level of [broadcast.Private] reveals only the name and
-//    description.
-//  - A privacy level of [broadcast.Secret] reveals nothing.
+//   - A privacy level of [broadcast.Public] reveals all the information
+//     including the name, description, privacy level, public key and salt.
+//   - A privacy level of [broadcast.Private] reveals only the name and
+//     description.
+//   - A privacy level of [broadcast.Secret] reveals nothing.
 func GenerateChannel(cmixID int, name, description string, privacyLevel int) ([]byte, error) {
 	// Get cmix from singleton so its rng can be used
 	cmix, err := cmixTrackerSingleton.get(cmixID)
@@ -449,11 +450,11 @@ func saveChannelPrivateKey(cmix *Cmix, channelID *id.ID, pk rsa.PrivateKey) erro
 // NOTE: This function is unsafe and only for debugging purposes only.
 //
 // Parameters:
-//  - cmixID - ID of [Cmix] object in tracker.
-//  - channelIdBase64 - The [id.ID] of the channel in base 64 encoding.
+//   - cmixID - ID of [Cmix] object in tracker.
+//   - channelIdBase64 - The [id.ID] of the channel in base 64 encoding.
 //
 // Returns:
-//  - The PEM file of the private key.
+//   - The PEM file of the private key.
 func GetSavedChannelPrivateKeyUNSAFE(cmixID int, channelIdBase64 string) (string, error) {
 	cmix, err := cmixTrackerSingleton.get(cmixID)
 	if err != nil {
@@ -498,11 +499,11 @@ func makeChannelPrivateKeyStoreKey(channelID *id.ID) string {
 // of a channel URL, use [GetShareUrlType].
 //
 // Parameters:
-//  - url - The channel's share URL. Should be received from another user or
-//    generated via [GetShareURL].
+//   - url - The channel's share URL. Should be received from another user or
+//     generated via [GetShareURL].
 //
 // Returns:
-//  - The channel pretty print.
+//   - The channel pretty print.
 func DecodePublicURL(url string) (string, error) {
 	c, err := cryptoBroadcast.DecodeShareURL(url, "")
 	if err != nil {
@@ -517,12 +518,12 @@ func DecodePublicURL(url string) (string, error) {
 // URLs. To get the privacy level of a channel URL, use [GetShareUrlType].
 //
 // Parameters:
-//  - url - The channel's share URL. Should be received from another user or
-//    generated via [GetShareURL].
-//  - password - The password needed to decrypt the secret data in the URL.
+//   - url - The channel's share URL. Should be received from another user or
+//     generated via [GetShareURL].
+//   - password - The password needed to decrypt the secret data in the URL.
 //
 // Returns:
-//  - The channel pretty print.
+//   - The channel pretty print.
 func DecodePrivateURL(url, password string) (string, error) {
 	c, err := cryptoBroadcast.DecodeShareURL(url, password)
 	if err != nil {
@@ -535,23 +536,24 @@ func DecodePrivateURL(url, password string) (string, error) {
 // GetChannelJSON returns the JSON of the channel for the given pretty print.
 //
 // Parameters:
-//  - prettyPrint - The pretty print of the channel.
+//   - prettyPrint - The pretty print of the channel.
 //
 // Returns:
-//  - JSON of the [broadcast.Channel] object.
+//   - JSON of the [broadcast.Channel] object.
 //
 // Example JSON of [broadcast.Channel]:
-//  {
-//    "ReceptionID": "Ja/+Jh+1IXZYUOn+IzE3Fw/VqHOscomD0Q35p4Ai//kD",
-//    "Name": "My_Channel",
-//    "Description": "Here is information about my channel.",
-//    "Salt": "+tlrU/htO6rrV3UFDfpQALUiuelFZ+Cw9eZCwqRHk+g=",
-//    "RsaPubKeyHash": "PViT1mYkGBj6AYmE803O2RpA7BX24EjgBdldu3pIm4o=",
-//    "RsaPubKeyLength": 5,
-//    "RSASubPayloads": 1,
-//    "Secret": "JxZt/wPx2luoPdHY6jwbXqNlKnixVU/oa9DgypZOuyI=",
-//    "Level": 0
-//  }
+//
+//	{
+//	  "ReceptionID": "Ja/+Jh+1IXZYUOn+IzE3Fw/VqHOscomD0Q35p4Ai//kD",
+//	  "Name": "My_Channel",
+//	  "Description": "Here is information about my channel.",
+//	  "Salt": "+tlrU/htO6rrV3UFDfpQALUiuelFZ+Cw9eZCwqRHk+g=",
+//	  "RsaPubKeyHash": "PViT1mYkGBj6AYmE803O2RpA7BX24EjgBdldu3pIm4o=",
+//	  "RsaPubKeyLength": 5,
+//	  "RSASubPayloads": 1,
+//	  "Secret": "JxZt/wPx2luoPdHY6jwbXqNlKnixVU/oa9DgypZOuyI=",
+//	  "Level": 0
+//	}
 func GetChannelJSON(prettyPrint string) ([]byte, error) {
 	c, err := cryptoBroadcast.NewChannelFromPrettyPrint(prettyPrint)
 	if err != nil {
@@ -564,11 +566,12 @@ func GetChannelJSON(prettyPrint string) ([]byte, error) {
 // ChannelInfo contains information about a channel.
 //
 // Example of ChannelInfo JSON:
-//  {
-//    "Name": "Test Channel",
-//    "Description": "This is a test channel",
-//    "ChannelID": "RRnpRhmvXtW9ugS1nILJ3WfttdctDvC2jeuH43E0g/0D",
-//  }
+//
+//	{
+//	  "Name": "Test Channel",
+//	  "Description": "This is a test channel",
+//	  "ChannelID": "RRnpRhmvXtW9ugS1nILJ3WfttdctDvC2jeuH43E0g/0D",
+//	}
 type ChannelInfo struct {
 	Name        string
 	Description string
@@ -578,13 +581,14 @@ type ChannelInfo struct {
 // GetChannelInfo returns the info about a channel from its public description.
 //
 // Parameters:
-//  - prettyPrint - The pretty print of the channel.
+//   - prettyPrint - The pretty print of the channel.
 //
 // The pretty print will be of the format:
-//  <Speakeasy-v3:Test_Channel|description:Channel description.|level:Public|created:1666718081766741100|secrets:+oHcqDbJPZaT3xD5NcdLY8OjOMtSQNKdKgLPmr7ugdU=|rCI0wr01dHFStjSFMvsBzFZClvDIrHLL5xbCOPaUOJ0=|493|1|7cBhJxVfQxWo+DypOISRpeWdQBhuQpAZtUbQHjBm8NQ=>
+//
+//	<Speakeasy-v3:Test_Channel|description:Channel description.|level:Public|created:1666718081766741100|secrets:+oHcqDbJPZaT3xD5NcdLY8OjOMtSQNKdKgLPmr7ugdU=|rCI0wr01dHFStjSFMvsBzFZClvDIrHLL5xbCOPaUOJ0=|493|1|7cBhJxVfQxWo+DypOISRpeWdQBhuQpAZtUbQHjBm8NQ=>
 //
 // Returns:
-//  - []byte - JSON of [ChannelInfo], which describes all relevant channel info.
+//   - []byte - JSON of [ChannelInfo], which describes all relevant channel info.
 func GetChannelInfo(prettyPrint string) ([]byte, error) {
 	_, bytes, err := getChannelInfo(prettyPrint)
 	return bytes, err
@@ -611,14 +615,15 @@ func getChannelInfo(prettyPrint string) (*cryptoBroadcast.Channel, []byte, error
 // been joined.
 //
 // Parameters:
-//  - channelPretty - A portable channel string. Should be received from
-//    another user or generated via GenerateChannel.
+//   - channelPretty - A portable channel string. Should be received from
+//     another user or generated via GenerateChannel.
 //
 // The pretty print will be of the format:
-//  <Speakeasy-v3:Test_Channel|description:Channel description.|level:Public|created:1666718081766741100|secrets:+oHcqDbJPZaT3xD5NcdLY8OjOMtSQNKdKgLPmr7ugdU=|rCI0wr01dHFStjSFMvsBzFZClvDIrHLL5xbCOPaUOJ0=|493|1|7cBhJxVfQxWo+DypOISRpeWdQBhuQpAZtUbQHjBm8NQ=>
+//
+//	<Speakeasy-v3:Test_Channel|description:Channel description.|level:Public|created:1666718081766741100|secrets:+oHcqDbJPZaT3xD5NcdLY8OjOMtSQNKdKgLPmr7ugdU=|rCI0wr01dHFStjSFMvsBzFZClvDIrHLL5xbCOPaUOJ0=|493|1|7cBhJxVfQxWo+DypOISRpeWdQBhuQpAZtUbQHjBm8NQ=>
 //
 // Returns:
-//  - []byte - JSON of [ChannelInfo], which describes all relevant channel info.
+//   - []byte - JSON of [ChannelInfo], which describes all relevant channel info.
 func (cm *ChannelsManager) JoinChannel(channelPretty string) ([]byte, error) {
 	c, info, err := getChannelInfo(channelPretty)
 	if err != nil {
@@ -634,13 +639,14 @@ func (cm *ChannelsManager) JoinChannel(channelPretty string) ([]byte, error) {
 // GetChannels returns the IDs of all channels that have been joined.
 //
 // Returns:
-//  - []byte - A JSON marshalled list of IDs.
+//   - []byte - A JSON marshalled list of IDs.
 //
 // JSON Example:
-//  {
-//    "U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVID",
-//    "15tNdkKbYXoMn58NO6VbDMDWFEyIhTWEGsvgcJsHWAgD"
-//  }
+//
+//	{
+//	  "U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVID",
+//	  "15tNdkKbYXoMn58NO6VbDMDWFEyIhTWEGsvgcJsHWAgD"
+//	}
 func (cm *ChannelsManager) GetChannels() ([]byte, error) {
 	channelIds := cm.api.GetChannels()
 	return json.Marshal(channelIds)
@@ -650,7 +656,7 @@ func (cm *ChannelsManager) GetChannels() ([]byte, error) {
 // channel was not previously joined.
 //
 // Parameters:
-//  - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
+//   - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
 func (cm *ChannelsManager) LeaveChannel(marshalledChanId []byte) error {
 	// Unmarshal channel ID
 	channelId, err := id.Unmarshal(marshalledChanId)
@@ -666,7 +672,7 @@ func (cm *ChannelsManager) LeaveChannel(marshalledChanId []byte) error {
 // memory (~3 weeks) over the event model.
 //
 // Parameters:
-//  - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
+//   - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
 func (cm *ChannelsManager) ReplayChannel(marshalledChanId []byte) error {
 
 	// Unmarshal channel ID
@@ -687,22 +693,25 @@ func (cm *ChannelsManager) ReplayChannel(marshalledChanId []byte) error {
 // channel's share URL and password, if it needs one.
 //
 // JSON example for a public channel:
-//  {
-//    "url": "https://internet.speakeasy.tech/?0Name=name&1Description=desc&2Level=Public&3Created=1665489600000000000&e=%2FWNZvuHPuv%2Bx23XbZXVNzCi7y8rUSxkh75MpR9UrsCo%3D&k=ddX1CH52xH%2F%2Fb6lKrbvDghdSmCQr90ktsOAZ%2FrhEonI%3D&l=2&m=0&p=328&s=%2FD%2FoQP2mio3XAWfhmWF0xmZrpj4nAsb9JLXj%2B0Mzq9Y%3D&v=1",
-//    "password": ""
-//  }
+//
+//	{
+//	  "url": "https://internet.speakeasy.tech/?0Name=name&1Description=desc&2Level=Public&3Created=1665489600000000000&e=%2FWNZvuHPuv%2Bx23XbZXVNzCi7y8rUSxkh75MpR9UrsCo%3D&k=ddX1CH52xH%2F%2Fb6lKrbvDghdSmCQr90ktsOAZ%2FrhEonI%3D&l=2&m=0&p=328&s=%2FD%2FoQP2mio3XAWfhmWF0xmZrpj4nAsb9JLXj%2B0Mzq9Y%3D&v=1",
+//	  "password": ""
+//	}
 //
 // JSON example for a private channel:
-//  {
-//    "url": "https://internet.speakeasy.tech/?0Name=name&1Description=desc&3Created=1665489600000000000&d=5AZQirb%2FYrmUITLn%2FFzCaGek1APfJnd2q0KwORGj%2BnbGg26kTShG6cfD3w6c%2BA3RDzxuKDSDN0zS4n1LbjiGe0KYdb8eJVeyRZtld516hfojNDXNAwZq8zbeZy4jjbF627fcLHRNS%2FaII4uJ5UB3gLUeBeZGraaybCCu3FIj1N4RbcJ5cQgT7hBf93bHmJc%3D&m=0&v=1",
-//    "password": "tribune gangrene labrador italics nutmeg process exhume legal"
-//  }
+//
+//	{
+//	  "url": "https://internet.speakeasy.tech/?0Name=name&1Description=desc&3Created=1665489600000000000&d=5AZQirb%2FYrmUITLn%2FFzCaGek1APfJnd2q0KwORGj%2BnbGg26kTShG6cfD3w6c%2BA3RDzxuKDSDN0zS4n1LbjiGe0KYdb8eJVeyRZtld516hfojNDXNAwZq8zbeZy4jjbF627fcLHRNS%2FaII4uJ5UB3gLUeBeZGraaybCCu3FIj1N4RbcJ5cQgT7hBf93bHmJc%3D&m=0&v=1",
+//	  "password": "tribune gangrene labrador italics nutmeg process exhume legal"
+//	}
 //
 // JSON example for a secret channel:
-//  {
-//    "url": "https://internet.speakeasy.tech/?d=w5evLthm%2Fq2j11g6PPtV0QoLaAqNCIER0OqxhxL%2FhpGVJI0057ZPgGBrKoJNE1%2FdoVuU35%2FhohuW%2BWvGlx6IuHoN6mDj0HfNj6Lo%2B8GwIaD6jOEwUcH%2FMKGsKnoqFsMaMPd5gXYgdHvA8l5SRe0gSCVqGKUaG6JgL%2FDu4iyjY7v4ykwZdQ7soWOcBLHDixGEkVLpwsCrPVHkT2K0W6gV74GIrQ%3D%3D&m=0&v=1",
-//    "password": "frenzy contort staple thicket consuming affiliate scion demeanor"
-//  }
+//
+//	{
+//	  "url": "https://internet.speakeasy.tech/?d=w5evLthm%2Fq2j11g6PPtV0QoLaAqNCIER0OqxhxL%2FhpGVJI0057ZPgGBrKoJNE1%2FdoVuU35%2FhohuW%2BWvGlx6IuHoN6mDj0HfNj6Lo%2B8GwIaD6jOEwUcH%2FMKGsKnoqFsMaMPd5gXYgdHvA8l5SRe0gSCVqGKUaG6JgL%2FDu4iyjY7v4ykwZdQ7soWOcBLHDixGEkVLpwsCrPVHkT2K0W6gV74GIrQ%3D%3D&m=0&v=1",
+//	  "password": "frenzy contort staple thicket consuming affiliate scion demeanor"
+//	}
 type ShareURL struct {
 	URL      string `json:"url"`
 	Password string `json:"password"`
@@ -726,14 +735,14 @@ type ShareURL struct {
 // public URLs.
 //
 // Parameters:
-//  - cmixID - The tracked Cmix object ID.
-//  - host - The URL to append the channel info to.
-//  - maxUses - The maximum number of uses the link can be used (0 for
-//    unlimited).
-//  - marshalledChanId - A marshalled channel ID ([id.ID]).
+//   - cmixID - The tracked Cmix object ID.
+//   - host - The URL to append the channel info to.
+//   - maxUses - The maximum number of uses the link can be used (0 for
+//     unlimited).
+//   - marshalledChanId - A marshalled channel ID ([id.ID]).
 //
 // Returns:
-//  - JSON of ShareURL.
+//   - JSON of ShareURL.
 func (cm *ChannelsManager) GetShareURL(cmixID int, host string, maxUses int,
 	marshalledChanId []byte) ([]byte, error) {
 
@@ -775,15 +784,16 @@ func (cm *ChannelsManager) GetShareURL(cmixID int, host string, maxUses int,
 // If the URL is an invalid channel URL, an error is returned.
 //
 // Parameters:
-//  - url - The channel share URL.
+//   - url - The channel share URL.
 //
 // Returns:
-//  - An int that corresponds to the [broadcast.PrivacyLevel] as outlined below.
+//   - An int that corresponds to the [broadcast.PrivacyLevel] as outlined below.
 //
 // Possible returns:
-//  0 = public channel
-//  1 = private channel
-//  2 = secret channel
+//
+//	0 = public channel
+//	1 = private channel
+//	2 = secret channel
 func GetShareUrlType(url string) (int, error) {
 	level, err := cryptoBroadcast.GetShareUrlType(url)
 	return int(level), err
@@ -797,11 +807,12 @@ func GetShareUrlType(url string) (int, error) {
 // ChannelsManager's Send operations.
 //
 // JSON Example:
-//  {
-//    "MessageId": "0kitNxoFdsF4q1VMSI/xPzfCnGB2l+ln2+7CTHjHbJw=",
-//    "Rounds":[1,5,9],
-//    "EphId": 0
-//  }
+//
+//	{
+//	  "MessageId": "0kitNxoFdsF4q1VMSI/xPzfCnGB2l+ln2+7CTHjHbJw=",
+//	  "Rounds":[1,5,9],
+//	  "EphId": 0
+//	}
 type ChannelSendReport struct {
 	MessageId []byte
 	RoundsList
@@ -817,22 +828,22 @@ type ChannelSendReport struct {
 // on the use case.
 //
 // Parameters:
-//  - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
-//  - messageType - The message type of the message. This will be a valid
-//    [channels.MessageType].
-//  - message - The contents of the message. This need not be of data type
-//    string, as the message could be a specified format that the channel may
-//    recognize.
-//  - leaseTimeMS - The lease of the message. This will be how long the message
-//    is valid until, in milliseconds. As per the channels.Manager
-//    documentation, this has different meanings depending on the use case.
-//    These use cases may be generic enough that they will not be enumerated
-//    here.
-//  - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be empty,
-//    and GetDefaultCMixParams will be used internally.
+//   - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
+//   - messageType - The message type of the message. This will be a valid
+//     [channels.MessageType].
+//   - message - The contents of the message. This need not be of data type
+//     string, as the message could be a specified format that the channel may
+//     recognize.
+//   - leaseTimeMS - The lease of the message. This will be how long the message
+//     is valid until, in milliseconds. As per the channels.Manager
+//     documentation, this has different meanings depending on the use case.
+//     These use cases may be generic enough that they will not be enumerated
+//     here.
+//   - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be empty,
+//     and GetDefaultCMixParams will be used internally.
 //
 // Returns:
-//  - []byte - A JSON marshalled ChannelSendReport.
+//   - []byte - A JSON marshalled ChannelSendReport.
 func (cm *ChannelsManager) SendGeneric(marshalledChanId []byte,
 	messageType int, message []byte, leaseTimeMS int64,
 	cmixParamsJSON []byte) ([]byte, error) {
@@ -865,23 +876,23 @@ func (cm *ChannelsManager) SendGeneric(marshalledChanId []byte,
 // message must be at most 510 bytes long.
 //
 // Parameters:
-//  - adminPrivateKey - The PEM-encoded admin RSA private key.
-//  - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
-//  - messageType - The message type of the message. This will be a valid
-//    [channels.MessageType].
-//  - message - The contents of the message. The message should be at most 510
-//    bytes. This need not be of data type string, as the message could be a
-//    specified format that the channel may recognize.
-//  - leaseTimeMS - The lease of the message. This will be how long the message
-//    is valid until, in milliseconds. As per the channels.Manager
-//    documentation, this has different meanings depending on the use case.
-//    These use cases may be generic enough that they will not be enumerated
-//    here.
-//  - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be empty,
-//    and GetDefaultCMixParams will be used internally.
+//   - adminPrivateKey - The PEM-encoded admin RSA private key.
+//   - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
+//   - messageType - The message type of the message. This will be a valid
+//     [channels.MessageType].
+//   - message - The contents of the message. The message should be at most 510
+//     bytes. This need not be of data type string, as the message could be a
+//     specified format that the channel may recognize.
+//   - leaseTimeMS - The lease of the message. This will be how long the message
+//     is valid until, in milliseconds. As per the channels.Manager
+//     documentation, this has different meanings depending on the use case.
+//     These use cases may be generic enough that they will not be enumerated
+//     here.
+//   - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be empty,
+//     and GetDefaultCMixParams will be used internally.
 //
 // Returns:
-//  - []byte - A JSON marshalled ChannelSendReport.
+//   - []byte - A JSON marshalled ChannelSendReport.
 func (cm *ChannelsManager) SendAdminGeneric(adminPrivateKey,
 	marshalledChanId []byte,
 	messageType int, message []byte, leaseTimeMS int64,
@@ -923,20 +934,20 @@ func (cm *ChannelsManager) SendAdminGeneric(adminPrivateKey,
 // lasting forever if [channels.ValidForever] is used.
 //
 // Parameters:
-//  - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
-//  - message - The contents of the message. The message should be at most 510
-//    bytes. This is expected to be Unicode, and thus a string data type is
-//    expected
-//  - leaseTimeMS - The lease of the message. This will be how long the message
-//    is valid until, in milliseconds. As per the channels.Manager
-//    documentation, this has different meanings depending on the use case.
-//    These use cases may be generic enough that they will not be enumerated
-//    here.
-//  - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be
-//    empty, and GetDefaultCMixParams will be used internally.
+//   - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
+//   - message - The contents of the message. The message should be at most 510
+//     bytes. This is expected to be Unicode, and thus a string data type is
+//     expected
+//   - leaseTimeMS - The lease of the message. This will be how long the message
+//     is valid until, in milliseconds. As per the channels.Manager
+//     documentation, this has different meanings depending on the use case.
+//     These use cases may be generic enough that they will not be enumerated
+//     here.
+//   - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be
+//     empty, and GetDefaultCMixParams will be used internally.
 //
 // Returns:
-//  - []byte - A JSON marshalled ChannelSendReport
+//   - []byte - A JSON marshalled ChannelSendReport
 func (cm *ChannelsManager) SendMessage(marshalledChanId []byte,
 	message string, leaseTimeMS int64, cmixParamsJSON []byte) ([]byte, error) {
 
@@ -969,25 +980,25 @@ func (cm *ChannelsManager) SendMessage(marshalledChanId []byte,
 // [channels.ValidForever] is used.
 //
 // Parameters:
-//  - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
-//  - message - The contents of the message. The message should be at most 510
-//    bytes. This is expected to be Unicode, and thus a string data type is
-//    expected.
-//  - messageToReactTo - The marshalled [channel.MessageID] of the message you
-//    wish to reply to. This may be found in the ChannelSendReport if replying
-//    to your own. Alternatively, if reacting to another user's message, you may
-//    retrieve it via the ChannelMessageReceptionCallback registered using
-//    RegisterReceiveHandler.
-//  - leaseTimeMS - The lease of the message. This will be how long the message
-//    is valid until, in milliseconds. As per the channels.Manager
-//    documentation, this has different meanings depending on the use case.
-//    These use cases may be generic enough that they will not be enumerated
-//    here.
-//  - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be empty,
-//    and GetDefaultCMixParams will be used internally.
+//   - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
+//   - message - The contents of the message. The message should be at most 510
+//     bytes. This is expected to be Unicode, and thus a string data type is
+//     expected.
+//   - messageToReactTo - The marshalled [channel.MessageID] of the message you
+//     wish to reply to. This may be found in the ChannelSendReport if replying
+//     to your own. Alternatively, if reacting to another user's message, you may
+//     retrieve it via the ChannelMessageReceptionCallback registered using
+//     RegisterReceiveHandler.
+//   - leaseTimeMS - The lease of the message. This will be how long the message
+//     is valid until, in milliseconds. As per the channels.Manager
+//     documentation, this has different meanings depending on the use case.
+//     These use cases may be generic enough that they will not be enumerated
+//     here.
+//   - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be empty,
+//     and GetDefaultCMixParams will be used internally.
 //
 // Returns:
-//  - []byte - A JSON marshalled ChannelSendReport
+//   - []byte - A JSON marshalled ChannelSendReport
 func (cm *ChannelsManager) SendReply(marshalledChanId []byte,
 	message string, messageToReactTo []byte, leaseTimeMS int64,
 	cmixParamsJSON []byte) ([]byte, error) {
@@ -1020,19 +1031,19 @@ func (cm *ChannelsManager) SendReply(marshalledChanId []byte,
 // Users will drop the reaction if they do not recognize the reactTo message.
 //
 // Parameters:
-//  - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
-//  - reaction - The user's reaction. This should be a single emoji with no
-//    other characters. As such, a Unicode string is expected.
-//  - messageToReactTo - The marshalled [channel.MessageID] of the message you
-//    wish to reply to. This may be found in the ChannelSendReport if replying
-//    to your own. Alternatively, if reacting to another user's message, you may
-//    retrieve it via the ChannelMessageReceptionCallback registered using
-//    RegisterReceiveHandler.
-//  - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be empty,
-//  and GetDefaultCMixParams will be used internally.
+//   - marshalledChanId - A JSON marshalled channel ID ([id.ID]).
+//   - reaction - The user's reaction. This should be a single emoji with no
+//     other characters. As such, a Unicode string is expected.
+//   - messageToReactTo - The marshalled [channel.MessageID] of the message you
+//     wish to reply to. This may be found in the ChannelSendReport if replying
+//     to your own. Alternatively, if reacting to another user's message, you may
+//     retrieve it via the ChannelMessageReceptionCallback registered using
+//     RegisterReceiveHandler.
+//   - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be empty,
+//     and GetDefaultCMixParams will be used internally.
 //
 // Returns:
-//  - []byte - A JSON marshalled ChannelSendReport.
+//   - []byte - A JSON marshalled ChannelSendReport.
 func (cm *ChannelsManager) SendReaction(marshalledChanId []byte,
 	reaction string, messageToReactTo []byte,
 	cmixParamsJSON []byte) ([]byte, error) {
@@ -1166,17 +1177,18 @@ func constructChannelSendReport(channelMessageId cryptoChannel.MessageID,
 // the callback as JSON marshalled bytes.
 //
 // JSON Example:
-//  {
-//    "ChannelId": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
-//    "MessageId": "3S6DiVjWH9mLmjy1oaam/3x45bJQzOW6u2KgeUn59wA=",
-//    "ReplyTo":"cxMyGUFJ+Ff1Xp2X+XkIpOnNAQEZmv8SNP5eYH4tCik=",
-//    "MessageType": 42,
-//    "SenderUsername": "hunter2",
-//    "Content": "YmFuX2JhZFVTZXI=",
-//    "Timestamp": 1662502150335283000,
-//    "Lease": 25,
-//    "Rounds": [ 1, 4, 9],
-//  }
+//
+//	{
+//	  "ChannelId": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+//	  "MessageId": "3S6DiVjWH9mLmjy1oaam/3x45bJQzOW6u2KgeUn59wA=",
+//	  "ReplyTo":"cxMyGUFJ+Ff1Xp2X+XkIpOnNAQEZmv8SNP5eYH4tCik=",
+//	  "MessageType": 42,
+//	  "SenderUsername": "hunter2",
+//	  "Content": "YmFuX2JhZFVTZXI=",
+//	  "Timestamp": 1662502150335283000,
+//	  "Lease": 25,
+//	  "Rounds": [ 1, 4, 9],
+//	}
 type ReceivedChannelMessageReport struct {
 	ChannelId   []byte
 	MessageId   []byte
@@ -1206,10 +1218,10 @@ type ChannelMessageReceptionCallback interface {
 // return an error on any re-registration.
 //
 // Parameters:
-//  - messageType - represents the [channels.MessageType] which will have a
-//    registered listener.
-//  - listenerCb - the callback which will be executed when a channel message
-//    of messageType is received.
+//   - messageType - represents the [channels.MessageType] which will have a
+//     registered listener.
+//   - listenerCb - the callback which will be executed when a channel message
+//     of messageType is received.
 func (cm *ChannelsManager) RegisterReceiveHandler(messageType int,
 	listenerCb ChannelMessageReceptionCallback) error {
 
@@ -1544,12 +1556,12 @@ func GetChannelDbCipherTrackerFromID(id int) (*ChannelDbCipher, error) {
 // NewChannelsDatabaseCipher constructs a ChannelDbCipher object.
 //
 // Parameters:
-//  - cmixID - The tracked [Cmix] object ID.
-//  - password - The password for storage. This should be the same password
-//    passed into [NewCmix].
-//  - plaintTextBlockSize - The maximum size of a payload to be encrypted.
-//    A payload passed into [ChannelDbCipher.Encrypt] that is larger than
-//    plaintTextBlockSize will result in an error.
+//   - cmixID - The tracked [Cmix] object ID.
+//   - password - The password for storage. This should be the same password
+//     passed into [NewCmix].
+//   - plaintTextBlockSize - The maximum size of a payload to be encrypted.
+//     A payload passed into [ChannelDbCipher.Encrypt] that is larger than
+//     plaintTextBlockSize will result in an error.
 func NewChannelsDatabaseCipher(cmixID int, password []byte,
 	plaintTextBlockSize int) (*ChannelDbCipher, error) {
 	// Get user from singleton
@@ -1588,9 +1600,9 @@ func (c *ChannelDbCipher) GetID() int {
 // done on the plaintext so all encrypted data looks uniform at rest.
 //
 // Parameters:
-//  - plaintext - The data to be encrypted. This must be smaller than the block
-//    size passed into [NewChannelsDatabaseCipher]. If it is larger, this will
-//    return an error.
+//   - plaintext - The data to be encrypted. This must be smaller than the block
+//     size passed into [NewChannelsDatabaseCipher]. If it is larger, this will
+//     return an error.
 func (c *ChannelDbCipher) Encrypt(plaintext []byte) ([]byte, error) {
 	return c.api.Encrypt(plaintext)
 }
@@ -1600,7 +1612,22 @@ func (c *ChannelDbCipher) Encrypt(plaintext []byte) ([]byte, error) {
 // this function.
 //
 // Parameters:
-//  - ciphertext - the encrypted data returned by [ChannelDbCipher.Encrypt].
+//   - ciphertext - the encrypted data returned by [ChannelDbCipher.Encrypt].
 func (c *ChannelDbCipher) Decrypt(ciphertext []byte) ([]byte, error) {
 	return c.api.Decrypt(ciphertext)
 }
+
+// MarshalJSON marshals the cipher into valid JSON. This function adheres to the
+// json.Marshaler interface.
+func (c *ChannelDbCipher) MarshalJSON() ([]byte, error) {
+	return c.api.MarshalJSON()
+}
+
+// UnmarshalJSON unmarshalls JSON into the cipher. This function adheres to the
+// json.Unmarshaler interface.
+//
+// Note that this function does not transfer the internal RNG. Use
+// NewCipherFromJSON to properly reconstruct a cipher from JSON.
+func (c *ChannelDbCipher) UnmarshalJSON(data []byte) error {
+	return c.api.UnmarshalJSON(data)
+}
diff --git a/go.mod b/go.mod
index 3826c9fdab530d07bee28869c9e5985b54a758e9..a2c5b32f792b6f14919837361555c576388b1cca 100644
--- a/go.mod
+++ b/go.mod
@@ -15,7 +15,7 @@ require (
 	github.com/stretchr/testify v1.8.0
 	gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f
 	gitlab.com/elixxir/comms v0.0.4-0.20221110181420-84bca6216fe4
-	gitlab.com/elixxir/crypto v0.0.7-0.20221114184755-9fecef9a2093
+	gitlab.com/elixxir/crypto v0.0.7-0.20221202020255-46eeab272a7f
 	gitlab.com/elixxir/ekv v0.2.1
 	gitlab.com/elixxir/primitives v0.0.3-0.20221114231218-cc461261a6af
 	gitlab.com/xx_network/comms v0.0.4-0.20221110181111-4f0694876936
diff --git a/go.sum b/go.sum
index 0e16f4709151412f6d35ba89bc9f949466bd6365..3f5ac5688ba1e0c8fec873c6653447ab0e7ce78a 100644
--- a/go.sum
+++ b/go.sum
@@ -485,8 +485,8 @@ gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f h1:yXGvNBqzZwA
 gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f/go.mod h1:H6jztdm0k+wEV2QGK/KYA+MY9nj9Zzatux/qIvDDv3k=
 gitlab.com/elixxir/comms v0.0.4-0.20221110181420-84bca6216fe4 h1:bLRjVCyMVde4n2hTVgoyyIAWrKI4CevpChchkPeb6A0=
 gitlab.com/elixxir/comms v0.0.4-0.20221110181420-84bca6216fe4/go.mod h1:XhI2/CMng+xcH3mAs+1aPz29PSNu1079XMJ8V+xxihw=
-gitlab.com/elixxir/crypto v0.0.7-0.20221114184755-9fecef9a2093 h1:lSU2+ANGn60XoMqGZ4qagTwHj7fmUaeGIx6Yza6DYvE=
-gitlab.com/elixxir/crypto v0.0.7-0.20221114184755-9fecef9a2093/go.mod h1:oRh3AwveOEvpk9E3kRcMGK8fImcEnN0PY4jr9HDgQE8=
+gitlab.com/elixxir/crypto v0.0.7-0.20221202020255-46eeab272a7f h1:e7h3InxgzRnYOqgUgHrTfK6CW8qNM2SiYRj9tOvsFjA=
+gitlab.com/elixxir/crypto v0.0.7-0.20221202020255-46eeab272a7f/go.mod h1:oRh3AwveOEvpk9E3kRcMGK8fImcEnN0PY4jr9HDgQE8=
 gitlab.com/elixxir/ekv v0.2.1 h1:dtwbt6KmAXG2Tik5d60iDz2fLhoFBgWwST03p7T+9Is=
 gitlab.com/elixxir/ekv v0.2.1/go.mod h1:USLD7xeDnuZEavygdrgzNEwZXeLQJK/w1a+htpN+JEU=
 gitlab.com/elixxir/primitives v0.0.3-0.20221114231218-cc461261a6af h1:xcPqknK1ehNb9xwcutTdoR0YgD7DC/ySh9z49tIpSxQ=