Skip to content

Commit

Permalink
Merge branch 'main' into add_ethereum_chain
Browse files Browse the repository at this point in the history
  • Loading branch information
hyphenized authored Jan 19, 2023
2 parents 4c397e0 + 733ff47 commit d9d0fcc
Show file tree
Hide file tree
Showing 11 changed files with 500 additions and 73 deletions.
14 changes: 14 additions & 0 deletions background/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,20 @@ export function isFungibleAssetAmount(
): assetAmount is FungibleAssetAmount {
return isFungibleAsset(assetAmount.asset)
}
/**
* Flips `pair` and `amounts` values in the PricePoint object.
*
* @param pricePoint
* @returns pricePoint with flipped pair and amounts
*/
export function flipPricePoint(pricePoint: PricePoint): PricePoint {
const { pair, amounts, time } = pricePoint
return {
pair: [pair[1], pair[0]],
amounts: [amounts[1], amounts[0]],
time,
}
}

/**
* Converts the given source asset amount, fungible or non-fungible, to a target
Expand Down
8 changes: 2 additions & 6 deletions background/redux-slices/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ethers } from "ethers"
import {
AnyAsset,
AnyAssetAmount,
flipPricePoint,
isFungibleAsset,
isSmartContractFungibleAsset,
PricePoint,
Expand Down Expand Up @@ -237,12 +238,7 @@ export const selectAssetPricePoint = createSelector(

// Flip it if the price point looks like USD-ETH
if (pricePoint.pair[0].symbol !== assetToFind.symbol) {
const { pair, amounts, time } = pricePoint
pricePoint = {
pair: [pair[1], pair[0]],
amounts: [amounts[1], amounts[0]],
time,
}
pricePoint = flipPricePoint(pricePoint)
}

const assetDecimals = isFungibleAsset(assetToFind)
Expand Down
File renamed without changes.
22 changes: 14 additions & 8 deletions background/redux-slices/selectors/nftsSelectors_update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import {
getAdditionalDataForFilter,
getFilteredCollections,
getNFTsCount,
getTotalFloorPriceInETH,
} from "../utils/nfts_update"
import { selectAccountTotals } from "./accountsSelectors"
import { selectCurrentAccount } from "./uiSelectors"
getTotalFloorPrice,
} from "../utils/nfts-utils"
import { getAssetsState, selectAccountTotals } from "./accountsSelectors"
import { selectCurrentAccount, selectMainCurrencySymbol } from "./uiSelectors"

const selectNFTs = createSelector(
(state: RootState) => state.nftsUpdate,
Expand Down Expand Up @@ -96,13 +96,19 @@ const selectAllNFTBadgesCollections = createSelector(
export const selectFilteredNFTCollections = createSelector(
selectAllNFTCollections,
selectNFTFilters,
(collections, filters) => getFilteredCollections(collections, filters)
getAssetsState,
selectMainCurrencySymbol,
(collections, filters, assets, mainCurrencySymbol) =>
getFilteredCollections(collections, filters, assets, mainCurrencySymbol)
)

export const selectFilteredNFTBadgesCollections = createSelector(
selectAllNFTBadgesCollections,
selectNFTFilters,
(collections, filters) => getFilteredCollections(collections, filters)
getAssetsState,
selectMainCurrencySymbol,
(collections, filters, assets, mainCurrencySymbol) =>
getFilteredCollections(collections, filters, assets, mainCurrencySymbol)
)

/* Counting selectors */
Expand Down Expand Up @@ -137,7 +143,7 @@ export const selectFilteredNFTCollectionsCount = createSelector(
)

/* Total Floor Price selectors */
export const selectFilteredTotalFloorPriceInETH = createSelector(
export const selectFilteredTotalFloorPrice = createSelector(
selectFilteredNFTCollections,
(collections) => getTotalFloorPriceInETH(collections)
(collections) => getTotalFloorPrice(collections)
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { BUILT_IN_NETWORK_BASE_ASSETS } from "../../constants"
import { NFT } from "../../nfts"
import { AssetsState, selectAssetPricePoint } from "../assets"
import {
Filter,
FiltersState,
NFTCollectionCached,
SortType,
} from "../nfts_update"
import { enrichAssetAmountWithMainCurrencyValues } from "./asset-utils"

const ETH_SYMBOLS = ["ETH", "WETH"]

Expand All @@ -14,6 +17,14 @@ export type AccountData = {
avatarURL: string
}

type NFTCollectionEnriched = NFTCollectionCached & {
floorPrice?: {
value: number
valueUSD?: number
tokenSymbol: string
}
}

const isEnabledFilter = (id: string, filters: Filter[]): boolean => {
return !!filters.find((filter) => id === filter.id && filter.isEnabled)
}
Expand All @@ -30,24 +41,19 @@ export const getAdditionalDataForFilter = (
return a ? { name: a.name, thumbnailURL: a.avatarURL } : {}
}

/* Items are sorted by price in ETH. All other elements are added at the end. */
const sortByPrice = (
/* Items are sorted by price in USD. All other elements are added at the end. */
export const sortByPrice = (
type: "asc" | "desc",
collection1: NFTCollectionCached,
collection2: NFTCollectionCached
collection1: NFTCollectionEnriched,
collection2: NFTCollectionEnriched
): number => {
if (collection1.floorPrice && collection2.floorPrice) {
if (isETHPrice(collection1) && isETHPrice(collection2)) {
if (type === "asc") {
return collection1.floorPrice.value - collection2.floorPrice.value
}
return collection2.floorPrice.value - collection1.floorPrice.value
}
}
if (collection1.floorPrice === undefined) return 1
if (collection2.floorPrice === undefined) return -1
if (collection1.floorPrice?.valueUSD === undefined) return 1
if (collection2.floorPrice?.valueUSD === undefined) return -1

return 1
if (type === "asc") {
return collection1.floorPrice.valueUSD - collection2.floorPrice.valueUSD
}
return collection2.floorPrice.valueUSD - collection1.floorPrice.valueUSD
}

const sortByDate = (
Expand Down Expand Up @@ -127,31 +133,100 @@ const sortNFTs = (
}
}

export const getTotalFloorPriceInETH = (
type TotalFloorPriceMap = { [symbol: string]: number }

export const getTotalFloorPrice = (
collections: NFTCollectionCached[]
): number =>
collections.reduce((sum, collection) => {
if (collection.floorPrice && isETHPrice(collection)) {
return sum + collection.floorPrice.value * (collection.nftCount ?? 0)
}
): TotalFloorPriceMap =>
collections.reduce(
(acc, collection) => {
if (!collection.floorPrice) return acc

const sum = collection.floorPrice.value * (collection.nftCount ?? 0)

if (isETHPrice(collection)) {
acc.ETH += sum
} else {
acc[collection.floorPrice.tokenSymbol] ??= 0
acc[collection.floorPrice.tokenSymbol] += sum
}

return sum
}, 0)
return acc
},
{ ETH: 0 } as TotalFloorPriceMap
)

export const getNFTsCount = (collections: NFTCollectionCached[]): number =>
collections.reduce((sum, collection) => sum + (collection.nftCount ?? 0), 0)

export function enrichCollectionWithUSDFloorPrice(
collection: NFTCollectionCached,
assets: AssetsState,
mainCurrencySymbol: string
): NFTCollectionEnriched {
if (!collection.floorPrice) return collection

const { tokenSymbol, value } = collection.floorPrice
const symbol = isETHPrice(collection) ? "ETH" : tokenSymbol

const baseAsset = BUILT_IN_NETWORK_BASE_ASSETS.find(
(asset) => symbol === asset.symbol
)

if (!baseAsset) return collection

const pricePoint = selectAssetPricePoint(
assets,
baseAsset,
mainCurrencySymbol
)

const valueUSD =
enrichAssetAmountWithMainCurrencyValues(
{
asset: baseAsset,
amount: BigInt(Math.round(value * 10 ** baseAsset.decimals)),
},
pricePoint,
2
).mainCurrencyAmount ?? 0

return {
...collection,
floorPrice: {
value,
valueUSD,
tokenSymbol,
},
}
}

export const getFilteredCollections = (
collections: NFTCollectionCached[],
filters: FiltersState
): NFTCollectionCached[] =>
collections
filters: FiltersState,
assets: AssetsState,
mainCurrencySymbol: string
): NFTCollectionCached[] => {
const applyPriceSort = filters.type === "asc" || filters.type === "desc"

return collections
.filter(
(collection) =>
isEnabledFilter(collection.id, filters.collections) &&
isEnabledFilter(collection.owner, filters.accounts)
)
.map((collection) => sortNFTs(collection, filters.type))
.map((collection) => {
const collectionWithSortedNFTs = sortNFTs(collection, filters.type)

return applyPriceSort
? enrichCollectionWithUSDFloorPrice(
collectionWithSortedNFTs,
assets,
mainCurrencySymbol
)
: collectionWithSortedNFTs
})
.sort((collection1, collection2) =>
sortCollections(collection1, collection2, filters.type)
)
}
Loading

0 comments on commit d9d0fcc

Please sign in to comment.