diff --git a/src/pages/pool/_id.vue b/src/pages/pool/_id.vue
index 32627dbd4..b58c6223a 100644
--- a/src/pages/pool/_id.vue
+++ b/src/pages/pool/_id.vue
@@ -36,6 +36,7 @@ import PoolRisks from '@/components/contextual/pages/pool/risks/PoolRisks.vue';
import { usePool } from '@/providers/local/pool.provider';
import { provideUserStaking } from '@/providers/local/user-staking.provider';
import { providerUserPools } from '@/providers/local/user-pools.provider';
+import PointsIncentivesCard from '@/components/contextual/pages/pool/staking/PointsIncentivesCard.vue';
const userStaking = provideUserStaking();
providerUserPools(userStaking);
@@ -157,6 +158,13 @@ const titleTokens = computed
(() => {
return orderedPoolTokens(pool.value, pool.value.tokens);
});
+const isPointsStakablePool = computed(() => {
+ if (!pool.value || POOLS.PointsGauges === undefined) return false;
+ return Object.keys(POOLS.PointsGauges).includes(poolId);
+});
+
+console.log('isPointsStakablePool', isPointsStakablePool);
+
const isStakablePool = computed(
(): boolean =>
POOLS.Stakable.VotingGaugePools.includes(poolId) ||
@@ -286,6 +294,12 @@ watch(
class="staking-incentives"
@set-restake-visibility="setRestakeVisibility"
/>
+
{
+ /**
+ * STATE
+ */
+
+ const poolId = ref(_poolId);
+ const poolAddress = computed((): string | undefined =>
+ poolId.value ? getAddressFromPoolId(poolId.value) : undefined
+ );
+
+ const pointsGaugeAddress = computed((): string | undefined | null => {
+ const gauges = configService.network.pools.PointsGauges;
+ if (!gauges || !poolId.value) return null;
+ return gauges[poolId.value] ? gauges[poolId.value] : null;
+ });
+
+ const {
+ data: _stakedShares,
+ isRefetching: isRefetchingStakedShares,
+ refetch: refetchStakedShares,
+ } = useStakedSharesQuery(
+ ref([
+ {
+ balance: '0',
+ gauge: {
+ id: pointsGaugeAddress.value,
+ poolAddress: poolAddress.value,
+ poolId: poolId.value,
+ totalSupply: '0',
+ isPreferentialGauge: true,
+ isKilled: false,
+ },
+ },
+ ] as GaugeShare[])
+ );
+
+ /**
+ * COMPOSABLES
+ */
+ const { balanceFor } = useTokens();
+ const { account, isWalletReady } = useWeb3();
+
+ // // Fetches all gauges for specified pool (incl. preferential gauge).
+ // const poolGaugesQuery = usePoolGaugesQuery(poolAddress);
+ // const { data: poolGauges, refetch: refetchPoolGauges } = poolGaugesQuery;
+
+ // // Access user data fetched on wallet connection/change.
+ // const { userGaugeSharesQuery, userBoostsQuery, stakedSharesQuery } =
+ // useUserData();
+ // const { data: userGaugeShares, refetch: refetchUserGaugeShares } =
+ // userGaugeSharesQuery;
+ // const { data: boostsMap, refetch: refetchUserBoosts } = userBoostsQuery;
+ // const {
+ // data: _stakedShares,
+ // refetch: refetchStakedShares,
+ // isRefetching: isRefetchingStakedShares,
+ // } = stakedSharesQuery;
+
+ /**
+ * COMPUTED
+ */
+ // const isLoading = computed(
+ // (): boolean =>
+ // isQueryLoading(poolGaugesQuery) ||
+ // (isWalletReady.value &&
+ // (isQueryLoading(stakedSharesQuery) ||
+ // isQueryLoading(userGaugeSharesQuery) ||
+ // isQueryLoading(userBoostsQuery)))
+ // );
+
+ const isLoading = computed((): boolean => !isWalletReady.value);
+
+ const isStakablePool = computed(
+ (): boolean => !!poolId.value && pointsGaugeAddress.value !== null
+ );
+
+ // User's staked shares for pool (onchain data).
+ const stakedShares = computed((): string => {
+ if (!poolId.value) return '0';
+
+ return _stakedShares?.value?.[poolId.value] || '0';
+ });
+
+ /**
+ * METHODS
+ */
+
+ /**
+ * Set current pool ID for this provider.
+ *
+ * @param {string} id - The pool ID to get staking data for.
+ */
+ function setCurrentPool(id: string) {
+ poolId.value = id;
+ }
+
+ // Triggers refetch of all queries in this provider.
+ async function refetchAllPoolStakingData() {
+ return Promise.all([refetchStakedShares()]);
+ }
+
+ /**
+ * stake
+ *
+ * Trigger stake transaction using the current user's full BPT balance for
+ * this pool.
+ */
+ // async function stake(): Promise {
+ // if (!poolAddress.value) throw new Error('No pool to stake.');
+ // if (!preferentialGaugeAddress.value) {
+ // throw new Error(
+ // `No preferential gauge found for this pool: ${poolId.value}`
+ // );
+ // }
+
+ // const gauge = new LiquidityGauge(preferentialGaugeAddress.value);
+ // // User's current full BPT balance for this pool.
+ // const userBptBalance = parseUnits(
+ // balanceFor(getAddress(poolAddress.value))
+ // );
+
+ // return await gauge.stake(userBptBalance);
+ // }
+
+ async function stakeForPoints(): Promise {
+ if (!poolAddress.value) throw new Error('No pool to stake.');
+ if (!pointsGaugeAddress.value) {
+ throw new Error(`No points gauge found for this pool: ${poolId.value}`);
+ }
+
+ const gauge = new LiquidityGauge(pointsGaugeAddress.value);
+ // User's current full BPT balance for this pool.
+ const userBptBalance = parseUnits(
+ balanceFor(getAddress(poolAddress.value))
+ );
+
+ return await gauge.stake(userBptBalance);
+ }
+
+ /**
+ * unstake
+ *
+ * Trigger unstake transaction using the first pool gauge that the user has a
+ * balance in.
+ */
+ // async function unstake(): Promise {
+ // if (!poolGauges.value?.pool?.gauges)
+ // throw new Error('Unable to unstake, no pool gauges');
+
+ // const gaugesWithUserBalance = await filterGaugesWhereUserHasBalance(
+ // poolGauges.value,
+ // account.value
+ // );
+ // const firstGaugeWithUserBalance = gaugesWithUserBalance[0];
+ // const gauge = new LiquidityGauge(firstGaugeWithUserBalance.id);
+ // const balance = await gauge.balance(account.value);
+ // return await gauge.unstake(balance);
+ // }
+
+ async function unstakeForPoints(): Promise {
+ if (!pointsGaugeAddress.value) {
+ throw new Error(`No points gauge found for this pool: ${poolId.value}`);
+ }
+ const gauge = new LiquidityGauge(pointsGaugeAddress.value);
+ const balance = await gauge.balance(account.value);
+ return await gauge.unstake(balance);
+ }
+
+ return {
+ isLoading,
+ stakedShares,
+ isStakablePool,
+ pointsGaugeAddress,
+ setCurrentPool,
+ isRefetchingStakedShares,
+ refetchStakedShares,
+ refetchAllPoolStakingData,
+ stakeForPoints,
+ unstakeForPoints,
+ };
+};
+
+/**
+ * Provide setup: response type + symbol.
+ */
+export type PoolPointsStakingProviderResponse = ReturnType<
+ typeof poolPointsStakingProvider
+>;
+export const PoolPointsStakingProviderSymbol: InjectionKey =
+ Symbol(symbolKeys.Providers.PoolPointsStaking);
+
+export function providePoolPointsStaking(poolId?: string) {
+ provide(PoolPointsStakingProviderSymbol, poolPointsStakingProvider(poolId));
+}
+
+export function usePoolPointsStaking(): PoolPointsStakingProviderResponse {
+ return safeInject(PoolPointsStakingProviderSymbol);
+}
diff --git a/src/providers/local/pool-staking.provider.ts b/src/providers/local/pool-staking.provider.ts
index f963cb990..1a62b44d7 100644
--- a/src/providers/local/pool-staking.provider.ts
+++ b/src/providers/local/pool-staking.provider.ts
@@ -26,11 +26,19 @@ export const poolStakingProvider = (_poolId?: string) => {
/**
* STATE
*/
+
const poolId = ref(_poolId);
const poolAddress = computed((): string | undefined =>
poolId.value ? getAddressFromPoolId(poolId.value) : undefined
);
+ // const isPointsPool = computed((): boolean => {
+ // if (!poolId.value) return false;
+ // return (
+ // configService.network.pools.PointsGauges?.[poolId.value] !== undefined
+ // );
+ // });
+
/**
* COMPOSABLES
*/
@@ -65,12 +73,20 @@ export const poolStakingProvider = (_poolId?: string) => {
isQueryLoading(userBoostsQuery)))
);
+ const isPointsLoading = computed((): boolean => !isWalletReady.value);
+
// The current preferential gauge for the specified pool.
const preferentialGaugeAddress = computed(
(): string | undefined | null =>
poolGauges.value?.pool?.preferentialGauge?.id
);
+ const pointsGaugeAddress = computed((): string | undefined | null => {
+ const gauges = configService.network.pools.PointsGauges;
+ if (!gauges || !poolId.value) return null;
+ return gauges[poolId.value] ? gauges[poolId.value] : null;
+ });
+
// Is it possible to stake this pool's BPT?
const isStakablePool = computed(
(): boolean =>
@@ -81,6 +97,10 @@ export const poolStakingProvider = (_poolId?: string) => {
)
);
+ const isStakablePoolForPoints = computed(
+ (): boolean => !!poolId.value && pointsGaugeAddress.value !== null
+ );
+
const gaugeTotalSupply = computed((): string => {
return poolGauges.value?.liquidityGauges?.[0]?.totalSupply || '0';
});
@@ -178,6 +198,21 @@ export const poolStakingProvider = (_poolId?: string) => {
return await gauge.stake(userBptBalance);
}
+ async function stakeForPoints(): Promise {
+ if (!poolAddress.value) throw new Error('No pool to stake.');
+ if (!pointsGaugeAddress.value) {
+ throw new Error(`No points gauge found for this pool: ${poolId.value}`);
+ }
+
+ const gauge = new LiquidityGauge(pointsGaugeAddress.value);
+ // User's current full BPT balance for this pool.
+ const userBptBalance = parseUnits(
+ balanceFor(getAddress(poolAddress.value))
+ );
+
+ return await gauge.stake(userBptBalance);
+ }
+
/**
* unstake
*
@@ -198,6 +233,15 @@ export const poolStakingProvider = (_poolId?: string) => {
return await gauge.unstake(balance);
}
+ async function unstakeForPoints(): Promise {
+ if (!pointsGaugeAddress.value) {
+ throw new Error(`No points gauge found for this pool: ${poolId.value}`);
+ }
+ const gauge = new LiquidityGauge(pointsGaugeAddress.value);
+ const balance = await gauge.balance(account.value);
+ return await gauge.unstake(balance);
+ }
+
/**
* Fetch preferential gauge address for pool.
*
@@ -233,19 +277,24 @@ export const poolStakingProvider = (_poolId?: string) => {
return {
isLoading,
+ isPointsLoading,
stakedShares,
isStakablePool,
+ isStakablePoolForPoints,
boost,
hasNonPrefGaugeBalance,
isRefetchingStakedShares,
refetchStakedShares,
preferentialGaugeAddress,
fetchPreferentialGaugeAddress,
+ pointsGaugeAddress,
gaugeTotalSupply,
setCurrentPool,
refetchAllPoolStakingData,
stake,
unstake,
+ stakeForPoints,
+ unstakeForPoints,
poolGauges,
};
};
diff --git a/src/providers/tokens.provider.ts b/src/providers/tokens.provider.ts
index 6beedabeb..004d31ec2 100644
--- a/src/providers/tokens.provider.ts
+++ b/src/providers/tokens.provider.ts
@@ -534,6 +534,7 @@ export const tokensProvider = (
const response = await axios.get(
`https://symm-prices.symmetric.workers.dev/${networkSlug}/prices/${tokenAddressesString}`
);
+ console.log(response);
let symmPrice = 0;
let rewardPrice = 0;
response.data.forEach(price => {
@@ -567,7 +568,11 @@ export const tokensProvider = (
// Inject veBAL because it's not in tokenlists.
const { veBAL } = configService.network.addresses;
await injectTokens([veBAL]);
- if (networkSlug === 'telos' || networkSlug === 'meter') {
+ if (
+ networkSlug === 'telos' ||
+ networkSlug === 'meter' ||
+ networkSlug === 'vana-moksha'
+ ) {
await getTokenPrices();
}
queriesEnabled.value = true;
@@ -624,7 +629,9 @@ export function provideTokens(
userSettings: UserSettingsResponse,
tokenLists: TokenListsResponse
) {
+ console.log('PROVIDE TOKENS');
const tokensResponse = tokensProvider(userSettings, tokenLists);
+
provide(TokensProviderSymbol, tokensResponse);
return tokensResponse;
}
diff --git a/src/services/api/graphql/generated/api-types.ts b/src/services/api/graphql/generated/api-types.ts
index 73429948f..26bd0f779 100644
--- a/src/services/api/graphql/generated/api-types.ts
+++ b/src/services/api/graphql/generated/api-types.ts
@@ -55,6 +55,9 @@ export enum GqlChain {
Zkevm = 'ZKEVM',
Telos = 'telos',
Meter = 'meter',
+ Taiko = 'taiko',
+ Etherlink = 'etherlink',
+ VanaMoksha = 'vana-moksha',
}
export type GqlContentNewsItem = {
diff --git a/src/services/api/graphql/mappers.ts b/src/services/api/graphql/mappers.ts
index 6e65537c7..c04015946 100644
--- a/src/services/api/graphql/mappers.ts
+++ b/src/services/api/graphql/mappers.ts
@@ -32,6 +32,12 @@ export function mapApiChain(
return Network.TELOS;
case 'meter':
return Network.METER;
+ case 'taiko':
+ return Network.TAIKO;
+ case 'etherlink':
+ return Network.ETHERLINK;
+ case 'vana-moksha':
+ return Network.VANAMOKSHA;
default:
throw new Error(`Unexpected API chain: ${apiChain}`);
diff --git a/src/types/pools.ts b/src/types/pools.ts
index 03ee428c5..521a9be04 100644
--- a/src/types/pools.ts
+++ b/src/types/pools.ts
@@ -162,6 +162,7 @@ export type Pools = {
// Pools that have additional rewards and therefore should be stakable but are not included in the VotingGaugePools list.
AllowList: string[];
};
+ PointsGauges?: Record;
Metadata: Record;
Deep: string[];
BoostedApr: string[];