Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/common-parks-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@graphprotocol/hypergraph": patch
"@graphprotocol/hypergraph-react": patch
---

Add configurable API origin support

- Add `Config.setApiOrigin()` and `Config.getApiOrigin()` functions to allow setting a custom API origin globally
- Add `apiOrigin` prop to `HypergraphAppProvider` for React apps
- Replace all hardcoded `Graph.TESTNET_API_ORIGIN` references with configurable `Config.getApiOrigin()`
- Default behavior remains unchanged (uses testnet) if not configured
9 changes: 9 additions & 0 deletions packages/hypergraph-react/src/HypergraphAppContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Repo } from '@automerge/automerge-repo/slim';
import { RepoContext } from '@automerge/automerge-repo-react-hooks';
import { Graph } from '@graphprotocol/grc-20';
import {
Config,
Connect,
type ConnectCallbackResult,
Identity,
Expand Down Expand Up @@ -232,6 +233,7 @@ export type HypergraphAppProviderProps = Readonly<{
children: ReactNode;
appId: string;
logInvalidResults?: boolean;
apiOrigin?: string;
}>;

const mockStorage = {
Expand All @@ -249,6 +251,7 @@ export function HypergraphAppProvider({
appId,
children,
logInvalidResults = true,
apiOrigin,
}: HypergraphAppProviderProps) {
const [websocketConnection, setWebsocketConnection] = useState<WebSocket>();
const [isConnecting, setIsConnecting] = useState(true);
Expand All @@ -259,6 +262,12 @@ export function HypergraphAppProvider({
const identity = useSelectorStore(store, (state) => state.context.identity);
const privyIdentity = useSelectorStore(store, (state) => state.context.privyIdentity);

useEffect(() => {
if (apiOrigin) {
Config.setApiOrigin(apiOrigin);
}
}, [apiOrigin]);

const logout = useCallback(() => {
websocketConnection?.close();
setWebsocketConnection(undefined);
Expand Down
8 changes: 2 additions & 6 deletions packages/hypergraph-react/src/hooks/use-spaces.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Graph } from '@graphprotocol/grc-20';
import { store } from '@graphprotocol/hypergraph';
import { Config, store } from '@graphprotocol/hypergraph';
import { useQuery } from '@tanstack/react-query';
import { useSelector } from '@xstate/store/react';
import { gql, request } from 'graphql-request';
Expand All @@ -10,7 +9,6 @@ const publicSpacesQueryDocument = gql`
query Spaces($accountAddress: String!) {
spaces(filter: {members: {some: {address: {is: $accountAddress}}}}) {
id
spaceAddress
page {
name
}
Expand All @@ -21,7 +19,6 @@ query Spaces($accountAddress: String!) {
type PublicSpacesQueryResult = {
spaces: {
id: string;
spaceAddress: string;
page: {
name: string;
} | null;
Expand All @@ -38,7 +35,7 @@ export const useSpaces = (params: { mode: 'public' | 'private' }) => {
queryKey: ['hypergraph-public-spaces', params.mode],
queryFn: async () => {
const result = await request<PublicSpacesQueryResult>(
`${Graph.TESTNET_API_ORIGIN}/v2/graphql`,
`${Config.getApiOrigin()}/v2/graphql`,
publicSpacesQueryDocument,
{
accountAddress,
Expand All @@ -48,7 +45,6 @@ export const useSpaces = (params: { mode: 'public' | 'private' }) => {
? result.spaces.map((space) => ({
id: space.id,
name: space.page?.name,
spaceAddress: space.spaceAddress,
}))
: [];
},
Expand Down
13 changes: 5 additions & 8 deletions packages/hypergraph-react/src/internal/generate-delete-ops.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Graph, type Op } from '@graphprotocol/grc-20';
import type { Op } from '@graphprotocol/grc-20';
import { Config } from '@graphprotocol/hypergraph';
import { gql, request } from 'graphql-request';

const deleteEntityQueryDocument = gql`
Expand Down Expand Up @@ -44,13 +45,9 @@ type DeleteEntityResult = {
};

export const generateDeleteOps = async ({ id }: { id: string; space: string }) => {
const result = await request<DeleteEntityResult>(
`${Graph.TESTNET_API_ORIGIN}/v2/graphql`,
deleteEntityQueryDocument,
{
entityId: id,
},
);
const result = await request<DeleteEntityResult>(`${Config.getApiOrigin()}/v2/graphql`, deleteEntityQueryDocument, {
entityId: id,
});
if (result.entity === null) {
throw new Error('Entity not found');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Graph, type Op } from '@graphprotocol/grc-20';
import type { Connect } from '@graphprotocol/hypergraph';
import { Constants } from '@graphprotocol/hypergraph';
import { Config, Constants } from '@graphprotocol/hypergraph';
import { useQueryClient } from '@tanstack/react-query';
import * as Option from 'effect/Option';
import type * as Schema from 'effect/Schema';
Expand Down Expand Up @@ -45,7 +45,7 @@ export const useDeleteEntityPublic = <S extends Schema.Schema.AnyNoContext>(
return async ({ id, walletClient }: { id: string; walletClient: Connect.SmartSessionClient }) => {
try {
const result = await request<EntityToDeleteQueryResult>(
`${Graph.TESTNET_API_ORIGIN}/v2/graphql`,
`${Config.getApiOrigin()}/v2/graphql`,
deleteEntityQueryDocument,
{
spaceId: space,
Expand Down
4 changes: 2 additions & 2 deletions packages/hypergraph-react/src/internal/use-public-space.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Graph } from '@graphprotocol/grc-20';
import { Config } from '@graphprotocol/hypergraph';
import { useQuery } from '@tanstack/react-query';
import { gql, request } from 'graphql-request';

Expand All @@ -24,7 +24,7 @@ export const usePublicSpace = ({ spaceId, enabled }: { spaceId: string; enabled:
const result = useQuery({
queryKey: ['hypergraph-public-space', spaceId],
queryFn: async () => {
const result = await request<SpaceQueryResult>(`${Graph.TESTNET_API_ORIGIN}/v2/graphql`, spaceQueryDocument, {
const result = await request<SpaceQueryResult>(`${Config.getApiOrigin()}/v2/graphql`, spaceQueryDocument, {
spaceId,
});
return result?.space?.page
Expand Down
4 changes: 2 additions & 2 deletions packages/hypergraph-react/src/prepare-publish.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Graph, type Id, type Op, type PropertiesParam, type RelationsParam } from '@graphprotocol/grc-20';
import { Constants, type Entity, Utils } from '@graphprotocol/hypergraph';
import { Config, Constants, type Entity, Utils } from '@graphprotocol/hypergraph';
import * as Option from 'effect/Option';
import type * as Schema from 'effect/Schema';
import * as SchemaAST from 'effect/SchemaAST';
Expand Down Expand Up @@ -49,7 +49,7 @@ export const preparePublish = async <S extends Schema.Schema.AnyNoContext>({
publicSpace,
}: PreparePublishParams<S>) => {
const data = await request<EntityToPublishQueryResult>(
`${Graph.TESTNET_API_ORIGIN}/v2/graphql`,
`${Config.getApiOrigin()}/v2/graphql`,
entityToPublishQueryDocument,
{
entityId: entity.id,
Expand Down
6 changes: 3 additions & 3 deletions packages/hypergraph-react/src/publish-ops.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Op } from '@graphprotocol/grc-20';
import { Graph, Ipfs } from '@graphprotocol/grc-20';
import { Connect } from '@graphprotocol/hypergraph';
import { Ipfs } from '@graphprotocol/grc-20';
import { Config, Connect } from '@graphprotocol/hypergraph';
import type { Hash } from 'viem';

type PublishParams = {
Expand Down Expand Up @@ -34,7 +34,7 @@ export const publishOps = async ({ name, ops, walletClient, space }: PublishPara
const cid = publishResult.cid;

// This returns the correct contract address and calldata depending on the space id
const result = await fetch(`${Graph.TESTNET_API_ORIGIN}/space/${space}/edit/calldata`, {
const result = await fetch(`${Config.getApiOrigin()}/space/${space}/edit/calldata`, {
method: 'POST',
body: JSON.stringify({ cid }),
});
Expand Down
4 changes: 2 additions & 2 deletions packages/hypergraph-react/test/prepare-publish.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Repo } from '@automerge/automerge-repo';
import { Graph, Id } from '@graphprotocol/grc-20';
import { Entity, store, Type } from '@graphprotocol/hypergraph';
import { Config, Entity, store, Type } from '@graphprotocol/hypergraph';
import '@testing-library/jest-dom/vitest';
import request from 'graphql-request';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
Expand Down Expand Up @@ -133,7 +133,7 @@ describe('preparePublish', () => {

const result = await preparePublish(params);

expect(mockRequest).toHaveBeenCalledWith(`${Graph.TESTNET_API_ORIGIN}/v2/graphql`, expect.any(String), {
expect(mockRequest).toHaveBeenCalledWith(`${Config.getApiOrigin()}/v2/graphql`, expect.any(String), {
entityId: entity.id,
spaceId: publicSpaceId,
});
Expand Down
23 changes: 23 additions & 0 deletions packages/hypergraph/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Graph } from '@graphprotocol/grc-20';

let apiOrigin: string | null = null;

/**
* Sets the API origin globally for all hypergraph API calls.
* @param origin - The API origin URL (e.g., "https://api.mainnet.graphprotocol.io")
*/
export const setApiOrigin = (origin: string) => {
apiOrigin = origin;
};

/**
* Gets the configured API origin, or defaults to Graph.TESTNET_API_ORIGIN if not set.
* @returns The API origin URL
*/
export const getApiOrigin = (): string => {
if (apiOrigin) {
return apiOrigin;
}
// Default to testnet
return Graph.TESTNET_API_ORIGIN;
};
9 changes: 2 additions & 7 deletions packages/hypergraph/src/entity/find-many-public.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Graph } from '@graphprotocol/grc-20';
import { Constants, type Entity, Utils } from '@graphprotocol/hypergraph';
import { Config, Constants, type Entity, Utils } from '@graphprotocol/hypergraph';
import * as Either from 'effect/Either';
import * as Option from 'effect/Option';
import type * as ParseResult from 'effect/ParseResult';
Expand Down Expand Up @@ -296,11 +295,7 @@ export const findManyPublic = async <
queryVariables.sortDirection = sortDirection;
}

const result = await request<EntityQueryResult>(
`${Graph.TESTNET_API_ORIGIN}/v2/graphql`,
queryDocument,
queryVariables,
);
const result = await request<EntityQueryResult>(`${Config.getApiOrigin()}/v2/graphql`, queryDocument, queryVariables);

const { data, invalidEntities, invalidRelationEntities } = parseResult<S, IncludeSpaceIds>(
result,
Expand Down
5 changes: 2 additions & 3 deletions packages/hypergraph/src/entity/find-one-public.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Graph } from '@graphprotocol/grc-20';
import { Constants, type Entity, Utils } from '@graphprotocol/hypergraph';
import { Config, Constants, type Entity, Utils } from '@graphprotocol/hypergraph';
import * as Either from 'effect/Either';
import * as Option from 'effect/Option';
import type * as ParseResult from 'effect/ParseResult';
Expand Down Expand Up @@ -165,7 +164,7 @@ export const findOnePublic = async <

const queryDocument = buildEntityQuery(relationTypeIds, includeSpaceIds);

const result = await request<EntityQueryResult>(`${Graph.TESTNET_API_ORIGIN}/v2/graphql`, queryDocument, {
const result = await request<EntityQueryResult>(`${Config.getApiOrigin()}/v2/graphql`, queryDocument, {
id,
spaceId: space,
});
Expand Down
5 changes: 2 additions & 3 deletions packages/hypergraph/src/entity/search-many-public.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Graph } from '@graphprotocol/grc-20';
import { Constants, type Entity, Utils } from '@graphprotocol/hypergraph';
import { Config, Constants, type Entity, Utils } from '@graphprotocol/hypergraph';
import * as Option from 'effect/Option';
import type * as Schema from 'effect/Schema';
import * as SchemaAST from 'effect/SchemaAST';
Expand Down Expand Up @@ -82,7 +81,7 @@ export const searchManyPublic = async <

const filterParams = filter ? Utils.translateFilterToGraphql(filter, type) : {};

const result = await request<EntityQueryResult>(`${Graph.TESTNET_API_ORIGIN}/v2/graphql`, queryDocument, {
const result = await request<EntityQueryResult>(`${Config.getApiOrigin()}/v2/graphql`, queryDocument, {
spaceId: space,
typeIds,
query,
Expand Down
1 change: 1 addition & 0 deletions packages/hypergraph/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export { Id } from '@graphprotocol/grc-20';
export * as Typesync from './cli/services/Model.js';
export * as Config from './config.js';
export * as Connect from './connect/index.js';
export * as Constants from './constants.js';
export * as Entity from './entity/index.js';
Expand Down
5 changes: 3 additions & 2 deletions packages/hypergraph/src/space/find-many-public.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ContentIds, Graph, SystemIds } from '@graphprotocol/grc-20';
import { ContentIds, SystemIds } from '@graphprotocol/grc-20';
import { Config } from '@graphprotocol/hypergraph';
import * as Either from 'effect/Either';
import * as EffectSchema from 'effect/Schema';
import { request } from 'graphql-request';
Expand Down Expand Up @@ -131,7 +132,7 @@ export const findManyPublic = async (params?: FindManyPublicParams) => {
throw new Error('Provide only one of memberAccountAddress or editorAccountAddress when calling findManyPublic().');
}

const endpoint = `${Graph.TESTNET_API_ORIGIN}/v2/graphql`;
const endpoint = `${Config.getApiOrigin()}/v2/graphql`;

if (memberAccountAddress) {
const queryResult = await request<SpacesQueryResult, SpacesQueryVariables>(endpoint, memberSpacesQueryDocument, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ type SchemaSpaceSelectProps = {
| {
id: string;
name: string | undefined;
spaceAddress: string;
},
): void;
};
Expand Down
Loading