Skip to content

Commit

Permalink
✨ working demo
Browse files Browse the repository at this point in the history
  • Loading branch information
AbdelStark committed Jul 17, 2024
1 parent 3679dfa commit 0d9a249
Show file tree
Hide file tree
Showing 16 changed files with 233 additions and 26 deletions.
11 changes: 11 additions & 0 deletions .env.docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
RUN_MODE=development
APP_SUBSCRIBED_RELAYS=ws://nostr-relay:8080
APP_PROVING_REQ_SUB_ID=askeladd.proving.request
APP_PROVING_RESP_SUB_ID=askeladd.proving.response

# User's secret key
# DO NOT USE THIS KEY IN PRODUCTION
APP_USER_BECH32_SK=nsec1tsaxyqcxp8atqup4facwp0as52f2c0evj4cxpw6yaqetusu7sg8qqzkr3k
# Prover agent's secret key
# DO NOT USE THIS KEY IN PRODUCTION
APP_PROVER_AGENT_SK=nsec18s6wcqlkglhjmfz3tnjkh0qscf6cqen96ecp5k5k73ktew3l97tstuvy2x
11 changes: 11 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
RUN_MODE=development
APP_SUBSCRIBED_RELAYS=ws://127.0.0.1:8080
APP_PROVING_REQ_SUB_ID=askeladd.proving.request
APP_PROVING_RESP_SUB_ID=askeladd.proving.response

# User's secret key
# DO NOT USE THIS KEY IN PRODUCTION
APP_USER_BECH32_SK=nsec1tsaxyqcxp8atqup4facwp0as52f2c0evj4cxpw6yaqetusu7sg8qqzkr3k
# Prover agent's secret key
# DO NOT USE THIS KEY IN PRODUCTION
APP_PROVER_AGENT_SK=nsec18s6wcqlkglhjmfz3tnjkh0qscf6cqen96ecp5k5k73ktew3l97tstuvy2x
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ Cargo.lock
/target

# Ignore macos specific files
.DS_Store
.DS_Store

# Ignore .env files
.env
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM rust:1.67-alpine AS builder
WORKDIR /usr/src/askeladd
RUN apk add --no-cache musl-dev
COPY . .
RUN cargo build --release

FROM alpine:3.14
RUN apk add --no-cache libgcc wget
COPY --from=builder /usr/src/askeladd/target/release/prover_agent /usr/local/bin/prover_agent
COPY --from=builder /usr/src/askeladd/target/release/user_cli /usr/local/bin/user_cli
COPY --from=builder /usr/src/askeladd/config /config
COPY --from=builder /usr/src/askeladd/.env.docker /.env
WORKDIR /usr/src/askeladd
ENV RUST_LOG=info
CMD ["prover_agent"]
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ As Zero-Knowledge-Proof technology keeps evolving rapidly, it's clear that there

> **Disclaimer:** Askeladd is only a proof of concept and should not be used in a production environment. It's a work in progress as a showcase of the STWO prover and the Nostr protocol.
Check out this video demonstration of Askeladd in action:

<https://github.com/AbdelStark/askeladd/assets/AbdelStark/docs/img/askeladd-demo.mp4>

## Architecture

![Askeladd Architecture](./docs/img/askeladd-architecture.png)
Expand All @@ -27,9 +31,21 @@ Typical flow:
3. The proof is published to the Nostr network
4. The user can verify the proof using the Askeladd verifier agent

## Getting Started
## Running the demo

### Using docker-compose

```bash
./run_demo.sh
```

### Manually

Create a `.env` file, you can use the `.env.example` file as a reference.

### Running the demo
```bash
cp .env.example .env
```

In terminal 1, run the nostr relay:

Expand Down
5 changes: 5 additions & 0 deletions config/default.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
subscribed_relays = ["ws://127.0.0.1:8080"]
proving_req_sub_id = "askeladd.proving.request"
proving_resp_sub_id = "askeladd.proving.response"
user_bech32_sk = "nsec1tsaxyqcxp8atqup4facwp0as52f2c0evj4cxpw6yaqetusu7sg8qqzkr3k"
prover_agent_sk = "nsec18s6wcqlkglhjmfz3tnjkh0qscf6cqen96ecp5k5k73ktew3l97tstuvy2x"
2 changes: 2 additions & 0 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ tokio = { version = "1", default-features = false }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
uuid = { version = "1.3", features = ["v4"] }
config = "0.14.0"
dotenv = "0.15"

[[bin]]
name = "user_cli"
Expand Down
18 changes: 11 additions & 7 deletions crates/cli/src/prover_agent.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
use askeladd_core::data_fixture::{self, PROVING_REQ_SUB_ID, SUBSCRIBED_RELAYS};
use askeladd_core::config::Settings;
use askeladd_core::prover_service::ProverService;
use askeladd_core::types::FibonnacciProvingRequest;
use dotenv::dotenv;
use nostr_sdk::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
let user_secret_key = SecretKey::from_bech32(data_fixture::USER_BECH32_SK)?;
// Load configuration from .env file
dotenv().ok();
let settings = Settings::new().expect("Failed to load settings");

let user_secret_key = SecretKey::from_bech32(&settings.user_bech32_sk)?;
let user_keys = Keys::new(user_secret_key);
let user_public_key = user_keys.public_key();

let prover_agent_keys =
Keys::new(SecretKey::from_bech32(data_fixture::PROVER_AGENT_SK).unwrap());
let prover_agent_keys = Keys::new(SecretKey::from_bech32(&settings.prover_agent_sk).unwrap());

let opts = Options::new().wait_for_send(false);
let client = Client::with_opts(&prover_agent_keys, opts);

for relay in SUBSCRIBED_RELAYS {
client.add_relay(Url::parse(relay).unwrap()).await?;
for relay in settings.subscribed_relays {
client.add_relay(&relay).await?;
}

client.connect().await;
println!("Client connected to relays.");

let proving_req_sub_id = SubscriptionId::new(PROVING_REQ_SUB_ID);
let proving_req_sub_id = SubscriptionId::new(settings.proving_req_sub_id);
let filter = Filter::new().kind(Kind::TextNote).author(user_public_key);

client
Expand Down
27 changes: 19 additions & 8 deletions crates/cli/src/user_cli.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
use askeladd_core::data_fixture::{self, PROVING_RESP_SUB_ID, SUBSCRIBED_RELAYS};
use askeladd_core::config::Settings;
use askeladd_core::types::{FibonnacciProvingRequest, FibonnacciProvingResponse};
use askeladd_core::verifier_service::VerifierService;
use dotenv::dotenv;
use nostr_sdk::prelude::*;
use tokio::time::{sleep, Duration};
use uuid::Uuid;

#[tokio::main]
async fn main() -> Result<()> {
let prover_agent_secret_key = SecretKey::from_bech32(data_fixture::PROVER_AGENT_SK)?;
println!("User agent starting...");
println!("Waiting 5 seconds before submitting proving request...");
// Add a delay before connecting
sleep(Duration::from_secs(5)).await;

// Load configuration from .env file
dotenv().ok();
let settings = Settings::new().expect("Failed to load settings");

let prover_agent_secret_key = SecretKey::from_bech32(&settings.prover_agent_sk)?;
let prover_agent_keys = Keys::new(prover_agent_secret_key);
let prover_agent_public_key = prover_agent_keys.public_key();
let user_keys = Keys::new(SecretKey::from_bech32(data_fixture::USER_BECH32_SK).unwrap());
let user_keys = Keys::new(SecretKey::from_bech32(&settings.user_bech32_sk).unwrap());

let opts = Options::new().wait_for_send(false);
let client = Client::with_opts(&user_keys, opts);

for relay in SUBSCRIBED_RELAYS {
client.add_relay(Url::parse(relay).unwrap()).await?;
for relay in settings.subscribed_relays {
client.add_relay(&relay).await?;
}

client.connect().await;
Expand All @@ -41,7 +52,7 @@ async fn main() -> Result<()> {
println!("Proving request published with event ID: {}", event_id);

// Subscribe to proving responses
let proving_resp_sub_id = SubscriptionId::new(PROVING_RESP_SUB_ID);
let proving_resp_sub_id = SubscriptionId::new(settings.proving_resp_sub_id);
let filter = Filter::new()
.kind(Kind::TextNote)
.author(prover_agent_public_key)
Expand Down Expand Up @@ -74,8 +85,8 @@ async fn main() -> Result<()> {
Ok(_) => println!("Proof successfully verified"),
Err(e) => println!("Proof verification failed: {}", e),
}
return Ok(true); // Stop listening after receiving and verifying the
// response
// Stop listening after receiving and verifying the response
return Ok(true);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ stwo-prover.workspace = true
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0.62"
config = "0.14.0"
dotenv = "0.15"
56 changes: 56 additions & 0 deletions crates/core/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::env;

use config::{Config, ConfigError, Environment, File};
use serde::Deserialize;

#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum StringOrVec {
String(String),
Vec(Vec<String>),
}

#[derive(Debug, Deserialize)]
pub struct Settings {
#[serde(deserialize_with = "deserialize_subscribed_relays")]
pub subscribed_relays: Vec<String>,
pub proving_req_sub_id: String,
pub proving_resp_sub_id: String,
pub user_bech32_sk: String,
pub prover_agent_sk: String,
}

fn deserialize_subscribed_relays<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = StringOrVec::deserialize(deserializer)?;
Ok(match value {
StringOrVec::String(s) => vec![s],
StringOrVec::Vec(v) => v,
})
}

impl Settings {
pub fn new() -> Result<Self, ConfigError> {
let run_mode = env::var("RUN_MODE").unwrap_or_else(|_| "development".into());

let s = Config::builder()
// Start off by merging in the "default" configuration file
.add_source(File::with_name("config/default"))
// Add in the current environment file
// Default to 'development' env
// Note that this file is _optional_
.add_source(File::with_name(&format!("config/{}", run_mode)).required(false))
// Add in a local configuration file
// This file shouldn't be checked in to git
.add_source(File::with_name("config/local").required(false))
// Add in settings from the environment (with a prefix of APP)
// Eg.. `APP_DEBUG=1 ./target/app` would set the `debug` key
.add_source(Environment::with_prefix("APP"))
.build()?;

// You can deserialize (and thus freeze) the entire configuration as
s.try_deserialize()
}
}
7 changes: 0 additions & 7 deletions crates/core/src/data_fixture.rs

This file was deleted.

2 changes: 1 addition & 1 deletion crates/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod data_fixture;
pub mod config;
pub mod prover_service;
pub mod types;
pub mod verifier_service;
37 changes: 37 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
version: "3.8"

services:
nostr-relay:
image: scsibug/nostr-rs-relay:latest
ports:
- "8080:8080"

prover-agent:
build:
context: .
dockerfile: Dockerfile
command: prover_agent
env_file: .env
volumes:
- ./config:/usr/src/askeladd/config
depends_on:
nostr-relay:
condition: service_started
environment:
- APP_SUBSCRIBED_RELAYS=ws://nostr-relay:8080

user-cli:
build:
context: .
dockerfile: Dockerfile
command: user_cli
env_file: .env
volumes:
- ./config:/usr/src/askeladd/config
depends_on:
nostr-relay:
condition: service_started
prover-agent:
condition: service_started
environment:
- APP_SUBSCRIBED_RELAYS=ws://nostr-relay:8080
Binary file added docs/img/askeladd-demo.mp4
Binary file not shown.
41 changes: 41 additions & 0 deletions run_demo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

# Function to stop all containers and exit
cleanup() {
echo "Stopping all containers..."
docker-compose down
exit 0
}

# Trap Ctrl+C and call cleanup
trap cleanup INT

# Ensure we're in the correct directory
cd "$(dirname "$0")"

# Build and start the containers
#docker-compose up --build -d
docker-compose up -d

# Wait for services to be ready
echo "Waiting for services to be ready..."
docker-compose run --rm user-cli /bin/sh -c "until wget -q --spider http://nostr-relay:8080; do sleep 1; done"

# Function to display logs with a specific color
show_logs() {
local container_name=$1
local color=$2
docker-compose logs -f "$container_name" | sed "s/^/$(tput setaf $color)[$container_name] /"
}

# Run log displays in the background
show_logs nostr-relay 1 &
show_logs prover-agent 2 &
show_logs user-cli 3 &

# Wait for user input to stop
echo "Demo is running. Press Enter to stop..."
read

# Cleanup and exit
cleanup

0 comments on commit 0d9a249

Please sign in to comment.