Skip to content

Commit 3538065

Browse files
author
Karl
committed
Merge branch 'develop' into feature/add-vue-skd-demo
2 parents df4d75c + 648894a commit 3538065

19 files changed

+763
-136
lines changed

packages/js-sdk/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"@babel/preset-env": "^7.19.4",
3636
"@babel/preset-typescript": "^7.18.6",
3737
"@types/supertest": "^2.0.12",
38+
"axios-mock-adapter": "^2.1.0",
3839
"babel-cli": "^6.26.0",
3940
"babel-jest": "^29.2.2",
4041
"babel-preset-env": "^1.7.0",

packages/js-sdk/src/Dm3.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { Conversations } from './conversation/Conversations';
2-
import { Tld } from './tld/Tld';
2+
import { ITLDResolver } from './tld/nameService/ITLDResolver';
33

44
export class Dm3 {
55
public readonly conversations: Conversations;
6-
public readonly tld: Tld;
6+
public readonly tld: ITLDResolver;
77

8-
constructor(conversations: Conversations, tld: Tld) {
8+
constructor(conversations: Conversations, tld: ITLDResolver) {
99
this.conversations = conversations;
1010
this.tld = tld;
1111
}

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

+226-23
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,237 @@
1+
import { StorageAPI } from '@dm3-org/dm3-lib-storage';
2+
import {
3+
getMockDeliveryServiceProfile,
4+
MockDeliveryServiceProfile,
5+
MockedUserProfile,
6+
MockMessageFactory,
7+
mockUserProfile,
8+
} from '@dm3-org/dm3-lib-test-helper';
9+
import axios from 'axios';
110
import { ethers } from 'ethers';
211
import { Dm3Sdk, Dm3SdkConfig } from './Dm3Sdk';
3-
import { StorageAPI } from '@dm3-org/dm3-lib-storage';
12+
13+
import MockAdapter from 'axios-mock-adapter';
14+
import { normalizeEnsName } from '@dm3-org/dm3-lib-profile';
15+
import { ITLDResolver } from './tld/nameService/ITLDResolver';
416

517
describe('Dm3Sdk', () => {
6-
let upController: ethers.Signer;
18+
let alice: MockedUserProfile;
19+
let bob: MockedUserProfile;
20+
let karl: MockedUserProfile;
21+
22+
//Axios mock to mock the http requests
23+
let axiosMock;
24+
25+
let deliveryService: MockDeliveryServiceProfile;
726

827
beforeEach(async () => {
9-
upController = ethers.Wallet.createRandom();
28+
alice = await mockUserProfile(
29+
ethers.Wallet.createRandom(),
30+
'alice.up',
31+
['test.io'],
32+
);
33+
bob = await mockUserProfile(ethers.Wallet.createRandom(), 'bob.up', [
34+
'test.io',
35+
]);
36+
37+
karl = await mockUserProfile(ethers.Wallet.createRandom(), 'karl.up', [
38+
'test.io',
39+
]);
40+
41+
deliveryService = await getMockDeliveryServiceProfile(
42+
ethers.Wallet.createRandom(),
43+
'http://localhost:3000',
44+
);
45+
axiosMock = new MockAdapter(axios);
46+
47+
//Mock BackendConnector HttpRequests
48+
//Mock profileExistsOnDeliveryService
49+
axiosMock
50+
.onGet(
51+
`http://localhost:4060/profile/${normalizeEnsName(
52+
alice.address,
53+
)}.addr.test`,
54+
)
55+
.reply(200);
56+
//Mock getChallenge
57+
axiosMock
58+
.onGet(
59+
`http://localhost:4060/auth/${normalizeEnsName(
60+
alice.address,
61+
)}.addr.test`,
62+
)
63+
.reply(200, 'mock-challenge');
64+
65+
//Mock getToken
66+
axiosMock
67+
.onPost(
68+
`http://localhost:4060/auth/${normalizeEnsName(
69+
alice.address,
70+
)}.addr.test`,
71+
)
72+
.reply(200);
1073
});
1174

12-
it('test', async () => {
13-
const luksoProvider = () => ({
14-
send: () => Promise.resolve([]),
15-
getSigner: () => Promise.resolve(upController),
75+
describe('conversations', () => {
76+
it('can add a conversation to the contact list', async () => {
77+
const mockTldResolver = {
78+
resolveTLDtoAlias: async () =>
79+
`${normalizeEnsName(bob.address)}.addr.test`,
80+
resolveAliasToTLD: async () => 'bob.eth',
81+
} as unknown as ITLDResolver;
82+
83+
const mockConfig: Dm3SdkConfig = {
84+
mainnetProvider: {} as ethers.providers.JsonRpcProvider,
85+
storageApi: {
86+
addConversation: async () => {},
87+
} as unknown as StorageAPI,
88+
nonce: '1',
89+
defaultDeliveryService: 'test.io',
90+
addressEnsSubdomain: '.addr.test',
91+
userEnsSubdomain: '.user.test',
92+
resolverBackendUrl: 'resolver.io',
93+
backendUrl: 'http://localhost:4060',
94+
_tld: mockTldResolver,
95+
};
96+
97+
const dm3 = await new Dm3Sdk(mockConfig).login({
98+
profileKeys: alice.profileKeys,
99+
profile: alice.signedUserProfile,
100+
accountAddress: alice.address,
101+
});
102+
103+
await dm3.conversations.addConversation('bob.eth');
104+
expect(dm3.conversations.list.length).toBe(1);
105+
expect(dm3.conversations.list[0].contact.name).toBe('bob.eth');
106+
});
107+
it('can multiple conversations to the contact list', async () => {
108+
const mockTldResolver = {
109+
resolveTLDtoAlias: async (ensName: string) => {
110+
if (ensName === 'alice.eth') {
111+
return `${normalizeEnsName(alice.address)}.addr.test`;
112+
}
113+
if (ensName === 'bob.eth') {
114+
return `${normalizeEnsName(bob.address)}.addr.test`;
115+
}
116+
return `${normalizeEnsName(karl.address)}.addr.test`;
117+
},
118+
resolveAliasToTLD: async (ensName: string) => {
119+
if (
120+
normalizeEnsName(ensName) ===
121+
normalizeEnsName(alice.address) + '.addr.test'
122+
) {
123+
return 'alice.eth';
124+
}
125+
if (
126+
normalizeEnsName(ensName) ===
127+
normalizeEnsName(bob.address) + '.addr.test'
128+
) {
129+
return 'bob.eth';
130+
}
131+
return 'karl.eth';
132+
},
133+
} as unknown as ITLDResolver;
134+
135+
const mockConfig: Dm3SdkConfig = {
136+
mainnetProvider: {} as ethers.providers.JsonRpcProvider,
137+
storageApi: {
138+
addConversation: async () => {},
139+
} as unknown as StorageAPI,
140+
nonce: '1',
141+
defaultDeliveryService: 'test.io',
142+
addressEnsSubdomain: '.addr.test',
143+
userEnsSubdomain: '.user.test',
144+
resolverBackendUrl: 'resolver.io',
145+
backendUrl: 'http://localhost:4060',
146+
_tld: mockTldResolver,
147+
};
148+
149+
const dm3 = await new Dm3Sdk(mockConfig).login({
150+
profileKeys: alice.profileKeys,
151+
profile: alice.signedUserProfile,
152+
accountAddress: alice.address,
153+
});
154+
155+
await dm3.conversations.addConversation('bob.eth');
156+
await dm3.conversations.addConversation('karl.eth');
157+
158+
expect(dm3.conversations.list.length).toBe(2);
159+
expect(dm3.conversations.list[0].contact.name).toBe('bob.eth');
160+
expect(dm3.conversations.list[1].contact.name).toBe('karl.eth');
161+
});
162+
it('dont add duplicate conversations', async () => {
163+
const mockTldResolver = {
164+
resolveTLDtoAlias: async () =>
165+
`${normalizeEnsName(bob.address)}.addr.test`,
166+
resolveAliasToTLD: async () => 'bob.eth',
167+
} as unknown as ITLDResolver;
168+
169+
const mockConfig: Dm3SdkConfig = {
170+
mainnetProvider: {} as ethers.providers.JsonRpcProvider,
171+
storageApi: {
172+
addConversation: async () => {},
173+
} as unknown as StorageAPI,
174+
nonce: '1',
175+
defaultDeliveryService: 'test.io',
176+
addressEnsSubdomain: '.addr.test',
177+
userEnsSubdomain: '.user.test',
178+
resolverBackendUrl: 'resolver.io',
179+
backendUrl: 'http://localhost:4060',
180+
_tld: mockTldResolver,
181+
};
182+
183+
const dm3 = await new Dm3Sdk(mockConfig).login({
184+
profileKeys: alice.profileKeys,
185+
profile: alice.signedUserProfile,
186+
accountAddress: alice.address,
187+
});
188+
189+
await dm3.conversations.addConversation('bob.eth');
190+
await dm3.conversations.addConversation('bob.eth');
191+
expect(dm3.conversations.list.length).toBe(1);
192+
expect(dm3.conversations.list[0].contact.name).toBe('bob.eth');
193+
});
194+
});
195+
196+
describe('Messages', () => {
197+
it('can send a message', async () => {
198+
const mockTldResolver = {
199+
resolveTLDtoAlias: async () =>
200+
`${normalizeEnsName(bob.address)}.addr.test`,
201+
resolveAliasToTLD: async () => 'bob.eth',
202+
} as unknown as ITLDResolver;
203+
204+
const mockConfig: Dm3SdkConfig = {
205+
mainnetProvider: {} as ethers.providers.JsonRpcProvider,
206+
storageApi: {
207+
addConversation: async () => {},
208+
addMessage: async () => {},
209+
} as unknown as StorageAPI,
210+
nonce: '1',
211+
defaultDeliveryService: 'test.io',
212+
addressEnsSubdomain: '.addr.test',
213+
userEnsSubdomain: '.user.test',
214+
resolverBackendUrl: 'resolver.io',
215+
backendUrl: 'http://localhost:4060',
216+
_tld: mockTldResolver,
217+
};
218+
219+
const dm3 = await new Dm3Sdk(mockConfig).login({
220+
profileKeys: alice.profileKeys,
221+
profile: alice.signedUserProfile,
222+
accountAddress: alice.address,
223+
});
224+
225+
expect(
226+
(await dm3.conversations.addConversation('bob.eth'))?.messages
227+
.list.length,
228+
).toBe(0);
229+
230+
const c = await dm3.conversations.addConversation('bob.eth');
231+
232+
await c?.messages.sendMessage('Hi');
233+
expect(c?.messages.list.length).toBe(1);
234+
expect(c?.messages.list[0].envelop.message.message).toBe('Hi');
16235
});
17-
const mockConfig: Dm3SdkConfig = {
18-
mainnetProvider: {} as ethers.providers.JsonRpcProvider,
19-
lukso: luksoProvider as any,
20-
nonce: '1',
21-
defaultDeliveryService: 'test.io',
22-
addressEnsSubdomain: 'addr.test',
23-
userEnsSubdomain: 'user.test',
24-
resolverBackendUrl: 'resolver.io',
25-
backendUrl: 'backend.io',
26-
storageApi: {} as StorageAPI,
27-
};
28-
29-
// const dm3 = await new Dm3Sdk().universalProfileLogin();
30-
// await dm3.conversations.addConversation('karl.eth');
31-
// const c = dm3.conversations.list;
32-
// const karl = c[0];
33236
});
34237
});

packages/js-sdk/src/Dm3Sdk.ts

+46-22
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { StorageAPI } from '@dm3-org/dm3-lib-storage';
1313
import { ethers } from 'ethers';
1414
import { Tld } from './tld/Tld';
1515
import { Dm3 } from './Dm3';
16+
import { ITLDResolver } from './tld/nameService/ITLDResolver';
1617

1718
/**
1819
* DM3SDK
@@ -36,7 +37,7 @@ export interface Dm3SdkConfig {
3637
userEnsSubdomain: string;
3738
resolverBackendUrl: string;
3839
backendUrl: string;
39-
lukso?: ethers.providers.ExternalProvider;
40+
_tld?: ITLDResolver;
4041
}
4142

4243
export class Dm3Sdk {
@@ -69,6 +70,11 @@ export class Dm3Sdk {
6970
*/
7071
public conversations: Conversations;
7172

73+
/**
74+
* DM3 TLD
75+
*/
76+
private _tld?: ITLDResolver;
77+
7278
constructor(config: Dm3SdkConfig) {
7379
//TODO keep ethers v5 for know but extract into common interface later
7480
this.mainnetProvider = config.mainnetProvider;
@@ -78,29 +84,30 @@ export class Dm3Sdk {
7884
this.addressEnsSubdomain = config.addressEnsSubdomain;
7985
this.userEnsSubdomain = config.userEnsSubdomain;
8086
this.resolverBackendUrl = config.resolverBackendUrl;
81-
//this.backendUrl = config.backendUrl;
82-
this.lukso = config.lukso;
87+
this.backendUrl = config.backendUrl;
8388
this.storageApi = config.storageApi;
89+
this._tld = config._tld;
8490
}
85-
86-
public async universalProfileLogin() {
87-
if (!this.lukso) {
88-
throw new Error('Lukso provider not found');
89-
}
90-
const tld = new Tld(
91-
this.mainnetProvider,
92-
this.addressEnsSubdomain,
93-
this.userEnsSubdomain,
94-
this.resolverBackendUrl,
95-
);
96-
const lc = await LuksoConnector._instance(
97-
this.lukso,
98-
this.nonce,
99-
this.defaultDeliveryService,
100-
);
101-
const loginResult = await lc.login();
102-
103-
const { profileKeys, profile, accountAddress } = loginResult as Success;
91+
/**
92+
* login can be used to login with a profile regardles the connector. Its also great for testing
93+
*/
94+
public async login({
95+
profileKeys,
96+
profile,
97+
accountAddress,
98+
}: {
99+
profileKeys: ProfileKeys;
100+
profile: SignedUserProfile;
101+
accountAddress: string;
102+
}) {
103+
const tld =
104+
this._tld ??
105+
new Tld(
106+
this.mainnetProvider,
107+
this.addressEnsSubdomain,
108+
this.userEnsSubdomain,
109+
this.resolverBackendUrl,
110+
);
104111

105112
this.profileKeys = profileKeys;
106113
this.profile = profile;
@@ -130,6 +137,7 @@ export class Dm3Sdk {
130137
tld,
131138
this.mainnetProvider,
132139
account,
140+
profileKeys,
133141
this.addressEnsSubdomain,
134142
);
135143

@@ -142,6 +150,22 @@ export class Dm3Sdk {
142150
return new Dm3(conversations, tld);
143151
}
144152

153+
//TODO use type of injected lukso provider
154+
public async universalProfileLogin(lukso: any) {
155+
if (!lukso) {
156+
throw new Error('Lukso provider not found');
157+
}
158+
const lc = await LuksoConnector._instance(
159+
lukso,
160+
this.nonce,
161+
this.defaultDeliveryService,
162+
);
163+
const loginResult = await lc.login();
164+
165+
const { profileKeys, profile, accountAddress } = loginResult as Success;
166+
return await this.login({ profileKeys, profile, accountAddress });
167+
}
168+
145169
private async initializeBackendConnector(
146170
accountAddress: string,
147171
profileKeys: ProfileKeys,

0 commit comments

Comments
 (0)