Circuit Control I

So far, we've seen two libraries as part of the Anyone NPM SDK:

  • Anon - the Anyone Client, which negotiates and maintains circuits through the network and runs a proxy server to forward traffic

  • AnonSocksClient - used in place of a typical requests library to forward get, post and other methods to the Anyone client!

Now, we will introduce one of the most powerful libraries - AnonControlClient - which interacts with the control port of the Anyone client and provides a new level of configurability. You can see circuit information that is hidden from most applications, send commands and manage circuits. Let's dive in!

Starting and Authenticating

For obvious reasons, not every app running locally alongside the Anyone Client can see or modify its behavior. Processes need to authenticate themselves on the client's control port and the AnonControlClient is no exception. Let's import it, much like the other libraries.

import { AnonControlClient } from "@anyone-protocol/anyone-client"; 

The control client is then instantiated much like anon, specifying the host and port number of the client to bind to. 127.0.0.1 and 9051 are the default values and will work with the default Anon object.

const anonControlClient = new AnonControlClient(); 

// You can also specify your host and port:
// const anonControlClient = new AnonControlClient(host: '127.0.0.1', port: 9051);

From there, assuming you have anon running anywhere in the local network, authenticating to the control port is simple

await anonControlClient.authenticate();

Let's create a new file control.js and put this all together. Notice that, unlike the SOCKS client, the AnonControlClient is only instantiated after we have given the Anyone client time to establish itself. In addition, best practices are also to call .end() on the control client once it is complete.

control.js
import { Anon } from "@anyone-protocol/anyone-client";
import { AnonControlClient } from "@anyone-protocol/anyone-client";


async function main() {
   const anon = new Anon();
   
    try {
        await anon.start();
        await new Promise(resolve => setTimeout(resolve, 12000));

        const anonControlClient = new AnonControlClient(); 
        await anonControlClient.authenticate() 
        
        anonControlClient.end()
        
    } catch(error) {
        console.log(error)
    } finally {
        
        await anon.stop()
    }
}

main()

Running node control.js should yield the following success message:

Reading Circuit Info

Now that we have authenticated, lets see what circuits have been created. The Anyone client often maintains multiple circuits within the network, and these can be seen as a JSON file with the circuitsStatus() function.

const circuits = await anonControlClient.circuitStatus();
console.log(JSON.stringify(circuits, null, 2));

Adding the above two lines after .authenticate and running as before will see a new JSON file outputted, like below:

[{
    "circuitId": 1,
    "state": "BUILT",
    "relays": [
      {
        "fingerprint": "54849A361F8CED0D1B70B722CB8B33E9071E5561",
        "nickname": "ATORDAuselive"
      }
    ],
    "buildFlags": [
      "ONEHOP_TUNNEL",
      "IS_INTERNAL",
      "NEED_CAPACITY"
    ],
    "purpose": "GENERAL",
    "timeCreated": "2024-11-08T12:10:46.596Z"
  },
...

This shows a list of objects, each representing a single circuit - that shows the circuit's status and the first relay within it!

To get further relay info, you could call getRelayInfo

const relayInfo0 = await anonControlClient.getRelayInfo(circuits[0].relays[0].fingerprint);
console.log('Relay [0] info:', relayInfo0);

Last updated