From e7e0ed120e452514a28d3dc05c921dbb4a256c30 Mon Sep 17 00:00:00 2001 From: Mircea Hasegan Date: Fri, 10 Oct 2025 17:06:43 +0200 Subject: [PATCH 1/2] feat: pubnub based notification service --- apps/browser-extension-wallet/manifest.json | 2 +- .../background/notifications-center.ts | 99 ++------ .../background/notifications-service.ts | 103 ++++++++ .../webpack.common.sw.js | 7 + package.json | 1 + yarn.lock | 234 +++++++++++++++++- 6 files changed, 359 insertions(+), 87 deletions(-) create mode 100644 apps/browser-extension-wallet/src/lib/scripts/background/notifications-service.ts diff --git a/apps/browser-extension-wallet/manifest.json b/apps/browser-extension-wallet/manifest.json index f9f9d1d2f8..e3c1838ce8 100644 --- a/apps/browser-extension-wallet/manifest.json +++ b/apps/browser-extension-wallet/manifest.json @@ -18,7 +18,7 @@ "permissions": ["webRequest", "storage", "tabs", "unlimitedStorage"], "host_permissions": [""], "content_security_policy": { - "extension_pages": "default-src 'self' $LOCALHOST_DEFAULT_SRC; frame-src https://connect.trezor.io/ https://www.youtube-nocookie.com; script-src 'self' 'wasm-unsafe-eval'; font-src 'self' data: https://use.typekit.net; object-src 'self'; connect-src $MEMPOOLSPACE_URL $BLOCKFROST_URLS $MAESTRO_URLS $CARDANO_SERVICES_URLS $CARDANO_WS_SERVER_URLS $SENTRY_URL $DAPP_RADAR_APPI_URL https://coingecko.live-mainnet.eks.lw.iog.io https://coingecko.live-mainnet.eks.lw.iog.io https://muesliswap.live-mainnet.eks.lw.iog.io $LOCALHOST_CONNECT_SRC $POSTHOG_HOST https://use.typekit.net https://api.handle.me/ https://*.api.handle.me/ data:; style-src * 'unsafe-inline'; img-src * data: blob:;" + "extension_pages": "default-src 'self' $LOCALHOST_DEFAULT_SRC; frame-src https://connect.trezor.io/ https://www.youtube-nocookie.com; script-src 'self' 'wasm-unsafe-eval'; font-src 'self' data: https://use.typekit.net; object-src 'self'; connect-src $MEMPOOLSPACE_URL $BLOCKFROST_URLS $MAESTRO_URLS $CARDANO_SERVICES_URLS $CARDANO_WS_SERVER_URLS $SENTRY_URL $DAPP_RADAR_APPI_URL https://coingecko.live-mainnet.eks.lw.iog.io https://coingecko.live-mainnet.eks.lw.iog.io https://muesliswap.live-mainnet.eks.lw.iog.io $LOCALHOST_CONNECT_SRC $POSTHOG_HOST https://use.typekit.net https://api.handle.me/ https://*.api.handle.me/ https://*.pndsn.com data:; style-src * 'unsafe-inline'; img-src * data: blob:;" }, "content_scripts": [ { diff --git a/apps/browser-extension-wallet/src/lib/scripts/background/notifications-center.ts b/apps/browser-extension-wallet/src/lib/scripts/background/notifications-center.ts index 7b4b024492..e841633c1a 100644 --- a/apps/browser-extension-wallet/src/lib/scripts/background/notifications-center.ts +++ b/apps/browser-extension-wallet/src/lib/scripts/background/notifications-center.ts @@ -1,107 +1,38 @@ import { runtime } from 'webextension-polyfill'; -import { of, ReplaySubject } from 'rxjs'; +import { of } from 'rxjs'; import { exposeApi } from '@cardano-sdk/web-extension'; import { - LaceNotification, NotificationsCenterProperties, notificationsCenterProperties, NotificationsTopic } from '@src/types/notifications-center'; import { logger } from '@lace/common'; +import { NotificationsService } from './notifications-service'; const exposeNotificationsCenterAPI = (): void => { - let notifications: LaceNotification[] = [ - { - message: { - body: 'The Glacier Drop phase 2 is live', - chain: 'Midnight', - format: 'plain', - id: 'id-1', - publisher: 'Midnight', - topicId: 'topic-1', - title: 'The Glacier Drop phase 2 is live' - } - }, - { - message: { - body: 'The new node version XYZ is out', - chain: 'Midnight', - format: 'plain', - id: 'id-2', - publisher: 'Midnight', - topicId: 'topic-2', - title: 'The new node version XYZ is out' - } - }, - { - message: { - body: 'The governance council has opened voting for governance action number 26.\nNIGHT holders are welcome to cast their votes until Aug-31 via the portal at\n\nhttps://governance.midnight.network', - chain: 'Cardano', - format: 'plain', - id: 'id-3', - publisher: 'Governance', - topicId: 'topic-1', - title: 'The governance council has opened voting for governance action number 26' - }, - read: true - } - ]; - - const topics: NotificationsTopic[] = [ - { id: 'topic-1', name: 'Topic One' }, - { id: 'topic-2', name: 'Topic Two', subscribed: true } - ]; - - const notifications$ = new ReplaySubject(1); - const topics$ = new ReplaySubject(1); - - const markAsRead = async (id?: LaceNotification['message']['id']): Promise => { - for (const notification of notifications) if (notification.message.id === id || !id) notification.read = true; - - notifications$.next(notifications); - - return Promise.resolve(); - }; - - const remove = async (id: LaceNotification['message']['id']): Promise => { - notifications = notifications.filter((notification) => notification.message.id !== id); - - notifications$.next(notifications); - - return Promise.resolve(); - }; - - const subscribe = async (topicId: NotificationsTopic['id']): Promise => { - for (const topic of topics) if (topic.id === topicId) topic.subscribed = true; - - topics$.next(topics); - - return Promise.resolve(); - }; - - const unsubscribe = async (topicId: NotificationsTopic['id']): Promise => { - for (const topic of topics) if (topic.id === topicId) delete topic.subscribed; - - topics$.next(topics); - - return Promise.resolve(); - }; - + const notificationsService = new NotificationsService(); exposeApi( { api$: of({ - notifications: { markAsRead, notifications$, remove }, - topics: { topics$, subscribe, unsubscribe } + notifications: { + markAsRead: async (id?: string): Promise => notificationsService.markAsRead(id), + notifications$: notificationsService.notifications$, + remove: async (id: string): Promise => notificationsService.remove(id) + }, + topics: { + topics$: notificationsService.topics$, + subscribe: async (topicId: NotificationsTopic['id']): Promise => + notificationsService.subscribe(topicId), + unsubscribe: async (topicId: NotificationsTopic['id']): Promise => + notificationsService.unsubscribe(topicId) + } }), baseChannel: 'notifications-center', properties: notificationsCenterProperties }, { logger, runtime } ); - - notifications$.next(notifications); - topics$.next(topics); }; if (!(globalThis as unknown as { LMP_BUNDLE: boolean }).LMP_BUNDLE) exposeNotificationsCenterAPI(); diff --git a/apps/browser-extension-wallet/src/lib/scripts/background/notifications-service.ts b/apps/browser-extension-wallet/src/lib/scripts/background/notifications-service.ts new file mode 100644 index 0000000000..27b07438be --- /dev/null +++ b/apps/browser-extension-wallet/src/lib/scripts/background/notifications-service.ts @@ -0,0 +1,103 @@ +import { LaceMessage, LaceNotification, NotificationsTopic } from '@src/types/notifications-center'; +import PubNub from 'pubnub'; +import { ReplaySubject } from 'rxjs'; + +const SUBSCRIBE_KEY = 'sub-c-95c77e55-b9e9-4f62-9584-6c907b0976c0'; +const USER_ID = 'lace-user-uuid-to-be-replaced'; + +export class NotificationsService { + private pubnub: PubNub; + private notifications: LaceNotification[] = []; + private topics: (NotificationsTopic & { subscription?: PubNub.Subscription })[] = []; + + topics$ = new ReplaySubject(1); + notifications$ = new ReplaySubject(1); + + constructor() { + this.pubnub = new PubNub({ + subscribeKey: SUBSCRIBE_KEY, + userId: USER_ID + }); + + this.pubnub.addListener({ + message: (message) => { + // eslint-disable-next-line no-console + console.log('[DEBUG] message', message); + const { title, body, chain, id } = message.message as unknown as LaceMessage; + this.notifications = [ + { + message: { + title, + body, + chain, + format: 'plain', + id, + publisher: 'Midnight Foundation', + topicId: message.channel + }, + read: false + }, + ...this.notifications + ]; + this.emitNotifications(); + } + }); + + // TODO: get topics every 5 minutes + this.fetchTopics(); + } + + private async fetchTopics(): Promise { + const response = await this.pubnub.objects.getAllChannelMetadata({ + include: { + totalCount: true + } + }); + + const newTopics = response.data.map((item) => ({ + id: item.id, + name: item.name, + subscribed: this.topics.find((t) => t.id === item.id)?.subscribed ?? false + })); + + this.topics = newTopics; + this.emitTopics(); + } + + subscribe(topicId: NotificationsTopic['id']): void { + const subscription = this.pubnub.channel(topicId).subscription(); + subscription.subscribe(); + this.topics = this.topics.map((t) => (t.id === topicId ? { ...t, subscribed: true, subscription } : t)); + this.emitTopics(); + } + + unsubscribe(topicId: NotificationsTopic['id']): void { + const topic = this.topics.find((t) => t.id === topicId); + if (topic) { + topic.subscription?.unsubscribe(); + topic.subscription = undefined; + topic.subscribed = false; + } + this.emitTopics(); + } + + markAsRead(id?: string): void { + for (const notification of this.notifications) if (notification.message.id === id || !id) notification.read = true; + + this.emitNotifications(); + } + + remove(id: string): void { + this.notifications = this.notifications.filter((notification) => notification.message.id !== id); + + this.emitNotifications(); + } + + private emitNotifications(): void { + this.notifications$.next(this.notifications); + } + + private emitTopics(): void { + this.topics$.next(this.topics.map((t) => ({ id: t.id, name: t.name, subscribed: t.subscribed }))); + } +} diff --git a/apps/browser-extension-wallet/webpack.common.sw.js b/apps/browser-extension-wallet/webpack.common.sw.js index 9d02816ab4..23bd16e17c 100644 --- a/apps/browser-extension-wallet/webpack.common.sw.js +++ b/apps/browser-extension-wallet/webpack.common.sw.js @@ -25,6 +25,13 @@ module.exports = () => }, // The background script in Firefox is a hidden DOM page, so target is web target: process.env.BROWSER === 'firefox' ? 'web' : 'webworker', + resolve: { + // Force PubNub to use Node.js version instead of browser version + // Browser version requires window object which is not available in service workers + alias: { + pubnub: path.resolve(__dirname, '../../node_modules/pubnub/lib/node/index.js') + } + }, module: { // configuration regarding modules rules: [ diff --git a/package.json b/package.json index 243a1e818a..daff5f341e 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,7 @@ "axios": "^1.9.0", "normalize.css": "^8.0.1", "openpgp": "^6.1.1", + "pubnub": "^10.1.0", "uuid": "^8.3.2" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 55ccacf944..037f5ea397 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25392,6 +25392,15 @@ __metadata: languageName: node linkType: hard +"agentkeepalive@npm:^3.5.2": + version: 3.5.3 + resolution: "agentkeepalive@npm:3.5.3" + dependencies: + humanize-ms: ^1.2.1 + checksum: c56879ca38fcf600ba1cd15ddf3fabd6de6e937a4762bfe6d8b75ac590eb3532ae00b1b986617afd37360e36e4e11d0be8d6612669312fff92a51cf4c3cfca7a + languageName: node + linkType: hard + "agentkeepalive@npm:^4.1.3, agentkeepalive@npm:^4.5.0": version: 4.5.0 resolution: "agentkeepalive@npm:4.5.0" @@ -26383,6 +26392,20 @@ __metadata: languageName: node linkType: hard +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 9102e246d1ed9b37ac36f57f0a6ca55226876553251a31fc80677e71471f463a54c872dc78d5d7f80740c8ba624395cccbe8b60f7b690c4418f487d8e9fd1106 + languageName: node + linkType: hard + +"async-generator-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-generator-function@npm:1.0.0" + checksum: 74a71a4a2dd7afd06ebb612f6d612c7f4766a351bedffde466023bf6dae629e46b0d2cd38786239e0fbf245de0c7df76035465e16d1213774a0efb22fec0d713 + languageName: node + linkType: hard + "async-limiter@npm:~1.0.0": version: 1.0.1 resolution: "async-limiter@npm:1.0.1" @@ -28089,7 +28112,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:5.7.1, buffer@npm:^5.2.1, buffer@npm:^5.5.0, buffer@npm:^5.6.0, buffer@npm:^5.7.1": +"buffer@npm:5.7.1, buffer@npm:^5.2.1, buffer@npm:^5.4.3, buffer@npm:^5.5.0, buffer@npm:^5.6.0, buffer@npm:^5.7.1": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -28665,6 +28688,20 @@ __metadata: languageName: node linkType: hard +"cbor-js@npm:^0.1.0": + version: 0.1.0 + resolution: "cbor-js@npm:0.1.0" + checksum: 9267e1d1eda70d34994fec05bb1aa53541673276131ff776194ee7b41e4ee80aec8c5c33f3a1bea3d393f9724c4f46c217b89ee2bcff6e35de583f3c533050fd + languageName: node + linkType: hard + +"cbor-sync@npm:^1.0.4": + version: 1.0.4 + resolution: "cbor-sync@npm:1.0.4" + checksum: 147834c64b43511b2ea601f02bc2cc4190ec8d41a7b8dc3e9037c636b484ca2124bc7d49da7a0f775ea5153ff799d57e45992816851dbb1d61335f308a0d0120 + languageName: node + linkType: hard + "cbor@npm:^9.0.1": version: 9.0.2 resolution: "cbor@npm:9.0.2" @@ -33347,6 +33384,18 @@ __metadata: languageName: node linkType: hard +"es-set-tostringtag@npm:^2.1.0": + version: 2.1.0 + resolution: "es-set-tostringtag@npm:2.1.0" + dependencies: + es-errors: ^1.3.0 + get-intrinsic: ^1.2.6 + has-tostringtag: ^1.0.2 + hasown: ^2.0.2 + checksum: 789f35de4be3dc8d11fdcb91bc26af4ae3e6d602caa93299a8c45cf05d36cc5081454ae2a6d3afa09cceca214b76c046e4f8151e092e6fc7feeb5efb9e794fc6 + languageName: node + linkType: hard + "es-shim-unscopables@npm:^1.0.0": version: 1.0.0 resolution: "es-shim-unscopables@npm:1.0.0" @@ -35806,6 +35855,13 @@ __metadata: languageName: node linkType: hard +"fflate@npm:^0.8.2": + version: 0.8.2 + resolution: "fflate@npm:0.8.2" + checksum: 29470337b85d3831826758e78f370e15cda3169c5cd4477c9b5eea2402261a74b2975bae816afabe1c15d21d98591e0d30a574f7103aa117bff60756fa3035d4 + languageName: node + linkType: hard + "figures@npm:^3.0.0, figures@npm:^3.1.0, figures@npm:^3.2.0": version: 3.2.0 resolution: "figures@npm:3.2.0" @@ -36339,6 +36395,19 @@ __metadata: languageName: node linkType: hard +"form-data@npm:^4.0.4": + version: 4.0.4 + resolution: "form-data@npm:4.0.4" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.8 + es-set-tostringtag: ^2.1.0 + hasown: ^2.0.2 + mime-types: ^2.1.12 + checksum: 9b7788836df9fa5a6999e0c02515b001946b2a868cfe53f026c69e2c537a2ff9fbfb8e9d2b678744628f3dc7a2d6e14e4e45dfaf68aa6239727f0bdb8ce0abf2 + languageName: node + linkType: hard + "format@npm:^0.2.0": version: 0.2.2 resolution: "format@npm:0.2.2" @@ -36772,6 +36841,13 @@ __metadata: languageName: node linkType: hard +"generator-function@npm:^2.0.0": + version: 2.0.1 + resolution: "generator-function@npm:2.0.1" + checksum: 3bf87f7b0230de5d74529677e6c3ceb3b7b5d9618b5a22d92b45ce3876defbaf5a77791b25a61b0fa7d13f95675b5ff67a7769f3b9af33f096e34653519e873d + languageName: node + linkType: hard + "generic-names@npm:^2.0.1": version: 2.0.1 resolution: "generic-names@npm:2.0.1" @@ -36883,6 +36959,27 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.6": + version: 1.3.1 + resolution: "get-intrinsic@npm:1.3.1" + dependencies: + async-function: ^1.0.0 + async-generator-function: ^1.0.0 + call-bind-apply-helpers: ^1.0.2 + es-define-property: ^1.0.1 + es-errors: ^1.3.0 + es-object-atoms: ^1.1.1 + function-bind: ^1.1.2 + generator-function: ^2.0.0 + get-proto: ^1.0.1 + gopd: ^1.2.0 + has-symbols: ^1.1.0 + hasown: ^2.0.2 + math-intrinsics: ^1.1.0 + checksum: c02b3b6a445f9cd53e14896303794ac60f9751f58a69099127248abdb0251957174c6524245fc68579dc8e6a35161d3d94c93e665f808274716f4248b269436a + languageName: node + linkType: hard + "get-nonce@npm:^1.0.0": version: 1.0.1 resolution: "get-nonce@npm:1.0.1" @@ -38613,7 +38710,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.1": +"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.6": version: 7.0.6 resolution: "https-proxy-agent@npm:7.0.6" dependencies: @@ -39118,6 +39215,13 @@ __metadata: languageName: node linkType: hard +"ip-address@npm:^10.0.1": + version: 10.0.1 + resolution: "ip-address@npm:10.0.1" + checksum: 525d5391cfd31a91f80f5857e98487aeaa8474e860a6725a0b6461ac8e436c7f8c869774dece391c8f8e7486306a34a4d1c094778c4c583a3f1f2cd905e5ed50 + languageName: node + linkType: hard + "ip-address@npm:^9.0.5": version: 9.0.5 resolution: "ip-address@npm:9.0.5" @@ -42516,6 +42620,7 @@ __metadata: p-retry: 5.1.2 postcss: 8.4.31 prettier: ^2.3.2 + pubnub: ^10.1.0 raw-loader: ^4.0.2 rollup: 2.56.3 rollup-plugin-cleaner: 1.0.0 @@ -42866,6 +42971,13 @@ __metadata: languageName: node linkType: hard +"lil-uuid@npm:^0.1.1": + version: 0.1.1 + resolution: "lil-uuid@npm:0.1.1" + checksum: 1ca634ede9930a5c0c379525cbe1cbc84d849836154428bb1d74e83e4f22380fc63e0c2ba6c0ed97296cc55bcbb52a1486846410078bd293c1a26b1658a26fdf + languageName: node + linkType: hard + "lilconfig@npm:^2.0.3": version: 2.0.3 resolution: "lilconfig@npm:2.0.3" @@ -46360,6 +46472,22 @@ __metadata: languageName: node linkType: hard +"pac-proxy-agent@npm:^7.1.0": + version: 7.2.0 + resolution: "pac-proxy-agent@npm:7.2.0" + dependencies: + "@tootallnate/quickjs-emscripten": ^0.23.0 + agent-base: ^7.1.2 + debug: ^4.3.4 + get-uri: ^6.0.1 + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.6 + pac-resolver: ^7.0.1 + socks-proxy-agent: ^8.0.5 + checksum: 099c1bc8944da6a98e8b7de1fbf23e4014bc3063f66a7c29478bd852c1162e1d086a4f80f874f40961ebd5c516e736aed25852db97b79360cbdcc9db38086981 + languageName: node + linkType: hard + "pac-resolver@npm:^7.0.0": version: 7.0.0 resolution: "pac-resolver@npm:7.0.0" @@ -46371,6 +46499,16 @@ __metadata: languageName: node linkType: hard +"pac-resolver@npm:^7.0.1": + version: 7.0.1 + resolution: "pac-resolver@npm:7.0.1" + dependencies: + degenerator: ^5.0.0 + netmask: ^2.0.2 + checksum: 839134328781b80d49f9684eae1f5c74f50a1d4482076d44c84fc2f3ca93da66fa11245a4725a057231e06b311c20c989fd0681e662a0792d17f644d8fe62a5e + languageName: node + linkType: hard + "package-hash@npm:^4.0.0": version: 4.0.0 resolution: "package-hash@npm:4.0.0" @@ -48483,6 +48621,22 @@ __metadata: languageName: node linkType: hard +"proxy-agent@npm:^6.3.0": + version: 6.5.0 + resolution: "proxy-agent@npm:6.5.0" + dependencies: + agent-base: ^7.1.2 + debug: ^4.3.4 + http-proxy-agent: ^7.0.1 + https-proxy-agent: ^7.0.6 + lru-cache: ^7.14.1 + pac-proxy-agent: ^7.1.0 + proxy-from-env: ^1.1.0 + socks-proxy-agent: ^8.0.5 + checksum: d03ad2d171c2768280ade7ea6a7c5b1d0746215d70c0a16e02780c26e1d347edd27b3f48374661ae54ec0f7b41e6e45175b687baf333b36b1fd109a525154806 + languageName: node + linkType: hard + "proxy-from-env@npm:^1.0.0, proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -48525,6 +48679,25 @@ __metadata: languageName: node linkType: hard +"pubnub@npm:^10.1.0": + version: 10.1.0 + resolution: "pubnub@npm:10.1.0" + dependencies: + agentkeepalive: ^3.5.2 + buffer: ^6.0.3 + cbor-js: ^0.1.0 + cbor-sync: ^1.0.4 + fflate: ^0.8.2 + form-data: ^4.0.4 + lil-uuid: ^0.1.1 + node-fetch: ^2.7.0 + proxy-agent: ^6.3.0 + react-native-url-polyfill: ^2.0.0 + text-encoding: ^0.7.0 + checksum: 6f8178b7f46a34d6abca718a2b9a640c900f772d8aea34e6b35b0c5a5b4e85b9ef7d9af9b956e94d2534367b6c592a5273191203377e1ea511ef5e8a9ccd8c13 + languageName: node + linkType: hard + "pump@npm:^2.0.0": version: 2.0.1 resolution: "pump@npm:2.0.1" @@ -49935,6 +50108,17 @@ __metadata: languageName: node linkType: hard +"react-native-url-polyfill@npm:^2.0.0": + version: 2.0.0 + resolution: "react-native-url-polyfill@npm:2.0.0" + dependencies: + whatwg-url-without-unicode: 8.0.0-3 + peerDependencies: + react-native: "*" + checksum: 1a2e1030a62fd093764b5330ce0ff34d72246e581dd2892cddc347d8621931aeb2c9ea3e054960484a1259230e8461e569e1890f1ff452d3c5c0adef70190fc3 + languageName: node + linkType: hard + "react-number-format@npm:^5.3.1": version: 5.4.0 resolution: "react-number-format@npm:5.4.0" @@ -53115,6 +53299,17 @@ __metadata: languageName: node linkType: hard +"socks-proxy-agent@npm:^8.0.5": + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" + dependencies: + agent-base: ^7.1.2 + debug: ^4.3.4 + socks: ^2.8.3 + checksum: b4fbcdb7ad2d6eec445926e255a1fb95c975db0020543fbac8dfa6c47aecc6b3b619b7fb9c60a3f82c9b2969912a5e7e174a056ae4d98cb5322f3524d6036e1d + languageName: node + linkType: hard + "socks@npm:^2.6.1, socks@npm:^2.7.1": version: 2.7.1 resolution: "socks@npm:2.7.1" @@ -53135,6 +53330,16 @@ __metadata: languageName: node linkType: hard +"socks@npm:^2.8.3": + version: 2.8.7 + resolution: "socks@npm:2.8.7" + dependencies: + ip-address: ^10.0.1 + smart-buffer: ^4.2.0 + checksum: 4bbe2c88cf0eeaf49f94b7f11564a99b2571bde6fd1e714ff95b38f89e1f97858c19e0ab0e6d39eb7f6a984fa67366825895383ed563fe59962a1d57a1d55318 + languageName: node + linkType: hard + "sonic-boom@npm:^3.7.0": version: 3.8.1 resolution: "sonic-boom@npm:3.8.1" @@ -55302,6 +55507,13 @@ __metadata: languageName: node linkType: hard +"text-encoding@npm:^0.7.0": + version: 0.7.0 + resolution: "text-encoding@npm:0.7.0" + checksum: b6109a843fb1b8748b32e1ecd6df74d370f46c13ac136bcb6ca15db70209bb0b8ec1f296ebb4b0dd9961150e205dcc044b89f8cf7657f6faef78c7569a2a81bc + languageName: node + linkType: hard + "text-extensions@npm:^1.0.0": version: 1.9.0 resolution: "text-extensions@npm:1.9.0" @@ -58412,6 +58624,13 @@ __metadata: languageName: node linkType: hard +"webidl-conversions@npm:^5.0.0": + version: 5.0.0 + resolution: "webidl-conversions@npm:5.0.0" + checksum: ccf1ec2ca7c0b5671e5440ace4a66806ae09c49016ab821481bec0c05b1b82695082dc0a27d1fe9d804d475a408ba0c691e6803fd21be608e710955d4589cd69 + languageName: node + linkType: hard + "webidl-conversions@npm:^6.1.0": version: 6.1.0 resolution: "webidl-conversions@npm:6.1.0" @@ -58689,6 +58908,17 @@ __metadata: languageName: node linkType: hard +"whatwg-url-without-unicode@npm:8.0.0-3": + version: 8.0.0-3 + resolution: "whatwg-url-without-unicode@npm:8.0.0-3" + dependencies: + buffer: ^5.4.3 + punycode: ^2.1.1 + webidl-conversions: ^5.0.0 + checksum: 1fe266f7161e0bd961087c1254a5a59d1138c3d402064495eed65e7590d9caed5a1d9acfd6e7a1b0bf0431253b0e637ee3e4ffc08387cd60e0b2ddb9d4687a4b + languageName: node + linkType: hard + "whatwg-url@npm:^10.0.0": version: 10.0.0 resolution: "whatwg-url@npm:10.0.0" From 0044a23075322f5b76565c14342dac8013b8fc4a Mon Sep 17 00:00:00 2001 From: Mircea Hasegan Date: Thu, 6 Nov 2025 16:06:24 +0100 Subject: [PATCH 2/2] feat: use env variable for subscribe key --- .../src/lib/scripts/background/notifications-service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/browser-extension-wallet/src/lib/scripts/background/notifications-service.ts b/apps/browser-extension-wallet/src/lib/scripts/background/notifications-service.ts index 27b07438be..e40b7b1ade 100644 --- a/apps/browser-extension-wallet/src/lib/scripts/background/notifications-service.ts +++ b/apps/browser-extension-wallet/src/lib/scripts/background/notifications-service.ts @@ -2,8 +2,8 @@ import { LaceMessage, LaceNotification, NotificationsTopic } from '@src/types/no import PubNub from 'pubnub'; import { ReplaySubject } from 'rxjs'; -const SUBSCRIBE_KEY = 'sub-c-95c77e55-b9e9-4f62-9584-6c907b0976c0'; -const USER_ID = 'lace-user-uuid-to-be-replaced'; +const SUBSCRIBE_KEY = process.env.PUBNUB_SUBSCRIBE_KEY; +const USER_ID = process.env.PUBNUB_USER_ID; export class NotificationsService { private pubnub: PubNub;