Skip to content
Merged
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
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ target/
.vscode/

mina-frost-client/tests/assets/
mina-frost-client/tests/assets-duplicate/

# GraphQL schemas
*.graphql

# AI generated folders
# AI generated folders and files
.claude/
.codex

# Playground
playground/
38 changes: 19 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions SIGNING-WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This guide walks you through signing Mina transactions using FROST threshold sig
| Join DKG (participant) | `mina-frost-client dkg -d <DESC> -s <SERVER_URL> -t <THRESHOLD> -c <CONFIG_PATH>` |
| List groups | `mina-frost-client groups -c <CONFIG_PATH>` |
| Coordinate signing | `mina-frost-client coordinator -g <GROUP_PUBKEY> -S <SIGNER_PUBKEYS> -m <TX_FILE> -o <SIG_OUT> -n <NETWORK> -c <CONFIG_PATH>` |
| Join signing | `mina-frost-client participant -g <GROUP_PUBKEY> -c <CONFIG_PATH>` |
| Join signing | `mina-frost-client participant -g <GROUP_PUBKEY> -S <SESSION_ID> -c <CONFIG_PATH>` |
| Build GraphQL | `mina-frost-client graphql-build -i <INPUT_JSON> -o <OUTPUT_FILE>` |
| Broadcast | `mina-frost-client graphql-broadcast -g <GRAPHQL_FILE> -e <ENDPOINT_URL>` |

Expand Down Expand Up @@ -601,7 +601,7 @@ mina-frost-client participant \
| `-c` | Path to participant's config file |
| `-s` | Server URL (optional if stored in group config) |
| `-g` | Group public key |
| `-S` | Session ID (optional if only one active session) |
| `-S` | Session ID (use `sessions` command to list if coordinator output was lost) |
| `-y` | Auto-approve signing (skip confirmation prompt) |

**Example:**
Expand All @@ -611,13 +611,15 @@ mina-frost-client participant \
-c ~/.frost/bob.toml \
-s localhost:2744 \
-g <GROUP_PUBLIC_KEY> \
-S <SESSION_ID> \
-y

# Eve joins
mina-frost-client participant \
-c ~/.frost/eve.toml \
-s localhost:2744 \
-g <GROUP_PUBLIC_KEY> \
-S <SESSION_ID> \
-y
```

Expand Down
31 changes: 25 additions & 6 deletions mina-frost-client/examples/signing_example/signing_example.sh
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,41 @@ use_frost_client coordinator \
-o "$GENERATED_DIR/signature.json" &
COORDINATOR_PID=$!

# Give coordinator time to create the signing session
# Wait for the coordinator to create the signing session and get its ID
echo "Waiting for coordinator to create signing session..."
sleep 5
SESSION_ID=""
for _i in $(seq 1 20); do
SESSION_ID=$(use_frost_client sessions \
-c "$GENERATED_DIR/alice.toml" \
--server-url "$SERVER_URL" \
--group "$GROUP_PUBLIC_KEY" 2>&1 \
| sed -n 's/^Session with ID //p' | head -n1)
[ -n "$SESSION_ID" ] && break
sleep 0.5
done

if [ -z "$SESSION_ID" ]; then
echo "ERROR: Could not get session ID from coordinator"
exit 1
fi
echo "Session ID: $SESSION_ID"

echo "Starting participant (Bob)..."
echo "y" | use_frost_client participant \
use_frost_client participant \
-c "$GENERATED_DIR/bob.toml" \
--server-url "$SERVER_URL" \
--group "$GROUP_PUBLIC_KEY" &
--group "$GROUP_PUBLIC_KEY" \
--session "$SESSION_ID" \
-y &
BOB_PID=$!

echo "Starting participant (Eve)..."
echo "y" | use_frost_client participant \
use_frost_client participant \
-c "$GENERATED_DIR/eve.toml" \
--server-url "$SERVER_URL" \
--group "$GROUP_PUBLIC_KEY" &
--group "$GROUP_PUBLIC_KEY" \
--session "$SESSION_ID" \
-y &
EVE_PID=$!

# Wait for completion
Expand Down
6 changes: 6 additions & 0 deletions mina-frost-client/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ impl std::fmt::Debug for PublicKey {
}
}

impl std::fmt::Display for PublicKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", hex::encode(&self.0))
}
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SendArgs {
pub session_id: Uuid,
Expand Down
5 changes: 2 additions & 3 deletions mina-frost-client/src/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,9 @@ pub enum Command {
/// to list)
#[arg(short, long)]
group: String,
/// The session ID to use (use `sessions` to list). Can be omitted in
/// case there is a single active session.
/// The session ID to use (use `sessions` to list).
#[arg(short = 'S', long)]
session: Option<String>,
session: String,
/// Automatically answer yes to signing any package.
#[arg(short = 'y', long, default_value_t = false)]
yes: bool,
Expand Down
6 changes: 3 additions & 3 deletions mina-frost-client/src/cli/participant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub async fn run_bluepallas(args: &Command) -> Result<(), Box<dyn Error>> {
&group_config,
key_package,
server_url,
session,
&session,
)?;

// Execute signing
Expand Down Expand Up @@ -84,7 +84,7 @@ fn setup_participant_config<C: Ciphersuite>(
group_config: &Group<C>,
key_package: KeyPackage<C>,
server_url: Option<String>,
session: Option<String>,
session: &str,
) -> Result<ParticipantConfig<C>, Box<dyn Error>> {
// Determine server URL
let server_url = if let Some(server_url) = server_url {
Expand Down Expand Up @@ -113,7 +113,7 @@ fn setup_participant_config<C: Ciphersuite>(
port: server_url_parsed
.port_or_known_default()
.expect("always works for https"),
session_id: session.unwrap_or_default(),
session_id: session.to_owned(),
comm_privkey: Some(
user_config
.communication_key
Expand Down
Loading