slidge-whatsapp 0.3.0b0__cp312-cp312-manylinux_2_36_aarch64.whl → 0.3.4__cp312-cp312-manylinux_2_36_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of slidge-whatsapp might be problematic. Click here for more details.

Files changed (167) hide show
  1. slidge_whatsapp/contact.py +2 -0
  2. slidge_whatsapp/event.go +72 -22
  3. slidge_whatsapp/generated/_whatsapp.cpython-312-aarch64-linux-gnu.h +175 -175
  4. slidge_whatsapp/generated/_whatsapp.cpython-312-aarch64-linux-gnu.so +0 -0
  5. slidge_whatsapp/generated/build.py +139 -139
  6. slidge_whatsapp/generated/go.py +1 -1
  7. slidge_whatsapp/generated/whatsapp.c +1513 -1513
  8. slidge_whatsapp/generated/whatsapp.go +1227 -1227
  9. slidge_whatsapp/generated/whatsapp.py +1382 -1382
  10. slidge_whatsapp/generated/whatsapp_go.h +175 -175
  11. slidge_whatsapp/go.mod +11 -11
  12. slidge_whatsapp/go.sum +26 -26
  13. slidge_whatsapp/session.go +4 -4
  14. slidge_whatsapp/vendor/github.com/ebitengine/purego/README.md +21 -5
  15. slidge_whatsapp/vendor/github.com/ebitengine/purego/abi_loong64.h +60 -0
  16. slidge_whatsapp/vendor/github.com/ebitengine/purego/cgo.go +1 -1
  17. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlerror.go +1 -1
  18. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn.go +1 -1
  19. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn_netbsd.go +15 -0
  20. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn_nocgo_netbsd.go +9 -0
  21. slidge_whatsapp/vendor/github.com/ebitengine/purego/dlfcn_stubs.s +1 -1
  22. slidge_whatsapp/vendor/github.com/ebitengine/purego/func.go +113 -60
  23. slidge_whatsapp/vendor/github.com/ebitengine/purego/gen.go +6 -0
  24. slidge_whatsapp/vendor/github.com/ebitengine/purego/go_runtime.go +1 -1
  25. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/cgo/dlfcn_cgo_unix.go +2 -2
  26. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go +2 -2
  27. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/abi_loong64.h +60 -0
  28. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/asm_loong64.s +40 -0
  29. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go +1 -1
  30. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go +1 -1
  31. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go +1 -1
  32. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_loong64.go +92 -0
  33. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_netbsd.go +106 -0
  34. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go +1 -1
  35. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go +1 -1
  36. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go +1 -1
  37. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go +1 -1
  38. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go +4 -0
  39. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go +4 -0
  40. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go +4 -0
  41. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_netbsd.go +26 -0
  42. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/netbsd.go +23 -0
  43. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go +1 -1
  44. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols.go +11 -1
  45. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_darwin.go +1 -0
  46. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_freebsd.go +1 -0
  47. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_linux.go +1 -0
  48. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_netbsd.go +30 -0
  49. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_loong64.s +71 -0
  50. slidge_whatsapp/vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_stubs.s +5 -1
  51. slidge_whatsapp/vendor/github.com/ebitengine/purego/nocgo.go +1 -1
  52. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_amd64.go +8 -4
  53. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_arm64.go +16 -6
  54. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_loong64.go +190 -0
  55. slidge_whatsapp/vendor/github.com/ebitengine/purego/struct_other.go +6 -2
  56. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_amd64.s +1 -1
  57. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_arm64.s +1 -1
  58. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_loong64.s +96 -0
  59. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_unix_arm64.s +1 -1
  60. slidge_whatsapp/vendor/github.com/ebitengine/purego/sys_unix_loong64.s +75 -0
  61. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall.go +6 -3
  62. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall_cgo_linux.go +3 -3
  63. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall_sysv.go +13 -10
  64. slidge_whatsapp/vendor/github.com/ebitengine/purego/syscall_windows.go +1 -1
  65. slidge_whatsapp/vendor/github.com/ebitengine/purego/zcallback_amd64.s +2002 -2002
  66. slidge_whatsapp/vendor/github.com/ebitengine/purego/zcallback_arm64.s +4002 -4002
  67. slidge_whatsapp/vendor/github.com/ebitengine/purego/zcallback_loong64.s +4014 -0
  68. slidge_whatsapp/vendor/go.mau.fi/libsignal/session/SessionCipher.go +7 -2
  69. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/log.go +1 -0
  70. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/module.go +119 -0
  71. slidge_whatsapp/vendor/go.mau.fi/util/dbutil/upgradetable.go +3 -34
  72. slidge_whatsapp/vendor/go.mau.fi/util/exbytes/string.go +20 -0
  73. slidge_whatsapp/vendor/go.mau.fi/util/exbytes/writer.go +78 -0
  74. slidge_whatsapp/vendor/go.mau.fi/util/exslices/cast.go +42 -0
  75. slidge_whatsapp/vendor/go.mau.fi/util/exslices/chunk.go +28 -0
  76. slidge_whatsapp/vendor/go.mau.fi/util/exslices/deduplicate.go +67 -0
  77. slidge_whatsapp/vendor/go.mau.fi/util/exslices/diff.go +63 -0
  78. slidge_whatsapp/vendor/go.mau.fi/util/exsync/event.go +15 -1
  79. slidge_whatsapp/vendor/go.mau.fi/util/exsync/syncmap.go +48 -7
  80. slidge_whatsapp/vendor/go.mau.fi/util/exsync/syncset.go +13 -0
  81. slidge_whatsapp/vendor/go.mau.fi/util/jsontime/helpers.go +16 -5
  82. slidge_whatsapp/vendor/go.mau.fi/util/jsontime/integer.go +27 -12
  83. slidge_whatsapp/vendor/go.mau.fi/util/random/string.go +47 -7
  84. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/decode.go +1 -0
  85. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/encode.go +60 -15
  86. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate/hash.go +1 -0
  87. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/appstate.go +20 -2
  88. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/armadillomessage.go +2 -2
  89. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/call.go +6 -0
  90. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/errors.go +1 -0
  91. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/group.go +63 -42
  92. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/internals.go +31 -15
  93. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/message.go +77 -26
  94. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/msgsecret.go +23 -0
  95. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/notification.go +5 -1
  96. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/pair.go +22 -23
  97. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/prekeys.go +21 -0
  98. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waAICommon/WAAICommon.pb.go +7747 -0
  99. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/{waBotMetadata/WABotMetadata.proto → waAICommon/WAAICommon.proto} +269 -9
  100. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.pb.go +128 -14
  101. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waDeviceCapabilities/WAProtobufsDeviceCapabilities.proto +10 -0
  102. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.pb.go +8953 -10087
  103. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waE2E/WAWebProtobufsE2E.proto +216 -330
  104. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waHistorySync/WAWebProtobufsHistorySync.pb.go +11 -2
  105. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waHistorySync/WAWebProtobufsHistorySync.proto +1 -0
  106. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.pb.go +226 -83
  107. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waStatusAttributions/WAStatusAttributions.proto +14 -0
  108. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.pb.go +709 -449
  109. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waSyncAction/WASyncAction.proto +24 -0
  110. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.pb.go +78 -24
  111. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWa6/WAWebProtobufsWa6.proto +6 -0
  112. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.pb.go +528 -267
  113. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waWeb/WAWebProtobufsWeb.proto +24 -0
  114. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/receipt.go +47 -14
  115. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/request.go +4 -0
  116. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/retry.go +6 -13
  117. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/send.go +130 -62
  118. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/sendfb.go +33 -32
  119. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/clientpayload.go +1 -1
  120. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/noop.go +16 -0
  121. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sessioncache.go +125 -0
  122. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/signal.go +8 -0
  123. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/lidmap.go +82 -4
  124. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/store.go +135 -55
  125. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/00-latest-schema.sql +8 -7
  126. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/sqlstore/upgrades/11-redacted-phone-contacts.sql +2 -0
  127. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/store/store.go +24 -2
  128. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/call.go +6 -5
  129. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/jid.go +24 -9
  130. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/message.go +7 -1
  131. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/types/user.go +3 -0
  132. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/user.go +43 -3
  133. slidge_whatsapp/vendor/golang.org/x/crypto/curve25519/curve25519.go +7 -4
  134. slidge_whatsapp/vendor/golang.org/x/net/http2/config.go +11 -6
  135. slidge_whatsapp/vendor/golang.org/x/net/http2/config_go125.go +15 -0
  136. slidge_whatsapp/vendor/golang.org/x/net/http2/config_go126.go +15 -0
  137. slidge_whatsapp/vendor/golang.org/x/net/http2/frame.go +24 -1
  138. slidge_whatsapp/vendor/golang.org/x/net/http2/http2.go +0 -1
  139. slidge_whatsapp/vendor/golang.org/x/net/http2/server.go +35 -26
  140. slidge_whatsapp/vendor/golang.org/x/net/http2/transport.go +4 -2
  141. slidge_whatsapp/vendor/golang.org/x/net/http2/writesched.go +2 -0
  142. slidge_whatsapp/vendor/golang.org/x/net/http2/{writesched_priority.go → writesched_priority_rfc7540.go} +52 -52
  143. slidge_whatsapp/vendor/golang.org/x/net/http2/writesched_priority_rfc9128.go +209 -0
  144. slidge_whatsapp/vendor/golang.org/x/net/http2/writesched_roundrobin.go +1 -1
  145. slidge_whatsapp/vendor/golang.org/x/net/internal/httpcommon/request.go +2 -2
  146. slidge_whatsapp/vendor/golang.org/x/net/internal/socks/socks.go +1 -1
  147. slidge_whatsapp/vendor/golang.org/x/sys/unix/affinity_linux.go +9 -0
  148. slidge_whatsapp/vendor/golang.org/x/sys/unix/fdset.go +1 -3
  149. slidge_whatsapp/vendor/golang.org/x/sys/unix/ifreq_linux.go +1 -3
  150. slidge_whatsapp/vendor/golang.org/x/sys/unix/mkall.sh +1 -0
  151. slidge_whatsapp/vendor/golang.org/x/sys/unix/syscall_linux.go +1 -3
  152. slidge_whatsapp/vendor/golang.org/x/sys/unix/syscall_netbsd.go +17 -0
  153. slidge_whatsapp/vendor/golang.org/x/sys/windows/syscall_windows.go +2 -0
  154. slidge_whatsapp/vendor/golang.org/x/sys/windows/types_windows.go +16 -0
  155. slidge_whatsapp/vendor/golang.org/x/sys/windows/zsyscall_windows.go +18 -0
  156. slidge_whatsapp/vendor/golang.org/x/text/unicode/bidi/core.go +2 -9
  157. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/filedesc/desc.go +35 -17
  158. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go +14 -0
  159. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go +20 -0
  160. slidge_whatsapp/vendor/google.golang.org/protobuf/internal/version/version.go +1 -1
  161. slidge_whatsapp/vendor/modules.txt +15 -13
  162. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.4.dist-info}/METADATA +4 -3
  163. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.4.dist-info}/RECORD +166 -138
  164. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.4.dist-info}/WHEEL +1 -1
  165. slidge_whatsapp/vendor/go.mau.fi/whatsmeow/proto/waBotMetadata/WABotMetadata.pb.go +0 -5156
  166. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.4.dist-info}/entry_points.txt +0 -0
  167. {slidge_whatsapp-0.3.0b0.dist-info → slidge_whatsapp-0.3.4.dist-info/licenses}/LICENSE +0 -0
@@ -68,10 +68,18 @@ func (n *NoopStore) HasSession(ctx context.Context, address string) (bool, error
68
68
  return false, n.Error
69
69
  }
70
70
 
71
+ func (n *NoopStore) GetManySessions(ctx context.Context, addresses []string) (map[string][]byte, error) {
72
+ return nil, n.Error
73
+ }
74
+
71
75
  func (n *NoopStore) PutSession(ctx context.Context, address string, session []byte) error {
72
76
  return n.Error
73
77
  }
74
78
 
79
+ func (n *NoopStore) PutManySessions(ctx context.Context, sessions map[string][]byte) error {
80
+ return n.Error
81
+ }
82
+
75
83
  func (n *NoopStore) DeleteAllSessions(ctx context.Context, phone string) error {
76
84
  return n.Error
77
85
  }
@@ -168,6 +176,10 @@ func (n *NoopStore) PutAllContactNames(ctx context.Context, contacts []ContactEn
168
176
  return n.Error
169
177
  }
170
178
 
179
+ func (n *NoopStore) PutManyRedactedPhones(ctx context.Context, entries []RedactedPhoneEntry) error {
180
+ return n.Error
181
+ }
182
+
171
183
  func (n *NoopStore) GetContact(ctx context.Context, user types.JID) (types.ContactInfo, error) {
172
184
  return types.ContactInfo{}, n.Error
173
185
  }
@@ -244,6 +256,10 @@ func (n *NoopStore) GetLIDForPN(ctx context.Context, pn types.JID) (types.JID, e
244
256
  return types.JID{}, n.Error
245
257
  }
246
258
 
259
+ func (n *NoopStore) GetManyLIDsForPNs(ctx context.Context, pns []types.JID) (map[types.JID]types.JID, error) {
260
+ return nil, n.Error
261
+ }
262
+
247
263
  func (n *NoopStore) GetPNForLID(ctx context.Context, lid types.JID) (types.JID, error) {
248
264
  return types.JID{}, n.Error
249
265
  }
@@ -0,0 +1,125 @@
1
+ // Copyright (c) 2025 Tulir Asokan
2
+ //
3
+ // This Source Code Form is subject to the terms of the Mozilla Public
4
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
+
7
+ package store
8
+
9
+ import (
10
+ "context"
11
+ "fmt"
12
+
13
+ "github.com/rs/zerolog"
14
+ "go.mau.fi/libsignal/state/record"
15
+
16
+ "go.mau.fi/util/exsync"
17
+ )
18
+
19
+ type contextKey int
20
+
21
+ const (
22
+ contextKeySessionCache contextKey = iota
23
+ )
24
+
25
+ type sessionCacheEntry struct {
26
+ Dirty bool
27
+ Found bool
28
+ Record *record.Session
29
+ }
30
+
31
+ type sessionCache = exsync.Map[string, sessionCacheEntry]
32
+
33
+ func getSessionCache(ctx context.Context) *sessionCache {
34
+ if ctx == nil {
35
+ return nil
36
+ }
37
+ val := ctx.Value(contextKeySessionCache)
38
+ if val == nil {
39
+ return nil
40
+ }
41
+ if cache, ok := val.(*sessionCache); ok {
42
+ return cache
43
+ }
44
+ return nil
45
+ }
46
+
47
+ func getCachedSession(ctx context.Context, addr string) *record.Session {
48
+ cache := getSessionCache(ctx)
49
+ if cache == nil {
50
+ return nil
51
+ }
52
+ sess, ok := cache.Get(addr)
53
+ if !ok {
54
+ return nil
55
+ }
56
+ return sess.Record
57
+ }
58
+
59
+ func putCachedSession(ctx context.Context, addr string, record *record.Session) bool {
60
+ cache := getSessionCache(ctx)
61
+ if cache == nil {
62
+ return false
63
+ }
64
+ cache.Set(addr, sessionCacheEntry{
65
+ Dirty: true,
66
+ Found: true,
67
+ Record: record,
68
+ })
69
+ return true
70
+ }
71
+
72
+ func (device *Device) WithCachedSessions(ctx context.Context, addresses []string) (map[string]bool, context.Context, error) {
73
+ if len(addresses) == 0 {
74
+ return nil, ctx, nil
75
+ }
76
+
77
+ sessions, err := device.Sessions.GetManySessions(ctx, addresses)
78
+ if err != nil {
79
+ return nil, ctx, fmt.Errorf("failed to prefetch sessions: %w", err)
80
+ }
81
+ wrapped := make(map[string]sessionCacheEntry, len(sessions))
82
+ existingSessions := make(map[string]bool, len(sessions))
83
+ for addr, rawSess := range sessions {
84
+ var sessionRecord *record.Session
85
+ var found bool
86
+ if rawSess == nil {
87
+ sessionRecord = record.NewSession(SignalProtobufSerializer.Session, SignalProtobufSerializer.State)
88
+ } else {
89
+ found = true
90
+ sessionRecord, err = record.NewSessionFromBytes(rawSess, SignalProtobufSerializer.Session, SignalProtobufSerializer.State)
91
+ if err != nil {
92
+ zerolog.Ctx(ctx).Err(err).
93
+ Str("address", addr).
94
+ Msg("Failed to deserialize session")
95
+ continue
96
+ }
97
+ }
98
+ existingSessions[addr] = found
99
+ wrapped[addr] = sessionCacheEntry{Record: sessionRecord, Found: found}
100
+ }
101
+
102
+ ctx = context.WithValue(ctx, contextKeySessionCache, (*sessionCache)(exsync.NewMapWithData(wrapped)))
103
+ return existingSessions, ctx, nil
104
+ }
105
+
106
+ func (device *Device) PutCachedSessions(ctx context.Context) error {
107
+ cache := getSessionCache(ctx)
108
+ if cache == nil {
109
+ return nil
110
+ }
111
+ dirtySessions := make(map[string][]byte)
112
+ for addr, item := range cache.Iter() {
113
+ if item.Dirty {
114
+ dirtySessions[addr] = item.Record.Serialize()
115
+ }
116
+ }
117
+ if len(dirtySessions) > 0 {
118
+ err := device.Sessions.PutManySessions(ctx, dirtySessions)
119
+ if err != nil {
120
+ return fmt.Errorf("failed to store cached sessions: %w", err)
121
+ }
122
+ }
123
+ cache.Clear()
124
+ return nil
125
+ }
@@ -84,6 +84,10 @@ func (device *Device) ContainsPreKey(ctx context.Context, preKeyID uint32) (bool
84
84
 
85
85
  func (device *Device) LoadSession(ctx context.Context, address *protocol.SignalAddress) (*record.Session, error) {
86
86
  addrString := address.String()
87
+ if sess := getCachedSession(ctx, addrString); sess != nil {
88
+ return sess, nil
89
+ }
90
+
87
91
  rawSess, err := device.Sessions.GetSession(ctx, addrString)
88
92
  if err != nil {
89
93
  return nil, fmt.Errorf("failed to load session with %s: %w", addrString, err)
@@ -104,6 +108,10 @@ func (device *Device) GetSubDeviceSessions(ctx context.Context, name string) ([]
104
108
 
105
109
  func (device *Device) StoreSession(ctx context.Context, address *protocol.SignalAddress, record *record.Session) error {
106
110
  addrString := address.String()
111
+ if putCachedSession(ctx, addrString, record) {
112
+ return nil
113
+ }
114
+
107
115
  err := device.Sessions.PutSession(ctx, addrString, record.Serialize())
108
116
  if err != nil {
109
117
  return fmt.Errorf("failed to store session with %s: %w", addrString, err)
@@ -13,10 +13,12 @@ import (
13
13
  "errors"
14
14
  "fmt"
15
15
  "slices"
16
+ "strings"
16
17
  "sync"
17
18
 
18
19
  "github.com/rs/zerolog"
19
20
  "go.mau.fi/util/dbutil"
21
+ "go.mau.fi/util/exslices"
20
22
 
21
23
  "go.mau.fi/whatsmeow/store"
22
24
  "go.mau.fi/whatsmeow/types"
@@ -61,18 +63,30 @@ func (s *CachedLIDMap) FillCache(ctx context.Context) error {
61
63
  if err != nil {
62
64
  return err
63
65
  }
64
- defer rows.Close()
66
+ err = s.scanManyLids(rows, nil)
67
+ s.cacheFilled = err == nil
68
+ return err
69
+ }
70
+
71
+ func (s *CachedLIDMap) scanManyLids(rows dbutil.Rows, fn func(lid, pn string)) error {
72
+ if fn == nil {
73
+ fn = func(lid, pn string) {}
74
+ }
65
75
  for rows.Next() {
66
76
  var lid, pn string
67
- err = rows.Scan(&lid, &pn)
77
+ err := rows.Scan(&lid, &pn)
68
78
  if err != nil {
69
79
  return err
70
80
  }
71
81
  s.pnToLIDCache[pn] = lid
72
82
  s.lidToPNCache[lid] = pn
83
+ fn(lid, pn)
73
84
  }
74
- s.cacheFilled = true
75
- return nil
85
+ err := rows.Close()
86
+ if err != nil {
87
+ return err
88
+ }
89
+ return rows.Err()
76
90
  }
77
91
 
78
92
  func (s *CachedLIDMap) getLIDMapping(ctx context.Context, source types.JID, targetServer, query string, sourceToTarget, targetToSource map[string]string) (types.JID, error) {
@@ -122,6 +136,69 @@ func (s *CachedLIDMap) GetPNForLID(ctx context.Context, lid types.JID) (types.JI
122
136
  )
123
137
  }
124
138
 
139
+ func (s *CachedLIDMap) GetManyLIDsForPNs(ctx context.Context, pns []types.JID) (map[types.JID]types.JID, error) {
140
+ if len(pns) == 0 {
141
+ return nil, nil
142
+ }
143
+
144
+ result := make(map[types.JID]types.JID, len(pns))
145
+
146
+ s.lidCacheLock.RLock()
147
+ missingPNs := make([]string, 0, len(pns))
148
+ missingPNDevices := make(map[string][]types.JID)
149
+ for _, pn := range pns {
150
+ if pn.Server != types.DefaultUserServer {
151
+ continue
152
+ }
153
+ if lidUser, ok := s.pnToLIDCache[pn.User]; ok && lidUser != "" {
154
+ result[pn] = types.JID{User: lidUser, Device: pn.Device, Server: types.HiddenUserServer}
155
+ } else if !s.cacheFilled {
156
+ missingPNs = append(missingPNs, pn.User)
157
+ missingPNDevices[pn.User] = append(missingPNDevices[pn.User], pn)
158
+ }
159
+ }
160
+ s.lidCacheLock.RUnlock()
161
+
162
+ if len(missingPNs) == 0 {
163
+ return result, nil
164
+ }
165
+
166
+ s.lidCacheLock.Lock()
167
+ defer s.lidCacheLock.Unlock()
168
+
169
+ var rows dbutil.Rows
170
+ var err error
171
+ if s.db.Dialect == dbutil.Postgres && PostgresArrayWrapper != nil {
172
+ rows, err = s.db.Query(
173
+ ctx,
174
+ `SELECT lid, pn FROM whatsmeow_lid_map WHERE pn = ANY($1)`,
175
+ PostgresArrayWrapper(missingPNs),
176
+ )
177
+ } else {
178
+ placeholders := make([]string, len(missingPNs))
179
+ for i := range missingPNs {
180
+ placeholders[i] = fmt.Sprintf("$%d", i+1)
181
+ }
182
+ rows, err = s.db.Query(
183
+ ctx,
184
+ fmt.Sprintf(`SELECT lid, pn FROM whatsmeow_lid_map WHERE pn IN (%s)`, strings.Join(placeholders, ",")),
185
+ exslices.CastToAny(missingPNs)...,
186
+ )
187
+ }
188
+ if err != nil {
189
+ return nil, err
190
+ }
191
+ err = s.scanManyLids(rows, func(lid, pn string) {
192
+ for _, dev := range missingPNDevices[pn] {
193
+ lidDev := dev
194
+ lidDev.Server = types.HiddenUserServer
195
+ lidDev.User = lid
196
+ result[dev] = lidDev.ToNonAD()
197
+ }
198
+ })
199
+ return result, err
200
+ }
201
+
125
202
  func (s *CachedLIDMap) PutLIDMapping(ctx context.Context, lid, pn types.JID) error {
126
203
  if lid.Server != types.HiddenUserServer || pn.Server != types.DefaultUserServer {
127
204
  return fmt.Errorf("invalid PutLIDMapping call %s/%s", lid, pn)
@@ -154,6 +231,7 @@ func (s *CachedLIDMap) PutManyLIDMappings(ctx context.Context, mappings []store.
154
231
  }
155
232
  return false
156
233
  })
234
+ mappings = exslices.DeduplicateUnsortedOverwrite(mappings)
157
235
  if len(mappings) == 0 {
158
236
  return nil
159
237
  }
@@ -19,6 +19,7 @@ import (
19
19
  "time"
20
20
 
21
21
  "go.mau.fi/util/dbutil"
22
+ "go.mau.fi/util/exslices"
22
23
  "go.mau.fi/util/exsync"
23
24
 
24
25
  "go.mau.fi/whatsmeow/store"
@@ -108,9 +109,11 @@ func (s *SQLStore) IsTrustedIdentity(ctx context.Context, address string, key [3
108
109
  }
109
110
 
110
111
  const (
111
- getSessionQuery = `SELECT session FROM whatsmeow_sessions WHERE our_jid=$1 AND their_id=$2`
112
- hasSessionQuery = `SELECT true FROM whatsmeow_sessions WHERE our_jid=$1 AND their_id=$2`
113
- putSessionQuery = `
112
+ getSessionQuery = `SELECT session FROM whatsmeow_sessions WHERE our_jid=$1 AND their_id=$2`
113
+ hasSessionQuery = `SELECT true FROM whatsmeow_sessions WHERE our_jid=$1 AND their_id=$2`
114
+ getManySessionQueryPostgres = `SELECT their_id, session FROM whatsmeow_sessions WHERE our_jid=$1 AND their_id = ANY($2)`
115
+ getManySessionQueryGeneric = `SELECT their_id, session FROM whatsmeow_sessions WHERE our_jid=$1 AND their_id IN (%s)`
116
+ putSessionQuery = `
114
117
  INSERT INTO whatsmeow_sessions (our_jid, their_id, session) VALUES ($1, $2, $3)
115
118
  ON CONFLICT (our_jid, their_id) DO UPDATE SET session=excluded.session
116
119
  `
@@ -158,6 +161,61 @@ func (s *SQLStore) HasSession(ctx context.Context, address string) (has bool, er
158
161
  return
159
162
  }
160
163
 
164
+ type addressSessionTuple struct {
165
+ Address string
166
+ Session []byte
167
+ }
168
+
169
+ var sessionScanner = dbutil.ConvertRowFn[addressSessionTuple](func(row dbutil.Scannable) (out addressSessionTuple, err error) {
170
+ err = row.Scan(&out.Address, &out.Session)
171
+ return
172
+ })
173
+
174
+ func (s *SQLStore) GetManySessions(ctx context.Context, addresses []string) (map[string][]byte, error) {
175
+ if len(addresses) == 0 {
176
+ return nil, nil
177
+ }
178
+
179
+ var rows dbutil.Rows
180
+ var err error
181
+ if s.db.Dialect == dbutil.Postgres && PostgresArrayWrapper != nil {
182
+ rows, err = s.db.Query(ctx, getManySessionQueryPostgres, s.JID, PostgresArrayWrapper(addresses))
183
+ } else {
184
+ args := make([]any, len(addresses)+1)
185
+ placeholders := make([]string, len(addresses))
186
+ args[0] = s.JID
187
+ for i, addr := range addresses {
188
+ args[i+1] = addr
189
+ placeholders[i] = fmt.Sprintf("$%d", i+2)
190
+ }
191
+ rows, err = s.db.Query(ctx, fmt.Sprintf(getManySessionQueryGeneric, strings.Join(placeholders, ",")), args...)
192
+ }
193
+ result := make(map[string][]byte, len(addresses))
194
+ for _, addr := range addresses {
195
+ result[addr] = nil
196
+ }
197
+ err = sessionScanner.NewRowIter(rows, err).Iter(func(tuple addressSessionTuple) (bool, error) {
198
+ result[tuple.Address] = tuple.Session
199
+ return true, nil
200
+ })
201
+ if err != nil {
202
+ return nil, err
203
+ }
204
+ return result, nil
205
+ }
206
+
207
+ func (s *SQLStore) PutManySessions(ctx context.Context, sessions map[string][]byte) error {
208
+ return s.db.DoTxn(ctx, nil, func(ctx context.Context) error {
209
+ for addr, sess := range sessions {
210
+ err := s.PutSession(ctx, addr, sess)
211
+ if err != nil {
212
+ return err
213
+ }
214
+ }
215
+ return nil
216
+ })
217
+ }
218
+
161
219
  func (s *SQLStore) PutSession(ctx context.Context, address string, session []byte) error {
162
220
  _, err := s.db.Exec(ctx, putSessionQuery, s.JID, address, session)
163
221
  return err
@@ -522,10 +580,10 @@ const (
522
580
  INSERT INTO whatsmeow_contacts (our_jid, their_jid, first_name, full_name) VALUES ($1, $2, $3, $4)
523
581
  ON CONFLICT (our_jid, their_jid) DO UPDATE SET first_name=excluded.first_name, full_name=excluded.full_name
524
582
  `
525
- putManyContactNamesQuery = `
526
- INSERT INTO whatsmeow_contacts (our_jid, their_jid, first_name, full_name)
527
- VALUES %s
528
- ON CONFLICT (our_jid, their_jid) DO UPDATE SET first_name=excluded.first_name, full_name=excluded.full_name
583
+ putRedactedPhoneQuery = `
584
+ INSERT INTO whatsmeow_contacts (our_jid, their_jid, redacted_phone)
585
+ VALUES ($1, $2, $3)
586
+ ON CONFLICT (our_jid, their_jid) DO UPDATE SET redacted_phone=excluded.redacted_phone
529
587
  `
530
588
  putPushNameQuery = `
531
589
  INSERT INTO whatsmeow_contacts (our_jid, their_jid, push_name) VALUES ($1, $2, $3)
@@ -536,13 +594,21 @@ const (
536
594
  ON CONFLICT (our_jid, their_jid) DO UPDATE SET business_name=excluded.business_name
537
595
  `
538
596
  getContactQuery = `
539
- SELECT first_name, full_name, push_name, business_name FROM whatsmeow_contacts WHERE our_jid=$1 AND their_jid=$2
597
+ SELECT first_name, full_name, push_name, business_name, redacted_phone FROM whatsmeow_contacts WHERE our_jid=$1 AND their_jid=$2
540
598
  `
541
599
  getAllContactsQuery = `
542
- SELECT their_jid, first_name, full_name, push_name, business_name FROM whatsmeow_contacts WHERE our_jid=$1
600
+ SELECT their_jid, first_name, full_name, push_name, business_name, redacted_phone FROM whatsmeow_contacts WHERE our_jid=$1
543
601
  `
544
602
  )
545
603
 
604
+ var putContactNamesMassInsertBuilder = dbutil.NewMassInsertBuilder[store.ContactEntry, [1]any](
605
+ putContactNameQuery, "($1, $%d, $%d, $%d)",
606
+ )
607
+
608
+ var putRedactedPhonesMassInsertBuilder = dbutil.NewMassInsertBuilder[store.RedactedPhoneEntry, [1]any](
609
+ putRedactedPhoneQuery, "($1, $%d, $%d)",
610
+ )
611
+
546
612
  func (s *SQLStore) PutPushName(ctx context.Context, user types.JID, pushName string) (bool, string, error) {
547
613
  s.contactCacheLock.Lock()
548
614
  defer s.contactCacheLock.Unlock()
@@ -607,44 +673,21 @@ func (s *SQLStore) PutContactName(ctx context.Context, user types.JID, firstName
607
673
 
608
674
  const contactBatchSize = 300
609
675
 
610
- func (s *SQLStore) putContactNamesBatch(ctx context.Context, contacts []store.ContactEntry) error {
611
- values := make([]any, 1, 1+len(contacts)*3)
612
- queryParts := make([]string, 0, len(contacts))
613
- values[0] = s.JID
614
- placeholderSyntax := "($1, $%d, $%d, $%d)"
615
- if s.db.Dialect == dbutil.SQLite {
616
- placeholderSyntax = "(?1, ?%d, ?%d, ?%d)"
617
- }
618
- i := 0
619
- handledContacts := make(map[types.JID]struct{}, len(contacts))
620
- for _, contact := range contacts {
621
- if contact.JID.IsEmpty() {
622
- s.log.Warnf("Empty contact info in mass insert: %+v", contact)
623
- continue
624
- }
625
- // The whole query will break if there are duplicates, so make sure there aren't any duplicates
626
- _, alreadyHandled := handledContacts[contact.JID]
627
- if alreadyHandled {
628
- s.log.Warnf("Duplicate contact info for %s in mass insert", contact.JID)
629
- continue
630
- }
631
- handledContacts[contact.JID] = struct{}{}
632
- baseIndex := i*3 + 1
633
- values = append(values, contact.JID.String(), contact.FirstName, contact.FullName)
634
- queryParts = append(queryParts, fmt.Sprintf(placeholderSyntax, baseIndex+1, baseIndex+2, baseIndex+3))
635
- i++
636
- }
637
- _, err := s.db.Exec(ctx, fmt.Sprintf(putManyContactNamesQuery, strings.Join(queryParts, ",")), values...)
638
- return err
639
- }
640
-
641
676
  func (s *SQLStore) PutAllContactNames(ctx context.Context, contacts []store.ContactEntry) error {
642
677
  if len(contacts) == 0 {
643
678
  return nil
644
679
  }
680
+ origLen := len(contacts)
681
+ contacts = exslices.DeduplicateUnsortedOverwriteFunc(contacts, func(t store.ContactEntry) types.JID {
682
+ return t.JID
683
+ })
684
+ if origLen != len(contacts) {
685
+ s.log.Warnf("%d duplicate contacts found in PutAllContactNames", origLen-len(contacts))
686
+ }
645
687
  err := s.db.DoTxn(ctx, nil, func(ctx context.Context) error {
646
688
  for slice := range slices.Chunk(contacts, contactBatchSize) {
647
- err := s.putContactNamesBatch(ctx, slice)
689
+ query, vars := putContactNamesMassInsertBuilder.Build([1]any{s.JID}, slice)
690
+ _, err := s.db.Exec(ctx, query, vars...)
648
691
  if err != nil {
649
692
  return err
650
693
  }
@@ -661,23 +704,59 @@ func (s *SQLStore) PutAllContactNames(ctx context.Context, contacts []store.Cont
661
704
  return nil
662
705
  }
663
706
 
707
+ func (s *SQLStore) PutManyRedactedPhones(ctx context.Context, entries []store.RedactedPhoneEntry) error {
708
+ if len(entries) == 0 {
709
+ return nil
710
+ }
711
+ origLen := len(entries)
712
+ entries = exslices.DeduplicateUnsortedOverwriteFunc(entries, func(t store.RedactedPhoneEntry) types.JID {
713
+ return t.JID
714
+ })
715
+ if origLen != len(entries) {
716
+ s.log.Warnf("%d duplicate contacts found in PutManyRedactedPhones", origLen-len(entries))
717
+ }
718
+ err := s.db.DoTxn(ctx, nil, func(ctx context.Context) error {
719
+ for slice := range slices.Chunk(entries, contactBatchSize) {
720
+ query, vars := putRedactedPhonesMassInsertBuilder.Build([1]any{s.JID}, slice)
721
+ _, err := s.db.Exec(ctx, query, vars...)
722
+ if err != nil {
723
+ return err
724
+ }
725
+ }
726
+ return nil
727
+ })
728
+ if err != nil {
729
+ return err
730
+ }
731
+ s.contactCacheLock.Lock()
732
+ for _, entry := range entries {
733
+ if cached, ok := s.contactCache[entry.JID]; ok && cached.RedactedPhone == entry.RedactedPhone {
734
+ continue
735
+ }
736
+ delete(s.contactCache, entry.JID)
737
+ }
738
+ s.contactCacheLock.Unlock()
739
+ return nil
740
+ }
741
+
664
742
  func (s *SQLStore) getContact(ctx context.Context, user types.JID) (*types.ContactInfo, error) {
665
743
  cached, ok := s.contactCache[user]
666
744
  if ok {
667
745
  return cached, nil
668
746
  }
669
747
 
670
- var first, full, push, business sql.NullString
671
- err := s.db.QueryRow(ctx, getContactQuery, s.JID, user).Scan(&first, &full, &push, &business)
748
+ var first, full, push, business, redactedPhone sql.NullString
749
+ err := s.db.QueryRow(ctx, getContactQuery, s.JID, user).Scan(&first, &full, &push, &business, &redactedPhone)
672
750
  if err != nil && !errors.Is(err, sql.ErrNoRows) {
673
751
  return nil, err
674
752
  }
675
753
  info := &types.ContactInfo{
676
- Found: err == nil,
677
- FirstName: first.String,
678
- FullName: full.String,
679
- PushName: push.String,
680
- BusinessName: business.String,
754
+ Found: err == nil,
755
+ FirstName: first.String,
756
+ FullName: full.String,
757
+ PushName: push.String,
758
+ BusinessName: business.String,
759
+ RedactedPhone: redactedPhone.String,
681
760
  }
682
761
  s.contactCache[user] = info
683
762
  return info, nil
@@ -703,17 +782,18 @@ func (s *SQLStore) GetAllContacts(ctx context.Context) (map[types.JID]types.Cont
703
782
  output := make(map[types.JID]types.ContactInfo, len(s.contactCache))
704
783
  for rows.Next() {
705
784
  var jid types.JID
706
- var first, full, push, business sql.NullString
707
- err = rows.Scan(&jid, &first, &full, &push, &business)
785
+ var first, full, push, business, redactedPhone sql.NullString
786
+ err = rows.Scan(&jid, &first, &full, &push, &business, &redactedPhone)
708
787
  if err != nil {
709
788
  return nil, fmt.Errorf("error scanning row: %w", err)
710
789
  }
711
790
  info := types.ContactInfo{
712
- Found: true,
713
- FirstName: first.String,
714
- FullName: full.String,
715
- PushName: push.String,
716
- BusinessName: business.String,
791
+ Found: true,
792
+ FirstName: first.String,
793
+ FullName: full.String,
794
+ PushName: push.String,
795
+ BusinessName: business.String,
796
+ RedactedPhone: redactedPhone.String,
717
797
  }
718
798
  output[jid] = info
719
799
  s.contactCache[jid] = &info
@@ -1,4 +1,4 @@
1
- -- v0 -> v10 (compatible with v8+): Latest schema
1
+ -- v0 -> v11 (compatible with v8+): Latest schema
2
2
  CREATE TABLE whatsmeow_device (
3
3
  jid TEXT PRIMARY KEY,
4
4
  lid TEXT,
@@ -98,12 +98,13 @@ CREATE TABLE whatsmeow_app_state_mutation_macs (
98
98
  );
99
99
 
100
100
  CREATE TABLE whatsmeow_contacts (
101
- our_jid TEXT,
102
- their_jid TEXT,
103
- first_name TEXT,
104
- full_name TEXT,
105
- push_name TEXT,
106
- business_name TEXT,
101
+ our_jid TEXT,
102
+ their_jid TEXT,
103
+ first_name TEXT,
104
+ full_name TEXT,
105
+ push_name TEXT,
106
+ business_name TEXT,
107
+ redacted_phone TEXT,
107
108
 
108
109
  PRIMARY KEY (our_jid, their_jid),
109
110
  FOREIGN KEY (our_jid) REFERENCES whatsmeow_device(jid) ON DELETE CASCADE ON UPDATE CASCADE
@@ -0,0 +1,2 @@
1
+ -- v11 (compatible with v8+): Store redacted phone number for LID members in groups
2
+ ALTER TABLE whatsmeow_contacts ADD COLUMN redacted_phone TEXT;
@@ -29,7 +29,9 @@ type IdentityStore interface {
29
29
  type SessionStore interface {
30
30
  GetSession(ctx context.Context, address string) ([]byte, error)
31
31
  HasSession(ctx context.Context, address string) (bool, error)
32
+ GetManySessions(ctx context.Context, addresses []string) (map[string][]byte, error)
32
33
  PutSession(ctx context.Context, address string, session []byte) error
34
+ PutManySessions(ctx context.Context, sessions map[string][]byte) error
33
35
  DeleteAllSessions(ctx context.Context, phone string) error
34
36
  DeleteSession(ctx context.Context, address string) error
35
37
  MigratePNToLID(ctx context.Context, pn, lid types.JID) error
@@ -82,11 +84,25 @@ type ContactEntry struct {
82
84
  FullName string
83
85
  }
84
86
 
87
+ func (ce ContactEntry) GetMassInsertValues() [3]any {
88
+ return [...]any{ce.JID.String(), ce.FirstName, ce.FullName}
89
+ }
90
+
91
+ type RedactedPhoneEntry struct {
92
+ JID types.JID
93
+ RedactedPhone string
94
+ }
95
+
96
+ func (rpe RedactedPhoneEntry) GetMassInsertValues() [2]any {
97
+ return [...]any{rpe.JID.String(), rpe.RedactedPhone}
98
+ }
99
+
85
100
  type ContactStore interface {
86
101
  PutPushName(ctx context.Context, user types.JID, pushName string) (bool, string, error)
87
102
  PutBusinessName(ctx context.Context, user types.JID, businessName string) (bool, string, error)
88
103
  PutContactName(ctx context.Context, user types.JID, fullName, firstName string) error
89
104
  PutAllContactNames(ctx context.Context, contacts []ContactEntry) error
105
+ PutManyRedactedPhones(ctx context.Context, entries []RedactedPhoneEntry) error
90
106
  GetContact(ctx context.Context, user types.JID) (types.ContactInfo, error)
91
107
  GetAllContacts(ctx context.Context) (map[types.JID]types.ContactInfo, error)
92
108
  }
@@ -148,11 +164,16 @@ type LIDMapping struct {
148
164
  PN types.JID
149
165
  }
150
166
 
167
+ func (lm LIDMapping) GetMassInsertValues() [2]any {
168
+ return [...]any{lm.LID.User, lm.PN.User}
169
+ }
170
+
151
171
  type LIDStore interface {
152
172
  PutManyLIDMappings(ctx context.Context, mappings []LIDMapping) error
153
173
  PutLIDMapping(ctx context.Context, lid, jid types.JID) error
154
174
  GetPNForLID(ctx context.Context, lid types.JID) (types.JID, error)
155
175
  GetLIDForPN(ctx context.Context, pn types.JID) (types.JID, error)
176
+ GetManyLIDsForPNs(ctx context.Context, pns []types.JID) (map[types.JID]types.JID, error)
156
177
  }
157
178
 
158
179
  type AllSessionSpecificStores interface {
@@ -187,8 +208,9 @@ type Device struct {
187
208
  RegistrationID uint32
188
209
  AdvSecretKey []byte
189
210
 
190
- ID *types.JID
191
- LID types.JID
211
+ ID *types.JID
212
+ LID types.JID
213
+
192
214
  Account *waAdv.ADVSignedDeviceIdentity
193
215
  Platform string
194
216
  BusinessName string
@@ -9,11 +9,12 @@ package types
9
9
  import "time"
10
10
 
11
11
  type BasicCallMeta struct {
12
- From JID
13
- Timestamp time.Time
14
- CallCreator JID
15
- CallID string
16
- GroupJID JID
12
+ From JID
13
+ Timestamp time.Time
14
+ CallCreator JID
15
+ CallCreatorAlt JID
16
+ CallID string
17
+ GroupJID JID
17
18
  }
18
19
 
19
20
  type CallRemoteMeta struct {