diff --git a/packages/checkout/src/constants/abi.ts b/packages/checkout/src/constants/abi.ts index be2a1cf6..b593e3de 100644 --- a/packages/checkout/src/constants/abi.ts +++ b/packages/checkout/src/constants/abi.ts @@ -183,84 +183,3 @@ export const ERC_1155_SALE_CONTRACT = [ "stateMutability": "view" } ] - -export const ERC_721_SALE_CONTRACT = [ - { - "type": "function", - "name": "mint", - "inputs": [ - { - "name": "to", - "type": "address", - "internalType": "address" - }, - { - "name": "amount", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "paymentToken", - "type": "address", - "internalType": "address" - }, - { - "name": "maxTotal", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "proof", - "type": "bytes32[]", - "internalType": "bytes32[]" - } - ], - "outputs": [], - "stateMutability": "payable" - }, - { - "type": "function", - "name": "saleDetails", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "tuple", - "internalType": "struct IERC721SaleFunctions.SaleDetails", - "components": [ - { - "name": "supplyCap", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "cost", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "paymentToken", - "type": "address", - "internalType": "address" - }, - { - "name": "startTime", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "endTime", - "type": "uint64", - "internalType": "uint64" - }, - { - "name": "merkleRoot", - "type": "bytes32", - "internalType": "bytes32" - } - ] - } - ], - "stateMutability": "view" - }, -] \ No newline at end of file diff --git a/packages/checkout/src/hooks/useSaleContractCheckout.ts b/packages/checkout/src/hooks/useERC1155SaleContractCheckout.ts similarity index 50% rename from packages/checkout/src/hooks/useSaleContractCheckout.ts rename to packages/checkout/src/hooks/useERC1155SaleContractCheckout.ts index efe94c7f..75546970 100644 --- a/packages/checkout/src/hooks/useSaleContractCheckout.ts +++ b/packages/checkout/src/hooks/useERC1155SaleContractCheckout.ts @@ -1,32 +1,31 @@ import { CheckoutOptionsSalesContractArgs } from '@0xsequence/marketplace' import { findSupportedNetwork } from '@0xsequence/network' -import { useSelectPaymentModal } from './useSelectPaymentModal' +import { useERC1155SaleContractPaymentModal } from './useSelectPaymentModal' import { useCheckoutOptionsSalesContract } from "./useCheckoutOptionsSalesContract" -import { ERC_1155_SALE_CONTRACT, ERC_721_SALE_CONTRACT } from '../constants/abi' +import { ERC_1155_SALE_CONTRACT } from '../constants/abi' import { Abi, Hex } from 'viem' import { useReadContract, useReadContracts } from 'wagmi' -interface UseSaleContractCheckoutArgs extends CheckoutOptionsSalesContractArgs { +interface UseERC1155SaleContractCheckoutArgs extends CheckoutOptionsSalesContractArgs { chain: number | string, - tokenType: 'ERC1155' | 'ERC721' } -interface UseSaleContractCheckoutReturn { - data?: undefined, +interface UseERC1155SaleContractCheckoutReturn { + openCheckoutModal: () => void, isLoading: boolean, isError: boolean } -export const useSaleContractCheckout = ({ +export const useERC1155SaleContractCheckout = ({ chain, - tokenType, contractAddress, wallet, collectionAddress, items, -}: UseSaleContractCheckoutArgs): UseSaleContractCheckoutReturn => { +}: UseERC1155SaleContractCheckoutArgs): UseERC1155SaleContractCheckoutReturn => { + const { openERC1155SaleContractPaymentModal } = useERC1155SaleContractPaymentModal() const { data: checkoutOptions, isLoading: isLoadingCheckoutOptions, isError: isErrorCheckoutOtions } = useCheckoutOptionsSalesContract(chain, { contractAddress, wallet, @@ -36,7 +35,7 @@ export const useSaleContractCheckout = ({ const network = findSupportedNetwork(chain) const chainId = network?.chainId || 137 - const { data: saleConfigData, isLoading: isLoadingSaleConfig, isError: isErrorSaleConfig } = useSaleContractConfig({ chainId, tokenType, contractAddress, tokenIds: items.map(i => i.tokenId) }) + const { data: saleConfigData, isLoading: isLoadingSaleConfig, isError: isErrorSaleConfig } = useSaleContractConfig({ chainId, contractAddress, tokenIds: items.map(i => i.tokenId) }) // Get sale contract currency data... // Get token sale data @@ -44,16 +43,33 @@ export const useSaleContractCheckout = ({ const isLoading = isLoadingCheckoutOptions || isLoadingSaleConfig const error = isErrorCheckoutOtions || isErrorSaleConfig - const openCheckoutModal = () => { - if (isLoading || error) return + if (isLoading || error) { + console.error('Error loading checkout options or sale config', { isLoading, error }) + return + } - // return openCheckoutModal({ - // }) + return () => { + openERC1155SaleContractPaymentModal({ + collectibles: items.map(item => ({ + tokenId: item.tokenId, + quantity: item.quantity + })), + chain: chainId, + price: items.reduce((acc, item) => { + const price = BigInt(saleConfigData?.saleConfigs.find(sale => sale.tokenId === item.tokenId)?.price || 0) + return acc + BigInt(item.quantity) * price + }, BigInt(0)).toString(), + currencyAddress: saleConfigData?.currencyAddress || '', + recipientAddress: wallet, + collectionAddress, + targetContractAddress: contractAddress, + }) + } } return ({ - data: undefined, + openCheckoutModal, isLoading, isError: error }) @@ -62,7 +78,6 @@ export const useSaleContractCheckout = ({ interface UseSaleContractConfigArgs { chainId: number contractAddress: string - tokenType: 'ERC1155'| 'ERC721', tokenIds: string[] } @@ -82,15 +97,12 @@ interface UseSaleContractConfigReturn { isError: boolean } -export const useSaleContractConfig = ({ chainId, tokenType, contractAddress, tokenIds, }: UseSaleContractConfigArgs): UseSaleContractConfigReturn => { +export const useSaleContractConfig = ({ chainId, contractAddress, tokenIds, }: UseSaleContractConfigArgs): UseSaleContractConfigReturn => { const { data: paymentTokenERC1155, isLoading: isLoadingPaymentTokenERC1155, isError: isErrorPaymentTokenERC1155 } = useReadContract({ chainId, abi: ERC_1155_SALE_CONTRACT, address: contractAddress as Hex, functionName: 'paymentToken', - query: { - enabled: tokenType === 'ERC1155' - } }) // [cost, supplyCap, startTime, endTime, merkleRoot] @@ -101,9 +113,6 @@ export const useSaleContractConfig = ({ chainId, tokenType, contractAddress, tok abi: ERC_1155_SALE_CONTRACT, address: contractAddress as Hex, functionName: 'globalSaleDetails', - query: { - enabled: tokenType === 'ERC1155' - } }) const baseTokenSaleContract = { @@ -120,74 +129,46 @@ export const useSaleContractConfig = ({ chainId, tokenType, contractAddress, tok const { data: tokenSaleDetailsERC1155, isLoading: isLoadingTokenSaleDetailsERC1155, isError: isErrorTokenSaleDetailsERC1155 } = useReadContracts({ contracts: tokenSaleContracts, - query: { - enabled: tokenType === 'ERC1155' - } - }) - - // [supplyCap, cost, paymentToken, startTime, endTime, merkleRoot] - type SaleDetailsERC721 = [bigint, bigint, string, bigint, string, string] - - const { data: saleDetailsERC721, isLoading: isLoadingSaleDetailsERC721, isError: isErrorSaleDetailsERC721 } = useReadContract({ - chainId, - abi: ERC_721_SALE_CONTRACT, - address: contractAddress as Hex, - functionName: 'saleDetails', - query: { - enabled: tokenType === 'ERC721' - } }) const isLoadingERC1155 = isLoadingPaymentTokenERC1155 || isLoadingGlobalSaleDetailsERC1155 || isLoadingTokenSaleDetailsERC1155 - const isLoadingERC721 = isLoadingSaleDetailsERC721 const isErrorERC1155 = isErrorPaymentTokenERC1155 || isErrorGlobalSaleDetailsERC1155 || isErrorTokenSaleDetailsERC1155 - const isErrorERC721 = isErrorSaleDetailsERC721 - if (isLoadingERC1155 || isLoadingERC721 || isErrorERC1155 || isErrorERC721) { + if (isLoadingERC1155 || isErrorERC1155) { return ({ data: undefined, - isLoading: tokenType === 'ERC1155' ? isLoadingERC1155 : isLoadingERC721, - isError: tokenType === 'ERC1155' ? isErrorERC1155 : isErrorERC721 + isLoading: isLoadingERC1155, + isError: isErrorERC1155 }) } const getSaleConfigs = (): SaleConfig[] => { let saleInfos: SaleConfig[] = [] - if (isLoadingERC1155 || isLoadingERC721 || isErrorERC1155 || isErrorERC721) return saleInfos + if (isLoadingERC1155 || isErrorERC1155 ) return saleInfos - if (tokenType === 'ERC1155') { - // In the sale contract, the global sale has priority over the token sale - // So we need to check if the global sale is set, and if it is, use that - // Otherwise, we use the token sale - const [costERC721, _, startTime, endTime] = globalSaleDetailsERC1155 as SaleDetailsERC1155 - const isGlobalSaleValid = endTime === BigInt(0) || (startTime <= BigInt(Math.floor(Date.now() / 1000)) || endTime >= BigInt(Math.floor(Date.now() / 1000))) - saleInfos = tokenIds.map((tokenId, index) => { - const tokenPrice = (tokenSaleDetailsERC1155?.[index].result as SaleDetailsERC1155)[0] || BigInt(0) - return ({ - tokenId, - price: (isGlobalSaleValid ? costERC721 : tokenPrice).toString() - }) - }) - } else { - saleInfos = tokenIds.map((tokenId, index) => { - const tokenPrice = (saleDetailsERC721 as SaleDetailsERC721)[1] || BigInt(0) - return ({ - tokenId, - price: tokenPrice.toString() - }) + // In the sale contract, the global sale has priority over the token sale + // So we need to check if the global sale is set, and if it is, use that + // Otherwise, we use the token sale + const [costERC1155, _, startTime, endTime] = globalSaleDetailsERC1155 as SaleDetailsERC1155 + const isGlobalSaleValid = endTime === BigInt(0) || (startTime <= BigInt(Math.floor(Date.now() / 1000)) || endTime >= BigInt(Math.floor(Date.now() / 1000))) + saleInfos = tokenIds.map((tokenId, index) => { + const tokenPrice = (tokenSaleDetailsERC1155?.[index].result as SaleDetailsERC1155)[0] || BigInt(0) + return ({ + tokenId, + price: (isGlobalSaleValid ? costERC1155 : tokenPrice).toString() }) - } + }) return saleInfos } return ({ data: { - currencyAddress: tokenType === 'ERC1155' ? (paymentTokenERC1155 as string) : (saleDetailsERC721 as SaleDetailsERC721)[2], + currencyAddress: paymentTokenERC1155 as string, saleConfigs: getSaleConfigs() }, - isLoading: tokenType === 'ERC1155' ? isLoadingERC1155 : isLoadingERC721, - isError: tokenType === 'ERC1155' ? isErrorERC1155 : isErrorERC721 + isLoading: isLoadingERC1155, + isError: isErrorERC1155 }) } \ No newline at end of file diff --git a/packages/checkout/src/hooks/useSelectPaymentModal.ts b/packages/checkout/src/hooks/useSelectPaymentModal.ts index bcc4f583..b0c92481 100644 --- a/packages/checkout/src/hooks/useSelectPaymentModal.ts +++ b/packages/checkout/src/hooks/useSelectPaymentModal.ts @@ -1,7 +1,7 @@ import { ethers } from 'ethers' import { encodeFunctionData, toHex } from 'viem' -import { ERC_1155_SALE_CONTRACT, ERC_721_SALE_CONTRACT } from '../constants/abi' +import { ERC_1155_SALE_CONTRACT } from '../constants/abi' import { SelectPaymentSettings } from '../contexts' import { useSelectPaymentContext } from '../contexts/SelectPaymentModal' @@ -55,46 +55,3 @@ export const useERC1155SaleContractPaymentModal = () => { selectPaymentSettings } } - -export const getERC721SaleContractConfig = ({ - chain, - price, - currencyAddress = ethers.ZeroAddress, - recipientAddress, - collectibles, - collectionAddress, - isDev = false, - ...restProps -}: SaleContractSettings): SelectPaymentSettings => { - const purchaseTransactionData = encodeFunctionData({ - abi: ERC_721_SALE_CONTRACT, - functionName: 'mint', - // [to, amount, paymentToken, maxTotal, proof] - // args: [recipientAddress, collectibles.map(c => BigInt(c.quantity)), toHex(0), currencyAddress, price, [toHex(0, { size: 32 })]] - }) - - return { - chain, - price, - currencyAddress, - recipientAddress, - collectibles, - collectionAddress, - isDev, - txData: purchaseTransactionData, - ...restProps - } -} - -export const useERC721SaleContractPaymentModal = () => { - const { openSelectPaymentModal, closeSelectPaymentModal, selectPaymentSettings } = useSelectPaymentModal() - const openERC721SaleContractPaymentModal = (saleContractSettings: SaleContractSettings) => { - openSelectPaymentModal(getERC721SaleContractConfig(saleContractSettings)) - } - - return { - openERC721SaleContractPaymentModal, - closeERC721SaleContractPaymentModal: closeSelectPaymentModal, - selectPaymentSettings - } -} \ No newline at end of file