Files
Igor Sirotin f9cc782a6f refactor: move services to pkg/services
Part of the Go project layout migration, item 31.

Pure move plus import-path rewrite across 687 files. No API or behaviour
change.

The services keep their grouping under pkg/services/<name> rather than
being promoted to pkg/<name>: 27 top-level directories in pkg/ would read
worse than what we have, and the grouping is what makes "an RPC service"
identifiable at a glance.

Paths that follow the move: the logosstorage test target and generate
step, the two wallet token-list tools, the migration-order check (and the
pre-rebase hook symlinked to it), and the storage env helper.

refs #7067
2026-08-21 10:11:05 +02:00

147 lines
4.7 KiB
Go

package syncing
import (
"encoding/json"
"errors"
"go.uber.org/zap"
gethcommon "github.com/ethereum/go-ethereum/common"
accsmanagementtypes "github.com/status-im/status-go/internal/accounts-management/types"
"github.com/status-im/status-go/internal/crypto/types"
"github.com/status-im/status-go/internal/db/multiaccounts/accounts"
multiaccountscommon "github.com/status-im/status-go/internal/db/multiaccounts/common"
maErrors "github.com/status-im/status-go/internal/db/multiaccounts/errors"
"github.com/status-im/status-go/internal/db/multiaccounts/settings"
"github.com/status-im/status-go/internal/protocol/protobuf"
"github.com/status-im/status-go/pkg/pubsub"
"github.com/status-im/status-go/pkg/services/accounts/accountsevent"
)
// TODO move this code out of the protocol package
// https://github.com/status-im/status-go/pull/6967#discussion_r2391383496
var (
ErrNotWatchOnlyAccount = errors.New("an account is not a watch only account")
ErrTryingToStoreOldWalletAccount = errors.New("trying to store an old wallet account")
)
func MapSyncAccountToAccount(message *protobuf.SyncAccount, accountOperability accsmanagementtypes.AccountOperable,
accType accsmanagementtypes.AccountType) *accsmanagementtypes.Account {
return &accsmanagementtypes.Account{
Address: types.BytesToAddress(message.Address),
KeyUID: message.KeyUid,
PublicKey: types.HexBytes(message.PublicKey),
Type: accType,
Path: message.Path,
Name: message.Name,
ColorID: multiaccountscommon.CustomizationColor(message.ColorId),
Emoji: message.Emoji,
Wallet: message.Wallet,
Chat: message.Chat,
Hidden: message.Hidden,
Clock: message.Clock,
Operable: accountOperability,
Removed: message.Removed,
Position: message.Position,
ProdPreferredChainIDs: message.ProdPreferredChainIDs,
TestPreferredChainIDs: message.TestPreferredChainIDs,
}
}
func HandleSyncWatchOnlyAccount(accountsDB *accounts.Database, message *protobuf.SyncAccount, accountsPublisher *pubsub.Publisher) (*accsmanagementtypes.Account, error) {
if message.KeyUid != "" {
return nil, ErrNotWatchOnlyAccount
}
accountOperability := accsmanagementtypes.AccountFullyOperable
accAddress := types.BytesToAddress(message.Address)
dbAccount, err := accountsDB.GetAccountByAddress(accAddress)
if err != nil && err != accounts.ErrDbAccountNotFound {
return nil, err
}
if dbAccount != nil {
if message.Clock <= dbAccount.Clock {
return nil, ErrTryingToStoreOldWalletAccount
}
if message.Removed {
err = accountsDB.RemoveAccount(accAddress, message.Clock)
if err != nil {
return nil, err
}
err = accountsDB.ResolveAccountsPositions(message.Clock)
if err != nil {
return nil, err
}
dbAccount.Removed = true
return dbAccount, nil
}
}
acc := MapSyncAccountToAccount(message, accountOperability, accsmanagementtypes.AccountTypeWatch)
err = accountsDB.SaveOrUpdateAccounts([]*accsmanagementtypes.Account{acc}, false)
if err != nil {
return nil, err
}
if accountsPublisher != nil {
payload := []gethcommon.Address{gethcommon.Address(acc.Address)}
if acc.Removed {
pubsub.Publish(accountsPublisher, accountsevent.AccountsRemovedEvent{
Accounts: payload,
})
} else {
pubsub.Publish(accountsPublisher, accountsevent.AccountsAddedEvent{
Accounts: payload,
})
}
}
return acc, nil
}
// extractSyncSetting parses incoming *protobuf.SyncSetting and stores the setting data if needed
func ExtractAndSaveSyncSetting(accountsDB *accounts.Database, logger *zap.Logger, syncSetting *protobuf.SyncSetting) (*settings.SyncSettingField, error) {
sf, err := settings.GetFieldFromProtobufType(syncSetting.Type)
if err != nil {
logger.Error(
"extractSyncSetting - settings.GetFieldFromProtobufType",
zap.Error(err),
zap.Any("syncSetting", syncSetting),
)
return nil, err
}
spf := sf.SyncProtobufFactory()
if spf == nil {
logger.Warn("extractSyncSetting - received protobuf for setting with no SyncProtobufFactory")
return nil, nil
}
if spf.Inactive() {
logger.Warn("extractSyncSetting - received protobuf for inactive sync setting")
return nil, nil
}
value := spf.ExtractValueFromProtobuf()(syncSetting)
err = accountsDB.SaveSyncSetting(sf, value, syncSetting.Clock)
if err == maErrors.ErrNewClockOlderThanCurrent {
logger.Info("extractSyncSetting - SaveSyncSetting :", zap.Error(err))
return nil, nil
}
if err != nil {
return nil, err
}
if v, ok := value.([]byte); ok {
value = json.RawMessage(v)
}
return &settings.SyncSettingField{SettingField: sf, Value: value}, nil
}