# Quickstart (Testnet)

In just a few minutes you will able to:

* **Define decryption conditions** – these are predefined rules or criteria that must be fulfilled before the encrypted data can be decrypted.
* **Encrypt data & assign decryption conditions** – when you encrypt data, you not only secure it but also tie the decryption process to the conditions you defined.
* **Threshold-decrypt data** – once the decryption conditions are met and validated by a threshold of TACo nodes, decryption can occur.

### 1. Installation

Install `taco` , `taco-auth`, and `ethers` with your favorite package manager:

<pre class="language-bash"><code class="lang-bash"><strong>$ npm install @nucypher/taco @nucypher/taco-auth ethers@5.7.2
</strong></code></pre>

{% hint style="warning" %}
TACo currently requires **ethers v5**. The API is not compatible with ethers v6 (`ethers.BrowserProvider`, `ethers.JsonRpcProvider` without the `providers` namespace, etc.).
{% endhint %}

### 2. Configuration

To run the code examples below, you will need the `ritualId` encryption parameter. **In production**, your wallet address (encryptor) will also have to be allow-listed for this specific ritual. Please reach out to us [here](https://discord.com/channels/411401661714792449/1344417143659171991) to receive a `ritualId` and allow-list access.\
\
Additionally, we have [publicly available testnet rituals](/for-developers/get-started-with-tac.md#threshold-decryption) for use when developing your apps.

### 3. Define decryption condition and encrypt data

With `ritualId` and [a web3 provider from `ethers`](https://docs.ethers.org/v5/api/providers/#providers-getDefaultProvider), we can `taco.encrypt` our data.

In this example, we will use our [`lynx` testnet](/for-developers/get-started-with-tac.md#threshold-decryption), where you can freely use `ritualId = 27`.

{% hint style="info" %}
The `polygonProvider` below connects to **Polygon Amoy** — this is where TACo's DKG coordination contracts live. It is **not** your application's chain provider. Your conditions can still target any supported EVM chain (Ethereum, Sepolia, etc.) regardless of this provider.
{% endhint %}

The `signerProvider` is required to [authenticate](/for-developers/taco-sdk/references/authentication.md) the Encryptor.

<pre class="language-typescript"><code class="lang-typescript">import { initialize, encrypt, conditions, domains } from '@nucypher/taco';
import { ethers } from "ethers";

// We have to initialize the TACo library first
await initialize();

// Define decryption condition
const ownsNFT = new conditions.predefined.erc721.ERC721Ownership({
  contractAddress: '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77',
  parameters: [3591],
  chain: 11155111,  // sepolia
});

const signerProvider = new ethers.providers.Web3Provider(window.ethereum);
const polygonProvider = new ethers.providers.JsonRpcProvider("https://polygon-amoy.drpc.org");

const message = "my secret message";
const ritualId = 27

// encrypt data
const messageKit = await encrypt(
<strong>  polygonProvider,
</strong><strong>  domains.DEVNET,
</strong>  message,
  ownsNFT,
  ritualId,
  signerProvider.getSigner() 
);
</code></pre>

### 4. Decrypt the data

Now we just have to pass the `messageKit` to the intended *data consumer*:

<pre class="language-typescript"><code class="lang-typescript"><strong>import { conditions, decrypt, domains, initialize } from '@nucypher/taco';
</strong>import { EIP4361AuthProvider, USER_ADDRESS_PARAM_DEFAULT } from '@nucypher/taco-auth';
import { ethers } from "ethers";

// We have to initialize the TACo library first
await initialize();

const web3Provider = new ethers.providers.Web3Provider(window.ethereum); 

const conditionContext =
  conditions.context.ConditionContext.fromMessageKit(messageKit);
  
// auth provider when condition contains ":userAddress" context variable
// the decryptor user must provide a signature to prove ownership of their wallet address
const authProvider = new EIP4361AuthProvider(
  web3Provider,
  web3Provider.getSigner(),
);
conditionContext.addAuthProvider(USER_ADDRESS_PARAM_DEFAULT, authProvider);

const decryptedMessage = await decrypt(
  web3Provider,
  domains.DEVNET,
  messageKit,
  conditionContext,
);
</code></pre>

Since `ownsNFT` condition refers to an NFT owned by the *data consumer*, `decrypt` call will prompt the recipient to sign a message and prove the ownership of the caller's wallet.

### Next steps

Learn more about using TACo in a sandboxed environment in the [Testnet](/for-developers/get-started-with-tac.md) section.

### Example applications

The following samples showcase integrations with React-based web apps, and serve as an 'end-to-end' reference for creating conditions-based encryption & decryption:

* [`taco-web/demos`](https://github.com/nucypher/taco-web/tree/main/demos)
* [`taco-web/examples/taco`](https://github.com/nucypher/taco-web/tree/main/examples/taco)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.taco.build/for-developers/access-control/quickstart-testnet.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
