diff --git a/build.js b/build.js new file mode 100644 index 0000000..cca2a6f --- /dev/null +++ b/build.js @@ -0,0 +1,14 @@ +import esbuild from "esbuild"; + +esbuild.buildSync({ + entryPoints: ["src/index.ts"], + outfile: "dist/index.js", + format: "esm", + bundle: true, + legalComments: "external", + // minify: true + define: { + global: "self", + }, + external: ["libkernel"], +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..db40730 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "@lumeweb/kernel-peer-discovery", + "version": "0.1.0", + "type": "module", + "scripts": { + "test": "jest", + "build-script": "tsc --project tsconfig.build.json && mv dist-build/build.js dist-build/build.mjs", + "compile": "pnpm run build-script && node build.js", + "build": "pnpm run compile && node ./dist-build/build.mjs dev" + }, + "dependencies": { + "@lumeweb/peer-discovery": "git+https://git.lumeweb.com/LumeWeb/peer-discovery.git", + "libkmodule": "^0.2.46" + }, + "devDependencies": { + "@scure/bip39": "^1.1.0", + "@skynetlabs/skynet-nodejs": "^2.9.0", + "@types/node": "^18.11.18", + "@types/read": "^0.0.29", + "cli-progress": "^3.11.2", + "esbuild": "^0.17.0", + "read": "^2.0.0", + "typescript": "^4.9.4" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..d77416b --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,677 @@ +lockfileVersion: 5.4 + +specifiers: + '@lumeweb/peer-discovery': git+https://git.lumeweb.com/LumeWeb/peer-discovery.git + '@scure/bip39': ^1.1.0 + '@skynetlabs/skynet-nodejs': ^2.9.0 + '@types/node': ^18.11.18 + '@types/read': ^0.0.29 + cli-progress: ^3.11.2 + esbuild: ^0.17.0 + libkmodule: ^0.2.46 + read: ^2.0.0 + typescript: ^4.9.4 + +dependencies: + '@lumeweb/peer-discovery': git.lumeweb.com/LumeWeb/peer-discovery/d2bd926275103d60fdd3c7c432eae5c278f49261 + libkmodule: 0.2.53 + +devDependencies: + '@scure/bip39': 1.1.0 + '@skynetlabs/skynet-nodejs': 2.9.0 + '@types/node': 18.11.18 + '@types/read': 0.0.29 + cli-progress: 3.11.2 + esbuild: 0.17.2 + read: 2.0.0 + typescript: 4.9.4 + +packages: + + /@esbuild/android-arm/0.17.2: + resolution: {integrity: sha512-Art7v3xYfqH1gEMUSP0Nx67pNAlC/Y3qSg3mOw8Wg7MP9bJLXL0DrmJaV1Qz1o4FwagtvDgkVOeBDpZgxdj13Q==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64/0.17.2: + resolution: {integrity: sha512-QSkmYISXr2uFoR+NdmmKyR5svYb0cXDCfzwNblLsrC8wTpx/I1L7u/zrjrf4aLoHoRTycZFIewJwBiUrO5DWtQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64/0.17.2: + resolution: {integrity: sha512-5VOaFBI0RK8jJVDHdeU1YJmpxXoOf1RPoiOBhk/Tvpulw7R1SwCsxHvC3eDQcoF0gV7YM4V2wJO0PR9tem6gCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64/0.17.2: + resolution: {integrity: sha512-iQJu1Zn1Wi91D5x/sslEn/jwae1tgSAEHK0R/kYzIr5jO992IJwDDuWhSGll23jHt18RECxahhGG0BWY/bVUTw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64/0.17.2: + resolution: {integrity: sha512-j750nyrwoRZd3VnPo5sd12/5U27TxFGmvmoDv93G2jiaGJPYKJ/+5IfRAvHahGePTUIRPyOlE5YLFw9MlzuBnw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64/0.17.2: + resolution: {integrity: sha512-ti7GU+/KUQQXEPmSUep7efZpA3KR2SkKsVuSL2FE7Yxka9apuqKfymAgQmVPMxstzAgCRBIu8uEu0KFmTfs3/Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64/0.17.2: + resolution: {integrity: sha512-NgooSKWSnrNKRuiumY1dg7KAGpsyXIMcwyOXN9imnqe8VFjqqrEOMqZRik0C1wlfLjiSCuMsj+YUSmBMAJMt0A==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm/0.17.2: + resolution: {integrity: sha512-8dfrRTd39n+THdAetwQKNwK6zBPR5oPjMtgRNXvRq8gsn/J5o69zTaOWVi3QO09BljqdShxU2dxDA09lDhdIqQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64/0.17.2: + resolution: {integrity: sha512-jcJ4cxwQyqEqgDwkqj7820nKx9cM5WBPCCU4oUXvTeG+DkkJE6/P75od0VPHmItFfEJu+/2vV85ebvFVomZcBg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32/0.17.2: + resolution: {integrity: sha512-dXZ3m++zaRVD2fqOUPP8QTh1Lfg6WO6uZDo/QJ3KdfnIR7dDToDtaA12AgKYvCed9Nuzf/gpKs/7/f6I02b/sg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64/0.17.2: + resolution: {integrity: sha512-/vntXkzSe9TUp0Rh35Wgye1EOhDtmIMjwC4rtahHcALmDXL+iuQGvwGFvXrP+sBigia/ltLryMAvCiqGV6plqw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el/0.17.2: + resolution: {integrity: sha512-guYcNHjMRO1BMxWAeb8LDfgQaU8oeUO65xtlclwBD+hX3163KBifEHyao1hK96J10BP9n0UmZug6GhtGZaNm2Q==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64/0.17.2: + resolution: {integrity: sha512-fzHTnIGIVqgUGZcFnnisguKD4UneF4uwWwkG+i8kBspMDdU1wJ0jha1VdtxWP7Ob1KGxuXcoUlrQkCVO+Z5iOw==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64/0.17.2: + resolution: {integrity: sha512-Sa+z7csvNVeAsTD83tVSggOb8CAU7EdDuihC8WhtoJfuDVkF5+Vi0imaiCjXQ7Ci5rz/a8IJ1H1MWX3eI9AmuQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x/0.17.2: + resolution: {integrity: sha512-jUFCO+/VA1Y/oeauSNBubp2UtGu4xjBUEFVgMPm0qLuw6xw18yOagKwBOPVmyE3ZSFqGd9BAPZM/JrtadgBryA==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64/0.17.2: + resolution: {integrity: sha512-naygxkSmr6x9tuvpa8iGefnXo3Rc3Noz7c4+Dn0MSfSWJwLaN2YR686e7HkI09irfjDdU5UAq9wcxUwjkYQNUA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64/0.17.2: + resolution: {integrity: sha512-Hagbdq4EpiG9XXJY6Ozfrl2RN5jkXZXd6BD39f43tWz0d8yyOrRZlofM1eA6JYQbdv6c8BUsUOcgopavIqwx4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64/0.17.2: + resolution: {integrity: sha512-Pkby+VEXY7+aWP8J2RUCfqWbbZz2M1GavRGGnE2kEPzwarba/BOk3B45PSaKwc3iKdK2rgCPCTjC/p9JoKNejA==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64/0.17.2: + resolution: {integrity: sha512-WAyg4dBTUsAPJ9cRnuQ23cwJWYRhP4e4y0M/l2+EpRjWW+g1MNAXKQQNNhRQ71zc8UixRVrqj+43ReHeZC8mJQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64/0.17.2: + resolution: {integrity: sha512-rMbO3gPpxuENd+AnZLgo4J/g+BkwxT3NK7nYpSZ0KlYtSdlxYMIMG5pznX7a1ISZKo67aGStne+K41jdkBywpA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32/0.17.2: + resolution: {integrity: sha512-73dWKDMhFk+4owS19OjEVbEDGFPRS1fyga3qOu5HPd5eTxJTjtlVTT/fG/S7AchA0vXS7hOqY70AAir1CkmICg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64/0.17.2: + resolution: {integrity: sha512-QFJlhf73HCBjTqAWWSIlD8JQBtmue0Dd6UV+KGccycJ3HKj1dCkXdRKJGwc5bZWiI9hrxcWsVEa1kVFaltC4vQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@noble/hashes/1.1.5: + resolution: {integrity: sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ==} + dev: true + + /@scure/base/1.1.1: + resolution: {integrity: sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==} + dev: true + + /@scure/bip39/1.1.0: + resolution: {integrity: sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==} + dependencies: + '@noble/hashes': 1.1.5 + '@scure/base': 1.1.1 + dev: true + + /@skynetlabs/skynet-nodejs/2.9.0: + resolution: {integrity: sha512-2zyh+6tsLdFDtGOoupig4qSj+4U+YueR56Tavl+AthtGzL+4ShpIhix5F1OBshHvP7mkoVJQKCZSsgvngfI+EA==} + dependencies: + '@skynetlabs/tus-js-client': 3.0.0 + axios: 0.27.2 + form-data: 4.0.0 + mime: 3.0.0 + skynet-js: 4.3.0 + url-join: 4.0.1 + transitivePeerDependencies: + - debug + dev: true + + /@skynetlabs/tus-js-client/2.4.1: + resolution: {integrity: sha512-cc//2XeIqfZQ7rC182MbMwx/xTh1Cw1mQb2BmeHh6rO+coioyUSX71znPCsvijdKM+3NYXbhg5r/ZV5028OXfg==} + dependencies: + buffer-from: 1.1.2 + combine-errors: 3.0.3 + is-stream: 2.0.1 + js-base64: 2.6.4 + lodash.throttle: 4.1.1 + proper-lockfile: 2.0.1 + url-parse: 1.5.10 + dev: true + + /@skynetlabs/tus-js-client/3.0.0: + resolution: {integrity: sha512-vEJGcN1o0kha4zGk6fu+iE1nG+F2KcNTBhaEAuh2hhEJlOxN91yR9kgjCxWJNol27tOq8kkYfweuowsRgO+i/Q==} + dependencies: + buffer-from: 1.1.2 + combine-errors: 3.0.3 + is-stream: 2.0.1 + js-base64: 3.7.4 + lodash.throttle: 4.1.1 + proper-lockfile: 4.1.2 + url-parse: 1.5.10 + dev: true + + /@types/node/18.11.18: + resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} + dev: true + + /@types/read/0.0.29: + resolution: {integrity: sha512-TisW3O3OhpP8/ZwaiqV7kewh9gnoH7PfqHd4hkCM9ogiqWEagu43WXpHWqgPbltXhembYJDpYB3cVwUIOweHXg==} + dev: true + + /ansi-regex/5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /async-mutex/0.3.2: + resolution: {integrity: sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==} + dependencies: + tslib: 2.4.1 + dev: true + + /asynckit/0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: true + + /axios/0.27.2: + resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} + dependencies: + follow-redirects: 1.15.2 + form-data: 4.0.0 + transitivePeerDependencies: + - debug + dev: true + + /b4a/1.6.1: + resolution: {integrity: sha512-AsKjNhz72yxteo/0EtQEiwkMUgk/tGmycXlbG4g3Ard2/ULtNLUykGOkeK0egmN27h0xMAhb76jYccW+XTBExA==} + dev: false + + /base32-decode/1.0.0: + resolution: {integrity: sha512-KNWUX/R7wKenwE/G/qFMzGScOgVntOmbE27vvc6GrniDGYb6a5+qWcuoXl8WIOQL7q0TpK7nZDm1Y04Yi3Yn5g==} + dev: true + + /base32-encode/1.2.0: + resolution: {integrity: sha512-cHFU8XeRyx0GgmoWi5qHMCVRiqU6J3MHWxVgun7jggCBUpVzm1Ir7M9dYr2whjSNc3tFeXfQ/oZjQu/4u55h9A==} + dependencies: + to-data-view: 1.1.0 + dev: true + + /base64-js/1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /blakejs/1.2.1: + resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} + dev: true + + /buffer-from/1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /buffer/6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + + /cli-progress/3.11.2: + resolution: {integrity: sha512-lCPoS6ncgX4+rJu5bS3F/iCz17kZ9MPZ6dpuTtI0KXKABkhyXIdYB3Inby1OpaGti3YlI3EeEkM9AuWpelJrVA==} + engines: {node: '>=4'} + dependencies: + string-width: 4.2.3 + dev: true + + /combine-errors/3.0.3: + resolution: {integrity: sha512-C8ikRNRMygCwaTx+Ek3Yr+OuZzgZjduCOfSQBjbM8V3MfgcjSTeto/GXP6PAwKvJz/v15b7GHZvx5rOlczFw/Q==} + dependencies: + custom-error-instance: 2.1.1 + lodash.uniqby: 4.5.0 + dev: true + + /combined-stream/1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + + /custom-error-instance/2.1.1: + resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==} + dev: true + + /delayed-stream/1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: true + + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /esbuild/0.17.2: + resolution: {integrity: sha512-odaHSgtYafOXt2nSISwdWlfRkb4ceMX3akY1mWspQpT08jsqVYEK1XtVusr250Rmbx8AVNWjMPI/yyvKqxOKMw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.2 + '@esbuild/android-arm64': 0.17.2 + '@esbuild/android-x64': 0.17.2 + '@esbuild/darwin-arm64': 0.17.2 + '@esbuild/darwin-x64': 0.17.2 + '@esbuild/freebsd-arm64': 0.17.2 + '@esbuild/freebsd-x64': 0.17.2 + '@esbuild/linux-arm': 0.17.2 + '@esbuild/linux-arm64': 0.17.2 + '@esbuild/linux-ia32': 0.17.2 + '@esbuild/linux-loong64': 0.17.2 + '@esbuild/linux-mips64el': 0.17.2 + '@esbuild/linux-ppc64': 0.17.2 + '@esbuild/linux-riscv64': 0.17.2 + '@esbuild/linux-s390x': 0.17.2 + '@esbuild/linux-x64': 0.17.2 + '@esbuild/netbsd-x64': 0.17.2 + '@esbuild/openbsd-x64': 0.17.2 + '@esbuild/sunos-x64': 0.17.2 + '@esbuild/win32-arm64': 0.17.2 + '@esbuild/win32-ia32': 0.17.2 + '@esbuild/win32-x64': 0.17.2 + dev: true + + /follow-redirects/1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: true + + /form-data/4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true + + /ieee754/1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-stream/2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /js-base64/2.6.4: + resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==} + dev: true + + /js-base64/3.7.4: + resolution: {integrity: sha512-wpM/wi20Tl+3ifTyi0RdDckS4YTD4Lf953mBRrpG8547T7hInHNPEj8+ck4gB8VDcGyeAWFK++Wb/fU1BeavKQ==} + dev: true + + /libkmodule/0.2.53: + resolution: {integrity: sha512-fwMcssu6mwH+xeuUwUFdGDYQgGvwuVs0RMtbBPEYHvPPOBDNbdesPmlax/+XwDn6XiGggg+wSvq7st2m4VbwEw==} + dependencies: + libskynet: 0.1.9 + dev: false + + /libskynet/0.1.9: + resolution: {integrity: sha512-lYP4GUbDZXUd0PyTyHz7RBPXGSBFmFZrc2JirnV7tlL4ii3Zi6m79z73zGWoiDBrHI25RR9s9gdm/LdBeXz9nQ==} + dev: false + + /lodash._baseiteratee/4.7.0: + resolution: {integrity: sha512-nqB9M+wITz0BX/Q2xg6fQ8mLkyfF7MU7eE+MNBNjTHFKeKaZAPEzEg+E8LWxKWf1DQVflNEn9N49yAuqKh2mWQ==} + dependencies: + lodash._stringtopath: 4.8.0 + dev: true + + /lodash._basetostring/4.12.0: + resolution: {integrity: sha512-SwcRIbyxnN6CFEEK4K1y+zuApvWdpQdBHM/swxP962s8HIxPO3alBH5t3m/dl+f4CMUug6sJb7Pww8d13/9WSw==} + dev: true + + /lodash._baseuniq/4.6.0: + resolution: {integrity: sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A==} + dependencies: + lodash._createset: 4.0.3 + lodash._root: 3.0.1 + dev: true + + /lodash._createset/4.0.3: + resolution: {integrity: sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA==} + dev: true + + /lodash._root/3.0.1: + resolution: {integrity: sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ==} + dev: true + + /lodash._stringtopath/4.8.0: + resolution: {integrity: sha512-SXL66C731p0xPDC5LZg4wI5H+dJo/EO4KTqOMwLYCH3+FmmfAKJEZCm6ohGpI+T1xwsDsJCfL4OnhorllvlTPQ==} + dependencies: + lodash._basetostring: 4.12.0 + dev: true + + /lodash.throttle/4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + dev: true + + /lodash.uniqby/4.5.0: + resolution: {integrity: sha512-IRt7cfTtHy6f1aRVA5n7kT8rgN3N1nH6MOWLcHfpWG2SH19E3JksLK38MktLxZDhlAjCP9jpIXkOnRXlu6oByQ==} + dependencies: + lodash._baseiteratee: 4.7.0 + lodash._baseuniq: 4.6.0 + dev: true + + /mime-db/1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types/2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /mime/3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + dev: true + + /mute-stream/1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true + + /path-browserify/1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: true + + /post-me/0.4.5: + resolution: {integrity: sha512-XgPdktF/2M5jglgVDULr9NUb/QNv3bY3g6RG22iTb5MIMtB07/5FJB5fbVmu5Eaopowc6uZx7K3e7x1shPwnXw==} + dev: true + + /proper-lockfile/2.0.1: + resolution: {integrity: sha512-rjaeGbsmhNDcDInmwi4MuI6mRwJu6zq8GjYCLuSuE7GF+4UjgzkL69sVKKJ2T2xH61kK7rXvGYpvaTu909oXaQ==} + engines: {node: '>=4.0.0'} + dependencies: + graceful-fs: 4.2.10 + retry: 0.10.1 + dev: true + + /proper-lockfile/4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + dependencies: + graceful-fs: 4.2.10 + retry: 0.12.0 + signal-exit: 3.0.7 + dev: true + + /querystringify/2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: true + + /randombytes/2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /read/2.0.0: + resolution: {integrity: sha512-88JMmpeeRYzW9gvIpYyXlYadWanW4vB2CYtDDVBfbRpbSogUNjTWEBXxJXMIVFSLjWVdCcdcIjI3+VV3Z2e9mw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + mute-stream: 1.0.0 + dev: true + + /requires-port/1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + dev: true + + /retry/0.10.1: + resolution: {integrity: sha512-ZXUSQYTHdl3uS7IuCehYfMzKyIDBNoAuUblvy5oGO5UJSUTmStUUVPXbA9Qxd173Bgre53yCQczQuHgRWAdvJQ==} + dev: true + + /retry/0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + dev: true + + /safe-buffer/5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /signal-exit/3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /sjcl/1.0.8: + resolution: {integrity: sha512-LzIjEQ0S0DpIgnxMEayM1rq9aGwGRG4OnZhCdjx7glTaJtf4zRfpg87ImfjSJjoW9vKpagd82McDOwbRT5kQKQ==} + dev: true + + /skynet-js/4.3.0: + resolution: {integrity: sha512-fkaKqHCheQ6tseL7keEU7v5IxwAlfROMMMYPcbo64n9SHfsVXjPmW5wowc6OgmpB5Mt5k4EMVlIrGqF2VbizIw==} + dependencies: + '@skynetlabs/tus-js-client': 2.4.1 + async-mutex: 0.3.2 + axios: 0.27.2 + base32-decode: 1.0.0 + base32-encode: 1.2.0 + base64-js: 1.5.1 + blakejs: 1.2.1 + buffer: 6.0.3 + mime: 3.0.0 + path-browserify: 1.0.1 + post-me: 0.4.5 + randombytes: 2.1.0 + sjcl: 1.0.8 + skynet-mysky-utils: 0.3.1 + tweetnacl: 1.0.3 + url-join: 4.0.1 + url-parse: 1.5.10 + transitivePeerDependencies: + - debug + dev: true + + /skynet-mysky-utils/0.3.1: + resolution: {integrity: sha512-UO9U1LUjwn+E8N1CV2iVJbl0VhVVKPwcOSTzgP9thX8Qp/zT+/+TVb1JTimqbd8+/gZhaP8BzrnmgRs6EVtFxA==} + dependencies: + post-me: 0.4.5 + dev: true + + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /strip-ansi/6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /to-data-view/1.1.0: + resolution: {integrity: sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==} + dev: true + + /tslib/2.4.1: + resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + dev: true + + /tweetnacl/1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + dev: true + + /typescript/4.9.4: + resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /url-join/4.0.1: + resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + dev: true + + /url-parse/1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: true + + git.lumeweb.com/LumeWeb/peer-discovery/d2bd926275103d60fdd3c7c432eae5c278f49261: + resolution: {commit: d2bd926275103d60fdd3c7c432eae5c278f49261, repo: https://git.lumeweb.com/LumeWeb/peer-discovery.git, type: git} + name: '@lumeweb/peer-discovery' + version: 0.1.0 + dependencies: + b4a: 1.6.1 + dev: false diff --git a/src-build/build.ts b/src-build/build.ts new file mode 100644 index 0000000..8703c34 --- /dev/null +++ b/src-build/build.ts @@ -0,0 +1,218 @@ +// This is the standard build script for a kernel module. + +import * as fs from "fs"; +import read from "read"; +import * as bip39 from "@scure/bip39"; +import { wordlist } from "@scure/bip39/wordlists/english.js"; +//@ts-ignore +import { SkynetClient } from "@skynetlabs/skynet-nodejs"; + +// Helper variables to make it easier to return empty values alongside errors. +const nu8 = new Uint8Array(0); +const nkp = { + publicKey: nu8, + secretKey: nu8, +}; + +// readFile is a wrapper for fs.readFileSync that handles the try-catch for the +// caller. +function readFile(fileName: string): [string, string | null] { + try { + let data = fs.readFileSync(fileName, "utf8"); + return [data, null]; + } catch (err) { + return ["", "unable to read file: " + JSON.stringify(err)]; + } +} + +// readFileBinary is a wrapper for fs.readFileSync that handles the try-catch +// for the caller. +function readFileBinary(fileName: string): [Uint8Array, string | null] { + try { + let data = fs.readFileSync(fileName, null); + return [data, null]; + } catch (err) { + return [nu8, "unable to read file: " + JSON.stringify(err)]; + } +} + +// writeFile is a wrapper for fs.writeFileSync which handles the try-catch in a +// non-exception way. +function writeFile(fileName: string, fileData: string): string | null { + try { + fs.writeFileSync(fileName, fileData); + return null; + } catch (err) { + return "unable to write file: " + JSON.stringify(err); + } +} + +// handlePass handles all portions of the script that occur after the password +// has been requested. If no password needs to be requested, handlePass will be +// called with a null input. We need to structure the code this way because the +// password reader is async and we can only access the password when using a +// callback. +function handlePass(password: string) { + try { + // If we are running prod and the seed file does not exist, we + // need to confirm the password and also warn the user to use a + // secure password. + if (!fs.existsSync(seedFile) && process.argv[2] === "prod") { + // The file does not exist, we need to confirm the + // password. + console.log(); + console.log( + "No production entry found for module. Creating new production module..." + ); + console.log( + "If someone can guess the password, they can push arbitrary changes to your module." + ); + console.log("Please use a secure password."); + console.log(); + read( + { prompt: "Confirm Password: ", silent: true }, + function (err: any, confirmPassword: string) { + if (err) { + console.error("unable to fetch password:", err); + process.exit(1); + } + if (password !== confirmPassword) { + console.error("passwords do not match"); + process.exit(1); + } + handlePassConfirm(moduleSalt, password); + } + ); + } else { + // If the seed file does exist, or if we are using dev, + // there's no need to confirm the password but we do + // need to pass the logic off to the handlePassConfirm + // callback. + handlePassConfirm(moduleSalt, password); + } + } catch (err) { + console.error("Unable to read seedFile:", err); + process.exit(1); + } +} + +// handlePassConfirm handles the full script after the confirmation password +// has been provided. If not confirmation password is needed, this function +// will be called anyway using the unconfirmed password as input. +function handlePassConfirm(seed: string, password: string) { + // Create the seedFile if it does not exist. For dev we just save the + // seed to disk outright, because this is a dev build and therefore not + // security sensitive. Also the dev seed does not get pushed to the + // github repo. + // + // For prod, we use the seed to create a new seed (called the shield) + // which allows us to verify that the developer has provided the right + // password when deploying the module. The shield does get pushed to + // the github repo so that the production module is the same on all + // devices. + if (!fs.existsSync(seedFile) && process.argv[2] !== "prod") { + // Generate the seed phrase and write it to the file. + let seedPhrase = bip39.generateMnemonic(wordlist); + let errWF = writeFile(seedFile, seedPhrase); + if (errWF !== null) { + console.error("unable to write file:", errWF); + process.exit(1); + } + } else if (!fs.existsSync(seedFile) && process.argv[2] === "prod") { + // Generate the seed phrase. + let seedPhrase = bip39.generateMnemonic(wordlist); + // Write the registry link to the file. + } + + // Load or verify the seed. If this is prod, the password is used to + // create and verify the seed. If this is dev, we just load the seed + // with no password. + let seedPhrase: string; + let registryLink: string; + if (process.argv[2] === "prod") { + // Generate the seed phrase from the password. + seedPhrase = bip39.generateMnemonic(wordlist); + } else { + let [sp, errRF] = readFile(seedFile); + if (errRF !== null) { + console.error("unable to read seed phrase for dev command from disk"); + process.exit(1); + } + seedPhrase = sp; + } + + let metadata = { + Filename: "index.js", + }; + const client = new SkynetClient("https://web3portal.com"); + client + .uploadFile("dist/index.js") + .then((result: any) => { + console.log("Immutable Link for kernel:", result); + }) + .catch((err: any) => { + console.error("unable to upload file", err); + process.exit(1); + }); +} + +// Add a newline for readability. +console.log(); + +// Check for a 'dev' or 'prod' input to the script. +if (process.argv.length !== 3) { + console.error("need to provide either 'dev' or 'prod' as an input"); + process.exit(1); +} + +// Create the build folder if it does not exist. +if (!fs.existsSync("build")) { + fs.mkdirSync("build"); +} + +// Determine the seed file. +let seedFile: string; +if (process.argv[2] === "prod") { + seedFile = "module-skylink"; +} else if (process.argv[2] === "dev") { + seedFile = "build/dev-seed"; +} else { + console.error("need to provide either 'dev' or 'prod' as an input"); + process.exit(1); +} + +// If doing a prod deployment, check whether the salt file exists. If it does +// not, create it. +let moduleSalt: string; +if (!fs.existsSync(".module-salt")) { + moduleSalt = bip39.generateMnemonic(wordlist); + let errWF = writeFile(".module-salt", moduleSalt); + if (errWF !== null) { + console.error("unable to write module salt file:", errWF); + process.exit(1); + } +} else { + let [ms, errRF] = readFile(".module-salt"); + if (errRF !== null) { + console.error("unable to read moduleSalt"); + process.exit(1); + } + ms = ms.replace(/\n$/, ""); + moduleSalt = ms; +} + +// Need to get a password if this is a prod build. +if (process.argv[2] === "prod") { + read( + { prompt: "Password: ", silent: true }, + function (err: any, password: string) { + if (err) { + console.error("unable to fetch password:", err); + process.exit(1); + } + handlePass(password); + } + ); +} else { + handlePass(""); +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..22a626c --- /dev/null +++ b/src/index.ts @@ -0,0 +1,92 @@ +import { addHandler, handleMessage } from "libkmodule"; +import type { ActiveQuery } from "libkmodule"; +import { PeerDiscovery } from "@lumeweb/peer-discovery"; +import type { PeerSource, Peer } from "@lumeweb/peer-discovery"; +import { callModule, logErr } from "libkmodule"; + +onmessage = handleMessage; + +const discovery = new PeerDiscovery(); + +function wrapSourceModule(module: string): PeerSource { + return async (pubkey: Buffer, options = {}): Promise => { + const [ret, err] = await callModule(module, "discover", { + pubkey, + options, + }); + if (err) { + logErr(err); + return false; + } + + return ret as Peer; + }; +} + +async function handleRegisterSource(aq: ActiveQuery): Promise { + let [name, error] = await callModule(aq.domain, "name"); + + if (error) { + aq.reject(error); + return; + } + + if (discovery.sourceExists(name)) { + aq.reject(`Source ${name} already exists`); + return; + } + + discovery.registerSource(name, wrapSourceModule(aq.domain)); +} + +function handleRemoveSource(aq: ActiveQuery): void { + if (!("name" in aq.callerInput)) { + aq.reject(`missing name`); + return; + } + + aq.respond(discovery.removeSource(aq.callerInput.name)); +} + +function handleRemoveAllSources(aq: ActiveQuery): void { + discovery.removeAllSources(); + + aq.respond(); +} + +function handleSourceExists(aq: ActiveQuery): void { + if (!("name" in aq.callerInput)) { + aq.reject(`missing name`); + return; + } + + aq.respond(discovery.sourceExists(aq.callerInput.name)); +} + +async function handleDiscover(aq: ActiveQuery) { + if (!("pubkey" in aq.callerInput)) { + aq.reject(`missing pubkey`); + return; + } + + if ( + "options" in aq.callerInput && + typeof aq.callerInput.options !== "object" + ) { + aq.reject(`options must be an object`); + return; + } + + const ret = await discovery.discover( + aq.callerInput.pubkey, + aq.callerInput.options + ); + + aq.respond(ret); +} + +addHandler("register", handleRegisterSource); +addHandler("remove", handleRemoveSource); +addHandler("removeAll", handleRemoveAllSources); +addHandler("exists", handleSourceExists); +addHandler("discover", handleDiscover); diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 0000000..90439ba --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "declaration": true, + "outDir": "./dist-build", + "strict": true, + "esModuleInterop": true + }, + "include": ["src-build"], + "exclude": ["node_modules", "**/__tests__/*"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..f0702eb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "esnext", + "declaration": true, + "moduleResolution": "nodenext", + "outDir": "./build", + "strict": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true + }, + "include": ["src"], + "exclude": ["node_modules", "**/__tests__/*"] +}