mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-07 15:53:14 +00:00
fix: suggestions fix
This commit is contained in:
parent
d427d49c65
commit
4f15237446
@ -36,7 +36,7 @@ impl Message {
|
|||||||
program_id: ProgramId,
|
program_id: ProgramId,
|
||||||
account_ids: Vec<AccountId>,
|
account_ids: Vec<AccountId>,
|
||||||
nonces: Vec<Nonce>,
|
nonces: Vec<Nonce>,
|
||||||
instruction_data: Vec<u32>,
|
instruction_data: InstructionData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
program_id,
|
program_id,
|
||||||
|
|||||||
@ -3,70 +3,15 @@ use base58::ToBase58;
|
|||||||
use clap::Subcommand;
|
use clap::Subcommand;
|
||||||
use itertools::Itertools as _;
|
use itertools::Itertools as _;
|
||||||
use key_protocol::key_management::key_tree::chain_index::ChainIndex;
|
use key_protocol::key_management::key_tree::chain_index::ChainIndex;
|
||||||
use nssa::{Account, AccountId, program::Program};
|
use nssa::{Account, program::Program};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
WalletCore,
|
TokenDefinition, TokenHolding, WalletCore,
|
||||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||||
helperfunctions::{AccountPrivacyKind, HumanReadableAccount, parse_addr_with_privacy_prefix},
|
helperfunctions::{AccountPrivacyKind, HumanReadableAccount, parse_addr_with_privacy_prefix},
|
||||||
};
|
};
|
||||||
|
|
||||||
const TOKEN_DEFINITION_TYPE: u8 = 0;
|
|
||||||
const TOKEN_DEFINITION_DATA_SIZE: usize = 23;
|
|
||||||
|
|
||||||
const TOKEN_HOLDING_TYPE: u8 = 1;
|
|
||||||
const TOKEN_HOLDING_DATA_SIZE: usize = 49;
|
|
||||||
|
|
||||||
struct TokenDefinition {
|
|
||||||
#[allow(unused)]
|
|
||||||
account_type: u8,
|
|
||||||
name: [u8; 6],
|
|
||||||
total_supply: u128,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TokenHolding {
|
|
||||||
#[allow(unused)]
|
|
||||||
account_type: u8,
|
|
||||||
pub definition_id: AccountId,
|
|
||||||
balance: u128,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TokenDefinition {
|
|
||||||
fn parse(data: &[u8]) -> Option<Self> {
|
|
||||||
if data.len() != TOKEN_DEFINITION_DATA_SIZE || data[0] != TOKEN_DEFINITION_TYPE {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let account_type = data[0];
|
|
||||||
let name = data[1..7].try_into().unwrap();
|
|
||||||
let total_supply = u128::from_le_bytes(data[7..].try_into().unwrap());
|
|
||||||
|
|
||||||
Some(Self {
|
|
||||||
account_type,
|
|
||||||
name,
|
|
||||||
total_supply,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TokenHolding {
|
|
||||||
pub fn parse(data: &[u8]) -> Option<Self> {
|
|
||||||
if data.len() != TOKEN_HOLDING_DATA_SIZE || data[0] != TOKEN_HOLDING_TYPE {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let account_type = data[0];
|
|
||||||
let definition_id = AccountId::new(data[1..33].try_into().unwrap());
|
|
||||||
let balance = u128::from_le_bytes(data[33..].try_into().unwrap());
|
|
||||||
Some(Self {
|
|
||||||
definition_id,
|
|
||||||
balance,
|
|
||||||
account_type,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents generic chain CLI subcommand
|
/// Represents generic chain CLI subcommand
|
||||||
#[derive(Subcommand, Debug, Clone)]
|
#[derive(Subcommand, Debug, Clone)]
|
||||||
pub enum AccountSubcommand {
|
pub enum AccountSubcommand {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use crate::{
|
|||||||
WalletCore,
|
WalletCore,
|
||||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||||
program_facades::amm::AMM,
|
program_facades::amm::Amm,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents generic CLI subcommand for a wallet working with amm program
|
/// Represents generic CLI subcommand for a wallet working with amm program
|
||||||
@ -32,7 +32,7 @@ pub enum AmmProgramAgnosticSubcommand {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
balance_b: u128,
|
balance_b: u128,
|
||||||
},
|
},
|
||||||
/// Swap with variable privacy
|
/// Swap
|
||||||
///
|
///
|
||||||
/// The account associated with swapping token must be owned
|
/// The account associated with swapping token must be owned
|
||||||
///
|
///
|
||||||
@ -52,7 +52,7 @@ pub enum AmmProgramAgnosticSubcommand {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
token_definition: String,
|
token_definition: String,
|
||||||
},
|
},
|
||||||
/// Add liquidity with variable privacy
|
/// Add liquidity
|
||||||
///
|
///
|
||||||
/// user_holding_a and user_holding_b must be owned.
|
/// user_holding_a and user_holding_b must be owned.
|
||||||
///
|
///
|
||||||
@ -74,7 +74,7 @@ pub enum AmmProgramAgnosticSubcommand {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
max_amount_b: u128,
|
max_amount_b: u128,
|
||||||
},
|
},
|
||||||
/// Remove liquidity with variable privacy
|
/// Remove liquidity
|
||||||
///
|
///
|
||||||
/// user_holding_lp must be owned.
|
/// user_holding_lp must be owned.
|
||||||
///
|
///
|
||||||
@ -132,8 +132,8 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
|||||||
AccountPrivacyKind::Public,
|
AccountPrivacyKind::Public,
|
||||||
AccountPrivacyKind::Public,
|
AccountPrivacyKind::Public,
|
||||||
) => {
|
) => {
|
||||||
AMM(wallet_core)
|
Amm(wallet_core)
|
||||||
.send_new_amm_definition(
|
.send_new_definition(
|
||||||
user_holding_a,
|
user_holding_a,
|
||||||
user_holding_b,
|
user_holding_b,
|
||||||
user_holding_lp,
|
user_holding_lp,
|
||||||
@ -146,7 +146,7 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// ToDo: Implement after private multi-chain calls is available
|
// ToDo: Implement after private multi-chain calls is available
|
||||||
anyhow::bail!("Only public execution allowed for AMM calls");
|
anyhow::bail!("Only public execution allowed for Amm calls");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
|||||||
|
|
||||||
match (user_holding_a_privacy, user_holding_b_privacy) {
|
match (user_holding_a_privacy, user_holding_b_privacy) {
|
||||||
(AccountPrivacyKind::Public, AccountPrivacyKind::Public) => {
|
(AccountPrivacyKind::Public, AccountPrivacyKind::Public) => {
|
||||||
AMM(wallet_core)
|
Amm(wallet_core)
|
||||||
.send_swap(
|
.send_swap(
|
||||||
user_holding_a,
|
user_holding_a,
|
||||||
user_holding_b,
|
user_holding_b,
|
||||||
@ -181,7 +181,7 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// ToDo: Implement after private multi-chain calls is available
|
// ToDo: Implement after private multi-chain calls is available
|
||||||
anyhow::bail!("Only public execution allowed for AMM calls");
|
anyhow::bail!("Only public execution allowed for Amm calls");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,8 +214,8 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
|||||||
AccountPrivacyKind::Public,
|
AccountPrivacyKind::Public,
|
||||||
AccountPrivacyKind::Public,
|
AccountPrivacyKind::Public,
|
||||||
) => {
|
) => {
|
||||||
AMM(wallet_core)
|
Amm(wallet_core)
|
||||||
.send_add_liq(
|
.send_add_liquidity(
|
||||||
user_holding_a,
|
user_holding_a,
|
||||||
user_holding_b,
|
user_holding_b,
|
||||||
user_holding_lp,
|
user_holding_lp,
|
||||||
@ -229,7 +229,7 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// ToDo: Implement after private multi-chain calls is available
|
// ToDo: Implement after private multi-chain calls is available
|
||||||
anyhow::bail!("Only public execution allowed for AMM calls");
|
anyhow::bail!("Only public execution allowed for Amm calls");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,8 +262,8 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
|||||||
AccountPrivacyKind::Public,
|
AccountPrivacyKind::Public,
|
||||||
AccountPrivacyKind::Public,
|
AccountPrivacyKind::Public,
|
||||||
) => {
|
) => {
|
||||||
AMM(wallet_core)
|
Amm(wallet_core)
|
||||||
.send_remove_liq(
|
.send_remove_liquidity(
|
||||||
user_holding_a,
|
user_holding_a,
|
||||||
user_holding_b,
|
user_holding_b,
|
||||||
user_holding_lp,
|
user_holding_lp,
|
||||||
@ -277,7 +277,7 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// ToDo: Implement after private multi-chain calls is available
|
// ToDo: Implement after private multi-chain calls is available
|
||||||
anyhow::bail!("Only public execution allowed for AMM calls");
|
anyhow::bail!("Only public execution allowed for Amm calls");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,6 +43,60 @@ pub enum AccDecodeData {
|
|||||||
Decode(nssa_core::SharedSecretKey, AccountId),
|
Decode(nssa_core::SharedSecretKey, AccountId),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TOKEN_DEFINITION_TYPE: u8 = 0;
|
||||||
|
const TOKEN_DEFINITION_DATA_SIZE: usize = 23;
|
||||||
|
|
||||||
|
const TOKEN_HOLDING_TYPE: u8 = 1;
|
||||||
|
const TOKEN_HOLDING_DATA_SIZE: usize = 49;
|
||||||
|
|
||||||
|
struct TokenDefinition {
|
||||||
|
#[allow(unused)]
|
||||||
|
account_type: u8,
|
||||||
|
name: [u8; 6],
|
||||||
|
total_supply: u128,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TokenHolding {
|
||||||
|
pub account_type: u8,
|
||||||
|
pub definition_id: AccountId,
|
||||||
|
pub balance: u128,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TokenDefinition {
|
||||||
|
fn parse(data: &[u8]) -> Option<Self> {
|
||||||
|
if data.len() != TOKEN_DEFINITION_DATA_SIZE || data[0] != TOKEN_DEFINITION_TYPE {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let account_type = data[0];
|
||||||
|
let name = data[1..7].try_into().unwrap();
|
||||||
|
let total_supply = u128::from_le_bytes(data[7..].try_into().unwrap());
|
||||||
|
|
||||||
|
Some(Self {
|
||||||
|
account_type,
|
||||||
|
name,
|
||||||
|
total_supply,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TokenHolding {
|
||||||
|
pub fn parse(data: &[u8]) -> Option<Self> {
|
||||||
|
if data.len() != TOKEN_HOLDING_DATA_SIZE || data[0] != TOKEN_HOLDING_TYPE {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let account_type = data[0];
|
||||||
|
let definition_id = AccountId::new(data[1..33].try_into().unwrap());
|
||||||
|
let balance = u128::from_le_bytes(data[33..].try_into().unwrap());
|
||||||
|
Some(Self {
|
||||||
|
definition_id,
|
||||||
|
balance,
|
||||||
|
account_type,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WalletCore {
|
pub struct WalletCore {
|
||||||
pub storage: WalletChainStore,
|
pub storage: WalletChainStore,
|
||||||
pub poller: TxPoller,
|
pub poller: TxPoller,
|
||||||
|
|||||||
@ -1,19 +1,109 @@
|
|||||||
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
|
||||||
use nssa::{AccountId, program::Program};
|
use nssa::{AccountId, ProgramId, program::Program};
|
||||||
|
use nssa_core::program::PdaSeed;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
WalletCore,
|
TokenHolding, WalletCore,
|
||||||
cli::account::TokenHolding,
|
program_facades::{OrphanHack49BytesInput, OrphanHack65BytesInput},
|
||||||
program_facades::{
|
|
||||||
OrphanHack49BytesInput, OrphanHack65BytesInput, compute_liquidity_token_pda,
|
|
||||||
compute_pool_pda, compute_vault_pda,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct AMM<'w>(pub &'w WalletCore);
|
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),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
impl AMM<'_> {
|
fn compute_pool_pda_seed(
|
||||||
pub async fn send_new_amm_definition(
|
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"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Amm<'w>(pub &'w WalletCore);
|
||||||
|
|
||||||
|
impl Amm<'_> {
|
||||||
|
pub async fn send_new_definition(
|
||||||
&self,
|
&self,
|
||||||
user_holding_a: AccountId,
|
user_holding_a: AccountId,
|
||||||
user_holding_b: AccountId,
|
user_holding_b: AccountId,
|
||||||
@ -25,12 +115,16 @@ impl AMM<'_> {
|
|||||||
|
|
||||||
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 {
|
let user_a_acc = self
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
.0
|
||||||
};
|
.get_account_public(user_holding_a)
|
||||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
.await
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
};
|
let user_b_acc = self
|
||||||
|
.0
|
||||||
|
.get_account_public(user_holding_b)
|
||||||
|
.await
|
||||||
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
|
|
||||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||||
@ -55,31 +149,25 @@ impl AMM<'_> {
|
|||||||
user_holding_lp,
|
user_holding_lp,
|
||||||
];
|
];
|
||||||
|
|
||||||
let Ok(nonces) = self
|
let nonces = self
|
||||||
.0
|
.0
|
||||||
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
||||||
.await
|
.await
|
||||||
else {
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(signing_key_a) = self
|
let signing_key_a = self
|
||||||
.0
|
.0
|
||||||
.storage
|
.storage
|
||||||
.user_data
|
.user_data
|
||||||
.get_pub_account_signing_key(&user_holding_a)
|
.get_pub_account_signing_key(&user_holding_a)
|
||||||
else {
|
.ok_or(ExecutionFailureKind::KeyNotFoundError)?;
|
||||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(signing_key_b) = self
|
let signing_key_b = self
|
||||||
.0
|
.0
|
||||||
.storage
|
.storage
|
||||||
.user_data
|
.user_data
|
||||||
.get_pub_account_signing_key(&user_holding_b)
|
.get_pub_account_signing_key(&user_holding_b)
|
||||||
else {
|
.ok_or(ExecutionFailureKind::KeyNotFoundError)?;
|
||||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
|
||||||
};
|
|
||||||
|
|
||||||
let message = nssa::public_transaction::Message::try_new(
|
let message = nssa::public_transaction::Message::try_new(
|
||||||
program.id(),
|
program.id(),
|
||||||
@ -112,12 +200,16 @@ impl AMM<'_> {
|
|||||||
|
|
||||||
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 {
|
let user_a_acc = self
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
.0
|
||||||
};
|
.get_account_public(user_holding_a)
|
||||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
.await
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
};
|
let user_b_acc = self
|
||||||
|
.0
|
||||||
|
.get_account_public(user_holding_b)
|
||||||
|
.await
|
||||||
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
|
|
||||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||||
@ -166,18 +258,18 @@ impl AMM<'_> {
|
|||||||
return Err(ExecutionFailureKind::AccountDataError(token_definition_id));
|
return Err(ExecutionFailureKind::AccountDataError(token_definition_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
let Ok(nonces) = self.0.get_accounts_nonces(vec![account_id_auth]).await else {
|
let nonces = self
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
.0
|
||||||
};
|
.get_accounts_nonces(vec![account_id_auth])
|
||||||
|
.await
|
||||||
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
|
|
||||||
let Some(signing_key) = self
|
let signing_key = self
|
||||||
.0
|
.0
|
||||||
.storage
|
.storage
|
||||||
.user_data
|
.user_data
|
||||||
.get_pub_account_signing_key(&account_id_auth)
|
.get_pub_account_signing_key(&account_id_auth)
|
||||||
else {
|
.ok_or(ExecutionFailureKind::KeyNotFoundError)?;
|
||||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
|
||||||
};
|
|
||||||
|
|
||||||
let message = nssa::public_transaction::Message::try_new(
|
let message = nssa::public_transaction::Message::try_new(
|
||||||
program.id(),
|
program.id(),
|
||||||
@ -195,7 +287,7 @@ impl AMM<'_> {
|
|||||||
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_add_liq(
|
pub async fn send_add_liquidity(
|
||||||
&self,
|
&self,
|
||||||
user_holding_a: AccountId,
|
user_holding_a: AccountId,
|
||||||
user_holding_b: AccountId,
|
user_holding_b: AccountId,
|
||||||
@ -209,12 +301,16 @@ impl AMM<'_> {
|
|||||||
|
|
||||||
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 {
|
let user_a_acc = self
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
.0
|
||||||
};
|
.get_account_public(user_holding_a)
|
||||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
.await
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
};
|
let user_b_acc = self
|
||||||
|
.0
|
||||||
|
.get_account_public(user_holding_b)
|
||||||
|
.await
|
||||||
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
|
|
||||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||||
@ -239,31 +335,25 @@ impl AMM<'_> {
|
|||||||
user_holding_lp,
|
user_holding_lp,
|
||||||
];
|
];
|
||||||
|
|
||||||
let Ok(nonces) = self
|
let nonces = self
|
||||||
.0
|
.0
|
||||||
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
.get_accounts_nonces(vec![user_holding_a, user_holding_b])
|
||||||
.await
|
.await
|
||||||
else {
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(signing_key_a) = self
|
let signing_key_a = self
|
||||||
.0
|
.0
|
||||||
.storage
|
.storage
|
||||||
.user_data
|
.user_data
|
||||||
.get_pub_account_signing_key(&user_holding_a)
|
.get_pub_account_signing_key(&user_holding_a)
|
||||||
else {
|
.ok_or(ExecutionFailureKind::KeyNotFoundError)?;
|
||||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(signing_key_b) = self
|
let signing_key_b = self
|
||||||
.0
|
.0
|
||||||
.storage
|
.storage
|
||||||
.user_data
|
.user_data
|
||||||
.get_pub_account_signing_key(&user_holding_b)
|
.get_pub_account_signing_key(&user_holding_b)
|
||||||
else {
|
.ok_or(ExecutionFailureKind::KeyNotFoundError)?;
|
||||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
|
||||||
};
|
|
||||||
|
|
||||||
let message = nssa::public_transaction::Message::try_new(
|
let message = nssa::public_transaction::Message::try_new(
|
||||||
program.id(),
|
program.id(),
|
||||||
@ -283,7 +373,7 @@ impl AMM<'_> {
|
|||||||
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_remove_liq(
|
pub async fn send_remove_liquidity(
|
||||||
&self,
|
&self,
|
||||||
user_holding_a: AccountId,
|
user_holding_a: AccountId,
|
||||||
user_holding_b: AccountId,
|
user_holding_b: AccountId,
|
||||||
@ -297,12 +387,16 @@ impl AMM<'_> {
|
|||||||
|
|
||||||
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 {
|
let user_a_acc = self
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
.0
|
||||||
};
|
.get_account_public(user_holding_a)
|
||||||
let Ok(user_b_acc) = self.0.get_account_public(user_holding_b).await else {
|
.await
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
};
|
let user_b_acc = self
|
||||||
|
.0
|
||||||
|
.get_account_public(user_holding_b)
|
||||||
|
.await
|
||||||
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
|
|
||||||
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
let definition_token_a_id = TokenHolding::parse(&user_a_acc.data)
|
||||||
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
.ok_or(ExecutionFailureKind::AccountDataError(user_holding_a))?
|
||||||
@ -327,18 +421,18 @@ impl AMM<'_> {
|
|||||||
user_holding_lp,
|
user_holding_lp,
|
||||||
];
|
];
|
||||||
|
|
||||||
let Ok(nonces) = self.0.get_accounts_nonces(vec![user_holding_lp]).await else {
|
let nonces = self
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
.0
|
||||||
};
|
.get_accounts_nonces(vec![user_holding_lp])
|
||||||
|
.await
|
||||||
|
.map_err(|_| ExecutionFailureKind::SequencerError)?;
|
||||||
|
|
||||||
let Some(signing_key_lp) = self
|
let signing_key_lp = self
|
||||||
.0
|
.0
|
||||||
.storage
|
.storage
|
||||||
.user_data
|
.user_data
|
||||||
.get_pub_account_signing_key(&user_holding_lp)
|
.get_pub_account_signing_key(&user_holding_lp)
|
||||||
else {
|
.ok_or(ExecutionFailureKind::KeyNotFoundError)?;
|
||||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
|
||||||
};
|
|
||||||
|
|
||||||
let message = nssa::public_transaction::Message::try_new(
|
let message = nssa::public_transaction::Message::try_new(
|
||||||
program.id(),
|
program.id(),
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
//! This module contains [`WalletCore`](crate::WalletCore) facades for interacting with various
|
//! This module contains [`WalletCore`](crate::WalletCore) facades for interacting with various
|
||||||
//! on-chain programs.
|
//! on-chain programs.
|
||||||
|
|
||||||
use nssa::{AccountId, ProgramId};
|
|
||||||
use nssa_core::program::PdaSeed;
|
|
||||||
use serde::{Serialize, ser::SerializeSeq};
|
use serde::{Serialize, ser::SerializeSeq};
|
||||||
|
|
||||||
pub mod amm;
|
pub mod amm;
|
||||||
@ -10,99 +8,6 @@ pub mod native_token_transfer;
|
|||||||
pub mod pinata;
|
pub mod pinata;
|
||||||
pub mod token;
|
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:
|
/// Why it is necessary:
|
||||||
///
|
///
|
||||||
/// Serialize implemented only for `[u8; N]` where `N<=32` and orphan rules would disallow custom
|
/// Serialize implemented only for `[u8; N]` where `N<=32` and orphan rules would disallow custom
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user