package protocol import ( "context" "time" "github.com/golang/protobuf/proto" gethcommon "github.com/ethereum/go-ethereum/common" multiAccCommon "github.com/status-im/status-go/multiaccounts/common" "github.com/status-im/status-go/protocol/common" "github.com/status-im/status-go/protocol/protobuf" v1protocol "github.com/status-im/status-go/protocol/v1" "github.com/status-im/status-go/services/wallet" ) func (m *Messenger) UpsertSavedAddress(ctx context.Context, sa wallet.SavedAddress) error { sa.UpdateClock, _ = m.getLastClockWithRelatedChat() err := m.savedAddressesManager.UpdateMetadataAndUpsertSavedAddress(sa) if err != nil { return err } return m.syncNewSavedAddress(ctx, &sa, sa.UpdateClock, m.dispatchMessage) } func (m *Messenger) DeleteSavedAddress(ctx context.Context, address gethcommon.Address, isTest bool) error { updateClock, _ := m.getLastClockWithRelatedChat() _, err := m.savedAddressesManager.DeleteSavedAddress(address, isTest, updateClock) if err != nil { return err } return m.syncDeletedSavedAddress(ctx, address, isTest, updateClock, m.dispatchMessage) } func (m *Messenger) GetSavedAddresses(ctx context.Context) ([]*wallet.SavedAddress, error) { return m.savedAddressesManager.GetSavedAddresses() } func (m *Messenger) GetSavedAddressesPerMode(isTest bool) ([]*wallet.SavedAddress, error) { return m.savedAddressesManager.GetSavedAddressesPerMode(isTest) } func (m *Messenger) RemainingCapacityForSavedAddresses(testnetMode bool) (int, error) { return m.savedAddressesManager.RemainingCapacityForSavedAddresses(testnetMode) } func (m *Messenger) garbageCollectRemovedSavedAddresses() error { return m.savedAddressesManager.DeleteSoftRemovedSavedAddresses(uint64(time.Now().AddDate(0, 0, -30).Unix())) } func (m *Messenger) dispatchSyncSavedAddress(ctx context.Context, syncMessage *protobuf.SyncSavedAddress, rawMessageHandler RawMessageHandler) error { if !m.hasPairedDevices() { return nil } clock, chat := m.getLastClockWithRelatedChat() encodedMessage, err := proto.Marshal(syncMessage) if err != nil { return err } rawMessage := common.RawMessage{ LocalChatID: chat.ID, Payload: encodedMessage, MessageType: protobuf.ApplicationMetadataMessage_SYNC_SAVED_ADDRESS, ResendType: common.ResendTypeDataSync, } _, err = rawMessageHandler(ctx, rawMessage) if err != nil { return err } chat.LastClockValue = clock return m.saveChat(chat) } func (m *Messenger) syncNewSavedAddress(ctx context.Context, savedAddress *wallet.SavedAddress, updateClock uint64, rawMessageHandler RawMessageHandler) error { return m.dispatchSyncSavedAddress(ctx, &protobuf.SyncSavedAddress{ Address: savedAddress.Address.Bytes(), Name: savedAddress.Name, Removed: savedAddress.Removed, UpdateClock: updateClock, ChainShortNames: savedAddress.ChainShortNames, Ens: savedAddress.ENSName, IsTest: savedAddress.IsTest, Color: string(savedAddress.ColorID), }, rawMessageHandler) } func (m *Messenger) syncDeletedSavedAddress(ctx context.Context, address gethcommon.Address, isTest bool, updateClock uint64, rawMessageHandler RawMessageHandler) error { return m.dispatchSyncSavedAddress(ctx, &protobuf.SyncSavedAddress{ Address: address.Bytes(), UpdateClock: updateClock, Removed: true, IsTest: isTest, }, rawMessageHandler) } func (m *Messenger) syncSavedAddress(ctx context.Context, savedAddress *wallet.SavedAddress, rawMessageHandler RawMessageHandler) (err error) { if savedAddress.Removed { if err = m.syncDeletedSavedAddress(ctx, savedAddress.Address, savedAddress.IsTest, savedAddress.UpdateClock, rawMessageHandler); err != nil { return err } } else { if err = m.syncNewSavedAddress(ctx, savedAddress, savedAddress.UpdateClock, rawMessageHandler); err != nil { return err } } return } func (m *Messenger) HandleSyncSavedAddress(state *ReceivedMessageState, syncMessage *protobuf.SyncSavedAddress, statusMessage *v1protocol.StatusMessage) (err error) { address := gethcommon.BytesToAddress(syncMessage.Address) if syncMessage.Removed { deleted, err := m.savedAddressesManager.DeleteSavedAddress( address, syncMessage.IsTest, syncMessage.UpdateClock) if err != nil { return err } if deleted { state.Response.AddSavedAddress(&wallet.SavedAddress{Address: address, ENSName: syncMessage.Ens, IsTest: syncMessage.IsTest, Removed: true}) } } else { sa := wallet.SavedAddress{ Address: address, Name: syncMessage.Name, ChainShortNames: syncMessage.ChainShortNames, ENSName: syncMessage.Ens, IsTest: syncMessage.IsTest, ColorID: multiAccCommon.CustomizationColor(syncMessage.Color), } sa.UpdateClock = syncMessage.UpdateClock added, err := m.savedAddressesManager.AddSavedAddressIfNewerUpdate(sa) if err != nil { return err } if added { state.Response.AddSavedAddress(&sa) } } return }