diff --git a/webapp/src/components/Modals/SellModal/SellModal.container.ts b/webapp/src/components/Modals/SellModal/SellModal.container.ts index 3c337fd534..125540e038 100644 --- a/webapp/src/components/Modals/SellModal/SellModal.container.ts +++ b/webapp/src/components/Modals/SellModal/SellModal.container.ts @@ -9,6 +9,7 @@ import { Authorization } from 'decentraland-dapps/dist/modules/authorization/typ import { isLoadingType } from 'decentraland-dapps/dist/modules/loading/selectors' import { upsertContracts } from '../../../modules/contract/actions' import { getContract } from '../../../modules/contract/selectors' +import { getIsOffchainPublicNFTOrdersEnabled } from '../../../modules/features/selectors' import { createOrderRequest, CREATE_ORDER_REQUEST, cancelOrderRequest, CANCEL_ORDER_REQUEST } from '../../../modules/order/actions' import { getLoading as getLoadingOrders } from '../../../modules/order/selectors' import { RootState } from '../../../modules/reducer' @@ -26,7 +27,8 @@ const mapState = (state: RootState): MapStateProps => { authorizations: getAuthorizations(state), isCreatingOrder: isLoadingType(getLoadingOrders(state), CREATE_ORDER_REQUEST), isAuthorizing: isLoadingType(getLoading(state), GRANT_TOKEN_REQUEST) || isLoadingType(getLoading(state), REVOKE_TOKEN_REQUEST), - isCancelling: isLoadingType(getLoading(state), CANCEL_ORDER_REQUEST) + isCancelling: isLoadingType(getLoading(state), CANCEL_ORDER_REQUEST), + isOffchainPublicNFTOrdersEnabled: getIsOffchainPublicNFTOrdersEnabled(state) } } diff --git a/webapp/src/components/Modals/SellModal/SellModal.tsx b/webapp/src/components/Modals/SellModal/SellModal.tsx index d7b1091c1d..7e96828f3f 100644 --- a/webapp/src/components/Modals/SellModal/SellModal.tsx +++ b/webapp/src/components/Modals/SellModal/SellModal.tsx @@ -10,7 +10,7 @@ import { toFixedMANAValue } from 'decentraland-dapps/dist/lib/mana' import { AuthorizationType, Authorization as Authorizations } from 'decentraland-dapps/dist/modules/authorization/types' import { hasAuthorization } from 'decentraland-dapps/dist/modules/authorization/utils' import { T, t } from 'decentraland-dapps/dist/modules/translation/utils' -import { ContractName } from 'decentraland-transactions' +import { ContractName, getContract as getDecentralandContract } from 'decentraland-transactions' import { Button, Field, Loader, Mana, Message, ModalNavigation } from 'decentraland-ui' import { useAuthorization } from '../../../lib/authorization' import { formatWeiMANA, parseMANANumber } from '../../../lib/mana' @@ -43,6 +43,7 @@ const SellModal = ({ error, onFetchAuthorizations, isCancelling, + isOffchainPublicNFTOrdersEnabled, onCancelOrder }: Props) => { const { orderService } = VendorFactory.build(nft.vendor) @@ -83,9 +84,13 @@ const SellModal = ({ network: nft.network }) + const offchainOrdersContract = isOffchainPublicNFTOrdersEnabled + ? getDecentralandContract(ContractName.OffChainMarketplace, nft.chainId) + : null + const authorization: Authorizations = { address: wallet?.address || '', - authorizedAddress: marketplace!.address, + authorizedAddress: !!offchainOrdersContract && isOffchainPublicNFTOrdersEnabled ? offchainOrdersContract.address : marketplace!.address, contractAddress: nft.contractAddress, contractName: (nft.category === NFTCategory.WEARABLE || nft.category === NFTCategory.EMOTE) && nft.network === Network.MATIC diff --git a/webapp/src/components/Modals/SellModal/SellModal.types.ts b/webapp/src/components/Modals/SellModal/SellModal.types.ts index 2be6678d2e..71fde20ea6 100644 --- a/webapp/src/components/Modals/SellModal/SellModal.types.ts +++ b/webapp/src/components/Modals/SellModal/SellModal.types.ts @@ -24,6 +24,7 @@ export type Props = Omit & { authorizations: Authorization[] isCreatingOrder: boolean isAuthorizing: boolean + isOffchainPublicNFTOrdersEnabled: boolean onFetchAuthorizations: typeof fetchAuthorizationsRequest onUpsertContracts: typeof upsertContracts onCancelOrder: typeof cancelOrderRequest @@ -34,7 +35,14 @@ export type OwnProps = Pick export type MapStateProps = Pick< Props, - 'authorizations' | 'wallet' | 'isCreatingOrder' | 'error' | 'getContract' | 'isAuthorizing' | 'isCancelling' + | 'authorizations' + | 'wallet' + | 'isCreatingOrder' + | 'error' + | 'getContract' + | 'isAuthorizing' + | 'isCancelling' + | 'isOffchainPublicNFTOrdersEnabled' > export type MapDispatchProps = Pick diff --git a/webapp/src/components/SettingsPage/Authorization/Authorization.container.ts b/webapp/src/components/SettingsPage/Authorization/Authorization.container.ts index 53e99c40ac..58ddf41327 100644 --- a/webapp/src/components/SettingsPage/Authorization/Authorization.container.ts +++ b/webapp/src/components/SettingsPage/Authorization/Authorization.container.ts @@ -10,6 +10,7 @@ import { import { getData as getAuthorizations, getLoading } from 'decentraland-dapps/dist/modules/authorization/selectors' import { areEqual } from 'decentraland-dapps/dist/modules/authorization/utils' import { getContract } from '../../../modules/contract/selectors' +import { getIsOffchainPublicNFTOrdersEnabled } from '../../../modules/features/selectors' import { RootState } from '../../../modules/reducer' import { getPendingAuthorizationTransactions } from '../../../modules/transaction/selectors' import { hasTransactionPending } from '../../../modules/transaction/utils' @@ -35,7 +36,8 @@ const mapState = (state: RootState, { authorization }: OwnProps): MapStateProps authorizations, pendingTransactions, isLoading: isLoading || hasTransactionPending(pendingTransactions, authorizedAddress, contractAddress), - getContract: (query: Partial) => getContract(state, query) + getContract: (query: Partial) => getContract(state, query), + isOffchainPublicNFTOrdersEnabled: getIsOffchainPublicNFTOrdersEnabled(state) } } diff --git a/webapp/src/components/SettingsPage/Authorization/Authorization.tsx b/webapp/src/components/SettingsPage/Authorization/Authorization.tsx index 5c3aa976fd..0e8a437db5 100644 --- a/webapp/src/components/SettingsPage/Authorization/Authorization.tsx +++ b/webapp/src/components/SettingsPage/Authorization/Authorization.tsx @@ -6,6 +6,7 @@ import { ChainCheck, TransactionLink } from 'decentraland-dapps/dist/containers' import { getChainConfiguration } from 'decentraland-dapps/dist/lib/chainConfiguration' import { AuthorizationType } from 'decentraland-dapps/dist/modules/authorization/types' import { t, T } from 'decentraland-dapps/dist/modules/translation/utils' +import { ContractName, getContract as getDecentralandContract } from 'decentraland-transactions' import { Form, Radio, Loader, Popup, RadioProps } from 'decentraland-ui' import { isAuthorized } from '../../../lib/authorization' import { locations } from '../../../modules/routing/locations' @@ -13,7 +14,16 @@ import { Props } from './Authorization.types' import './Authorization.css' const Authorization = (props: Props) => { - const { authorization, authorizations, shouldUpdateSpendingCap, isLoading, onGrant, onRevoke, getContract } = props + const { + authorization, + authorizations, + shouldUpdateSpendingCap, + isLoading, + isOffchainPublicNFTOrdersEnabled, + onGrant, + onRevoke, + getContract + } = props const handleOnChange = useCallback( (isChecked: boolean) => { @@ -39,7 +49,9 @@ const Authorization = (props: Props) => { const { contractAddress, authorizedAddress } = authorization - const contract = getContract({ address: authorizedAddress }) + const contract = isOffchainPublicNFTOrdersEnabled + ? getDecentralandContract(ContractName.OffChainMarketplace, authorization.chainId) + : getContract({ address: authorizedAddress }) const token = getContract({ address: contractAddress }) if (!contract || !token) { diff --git a/webapp/src/components/SettingsPage/Authorization/Authorization.types.ts b/webapp/src/components/SettingsPage/Authorization/Authorization.types.ts index 53686a911e..2f389ae010 100644 --- a/webapp/src/components/SettingsPage/Authorization/Authorization.types.ts +++ b/webapp/src/components/SettingsPage/Authorization/Authorization.types.ts @@ -15,6 +15,7 @@ export type Props = { authorizations: Authorization[] pendingTransactions: Transaction[] isLoading: boolean + isOffchainPublicNFTOrdersEnabled: boolean shouldUpdateSpendingCap?: boolean getContract: (query: Partial) => ReturnType onGrant: typeof grantTokenRequest @@ -22,6 +23,9 @@ export type Props = { } export type OwnProps = Pick -export type MapStateProps = Pick +export type MapStateProps = Pick< + Props, + 'authorizations' | 'pendingTransactions' | 'isLoading' | 'getContract' | 'isOffchainPublicNFTOrdersEnabled' +> export type MapDispatchProps = Pick export type MapDispatch = Dispatch diff --git a/webapp/src/contracts/ERC721Collection.json b/webapp/src/contracts/ERC721Collection.json new file mode 100644 index 0000000000..d6eb2daad8 --- /dev/null +++ b/webapp/src/contracts/ERC721Collection.json @@ -0,0 +1,1624 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_itemId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "string", + "name": "rarity", + "type": "string" + }, + { + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "internalType": "string", + "name": "metadata", + "type": "string" + }, + { + "internalType": "string", + "name": "contentHash", + "type": "string" + } + ], + "indexed": false, + "internalType": "struct ERC721BaseCollectionV2.Item", + "name": "_item", + "type": "tuple" + } + ], + "name": "AddItem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "_oldBaseURI", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "_newBaseURI", + "type": "string" + } + ], + "name": "BaseURI", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Complete", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_previousCreator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_newCreator", + "type": "address" + } + ], + "name": "CreatorshipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_beneficiary", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_itemId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_issuedId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_caller", + "type": "address" + } + ], + "name": "Issue", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "userAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "relayerAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "functionSignature", + "type": "bytes" + } + ], + "name": "MetaTransactionExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_itemId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "_contentHash", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "_metadata", + "type": "string" + } + ], + "name": "RescueItem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "_previousValue", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_newValue", + "type": "bool" + } + ], + "name": "SetApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "_previousValue", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_newValue", + "type": "bool" + } + ], + "name": "SetEditable", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_manager", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_value", + "type": "bool" + } + ], + "name": "SetGlobalManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_value", + "type": "bool" + } + ], + "name": "SetGlobalMinter", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_itemId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_manager", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "_value", + "type": "bool" + } + ], + "name": "SetItemManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_itemId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "SetItemMinter", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_itemId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "_beneficiary", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "_metadata", + "type": "string" + } + ], + "name": "UpdateItemData", + "type": "event" + }, + { + "inputs": [], + "name": "COLLECTION_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ISSUED_ID_BITS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ITEM_ID_BITS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_ISSUED_ID", + "outputs": [ + { + "internalType": "uint216", + "name": "", + "type": "uint216" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_ITEM_ID", + "outputs": [ + { + "internalType": "uint40", + "name": "", + "type": "uint40" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "string", + "name": "rarity", + "type": "string" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "internalType": "string", + "name": "metadata", + "type": "string" + } + ], + "internalType": "struct ERC721BaseCollectionV2.ItemParam[]", + "name": "_items", + "type": "tuple[]" + } + ], + "name": "addItems", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "_tokenIds", + "type": "uint256[]" + } + ], + "name": "batchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "completeCollection", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "createdAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "creator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_id", + "type": "uint256" + } + ], + "name": "decodeTokenId", + "outputs": [ + { + "internalType": "uint256", + "name": "itemId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "issuedId", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "domainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_itemIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "_prices", + "type": "uint256[]" + }, + { + "internalType": "address[]", + "name": "_beneficiaries", + "type": "address[]" + }, + { + "internalType": "string[]", + "name": "_metadatas", + "type": "string[]" + } + ], + "name": "editItemsData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_itemId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_issuedId", + "type": "uint256" + } + ], + "name": "encodeTokenId", + "outputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "userAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "functionSignature", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "sigR", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "sigS", + "type": "bytes32" + }, + { + "internalType": "uint8", + "name": "sigV", + "type": "uint8" + } + ], + "name": "executeMetaTransaction", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getChainId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "globalManagers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "globalMinters", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initImplementation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "_baseURI", + "type": "string" + }, + { + "internalType": "address", + "name": "_creator", + "type": "address" + }, + { + "internalType": "bool", + "name": "_shouldComplete", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_isApproved", + "type": "bool" + }, + { + "internalType": "contract IRarities", + "name": "_rarities", + "type": "address" + }, + { + "components": [ + { + "internalType": "string", + "name": "rarity", + "type": "string" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "internalType": "string", + "name": "metadata", + "type": "string" + } + ], + "internalType": "struct ERC721BaseCollectionV2.ItemParam[]", + "name": "_items", + "type": "tuple[]" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isApproved", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isCompleted", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isEditable", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isMintingAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_beneficiaries", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_itemIds", + "type": "uint256[]" + } + ], + "name": "issueTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "itemManagers", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "itemMinters", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "items", + "outputs": [ + { + "internalType": "string", + "name": "rarity", + "type": "string" + }, + { + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "internalType": "string", + "name": "metadata", + "type": "string" + }, + { + "internalType": "string", + "name": "contentHash", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "itemsCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rarities", + "outputs": [ + { + "internalType": "contract IRarities", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_itemIds", + "type": "uint256[]" + }, + { + "internalType": "string[]", + "name": "_contentHashes", + "type": "string[]" + }, + { + "internalType": "string[]", + "name": "_metadatas", + "type": "string[]" + } + ], + "name": "rescueItems", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "_tokenIds", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_value", + "type": "bool" + } + ], + "name": "setApproved", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_baseURI", + "type": "string" + } + ], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_value", + "type": "bool" + } + ], + "name": "setEditable", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_itemIds", + "type": "uint256[]" + }, + { + "internalType": "address[]", + "name": "_managers", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "_values", + "type": "bool[]" + } + ], + "name": "setItemsManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_itemIds", + "type": "uint256[]" + }, + { + "internalType": "address[]", + "name": "_minters", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_values", + "type": "uint256[]" + } + ], + "name": "setItemsMinters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_managers", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "_values", + "type": "bool[]" + } + ], + "name": "setManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_minters", + "type": "address[]" + }, + { + "internalType": "bool[]", + "name": "_values", + "type": "bool[]" + } + ], + "name": "setMinters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newCreator", + "type": "address" + } + ], + "name": "transferCreatorship", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/webapp/src/modules/transak/sagas.ts b/webapp/src/modules/transak/sagas.ts index 42e33e5757..54be8ac189 100644 --- a/webapp/src/modules/transak/sagas.ts +++ b/webapp/src/modules/transak/sagas.ts @@ -21,6 +21,37 @@ export function* transakSaga() { yield takeEvery(OPEN_TRANSAK, handleOpenTransak) } +const MarketplaceV3ContractIds: Pick>>, Network.MATIC | Network.ETHEREUM> = { + [Network.MATIC]: { + [ChainId.MATIC_AMOY]: '670660ed2bbeb54123b28728', + [ChainId.MATIC_MAINNET]: '6717e6cd2fb1688e111c1a80' + }, + [Network.ETHEREUM]: { + [ChainId.ETHEREUM_MAINNET]: '', + [ChainId.ETHEREUM_SEPOLIA]: '671a23e92bbeb54123b3b692' + } +} +const MarketplaceV2ContractIds: Pick>>, Network.MATIC | Network.ETHEREUM> = { + [Network.MATIC]: { + [ChainId.MATIC_AMOY]: '670e86dd2bbeb54123b3a2a3', + [ChainId.MATIC_MAINNET]: '6717e6dac00223b9cc8e51cd' + }, + [Network.ETHEREUM]: { + [ChainId.ETHEREUM_MAINNET]: '', + [ChainId.ETHEREUM_SEPOLIA]: '671f9815945ac8890fbae4c6' + } +} +const TransakMulticallContracts: Pick>>, Network.MATIC | Network.ETHEREUM> = { + [Network.MATIC]: { + [ChainId.MATIC_AMOY]: '0xCB9bD5aCD627e8FcCf9EB8d4ba72AEb1Cd8Ff5EF', + [ChainId.MATIC_MAINNET]: '0x4A598B7eC77b1562AD0dF7dc64a162695cE4c78A' + }, + [Network.ETHEREUM]: { + [ChainId.ETHEREUM_MAINNET]: '0xab88cd272863b197b48762ea283f24a13f6586dd', + [ChainId.ETHEREUM_SEPOLIA]: '0xD84aC4716A082B1F7eCDe9301aA91A7c4B62ECd7' + } +} + function* handleOpenTransak(action: OpenTransakAction) { const { asset, order } = action.payload const transakConfig: TransakConfig = { @@ -43,40 +74,37 @@ function* handleOpenTransak(action: OpenTransakAction) { const tradeId = isNFT(asset) ? order?.tradeId : asset.tradeId let calldata: string = '' let contractId - const TRANSAK_MULTICALL_CONTRACT = '0xCB9bD5aCD627e8FcCf9EB8d4ba72AEb1Cd8Ff5EF' - const MarketplaceV3ContractIds: Pick>>, Network.MATIC | Network.ETHEREUM> = { - [Network.MATIC]: { - [ChainId.MATIC_AMOY]: '670660ed2bbeb54123b28728', - [ChainId.MATIC_MAINNET]: 'XXX' - }, - [Network.ETHEREUM]: { - [ChainId.ETHEREUM_MAINNET]: 'XXX', - [ChainId.ETHEREUM_SEPOLIA]: '671a23e92bbeb54123b3b692' - } + + const transakMulticallContract = TransakMulticallContracts[asset.network]?.[asset.chainId] + if (!transakMulticallContract) { + throw new Error(`Transak multicall contract not found for network ${asset.network} and chainId ${asset.chainId}`) } + if (tradeId && wallet?.address) { contractId = MarketplaceV3ContractIds[asset.network]?.[asset.chainId] if (!contractId) { throw new Error(`Marketplace contract not found for network ${asset.network} and chainId ${asset.chainId}`) - return } const tradeService = new TradeService(API_SIGNER, MARKETPLACE_SERVER_URL, () => undefined) const trade: Trade = yield call([tradeService, 'fetchTrade'], tradeId) const { abi } = getContract(ContractName.OffChainMarketplace, asset.chainId) const MarketplaveV3Interface = new ethers.utils.Interface(abi) - calldata = MarketplaveV3Interface.encodeFunctionData('accept', [[getOnChainTrade(trade, TRANSAK_MULTICALL_CONTRACT)]]) + calldata = MarketplaveV3Interface.encodeFunctionData('accept', [[getOnChainTrade(trade, transakMulticallContract)]]) } else if (order && isNFT(asset)) { - contractId = '670e86dd2bbeb54123b3a2a3' // MarketplaceV2 contractId + contractId = MarketplaceV2ContractIds[asset.network]?.[asset.chainId] + if (!contractId) { + throw new Error(`Marketplace contract not found for network ${asset.network} and chainId ${asset.chainId}`) + } const contractName = getContractName(order.marketplaceAddress) const contract = getContract(contractName, order.chainId) const MarketplaceV2Interface = new ethers.utils.Interface(contract.abi) calldata = MarketplaceV2Interface.encodeFunctionData('executeOrder', [[asset.contractAddress, asset.tokenId, order.price]]) } else if (!isNFT(asset)) { - contractId = '670e8b512bbeb54123b3a2b4' // CollectionStore contractId + contractId = asset.chainId === ChainId.MATIC_AMOY ? '670e8b512bbeb54123b3a2b4' : '6717e6e62fb1688e111c1a87' // CollectionStore contractId const contract = getContract(ContractName.CollectionStore, asset.chainId) const CollectionStoreInterface = new ethers.utils.Interface(contract.abi) calldata = CollectionStoreInterface.encodeFunctionData('buy', [ - [[asset.contractAddress, [asset.itemId], [asset.price], [TRANSAK_MULTICALL_CONTRACT]]] + [[asset.contractAddress, [asset.itemId], [asset.price], [transakMulticallContract]]] ]) } diff --git a/webapp/src/modules/vendor/decentraland/analytics/api.ts b/webapp/src/modules/vendor/decentraland/analytics/api.ts index b1ef5ec0a7..44ca6212b4 100644 --- a/webapp/src/modules/vendor/decentraland/analytics/api.ts +++ b/webapp/src/modules/vendor/decentraland/analytics/api.ts @@ -1,6 +1,6 @@ import { BaseAPI } from 'decentraland-dapps/dist/lib/api' import { AnalyticsTimeframe, AnalyticsVolumeData } from '../../../analytics/types' -import { NFT_SERVER_URL } from '../nft' +import { MARKETPLACE_SERVER_URL } from '../marketplace/api' import { retryParams } from '../utils' class AnalyticsAPI extends BaseAPI { @@ -8,4 +8,4 @@ class AnalyticsAPI extends BaseAPI { this.request('get', `/volume/${timeframe}`) as Promise<{ data: AnalyticsVolumeData }> } -export const analyticsAPI = new AnalyticsAPI(NFT_SERVER_URL, retryParams) +export const analyticsAPI = new AnalyticsAPI(MARKETPLACE_SERVER_URL, retryParams) diff --git a/webapp/src/modules/vendor/decentraland/catalog/api.ts b/webapp/src/modules/vendor/decentraland/catalog/api.ts index 93f4967526..53af9622aa 100644 --- a/webapp/src/modules/vendor/decentraland/catalog/api.ts +++ b/webapp/src/modules/vendor/decentraland/catalog/api.ts @@ -6,7 +6,7 @@ import { retryParams } from '../utils' export class CatalogAPI extends BaseClient { async get(filters: CatalogFilters = {}, headers?: Record): Promise<{ data: Item[] }> { const queryParams = this.buildItemsQueryString(filters) - return this.fetch(`/v1/catalog?${queryParams}`, { + return this.fetch(`/v2/catalog?${queryParams}`, { headers }) } diff --git a/webapp/src/modules/vendor/decentraland/rankings/api.ts b/webapp/src/modules/vendor/decentraland/rankings/api.ts index e7e9a760e2..ea8b64c52b 100644 --- a/webapp/src/modules/vendor/decentraland/rankings/api.ts +++ b/webapp/src/modules/vendor/decentraland/rankings/api.ts @@ -1,6 +1,6 @@ import { BaseAPI } from 'decentraland-dapps/dist/lib/api' import { AnalyticsTimeframe, RankingEntities, RankingEntity, RankingsFilters } from '../../../analytics/types' -import { NFT_SERVER_URL } from '../nft' +import { MARKETPLACE_SERVER_URL } from '../marketplace/api' import { retryParams } from '../utils' const DEFAULT_REQUEST_SIZE = 5 @@ -30,4 +30,4 @@ class RankingsAPI extends BaseAPI { } } -export const rankingsAPI = new RankingsAPI(NFT_SERVER_URL, retryParams) +export const rankingsAPI = new RankingsAPI(MARKETPLACE_SERVER_URL, retryParams)