From c0c3db59dd3f431ff75af74458385ab769fd92ae Mon Sep 17 00:00:00 2001 From: raschel <38816784+aymericdelab@users.noreply.github.com> Date: Sun, 22 Dec 2024 17:45:33 +0100 Subject: [PATCH 1/2] fix realms limit (#2583) (#2584) * fix weight config * fix realms limit * add structures to bridge * feedback --- landing/src/components/modules/bridge-in.tsx | 61 +++++--------- .../components/modules/bridge-out-step-1.tsx | 58 +++++--------- .../components/modules/bridge-out-step-2.tsx | 20 ++--- .../src/dojo/modelManager/ConfigManager.ts | 11 +-- landing/src/hooks/gql/gql.ts | 61 +++++++++----- landing/src/hooks/gql/graphql.ts | 2 +- landing/src/hooks/helpers/use-sync-entity.tsx | 39 --------- landing/src/hooks/helpers/useEntities.tsx | 79 ++++++++++++------- landing/src/hooks/query/entities.tsx | 2 +- 9 files changed, 144 insertions(+), 189 deletions(-) delete mode 100644 landing/src/hooks/helpers/use-sync-entity.tsx diff --git a/landing/src/components/modules/bridge-in.tsx b/landing/src/components/modules/bridge-in.tsx index c2c4d2373..851a1e0fe 100644 --- a/landing/src/components/modules/bridge-in.tsx +++ b/landing/src/components/modules/bridge-in.tsx @@ -1,7 +1,6 @@ import { configManager } from "@/dojo/setup"; import { execute } from "@/hooks/gql/execute"; import { useEntities } from "@/hooks/helpers/useEntities"; -import { useRealm } from "@/hooks/helpers/useRealms"; import { useResourceBalance } from "@/hooks/helpers/useResources"; import { GET_CAPACITY_SPEED_CONFIG } from "@/hooks/query/capacityConfig"; import { useLords } from "@/hooks/use-lords"; @@ -25,30 +24,24 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/ import { calculateDonkeysNeeded, getSeasonAddresses, getTotalResourceWeight } from "../ui/utils/utils"; import { BridgeFees } from "./bridge-fees"; -interface S0EternumRealm { - __typename: "s0_eternum_Realm"; - realm_id: number; -} - -function isS0EternumRealm(model: any): model is S0EternumRealm { - return model?.__typename === "s0_eternum_Realm"; -} - export const BridgeIn = () => { const { address } = useAccount(); const [realmEntityId, setRealmEntityId] = useState(); - const { getBalance, isLoading: isResourcesLoading } = useResourceBalance({entityId: realmEntityId}); + const { getBalance, isLoading: isResourcesLoading } = useResourceBalance({ entityId: realmEntityId }); const { data } = useQuery({ queryKey: ["capacitySpeedConfig"], - queryFn: () => execute(GET_CAPACITY_SPEED_CONFIG, { category: "Donkey", entityType: DONKEY_ENTITY_TYPE }), + queryFn: () => execute(GET_CAPACITY_SPEED_CONFIG, { category: "Donkey", entityType: DONKEY_ENTITY_TYPE }), refetchInterval: 10_000, }); - const donkeyConfig = useMemo(() => ({ - capacity: Number(data?.s0EternumCapacityConfigModels?.edges?.[0]?.node?.weight_gram ?? 0), - speed: data?.s0EternumSpeedConfigModels?.edges?.[0]?.node?.sec_per_km ?? 0 - }), [data]); + const donkeyConfig = useMemo( + () => ({ + capacity: Number(data?.s0EternumCapacityConfigModels?.edges?.[0]?.node?.weight_gram ?? 0), + speed: data?.s0EternumSpeedConfigModels?.edges?.[0]?.node?.sec_per_km ?? 0, + }), + [data], + ); const [resourceFees, setResourceFees] = useState< { @@ -66,7 +59,6 @@ export const BridgeIn = () => { configManager.getSpeedConfig(DONKEY_ENTITY_TYPE), true, ); - const { getRealmNameById } = useRealm(); const [isLoading, setIsLoading] = useState(false); const [selectedResourceIds, setSelectedResourceIds] = useState([ResourcesIds.Lords]); const [selectedResourceAmounts, setSelectedResourceAmounts] = useState<{ [key: string]: number }>({ @@ -85,26 +77,11 @@ export const BridgeIn = () => { }); }; - const { data: playerRealms } = useEntities(); - const playerRealmsIdAndName = useMemo(() => { - return playerRealms?.s0EternumOwnerModels?.edges?.map((realm) => { - const realmModel = realm?.node?.entity?.models?.find(isS0EternumRealm); - return { - realmId: realmModel?.realm_id, - entityId: realm?.node?.entity_id, - name: getRealmNameById(realmModel?.realm_id ?? 0), - }; - }); - }, [playerRealms, getRealmNameById]); + const { playerStructures } = useEntities(); const travelTime = useMemo(() => { if (realmEntityId) { - return computeTravelTime( - Number(ADMIN_BANK_ENTITY_ID), - Number(realmEntityId!), - donkeyConfig.speed, - true, - ); + return computeTravelTime(Number(ADMIN_BANK_ENTITY_ID), Number(realmEntityId!), donkeyConfig.speed, true); } else { return 0; } @@ -139,7 +116,7 @@ export const BridgeIn = () => { } }, [orderWeight, donkeyConfig.capacity]); - const donkeyBalance = getBalance(ResourcesIds.Donkey) + const donkeyBalance = getBalance(ResourcesIds.Donkey); const { bridgeIntoRealm } = useBridgeAsset(); useEffect(() => { @@ -261,21 +238,21 @@ export const BridgeIn = () => { } > {address ? ( - + ) : (
-- Connect your wallet --
)} - {playerRealmsIdAndName?.length - ? playerRealmsIdAndName.map((realm) => { + {playerStructures?.length + ? playerStructures.map((structure) => { return ( - - #{realm.realmId} - {realm.name} + + #{structure.realmId} - {structure.name} ); }) - : "No Realms settled in Eternum"} + : "No Structure settled in Eternum"} @@ -399,7 +376,7 @@ const ResourceInputRow = ({ const { data: balance } = useBalance({ token: resourceAddress as `0x${string}`, address: address }); const { lordsBalance } = useLords({ disabled: id !== ResourcesIds.Lords }); - const { data, getBalance } = useResourceBalance({entityId: realmEntityId}); + const { data, getBalance } = useResourceBalance({ entityId: realmEntityId }); const fetchedBalance = id !== ResourcesIds.Lords diff --git a/landing/src/components/modules/bridge-out-step-1.tsx b/landing/src/components/modules/bridge-out-step-1.tsx index c8c178680..a8dd204de 100644 --- a/landing/src/components/modules/bridge-out-step-1.tsx +++ b/landing/src/components/modules/bridge-out-step-1.tsx @@ -1,7 +1,6 @@ import { configManager } from "@/dojo/setup"; import { execute } from "@/hooks/gql/execute"; import { useEntities } from "@/hooks/helpers/useEntities"; -import { useRealm } from "@/hooks/helpers/useRealms"; import { useResourceBalance } from "@/hooks/helpers/useResources"; import { GET_CAPACITY_SPEED_CONFIG } from "@/hooks/query/capacityConfig"; import { useBridgeAsset } from "@/hooks/useBridge"; @@ -33,35 +32,30 @@ import { } from "../ui/utils/utils"; import { BridgeFees } from "./bridge-fees"; -interface S0EternumRealm { - __typename: "s0_eternum_Realm"; - realm_id: number; -} - -function isS0EternumRealm(model: any): model is S0EternumRealm { - return model?.__typename === "s0_eternum_Realm"; -} export const BridgeOutStep1 = () => { const { address } = useAccount(); const [realmEntityId, setRealmEntityId] = useState(""); - const { getRealmNameById } = useRealm(); const { computeTravelTime } = useTravel( Number(ADMIN_BANK_ENTITY_ID), Number(realmEntityId!), configManager.getSpeedConfig(DONKEY_ENTITY_TYPE), true, - ); const [isFeesOpen, setIsFeesOpen] = useState(false); + ); + const [isFeesOpen, setIsFeesOpen] = useState(false); const { data } = useQuery({ queryKey: ["capacitySpeedConfig"], - queryFn: () => execute(GET_CAPACITY_SPEED_CONFIG, { category: "Donkey", entityType: DONKEY_ENTITY_TYPE }), + queryFn: () => execute(GET_CAPACITY_SPEED_CONFIG, { category: "Donkey", entityType: DONKEY_ENTITY_TYPE }), refetchInterval: 10_000, }); - const donkeyConfig = useMemo(() => ({ - capacity: Number(data?.s0EternumCapacityConfigModels?.edges?.[0]?.node?.weight_gram ?? 0), - speed: data?.s0EternumSpeedConfigModels?.edges?.[0]?.node?.sec_per_km ?? 0 - }), [data]); + const donkeyConfig = useMemo( + () => ({ + capacity: Number(data?.s0EternumCapacityConfigModels?.edges?.[0]?.node?.weight_gram ?? 0), + speed: data?.s0EternumSpeedConfigModels?.edges?.[0]?.node?.sec_per_km ?? 0, + }), + [data], + ); const [isLoading, setIsLoading] = useState(false); const { bridgeStartWithdrawFromRealm } = useBridgeAsset(); @@ -84,7 +78,7 @@ export const BridgeOutStep1 = () => { }[] >([]); - const { getBalance } = useResourceBalance({entityId: Number(realmEntityId)}); + const { getBalance } = useResourceBalance({ entityId: Number(realmEntityId) }); const donkeyBalance = useMemo(() => { if (realmEntityId) { return getBalance(ResourcesIds.Donkey); @@ -93,26 +87,11 @@ export const BridgeOutStep1 = () => { } }, [getBalance, realmEntityId]); - const { data: playerRealms } = useEntities(); - const playerRealmsIdAndName = useMemo(() => { - return playerRealms?.s0EternumOwnerModels?.edges?.map((realm) => { - const realmModel = realm?.node?.entity?.models?.find(isS0EternumRealm); - return { - realmId: realmModel?.realm_id, - entityId: realm?.node?.entity_id, - name: getRealmNameById(realmModel?.realm_id ?? 0), - }; - }); - }, [playerRealms, getRealmNameById]); + const { playerStructures } = useEntities(); const travelTime = useMemo(() => { if (realmEntityId) { - return computeTravelTime( - Number(ADMIN_BANK_ENTITY_ID), - Number(realmEntityId!), - donkeyConfig.speed, - false, - ); + return computeTravelTime(Number(ADMIN_BANK_ENTITY_ID), Number(realmEntityId!), donkeyConfig.speed, false); } else { return 0; } @@ -247,13 +226,13 @@ export const BridgeOutStep1 = () => { : "border-gold/40") } > - {address ? :
-- Connect your wallet --
} + {address ? :
-- Connect your wallet --
} - {playerRealmsIdAndName?.map((realm) => { + {playerStructures?.map((structure) => { return ( - - #{realm.realmId} - {realm.name} + + #{structure.realmId} - {structure.name} ); })} @@ -295,8 +274,7 @@ export const BridgeOutStep1 = () => {
- {donkeysNeeded} / {divideByPrecision(donkeyBalance)}{" "} - + {donkeysNeeded} / {divideByPrecision(donkeyBalance)}
{ const { address } = useAccount(); - const dojo = useDojo(); + const { playerStructures } = useEntities(); - const { data: playerRealms } = useEntities(); - const realmEntityIds = useMemo(() => { - return playerRealms?.s0EternumOwnerModels?.edges?.map((realm) => realm?.node?.entity_id) ?? []; - }, [playerRealms]); - - const { donkeyInfos } = useDonkeyArrivals(realmEntityIds); + const { donkeyInfos } = useDonkeyArrivals(playerStructures.map((structure) => structure.entityId)); const [isLoading, setIsLoading] = useState(false); const [isRefreshing, setIsRefreshing] = useState(false); @@ -46,7 +40,6 @@ export const BridgeOutStep2 = () => { }[] >([]); - const [refreshTrigger, setRefreshTrigger] = useState(0); /*const donkeysArrivals = useMemo(() => { if (bankPosition) { @@ -63,8 +56,6 @@ export const BridgeOutStep2 = () => { //useSyncEntity(donkeyArrivalsEntityIds); - - const { bridgeFinishWithdrawFromRealm } = useBridgeAsset(); const onFinishWithdrawFromBank = async () => { @@ -97,7 +88,8 @@ export const BridgeOutStep2 = () => { const updateResourcesFromSelectedDonkeys = (selectedDonkeyIds: Set) => { const allResources = Array.from(selectedDonkeyIds).flatMap( - (id) => donkeyInfos?.find((d) => d?.donkeyEntityId && BigInt(d.donkeyEntityId) === id)?.donkeyResourceBalances || [], + (id) => + donkeyInfos?.find((d) => d?.donkeyEntityId && BigInt(d.donkeyEntityId) === id)?.donkeyResourceBalances || [], ); setSelectedResourceIds(allResources.map((r) => r.resourceId as never)); @@ -250,7 +242,7 @@ export const BridgeOutStep2 = () => { className={`${ selectedDonkeys.has(BigInt(donkey?.donkeyEntityId || 0)) ? "bg-gold/10" : "" } hover:bg-gold/5 ${!isArrived ? "opacity-60" : "cursor-pointer"}`} - onClick={(e) => { + onClick={(e) => { if (!isArrived) return; const newSelected = new Set(selectedDonkeys); diff --git a/landing/src/dojo/modelManager/ConfigManager.ts b/landing/src/dojo/modelManager/ConfigManager.ts index 9b3eaafc3..f71880dc9 100644 --- a/landing/src/dojo/modelManager/ConfigManager.ts +++ b/landing/src/dojo/modelManager/ConfigManager.ts @@ -231,12 +231,13 @@ export class ClientConfigManager { } getResourceWeight(resourceId: number): number { + // todo: using EternumGlobalConfig because no access to recs return this.getValueOrDefault(() => { - const weightConfig = getComponentValue( - this.components.WeightConfig, - getEntityIdFromKeys([WORLD_CONFIG_ID, BigInt(resourceId)]), - ); - return Number(weightConfig?.weight_gram ?? 0); + const weightGram = + EternumGlobalConfig.resources.resourceWeightsGrams[ + resourceId as keyof typeof EternumGlobalConfig.resources.resourceWeightsGrams + ]; + return weightGram; }, 0); } diff --git a/landing/src/hooks/gql/gql.ts b/landing/src/hooks/gql/gql.ts index 7effd4df3..dd58633a6 100644 --- a/landing/src/hooks/gql/gql.ts +++ b/landing/src/hooks/gql/gql.ts @@ -1,7 +1,5 @@ /* eslint-disable */ -import * as types from './graphql'; - - +import * as types from "./graphql"; /** * Map of all GraphQL operations in the project. @@ -15,49 +13,72 @@ import * as types from './graphql'; * Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size */ const documents = { - "\n query getCapacitySpeedConfig($category: Enum!, $entityType: u32!) {\n s0EternumCapacityConfigModels(where: {category: $category }) {\n edges{\n node {\n weight_gram\n }\n }\n }\n s0EternumSpeedConfigModels(where: {entity_type: $entityType }) {\n edges{\n node {\n sec_per_km\n }\n }\n }\n }\n": types.GetCapacitySpeedConfigDocument, - "\n query getEternumOwnerRealmIds($accountAddress: ContractAddress!) {\n s0EternumOwnerModels(where: { address: $accountAddress }) {\n edges {\n node {\n address\n entity_id\n entity {\n models {\n __typename\n ... on s0_eternum_Realm {\n realm_id\n }\n }\n }\n }\n }\n }\n }\n": types.GetEternumOwnerRealmIdsDocument, - "\n query getEternumEntityOwner($entityOwnerIds: [u32!]!) {\n s0EternumEntityOwnerModels(where: { entity_owner_idIN: $entityOwnerIds}, limit: 200) {\n edges {\n node {\n entity_id\n entity_owner_id\n entity {\n models {\n __typename\n ... on s0_eternum_OwnedResourcesTracker {\n resource_types\n }\n ... on s0_eternum_Position {\n x\n y\n }\n ... on s0_eternum_ArrivalTime {\n arrives_at\n }\n ... on s0_eternum_Weight {\n value\n }\n }\n }\n }\n }\n }\n }\n": types.GetEternumEntityOwnerDocument, - "\n query getAccountTokens($accountAddress: String!) {\n tokenBalances(accountAddress: $accountAddress, limit: 8000) {\n edges {\n node {\n tokenMetadata {\n __typename\n ... on ERC721__Token {\n tokenId\n metadataDescription\n imagePath\n contractAddress\n metadata\n }\n }\n }\n }\n }\n }\n": types.GetAccountTokensDocument, - "\n query getERC721Mints {\n tokenTransfers(accountAddress: \"0x0\", limit: 8000) {\n edges {\n node {\n tokenMetadata {\n __typename\n ... on ERC721__Token {\n tokenId\n metadataDescription\n imagePath\n contractAddress\n metadata\n }\n }\n }\n }\n }\n }\n": types.GetErc721MintsDocument, - "\n query eternumStatistics {\n s0EternumAddressNameModels {\n totalCount\n }\n s0EternumHyperstructureModels {\n totalCount\n }\n s0EternumRealmModels {\n totalCount\n }\n s0EternumFragmentMineDiscoveredModels {\n totalCount\n }\n }\n": types.EternumStatisticsDocument, - "\n query getEntityPosition($entityIds: [u32!]!) {\n s0EternumPositionModels(where: { entity_idIN: $entityIds }) {\n edges {\n node {\n x\n y\n entity_id\n entity {\n __typename\n }\n }\n }\n }\n }\n": types.GetEntityPositionDocument, - "\n query getEntitiesResources($entityIds: [u32!]!) {\n s0EternumResourceModels(\n where: { \n entity_idIN: $entityIds\n }\n limit: 100\n ) {\n edges {\n node {\n entity_id\n resource_type\n balance\n entity {\n __typename\n }\n }\n }\n }\n }\n": types.GetEntitiesResourcesDocument, + "\n query getCapacitySpeedConfig($category: Enum!, $entityType: u32!) {\n s0EternumCapacityConfigModels(where: {category: $category }) {\n edges{\n node {\n weight_gram\n }\n }\n }\n s0EternumSpeedConfigModels(where: {entity_type: $entityType }) {\n edges{\n node {\n sec_per_km\n }\n }\n }\n }\n": + types.GetCapacitySpeedConfigDocument, + "\n query getEternumOwnerRealmIds($accountAddress: ContractAddress!) {\n s0EternumOwnerModels(where: { address: $accountAddress }, limit: 1000) {\n edges {\n node {\n address\n entity_id\n entity {\n models {\n __typename\n ... on s0_eternum_Realm {\n realm_id\n }\n }\n }\n }\n }\n }\n }\n": + types.GetEternumOwnerRealmIdsDocument, + "\n query getEternumEntityOwner($entityOwnerIds: [u32!]!) {\n s0EternumEntityOwnerModels(where: { entity_owner_idIN: $entityOwnerIds}, limit: 200) {\n edges {\n node {\n entity_id\n entity_owner_id\n entity {\n models {\n __typename\n ... on s0_eternum_OwnedResourcesTracker {\n resource_types\n }\n ... on s0_eternum_Position {\n x\n y\n }\n ... on s0_eternum_ArrivalTime {\n arrives_at\n }\n ... on s0_eternum_Weight {\n value\n }\n }\n }\n }\n }\n }\n }\n": + types.GetEternumEntityOwnerDocument, + "\n query getAccountTokens($accountAddress: String!) {\n tokenBalances(accountAddress: $accountAddress, limit: 8000) {\n edges {\n node {\n tokenMetadata {\n __typename\n ... on ERC721__Token {\n tokenId\n metadataDescription\n imagePath\n contractAddress\n metadata\n }\n }\n }\n }\n }\n }\n": + types.GetAccountTokensDocument, + '\n query getERC721Mints {\n tokenTransfers(accountAddress: "0x0", limit: 8000) {\n edges {\n node {\n tokenMetadata {\n __typename\n ... on ERC721__Token {\n tokenId\n metadataDescription\n imagePath\n contractAddress\n metadata\n }\n }\n }\n }\n }\n }\n': + types.GetErc721MintsDocument, + "\n query eternumStatistics {\n s0EternumAddressNameModels {\n totalCount\n }\n s0EternumHyperstructureModels {\n totalCount\n }\n s0EternumRealmModels {\n totalCount\n }\n s0EternumFragmentMineDiscoveredModels {\n totalCount\n }\n }\n": + types.EternumStatisticsDocument, + "\n query getEntityPosition($entityIds: [u32!]!) {\n s0EternumPositionModels(where: { entity_idIN: $entityIds }) {\n edges {\n node {\n x\n y\n entity_id\n entity {\n __typename\n }\n }\n }\n }\n }\n": + types.GetEntityPositionDocument, + "\n query getEntitiesResources($entityIds: [u32!]!) {\n s0EternumResourceModels(\n where: { \n entity_idIN: $entityIds\n }\n limit: 100\n ) {\n edges {\n node {\n entity_id\n resource_type\n balance\n entity {\n __typename\n }\n }\n }\n }\n }\n": + types.GetEntitiesResourcesDocument, }; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query getCapacitySpeedConfig($category: Enum!, $entityType: u32!) {\n s0EternumCapacityConfigModels(where: {category: $category }) {\n edges{\n node {\n weight_gram\n }\n }\n }\n s0EternumSpeedConfigModels(where: {entity_type: $entityType }) {\n edges{\n node {\n sec_per_km\n }\n }\n }\n }\n"): typeof import('./graphql').GetCapacitySpeedConfigDocument; +export function graphql( + source: "\n query getCapacitySpeedConfig($category: Enum!, $entityType: u32!) {\n s0EternumCapacityConfigModels(where: {category: $category }) {\n edges{\n node {\n weight_gram\n }\n }\n }\n s0EternumSpeedConfigModels(where: {entity_type: $entityType }) {\n edges{\n node {\n sec_per_km\n }\n }\n }\n }\n", +): typeof import("./graphql").GetCapacitySpeedConfigDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query getEternumOwnerRealmIds($accountAddress: ContractAddress!) {\n s0EternumOwnerModels(where: { address: $accountAddress }) {\n edges {\n node {\n address\n entity_id\n entity {\n models {\n __typename\n ... on s0_eternum_Realm {\n realm_id\n }\n }\n }\n }\n }\n }\n }\n"): typeof import('./graphql').GetEternumOwnerRealmIdsDocument; +export function graphql( + source: "\n query getEternumOwnerRealmIds($accountAddress: ContractAddress!) {\n s0EternumOwnerModels(where: { address: $accountAddress }, limit: 1000) {\n edges {\n node {\n address\n entity_id\n entity {\n models {\n __typename\n ... on s0_eternum_Realm {\n realm_id\n }\n }\n }\n }\n }\n }\n }\n", +): typeof import("./graphql").GetEternumOwnerRealmIdsDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query getEternumEntityOwner($entityOwnerIds: [u32!]!) {\n s0EternumEntityOwnerModels(where: { entity_owner_idIN: $entityOwnerIds}, limit: 200) {\n edges {\n node {\n entity_id\n entity_owner_id\n entity {\n models {\n __typename\n ... on s0_eternum_OwnedResourcesTracker {\n resource_types\n }\n ... on s0_eternum_Position {\n x\n y\n }\n ... on s0_eternum_ArrivalTime {\n arrives_at\n }\n ... on s0_eternum_Weight {\n value\n }\n }\n }\n }\n }\n }\n }\n"): typeof import('./graphql').GetEternumEntityOwnerDocument; +export function graphql( + source: "\n query getEternumEntityOwner($entityOwnerIds: [u32!]!) {\n s0EternumEntityOwnerModels(where: { entity_owner_idIN: $entityOwnerIds}, limit: 200) {\n edges {\n node {\n entity_id\n entity_owner_id\n entity {\n models {\n __typename\n ... on s0_eternum_OwnedResourcesTracker {\n resource_types\n }\n ... on s0_eternum_Position {\n x\n y\n }\n ... on s0_eternum_ArrivalTime {\n arrives_at\n }\n ... on s0_eternum_Weight {\n value\n }\n }\n }\n }\n }\n }\n }\n", +): typeof import("./graphql").GetEternumEntityOwnerDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query getAccountTokens($accountAddress: String!) {\n tokenBalances(accountAddress: $accountAddress, limit: 8000) {\n edges {\n node {\n tokenMetadata {\n __typename\n ... on ERC721__Token {\n tokenId\n metadataDescription\n imagePath\n contractAddress\n metadata\n }\n }\n }\n }\n }\n }\n"): typeof import('./graphql').GetAccountTokensDocument; +export function graphql( + source: "\n query getAccountTokens($accountAddress: String!) {\n tokenBalances(accountAddress: $accountAddress, limit: 8000) {\n edges {\n node {\n tokenMetadata {\n __typename\n ... on ERC721__Token {\n tokenId\n metadataDescription\n imagePath\n contractAddress\n metadata\n }\n }\n }\n }\n }\n }\n", +): typeof import("./graphql").GetAccountTokensDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query getERC721Mints {\n tokenTransfers(accountAddress: \"0x0\", limit: 8000) {\n edges {\n node {\n tokenMetadata {\n __typename\n ... on ERC721__Token {\n tokenId\n metadataDescription\n imagePath\n contractAddress\n metadata\n }\n }\n }\n }\n }\n }\n"): typeof import('./graphql').GetErc721MintsDocument; +export function graphql( + source: '\n query getERC721Mints {\n tokenTransfers(accountAddress: "0x0", limit: 8000) {\n edges {\n node {\n tokenMetadata {\n __typename\n ... on ERC721__Token {\n tokenId\n metadataDescription\n imagePath\n contractAddress\n metadata\n }\n }\n }\n }\n }\n }\n', +): typeof import("./graphql").GetErc721MintsDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query eternumStatistics {\n s0EternumAddressNameModels {\n totalCount\n }\n s0EternumHyperstructureModels {\n totalCount\n }\n s0EternumRealmModels {\n totalCount\n }\n s0EternumFragmentMineDiscoveredModels {\n totalCount\n }\n }\n"): typeof import('./graphql').EternumStatisticsDocument; +export function graphql( + source: "\n query eternumStatistics {\n s0EternumAddressNameModels {\n totalCount\n }\n s0EternumHyperstructureModels {\n totalCount\n }\n s0EternumRealmModels {\n totalCount\n }\n s0EternumFragmentMineDiscoveredModels {\n totalCount\n }\n }\n", +): typeof import("./graphql").EternumStatisticsDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query getEntityPosition($entityIds: [u32!]!) {\n s0EternumPositionModels(where: { entity_idIN: $entityIds }) {\n edges {\n node {\n x\n y\n entity_id\n entity {\n __typename\n }\n }\n }\n }\n }\n"): typeof import('./graphql').GetEntityPositionDocument; +export function graphql( + source: "\n query getEntityPosition($entityIds: [u32!]!) {\n s0EternumPositionModels(where: { entity_idIN: $entityIds }) {\n edges {\n node {\n x\n y\n entity_id\n entity {\n __typename\n }\n }\n }\n }\n }\n", +): typeof import("./graphql").GetEntityPositionDocument; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query getEntitiesResources($entityIds: [u32!]!) {\n s0EternumResourceModels(\n where: { \n entity_idIN: $entityIds\n }\n limit: 100\n ) {\n edges {\n node {\n entity_id\n resource_type\n balance\n entity {\n __typename\n }\n }\n }\n }\n }\n"): typeof import('./graphql').GetEntitiesResourcesDocument; - +export function graphql( + source: "\n query getEntitiesResources($entityIds: [u32!]!) {\n s0EternumResourceModels(\n where: { \n entity_idIN: $entityIds\n }\n limit: 100\n ) {\n edges {\n node {\n entity_id\n resource_type\n balance\n entity {\n __typename\n }\n }\n }\n }\n }\n", +): typeof import("./graphql").GetEntitiesResourcesDocument; export function graphql(source: string) { return (documents as any)[source] ?? {}; diff --git a/landing/src/hooks/gql/graphql.ts b/landing/src/hooks/gql/graphql.ts index 7bc17ca3e..34c0aceaa 100644 --- a/landing/src/hooks/gql/graphql.ts +++ b/landing/src/hooks/gql/graphql.ts @@ -7352,7 +7352,7 @@ export const GetCapacitySpeedConfigDocument = new TypedDocumentString(` `) as unknown as TypedDocumentString; export const GetEternumOwnerRealmIdsDocument = new TypedDocumentString(` query getEternumOwnerRealmIds($accountAddress: ContractAddress!) { - s0EternumOwnerModels(where: {address: $accountAddress}) { + s0EternumOwnerModels(where: {address: $accountAddress}, limit: 1000) { edges { node { address diff --git a/landing/src/hooks/helpers/use-sync-entity.tsx b/landing/src/hooks/helpers/use-sync-entity.tsx deleted file mode 100644 index e3511daff..000000000 --- a/landing/src/hooks/helpers/use-sync-entity.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { addToSubscription } from "@/dojo/queries"; -import { useEffect, useMemo, useState } from "react"; -import { useDojo } from "../context/DojoContext"; -import { useEntities } from "./useEntities"; - -export const useSyncEntity = (entityIds: number | number[]) => { - const dojo = useDojo(); - const [isSyncing, setIsSyncing] = useState(false); - - useEffect(() => { - setIsSyncing(true); - const fetch = async () => { - try { - const ids = Array.isArray(entityIds) ? entityIds : [entityIds]; - await Promise.all( - ids.map((id) => - addToSubscription(dojo.network.toriiClient, dojo.network.contractComponents as any, id.toString()), - ), - ); - } catch (error) { - console.error("Fetch failed", error); - } finally { - setIsSyncing(false); - } - }; - fetch(); - }, [entityIds]); - - return isSyncing; -}; - -export const useSyncPlayerRealms = () => { - const { playerRealms } = useEntities(); - const realmEntityIds = useMemo(() => { - return playerRealms.map((realm) => realm!.entity_id); - }, [playerRealms]); - - return useSyncEntity(realmEntityIds); -}; diff --git a/landing/src/hooks/helpers/useEntities.tsx b/landing/src/hooks/helpers/useEntities.tsx index c0b9c3451..df7543947 100644 --- a/landing/src/hooks/helpers/useEntities.tsx +++ b/landing/src/hooks/helpers/useEntities.tsx @@ -1,36 +1,26 @@ import { useAccount } from "@starknet-react/core"; import { useQuery } from "@tanstack/react-query"; +import { useMemo } from "react"; import { execute } from "../gql/execute"; import { GET_ETERNUM_OWNER_REALM_IDS } from "../query/entities"; +import { useRealm } from "./useRealms"; -export const useEntities = () => { - /*const { - account: { account }, - setup: { - components: { Realm, Owner }, - }, - } = useDojo();*/ - - const { address } = useAccount(); +export interface S0EternumRealm { + __typename: "s0_eternum_Realm"; + realm_id: number; +} - /* const dojoAddress = ContractAddress(account?.address || ""); +export function isS0EternumRealm(model: any): model is S0EternumRealm { + return model?.__typename === "s0_eternum_Realm"; +} - // Get all realms - const allRealms = useEntityQuery([Has(Realm)]); +export function isS0EternumStructure(model: any) { + return model?.__typename === "s0_eternum_Structure"; +} - const filterPlayerRealms = useMemo(() => { - return allRealms.filter((id) => { - const owner = getComponentValue(Owner, id); - return owner && ContractAddress(owner.address) === ContractAddress(dojoAddress); - }); - }, [allRealms, dojoAddress]); - - const playerRealms = useMemo(() => { - return filterPlayerRealms.map((id) => { - const realm = getComponentValue(Realm, id); - return realm; - }); - }, [filterPlayerRealms]);*/ +export const useEntities = () => { + const { address } = useAccount(); + const { getRealmNameById } = useRealm(); const { data, isLoading } = useQuery({ queryKey: ["entityResources", address], @@ -38,8 +28,43 @@ export const useEntities = () => { refetchInterval: 10_000, }); + const playerRealms = useMemo(() => { + if (!data) return []; + + return data.s0EternumOwnerModels?.edges + ?.map((realm) => { + const realmModel = realm?.node?.entity?.models?.find(isS0EternumRealm); + if (!realmModel) return null; + return { + realmId: realmModel?.realm_id, + entityId: realm?.node?.entity_id, + name: getRealmNameById(realmModel?.realm_id ?? 0), + }; + }) + .filter(Boolean) as { realmId: number; entityId: number; name: string }[]; + }, [data, getRealmNameById]); + + const playerStructures = useMemo(() => { + if (!data) return []; + + return data.s0EternumOwnerModels?.edges + ?.map((structure) => { + const structureModel = structure?.node?.entity?.models?.find(isS0EternumStructure); + if (!structureModel) return null; + const realmModel = structure?.node?.entity?.models?.find(isS0EternumRealm); + const entityId = structure?.node?.entity_id; + return { + realmId: realmModel?.realm_id || entityId, + entityId, + name: realmModel ? getRealmNameById(realmModel?.realm_id ?? 0) : "Structure", + }; + }) + .filter(Boolean) as { realmId: number | undefined; entityId: number; name: string }[]; + }, [data, getRealmNameById]); + return { - data, - //playerRealms, + playerRealms, + playerStructures, + isLoading, }; }; diff --git a/landing/src/hooks/query/entities.tsx b/landing/src/hooks/query/entities.tsx index 430d61194..0abfb41db 100644 --- a/landing/src/hooks/query/entities.tsx +++ b/landing/src/hooks/query/entities.tsx @@ -2,7 +2,7 @@ import { graphql } from "../gql"; export const GET_ETERNUM_OWNER_REALM_IDS = graphql(` query getEternumOwnerRealmIds($accountAddress: ContractAddress!) { - s0EternumOwnerModels(where: { address: $accountAddress }) { + s0EternumOwnerModels(where: { address: $accountAddress }, limit: 1000) { edges { node { address From b096ce2f000ef828ddd402c67de00cad9c402cf2 Mon Sep 17 00:00:00 2001 From: raschel <38816784+aymericdelab@users.noreply.github.com> Date: Sun, 22 Dec 2024 23:02:53 +0100 Subject: [PATCH 2/2] next (#2586) --- client/src/dojo/debouncedQueries.ts | 6 ++-- client/src/dojo/queries.ts | 35 ++++------------------ client/src/hooks/store/useWorldLoading.tsx | 4 +-- client/src/ui/components/WorldLoading.tsx | 2 +- client/src/ui/layouts/World.tsx | 8 ++--- 5 files changed, 15 insertions(+), 40 deletions(-) diff --git a/client/src/dojo/debouncedQueries.ts b/client/src/dojo/debouncedQueries.ts index 58558184e..ea350511a 100644 --- a/client/src/dojo/debouncedQueries.ts +++ b/client/src/dojo/debouncedQueries.ts @@ -2,7 +2,7 @@ import { Component, Metadata, Schema } from "@dojoengine/recs"; import { ToriiClient } from "@dojoengine/torii-client"; import debounce from "lodash/debounce"; import { - addArrivalsSubscription, + addDonkeysAndArmiesSubscription, addHyperstructureSubscription, addMarketSubscription, addToSubscription, @@ -103,14 +103,14 @@ export const debouncedAddToSubscriptionOneKey = debounce( { leading: true }, ); -export const debounceAddResourceArrivals = debounce( +export const debounceAddDonkeysAndArmiesSubscription = debounce( async ( client: ToriiClient, components: Component[], entityID: number[], onComplete?: () => void, ) => { - await subscriptionQueue.add(() => addArrivalsSubscription(client, components, entityID), onComplete); + await subscriptionQueue.add(() => addDonkeysAndArmiesSubscription(client, components, entityID), onComplete); }, 250, { leading: true }, diff --git a/client/src/dojo/queries.ts b/client/src/dojo/queries.ts index 20f2e334d..99575f481 100644 --- a/client/src/dojo/queries.ts +++ b/client/src/dojo/queries.ts @@ -191,7 +191,7 @@ export const addHyperstructureSubscription = async ( console.log("HyperstructureEnd", end - start); }; -export const addArrivalsSubscription = async ( +export const addDonkeysAndArmiesSubscription = async ( client: ToriiClient, components: Component[], entityIds: number[], @@ -200,35 +200,6 @@ export const addArrivalsSubscription = async ( console.log("ArrivalsEnd: starting resource arrivals"); await getEntities( client, - // todo: waiting on ghlim to check issue with this query - // { - // Composite: { - // operator: "And", - // clauses: [ - // { - // Composite: { - // operator: "Or", - // clauses: entityIds.map((id) => ({ - // Member: { - // model: "s0_eternum-EntityOwner", - // member: "entity_owner_id", - // operator: "Eq", - // value: { Primitive: { U32: id } }, - // }, - // })), - // }, - // }, - // { - // Member: { - // model: "s0_eternum-OwnedResourcesTracker", - // member: "resource_types", - // operator: "Neq", - // value: { Primitive: { U256: "0" } }, - // }, - // }, - // ], - // }, - // }, { Composite: { operator: "Or", @@ -248,10 +219,14 @@ export const addArrivalsSubscription = async ( [ "s0_eternum-Army", "s0_eternum-Position", + "s0_eternum-Health", "s0_eternum-EntityOwner", + "s0_eternum-Protectee", + "s0_eternum-Stamina", "s0_eternum-Weight", "s0_eternum-OwnedResourcesTracker", "s0_eternum-ArrivalTime", + "s0_eternum-Quantity", ], 1000, false, diff --git a/client/src/hooks/store/useWorldLoading.tsx b/client/src/hooks/store/useWorldLoading.tsx index 5a1ab77b5..55e76cf11 100644 --- a/client/src/hooks/store/useWorldLoading.tsx +++ b/client/src/hooks/store/useWorldLoading.tsx @@ -7,7 +7,7 @@ export enum LoadingStateKey { Market = "market", PlayerStructuresOneKey = "playerStructuresOneKey", PlayerStructuresTwoKey = "playerStructuresTwoKey", - Arrivals = "arrivals", + DonkeysAndArmies = "donkeysAndArmies", Map = "map", Bank = "bank", World = "world", @@ -32,7 +32,7 @@ export const createWorldStoreSlice = (set: any) => ({ [LoadingStateKey.Market]: false, [LoadingStateKey.PlayerStructuresOneKey]: false, [LoadingStateKey.PlayerStructuresTwoKey]: false, - [LoadingStateKey.Arrivals]: false, + [LoadingStateKey.DonkeysAndArmies]: false, [LoadingStateKey.Map]: false, [LoadingStateKey.Bank]: false, [LoadingStateKey.World]: false, diff --git a/client/src/ui/components/WorldLoading.tsx b/client/src/ui/components/WorldLoading.tsx index 71d753486..fbb45c35a 100644 --- a/client/src/ui/components/WorldLoading.tsx +++ b/client/src/ui/components/WorldLoading.tsx @@ -12,7 +12,7 @@ export const WorldLoading = () => { if (loadingStates[LoadingStateKey.Market]) items.push("Market"); if (loadingStates[LoadingStateKey.PlayerStructuresOneKey] || loadingStates[LoadingStateKey.PlayerStructuresTwoKey]) items.push("Player Structures"); - if (loadingStates[LoadingStateKey.Arrivals]) items.push("Arrivals"); + if (loadingStates[LoadingStateKey.DonkeysAndArmies]) items.push("Donkeys and Armies"); if (loadingStates[LoadingStateKey.Map]) items.push("Map"); if (loadingStates[LoadingStateKey.Bank]) items.push("Bank"); if (loadingStates[LoadingStateKey.World]) items.push("World"); diff --git a/client/src/ui/layouts/World.tsx b/client/src/ui/layouts/World.tsx index 5448f989e..1817fc8dd 100644 --- a/client/src/ui/layouts/World.tsx +++ b/client/src/ui/layouts/World.tsx @@ -4,7 +4,7 @@ import { Redirect } from "wouter"; import useUIStore from "../../hooks/store/useUIStore"; import { - debounceAddResourceArrivals, + debounceAddDonkeysAndArmiesSubscription, debouncedAddHyperstructureSubscription, debouncedAddMarketSubscription, debouncedAddToSubscription, @@ -164,7 +164,7 @@ export const World = ({ backgroundImage }: { backgroundImage: string }) => { const fetch = async () => { setLoading(LoadingStateKey.PlayerStructuresOneKey, true); setLoading(LoadingStateKey.PlayerStructuresTwoKey, true); - setLoading(LoadingStateKey.Arrivals, true); + setLoading(LoadingStateKey.DonkeysAndArmies, true); const isSyncing = true; @@ -186,11 +186,11 @@ export const World = ({ backgroundImage }: { backgroundImage: string }) => { ), ]); - await debounceAddResourceArrivals( + await debounceAddDonkeysAndArmiesSubscription( dojo.network.toriiClient, dojo.network.contractComponents as any, [...structures.map((structure) => structure.entity_id)], - () => setLoading(LoadingStateKey.Arrivals, false), + () => setLoading(LoadingStateKey.DonkeysAndArmies, false), ); } catch (error) { console.error("Fetch failed", error);