# Welcome to NFTDelegation

An introduction to NFTDelegation, and why we need it.

## Overview and purpose

Crypto makes self-sovereignty of digital goods like NFTs a reality.&#x20;

When we hold our own NFTs, we become their guardian: responsible for the safe and secure storage and management of each one. We must protect ourselves from scammers, phishing sites, accidents, loss, and all the other ways our NFTs may be exposed.

We need NFTDelegation: on-chain NFT security management, permissionless and accessible by anyone, to mitigate the risks to valuables that come with self-custody, while allowing the NFT owners to remaining actively involved in web3 communities.

NFTDelegation primarily provides an easy way to register and manage:&#x20;

1. delegation of the community benefits associated with holding an NFT
2. and consolidation of multiple addresses into a single crypto-centric identity.

NFTDelegation is an open-source smart contract that implements a complete vision of NFT delegation and address consolidation, developed by 6529 Open Research Labs. The smart contract functions can be accessed directly, or more conveniently through NFTDelegation.com, which enables an easy way to register and manage your delegations and consolidations.

The combination of these delegation and consolidation features support a multi-address architecture for secure and convenient NFT activities across the web3 ecosystem. We will explain this fully, here in this guide.

Please note: while NFTDelegation requires on-chain transactions to write data to the blockchain, the NFTs of connected wallets are never touched by the smart contract. NFTDelegation cannot transfer any assets. You'll see no such permission requests when signing in. The source code is reviewable as verification that NFTs simply cannot be moved by any action taken through the NFTDelegation smart contract.

## What is a delegation?

Delegation allows NFT ownership advantages to be shared beyond the address holding the NFT.

Holding an NFT can grant the address that holds it certain benefits, such as allowlist access for minting, or voting rights. To show you are the owner of the NFT, you would traditionally need to connect the wallet holding the NFT to the site providing the benefit.&#x20;

But connecting to many sites with a address holding a lot of value is clearly unwise. Get just one signature wrong, and your wallet could be drained.&#x20;

Delegation bestows the benefits of holding an NFT (in a 'cold' wallet) on a different address (a 'hot' wallet), without transferring ownership and without the risks. You can then use this hot wallet (that's holding less value) to connect to web3 sites, without any concern of losing the original NFT.&#x20;

Beyond minting or voting, this could also be used for claiming airdrops, metaverse integration, and much more.

## What is consolidation?

While managing multiple addresses can provide great security, how can we identify that they all belong to the same person? Consolidation!&#x20;

Consolidation is an on-chain method of signing a two-way agreement between addresses, to indicate they both assert that they belong together, to be treated as a single entity.&#x20;

This allows users of delegations to indicate publicly that their addresses are unified, much like the way someone will use the same distinctive handle across social media sites to indicate they all belong to the same person.

Similarly, by utilizing consolidations, web3 communities can recognize the activity of individual members, as they take actions across multiple addresses. For example: as a new NFT is minted and eventually transferred to a vault address, it will show as changing addresses. But if those addresses are consolidated, it can be recognized as the work of a single individual.&#x20;

## How does NFTDelegation work?

The NFTDelegation smart contract simply holds a mapping between your addresses, with your chosen description of when that mapping should apply.

By holding data on-chain, your delegations are available to any dApp that chooses to recognize and work with delegated addresses.

You can use NFTDelegation.com to describe how your addresses are related to each other, and that information is recorded fully on-chain. Don't want to connect through our site? No problem: you can register your delegations directly on the smart contract via your favorite blockchain explorer.

Any projects that want to make use of this info can get the data from the blockchain, without any additional input or signing required.

## Explore more of what's possible

{% content-ref url="/pages/kvFfTJRw7cYTkrhanCl9" %}
[Features](/overview/features)
{% endcontent-ref %}

{% content-ref url="/pages/QM6bkY7umOYmlhKJBsFJ" %}
[Use Cases](/overview/use-cases)
{% endcontent-ref %}

## Get started

We've put together some helpful guides for you to get setup with NFTDelegation quickly and easily.

{% content-ref url="/pages/IqD2zChdlEwnicQPuuwC" %}
[How to Register a Delegation?](/guides/how-to-register/how-to-register-a-delegation)
{% endcontent-ref %}

{% content-ref url="/pages/syn2rMkimXmBXvzxH48Q" %}
[How to Register a Delegation Manager?](/guides/how-to-register/how-to-register-a-delegation-manager)
{% endcontent-ref %}

{% content-ref url="/pages/qtj0aJ8GfM4jz6uDXyEL" %}
[How to Register a Consolidation?](/guides/how-to-register/how-to-register-a-consolidation)
{% endcontent-ref %}


# Features

The smart contract has extensive options for managing delegations

## Basic delegation by use case and collection

There are 4 distinct approaches to basic delegation. In all cases, the 'vault' address holds the NFTs, and assigns rights and benefits to a more active 'hot' address (that holds very limited value).&#x20;

In the most general case, the vault delegates all rights and benefits to hot address, for ANY collection of NFTs. Once that delegation is recorded on chain, projects that recognize NFTDelegation will grant NFT ownership benefits to the hot address.

The granting of all rights can also be scoped to a specific NFT collection. For example, a collector who desires to interact with The Memes collection via a dedicated address like memes.collector.eth can use NFTDelegation to assign all rights from the vault, to that specific address. NFTs from other collections will not be impacted, and can have their own collection-specific delegations.&#x20;

Collectors may also assign specific rights on an individual basis, with use cases. By using use-case specific delegations, the vault address might assign voting rights to one address, and minting rights to a different address.&#x20;

These specific use-cases can be assigned by individual collection, or can apply for all collections.&#x20;

So, from most general to most specific, the basic approaches that can be registered on-chain are:

1. Delegate ALL use cases for ANY collection
2. Delegate ALL use cases for a single collection
3. Delegate a specific use case for ANY collection
4. Delegate a specific use case for a single collection

These different delegations can co-exist, and may at times even overlap. Projects will generally recognize the most recent delegation that applies as the canonical option to respect, if there is any conflict.

## NFTDelegation supports deep customization

Beyond scoping delegations to specific use cases or collections, collectors can get even more granular, and register delegations for individual tokens.&#x20;

For example, if a collector had multiple BAYC tokens in the vault, each token could delegate rights to a distinct active address. That would let activity related to each token remain separated by address.&#x20;

In further support of fine-grained management, collectors may choose an expiration date for delegations of all types. This means the assignment of rights will be time limited, from the time of creation. This is useful for temporary delegations, or short-term configurations that you don't want to have to remember to revert.&#x20;

Delegations can be created with these options one at a time, or in batches.&#x20;

## All delegations are updatable revokable

Any delegation that's recorded on the blockchain can be updated through the NFTDelegation smart contract or website. Updates can rewrite any of the key attributes of the delegation.

Sometimes, updates aren't enough. At any time, a collector may revoke previously-created delegations. This breaks the link between addresses.&#x20;

Revocation of delegations can also be done in batches, for expedient removal of assigned delegationas.&#x20;

## Addresses can be locked

If a collector does not want their address to accept any incoming delegation assignments, they can mark their address as locked, via the NFTDelegation smart contract.&#x20;

This will prevent anyone else from delegating to the locked address. Any attempts to delegate to a locked address will result in an error message.

## Reading delegation data

The NFTDelegation smart contract provides a number of ways to retrieve delgation date from the blockchain.&#x20;

Projects wanting to use delegation data can invoke functions to:&#x20;

1. return an array of all delegation addresses assigned by a Delegator for a specific use case on a specific NFT collection (including the option for ALL + ANY general delegations).
2. return an array of all delegators for a specific use case on a specific NFT collection given a delegation address.
3. return an array of all active delegations for a specific use case on a specific NFT collection on a certain date.
4. return an array of all active Delegators for a specific use case on a specific NFT collection on a certain date.
5. get the status (true/false) of a delegation.
6. get the status (true/false) of a delegation, given a token id.
7. check the status (true/false) of an active delegator on a given date.
8. get the tokens ids as well as the expiry dates of a delegation given a delegator address and an assigned address.
9. get the most recent delegation address delegated on a specific use case
10. get the most recent Delegator given an assigned address.
11. check the consolidation relationship between two addresses.

All this info can be used during mints, or any other times that NFT possession brings rights along with it.&#x20;


# Use Cases

## Active (canonical) use cases

| #N        | Use Case                                                              |
| --------- | --------------------------------------------------------------------- |
| 1         | All                                                                   |
| 2         | Minting / Allowlist                                                   |
| 3         | Airdrops                                                              |
| 4         | Voting / Governance                                                   |
| 5         | Avatar Display                                                        |
| 6         | Social Media                                                          |
| 7         | Physical Events Access                                                |
| 8         | Virtual Events Access                                                 |
| 9         | Club Access                                                           |
| 10        | Metaverse Access                                                      |
| 11        | Metaverse Land                                                        |
| 12        | Gameplay                                                              |
| 13        | IP Licensing                                                          |
| 14        | NFT rentals                                                           |
| 15        | View Access                                                           |
| 16        | Manage Access                                                         |
| 17        | Mint To Address                                                       |
| 18        | Team                                                                  |
| 19        | Artists                                                               |
| 20 to 949 | Reserved by NFTDelegation.com for future Active (Canonical) Use Cases |

* Use cases #1 to #19 are active canonical (official) use cases.
* \#20 to #949 are reserved for additional Active (Canonical) use cases, to be added from time to time by NFTDelegation.com.

## Special use cases

| #N         | Use Case                               |
| ---------- | -------------------------------------- |
| 950 to 997 | Reserved for Future Special Use Cases  |
| 998        | Delegation Management (Sub-delegation) |
| 999        | Consolidation                          |

* Special Use Cases are not captured by Use Case #1 ("All").
* \#950 to #997 are reserved for future Special use cases.
* \#998 is for Delegation Management (Sub-delegation) (giving the right to another address to add or remove delegations on the initial address's behalf).
* \#999 is for Consolidation (linking addresses together).

## Application specific use cases

| #N    | Use Case                       |
| ----- | ------------------------------ |
| 1000+ | Application-specific use cases |

* \#1,000+ are available to any team who wants to create an application-specific use case.
* Any team can call the updateUseCaseCounter() function to increment/create another use case for their own use.


# How to Register

{% content-ref url="/pages/IqD2zChdlEwnicQPuuwC" %}
[How to Register a Delegation?](/guides/how-to-register/how-to-register-a-delegation)
{% endcontent-ref %}

{% content-ref url="/pages/syn2rMkimXmBXvzxH48Q" %}
[How to Register a Delegation Manager?](/guides/how-to-register/how-to-register-a-delegation-manager)
{% endcontent-ref %}

{% content-ref url="/pages/qtj0aJ8GfM4jz6uDXyEL" %}
[How to Register a Consolidation?](/guides/how-to-register/how-to-register-a-consolidation)
{% endcontent-ref %}

{% content-ref url="/pages/BPGVI73gae6LSxmPDEzG" %}
[How to Delegate using SAFE (formerly GNOSIS) using the Transaction Builder?](/guides/how-to-register/how-to-delegate-using-safe-formerly-gnosis-using-the-transaction-builder)
{% endcontent-ref %}


# How to Register a Delegation?

Use a delegation to allow a “hot” wallet to take actions on behalf of a “cold” wallet.

#### Steps on Registering a Delegation:

1. Launch the Delegation Wizard.
2. Choose Delegate Action and click Next.
3. Select a specific Use case to register a delegation or just choose all use cases and click Next.
4. Select a specific Collection to register the delegation or choose Any Collection and click Next.
5. Enter the Delegate Address and click Next.
6. Review Details, click Submit and execute the transaction.

Please note that if the connected address was assigned by an address as a Delegation Manager after you select the Delegate Action Type you will be asked to Select the address for which you want to register a delegation. In this case you can select Connected wallet and proceed with the next steps.


# How to Register a Delegation Manager?

Delegation Management (Sub-delegation) allows you to reduce the number of delegation transactions you perform with your "Vault Address" by delegating all contract interactions, including changing delegations, to a "Delegated Address."

This ensures your Vault remains cold (not connected) after the initial Delegation Management delegation.

To use Delegation Management (Sub-Delegation) do the following:

1. With your "Vault Address," perform a single transaction to register a Delegation Manager to your "Delegated Address".
2. Use the "Delegated Address" with Delegation Management (Sub-delegation) permissions to register future or additional delegations on behalf of the delegator.

#### Steps on Registering a Delegation Manager:

1. Launch the Delegation Wizard.
2. Click on Appoint Delegation Manager and click Next.
3. Select a specific Collection or choose Any Collection and click Next.
4. Enter the Delegate Address and click Next.
5. Review Details, click Submit and execute the transaction.

Please note that if the connected address was assigned by an address as a Delegation Manager after you select the Appoint Delegation Manager Type you will be asked to Select the address for which you want to register a delegation manager. In this case you can select Connected wallet and proceed with the next steps.


# How to Register a Consolidation?

A consolidation is used when you want to establish an ownership connection between two addresses, such as combining the Total Days Held (TDH) of multiple wallets that you control.

To create a consolidation between two wallets (e.g., Wallet A and Wallet B), both wallets must register a consolidation with each other.

This means that you need to register a delegation address with consolidation from Wallet A to Wallet B, and vice versa, from Wallet B to Wallet A.

#### Steps on Registering a Consolidation:

1. Launch the Delegation Wizard.
2. Click on Consolidate Wallets Type and click Next.
3. Select a specific Collection or choose Any Collection and click Next.
4. Enter the Delegate Address and click Next.
5. Review Details, click Submit and execute the transaction.

Please note that if the connected address was assigned by an address as a Delegation Manager after you select the Consolidate Wallets Type you will be asked to Select the address for which you want to register a consolidation. In this case you can select Connected wallet and proceed with the next steps.


# How to Register a Delegation/ Consolidation/Delegation Manager (Advanced)?

This process allows you to create 1..5 delegations, insert an expiry date or delegate a specific token id..

1. Launch the Delegation Wizard.
2. Click on the Advanced Users button.
3. Complete the form:
   * Choose a Type.
   * Choose the collection for which you want to register the delegation (e.g., ‘Any Collection’ for all collections or a specific collection such as 'The Memes Collection').
   * Enter the delegation address (e.g., a hot wallet address).
   * Select a specific use case for the delegation (e.g., '#1 All').
4. Continue, or Click the 'Submit' button and execute the transaction.

Using the process below you will be able to add an expiry date or a specific token id during the registration. To do so:

1. Before submitting please Click on the Change Button.
2. Set an Expiry Date.
3. Select a specific Token ID.
4. Continue, or Click the 'Submit' button and execute the transaction.

As mentioned earlier this process allows you also to register 1..5 delegations under a single transaction. To do so:

1. After you fill in the details needed to register a delegation, click the Batch button. This will open a new form to fill in.
2. After you finish with all delegations Click the 'Submit' button and execute the transaction.


# How to Delegate using SAFE (formerly GNOSIS) using the Transaction Builder?

This page outlines the process for registering a Delegation Manager (Sub-delegation) to a "Delegated Wallet" using your "Safe Wallet".\
\
Safe (formerly Gnosis Safe) is a multi-signature smart contract-based wallet often used as a secure vault for NFTs and other tokens. You can find out more about SAFE [here.](https://safe.global/)\
\
Delegation Management (Sub-delegation) allows you to reduce the number of delegation transactions you perform with your "Vault Address" by delegating all contract interactions, including changing delegations, to a "Delegated Address."

#### Recommended Approach

The best approach for most Safe users is to set a Delegation Manager to a hotter address such as a Trezor address. This allows the hotter wallet to make and change delegations on behalf of the Safe without having to sign further transactions from the Safe.

The steps below show how to set a Delegation Manager (Sub-delegation), for all collections and all use cases. If you would like to set a different type of delegation, you would follow the same general process but make different selections for the collection or use cases.

1. Connect with your "Safe Wallet" [here](https://app.safe.global/welcome) and go to the Transaction Builder app.
2. In the New Transaction Area:
   * Enter the NFTDelegation.com smart contract Address: 0x2202CB9c00487e7e8EF21e6d8E914B32e709f43d
   * Enter the NFTDelegation.com smart contract ABI. [Click here to get the ABI.](https://6529bucket.s3.eu-west-1.amazonaws.com/seize_html/delegations-center-getting-started/screenshots/NFTDelegationABI.js.json)
3. In the Transaction Information Area:
   * Select registerDelegationAddress as the Contract Method Selector
   * Enter the value 0x8888888888888888888888888888888888888888 in the collection address box. This value refers to "Any Collection".
   * Enter the delegation address (for the Delegation Manager).
   * Enter the value 64060588800 as the expiry date. This value represents "no expiry date".
   * Enter the value 998 as the Use Case. This value represents "Delegation Management (Sub-delegation)".
   * Enter true in the allTokens input box.
   * Enter 0 in the tokenId input box.
   * Click the 'Add transaction' button.
4. To Execute the transaction:
   * Click on the 'Create Batch' button.
   * Click on the 'Send Batch' button.
   * Click on the 'Submit' button and execute the transaction.

Please note that if you want to register just a Delegation Action or a consolidation for your Safe wallet you can follow the same steps but you need to change the Use Case value within the Transaction Information Area.<br>


# How to View

{% content-ref url="/pages/zKSKTVrqRtsw0OUSEI1y" %}
[How to View Your Delegations?](/guides/how-to-view/how-to-view-your-delegations)
{% endcontent-ref %}

{% content-ref url="/pages/G0NKqDtThkt4UFLtWoIM" %}
[How to View Your Delegation Managers (Sub-Delegations)?](/guides/how-to-view/how-to-view-your-delegation-managers-sub-delegations)
{% endcontent-ref %}

{% content-ref url="/pages/0N023nvu9RPfUIHbMdGE" %}
[How to View Your Consolidations?](/guides/how-to-view/how-to-view-your-consolidations)
{% endcontent-ref %}


# How to View Your Delegations?

1. Click on My Activity.
2. Select a Collection from the My Collections Section.
3. At the Delegations Area within the Collection you will be able to view your outgoing and incoming delegations.

You can also use the Filters that exist on the My Activity page to view your delegations by selecting Delegations from the Type drop-down menu.


# How to View Your Delegation Managers (Sub-Delegations)?

1. Click on My Activity.
2. Select a Collection from the My Collections Section.
3. At the Delegation Managers (Sub-Delegations) within the Collection you will be able to view your outgoing and incoming sub-delegations.

You can also use the Filters that exist on the My Activity page to view your Delegation Managers by selecting Delegation Managers from the Type drop-down menu.


# How to View Your Consolidations?

1. Click on My Activity.
2. Select a Collection from the My Collections Section.
3. At the Consolidations within the Collection you will be able to view your outgoing and incoming consolidations.

You can also use the Filters that exist on the My Activity page to view your Consolidations by selecting Consolidations from the Type drop-down menu.


# How to Manage

{% content-ref url="/pages/kJKNNE4jUjmiU2fqHZmc" %}
[How to Update a Delegation/Delegation Manager/Consolidation?](/guides/how-to-manage/how-to-update-a-delegation-delegation-manager-consolidation)
{% endcontent-ref %}

{% content-ref url="/pages/cXBXEFi1MvPYX0mlPjGI" %}
[How to Revoke a Delegation/Delegation Manager/Consolidation?](/guides/how-to-manage/how-to-revoke-a-delegation-delegation-manager-consolidation)
{% endcontent-ref %}


# How to Update a Delegation/Delegation Manager/Consolidation?

1. Click on My Activity.
2. Select a Collection from the My Collections Section.
3. On the Collection page, find the address that you want to update and click the 'Update' button next to it.
4. Fill out the Update Delegation form:
   * Enter the new address.
   * Select an expiry date.
   * Specify if the updated delegation applies to all tokens owned by the Delegator or just a specific token.
5. Click the 'Submit' button and execute the transaction.


# How to Revoke a Delegation/Delegation Manager/Consolidation?

**Method 1:**

1. Click on My Activity.
2. Select a Collection from the My Collections Section.
3. On the Collection page, find the address that you want to revoke and click the 'Revoke' button next to it.
4. Execute the transaction.

**Method 2:**

Within the My Activity Page you can see a set of Actions under the My Actions section.

1. Click on Revoke.
2. Now you can select 1..5 delegations to remove.
3. Click the Revoke button at the end of the list.
4. Execute the transaction.


# How to Manage using Delegation Management (Sub-Delegation) Rights

{% content-ref url="/pages/ot5EpMfoYNeM1N17XbDb" %}
[How to Register a Delegation Using Delegation Management (Sub-Delegation) Rights?](/guides/how-to-manage-using-delegation-management-sub-delegation-rights/how-to-register-a-delegation-using-delegation-management-sub-delegation-rights)
{% endcontent-ref %}

{% content-ref url="/pages/PIo3lvQ7itubRZABSfKj" %}
[How to Revoke a Delegation Using Delegation Management (Sub-Delegation) Rights?](/guides/how-to-manage-using-delegation-management-sub-delegation-rights/how-to-revoke-a-delegation-using-delegation-management-sub-delegation-rights)
{% endcontent-ref %}


# How to Register a Delegation Using Delegation Management (Sub-Delegation) Rights?

First of all you need to be sure that you were Appointed as a Delegation Manager.

**Method 1:**

1. Launch the Delegation Wizard.
2. Choose Delegate Action and click Next.
3. Select the Delegator Address for which you want to register a delegation on his/her behalf.
4. Select a specific usecase to register the delegation or just choose all use cases and click Next.
5. Select a specific Collection to register the delegation or choose Any Collection and click Next.
6. Enter the Delegate Address and click Next.
7. Review Details, click Submit and execute the transaction.

Note: If you would like to set a Delegation Manager or a Consolidation, you should follow the same general process but you need to select the 'Consolidate Wallets' or 'Appoint Delegation Manager' types instead of Delegate Actions.

**Method 2:**

1. Launch Delegation Wizard.
2. Click on the Advanced Users button.
3. Click on the Register as Delegation Manager button.
4. Complete the form:
   * Select Delegator.
   * Choose a Type.
   * Choose the collection for which you want to register the delegation (e.g., ‘Any Collection’ for all collections or a specific collection such as 'The Memes Collection').
   * Enter the delegation address (e.g., a hot wallet address).
   * Select a specific use case for the delegation (e.g., '#1 All').
5. Click the 'Submit' button and execute the transaction.

Please note that using the Method 2 you are also able to add an expiry date or add a specific token id during the registration of a delegation. To do so:

1. Before submitting please Click on the Change Button.
2. Set an Expiry Date.
3. Select a specific Token ID.
4. Click the 'Submit' button and execute the transaction.


# How to Revoke a Delegation Using Delegation Management (Sub-Delegation) Rights?

First of all you need to be sure that you were Appointed as a Delegation Manager.

1. Click on My Activity.
2. Select the Delegation Manager type from the Type drop-down menu.
3. Click on the Delegation Manager address.
4. Once you are in the Delegation Manager Activity Area you will be able to view the My Delegation Manager Actions.
5. Click on Revoke.
6. Select the delegation that you would like to revoke on behalf of the Delegation Manager.
7. Click the Revoke button at the end of the list.
8. Execute the transaction.


# How to Lock

{% content-ref url="/pages/cS8O603oNbCHs5y66E4y" %}
[How to Globally Lock Your Wallet ?](/guides/how-to-lock/how-to-globally-lock-your-wallet)
{% endcontent-ref %}

{% content-ref url="/pages/42k0e6IubFKaO2zELZ0d" %}
[How to Lock Your Wallet for a Specific Collection?](/guides/how-to-lock/how-to-lock-your-wallet-for-a-specific-collection)
{% endcontent-ref %}

{% content-ref url="/pages/ycFYVzMo26A4doBZuabL" %}
[How to Lock Your Wallet for a Specific Use Case on a Collection?](/guides/how-to-lock/how-to-lock-your-wallet-for-a-specific-use-case-on-a-collection)
{% endcontent-ref %}


# How to Globally Lock Your Wallet ?

The primary purpose of a Global Lock is to lock your address in order to reject any incoming delegation. While we do not think this will be a common case, we could imagine people doing this to then try to socially engineer a third party by pretending your addresses are related. Note that nobody can delegate on your behalf, in any case.

You should only do this after you have made your own delegations, if you are certain that you do not plan to delegate any more addresses, as you would have to then unlock to accept your own delegations.

**To lock your wallet globally:**

**Method 1:**

1. Click on My Activity.
2. Select 'Any Collection' from the My Collections Section.
3. At the bottom of the Manage/View Any Collection page, click the 'Lock Wallet' button.
4. Execute the transaction.

**Method 2:**

Within the My Activity Page you can see a set of Actions under My Actions section.

1. Click on Lock Wallet.
2. Execute the transaction.


# How to Lock Your Wallet for a Specific Collection?

The primary purpose of Collection lock is to lock your address so as to reject any incoming delegations for a specific collection.

You should only do this after you have made your own delegations, if you are certain that you do not plan to delegate any more addresses, as you would have to then unlock to accept your own delegations.

**To lock your wallet for a specific collection:**

1. Click on My Activity.
2. Select a Collection from the My Collections Section.
3. At the bottom of the Manage/View Any Collection page, click the 'Lock Wallet' button.
4. Execute the transaction.


# How to Lock Your Wallet for a Specific Use Case on a Collection?

The primary purpose of Use case lock is to lock your address so as to reject any incoming delegations for a specific use case either on a specific collection or all collections.

You should only do this after you have made your own delegations, if you are certain that you do not plan to delegate any more addresses, as you would have to then unlock to accept your own delegations.

**To lock your wallet for a specific use case:**

1. Click on My Activity.
2. Select a Collection from the My Collections Section.
3. Click the 'Lock Use Case' button.
4. Execute the transaction.

Please note that if you choose Any Collection then the Use case lock will apply for all contracts.


# How to Unlock

{% content-ref url="/pages/33hhoREg7uyzWwU326rh" %}
[How to Globally Unlock Your Wallet ?](/guides/how-to-unlock/how-to-globally-unlock-your-wallet)
{% endcontent-ref %}

{% content-ref url="/pages/oiImkVkWEE7GSwG6AfGX" %}
[How to Unlock Your Wallet for a Specific Collection?](/guides/how-to-unlock/how-to-unlock-your-wallet-for-a-specific-collection)
{% endcontent-ref %}

{% content-ref url="/pages/S3EnvMRWvARSPndBDFgN" %}
[How to Unlock Your Wallet for a Specific Use Case?](/guides/how-to-unlock/how-to-unlock-your-wallet-for-a-specific-use-case)
{% endcontent-ref %}


# How to Globally Unlock Your Wallet ?

**Method 1:**

1. Click on My Activity.
2. Select 'Any Collection' from the My Collections Tab.
3. At the bottom of the Manage/View Any Collection page, click the 'Unlock Wallet' button.
4. Execute the transaction.&#x20;

**Method 2:**

Within the My Activity Page you can see a set of Actions under My Actions section.

1. Click on Unlock Wallet.
2. Execute the transaction.

Your wallet will be unlocked, and it will start accepting incoming delegations for any collection.


# How to Unlock Your Wallet for a Specific Collection?

1. Click on My Activity.
2. Select a Collection from the My Collections Tab.
3. At the bottom of the Manage/View Any Collection page, click the 'Unlock Wallet' button.
4. Execute the transaction. Your wallet will be unlocked, and it will start accepting incoming delegations for that specific collection.


# How to Unlock Your Wallet for a Specific Use Case?

1. Click on My Activity.
2. Select a Collection from the My Collections Tab.
3. Click the 'Unlock Use Case' button.
4. Execute the transaction.&#x20;

Your wallet will be unlocked, and it will start accepting incoming delegations for that specific use case on the collection.


# What is TAP?

This page outlines **TAP**, a Three Address Protocol for organizing your Ethereum addresses and using the delegation, consolidation and delegation management features of NFTDelegation to enhance security. While personal circumstances may vary and no approach is fool-proof, the following guidelines should benefit most people in the NFT ecosystem.

Your personal circumstances may vary, no approach is fool-proof and you still have to get implement the below correctly, but the overall approach described should be a good approach for most people.

Overview: It is crucial to implement safety measures to protect your Ether, ERC-20 tokens, and NFTs. Common ways to lose cryptocurrency assets include:

* Phishing: Disclosing your seed phrase or granting access to your computer (e.g., via screen sharing) to someone. The best way to mitigate this risk is by never revealing your seed phrase or computer access.
* Malware: Malicious software on your computer can access the private key of a hot wallet such as Metamask. The most effective tactic is to use a hardware wallet.
* Connecting to malicious websites: These sites can steal your NFTs if you sign a malicious transaction, even when using a hardware wallet. To avoid this issue, use separate addresses for your "vault," "transaction wallet," and "minting wallet."

By organizing your Ethereum activities to avoid these risks, you can reduce your risk of loss.

**How to use TAP?**

1. Create three Ethereum addresses:
   1. Address A: The "vault" where you store NFTs for extended periods without connecting it to any services. You only transfer NFTs in and out of this address.
   2. Address B: The "transaction" address where you store NFTs you are currently selling and is used for buying or selling NFTs on trusted marketplaces such as OpenSea.
   3. Address C: The "minting" address for minting NFTs and connecting to unknown or untrusted services. You have no NFTs held on this address and you can mint wherever you want. Once you mint, transfer to the Vault or Transaction address
2. Reasonable variations of the above approach could include:
   1. Higher Security: Address A can be a SAFE (formerly Gnosis) multi-sig smart contract for enhanced security and resilience.
   2. More Convenience: Address C can be a hot wallet or mobile wallet for easier minting.
3. (Optional) Label addresses using ENS subdomains (e.g., mint.yourname.eth) for improved legibility and reduced risk of erroneous transactions.

| Good TAP                           | Great TAP                                 |
| ---------------------------------- | ----------------------------------------- |
| Minting (MM Address)               | Minting (MM or HW Wallet Address #1)      |
| Transaction (HW Wallet Address #1) | Transaction (HW Wallet Address #2)        |
| Vault (HW Wallet Address #2)       | Vault ([@safe](https://twitter.com/safe)) |


# How to Register Delegations (TAP)?

Registering delegations allows you to mint or perform other actions from your most convenient wallet. The optimal method for setting delegations in TAP is described below.

Assuming three sample addresses:

* Address A (vault address) : 0xAcf42B85eCb77d9332584119FD78a3DE9953c2a0
* Address B (transaction address) : 0x3558C942EeA9e9Bb9b1a6A02d272756EDD3A1Fe4
* Address C (minting address) : 0xD0f03CB42Fe821c0654846E474c19484865c5B4a

1. Connect to NFTDelegation.com with Address A (vault) and Set Address B (transaction) as the Delegation Manager of Address A by following the steps below:
   1. Launch the Wallet Wizard.
   2. Select Appoint Delegation Manager and click Next.
   3. Select a specific Collection or choose Any Collection and click Next.
   4. Insert the Delegate Address and click Next.
   5. Review Details and click Submit.

Note: Once completed, Address A will not need to connect to any service again, and further delegations can be made on its behalf by Address B.

2. Connect to NFTDelegation.com with Address B (transaction):

   1. Delegate Use Case 1 (all) or 2 (minting/allowlist) to Address C (minting).
      * Launch the Wallet Wizard.
      * Select Delegate Actions and click Next.
      * Select Connected wallet as the Delegator.
      * Select all Use Cases or Use Case #2 Minting / Allowlist and click Next.
      * Select Any Collection and click Next.
      * Enter wallet Address C and click Next.
      * Review Details, click Submit and execute the transaction.
   2. Delegate Use Case 1 (all) or 2 (minting/allowlist) on behalf of Address A (vault) to Address C (minting).
      * Click on My Activity.
      * Select Delegate Actions and click Next.
      * Select Address A as the Delegator.
      * Select all Use Cases or Use Case #2 Minting / Allowlist and click Next.
      * Select Any Collection and click Next.
      * Enter wallet Address C and click Next.
      * Review Details, click Submit and execute the transaction.

   This will assign all usecases or all /minting allowlist spots for Addresses A, B, and C to Address C, that can mint on behalf of all three. Address B can continue to manage delegations for Address A.

3. \[To confirm] Connect to NFTDelegation.com with Address C (minting)&#x20;
   1. Click on My Activity.
   2. Select Any Collection from the My Collections Tab.
   3. In the Delegations Area you should view the two delegation addresses in the Delegations area: one for wallet A and one for wallet B.


# How to Register Consolidations (TAP)?

Consolidations are distinct from delegations and are used to establish an on-chain message to treat two or more addresses as one.

This allows for a unified view of your NFTs in on-site galleries and for any allowlist calculations.

Assuming three sample addresses:

* Address A (vault address) : 0xAcf42B85eCb77d9332584119FD78a3DE9953c2a0
* Address B (transaction address) : 0x3558C942EeA9e9Bb9b1a6A02d272756EDD3A1Fe4
* Address C (minting address) : 0xD0f03CB42Fe821c0654846E474c19484865c5B4a

Below is a process that assumes you already have TAP and have granted Delegation Management (Sub-delegation) rights from your vault to your transaction wallet.

**Using Address B:**

1. Set a consolidation with Address A:
   * Launch the Wallet Wizard.
   * Select Consolidate Wallets and click Next.
   * Select Connected wallet as the Delegator.
   * Select a specific Collection or choose Any Collection and click Next.
   * Enter the wallet Address A and click Next.
   * Review Details, click Submit and execute the transaction.
2. Set a consolidation with Address C:
   * Follow the same steps as above and enter wallet Address C.
3. Set a consolidation on behalf of Address A with Address B (requires Delegation Management (Sub-delegation) from wallet A to wallet B):
   * Launch the Wallet Wizard.
   * Select Consolidate Wallets and click Next.
   * Select Address A as the Delegator.
   * Select a specific Collection or choose Any Collection and click Next.
   * Enter the wallet Address B and click Next.
   * Review Details, click Submit and execute the transaction.
4. Set a consolidation on behalf of Address A with Address C (requires Delegation Management (Sub-delegation) from wallet A to wallet B):
   * Follow the same steps as above and enter wallet Address C.

**Using Address C:**

1. Set a consolidation with Address A:
   * Launch the Wallet Wizard.
   * Select Consolidate Wallets and click Next.
   * Select a specific Collection or choose Any Collection and click Next.
   * Enter the wallet Address A and click Next.
   * Review Details, click Submit and execute the transaction.
2. Set a consolidation with Address B:
   * Follow the same steps as above and enter wallet Address B.
3. \[To confirm] Connect to NFTDelegation.com with Address C (minting)&#x20;
   1. Click on My Activity.
   2. Select Any Collection from the My Collections Tab.
   3. In the Consolidations Area check the consolidation status.

**Notes:**

* More than three addresses can have consolidations.


# General Info

The Developer Center guides you on how to incorporate the NFTDelegation smart contract into your upcoming or existing project, ensuring that users can maintain their security while utilizing your service.

Please note that this section requires basic solidity knowledge into how your mint/claim contract works.


# Contract Addresses

NFTDelegation is currently deployed on the Mainnet and Testnet Blockchain networks mentioned below:

#### Mainnet Deployments

| Network    | Deployer               | Contract Address                                                                                                                                                 |
| ---------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ethereum   | 0x707e25f...C74bc6eE8F | <p><a href="https://etherscan.io/address/0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d">0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d</a><br></p>                      |
| Polygon    | 0x707e25f...C74bc6eE8F | <p><a href="https://polygonscan.com/address/0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d">0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d</a><br></p>                   |
| Binance SC | 0x707e25f...C74bc6eE8F | <p><a href="https://bscscan.com/address/0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d">0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d</a><br></p>                       |
| Avalanche  | 0x707e25f...C74bc6eE8F | <p><a href="https://snowtrace.io/address/0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d">0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d</a><br></p>                      |
| Klaytn     | 0x707e25f...C74bc6eE8F | <p><a href="https://scope.klaytn.com/account/0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d?tabId=internalTx">0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d</a><br></p> |
| Arbitrum   | 0x707e25f...C74bc6eE8F | <p><a href="https://arbiscan.io/address/0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d">0x2202cb9c00487e7e8ef21e6d8e914b32e709f43d</a><br></p>                       |

#### Testnet Deployments

| Network | Deployer               | Contract Address                                                                                                                                    |
| ------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Sepolia | 0xAcf42B8...DE9953c2a0 | <p><a href="https://sepolia.etherscan.io/address/0x8f86c644f845A077999939C69Bc787662377d915">0x8f86c644f845A077999939C69Bc787662377d915</a><br></p> |
| Goerli  | 0xAcf42B8...DE9953c2a0 | <p><a href="https://goerli.etherscan.io/address/0xad024eed08190285edb7100c9caabe79d48e448b">0xAD024eeD08190285Edb7100c9Caabe79d48e448B</a><br></p>  |


# Getter Functions

This page provides an overview on how the getter functions of the NFTDelegation smart contract work.

#### Main Retrieve functions

#### How to retrieve all delegation addresses delegated from a Delegator on a specific use case on a collection?

Purpose: The retrieveDelegationAddresses() function retrieves all delegation addresses (active & inactive) assigned by a delegator on a specific use case on a specific collection.

Description: The function takes three parameters: \_delegatorAddress, \_collectionAddress and \_useCase. The \_delegatorAddress parameter is the address of the delegator. The \_collectionAddress parameter is the address of the collection for which the delegation addresses will be retrieved. The \_useCase parameter is the type of delegation for which all delegation addresses will be returned. This function returns an address array that includes all delegation addresses delegated from a delegator on a specific usecase on a specific collection.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve all delegation addresses delegated from a delegator.
  * @param _delegatorAddress The delegator address.
  * @param _collectionAddress The address of a specific collection.
  * @param _useCase The type of delegation.
  * @return an array with all delegation addresses.
*/

function retrieveDelegationAddresses(
  address _delegatorAddress,
  address _collectionAddress,
  uint8 _useCase
) public view returns (address[]) {
  return delegationAddresses;
}
```

{% endcode %}

#### How to retrieve all delegators who gave delegation rights to a delegation Address on a specific use case on a collection?

Purpose: The retrieveDelegators() function retrieves all delegators addresses (active & inactive) who gave delegation rights to a delegation Address on a specific use case on a specific collection

Description: The function takes three parameters: \_delegationAddress, \_collectionAddress and \_useCase. The \_delegationAddress parameter is the address for which a delegator gave delegation rights. The \_collectionAddress parameter is the address of the collection for which the delegators' addresses will be retrieved. The \_useCase parameter is the type of delegation for which all delegators' addresses will be returned. This function returns an address array that includes all delegators' addresses who gave delegation rights to a delegation address on a specific usecase on a specific collection.

```
/**
  * @dev Retrieve all delegators' addresses who gave delegation rights.
  * @param _delegationAddress The delegation address for which all delegators will be returned.
  * @param _collectionAddress The address of a specific collection.
  * @param _useCase The type of delegation.
  * @return an array with all delegators' addresses.
*/

function retrieveDelegators(
  address _delegationAddress,
  address _collectionAddress,
  uint8 _useCase
) public view returns (address[]) {
  return delegatorsAddresses;
}
```

#### How to check if a delegation exists given a delegator address?

Purpose: The retrieveDelegatorStatusOfDelegation() function retrieves the status of a delegation given a delegator address.

Description: The function takes three parameters: \_delegatorAddress, \_collectionAddress and \_useCase. The \_delegatorAddress parameter is the address of the delegator. The \_collectionAddress parameter is the address of the collection for which the status will be returned. The \_useCase parameter is the type of delegation for which the delegation status will be returned. This function returns a boolean value indicating whether a delegation on a specific use case on a specific collection exists or not, if true it means that the delegator registered a delegation address on a specific use case on a specific collection.

```
/**
  * @dev Retrieve the delegation status given a delegator address.
  * @param _delegatorAddress The delegator address.
  * @param _collectionAddress The address of a specific collection.
  * @param _useCase The type of delegation.
  * @return true if delegation exists, false otherwise.
*/

function retrieveDelegatorStatusOfDelegation(
  address _delegatorAddress,
  address _collectionAddress,
  uint8 _useCase
) public view returns (bool) {
  return true/false;
}
```

#### How to check if a delegation exists given a delegation address?

Purpose: The retrieveDelegationAddressStatusOfDelegation() function retrieves the status of a delegation given a delegation address.

Description: The function takes three parameters: \_delegationAddress, \_collectionAddress and \_useCase. The \_delegationAddress parameter is the address for which a delegation was registered. The \_collectionAddress parameter is the address of the collection for which the status will be returned. The \_useCase parameter is the type of delegation for which the delegation status will be returned. This function returns a boolean value indicating whether a delegation on a specific use case on a specific collection exists or not, if true it means that a delegator registered the given delegation address on a specific use case on a specific collection.

```
/**
  * @dev Retrieve the delegation status given a delegation address.
  * @param _delegationAddress The delegation address.
  * @param _collectionAddress The address of a specific collection.
  * @param _useCase The type of delegation.
  * @return true if delegation exists, false otherwise.
*/

function retrieveDelegationAddressStatusOfDelegation(
  address _delegationAddress,
  address _collectionAddress,
  uint8 _useCase
) public view returns (bool) {
  return true/false;
}
```

#### How to check if a delegation exists given a delegator address and a delegation address??

Purpose: The retrieveGlobalStatusOfDelegation() function retrieves the status of a delegation given both the address of the delegator and the delegation address.

Description: The function takes four parameters: \_delegatorAddress, \_delegationAddress, \_collectionAddress and \_useCase. The \_delegatorAddress parameter is the address of the delegator. The \_delegationAddress parameter is the address for which a delegation was registered. The \_collectionAddress parameter is the address of the collection for which the status will be returned. The \_useCase parameter is the type of delegation for which the delegation status will be returned. This function returns a boolean value indicating whether a delegation on a specific use case on a specific collection exists or not, if true it means that a delegator registered the given delegation address on a specific use case on a specific collection.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve the delegation status given a delegator address and a delegation address.
  * @param _delegatorAddress The delegator address.
  * @param _collectionAddress The address of a specific collection.
  * @param _delegationAddress The delegation address.
  * @param _useCase The type of delegation.
  * @return true if delegation exists, false otherwise.
*/

function retrieveGlobalStatusOfDelegation(
  address _delegatorAddress  
  address _collectionAddress,
  address _delegationAddress,
  uint8 _useCase
) public view returns (bool) {
  return true/false;
}
```

{% endcode %}

#### How to retrieve the most recent delegation address delegated from a Delegator on a specific use case on a collection?

Purpose: The retrieveMostRecentDelegation() function retrieves the most recent delegation addresses assigned by a delegator on a specific use case on a specific collection.

Description: The function takes three parameters: \_delegatorAddress, \_collectionAddress and \_useCase. The \_delegatorAddress parameter is the address of the delegator. The \_collectionAddress parameter is the address of the collection for which the most recent delegation address will be retrieved. The \_useCase parameter is the type of delegation for which the most recent delegation address will be returned. This function returns the most recent address delegated from a delegator on a specific usecase on a specific collection.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve the most recent delegation address delegated from a delegator.
  * @param _delegatorAddress The delegator address.
  * @param _collectionAddress The address of a specific collection.
  * @param _useCase The type of delegation.
  * @return the most recent delegation address.
*/

function retrieveMostRecentDelegation(
  address _delegatorAddress,
  address _collectionAddress,
  uint8 _useCase
) public view returns (address) {
  return delegationAddress;
}
```

{% endcode %}

#### How to retrieve the most recent delegator who gave delegation rights to a delegation Address on a specific use case on a collection?

Purpose: The retrieveMostRecentDelegator() function retrieves most recent delegator who gave delegation rights to a delegation Address on a specific use case on a specific collection

Description: The function takes three parameters: \_delegationAddress, \_collectionAddress and \_useCase. The \_delegationAddress parameter is the address for which a delegator gave delegation rights. The \_collectionAddress parameter is the address of the collection for which the delegators' addresses will be retrieved. The \_useCase parameter is the type of delegation for which all delegators' addresses will be returned. This function returns the most recent delegator address who gave delegation rights to a delegation address on a specific usecase on a specific collection.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve the most recent delegator address.
  * @param _delegationAddress The delegation address for which the most recent delegator will be returned.
  * @param _collectionAddress The address of a specific collection.
  * @param _useCase The type of delegation.
  * @return the most recent delegator address.
*/

function retrieveMostRecentDelegator(
  address _delegationAddress,
  address _collectionAddress,
  uint8 _useCase
) public view returns (address) {
  return delegatorsAddress;
}
```

{% endcode %}

#### How to retrieve the active delegation addresses delegated from a Delegator on a specific use case on a collection?

Purpose: The retrieveActiveDelegations() function retrieves the active delegation addresses assigned by a delegator on a specific use case on a specific collection.

Description: The function takes four parameters: \_delegatorAddress, \_collectionAddress, \_date and \_useCase. The \_delegatorAddress parameter is the address of the delegator. The \_collectionAddress parameter is the address of the collection for which the active delegation addresses will be retrieved. The \_date parameter is the epoch time value for which the active delegation addresses will be retrieved, \_date compares its value against the \_expiryDate that was given when a delegation was registered. The \_useCase parameter is the type of delegation for which all delegation addresses will be returned. This function returns an address array that includes the active delegation addresses delegated from a delegator on a specific usecase on a specific collection.

```
/**
  * @dev Retrieve the active delegation addresses delegated from a delegator.
  * @param _delegatorAddress The delegator address.
  * @param _collectionAddress The address of a specific collection.
  * @param _date The epoch time value of a given date.
  * @param _useCase The type of delegation.
  * @return an array with all delegation addresses.
*/

function retrieveActiveDelegations(
  address _delegatorAddress,
  address _collectionAddress,
  uint256 _date,
  uint8 _useCase
) public view returns (address[]) {
  return delegationAddresses;
}
```

#### How to retrieve the active delegators who gave delegation rights to a delegation Address on a specific use case on a collection?

Purpose: The retrieveActiveDelegators() function retrieves the active delegators addresses who gave delegation rights to a delegation Address on a specific use case on a specific collection

Description: The function takes four parameters: \_delegationAddress, \_collectionAddress, \_date and \_useCase. The \_delegationAddress parameter is the address for which a delegator gave delegation rights. The \_collectionAddress parameter is the address of the collection for which the delegators' addresses will be retrieved. The \_date parameter is the epoch time value for which the active delegators' addresses will be retrieved, \_date compares its value against the \_expiryDate that was given when a delegation was registered. The \_useCase parameter is the type of delegation for which all delegators' addresses will be returned. This function returns an address array that includes the active delegators' addresses who gave delegation rights to a delegation address on a specific usecase on a specific collection.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve the active delegators' addresses who gave delegation rights.
  * @param _delegationAddress The delegation address for which all delegators will be returned.
  * @param _collectionAddress The address of a specific collection.
  * @param _date The epoch time value of a given date.
  * @param _useCase The type of delegation.
  * @return an array with all delegators' addresses.
*/

function retrieveActiveDelegators(
  address _delegationAddress,
  address _collectionAddress,
  uint256 _date,
  uint8 _useCase
) public view returns (address[]) {
  return delegatorsAddresses;
}
```

{% endcode %}

#### How to check if a delegator gave sub-delegation rights to a delegation address on a collection?

Purpose: The retrieveSubDelegationStatus() function retrieves the sub-delegation rights status between a delegator and a delegation address.

Description: The function takes three parameters: \_delegatorAddress, \_collectionAddress and \_delegationAddress. The \_delegatorAddress parameter is the address of the delegator. The \_collectionAddress parameter is the address of the collection for which sub-delegation rights were given from a delegator to a delegation address. The \_delegationAddress parameter is the address for which the delegator gave sub-delegation rights. This function returns a boolean value indicating whether sub-delegation rights were given from the delegator to the delegation address.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve sub-delegation rights status between a delegator and a delegation address.
  * @param _delegatorAddress The delegator address.
  * @param _collectionAddress The address of a specific collection.
  * @param _delegationAddress The delegation address.
  * @return true if the delegator gave sub-delegation rights to the delegation address.
*/

function retrieveSubDelegationStatus(
  address _delegatorAddress,
  address _collectionAddress,
  address _delegationAddress
) public view returns (bool) {
  return true/false;
}
```

{% endcode %}

#### How to check the consolidation status/relationship between two addresses on a collection?

Purpose: The checkConsolidationStatus() function retrieves consolidation status/relationship between two addresses that may exist on a collection.

Description: The function takes three parameters: \_wallet1, \_wallet2 and \_collectionAddress. The \_wallet1 and \_wallet2 parameters can either be a delegator address, a delegation address or any other address. The \_collectionAddress parameter is the address of the collection for which consolidation status/relationship may exist between the two addresses. This function returns a boolean value indicating whether a consolidation status/relationship exists between the two given addresses.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve the consolidation status/relationship between two addresses.
  * @param _wallet1 The delegator/delegation/other address.
  * @param _wallet2 The delegator/delegation/other address.
  * @param _collectionAddress The address of a specific collection.
  * @return true if consolidation status/relationship exists between the two given addresses.
*/

function checkConsolidationStatus(
  address _wallet1,
  address _wallet2,
  address _collectionAddress
) public view returns (bool) {
  return true/false;
}
```

{% endcode %}

#### Other Retrieve Functions

#### How to retrieve all data about a delegator address for a specific usecase on a collection?

Purpose: The retrieveDelegationAddressesTokensIDsandExpiredDates() function retrieves for a specific use case on a specific collection, the delegation addresses, token IDs, expiry dates and if the delegator assigned all tokens owned or a specific token when codnucting a delegation.

Description: The function takes three parameters: \_delegatorAddress, \_collectionAddress and \_useCase. The \_delegatorAddress parameter is the address of the delegator. The \_collectionAddress parameter is the address of the collection for which full data will be retrieved. The \_useCase parameter is the type of delegation for which full data will be returned. This function returns an address array that includes all delegation addresses delegated from a delegator on a specific usecase on a specific collection, a uint array that includes the token ids that were registered, a bool array that indicates if all tokens owned by the delegator were assigned during the registration or just a specific token id and a uint array that includes expiry dates of each delegation.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve full data about a delegator.
  * @param _delegatorAddress The delegator address for which full data will be returned.
  * @param _collectionAddress The address of a specific collection.
  * @param _useCase The type of delegation.
  * @return an array with all delegation addresses, an array with the token ids registered, an array that indicates if the delegator delegated all tokens owned or a specific token and an array with the expiry dates of each delegation.
*/

function retrieveDelegationAddressesTokensIDsandExpiredDates(
  address _delegatorAddress,
  address _collectionAddress,
  uint8 _useCase
) public view returns (address[], uint256[], bool[], uint256[]) {
  return delegationAddresses, allExpirations, allTokens, tokenIDs;
}
```

{% endcode %}

#### How to retrieve all data about a delegation address for a specific usecase on a collection?

Purpose: The retrieveDelegatorsTokensIDsandExpiredDates() function retrieves for a specific use case on a specific collection, the delegators' addresses, token IDs, expiry dates and if the delegator assigned all tokens owned or a specific token when codnucting a delegation.

Description: The function takes three parameters: \_delegationAddress, \_collectionAddress and \_useCase. The \_delegationAddress parameter is the address for which full data will be retrieved. The \_collectionAddress parameter is the address of the collection for which full data will be retrieved. The \_useCase parameter is the type of delegation for which full data will be returned. This function returns an address array that includes all delegators' addresses who gave delegation rights to a delegation address on a specific usecase on a specific collection, a uint array that includes the token ids that were registered, a bool array that indicates if all tokens owned by the delegator were assigned during the registration or just a specific token id and a uint array that includes expiry dates of each delegation.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve full data about a delegation address.
  * @param _delegationAddress The delegation address for which full data will be returned.
  * @param _collectionAddress The address of a specific collection.
  * @param _useCase The type of delegation.
  * @return an array with all delegators' addresses, an array with the token ids registered, an array that indicates if the delegator delegated all tokens owned or a specific token and an array with the expiry dates of each delegation.
*/

function retrieveDelegatorsTokensIDsandExpiredDates(
  address _delegationAddress,
  address _collectionAddress,
  uint8 _useCase
) public view returns (address[], uint256[], bool[], uint256[]) {
  return delegatorsAddresses, allExpirations, allTokens, tokenIDs;
}
```

{% endcode %}

#### How to check the delegation status given a specific token id?

Purpose: The retrieveTokenStatus() function retrieves the status of a delegation given a specific token id.

Description: The function takes five parameters: \_delegatorAddress, \_collectionAddress, \_delegationAddress, \_useCase and \_tokenid. The \_delegatorAddress parameter is the address that registered a delegation using a specific token id of a collection. The \_delegatorAddress must match the token owner address of that specific token id within the collection. The \_collectionAddress parameter is the address of the collection for which delegation rights were given. The \_delegationAddress parameter is the address for which delegation rights were given on that specific token id. The \_useCase parameter is the type of delegation. This function returns a boolean value indicating whether delegation rights were given for the specific token id by the token owner.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve the delegation status given a specific token id.
  * @param _delegatorAddress The delegator/token owner address.
  * @param _collectionAddress The address of a specific collection.
  * @param _delegationAddress The delegation address for which full data will be returned.
  * @param _useCase The type of delegation.
  * @param _tokenid The unique token id.
  * @return true if the delegation rights were given by the token owner of the specific token id.
*/

function retrieveTokenStatus(
  address _delegatorAddress,
  address _collectionAddress,
  address _delegationAddress,
  uint8 _useCase,
  uint256 _tokenid
) public view returns (bool) {
  return true/false;
}
```

{% endcode %}

#### How to retrieve the global lock status that exists on a delegation address?

Purpose: The retrieveGlobalLockStatus() function retrieves the global lock status of a delegation Address.

Description: The function takes one parameter: \_delegationAddress. The \_delegationAddress parameter is the address for which the global lock status will be returned. This function returns a boolean value indicating whether the global lock is enabled or not, if true it means that the \_delegationAddress is locked and cannot be registered in any other usecase or collection.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve the global lock status of a delegation address.
  * @param _delegationAddress The delegation address.
  * @return true if the global lock is enabled, false otherwise.
*/

function retrieveGlobalLockStatus(
  address _delegationAddress
) public view returns (bool) {
  return globalLock;
}
```

{% endcode %}

#### How to retrieve the collection lock status that exists on a delegation address?

Purpose: The retrieveCollectionLockStatus() function retrieves the collection lock status of a delegation Address.

Description: The function takes two parameters: \_collectionAddress and \_delegationAddress. The \_collectionAddress parameter is the address of the collection for which the collection lock status of a delegation Address will be retrieved. The \_delegationAddress parameter is the address for which the collection lock status will be returned. This function returns a boolean value indicating whether the collection lock is enabled or not, if true it means that the \_delegationAddress is locked and cannot be registered within the same collection.

```
/**
  * @dev Retrieve the collection lock status of a delegation address.
  * @param _collectionAddress The address of a specific collection.
  * @param _delegationAddress The delegation address.
  * @return true if the collection lock is enabled, false otherwise.
*/

function retrieveCollectionLockStatus(
  address _collectionAddress,
  address _delegationAddress
) public view returns (bool) {
  return collectionLock;
}
```

#### How to retrieve the collection use case lock status that exists on a delegation address?

Purpose: The retrieveCollectionUseCaseLockStatus() function retrieves the collection use case lock status of a delegation Address.

Description: The function takes three parameters: \_collectionAddress, \_delegationAddress and \_useCase. The \_collectionAddress parameter is the address of the collection for which the collection use case lock status of a delegation Address will be retrieved. The \_delegationAddress parameter is the address for which the collection use case lock status will be returned. The \_useCase parameter is the type of delegation for which the collection use case status will be returned. This function returns a boolean value indicating whether the collection use case lock is enabled or not, if true it means that the \_delegationAddress is locked and cannot be registered for the same use case within the same collection.

```
/**
  * @dev Retrieve the collection use case lock status of a delegation address.
  * @param _collectionAddress The address of a specific collection.
  * @param _delegationAddress The delegation address.
  * @param _useCase The type of delegation.
  * @return true if the collection lock is enabled, false otherwise.
*/

function retrieveCollectionUseCaseLockStatus(
  address _collectionAddress,
  address _delegationAddress,
  uint8 _useCase
) public view returns (bool) {
  return collectionUsecaseLock;
}
```

#### How to check if a delegator address is active or not?

Purpose: The retrieveStatusOfActiveDelegator() function checks if a delegator address who gave delegation rights to a delegation Address on a specific use case on a specific collection is active or not.

Description: The function takes five parameters: \_delegatorAddress, \_collectionAddress, \_delegationAddress, \_date and \_useCase. The \_delegatorAddress parameter is the address of the delegator. The \_collectionAddress parameter is the address of the collection for which the status, active or inactive, of the delegator will be retrieved. The \_delegationAddress parameter is the address for which a delegator gave delegation rights. The \_date parameter is the epoch time value for which the status of the delegator address will be retrieved, \_date compares its value against the \_expiryDate that was given when a delegation was registered. The \_useCase parameter is the type of delegation for which the status of the delegator will be returned. This function returns a boolean variable that indicates if a delegator address is active or not.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve if a delegator address is active or not.
  * @param _delegatorAddress The address of delegator that will be checked.
  * @param _collectionAddress The address of a specific collection.
  * @param _delegationAddress The delegation address for which all delegators will be returned.
  * @param _date The epoch time value of a given date.
  * @param _useCase The type of delegation.
  * @return true if the delegator address is active, false otherwise.
*/

function retrieveStatusOfActiveDelegator(
  address _delegatorAddress,
  address _collectionAddress,
  address _delegationAddress,
  uint256 _date,
  uint8 _useCase
) public view returns (bool) {
  return true/false;
}
```

{% endcode %}

#### How to check if a delegation address is the most recent one delegated?

Purpose: The retrieveStatusOfMostRecentDelegation() function checks the status of a delegation address to identify if it's the most recent one delegated or not.

Description: The function takes four parameters: \_delegatorAddress, \_collectionAddress, \_delegationAddress and \_useCase. The \_delegatorAddress parameter is the address of the delegator. The \_collectionAddress parameter is the address of the collection for which the status of the most recent delegation address will be retrieved. The \_delegationAddress parameter is the address that will be checked if its the most recent delegated or not. The \_useCase parameter is the type of delegation for which the status of the delegation Address will be returned. This function returns a boolean variable that indicates if a delegation address is the most rent one delegated or not.

{% code overflow="wrap" %}

```
/**
  * @dev Retrieve if a delegation address is the most recent delegated one or not.
  * @param _delegatorAddress The delegator address.
  * @param _collectionAddress The address of a specific collection.
  * @param _delegationAddress The delegation address that will be checked.
  * @param _useCase The type of delegation.
  * @return true if the delegation address is the most recent one delegated, false otherwise.
*/

function retrieveStatusOfMostRecentDelegation(
  address _delegatorAddress,
  address _collectionAddress,
  address _delegationAddress,
  uint8 _useCase
) public view returns (bool) {
  return true/false;
}
```

{% endcode %}


# Setter Functions

This page provides an overview on how the setter functions of the NFTDelegation smart contract work.

#### How to register a Delegation Address?

Purpose: The registerDelegationAddress() function registers a new delegation Address.

Description: The function takes six parameters: \_collectionAddress, \_delegationAddress, \_expiryDate, \_useCase, \_allTokens and \_tokenid. The \_collectionAddress parameter is the address of the collection that the delegation address will be registered. The \_delegationAddress parameter is the address to register. The \_expiryDate parameter sets the expiry date of the delegation, after that date the delegation is not active. The \_useCase parameter is the type of delegation to register. The \_allTokens parameter can take two statuses (true/false), if true it registers the delegation for all collection tokens owned by the delegator, if false then it refers to a specific token that is set on the \_tokenid parameter. The \_tokenid parameter is the ID of the token to register the delegation for.

Notes:

* To register a delegation Address for all collections the value of parameter \_collectionAddress should be set to 0x8888888888888888888888888888888888888888.
* To delegate for all tokens owned set the \_allTokens parameter to true, otherwise, by setting \_allTokens to false the delegation refers only to the token id set in the \_tokenid parameter

```
/**
  * @dev Registers a new delegation address.
  * @param _collectionAddress The address of a specific collection.
  * @param _delegationAddress The delegation address.
  * @param _expiryDate The expiry date of the delegation.
  * @param _useCase The type of delegation.
  * @param _allTokens Refers to all tokens owned by a delegator or a specific token.
  * @param _tokenid The ID of the token to register the delegation for. 
*/

function registerDelegationAddress(
  address _collectionAddress,
  address _delegationAddress,
  uint256 _expiryDate,
  uint8 _useCase
  bool _allTokens,
  uint256 _tokenid
) public;
```

#### How to register a Delegation Address using an address with sub-delegation rights?

Purpose: The registerDelegationAddressUsingSubDelegation() function registers a new delegation Address by taking into consideration the sub-delegation rights given by a delegator to a specific delegation Address.

Description: The function takes seven parameters: \_delegatorAddress, \_collectionAddress, \_delegationAddress, \_expiryDate, \_useCase, \_allTokens and \_tokenid. The \_delegatorAddress parameter is the address of the delegator who gave sub-delegation rights to the address that will execute this function. The \_collectionAddress parameter is the address of the collection that the delegation will be registered. The \_delegationAddress parameter is the address to register. The \_expiryDate parameter sets the expiry date of the delegation, after that date the delegation is not active. The \_useCase parameter is the type of delegation to register. The \_allTokens parameter can take two status (true/false), if true it registers the delegation for all collection tokens owned by the delegator, if false then it refers to a specific token that is set on the \_tokenid parameter. The \_tokenid parameter is the ID of the token to register the delegation for.

```
/**
  * @dev Registers a new delegation address from a hot wallet that has sub-delegation rights.
  * @param _delegatorAddress The address of the delegator who gave sub-delegation rights.
  * @param _collectionAddress The address of a specific collection.
  * @param _delegationAddress The delegation address.
  * @param _expiryDate The expiry date of the delegation.
  * @param _useCase The type of delegation.
  * @param _allTokens Refers to all tokens owned by a delegator or a specific token.
  * @param _tokenid The ID of the token to register the delegation for. 
 */

function registerDelegationAddressUsingSubDelegation(
    address _delegatorAddress,
    address _collectionAddress,
    address _delegationAddress,
    uint256 _expiryDate,
    uint8 _useCase
    bool _allTokens,
    uint256 _tokenid
) public;
```

#### How to revoke a Delegation Address?

Purpose: The revokeDelegationAddress() function revokes the delegation rights given to a delegation address on a specific use case for a specific collection.

Description: The function takes three parameters: \_collectionAddress, \_delegationAddress and \_useCase. The \_collectionAddress parameter is the address of the collection that the delegation will be revoked. The \_delegationAddress parameter is the address that will be revoked. The \_useCase parameter is the type of delegation that will be revoked.

```
  /**
    * @dev Revokes a delegation address.
    * @param _collectionAddress The address of a specific collection.
    * @param _delegationAddress The delegation address.
    * @param _expiryDate The expiry date of the delegation.
    * @param _useCase The type of delegation.
  */

  function revokeDelegationAddress(
      address _collectionAddress,
      address _delegationAddress,
      uint8 _useCase
  ) public;
```

#### How to revoke a Delegation Address using an address with sub-delegation rights?

Purpose: The revokeDelegationAddressUsingSubdelegation() function revokes the delegation rights given to a delegation address on a specific use case for a specific collection by taking into consideration the sub-delegation rights given by a delegator to a specific delegation Address.

Description: The function takes four parameters: \_delegatorAddress, \_collectionAddress, \_delegationAddress and \_useCase. The \_delegatorAddress parameter is the address of the delegator who gave sub-delegation rights to the address that will execute this function. The \_collectionAddress parameter is the address of the collection that the delegation will be revoked. The \_delegationAddress parameter is the address that will be revoked. The \_useCase parameter is the type of delegation that will be revoked.

```
  /**
    * @dev Revokes a delegation address from a delegator using sub-delegation rights.
    * @param _delegatorAddress The address of the delegator who gave sub-delegation rights.
    * @param _collectionAddress The address of a specific collection.
    * @param _delegationAddress The delegation address.
    * @param _useCase The type of delegation.
  */

  function revokeDelegationAddressUsingSubdelegation(
      address _delegatorAddress,
      address _collectionAddress,
      address _delegationAddress,
      uint8 _useCase
  ) public;
```

#### How to register multiple Delegation Addresses?

Purpose: The batchDelegations() function registers delegation rights to 1 to 5 delegation addresses on various use cases of different collections.

Description: The function takes six parameters: \_collectionAddresses\[], \_delegationAddresses\[], \_expiryDates\[], \_useCases\[], \_allTokens\[] and \_tokenids\[]. The \_collectionAddresses\[] parameter is an array that includes the collection addresses for each one of the delegation addresses that will be registered. The \_delegationAddresses\[] parameter is an array that includes the delegation addresses that will be registered for each one of the collection addresses. The \_expiryDates\[] parameter is an array that includes the expiry date for each one of the delegations. The \_useCases\[] parameter is an array that includes the type of a delegation that will be registered. The \_allTokens parameter is an array that refers to the delegated tokens of each collection. The \_tokenids\[] parameter is an array that specifies the token id assigned to a delegation.

```
  /**
    * @dev Registers 1 to 5 delegation addresses to a delegator.
    * @param _collectionAddresses[] The addresses of specific collections.
    * @param _delegationAddresses[] The delegation addresses.
    * @param _expiryDates[] The expiry date of each delegation.
    * @param _useCases[] The type of each delegation.
    * @param _allTokens[] Refers to all tokens owned by a delegator or a specific token.
    * @param _tokenids[] The ID of the token to register the delegation for. 
  */

  function batchDelegations(
      address[] _ collectionAddresses,
      address[] _ delegationAddresses,
      uint256[] _ expiryDates,
      uint8[] _useCases,
      bool[] _allTokens,
      uint256[] _tokenids
  ) public;
```

#### How to revoke multiple Delegation Addresses?

Purpose: The batchRevocations() function revokes the delegation rights given to 1 to 5 delegation addresses on various use cases of different collections.

Description: The function takes three parameters: \_collectionAddresses\[], \_delegationAddresses\[] and \_useCases\[]. The \_collectionAddresses parameter is an array that includes the collection addresses for each one of the delegation addresses that will be revoked. The \_delegationAddresses parameter is an array that includes the delegation addresses for each one of the collection addresses that will be revoked. The \_useCases parameter is an array that includes the types of delegations that will be revoked.

```
  /**
    * @dev Revokes 1 to 5 delegation addresses from a delegator.
    * @param _collectionAddresses[] The addresses of specific collections.
    * @param _delegationAddresses[] The delegation addresses.
    * @param _ useCases[] The types of delegations.
  */

  function batchRevocations(
      address[] _ collectionAddresses,
      address[] _ delegationAddresses,
      uint8[] _ useCases
  ) public;
```

#### How to update a Delegation Address?

Purpose: The updateDelegationAddress() function updates a delegation Address.

Description: The function takes seven parameters: \_collectionAddress, \_olddelegationAddress, \_newdelegationAddress, \_expiryDate, \_useCase, \_allTokens and \_tokenid. The \_collectionAddress parameter is the address of the collection that the new delegation will be registered. The \_olddelegationAddress parameter is the address that will be removed. The \_newdelegationAddress parameter is the address to register. The \_expiryDate parameter sets the expiry date of the delegation, after that date the delegation is not active. The \_useCase parameter is the type of delegation to register. The \_allTokens parameter can take two statuses (true/false), if true it registers the delegation for all collection tokens owned by the delegator, otherwise, if false then it refers to a specific token that is set on the \_tokenid parameter. The \_tokenid parameter is the ID of the token to register the delegation for.

```
  /**
    * @dev Updates a delegation address.
    * @param _collectionAddress The address of a specific collection.
    * @param _olddelegationAddress The previous delegation address.
    * @param _newdelegationAddress The new delegation address.
    * @param _expiryDate The expiry date of the delegation.
    * @param _useCase The type of delegation.
    * @param _allTokens Refers to all tokens owned by a delegator or a specific token.
    * @param _tokenid The ID of the token to register the new delegation for.
  */

  function updateDelegationAddress(
      address _collectionAddress,
      address _olddelegationAddress,
      address _newdelegationAddress,
      uint256 _expiryDate,
      uint8 _useCase
      bool _allTokens,
      uint256 _tokenid
  ) public;
```

#### How to globally lock my hot wallet?

Purpose: The setGlobalLock() function locks the wallet address that executes the transaction to prevent any delegation registration of it on any use case on any collection.

Description: The function takes one parameter: \_status. The \_status parameter is a bool value (true/false), if \_status = true the wallet address locks itself, if \_status = false the wallet address unlocks.

```
  /**
    * @dev Locks a wallet address globally.
    * @param _status The lock status of the wallet address.
  */

  function setGlobalLock(
      bool _status
  ) public;
```

#### How to lock my hot wallet on a collection?

Purpose: The setCollectionLock() function locks the wallet address that executes the transaction to prevent any registration of it on a specific collection.

Description: The function takes two parameters: \_collectionAddress and \_status. The \_collectionAddress parameter is the address of the collection that the wallet address will be locked/unlocked. The \_status parameter is a bool value (true/false), if \_status = true the wallet address locks itself, if \_status = false the wallet address unlocks.

```
  /**
    * @dev Locks a wallet address on a specific collection.
    * @param _collectionAddress The address of a specific collection.
    * @param _status The lock status of the wallet address.
  */

  function setCollectionLock(
      address _collectionAddress,
      bool _status
  ) public;
```

#### How to lock my hot wallet on a specific usecase on a collection?

Purpose: The setCollectionUsecaseLock() function locks the wallet address that executes the transaction to prevent any registration of it on a specific usecase on a specific collection.

Description: The function takes three parameters: \_collectionAddress, \_useCase and \_status. The \_collectionAddress parameter is the address of the collection that the wallet address will be locked/unlocked. The \_useCase parameter is the type for which the wallet address will be locked/unlocked. The \_status parameter is a bool value (true/false), if \_status = true the wallet address locks itself, if \_status = false the wallet address unlocks.

```
  /**
    * @dev Locks a wallet address on a specific usecase on a specific collection.
    * @param _collectionAddress The address of a specific collection.
    * @param _useCase The type for which the wallet address will be locked/unlocked.
    * @param _status The lock status of the wallet address.
  */

  function setCollectionUsecaseLock(
      address _collectionAddress,
      uint8 _useCase,
      bool _status
  ) public;
```


# INFTDelegationRead.sol

This page provides the solidity Interface for all Getter functions (Read functions) of the NFTDelegation.com Smart Contract.

{% tabs %}
{% tab title="Code" %}
{% code overflow="wrap" %}

```
//SPDX-License-Identifier: MIT

/**
 * @dev Interface for all Getter functions (Read functions) of the NFTDelegation.com Smart Contract
 */

pragma solidity ^0.8.18;

interface INFTDelegationRead {
    
    /**
     * @notice This function returns an array of all delegation addresses (active AND inactive) assigned by a delegator for a specific use case on a specific NFT collection
     */

    function retrieveDelegationAddresses(address _delegatorAddress, address _collectionAddress, uint256 _useCase) external view returns (address[] memory);
    
    /**
     * @notice This function returns an array of all delegators (active AND inactive) that delegated to a delegationAddress for a specific use case on a specific NFT collection
     */

     function retrieveDelegators(address _delegationAddress, address _collectionAddress, uint256 _useCase) external view returns (address[] memory);

     /**
     * @notice This function returns the most recent delegation address delegated on a specific use case on a specific NFT collection
     */

    function retrieveMostRecentDelegation(address _delegatorAddress, address _collectionAddress, uint256 _useCase) external view returns (address);

    /**
     * @notice This function returns the most recent delegator on a specific use case on a specific NFT collection for a delegation Address
     */

    function retrieveMostRecentDelegator(address _delegationAddress, address _collectionAddress, uint256 _useCase) external view returns (address);

    /**
     * @notice This function returns the status of a delegation for a delegator address and a delegation address
     */

    function retrieveGlobalStatusOfDelegation(address _delegatorAddress, address _collectionAddress, address _delegationAddress, uint256 _useCase) external view returns (bool);

    /**
     * @notice This function returns the status of a delegation given the delegator address, the collection address, the delegation address as well as a specific token id
     */

    function retrieveTokenStatus(address _delegatorAddress, address _collectionAddress, address _delegationAddress, uint256 _useCase, uint256 _tokenId) external view returns (bool);

    /**
     * @notice This function checks if the delegation address performing actions is the most recent delegated by the specific delegator
     */

    function retrieveStatusOfMostRecentDelegation(address _delegatorAddress, address _collectionAddress, address _delegationAddress, uint256 _useCase) external view returns (bool);

     /**
     * @notice This function checks if a delegator granted subdelegation status to an Address
     */

    function retrieveSubDelegationStatus(address _delegatorAddress, address _collectionAddress, address _delegationAddress) external view returns (bool);

     /**
     * @notice This function checks the status of an active delegator for a delegation Address
     */

    function retrieveStatusOfActiveDelegator(address _delegatorAddress, address _collectionAddress, address _delegationAddress, uint256 _date, uint256 _useCase) external view returns (bool);

    /**
     * @notice This function checks the Consolidation status between 2 addresses
     */

    function checkConsolidationStatus(address _wallet1, address _wallet2, address _collectionAddress) external view returns (bool);

    /**
     * @notice This function returns the Global Lock Status of an address
     */

    function retrieveGlobalLockStatus(address _delegationAddress) external view returns (bool);

    /**
     * @notice This function returns the Collection Lock Status of an address
     */

    function retrieveCollectionLockStatus(address _collectionAddress, address _delegationAddress) external view returns (bool);

    /**
     * @notice This function returns the Collection Use Case Lock Status of an address
     */

    function retrieveCollectionUseCaseLockStatus(address _collectionAddress, address _delegationAddress, uint256 _useCase) external view returns (bool);

    /**
     * @notice This function returns the status of a collection/delegation for a delegator
     */

    function retrieveDelegatorStatusOfDelegation(address _delegatorAddress, address _collectionAddress, uint256 _useCase) external view returns (bool);

    /**
     * @notice This function returns the status of a collection/delegation for a delegation address (hot wallet)
     */

    function retrieveDelegationAddressStatusOfDelegation(address _delegationAddress, address _collectionAddress, uint256 _useCase) external view returns (bool);

    /**
     * @notice This function returns all delegation addresses, expiry dates of delegations, if the delegations refer to all tokens and tokensids for a delegator address
     */

    function retrieveDelegationAddressesTokensIDsandExpiredDates(address _delegatorAddress, address _collectionAddress, uint256 _useCase) external view returns (address[] memory, uint256[] memory, bool[] memory, uint256[] memory);

    /**
     * @notice This function returns an array of all active delegation addresses on a certain date for a specific use case on a specific NFT collection for a delegator address
     */

    function retrieveActiveDelegations(address _delegatorAddress, address _collectionAddress, uint256 _date, uint256 _useCase) external view returns (address[] memory);

    /**
     * @notice This function returns all delegator addresses, expiry dates of delegations, if the delegations refer to all tokens and tokensids for a delegator address
     */

    function retrieveDelegatorsTokensIDsandExpiredDates(address _delegationAddress, address _collectionAddress, uint256 _useCase) external view returns (address[] memory, uint256[] memory, bool[] memory, uint256[] memory);

    /**
     * @notice This function returns an array of all active delegators on a certain date for a specific use case on a specific NFT collection for a delegation address
     */

    function retrieveActiveDelegators(address _delegationAddress, address _collectionAddress, uint256 _date, uint256 _useCase) external view returns (address[] memory);

}
```

{% endcode %}
{% endtab %}
{% endtabs %}


# INFTDelegationWrite.sol

This page provides the solidity Interface for all Setter functions (Write functions) of the NFTDelegation.com Smart Contract.

{% tabs %}
{% tab title="Code" %}
{% code overflow="wrap" %}

```
//SPDX-License-Identifier: MIT

/**
 * @dev Interface for all Setter functions (Write functions) of the NFTDelegation.com Smart Contract
 */

pragma solidity ^0.8.18;

interface INFTDelegationWrite {

    /**
     * @notice This function allows a Delegator to register a delegation address on a specific usecase on a certain collection
     */

    function registerDelegationAddress(address _collectionAddress, address _delegationAddress, uint256 _expiryDate, uint256 _useCase, bool _allTokens, uint256 _tokenId) external;

    /**
     * @notice This function allows a wallet address that has sub-delegation rights to register a delegation address on a specific usecase on a certain collection on behalf of a delegator
     */

    function registerDelegationAddressUsingSubDelegation(address _delegatorAddress, address _collectionAddress, address _delegationAddress, uint256 _expiryDate, uint256 _useCase, bool _allTokens, uint256 _tokenId) external;

    /**
     * @notice This function allows a Delegator to revoke a delegation address from a specific usecase for a certain collection
     */

    function revokeDelegationAddress(address _collectionAddress, address _delegationAddress, uint256 _useCase) external;

    /**
     * @notice This function allows a wallet address that has sub-delegation rights to revoke a delegation address from a specific usecase for a certain collection on behalf of a delegator
     */

    function revokeDelegationAddressUsingSubdelegation(address _delegatorAddress, address _collectionAddress, address _delegationAddress, uint256 _useCase) external;

    /**
     * @notice This function allows a Delegator to update a delegation address, already registered, on a specific use case on a certain collection
     */

    function updateDelegationAddress(address _collectionAddress, address _olddelegationAddress, address _newdelegationAddress, uint256 _expiryDate, uint256 _useCase, bool _allTokens, uint256 _tokenId) external;

    /**
     * @notice This function allows a Delegator to register up to 5 delegation addresses on various usecases on various collections
     */

    function batchDelegations(address[] memory _collectionAddresses, address[] memory _delegationAddresses, uint256[] memory _expiryDates, uint256[] memory _useCases, bool[] memory _allTokens, uint256[] memory _tokenIds) external;
    
    /**
     * @notice This function allows a Delegator to revoke up to 5 delegation addresses
     */

    function batchRevocations(address[] memory _collectionAddresses, address[] memory _delegationAddresses, uint256[] memory _useCases) external;

    /**
     * @notice This function allows a wallet address to be locked globally
     */

    function setGlobalLock(bool _status) external;

    /**
     * @notice This function allows a wallet address to be locked on a collection
     */

    function setCollectionLock(address _collectionAddress, bool _status) external;

    /**
     * @notice This function allows a wallet address to be locked on a specific use case on a collection
     */

    function setCollectionUsecaseLock(address _collectionAddress, uint256 _useCase, bool _status) external;

    /**
     * @notice This function allows a wallet address to update the number of use cases
     */

    function updateUseCaseCounter() external;

}
```

{% endcode %}
{% endtab %}
{% endtabs %}


# NFTDelegation Integrations

{% content-ref url="/pages/iHdJZdro1Y7veqjMiw45" %}
[Retrieve Calls](/developer-center/nftdelegation-integrations/retrieve-calls)
{% endcontent-ref %}

{% content-ref url="/pages/ZoB9jW1FyqaORCXOQ1cG" %}
[ERC721 Integration](/developer-center/nftdelegation-integrations/erc721-integration)
{% endcontent-ref %}


# Retrieve Calls

This page demonstrates how the NFTDelegation.com smart contract can be integrated to make external calls.

Steps:

1. Import Interfaces within your smart contract

```
import "./INFTDelegationRead.sol";
```

2. Declare the Read Interface variable as below:

```
INFTDelegationRead public dmcRead;
```

3. Modify your constructor as below. When deploying the smart contract input the NFTDelegation smart contract address 0x2202CB9c00487e7e8EF21e6d8E914B32e709f43d within your constructor.

```
constructor(address _NFTdelegationManagementContract) {
    dmcRead = INFTDelegationRead(_NFTdelegationManagementContract);
}
```

4. Add function calls

The retrieveDelegators() function returns an array of Delegators for the function caller address (msg.sender) based on 'Any Collection' and 'All Use Cases'.&#x20;

{% code overflow="wrap" %}

```
function retrieveDelegators() public view returns(address[] memory) {
    return dmcRead.retrieveDelegators(msg.sender, 0x8888888888888888888888888888888888888888, 1);
}
```

{% endcode %}

The checkMintingStatus(\_vault) function checks the minting eligibility status for the function caller (msg.sender) by providing a Delegator's address as an input. This function is based on 'Any Collection' and 'Minting Use Case #2' and returns a bool status (true/false).&#x20;

{% code overflow="wrap" %}

```
function checkMintingStatus(address _vault) public view returns(bool) {
    return dmcRead.retrieveGlobalStatusOfDelegation(_vault, 0x8888888888888888888888888888888888888888, msg.sender, 2);
}
```

{% endcode %}

The retrieveTokenStatus(\_vault, \_tokenid) function checks if a delegation was registered from the a Delegator to the function caller (msg.sender) for an individual token id on a specific usecase on a specific collection and returns a bool status (true/false).&#x20;

{% code overflow="wrap" %}

```
function retrieveTokenStatus(address _vault, uint256 _tokenid) public view returns(bool) {
    return dmcRead.retrieveTokenStatus(_vault,         0x33fd426905f149f8376e227d0c9d3340aad17af1, msg.sender, 1, _tokenid);
}
```

{% endcode %}

Please note that you can customize the demo functions for the collection or usecase that you are interested in.

**Full Source Code**

{% tabs %}
{% tab title="Code" %}
{% code overflow="wrap" %}

```
// SPDX-License-Identifier: MIT

import "./INFTDelegationRead.sol";

pragma solidity ^0.8.18;

contract NFTDelegationDEMO {
    
    INFTDelegationRead public dmcRead;

    constructor(address _NFTdelegationManagementContract) {
        dmcRead = INFTDelegationRead(_NFTdelegationManagementContract);
    }

    // Sample function for retrieving the delegators of msg.sender on Any collection for Any Use case

    function retrieveDelegators() public view returns(address[] memory) {
        return dmcRead.retrieveDelegators(msg.sender, 0x8888888888888888888888888888888888888888, 1);
    }

    // Sample function for retrieving the delegation status of msg.sender given a Delegator address

    function checkMintingStatus(address _vault) public view returns(bool) {
        return dmcRead.retrieveGlobalStatusOfDelegation(_vault, 0x8888888888888888888888888888888888888888, msg.sender, 2);
    }
    
    // Sample function for retrieving the token status given a delegator address

    function retrieveTokenStatus(address _vault, uint256 _tokenid) public view returns(bool) {
        return dmcRead.retrieveTokenStatus(_vault, 0x8888888888888888888888888888888888888888, msg.sender, 1, _tokenid);
    }

}
```

{% endcode %}
{% endtab %}
{% endtabs %}


# ERC721 Integration

This page demonstrates how an ERC721 smart contract can integrate the NFTDelegation.com smart contract during their minting.

Steps:

1. Import Interfaces within your smart contract

```
import "./INFTDelegationRead.sol";
```

2. Declare the Read Interface variable as below:

```
INFTDelegationRead public dmcRead;
```

3. Add a control mechanism as follows to check the minting process and block the Delegators' addresses for minting more than one time.

```
mapping (address => bool) public checkDelegatorMints;
```

4. Modify your ERC721 constructor as below. When deploying the smart contract input the NFTDelegation smart contract address 0x2202CB9c00487e7e8EF21e6d8E914B32e709f43d within your constructor.

{% code overflow="wrap" %}

```
constructor(address _delegationManagementContract, string memory name, string memory symbol) ERC721(name, symbol) {
    dmc = INFTDelegationRead(_delegationManagementContract);
}
```

{% endcode %}

5. Suggested Options for minting

**Option A:**&#x20;

Modify the minting function to take into consideration the retrieveDelegators() function from the NFTDelegation.com Smart Contract based on 'Any Collection' and 'All Use Cases'.&#x20;

By calling this function all Delegators of the msg.sender are retrieved, the tokens are minted and they are sent to each one of the Delegators.

{% code overflow="wrap" %}

```
function mintTokensForAllDelegators() public payable {
    // add your minting requirements and control mechanisms
    // to use NFTDelegation.com Smart Contract please add the code below
    address[] memory dmcDelegators;
    // use the collection and use case that you would like to retrieve delegators, in this case is 'Any Collection' and 'All Use Cases'
    dmcDelegators = dmc.retrieveDelegators(msg.sender, 0x8888888888888888888888888888888888888888, 1);
    // minting process
    for(uint i = 0; i <= dmcDelegators.length-1; i++) {
        uint mintIndex = totalSupply();
        // control mechanisms to prevent wallets on minting again using the same delegators addresses
        if (checkDelegatorMints[dmcDelegators[i]] == false) {
            _safeMint(dmcDelegators[i], mintIndex);
            checkDelegatorMints[dmcDelegators[i]] = true;
        } else {}
    }
}
```

{% endcode %}

**Option B:**&#x20;

Minting function modifications that takes into consideration the retrieveGlobalStatusOfDelegation() function from the NFTDelegation.com Smart Contract based on 'Any Collection' and 'All Use Cases'.&#x20;

During Option B the function awaits for one parameter, address *\_vault*. If a delegation between the *\_vault* address and the *msg.sender* exists the token will be minted and sent to the *\_vault* address.

{% code overflow="wrap" %}

```
function mintTokensPerDelegator(address _vault) public payable {
    // add your minting requirements and control mechanisms
    // to use NFTDelegation.com Smart Contract please add the code below
    bool isAllowedToMint;
    // check if a delegation between msg.sender and the vault exists on a specific usecase and collection, in this case is 'Any Collection' and 'All Use Cases'
    isAllowedToMint = dmc.retrieveGlobalStatusOfDelegation(_vault, 0x8888888888888888888888888888888888888888, msg.sender, 1);
    require(isAllowedToMint == true, "No delegation exists");
    // minting process
    uint mintIndex = totalSupply();
    // control mechanisms to prevent wallets on minting again using the delegator's address
    if (checkDelegatorMints[_vault] == false) {
        _safeMint(_vault, mintIndex);
        checkDelegatorMints[_vault] = true;
    } else  { 
            revert("Already Minted");
            }
}
```

{% endcode %}

**Option C:**&#x20;

Minting function modifications that takes into consideration the retrieveGlobalStatusOfDelegation() function from the NFTDelegation.com Smart Contract based on 'Any Collection' and 'All Use Cases'.&#x20;

During Option C the function awaits for two parameters, address *\_vault* and *address \_mintToAddress .* If a delegation between the *\_vault* address and the *msg.sender* exists the token will be minted and sent to the *\_mintToAddress* address that can be different than the *\_vault*.

{% code overflow="wrap" %}

```
function mintTokensPerDelegatorOtherAddress(address _vault, address _mintToAddress) public payable {
    // add your minting requirements and control mechanisms
    // to use NFTDelegation.com Smart Contract please add the code below
    bool isAllowedToMint;
    // check if a delegation between msg.sender and the vault exists on a specific usecase and collection, in this case is 'Any Collection' and 'All Use Cases'
    isAllowedToMint = dmc.retrieveGlobalStatusOfDelegation(_vault, 0x8888888888888888888888888888888888888888, msg.sender, 1);
    require(isAllowedToMint == true, "No delegation exists");
    // minting process
    uint mintIndex = totalSupply();
    // control mechanisms to prevent wallets on minting again using the delegator's address
    if (checkDelegatorMints[_vault] == false) {
        _safeMint(_mintToAddress, mintIndex);
        checkDelegatorMints[_vault] = true;
    } else  { 
            revert("Already Minted");
            }
}
```

{% endcode %}

Please note that this is a sample smart contract for demonstrating the usage of NFTDelegation within an ERC721 contract.

**Source Code**

{% tabs %}
{% tab title="Code" %}
{% code overflow="wrap" %}

```
// SPDX-License-Identifier: MIT

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./INFTDelegationRead.sol";

pragma solidity ^0.8.19;

contract ERC721_sample is ERC721, ERC721Enumerable, Ownable {

        // NFTDelegation.com contract declaration
        INFTDelegationRead public dmc;

        // Contol mechanism to check minting and not allow the same Delegatees to mint again
        mapping (address => bool) public checkDelegatorMints;

        constructor(address _delegationManagementContract, string memory name, string memory symbol) ERC721(name, symbol) {
            dmc = INFTDelegationRead(_delegationManagementContract);
        }

        /**
        * OPTION A:
        * Minting function that takes into consideration the retrieveDelegators() function from the NFTDelegation.com Smart Contract
        * The msg.sender (delegated address) mints on behalf of all Delegators and the minted tokens are sent to the Delegators Addresses
        */

        function mintTokensForAllDelegators() public payable {
            // add your minting requirements and control mechanisms
            // to use NFTDelegation.com Smart Contract please add the code below
            address[] memory dmcDelegators;
            // use the collection and use case that you would like to retrieve delegators, in this case is 'Any Collection' and 'All Use Cases'
            dmcDelegators = dmc.retrieveDelegators(msg.sender, 0x8888888888888888888888888888888888888888, 1);
            // minting process
            for(uint i = 0; i <= dmcDelegators.length-1; i++) {
                uint mintIndex = totalSupply();
                // control mechanisms to prevent wallets on minting again using the delegators addresses
                if (checkDelegatorMints[dmcDelegators[i]] == false) {
                    _safeMint(dmcDelegators[i], mintIndex);
                    checkDelegatorMints[dmcDelegators[i]] = true;
                } else {}
            }
        }

        /**
        * OPTION B:
        * Minting function that takes into consideration the retrieveGlobalStatusOfDelegation() function from the NFTDelegation.com Smart Contract
        * In this option the minted token is sent to the Delegator's Address
        */

        function mintTokensPerDelegator(address _vault) public payable {
            // add your minting requirements and control mechanisms
            // to use NFTDelegation.com Smart Contract please add the code below
            bool isAllowedToMint;
            // check if a delegation between msg.sender and the vault exists on a specific usecase and collection, in this case is 'Any Collection' and 'All Use Cases'
            isAllowedToMint = dmc.retrieveGlobalStatusOfDelegation(_vault, 0x8888888888888888888888888888888888888888, msg.sender, 1);
            require(isAllowedToMint == true, "No delegation exists");
            // minting process
            uint mintIndex = totalSupply();
            // control mechanisms to prevent wallets on minting again using the delegator's address
            if (checkDelegatorMints[_vault] == false) {
                _safeMint(_vault, mintIndex);
                checkDelegatorMints[_vault] = true;
            } else  { 
                    revert("Already Minted");
                    }
        }

        /**
        * OPTION C:
        * Minting function that takes into consideration the retrieveGlobalStatusOfDelegation() function from the NFTDelegation.com Smart Contract
        * In this option the minted token is sent to the _mintToAddress address
        */

        function mintTokensPerDelegatorOtherAddress(address _vault, address _mintToAddress) public payable {
            // add your minting requirements and control mechanisms
            // to use NFTDelegation.com Smart Contract please add the code below
            bool isAllowedToMint;
            // check if a delegation between msg.sender and the vault exists on a specific usecase and collection, in this case is 'Any Collection' and 'All Use Cases'
            isAllowedToMint = dmc.retrieveGlobalStatusOfDelegation(_vault, 0x8888888888888888888888888888888888888888, msg.sender, 1);
            require(isAllowedToMint == true, "No delegation exists");
            // minting process
            uint mintIndex = totalSupply();
            // control mechanisms to prevent wallets on minting again using the delegator's address
            if (checkDelegatorMints[_vault] == false) {
                _safeMint(_mintToAddress, mintIndex);
                checkDelegatorMints[_vault] = true;
            } else  { 
                    revert("Already Minted");
                    }
        }

        // The following functions are overrides required by Solidity.

        function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId, batchSize);
        }

        function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) {
        return super.supportsInterface(interfaceId);
        }

}
```

{% endcode %}
{% endtab %}
{% endtabs %}

**Extension A: Mint based on smart contract's max Allowance**

Modify the smart contract to allow a delegated address to mint on behalf of the Delegator address the max tokens allowed. In this case the minting is not 1 token per Delegator Address but more based on the maxAllowance number set on the smart contract.

Modifications:

Add a uint256 variable and a mapping that will be used to count the number of successful mints per address.

{% code overflow="wrap" %}

```
uint256 maxAllowance;
mapping (address => uint256) public checkDelegatorMintsAllowance;
```

{% endcode %}

Modify the constructor as below and add a value for the maxAllowance variable.

{% code overflow="wrap" %}

```
constructor(address _delegationManagementContract, string memory name, string memory symbol) ERC721(name, symbol) {
    dmc = INFTDelegationRead(_delegationManagementContract);
    maxAllowance = 2;
}
```

{% endcode %}

Modify the minting function as below:

{% code overflow="wrap" %}

```
function mintTokensPerDelegatorAllowance(address _vault, uint256 _noOfTokens) public payable {
    // add your minting requirements and control mechanisms
    // to use NFTDelegation.com Smart Contract please add the code below
    bool isAllowedToMint;
    // check if a delegation between msg.sender and the vault exists on a specific usecase and collection, in this case is 'Any Collection' and 'All Use Cases'
    isAllowedToMint = dmc.retrieveGlobalStatusOfDelegation(_vault, 0x8888888888888888888888888888888888888888, msg.sender, 1);
    require(isAllowedToMint == true, "No delegation exists");
    // control mechanisms to mint based on max Allowance
    for (uint256 i=0; i < _noOfTokens; i++) {
        if (checkDelegatorMintsAllowance[_vault] < maxAllowance) {
            uint mintIndex = totalSupply();
            _safeMint(_vault, mintIndex);
            checkDelegatorMintsAllowance[_vault] = checkDelegatorMintsAllowance[_vault] + 1;
        } else  { 
                revert("Max Allowance Reached");
                }
        }
}
```

{% endcode %}

**Extension B: Mint based on Merkle Proofs**

Modify the smart contract to allow the delegated address to mint on behalf of the Delegator Address when the Delegator Address has an allowlist. The amount of tokens minted per Delegator Address varies.

Example:

<table><thead><tr><th width="577">Delegator Address</th><th>Max Allowance</th></tr></thead><tbody><tr><td>0x5B38Da6a701c568545dCfcB03FcB875f56beddC4</td><td>1</td></tr><tr><td>0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2</td><td>2</td></tr><tr><td>0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db</td><td>3</td></tr></tbody></table>

Modifications:

Import the MerkleProof library

```
import "./MerkleProof.sol";
```

Add a bytes32 variable for the MerkleRoot and a mapping that will be used to count the number of successful mints per address.

{% code overflow="wrap" %}

```
bytes32 merkleRoot;
mapping (address => uint256) public checkDelegatorMintsAllowance;
```

{% endcode %}

Modify the constructor so as to accept a Merkle Root as an input.

{% code overflow="wrap" %}

```
constructor(address _delegationManagementContract, bytes32 _merkleRoot, string memory name, string memory symbol) ERC721(name, symbol) {
    dmc = INFTDelegationRead(_delegationManagementContract);
    merkleRoot = _merkleRoot;
}

```

{% endcode %}

Modify the minting function as below:

{% code overflow="wrap" %}

```
function mintTokensPerDelegatorMerkle(address _vault, uint256 _noOfTokens, bytes32[] calldata merkleProof) public payable {
    // add your minting requirements and control mechanisms
    // to use NFTDelegation.com Smart Contract please add the code below
    bool isAllowedToMint;
    // check if a delegation between msg.sender and the vault exists on a specific usecase and collection, in this case is 'Any Collection' and 'All Use Cases'
    isAllowedToMint = dmc.retrieveGlobalStatusOfDelegation(_vault, 0x8888888888888888888888888888888888888888, msg.sender, 1);
    require(isAllowedToMint == true, "No delegation exists");
    // check merkle proofs
    bytes32 node = keccak256(abi.encodePacked(_vault, _noOfTokens));
    require(MerkleProof.verifyCalldata(merkleProof, merkleRoot, node), 'invalid proof');
    // control mechanisms to mint based on max Allowance per address
    for (uint256 i=0; i < _noOfTokens; i++) {
        if (checkDelegatorMintsAllowance[_vault] < _noOfTokens) {
            uint mintIndex = totalSupply();
            _safeMint(_vault, mintIndex);
            checkDelegatorMintsAllowance[_vault] = checkDelegatorMintsAllowance[_vault] + 1;
        } else  { 
                revert("Max Allowance Reached");
                }
        }
}

```

{% endcode %}


