Skip to content

Commit 41a294b

Browse files
authored
Split verify command into sub directories (#2939)
Hey! I've took over the verifier portion at Nethermind voyager team. This supersedes the attempt at #2566 and it's prep pr for #2287. ## Introduced changes This PR *doesn't change anything*, but it moves files around into subdirectory so the follow up PR has more friendly diff. ## Checklist <!-- Make sure all of these are complete --> - [x] Linked relevant issue - [ ] Updated relevant documentation - [ ] Added relevant tests - [x] Performed self-review of the code - [ ] Added changes to `CHANGELOG.md`
1 parent 6c419a6 commit 41a294b

File tree

5 files changed

+119
-103
lines changed

5 files changed

+119
-103
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use anyhow::Result;
2+
use camino::Utf8PathBuf;
3+
use serde::Serialize;
4+
use sncast::{Network, response::structs::VerifyResponse};
5+
use starknet_types_core::felt::Felt;
6+
7+
#[derive(Serialize, Debug)]
8+
pub struct VerificationPayload {
9+
pub contract_name: String,
10+
pub contract_address: String,
11+
pub source_code: serde_json::Value,
12+
}
13+
14+
#[async_trait::async_trait]
15+
pub trait VerificationInterface {
16+
fn new(network: Network, workspace_dir: Utf8PathBuf) -> Self;
17+
async fn verify(&self, contract_address: Felt, contract_name: String)
18+
-> Result<VerifyResponse>;
19+
fn gen_explorer_url(&self) -> Result<String>;
20+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
use anyhow::{Result, anyhow, bail};
2+
use camino::Utf8PathBuf;
3+
use clap::{Args, ValueEnum};
4+
use promptly::prompt;
5+
use scarb_api::StarknetContractArtifacts;
6+
use sncast::{Network, response::structs::VerifyResponse};
7+
use starknet_types_core::felt::Felt;
8+
use std::{collections::HashMap, fmt};
9+
10+
pub mod explorer;
11+
pub mod walnut;
12+
13+
use explorer::VerificationInterface;
14+
use walnut::WalnutVerificationInterface;
15+
16+
#[derive(Args)]
17+
#[command(about = "Verify a contract through a block explorer")]
18+
pub struct Verify {
19+
/// Address of a contract to be verified
20+
#[clap(short = 'd', long)]
21+
pub contract_address: Felt,
22+
23+
/// Name of the contract that is being verified
24+
#[clap(short, long)]
25+
pub contract_name: String,
26+
27+
/// Block explorer to use for the verification
28+
#[clap(short, long, value_enum, default_value_t = Verifier::Walnut)]
29+
pub verifier: Verifier,
30+
31+
/// The network on which block explorer will do the verification
32+
#[clap(short, long, value_enum)]
33+
pub network: Network,
34+
35+
/// Assume "yes" as answer to confirmation prompt and run non-interactively
36+
#[clap(long, default_value = "false")]
37+
pub confirm_verification: bool,
38+
39+
/// Specifies scarb package to be used
40+
#[clap(long)]
41+
pub package: Option<String>,
42+
}
43+
44+
#[derive(ValueEnum, Clone, Debug)]
45+
pub enum Verifier {
46+
Walnut,
47+
}
48+
49+
impl fmt::Display for Verifier {
50+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51+
match *self {
52+
Verifier::Walnut => write!(f, "walnut"),
53+
}
54+
}
55+
}
56+
57+
pub async fn verify(
58+
contract_address: Felt,
59+
contract_name: String,
60+
verifier: Verifier,
61+
network: Network,
62+
confirm_verification: bool,
63+
manifest_path: &Utf8PathBuf,
64+
artifacts: &HashMap<String, StarknetContractArtifacts>,
65+
) -> Result<VerifyResponse> {
66+
// Let's ask confirmation
67+
if !confirm_verification {
68+
let prompt_text = format!(
69+
"\n\tYou are about to submit the entire workspace code to the third-party verifier at {verifier}.\n\n\tImportant: Make sure your project does not include sensitive information like private keys. The snfoundry.toml file will be uploaded. Keep the keystore outside the project to prevent it from being uploaded.\n\n\tAre you sure you want to proceed? (Y/n)"
70+
);
71+
let input: String = prompt(prompt_text)?;
72+
73+
if !input.starts_with('Y') {
74+
bail!("Verification aborted");
75+
}
76+
}
77+
78+
if !artifacts.contains_key(&contract_name) {
79+
return Err(anyhow!("Contract named '{contract_name}' was not found"));
80+
}
81+
82+
// Build JSON Payload for the verification request
83+
// get the parent dir of the manifest path
84+
let workspace_dir = manifest_path
85+
.parent()
86+
.ok_or(anyhow!("Failed to obtain workspace dir"))?;
87+
88+
match verifier {
89+
Verifier::Walnut => {
90+
let walnut = WalnutVerificationInterface::new(network, workspace_dir.to_path_buf());
91+
walnut.verify(contract_address, contract_name).await
92+
}
93+
}
94+
}
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,20 @@
11
use anyhow::{Context, Result, anyhow};
2-
use anyhow::{Ok, bail};
32
use camino::Utf8PathBuf;
4-
use clap::{Args, ValueEnum};
5-
use promptly::prompt;
63
use reqwest::StatusCode;
7-
use scarb_api::StarknetContractArtifacts;
8-
use serde::Serialize;
94
use sncast::Network;
105
use sncast::response::structs::VerifyResponse;
116
use starknet_types_core::felt::Felt;
12-
use std::collections::HashMap;
7+
use std::env;
138
use std::ffi::OsStr;
14-
use std::{env, fmt};
159
use walkdir::WalkDir;
1610

17-
struct WalnutVerificationInterface {
11+
use super::explorer::{VerificationInterface, VerificationPayload};
12+
13+
pub struct WalnutVerificationInterface {
1814
network: Network,
1915
workspace_dir: Utf8PathBuf,
2016
}
2117

22-
#[async_trait::async_trait]
23-
trait VerificationInterface {
24-
fn new(network: Network, workspace_dir: Utf8PathBuf) -> Self;
25-
async fn verify(&self, contract_address: Felt, contract_name: String)
26-
-> Result<VerifyResponse>;
27-
fn gen_explorer_url(&self) -> Result<String>;
28-
}
29-
3018
#[async_trait::async_trait]
3119
impl VerificationInterface for WalnutVerificationInterface {
3220
fn new(network: Network, workspace_dir: Utf8PathBuf) -> Self {
@@ -109,90 +97,3 @@ impl VerificationInterface for WalnutVerificationInterface {
10997
Ok(format!("{api_base_url}{path}"))
11098
}
11199
}
112-
113-
#[derive(Args)]
114-
#[command(about = "Verify a contract through a block explorer")]
115-
pub struct Verify {
116-
/// Address of a contract to be verified
117-
#[clap(short = 'd', long)]
118-
pub contract_address: Felt,
119-
120-
/// Name of the contract that is being verified
121-
#[clap(short, long)]
122-
pub contract_name: String,
123-
124-
/// Block explorer to use for the verification
125-
#[clap(short, long, value_enum, default_value_t = Verifier::Walnut)]
126-
pub verifier: Verifier,
127-
128-
/// The network on which block explorer will do the verification
129-
#[clap(short, long, value_enum)]
130-
pub network: Network,
131-
132-
/// Assume "yes" as answer to confirmation prompt and run non-interactively
133-
#[clap(long, default_value = "false")]
134-
pub confirm_verification: bool,
135-
136-
/// Specifies scarb package to be used
137-
#[clap(long)]
138-
pub package: Option<String>,
139-
}
140-
141-
#[derive(ValueEnum, Clone, Debug)]
142-
pub enum Verifier {
143-
Walnut,
144-
}
145-
146-
impl fmt::Display for Verifier {
147-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
148-
match *self {
149-
Verifier::Walnut => write!(f, "walnut"),
150-
}
151-
}
152-
}
153-
154-
#[derive(Serialize, Debug)]
155-
struct VerificationPayload {
156-
contract_name: String,
157-
contract_address: String,
158-
source_code: serde_json::Value,
159-
}
160-
161-
pub async fn verify(
162-
contract_address: Felt,
163-
contract_name: String,
164-
verifier: Verifier,
165-
network: Network,
166-
confirm_verification: bool,
167-
manifest_path: &Utf8PathBuf,
168-
artifacts: &HashMap<String, StarknetContractArtifacts>,
169-
) -> Result<VerifyResponse> {
170-
// Let's ask confirmation
171-
if !confirm_verification {
172-
let prompt_text = format!(
173-
"\n\tYou are about to submit the entire workspace code to the third-party verifier at {verifier}.\n\n\tImportant: Make sure your project does not include sensitive information like private keys. The snfoundry.toml file will be uploaded. Keep the keystore outside the project to prevent it from being uploaded.\n\n\tAre you sure you want to proceed? (Y/n)"
174-
);
175-
let input: String = prompt(prompt_text)?;
176-
177-
if !input.starts_with('Y') {
178-
bail!("Verification aborted");
179-
}
180-
}
181-
182-
if !artifacts.contains_key(&contract_name) {
183-
return Err(anyhow!("Contract named '{contract_name}' was not found"));
184-
}
185-
186-
// Build JSON Payload for the verification request
187-
// get the parent dir of the manifest path
188-
let workspace_dir = manifest_path
189-
.parent()
190-
.ok_or(anyhow!("Failed to obtain workspace dir"))?;
191-
192-
match verifier {
193-
Verifier::Walnut => {
194-
let walnut = WalnutVerificationInterface::new(network, workspace_dir.to_path_buf());
195-
walnut.verify(contract_address, contract_name).await
196-
}
197-
}
198-
}

crates/sncast/tests/e2e/verify/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mod walnut;

0 commit comments

Comments
 (0)