> For the complete documentation index, see [llms.txt](https://docs.ethscriptions.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ethscriptions.com/ethscriptions-appchain/protocol-handlers.md).

# Protocol Handlers

Protocol handlers allow developers to extend ethscription functionality with custom on-chain logic. When an ethscription includes protocol parameters, the Ethscriptions contract routes the call to a registered handler.

{% hint style="info" %}
Protocol handlers are an **AppChain-only** feature. They require smart contract execution on the L2.
{% endhint %}

## How It Works

1. **Registration** - A handler contract registers with the main Ethscriptions contract
2. **Creation** - User creates an ethscription with protocol parameters in the Data URI
3. **Routing** - The Ethscriptions contract detects the protocol and calls the handler
4. **Execution** - The handler performs custom logic (mint tokens, add to collection, etc.)

```
User → L1 Transaction → Derivation Node → Ethscriptions Contract → Protocol Handler
```

## Built-in Protocols

| Protocol                           | Purpose                                         | Documentation                                                                     |
| ---------------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------- |
| `erc-721-ethscriptions-collection` | Curated NFT collections with merkle enforcement | [Collections](/ethscriptions-appchain/collections.md)                             |
| `erc-20-fixed-denomination`        | Fungible tokens with fixed-denomination notes   | [Fixed Denomination Tokens](/ethscriptions-appchain/fixed-denomination-tokens.md) |

## Protocol Data URI Format

Protocols are invoked by adding parameters to the Data URI. Two encoding styles are supported:

### Header-Based (for binary content)

Best for images and other binary data where the content itself is the payload:

```
data:image/png;rule=esip6;p=erc-721-ethscriptions-collection;op=add_self_to_collection;d=<base64-json>;base64,<image-bytes>
```

| Parameter        | Description                             |
| ---------------- | --------------------------------------- |
| `p=<protocol>`   | Protocol handler name (lowercase)       |
| `op=<operation>` | Operation to invoke on the handler      |
| `d=<base64>`     | Base64-encoded JSON parameters          |
| `rule=esip6`     | (Optional) Allow duplicate content URIs |

### JSON Body (for text-based operations)

Best for operations where the parameters ARE the content:

```
data:application/json,{"p":"erc-20-fixed-denomination","op":"deploy","tick":"mytoken","max":"1000000","lim":"1000"}
```

The JSON body contains:

* `p` - Protocol handler name
* `op` - Operation name
* Additional operation-specific fields

## Example: Creating a Collection Item

Header-based format for adding an image to a collection:

```
data:image/png;rule=esip6;p=erc-721-ethscriptions-collection;op=add_self_to_collection;d=eyJjb2xsZWN0aW9uSWQiOiIweC4uLiIsIml0ZW1JbmRleCI6MX0=;base64,iVBORw0KGgo...
```

Where the base64-decoded `d` parameter contains:

```json
{
  "collection_id": "0x...",
  "item": {
    "item_index": "1",
    "name": "Item #2",
    "background_color": "#00FF00",
    "description": "The second item",
    "attributes": [{"trait_type": "Rarity", "value": "Rare"}],
    "merkle_proof": []
  }
}
```

## Example: Deploying a Token

JSON body format for deploying a fixed-denomination token:

```
data:application/json,{"p":"erc-20-fixed-denomination","op":"deploy","tick":"mytoken","max":"1000000","lim":"1000"}
```

## Protocol Handler Contract Interface

Handlers implement the `IProtocolHandler` interface:

```solidity
interface IProtocolHandler {
    // Called when ethscription is transferred
    function onTransfer(
        bytes32 ethscriptionId,
        address from,
        address to
    ) external;

    // Returns the protocol name
    function protocolName() external pure returns (string memory);
}
```

Operation functions (prefixed with `op_`) are called dynamically based on the `op` parameter in the data URI. For example, the collections manager implements:

* `op_create_collection_and_add_self(...)`
* `op_add_self_to_collection(...)`
* `op_edit_collection(...)`

These are not part of the interface - the Ethscriptions contract uses dynamic dispatch to call them.

## Events

The Ethscriptions contract emits events for protocol operations:

```solidity
event ProtocolHandlerSuccess(
    bytes32 indexed ethscriptionId,
    string protocol,
    bytes returnData
);

event ProtocolHandlerFailed(
    bytes32 indexed ethscriptionId,
    string protocol,
    bytes revertData
);
```

## Registration

Protocols are registered at genesis or through governance. The main contract maintains a mapping:

```solidity
mapping(string => address) public protocolHandlers;
```

When an ethscription with protocol params is created, the contract looks up the handler and calls the appropriate `op_*` function.

## Security Considerations

* Protocol handlers run within the Ethscriptions contract's context
* Handlers cannot modify ethscription ownership directly
* All state changes are atomic with the ethscription creation
* Failed handler calls emit `ProtocolHandlerFailed` but don't revert the ethscription creation
