mirror of
https://github.com/tlsnotary/tlsn-js.git
synced 2026-01-08 20:18:01 -05:00
Demo UI (#85)
* feat: webp2p demo ui update * feat: webp2p demo ui update * fix: webp2p webpack * chore: linting * feat: styled react-ts demo, fixed interactive demo bug * chore: cleanup * Improved React demo * fix: unnessecary dependencies in package * Improved interactive demo * Fixed readme * Removed unused type --------- Co-authored-by: Hendrik Eeckhaut <hendrik@eeckhaut.org>
This commit is contained in:
@@ -9,9 +9,13 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.7.1",
|
||||
"css-loader": "^7.1.2",
|
||||
"postcss-loader": "^8.1.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-loader-spinner": "^6.1.6",
|
||||
"style-loader": "^4.0.0",
|
||||
"tlsn-js": "file:../../.."
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -20,7 +24,12 @@
|
||||
"babel-loader": "^9.1.3",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"postcss": "^8.4.49",
|
||||
"postcss-preset-env": "^10.1.1",
|
||||
"sass": "^1.82.0",
|
||||
"sass-loader": "^16.0.4",
|
||||
"source-map-loader": "^5.0.0",
|
||||
"tailwindcss": "^3.4.16",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
|
||||
4
demo/interactive-demo/prover-ts/postcss.config.js
Normal file
4
demo/interactive-demo/prover-ts/postcss.config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
const tailwindcss = require("tailwindcss");
|
||||
module.exports = {
|
||||
plugins: ["postcss-preset-env", tailwindcss],
|
||||
};
|
||||
3
demo/interactive-demo/prover-ts/src/app.scss
Normal file
3
demo/interactive-demo/prover-ts/src/app.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -4,6 +4,7 @@ import * as Comlink from 'comlink';
|
||||
import { Watch } from 'react-loader-spinner';
|
||||
import { Prover as TProver } from 'tlsn-js';
|
||||
import { type Method } from 'tlsn-wasm';
|
||||
import './app.scss';
|
||||
|
||||
const { init, Prover }: any = Comlink.wrap(
|
||||
new Worker(new URL('./worker.ts', import.meta.url)),
|
||||
@@ -14,6 +15,11 @@ const root = createRoot(container!);
|
||||
|
||||
root.render(<App />);
|
||||
|
||||
const serverUrl = 'https://swapi.dev/api/people/1';
|
||||
// let websocketProxyUrl = 'wss://notary.pse.dev/proxy';
|
||||
const websocketProxyUrl = 'ws://localhost:55688';
|
||||
const verifierProxyUrl = 'ws://localhost:9816/verify';
|
||||
|
||||
function App(): ReactElement {
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const [result, setResult] = useState<string | null>(null);
|
||||
@@ -21,16 +27,14 @@ function App(): ReactElement {
|
||||
const onClick = useCallback(async () => {
|
||||
setProcessing(true);
|
||||
|
||||
const url = 'https://swapi.dev/api/people/1';
|
||||
const url = serverUrl;
|
||||
const method: Method = 'GET';
|
||||
const headers = {
|
||||
secret: "TLSNotary's private key",
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
const body = {};
|
||||
// let websocketProxyUrl = 'wss://notary.pse.dev/proxy';
|
||||
const websocketProxyUrl = 'ws://localhost:55688';
|
||||
const verifierProxyUrl = 'ws://localhost:9816/verify';
|
||||
|
||||
const hostname = new URL(url).hostname;
|
||||
|
||||
let prover: TProver;
|
||||
@@ -98,7 +102,6 @@ function App(): ReactElement {
|
||||
console.log('Start reveal:', reveal);
|
||||
await prover.reveal(reveal);
|
||||
console.timeEnd('reveal');
|
||||
|
||||
} catch (error) {
|
||||
console.dir(error);
|
||||
console.error('Error during data reveal:', error);
|
||||
@@ -114,50 +117,92 @@ function App(): ReactElement {
|
||||
received: transcript.recv,
|
||||
});
|
||||
|
||||
setResult('Unredacted data successfully revealed to Verifier. Check the Verifier\'s console output to see what exactly was shared and revealed.');
|
||||
setResult(
|
||||
"Unredacted data successfully revealed to Verifier. Check the Verifier's console output to see what exactly was shared and revealed.",
|
||||
);
|
||||
|
||||
setProcessing(false);
|
||||
|
||||
|
||||
}, [setResult, setProcessing]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>TLSNotary interactive prover demo</h1>
|
||||
<div>
|
||||
Before clicking the start button, make sure the{' '}
|
||||
<i>interactive verifier</i> and the <i>web socket proxy</i> are running.
|
||||
Check the <a href="README.md">README</a> for the details.
|
||||
<div className="flex flex-col items-center justify-center w-full min-h-screen bg-gray-50 p-4">
|
||||
<h1 className="text-4xl font-bold text-slate-500 mb-2">TLSNotary</h1>
|
||||
<span className="text-lg text-gray-600 mb-4">
|
||||
Interactive Prover Demo
|
||||
</span>
|
||||
|
||||
<div className="text-center text-gray-700 mb-6">
|
||||
<p>
|
||||
Before clicking the <span className="font-semibold">Start</span> button,
|
||||
make sure the <i>interactive verifier</i> and the{' '}
|
||||
<i>web socket proxy</i> are running.</p>
|
||||
<p>Check the{' '}
|
||||
<a href="README.md" className="text-blue-600 hover:underline">
|
||||
README
|
||||
</a>{' '}
|
||||
for the details.
|
||||
</p>
|
||||
<table className="text-left table-auto w-full mt-4">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-4 py-2 text-left">Demo Settings</th>
|
||||
<th className="px-4 py-2 text-left">URL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="border px-4 py-2">Server</td>
|
||||
<td className="border px-4 py-2">{serverUrl}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="border px-4 py-2">Verifier</td>
|
||||
<td className="border px-4 py-2">{verifierProxyUrl}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="border px-4 py-2">WebSocket Proxy</td>
|
||||
<td className="border px-4 py-2">{websocketProxyUrl}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<button onClick={!processing ? onClick : undefined} disabled={processing}>
|
||||
<button
|
||||
onClick={!processing ? onClick : undefined}
|
||||
disabled={processing}
|
||||
className={`px-6 py-2 rounded-lg font-medium text-white
|
||||
${processing ? 'bg-slate-400 cursor-not-allowed' : 'bg-slate-600 hover:bg-slate-700'}
|
||||
`}
|
||||
>
|
||||
Start Prover
|
||||
</button>
|
||||
<br />
|
||||
<div>
|
||||
<b>Proof: </b>
|
||||
|
||||
<div className="mt-6 w-full max-w-3xl text-center">
|
||||
<b className="text-lg font-medium text-gray-800">Proof: </b>
|
||||
{!processing && !result ? (
|
||||
<i>not started yet</i>
|
||||
<i className="text-gray-500">Not started yet</i>
|
||||
) : !result ? (
|
||||
<>
|
||||
Proving data from swapi...
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<p className="text-gray-700 mb-2">Proving data from swapi...</p>
|
||||
<Watch
|
||||
visible={true}
|
||||
height="40"
|
||||
width="40"
|
||||
radius="48"
|
||||
color="#000000"
|
||||
color="#4A5568"
|
||||
ariaLabel="watch-loading"
|
||||
wrapperStyle={{}}
|
||||
wrapperClass=""
|
||||
/>
|
||||
Open <i>Developer tools</i> to follow progress
|
||||
</>
|
||||
<p className="text-sm text-gray-500 mt-2">
|
||||
Open <i>Developer Tools</i> to follow progress
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<pre>{JSON.stringify(result, null, 2)}</pre>
|
||||
</>
|
||||
<div className="bg-gray-100 border border-gray-300 p-4 rounded-lg mt-4">
|
||||
<pre className="text-left text-sm text-gray-800 whitespace-pre-wrap overflow-auto">
|
||||
{JSON.stringify(result, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
12
demo/interactive-demo/prover-ts/tailwind.config.js
Normal file
12
demo/interactive-demo/prover-ts/tailwind.config.js
Normal file
@@ -0,0 +1,12 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{js,jsx,ts,tsx}'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#243f5f',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
@@ -20,7 +20,7 @@
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": [
|
||||
"app.tsx",
|
||||
"worker.ts"
|
||||
"src/app.tsx",
|
||||
"src/worker.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ var options = {
|
||||
],
|
||||
mode: 'development',
|
||||
entry: {
|
||||
app: path.join(__dirname, 'app.tsx'),
|
||||
app: path.join(__dirname, 'src', 'app.tsx'),
|
||||
},
|
||||
output: {
|
||||
filename: '[name].bundle.js',
|
||||
@@ -51,6 +51,9 @@ var options = {
|
||||
test: /\.(ts|tsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: 'source-map-loader',
|
||||
},
|
||||
{
|
||||
loader: require.resolve('ts-loader'),
|
||||
},
|
||||
@@ -68,6 +71,29 @@ var options = {
|
||||
],
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
{
|
||||
// look for .css or .scss files
|
||||
test: /\.(css|scss)$/,
|
||||
// in the `web` directory
|
||||
use: [
|
||||
{
|
||||
loader: 'style-loader',
|
||||
},
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: { importLoaders: 1 },
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
@@ -75,6 +101,11 @@ var options = {
|
||||
extensions: fileExtensions
|
||||
.map((extension) => '.' + extension)
|
||||
.concat(['.js', '.jsx', '.ts', '.tsx', '.css']),
|
||||
fallback: {
|
||||
crypto: require.resolve('crypto-browserify'),
|
||||
stream: require.resolve('stream-browserify'),
|
||||
vm: require.resolve('vm-browserify'),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin({
|
||||
@@ -87,15 +118,16 @@ var options = {
|
||||
],
|
||||
}),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{ from: '../README.md', to: 'README.md' },
|
||||
],
|
||||
patterns: [{ from: '../README.md', to: 'README.md' }],
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.join(__dirname, 'index.ejs'),
|
||||
filename: 'index.html',
|
||||
cache: false,
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
Buffer: ['buffer', 'Buffer'],
|
||||
}),
|
||||
@@ -105,13 +137,16 @@ var options = {
|
||||
// - https://github.com/GoogleChromeLabs/wasm-bindgen-rayon#setting-up
|
||||
// - https://web.dev/i18n/en/coop-coep/
|
||||
devServer: {
|
||||
port: 3456,
|
||||
port: 8080,
|
||||
host: 'localhost',
|
||||
hot: true,
|
||||
headers: {
|
||||
'Cross-Origin-Embedder-Policy': 'require-corp',
|
||||
'Cross-Origin-Opener-Policy': 'same-origin',
|
||||
},
|
||||
client: {
|
||||
overlay: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -11,9 +11,16 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"comlink": "^4.4.1",
|
||||
"css-loader": "^7.1.2",
|
||||
"postcss": "^8.4.49",
|
||||
"postcss-loader": "^8.1.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-loader-spinner": "^6.1.6",
|
||||
"sass": "^1.83.1",
|
||||
"sass-loader": "^16.0.4",
|
||||
"style-loader": "^4.0.0",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tlsn-js": "../../"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -23,6 +30,7 @@
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"postcss-preset-env": "^10.1.3",
|
||||
"source-map-loader": "^5.0.0",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"ts-loader": "^9.4.2",
|
||||
|
||||
4
demo/react-ts-webpack/postcss.config.js
Normal file
4
demo/react-ts-webpack/postcss.config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
const tailwindcss = require("tailwindcss");
|
||||
module.exports = {
|
||||
plugins: ["postcss-preset-env", tailwindcss],
|
||||
};
|
||||
3
demo/react-ts-webpack/src/app.scss
Normal file
3
demo/react-ts-webpack/src/app.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
Transcript,
|
||||
} from 'tlsn-js';
|
||||
import { PresentationJSON } from 'tlsn-js/build/types';
|
||||
import './app.scss';
|
||||
|
||||
const { init, Prover, Presentation }: any = Comlink.wrap(
|
||||
new Worker(new URL('./worker.ts', import.meta.url)),
|
||||
@@ -20,6 +21,14 @@ const root = createRoot(container!);
|
||||
|
||||
root.render(<App />);
|
||||
|
||||
const local = true; // Toggle between local and remote notary
|
||||
const notaryUrl = local ? 'http://localhost:7047' : 'https://notary.pse.dev/v0.1.0-alpha.7';
|
||||
const websocketProxyUrl = local ? 'ws://localhost:55688' : 'wss://notary.pse.dev/proxy?token=swapi.dev';
|
||||
const loggingLevel = 'Info'; // https://github.com/tlsnotary/tlsn/blob/main/crates/wasm/src/log.rs#L8
|
||||
|
||||
const serverUrl = 'https://swapi.dev/api/people/1';
|
||||
const serverDns = 'swapi.dev';
|
||||
|
||||
function App(): ReactElement {
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
const [processing, setProcessing] = useState(false);
|
||||
@@ -29,22 +38,24 @@ function App(): ReactElement {
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
await init({ loggingLevel: 'Info' });
|
||||
await init({ loggingLevel: loggingLevel });
|
||||
setInitialized(true);
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const onClick = useCallback(async () => {
|
||||
setProcessing(true);
|
||||
const notary = NotaryServer.from(`http://localhost:7047`);
|
||||
const notary = NotaryServer.from(notaryUrl);
|
||||
console.time('submit');
|
||||
const prover = (await new Prover({
|
||||
serverDns: 'swapi.dev',
|
||||
serverDns: serverDns,
|
||||
maxRecvData: 2048,
|
||||
})) as TProver;
|
||||
|
||||
await prover.setup(await notary.sessionUrl());
|
||||
const resp = await prover.sendRequest('ws://localhost:55688', {
|
||||
url: 'https://swapi.dev/api/people/1',
|
||||
|
||||
const resp = await prover.sendRequest(websocketProxyUrl, {
|
||||
url: serverUrl,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -98,13 +109,14 @@ function App(): ReactElement {
|
||||
const onAltClick = useCallback(async () => {
|
||||
setProcessing(true);
|
||||
const proof = await (Prover.notarize as typeof TProver.notarize)({
|
||||
notaryUrl: 'http://localhost:7047',
|
||||
websocketProxyUrl: 'ws://localhost:55688',
|
||||
url: 'https://swapi.dev/api/people/1',
|
||||
notaryUrl: notaryUrl,
|
||||
websocketProxyUrl: websocketProxyUrl,
|
||||
url: serverUrl,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
|
||||
body: {
|
||||
hello: 'world',
|
||||
one: 1,
|
||||
@@ -124,7 +136,7 @@ function App(): ReactElement {
|
||||
const proof = (await new Presentation(
|
||||
presentationJSON.data,
|
||||
)) as TPresentation;
|
||||
const notary = NotaryServer.from(`http://localhost:7047`);
|
||||
const notary = NotaryServer.from(notaryUrl);
|
||||
const notaryKey = await notary.publicKey('hex');
|
||||
const verifierOutput = await proof.verify();
|
||||
const transcript = new Transcript({
|
||||
@@ -146,60 +158,117 @@ function App(): ReactElement {
|
||||
}, [presentationJSON, setResult]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<button
|
||||
onClick={!processing ? onClick : undefined}
|
||||
disabled={processing || !initialized}
|
||||
>
|
||||
Start Demo (Normal config)
|
||||
</button>
|
||||
<div className="bg-slate-100 min-h-screen p-6 text-slate-800 flex flex-col items-center">
|
||||
<h1 className="text-2xl font-bold mb-6 text-slate-700">
|
||||
TLSNotary React TypeScript Demo{' '}
|
||||
</h1>
|
||||
<div className="mb-4 text-base font-light max-w-2xl">
|
||||
<p>
|
||||
This demo showcases how to use TLSNotary in a React/TypeScript app with the tlsn-js library.
|
||||
We will fetch JSON data from the Star Wars API, notarize the TLS request using TLSNotary,
|
||||
and verify the proof. The demo runs entirely in the browser.
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://docs.tlsnotary.org/quick_start/tlsn-js.html" className="text-blue-500 hover:underline">
|
||||
More info
|
||||
</a>
|
||||
</p>
|
||||
<table className="table-auto w-full mt-4">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-4 py-2 text-left">Demo Settings</th>
|
||||
<th className="px-4 py-2 text-left">URL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="border px-4 py-2">Server</td>
|
||||
<td className="border px-4 py-2">{serverUrl}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="border px-4 py-2">Notary Server</td>
|
||||
<td className="border px-4 py-2">{notaryUrl}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="border px-4 py-2">WebSocket Proxy</td>
|
||||
<td className="border px-4 py-2">{websocketProxyUrl}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
onClick={!processing ? onAltClick : undefined}
|
||||
disabled={processing || !initialized}
|
||||
>
|
||||
Start Demo 2 (With helper method)
|
||||
</button>
|
||||
|
||||
<div className="mb-4">
|
||||
<p className="mb-2 text-base font-light">
|
||||
There are two versions of the demo: one with a normal config and one with a helper method.
|
||||
</p>
|
||||
<div className="flex justify-center gap-4">
|
||||
<button
|
||||
onClick={!processing ? onClick : undefined}
|
||||
disabled={processing || !initialized}
|
||||
className={`px-4 py-2 rounded-md text-white shadow-md font-semibold
|
||||
${processing || !initialized ? 'bg-slate-400 cursor-not-allowed' : 'bg-slate-600 hover:bg-slate-700'}`}
|
||||
>
|
||||
Start Demo (Normal config)
|
||||
</button>
|
||||
<button
|
||||
onClick={!processing ? onAltClick : undefined}
|
||||
disabled={processing || !initialized}
|
||||
className={`px-4 py-2 rounded-md text-white shadow-md font-semibold
|
||||
${processing || !initialized ? 'bg-slate-400 cursor-not-allowed' : 'bg-slate-600 hover:bg-slate-700'}`}
|
||||
>
|
||||
Start Demo 2 (With helper method)
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<b>Proof: </b>
|
||||
{!processing && !presentationJSON ? (
|
||||
<i>not started</i>
|
||||
) : !presentationJSON ? (
|
||||
<>
|
||||
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(presentationJSON, null, 2)}</pre>
|
||||
{processing && (
|
||||
<div className="mt-6 flex justify-center items-center">
|
||||
<Watch
|
||||
visible={true}
|
||||
height="40"
|
||||
width="40"
|
||||
radius="48"
|
||||
color="#1E293B"
|
||||
ariaLabel="watch-loading"
|
||||
wrapperStyle={{}}
|
||||
wrapperClass=""
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col sm:flex-row gap-6 w-full max-w-4xl">
|
||||
<div className="flex-1 bg-slate-50 border border-slate-200 rounded p-4">
|
||||
<b className="text-slate-600">Proof: </b>
|
||||
{!processing && !presentationJSON ? (
|
||||
<i className="text-slate-500">not started</i>
|
||||
) : !presentationJSON ? (
|
||||
<div className="flex flex-col items-start space-y-2">
|
||||
<span>Proving data from {serverDns}...</span>
|
||||
<span className="text-slate-500">
|
||||
Open <i>Developer tools</i> to follow progress
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<details className="bg-slate-50 border border-slate-200 rounded p-2">
|
||||
<summary className="cursor-pointer text-slate-600">
|
||||
View Proof
|
||||
</summary>
|
||||
<pre className="mt-2 p-2 bg-slate-100 rounded text-sm text-slate-800">
|
||||
{JSON.stringify(presentationJSON, null, 2)}
|
||||
</pre>
|
||||
</details>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<b>Verification: </b>
|
||||
{!presentationJSON ? (
|
||||
<i>not started</i>
|
||||
) : !result ? (
|
||||
<i>verifying</i>
|
||||
) : (
|
||||
<pre>{JSON.stringify(result, null, 2)}</pre>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1 bg-slate-50 border border-slate-200 rounded p-4">
|
||||
<b className="text-slate-600">Verification: </b>
|
||||
{!presentationJSON ? (
|
||||
<i className="text-slate-500">not started</i>
|
||||
) : !result ? (
|
||||
<i className="text-slate-500">verifying</i>
|
||||
) : (
|
||||
<pre className="mt-2 p-2 bg-slate-100 rounded text-sm text-slate-800">
|
||||
{JSON.stringify(result, null, 2)}
|
||||
</pre>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
12
demo/react-ts-webpack/tailwind.config.js
Normal file
12
demo/react-ts-webpack/tailwind.config.js
Normal file
@@ -0,0 +1,12 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{js,jsx,ts,tsx}'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#243f5f',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
29
demo/react-ts-webpack/webpack.js
vendored
29
demo/react-ts-webpack/webpack.js
vendored
@@ -71,6 +71,29 @@ var options = {
|
||||
],
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
{
|
||||
// look for .css or .scss files
|
||||
test: /\.(css|scss)$/,
|
||||
// in the `web` directory
|
||||
use: [
|
||||
{
|
||||
loader: 'style-loader',
|
||||
},
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: { importLoaders: 1 },
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
@@ -111,10 +134,16 @@ var options = {
|
||||
// - https://github.com/GoogleChromeLabs/wasm-bindgen-rayon#setting-up
|
||||
// - https://web.dev/i18n/en/coop-coep/
|
||||
devServer: {
|
||||
port: 8080,
|
||||
host: 'localhost',
|
||||
hot: true,
|
||||
headers: {
|
||||
'Cross-Origin-Embedder-Policy': 'require-corp',
|
||||
'Cross-Origin-Opener-Policy': 'same-origin',
|
||||
},
|
||||
client: {
|
||||
overlay: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -192,49 +192,60 @@ function App(): ReactElement {
|
||||
}, [ready]);
|
||||
|
||||
return (
|
||||
<div className="w-screen h-screen flex flex-col overflow-hidden">
|
||||
<div className="w-full p-2.5 bg-slate-200 mb-5 flex-shrink-0">
|
||||
<h1>Web-to-Web P2P Demo</h1>
|
||||
<p>
|
||||
<div className="w-screen h-screen flex flex-col bg-slate-100 overflow-hidden">
|
||||
<div className="w-full p-4 bg-slate-800 text-white flex-shrink-0 shadow-md">
|
||||
<h1 className="text-xl font-bold">Web-to-Web P2P Demo</h1>
|
||||
<p className="text-sm mt-1">
|
||||
This demo showcases peer-to-peer communication between a web prover
|
||||
and a web verifier using TLSNotary. The prover fetches data from{' '}
|
||||
<a href="https://swapi.dev" target="_blank" rel="noopener noreferrer">
|
||||
<a
|
||||
href="https://swapi.dev"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="underline text-blue-400 hover:text-blue-300"
|
||||
>
|
||||
swapi.dev
|
||||
</a>{' '}
|
||||
and proves it to the verifier.
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid grid-rows-2 grid-cols-2 p-2 gap-2 flex-grow">
|
||||
<div className="flex flex-col items-center border border-slate-300 bg-slate-50 rounded row-span-1 col-span-1 p-4 gap-2">
|
||||
<div className="font-semibold">Prover</div>
|
||||
<div className="flex flex-col text-sm bg-white border border-slate-300 w-full flex-grow cursor-text py-1 overflow-y-auto">
|
||||
|
||||
<div className="grid grid-rows-2 grid-cols-2 gap-4 p-4 flex-grow">
|
||||
<div className="flex flex-col items-center border border-slate-300 bg-white rounded-lg shadow-md row-span-1 col-span-1 p-4 gap-2">
|
||||
<div className="font-semibold text-slate-700 text-lg">Prover</div>
|
||||
<div className="flex flex-col text-sm bg-slate-50 border border-slate-200 w-full flex-grow py-2 overflow-y-auto rounded">
|
||||
{proverMessages.map((m, index) => (
|
||||
<span key={index} className="px-2 py-1 text-slate-600 break-all">
|
||||
{m}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center border border-slate-300 bg-slate-100 rounded row-span-1 col-span-1 p-4 gap-2">
|
||||
<div className="font-semibold">Verifier</div>
|
||||
<div className="flex flex-col text-sm bg-white border border-slate-300 w-full flex-grow cursor-text py-1 overflow-y-auto">
|
||||
{verifierMessages.map((m, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="px-1 py-0.5 text-slate-600 break-all"
|
||||
className="px-3 py-1 text-slate-600 break-words"
|
||||
>
|
||||
{m}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row justify-center row-span-1 col-span-2">
|
||||
|
||||
<div className="flex flex-col items-center border border-slate-300 bg-white rounded-lg shadow-md row-span-1 col-span-1 p-4 gap-2">
|
||||
<div className="font-semibold text-slate-700 text-lg">Verifier</div>
|
||||
<div className="flex flex-col text-sm bg-slate-50 border border-slate-200 w-full flex-grow py-2 overflow-y-auto rounded">
|
||||
{verifierMessages.map((m, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="px-3 py-1 text-slate-600 break-words"
|
||||
>
|
||||
{m}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row justify-center items-center row-span-1 col-span-2">
|
||||
<Button
|
||||
className="h-fit"
|
||||
className="bg-slate-800 text-white font-semibold px-6 py-3 rounded-lg shadow-md hover:bg-slate-700 disabled:opacity-50"
|
||||
disabled={!ready || started}
|
||||
onClick={start}
|
||||
>
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
{ready && !started ? (
|
||||
<>Start Demo</>
|
||||
) : (
|
||||
@@ -243,10 +254,8 @@ function App(): ReactElement {
|
||||
height="40"
|
||||
width="40"
|
||||
radius="48"
|
||||
color="#000000"
|
||||
color="#ffffff"
|
||||
ariaLabel="watch-loading"
|
||||
wrapperStyle={{}}
|
||||
wrapperClass=""
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -134,7 +134,7 @@ var options = {
|
||||
// - https://github.com/GoogleChromeLabs/wasm-bindgen-rayon#setting-up
|
||||
// - https://web.dev/i18n/en/coop-coep/
|
||||
devServer: {
|
||||
port: 3456,
|
||||
port: 8080,
|
||||
host: 'localhost',
|
||||
hot: true,
|
||||
headers: {
|
||||
|
||||
3615
package-lock.json
generated
3615
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
2092
pnpm-lock.yaml
generated
2092
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -273,7 +273,6 @@ export class Prover {
|
||||
async reveal(reveal: Reveal) {
|
||||
return this.#prover.reveal(reveal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class Verifier {
|
||||
|
||||
Reference in New Issue
Block a user