Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wallet): add Liquid Auth provider #215

Merged
merged 42 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c627ffb
feat: adds Liquid as a Wallet/Provider
HashMapsData2Value Aug 14, 2024
eae5800
chore: adds liquid-auth-js as dependency
HashMapsData2Value Aug 14, 2024
c5677b0
chore: updates lock file
HashMapsData2Value Aug 14, 2024
81ec79f
feat: adds Liquid Auth to vanilla-js example
HashMapsData2Value Aug 14, 2024
d744c77
chore: todos
HashMapsData2Value Aug 15, 2024
9ff7856
feat: adds docker-compose
HashMapsData2Value Aug 21, 2024
91bcf35
chore: debug info
HashMapsData2Value Aug 21, 2024
11312bd
chore: get session
HashMapsData2Value Aug 21, 2024
9571b41
feat: local development possible using nginx
HashMapsData2Value Aug 22, 2024
508282d
fix: removes http-server, uses only Nginx
HashMapsData2Value Aug 22, 2024
cb99659
docs: clarify troubleshooting and spin up
HashMapsData2Value Aug 22, 2024
44da659
feat: working connect
HashMapsData2Value Aug 24, 2024
50445b7
feat: adds disconnect
HashMapsData2Value Aug 25, 2024
5e63a69
feat: defined resumeSession, message passing
HashMapsData2Value Aug 28, 2024
7c58115
feat: Working e2e Use-Wallet Liquid-Auth integration
HashMapsData2Value Aug 29, 2024
3159ea7
chore: removes fluff
HashMapsData2Value Aug 30, 2024
2b33533
feat: adds working examples
HashMapsData2Value Sep 2, 2024
f4440a0
fix: breaking up of concerns
HashMapsData2Value Sep 2, 2024
d471005
chore: whitespaces
HashMapsData2Value Sep 2, 2024
8912e25
chore: pnpm-lock
HashMapsData2Value Sep 2, 2024
02c8773
Merge branch 'TxnLab:main' into feat/LiquidAuth-Provider
HashMapsData2Value Sep 2, 2024
86d6991
chore: fix
HashMapsData2Value Sep 2, 2024
a9955f5
chore: remove from nextjs
HashMapsData2Value Sep 2, 2024
ed37c36
feat: separate out Liquid Auth Use-Wallet Client
HashMapsData2Value Sep 2, 2024
16c8516
chore: update pnpm-lock
HashMapsData2Value Sep 3, 2024
28b7849
fix: ngrok example file port
HashMapsData2Value Sep 4, 2024
da4abd7
Merge branch 'main' into feat/LiquidAuth-Provider
HashMapsData2Value Sep 6, 2024
bc3c864
test: test
HashMapsData2Value Sep 6, 2024
4282493
chore: update pnpm
HashMapsData2Value Sep 6, 2024
dbcdbfd
chore: adds tests
HashMapsData2Value Sep 6, 2024
5cf6753
lint: remove unused import
HashMapsData2Value Sep 6, 2024
356cb70
chore: pretier
HashMapsData2Value Sep 6, 2024
8351a4f
chore: prettier and linter
HashMapsData2Value Sep 6, 2024
93448c6
chore: prettier and linter
HashMapsData2Value Sep 6, 2024
29d6b80
chore: prettier
HashMapsData2Value Sep 6, 2024
89ac677
chore: make LiquidAuthClient public and fix option
HashMapsData2Value Sep 6, 2024
4b1dc7b
Merge branch 'TxnLab:main' into feat/LiquidAuth-Provider
HashMapsData2Value Sep 9, 2024
8039c32
fix: use npm package
HashMapsData2Value Oct 3, 2024
ff35ae2
Merge branch 'main' into feat/LiquidAuth-Provider
HashMapsData2Value Oct 3, 2024
1fd05fb
chore: update package version
HashMapsData2Value Oct 15, 2024
3666ade
chore: update package.json
HashMapsData2Value Oct 15, 2024
872cc89
chore: sync versions
HashMapsData2Value Oct 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions examples/liquid-auth-backend/.env.docker.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Application
NODE_ENV=production
SENTRY_DNS=
PORT=5173

# Database
DB_HOST=mongo:27017
DB_USERNAME=algorand
DB_PASSWORD=algorand
DB_NAME=fido
DB_ATLAS=false

# Events
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_USERNAME=default
REDIS_PASSWORD=

# FIDO2
RP_NAME=Algorand Foundation FIDO2 Server
HOSTNAME=<NGROK_STATIC_DOMAIN>
ORIGIN=https://<NGROK_STATIC_DOMAIN>

ANDROID_SHA256HASH=47:CC:4E:EE:B9:50:59:A5:8B:E0:19:45:CA:0A:6D:59:16:F9:A9:C2:96:75:F8:F3:64:86:92:46:2B:7D:5D:5C
ANDROID_PACKAGENAME=foundation.algorand.demo
2 changes: 2 additions & 0 deletions examples/liquid-auth-backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env.docker
ngrok.yml
147 changes: 147 additions & 0 deletions examples/liquid-auth-backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Liquid Auth Backend

In order to use the Liquid Auth use-wallet wallet/provider it is necessary to run the Liquid Auth backend.

When a user engages in the _connect_ flow for the "Liquid" use-wallet option, it will generate a request-id presented through a QR code. When the QR code is scanned by a Liquid Auth-powered wallet (such as the [Liquid Auth Android demo mobile wallet app](https://github.com/algorandfoundation/liquid-auth-android/tree/develop)), the wallet app will read the request-id, acquire the origin and proceed to follow normal WebAuthn/FIDO2 flows such as generating and registering pass key credentials specific for that origin. It will then make a post request to the Liquid Auth backend it expects to be located at the origin.

To achieve this flow when developing locally, we make use of ngrok. Ngrok tunnels requests from the Internet (from the static domain provided for you) into our local computer, allow you to expose your local port HTTP to the world.

For more information on Liquid Auth, please [refer to the documentation](https://liquidauth.com).

## Liquid Auth Backend

The Liquid Auth backend is composed of the following components:

- NestJS: a headless NestJS API server.
- MongoDB: for maintaining sessions and persisting certain user data, like passkeys.
- Redis: for Web Sockets. Once a connection has been established communication happens peer-to-peer over WebRTC, but for the initial handshake Web Sockets are needed.
- CoTurn: to run your own TURN server. (Nodely.io kindly also offers TURN servers as public infrastructure.)
- Ngrok: creates the traffic tunnel to ngrok.com.

Refer to the `docker-compose.yaml` file for the specific images and additional specification.

Additionally, the following services:

- Frontend: An Nginx server that runs the Frontend part, e.g. by serving static files produced by the vanilla-ts example, as well as routing API calls to the NestJS API server.

## Setup

### 1. Install Docker

If you do not have it already, install [Docker](https://www.docker.com).

### 2. Sign Up for Ngrok

Navigate to [ngrok.com](https://ngrok.com) and sign up.

Follow all the steps.

Collect your **_Authtoken_** and **_Static Domain_**. You will need them in the next steps.

### 3. Create the YAML files

In this folder (liquid-auth-backend), the following YAML files must be created:

- .env.docker
- ngrok.yaml

Example files have been created and are checked in, but they need to be updated with your Ngrok authtoken and static domain.

Create `.env.docker` as follows, replacing <NGROK_STATIC_DOMAIN> with the static domain:

```YAML
# Application
NODE_ENV=production
SENTRY_DNS=
PORT=5173

# Database
DB_HOST=mongo:27017
DB_USERNAME=algorand
DB_PASSWORD=algorand
DB_NAME=fido
DB_ATLAS=false

# Events
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_USERNAME=default
REDIS_PASSWORD=

# FIDO2
RP_NAME=Algorand Foundation FIDO2 Server
HOSTNAME=<NGROK_STATIC_DOMAIN>
ORIGIN=https://<NGROK_STATIC_DOMAIN>

ANDROID_SHA256HASH=47:CC:4E:EE:B9:50:59:A5:8B:E0:19:45:CA:0A:6D:59:16:F9:A9:C2:96:75:F8:F3:64:86:92:46:2B:7D:5D:5C
ANDROID_PACKAGENAME=foundation.algorand.demo
```

For example it might look like this:

```YAML
HOSTNAME=different-precisely-worm.ngrok-free.app
ORIGIN=https://different-precisely-worm.ngrok-free.app
```

Similarly, create `ngrok.yml`as follows, replacing <NGROK_STATIC_DOMAIN> and <NGROK_AUTH_TOKEN>:

```YAML
version: 2
authtoken: <NGROK_AUTH_TOKEN>
tunnels:
website:
addr: frontend:80
proto: http
domain: <NGROK_STATIC_DOMAIN>
```

### 4. Build the static files

Follow the instructions to build the frontend example of your choice.

E.g., build `packages/use-wallet` and then build `examples/vanilla-ts`.

By default we set `FRONTEND_BUILD_FOLDER=../vanilla-ts/dist`, i.e. the vanilla-ts example, but you are free to change the path to the build-folder name in the docker-compose folder, or set the env variable explicitly.

The key thing is to ensure that Nginx has static files to serve.

### 5. Spin up the services

Run `docker-compose up -d` from this directory.

This will start up the docker services and detach the output (logs) from the terminal window.

Navigate to your static domain. You should be met with the frontend, e.g. examples/vanilla-ts. Additionally, navigate to `<static domain>/auth/session` and check that you get a valid JSON response (with user being set or simply being null) to confirm that the API server is running.

## Troubleshooting

#### Ngrok & VPNs

Ngrok sometimes does not play well with VPNs, so you might need to disable it.

#### Platform Error

You might get the following error:

> ! liquid-auth The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested 0.0s

Or a similar. In this case, this error appears on MacBook Pros that are running Apple Silicon.

To fix this, we can force Docker to emulate linux/amd64, by adding `platform: linux/amd64` to the service in `docker-compose.yml`:

```YAML
// ...
liquid-auth:
image: ghcr.io/algorandfoundation/liquid-auth:develop
platform: linux/amd64
restart: no
env_file:
- .env.docker
ports:
- "5173:5173"
depends_on:
- redis
- mongo
// ...
```
75 changes: 75 additions & 0 deletions examples/liquid-auth-backend/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
services:
liquid-auth:
image: ghcr.io/algorandfoundation/liquid-auth:develop
restart: no
env_file:
- .env.docker
ports:
- '5173:5173'
depends_on:
- redis
- mongo

frontend:
image: nginx:latest
volumes:
- ${FRONTEND_BUILD_FOLDER:-../vanilla-ts/dist}:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/conf.d/default.conf
ports:
- '80:80'
depends_on:
- liquid-auth

ngrok:
image: ngrok/ngrok:latest
restart: no
command:
- 'start'
- '--all'
- '--config'
- '/etc/ngrok.yml'
volumes:
- ./ngrok.yml:/etc/ngrok.yml
ports:
- 4040:4040
depends_on:
- frontend

redis:
image: redis
restart: always
ports:
- '6379:6379'

mongo:
image: mongo:7.0
restart: no
environment:
- MONGO_INITDB_DATABASE=${DB_NAME:-fido}
- MONGO_INITDB_ROOT_USERNAME=${DB_USERNAME:-algorand}
- MONGO_INITDB_ROOT_PASSWORD=${DB_PASSWORD:-algorand}
ports:
- '27017:27017'
volumes:
- mongo:/data/db

turn:
image: coturn/coturn
restart: no
deploy:
replicas: 0 # Not in use, relying instead on Nodely's TURN server
depends_on:
- mongo
ports:
- '3478:3478'
- '3478:3478/udp'
- '5349:5349'
- '5349:5349/udp'
command:
- '--no-auth'
- '--mongo-userdb'
- 'mongodb://${DB_USERNAME:-algorand}:${DB_PASSWORD:-algorand}@mongo:27017/${DB_NAME:-coturn}?authSource=admin&retryWrites=true&w=majority'
- '--redis-userdb'
- 'ip=redis dbname=0'
volumes:
mongo:
28 changes: 28 additions & 0 deletions examples/liquid-auth-backend/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
server {
listen 80;

location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}

location ~ ^/(auth|.well-known|connect|attestation|assertion)/ {
proxy_pass http://liquid-auth:5173;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location /socket.io {
proxy_pass http://liquid-auth:5173;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
7 changes: 7 additions & 0 deletions examples/liquid-auth-backend/ngrok.yml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: 2
authtoken: <NGROK_AUTH_TOKEN>
tunnels:
website:
addr: frontend:80
proto: http
domain: <NGROK_STATIC_DOMAIN>
3 changes: 3 additions & 0 deletions examples/nuxt/plugins/walletManager.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export default defineNuxtPlugin((nuxtApp) => {
},
WalletId.KMD,
WalletId.KIBISIS,
{
id: WalletId.LIQUID
},
{
id: WalletId.LUTE,
options: { siteName: 'Example Site' }
Expand Down
3 changes: 3 additions & 0 deletions examples/react-ts/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const walletManager = new WalletManager({
},
WalletId.KMD,
WalletId.KIBISIS,
{
id: WalletId.LIQUID
},
{
id: WalletId.LUTE,
options: { siteName: 'Example Site' }
Expand Down
3 changes: 3 additions & 0 deletions examples/solid-ts/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const walletManager = new WalletManager({
},
WalletId.KMD,
WalletId.KIBISIS,
{
id: WalletId.LIQUID
},
{
id: WalletId.LUTE,
options: { siteName: 'Example Site' }
Expand Down
3 changes: 3 additions & 0 deletions examples/vanilla-ts/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const walletManager = new WalletManager({
},
WalletId.KMD,
WalletId.KIBISIS,
{
id: WalletId.LIQUID
},
{
id: WalletId.LUTE,
options: { siteName: 'Example Site' }
Expand Down
3 changes: 3 additions & 0 deletions examples/vue-ts/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ app.use(WalletManagerPlugin, {
},
WalletId.KMD,
WalletId.KIBISIS,
{
id: WalletId.LIQUID
},
{
id: WalletId.LUTE,
options: { siteName: 'Example Site' }
Expand Down
5 changes: 5 additions & 0 deletions packages/use-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
},
"devDependencies": {
"@agoralabs-sh/avm-web-provider": "1.7.0",
"@algorandfoundation/liquid-auth-use-wallet-client": "1.1.0",
"@blockshake/defly-connect": "1.1.6",
"@magic-ext/algorand": "23.11.0",
"@magic-sdk/provider": "28.11.0",
Expand All @@ -59,6 +60,7 @@
},
"peerDependencies": {
"@agoralabs-sh/avm-web-provider": "^1.7.0",
"@algorandfoundation/liquid-auth-use-wallet-client": "1.1.0",
"@blockshake/defly-connect": "^1.1.6",
"@perawallet/connect": "^1.3.4",
"@perawallet/connect-beta": "^2.0.21",
Expand All @@ -71,6 +73,9 @@
"@agoralabs-sh/avm-web-provider": {
"optional": true
},
"@algorandfoundation/liquid-auth-use-wallet-client": {
"optional": true
},
"@blockshake/defly-connect": {
"optional": true
},
Expand Down
3 changes: 3 additions & 0 deletions packages/use-wallet/setupTests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Define `self` to avoid ReferenceError in Node.js environment
// eslint-disable-next-line no-extra-semi
;(global as any).self = global
Loading