├── .eslintrc.json ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── artwork ├── diagrams.ai └── user_images.psd ├── jsconfig.json ├── mdx-components.jsx ├── next.config.mjs ├── package-lock.json ├── package.json ├── postcss.config.js ├── prettier.config.js ├── public ├── blog │ ├── 0rtt-api │ │ ├── 0rtt-norenew.png │ │ ├── 0rtt-renew.png │ │ ├── 1rtt.png │ │ ├── decryptedpayload.png │ │ ├── wireshark-decrypted.png │ │ └── wireshark-encrypted.png │ ├── blake3-hazmat-api │ │ ├── blake-tree-21-dark.png │ │ ├── blake-tree-21.png │ │ ├── blake-tree-21.svg │ │ ├── blake-tree-6-dark.png │ │ ├── blake-tree-6.png │ │ ├── blake-tree-6.svg │ │ └── crates.png │ ├── frost-threshold-signatures │ │ ├── frost_protocol_dark.svg │ │ ├── frost_protocol_light.svg │ │ ├── frost_usage_dark.svg │ │ ├── frost_usage_light.svg │ │ ├── protocol.jpeg │ │ └── usage.jpeg │ ├── iroh-0-16-a-better-client │ │ └── iroh-doctor-plot.png │ ├── iroh-0-17-0-everything-is-a-little-better │ │ └── perf-chart.png │ └── iroh-global-node-discovery │ │ └── pkarr.png ├── diagrams │ ├── blobs_fig_1_blob.svg │ ├── blobs_fig_1_blob_dark.svg │ ├── blobs_fig_2_collection.svg │ ├── blobs_fig_2_collection_dark.svg │ ├── blobs_fig_3_size_proofs.svg │ ├── dag_sync_post.svg │ ├── dag_sync_post_dark.svg │ ├── documents.svg │ ├── documents_dark.svg │ ├── gossip_swarm_dark.svg │ └── gossip_swarm_light.svg ├── docs │ └── anchor-http-api │ │ └── openapi.yaml ├── img │ ├── diagram │ │ └── fig_1_iroh_cloud_gateway.svg │ ├── icon │ │ ├── icon_carat.svg │ │ ├── icon_faster.svg │ │ ├── icon_menu.svg │ │ ├── icon_mobile.svg │ │ ├── icon_open.svg │ │ ├── icon_platforms.svg │ │ ├── icon_practical.svg │ │ └── icon_search.svg │ ├── ios-starter │ │ ├── 01_project_naming.png │ │ ├── 02_resolve_package.png │ │ ├── 03_add_package.png │ │ ├── 04_build_frameworks.png │ │ ├── 05_add_system_configuration.png │ │ ├── 06_start_console.png │ │ └── 07_running_app.png │ ├── kv │ │ ├── iroh-kv-1.png │ │ ├── iroh-kv-2.png │ │ ├── iroh-kv-3.png │ │ ├── iroh-kv-4.png │ │ ├── iroh-kv-og-1.png │ │ ├── iroh_kv_1.png │ │ ├── iroh_kv_1_1200.png │ │ ├── iroh_kv_2.png │ │ ├── iroh_kv_3.png │ │ └── iroh_kv_4.png │ ├── logo │ │ ├── iroh-wordmark-dark.svg │ │ ├── iroh-wordmark-purple.svg │ │ ├── n0-wordmark-dark.svg │ │ ├── n0-wordmark-gray.svg │ │ ├── n0-wordmark-salmon.svg │ │ ├── number-zero-wordmark-dark.svg │ │ ├── number-zero-wordmark-gray.svg │ │ └── number-zero-wordmark-salmon.svg │ ├── sendme │ │ └── sendme_hero_1.svg │ └── users │ │ ├── delta_chat.png │ │ ├── dumbpipe.png │ │ ├── fish_folk.png │ │ ├── sendme.png │ │ └── shaga.png ├── legal │ └── index.html ├── motion-canvas │ ├── Discovery.project.js │ ├── Publishing.project.js │ ├── _virtual_settings-6986020f.js │ └── _virtual_settings-c09ffc35.css ├── papers │ └── MIT-LCS-TM-394.pdf ├── robots.txt ├── search_index.en.js ├── sendme.ps1 ├── sendme.sh └── svg │ ├── connect_devices_dark.svg │ ├── connect_devices_light.svg │ ├── dumbpipe_icon.svg │ ├── sendme_icon.svg │ └── server.svg ├── readme.md ├── src ├── app │ ├── api │ │ └── og │ │ │ └── route.jsx │ ├── blog │ │ ├── 0rtt-api │ │ │ └── page.mdx │ │ ├── a-new-direction-for-iroh │ │ │ └── page.mdx │ │ ├── a-richer-tags-api │ │ │ └── page.mdx │ │ ├── async-rust-challenges-in-iroh │ │ │ └── page.mdx │ │ ├── blake3-hazmat-api │ │ │ └── page.mdx │ │ ├── blob-store-design-challenges │ │ │ └── page.mdx │ │ ├── closing-a-quic-connection │ │ │ └── page.mdx │ │ ├── comparing-iroh-and-libp2p │ │ │ └── page.mdx │ │ ├── consensus-is-impossible │ │ │ └── page.mdx │ │ ├── ffi-updates │ │ │ └── page.mdx │ │ ├── frost-threshold-signatures │ │ │ └── page.mdx │ │ ├── healing-connections │ │ │ └── page.mdx │ │ ├── iroh-0-14-0-dial-the-world │ │ │ └── page.mdx │ │ ├── iroh-0-15-0-shut-me-down │ │ │ └── page.mdx │ │ ├── iroh-0-16-a-better-client │ │ │ └── page.mdx │ │ ├── iroh-0-17-0-everything-is-a-little-better │ │ │ └── page.mdx │ │ ├── iroh-0-18-small-but-helpful │ │ │ └── page.mdx │ │ ├── iroh-0-19-make-it-your-own │ │ │ └── page.mdx │ │ ├── iroh-0-20-more-ways-to-connect │ │ │ └── page.mdx │ │ ├── iroh-0-21-fix-clean-polish │ │ │ └── page.mdx │ │ ├── iroh-0-22-cleanup-on-aisle-five │ │ │ └── page.mdx │ │ ├── iroh-0-23-welcoming-nodejs-to-the-family │ │ │ └── page.mdx │ │ ├── iroh-0-24-0-quinn-11 │ │ │ └── page.mdx │ │ ├── iroh-0-25-0-custom-protocols-for-all │ │ │ └── page.mdx │ │ ├── iroh-0-26-0-Say-Hello-to-Your-Neighbors │ │ │ └── page.mdx │ │ ├── iroh-0-27-0-Squashing-Bugs-And-Taking-Names │ │ │ └── page.mdx │ │ ├── iroh-0-28-let-them-have-crates │ │ │ └── page.mdx │ │ ├── iroh-0-29-net-is-the-new-iroh │ │ │ └── page.mdx │ │ ├── iroh-0-30-0-slimming-down │ │ │ └── page.mdx │ │ ├── iroh-0-31-0-back-to-fighting-fit │ │ │ └── page.mdx │ │ ├── iroh-0-32-0-browser-alpha-qad-and-n0-future │ │ │ └── page.mdx │ │ ├── iroh-0-33-0-browsers-and-discovery-and-0-RTT-oh-my │ │ │ └── page.mdx │ │ ├── iroh-0-34-0-raw-public-keys │ │ │ └── page.mdx │ │ ├── iroh-0-35-prepping-for-1-0 │ │ │ └── page.mdx │ │ ├── iroh-and-the-web │ │ │ └── page.mdx │ │ ├── iroh-content-discovery │ │ │ └── page.mdx │ │ ├── iroh-dag-sync │ │ │ └── page.mdx │ │ ├── iroh-dns │ │ │ └── page.mdx │ │ ├── iroh-global-node-discovery │ │ │ └── page.mdx │ │ ├── layout.jsx │ │ ├── page.jsx │ │ ├── relay-down-a-post-mortem │ │ │ └── page.mdx │ │ ├── road-to-1-0 │ │ │ └── page.mdx │ │ ├── smaller-is-better │ │ │ └── page.mdx │ │ ├── what-is-derp │ │ │ └── page.mdx │ │ └── why-we-forked-quinn │ │ │ └── page.mdx │ ├── changelog │ │ ├── page.jsx │ │ └── releases.json │ ├── docs │ │ ├── concepts │ │ │ ├── discovery │ │ │ │ └── page.mdx │ │ │ ├── endpoint │ │ │ │ └── page.mdx │ │ │ ├── page.mdx │ │ │ ├── protocol │ │ │ │ └── page.mdx │ │ │ ├── relay │ │ │ │ └── page.mdx │ │ │ ├── router │ │ │ │ └── page.mdx │ │ │ └── tickets │ │ │ │ └── page.mdx │ │ ├── examples │ │ │ ├── gossip-chat │ │ │ │ └── page.mdx │ │ │ ├── page.mdx │ │ │ └── todos │ │ │ │ └── page.mdx │ │ ├── faq │ │ │ └── page.mdx │ │ ├── ipfs │ │ │ └── page.mdx │ │ ├── layout.jsx │ │ ├── overview │ │ │ └── page.mdx │ │ ├── page.mdx │ │ ├── protocols │ │ │ ├── docs │ │ │ │ └── page.mdx │ │ │ ├── gossip │ │ │ │ └── page.mdx │ │ │ ├── net │ │ │ │ ├── holepunching │ │ │ │ │ └── page.mdx │ │ │ │ └── page.mdx │ │ │ └── writing │ │ │ │ └── page.mdx │ │ ├── quickstart │ │ │ └── page.mdx │ │ ├── reference │ │ │ ├── glossary │ │ │ │ └── page.mdx │ │ │ └── http-api │ │ │ │ └── page.mdx │ │ ├── tour │ │ │ ├── 1-endpoints │ │ │ │ └── page.mdx │ │ │ ├── 2-relays │ │ │ │ └── page.mdx │ │ │ ├── 3-discovery │ │ │ │ └── page.mdx │ │ │ ├── 4-protocols │ │ │ │ └── page.mdx │ │ │ ├── 5-routers │ │ │ │ └── page.mdx │ │ │ ├── 6-conclusion │ │ │ │ └── page.mdx │ │ │ └── page.mdx │ │ └── wasm-browser-support │ │ │ └── page.mdx │ ├── favicon.ico │ ├── layout.jsx │ ├── not-found.jsx │ ├── page.mdx │ ├── proto │ │ ├── [slug] │ │ │ └── page.jsx │ │ ├── layout.jsx │ │ ├── page.jsx │ │ └── protocols.js │ ├── providers.jsx │ ├── roadmap │ │ ├── page.jsx │ │ └── roadmap.json │ ├── rss.xml │ │ └── route.js │ ├── sendme │ │ ├── PageIcon.jsx │ │ ├── bg.jsx │ │ └── page.mdx │ └── sitemap.js ├── components │ ├── ApiCommands.jsx │ ├── BlankLayout.jsx │ ├── BlogHeader.jsx │ ├── BlogPostLayout.jsx │ ├── Breadcrumbs.jsx │ ├── Button.jsx │ ├── Card.jsx │ ├── Code.jsx │ ├── ConnectDevicesIllustration.jsx │ ├── EmailSubscribe.jsx │ ├── Examples.jsx │ ├── Footer.jsx │ ├── FooterMarketing.jsx │ ├── FromTheBlog.jsx │ ├── GithubStars.jsx │ ├── GlowCard.jsx │ ├── GridPattern.jsx │ ├── Header.jsx │ ├── HeaderSparse.jsx │ ├── Heading.jsx │ ├── HeroPattern.jsx │ ├── HomeHero.tsx │ ├── Input.jsx │ ├── Layout.jsx │ ├── Libraries.jsx │ ├── Logo.jsx │ ├── Logotype.jsx │ ├── MobileNavigation.jsx │ ├── MotionCanvas.jsx │ ├── MotionCanvasDynamic.jsx │ ├── Navigation.jsx │ ├── PageNavigation.jsx │ ├── PerfChartIllustration.jsx │ ├── Prose.jsx │ ├── ProtocolCard.jsx │ ├── ProtocolHeroList.jsx │ ├── Readme.jsx │ ├── References.jsx │ ├── Resources.jsx │ ├── Search.jsx │ ├── SectionProvider.jsx │ ├── SendmePage.jsx │ ├── Tabs.jsx │ ├── Tag.jsx │ ├── ThemeImage.jsx │ ├── ThemeToggle.jsx │ ├── UsersShowcase.jsx │ ├── icons │ │ ├── BellIcon.jsx │ │ ├── BoltIcon.jsx │ │ ├── BookIcon.jsx │ │ ├── CalendarIcon.jsx │ │ ├── CartIcon.jsx │ │ ├── ChatBubbleIcon.jsx │ │ ├── CheckIcon.jsx │ │ ├── ChevronRightLeftIcon.jsx │ │ ├── ClipboardIcon.jsx │ │ ├── CogIcon.jsx │ │ ├── CopyIcon.jsx │ │ ├── DocumentIcon.jsx │ │ ├── EnvelopeIcon.jsx │ │ ├── FaceSmileIcon.jsx │ │ ├── FolderIcon.jsx │ │ ├── GithubIcon.jsx │ │ ├── LinkIcon.jsx │ │ ├── ListIcon.jsx │ │ ├── MagnifyingGlassIcon.jsx │ │ ├── MapPinIcon.jsx │ │ ├── PackageIcon.jsx │ │ ├── PaperAirplaneIcon.jsx │ │ ├── PaperClipIcon.jsx │ │ ├── ShapesIcon.jsx │ │ ├── ShirtIcon.jsx │ │ ├── SquaresPlusIcon.jsx │ │ ├── TagIcon.jsx │ │ ├── UserIcon.jsx │ │ ├── UsersIcon.jsx │ │ └── WrenchCodeIcon.jsx │ ├── mdx.jsx │ └── youtube.jsx ├── fonts │ └── Koulen-Regular.ttf ├── images │ ├── icons │ │ ├── icon_carat.svg │ │ ├── icon_faster.svg │ │ ├── icon_menu.svg │ │ ├── icon_mobile.svg │ │ ├── icon_open.svg │ │ ├── icon_platforms.svg │ │ ├── icon_practical.svg │ │ └── icon_search.svg │ └── logos │ │ ├── go.svg │ │ ├── kotlin.svg │ │ ├── node.svg │ │ ├── php.svg │ │ ├── python.svg │ │ ├── ruby.svg │ │ ├── rust.svg │ │ └── swift.svg ├── lib │ ├── blog.js │ ├── formatDate.js │ ├── mdx │ │ ├── recma.mjs │ │ ├── rehype.mjs │ │ ├── remark.mjs │ │ └── search.mjs │ ├── pages.js │ └── remToPx.js ├── mdx │ ├── recma.mjs │ ├── rehype.mjs │ ├── remark.mjs │ └── search.mjs ├── palette.jsx └── styles │ └── tailwind.css ├── tailwind.config.js └── typography.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next", 3 | "rules": { 4 | "@next/next/no-img-element": "off" 5 | } 6 | } -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | spellcheck: 11 | name: check spelling 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: checkout 15 | uses: actions/checkout@master 16 | 17 | - uses: actions/setup-go@v4 18 | - run: curl -L https://git.io/misspell | bash 19 | 20 | - name: Check spelling 21 | run: ./bin/misspell -error ./src/app/** 22 | 23 | lint: 24 | name: lint 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@master 28 | 29 | - name: Install Node.js dependencies 30 | run: npm ci 31 | 32 | - name: Lint 33 | run: npm run lint -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /scripts/node_modules 6 | /.pnp 7 | .pnp.js 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | .parcel-cache 23 | 24 | # debug 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | 29 | # local env files 30 | .env*.local 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | 39 | # go 40 | extern 41 | iroh_data_dir 42 | 43 | # rust 44 | api-code-examples/target 45 | 46 | # nodejs 47 | api-code-examples/node_modules 48 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "api-code-examples/go/extern/iroh-ffi"] 2 | path = api-code-examples/go/extern/iroh-ffi 3 | url = https://github.com/n0-computer/iroh-ffi.git 4 | -------------------------------------------------------------------------------- /artwork/diagrams.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/artwork/diagrams.ai -------------------------------------------------------------------------------- /artwork/user_images.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/artwork/user_images.psd -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /mdx-components.jsx: -------------------------------------------------------------------------------- 1 | import * as mdxComponents from '@/components/mdx' 2 | 3 | export function useMDXComponents(components) { 4 | return { 5 | ...components, 6 | ...mdxComponents 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | import nextMDX from '@next/mdx' 2 | 3 | import { recmaPlugins } from './src/mdx/recma.mjs' 4 | import { rehypePlugins } from './src/mdx/rehype.mjs' 5 | import { remarkPlugins } from './src/mdx/remark.mjs' 6 | import withSearch from './src/mdx/search.mjs' 7 | 8 | const withMDX = nextMDX({ 9 | options: { 10 | remarkPlugins, 11 | rehypePlugins, 12 | recmaPlugins, 13 | }, 14 | }) 15 | 16 | const redirects = async () => { 17 | return [ 18 | // LETS GO DISCORD WAHOO 19 | { source: '/discord', destination: 'https://discord.gg/DpmJgtU7cW', basePath: false, permanent: false, }, 20 | 21 | // transition from protocols in docs section to protocols registry 22 | { source: '/docs/protocols/docs', destination: '/proto/iroh-docs', permanent: true, }, 23 | { source: '/docs/protocols/blobs', destination: '/proto/iroh-blobs', permanent: true, }, 24 | { source: '/docs/protocols/gossip', destination: '/proto/iroh-gossip', permanent: true, }, 25 | { source: '/docs/protocols/net', destination: '/docs/overview', permanent: true, }, 26 | 27 | { source: '/docs/api', destination: '/docs/sdks', permanent: true, }, 28 | { source: '/docs/api/:slug', destination: '/docs/sdks', permanent: true, }, 29 | 30 | // there's no more CLI to install. Instead, lead people towards general iroh docs 31 | { source: '/docs/install', destination: '/docs', permanent: true, }, 32 | 33 | // Reported at https://github.com/n0-computer/iroh.computer/issues/222 34 | // Some redirects 35 | { source: '/docs/components/networking', destination: '/docs/overview', permanent: true }, 36 | { source: '/docs/components/net', destination: '/docs/overview', permanent: true }, 37 | { source: '/docs/layers/blobs', destination: '/proto/iroh-blobs', permanent: true }, 38 | { source: '/docs/layers/gossip', destination: '/proto/iroh-gossip', permanent: true }, 39 | { source: '/docs/layers/documents', destination: '/proto/iroh-docs', permanent: true }, 40 | ] 41 | } 42 | 43 | 44 | /** @type {import('next').NextConfig} */ 45 | const nextConfig = { 46 | pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'mdx'], 47 | redirects, 48 | } 49 | 50 | export default withSearch(withMDX(nextConfig)) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "iroh.computer", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "browserslist": "defaults, not ie <= 11", 12 | "dependencies": { 13 | "@algolia/autocomplete-core": "^1.11.1", 14 | "@headlessui/react": "^2.1.0", 15 | "@headlessui/tailwindcss": "^0.2.0", 16 | "@heroicons/react": "^2.1.1", 17 | "@mdx-js/loader": "^3.0.0", 18 | "@mdx-js/react": "^3.0.0", 19 | "@motion-canvas/core": "^3.17.0", 20 | "@motion-canvas/player": "^3.17.0", 21 | "@next/mdx": "^14.0.4", 22 | "@sindresorhus/slugify": "^2.1.1", 23 | "@tailwindcss/typography": "^0.5.10", 24 | "@vercel/og": "^0.6.2", 25 | "acorn": "^8.10.0", 26 | "autoprefixer": "^10.4.16", 27 | "clsx": "^2.1.0", 28 | "ejs": "^3.1.10", 29 | "fast-glob": "^3.3.1", 30 | "flexsearch": "^0.7.31", 31 | "framer-motion": "^10.18.0", 32 | "mdast-util-to-string": "^4.0.0", 33 | "mdx-annotations": "^0.1.4", 34 | "next": "15.0.1", 35 | "next-themes": "^0.2.1", 36 | "react": "^18.2.0", 37 | "react-dom": "^18.2.0", 38 | "react-highlight-words": "^0.20.0", 39 | "react-markdown": "^9.0.1", 40 | "remark": "^15.0.1", 41 | "remark-gfm": "^4.0.0", 42 | "remark-mdx": "^3.0.0", 43 | "rss": "^1.2.2", 44 | "shiki": "^0.14.7", 45 | "simple-functional-loader": "^1.2.1", 46 | "simplex-noise": "^4.0.3", 47 | "tailwindcss": "^3.4.1", 48 | "unist-util-filter": "^5.0.1", 49 | "unist-util-visit": "^5.0.0", 50 | "zustand": "^4.4.3" 51 | }, 52 | "devDependencies": { 53 | "eslint": "^8.56.0", 54 | "eslint-config-next": "^14.0.4", 55 | "eslint-plugin-mdx": "^2.2.0", 56 | "eslint-plugin-react": "^7.33.2", 57 | "prettier": "^3.3.2", 58 | "prettier-plugin-tailwindcss": "^0.6.5" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: true, 3 | semi: false, 4 | plugins: [require('prettier-plugin-tailwindcss')], 5 | } 6 | -------------------------------------------------------------------------------- /public/blog/0rtt-api/0rtt-norenew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/0rtt-api/0rtt-norenew.png -------------------------------------------------------------------------------- /public/blog/0rtt-api/0rtt-renew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/0rtt-api/0rtt-renew.png -------------------------------------------------------------------------------- /public/blog/0rtt-api/1rtt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/0rtt-api/1rtt.png -------------------------------------------------------------------------------- /public/blog/0rtt-api/decryptedpayload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/0rtt-api/decryptedpayload.png -------------------------------------------------------------------------------- /public/blog/0rtt-api/wireshark-decrypted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/0rtt-api/wireshark-decrypted.png -------------------------------------------------------------------------------- /public/blog/0rtt-api/wireshark-encrypted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/0rtt-api/wireshark-encrypted.png -------------------------------------------------------------------------------- /public/blog/blake3-hazmat-api/blake-tree-21-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/blake3-hazmat-api/blake-tree-21-dark.png -------------------------------------------------------------------------------- /public/blog/blake3-hazmat-api/blake-tree-21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/blake3-hazmat-api/blake-tree-21.png -------------------------------------------------------------------------------- /public/blog/blake3-hazmat-api/blake-tree-6-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/blake3-hazmat-api/blake-tree-6-dark.png -------------------------------------------------------------------------------- /public/blog/blake3-hazmat-api/blake-tree-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/blake3-hazmat-api/blake-tree-6.png -------------------------------------------------------------------------------- /public/blog/blake3-hazmat-api/crates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/blake3-hazmat-api/crates.png -------------------------------------------------------------------------------- /public/blog/frost-threshold-signatures/protocol.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/frost-threshold-signatures/protocol.jpeg -------------------------------------------------------------------------------- /public/blog/frost-threshold-signatures/usage.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/frost-threshold-signatures/usage.jpeg -------------------------------------------------------------------------------- /public/blog/iroh-0-16-a-better-client/iroh-doctor-plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/iroh-0-16-a-better-client/iroh-doctor-plot.png -------------------------------------------------------------------------------- /public/blog/iroh-0-17-0-everything-is-a-little-better/perf-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/iroh-0-17-0-everything-is-a-little-better/perf-chart.png -------------------------------------------------------------------------------- /public/blog/iroh-global-node-discovery/pkarr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/blog/iroh-global-node-discovery/pkarr.png -------------------------------------------------------------------------------- /public/img/icon/icon_carat.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/icon/icon_faster.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/icon/icon_menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/icon/icon_mobile.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/icon/icon_open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/icon/icon_platforms.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/icon/icon_practical.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/icon/icon_search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/ios-starter/01_project_naming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/ios-starter/01_project_naming.png -------------------------------------------------------------------------------- /public/img/ios-starter/02_resolve_package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/ios-starter/02_resolve_package.png -------------------------------------------------------------------------------- /public/img/ios-starter/03_add_package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/ios-starter/03_add_package.png -------------------------------------------------------------------------------- /public/img/ios-starter/04_build_frameworks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/ios-starter/04_build_frameworks.png -------------------------------------------------------------------------------- /public/img/ios-starter/05_add_system_configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/ios-starter/05_add_system_configuration.png -------------------------------------------------------------------------------- /public/img/ios-starter/06_start_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/ios-starter/06_start_console.png -------------------------------------------------------------------------------- /public/img/ios-starter/07_running_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/ios-starter/07_running_app.png -------------------------------------------------------------------------------- /public/img/kv/iroh-kv-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/kv/iroh-kv-1.png -------------------------------------------------------------------------------- /public/img/kv/iroh-kv-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/kv/iroh-kv-2.png -------------------------------------------------------------------------------- /public/img/kv/iroh-kv-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/kv/iroh-kv-3.png -------------------------------------------------------------------------------- /public/img/kv/iroh-kv-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/kv/iroh-kv-4.png -------------------------------------------------------------------------------- /public/img/kv/iroh-kv-og-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/kv/iroh-kv-og-1.png -------------------------------------------------------------------------------- /public/img/kv/iroh_kv_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/kv/iroh_kv_1.png -------------------------------------------------------------------------------- /public/img/kv/iroh_kv_1_1200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/kv/iroh_kv_1_1200.png -------------------------------------------------------------------------------- /public/img/kv/iroh_kv_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/kv/iroh_kv_2.png -------------------------------------------------------------------------------- /public/img/kv/iroh_kv_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/kv/iroh_kv_3.png -------------------------------------------------------------------------------- /public/img/kv/iroh_kv_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/kv/iroh_kv_4.png -------------------------------------------------------------------------------- /public/img/logo/iroh-wordmark-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/logo/iroh-wordmark-purple.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/logo/n0-wordmark-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/logo/n0-wordmark-gray.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/logo/n0-wordmark-salmon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/img/users/delta_chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/users/delta_chat.png -------------------------------------------------------------------------------- /public/img/users/dumbpipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/users/dumbpipe.png -------------------------------------------------------------------------------- /public/img/users/fish_folk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/users/fish_folk.png -------------------------------------------------------------------------------- /public/img/users/sendme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/users/sendme.png -------------------------------------------------------------------------------- /public/img/users/shaga.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/img/users/shaga.png -------------------------------------------------------------------------------- /public/motion-canvas/_virtual_settings-c09ffc35.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;700&family=Space+Mono&display=swap'); -------------------------------------------------------------------------------- /public/papers/MIT-LCS-TM-394.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/public/papers/MIT-LCS-TM-394.pdf -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | Allow: /api/og/* 4 | Sitemap: https://iroh.computer/sitemap.xml 5 | -------------------------------------------------------------------------------- /public/sendme.ps1: -------------------------------------------------------------------------------- 1 | $repo = "n0-computer/sendme" 2 | $release_url = "https://api.github.com/repos/$repo/releases/latest" 3 | 4 | $target = "windows-x86_64" 5 | $zipFile = "sendme.zip" 6 | $extractPath = ".\sendme" 7 | 8 | Write-Host "Fetching latest release for $target..." 9 | $releaseJson = Invoke-RestMethod -Uri $release_url 10 | $releaseUrl = ($releaseJson.assets | Where-Object { $_.browser_download_url -match $target }).browser_download_url 11 | 12 | if (-not $releaseUrl) { 13 | Write-Host "Error: No release found for $target" -ForegroundColor Red 14 | exit 1 15 | } 16 | 17 | Write-Host "Downloading from $releaseUrl..." 18 | Invoke-WebRequest -Uri $releaseUrl -OutFile $zipFile 19 | 20 | Write-Host "Extracting..." 21 | Expand-Archive -Path $zipFile -DestinationPath $extractPath -Force 22 | 23 | Write-Host "Cleaning up..." 24 | Remove-Item -Force $zipFile 25 | 26 | Write-Host "Installation complete!" 27 | 28 | # Add the 'sendme' folder to PATH 29 | $sendmePath = (Resolve-Path $extractPath).Path 30 | 31 | # Add the folder to the PATH permanently (user level) 32 | $env:Path += ";$sendmePath" 33 | [System.Environment]::SetEnvironmentVariable("Path", $env:Path, [System.EnvironmentVariableTarget]::User) 34 | 35 | Write-Host "'$sendmePath' has been permanently added to user PATH." -ForegroundColor Green -------------------------------------------------------------------------------- /public/sendme.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright 2023 n0. All rights reserved. Dual MIT/Apache license. 3 | # Windows support provided by neuralpain. 4 | 5 | set -e 6 | 7 | repo="n0-computer/sendme" 8 | release_url="https://api.github.com/repos/$repo/releases/latest" 9 | 10 | if [ "$OS" = "Windows_NT" ]; then 11 | target="windows-x86_64" 12 | else 13 | case $(uname -sm) in 14 | "Darwin x86_64") target="darwin-x86_64" ;; 15 | "Darwin arm64") target="darwin-aarch64" ;; 16 | "Linux x86_64") target="linux-x86_64" ;; 17 | "Linux arm64"|"Linux aarch64") target="linux-aarch64" ;; 18 | *) target="linux-x86_64" ;; 19 | esac 20 | fi 21 | 22 | echo "Downloading $repo for $target" 23 | release_target_url=$( 24 | curl -s "$release_url" | 25 | grep "browser_download_url" | 26 | grep "$target" | 27 | sed -re 's/.*: "([^"]+)".*/\1/' \ 28 | ) 29 | 30 | if [[ "$release_target_url" =~ \.zip$ ]]; then 31 | release_archive=$( 32 | curl -s "$release_url" | 33 | grep "name" | 34 | grep "$target" | 35 | sed -re 's/.*: "([^"]+)".*/\1/' \ 36 | ) 37 | curl -sL "$release_target_url" -o $release_archive 38 | unzip -oq $release_archive 39 | rm -rf $release_archive 40 | else 41 | curl -sL "$release_target_url" | tar xz 42 | fi 43 | -------------------------------------------------------------------------------- /public/svg/connect_devices_dark.svg: -------------------------------------------------------------------------------- 1 | DIRECTDIRECTRELAYDIRECT -------------------------------------------------------------------------------- /public/svg/connect_devices_light.svg: -------------------------------------------------------------------------------- 1 | DIRECTDIRECTRELAYDIRECT -------------------------------------------------------------------------------- /public/svg/dumbpipe_icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/svg/server.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # iroh.computer 2 | 3 | The docs theme is based on the [protocol](https://protocol.tailwindui.com) tailwind theme, with a bunch of modifications. Protocol is a [Tailwind UI](https://tailwindui.com) site template built using [Tailwind CSS](https://tailwindcss.com) and [Next.js](https://nextjs.org). 4 | 5 | ## Getting started 6 | 7 | You'll need [`node`](https://nodejs.org/) to run locally. To get started with this template, first install the npm dependencies: 8 | 9 | ```bash 10 | npm install 11 | ``` 12 | 13 | Next, run the development server: 14 | 15 | ```bash 16 | npm run dev 17 | ``` 18 | 19 | Finally, open [http://localhost:3000](http://localhost:3000) in your browser to view the website. 20 | 21 | ## Editing docs content 22 | Our docs are generated. Use the following steps to make adjustments to the content and update the website to match: 23 | 24 | - make your edits to the documentation in the `api-code-examples/api.mjs` file 25 | - cd into the `scripts` folder 26 | - run `npm install` if you have not run it in this folder previously 27 | - run `node generate-api-pages.js` to generate the doc files for the website 28 | 29 | ### Style / grammar guide 30 | Follow the style that has already been layed out. But as a general rule of thumb, follow normal English punctuation, but favor brevity over proper grammar. In other words, use capital letters at the start of sentences, and end them with a period, but sentences can be fragments if that gets the point across quicker. 31 | 32 | ## Learn more 33 | 34 | To learn more about the technologies used in this site template, see the following resources: 35 | 36 | - [Tailwind CSS](https://tailwindcss.com/docs) - the official Tailwind CSS documentation 37 | - [Next.js](https://nextjs.org/docs) - the official Next.js documentation 38 | - [Headless UI](https://headlessui.dev) - the official Headless UI documentation 39 | - [Framer Motion](https://www.framer.com/docs/) - the official Framer Motion documentation 40 | - [MDX](https://mdxjs.com/) - the official MDX documentation 41 | - [Algolia Autocomplete](https://www.algolia.com/doc/ui-libraries/autocomplete/introduction/what-is-autocomplete/) - the official Algolia Autocomplete documentation 42 | - [FlexSearch](https://github.com/nextapps-de/flexsearch) - the official FlexSearch documentation 43 | - [Zustand](https://docs.pmnd.rs/zustand/getting-started/introduction) - the official Zustand documentation 44 | -------------------------------------------------------------------------------- /src/app/api/og/route.jsx: -------------------------------------------------------------------------------- 1 | import { ImageResponse } from '@vercel/og'; 2 | 3 | export async function GET(request) { 4 | const { searchParams } = await new URL(request.url); 5 | 6 | return new ImageResponse( 7 | ( 8 |
9 |
10 |
11 |

12 | { await searchParams.get('title') } 13 | { await searchParams.get('subtitle') } 14 |

15 |
16 |
17 |
18 | ), 19 | { 20 | width: 1200, 21 | height: 630, 22 | }, 23 | ); 24 | } -------------------------------------------------------------------------------- /src/app/blog/layout.jsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import {usePathname} from 'next/navigation'; 4 | 5 | import {SectionProvider} from '@/components/SectionProvider'; 6 | 7 | export default function DocsLayout({children, sections = {}}) { 8 | const pathname = usePathname(); 9 | sections = sections[pathname] || []; 10 | 11 | return ( 12 | 13 | {children} 14 | 15 | ); 16 | } -------------------------------------------------------------------------------- /src/app/blog/page.jsx: -------------------------------------------------------------------------------- 1 | import { getAllPosts } from '@/lib/blog' 2 | import { formatDate } from '@/lib/formatDate' 3 | 4 | import { Card } from '@/components/Card' 5 | import BlogHeader from '@/components/BlogHeader' 6 | import { FooterMarketing } from '@/components/FooterMarketing' 7 | 8 | export const metadata = { 9 | title: 'Blog', 10 | description: 11 | 'Articles related to iroh use & development', 12 | } 13 | 14 | function Article({ post }) { 15 | return ( 16 |
17 | 18 | 19 | {post.title} 20 | 21 | 27 | {formatDate(post.date)} 28 | 29 | {post.description} 30 | Read Post 31 | 32 | 37 | {formatDate(post.date)} 38 | 39 |
40 | ) 41 | } 42 | 43 | 44 | export default async function ArticlesIndex() { 45 | let posts = await getAllPosts() 46 | 47 | return ( 48 |
49 | 50 |
51 |
52 |

Blog

53 |

all things iroh & development

54 |
55 |
56 |
57 | {posts.map((post) => ( 58 |
59 | ))} 60 |
61 |
62 |
63 | 64 |
65 | ) 66 | } -------------------------------------------------------------------------------- /src/app/blog/what-is-derp/page.mdx: -------------------------------------------------------------------------------- 1 | import { BlogPostLayout } from '@/components/BlogPostLayout' 2 | import Image from 'next/image' 3 | // import designSystem from './planetaria-design-system.png' 4 | 5 | export const post = { 6 | draft: true, 7 | author: 'b5', 8 | date: '2024-01-05', 9 | title: 'Iroh connections: What is DERP?', 10 | description: 11 | 'Designated Encrypted Relay for Packets (DERP) is a protocol for sending encrypted packets between two parties without revealing the IP address of either party to the other. DERP is designed to be used in conjunction with DERP servers, which are trusted third parties that relay DERP packets between clients.', 12 | } 13 | 14 | export const metadata = { 15 | title: post.title, 16 | description: post.description, 17 | openGraph: { 18 | title: post.title, 19 | description: post.description, 20 | images: [{ 21 | url: `/api/og?title=Blog&subtitle=${post.title}`, 22 | width: 1200, 23 | height: 630, 24 | alt: post.title, 25 | type: 'image/png', 26 | }], 27 | type: 'article' 28 | } 29 | } 30 | 31 | export const references = [ 32 | { 33 | name: 'DERP', 34 | url: 'https://tailscale.com/blog/what-is-derp/', 35 | }, 36 | { 37 | name: 'DERP Protocol', 38 | url: 'https://tailscale.com/blog/derp-protocol/', 39 | }, 40 | { 41 | name: 'DERP Server Map', 42 | url: 'https://derpmap.tailscale.com/', 43 | } 44 | ] 45 | 46 | export default (props) => 47 | 48 | 49 | ## Introduction 50 | 51 | Briefly introduce the concept of P2P networking and the role of NAT traversal. 52 | Introduce Iroh and its mission to simplify P2P connectivity. 53 | 54 | ## The DERP Protocol in Iroh 55 | 56 | Explain the original DERP protocol by Tailscale, focusing on its functionality and limitations. 57 | Discuss how Iroh has adapted and enhanced the DERP protocol, emphasizing the use of DERP URLs instead of regions. 58 | 59 | ## Advancements in Connection Establishment 60 | 61 | Elaborate on Iroh's modifications to connect users discovered in the wild. 62 | Explain the significance of using DERP URLs and how it improves connection flexibility and reliability. 63 | 64 | ## NodeIDs and ED25519 Key 65 | 66 | Describe the concept of a NodeID in Iroh's system. 67 | Explain how NodeIDs are derived from ED25519 keys and their role in secure and efficient connection establishment. 68 | 69 | ## Conclusion 70 | 71 | Summarize the benefits of Iroh's approach to the DERP protocol, highlighting ease of use, enhanced connectivity, and security. 72 | Encourage readers to explore Iroh for a streamlined P2P experience. -------------------------------------------------------------------------------- /src/app/changelog/page.jsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | import clsx from 'clsx'; 3 | import { CheckCircleIcon } from '@heroicons/react/20/solid'; 4 | 5 | import { EmailSubscribe } from "@/components/EmailSubscribe" 6 | import { BlankLayout } from '@/components/BlankLayout'; 7 | import { formatDate } from '@/lib/formatDate' 8 | import releases from './releases.json'; 9 | 10 | export const metadata = { 11 | title: 'Changelog', 12 | description: 13 | 'Iroh Release History', 14 | }; 15 | 16 | export default function Component() { 17 | return ( 18 | 19 |

Change Log

20 |
21 |

Subscribe for updates

22 | 23 |
24 |

We'll send you an email with each new release of iroh & and a link to the blog post. Right now iroh is releasing roughly every 3 weeks.

25 |
26 |
27 | {releases.map((release, i) => )} 28 |
29 | ) 30 | } 31 | 32 | function Release({ data }) { 33 | const { version, date, title, github_release, changelog, blog_post, highlights } = data; 34 | return ( 35 |
38 |
39 | 40 |
41 |
42 |

43 | {version} 44 |

45 |

{formatDate(date, true)}

46 |
47 |
48 |

{title || "untitled"}

49 | {blog_post && blog post} 50 | {github_release && github} 51 | {changelog && changelog} 52 | {highlights && (
    53 | {highlights.map((hl, i) =>
  • {hl}
  • )} 54 |
)} 55 |
56 |
57 | ) 58 | } 59 | -------------------------------------------------------------------------------- /src/app/docs/concepts/discovery/page.mdx: -------------------------------------------------------------------------------- 1 | # Discovery 2 | 3 | Discovery is the glue that connects a [Node Identifier](/docs/concepts/endpoint#node-identifiers) to something we can dial. Discovery services resolve NodeIds to either a home Relay URL or direct-dialing information. {{className: 'lead'}} 4 | 5 | 6 | More details on discovery in the discovery module [documentation](https://docs.rs/iroh/latest/iroh/discovery/index.html) 7 | 8 | 9 | Node discovery is an automated system for an [Endpoint](/docs/concepts/endpoint) to retrieve addressing information. Each iroh node will automatically publish their own addressing information with configured discovery services. Usually this means publishing which [Home Relay](/docs/concepts/relay#home-relay) a node is findable at, but they could also publish their direct addresses. 10 | 11 | ## Discovery Services 12 | 13 | There are four different implementations of the discovery service in iroh, all of which map NodeIds to addresses: 14 | 15 | | | Discovery Implementation | Description | 16 | | --- | --- | --- | 17 | | 1 | [DNS](#dns-discovery) | uses a custom Domain Name System server | 18 | | 2 | [Local](#local-discovery) | uses an mDNS-like system to find nodes on the local network | 19 | | 3 | [Pkarr](#pkarr-discovery) | uses Pkarr Servers over HTTP | 20 | | 4 | [DHT](#dht-discovery) | uses the BitTorrent Mainline DHT | 21 | 22 | By Default, iroh uses the DNS discovery system to resolve NodeIds to addresses. And can be configured to use any of the other discovery systems. 23 | 24 | ## DNS Discovery 25 | DNS performs node lookups via the standard DNS systems. To publish to this DNS server a PkarrPublisher is needed. Number 0 runs a public instance of the DNS discovery system 26 | 27 | 28 | DNS Discovery has has it's own [blog post](/blog/iroh-dns)! 29 | 30 | 31 | ## Local Discovery 32 | Local discovery adds the ability to scan local networks for other iroh nodes, using Local Swarm Discovery. This is useful for local networks, or for bootstrapping a network before a relay is available. 33 | 34 | Local Discovery is _not_ enabled by default, and must be enabled by the user. You'll need to add the `discovery-local-network` feature flag to your `Cargo.toml` to use it. 35 | 36 | ```toml 37 | [dependencies] 38 | # Make sure to use the most recent version here instead of nn. (at the time of writing: 0.32) 39 | iroh = { version = "0.nn", features = ["discovery-local-network"] } 40 | ``` 41 | 42 | Then configure your endpoint to use local discovery concurrently with DNS discovery: 43 | 44 | ```rust 45 | use iroh::Endpoint; 46 | 47 | let ep = Endpoint::builder() 48 | .discovery_n0() 49 | .discovery_local_network() 50 | .bind() 51 | .await?; 52 | ``` 53 | 54 | ## Pkarr Discovery 55 | The Pkarr resolver can perform lookups from designated [pkarr relay servers](https://github.com/Pubky/pkarr#servers) using HTTP. Read more about the pkarr project [here](https://github.com/Pubky/pkarr?tab=readme-ov-file#pkarr). 56 | 57 | ## DHT Discovery 58 | DHT discovery uses the [BitTorrent Mainline](https://en.wikipedia.org/wiki/Mainline_DHT) distributed hash table (DHT) to publish & resolve NodeIds. 59 | 60 | DHT Discovery is _not_ enabled by default, and must be enabled by the user. You'll need to add the `discovery-pkarr-dht` feature flag to your `Cargo.toml` to use it. 61 | 62 | ```toml 63 | [dependencies] 64 | # Make sure to use the most recent version here instead of nn. (at the time of writing: 0.32) 65 | iroh = { version = "0.nn", features = ["discovery-pkarr-dht"] } 66 | ``` 67 | 68 | Then configure your endpoint to use DHT discovery concurrently with DNS discovery: 69 | 70 | ```rust 71 | use iroh::Endpoint; 72 | 73 | let ep = Endpoint::builder() 74 | .discovery_n0() 75 | .discovery_dht() 76 | .bind() 77 | .await?; 78 | ``` 79 | -------------------------------------------------------------------------------- /src/app/docs/concepts/endpoint/page.mdx: -------------------------------------------------------------------------------- 1 | # Endpoints 2 | 3 | An _endpoint_ is the main API interface to create connections to, and accept connections from other iroh nodes. The connections are peer-to-peer and encrypted, a [Relay](/docs/concepts/relay) server is used to make the connections reliable. Endpoints have a `NodeID` (the public half of an Ed25519 keypair) and the private key used to sign and decrypt messages. 4 | 5 | Generally, an application will have a single endpoint instance. This ensures all the connections made share the same peer-to-peer connections to other iroh nodes, while still remaining independent connections. This will result in more optimal network behaviour. 6 | 7 | Somewhere in a program that uses iroh for direct connections, you'll see code like this: 8 | 9 | ```rust 10 | use iroh::Endpoint; 11 | 12 | #[tokio::main] 13 | async fn main() { 14 | let endpoint = Endpoint::builder().bind().await.unwrap(); 15 | // ... 16 | } 17 | ``` 18 | 19 | Breaking that down the `builder` sets up configuration for the endpoint, and `bind` creates the endpoint and starts listening for incoming connections. The `await` keyword is used to wait for the endpoint to be created in an asynchronous context. 20 | 21 | Once you have an endpoint, you can use it to create connections to other nodes, or accept incoming connections from other nodes. 22 | 23 | ## Node Identifiers 24 | 25 | Each endpoint in iroh has a unique identifier (`NodeID`) created as a cryptographic key. This can be used to globally identify a node. Because `NodeIDs` are cryptographic keys, they are also the mechanism by which all traffic is always encrypted for a specific node only. 26 | 27 | See the [NodeID](https://docs.rs/iroh/latest/iroh/type.NodeId.html) documentation for more info. 28 | 29 | ## Connections 30 | 31 | Because we're in a peer-2-peer context, either node might be operating as the "server", so we use `connect` and `accept` to distinguish between the two. The `connect` method is used to create a new connection to a remote node, while `accept` is used to accept incoming connections from a remote node. 32 | 33 | Connections are full-fledged QUIC connections, giving you access to most features of QUIC / HTTP3, including bidirectional and unidirectional streams. 34 | 35 | 36 | Due to the light-weight properties of QUIC streams a stream can only be accepted once the initiating peer has sent some data on it. 37 | 38 | 39 | ## Building on Endpoints 40 | 41 | Endpoints are a low-level primitive that iroh exposes on purpose. For some projects like [dumbpipe](https://dumbpipe.dev), endpoints are 95% of what you need to connect any two devices on the planet. For others, like [iroh-blobs](/proto/iroh-blobs), endpoints are the foundation that higher-level protocols are built on. Most projects will not work with endpoints beyond constructing one and feeding it to one or more [protocols](/docs/concepts/protocol). 42 | -------------------------------------------------------------------------------- /src/app/docs/concepts/page.mdx: -------------------------------------------------------------------------------- 1 | import { Resources, Resource } from '@/components/Resources'; 2 | 3 | # Concepts 4 | 5 | 6 | 13 | 20 | 27 | -------------------------------------------------------------------------------- /src/app/docs/concepts/protocol/page.mdx: -------------------------------------------------------------------------------- 1 | 2 | # Protocols 3 | 4 | Iroh is organized into _protocols_: Composable networking software built on iroh connections. {{className: 'lead'}} 5 | 6 | 7 | The foundation of iroh is direct connections, which protocols use to extend up to higher-level functionality. When integrating iroh into an application you can use protocols to quickly add functionality, or write your own protocol(s) to maintain total control over how your application communicates. 8 | 9 | ## ALPN identifiers 10 | 11 | Iroh builds on QUIC connections, and uses [application level protocol negotiation](https://datatracker.ietf.org/doc/html/rfc7301) (ALPN, a widely used and well specified TLS extension) to run multiple protocols on the same QUIC endpoint. An ALPN identifier is the string that identifies the protocol and is used for protocol negotiation between endpoints. For example, the [iroh-blobs](/proto/iroh-blobs) protocol ALPN is [`/iroh-bytes/4`](https://github.com/n0-computer/iroh-blobs/blob/124820698cd85691e0d72aeed6e1ac028886b34a/src/protocol.rs#L353). 12 | This makes sure that an endpoint that accepts a connection can gracefully indicate whether it supports the requested protocol. 13 | [In the future](https://github.com/n0-computer/iroh/issues/2949) you'll be able to use multiple ALPN identifiers when connecting as a way to negotiate e.g. protocol versions. For example, you would connect using `/iroh-bytes/5` as well as `/iroh-bytes/4`, and the other side could respond with `/iroh-bytes/4` to indicating it doesn't have support for `/iroh-bytes/5`. 14 | 15 | 16 | ## The Accept Loop 17 | 18 | The accept loop is the main loop of an iroh server. It listens for incoming connections, and then processes them. The accept loop is the entry point for all iroh protocols, and is where you can add your own protocol to the iroh stack. 19 | 20 | Coming from the world of HTTP servers, the accept loop is similar to the main loop of an HTTP server. The main difference is that the accept loop is more flexible, as it can run multiple protocols on the same endpoint. Normally HTTP servers hide the raw accept loop from you, and instead route to the correct handler based on the URL. In iroh, the accept loop is exposed to you, and you can use it to route to the correct protocol based on the ALPN. 21 | -------------------------------------------------------------------------------- /src/app/docs/concepts/router/page.mdx: -------------------------------------------------------------------------------- 1 | 2 | ## Router 3 | 4 | To make composing protocols easier, iroh includes a _router_ for composing together multiple protocols. {{className: 'lead'}} 5 | 6 | The router implements the [accept loop](/docs/concepts/protocol#the-accept-loop) on your behalf, and routes incoming connections to the correct protocol based on the [ALPN](/docs/concepts/protocol#alpns). We recommend using the router to compose protocols, as it makes it easier to add new protocols to your application. 7 | 8 | We use the term _router_ because it mimics what an HTTP server would do with an URL-based router. 9 | 10 | ```rust 11 | use anyhow::Result; 12 | use iroh::protocol::Router; 13 | use iroh::Endpoint; 14 | use iroh_blobs::net_protocol::Blobs; 15 | use iroh_blobs::util::local_pool::LocalPool; 16 | 17 | 18 | #[tokio::main] 19 | async fn main() -> Result<()> { 20 | // Build an endpoint, defaulting to the public n0 relay network 21 | let endpoint = Endpoint::builder().discovery_n0().bind().await?; 22 | 23 | // configure the blobs protocol to run in-memory 24 | let blobs = Blobs::memory().build(&endpoint); 25 | 26 | // Build our router and add the blobs protocol, 27 | // identified by its ALPN. Spawn the router to start listening. 28 | let router = Router::builder(endpoint) 29 | .accept(iroh_blobs::ALPN, blobs) 30 | .spawn(); 31 | 32 | // get our own address. At this point we have a running router 33 | // that's ready to accept connections. 34 | let addr = router.endpoint().node_addr().await?; 35 | 36 | // Wait for exit 37 | tokio::signal::ctrl_c().await?; 38 | 39 | // Gracefully close the endpoint & protocols. 40 | // This makes sure that remote nodes are notified about possibly still open connections 41 | // and any data is written to disk fully (or any other shutdown procedure for protocols). 42 | router.shutdown().await?; 43 | 44 | Ok(()) 45 | } 46 | ``` 47 | 48 | You can add whatever protocols you need to the router, multiplexing them all over the same endpoint. 49 | -------------------------------------------------------------------------------- /src/app/docs/examples/page.mdx: -------------------------------------------------------------------------------- 1 | import { Examples } from '@/components/Examples' 2 | 3 | # Examples 4 | 5 | Learn by examining practical code examples. We try to collage together examples to show a broad range of platforms & techniques while working with iroh.{{className: 'lead'}} 6 | 7 | 8 | The [iroh examples repo](https://github.com/n0-computer/iroh-examples) has a grab bag of extra examples. Post an issue there if you have a request for a specific example, or [join the discord](https://iroh.computer/discord). 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/app/docs/examples/todos/page.mdx: -------------------------------------------------------------------------------- 1 | 2 | # TODOs example 3 | 4 | https://github.com/n0-computer/iroh-tauri-todomvc 5 | 6 | ## Tauri 7 | -------------------------------------------------------------------------------- /src/app/docs/layout.jsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import Link from 'next/link'; 4 | import {usePathname} from 'next/navigation'; 5 | import {motion} from 'framer-motion'; 6 | 7 | import {Footer} from '@/components/Footer'; 8 | import {Prose} from '@/components/Prose'; 9 | import {Header} from '@/components/Header'; 10 | import {Logotype} from '@/components/Logotype'; 11 | import {Navigation} from '@/components/Navigation'; 12 | import {SectionProvider} from '@/components/SectionProvider'; 13 | 14 | export const navItems = [ 15 | { 16 | title: 'Getting Started', 17 | links: [ 18 | {title: 'Overview', href: '/docs/overview'}, 19 | {title: 'Quickstart', href: '/docs/quickstart'}, 20 | {title: 'Tour', href: '/docs/tour' }, 21 | {title: 'Examples', href: '/docs/examples'}, 22 | ], 23 | }, 24 | { title: 'Concepts', 25 | links: [ 26 | {title: 'Endpoint', href: '/docs/concepts/endpoint'}, 27 | {title: 'Relay', href: '/docs/concepts/relay'}, 28 | {title: 'Discovery', href: '/docs/concepts/discovery'}, 29 | {title: 'Protocol', href: '/docs/concepts/protocol'}, 30 | {title: 'Router', href: '/docs/concepts/router'}, 31 | {title: 'Ticket', href: '/docs/concepts/tickets'}, 32 | ], 33 | }, 34 | {title: 'Resources', 35 | links: [ 36 | {title: 'Protocol Registry', href: '/proto'}, 37 | {title: 'Write your own Protocol', href: '/docs/protocols/writing'}, 38 | {title: 'Awesome List', href: 'https://github.com/n0-computer/awesome-iroh'}, 39 | {title: 'FAQ', href: '/docs/faq' }, 40 | {title: 'Wasm/Browser Support', href: '/docs/wasm-browser-support' }, 41 | ], 42 | }, 43 | ]; 44 | 45 | export default function DocsLayout({children, sections = {}}) { 46 | const pathname = usePathname(); 47 | sections = sections[pathname] || []; 48 | 49 | return ( 50 | 51 |
52 | 56 |
57 |
58 | 59 | 60 | 61 |
62 |
63 | 64 |
65 |
66 |
67 |
68 |
69 | {children} 70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | ); 79 | } 80 | -------------------------------------------------------------------------------- /src/app/docs/overview/page.mdx: -------------------------------------------------------------------------------- 1 | export const metadata = { 2 | title: 'Overview', 3 | description: 4 | 'A high-level description of what iroh is', 5 | }; 6 | 7 | 8 | # Overview 9 | 10 | Iroh lets you establish direct peer-to-peer connections whenever possible, falling back to relay servers if necessary. 11 | This gives you fast, reliable QUIC connections that are authenticated and encrypted end-to-end. {{className: 'lead'}} 12 | 13 | 14 | ## Iroh is "dial by public key" 15 | 16 | In the iroh world, you dial another node by its `NodeId`, a 32-byte ed25519 public key. Unlike IP addresses, this ID is globally unique, and instead of being assigned, you can cheaply generate as many as you want yourself. It also doesn't change when you change networks. 17 | You won't have to think about NATs getting in your way, iroh traverses them for you. 18 | Basing connections on asymmetric public keys is what allows iroh to *always* end-to-end encrypt and authenticate connections. 19 | 20 | 21 | ## Peer to peer 22 | 23 | Iroh is built on peer-to-peer QUIC using both relays and holepunching. 24 | 25 | Peers must know the NodeId of a peer before connecting to it. 26 | They verify this NodeId during the connection handshake to provide end-to-end encryption and authentication. 27 | 28 | Peer to peer connectivity is established with the help of a relay server. 29 | On startup peers register their NodeId with a home relay server. 30 | The relay server provides assistance to traverse firewalls, 31 | NATs or others alike. 32 | If no direct connection can be established, 33 | the connection is relayed via the server. 34 | 35 | Peers can also connect directly without using a relay server. 36 | For this, 37 | however, 38 | the listening peer must be directly reachable by the connecting peer via one of it's addresses. 39 | 40 | 41 | ## Iroh is built on QUIC 42 | 43 | 44 | This gives iroh super-powers: 45 | - encryption & authentication 46 | - stream multiplexing 47 | - no head-of-line blocking issues 48 | - stream priorities 49 | - one shared congestion controller 50 | - an encrypted, unreliable datagram transport 51 | - zero round trip time connection establishment if you've connected to another node before 52 | 53 | A single QUIC connection can power all of your protocol's complex interactions: 54 | - Stream both video and audio without video packet loss affecting audio. Prioritize audio by increasing that stream's priority. 55 | - Use the unreliable datagram transport for your game's state and input networking. Also re-use the same connection for streaming assets or real-time audio or video. 56 | - Avoid unnecessary network round-trips when your phone comes back from suspension with zero round trip time connection establishment. 57 | 58 | 59 | ## The higher level: Give your users agency back 60 | 61 | Iroh bootstraps a new internet: Your user's home computer is as inter-connected as a virtual private server. 62 | There might not be a need for intermediaries if their powerful smartphone can accept incoming connections like any other service. 63 | 64 | This gives users back power and agency to use their devices the way they want to.\ 65 | No need to fight for static IP addresses from your ISP.\ 66 | No need to buy domain names to participate in the internet.\ 67 | No need to set up complicated TLS certificates to get what should be a *baseline* feature: Encryption. 68 | 69 | ## Want to see where iroh's headed? 70 | 71 | See [our roadmap](/roadmap) to find out what's planned. 72 | -------------------------------------------------------------------------------- /src/app/docs/page.mdx: -------------------------------------------------------------------------------- 1 | import {Resources, Resource} from '@/components/Resources' 2 | import {HeroPattern} from '@/components/HeroPattern' 3 | 4 | export const metadata = { 5 | title: 'Documentation', 6 | description: 7 | 'Learn about Iroh and how to integrate into your own project.', 8 | } 9 | 10 | export const sections = [ 11 | {title: 'Resources', id: 'resources'}, 12 | ] 13 | 14 | 15 | 16 | # Iroh Documentation 17 | 18 | Iroh lets you establish direct peer-to-peer connections whenever possible, falling back to relay servers if necessary. 19 | This gives you fast, reliable connections that are authenticated and encrypted end-to-end using QUIC. {{className: 'lead'}} 20 | 21 |
22 |
24 | 25 | ## Getting started {{anchor: false}} 26 | 27 | The best place to start is by reading the overview, a high level look at the problems iroh solves. {{className: 'lead'}} 28 | 29 |
30 |
37 | 38 | 39 | 46 | 53 | 60 | 61 | -------------------------------------------------------------------------------- /src/app/docs/reference/glossary/page.mdx: -------------------------------------------------------------------------------- 1 | # Glossary 2 | 3 | A set of commonly used terms in the iroh ecosystem.{{className: 'lead'}} 4 | 5 | | Term | Definition | 6 | | ---- | ---------- | 7 | | [**Blob**](/docs/layers/blobs) | A piece of data stored in the iroh network. Blobs are immutable, content-addressed (refer by hash), and opaque. | 8 | | [**Document**](/docs/layers/document) | A mutable piece of data stored in the iroh network. Documents are content-addressed (refer by hash), and can be read and written to. | 9 | | **DocID** | A unique identifier for a document in an iroh network. A docID is the public half of a keyPair. | 10 | | **NodeID** | A unique identifier for a node in an iroh network. A nodeId is a keyPair | 11 | | [**Ticket**](/docs/concepts/tickets) | A single serialized token containing everything needed to kick off an interaction with another node running iroh. | 12 | -------------------------------------------------------------------------------- /src/app/docs/tour/1-endpoints/page.mdx: -------------------------------------------------------------------------------- 1 | import { PageLink } from '@/components/PageNavigation'; 2 | 3 | # 1. Endpoints 4 | 5 | The journey of a connection starts with an endpoint. An endpoint is one of the two termination points for a connection. It’s one of the tin cans that the wire is connected to. Because this is peer-2-peer, endpoints both _initiate_ *and* _accept_ connections. The endpoint handles both. 6 | 7 | Let's first add iroh to our project. From the project root run `cargo add iroh` to install the latest version: 8 | 9 | ```bash 10 | $ cargo add iroh 11 | Updating crates.io index 12 | Adding iroh v0.32.1 to dependencies 13 | Features: 14 | + metrics 15 | - discovery-pkarr-dht 16 | - discovery-local-network 17 | - examples 18 | - test-utils 19 | Updating crates.io index 20 | Locking 432 packages to latest compatible versions 21 | ``` 22 | 23 | We're also going to need a few supporting libraries so let's add those as well: 24 | 25 | ```bash 26 | cargo add tokio anyhow rand 27 | ``` 28 | 29 | In the end your `Cargo.toml` file's `[dependencies]` section should look something like this. It's ok if the version numbers are slightly different: 30 | 31 | ```toml 32 | [dependencies] 33 | anyhow = "1.0.95" 34 | iroh = "0.32.1" 35 | rand = "0.8.5" 36 | tokio = "1.43.0" 37 | ``` 38 | 39 | ## Starting an Endpoint 40 | 41 | With our dependencies added, open up `src/main.rs` and add the following code: 42 | 43 | ```rust 44 | #[tokio::main] 45 | async fn main() -> anyhow::Result<()> { 46 | // Create an endpoint 47 | let builder = iroh::Endpoint::builder(); 48 | 49 | // bind it to a socket 50 | let endpoint = builder.bind().await?; 51 | 52 | // print this endpoint's node id 53 | println!("node id: {:?}", endpoint.node_id()); 54 | 55 | // exit the program 56 | Ok(()) 57 | } 58 | ``` 59 | 60 | 61 | Then save and run your program with `cargo run`. You should see output similar to this: 62 | 63 | ```bash 64 | b5 at number-0 in ~/code/iroh-tour (main●) 65 | $ cargo run 66 | Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.80s 67 | Running `/Users/b5/.cargo/build/debug/iroh-tour` 68 | node id: PublicKey(95224c92856163add8a9cb68a81183aa5d9881c4def58625a9f4266a0743b479) 69 | ``` 70 | 71 | 72 | This code just prints it's ID & exits. For a more complete example, check out the [connect example](https://github.com/n0-computer/iroh/blob/main/iroh/examples/connect.rs) 73 | 74 | 75 | The non-setup part of this program adds up to 3 lines of code, and one of them is a print statement! The first line constructs an endpoint. 99% of apps will have a single endpoint in the entire app, so you’ll build the endpoint once, and refer to it a bunch. Then we call *bind* to ask the operating system for a networking port. This calling bind will kick off work in the background that we’ll talk about in a bit. 76 | 77 | Those three lines are the beating heart of adding iroh to an app. Once the node ID prints we have an active endpoint that's ready to connect & (if configured to) accept connections. Everything else builds up from here. 78 | 79 |
80 |
81 | 82 |
83 |
84 | 85 |
86 |
87 | -------------------------------------------------------------------------------- /src/app/docs/tour/3-discovery/page.mdx: -------------------------------------------------------------------------------- 1 | import { PageLink } from '@/components/PageNavigation'; 2 | 3 | # 3. Discovery 4 | 5 | Discovery is the glue that connects a [Node Identifier](/docs/concepts/endpoint#node-identifiers) to something we can dial. There are a few different types of discovery services, but for all of them you put a `NodeID` in, and get back either the home relay of that node, or IP addresses to dial. 6 | 7 | There are different implementations of the discovery service in iroh, the most popular of which are DNS & Local Discovery. DNS uses the same domain name system that connects "example.com" to an IP address to map node ids to relay servers, and local discovery uses your local network to find nodes to talk to on local WiFi, even if that WiFi network doesn’t have a wider internet connection. 8 | 9 | ### DNS Discovery 10 | 11 | First, let's add the n0 DNS discovery service as a default: 12 | 13 | ```rust 14 | use iroh::{Endpoint, RelayMode}; 15 | 16 | #[tokio::main] 17 | async fn main() -> anyhow::Result<()> { 18 | let builder = Endpoint::builder() 19 | .relay_mode(RelayMode::Default) 20 | .discovery_n0(); 21 | 22 | let endpoint = builder.bind().await?; 23 | 24 | println!("node id: {:?}", endpoint.node_id()); 25 | Ok(()) 26 | } 27 | ``` 28 | 29 | Now when this endpoint boots up, it will list itself on the n0 DNS service. From here we can pass along the node identifier, and other nodes can use the n0 DNS service to find the home relay of this node. 30 | 31 | ### Local Discovery 32 | 33 | Local discovery has the extra trick of being able to actually find new nodes on the local network. Before we can do that, we need to add the `discovery-local-network` feature to our `Cargo.toml` file: 34 | 35 | ``` 36 | cargo add iroh --features discovery-local-network 37 | ``` 38 | 39 | This will change our `Cargo.toml` file `[dependencies]` section to look like this: 40 | 41 | ```toml 42 | [dependencies] 43 | anyhow = "1.0.95" 44 | iroh = { version = "0.32.1", features = ["discovery-local-network"] } 45 | rand = "0.8.5" 46 | tokio = "1.43.0" 47 | ``` 48 | 49 | And with that we can set up local discovery: 50 | 51 | ```rust 52 | use iroh::{Endpoint, RelayMode, SecretKey}; 53 | 54 | #[tokio::main] 55 | async fn main() -> anyhow::Result<()> { 56 | let builder = Endpoint::builder() 57 | .relay_mode(RelayMode::Default) 58 | .discovery_n0() 59 | .discovery_local_network() 60 | 61 | let endpoint = builder.bind().await?; 62 | println!("node id: {:?}", endpoint.node_id()); 63 | Ok(()) 64 | } 65 | ``` 66 | 67 | Here we’ve added discovery to the endpoint constructor, passing in our two discovery services, and that’s it, iroh will now use these two services to get something it can dial for a given node ID. 68 | 69 | 70 | For an example of this in action, check out the [local discovery example](https://github.com/n0-computer/iroh/blob/main/iroh/examples/locally-discovered-nodes.rs). 71 | 72 | 73 |
74 |
75 | 76 |
77 |
78 | 79 |
80 |
81 | -------------------------------------------------------------------------------- /src/app/docs/tour/4-protocols/page.mdx: -------------------------------------------------------------------------------- 1 | import { PageLink } from '@/components/PageNavigation'; 2 | 3 | # 4. Protocols 4 | 5 | At this point, we’re connected, yay! Now we just have to… do something… with that connection. That’s where protocols come in. 6 | 7 | Protocols are modules you compose together to add functionality to connections. Protocols exist for file transfer, game server sync, message broadcasting, document collaboration, all kinds of stuff. You can use off-the-shelf protocols to quickly add functionality, work directly with QUIC streams & build a fully custom protocol that does exactly what you want, or fork an existing protocol to get what you need. 8 | 9 | Coming from the world of HTTP client/server models, protocols are kinda like request handlers, but they can go beyond request/response creating multiple streams of data and usually code up both initiating & accepting protocol connections in the same. 10 | 11 | Protocols are an ever-growing topic, but to give you a basic let's add the [blobs](/proto/iroh-blobs) protocol. First we need to add it to our depdendencies: 12 | 13 | ``` 14 | cargo add iroh-blobs --features=rpc 15 | ``` 16 | 17 | then adjust our code: 18 | 19 | ```rust 20 | use iroh::{protocol::Router, Endpoint}; 21 | use iroh_blobs::net_protocol::Blobs; 22 | 23 | #[tokio::main] 24 | async fn main() -> anyhow::Result<()> { 25 | let endpoint = Endpoint::builder().discovery_n0().bind().await?; 26 | 27 | let blobs = Blobs::memory().build(&endpoint); 28 | 29 | // build the router 30 | let router = Router::builder(endpoint) 31 | .accept(iroh_blobs::ALPN, blobs.clone()) 32 | .spawn(); 33 | 34 | router.shutdown().await?; 35 | 36 | Ok(()) 37 | } 38 | ``` 39 | 40 | 41 | This code doesn't actually _do_ anything with the blobs protocol. For a real-world example, check out [sendme](https://github.com/n0-computer/sendme) 42 | 43 | 44 | This code sets up everything we need to both provide data we have locally when others request it, and ask other nodes that run the blobs protocol for data. Starting at the top, we first construct the endpoint, then we construct an instance of the blobs protocol, then add a _router_ (more on that in a minute) that listens for blobs protocol connections. 45 | 46 | 47 |
48 |
49 | 50 |
51 |
52 | 53 |
54 |
55 | -------------------------------------------------------------------------------- /src/app/docs/tour/5-routers/page.mdx: -------------------------------------------------------------------------------- 1 | import { PageLink } from '@/components/PageNavigation'; 2 | 3 | # 5. Routers 4 | 5 | Most apps will use more than one protocol. A router let’s you stack protocols on top of iroh's peer-to-peer connections. Routers handle the *accept* side of an iroh endpoint, but the connection initiation side is still handled by the protocol instance itself. 6 | 7 | Since we've already set up a router when adding iroh blobs, we can add another protocol to the router with a few lines of code. Let's add iroh gossip, first by installing the dependency: 8 | 9 | ``` 10 | cargo add iroh-gossip 11 | ``` 12 | 13 | Then we can setup gossip & add it to our router: 14 | 15 | ```rust 16 | use iroh::{protocol::Router, Endpoint}; 17 | use iroh_blobs::net_protocol::Blobs; 18 | use iroh_gossip::{net::Gossip, ALPN}; 19 | 20 | #[tokio::main] 21 | async fn main() -> anyhow::Result<()> { 22 | let endpoint = Endpoint::builder().discovery_n0().bind().await?; 23 | 24 | let blobs = Blobs::memory().build(&endpoint); 25 | 26 | let gossip = Gossip::builder().spawn(endpoint.clone()).await?; 27 | 28 | // build the router 29 | let router = Router::builder(endpoint) 30 | .accept(iroh_blobs::ALPN, blobs.clone()) 31 | .accept(iroh_gossip::ALPN, gossip.clone()) 32 | .spawn(); 33 | 34 | router.shutdown().await?; 35 | Ok(()) 36 | } 37 | ``` 38 | 39 | The amount of code is small, but the conceptual shift is a nice-to-have, wrapping an endpoint in a router makes the design intent of iroh clear: set up an endpoint, pull in protocols, feed them to the router, and bind your way to glory. 40 | 41 |
42 |
43 | 44 |
45 |
46 | 47 |
48 |
49 | -------------------------------------------------------------------------------- /src/app/docs/tour/6-conclusion/page.mdx: -------------------------------------------------------------------------------- 1 | import { PageLink } from '@/components/PageNavigation'; 2 | 3 | # 6. Things iroh doesn’t do out of the box 4 | 5 | Before we go, let’s talk through a little of what iroh *doesn’t* cover: 6 | 7 | ### Magically keep nodes online 8 | First, iroh doesn’t magically ensure the device you’re trying to dial is online. It doesn’t buffer messages & wait until you turn your phone back on. The technical term for this is “network churn”, and programming around the reality that nodes can come online & go offline whenever they want is the core concern of all distributed systems programming. 9 | 10 | ### Obscure your IP address 11 | Second, iroh doesn’t obscure your IP address. nodes accepting connections will know your IP address. This is one of the biggest reason we think that iroh should be a library that users build into apps that have an in-built sense of trust. Keep in mind: sharing IP addresses is common practice in the wild, nearly all of major video conferencing tools do this. Video games do this. Heck, Spotify used to do this. And keep in mind, seeing your IP address is a thing traditional servers *always* have access to. 12 | 13 | ### Peer Signaling 14 | Lastly, iroh doesn’t yet come with a built-in peer signaling mechanism, that is, a way to get alice’s node id to bob. This seems like a massive oversight, but it’s on purpose: different apps have different opinions about how peers should learn about each other. In some cases it’s as simple as storing NodeIDs in an app database & passing them out as API responses. In other cases it’s local discovery only, or using tickets to encode dialing details + protocol invocations in a single string. We'll talk through patterns for peer signaling in future docs. 15 | 16 | ## Conclusion 17 | 18 | This concludes the iroh tour! Now that you understand a bit of iroh here are some next steps: 19 | * check the [examples](/docs/examples) 20 | * [join the discord](https://iroh.computer/discord) 21 | * have a look through the iroh [awesome list](https://github.com/n0-computer/awesome-iroh) 22 | 23 |
24 |
25 | 26 |
27 |
28 | -------------------------------------------------------------------------------- /src/app/docs/tour/page.mdx: -------------------------------------------------------------------------------- 1 | import { PageLink } from '@/components/PageNavigation'; 2 | 3 | # A Tour of iroh 4 | 5 | Let's take a tour of iroh! This tutorial will touch on 5 core concepts and a few supporting ideas that will get you familiar with what iroh does and how it works. 6 | 7 | We're going to do this tutorial in rust, so the first thing we'll need to do is confirm you have a working rust environment. If you don't, you can install it by following the instructions at https://www.rust-lang.org/tools/install for your operating system. 8 | 9 | Once you're up & running, let's create a new rust project by running the following command in your terminal: 10 | 11 | ```bash 12 | cargo new iroh-tour 13 | ``` 14 | 15 | This will create an empty rust project in a new directory called `iroh-tour`. Change into that directory and open it in your favorite code editor. You should be able to run it from the project root, run it with `cargo run` and see something like this: 16 | 17 | ```bash 18 | $ cargo run 19 | Compiling iroh-tour v0.1.0 (/Users/b5/code/iroh-tour) 20 | Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.69s 21 | Running `/Users/b5/.cargo/build/debug/iroh-tour` 22 | Hello, world! 23 | ``` 24 | 25 | ## Overview 26 | 27 | Here's a high level overview of how everything fits together: 28 | 29 | Iroh is a library for establishing the most direct QUIC connection possible between two devices. Every _endpoint_ uses the public half of a cryptographic keypair to identify itself. Assuming at least one configured _relay server_ is reachable, an endpoint keeps exactly one TCP connection to a “home relay” that other nodes use for connection establishment, and as a fallback transport. Iroh uses a suite of _discovery services_ to resolve home relays & endpoint IDs. Connections between endpoints use QUIC ALPNs to distinguish between _protocols_, while _routers_ automate the endpoint accept loop for protocol multiplexing.{{ className: 'lead' }} 30 | 31 | This paragraph touches on five key points worth understanding in iroh: 32 | 33 | * [Endpoints](/docs/tour/1-endpoints) 34 | * [Relays](/docs/tour/2-relays) 35 | * [Discovery](/docs/tour/3-discovery) 36 | * [Protocols](/docs/tour/4-protocols) 37 | * [Routers](/docs/tour/5-routers) 38 | 39 | We'll touch on each of these on the tour, and by the end you should have a good understanding of how they all fit together. The code we'll be writing here will build & execute, but it won't _do_ much. We'll link to examples and other resources along the way so you can explore further. 40 | 41 | 50 | -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0-computer/iroh.computer/3befb7792ea49b0bfdeceaf4b9895d4937e56597/src/app/favicon.ico -------------------------------------------------------------------------------- /src/app/layout.jsx: -------------------------------------------------------------------------------- 1 | import glob from 'fast-glob'; 2 | import Script from 'next/script'; 3 | 4 | import {Providers} from '@/app/providers'; 5 | import '@/styles/tailwind.css'; 6 | 7 | export const metadata = { 8 | metadataBase: new URL('https://www.iroh.computer'), 9 | title: { 10 | template: '%s - Iroh', 11 | default: 'docs, guides, and examples', 12 | }, 13 | openGraph: { 14 | title: 'iroh', 15 | description: 'less net work for networks', 16 | images: [{ 17 | url: '/api/og?title=iroh&subtitle=less net work for networks', 18 | width: 1200, 19 | height: 630, 20 | alt: 'iroh. less net work for networks', 21 | type: 'image/png', 22 | }], 23 | type: 'website' 24 | } 25 | }; 26 | 27 | export default async function RootLayout({children}) { 28 | let pages = await glob('**/*.mdx', {cwd: 'src/app'}); 29 | let allSectionEntries = await Promise.all( 30 | pages.map(async (filename) => [ 31 | '/' + filename.replace(/(^|\/)page\.mdx$/, ''), 32 | (await import(`./${filename}`)).sections, 33 | ]), 34 | ); 35 | let allSections = Object.fromEntries(allSectionEntries); 36 | 37 | return ( 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 | {children} 47 |
48 |
49 | 50 |