mirror of
https://github.com/status-im/status-console-client.git
synced 2025-02-24 16:48:09 +00:00
128 lines
2.8 KiB
Go
128 lines
2.8 KiB
Go
package client
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
)
|
|
|
|
//go:generate stringer -type=ContactType
|
|
|
|
// ContactType defines a type of a contact.
|
|
type ContactType int
|
|
|
|
// ContactState defines state of the contact.
|
|
type ContactState int
|
|
|
|
func (c ContactType) MarshalJSON() ([]byte, error) {
|
|
return []byte(fmt.Sprintf(`"%s"`, c)), nil
|
|
}
|
|
|
|
func (c *ContactType) UnmarshalJSON(data []byte) error {
|
|
switch string(data) {
|
|
case fmt.Sprintf(`"%s"`, ContactPublicRoom):
|
|
*c = ContactPublicRoom
|
|
case fmt.Sprintf(`"%s"`, ContactPublicKey):
|
|
*c = ContactPublicKey
|
|
default:
|
|
return fmt.Errorf("invalid ContactType: %s", data)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Types of contacts.
|
|
const (
|
|
ContactPublicRoom ContactType = iota + 1
|
|
ContactPublicKey
|
|
|
|
// ContactAdded default level. Added or confirmed by user.
|
|
ContactAdded ContactState = iota
|
|
// ContactNew contact got connected to us and waits for being added or blocked.
|
|
ContactNew
|
|
// Messages of the blocked contact must be discarded (or atleast not visible to the user)
|
|
ContactBlocked
|
|
)
|
|
|
|
// Contact is a single contact which has a type and name.
|
|
type Contact struct {
|
|
Name string `json:"name"`
|
|
Type ContactType `json:"type"`
|
|
State ContactState `json:"state"`
|
|
Topic string `json:"topic"`
|
|
PublicKey *ecdsa.PublicKey `json:"-"`
|
|
}
|
|
|
|
// String returns a string representation of Contact.
|
|
func (c Contact) String() string {
|
|
return c.Name
|
|
}
|
|
|
|
// Equal returns true if contacts have same name and same type.
|
|
func (c Contact) Equal(other Contact) bool {
|
|
return c.Name == other.Name && c.Type == other.Type
|
|
}
|
|
|
|
func (c Contact) MarshalJSON() ([]byte, error) {
|
|
type ContactAlias Contact
|
|
|
|
item := struct {
|
|
ContactAlias
|
|
PublicKey string `json:"public_key,omitempty"`
|
|
}{
|
|
ContactAlias: ContactAlias(c),
|
|
}
|
|
|
|
if c.PublicKey != nil {
|
|
item.PublicKey = hexutil.Encode(crypto.FromECDSAPub(c.PublicKey))
|
|
}
|
|
|
|
return json.Marshal(&item)
|
|
}
|
|
|
|
func (c *Contact) UnmarshalJSON(data []byte) error {
|
|
type ContactAlias Contact
|
|
|
|
var item struct {
|
|
*ContactAlias
|
|
PublicKey string `json:"public_key,omitempty"`
|
|
}
|
|
|
|
if err := json.Unmarshal(data, &item); err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(item.PublicKey) > 2 {
|
|
pubKey, err := hexutil.Decode(item.PublicKey)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
item.ContactAlias.PublicKey, err = crypto.UnmarshalPubkey(pubKey)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
*c = *(*Contact)(item.ContactAlias)
|
|
|
|
return nil
|
|
}
|
|
|
|
// ContactWithPublicKey creates a new private contact.
|
|
func ContactWithPublicKey(name, pubKeyHex string) (c Contact, err error) {
|
|
c.Name = name
|
|
c.Type = ContactPublicKey
|
|
c.Topic = DefaultPrivateTopic()
|
|
pubKeyBytes, err := hexutil.Decode(pubKeyHex)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
c.PublicKey, err = crypto.UnmarshalPubkey(pubKeyBytes)
|
|
return
|
|
}
|