Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

main #2561

Merged
merged 6 commits into from
Dec 19, 2024
Merged

main #2561

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
6 changes: 3 additions & 3 deletions client/.env.production
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ VITE_PUBLIC_WORLD_ADDRESS="0x5013b17c43a2b664ec2a38aa45f6d891db1188622ec7cf32041
VITE_PUBLIC_ACCOUNT_CLASS_HASH="0x07dc7899aa655b0aae51eadff6d801a58e97dd99cf4666ee59e704249e51adf2"
VITE_PUBLIC_FEE_TOKEN_ADDRESS=0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7

VITE_PUBLIC_TORII=https://api.cartridge.gg/x/eternum-mainnet/torii
VITE_PUBLIC_TORII=https://api.cartridge.gg/x/eternum-prod/torii
VITE_PUBLIC_NODE_URL=https://api.cartridge.gg/x/starknet/mainnet
VITE_PUBLIC_DEV=false
VITE_PUBLIC_GAME_VERSION="v1.0.0"
VITE_PUBLIC_SHOW_FPS=false
VITE_PUBLIC_GRAPHICS_DEV=false
VITE_PUBLIC_TORII_RELAY=/dns4/api.cartridge.gg/tcp/443/x-parity-wss/%2Fx%2Feternum-mainnet%2Ftorii%2Fwss
VITE_PUBLIC_TORII_RELAY=/dns4/api.cartridge.gg/tcp/443/x-parity-wss/%2Fx%2Feternum-prod%2Ftorii%2Fwss

VITE_SEASON_PASS_ADDRESS=0x057675b9c0bd62b096a2e15502a37b290fa766ead21c33eda42993e48a714b80
VITE_REALMS_ADDRESS=0x07ae27a31bb6526e3de9cf02f081f6ce0615ac12a6d7b85ee58b8ad7947a2809
Expand All @@ -19,7 +19,7 @@ VITE_LORDS_ADDRESS=0x0124aeb495b947201f5fac96fd1138e326ad86195b98df6dec9009158a5
VITE_SOCIAL_LINK=http://bit.ly/3Zz1mpp

VITE_PUBLIC_CHAIN=mainnet
VITE_PUBLIC_SLOT=eternum-mainnet
VITE_PUBLIC_SLOT=eternum-prod

VITE_PUBLIC_CONSTRUCTION_FLAG=true
VITE_PUBLIC_HIDE_THREEJS_MENU=false
Expand Down
30 changes: 30 additions & 0 deletions client/src/dojo/entityWorker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { debounce } from "lodash";

let entityBatch = {};
let logging = false;
const DEBOUNCE_DELAY = 1000;

let debouncedSendBatch = debounce(() => {
if (Object.keys(entityBatch).length > 0) {
console.log("Worker: Sending batch", entityBatch);
self.postMessage({ updatedEntities: entityBatch });
entityBatch = {};
}
}, DEBOUNCE_DELAY);

self.onmessage = async (e) => {
const { type, entities, logging: logFlag } = e.data;
if (type === "update") {
logging = logFlag;
if (logging) console.log("Worker: Received entities update");
handleUpdate(entities.fetchedEntities, entities.data);
}
};

function handleUpdate(fetchedEntities, data) {
entityBatch[fetchedEntities] = {
...entityBatch[fetchedEntities],
...data,
};
debouncedSendBatch();
}
2 changes: 2 additions & 0 deletions client/src/dojo/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ export const addToSubscription = async <S extends Schema>(
position?: { x: number; y: number }[],
) => {
const start = performance.now();

console.log("AddToSubscriptionStart", entityID);
await getEntities(
client,
{
Expand Down
73 changes: 14 additions & 59 deletions client/src/dojo/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,73 +4,18 @@ import {
WORLD_CONFIG_ID,
} from "@bibliothecadao/eternum";
import { DojoConfig } from "@dojoengine/core";
import { Component, Metadata, Schema } from "@dojoengine/recs";
import { getEntities, getEvents, setEntities } from "@dojoengine/state";
import { Clause, EntityKeysClause, ToriiClient } from "@dojoengine/torii-client";
import { debounce } from "lodash";
import { getEntities, getEvents } from "@dojoengine/state";
import { Clause } from "@dojoengine/torii-client";
import { createClientComponents } from "./createClientComponents";
import { createSystemCalls } from "./createSystemCalls";
import { ClientConfigManager } from "./modelManager/ConfigManager";
import { setupNetwork } from "./setupNetwork";
import { setupWorker } from "./worker";

export type SetupResult = Awaited<ReturnType<typeof setup>>;

export const configManager = ClientConfigManager.instance();

export const syncEntitiesDebounced = async <S extends Schema>(
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
entityKeyClause: EntityKeysClause[],
logging: boolean = true,
historical: boolean = false,
) => {
if (logging) console.log("Starting syncEntities");

let entityBatch: Record<string, any> = {};

const debouncedSetEntities = debounce(() => {
if (Object.keys(entityBatch).length > 0) {
// console.log("Applying batch update", entityBatch);
setEntities(entityBatch, components, logging);
entityBatch = {}; // Clear the batch after applying
}
}, 1000); // Increased debounce time to 1 second for larger batches

// Handle entity updates
const entitySub = await client.onEntityUpdated(entityKeyClause, (fetchedEntities: any, data: any) => {
if (logging) console.log("Entity updated", fetchedEntities);
// Merge new data with existing data for this entity
entityBatch[fetchedEntities] = {
...entityBatch[fetchedEntities],
...data,
};
debouncedSetEntities();
});

// Handle event message updates
const eventSub = await client.onEventMessageUpdated(
entityKeyClause,
historical,
(fetchedEntities: any, data: any) => {
if (logging) console.log("Event message updated", fetchedEntities);
// Merge new data with existing data for this entity
entityBatch[fetchedEntities] = {
...entityBatch[fetchedEntities],
...data,
};
debouncedSetEntities();
},
);

// Return combined subscription that can cancel both
return {
cancel: () => {
entitySub.cancel();
eventSub.cancel();
},
};
};

export async function setup({ ...config }: DojoConfig) {
const network = await setupNetwork(config);
const components = createClientComponents(network);
Expand Down Expand Up @@ -167,7 +112,17 @@ export async function setup({ ...config }: DojoConfig) {
false,
);

const sync = await syncEntitiesDebounced(network.toriiClient, network.contractComponents as any, [], false);
const sync = await setupWorker(
{
rpcUrl: config.rpcUrl,
toriiUrl: config.toriiUrl,
relayUrl: config.relayUrl,
worldAddress: config.manifest.world.address || "",
},
network.contractComponents as any,
[],
false,
);

configManager.setDojo(components);

Expand Down
56 changes: 56 additions & 0 deletions client/src/dojo/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Component, Metadata, Schema } from "@dojoengine/recs";
import { setEntities } from "@dojoengine/state";
import { EntityKeysClause, createClient } from "@dojoengine/torii-wasm";

export async function setupWorker(
config: { rpcUrl: string; toriiUrl: string; relayUrl: string; worldAddress: string },
components: Component<Schema, Metadata, undefined>[],
entityKeyClause: EntityKeysClause[],
historical: boolean,
logging = false,
) {
if (logging) console.log("Starting syncEntities");

const worker = new Worker(new URL("./entityWorker.js", import.meta.url), { type: "module" });

// Create the client in the main thread
const toriiClient = await createClient({
rpcUrl: config.rpcUrl,
toriiUrl: config.toriiUrl,
relayUrl: config.relayUrl,
worldAddress: config.worldAddress,
});

// Listen for batches from the Worker
worker.onmessage = (event) => {
const { updatedEntities } = event.data;
setEntities(updatedEntities, components, logging);
};

// Set up subscriptions in the main thread
await toriiClient.onEntityUpdated(entityKeyClause, (fetchedEntities: any, data: any) => {
if (logging) console.log("Main: Entity updated", fetchedEntities);
// Send updates to worker for processing
worker.postMessage({
type: "update",
entities: { fetchedEntities, data },
logging,
});
});

await toriiClient.onEventMessageUpdated(entityKeyClause, historical, (fetchedEntities: any, data: any) => {
if (logging) console.log("Main: Event message updated", fetchedEntities);
// Send updates to worker for processing
worker.postMessage({
type: "update",
entities: { fetchedEntities, data },
logging,
});
});

return {
cancel: () => {
worker.terminate();
},
};
}
125 changes: 84 additions & 41 deletions client/src/ui/components/bank/LiquidityResourceRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const LiquidityResourceRow = ({
const [canCarry, setCanCarry] = useState(false);
const [openConfirmation, setOpenConfirmation] = useState(false);
const [showInputResourcesPrice, setShowInputResourcesPrice] = useState(false);
const [withdrawalPercentage, setWithdrawalPercentage] = useState(100);

const marketEntityId = useMemo(
() => getEntityIdFromKeys([BigInt(bankEntityId), BigInt(resourceId)]),
Expand Down Expand Up @@ -80,29 +81,52 @@ export const LiquidityResourceRow = ({

const { computeTravelTime } = useTravel();

const onWithdraw = useCallback(() => {
setIsLoading(true);
const sharesUnscaled = marketManager.getSharesUnscaled();
const totalLiquidityUnscaled = marketManager.getTotalLiquidityUnscaled();
const withdrawShares = sharesUnscaled > totalLiquidityUnscaled ? totalLiquidityUnscaled : sharesUnscaled;
dojoContext.setup.systemCalls
.remove_liquidity({
bank_entity_id: bankEntityId,
entity_id: entityId,
resource_type: BigInt(resourceId),
shares: withdrawShares,
signer: dojoContext.account.account,
})
.finally(() => {
setIsLoading(false);
setOpenConfirmation(false);
});
}, [dojoContext, bankEntityId, entityId, resourceId, marketManager]);
const onWithdraw = useCallback(
(percentage: number) => {
setIsLoading(true);
const { withdrawShares } = calculateWithdrawAmounts(percentage);

dojoContext.setup.systemCalls
.remove_liquidity({
bank_entity_id: bankEntityId,
entity_id: entityId,
resource_type: BigInt(resourceId),
shares: withdrawShares,
signer: dojoContext.account.account,
})
.finally(() => {
setIsLoading(false);
setOpenConfirmation(false);
});
},
[dojoContext, bankEntityId, entityId, resourceId, marketManager],
);

const calculateWithdrawAmounts = useCallback(
(percentage: number) => {
const sharesUnscaled = marketManager.getSharesUnscaled();
const totalLiquidityUnscaled = marketManager.getTotalLiquidityUnscaled();
const maxShares = sharesUnscaled > totalLiquidityUnscaled ? totalLiquidityUnscaled : sharesUnscaled;
const withdrawShares = (maxShares * BigInt(percentage)) / BigInt(100);

const lordsToReceive = (lordsAmount * percentage) / 100;
const resourceToReceive = (resourceAmount * percentage) / 100;

return {
withdrawShares: withdrawShares,
lords: lordsToReceive,
resource: resourceToReceive,
};
},
[marketManager, lordsAmount, resourceAmount],
);

const renderConfirmationPopup = useMemo(() => {
const { lords, resource } = calculateWithdrawAmounts(withdrawalPercentage);

const travelResources = [
{ amount: divideByPrecision(lordsAmount), resourceId: ResourcesIds.Lords },
{ amount: divideByPrecision(resourceAmount), resourceId: resourceId },
{ amount: divideByPrecision(lords), resourceId: ResourcesIds.Lords },
{ amount: divideByPrecision(resource), resourceId: resourceId },
];

return (
Expand All @@ -111,36 +135,54 @@ export const LiquidityResourceRow = ({
warning="Warning: not enough donkeys to transport resources"
disabled={!canCarry}
isLoading={isLoading}
onConfirm={onWithdraw}
onConfirm={() => onWithdraw(withdrawalPercentage)}
onCancel={() => setOpenConfirmation(false)}
>
<div>
<div className="flex items-center justify-center space-x-2">
{travelResources.map((cost, index) => (
<div key={index} className="flex items-center">
<ResourceCost withTooltip amount={cost.amount} resourceId={cost.resourceId} />
</div>
))}
<div className="space-y-4">
<div className="flex flex-col items-center space-y-2">
<div className="w-full flex items-center justify-between">
<span>Withdrawal Amount:</span>
<span className="font-bold">{withdrawalPercentage}%</span>
</div>
<input
type="range"
min="0"
max="100"
value={withdrawalPercentage}
onChange={(e) => setWithdrawalPercentage(Number(e.target.value))}
className="w-full appearance-none bg-gold/20 h-2 rounded-lg focus:outline-none [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:bg-gold [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:cursor-pointer [&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:bg-gold [&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:cursor-pointer"
/>
</div>
<div className="bg-gold/10 p-2 mt-2 rounded-lg h-auto">
<div className="flex flex-col items-center">
<TravelInfo
entityId={entityId}
resources={travelResources}
travelTime={computeTravelTime(
bankEntityId,
entityId,
configManager.getSpeedConfig(EntityType.DONKEY),
true,
)}
setCanCarry={setCanCarry}
/>

<div>
<div className="flex items-center justify-center space-x-2">
{travelResources.map((cost, index) => (
<div key={index} className="flex items-center">
<ResourceCost withTooltip amount={cost.amount} resourceId={cost.resourceId} />
</div>
))}
</div>
<div className="bg-gold/10 p-2 mt-2 rounded-lg h-auto">
<div className="flex flex-col items-center">
<TravelInfo
entityId={entityId}
resources={travelResources}
travelTime={computeTravelTime(
bankEntityId,
entityId,
configManager.getSpeedConfig(EntityType.DONKEY),
true,
)}
setCanCarry={setCanCarry}
/>
</div>
</div>
</div>
</div>
</ConfirmationPopup>
);
}, [
withdrawalPercentage,
lordsAmount,
resourceAmount,
canCarry,
Expand All @@ -151,6 +193,7 @@ export const LiquidityResourceRow = ({
entityId,
computeTravelTime,
setCanCarry,
calculateWithdrawAmounts,
]);

return (
Expand Down
1 change: 1 addition & 0 deletions client/src/ui/components/resources/InventoryResources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const InventoryResources = ({

setIsSyncing(true);
try {
console.log("AddToSubscriptionStart - 4");
await addToSubscription(dojo.network.toriiClient, dojo.network.contractComponents as any, [
entityId.toString(),
]);
Expand Down
2 changes: 1 addition & 1 deletion client/src/ui/components/trading/MarketModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export const MarketModal = () => {
</Select>
</div>
<div className=" ml-2 bg-map align-middle flex gap-2">
{currencyFormat(Number(lordsBalance), 0)}{" "}
{currencyFormat(Number(lordsBalance), 2)}{" "}
<ResourceIcon resource={ResourcesIds[ResourcesIds.Lords]} size="lg" />
</div>
</div>
Expand Down
Loading
Loading