Skip to content

Commit

Permalink
chore: add react/typescript demo and quick start (#14)
Browse files Browse the repository at this point in the history
* chore: add react/typescript demo and quick start

# Conflicts:
#	package.json

* doc: improve quickstart

---------

Co-authored-by: Hendrik Eeckhaut <[email protected]>
  • Loading branch information
0xtsukino and heeckhau authored Feb 15, 2024
1 parent afe9e48 commit 829b59d
Show file tree
Hide file tree
Showing 9 changed files with 318 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ pnpm-lock.yaml
build/
dev-build/
test-build/
./demo/node_modules
./demo/package-lock.json
1 change: 1 addition & 0 deletions demo/react-ts-webpack/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock.json
87 changes: 87 additions & 0 deletions demo/react-ts-webpack/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, { ReactElement, useCallback, useEffect, useState } from 'react';
import { createRoot } from 'react-dom/client';
import { prove, verify } from '../../src';
import { Proof } from 'tlsn-js/build/types';
import { Watch } from 'react-loader-spinner'

const container = document.getElementById('root');
const root = createRoot(container!);

root.render(<App />);

function App(): ReactElement {
const [processing, setProcessing] = useState(false);
const [result, setResult] = useState<{
time: number;
sent: string;
recv: string;
notaryUrl: string;
} | null>(null);
const [proof, setProof] = useState<Proof | null>(null);

const onClick = useCallback(async () => {
setProcessing(true);
const p = await prove('https://swapi.dev/api/people/1', {
method: 'GET',
maxTranscriptSize: 16384,
notaryUrl: 'http://localhost:7047',
websocketProxyUrl: 'ws://localhost:55688',
});
setProof(p);
}, [setProof, setProcessing]);

useEffect(() => {
(async () => {
if (proof) {
const r = await verify(proof);
setResult(r);
setProcessing(false);
}
})();
}, [proof, setResult]);

return (
<div>
<button onClick={!processing ? onClick : undefined} disabled={processing}>
Start demo
</button>
<div>
<b>Proof: </b>
{!processing && !proof
? <i>not started</i>
: !proof
? <>
Proving data from swapi...
<Watch
visible={true}
height="40"
width="40"
radius="48"
color="#000000"
ariaLabel="watch-loading"
wrapperStyle={{}}
wrapperClass=""
/>
Open <i>Developer tools</i> to follow progress
</>
: <>
<details>
<summary>View Proof</summary>
<pre>{JSON.stringify(proof, null, 2)}</pre>
</details>
</>
}

</div>
<div>
<b>Verification: </b>
{!proof
? <i>not started</i>
: !result
? <i>verifying</i>
: <pre>{JSON.stringify(result, null, 2)}</pre>
}
</div>
</div>
);
}
16 changes: 16 additions & 0 deletions demo/react-ts-webpack/index.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React/Typescrip Example</title>
</head>

<body>
<script>
</script>
<div id="root"></div>
</body>

</html>
30 changes: 30 additions & 0 deletions demo/react-ts-webpack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "react-ts-webpack",
"version": "1.0.0",
"description": "",
"main": "webpack.js",
"scripts": {
"dev": "webpack-dev-server --config webpack.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-loader-spinner": "^6.1.6",
"tlsn-js": "../../../tlsn-js"
},
"devDependencies": {
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.10",
"babel-loader": "^9.1.3",
"copy-webpack-plugin": "^11.0.0",
"html-webpack-plugin": "^5.5.0",
"source-map-loader": "^5.0.0",
"ts-loader": "^9.4.2",
"typescript": "^4.9.4",
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1"
}
}
19 changes: 19 additions & 0 deletions demo/react-ts-webpack/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"noEmit": false,
"jsx": "react"
},
"include": ["app.tsx"]
}
100 changes: 100 additions & 0 deletions demo/react-ts-webpack/webpack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
var webpack = require('webpack'),
path = require('path'),
HtmlWebpackPlugin = require('html-webpack-plugin');

const ASSET_PATH = process.env.ASSET_PATH || '/';

var alias = {};

var fileExtensions = [
'jpg',
'jpeg',
'png',
'gif',
'eot',
'otf',
'svg',
'ttf',
'woff',
'woff2',
];

var options = {
ignoreWarnings: [
/Circular dependency between chunks with runtime/,
/ResizeObserver loop completed with undelivered notifications/,
],
mode: 'development',
entry: {
app: path.join(__dirname, 'app.tsx'),
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'build'),
clean: true,
publicPath: ASSET_PATH,
},
module: {
rules: [
{
test: new RegExp('.(' + fileExtensions.join('|') + ')$'),
type: 'asset/resource',
exclude: /node_modules/,
},
{
test: /\.html$/,
loader: 'html-loader',
exclude: /node_modules/,
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: [
{
loader: require.resolve('ts-loader'),
},
],
},
{
test: /\.(js|jsx)$/,
use: [
{
loader: 'source-map-loader',
},
{
loader: require.resolve('babel-loader'),
},
],
exclude: /node_modules/,
},
],
},
resolve: {
alias: alias,
extensions: fileExtensions
.map((extension) => '.' + extension)
.concat(['.js', '.jsx', '.ts', '.tsx', '.css']),
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'index.ejs'),
filename: 'index.html',
cache: false,
}),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
].filter(Boolean),
// Required by wasm-bindgen-rayon, in order to use SharedArrayBuffer on the Web
// Ref:
// - https://github.com/GoogleChromeLabs/wasm-bindgen-rayon#setting-up
// - https://web.dev/i18n/en/coop-coep/
devServer: {
headers: {
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
},
},
};

module.exports = options;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
"build:wasm": "wasm-pack build --target web wasm/prover",
"watch:dev": "webpack --config webpack.web.dev.config.js --watch",
"predev": "sh utils/check-wasm.sh",
"dev": "concurrently npm:watch:dev npm:serve:dev",
"lint:wasm": "cd wasm/prover; cargo clippy --target wasm32-unknown-unknown",
"dev": "concurrently npm:watch:dev npm:serve:test",
"lint:eslint": "eslint . --fix",
"lint:tsc": "tsc --noEmit",
"lint": "concurrently npm:lint:tsc npm:lint:eslint",
Expand Down
62 changes: 62 additions & 0 deletions quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Quick Start Guide

There is a simple react/typescript demo app in `./demo/react-ts-webpack`. The directory contains a webpack configuration file that allows you to quickly bootstrap a webpack app using tlsn-js.

## Run a local notary server and websocket proxy

### Websocket Proxy <a name="proxy"></a>

Since a web browser doesn't have the ability to make TCP connection, we need to use a websocket proxy server.

To run your own websockify proxy **locally**, run:
```sh
git clone https://github.com/novnc/websockify && cd websockify
./docker/build.sh
docker run -it --rm -p 55688:80 novnc/websockify 80 swapi.dev:443
```

Note the `swapi.dev:443` argument on the last line, this is the server we will use in this quick start.

### Run a Local Notary Server <a name="local-notary"></a>

For this demo, we also need to run a local notary server.

1. Clone the TLSNotary repository:
```shell
git clone https://github.com/tlsnotary/tlsn.git --branch "v0.1.0-alpha.4"
```
2. Edit the notary server config file (`notary-server/config/config.yaml`) to turn off TLS so that the browser extension can connect to the local notary server without requiring extra steps to accept self-signed certificates in the browser.
```yaml
tls:
enabled: false
```
3. Run the notary server:
```shell
cd notary-server
cargo run --release
```

The notary server will now be running in the background waiting for connections.

## `tlsn-js` in a React/Typescript app

### Run the
1. Clone the repository
```sh
git clone https://github.com/tlsnotary/tlsn-js
```
2. Go to the demo folder
```sh
cd ./tlsn-js/demo/react-ts-webpack
```
3. Install dependencies
```sh
npm i
```
4. Start Webpack Dev Server:
```
npm run dev
```
5. Open `http://localhost:8080` in your browser
6. Click the **start demo** button
7. Open developer tools and monitor the console logs

0 comments on commit 829b59d

Please sign in to comment.