Skip to content

Commit

Permalink
[client] show Lp fees
Browse files Browse the repository at this point in the history
Fixes #1864
  • Loading branch information
aymericdelab committed Oct 22, 2024
1 parent 8165175 commit 32f5701
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 9 deletions.
24 changes: 24 additions & 0 deletions client/src/dojo/contractComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1728,6 +1728,30 @@ const eventsComponents = (world: World) => {
},
);
})(),

LiquidityEvent: (() => {
return defineComponent(
world,
{
bank_entity_id: RecsType.Number,
entity_id: RecsType.Number,
resource_type: RecsType.Number,
lords_amount: RecsType.BigInt,
resource_amount: RecsType.BigInt,
resource_price: RecsType.BigInt,
add: RecsType.Boolean,
timestamp: RecsType.BigInt,
},
{
metadata: {
namespace: "eternum",
name: "LiquidityEvent",
types: ["u32", "u32", "u8", "u128", "u128", "u128", "bool", "u64"],
customTypes: [],
},
},
);
})(),
},
};
};
12 changes: 11 additions & 1 deletion client/src/ui/components/bank/AddLiquidity.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MarketManager } from "@/dojo/modelManager/MarketManager";
import { useDojo } from "@/hooks/context/DojoContext";
import { useEntities } from "@/hooks/helpers/useEntities";
import { getResourceBalance } from "@/hooks/helpers/useResources";
import { useIsResourcesLocked } from "@/hooks/helpers/useStructures";
import Button from "@/ui/elements/Button";
Expand Down Expand Up @@ -28,6 +29,10 @@ const AddLiquidity = ({

const { getBalance } = getResourceBalance();

const { playerStructures } = useEntities();

const playerStructureIds = playerStructures().map((structure) => structure.entity_id);

const [isLoading, setIsLoading] = useState(false);
const [resourceId, setResourceId] = useState<ResourcesIds>(ResourcesIds.Wood);
const [lordsAmount, setLordsAmount] = useState(0);
Expand Down Expand Up @@ -140,7 +145,12 @@ const AddLiquidity = ({
</div>
<div className="p-2">
<LiquidityTableHeader />
<LiquidityResourceRow bankEntityId={bankEntityId} entityId={entityId} resourceId={resourceId} />
<LiquidityResourceRow
playerStructureIds={playerStructureIds}
bankEntityId={bankEntityId}
entityId={entityId}
resourceId={resourceId}
/>
<div className="w-full flex flex-col justify-center mt-4">
<Button
variant="primary"
Expand Down
93 changes: 88 additions & 5 deletions client/src/ui/components/bank/LiquidityResourceRow.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ClientComponents } from "@/dojo/createClientComponents";
import { MarketManager } from "@/dojo/modelManager/MarketManager";
import { configManager } from "@/dojo/setup";
import { useDojo } from "@/hooks/context/DojoContext";
Expand All @@ -6,26 +7,66 @@ import Button from "@/ui/elements/Button";
import { ResourceCost } from "@/ui/elements/ResourceCost";
import { ResourceIcon } from "@/ui/elements/ResourceIcon";
import { divideByPrecision, getEntityIdFromKeys } from "@/ui/utils/utils";
import { ContractAddress, DONKEY_ENTITY_TYPE, ID, ResourcesIds, resources } from "@bibliothecadao/eternum";
import {
ContractAddress,
DONKEY_ENTITY_TYPE,
ID,
RESOURCE_INPUTS_SCALED,
RESOURCE_OUTPUTS,
ResourcesIds,
resources,
} from "@bibliothecadao/eternum";
import { useComponentValue } from "@dojoengine/react";
import { ComponentValue, HasValue, getComponentValue, runQuery } from "@dojoengine/recs";
import React, { useCallback, useMemo, useState } from "react";
import { TravelInfo } from "../resources/ResourceWeight";
import { ConfirmationPopup } from "./ConfirmationPopup";

type LiquidityResourceRowProps = {
playerStructureIds: ID[];
bankEntityId: ID;
entityId: ID;
resourceId: ResourcesIds;
isFirst?: boolean;
};

export const LiquidityResourceRow = ({ bankEntityId, entityId, resourceId, isFirst }: LiquidityResourceRowProps) => {
export const LiquidityResourceRow = ({
playerStructureIds,
bankEntityId,
entityId,
resourceId,
isFirst,
}: LiquidityResourceRowProps) => {
const dojoContext = useDojo();
const [isLoading, setIsLoading] = useState(false);
const [canCarry, setCanCarry] = useState(false);
const [openConfirmation, setOpenConfirmation] = useState(false);
const [showInputResourcesPrice, setShowInputResourcesPrice] = useState(false);

const playerLiquidityInfo: ComponentValue<ClientComponents["events"]["LiquidityEvent"]["schema"]> | null =
useMemo(() => {
let mostRecentEvent: ComponentValue<ClientComponents["events"]["LiquidityEvent"]["schema"]> | null = null;

playerStructureIds.forEach((structureId) => {
const liquidityEvents = runQuery([
HasValue(dojoContext.setup.components.events.LiquidityEvent, {
bank_entity_id: bankEntityId,
entity_id: structureId,
resource_type: resourceId,
}),
]);

liquidityEvents.forEach((event) => {
const eventInfo = getComponentValue(dojoContext.setup.components.events.LiquidityEvent, event);
if (eventInfo && (!mostRecentEvent || eventInfo.timestamp > mostRecentEvent.timestamp)) {
mostRecentEvent = eventInfo;
}
});
});

return mostRecentEvent as ComponentValue<ClientComponents["events"]["LiquidityEvent"]["schema"]> | null;
}, [playerStructureIds, bankEntityId, resourceId]);

const marketEntityId = useMemo(
() => getEntityIdFromKeys([BigInt(bankEntityId), BigInt(resourceId)]),
[bankEntityId, resourceId],
Expand Down Expand Up @@ -65,6 +106,27 @@ export const LiquidityResourceRow = ({ bankEntityId, entityId, resourceId, isFir
const [totalLords, totalResource] = marketManager.getReserves();
const [lordsAmount, resourceAmount] = marketManager.getMyLP();

const [lordsDifferencePercentage, resourceDifferencePercentage] = useMemo(() => {
if (!playerLiquidityInfo) return [0, 0];
return [
((lordsAmount - Number(playerLiquidityInfo.lords_amount)) / Number(playerLiquidityInfo.lords_amount)) * 100,
((resourceAmount - Number(playerLiquidityInfo.resource_amount)) / Number(playerLiquidityInfo.resource_amount)) *
100,
];
}, [playerLiquidityInfo, lordsAmount, resourceAmount]);

const totalValueDifferenceInLords = useMemo(() => {
if (!playerLiquidityInfo) return 0;
const currentResourcePrice = marketManager.getMarketPrice();
const previousResourcePrice = divideByPrecision(Number(playerLiquidityInfo.resource_price));

const currentTotalValue = lordsAmount + currentResourcePrice * resourceAmount;
const previousTotalValue =
Number(playerLiquidityInfo.lords_amount) + previousResourcePrice * Number(playerLiquidityInfo.resource_amount);

return divideByPrecision(currentTotalValue - previousTotalValue);
}, [playerLiquidityInfo, totalLords, totalResource, marketManager]);

const myLiquidity = marketManager.getLiquidity();
const canWithdraw = useMemo(
() => (myLiquidity?.shares.mag || 0) > 0 && (totalLords > 0 || totalResource > 0),
Expand Down Expand Up @@ -164,7 +226,7 @@ export const LiquidityResourceRow = ({ bankEntityId, entityId, resourceId, isFir
)}
</div>

<div className="flex flex-col col-span-2">
<div className="flex flex-col col-span-2 justify-center">
<div className="flex">
<div>{divideByPrecision(totalLords).toLocaleString()}</div>
<ResourceIcon resource="Lords" size="sm" />
Expand All @@ -180,12 +242,33 @@ export const LiquidityResourceRow = ({ bankEntityId, entityId, resourceId, isFir
<div className="flex">
<div>{divideByPrecision(lordsAmount).toLocaleString()}</div>
<ResourceIcon resource="Lords" size="sm" />
{lordsAmount > 0 && (
<span className={`ml-1 text-xs ${lordsDifferencePercentage >= 0 ? "text-green" : "text-red"}`}>
({lordsDifferencePercentage > 0 ? "+" : ""}
{lordsDifferencePercentage.toFixed(2)}%)
</span>
)}
</div>

<div className="flex">
<div>{divideByPrecision(resourceAmount).toLocaleString()}</div>
<ResourceIcon resource={ResourcesIds[resourceId]} size="sm" />
{lordsAmount > 0 && (
<span className={`ml-1 text-xs ${resourceDifferencePercentage >= 0 ? "text-green" : "text-red"}`}>
({resourceDifferencePercentage > 0 ? "+" : ""}
{resourceDifferencePercentage.toFixed(2)}%)
</span>
)}
</div>

{totalValueDifferenceInLords > 0 && (
<div className="flex mt-1">
<span className={`text-xs ${totalValueDifferenceInLords >= 0 ? "text-green" : "text-red"}`}>
{totalValueDifferenceInLords >= 0 ? "+" : "-"}
{Math.abs(totalValueDifferenceInLords).toFixed(2)} Lords (uPNL)
</span>
</div>
)}
</div>

<div>
Expand All @@ -208,8 +291,8 @@ export const LiquidityResourceRow = ({ bankEntityId, entityId, resourceId, isFir

const InputResourcesPrice = ({ marketManager }: { marketManager: MarketManager }) => {
const { setup } = useDojo();
const inputResources = configManager.resourceInputs[marketManager.resourceId];
const outputAmount = configManager.getResourceOutputs(marketManager.resourceId);
const inputResources = RESOURCE_INPUTS_SCALED[marketManager.resourceId];
const outputAmount = RESOURCE_OUTPUTS[marketManager.resourceId];

if (!inputResources?.length) return null;
const totalPrice =
Expand Down
6 changes: 6 additions & 0 deletions client/src/ui/components/bank/LiquidityTable.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useEntities } from "@/hooks/helpers/useEntities";
import { ID, RESOURCE_TIERS, resources } from "@bibliothecadao/eternum";
import { useState } from "react";
import { LiquidityResourceRow } from "./LiquidityResourceRow";
Expand Down Expand Up @@ -36,6 +37,10 @@ export const LiquidityTable = ({ bankEntityId, entity_id }: LiquidityTableProps)
);
});

const { playerStructures } = useEntities();

const playerStructureIds = playerStructures().map((structure) => structure.entity_id);

return (
<div className="p-4 h-full bg-gold/10 overflow-x-auto relative">
<input
Expand All @@ -51,6 +56,7 @@ export const LiquidityTable = ({ bankEntityId, entity_id }: LiquidityTableProps)
{filteredResources.map((resourceId, index) => (
<LiquidityResourceRow
key={resourceId}
playerStructureIds={playerStructureIds}
bankEntityId={bankEntityId!}
entityId={entity_id}
resourceId={resourceId}
Expand Down
3 changes: 0 additions & 3 deletions contracts/scripts/contracts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ export DEV_RESOURCE_SYSTEMS=$(get_contract_address "eternum-dev_resource_systems

export COMBAT_SYSTEMS=$(get_contract_address "eternum-combat_systems")

export LEVELING_SYSTEMS=$(get_contract_address "eternum-leveling_systems")

export NAME_SYSTEMS=$(get_contract_address "eternum-name_systems")

export BANK_SYSTEMS=$(get_contract_address "eternum-bank_systems")
Expand Down Expand Up @@ -72,7 +70,6 @@ echo travel : $TRAVEL_SYSTEMS
echo realm : $REALM_SYSTEMS
echo test_resource : $DEV_RESOURCE_SYSTEMS
echo combat : $COMBAT_SYSTEMS
echo leveling : $LEVELING_SYSTEMS
echo name : $NAME_SYSTEMS
echo bank : $BANK_SYSTEMS
echo swap : $SWAP_SYSTEMS
Expand Down

0 comments on commit 32f5701

Please sign in to comment.