Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinDecentrio committed Jul 15, 2024
1 parent 55d56cf commit c1f2253
Show file tree
Hide file tree
Showing 211 changed files with 12,928 additions and 0 deletions.
575 changes: 575 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

98 changes: 98 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Minifront

A minimal frontend for interacting with the [Penumbra](https://penumbra.zone/) chain.
Every Penumbra RPC endpoint will be hosting this static frontend as it is embedded into the node software.

**Note**: A Penumbra wallet extension is required for full functionality.

A number of technical decisions were made to ensure minifront is maximally client side and does not leak
information unnecessarily:

- Client-side biased js framework ✅
- Hash routing ✅
- Pre-load all static assets ⚠️ (in progress...)
- Server rendering ❌
- Route-based code splitting ❌
- Idiomatic urls & query params ❌
- Build-time pre-rendering ❌

[Read more](https://x.com/grod220/status/1760217326245285923) about how this frontend embraces censorship resistance and privacy.

## Deploy anywhere

The `dist/` output of the build is simply static assets. That means, it basically can be hosted anywhere.
First, download `dist.zip` from the [latest minifront release from github](https://github.com/penumbra-zone/web/releases?q=minifront&expanded=true).
Unzip that and take it to a variety of host providers. Examples:

### Vercel

```shell
npm i -g vercel # install the Vercel cli
vercel login
vercel ./dist
```

### Netlify

```shell
npm install netlify-cli -g # install the netlify cli
netlify login
cd ./dist
netlify deploy
```

### Github pages

Can follow [this guide](https://pages.github.com/).
Let's say your username is **roboto7237**.
First create a new repo specifically named in this format: roboto7237.github.io. Then do:

```shell
git clone https://github.com/roboto7237/roboto7237.github.io
cp -r ./dist/* ./roboto7237.github.io/ # copies all minifront code into the new folder
git add --all
git commit -m "Initial commit"
git push -u origin main
```

### Others

There are a ton of other places where static files can be hosted:

- [Cloudflare pages](https://pages.cloudflare.com/)
- [Firebase](https://firebase.google.com/docs/hosting)
- [Render](https://render.com/)
- [Surge](https://surge.sh/)
- [Google cloud](https://cloud.google.com/storage/docs/hosting-static-website)
- [AWS](https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html)

## Build locally

Prerequisites:

- Install [nodejs](https://nodejs.org/)
- Install [pnpm](https://pnpm.io/installation)
- Add buf registry: `npm config set @buf:registry https://buf.build/gen/npm/v1/`

```shell
pnpm install
pnpm dev
# Will be live at https://localhost:5173/
```

## Technologies Used

- TypeScript
- React
- vite / vitest
- Turborepo
- react-router-dom
- zustand
- tailwindcss
- framer-motion
- @bufbuild/protobuf
- @testing-library/react

## License

This project is dual-licensed under MIT and Apache-2.0
55 changes: 55 additions & 0 deletions __mocks__/zustand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Mock Zustand for tests.
*
* @see https://github.com/pmndrs/zustand/blob/main/docs/guides/testing.md#vitest
*/
import * as zustand from 'zustand';
import { act } from '@testing-library/react';
import { afterEach, vi } from 'vitest';

const { create: actualCreate, createStore: actualCreateStore } =
await vi.importActual<typeof zustand>('zustand');

// a variable to hold reset functions for all stores declared in the app
export const storeResetFns = new Set<() => void>();

const createUncurried = <T>(stateCreator: zustand.StateCreator<T>) => {
const store = actualCreate(stateCreator);
const initialState = store.getInitialState();
storeResetFns.add(() => {
store.setState(initialState, true);
});
return store;
};

// when creating a store, we get its initial state, create a reset function and add it in the set
export const create = (<T>(stateCreator: zustand.StateCreator<T>) => {
// to support curried version of create
return typeof stateCreator === 'function' ? createUncurried(stateCreator) : createUncurried;
}) as typeof zustand.create;

const createStoreUncurried = <T>(stateCreator: zustand.StateCreator<T>) => {
const store = actualCreateStore(stateCreator);
const initialState = store.getInitialState();
storeResetFns.add(() => {
store.setState(initialState, true);
});
return store;
};

// when creating a store, we get its initial state, create a reset function and add it in the set
export const createStore = (<T>(stateCreator: zustand.StateCreator<T>) => {
// to support curried version of createStore
return typeof stateCreator === 'function'
? createStoreUncurried(stateCreator)
: createStoreUncurried;
}) as typeof zustand.createStore;

// reset all stores after each test run
afterEach(() => {
act(() => {
storeResetFns.forEach(resetFn => {
resetFn();
});
});
});
25 changes: 25 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"hosting": {
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"cleanUrls": true,
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
"emulators": {
"ui": {
"enabled": true
},
"functions": {
"port": 5001
},
"hosting": {
"enabled": true,
"port": 5000
}
}
}
10 changes: 10 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!doctype html>
<html lang="en">
<head>
<link href="./favicon.png" rel="icon" sizes="80x80" type="image/png" />
</head>
<body>
<div id="root"></div>
<script src="./src/main.tsx" type="module"></script>
</body>
</html>
68 changes: 68 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"name": "minifront",
"version": "6.11.1",
"private": true,
"license": "(MIT OR Apache-2.0)",
"type": "module",
"scripts": {
"build": "vite build",
"clean": "rm -rfv dist *.tsbuildinfo",
"dev:app": "vite --port 5173",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"lint:strict": "tsc --noEmit && eslint src --max-warnings 0",
"preview": "vite preview",
"test": "vitest run"
},
"dependencies": {
"@bufbuild/protobuf": "^1.10.0",
"@cosmjs/proto-signing": "^0.32.3",
"@cosmjs/stargate": "^0.32.3",
"@cosmos-kit/core": "^2.12.0",
"@cosmos-kit/react": "^2.15.0",
"@interchain-ui/react": "^1.23.16",
"@penumbra-labs/registry": "10.0.0",
"@penumbra-zone/bech32m": "workspace:*",
"@penumbra-zone/client": "workspace:*",
"@penumbra-zone/crypto-web": "workspace:*",
"@penumbra-zone/getters": "workspace:*",
"@penumbra-zone/perspective": "workspace:*",
"@penumbra-zone/protobuf": "workspace:*",
"@penumbra-zone/transport-dom": "workspace:*",
"@penumbra-zone/types": "workspace:*",
"@penumbra-zone/zquery": "workspace:*",
"@radix-ui/react-dialog": "1.0.5",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-menubar": "^1.0.4",
"@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-portal": "^1.0.4",
"@remix-run/router": "^1.16.1",
"@repo/ui": "workspace:*",
"@tanstack/react-query": "4.36.1",
"bech32": "^2.0.0",
"bignumber.js": "^9.1.2",
"chain-registry": "^1.62.8",
"cosmos-kit": "^2.17.0",
"date-fns": "^3.6.0",
"framer-motion": "^11.2.4",
"immer": "^10.1.1",
"lodash": "^4.17.21",
"lucide-react": "^0.378.0",
"osmo-query": "^16.13.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-helmet": "^6.1.0",
"react-loader-spinner": "^6.1.6",
"react-router-dom": "^6.23.1",
"sonner": "1.4.3",
"tailwindcss": "^3.4.3",
"zustand": "^4.5.2"
},
"devDependencies": {
"@chain-registry/types": "^0.44.6",
"@types/lodash": "^4.17.4",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.3.0",
"@types/react-helmet": "^6.1.11"
}
}
1 change: 1 addition & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@repo/ui/postcss.config.js';
5 changes: 5 additions & 0 deletions public/arrow-down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions public/arrow-replace.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions public/auction-gradient.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions public/coin-stack-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/fuel.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions public/funds-gradient.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions public/history-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions public/ibc-gradient.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit c1f2253

Please sign in to comment.