Skip to content

Commit

Permalink
Merge pull request #24 from gnosis/app-erc-1155-support
Browse files Browse the repository at this point in the history
app: ERC-1155 support
  • Loading branch information
jfschwarz authored Jul 11, 2023
2 parents 0f99112 + ac5fcd1 commit cf9bb6b
Show file tree
Hide file tree
Showing 12 changed files with 116 additions and 108 deletions.
16 changes: 5 additions & 11 deletions frontend/src/components/NFTGridItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { calculateERC721MechAddress, deployERC721Mech } from "mech-sdk"
import { useState } from "react"
import { useSigner } from "wagmi"
import copy from "copy-to-clipboard"
Expand All @@ -12,6 +11,8 @@ import { JsonRpcSigner } from "@ethersproject/providers"
import Spinner from "../Spinner"
import { MechNFT } from "../../hooks/useNFTsByOwner"
import ChainIcon from "../ChainIcon"
import { deployMech } from "../../utils/deployMech"
import { calculateMechAddress } from "../../utils/calculateMechAddress"

interface Props {
nftData: MechNFT
Expand All @@ -20,21 +21,14 @@ interface Props {
const NFTGridItem: React.FC<Props> = ({ nftData }) => {
const [imageError, setImageError] = useState(false)
const [deploying, setDeploying] = useState(false)
const chainId = parseInt(nftData.blockchain.shortChainId)
const chainId = parseInt(nftData.blockchain.shortChainID)
const { data: signer } = useSigner()
const mechAddress = calculateERC721MechAddress(
nftData.contractAddress,
nftData.nft.tokenID
)
const mechAddress = calculateMechAddress(nftData)

const handleDeploy = async () => {
setDeploying(true)
try {
const deployTx = await deployERC721Mech(
nftData.contractAddress,
nftData.nft.tokenID,
signer as JsonRpcSigner
)
const deployTx = await deployMech(nftData, signer as JsonRpcSigner)
console.log("deploy tx", deployTx)
setDeploying(false)
} catch (e) {
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/components/NFTItem/NFTItem.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@
align-items: center;
}

.name {
}

.info {
width: 45%;
display: flex;
Expand Down Expand Up @@ -124,12 +127,19 @@
.address {
cursor: pointer;
transition: filter 0.1s ease-in-out;
max-width: 139px;
}

.address:hover {
filter: brightness(1.2);
}

.ellipsis {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}

.spinner {
width: 100%;
display: flex;
Expand Down
36 changes: 20 additions & 16 deletions frontend/src/components/NFTItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,22 @@ import clsx from "clsx"
import useAccountBalance from "../../hooks/useAccountBalance"
import Spinner from "../Spinner"
import { useDeployMech } from "../../hooks/useDeployMech"
import { calculateERC721MechAddress } from "mech-sdk"

import { MechNFT } from "../../hooks/useNFTsByOwner"
import { calculateMechAddress } from "../../utils/calculateMechAddress"

interface Props {
token: string
tokenId: string
nftData: MechNFT
operatorAddress?: string
}

const NFTItem: React.FC<Props> = ({
token,
tokenId,
nftData,
operatorAddress,
}) => {
const mechAddress = calculateERC721MechAddress(token, tokenId)
const NFTItem: React.FC<Props> = ({ nftData }) => {
const mechAddress = calculateMechAddress(nftData)

const operatorAddress = nftData.nft.owner?.address as string | undefined
const operatorLabel =
operatorAddress &&
((nftData.nft.owner?.ens && nftData.nft.owner?.ens[0]?.name) ||
shortenAddress(operatorAddress))

const [imageError, setImageError] = useState(false)

Expand All @@ -33,17 +32,18 @@ const NFTItem: React.FC<Props> = ({
error: assetsError,
} = useAccountBalance({ address: mechAddress })

const { deployed } = useDeployMech(token, tokenId)
const { deployed } = useDeployMech(nftData)

return (
<div className={classes.itemContainer}>
<div className={classes.header}>
<p className={classes.tokenName}>
{nftData.nft.title || nftData.nft.contractTitle || "..."}
</p>
{nftData.nft.tokenID.length < 5 && (
<p className={classes.tokenId}>{nftData.nft.tokenID || "..."}</p>
)}

<p className={classes.tokenId} title={nftData.nft.tokenID}>
{nftData.nft.tokenID}
</p>
</div>
<div className={classes.main}>
{(imageError || !nftData.nft.previews) && (
Expand Down Expand Up @@ -78,6 +78,7 @@ const NFTItem: React.FC<Props> = ({
<div
className={clsx(classes.infoItem, classes.address)}
onClick={() => copy(mechAddress)}
title={mechAddress}
>
{shortenAddress(mechAddress)}
</div>
Expand All @@ -91,8 +92,11 @@ const NFTItem: React.FC<Props> = ({
onClick={
operatorAddress ? () => copy(operatorAddress) : undefined
}
title={operatorAddress}
>
{operatorAddress ? shortenAddress(operatorAddress) : "\u2014"}
<div className={classes.ellipsis}>
{operatorAddress ? operatorLabel : "\u2014"}
</div>
</div>
</li>
<li>
Expand Down
19 changes: 9 additions & 10 deletions frontend/src/hooks/useDeployMech.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import { useEffect, useState } from "react"
import { useChainId, useProvider, useSigner } from "wagmi"
import {
calculateERC721MechAddress,
makeERC721MechDeployTransaction,
} from "mech-sdk"
import { useProvider, useSigner } from "wagmi"
import { calculateMechAddress } from "../utils/calculateMechAddress"
import { makeMechDeployTransaction } from "../utils/deployMech"
import { MechNFT } from "./useNFTsByOwner"

export const useDeployMech = (token: string, tokenId: string) => {
const mechAddress = calculateERC721MechAddress(token, tokenId)
export const useDeployMech = (token: MechNFT | null) => {
const mechAddress = token && calculateMechAddress(token)
const { data: signer } = useSigner()
const chainId = useChainId()

const provider = useProvider()
const [deployed, setDeployed] = useState(false)
useEffect(() => {
if (!mechAddress) return
provider.getCode(mechAddress).then((code) => setDeployed(code !== "0x"))
}, [provider, mechAddress])

const [deployPending, setDeployPending] = useState(false)
const deploy = async () => {
if (!signer) return
const tx = makeERC721MechDeployTransaction(token, tokenId, chainId)
if (!signer || !token) return
const tx = makeMechDeployTransaction(token)
setDeployPending(true)
try {
const res = await signer.sendTransaction(tx)
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/hooks/useHandleRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ import { useCallback } from "react"
import { useJsonRpcSigner } from "./useJsonRpcSigner"
import { ProvideWalletConnect } from "./useWalletConnect"

export const useHandleRequest = (mechAddress: string) => {
export const useHandleRequest = (mechAddress: string | null) => {
const signer = useJsonRpcSigner()

const handleRequest = useCallback<HandleRequest>(
async ({ session, request }) => {
if (!mechAddress) {
throw new Error("mech address not available")
}

console.debug("handle request", { session, request })
if (!signer) {
throw new Error("signer not available")
Expand Down
11 changes: 3 additions & 8 deletions frontend/src/hooks/useNFT.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { calculateERC721MechAddress } from "mech-sdk"
import { useEffect, useState } from "react"
import { useProvider } from "wagmi"

import { nxyzNFT, nxyzSupportedChains } from "../types/nxyzApiTypes"
import { calculateMechAddress } from "../utils/calculateMechAddress"
import { MechNFT } from "./useNFTsByOwner"

interface NFTProps {
Expand All @@ -12,7 +12,7 @@ interface NFTProps {
}

interface NFTResult {
data: MechNFT
data: MechNFT | null
isLoading: boolean
error: any
}
Expand All @@ -38,12 +38,7 @@ const useNFT: useNFTType = ({ contractAddress, blockchain, tokenId }) => {
if (!mechData) throw new Error("No metadata")

const hasMech =
(await provider.getCode(
calculateERC721MechAddress(
mechData.contractAddress,
mechData.nft.tokenID
)
)) !== "0x"
(await provider.getCode(calculateMechAddress(mechData))) !== "0x"
mechData.hasMech = hasMech
} catch (error) {
console.log(error)
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/hooks/useNFTsByOwner.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { calculateERC721MechAddress } from "mech-sdk"
import { useEffect, useState } from "react"
import { useProvider } from "wagmi"
import { nxyzNFT, nxyzSupportedChains } from "../types/nxyzApiTypes"
import { calculateMechAddress } from "../utils/calculateMechAddress"

interface NFTProps {
walletAddress: string
Expand All @@ -11,6 +11,7 @@ interface NFTProps {

export interface MechNFT extends nxyzNFT {
hasMech?: boolean
tokenStandard?: "ERC-721" | "ERC-1155"
}

interface MechGetNFTsByOwnerReply {
Expand Down Expand Up @@ -51,9 +52,7 @@ const useNFTsByOwner: useNFTsByOwnerType = ({
const nft = nfts[index] as MechNFT
try {
const hasMech =
(await provider.getCode(
calculateERC721MechAddress(nft.contractAddress, nft.nft.tokenID)
)) !== "0x"
(await provider.getCode(calculateMechAddress(nft))) !== "0x"
nft.hasMech = hasMech
} catch (error) {
console.log(error)
Expand Down
38 changes: 0 additions & 38 deletions frontend/src/hooks/useTokenUrl.ts

This file was deleted.

24 changes: 6 additions & 18 deletions frontend/src/routes/Mech/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import React from "react"
import { useParams } from "react-router-dom"
import { calculateERC721MechAddress } from "mech-sdk"
import { useChainId } from "wagmi"
import Layout from "../../components/Layout"
import { useErc721OwnerOf } from "../../generated"
import { BigNumber } from "ethers"
import useNFT from "../../hooks/useNFT"
import NFTItem from "../../components/NFTItem"

Expand All @@ -15,6 +12,7 @@ import { ProvideWalletConnect } from "../../hooks/useWalletConnect"
import { useHandleRequest } from "../../hooks/useHandleRequest"
import { useDeployMech } from "../../hooks/useDeployMech"
import MechDeploy from "../../components/Deploy"
import { calculateMechAddress } from "../../utils/calculateMechAddress"

const Mech: React.FC = () => {
const { token, tokenId } = useParams()
Expand All @@ -34,29 +32,19 @@ const Mech: React.FC = () => {

const chainId = useChainId()

const { data: tokenOwner } = useErc721OwnerOf({
address: token as `0x${string}`,
args: [BigNumber.from(tokenId)],
})

const { deployed, deploy, deployPending } = useDeployMech(token, tokenId)
const { deployed, deploy, deployPending } = useDeployMech(data)

const mechAddress = calculateERC721MechAddress(token, tokenId)
const mechAddress = data && calculateMechAddress(data)

const handleRequest = useHandleRequest(mechAddress)

return (
<Layout mechAddress={mechAddress}>
<Layout mechAddress={mechAddress || undefined}>
<div className={classes.container}>
{isLoading && <Spinner />}
{!error && !isLoading && data && (
{!error && !isLoading && data && mechAddress && (
<>
<NFTItem
token={token}
tokenId={tokenId}
nftData={data}
operatorAddress={tokenOwner}
/>
<NFTItem nftData={data} />

<ProvideWalletConnect
chainId={chainId}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/types/nxyzApiTypes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export interface nxyzBlockchain {
name: string
shortName: string
chainId: string
shortChainId: string
chainID: string
shortChainID: string
}

export interface nxyzTokenSymbol {
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/utils/calculateMechAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {
calculateERC1155MechAddress,
calculateERC721MechAddress,
} from "mech-sdk"
import { MechNFT } from "../hooks/useNFTsByOwner"

export const calculateMechAddress = (token: MechNFT) => {
return token.tokenStandard === "ERC-1155"
? calculateERC1155MechAddress(
token.contractAddress,
[token.nft.tokenID],
[1],
1
)
: calculateERC721MechAddress(token.contractAddress, token.nft.tokenID)
}
Loading

1 comment on commit cf9bb6b

@vercel
Copy link

@vercel vercel bot commented on cf9bb6b Jul 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

mech – ./

mech-omega.vercel.app
mech-gnosis-guild.vercel.app
mech-git-main-gnosis-guild.vercel.app

Please sign in to comment.