From d340447aba098dbac6163bfbacca0429323e6e45 Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Fri, 23 Jun 2023 03:28:39 -0400 Subject: [PATCH] feat: add portal management apis --- src/portal.ts | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/types.ts | 5 ++++ 2 files changed, 83 insertions(+) create mode 100644 src/portal.ts diff --git a/src/portal.ts b/src/portal.ts new file mode 100644 index 0000000..1219014 --- /dev/null +++ b/src/portal.ts @@ -0,0 +1,78 @@ +import { ErrTuple, KeyPair, Portal } from "#types.js"; +import { Client } from "@lumeweb/libportal"; +import { deriveChildKey } from "#keys.js"; +import { ed25519 } from "@noble/curves/ed25519"; +import { bytesToHex } from "@noble/hashes/utils.js"; + +let activePortalMasterKey; + +export const DEFAULT_PORTAL_LIST: Portal[] = [ + { id: "lumeweb", url: "https://web3portal.com", name: "web3portal.com" }, +]; + +const ACTIVE_PORTALS = new Set(); + +type PortalSessionsStore = { [id: string]: string }; + +export function maybeInitDefaultPortals(): ErrTuple { + if (!activePortalMasterKey) { + return [null, "activePortalMasterKey not set"]; + } + + let portalSessionsData = window.localStorage.getItem("portals"); + let portalSessions: PortalSessionsStore = {}; + if (portalSessions) { + portalSessions = JSON.parse( + portalSessionsData as string, + ) as PortalSessionsStore; + } + + for (const portal of DEFAULT_PORTAL_LIST) { + let jwt: string | null = null; + + if (portalSessions) { + if (portal.id in portalSessions) { + jwt = portalSessions[portal.id]; + } + } + + const client = new Client({ + email: generatePortalEmail(portal), + portalUrl: portal.url, + privateKey: generatePortalKeyPair(portal).privateKey, + jwt: jwt as string, + }); + + ACTIVE_PORTALS.add(client); + } + + return [null, null]; +} + +export function setActivePortalMasterKey(key: Uint8Array) { + activePortalMasterKey = key; +} + +export function generatePortalEmail(portal: Portal) { + const keyPair = generatePortalKeyPair(portal); + + const userId = bytesToHex(keyPair.publicKey.slice(0, 12)); + + return `${userId}@example.com`; +} + +export function generatePortalKeyPair(portal: Portal): KeyPair { + const privateKey = deriveChildKey( + activePortalMasterKey, + `portal-account:${portal.id}`, + ); + + return { + privateKey, + publicKey: ed25519.getPublicKey(privateKey), + }; +} + +export function getActivePortals(): Set { + return ACTIVE_PORTALS; +} diff --git a/src/types.ts b/src/types.ts index 33b1e23..7d4958e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -71,6 +71,11 @@ interface RequestOverrideResponse { body?: Uint8Array; } +export interface KeyPair { + publicKey: Uint8Array; + privateKey: Uint8Array; +} + export { DataFn, ErrFn,