Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: burn capital, landing page and multi burn #1222

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/icons/fire.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions networks.json
Original file line number Diff line number Diff line change
Expand Up @@ -10894,7 +10894,11 @@
"featureObjects": [
{
"type": "CosmWasmNFTsBurner",
"burnerContractAddress": "tori16tlfw7uq73d5n8j5tl0zl367c58f032j50jgxr3e7f09gez3xq5qvcrxy7"
"burnerContractAddress": "tori16tlfw7uq73d5n8j5tl0zl367c58f032j50jgxr3e7f09gez3xq5qvcrxy7",
"authorizedCollections": [
"tori-tori1upd858fjdlme0wv4vd2v7c4majyr9dg53rl72dzfhds9zusmn9mqzjk22e",
"tori-tori1quj5act407qgszngzsh9elcelzl9pgcglq3844cwqex3cxzzeres0ckprs"
]
}
],
"registryName": "teritori",
Expand Down Expand Up @@ -11075,7 +11079,10 @@
},
{
"type": "CosmWasmNFTsBurner",
"burnerContractAddress": "tori1qyl0j7a24amk8k8gcmvv07y2zjx7nkcwpk73js24euh64hkja6esd2p2xp"
"burnerContractAddress": "tori1qyl0j7a24amk8k8gcmvv07y2zjx7nkcwpk73js24euh64hkja6esd2p2xp",
"authorizedCollections": [
"testori-tori1r8raaqul4j05qtn0t05603mgquxfl8e9p7kcf7smwzcv2hc5rrlq0vket0"
]
}
],
"currencies": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const MainConnectWalletButton: React.FC<{
<View style={style}>
<PrimaryButton
size={size}
fullWidth
text="Connect wallet"
onPress={() => setIsConnectWalletVisible(true)}
/>
Expand Down
56 changes: 48 additions & 8 deletions packages/components/nfts/NFTView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { SecondaryButton } from "../buttons/SecondaryButton";
import { UserAvatarWithFrame } from "../images/AvatarWithFrame";
import { SpacerColumn, SpacerRow } from "../spacer";

import { PrimaryButton } from "@/components/buttons/PrimaryButton";
import { useFeedbacks } from "@/context/FeedbacksProvider";
import { TeritoriNftClient } from "@/contracts-clients/teritori-nft/TeritoriNft.client";
import { popularCollectionsQueryKey } from "@/hooks/marketplace/usePopularCollections";
Expand All @@ -59,6 +60,12 @@ import { nftBurnerUserCountQueryKey } from "@/hooks/nft-burner/useNFTBurnerUserC
import { collectionStatsQueryKey } from "@/hooks/useCollectionStats";
import { nftsQueryKey } from "@/hooks/useNFTs";
import { getKeplrSigningCosmWasmClient } from "@/networks/signer";
import {
addSelectedToBurn,
setShowBurnCart,
selectSelectedNFTIds as selectSelectedNFTIdsForBurn,
removeSelectedFromBurn,
} from "@/store/slices/burnCartItems";

// NOTE: we put content in a memoized component to only rerender the container when the window width changes

Expand Down Expand Up @@ -434,6 +441,23 @@ const NFTViewFooter: React.FC<{ nft: NFT; localSelected: boolean }> = memo(
({ nft, localSelected }) => {
const selectedWallet = useSelectedWallet();
const isOwner = nft.ownerId === selectedWallet?.userId;
const dispatch = useAppDispatch();

const burnerFeature = getNetworkFeature(
nft.networkId,
NetworkFeature.CosmWasmNFTsBurner,
);
const { data: authorizedCollections } = useNFTBurnerAuthorizedCollections(
nft.networkId,
);

const showRecycle =
!!burnerFeature &&
(authorizedCollections || []).includes(nft.nftContractAddress);

const selectedForBurn = useSelector(selectSelectedNFTIdsForBurn).includes(
nft.id,
);
return (
<View
style={{
Expand Down Expand Up @@ -473,14 +497,30 @@ const NFTViewFooter: React.FC<{ nft: NFT; localSelected: boolean }> = memo(
</BrandText>
</>
) : (
<BrandText
style={{
fontSize: 12,
color: neutral77,
}}
>
Not listed
</BrandText>
<>
{showRecycle ? (
<PrimaryButton
onPress={() => {
dispatch(setShowBurnCart(true));
if (!selectedForBurn) {
dispatch(addSelectedToBurn(nft));
} else {
dispatch(removeSelectedFromBurn(nft.id));
}
}}
text={selectedForBurn ? "Added to the burn 🔥" : "Burnable"}
/>
) : (
<BrandText
style={{
fontSize: 12,
color: neutral77,
}}
>
Not listed
</BrandText>
)}
</>
)}
</View>
<SpacerRow size={2} />
Expand Down
1 change: 1 addition & 0 deletions packages/hooks/useCollectionInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { isLinkBanned } from "@/utils/link-ban";
export const useCollectionInfo = (
id: string,
forceInterval?: number,
enabled: boolean = true,
): {
collectionInfo: CollectionInfo;
notFound: boolean;
Expand Down
9 changes: 6 additions & 3 deletions packages/hooks/useCollectionStats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import { parseNetworkObjectId, NetworkKind } from "@/networks";
import { getMarketplaceClient } from "@/utils/backend";

export const collectionStatsQueryKey = (
collectionId: string,
collectionId?: string,
ownerId?: string,
) => {
const qk = ["collectionStats", collectionId];
if (ownerId) {
const qk = ["collectionStats"];
if (collectionId) {
qk.push(collectionId);
}
if (collectionId && ownerId) {
qk.push(ownerId);
}
return qk;
Expand Down
1 change: 1 addition & 0 deletions packages/networks/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type CosmWasmPremiumFeed = z.infer<typeof zodCosmWasmPremiumFeed>;
const zodCosmWasmNFTsBurner = z.object({
type: z.literal(NetworkFeature.CosmWasmNFTsBurner),
burnerContractAddress: z.string(),
authorizedCollections: z.array(z.string()), // FIXME: use nft contract address instead of minter contract address in ids
});

export type CosmWasmNFTsBurner = z.infer<typeof zodCosmWasmNFTsBurner>;
Expand Down
3 changes: 3 additions & 0 deletions packages/networks/teritori-testnet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const nftsBurnerFeature: CosmWasmNFTsBurner = {
type: NetworkFeature.CosmWasmNFTsBurner,
burnerContractAddress:
"tori1qyl0j7a24amk8k8gcmvv07y2zjx7nkcwpk73js24euh64hkja6esd2p2xp",
authorizedCollections: [
"testori-tori1r8raaqul4j05qtn0t05603mgquxfl8e9p7kcf7smwzcv2hc5rrlq0vket0",
],
};

const riotContractAddressGen0 =
Expand Down
4 changes: 4 additions & 0 deletions packages/networks/teritori/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ const burnCapitalFeature: CosmWasmNFTsBurner = {
type: NetworkFeature.CosmWasmNFTsBurner,
burnerContractAddress:
"tori16tlfw7uq73d5n8j5tl0zl367c58f032j50jgxr3e7f09gez3xq5qvcrxy7",
authorizedCollections: [
"tori-tori1upd858fjdlme0wv4vd2v7c4majyr9dg53rl72dzfhds9zusmn9mqzjk22e", // Sasquatch Society Farmers
"tori-tori1quj5act407qgszngzsh9elcelzl9pgcglq3844cwqex3cxzzeres0ckprs", // ToriWadz
],
};

export const teritoriNetwork: CosmosNetworkInfo = {
Expand Down
96 changes: 85 additions & 11 deletions packages/screens/BurnCapital/BurnCapitalScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,101 @@
import React, { useEffect } from "react";
import { View } from "react-native";
import { useDispatch } from "react-redux";

import { BrandText } from "@/components/BrandText";
import { ScreenContainer } from "@/components/ScreenContainer";
import { useNFTBurnerTotal } from "@/hooks/nft-burner/useNFTBurnerTotal";
import { useNFTBurnerUserCount } from "@/hooks/nft-burner/useNFTBurnerUserCount";
import { useIsMobile } from "@/hooks/useIsMobile";
import { useSelectedNetworkId } from "@/hooks/useSelectedNetwork";
import useSelectedWallet from "@/hooks/useSelectedWallet";
import { teritoriNetwork } from "@/networks/teritori";
import { ScreenFC } from "@/utils/navigation";
import { NetworkFeature, getNetwork } from "@/networks";
import { BurnSideCart } from "@/screens/BurnCapital/components/BurnSideCart";
import { BurnableNFTs } from "@/screens/BurnCapital/components/BurnableNFTs";
import { TopSectionConnectWallet } from "@/screens/BurnCapital/components/TopSectionConnectWallet";
import { setSelectedNetworkId } from "@/store/slices/settings";
import { ScreenFC, useAppNavigation } from "@/utils/navigation";
import { neutral00, neutral33 } from "@/utils/style/colors";
import { fontSemibold20 } from "@/utils/style/fonts";
import { layout } from "@/utils/style/layout";

export const BurnCapitalScreen: ScreenFC<"BurnCapital"> = ({ route }) => {
const inputNetwork = route.params?.network || teritoriNetwork.id;
const inputNetwork = route.params?.network;
const selectedWallet = useSelectedWallet();
const selectedNetworkId = useSelectedNetworkId();
const dispatch = useDispatch();
const navigation = useAppNavigation();
const isMobile = useIsMobile();

useEffect(() => {
if (!inputNetwork) {
return;
}
const network = getNetwork(inputNetwork);
if (!network) {
return;
}
dispatch(setSelectedNetworkId(network.id));
}, [dispatch, inputNetwork]);

const { data: count } = useNFTBurnerUserCount(selectedWallet?.userId);
const { data: total } = useNFTBurnerTotal(selectedNetworkId);
return (
<ScreenContainer fullWidth forceNetworkId={inputNetwork}>
<BrandText>Burn Capital</BrandText>
{typeof total === "number" && (
<BrandText>Total burned: {total}</BrandText>
)}
{typeof count === "number" && (
<BrandText>Burned by you: {count}</BrandText>
)}
<ScreenContainer
isLarge
footerChildren={<></>}
fullWidth
forceNetworkFeatures={[NetworkFeature.CosmWasmNFTsBurner]}
headerChildren={
<BrandText style={fontSemibold20}>BURN Capital 🔥</BrandText>
}
responsive
onBackPress={() => navigation.navigate("Marketplace")}
>
<View
style={{
marginTop: layout.spacing_x4,
}}
>
<View
style={{
flexWrap: "nowrap",
justifyContent: "space-between",
alignItems: "center",
}}
>
<TopSectionConnectWallet />
{typeof total === "number" && (
<BrandText>Total burned: {total}</BrandText>
)}
{typeof count === "number" && (
<BrandText>Burned by you: {count}</BrandText>
)}

<BurnableNFTs
ownerId={selectedWallet?.userId || ""}
style={{ marginHorizontal: layout.spacing_x3 }}
/>
<BurnSideCart
style={{
position: isMobile ? "relative" : "absolute",
right: isMobile ? 0 : 50,
top: isMobile ? 0 : 500,
marginTop: layout.spacing_x4,
flexDirection: "column",
width: 245,
marginBottom: layout.spacing_x2_5,
backgroundColor: neutral00,
borderRadius: layout.spacing_x2,
borderColor: neutral33,
borderWidth: 1,
paddingVertical: layout.spacing_x1,
paddingHorizontal: layout.spacing_x1_5,
borderStyle: "solid",
}}
/>
</View>
</View>
</ScreenContainer>
);
};
Loading
Loading