chore: Use raw.githubusercontent.com instead of swapi for the demos (#105)

+ use a local proxy for testing
+ avoid duplicate github action runs
This commit is contained in:
Hendrik Eeckhaut
2025-05-12 16:34:36 +02:00
committed by GitHub
parent 8bf3745407
commit 8bc8a94948
14 changed files with 104 additions and 69 deletions

View File

@@ -1,7 +1,6 @@
name: ci
on:
push:
pull_request:
release:
types: [published]
@@ -19,12 +18,12 @@ jobs:
env:
RELEASE_MODE: 'dry-run' # dry-run by default, will be set to 'publish' for release builds
services:
notary-server:
image: ghcr.io/tlsnotary/tlsn/notary-server:v0.1.0-alpha.10
env:
NOTARY_SERVER__TLS__ENABLED: false
ports:
- 7047:7047
notary-server:
image: ghcr.io/tlsnotary/tlsn/notary-server:v0.1.0-alpha.10
env:
NOTARY_SERVER__TLS__ENABLED: false
ports:
- 7047:7047
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -76,7 +75,13 @@ jobs:
run: echo "CHROME_PATH=${{ steps.setup-chrome.outputs['chrome-path'] }}" >> $GITHUB_ENV
- name: Test
run: npm run test
run: |
# Install wstcp and use it in the background
cargo install wstcp
wstcp --bind-addr 127.0.0.1:55688 raw.githubusercontent.com:443 &
WSTCP_PID=$!
trap "kill $WSTCP_PID" EXIT
npm run test
- name: Determine release type (dry-run or publish)
run: |

View File

@@ -14,11 +14,11 @@ cd prover-rs; cargo run --release
```bash
cd verifier-rs; cargo run --release
```
2. Since a web browser doesn't have the ability to make TCP connection, we need to use a websocket proxy server to access <swapi.dev>.
2. Since a web browser doesn't have the ability to make TCP connection, we need to use a websocket proxy server to access <raw.githubusercontent.com>.
```bash
cargo install wstcp
wstcp --bind-addr 127.0.0.1:55688 swapi.dev:443
wstcp --bind-addr 127.0.0.1:55688 raw.githubusercontent.com:443
```
3. Run the prover
1. Build tlsn-js

View File

@@ -27,4 +27,5 @@ ws_stream_tungstenite = { version = "0.13", features = ["tokio_io"] }
tlsn-core = { git = "https://github.com/tlsnotary/tlsn.git", tag = "v0.1.0-alpha.10", package = "tlsn-core" }
tlsn-prover = { git = "https://github.com/tlsnotary/tlsn.git", tag = "v0.1.0-alpha.10", package = "tlsn-prover" }
tlsn-common = { git = "https://github.com/tlsnotary/tlsn.git", tag = "v0.1.0-alpha.10", package = "tlsn-common" }
tlsn-common = { git = "https://github.com/tlsnotary/tlsn.git", tag = "v0.1.0-alpha.10", package = "tlsn-common" }
spansy = {git = "https://github.com/tlsnotary/tlsn-utils", package = "spansy", branch = "dev"}

View File

@@ -2,7 +2,7 @@
An implementation of the interactive prover in Rust.
## Running the prover
1. Configure this prover setting via the global variables defined in [main.rs](./src/main.rs) — please ensure that the hardcoded `SERVER_URL` and `VERIFICATION_SESSION_ID` have the same values on the verifier side.
1. Configure this prover setting via the global variables defined in [main.rs](./src/main.rs) — please ensure that the hardcoded `SERVER_URL` is the same on the verifier side.
2. Start the prover by running the following in a terminal at the root of this crate.
```bash
cargo run --release

View File

@@ -2,7 +2,11 @@ use async_tungstenite::{tokio::connect_async_with_config, tungstenite::protocol:
use http_body_util::Empty;
use hyper::{body::Bytes, Request, StatusCode, Uri};
use hyper_util::rt::TokioIo;
use regex::Regex;
use spansy::{
http::parse_response,
json::{self},
Spanned,
};
use tlsn_common::config::ProtocolConfig;
use tlsn_core::transcript::Idx;
use tlsn_prover::{state::Prove, Prover, ProverConfig};
@@ -23,7 +27,7 @@ const MAX_RECV_DATA: usize = 1 << 14;
const SECRET: &str = "TLSNotary's private key 🤡";
/// Make sure the following url's domain is the same as SERVER_DOMAIN on the verifier side
const SERVER_URL: &str = "https://swapi.dev/api/people/1";
const SERVER_URL: &str = "https://raw.githubusercontent.com/tlsnotary/tlsn/refs/tags/v0.1.0-alpha.10/crates/server-fixture/server/src/data/1kb.json";
#[tokio::main]
async fn main() {
@@ -140,18 +144,27 @@ async fn prover<T: AsyncWrite + AsyncRead + Send + Unpin + 'static>(verifier_soc
/// Redacts and reveals received data to the verifier.
fn redact_and_reveal_received_data(prover: &mut Prover<Prove>) -> Idx {
let recv_transcript = prover.transcript().received();
let recv_transcript_len = recv_transcript.len();
// Get the homeworld from the received data.
// Get the some information from the received data.
let received_string = String::from_utf8(recv_transcript.to_vec()).unwrap();
debug!("Received data: {}", received_string);
let re = Regex::new(r#""homeworld"\s?:\s?"(.*?)""#).unwrap();
let homeworld_match = re.captures(&received_string).unwrap().get(1).unwrap();
let resp = parse_response(recv_transcript).unwrap();
let body = resp.body.unwrap();
let mut json = json::parse_slice(body.as_bytes()).unwrap();
json.offset(body.content.span().indices().min().unwrap());
// Reveal everything except for the homeworld.
let start = homeworld_match.start();
let end = homeworld_match.end();
Idx::new([0..start, end..recv_transcript_len])
let name = json.get("information.name").expect("name field not found");
let street = json
.get("information.address.street")
.expect("street field not found");
let name_start = name.span().indices().min().unwrap() - 9; // 9 is the length of "name: "
let name_end = name.span().indices().max().unwrap() + 1; // include `"`
let street_start = street.span().indices().min().unwrap() - 11; // 11 is the length of "street: "
let street_end = street.span().indices().max().unwrap() + 1; // include `"`
Idx::new([name_start..name_end + 1, street_start..street_end + 1])
}
/// Redacts and reveals sent data to the verifier.

View File

@@ -17,8 +17,8 @@ const root = createRoot(container!);
root.render(<App />);
const serverUrl = 'https://swapi.dev/api/people/1';
// let websocketProxyUrl = 'wss://notary.pse.dev/proxy';
const serverUrl = 'https://raw.githubusercontent.com/tlsnotary/tlsn/refs/tags/v0.1.0-alpha.10/crates/server-fixture/server/src/data/1kb.json';
// const websocketProxyUrl = `wss://notary.pse.dev/proxy`;
const websocketProxyUrl = 'ws://localhost:55688';
const verifierProxyUrl = 'ws://localhost:9816/verify';
@@ -44,7 +44,10 @@ function App(): ReactElement {
console.time('setup');
await init({ loggingLevel: 'Info' });
console.log('Setting up Prover for', hostname);
prover = (await new Prover({ serverDns: hostname })) as TProver;
prover = (await new Prover({
serverDns: hostname,
maxRecvData: 2000
})) as TProver;
console.log('Setting up Prover: 1/2');
await prover.setup(verifierProxyUrl);
console.log('Setting up Prover: done');
@@ -89,6 +92,8 @@ function App(): ReactElement {
const body = JSON.parse(recvBody[0].toString());
console.log("test", body.information.address.street);
console.time('reveal');
const reveal: Commit = {
sent: subtractRanges(
@@ -110,9 +115,8 @@ function App(): ReactElement {
`${recvHeaders[14]}: ${recvHeaders[15]}`,
`${recvHeaders[16]}: ${recvHeaders[17]}`,
`${recvHeaders[18]}: ${recvHeaders[19]}`,
`"name":"${body.name}"`,
`"gender":"${body.gender}"`,
`"eye_color":"${body.eye_color}"`,
`"name": "${body.information.name}"`,
`"street": "${body.information.address.street}"`,
],
Buffer.from(recv).toString('utf-8'),
),
@@ -203,7 +207,7 @@ function App(): ReactElement {
<i className="text-gray-500">Not started yet</i>
) : !result ? (
<div className="flex flex-col items-center justify-center">
<p className="text-gray-700 mb-2">Proving data from swapi...</p>
<p className="text-gray-700 mb-2">Proving data from GitHub...</p>
<Watch
visible={true}
height="40"

View File

@@ -44,7 +44,7 @@ pub async fn run_server(
) -> Result<(), eyre::ErrReport> {
let verifier_address = SocketAddr::new(
IpAddr::V4(verifier_host.parse().map_err(|err| {
eyre!("Failed to parse verifer host address from server config: {err}")
eyre!("Failed to parse verifier host address from server config: {err}")
})?),
verifier_port,
);
@@ -153,10 +153,11 @@ async fn verifier<T: AsyncWrite + AsyncRead + Send + Unpin + 'static>(
debug!("Starting received data verification...");
let received = partial_transcript.received_unsafe().to_vec();
let response = String::from_utf8(received.clone()).expect("Verifier expected received data");
debug!("Received data: {:?}", response);
response
.find("eye_color")
.ok_or_else(|| eyre!("Verification failed: missing eye_color in received data"))?;
.find("123 Elm Street")
.ok_or_else(|| eyre!("Verification failed: missing data in received data"))?;
// Check Session info: server name.
if session_info.server_name.as_str() != server_domain {
return Err(eyre!("Verification failed: server name mismatches"));

View File

@@ -7,7 +7,7 @@ const VERIFIER_HOST: &str = "0.0.0.0";
const VERIFIER_PORT: u16 = 9816;
/// Make sure the following domain is the same in SERVER_URL on the prover side
const SERVER_DOMAIN: &str = "swapi.dev";
const SERVER_DOMAIN: &str = "raw.githubusercontent.com";
#[tokio::main]
async fn main() -> Result<(), eyre::ErrReport> {

View File

@@ -29,11 +29,11 @@ const notaryUrl = local
: 'https://notary.pse.dev/v0.1.0-alpha.10';
const websocketProxyUrl = local
? 'ws://localhost:55688'
: 'wss://notary.pse.dev/proxy?token=swapi.dev';
: 'wss://notary.pse.dev/proxy?token=raw.githubusercontent.com';
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';
const serverUrl = 'https://raw.githubusercontent.com/tlsnotary/tlsn/refs/tags/v0.1.0-alpha.10/crates/server-fixture/server/src/data/1kb.json';
const serverDns = 'raw.githubusercontent.com';
function App(): ReactElement {
const [initialized, setInitialized] = useState(false);
@@ -111,8 +111,8 @@ function App(): ReactElement {
`${recvHeaders[14]}: ${recvHeaders[15]}`,
`${recvHeaders[16]}: ${recvHeaders[17]}`,
`${recvHeaders[18]}: ${recvHeaders[19]}`,
`"name":"${body.name}"`,
`"gender":"${body.gender}"`,
`"name": "${body.information.name}"`,
`"street": "${body.information.address.street}"`,
],
Buffer.from(recv).toString('utf-8'),
),
@@ -240,7 +240,7 @@ function App(): ReactElement {
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'}`}
${processing || !initialized ? 'bg-slate-400 cursor-not-allowed' : 'bg-slate-600 hover:bg-slate-700'}`}
>
Start Demo (Normal config)
</button>
@@ -248,7 +248,7 @@ function App(): ReactElement {
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'}`}
${processing || !initialized ? 'bg-slate-400 cursor-not-allowed' : 'bg-slate-600 hover:bg-slate-700'}`}
>
Start Demo 2 (With helper method)
</button>
@@ -268,7 +268,7 @@ function App(): ReactElement {
/>
</div>
)}
<div className="flex flex-col sm:flex-row gap-6 w-full max-w-4xl">
<div className="flex flex-col 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 ? (
@@ -285,7 +285,10 @@ function App(): ReactElement {
<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">
<pre
className="mt-2 p-2 bg-slate-100 rounded text-sm text-slate-800 overflow-auto"
style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}
>
{JSON.stringify(presentationJSON, null, 2)}
</pre>
</details>
@@ -298,7 +301,10 @@ function App(): ReactElement {
) : !result ? (
<i className="text-slate-500">verifying</i>
) : (
<pre className="mt-2 p-2 bg-slate-100 rounded text-sm text-slate-800">
<pre
className="mt-2 p-2 bg-slate-100 rounded text-sm text-slate-800 overflow-auto"
style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}
>
{JSON.stringify(result, null, 2)}
</pre>
)}

View File

@@ -1,7 +1,7 @@
# Web-to-Web P2P Demo
This project demonstrates a peer-to-peer (P2P) communication between two web clients using TLSNotary.
The web prover will get data from <https://swapi.dev> and prove it to the web verifier.
The web prover will get data from <https://raw.githubusercontent.com> and prove it to the web verifier.
In this demo, the two web clients run in the same browser page (`./src/app.tsx`) and communicate via a simple websocket server (`./server/index.js`)

View File

@@ -27,9 +27,9 @@ let proverLogs: string[] = [];
let verifierLogs: string[] = [];
const p2pProxyUrl = 'ws://localhost:3001';
const serverDns = 'swapi.dev';
const serverDns = 'raw.githubusercontent.com';
const webSocketProxy = `wss://notary.pse.dev/proxy?token=${serverDns}`;
const requestUrl = `https://swapi.dev/api/people/1`;
const requestUrl = `https://raw.githubusercontent.com/tlsnotary/tlsn/refs/tags/v0.1.0-alpha.10/crates/server-fixture/server/src/data/1kb.json`;
function App(): ReactElement {
const [ready, setReady] = useState(false);
@@ -40,7 +40,7 @@ function App(): ReactElement {
// Initialize TLSNotary
useEffect(() => {
(async () => {
await init({ loggingLevel: 'Debug' });
await init({ loggingLevel: 'Info' });
setReady(true);
})();
}, []);
@@ -96,11 +96,14 @@ function App(): ReactElement {
addProverLog('Instantiate Prover class');
const prover: TProver = await new Prover({
serverDns: serverDns,
maxRecvData: 2000
});
addProverLog('Prover class instantiated');
addVerifierLog('Instantiate Verifier class');
const verifier: TVerifier = await new Verifier({});
const verifier: TVerifier = await new Verifier({
maxRecvData: 2000
});
addVerifierLog('Verifier class instantiated');
addVerifierLog('Connect verifier to p2p proxy');
@@ -190,8 +193,8 @@ function App(): ReactElement {
`${recvHeaders[14]}: ${recvHeaders[15]}`,
`${recvHeaders[16]}: ${recvHeaders[17]}`,
`${recvHeaders[18]}: ${recvHeaders[19]}`,
`"name":"${body.name}"`,
`"gender":"${body.gender}"`,
`"name": "${body.information.name}"`,
`"street": "${body.information.address.street}"`,
],
Buffer.from(recv).toString('utf-8'),
),
@@ -222,12 +225,12 @@ function App(): ReactElement {
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"
href="https://raw.githubusercontent.com/tlsnotary/tlsn/refs/tags/v0.1.0-alpha.10/crates/server-fixture/server/src/data/1kb.json"
target="_blank"
rel="noopener noreferrer"
className="underline text-blue-400 hover:text-blue-300"
>
swapi.dev
our GitHub repository
</a>{' '}
and proves it to the verifier.
</p>
@@ -240,7 +243,7 @@ function App(): ReactElement {
{proverMessages.map((m, index) => (
<span
key={index}
className="px-3 py-1 text-slate-600 break-words"
className="px-3 py-1 text-slate-600 break-all"
>
{m}
</span>
@@ -254,7 +257,7 @@ function App(): ReactElement {
{verifierMessages.map((m, index) => (
<span
key={index}
className="px-3 py-1 text-slate-600 break-words"
className="px-3 py-1 text-slate-600 break-all"
>
{m}
</span>

View File

@@ -8,22 +8,22 @@ There is a simple react/typescript demo app in `./demo/react-ts-webpack`. The di
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 websocket proxy for `https://swapi.dev` **locally**:
To run your own websocket proxy for `https://raw.githubusercontent.com` **locally**:
1. Install [websocat](https://github.com/vi/websocat):
1. Install [wstcp](https://github.com/sile/wstcp):
| tool | command |
| ------ | ------------------------------ |
| cargo | `cargo install websocat` |
| brew | `brew install websocat` |
| source | https://github.com/vi/websocat |
| Tool | Command |
| ------ | ----------------------------- |
| cargo | `cargo install wstcp` |
| brew | `brew install wstcp` |
| source | https://github.com/sile/wstcp |
2. Run a websocket proxy for `https://swapi.dev`:
2. Run a websocket proxy for `https://raw.githubusercontent.com`:
```sh
websocat --binary -v ws-l:0.0.0.0:55688 tcp:swapi.dev:443
wstcp --bind-addr 127.0.0.1:55688 raw.githubusercontent.com:443
```
Note the `tcp:swapi.dev:443` argument on the last line, this is the server we will use in this quick start.
Note the `raw.githubusercontent.com: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>

View File

@@ -37,7 +37,7 @@ The `./demo` folder contains three demos of `tlsn-js`:
## Running a local websocket proxy
In the demos, we attest data from the `https://swapi.dev` website. Because the browser does not allow for TCP connections, you need to set up a websocket proxy:
In the demos, we attest data from `https://raw.githubusercontent.com`. Because the browser does not allow for TCP connections, you need to set up a websocket proxy:
1. Install [wstcp](https://github.com/sile/wstcp):
@@ -47,11 +47,10 @@ In the demos, we attest data from the `https://swapi.dev` website. Because the b
| brew | `brew install wstcp` |
| source | https://github.com/sile/wstcp |
2. Run a websocket proxy for `https://swapi.dev`:
2. Run a websocket proxy for `https://raw.githubusercontent.com`:
```sh
wstcp --bind-addr 127.0.0.1:55688 swapi.dev:443
wstcp --bind-addr 127.0.0.1:55688 raw.githubusercontent.com:443
```
## Install as NPM Package
```sh

View File

@@ -28,7 +28,10 @@ const { init, Prover, Presentation }: any = Comlink.wrap(
})) as _Prover;
const notary = NotaryServer.from('http://127.0.0.1:7047');
await prover.setup(await notary.sessionUrl());
await prover.sendRequest('wss://notary.pse.dev/proxy?token=raw.githubusercontent.com', {
// const websocketProxyUrl = 'wss://notary.pse.dev/proxy?token=raw.githubusercontent.com';
const websocketProxyUrl = 'ws://127.0.0.1:55688';
await prover.sendRequest(websocketProxyUrl, {
url: 'https://raw.githubusercontent.com/tlsnotary/tlsn/refs/heads/main/crates/server-fixture/server/src/data/protected_data.json',
headers: {
'content-type': 'application/json',