From bd071c10b4a20369fae4ac46e68d388251356f3c Mon Sep 17 00:00:00 2001 From: thisisommore Date: Sun, 3 Sep 2023 17:34:29 +0000 Subject: [PATCH] Add unmonetize support --- src/app/account/AccountListBtn.tsx | 28 ++++++++ src/app/account/page.tsx | 70 ++++++++++--------- .../octav3/GET_ALL_MUSIC/getAllMusic.ts | 2 +- .../GET_MY_LISTED_MUSIC/getMyListedMusic.ts | 3 +- .../queries/octav3/__generated__/gql.ts | 8 +-- .../queries/octav3/__generated__/graphql.ts | 12 +++- src/services/smart-contract/unmonetize.ts | 27 +++++++ 7 files changed, 109 insertions(+), 41 deletions(-) create mode 100644 src/app/account/AccountListBtn.tsx create mode 100644 src/services/smart-contract/unmonetize.ts diff --git a/src/app/account/AccountListBtn.tsx b/src/app/account/AccountListBtn.tsx new file mode 100644 index 0000000..c946fac --- /dev/null +++ b/src/app/account/AccountListBtn.tsx @@ -0,0 +1,28 @@ +import OButton from "@/components/OButton/OButton"; +import React from "react"; + +const AccountListBtn = ({ + monetizeId, + onList, + onUnlist, +}: { + // monetizeId should be -1 when it is non existence + monetizeId: bigint; + onList: () => void; + onUnlist: () => void; +}) => { + return ( + -1 ? "gray" : "yellow"} + btnType="fill" + className="w-full mt-2" + onClick={() => { + (monetizeId ?? -1) > -1 ? onUnlist() : onList(); + }} + > + {(monetizeId ?? -1) > -1 ? "Unlist" : "List"} + + ); +}; + +export default AccountListBtn; diff --git a/src/app/account/page.tsx b/src/app/account/page.tsx index 4ebd335..2a8605f 100644 --- a/src/app/account/page.tsx +++ b/src/app/account/page.tsx @@ -18,6 +18,8 @@ import { USDCxWalletBalanceSub } from "@/subs/WalletBalanceSub"; import { useQuery } from "@apollo/client"; import React, { useContext, useEffect, useState } from "react"; import { usePublicClient, useWalletClient } from "wagmi"; +import AccountListBtn from "./AccountListBtn"; +import { unmonetize } from "@/services/smart-contract/unmonetize"; const Account = () => { const { data: walletClient } = useWalletClient(); @@ -136,9 +138,9 @@ const Account = () => { handlePlaySongSpinamp(e); }} customBtn={ - { + { if (!e.contractAddress || !e.tokenId) return false; return ( (ele.musicNftAddr as string).toLowerCase() == @@ -146,13 +148,9 @@ const Account = () => { (ele.musicNftTokenId as string).toLowerCase() == e.tokenId.toLowerCase() ); - }) ?? -1) > -1 - ? "gray" - : "yellow" - } - btnType="fill" - className="w-full mt-2" - onClick={() => { + })?.id ?? "-1" + )} + onList={() => { //TODO error if ( !walletClient || @@ -170,20 +168,18 @@ const Account = () => { walletClient ); }} - > - {myListedMusic && - myListedMusic?.octaveTokens.findIndex((ele) => { - if (!e.contractAddress || !e.tokenId) return false; - return ( - (ele.musicNftAddr as string).toLowerCase() == - e.contractAddress.toLowerCase() && - (ele.musicNftTokenId as string).toLowerCase() == - e.tokenId.toLowerCase() - ); - }) > -1 - ? "Unlist" - : "List"} - + onUnlist={() => { + if ( + !walletClient || + !publicClient || + !e.contractAddress || + !e.tokenId || + !e.tokenUri + ) + return; + unmonetize(BigInt(e.tokenId), publicClient, walletClient); + }} + /> } /> ); @@ -198,11 +194,19 @@ const Account = () => { handlePlaySong(e); }} customBtn={ - { + { + if (!e.id) return false; + return ( + (ele.musicNftAddr as string).toLowerCase() == + MusicNFTAddr.toLowerCase() && + (ele.musicNftTokenId as string).toLowerCase() == + e.id.toLowerCase() + ); + })?.id ?? "-1" + )} + onList={() => { //TODO error if (!walletClient || !publicClient || !e.id || !e.tokenUri) return; @@ -214,9 +218,11 @@ const Account = () => { walletClient ); }} - > - List - + onUnlist={() => { + if (!walletClient || !publicClient || !e.id) return; + unmonetize(BigInt(e.id), publicClient, walletClient); + }} + /> } /> ); diff --git a/src/graph-ql/queries/octav3/GET_ALL_MUSIC/getAllMusic.ts b/src/graph-ql/queries/octav3/GET_ALL_MUSIC/getAllMusic.ts index 2782f4d..7668dd3 100644 --- a/src/graph-ql/queries/octav3/GET_ALL_MUSIC/getAllMusic.ts +++ b/src/graph-ql/queries/octav3/GET_ALL_MUSIC/getAllMusic.ts @@ -2,7 +2,7 @@ import { gql } from "../__generated__"; export const GET_ALL_MUSIC = gql(` query GetAllMusic @api(name: octav3){ - octaveTokens { + octaveTokens(where:{closed:false}) { id owner musicNftAddr diff --git a/src/graph-ql/queries/octav3/GET_MY_LISTED_MUSIC/getMyListedMusic.ts b/src/graph-ql/queries/octav3/GET_MY_LISTED_MUSIC/getMyListedMusic.ts index 5734c1f..5118941 100644 --- a/src/graph-ql/queries/octav3/GET_MY_LISTED_MUSIC/getMyListedMusic.ts +++ b/src/graph-ql/queries/octav3/GET_MY_LISTED_MUSIC/getMyListedMusic.ts @@ -2,7 +2,8 @@ import { gql } from "../__generated__"; export const GET_MY_LISTED_MUSIC = gql(` query GetMyListedMusic($owner:Bytes) @api(name: octav3){ - octaveTokens(where:{owner:$owner}) { + octaveTokens(where:{owner:$owner,closed:false}) { + id musicNftAddr musicNftTokenId } diff --git a/src/graph-ql/queries/octav3/__generated__/gql.ts b/src/graph-ql/queries/octav3/__generated__/gql.ts index ff7d10d..f22b78b 100644 --- a/src/graph-ql/queries/octav3/__generated__/gql.ts +++ b/src/graph-ql/queries/octav3/__generated__/gql.ts @@ -13,8 +13,8 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/ * Therefore it is highly recommended to use the babel or swc plugin for production. */ const documents = { - "\nquery GetAllMusic @api(name: octav3){\n octaveTokens {\n id\n owner\n musicNftAddr\n musicNftTokenId\n tokenUri\n }\n }\n": types.GetAllMusicDocument, - "\nquery GetMyListedMusic($owner:Bytes) @api(name: octav3){\n octaveTokens(where:{owner:$owner}) {\n musicNftAddr\n musicNftTokenId\n }\n }\n": types.GetMyListedMusicDocument, + "\nquery GetAllMusic @api(name: octav3){\n octaveTokens(where:{closed:false}) {\n id\n owner\n musicNftAddr\n musicNftTokenId\n tokenUri\n }\n }\n": types.GetAllMusicDocument, + "\nquery GetMyListedMusic($owner:Bytes) @api(name: octav3){\n octaveTokens(where:{owner:$owner,closed:false}) {\n id\n musicNftAddr\n musicNftTokenId\n }\n }\n": types.GetMyListedMusicDocument, "\nquery GetMyMusic($owner:Bytes) @api(name: octav3){\n musicTokens(where:{owner:$owner}) {\n id\n tokenUri\n }\n }\n": types.GetMyMusicDocument, }; @@ -35,11 +35,11 @@ export function gql(source: string): unknown; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function gql(source: "\nquery GetAllMusic @api(name: octav3){\n octaveTokens {\n id\n owner\n musicNftAddr\n musicNftTokenId\n tokenUri\n }\n }\n"): (typeof documents)["\nquery GetAllMusic @api(name: octav3){\n octaveTokens {\n id\n owner\n musicNftAddr\n musicNftTokenId\n tokenUri\n }\n }\n"]; +export function gql(source: "\nquery GetAllMusic @api(name: octav3){\n octaveTokens(where:{closed:false}) {\n id\n owner\n musicNftAddr\n musicNftTokenId\n tokenUri\n }\n }\n"): (typeof documents)["\nquery GetAllMusic @api(name: octav3){\n octaveTokens(where:{closed:false}) {\n id\n owner\n musicNftAddr\n musicNftTokenId\n tokenUri\n }\n }\n"]; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function gql(source: "\nquery GetMyListedMusic($owner:Bytes) @api(name: octav3){\n octaveTokens(where:{owner:$owner}) {\n musicNftAddr\n musicNftTokenId\n }\n }\n"): (typeof documents)["\nquery GetMyListedMusic($owner:Bytes) @api(name: octav3){\n octaveTokens(where:{owner:$owner}) {\n musicNftAddr\n musicNftTokenId\n }\n }\n"]; +export function gql(source: "\nquery GetMyListedMusic($owner:Bytes) @api(name: octav3){\n octaveTokens(where:{owner:$owner,closed:false}) {\n id\n musicNftAddr\n musicNftTokenId\n }\n }\n"): (typeof documents)["\nquery GetMyListedMusic($owner:Bytes) @api(name: octav3){\n octaveTokens(where:{owner:$owner,closed:false}) {\n id\n musicNftAddr\n musicNftTokenId\n }\n }\n"]; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/src/graph-ql/queries/octav3/__generated__/graphql.ts b/src/graph-ql/queries/octav3/__generated__/graphql.ts index 9d7b5b5..46db29c 100644 --- a/src/graph-ql/queries/octav3/__generated__/graphql.ts +++ b/src/graph-ql/queries/octav3/__generated__/graphql.ts @@ -106,6 +106,7 @@ export enum MusicToken_OrderBy { export type OctaveToken = { __typename?: 'OctaveToken'; + closed: Scalars['Boolean']['output']; id: Scalars['String']['output']; musicNftAddr: Scalars['Bytes']['output']; musicNftTokenId: Scalars['BigInt']['output']; @@ -117,6 +118,10 @@ export type OctaveToken_Filter = { /** Filter for the block changed event. */ _change_block?: InputMaybe; and?: InputMaybe>>; + closed?: InputMaybe; + closed_in?: InputMaybe>; + closed_not?: InputMaybe; + closed_not_in?: InputMaybe>; id?: InputMaybe; id_contains?: InputMaybe; id_contains_nocase?: InputMaybe; @@ -189,6 +194,7 @@ export type OctaveToken_Filter = { }; export enum OctaveToken_OrderBy { + Closed = 'closed', Id = 'id', MusicNftAddr = 'musicNftAddr', MusicNftTokenId = 'musicNftTokenId', @@ -348,7 +354,7 @@ export type GetMyListedMusicQueryVariables = Exact<{ }>; -export type GetMyListedMusicQuery = { __typename?: 'Query', octaveTokens: Array<{ __typename?: 'OctaveToken', musicNftAddr: any, musicNftTokenId: any }> }; +export type GetMyListedMusicQuery = { __typename?: 'Query', octaveTokens: Array<{ __typename?: 'OctaveToken', id: string, musicNftAddr: any, musicNftTokenId: any }> }; export type GetMyMusicQueryVariables = Exact<{ owner?: InputMaybe; @@ -358,6 +364,6 @@ export type GetMyMusicQueryVariables = Exact<{ export type GetMyMusicQuery = { __typename?: 'Query', musicTokens: Array<{ __typename?: 'MusicToken', id: string, tokenUri: string }> }; -export const GetAllMusicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAllMusic"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"api"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"EnumValue","value":"octav3"}}]}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"octaveTokens"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"owner"}},{"kind":"Field","name":{"kind":"Name","value":"musicNftAddr"}},{"kind":"Field","name":{"kind":"Name","value":"musicNftTokenId"}},{"kind":"Field","name":{"kind":"Name","value":"tokenUri"}}]}}]}}]} as unknown as DocumentNode; -export const GetMyListedMusicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMyListedMusic"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"owner"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Bytes"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"api"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"EnumValue","value":"octav3"}}]}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"octaveTokens"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"owner"},"value":{"kind":"Variable","name":{"kind":"Name","value":"owner"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"musicNftAddr"}},{"kind":"Field","name":{"kind":"Name","value":"musicNftTokenId"}}]}}]}}]} as unknown as DocumentNode; +export const GetAllMusicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAllMusic"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"api"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"EnumValue","value":"octav3"}}]}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"octaveTokens"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"closed"},"value":{"kind":"BooleanValue","value":false}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"owner"}},{"kind":"Field","name":{"kind":"Name","value":"musicNftAddr"}},{"kind":"Field","name":{"kind":"Name","value":"musicNftTokenId"}},{"kind":"Field","name":{"kind":"Name","value":"tokenUri"}}]}}]}}]} as unknown as DocumentNode; +export const GetMyListedMusicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMyListedMusic"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"owner"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Bytes"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"api"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"EnumValue","value":"octav3"}}]}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"octaveTokens"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"owner"},"value":{"kind":"Variable","name":{"kind":"Name","value":"owner"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"closed"},"value":{"kind":"BooleanValue","value":false}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"musicNftAddr"}},{"kind":"Field","name":{"kind":"Name","value":"musicNftTokenId"}}]}}]}}]} as unknown as DocumentNode; export const GetMyMusicDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMyMusic"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"owner"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Bytes"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"api"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"EnumValue","value":"octav3"}}]}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"musicTokens"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"owner"},"value":{"kind":"Variable","name":{"kind":"Name","value":"owner"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"tokenUri"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/src/services/smart-contract/unmonetize.ts b/src/services/smart-contract/unmonetize.ts new file mode 100644 index 0000000..abd19d3 --- /dev/null +++ b/src/services/smart-contract/unmonetize.ts @@ -0,0 +1,27 @@ +import { Octav3Addr } from "../../env"; +import { PublicClient, WalletClient, getContract } from "viem"; +import Octave from "@/contracts/abis/Octave"; + +export const unmonetize = async (monetizeId: bigint, publicClient: PublicClient, walletClient: WalletClient) => { + if (!walletClient.account) { + //TODO error + return + } + try { + // connect to market smart-contract + const adNft = getContract({ + address: Octav3Addr, + abi: Octave, + publicClient, + walletClient, + }); + + // invoke contract func and mint ad nft + await adNft.write. + closedForMonetize([monetizeId], { account: walletClient.account, chain: walletClient.chain }) + + // end minting + } catch (err: unknown) { + console.log(err); + } +}; \ No newline at end of file