mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-08-26 14:41:12 +00:00
refactor: migrate programs to LEZ lez-core-v0.2.0
Bump the LEZ dependency from the `v0.2.0-rc3` tags to the released
`lez-core-v0.2.0` tag across the workspace and all guest manifests. The crate
was renamed upstream, so `nssa_core`/`nssa` now resolve via the `lee_core`/`lee`
packages, and spel-framework points at the `refactor/lez-v020-compat` fork
branch for compatibility.
Adapt the integration tests to the new API surface:
- `NssaError` is now `LeeError` (error variants unchanged).
- Account inputs move from numeric mask vectors (`vec![2, 0, 0]`) to typed
`InputAccountIdentity` values (e.g. `PrivateUnauthorized { epk, view_tag,
npk, ssk, identifier }`).
- `ViewingPublicKey::from_scalar` → `from_seed(d, z)`; `AccountId::from(&npk)`
→ `AccountId::for_regular_private_account(&npk, 0)`; ephemeral-key/shared-
secret setup → `SharedSecretKey::encapsulate_deterministic(...)` with the
circuit filling the EPK.
Regenerate all guest Cargo.lock files and the workspace lockfile to match.
This commit is contained in:
@@ -7,8 +7,8 @@ edition = "2021"
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0" }
|
||||
amm_core = { path = "core" }
|
||||
token_core = { path = "../token/core" }
|
||||
twap_oracle_core = { path = "../twap_oracle/core" }
|
||||
|
||||
@@ -7,8 +7,8 @@ edition = "2021"
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
spel-framework-macros = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework-macros" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
spel-framework-macros = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework-macros" }
|
||||
token_core = { path = "../../token/core" }
|
||||
borsh = { version = "1.5", features = ["derive"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
Generated
+137
-1458
File diff suppressed because it is too large
Load Diff
@@ -56,8 +56,8 @@ name = "amm"
|
||||
path = "src/bin/amm.rs"
|
||||
|
||||
[dependencies]
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
|
||||
spel-framework = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee_core" }
|
||||
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||
amm_core = { path = "../../core" }
|
||||
amm_program = { path = "../..", package = "amm_program" }
|
||||
|
||||
@@ -7,6 +7,6 @@ edition = "2021"
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
ata_core = { path = "core" }
|
||||
token_core = { path = "../token/core" }
|
||||
|
||||
@@ -7,7 +7,7 @@ edition = "2021"
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
borsh = { version = "1.5", features = ["derive"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||
|
||||
Generated
+123
-1649
File diff suppressed because it is too large
Load Diff
@@ -56,8 +56,8 @@ name = "ata"
|
||||
path = "src/bin/ata.rs"
|
||||
|
||||
[dependencies]
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
|
||||
spel-framework = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee_core" }
|
||||
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||
# Pin ruint (transitive via risc0-binfmt) below 1.18, which raised its MSRV to
|
||||
# rustc 1.90. The risc0 guest toolchain ships rustc 1.88, so 1.18+ fails the
|
||||
|
||||
@@ -11,8 +11,8 @@ edition = "2021"
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
nssa = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
nssa = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
twap_oracle_core = { path = "../twap_oracle/core" }
|
||||
twap-oracle-methods = { path = "../twap_oracle/methods" }
|
||||
# `prove` exposes `ExecutorImpl`/`Session` (the cycle split); we only execute, never prove.
|
||||
|
||||
@@ -8,7 +8,7 @@ workspace = true
|
||||
|
||||
[dependencies]
|
||||
nssa = { workspace = true }
|
||||
nssa_core = { workspace = true, features = ["host"] }
|
||||
nssa_core = { workspace = true, features = ["host", "test_utils"] }
|
||||
amm_core = { workspace = true }
|
||||
token_core = { workspace = true }
|
||||
ata_core = { workspace = true }
|
||||
|
||||
@@ -8,7 +8,7 @@ use amm_core::{
|
||||
MINIMUM_LIQUIDITY,
|
||||
};
|
||||
use nssa::{
|
||||
error::NssaError,
|
||||
error::LeeError,
|
||||
program_deployment_transaction::{self, ProgramDeploymentTransaction},
|
||||
public_transaction, PrivateKey, PublicKey, PublicTransaction, V03State,
|
||||
CLOCK_01_PROGRAM_ACCOUNT_ID,
|
||||
@@ -1043,7 +1043,7 @@ fn try_execute_new_definition(
|
||||
state: &mut V03State,
|
||||
fees: u128,
|
||||
authorize_user_lp: bool,
|
||||
) -> Result<(), NssaError> {
|
||||
) -> Result<(), LeeError> {
|
||||
let instruction = amm_core::Instruction::NewDefinition {
|
||||
token_a_amount: Balances::vault_a_init(),
|
||||
token_b_amount: Balances::vault_b_init(),
|
||||
@@ -1280,7 +1280,7 @@ fn execute_initialize(state: &mut V03State) {
|
||||
fn execute_create_price_observations(
|
||||
state: &mut V03State,
|
||||
window_duration: u64,
|
||||
) -> Result<(), NssaError> {
|
||||
) -> Result<(), LeeError> {
|
||||
let instruction = amm_core::Instruction::CreatePriceObservations { window_duration };
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@@ -1306,7 +1306,7 @@ fn execute_create_price_observations(
|
||||
fn execute_create_oracle_price_account(
|
||||
state: &mut V03State,
|
||||
window_duration: u64,
|
||||
) -> Result<(), NssaError> {
|
||||
) -> Result<(), LeeError> {
|
||||
let instruction = amm_core::Instruction::CreateOraclePriceAccount { window_duration };
|
||||
|
||||
let message = public_transaction::Message::try_new(
|
||||
@@ -1421,7 +1421,7 @@ fn execute_update_config(
|
||||
token_program_id: Option<nssa_core::program::ProgramId>,
|
||||
twap_oracle_program_id: Option<nssa_core::program::ProgramId>,
|
||||
new_authority: Option<AccountId>,
|
||||
) -> Result<(), NssaError> {
|
||||
) -> Result<(), LeeError> {
|
||||
let signer_id = AccountId::from(&PublicKey::new_from_private_key(signer));
|
||||
let instruction = amm_core::Instruction::UpdateConfig {
|
||||
token_program_id,
|
||||
@@ -1482,7 +1482,7 @@ fn amm_update_config_rejects_non_admin() {
|
||||
// user_a is not the admin; even though they sign, the update is rejected and the config is
|
||||
// left unchanged.
|
||||
let result = execute_update_config(&mut state, &Keys::user_a(), Some([123u32; 8]), None, None);
|
||||
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
|
||||
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
|
||||
|
||||
let config = config_data(&state);
|
||||
assert_eq!(config.token_program_id, Ids::token_program());
|
||||
@@ -1500,7 +1500,7 @@ fn amm_update_config_authority_handoff_revokes_old_admin() {
|
||||
|
||||
// The original admin can no longer update.
|
||||
let result = execute_update_config(&mut state, &Keys::admin(), Some([123u32; 8]), None, None);
|
||||
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
|
||||
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
|
||||
|
||||
// The new admin can.
|
||||
execute_update_config(&mut state, &Keys::user_a(), Some([124u32; 8]), None, None).unwrap();
|
||||
@@ -1609,7 +1609,7 @@ fn amm_create_oracle_price_account_rejects_existing_account() {
|
||||
|
||||
// A second creation for the same (pool, window) is rejected and leaves the account intact.
|
||||
let result = execute_create_oracle_price_account(&mut state, window_duration);
|
||||
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
|
||||
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
|
||||
assert_eq!(
|
||||
state.get_account_by_id(Ids::oracle_price_account(window_duration)),
|
||||
after_first
|
||||
@@ -1633,7 +1633,7 @@ fn amm_create_price_observations_rejects_existing_account() {
|
||||
// A second creation for the same (pool, window) is rejected because the observations account
|
||||
// already exists, and leaves the existing account intact.
|
||||
let result = execute_create_price_observations(&mut state, window_duration);
|
||||
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
|
||||
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
|
||||
let feed_after_second = twap_oracle_core::PriceObservations::try_from(
|
||||
&state
|
||||
.get_account_by_id(Ids::price_observations(window_duration))
|
||||
@@ -1653,7 +1653,7 @@ fn amm_create_price_observations_without_current_tick_account_fails() {
|
||||
state.force_insert_account(Ids::current_tick_account(), Account::default());
|
||||
|
||||
let result = execute_create_price_observations(&mut state, window_duration);
|
||||
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
|
||||
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
|
||||
assert_eq!(
|
||||
state.get_account_by_id(Ids::price_observations(window_duration)),
|
||||
Account::default()
|
||||
@@ -1680,7 +1680,7 @@ fn advance_clock(state: &mut V03State, timestamp: u64) {
|
||||
/// Calls the TWAP oracle's permissionless `RecordTick` directly (it is not wrapped by the AMM),
|
||||
/// folding the pool's current tick into its observations ring buffer for the given window.
|
||||
#[cfg(test)]
|
||||
fn execute_record_tick(state: &mut V03State, window_duration: u64) -> Result<(), NssaError> {
|
||||
fn execute_record_tick(state: &mut V03State, window_duration: u64) -> Result<(), LeeError> {
|
||||
let instruction = twap_oracle_core::Instruction::RecordTick {
|
||||
price_source_id: Ids::pool_definition(),
|
||||
window_duration,
|
||||
@@ -1746,7 +1746,7 @@ fn read_oracle_price(
|
||||
/// the TWAP from the pool's observations — extrapolating the tail from the current tick — and
|
||||
/// writes it to the oracle price account.
|
||||
#[cfg(test)]
|
||||
fn execute_publish_price(state: &mut V03State, window_duration: u64) -> Result<(), NssaError> {
|
||||
fn execute_publish_price(state: &mut V03State, window_duration: u64) -> Result<(), LeeError> {
|
||||
let instruction = twap_oracle_core::Instruction::PublishPrice {
|
||||
price_source_id: Ids::pool_definition(),
|
||||
window_duration,
|
||||
@@ -2276,7 +2276,7 @@ fn amm_new_definition_without_user_lp_authorization_fails() {
|
||||
|
||||
let result = try_execute_new_definition(&mut state, Balances::fee_tier(), false);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
|
||||
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
|
||||
assert_eq!(
|
||||
state.get_account_by_id(Ids::pool_definition()),
|
||||
Account::default()
|
||||
@@ -2317,8 +2317,8 @@ fn amm_new_definition_precreated_user_lp_unsigned_fails() {
|
||||
state.force_insert_account(Ids::vault_b(), Accounts::vault_b_reinitializable());
|
||||
|
||||
let result = try_execute_new_definition(&mut state, Balances::fee_tier(), false);
|
||||
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
|
||||
|
||||
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
|
||||
assert_eq!(
|
||||
state.get_account_by_id(Ids::pool_definition()),
|
||||
Account::default()
|
||||
@@ -2380,9 +2380,10 @@ fn amm_new_definition_rejects_unsupported_fee_tier_transaction() {
|
||||
Accounts::token_lp_definition_reinitializable(),
|
||||
);
|
||||
|
||||
let result = try_execute_new_definition(&mut state, 2, false);
|
||||
// `user_holding_lp` is signed so the rejection isolates the unsupported fee tier.
|
||||
let result = try_execute_new_definition(&mut state, 2, true);
|
||||
|
||||
assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_))));
|
||||
assert!(matches!(result, Err(LeeError::ProgramExecutionFailed(_))));
|
||||
assert_eq!(
|
||||
state.get_account_by_id(Ids::pool_definition()),
|
||||
Accounts::pool_definition_zero_supply_reinitializable()
|
||||
@@ -2789,7 +2790,7 @@ fn amm_swap_rejects_expired_deadline() {
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
assert!(matches!(
|
||||
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
|
||||
Err(NssaError::OutOfValidityWindow)
|
||||
Err(LeeError::OutOfValidityWindow)
|
||||
));
|
||||
}
|
||||
|
||||
@@ -2832,7 +2833,7 @@ fn amm_swap_exact_output_rejects_expired_deadline() {
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
assert!(matches!(
|
||||
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
|
||||
Err(NssaError::OutOfValidityWindow)
|
||||
Err(LeeError::OutOfValidityWindow)
|
||||
));
|
||||
}
|
||||
|
||||
@@ -2877,7 +2878,7 @@ fn amm_add_liquidity_rejects_expired_deadline() {
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
assert!(matches!(
|
||||
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
|
||||
Err(NssaError::OutOfValidityWindow)
|
||||
Err(LeeError::OutOfValidityWindow)
|
||||
));
|
||||
}
|
||||
|
||||
@@ -2918,7 +2919,7 @@ fn amm_remove_liquidity_rejects_expired_deadline() {
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
assert!(matches!(
|
||||
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
|
||||
Err(NssaError::OutOfValidityWindow)
|
||||
Err(LeeError::OutOfValidityWindow)
|
||||
));
|
||||
}
|
||||
|
||||
@@ -2967,7 +2968,7 @@ fn amm_new_definition_rejects_expired_deadline() {
|
||||
let tx = PublicTransaction::new(message, witness_set);
|
||||
assert!(matches!(
|
||||
state.transition_from_public_transaction(&tx, 0, block_timestamp_ms),
|
||||
Err(NssaError::OutOfValidityWindow)
|
||||
Err(LeeError::OutOfValidityWindow)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,12 @@ use nssa::{
|
||||
},
|
||||
program::Program,
|
||||
program_deployment_transaction::{self, ProgramDeploymentTransaction},
|
||||
public_transaction, EphemeralPublicKey, PrivateKey, PublicKey, PublicTransaction,
|
||||
SharedSecretKey, V03State,
|
||||
public_transaction, PrivateKey, PublicKey, PublicTransaction, SharedSecretKey, V03State,
|
||||
};
|
||||
use nssa_core::{
|
||||
account::{Account, AccountId, AccountWithMetadata, Data, Nonce},
|
||||
encryption::{Scalar, ViewingPublicKey},
|
||||
NullifierPublicKey, NullifierSecretKey,
|
||||
encryption::{EphemeralPublicKey, ViewingPublicKey},
|
||||
EncryptedAccountData, InputAccountIdentity, NullifierPublicKey, NullifierSecretKey,
|
||||
};
|
||||
use token_core::{TokenDefinition, TokenHolding};
|
||||
|
||||
@@ -511,16 +510,15 @@ fn ata_create_from_private_owner() {
|
||||
// Private owner key material
|
||||
let owner_nsk: NullifierSecretKey = [13u8; 32];
|
||||
let owner_npk = NullifierPublicKey::from(&owner_nsk);
|
||||
let owner_vsk: Scalar = [31u8; 32];
|
||||
let owner_vpk = ViewingPublicKey::from_scalar(owner_vsk);
|
||||
let owner_id = AccountId::from(&owner_npk);
|
||||
// `ViewingPublicKey::from_seed` needs two 32-byte halves `(d, z)`.
|
||||
let owner_vpk = ViewingPublicKey::from_seed(&[31u8; 32], &[32u8; 32]);
|
||||
let owner_id = AccountId::for_regular_private_account(&owner_npk, 0);
|
||||
|
||||
// ATA derived from the private owner
|
||||
let seed = compute_ata_seed(Ids::token_program(), owner_id, Ids::token_definition());
|
||||
let owner_ata_id = get_associated_token_account_id(&Ids::ata_program(), &seed);
|
||||
|
||||
// Pre-states: private uninitialized owner (mask=2), public token definition (mask=0), public
|
||||
// uninitialized ATA (mask=0)
|
||||
// Pre-states: private uninitialized owner, public token definition, public uninitialized ATA.
|
||||
let owner_pre = AccountWithMetadata::new(Account::default(), false, owner_id);
|
||||
let def_pre = AccountWithMetadata::new(
|
||||
Accounts::token_definition_init(),
|
||||
@@ -534,10 +532,8 @@ fn ata_create_from_private_owner() {
|
||||
};
|
||||
let instruction_data = Program::serialize_instruction(instruction).unwrap();
|
||||
|
||||
// Ephemeral key for encrypting the private owner's post-state
|
||||
let esk: Scalar = [3u8; 32];
|
||||
let shared_secret = SharedSecretKey::new(&esk, &owner_vpk);
|
||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||
// Encapsulate a shared secret against the owner's viewing key; the circuit fills the EPK.
|
||||
let shared_secret = SharedSecretKey::encapsulate_deterministic(&owner_vpk, &[0u8; 32], 0).0;
|
||||
|
||||
let ata_program = Program::new(ata_methods::ATA_ELF.to_vec()).unwrap();
|
||||
let token_program = Program::new(token_methods::TOKEN_ELF.to_vec()).unwrap();
|
||||
@@ -549,11 +545,20 @@ fn ata_create_from_private_owner() {
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![owner_pre, def_pre, ata_pre],
|
||||
instruction_data,
|
||||
// owner=new private (2), token_definition=public (0), ata=public (0)
|
||||
vec![2, 0, 0],
|
||||
vec![(owner_npk, shared_secret)],
|
||||
vec![], // no NSKs: new private accounts don't require one
|
||||
vec![None], // no membership proof: owner is being created, not spending
|
||||
vec![
|
||||
// owner: new private account, not owned/spent by the caller (no nsk, no proof).
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&owner_npk, &owner_vpk),
|
||||
npk: owner_npk,
|
||||
ssk: shared_secret,
|
||||
identifier: 0,
|
||||
},
|
||||
// token_definition: public
|
||||
InputAccountIdentity::Public,
|
||||
// ata: public
|
||||
InputAccountIdentity::Public,
|
||||
],
|
||||
&program_with_deps,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -561,7 +566,6 @@ fn ata_create_from_private_owner() {
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![Ids::token_definition(), owner_ata_id],
|
||||
vec![],
|
||||
vec![(owner_npk, owner_vpk, epk)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
use nssa::{
|
||||
execute_and_prove,
|
||||
privacy_preserving_transaction::{Message, WitnessSet},
|
||||
privacy_preserving_transaction::{Message, PrivacyPreservingTransaction, WitnessSet},
|
||||
program::Program,
|
||||
program_deployment_transaction::{self, ProgramDeploymentTransaction},
|
||||
public_transaction, PrivacyPreservingTransaction, PrivateKey, PublicKey, PublicTransaction,
|
||||
SharedSecretKey, V03State,
|
||||
public_transaction, PrivateKey, PublicKey, PublicTransaction, SharedSecretKey, V03State,
|
||||
};
|
||||
use nssa_core::{
|
||||
account::{Account, AccountId, AccountWithMetadata, Data, Nonce},
|
||||
encryption::{EphemeralPublicKey, ViewingPublicKey},
|
||||
Commitment, NullifierPublicKey, NullifierSecretKey,
|
||||
Commitment, EncryptedAccountData, InputAccountIdentity, NullifierPublicKey, NullifierSecretKey,
|
||||
};
|
||||
use token_core::{TokenDefinition, TokenHolding};
|
||||
|
||||
@@ -616,12 +615,14 @@ impl PrivateKeys {
|
||||
NullifierPublicKey::from(&Self::holder_nsk())
|
||||
}
|
||||
|
||||
fn holder_vsk() -> [u8; 32] {
|
||||
[73; 32]
|
||||
// `ViewingPublicKey::from_seed` needs two 32-byte halves `(d, z)`. We reuse the
|
||||
// legacy viewing scalar as `d` and pick a fixed distinct `z`.
|
||||
fn holder_vpk() -> ViewingPublicKey {
|
||||
ViewingPublicKey::from_seed(&[73; 32], &[74; 32])
|
||||
}
|
||||
|
||||
fn holder_vpk() -> ViewingPublicKey {
|
||||
ViewingPublicKey::from_scalar(Self::holder_vsk())
|
||||
fn holder_id() -> AccountId {
|
||||
AccountId::for_regular_private_account(&Self::holder_npk(), 0)
|
||||
}
|
||||
|
||||
fn recipient_nsk() -> NullifierSecretKey {
|
||||
@@ -632,12 +633,12 @@ impl PrivateKeys {
|
||||
NullifierPublicKey::from(&Self::recipient_nsk())
|
||||
}
|
||||
|
||||
fn recipient_vsk() -> [u8; 32] {
|
||||
[48; 32]
|
||||
fn recipient_vpk() -> ViewingPublicKey {
|
||||
ViewingPublicKey::from_seed(&[48; 32], &[49; 32])
|
||||
}
|
||||
|
||||
fn recipient_vpk() -> ViewingPublicKey {
|
||||
ViewingPublicKey::from_scalar(Self::recipient_vsk())
|
||||
fn recipient_id() -> AccountId {
|
||||
AccountId::for_regular_private_account(&Self::recipient_npk(), 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,13 +655,16 @@ fn shielded_token_transfer(amount: u128, state: &mut V03State) -> Account {
|
||||
let sender_account = state.get_account_by_id(sender_id);
|
||||
let sender_nonce = sender_account.nonce;
|
||||
|
||||
let sender = AccountWithMetadata::new(sender_account, true, sender_id);
|
||||
let recipient =
|
||||
AccountWithMetadata::new(Account::default(), false, &PrivateKeys::recipient_npk());
|
||||
let recipient_npk = PrivateKeys::recipient_npk();
|
||||
let recipient_vpk = PrivateKeys::recipient_vpk();
|
||||
let recipient_id = PrivateKeys::recipient_id();
|
||||
|
||||
let esk = [99u8; 32];
|
||||
let shared_secret = SharedSecretKey::new(&esk, &PrivateKeys::recipient_vpk());
|
||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||
let sender = AccountWithMetadata::new(sender_account, true, sender_id);
|
||||
let recipient = AccountWithMetadata::new(Account::default(), false, recipient_id);
|
||||
|
||||
// Sender encapsulates a shared secret against the recipient's viewing key. The
|
||||
// circuit fills the real EPK, so we pass an empty placeholder in the identity.
|
||||
let shared_secret = SharedSecretKey::encapsulate_deterministic(&recipient_vpk, &[0u8; 32], 0).0;
|
||||
|
||||
let instruction = token_core::Instruction::Transfer {
|
||||
amount_to_transfer: amount,
|
||||
@@ -668,25 +672,22 @@ fn shielded_token_transfer(amount: u128, state: &mut V03State) -> Account {
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![sender, recipient],
|
||||
Program::serialize_instruction(instruction).unwrap(),
|
||||
vec![0, 2],
|
||||
vec![(PrivateKeys::recipient_npk(), shared_secret)],
|
||||
vec![],
|
||||
vec![None],
|
||||
vec![
|
||||
InputAccountIdentity::Public,
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&recipient_npk, &recipient_vpk),
|
||||
npk: recipient_npk,
|
||||
ssk: shared_secret,
|
||||
identifier: 0,
|
||||
},
|
||||
],
|
||||
&token_program().into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![sender_id],
|
||||
vec![sender_nonce],
|
||||
vec![(
|
||||
PrivateKeys::recipient_npk(),
|
||||
PrivateKeys::recipient_vpk(),
|
||||
epk,
|
||||
)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
let message =
|
||||
Message::try_from_circuit_output(vec![sender_id], vec![sender_nonce], output).unwrap();
|
||||
|
||||
let witness_set = WitnessSet::for_message(&message, proof, &[&Keys::holder_key()]);
|
||||
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
||||
@@ -701,7 +702,7 @@ fn shielded_token_transfer(amount: u128, state: &mut V03State) -> Account {
|
||||
definition_id: Ids::token_definition(),
|
||||
balance: amount,
|
||||
}),
|
||||
nonce: Nonce::private_account_nonce_init(&PrivateKeys::recipient_npk()),
|
||||
nonce: Nonce::private_account_nonce_init(&recipient_id),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,7 +726,7 @@ fn token_shielded_transfer() {
|
||||
}
|
||||
);
|
||||
|
||||
let recipient_commitment = Commitment::new(&PrivateKeys::recipient_npk(), &recipient_account);
|
||||
let recipient_commitment = Commitment::new(&PrivateKeys::recipient_id(), &recipient_account);
|
||||
assert!(state
|
||||
.get_proof_for_commitment(&recipient_commitment)
|
||||
.is_some());
|
||||
@@ -742,22 +743,24 @@ fn token_private_transfer() {
|
||||
let sender_npk = PrivateKeys::recipient_npk();
|
||||
let sender_nsk = PrivateKeys::recipient_nsk();
|
||||
let sender_vpk = PrivateKeys::recipient_vpk();
|
||||
let sender_id = PrivateKeys::recipient_id();
|
||||
|
||||
let new_recipient_npk = PrivateKeys::holder_npk();
|
||||
let new_recipient_vpk = PrivateKeys::holder_vpk();
|
||||
let new_recipient_id = PrivateKeys::holder_id();
|
||||
|
||||
let sender_commitment = Commitment::new(&sender_npk, &sender_account);
|
||||
let sender_commitment = Commitment::new(&sender_id, &sender_account);
|
||||
let membership_proof = state
|
||||
.get_proof_for_commitment(&sender_commitment)
|
||||
.expect("sender's commitment must be in the set");
|
||||
|
||||
let esk_1 = [11u8; 32];
|
||||
let shared_secret_1 = SharedSecretKey::new(&esk_1, &sender_vpk);
|
||||
let epk_1 = EphemeralPublicKey::from_scalar(esk_1);
|
||||
// Distinct `output_index` per private output keeps the encapsulated secrets reproducible.
|
||||
let shared_secret_1 = SharedSecretKey::encapsulate_deterministic(&sender_vpk, &[0u8; 32], 0).0;
|
||||
let shared_secret_2 =
|
||||
SharedSecretKey::encapsulate_deterministic(&new_recipient_vpk, &[0u8; 32], 1).0;
|
||||
|
||||
let esk_2 = [22u8; 32];
|
||||
let shared_secret_2 = SharedSecretKey::new(&esk_2, &new_recipient_vpk);
|
||||
let epk_2 = EphemeralPublicKey::from_scalar(esk_2);
|
||||
|
||||
let sender_pre = AccountWithMetadata::new(sender_account.clone(), true, &sender_npk);
|
||||
let new_recipient_pre = AccountWithMetadata::new(Account::default(), false, &new_recipient_npk);
|
||||
let sender_pre = AccountWithMetadata::new(sender_account.clone(), true, sender_id);
|
||||
let new_recipient_pre = AccountWithMetadata::new(Account::default(), false, new_recipient_id);
|
||||
|
||||
let instruction = token_core::Instruction::Transfer {
|
||||
amount_to_transfer: transfer_amount,
|
||||
@@ -765,27 +768,31 @@ fn token_private_transfer() {
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![sender_pre, new_recipient_pre],
|
||||
Program::serialize_instruction(instruction).unwrap(),
|
||||
vec![1, 2],
|
||||
vec![
|
||||
(sender_npk, shared_secret_1),
|
||||
(new_recipient_npk, shared_secret_2),
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&sender_npk, &sender_vpk),
|
||||
ssk: shared_secret_1,
|
||||
nsk: sender_nsk,
|
||||
membership_proof,
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(
|
||||
&new_recipient_npk,
|
||||
&new_recipient_vpk,
|
||||
),
|
||||
npk: new_recipient_npk,
|
||||
ssk: shared_secret_2,
|
||||
identifier: 0,
|
||||
},
|
||||
],
|
||||
vec![sender_nsk],
|
||||
vec![state.get_proof_for_commitment(&sender_commitment), None],
|
||||
&token_program().into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![],
|
||||
vec![],
|
||||
vec![
|
||||
(sender_npk, sender_vpk, epk_1),
|
||||
(new_recipient_npk, new_recipient_vpk, epk_2),
|
||||
],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
let message = Message::try_from_circuit_output(vec![], vec![], output).unwrap();
|
||||
|
||||
let witness_set = WitnessSet::for_message(&message, proof, &[]);
|
||||
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
||||
@@ -794,7 +801,7 @@ fn token_private_transfer() {
|
||||
.unwrap();
|
||||
|
||||
let sender_nonce_after =
|
||||
Nonce::private_account_nonce_init(&sender_npk).private_account_nonce_increment(&sender_nsk);
|
||||
Nonce::private_account_nonce_init(&sender_id).private_account_nonce_increment(&sender_nsk);
|
||||
let new_sender_account = Account {
|
||||
program_owner: Ids::token_program(),
|
||||
balance: 0,
|
||||
@@ -805,7 +812,7 @@ fn token_private_transfer() {
|
||||
nonce: sender_nonce_after,
|
||||
};
|
||||
assert!(state
|
||||
.get_proof_for_commitment(&Commitment::new(&sender_npk, &new_sender_account))
|
||||
.get_proof_for_commitment(&Commitment::new(&sender_id, &new_sender_account))
|
||||
.is_some());
|
||||
|
||||
let new_recipient_account = Account {
|
||||
@@ -815,10 +822,10 @@ fn token_private_transfer() {
|
||||
definition_id: Ids::token_definition(),
|
||||
balance: transfer_amount,
|
||||
}),
|
||||
nonce: Nonce::private_account_nonce_init(&new_recipient_npk),
|
||||
nonce: Nonce::private_account_nonce_init(&new_recipient_id),
|
||||
};
|
||||
assert!(state
|
||||
.get_proof_for_commitment(&Commitment::new(&new_recipient_npk, &new_recipient_account))
|
||||
.get_proof_for_commitment(&Commitment::new(&new_recipient_id, &new_recipient_account))
|
||||
.is_some());
|
||||
}
|
||||
|
||||
@@ -833,20 +840,22 @@ fn token_deshielded_transfer() {
|
||||
let sender_npk = PrivateKeys::recipient_npk();
|
||||
let sender_nsk = PrivateKeys::recipient_nsk();
|
||||
let sender_vpk = PrivateKeys::recipient_vpk();
|
||||
let sender_id = PrivateKeys::recipient_id();
|
||||
|
||||
let public_recipient_id = Ids::recipient();
|
||||
let sender_commitment = Commitment::new(&sender_npk, &sender_account);
|
||||
let sender_commitment = Commitment::new(&sender_id, &sender_account);
|
||||
let membership_proof = state
|
||||
.get_proof_for_commitment(&sender_commitment)
|
||||
.expect("sender's commitment must be in the set");
|
||||
|
||||
let esk = [55u8; 32];
|
||||
let shared_secret = SharedSecretKey::new(&esk, &sender_vpk);
|
||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||
let shared_secret = SharedSecretKey::encapsulate_deterministic(&sender_vpk, &[0u8; 32], 0).0;
|
||||
|
||||
let public_recipient_pre = AccountWithMetadata::new(
|
||||
state.get_account_by_id(public_recipient_id),
|
||||
false,
|
||||
public_recipient_id,
|
||||
);
|
||||
let sender_pre = AccountWithMetadata::new(sender_account.clone(), true, &sender_npk);
|
||||
let sender_pre = AccountWithMetadata::new(sender_account.clone(), true, sender_id);
|
||||
|
||||
let instruction = token_core::Instruction::Transfer {
|
||||
amount_to_transfer: deshield_amount,
|
||||
@@ -854,21 +863,23 @@ fn token_deshielded_transfer() {
|
||||
let (output, proof) = execute_and_prove(
|
||||
vec![sender_pre, public_recipient_pre],
|
||||
Program::serialize_instruction(instruction).unwrap(),
|
||||
vec![1, 0],
|
||||
vec![(sender_npk, shared_secret)],
|
||||
vec![sender_nsk],
|
||||
vec![state.get_proof_for_commitment(&sender_commitment)],
|
||||
vec![
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: EncryptedAccountData::compute_view_tag(&sender_npk, &sender_vpk),
|
||||
ssk: shared_secret,
|
||||
nsk: sender_nsk,
|
||||
membership_proof,
|
||||
identifier: 0,
|
||||
},
|
||||
InputAccountIdentity::Public,
|
||||
],
|
||||
&token_program().into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![public_recipient_id],
|
||||
vec![],
|
||||
vec![(sender_npk, sender_vpk, epk)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
let message =
|
||||
Message::try_from_circuit_output(vec![public_recipient_id], vec![], output).unwrap();
|
||||
|
||||
let witness_set = WitnessSet::for_message(&message, proof, &[]);
|
||||
let tx = PrivacyPreservingTransaction::new(message, witness_set);
|
||||
@@ -890,7 +901,7 @@ fn token_deshielded_transfer() {
|
||||
);
|
||||
|
||||
let sender_nonce_after =
|
||||
Nonce::private_account_nonce_init(&sender_npk).private_account_nonce_increment(&sender_nsk);
|
||||
Nonce::private_account_nonce_init(&sender_id).private_account_nonce_increment(&sender_nsk);
|
||||
let new_sender_account = Account {
|
||||
program_owner: Ids::token_program(),
|
||||
balance: 0,
|
||||
@@ -901,6 +912,6 @@ fn token_deshielded_transfer() {
|
||||
nonce: sender_nonce_after,
|
||||
};
|
||||
assert!(state
|
||||
.get_proof_for_commitment(&Commitment::new(&sender_npk, &new_sender_account))
|
||||
.get_proof_for_commitment(&Commitment::new(&sender_id, &new_sender_account))
|
||||
.is_some());
|
||||
}
|
||||
|
||||
@@ -4,6 +4,6 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
stablecoin_core = { path = "core" }
|
||||
token_core = { path = "../token/core" }
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
borsh = { version = "1.5", features = ["derive"] }
|
||||
alloy-primitives = { version = "1", default-features = false }
|
||||
# Pin ruint (transitive via alloy-primitives) below 1.18, which raised its MSRV to rustc 1.90.
|
||||
@@ -14,4 +14,4 @@ ruint = { version = "=1.17.0", default-features = false }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
twap_oracle_core = { path = "../../twap_oracle/core" }
|
||||
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||
spel-framework-macros = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework-macros" }
|
||||
spel-framework-macros = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework-macros" }
|
||||
|
||||
+135
-1456
File diff suppressed because it is too large
Load Diff
@@ -14,8 +14,8 @@ name = "stablecoin"
|
||||
path = "src/bin/stablecoin.rs"
|
||||
|
||||
[dependencies]
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
|
||||
spel-framework = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee_core" }
|
||||
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||
twap_oracle_core = { path = "../../../twap_oracle/core" }
|
||||
stablecoin_core = { path = "../../core" }
|
||||
|
||||
@@ -7,5 +7,5 @@ edition = "2021"
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
token_core = { path = "core" }
|
||||
|
||||
@@ -7,7 +7,7 @@ edition = "2021"
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
spel-framework-macros = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework-macros" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
spel-framework-macros = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework-macros" }
|
||||
borsh = { version = "1.5", features = ["derive"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
Generated
+122
-1648
File diff suppressed because it is too large
Load Diff
@@ -56,8 +56,8 @@ name = "token"
|
||||
path = "src/bin/token.rs"
|
||||
|
||||
[dependencies]
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
|
||||
spel-framework = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee_core" }
|
||||
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||
# Pin ruint (transitive via risc0-binfmt) below 1.18, which raised its MSRV to
|
||||
# rustc 1.90. The risc0 guest toolchain ships rustc 1.88, so 1.18+ fails the
|
||||
|
||||
@@ -4,8 +4,8 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0" }
|
||||
twap_oracle_core = { path = "core" }
|
||||
|
||||
[lints]
|
||||
|
||||
@@ -7,10 +7,10 @@ edition = "2021"
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", features = ["host"], package = "lee_core" }
|
||||
borsh = { version = "1.5", features = ["derive"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
spel-framework-macros = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework-macros" }
|
||||
spel-framework-macros = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework-macros" }
|
||||
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||
uniswap_v3_math = "0.6.2"
|
||||
alloy-primitives = { version = "1", default-features = false }
|
||||
|
||||
+135
-1456
File diff suppressed because it is too large
Load Diff
@@ -14,9 +14,9 @@ name = "twap_oracle"
|
||||
path = "src/bin/twap_oracle.rs"
|
||||
|
||||
[dependencies]
|
||||
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
|
||||
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
|
||||
spel-framework = { git = "https://github.com/0x-r4bbit/spel.git", branch = "refactor/lez-v020-compat", package = "spel-framework" }
|
||||
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0", package = "lee_core" }
|
||||
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "lez-core-v0.2.0" }
|
||||
risc0-zkvm = { version = "=3.0.5", default-features = false }
|
||||
twap_oracle_core = { path = "../../core" }
|
||||
twap_oracle_program = { path = "../..", package = "twap_oracle_program" }
|
||||
|
||||
Reference in New Issue
Block a user