diff --git a/apps/tangle-dapp/hooks/useLocalStorage.ts b/apps/tangle-dapp/hooks/useLocalStorage.ts
index ae4b9e110..25cc0c9fd 100644
--- a/apps/tangle-dapp/hooks/useLocalStorage.ts
+++ b/apps/tangle-dapp/hooks/useLocalStorage.ts
@@ -22,7 +22,6 @@ export enum LocalStorageKey {
PAYOUTS = 'payouts',
CUSTOM_RPC_ENDPOINT = 'customRpcEndpoint',
KNOWN_NETWORK_ID = 'knownNetworkId',
- WAS_BANNER_DISMISSED = 'wasBannerDismissed',
SERVICES_CACHE = 'servicesCache',
SUBSTRATE_WALLETS_METADATA = 'substrateWalletsMetadata',
BRIDGE_TX_QUEUE_BY_ACC = 'bridgeTxQueue',
@@ -72,15 +71,13 @@ export type LocalStorageValueOf =
? string
: T extends LocalStorageKey.KNOWN_NETWORK_ID
? number
- : T extends LocalStorageKey.WAS_BANNER_DISMISSED
- ? boolean
- : T extends LocalStorageKey.SUBSTRATE_WALLETS_METADATA
- ? SubstrateWalletsMetadataCache
- : T extends LocalStorageKey.BRIDGE_TX_QUEUE_BY_ACC
- ? TxQueueByAccount
- : T extends LocalStorageKey.LIQUID_STAKING_TABLE_DATA
- ? LiquidStakingTableData
- : never;
+ : T extends LocalStorageKey.SUBSTRATE_WALLETS_METADATA
+ ? SubstrateWalletsMetadataCache
+ : T extends LocalStorageKey.BRIDGE_TX_QUEUE_BY_ACC
+ ? TxQueueByAccount
+ : T extends LocalStorageKey.LIQUID_STAKING_TABLE_DATA
+ ? LiquidStakingTableData
+ : never;
export const getJsonFromLocalStorage = (
key: Key,
From ebb915e937be0bc03764958965c922a9233dbba6 Mon Sep 17 00:00:00 2001
From: yurixander <101931215+yurixander@users.noreply.github.com>
Date: Wed, 25 Sep 2024 17:04:40 -0400
Subject: [PATCH 24/54] fix(tangle-dapp): Fix Tangle networks id issue
---
.../stakeAndUnstake/FeeDetailItem.tsx | 3 +++
.../LiquidStaking/stakeAndUnstake/LsStakeCard.tsx | 13 +++++++++----
.../stakeAndUnstake/useLsFeePercentage.ts | 15 ++++++++++++---
apps/tangle-dapp/constants/liquidStaking/types.ts | 12 +++++++++++-
.../data/liquidStaking/useLsExchangeRate.ts | 8 ++++++--
apps/tangle-dapp/data/liquidStaking/useLsStore.ts | 6 ++++--
.../utils/liquidStaking/getLsProtocolDef.ts | 12 +++++++++---
7 files changed, 54 insertions(+), 15 deletions(-)
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/FeeDetailItem.tsx b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/FeeDetailItem.tsx
index 1385ae19a..7e1488ae7 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/FeeDetailItem.tsx
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/FeeDetailItem.tsx
@@ -1,6 +1,7 @@
import { BN, BN_ZERO } from '@polkadot/util';
import { FC, useMemo } from 'react';
+import { EMPTY_VALUE_PLACEHOLDER } from '../../../constants';
import { LsProtocolId } from '../../../constants/liquidStaking/types';
import formatBn from '../../../utils/formatBn';
import getLsProtocolDef from '../../../utils/liquidStaking/getLsProtocolDef';
@@ -36,6 +37,8 @@ const FeeDetailItem: FC = ({
// Propagate error or loading state.
if (!(feeAmount instanceof BN)) {
return feeAmount;
+ } else if (feeAmount.isZero()) {
+ return EMPTY_VALUE_PLACEHOLDER;
}
const formattedAmount = formatBn(feeAmount, protocol.decimals, {
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
index 15fa7e4cf..0c68937c6 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
@@ -22,12 +22,12 @@ import {
LsProtocolId,
LsSearchParamKey,
} from '../../../constants/liquidStaking/types';
+import useMintTx from '../../../data/liquidStaking/parachain/useMintTx';
import useLsPoolJoinTx from '../../../data/liquidStaking/tangle/useLsPoolJoinTx';
import useLsExchangeRate, {
ExchangeRateType,
} from '../../../data/liquidStaking/useLsExchangeRate';
import { useLsStore } from '../../../data/liquidStaking/useLsStore';
-import useMintTx from '../../../data/liquidStaking/parachain/useMintTx';
import useLiquifierDeposit from '../../../data/liquifier/useLiquifierDeposit';
import useActiveAccountAddress from '../../../hooks/useActiveAccountAddress';
import useSearchParamState from '../../../hooks/useSearchParamState';
@@ -59,8 +59,10 @@ const LsStakeCard: FC = () => {
selectedPoolId,
} = useLsStore();
- const { execute: executeTanglePoolJoinTx } = useLsPoolJoinTx();
- const { execute: executeParachainMintTx, status: mintTxStatus } = useMintTx();
+ const { execute: executeTanglePoolJoinTx, status: tanglePoolJoinTxStatus } =
+ useLsPoolJoinTx();
+ const { execute: executeParachainMintTx, status: parachainMintTxStatus } =
+ useMintTx();
const performLiquifierDeposit = useLiquifierDeposit();
const activeAccountAddress = useActiveAccountAddress();
@@ -242,7 +244,10 @@ const LsStakeCard: FC = () => {
fromAmount === null ||
fromAmount.isZero()
}
- isLoading={mintTxStatus === TxStatus.PROCESSING}
+ isLoading={
+ parachainMintTxStatus === TxStatus.PROCESSING ||
+ tanglePoolJoinTxStatus === TxStatus.PROCESSING
+ }
loadingText="Processing"
onClick={handleStakeClick}
isFullWidth
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsFeePercentage.ts b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsFeePercentage.ts
index e7351fb7d..db26b4d05 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsFeePercentage.ts
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsFeePercentage.ts
@@ -63,9 +63,18 @@ const useLsFeePercentage = (
? null
: Number(rawLiquifierFeeOrError) / 100;
- return protocol.networkId === LsNetworkId.TANGLE_RESTAKING_PARACHAIN
- ? parachainFee
- : liquifierFeePercentageOrError;
+ switch (protocol.networkId) {
+ case LsNetworkId.TANGLE_RESTAKING_PARACHAIN:
+ return parachainFee;
+ case LsNetworkId.ETHEREUM_MAINNET_LIQUIFIER:
+ return liquifierFeePercentageOrError;
+ // Tangle networks with the `lst` pallet have no fees for
+ // joining or leaving pools as of now.
+ case LsNetworkId.TANGLE_LOCAL:
+ case LsNetworkId.TANGLE_MAINNET:
+ case LsNetworkId.TANGLE_TESTNET:
+ return 0;
+ }
};
export default useLsFeePercentage;
diff --git a/apps/tangle-dapp/constants/liquidStaking/types.ts b/apps/tangle-dapp/constants/liquidStaking/types.ts
index 54309f2ae..8058e4466 100644
--- a/apps/tangle-dapp/constants/liquidStaking/types.ts
+++ b/apps/tangle-dapp/constants/liquidStaking/types.ts
@@ -39,7 +39,17 @@ export type LsLiquifierProtocolId =
| LsProtocolId.LIVEPEER
| LsProtocolId.POLYGON;
-export type LsParachainChainId = Exclude;
+export type LsParachainChainId =
+ | LsProtocolId.POLKADOT
+ | LsProtocolId.PHALA
+ | LsProtocolId.MOONBEAM
+ | LsProtocolId.ASTAR
+ | LsProtocolId.MANTA;
+
+export type LsTangleNetworkId =
+ | LsProtocolId.TANGLE_MAINNET
+ | LsProtocolId.TANGLE_TESTNET
+ | LsProtocolId.TANGLE_LOCAL;
export enum LsToken {
DOT = 'DOT',
diff --git a/apps/tangle-dapp/data/liquidStaking/useLsExchangeRate.ts b/apps/tangle-dapp/data/liquidStaking/useLsExchangeRate.ts
index 513ea30fe..9df9b0a57 100644
--- a/apps/tangle-dapp/data/liquidStaking/useLsExchangeRate.ts
+++ b/apps/tangle-dapp/data/liquidStaking/useLsExchangeRate.ts
@@ -14,8 +14,8 @@ import calculateBnRatio from '../../utils/calculateBnRatio';
import getLsProtocolDef from '../../utils/liquidStaking/getLsProtocolDef';
import useContractRead from '../liquifier/useContractRead';
import { ContractReadOptions } from '../liquifier/useContractReadOnce';
-import usePolling from './usePolling';
import { useLsStore } from './useLsStore';
+import usePolling from './usePolling';
export enum ExchangeRateType {
NativeToDerivative,
@@ -147,8 +147,12 @@ const useLsExchangeRate = (type: ExchangeRateType) => {
switch (selectedNetworkId) {
case LsNetworkId.ETHEREUM_MAINNET_LIQUIFIER:
promise = fetchLiquifierExchangeRate();
+
+ break;
case LsNetworkId.TANGLE_RESTAKING_PARACHAIN:
promise = parachainExchangeRate;
+
+ break;
// Tangle networks with the `lst` pallet have a fixed exchange
// rate of 1:1.
case LsNetworkId.TANGLE_LOCAL:
@@ -166,7 +170,7 @@ const useLsExchangeRate = (type: ExchangeRateType) => {
}
setExchangeRate(newExchangeRate);
- }, [fetchLiquifierExchangeRate, parachainExchangeRate, protocol]);
+ }, [fetchLiquifierExchangeRate, parachainExchangeRate, selectedNetworkId]);
// Pause or resume ERC20-based exchange rate fetching based
// on whether the requested protocol is a parachain or an ERC20 token.
diff --git a/apps/tangle-dapp/data/liquidStaking/useLsStore.ts b/apps/tangle-dapp/data/liquidStaking/useLsStore.ts
index c12418f93..3e7d6d279 100644
--- a/apps/tangle-dapp/data/liquidStaking/useLsStore.ts
+++ b/apps/tangle-dapp/data/liquidStaking/useLsStore.ts
@@ -24,9 +24,11 @@ type Store = State & Actions;
export const useLsStore = create((set) => ({
selectedPoolId: null,
- selectedNetworkId: LsNetworkId.TANGLE_RESTAKING_PARACHAIN,
- selectedProtocolId: LsProtocolId.POLKADOT,
selectedNetworkEntities: new Set(),
+ // Default the selected network and protocol to the Tangle testnet,
+ // and tTNT, until liquid staking pools are deployed to mainnet.
+ selectedNetworkId: LsNetworkId.TANGLE_TESTNET,
+ selectedProtocolId: LsProtocolId.TANGLE_TESTNET,
setSelectedPoolId: (selectedPoolId) => set({ selectedPoolId }),
setSelectedProtocolId: (selectedProtocolId) => set({ selectedProtocolId }),
setSelectedNetworkEntities: (selectedNetworkEntities) =>
diff --git a/apps/tangle-dapp/utils/liquidStaking/getLsProtocolDef.ts b/apps/tangle-dapp/utils/liquidStaking/getLsProtocolDef.ts
index faa8bf5a0..a47aade40 100644
--- a/apps/tangle-dapp/utils/liquidStaking/getLsProtocolDef.ts
+++ b/apps/tangle-dapp/utils/liquidStaking/getLsProtocolDef.ts
@@ -1,7 +1,11 @@
import assert from 'assert';
import { LS_PROTOCOLS } from '../../constants/liquidStaking/constants';
-import { LsTangleNetworkDef } from '../../constants/liquidStaking/types';
+import {
+ LsLiquifierProtocolId,
+ LsTangleNetworkDef,
+ LsTangleNetworkId,
+} from '../../constants/liquidStaking/types';
import {
LsLiquifierProtocolDef,
LsParachainChainDef,
@@ -11,9 +15,11 @@ import {
type IdToDefMap = T extends LsParachainChainId
? LsParachainChainDef
- : T extends LsProtocolId.TANGLE_MAINNET
+ : T extends LsTangleNetworkId
? LsTangleNetworkDef
- : LsLiquifierProtocolDef;
+ : T extends LsLiquifierProtocolId
+ ? LsLiquifierProtocolDef
+ : never;
const getLsProtocolDef = (id: T): IdToDefMap => {
const result = LS_PROTOCOLS.find((def) => def.id === id);
From 77794888f4508d3e612ac943acfbd7e589beb46a Mon Sep 17 00:00:00 2001
From: yurixander <101931215+yurixander@users.noreply.github.com>
Date: Thu, 26 Sep 2024 00:40:42 -0400
Subject: [PATCH 25/54] feat(tangle-dapp): Create `useLsPoolUnbondTx` hook
---
.../stakeAndUnstake/LsAgnosticBalance.tsx | 2 +-
.../stakeAndUnstake/LsStakeCard.tsx | 2 +
.../stakeAndUnstake/LsUnstakeCard.tsx | 93 ++++++++++---------
.../stakeAndUnstake/useLsAgnosticBalance.ts | 27 +++++-
.../UnstakeRequestsTable.tsx | 5 +-
apps/tangle-dapp/constants/index.ts | 1 +
.../liquidStaking/adapters/tangleLocal.tsx | 2 +-
.../liquidStaking/adapters/tangleMainnet.tsx | 2 +-
.../liquidStaking/adapters/tangleTestnet.tsx | 2 +-
.../liquidStaking/tangle/useLsPoolBalance.ts | 49 ++++++++++
.../liquidStaking/tangle/useLsPoolUnbondTx.ts | 28 ++++++
apps/tangle-dapp/hooks/useTxNotification.tsx | 1 +
apps/tangle-dapp/utils/Optional.ts | 24 ++++-
13 files changed, 181 insertions(+), 57 deletions(-)
create mode 100644 apps/tangle-dapp/data/liquidStaking/tangle/useLsPoolBalance.ts
create mode 100644 apps/tangle-dapp/data/liquidStaking/tangle/useLsPoolUnbondTx.ts
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsAgnosticBalance.tsx b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsAgnosticBalance.tsx
index a558975dc..58d11a69e 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsAgnosticBalance.tsx
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsAgnosticBalance.tsx
@@ -14,10 +14,10 @@ import { twMerge } from 'tailwind-merge';
import { EMPTY_VALUE_PLACEHOLDER } from '../../../constants';
import { LS_DERIVATIVE_TOKEN_PREFIX } from '../../../constants/liquidStaking/constants';
import { LsNetworkId } from '../../../constants/liquidStaking/types';
+import { useLsStore } from '../../../data/liquidStaking/useLsStore';
import formatBn from '../../../utils/formatBn';
import getLsProtocolDef from '../../../utils/liquidStaking/getLsProtocolDef';
import useLsAgnosticBalance from './useLsAgnosticBalance';
-import { useLsStore } from '../../../data/liquidStaking/useLsStore';
export type LsAgnosticBalanceProps = {
isNative?: boolean;
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
index 0c68937c6..cda7cb3c0 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
@@ -61,8 +61,10 @@ const LsStakeCard: FC = () => {
const { execute: executeTanglePoolJoinTx, status: tanglePoolJoinTxStatus } =
useLsPoolJoinTx();
+
const { execute: executeParachainMintTx, status: parachainMintTxStatus } =
useMintTx();
+
const performLiquifierDeposit = useLiquifierDeposit();
const activeAccountAddress = useActiveAccountAddress();
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsUnstakeCard.tsx b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsUnstakeCard.tsx
index b37a5361a..2afd1a6b2 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsUnstakeCard.tsx
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsUnstakeCard.tsx
@@ -16,11 +16,12 @@ import {
LsProtocolId,
LsSearchParamKey,
} from '../../../constants/liquidStaking/types';
+import useRedeemTx from '../../../data/liquidStaking/parachain/useRedeemTx';
+import useLsPoolUnbondTx from '../../../data/liquidStaking/tangle/useLsPoolUnbondTx';
import useLsExchangeRate, {
ExchangeRateType,
} from '../../../data/liquidStaking/useLsExchangeRate';
import { useLsStore } from '../../../data/liquidStaking/useLsStore';
-import useRedeemTx from '../../../data/liquidStaking/parachain/useRedeemTx';
import useLiquifierUnlock from '../../../data/liquifier/useLiquifierUnlock';
import useActiveAccountAddress from '../../../hooks/useActiveAccountAddress';
import useSearchParamSync from '../../../hooks/useSearchParamSync';
@@ -34,7 +35,6 @@ import LsInput from './LsInput';
import SelectTokenModal from './SelectTokenModal';
import TotalDetailItem from './TotalDetailItem';
import UnstakePeriodDetailItem from './UnstakePeriodDetailItem';
-import UnstakeRequestSubmittedModal from './UnstakeRequestSubmittedModal';
import useLsChangeNetwork from './useLsChangeNetwork';
import useLsSpendingLimits from './useLsSpendingLimits';
@@ -44,14 +44,12 @@ const LsUnstakeCard: FC = () => {
const activeAccountAddress = useActiveAccountAddress();
const tryChangeNetwork = useLsChangeNetwork();
- const { selectedProtocolId, setSelectedProtocolId, selectedNetworkId } =
- useLsStore();
-
- const [didLiquifierUnlockSucceed, setDidLiquifierUnlockSucceed] =
- useState(false);
-
- const [isRequestSubmittedModalOpen, setIsRequestSubmittedModalOpen] =
- useState(false);
+ const {
+ selectedProtocolId,
+ setSelectedProtocolId,
+ selectedNetworkId,
+ selectedPoolId,
+ } = useLsStore();
// TODO: Won't both of these hooks be attempting to update the same state?
useSearchParamSync({
@@ -62,11 +60,11 @@ const LsUnstakeCard: FC = () => {
setValue: setSelectedProtocolId,
});
- const {
- execute: executeRedeemTx,
- status: redeemTxStatus,
- txHash: redeemTxHash,
- } = useRedeemTx();
+ const { execute: executeParachainRedeemTx, status: parachainRedeemTxStatus } =
+ useRedeemTx();
+
+ const { execute: executeTangleUnbondTx, status: tangleUnbondTxStatus } =
+ useLsPoolUnbondTx();
const performLiquifierUnlock = useLiquifierUnlock();
@@ -94,6 +92,11 @@ const LsUnstakeCard: FC = () => {
stringify: (value) => value?.toString(),
});
+ const isTangleNetwork =
+ selectedNetworkId === LsNetworkId.TANGLE_LOCAL ||
+ selectedNetworkId === LsNetworkId.TANGLE_MAINNET ||
+ selectedNetworkId === LsNetworkId.TANGLE_TESTNET;
+
const handleUnstakeClick = useCallback(async () => {
// Cannot perform transaction: Amount not set.
if (fromAmount === null) {
@@ -102,9 +105,9 @@ const LsUnstakeCard: FC = () => {
if (
selectedProtocol.networkId === LsNetworkId.TANGLE_RESTAKING_PARACHAIN &&
- executeRedeemTx !== null
+ executeParachainRedeemTx !== null
) {
- executeRedeemTx({
+ return executeParachainRedeemTx({
amount: fromAmount,
currency: selectedProtocol.currency,
});
@@ -112,16 +115,28 @@ const LsUnstakeCard: FC = () => {
selectedProtocol.networkId === LsNetworkId.ETHEREUM_MAINNET_LIQUIFIER &&
performLiquifierUnlock !== null
) {
- setDidLiquifierUnlockSucceed(false);
-
- const success = await performLiquifierUnlock(
- selectedProtocol.id,
- fromAmount,
- );
+ return performLiquifierUnlock(selectedProtocol.id, fromAmount);
+ }
- setDidLiquifierUnlockSucceed(success);
+ if (
+ isTangleNetwork &&
+ executeTangleUnbondTx !== null &&
+ selectedPoolId !== null
+ ) {
+ return executeTangleUnbondTx({
+ points: fromAmount,
+ poolId: selectedPoolId,
+ });
}
- }, [executeRedeemTx, fromAmount, performLiquifierUnlock, selectedProtocol]);
+ }, [
+ executeParachainRedeemTx,
+ executeTangleUnbondTx,
+ fromAmount,
+ isTangleNetwork,
+ performLiquifierUnlock,
+ selectedPoolId,
+ selectedProtocol,
+ ]);
const toAmount = useMemo(() => {
if (fromAmount === null || exchangeRate === null) {
@@ -140,14 +155,6 @@ const LsUnstakeCard: FC = () => {
return [{ address: '0x123456' as any, amount: new BN(100), decimals: 18 }];
}, []);
- // Open the request submitted modal when the redeem
- // transaction is complete.
- useEffect(() => {
- if (redeemTxStatus === TxStatus.COMPLETE || didLiquifierUnlockSucceed) {
- setIsRequestSubmittedModalOpen(true);
- }
- }, [didLiquifierUnlockSucceed, redeemTxStatus]);
-
// Reset the input amount when the network changes.
useEffect(() => {
setFromAmount(null);
@@ -161,12 +168,15 @@ const LsUnstakeCard: FC = () => {
/>
);
- // TODO: Also check if the user has enough balance to unstake.
+ // TODO: Also check if the user has enough balance to unstake. Convert this into a self-executing function to break down the complexity of a one-liner.
const canCallUnstake =
(selectedProtocol.networkId === LsNetworkId.TANGLE_RESTAKING_PARACHAIN &&
- executeRedeemTx !== null) ||
+ executeParachainRedeemTx !== null) ||
(selectedProtocol.networkId === LsNetworkId.ETHEREUM_MAINNET_LIQUIFIER &&
- performLiquifierUnlock !== null);
+ performLiquifierUnlock !== null) ||
+ (isTangleNetwork &&
+ executeTangleUnbondTx !== null &&
+ selectedPoolId !== null);
return (
<>
@@ -237,7 +247,10 @@ const LsUnstakeCard: FC = () => {
fromAmount === null ||
fromAmount.isZero()
}
- isLoading={redeemTxStatus === TxStatus.PROCESSING}
+ isLoading={
+ parachainRedeemTxStatus === TxStatus.PROCESSING ||
+ tangleUnbondTxStatus === TxStatus.PROCESSING
+ }
loadingText="Processing"
onClick={handleUnstakeClick}
isFullWidth
@@ -251,12 +264,6 @@ const LsUnstakeCard: FC = () => {
onClose={() => setIsSelectTokenModalOpen(false)}
onTokenSelect={handleTokenSelect}
/>
-
- setIsRequestSubmittedModalOpen(false)}
- txHash={redeemTxHash}
- />
>
);
};
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsAgnosticBalance.ts b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsAgnosticBalance.ts
index 2a3045e03..b6a017a82 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsAgnosticBalance.ts
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsAgnosticBalance.ts
@@ -7,12 +7,13 @@ import LIQUIFIER_TG_TOKEN_ABI from '../../../constants/liquidStaking/liquifierTg
import { LsNetworkId } from '../../../constants/liquidStaking/types';
import useBalances from '../../../data/balances/useBalances';
import useParachainBalances from '../../../data/liquidStaking/parachain/useParachainBalances';
+import useLsPoolBalance from '../../../data/liquidStaking/tangle/useLsPoolBalance';
+import { useLsStore } from '../../../data/liquidStaking/useLsStore';
import usePolling from '../../../data/liquidStaking/usePolling';
import useContractReadOnce from '../../../data/liquifier/useContractReadOnce';
import useActiveAccountAddress from '../../../hooks/useActiveAccountAddress';
import useEvmAddress20 from '../../../hooks/useEvmAddress';
import getLsProtocolDef from '../../../utils/liquidStaking/getLsProtocolDef';
-import { useLsStore } from '../../../data/liquidStaking/useLsStore';
type BalanceUpdater = (
prevBalance: BN | null | typeof EMPTY_VALUE_PLACEHOLDER,
@@ -51,6 +52,7 @@ const useLsAgnosticBalance = (isNative: boolean) => {
const { nativeBalances, liquidBalances } = useParachainBalances();
const { free: tangleFreeBalance } = useBalances();
const { selectedProtocolId, selectedNetworkId } = useLsStore();
+ const tangleAssetBalance = useLsPoolBalance();
// TODO: Why not use the subscription hook variants (useContractRead) instead of manually utilizing usePolling?
const readErc20 = useContractReadOnce(erc20Abi);
@@ -139,12 +141,29 @@ const useLsAgnosticBalance = (isNative: boolean) => {
// Update the balance to the Tangle balance when the Tangle
// network is the active network.
useEffect(() => {
- if (!isLsTangleNetwork || tangleFreeBalance === null) {
+ if (!isLsTangleNetwork) {
+ return;
+ }
+ // Relevant balance hasn't loaded yet or isn't available.
+ else if (
+ (isNative && tangleFreeBalance === null) ||
+ (!isNative && tangleAssetBalance === null)
+ ) {
return;
}
- setBalance(createBalanceStateUpdater(tangleFreeBalance));
- }, [protocol.networkId, tangleFreeBalance, isLsTangleNetwork]);
+ setBalance(
+ createBalanceStateUpdater(
+ isNative ? tangleFreeBalance : tangleAssetBalance,
+ ),
+ );
+ }, [
+ protocol.networkId,
+ tangleFreeBalance,
+ isLsTangleNetwork,
+ tangleAssetBalance,
+ isNative,
+ ]);
return { balance, isRefreshing };
};
diff --git a/apps/tangle-dapp/components/LiquidStaking/unstakeRequestsTable/UnstakeRequestsTable.tsx b/apps/tangle-dapp/components/LiquidStaking/unstakeRequestsTable/UnstakeRequestsTable.tsx
index b776a3efa..abc81f56c 100644
--- a/apps/tangle-dapp/components/LiquidStaking/unstakeRequestsTable/UnstakeRequestsTable.tsx
+++ b/apps/tangle-dapp/components/LiquidStaking/unstakeRequestsTable/UnstakeRequestsTable.tsx
@@ -320,18 +320,19 @@ const UnstakeRequestsTable: FC = () => {
/>
)}
+ {/* TODO: Assert that the id is either parachain or liquifier, if it isn't then we might need to hide this unstake requests table and show a specific one for Tangle networks (LS pools). */}
{isLsParachainChainId(selectedProtocolId) ? (
- ) : (
+ ) : isLiquifierProtocolId(selectedProtocolId) ? (
- )}
+ ) : undefined}
)}
diff --git a/apps/tangle-dapp/constants/index.ts b/apps/tangle-dapp/constants/index.ts
index a713620f6..b7e6d0ba2 100644
--- a/apps/tangle-dapp/constants/index.ts
+++ b/apps/tangle-dapp/constants/index.ts
@@ -62,6 +62,7 @@ export enum TxName {
LS_LIQUIFIER_UNLOCK = 'liquifier unlock',
LS_LIQUIFIER_WITHDRAW = 'liquifier withdraw',
LS_TANGLE_POOL_JOIN = 'join liquid staking pool',
+ LS_TANGLE_POOL_UNBOND = 'unbond from liquid staking pool',
}
export const PAYMENT_DESTINATION_OPTIONS: StakingRewardsDestinationDisplayText[] =
diff --git a/apps/tangle-dapp/data/liquidStaking/adapters/tangleLocal.tsx b/apps/tangle-dapp/data/liquidStaking/adapters/tangleLocal.tsx
index 9afc6fc43..3dff97eeb 100644
--- a/apps/tangle-dapp/data/liquidStaking/adapters/tangleLocal.tsx
+++ b/apps/tangle-dapp/data/liquidStaking/adapters/tangleLocal.tsx
@@ -18,7 +18,7 @@ const TANGLE_LOCAL = {
decimals: TANGLE_TOKEN_DECIMALS,
rpcEndpoint: TANGLE_LOCAL_DEV_NETWORK.wsRpcEndpoint,
timeUnit: CrossChainTimeUnit.POLKADOT_ERA,
- unstakingPeriod: 28,
+ unstakingPeriod: 14,
ss58Prefix: TANGLE_LOCAL_DEV_NETWORK.ss58Prefix,
tangleNetwork: TANGLE_LOCAL_DEV_NETWORK,
} as const satisfies LsTangleNetworkDef;
diff --git a/apps/tangle-dapp/data/liquidStaking/adapters/tangleMainnet.tsx b/apps/tangle-dapp/data/liquidStaking/adapters/tangleMainnet.tsx
index 71ad06ff2..8b61eb3e9 100644
--- a/apps/tangle-dapp/data/liquidStaking/adapters/tangleMainnet.tsx
+++ b/apps/tangle-dapp/data/liquidStaking/adapters/tangleMainnet.tsx
@@ -24,7 +24,7 @@ const TANGLE_MAINNET = {
? TANGLE_MAINNET_NETWORK.wsRpcEndpoint
: TANGLE_LOCAL_DEV_NETWORK.wsRpcEndpoint,
timeUnit: CrossChainTimeUnit.POLKADOT_ERA,
- unstakingPeriod: 28,
+ unstakingPeriod: 14,
ss58Prefix: TANGLE_MAINNET_NETWORK.ss58Prefix,
tangleNetwork: TANGLE_MAINNET_NETWORK,
} as const satisfies LsTangleNetworkDef;
diff --git a/apps/tangle-dapp/data/liquidStaking/adapters/tangleTestnet.tsx b/apps/tangle-dapp/data/liquidStaking/adapters/tangleTestnet.tsx
index a20d054af..1e9a8f258 100644
--- a/apps/tangle-dapp/data/liquidStaking/adapters/tangleTestnet.tsx
+++ b/apps/tangle-dapp/data/liquidStaking/adapters/tangleTestnet.tsx
@@ -25,7 +25,7 @@ const TANGLE_TESTNET = {
? TANGLE_MAINNET_NETWORK.wsRpcEndpoint
: TANGLE_LOCAL_DEV_NETWORK.wsRpcEndpoint,
timeUnit: CrossChainTimeUnit.POLKADOT_ERA,
- unstakingPeriod: 28,
+ unstakingPeriod: 14,
ss58Prefix: TANGLE_MAINNET_NETWORK.ss58Prefix,
tangleNetwork: TANGLE_TESTNET_NATIVE_NETWORK,
} as const satisfies LsTangleNetworkDef;
diff --git a/apps/tangle-dapp/data/liquidStaking/tangle/useLsPoolBalance.ts b/apps/tangle-dapp/data/liquidStaking/tangle/useLsPoolBalance.ts
new file mode 100644
index 000000000..14a8f3c28
--- /dev/null
+++ b/apps/tangle-dapp/data/liquidStaking/tangle/useLsPoolBalance.ts
@@ -0,0 +1,49 @@
+import { BN_ZERO } from '@polkadot/util';
+import { useCallback, useMemo } from 'react';
+
+import useApiRx from '../../../hooks/useApiRx';
+import useNetworkFeatures from '../../../hooks/useNetworkFeatures';
+import useSubstrateAddress from '../../../hooks/useSubstrateAddress';
+import { NetworkFeature } from '../../../types';
+import { useLsStore } from '../useLsStore';
+
+const useLsPoolBalance = () => {
+ const substrateAddress = useSubstrateAddress();
+ const networkFeatures = useNetworkFeatures();
+ const isSupported = networkFeatures.includes(NetworkFeature.LsPools);
+ const { selectedPoolId } = useLsStore();
+
+ const { result: tanglePoolAssetAccountOpt } = useApiRx(
+ useCallback(
+ (api) => {
+ // The liquid staking pools functionality isn't available on the active
+ // network, the user hasn't selected a pool yet, or there is no active
+ // account.
+ if (
+ !isSupported ||
+ selectedPoolId === null ||
+ substrateAddress === null
+ ) {
+ return null;
+ }
+
+ return api.query.assets.account(selectedPoolId, substrateAddress);
+ },
+ [isSupported, selectedPoolId, substrateAddress],
+ ),
+ );
+
+ const derivativeBalanceOpt = useMemo(() => {
+ if (tanglePoolAssetAccountOpt === null) {
+ return null;
+ } else if (tanglePoolAssetAccountOpt.isNone) {
+ return BN_ZERO;
+ }
+
+ return tanglePoolAssetAccountOpt.unwrap().balance.toBn();
+ }, [tanglePoolAssetAccountOpt]);
+
+ return derivativeBalanceOpt;
+};
+
+export default useLsPoolBalance;
diff --git a/apps/tangle-dapp/data/liquidStaking/tangle/useLsPoolUnbondTx.ts b/apps/tangle-dapp/data/liquidStaking/tangle/useLsPoolUnbondTx.ts
new file mode 100644
index 000000000..b72bd79a1
--- /dev/null
+++ b/apps/tangle-dapp/data/liquidStaking/tangle/useLsPoolUnbondTx.ts
@@ -0,0 +1,28 @@
+import { BN } from '@polkadot/util';
+import { useCallback } from 'react';
+
+import { TxName } from '../../../constants';
+import {
+ SubstrateTxFactory,
+ useSubstrateTxWithNotification,
+} from '../../../hooks/useSubstrateTx';
+
+export type LsPoolUnbondTxContext = {
+ poolId: number;
+ points: BN;
+};
+
+const useLsPoolUnbondTx = () => {
+ const substrateTxFactory: SubstrateTxFactory
=
+ useCallback(async (api, activeSubstrateAddress, { poolId, points }) => {
+ return api.tx.lst.unbond({ Id: activeSubstrateAddress }, poolId, points);
+ }, []);
+
+ // TODO: Add EVM support once precompile(s) for the `lst` pallet are implemented on Tangle.
+ return useSubstrateTxWithNotification(
+ TxName.LS_TANGLE_POOL_UNBOND,
+ substrateTxFactory,
+ );
+};
+
+export default useLsPoolUnbondTx;
diff --git a/apps/tangle-dapp/hooks/useTxNotification.tsx b/apps/tangle-dapp/hooks/useTxNotification.tsx
index 6c05ff185..f4b5e522a 100644
--- a/apps/tangle-dapp/hooks/useTxNotification.tsx
+++ b/apps/tangle-dapp/hooks/useTxNotification.tsx
@@ -37,6 +37,7 @@ const SUCCESS_MESSAGES: Record = {
[TxName.LS_LIQUIFIER_UNLOCK]: 'Liquifier unlock successful',
[TxName.LS_LIQUIFIER_WITHDRAW]: 'Liquifier withdrawal successful',
[TxName.LS_TANGLE_POOL_JOIN]: 'Joined liquid staking pool',
+ [TxName.LS_TANGLE_POOL_UNBOND]: 'Unbonded from liquid staking pool',
};
const makeKey = (txName: TxName): `${TxName}-tx-notification` =>
diff --git a/apps/tangle-dapp/utils/Optional.ts b/apps/tangle-dapp/utils/Optional.ts
index ac952ecb4..00ebd86ef 100644
--- a/apps/tangle-dapp/utils/Optional.ts
+++ b/apps/tangle-dapp/utils/Optional.ts
@@ -19,9 +19,9 @@
*
* @example
* ```
- * const value = new Optional(42);
+ * const valueOpt = Optional.new(42);
*
- * if (value.value !== null) {
+ * if (valueOpt.value !== null) {
* console.log(value.value);
* } else {
* console.log('Value is not present!');
@@ -29,6 +29,14 @@
* ```
*/
class Optional> {
+ static empty>(): Optional {
+ return new Optional();
+ }
+
+ static new>(value: T): Optional {
+ return new Optional(value);
+ }
+
readonly value: T | null;
constructor(value?: T) {
@@ -37,10 +45,18 @@ class Optional> {
map>(f: (value: T) => U): Optional {
if (this.value === null) {
- return new Optional();
+ return Optional.empty();
+ }
+
+ return Optional.new(f(this.value));
+ }
+
+ unwrapOrThrow(): T {
+ if (this.value === null) {
+ throw new Error('Value is not present!');
}
- return new Optional(f(this.value));
+ return this.value;
}
get isPresent(): boolean {
From 941fb7c90e2f0f8700c37828ca9fb37306332b95 Mon Sep 17 00:00:00 2001
From: yurixander <101931215+yurixander@users.noreply.github.com>
Date: Fri, 27 Sep 2024 03:44:28 -0400
Subject: [PATCH 26/54] ci(tangle-dapp): Fix lint errors
---
.../constants/liquidStaking/types.ts | 17 +++++++----------
.../liquidStaking/adapters/tangleMainnet.tsx | 10 ++--------
.../liquidStaking/adapters/tangleTestnet.tsx | 13 +++----------
.../utils/liquidStaking/getLsTangleNetwork.ts | 2 +-
4 files changed, 13 insertions(+), 29 deletions(-)
diff --git a/apps/tangle-dapp/constants/liquidStaking/types.ts b/apps/tangle-dapp/constants/liquidStaking/types.ts
index 8058e4466..9e1bb6d02 100644
--- a/apps/tangle-dapp/constants/liquidStaking/types.ts
+++ b/apps/tangle-dapp/constants/liquidStaking/types.ts
@@ -4,6 +4,12 @@ import {
} from '@polkadot/types/lookup';
import { BN } from '@polkadot/util';
import { HexString } from '@polkadot/util/types';
+import {
+ TANGLE_LOCAL_DEV_NETWORK,
+ TANGLE_MAINNET_NETWORK,
+ TANGLE_TESTNET_NATIVE_NETWORK,
+} from '@webb-tools/webb-ui-components/constants/networks';
+import { Network as TangleNetwork } from '@webb-tools/webb-ui-components/constants/networks';
import {
LsNetworkEntityAdapter,
@@ -11,12 +17,6 @@ import {
} from '../../data/liquidStaking/adapter';
import { SubstrateAddress } from '../../types/utils';
import { CrossChainTimeUnit } from '../../utils/CrossChainTime';
-import {
- TANGLE_LOCAL_DEV_NETWORK,
- TANGLE_MAINNET_NETWORK,
- TANGLE_TESTNET_NATIVE_NETWORK,
- Network as TangleNetwork,
-} from '../../../../libs/webb-ui-components/src/constants/networks';
export enum LsProtocolId {
POLKADOT,
@@ -99,10 +99,7 @@ export interface LsTangleNetworkDef extends ProtocolDefCommon {
| LsNetworkId.TANGLE_MAINNET
| LsNetworkId.TANGLE_TESTNET
| LsNetworkId.TANGLE_LOCAL;
- id:
- | LsProtocolId.TANGLE_MAINNET
- | LsProtocolId.TANGLE_TESTNET
- | LsProtocolId.TANGLE_LOCAL;
+ id: LsTangleNetworkId;
token: LsToken.TNT | LsToken.TTNT;
rpcEndpoint: string;
ss58Prefix:
diff --git a/apps/tangle-dapp/data/liquidStaking/adapters/tangleMainnet.tsx b/apps/tangle-dapp/data/liquidStaking/adapters/tangleMainnet.tsx
index 8b61eb3e9..6e908966a 100644
--- a/apps/tangle-dapp/data/liquidStaking/adapters/tangleMainnet.tsx
+++ b/apps/tangle-dapp/data/liquidStaking/adapters/tangleMainnet.tsx
@@ -1,10 +1,6 @@
import { TANGLE_TOKEN_DECIMALS } from '@webb-tools/dapp-config';
-import {
- TANGLE_LOCAL_DEV_NETWORK,
- TANGLE_MAINNET_NETWORK,
-} from '@webb-tools/webb-ui-components/constants/networks';
+import { TANGLE_MAINNET_NETWORK } from '@webb-tools/webb-ui-components/constants/networks';
-import { IS_PRODUCTION_ENV } from '../../../constants/env';
import {
LsNetworkId,
LsProtocolId,
@@ -20,9 +16,7 @@ const TANGLE_MAINNET = {
token: LsToken.TNT,
chainIconFileName: 'tangle',
decimals: TANGLE_TOKEN_DECIMALS,
- rpcEndpoint: IS_PRODUCTION_ENV
- ? TANGLE_MAINNET_NETWORK.wsRpcEndpoint
- : TANGLE_LOCAL_DEV_NETWORK.wsRpcEndpoint,
+ rpcEndpoint: TANGLE_MAINNET_NETWORK.wsRpcEndpoint,
timeUnit: CrossChainTimeUnit.POLKADOT_ERA,
unstakingPeriod: 14,
ss58Prefix: TANGLE_MAINNET_NETWORK.ss58Prefix,
diff --git a/apps/tangle-dapp/data/liquidStaking/adapters/tangleTestnet.tsx b/apps/tangle-dapp/data/liquidStaking/adapters/tangleTestnet.tsx
index 1e9a8f258..01fb3e36c 100644
--- a/apps/tangle-dapp/data/liquidStaking/adapters/tangleTestnet.tsx
+++ b/apps/tangle-dapp/data/liquidStaking/adapters/tangleTestnet.tsx
@@ -1,11 +1,6 @@
import { TANGLE_TOKEN_DECIMALS } from '@webb-tools/dapp-config';
-import {
- TANGLE_LOCAL_DEV_NETWORK,
- TANGLE_MAINNET_NETWORK,
- TANGLE_TESTNET_NATIVE_NETWORK,
-} from '@webb-tools/webb-ui-components/constants/networks';
+import { TANGLE_TESTNET_NATIVE_NETWORK } from '@webb-tools/webb-ui-components/constants/networks';
-import { IS_PRODUCTION_ENV } from '../../../constants/env';
import {
LsNetworkId,
LsProtocolId,
@@ -21,12 +16,10 @@ const TANGLE_TESTNET = {
token: LsToken.TNT,
chainIconFileName: 'tangle',
decimals: TANGLE_TOKEN_DECIMALS,
- rpcEndpoint: IS_PRODUCTION_ENV
- ? TANGLE_MAINNET_NETWORK.wsRpcEndpoint
- : TANGLE_LOCAL_DEV_NETWORK.wsRpcEndpoint,
+ rpcEndpoint: TANGLE_TESTNET_NATIVE_NETWORK.wsRpcEndpoint,
timeUnit: CrossChainTimeUnit.POLKADOT_ERA,
unstakingPeriod: 14,
- ss58Prefix: TANGLE_MAINNET_NETWORK.ss58Prefix,
+ ss58Prefix: TANGLE_TESTNET_NATIVE_NETWORK.ss58Prefix,
tangleNetwork: TANGLE_TESTNET_NATIVE_NETWORK,
} as const satisfies LsTangleNetworkDef;
diff --git a/apps/tangle-dapp/utils/liquidStaking/getLsTangleNetwork.ts b/apps/tangle-dapp/utils/liquidStaking/getLsTangleNetwork.ts
index e0926314c..6d0924c7b 100644
--- a/apps/tangle-dapp/utils/liquidStaking/getLsTangleNetwork.ts
+++ b/apps/tangle-dapp/utils/liquidStaking/getLsTangleNetwork.ts
@@ -7,8 +7,8 @@ import {
TANGLE_TESTNET_NATIVE_NETWORK,
} from '@webb-tools/webb-ui-components/constants/networks';
-import { LsNetworkId } from '../../constants/liquidStaking/types';
import { IS_PRODUCTION_ENV } from '../../constants/env';
+import { LsNetworkId } from '../../constants/liquidStaking/types';
// TODO: Obtain the Tangle network directly from the adapter's `tangleNetwork` property instead of using this helper method.
const getLsTangleNetwork = (networkId: LsNetworkId): Network | null => {
From 4669f026107f5b9916ca2cce9e186764f84986be Mon Sep 17 00:00:00 2001
From: yurixander <101931215+yurixander@users.noreply.github.com>
Date: Fri, 27 Sep 2024 04:04:30 -0400
Subject: [PATCH 27/54] fix(tangle-dapp): Use `switchNetwork` instead of
`setNetwork`
---
.../stakeAndUnstake/LsStakeCard.tsx | 10 ++++----
.../stakeAndUnstake/useLsChangeNetwork.ts | 24 ++++---------------
apps/tangle-dapp/hooks/useNetworkSwitcher.ts | 6 +++--
3 files changed, 14 insertions(+), 26 deletions(-)
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
index cda7cb3c0..35437dba8 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
@@ -76,6 +76,11 @@ const LsStakeCard: FC = () => {
const selectedProtocol = getLsProtocolDef(selectedProtocolId);
const tryChangeNetwork = useLsChangeNetwork();
+ const isTangleNetwork =
+ selectedNetworkId === LsNetworkId.TANGLE_LOCAL ||
+ selectedNetworkId === LsNetworkId.TANGLE_MAINNET ||
+ selectedNetworkId === LsNetworkId.TANGLE_TESTNET;
+
// TODO: Not loading the correct protocol for: '?amount=123000000000000000000&protocol=7&network=1&action=stake'. When network=1, it switches to protocol=5 on load. Could this be because the protocol is reset to its default once the network is switched?
useSearchParamSync({
key: LsSearchParamKey.PROTOCOL_ID,
@@ -102,11 +107,6 @@ const LsStakeCard: FC = () => {
const exchangeRate =
exchangeRateOrError instanceof Error ? null : exchangeRateOrError;
- const isTangleNetwork =
- selectedNetworkId === LsNetworkId.TANGLE_LOCAL ||
- selectedNetworkId === LsNetworkId.TANGLE_MAINNET ||
- selectedNetworkId === LsNetworkId.TANGLE_TESTNET;
-
const handleStakeClick = useCallback(async () => {
// Not ready yet; no amount given.
if (fromAmount === null) {
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsChangeNetwork.ts b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsChangeNetwork.ts
index e40f30c8b..f467cc853 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsChangeNetwork.ts
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsChangeNetwork.ts
@@ -4,16 +4,15 @@ import { useCallback } from 'react';
import { LsNetworkId } from '../../../constants/liquidStaking/types';
import { NETWORK_FEATURE_MAP } from '../../../constants/networks';
-import useNetworkStore from '../../../context/useNetworkStore';
import { useLsStore } from '../../../data/liquidStaking/useLsStore';
+import useNetworkSwitcher from '../../../hooks/useNetworkSwitcher';
import { NetworkFeature } from '../../../types';
import getLsNetwork from '../../../utils/liquidStaking/getLsNetwork';
import getLsTangleNetwork from '../../../utils/liquidStaking/getLsTangleNetwork';
-import testRpcEndpointConnection from '../../NetworkSelector/testRpcEndpointConnection';
const useLsChangeNetwork = () => {
const { selectedNetworkId, setSelectedNetworkId } = useLsStore();
- const { setNetwork } = useNetworkStore();
+ const { switchNetwork } = useNetworkSwitcher();
const { notificationApi } = useWebbUI();
const tryChangeNetwork = useCallback(
@@ -48,24 +47,11 @@ const useLsChangeNetwork = () => {
return;
}
- // Try connecting to the new network.
- const isRpcUp = await testRpcEndpointConnection(
- tangleNetwork.wsRpcEndpoint,
- );
-
- if (!isRpcUp) {
- notificationApi({
- message: 'Failed to connect to the network',
- variant: 'error',
- });
-
- return;
+ if (await switchNetwork(tangleNetwork, false)) {
+ setSelectedNetworkId(newNetworkId);
}
-
- setSelectedNetworkId(newNetworkId);
- setNetwork(tangleNetwork);
},
- [notificationApi, selectedNetworkId, setNetwork, setSelectedNetworkId],
+ [notificationApi, selectedNetworkId, setSelectedNetworkId, switchNetwork],
);
return tryChangeNetwork;
diff --git a/apps/tangle-dapp/hooks/useNetworkSwitcher.ts b/apps/tangle-dapp/hooks/useNetworkSwitcher.ts
index 9d79e26af..8d0516081 100644
--- a/apps/tangle-dapp/hooks/useNetworkSwitcher.ts
+++ b/apps/tangle-dapp/hooks/useNetworkSwitcher.ts
@@ -75,7 +75,7 @@ const useNetworkSwitcher = () => {
async (newNetwork: Network, isCustom: boolean) => {
// Already on the requested network.
if (network.id === newNetwork.id) {
- return;
+ return true;
}
// Test connection to the new network.
else if (!(await testRpcEndpointConnection(newNetwork.wsRpcEndpoint))) {
@@ -84,7 +84,7 @@ const useNetworkSwitcher = () => {
message: `Unable to connect to the requested network: ${newNetwork.wsRpcEndpoint}`,
});
- return;
+ return false;
}
if (activeWallet !== undefined) {
@@ -122,6 +122,8 @@ const useNetworkSwitcher = () => {
setIsCustom(isCustom);
setNetwork(newNetwork);
+
+ return true;
},
[
activeWallet,
From 8f56acf5731885f48af9e53c9901c2a386d6b5e4 Mon Sep 17 00:00:00 2001
From: yurixander <101931215+yurixander@users.noreply.github.com>
Date: Fri, 27 Sep 2024 04:10:46 -0400
Subject: [PATCH 28/54] fix(tangle-dapp): Fix network mismatch on load bug
---
apps/tangle-dapp/app/liquid-staking/page.tsx | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/apps/tangle-dapp/app/liquid-staking/page.tsx b/apps/tangle-dapp/app/liquid-staking/page.tsx
index d6812958a..3f98607a4 100644
--- a/apps/tangle-dapp/app/liquid-staking/page.tsx
+++ b/apps/tangle-dapp/app/liquid-staking/page.tsx
@@ -1,6 +1,6 @@
'use client';
-import { FC } from 'react';
+import { FC, useEffect } from 'react';
import { LsValidatorTable } from '../../components/LiquidStaking/LsValidatorTable';
import LsStakeCard from '../../components/LiquidStaking/stakeAndUnstake/LsStakeCard';
@@ -8,8 +8,11 @@ import LsUnstakeCard from '../../components/LiquidStaking/stakeAndUnstake/LsUnst
import UnstakeRequestsTable from '../../components/LiquidStaking/unstakeRequestsTable/UnstakeRequestsTable';
import { LsSearchParamKey } from '../../constants/liquidStaking/types';
import LsPoolsTable from '../../containers/LsPoolsTable';
+import useNetworkStore from '../../context/useNetworkStore';
import { useLsStore } from '../../data/liquidStaking/useLsStore';
+import useNetworkSwitcher from '../../hooks/useNetworkSwitcher';
import useSearchParamState from '../../hooks/useSearchParamState';
+import getLsTangleNetwork from '../../utils/liquidStaking/getLsTangleNetwork';
import isLsParachainChainId from '../../utils/liquidStaking/isLsParachainChainId';
import TabListItem from '../restake/TabListItem';
import TabsList from '../restake/TabsList';
@@ -28,10 +31,22 @@ const LiquidStakingTokenPage: FC = () => {
value ? SearchParamAction.STAKE : SearchParamAction.UNSTAKE,
});
- const { selectedProtocolId } = useLsStore();
+ const { selectedProtocolId, selectedNetworkId } = useLsStore();
+ const { network } = useNetworkStore();
+ const { switchNetwork } = useNetworkSwitcher();
+ const lsTangleNetwork = getLsTangleNetwork(selectedNetworkId);
const isParachainChain = isLsParachainChainId(selectedProtocolId);
+ // Sync the network with the selected liquid staking network on load.
+ // It might differ initially if the user navigates to the page and
+ // the active network differs from the default liquid staking network.
+ useEffect(() => {
+ if (lsTangleNetwork !== null && lsTangleNetwork.id !== network.id) {
+ switchNetwork(lsTangleNetwork, false);
+ }
+ }, [lsTangleNetwork, network.id, selectedNetworkId, switchNetwork]);
+
return (
From fff064d0e7e45a3b62e1cd2e08fd5e57274d6818 Mon Sep 17 00:00:00 2001
From: yurixander <101931215+yurixander@users.noreply.github.com>
Date: Fri, 27 Sep 2024 04:44:17 -0400
Subject: [PATCH 29/54] refactor(tangle-dapp): Get rid of `TotalDetailItem`
component
---
.../stakeAndUnstake/FeeDetailItem.tsx | 6 +-
.../stakeAndUnstake/LsStakeCard.tsx | 25 ++---
.../stakeAndUnstake/LsUnstakeCard.tsx | 25 ++---
.../stakeAndUnstake/TotalDetailItem.tsx | 92 -------------------
.../stakeAndUnstake/useLsFeePercentage.ts | 4 +-
5 files changed, 33 insertions(+), 119 deletions(-)
delete mode 100644 apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/TotalDetailItem.tsx
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/FeeDetailItem.tsx b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/FeeDetailItem.tsx
index 7e1488ae7..f90b8bcfb 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/FeeDetailItem.tsx
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/FeeDetailItem.tsx
@@ -10,17 +10,17 @@ import DetailItem from './DetailItem';
import useLsFeePercentage from './useLsFeePercentage';
export type FeeDetailItemProps = {
- isMinting: boolean;
+ isStaking: boolean;
inputAmount: BN | null;
protocolId: LsProtocolId;
};
const FeeDetailItem: FC = ({
- isMinting,
+ isStaking,
inputAmount,
protocolId,
}) => {
- const feePercentage = useLsFeePercentage(protocolId, isMinting);
+ const feePercentage = useLsFeePercentage(protocolId, isStaking);
const protocol = getLsProtocolDef(protocolId);
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
index 35437dba8..0d219a35a 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsStakeCard.tsx
@@ -34,14 +34,15 @@ import useSearchParamState from '../../../hooks/useSearchParamState';
import useSearchParamSync from '../../../hooks/useSearchParamSync';
import { TxStatus } from '../../../hooks/useSubstrateTx';
import getLsProtocolDef from '../../../utils/liquidStaking/getLsProtocolDef';
+import scaleAmountByPercentage from '../../../utils/scaleAmountByPercentage';
import ExchangeRateDetailItem from './ExchangeRateDetailItem';
import FeeDetailItem from './FeeDetailItem';
import LsAgnosticBalance from './LsAgnosticBalance';
import LsFeeWarning from './LsFeeWarning';
import LsInput from './LsInput';
-import TotalDetailItem from './TotalDetailItem';
import UnstakePeriodDetailItem from './UnstakePeriodDetailItem';
import useLsChangeNetwork from './useLsChangeNetwork';
+import useLsFeePercentage from './useLsFeePercentage';
import useLsSpendingLimits from './useLsSpendingLimits';
const LsStakeCard: FC = () => {
@@ -146,13 +147,21 @@ const LsStakeCard: FC = () => {
selectedPoolId,
]);
+ const feePercentage = useLsFeePercentage(selectedProtocolId, true);
+
const toAmount = useMemo(() => {
- if (fromAmount === null || exchangeRate === null) {
+ if (
+ fromAmount === null ||
+ exchangeRate === null ||
+ typeof feePercentage !== 'number'
+ ) {
return null;
}
- return fromAmount.muln(exchangeRate);
- }, [fromAmount, exchangeRate]);
+ const feeAmount = scaleAmountByPercentage(fromAmount, feePercentage);
+
+ return fromAmount.muln(exchangeRate).sub(feeAmount);
+ }, [fromAmount, exchangeRate, feePercentage]);
const canCallStake =
(fromAmount !== null &&
@@ -224,15 +233,9 @@ const LsStakeCard: FC = () => {
-
-
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsUnstakeCard.tsx b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsUnstakeCard.tsx
index 2afd1a6b2..52bb6cb04 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsUnstakeCard.tsx
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/LsUnstakeCard.tsx
@@ -27,15 +27,16 @@ import useActiveAccountAddress from '../../../hooks/useActiveAccountAddress';
import useSearchParamSync from '../../../hooks/useSearchParamSync';
import { TxStatus } from '../../../hooks/useSubstrateTx';
import getLsProtocolDef from '../../../utils/liquidStaking/getLsProtocolDef';
+import scaleAmountByPercentage from '../../../utils/scaleAmountByPercentage';
import ExchangeRateDetailItem from './ExchangeRateDetailItem';
import FeeDetailItem from './FeeDetailItem';
import LsAgnosticBalance from './LsAgnosticBalance';
import LsFeeWarning from './LsFeeWarning';
import LsInput from './LsInput';
import SelectTokenModal from './SelectTokenModal';
-import TotalDetailItem from './TotalDetailItem';
import UnstakePeriodDetailItem from './UnstakePeriodDetailItem';
import useLsChangeNetwork from './useLsChangeNetwork';
+import useLsFeePercentage from './useLsFeePercentage';
import useLsSpendingLimits from './useLsSpendingLimits';
const LsUnstakeCard: FC = () => {
@@ -138,13 +139,21 @@ const LsUnstakeCard: FC = () => {
selectedProtocol,
]);
+ const feePercentage = useLsFeePercentage(selectedProtocolId, false);
+
const toAmount = useMemo(() => {
- if (fromAmount === null || exchangeRate === null) {
+ if (
+ fromAmount === null ||
+ exchangeRate === null ||
+ typeof feePercentage !== 'number'
+ ) {
return null;
}
- return fromAmount.muln(exchangeRate);
- }, [exchangeRate, fromAmount]);
+ const feeAmount = scaleAmountByPercentage(fromAmount, feePercentage);
+
+ return fromAmount.divn(exchangeRate).sub(feeAmount);
+ }, [exchangeRate, feePercentage, fromAmount]);
const handleTokenSelect = useCallback(() => {
setIsSelectTokenModalOpen(false);
@@ -225,13 +234,7 @@ const LsUnstakeCard: FC = () => {
-
-
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/TotalDetailItem.tsx b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/TotalDetailItem.tsx
deleted file mode 100644
index 86a19cff2..000000000
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/TotalDetailItem.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import { BN } from '@polkadot/util';
-import { FC, useMemo } from 'react';
-
-import { EMPTY_VALUE_PLACEHOLDER } from '../../../constants';
-import { LS_DERIVATIVE_TOKEN_PREFIX } from '../../../constants/liquidStaking/constants';
-import { LsProtocolId } from '../../../constants/liquidStaking/types';
-import useLsExchangeRate, {
- ExchangeRateType,
-} from '../../../data/liquidStaking/useLsExchangeRate';
-import formatBn from '../../../utils/formatBn';
-import getLsProtocolDef from '../../../utils/liquidStaking/getLsProtocolDef';
-import scaleAmountByPercentage from '../../../utils/scaleAmountByPercentage';
-import DetailItem from './DetailItem';
-import useLsFeePercentage from './useLsFeePercentage';
-
-export type TotalDetailItemProps = {
- isMinting: boolean;
- inputAmount: BN | null;
- protocolId: LsProtocolId;
-};
-
-const TotalDetailItem: FC = ({
- isMinting,
- inputAmount,
- protocolId,
-}) => {
- const feePercentage = useLsFeePercentage(protocolId, isMinting);
-
- const { exchangeRate } = useLsExchangeRate(
- isMinting
- ? ExchangeRateType.NativeToDerivative
- : ExchangeRateType.DerivativeToNative,
- );
-
- const protocol = getLsProtocolDef(protocolId);
-
- const totalAmount = useMemo(() => {
- if (
- inputAmount === null ||
- exchangeRate === null ||
- feePercentage === null
- ) {
- return null;
- }
- // Propagate errors.
- else if (feePercentage instanceof Error) {
- return feePercentage;
- } else if (exchangeRate instanceof Error) {
- return exchangeRate;
- }
-
- const feeAmount = scaleAmountByPercentage(inputAmount, feePercentage);
-
- return isMinting
- ? inputAmount.muln(exchangeRate).sub(feeAmount)
- : inputAmount.divn(exchangeRate).sub(feeAmount);
- }, [exchangeRate, feePercentage, inputAmount, isMinting]);
-
- const formattedTotalAmount = useMemo(() => {
- // Nothing to show if the input amount is not set.
- if (inputAmount === null) {
- return EMPTY_VALUE_PLACEHOLDER;
- }
- // Propagate error or loading state.
- else if (!(totalAmount instanceof BN)) {
- return totalAmount;
- }
-
- return formatBn(totalAmount, protocol.decimals, {
- includeCommas: true,
- });
- }, [inputAmount, totalAmount, protocol.decimals]);
-
- const token = isMinting
- ? `${LS_DERIVATIVE_TOKEN_PREFIX}${protocol.token}`
- : protocol.token;
-
- const value =
- typeof formattedTotalAmount === 'string'
- ? `${formattedTotalAmount} ${token}`
- : formattedTotalAmount;
-
- return (
-
- );
-};
-
-export default TotalDetailItem;
diff --git a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsFeePercentage.ts b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsFeePercentage.ts
index db26b4d05..0a4691201 100644
--- a/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsFeePercentage.ts
+++ b/apps/tangle-dapp/components/LiquidStaking/stakeAndUnstake/useLsFeePercentage.ts
@@ -13,7 +13,7 @@ import getLsProtocolDef from '../../../utils/liquidStaking/getLsProtocolDef';
const useLsFeePercentage = (
protocolId: LsProtocolId,
- isMinting: boolean,
+ isStaking: boolean,
): number | Error | null => {
const { result: parachainFees } = useParachainLsFees();
@@ -22,7 +22,7 @@ const useLsFeePercentage = (
const parachainFee =
parachainFees === null
? null
- : isMinting
+ : isStaking
? parachainFees.mintFeePercentage
: parachainFees.redeemFeePercentage;
From 75d118c0f4ecf1f91b4645a1a7b2281e4ef1f10b Mon Sep 17 00:00:00 2001
From: yurixander <101931215+yurixander@users.noreply.github.com>
Date: Fri, 27 Sep 2024 21:56:20 -0400
Subject: [PATCH 30/54] refactor(tangle-dapp): Start page merge process
---
.../app/liquid-staking/overview/page.tsx | 5 +-
.../LiquidStaking/VaultsAndAssetsTable.tsx | 190 -----------------
.../constants/liquidStaking/types.ts | 3 +-
apps/tangle-dapp/containers/LsPoolsTable.tsx | 12 --
.../LsPoolsTable2/LsPoolsTable2.tsx | 159 +++++++++++++++
.../LsPoolsTable2/LsProtocolsTable.tsx | 191 ++++++++++++++++++
.../containers/LsPoolsTable2/index.ts | 1 +
.../data/liquidStaking/useLsPools.ts | 24 +--
.../components/VaultsTable/AssetsTable.tsx | 78 -------
.../components/VaultsTable/VaultsTable.tsx | 92 ---------
.../src/components/VaultsTable/index.ts | 1 -
.../src/components/VaultsTable/types.ts | 16 --
.../src/components/index.ts | 2 +-
13 files changed, 368 insertions(+), 406 deletions(-)
delete mode 100644 apps/tangle-dapp/components/LiquidStaking/VaultsAndAssetsTable.tsx
create mode 100644 apps/tangle-dapp/containers/LsPoolsTable2/LsPoolsTable2.tsx
create mode 100644 apps/tangle-dapp/containers/LsPoolsTable2/LsProtocolsTable.tsx
create mode 100644 apps/tangle-dapp/containers/LsPoolsTable2/index.ts
delete mode 100644 libs/webb-ui-components/src/components/VaultsTable/AssetsTable.tsx
delete mode 100644 libs/webb-ui-components/src/components/VaultsTable/VaultsTable.tsx
delete mode 100644 libs/webb-ui-components/src/components/VaultsTable/index.ts
delete mode 100644 libs/webb-ui-components/src/components/VaultsTable/types.ts
diff --git a/apps/tangle-dapp/app/liquid-staking/overview/page.tsx b/apps/tangle-dapp/app/liquid-staking/overview/page.tsx
index ec2d8b4db..fac3a614f 100644
--- a/apps/tangle-dapp/app/liquid-staking/overview/page.tsx
+++ b/apps/tangle-dapp/app/liquid-staking/overview/page.tsx
@@ -1,7 +1,6 @@
-import { Typography } from '@webb-tools/webb-ui-components';
+import { LsProtocolsTable, Typography } from '@webb-tools/webb-ui-components';
import { FC } from 'react';
-import VaultsAndAssetsTable from '../../../components/LiquidStaking/VaultsAndAssetsTable';
import StatItem from '../../../components/StatItem';
const LiquidStakingPage: FC = () => {
@@ -28,7 +27,7 @@ const LiquidStakingPage: FC = () => {