diff --git a/packages/examples/sdk-frontend-react/src/app/ChatTest/CreateGroupTest.tsx b/packages/examples/sdk-frontend-react/src/app/ChatTest/CreateGroupTest.tsx index b55bc7b44..c37604b2e 100644 --- a/packages/examples/sdk-frontend-react/src/app/ChatTest/CreateGroupTest.tsx +++ b/packages/examples/sdk-frontend-react/src/app/ChatTest/CreateGroupTest.tsx @@ -112,8 +112,8 @@ const CreateGroupTest = () => { { 'all': [ { - 'type': 'PUSH', - 'category': 'owner', + 'type': PushAPI.ConditionType.PUSH, + 'category': 'ERC20', 'subcategory': 'holder', 'data': { 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', diff --git a/packages/examples/sdk-frontend-react/src/app/ChatUITest/ChatViewComponent.tsx b/packages/examples/sdk-frontend-react/src/app/ChatUITest/ChatViewComponent.tsx index 437dc61ec..0f7dae1ef 100644 --- a/packages/examples/sdk-frontend-react/src/app/ChatUITest/ChatViewComponent.tsx +++ b/packages/examples/sdk-frontend-react/src/app/ChatUITest/ChatViewComponent.tsx @@ -17,7 +17,7 @@ const ChatViewComponentTest = () => { {/* */} - console.log("BOIIII RETURNNNSSSSS")} chatId='196f58cbe07c7eb5716d939e0a3be1f15b22b2334d5179c601566600016860ac' limit={10}/> + console.log("BOIIII RETURNNNSSSSS")} chatId='c4828a375fd261577927a9d73fe3fa30204c6667a3adbc345e010eccf5ec740e' limit={10}/> ); diff --git a/packages/examples/sdk-frontend-react/src/app/SpaceTest/CreateSpaceTest.tsx b/packages/examples/sdk-frontend-react/src/app/SpaceTest/CreateSpaceTest.tsx index 889a97b65..925f516bb 100644 --- a/packages/examples/sdk-frontend-react/src/app/SpaceTest/CreateSpaceTest.tsx +++ b/packages/examples/sdk-frontend-react/src/app/SpaceTest/CreateSpaceTest.tsx @@ -107,7 +107,7 @@ const CreateSpaceTest = () => { numberOfERC20 != null ? Number(numberOfERC20) : undefined, signer: librarySigner, env, - meta: meta, + // meta: meta, scheduleAt: new Date(scheduleAt), scheduleEnd: scheduleEnd ? new Date(scheduleEnd) : null, }); diff --git a/packages/examples/sdk-frontend-react/src/app/SpaceTest/GetSpaceAccessTest.tsx b/packages/examples/sdk-frontend-react/src/app/SpaceTest/GetSpaceAccessTest.tsx new file mode 100644 index 000000000..b9c6a1bb9 --- /dev/null +++ b/packages/examples/sdk-frontend-react/src/app/SpaceTest/GetSpaceAccessTest.tsx @@ -0,0 +1,86 @@ +import { useState, useContext } from 'react'; +import { + Section, + SectionItem, + CodeFormatter, + SectionButton, +} from '../components/StyledComponents'; +import Loader from '../components/Loader'; +import { EnvContext } from '../context'; +import * as PushAPI from '@pushprotocol/restapi'; + +const GetSpaceAccessTest = () => { + const { env } = useContext(EnvContext); + const [isLoading, setLoading] = useState(false); + const [spaceId, setSpaceId] = useState(''); + const [did, setDid] = useState(''); + const [sendResponse, setSendResponse] = useState(''); + + const updateSpaceId = (e: React.SyntheticEvent) => { + setSpaceId((e.target as HTMLInputElement).value); + }; + + const updateDid = (e: React.SyntheticEvent) => { + setDid((e.target as HTMLInputElement).value); + }; + + const testGetSpaceAccess = async () => { + try { + setLoading(true); + + const response = await PushAPI.space.getAccess({ + spaceId: spaceId, + did: did, + env, + }); + setSendResponse(response); + } catch (e) { + console.error(e); + } finally { + setLoading(false); + } + }; + + return ( +
+

Get Space Access Test Page

+ + + +
+ + get space access + + + + + + + + + + +
+ {sendResponse ? ( + + {JSON.stringify(sendResponse, null, 4)} + + ) : null} +
+
+
+
+ ); +}; + +export default GetSpaceAccessTest; diff --git a/packages/examples/sdk-frontend-react/src/app/SpaceTest/SpaceTest.tsx b/packages/examples/sdk-frontend-react/src/app/SpaceTest/SpaceTest.tsx index 78405b5fc..817f970fa 100644 --- a/packages/examples/sdk-frontend-react/src/app/SpaceTest/SpaceTest.tsx +++ b/packages/examples/sdk-frontend-react/src/app/SpaceTest/SpaceTest.tsx @@ -68,6 +68,9 @@ const SpaceTest = () => { SPACE.GETSPACESTRENDING + + SPACE.GETSPACEACCESS + diff --git a/packages/examples/sdk-frontend-react/src/app/app.tsx b/packages/examples/sdk-frontend-react/src/app/app.tsx index 8eda9d079..b03d59c33 100644 --- a/packages/examples/sdk-frontend-react/src/app/app.tsx +++ b/packages/examples/sdk-frontend-react/src/app/app.tsx @@ -58,6 +58,8 @@ import RemoveSpeakersFromSpaceTest from './SpaceTest/RemoveSpeakersFromSpaceTest import GetSpacesTest from './SpaceTest/GetSpacesTest'; import GetSpacesRequestsTest from './SpaceTest/GetSpacesRequestsTest'; import GetSpacesTrendingTest from './SpaceTest/GetSpacesTrendingTest'; +import GetSpaceAccessTest from './SpaceTest/GetSpaceAccessTest'; + import SpaceUITest from './SpaceUITest/SpaceUITest'; import { SpaceWidget, @@ -507,7 +509,10 @@ export function App() { path="/getSpacesTrending" element={} /> - + } + /> {/* spaces ui components routes */} } /> diff --git a/packages/restapi/README.md b/packages/restapi/README.md index 46d511e72..88f61c8c7 100644 --- a/packages/restapi/README.md +++ b/packages/restapi/README.md @@ -87,6 +87,7 @@ This package gives access to Push Protocol (Push Nodes) APIs. Visit [Developer D - [For Spaces](#for-spaces) - [To create a space](#to-create-a-space) - [To create a token gated space](#to-create-a-token-gated-space) + - [To check user access of a token gated space](#to-check-user-access-of-a-token-gated-space) - [To update space details](#to-update-space-details) - [To update token gated space details](#to-update-token-gated-space-details) - [To get space details by spaceId](#to-get-space-details-by-spaceid) @@ -1654,6 +1655,7 @@ const user = await PushAPI.user.create({ }; }; progressHook?: (progress: ProgressHookType) => void; + origin? : string | null; }) ``` @@ -1665,6 +1667,8 @@ const user = await PushAPI.user.create({ | version | 'x25519-xsalsa20-poly1305' or 'eip191-aes256-gcm-hkdf-sha256' | | additionalMeta | Additional meta data for user | | progressHook | Progress hook | +| origin | Origin through which user is created | + Example creating normal user for chat: @@ -3378,37 +3382,40 @@ Allowed Options (params with _ are mandatory) ```typescript export enum ConditionType { PUSH = 'PUSH', - GUILD = 'GUILD', + GUILD = 'GUILD' } export type Data = { - address?: string; - amount?: number; - decimals?: number; - guildId?: string; - roleId?: string; -}; + contract?: string + amount?: number + decimals?: number + guildId?: string + guildRoleId?: string + guildRoleAction?: 'all' | 'any' + url?: string + comparison?: '>' | '<' | '>=' | '<=' | '==' | '!=' +} export type ConditionBase = { - type: ConditionType; - category?: string; - subcategory?: string; - data: Data; - access?: boolean; -}; + type?: ConditionType + category?: string + subcategory?: string + data?: Data + access?: Boolean +} export type Condition = ConditionBase & { - any?: ConditionBase[]; - all?: ConditionBase[]; -}; + any?: ConditionBase[] + all?: ConditionBase[] +} export interface Rules { groupAccess?: { - conditions: Array; - }; + conditions: Array + } chatAccess?: { - conditions: Array; - }; + conditions: Array + } } ``` @@ -3428,13 +3435,38 @@ There are two main types of conditions: `PUSH` and `GUILD`. PUSH conditions may relate to: -- **ERC721**: Needs an address and an amount, and can only have the `nft_owner` subcategory. -- **ERC20**: Needs an address, an amount, and a decimals value. It can only have the `token_holder` subcategory. +- **ERC721**: Needs an address and an amount, and can only have the `owner` subcategory. +- **ERC20**: Needs an address, an amount, and a decimals value. It can only have the `holder` subcategory. +- **CustomEndpoint**: The `CustomEndpoint` provides a flexible way to validate a condition based on the response from a custom API endpoint. This is particularly useful when you want to incorporate data or validation logic that is external to your main application. As of now the Get API is supported and should return the 200 OK if the user is allowed to access. +
+  {
+    "type": "PUSH",
+    "category": "CustomEndpoint",
+    "subcategory": "GET",
+    "data": {
+      "url": "https://api.example.com/user/{{user_address}}/validate"
+    }
+  }
+
+Explanation: + +- ***type***: Represents the type of the condition, in this case "PUSH". +- ***category***: Specifies that this is a condition based on a custom endpoint. +- ***subcategory***: Represents the HTTP method for the request, in this case, a "GET" request. +- ***data***: Contains the properties for the condition. +- ***url***: The endpoint URL with a placeholder ({{user_address}}) which will be replaced with the actual user address when the condition is being evaluated. #### GUILD Conditions -GUILD conditions require both guild ID and role ID. +GUILD conditions require both guildID and guildRoleId or guildRoleAction. +- **Working**: +Guild ID Validation: The function first checks for the presence of the guildId. +API Call: On confirming its presence, the function then fetches guild data from a specific API endpoint to ascertain the guild's validity. +Role and Action Checks: After validating the guild: +The function checks for the presence of guildRoleId or guildRoleAction. At least one must be specified. +If guildRoleId is given, its legitimacy is cross-verified with the guild's roles. +For guildRoleAction, the function ensures its value is strictly "all" or "any".
Expected response (create group) @@ -3553,9 +3585,9 @@ GUILD conditions require both guild ID and role ID. { 'type': 'PUSH', 'category': 'ERC20', - 'subcategory': 'token_holder', + 'subcategory': 'holder', 'data': { - 'address': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', 'amount': 1000, 'decimals': 18 } @@ -3564,9 +3596,17 @@ GUILD conditions require both guild ID and role ID. 'type': 'GUILD', 'data': { 'guildId': '13468', - 'roleId': '19924' + 'guildRoleId': '19924' } - } + }, + { + "type": "PUSH", + "category": 'CustomEndpoint', + "subcategory": "GET" + "data": { + "url": "https://api.example.com/users/{{user_address}}/checkAccess", + } + } ] } ] @@ -3578,9 +3618,9 @@ GUILD conditions require both guild ID and role ID. { 'type': 'PUSH', 'category': 'ERC20', - 'subcategory': 'token_holder', + 'subcategory': 'holder', 'data': { - 'address': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', 'amount': 1000, 'decimals': 18 } @@ -3589,7 +3629,14 @@ GUILD conditions require both guild ID and role ID. 'type': 'GUILD', 'data': { 'guildId': '13468', - 'roleId': '19924' + 'guildRoleId': '19924' + } + }, + { + 'type': 'GUILD', + 'data': { + 'guildId': '13468', + 'guildRoleAction': 'all/any' } } ] @@ -3642,9 +3689,9 @@ Allowed Options (params with _ are mandatory) { 'type': 'PUSH', 'category': 'ERC20', - 'subcategory': 'token_holder', + 'subcategory': 'holder', 'data': { - 'address': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', 'amount': 1000, 'decimals': 18 }, @@ -3654,16 +3701,16 @@ Allowed Options (params with _ are mandatory) 'type': 'GUILD', 'data': { 'guildId': '13468', - 'roleId': '19924' + 'guildRoleId': '19924' }, 'access': true }, { 'type': 'PUSH', 'category': 'ERC721', - 'subcategory': 'nft_owner', + 'subcategory': 'owner', 'data': { - 'address': 'eip155:5:0x42af3147f17239341477113484752D5D3dda997B', + 'contract': 'eip155:5:0x42af3147f17239341477113484752D5D3dda997B', 'amount': 1 }, 'access': true @@ -3679,9 +3726,9 @@ Allowed Options (params with _ are mandatory) { 'type': 'PUSH', 'category': 'ERC20', - 'subcategory': 'token_holder', + 'subcategory': 'holder', 'data': { - 'address': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', 'amount': 1000, 'decimals': 18 }, @@ -3691,7 +3738,7 @@ Allowed Options (params with _ are mandatory) 'type': 'GUILD', 'data': { 'guildId': '13468', - 'roleId': '19924' + 'guildRoleId': '19924' }, 'access': true } @@ -3761,9 +3808,9 @@ const response = await PushAPI.chat.updateGroup({ { 'type': 'PUSH', 'category': 'ERC20', - 'subcategory': 'token_holder', + 'subcategory': 'holder', 'data': { - 'address': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', 'amount': 1000, 'decimals': 18 } @@ -3772,7 +3819,7 @@ const response = await PushAPI.chat.updateGroup({ 'type': 'GUILD', 'data': { 'guildId': '13468', - 'roleId': '19924' + 'guidlRoleId': '19924' } } ] @@ -3786,9 +3833,9 @@ const response = await PushAPI.chat.updateGroup({ { 'type': 'PUSH', 'category': 'ERC20', - 'subcategory': 'token_holder', + 'subcategory': 'holder', 'data': { - 'address': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', 'amount': 1000, 'decimals': 18 } @@ -3797,7 +3844,7 @@ const response = await PushAPI.chat.updateGroup({ 'type': 'GUILD', 'data': { 'guildId': '13468', - 'roleId': '19924' + 'guildRoleId': '19924' } } ] @@ -3961,9 +4008,9 @@ Allowed Options (params with _ are mandatory) { 'type': 'PUSH', 'category': 'ERC20', - 'subcategory': 'token_holder', + 'subcategory': 'holder', 'data': { - 'address': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', 'amount': 1000, 'decimals': 18 } @@ -3972,7 +4019,7 @@ Allowed Options (params with _ are mandatory) 'type': 'GUILD', 'data': { 'guildId': '13468', - 'roleId': '19924' + 'guildRoleId': '19924' } } ] @@ -3986,9 +4033,9 @@ Allowed Options (params with _ are mandatory) { 'type': 'PUSH', 'category': 'ERC20', - 'subcategory': 'token_holder', + 'subcategory': 'holder', 'data': { - 'address': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', 'amount': 1000, 'decimals': 18 } @@ -3997,7 +4044,7 @@ Allowed Options (params with _ are mandatory) 'type': 'GUILD', 'data': { 'guildId': '13468', - 'roleId': '19924' + 'guildRoleId': '19924' } } ] @@ -4660,9 +4707,9 @@ const response = await PushAPI.space.create({ { 'type': 'PUSH', 'category': 'ERC20', - 'subcategory': 'token_holder', + 'subcategory': 'holder', 'data': { - 'address': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', 'amount': 1000, 'decimals': 18 } @@ -4671,7 +4718,7 @@ const response = await PushAPI.space.create({ 'type': 'GUILD', 'data': { 'guildId': '13468', - 'roleId': '19924' + 'guildRoleId': '19924' } } ] @@ -4713,34 +4760,40 @@ Allowed Options (params with _ are mandatory) ```typescript export enum ConditionType { PUSH = 'PUSH', - GUILD = 'GUILD', + GUILD = 'GUILD' } export type Data = { - address?: string; - amount?: number; - decimals?: number; - guildId?: string; - roleId?: string; -}; + contract?: string + amount?: number + decimals?: number + guildId?: string + guildRoleId?: string + guildRoleAction?: 'all' | 'any' + url?: string + comparison?: '>' | '<' | '>=' | '<=' | '==' | '!=' +} export type ConditionBase = { - type: ConditionType; - category?: string; - subcategory?: string; - data: Data; - access?: boolean; -}; + type?: ConditionType + category?: string + subcategory?: string + data?: Data + access?: Boolean +} export type Condition = ConditionBase & { - any?: ConditionBase[]; - all?: ConditionBase[]; -}; + any?: ConditionBase[] + all?: ConditionBase[] +} export interface Rules { - spaceAccess?: { - conditions: Array; - }; + groupAccess?: { + conditions: Array + } + chatAccess?: { + conditions: Array + } } ``` @@ -4831,9 +4884,9 @@ export interface Rules { { 'type': 'PUSH', 'category': 'ERC20', - 'subcategory': 'token_holder', + 'subcategory': 'holder', 'data': { - 'address': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', 'amount': 1000, 'decimals': 18 } @@ -4842,7 +4895,7 @@ export interface Rules { 'type': 'GUILD', 'data': { 'guildId': '13468', - 'roleId': '19924' + 'guildRoleId': '19924' } } ] @@ -4859,6 +4912,78 @@ export interface Rules { --- +### **To check user access of a token gated group** + +```typescript + +// actual api +const response = await PushAPI.space.getAccess({ + spaceId:'8f7be0068a677df166c2e5b8a9030fe8a4341807150339e588853c0049df3106', + did: '0x9e60c47edF21fa5e5Af33347680B3971F2FfD464' + env: 'staging', +}); +``` + +Allowed Options (params with _ are mandatory) +| Param | Type | Default | Remarks | +|----------|---------|---------|--------------------------------------------| +| spaceId | string | - | space address | +| did | string | - | user address | +| env | string | 'prod' | API env - 'prod', 'staging', 'dev'| + + +
+ Expected response (space access) + +```typescript +// PushAPI_chat_getSpaceAccess | Response - 200 OK +{ + 'spaceAccess': true, + 'rules': { + 'spaceAccess': { + 'conditions': [ + { + 'any': [ + { + 'type': 'PUSH', + 'category': 'ERC20', + 'subcategory': 'holder', + 'data': { + 'contract': 'eip155:5:0x2b9bE9259a4F5Ba6344c1b1c07911539642a2D33', + 'amount': 1000, + 'decimals': 18 + }, + 'access': false + }, + { + 'type': 'GUILD', + 'data': { + 'guildId': '13468', + 'guildRoleId': '19924' + }, + 'access': true + }, + { + 'type': 'PUSH', + 'category': 'ERC721', + 'subcategory': 'owner', + 'data': { + 'contract': 'eip155:5:0x42af3147f17239341477113484752D5D3dda997B', + 'amount': 1 + }, + 'access': true + } + ] + } + ] + } +} + +``` +
+ +--- + ### **To update space details** Note - updateSpace is an idompotent call diff --git a/packages/restapi/package.json b/packages/restapi/package.json index 53cc50304..fc72b0867 100644 --- a/packages/restapi/package.json +++ b/packages/restapi/package.json @@ -10,7 +10,6 @@ }, "dependencies": { "@ambire/signature-validator": "^1.3.1", - "@livepeer/webrtmp-sdk": "^0.2.3", "@metamask/eth-sig-util": "^5.0.2", "buffer": "^6.0.3", "crypto-js": "^4.1.1", diff --git a/packages/restapi/src/lib/chat/getGroupAccess.ts b/packages/restapi/src/lib/chat/getGroupAccess.ts index 83603a17f..fa82629eb 100644 --- a/packages/restapi/src/lib/chat/getGroupAccess.ts +++ b/packages/restapi/src/lib/chat/getGroupAccess.ts @@ -1,6 +1,7 @@ import axios from 'axios'; import { getAPIBaseUrls } from '../helpers'; import Constants, { ENV } from '../constants'; +import { GroupAccess } from '../types'; /** * GET /v1/chat/groups/:chatId/access/:did @@ -14,7 +15,7 @@ export interface GetGroupAccessType { export const getGroupAccess = async ( options: GetGroupAccessType -): Promise => { +): Promise => { // Replace "any" with the actual response type const { chatId, did, env = Constants.ENV.PROD } = options || {}; try { diff --git a/packages/restapi/src/lib/chat/helpers/payloadHelper.ts b/packages/restapi/src/lib/chat/helpers/payloadHelper.ts index 005249dfe..3acf55182 100644 --- a/packages/restapi/src/lib/chat/helpers/payloadHelper.ts +++ b/packages/restapi/src/lib/chat/helpers/payloadHelper.ts @@ -1,5 +1,5 @@ import { isValidETHAddress, walletToPCAIP10 } from '../../helpers'; -import { IConnectedUser, GroupDTO, SpaceDTO, ChatStatus, Rules, SpaceRules } from '../../types'; +import { IConnectedUser, GroupDTO, SpaceDTO, ChatStatus, Rules, SpaceRules, GroupAccess, SpaceAccess } from '../../types'; import { getEncryptedRequest } from './crypto'; import { ENV, MessageType } from '../../constants'; import * as AES from './aes'; @@ -239,10 +239,32 @@ export const groupDtoToSpaceDto = (groupDto: GroupDTO): SpaceDTO => { export const convertSpaceRulesToRules = (spaceRules: SpaceRules): Rules => { return { groupAccess: spaceRules.spaceAccess, - chattingAccess: undefined, + chatAccess: undefined, }; } +export const convertRulesToSpaceRules = (rules: Rules): SpaceRules => { + return { + spaceAccess: rules.groupAccess, + }; +}; + +export const groupAccessToSpaceAccess = ( + group: GroupAccess +): SpaceAccess => { + const spaceAccess: SpaceAccess = { + spaceAccess: group.groupAccess, + }; + + // If rules are present in the groupAccess, map them to the spaceAccess + if (group.rules) { + spaceAccess.rules = convertRulesToSpaceRules(group.rules); + } + + return spaceAccess; +}; + + export const updateGroupPayload = ( groupName: string, groupImage: string | null, diff --git a/packages/restapi/src/lib/chat/helpers/service.ts b/packages/restapi/src/lib/chat/helpers/service.ts index c0f016319..f573840aa 100644 --- a/packages/restapi/src/lib/chat/helpers/service.ts +++ b/packages/restapi/src/lib/chat/helpers/service.ts @@ -22,6 +22,7 @@ type CreateUserOptionsType = { publicKey?: string; encryptedPrivateKey?: string; env?: ENV; + origin? : string | null; }; export const createUserService = async (options: CreateUserOptionsType) => { @@ -30,6 +31,7 @@ export const createUserService = async (options: CreateUserOptionsType) => { publicKey = '', encryptedPrivateKey = '', env = Constants.ENV.PROD, + origin, } = options || {}; let { user } = options || {}; @@ -47,7 +49,7 @@ export const createUserService = async (options: CreateUserOptionsType) => { caip10: walletToPCAIP10(user), did: walletToPCAIP10(user), publicKey, - encryptedPrivateKey, + encryptedPrivateKey }; const hash = generateHash(data); @@ -56,6 +58,7 @@ export const createUserService = async (options: CreateUserOptionsType) => { const body = { ...data, + origin: origin, ...signatureObj, }; diff --git a/packages/restapi/src/lib/space/Space.ts b/packages/restapi/src/lib/space/Space.ts index 577e8b11f..5f2399f85 100644 --- a/packages/restapi/src/lib/space/Space.ts +++ b/packages/restapi/src/lib/space/Space.ts @@ -28,7 +28,6 @@ import { SpaceSpecificData, } from '../types'; import { VIDEO_CALL_TYPE } from '../payloads/constants'; -import getLiveSpaceData from './helpers/getLiveSpaceData'; import sendLiveSpaceData from './helpers/sendLiveSpaceData'; import { META_ACTION } from '../types/messageObjectTypes'; import { broadcastRaisedHand } from './broadcastRaisedHand'; @@ -83,7 +82,7 @@ export interface SpaceConstructorType extends EnvOptionsType { // declaring the Space class export class Space extends Video { - protected mergeStreamObject: VideoStreamMerger | null = null; + protected mergedStream: VideoStreamMerger | null = null; protected spaceSpecificData: SpaceSpecificData; protected setSpaceSpecificData: ( @@ -121,29 +120,37 @@ export class Space extends Video { this.data.meta.broadcast?.hostAddress && this.data.meta.broadcast.hostAddress === this.data.local.address ) { - addToMergedStream(this.mergeStreamObject!, receivedStream); + addToMergedStream(this.mergedStream!, receivedStream); // update live space info - const oldLiveSpaceData = await getLiveSpaceData({ - localAddress: this.data.local.address, - pgpPrivateKey: this.pgpPrivateKey, - env: this.env, - spaceId: this.spaceSpecificData.spaceId, - }); - const updatedLiveSpaceData = produce(oldLiveSpaceData, (draft) => { - // check if the address was a listener - const listnerIndex = draft.listeners.findIndex( - (listner) => listner.address === senderAddress - ); - if (listnerIndex > -1) draft.listeners.splice(listnerIndex, 1); - - // TODO: Create distinction between speakers and co hosts - draft.speakers.push({ - address: senderAddress, - audio, - emojiReactions: null, - }); - }); + const updatedLiveSpaceData = produce( + this.spaceSpecificData.liveSpaceData, + (draft) => { + // check if the address was a listener + const listenerIndex = + this.spaceSpecificData.liveSpaceData.listeners.findIndex( + (listener) => listener.address === senderAddress + ); + + // TODO: Create distinction between speakers and co hosts + draft.speakers.push({ + address: senderAddress, + audio, + emojiReactions: + listenerIndex > -1 + ? this.spaceSpecificData.liveSpaceData.listeners[ + listenerIndex + ].emojiReactions + : null, + }); + + if (listenerIndex > -1) draft.listeners.splice(listenerIndex, 1); + } + ); + this.setSpaceSpecificData(() => ({ + ...this.spaceSpecificData, + liveSpaceData: updatedLiveSpaceData, + })); await sendLiveSpaceData({ liveSpaceData: updatedLiveSpaceData, pgpPrivateKey: this.pgpPrivateKey, @@ -152,10 +159,6 @@ export class Space extends Video { signer: this.signer, action: META_ACTION.PROMOTE_TO_ADMIN, // TODO: Add a meta action for SPEAKER_JOINED }); - this.setSpaceSpecificData(() => ({ - ...this.spaceSpecificData, - liveSpaceData: updatedLiveSpaceData, - })); } }, setData: function () { diff --git a/packages/restapi/src/lib/space/acceptPromotionRequest.ts b/packages/restapi/src/lib/space/acceptPromotionRequest.ts index ffa2b9d2b..0a5ea4ea3 100644 --- a/packages/restapi/src/lib/space/acceptPromotionRequest.ts +++ b/packages/restapi/src/lib/space/acceptPromotionRequest.ts @@ -1,17 +1,11 @@ -import { produce } from 'immer'; - import type Space from './Space'; import { addSpeakers } from './addSpeakers'; -import getLiveSpaceData from './helpers/getLiveSpaceData'; -import sendLiveSpaceData from './helpers/sendLiveSpaceData'; import { pCAIP10ToWallet } from '../helpers'; import { SPACE_ACCEPT_REQUEST_TYPE, SPACE_INVITE_ROLES, } from '../payloads/constants'; -import { META_ACTION } from '../types/messageObjectTypes'; -import { AdminPeer } from '../types'; export interface IAcceptPromotionRequestType { signalData: any; @@ -41,44 +35,6 @@ export async function acceptPromotionRequest( env: this.env, }); - // get old live space data - const oldLiveSpaceData = await getLiveSpaceData({ - localAddress: this.data.local.address, - pgpPrivateKey: this.pgpPrivateKey, - env: this.env, - spaceId: this.spaceSpecificData.spaceId, - }); - - // update the metamessage - const updatedLiveSpaceData = produce(oldLiveSpaceData, (draft) => { - const listnerIndex = draft.listeners.findIndex( - (listner) => listner.address === pCAIP10ToWallet(promoteeAddress) - ); - if (listnerIndex > -1) draft.listeners[listnerIndex].handRaised = false; - - // convert listener to speaker type (ListenerPeer -> AdminPeer) - const promotedListener: AdminPeer = { - address: draft.listeners[listnerIndex].address, - emojiReactions: draft.listeners[listnerIndex].emojiReactions, - audio: true, - }; - - // remove listener from speaker array - draft.listeners.splice(listnerIndex, 1); - - // add listener to speaker array - draft.speakers.push(promotedListener); - }); - - await sendLiveSpaceData({ - liveSpaceData: updatedLiveSpaceData, - pgpPrivateKey: this.pgpPrivateKey, - env: this.env, - spaceId: this.spaceSpecificData.spaceId, - signer: this.signer, - action: META_ACTION.PROMOTE_TO_SPEAKER, - }); - // accept the promotion request this.acceptRequest({ signalData, diff --git a/packages/restapi/src/lib/space/broadcastRaisedHand.ts b/packages/restapi/src/lib/space/broadcastRaisedHand.ts index 8ff2a21f2..3554de01c 100644 --- a/packages/restapi/src/lib/space/broadcastRaisedHand.ts +++ b/packages/restapi/src/lib/space/broadcastRaisedHand.ts @@ -1,10 +1,10 @@ import { produce } from 'immer'; -import type Space from './Space'; -import getLiveSpaceData from './helpers/getLiveSpaceData'; import sendLiveSpaceData from './helpers/sendLiveSpaceData'; import { META_ACTION } from '../types/messageObjectTypes'; import { pCAIP10ToWallet } from '../helpers'; +import type Space from './Space'; + export interface BroadcastRaisedHandType { promoteeAddress: string; } @@ -15,22 +15,26 @@ export async function broadcastRaisedHand( ) { const { promoteeAddress } = options || {}; - console.log('BROADCAST RAISE HAND', promoteeAddress); + console.log('BROADCAST RAISE HAND', options); // update live space info - const oldLiveSpaceData = await getLiveSpaceData({ - localAddress: this.data.local.address, - pgpPrivateKey: this.pgpPrivateKey, - env: this.env, - spaceId: this.spaceSpecificData.spaceId, - }); - const updatedLiveSpaceData = produce(oldLiveSpaceData, (draft) => { - const listenerIndex = draft.listeners.findIndex( - (listner) => - pCAIP10ToWallet(listner.address) === pCAIP10ToWallet(promoteeAddress) - ); - if (listenerIndex !== -1) draft.listeners[listenerIndex].handRaised = true; - }); + const updatedLiveSpaceData = produce( + this.spaceSpecificData.liveSpaceData, + (draft) => { + const listenerIndex = + this.spaceSpecificData.liveSpaceData.listeners.findIndex( + (listener) => + pCAIP10ToWallet(listener.address) === + pCAIP10ToWallet(promoteeAddress) + ); + if (listenerIndex !== -1) + draft.listeners[listenerIndex].handRaised = true; + } + ); + this.setSpaceSpecificData(() => ({ + ...this.spaceSpecificData, + liveSpaceData: updatedLiveSpaceData, + })); await sendLiveSpaceData({ liveSpaceData: updatedLiveSpaceData, pgpPrivateKey: this.pgpPrivateKey, @@ -39,8 +43,4 @@ export async function broadcastRaisedHand( signer: this.signer, action: META_ACTION.USER_INTERACTION, }); - this.setSpaceSpecificData(() => ({ - ...this.spaceSpecificData, - liveSpaceData: updatedLiveSpaceData, - })); } diff --git a/packages/restapi/src/lib/space/create.ts b/packages/restapi/src/lib/space/create.ts index c05f01011..edfab86d1 100644 --- a/packages/restapi/src/lib/space/create.ts +++ b/packages/restapi/src/lib/space/create.ts @@ -16,7 +16,6 @@ export interface ChatCreateSpaceType extends EnvOptionsType { contractAddressERC20?: string; numberOfERC20?: number; pgpPrivateKey?: string; - meta?: string; scheduleAt: Date; scheduleEnd?: Date | null; rules?: SpaceRules | null; @@ -37,7 +36,6 @@ export async function create(options: ChatCreateSpaceType): Promise { numberOfERC20, env = Constants.ENV.PROD, pgpPrivateKey = null, - meta, scheduleAt, scheduleEnd, rules, @@ -60,7 +58,6 @@ export async function create(options: ChatCreateSpaceType): Promise { numberOfERC20: numberOfERC20, env, pgpPrivateKey, - meta: meta, groupType: 'spaces', scheduleAt: scheduleAt, scheduleEnd: scheduleEnd, diff --git a/packages/restapi/src/lib/space/getAccess.ts b/packages/restapi/src/lib/space/getAccess.ts new file mode 100644 index 000000000..1d4397170 --- /dev/null +++ b/packages/restapi/src/lib/space/getAccess.ts @@ -0,0 +1,32 @@ +import Constants, { ENV } from '../constants'; +import { getGroupAccess, groupAccessToSpaceAccess } from '../chat'; +import { SpaceAccess } from '../types'; + +/** + * GET /v1/chat/groups/:chatId/access/:did + */ + +export interface GetSpaceAccessType { + spaceId: string; + did: string; // Decentralized Identifier + env?: ENV; +} + +export const getAccess = async (options: GetSpaceAccessType): Promise => { + // Replace "any" with the actual response type + const { spaceId, did, env = Constants.ENV.PROD } = options || {}; + try { + if (spaceId == null || spaceId.length === 0) { + throw new Error(`spaceId cannot be null or empty`); + } + if (did == null || did.length === 0) { + throw new Error(`did cannot be null or empty`); + } + + const access = await getGroupAccess({ chatId: spaceId, did: did, env: env }); + return groupAccessToSpaceAccess(access); + } catch (err) { + console.error(`[Push SDK] - API - Error - API ${getAccess.name} -: `, err); + throw Error(`[Push SDK] - API - Error - API ${getAccess.name} -: ${err}`); + } +}; diff --git a/packages/restapi/src/lib/space/index.ts b/packages/restapi/src/lib/space/index.ts index e2ea49306..4431c4322 100644 --- a/packages/restapi/src/lib/space/index.ts +++ b/packages/restapi/src/lib/space/index.ts @@ -12,5 +12,6 @@ export * from './addListeners'; export * from './removeListeners'; export * from './approve'; export * from './requests'; +export * from './getAccess'; export {spaceFeed as space} from './spaceFeed'; export * from './Space' diff --git a/packages/restapi/src/lib/space/onJoinListener.ts b/packages/restapi/src/lib/space/onJoinListener.ts index d591c5adf..497701d57 100644 --- a/packages/restapi/src/lib/space/onJoinListener.ts +++ b/packages/restapi/src/lib/space/onJoinListener.ts @@ -1,7 +1,7 @@ -import getLiveSpaceData from './helpers/getLiveSpaceData'; import sendLiveSpaceData from './helpers/sendLiveSpaceData'; import { get } from './get'; import { pCAIP10ToWallet } from '../helpers'; +import { produce } from 'immer'; import { META_ACTION } from '../types/messageObjectTypes'; import type Space from './Space'; @@ -34,43 +34,47 @@ export async function onJoinListener(this: Space, options: OnJoinListenerType) { !member.isSpeaker ); - // if the address is not a listner then we dont fire a meta message + // if the address is not a listener then we dont fire a meta message if (!isAddressListener) { return; } // check if the listener is already present in the liveSpaceData - const fetchedLiveSpaceData = await getLiveSpaceData({ - localAddress: this.data.local.address, - spaceId: this.spaceSpecificData.spaceId, - pgpPrivateKey: this.pgpPrivateKey, - env: this.env, - }); + const modifiedLiveSpaceData = produce( + this.spaceSpecificData.liveSpaceData, + (draft) => { + const isListenerAlreadyAdded = this.spaceSpecificData.liveSpaceData.listeners.find( + (currentListener) => + pCAIP10ToWallet(currentListener.address) === + pCAIP10ToWallet(receivedAddress) + ); - const isListenerAlreadyAdded = fetchedLiveSpaceData.listeners.find( - (currentListener) => - pCAIP10ToWallet(currentListener.address) === - pCAIP10ToWallet(receivedAddress) + if (isListenerAlreadyAdded) { + // listener is already added in the meta message + // might be case when the listener has left the space + } else { + // adding new listener in the live space data + draft.listeners.push({ + address: pCAIP10ToWallet(receivedAddress), + handRaised: false, + emojiReactions: null, + }); + } + } ); - if (isListenerAlreadyAdded) { - // listener is already added in the meta message - // might be case when the listener has left the space - } + this.setSpaceSpecificData(() => ({ + ...this.spaceSpecificData, + liveSpaceData: modifiedLiveSpaceData, + })); - // adding new listener in the live space data - fetchedLiveSpaceData.listeners.push({ - address: pCAIP10ToWallet(receivedAddress), - handRaised: false, - emojiReactions: null, - }); // firing a meta message await sendLiveSpaceData({ spaceId: this.spaceSpecificData.spaceId, pgpPrivateKey: this.pgpPrivateKey, env: this.env, signer: this.signer, - liveSpaceData: fetchedLiveSpaceData, + liveSpaceData: modifiedLiveSpaceData, action: META_ACTION.ADD_LISTENER, }); } diff --git a/packages/restapi/src/lib/space/rejectPromotionRequest.ts b/packages/restapi/src/lib/space/rejectPromotionRequest.ts index 0a3c4ea33..fba5b91ed 100644 --- a/packages/restapi/src/lib/space/rejectPromotionRequest.ts +++ b/packages/restapi/src/lib/space/rejectPromotionRequest.ts @@ -1,10 +1,10 @@ import { produce } from 'immer'; -import type Space from './Space'; -import getLiveSpaceData from './helpers/getLiveSpaceData'; import sendLiveSpaceData from './helpers/sendLiveSpaceData'; import { META_ACTION } from '../types/messageObjectTypes'; import { pCAIP10ToWallet } from '../helpers'; +import type Space from './Space'; + export interface RejectPromotionRequestType { promoteeAddress: string; } @@ -21,18 +21,20 @@ export async function rejectPromotionRequest( }); // update live space info - const oldLiveSpaceData = await getLiveSpaceData({ - localAddress: this.data.local.address, - pgpPrivateKey: this.pgpPrivateKey, - env: this.env, - spaceId: this.spaceSpecificData.spaceId, - }); - const updatedLiveSpaceData = produce(oldLiveSpaceData, (draft) => { - const listnerIndex = draft.listeners.findIndex( - (listner) => listner.address === pCAIP10ToWallet(promoteeAddress) - ); - if (listnerIndex > -1) draft.listeners[listnerIndex].handRaised = false; - }); + const updatedLiveSpaceData = produce( + this.spaceSpecificData.liveSpaceData, + (draft) => { + const listnerIndex = + this.spaceSpecificData.liveSpaceData.listeners.findIndex( + (listener) => listener.address === pCAIP10ToWallet(promoteeAddress) + ); + if (listnerIndex > -1) draft.listeners[listnerIndex].handRaised = false; + } + ); + this.setSpaceSpecificData(() => ({ + ...this.spaceSpecificData, + liveSpaceData: updatedLiveSpaceData, + })); await sendLiveSpaceData({ liveSpaceData: updatedLiveSpaceData, pgpPrivateKey: this.pgpPrivateKey, @@ -41,8 +43,4 @@ export async function rejectPromotionRequest( signer: this.signer, action: META_ACTION.USER_INTERACTION, // TODO: Add a reject request type }); - this.setSpaceSpecificData(() => ({ - ...this.spaceSpecificData, - liveSpaceData: updatedLiveSpaceData, - })); } diff --git a/packages/restapi/src/lib/space/start.ts b/packages/restapi/src/lib/space/start.ts index c55bb5602..c5df1f0bc 100644 --- a/packages/restapi/src/lib/space/start.ts +++ b/packages/restapi/src/lib/space/start.ts @@ -13,7 +13,6 @@ import { get } from './get'; import { updateGroup } from '../chat/updateGroup'; import getMergeStreamObject from './helpers/getMergeStreamObject'; import axios from 'axios'; -import { Client } from '@livepeer/webrtmp-sdk'; export interface StartSpaceType extends EnvOptionsType { spaceId: string; @@ -120,9 +119,9 @@ export async function start(this: Space, options: StartType): Promise { // send a notification/meta message to all the added listeners (members) telling the space has started // create the mergeStream object - const mergeStreamObject = getMergeStreamObject(this.data.local.stream); + const mergedStream = getMergeStreamObject(this.data.local.stream); // store the mergeStreamObject - this.mergeStreamObject = mergeStreamObject; + this.mergedStream = mergedStream; const url = 'https://livepeer.studio/api/stream'; const data = { @@ -140,26 +139,87 @@ export async function start(this: Space, options: StartType): Promise { console.log('livepeer details', streamKey, playbackId); - // TODO: store the playbackId on group meta data, temp -> groupDescription - this.update({ spaceDescription: playbackId }); + this.update({ meta: playbackId }); - // cast to the stream - const client = new Client(); - const session = client.cast(mergeStreamObject.result!, streamKey); - session.on('open', () => { - console.log('Live stream started.'); - // TODO: Update the space data - }); + let redirectUrl; + try { + console.log('Ignore the following error'); - session.on('close', () => { - console.log('Live stream stopped.'); - // TODO: Update the space data - }); + // the redirect URL from the above GET request + await axios.get(`https://livepeer.studio/webrtc/${streamKey}`); + } catch (err: any) { + console.log('redirectUrl error', err); + redirectUrl = err.request.responseURL; + } + + // we use the host from the redirect URL in the ICE server configuration + const host = new URL(redirectUrl).host; + + const iceServers = [ + { + urls: `stun:${host}`, + }, + { + urls: `turn:${host}`, + username: 'livepeer', + credential: 'livepeer', + }, + ]; + + const peerConnection = new RTCPeerConnection({ iceServers }); - session.on('error', (err) => { - console.log('Live stream error.', err.message); - // TODO: Update the space data + const newAudioTrack = mergedStream.result?.getAudioTracks?.()?.[0] ?? null; + + if (newAudioTrack) { + peerConnection?.addTransceiver(newAudioTrack, { + direction: 'sendonly', + }); + } + + /** + * https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createOffer + * We create an SDP offer here which will be shared with the server + */ + const offer = await peerConnection.createOffer(); + /** https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription */ + await peerConnection.setLocalDescription(offer); + + /** Wait for ICE gathering to complete */ + const ofr = await new Promise((resolve) => { + /** Wait at most five seconds for ICE gathering. */ + setTimeout(() => { + resolve(peerConnection.localDescription); + }, 5000); + peerConnection.onicegatheringstatechange = (_ev) => { + if (peerConnection.iceGatheringState === 'complete') { + resolve(peerConnection.localDescription); + } + }; }); + if (!ofr) { + throw Error('failed to gather ICE candidates for offer'); + } + /** + * This response contains the server's SDP offer. + * This specifies how the client should communicate, + * and what kind of media client and server have negotiated to exchange. + */ + const sdpResponse = await fetch(redirectUrl, { + method: 'POST', + mode: 'cors', + headers: { + 'content-type': 'application/sdp', + }, + body: ofr.sdp, + }); + if (sdpResponse.ok) { + const answerSDP = await sdpResponse.text(); + await peerConnection.setRemoteDescription( + new RTCSessionDescription({ type: 'answer', sdp: answerSDP }) + ); + } + + console.log('Live Stream started'); } catch (err) { console.error(`[Push SDK] - API - Error - API ${start.name} -: `, err); throw Error(`[Push SDK] - API - Error - API ${start.name} -: ${err}`); diff --git a/packages/restapi/src/lib/space/update.ts b/packages/restapi/src/lib/space/update.ts index 2ccbea8ef..8459f519d 100644 --- a/packages/restapi/src/lib/space/update.ts +++ b/packages/restapi/src/lib/space/update.ts @@ -15,14 +15,21 @@ export interface ChatUpdateSpaceType { spaceDescription?: string; scheduleAt?: Date; scheduleEnd?: Date | null; + meta?: string | null; } export async function update( this: Space, options: ChatUpdateSpaceType ): Promise { - const { spaceName, spaceImage, spaceDescription, scheduleAt, scheduleEnd } = - options || {}; + const { + spaceName, + spaceImage, + spaceDescription, + scheduleAt, + scheduleEnd, + meta, + } = options || {}; try { const space = await get({ spaceId: this.spaceSpecificData.spaceId, @@ -60,6 +67,7 @@ export async function update( pgpPrivateKey: this.pgpPrivateKey, scheduleAt: scheduleAt ? scheduleAt : space.scheduleAt, scheduleEnd: scheduleEnd ? scheduleEnd : space.scheduleEnd, + meta: meta ? meta : space.meta, }); // update space specific data diff --git a/packages/restapi/src/lib/types/index.ts b/packages/restapi/src/lib/types/index.ts index 8e2f884fc..002660876 100644 --- a/packages/restapi/src/lib/types/index.ts +++ b/packages/restapi/src/lib/types/index.ts @@ -242,6 +242,7 @@ export interface IUser { encryptedPrivateKey: string; publicKey: string; verificationProof: string; + origin?: string | null; /** * @deprecated Use `profile.name` instead. @@ -310,11 +311,14 @@ export enum ConditionType { } export type Data = { - address?: string; + contract?: string; amount?: number; decimals?: number; guildId?: string; - roleId?: string; + guildRoleId?: string; + guildRoleAction?: 'all' | 'any'; + url?: string; + comparison?: '>' | '<' | '>=' | '<=' | '==' | '!='; }; export type ConditionBase = { @@ -335,7 +339,7 @@ export interface Rules { groupAccess?: { conditions: Array; }; - chattingAccess?: { + chatAccess?: { conditions: Array; }; } @@ -346,6 +350,16 @@ export interface SpaceRules { }; } +export interface GroupAccess { + groupAccess: boolean; + chatAccess: boolean; + rules?: Rules; +} + +export interface SpaceAccess { + spaceAccess: boolean; + rules?: SpaceRules; +} export interface GroupDTO { members: { diff --git a/packages/restapi/src/lib/user/createUser.ts b/packages/restapi/src/lib/user/createUser.ts index 6f8df4419..2d812de3f 100644 --- a/packages/restapi/src/lib/user/createUser.ts +++ b/packages/restapi/src/lib/user/createUser.ts @@ -35,6 +35,7 @@ export type CreateUserProps = { }; }; progressHook?: (progress: ProgressHookType) => void; + origin? : string | null }; interface ICreateUser extends IUser { @@ -55,6 +56,7 @@ export const create = async ( }, }, progressHook, + origin } = options || {}; try { @@ -121,6 +123,7 @@ export const create = async ( publicKey: publicKey, encryptedPrivateKey: JSON.stringify(encryptedPrivateKey), env, + origin: origin }; const createdUser: ICreateUser = await createUserService(body); diff --git a/packages/restapi/src/lib/video/Video.ts b/packages/restapi/src/lib/video/Video.ts index 1d75ab164..06d33c9d9 100644 --- a/packages/restapi/src/lib/video/Video.ts +++ b/packages/restapi/src/lib/video/Video.ts @@ -900,28 +900,33 @@ export class Video { if (this.data.local.audio !== state) { // need to change the audio state - // signal all the connected peers that the local peer has changed their audio state + // Signal all the connected peers that the local peer has changed their audio state for (const incomingPeer of this.data.incoming) { - if (incomingPeer.status === VideoCallStatus.CONNECTED) { - this.peerInstances[incomingPeer.address]?.send( - JSON.stringify({ type: 'isAudioOn', value: state }) - ); + if (incomingPeer.status === VideoCallStatus.CONNECTED && this.peerInstances[incomingPeer.address]) { + try { + this.peerInstances[incomingPeer.address].send( + JSON.stringify({ type: 'isAudioOn', value: state }) + ); + } catch (error) { + console.error("Error sending data:", error); + } } } - if (this.data.local.stream) { - if (state) { - restartAudioStream(this.data.local.stream); - } else { - stopAudioStream(this.data.local.stream); + + if (this.data.local.stream) { + if (state) { + restartAudioStream(this.data.local.stream); + } else { + stopAudioStream(this.data.local.stream); + } + this.setData((oldData) => { + return produce(oldData, (draft) => { + draft.local.audio = state; + }); + }); } - this.setData((oldData) => { - return produce(oldData, (draft) => { - draft.local.audio = state; - }); - }); - } } - } +} // helper functions diff --git a/packages/restapi/yarn.lock b/packages/restapi/yarn.lock index ecb8c0c6a..de55ed8e8 100644 --- a/packages/restapi/yarn.lock +++ b/packages/restapi/yarn.lock @@ -436,13 +436,6 @@ tus-js-client "^3.1.0" zustand "^4.3.9" -"@livepeer/webrtmp-sdk@^0.2.3": - version "0.2.5" - resolved "https://registry.npmjs.org/@livepeer/webrtmp-sdk/-/webrtmp-sdk-0.2.5.tgz" - integrity sha512-2XroFoza1f9OuywtWrGHm9v4ogNxOdr2pnDGqF3EcsLRsGx5LhOKwWnEjLep+H37pSwpMRRJARQmz+qq/WoQYA== - dependencies: - events "3.3.0" - "@ljharb/resumer@^0.0.1": version "0.0.1" resolved "https://registry.npmjs.org/@ljharb/resumer/-/resumer-0.0.1.tgz" @@ -1224,11 +1217,6 @@ ethjs-util@^0.1.6: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" -events@3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - execa@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz" @@ -1244,7 +1232,7 @@ execa@^1.0.0: figures@^1.4.0: version "1.7.0" - resolved "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" integrity sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ== dependencies: escape-string-regexp "^1.0.5" @@ -1279,7 +1267,7 @@ flat@^5.0.2: for-each@^0.3.3: version "0.3.3" - resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== dependencies: is-callable "^1.1.3" @@ -1296,12 +1284,12 @@ fsevents@~2.3.2: function-bind@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== function.prototype.name@^1.1.5: version "1.1.5" - resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== dependencies: call-bind "^1.0.2" @@ -1311,7 +1299,7 @@ function.prototype.name@^1.1.5: functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" - resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== get-browser-rtc@^1.1.0: @@ -1336,7 +1324,7 @@ get-func-name@^2.0.0: get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== dependencies: function-bind "^1.1.1" @@ -1346,7 +1334,7 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ get-package-type@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== get-stream@^4.0.0: @@ -1358,7 +1346,7 @@ get-stream@^4.0.0: get-symbol-description@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== dependencies: call-bind "^1.0.2" @@ -1385,7 +1373,7 @@ glob@7.2.0: glob@^7.2.3: version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -1397,38 +1385,38 @@ glob@^7.2.3: globalthis@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== dependencies: define-properties "^1.1.3" gopd@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== dependencies: get-intrinsic "^1.1.3" graceful-fs@^4.2.4: version "4.2.11" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== has-ansi@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== dependencies: ansi-regex "^2.0.0" has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-dynamic-import@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/has-dynamic-import/-/has-dynamic-import-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/has-dynamic-import/-/has-dynamic-import-2.0.1.tgz#9bca87846aa264f2ad224fcd014946f5e5182f52" integrity sha512-X3fbtsZmwb6W7fJGR9o7x65fZoodygCrZ3TVycvghP62yYQfS0t4RS0Qcz+j5tQYUKeSWS09tHkWW6WhFV3XhQ== dependencies: call-bind "^1.0.2" @@ -1446,38 +1434,38 @@ has-flag@^4.0.0: has-property-descriptors@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== dependencies: get-intrinsic "^1.1.1" has-proto@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== has-tostringtag@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== dependencies: has-symbols "^1.0.2" has@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" - resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" @@ -1490,12 +1478,12 @@ he@1.2.0: hls.js@^1.4.9: version "1.4.10" - resolved "https://registry.npmjs.org/hls.js/-/hls.js-1.4.10.tgz" + resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-1.4.10.tgz#3feac40f21a558453b243b5b926b7317e70624e1" integrity sha512-wAVSj4Fm2MqOHy5+BlYnlKxXvJlv5IuZHjlzHu18QmjRzSDFQiUDWdHs5+NsFMQrgKEBwuWDcyvaMC9dUzJ5Uw== hmac-drbg@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== dependencies: hash.js "^1.0.3" @@ -1527,7 +1515,7 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, internal-slot@^1.0.4, internal-slot@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== dependencies: get-intrinsic "^1.2.0" @@ -1541,7 +1529,7 @@ invert-kv@^2.0.0: is-arguments@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== dependencies: call-bind "^1.0.2" @@ -1549,7 +1537,7 @@ is-arguments@^1.1.1: is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== dependencies: call-bind "^1.0.2" @@ -1558,7 +1546,7 @@ is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: is-bigint@^1.0.1: version "1.0.4" - resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== dependencies: has-bigints "^1.0.1" @@ -1572,7 +1560,7 @@ is-binary-path@~2.1.0: is-boolean-object@^1.1.0: version "1.1.2" - resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== dependencies: call-bind "^1.0.2" @@ -1580,19 +1568,19 @@ is-boolean-object@^1.1.0: is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" - resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== is-core-module@^2.9.0: - version "2.13.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + version "2.12.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== dependencies: has "^1.0.3" is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== dependencies: has-tostringtag "^1.0.0" @@ -1604,7 +1592,7 @@ is-extglob@^2.1.1: is-finite@^1.0.1: version "1.1.0" - resolved "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== is-fullwidth-code-point@^1.0.0: @@ -1638,17 +1626,17 @@ is-hex-prefixed@1.0.0: is-map@^2.0.1, is-map@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== is-negative-zero@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== is-number-object@^1.0.4: version "1.0.7" - resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== dependencies: has-tostringtag "^1.0.0" @@ -1665,7 +1653,7 @@ is-plain-obj@^2.1.0: is-regex@^1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" @@ -1673,12 +1661,12 @@ is-regex@^1.1.4: is-set@^2.0.1, is-set@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== is-shared-array-buffer@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== dependencies: call-bind "^1.0.2" @@ -1690,26 +1678,26 @@ is-stream@^1.1.0: is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" - resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== dependencies: has-tostringtag "^1.0.0" is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: has-symbols "^1.0.2" is-typed-array@^1.1.10, is-typed-array@^1.1.9: version "1.1.12" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== dependencies: which-typed-array "^1.1.11" @@ -1721,19 +1709,19 @@ is-unicode-supported@^0.1.0: is-weakmap@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== is-weakref@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== dependencies: call-bind "^1.0.2" is-weakset@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== dependencies: call-bind "^1.0.2" @@ -1741,12 +1729,12 @@ is-weakset@^2.0.1: isarray@^2.0.5: version "2.0.5" - resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== isarray@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== isexe@^2.0.0: diff --git a/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx b/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx index 43a5af227..0a14ccbcc 100644 --- a/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx +++ b/packages/uiweb/src/lib/components/chat/MessageInput/MessageInput.tsx @@ -25,7 +25,7 @@ import { Image } from "../../reusables"; import { ConnectButtonComp } from "../ConnectButton"; import useGetGroupByID from "../../../hooks/chat/useGetGroupByID"; import { ethers } from "ethers"; -import { pCAIP10ToWallet } from "../../../helpers"; +import { pCAIP10ToWallet, setAccessControl } from "../../../helpers"; /** * @interface IThemeProps @@ -91,12 +91,14 @@ export const MessageInput: React.FC = ({ chatId, Emoji = true const storedTimestamp = JSON.parse(storedTimestampJSON); const currentTimestamp = new Date().getTime(); const twentyFourHoursInMilliseconds = 24 * 60 * 60 * 1000; + console.log(twentyFourHoursInMilliseconds) - if (currentTimestamp - storedTimestamp < twentyFourHoursInMilliseconds) { - console.log(currentTimestamp - storedTimestamp) + if (Math.abs(currentTimestamp - storedTimestamp) < twentyFourHoursInMilliseconds) { + console.log(Math.abs(currentTimestamp - storedTimestamp)) setVerified(true); } else { setVerified(false); + setAccessControl(chatId, true) } } }, [chatId, verified]) @@ -184,6 +186,7 @@ export const MessageInput: React.FC = ({ chatId, Emoji = true console.log(groupInfo, "groupInfooooo") } } + console.log(verificationSuccessfull, "verrifficagtionnn") useEffect(() => { console.log(chatId, "chatIdddd") @@ -216,7 +219,10 @@ export const MessageInput: React.FC = ({ chatId, Emoji = true ) } - {pgpPrivateKey && !verified && isRules && ( + {pgpPrivateKey && + !verified + // verified + && isRules && (
@@ -232,13 +238,13 @@ export const MessageInput: React.FC = ({ chatId, Emoji = true {pgpPrivateKey && !verificationSuccessfull && (
- Verification Failed + Verification Failed Please ensure the following conditions are met to participate and send messages.
token-gated
{/* Added marginLeft */} - Token Gated - You need to have 1 PUSH Token in your wallet to be able to send messages. + Token Gated + You need to have 1 PUSH Token in your wallet to be able to send messages.
@@ -266,7 +272,10 @@ export const MessageInput: React.FC = ({ chatId, Emoji = true
)} - {pgpPrivateKey && (isRules ? verified : true) && + {pgpPrivateKey && + (isRules ? verified : true) + // true + && <>
{Emoji && diff --git a/packages/uiweb/src/lib/components/space/SpaceWidget/LiveWidgetContent.tsx b/packages/uiweb/src/lib/components/space/SpaceWidget/LiveWidgetContent.tsx index 1e89abac9..2e996e542 100644 --- a/packages/uiweb/src/lib/components/space/SpaceWidget/LiveWidgetContent.tsx +++ b/packages/uiweb/src/lib/components/space/SpaceWidget/LiveWidgetContent.tsx @@ -1,5 +1,5 @@ -import React, { useEffect, useState, useRef, useContext } from 'react'; -import styled, { keyframes, ThemeProvider } from 'styled-components'; +import React, { useEffect, useState, useContext } from 'react'; +import styled, { ThemeProvider } from 'styled-components'; import { Player } from '@livepeer/react'; import * as PushAPI from '@pushprotocol/restapi'; import { SpaceDTO } from '@pushprotocol/restapi'; @@ -17,7 +17,6 @@ import MicOnIcon from '../../../icons/micon.svg'; import MicEngagedIcon from '../../../icons/MicEngage.svg'; import MuteIcon from '../../../icons/Muted.svg'; import HandIcon from '../../../icons/hand.svg'; -import ShareIcon from '../../../icons/Share.svg'; import MembersIcon from '../../../icons/Members.svg'; import { useSpaceData } from '../../../hooks'; import { SpaceStatus } from './WidgetContent'; @@ -51,7 +50,6 @@ export const LiveWidgetContent: React.FC = ({ setSpaceObjectData, isSpeaker, isListener, - setSpaceWidgetId, isJoined, initSpaceObject, raisedHandInfo, @@ -202,24 +200,25 @@ export const LiveWidgetContent: React.FC = ({ }, [spaceObjectData?.connectionData?.local?.stream]); useEffect(() => { - if (!spaceObjectData?.spaceDescription) return; - const playBackUrl = spaceObjectData?.spaceDescription; - setPlayBackUrl(playBackUrl); - }, [spaceObjectData?.spaceDescription]); + if (!spaceObjectData?.meta) return; + setPlayBackUrl(spaceObjectData?.meta); + }, [spaceObjectData?.meta]); return ( { @@ -321,7 +320,9 @@ export const LiveWidgetContent: React.FC = ({
diff --git a/packages/uiweb/src/lib/components/space/SpaceWidget/SpaceWidget.tsx b/packages/uiweb/src/lib/components/space/SpaceWidget/SpaceWidget.tsx index a3534585b..2a0ea7fe1 100644 --- a/packages/uiweb/src/lib/components/space/SpaceWidget/SpaceWidget.tsx +++ b/packages/uiweb/src/lib/components/space/SpaceWidget/SpaceWidget.tsx @@ -142,7 +142,7 @@ const Container = styled.div` border: 1px solid ${(props) => props.theme.borderColor}; // update acc to theme display: flex; flex-direction: column; - width: ${(props) => (props.width ? `${props.width}px` : 'auto')}; + width: ${(props) => (props.width ? `${props.width}px` : `${DEFAULT_MAXWIDTH}px`)}; max-width: ${(props) => props.width ? `${props.width}px` : `${DEFAULT_MAXWIDTH}px`}; min-width: 320px; diff --git a/packages/uiweb/src/lib/helpers/chat/localStorage.ts b/packages/uiweb/src/lib/helpers/chat/localStorage.ts index 4d7dac903..9ceedaaf9 100644 --- a/packages/uiweb/src/lib/helpers/chat/localStorage.ts +++ b/packages/uiweb/src/lib/helpers/chat/localStorage.ts @@ -61,3 +61,12 @@ export const setPfp = ({ }) => { localStorage.setItem(account, value); }; + +export const setAccessControl = (chatId: string, toRemove: boolean) => { + if (toRemove) { + localStorage.removeItem(chatId); + } else { + const timestamp = new Date().getTime(); + localStorage.setItem(chatId, JSON.stringify(timestamp)); + } +}; diff --git a/packages/uiweb/src/lib/hooks/chat/usePushSendMessage.ts b/packages/uiweb/src/lib/hooks/chat/usePushSendMessage.ts index 7b202d7d0..415799e77 100644 --- a/packages/uiweb/src/lib/hooks/chat/usePushSendMessage.ts +++ b/packages/uiweb/src/lib/hooks/chat/usePushSendMessage.ts @@ -1,8 +1,9 @@ import * as PushAPI from '@pushprotocol/restapi'; import { useCallback, useContext, useState } from 'react'; - +import useVerifyAccessControl from './useVerifyAccessControl'; import { useChatData } from '..'; import { ENV } from '../../config'; +import { setAccessControl } from '../../helpers'; interface SendMessageParams { message: string; @@ -14,6 +15,8 @@ const usePushSendMessage = () => { const [error, setError] = useState(); const [loading, setLoading] = useState(false); + const { verificationSuccessfull, setVerificationSuccessfull, setVerified } = + useVerifyAccessControl(); const { pgpPrivateKey, env, account } = useChatData(); const sendMessage = useCallback( @@ -30,12 +33,17 @@ const usePushSendMessage = () => { env: env, }); setLoading(false); - console.log(response, "resssponssseeee"); + console.log(response); if (!response) { return false; } return; } catch (error: Error | any) { + if (error.message.includes('400')) { + setAccessControl(chatId, true); + setVerified(false); + setVerificationSuccessfull(false); + } setLoading(false); setError(error.message); console.log(error); diff --git a/packages/uiweb/src/lib/hooks/chat/useVerifyAccessControl.ts b/packages/uiweb/src/lib/hooks/chat/useVerifyAccessControl.ts index 114109c5a..f50ce89f6 100644 --- a/packages/uiweb/src/lib/hooks/chat/useVerifyAccessControl.ts +++ b/packages/uiweb/src/lib/hooks/chat/useVerifyAccessControl.ts @@ -2,6 +2,7 @@ import * as PushAPI from '@pushprotocol/restapi'; import { useCallback, useState } from 'react'; import { ENV } from '../../config'; import { useChatData } from './useChatData'; +import { setAccessControl } from '../../helpers'; interface VerifyAccessControlParams { chatId: string; @@ -17,6 +18,7 @@ const useVerifyAccessControl = () => { const { pgpPrivateKey, env, account } = useChatData(); + console.log('Verification control hook'); const verifyAccessControl = useCallback( async (options: VerifyAccessControlParams) => { const { chatId, did } = options || {}; @@ -32,11 +34,7 @@ const useVerifyAccessControl = () => { setVerificationSuccessfull(false); } else if (response.chatAccess === true) { setVerified(true); - const timestamp = new Date().getTime(); - localStorage.setItem( - chatId, - JSON.stringify(timestamp) - ); + setAccessControl(chatId, false); } console.log(response); if (!response) { @@ -51,9 +49,17 @@ const useVerifyAccessControl = () => { return; } }, - [pgpPrivateKey, account] + [pgpPrivateKey, account, verificationSuccessfull, verified, setVerified] ); - return { verifyAccessControl, error, loading, verificationSuccessfull, setVerificationSuccessfull, verified, setVerified }; + return { + verifyAccessControl, + error, + loading, + verificationSuccessfull, + setVerificationSuccessfull, + verified, + setVerified, + }; }; export default useVerifyAccessControl;