diff --git a/.all-contributorsrc b/.all-contributorsrc index d9607ec5..3e1a42a2 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -108,6 +108,15 @@ "contributions": [ "code" ] + }, + { + "login": "PoulavBhowmick03", + "name": "Poulav Bhowmick", + "avatar_url": "https://avatars.githubusercontent.com/u/133862694?v=4", + "profile": "https://poulav.vercel.app/", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 35b8d931..36d9ddf9 100644 --- a/README.md +++ b/README.md @@ -239,6 +239,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Yusuf Habib
Yusuf Habib

💻 Isaac Onyemaechi Ugwu
Isaac Onyemaechi Ugwu

💻 Oche
Oche

💻 + Poulav Bhowmick
Poulav Bhowmick

💻 diff --git a/apps/indexer/docker-compose.yml b/apps/indexer/docker-compose.yml index 601479d0..a8208a78 100644 --- a/apps/indexer/docker-compose.yml +++ b/apps/indexer/docker-compose.yml @@ -56,6 +56,61 @@ services: - backend restart: on-failure + buy-indexer: + environment: + - AUTH_TOKEN=${AUTH_TOKEN} + image: quay.io/apibara/sink-postgres:latest + command: 'run ./indexer/buy-token.js --connection-string postgresql://admin:password@postgres:5432/indexer -A ${AUTH_TOKEN}' + volumes: + - ./src:/indexer + depends_on: + - postgres + networks: + - backend + restart: on-failure + + + sell-indexer: + environment: + - AUTH_TOKEN=${AUTH_TOKEN} + image: quay.io/apibara/sink-postgres:latest + command: 'run ./indexer/sell-token.js --connection-string postgresql://admin:password@postgres:5432/indexer -A ${AUTH_TOKEN}' + volumes: + - ./src:/indexer + depends_on: + - postgres + networks: + - backend + restart: on-failure + + token-indexer: + environment: + - AUTH_TOKEN=${AUTH_TOKEN} + image: quay.io/apibara/sink-postgres:latest + command: 'run ./indexer/token-launch.js --connection-string postgresql://admin:password@postgres:5432/indexer -A ${AUTH_TOKEN}' + volumes: + - ./src:/indexer + depends_on: + - postgres + networks: + - backend + restart: on-failure + + deploy-indexer: + environment: + - AUTH_TOKEN=${AUTH_TOKEN} + image: quay.io/apibara/sink-postgres:latest + command: 'run ./indexer/deploy-token.js --connection-string postgresql://admin:password@postgres:5432/indexer -A ${AUTH_TOKEN}' + volumes: + - ./src:/indexer + depends_on: + - postgres + networks: + - backend + restart: on-failure + + + networks: backend: driver: bridge diff --git a/apps/mobile/src/components/PrivateKeyImport/index.tsx b/apps/mobile/src/components/PrivateKeyImport/index.tsx index f8673afc..688404d3 100644 --- a/apps/mobile/src/components/PrivateKeyImport/index.tsx +++ b/apps/mobile/src/components/PrivateKeyImport/index.tsx @@ -37,11 +37,13 @@ export const PrivateKeyImport: React.FC = () => { showToast({type: 'error', title: 'Password is required'}); return; } - const passwordRetrieve = await retrievePassword(); - if (password != passwordRetrieve) { - showToast({type: 'error', title: 'Invalid password'}); - return; - } + + /** TODO fix in web */ + // const passwordRetrieve = await retrievePassword(); + // if (password != passwordRetrieve) { + // showToast({type: 'error', title: 'Invalid password'}); + // return; + // } const privateKey = await retrieveAndDecryptPrivateKey(password); if (!privateKey || privateKey.length !== 32) { showToast({type: 'error', title: 'Invalid password'}); diff --git a/apps/mobile/src/modules/Group/all/AllGroup.tsx b/apps/mobile/src/modules/Group/all/AllGroup.tsx index 833c3a0b..32a62786 100644 --- a/apps/mobile/src/modules/Group/all/AllGroup.tsx +++ b/apps/mobile/src/modules/Group/all/AllGroup.tsx @@ -1,6 +1,6 @@ import {useNavigation} from '@react-navigation/native'; import {useAuth, useGetAllGroupList, useGetGroupList} from 'afk_nostr_sdk'; -import {FlatList, SafeAreaView, Text, TouchableOpacity, View} from 'react-native'; +import {ActivityIndicator, FlatList, SafeAreaView, Text, TouchableOpacity, View} from 'react-native'; import {PadlockIcon, SlantedArrowIcon} from '../../../assets/icons'; import {useStyles} from '../../../hooks'; @@ -11,14 +11,15 @@ export default function AllGroupListComponent() { const {publicKey: pubKey} = useAuth(); const data = useGetGroupList({ - pubKey, - }); - const allGroup = useGetAllGroupList({ - pubKey, + // pubKey, }); + // const allGroup = useGetAllGroupList({ + // pubKey, + // }); - console.log(allGroup.data, 'AllGroup'); - console.log(data.data, 'AllGroup2'); + // console.log("AllGroup", allGroup.data); + console.log("AllGroup", data.data); + // console.log(data.data, 'AllGroup2'); const styles = useStyles(stylesheet); const navigation = useNavigation(); @@ -28,6 +29,8 @@ export default function AllGroupListComponent() { My Groups + + {data?.data?.pages?.length == 0 && } ( diff --git a/apps/mobile/src/modules/Group/groupDetail/GroupChatDetail.tsx b/apps/mobile/src/modules/Group/groupDetail/GroupChatDetail.tsx index c4a459ef..be83fecf 100644 --- a/apps/mobile/src/modules/Group/groupDetail/GroupChatDetail.tsx +++ b/apps/mobile/src/modules/Group/groupDetail/GroupChatDetail.tsx @@ -1,6 +1,6 @@ import {useQueryClient} from '@tanstack/react-query'; import {useAuth, useDeleteGroup, useGetGroupMemberList, useGetGroupMetadata} from 'afk_nostr_sdk'; -import React, {useRef, useState} from 'react'; +import React, {useEffect, useRef, useState} from 'react'; import {FlatList, Pressable, SafeAreaView, TouchableOpacity, View} from 'react-native'; import {AddPostIcon, BackIcon, EditIcon, TrashIcon, UserPlusIcon} from '../../../assets/icons'; @@ -32,6 +32,12 @@ const GroupChatDetail: React.FC = ({navigation, rout const styles = useStyles(stylesheet); const [selectedMember, setSelectedMember] = useState(); + /** Todo check if user is already added as a member */ + useEffect(() => { + + },[]) + + const onOpen = (selected: any) => { modalizeRef.current?.open(); setSelectedMember(selected); diff --git a/apps/mobile/src/modules/Group/message/GroupMessage.tsx b/apps/mobile/src/modules/Group/message/GroupMessage.tsx index c4556977..79edff07 100644 --- a/apps/mobile/src/modules/Group/message/GroupMessage.tsx +++ b/apps/mobile/src/modules/Group/message/GroupMessage.tsx @@ -1,41 +1,75 @@ -import {useQueryClient} from '@tanstack/react-query'; +import { useQueryClient } from '@tanstack/react-query'; import { + AdminGroupPermission, useAuth, useGetGroupMemberList, + useGetGroupMemberListPubkey, useGetGroupMessages, + useJoinGroupRequest, + useNostrContext, useProfile, useSendGroupMessages, } from 'afk_nostr_sdk'; -import React, {useState} from 'react'; -import {FlatList, Modal, Pressable, SafeAreaView, Text, TouchableOpacity, View} from 'react-native'; - -import {BackIcon, MenuIcons} from '../../../assets/icons'; -import {IconButton, Input, KeyboardFixedView} from '../../../components'; -import {useStyles} from '../../../hooks'; -import {useToast} from '../../../hooks/modals'; -import {GroupChatScreenProps} from '../../../types'; +import React, { useEffect, useState } from 'react'; +import { FlatList, Modal, Pressable, SafeAreaView, Text, TouchableOpacity, View } from 'react-native'; + +import { BackIcon, MenuIcons } from '../../../assets/icons'; +import { IconButton, Input, KeyboardFixedView } from '../../../components'; +import { useStyles } from '../../../hooks'; +import { useToast } from '../../../hooks/modals'; +import { GroupChatScreenProps } from '../../../types'; import stylesheet from './styles'; +import { checkGroupPermission } from 'afk_nostr_sdk/src/hooks/group/private/useGetPermission'; +import { NDKEvent } from '@nostr-dev-kit/ndk'; + +const GroupChat: React.FC = ({ navigation, route }) => { + const { publicKey } = useAuth(); + const ndk = useNostrContext() + const groupdId = route.params.groupId -const GroupChat: React.FC = ({navigation, route}) => { - const {publicKey} = useAuth(); - const memberListData = useGetGroupMemberList({ + const memberListData = useGetGroupMemberListPubkey({ groupId: route.params.groupId, }); - const profile = useProfile({publicKey}); + + const joinRequest = useJoinGroupRequest() + const profile = useProfile({ publicKey }); const [menuVisible, setMenuVisible] = useState(false); + const [isUserMember, setIsUserMember] = useState(false); const [replyToId, setReplyToId] = useState(null); const [replyToContent, setReplyToContent] = useState(''); const [selectedMessageId, setSelectedMessageId] = useState(null); const queryClient = useQueryClient(); - const {showToast} = useToast(); - const {data: messageData} = useGetGroupMessages({ + const { showToast } = useToast(); + const { data: messageData } = useGetGroupMessages({ groupId: route.params.groupId, authors: publicKey, }); - const {mutate} = useSendGroupMessages(); + const { mutate } = useSendGroupMessages(); const styles = useStyles(stylesheet); const [message, setMessage] = useState(''); + /** Todo check if user is a member */ + useEffect(() => { + + const getUserIsMember = () => { + let isMember = memberListData?.data?.pages?.flat().find((e: NDKEvent) => { + console.log("e", e) + const pubkey = e?.tags?.find((tag: string[]) => tag[0] === 'p')?.[1]; + console.log("pubKey", pubkey) + if (pubkey == publicKey) { + console.log("pubkey == publicKey", pubkey == publicKey) + + return e + } + return undefined; + }) + if (isMember) setIsUserMember(true) + } + + getUserIsMember() + + }, [memberListData]) + const handleLongPress = (messageId: any, messageContent: string) => { setSelectedMessageId(messageId); setReplyToContent(messageContent); @@ -62,8 +96,8 @@ const GroupChat: React.FC = ({navigation, route}) => { }, { onSuccess() { - showToast({type: 'success', title: 'Message sent successfully'}); - queryClient.invalidateQueries({queryKey: ['getGroupMessages', route.params.groupId]}); + showToast({ type: 'success', title: 'Message sent successfully' }); + queryClient.invalidateQueries({ queryKey: ['getGroupMessages', route.params.groupId] }); setMessage(''); setReplyToId(null); setReplyToContent(''); @@ -78,6 +112,23 @@ const GroupChat: React.FC = ({navigation, route}) => { ); }; + const requestToJoin = () => { + + joinRequest.mutateAsync({ + groupId: groupdId, + + + + }, + { + onSuccess: () => { + + }, + }, + ) + + }; + return ( @@ -103,17 +154,33 @@ const GroupChat: React.FC = ({navigation, route}) => { - } - keyExtractor={(item: any) => item.id} - contentContainerStyle={styles.messageList} - inverted - /> + + {isUserMember && + } + keyExtractor={(item: any) => item.id} + contentContainerStyle={styles.messageList} + inverted + /> + } + + {!isUserMember && + + + + You are not a member + Request to join the group + + requestToJoin()} icon="SendIcon" size={24} /> + + + } + {replyToId && } - + void; message: string}) => { +const ReplyIndicator = ({ message, onCancel }: { onCancel: () => void; message: string }) => { const styles = useStyles(stylesheet); return ( @@ -202,7 +269,7 @@ const LongPressMenu = ({ - Reply Message + Reply Message diff --git a/apps/mobile/src/screens/Feed/index.tsx b/apps/mobile/src/screens/Feed/index.tsx index 9f24d652..5daa572c 100644 --- a/apps/mobile/src/screens/Feed/index.tsx +++ b/apps/mobile/src/screens/Feed/index.tsx @@ -27,7 +27,7 @@ export const Feed: React.FC = ({ navigation }) => { ]); const contacts = useContacts() - console.log("contacts", contacts) + // console.log("contacts", contacts) const notes = useSearch({ // search: search, kinds, @@ -63,10 +63,11 @@ export const Feed: React.FC = ({ navigation }) => { setKinds={setKinds} setSortBy={setSortBy} sortBy={activeSortBy} - contactList={contacts?.data?.map((item) => item)} + // contactList={contacts?.data?.map((item) => item)} /> {notes?.isLoading && } + {notes?.data?.pages?.length == 0 && } diff --git a/apps/mobile/src/types/tab.ts b/apps/mobile/src/types/tab.ts index 3b88d3a8..7b70af1a 100644 --- a/apps/mobile/src/types/tab.ts +++ b/apps/mobile/src/types/tab.ts @@ -33,9 +33,9 @@ export const TABS_TIP_LIST: {screen?: string; title: string; tab: SelectedTab}[] tab: SelectedTab.TIPS, }, { - title: 'Messages', - screen: 'Messages', - tab: SelectedTab.MESSAGES, + title: 'All Group', + screen: 'AllGroup', + tab: SelectedTab.ALL_GROUP, }, { title: 'Channels', @@ -43,9 +43,9 @@ export const TABS_TIP_LIST: {screen?: string; title: string; tab: SelectedTab}[] tab: SelectedTab.CHANNELS, }, { - title: 'All Group', - screen: 'AllGroup', - tab: SelectedTab.ALL_GROUP, + title: 'Messages', + screen: 'Messages', + tab: SelectedTab.MESSAGES, }, // { // title: 'Messages', diff --git a/apps/mobile/src/utils/storage.ts b/apps/mobile/src/utils/storage.ts index 47c745f5..96f5de62 100644 --- a/apps/mobile/src/utils/storage.ts +++ b/apps/mobile/src/utils/storage.ts @@ -65,16 +65,24 @@ export const retrieveAndDecryptPrivateKey = async (password: string): Promise { if (isSecureStoreAvailable) { return SecureStore.setItemAsync('password', password, {requireAuthentication: true}); } + // else { + // return await AsyncStorage.setItem('password', password); + // } }; +/** TODO add security for password retrieve in Web view? */ export const retrievePassword = async () => { if (isSecureStoreAvailable) { return SecureStore.getItemAsync('password', {requireAuthentication: true}); } + // else { + // return await AsyncStorage.getItem('password'); + // } return null; }; diff --git a/onchain/cairo/.snfoundry_cache/.prev_tests_failed b/onchain/cairo/.snfoundry_cache/.prev_tests_failed index 70563d04..e69de29b 100644 --- a/onchain/cairo/.snfoundry_cache/.prev_tests_failed +++ b/onchain/cairo/.snfoundry_cache/.prev_tests_failed @@ -1 +0,0 @@ -afk::tests::launchpad_tests::launchpad_tests::launchpad_integration diff --git a/onchain/cairo/src/social/namespace.cairo b/onchain/cairo/src/social/namespace.cairo index 19af9787..94a70fc3 100644 --- a/onchain/cairo/src/social/namespace.cairo +++ b/onchain/cairo/src/social/namespace.cairo @@ -309,8 +309,8 @@ mod tests { tags: "[]", content: linked_wallet.clone(), sig: Signature { - r: 0x8ffbabf63d0fd526dffb8c04d04a216bb03743fae22826a2b42005d478c48360_u256, - s: 0x6aa0f5295635d03d6d3f61aaf7f4163175ed1a9001550b9da4c0a3a6098c0fab_u256, + r: 0x4e04216ca171673375916f12e1a56e00dca1d39e44207829d659d06f3a972d6f_u256, + s: 0xa16bc69fab00104564b9dad050a29af4d2380c229de984e49ad125fe29b5be8e_u256, // r: 0x051b6d408b709d29b6ef55b1aa74d31a9a265c25b0b91c2502108b67b29c0d5c_u256, // s: 0xe31f5691af0e950eb8697fdbbd464ba725b2aaf7e5885c4eaa30a1e528269793_u256 } @@ -365,7 +365,7 @@ mod tests { } #[test] - #[should_panic(expected: 'can\'t verify signature')] + #[should_panic()] fn link_incorrect_signature() { let (_, _, sender_address, namespace, fail_request_linked_wallet_to_caller) = request_fixture(); @@ -383,7 +383,7 @@ mod tests { } #[test] - #[should_panic(expected: 'can\'t verify signature')] + #[should_panic()] fn link_incorrect_signature_link_to() { let (request, _, sender_address, namespace, _) = request_fixture(); cheat_caller_address_global(sender_address); @@ -391,7 +391,7 @@ mod tests { start_cheat_caller_address(namespace.contract_address, sender_address); let request_test_failed_sig = SocialRequest { sig: Signature { - r: 0x2570a9a0c92c180bd4ac826c887e63844b043e3b65da71a857d2aa29e7cd3a4e_u256, + r: 0x2570a9a0c92c180bd4ac826c887e63844b043e3b65da71a857d2aa29e7cd3a5e_u256, s: 0x1c0c0a8b7a8330b6b8915985c9cd498a407587213c2e7608e7479b4ef966605f_u256, }, ..request, diff --git a/onchain/foundry.toml b/onchain/foundry.toml index 18434eee..5d10f4ec 100644 --- a/onchain/foundry.toml +++ b/onchain/foundry.toml @@ -3,6 +3,8 @@ src = "solidity_contracts/src" test = "solidity_contracts/test" out = "out" libs = ["solidity_contracts/lib"] +evm_version= "cancun" # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options + diff --git a/onchain/solidity_contracts/src/defi/Vault.sol b/onchain/solidity_contracts/src/defi/Vault.sol index 82940499..f7772d7e 100644 --- a/onchain/solidity_contracts/src/defi/Vault.sol +++ b/onchain/solidity_contracts/src/defi/Vault.sol @@ -57,11 +57,6 @@ contract ABTCVault is uint256 burnedAmount ); - /// @custom:oz-upgrades-unsafe-allow constructor - constructor() { - _disableInitializers(); - } - function initialize( address _admin, address _underlying @@ -81,6 +76,7 @@ contract ABTCVault is function setWrappedBTCToken( address _token, bool _isPermitted, + uint256 ratio, uint256 _poolingTimestamp ) external onlyRole(DEFAULT_ADMIN_ROLE) { wrappedBTCTokens[_token] = WrappedBTC(_isPermitted, _poolingTimestamp); diff --git a/onchain/solidity_contracts/test/Vault.t.sol b/onchain/solidity_contracts/test/Vault.t.sol index 3b172f8b..002c1adc 100644 --- a/onchain/solidity_contracts/test/Vault.t.sol +++ b/onchain/solidity_contracts/test/Vault.t.sol @@ -27,6 +27,7 @@ contract ABTCVaultTest is Test { wbtc = new MockWrappedBTC("Wrapped BTC", "WBTC"); tbtc = new MockWrappedBTC("tBTC", "TBTC"); + // vault = new ABTCVault(); vault = new ABTCVault(); vault.initialize(admin, address(wbtc)); @@ -48,7 +49,7 @@ contract ABTCVaultTest is Test { } function testSetWrappedBTCToken() public { - vault.setWrappedBTCToken(address(wbtc), true, block.timestamp); + vault.setWrappedBTCToken(address(wbtc), true, 1e18, block.timestamp); (bool isPermitted, uint256 poolingTimestamp) = vault.wrappedBTCTokens( address(wbtc) ); diff --git a/packages/afk_nostr_sdk/src/hooks/group/private/useAddMember.ts b/packages/afk_nostr_sdk/src/hooks/group/private/useAddMember.ts index eb5dbfec..a62b97f7 100644 --- a/packages/afk_nostr_sdk/src/hooks/group/private/useAddMember.ts +++ b/packages/afk_nostr_sdk/src/hooks/group/private/useAddMember.ts @@ -3,14 +3,26 @@ import {useMutation} from '@tanstack/react-query'; import {useNostrContext} from '../../../context/NostrContext'; import {useAuth} from '../../../store'; +import { checkGroupPermission } from './useGetPermission'; +import { AdminGroupPermission } from './useAddPermissions'; // TODO export const useAddMember = () => { const {ndk} = useNostrContext(); + const {publicKey} = useAuth() return useMutation({ mutationKey: ['addMemberGroup', ndk], mutationFn: async (data: {pubkey: string; groupId: string}) => { + + const hasPermission = checkGroupPermission({ + groupId: data.groupId, + ndk, + pubkey:publicKey, + action: AdminGroupPermission.DeleteEvent, + }); + + const event = new NDKEvent(ndk); event.kind = NDKKind.GroupAdminAddUser; event.tags = [ diff --git a/packages/afk_nostr_sdk/src/hooks/group/private/useGetGroupMember.ts b/packages/afk_nostr_sdk/src/hooks/group/private/useGetGroupMember.ts index 0f0664ec..194584ff 100644 --- a/packages/afk_nostr_sdk/src/hooks/group/private/useGetGroupMember.ts +++ b/packages/afk_nostr_sdk/src/hooks/group/private/useGetGroupMember.ts @@ -95,3 +95,57 @@ export const useGetGroupRequest = (options: UseGetGroupListOptions) => { placeholderData: {pages: [], pageParams: []}, }); }; + + + +export const useGetGroupMemberListPubkey = (options: UseGetGroupListOptions) => { + const {ndk} = useNostrContext(); + const {publicKey} = useAuth(); + + return useInfiniteQuery({ + queryKey: ['getAllGroupMember', publicKey, options.search, options.groupId], + initialPageParam: 0, + getNextPageParam: (lastPage, allPages, lastPageParam) => { + if (!lastPage?.length) return undefined; + const pageParam = lastPage[lastPage.length - 1].created_at - 1; + if (!pageParam || pageParam === lastPageParam) return undefined; + return pageParam; + }, + queryFn: async ({pageParam}) => { + const events = await ndk.fetchEvents({ + kinds: [NDKKind.GroupAdminAddUser, NDKKind.GroupAdminRemoveUser], + authors: [publicKey], + '#d': [options.groupId], + until: pageParam || Math.round(Date.now() / 1000), + limit: options?.limit || 20, + search: options?.search, + }); + + const memberMap = new Map(); + + [...events] + .sort((a, b) => a.created_at - b.created_at) + .forEach((event) => { + const pubkey = event.tags.find((tag) => tag[0] === 'p')?.[1]; + if (!pubkey) return; + + if (event.kind === NDKKind.GroupAdminAddUser) { + memberMap.set(pubkey, {...event, isRemoved: false}); + } else if (event.kind === NDKKind.GroupAdminRemoveUser) { + const existingMember = memberMap.get(pubkey); + if (existingMember) { + // memberMap.set(pubkey, {...existingMember, isRemoved: true}); + memberMap.delete(pubkey); + } + } + }); + + const currentMembers = Array.from(memberMap.values()) + .filter((member) => !member.isRemoved) + .sort((a, b) => b.created_at - a.created_at); + + return currentMembers; + }, + placeholderData: {pages: [], pageParams: []}, + }); +}; \ No newline at end of file diff --git a/packages/afk_nostr_sdk/src/hooks/group/private/useGetGroups.ts b/packages/afk_nostr_sdk/src/hooks/group/private/useGetGroups.ts index 6fe1ca1b..9eeafca6 100644 --- a/packages/afk_nostr_sdk/src/hooks/group/private/useGetGroups.ts +++ b/packages/afk_nostr_sdk/src/hooks/group/private/useGetGroups.ts @@ -4,7 +4,7 @@ import {useInfiniteQuery} from '@tanstack/react-query'; import {useNostrContext} from '../../../context/NostrContext'; interface UseGetActiveGroupListOptions { - pubKey: string; + pubKey?: string | undefined; search?: string; limit?: number; } @@ -37,7 +37,7 @@ export const useGetGroupList = (options: UseGetActiveGroupListOptions) => { GroupAdminDeleteGroup, NDKKind.GroupAdminEditMetadata, ], - authors: [options.pubKey], + // authors: options?.pubKey ? [options.pubKey]: [], until: pageParam || Math.round(Date.now() / 1000), }); [...events] @@ -104,3 +104,34 @@ export const useGetAllGroupList = (options: UseGetActiveGroupListOptions) => { placeholderData: {pages: [], pageParams: []}, }); }; + +/** + * This hooks returns all groups added by admin. + * @param options + * @returns + */ +export const useGetAllGroupListByMemberAdded = (options: UseGetActiveGroupListOptions) => { + const {ndk} = useNostrContext(); + + return useInfiniteQuery({ + queryKey: ['getAllGroupLists', options.pubKey, options?.search], + initialPageParam: 0, + getNextPageParam: (lastPage, allPages, lastPageParam) => { + if (!lastPage?.length) return undefined; + + const pageParam = lastPage[lastPage.length - 1].created_at - 1; + if (!pageParam || pageParam === lastPageParam) return undefined; + return pageParam; + }, + queryFn: async ({pageParam}) => { + const events = await ndk.fetchEvents({ + kinds: [NDKKind.GroupAdminAddUser], + until: pageParam || Math.round(Date.now() / 1000), + }); + + return [...events]; + }, + placeholderData: {pages: [], pageParams: []}, + }); +}; + diff --git a/packages/afk_nostr_sdk/src/hooks/group/private/useJoinRequest.ts b/packages/afk_nostr_sdk/src/hooks/group/private/useJoinRequest.ts index e069564d..7b282540 100644 --- a/packages/afk_nostr_sdk/src/hooks/group/private/useJoinRequest.ts +++ b/packages/afk_nostr_sdk/src/hooks/group/private/useJoinRequest.ts @@ -2,19 +2,21 @@ import {NDKEvent, NDKKind} from '@nostr-dev-kit/ndk'; import {useMutation} from '@tanstack/react-query'; import {useNostrContext} from '../../../context/NostrContext'; +import { useAuth } from '../../../store'; export const useJoinGroupRequest = () => { const {ndk} = useNostrContext(); + const {publicKey} = useAuth() return useMutation({ mutationKey: ['joinGroupRequest', ndk], - mutationFn: async (data: {groupId: string; content?: string; pubkey: string}) => { + mutationFn: async (data: {groupId: string; content?: string}) => { const event = new NDKEvent(ndk); event.kind = NDKKind.GroupAdminRequestJoin; event.content = data?.content || ''; event.tags = [ ['h', data.groupId], - ['p', data.pubkey], + ['p', publicKey], ]; return event.publish(); }, diff --git a/packages/afk_nostr_sdk/src/hooks/index.ts b/packages/afk_nostr_sdk/src/hooks/index.ts index 0e0618a7..215d9c8e 100644 --- a/packages/afk_nostr_sdk/src/hooks/index.ts +++ b/packages/afk_nostr_sdk/src/hooks/index.ts @@ -20,8 +20,8 @@ export {useRootNotes} from './useRootNotes'; export {useSearchNotes} from './useSearchNotes'; export {useSendNote} from './useSendNote'; export {useAddMember} from './group/private/useAddMember'; -export {useGetGroupMemberList, useGetGroupRequest} from './group/private/useGetGroupMember'; -export {useAddPermissions} from './group/private/useAddPermissions'; +export {useGetGroupMemberList, useGetGroupRequest, useGetGroupMemberListPubkey} from './group/private/useGetGroupMember'; +export {useAddPermissions, AdminGroupPermission} from './group/private/useAddPermissions'; export {useCreateGroup} from './group/private/useCreateGroup'; export {useGetGroupList, useGetAllGroupList} from './group/private/useGetGroups'; export {useDeleteEvent} from './group/private/useDeleteEvent'; diff --git a/packages/afk_nostr_sdk/src/hooks/search/useSearch.tsx b/packages/afk_nostr_sdk/src/hooks/search/useSearch.tsx index 9f92f371..ce25b714 100644 --- a/packages/afk_nostr_sdk/src/hooks/search/useSearch.tsx +++ b/packages/afk_nostr_sdk/src/hooks/search/useSearch.tsx @@ -10,6 +10,7 @@ export type UseSearch = { kind?: NDKKind; kinds?: NDKKind[]; sortBy?: string; + limit?:number; }; export const useSearch = (options?: UseSearch) => { @@ -34,7 +35,7 @@ export const useSearch = (options?: UseSearch) => { search: options?.search, // content: options?.search, until: pageParam || Math.round(Date.now() / 1000), - limit: 20, + limit: options?.limit ?? 20, }); console.log('notes', notes); diff --git a/packages/pixel_ui/src/configs/backend.config copy.json b/packages/pixel_ui/src/configs/backend.config copy.json index e9f57c37..9636245b 100644 --- a/packages/pixel_ui/src/configs/backend.config copy.json +++ b/packages/pixel_ui/src/configs/backend.config copy.json @@ -1,6 +1,7 @@ { "host": "api.art-peace.net", "port": 8080, + "consumer_port": 8081, "scripts": { "place_pixel_devnet": "../tests/integration/local/place_pixel.sh", "place_extra_pixels_devnet": "../tests/integration/local/place_extra_pixels.sh", diff --git a/packages/pixel_ui/src/configs/backend.config.json b/packages/pixel_ui/src/configs/backend.config.json index b1056020..12528cd7 100644 --- a/packages/pixel_ui/src/configs/backend.config.json +++ b/packages/pixel_ui/src/configs/backend.config.json @@ -1,8 +1,7 @@ { - "host_local": "localhost", - "host": "backend-pixel.onrender.com/", - "host_p": "localhost", + "host": "backend-pixel.onrender.com", "port": 8082, + "consumer_port": 8081, "scripts": { "place_pixel_devnet": "../tests/integration/local/place_pixel.sh", "place_extra_pixels_devnet": "../tests/integration/local/place_extra_pixels.sh", diff --git a/packages/pixel_ui/src/configs/backend.dev.config.json b/packages/pixel_ui/src/configs/backend.dev.config.json new file mode 100644 index 00000000..9b82be15 --- /dev/null +++ b/packages/pixel_ui/src/configs/backend.dev.config.json @@ -0,0 +1,16 @@ +{ + "host": "localhost", + "port": 8082, + "consumer_port": 8081, + "scripts": { + "place_pixel_devnet": "../tests/integration/local/place_pixel.sh", + "place_extra_pixels_devnet": "../tests/integration/local/place_extra_pixels.sh", + "add_template_devnet": "../tests/integration/local/add_template.sh", + "mint_nft_devnet": "../tests/integration/local/mint_nft.sh" + }, + "production": false, + "websocket": { + "read_buffer_size": 1024, + "write_buffer_size": 1024 + } +} diff --git a/packages/pixel_ui/src/services/apiService.js b/packages/pixel_ui/src/services/apiService.js index 50bd4bf6..784d112a 100644 --- a/packages/pixel_ui/src/services/apiService.js +++ b/packages/pixel_ui/src/services/apiService.js @@ -4,6 +4,7 @@ export const fetchWrapper = async (url, options = {}) => { const controller = new AbortController(); const signal = controller.signal; try { + console.log("backendUrl",backendUrl) const response = await fetch(`${backendUrl}/${url}`, { mode: 'cors', signal, diff --git a/packages/pixel_ui/src/utils/Consts.js b/packages/pixel_ui/src/utils/Consts.js index ded5b5b0..64ed13f1 100644 --- a/packages/pixel_ui/src/utils/Consts.js +++ b/packages/pixel_ui/src/utils/Consts.js @@ -1,10 +1,15 @@ -import backendConfig from '../configs/backend.config.json'; - +import backendConfigProd from '../configs/backend.config.json'; +import backendConfigDev from '../configs/backend.dev.config.json'; +const isProduction = process.env.REACT_APP_NODE_ENV == "true" ? true : false /** TODO add ENV and config for prod and test */ /** TODO fix url */ + +// const backendConfig = isProduction ? backendConfigProd : backendConfigDev +const backendConfig = backendConfigProd +// const backendConfig = backendConfigDev + // TODO used REACT_APP_NODE_ENV -// const isProduction = process.env.REACT_APP_NODE_ENV == "true" ? true : false -const isProduction = true +// const isProduction = true // export const backendUrl = 'https://' + backendConfig.host; console.log("isProduction", isProduction) console.log("REACT_APP_BACKEND_URL", process.env.REACT_APP_BACKEND_URL) diff --git a/turbo.json b/turbo.json index 67c35c5a..db4793e3 100644 --- a/turbo.json +++ b/turbo.json @@ -63,8 +63,8 @@ "APP_URL", "NEXT_PUBLIC_WALLET_CONNECT_ID", "EXPO_PUBLIC_PIXEL_URL", - "REACT_APP_BACKEND_URL", - "REACT_APP_NODE_ENV" + "REACT_APP_BACKEND_URL", + "REACT_APP_NODE_ENV" ] }, "deploy": {