From 3f84c10b5353f2c2de5750f48d791be27a6f4ce3 Mon Sep 17 00:00:00 2001 From: Siddesh Sankhya <79219618+Siddesh7@users.noreply.github.com> Date: Mon, 29 Jan 2024 17:13:36 +0530 Subject: [PATCH 1/2] 1050 update video example implementation in sdk-frontend (#1070) * fix: use latest imports in example app * feat: use latest rainbowkit library * chore: use latest restapi package * chore: remove unnecessary libs --- .../sdk-frontend/helpers/getCAIPAddress.ts | 8 +- packages/examples/sdk-frontend/package.json | 9 +- packages/examples/sdk-frontend/pages/_app.tsx | 10 +-- .../examples/sdk-frontend/pages/video-v2.tsx | 88 +++++++++---------- .../examples/sdk-frontend/pages/video.tsx | 37 ++++---- 5 files changed, 77 insertions(+), 75 deletions(-) diff --git a/packages/examples/sdk-frontend/helpers/getCAIPAddress.ts b/packages/examples/sdk-frontend/helpers/getCAIPAddress.ts index 09fcea3dc..c4a8f0d02 100644 --- a/packages/examples/sdk-frontend/helpers/getCAIPAddress.ts +++ b/packages/examples/sdk-frontend/helpers/getCAIPAddress.ts @@ -1,12 +1,12 @@ -import { ENV } from "@pushprotocol/restapi/src/lib/constants"; -import { ethers } from "ethers"; +import { ENV } from '@pushprotocol/restapi/src/lib/constants'; +import { isAddress } from 'viem'; export interface AddressValidatorsType { [key: string]: ({ address }: { address: string }) => boolean; } export function isValidETHAddress(address: string) { - return ethers.utils.isAddress(address); + return isAddress(address); } const AddressValidators: AddressValidatorsType = { @@ -16,7 +16,7 @@ const AddressValidators: AddressValidatorsType = { }; function validateCAIP(addressInCAIP: string) { - const [blockchain, networkId, address] = addressInCAIP.split(":"); + const [blockchain, networkId, address] = addressInCAIP.split(':'); if (!blockchain) return false; if (!networkId) return false; diff --git a/packages/examples/sdk-frontend/package.json b/packages/examples/sdk-frontend/package.json index a789c5ad6..bafb1a681 100644 --- a/packages/examples/sdk-frontend/package.json +++ b/packages/examples/sdk-frontend/package.json @@ -9,17 +9,16 @@ "lint": "next lint" }, "dependencies": { - "@pushprotocol/restapi": "^1.6.2", + "@pushprotocol/restapi": "^1.6.4", "@pushprotocol/socket": "^0.5.1", - "@pushprotocol/uiweb": "^1.1.8", - "@rainbow-me/rainbowkit": "0.12.14", - "ethers": "^5", + "@rainbow-me/rainbowkit": "^1.3.3", "immer": "^10.0.2", "next": "^13.4.3", "react": "^18.2.0", "react-dom": "^18.2.0", "styled-components": "^5.3.11", - "wagmi": "0.12.13" + "viem": "1", + "wagmi": "1" }, "devDependencies": { "@types/node": "^18.16.12", diff --git a/packages/examples/sdk-frontend/pages/_app.tsx b/packages/examples/sdk-frontend/pages/_app.tsx index f56330a22..4840d44e4 100644 --- a/packages/examples/sdk-frontend/pages/_app.tsx +++ b/packages/examples/sdk-frontend/pages/_app.tsx @@ -5,7 +5,7 @@ import { RainbowKitProvider, darkTheme, } from '@rainbow-me/rainbowkit'; -import { configureChains, createClient, WagmiConfig } from 'wagmi'; +import { configureChains, createConfig, WagmiConfig } from 'wagmi'; import { sepolia } from 'wagmi/chains'; import { publicProvider } from 'wagmi/providers/public'; import { infuraProvider } from 'wagmi/providers/infura'; @@ -17,7 +17,7 @@ import { useEffect, useState } from 'react'; // import { useSpaceComponents } from './../components/Spaces/useSpaceComponent'; import { AccountContext } from '../contexts'; -const { chains, provider } = configureChains( +const { chains, publicClient } = configureChains( [sepolia], [ infuraProvider({ apiKey: '5524d420b29f4f7a8d8d2f582a0d43f7' }), @@ -31,10 +31,10 @@ const { connectors } = getDefaultWallets({ chains, }); -const wagmiClient = createClient({ +const wagmiConfig = createConfig({ autoConnect: true, connectors, - provider, + publicClient, }); export interface ISpacesComponentProps { @@ -67,7 +67,7 @@ function MyApp({ Component, pageProps }: AppProps) { <> {/* hacky fix for wagmi ssr hydration errors */} {loadWagmi ? ( - + { const { isConnected } = useAccount(); - const { data: signer } = useSigner(); + const { data: signer } = useWalletClient(); const aliceVideoCall = useRef(); - const [latestVideoEvent, setLatestVideoEvent] = useState( - null - ); + const [isPushStreamConnected, setIsPushStreamConnected] = useState(false); - const [data, setData] = useState(video.initVideoCallData); + const [data, setData] = useState( + CONSTANTS.VIDEO.INITIAL_DATA + ); + const [incomingCallerAddress, setIncomingCallerAddress] = useState< + string | null + >(null); const [recipientAddress, setRecipientAddress] = useState(); const initializePushAPI = async () => { @@ -49,27 +45,30 @@ const VideoV2: NextPage = () => { setIsPushStreamConnected(false); }); - createdStream.on(CONSTANTS.STREAM.VIDEO, async (data: VideoEvent) => { - if (data.event === CONSTANTS.VIDEO.EVENT.REQUEST) { - setLatestVideoEvent(data); - } - - if (data.event === CONSTANTS.VIDEO.EVENT.APPROVE) { - console.log('Video Call Approved'); - } - - if (data.event === CONSTANTS.VIDEO.EVENT.DENY) { - alert('User Denied the Call'); - } - - if (data.event === CONSTANTS.VIDEO.EVENT.CONNECT) { - console.log('Video Call Connected'); - } - - if (data.event === CONSTANTS.VIDEO.EVENT.DISCONNECT) { - alert('Video Call ended!'); + createdStream.on( + CONSTANTS.STREAM.VIDEO, + async (data: TYPES.VIDEO.EVENT) => { + if (data.event === CONSTANTS.VIDEO.EVENT.REQUEST) { + setIncomingCallerAddress(data.peerInfo.address); + } + + if (data.event === CONSTANTS.VIDEO.EVENT.APPROVE) { + console.log('Video Call Approved'); + } + + if (data.event === CONSTANTS.VIDEO.EVENT.DENY) { + alert('User Denied the Call'); + } + + if (data.event === CONSTANTS.VIDEO.EVENT.CONNECT) { + console.log('Video Call Connected'); + } + + if (data.event === CONSTANTS.VIDEO.EVENT.DISCONNECT) { + alert('Video Call ended!'); + } } - }); + ); aliceVideoCall.current = await userAlice.video.initialize(setData, { stream: createdStream, @@ -85,13 +84,14 @@ const VideoV2: NextPage = () => { // Here we initialize the push video API, which is the first and important step to make video calls useEffect(() => { if (!signer) return; - if (data?.incoming[0]?.status !== VideoCallStatus.UNINITIALIZED) return; // data?.incoming[0]?.status will have a status of VideoCallStatus.UNINITIALIZED when the video call is not initialized, call ended or denied. So we Initialize the Push API here. + if (data?.incoming[0]?.status !== CONSTANTS.VIDEO.STATUS.UNINITIALIZED) + return; // data?.incoming[0]?.status will have a status of VideoCallStatus.UNINITIALIZED when the video call is not initialized, call ended or denied. So we Initialize the Push API here. initializePushAPI(); }, [signer, data.incoming[0].status]); useEffect(() => { console.log('isPushStreamConnected', isPushStreamConnected); // This will be true when the push stream is connected - }, [isPushStreamConnected, latestVideoEvent]); + }, [isPushStreamConnected]); // This function is used to request a video call to a recipient const requestVideoCall = async (recipient: string) => { @@ -100,17 +100,17 @@ const VideoV2: NextPage = () => { // This function is used to accept the incoming video call const acceptIncomingCall = async () => { - await aliceVideoCall.current.approve(latestVideoEvent?.peerInfo); + await aliceVideoCall.current.approve(incomingCallerAddress); }; // This function is used to deny the incoming video call const denyIncomingCall = async () => { - await aliceVideoCall.current.deny(latestVideoEvent?.peerInfo); + await aliceVideoCall.current.deny(incomingCallerAddress); }; // This function is used to end the ongoing video call const endCall = async () => { - await aliceVideoCall.current.disconnect(data?.incoming[0]?.address); + await aliceVideoCall.current.disconnect(); }; return ( @@ -145,7 +145,7 @@ const VideoV2: NextPage = () => { - {data?.incoming[0]?.status === VideoCallStatus.CONNECTED && ( + {data?.incoming[0]?.status === CONSTANTS.VIDEO.STATUS.CONNECTED && ( )} - {data.incoming[0].status === VideoCallStatus.RECEIVED && ( + {data.incoming[0].status === CONSTANTS.VIDEO.STATUS.RECEIVED && ( diff --git a/packages/examples/sdk-frontend/pages/video.tsx b/packages/examples/sdk-frontend/pages/video.tsx index c3c79ee6c..37f4a3a38 100644 --- a/packages/examples/sdk-frontend/pages/video.tsx +++ b/packages/examples/sdk-frontend/pages/video.tsx @@ -3,13 +3,16 @@ import type { NextPage } from 'next'; import * as PushAPI from '@pushprotocol/restapi'; import { ENV } from '@pushprotocol/restapi/src/lib/constants'; import { produce } from 'immer'; -import { useAccount, useNetwork, useSigner } from 'wagmi'; +import { useAccount, useNetwork, useWalletClient } from 'wagmi'; import styled from 'styled-components'; import { usePushSocket } from '../hooks/usePushSocket'; import { useEffect, useRef, useState } from 'react'; import VideoPlayer from '../components/VideoPlayer'; -import { ADDITIONAL_META_TYPE, VIDEO_NOTIFICATION_ACCESS_TYPE } from '@pushprotocol/restapi/src/lib/payloads/constants'; +import { + ADDITIONAL_META_TYPE, + VIDEO_NOTIFICATION_ACCESS_TYPE, +} from '@pushprotocol/restapi/src/lib/payloads/constants'; interface VideoCallMetaDataType { recipientAddress: string; @@ -25,7 +28,7 @@ const env = ENV.DEV; const Home: NextPage = () => { const { address, isConnected } = useAccount(); const { chain } = useNetwork(); - const { data: signer } = useSigner(); + const { data: signer } = useWalletClient(); const { pushSocket, isPushSocketConnected, latestFeedItem } = usePushSocket({ env, }); @@ -114,10 +117,10 @@ const Home: NextPage = () => { access: { type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT, data: { - chatId: data.meta.chatId - } - } - } + chatId: data.meta.chatId, + }, + }, + }, }); }; @@ -176,10 +179,10 @@ const Home: NextPage = () => { access: { type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT, data: { - chatId: data.meta.chatId - } - } - } + chatId: data.meta.chatId, + }, + }, + }, }); } })(); @@ -236,9 +239,9 @@ const Home: NextPage = () => { access: { type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT, data: { - chatId: data.meta.chatId - } - } + chatId: data.meta.chatId, + }, + }, }, retry: true, }); @@ -254,9 +257,9 @@ const Home: NextPage = () => { access: { type: VIDEO_NOTIFICATION_ACCESS_TYPE.PUSH_CHAT, data: { - chatId: data.meta.chatId - } - } + chatId: data.meta.chatId, + }, + }, }, retry: true, }); From 0d3fd9124ce94d77efee86783f90de6aadbaea68 Mon Sep 17 00:00:00 2001 From: Monalisha Mishra <42746736+mishramonalisha76@users.noreply.github.com> Date: Tue, 30 Jan 2024 17:26:59 +0530 Subject: [PATCH 2/2] fix: fixed signer bug (#1073) --- .../sdk-frontend-react/src/app/app.tsx | 18 +++++++++++++++--- .../chat/MessageInput/MessageInput.tsx | 5 +++-- .../src/lib/dataProviders/ChatDataProvider.tsx | 7 ++++--- .../uiweb/src/lib/hooks/chat/useChatProfile.ts | 9 ++++++--- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/examples/sdk-frontend-react/src/app/app.tsx b/packages/examples/sdk-frontend-react/src/app/app.tsx index 402d723c0..2074d5514 100644 --- a/packages/examples/sdk-frontend-react/src/app/app.tsx +++ b/packages/examples/sdk-frontend-react/src/app/app.tsx @@ -2,6 +2,7 @@ import { useContext, useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; import { Route, Routes, Link } from 'react-router-dom'; import { useWeb3React } from '@web3-react/core'; +import { PushAPI } from "@pushprotocol/restapi"; import ConnectButtonComp from './components/Connect'; import { Checkbox } from './components/Checkbox'; import Dropdown from './components/Dropdown'; @@ -69,7 +70,7 @@ import { SpaceInvitesComponent, } from './SpaceUITest'; import { useSpaceComponents } from './SpaceUITest/useSpaceComponents'; -import * as PushAPI from '@pushprotocol/restapi'; +import * as PushApi from '@pushprotocol/restapi'; import { ChatWidgetTest } from './ChatWidgetTest'; import { CHAT_THEME_OPTIONS, @@ -94,6 +95,7 @@ import GetGroupInfoTest from './ChatTest/GetGroupInfoTest'; import GetGroupMembersTest from './ChatTest/GetGroupMembersTest'; import VideoV2 from './Video'; + window.Buffer = window.Buffer || Buffer; interface Web3ReactState { @@ -230,6 +232,7 @@ export function App() { const { SpaceWidgetComponent } = useSpaceComponents(); const [spaceId, setSpaceId] = useState(''); const [pgpPrivateKey, setPgpPrivateKey] = useState(''); + const [pushUser, setPushUser] = useState(); const socketData = useSDKSocket({ account: account, @@ -250,12 +253,18 @@ export function App() { (async () => { if (!account || !env || !library) return; - const user = await PushAPI.user.get({ account: account, env }); + const user = await PushApi.user.get({ account: account, env }); let pgpPrivateKey; const librarySigner = await library.getSigner(account); + const pushUser = await PushAPI.initialize(librarySigner!, { + env: env, + account: account, + alpha: { feature: ['SCALABILITY_V2'] }, + }) + setPushUser(pushUser); setSigner(librarySigner); if (user?.encryptedPrivateKey) { - pgpPrivateKey = await PushAPI.chat.decryptPGPKey({ + pgpPrivateKey = await PushApi.chat.decryptPGPKey({ encryptedPGPPrivateKey: user.encryptedPrivateKey, account: account, signer: librarySigner, @@ -320,6 +329,9 @@ export function App() { diff --git a/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx b/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx index d41775d41..aded4a698 100644 --- a/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx +++ b/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx @@ -53,7 +53,8 @@ interface IThemeProps { } const ConnectButtonSection = ({ autoConnect }: { autoConnect: boolean }) => { - const { signer } = useChatData(); + const { pgpPrivateKey,account } = useChatData(); + return (
{ alignItems="center" padding="8px" > - {!signer && ( + {!(pgpPrivateKey && account) && ( { (async () => { - if (accountVal && envVal ) { + if (accountVal && envVal && !pushUserVal ) { const pushUser = await initializePushUser({ signer: signerVal, account: accountVal!, @@ -115,7 +116,7 @@ export const ChatUIProvider = ({ (async () => { let user; if (account) { - user = await fetchChatProfile({ profileId: account, env }); + user = await fetchChatProfile({ profileId: account, env ,pushUser}); if (user) setConnectedProfile(user); } })(); diff --git a/packages/uiweb/src/lib/hooks/chat/useChatProfile.ts b/packages/uiweb/src/lib/hooks/chat/useChatProfile.ts index 4bf6832d1..175a728eb 100644 --- a/packages/uiweb/src/lib/hooks/chat/useChatProfile.ts +++ b/packages/uiweb/src/lib/hooks/chat/useChatProfile.ts @@ -1,24 +1,27 @@ -import * as PushAPI from '@pushprotocol/restapi'; import { useCallback, useContext } from 'react'; import { useChatData } from './useChatData'; import { Env } from '@pushprotocol/restapi'; +import { PushAPI } from "@pushprotocol/restapi"; export interface FetchProfileParams { profileId?: string; env?: Env; + pushUser?: PushAPI; } const useChatProfile = () => { - const { pushUser } = useChatData(); + const { pushUser:contextPushUser } = useChatData(); const fetchChatProfile = useCallback( async ({ profileId, + pushUser = contextPushUser, //note: remove env when chat and notification component is shifted to class based env }: FetchProfileParams): Promise => { try { let userReadOnly; - if(profileId) + + if(profileId && pushUser) userReadOnly = await pushUser!.info({ overrideAccount: profileId }); else userReadOnly = await pushUser!.info();