Main update (#801)
* fix: fixed transaction messages (#792) * Open Source + Docker image (#793) * feat: added dummy charting library * feat: added docker workflow * feat: remove tests and code-coverage * feat: added final TradingView fallback * env: set private to false * fix: added production env * env: added README and LICENSE * env: cleanup variables * env: add license field * env: finish docker setup * fix: updated the description of the dummy data * docker: update actions to node 20 (#796) * docker: added v2 prefix to tags * perps: trading fee + expected price (#800) * env: updated dependencies (#799) * update docker CI to node 20 (#797) * fix: fixed transaction messages (#792) * Open Source + Docker image (#793) * feat: added dummy charting library * feat: added docker workflow * feat: remove tests and code-coverage * feat: added final TradingView fallback * env: set private to false * fix: added production env * env: added README and LICENSE * env: cleanup variables * env: add license field * env: finish docker setup * fix: updated the description of the dummy data * docker: update actions to node 20 (#796) * docker: added v2 prefix to tags * env: updated dependencies --------- Co-authored-by: Bob van der Helm <34470358+bobthebuidlr@users.noreply.github.com>
This commit is contained in:
parent
2ca6771f48
commit
0bc3dcc687
@ -24,7 +24,7 @@
|
||||
"@delphi-labs/shuttle-react": "^3.19.1",
|
||||
"@keplr-wallet/cosmos": "^0.12.67",
|
||||
"@splinetool/react-spline": "^2.2.6",
|
||||
"@splinetool/runtime": "^1.0.51",
|
||||
"@splinetool/runtime": "^1.0.52",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tanstack/react-table": "^8.11.8",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
@ -35,7 +35,7 @@
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"moment": "^2.30.1",
|
||||
"next": "^13.5.4",
|
||||
"next": "^14.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-device-detect": "^2.2.3",
|
||||
"react-dom": "^18.2.0",
|
||||
@ -47,7 +47,6 @@
|
||||
"react-toastify": "^10.0.4",
|
||||
"react-use-clipboard": "^1.0.9",
|
||||
"recharts": "^2.12.0",
|
||||
"sharp": "^0.33.2",
|
||||
"swr": "^2.2.4",
|
||||
"tailwind-scrollbar-hide": "^1.1.7",
|
||||
"zustand": "^4.5.0"
|
||||
@ -62,7 +61,7 @@
|
||||
"@types/react-dom": "18.2.19",
|
||||
"@types/react-helmet": "^6.1.11",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"dotenv": "^16.4.1",
|
||||
"dotenv": "^16.4.3",
|
||||
"dotenv-cli": "^7.3.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-next": "^14.1.0",
|
||||
|
28
src/components/perps/Module/ExpectedPrice.tsx
Normal file
28
src/components/perps/Module/ExpectedPrice.tsx
Normal file
@ -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 <CircularProgress className='h-full' size={12} />
|
||||
|
||||
if (tradingFeeAndPrice?.price) {
|
||||
return <DisplayCurrency coin={BNCoin.fromDenomAndBigNumber('usd', tradingFeeAndPrice.price)} />
|
||||
}
|
||||
|
||||
return '-'
|
||||
}
|
@ -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) {
|
||||
<Text size='xs' className='font-bold mb-2'>
|
||||
Summary
|
||||
</Text>
|
||||
<SummaryLine label='Expected Price'>-</SummaryLine>
|
||||
<SummaryLine label='Expected Price'>
|
||||
<ExpectedPrice
|
||||
denom={props.asset.denom}
|
||||
newAmount={newAmount}
|
||||
previousAmount={props.previousAmount}
|
||||
/>
|
||||
</SummaryLine>
|
||||
<SummaryLine
|
||||
label='Fees'
|
||||
tooltip={`${tradingFee ? tradingFee.rate.times(100) + '% ' : ''}Trading Fees`}
|
||||
>
|
||||
<TradingFee denom={props.asset.denom} amount={props.amount} />
|
||||
<TradingFee
|
||||
denom={props.asset.denom}
|
||||
newAmount={newAmount}
|
||||
previousAmount={props.previousAmount}
|
||||
/>
|
||||
</SummaryLine>
|
||||
<SummaryLine label='Total'>-</SummaryLine>
|
||||
</div>
|
||||
|
@ -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 <CircularProgress className='h-full' size={12} />
|
||||
if (props.amount.isZero() || !openingFee) return '-'
|
||||
if (props.newAmount.isEqualTo(props.previousAmount) || !tradingFeeAndPrice?.fee) return '-'
|
||||
|
||||
return <DisplayCurrency coin={openingFee.fee} />
|
||||
return <DisplayCurrency coin={tradingFeeAndPrice.fee} />
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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: {
|
||||
|
@ -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<string>(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) })),
|
||||
)
|
||||
}
|
77
src/hooks/perps/useTradingFeeAndPrice.ts
Normal file
77
src/hooks/perps/useTradingFeeAndPrice.ts
Normal file
@ -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<BigNumber>(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),
|
||||
}),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
@ -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<OwnerResponse>
|
||||
@ -63,13 +54,7 @@ export interface MarsPerpsReadOnlyInterface {
|
||||
startAfter?: string
|
||||
}) => Promise<ArrayOfDepositResponse>
|
||||
unlocks: ({ depositor }: { depositor: string }) => Promise<ArrayOfUnlockState>
|
||||
position: ({
|
||||
accountId,
|
||||
denom,
|
||||
}: {
|
||||
accountId: string
|
||||
denom: string
|
||||
}) => Promise<PositionResponse>
|
||||
denomAccounting: ({ denom }: { denom: string }) => Promise<Accounting>
|
||||
positions: ({
|
||||
limit,
|
||||
startAfter,
|
||||
@ -80,6 +65,32 @@ export interface MarsPerpsReadOnlyInterface {
|
||||
positionsByAccount: ({ accountId }: { accountId: string }) => Promise<PositionsByAccountResponse>
|
||||
totalPnl: () => Promise<SignedDecimal>
|
||||
openingFee: ({ denom, size }: { denom: string; size: SignedDecimal }) => Promise<TradingFee>
|
||||
denomRealizedPnlForAccount: ({
|
||||
accountId,
|
||||
denom,
|
||||
}: {
|
||||
accountId: string
|
||||
denom: string
|
||||
}) => Promise<PnlAmounts>
|
||||
position: ({
|
||||
accountId,
|
||||
denom,
|
||||
newSize,
|
||||
}: {
|
||||
accountId: string
|
||||
denom: string
|
||||
newSize?: SignedDecimal
|
||||
}) => Promise<PositionResponse>
|
||||
positionFees: ({
|
||||
accountId,
|
||||
denom,
|
||||
newSize,
|
||||
}: {
|
||||
accountId: string
|
||||
denom: string
|
||||
newSize: SignedDecimal
|
||||
}) => Promise<PositionFeesResponse>
|
||||
totalAccounting: () => Promise<Accounting>
|
||||
}
|
||||
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<OwnerResponse> => {
|
||||
@ -175,16 +190,10 @@ export class MarsPerpsQueryClient implements MarsPerpsReadOnlyInterface {
|
||||
},
|
||||
})
|
||||
}
|
||||
position = async ({
|
||||
accountId,
|
||||
denom,
|
||||
}: {
|
||||
accountId: string
|
||||
denom: string
|
||||
}): Promise<PositionResponse> => {
|
||||
|
||||
denomAccounting = async ({ denom }: { denom: string }): Promise<Accounting> => {
|
||||
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<PnlAmounts> => {
|
||||
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<PositionResponse> => {
|
||||
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<PositionFeesResponse> => {
|
||||
return this.client.queryContractSmart(this.contractAddress, {
|
||||
position_fees: {
|
||||
account_id: accountId,
|
||||
denom,
|
||||
new_size: newSize,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
totalAccounting = async (): Promise<Accounting> => {
|
||||
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<ExecuteResult>
|
||||
modifyPosition: (
|
||||
{
|
||||
accountId,
|
||||
denom,
|
||||
newSize,
|
||||
}: {
|
||||
accountId: string
|
||||
denom: string
|
||||
newSize: SignedDecimal
|
||||
},
|
||||
fee?: number | StdFee | 'auto',
|
||||
memo?: string,
|
||||
_funds?: Coin[],
|
||||
) => Promise<ExecuteResult>
|
||||
}
|
||||
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<ExecuteResult> => {
|
||||
return await this.client.execute(
|
||||
this.sender,
|
||||
this.contractAddress,
|
||||
{
|
||||
modify_position: {
|
||||
account_id: accountId,
|
||||
denom,
|
||||
new_size: newSize,
|
||||
},
|
||||
},
|
||||
fee,
|
||||
memo,
|
||||
_funds,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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<string, unknown>) =>
|
||||
[{ ...marsPerpsQueryKeys.address(contractAddress)[0], method: 'opening_fee', args }] as const,
|
||||
denomAccounting: (contractAddress: string | undefined, args?: Record<string, unknown>) =>
|
||||
[
|
||||
{ ...marsPerpsQueryKeys.address(contractAddress)[0], method: 'denom_accounting', args },
|
||||
] as const,
|
||||
totalAccounting: (contractAddress: string | undefined, args?: Record<string, unknown>) =>
|
||||
[
|
||||
{ ...marsPerpsQueryKeys.address(contractAddress)[0], method: 'total_accounting', args },
|
||||
] as const,
|
||||
denomRealizedPnlForAccount: (
|
||||
contractAddress: string | undefined,
|
||||
args?: Record<string, unknown>,
|
||||
) =>
|
||||
[
|
||||
{
|
||||
...marsPerpsQueryKeys.address(contractAddress)[0],
|
||||
method: 'denom_realized_pnl_for_account',
|
||||
args,
|
||||
},
|
||||
] as const,
|
||||
positionFees: (contractAddress: string | undefined, args?: Record<string, unknown>) =>
|
||||
[{ ...marsPerpsQueryKeys.address(contractAddress)[0], method: 'position_fees', args }] as const,
|
||||
}
|
||||
export interface MarsPerpsReactQuery<TResponse, TData = TResponse> {
|
||||
client: MarsPerpsQueryClient | undefined
|
||||
@ -92,6 +117,90 @@ export interface MarsPerpsReactQuery<TResponse, TData = TResponse> {
|
||||
initialData?: undefined
|
||||
}
|
||||
}
|
||||
export interface MarsPerpsPositionFeesQuery<TData>
|
||||
extends MarsPerpsReactQuery<PositionFeesResponse, TData> {
|
||||
args: {
|
||||
accountId: string
|
||||
denom: string
|
||||
newSize: SignedDecimal
|
||||
}
|
||||
}
|
||||
export function useMarsPerpsPositionFeesQuery<TData = PositionFeesResponse>({
|
||||
client,
|
||||
args,
|
||||
options,
|
||||
}: MarsPerpsPositionFeesQuery<TData>) {
|
||||
return useQuery<PositionFeesResponse, Error, TData>(
|
||||
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<TData>
|
||||
extends MarsPerpsReactQuery<PnlAmounts, TData> {
|
||||
args: {
|
||||
accountId: string
|
||||
denom: string
|
||||
}
|
||||
}
|
||||
export function useMarsPerpsDenomRealizedPnlForAccountQuery<TData = PnlAmounts>({
|
||||
client,
|
||||
args,
|
||||
options,
|
||||
}: MarsPerpsDenomRealizedPnlForAccountQuery<TData>) {
|
||||
return useQuery<PnlAmounts, Error, TData>(
|
||||
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<TData>
|
||||
extends MarsPerpsReactQuery<Accounting, TData> {}
|
||||
export function useMarsPerpsTotalAccountingQuery<TData = Accounting>({
|
||||
client,
|
||||
options,
|
||||
}: MarsPerpsTotalAccountingQuery<TData>) {
|
||||
return useQuery<Accounting, Error, TData>(
|
||||
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<TData>
|
||||
extends MarsPerpsReactQuery<Accounting, TData> {
|
||||
args: {
|
||||
denom: string
|
||||
}
|
||||
}
|
||||
export function useMarsPerpsDenomAccountingQuery<TData = Accounting>({
|
||||
client,
|
||||
args,
|
||||
options,
|
||||
}: MarsPerpsDenomAccountingQuery<TData>) {
|
||||
return useQuery<Accounting, Error, TData>(
|
||||
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<TData> extends MarsPerpsReactQuery<TradingFee, TData> {
|
||||
args: {
|
||||
denom: string
|
||||
@ -177,6 +286,7 @@ export interface MarsPerpsPositionQuery<TData>
|
||||
args: {
|
||||
accountId: string
|
||||
denom: string
|
||||
newSize?: SignedDecimal
|
||||
}
|
||||
}
|
||||
export function useMarsPerpsPositionQuery<TData = PositionResponse>({
|
||||
@ -191,6 +301,7 @@ export function useMarsPerpsPositionQuery<TData = PositionResponse>({
|
||||
? 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<TData = OwnerResponse>({
|
||||
{ ...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<ExecuteResult, Error, MarsPerpsModifyPositionMutation>,
|
||||
'mutationFn'
|
||||
>,
|
||||
) {
|
||||
return useMutation<ExecuteResult, Error, MarsPerpsModifyPositionMutation>(
|
||||
({ client, msg, args: { fee, memo, funds } = {} }) =>
|
||||
client.modifyPosition(msg, fee, memo, funds),
|
||||
options,
|
||||
)
|
||||
}
|
||||
export interface MarsPerpsClosePositionMutation {
|
||||
client: MarsPerpsClient
|
||||
msg: {
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user