diff --git a/.yarnrc.yml b/.yarnrc.yml index 774c08021..b29a1efeb 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -1,17 +1,17 @@ nodeLinker: node-modules npmScopes: - testscope: - npmPublishRegistry: 'http://localhost:4873' - npmRegistryServer: 'http://localhost:4873' + testscope: + npmPublishRegistry: "http://localhost:4873" + npmRegistryServer: "http://localhost:4873" plugins: - - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs - spec: '@yarnpkg/plugin-workspace-tools' - - path: .yarn/plugins/@yarnpkg/plugin-version.cjs - spec: '@yarnpkg/plugin-version' + - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs + spec: "@yarnpkg/plugin-workspace-tools" + - path: .yarn/plugins/@yarnpkg/plugin-version.cjs + spec: "@yarnpkg/plugin-version" unsafeHttpWhitelist: - - localhost + - localhost yarnPath: .yarn/releases/yarn-3.5.1.cjs diff --git a/packages/js-sdk/package.json b/packages/js-sdk/package.json index 9f14bd40d..78f52048c 100644 --- a/packages/js-sdk/package.json +++ b/packages/js-sdk/package.json @@ -22,7 +22,7 @@ "@web3-name-sdk/core": "^0.2.0", "axios": "^0.27.2", "dotenv": "^16.0.1", - "ethers": "5", + "ethers": "5.7.2", "siwe": "^2.3.2", "socket.io-client": "^4.8.1" }, diff --git a/packages/js-sdk/src/Dm3.ts b/packages/js-sdk/src/Dm3.ts deleted file mode 100644 index 380f65eec..000000000 --- a/packages/js-sdk/src/Dm3.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Conversations } from './conversation/Conversations'; -import { ITLDResolver } from './tld/nameService/ITLDResolver'; - -export class Dm3 { - public readonly conversations: Conversations; - public readonly tld: ITLDResolver; - - constructor(conversations: Conversations, tld: ITLDResolver) { - this.conversations = conversations; - this.tld = tld; - } -} diff --git a/packages/js-sdk/src/Dm3Sdk.ts b/packages/js-sdk/src/Dm3Sdk.ts index 957c91194..2416ae69f 100644 --- a/packages/js-sdk/src/Dm3Sdk.ts +++ b/packages/js-sdk/src/Dm3Sdk.ts @@ -1,3 +1,4 @@ +import { EventEmitter } from 'events'; import { normalizeEnsName, ProfileKeys, @@ -12,7 +13,7 @@ import { BackendConnector } from './api/BackendConnector'; import { StorageAPI } from '@dm3-org/dm3-lib-storage'; import { ethers } from 'ethers'; import { Tld } from './tld/Tld'; -import { Dm3 } from './Dm3'; +// import { Dm3 } from './Dm3'; import { ITLDResolver } from './tld/nameService/ITLDResolver'; /** @@ -40,7 +41,7 @@ export interface Dm3SdkConfig { _tld?: ITLDResolver; } -export class Dm3Sdk { +export class Dm3Sdk extends EventEmitter { private readonly mainnetProvider: ethers.providers.JsonRpcProvider; private readonly lukso?: ethers.providers.ExternalProvider; @@ -70,12 +71,38 @@ export class Dm3Sdk { */ public conversations: Conversations; + private _selectedConversationId: string; + + getConversations() { + return this.conversations; + } + + getMessagesByConversation(ensName?: string) { + if (ensName) { + this._selectedConversationId = ensName; + } + + if (!this._selectedConversationId) { + throw new Error('No conversation selected'); + } + + // TODO: ens name might not be the best option to identify the conversation, we should introduce some id + const selectedConversation = this.conversations.list.find(c => c.contact.account.ensName === this._selectedConversationId); + + if (!selectedConversation) { + throw new Error('Selected conversation not found'); + } + + return selectedConversation.messages; + } + /** * DM3 TLD */ private _tld?: ITLDResolver; constructor(config: Dm3SdkConfig) { + super(); //TODO keep ethers v5 for know but extract into common interface later this.mainnetProvider = config.mainnetProvider; this.nonce = config.nonce; @@ -154,10 +181,15 @@ export class Dm3Sdk { account, profileKeys, this.addressEnsSubdomain, + (event: string, eventData: any) => { + this.emit('dm3_event', { event, eventData }); + }, ); await conversations._init(); - return new Dm3(conversations, tld); + this.conversations = conversations; + + return this; } /** diff --git a/packages/js-sdk/src/conversation/Conversations.ts b/packages/js-sdk/src/conversation/Conversations.ts index 8848e8704..d82f3f1a3 100644 --- a/packages/js-sdk/src/conversation/Conversations.ts +++ b/packages/js-sdk/src/conversation/Conversations.ts @@ -22,6 +22,7 @@ export class Conversations { private readonly account: Account; private readonly profileKeys: ProfileKeys; public list: Conversation[]; + private callback: (event: string, eventData: any) => void; constructor( storageApi: StorageAPI, @@ -30,6 +31,7 @@ export class Conversations { account: Account, profileKeys: ProfileKeys, addressEnsSubdomain: string, + callback: (event: string, eventData: any) => void, ) { this.storageApi = storageApi; this.tld = tld; @@ -38,6 +40,7 @@ export class Conversations { this.addressEnsSubdomain = addressEnsSubdomain; this.profileKeys = profileKeys; this.list = []; + this.callback = callback; } public async _init() { @@ -51,6 +54,7 @@ export class Conversations { } public async addConversation(_ensName: string) { + this.callback('start_add_conversation', { ensName: _ensName }); const contactTldName = normalizeEnsName(_ensName); const aliasName = await this.tld.resolveTLDtoAlias(contactTldName); @@ -65,6 +69,7 @@ export class Conversations { const conversationPreview = this._addConversation(newConversation); //Add the contact to the storage in the background this.storageApi.addConversation(aliasName, [contactTldName]); + this.callback('finalise_add_conversation', { ensName: _ensName }); return conversationPreview; } @@ -170,7 +175,7 @@ export class Conversations { contact: hydratedContact, }; this.list.push(hydratedConversation); - + this.callback('add_message', { ensName: contact.account.ensName }); return hydratedConversation; }; diff --git a/packages/js-sdk/src/index.ts b/packages/js-sdk/src/index.ts index 5b850624b..3433dfc16 100644 --- a/packages/js-sdk/src/index.ts +++ b/packages/js-sdk/src/index.ts @@ -1,4 +1,3 @@ export * from './Dm3Sdk'; -export * from './Dm3'; export * from './conversation/types'; export * from './message/types'; diff --git a/packages/messenger-vue-demo/src/composables/chat.ts b/packages/messenger-vue-demo/src/composables/chat.ts index f70a03887..0884aafb2 100644 --- a/packages/messenger-vue-demo/src/composables/chat.ts +++ b/packages/messenger-vue-demo/src/composables/chat.ts @@ -1,8 +1,8 @@ import { computed, ref, markRaw, type Ref } from 'vue'; -import { Dm3, Dm3Sdk, type Dm3SdkConfig } from '@dm3-org/dm3-js-sdk'; +import { Dm3Sdk, type Dm3SdkConfig } from '@dm3-org/dm3-js-sdk'; import {ethers} from 'ethers'; import type { Conversation } from '@dm3-org/dm3-lib-storage'; -import { transformToMessages, transformToRooms, type ChatRoom } from '@/chatUtils'; +import { transformToMessages, transformToRooms, type ChatRoom } from '../utils/chatUtils'; import { computedAsync } from '@vueuse/core'; const sepoliaProvider = new ethers.providers.JsonRpcProvider("https://eth-sepolia.g.alchemy.com/v2/cBTHRhVcZ3Vt4BOFpA_Hi5DcTB1KQQV1", { @@ -23,6 +23,10 @@ const configLukso: Dm3SdkConfig = { const sdk = new Dm3Sdk(configLukso); +sdk.on('dm3_event', (eventData) => { + console.log('dm3_event', eventData); +}); + // TODO: check for installed extension // https://docs.lukso.tech/install-up-browser-extension/ @@ -57,14 +61,14 @@ const requestProvider = (): Promise => { export function useDm3Chat(): UseDm3ChatReturnType { const roomsLoaded = ref(false); const messagesLoaded = ref(false); - const dm3Instance = ref(null); + const dm3Instance = ref(null); const isReady = ref(false); const selectedConversation = ref(null); const loggedInAccount = ref(null); const init = async () => { const dm3 = await sdk.universalProfileLoginWithCache(requestProvider); - dm3Instance.value = markRaw(dm3); + dm3Instance.value = dm3; isReady.value = true; loggedInAccount.value = 'TODO'; }; @@ -80,7 +84,7 @@ export function useDm3Chat(): UseDm3ChatReturnType { })); roomsLoaded.value = true; - return transformToRooms(conversationsPreview.value); + return transformToRooms(conversationsPreview.value as any); }); const messages = ref([]); diff --git a/packages/messenger-vue-demo/src/chatUtils.ts b/packages/messenger-vue-demo/src/utils/chatUtils.ts similarity index 99% rename from packages/messenger-vue-demo/src/chatUtils.ts rename to packages/messenger-vue-demo/src/utils/chatUtils.ts index 366908bb7..ab8505bcd 100644 --- a/packages/messenger-vue-demo/src/chatUtils.ts +++ b/packages/messenger-vue-demo/src/utils/chatUtils.ts @@ -79,8 +79,6 @@ export type ChatRoom = { export function transformToMessages(messagesData: any[]): any[] { return messagesData.map((message) => { - console.log('message', message); - // Ensure _id and senderId are valid const _id = message.envelop.id ? String(message.envelop.id) : "unknown_id"; const senderId = message.envelop.message.metadata.from ? String(message.envelop.message.metadata.from) : "unknown_sender"; diff --git a/packages/messenger-vue-demo/tsconfig.app.json b/packages/messenger-vue-demo/tsconfig.app.json index b066d0def..90bab659a 100644 --- a/packages/messenger-vue-demo/tsconfig.app.json +++ b/packages/messenger-vue-demo/tsconfig.app.json @@ -3,6 +3,7 @@ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], "exclude": ["src/**/__tests__/*"], "compilerOptions": { + "allowSyntheticDefaultImports": true, "noImplicitAny": false, "allowJs": true, "composite": true, diff --git a/packages/messenger-vue-demo/tsconfig.node.json b/packages/messenger-vue-demo/tsconfig.node.json index 5a0c6a54f..fe145662c 100644 --- a/packages/messenger-vue-demo/tsconfig.node.json +++ b/packages/messenger-vue-demo/tsconfig.node.json @@ -11,7 +11,7 @@ "composite": true, "noEmit": true, "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - + "allowSyntheticDefaultImports": true, "module": "ESNext", "moduleResolution": "Bundler", "types": ["node"] diff --git a/packages/messenger-vue-demo/vite.config.ts b/packages/messenger-vue-demo/vite.config.ts index 5f6d2e7c8..13cd87a56 100644 --- a/packages/messenger-vue-demo/vite.config.ts +++ b/packages/messenger-vue-demo/vite.config.ts @@ -3,7 +3,6 @@ import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueDevTools from 'vite-plugin-vue-devtools' - // https://vite.dev/config/ export default defineConfig({ plugins: [ @@ -20,21 +19,24 @@ export default defineConfig({ ], resolve: { alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) + '@/': fileURLToPath(new URL('./src', import.meta.url)) }, }, // due to built of libs with "module": "CommonJS", instead of "ESNext", we need to force pre-bundle them optimizeDeps: { - include: ['@dm3-org/dm3-js-sdk', '@dm3-org/dm3-lib-crypto', 'dm3-org/dm3-lib-profile'], + include: ['@dm3-org/dm3-js-sdk', '@dm3-org/dm3-lib-crypto', '@dm3-org/dm3-lib-profile'], }, build: { + sourcemap: 'inline', commonjsOptions: { + transformMixedEsModules: true, // Ensure your library is included in CommonJS handling - include: [/node_modules/, - /@dm3-org\/dm3-js-sdk/, - /@dm3-org\/dm3-lib-crypto/, - /dm3-org\/dm3-lib-profile/, - /@dm3-org\/dm3-lib-storage/, + include: [ + 'node_modules/*', + '@dm3-org/dm3-js-sdk', + '@dm3-org/dm3-lib-crypto', + '@dm3-org/dm3-lib-profile', + '@dm3-org/dm3-lib-storage', ], }, }, diff --git a/yarn.lock b/yarn.lock index 0017f386f..407d0cfcd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2520,7 +2520,7 @@ __metadata: babel-jest: ^29.2.2 babel-preset-env: ^1.7.0 dotenv: ^16.0.1 - ethers: 5 + ethers: 5.7.2 jest: ^29.2.2 jest-mock-extended: 2.0.4 prettier: ^2.6.2 @@ -18277,7 +18277,7 @@ __metadata: languageName: node linkType: hard -"ethers@npm:5, ethers@npm:5.7.2, ethers@npm:^5.0.13, ethers@npm:^5.7.0, ethers@npm:^5.7.1, ethers@npm:^5.7.2": +"ethers@npm:5.7.2, ethers@npm:^5.0.13, ethers@npm:^5.7.0, ethers@npm:^5.7.1, ethers@npm:^5.7.2": version: 5.7.2 resolution: "ethers@npm:5.7.2" dependencies: