New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@diva.exchange/i2p-sam

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@diva.exchange/i2p-sam

I2P SAM: peer-to-peer communication between applications over I2P

  • 5.4.2
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
8.6K
decreased by-13.63%
Maintainers
1
Weekly downloads
 
Created
Source

I2P SAM

An I2P SAM library: enabling applications to communicate through the I2P network.

Long story short: I2P is an anonymous network layer allowing censorship-resistant and end-to-end-encrypted communication. I2P is a fully distributed, "privacy-by-design" peer-to-peer network.

To get I2P up and running, take a look at the project: https://github.com/diva-exchange/i2p

Use Cases

I2P is an instantly available peer-to-peer network which can be used for things like:

  • chat, social media and alike - all private and secure
  • distributed databases, aka blockchains (see https://testnet.diva.exchange as an example)
  • gaming, file sharing and ... whatever else you come up with

I2P is fully distributed, well researched and gets further developed by a competent community.

This I2P SAM library helps developers to create an I2P application quickly and hassle-free.

Get Started

npm i @diva.exchange/i2p-sam

or, lighter, without developer dependencies:

npm i --omit dev @diva.exchange/i2p-sam

Quick Start - Examples

How to Use Streams

Send an HTTP GET request to diva.i2p and output the response:

import { createStream } from '@diva.exchange/i2p-sam';

(async () => {

  const s = await createStream({
    stream: {
      destination: 'diva.i2p'
    },
    sam: {
      // your local I2P SAM host,
      // like 172.19.74.11 if you use the given test
      // docker container (see "Unit Tests" below)
      host: '127.0.0.1',
      // your local I2P SAM port, this is the default
      portTCP: 7656
    },
  });
  s.on('data', (data: Buffer) => {
    console.log('Incoming Data: ' + data.toString());
  });
  
  s.stream(Buffer.from('GET /hosts.txt HTTP/1.1\r\nHost: diva.i2p\r\n\r\n'));

})();

Forward incoming streaming data to a local socket server:

import { createStream, createForward, I2pSamStream } from '@diva.exchange/i2p-sam';
import net from 'net';

(async () => {
  const serverForward = net.createServer((c) => {
    console.debug('client connected');
    c.on('end', () => {
      console.debug('client disconnected');
    });
    c.on('data', (data: Buffer) => {
      console.debug(data.toString());
      c.write(`Hello Client!\n`);
    });
  });
  serverForward.listen(20222, '127.0.0.2');

  const samForward: I2pSamStream = await createForward({
    sam: { 
      host: '127.0.0.1',  // your local I2P SAM host
      portTCP: 7656       // your local I2P SAM port
    },
    forward: {
      host: '127.0.0.2',  // your local listener, see above
      port: 20222,        // your local listener, see above
    },
  });

  const samClient: I2pSamStream = await createStream({
    sam: { 
      host: '127.0.0.1',  // your local I2P SAM host
      portTCP: 7656       // your local I2P SAM port
    },
    stream: {
      destination: samForward.getPublicKey()
    },
  });
  // event handler
  samClient.on('data', (data: Buffer) => {
    console.debug(data.toString());
  });
  // send some data to destination
  samClient.stream(Buffer.from(`Hi Server!\n`));
})();

How to Use Reply-able Datagrams

NOTE: reply-able datagrams contain the origin of the data. An "origin" is defined as the public key of a node in the I2P network.

Send reply-able UDP messages from peer A to peer B through the I2P network:

import { createDatagram, toB32 } from '@diva.exchange/i2p-sam';

(async () => {
  // instantiate Peer A
  const peerA = await createDatagram({
    sam: {
      host: '127.0.0.1',  // your local I2P SAM host
      portTCP: 7656       // your local I2P SAM port
    }
  }); 
  
  // instantiate Peer B
  const peerB = await createDatagram({
    sam: {
      host: '127.0.0.1',  // your local I2P SAM host
      portTCP: 7656       // your local I2P SAM port
    },
    listen: { 
      address: '127.0.0.1',  // udp listener
      port: 20202            // udp listener
    }
  }).on('data', (data: Buffer, from) => {
    console.debug(`Incoming Data from ${toB32(from)}: ${data.toString()}`);
  });

    
  // send 100 messages via UDP, every 500ms a message
  // IMPORTANT: UDP is not reliable. Some messages might get lost.
  const msg: string = 'Hello World';
  await new Promise((resolve) => {
    let t = 0;
    const i = setInterval(() => {
      peerA.send(peerB.getPublicKey(), Buffer.from(`${t} ${msg}`));
      if (t++ >= 100) {
        clearInterval(i);
        resolve(true);
      }
    }, 500);
  });
})();

How to Use Raw Datagrams

NOTE: raw datagrams do not contain the "origin" of the data. A typical use case for raw datagrams: broadcasting of data. Raw datagrams are lean.

Send raw UDP messages from peer A to peer B through the I2P network:

import { createRaw } from '@diva.exchange/i2p-sam';

(async () => {
  // instantiate Peer A
  const peerA = await createRaw({
    sam: {
      host: '127.0.0.1',  // your local I2P SAM host
      portTCP: 7656       // your local I2P SAM port
    }
  }); 
  
  // instantiate Peer B
  const peerB = await createRaw({
    sam: {
      host: '127.0.0.1',  // your local I2P SAM host
      portTCP: 7656       // your local I2P SAM port
    },
    listen: { 
      address: '127.0.0.1',  // udp listener
      port: 20202            // udp listener
    }
  }).on('data', (data: Buffer) => {
    console.log('Incoming Data: ' + data.toString());
  });

  // send 100 messages via UDP, every 500ms a message
  // IMPORTANT: UDP is not reliable. Some messages might get lost.
  const msg: string = 'Hello Peer B - I am Peer A';
  await new Promise((resolve) => {
    let t = 0;
    const i = setInterval(() => {
      peerA.send(peerB.getPublicKey(), Buffer.from(`${t} ${msg}`));
      if (t++ >= 100) {
        clearInterval(i);
        resolve(true);
      }
    }, 500);
  });
})();

API

getPublicKey(): string

Get the public key of the local destination.

Example:

import { createDatagram } from '@diva.exchange/i2p-sam';

createDatagram({
  sam: {
    host: '127.0.0.1',  // your local I2P SAM host
    portTCP: 7656       // your local I2P SAM port
  }
}).then((sam) => console.log(sam.getPublicKey()));

getPrivateKey(): string

Get the private key of the local destination.

Example:

import { createDatagram } from '@diva.exchange/i2p-sam';

createDatagram({
  sam: {
    host: '127.0.0.1',  // your local I2P SAM host
    portTCP: 7656       // your local I2P SAM port
  }
}).then((sam) => console.log(sam.getPrivateKey()));

getKeyPair(): { public: string, private: string }

Get the public and private key of the local destination.

Example:

import { createStream } from '@diva.exchange/i2p-sam';

createStream({
  sam: {
    host: '127.0.0.1',  // your local I2P SAM host
    portTCP: 7656       // your local I2P SAM port
  },
  stream: {
    destination: 'diva.i2p'
  },
}).then((sam) => console.log(sam.getKeyPair()));

close()

Close a SAM connection.

Example:

import { createRaw } from '@diva.exchange/i2p-sam';

(async () => {
  const sam = await createRaw({
    sam: {
      host: '127.0.0.1',  // your local I2P SAM host
      portTCP: 7656       // your local I2P SAM port
    }
  });
  
  sam.close();
})();

toB32(destination: string): string

Convert a destination to a b32 address (without any extensions - just a Base32 string).

Example:

import { toB32 } from '@diva.exchange/i2p-sam';

console.log(toB32('[some base64-encoded destination]'));

createLocalDestination(c: Configuration): Promise<{ address: string, public: string, private: string }>

Create a new local destination and return its properties.

Example:

import { createLocalDestination } from '@diva.exchange/i2p-sam';

createLocalDestination({
  sam: {
    host: '127.0.0.1',  // your local I2P SAM host
    portTCP: 7656       // your local I2P SAM port
  }
}).then((obj) => console.log(obj));

lookup(c: Configuration, name: string): Promise<string>

Lookup (aka resolve) an I2P address (like diva.i2p or also a .b32.i2p address) to a destination. The destination, which is the public key, is a base64 encoded string.

Example:

import { lookup } from '@diva.exchange/i2p-sam';

lookup({
  sam: {
    host: '127.0.0.1',  // your local I2P SAM host
    portTCP: 7656       // your local I2P SAM port
  }
}, 'diva.i2p').then((dest) => console.log(dest));

stream(msg: Buffer)

Example: see the Get Started: How to Use Streams above.

send(destination: string, msg: Buffer)

Example: see Get Started: How to Use Datagrams above.

Configuration and its Defaults

type tSession = {
  id?: string;
  options?: string;
};

type tStream = {
  destination: string;
};

type tForward = {
  host: string;
  port: number;
  silent?: boolean;
};

type tListen = {
  address: string;
  port: number;
  hostForward?: string;
  portForward?: number;
};

type tSam = {
  host: string;
  portTCP: number;
  portUDP?: number;
  versionMin?: string;
  versionMax?: string;
  publicKey?: string;
  privateKey?: string;
  timeout?: number;
};

export type Configuration = {
  session?: tSession;
  stream?: tStream;
  forward?: tForward;
  listen?: tListen;
  sam?: tSam;
};

type ConfigurationDefault = {
  session: tSession;
  stream: tStream;
  forward: tForward;
  listen: tListen;
  sam: tSam;
};

const DEFAULT_CONFIGURATION: ConfigurationDefault = {
  session: {
    id: '',
    options: '',
  },
  stream: {
    destination: '',
  },
  forward: {
    host: '',
    port: 0,
    silent: false,
  },
  listen: {
    address: '127.0.0.1',
    port: 0,
    hostForward: '',
    portForward: 0,
  },
  sam: {
    host: '127.0.0.1',
    portTCP: 7656,
    portUDP: 7655,
    versionMin: '',
    versionMax: '',
    publicKey: '',
    privateKey: '',
    timeout: 300,
  },
};

Events

data

Incoming data.

error

Generic Error event - emitted if sockets report errors.

import { createRaw } from '@diva.exchange/i2p-sam';

(async () => {
  const sam = await createRaw({
    sam: {
      host: '127.0.0.1',  // your local I2P SAM host
      portTCP: 7656       // your local I2P SAM port
    }
  });
  sam.on('error', (error) => console.debug(error));
})();
close

Emitted if one of the involved sockets got closed.

How to Run Unit Tests

Assumptions:

  1. git, node and npm is available.
  2. docker and docker-compose is available.

Clone the source code from git git clone https://github.com/diva-exchange/i2p-sam.git and enter the folder i2p-sam.

Prepare the test environment by creating the docker container:

docker compose -f test/sam.diva.i2p.yml up -d

Check whether the I2P test node is properly running by accessing the local console on: http://172.19.74.11:7070.

To modify the IP address of the local console, adapt the file test/sam.diva.i2p.yml.

After the docker container is running for about five minutes (reason: the I2P network needs some minutes to integrate), execute the unit tests:

npm run test

Executing the unit tests will take around 5 minutes. Reason: the communication via I2P gets tested - which is the purpose of this library.

Stop the container (and purge all data within):

docker compose -f test/sam.diva.i2p.yml down --volumes

Linting

To lint the code, use

npm run lint

Contributions

Contributions are very welcome. This is the general workflow:

  1. Fork from https://github.com/diva-exchange/divachain/
  2. Pull the forked project to your local developer environment
  3. Make your changes, test, commit and push them
  4. Create a new pull request on github.com

It is strongly recommended to sign your commits: https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key

If you have questions, please just contact us (see below).

Donations

Your donation goes entirely to the project. Your donation makes the development of DIVA.EXCHANGE faster. Thanks a lot.

XMR

42QLvHvkc9bahHadQfEzuJJx4ZHnGhQzBXa8C9H3c472diEvVRzevwpN7VAUpCPePCiDhehH4BAWh8kYicoSxpusMmhfwgx

XMR

or via https://www.diva.exchange/en/join-in/

BTC

3Ebuzhsbs6DrUQuwvMu722LhD8cNfhG1gs

BTC

Contact the Developers

On DIVA.EXCHANGE you'll find various options to get in touch with the team.

Talk to us via Telegram (English or German).

References

SAM docs: https://geti2p.net/en/docs/api/samv3

I2Pd: https://i2pd.readthedocs.io/

License

APACHE 2.0

Keywords

FAQs

Package last updated on 30 Jan 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc