Skip to content

Commit

Permalink
feat: add list of already bridged nfts to create form
Browse files Browse the repository at this point in the history
  • Loading branch information
marthendalnunes committed Apr 1, 2024
1 parent dccb3e8 commit 3dafadf
Show file tree
Hide file tree
Showing 15 changed files with 705 additions and 1,486 deletions.
3 changes: 2 additions & 1 deletion apps/website/.eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
**/components/shared/table/**
**/generated
.next/**
tailwind.config.js
tailwind.config.js
lib/event-cache/gql/fragment-masking.ts
20 changes: 20 additions & 0 deletions apps/website/codegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { CodegenConfig } from "@graphql-codegen/cli"
import * as dotenv from "dotenv"

dotenv.config()

if (!process.env.NEXT_PUBLIC_API_EVENT_CACHE)
throw new Error("NEXT_PUBLIC_API_EVENT_CACHE is not set")

const config: CodegenConfig = {
schema: process.env.NEXT_PUBLIC_API_EVENT_CACHE,
documents: ["lib/event-cache/hooks/*.tsx"],
ignoreNoDocuments: true, // for better experience with the watcher
generates: {
"./lib/event-cache/gql/": {
preset: "client",
},
},
}

export default config
45 changes: 44 additions & 1 deletion apps/website/components/form-create-l2-erc721.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,21 @@ import { l1NetworkOptions, l2NetworksOptions } from "@/data/networks/options"
import { zodResolver } from "@hookform/resolvers/zod"
import { SubmitHandler, useForm } from "react-hook-form"
import { useDebounce } from "usehooks-ts"
import { decodeEventLog, type Address, type BaseError } from "viem"
import {
checksumAddress,
decodeEventLog,
isAddress,
type Address,
type BaseError,
} from "viem"
import {
useAccount,
useTransactionReceipt,
useWaitForTransactionReceipt,
} from "wagmi"
import { z } from "zod"

import { useGetOtimismMintableERC721ByRemoteTokenQuery } from "@/lib/event-cache/hooks/use-get-optimism-mintable-erc721-by-remote-token"
import {
useReadErc721Name,
useReadErc721Symbol,
Expand Down Expand Up @@ -102,6 +109,19 @@ export const FormCreateL2ERC721 = ({
},
]

const getOtimismMintableERC721ByRemoteTokenQuery =
useGetOtimismMintableERC721ByRemoteTokenQuery({
chainId: Number(watchL2ChainId),
remoteToken: isAddress(watchRemoteToken)
? checksumAddress(watchRemoteToken)
: "0x0",
query: {
enabled: isAddress(watchRemoteToken) && Boolean(Number(watchL2ChainId)),
},
})

getOtimismMintableERC721ByRemoteTokenQuery.data

const { address, chainId: currentChainId } = useAccount()
const erc721NameRead = useReadErc721Name({
chainId: l1Chain.chainId,
Expand Down Expand Up @@ -216,6 +236,29 @@ export const FormCreateL2ERC721 = ({
</FormItem>
)}
/>
{getOtimismMintableERC721ByRemoteTokenQuery.data &&
getOtimismMintableERC721ByRemoteTokenQuery.data
?.optimismMintableERC721s?.items?.length > 0 && (
<div className="flex flex-col gap-y-2">
<p className="text-sm font-medium text-red-500">
This NFT has already been bridged to the L2 network.
</p>
<Card className="max-h-[200px] overflow-y-auto break-words p-4">
{getOtimismMintableERC721ByRemoteTokenQuery.data?.optimismMintableERC721s?.items?.map(
(item) => (
<BlockExplorerLink
key={item.id}
address={item.localToken as Address}
chainId={item.chainId}
className="block py-0.5 text-sm underline-offset-2"
>
{item.localToken}
</BlockExplorerLink>
)
)}
</Card>
</div>
)}
{!address ? (
<ConnectButton className="w-full" />
) : l2Chain?.chainId === undefined ||
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/* eslint-disable */
import {
DocumentTypeDecoration,
ResultOf,
TypedDocumentNode,
} from "@graphql-typed-document-node/core"
import { FragmentDefinitionNode } from "graphql"

import { Incremental, TypedDocumentString } from "./graphql"
import { Incremental } from "./graphql"

export type FragmentType<
TDocumentType extends DocumentTypeDecoration<any, any>
Expand Down Expand Up @@ -60,21 +61,26 @@ export function makeFragmentData<
return data as FragmentType<F>
}
export function isFragmentReady<TQuery, TFrag>(
queryNode: TypedDocumentString<TQuery, any>,
fragmentNode: TypedDocumentString<TFrag, any>,
queryNode: DocumentTypeDecoration<TQuery, any>,
fragmentNode: TypedDocumentNode<TFrag>,
data:
| FragmentType<TypedDocumentString<Incremental<TFrag>, any>>
| FragmentType<TypedDocumentNode<Incremental<TFrag>, any>>
| null
| undefined
): data is FragmentType<typeof fragmentNode> {
const deferredFields = queryNode.__meta__?.deferredFields as Record<
string,
(keyof TFrag)[]
>
const fragName = fragmentNode.__meta__?.fragmentName as string | undefined
const deferredFields = (
queryNode as {
__meta__?: { deferredFields: Record<string, (keyof TFrag)[]> }
}
).__meta__?.deferredFields

if (!deferredFields || !fragName) return true
if (!deferredFields) return true

const fields = deferredFields[fragName] ?? []
const fragDef = fragmentNode.definitions[0] as
| FragmentDefinitionNode
| undefined
const fragName = fragDef?.name?.value

const fields = (fragName && deferredFields[fragName]) || []
return fields.length > 0 && fields.every((field) => data && field in data)
}
55 changes: 55 additions & 0 deletions apps/website/lib/event-cache/gql/gql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* eslint-disable */
import { TypedDocumentNode as DocumentNode } from "@graphql-typed-document-node/core"

import * as types from "./graphql"

/**
* Map of all GraphQL operations in the project.
*
* This map has several performance disadvantages:
* 1. It is not tree-shakeable, so it will include all operations in the project.
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
* 3. It does not support dead code elimination, so it will add unused operations.
*
* Therefore it is highly recommended to use the babel or swc plugin for production.
*/
const documents = {
"\n query allOptimismMintableERC721Query($limit: Int) {\n optimismMintableERC721s(limit: $limit) {\n items {\n id\n chainId\n blockNumber\n localToken\n localName\n localSymbol\n remoteToken\n remoteName\n remoteSymbol\n deployer\n }\n }\n }\n":
types.AllOptimismMintableErc721QueryDocument,
"\n query getOtimismMintableERC721ByRemoteTokenQuery(\n $remoteToken: String!\n $chainId: Int!\n ) {\n optimismMintableERC721s(\n where: { remoteToken: $remoteToken, chainId: $chainId }\n ) {\n items {\n id\n chainId\n blockNumber\n localToken\n localName\n localSymbol\n remoteToken\n remoteName\n remoteSymbol\n deployer\n }\n }\n }\n":
types.GetOtimismMintableErc721ByRemoteTokenQueryDocument,
}

/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*
*
* @example
* ```ts
* const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
* ```
*
* The query argument is unknown!
* Please regenerate the types.
*/
export function graphql(source: string): unknown

/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(
source: "\n query allOptimismMintableERC721Query($limit: Int) {\n optimismMintableERC721s(limit: $limit) {\n items {\n id\n chainId\n blockNumber\n localToken\n localName\n localSymbol\n remoteToken\n remoteName\n remoteSymbol\n deployer\n }\n }\n }\n"
): (typeof documents)["\n query allOptimismMintableERC721Query($limit: Int) {\n optimismMintableERC721s(limit: $limit) {\n items {\n id\n chainId\n blockNumber\n localToken\n localName\n localSymbol\n remoteToken\n remoteName\n remoteSymbol\n deployer\n }\n }\n }\n"]
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(
source: "\n query getOtimismMintableERC721ByRemoteTokenQuery(\n $remoteToken: String!\n $chainId: Int!\n ) {\n optimismMintableERC721s(\n where: { remoteToken: $remoteToken, chainId: $chainId }\n ) {\n items {\n id\n chainId\n blockNumber\n localToken\n localName\n localSymbol\n remoteToken\n remoteName\n remoteSymbol\n deployer\n }\n }\n }\n"
): (typeof documents)["\n query getOtimismMintableERC721ByRemoteTokenQuery(\n $remoteToken: String!\n $chainId: Int!\n ) {\n optimismMintableERC721s(\n where: { remoteToken: $remoteToken, chainId: $chainId }\n ) {\n items {\n id\n chainId\n blockNumber\n localToken\n localName\n localSymbol\n remoteToken\n remoteName\n remoteSymbol\n deployer\n }\n }\n }\n"]

export function graphql(source: string) {
return (documents as any)[source] ?? {}
}

export type DocumentType<TDocumentNode extends DocumentNode<any, any>> =
TDocumentNode extends DocumentNode<infer TType, any> ? TType : never
Loading

0 comments on commit 3dafadf

Please sign in to comment.