mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-02 13:23:10 +00:00
fix: public execution finalized
This commit is contained in:
parent
cde11e75d6
commit
c1283d4a0c
@ -2224,30 +2224,18 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
.account;
|
||||
|
||||
assert_eq!(
|
||||
user_holding_a_acc.data.as_ref(),
|
||||
&[
|
||||
1, 216, 180, 23, 229, 146, 37, 77, 185, 234, 186, 245, 33, 228, 197, 251, 244, 10,
|
||||
137, 115, 157, 2, 246, 137, 52, 234, 64, 155, 199, 101, 15, 43, 83, 4, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
u128::from_le_bytes(user_holding_a_acc.data[33..].try_into().unwrap()),
|
||||
4
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
user_holding_b_acc.data.as_ref(),
|
||||
&[
|
||||
1, 244, 191, 88, 67, 111, 12, 245, 25, 212, 169, 62, 209, 159, 73, 107, 101, 173,
|
||||
88, 13, 55, 71, 91, 113, 88, 208, 91, 136, 222, 139, 2, 97, 110, 4, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
u128::from_le_bytes(user_holding_b_acc.data[33..].try_into().unwrap()),
|
||||
4
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
user_holding_lp_acc.data.as_ref(),
|
||||
&[
|
||||
1, 16, 61, 24, 200, 168, 141, 91, 149, 164, 35, 114, 25, 6, 40, 204, 181, 95, 39,
|
||||
59, 56, 56, 96, 222, 157, 226, 48, 111, 53, 30, 1, 41, 94, 3, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
u128::from_le_bytes(user_holding_lp_acc.data[33..].try_into().unwrap()),
|
||||
3
|
||||
);
|
||||
|
||||
info!("=================== AMM DEFINITION FINISHED ===============");
|
||||
@ -2287,30 +2275,173 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
|
||||
.account;
|
||||
|
||||
assert_eq!(
|
||||
user_holding_a_acc.data.as_ref(),
|
||||
&[
|
||||
1, 216, 180, 23, 229, 146, 37, 77, 185, 234, 186, 245, 33, 228, 197, 251, 244, 10,
|
||||
137, 115, 157, 2, 246, 137, 52, 234, 64, 155, 199, 101, 15, 43, 83, 2, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
u128::from_le_bytes(user_holding_a_acc.data[33..].try_into().unwrap()),
|
||||
2
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
user_holding_b_acc.data.as_ref(),
|
||||
&[
|
||||
1, 244, 191, 88, 67, 111, 12, 245, 25, 212, 169, 62, 209, 159, 73, 107, 101, 173,
|
||||
88, 13, 55, 71, 91, 113, 88, 208, 91, 136, 222, 139, 2, 97, 110, 5, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
u128::from_le_bytes(user_holding_b_acc.data[33..].try_into().unwrap()),
|
||||
5
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
user_holding_lp_acc.data.as_ref(),
|
||||
&[
|
||||
1, 16, 61, 24, 200, 168, 141, 91, 149, 164, 35, 114, 25, 6, 40, 204, 181, 95, 39,
|
||||
59, 56, 56, 96, 222, 157, 226, 48, 111, 53, 30, 1, 41, 94, 3, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
u128::from_le_bytes(user_holding_lp_acc.data[33..].try_into().unwrap()),
|
||||
3
|
||||
);
|
||||
|
||||
info!("=================== FIRST SWAP FINISHED ===============");
|
||||
|
||||
// Make swap
|
||||
|
||||
let subcommand = AmmProgramAgnosticSubcommand::Swap {
|
||||
user_holding_a: make_public_account_input_from_str(&recipient_account_id_1.to_string()),
|
||||
user_holding_b: make_public_account_input_from_str(&recipient_account_id_2.to_string()),
|
||||
amount_in: 2,
|
||||
min_amount_out: 1,
|
||||
token_definition: definition_account_id_2.to_string(),
|
||||
};
|
||||
|
||||
wallet::cli::execute_subcommand(Command::AMM(subcommand))
|
||||
.await
|
||||
.unwrap();
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let user_holding_a_acc = seq_client
|
||||
.get_account(recipient_account_id_1.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
let user_holding_b_acc = seq_client
|
||||
.get_account(recipient_account_id_2.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
let user_holding_lp_acc = seq_client
|
||||
.get_account(user_holding_lp.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
assert_eq!(
|
||||
u128::from_le_bytes(user_holding_a_acc.data[33..].try_into().unwrap()),
|
||||
4
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
u128::from_le_bytes(user_holding_b_acc.data[33..].try_into().unwrap()),
|
||||
3
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
u128::from_le_bytes(user_holding_lp_acc.data[33..].try_into().unwrap()),
|
||||
3
|
||||
);
|
||||
|
||||
info!("=================== SECOND SWAP FINISHED ===============");
|
||||
|
||||
// Add liquidity
|
||||
|
||||
let subcommand = AmmProgramAgnosticSubcommand::AddLiquidity {
|
||||
user_holding_a: make_public_account_input_from_str(&recipient_account_id_1.to_string()),
|
||||
user_holding_b: make_public_account_input_from_str(&recipient_account_id_2.to_string()),
|
||||
user_holding_lp: make_public_account_input_from_str(&user_holding_lp.to_string()),
|
||||
min_amount_lp: 1,
|
||||
max_amount_a: 2,
|
||||
max_amount_b: 2,
|
||||
};
|
||||
|
||||
wallet::cli::execute_subcommand(Command::AMM(subcommand))
|
||||
.await
|
||||
.unwrap();
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let user_holding_a_acc = seq_client
|
||||
.get_account(recipient_account_id_1.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
let user_holding_b_acc = seq_client
|
||||
.get_account(recipient_account_id_2.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
let user_holding_lp_acc = seq_client
|
||||
.get_account(user_holding_lp.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
assert_eq!(
|
||||
u128::from_le_bytes(user_holding_a_acc.data[33..].try_into().unwrap()),
|
||||
3
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
u128::from_le_bytes(user_holding_b_acc.data[33..].try_into().unwrap()),
|
||||
1
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
u128::from_le_bytes(user_holding_lp_acc.data[33..].try_into().unwrap()),
|
||||
4
|
||||
);
|
||||
|
||||
info!("=================== ADD LIQ FINISHED ===============");
|
||||
|
||||
// Remove liquidity
|
||||
|
||||
let subcommand = AmmProgramAgnosticSubcommand::RemoveLiquidity {
|
||||
user_holding_a: make_public_account_input_from_str(&recipient_account_id_1.to_string()),
|
||||
user_holding_b: make_public_account_input_from_str(&recipient_account_id_2.to_string()),
|
||||
user_holding_lp: make_public_account_input_from_str(&user_holding_lp.to_string()),
|
||||
balance_lp: 2,
|
||||
max_amount_a: 1,
|
||||
max_amount_b: 1,
|
||||
};
|
||||
|
||||
wallet::cli::execute_subcommand(Command::AMM(subcommand))
|
||||
.await
|
||||
.unwrap();
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let user_holding_a_acc = seq_client
|
||||
.get_account(recipient_account_id_1.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
let user_holding_b_acc = seq_client
|
||||
.get_account(recipient_account_id_2.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
let user_holding_lp_acc = seq_client
|
||||
.get_account(user_holding_lp.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.account;
|
||||
|
||||
assert_eq!(
|
||||
u128::from_le_bytes(user_holding_a_acc.data[33..].try_into().unwrap()),
|
||||
5
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
u128::from_le_bytes(user_holding_b_acc.data[33..].try_into().unwrap()),
|
||||
4
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
u128::from_le_bytes(user_holding_lp_acc.data[33..].try_into().unwrap()),
|
||||
2
|
||||
);
|
||||
|
||||
info!("Success!");
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use nssa::AccountId;
|
||||
|
||||
use crate::{
|
||||
PrivacyPreservingAccount, WalletCore,
|
||||
WalletCore,
|
||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||
helperfunctions::parse_addr_with_privacy_prefix,
|
||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||
program_facades::amm::AMM,
|
||||
};
|
||||
|
||||
@ -14,6 +15,8 @@ pub enum AmmProgramAgnosticSubcommand {
|
||||
/// Produce a new token
|
||||
///
|
||||
/// user_holding_a and user_holding_b must be owned.
|
||||
///
|
||||
/// Only public execution allowed
|
||||
New {
|
||||
/// user_holding_a - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
@ -32,6 +35,8 @@ pub enum AmmProgramAgnosticSubcommand {
|
||||
/// Swap with variable privacy
|
||||
///
|
||||
/// The account associated with swapping token must be owned
|
||||
///
|
||||
/// Only public execution allowed
|
||||
Swap {
|
||||
/// user_holding_a - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
@ -50,19 +55,9 @@ pub enum AmmProgramAgnosticSubcommand {
|
||||
/// Add liquidity with variable privacy
|
||||
///
|
||||
/// user_holding_a and user_holding_b must be owned.
|
||||
///
|
||||
/// Only public execution allowed
|
||||
AddLiquidity {
|
||||
/// amm_pool - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
amm_pool: String,
|
||||
/// vault_holding_a - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
vault_holding_a: String,
|
||||
/// vault_holding_b - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
vault_holding_b: String,
|
||||
/// pool_lp - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
pool_lp: String,
|
||||
/// user_holding_a - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
user_holding_a: String,
|
||||
@ -82,19 +77,9 @@ pub enum AmmProgramAgnosticSubcommand {
|
||||
/// Remove liquidity with variable privacy
|
||||
///
|
||||
/// user_holding_lp must be owned.
|
||||
///
|
||||
/// Only public execution allowed
|
||||
RemoveLiquidity {
|
||||
/// amm_pool - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
amm_pool: String,
|
||||
/// vault_holding_a - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
vault_holding_a: String,
|
||||
/// vault_holding_b - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
vault_holding_b: String,
|
||||
/// pool_lp - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
pool_lp: String,
|
||||
/// user_holding_a - valid 32 byte base58 string with privacy prefix
|
||||
#[arg(long)]
|
||||
user_holding_a: String,
|
||||
@ -126,43 +111,43 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
balance_a,
|
||||
balance_b,
|
||||
} => {
|
||||
let user_holding_a = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?,
|
||||
)?;
|
||||
let user_holding_b = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_b)?,
|
||||
)?;
|
||||
let user_holding_lp = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_lp)?,
|
||||
)?;
|
||||
let (user_holding_a, user_holding_a_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?;
|
||||
let (user_holding_b, user_holding_b_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_b)?;
|
||||
let (user_holding_lp, user_holding_lp_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_lp)?;
|
||||
|
||||
let is_public_tx = [&user_holding_a, &user_holding_b, &user_holding_lp]
|
||||
.into_iter()
|
||||
.all(|acc| acc.is_public());
|
||||
let user_holding_a: AccountId = user_holding_a.parse()?;
|
||||
let user_holding_b: AccountId = user_holding_b.parse()?;
|
||||
let user_holding_lp: AccountId = user_holding_lp.parse()?;
|
||||
|
||||
if is_public_tx {
|
||||
AMM(wallet_core)
|
||||
.send_new_amm_definition(
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
balance_a,
|
||||
balance_b,
|
||||
)
|
||||
.await?;
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
} else {
|
||||
AMM(wallet_core)
|
||||
.send_new_amm_definition_privacy_preserving(
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
balance_a,
|
||||
balance_b,
|
||||
)
|
||||
.await?;
|
||||
// ToDo: change into correct return value
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
match (
|
||||
user_holding_a_privacy,
|
||||
user_holding_b_privacy,
|
||||
user_holding_lp_privacy,
|
||||
) {
|
||||
(
|
||||
AccountPrivacyKind::Public,
|
||||
AccountPrivacyKind::Public,
|
||||
AccountPrivacyKind::Public,
|
||||
) => {
|
||||
AMM(wallet_core)
|
||||
.send_new_amm_definition(
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
balance_a,
|
||||
balance_b,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
}
|
||||
_ => {
|
||||
// ToDo: Implement after private multi-chain calls is available
|
||||
anyhow::bail!("Only public execution allowed for AMM calls");
|
||||
}
|
||||
}
|
||||
}
|
||||
AmmProgramAgnosticSubcommand::Swap {
|
||||
@ -172,47 +157,35 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
min_amount_out,
|
||||
token_definition,
|
||||
} => {
|
||||
let user_holding_a = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?,
|
||||
)?;
|
||||
let user_holding_b = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_b)?,
|
||||
)?;
|
||||
let (user_holding_a, user_holding_a_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?;
|
||||
let (user_holding_b, user_holding_b_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_b)?;
|
||||
|
||||
let is_public_tx = [&user_holding_a, &user_holding_b]
|
||||
.into_iter()
|
||||
.all(|acc| acc.is_public());
|
||||
let user_holding_a: AccountId = user_holding_a.parse()?;
|
||||
let user_holding_b: AccountId = user_holding_b.parse()?;
|
||||
|
||||
if is_public_tx {
|
||||
AMM(wallet_core)
|
||||
.send_swap(
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
amount_in,
|
||||
min_amount_out,
|
||||
token_definition.parse()?,
|
||||
)
|
||||
.await?;
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
} else {
|
||||
AMM(wallet_core)
|
||||
.send_swap_privacy_preserving(
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
amount_in,
|
||||
min_amount_out,
|
||||
token_definition.parse()?,
|
||||
)
|
||||
.await?;
|
||||
// ToDo: change into correct return value
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
match (user_holding_a_privacy, user_holding_b_privacy) {
|
||||
(AccountPrivacyKind::Public, AccountPrivacyKind::Public) => {
|
||||
AMM(wallet_core)
|
||||
.send_swap(
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
amount_in,
|
||||
min_amount_out,
|
||||
token_definition.parse()?,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
}
|
||||
_ => {
|
||||
// ToDo: Implement after private multi-chain calls is available
|
||||
anyhow::bail!("Only public execution allowed for AMM calls");
|
||||
}
|
||||
}
|
||||
}
|
||||
AmmProgramAgnosticSubcommand::AddLiquidity {
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
@ -220,80 +193,47 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
max_amount_a,
|
||||
max_amount_b,
|
||||
} => {
|
||||
let amm_pool = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&amm_pool)?,
|
||||
)?;
|
||||
let vault_holding_a = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&vault_holding_a)?,
|
||||
)?;
|
||||
let vault_holding_b = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&vault_holding_b)?,
|
||||
)?;
|
||||
let pool_lp = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&pool_lp)?,
|
||||
)?;
|
||||
let user_holding_a = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?,
|
||||
)?;
|
||||
let user_holding_b = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_b)?,
|
||||
)?;
|
||||
let user_holding_lp = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_lp)?,
|
||||
)?;
|
||||
let (user_holding_a, user_holding_a_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?;
|
||||
let (user_holding_b, user_holding_b_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_b)?;
|
||||
let (user_holding_lp, user_holding_lp_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_lp)?;
|
||||
|
||||
let is_public_tx = [
|
||||
&amm_pool,
|
||||
&vault_holding_a,
|
||||
&vault_holding_b,
|
||||
&pool_lp,
|
||||
&user_holding_a,
|
||||
&user_holding_b,
|
||||
&user_holding_lp,
|
||||
]
|
||||
.into_iter()
|
||||
.all(|acc| acc.is_public());
|
||||
let user_holding_a: AccountId = user_holding_a.parse()?;
|
||||
let user_holding_b: AccountId = user_holding_b.parse()?;
|
||||
let user_holding_lp: AccountId = user_holding_lp.parse()?;
|
||||
|
||||
if is_public_tx {
|
||||
AMM(wallet_core)
|
||||
.send_add_liq(
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
min_amount_lp,
|
||||
max_amount_a,
|
||||
max_amount_b,
|
||||
)
|
||||
.await?;
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
} else {
|
||||
AMM(wallet_core)
|
||||
.send_add_liq_privacy_preserving(
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
min_amount_lp,
|
||||
max_amount_a,
|
||||
max_amount_b,
|
||||
)
|
||||
.await?;
|
||||
// ToDo: change into correct return value
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
match (
|
||||
user_holding_a_privacy,
|
||||
user_holding_b_privacy,
|
||||
user_holding_lp_privacy,
|
||||
) {
|
||||
(
|
||||
AccountPrivacyKind::Public,
|
||||
AccountPrivacyKind::Public,
|
||||
AccountPrivacyKind::Public,
|
||||
) => {
|
||||
AMM(wallet_core)
|
||||
.send_add_liq(
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
min_amount_lp,
|
||||
max_amount_a,
|
||||
max_amount_b,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
}
|
||||
_ => {
|
||||
// ToDo: Implement after private multi-chain calls is available
|
||||
anyhow::bail!("Only public execution allowed for AMM calls");
|
||||
}
|
||||
}
|
||||
}
|
||||
AmmProgramAgnosticSubcommand::RemoveLiquidity {
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
@ -301,73 +241,44 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
max_amount_a,
|
||||
max_amount_b,
|
||||
} => {
|
||||
let amm_pool = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&amm_pool)?,
|
||||
)?;
|
||||
let vault_holding_a = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&vault_holding_a)?,
|
||||
)?;
|
||||
let vault_holding_b = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&vault_holding_b)?,
|
||||
)?;
|
||||
let pool_lp = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&pool_lp)?,
|
||||
)?;
|
||||
let user_holding_a = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?,
|
||||
)?;
|
||||
let user_holding_b = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_b)?,
|
||||
)?;
|
||||
let user_holding_lp = PrivacyPreservingAccount::parse_with_privacy(
|
||||
parse_addr_with_privacy_prefix(&user_holding_lp)?,
|
||||
)?;
|
||||
let (user_holding_a, user_holding_a_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?;
|
||||
let (user_holding_b, user_holding_b_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_b)?;
|
||||
let (user_holding_lp, user_holding_lp_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_lp)?;
|
||||
|
||||
let is_public_tx = [
|
||||
&amm_pool,
|
||||
&vault_holding_a,
|
||||
&vault_holding_b,
|
||||
&pool_lp,
|
||||
&user_holding_a,
|
||||
&user_holding_b,
|
||||
&user_holding_lp,
|
||||
]
|
||||
.into_iter()
|
||||
.all(|acc| acc.is_public());
|
||||
let user_holding_a: AccountId = user_holding_a.parse()?;
|
||||
let user_holding_b: AccountId = user_holding_b.parse()?;
|
||||
let user_holding_lp: AccountId = user_holding_lp.parse()?;
|
||||
|
||||
if is_public_tx {
|
||||
AMM(wallet_core)
|
||||
.send_remove_liq(
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
balance_lp,
|
||||
max_amount_a,
|
||||
max_amount_b,
|
||||
)
|
||||
.await?;
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
} else {
|
||||
AMM(wallet_core)
|
||||
.send_remove_liq_privacy_preserving(
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
balance_lp,
|
||||
max_amount_a,
|
||||
max_amount_b,
|
||||
)
|
||||
.await?;
|
||||
// ToDo: change into correct return value
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
match (
|
||||
user_holding_a_privacy,
|
||||
user_holding_b_privacy,
|
||||
user_holding_lp_privacy,
|
||||
) {
|
||||
(
|
||||
AccountPrivacyKind::Public,
|
||||
AccountPrivacyKind::Public,
|
||||
AccountPrivacyKind::Public,
|
||||
) => {
|
||||
AMM(wallet_core)
|
||||
.send_remove_liq(
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
balance_lp,
|
||||
max_amount_a,
|
||||
max_amount_b,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
}
|
||||
_ => {
|
||||
// ToDo: Implement after private multi-chain calls is available
|
||||
anyhow::bail!("Only public execution allowed for AMM calls");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ use common::transaction::NSSATransaction;
|
||||
use nssa::AccountId;
|
||||
|
||||
use crate::{
|
||||
AccDecodeData::Decode,
|
||||
WalletCore,
|
||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||
@ -87,7 +88,7 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
||||
.await?;
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret, account_id)];
|
||||
let acc_decode_data = vec![Decode(secret, account_id)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
@ -328,7 +329,7 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandPrivate {
|
||||
.await?;
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret_from, from), (secret_to, to)];
|
||||
let acc_decode_data = vec![Decode(secret_from, from), Decode(secret_to, to)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
@ -372,7 +373,7 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandPrivate {
|
||||
.await?;
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret_from, from)];
|
||||
let acc_decode_data = vec![Decode(secret_from, from)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
@ -412,7 +413,7 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandShielded {
|
||||
.await?;
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret, to)];
|
||||
let acc_decode_data = vec![Decode(secret, to)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
@ -491,7 +492,7 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommand {
|
||||
.await?;
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret, from)];
|
||||
let acc_decode_data = vec![Decode(secret, from)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
|
||||
@ -3,6 +3,7 @@ use clap::Subcommand;
|
||||
use common::{PINATA_BASE58, transaction::NSSATransaction};
|
||||
|
||||
use crate::{
|
||||
AccDecodeData::Decode,
|
||||
WalletCore,
|
||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||
@ -159,7 +160,7 @@ impl WalletSubcommand for PinataProgramSubcommandPrivate {
|
||||
println!("Transaction data is {transfer_tx:?}");
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret_winner, winner_account_id)];
|
||||
let acc_decode_data = vec![Decode(secret_winner, winner_account_id)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
|
||||
@ -4,6 +4,7 @@ use common::transaction::NSSATransaction;
|
||||
use nssa::AccountId;
|
||||
|
||||
use crate::{
|
||||
AccDecodeData::Decode,
|
||||
WalletCore,
|
||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||
@ -421,8 +422,8 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![
|
||||
(secret_sender, sender_account_id),
|
||||
(secret_recipient, recipient_account_id),
|
||||
Decode(secret_sender, sender_account_id),
|
||||
Decode(secret_recipient, recipient_account_id),
|
||||
];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
@ -473,7 +474,7 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
||||
.await?;
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret_sender, sender_account_id)];
|
||||
let acc_decode_data = vec![Decode(secret_sender, sender_account_id)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
@ -521,7 +522,7 @@ impl WalletSubcommand for TokenProgramSubcommandDeshielded {
|
||||
.await?;
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret_sender, sender_account_id)];
|
||||
let acc_decode_data = vec![Decode(secret_sender, sender_account_id)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
@ -614,7 +615,7 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
||||
.await?;
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret_recipient, recipient_account_id)];
|
||||
let acc_decode_data = vec![Decode(secret_recipient, recipient_account_id)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
@ -673,8 +674,8 @@ impl WalletSubcommand for CreateNewTokenProgramSubcommand {
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![
|
||||
(secret_definition, definition_account_id),
|
||||
(secret_supply, supply_account_id),
|
||||
Decode(secret_definition, definition_account_id),
|
||||
Decode(secret_supply, supply_account_id),
|
||||
];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
@ -723,7 +724,7 @@ impl WalletSubcommand for CreateNewTokenProgramSubcommand {
|
||||
.await?;
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret_definition, definition_account_id)];
|
||||
let acc_decode_data = vec![Decode(secret_definition, definition_account_id)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
@ -771,7 +772,7 @@ impl WalletSubcommand for CreateNewTokenProgramSubcommand {
|
||||
.await?;
|
||||
|
||||
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
|
||||
let acc_decode_data = vec![(secret_supply, supply_account_id)];
|
||||
let acc_decode_data = vec![Decode(secret_supply, supply_account_id)];
|
||||
|
||||
wallet_core.decode_insert_privacy_preserving_transaction_results(
|
||||
tx,
|
||||
|
||||
@ -38,6 +38,11 @@ pub mod poller;
|
||||
mod privacy_preserving_tx;
|
||||
pub mod program_facades;
|
||||
|
||||
pub enum AccDecodeData {
|
||||
Skip,
|
||||
Decode(nssa_core::SharedSecretKey, AccountId),
|
||||
}
|
||||
|
||||
pub struct WalletCore {
|
||||
pub storage: WalletChainStore,
|
||||
pub poller: TxPoller,
|
||||
@ -218,28 +223,32 @@ impl WalletCore {
|
||||
pub fn decode_insert_privacy_preserving_transaction_results(
|
||||
&mut self,
|
||||
tx: nssa::privacy_preserving_transaction::PrivacyPreservingTransaction,
|
||||
acc_decode_data: &[(nssa_core::SharedSecretKey, AccountId)],
|
||||
acc_decode_mask: &[AccDecodeData],
|
||||
) -> Result<()> {
|
||||
for (output_index, (secret, acc_account_id)) in acc_decode_data.iter().enumerate() {
|
||||
let acc_ead = tx.message.encrypted_private_post_states[output_index].clone();
|
||||
let acc_comm = tx.message.new_commitments[output_index].clone();
|
||||
for (output_index, acc_decode_data) in acc_decode_mask.iter().enumerate() {
|
||||
match acc_decode_data {
|
||||
AccDecodeData::Decode(secret, acc_account_id) => {
|
||||
let acc_ead = tx.message.encrypted_private_post_states[output_index].clone();
|
||||
let acc_comm = tx.message.new_commitments[output_index].clone();
|
||||
|
||||
let res_acc = nssa_core::EncryptionScheme::decrypt(
|
||||
&acc_ead.ciphertext,
|
||||
secret,
|
||||
&acc_comm,
|
||||
output_index as u32,
|
||||
)
|
||||
.unwrap();
|
||||
let res_acc = nssa_core::EncryptionScheme::decrypt(
|
||||
&acc_ead.ciphertext,
|
||||
secret,
|
||||
&acc_comm,
|
||||
output_index as u32,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
println!("Received new acc {res_acc:#?}");
|
||||
println!("Received new acc {res_acc:#?}");
|
||||
|
||||
self.storage
|
||||
.insert_private_account_data(*acc_account_id, res_acc);
|
||||
self.storage
|
||||
.insert_private_account_data(*acc_account_id, res_acc);
|
||||
}
|
||||
AccDecodeData::Skip => {}
|
||||
}
|
||||
}
|
||||
|
||||
println!("Transaction data is {:?}", tx.message);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ use nssa_core::{
|
||||
encryption::{EphemeralPublicKey, IncomingViewingPublicKey},
|
||||
};
|
||||
|
||||
use crate::{WalletCore, helperfunctions::AccountPrivacyKind};
|
||||
use crate::WalletCore;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum PrivacyPreservingAccount {
|
||||
@ -21,15 +21,6 @@ pub enum PrivacyPreservingAccount {
|
||||
}
|
||||
|
||||
impl PrivacyPreservingAccount {
|
||||
pub fn parse_with_privacy(input: (String, AccountPrivacyKind)) -> Result<Self> {
|
||||
let acc_id: AccountId = input.0.parse()?;
|
||||
|
||||
match input.1 {
|
||||
AccountPrivacyKind::Public => Ok(Self::Public(acc_id)),
|
||||
AccountPrivacyKind::Private => Ok(Self::PrivateOwned(acc_id)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_public(&self) -> bool {
|
||||
matches!(&self, Self::Public(_))
|
||||
}
|
||||
|
||||
@ -1,279 +1,108 @@
|
||||
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
||||
use nssa::{AccountId, ProgramId, program::Program};
|
||||
use nssa_core::{SharedSecretKey, program::PdaSeed};
|
||||
use serde::{Serialize, ser::SerializeSeq};
|
||||
use nssa::{AccountId, program::Program};
|
||||
|
||||
use crate::{PrivacyPreservingAccount, WalletCore, cli::account::TokenHolding};
|
||||
|
||||
fn compute_pool_pda(
|
||||
amm_program_id: ProgramId,
|
||||
definition_token_a_id: AccountId,
|
||||
definition_token_b_id: AccountId,
|
||||
) -> AccountId {
|
||||
AccountId::from((
|
||||
&amm_program_id,
|
||||
&compute_pool_pda_seed(definition_token_a_id, definition_token_b_id),
|
||||
))
|
||||
}
|
||||
|
||||
fn compute_pool_pda_seed(
|
||||
definition_token_a_id: AccountId,
|
||||
definition_token_b_id: AccountId,
|
||||
) -> PdaSeed {
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
let mut i: usize = 0;
|
||||
let (token_1, token_2) = loop {
|
||||
if definition_token_a_id.value()[i] > definition_token_b_id.value()[i] {
|
||||
let token_1 = definition_token_a_id;
|
||||
let token_2 = definition_token_b_id;
|
||||
break (token_1, token_2);
|
||||
} else if definition_token_a_id.value()[i] < definition_token_b_id.value()[i] {
|
||||
let token_1 = definition_token_b_id;
|
||||
let token_2 = definition_token_a_id;
|
||||
break (token_1, token_2);
|
||||
}
|
||||
|
||||
if i == 32 {
|
||||
panic!("Definitions match");
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
};
|
||||
|
||||
let mut bytes = [0; 64];
|
||||
bytes[0..32].copy_from_slice(&token_1.to_bytes());
|
||||
bytes[32..].copy_from_slice(&token_2.to_bytes());
|
||||
|
||||
PdaSeed::new(
|
||||
Impl::hash_bytes(&bytes)
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("Hash output must be exactly 32 bytes long"),
|
||||
)
|
||||
}
|
||||
|
||||
fn compute_vault_pda(
|
||||
amm_program_id: ProgramId,
|
||||
pool_id: AccountId,
|
||||
definition_token_id: AccountId,
|
||||
) -> AccountId {
|
||||
AccountId::from((
|
||||
&amm_program_id,
|
||||
&compute_vault_pda_seed(pool_id, definition_token_id),
|
||||
))
|
||||
}
|
||||
|
||||
fn compute_vault_pda_seed(pool_id: AccountId, definition_token_id: AccountId) -> PdaSeed {
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
let mut bytes = [0; 64];
|
||||
bytes[0..32].copy_from_slice(&pool_id.to_bytes());
|
||||
bytes[32..].copy_from_slice(&definition_token_id.to_bytes());
|
||||
|
||||
PdaSeed::new(
|
||||
Impl::hash_bytes(&bytes)
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("Hash output must be exactly 32 bytes long"),
|
||||
)
|
||||
}
|
||||
|
||||
fn compute_liquidity_token_pda(amm_program_id: ProgramId, pool_id: AccountId) -> AccountId {
|
||||
AccountId::from((&amm_program_id, &compute_liquidity_token_pda_seed(pool_id)))
|
||||
}
|
||||
|
||||
fn compute_liquidity_token_pda_seed(pool_id: AccountId) -> PdaSeed {
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
let mut bytes = [0; 64];
|
||||
bytes[0..32].copy_from_slice(&pool_id.to_bytes());
|
||||
bytes[32..].copy_from_slice(&[0; 32]);
|
||||
|
||||
PdaSeed::new(
|
||||
Impl::hash_bytes(&bytes)
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("Hash output must be exactly 32 bytes long"),
|
||||
)
|
||||
}
|
||||
|
||||
struct OrphanHack65BytesInput([u32; 65]);
|
||||
|
||||
impl OrphanHack65BytesInput {
|
||||
fn expand(orig: [u8; 65]) -> Self {
|
||||
let mut res = [0u32; 65];
|
||||
|
||||
for (idx, val) in orig.into_iter().enumerate() {
|
||||
res[idx] = val as u32;
|
||||
}
|
||||
|
||||
Self(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for OrphanHack65BytesInput {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(65))?;
|
||||
for word in self.0 {
|
||||
seq.serialize_element(&word)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
struct OrphanHack49BytesInput([u32; 49]);
|
||||
|
||||
impl OrphanHack49BytesInput {
|
||||
fn expand(orig: [u8; 49]) -> Self {
|
||||
let mut res = [0u32; 49];
|
||||
|
||||
for (idx, val) in orig.into_iter().enumerate() {
|
||||
res[idx] = val as u32;
|
||||
}
|
||||
|
||||
Self(res)
|
||||
}
|
||||
|
||||
fn words(&self) -> Vec<u32> {
|
||||
self.0.to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for OrphanHack49BytesInput {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(49))?;
|
||||
for word in self.0 {
|
||||
seq.serialize_element(&word)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
use crate::{
|
||||
WalletCore,
|
||||
cli::account::TokenHolding,
|
||||
program_facades::{
|
||||
OrphanHack49BytesInput, OrphanHack65BytesInput, compute_liquidity_token_pda,
|
||||
compute_pool_pda, compute_vault_pda,
|
||||
},
|
||||
};
|
||||
|
||||
pub struct AMM<'w>(pub &'w WalletCore);
|
||||
|
||||
impl AMM<'_> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_new_amm_definition(
|
||||
&self,
|
||||
user_holding_a: PrivacyPreservingAccount,
|
||||
user_holding_b: PrivacyPreservingAccount,
|
||||
user_holding_lp: PrivacyPreservingAccount,
|
||||
user_holding_a: AccountId,
|
||||
user_holding_b: AccountId,
|
||||
user_holding_lp: AccountId,
|
||||
balance_a: u128,
|
||||
balance_b: u128,
|
||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||
let (instruction, program) = amm_program_preparation_definition(balance_a, balance_b);
|
||||
|
||||
match (user_holding_a, user_holding_b, user_holding_lp) {
|
||||
(
|
||||
PrivacyPreservingAccount::Public(user_holding_a),
|
||||
PrivacyPreservingAccount::Public(user_holding_b),
|
||||
PrivacyPreservingAccount::Public(user_holding_lp),
|
||||
) => {
|
||||
let amm_program_id = Program::amm().id();
|
||||
let amm_program_id = Program::amm().id();
|
||||
|
||||
let Ok(user_a_acc) = self.0.get_account_public(user_holding_a).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(user_a_acc) = self.0.get_account_public(user_holding_a).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
let definition_token_b_id = TokenHolding::parse(&user_b_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
let definition_token_b_id = TokenHolding::parse(&user_b_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
|
||||
let amm_pool =
|
||||
compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id);
|
||||
let vault_holding_a =
|
||||
compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id);
|
||||
let vault_holding_b =
|
||||
compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id);
|
||||
let pool_lp = compute_liquidity_token_pda(amm_program_id, amm_pool);
|
||||
let amm_pool =
|
||||
compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id);
|
||||
let vault_holding_a = compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id);
|
||||
let vault_holding_b = compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id);
|
||||
let pool_lp = compute_liquidity_token_pda(amm_program_id, amm_pool);
|
||||
|
||||
let account_ids = vec![
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
];
|
||||
let account_ids = vec![
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
];
|
||||
|
||||
let Ok(nonces) = self
|
||||
.0
|
||||
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
||||
.await
|
||||
else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(nonces) = self
|
||||
.0
|
||||
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
||||
.await
|
||||
else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let Some(signing_key_a) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_a)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
let Some(signing_key_a) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_a)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
|
||||
let Some(signing_key_b) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_b)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
let Some(signing_key_b) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_b)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
|
||||
let message = nssa::public_transaction::Message::try_new(
|
||||
program.id(),
|
||||
account_ids,
|
||||
nonces,
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
let message = nssa::public_transaction::Message::try_new(
|
||||
program.id(),
|
||||
account_ids,
|
||||
nonces,
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set = nssa::public_transaction::WitnessSet::for_message(
|
||||
&message,
|
||||
&[signing_key_a, signing_key_b],
|
||||
);
|
||||
let witness_set = nssa::public_transaction::WitnessSet::for_message(
|
||||
&message,
|
||||
&[signing_key_a, signing_key_b],
|
||||
);
|
||||
|
||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||
|
||||
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_new_amm_definition_privacy_preserving(
|
||||
&self,
|
||||
_user_holding_a: PrivacyPreservingAccount,
|
||||
_user_holding_b: PrivacyPreservingAccount,
|
||||
_user_holding_lp: PrivacyPreservingAccount,
|
||||
_balance_a: u128,
|
||||
_balance_b: u128,
|
||||
) -> Result<(SendTxResponse, [Option<SharedSecretKey>; 3]), ExecutionFailureKind> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_swap(
|
||||
&self,
|
||||
user_holding_a: PrivacyPreservingAccount,
|
||||
user_holding_b: PrivacyPreservingAccount,
|
||||
user_holding_a: AccountId,
|
||||
user_holding_b: AccountId,
|
||||
amount_in: u128,
|
||||
min_amount_out: u128,
|
||||
token_definition_id: AccountId,
|
||||
@ -281,162 +110,96 @@ impl AMM<'_> {
|
||||
let (instruction, program) =
|
||||
amm_program_preparation_swap(amount_in, min_amount_out, token_definition_id);
|
||||
|
||||
match (user_holding_a, user_holding_b) {
|
||||
(
|
||||
PrivacyPreservingAccount::Public(user_holding_a),
|
||||
PrivacyPreservingAccount::Public(user_holding_b),
|
||||
) => {
|
||||
let amm_program_id = Program::amm().id();
|
||||
let amm_program_id = Program::amm().id();
|
||||
|
||||
let Ok(user_a_acc) = self.0.get_account_public(user_holding_a).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(user_a_acc) = self.0.get_account_public(user_holding_a).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
let definition_token_b_id = TokenHolding::parse(&user_b_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
let definition_token_b_id = TokenHolding::parse(&user_b_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
|
||||
let amm_pool =
|
||||
compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id);
|
||||
let vault_holding_a =
|
||||
compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id);
|
||||
let vault_holding_b =
|
||||
compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id);
|
||||
let amm_pool =
|
||||
compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id);
|
||||
let vault_holding_a = compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id);
|
||||
let vault_holding_b = compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id);
|
||||
|
||||
let account_ids = vec![
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
];
|
||||
let account_ids = vec![
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
];
|
||||
|
||||
let account_id_auth;
|
||||
let account_id_auth;
|
||||
|
||||
// Checking, which account are associated with TokenDefinition
|
||||
let token_holder_acc_a = self
|
||||
.0
|
||||
.get_account_public(user_holding_a)
|
||||
.await
|
||||
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||
let token_holder_acc_b = self
|
||||
.0
|
||||
.get_account_public(user_holding_b)
|
||||
.await
|
||||
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||
// Checking, which account are associated with TokenDefinition
|
||||
let token_holder_acc_a = self
|
||||
.0
|
||||
.get_account_public(user_holding_a)
|
||||
.await
|
||||
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||
let token_holder_acc_b = self
|
||||
.0
|
||||
.get_account_public(user_holding_b)
|
||||
.await
|
||||
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||
|
||||
let token_holder_a = TokenHolding::parse(&token_holder_acc_a.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?;
|
||||
let token_holder_b = TokenHolding::parse(&token_holder_acc_b.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_b))?;
|
||||
let token_holder_a = TokenHolding::parse(&token_holder_acc_a.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?;
|
||||
let token_holder_b = TokenHolding::parse(&token_holder_acc_b.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_b))?;
|
||||
|
||||
if token_holder_a.definition_id == token_definition_id {
|
||||
account_id_auth = user_holding_a;
|
||||
} else if token_holder_b.definition_id == token_definition_id {
|
||||
account_id_auth = user_holding_b;
|
||||
} else {
|
||||
return Err(ExecutionFailureKind::AccountDataError(token_definition_id));
|
||||
}
|
||||
|
||||
let Ok(nonces) = self.0.get_accounts_nonces(vec![account_id_auth]).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let Some(signing_key) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&account_id_auth)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
|
||||
let message = nssa::public_transaction::Message::try_new(
|
||||
program.id(),
|
||||
account_ids,
|
||||
nonces,
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set =
|
||||
nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]);
|
||||
|
||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||
|
||||
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
if token_holder_a.definition_id == token_definition_id {
|
||||
account_id_auth = user_holding_a;
|
||||
} else if token_holder_b.definition_id == token_definition_id {
|
||||
account_id_auth = user_holding_b;
|
||||
} else {
|
||||
return Err(ExecutionFailureKind::AccountDataError(token_definition_id));
|
||||
}
|
||||
|
||||
let Ok(nonces) = self.0.get_accounts_nonces(vec![account_id_auth]).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let Some(signing_key) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&account_id_auth)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
|
||||
let message = nssa::public_transaction::Message::try_new(
|
||||
program.id(),
|
||||
account_ids,
|
||||
nonces,
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set =
|
||||
nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]);
|
||||
|
||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||
|
||||
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_swap_privacy_preserving(
|
||||
&self,
|
||||
_user_holding_a: PrivacyPreservingAccount,
|
||||
_user_holding_b: PrivacyPreservingAccount,
|
||||
_amount_in: u128,
|
||||
_min_amount_out: u128,
|
||||
_token_definition_id: AccountId,
|
||||
) -> Result<(SendTxResponse, [Option<SharedSecretKey>; 5]), ExecutionFailureKind> {
|
||||
todo!()
|
||||
// let (instruction_data, program) =
|
||||
// amm_program_preparation_swap(amount_in, min_amount_out, token_definition_id);
|
||||
|
||||
// self.0
|
||||
// .send_privacy_preserving_tx(
|
||||
// vec![
|
||||
// amm_pool.clone(),
|
||||
// vault_holding_1.clone(),
|
||||
// vault_holding_2.clone(),
|
||||
// user_holding_a.clone(),
|
||||
// user_holding_b.clone(),
|
||||
// ],
|
||||
// &instruction_data.words(),
|
||||
// &program,
|
||||
// )
|
||||
// .await
|
||||
// .map(|(resp, secrets)| {
|
||||
// let mut secrets = secrets.into_iter();
|
||||
// let mut secrets_res = [None; 5];
|
||||
|
||||
// for acc_id in [
|
||||
// amm_pool,
|
||||
// vault_holding_1,
|
||||
// vault_holding_2,
|
||||
// user_holding_a,
|
||||
// user_holding_b,
|
||||
// ]
|
||||
// .iter()
|
||||
// .enumerate()
|
||||
// {
|
||||
// if acc_id.1.is_private() {
|
||||
// let secret = secrets.next().expect("expected next secret");
|
||||
|
||||
// secrets_res[acc_id.0] = Some(secret);
|
||||
// }
|
||||
// }
|
||||
|
||||
// (resp, secrets_res)
|
||||
// })
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_add_liq(
|
||||
&self,
|
||||
amm_pool: PrivacyPreservingAccount,
|
||||
vault_holding_a: PrivacyPreservingAccount,
|
||||
vault_holding_b: PrivacyPreservingAccount,
|
||||
pool_lp: PrivacyPreservingAccount,
|
||||
user_holding_a: PrivacyPreservingAccount,
|
||||
user_holding_b: PrivacyPreservingAccount,
|
||||
user_holding_lp: PrivacyPreservingAccount,
|
||||
user_holding_a: AccountId,
|
||||
user_holding_b: AccountId,
|
||||
user_holding_lp: AccountId,
|
||||
min_amount_lp: u128,
|
||||
max_amount_a: u128,
|
||||
max_amount_b: u128,
|
||||
@ -444,7 +207,29 @@ impl AMM<'_> {
|
||||
let (instruction, program) =
|
||||
amm_program_preparation_add_liq(min_amount_lp, max_amount_a, max_amount_b);
|
||||
|
||||
match (
|
||||
let amm_program_id = Program::amm().id();
|
||||
|
||||
let Ok(user_a_acc) = self.0.get_account_public(user_holding_a).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
let definition_token_b_id = TokenHolding::parse(&user_b_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
|
||||
let amm_pool =
|
||||
compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id);
|
||||
let vault_holding_a = compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id);
|
||||
let vault_holding_b = compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id);
|
||||
let pool_lp = compute_liquidity_token_pda(amm_program_id, amm_pool);
|
||||
|
||||
let account_ids = vec![
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
@ -452,142 +237,57 @@ impl AMM<'_> {
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
) {
|
||||
(
|
||||
PrivacyPreservingAccount::Public(amm_pool),
|
||||
PrivacyPreservingAccount::Public(vault_holding_a),
|
||||
PrivacyPreservingAccount::Public(vault_holding_b),
|
||||
PrivacyPreservingAccount::Public(pool_lp),
|
||||
PrivacyPreservingAccount::Public(user_holding_a),
|
||||
PrivacyPreservingAccount::Public(user_holding_b),
|
||||
PrivacyPreservingAccount::Public(user_holding_lp),
|
||||
) => {
|
||||
let account_ids = vec![
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
];
|
||||
];
|
||||
|
||||
let Ok(nonces) = self
|
||||
.0
|
||||
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
||||
.await
|
||||
else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let Some(signing_key_a) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_a)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
|
||||
let Some(signing_key_b) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_b)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
|
||||
let message = nssa::public_transaction::Message::try_new(
|
||||
program.id(),
|
||||
account_ids,
|
||||
nonces,
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set = nssa::public_transaction::WitnessSet::for_message(
|
||||
&message,
|
||||
&[signing_key_a, signing_key_b],
|
||||
);
|
||||
|
||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||
|
||||
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_add_liq_privacy_preserving(
|
||||
&self,
|
||||
amm_pool: PrivacyPreservingAccount,
|
||||
vault_holding_a: PrivacyPreservingAccount,
|
||||
vault_holding_b: PrivacyPreservingAccount,
|
||||
pool_lp: PrivacyPreservingAccount,
|
||||
user_holding_a: PrivacyPreservingAccount,
|
||||
user_holding_b: PrivacyPreservingAccount,
|
||||
user_holding_lp: PrivacyPreservingAccount,
|
||||
min_amount_lp: u128,
|
||||
max_amount_a: u128,
|
||||
max_amount_b: u128,
|
||||
) -> Result<(SendTxResponse, [Option<SharedSecretKey>; 7]), ExecutionFailureKind> {
|
||||
let (instruction_data, program) =
|
||||
amm_program_preparation_add_liq(min_amount_lp, max_amount_a, max_amount_b);
|
||||
|
||||
self.0
|
||||
.send_privacy_preserving_tx(
|
||||
vec![
|
||||
amm_pool.clone(),
|
||||
vault_holding_a.clone(),
|
||||
vault_holding_b.clone(),
|
||||
pool_lp.clone(),
|
||||
user_holding_a.clone(),
|
||||
user_holding_b.clone(),
|
||||
user_holding_lp.clone(),
|
||||
],
|
||||
&instruction_data.words(),
|
||||
&program,
|
||||
)
|
||||
let Ok(nonces) = self
|
||||
.0
|
||||
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
||||
.await
|
||||
.map(|(resp, secrets)| {
|
||||
let mut secrets = secrets.into_iter();
|
||||
let mut secrets_res = [None; 7];
|
||||
else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
for acc_id in [
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
]
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
if acc_id.1.is_private() {
|
||||
let secret = secrets.next().expect("expected next secret");
|
||||
let Some(signing_key_a) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_a)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
|
||||
secrets_res[acc_id.0] = Some(secret);
|
||||
}
|
||||
}
|
||||
let Some(signing_key_b) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_b)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
|
||||
(resp, secrets_res)
|
||||
})
|
||||
let message = nssa::public_transaction::Message::try_new(
|
||||
program.id(),
|
||||
account_ids,
|
||||
nonces,
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let witness_set = nssa::public_transaction::WitnessSet::for_message(
|
||||
&message,
|
||||
&[signing_key_a, signing_key_b],
|
||||
);
|
||||
|
||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||
|
||||
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_remove_liq(
|
||||
&self,
|
||||
amm_pool: PrivacyPreservingAccount,
|
||||
vault_holding_a: PrivacyPreservingAccount,
|
||||
vault_holding_b: PrivacyPreservingAccount,
|
||||
pool_lp: PrivacyPreservingAccount,
|
||||
user_holding_a: PrivacyPreservingAccount,
|
||||
user_holding_b: PrivacyPreservingAccount,
|
||||
user_holding_lp: PrivacyPreservingAccount,
|
||||
user_holding_a: AccountId,
|
||||
user_holding_b: AccountId,
|
||||
user_holding_lp: AccountId,
|
||||
balance_lp: u128,
|
||||
max_amount_a: u128,
|
||||
max_amount_b: u128,
|
||||
@ -595,7 +295,29 @@ impl AMM<'_> {
|
||||
let (instruction, program) =
|
||||
amm_program_preparation_remove_liq(balance_lp, max_amount_a, max_amount_b);
|
||||
|
||||
match (
|
||||
let amm_program_id = Program::amm().id();
|
||||
|
||||
let Ok(user_a_acc) = self.0.get_account_public(user_holding_a).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
let definition_token_b_id = TokenHolding::parse(&user_b_acc.data)
|
||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||
.definition_id;
|
||||
|
||||
let amm_pool =
|
||||
compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id);
|
||||
let vault_holding_a = compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id);
|
||||
let vault_holding_b = compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id);
|
||||
let pool_lp = compute_liquidity_token_pda(amm_program_id, amm_pool);
|
||||
|
||||
let account_ids = vec![
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
@ -603,134 +325,38 @@ impl AMM<'_> {
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
) {
|
||||
(
|
||||
PrivacyPreservingAccount::Public(amm_pool),
|
||||
PrivacyPreservingAccount::Public(vault_holding_a),
|
||||
PrivacyPreservingAccount::Public(vault_holding_b),
|
||||
PrivacyPreservingAccount::Public(pool_lp),
|
||||
PrivacyPreservingAccount::Public(user_holding_a),
|
||||
PrivacyPreservingAccount::Public(user_holding_b),
|
||||
PrivacyPreservingAccount::Public(user_holding_lp),
|
||||
) => {
|
||||
let account_ids = vec![
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
];
|
||||
];
|
||||
|
||||
let Ok(nonces) = self
|
||||
.0
|
||||
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
||||
.await
|
||||
else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
let Ok(nonces) = self.0.get_accounts_nonces(vec![user_holding_lp]).await else {
|
||||
return Err(ExecutionFailureKind::SequencerError);
|
||||
};
|
||||
|
||||
let Some(signing_key_a) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_a)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
let Some(signing_key_lp) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_lp)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
|
||||
let Some(signing_key_b) = self
|
||||
.0
|
||||
.storage
|
||||
.user_data
|
||||
.get_pub_account_signing_key(&user_holding_b)
|
||||
else {
|
||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||
};
|
||||
let message = nssa::public_transaction::Message::try_new(
|
||||
program.id(),
|
||||
account_ids,
|
||||
nonces,
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let message = nssa::public_transaction::Message::try_new(
|
||||
program.id(),
|
||||
account_ids,
|
||||
nonces,
|
||||
instruction,
|
||||
)
|
||||
.unwrap();
|
||||
let witness_set =
|
||||
nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key_lp]);
|
||||
|
||||
let witness_set = nssa::public_transaction::WitnessSet::for_message(
|
||||
&message,
|
||||
&[signing_key_a, signing_key_b],
|
||||
);
|
||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||
|
||||
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||
|
||||
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn send_remove_liq_privacy_preserving(
|
||||
&self,
|
||||
amm_pool: PrivacyPreservingAccount,
|
||||
vault_holding_a: PrivacyPreservingAccount,
|
||||
vault_holding_b: PrivacyPreservingAccount,
|
||||
pool_lp: PrivacyPreservingAccount,
|
||||
user_holding_a: PrivacyPreservingAccount,
|
||||
user_holding_b: PrivacyPreservingAccount,
|
||||
user_holding_lp: PrivacyPreservingAccount,
|
||||
balance_lp: u128,
|
||||
max_amount_a: u128,
|
||||
max_amount_b: u128,
|
||||
) -> Result<(SendTxResponse, [Option<SharedSecretKey>; 7]), ExecutionFailureKind> {
|
||||
let (instruction_data, program) =
|
||||
amm_program_preparation_remove_liq(balance_lp, max_amount_a, max_amount_b);
|
||||
|
||||
self.0
|
||||
.send_privacy_preserving_tx(
|
||||
vec![
|
||||
amm_pool.clone(),
|
||||
vault_holding_a.clone(),
|
||||
vault_holding_b.clone(),
|
||||
pool_lp.clone(),
|
||||
user_holding_a.clone(),
|
||||
user_holding_b.clone(),
|
||||
user_holding_lp.clone(),
|
||||
],
|
||||
&instruction_data.words(),
|
||||
&program,
|
||||
)
|
||||
.await
|
||||
.map(|(resp, secrets)| {
|
||||
let mut secrets = secrets.into_iter();
|
||||
let mut secrets_res = [None; 7];
|
||||
|
||||
for acc_id in [
|
||||
amm_pool,
|
||||
vault_holding_a,
|
||||
vault_holding_b,
|
||||
pool_lp,
|
||||
user_holding_a,
|
||||
user_holding_b,
|
||||
user_holding_lp,
|
||||
]
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
if acc_id.1.is_private() {
|
||||
let secret = secrets.next().expect("expected next secret");
|
||||
|
||||
secrets_res[acc_id.0] = Some(secret);
|
||||
}
|
||||
}
|
||||
|
||||
(resp, secrets_res)
|
||||
})
|
||||
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn amm_program_preparation_definition(
|
||||
balance_a: u128,
|
||||
balance_b: u128,
|
||||
|
||||
@ -1,7 +1,142 @@
|
||||
//! This module contains [`WalletCore`](crate::WalletCore) facades for interacting with various
|
||||
//! on-chain programs.
|
||||
|
||||
use nssa::{AccountId, ProgramId};
|
||||
use nssa_core::program::PdaSeed;
|
||||
use serde::{Serialize, ser::SerializeSeq};
|
||||
|
||||
pub mod amm;
|
||||
pub mod native_token_transfer;
|
||||
pub mod pinata;
|
||||
pub mod token;
|
||||
|
||||
fn compute_pool_pda(
|
||||
amm_program_id: ProgramId,
|
||||
definition_token_a_id: AccountId,
|
||||
definition_token_b_id: AccountId,
|
||||
) -> AccountId {
|
||||
AccountId::from((
|
||||
&amm_program_id,
|
||||
&compute_pool_pda_seed(definition_token_a_id, definition_token_b_id),
|
||||
))
|
||||
}
|
||||
|
||||
fn compute_pool_pda_seed(
|
||||
definition_token_a_id: AccountId,
|
||||
definition_token_b_id: AccountId,
|
||||
) -> PdaSeed {
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
let mut i: usize = 0;
|
||||
let (token_1, token_2) = loop {
|
||||
if definition_token_a_id.value()[i] > definition_token_b_id.value()[i] {
|
||||
let token_1 = definition_token_a_id;
|
||||
let token_2 = definition_token_b_id;
|
||||
break (token_1, token_2);
|
||||
} else if definition_token_a_id.value()[i] < definition_token_b_id.value()[i] {
|
||||
let token_1 = definition_token_b_id;
|
||||
let token_2 = definition_token_a_id;
|
||||
break (token_1, token_2);
|
||||
}
|
||||
|
||||
if i == 32 {
|
||||
panic!("Definitions match");
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
};
|
||||
|
||||
let mut bytes = [0; 64];
|
||||
bytes[0..32].copy_from_slice(&token_1.to_bytes());
|
||||
bytes[32..].copy_from_slice(&token_2.to_bytes());
|
||||
|
||||
PdaSeed::new(
|
||||
Impl::hash_bytes(&bytes)
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("Hash output must be exactly 32 bytes long"),
|
||||
)
|
||||
}
|
||||
|
||||
fn compute_vault_pda(
|
||||
amm_program_id: ProgramId,
|
||||
pool_id: AccountId,
|
||||
definition_token_id: AccountId,
|
||||
) -> AccountId {
|
||||
AccountId::from((
|
||||
&amm_program_id,
|
||||
&compute_vault_pda_seed(pool_id, definition_token_id),
|
||||
))
|
||||
}
|
||||
|
||||
fn compute_vault_pda_seed(pool_id: AccountId, definition_token_id: AccountId) -> PdaSeed {
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
let mut bytes = [0; 64];
|
||||
bytes[0..32].copy_from_slice(&pool_id.to_bytes());
|
||||
bytes[32..].copy_from_slice(&definition_token_id.to_bytes());
|
||||
|
||||
PdaSeed::new(
|
||||
Impl::hash_bytes(&bytes)
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("Hash output must be exactly 32 bytes long"),
|
||||
)
|
||||
}
|
||||
|
||||
fn compute_liquidity_token_pda(amm_program_id: ProgramId, pool_id: AccountId) -> AccountId {
|
||||
AccountId::from((&amm_program_id, &compute_liquidity_token_pda_seed(pool_id)))
|
||||
}
|
||||
|
||||
fn compute_liquidity_token_pda_seed(pool_id: AccountId) -> PdaSeed {
|
||||
use risc0_zkvm::sha::{Impl, Sha256};
|
||||
|
||||
let mut bytes = [0; 64];
|
||||
bytes[0..32].copy_from_slice(&pool_id.to_bytes());
|
||||
bytes[32..].copy_from_slice(&[0; 32]);
|
||||
|
||||
PdaSeed::new(
|
||||
Impl::hash_bytes(&bytes)
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.expect("Hash output must be exactly 32 bytes long"),
|
||||
)
|
||||
}
|
||||
|
||||
/// Why it is necessary:
|
||||
///
|
||||
/// Serialize implemented only for `[u8; N]` where `N<=32` and orphan rules would disallow custom
|
||||
/// Serialize impls for them.
|
||||
///
|
||||
/// Additionally, RISC0 splits instructions into words of 4-byte size which glues bytes for custom
|
||||
/// structs so we need to expand each byte into `u32` to preserve shape, because AMM awaits
|
||||
/// `Vec<u8>` as instruction.
|
||||
struct OrphanHackNBytesInput<const N: usize>([u32; N]);
|
||||
|
||||
impl<const N: usize> OrphanHackNBytesInput<N> {
|
||||
fn expand(orig: [u8; N]) -> Self {
|
||||
let mut res = [0u32; N];
|
||||
|
||||
for (idx, val) in orig.into_iter().enumerate() {
|
||||
res[idx] = val as u32;
|
||||
}
|
||||
|
||||
Self(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Serialize for OrphanHackNBytesInput<N> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(N))?;
|
||||
for word in self.0 {
|
||||
seq.serialize_element(&word)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
type OrphanHack65BytesInput = OrphanHackNBytesInput<65>;
|
||||
type OrphanHack49BytesInput = OrphanHackNBytesInput<49>;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user