feat: update commitment mechanism for new private account (#546)

* refactor(privacy_preserving_circuit): extract functions for readability

* feat: update commitment mechanism for new private accounts

Allow init accounts to optionally use a real membership proof for
DUMMY_COMMITMENT instead of hardcoding DUMMY_COMMITMENT_HASH as the
CommitmentSetDigest. The wallet fetches the proof from the sequencer
and passes it through the circuit.

* fix: address clippy lints and fix integration test visibility

* add tests

* refactor: removed duplicated code

* refactor: simplify init nullifier mechanism

Replace Option<MembershipProof> with Option<CommitmentSetDigest> on init
variants (PrivateAuthorizedInit, PrivateUnauthorized, PrivatePdaInit).
The circuit now receives the commitment tree root directly instead of
recomputing it from a Merkle proof.

* refactor: use CommitmentSetDigest directly instead of Option for init commitment root

Address PR #546 review feedback: the circuit now accepts CommitmentSetDigest
directly on init variants (PrivateAuthorizedInit, PrivateUnauthorized,
PrivatePdaInit), with callers providing DUMMY_COMMITMENT_HASH as the default.
Also fixes duplicate resolve_external_seed from rebase and rebuilds artifacts.
This commit is contained in:
jonesmarvin8 2026-07-01 09:03:29 -04:00 committed by Marvin Jones
parent ca36cf50b1
commit ca31bd7e46
20 changed files with 202 additions and 25 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -11,8 +11,10 @@ use lee::{
privacy_preserving_transaction::circuit::ProgramWithDependencies, program::Program,
};
use lee_core::{
EncryptedAccountData, InputAccountIdentity, NullifierPublicKey,
account::AccountWithMetadata,
DUMMY_COMMITMENT, DUMMY_COMMITMENT_HASH, EncryptedAccountData, InputAccountIdentity, Nullifier,
NullifierPublicKey,
account::{Account, AccountWithMetadata},
compute_digest_for_path,
encryption::{EphemeralPublicKey, ViewingPublicKey},
};
use log::info;
@ -710,6 +712,7 @@ async fn ppt_cant_chain_call_faucet() -> Result<()> {
npk,
ssk,
identifier: 1337,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
},
],
@ -720,3 +723,100 @@ async fn ppt_cant_chain_call_faucet() -> Result<()> {
Ok(())
}
async fn prove_init_with_commitment_root(
ctx: &TestContext,
commitment_root: lee_core::CommitmentSetDigest,
) -> Result<lee_core::PrivacyPreservingCircuitOutput> {
let program = programs::authenticated_transfer();
let sender_id = ctx.existing_public_accounts()[0];
let sender_pre = AccountWithMetadata::new(
ctx.sequencer_client().get_account(sender_id).await?,
true,
sender_id,
);
let nsk: lee_core::NullifierSecretKey = [7; 32];
let npk = NullifierPublicKey::from(&nsk);
let vpk = ViewingPublicKey::from_bytes(vec![4_u8; 1184]).unwrap();
let ssk = SharedSecretKey([55_u8; 32]);
let recipient_account_id = AccountId::for_regular_private_account(&npk, 0);
let recipient = AccountWithMetadata::new(Account::default(), false, recipient_account_id);
let (output, _) = execute_and_prove(
vec![sender_pre, recipient],
Program::serialize_instruction(authenticated_transfer_core::Instruction::Transfer {
amount: 1,
})?,
vec![
InputAccountIdentity::Public,
InputAccountIdentity::PrivateUnauthorized {
epk: EphemeralPublicKey(Vec::new()),
view_tag: EncryptedAccountData::compute_view_tag(&npk, &vpk),
npk,
ssk,
identifier: 0,
commitment_root,
},
],
&program.into(),
)?;
Ok(output)
}
#[test]
async fn init_with_dummy_commitment_root_produces_valid_root() -> Result<()> {
let ctx = TestContext::new().await?;
let dummy_proof = ctx
.sequencer_client()
.get_proof_for_commitment(DUMMY_COMMITMENT)
.await?
.expect("DUMMY_COMMITMENT must be in genesis commitment set");
let expected_digest = compute_digest_for_path(&DUMMY_COMMITMENT, &dummy_proof);
let nsk: lee_core::NullifierSecretKey = [7; 32];
let npk = NullifierPublicKey::from(&nsk);
let recipient_account_id = AccountId::for_regular_private_account(&npk, 0);
let output = prove_init_with_commitment_root(&ctx, expected_digest).await?;
assert_eq!(output.new_nullifiers.len(), 1);
let (nullifier, digest) = &output.new_nullifiers[0];
assert_eq!(
*nullifier,
Nullifier::for_account_initialization(&recipient_account_id)
);
assert_eq!(*digest, expected_digest);
assert_ne!(*digest, DUMMY_COMMITMENT_HASH);
Ok(())
}
#[test]
async fn init_nullifier_digest_is_bound_to_commitment_root() -> Result<()> {
let ctx = TestContext::new().await?;
let dummy_proof = ctx
.sequencer_client()
.get_proof_for_commitment(DUMMY_COMMITMENT)
.await?
.expect("DUMMY_COMMITMENT must be in genesis commitment set");
let expected_digest = compute_digest_for_path(&DUMMY_COMMITMENT, &dummy_proof);
let output_with_root = prove_init_with_commitment_root(&ctx, expected_digest).await?;
let output_without_root = prove_init_with_commitment_root(&ctx, DUMMY_COMMITMENT_HASH).await?;
assert_eq!(output_with_root.new_nullifiers[0].1, expected_digest);
assert_eq!(
output_without_root.new_nullifiers[0].1,
DUMMY_COMMITMENT_HASH
);
assert_ne!(
output_with_root.new_nullifiers[0].1,
output_without_root.new_nullifiers[0].1,
);
Ok(())
}

View File

@ -22,7 +22,7 @@ use lee::{
program::Program,
};
use lee_core::{
EncryptedAccountData, InputAccountIdentity, NullifierPublicKey,
DUMMY_COMMITMENT_HASH, EncryptedAccountData, InputAccountIdentity, NullifierPublicKey,
account::{Account, AccountWithMetadata},
encryption::ViewingPublicKey,
program::PdaSeed,
@ -78,6 +78,7 @@ async fn fund_private_pda(
npk,
ssk,
identifier,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: Some((seed, authority_program_id)),
},
];

View File

@ -23,7 +23,8 @@ use lee::{
public_transaction as putx,
};
use lee_core::{
EncryptedAccountData, InputAccountIdentity, MembershipProof, NullifierPublicKey,
DUMMY_COMMITMENT_HASH, EncryptedAccountData, InputAccountIdentity, MembershipProof,
NullifierPublicKey,
account::{AccountWithMetadata, Nonce, data::Data},
encryption::ViewingPublicKey,
};
@ -314,6 +315,7 @@ fn build_privacy_transaction() -> PrivacyPreservingTransaction {
npk: recipient_npk,
ssk: recipient_ss,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
},
],
&program.into(),

View File

@ -1,7 +1,7 @@
use lee_core::{
Commitment, CommitmentSetDigest, DUMMY_COMMITMENT_HASH, EncryptedAccountData, EncryptionScheme,
EphemeralPublicKey, InputAccountIdentity, MembershipProof, Nullifier, NullifierPublicKey,
NullifierSecretKey, PrivacyPreservingCircuitOutput, PrivateAccountKind, SharedSecretKey,
Commitment, CommitmentSetDigest, EncryptedAccountData, EncryptionScheme, EphemeralPublicKey,
InputAccountIdentity, MembershipProof, Nullifier, NullifierPublicKey, NullifierSecretKey,
PrivacyPreservingCircuitOutput, PrivateAccountKind, SharedSecretKey,
account::{Account, AccountId, Nonce},
compute_digest_for_path,
};
@ -20,7 +20,7 @@ struct PrivateOutputHandler<'ctx> {
}
impl PrivateOutputHandler<'_> {
fn authorized_init(self, nsk: &NullifierSecretKey) {
fn authorized_init(self, nsk: &NullifierSecretKey, commitment_root: &CommitmentSetDigest) {
let npk = NullifierPublicKey::from(nsk);
let account_id =
derive_and_verify_account_id(&npk, self.identifier, self.pre_state.account_id);
@ -35,7 +35,7 @@ impl PrivateOutputHandler<'_> {
"Found new private account with non default values"
);
let (new_nullifier, new_nonce) = init_nullifier_and_nonce(&account_id);
let (new_nullifier, new_nonce) = init_nullifier_and_nonce(&account_id, commitment_root);
let kind = PrivateAccountKind::Regular(self.identifier);
self.emit_private_output(&account_id, &kind, new_nullifier, new_nonce);
@ -67,7 +67,7 @@ impl PrivateOutputHandler<'_> {
self.emit_private_output(&account_id, &kind, new_nullifier, new_nonce);
}
fn unauthorized(self, npk: &NullifierPublicKey) {
fn unauthorized(self, npk: &NullifierPublicKey, commitment_root: &CommitmentSetDigest) {
let account_id =
derive_and_verify_account_id(npk, self.identifier, self.pre_state.account_id);
@ -81,7 +81,7 @@ impl PrivateOutputHandler<'_> {
"Found new private account marked as authorized."
);
let (new_nullifier, new_nonce) = init_nullifier_and_nonce(&account_id);
let (new_nullifier, new_nonce) = init_nullifier_and_nonce(&account_id, commitment_root);
let kind = PrivateAccountKind::Regular(self.identifier);
self.emit_private_output(&account_id, &kind, new_nullifier, new_nonce);
@ -89,6 +89,7 @@ impl PrivateOutputHandler<'_> {
fn pda_init(
self,
commitment_root: &CommitmentSetDigest,
pos: usize,
pda_seed_by_position: &std::collections::HashMap<
usize,
@ -108,7 +109,8 @@ impl PrivateOutputHandler<'_> {
"New private PDA must be default"
);
let (new_nullifier, new_nonce) = init_nullifier_and_nonce(&self.pre_state.account_id);
let (new_nullifier, new_nonce) =
init_nullifier_and_nonce(&self.pre_state.account_id, commitment_root);
let account_id = self.pre_state.account_id;
let (authority_program_id, seed) = pda_seed_by_position
@ -203,10 +205,13 @@ impl PrivateOutputHandler<'_> {
}
}
fn init_nullifier_and_nonce(account_id: &AccountId) -> ((Nullifier, CommitmentSetDigest), Nonce) {
fn init_nullifier_and_nonce(
account_id: &AccountId,
commitment_root: &CommitmentSetDigest,
) -> ((Nullifier, CommitmentSetDigest), Nonce) {
let nullifier = (
Nullifier::for_account_initialization(account_id),
DUMMY_COMMITMENT_HASH,
*commitment_root,
);
let nonce = Nonce::private_account_nonce_init(account_id);
(nullifier, nonce)
@ -271,6 +276,7 @@ pub fn compute_circuit_output(
ssk,
nsk,
identifier,
commitment_root,
} => PrivateOutputHandler {
output: &mut output,
output_index: &mut output_index,
@ -281,7 +287,7 @@ pub fn compute_circuit_output(
ssk,
identifier: *identifier,
}
.authorized_init(nsk),
.authorized_init(nsk, commitment_root),
InputAccountIdentity::PrivateAuthorizedUpdate {
epk,
view_tag,
@ -306,6 +312,7 @@ pub fn compute_circuit_output(
npk,
ssk,
identifier,
commitment_root,
} => PrivateOutputHandler {
output: &mut output,
output_index: &mut output_index,
@ -316,13 +323,14 @@ pub fn compute_circuit_output(
ssk,
identifier: *identifier,
}
.unauthorized(npk),
.unauthorized(npk, commitment_root),
InputAccountIdentity::PrivatePdaInit {
epk,
view_tag,
npk: _,
ssk,
identifier,
commitment_root,
seed: _,
} => PrivateOutputHandler {
output: &mut output,
@ -334,7 +342,7 @@ pub fn compute_circuit_output(
ssk,
identifier: *identifier,
}
.pda_init(pos, &pda_seed_by_position),
.pda_init(commitment_root, pos, &pda_seed_by_position),
InputAccountIdentity::PrivatePdaUpdate {
epk,
view_tag,

View File

@ -38,6 +38,7 @@ pub enum InputAccountIdentity {
ssk: SharedSecretKey,
nsk: NullifierSecretKey,
identifier: Identifier,
commitment_root: CommitmentSetDigest,
},
/// Update of an authorized standalone private account: existing on-chain commitment, with
/// membership proof.
@ -57,6 +58,7 @@ pub enum InputAccountIdentity {
npk: NullifierPublicKey,
ssk: SharedSecretKey,
identifier: Identifier,
commitment_root: CommitmentSetDigest,
},
/// Init of a private PDA, unauthorized. The npk-to-account_id binding is proven upstream
/// via `Claim::Pda(seed)` or a caller's `pda_seeds` match. The identifier diversifies the
@ -68,6 +70,7 @@ pub enum InputAccountIdentity {
npk: NullifierPublicKey,
ssk: SharedSecretKey,
identifier: Identifier,
commitment_root: CommitmentSetDigest,
/// When `Some((seed, authority_program_id))`, the circuit binds this position via the
/// external derivation check
/// `AccountId::for_private_pda(authority_program_id, seed, npk, identifier) ==

View File

@ -273,6 +273,7 @@ mod tests {
npk: recipient_keys.npk(),
ssk: shared_secret,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
},
],
&crate::test_methods::simple_balance_transfer().into(),
@ -387,6 +388,7 @@ mod tests {
npk: recipient_keys.npk(),
ssk: shared_secret_2,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
},
],
&program.into(),
@ -460,6 +462,7 @@ mod tests {
npk: account_keys.npk(),
ssk: shared_secret,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
}],
&program_with_deps,
);
@ -491,6 +494,7 @@ mod tests {
npk,
ssk: shared_secret,
identifier,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
}],
&program.clone().into(),
@ -540,6 +544,7 @@ mod tests {
npk,
ssk: shared_secret_pda,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
}],
&program_with_deps,
@ -595,6 +600,7 @@ mod tests {
npk,
ssk: shared_secret_pda,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
},
InputAccountIdentity::Public,
@ -653,6 +659,7 @@ mod tests {
npk: shared_npk,
ssk: shared_secret,
identifier: shared_identifier,
commitment_root: DUMMY_COMMITMENT_HASH,
},
],
&program.into(),
@ -683,6 +690,7 @@ mod tests {
ssk,
nsk: keys.nsk,
identifier,
commitment_root: DUMMY_COMMITMENT_HASH,
}],
&program.into(),
)
@ -714,6 +722,7 @@ mod tests {
npk: keys.npk(),
ssk,
identifier,
commitment_root: DUMMY_COMMITMENT_HASH,
}],
&program.into(),
)
@ -848,6 +857,7 @@ mod tests {
npk,
ssk: shared_secret,
identifier: 99,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
}],
&program.into(),

View File

@ -2,8 +2,7 @@ use std::collections::{BTreeSet, HashMap, HashSet};
use borsh::{BorshDeserialize, BorshSerialize};
use lee_core::{
BlockId, Commitment, CommitmentSetDigest, DUMMY_COMMITMENT, MembershipProof, Nullifier,
Timestamp,
BlockId, Commitment, CommitmentSetDigest, DUMMY_COMMITMENT, MembershipProof, Nullifier, Timestamp,
account::{Account, AccountId},
program::ProgramId,
};
@ -327,8 +326,8 @@ pub mod tests {
use std::collections::HashMap;
use lee_core::{
BlockId, Commitment, EncryptedAccountData, InputAccountIdentity, Nullifier,
NullifierPublicKey, NullifierSecretKey, SharedSecretKey, Timestamp,
BlockId, Commitment, DUMMY_COMMITMENT_HASH, EncryptedAccountData, InputAccountIdentity,
Nullifier, NullifierPublicKey, NullifierSecretKey, SharedSecretKey, Timestamp,
account::{Account, AccountId, AccountWithMetadata, Nonce, data::Data},
encryption::{EphemeralPublicKey, ViewingPublicKey},
program::{
@ -1192,6 +1191,7 @@ pub mod tests {
npk: recipient_keys.npk(),
ssk: shared_secret,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
},
],
&crate::test_methods::simple_balance_transfer().into(),
@ -1259,6 +1259,7 @@ pub mod tests {
npk: recipient_keys.npk(),
ssk: shared_secret_2,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
},
],
&program.into(),
@ -1908,6 +1909,7 @@ pub mod tests {
0,
)
.0,
commitment_root: DUMMY_COMMITMENT_HASH,
identifier: 0,
},
],
@ -1974,6 +1976,7 @@ pub mod tests {
0,
)
.0,
commitment_root: DUMMY_COMMITMENT_HASH,
identifier: 0,
},
],
@ -2040,6 +2043,7 @@ pub mod tests {
0,
)
.0,
commitment_root: DUMMY_COMMITMENT_HASH,
identifier: 0,
},
],
@ -2106,6 +2110,7 @@ pub mod tests {
0,
)
.0,
commitment_root: DUMMY_COMMITMENT_HASH,
identifier: 0,
},
],
@ -2172,6 +2177,7 @@ pub mod tests {
0,
)
.0,
commitment_root: DUMMY_COMMITMENT_HASH,
identifier: 0,
},
],
@ -2236,6 +2242,7 @@ pub mod tests {
0,
)
.0,
commitment_root: DUMMY_COMMITMENT_HASH,
identifier: 0,
},
],
@ -2279,6 +2286,7 @@ pub mod tests {
npk,
ssk: shared_secret,
identifier: u128::MAX,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
},
],
@ -2314,6 +2322,7 @@ pub mod tests {
npk,
ssk: shared_secret,
identifier: u128::MAX,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
}],
&program.into(),
@ -2357,6 +2366,7 @@ pub mod tests {
npk: npk_b,
ssk: shared_secret,
identifier: u128::MAX,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
}],
&program.into(),
@ -2396,6 +2406,7 @@ pub mod tests {
npk,
ssk: shared_secret,
identifier: u128::MAX,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
}],
&program_with_deps,
@ -2438,6 +2449,7 @@ pub mod tests {
npk,
ssk: shared_secret,
identifier: u128::MAX,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
}],
&program_with_deps,
@ -2479,6 +2491,7 @@ pub mod tests {
npk: keys_a.npk(),
ssk: shared_a,
identifier: u128::MAX,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
},
InputAccountIdentity::PrivatePdaInit {
@ -2487,6 +2500,7 @@ pub mod tests {
npk: keys_b.npk(),
ssk: shared_b,
identifier: u128::MAX,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
},
],
@ -2531,6 +2545,7 @@ pub mod tests {
npk,
ssk: shared_secret,
identifier: u128::MAX,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: None,
}],
&program.into(),
@ -3302,6 +3317,7 @@ pub mod tests {
ssk: shared_secret,
nsk: private_keys.nsk,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
}],
&program.into(),
)
@ -3349,6 +3365,7 @@ pub mod tests {
npk: private_keys.npk(),
ssk: shared_secret,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
}],
&program.into(),
)
@ -3400,6 +3417,7 @@ pub mod tests {
ssk: shared_secret,
nsk: private_keys.nsk,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
}],
&claimer_program.into(),
)
@ -3446,6 +3464,7 @@ pub mod tests {
ssk: shared_secret2,
nsk: private_keys.nsk,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
}],
&noop_program.into(),
);
@ -3788,6 +3807,7 @@ pub mod tests {
npk: account_keys.npk(),
ssk: shared_secret,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
}],
&validity_window_program.into(),
)
@ -3856,6 +3876,7 @@ pub mod tests {
npk: account_keys.npk(),
ssk: shared_secret,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
}],
&validity_window_program.into(),
)
@ -4200,6 +4221,7 @@ pub mod tests {
npk: alice_npk,
ssk: alice_shared_0,
identifier: 0,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: Some((seed, proxy_id)),
},
],
@ -4240,6 +4262,7 @@ pub mod tests {
npk: alice_npk,
ssk: alice_shared_1,
identifier: 1,
commitment_root: DUMMY_COMMITMENT_HASH,
seed: Some((seed, proxy_id)),
},
],

View File

@ -5,8 +5,8 @@ use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
use keycard_wallet::{KeycardWallet, python_path};
use lee::{AccountId, PrivateKey, PublicKey, Signature};
use lee_core::{
Identifier, InputAccountIdentity, MembershipProof, NullifierPublicKey, NullifierSecretKey,
SharedSecretKey,
CommitmentSetDigest, DUMMY_COMMITMENT_HASH, Identifier, InputAccountIdentity, MembershipProof,
NullifierPublicKey, NullifierSecretKey, SharedSecretKey,
account::{AccountWithMetadata, Nonce},
encryption::{EncryptedAccountData, EphemeralPublicKey, ViewingPublicKey},
};
@ -187,6 +187,7 @@ enum State {
pub struct AccountManager {
states: Vec<State>,
pin: Option<String>,
dummy_commitment_root: CommitmentSetDigest,
}
impl AccountManager {
@ -340,7 +341,24 @@ impl AccountManager {
states.push(state);
}
Ok(Self { states, pin })
let has_init_account = states
.iter()
.any(|s| matches!(s, State::Private(pre) if pre.proof.is_none()));
let dummy_commitment_root = if has_init_account {
wallet
.get_commitment_root()
.await
.map_err(ExecutionFailureKind::SequencerError)?
.unwrap_or(DUMMY_COMMITMENT_HASH)
} else {
DUMMY_COMMITMENT_HASH
};
Ok(Self {
states,
pin,
dummy_commitment_root,
})
}
pub fn pre_states(&self) -> Vec<AccountWithMetadata> {
@ -404,6 +422,7 @@ impl AccountManager {
npk: pre.npk,
ssk: pre.ssk,
identifier: pre.identifier,
commitment_root: self.dummy_commitment_root,
seed: None,
},
},
@ -424,6 +443,7 @@ impl AccountManager {
ssk: pre.ssk,
nsk,
identifier: pre.identifier,
commitment_root: self.dummy_commitment_root,
},
(None, _) => InputAccountIdentity::PrivateUnauthorized {
epk: pre.epk.clone(),
@ -431,6 +451,7 @@ impl AccountManager {
npk: pre.npk,
ssk: pre.ssk,
identifier: pre.identifier,
commitment_root: self.dummy_commitment_root,
},
},
})

View File

@ -22,7 +22,8 @@ use lee::{
},
};
use lee_core::{
Commitment, MembershipProof, SharedSecretKey, account::Nonce, program::InstructionData,
Commitment, CommitmentSetDigest, DUMMY_COMMITMENT, MembershipProof, SharedSecretKey,
account::Nonce, compute_digest_for_path, program::InstructionData,
};
use log::info;
use sequencer_service_rpc::{RpcClient as _, SequencerClient, SequencerClientBuilder};
@ -508,6 +509,14 @@ impl WalletCore {
}
}
pub async fn get_commitment_root(&self) -> Result<Option<CommitmentSetDigest>> {
let proof = self
.sequencer_client
.get_proof_for_commitment(DUMMY_COMMITMENT)
.await?;
Ok(proof.map(|p| compute_digest_for_path(&DUMMY_COMMITMENT, &p)))
}
pub fn decode_insert_privacy_preserving_transaction_results(
&mut self,
tx: &lee::privacy_preserving_transaction::PrivacyPreservingTransaction,