Skip to content

Commit

Permalink
Merge pull request #141 from indexnetwork/dev
Browse files Browse the repository at this point in the history
Iterate
  • Loading branch information
serefyarar authored Sep 8, 2024
2 parents a1dc732 + 5f85624 commit 7b7cd99
Show file tree
Hide file tree
Showing 15 changed files with 302 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/web-app-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
DOCKER_TAG: indexnetwork/web3-web-app:${{ steps.build-time.outputs.time }}
DOCKER_REGISTRY: 236785930124.dkr.ecr.us-east-1.amazonaws.com
run: |
docker build --build-arg INFURA_API_KEY=${{ secrets.INFURA_API_KEY }} --build-arg API_URL=${API_URL} -t $DOCKER_TAG .
docker build --build-arg INFURA_API_KEY=${{ secrets.INFURA_API_KEY }} --build-arg API_URL=${API_URL} --build-arg MAGICBELL_API_KEY=${{ secrets.MAGICBELL_API_KEY }} -t $DOCKER_TAG .
docker tag $DOCKER_TAG $DOCKER_REGISTRY/$DOCKER_TAG
docker push $DOCKER_REGISTRY/$DOCKER_TAG
docker tag $DOCKER_TAG $DOCKER_REGISTRY/indexnetwork/web3-web-app:latest-${GITHUB_REF#refs/heads/}
Expand Down
1 change: 1 addition & 0 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"codeco": "^1.2.1",
"cookie-parser": "~1.4.6",
"cross-eventsource": "^1.0.0",
"crypto": "^1.0.1",
"debug": "~2.6.9",
"did-session": "^2.1.2",
"dotenv": "^16.0.3",
Expand Down
31 changes: 31 additions & 0 deletions api/src/agents/basic_subscriber.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import axios from "axios";
import { getAgentDID } from "../utils/helpers.js";
import { ConversationService } from "../services/conversation.js";
import { DIDService } from "../services/did.js";

export const handleNewItemEvent = async (
chatId,
Expand Down Expand Up @@ -53,6 +54,7 @@ export const handleNewItemEvent = async (
role: "assistant",
name: "listener",
});

await redisClient.publish(
`agentStream:${chatId}:update`,
JSON.stringify({
Expand All @@ -61,6 +63,35 @@ export const handleNewItemEvent = async (
messageId: assistantMessage.id,
}),
);

const didService = new DIDService(definition);

const conversation = await conversationService.getConversation(chatId);
const recipients = await Promise.all(
conversation.members
.filter((memberId) => memberId.id !== agentDID.id)
.map(async (memberId) => {
const externalId = await didService.getControllerDIDByEncryptionDID(memberId.id);
console.log('External ID:', externalId);
return {
external_id: externalId
};
})
);
await axios.post('https://api.magicbell.com/broadcasts', {
broadcast: {
title: conversation.summary,
content: resp.data,
recipients
}
}, {
headers: {
'X-MAGICBELL-API-KEY': process.env.MAGICBELL_API_KEY,
'X-MAGICBELL-API-SECRET': process.env.MAGICBELL_API_SECRET,
'Content-Type': 'application/json'
}
})

await redisClient.hSet(
`subscriptions`,
chatId,
Expand Down
19 changes: 19 additions & 0 deletions api/src/controllers/did.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { DIDService } from "../services/did.js";
import crypto from 'crypto';
import axios from "axios";


export const getIndexes = async (req, res) => {
// sendLit(req.params.id) // TODO Fix later.
const definition = req.app.get("runtimeDefinition");
Expand Down Expand Up @@ -85,6 +89,21 @@ export const getProfileFromSession = async (req, res, next) => {
id: req.params.did,
};
}

profile.hmac = crypto.createHmac('sha256', process.env.MAGICBELL_API_SECRET)
.update(req.session.did.parent)
.digest('base64');

await axios.post('https://api.magicbell.com/users', {
user: {
external_id: req.session.did.parent
}
}, {
headers: {
'X-MAGICBELL-API-KEY': process.env.MAGICBELL_API_KEY,
'X-MAGICBELL-API-SECRET': process.env.MAGICBELL_API_SECRET
}
});

res.status(200).json(profile);
} catch (error) {
Expand Down
44 changes: 44 additions & 0 deletions api/src/services/did.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,50 @@ export class DIDService {
throw error;
}
}

async getControllerDIDByEncryptionDID(userEncryptionDID) {
try {
const query = `
query {
publicEncryptionDIDIndex(first: 10, filters: {
where: {
publicEncryptionDID: {
equalTo: "${userEncryptionDID}"
}
}
}) {
edges {
node {
id
controllerDID {
id
}
publicEncryptionDID {
id
}
}
}
}
}
`;

const { data, errors } = await this.client.executeQuery(query);

if (errors) {
throw new Error(`Error getting controller DID: ${JSON.stringify(errors)}`);
}

if (!data || !data.publicEncryptionDIDIndex || data.publicEncryptionDIDIndex.edges.length === 0) {
throw new Error("Controller DID not found");
}

return data.publicEncryptionDIDIndex.edges[0].node.controllerDID.id;
} catch (error) {
console.error("Exception occurred in getControllerDIDByEncryptionDID:", error);
throw error;
}
}

async publicEncryptionDID() {
if (!this.did) {
throw new Error("DID not set. Use setDID() to set the did.");
Expand Down
5 changes: 5 additions & 0 deletions api/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5166,6 +5166,11 @@ crossws@^0.2.0, crossws@^0.2.2:
resolved "https://registry.yarnpkg.com/crossws/-/crossws-0.2.4.tgz#82a8b518bff1018ab1d21ced9e35ffbe1681ad03"
integrity sha512-DAxroI2uSOgUKLz00NX6A8U/8EE3SZHmIND+10jkVSaypvyt57J5JEOxAQOL6lQxyzi/wZbTIwssU1uy69h5Vg==

crypto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/crypto/-/crypto-1.0.1.tgz#2af1b7cad8175d24c8a1b0778255794a21803037"
integrity sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==

css-parse@1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.0.4.tgz#38b0503fbf9da9f54e9c1dbda60e145c77117bdd"
Expand Down
4 changes: 4 additions & 0 deletions web-app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ ENV NEXT_PUBLIC_API_URL=$API_URL

ARG INFURA_API_KEY
ENV INFURA_API_KEY=$INFURA_API_KEY

ARG MAGICBELL_API_KEY
ENV MAGICBELL_API_KEY=$MAGICBELL_API_KEY

COPY . .
RUN yarn
RUN yarn build
Expand Down
3 changes: 3 additions & 0 deletions web-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"@lit-protocol/contracts-sdk": "4.1.1",
"@lit-protocol/lit-node-client": "4.1.1",
"@lit-protocol/uint8arrays": "4.1.1",
"@magicbell/user-client": "^0.2.0",
"@magicbell/webpush": "^2.0.2",
"@metamask/sdk-react": "^0.28.0",
"@nanostores/react": "ai/react",
"@radix-ui/react-alert-dialog": "^1.0.4",
Expand Down Expand Up @@ -60,6 +62,7 @@
"lodash.debounce": "^4.0.8",
"lottie-react": "^2.3.1",
"lottie-react-web": "^2.2.2",
"magicbell": "^3.3.0",
"moment": "^2.29.3",
"multiformats": "^12.1.1",
"nanoid": "^5.0.7",
Expand Down
41 changes: 21 additions & 20 deletions web-app/public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
{
"name": "Index Network",
"short_name": "Index",
"start_url": "/",
"display": "standalone",
"background_color": "#black",
"theme_color": "#90cdf4",
"orientation": "portrait-primary",
"icons": [
{
"src": "favicon-white.png",
"sizes": "500x500",
"type": "image/png"
},
{
"src": "favicon-white.png",
"sizes": "192x192",
"type": "image/png"
}
]
}
"name":"Index Network",
"short_name":"Index",
"start_url":"/notifications",
"display":"standalone",
"background_color":"black",
"theme_color":"black",
"orientation":"portrait-primary",
"icons":[
{
"src":"favicon-white.png",
"sizes":"500x500",
"type":"image/png"
},
{
"src":"favicon-white.png",
"sizes":"192x192",
"type":"image/png"
}
],
"permissions": ["notifications"]
}
2 changes: 2 additions & 0 deletions web-app/public/sw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

importScripts('https://assets.magicbell.io/web-push-notifications/sw.js');
1 change: 1 addition & 0 deletions web-app/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
metadataBase: new URL("https://index.network"),
title: "Index Network | Discovery Protocol",
manifest: "/manifest.json",
description:
"Index allows you to create truly personalised and autonomous discovery experiences across the web",
referrer: "origin-when-cross-origin",
Expand Down
96 changes: 96 additions & 0 deletions web-app/src/app/notifications/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
"use client";

import type { NextPage } from "next";
import { useState, useEffect } from "react";
import { WebPushClient } from "@magicbell/webpush";
import Head from "next/head";
import { useApi } from "@/context/APIContext";
import { useAuth } from "@/context/AuthContext";

const Notifications: NextPage = () => {
const [client, setClient] = useState<WebPushClient | null>(null);
const [isSubscribed, setIsSubscribed] = useState(false);
const { api: apiService, ready: apiReady } = useApi();
const { session, userDID } = useAuth();
useEffect(() => {
if (!apiReady) return;
if (!session) return;

const initializeWebPushClient = async () => {
if ("serviceWorker" in navigator) {
try {
// Service Worker'ı kaydet
const registration = await navigator.serviceWorker.register("/sw.js");
console.log("Service Worker registered successfully:", registration);

// Service Worker'ın aktif olmasını bekle
await navigator.serviceWorker.ready;
console.log("Service Worker is now ready");

const profile = await apiService?.getCurrentProfile();
if (!profile) {
return;
}

console.log(profile);

const webPushClient = new WebPushClient({
apiKey: process.env.MAGICBELL_API_KEY || "",
userExternalId: profile?.id,
userHmac: profile.hmac!,
serviceWorkerPath: "/sw.js",
});

setClient(webPushClient);

const subscribed = await webPushClient.isSubscribed();
setIsSubscribed(subscribed);
} catch (error) {
console.error("Error initializing WebPush:", error);
}
} else {
console.error("Service Workers are not supported in this browser");
}
};

initializeWebPushClient();
}, [session, apiReady]);

const handleSubscribe = async () => {
if (client) {
try {
await client.subscribe();
setIsSubscribed(true);
} catch (error) {
console.error("Subscription failed:", error);
}
}
};

const handleUnsubscribe = async () => {
if (client) {
try {
await client.unsubscribe();
setIsSubscribed(false);
} catch (error) {
console.error("Unsubscription failed:", error);
}
}
};

return (
<div>
<h1>Web Push Notifications</h1>
{isSubscribed ? (
<button onClick={handleUnsubscribe}>Bildirimleri Kapat</button>
) : (
<button onClick={handleSubscribe}>Bilaadirimleri Aç</button>
)}
<Head>
<link rel="manifest" href="/manifest.json"/>
</Head>
</div>
);
};

export default Notifications;
7 changes: 7 additions & 0 deletions web-app/src/services/api-service-new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const API_ENDPOINTS = {
STAR_INDEX: "/dids/:did/indexes/:indexId/star",
OWN_INDEX: "/dids/:did/indexes/:indexId/own",
GET_PROFILE: "/dids/:did/profile",
GET_CURRENT_PROFILE: "/profile",
UPDATE_PROFILE: "/profile",
UPLOAD_AVATAR: "/profile/upload_avatar",
GET_ITEMS: "/indexes/:indexId/items",
Expand Down Expand Up @@ -101,6 +102,12 @@ class ApiService {
return data;
}

async getCurrentProfile(): Promise<Users> {
const url = API_ENDPOINTS.GET_CURRENT_PROFILE;
const { data } = await this.apiAxios.get<Users>(url);
return data;
}

async updateProfile(params: Partial<Users>): Promise<Users> {
const url = API_ENDPOINTS.UPDATE_PROFILE;
const { data } = await this.apiAxios.patch<Users>(url, params);
Expand Down
1 change: 1 addition & 0 deletions web-app/src/types/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ export interface Users {
name?: string;
bio?: string;
avatar?: string;
hmac?: string;
createdAt?: string;
updatedAt?: string;
}
Expand Down
Loading

0 comments on commit 7b7cd99

Please sign in to comment.