From 9c507b145d4a016af8c494c10ac4fb9cc3460b87 Mon Sep 17 00:00:00 2001
From: Bob van der Helm <34470358+bobthebuidlr@users.noreply.github.com>
Date: Tue, 13 Feb 2024 16:55:14 +0100
Subject: [PATCH] perps: trading fee + expected price
---
src/components/perps/Module/ExpectedPrice.tsx | 28 ++
src/components/perps/Module/Summary.tsx | 29 +-
src/components/perps/Module/TradingFee.tsx | 15 +-
src/components/perps/Module/usePerpsModule.ts | 8 +-
src/configs/chains/neutron/pion-1.ts | 16 +-
src/hooks/perps/useTradingFee.ts | 21 --
src/hooks/perps/useTradingFeeAndPrice.ts | 77 +++++
.../generated/mars-perps/MarsPerps.client.ts | 202 +++++++++++---
.../mars-perps/MarsPerps.react-query.ts | 140 +++++++++-
.../generated/mars-perps/MarsPerps.types.ts | 264 +++++++++---------
10 files changed, 582 insertions(+), 218 deletions(-)
create mode 100644 src/components/perps/Module/ExpectedPrice.tsx
delete mode 100644 src/hooks/perps/useTradingFee.ts
create mode 100644 src/hooks/perps/useTradingFeeAndPrice.ts
diff --git a/src/components/perps/Module/ExpectedPrice.tsx b/src/components/perps/Module/ExpectedPrice.tsx
new file mode 100644
index 00000000..80c23a1a
--- /dev/null
+++ b/src/components/perps/Module/ExpectedPrice.tsx
@@ -0,0 +1,28 @@
+import BigNumber from 'bignumber.js'
+
+import { CircularProgress } from 'components/common/CircularProgress'
+import DisplayCurrency from 'components/common/DisplayCurrency'
+import useTradingFeeAndPrice from 'hooks/perps/useTradingFeeAndPrice'
+import { BNCoin } from 'types/classes/BNCoin'
+
+type Props = {
+ denom: string
+ newAmount: BigNumber
+ previousAmount: BigNumber
+}
+
+export const ExpectedPrice = (props: Props) => {
+ const { data: tradingFeeAndPrice, isLoading } = useTradingFeeAndPrice(
+ props.denom,
+ props.newAmount,
+ props.previousAmount,
+ )
+
+ if (isLoading) return
+
+ if (tradingFeeAndPrice?.price) {
+ return
+ }
+
+ return '-'
+}
diff --git a/src/components/perps/Module/Summary.tsx b/src/components/perps/Module/Summary.tsx
index 7b4a774e..3a44b908 100644
--- a/src/components/perps/Module/Summary.tsx
+++ b/src/components/perps/Module/Summary.tsx
@@ -7,10 +7,11 @@ import { ArrowRight } from 'components/common/Icons'
import SummaryLine from 'components/common/SummaryLine'
import Text from 'components/common/Text'
import TradeDirection from 'components/perps/BalancesTable/Columns/TradeDirection'
+import { ExpectedPrice } from 'components/perps/Module/ExpectedPrice'
import TradingFee from 'components/perps/Module/TradingFee'
import { BN_ZERO } from 'constants/math'
import useCurrentAccount from 'hooks/accounts/useCurrentAccount'
-import useTradingFee from 'hooks/perps/useTradingFee'
+import useTradingFeeAndPrice from 'hooks/perps/useTradingFeeAndPrice'
import useStore from 'store'
import { BNCoin } from 'types/classes/BNCoin'
import { formatLeverage } from 'utils/formatters'
@@ -20,7 +21,7 @@ type Props = {
amount: BigNumber
tradeDirection: TradeDirection
asset: Asset
- previousAmount?: BigNumber | null
+ previousAmount: BigNumber
previousTradeDirection?: 'long' | 'short'
previousLeverage?: number | null
hasActivePosition: boolean
@@ -32,17 +33,21 @@ export default function PerpsSummary(props: Props) {
const modifyPerpPosition = useStore((s) => s.modifyPerpPosition)
const closePerpPosition = useStore((s) => s.closePerpPosition)
const currentAccount = useCurrentAccount()
- const { data: tradingFee, isLoading } = useTradingFee(props.asset.denom, props.amount)
const newAmount = useMemo(
() => (props.previousAmount ?? BN_ZERO).plus(props.amount),
[props.amount, props.previousAmount],
)
+ const { data: tradingFee } = useTradingFeeAndPrice(
+ props.asset.denom,
+ newAmount,
+ props.previousAmount,
+ )
const onConfirm = useCallback(async () => {
if (!currentAccount) return
- if (props.previousAmount && newAmount.isZero()) {
+ if (!props.previousAmount.isZero() && newAmount.isZero()) {
await closePerpPosition({
accountId: currentAccount.id,
denom: props.asset.denom,
@@ -50,7 +55,7 @@ export default function PerpsSummary(props: Props) {
return props.onTxExecuted()
}
- if (props.previousAmount && newAmount) {
+ if (!props.previousAmount.isZero() && !newAmount.isZero()) {
await modifyPerpPosition({
accountId: currentAccount.id,
coin: BNCoin.fromDenomAndBigNumber(props.asset.denom, newAmount),
@@ -75,12 +80,22 @@ export default function PerpsSummary(props: Props) {
Summary
- -
+
+
+
-
+
-
diff --git a/src/components/perps/Module/TradingFee.tsx b/src/components/perps/Module/TradingFee.tsx
index 5544ea1c..617d63d1 100644
--- a/src/components/perps/Module/TradingFee.tsx
+++ b/src/components/perps/Module/TradingFee.tsx
@@ -2,18 +2,23 @@ import BigNumber from 'bignumber.js'
import { CircularProgress } from 'components/common/CircularProgress'
import DisplayCurrency from 'components/common/DisplayCurrency'
-import useTradingFee from 'hooks/perps/useTradingFee'
+import useTradingFeeAndPrice from 'hooks/perps/useTradingFeeAndPrice'
type Props = {
denom: string
- amount: BigNumber
+ newAmount: BigNumber
+ previousAmount: BigNumber
}
export default function TradingFee(props: Props) {
- const { data: openingFee, isLoading } = useTradingFee(props.denom, props.amount)
+ const { data: tradingFeeAndPrice, isLoading } = useTradingFeeAndPrice(
+ props.denom,
+ props.newAmount,
+ props.previousAmount,
+ )
if (isLoading) return
- if (props.amount.isZero() || !openingFee) return '-'
+ if (props.newAmount.isEqualTo(props.previousAmount) || !tradingFeeAndPrice?.fee) return '-'
- return
+ return
}
diff --git a/src/components/perps/Module/usePerpsModule.ts b/src/components/perps/Module/usePerpsModule.ts
index 20dc32c8..e6813eb6 100644
--- a/src/components/perps/Module/usePerpsModule.ts
+++ b/src/components/perps/Module/usePerpsModule.ts
@@ -38,7 +38,11 @@ export default function usePerpsModule(amount: BigNumber | null) {
const previousLeverage = useMemo(
() =>
previousAmount
- ? price.times(demagnify(previousAmount, perpsAsset)).div(accountNetValue).plus(1).toNumber()
+ ? price
+ .times(demagnify(previousAmount.abs(), perpsAsset))
+ .div(accountNetValue)
+ .plus(1)
+ .toNumber()
: null,
[accountNetValue, perpsAsset, previousAmount, price],
)
@@ -46,7 +50,7 @@ export default function usePerpsModule(amount: BigNumber | null) {
const leverage = useMemo(
() =>
price
- .times(demagnify(previousAmount.plus(amount ?? BN_ZERO), perpsAsset))
+ .times(demagnify(previousAmount.plus(amount ?? BN_ZERO).abs(), perpsAsset))
.div(accountNetValue)
.plus(1)
.toNumber(),
diff --git a/src/configs/chains/neutron/pion-1.ts b/src/configs/chains/neutron/pion-1.ts
index 2cfd289d..a3c125ba 100644
--- a/src/configs/chains/neutron/pion-1.ts
+++ b/src/configs/chains/neutron/pion-1.ts
@@ -21,14 +21,14 @@ const Pion1: ChainConfig = {
id: ChainInfoID.Pion1,
name: 'Neutron Testnet',
contracts: {
- redBank: 'neutron1gpv59ff87mfvx8s3fn5ku3l8dn94fkj4q37sruhwfl0zzgjsejqs3xejyj',
- incentives: 'neutron1au78lscqqh77ghvl6eq2d58vy439q0gprhz0sc5q4r9svh63hquqtwlrsw',
- oracle: 'neutron1z44naqtpn20z5yws7updsgcplm7tcfkcn67uejvc0l7n8hy6vupq0894qs',
- swapper: 'neutron1td4dn53k7ythdj8ah3xv5p66swq3sy2a9jzq4yrue8aa4dvwacrs7dachf',
- params: 'neutron16l9j74q6ht9ycd37qxt6tz83l3r3cwec4qu9r5mkd66kcve23ywspjqhjp',
- creditManager: 'neutron1swud86k6acvpjfn68cv6tz3h7z72nz395d7y5e3yxknrc8yl9faqxn5jjw',
- accountNft: 'neutron1apus79ka5v30wmwdxzzapprrzxxw6mz0hc0uk3g030t0m5f0asuq8x3ldf',
- perps: 'neutron1ssnc38h40fu0d2et8f38z83ealgugh06r4anqa6dn6hlz6syqaqsmj6zcy',
+ redBank: 'neutron1h7lvw8nm64x3zxlue6ec3vrk4e504d7c2wqq6y9uq2nu2shygh8qxm22up',
+ incentives: 'neutron1e28g4d93rthgjrtrxsze2f5lcljsxst24szhx0gjsvcmwzqsdruswau7hv',
+ oracle: 'neutron1lwwmygj9cfm5jy623vvk37athq5fnjnm00wfjap2q49lfk8wylkqtujcym',
+ swapper: 'neutron1yk90r8efz897ev7vve9anfl4w342czn8f35qlyd3s2hsg4tctdms7vwexp',
+ params: 'neutron16kqg3hr2qc36gz2wqvdzsctatkmzd3ss5gc07tnj6u3n5ajw89asrx8hfp',
+ creditManager: 'neutron1kj50g96c86nu7jmy5y7uy5cyjanntgru0eekmwz2qcmyyvx6383s8dgvm6',
+ accountNft: 'neutron17wvpxdc3k37054ume0ga4r0r6ra2rpfe622m0ecgd9s7xd5s0qusspc4ct',
+ perps: 'neutron14v9g7regs90qvful7djcajsvrfep5pg9qau7qm6wya6c2lzcpnms692dlt',
pyth: 'neutron15ldst8t80982akgr8w8ekcytejzkmfpgdkeq4xgtge48qs7435jqp87u3t',
},
endpoints: {
diff --git a/src/hooks/perps/useTradingFee.ts b/src/hooks/perps/useTradingFee.ts
deleted file mode 100644
index ddc74453..00000000
--- a/src/hooks/perps/useTradingFee.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import BigNumber from 'bignumber.js'
-import useSWR from 'swr'
-
-import useChainConfig from 'hooks/useChainConfig'
-import useClients from 'hooks/useClients'
-import useDebounce from 'hooks/useDebounce'
-import { BNCoin } from 'types/classes/BNCoin'
-import { BN } from 'utils/helpers'
-
-export default function useTradingFee(denom: string, amount: BigNumber) {
- const chainConfig = useChainConfig()
- const debouncedAmount = useDebounce(amount.toString(), 500)
- const clients = useClients()
- const enabled = !amount.isZero() && clients
-
- return useSWR(enabled && `${chainConfig.id}/perps/${denom}/tradingFee/${debouncedAmount}`, () =>
- clients!.perps
- .openingFee({ denom, size: amount as any })
- .then((resp) => ({ rate: BN(resp.rate), fee: BNCoin.fromCoin(resp.fee) })),
- )
-}
diff --git a/src/hooks/perps/useTradingFeeAndPrice.ts b/src/hooks/perps/useTradingFeeAndPrice.ts
new file mode 100644
index 00000000..9a4b576e
--- /dev/null
+++ b/src/hooks/perps/useTradingFeeAndPrice.ts
@@ -0,0 +1,77 @@
+import BigNumber from 'bignumber.js'
+import useSWR from 'swr'
+
+import { BN_ZERO } from 'constants/math'
+import useCurrentAccount from 'hooks/accounts/useCurrentAccount'
+import useChainConfig from 'hooks/useChainConfig'
+import useClients from 'hooks/useClients'
+import useDebounce from 'hooks/useDebounce'
+import { BNCoin } from 'types/classes/BNCoin'
+import { BN } from 'utils/helpers'
+
+export default function useTradingFeeAndPrice(
+ denom: string,
+ newAmount: BigNumber,
+ previousAmount: BigNumber,
+) {
+ const chainConfig = useChainConfig()
+ const accountId = useCurrentAccount()?.id
+ const debouncedAmount = useDebounce(newAmount, 500)
+ const clients = useClients()
+ const enabled = !debouncedAmount.isEqualTo(previousAmount) && clients && !!accountId
+
+ return useSWR(
+ enabled && `${chainConfig.id}/perps/${denom}/positionFeeAndPrice/${debouncedAmount}`,
+ async () => {
+ const isChangingTradeDirection =
+ newAmount.isNegative() !== previousAmount.isNegative() && !previousAmount.isZero()
+
+ if (!isChangingTradeDirection) {
+ const positionFees = await clients!.perps.positionFees({
+ denom,
+ newSize: newAmount.toString() as any,
+ accountId: accountId!,
+ })
+
+ return {
+ price: positionFees.opening_exec_price
+ ? BN(positionFees.opening_exec_price)
+ : BN(positionFees.closing_exec_price ?? BN_ZERO),
+ fee: BNCoin.fromDenomAndBigNumber(
+ positionFees.base_denom,
+ BN(positionFees.opening_fee).plus(positionFees.closing_fee),
+ ),
+ rate: BN(0.005),
+ }
+ }
+
+ // WHen direction is changed, we need to query both the 'closing' fees
+ // and also query how the new position would be opened. SC limits flipping trade direction.
+ const closingPositionFees$ = clients!.perps.positionFees({
+ denom,
+ newSize: '0' as any,
+ accountId: accountId!,
+ })
+
+ const openingPositionFees$ = clients!.perps.positionFees({
+ denom,
+ newSize: newAmount.toString() as any,
+ accountId: '91283123987467', // TODO: Remove this hard-coded value. SC currently does not allow flipping, so providing arbitrary accountId prevents this
+ })
+
+ return await Promise.all([closingPositionFees$, openingPositionFees$]).then(
+ ([closingPositionFees, openingPositionFees]) => ({
+ price: BN(openingPositionFees.opening_exec_price ?? 0),
+ fee: BNCoin.fromDenomAndBigNumber(
+ closingPositionFees.base_denom,
+ BN(closingPositionFees.opening_fee)
+ .plus(closingPositionFees.closing_fee)
+ .plus(openingPositionFees.opening_fee)
+ .plus(openingPositionFees.closing_fee),
+ ),
+ rate: BN(0.005),
+ }),
+ )
+ },
+ )
+}
diff --git a/src/types/generated/mars-perps/MarsPerps.client.ts b/src/types/generated/mars-perps/MarsPerps.client.ts
index e3e32221..17a895cc 100644
--- a/src/types/generated/mars-perps/MarsPerps.client.ts
+++ b/src/types/generated/mars-perps/MarsPerps.client.ts
@@ -5,41 +5,32 @@
* and run the @cosmwasm/ts-codegen generate command to regenerate this file.
*/
-import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from '@cosmjs/cosmwasm-stargate'
-import { StdFee } from '@cosmjs/amino'
+import { StdFee } from "@cosmjs/amino";
+import { CosmWasmClient, ExecuteResult, SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import {
- Decimal,
- Uint128,
- OracleBaseForString,
- ParamsBaseForString,
- InstantiateMsg,
- ExecuteMsg,
- OwnerUpdate,
- SignedDecimal,
- QueryMsg,
- ConfigForString,
- DenomStateResponse,
- Funding,
+ Accounting,
ArrayOfDenomStateResponse,
- DepositResponse,
ArrayOfDepositResponse,
- TradingFee,
- Coin,
- OwnerResponse,
- PerpDenomState,
- DenomPnlValues,
- PnL,
- PositionResponse,
- PerpPosition,
- PositionPnl,
- PnlCoins,
- PnlValues,
ArrayOfPositionResponse,
- PositionsByAccountResponse,
ArrayOfUnlockState,
- UnlockState,
- VaultState,
-} from './MarsPerps.types'
+ Coin,
+ ConfigForString,
+ Decimal,
+ DenomStateResponse,
+ DepositResponse,
+ OwnerResponse,
+ OwnerUpdate,
+ PerpDenomState,
+ PnlAmounts,
+ PositionFeesResponse,
+ PositionResponse,
+ PositionsByAccountResponse,
+ SignedDecimal,
+ TradingFee,
+ Uint128,
+ VaultState
+} from "./MarsPerps.types";
+
export interface MarsPerpsReadOnlyInterface {
contractAddress: string
owner: () => Promise
@@ -63,13 +54,7 @@ export interface MarsPerpsReadOnlyInterface {
startAfter?: string
}) => Promise
unlocks: ({ depositor }: { depositor: string }) => Promise
- position: ({
- accountId,
- denom,
- }: {
- accountId: string
- denom: string
- }) => Promise
+ denomAccounting: ({ denom }: { denom: string }) => Promise
positions: ({
limit,
startAfter,
@@ -80,6 +65,32 @@ export interface MarsPerpsReadOnlyInterface {
positionsByAccount: ({ accountId }: { accountId: string }) => Promise
totalPnl: () => Promise
openingFee: ({ denom, size }: { denom: string; size: SignedDecimal }) => Promise
+ denomRealizedPnlForAccount: ({
+ accountId,
+ denom,
+ }: {
+ accountId: string
+ denom: string
+ }) => Promise
+ position: ({
+ accountId,
+ denom,
+ newSize,
+ }: {
+ accountId: string
+ denom: string
+ newSize?: SignedDecimal
+ }) => Promise
+ positionFees: ({
+ accountId,
+ denom,
+ newSize,
+ }: {
+ accountId: string
+ denom: string
+ newSize: SignedDecimal
+ }) => Promise
+ totalAccounting: () => Promise
}
export class MarsPerpsQueryClient implements MarsPerpsReadOnlyInterface {
client: CosmWasmClient
@@ -102,6 +113,10 @@ export class MarsPerpsQueryClient implements MarsPerpsReadOnlyInterface {
this.positionsByAccount = this.positionsByAccount.bind(this)
this.totalPnl = this.totalPnl.bind(this)
this.openingFee = this.openingFee.bind(this)
+ this.denomAccounting = this.denomAccounting.bind(this)
+ this.totalAccounting = this.totalAccounting.bind(this)
+ this.denomRealizedPnlForAccount = this.denomRealizedPnlForAccount.bind(this)
+ this.positionFees = this.positionFees.bind(this)
}
owner = async (): Promise => {
@@ -175,16 +190,10 @@ export class MarsPerpsQueryClient implements MarsPerpsReadOnlyInterface {
},
})
}
- position = async ({
- accountId,
- denom,
- }: {
- accountId: string
- denom: string
- }): Promise => {
+
+ denomAccounting = async ({ denom }: { denom: string }): Promise => {
return this.client.queryContractSmart(this.contractAddress, {
- position: {
- account_id: accountId,
+ denom_accounting: {
denom,
},
})
@@ -233,6 +242,63 @@ export class MarsPerpsQueryClient implements MarsPerpsReadOnlyInterface {
},
})
}
+
+ denomRealizedPnlForAccount = async ({
+ accountId,
+ denom,
+ }: {
+ accountId: string
+ denom: string
+ }): Promise => {
+ return this.client.queryContractSmart(this.contractAddress, {
+ denom_realized_pnl_for_account: {
+ account_id: accountId,
+ denom,
+ },
+ })
+ }
+
+ position = async ({
+ accountId,
+ denom,
+ newSize,
+ }: {
+ accountId: string
+ denom: string
+ newSize?: SignedDecimal
+ }): Promise => {
+ return this.client.queryContractSmart(this.contractAddress, {
+ position: {
+ account_id: accountId,
+ denom,
+ new_size: newSize,
+ },
+ })
+ }
+
+ positionFees = async ({
+ accountId,
+ denom,
+ newSize,
+ }: {
+ accountId: string
+ denom: string
+ newSize: SignedDecimal
+ }): Promise => {
+ return this.client.queryContractSmart(this.contractAddress, {
+ position_fees: {
+ account_id: accountId,
+ denom,
+ new_size: newSize,
+ },
+ })
+ }
+
+ totalAccounting = async (): Promise => {
+ return this.client.queryContractSmart(this.contractAddress, {
+ total_accounting: {},
+ })
+ }
}
export interface MarsPerpsInterface extends MarsPerpsReadOnlyInterface {
contractAddress: string
@@ -323,6 +389,20 @@ export interface MarsPerpsInterface extends MarsPerpsReadOnlyInterface {
memo?: string,
_funds?: Coin[],
) => Promise
+ modifyPosition: (
+ {
+ accountId,
+ denom,
+ newSize,
+ }: {
+ accountId: string
+ denom: string
+ newSize: SignedDecimal
+ },
+ fee?: number | StdFee | 'auto',
+ memo?: string,
+ _funds?: Coin[],
+ ) => Promise
}
export class MarsPerpsClient extends MarsPerpsQueryClient implements MarsPerpsInterface {
client: SigningCosmWasmClient
@@ -343,6 +423,7 @@ export class MarsPerpsClient extends MarsPerpsQueryClient implements MarsPerpsIn
this.withdraw = this.withdraw.bind(this)
this.openPosition = this.openPosition.bind(this)
this.closePosition = this.closePosition.bind(this)
+ this.modifyPosition = this.modifyPosition.bind(this)
}
updateOwner = async (
@@ -547,4 +628,33 @@ export class MarsPerpsClient extends MarsPerpsQueryClient implements MarsPerpsIn
_funds,
)
}
+ modifyPosition = async (
+ {
+ accountId,
+ denom,
+ newSize,
+ }: {
+ accountId: string
+ denom: string
+ newSize: SignedDecimal
+ },
+ fee: number | StdFee | 'auto' = 'auto',
+ memo?: string,
+ _funds?: Coin[],
+ ): Promise => {
+ return await this.client.execute(
+ this.sender,
+ this.contractAddress,
+ {
+ modify_position: {
+ account_id: accountId,
+ denom,
+ new_size: newSize,
+ },
+ },
+ fee,
+ memo,
+ _funds,
+ )
+ }
}
diff --git a/src/types/generated/mars-perps/MarsPerps.react-query.ts b/src/types/generated/mars-perps/MarsPerps.react-query.ts
index d7e7c2a0..55a0f36a 100644
--- a/src/types/generated/mars-perps/MarsPerps.react-query.ts
+++ b/src/types/generated/mars-perps/MarsPerps.react-query.ts
@@ -19,6 +19,10 @@ import {
SignedDecimal,
QueryMsg,
ConfigForString,
+ Accounting,
+ Balance,
+ CashFlow,
+ PnlAmounts,
DenomStateResponse,
Funding,
ArrayOfDenomStateResponse,
@@ -28,13 +32,13 @@ import {
Coin,
OwnerResponse,
PerpDenomState,
- DenomPnlValues,
+ PnlValues,
PnL,
PositionResponse,
PerpPosition,
PositionPnl,
PnlCoins,
- PnlValues,
+ PositionFeesResponse,
ArrayOfPositionResponse,
PositionsByAccountResponse,
ArrayOfUnlockState,
@@ -82,6 +86,27 @@ export const marsPerpsQueryKeys = {
[{ ...marsPerpsQueryKeys.address(contractAddress)[0], method: 'total_pnl', args }] as const,
openingFee: (contractAddress: string | undefined, args?: Record) =>
[{ ...marsPerpsQueryKeys.address(contractAddress)[0], method: 'opening_fee', args }] as const,
+ denomAccounting: (contractAddress: string | undefined, args?: Record) =>
+ [
+ { ...marsPerpsQueryKeys.address(contractAddress)[0], method: 'denom_accounting', args },
+ ] as const,
+ totalAccounting: (contractAddress: string | undefined, args?: Record) =>
+ [
+ { ...marsPerpsQueryKeys.address(contractAddress)[0], method: 'total_accounting', args },
+ ] as const,
+ denomRealizedPnlForAccount: (
+ contractAddress: string | undefined,
+ args?: Record,
+ ) =>
+ [
+ {
+ ...marsPerpsQueryKeys.address(contractAddress)[0],
+ method: 'denom_realized_pnl_for_account',
+ args,
+ },
+ ] as const,
+ positionFees: (contractAddress: string | undefined, args?: Record) =>
+ [{ ...marsPerpsQueryKeys.address(contractAddress)[0], method: 'position_fees', args }] as const,
}
export interface MarsPerpsReactQuery {
client: MarsPerpsQueryClient | undefined
@@ -92,6 +117,90 @@ export interface MarsPerpsReactQuery {
initialData?: undefined
}
}
+export interface MarsPerpsPositionFeesQuery
+ extends MarsPerpsReactQuery {
+ args: {
+ accountId: string
+ denom: string
+ newSize: SignedDecimal
+ }
+}
+export function useMarsPerpsPositionFeesQuery({
+ client,
+ args,
+ options,
+}: MarsPerpsPositionFeesQuery) {
+ return useQuery(
+ marsPerpsQueryKeys.positionFees(client?.contractAddress, args),
+ () =>
+ client
+ ? client.positionFees({
+ accountId: args.accountId,
+ denom: args.denom,
+ newSize: args.newSize,
+ })
+ : Promise.reject(new Error('Invalid client')),
+ { ...options, enabled: !!client && (options?.enabled != undefined ? options.enabled : true) },
+ )
+}
+export interface MarsPerpsDenomRealizedPnlForAccountQuery
+ extends MarsPerpsReactQuery {
+ args: {
+ accountId: string
+ denom: string
+ }
+}
+export function useMarsPerpsDenomRealizedPnlForAccountQuery({
+ client,
+ args,
+ options,
+}: MarsPerpsDenomRealizedPnlForAccountQuery) {
+ return useQuery(
+ marsPerpsQueryKeys.denomRealizedPnlForAccount(client?.contractAddress, args),
+ () =>
+ client
+ ? client.denomRealizedPnlForAccount({
+ accountId: args.accountId,
+ denom: args.denom,
+ })
+ : Promise.reject(new Error('Invalid client')),
+ { ...options, enabled: !!client && (options?.enabled != undefined ? options.enabled : true) },
+ )
+}
+export interface MarsPerpsTotalAccountingQuery
+ extends MarsPerpsReactQuery {}
+export function useMarsPerpsTotalAccountingQuery({
+ client,
+ options,
+}: MarsPerpsTotalAccountingQuery) {
+ return useQuery(
+ marsPerpsQueryKeys.totalAccounting(client?.contractAddress),
+ () => (client ? client.totalAccounting() : Promise.reject(new Error('Invalid client'))),
+ { ...options, enabled: !!client && (options?.enabled != undefined ? options.enabled : true) },
+ )
+}
+export interface MarsPerpsDenomAccountingQuery
+ extends MarsPerpsReactQuery {
+ args: {
+ denom: string
+ }
+}
+export function useMarsPerpsDenomAccountingQuery({
+ client,
+ args,
+ options,
+}: MarsPerpsDenomAccountingQuery) {
+ return useQuery(
+ marsPerpsQueryKeys.denomAccounting(client?.contractAddress, args),
+ () =>
+ client
+ ? client.denomAccounting({
+ denom: args.denom,
+ })
+ : Promise.reject(new Error('Invalid client')),
+ { ...options, enabled: !!client && (options?.enabled != undefined ? options.enabled : true) },
+ )
+}
export interface MarsPerpsOpeningFeeQuery extends MarsPerpsReactQuery {
args: {
denom: string
@@ -177,6 +286,7 @@ export interface MarsPerpsPositionQuery
args: {
accountId: string
denom: string
+ newSize?: SignedDecimal
}
}
export function useMarsPerpsPositionQuery({
@@ -191,6 +301,7 @@ export function useMarsPerpsPositionQuery({
? client.position({
accountId: args.accountId,
denom: args.denom,
+ newSize: args.newSize,
})
: Promise.reject(new Error('Invalid client')),
{ ...options, enabled: !!client && (options?.enabled != undefined ? options.enabled : true) },
@@ -364,6 +475,31 @@ export function useMarsPerpsOwnerQuery({
{ ...options, enabled: !!client && (options?.enabled != undefined ? options.enabled : true) },
)
}
+export interface MarsPerpsModifyPositionMutation {
+ client: MarsPerpsClient
+ msg: {
+ accountId: string
+ denom: string
+ newSize: SignedDecimal
+ }
+ args?: {
+ fee?: number | StdFee | 'auto'
+ memo?: string
+ funds?: Coin[]
+ }
+}
+export function useMarsPerpsModifyPositionMutation(
+ options?: Omit<
+ UseMutationOptions,
+ 'mutationFn'
+ >,
+) {
+ return useMutation(
+ ({ client, msg, args: { fee, memo, funds } = {} }) =>
+ client.modifyPosition(msg, fee, memo, funds),
+ options,
+ )
+}
export interface MarsPerpsClosePositionMutation {
client: MarsPerpsClient
msg: {
diff --git a/src/types/generated/mars-perps/MarsPerps.types.ts b/src/types/generated/mars-perps/MarsPerps.types.ts
index ea93234d..aacba981 100644
--- a/src/types/generated/mars-perps/MarsPerps.types.ts
+++ b/src/types/generated/mars-perps/MarsPerps.types.ts
@@ -22,70 +22,70 @@ export interface InstantiateMsg {
}
export type ExecuteMsg =
| {
- update_owner: OwnerUpdate
-}
+ update_owner: OwnerUpdate
+ }
| {
- init_denom: {
- denom: string
- max_funding_velocity: Decimal
- skew_scale: Decimal
- }
-}
+ init_denom: {
+ denom: string
+ max_funding_velocity: Decimal
+ skew_scale: Decimal
+ }
+ }
| {
- enable_denom: {
- denom: string
- }
-}
+ enable_denom: {
+ denom: string
+ }
+ }
| {
- disable_denom: {
- denom: string
- }
-}
+ disable_denom: {
+ denom: string
+ }
+ }
| {
- deposit: {}
-}
+ deposit: {}
+ }
| {
- unlock: {
- shares: Uint128
- }
-}
+ unlock: {
+ shares: Uint128
+ }
+ }
| {
- withdraw: {}
-}
+ withdraw: {}
+ }
| {
- open_position: {
- account_id: string
- denom: string
- size: SignedDecimal
- }
-}
+ open_position: {
+ account_id: string
+ denom: string
+ size: SignedDecimal
+ }
+ }
| {
- close_position: {
- account_id: string
- denom: string
- }
-}
+ close_position: {
+ account_id: string
+ denom: string
+ }
+ }
| {
- modify_position: {
- account_id: string
- denom: string
- new_size: SignedDecimal
- }
-}
+ modify_position: {
+ account_id: string
+ denom: string
+ new_size: SignedDecimal
+ }
+ }
export type OwnerUpdate =
| {
- propose_new_owner: {
- proposed: string
- }
-}
+ propose_new_owner: {
+ proposed: string
+ }
+ }
| 'clear_proposed'
| 'accept_proposed'
| 'abolish_owner_role'
| {
- set_emergency_owner: {
- emergency_owner: string
- }
-}
+ set_emergency_owner: {
+ emergency_owner: string
+ }
+ }
| 'clear_emergency_owner'
export interface SignedDecimal {
abs: Decimal
@@ -94,86 +94,94 @@ export interface SignedDecimal {
}
export type QueryMsg =
| {
- owner: {}
-}
+ owner: {}
+ }
| {
- config: {}
-}
+ config: {}
+ }
| {
- vault_state: {}
-}
+ vault_state: {}
+ }
| {
- denom_state: {
- denom: string
- }
-}
+ denom_state: {
+ denom: string
+ }
+ }
| {
- perp_denom_state: {
- denom: string
- }
-}
+ perp_denom_state: {
+ denom: string
+ }
+ }
| {
- denom_states: {
- limit?: number | null
- start_after?: string | null
- }
-}
+ denom_states: {
+ limit?: number | null
+ start_after?: string | null
+ }
+ }
| {
- deposit: {
- depositor: string
- }
-}
+ deposit: {
+ depositor: string
+ }
+ }
| {
- deposits: {
- limit?: number | null
- start_after?: string | null
- }
-}
+ deposits: {
+ limit?: number | null
+ start_after?: string | null
+ }
+ }
| {
- unlocks: {
- depositor: string
- }
-}
+ unlocks: {
+ depositor: string
+ }
+ }
| {
- position: {
- account_id: string
- denom: string
- }
-}
+ position: {
+ account_id: string
+ denom: string
+ new_size?: SignedDecimal | null
+ }
+ }
| {
- positions: {
- limit?: number | null
- start_after?: [string, string] | null
- }
-}
+ positions: {
+ limit?: number | null
+ start_after?: [string, string] | null
+ }
+ }
| {
- positions_by_account: {
- account_id: string
- }
-}
+ positions_by_account: {
+ account_id: string
+ }
+ }
| {
- total_pnl: {}
-}
+ total_pnl: {}
+ }
| {
- opening_fee: {
- denom: string
- size: SignedDecimal
- }
-}
+ opening_fee: {
+ denom: string
+ size: SignedDecimal
+ }
+ }
| {
- denom_accounting: {
- denom: string
- }
-}
+ denom_accounting: {
+ denom: string
+ }
+ }
| {
- total_accounting: {}
-}
+ total_accounting: {}
+ }
| {
- denom_realized_pnl_for_account: {
- account_id: string
- denom: string
- }
-}
+ denom_realized_pnl_for_account: {
+ account_id: string
+ denom: string
+ }
+ }
+ | {
+ position_fees: {
+ account_id: string
+ denom: string
+ new_size: SignedDecimal
+ }
+ }
export interface ConfigForString {
base_denom: string
closing_fee_rate: Decimal
@@ -203,7 +211,7 @@ export interface CashFlow {
opening_fee: SignedDecimal
price_pnl: SignedDecimal
}
-export interface RealizedPnlAmounts {
+export interface PnlAmounts {
accrued_funding: SignedDecimal
closing_fee: SignedDecimal
opening_fee: SignedDecimal
@@ -250,26 +258,26 @@ export interface PerpDenomState {
denom: string
enabled: boolean
long_oi: Decimal
- pnl_values: DenomPnlValues
+ pnl_values: PnlValues
rate: SignedDecimal
short_oi: Decimal
total_entry_cost: SignedDecimal
total_entry_funding: SignedDecimal
}
-export interface DenomPnlValues {
+export interface PnlValues {
accrued_funding: SignedDecimal
- closing_fees: SignedDecimal
+ closing_fee: SignedDecimal
pnl: SignedDecimal
price_pnl: SignedDecimal
}
export type PnL =
| 'break_even'
| {
- profit: Coin
-}
+ profit: Coin
+ }
| {
- loss: Coin
-}
+ loss: Coin
+ }
export interface PositionResponse {
account_id: string
position: PerpPosition
@@ -282,11 +290,12 @@ export interface PerpPosition {
denom: string
entry_exec_price: Decimal
entry_price: Decimal
- realised_pnl: RealizedPnlAmounts
+ realised_pnl: PnlAmounts
size: SignedDecimal
unrealised_pnl: PositionPnl
}
export interface PositionPnl {
+ amounts: PnlAmounts
coins: PnlCoins
values: PnlValues
}
@@ -294,11 +303,12 @@ export interface PnlCoins {
closing_fee: Coin
pnl: PnL
}
-export interface PnlValues {
- accrued_funding: SignedDecimal
- closing_fee: SignedDecimal
- pnl: SignedDecimal
- price_pnl: SignedDecimal
+export interface PositionFeesResponse {
+ base_denom: string
+ closing_exec_price?: Decimal | null
+ closing_fee: Uint128
+ opening_exec_price?: Decimal | null
+ opening_fee: Uint128
}
export type ArrayOfPositionResponse = PositionResponse[]
export interface PositionsByAccountResponse {