From c3184f981efda7e4252ffec583d6c6b214ff27b5 Mon Sep 17 00:00:00 2001 From: Josef Date: Wed, 17 Jul 2024 21:43:14 +0200 Subject: [PATCH] docs: cleanup readme (#1485) * docs: cleanup readme * docs: cleanup docs * docs: remove outdated docs --- README.md | 26 +--------- docs/custody.md | 24 ---------- docs/deployment.md | 14 ------ docs/extension-services.md | 97 -------------------------------------- docs/publishing.md | 54 --------------------- docs/state-management.md | 50 -------------------- docs/testing.md | 1 - docs/web-workers.md | 14 ------ 8 files changed, 1 insertion(+), 279 deletions(-) delete mode 100644 docs/custody.md delete mode 100644 docs/publishing.md delete mode 100644 docs/state-management.md delete mode 100644 docs/web-workers.md diff --git a/README.md b/README.md index be176a0843..6a55e22f3d 100644 --- a/README.md +++ b/README.md @@ -75,34 +75,10 @@ pnpm dev ``` You now have a local copy of Minifront available at -[`https://localhost:5173`](https://localhost:5173) and an unbundled Prax is -available at [`apps/extension/dist`](apps/extension/dist), ready to be loaded -into your browser. +[`https://localhost:5173`](https://localhost:5173). Minifront will hot-reload. -If you're working on Prax, Chrome will show extension page changes after a -manual refresh, but cannot reload the extension worker scripts or content -scripts. For worker script changes, you must manually reload the extension. For -content script changes, you must also manually reload pages hosting the injected -scripts. - -#### Loading your unbundled build of Prax into Chrome - -After building Prax, you can load it into Chrome. - -It's recommended to use a dedicated browser profile for development, not your -personal profile. - -1. Go to the Extensions page [`chrome://extensions`](chrome://extensions) -2. Enable _Developer Mode_ by clicking the toggle switch at the top right -3. Click the button _Load unpacked extension_ at the top and locate your cloned - repository. Select the extension's build output directory - [`apps/extension/dist`](../apps/extension/dist). -4. Activate the extension to enter onboarding. - - You may set a blank password. - - You can pin the Prax extension button to your toolbar for quick access. - ## Security If you believe you've found a security-related issue with Penumbra, diff --git a/docs/custody.md b/docs/custody.md deleted file mode 100644 index 69b3eb6019..0000000000 --- a/docs/custody.md +++ /dev/null @@ -1,24 +0,0 @@ -# Custody - -### Password - -new API -in-memory password key in zustand -await session.set('passwordKey', key); -await local.set('passwordKeyPrint', keyPrint.toJson()); - -When setting up for the first time, you'll need to set a password. - -This password is hashed via `PBKDF2`, see [keyStretchingHash() function](../packages/crypto/src/encryption.ts). -It utilizes a pseudorandom function along with a salt value and iteration. The use of a salt provides protection against pre-computed attacks such as rainbow tables, and the iteration count slows down brute-force attacks. - -The password `Key` (private key material) is stored in `chrome.storage.session` used for deriving spending keys for wallets later. - -The password `KeyPrint` (public hash/salt) is stored in `chrome.storage.local` to later validate logins when session storage is wiped. - -### New wallet - -Upon importing or generating a new seed phrase, it is: - -- Encrypted using `AES-GCM`, see [encrypt() function](../packages/crypto/src/encryption.ts) -- `Box` (nonce/ciphertext) is stored in `chrome.storage.local` for later decryption diff --git a/docs/deployment.md b/docs/deployment.md index 29bdb8740e..5ce33eaed4 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -1,19 +1,5 @@ # Deployment Workflows -### Prax Chrome Extension - -Create a [github issue deployment issue](https://github.com/penumbra-zone/web/issues/new?template=deployment.md&title=Publish+vX.X.X+extension+%2B+web+app) to track deployment progress and steps. - -Upon a new [git tag](https://github.com/penumbra-zone/web/releases/tag/v4.2.0) being pushed to the repo, -a [workflow](../.github/workflows/extension-publish.yml) is kicked off. It then requests permission to -continue from [github group](https://github.com/orgs/penumbra-zone/teams/penumbra-labs) and, after approval, -bundles the extension into a .zip which gets put in the Chrome Webstore review queue. It typically takes -1-3 days to go live. The publication status can be monitored in the [Chrome Developer Dashboard](https://chrome.google.com/webstore/devconsole/aabc0949-93db-4e77-ad9f-e6ca1d132501?hl=en). - -### Web app - -Manually run [Deploy Firebase Dapp](https://github.com/penumbra-zone/web/actions/workflows/deploy-firebase-dapp.yml) github action on main branch. - ### NPM Packages The packages in this repo are published using [changesets](https://github.com/changesets/changesets). diff --git a/docs/extension-services.md b/docs/extension-services.md index 1f6f69a933..383ecfbd50 100644 --- a/docs/extension-services.md +++ b/docs/extension-services.md @@ -1,100 +1,3 @@ -# Extension Services - -Prax uses a custom transport for `@connectrpc/connect` to provide -Protobuf-specified services via a DOM channel `MessagePort` and the Chrome -extension runtime. - -Interestingly, this transport should be generally applicable to any -Protobuf-specified interface, including all auto-generated clients and server -stubs from the buf registry. - -If you are interested in using the transport for -your own project, the generic packages are available in -`@penumbra-zone/transport-dom` and `@penumbra-zone/transport-chrome`. - -You may use locally generated service types, or simply install the [appropriate -packages from the buf -registry](https://buf.build/penumbra-zone/penumbra/sdks/main). If you are using -npm, buf's [npm-specific guide](https://buf.build/docs/bsr/generated-sdks/npm) -is recommended reading. - -## Clients - -Each channel transport can be used as a page-level singleton servicing multiple -clients. Developers using React queriers may be interested in -`@connectrpc/connect-query`. - -Creation is fully synchronous from the constructor's perspective, and the client -is immediately useable, but requests are delayed until init actually completes. - -### Connection to Prax - -For developing a dapp that connects to Prax, you may use the convenience functions in `@penumbra-zone/client`. - -```ts -import { createPraxClient } from '@penumbra-zone/client'; -import { ViewService } from '@penumbra-zone/protobuf'; - -const viewClient = createPraxClient(ViewService); -``` - -An incredibly simple use might be something like this. - -```ts -import { bech32mAddress } from '@penumbra-zone/bech32m/penumbra'; - -const { address } = await viewClient.addressByIndex({}); -console.log(bech32mAddress(address)); -``` - -### More control - -Other providers may be available, and you can configure the transport however -you'd like. Use of the client is identical. - -```ts -import { getAnyPenumbraPort } from '@penumbra-zone/client'; -import { ViewService } from '@penumbra-zone/protobuf'; -import { bech32mAddress } from '@penumbra-zone/bech32m/penumbra'; - -const channelTransport = createChannelTransport({ - getPort: getAnyPenumbraPort, - jsonOptions: { typeRegistry: createRegistry(ViewService) }, -}); - -const viewClient = createPromiseClient(ViewService, channelTransport); -const { address } = await viewClient.addressByIndex({}); -console.log(bech32mAddress(address)); -``` - -### The actual interface - -These are just convenience methods to this interface. A global record, on which -arbitrary strings identify providers, with a simple interface to connect or -request permission to connect. - -If you're developing a wallet, injection of a record here will allow you to -expose your wallet to potentially interested web apps. - - - -```ts -export const PenumbraSymbol = Symbol.for('penumbra'); - -export interface PenumbraProvider { - readonly connect: () => Promise; - readonly request: () => Promise; - readonly isConnected: () => boolean | undefined; - readonly manifest: string; -} - -declare global { - interface Window { - readonly [PenumbraSymbol]?: undefined | Readonly>; - } -} -``` - ## Service Implementation Services in this repository should eventually be re-useable, but you can also diff --git a/docs/publishing.md b/docs/publishing.md deleted file mode 100644 index eff06f0b32..0000000000 --- a/docs/publishing.md +++ /dev/null @@ -1,54 +0,0 @@ -# Publishing Extension - -Publishing a new version of the extension should be a very careful process. -The extension is a hot wallet and custodies the user's encrypted seed phrase. -If the publishing pipeline was compromised, a bad actor could upload malicious code. - -### Access to publish - -#### #1 - Penumbra Labs [google group](https://groups.google.com/a/penumbralabs.xyz/g/chrome-extension-publishers) - -This entity is a [group publisher](https://developer.chrome.com/docs/webstore/group-publishers/). Members of the -group have publish permissions. Note: For a group member to publish updates, that member must register as a Chrome Web -Store developer and pay the one-time registration fee. -Package uploads are done through -the [Chrome Web Store Developer Dashboard](https://chrome.google.com/webstore/devconsole/). - -#### #2 - Github CI/CD - -Upon a github release, the `penumbra-zone/penumbra-labs` github team will be pinged for a review of the release. -Any one of the members can approve it. Upon doing so, the pipeline will trigger packaging and uploading the extension -code on the main branch. -See github action [here](../.github/workflows/extension-publish.yml). - -Two versions of the extension will be uploaded: - -- **Prax Wallet BETA**: A private beta version of the extension, used to garner feedback from external contributors ( - i.e. passionate discord members). Users can be added to this list in - the [prax-beta-testers google group](https://groups.google.com/a/penumbralabs.xyz/g/prax-beta-testers). -- **Prax Wallet**: The public, production version of the extension. - -After the pipeline has run, one of the chrome publishers with dashboard access, should take these actions: - -1. Submit the **BETA** version for approval with immediate publishing. There is no risks on this end for breakage. After - approval, test extensively for bugs. -2. Submit the **PRODUCTION** version for approval but _without_ publishing (should uncheck box that says _"Publish Prax - wallet automatically after it has passed review"_). Once approved and BETA version is validated, it can be published - and go live instantly. - -##### Credentials - -The credentials for this have been generated in -the [penumbra-web google cloud project](https://console.cloud.google.com/apis/credentials?project=penumbra-web&supportedpurview=project). -If the one who generated the credentials has been removed from the ownership google group (from #1 above), -new credentials need to be generated for -the [ext-publish](https://github.com/penumbra-zone/web/settings/environments/1654975857/edit) github environment: - -- GOOGLE_CLIENT_ID -- GOOGLE_CLIENT_SECRET -- GOOGLE_REFRESH_TOKEN - -These can be generated by following -the [chrome webstore api guide](https://developer.chrome.com/docs/webstore/using_webstore_api/). - -Note: there is a Chrome review process that typically takes 1-2 days. diff --git a/docs/state-management.md b/docs/state-management.md deleted file mode 100644 index 80ad866118..0000000000 --- a/docs/state-management.md +++ /dev/null @@ -1,50 +0,0 @@ -# State management - -## Web extension - -The extension has three types of state: - -### In-memory state - -We use [Zustand](https://github.com/pmndrs/zustand) for this. It is based on simplified flux principles and is similar to Redux. -We chose Zustand given its minimalistic, no-boilerplate, hooks-integrated approach. We use `immer` middleware for easier state mutations. - -Can be found here: [apps/extension/src/state/](../apps/extension/src/state/). See examples in that folder on how to create your own slice and add to the store. - -On refresh, this state is wiped and only the persisted state [apps/extension/src/state/persist.ts](../apps/extension/src/state/persist.ts) is rehyrated. - -Be sure to test store functionality! Example using `vitest` here: [apps/extension/src/state/password.test.ts](../apps/extension/src/state/password.test.ts). - -### Session state - -Meant to be used for short-term persisted data. Holds data in memory for the duration of a browser session. - -Sourced from `chrome.storage.session`. Some helpers fns: - -- Clear all state: `chrome.storage.session.clear()` -- See all state: `chrome.storage.session.get().then(console.log)` - -See `apps/extension/src/state/password.ts` for an example of how to do typesafe storage that is synced with Zustand. -Also, be sure to rehydrate Zustand state here: [apps/extension/src/state/persist.ts](../apps/extension/src/state/persist.ts). - -### Local state - -Same API as above, except uses `chrome.storage.local`. -Meant to be used for long-term persisted data. It is cleared when the extension is removed. - -### Migrations - -If your persisted state changes in a breaking way, it's important to write a migration. Steps: - -1. Create a new version in the respective storage file. Example: [SessionStorageVersion](../apps/extension/src/storage/session.ts). -2. Write the migration functions. Should have a data structure that looks like: - -```typescript - { - "seedPhrase": { // storage key - "V1": (old) => old.split(' ') // old version: migrate fn - } - } -``` - -3. See [apps/extension/src/storage/migration.test.ts](../apps/extension/src/storage/migration.test.ts) for an example. Make sure you add types to your migration function! diff --git a/docs/testing.md b/docs/testing.md index 88165426a8..331c7b234f 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -7,7 +7,6 @@ much as we can. If we do, our app will be far more resilient to changes. Different kinds of testing examples: - Unit tests: [packages/crypto/src/encryption.test.ts](../packages/crypto/src/encryption.test.ts) -- Zustand store tests: [apps/extension/src/state/password.test.ts](../apps/extension/src/state/password.test.ts) - Zod tests to validate types: [packages/wasm/src/client.test.ts](../packages/wasm/src/keys.test.ts) ### Vitest diff --git a/docs/web-workers.md b/docs/web-workers.md deleted file mode 100644 index 97477e26ea..0000000000 --- a/docs/web-workers.md +++ /dev/null @@ -1,14 +0,0 @@ -# Web workers - -The heavy lifting of requests happen in the service worker. Unfortunately, it's an odd runtime environment -and doesn't have access to the same apis as a normal web app. Here is what we have confirmed: - -- Using web-workers directly from a service worker. Not supported ❌ -- Using wasm-threads (wasm-rayon-bindgen). Not supported as it uses web workers underneath the hood ❌ -- Using offscreen api. Works ✅ - -The offscreen api workaround solution was [recommended by Google engineers](https://bugs.chromium.org/p/chromium/issues/detail?id=1219164). -It works by opening an invisible window and issue commands to it to access the full web api. -If it sounds hacky, it's because it is. Here is an [example code](https://github.com/GoogleChrome/chrome-extensions-samples/blob/f608c65e61c2fbf3749ccba88ddce6fafd65e71f/functional-samples/cookbook.offscreen-dom/background.js) of it in use. - -Note: It doesn't look like [comlink](https://github.com/GoogleChromeLabs/comlink) works via this method.