Skip to content

Commit fe4c904

Browse files
committed
normalize ensContract name before inserting a contract
1 parent 2beac4d commit fe4c904

File tree

5 files changed

+135
-27
lines changed

5 files changed

+135
-27
lines changed

packages/messenger-widget/src/components/Chat/Chat.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ export function Chat(props: HideFunctionProps) {
5757
}, [selectedContact]);
5858

5959
const messages = useMemo(() => {
60+
if (!selectedContact?.contactDetails.account.ensName) {
61+
return [];
62+
}
6063
return getMessages(selectedContact?.contactDetails.account.ensName!);
6164
}, [selectedContact, getMessages]);
6265

packages/messenger-widget/src/components/Contacts/Contacts.tsx

+9-3
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,15 @@ export function Contacts(props: DashboardProps) {
145145
: 'contact-details-container-active'
146146
: '',
147147
)}
148-
onClick={() =>
149-
setSelectedContactName(data.name)
150-
}
148+
onClick={() => {
149+
console.log(
150+
'set selected contact ',
151+
data.contactDetails.account.ensName,
152+
);
153+
setSelectedContactName(
154+
data.contactDetails.account.ensName,
155+
);
156+
}}
151157
>
152158
<div
153159
className="col-12 d-flex flex-row align-items-center

packages/messenger-widget/src/hooks/auth/useAuth.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
/* eslint-disable no-console */
22
import { useAccount, useWalletClient } from 'wagmi';
3-
import { Account, ProfileKeys } from '@dm3-org/dm3-lib-profile';
3+
import {
4+
Account,
5+
ProfileKeys,
6+
normalizeEnsName,
7+
} from '@dm3-org/dm3-lib-profile';
48
import { UserDB } from '@dm3-org/dm3-lib-storage';
59
import { useEffect, useMemo, useState, useContext } from 'react';
610
import { useMainnetProvider } from '../mainnetprovider/useMainnetProvider';
@@ -116,6 +120,7 @@ export const useAuth = (onStorageSet: (userDb: UserDB) => void) => {
116120
onStorageSet(userDb);
117121
setAccount({
118122
...account,
123+
ensName: normalizeEnsName(account.ensName),
119124
profile: signedUserProfile.profile,
120125
profileSignature: signedUserProfile.signature,
121126
});

packages/messenger-widget/src/hooks/conversation/useConversation.tsx

+29-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { StorageContext } from '../../context/StorageContext';
66
import { ContactPreview, getDefaultContract } from '../../interfaces/utils';
77
import { useMainnetProvider } from '../mainnetprovider/useMainnetProvider';
88
import { hydrateContract } from './hydrateContact';
9+
import { fetchPendingConversations } from '../../adapters/messages';
10+
import { normalizeEnsName } from '@dm3-org/dm3-lib-profile';
911

1012
export const useConversation = () => {
1113
const mainnetProvider = useMainnetProvider();
@@ -25,7 +27,7 @@ export const useConversation = () => {
2527

2628
const conversationCount = useMemo(() => contacts.length, [contacts]);
2729

28-
const { account } = useContext(AuthContext);
30+
const { account, deliveryServiceToken } = useContext(AuthContext);
2931

3032
const selectedContact = useMemo(() => {
3133
return contacts.find(
@@ -40,10 +42,13 @@ export const useConversation = () => {
4042
setSelectedContactName(undefined);
4143
setContacts([]);
4244
const init = async (page: number = 0) => {
45+
if (!account || !storageInitialized) {
46+
return;
47+
}
4348
const currentConversationsPage = await getConversations(page);
4449

4550
//Hydrate the contacts by fetching their profile and DS profile
46-
const newContacts = await Promise.all(
51+
const storedContacts = await Promise.all(
4752
currentConversationsPage.map((conversation) => {
4853
const isHidden = conversation.isHidden;
4954
//Hydrating is the most expensive operation. Hence we only hydrate if the contact is not hidden
@@ -58,7 +63,7 @@ export const useConversation = () => {
5863
}),
5964
);
6065
//It might be the case that contacts are added via websocket. In this case we do not want to add them again
61-
const contactsWithoutDuplicates = newContacts.filter(
66+
const contactsWithoutDuplicates = storedContacts.filter(
6267
(newContact) =>
6368
!contacts.some(
6469
(existingContact) =>
@@ -68,16 +73,31 @@ export const useConversation = () => {
6873
);
6974

7075
setContacts((prev) => [...prev, ...contactsWithoutDuplicates]);
76+
//as long as there is no pagination we fetch the next page until we get an empty page
7177
if (currentConversationsPage.length > 0) {
7278
await init(page + 1);
7379
}
74-
80+
await handlePendingConversations();
7581
setConversationsInitialized(true);
7682
};
7783
init();
7884
}, [storageInitialized, account]);
7985

80-
const addConversation = (ensName: string) => {
86+
const handlePendingConversations = async () => {
87+
//At first we've to check if there are pending conversations not yet added to the list
88+
const pendingConversations = await fetchPendingConversations(
89+
mainnetProvider,
90+
account!,
91+
deliveryServiceToken!,
92+
);
93+
//Every pending conversation is going to be added to the conversation list
94+
pendingConversations.forEach((pendingConversation) => {
95+
addConversation(pendingConversation);
96+
});
97+
};
98+
99+
const addConversation = (_ensName: string) => {
100+
const ensName = normalizeEnsName(_ensName);
81101
const alreadyAddedContact = contacts.find(
82102
(existingContact) =>
83103
existingContact.contactDetails.account.ensName === ensName,
@@ -129,7 +149,8 @@ export const useConversation = () => {
129149
});
130150
};
131151

132-
const toggleHideContact = (ensName: string, isHidden: boolean) => {
152+
const toggleHideContact = (_ensName: string, isHidden: boolean) => {
153+
const ensName = normalizeEnsName(_ensName);
133154
setContacts((prev) => {
134155
return prev.map((existingContact) => {
135156
//Find the contact in the list and replace it with the hydrated one
@@ -148,7 +169,8 @@ export const useConversation = () => {
148169
toggleHideContactAsync(ensName, isHidden);
149170
};
150171

151-
const hideContact = (ensName: string) => {
172+
const hideContact = (_ensName: string) => {
173+
const ensName = normalizeEnsName(_ensName);
152174
toggleHideContact(ensName, true);
153175
setSelectedContactName(undefined);
154176
};

packages/messenger-widget/src/hooks/messages/useMessage.tsx

+88-16
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@ import { StorageContext } from '../../context/StorageContext';
1414
import { Connection } from '../../interfaces/web3';
1515
import { getHaltDelivery } from '../../utils/common-utils';
1616
import { MessageActionType } from '../../utils/enum-type-utils';
17-
import { encryptAsymmetric } from '@dm3-org/dm3-lib-crypto';
17+
import { decryptAsymmetric, encryptAsymmetric } from '@dm3-org/dm3-lib-crypto';
18+
import {
19+
getDeliveryServiceProfile,
20+
normalizeEnsName,
21+
} from '@dm3-org/dm3-lib-profile';
22+
import { useMainnetProvider } from '../mainnetprovider/useMainnetProvider';
23+
import axios from 'axios';
24+
import { fetchNewMessages } from '../../adapters/messages';
1825

1926
type MessageStorage = { [contact: string]: StorageEnvelopContainer[] };
2027

@@ -27,18 +34,20 @@ export const useMessage = (connection: Connection) => {
2734
getMessages: getMessagesFromStorage,
2835
storeMessage,
2936
} = useContext(StorageContext);
37+
38+
const mainnetProvider = useMainnetProvider();
3039
const [messages, setMessages] = useState<MessageStorage>({});
3140

3241
const [contactsLoading, setContactsLoading] = useState<string[]>([]);
3342

3443
useEffect(() => {
3544
//Find new contacts
3645
const newContacts = contacts.filter(
37-
(contact) => !messages[contact.name],
46+
(contact) => !messages[contact.contactDetails.account.ensName],
3847
);
3948

4049
newContacts.forEach((contact) => {
41-
addNewContact(contact.name);
50+
addNewContact(contact.contactDetails.account.ensName);
4251
});
4352
}, [contacts]);
4453

@@ -47,13 +56,15 @@ export const useMessage = (connection: Connection) => {
4756
}, [messages]);
4857

4958
const contactIsLoading = useCallback(
50-
(contact: string) => {
59+
(_contactName: string) => {
60+
const contact = normalizeEnsName(_contactName);
5161
return contactsLoading.includes(contact);
5262
},
5363
[contactsLoading],
5464
);
5565

56-
const addNewContact = (contact: string) => {
66+
const addNewContact = (_contactName: string) => {
67+
const contact = normalizeEnsName(_contactName);
5768
//Contact already exists
5869
if (messages[contact]) {
5970
return;
@@ -67,7 +78,8 @@ export const useMessage = (connection: Connection) => {
6778
loadInitialMessages(contact);
6879
};
6980

70-
const addMessage = async (contact: string, message: Message) => {
81+
const addMessage = async (_contactName: string, message: Message) => {
82+
const contact = normalizeEnsName(_contactName);
7183
//Find the recipient of the message in the contact list
7284
const recipient = contacts.find((c) => c.name === contact);
7385

@@ -103,6 +115,7 @@ export const useMessage = (connection: Connection) => {
103115
],
104116
};
105117
});
118+
console.log('storeMessage', contact, storageEnvelopContainer);
106119
storeMessage(contact, storageEnvelopContainer);
107120
return;
108121
}
@@ -148,31 +161,90 @@ export const useMessage = (connection: Connection) => {
148161
};
149162

150163
const getMessages = useCallback(
151-
(contact: string) => {
152-
return messages[contact] ?? [];
164+
(_contactName: string) => {
165+
const contactName = normalizeEnsName(_contactName);
166+
console.log('get messages for ', contactName);
167+
console.log('return messages ', messages[contactName] ?? []);
168+
return messages[contactName] ?? [];
153169
},
154170
[messages],
155171
);
156172

157-
const loadInitialMessages = async (contactName: string) => {
173+
const fetchMessagesFromStorage = async (contactName: string) => {
158174
setContactsLoading((prev) => {
159175
return [...prev, contactName];
160176
});
161177
const MAX_MESSAGES_PER_CHUNK = 100;
162178
const numberOfmessages = await getNumberOfMessages(contactName);
163-
const lastMessages = await getMessagesFromStorage(
179+
const storedMessages = await getMessagesFromStorage(
164180
contactName,
165181
Math.floor(numberOfmessages / MAX_MESSAGES_PER_CHUNK),
166182
);
167183

168-
console.log(numberOfmessages, lastMessages);
169-
console.log(contactName, lastMessages);
184+
console.log(
185+
`got messages from Storage for ${contactName}`,
186+
storedMessages,
187+
);
170188

171-
const messages = lastMessages.filter(
172-
({ envelop }: StorageEnvelopContainer) => {
173-
return envelop.message.metadata?.type === MessageActionType.NEW;
174-
},
189+
return storedMessages;
190+
};
191+
192+
const fetchMessagesFromDeliveryService = async (contactName: string) => {
193+
//Fetch the pending messages from the delivery service
194+
const encryptedIncommingMessages = await fetchNewMessages(
195+
mainnetProvider,
196+
account!,
197+
deliveryServiceToken!,
198+
contactName,
199+
);
200+
201+
const incommingMessages: StorageEnvelopContainer[] = await Promise.all(
202+
encryptedIncommingMessages.map(async (envelop) => {
203+
const decryptedEnvelop: Envelop = {
204+
message: JSON.parse(
205+
await decryptAsymmetric(
206+
profileKeys?.encryptionKeyPair!,
207+
JSON.parse(envelop.message),
208+
),
209+
),
210+
postmark: JSON.parse(
211+
await decryptAsymmetric(
212+
profileKeys?.encryptionKeyPair!,
213+
JSON.parse(envelop.postmark!),
214+
),
215+
),
216+
metadata: envelop.metadata,
217+
};
218+
return {
219+
envelop: decryptedEnvelop,
220+
//Messages from the delivery service are already send by the sender
221+
messageState: MessageState.Send,
222+
};
223+
}),
224+
);
225+
226+
console.log(
227+
`got messages from DS for ${contactName}`,
228+
incommingMessages,
175229
);
230+
231+
return incommingMessages;
232+
};
233+
234+
const loadInitialMessages = async (_contactName: string) => {
235+
const contactName = normalizeEnsName(_contactName);
236+
237+
const initialMessages = await Promise.all([
238+
fetchMessagesFromDeliveryService(contactName),
239+
fetchMessagesFromStorage(contactName),
240+
]);
241+
242+
const messages = initialMessages
243+
.reduce((acc, val) => acc.concat(val), [])
244+
.filter(({ envelop }: StorageEnvelopContainer) => {
245+
return envelop.message.metadata?.type === MessageActionType.NEW;
246+
});
247+
176248
setMessages((prev) => {
177249
return {
178250
...prev,

0 commit comments

Comments
 (0)