chore!: simplify local pairing API (#5643)
* chore!: switch to use CreateAccount, fix tests * chore_: move GenerateInstallationID to multidevice * chore!: clean up ReceiverConfig * chore_: use DefaultKeystoreRelativePath * chore_: cleanup * fix_: import api * chore_: lint fix * chore_: remove unused import
This commit is contained in:
parent
771f26210a
commit
f660be0daa
|
@ -1181,7 +1181,7 @@ func TestConvertAccount(t *testing.T) {
|
|||
|
||||
defaultSettings, err := defaultSettings(genAccInfo.KeyUID, genAccInfo.Address, derivedAccounts)
|
||||
require.NoError(t, err)
|
||||
nodeConfig, err := defaultNodeConfig(defaultSettings.InstallationID, &requests.CreateAccount{
|
||||
nodeConfig, err := DefaultNodeConfig(defaultSettings.InstallationID, &requests.CreateAccount{
|
||||
LogLevel: defaultSettings.LogLevel,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -6,44 +6,48 @@ import (
|
|||
"math/big"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/status-im/status-go/account/generator"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"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/encryption/multidevice"
|
||||
"github.com/status-im/status-go/protocol/identity/alias"
|
||||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
"github.com/status-im/status-go/protocol/requests"
|
||||
)
|
||||
|
||||
const pathWalletRoot = "m/44'/60'/0'/0"
|
||||
const pathEIP1581 = "m/43'/60'/1581'"
|
||||
const pathDefaultChat = pathEIP1581 + "/0'/0"
|
||||
const pathEncryption = pathEIP1581 + "/1'/0"
|
||||
const pathDefaultWallet = pathWalletRoot + "/0"
|
||||
const defaultMnemonicLength = 12
|
||||
const shardsTestClusterID = 16
|
||||
const walletAccountDefaultName = "Account 1"
|
||||
const keystoreRelativePath = "keystore"
|
||||
const DefaultKeycardPairingDataFile = "/ethereum/mainnet_rpc/keycard/pairings.json"
|
||||
const (
|
||||
pathWalletRoot = "m/44'/60'/0'/0"
|
||||
pathEIP1581 = "m/43'/60'/1581'"
|
||||
pathDefaultChat = pathEIP1581 + "/0'/0"
|
||||
pathEncryption = pathEIP1581 + "/1'/0"
|
||||
pathDefaultWallet = pathWalletRoot + "/0"
|
||||
defaultMnemonicLength = 12
|
||||
shardsTestClusterID = 16
|
||||
walletAccountDefaultName = "Account 1"
|
||||
|
||||
const DefaultDataDir = "/ethereum/mainnet_rpc"
|
||||
const DefaultNodeName = "StatusIM"
|
||||
const DefaultLogFile = "geth.log"
|
||||
const DefaultLogLevel = "ERROR"
|
||||
const DefaultMaxPeers = 20
|
||||
const DefaultMaxPendingPeers = 20
|
||||
const DefaultListenAddr = ":0"
|
||||
const DefaultMaxMessageDeliveryAttempts = 3
|
||||
const DefaultVerifyTransactionChainID = 1
|
||||
DefaultKeystoreRelativePath = "keystore"
|
||||
DefaultKeycardPairingDataFile = "/ethereum/mainnet_rpc/keycard/pairings.json"
|
||||
DefaultDataDir = "/ethereum/mainnet_rpc"
|
||||
DefaultNodeName = "StatusIM"
|
||||
DefaultLogFile = "geth.log"
|
||||
DefaultLogLevel = "ERROR"
|
||||
DefaultMaxPeers = 20
|
||||
DefaultMaxPendingPeers = 20
|
||||
DefaultListenAddr = ":0"
|
||||
DefaultMaxMessageDeliveryAttempts = 3
|
||||
DefaultVerifyTransactionChainID = 1
|
||||
DefaultCurrentNetwork = "mainnet_rpc"
|
||||
)
|
||||
|
||||
var paths = []string{pathWalletRoot, pathEIP1581, pathDefaultChat, pathDefaultWallet, pathEncryption}
|
||||
var (
|
||||
paths = []string{pathWalletRoot, pathEIP1581, pathDefaultChat, pathDefaultWallet, pathEncryption}
|
||||
|
||||
var DefaultFleet = params.FleetStatusProd
|
||||
DefaultFleet = params.FleetStatusProd
|
||||
|
||||
var overrideApiConfig = overrideApiConfigProd
|
||||
overrideApiConfig = overrideApiConfigProd
|
||||
)
|
||||
|
||||
func defaultSettings(keyUID string, address string, derivedAddresses map[string]generator.AccountInfo) (*settings.Settings, error) {
|
||||
chatKeyString := derivedAddresses[pathDefaultChat].PublicKey
|
||||
|
@ -77,7 +81,7 @@ func defaultSettings(keyUID string, address string, derivedAddresses map[string]
|
|||
s.SigningPhrase = signingPhrase
|
||||
|
||||
s.SendPushNotifications = true
|
||||
s.InstallationID = uuid.New().String()
|
||||
s.InstallationID = multidevice.GenerateInstallationID()
|
||||
s.UseMailservers = true
|
||||
|
||||
s.PreviewPrivacy = true
|
||||
|
@ -102,7 +106,7 @@ func defaultSettings(keyUID string, address string, derivedAddresses map[string]
|
|||
}
|
||||
networkRawMessage := json.RawMessage(networksJSON)
|
||||
s.Networks = &networkRawMessage
|
||||
s.CurrentNetwork = "mainnet_rpc"
|
||||
s.CurrentNetwork = DefaultCurrentNetwork
|
||||
|
||||
s.TokenGroupByCommunity = false
|
||||
s.ShowCommunityAssetWhenSendingTokens = true
|
||||
|
@ -250,9 +254,10 @@ func overrideApiConfigProd(nodeConfig *params.NodeConfig, config *requests.APICo
|
|||
nodeConfig.WSPort = config.WSPort
|
||||
}
|
||||
|
||||
func defaultNodeConfig(installationID string, request *requests.CreateAccount, opts ...params.Option) (*params.NodeConfig, error) {
|
||||
func DefaultNodeConfig(installationID string, request *requests.CreateAccount, opts ...params.Option) (*params.NodeConfig, error) {
|
||||
// Set mainnet
|
||||
nodeConfig := ¶ms.NodeConfig{}
|
||||
nodeConfig.RootDataDir = request.RootDataDir
|
||||
nodeConfig.LogEnabled = request.LogEnabled
|
||||
nodeConfig.LogFile = DefaultLogFile
|
||||
nodeConfig.LogDir = request.LogFilePath
|
||||
|
@ -399,6 +404,12 @@ func defaultNodeConfig(installationID string, request *requests.CreateAccount, o
|
|||
return nodeConfig, nil
|
||||
}
|
||||
|
||||
func DefaultKeystorePath(rootDataDir string, keyUID string) (string, string) {
|
||||
relativePath := filepath.Join(DefaultKeystoreRelativePath, keyUID)
|
||||
absolutePath := filepath.Join(rootDataDir, relativePath)
|
||||
return relativePath, absolutePath
|
||||
}
|
||||
|
||||
func buildSigningPhrase() (string, error) {
|
||||
length := big.NewInt(int64(len(dictionary)))
|
||||
a, err := rand.Int(rand.Reader, length)
|
||||
|
|
|
@ -74,8 +74,6 @@ var (
|
|||
ErrRPCClientUnavailable = errors.New("JSON-RPC client is unavailable")
|
||||
// ErrDBNotAvailable is returned if a method is called before the DB is available for usage
|
||||
ErrDBNotAvailable = errors.New("DB is unavailable")
|
||||
// ErrConfigNotAvailable is returned if a method is called before the nodeconfig is set
|
||||
ErrConfigNotAvailable = errors.New("NodeConfig is not available")
|
||||
)
|
||||
|
||||
var _ StatusBackend = (*GethStatusBackend)(nil)
|
||||
|
@ -1340,7 +1338,7 @@ func (b *GethStatusBackend) RestoreKeycardAccountAndLogin(request *requests.Rest
|
|||
return nil, err
|
||||
}
|
||||
|
||||
keyStoreDir, err := b.initKeyStoreDirWithAccount(request.RootDataDir, request.Keycard.KeyUID)
|
||||
keyStoreDir, err := b.InitKeyStoreDirWithAccount(request.RootDataDir, request.Keycard.KeyUID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1438,7 +1436,7 @@ func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizati
|
|||
return nil, err
|
||||
}
|
||||
|
||||
keyStoreDir, err := b.initKeyStoreDirWithAccount(request.RootDataDir, info.KeyUID)
|
||||
keyStoreDir, err := b.InitKeyStoreDirWithAccount(request.RootDataDir, info.KeyUID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1511,12 +1509,11 @@ func (b *GethStatusBackend) prepareNodeAccount(request *requests.CreateAccount,
|
|||
return response, nil
|
||||
}
|
||||
|
||||
func (b *GethStatusBackend) initKeyStoreDirWithAccount(rootDataDir, keyUID string) (string, error) {
|
||||
func (b *GethStatusBackend) InitKeyStoreDirWithAccount(rootDataDir, keyUID string) (string, error) {
|
||||
b.UpdateRootDataDir(rootDataDir)
|
||||
keystoreDir := keystoreRelativePath
|
||||
userKeyStoreDir := filepath.Join(keystoreDir, keyUID)
|
||||
keyStoreRelativePath, keystoreAbsolutePath := DefaultKeystorePath(rootDataDir, keyUID)
|
||||
// Initialize keystore dir with account
|
||||
return userKeyStoreDir, b.accountManager.InitKeystore(filepath.Join(b.rootDataDir, userKeyStoreDir))
|
||||
return keyStoreRelativePath, b.accountManager.InitKeystore(keystoreAbsolutePath)
|
||||
}
|
||||
|
||||
func (b *GethStatusBackend) generateAccountInfo(mnemonic string) (*generator.GeneratedAccountInfo, error) {
|
||||
|
@ -1629,7 +1626,7 @@ func (b *GethStatusBackend) prepareSettings(request *requests.CreateAccount, inp
|
|||
}
|
||||
|
||||
func (b *GethStatusBackend) prepareConfig(request *requests.CreateAccount, input *prepareAccountInput, installationID string) (*params.NodeConfig, error) {
|
||||
nodeConfig, err := defaultNodeConfig(installationID, request, input.opts...)
|
||||
nodeConfig, err := DefaultNodeConfig(installationID, request, input.opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"database/sql"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/crypto"
|
||||
)
|
||||
|
||||
|
@ -127,3 +129,7 @@ func (s *Multidevice) DisableInstallation(myIdentityKey *ecdsa.PublicKey, instal
|
|||
myIdentityKeyC := crypto.CompressPubkey(myIdentityKey)
|
||||
return s.persistence.DisableInstallation(myIdentityKeyC, installationID)
|
||||
}
|
||||
|
||||
func GenerateInstallationID() string {
|
||||
return uuid.New().String()
|
||||
}
|
||||
|
|
|
@ -123,11 +123,11 @@ func (c *CreateAccount) Validate(validation *CreateAccountValidation) error {
|
|||
return errors.Wrap(ErrCreateAccountInvalidDisplayName, err.Error())
|
||||
}
|
||||
|
||||
if len(c.Password) == 0 {
|
||||
if len(c.Password) == 0 && !validation.AllowEmptyPassword {
|
||||
return ErrCreateAccountInvalidPassword
|
||||
}
|
||||
|
||||
if len(c.CustomizationColor) == 0 {
|
||||
if len(c.CustomizationColor) == 0 && !validation.AllowEmptyCustomizationColor {
|
||||
return ErrCreateAccountInvalidCustomizationColor
|
||||
}
|
||||
|
||||
|
@ -140,5 +140,7 @@ func (c *CreateAccount) Validate(validation *CreateAccountValidation) error {
|
|||
|
||||
// NOTE: Reasoning for this struct here: https://github.com/status-im/status-go/pull/4980#discussion_r1539219099
|
||||
type CreateAccountValidation struct {
|
||||
AllowEmptyDisplayName bool
|
||||
AllowEmptyDisplayName bool
|
||||
AllowEmptyPassword bool
|
||||
AllowEmptyCustomizationColor bool
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/status-im/status-go/connection"
|
||||
"github.com/status-im/status-go/eth-node/crypto"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"runtime"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
|
@ -523,11 +524,12 @@ func setupReceivingClient(backend *api.GethStatusBackend, cs, configJSON string)
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
receiverConf := conf.ReceiverConfig
|
||||
if err = setDefaultNodeConfig(receiverConf.NodeConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = validateAndVerifyNodeConfig(conf, receiverConf)
|
||||
|
||||
// This is a temporal solution to allow clients not to pass DeviceType.
|
||||
// Check DeviceType deprecation reason for more info.
|
||||
conf.ReceiverConfig.DeviceType = runtime.GOOS
|
||||
|
||||
err = validateReceiverConfig(conf, conf.ReceiverConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -10,9 +10,6 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/protocol/requests"
|
||||
|
||||
"gopkg.in/go-playground/validator.v9"
|
||||
|
@ -43,12 +40,6 @@ func newValidate() (*validator.Validate, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := validate.RegisterValidation("not_end_keyuid", func(fl validator.FieldLevel) bool {
|
||||
keystorePath := fl.Field().String()
|
||||
return len(keystorePath) <= 66 || !keyUIDPattern.MatchString(keystorePath[len(keystorePath)-66:])
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return validate, nil
|
||||
}
|
||||
|
||||
|
@ -120,21 +111,17 @@ func validateAndVerifyPassword(s interface{}, senderConfig *SenderConfig) error
|
|||
return validateKeys(keys, senderConfig.Password)
|
||||
}
|
||||
|
||||
func validateAndVerifyNodeConfig(s interface{}, receiverConfig *ReceiverConfig) error {
|
||||
func validateReceiverConfig(s interface{}, receiverConfig *ReceiverConfig) error {
|
||||
err := validate(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if receiverConfig.NodeConfig == nil {
|
||||
return fmt.Errorf("node config is required for receiver config")
|
||||
}
|
||||
|
||||
if receiverConfig.NodeConfig.RootDataDir == "" {
|
||||
return fmt.Errorf("root data dir is required for node config")
|
||||
}
|
||||
|
||||
return receiverConfig.NodeConfig.Validate()
|
||||
return receiverConfig.CreateAccount.Validate(&requests.CreateAccountValidation{
|
||||
AllowEmptyDisplayName: true,
|
||||
AllowEmptyCustomizationColor: true,
|
||||
AllowEmptyPassword: true,
|
||||
})
|
||||
}
|
||||
|
||||
func emptyDir(dir string) error {
|
||||
|
@ -247,109 +234,3 @@ func validateKeystoreFilesConfig(backend *api.GethStatusBackend, conf interface{
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// setDefaultNodeConfig sets default values for the node configuration.
|
||||
// Config Values still needed from the mobile include
|
||||
// VerifyTransactionURL/VerifyENSURL/VerifyENSContractAddress/VerifyTransactionChainID
|
||||
// LogEnabled/LogDir/RootDataDir/LightClient/Nameserver
|
||||
func setDefaultNodeConfig(c *params.NodeConfig) error {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := c.UpdateWithDefaults()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// following specifiedXXX variables are used to check if frontend has specified the value
|
||||
// if not, the default value is set. NOTE: we also check 2 extra fields: WakuV2Config(LightClient|Nameserver)
|
||||
// see api.SetFleet for more details
|
||||
specifiedVerifyTransactionURL := c.ShhextConfig.VerifyTransactionURL
|
||||
specifiedVerifyENSURL := c.ShhextConfig.VerifyENSURL
|
||||
specifiedVerifyENSContractAddress := c.ShhextConfig.VerifyENSContractAddress
|
||||
specifiedVerifyTransactionChainID := c.ShhextConfig.VerifyTransactionChainID
|
||||
specifiedNetworkID := c.NetworkID
|
||||
specifiedNetworks := c.Networks
|
||||
specifiedUpstreamConfigURL := c.UpstreamConfig.URL
|
||||
specifiedLogEnabled := c.LogEnabled
|
||||
specifiedLogLevel := c.LogLevel
|
||||
specifiedFleet := c.ClusterConfig.Fleet
|
||||
specifiedInstallationID := c.ShhextConfig.InstallationID
|
||||
specifiedTorrentConfigEnabled := c.TorrentConfig.Enabled
|
||||
specifiedTorrentConfigPort := c.TorrentConfig.Port
|
||||
|
||||
if len(specifiedNetworks) == 0 {
|
||||
c.Networks = api.BuildDefaultNetworks(&requests.WalletSecretsConfig{})
|
||||
}
|
||||
|
||||
if specifiedNetworkID == 0 {
|
||||
c.NetworkID = c.Networks[0].ChainID
|
||||
}
|
||||
|
||||
c.UpstreamConfig.Enabled = true
|
||||
if specifiedUpstreamConfigURL == "" {
|
||||
c.UpstreamConfig.URL = c.Networks[0].RPCURL
|
||||
}
|
||||
|
||||
if specifiedLogEnabled && specifiedLogLevel == "" {
|
||||
c.LogLevel = api.DefaultLogLevel
|
||||
}
|
||||
c.LogFile = api.DefaultLogFile
|
||||
|
||||
c.Name = api.DefaultNodeName
|
||||
c.DataDir = api.DefaultDataDir
|
||||
c.KeycardPairingDataFile = api.DefaultKeycardPairingDataFile
|
||||
c.Rendezvous = false
|
||||
c.NoDiscovery = true
|
||||
c.MaxPeers = api.DefaultMaxPeers
|
||||
c.MaxPendingPeers = api.DefaultMaxPendingPeers
|
||||
|
||||
c.LocalNotificationsConfig = params.LocalNotificationsConfig{Enabled: true}
|
||||
c.BrowsersConfig = params.BrowsersConfig{Enabled: true}
|
||||
c.PermissionsConfig = params.PermissionsConfig{Enabled: true}
|
||||
c.MailserversConfig = params.MailserversConfig{Enabled: true}
|
||||
|
||||
c.ListenAddr = api.DefaultListenAddr
|
||||
|
||||
if specifiedFleet == "" {
|
||||
err = api.SetDefaultFleet(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if specifiedInstallationID == "" {
|
||||
specifiedInstallationID = uuid.New().String()
|
||||
}
|
||||
|
||||
c.ShhextConfig = params.ShhextConfig{
|
||||
InstallationID: specifiedInstallationID,
|
||||
MaxMessageDeliveryAttempts: api.DefaultMaxMessageDeliveryAttempts,
|
||||
MailServerConfirmations: true,
|
||||
DataSyncEnabled: true,
|
||||
PFSEnabled: true,
|
||||
VerifyTransactionURL: specifiedVerifyTransactionURL,
|
||||
VerifyENSURL: specifiedVerifyENSURL,
|
||||
VerifyENSContractAddress: specifiedVerifyENSContractAddress,
|
||||
}
|
||||
if specifiedVerifyTransactionChainID == 0 {
|
||||
c.ShhextConfig.VerifyTransactionChainID = int64(c.Networks[0].ChainID)
|
||||
}
|
||||
|
||||
if specifiedVerifyTransactionURL == "" {
|
||||
c.ShhextConfig.VerifyTransactionURL = c.Networks[0].FallbackURL
|
||||
}
|
||||
if specifiedVerifyENSURL == "" {
|
||||
c.ShhextConfig.VerifyENSURL = c.Networks[0].FallbackURL
|
||||
}
|
||||
|
||||
c.TorrentConfig = params.TorrentConfig{
|
||||
Enabled: specifiedTorrentConfigEnabled,
|
||||
Port: specifiedTorrentConfigPort,
|
||||
DataDir: filepath.Join(c.RootDataDir, params.ArchivesRelativePath),
|
||||
TorrentDir: filepath.Join(c.RootDataDir, params.TorrentTorrentsRelativePath),
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -54,7 +54,10 @@ func (tpsc *TestPairingServerComponents) SetupPairingServerComponents(t *testing
|
|||
|
||||
tpsc.SS, err = NewSenderServer(nil, &SenderServerConfig{ServerConfig: sc, SenderConfig: &SenderConfig{}})
|
||||
require.NoError(t, err)
|
||||
tpsc.RS, err = NewReceiverServer(nil, &ReceiverServerConfig{ServerConfig: sc, ReceiverConfig: &ReceiverConfig{}})
|
||||
tpsc.RS, err = NewReceiverServer(nil, &ReceiverServerConfig{
|
||||
ServerConfig: sc,
|
||||
ReceiverConfig: &ReceiverConfig{},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,9 @@ import (
|
|||
"crypto/tls"
|
||||
"net"
|
||||
|
||||
"github.com/status-im/status-go/api"
|
||||
"github.com/status-im/status-go/multiaccounts"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/protocol/requests"
|
||||
)
|
||||
|
||||
type SenderConfig struct {
|
||||
|
@ -23,20 +24,13 @@ type SenderConfig struct {
|
|||
}
|
||||
|
||||
type ReceiverConfig struct {
|
||||
// nodeConfig is required, but we'll validate it separately
|
||||
NodeConfig *params.NodeConfig `json:"nodeConfig"`
|
||||
|
||||
// ReceiverConfig.KeystorePath must not end with keyUID (because keyUID is not known yet)
|
||||
KeystorePath string `json:"keystorePath" validate:"required,not_end_keyuid"`
|
||||
CreateAccount *requests.CreateAccount `json:"createAccount" validate:"required"`
|
||||
|
||||
// DeviceType SendPairInstallation need this information
|
||||
DeviceType string `json:"deviceType" validate:"required"`
|
||||
KDFIterations int `json:"kdfIterations" validate:"gte=0"`
|
||||
// Deprecated: This field will be automatically overridden with runtime.GOOS and can be omitted by client.
|
||||
// The field will be removed in https://github.com/status-im/status-go/issues/3351 is fully implemented.
|
||||
DeviceType string `json:"-"`
|
||||
|
||||
// SettingCurrentNetwork corresponding to field current_network from table settings, so that we can override current network from sender
|
||||
SettingCurrentNetwork string `json:"settingCurrentNetwork" validate:"required"`
|
||||
|
||||
DeviceName string `json:"deviceName"`
|
||||
DB *multiaccounts.Database `json:"-"`
|
||||
LoggedInKeyUID string `json:"-"`
|
||||
}
|
||||
|
@ -146,3 +140,10 @@ func NewReceiverServerConfig() *ReceiverServerConfig {
|
|||
ServerConfig: new(ServerConfig),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ReceiverConfig) AbsoluteKeystorePath() string {
|
||||
// Follow the same path as in InitKeyStoreDirWithAccount
|
||||
// Keep keyUID empty as it's unknown yet
|
||||
_, path := api.DefaultKeystorePath(c.CreateAccount.RootDataDir, "")
|
||||
return path
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package pairing
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"gopkg.in/go-playground/validator.v9"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/status-im/status-go/protocol/requests"
|
||||
)
|
||||
|
||||
func TestConfigTestSuite(t *testing.T) {
|
||||
|
@ -75,30 +77,17 @@ func (s *ConfigTestSuite) TestValidationKeyUID() {
|
|||
}
|
||||
|
||||
func (s *ConfigTestSuite) TestValidationNotEndKeyUID() {
|
||||
nodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", "/dummy/path")
|
||||
nodeConfig.RootDataDir = "/tmp"
|
||||
require.NoError(s.T(), err, "nodeConfigForLocalPairSync should not return error")
|
||||
s.T().Run("Valid keystore path without keyUID", func(t *testing.T) {
|
||||
r := &ReceiverConfig{
|
||||
NodeConfig: nodeConfig,
|
||||
KeystorePath: "some/path/",
|
||||
DeviceType: "phone",
|
||||
KDFIterations: 1,
|
||||
SettingCurrentNetwork: "mainnet",
|
||||
}
|
||||
assert.NoError(t, setDefaultNodeConfig(r.NodeConfig))
|
||||
assert.NoError(t, validateAndVerifyNodeConfig(r, r), "ReceiverConfig validation should pass")
|
||||
})
|
||||
keyUIDPattern := regexp.MustCompile(`^0x[0-9a-fA-F]{64}$`)
|
||||
|
||||
s.T().Run("Invalid keystore path with keyUID", func(t *testing.T) {
|
||||
r := &ReceiverConfig{
|
||||
NodeConfig: nodeConfig,
|
||||
KeystorePath: "some/path/0x130cc0ebdaecd220c1d6dea0ef01d575ef5364506785745049eb98ddf49cb54e",
|
||||
DeviceType: "phone",
|
||||
KDFIterations: 1,
|
||||
SettingCurrentNetwork: "mainnet",
|
||||
}
|
||||
assert.NoError(t, setDefaultNodeConfig(r.NodeConfig))
|
||||
assert.Error(t, validateAndVerifyNodeConfig(r, r), "ReceiverConfig validation should fail")
|
||||
})
|
||||
r := &ReceiverConfig{
|
||||
CreateAccount: &requests.CreateAccount{
|
||||
RootDataDir: "/tmp",
|
||||
KdfIterations: 1,
|
||||
DeviceName: "device-1",
|
||||
},
|
||||
}
|
||||
keystorePath := r.AbsoluteKeystorePath()
|
||||
s.Require().True(len(keystorePath) <= 66 || !keyUIDPattern.MatchString(keystorePath[len(keystorePath)-66:]))
|
||||
|
||||
s.Require().NoError(validateReceiverConfig(r, r), "ReceiverConfig validation should pass")
|
||||
}
|
||||
|
|
|
@ -14,13 +14,9 @@ import (
|
|||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
)
|
||||
|
||||
const keystoreDir = "keystore"
|
||||
|
||||
var (
|
||||
ErrKeyFileAlreadyExists = errors.New("key file already exists")
|
||||
ErrKeyUIDEmptyAsSender = errors.New("keyUID must be provided as sender")
|
||||
ErrNodeConfigNilAsReceiver = errors.New("node config must be provided as receiver")
|
||||
ErrLoggedInKeyUIDConflict = errors.New("logged in keyUID not same as keyUID in payload")
|
||||
ErrKeyFileAlreadyExists = errors.New("key file already exists")
|
||||
ErrLoggedInKeyUIDConflict = errors.New("logged in keyUID not same as keyUID in payload")
|
||||
)
|
||||
|
||||
// AccountPayload represents the payload structure a Server handles
|
||||
|
|
|
@ -13,9 +13,11 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/status-im/status-go/api"
|
||||
"github.com/status-im/status-go/common/dbsetup"
|
||||
"github.com/status-im/status-go/images"
|
||||
"github.com/status-im/status-go/multiaccounts"
|
||||
"github.com/status-im/status-go/protocol/requests"
|
||||
"github.com/status-im/status-go/server/servertest"
|
||||
"github.com/status-im/status-go/t/utils"
|
||||
)
|
||||
|
@ -62,21 +64,14 @@ func setupTestDB(t *testing.T) (*multiaccounts.Database, func()) {
|
|||
}
|
||||
}
|
||||
|
||||
func makeKeystores(t *testing.T) (string, string) {
|
||||
func makeKeystore(t *testing.T) string {
|
||||
keyStoreDir := t.TempDir()
|
||||
emptyKeyStoreDir := t.TempDir()
|
||||
|
||||
keyStoreDir = filepath.Join(keyStoreDir, keystoreDir, keyUID)
|
||||
// TODO test case where the keystore dir does not yet exist because the device is new
|
||||
emptyKeyStoreDir = filepath.Join(emptyKeyStoreDir, keystoreDir)
|
||||
keyStoreDir = filepath.Join(keyStoreDir, api.DefaultKeystoreRelativePath)
|
||||
|
||||
err := os.MkdirAll(keyStoreDir, 0777)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.MkdirAll(emptyKeyStoreDir, 0777)
|
||||
require.NoError(t, err)
|
||||
|
||||
return keyStoreDir, emptyKeyStoreDir
|
||||
return keyStoreDir
|
||||
}
|
||||
|
||||
func initKeys(t *testing.T, keyStoreDir string) {
|
||||
|
@ -116,7 +111,7 @@ func (pms *PayloadMarshallerSuite) SetupTest() {
|
|||
|
||||
db1, db1td := setupTestDB(pms.T())
|
||||
db2, db2td := setupTestDB(pms.T())
|
||||
keystore1, keystore2 := makeKeystores(pms.T())
|
||||
keystore1 := filepath.Join(makeKeystore(pms.T()), keyUID)
|
||||
pms.teardown = func() {
|
||||
db1td()
|
||||
db2td()
|
||||
|
@ -134,8 +129,10 @@ func (pms *PayloadMarshallerSuite) SetupTest() {
|
|||
}
|
||||
|
||||
pms.config2 = &ReceiverConfig{
|
||||
DB: db2,
|
||||
KeystorePath: keystore2,
|
||||
DB: db2,
|
||||
CreateAccount: &requests.CreateAccount{
|
||||
RootDataDir: pms.T().TempDir(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,7 +290,7 @@ func (pms *PayloadMarshallerSuite) TestPayloadMarshaller_StorePayloads() {
|
|||
pms.Require().NoError(err)
|
||||
|
||||
// TEST PairingPayloadRepository 2 Store()
|
||||
keys := getFiles(pms.T(), filepath.Join(pms.config2.KeystorePath, keyUID))
|
||||
keys := getFiles(pms.T(), filepath.Join(pms.config2.AbsoluteKeystorePath(), keyUID))
|
||||
|
||||
pms.Require().Len(keys, 2)
|
||||
pms.Require().Len(keys[utils.GetAccount1PKFile()], 489)
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/status-im/status-go/api"
|
||||
"github.com/status-im/status-go/multiaccounts"
|
||||
"github.com/status-im/status-go/multiaccounts/accounts"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/protocol/requests"
|
||||
"github.com/status-im/status-go/signal"
|
||||
)
|
||||
|
||||
|
@ -126,9 +126,12 @@ func NewAccountPayloadStorer(p *AccountPayload, config *ReceiverConfig) (*Accoun
|
|||
return ppr, nil
|
||||
}
|
||||
|
||||
if config.CreateAccount != nil {
|
||||
ppr.kdfIterations = config.CreateAccount.KdfIterations
|
||||
ppr.keystorePath = config.AbsoluteKeystorePath()
|
||||
}
|
||||
|
||||
ppr.multiaccountsDB = config.DB
|
||||
ppr.kdfIterations = config.KDFIterations
|
||||
ppr.keystorePath = config.KeystorePath
|
||||
ppr.loggedInKeyUID = config.LoggedInKeyUID
|
||||
return ppr, nil
|
||||
}
|
||||
|
@ -173,7 +176,7 @@ func (aps *AccountPayloadStorer) storeKeys(keyStorePath string) error {
|
|||
|
||||
// If lastDir == keystoreDir we presume we need to create the rest of the keystore path
|
||||
// else we presume the provided keystore is valid
|
||||
if lastDir == keystoreDir {
|
||||
if lastDir == api.DefaultKeystoreRelativePath {
|
||||
if aps.multiaccount == nil || aps.multiaccount.KeyUID == "" {
|
||||
return fmt.Errorf("no known Key UID")
|
||||
}
|
||||
|
@ -237,10 +240,8 @@ type RawMessageStorer struct {
|
|||
payload *RawMessagesPayload
|
||||
syncRawMessageHandler *SyncRawMessageHandler
|
||||
accountPayload *AccountPayload
|
||||
nodeConfig *params.NodeConfig
|
||||
settingCurrentNetwork string
|
||||
createAccount *requests.CreateAccount
|
||||
deviceType string
|
||||
deviceName string
|
||||
}
|
||||
|
||||
func NewRawMessageStorer(backend *api.GethStatusBackend, payload *RawMessagesPayload, accountPayload *AccountPayload, config *ReceiverConfig) *RawMessageStorer {
|
||||
|
@ -248,10 +249,8 @@ func NewRawMessageStorer(backend *api.GethStatusBackend, payload *RawMessagesPay
|
|||
syncRawMessageHandler: NewSyncRawMessageHandler(backend),
|
||||
payload: payload,
|
||||
accountPayload: accountPayload,
|
||||
nodeConfig: config.NodeConfig,
|
||||
settingCurrentNetwork: config.SettingCurrentNetwork,
|
||||
deviceType: config.DeviceType,
|
||||
deviceName: config.DeviceName,
|
||||
createAccount: config.CreateAccount,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,7 +258,7 @@ func (r *RawMessageStorer) Store() error {
|
|||
if r.accountPayload == nil || r.accountPayload.multiaccount == nil {
|
||||
return fmt.Errorf("no known multiaccount when storing raw messages")
|
||||
}
|
||||
return r.syncRawMessageHandler.HandleRawMessage(r.accountPayload, r.nodeConfig, r.settingCurrentNetwork, r.deviceType, r.deviceName, r.payload)
|
||||
return r.syncRawMessageHandler.HandleRawMessage(r.accountPayload, r.createAccount, r.deviceType, r.payload)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -443,7 +442,7 @@ func (kfps *KeystoreFilesPayloadStorer) storeKeys(keyStorePath string) error {
|
|||
|
||||
// If lastDir == keystoreDir we presume we need to create the rest of the keystore path
|
||||
// else we presume the provided keystore is valid
|
||||
if lastDir == keystoreDir {
|
||||
if lastDir == api.DefaultKeystoreRelativePath {
|
||||
keyStorePath = filepath.Join(keyStorePath, kfps.loggedInKeyUID)
|
||||
_, err := os.Stat(keyStorePath)
|
||||
if os.IsNotExist(err) {
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"crypto/ecdsa"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
|
@ -12,9 +11,9 @@ import (
|
|||
"github.com/status-im/status-go/api"
|
||||
"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/encryption/multidevice"
|
||||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
|
||||
"github.com/status-im/status-go/protocol/requests"
|
||||
"github.com/status-im/status-go/signal"
|
||||
)
|
||||
|
||||
|
@ -88,39 +87,15 @@ func (s *SyncRawMessageHandler) PrepareRawMessage(keyUID, deviceType string) (rm
|
|||
return
|
||||
}
|
||||
|
||||
func (s *SyncRawMessageHandler) HandleRawMessage(accountPayload *AccountPayload, nodeConfig *params.NodeConfig, settingCurrentNetwork, deviceType string, deviceName string, rmp *RawMessagesPayload) (err error) {
|
||||
account := accountPayload.multiaccount
|
||||
func (s *SyncRawMessageHandler) HandleRawMessage(
|
||||
accountPayload *AccountPayload,
|
||||
createAccountRequest *requests.CreateAccount,
|
||||
deviceType string,
|
||||
rmp *RawMessagesPayload) (err error) {
|
||||
|
||||
activeAccount, _ := s.backend.GetActiveAccount()
|
||||
if activeAccount == nil { // not login yet
|
||||
s.backend.UpdateRootDataDir(nodeConfig.RootDataDir)
|
||||
// because client don't know keyUID before received data, we need help client to update keystore dir
|
||||
keystoreDir := filepath.Join(nodeConfig.KeyStoreDir, account.KeyUID)
|
||||
nodeConfig.KeyStoreDir = keystoreDir
|
||||
|
||||
var chatKey *ecdsa.PrivateKey
|
||||
if accountPayload.chatKey != "" {
|
||||
chatKeyHex := strings.Trim(accountPayload.chatKey, "0x")
|
||||
chatKey, err = ethcrypto.HexToECDSA(chatKeyHex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if accountPayload.exist {
|
||||
err = s.backend.StartNodeWithAccount(*account, accountPayload.password, nodeConfig, chatKey)
|
||||
} else {
|
||||
accountManager := s.backend.AccountManager()
|
||||
err = accountManager.InitKeystore(filepath.Join(nodeConfig.RootDataDir, keystoreDir))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rmp.setting.DeviceName = deviceName
|
||||
rmp.setting.InstallationID = nodeConfig.ShhextConfig.InstallationID
|
||||
rmp.setting.CurrentNetwork = settingCurrentNetwork
|
||||
|
||||
err = s.backend.StartNodeWithAccountAndInitialConfig(*account, accountPayload.password, *rmp.setting, nodeConfig, rmp.profileKeypair.Accounts, chatKey)
|
||||
}
|
||||
err = s.login(accountPayload, createAccountRequest, rmp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -152,3 +127,46 @@ func (s *SyncRawMessageHandler) HandleRawMessage(accountPayload *AccountPayload,
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SyncRawMessageHandler) login(accountPayload *AccountPayload, createAccountRequest *requests.CreateAccount, rmp *RawMessagesPayload) error {
|
||||
account := accountPayload.multiaccount
|
||||
installationID := multidevice.GenerateInstallationID()
|
||||
nodeConfig, err := api.DefaultNodeConfig(installationID, createAccountRequest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
keystoreRelativePath, err := s.backend.InitKeyStoreDirWithAccount(nodeConfig.RootDataDir, account.KeyUID)
|
||||
nodeConfig.KeyStoreDir = keystoreRelativePath
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var chatKey *ecdsa.PrivateKey
|
||||
if accountPayload.chatKey != "" {
|
||||
chatKeyHex := strings.Trim(accountPayload.chatKey, "0x")
|
||||
chatKey, err = ethcrypto.HexToECDSA(chatKeyHex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if accountPayload.exist {
|
||||
return s.backend.StartNodeWithAccount(*account, accountPayload.password, nodeConfig, chatKey)
|
||||
}
|
||||
|
||||
// Override some of received settings
|
||||
rmp.setting.DeviceName = createAccountRequest.DeviceName
|
||||
rmp.setting.InstallationID = installationID
|
||||
rmp.setting.CurrentNetwork = api.DefaultCurrentNetwork
|
||||
|
||||
return s.backend.StartNodeWithAccountAndInitialConfig(
|
||||
*account,
|
||||
accountPayload.password,
|
||||
*rmp.setting,
|
||||
nodeConfig,
|
||||
rmp.profileKeypair.Accounts,
|
||||
chatKey,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"net"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
|
@ -296,11 +297,12 @@ func StartUpReceiverServer(backend *api.GethStatusBackend, configJSON string) (s
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
receiverConf := conf.ReceiverConfig
|
||||
if err = setDefaultNodeConfig(receiverConf.NodeConfig); err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = validateAndVerifyNodeConfig(conf, receiverConf)
|
||||
|
||||
// This is a temporal solution to allow clients not to pass DeviceType.
|
||||
// Check DeviceType deprecation reason for more info.
|
||||
conf.ReceiverConfig.DeviceType = runtime.GOOS
|
||||
|
||||
err = validateReceiverConfig(conf, conf.ReceiverConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -20,19 +20,13 @@ import (
|
|||
"github.com/status-im/status-go/protocol/encryption/multidevice"
|
||||
"github.com/status-im/status-go/protocol/tt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"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/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/common"
|
||||
"github.com/status-im/status-go/protocol/identity/alias"
|
||||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
"github.com/status-im/status-go/protocol/requests"
|
||||
accservice "github.com/status-im/status-go/services/accounts"
|
||||
|
@ -58,8 +52,6 @@ const (
|
|||
expectedKDFIterations = 1024
|
||||
)
|
||||
|
||||
var paths = []string{pathWalletRoot, pathEIP1581, pathDefaultChat, pathDefaultWallet}
|
||||
|
||||
func TestSyncDeviceSuite(t *testing.T) {
|
||||
suite.Run(t, new(SyncDeviceSuite))
|
||||
}
|
||||
|
@ -79,72 +71,37 @@ func (s *SyncDeviceSuite) SetupTest() {
|
|||
|
||||
func (s *SyncDeviceSuite) prepareBackendWithAccount(mnemonic, tmpdir string) *api.GethStatusBackend {
|
||||
backend := s.prepareBackendWithoutAccount(tmpdir)
|
||||
accountManager := backend.AccountManager()
|
||||
accGenerator := accountManager.AccountsGenerator()
|
||||
|
||||
var (
|
||||
generatedAccountInfo generator.GeneratedAndDerivedAccountInfo
|
||||
err error
|
||||
)
|
||||
if len(mnemonic) > 0 {
|
||||
generatedAccountInfo.GeneratedAccountInfo, err = accGenerator.ImportMnemonic(mnemonic, "")
|
||||
require.NoError(s.T(), err)
|
||||
generatedAccountInfo.Derived, err = accGenerator.DeriveAddresses(generatedAccountInfo.ID, paths)
|
||||
require.NoError(s.T(), err)
|
||||
displayName, err := common.RandomAlphabeticalString(8)
|
||||
s.Require().NoError(err)
|
||||
|
||||
deviceName, err := common.RandomAlphanumericString(8)
|
||||
s.Require().NoError(err)
|
||||
|
||||
createAccount := requests.CreateAccount{
|
||||
RootDataDir: tmpdir,
|
||||
KdfIterations: dbsetup.ReducedKDFIterationsNumber,
|
||||
DisplayName: displayName,
|
||||
DeviceName: deviceName,
|
||||
Password: s.password,
|
||||
CustomizationColor: "primary",
|
||||
}
|
||||
|
||||
if mnemonic == "" {
|
||||
_, err = backend.CreateAccountAndLogin(&createAccount)
|
||||
} else {
|
||||
generatedAccountInfos, err := accGenerator.GenerateAndDeriveAddresses(12, 1, "", paths)
|
||||
require.NoError(s.T(), err)
|
||||
generatedAccountInfo = generatedAccountInfos[0]
|
||||
}
|
||||
account := multiaccounts.Account{
|
||||
KeyUID: generatedAccountInfo.KeyUID,
|
||||
KDFIterations: dbsetup.ReducedKDFIterationsNumber,
|
||||
}
|
||||
err = accountManager.InitKeystore(filepath.Join(tmpdir, keystoreDir, account.KeyUID))
|
||||
require.NoError(s.T(), err)
|
||||
err = backend.OpenAccounts()
|
||||
require.NoError(s.T(), err)
|
||||
derivedAddresses := generatedAccountInfo.Derived
|
||||
_, err = accGenerator.StoreDerivedAccounts(generatedAccountInfo.ID, s.password, paths)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
settings, err := defaultSettings(generatedAccountInfo.GeneratedAccountInfo, derivedAddresses, nil)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
account.Name = settings.Name
|
||||
|
||||
nodeConfig, err := nodeConfigForLocalPairSync(settings.InstallationID, account.KeyUID, tmpdir)
|
||||
nodeConfig.RootDataDir = tmpdir
|
||||
require.NoError(s.T(), err)
|
||||
require.NoError(s.T(), setDefaultNodeConfig(nodeConfig))
|
||||
|
||||
walletDerivedAccount := derivedAddresses[pathDefaultWallet]
|
||||
walletAccount := &accounts.Account{
|
||||
PublicKey: types.Hex2Bytes(walletDerivedAccount.PublicKey),
|
||||
KeyUID: generatedAccountInfo.KeyUID,
|
||||
Address: types.HexToAddress(walletDerivedAccount.Address),
|
||||
ColorID: "",
|
||||
Wallet: true,
|
||||
Path: pathDefaultWallet,
|
||||
Name: "Ethereum account",
|
||||
_, err = backend.RestoreAccountAndLogin(&requests.RestoreAccount{
|
||||
Mnemonic: mnemonic,
|
||||
FetchBackup: false,
|
||||
CreateAccount: createAccount,
|
||||
})
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
s.Require().NoError(err)
|
||||
|
||||
accounts := []*accounts.Account{walletAccount, chatAccount}
|
||||
err = backend.StartNodeWithAccountAndInitialConfig(account, s.password, *settings, nodeConfig, accounts, nil)
|
||||
require.NoError(s.T(), err)
|
||||
multiaccounts, err := backend.GetAccounts()
|
||||
require.NoError(s.T(), err)
|
||||
require.NotEmpty(s.T(), multiaccounts[0].ColorHash)
|
||||
accs, err := backend.GetAccounts()
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotEmpty(accs[0].ColorHash)
|
||||
|
||||
return backend
|
||||
}
|
||||
|
@ -163,7 +120,7 @@ func (s *SyncDeviceSuite) pairAccounts(serverBackend *api.GethStatusBackend, ser
|
|||
serverActiveAccount, err := serverBackend.GetActiveAccount()
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
serverKeystorePath := filepath.Join(serverDir, keystoreDir, serverActiveAccount.KeyUID)
|
||||
serverKeystorePath := filepath.Join(serverDir, api.DefaultKeystoreRelativePath, serverActiveAccount.KeyUID)
|
||||
serverConfig := &SenderServerConfig{
|
||||
SenderConfig: &SenderConfig{
|
||||
KeystorePath: serverKeystorePath,
|
||||
|
@ -182,27 +139,21 @@ func (s *SyncDeviceSuite) pairAccounts(serverBackend *api.GethStatusBackend, ser
|
|||
|
||||
// Start receiving client
|
||||
|
||||
err = clientBackend.AccountManager().InitKeystore(filepath.Join(clientDir, keystoreDir))
|
||||
err = clientBackend.AccountManager().InitKeystore(filepath.Join(clientDir, api.DefaultKeystoreRelativePath))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = clientBackend.OpenAccounts()
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
clientNodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", clientDir)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
clientKeystoreDir := filepath.Join(clientDir, keystoreDir)
|
||||
clientPayloadSourceConfig := ReceiverClientConfig{
|
||||
ReceiverConfig: &ReceiverConfig{
|
||||
KeystorePath: clientKeystoreDir,
|
||||
DeviceType: "desktop",
|
||||
KDFIterations: expectedKDFIterations,
|
||||
NodeConfig: clientNodeConfig,
|
||||
SettingCurrentNetwork: currentNetwork,
|
||||
CreateAccount: &requests.CreateAccount{
|
||||
RootDataDir: clientDir,
|
||||
KdfIterations: expectedKDFIterations,
|
||||
},
|
||||
},
|
||||
ClientConfig: new(ClientConfig),
|
||||
}
|
||||
clientNodeConfig.RootDataDir = clientDir
|
||||
|
||||
clientConfigBytes, err := json.Marshal(clientPayloadSourceConfig)
|
||||
require.NoError(s.T(), err)
|
||||
|
@ -287,24 +238,21 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsSender() {
|
|||
}()
|
||||
ctx := context.TODO()
|
||||
|
||||
err := serverBackend.AccountManager().InitKeystore(filepath.Join(serverTmpDir, keystoreDir))
|
||||
err := serverBackend.AccountManager().InitKeystore(filepath.Join(serverTmpDir, api.DefaultKeystoreRelativePath))
|
||||
require.NoError(s.T(), err)
|
||||
err = serverBackend.OpenAccounts()
|
||||
require.NoError(s.T(), err)
|
||||
serverNodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", serverTmpDir)
|
||||
require.NoError(s.T(), err)
|
||||
serverKeystoreDir := filepath.Join(serverTmpDir, keystoreDir)
|
||||
|
||||
serverPayloadSourceConfig := &ReceiverServerConfig{
|
||||
ReceiverConfig: &ReceiverConfig{
|
||||
NodeConfig: serverNodeConfig,
|
||||
KeystorePath: serverKeystoreDir,
|
||||
DeviceType: "desktop",
|
||||
KDFIterations: expectedKDFIterations,
|
||||
SettingCurrentNetwork: currentNetwork,
|
||||
CreateAccount: &requests.CreateAccount{
|
||||
RootDataDir: serverTmpDir,
|
||||
KdfIterations: expectedKDFIterations,
|
||||
},
|
||||
},
|
||||
ServerConfig: new(ServerConfig),
|
||||
}
|
||||
serverNodeConfig.RootDataDir = serverTmpDir
|
||||
|
||||
serverConfigBytes, err := json.Marshal(serverPayloadSourceConfig)
|
||||
require.NoError(s.T(), err)
|
||||
cs, err := StartUpReceiverServer(serverBackend, string(serverConfigBytes))
|
||||
|
@ -330,7 +278,7 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsSender() {
|
|||
// startup sending client
|
||||
clientActiveAccount, err := clientBackend.GetActiveAccount()
|
||||
require.NoError(s.T(), err)
|
||||
clientKeystorePath := filepath.Join(clientTmpDir, keystoreDir, clientActiveAccount.KeyUID)
|
||||
clientKeystorePath := filepath.Join(clientTmpDir, api.DefaultKeystoreRelativePath, clientActiveAccount.KeyUID)
|
||||
clientPayloadSourceConfig := SenderClientConfig{
|
||||
SenderConfig: &SenderConfig{
|
||||
KeystorePath: clientKeystorePath,
|
||||
|
@ -367,14 +315,17 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsSender() {
|
|||
|
||||
serverActiveAccount, err := serverBackend.GetActiveAccount()
|
||||
require.NoError(s.T(), err)
|
||||
require.Equal(s.T(), serverActiveAccount.Name, clientActiveAccount.Name)
|
||||
require.Equal(s.T(), serverActiveAccount.KDFIterations, expectedKDFIterations)
|
||||
require.Equal(s.T(), clientActiveAccount.Name, serverActiveAccount.Name)
|
||||
require.Equal(s.T(), expectedKDFIterations, serverActiveAccount.KDFIterations)
|
||||
|
||||
serverMessenger := serverBackend.Messenger()
|
||||
clientMessenger := clientBackend.Messenger()
|
||||
require.True(s.T(), serverMessenger.HasPairedDevices())
|
||||
require.True(s.T(), clientMessenger.HasPairedDevices())
|
||||
|
||||
serverNodeConfig, err := serverBackend.GetNodeConfig()
|
||||
s.Require().NoError(err)
|
||||
|
||||
err = clientMessenger.DisableInstallation(serverNodeConfig.ShhextConfig.InstallationID)
|
||||
require.NoError(s.T(), err)
|
||||
require.False(s.T(), clientMessenger.HasPairedDevices())
|
||||
|
@ -415,7 +366,7 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsReceiver() {
|
|||
|
||||
serverActiveAccount, err := serverBackend.GetActiveAccount()
|
||||
require.NoError(s.T(), err)
|
||||
serverKeystorePath := filepath.Join(serverTmpDir, keystoreDir, serverActiveAccount.KeyUID)
|
||||
serverKeystorePath := filepath.Join(serverTmpDir, api.DefaultKeystoreRelativePath, serverActiveAccount.KeyUID)
|
||||
var config = &SenderServerConfig{
|
||||
SenderConfig: &SenderConfig{
|
||||
KeystorePath: serverKeystorePath,
|
||||
|
@ -462,24 +413,21 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsReceiver() {
|
|||
_, err = serverMessenger.DeleteMessageForMeAndSync(ctx, publicChatID, serverMessageID)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
err = clientBackend.AccountManager().InitKeystore(filepath.Join(clientTmpDir, keystoreDir))
|
||||
err = clientBackend.AccountManager().InitKeystore(filepath.Join(clientTmpDir, api.DefaultKeystoreRelativePath))
|
||||
require.NoError(s.T(), err)
|
||||
err = clientBackend.OpenAccounts()
|
||||
require.NoError(s.T(), err)
|
||||
clientNodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", clientTmpDir)
|
||||
require.NoError(s.T(), err)
|
||||
clientKeystoreDir := filepath.Join(clientTmpDir, keystoreDir)
|
||||
|
||||
clientPayloadSourceConfig := ReceiverClientConfig{
|
||||
ReceiverConfig: &ReceiverConfig{
|
||||
KeystorePath: clientKeystoreDir,
|
||||
DeviceType: "iphone",
|
||||
KDFIterations: expectedKDFIterations,
|
||||
NodeConfig: clientNodeConfig,
|
||||
SettingCurrentNetwork: currentNetwork,
|
||||
CreateAccount: &requests.CreateAccount{
|
||||
RootDataDir: clientTmpDir,
|
||||
KdfIterations: expectedKDFIterations,
|
||||
DeviceName: "device-1",
|
||||
},
|
||||
},
|
||||
ClientConfig: new(ClientConfig),
|
||||
}
|
||||
clientNodeConfig.RootDataDir = clientTmpDir
|
||||
clientConfigBytes, err := json.Marshal(clientPayloadSourceConfig)
|
||||
require.NoError(s.T(), err)
|
||||
err = StartUpReceivingClient(clientBackend, cs, string(clientConfigBytes))
|
||||
|
@ -514,9 +462,13 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsReceiver() {
|
|||
require.True(s.T(), serverMessenger.HasPairedDevices())
|
||||
require.True(s.T(), clientMessenger.HasPairedDevices())
|
||||
|
||||
clientNodeConfig, err := clientBackend.GetNodeConfig()
|
||||
s.Require().NoError(err)
|
||||
|
||||
err = serverMessenger.DisableInstallation(clientNodeConfig.ShhextConfig.InstallationID)
|
||||
require.NoError(s.T(), err)
|
||||
require.False(s.T(), serverMessenger.HasPairedDevices())
|
||||
|
||||
serverNodeConfig, err := serverBackend.GetNodeConfig()
|
||||
require.NoError(s.T(), err)
|
||||
err = clientMessenger.DisableInstallation(serverNodeConfig.ShhextConfig.InstallationID)
|
||||
|
@ -739,77 +691,6 @@ func (s *SyncDeviceSuite) TestPairAcceptContactRequest() {
|
|||
})
|
||||
}
|
||||
|
||||
func defaultSettings(generatedAccountInfo generator.GeneratedAccountInfo, derivedAddresses map[string]generator.AccountInfo, mnemonic *string) (*settings.Settings, error) {
|
||||
chatKeyString := derivedAddresses[pathDefaultChat].PublicKey
|
||||
|
||||
syncSettings := &settings.Settings{}
|
||||
syncSettings.KeyUID = generatedAccountInfo.KeyUID
|
||||
syncSettings.Address = types.HexToAddress(generatedAccountInfo.Address)
|
||||
syncSettings.WalletRootAddress = types.HexToAddress(derivedAddresses[pathWalletRoot].Address)
|
||||
|
||||
// Set chat key & name
|
||||
name, err := alias.GenerateFromPublicKeyString(chatKeyString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
syncSettings.Name = name
|
||||
syncSettings.PublicKey = chatKeyString
|
||||
|
||||
syncSettings.DappsAddress = types.HexToAddress(derivedAddresses[pathDefaultWallet].Address)
|
||||
syncSettings.EIP1581Address = types.HexToAddress(derivedAddresses[pathEIP1581].Address)
|
||||
syncSettings.Mnemonic = mnemonic
|
||||
|
||||
syncSettings.SigningPhrase = "balabala"
|
||||
|
||||
syncSettings.SendPushNotifications = true
|
||||
syncSettings.InstallationID = uuid.New().String()
|
||||
syncSettings.UseMailservers = true
|
||||
|
||||
syncSettings.PreviewPrivacy = true
|
||||
syncSettings.Currency = "usd"
|
||||
syncSettings.ProfilePicturesVisibility = 1
|
||||
syncSettings.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)
|
||||
syncSettings.WalletVisibleTokens = &visibleTokenJSONRaw
|
||||
|
||||
networks := `[{"id":"goerli_rpc","chain-explorer-link":"https://goerli.etherscan.io/address/","name":"Goerli with upstream RPC","config":{"NetworkId":5,"DataDir":"/ethereum/goerli_rpc","UpstreamConfig":{"Enabled":true,"URL":"https://goerli-archival.rpc.grove.city/v1/3ef2018191814b7e1009b8d9"}}},{"id":"mainnet_rpc","chain-explorer-link":"https://etherscan.io/address/","name":"Mainnet with upstream RPC","config":{"NetworkId":1,"DataDir":"/ethereum/mainnet_rpc","UpstreamConfig":{"Enabled":true,"URL":"https://eth-archival.rpc.grove.city/v1/3ef2018191814b7e1009b8d9"}}}]`
|
||||
var networksRawMessage json.RawMessage = []byte(networks)
|
||||
syncSettings.Networks = &networksRawMessage
|
||||
syncSettings.CurrentNetwork = currentNetwork
|
||||
|
||||
return syncSettings, nil
|
||||
}
|
||||
|
||||
func nodeConfigForLocalPairSync(installationID, keyUID, tmpDir string) (*params.NodeConfig, error) {
|
||||
// Set mainnet
|
||||
nodeConfig := ¶ms.NodeConfig{}
|
||||
nodeConfig.LogEnabled = true
|
||||
nodeConfig.LogLevel = "DEBUG"
|
||||
nodeConfig.LogDir = tmpDir
|
||||
nodeConfig.KeyStoreDir = filepath.Join(keystoreDir, keyUID)
|
||||
nodeConfig.KeycardPairingDataFile = filepath.Join("keycard", "pairings.json")
|
||||
nodeConfig.ShhextConfig = params.ShhextConfig{
|
||||
InstallationID: installationID,
|
||||
}
|
||||
|
||||
// need specify cluster config here, otherwise TestPairingThreeDevices will fail due to no messages(CR) received
|
||||
// TODO(frank) need to figure out why above happen
|
||||
clusterConfig, err := params.LoadClusterConfigFromFleet(params.FleetProd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nodeConfig.ClusterConfig = *clusterConfig
|
||||
|
||||
return nodeConfig, nil
|
||||
}
|
||||
|
||||
type testTimeSource struct{}
|
||||
|
||||
func (t *testTimeSource) GetCurrentTime() uint64 {
|
||||
|
@ -926,14 +807,14 @@ func (s *SyncDeviceSuite) TestTransferringKeystoreFiles() {
|
|||
require.NoError(s.T(), err, "saving seed phrase keypair on client without keystore files")
|
||||
|
||||
// check server - server should contain keystore files for imported seed phrase
|
||||
serverKeystorePath := filepath.Join(serverTmpDir, keystoreDir, serverActiveAccount.KeyUID)
|
||||
serverKeystorePath := filepath.Join(serverTmpDir, api.DefaultKeystoreRelativePath, serverActiveAccount.KeyUID)
|
||||
require.True(s.T(), containsKeystoreFile(serverKeystorePath, serverSeedPhraseKp.DerivedFrom[2:]))
|
||||
for _, acc := range serverSeedPhraseKp.Accounts {
|
||||
require.True(s.T(), containsKeystoreFile(serverKeystorePath, acc.Address.String()[2:]))
|
||||
}
|
||||
|
||||
// check client - client should not contain keystore files for imported seed phrase
|
||||
clientKeystorePath := filepath.Join(clientTmpDir, keystoreDir, clientActiveAccount.KeyUID)
|
||||
clientKeystorePath := filepath.Join(clientTmpDir, api.DefaultKeystoreRelativePath, clientActiveAccount.KeyUID)
|
||||
require.False(s.T(), containsKeystoreFile(clientKeystorePath, clientSeedPhraseKp.DerivedFrom[2:]))
|
||||
for _, acc := range clientSeedPhraseKp.Accounts {
|
||||
require.False(s.T(), containsKeystoreFile(clientKeystorePath, acc.Address.String()[2:]))
|
||||
|
@ -1122,14 +1003,14 @@ func (s *SyncDeviceSuite) TestTransferringKeystoreFilesAfterStopUisngKeycard() {
|
|||
len(serverKp.Keycards) == len(clientKp.Keycards))
|
||||
|
||||
// Check server - server should contain keystore files for imported seed phrase
|
||||
serverKeystorePath := filepath.Join(serverTmpDir, keystoreDir, serverActiveAccount.KeyUID)
|
||||
serverKeystorePath := filepath.Join(serverTmpDir, api.DefaultKeystoreRelativePath, serverActiveAccount.KeyUID)
|
||||
require.True(s.T(), containsKeystoreFile(serverKeystorePath, serverKp.DerivedFrom[2:]))
|
||||
for _, acc := range serverKp.Accounts {
|
||||
require.True(s.T(), containsKeystoreFile(serverKeystorePath, acc.Address.String()[2:]))
|
||||
}
|
||||
|
||||
// Check client - client should not contain keystore files for imported seed phrase
|
||||
clientKeystorePath := filepath.Join(clientTmpDir, keystoreDir, clientActiveAccount.KeyUID)
|
||||
clientKeystorePath := filepath.Join(clientTmpDir, api.DefaultKeystoreRelativePath, clientActiveAccount.KeyUID)
|
||||
require.False(s.T(), containsKeystoreFile(clientKeystorePath, clientKp.DerivedFrom[2:]))
|
||||
for _, acc := range clientKp.Accounts {
|
||||
require.False(s.T(), containsKeystoreFile(clientKeystorePath, acc.Address.String()[2:]))
|
||||
|
@ -1306,7 +1187,7 @@ func (s *SyncDeviceSuite) TestPreventLoggedInAccountLocalPairingClientAsReceiver
|
|||
|
||||
serverActiveAccount, err := serverBackend.GetActiveAccount()
|
||||
s.NoError(err)
|
||||
serverKeystorePath := filepath.Join(serverTmpDir, keystoreDir, serverActiveAccount.KeyUID)
|
||||
serverKeystorePath := filepath.Join(serverTmpDir, api.DefaultKeystoreRelativePath, serverActiveAccount.KeyUID)
|
||||
var config = &SenderServerConfig{
|
||||
SenderConfig: &SenderConfig{
|
||||
KeystorePath: serverKeystorePath,
|
||||
|
@ -1321,20 +1202,16 @@ func (s *SyncDeviceSuite) TestPreventLoggedInAccountLocalPairingClientAsReceiver
|
|||
cs, err := StartUpSenderServer(serverBackend, string(configBytes))
|
||||
s.NoError(err)
|
||||
|
||||
clientKeystoreDir := filepath.Join(clientTmpDir, keystoreDir)
|
||||
clientNodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", clientTmpDir)
|
||||
s.NoError(err)
|
||||
clientPayloadSourceConfig := ReceiverClientConfig{
|
||||
ReceiverConfig: &ReceiverConfig{
|
||||
KeystorePath: clientKeystoreDir,
|
||||
DeviceType: "iphone",
|
||||
KDFIterations: expectedKDFIterations,
|
||||
NodeConfig: clientNodeConfig,
|
||||
SettingCurrentNetwork: currentNetwork,
|
||||
CreateAccount: &requests.CreateAccount{
|
||||
RootDataDir: clientTmpDir,
|
||||
KdfIterations: expectedKDFIterations,
|
||||
DeviceName: "client-device",
|
||||
},
|
||||
},
|
||||
ClientConfig: new(ClientConfig),
|
||||
}
|
||||
clientNodeConfig.RootDataDir = clientTmpDir
|
||||
clientConfigBytes, err := json.Marshal(clientPayloadSourceConfig)
|
||||
s.NoError(err)
|
||||
err = StartUpReceivingClient(clientBackend, cs, string(clientConfigBytes))
|
||||
|
@ -1351,20 +1228,17 @@ func (s *SyncDeviceSuite) TestPreventLoggedInAccountLocalPairingClientAsSender()
|
|||
s.NoError(clientBackend.Logout())
|
||||
}()
|
||||
|
||||
serverNodeConfig, err := nodeConfigForLocalPairSync(uuid.New().String(), "", serverTmpDir)
|
||||
s.NoError(err)
|
||||
serverKeystoreDir := filepath.Join(serverTmpDir, keystoreDir)
|
||||
serverPayloadSourceConfig := &ReceiverServerConfig{
|
||||
ReceiverConfig: &ReceiverConfig{
|
||||
NodeConfig: serverNodeConfig,
|
||||
KeystorePath: serverKeystoreDir,
|
||||
DeviceType: "desktop",
|
||||
KDFIterations: expectedKDFIterations,
|
||||
SettingCurrentNetwork: currentNetwork,
|
||||
CreateAccount: &requests.CreateAccount{
|
||||
RootDataDir: serverTmpDir,
|
||||
KdfIterations: expectedKDFIterations,
|
||||
DeviceName: "server-device",
|
||||
},
|
||||
},
|
||||
ServerConfig: new(ServerConfig),
|
||||
}
|
||||
serverNodeConfig.RootDataDir = serverTmpDir
|
||||
|
||||
serverConfigBytes, err := json.Marshal(serverPayloadSourceConfig)
|
||||
s.NoError(err)
|
||||
cs, err := StartUpReceiverServer(serverBackend, string(serverConfigBytes))
|
||||
|
@ -1372,7 +1246,7 @@ func (s *SyncDeviceSuite) TestPreventLoggedInAccountLocalPairingClientAsSender()
|
|||
|
||||
clientActiveAccount, err := clientBackend.GetActiveAccount()
|
||||
s.NoError(err)
|
||||
clientKeystorePath := filepath.Join(clientTmpDir, keystoreDir, clientActiveAccount.KeyUID)
|
||||
clientKeystorePath := filepath.Join(clientTmpDir, api.DefaultKeystoreRelativePath, clientActiveAccount.KeyUID)
|
||||
clientPayloadSourceConfig := SenderClientConfig{
|
||||
SenderConfig: &SenderConfig{
|
||||
KeystorePath: clientKeystorePath,
|
||||
|
|
Loading…
Reference in New Issue