diff --git a/components/OpenOrdersTable.tsx b/components/OpenOrdersTable.tsx index 46ed5d70..4aa6b8c6 100644 --- a/components/OpenOrdersTable.tsx +++ b/components/OpenOrdersTable.tsx @@ -414,6 +414,7 @@ const OpenOrdersTable = () => { const bidInfo = useMangoStore.getState().accountInfos[marketConfig.bidsKey.toString()] const wallet = useMangoStore.getState().wallet.current + const referrerPk = useMangoStore.getState().referrerPk if (!wallet || !mangoGroup || !mangoAccount || !market) return setModifyId(order.orderId) @@ -455,7 +456,9 @@ const OpenOrdersTable = () => { size, orderType, 0, - order.side === 'buy' ? askInfo : bidInfo + order.side === 'buy' ? askInfo : bidInfo, + false, + referrerPk ) } notify({ title: t('successfully-placed'), txid }) diff --git a/components/RecentMarketTrades.tsx b/components/RecentMarketTrades.tsx index 25c600b4..730f98f9 100644 --- a/components/RecentMarketTrades.tsx +++ b/components/RecentMarketTrades.tsx @@ -4,7 +4,7 @@ import useInterval from '../hooks/useInterval' import ChartApi from '../utils/chartDataConnector' import { ElementTitle } from './styles' import { getDecimalCount, isEqual, usdFormatter } from '../utils/index' -import useMangoStore from '../stores/useMangoStore' +import useMangoStore, { CLUSTER } from '../stores/useMangoStore' import { useViewport } from '../hooks/useViewport' import { breakpoints } from './TradePageGrid' import { ExpandableRow } from './TableElements' @@ -37,11 +37,15 @@ export default function RecentMarketTrades() { }, [marketConfig, trades]) useEffect(() => { - fetchTradesForChart() + if (CLUSTER === 'mainnet') { + fetchTradesForChart() + } }, [fetchTradesForChart]) useInterval(async () => { - fetchTradesForChart() + if (CLUSTER === 'mainnet') { + fetchTradesForChart() + } }, 2000) return !isMobile ? ( diff --git a/components/TradingView/index.tsx b/components/TradingView/index.tsx index 7d59d2f0..90aa3841 100755 --- a/components/TradingView/index.tsx +++ b/components/TradingView/index.tsx @@ -270,6 +270,7 @@ const TVChartContainer = () => { const bidInfo = useMangoStore.getState().accountInfos[marketConfig.bidsKey.toString()] const wallet = useMangoStore.getState().wallet.current + const referrerPk = useMangoStore.getState().referrerPk if (!wallet || !mangoGroup || !mangoAccount || !market) return @@ -311,7 +312,9 @@ const TVChartContainer = () => { order.size, orderType, 0, - order.side === 'buy' ? askInfo : bidInfo + order.side === 'buy' ? askInfo : bidInfo, + false, + referrerPk ) } diff --git a/components/trade_form/AdvancedTradeForm.tsx b/components/trade_form/AdvancedTradeForm.tsx index 990dbc5b..c4799f53 100644 --- a/components/trade_form/AdvancedTradeForm.tsx +++ b/components/trade_form/AdvancedTradeForm.tsx @@ -569,6 +569,7 @@ export default function AdvancedTradeForm({ const bidInfo = useMangoStore.getState().accountInfos[marketConfig.bidsKey.toString()] const wallet = useMangoStore.getState().wallet.current + const referrerPk = useMangoStore.getState().referrerPk if (!wallet || !mangoGroup || !mangoAccount || !market) return @@ -667,7 +668,8 @@ export default function AdvancedTradeForm({ perpOrderType, Date.now(), side === 'buy' ? askInfo : bidInfo, // book side used for ConsumeEvents - reduceOnly + reduceOnly, + referrerPk ) } } diff --git a/hooks/useHydrateStore.tsx b/hooks/useHydrateStore.tsx index f46bf5ec..8f2f1331 100644 --- a/hooks/useHydrateStore.tsx +++ b/hooks/useHydrateStore.tsx @@ -1,6 +1,6 @@ import { useEffect } from 'react' -import { AccountInfo } from '@solana/web3.js' -import useMangoStore from '../stores/useMangoStore' +import { AccountInfo, PublicKey } from '@solana/web3.js' +import useMangoStore, { programId } from '../stores/useMangoStore' import useInterval from './useInterval' import { Orderbook as SpotOrderBook, Market } from '@project-serum/serum' import { @@ -8,6 +8,8 @@ import { BookSideLayout, MangoAccountLayout, PerpMarket, + ReferrerMemory, + ReferrerMemoryLayout, } from '@blockworks-foundation/mango-client' import { actionsSelector, @@ -91,6 +93,7 @@ const useHydrateStore = () => { }) }, [marketConfig, markets, setMangoStore]) + // watch selected Mango Account for changes useEffect(() => { if (!mangoAccount) return console.log('in mango account WS useEffect') @@ -132,6 +135,42 @@ const useHydrateStore = () => { } }, [mangoAccount]) + // fetch referrer for selected Mango Account + useEffect(() => { + if (mangoAccount) { + const fetchReferrer = async () => { + try { + const [referrerMemoryPk] = await PublicKey.findProgramAddress( + [ + mangoAccount.publicKey.toBytes(), + new Buffer('ReferrerMemory', 'utf-8'), + ], + programId + ) + console.log('referrerMemoryPk', referrerMemoryPk) + const info = await connection.getAccountInfo(referrerMemoryPk) + console.log('info useHydrateStore set referrer is:', info) + + if (info) { + const decodedReferrer = ReferrerMemoryLayout.decode(info.data) + const referrerMemory = new ReferrerMemory(decodedReferrer) + console.log( + 'referrer is saved as:', + referrerMemory.referrerMangoAccount + ) + setMangoStore((state) => { + state.referrerPk = referrerMemory.referrerMangoAccount + }) + } + } catch (e) { + console.error('Unable to fetch referrer', e) + } + } + + fetchReferrer() + } + }, [mangoAccount]) + // hydrate orderbook with all markets in mango group useEffect(() => { let previousBidInfo: AccountInfo | null = null diff --git a/pages/_app.tsx b/pages/_app.tsx index 6e24baf2..804bbc47 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -20,7 +20,15 @@ import { useOpenOrders } from '../hooks/useOpenOrders' import usePerpPositions from '../hooks/usePerpPositions' import { useEffect } from 'react' import { PublicKey } from '@solana/web3.js' -import { mangoClientSelector, mangoGroupSelector } from '../stores/selectors' +import { + connectionSelector, + mangoClientSelector, + mangoGroupSelector, +} from '../stores/selectors' +import { + ReferrerIdRecordLayout, + ReferrerIdRecord, +} from '@blockworks-foundation/mango-client' const MangoStoreUpdater = () => { useHydrateStore() @@ -42,30 +50,37 @@ const PerpPositionsStoreUpdater = () => { return null } -const TrackReferrer = () => { +const FetchReferrer = () => { const setMangoStore = useMangoStore((s) => s.set) const mangoClient = useMangoStore(mangoClientSelector) const mangoGroup = useMangoStore(mangoGroupSelector) + const connection = useMangoStore(connectionSelector) const router = useRouter() const { query } = router useEffect(() => { const storeReferrer = async () => { if (query.ref && mangoGroup) { - let reffererPk + let referrerPk if (query.ref.length === 44) { - reffererPk = new PublicKey(query.ref) + referrerPk = new PublicKey(query.ref) } else { const { referrerPda } = await mangoClient.getReferrerPda( mangoGroup, query.ref as string ) - reffererPk = referrerPda + console.log('in App referrerPda', referrerPda) + const info = await connection.getAccountInfo(referrerPda) + console.log('in App referrerPda info', info) + if (info) { + const decoded = ReferrerIdRecordLayout.decode(info.data) + const referrerRecord = new ReferrerIdRecord(decoded) + referrerPk = referrerRecord.referrerMangoAccount + } } - console.log('reffererPk', reffererPk) - + console.log('in App referrerPk from url is:', referrerPk) setMangoStore((state) => { - state.ref = reffererPk + state.referrerPk = referrerPk }) } } @@ -146,7 +161,7 @@ function App({ Component, pageProps }) { - + diff --git a/pages/referral.tsx b/pages/referral.tsx index 6b57ec72..59c4d6c3 100644 --- a/pages/referral.tsx +++ b/pages/referral.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { useEffect, useState, useCallback } from 'react' import PageBodyContainer from '../components/PageBodyContainer' import TopBar from '../components/TopBar' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' @@ -14,7 +14,10 @@ import Button from '../components/Button' import { copyToClipboard } from '../utils' import Input from '../components/Input' import { notify } from '../utils/notifications' -import { getMarketIndexBySymbol } from '@blockworks-foundation/mango-client' +import { + getMarketIndexBySymbol, + ReferrerIdRecord, +} from '@blockworks-foundation/mango-client' export async function getStaticProps({ locale }) { return { @@ -32,18 +35,21 @@ export default function Referral() { const client = useMangoStore(mangoClientSelector) const wallet = useMangoStore(walletSelector) - const [customRefLink, setCustomRefLink] = useState('') + const [customRefLinkInput, setCustomRefLinkInput] = useState('') + const [existingCustomRefLInks, setExistingCustomRefLinks] = + useState() - console.log('MangoAccount', mangoAccount) + const fetchCustomReferralLinks = useCallback(async () => { + const referrerIds = await client.getReferrerIdsForMangoAccount(mangoAccount) - // TODO: check if this is still needed on every top level page - // useEffect(() => { - // // @ts-ignore - // if (window.solana) { - // // @ts-ignore - // window.solana.connect({ onlyIfTrusted: true }) - // } - // }, []) + setExistingCustomRefLinks(referrerIds) + }, [mangoAccount]) + + useEffect(() => { + if (mangoAccount) { + fetchCustomReferralLinks() + } + }, [mangoAccount]) const submitRefLink = async () => { try { @@ -51,7 +57,7 @@ export default function Referral() { mangoGroup, mangoAccount, wallet, - customRefLink + customRefLinkInput ) notify({ txid, @@ -72,6 +78,8 @@ export default function Referral() { mangoGroup && mangoAccount ? mangoAccount.deposits[mngoIndex].toNumber() > 10000 : false + const hasCustomRefLinks = + existingCustomRefLInks && existingCustomRefLInks.length > 0 return (
@@ -112,6 +120,7 @@ export default function Referral() { {mangoAccount.publicKey.toString()}
) : null} +
+ {hasCustomRefLinks + ? existingCustomRefLInks.map((customRefs) => { + return ( +
+
+
{`https://trade.mango.markets?ref=${customRefs.referrerId}`}
+
+ +
+
+
+ ) + }) + : null} +
diff --git a/stores/useMangoStore.tsx b/stores/useMangoStore.tsx index caec89ce..af7e00f5 100644 --- a/stores/useMangoStore.tsx +++ b/stores/useMangoStore.tsx @@ -159,7 +159,7 @@ export interface MangoStore extends State { cache: MangoCache | null } mangoAccounts: MangoAccount[] - ref: string + referrerPk: PublicKey | null selectedMangoAccount: { current: MangoAccount | null initialLoad: boolean @@ -272,7 +272,7 @@ const useMangoStore = create((set, get) => { }, mangoGroups: [], mangoAccounts: [], - ref: '', + referrerPk: null, selectedMangoAccount: { current: null, initialLoad: true, diff --git a/utils/mango.tsx b/utils/mango.tsx index 3ff40fd8..58b8e5f8 100644 --- a/utils/mango.tsx +++ b/utils/mango.tsx @@ -17,7 +17,8 @@ export async function deposit({ const wallet = useMangoStore.getState().wallet.current const tokenIndex = mangoGroup.getTokenIndex(fromTokenAcc.mint) const mangoClient = useMangoStore.getState().connection.client - const referrer = useMangoStore.getState().ref + const referrer = useMangoStore.getState().referrerPk + console.log('referrerPk', referrer) if (mangoAccount) { return await mangoClient.deposit( @@ -36,6 +37,7 @@ export async function deposit({ wallet.publicKey, false ) + console.log('in deposit and create, referrer is', referrer) return await mangoClient.createMangoAccountAndDeposit( mangoGroup, wallet, diff --git a/yarn.lock b/yarn.lock index d5924164..ad170e3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1292,12 +1292,16 @@ ======= "@blockworks-foundation/mango-client@git+https://github.com/blockworks-foundation/mango-client-v3.git#dd/reflinks": version "3.3.13" +<<<<<<< HEAD <<<<<<< HEAD resolved "git+https://github.com/blockworks-foundation/mango-client-v3.git#33ceaf776f95c95d647d2624484b8fbc412f7898" >>>>>>> e0d3a1f... create referral page ======= resolved "git+https://github.com/blockworks-foundation/mango-client-v3.git#148835a26d004808e4a8bc5e7335957fa31becd5" >>>>>>> 33c4938... wip +======= + resolved "git+https://github.com/blockworks-foundation/mango-client-v3.git#2e3b6d2927b77c8cf1104cd1acf38546f28ea54f" +>>>>>>> 6d27077... add ref links dependencies: "@project-serum/anchor" "^0.16.2" "@project-serum/serum" "0.13.55" @@ -2173,6 +2177,7 @@ dotenv "10.0.0" "@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0": +<<<<<<< HEAD <<<<<<< HEAD version "1.34.0" resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.34.0.tgz#33becf2c7e87497d73406374185e54e0b7bc235d" @@ -2182,6 +2187,11 @@ resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.33.0.tgz#3b8c0b4cd259ffe8764937f1001f79958c5d9533" integrity sha512-R53wvQQsUKCCJ9UmOfDlxCwC94jzjmpjr6wT/Xf1uFavZblSLAtzLaF4vbGIS465lk3mW6oJMtASd8cqSnr8Mw== >>>>>>> 33c4938... wip +======= + version "1.34.0" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.34.0.tgz#33becf2c7e87497d73406374185e54e0b7bc235d" + integrity sha512-6QvqN2DqEELvuV+5yUQM8P9fRiSG+6SzQ58HjumJqODu14r7eu5HXVWEymvKAvMLGME+0TmAdJHjw9xD5NgUWA== +>>>>>>> 6d27077... add ref links dependencies: "@babel/runtime" "^7.12.5" "@ethersproject/sha2" "^5.5.0" @@ -3180,16 +3190,11 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" -bn.js@5.1.3, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9, bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@~5.2.0: +bn.js@5.1.3, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9, bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.2.0, bn.js@~5.2.0: version "5.1.3" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== -bn.js@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" - integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== - boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"