196 lines
5.4 KiB
TypeScript
196 lines
5.4 KiB
TypeScript
import compact from 'lodash/compact';
|
|
import {
|
|
makeDataProvider,
|
|
makeDerivedDataProvider,
|
|
} from '@vegaprotocol/data-provider';
|
|
import * as Schema from '@vegaprotocol/types';
|
|
import BigNumber from 'bignumber.js';
|
|
import {
|
|
LiquidityProvidersDocument,
|
|
LiquidityProvisionsDocument,
|
|
type LiquidityProvidersQuery,
|
|
type LiquidityProvidersQueryVariables,
|
|
type LiquidityProvisionsQuery,
|
|
type LiquidityProvisionsQueryVariables,
|
|
type LiquidityProviderFieldsFragment,
|
|
type LiquidityProvisionFieldsFragment,
|
|
} from './__generated__/MarketLiquidity';
|
|
|
|
export type LiquidityProvisionFields = LiquidityProvisionFieldsFragment &
|
|
Schema.LiquiditySLAParameters & {
|
|
currentCommitmentAmount?: string;
|
|
currentFee?: string;
|
|
};
|
|
|
|
export const liquidityProvisionsDataProvider = makeDataProvider<
|
|
LiquidityProvisionsQuery,
|
|
LiquidityProvisionFields[],
|
|
never,
|
|
never,
|
|
LiquidityProvisionsQueryVariables
|
|
>({
|
|
query: LiquidityProvisionsDocument,
|
|
getData: (responseData: LiquidityProvisionsQuery | null) => {
|
|
return (responseData?.market?.liquidityProvisions?.edges
|
|
?.filter((n) => !!n)
|
|
.map((e) => {
|
|
let node;
|
|
if (!e?.node.pending && e?.node.current) {
|
|
node = {
|
|
...e?.node.current,
|
|
...responseData.market?.liquiditySLAParameters,
|
|
};
|
|
} else if (!e?.node.current && e?.node.pending) {
|
|
node = {
|
|
...e?.node.pending,
|
|
...responseData.market?.liquiditySLAParameters,
|
|
};
|
|
} else {
|
|
node = {
|
|
...e?.node.pending,
|
|
currentCommitmentAmount: e?.node.current.commitmentAmount,
|
|
currentFee: e?.node.current.fee,
|
|
...responseData.market?.liquiditySLAParameters,
|
|
};
|
|
}
|
|
return node;
|
|
}) ?? []) as LiquidityProvisionFields[];
|
|
},
|
|
});
|
|
|
|
export const lpDataProvider = makeDataProvider<
|
|
LiquidityProvidersQuery,
|
|
LiquidityProviderFieldsFragment[],
|
|
never,
|
|
never,
|
|
LiquidityProvidersQueryVariables
|
|
>({
|
|
query: LiquidityProvidersDocument,
|
|
getData: (data) => {
|
|
return (
|
|
data?.liquidityProviders?.edges.filter(Boolean).map((e) => e.node) ?? []
|
|
);
|
|
},
|
|
});
|
|
|
|
export type Filter = { partyId?: string; active?: boolean };
|
|
|
|
export const lpAggregatedDataProvider = makeDerivedDataProvider<
|
|
LiquidityProvisionData[],
|
|
never,
|
|
LiquidityProvisionsQueryVariables & { filter?: Filter }
|
|
>(
|
|
[
|
|
(callback, client, variables) =>
|
|
liquidityProvisionsDataProvider(callback, client, {
|
|
marketId: variables.marketId,
|
|
}),
|
|
(callback, client, variables) =>
|
|
lpDataProvider(callback, client, {
|
|
marketId: variables.marketId,
|
|
}),
|
|
],
|
|
(
|
|
[liquidityProvisions, liquidityProvider],
|
|
{ filter }
|
|
): LiquidityProvisionData[] => {
|
|
return getLiquidityProvision(
|
|
liquidityProvisions,
|
|
liquidityProvider,
|
|
filter
|
|
);
|
|
}
|
|
);
|
|
|
|
export const matchFilter = (filter: Filter, lp: LiquidityProvisionData) => {
|
|
if (filter.partyId && lp.party.id !== filter.partyId) {
|
|
return false;
|
|
}
|
|
if (
|
|
filter.active === true &&
|
|
lp.status !== Schema.LiquidityProvisionStatus.STATUS_ACTIVE &&
|
|
lp.status !== Schema.LiquidityProvisionStatus.STATUS_PENDING
|
|
) {
|
|
return false;
|
|
}
|
|
if (
|
|
filter.active === false &&
|
|
lp.status === Schema.LiquidityProvisionStatus.STATUS_ACTIVE
|
|
) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
export interface LiquidityProvisionData
|
|
extends Omit<LiquidityProvisionFields, '__typename'>,
|
|
Partial<LiquidityProviderFieldsFragment>,
|
|
Omit<Schema.LiquiditySLAParameters, '__typename'> {
|
|
assetDecimalPlaces?: number;
|
|
balance?: number;
|
|
averageEntryValuation?: string;
|
|
equityLikeShare?: string;
|
|
earmarkedFees?: number;
|
|
status: Schema.LiquidityProvisionStatus;
|
|
}
|
|
|
|
export const getLiquidityProvision = (
|
|
liquidityProvisions: LiquidityProvisionFields[],
|
|
liquidityProviders: LiquidityProviderFieldsFragment[],
|
|
filter?: Filter
|
|
): LiquidityProvisionData[] => {
|
|
return liquidityProvisions
|
|
.filter((lp) => {
|
|
if (
|
|
![
|
|
Schema.LiquidityProvisionStatus.STATUS_ACTIVE,
|
|
Schema.LiquidityProvisionStatus.STATUS_UNDEPLOYED,
|
|
Schema.LiquidityProvisionStatus.STATUS_PENDING,
|
|
].includes(lp.status)
|
|
) {
|
|
return false;
|
|
}
|
|
if (filter && !matchFilter(filter, lp)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
})
|
|
.map((liquidityProvision) => {
|
|
const liquidityProvider = liquidityProviders.find(
|
|
(f) => liquidityProvision.party.id === f.partyId
|
|
);
|
|
if (!liquidityProvider) return liquidityProvision;
|
|
const accounts = compact(
|
|
liquidityProvision.party.accountsConnection?.edges
|
|
).map((e) => e.node);
|
|
const bondAccounts = accounts?.filter(
|
|
(a) => a?.type === Schema.AccountType.ACCOUNT_TYPE_BOND
|
|
);
|
|
const feeAccounts = accounts?.filter(
|
|
(a) => a?.type === Schema.AccountType.ACCOUNT_TYPE_LP_LIQUIDITY_FEES
|
|
);
|
|
const balance =
|
|
bondAccounts
|
|
?.reduce(
|
|
(acc, a) => acc.plus(new BigNumber(a.balance ?? 0)),
|
|
new BigNumber(0)
|
|
)
|
|
.toNumber() ?? 0;
|
|
|
|
const earmarkedFees =
|
|
feeAccounts
|
|
?.reduce(
|
|
(acc, a) => acc.plus(new BigNumber(a.balance ?? 0)),
|
|
new BigNumber(0)
|
|
)
|
|
.toNumber() ?? 0;
|
|
return {
|
|
...liquidityProvision,
|
|
...liquidityProvider,
|
|
balance,
|
|
earmarkedFees,
|
|
__typename: undefined,
|
|
};
|
|
});
|
|
};
|