Add spiff workflow cmd

This commit is contained in:
Andrea Maria Piana 2022-10-14 09:50:36 +01:00
parent d1ec6d876c
commit 5d0e08ec7b
27 changed files with 1456 additions and 58 deletions

View File

@ -876,6 +876,11 @@ func (b *GethStatusBackend) loadNodeConfig(inputNodeCfg *params.NodeConfig) erro
} }
if inputNodeCfg != nil { if inputNodeCfg != nil {
// If an installationID is provided, we override it
if conf != nil && conf.ShhextConfig.InstallationID != "" {
inputNodeCfg.ShhextConfig.InstallationID = conf.ShhextConfig.InstallationID
}
conf, err = b.OverwriteNodeConfigValues(conf, inputNodeCfg) conf, err = b.OverwriteNodeConfigValues(conf, inputNodeCfg)
if err != nil { if err != nil {
return err return err

View File

@ -78,6 +78,20 @@ func SerializeLegacyKey(key string) (string, error) {
return SerializePublicKey(keyWithPrefix, "z") return SerializePublicKey(keyWithPrefix, "z")
} }
// DeserializeCompressedKey converts a base58 compressed key to
// a secp251k1 uncompressed key
func DeserializeCompressedKey(key string) (string, error) {
if len(key) == 0 {
return "", errors.New("invalid key length")
}
deserialisedKey, err := DeserializePublicKey(key, "f")
if err != nil {
return "", err
}
return "0x" + deserialisedKey[5:], nil
}
// getPublicKeyType wrapper for the `varint.FromUvarint()` func // getPublicKeyType wrapper for the `varint.FromUvarint()` func
func getPublicKeyType(key []byte) (uint64, int, error) { func getPublicKeyType(key []byte) (uint64, int, error) {
return varint.FromUvarint(key) return varint.FromUvarint(key)

View File

@ -165,7 +165,7 @@ func main() {
} }
keyString := common.PubkeyToHex(&key.PublicKey) keyString := common.PubkeyToHex(&key.PublicKey)
_, err = wakuext.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(keyString)}) _, err = wakuext.AddContact(context.Background(), &requests.AddContact{ID: keyString})
if err != nil { if err != nil {
logger.Error("failed Add contact", "err", err) logger.Error("failed Add contact", "err", err)
return return
@ -185,7 +185,7 @@ func main() {
return return
} }
_, err = wakuext.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contact.ID)}) _, err = wakuext.AddContact(context.Background(), &requests.AddContact{ID: contact.ID})
if err != nil { if err != nil {
return return
} }

3
cmd/spiff-workflow/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
spiff-workflow
run.sh
tmp/

View File

@ -0,0 +1,86 @@
### How to build
You must have go installed.
Then you can run, from `cmd/spiff-workflow`
```
go build --mod=vendor
```
which should create a `spiff-workflow` executable
### How to run
```
./spiff-workflow --seed-phrase "your seed phrase"
```
The parameters are:
`seed-phrase`: the seed phrase of the account to be created
The db will be created in the `./tmp` directory, and it will erase any previous data
The server will be listening on `localhost:8545` and it will respond to RPC calls.
### Sending a message
First add the user as a contact (if you have a message):
```
curl -XPOST http://localhost:8545 -H 'Content-type: application/json' -d '{"jsonrpc":"2.0","method":"wakuext_sendContactRequest","params":[{"id": "0x04d3c86dfc77b195b705e1831935066076018aa0d7c40044829801ebbfe9b06480ce4662072bf16a3ca7cb8f6289207614deceaf7d33e099dfc9281610375fec08", "message": "hello"}],"id":1}'
```
If you don't want to send a message:
```
curl -XPOST http://localhost:8545 -H 'Content-type: application/json' -d '{"jsonrpc":"2.0","method":"wakuext_addContact","params":[{"id": "0x04d3c86dfc77b195b705e1831935066076018aa0d7c40044829801ebbfe9b06480ce4662072bf16a3ca7cb8f6289207614deceaf7d33e099dfc9281610375fec08"}],"id":1}'
```
Accept the contact request in the receiving device (you should see a notification in the activity center)
```
curl -XPOST http://localhost:8545 -H 'Content-type: application/json' -d '{"jsonrpc":"2.0","method":"wakuext_sendOneToOneMessage","params":[{"id": "0x04e431a0baaac2602052f259d4304371d0e0d86cb024497899cf3e82211ff17a9723d8ca67b6575a700086b2aa6ab0df4dab1f8e94114912f269fc6b1ee6764a58", "message": "hello"}],"id":1}'
```
Just replace `id` with the public key you want to use, and `message` with the text you want to send.
### Creating a private group chat
To create a private group chat, you need interactions on both devices.
First add the user as a contact:
```
curl -XPOST http://localhost:8545 -H 'Content-type: application/json' -d '{"jsonrpc":"2.0","method":"wakuext_sendContactRequest","params":[{"id": "0x04d3c86dfc77b195b705e1831935066076018aa0d7c40044829801ebbfe9b06480ce4662072bf16a3ca7cb8f6289207614deceaf7d33e099dfc9281610375fec08", "message": "hello"}],"id":1}'
```
Accept the contact request in the receiving device (you should see a notification in the activity center)
Then create a group chat with the member(s):
```
curl -XPOST http://localhost:8545 -H 'Content-type: application/json' -d '{"jsonrpc":"2.0","method":"wakuext_createGroupChatWithMembers","params":[null, "group-chat-name", ["0x04d3c86dfc77b195b705e1831935066076018aa0d7c40044829801ebbfe9b06480ce4662072bf16a3ca7cb8f6289207614deceaf7d33e099dfc9281610375fec08"]],"id":1}'
```
You will need to note the ID returned by the response, for example, in the response:
```
{"jsonrpc":"2.0","id":1,"result":{"chats":[{"id":"8291eae1-338c-4481-9997-04edd2d2bbed-0x0490cbce029eaf094c7f2dcf1feb2d60e91ab1498847eb29fa98cc5ea5a36666b3f9ada142f3080f5074abd942c863438f6af9475f30781790c7e36f9acd2ac93e","name":"group-chat-name",
```
The ID is:
```
"8291eae1-338c-4481-9997-04edd2d2bbed-0x0490cbce029eaf094c7f2dcf1feb2d60e91ab1498847eb29fa98cc5ea5a36666b3f9ada142f3080f5074abd942c863438f6af9475f30781790c7e36f9acd2ac93e"
```
You can then send messages to this group chat similarly as you send messages for 1-to-1 chats, using the id of the newly created chat:
```
curl -XPOST http://localhost:8545 -H 'Content-type: application/json' -d '{"jsonrpc":"2.0","method":"wakuext_sendGroupChatMessage","params":[{"id": "8291eae1-338c-4481-9997-04edd2d2bbed-0x0490cbce029eaf094c7f2dcf1feb2d60e91ab1498847eb29fa98cc5ea5a36666b3f9ada142f3080f5074abd942c863438f6af9475f30781790c7e36f9acd2ac93e", "message": "hello"}],"id":1}'
```
Mind that if you restart the node, you will need to create a new group chat, since we are currently not keeping storage on restart.

View File

@ -0,0 +1,37 @@
package main
import (
"fmt"
"os"
"path"
"strings"
)
// configFlags represents an array of JSON configuration files passed to a command line utility
type configFlags []string
func (f *configFlags) String() string {
return strings.Join(*f, ", ")
}
func (f *configFlags) Set(value string) error {
if !path.IsAbs(value) {
// Convert to absolute path
cwd, err := os.Getwd()
if err != nil {
return err
}
value = path.Join(cwd, value)
}
// Check that the file exists
stat, err := os.Stat(value)
if err != nil {
return err
}
if stat.IsDir() {
return fmt.Errorf("path does not represent a file: %s", value)
}
*f = append(*f, value)
return nil
}

407
cmd/spiff-workflow/main.go Normal file
View File

@ -0,0 +1,407 @@
package main
import (
"encoding/json"
"flag"
"fmt"
stdlog "log"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/google/uuid"
"golang.org/x/crypto/ssh/terminal"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/account/generator"
"github.com/status-im/status-go/api"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/logutils"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol"
"github.com/status-im/status-go/protocol/identity/alias"
waku2extn "github.com/status-im/status-go/services/wakuv2ext"
"github.com/status-im/status-go/sqlite"
)
const (
serverClientName = "Statusd"
)
var (
configFiles configFlags
logLevel = flag.String("log", "INFO", `Log level, one of: "ERROR", "WARN", "INFO", "DEBUG", and "TRACE"`)
logWithoutColors = flag.Bool("log-without-color", false, "Disables log colors")
seedPhrase = flag.String("seed-phrase", "", "Seed phrase")
version = flag.Bool("version", false, "Print version and dump configuration")
dataDir = flag.String("dir", getDefaultDataDir(), "Directory used by node to store data")
networkID = flag.Int(
"network-id",
params.GoerliNetworkID,
fmt.Sprintf(
"A network ID: %d (Mainnet), %d (Goerli)",
params.MainNetworkID, params.GoerliNetworkID,
),
)
listenAddr = flag.String("addr", "", "address to bind listener to")
)
// All general log messages in this package should be routed through this logger.
var logger = log.New("package", "status-go/cmd/statusd")
func init() {
flag.Var(&configFiles, "c", "JSON configuration file(s). Multiple configuration files can be specified, and will be merged in occurrence order")
}
// nolint:gocyclo
func main() {
colors := terminal.IsTerminal(int(os.Stdin.Fd()))
if err := logutils.OverrideRootLog(true, "ERROR", logutils.FileOptions{}, colors); err != nil {
stdlog.Fatalf("Error initializing logger: %v", err)
}
flag.Usage = printUsage
flag.Parse()
if flag.NArg() > 0 {
printUsage()
logger.Error("Extra args in command line: %v", flag.Args())
os.Exit(1)
}
opts := []params.Option{}
config, err := params.NewNodeConfigWithDefaultsAndFiles(
*dataDir,
uint64(*networkID),
opts,
configFiles,
)
if err != nil {
printUsage()
logger.Error(err.Error())
os.Exit(1)
}
// Use listenAddr if and only if explicitly provided in the arguments.
// The default value is set in params.NewNodeConfigWithDefaultsAndFiles().
if *listenAddr != "" {
config.ListenAddr = *listenAddr
}
if *logLevel != "" {
config.LogLevel = *logLevel
}
// set up logging options
setupLogging(config)
// We want statusd to be distinct from StatusIM client.
config.Name = serverClientName
if *version {
printVersion(config)
return
}
backend := api.NewGethStatusBackend()
err = ImportAccount(*seedPhrase, backend)
if err != nil {
logger.Error("failed import account", "err", err)
return
}
wakuextservice := backend.StatusNode().WakuV2ExtService()
if wakuextservice == nil {
logger.Error("wakuext not available")
return
}
wakuext := waku2extn.NewPublicAPI(wakuextservice)
// This will start the push notification server as well as
// the config is set to Enabled
_, err = wakuext.StartMessenger()
if err != nil {
logger.Error("failed to start messenger", "error", err)
return
}
retrieveMessagesLoop(wakuext.Messenger(), 300*time.Millisecond)
}
func getDefaultDataDir() string {
if home := os.Getenv("HOME"); home != "" {
return filepath.Join(home, ".statusd")
}
return "./statusd-data"
}
func setupLogging(config *params.NodeConfig) {
logSettings := logutils.LogSettings{
Enabled: config.LogEnabled,
MobileSystem: config.LogMobileSystem,
Level: config.LogLevel,
File: config.LogFile,
MaxSize: config.LogMaxSize,
MaxBackups: config.LogMaxBackups,
CompressRotated: config.LogCompressRotated,
}
colors := !(*logWithoutColors) && terminal.IsTerminal(int(os.Stdin.Fd()))
if err := logutils.OverrideRootLogWithConfig(logSettings, colors); err != nil {
stdlog.Fatalf("Error initializing logger: %v", err)
}
}
// printVersion prints verbose output about version and config.
func printVersion(config *params.NodeConfig) {
fmt.Println(strings.Title(config.Name))
fmt.Println("Version:", config.Version)
fmt.Println("Network ID:", config.NetworkID)
fmt.Println("Go Version:", runtime.Version())
fmt.Println("OS:", runtime.GOOS)
fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH"))
fmt.Printf("GOROOT=%s\n", runtime.GOROOT())
fmt.Println("Loaded Config: ", config)
}
func printUsage() {
usage := `
Usage: statusd [options]
Examples:
statusd # run regular Whisper node that joins Status network
statusd -c ./default.json # run node with configuration specified in ./default.json file
statusd -c ./default.json -c ./standalone.json # run node with configuration specified in ./default.json file, after merging ./standalone.json file
statusd -c ./default.json -metrics # run node with configuration specified in ./default.json file, and expose ethereum metrics with debug_metrics jsonrpc call
Options:
`
fmt.Fprint(os.Stderr, usage)
flag.PrintDefaults()
}
const pathWalletRoot = "m/44'/60'/0'/0"
const pathEIP1581 = "m/43'/60'/1581'"
const pathDefaultChat = pathEIP1581 + "/0'/0"
const pathDefaultWallet = pathWalletRoot + "/0"
var paths = []string{pathWalletRoot, pathEIP1581, pathDefaultChat, pathDefaultWallet}
func defaultSettings(generatedAccountInfo generator.GeneratedAccountInfo, derivedAddresses map[string]generator.AccountInfo, mnemonic *string) (*settings.Settings, error) {
chatKeyString := derivedAddresses[pathDefaultChat].PublicKey
settings := &settings.Settings{}
settings.KeyUID = generatedAccountInfo.KeyUID
settings.Address = types.HexToAddress(generatedAccountInfo.Address)
settings.WalletRootAddress = types.HexToAddress(derivedAddresses[pathWalletRoot].Address)
// Set chat key & name
name, err := alias.GenerateFromPublicKeyString(chatKeyString)
if err != nil {
return nil, err
}
settings.Name = name
settings.PublicKey = chatKeyString
settings.DappsAddress = types.HexToAddress(derivedAddresses[pathDefaultWallet].Address)
settings.EIP1581Address = types.HexToAddress(derivedAddresses[pathEIP1581].Address)
settings.Mnemonic = mnemonic
signingPhrase, err := buildSigningPhrase()
if err != nil {
return nil, err
}
settings.SigningPhrase = signingPhrase
settings.SendPushNotifications = true
settings.InstallationID = uuid.New().String()
settings.UseMailservers = true
settings.PreviewPrivacy = true
settings.Currency = "usd"
settings.ProfilePicturesVisibility = 1
settings.LinkPreviewRequestEnabled = true
visibleTokens := make(map[string][]string)
visibleTokens["mainnet"] = []string{"SNT"}
visibleTokensJSON, err := json.Marshal(visibleTokens)
if err != nil {
return nil, err
}
visibleTokenJSONRaw := json.RawMessage(visibleTokensJSON)
settings.WalletVisibleTokens = &visibleTokenJSONRaw
// TODO: fix this
networks := make([]map[string]string, 0)
networksJSON, err := json.Marshal(networks)
if err != nil {
return nil, err
}
networkRawMessage := json.RawMessage(networksJSON)
settings.Networks = &networkRawMessage
settings.CurrentNetwork = "mainnet_rpc"
return settings, nil
}
func defaultNodeConfig(installationID string) (*params.NodeConfig, error) {
// Set mainnet
nodeConfig := &params.NodeConfig{}
nodeConfig.NetworkID = 1
nodeConfig.LogLevel = "DEBUG"
nodeConfig.DataDir = "/ethereum/mainnet_rpc"
nodeConfig.HTTPEnabled = true
nodeConfig.HTTPPort = 8545
// FIXME: This should be taken from CLI flags.
nodeConfig.HTTPHost = "0.0.0.0"
// FIXME: This should be taken from CLI flags.
nodeConfig.HTTPVirtualHosts = []string{"localhost", "wakunode"}
nodeConfig.APIModules = "wakuext,ext,waku"
nodeConfig.UpstreamConfig = params.UpstreamRPCConfig{
Enabled: true,
URL: "https://mainnet.infura.io/v3/800c641949d64d768a5070a1b0511938",
}
nodeConfig.Name = "StatusIM"
nodeConfig.Rendezvous = false
clusterConfig, err := params.LoadClusterConfigFromFleet("eth.prod")
if err != nil {
return nil, err
}
nodeConfig.ClusterConfig = *clusterConfig
nodeConfig.WalletConfig = params.WalletConfig{Enabled: true}
nodeConfig.LocalNotificationsConfig = params.LocalNotificationsConfig{Enabled: true}
nodeConfig.BrowsersConfig = params.BrowsersConfig{Enabled: true}
nodeConfig.PermissionsConfig = params.PermissionsConfig{Enabled: true}
nodeConfig.MailserversConfig = params.MailserversConfig{Enabled: true}
nodes := []string{"enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@prod.nodes.status.im"}
nodeConfig.ClusterConfig.WakuNodes = nodes
nodeConfig.ClusterConfig.DiscV5BootstrapNodes = nodes
nodeConfig.EnableNTPSync = true
nodeConfig.WakuV2Config = params.WakuV2Config{
Enabled: true,
EnableDiscV5: true,
DiscoveryLimit: 20,
UDPPort: 9002,
}
nodeConfig.ShhextConfig = params.ShhextConfig{
BackupDisabledDataDir: "",
InstallationID: installationID,
MaxMessageDeliveryAttempts: 6,
MailServerConfirmations: true,
VerifyTransactionURL: "",
VerifyENSURL: "",
VerifyENSContractAddress: "",
VerifyTransactionChainID: 1,
DataSyncEnabled: true,
PFSEnabled: true,
}
// TODO: check topics
return nodeConfig, nil
}
func ImportAccount(seedPhrase string, backend *api.GethStatusBackend) error {
backend.UpdateRootDataDir("./tmp")
manager := backend.AccountManager()
if err := manager.InitKeystore("./tmp"); err != nil {
return err
}
err := backend.OpenAccounts()
if err != nil {
logger.Error("failed open accounts", err)
return err
}
generator := manager.AccountsGenerator()
generatedAccountInfo, err := generator.ImportMnemonic(seedPhrase, "")
if err != nil {
logger.Error("failed import mnemonic", err)
return err
}
derivedAddresses, err := generator.DeriveAddresses(generatedAccountInfo.ID, paths)
if err != nil {
logger.Error("failed derive", err)
return err
}
var exist bool
_, err = generator.StoreDerivedAccounts(generatedAccountInfo.ID, "", paths)
if err != nil && err.Error() == "account already exists" {
exist = true
} else if err != nil {
logger.Error("failed store derive", err)
return err
}
account := multiaccounts.Account{
KeyUID: generatedAccountInfo.KeyUID,
KDFIterations: sqlite.ReducedKDFIterationsNumber,
}
settings, err := defaultSettings(generatedAccountInfo, derivedAddresses, &seedPhrase)
if err != nil {
return err
}
nodeConfig, err := defaultNodeConfig(settings.InstallationID)
if err != nil {
return err
}
walletDerivedAccount := derivedAddresses[pathDefaultWallet]
walletAccount := &accounts.Account{
PublicKey: types.Hex2Bytes(walletDerivedAccount.PublicKey),
KeyUID: generatedAccountInfo.KeyUID,
Address: types.HexToAddress(walletDerivedAccount.Address),
Color: "",
Wallet: true,
Path: pathDefaultWallet,
Name: "Ethereum account",
}
chatDerivedAccount := derivedAddresses[pathDefaultChat]
chatAccount := &accounts.Account{
PublicKey: types.Hex2Bytes(chatDerivedAccount.PublicKey),
KeyUID: generatedAccountInfo.KeyUID,
Address: types.HexToAddress(chatDerivedAccount.Address),
Name: settings.Name,
Chat: true,
Path: pathDefaultChat,
}
fmt.Println(nodeConfig)
accounts := []*accounts.Account{walletAccount, chatAccount}
if !exist {
return backend.StartNodeWithAccountAndInitialConfig(account, "", *settings, nodeConfig, accounts)
}
return backend.StartNodeWithAccount(account, "", nodeConfig)
}
func retrieveMessagesLoop(messenger *protocol.Messenger, tick time.Duration) {
ticker := time.NewTicker(tick)
defer ticker.Stop()
for { //nolint: gosimple
select {
case <-ticker.C:
_, err := messenger.RetrieveAll()
if err != nil {
logger.Error("failed to retrieve raw messages", "err", err)
continue
}
}
}
}

View File

@ -0,0 +1,650 @@
package main
import (
"crypto/rand"
"math/big"
)
func buildSigningPhrase() (string, error) {
length := big.NewInt(int64(len(dictionary)))
a, err := rand.Int(rand.Reader, length)
if err != nil {
return "", err
}
b, err := rand.Int(rand.Reader, length)
if err != nil {
return "", err
}
c, err := rand.Int(rand.Reader, length)
if err != nil {
return "", err
}
return dictionary[a.Int64()] + " " + dictionary[b.Int64()] + " " + dictionary[c.Int64()], nil
}
var dictionary = []string{
"acid",
"alto",
"apse",
"arch",
"area",
"army",
"atom",
"aunt",
"babe",
"baby",
"back",
"bail",
"bait",
"bake",
"ball",
"band",
"bank",
"barn",
"base",
"bass",
"bath",
"bead",
"beak",
"beam",
"bean",
"bear",
"beat",
"beef",
"beer",
"beet",
"bell",
"belt",
"bend",
"bike",
"bill",
"bird",
"bite",
"blow",
"blue",
"boar",
"boat",
"body",
"bolt",
"bomb",
"bone",
"book",
"boot",
"bore",
"boss",
"bowl",
"brow",
"bulb",
"bull",
"burn",
"bush",
"bust",
"cafe",
"cake",
"calf",
"call",
"calm",
"camp",
"cane",
"cape",
"card",
"care",
"carp",
"cart",
"case",
"cash",
"cast",
"cave",
"cell",
"cent",
"chap",
"chef",
"chin",
"chip",
"chop",
"chub",
"chug",
"city",
"clam",
"clef",
"clip",
"club",
"clue",
"coal",
"coat",
"code",
"coil",
"coin",
"coke",
"cold",
"colt",
"comb",
"cone",
"cook",
"cope",
"copy",
"cord",
"cork",
"corn",
"cost",
"crab",
"craw",
"crew",
"crib",
"crop",
"crow",
"curl",
"cyst",
"dame",
"dare",
"dark",
"dart",
"dash",
"data",
"date",
"dead",
"deal",
"dear",
"debt",
"deck",
"deep",
"deer",
"desk",
"dhow",
"diet",
"dill",
"dime",
"dirt",
"dish",
"disk",
"dock",
"doll",
"door",
"dory",
"drag",
"draw",
"drop",
"drug",
"drum",
"duck",
"dump",
"dust",
"duty",
"ease",
"east",
"eave",
"eddy",
"edge",
"envy",
"epee",
"exam",
"exit",
"face",
"fact",
"fail",
"fall",
"fame",
"fang",
"farm",
"fawn",
"fear",
"feed",
"feel",
"feet",
"file",
"fill",
"film",
"find",
"fine",
"fire",
"fish",
"flag",
"flat",
"flax",
"flow",
"foam",
"fold",
"font",
"food",
"foot",
"fork",
"form",
"fort",
"fowl",
"frog",
"fuel",
"full",
"gain",
"gale",
"galn",
"game",
"garb",
"gate",
"gear",
"gene",
"gift",
"girl",
"give",
"glad",
"glen",
"glue",
"glut",
"goal",
"goat",
"gold",
"golf",
"gong",
"good",
"gown",
"grab",
"gram",
"gray",
"grey",
"grip",
"grit",
"gyro",
"hail",
"hair",
"half",
"hall",
"hand",
"hang",
"harm",
"harp",
"hate",
"hawk",
"head",
"heat",
"heel",
"hell",
"helo",
"help",
"hemp",
"herb",
"hide",
"high",
"hill",
"hire",
"hive",
"hold",
"hole",
"home",
"hood",
"hoof",
"hook",
"hope",
"hops",
"horn",
"hose",
"host",
"hour",
"hunt",
"hurt",
"icon",
"idea",
"inch",
"iris",
"iron",
"item",
"jail",
"jeep",
"jeff",
"joey",
"join",
"joke",
"judo",
"jump",
"junk",
"jury",
"jute",
"kale",
"keep",
"kick",
"kill",
"kilt",
"kind",
"king",
"kiss",
"kite",
"knee",
"knot",
"lace",
"lack",
"lady",
"lake",
"lamb",
"lamp",
"land",
"lark",
"lava",
"lawn",
"lead",
"leaf",
"leek",
"lier",
"life",
"lift",
"lily",
"limo",
"line",
"link",
"lion",
"lisa",
"list",
"load",
"loaf",
"loan",
"lock",
"loft",
"long",
"look",
"loss",
"lout",
"love",
"luck",
"lung",
"lute",
"lynx",
"lyre",
"maid",
"mail",
"main",
"make",
"male",
"mall",
"manx",
"many",
"mare",
"mark",
"mask",
"mass",
"mate",
"math",
"meal",
"meat",
"meet",
"menu",
"mess",
"mice",
"midi",
"mile",
"milk",
"mime",
"mind",
"mine",
"mini",
"mint",
"miss",
"mist",
"moat",
"mode",
"mole",
"mood",
"moon",
"most",
"moth",
"move",
"mule",
"mutt",
"nail",
"name",
"neat",
"neck",
"need",
"neon",
"nest",
"news",
"node",
"nose",
"note",
"oboe",
"okra",
"open",
"oval",
"oven",
"oxen",
"pace",
"pack",
"page",
"pail",
"pain",
"pair",
"palm",
"pard",
"park",
"part",
"pass",
"past",
"path",
"peak",
"pear",
"peen",
"peer",
"pelt",
"perp",
"pest",
"pick",
"pier",
"pike",
"pile",
"pimp",
"pine",
"ping",
"pink",
"pint",
"pipe",
"piss",
"pith",
"plan",
"play",
"plot",
"plow",
"poem",
"poet",
"pole",
"polo",
"pond",
"pony",
"poof",
"pool",
"port",
"post",
"prow",
"pull",
"puma",
"pump",
"pupa",
"push",
"quit",
"race",
"rack",
"raft",
"rage",
"rail",
"rain",
"rake",
"rank",
"rate",
"read",
"rear",
"reef",
"rent",
"rest",
"rice",
"rich",
"ride",
"ring",
"rise",
"risk",
"road",
"robe",
"rock",
"role",
"roll",
"roof",
"room",
"root",
"rope",
"rose",
"ruin",
"rule",
"rush",
"ruth",
"sack",
"safe",
"sage",
"sail",
"sale",
"salt",
"sand",
"sari",
"sash",
"save",
"scow",
"seal",
"seat",
"seed",
"self",
"sell",
"shed",
"shin",
"ship",
"shoe",
"shop",
"shot",
"show",
"sick",
"side",
"sign",
"silk",
"sill",
"silo",
"sing",
"sink",
"site",
"size",
"skin",
"sled",
"slip",
"smog",
"snob",
"snow",
"soap",
"sock",
"soda",
"sofa",
"soft",
"soil",
"song",
"soot",
"sort",
"soup",
"spot",
"spur",
"stag",
"star",
"stay",
"stem",
"step",
"stew",
"stop",
"stud",
"suck",
"suit",
"swan",
"swim",
"tail",
"tale",
"talk",
"tank",
"tard",
"task",
"taxi",
"team",
"tear",
"teen",
"tell",
"temp",
"tent",
"term",
"test",
"text",
"thaw",
"tile",
"till",
"time",
"tire",
"toad",
"toga",
"togs",
"tone",
"tool",
"toot",
"tote",
"tour",
"town",
"tram",
"tray",
"tree",
"trim",
"trip",
"tuba",
"tube",
"tuna",
"tune",
"turn",
"tutu",
"twig",
"type",
"unit",
"user",
"vane",
"vase",
"vast",
"veal",
"veil",
"vein",
"vest",
"vibe",
"view",
"vise",
"wait",
"wake",
"walk",
"wall",
"wash",
"wasp",
"wave",
"wear",
"weed",
"week",
"well",
"west",
"whip",
"wife",
"will",
"wind",
"wine",
"wing",
"wire",
"wish",
"wolf",
"wood",
"wool",
"word",
"work",
"worm",
"wrap",
"wren",
"yard",
"yarn",
"yawl",
"year",
"yoga",
"yoke",
"yurt",
"zinc",
"zone",
}

View File

@ -1828,7 +1828,7 @@ func (s *MessengerCommunitiesSuite) TestShareCommunity() {
// Add bob to contacts so it does not go on activity center // Add bob to contacts so it does not go on activity center
bobPk := common.PubkeyToHex(&s.alice.identity.PublicKey) bobPk := common.PubkeyToHex(&s.alice.identity.PublicKey)
request := &requests.AddContact{ID: types.Hex2Bytes(bobPk)} request := &requests.AddContact{ID: bobPk}
_, err = s.alice.AddContact(context.Background(), request) _, err = s.alice.AddContact(context.Background(), request)
s.Require().NoError(err) s.Require().NoError(err)

View File

@ -70,7 +70,7 @@ func (s *MessengerActivityCenterMessageSuite) TestDeleteOneToOneChat() {
s.Require().NoError(err) s.Require().NoError(err)
r := &requests.SendContactRequest{ r := &requests.SendContactRequest{
ID: types.Hex2Bytes(s.m.myHexIdentity()), ID: s.m.myHexIdentity(),
Message: "hello", Message: "hello",
} }
sendResponse, err := theirMessenger.SendContactRequest(context.Background(), r) sendResponse, err := theirMessenger.SendContactRequest(context.Background(), r)

View File

@ -77,14 +77,14 @@ func (s *MessengerBackupSuite) TestBackupContacts() {
s.Require().NoError(err) s.Require().NoError(err)
contactID1 := types.EncodeHex(crypto.FromECDSAPub(&contact1Key.PublicKey)) contactID1 := types.EncodeHex(crypto.FromECDSAPub(&contact1Key.PublicKey))
_, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contactID1)}) _, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: contactID1})
s.Require().NoError(err) s.Require().NoError(err)
contact2Key, err := crypto.GenerateKey() contact2Key, err := crypto.GenerateKey()
s.Require().NoError(err) s.Require().NoError(err)
contactID2 := types.EncodeHex(crypto.FromECDSAPub(&contact2Key.PublicKey)) contactID2 := types.EncodeHex(crypto.FromECDSAPub(&contact2Key.PublicKey))
_, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contactID2)}) _, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: contactID2})
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Len(bob1.Contacts(), 2) s.Require().Len(bob1.Contacts(), 2)
@ -325,7 +325,7 @@ func (s *MessengerBackupSuite) TestBackupContactsGreaterThanBatch() {
s.Require().NoError(err) s.Require().NoError(err)
contactID := types.EncodeHex(crypto.FromECDSAPub(&contactKey.PublicKey)) contactID := types.EncodeHex(crypto.FromECDSAPub(&contactKey.PublicKey))
_, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contactID)}) _, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: contactID})
s.Require().NoError(err) s.Require().NoError(err)
} }
@ -365,14 +365,14 @@ func (s *MessengerBackupSuite) TestBackupRemovedContact() {
s.Require().NoError(err) s.Require().NoError(err)
contactID1 := types.EncodeHex(crypto.FromECDSAPub(&contact1Key.PublicKey)) contactID1 := types.EncodeHex(crypto.FromECDSAPub(&contact1Key.PublicKey))
_, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contactID1)}) _, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: contactID1})
s.Require().NoError(err) s.Require().NoError(err)
contact2Key, err := crypto.GenerateKey() contact2Key, err := crypto.GenerateKey()
s.Require().NoError(err) s.Require().NoError(err)
contactID2 := types.EncodeHex(crypto.FromECDSAPub(&contact2Key.PublicKey)) contactID2 := types.EncodeHex(crypto.FromECDSAPub(&contact2Key.PublicKey))
_, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contactID2)}) _, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: contactID2})
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Len(bob1.Contacts(), 2) s.Require().Len(bob1.Contacts(), 2)
@ -388,7 +388,7 @@ func (s *MessengerBackupSuite) TestBackupRemovedContact() {
// Bob 2 add one of the same contacts // Bob 2 add one of the same contacts
_, err = bob2.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contactID2)}) _, err = bob2.AddContact(context.Background(), &requests.AddContact{ID: contactID2})
s.Require().NoError(err) s.Require().NoError(err)
// Bob 1 now removes one of the contact that was also on bob 2 // Bob 1 now removes one of the contact that was also on bob 2
@ -488,7 +488,7 @@ func (s *MessengerBackupSuite) TestBackupBlockedContacts() {
s.Require().NoError(err) s.Require().NoError(err)
contactID1 := types.EncodeHex(crypto.FromECDSAPub(&contact1Key.PublicKey)) contactID1 := types.EncodeHex(crypto.FromECDSAPub(&contact1Key.PublicKey))
_, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contactID1)}) _, err = bob1.AddContact(context.Background(), &requests.AddContact{ID: contactID1})
s.Require().NoError(err) s.Require().NoError(err)
// Backup // Backup

View File

@ -71,7 +71,7 @@ func (s *MessengerContactRequestSuite) TestReceiveAndAcceptContactRequest() { //
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
request := &requests.SendContactRequest{ request := &requests.SendContactRequest{
ID: types.Hex2Bytes(contactID), ID: contactID,
Message: messageText, Message: messageText,
} }
@ -219,7 +219,7 @@ func (s *MessengerContactRequestSuite) TestReceiveAndDismissContactRequest() {
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
request := &requests.SendContactRequest{ request := &requests.SendContactRequest{
ID: types.Hex2Bytes(contactID), ID: contactID,
Message: messageText, Message: messageText,
} }
@ -314,7 +314,7 @@ func (s *MessengerContactRequestSuite) TestReceiveAcceptAndRetractContactRequest
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
request := &requests.SendContactRequest{ request := &requests.SendContactRequest{
ID: types.Hex2Bytes(contactID), ID: contactID,
Message: messageText, Message: messageText,
} }
@ -525,7 +525,7 @@ func (s *MessengerContactRequestSuite) TestReceiveAndAcceptContactRequestTwice()
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
request := &requests.SendContactRequest{ request := &requests.SendContactRequest{
ID: types.Hex2Bytes(contactID), ID: contactID,
Message: messageText, Message: messageText,
} }
@ -675,7 +675,7 @@ func (s *MessengerContactRequestSuite) TestAcceptLatestContactRequestForContact(
myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey)) myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
request := &requests.SendContactRequest{ request := &requests.SendContactRequest{
ID: types.Hex2Bytes(contactID), ID: contactID,
Message: messageText, Message: messageText,
} }
@ -805,7 +805,7 @@ func (s *MessengerContactRequestSuite) TestDismissLatestContactRequestForContact
myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey)) myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
request := &requests.SendContactRequest{ request := &requests.SendContactRequest{
ID: types.Hex2Bytes(contactID), ID: contactID,
Message: messageText, Message: messageText,
} }
@ -880,7 +880,7 @@ func (s *MessengerContactRequestSuite) TestReceiveAndAcceptLegacyContactRequest(
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
request := &requests.AddContact{ request := &requests.AddContact{
ID: types.Hex2Bytes(contactID), ID: contactID,
} }
// Send contact request // Send contact request
@ -952,7 +952,7 @@ func (s *MessengerContactRequestSuite) TestLegacyContactRequestNotifications() {
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
request := &requests.AddContact{ request := &requests.AddContact{
ID: types.Hex2Bytes(contactID), ID: contactID,
} }
// Send legacy contact request // Send legacy contact request
@ -1003,7 +1003,7 @@ func (s *MessengerContactRequestSuite) TestReceiveMultipleLegacy() {
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
request := &requests.AddContact{ request := &requests.AddContact{
ID: types.Hex2Bytes(contactID), ID: contactID,
} }
// Send legacy contact request // Send legacy contact request
@ -1103,7 +1103,7 @@ func (s *MessengerContactRequestSuite) TestAcceptLatestLegacyContactRequestForCo
myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey)) myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
request := &requests.AddContact{ request := &requests.AddContact{
ID: types.Hex2Bytes(contactID), ID: contactID,
} }
// Send contact request // Send contact request
@ -1188,7 +1188,7 @@ func (s *MessengerContactRequestSuite) TestPairedDevicesRemoveContact() {
myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey)) myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey))
request := &requests.AddContact{ request := &requests.AddContact{
ID: types.Hex2Bytes(contactID), ID: contactID,
} }
// Send contact request // Send contact request
@ -1347,7 +1347,7 @@ func (s *MessengerContactRequestSuite) TestAliceRecoverStateSendContactRequest()
myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey)) myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey))
request := &requests.AddContact{ request := &requests.AddContact{
ID: types.Hex2Bytes(bobID), ID: bobID,
} }
_, err = alice1.AddContact(context.Background(), request) _, err = alice1.AddContact(context.Background(), request)
@ -1400,7 +1400,7 @@ func (s *MessengerContactRequestSuite) TestAliceRecoverStateSendContactRequest()
// adds bob again to her device // adds bob again to her device
request = &requests.AddContact{ request = &requests.AddContact{
ID: types.Hex2Bytes(bobID), ID: bobID,
} }
_, err = alice2.AddContact(context.Background(), request) _, err = alice2.AddContact(context.Background(), request)
@ -1454,7 +1454,7 @@ func (s *MessengerContactRequestSuite) TestAliceRecoverStateReceiveContactReques
myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey)) myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey))
request := &requests.AddContact{ request := &requests.AddContact{
ID: types.Hex2Bytes(bobID), ID: bobID,
} }
_, err = alice1.AddContact(context.Background(), request) _, err = alice1.AddContact(context.Background(), request)
@ -1565,7 +1565,7 @@ func (s *MessengerContactRequestSuite) TestAliceOfflineRetractsAndAddsCorrectOrd
myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey)) myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey))
request := &requests.AddContact{ request := &requests.AddContact{
ID: types.Hex2Bytes(bobID), ID: bobID,
} }
_, err = alice1.AddContact(context.Background(), request) _, err = alice1.AddContact(context.Background(), request)
@ -1614,7 +1614,7 @@ func (s *MessengerContactRequestSuite) TestAliceOfflineRetractsAndAddsCorrectOrd
// adds bob again to her device // adds bob again to her device
request = &requests.AddContact{ request = &requests.AddContact{
ID: types.Hex2Bytes(bobID), ID: bobID,
} }
_, err = alice1.AddContact(context.Background(), request) _, err = alice1.AddContact(context.Background(), request)
@ -1651,7 +1651,7 @@ func (s *MessengerContactRequestSuite) TestAliceOfflineRetractsAndAddsWrongOrder
myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey)) myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey))
request := &requests.AddContact{ request := &requests.AddContact{
ID: types.Hex2Bytes(bobID), ID: bobID,
} }
_, err = alice1.AddContact(context.Background(), request) _, err = alice1.AddContact(context.Background(), request)
@ -1700,7 +1700,7 @@ func (s *MessengerContactRequestSuite) TestAliceOfflineRetractsAndAddsWrongOrder
// adds bob again to her device // adds bob again to her device
request = &requests.AddContact{ request = &requests.AddContact{
ID: types.Hex2Bytes(bobID), ID: bobID,
} }
_, err = alice1.AddContact(context.Background(), request) _, err = alice1.AddContact(context.Background(), request)

View File

@ -74,7 +74,7 @@ func (s *MessengerContactUpdateSuite) TestReceiveContactUpdate() {
theirContactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) theirContactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
response, err := theirMessenger.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contactID)}) response, err := theirMessenger.AddContact(context.Background(), &requests.AddContact{ID: contactID})
s.Require().NoError(err) s.Require().NoError(err)
s.Require().NotNil(response) s.Require().NotNil(response)
@ -136,7 +136,7 @@ func (s *MessengerContactUpdateSuite) TestAddContact() {
_, err := theirMessenger.Start() _, err := theirMessenger.Start()
s.Require().NoError(err) s.Require().NoError(err)
response, err := theirMessenger.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contactID)}) response, err := theirMessenger.AddContact(context.Background(), &requests.AddContact{ID: contactID})
s.Require().NoError(err) s.Require().NoError(err)
s.Require().NotNil(response) s.Require().NotNil(response)
@ -171,7 +171,7 @@ func (s *MessengerContactUpdateSuite) TestAddContactWithENS() {
s.Require().NoError(theirMessenger.ENSVerified(contactID, ensName)) s.Require().NoError(theirMessenger.ENSVerified(contactID, ensName))
response, err := theirMessenger.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contactID)}) response, err := theirMessenger.AddContact(context.Background(), &requests.AddContact{ID: contactID})
s.Require().NoError(err) s.Require().NoError(err)
s.Require().NotNil(response) s.Require().NotNil(response)
s.Require().Len(response.Contacts, 1) s.Require().Len(response.Contacts, 1)

View File

@ -54,7 +54,7 @@ func (s *MessengerVerificationRequests) mutualContact(theirMessenger *Messenger)
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey)) contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
request := &requests.SendContactRequest{ request := &requests.SendContactRequest{
ID: types.Hex2Bytes(contactID), ID: contactID,
Message: messageText, Message: messageText,
} }

View File

@ -187,7 +187,10 @@ func (m *Messenger) SendContactRequest(ctx context.Context, request *requests.Se
return nil, err return nil, err
} }
chatID := request.ID.String() chatID, err := request.HexID()
if err != nil {
return nil, err
}
response, err := m.addContact( response, err := m.addContact(
chatID, chatID,
@ -530,8 +533,13 @@ func (m *Messenger) AddContact(ctx context.Context, request *requests.AddContact
return nil, err return nil, err
} }
id, err := request.HexID()
if err != nil {
return nil, err
}
return m.addContact( return m.addContact(
request.ID.String(), id,
request.ENSName, request.ENSName,
request.Nickname, request.Nickname,
request.DisplayName, request.DisplayName,

View File

@ -13,6 +13,7 @@ import (
"github.com/status-im/status-go/images" "github.com/status-im/status-go/images"
"github.com/status-im/status-go/protocol/common" "github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/protobuf" "github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests"
v1protocol "github.com/status-im/status-go/protocol/v1" v1protocol "github.com/status-im/status-go/protocol/v1"
) )
@ -34,13 +35,22 @@ func (m *Messenger) validateAddedGroupMembers(members []string) error {
} }
func (m *Messenger) CreateGroupChatWithMembers(ctx context.Context, name string, members []string) (*MessengerResponse, error) { func (m *Messenger) CreateGroupChatWithMembers(ctx context.Context, name string, members []string) (*MessengerResponse, error) {
if err := m.validateAddedGroupMembers(members); err != nil { var convertedKeyMembers []string
for _, m := range members {
k, err := requests.ConvertCompressedToLegacyKey(m)
if err != nil {
return nil, err
}
convertedKeyMembers = append(convertedKeyMembers, k)
}
if err := m.validateAddedGroupMembers(convertedKeyMembers); err != nil {
return nil, err return nil, err
} }
var response MessengerResponse var response MessengerResponse
logger := m.logger.With(zap.String("site", "CreateGroupChatWithMembers")) logger := m.logger.With(zap.String("site", "CreateGroupChatWithMembers"))
logger.Info("Creating group chat", zap.String("name", name), zap.Any("members", members)) logger.Info("Creating group chat", zap.String("name", name), zap.Any("members", convertedKeyMembers))
chat := CreateGroupChat(m.getTimesource()) chat := CreateGroupChat(m.getTimesource())
clock, _ := chat.NextClockAndTimestamp(m.getTimesource()) clock, _ := chat.NextClockAndTimestamp(m.getTimesource())
@ -57,8 +67,8 @@ func (m *Messenger) CreateGroupChatWithMembers(ctx context.Context, name string,
clock, _ = chat.NextClockAndTimestamp(m.getTimesource()) clock, _ = chat.NextClockAndTimestamp(m.getTimesource())
// Add members // Add members
if len(members) > 0 { if len(convertedKeyMembers) > 0 {
event := v1protocol.NewMembersAddedEvent(members, clock) event := v1protocol.NewMembersAddedEvent(convertedKeyMembers, clock)
event.ChatID = chat.ID event.ChatID = chat.ID
err = event.Sign(m.identity) err = event.Sign(m.identity)
if err != nil { if err != nil {

View File

@ -320,7 +320,7 @@ func (s *MessengerProfilePictureHandlerSuite) TestE2eSendingReceivingProfilePict
s.logger.Debug("bob add contact before") s.logger.Debug("bob add contact before")
if bc { if bc {
s.logger.Debug("bob has contact to add") s.logger.Debug("bob has contact to add")
_, err = s.bob.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(s.generateKeyUID(&s.alice.identity.PublicKey))}) _, err = s.bob.AddContact(context.Background(), &requests.AddContact{ID: s.generateKeyUID(&s.alice.identity.PublicKey)})
s.Require().NoError(err) s.Require().NoError(err)
s.logger.Debug("bob add contact after") s.logger.Debug("bob add contact after")
} }
@ -367,7 +367,7 @@ func (s *MessengerProfilePictureHandlerSuite) TestE2eSendingReceivingProfilePict
s.logger.Debug("alice add contact before") s.logger.Debug("alice add contact before")
if ac { if ac {
s.logger.Debug("alice has contact to add") s.logger.Debug("alice has contact to add")
_, err = s.alice.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(s.generateKeyUID(&s.bob.identity.PublicKey))}) _, err = s.alice.AddContact(context.Background(), &requests.AddContact{ID: s.generateKeyUID(&s.bob.identity.PublicKey)})
s.Require().NoError(err) s.Require().NoError(err)
s.logger.Debug("alice add contact after") s.logger.Debug("alice add contact after")
} }

View File

@ -106,7 +106,7 @@ func (s *MessengerInstallationSuite) TestReceiveInstallation() {
contact, err := BuildContactFromPublicKey(&contactKey.PublicKey) contact, err := BuildContactFromPublicKey(&contactKey.PublicKey)
s.Require().NoError(err) s.Require().NoError(err)
response, err = s.m.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contact.ID)}) response, err = s.m.AddContact(context.Background(), &requests.AddContact{ID: contact.ID})
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Len(response.Contacts, 1) s.Require().Len(response.Contacts, 1)
@ -179,7 +179,7 @@ func (s *MessengerInstallationSuite) TestSyncInstallation() {
s.m.allContacts.Store(contact.ID, contact) s.m.allContacts.Store(contact.ID, contact)
contact.LocalNickname = "Test Nickname" contact.LocalNickname = "Test Nickname"
_, err = s.m.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contact.ID)}) _, err = s.m.AddContact(context.Background(), &requests.AddContact{ID: contact.ID})
s.Require().NoError(err) s.Require().NoError(err)
_, err = s.m.SetContactLocalNickname(&requests.SetContactLocalNickname{ID: types.Hex2Bytes(contact.ID), Nickname: contact.LocalNickname}) _, err = s.m.SetContactLocalNickname(&requests.SetContactLocalNickname{ID: types.Hex2Bytes(contact.ID), Nickname: contact.LocalNickname})
s.Require().NoError(err) s.Require().NoError(err)

View File

@ -359,3 +359,61 @@ func (m *Messenger) addContactRequestPropagatedState(message *common.Message) er
message.ContactRequestPropagatedState = contact.ContactRequestPropagatedState() message.ContactRequestPropagatedState = contact.ContactRequestPropagatedState()
return nil return nil
} }
func (m *Messenger) SendOneToOneMessage(request *requests.SendOneToOneMessage) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}
chatID, err := request.HexID()
if err != nil {
return nil, err
}
_, ok := m.allChats.Load(chatID)
if !ok {
// Only one to one chan be muted when it's not in the database
publicKey, err := common.HexToPubkey(chatID)
if err != nil {
return nil, err
}
// Create a one to one chat
chat := CreateOneToOneChat(chatID, publicKey, m.getTimesource())
err = m.initChatSyncFields(chat)
if err != nil {
return nil, err
}
err = m.saveChat(chat)
if err != nil {
return nil, err
}
}
message := &common.Message{}
message.Text = request.Message
message.ChatId = chatID
message.ContentType = protobuf.ChatMessage_TEXT_PLAIN
return m.sendChatMessage(context.Background(), message)
}
func (m *Messenger) SendGroupChatMessage(request *requests.SendGroupChatMessage) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}
chatID := request.ID
_, ok := m.allChats.Load(chatID)
if !ok {
return nil, ErrChatNotFound
}
message := &common.Message{}
message.Text = request.Message
message.ChatId = chatID
message.ContentType = protobuf.ChatMessage_TEXT_PLAIN
return m.sendChatMessage(context.Background(), message)
}

View File

@ -156,7 +156,7 @@ func (s *MessengerSuite) TestInit() {
Prep: func() { Prep: func() {
key, err := crypto.GenerateKey() key, err := crypto.GenerateKey()
s.Require().NoError(err) s.Require().NoError(err)
_, err = s.m.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(types.EncodeHex(crypto.FromECDSAPub(&key.PublicKey)))}) _, err = s.m.AddContact(context.Background(), &requests.AddContact{ID: types.EncodeHex(crypto.FromECDSAPub(&key.PublicKey))})
s.Require().NoError(err) s.Require().NoError(err)
}, },
AddedFilters: 2, AddedFilters: 2,
@ -1289,7 +1289,7 @@ func (s *MessengerSuite) TestBlockContact() {
s.Require().NoError(s.m.SaveChat(chat2)) s.Require().NoError(s.m.SaveChat(chat2))
s.Require().NoError(s.m.SaveChat(chat3)) s.Require().NoError(s.m.SaveChat(chat3))
_, err = s.m.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(contact.ID)}) _, err = s.m.AddContact(context.Background(), &requests.AddContact{ID: contact.ID})
s.Require().NoError(err) s.Require().NoError(err)
messages := []*common.Message{ messages := []*common.Message{
@ -1418,7 +1418,7 @@ func (s *MessengerSuite) TestBlockContact() {
} }
func (s *MessengerSuite) TestContactPersistence() { func (s *MessengerSuite) TestContactPersistence() {
_, err := s.m.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(testPK)}) _, err := s.m.AddContact(context.Background(), &requests.AddContact{ID: testPK})
s.Require().NoError(err) s.Require().NoError(err)
savedContacts := s.m.Contacts() savedContacts := s.m.Contacts()

View File

@ -300,7 +300,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationFromContactO
ContactRequestLocalState: ContactRequestStateSent, ContactRequestLocalState: ContactRequestStateSent,
} }
_, err = bob.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(aliceContact.ID)}) _, err = bob.AddContact(context.Background(), &requests.AddContact{ID: aliceContact.ID})
s.Require().NoError(err) s.Require().NoError(err)
// Enable from contacts only // Enable from contacts only
@ -446,7 +446,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationRetries() {
ContactRequestLocalState: ContactRequestStateSent, ContactRequestLocalState: ContactRequestStateSent,
} }
_, err = bob.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(aliceContact.ID)}) _, err = bob.AddContact(context.Background(), &requests.AddContact{ID: aliceContact.ID})
s.Require().NoError(err) s.Require().NoError(err)
// Add frank has a contact // Add frank has a contact
@ -456,7 +456,7 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationRetries() {
ContactRequestLocalState: ContactRequestStateSent, ContactRequestLocalState: ContactRequestStateSent,
} }
_, err = bob.AddContact(context.Background(), &requests.AddContact{ID: types.Hex2Bytes(frankContact.ID)}) _, err = bob.AddContact(context.Background(), &requests.AddContact{ID: frankContact.ID})
s.Require().NoError(err) s.Require().NoError(err)
// Enable from contacts only // Enable from contacts only

View File

@ -2,17 +2,15 @@ package requests
import ( import (
"errors" "errors"
"github.com/status-im/status-go/eth-node/types"
) )
var ErrAddContactInvalidID = errors.New("add-contact: invalid id") var ErrAddContactInvalidID = errors.New("add-contact: invalid id")
type AddContact struct { type AddContact struct {
ID types.HexBytes `json:"id"` ID string `json:"id"`
Nickname string `json:"nickname"` Nickname string `json:"nickname"`
DisplayName string `json:"displayName"` DisplayName string `json:"displayName"`
ENSName string `json:"ensName"` ENSName string `json:"ensName"`
} }
func (a *AddContact) Validate() error { func (a *AddContact) Validate() error {
@ -22,3 +20,7 @@ func (a *AddContact) Validate() error {
return nil return nil
} }
func (a *AddContact) HexID() (string, error) {
return ConvertCompressedToLegacyKey(a.ID)
}

View File

@ -0,0 +1,39 @@
package requests
import (
"errors"
)
var ErrCreateAccountInvalidDisplayName = errors.New("create-account: invalid display name")
var ErrCreateAccountInvalidPassword = errors.New("create-account: invalid password")
var ErrCreateAccountInvalidImagePath = errors.New("create-account: invalid image path")
var ErrCreateAccountInvalidColor = errors.New("create-account: invalid color")
type CreateAccount struct {
DisplayName string `json:"displayName"`
Password string `json:"password"`
ImagePath string `json:"imagePath"`
Color string `json:"color"`
}
func (c *CreateAccount) Validate() error {
// TODO(cammellos): Add proper validation for password/displayname/etc
if len(c.DisplayName) == 0 {
return ErrCreateAccountInvalidDisplayName
}
if len(c.Password) == 0 {
return ErrCreateAccountInvalidPassword
}
if len(c.ImagePath) == 0 {
return ErrCreateAccountInvalidImagePath
}
if len(c.Color) == 0 {
return ErrCreateAccountInvalidColor
}
return nil
}

View File

@ -3,15 +3,17 @@ package requests
import ( import (
"errors" "errors"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/api/multiformat"
) )
var ErrSendContactRequestInvalidID = errors.New("send-contact-request: invalid id") var ErrSendContactRequestInvalidID = errors.New("send-contact-request: invalid id")
var ErrSendContactRequestInvalidMessage = errors.New("send-contact-request: invalid message") var ErrSendContactRequestInvalidMessage = errors.New("send-contact-request: invalid message")
const legacyKeyLength = 132
type SendContactRequest struct { type SendContactRequest struct {
ID types.HexBytes `json:"id"` ID string `json:"id"`
Message string `json:"message"` Message string `json:"message"`
} }
func (a *SendContactRequest) Validate() error { func (a *SendContactRequest) Validate() error {
@ -25,3 +27,14 @@ func (a *SendContactRequest) Validate() error {
return nil return nil
} }
func ConvertCompressedToLegacyKey(k string) (string, error) {
if len(k) == legacyKeyLength {
return k, nil
}
return multiformat.DeserializeCompressedKey(k)
}
func (a *SendContactRequest) HexID() (string, error) {
return ConvertCompressedToLegacyKey(a.ID)
}

View File

@ -0,0 +1,25 @@
package requests
import (
"errors"
)
var ErrSendGroupChatMessageInvalidID = errors.New("send-group-chat-message: invalid id")
var ErrSendGroupChatMessageInvalidMessage = errors.New("send-group-chat-message: invalid message")
type SendGroupChatMessage struct {
ID string `json:"id"`
Message string `json:"message"`
}
func (a *SendGroupChatMessage) Validate() error {
if len(a.ID) == 0 {
return ErrSendGroupChatMessageInvalidID
}
if len(a.Message) == 0 {
return ErrSendGroupChatMessageInvalidMessage
}
return nil
}

View File

@ -0,0 +1,29 @@
package requests
import (
"errors"
)
var ErrSendOneToOneMessageInvalidID = errors.New("send-one-to-one-message: invalid id")
var ErrSendOneToOneMessageInvalidMessage = errors.New("send-one-to-one-message: invalid message")
type SendOneToOneMessage struct {
ID string `json:"id"`
Message string `json:"message"`
}
func (a *SendOneToOneMessage) Validate() error {
if len(a.ID) == 0 {
return ErrSendOneToOneMessageInvalidID
}
if len(a.Message) == 0 {
return ErrSendOneToOneMessageInvalidMessage
}
return nil
}
func (a *SendOneToOneMessage) HexID() (string, error) {
return ConvertCompressedToLegacyKey(a.ID)
}

View File

@ -771,6 +771,14 @@ func (api *PublicAPI) SendChatMessages(ctx context.Context, messages []*common.M
return api.service.messenger.SendChatMessages(ctx, messages) return api.service.messenger.SendChatMessages(ctx, messages)
} }
func (api *PublicAPI) SendOneToOneMessage(request *requests.SendOneToOneMessage) (*protocol.MessengerResponse, error) {
return api.service.messenger.SendOneToOneMessage(request)
}
func (api *PublicAPI) SendGroupChatMessage(request *requests.SendGroupChatMessage) (*protocol.MessengerResponse, error) {
return api.service.messenger.SendGroupChatMessage(request)
}
func (api *PublicAPI) EditMessage(ctx context.Context, request *requests.EditMessage) (*protocol.MessengerResponse, error) { func (api *PublicAPI) EditMessage(ctx context.Context, request *requests.EditMessage) (*protocol.MessengerResponse, error) {
return api.service.messenger.EditMessage(ctx, request) return api.service.messenger.EditMessage(ctx, request)
} }
@ -1272,6 +1280,10 @@ func (api *PublicAPI) CollapsedCommunityCategories() ([]protocol.CollapsedCommun
return api.service.messenger.CollapsedCommunityCategories() return api.service.messenger.CollapsedCommunityCategories()
} }
func (api *PublicAPI) Messenger() *protocol.Messenger {
return api.service.messenger
}
// ----- // -----
// HELPER // HELPER
// ----- // -----