From 8c2ce80e41e2b935e27f71f076545ec409f83e18 Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sun, 28 Apr 2024 08:31:31 +0000 Subject: [PATCH 1/2] chore(rosenet-node): refactor file structure Update file names, paths, variable names and more. --- .devcontainer/devcontainer.json | 5 ++++ .../RoseNetNodeContext.ts} | 4 +-- .../rosenet-node/lib/createRoseNetNode.ts | 27 ++++++++++--------- .../{pushable.ts => stream/createPushable.ts} | 0 .../stream-service.ts} | 16 ++++++----- .../rosenet-node/lib/{ => utils}/codec.ts | 0 .../createPushable.spec.ts} | 2 +- .../tests/{ => utils}/codec.spec.ts | 2 +- 8 files changed, 33 insertions(+), 23 deletions(-) rename packages/rosenet-node/lib/{RoseNetNodeTools.ts => context/RoseNetNodeContext.ts} (72%) rename packages/rosenet-node/lib/{pushable.ts => stream/createPushable.ts} (100%) rename packages/rosenet-node/lib/{getStreamAndPushable.ts => stream/stream-service.ts} (88%) rename packages/rosenet-node/lib/{ => utils}/codec.ts (100%) rename packages/rosenet-node/tests/{pushable.spec.ts => stream/createPushable.spec.ts} (91%) rename packages/rosenet-node/tests/{ => utils}/codec.spec.ts (96%) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 49fadd2..bed8080 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -21,8 +21,13 @@ "terminal.integrated.defaultProfile.linux": "zsh", "terminal.integrated.profiles.linux": { "zsh": { "path": "/bin/zsh" } }, }, + "extensions": ["hashicorp.terraform"], }, }, + "features": { + "ghcr.io/robbert229/devcontainer-features/opentofu:1": {}, + "ghcr.io/devcontainers/features/docker-in-docker:2": {}, + }, // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. // "remoteUser": "root" diff --git a/packages/rosenet-node/lib/RoseNetNodeTools.ts b/packages/rosenet-node/lib/context/RoseNetNodeContext.ts similarity index 72% rename from packages/rosenet-node/lib/RoseNetNodeTools.ts rename to packages/rosenet-node/lib/context/RoseNetNodeContext.ts index 0100319..01eb7a5 100644 --- a/packages/rosenet-node/lib/RoseNetNodeTools.ts +++ b/packages/rosenet-node/lib/context/RoseNetNodeContext.ts @@ -1,10 +1,10 @@ import { AbstractLogger } from '@rosen-bridge/logger-interface'; -const RoseNetNodeTools = { +const RoseNetNodeContext = { logger: console as AbstractLogger, init(logger: AbstractLogger) { this.logger = logger; }, }; -export default RoseNetNodeTools; +export default RoseNetNodeContext; diff --git a/packages/rosenet-node/lib/createRoseNetNode.ts b/packages/rosenet-node/lib/createRoseNetNode.ts index 7d5367a..ac176bf 100644 --- a/packages/rosenet-node/lib/createRoseNetNode.ts +++ b/packages/rosenet-node/lib/createRoseNetNode.ts @@ -16,9 +16,9 @@ import { privateKeyToPeerId, } from '@rosen-bridge/rosenet-utils'; -import { decode, encode } from './codec'; -import getStreamAndPushable from './getStreamAndPushable'; -import RoseNetNodeTools from './RoseNetNodeTools'; +import { decode, encode } from './utils/codec'; +import streamService from './stream/stream-service'; +import RoseNetNodeContext from './context/RoseNetNodeContext'; import RoseNetNodeError from './errors/RoseNetNodeError'; @@ -36,7 +36,7 @@ const createRoseNetNode = async ({ logger, ...config }: RoseNetNodeConfig) => { throw new RoseNetNodeError('Cannot start a RoseNet node without a relay'); } - RoseNetNodeTools.init(logger); + RoseNetNodeContext.init(logger); /** * return if a peer is unauthorized, i.e. not whitelisted @@ -47,7 +47,7 @@ const createRoseNetNode = async ({ logger, ...config }: RoseNetNodeConfig) => { const peerId = await privateKeyToPeerId(config.privateKey); - RoseNetNodeTools.logger.debug(`PeerId ${peerId.toString()} generated`); + RoseNetNodeContext.logger.debug(`PeerId ${peerId.toString()} generated`); const node = await createLibp2p({ peerId, @@ -85,20 +85,23 @@ const createRoseNetNode = async ({ logger, ...config }: RoseNetNodeConfig) => { pubsub: gossipsub({ allowPublishToZeroPeers: true }), }, }); - RoseNetNodeTools.logger.debug('RoseNet node created'); + RoseNetNodeContext.logger.debug('RoseNet node created'); - addEventListeners(node, RoseNetNodeTools.logger); + addEventListeners(node, RoseNetNodeContext.logger); return { start: async () => node.start(), sendMessage: async (to: string, message: string) => { - const { stream, pushable } = await getStreamAndPushable(to, node); + const { stream, pushable } = await streamService.getStreamAndPushable( + to, + node, + ); pipe(pushable, (source) => map(source, encode), stream); pushable.push(message); await Promise.resolve(); - RoseNetNodeTools.logger.debug('message piped through created stream', { + RoseNetNodeContext.logger.debug('message piped through created stream', { message, }); }, @@ -108,7 +111,7 @@ const createRoseNetNode = async ({ logger, ...config }: RoseNetNodeConfig) => { node.handle( ROSENET_DIRECT_PROTOCOL_V1, async ({ connection, stream }) => { - RoseNetNodeTools.logger.debug( + RoseNetNodeContext.logger.debug( `incoming connection stream with protocol ${ROSENET_DIRECT_PROTOCOL_V1}`, { remoteAddress: connection.remoteAddr.toString(), @@ -118,7 +121,7 @@ const createRoseNetNode = async ({ logger, ...config }: RoseNetNodeConfig) => { pipe(stream, decode, async (source) => { for await (const message of source) { await handler(connection.remotePeer.toString(), message); - RoseNetNodeTools.logger.debug( + RoseNetNodeContext.logger.debug( 'incoming message handled successfully', { message, @@ -129,7 +132,7 @@ const createRoseNetNode = async ({ logger, ...config }: RoseNetNodeConfig) => { }, { runOnTransientConnection: true }, ); - RoseNetNodeTools.logger.debug( + RoseNetNodeContext.logger.debug( `handler for ${ROSENET_DIRECT_PROTOCOL_V1} protocol set`, ); }, diff --git a/packages/rosenet-node/lib/pushable.ts b/packages/rosenet-node/lib/stream/createPushable.ts similarity index 100% rename from packages/rosenet-node/lib/pushable.ts rename to packages/rosenet-node/lib/stream/createPushable.ts diff --git a/packages/rosenet-node/lib/getStreamAndPushable.ts b/packages/rosenet-node/lib/stream/stream-service.ts similarity index 88% rename from packages/rosenet-node/lib/getStreamAndPushable.ts rename to packages/rosenet-node/lib/stream/stream-service.ts index 24e8e0e..2022735 100644 --- a/packages/rosenet-node/lib/getStreamAndPushable.ts +++ b/packages/rosenet-node/lib/stream/stream-service.ts @@ -3,10 +3,10 @@ import { peerIdFromString } from '@libp2p/peer-id'; import { shuffle } from 'fast-shuffle'; import { Libp2p } from 'libp2p'; -import RoseNetNodeTools from './RoseNetNodeTools'; -import createPushable, { Pushable } from './pushable'; +import RoseNetNodeContext from '../context/RoseNetNodeContext'; +import createPushable, { Pushable } from './createPushable'; -import { ROSENET_DIRECT_PROTOCOL_V1 } from './constants'; +import { ROSENET_DIRECT_PROTOCOL_V1 } from '../constants'; const cache = new Map< string, @@ -33,7 +33,7 @@ const isStreamWritable = (stream: Stream) => async function getStreamAndPushable(to: string, node: Libp2p) { const cacheHit = cache.get(to); if (cacheHit && isStreamWritable(cacheHit.stream)) { - RoseNetNodeTools.logger.debug( + RoseNetNodeContext.logger.debug( `Found existing stream and pushable in the cache to peer ${to}`, { stream: { @@ -55,7 +55,7 @@ async function getStreamAndPushable(to: string, node: Libp2p) { ); const connection = possibleOpenConnectionToPeer ?? (await node.dial(peerId)); - RoseNetNodeTools.logger.debug( + RoseNetNodeContext.logger.debug( possibleOpenConnectionToPeer ? `Found an open connection to peer ${to}` : `Established a new connection to peer ${to}`, @@ -80,7 +80,7 @@ async function getStreamAndPushable(to: string, node: Libp2p) { runOnTransientConnection: true, })); - RoseNetNodeTools.logger.debug( + RoseNetNodeContext.logger.debug( possibleWritableStream ? `Found an open stream to peer ${to}` : `Created a new stream to peer ${to}`, @@ -106,4 +106,6 @@ async function getStreamAndPushable(to: string, node: Libp2p) { return pair; } -export default getStreamAndPushable; +export default { + getStreamAndPushable, +}; diff --git a/packages/rosenet-node/lib/codec.ts b/packages/rosenet-node/lib/utils/codec.ts similarity index 100% rename from packages/rosenet-node/lib/codec.ts rename to packages/rosenet-node/lib/utils/codec.ts diff --git a/packages/rosenet-node/tests/pushable.spec.ts b/packages/rosenet-node/tests/stream/createPushable.spec.ts similarity index 91% rename from packages/rosenet-node/tests/pushable.spec.ts rename to packages/rosenet-node/tests/stream/createPushable.spec.ts index 8d734af..14e341a 100644 --- a/packages/rosenet-node/tests/pushable.spec.ts +++ b/packages/rosenet-node/tests/stream/createPushable.spec.ts @@ -1,6 +1,6 @@ import { it, describe, expect } from 'vitest'; -import createPushable, { Pushable } from '../lib/pushable'; +import createPushable, { Pushable } from '../../lib/stream/createPushable'; /** * delegate to the pushable parameter, essentially returning an iterator from diff --git a/packages/rosenet-node/tests/codec.spec.ts b/packages/rosenet-node/tests/utils/codec.spec.ts similarity index 96% rename from packages/rosenet-node/tests/codec.spec.ts rename to packages/rosenet-node/tests/utils/codec.spec.ts index ced71fc..1abdb5f 100644 --- a/packages/rosenet-node/tests/codec.spec.ts +++ b/packages/rosenet-node/tests/utils/codec.spec.ts @@ -2,7 +2,7 @@ import first from 'it-first'; import { Uint8ArrayList } from 'uint8arraylist'; import { describe, expect, it } from 'vitest'; -import { decode, encode } from '../lib/codec'; +import { decode, encode } from '../../lib/utils/codec'; const message = 'hello world'; const lengthPrefixByteArray = Uint8Array.from([message.length]); From 867f0501d8b674fce985029cabdbdd5db787103e Mon Sep 17 00:00:00 2001 From: Mohammad Kermani Date: Sun, 28 Apr 2024 13:16:52 +0000 Subject: [PATCH 2/2] feat(rosenet-node): announce public ip --- .changeset/thick-rabbits-look.md | 5 + package-lock.json | 450 +++++++++++++++++- .../lib/address/address-service.ts | 29 ++ packages/rosenet-node/lib/constants.ts | 1 + .../rosenet-node/lib/createRoseNetNode.ts | 21 +- packages/rosenet-node/lib/types.ts | 1 + packages/rosenet-node/package.json | 4 +- .../tests/address/address-service.spec.ts | 29 ++ 8 files changed, 531 insertions(+), 9 deletions(-) create mode 100644 .changeset/thick-rabbits-look.md create mode 100644 packages/rosenet-node/lib/address/address-service.ts create mode 100644 packages/rosenet-node/tests/address/address-service.spec.ts diff --git a/.changeset/thick-rabbits-look.md b/.changeset/thick-rabbits-look.md new file mode 100644 index 0000000..7dd26e4 --- /dev/null +++ b/.changeset/thick-rabbits-look.md @@ -0,0 +1,5 @@ +--- +'@rosen-bridge/rosenet-node': minor +--- + +announce public ip diff --git a/package-lock.json b/package-lock.json index 93f061b..8a11963 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1794,6 +1794,11 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" + }, "node_modules/@libp2p/bootstrap": { "version": "10.0.15", "resolved": "https://registry.npmjs.org/@libp2p/bootstrap/-/bootstrap-10.0.15.tgz", @@ -2227,6 +2232,20 @@ "node": ">=6 <7 || >=8" } }, + "node_modules/@multiformats/dns": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@multiformats/dns/-/dns-1.0.6.tgz", + "integrity": "sha512-nt/5UqjMPtyvkG9BQYdJ4GfLK3nMqGpFZOzf4hAmIa0sJh2LlS9YKXZ4FgwBDsaHvzZqR/rUFIywIc7pkHNNuw==", + "dependencies": { + "@types/dns-packet": "^5.6.5", + "buffer": "^6.0.3", + "dns-packet": "^5.6.1", + "hashlru": "^2.3.0", + "p-queue": "^8.0.1", + "progress-events": "^1.0.0", + "uint8arrays": "^5.0.2" + } + }, "node_modules/@multiformats/mafmt": { "version": "12.1.6", "resolved": "https://registry.npmjs.org/@multiformats/mafmt/-/mafmt-12.1.6.tgz", @@ -2547,6 +2566,28 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, + "node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -2571,12 +2612,25 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@types/dns-packet": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/@types/dns-packet/-/dns-packet-5.6.5.tgz", + "integrity": "sha512-qXOC7XLOEe43ehtWJCMnQXvgcIpv6rPmQ1jXT98Ad8A3TB1Ue50jsCbSSSyuazScEuZ/Q026vHbrOTVkmwA+7Q==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -2599,7 +2653,6 @@ "version": "20.11.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.13.tgz", "integrity": "sha512-5G4zQwdiQBSWYTDAH1ctw2eidqdhMJaNsiIDKHFr55ihz5Trl2qqR8fdrT732yPBho5gkNxXm67OxWFBqX9aPg==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -3225,6 +3278,25 @@ "dev": true, "license": "MIT" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/better-path-resolve": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", @@ -3298,6 +3370,29 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -3307,6 +3402,31 @@ "node": ">=8" } }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, "node_modules/call-bind": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", @@ -3709,6 +3829,31 @@ "node": ">=0.10.0" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -3738,6 +3883,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, "node_modules/define-data-property": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", @@ -3836,6 +3989,28 @@ "receptacle": "^1.3.2" } }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dns-socket": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/dns-socket/-/dns-socket-4.2.2.tgz", + "integrity": "sha512-BDeBd8najI4/lS00HSKpdFia+OvUMytaVjfzR9n5Lq8MlZRSvtbI+uLtx1+XmQFls5wFU9dssccTmQQ6nfpjdg==", + "dependencies": { + "dns-packet": "^5.2.4" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/doctrine": { "version": "3.0.0", "dev": true, @@ -4465,6 +4640,14 @@ "is-callable": "^1.1.3" } }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "engines": { + "node": ">= 14.17" + } + }, "node_modules/fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", @@ -4585,7 +4768,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, "engines": { "node": ">=10" }, @@ -4702,6 +4884,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4796,6 +5002,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hashlru": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/hashlru/-/hashlru-2.3.0.tgz", + "integrity": "sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A==" + }, "node_modules/hasown": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", @@ -4820,6 +5031,34 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/human-id": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", @@ -4861,6 +5100,25 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "dev": true, @@ -4943,6 +5201,17 @@ "node": ">= 0.4" } }, + "node_modules/ip-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-5.0.0.tgz", + "integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -5065,6 +5334,20 @@ "node": ">=0.10.0" } }, + "node_modules/is-ip": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-4.0.0.tgz", + "integrity": "sha512-4B4XA2HEIm/PY+OSpeMBXr8pGWBYbXuHgjMAqrwbLO3CPTCAd9ArEJzBUKGZtk9viY6+aSfadGnWyjY3ydYZkw==", + "dependencies": { + "ip-regex": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-loopback-addr": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-loopback-addr/-/is-loopback-addr-2.0.2.tgz", @@ -5522,6 +5805,11 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -5566,6 +5854,14 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -5994,6 +6290,17 @@ "get-func-name": "^2.0.1" } }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "dev": true, @@ -6151,6 +6458,17 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -6300,6 +6618,17 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/npm-run-path": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", @@ -6425,6 +6754,14 @@ "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", "dev": true }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "engines": { + "node": ">=12.20" + } + }, "node_modules/p-defer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.0.tgz", @@ -6872,6 +7209,74 @@ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true }, + "node_modules/public-ip": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/public-ip/-/public-ip-6.0.2.tgz", + "integrity": "sha512-+6bkjnf0yQ4+tZV0zJv1017DiIF7y6R4yg17Mrhhkc25L7dtQtXWHgSCrz9BbLL4OeTFbPK4EALXqJUrwCIWXw==", + "dependencies": { + "aggregate-error": "^4.0.1", + "dns-socket": "^4.2.2", + "got": "^12.1.0", + "is-ip": "^4.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/public-ip/node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/public-ip/node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/public-ip/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/public-ip/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -7165,6 +7570,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -7174,6 +7584,20 @@ "node": ">=4" } }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/restore-cursor": { "version": "3.1.0", "dev": true, @@ -8307,8 +8731,7 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/universalify": { "version": "0.1.2", @@ -8952,13 +9375,15 @@ "@libp2p/peer-id": "^4.0.6", "@libp2p/pubsub-peer-discovery": "^10.0.2", "@libp2p/tcp": "^9.0.15", + "@multiformats/multiaddr": "^12.2.1", "@rosen-bridge/rosenet-utils": "^0.0.0", "fast-shuffle": "^6.1.0", "it-first": "^3.0.4", "it-length-prefixed": "^9.0.4", "it-map": "^3.0.5", "it-pipe": "^3.0.1", - "libp2p": "^1.2.3" + "libp2p": "^1.2.3", + "public-ip": "^6.0.2" }, "devDependencies": { "@types/node": "^20.11.9", @@ -8978,6 +9403,20 @@ "node": ">=20.11.0" } }, + "packages/rosenet-node/node_modules/@multiformats/multiaddr": { + "version": "12.2.1", + "resolved": "https://registry.npmjs.org/@multiformats/multiaddr/-/multiaddr-12.2.1.tgz", + "integrity": "sha512-UwjoArBbv64FlaetV4DDwh+PUMfzXUBltxQwdh+uTYnGFzVa8ZfJsn1vt1RJlJ6+Xtrm3RMekF/B+K338i2L5Q==", + "dependencies": { + "@chainsafe/is-ip": "^2.0.1", + "@chainsafe/netmask": "^2.0.0", + "@libp2p/interface": "^1.0.0", + "@multiformats/dns": "^1.0.3", + "multiformats": "^13.0.0", + "uint8-varint": "^2.0.1", + "uint8arrays": "^5.0.0" + } + }, "packages/rosenet-node/node_modules/@vitest/coverage-v8": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.3.0.tgz", @@ -9596,6 +10035,7 @@ } }, "tests/scaling-peer-discovery": { + "name": "@rosenet-tests/scaling-peer-discovery", "version": "0.0.0", "license": "GPL-3.0", "dependencies": { diff --git a/packages/rosenet-node/lib/address/address-service.ts b/packages/rosenet-node/lib/address/address-service.ts new file mode 100644 index 0000000..0fdc47c --- /dev/null +++ b/packages/rosenet-node/lib/address/address-service.ts @@ -0,0 +1,29 @@ +import { isIP } from 'node:net'; + +import { fromNodeAddress } from '@multiformats/multiaddr'; +import { publicIp } from 'public-ip'; + +/** + * identify public ip (v4 or v6) of current node + */ +const identifyPublicIP = () => publicIp(); + +/** + * get multiaddr containing public ip of current node, to be used as announce + * address + */ +const getAnnounceMultiaddr = async (port: number) => { + const ip = await identifyPublicIP(); + const ipVersion = isIP(ip); + + const multiaddr = fromNodeAddress( + { address: ip, family: ipVersion as 4 | 6, port }, + 'tcp', + ); + + return multiaddr.toString(); +}; + +export default { + getAnnounceMultiaddr, +}; diff --git a/packages/rosenet-node/lib/constants.ts b/packages/rosenet-node/lib/constants.ts index 791e232..65a330f 100644 --- a/packages/rosenet-node/lib/constants.ts +++ b/packages/rosenet-node/lib/constants.ts @@ -1,2 +1,3 @@ export const RELAYS_COUNT_TO_CONNECT = 3; export const ROSENET_DIRECT_PROTOCOL_V1 = '/rosenet/direct/1'; +export const DEFAULT_NODE_PORT = 55123; diff --git a/packages/rosenet-node/lib/createRoseNetNode.ts b/packages/rosenet-node/lib/createRoseNetNode.ts index ac176bf..c7a1000 100644 --- a/packages/rosenet-node/lib/createRoseNetNode.ts +++ b/packages/rosenet-node/lib/createRoseNetNode.ts @@ -16,13 +16,17 @@ import { privateKeyToPeerId, } from '@rosen-bridge/rosenet-utils'; -import { decode, encode } from './utils/codec'; -import streamService from './stream/stream-service'; import RoseNetNodeContext from './context/RoseNetNodeContext'; +import addressService from './address/address-service'; +import streamService from './stream/stream-service'; + +import { decode, encode } from './utils/codec'; + import RoseNetNodeError from './errors/RoseNetNodeError'; import { + DEFAULT_NODE_PORT, RELAYS_COUNT_TO_CONNECT, ROSENET_DIRECT_PROTOCOL_V1, } from './constants'; @@ -31,7 +35,11 @@ import packageJson from '../package.json' with { type: 'json' }; import { RoseNetNodeConfig } from './types'; -const createRoseNetNode = async ({ logger, ...config }: RoseNetNodeConfig) => { +const createRoseNetNode = async ({ + logger, + port = DEFAULT_NODE_PORT, + ...config +}: RoseNetNodeConfig) => { if (!config.relayMultiaddrs.length) { throw new RoseNetNodeError('Cannot start a RoseNet node without a relay'); } @@ -49,6 +57,9 @@ const createRoseNetNode = async ({ logger, ...config }: RoseNetNodeConfig) => { RoseNetNodeContext.logger.debug(`PeerId ${peerId.toString()} generated`); + const announceMultiaddr = await addressService.getAnnounceMultiaddr(port); + logger.info(`${announceMultiaddr} set as announce multiaddr`); + const node = await createLibp2p({ peerId, transports: [ @@ -57,6 +68,10 @@ const createRoseNetNode = async ({ logger, ...config }: RoseNetNodeConfig) => { }), tcp(), ], + addresses: { + listen: [`/ip4/0.0.0.0/tcp/${port}`], + announce: [announceMultiaddr], + }, connectionEncryption: [noise()], connectionGater: { ...(config.whitelist && { diff --git a/packages/rosenet-node/lib/types.ts b/packages/rosenet-node/lib/types.ts index b3feffd..5de3b84 100644 --- a/packages/rosenet-node/lib/types.ts +++ b/packages/rosenet-node/lib/types.ts @@ -4,5 +4,6 @@ export interface RoseNetNodeConfig { relayMultiaddrs: string[]; logger: AbstractLogger; privateKey: string; + port?: number; whitelist?: string[]; } diff --git a/packages/rosenet-node/package.json b/packages/rosenet-node/package.json index dfacdae..39be0d3 100644 --- a/packages/rosenet-node/package.json +++ b/packages/rosenet-node/package.json @@ -44,12 +44,14 @@ "@libp2p/peer-id": "^4.0.6", "@libp2p/pubsub-peer-discovery": "^10.0.2", "@libp2p/tcp": "^9.0.15", + "@multiformats/multiaddr": "^12.2.1", "@rosen-bridge/rosenet-utils": "^0.0.0", "fast-shuffle": "^6.1.0", "it-first": "^3.0.4", "it-length-prefixed": "^9.0.4", "it-map": "^3.0.5", "it-pipe": "^3.0.1", - "libp2p": "^1.2.3" + "libp2p": "^1.2.3", + "public-ip": "^6.0.2" } } diff --git a/packages/rosenet-node/tests/address/address-service.spec.ts b/packages/rosenet-node/tests/address/address-service.spec.ts new file mode 100644 index 0000000..e53541a --- /dev/null +++ b/packages/rosenet-node/tests/address/address-service.spec.ts @@ -0,0 +1,29 @@ +import { describe, expect, it, vi } from 'vitest'; + +import addressService from '../../lib/address/address-service'; + +const fakePublicIP = vi.hoisted(() => '172.20.20.20'); +const fakePort = 12345; + +vi.mock('public-ip', () => ({ + publicIp: vi.fn().mockResolvedValue(fakePublicIP), +})); + +describe('getAnnounceMultiaddr', () => { + /** + * @target + * getAnnounceMultiaddr should get announce multiaddr + * @dependencies + * - `public-ip` package + * @scenario + * - call the function + * @expected + * - announceMultiaddr should be the correct one + */ + it('should get announce multiaddr', async () => { + const announceMultiaddr = + await addressService.getAnnounceMultiaddr(fakePort); + + expect(announceMultiaddr).toEqual(`/ip4/${fakePublicIP}/tcp/${fakePort}`); + }); +});