-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ECO-2036): Add "My emojicoins" page (#606)
- Loading branch information
Showing
27 changed files
with
894 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"editor.codeActionsOnSave": { | ||
"source.fixAll": "explicit" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"$schema": "https://ui.shadcn.com/schema.json", | ||
"aliases": { | ||
"components": "components", | ||
"hooks": "hooks", | ||
"lib": "lib", | ||
"ui": "components/ui", | ||
"utils": "lib/utils/class-name" | ||
}, | ||
"iconLibrary": "lucide", | ||
"rsc": true, | ||
"style": "new-york", | ||
"tailwind": { | ||
"baseColor": "slate", | ||
"config": "tailwind.config.js", | ||
"css": "src/app/global.css", | ||
"cssVariables": true, | ||
"prefix": "" | ||
}, | ||
"tsx": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { getSymbolEmojisInString, symbolBytesToEmojis } from "@sdk/emoji_data"; | ||
import { fetchSpecificMarkets } from "@sdk/indexer-v2/queries"; | ||
import { toNominalPrice } from "@sdk/utils"; | ||
import { WalletClientPage } from "components/pages/wallet/WalletClientPage"; | ||
import { AptPriceContextProvider } from "context/AptPrice"; | ||
import { | ||
fetchAllFungibleAssetsBalance, | ||
type TokenBalance, | ||
} from "lib/aptos-indexer/fungible-assets"; | ||
import { getAptPrice } from "lib/queries/get-apt-price"; | ||
import { toNominal } from "lib/utils/decimals"; | ||
import { emojisToName } from "lib/utils/emojis-to-name-or-symbol"; | ||
import { type Metadata } from "next"; | ||
import { emojiNamesToPath } from "utils/pathname-helpers"; | ||
|
||
export const metadata: Metadata = { | ||
title: "Explore the cult", | ||
description: `Explore the emojicoin cult`, | ||
}; | ||
|
||
export type FullCoinData = Omit<TokenBalance, "amount"> & | ||
Awaited<ReturnType<typeof fetchSpecificMarkets>>[number] & { | ||
symbol: string; | ||
marketCap: number; | ||
emojiData: ReturnType<typeof symbolBytesToEmojis>; | ||
emojiName: string; | ||
emojiPath: string; | ||
amount: number; | ||
price: number; | ||
ownedValue: number; | ||
percentage?: number; | ||
}; | ||
|
||
export default async function WalletPage({ params }: { params: { address: string } }) { | ||
const [ownedTokens, aptPrice] = await Promise.all([ | ||
fetchAllFungibleAssetsBalance({ ownerAddress: params.address }), | ||
getAptPrice(), | ||
]); | ||
const markets = await fetchSpecificMarkets( | ||
ownedTokens.map((t) => getSymbolEmojisInString(t.metadata.symbol)) | ||
); | ||
const marketDataMap: Record<string, (typeof markets)[number]> = markets.reduce((acc, market) => { | ||
acc[market.market.symbolData.symbol] = market; | ||
return acc; | ||
}, {}); | ||
|
||
const coinsWithData = ownedTokens.map((coin) => { | ||
const marketData = marketDataMap[coin.metadata.symbol]; | ||
const emojiData = symbolBytesToEmojis(coin.metadata.symbol); | ||
const emojiName = emojisToName(emojiData.emojis); | ||
const emojiPath = emojiNamesToPath(emojiData.emojis.map((x) => x.name)); | ||
const price = marketData ? toNominalPrice(marketData.lastSwap.avgExecutionPriceQ64) : 0; | ||
const amount = toNominal(BigInt(coin.amount)); | ||
const ownedValue = amount * price; | ||
const marketCap = marketData ? toNominal(marketData.state.instantaneousStats.marketCap) : 0; | ||
return { | ||
...coin, | ||
...marketData, | ||
marketCap, | ||
emojiName, | ||
symbol: coin.metadata.symbol, | ||
emojiData, | ||
emojiPath, | ||
amount, | ||
price, | ||
ownedValue, | ||
// Will be calculated later. | ||
percentage: 0, | ||
}; | ||
}); | ||
|
||
const walletStats = coinsWithData.reduce( | ||
(acc, coin) => { | ||
acc.totalValue += coin.ownedValue; | ||
return acc; | ||
}, | ||
{ totalValue: 0 } | ||
); | ||
|
||
coinsWithData.forEach((coin) => { | ||
coin.percentage = (coin.ownedValue / walletStats.totalValue) * 100; | ||
}); | ||
|
||
return ( | ||
<div className="mx-auto"> | ||
<AptPriceContextProvider aptPrice={aptPrice}> | ||
<WalletClientPage | ||
address={params.address} | ||
ownedCoins={coinsWithData} | ||
walletStats={walletStats} | ||
/> | ||
</AptPriceContextProvider> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
src/typescript/frontend/src/components/pages/wallet/PortfolioRow.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { type FullCoinData } from "app/wallet/[address]/page"; | ||
import { FormattedNumber } from "components/FormattedNumber"; | ||
import { AptCell } from "components/ui/table-cells/apt-cell"; | ||
import { TableCell, TableRow } from "components/ui/table/table"; | ||
import { useAptPrice } from "context/AptPrice"; | ||
import { useRouter } from "next/navigation"; | ||
import { useMemo, type FC } from "react"; | ||
import { ROUTES } from "router/routes"; | ||
import { Emoji } from "utils/emoji"; | ||
|
||
interface Props { | ||
index: number; | ||
coinData: FullCoinData; | ||
walletStats: { | ||
totalValue: number; | ||
}; | ||
} | ||
|
||
export const PortfolioRow: FC<Props> = ({ coinData, index, walletStats }) => { | ||
const router = useRouter(); | ||
const aptPrice = useAptPrice(); | ||
const usdOwnedValue = useMemo( | ||
() => (aptPrice || 0) * coinData.ownedValue, | ||
[aptPrice, coinData.ownedValue] | ||
); | ||
return ( | ||
<TableRow | ||
index={index} | ||
onClick={() => router.push("/market/" + coinData.emojiPath)} | ||
className="cursor-pointer" | ||
> | ||
<TableCell className="text-center"> | ||
{!coinData.inBondingCurve ? ( | ||
<a | ||
className="hover:underline" | ||
href={`${ROUTES.pools}?pool=${coinData.symbol}`} | ||
onClick={(e) => e.stopPropagation()} | ||
> | ||
<Emoji | ||
className={`${coinData.symbol.length <= 2 ? "text-[24px]" : "text-[20px]"} text-nowrap`} | ||
emojis={coinData.symbol} | ||
/> | ||
</a> | ||
) : ( | ||
<Emoji | ||
className={`${coinData.symbol.length <= 2 ? "text-[24px]" : "text-[20px]"} text-nowrap`} | ||
emojis={coinData.symbol} | ||
/> | ||
)} | ||
</TableCell> | ||
<TableCell className="text-end"> | ||
<FormattedNumber | ||
scramble | ||
value={(coinData.ownedValue / walletStats.totalValue) * 100} | ||
suffix="%" | ||
style={"fixed"} | ||
/> | ||
</TableCell> | ||
<TableCell className="text-right"> | ||
<FormattedNumber scramble value={coinData.amount} style={"fixed"} /> | ||
</TableCell> | ||
<TableCell className="text-right"> | ||
<span className="flex items-center justify-end gap-1"> | ||
<AptCell value={coinData.marketCap} /> | ||
</span> | ||
</TableCell> | ||
<TableCell className="text-right"> | ||
<span className="flex items-center justify-end gap-1"> | ||
<FormattedNumber scramble value={usdOwnedValue} style={"fixed"} prefix="$" /> | ||
</span> | ||
</TableCell> | ||
<TableCell className="text-right px-6"> | ||
<span className="flex items-center justify-end gap-1"> | ||
<AptCell value={coinData.ownedValue} /> | ||
</span> | ||
</TableCell> | ||
</TableRow> | ||
); | ||
}; |
Oops, something went wrong.