Configuring Royalties

Guide to set up royalties to be compatible with GhostMarket.

On either our integrated EVM blockchains (BSC/Avalanche/Polygon/Ethereum/Base) or Neo N3, we support two different kind of royalties: NFT level royalties Contract level royalties (also called collection level royalties) On Phantasma, we support only NFT level royalties.

Note that if a NFT has royalties, our current implementation prevent it to be traded against indivisible currencies (like NEO), but if it does not have royalties, it's allowed.

NFT level royalties

Those are royalties at a NFT level, meaning on one smart contract each NFT can have individual royalties recipient and values.

EVM

For NFT level royalties on EVM, as long as a contract support EIP-2981, our trading contracts will honour the configured per NFT royalties automatically if supported by the contract, without having to configure anything.

Neo N3

For NFT level royalties on Neo N3, a contract need to implement a custom method getRoyalties which we designed. This method also has to be tagged as Safe (read only). Example in Python:

@public(safe=True) def getRoyalties(tokenId: bytes) -> bytes: """ Get a token royalties values. :param tokenId: the token to get royalties values :type tokenId: ByteString :return: bytes of addresses and values for this token royalties. :raise AssertionError: raised if any tokenId is not a valid NFT. """ royalties = get_royalties(tokenId) return royalties

The returned royalties has to be in the following JSON format [{"address":"NNau7VyBMQno89H8aAyirVJTdyLVeRxHGy","value":"1000"}]where NNau7VyBMQno89H8aAyirVJTdyLVeRxHGy would be getting 10% of all sales as royalties. Note that the value is in BPS (ie 10% is 1000). We support multiple royalties, up to a maximum combined of 50% royalties. Once implemented in a contract, our trading contracts will honour the configured per NFT royalties automatically if supported by the contract, without having to configure anything.

Phantasma

For NFT level royalties on Phantasma, as long as a smart contract implements Phantasma native royalty standard, our trading contracts will honour the configured per NFT royalties automatically if supported by the NFT, without having to configure anything. Phantasma royalty standard requires the following in ROM for each NFT where one wants royalty:

            creator, // creator - royalties recipient
            royalties // royalties - royalties value - integer

Contract level royalties

Those are royalties at a contract level, meaning on one smart contract the royalties recipient and value is the same for all the NFT. This type of royalties can be configured either from GhostMarket platform itself (in collection settings, when connected with a contract owner wallet), or by directly interacting with smart contracts as explained in the next section.

EVM

For contract level royalties on all the EVM blockchains we have integrated, we have a custom royalties registry smart contract, where contract owners can register their own custom royalty recipient / royalty value. To do so, a transaction needs to be initiated on our royalties smart contract and call a method with some parameters: - Avalanche MainNet royalties contract: 0x913FbdC42a77edb0aEFFCEEAe00240C368d9B6b1 - Avalanche Testnet royalties contract: 0x92bf637c4FadEC1b698002cbA1583850e6EC97d3

- BSC MainNet trading royalties: 0x1073e1d5977002d5db4F9E776482E8BF113C745c - BSC Testnet trading royalties: 0x5EC6bFE900C140323C66FC9Fc53619631B46Cb69

- Polygon MainNet royalties contract: 0x7eD7Bff3bEfa9cEDf6A6d4768F4051fEd7fC1975 - Polygon Testnet royalties contract: 0x7E20461EcC3B27586EFEa0e3dB9E80bfbE55B9eB

- Ethereum MainNet royalties contract: 0x3dA0bD10dfD98E96E04fbAa8e0512b2c413b096A - Ethereum Testnet royalties contract: 0xca1284B5EEb97c31cc693c4b182C8E1075Dc57f9

- Base MainNet royalties contract: 0x92E20C3534535db17D4c7c622538eB0930544230 - Base Testnet royalties contract: 0xca1284B5EEb97c31cc693c4b182C8E1075Dc57f9

- method: setRoyaltiesByToken - parameters: token (address), and royalties (array of account/value objects)

Here's an example of the parameters in Javascript when calling this method to configure a contract royalties for one royalty recipient/value:

        const royaltiesStruct = [[royaltiesRecipient, royalties]]

        const dataOrMethod = contract.methods.setRoyaltiesByToken(
            contractHash, // contract address
            royaltiesStruct // royalties in BPS
        )

Neo N3

For contract level royalties on Neo N3 we have a custom method on our trading smart contract, where contract owners can register their own custom royalty recipient / royalty value. To do so, a transaction needs to be initiated on our trading contract and call a method with some parameters: - Neo N3 MainNet trading contract: 0xcc638d55d99fc81295daccbaf722b84f179fb9c4 - Neo N3 TestNet trading contract: 0xa4276772f429fc31032c4cd8bf3c98c806318f3e

- method: SetRoyaltiesForContract - parameters: contract (UInt160), and royalties (array of Address/Value objects) Important: this method requires a double Signer, 1) the contract owner, and 2) the contract itself. So when calling it, you need to pass an array of those two Signers

        const signers = [
            {
                account: contractOwner, // script hash format
                scopes: 16,
                allowedContracts // trading contract + nft contract to register
            },
            {
                account: contractHash, // script hash format
                scopes: 16,
                allowedContracts // trading contract + nft contract to register
            }
        ]

Here's an example of the parameters to pass in Javascript when calling this method to configure a contract royalties for one royalty recipient/value:

        argsSetCollectionRoyalties = [
            {
                type: 'Hash160', // UInt160
                value: contractHash
            },
            {
                type: 'Array', // Array
                value: [
                    {
                        type: 'Array', // Array
                        value: [
                            {
                                type: 'Hash160', // UInt160
                                value: royaltiesRecipient // recipient script hash
                            },
                            {
                                type: 'Integer', // BigInteger
                                value: royaltiesValue // royalties in BPS
                            }
                        ]
                    }
                ]
            }
        ]

Last updated