Skip to content

Commit 0c838b3

Browse files
committed
add Messages to SDK Api
1 parent 17dd080 commit 0c838b3

File tree

4 files changed

+106
-13
lines changed

4 files changed

+106
-13
lines changed

packages/js-sdk/src/Dm3Sdk.test.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ describe('Dm3Sdk', () => {
198198
});
199199
});
200200

201-
describe('messages', () => {
201+
describe('Messages', () => {
202202
it('can send a message', async () => {
203203
const mockTldResolver = {
204204
resolveTLDtoAlias: async () =>
@@ -235,6 +235,42 @@ describe('Dm3Sdk', () => {
235235
expect(c?.messages.list().length).toBe(0);
236236
await c?.messages.addMessage('bob.eth', msg1);
237237

238+
expect(c?.messages.list().length).toBe(1);
239+
expect(c?.messages.list()[0].envelop.message.message).toBe('Hi');
240+
});
241+
it('can send a message', async () => {
242+
const mockTldResolver = {
243+
resolveTLDtoAlias: async () =>
244+
`${normalizeEnsName(bob.address)}.addr.test`,
245+
resolveAliasToTLD: async () => 'bob.eth',
246+
} as unknown as ITLDResolver;
247+
248+
const mockConfig: Dm3SdkConfig = {
249+
mainnetProvider: {} as ethers.providers.JsonRpcProvider,
250+
storageApi: {
251+
addConversation: async () => {},
252+
addMessage: async () => {},
253+
} as unknown as StorageAPI,
254+
nonce: '1',
255+
defaultDeliveryService: 'test.io',
256+
addressEnsSubdomain: '.addr.test',
257+
userEnsSubdomain: '.user.test',
258+
resolverBackendUrl: 'resolver.io',
259+
backendUrl: 'http://localhost:4060',
260+
_tld: mockTldResolver,
261+
};
262+
263+
const dm3 = await new Dm3Sdk(mockConfig).login({
264+
profileKeys: alice.profileKeys,
265+
profile: alice.signedUserProfile,
266+
accountAddress: alice.address,
267+
});
268+
269+
const c = await dm3.conversations.addConversation('bob.eth');
270+
expect(c?.messages.list().length).toBe(0);
271+
272+
await c?.messages.sendMessage('Hi');
273+
238274
expect(c?.messages.list().length).toBe(1);
239275
expect(c?.messages.list()[0].envelop.message.message).toBe('Hi');
240276
});

packages/js-sdk/src/Dm3Sdk.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ export class Dm3Sdk {
137137
tld,
138138
this.mainnetProvider,
139139
account,
140+
profileKeys,
140141
this.addressEnsSubdomain,
141142
);
142143

packages/js-sdk/src/conversation/Conversations.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
/* eslint-disable max-len */
2-
import { Account, normalizeEnsName } from '@dm3-org/dm3-lib-profile';
2+
import {
3+
Account,
4+
normalizeEnsName,
5+
ProfileKeys,
6+
} from '@dm3-org/dm3-lib-profile';
37
import {
48
Conversation as ConversationDto,
59
StorageAPI,
@@ -16,21 +20,23 @@ export class Conversations {
1620
private readonly tld: ITLDResolver;
1721
private readonly addressEnsSubdomain: string;
1822
private readonly account: Account;
19-
23+
private readonly profileKeys: ProfileKeys;
2024
public list: Conversation[];
2125

2226
constructor(
2327
storageApi: StorageAPI,
2428
tld: ITLDResolver,
2529
mainnetProvider: ethers.providers.JsonRpcProvider,
2630
account: Account,
31+
profileKeys: ProfileKeys,
2732
addressEnsSubdomain: string,
2833
) {
2934
this.storageApi = storageApi;
3035
this.tld = tld;
3136
this.account = account;
3237
this.provider = mainnetProvider;
3338
this.addressEnsSubdomain = addressEnsSubdomain;
39+
this.profileKeys = profileKeys;
3440
this.list = [];
3541
}
3642

@@ -89,7 +95,13 @@ export class Conversations {
8995

9096
const newConversation: Conversation = {
9197
//TODO change that once Message class has been implemented
92-
messages: new Messages(this.storageApi, this),
98+
messages: new Messages(
99+
this.storageApi,
100+
this,
101+
this.account,
102+
this.profileKeys,
103+
newContact,
104+
),
93105
contact: newContact,
94106
};
95107
//Set the new contact to the list
@@ -103,7 +115,13 @@ export class Conversations {
103115
);
104116

105117
const hydratedConversation: Conversation = {
106-
messages: new Messages(this.storageApi, this),
118+
messages: new Messages(
119+
this.storageApi,
120+
this,
121+
this.account,
122+
this.profileKeys,
123+
hydratedContact,
124+
),
107125
contact: hydratedContact,
108126
};
109127
//find existing contact and replace it with the hydrated one
@@ -132,7 +150,13 @@ export class Conversations {
132150
this.addressEnsSubdomain,
133151
);
134152
const hydratedConversation: Conversation = {
135-
messages: new Messages(this.storageApi, this),
153+
messages: new Messages(
154+
this.storageApi,
155+
this,
156+
this.account,
157+
this.profileKeys,
158+
hydratedContact,
159+
),
136160
contact: hydratedContact,
137161
};
138162
this.list.push(hydratedConversation);

packages/js-sdk/src/message/Messages.ts

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { encryptAsymmetric } from '@dm3-org/dm3-lib-crypto';
1+
import { encryptAsymmetric, sign } from '@dm3-org/dm3-lib-crypto';
22
import {
33
buildEnvelop,
44
EncryptionEnvelop,
@@ -22,21 +22,53 @@ import { MessageModel, MessageSource } from './types';
2222
export class Messages {
2323
private readonly storageApi: StorageAPI;
2424
private readonly conversations: Conversations;
25-
private readonly account: Account;
26-
private readonly profileKeys: ProfileKeys;
2725

2826
private readonly _messages: MessageModel[];
2927

30-
constructor(storageApi: StorageAPI, conversations: Conversations) {
28+
private readonly senderAccount: Account;
29+
private readonly senderProfileKeys: ProfileKeys;
30+
private readonly receiver: Contact;
31+
32+
constructor(
33+
storageApi: StorageAPI,
34+
conversations: Conversations,
35+
senderAccount: Account,
36+
senderProfileKeys: ProfileKeys,
37+
receiver: Contact,
38+
) {
3139
this.storageApi = storageApi;
3240
this.conversations = conversations;
33-
41+
this.senderAccount = senderAccount;
42+
this.senderProfileKeys = senderProfileKeys;
43+
this.receiver = receiver;
3444
this._messages = [];
3545
}
3646

3747
public list() {
3848
return renderMessage(this._messages);
3949
}
50+
public async sendMessage(msg: string) {
51+
const messageWithoutSig: Omit<Message, 'signature'> = {
52+
message: msg,
53+
attachments: [],
54+
metadata: {
55+
referenceMessageHash: undefined,
56+
type: 'NEW',
57+
to: this.receiver.account.ensName,
58+
from: this.senderAccount.ensName,
59+
timestamp: new Date().getTime(),
60+
},
61+
};
62+
63+
const message: Message = {
64+
...messageWithoutSig,
65+
signature: await sign(
66+
this.senderProfileKeys.signingKeyPair.privateKey,
67+
stringify(messageWithoutSig),
68+
),
69+
};
70+
return await this.addMessage(this.receiver.account.ensName, message);
71+
}
4072

4173
public async addMessage(
4274
_contactName: string,
@@ -112,7 +144,7 @@ export class Messages {
112144
(publicKey: string, msg: string) =>
113145
encryptAsymmetric(publicKey, msg),
114146
{
115-
from: this.account!,
147+
from: this.senderAccount!,
116148
to: {
117149
...recipient!.account,
118150
//Cover edge case of lukso names. TODO discuss with the team and decide how to dela with non ENS names
@@ -121,7 +153,7 @@ export class Messages {
121153
: recipient.name,
122154
},
123155
deliverServiceProfile,
124-
keys: this.profileKeys!,
156+
keys: this.senderProfileKeys,
125157
},
126158
);
127159
},

0 commit comments

Comments
 (0)