# Welcome

Welcome to the official documentation for the TAP Protocol, an innovative and extendible OrdFi-enabling protocol built on top of Bitcoin's Ordinals.

Tap is designed to be the most powerful metaprotocol on Bitcoin L1, offering a range of features and capabilities without relying on Layer 2 solutions.

In this documentation, you'll find comprehensive information on:

* The structure and components of TAP Protocol
* Basic functions compatible with existing BRC-20 infrastructure
* Extended functions:
  * Mass-Send
  * Peer2Peer trading
  * Prevent transferable grief attacks
  * Account Abstraction:
    * Privilege Authorities
    * Token Authorities
  * Digital Matter Theory assets
  * Bitmap Support

Whether you're a developer, a marketplace operator, or simply curious about the future of Bitcoin-native tokens, this guide will provide you with the knowledge you need to understand and leverage the Tap Protocol.

Join us as we explore the cutting edge of Ordinals technology and unlock new possibilities for decentralized finance on Bitcoin!

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Basic Functions</strong></td><td>How to interact with the TAP Protocol at the base level.</td><td></td><td></td><td><a href="/pages/CyH2xJQs9yWJ1S8BYNav">/pages/CyH2xJQs9yWJ1S8BYNav</a></td></tr><tr><td><strong>Extended Functions</strong></td><td>Learn more about the concepts and principles of the TAP Protocol.</td><td></td><td></td><td><a href="/pages/JjjojIyKxaiBPzzLwvtg">/pages/JjjojIyKxaiBPzzLwvtg</a></td></tr><tr><td><strong>Smart Contracts</strong></td><td>Learn how to write smart contracts for the TAP Protocol on Bitcoin L1.</td><td></td><td></td><td><a href="/pages/ywJoXrVppmceUYhcvAfn">/pages/ywJoXrVppmceUYhcvAfn</a></td></tr></tbody></table>


# Basic Functions

### Prerequisites

* A Bitcoin wallet with Ordinals support.
* An inscription service or app of your choice that is capable of inscribing text for Bitcoin Ordinals.
* The [TAP Reader](https://github.com/Trac-Systems/tap-reader/) to lookup deployments, mint status, account balances and much more.

### Basic Functions

Aside from its special features, the TAP Protocol is compatible with the BRC-20 specs for Bitcoin Ordinals when it comes to the basic functions for  Deploy, Mint and Transfer. The processes behind these functions are mirroring those precisely. This allows existing projects to support TAP Protocol with minimal efforts.

However, when it comes to tickers, there are a few differences:

* All tickers support the full unicode range.
* The allowed length per ticker is 1-32 symbols.
* A symbol is the "visual length", not the byte-length. If a symbol spans across 2 or more bytes, it's still having a length of 1.
* Whitespaces, also leading and trailing, are unicode, as well and are therefore valid.
* Tickers starting with a dash or "dmt-" are reserved for cursed tokens and Digital Matter Theory assets.
* In clients, it is recommended to render ticker names in quotes to make whitespaces clearly visible. Additionally, a unique hash representation over the unicode tickers can be provided.

### Token Deploy

Deploying a token is a simple Bitcoin Ordinals text inscription in JSON-format. There are tools to simplify the process, but on a base level, it's as simple as storing the following JSON on-chain using a text inscription service or app:

```json
{ 
  "p": "tap",
  "op": "token-deploy",
  "tick": "tap",
  "max": "21000000",
  "lim": "1000"
}
```

"p" represents the name of the protocol being used.

"op" is the function to be executed, in the above example that would be the function to deploy a new token.

"tick" is the ticker you want to deploy.

"max" is the maximum supply of the token.

"lim" is the maximum that can be minted per mint inscription (see below).

With the above setup, and given the deployment was successful, anyone can mint up to 1000 tokens per mint inscription until the supply exhausted.

Should the deployment fail, for example if the ticker exists already, the deployment will be invalid and no mints are possible for the particular deployment.

### Token Mint

To mint tokens from a deployed ticker, we need another inscription type that represents a function to perform a mint. Any minter can now inscribe the following JSON to mint from the deployment above. After a sucessful mint, the minted token amount will be credited to the address that the inscription has been created for:

```json
{ 
  "p": "tap",
  "op": "token-mint",
  "tick": "tap",
  "amt": "1000"
}
```

"p" represents the name of the protocol being used.

"op" is the function to be executed, in the above example that would be the function to mint a token.

"tick" is the ticker you want to mint.

"amt" is the amount you want to mint. This is usually the the maximum per mint reflected in the token-deploy function under "lim".

Once all tokens are minted, any further mint will be invalid and fail.

### Token Transfer

Transferring tokens is a 2-step procedure. 1st you need to inscribe the inscription text below to activate the desired amount of tokens. This process is also known as creating transferable inscriptions.&#x20;

2nd, once inscribed (available in your wallet), you need to send the resulting Ordinal from your wallet to the receiver address. Once received, the token amount is being credited to the receiver and deducted from your wallet's balance.

Aside from transferring tokens, this allows to trade tokens for actual Bitcoin and is the most basic option for trading:

```json
{ 
  "p": "tap",
  "op": "token-transfer",
  "tick": "tap",
  "amt": "100"
}
```

"p" represents the name of the protocol being used.

"op" is the function to be executed, in the above example that would be the function to transfer tokens.

"tick" is the ticker you want to transfer.

"amt" is the amount of tokens you want to create a transferable inscription for.

To cancel a transferable, simply send it to yourself.

### Caveats

Despite the basic function representing a simple and effective way to create and distribute tokens, those may come with flaws for some use-cases:

* Mints are always public. By default, there is no way to restrict the minting process (fair mints).
* Mints are prone to frontrunning. Others can pay a higher fee and front-run anyone with lower fees.
* Transfers require a 2-step process, which can feel disruptive if you just want to send tokens from A to B.
* There is no programmability supported.&#x20;

While for many projects, the above features are enough, the TAP Protocol offers a set of extended functions to address the limitations of BRC-20.


# Extended Functions

This section desribes each extended functions of the TAP Protocol. From how to prevent transferable grief attacks to functions that help to support programmability, you'll find everything you need here.

Many of the extended functions are tappable. **Tappable** means that these functions require an approval. This process is simple: inscribe a function into your wallet and send it to yourself to approve.

The TAP Protocol got its name from this process to allow for most of the special features to function.

### Prerequisites

* A Bitcoin wallet with Ordinals support.
* An inscription service or app of your choice that is capable of inscribing text for Bitcoin Ordinals.
* The [TAP Reader](https://github.com/Trac-Systems/tap-reader/) to lookup deployments, mint status, account balances and much more.
* Additional resources - if any - in the description of each extended function.


# Block Transferables

{% hint style="info" %}
Tappable
{% endhint %}

To prevent grief attacks using the external "token-transfer", account holders can entirely disable this function by inscribing the inscription text below to themselves and tap (=send to yourself) the inscription. This feature is especially important if token-authorities are being used that redeem tokens from their own accounts.

Once tapped (=inscribed and again sent to yourself), incoming inscribe transfers are being skipped/invalidated such that no subsequent transfers using "token-transfer" aren't possible anymore. Existing transferables stay intact and can be used:

```json
{
  "p" : "tap",
  "op" : "block-transferables"
}
```


# Unblock Transferables

{% hint style="info" %}
Tappable
{% endhint %}

To unblock inscribe transfers, the function below must be tapped (=inscribed and again sent to yourself). Once tapped, inscribe transfers will continue to work normally and contribute to the overall transferable amounts of the account again.

```json
{
  "p" : "tap",
  "op" : "unblock-transferables"
}
```


# Mass Send

{% hint style="info" %}
Tappable
{% endhint %}

Enables mass-transfer of different tokens to many recipients:

* Users inscribe a "token-send" inscription to their Bitcoin address.
* After the transaction confirmed, the inscription has to be resent to the same address for confirmation (tapping).
* Upon tapping, the Bitcoin address must own the the amounts of tokens that are given with the inscription.
* Only if the "token-send" inscription is tapped, sending tokens will be performed.
* The receiver addresses must be carefully validated: must be valid Bitcoin addresses, must be trimmed, addresses starting with bc1 have to be lowercased.
* "token-send" is atomic upon inscribing (before tapping): all amounts, tickers and addresses must be syntactically valid.
* Upon tapping, invalid and semantically incorrect token sends must be skipped (e.g. insufficient funds, invalid amounts or invalid data types).
* Each successful token send must credit the given amounts to recipient and be removed from the sender's balance.
* Each send item must exclusively operate on available balances, not overall balances (available = balance - transferable).

```json
{
  "p" : "tap",
  "op" : "token-send",
  "items" : [
     {
      "tick": "-tap",
      "amt": "10000",
      "address" : "bc1p9lpne8pnzq87dpygtqdd9vd3w28fknwwgv362xff9zv4ewxg6was504w20"
     },
     {
      "tick": "tap",
      "amt": "10000",
      "address" : "bc1p063utyzvjuhkn0g06l5xq6e9nv6p4kjh5yxrwsr94de5zfhrj7csns0aj4"
     }
  ]
}
```


# Token Authority

{% hint style="info" %}
Tappable
{% endhint %}

The function set "token-auth" allows 3rd parties (authorities) to independently issue signed redeem inscriptions. These signed redeem inscriptions may be inscribed by anyone and authorized tokens being sent to recipients. This allows for custom logic to be specified about what tokens should go where and when.

This makes TAP basically a no-knowledge protocol within Ordinals as it doesn't need to know the details of custom logic provided by 3rd parties. Unlike zk-rollups, token-auth relies solely on message signatures and does not require sequencers or L2 mediators. Token-auth can even be used to connect with zk-rollup solutions, adding an extra layer of authenticity.

token-auth does not rely on witness data hacking. All operations are clearly contained within the Ordinal envelope's data and thus easily provable by any indexer or individual.

Typical use-cases for token-auth are gamification (e.g. convert points to tokens), token bridges, staking, reward systems, cross-chain marketplaces and more.

### **Create an authority**

To create an authority, a special token-auth inscription must be sent and tapped with an address that holds authorized tokens.

Manual creation of token-auth code is not recommended as it requires message signatures. See the [boilerplate](https://github.com/Trac-Systems/tap-protocol-token-auth-boilerplate) that helps to generate signed token auths.&#x20;

Token-auth uses secp256k1 signatures. See <https://github.com/paulmillr/noble-secp256k1> as an example implementation.

Example:

```json
{
   "p":"tap",
   "op":"token-auth",
   "sig":{
      "v":"0",
      "r":"51143521410606380758535576062355234772504706283689533465002520447203156100709",
      "s":"23524754809729078525228087002160468580495709275023865450917881139756565577560"
   },
   "hash":"0f30c22be2f46e819538ca1281aadb82d3928cae5a699cade80013c5b14871e4",
   "salt":"0.25991027744263695",
   "auth":[
      "gib"
   ]
}
```

* The "auth" attribute must contain an array of deployed TAP protocol tokens that are verified for the authority's account.
* If the "auth" attribute's array is empty, all tokens owned by the authority's account are authorized.
* Upon indexing, the token-auth inscription must be verified against the signature ("sig"), "hash" attribute and public key.
* The public key must be recovered by using "hash".
* To prevent hash collisions, a custom "salt" value has to be provided by the authority.
* To verify, the "auth" array must be JSON-stringified and sha256-hashed with "salt" (sha256(auth + salt)).
* "hash" must be unique and can only be used once across the entire indexing state.
* Token-auth is atomic, this means that all tokens in "auth" must be deployed at the time of inscribing (if the "auth" array is *not* empty).
* The authority address does NOT need to own the authorized tokens at the time of inscribing (but should, upon redeeming, see below).
* If all authorized tokens are deployed or the "auth" array is empty, the hashed signature is valid and the hash has never been used before, the token-auth inscription must be indexed after tapping (=sending to "yourself").

### **Create a redeem inscription**

Tokens to redeem are signed and issued by the authority. The inscription code may be inscribed by everyone and it is under the sole discretion of the authority when and how redeems are issued. Typically, an authority would sign and issue a redeem when all its conditions are met.

Manual creation of token-auth code is not recommended as it requires message signatures. See this example script that helps to generate signed token auths. Token-auth uses secp256k1 signatures. See <https://github.com/paulmillr/noble-secp256k1> as an example implementation.

```json
{
   "p":"tap",
   "op":"token-auth",
   "sig":{
      "v":"1",
      "r":"113472523327934685528808901641630457916054343054143422440331961430719594721038",
      "s":"21393407019197854961723689634443789868582208930187383447036700552814535514199"
   },
   "hash":"82e2b0d098dcdab820ff866b011250af8841a6b59cedd7164bb94b63d2598de9",
   "salt":"0.46074583388095514",
   "redeem":{
      "items":[
         {
            "tick":"gib",
            "amt":"546",
            "address":"bc1p9lpne8pnzq87dpygtqdd9vd3w28fknwwgv362xff9zv4ewxg6was504w20"
         }
      ],
      "auth":"fd3664a56cf6d14b21504e5d83a3d4867ee256f06cbe3bddf2787d6a80a86078i0",
      "data":""
   }
}
```

* The "redeem" attribute must contain an object consisting of "redeem" => "items", the inscription id of the signing authority ("redeem" => ""auth") and "redeem" => "data".
* Upon indexing, the token-auth inscription must be verified against the signature ("sig"), "hash" attribute and public key.
* The public key must be recovered by using "hash".
* To prevent hash collisions, a custom "salt" value has to be provided by the authority.
* To verify, the "auth" array must be JSON-stringified and sha256-hashed with "salt" (sha256(auth + salt)).
* "hash" must be unique and can only be used once across the entire indexing state.
* "redeem" => "data" must be present but may be empty.
* Based on the inscription id in "auth", the public key by the authority must be recovered and compared with the public key of the redeem.
* Both public keys must match.
* Both hashes must be valid.
* The original auth inscription mustn't be cancelled.
* All tickers in "redeem" => "items" must be specified in the original "auth" inscription.
* If all conditions are met, the tokens specified in "redeem" => "items" must be sent exactly like TAP's function "token-send" above, including all of its conditions. Tapping is not required, as this is a signed transaction and may be inscribed by everyone.

### **Cancel an authority**

To cancel a "token-auth", the authority must send an inscription like below to its associated address and tap.

```json
{
   "p":"tap",
   "op":"token-auth",
   "cancel" : "fd3664a56cf6d14b21504e5d83a3d4867ee256f06cbe3bddf2787d6a80a86078i0"
}
```

* "cancel" must point to an existing an non-cancelled "token-auth" of the authority.
* Once tapped, no further redeems may be executed on the inscribed "token-auth", indefinitely.


# Privilege Authority

{% hint style="info" %}
Tappable
{% endhint %}

The function set "privilege-auth" allows 3rd parties (authorities) to implement token/unat/collectible whitelists, launchpads and general-purpose provenance for file hashes (sha256).

### **Create an privilege authority**

To create a privilege authority, a special privilege-auth inscription must be sent and tapped.

Manual creation of privilege-auth code is not recommended as it requires message signatures. See the [boilerplate](https://github.com/Trac-Systems/tap-protocol-privilege-auth-boilerplate) that helps to generate signed privileges. Privilege-auth uses secp256k1 signatures. See <https://github.com/paulmillr/noble-secp256k1> as an example implementation.

Example:

```json
{
   "p":"tap",
   "op":"privilege-auth",
   "sig":{
      "v":"0",
      "r":"86508516128453602592995353796555408942165629541645840597158531627249758208446",
      "s":"34207792571992691071321015990261453361621215423082720220623653945331263914520"
   },
   "hash":"a7a8fe6a46d7dd3aac3518ecdc97577be5319eb5ae8588eee9c92ad96eed3b68",
   "salt":"0.41631368860188056",
   "auth":{
      "name":"Some privilege authority"
   }
}
```

### **Token deployments**

Token deployments work exactly like regular deployments as described earlier but a new attribute called "prv" must be added, pointing to an existing, active (not cancelled) token authority by using its inscription id (not number).

If there is no valid authority at the given inscription id for "prv", the deployment will fail. If the authority is valid, only the authority specified in "prv" will be allowed to specify what address is allowed to mint tokens.

The authority still has to respect all given rules as of the deployment inscription. It cannot override limits, max supply, tickers.

Example of regular token deploys on the TAP Protocol:

```json
{ 
  "p": "tap",
  "op": "token-deploy",
  "tick": "tap",
  "max": "21000000",
  "lim": "1000",
  "prv" : "fd3664a56cf6d14b21504e5d83a3d4867ee256f06cbe3bddf2787d6a80a86078i0"
}
```

Example for DMT token deploys on the TAP Protocol:

```json
{
"p": "tap",
"op": "dmt-deploy",
"elem": "63b5bd2e28c043c4812981718e65d202ab8f68c0f6a1834d9ebea49d8fac7e62i0",
"tick": "nat",
"dt": "n",
"prv" : "fd3664a56cf6d14b21504e5d83a3d4867ee256f06cbe3bddf2787d6a80a86078i0"
}
```

### **Token mints**

Token mints work exactly like regular mints as described further above but a new attribute called "prv" must be provided. "prv" must contain an object specifying the authority's signature and the wallet address that is allowed to mint. "salt" can be used to pass extra data to make sure the resulting hash is always unique. It is however recommended to use non-random salts (e.g. inscription ids) if the authority has the requirement internally to be able to re-index at all times.

The authority must broadcast the signed inscription text via an offchain mechanism of its choice.

The signature given with the "prv" attribute object must match the signature of the authority. Only if both resulting public keys match, the mint is valid. If the the resulting keys do not match, or the signature is invalid, the mint will be rejected.

If any other address other than the one given tries to mint, the mint will fail and the authority has to re-issue a signed inscription with a new salt since hashes are unique across the protocol.

Example mint inscription text on the TAP Protocol:

```json
{
   "p":"tap",
   "op":"token-mint",
   "tick":"tap",
   "amt":1000,
   "prv":{
      "sig":{
         "v":"0",
         "r":"106344897850645353394557411159466118155649878604746085611434406050662507764701",
         "s":"5566788626956401066167017793946358967684734480695302740591785789681566880049"
      },
      "hash":"931c0b44c1811ba4a8ac7c696a7f0e664ea85b18c34ec32d492fcc99fd7ee4a7",
      "address":"tb1pf9jluy2g797290uq5nutqm2yuynds6uf868ytc37nht53c5j8w3s7nfta7",
      "salt":"0.3624804148476173"
   }
}
```

Example DMT mint inscription text on the TAP Protocol:

```json
{
   "p":"tap",
   "op":"dmt-mint",
   "tick":"nat",
   "blk":840000,
   "dep":"825e287bb7dd163ed633110e31bc6abb6c80815ca68b7dd3cc71d729ecaaa3dci0",
   "prv":{
      "sig":{
         "v":"0",
         "r":"10387661166049122705773272120018537684460586485610280053381057207269720400370",
         "s":"47937738938877326713978443360828324693873763102762802539146112797003515228281"
      },
      "hash":"1056344a88698e989aa6799c46d72f5b110fb26ff0426c1a84a6640803b0d74c",
      "address":"tb1pf9jluy2g797290uq5nutqm2yuynds6uf868ytc37nht53c5j8w3s7nfta7",
      "salt":"0.3903927009829504"
   }
}
```

### **Hashed Verifications**

Hash verifications within privileges are a general-purpose mechanism to determine what file hash (sha256) may be assigned to a given address.

If an authority issues such a signed inscription text, it can signal that it sees the address as the valid owner of that hash.

An interesting aspect of hashed verfications that these might be used as collectibles as they contain verified file hashes of linked or offchain content.

Different authorities may have different opinions. That's why it's important that projects managing authorities, must broadcast their authority inscription ids via offchain channels to provide the source of truth.

Like deployments & mints, a signature and the inscription id of the authority must be given ("prv").

The attribute "verify" must contain an sha256 hash, representing a hash over file contents. "col" must be used to specify a "collection" name to allow for organizing the hashes. Maximum allowed symbols: 512 (as of unicode). "seq" must be an unsigned integer, that may be arbitrary and not larger than 9007199254740991.

If "seq" is passed as string, the verification will fail. "col" may be an empty string but must be present.

"salt" can be used to pass extra data to make sure the resulting hash is always unique. It is however recommended to use non-random salts (e.g. inscription ids) if the authority has the requirement internally to be able to re-index at all times.

```json
{
   "p":"tap",
   "op":"privilege-auth",
   "sig":{
      "v":"0",
      "r":"102486240205705464835967036484087123773428387054126262751119766795035126943608",
      "s":"2461281772805092833125901827999803585726660443752983045919874042616328309644"
   },
   "hash":"81906992bfffa87f48cdeaecff29bac840553ac0bdfb9288bed0cab6de573efc",
   "address":"tb1pltn4mqlpxxswxhmkj2ejdd0z98v74nr0xxdresvwvp5cyvctm0zs3m750l",
   "salt":"0.9698534940599512",
   "prv":"e349a9126a9476eb534457a7e78c748aeca67ec4d53fa9f0772408fb7233a9fei0",
   "verify":"cea505f61f375ea2d8ea56f593e6b436f963753616c2095e755cb5ca4a6df85c",
   "col":"super collection",
   "seq":111
}
```

### **Cancel a privilege authority**

To cancel a "privilege-auth", the authority must send an inscription like below to its associated address and tap. From this point on, no mints or verifications can take place anymore that originally have been managed by the authority. This can be used for blockouts, collection finalization etc.

```json
{
   "p":"tap",
   "op":"privilege-auth",
   "cancel" : "fd3664a56cf6d14b21504e5d83a3d4867ee256f06cbe3bddf2787d6a80a86078i0"
}
```


# Peer2Peer Trading

{% hint style="info" %}
Tappable
{% endhint %}

The functional set "token-trade" consists of 3 functions to allow text-inscription based trading. By inscribing a trade inscription as seller, a trade is being added to the Ordinals collection and can be picked up by any buyer for the duration of a valid period in blocks.

Upon filling a trade by the buyer, an optional fee receiver address may be added to receive fixed 0.3% fees in tokens per filled trade. Fees are applied on top of the purchased token and is being paid by the buyer. Fees give inscription services and marketplaces a way to benefit from internal trading, while buyers benefit from the convenience and guidance of their services.

To inscribe a trade, a seller has to inscribe a text inscription in the following format:

### **Creating a Trade**

```json
{
  "p" : "tap",
  "op" : "token-trade",
  "side" : "0",
  "tick" : "tap",
  "amt" : "1",
  "accept" : [
    {
      "tick" : "buidl",
      "amt" : "0.1"
    },
    {
      "tick" : "based",
      "amt" : "0.2"
    }
  ],
  "valid" : "900000"
}
```

As soon as the inscription above is inscribed, the trade is open and ready to be filled under the following conditions:

* All attributes are mandatory as of the example above.
* Side = 0 specifies that this is a trade function by a seller.
* The seller must own the offered token amount in the moment of filling the trade by a buyer.
* The offered token amount must be deducted from the available balances, not overall balances (available = balance - transferable).
* The tokens defined in the "accept" attribute represent accepted tokens for the trade.
* If any of the accepted tokens are being used by the buyer, the trade concludes.
* The tokens defined in the "accept" attribute must be deployed in the moment of filling the trade by a buyer.
* The block specified in the "valid" attribute must be a future block (inclusive).
* The trade is invalid and not being indexed if the current block is larger than "valid".
* Up to block 824543 and if the offered token is cursed, then the inscription has to be inscribed as cursed.
* Ticks within the "accept" attribute must be unique. Only the first will count if there is more than one of the same.
* After inscribing the function, sellers have to send the inscription to themselves to approve (tapping).

### **Cancel a Trade**

\
In order to cancel an existing, non-expired trade. The following function has to be inscribed and tapped:

```json
{
  "p" : "tap",
  "op" : "token-trade",
  "side" : "0",
  "trade" : "<inscription id>"
}
```

* All attributes are mandatory as of the example above.
* Side = 0 specifies that this is a trade function by a seller.
* The "trade" attribute has to be populated with the inscription id (*not* number) of the referenced trade inscription above.
* The trade will only cancel if the referenced trade inscription is owned by wallet address that intends to cancel.
* After a trade has been cancelled, no trades for it can occur.
* After inscribing the function, sellers have to send the inscription to themselves to approve (tapping).

### **Fill a Trade**

Valid trades are fillable by inscribing a token-trade inscription that specifies which offered token to purchase, with a reference to the original trade inscription. Additionally, an optional fee receiver may be specified. The fee receiver will earn fixed 0.3% of the token that the buyer is purchasing. The fee is applied on top of the purchase amount.

```json
{
  "p" : "tap",
  "op" : "token-trade",
  "side" : "1",
  "trade" : "<inscription id>",
  "tick" : "based",
  "amt" : "0.2",
  "fee_rcv" : "<fee receiver address>"
}
```

* Except "fee\_rcv", all attributes are mandatory as of the example above.
* Side = 1 specifies that this is a trade function by a buyer.
* The "trade" attribute must match the original trade inscription id (*not* number).
* The "tick" and "amt" attributes must exactly match one of the accepted tokens from the referenced trade inscription.
* The buyer must *not* fill all accepted tokens as of the referenced trade but exactly one.
* The ticker must be deployed in order to get the above indexed.
* The buyer must own the specified token and it's amount + 0.3% trading fees if the "fee\_rcv" attribute is set.
* If the "fee\_rcv" attribute is set, it must be a valid Bitcoin address.
* After inscribing the function, buyers have to send the inscription to themselves to approve (tapping).
* If the current block upon tapping is larger than the block in the "valid" attribute as of the referenced trade, filling will fail.
* If all conditions are met, the token and its exact amount is being sent to the seller and the offered token is being sent to the buyer. If fees apply, the fee will be sent to the fee receiver.
* Fees are only applicable on amounts and decimals that allow 0.3% to be applied. This means there may be zero fees if not applicable.


# TAP / ICP Overview

TAP Protocol supports account abstraction through authorities and therefore makes it possible to utilize programmability for platforms of your choice. Please see the extended functions for [Token Authorities ](/functions/publish-your-docs/token-authority)and [Privilege Authorities](/functions/publish-your-docs/privilege-authority) for details.

Through managing your authorities, you are able to apply algorithms and rule over the distribution of assets. Token Authorities are used to issue existing tokens, owned by the authority while Privilege Authorities manage the distribution of new assets.

### Why ICP?

While there are use-cases that allow for centralized programmability, we feel it is important to showcase how decentralized platforms can (and should) be utilized to allow for programmability with the TAP Protocol on Bitcoin L1.

One platform that is a good fit for the task is [ICP](https://internetcomputer.org/) (Internet Computer). Due to its integration with Bitcoin, you are able to directly enforce rules on the funds managed by your ICP smart contracts (called canisters).

The computation costs on ICP are extremely low, making it a very cost-effective way for users to interact with your dapps.

### Advantages

Bundling your smart contracts with TAP Readers as oracles, you'll have the currently most straightforward and most powerful tool to allow for programmability on Bitcoin L1.

Instead of modified Ord clients that try to mimic an EVM execution layer or overly complex rollup structures, this makes it possible to enable a frictionless experience for users, as there is nothing else required than a regular wallet with Ordinals support (no bridging, no L2 wallets).

Additionally, there is no need for bridging BTC. Users can transparently use their assets to perform actions on your smart contracts.

### Examples

Please check our [TAP / ICP Boilerplate](https://github.com/Trac-Systems/tap-icp-azle-boilerplate-canister) that utilizes Typescript integration and makes it even easier to create smart contracts compared to other solutions out there.&#x20;

See the diagram below that identifies the components that interact with your smart contracts:

<figure><img src="/files/KMypgQ0zENsowA4srkfh" alt=""><figcaption></figcaption></figure>


# More Chain Support

We are working hard to introduce more examples of smart contracts on other chains. Stay tuned as we are updating this section as we go.


