Skip to content

Commit 35aaab2

Browse files
authored
add public delete (#239)
1 parent 8fe6d9a commit 35aaab2

File tree

4 files changed

+120
-9
lines changed

4 files changed

+120
-9
lines changed
Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,55 @@
1-
import { useQuery } from '@graphprotocol/hypergraph-react';
1+
import { getSmartAccountWalletClient } from '@/lib/smart-account';
2+
import { _useDeleteEntityPublic, useQuery } from '@graphprotocol/hypergraph-react';
3+
import { useState } from 'react';
24
import { Event } from '../schema';
5+
import { Button } from './ui/button';
36

47
export const Playground = () => {
5-
const {
6-
data: entityData,
7-
isLoading,
8-
isError,
9-
} = useQuery(Event, {
8+
const { data, isLoading, isError } = useQuery(Event, {
109
mode: 'public',
1110
include: {
1211
sponsors: {
1312
jobOffers: {},
1413
},
1514
},
1615
});
16+
const [isDeleting, setIsDeleting] = useState(false);
1717

18-
console.log({ isLoading, isError, entityData });
18+
const deleteEntity = _useDeleteEntityPublic(Event, {
19+
space: '1c954768-7e14-4f0f-9396-0fe9dcd55fe8',
20+
});
21+
22+
console.log({ isLoading, isError, data });
1923

2024
return (
2125
<div>
2226
{isLoading && <div>Loading...</div>}
2327
{isError && <div>Error</div>}
24-
<pre className="text-xs">{JSON.stringify(entityData, null, 2)}</pre>
28+
{data?.map((event) => (
29+
<div key={event.id}>
30+
<h2>{event.name}</h2>
31+
<Button
32+
onClick={async () => {
33+
setIsDeleting(true);
34+
const walletClient = await getSmartAccountWalletClient();
35+
if (!walletClient) {
36+
alert('Wallet client not found');
37+
return;
38+
}
39+
await deleteEntity({
40+
id: event.id,
41+
// @ts-expect-error - TODO: fix the types error
42+
walletClient,
43+
});
44+
setIsDeleting(false);
45+
}}
46+
disabled={isDeleting}
47+
>
48+
{isDeleting ? 'Deleting...' : 'Delete'}
49+
</Button>
50+
<pre className="text-xs">{JSON.stringify(event, null, 2)}</pre>
51+
</div>
52+
))}
2553
</div>
2654
);
2755
};

apps/events/src/lib/smart-account.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export const getSmartAccountWalletClient = async () => {
88
// return await grc20getSmartAccountWalletClient({
99
// privateKey,
1010
// });
11-
console.log('privateKey', privateKey);
1211
return await getWalletClient({
1312
privateKey,
1413
});

packages/hypergraph-react/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export {
2323
useUpdateEntity,
2424
} from './HypergraphSpaceContext.js';
2525
export { generateDeleteOps as _generateDeleteOps } from './internal/generate-delete-ops.js';
26+
export { useDeleteEntityPublic as _useDeleteEntityPublic } from './internal/use-delete-entity-public.js';
2627
export { useGenerateCreateOps as _useGenerateCreateOps } from './internal/use-generate-create-ops.js';
2728
export { useQueryPublic as _useQueryPublic } from './internal/use-query-public.js';
2829
export { publishOps } from './publish-ops.js';
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { type GeoSmartAccount, Graph, type Op } from '@graphprotocol/grc-20';
2+
import type { Entity } from '@graphprotocol/hypergraph';
3+
import { useQueryClient } from '@tanstack/react-query';
4+
import request, { gql } from 'graphql-request';
5+
import { publishOps } from '../publish-ops.js';
6+
import { GEO_API_TESTNET_ENDPOINT } from './constants.js';
7+
8+
type DeleteEntityPublicParams = {
9+
space: string;
10+
};
11+
12+
const deleteEntityQueryDocument = gql`
13+
query entityToDelete($entityId: String!, $spaceId: String!) {
14+
entity(id: $entityId, spaceId: $spaceId) {
15+
values {
16+
propertyId
17+
}
18+
relations {
19+
id
20+
}
21+
}
22+
}
23+
`;
24+
25+
type EntityToDeleteQueryResult = {
26+
entity: {
27+
values: {
28+
propertyId: string;
29+
}[];
30+
relations: {
31+
id: string;
32+
}[];
33+
};
34+
} | null;
35+
36+
export const useDeleteEntityPublic = <S extends Entity.AnyNoContext>(type: S, { space }: DeleteEntityPublicParams) => {
37+
const queryClient = useQueryClient();
38+
39+
return async ({ id, walletClient }: { id: string; walletClient: GeoSmartAccount }) => {
40+
try {
41+
const result = await request<EntityToDeleteQueryResult>(GEO_API_TESTNET_ENDPOINT, deleteEntityQueryDocument, {
42+
spaceId: space,
43+
entityId: id,
44+
});
45+
if (!result) {
46+
return { success: false, error: 'Entity not found' };
47+
}
48+
const { values, relations } = result.entity;
49+
const ops: Op[] = [];
50+
const { ops: unsetEntityValuesOps } = Graph.unsetEntityValues({
51+
id,
52+
properties: values.map(({ propertyId }) => propertyId),
53+
});
54+
ops.push(...unsetEntityValuesOps);
55+
for (const relation of relations) {
56+
const { ops: deleteRelationOps } = Graph.deleteRelation({ id: relation.id });
57+
ops.push(...deleteRelationOps);
58+
}
59+
60+
const { cid, txResult } = await publishOps({
61+
ops,
62+
space,
63+
name: `Delete entity ${id}`,
64+
walletClient,
65+
network: 'TESTNET',
66+
});
67+
// TODO: temporary fix until we get the information from the API when a transaction is confirmed
68+
await new Promise((resolve) => setTimeout(resolve, 2000));
69+
queryClient.invalidateQueries({
70+
queryKey: [
71+
'hypergraph-public-entities',
72+
// @ts-expect-error - TODO: find a better way to access the type.name
73+
type.name,
74+
space,
75+
],
76+
});
77+
78+
return { success: true, cid, txResult };
79+
} catch (error) {
80+
return { success: false, error: 'Failed to delete entity' };
81+
}
82+
};
83+
};

0 commit comments

Comments
 (0)