merge main
This commit is contained in:
commit
d0845efbae
91
README.md
91
README.md
|
@ -1,57 +1,78 @@
|
||||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
This repo contains the Next.js app for the Mango v4 user interface.
|
||||||
|
|
||||||
## Dependency Management
|
## ⚡️ Quickstart
|
||||||
|
|
||||||
When updating dependencies, there are various files that must be kept up-to-date. Newly added, or updated dependencies can introduce unwanted/malicious scripts that can introduce risks for users and/or developers. The `lavamoat allow-scripts` feature allows us to deny by default, but adds some additional steps to the usual workflow.
|
To get started, follow these steps:
|
||||||
|
|
||||||
`yarn.lock`:
|
1. **Clone the repo:** Begin by cloning the repository using the command:
|
||||||
|
|
||||||
- Instead of running `yarn` or `yarn install`, run `yarn setup` to ensure the `yarn.lock` file is in sync and that dependency scripts are run according to the `allowScripts` policy (set in `packages.json`)
|
```bash
|
||||||
- If `lavamoat` detects new scripts that are not explicitely allowed/denied, it'll throw and error with details (see below)
|
git clone git@github.com:blockworks-foundation/mango-v4-ui.git
|
||||||
- Running `yarn setup` will also dedupe the `yarn.lock` file to reduce the dependency tree. Note CI will fail if there are dupes in `yarn.lock`!
|
```
|
||||||
|
|
||||||
The `allowScripts` configuration in `package.json`:
|
2. **Install Dependencies:** Move into the directory and install the dependencies:
|
||||||
|
|
||||||
- There are two ways to configure script policies:
|
```bash
|
||||||
1. Update the allow-scripts section manually by adding the missing package in the `allowScripts` section in `package.json`
|
cd mango-v4-ui
|
||||||
2. Run `yarn allow-scripts auto` to update the `allowScripts` configuration automatically
|
yarn setup
|
||||||
- Review each new package to determine whether the install script needs to run or not, testing if necessary.
|
```
|
||||||
- Use `npx can-i-ignore-scripts` to help assessing whether scripts are needed
|
|
||||||
|
3. **Run the app:**
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
First, run the development server:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
|
||||||
# or
|
|
||||||
yarn dev
|
yarn dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
4. Browse to http://localhost:3000
|
||||||
|
|
||||||
You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
|
## ⌨️ Contributor's Guide
|
||||||
|
|
||||||
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
|
### Code quality
|
||||||
|
|
||||||
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
|
- Avoid duplication
|
||||||
|
- Consider performance (use useMemo and useCallback where appropriate)
|
||||||
|
- Create logical components and give them descriptive names
|
||||||
|
- Destructure objects and arrays
|
||||||
|
- Define constants for event functions unless they are very simple e.g. a single state update
|
||||||
|
- Create hooks for shared logic
|
||||||
|
- Add translation keys in alphabetical order
|
||||||
|
|
||||||
## Learn More
|
### Branching
|
||||||
|
|
||||||
To learn more about Next.js, take a look at the following resources:
|
Prefix your branches with your Git username and give them concise and descriptive names
|
||||||
|
e.g. username/branch-name
|
||||||
|
|
||||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
### Commits
|
||||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
|
||||||
|
|
||||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
Add commits for each self-contained change and give your commits clear messages that describe the change. Smaller commits that encompass a specific change are preferred over large commits with many changes
|
||||||
|
|
||||||
## Deploy on Vercel
|
### PRs
|
||||||
|
|
||||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
All PRs should have a meaningful name and include a description of what the changes are.
|
||||||
|
|
||||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
If there are visual changes, include screenshots in the description.
|
||||||
|
|
||||||
## Creating Color Themes
|
If the PR is unfinished include a "TODO" section with work not yet completed. If there are known issues/bugs include a section outlining what they are.
|
||||||
|
|
||||||
|
#### Drafts
|
||||||
|
|
||||||
|
Opening draft PRs is a good way for other contributors to know a feature is being worked on. This is most useful for larger/complex features and is not a requirement. When your feature is at a point where you'd like to gather feedback or it's close to completion open a draft PR and share the preview link in the relevant Discord channel
|
||||||
|
|
||||||
|
Prefix "WIP:" to your draft PR name
|
||||||
|
|
||||||
|
### Reviews
|
||||||
|
|
||||||
|
When your changes are finished, who you request review from depends on the type of changes.
|
||||||
|
|
||||||
|
For complex changes e.g. new transactions, large features, lots of client or backend interactions you should at a minimum include @tlrsssss in your review
|
||||||
|
|
||||||
|
For changes that affect visual elements of the app (including text changes), request a review from @saml33 at a minimum
|
||||||
|
|
||||||
|
If you're unsure, request a review from @tlrssss and @saml33
|
||||||
|
|
||||||
|
If your work involves other parts of the stack (backend, client, etc.) request a review from the relevant person in that area
|
||||||
|
|
||||||
|
## 🎨 Creating Color Themes
|
||||||
|
|
||||||
1. Copy one of the other color themes in [tailwind.config.js](https://github.com/blockworks-foundation/mango-v4-ui/blob/main/tailwind.config.js) (starting line 25)
|
1. Copy one of the other color themes in [tailwind.config.js](https://github.com/blockworks-foundation/mango-v4-ui/blob/main/tailwind.config.js) (starting line 25)
|
||||||
2. Modify the colors. For the variables bkg-\* and fgd-\* pick a base color for bkg-1 and fgd-1 then adjust the lightness for 2-4. Use this same process to create dark/hover variations for the colors that have these properties. The base color can be anything that works for your theme.
|
2. Modify the colors. For the variables bkg-\* and fgd-\* pick a base color for bkg-1 and fgd-1 then adjust the lightness for 2-4. Use this same process to create dark/hover variations for the colors that have these properties. The base color can be anything that works for your theme.
|
||||||
|
|
|
@ -37,6 +37,8 @@ import { NFT } from 'types'
|
||||||
import { useViewport } from 'hooks/useViewport'
|
import { useViewport } from 'hooks/useViewport'
|
||||||
import useLocalStorageState from 'hooks/useLocalStorageState'
|
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||||
import { SIDEBAR_COLLAPSE_KEY } from 'utils/constants'
|
import { SIDEBAR_COLLAPSE_KEY } from 'utils/constants'
|
||||||
|
import { createTransferInstruction } from '@solana/spl-token'
|
||||||
|
import { PublicKey, TransactionInstruction } from '@solana/web3.js'
|
||||||
|
|
||||||
const SideNav = ({ collapsed }: { collapsed: boolean }) => {
|
const SideNav = ({ collapsed }: { collapsed: boolean }) => {
|
||||||
const { t } = useTranslation(['common', 'search'])
|
const { t } = useTranslation(['common', 'search'])
|
||||||
|
@ -46,6 +48,10 @@ const SideNav = ({ collapsed }: { collapsed: boolean }) => {
|
||||||
const themeData = mangoStore((s) => s.themeData)
|
const themeData = mangoStore((s) => s.themeData)
|
||||||
const nfts = mangoStore((s) => s.wallet.nfts.data)
|
const nfts = mangoStore((s) => s.wallet.nfts.data)
|
||||||
const { mangoAccount } = useMangoAccount()
|
const { mangoAccount } = useMangoAccount()
|
||||||
|
const setPrependedGlobalAdditionalInstructions = mangoStore(
|
||||||
|
(s) => s.actions.setPrependedGlobalAdditionalInstructions,
|
||||||
|
)
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { pathname } = router
|
const { pathname } = router
|
||||||
|
|
||||||
|
@ -88,14 +94,39 @@ const SideNav = ({ collapsed }: { collapsed: boolean }) => {
|
||||||
return mangoNfts
|
return mangoNfts
|
||||||
}, [nfts])
|
}, [nfts])
|
||||||
|
|
||||||
|
//mark transactions with used nfts
|
||||||
|
useEffect(() => {
|
||||||
|
let newInstruction: TransactionInstruction[] = []
|
||||||
|
if (mangoNfts.length && theme) {
|
||||||
|
const collectionAddress = CUSTOM_SKINS[theme.toLowerCase()]
|
||||||
|
const usedNft = mangoNfts.find(
|
||||||
|
(nft) => nft.collectionAddress === collectionAddress,
|
||||||
|
)
|
||||||
|
if (usedNft && publicKey && collectionAddress) {
|
||||||
|
newInstruction = [
|
||||||
|
createTransferInstruction(
|
||||||
|
new PublicKey(usedNft.tokenAccount),
|
||||||
|
new PublicKey(usedNft.tokenAccount),
|
||||||
|
publicKey,
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setPrependedGlobalAdditionalInstructions(newInstruction)
|
||||||
|
}, [mangoNfts, theme, themeData])
|
||||||
|
|
||||||
// find sidebar image url from skin nft for theme
|
// find sidebar image url from skin nft for theme
|
||||||
const sidebarImageUrl = useMemo(() => {
|
const sidebarImageUrl = useMemo(() => {
|
||||||
if (!theme) return themeData.sideImagePath
|
if (!theme) return themeData.sideImagePath
|
||||||
const collectionAddress = CUSTOM_SKINS[theme.toLowerCase()]
|
const collectionAddress = CUSTOM_SKINS[theme.toLowerCase()]
|
||||||
if (collectionAddress && mangoNfts.length) {
|
if (collectionAddress && mangoNfts.length) {
|
||||||
const sidebarImageUrl =
|
const attributes = mangoNfts.find(
|
||||||
mangoNfts.find((nft) => nft.collectionAddress === collectionAddress)
|
(nft) => nft.collectionAddress === collectionAddress,
|
||||||
?.image || themeData.sideImagePath
|
)?.json?.attributes
|
||||||
|
const sidebarImageUrl = attributes
|
||||||
|
? attributes[0].value || themeData.sideImagePath
|
||||||
|
: ''
|
||||||
return sidebarImageUrl
|
return sidebarImageUrl
|
||||||
}
|
}
|
||||||
return themeData.sideImagePath
|
return themeData.sideImagePath
|
||||||
|
|
|
@ -468,9 +468,18 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
|
||||||
Number(tierPreset.maintLiabWeight),
|
Number(tierPreset.maintLiabWeight),
|
||||||
Number(tierPreset.initLiabWeight),
|
Number(tierPreset.initLiabWeight),
|
||||||
Number(tierPreset.liquidationFee),
|
Number(tierPreset.liquidationFee),
|
||||||
|
Number(tierPreset.delayIntervalSeconds),
|
||||||
|
Number(tierPreset.delayGrowthLimit),
|
||||||
|
Number(tierPreset.stableGrowthLimit),
|
||||||
Number(tierPreset.minVaultToDepositsRatio),
|
Number(tierPreset.minVaultToDepositsRatio),
|
||||||
new BN(tierPreset.netBorrowLimitWindowSizeTs),
|
new BN(tierPreset.netBorrowLimitWindowSizeTs),
|
||||||
new BN(tierPreset.netBorrowLimitPerWindowQuote),
|
new BN(tierPreset.netBorrowLimitPerWindowQuote),
|
||||||
|
Number(tierPreset.borrowWeightScale),
|
||||||
|
Number(tierPreset.depositWeightScale),
|
||||||
|
Number(tierPreset.reduceOnly),
|
||||||
|
Number(tierPreset.tokenConditionalSwapTakerFeeRate),
|
||||||
|
Number(tierPreset.tokenConditionalSwapMakerFeeRate),
|
||||||
|
Number(tierPreset.flashLoanDepositFeeRate),
|
||||||
)
|
)
|
||||||
.accounts({
|
.accounts({
|
||||||
admin: MANGO_DAO_WALLET,
|
admin: MANGO_DAO_WALLET,
|
||||||
|
@ -502,13 +511,16 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
tierPreset.borrowWeightScale,
|
null,
|
||||||
tierPreset.depositWeightScale,
|
null,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
)
|
)
|
||||||
.accounts({
|
.accounts({
|
||||||
oracle: new PublicKey(advForm.oraclePk),
|
oracle: new PublicKey(advForm.oraclePk),
|
||||||
|
@ -524,7 +536,9 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
|
||||||
} as AccountMeta,
|
} as AccountMeta,
|
||||||
])
|
])
|
||||||
.instruction()
|
.instruction()
|
||||||
|
if (!tierPreset.insuranceFound) {
|
||||||
proposalTx.push(editIx)
|
proposalTx.push(editIx)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const trustlessIx = await client!.program.methods
|
const trustlessIx = await client!.program.methods
|
||||||
.tokenRegisterTrustless(Number(advForm.tokenIndex), advForm.name)
|
.tokenRegisterTrustless(Number(advForm.tokenIndex), advForm.name)
|
||||||
|
|
|
@ -15,7 +15,7 @@ const CreateAccountModal = ({ isOpen, onClose }: ModalProps) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onClose={onClose}>
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
<div className="flex min-h-[264px] flex-col items-center justify-center">
|
<div className="flex min-h-[400px] flex-col items-center justify-center">
|
||||||
<CreateAccountForm customClose={handleClose} />
|
<CreateAccountForm customClose={handleClose} />
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -122,7 +122,7 @@ const CreateSwitchboardOracleModal = ({
|
||||||
minRequiredOracleResults: 3,
|
minRequiredOracleResults: 3,
|
||||||
minRequiredJobResults: 2,
|
minRequiredJobResults: 2,
|
||||||
minUpdateDelaySeconds: 6,
|
minUpdateDelaySeconds: 6,
|
||||||
forceReportPeriod: 24 * 60 * 60,
|
forceReportPeriod: 60 * 60,
|
||||||
withdrawAuthority: MANGO_DAO_WALLET,
|
withdrawAuthority: MANGO_DAO_WALLET,
|
||||||
authority: payer,
|
authority: payer,
|
||||||
crankDataBuffer: crankAccount.dataBuffer?.publicKey,
|
crankDataBuffer: crankAccount.dataBuffer?.publicKey,
|
||||||
|
|
|
@ -196,6 +196,9 @@ const DashboardSuggestedValues = ({
|
||||||
bank.reduceOnly ? 0 : null,
|
bank.reduceOnly ? 0 : null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
getNullOrVal(fieldsToChange.tokenConditionalSwapTakerFeeRate),
|
||||||
|
getNullOrVal(fieldsToChange.tokenConditionalSwapMakerFeeRate),
|
||||||
|
getNullOrVal(fieldsToChange.loanFeeRate),
|
||||||
)
|
)
|
||||||
.accounts({
|
.accounts({
|
||||||
group: group!.publicKey,
|
group: group!.publicKey,
|
||||||
|
|
|
@ -102,7 +102,7 @@ const MangoAccountsListModal = ({
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onClose={onClose}>
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
<div className="inline-block w-full transform overflow-x-hidden">
|
<div className="inline-block w-full transform overflow-x-hidden">
|
||||||
<div className="flex min-h-[364px] flex-col justify-between">
|
<div className="flex min-h-[400px] flex-col justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-center">{t('accounts')}</h2>
|
<h2 className="text-center">{t('accounts')}</h2>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
|
|
|
@ -14,7 +14,11 @@ import {
|
||||||
TrHead,
|
TrHead,
|
||||||
} from '@components/shared/TableElements'
|
} from '@components/shared/TableElements'
|
||||||
import Tooltip from '@components/shared/Tooltip'
|
import Tooltip from '@components/shared/Tooltip'
|
||||||
import { NoSymbolIcon, UsersIcon } from '@heroicons/react/20/solid'
|
import {
|
||||||
|
EyeSlashIcon,
|
||||||
|
NoSymbolIcon,
|
||||||
|
UsersIcon,
|
||||||
|
} from '@heroicons/react/20/solid'
|
||||||
import { useWallet } from '@solana/wallet-adapter-react'
|
import { useWallet } from '@solana/wallet-adapter-react'
|
||||||
import { PublicKey } from '@solana/web3.js'
|
import { PublicKey } from '@solana/web3.js'
|
||||||
import mangoStore from '@store/mangoStore'
|
import mangoStore from '@store/mangoStore'
|
||||||
|
@ -32,6 +36,7 @@ import PerpSideBadge from './PerpSideBadge'
|
||||||
import TableMarketName from './TableMarketName'
|
import TableMarketName from './TableMarketName'
|
||||||
import { useSortableData } from 'hooks/useSortableData'
|
import { useSortableData } from 'hooks/useSortableData'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
|
import { useHiddenMangoAccounts } from 'hooks/useHiddenMangoAccounts'
|
||||||
|
|
||||||
const TradeHistory = () => {
|
const TradeHistory = () => {
|
||||||
const { t } = useTranslation(['common', 'trade'])
|
const { t } = useTranslation(['common', 'trade'])
|
||||||
|
@ -45,6 +50,7 @@ const TradeHistory = () => {
|
||||||
} = useTradeHistory()
|
} = useTradeHistory()
|
||||||
const { width } = useViewport()
|
const { width } = useViewport()
|
||||||
const { connected } = useWallet()
|
const { connected } = useWallet()
|
||||||
|
const { hiddenAccounts } = useHiddenMangoAccounts()
|
||||||
const showTableView = width ? width > breakpoints.md : false
|
const showTableView = width ? width > breakpoints.md : false
|
||||||
|
|
||||||
const formattedTableData = useCallback(() => {
|
const formattedTableData = useCallback(() => {
|
||||||
|
@ -142,6 +148,14 @@ const TradeHistory = () => {
|
||||||
{tableData.map((trade, index: number) => {
|
{tableData.map((trade, index: number) => {
|
||||||
const { side, price, market, size, feeCost, liquidity, value } =
|
const { side, price, market, size, feeCost, liquidity, value } =
|
||||||
trade
|
trade
|
||||||
|
|
||||||
|
let counterpartyAddress = ''
|
||||||
|
if ('taker' in trade) {
|
||||||
|
counterpartyAddress =
|
||||||
|
trade.liquidity === 'Taker'
|
||||||
|
? trade.maker.toString()
|
||||||
|
: trade.taker.toString()
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<TrBody
|
<TrBody
|
||||||
key={`${side}${size}${price}${index}`}
|
key={`${side}${size}${price}${index}`}
|
||||||
|
@ -184,29 +198,41 @@ const TradeHistory = () => {
|
||||||
<Td className="xl:!pl-0">
|
<Td className="xl:!pl-0">
|
||||||
{'taker' in trade ? (
|
{'taker' in trade ? (
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
|
{!hiddenAccounts?.includes(counterpartyAddress) ? (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content={`View Counterparty ${abbreviateAddress(
|
content={t('trade:tooltip-view-counterparty', {
|
||||||
|
pk: abbreviateAddress(
|
||||||
trade.liquidity === 'Taker'
|
trade.liquidity === 'Taker'
|
||||||
? new PublicKey(trade.maker)
|
? new PublicKey(trade.maker)
|
||||||
: new PublicKey(trade.taker),
|
: new PublicKey(trade.taker),
|
||||||
)}`}
|
),
|
||||||
|
})}
|
||||||
delay={0}
|
delay={0}
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
className=""
|
className=""
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
href={`/?address=${
|
href={`/?address=${counterpartyAddress}`}
|
||||||
trade.liquidity === 'Taker'
|
|
||||||
? trade.maker
|
|
||||||
: trade.taker
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<IconButton size="small">
|
<IconButton size="small">
|
||||||
<UsersIcon className="h-4 w-4" />
|
<UsersIcon className="h-4 w-4" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</a>
|
</a>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
<Tooltip
|
||||||
|
content={t('trade:tooltip-private-counterparty')}
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
className="bg-th-bkg-1"
|
||||||
|
disabled
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<EyeSlashIcon className="h-4 w-4" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</Td>
|
</Td>
|
||||||
|
@ -220,6 +246,13 @@ const TradeHistory = () => {
|
||||||
<div>
|
<div>
|
||||||
{combinedTradeHistory.map((trade, index: number) => {
|
{combinedTradeHistory.map((trade, index: number) => {
|
||||||
const { side, price, market, size, liquidity } = trade
|
const { side, price, market, size, liquidity } = trade
|
||||||
|
let counterpartyAddress = ''
|
||||||
|
if ('taker' in trade) {
|
||||||
|
counterpartyAddress =
|
||||||
|
trade.liquidity === 'Taker'
|
||||||
|
? trade.maker.toString()
|
||||||
|
: trade.taker.toString()
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="flex items-center justify-between border-b border-th-bkg-3 p-4"
|
className="flex items-center justify-between border-b border-th-bkg-3 p-4"
|
||||||
|
@ -259,18 +292,41 @@ const TradeHistory = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{'taker' in trade ? (
|
{'taker' in trade ? (
|
||||||
|
!hiddenAccounts?.includes(counterpartyAddress) ? (
|
||||||
|
<Tooltip
|
||||||
|
content={t('trade:tooltip-view-counterparty', {
|
||||||
|
pk: abbreviateAddress(
|
||||||
|
liquidity === 'Taker'
|
||||||
|
? new PublicKey(trade.maker)
|
||||||
|
: new PublicKey(trade.taker),
|
||||||
|
),
|
||||||
|
})}
|
||||||
|
delay={0}
|
||||||
|
>
|
||||||
<a
|
<a
|
||||||
className=""
|
className=""
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
href={`/?address=${
|
href={`/?address=${counterpartyAddress}`}
|
||||||
liquidity === 'Taker' ? trade.maker : trade.taker
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<IconButton size="small">
|
<IconButton size="small">
|
||||||
<UsersIcon className="h-4 w-4" />
|
<UsersIcon className="h-4 w-4" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</a>
|
</a>
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
<Tooltip
|
||||||
|
content={t('trade:tooltip-private-counterparty')}
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
className="bg-th-bkg-1"
|
||||||
|
disabled
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<EyeSlashIcon className="h-4 w-4" />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -39,7 +39,7 @@ export const getOracleProvider = (
|
||||||
case OracleProvider.Switchboard:
|
case OracleProvider.Switchboard:
|
||||||
return [
|
return [
|
||||||
'Switchboard',
|
'Switchboard',
|
||||||
`https://switchboard.xyz/explorer/3/${marketOrBase.oracle.toString()}`,
|
`https://app.switchboard.xyz/solana/mainnet-beta/feed/${marketOrBase.oracle.toString()}`,
|
||||||
]
|
]
|
||||||
case OracleProvider.Stub:
|
case OracleProvider.Stub:
|
||||||
return ['Stub', '']
|
return ['Stub', '']
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blockworks-foundation/mango-feeds": "0.1.7",
|
"@blockworks-foundation/mango-feeds": "0.1.7",
|
||||||
"@blockworks-foundation/mango-v4": "^0.19.15",
|
"@blockworks-foundation/mango-v4": "^0.19.20",
|
||||||
"@blockworks-foundation/mango-v4-settings": "0.2.6",
|
"@blockworks-foundation/mango-v4-settings": "0.2.8",
|
||||||
"@headlessui/react": "1.6.6",
|
"@headlessui/react": "1.6.6",
|
||||||
"@heroicons/react": "2.0.10",
|
"@heroicons/react": "2.0.10",
|
||||||
"@metaplex-foundation/js": "0.19.4",
|
"@metaplex-foundation/js": "0.19.4",
|
||||||
|
|
|
@ -197,6 +197,7 @@
|
||||||
"vote": "Vote",
|
"vote": "Vote",
|
||||||
"yes": "Yes",
|
"yes": "Yes",
|
||||||
"you": "You",
|
"you": "You",
|
||||||
"using-ledger": "Using Ledger"
|
"using-ledger": "Using Ledger",
|
||||||
|
"sign-to-in-app-notifications": "Sign to in app notifications"
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,9 +106,11 @@
|
||||||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||||
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
||||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||||
|
"tooltip-private-counterparty": "Counterparty has Private Account enabled",
|
||||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||||
"tooltip-volume-alert": "Volume Alert Settings",
|
|
||||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||||
|
"tooltip-view-counterparty": "View counterparty {{pk}}",
|
||||||
|
"tooltip-volume-alert": "Volume Alert Settings",
|
||||||
"total-pnl": "Total PnL",
|
"total-pnl": "Total PnL",
|
||||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||||
"trades": "Trades",
|
"trades": "Trades",
|
||||||
|
|
|
@ -197,6 +197,7 @@
|
||||||
"vote": "Vote",
|
"vote": "Vote",
|
||||||
"yes": "Yes",
|
"yes": "Yes",
|
||||||
"you": "You",
|
"you": "You",
|
||||||
"using-ledger": "Using Ledger"
|
"using-ledger": "Using Ledger",
|
||||||
|
"sign-to-in-app-notifications": "Sign to in app notifications"
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,9 +106,11 @@
|
||||||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||||
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
||||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||||
|
"tooltip-private-counterparty": "Counterparty has Private Account enabled",
|
||||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||||
"tooltip-volume-alert": "Volume Alert Settings",
|
|
||||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||||
|
"tooltip-view-counterparty": "View counterparty {{pk}}",
|
||||||
|
"tooltip-volume-alert": "Volume Alert Settings",
|
||||||
"total-pnl": "Total PnL",
|
"total-pnl": "Total PnL",
|
||||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||||
"trades": "Trades",
|
"trades": "Trades",
|
||||||
|
@ -119,6 +121,7 @@
|
||||||
"tweet-position": "Tweet",
|
"tweet-position": "Tweet",
|
||||||
"unrealized-pnl": "Unrealized PnL",
|
"unrealized-pnl": "Unrealized PnL",
|
||||||
"unsettled": "Unsettled",
|
"unsettled": "Unsettled",
|
||||||
|
"view-counterparty": "View counterparty {{pk}}",
|
||||||
"volume-alert": "Volume Alert",
|
"volume-alert": "Volume Alert",
|
||||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||||
}
|
}
|
|
@ -197,6 +197,7 @@
|
||||||
"vote": "Vote",
|
"vote": "Vote",
|
||||||
"yes": "Yes",
|
"yes": "Yes",
|
||||||
"you": "You",
|
"you": "You",
|
||||||
"using-ledger": "Using Ledger"
|
"using-ledger": "Using Ledger",
|
||||||
|
"sign-to-in-app-notifications": "Sign to in app notifications"
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,9 +106,11 @@
|
||||||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||||
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
||||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||||
|
"tooltip-private-counterparty": "Counterparty has Private Account enabled",
|
||||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||||
"tooltip-volume-alert": "Volume Alert Settings",
|
|
||||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||||
|
"tooltip-view-counterparty": "View counterparty {{pk}}",
|
||||||
|
"tooltip-volume-alert": "Volume Alert Settings",
|
||||||
"total-pnl": "Total PnL",
|
"total-pnl": "Total PnL",
|
||||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||||
"trades": "Trades",
|
"trades": "Trades",
|
||||||
|
@ -119,6 +121,7 @@
|
||||||
"tweet-position": "Tweet",
|
"tweet-position": "Tweet",
|
||||||
"unrealized-pnl": "Unrealized PnL",
|
"unrealized-pnl": "Unrealized PnL",
|
||||||
"unsettled": "Unsettled",
|
"unsettled": "Unsettled",
|
||||||
|
"view-counterparty": "View counterparty {{pk}}",
|
||||||
"volume-alert": "Volume Alert",
|
"volume-alert": "Volume Alert",
|
||||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||||
}
|
}
|
|
@ -196,6 +196,7 @@
|
||||||
"vote": "投票",
|
"vote": "投票",
|
||||||
"yes": "是",
|
"yes": "是",
|
||||||
"you": "你",
|
"you": "你",
|
||||||
"using-ledger": "Using Ledger"
|
"using-ledger": "Using Ledger",
|
||||||
|
"sign-to-in-app-notifications": "Sign to in app notifications"
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,8 +110,10 @@
|
||||||
"tooltip-insured": "如果发生破产,{{tokenOrMarket}}损失是否可以从保险基金中归还",
|
"tooltip-insured": "如果发生破产,{{tokenOrMarket}}损失是否可以从保险基金中归还",
|
||||||
"tooltip-ioc": "IOC交易若不吃单就会被取消。任何无法立刻成交的部分将被取消",
|
"tooltip-ioc": "IOC交易若不吃单就会被取消。任何无法立刻成交的部分将被取消",
|
||||||
"tooltip-post": "Post交易若不挂单就会被取消。",
|
"tooltip-post": "Post交易若不挂单就会被取消。",
|
||||||
|
"tooltip-private-counterparty": "Counterparty has Private Account enabled",
|
||||||
"tooltip-slippage": "当前价格与您的交易将执行的价格之间的差值的估计",
|
"tooltip-slippage": "当前价格与您的交易将执行的价格之间的差值的估计",
|
||||||
"tooltip-stable-price": "稳定价格用于一个安全机制。此机制可以限制用户在预言机价格快速波动时下风险高的订单",
|
"tooltip-stable-price": "稳定价格用于一个安全机制。此机制可以限制用户在预言机价格快速波动时下风险高的订单",
|
||||||
|
"tooltip-view-counterparty": "View counterparty {{pk}}",
|
||||||
"tooltip-volume-alert": "交易量警报设定",
|
"tooltip-volume-alert": "交易量警报设定",
|
||||||
"total-pnl": "总盈亏",
|
"total-pnl": "总盈亏",
|
||||||
"trade-sounds-tooltip": "为每笔新交易播放警报声音",
|
"trade-sounds-tooltip": "为每笔新交易播放警报声音",
|
||||||
|
@ -119,6 +121,7 @@
|
||||||
"tweet-position": "分享至Twitter",
|
"tweet-position": "分享至Twitter",
|
||||||
"unrealized-pnl": "未实现盈亏",
|
"unrealized-pnl": "未实现盈亏",
|
||||||
"unsettled": "未结清",
|
"unsettled": "未结清",
|
||||||
|
"view-counterparty": "View counterparty {{pk}}",
|
||||||
"volume-alert": "交易量警报",
|
"volume-alert": "交易量警报",
|
||||||
"volume-alert-desc": "交易量超过警报设定时播放声音"
|
"volume-alert-desc": "交易量超过警报设定时播放声音"
|
||||||
}
|
}
|
|
@ -196,5 +196,7 @@
|
||||||
"vote": "投票",
|
"vote": "投票",
|
||||||
"yes": "是",
|
"yes": "是",
|
||||||
"you": "你",
|
"you": "你",
|
||||||
|
"using-ledger": "Using Ledger",
|
||||||
|
"sign-to-in-app-notifications": "Sign to in app notifications"
|
||||||
"using-ledger": "Using Ledger"
|
"using-ledger": "Using Ledger"
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,8 +106,10 @@
|
||||||
"tooltip-insured": "如果發生破產,{{tokenOrMarket}}損失是否可以從保險基金中歸還",
|
"tooltip-insured": "如果發生破產,{{tokenOrMarket}}損失是否可以從保險基金中歸還",
|
||||||
"tooltip-ioc": "IOC交易若不吃單就會被取消。任何無法立刻成交的部分將被取消",
|
"tooltip-ioc": "IOC交易若不吃單就會被取消。任何無法立刻成交的部分將被取消",
|
||||||
"tooltip-post": "Post交易若不掛單就會被取消。",
|
"tooltip-post": "Post交易若不掛單就會被取消。",
|
||||||
|
"tooltip-private-counterparty": "Counterparty has Private Account enabled",
|
||||||
"tooltip-slippage": "當前價格與您的交易將執行的價格之間的差值的估計",
|
"tooltip-slippage": "當前價格與您的交易將執行的價格之間的差值的估計",
|
||||||
"tooltip-stable-price": "穩定價格用於一個安全機制。此機制可以限制用戶在預言機價格快速波動時下風險高的訂單",
|
"tooltip-stable-price": "穩定價格用於一個安全機制。此機制可以限制用戶在預言機價格快速波動時下風險高的訂單",
|
||||||
|
"tooltip-view-counterparty": "View counterparty {{pk}}",
|
||||||
"tooltip-volume-alert": "交易量警報設定",
|
"tooltip-volume-alert": "交易量警報設定",
|
||||||
"total-pnl": "總盈虧",
|
"total-pnl": "總盈虧",
|
||||||
"trade-sounds-tooltip": "為每筆新交易播放警報聲音",
|
"trade-sounds-tooltip": "為每筆新交易播放警報聲音",
|
||||||
|
@ -119,6 +121,7 @@
|
||||||
"tweet-position": "分享至Twitter",
|
"tweet-position": "分享至Twitter",
|
||||||
"unrealized-pnl": "未實現盈虧",
|
"unrealized-pnl": "未實現盈虧",
|
||||||
"unsettled": "未結清",
|
"unsettled": "未結清",
|
||||||
|
"view-counterparty": "View counterparty {{pk}}",
|
||||||
"volume-alert": "交易量警報",
|
"volume-alert": "交易量警報",
|
||||||
"volume-alert-desc": "交易量超過警報設定時播放聲音"
|
"volume-alert-desc": "交易量超過警報設定時播放聲音"
|
||||||
}
|
}
|
|
@ -9,6 +9,7 @@ import {
|
||||||
Keypair,
|
Keypair,
|
||||||
PublicKey,
|
PublicKey,
|
||||||
RecentPrioritizationFees,
|
RecentPrioritizationFees,
|
||||||
|
TransactionInstruction,
|
||||||
} from '@solana/web3.js'
|
} from '@solana/web3.js'
|
||||||
import { OpenOrders, Order } from '@project-serum/serum/lib/market'
|
import { OpenOrders, Order } from '@project-serum/serum/lib/market'
|
||||||
import { Orderbook } from '@project-serum/serum'
|
import { Orderbook } from '@project-serum/serum'
|
||||||
|
@ -114,10 +115,18 @@ export const emptyWallet = new EmptyWallet(Keypair.generate())
|
||||||
|
|
||||||
const initMangoClient = (
|
const initMangoClient = (
|
||||||
provider: AnchorProvider,
|
provider: AnchorProvider,
|
||||||
opts = { prioritizationFee: DEFAULT_PRIORITY_FEE },
|
opts: {
|
||||||
|
prioritizationFee: number
|
||||||
|
prependedGlobalAdditionalInstructions: TransactionInstruction[]
|
||||||
|
} = {
|
||||||
|
prioritizationFee: DEFAULT_PRIORITY_FEE,
|
||||||
|
prependedGlobalAdditionalInstructions: [],
|
||||||
|
},
|
||||||
): MangoClient => {
|
): MangoClient => {
|
||||||
return MangoClient.connect(provider, CLUSTER, MANGO_V4_ID[CLUSTER], {
|
return MangoClient.connect(provider, CLUSTER, MANGO_V4_ID[CLUSTER], {
|
||||||
prioritizationFee: opts.prioritizationFee,
|
prioritizationFee: opts.prioritizationFee,
|
||||||
|
prependedGlobalAdditionalInstructions:
|
||||||
|
opts.prependedGlobalAdditionalInstructions,
|
||||||
idsSource: 'api',
|
idsSource: 'api',
|
||||||
postSendTxCallback: ({ txid }: { txid: string }) => {
|
postSendTxCallback: ({ txid }: { txid: string }) => {
|
||||||
notify({
|
notify({
|
||||||
|
@ -193,6 +202,7 @@ export type MangoStore = {
|
||||||
details: ProfileDetails | null
|
details: ProfileDetails | null
|
||||||
loadDetails: boolean
|
loadDetails: boolean
|
||||||
}
|
}
|
||||||
|
prependedGlobalAdditionalInstructions: TransactionInstruction[]
|
||||||
priorityFee: number
|
priorityFee: number
|
||||||
selectedMarket: {
|
selectedMarket: {
|
||||||
name: string | undefined
|
name: string | undefined
|
||||||
|
@ -283,6 +293,9 @@ export type MangoStore = {
|
||||||
connectMangoClientWithWallet: (wallet: WalletAdapter) => Promise<void>
|
connectMangoClientWithWallet: (wallet: WalletAdapter) => Promise<void>
|
||||||
loadMarketFills: () => Promise<void>
|
loadMarketFills: () => Promise<void>
|
||||||
updateConnection: (url: string) => void
|
updateConnection: (url: string) => void
|
||||||
|
setPrependedGlobalAdditionalInstructions: (
|
||||||
|
instructions: TransactionInstruction[],
|
||||||
|
) => void
|
||||||
estimatePriorityFee: (feeMultiplier: number) => Promise<void>
|
estimatePriorityFee: (feeMultiplier: number) => Promise<void>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,6 +371,7 @@ const mangoStore = create<MangoStore>()(
|
||||||
details: { profile_name: '', trader_category: '', wallet_pk: '' },
|
details: { profile_name: '', trader_category: '', wallet_pk: '' },
|
||||||
},
|
},
|
||||||
priorityFee: DEFAULT_PRIORITY_FEE,
|
priorityFee: DEFAULT_PRIORITY_FEE,
|
||||||
|
prependedGlobalAdditionalInstructions: [],
|
||||||
selectedMarket: {
|
selectedMarket: {
|
||||||
name: 'SOL/USDC',
|
name: 'SOL/USDC',
|
||||||
current: undefined,
|
current: undefined,
|
||||||
|
@ -1016,8 +1030,11 @@ const mangoStore = create<MangoStore>()(
|
||||||
)
|
)
|
||||||
provider.opts.skipPreflight = true
|
provider.opts.skipPreflight = true
|
||||||
const priorityFee = get().priorityFee ?? DEFAULT_PRIORITY_FEE
|
const priorityFee = get().priorityFee ?? DEFAULT_PRIORITY_FEE
|
||||||
|
|
||||||
const client = initMangoClient(provider, {
|
const client = initMangoClient(provider, {
|
||||||
prioritizationFee: priorityFee,
|
prioritizationFee: priorityFee,
|
||||||
|
prependedGlobalAdditionalInstructions:
|
||||||
|
get().prependedGlobalAdditionalInstructions,
|
||||||
})
|
})
|
||||||
|
|
||||||
set((s) => {
|
set((s) => {
|
||||||
|
@ -1033,6 +1050,25 @@ const mangoStore = create<MangoStore>()(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async setPrependedGlobalAdditionalInstructions(
|
||||||
|
instructions: TransactionInstruction[],
|
||||||
|
) {
|
||||||
|
const set = get().set
|
||||||
|
const client = mangoStore.getState().client
|
||||||
|
|
||||||
|
const provider = client.program.provider as AnchorProvider
|
||||||
|
provider.opts.skipPreflight = true
|
||||||
|
|
||||||
|
const newClient = initMangoClient(provider, {
|
||||||
|
prioritizationFee: get().priorityFee,
|
||||||
|
prependedGlobalAdditionalInstructions: instructions,
|
||||||
|
})
|
||||||
|
|
||||||
|
set((s) => {
|
||||||
|
s.client = newClient
|
||||||
|
s.prependedGlobalAdditionalInstructions = instructions
|
||||||
|
})
|
||||||
|
},
|
||||||
async fetchProfileDetails(walletPk: string) {
|
async fetchProfileDetails(walletPk: string) {
|
||||||
const set = get().set
|
const set = get().set
|
||||||
set((state) => {
|
set((state) => {
|
||||||
|
@ -1128,7 +1164,11 @@ const mangoStore = create<MangoStore>()(
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
newProvider.opts.skipPreflight = true
|
newProvider.opts.skipPreflight = true
|
||||||
const newClient = initMangoClient(newProvider)
|
const newClient = initMangoClient(newProvider, {
|
||||||
|
prependedGlobalAdditionalInstructions:
|
||||||
|
get().prependedGlobalAdditionalInstructions,
|
||||||
|
prioritizationFee: DEFAULT_PRIORITY_FEE,
|
||||||
|
})
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.connection = newConnection
|
state.connection = newConnection
|
||||||
state.client = newClient
|
state.client = newClient
|
||||||
|
@ -1180,6 +1220,8 @@ const mangoStore = create<MangoStore>()(
|
||||||
provider.opts.skipPreflight = true
|
provider.opts.skipPreflight = true
|
||||||
const newClient = initMangoClient(provider, {
|
const newClient = initMangoClient(provider, {
|
||||||
prioritizationFee: feeEstimate,
|
prioritizationFee: feeEstimate,
|
||||||
|
prependedGlobalAdditionalInstructions:
|
||||||
|
get().prependedGlobalAdditionalInstructions,
|
||||||
})
|
})
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.priorityFee = feeEstimate
|
state.priorityFee = feeEstimate
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
Serum3Market,
|
Serum3Market,
|
||||||
} from '@blockworks-foundation/mango-v4'
|
} from '@blockworks-foundation/mango-v4'
|
||||||
import { Modify } from '@blockworks-foundation/mango-v4'
|
import { Modify } from '@blockworks-foundation/mango-v4'
|
||||||
|
import { JsonMetadata } from '@metaplex-foundation/js'
|
||||||
import { Event } from '@project-serum/serum/lib/queue'
|
import { Event } from '@project-serum/serum/lib/queue'
|
||||||
import { PublicKey } from '@solana/web3.js'
|
import { PublicKey } from '@solana/web3.js'
|
||||||
import { formatTradeHistory } from 'hooks/useTradeHistory'
|
import { formatTradeHistory } from 'hooks/useTradeHistory'
|
||||||
|
@ -305,6 +306,7 @@ export interface NFT {
|
||||||
name: string
|
name: string
|
||||||
mint: string
|
mint: string
|
||||||
tokenAccount: string
|
tokenAccount: string
|
||||||
|
json: JsonMetadata | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PerpStatsItem {
|
export interface PerpStatsItem {
|
||||||
|
|
|
@ -49,7 +49,7 @@ export const FAVORITE_SWAPS_KEY = 'favoriteSwaps-0.1'
|
||||||
|
|
||||||
export const THEME_KEY = 'theme-0.1'
|
export const THEME_KEY = 'theme-0.1'
|
||||||
|
|
||||||
export const RPC_PROVIDER_KEY = 'rpcProviderKey-0.8'
|
export const RPC_PROVIDER_KEY = 'rpcProviderKey-0.9'
|
||||||
|
|
||||||
export const PRIORITY_FEE_KEY = 'priorityFeeKey-0.2'
|
export const PRIORITY_FEE_KEY = 'priorityFeeKey-0.2'
|
||||||
|
|
||||||
|
|
|
@ -84,5 +84,5 @@ export const nftThemeMeta: NftThemeMeta = {
|
||||||
|
|
||||||
export const CUSTOM_SKINS: { [key: string]: string } = {
|
export const CUSTOM_SKINS: { [key: string]: string } = {
|
||||||
bonk: '6FUYsgvSPiLsMpKZqLWswkw7j4juudZyVopU6RYKLkQ3',
|
bonk: '6FUYsgvSPiLsMpKZqLWswkw7j4juudZyVopU6RYKLkQ3',
|
||||||
pepe: '6FUYsgvSPiLsMpKZqLWswkw7j4juudZyVopU6RYKLkQ3',
|
pepe: 'B4QhXJaSnUBT8aWiPz5GmB9sjXdQDtHXv8x1WsRFHNJx',
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,7 @@ const enhanceNFT = (nft: NftWithATA) => {
|
||||||
collectionAddress: nft.collection?.address.toBase58(),
|
collectionAddress: nft.collection?.address.toBase58(),
|
||||||
mint: nft.mint.address.toBase58(),
|
mint: nft.mint.address.toBase58(),
|
||||||
tokenAccount: nft.tokenAccountAddress?.toBase58() || '',
|
tokenAccount: nft.tokenAccountAddress?.toBase58() || '',
|
||||||
|
json: nft.json,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
yarn.lock
20
yarn.lock
|
@ -26,24 +26,24 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
ws "^8.13.0"
|
ws "^8.13.0"
|
||||||
|
|
||||||
"@blockworks-foundation/mango-v4-settings@0.2.6":
|
"@blockworks-foundation/mango-v4-settings@0.2.8":
|
||||||
version "0.2.6"
|
version "0.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4-settings/-/mango-v4-settings-0.2.6.tgz#725a8cf669e164cd7694d97989472f7852afad68"
|
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4-settings/-/mango-v4-settings-0.2.8.tgz#fa88d6ddb6dcc1dd1cd8f75ab96bc0d41629799d"
|
||||||
integrity sha512-RK8O8lbflIN9IgNE1uUkjrtlv/7f0BjIqTwcuLNFos6/e/Q2/AnlXRlD5Y9WnO6xS7mXNsw9kr05xCxeYZzM1Q==
|
integrity sha512-20h5+Vky3YZfd3ekcnMgUxp1XaddFgtSNE6SPCy1oOAOjzvDHgZ3AVJd95WTTjTONGTZqqmTbP2ReWIu4ZfP6w==
|
||||||
dependencies:
|
dependencies:
|
||||||
bn.js "^5.2.1"
|
bn.js "^5.2.1"
|
||||||
eslint-config-prettier "^9.0.0"
|
eslint-config-prettier "^9.0.0"
|
||||||
|
|
||||||
"@blockworks-foundation/mango-v4@^0.19.15":
|
"@blockworks-foundation/mango-v4@^0.19.20":
|
||||||
version "0.19.15"
|
version "0.19.20"
|
||||||
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4/-/mango-v4-0.19.15.tgz#0e62d9c2f06c103b39abb648a529702048fd2706"
|
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4/-/mango-v4-0.19.20.tgz#5932b98bfc94eed1f7cdffdef535afe19c1cce03"
|
||||||
integrity sha512-aWtnBgbPJ2F1RZ4dCpu2ans5KQmt7d4en55Dp/n17hWjRUGA4tTPwthE8uoeRqc6ih19ldgDj2oMQAl6XzWQzg==
|
integrity sha512-UGPmJ/NPDdIHM7BcYSOOZHDYDse6mefTGI2IK9MRxaqAVpqfFj3Kjk8mM12O+CW1cySaMl3NUAyR/Ul0jGY+jg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@coral-xyz/anchor" "^0.27.0"
|
"@coral-xyz/anchor" "^0.27.0"
|
||||||
"@project-serum/serum" "0.13.65"
|
"@project-serum/serum" "0.13.65"
|
||||||
"@pythnetwork/client" "~2.14.0"
|
"@pythnetwork/client" "~2.14.0"
|
||||||
"@solana/spl-token" "0.3.7"
|
"@solana/spl-token" "0.3.7"
|
||||||
"@solana/web3.js" "^1.73.2"
|
"@solana/web3.js" "^1.78.2"
|
||||||
"@switchboard-xyz/sbv2-lite" "^0.1.6"
|
"@switchboard-xyz/sbv2-lite" "^0.1.6"
|
||||||
big.js "^6.1.1"
|
big.js "^6.1.1"
|
||||||
binance-api-node "^0.12.0"
|
binance-api-node "^0.12.0"
|
||||||
|
@ -1999,7 +1999,7 @@
|
||||||
"@wallet-standard/app" "^1.0.1"
|
"@wallet-standard/app" "^1.0.1"
|
||||||
"@wallet-standard/base" "^1.0.1"
|
"@wallet-standard/base" "^1.0.1"
|
||||||
|
|
||||||
"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.22.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.44.3", "@solana/web3.js@^1.50.1", "@solana/web3.js@^1.56.2", "@solana/web3.js@^1.63.1", "@solana/web3.js@^1.66.2", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.73.2", "@solana/web3.js@^1.78.3":
|
"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.22.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.44.3", "@solana/web3.js@^1.50.1", "@solana/web3.js@^1.56.2", "@solana/web3.js@^1.63.1", "@solana/web3.js@^1.66.2", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.78.2", "@solana/web3.js@^1.78.3":
|
||||||
version "1.78.4"
|
version "1.78.4"
|
||||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.78.4.tgz#e8ca9abe4ec2af5fc540c1d272efee24aaffedb3"
|
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.78.4.tgz#e8ca9abe4ec2af5fc540c1d272efee24aaffedb3"
|
||||||
integrity sha512-up5VG1dK+GPhykmuMIozJZBbVqpm77vbOG6/r5dS7NBGZonwHfTLdBbsYc3rjmaQ4DpCXUa3tUc4RZHRORvZrw==
|
integrity sha512-up5VG1dK+GPhykmuMIozJZBbVqpm77vbOG6/r5dS7NBGZonwHfTLdBbsYc3rjmaQ4DpCXUa3tUc4RZHRORvZrw==
|
||||||
|
|
Loading…
Reference in New Issue