Skip to content

Instantly share code, notes, and snippets.

@SahidMiller
Created June 19, 2021 18:05
Show Gist options
  • Save SahidMiller/04b43c3bca5fba2264abf89039c9f24f to your computer and use it in GitHub Desktop.
Save SahidMiller/04b43c3bca5fba2264abf89039c9f24f to your computer and use it in GitHub Desktop.
Circuit-relay multihop
//https://github.com/libp2p/js-libp2p/blob/707bd7843c5b05a70916055015e3f483cc385759/src/circuit/circuit/stream-handler.js
import StreamHandler from "./stream-handler.js";
//https://github.com/libp2p/js-libp2p/blob/707bd7843c5b05a70916055015e3f483cc385759/src/circuit/protocol/index.proto
import CircuitPB from "./circuit-pb.js";
import PeerId from "peer-id";
import { Multiaddr } from "multiaddr";
import toConnection from "libp2p-utils/src/stream-to-ma-conn.js";
const PROTOCOL = "/libp2p/circuit/relay/0.1.0";
export default async function getCircuitRelay(
libp2p,
connection,
destinationId
) {
const { stream } = await connection.newStream(PROTOCOL);
const destinationPeer = PeerId.createFromCID(destinationId);
const streamHandler = new StreamHandler({ stream });
streamHandler.write({
type: CircuitPB.Type.HOP,
srcPeer: {
id: libp2p.peerId.toBytes(),
addrs: [],
},
dstPeer: {
id: destinationPeer.toBytes(),
addrs: [new Multiaddr("/p2p/" + destinationPeer.toB58String()).bytes],
},
});
const response = await streamHandler.read();
if (response && response.code === CircuitPB.Status.SUCCESS) {
const vStream = streamHandler.rest();
const maConn = toConnection({
stream: vStream,
remoteAddr: connection.remoteAddr.encapsulate(
`/p2p-circuit/p2p/${destinationId}`
),
localAddr: connection.remoteAddr.encapsulate(
`/p2p-circuit/p2p/${libp2p.peerId.toB58String()}`
),
});
return await libp2p.upgrader.upgradeOutbound(maConn);
}
}
const getCircuitRelay = require('./circuit-relay').default
/**
*
* Connect to remote node. Optional addHop param to hop using remote node.
* This stream is multihop when remote node multiaddr is a /p2p-circuit/ address and addHop id provided.
*
* @param {*} multiaddrs Multiaddrs of remote node to connect to (like libp2p.dial)
* @param {*} addHop PeerId for additional hop using remote node
* @param {*} proto Protocol to dial on resulting stream
* @returns stream for protocol
*/
const connect = (multiaddrs, addHop, proto) => {
const { libp2p } = await ipfs.createPeer();
let connection = await libp2p.dial(multiaddr);
if (addHop) {
connection = await getCircuitRelay(libp2p, connection, addHop);
}
const { stream } = connection && (await connection.newStream(proto));
return stream
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment