Skip to content

Commit

Permalink
remove wallet, add crypto icons, add check using drop purchases, fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
alchemistgo87 committed Jul 21, 2023
1 parent 45713e6 commit ebf4b83
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 66 deletions.
2 changes: 2 additions & 0 deletions @types/graphql.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ declare module '*/drop.graphql' {
const defaultDocument: DocumentNode;
export const MintNft: DocumentNode;
export const GetDrop: DocumentNode;
export const GetDropPurchases: DocumentNode;

export default defaultDocument;
}
Expand Down Expand Up @@ -63,6 +64,7 @@ declare module '*/project.graphql' {
import { DocumentNode } from 'graphql';
const defaultDocument: DocumentNode;
export const GetProjectDrop: DocumentNode;
export const GetProjectDropPurchases: DocumentNode;

export default defaultDocument;
}
Expand Down
1 change: 1 addition & 0 deletions holaplex.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -1421,6 +1421,7 @@ type Query {
"""
creditSheet: [ActionCost!]!
drop: Drop
dropPurchases: Drop

"""
Returns a list of event types that an external service can subscribe to.
Expand Down
11 changes: 11 additions & 0 deletions prisma/migrations/20230721091723_drop_wallet/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:
- You are about to drop the `Wallet` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE "Wallet" DROP CONSTRAINT "Wallet_holaplexCustomerId_fkey";

-- DropTable
DROP TABLE "Wallet";
7 changes: 0 additions & 7 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,8 @@ model User {
holaplexCustomerId String? @unique @db.Uuid
accounts Account[]
sessions Session[]
wallets Wallet[]
}

model Wallet {
id String @id @default(cuid())
holaplexCustomerId String @db.Uuid
user User @relation(fields: [holaplexCustomerId], references: [holaplexCustomerId], onDelete: Cascade)
address String
}

model VerificationToken {
identifier String
Expand Down
1 change: 1 addition & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Me {

type Query {
drop: Drop
dropPurchases: Drop
me: Me
collections: [CollectionMint]
}
Expand Down
56 changes: 34 additions & 22 deletions src/app/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use client';
import Image from 'next/image';
import { useMemo } from 'react';
import { CollectionMint, Holder } from '@/graphql.types';
import { AssetType, CollectionMint, Holder, Purchase } from '@/graphql.types';
import { shorten } from '../modules/wallet';
import { MintDrop } from '@/mutations/mint.graphql';
import { ApolloError, useMutation, useQuery } from '@apollo/client';
import { GetDrop } from '@/queries/drop.graphql';
import { GetDropPurchases, GetDrop } from '@/queries/drop.graphql';
import Link from 'next/link';
import { isNil, not, pipe } from 'ramda';
import useMe from '@/hooks/useMe';
Expand All @@ -15,6 +15,7 @@ import { PopoverBox } from '../components/Popover';
import { Icon } from '../components/Icon';
import { signOut } from 'next-auth/react';
import Copy from '../components/Copy';
import CryptoIcon from '../components/CryptoIcon';

interface MintData {
mint: CollectionMint;
Expand All @@ -29,13 +30,17 @@ export default function Home({ session }: HomeProps) {
const dropQuery = useQuery(GetDrop);
const collection = dropQuery.data?.drop.collection;
const metadataJson = collection?.metadataJson;

const dropPurchasesQuery = useQuery(GetDropPurchases);
const walletAddresses = me?.wallets?.map((wallet) => wallet?.address);
const holder = useMemo(() => {
return collection?.holders?.find((holder: Holder) =>
walletAddresses?.includes(holder.address)

const purchase = useMemo(() => {
return dropPurchasesQuery.data?.dropPurchases.purchases?.find(
(purchase: Purchase) => walletAddresses?.includes(purchase.wallet)
);
}, [collection?.holders, walletAddresses]);
const owns = pipe(isNil, not)(holder);
}, [dropPurchasesQuery.data?.dropPurchases.purchases, walletAddresses]);

const purchased = pipe(isNil, not)(purchase);
const [mint, { loading }] = useMutation<MintData>(MintDrop, {
awaitRefetchQueries: true,
refetchQueries: [
Expand Down Expand Up @@ -98,23 +103,27 @@ export default function Home({ session }: HomeProps) {
Wallet addresses
</span>

<div className='flex flex-col gap-2 mt-1 items-center'>
<div className='flex flex-col gap-2 mt-4 items-center'>
{me?.wallets?.map((wallet) => {
return (
<div key={wallet?.address} className='flex gap-2'>
<span className='text-xs'>
{`(${wallet?.assetId}) ${shorten(
wallet?.address as string
)}`}
</span>
<div
key={wallet?.address}
className='flex gap-2 items-center'
>
<div className='flex items-center'>
<CryptoIcon assetType={wallet?.assetId as AssetType} />
<span className='text-xs'>
{shorten(wallet?.address as string)}
</span>
</div>
<Copy copyString={wallet?.address as string} />
</div>
);
})}
</div>
<button
onClick={() => signOut()}
className='text-cta font-medium md:font-bold md:border-2 md:rounded-full md:border-cta md:py-3 md:px-6 mt-10'
className='text-cta font-medium md:font-bold md:border-2 md:rounded-full md:border-cta md:py-3 md:px-6 mt-6'
>
Log out
</button>
Expand Down Expand Up @@ -191,7 +200,7 @@ export default function Home({ session }: HomeProps) {
<div className='font-bold rounded-full bg-backdrop w-32 h-12 transition animate-pulse' />
</>
) : session ? (
owns ? (
purchased ? (
<div className='flex flex-row w-full items-center gap-2 justify-between'>
<div className='flex flex-col gap-2'>
<span className='text-neautraltext font-semibold'>
Expand All @@ -215,16 +224,19 @@ export default function Home({ session }: HomeProps) {
/>

<div className='flex flex-col gap-1 justify-between'>
<span className='text-gray-300 text-xs'>
<span className='text-gray-300 text-xs mb-1'>
Wallets connected
</span>
{me?.wallets?.map((wallet) => {
return (
<span key={wallet?.address} className='text-sm'>
{`(${wallet?.assetId}) ${shorten(
wallet?.address as string
)}`}
</span>
<div key={wallet?.address} className='flex'>
<CryptoIcon
assetType={wallet?.assetId as AssetType}
/>
<span className='text-sm'>
{shorten(wallet?.address as string)}
</span>
</div>
);
})}
</div>
Expand Down
27 changes: 20 additions & 7 deletions src/app/collectibles/Collectibles.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
'use client';
import { useQuery } from '@apollo/client';
import { CollectionMint, CreationStatus } from '../../graphql.types';
import { AssetType, CollectionMint, CreationStatus } from '../../graphql.types';
import { GetCollections } from '@/queries/collections.graphql';
import { shorten } from '../../modules/wallet';
import Copy from '../../components/Copy';
import { signOut } from 'next-auth/react';
import useMe from '../../hooks/useMe';
import Link from 'next/link';
import { XMarkIcon, ArrowLeftIcon } from '@heroicons/react/24/solid';
import CryptoIcon from '../../components/CryptoIcon';

interface GetCollectionsData {
collections: [CollectionMint];
Expand All @@ -33,12 +34,24 @@ export default function Collectibles() {
<div className='flex flex-col gap-1 items-center'>
<img className='w-20 h-20 rounded-full' src={me?.image as string} />
<div className='mt-6'>
<span className='text-xs text-neautraltext'>Wallet address</span>
<div className='flex gap-2 mt-1'>
<span className='text-xs font-medium'>
{shorten(me?.wallet?.address as string)}
</span>
<Copy copyString={me?.wallet?.address as string} />
<span className='text-xs text-neautraltext'>Wallet addresses</span>
<div className='flex flex-col gap-2 mt-4 items-center'>
{me?.wallets?.map((wallet) => {
return (
<div
key={wallet?.address}
className='flex gap-2 items-center'
>
<div className='flex items-center'>
<CryptoIcon assetType={wallet?.assetId as AssetType} />
<span className='text-xs'>
{shorten(wallet?.address as string)}
</span>
</div>
<Copy copyString={wallet?.address as string} />
</div>
);
})}
</div>
</div>
</div>
Expand Down
20 changes: 20 additions & 0 deletions src/components/CryptoIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { AssetType } from '../graphql.types';
import { Icon } from './Icon';

interface CryptoIconProps {
assetType: AssetType;
className?: string;
}

export default function CryptoIcon({ assetType, className }: CryptoIconProps) {
switch (assetType) {
case AssetType.Sol:
return <Icon.Solana className={className} />;
case AssetType.Matic:
return <Icon.Polygon className={className} />;
case AssetType.Eth:
return <Icon.Eth className={className} />;
default:
return <></>;
}
}
70 changes: 70 additions & 0 deletions src/components/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,76 @@ export function Icon() {
return <div></div>;
}

function Polygon({ className = '' }: IconProps) {
return (
<svg
width='24'
height='22'
viewBox='0 0 24 22'
className={className}
xmlns='http://www.w3.org/2000/svg'
>
<path
d='M12.1149 4.27893C11.8225 4.11276 11.4465 4.11276 11.1123 4.27893L8.77285 5.64985L7.18538 6.52226L4.88773 7.89317C4.5953 8.05935 4.21932 8.05935 3.88512 7.89317L2.08877 6.81306C1.79634 6.64688 1.58747 6.31454 1.58747 5.94065V3.8635C1.58747 3.53116 1.75457 3.19881 2.08877 2.9911L3.88512 1.95252C4.17755 1.78635 4.55352 1.78635 4.88773 1.95252L6.68407 3.03264C6.9765 3.19881 7.18538 3.53116 7.18538 3.90504V5.27596L8.77285 4.36202V2.94955C8.77285 2.61721 8.60574 2.28487 8.27154 2.07715L4.9295 0.124629C4.63708 -0.041543 4.2611 -0.041543 3.92689 0.124629L0.501306 2.11869C0.167102 2.28487 0 2.61721 0 2.94955V6.8546C0 7.18694 0.167102 7.51929 0.501306 7.727L3.88512 9.67953C4.17755 9.8457 4.55352 9.8457 4.88773 9.67953L7.18538 8.35015L8.77285 7.4362L11.0705 6.10682C11.3629 5.94065 11.7389 5.94065 12.0731 6.10682L13.8695 7.1454C14.1619 7.31157 14.3708 7.64392 14.3708 8.0178V10.095C14.3708 10.4273 14.2037 10.7596 13.8695 10.9674L12.1149 12.0059C11.8225 12.1721 11.4465 12.1721 11.1123 12.0059L9.31593 10.9674C9.0235 10.8012 8.81462 10.4688 8.81462 10.095V8.76558L7.22715 9.67953V11.0504C7.22715 11.3828 7.39426 11.7151 7.72846 11.9228L11.1123 13.8754C11.4047 14.0415 11.7807 14.0415 12.1149 13.8754L15.4987 11.9228C15.7911 11.7567 16 11.4243 16 11.0504V7.10386C16 6.77151 15.8329 6.43917 15.4987 6.23145L12.1149 4.27893Z'
fill='white'
/>
</svg>
);
}
Icon.Polygon = Polygon;

function Solana({ className = '' }: IconProps) {
return (
<svg
width='24'
height='24'
viewBox='0 0 24 24'
className={className}
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path
d='M4.59949 4.14168C4.70006 4.0522 4.83281 4 4.96958 4H17.7377C17.971 4 18.0877 4.26099 17.9228 4.41385L15.4005 6.75153C15.304 6.84101 15.1712 6.89321 15.0304 6.89321H2.26229C2.02897 6.89321 1.91231 6.63222 2.07724 6.47936L4.59949 4.14168Z'
fill='white'
/>
<path
d='M15.4005 8.69508C15.304 8.6056 15.1712 8.5534 15.0304 8.5534H2.26229C2.02897 8.5534 1.91231 8.81439 2.07724 8.96725L4.59949 11.3049C4.69604 11.3944 4.82879 11.4466 4.96958 11.4466H17.7377C17.971 11.4466 18.0877 11.1856 17.9228 11.0328L15.4005 8.69508Z'
fill='white'
/>
<path
d='M4.59949 13.2485C4.69604 13.159 4.82879 13.1068 4.96958 13.1068H17.7377C17.971 13.1068 18.0877 13.3678 17.9228 13.5206L15.4005 15.8583C15.304 15.9478 15.1712 16 15.0304 16H2.26229C2.02897 16 1.91231 15.739 2.07724 15.5862L4.59949 13.2485Z'
fill='white'
/>
</svg>
);
}
Icon.Solana = Solana;

function Eth({ className = '' }: IconProps) {
return (
<svg
width='12'
height='18'
viewBox='0 0 12 18'
className={className}
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path d='M5.99825 0L0 9.16693L5.99825 12.4326V6.65578V0Z' fill='white' />
<path
d='M5.99825 0L5.8672 0.410163V12.3121L5.99825 12.4326L11.9965 9.16693L5.99825 0Z'
fill='white'
/>
<path
d='M5.99819 13.4787L5.92436 13.5616V17.8014L5.99819 18L12 10.2147L5.99819 13.4787Z'
fill='white'
/>
<path d='M5.99819 18V13.4787L0 10.2146L5.99819 18Z' fill='white' />
</svg>
);
}
Icon.Eth = Eth;

function Loading({ className }: IconProps) {
return (
<svg
Expand Down
2 changes: 2 additions & 0 deletions src/graphql.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1375,6 +1375,7 @@ export type Query = {
*/
creditSheet: Array<ActionCost>;
drop?: Maybe<Drop>;
dropPurchases?: Maybe<Drop>;
/**
* Returns a list of event types that an external service can subscribe to.
*
Expand Down Expand Up @@ -2280,6 +2281,7 @@ export type QueryResolvers<ContextType = any, ParentType extends ResolversParent
collections?: Resolver<Maybe<Array<Maybe<ResolversTypes['CollectionMint']>>>, ParentType, ContextType>;
creditSheet?: Resolver<Array<ResolversTypes['ActionCost']>, ParentType, ContextType>;
drop?: Resolver<Maybe<ResolversTypes['Drop']>, ParentType, ContextType>;
dropPurchases?: Resolver<Maybe<ResolversTypes['Drop']>, ParentType, ContextType>;
eventTypes?: Resolver<Array<ResolversTypes['EventType']>, ParentType, ContextType>;
invite?: Resolver<Maybe<ResolversTypes['Invite']>, ParentType, ContextType, RequireFields<QueryInviteArgs, 'id'>>;
me?: Resolver<Maybe<ResolversTypes['Me']>, ParentType, ContextType>;
Expand Down
12 changes: 2 additions & 10 deletions src/modules/user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ApolloClient, NormalizedCacheObject } from '@apollo/client';
import { PrismaClient } from '@prisma/client';
import { AssetType, Me, Project, User, Wallet } from '@/graphql.types';
import { AssetType, Me, Project } from '@/graphql.types';
import { GetCustomerWallets } from '@/queries/customer.graphql';

interface GetCustomerWalletsData {
Expand Down Expand Up @@ -42,19 +42,11 @@ export default class UserSource {
}
});

const assetTypes = process.env.HOLAPLEX_WALLET_ASSET_TYPE?.split(
','
) as AssetType[];

const wallets = data.project.customer?.treasury?.wallets?.filter((wallet) =>
assetTypes.includes(wallet.assetId as AssetType)
);

return {
name: user?.name,
email: user?.email,
image: user?.image,
wallets: wallets
wallets: data.project.customer?.treasury?.wallets
} as Me;
}
}
12 changes: 1 addition & 11 deletions src/pages/api/auth/[...nextauth].ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export const authOptions: NextAuthOptions = {

await Promise.all(
assetTypes?.map(async (assetType) => {
const createCustomerWalletResponse = await holaplex.mutate<
await holaplex.mutate<
CreateCustomerWalletData,
CreateCustomerWalletVars
>({
Expand All @@ -126,16 +126,6 @@ export const authOptions: NextAuthOptions = {
}
}
});

const wallet =
createCustomerWalletResponse.data?.createCustomerWallet.wallet;

await db.wallet.create({
data: {
holaplexCustomerId: me.holaplexCustomerId as string,
address: wallet?.address as string
}
});
})
);
}
Expand Down
Loading

0 comments on commit ebf4b83

Please sign in to comment.