> ## Documentation Index
> Fetch the complete documentation index at: https://docs.patchwork.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Scopes

> Scopes are application-level Patchwork namespaces for configuring settings and permissions or your app.

When creating a new application, the first thing you'll do is create a Patchwork Scope for your app. You'll then define within that scope which contracts can mint, assign NFTs, and modify metadata. Scopes are free to claim on a first-come-first-serve basis, and can be transferred to other parties.

## Scope creation

Scopes are claimed using `PatchworkProtocol:claimScope()`. Typically you'll call this in your contracts' deploy script, but it can be manually called if desired.

<Note>When called, the owner of the claimed Scope is set to the party calling the function.</Note>

For example, this Forge deploy script claims the Scope `fooscope123`.

```solidity deploy.s.sol theme={null}
pragma solidity ^0.8.13;

import "forge-std/Script.sol";
import "@patchwork/PatchworkProtocol.sol";

contract FooDeploy is Script {
    function run() external {
        PatchworkProtocol patchworkProtocol = PatchworkProtocol(ADDRESSFORPATCHWORK);

        vm.startBroadcast();
        patchworkProtocol.claimScope("fooscope123");

        // ...rest of deploy code
    }
}
```

## Scope permissions

**Operators**

Scope Operators are added and removed by the scope owner.

Operators may perform the following functions:

* Add/Remove bankers
* Add/Remove whitelisted addresses
* Configure minting
* Set patch and assignment fees

It is common to have an EOA or a contract act as an operator. Contracts as operators are often used to have the contract perform logic and run assignment routines.

**Bankers**

Scope Bankers are added and removed by scope owners or operators.

Bankers may perform the following functions:

* Withdraw fees collected by the protocol

**Whitelist**

Whitelisting is how scopes prevent spoofing. Whitelisting can be disabled for a scope for cases where spoofing doesn't matter, but by defualt an address must be whitelisted in order to claim it is part of the scope.

## Adding contracts to your Scope

Registering a contract to your Scope is a 2-part process. The first part is declaring the Scope in your contract's Patchwork721 constructor, where the first param is the name of your claimed Scope.

```solidity Foo.sol theme={null}
pragma solidity ^0.8.23;

import "@patchwork/Patchwork721.sol";

contract Foo is Patchwork721 {
    constructor(address manager_, address owner_)
        Patchwork721("fooscope123", "Foo", "FOO", manager_, owner_)
    { }

    // ...rest of contract code
}
```

The second part is granting your deployed contract the relevant Scope permissions. This is typically done in your contract's deploy script.

```solidity deploy.s.sol theme={null}
    // Sets scope rules to default: No user patch, No user assign, Require whitelist
    patchworkProtocol.setScopeRules("fooscope123", false, false, true);
    // Add foocontract as a scope operator so it may perform assignments
    patchworkProtocol.addOperator("fooscope123", address(foocontract));
    // Whitelist foocontract in the scope
    patchworkProtocol.addWhitelist("fooscope123", address(foocontract));
```

## Adding and removing operators

```solidity theme={null}
    patchworkProtocol.addOperator("fooscope123", opAddr)
    patchworkProtocol.removeOperator("fooscope123", opAddr)
```

## Transfering Scopes

Scope transfers must first elect a new owner by calling `transferScopeOwner` from the current owner's address, then the new owner must call `acceptScopeTransfer` for the transfer to execute.
To cancel a transfer before the scope has been accepted, call `cancelScopeTransfer`

```solidity theme={null}
    patchworkProtocol.transferScopeOwnership("fooscope123", newOwnerAddr);
    patchworkProtocol.cancelScopeTransfer("fooscope123")
    patchworkProtocol.acceptScopeTransfer("fooscope123")
    patchworkProtocol.getScopeOwnerElect("fooscope123")
    patchworkProtocol.getScopeOwner("fooscope123")
```

## Adding and removing bankers

```solidity theme={null}
    patchworkProtocol.addBanker("fooscope123", bankerAddr)
    patchworkProtocol.removeBanker("fooscope123", bankerAddr)
```

## Withdrawing fees

```solidity theme={null}
    uint256 balance = patchworkProtocol.balanceOf("fooscope123");
    patchworkProtocol.withdraw("fooscope123", balance);
```

## Configuring minting

```solidity theme={null}
    patchworkProtocol.setMintConfiguration(mintableAddr, config)
```

## Setting patch and assignment fees

```solidity theme={null}
    patchworkProtocol.setPatchFee(patchContractAddr, baseFee)
    patchworkProtocol.getPatchFee(patchContractAddr)
    patchworkProtocol.setAssignFee(fragmentContractAddr, baseFee)
    patchworkProtocol.getAssignFee(fragmentContractAddr)
```
