This commit is contained in:
Derrick Hammer 2023-04-03 13:29:20 -04:00
parent 7efd901b97
commit 2e15a16faa
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
15 changed files with 1293 additions and 5219 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
"description": "Lume Web is your decentralized gateway into the web3 internet, the web owned and controlled by its users",
"manifest_version": 2,
"name": "Lume Web",
"version": "0.3.0",
"version": "0.3.0.3",
"homepage_url": "https://lumeweb.com",
"icons": {
"48": "icon.png",
@ -24,7 +24,7 @@
"content_scripts": [
{
"matches": [
"http://kernel.skynet/"
"http://kernel.lume/"
],
"js": [
"bootloader.js"

View File

@ -16,7 +16,7 @@ esbuild.buildSync({
esbuild.buildSync({
entryPoints: ["src/main/bootloader.ts"],
outfile: "dist/bootloader.js",
format: "esm",
format: "iife",
bundle: true,
legalComments: "external",
// minify: true
@ -27,14 +27,14 @@ esbuild.buildSync({
esbuild.buildSync({
entryPoints: ["src/main/bridge.ts"],
outfile: "dist/bridge.js",
format: "esm",
format: "iife",
bundle: true,
legalComments: "external",
// minify: true
define: {
global: "self",
},
});
}); /*
esbuild.buildSync({
entryPoints: ["src/main/crypto.ts"],
outfile: "dist/crypto.js",
@ -58,3 +58,4 @@ esbuild.buildSync({
global: "window",
}
});
*/

View File

@ -15,45 +15,45 @@
"author": "David Vorick",
"license": "MIT",
"devDependencies": {
"@lumeweb/kernel-dns-client": "https://github.com/LumeWeb/kernel-dns-client.git",
"@lumeweb/webextension-polyfill": "https://github.com/LumeWeb/webextension-polyfill.git",
"@helia/unixfs": "^1.2.1",
"@rollup/plugin-node-resolve": "^13.3.0",
"@types/ejs": "^3.1.1",
"@types/ejs": "^3.1.2",
"@types/read": "^0.0.29",
"@types/webextension-polyfill": "^0.9.0",
"@typescript-eslint/eslint-plugin": "^5.18.0",
"@types/webextension-polyfill": "^0.9.2",
"@typescript-eslint/eslint-plugin": "^5.57.0",
"browserify-fs": "^1.0.0",
"cpy-cli": "^4.1.0",
"esbuild": "^0.14.51",
"eslint": "^8.13.0",
"cpy-cli": "^4.2.0",
"esbuild": "^0.14.54",
"eslint": "^8.37.0",
"events": "^3.3.0",
"path-browserify": "^1.0.1",
"prettier": "^2.6.2",
"prettier": "^2.8.7",
"process": "^0.11.10",
"rimraf": "^3.0.2",
"rollup": "^2.75.6",
"rollup": "^2.79.1",
"stream": "^0.0.2",
"typescript": "^4.6.3",
"util": "^0.12.4",
"typescript": "^4.9.5",
"util": "^0.12.5",
"webextension-polyfill": "^0.9.0"
},
"dependencies": {
"@lumeweb/kernel-dht-client": "https://github.com/LumeWeb/kernel-dht-client.git",
"@lumeweb/kernel-ipfs-client": "https://github.com/LumeWeb/kernel-ipfs-client.git",
"@lumeweb/libresolver": "https://github.com/LumeWeb/libresolver.git",
"@lumeweb/tld-enum": "https://github.com/LumeWeb/list-of-top-level-domains.git",
"@peculiar/webcrypto": "^1.4.0",
"dexie": "^3.2.2",
"ejs": "^3.1.8",
"@lumeweb/kernel-dns-client": "git+https://git.lumeweb.com/LumeWeb/kernel-dns-client.git",
"@lumeweb/kernel-ipfs-client": "git+https://git.lumeweb.com/LumeWeb/kernel-ipfs-client.git",
"@lumeweb/libresolver": "git+https://git.lumeweb.com/LumeWeb/libresolver.git",
"@lumeweb/tld-enum": "git+https://git.lumeweb.com/LumeWeb/list-of-top-level-domains.git",
"@lumeweb/webextension-polyfill": "git+https://git.lumeweb.com/LumeWeb/webextension-polyfill.git",
"@peculiar/webcrypto": "^1.4.3",
"@siaweb/libweb": "git+https://git.lumeweb.com/LumeWeb/libsiaweb.git",
"buffer": "^6.0.3",
"is-ipfs": "^6.0.2",
"libkernel": "https://github.com/LumeWeb/libextension.git",
"libkernel": "^0.1.48",
"libskynet": "^0.0.62",
"node-cache": "^5.1.2"
},
"browser": {
"libkmodule": false,
"path": "path-browserify",
"crypto": "crypto-browserify",
"fs": "browserify-fs",
"crypto": "crypto-browserify"
"libkmodule": false,
"path": "path-browserify"
}
}

7
src/clients.ts Normal file
View File

@ -0,0 +1,7 @@
import { createClient as createDnsClient } from "@lumeweb/kernel-dns-client";
import { createClient as createIpfsClient } from "@lumeweb/kernel-ipfs-client";
const dnsClient = createDnsClient();
const ipfsClient = createIpfsClient();
export { dnsClient, ipfsClient };

View File

@ -7,86 +7,17 @@ import {
OnRequestDetailsType,
StreamFilter,
} from "../types.js";
import { getRelayProxies, streamToArray } from "../util.js";
import { ipfsPath, ipnsPath, path } from "is-ipfs";
import {
fetchIpfs,
fetchIpns,
statIpfs,
statIpns,
} from "@lumeweb/kernel-ipfs-client";
import ejs from "ejs";
import { cacheDb } from "../databases.js";
import { getRelayProxies } from "../util.js";
import { ipfsPath, ipnsPath, path as checkPath } from "is-ipfs";
import { createClient } from "@lumeweb/kernel-ipfs-client";
import { DNS_RECORD_TYPE, DNSResult } from "@lumeweb/libresolver";
import RequestStream from "../requestStream.js";
import ContentFilterRegistry from "../contentFilterRegistry.js";
const INDEX_HTML_FILES = ["index.html", "index.htm", "index.shtml"];
const DIRECTORY_TEMPLATE = ejs.compile(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= path %></title>
<style></style>
</head>
<body>
<div id="header" class="row">
<div class="col-xs-2">
<div id="logo" class="ipfs-logo"></div>
</div>
</div>
<br>
<div class="col-xs-12">
<div class="panel panel-default">
<div class="panel-heading">
<strong>Index of <%= path %></strong>
</div>
<table class="table table-striped">
<tbody>
<tr>
<td class="narrow">
<div class="ipfs-icon ipfs-_blank">&nbsp;</div>
</td>
<td class="padding">
<a href="<%= parentHref %>">..</a>
</td>
<td></td>
</tr>
<% links.forEach(function (link) { %>
<tr>
<td><div class="ipfs-icon ipfs-_blank">&nbsp;</div></td>
<td><a href="<%= link.link %>"><%= link.name %></a></t>
<td><%= link.size %></td>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</div>
</body>
</html>`);
interface StatFileResponse {
exists: boolean;
contentType: string | null;
error: any;
directory: boolean;
files: StatFileSubfile[];
timeout: boolean;
size: number;
}
interface StatFileSubfile {
name: string;
size: number;
}
const MAX_CACHE_SIZE = 1024 * 1024 * 1024 * 50;
import { UnixFSStats } from "@helia/unixfs";
import * as path from "path";
export default class IpfsProvider extends BaseProvider {
private _client = createClient();
async shouldHandleRequest(
details: OnBeforeRequestDetailsType
): Promise<boolean> {
@ -99,15 +30,16 @@ export default class IpfsProvider extends BaseProvider {
}
let contentRecords = (dnsResult as DNSResult).records.map(
(item) => "/" + item.value.replace("://", "/").replace(/^\+/, "/")
(item: { value: string }) =>
"/" + item.value.replace("://", "/").replace(/^\+/, "/")
);
contentRecords = contentRecords.filter((item) => path(item));
contentRecords = contentRecords.filter((item) => checkPath(item));
if (!contentRecords.length) {
return false;
}
this.setData(details, "hash", contentRecords.shift());
this.setData(details, "cid", contentRecords.shift());
return true;
}
@ -131,64 +63,35 @@ export default class IpfsProvider extends BaseProvider {
): Promise<BlockingResponse | boolean> {
let urlObj = new URL(details.url);
let urlPath = urlObj.pathname;
let hash = this.getData(details, "hash");
let resp: StatFileResponse | null = null;
let fetchMethod: typeof fetchIpfs | typeof fetchIpns;
const cid = this.getData(details, "cid");
let err;
let contentType: string;
let contentSize = 0;
let stat: UnixFSStats | null = null;
let cachedPage: { contentType: string; data: Blob } | null = null;
let parsedPath = path.parse(urlPath);
let contentSize;
try {
// @ts-ignore
cachedPage = await cacheDb.items.where("url").equals(details.url).first();
} catch {}
if (!cachedPage) {
try {
if (ipfsPath(hash)) {
hash = hash.replace("/ipfs/", "");
resp = await statIpfs(hash.replace("/ipfs/", ""), urlPath);
fetchMethod = fetchIpfs;
} else if (ipnsPath(hash)) {
hash = hash.replace("/ipns/", "");
resp = await statIpns(hash.replace("/ipns/", ""), urlPath);
fetchMethod = fetchIpns;
} else {
err = "invalid content";
}
} catch (e: any) {
err = (e as Error).message;
if (ipnsPath(parsedPath.root)) {
let ipnsLookup = await this._client.ipns(cid);
stat = await this._client.stat(ipnsLookup);
} else if (ipfsPath(parsedPath.root)) {
stat = await this._client.stat(cid);
}
contentType = resp?.contentType as string;
if (contentType?.includes(";")) {
contentType = contentType?.split(";").shift() as string;
}
contentSize = resp?.size as number;
} else {
contentType = cachedPage.contentType;
contentSize = cachedPage.data.size;
} catch (e) {
err = (e as Error).message;
}
if (resp) {
if (!resp.exists) {
err = "404";
}
if (resp.directory) {
contentType = "text/html";
}
if (err) {
err = "404";
}
this.setData(details, "contentType", contentType);
// this.setData(details, "contentType", contentType);
const isSmallFile = contentSize <= MAX_CACHE_SIZE;
const reqStream = new RequestStream(
details,
isSmallFile && ContentFilterRegistry.hasFilters(contentType)
details
/* ContentFilterRegistry.hasFilters(contentType)
? ContentFilterRegistry.filter(contentType)
: undefined
: undefined*/
);
reqStream.start();
@ -196,49 +99,20 @@ export default class IpfsProvider extends BaseProvider {
reqStream.close();
return {};
}
if (cachedPage) {
(
cachedPage?.data.stream() as unknown as ReadableStream<Uint8Array>
).pipeThrough(reqStream.stream);
return {};
}
if (resp?.directory) {
let indexFiles =
resp?.files.filter((item) => INDEX_HTML_FILES.includes(item.name)) ||
[];
if (indexFiles.length > 0) {
urlPath += `/${indexFiles[0].name}`;
}
}
if (isSmallFile) {
streamToArray(reqStream.readableStream).then((data: Uint8Array) => {
// @ts-ignore
return cacheDb.items.put({
url: details.url,
contentType,
data: new Blob([data.buffer], { type: contentType }),
timestamp: Date.now(),
});
});
}
const streamWriter = reqStream.stream.writable.getWriter();
// @ts-ignore
fetchMethod?.(hash, urlPath, (data: Buffer) => {
streamWriter.write(data);
})
.then(() => {
streamWriter.releaseLock();
return reqStream.close();
})
.catch((e: any) => {
const reader = this._client.cat(parsedPath.root, { path: parsedPath.dir });
(async function () {
try {
for await (const chunk of reader.iterable) {
streamWriter.write(chunk);
}
} catch {
streamWriter.releaseLock();
reqStream.close();
});
}
})();
return {};
}

View File

@ -1,117 +0,0 @@
import BaseProvider from "./baseProvider.js";
import {
BlockingResponse,
OnBeforeRequestDetailsType,
OnHeadersReceivedDetailsType,
OnRequestDetailsType,
} from "../types.js";
import { validSkylink } from "libskynet";
import { downloadSkylink, getRelayProxies } from "../util.js";
import browser from "@lumeweb/webextension-polyfill";
import { DNS_RECORD_TYPE, DNSResult } from "@lumeweb/libresolver";
export default class SkynetProvider extends BaseProvider {
async shouldHandleRequest(
details: OnBeforeRequestDetailsType
): Promise<boolean> {
let dnsResult: DNSResult | boolean | string = await this.resolveDns(
details,
[DNS_RECORD_TYPE.CONTENT, DNS_RECORD_TYPE.TEXT]
);
if (!dnsResult) {
return false;
}
let contentRecords = (dnsResult as DNSResult).records
.map((item) => {
item.value = item.value.replace("sia://", "");
return item;
})
.filter((item) => {
try {
return validSkylink(item.value);
} catch (e) {
return false;
}
});
if (!contentRecords.length) {
return false;
}
this.setData(details, "hash", contentRecords.shift()?.value);
return true;
}
async handleProxy(details: OnRequestDetailsType): Promise<any> {
return getRelayProxies();
}
async handleRequest(
details: OnBeforeRequestDetailsType
): Promise<BlockingResponse | boolean> {
const hash = this.getData(details, "hash");
let urlObj = new URL(details.url);
let path = urlObj.pathname;
let fileData: any, err;
if (urlObj.protocol == "https") {
urlObj.protocol = "http";
return { redirectUrl: urlObj.toString() };
}
try {
[fileData, err] = await downloadSkylink(hash, path);
} catch (e: any) {
debugger;
this.setData(details, "error", (e as Error).message);
return {};
}
if (err) {
this.setData(details, "error", err);
return {};
}
this.setData(details, "headers", fileData.response?.headers);
const filter = browser.webRequest.filterResponseData(details.requestId);
filter.ondata = () => {};
filter.onstop = () => {
fileData.response.arrayBuffer().then((data: any) => {
filter.write(data);
filter.close();
});
};
return true;
}
async handleHeaders(
details: OnHeadersReceivedDetailsType
): Promise<BlockingResponse | boolean> {
const err = this.getData(details, "error");
let headers: Headers = this.getData(details, "headers") as Headers;
if (err) {
return {
responseHeaders: [
{
name: "Status-Code",
value: err == "404" ? "404" : "400",
},
{
name: "Content-Type",
value: "text/html; charset=utf8",
},
],
};
}
return {
responseHeaders: Array.from(headers).map((item: string[]) => {
return { name: item[0], value: item[1] };
}),
};
}
}

View File

@ -2,20 +2,12 @@ import browser from "@lumeweb/webextension-polyfill";
import type WebEngine from "./webEngine.js";
import type { Menus, Tabs } from "./types.js";
import IpfsProvider from "./contentProviders/ipfsProvider.js";
import { cacheDb } from "./databases.js";
export default function setup(engine: WebEngine) {
browser.menus.create({
title: "Clear Cache",
id: "clear-cache",
onclick: async (info: Menus.OnClickData, tab: Tabs.Tab) => {
// @ts-ignore
await cacheDb.items
.where("url")
.startsWithIgnoreCase(
`http://${new URL(info.pageUrl as string).hostname}`
)
.delete();
browser.tabs.reload(tab.id);
},
});

View File

@ -1,7 +0,0 @@
import Dexie from "dexie";
export const cacheDb = new Dexie("LumeWebIFSCache");
cacheDb.version(1).stores({
items: `url,contentType,data,timestamp`,
});

View File

@ -1,16 +1,13 @@
import NodeCache from "node-cache";
import {
ready as dnsReady,
resolve as resolveDns,
} from "@lumeweb/kernel-dns-client";
import {
DNS_RECORD_TYPE,
DNSRecord,
DNSResult,
ResolverOptions,
} from "@lumeweb/libresolver";
import { blake2b, bufToHex, Err } from "libskynet/dist";
import { getDnsSetupPromise } from "./main/vars.js";
import { createClient, DnsClient } from "@lumeweb/kernel-dns-client";
import { dnsClient } from "./clients.js";
const cache = new NodeCache({ stdTTL: 60 });
@ -32,7 +29,7 @@ export async function resolve(
let res;
try {
res = await resolveDns(domain, options, bypassCache);
res = await dnsClient.resolve(domain, options, bypassCache);
} catch (e: any) {
return e as Error;
}

View File

@ -1,11 +1,9 @@
import tldEnum from "@lumeweb/tld-enum";
import WebEngine from "../webEngine.js";
import InternalProvider from "../contentProviders/internalProvider.js";
import SkynetProvider from "../contentProviders/skynetProvider.js";
import ServerProvider from "../contentProviders/serverProvider.js";
import { init } from "libkernel";
import { init, kernelLoaded } from "libkernel";
import IpfsProvider from "../contentProviders/ipfsProvider.js";
import { ready as dnsReady } from "@lumeweb/kernel-dns-client";
import {
addQuery,
getAuthStatusResolve,
@ -33,9 +31,11 @@ import {
setOpenPort,
setTimer,
} from "./vars.js";
// @ts-ignore
import browser from "@lumeweb/webextension-polyfill";
import setupContextMenus from "../contextMenu.js";
import { callModule } from "libkernel";
import { ipfsClient } from "../clients.js";
function logLargeObjects() {
let queriesLen = Object.keys(getQueries()).length;
@ -49,6 +49,7 @@ function logLargeObjects() {
setTimer(getTimer() * 1.25);
setTimeout(logLargeObjects, getTimer());
}
setTimeout(logLargeObjects, getTimer());
export function queryKernel(query: any): Promise<any> {
@ -75,9 +76,12 @@ export function queryKernel(query: any): Promise<any> {
});
});
}
function handleKernelMessage(event: MessageEvent) {
let data = event.data.data;
console.log("handleKernelMessage debug", event.data);
if (event.data.method === "kernelBridgeVersion") {
getBlockForBridge().then(() => {
for (let [, port] of Object.entries(getOpenPorts())) {
@ -152,6 +156,8 @@ function handleBridgeMessage(
data: any,
domain: string
) {
console.log("handleBridgeMessage debug", data.data);
if (data.method === "bridgeLoaded") {
getBridgeLoadedResolve()();
return;
@ -174,8 +180,10 @@ function handleBridgeMessage(
});
data["domain"] = domain;
}
getKernelIframe().contentWindow!.postMessage(data, "http://kernel.lume");
}
function bridgeListener(port: any) {
let portNonce = getPortsNonce();
increasePortsNonce();
@ -206,14 +214,24 @@ async function boot() {
const engine = new WebEngine();
engine.registerContentProvider(new InternalProvider(engine));
engine.registerContentProvider(new SkynetProvider(engine));
engine.registerContentProvider(new IpfsProvider(engine));
engine.registerContentProvider(new ServerProvider(engine));
setKernelIframe(document.createElement("iframe"));
getKernelIframe().src = "http://kernel.lume";
getKernelIframe().onload = init;
document.body.appendChild(getKernelIframe());
await new Promise((resolve) => {
getKernelIframe().onload = () => {
init().then(resolve);
};
document.body.appendChild(getKernelIframe());
});
// @ts-ignore
window.callModule = callModule;
await kernelLoaded();
await ipfsClient.ready();
setupContextMenus(engine);
setDnsSetupPromise(dnsSetup());
@ -222,19 +240,12 @@ async function boot() {
async function dnsSetup() {
const resolvers = [
"AQBXtVkPDbZ5Qmjl8dzJ0siSYaFcS3XbDZHapxmZCLfwfg", // icann
"AQAI3TbarrXRxWtrb_5XO-gMYg-UsjVAChue5JEoqywbAw", // eip137
"AQD0s0wZNpZCVg_iO96E6Ff66WxGa2CZst_DCYR_DoQPxw", // solana
"AQDtYcJGbquAHA-idtZ-gPOlNBgEVeCZtZUtsyL_J5ZiUA", // algorand
"AQDkqoCzCR6s5MP_k6Ee9QWfEwaH5-7XleCKFL1CdxExxQ", // avax
"AQC7ALr-OtkFT7qZby2BdMMNbTRXHNMGlpV6r96b35Z79Q", // evmos
"AQAmQoZLu1DqIiZaRWRpomvMarQ8Uc3kdHJQBo0r-9uYtg", // handshake
"_B1zdE-P7e1csLVoT9w3DvgxWGdDdUj9tnkRGzXyYV-rkg", // ens
"vAN0mq5cLYOK2e2Wk1Is980LYSW3reHKrd-w2-vqWfwNUw", // hns
];
for (const resolver of resolvers) {
await callModule(resolver, "register");
}
await dnsReady();
}
boot();

View File

@ -1,28 +1,14 @@
import {
addContextToErr,
b64ToBuf,
bufToHex,
bufToStr,
computeRegistrySignature,
defaultPortalList,
deriveChildSeed,
deriveRegistryEntryID,
downloadSkylink,
Ed25519Keypair,
entryIDToSkylink,
Err,
hexToBuf,
progressiveFetch,
progressiveFetchResult,
taggedRegistryEntryKeys,
objAsString,
verifyRegistryWriteResponse,
} from "libskynet";
} from "@siaweb/libweb";
var browser: any; // tsc
declare var browser: any; // tsc
const defaultKernelResolverLink =
"AQDJDoXMJiiEMBxXodQvUV89qtQHsnXWyV1ViQ9M1pMjUg";
const defaultKernelLink = "RAAdkljTc2ZmgSNV5EKr-fJZSEEz8irbf2QEqBw9hoEIKA";
document.title = "kernel.lume";
let header = document.createElement("h1");
@ -254,175 +240,75 @@ function downloadKernel(
kernelSkylink: string
): Promise<[kernelCode: string, err: Err]> {
return new Promise((resolve) => {
downloadSkylink(kernelSkylink).then(([fileData, err]) => {
if (err === "404") {
resolve(["", err]);
fetch(`https://web3portal.com/${kernelSkylink}`).then((result) => {
if (result.status === 404) {
resolve(["", result.status.toString()]);
return;
}
if (!result.ok) {
resolve(["", result.statusText]);
return;
}
result
.blob()
.then((blob) => {
return blob.arrayBuffer();
})
.then((data) => {
let [kernelCode, errBBTS] = bufToStr(data);
if (err !== null) {
resolve([
"",
addContextToErr(err, "unable to download the default kernel"),
]);
return;
}
if (errBBTS !== null) {
resolve([
"",
addContextToErr(null, "unable to decode the default kernel"),
]);
return;
}
let [kernelCode, errBBTS] = bufToStr(fileData);
if (errBBTS !== null) {
resolve([
"",
addContextToErr(err, "unable to decode the default kernel"),
]);
return;
}
resolve([kernelCode, null]);
resolve([kernelCode, null]);
});
});
});
}
function downloadDefaultKernel(): Promise<[kernelCode: string, err: Err]> {
return downloadKernel(defaultKernelResolverLink);
return downloadKernel(defaultKernelLink);
}
function setUserKernelAsDefault(keypair: Ed25519Keypair, dataKey: Uint8Array) {
log(
"user kernel not found, setting user kernel to " + defaultKernelResolverLink
);
async function loadKernel() {
let [kernelCode, err] = await downloadDefaultKernel();
let [defaultKernelSkylink, err64] = b64ToBuf(defaultKernelResolverLink);
if (err64 !== null) {
log("unable to convert default kernel link to a Uint8Array");
if (err !== null) {
let extErr = addContextToErr(err, "unable to download kernel");
kernelLoaded = extErr;
logErr(extErr);
sendAuthUpdate();
return;
}
let [sig, errCRS] = computeRegistrySignature(
keypair.secretKey,
dataKey,
defaultKernelSkylink,
0n
);
if (errCRS !== null) {
log(
addContextToErr(
errCRS,
"unable to compute registry signature to set user kernel"
)
);
try {
eval(kernelCode);
kernelLoaded = "success";
sendAuthUpdate();
log("kernel successfully loaded");
return;
} catch (err: any) {
let extErr = addContextToErr(err, "unable to eval kernel");
kernelLoaded = extErr;
logErr(extErr);
logErr(err.toString());
console.error(extErr);
console.error(err);
sendAuthUpdate();
return;
}
let dataKeyHex = bufToHex(dataKey);
let endpoint = "/skynet/registry";
let postBody = {
publickey: {
algorithm: "ed25519",
key: Array.from(keypair.publicKey),
},
datakey: dataKeyHex,
revision: 0,
data: Array.from(defaultKernelSkylink),
signature: Array.from(sig),
};
let fetchOpts = {
method: "post",
body: JSON.stringify(postBody),
};
progressiveFetch(
endpoint,
fetchOpts,
defaultPortalList,
verifyRegistryWriteResponse
).then((result: progressiveFetchResult) => {
if (result.success !== true) {
log("unable to update the user kernel registry entry\n", result.logs);
return;
}
log(
"successfully updated the user kernel registry entry to the default kernel"
);
});
}
function downloadUserKernel(): Promise<[kernelCode: string, err: Err]> {
return new Promise((resolve) => {
let kernelEntrySeed = deriveChildSeed(userSeed, "userPreferredKernel2");
let [keypair, dataKey, errTREK] = taggedRegistryEntryKeys(
kernelEntrySeed,
"user kernel"
);
if (errTREK !== null) {
resolve([
"",
addContextToErr(errTREK, "unable to create user kernel registry keys"),
]);
return;
}
let [entryID, errREID] = deriveRegistryEntryID(keypair.publicKey, dataKey);
if (errREID !== null) {
resolve([
"",
addContextToErr(errREID, "unable to derive registry entry id"),
]);
return;
}
let userKernelSkylink = entryIDToSkylink(entryID);
downloadKernel(userKernelSkylink).then(([kernelCode, err]) => {
if (err === "404") {
downloadDefaultKernel().then(([defaultCode, errDefault]) => {
if (errDefault === null) {
setUserKernelAsDefault(keypair, dataKey);
}
resolve([defaultCode, errDefault]);
return;
});
return;
}
log("found user kernel, using: " + userKernelSkylink);
resolve([kernelCode, err]);
});
});
}
function loadKernel() {
downloadUserKernel().then(([kernelCode, err]) => {
if (err !== null) {
let extErr = addContextToErr(err, "unable to download kernel");
kernelLoaded = extErr;
logErr(extErr);
sendAuthUpdate();
return;
}
try {
eval(kernelCode);
kernelLoaded = "success";
sendAuthUpdate();
log("kernel successfully loaded");
return;
} catch (err: any) {
let extErr = addContextToErr(err, "unable to eval kernel");
kernelLoaded = extErr;
logErr(extErr);
logErr(err.toString());
console.error(extErr);
console.error(err);
sendAuthUpdate();
return;
}
});
}
let loginComplete = false;
let logoutComplete = false;
let kernelLoaded = "not yet";
function sendAuthUpdate() {
window.parent.postMessage(
/* window.parent.postMessage(
{
method: "kernelAuthStatus",
data: {
@ -432,13 +318,13 @@ function sendAuthUpdate() {
},
},
"*"
);
);*/
}
sendAuthUpdate();
let userSeed: Uint8Array;
var userSeed: Uint8Array;
function checkForLoadKernel() {
let userSeedString = window.localStorage.getItem("v1-seed");
let userSeedString = window.localStorage.getItem("v1-key");
if (userSeedString === null) {
sendAuthUpdate();
return;

View File

@ -36,6 +36,11 @@ function handleBackgroundMessage(data: any) {
}
}
/* port.postMessage({
method: "log1",
data: data,
});*/
// Pass the message through to the main page.
window.postMessage(data);
}
@ -130,6 +135,12 @@ function handleMessage(event: MessageEvent) {
// Everything else just gets ignored.
}
window.addEventListener("message", handleMessage);
window.addEventListener("message", (event) => {
port.postMessage({
method: "log1",
data: [event.data, event.origin],
});
});
port.postMessage({
method: "bridgeLoaded",
});

View File

@ -1,21 +1,8 @@
import {
addContextToErr,
b64ToBuf,
defaultPortalList,
Err,
objAsString,
progressiveFetch,
progressiveFetchResult,
validSkylink,
verifyDownloadResponse,
} from "libskynet";
import { DHT } from "@lumeweb/kernel-dht-client";
import { defaultPortalList } from "libskynet";
defaultPortalList.unshift("https://web3portal.com");
defaultPortalList.pop();
const relayDht = new DHT();
export function isIp(ip: string) {
return /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(
ip
@ -33,12 +20,15 @@ export function normalizeDomain(domain: string): string {
}
export async function getRelayProxies() {
let relays: string[] = await relayDht.getRelayServers();
let proxies = [{ type: "http", host: "localhost", port: 25252 }];
//let relays: string[] = await relayDht.getRelayServers();
let proxies = [
{ type: "http", host: "localhost", port: 25252 },
{ type: "http", host: "161.35.121.185", port: 25252 },
];
/*
for (const relay of relays) {
proxies.push({ type: "http", host: new URL(relay).hostname, port: 25252 });
}
}*/
return proxies;
}
@ -46,9 +36,6 @@ export async function getRelayProxies() {
export const requestProxies = [
{ type: "http", host: "localhost", port: 25252 },
{ type: "http", host: "web3portal.com", port: 80 },
{ type: "http", host: "siasky.net", port: 80 },
{ type: "http", host: "skynetfree.net", port: 80 },
{ type: "http", host: "skynetpro.net", port: 80 },
];
export function getTld(hostname: string): string {
@ -56,80 +43,6 @@ export function getTld(hostname: string): string {
? hostname.split(".")[hostname.split(".").length - 1]
: hostname;
}
export type FileDataType = {
err: null;
response: Response | null;
fileData: Uint8Array;
};
export function downloadSkylink(
skylink: string,
path?: string
): Promise<[data: FileDataType, err: Err]> {
return new Promise((resolve) => {
// Get the Uint8Array of the input skylink.
let [u8Link, errBTB] = b64ToBuf(skylink);
if (errBTB !== null) {
resolve([{} as any, addContextToErr(errBTB, "unable to decode skylink")]);
return;
}
if (!validSkylink(u8Link)) {
resolve([{} as any, "skylink appears to be invalid"]);
return;
}
// Prepare the download call.
let endpoint = "/" + skylink;
if (path) {
endpoint += path;
}
let fileDataPtr: FileDataType = {
fileData: new Uint8Array(0),
err: null,
response: null,
};
let verifyFunction = function (response: Response): Promise<Err> {
return verifyDownloadResponse(response, u8Link, fileDataPtr);
};
// Perform the download call.
progressiveFetch(endpoint, null, defaultPortalList, () =>
Promise.resolve(null)
).then((result: progressiveFetchResult) => {
// Return an error if the call failed.
if (result.success !== true) {
// Check for a 404.
for (let i = 0; i < result.responsesFailed.length; i++) {
if (result.responsesFailed[i].status === 404) {
resolve([{} as any, "404"]);
return;
}
}
// Error is not a 404, return the logs as the error.
let err = objAsString(result.logs);
resolve([
{} as any,
addContextToErr(err, "unable to complete download"),
]);
return;
}
// Check if the portal is honest but the download is corrupt.
if (fileDataPtr.err !== null) {
resolve([
{} as any,
addContextToErr(fileDataPtr.err, "download is corrupt"),
]);
return;
}
fileDataPtr.response = result.response;
resolve([fileDataPtr, null]);
});
});
}
export async function* iterateStream(
stream: ReadableStream<any>
): AsyncGenerator<Uint8Array> {

2933
yarn.lock

File diff suppressed because it is too large Load Diff