From 766d72bd754bf11201dbfec3daa85154b25694ca Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Fri, 10 Oct 2025 17:44:42 -0300 Subject: [PATCH] remove get programs --- common/src/rpc_primitives/requests.rs | 12 +++++++++++ common/src/sequencer_client/mod.rs | 27 ++++++++++++++++++++++-- nssa/src/lib.rs | 1 + sequencer_rpc/src/process.rs | 30 +++++++++++++++++++++++---- wallet/src/lib.rs | 30 ++++++++++++++++++++++++++- 5 files changed, 93 insertions(+), 7 deletions(-) diff --git a/common/src/rpc_primitives/requests.rs b/common/src/rpc_primitives/requests.rs index 94c2ddc..91596e6 100644 --- a/common/src/rpc_primitives/requests.rs +++ b/common/src/rpc_primitives/requests.rs @@ -1,8 +1,11 @@ +use std::collections::HashMap; + use crate::parse_request; use super::errors::RpcParseError; use super::parser::RpcRequest; use super::parser::parse_params; +use nssa_core::program::ProgramId; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -58,6 +61,9 @@ pub struct GetProofForCommitmentRequest { pub commitment: nssa_core::Commitment, } +#[derive(Serialize, Deserialize, Debug)] +pub struct GetProgramIdsRequest {} + parse_request!(HelloRequest); parse_request!(RegisterAccountRequest); parse_request!(SendTxRequest); @@ -70,6 +76,7 @@ parse_request!(GetTransactionByHashRequest); parse_request!(GetAccountsNoncesRequest); parse_request!(GetProofForCommitmentRequest); parse_request!(GetAccountRequest); +parse_request!(GetProgramIdsRequest); #[derive(Serialize, Deserialize, Debug)] pub struct HelloResponse { @@ -126,3 +133,8 @@ pub struct GetAccountResponse { pub struct GetProofForCommitmentResponse { pub membership_proof: Option, } + +#[derive(Serialize, Deserialize, Debug)] +pub struct GetProgramIdsResponse { + pub program_ids: HashMap, +} diff --git a/common/src/sequencer_client/mod.rs b/common/src/sequencer_client/mod.rs index 1aec903..2d1bc4c 100644 --- a/common/src/sequencer_client/mod.rs +++ b/common/src/sequencer_client/mod.rs @@ -1,16 +1,19 @@ +use std::collections::HashMap; + use super::rpc_primitives::requests::{ GetAccountBalanceRequest, GetAccountBalanceResponse, GetBlockDataRequest, GetBlockDataResponse, GetGenesisIdRequest, GetGenesisIdResponse, GetInitialTestnetAccountsRequest, }; use anyhow::Result; use json::{SendTxRequest, SendTxResponse, SequencerRpcRequest, SequencerRpcResponse}; +use nssa_core::program::ProgramId; use reqwest::Client; use serde_json::Value; use crate::rpc_primitives::requests::{ GetAccountRequest, GetAccountResponse, GetAccountsNoncesRequest, GetAccountsNoncesResponse, - GetProofForCommitmentRequest, GetProofForCommitmentResponse, GetTransactionByHashRequest, - GetTransactionByHashResponse, + GetProgramIdsRequest, GetProgramIdsResponse, GetProofForCommitmentRequest, + GetProofForCommitmentResponse, GetTransactionByHashRequest, GetTransactionByHashResponse, }; use crate::sequencer_client::json::AccountInitialData; use crate::transaction::{EncodedTransaction, NSSATransaction}; @@ -237,4 +240,24 @@ impl SequencerClient { Ok(resp_deser) } + + // Get Ids of the programs used by the node + pub async fn get_program_ids( + &self, + ) -> Result, SequencerClientError> { + let acc_req = GetProgramIdsRequest {}; + + let req = serde_json::to_value(acc_req).unwrap(); + + let resp = self + .call_method_with_payload("get_program_ids", req) + .await + .unwrap(); + + let resp_deser = serde_json::from_value::(resp) + .unwrap() + .program_ids; + + Ok(resp_deser) + } } diff --git a/nssa/src/lib.rs b/nssa/src/lib.rs index 21defa9..296cb2a 100644 --- a/nssa/src/lib.rs +++ b/nssa/src/lib.rs @@ -7,6 +7,7 @@ pub mod public_transaction; mod signature; mod state; +pub use program_methods::PRIVACY_PRESERVING_CIRCUIT_ID; pub use nssa_core::account::{Account, AccountId}; pub use nssa_core::address::Address; pub use privacy_preserving_transaction::{ diff --git a/sequencer_rpc/src/process.rs b/sequencer_rpc/src/process.rs index f376f94..d8c3c01 100644 --- a/sequencer_rpc/src/process.rs +++ b/sequencer_rpc/src/process.rs @@ -1,6 +1,8 @@ +use std::collections::HashMap; + use actix_web::Error as HttpError; use base64::{Engine, engine::general_purpose}; -use nssa; +use nssa::{self, program::Program}; use sequencer_core::config::AccountInitialData; use serde_json::Value; @@ -14,9 +16,9 @@ use common::{ requests::{ GetAccountBalanceRequest, GetAccountBalanceResponse, GetAccountRequest, GetAccountResponse, GetAccountsNoncesRequest, GetAccountsNoncesResponse, - GetInitialTestnetAccountsRequest, GetProofForCommitmentRequest, - GetProofForCommitmentResponse, GetTransactionByHashRequest, - GetTransactionByHashResponse, + GetInitialTestnetAccountsRequest, GetProgramIdsRequest, GetProgramIdsResponse, + GetProofForCommitmentRequest, GetProofForCommitmentResponse, + GetTransactionByHashRequest, GetTransactionByHashResponse, }, }, transaction::EncodedTransaction, @@ -40,6 +42,7 @@ pub const GET_TRANSACTION_BY_HASH: &str = "get_transaction_by_hash"; pub const GET_ACCOUNTS_NONCES: &str = "get_accounts_nonces"; pub const GET_ACCOUNT: &str = "get_account"; pub const GET_PROOF_FOR_COMMITMENT: &str = "get_proof_for_commitment"; +pub const GET_PROGRAM_IDS: &str = "get_program_ids"; pub const HELLO_FROM_SEQUENCER: &str = "HELLO_FROM_SEQUENCER"; @@ -267,6 +270,24 @@ impl JsonHandler { respond(helperstruct) } + async fn process_get_program_ids(&self, request: Request) -> Result { + let _get_proof_req = GetProgramIdsRequest::parse(Some(request.params))?; + + let mut program_ids = HashMap::new(); + program_ids.insert( + "authenticated_transfer".to_string(), + Program::authenticated_transfer_program().id(), + ); + program_ids.insert("token".to_string(), Program::token().id()); + program_ids.insert("pinata".to_string(), Program::pinata().id()); + program_ids.insert( + "privacy_preserving_circuit".to_string(), + nssa::PRIVACY_PRESERVING_CIRCUIT_ID, + ); + let helperstruct = GetProgramIdsResponse { program_ids }; + respond(helperstruct) + } + pub async fn process_request_internal(&self, request: Request) -> Result { match request.method.as_ref() { HELLO => self.process_temp_hello(request).await, @@ -280,6 +301,7 @@ impl JsonHandler { GET_ACCOUNT => self.process_get_account(request).await, GET_TRANSACTION_BY_HASH => self.process_get_transaction_by_hash(request).await, GET_PROOF_FOR_COMMITMENT => self.process_get_proof_by_commitment(request).await, + GET_PROGRAM_IDS => self.process_get_program_ids(request).await, _ => Err(RpcErr(RpcError::method_not_found(request.method))), } } diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 0e8b1cb..12505ff 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -11,7 +11,7 @@ use anyhow::Result; use chain_storage::WalletChainStore; use config::WalletConfig; use log::info; -use nssa::{Account, Address}; +use nssa::{program::Program, Account, Address}; use clap::{Parser, Subcommand}; use nssa_core::Commitment; @@ -377,6 +377,9 @@ pub enum Command { #[arg(long)] solution: u128, }, + // Check the wallet can connect to the node and builtin local programs + // match the remote versions + CheckHealth { } } ///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config @@ -845,6 +848,31 @@ pub async fn execute_subcommand(command: Command) -> Result { + let remote_program_ids = wallet_core.sequencer_client.get_program_ids().await.expect("Error fetching program ids"); + let Some(authenticated_transfer_id) = remote_program_ids.get("authenticated_transfer") else { + panic!("Missing authenticated transfer ID from remote"); + }; + if authenticated_transfer_id != &Program::authenticated_transfer_program().id() { + panic!("Local ID for authenticated transfer program is different from remote"); + } + let Some(token_id) = remote_program_ids.get("token") else { + panic!("Missing token program ID from remote"); + }; + if token_id != &Program::token().id() { + panic!("Local ID for token program is different from remote"); + } + let Some(circuit_id) = remote_program_ids.get("privacy_preserving_circuit") else { + panic!("Missing privacy preserving circuit ID from remote"); + }; + if circuit_id != &nssa::PRIVACY_PRESERVING_CIRCUIT_ID { + panic!("Local ID for privacy preserving circuit is different from remote"); + } + + println!("✅All looks good!"); + SubcommandReturnValue::Empty } };