Skip to content

Commit

Permalink
Add Commands
Browse files Browse the repository at this point in the history
This commit adds handling of Transaction commands.
  • Loading branch information
cammellos committed Dec 13, 2019
1 parent 52dd835 commit d34166d
Show file tree
Hide file tree
Showing 51 changed files with 4,424 additions and 1,750 deletions.
27 changes: 27 additions & 0 deletions protocol/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,33 @@ func stringSliceToPublicKeys(slice []string, prefixed bool) ([]*ecdsa.PublicKey,
return result, nil
}

// NextClockAndTimestamp returns the next clock value
// and the current timestamp
func (c *Chat) NextClockAndTimestamp() (uint64, uint64) {
clock := c.LastClockValue
timestamp := timestampInMs()
if clock == 0 || clock < timestamp {
clock = timestamp
} else {
clock = clock + 1
}
return clock, timestamp
}

func (c *Chat) UpdateFromMessage(message *Message) error {
c.Timestamp = int64(timestampInMs())
if c.LastClockValue <= message.Clock {
jsonMessage, err := json.Marshal(message)
if err != nil {
return err
}

c.LastClockValue = message.Clock
c.LastMessage = jsonMessage
}
return nil
}

func stringSliceContains(slice []string, item string) bool {
for _, s := range slice {
if s == item {
Expand Down
142 changes: 94 additions & 48 deletions protocol/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,42 @@ type QuotedMessage struct {
Text string `json:"text"`
}

type CommandState int

const (
CommandStateRequestAddressForTransaction CommandState = iota + 1
CommandStateRequestAddressForTransactionDeclined
CommandStateRequestAddressForTransactionAccepted
CommandStateRequestTransaction
CommandStateRequestTransactionDeclined
CommandStateTransactionPending
CommandStateTransactionSent
)

type CommandParameters struct {
// ID is the ID of the initial message
ID string `json:"id"`
// Address is the address sent with the command
Address string `json:"address"`
// Contract is the contract address for ERC20 tokens
Contract string `json:"contract"`
// Value is the value as a string sent
Value string `json:"value"`
// TransactionHash is the hash of the transaction
TransactionHash string `json:"transactionHash"`
// CommandState is the state of the command
CommandState CommandState
// The parameters for token transactions
ERC20Parameters []string `json:"erc20Parameters"`
}

const (
OutgoingStatusSending = "sending"
OutgoingStatusSent = "sent"
)

// Message represents a message record in the database,
// more specifically in user_messages_legacy table.
// more specifically in user_messages table.
type Message struct {
protobuf.ChatMessage

Expand All @@ -41,70 +70,87 @@ type Message struct {
// The chat id to be stored locally
LocalChatID string `json:"localChatId"`

RetryCount int `json:"retryCount"`
Seen bool `json:"seen"`
OutgoingStatus string `json:"outgoingStatus,omitempty"`

QuotedMessage *QuotedMessage `json:"quotedMessage"`

// CommandParameters is the parameters sent with the message
CommandParameters *CommandParameters `json:"commandParameters"`

// Computed fields
RTL bool `json:"rtl"`
ParsedText []byte `json:"parsedText"`
LineCount int `json:"lineCount"`

// Replace indicates that this is a replacement of a message
// that has been updated
Replace string `json:"replace"`
SigPubKey *ecdsa.PublicKey `json:"-"`
// RawPayload is the marshaled payload, used for resending the message
RawPayload []byte `json:"-"`
}

// RawMessage represent a sent or received message, kept for being able
// to re-send/propagate
type RawMessage struct {
ID string
LocalChatID string
LastSent uint64
SendCount int
Sent bool
ResendAutomatically bool
MessageType protobuf.ApplicationMetadataMessage_Type
Payload []byte
Recipients []*ecdsa.PublicKey
}

func (m *Message) MarshalJSON() ([]byte, error) {
type MessageAlias Message
item := struct {
ID string `json:"id"`
WhisperTimestamp uint64 `json:"whisperTimestamp"`
From string `json:"from"`
Alias string `json:"alias"`
Identicon string `json:"identicon"`
RetryCount int `json:"retryCount"`
Seen bool `json:"seen"`
OutgoingStatus string `json:"outgoingStatus,omitempty"`
QuotedMessage *QuotedMessage `json:"quotedMessage"`
RTL bool `json:"rtl"`
ParsedText json.RawMessage `json:"parsedText"`
LineCount int `json:"lineCount"`
Text string `json:"text"`
ChatId string `json:"chatId"`
LocalChatID string `json:"localChatId"`
Clock uint64 `json:"clock"`
ResponseTo string `json:"responseTo"`
EnsName string `json:"ensName"`
Sticker *protobuf.StickerMessage `json:"sticker"`
Timestamp uint64 `json:"timestamp"`
ContentType protobuf.ChatMessage_ContentType `json:"contentType"`
MessageType protobuf.ChatMessage_MessageType `json:"messageType"`
ID string `json:"id"`
WhisperTimestamp uint64 `json:"whisperTimestamp"`
From string `json:"from"`
Alias string `json:"alias"`
Identicon string `json:"identicon"`
Seen bool `json:"seen"`
OutgoingStatus string `json:"outgoingStatus,omitempty"`
QuotedMessage *QuotedMessage `json:"quotedMessage"`
RTL bool `json:"rtl"`
ParsedText json.RawMessage `json:"parsedText"`
LineCount int `json:"lineCount"`
Text string `json:"text"`
ChatId string `json:"chatId"`
LocalChatID string `json:"localChatId"`
Clock uint64 `json:"clock"`
ResponseTo string `json:"responseTo"`
EnsName string `json:"ensName"`
Sticker *protobuf.StickerMessage `json:"sticker"`
CommandParameters *CommandParameters `json:"commandParameters"`
Timestamp uint64 `json:"timestamp"`
ContentType protobuf.ChatMessage_ContentType `json:"contentType"`
MessageType protobuf.ChatMessage_MessageType `json:"messageType"`
}{
ID: m.ID,
WhisperTimestamp: m.WhisperTimestamp,
From: m.From,
Alias: m.Alias,
Identicon: m.Identicon,
RetryCount: m.RetryCount,
Seen: m.Seen,
OutgoingStatus: m.OutgoingStatus,
QuotedMessage: m.QuotedMessage,
RTL: m.RTL,
ParsedText: m.ParsedText,
LineCount: m.LineCount,
Text: m.Text,
ChatId: m.ChatId,
LocalChatID: m.LocalChatID,
Clock: m.Clock,
ResponseTo: m.ResponseTo,
EnsName: m.EnsName,
Timestamp: m.Timestamp,
ContentType: m.ContentType,
MessageType: m.MessageType,
Sticker: m.GetSticker(),
ID: m.ID,
WhisperTimestamp: m.WhisperTimestamp,
From: m.From,
Alias: m.Alias,
Identicon: m.Identicon,
Seen: m.Seen,
OutgoingStatus: m.OutgoingStatus,
QuotedMessage: m.QuotedMessage,
RTL: m.RTL,
ParsedText: m.ParsedText,
LineCount: m.LineCount,
Text: m.Text,
ChatId: m.ChatId,
LocalChatID: m.LocalChatID,
Clock: m.Clock,
ResponseTo: m.ResponseTo,
EnsName: m.EnsName,
Timestamp: m.Timestamp,
ContentType: m.ContentType,
MessageType: m.MessageType,
Sticker: m.GetSticker(),
CommandParameters: m.CommandParameters,
}

return json.Marshal(item)
Expand Down
39 changes: 39 additions & 0 deletions protocol/message_builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package protocol

import (
"crypto/ecdsa"

"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol/identity/alias"
"github.com/status-im/status-go/protocol/identity/identicon"
)

func buildBasicMessage(message *Message, chat *Chat, key *ecdsa.PublicKey) error {
clock, timestamp := chat.NextClockAndTimestamp()

message.LocalChatID = chat.ID
message.Clock = clock
message.Timestamp = timestamp
message.From = types.EncodeHex(crypto.FromECDSAPub(key))
message.SigPubKey = key
message.WhisperTimestamp = timestamp
message.Seen = true
message.OutgoingStatus = OutgoingStatusSending

identicon, err := identicon.GenerateBase64(message.From)
if err != nil {
return err
}

message.Identicon = identicon

alias, err := alias.GenerateFromPublicKeyString(message.From)
if err != nil {
return err
}

message.Alias = alias
return nil

}
Loading

0 comments on commit d34166d

Please sign in to comment.