# Circuit Control II

Now that we've used the **AnonControlClient** to see some circuit info, lets use it to assemble circuits with a little more customization!

<details>

<summary>Aside: Relay Fingerprints and Circuits</summary>

**Fingerprints**\
All relays have a unique identifier known as a fingerprint. Within the clients, authorities and even on-chain, the fingerprint is a relay's foremost identifier (even ahead of it's IP address). When selecting relays to build a circuit through, the fingerprint is how you specify them.

{% code title="Example Fingerprint" %}

```
41B78C1198702625B30FB225AE37AAC0B2FA4ED

```

{% endcode %}

**Circuits**\
A chain of relays that continually decrypt packets between an Anyone client and its destination (website or hidden service) is called a circuit.&#x20;

The default onion routing circuit in the Anyone Network is 3 hops- an Entry relay, Middle relay and Exit relay. This model provides a certain level of defence against malicious relays, as a single relay does not have enough information to deanonymize a user.&#x20;

However, circuits of any length can be constructed, including just one relay. However, if used to visit public websites, one of the relays must be an Exit.&#x20;

</details>

### Creating a Random Circuit&#x20;

We will be introducing the function `extendCircuits` , which is used to negotiate a new circuit. If no arguments are passed, `extendCircuits` will select a circuit using the default, randomized selection process, and return a circuit ID number.&#x20;

```javascript
const circuitID = await anonControlClient.extendCircuit();
console.log("Randomly created circuit:", circuitID);
```

This circuit ID can then be used to manage it further, including closing that specific circuit:

```javascript
await anonControlClient.closeCircuit(circuitID)
```

### Creating a Manual Circuit

The `extendCircuit` function can also take in an object structured like below, specifying the relays in order by fingerprint:

```javascript
{
    serverSpecs: [
        "41E262A8DAFB34B7AD5F82280813584101E2A47A",
        "41ADDE21CDCE614FF35DA58CDC15BC7A4A6DFE4D"
    ]
}
```

As is evident, it is not essential to specify a path of exactly three relays. So long as the first fingerprint has the `Guard` flag (which means the relay can act as an entry relay) and the final fingerprint has the `Exit` flag (which means it's able to forward your traffic over the clear-web), the circuit can be of any length. It can even consist of a single node, so long as that relay can be both an Entry and Exit node! &#x20;

How do we find the available fingerprints and the information needed to build a circuit from them? We have recently rolled out a new function in the NPM SDK: `routerStatus` that does exactly that!

#### Using the routerStatus Function

Note: Ensure that you have updated your npm client by running `npm update` within the working directory after it has been setup, to have access to this new function. Once the control client is setup, the new function simply needs to be called asynchronously:

```javascript
const routerStatus = await anonControlClient.routerStatus();
console.log(JSON.stringify(routerStatus, null, 2));
```

Once the promise is resolved, the function returns a JSON file listing. Let's have a look at its format:

```json
{
    "nickname": "AnyoneRelay02",
    "fingerprint": "Dz8wKhDvPf0z8Y1PCoWm9q3eMSE",
    "digest": "xBuwTXYjA2HoNP5jum/aJ4QPqCg",
    "publishedTime": "2038-01-01T00:00:00.000Z",
    "ip": "162.55.183.223",
    "orPort": 9001,
    "dirPort": 0,
    "flags": [
      "Fast",
      "Guard",
      "HSDir",
      "Running",
      "Stable",
      "V2Dir",
      "Valid"
    ],
    "bandwidth": 38000
},
{
  "nickname": "DeadZone",
```

Relays are listed in order, and have their own object which includes information on its IP, bandwidth and flags!

{% hint style="warning" %}
The introduction of custom circuits and the ability to build them based on manual criteria opens up a huge range of potential applications, including the use of algorithms and AI to create circuits. However, it also shifts the risk of de-anonymization onto you - the application developer - and subsequently your users. \
\
Be wary of the centralization risks of choosing circuits from a limited set of circuits, and look out for algorithms developed by the community to get the best of both worlds!
{% endhint %}

&#x20;


---

# 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.anyone.io/sdk/npm/tutorials/circuit-control-ii.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.
