Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- `sncast get nonce` command to get the nonce of a contract.
- `sncast get tx` command to get transaction details by hash.
- `sncast utils selector` command to calculate entrypoint selector (sn_keccak) from function name.

### Forge

Expand Down
1 change: 1 addition & 0 deletions crates/sncast/src/response/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod class_hash;
pub mod selector;
pub mod serialize;
18 changes: 18 additions & 0 deletions crates/sncast/src/response/utils/selector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use crate::response::cast_message::SncastCommandMessage;
use conversions::padded_felt::PaddedFelt;
use conversions::string::IntoPaddedHexStr;
use foundry_ui::styling;
use serde::{Deserialize, Serialize};

#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
pub struct SelectorResponse {
pub selector: PaddedFelt,
}

impl SncastCommandMessage for SelectorResponse {
fn text(&self) -> String {
styling::OutputBuilder::new()
.field("Selector", &self.selector.into_padded_hex_str())
.build()
}
}
11 changes: 10 additions & 1 deletion crates/sncast/src/starknet_commands/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ use crate::{
process_command_result,
starknet_commands::{
self,
utils::{class_hash::ClassHash, serialize::Serialize},
utils::{class_hash::ClassHash, selector::Selector, serialize::Serialize},
},
};

pub mod class_hash;
pub mod felt_or_id;
pub mod selector;
pub mod serialize;

#[derive(Args)]
Expand All @@ -36,6 +37,9 @@ pub enum Commands {

/// Get contract class hash
ClassHash(ClassHash),

/// Calculate selector from name
Selector(Selector),
}

pub async fn utils(
Expand Down Expand Up @@ -76,6 +80,11 @@ pub async fn utils(

process_command_result("class-hash", Ok(result), ui, None);
}

Commands::Selector(sel) => {
let result = selector::get_selector(&sel).map_err(handle_starknet_command_error)?;
process_command_result("selector", Ok(result), ui, None);
}
}

Ok(())
Expand Down
30 changes: 30 additions & 0 deletions crates/sncast/src/starknet_commands/utils/selector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use anyhow::anyhow;
use clap::Args;
use conversions::IntoConv;
use sncast::response::{errors::StarknetCommandError, utils::selector::SelectorResponse};
use starknet_rust::core::utils::get_selector_from_name;

#[derive(Args, Debug)]
#[command(about = "Calculate entrypoint selector from function name", long_about = None)]
pub struct Selector {
/// Function name
pub name: String,
}

#[allow(clippy::result_large_err)]
pub fn get_selector(selector: &Selector) -> Result<SelectorResponse, StarknetCommandError> {
let trimmed = selector.name.trim();

if trimmed.contains('(') || trimmed.contains(')') {
return Err(StarknetCommandError::UnknownError(anyhow!(
"Parentheses and the content within should not be supplied"
)));
}

let felt = get_selector_from_name(trimmed)
.map_err(|e| StarknetCommandError::UnknownError(anyhow::Error::from(e)))?;

Ok(SelectorResponse {
selector: felt.into_(),
})
}
1 change: 1 addition & 0 deletions crates/sncast/tests/e2e/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod main_tests;
mod multicall;
mod nonce;
mod script;
mod selector;
mod serialize;
mod show_config;
mod transaction;
Expand Down
47 changes: 47 additions & 0 deletions crates/sncast/tests/e2e/selector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::helpers::runner::runner;
use indoc::indoc;
use shared::test_utils::output_assert::{assert_stderr_contains, assert_stdout_contains};

#[test]
fn test_selector_happy_case() {
let args = vec!["utils", "selector", "transfer"];
let snapbox = runner(&args);
let output = snapbox.assert().success();

assert_stdout_contains(
output,
indoc! {r"
Selector: 0x0083afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e
"},
);
}

#[test]
fn test_selector_json_output() {
let args = vec!["--json", "utils", "selector", "transfer"];
let snapbox = runner(&args);
let output = snapbox.assert().success();
let stdout = output.get_output().stdout.clone();

let json: serde_json::Value = serde_json::from_slice(&stdout).unwrap();
assert_eq!(json["command"], "selector");
assert_eq!(json["type"], "response");
assert_eq!(
json["selector"],
"0x0083afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e"
);
}

#[test]
fn test_selector_with_parentheses() {
let args = vec!["utils", "selector", "transfer(u256)"];
let snapbox = runner(&args);
let output = snapbox.assert().failure();

assert_stderr_contains(
output,
indoc! {r"
Error: Parentheses and the content within should not be supplied
"},
);
}
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
* [utils](appendix/sncast/utils/utils.md)
* [serialize](appendix/sncast/utils/serialize.md)
* [class-hash](appendix/sncast/utils/class_hash.md)
* [selector](appendix/sncast/utils/selector.md)
* [`sncast` Library Reference](appendix/sncast-library.md)
* [declare](appendix/sncast-library/declare.md)
* [deploy](appendix/sncast-library/deploy.md)
Expand Down
1 change: 1 addition & 0 deletions docs/src/appendix/sncast.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
* [utils](./sncast/utils/utils.md)
* [serialize](./sncast/utils/serialize.md)
* [class-hash](./sncast/utils/class_hash.md)
* [selector](./sncast/utils/selector.md)
* [verify](./sncast/verify.md)
* [completions](./sncast/completions.md)
22 changes: 22 additions & 0 deletions docs/src/appendix/sncast/utils/selector.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# `selector`
Calculate entrypoint selector from function name.

## `<NAME>`
Required.

The function name (e.g. `transfer`, `balance_of`). Do not include parentheses or parameter types.

## Example

```shell
$ sncast utils selector transfer
```

<details>
<summary>Output:</summary>

```shell
Selector: 0x0[..]
```
</details>
<br>
1 change: 1 addition & 0 deletions docs/src/appendix/sncast/utils/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ Provides a set of utility commands.
It has the following subcommands:
* [`serialize`](./serialize.md)
* [`class-hash`](./class_hash.md)
* [`selector`](./selector.md)
Loading