-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
1,911 additions
and
747 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
[package] | ||
name = "toolkit" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
semaphore = { git = "https://github.com/worldcoin/semaphore-rs", rev = "d0d1f899add7116ccc1228f5e5e5ee2e2e233768", features = [ | ||
"depth_30", | ||
] } | ||
world-chain-builder = { path = "../.." } | ||
|
||
# Alloy | ||
alloy-consensus = "0.3" | ||
alloy-network = "0.3" | ||
alloy-primitives = "0.8" | ||
alloy-rlp = "0.3" | ||
|
||
# 3rd party | ||
bytes = "1.7.2" | ||
clap = { version = "4", features = ["derive", "env"] } | ||
eyre = { version = "0.6", package = "color-eyre" } | ||
hex = "0.4.3" | ||
serde = { version = "1", features = ["derive"] } | ||
serde_json = "1.0" | ||
tokio = { version = "1", features = ["full"] } | ||
dotenvy = "0.15.7" | ||
chrono = "0.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use bytes::{Bytes, BytesMut}; | ||
use chrono::NaiveDate; | ||
use clap::Parser; | ||
use identity_source::IdentitySource; | ||
use inclusion_proof_source::InclusionProofSource; | ||
|
||
pub mod identity_source; | ||
pub mod inclusion_proof_source; | ||
mod utils; | ||
|
||
#[derive(Debug, Clone, Parser)] | ||
pub struct Opt { | ||
#[clap(subcommand)] | ||
pub cmd: Cmd, | ||
} | ||
|
||
#[derive(Debug, Clone, Parser)] | ||
pub enum Cmd { | ||
Prove(ProveArgs), | ||
|
||
Send(SendArgs), | ||
} | ||
|
||
#[derive(Debug, Clone, Parser)] | ||
pub struct ProveArgs { | ||
/// Raw tx | ||
/// | ||
/// can be constructed with `cast mktx` | ||
#[clap(short, long)] | ||
#[clap(value_parser = utils::bytes_parse_hex)] | ||
pub tx: Bytes, | ||
|
||
/// The PBH nonce for the priority tx | ||
/// | ||
/// should be in range 0-30 otherwise the tx will be discarded as invalid | ||
#[clap(short = 'N', long)] | ||
#[clap(alias = "nonce")] | ||
pub pbh_nonce: u16, | ||
|
||
/// Overrides the current date for PBH proof generation | ||
/// Format: "YYYY-MM-DD" | ||
/// | ||
/// Dates are always assumed to be in UTC | ||
#[clap(short = 'D', long)] | ||
pub custom_date: Option<NaiveDate>, | ||
|
||
#[command(flatten)] | ||
pub identity_source: IdentitySource, | ||
|
||
#[command(flatten)] | ||
pub inclusion_proof_source: InclusionProofSource, | ||
} | ||
|
||
#[derive(Debug, Clone, Parser)] | ||
pub struct SendArgs {} |
43 changes: 43 additions & 0 deletions
43
world-chain-builder/crates/toolkit/src/cli/identity_source.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
use std::path::PathBuf; | ||
|
||
use bytes::BytesMut; | ||
use clap::Args; | ||
use semaphore::identity::Identity; | ||
|
||
use super::utils::bytes_mut_parse_hex; | ||
|
||
#[derive(Debug, Clone, Args)] | ||
pub struct IdentitySource { | ||
/// Hex encoded identity secret | ||
#[clap( | ||
short = 'I', | ||
long, | ||
conflicts_with = "identity_file", | ||
required_unless_present = "identity_file", | ||
value_parser = bytes_mut_parse_hex | ||
)] | ||
pub identity: Option<BytesMut>, | ||
|
||
/// Path to a file containing the identity secret | ||
#[clap( | ||
long, | ||
conflicts_with = "identity", | ||
required_unless_present = "identity" | ||
)] | ||
pub identity_file: Option<PathBuf>, | ||
} | ||
|
||
impl IdentitySource { | ||
pub fn load(&self) -> Identity { | ||
if let Some(mut identity) = self.identity.clone() { | ||
return Identity::from_secret(identity.as_mut(), None); | ||
} | ||
|
||
if let Some(identity_file) = &self.identity_file { | ||
let mut identity = std::fs::read(identity_file).unwrap(); | ||
return Identity::from_secret(identity.as_mut(), None); | ||
} | ||
|
||
unreachable!() | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
world-chain-builder/crates/toolkit/src/cli/inclusion_proof_source.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use std::path::PathBuf; | ||
|
||
use clap::Args; | ||
use semaphore::poseidon_tree::Proof; | ||
|
||
use super::utils::parse_from_json; | ||
|
||
#[derive(Debug, Clone, Args)] | ||
pub struct InclusionProofSource { | ||
/// Inclusion proof in JSON format | ||
#[clap( | ||
short = 'P', | ||
long, | ||
value_parser = parse_from_json::<Proof>, | ||
conflicts_with = "inclusion_proof_file", | ||
required_unless_present = "inclusion_proof_file" | ||
)] | ||
pub inclusion_proof: Option<Proof>, | ||
|
||
#[clap( | ||
long, | ||
conflicts_with = "inclusion_proof", | ||
required_unless_present = "inclusion_proof" | ||
)] | ||
pub inclusion_proof_file: Option<PathBuf>, | ||
|
||
// TODO: Add fetching from signup-sequencer/world-tree | ||
// TODO: Add fetching from smart contract via RPC | ||
} | ||
|
||
impl InclusionProofSource { | ||
pub fn load(&self) -> Proof { | ||
if let Some(inclusion_proof) = self.inclusion_proof.clone() { | ||
return inclusion_proof; | ||
} | ||
|
||
if let Some(inclusion_proof_file) = &self.inclusion_proof_file { | ||
let inclusion_proof = std::fs::read(inclusion_proof_file).unwrap(); | ||
return serde_json::from_slice(&inclusion_proof).unwrap(); | ||
} | ||
|
||
unreachable!() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use bytes::{Bytes, BytesMut}; | ||
use serde::de::DeserializeOwned; | ||
|
||
pub fn bytes_mut_parse_hex(s: &str) -> eyre::Result<BytesMut> { | ||
Ok(BytesMut::from( | ||
&hex::decode(s.trim_start_matches("0x"))?[..], | ||
)) | ||
} | ||
|
||
pub fn bytes_parse_hex(s: &str) -> eyre::Result<Bytes> { | ||
Ok(Bytes::from( | ||
hex::decode(s.trim_start_matches("0x"))?, | ||
)) | ||
} | ||
|
||
pub fn parse_from_json<'a, T>(s: &'a str) -> eyre::Result<T> | ||
where | ||
T: DeserializeOwned, | ||
{ | ||
Ok(serde_json::from_str(s)?) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use alloy_consensus::TxEnvelope; | ||
use alloy_rlp::Decodable; | ||
use clap::Parser; | ||
use cli::{Cmd, Opt}; | ||
use semaphore::hash_to_field; | ||
use world_chain_builder::date_marker::DateMarker; | ||
use world_chain_builder::external_nullifier::ExternalNullifier; | ||
|
||
mod cli; | ||
|
||
#[tokio::main] | ||
async fn main() -> eyre::Result<()> { | ||
dotenvy::dotenv().ok(); | ||
|
||
let args = Opt::parse(); | ||
println!("{:#?}", args); | ||
|
||
match args.cmd { | ||
Cmd::Prove(prove_args) => { | ||
let tx: TxEnvelope = TxEnvelope::decode(&mut prove_args.tx.as_ref())?; | ||
|
||
let tx_hash = tx.tx_hash(); | ||
let signal_hash = hash_to_field(tx_hash.as_ref()); | ||
|
||
let identity = prove_args.identity_source.load(); | ||
let merkle_proof = prove_args.inclusion_proof_source.load(); | ||
|
||
let date = prove_args | ||
.custom_date | ||
.unwrap_or_else(|| chrono::Utc::now().naive_utc().date()); | ||
|
||
let month = DateMarker::from(date); | ||
|
||
let external_nullifier = ExternalNullifier::new(month, prove_args.pbh_nonce); | ||
let external_nullifier_hash = external_nullifier.hash(); | ||
|
||
let semaphore_proof = semaphore::protocol::generate_proof( | ||
&identity, | ||
&merkle_proof, | ||
external_nullifier_hash, | ||
signal_hash, | ||
)?; | ||
} | ||
_ => unimplemented!(), | ||
} | ||
|
||
Ok(()) | ||
} |
Oops, something went wrong.