Last active
August 8, 2024 19:20
-
-
Save bellbind/fbbb4eb9512e62c589057aa677866b5f to your computer and use it in GitHub Desktop.
[helia] connect browser to server on localhost with archived webRTCStar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "@libp2p/bootstrap"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "libp2p/circuit-relay"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "@helia/unixfs"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "helia"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "@multiformats/multiaddr"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "multiformats"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "@libp2p/webrtc-star"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "@libp2p/webrtc"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "@libp2p/websockets"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "@libp2p/webtransport"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export * from "@libp2p/websockets/filters"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<link rel="icon" href="data:image/x-icon," /> | |
<meta http-equiv="Content-Security-Policy" content="default-src * data: ws: wss: http: https: 'self' 'unsafe-inline' 'unsafe-eval';" /> | |
<script type="importmap"> | |
{ | |
"imports": { | |
"helia": "./lib-helia.js", | |
"@helia/unixfs": "./lib-helia-unixfs.js", | |
"@libp2p/bootstrap": "./lib-bootstrap.js", | |
"libp2p/circuit-relay": "./lib-circuit.js", | |
"@libp2p/webrtc": "./lib-webrtc.js", | |
"@libp2p/webtransport": "./lib-webtransport.js", | |
"@libp2p/websockets": "./lib-websockets.js", | |
"@libp2p/websockets/filters": "./lib-ws-filters.js", | |
"@libp2p/webrtc-star": "./lib-webrtc-star.js", | |
"multiformats/cid": "./lib-multiformats.js", | |
"@multiformats/multiaddr": "./lib-multiaddr.js" | |
} | |
} | |
</script> | |
<script type="module" src="./helia-on-browser.js"></script> | |
</head> | |
<body> | |
Open JavaScript console to check result | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// npm i helia @helia/unixfs | |
// const helia = Helia, {unixfs} = HeliaUnixfs, {CID} = Multiformats; // from CDN | |
import * as helia from "helia"; | |
import {unixfs} from "@helia/unixfs"; | |
import {CID} from "multiformats/cid"; | |
import {multiaddr} from "@multiformats/multiaddr"; | |
import {bootstrap} from "@libp2p/bootstrap"; | |
import {circuitRelayTransport} from "libp2p/circuit-relay"; | |
import {webRTC, webRTCDirect} from "@libp2p/webrtc"; | |
import {webTransport} from "@libp2p/webtransport"; | |
import {webSockets} from "@libp2p/websockets"; | |
import {webRTCStar} from "@libp2p/webrtc-star"; | |
import * as filters from "@libp2p/websockets/filters"; | |
//NOTE: not implement rs[Symbol.asyncIterator] in browser impls | |
const rsWithAi = rs => { | |
if (!(Symbol.asyncIterator in rs)) rs[Symbol.asyncIterator] = async function *() { | |
const reader = rs.getReader(); | |
try { | |
while (true) { | |
const {value, done} = await reader.read(); | |
if (done) return; | |
yield value; | |
} | |
} finally { | |
reader.releaseLock(); | |
} | |
}; | |
return rs; | |
}; | |
// https://github.com/ipfs/helia/blob/main/packages/helia/src/utils/bootstrappers.ts | |
const bootstrapConfig = { | |
list: [ | |
'/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN', | |
'/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa', | |
'/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb', | |
'/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt', | |
'/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ', | |
] | |
}; | |
const star = webRTCStar(); | |
const node1 = await helia.createHelia({ | |
libp2p: { | |
// https://github.com/ipfs/helia/blob/main/packages/helia/src/utils/libp2p-defaults.browser.ts#L27 | |
addresses: { | |
listen: [ | |
"/webrtc", "/wss", "/ws", | |
"/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star", // see | |
], | |
}, | |
transports: [ | |
webRTC(), webRTCDirect(), | |
webTransport(), | |
// https://github.com/libp2p/js-libp2p-websockets#libp2p-usage-example | |
webSockets({filter: filters.all}), | |
circuitRelayTransport({discoverRelays: 1}), | |
star.transport, | |
], | |
peerDiscovery: [bootstrap(bootstrapConfig), star.discovery], | |
// https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md#configuring-connection-gater | |
connectionGater: { | |
denyDialMultiaddr: async (...args) => false, | |
}, | |
}, | |
}); // tcp network, stored on memory (not use files) | |
console.log("[createHelia]"); | |
const node1fs = unixfs(node1); | |
//IMPORTANT: must await libp2p.getMultiaddrs().length > 0 | |
while (node1.libp2p.getMultiaddrs().length === 0) await new Promise(f => setTimeout(f, 500)); | |
console.log("[libp2p.getMultiaddrs]", node1.libp2p.getMultiaddrs().map(ma => `${ma}`)); | |
// libp2p dialProtocol examples | |
const proto = "/my-echo/0.1"; | |
const handler = ({connection, stream}) => { | |
stream.sink(async function* () { | |
for await (const bufs of stream.source) { | |
yield bufs.slice().slice(); | |
} | |
}()); | |
}; | |
await node1.libp2p.handle(proto, handler); | |
const send = async (ma, msg) => { | |
if (typeof ma === "string") ma = multiaddr(ma); | |
const stream = await node1.libp2p.dialProtocol(ma, proto); | |
stream.sink(async function* () { | |
yield (new TextEncoder().encode(msg)); | |
}()); | |
for await (const bufs of stream.source) { | |
return new TextDecoder().decode(bufs.slice().slice()); | |
} | |
}; | |
// for web console | |
window.ctx = { | |
helia, CID, multiaddr, node1, node1fs, | |
maStar: localId => multiaddr(`/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/p2p/${localId}`), | |
maP2p: localId => multiaddr(`/p2p/${localId}`), | |
cidHw: CID.parse("bafkreid7qoywk77r7rj3slobqfekdvs57qwuwh5d2z3sqsw52iabe3mqne"), // served on helia-wrtc-star.mjs | |
send, | |
}; | |
/* | |
// example data | |
const blob = new Blob([new TextEncoder().encode("Hello World!")], {type: "text/plain;charset=utf-8"}); | |
console.log("[Blob]", blob); | |
// publish blob as CID with addByteStream() | |
const cid = await ctx.node1fs.addByteStream(rsWithAi(blob.stream())); | |
//const cid = await ctx.node1fs.addBytes(new Uint8Array(await blob.arrayBuffer())); | |
console.log("[unixfs.addByteStream]", cid); | |
const cidStr = cid.toString(); | |
const cidAlt = CID.parse(cidStr); | |
const ret1 = await ctx.node1.pins.add(cidAlt); //NOTE: pins not accept CID string | |
console.log("[pins.add]", ret1); | |
// NOTE: helia's pins needs stored blocks in blockstore (e.g. cannnot pin before stat()/ls()/cat()) | |
const stat = await ctx.node1fs.stat(cidStr); | |
console.log("[unixfs.stat]", stat); | |
// get CID object from CID string with ls() from @helia/unixfs | |
for await (const entry of ctx.node1fs.ls(cidStr)) console.log("[unixfs.ls]", entry.cid); | |
// retrieve data with cat(cid or cid-string) | |
const u8as = []; | |
for await (const u8a of ctx.node1fs.cat(cidStr)) { | |
console.log("[unixfs.cat]", u8a); | |
u8as.push(u8a.slice()); | |
} | |
console.log("[Blob.text]", await (new Blob(u8as).text())); | |
*/ | |
// stop only helia nodes; unixfs is just a wrapper | |
//console.log("[helia.stop]", await node1.stop()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// helia | |
import * as helia from "helia"; | |
import {unixfs} from "@helia/unixfs"; | |
import {CID} from "multiformats/cid"; | |
import {multiaddr} from "@multiformats/multiaddr"; | |
// modules required for helia creation on nodejs | |
// transports | |
import {tcp} from "@libp2p/tcp"; | |
import {webSockets} from "@libp2p/websockets"; | |
import {webRTC, webRTCDirect} from "@libp2p/webrtc"; | |
import {circuitRelayTransport, circuitRelayServer} from "libp2p/circuit-relay"; | |
// peerDiscovery | |
import {mdns} from "@libp2p/mdns"; | |
import {bootstrap} from "@libp2p/bootstrap"; | |
// contentRouters | |
import {ipniContentRouting} from "@libp2p/ipni-content-routing"; | |
//wrtc-star | |
import {sigServer} from "@libp2p/webrtc-star-signalling-server"; | |
import {webRTCStar} from "@libp2p/webrtc-star"; | |
import wrtc from "@koush/wrtc"; | |
// repl | |
import * as repl from "node:repl"; | |
// for webrtc-star | |
const sig = await sigServer({ | |
host: "0.0.0.0", | |
port: 9090, | |
}); | |
const sigAddr = "/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star"; | |
// https://github.com/ipfs/helia/blob/main/packages/helia/src/utils/bootstrappers.ts | |
const bootstrapConfig = { | |
list: [ | |
'/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN', | |
'/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa', | |
'/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb', | |
'/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt', | |
'/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ', | |
] | |
}; | |
const star = webRTCStar({wrtc}); | |
// https://github.com/ipfs/helia/blob/main/packages/helia/src/index.ts | |
const node = await helia.createHelia({libp2p: { | |
addresses: { | |
listen: [ | |
"/ip4/0.0.0.0/tcp/0", | |
"/ip4/0.0.0.0/tcp/0/ws", | |
//"/ip4/0.0.0.0/tcp/0/wss", | |
sigAddr, | |
] | |
}, | |
transports: [ | |
tcp(), | |
webSockets({websocket: {rejectUnauthorized: false}}), | |
circuitRelayTransport({discoverRelays: 1}), | |
star.transport, | |
], | |
peerDiscovery: [mdns(), bootstrap(bootstrapConfig), star.discovery], | |
// from https://github.com/libp2p/js-libp2p-webtransport/blob/main/examples/fetch-file-from-kubo/src/libp2p.ts | |
connectionGater: {denyDialMultiaddr: async () => false}, | |
}}); | |
// libp2p dialProtocol examples | |
const proto = "/my-echo/0.1"; | |
const handler = ({connection, stream}) => { | |
stream.sink(async function* () { | |
for await (const bufs of stream.source) { | |
yield bufs.slice().slice(); | |
} | |
}()); | |
}; | |
await node.libp2p.handle(proto, handler); | |
const send = async (ma, msg) => { | |
if (typeof ma === "string") ma = multiaddr(ma); | |
const stream = await node.libp2p.dialProtocol(ma, proto); | |
stream.sink(async function* () { | |
yield (new TextEncoder().encode(msg)); | |
}()); | |
for await (const bufs of stream.source) { | |
return new TextDecoder().decode(bufs.slice().slice()); | |
} | |
}; | |
// ipfs examples | |
console.log("[multiaddrs]"); | |
console.log(node.libp2p.getMultiaddrs().map(ma => `${ma}`)); | |
console.log("[serve example data] try to access the CID from other node"); | |
const nodefs = unixfs(node); | |
const blob = new Blob([new TextEncoder().encode("Hello World!")], {type: "text/plain;charset=utf-8"}); | |
const cid = await nodefs.addByteStream(blob.stream()); | |
console.log(cid); | |
const cidStr = cid.toString(); | |
const cidAlt = CID.parse(cidStr); | |
const ret1 = await node.pins.add(cidAlt); //NOTE: pins not accept CID string | |
console.log(ret1); | |
// control with repl | |
console.log("To stop with Ctrl+D"); | |
const stop = () => Promise.all([node.stop(), sig.stop()]); | |
const rs = repl.start({ | |
prompt: "> ", | |
}); | |
rs.once("exit", () => { | |
stop().then(() => { | |
console.log("node and sig stopped..."); | |
rs.close(); | |
}).catch(console.error); | |
}); | |
Object.assign(rs.context, { | |
node, nodefs, CID, multiaddr, send, | |
}); | |
//await Promise.all([node.stop(), sig.stop()]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"devDependencies": { | |
"@helia/unixfs": "^1.3.0", | |
"@koush/wrtc": "^0.5.3", | |
"@libp2p/bootstrap": "^8.0.0", | |
"@libp2p/mdns": "^8.0.0", | |
"@libp2p/tcp": "^7.0.3", | |
"@libp2p/webrtc": "^2.0.11", | |
"@libp2p/webrtc-star": "^7.0.0", | |
"@libp2p/webrtc-star-signalling-server": "^4.0.0", | |
"@libp2p/websockets": "^6.0.3", | |
"@multiformats/multiaddr": "^12.1.3", | |
"esbuild": "^0.18.3", | |
"helia": "^1.3.2", | |
"http-server": "^14.1.1", | |
"multiformats": "^12.0.1" | |
}, | |
"scripts": { | |
"local": "node helia-wrtc-star.mjs", | |
"build:helia": "esbuild dep-helia.js --bundle --format=esm --target=chrome114 --define:global=window --keep-names --outfile=lib-helia.js", | |
"build:unixfs": "esbuild dep-helia-unixfs.js --bundle --format=esm --target=chrome114 --define:global=window --outfile=lib-helia-unixfs.js", | |
"build:multiformats": "esbuild dep-multiformats.js --bundle --format=esm --target=chrome114 --define:global=window --outfile=lib-multiformats.js", | |
"build:multiaddr": "esbuild dep-multiaddr.js --bundle --format=esm --target=chrome114 --define:global=window --outfile=lib-multiaddr.js", | |
"build:bootstrap": "esbuild dep-bootstrap.js --bundle --format=esm --target=chrome114 --define:global=window --outfile=lib-bootstrap.js", | |
"build:circuit": "esbuild dep-circuit.js --bundle --format=esm --target=chrome114 --define:global=window --outfile=lib-circuit.js", | |
"build:webrtc": "esbuild dep-webrtc.js --bundle --format=esm --target=chrome114 --define:global=window --outfile=lib-webrtc.js", | |
"build:webtransport": "esbuild dep-webtransport.js --bundle --format=esm --target=chrome114 --define:global=window --outfile=lib-webtransport.js", | |
"build:websockets": "esbuild dep-websockets.js --bundle --format=esm --target=chrome114 --define:global=window --outfile=lib-websockets.js", | |
"build:webrtc-star": "esbuild dep-webrtc-star.js --bundle --format=esm --target=chrome114 --define:global=window --outfile=lib-webrtc-star.js", | |
"build:ws-filters": "esbuild dep-ws-filters.js --bundle --format=esm --target=chrome114 --define:global=window --outfile=lib-ws-filters.js", | |
"build": "npm run build:helia && npm run build:unixfs && npm run build:multiformats && npm run build:multiaddr && npm run build:bootstrap && npm run build:circuit && npm run build:webrtc && npm run build:webtransport && npm run build:websockets && npm run build:ws-filters && npm run build:webrtc-star", | |
"server": "http-server" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to play browser to server connection
http://localhost:8080/helia-on-browser.html
, then open Web Console for trying to:.../p2p-webrtc-star/...
addressctx.node1.libp2p.getMultiaddrs().map(ma => ma.toString())
/p2p/...
or/ip4/127.0.0.1/tcp/9090/ws/p2p-webrtc-star/p2p/...
:await ctx.node1.libp2p.dial(ctx.maP2p("12D3...."))
stat
,ls
,cat
) with cid served from local helia on nodejsstat = await ctx.node1fs.stat(ctx.cidHw)
for await (const entry of ctx.node1fs.ls(ctx.cidHw)) console.log("[unixfs.ls]", entry.cid);
libp2p.dialProtocol()
withsend()
await send("/p2p/12D3...", "hello")
on nodejs repl or web console