mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-08-25 22:21:16 +00:00
feat(amm-client): add lossless host adapters
This commit is contained in:
@@ -18,10 +18,11 @@ use serde::Deserialize;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
use crate::{
|
||||
account_snapshot_from_sequencer_response,
|
||||
discovery::{self, CanonicalPair, PairReadManifest},
|
||||
plan_add_liquidity, plan_create_oracle_price_account, plan_create_pool,
|
||||
plan_create_price_observations, plan_initialize, plan_remove_liquidity, plan_swap_exact_input,
|
||||
plan_swap_exact_output, plan_sync_reserves, plan_update_config,
|
||||
human_price_ratio_to_q64_64, plan_add_liquidity, plan_create_oracle_price_account,
|
||||
plan_create_pool, plan_create_price_observations, plan_initialize, plan_remove_liquidity,
|
||||
plan_swap_exact_input, plan_swap_exact_output, plan_sync_reserves, plan_update_config,
|
||||
quote::{
|
||||
self as client_quote, AccountSnapshot, ValidatedFungibleDefinition,
|
||||
ValidatedFungibleHolding, ValidatedPoolSnapshot,
|
||||
@@ -30,10 +31,10 @@ use crate::{
|
||||
CreatePoolPlanInput, CreatePriceObservationsPlanInput, InitializePlanInput, IntentError,
|
||||
OpeningLiquidityIntent, PoolContext, PreparedAddLiquidity, PreparedCallerOpeningPair,
|
||||
PreparedCreatePool, PreparedOpeningPair, PreparedRemoveLiquidity, PreparedSwapExactInput,
|
||||
PreparedSwapExactOutput, PreparedTransaction, RemoveLiquidityPlanInput, SlippageTolerance,
|
||||
SwapExactInputPlanInput, SwapExactOutputPlanInput, SyncReservesPlanInput, TransactionError,
|
||||
TransactionOperation, TransactionPlan, UpdateConfigPlanInput, WalletPrerequisites,
|
||||
SLIPPAGE_BPS_DENOMINATOR,
|
||||
PreparedSwapExactOutput, PreparedTransaction, RemoveLiquidityPlanInput, SequencerAccountError,
|
||||
SlippageTolerance, SwapExactInputPlanInput, SwapExactOutputPlanInput, SyncReservesPlanInput,
|
||||
TransactionError, TransactionOperation, TransactionPlan, UpdateConfigPlanInput,
|
||||
WalletPrerequisites, SLIPPAGE_BPS_DENOMINATOR,
|
||||
};
|
||||
|
||||
/// Version of the reusable AMM client JSON contract.
|
||||
@@ -90,6 +91,12 @@ impl From<TransactionError> for WireError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SequencerAccountError> for WireError {
|
||||
fn from(error: SequencerAccountError) -> Self {
|
||||
Self::new(error.code(), error.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Deserialize)]
|
||||
#[serde(try_from = "String")]
|
||||
struct ProgramIdInput(ProgramId);
|
||||
@@ -410,6 +417,25 @@ impl PoolInput {
|
||||
#[serde(tag = "operation", rename_all = "snake_case")]
|
||||
enum QuoteRequest {
|
||||
ProtocolConstants,
|
||||
AccountSnapshotFromSequencerResponse {
|
||||
#[serde(rename = "accountId")]
|
||||
account_id: String,
|
||||
response: String,
|
||||
},
|
||||
HumanPriceRatioToQ64_64 {
|
||||
#[serde(rename = "firstTokenDefinitionId")]
|
||||
first_token_definition_id: String,
|
||||
#[serde(rename = "secondTokenDefinitionId")]
|
||||
second_token_definition_id: String,
|
||||
#[serde(rename = "firstAmount")]
|
||||
first_amount: String,
|
||||
#[serde(rename = "secondAmount")]
|
||||
second_amount: String,
|
||||
#[serde(rename = "firstTokenDecimals")]
|
||||
first_token_decimals: String,
|
||||
#[serde(rename = "secondTokenDecimals")]
|
||||
second_token_decimals: String,
|
||||
},
|
||||
DeriveConfigId {
|
||||
#[serde(rename = "ammProgramId")]
|
||||
amm_program_id: ProgramIdInput,
|
||||
@@ -1275,7 +1301,7 @@ pub fn plan_json(value: Value) -> Result<Value, WireError> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Evaluates one reusable AMM economic quote from tagged JSON.
|
||||
/// Evaluates one reusable AMM quote, discovery operation, or lossless host adapter from JSON.
|
||||
pub fn quote_json(value: Value) -> Result<Value, WireError> {
|
||||
validate_wire_schema(&value)?;
|
||||
let request: QuoteRequest = serde_json::from_value(value)
|
||||
@@ -1290,6 +1316,33 @@ pub fn quote_json(value: Value) -> Result<Value, WireError> {
|
||||
.map(u128::to_string)
|
||||
.collect::<Vec<_>>(),
|
||||
})),
|
||||
QuoteRequest::AccountSnapshotFromSequencerResponse {
|
||||
account_id: requested_account_id,
|
||||
response,
|
||||
} => {
|
||||
let snapshot = account_snapshot_from_sequencer_response(
|
||||
account_id(&requested_account_id, "accountId")?,
|
||||
&response,
|
||||
)?;
|
||||
Ok(account_snapshot_json(&snapshot))
|
||||
}
|
||||
QuoteRequest::HumanPriceRatioToQ64_64 {
|
||||
first_token_definition_id,
|
||||
second_token_definition_id,
|
||||
first_amount,
|
||||
second_amount,
|
||||
first_token_decimals,
|
||||
second_token_decimals,
|
||||
} => Ok(json!({
|
||||
"priceQ64_64": human_price_ratio_to_q64_64(
|
||||
account_id(&first_token_definition_id, "firstTokenDefinitionId")?,
|
||||
account_id(&second_token_definition_id, "secondTokenDefinitionId")?,
|
||||
&first_amount,
|
||||
&second_amount,
|
||||
decimal_u8(&first_token_decimals, "firstTokenDecimals")?,
|
||||
decimal_u8(&second_token_decimals, "secondTokenDecimals")?,
|
||||
)?.to_string(),
|
||||
})),
|
||||
QuoteRequest::DeriveConfigId { amm_program_id } => Ok(json!({
|
||||
"configId": discovery::derive_config_id(amm_program_id.into()).to_string(),
|
||||
})),
|
||||
@@ -1944,6 +1997,22 @@ fn pool_update_json(pool: PoolUpdate) -> Value {
|
||||
})
|
||||
}
|
||||
|
||||
fn account_snapshot_json(snapshot: &AccountSnapshot) -> Value {
|
||||
let account = snapshot.account();
|
||||
json!({
|
||||
"id": snapshot.account_id().to_string(),
|
||||
"programOwner": program_id_hex(account.program_owner),
|
||||
"balance": account.balance.to_string(),
|
||||
"nonce": account.nonce.0.to_string(),
|
||||
"data": account
|
||||
.data
|
||||
.as_ref()
|
||||
.iter()
|
||||
.map(|byte| format!("{byte:02x}"))
|
||||
.collect::<String>(),
|
||||
})
|
||||
}
|
||||
|
||||
fn amm_context_json(context: &AmmContext) -> Value {
|
||||
json!({
|
||||
"ammProgramId": program_id_hex(context.amm_program_id),
|
||||
@@ -2307,6 +2376,10 @@ fn decimal_u64(value: &str, field: &str) -> Result<u64, WireError> {
|
||||
decimal(value, field)
|
||||
}
|
||||
|
||||
fn decimal_u8(value: &str, field: &str) -> Result<u8, WireError> {
|
||||
decimal(value, field)
|
||||
}
|
||||
|
||||
fn optional_decimal_u128(value: Option<String>, field: &str) -> Result<Option<u128>, WireError> {
|
||||
value
|
||||
.as_deref()
|
||||
|
||||
Reference in New Issue
Block a user