diff --git a/binding_tests/interface_test.go b/binding_tests/interface_test.go index eb7efebe..36584742 100644 --- a/binding_tests/interface_test.go +++ b/binding_tests/interface_test.go @@ -144,8 +144,8 @@ func TestSignOrderMatching(t *testing.T) { ) taker, err = taker.CreateSignedOrder(zklink_signer) assert.Nil(t, err) - assert.NotNil(t, taker.Signature()) - fmt.Printf("taker signature:%v\n", taker.Signature()) + assert.NotNil(t, taker.GetSignature()) + fmt.Printf("taker signature:%v\n", taker.GetSignature()) maker := sdk.NewOrder( sdk.AccountId(2), @@ -164,8 +164,8 @@ func TestSignOrderMatching(t *testing.T) { ) maker, err = maker.CreateSignedOrder(zklink_signer) assert.Nil(t, err) - assert.NotNil(t, maker.Signature()) - fmt.Printf("maker signature:%v\n", maker.Signature()) + assert.NotNil(t, maker.GetSignature()) + fmt.Printf("maker signature:%v\n", maker.GetSignature()) builder := sdk.OrderMatchingBuilder{ sdk.AccountId(3), @@ -320,8 +320,8 @@ func TestContractMatching(t *testing.T) { Size: *big.NewInt(100), Price: *big.NewInt(100), Direction: false, - MakerFeeRatio: 10, - TakerFeeRatio: 20, + MakerFeeRate: 10, + TakerFeeRate: 20, HasSubsidy: false, } taker := sdk.NewContract(contract_builder) diff --git a/bindings/sdk/src/ffi.udl b/bindings/sdk/src/ffi.udl index b657fb31..0688b25e 100644 --- a/bindings/sdk/src/ffi.udl +++ b/bindings/sdk/src/ffi.udl @@ -72,8 +72,8 @@ dictionary ContractBuilder { BigUint size; BigUint price; boolean direction; - u8 taker_fee_ratio; - u8 maker_fee_ratio; + u8 taker_fee_rate; + u8 maker_fee_rate; boolean has_subsidy; }; @@ -253,7 +253,7 @@ interface Deposit { interface Withdraw { constructor(WithdrawBuilder builder); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); sequence get_bytes(); sequence tx_hash(); string json_str(); @@ -271,7 +271,7 @@ interface Withdraw { interface ChangePubKey { constructor(ChangePubKeyBuilder builder); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); sequence get_bytes(); sequence tx_hash(); string json_str(); @@ -285,7 +285,7 @@ interface ChangePubKey { interface ForcedExit { constructor(ForcedExitBuilder builder); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); sequence get_bytes(); sequence tx_hash(); string json_str(); @@ -310,7 +310,7 @@ interface FullExit { interface Transfer { constructor(TransferBuilder builder); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); sequence get_bytes(); sequence tx_hash(); string json_str(); @@ -339,11 +339,11 @@ interface Order { BigUint price, boolean is_sell, boolean has_subsidy, - u8 fee_ratio1, - u8 fee_ratio2, + u8 fee_rate1, + u8 fee_rate2, ZkLinkSignature ?signature ); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); sequence get_bytes(); string json_str(); boolean is_valid(); @@ -359,7 +359,7 @@ interface OrderMatching { sequence tx_hash(); string json_str(); boolean is_valid(); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); boolean is_signature_valid(); [Throws=ZkSignerError] OrderMatching create_signed_tx(ZkLinkSigner signer); @@ -370,7 +370,7 @@ interface Contract { constructor(ContractBuilder builder); boolean is_long(); boolean is_short(); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); boolean is_signature_valid(); sequence get_bytes(); }; @@ -391,7 +391,7 @@ interface AutoDeleveraging { sequence tx_hash(); string json_str(); boolean is_valid(); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); boolean is_signature_valid(); ZkLinkTx to_zklink_tx(); [Throws=ZkSignerError] @@ -404,7 +404,7 @@ interface ContractMatching { sequence tx_hash(); string json_str(); boolean is_valid(); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); boolean is_signature_valid(); ZkLinkTx to_zklink_tx(); [Throws=ZkSignerError] @@ -417,7 +417,7 @@ interface Funding { sequence tx_hash(); string json_str(); boolean is_valid(); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); boolean is_signature_valid(); ZkLinkTx to_zklink_tx(); [Throws=ZkSignerError] @@ -430,7 +430,7 @@ interface Liquidation { sequence tx_hash(); string json_str(); boolean is_valid(); - ZkLinkSignature signature(); + ZkLinkSignature get_signature(); boolean is_signature_valid(); ZkLinkTx to_zklink_tx(); [Throws=ZkSignerError] diff --git a/bindings/wasm/src/tx_types/order_matching.rs b/bindings/wasm/src/tx_types/order_matching.rs index c0b1ed3e..e424c4b8 100644 --- a/bindings/wasm/src/tx_types/order_matching.rs +++ b/bindings/wasm/src/tx_types/order_matching.rs @@ -28,8 +28,8 @@ impl Order { amount: String, price: String, is_sell: bool, - maker_fee_ratio: u8, - taker_fee_ratio2: u8, + maker_fee_rate: u8, + taker_fee_rate: u8, has_subsidy: bool, ) -> Order { Order { @@ -43,7 +43,7 @@ impl Order { amount: BigUint::from_str(&amount).unwrap(), price: BigUint::from_str(&price).unwrap(), is_sell: is_sell as u8, - fee_rates: [maker_fee_ratio, taker_fee_ratio2], + fee_rates: [maker_fee_rate, taker_fee_rate], has_subsidy: has_subsidy as u8, signature: Default::default(), }, diff --git a/provider/src/response.rs b/provider/src/response.rs index cc5249b9..af19e741 100644 --- a/provider/src/response.rs +++ b/provider/src/response.rs @@ -7,16 +7,19 @@ use serde::{Deserialize, Serialize}; use chrono::serde::{ts_microseconds, ts_microseconds_option}; use zklink_sdk_signers::eth_signer::H256; use zklink_sdk_signers::zklink_signer::pubkey_hash::PubKeyHash; -use zklink_sdk_types::basic_types::tx_hash::TxHash; -use zklink_sdk_types::basic_types::{ - AccountId, BlockNumber, ChainId, Nonce, SlotId, SubAccountId, TokenId, ZkLinkAddress, +use zklink_sdk_types::prelude::{ + AccountId, BigIntSerdeWrapper, BigUintSerdeWrapper, BlockNumber, ChainId, MarginId, Nonce, + PairId, SlotId, SubAccountId, TokenId, TxHash, ZkLinkAddress, U256, }; -use zklink_sdk_types::prelude::{BigUintSerdeWrapper, U256}; use zklink_sdk_types::tx_type::zklink_tx::ZkLinkTx; pub type SubAccountNonces = HashMap; -pub type SubAccountBalances = HashMap>; +pub type SubAccountBalances = HashMap>; +pub type SubAccountPositions = HashMap>; pub type SubAccountOrders = HashMap>; +pub type SubAccountGlobalVars = HashMap; +pub type MarginParams = HashMap; +pub type ContractParams = HashMap; #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] @@ -117,6 +120,31 @@ pub struct AccountInfoResp { pub sub_account_nonces: SubAccountNonces, } +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct GlobalVarsResp { + pub sub_account_id: SubAccountId, + pub fee_account: Option, + pub insurance_fund_account: Option, + pub margin_params: MarginParams, + pub contract_params: ContractParams, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct ResponseMarginParams { + pub token_id: TokenId, + pub ratio: u8, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct ResponseContractParams { + pub initial_margin_rate: u16, + pub maintenance_margin_rate: u16, + pub acc_funding_rate: i32, +} + #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] pub struct ResponseTidyOrder { @@ -130,6 +158,31 @@ impl ResponseTidyOrder { } } +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct ResponsePosition { + pub direction: bool, + pub price: BigDecimal, + pub size: BigDecimal, + pub acc_funding_rate: i32, +} + +impl ResponsePosition { + pub fn new( + direction: bool, + price: BigDecimal, + size: BigDecimal, + acc_funding_rate: i32, + ) -> Self { + Self { + direction, + price, + size, + acc_funding_rate, + } + } +} + #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] pub struct AccountSnapshotResp { @@ -141,28 +194,123 @@ pub struct AccountSnapshotResp { pub balances: SubAccountBalances, pub order_slots: SubAccountOrders, pub block_number: BlockNumber, + pub positions: SubAccountPositions, } #[derive(Debug, Serialize, Deserialize, Clone)] -#[serde(tag = "type")] +#[serde(tag = "stateUpdateType")] pub enum StateUpdateResp { + AccountUpdate(AccountUpdateResp), + GlobalVarsUpdate(GlobalVarsUpdateResp), +} + +impl From for StateUpdateResp { + fn from(value: AccountUpdateResp) -> Self { + Self::AccountUpdate(value) + } +} + +impl From for StateUpdateResp { + fn from(value: GlobalVarsUpdateResp) -> Self { + Self::GlobalVarsUpdate(value) + } +} + +impl StateUpdateResp { + pub fn update_id(&self) -> i32 { + match self { + StateUpdateResp::AccountUpdate(u) => u.update_id(), + StateUpdateResp::GlobalVarsUpdate(u) => u.update_id(), + } + } +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(tag = "accountUpdateType")] +pub enum AccountUpdateResp { AccountCreate(AccountCreateResp), AccountChangePubkeyUpdate(AccountChangePubkeyUpdateResp), BalanceUpdate(BalanceUpdateResp), OrderUpdate(OrderUpdateResp), + PositionUpdate(PositionUpdateResp), } -impl StateUpdateResp { +impl AccountUpdateResp { pub fn update_id(&self) -> i32 { match self { - StateUpdateResp::AccountCreate(u) => u.update_id, - StateUpdateResp::AccountChangePubkeyUpdate(u) => u.update_id, - StateUpdateResp::BalanceUpdate(u) => u.update_id, - StateUpdateResp::OrderUpdate(u) => u.update_id, + AccountUpdateResp::AccountCreate(u) => u.update_id, + AccountUpdateResp::AccountChangePubkeyUpdate(u) => u.update_id, + AccountUpdateResp::BalanceUpdate(u) => u.update_id, + AccountUpdateResp::OrderUpdate(u) => u.update_id, + AccountUpdateResp::PositionUpdate(u) => u.update_id, } } } +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(tag = "globalVarUpdate")] +pub enum GlobalVarsUpdateResp { + FeeAccountUpdate(FeeAccountUpdateResp), + InsuranceFundAccountUpdate(InsuranceFundAccountUpdateResp), + MarginParamsUpdate(MarginParamsUpdateResp), + ContractParamsUpdate(ContractParamsUpdateResp), +} + +impl GlobalVarsUpdateResp { + pub fn update_id(&self) -> i32 { + match self { + GlobalVarsUpdateResp::FeeAccountUpdate(u) => u.update_id, + GlobalVarsUpdateResp::InsuranceFundAccountUpdate(u) => u.update_id, + GlobalVarsUpdateResp::MarginParamsUpdate(u) => u.update_id, + GlobalVarsUpdateResp::ContractParamsUpdate(u) => u.update_id, + } + } +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct FeeAccountUpdateResp { + pub update_id: i32, + pub sub_account_id: SubAccountId, + pub old_fee_account_id: AccountId, + pub new_fee_account_id: AccountId, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct InsuranceFundAccountUpdateResp { + pub update_id: i32, + pub sub_account_id: SubAccountId, + pub old_insurance_fund_account_id: AccountId, + pub new_insurance_fund_account_id: AccountId, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct MarginParamsUpdateResp { + pub update_id: i32, + pub sub_account_id: SubAccountId, + pub margin_id: MarginId, + pub old_token_id: TokenId, + pub new_token_id: TokenId, + pub old_ratio: u8, + pub new_ratio: u8, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct ContractParamsUpdateResp { + pub update_id: i32, + pub sub_account_id: SubAccountId, + pub pair_id: PairId, + pub old_maintenance_margin_rate: u16, + pub new_maintenance_margin_rate: u16, + pub old_initial_margin_rate: u16, + pub new_initial_margin_rate: u16, + pub old_acc_funding_rate: i32, + pub new_acc_funding_rate: i32, +} + #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] pub struct AccountCreateResp { @@ -189,8 +337,8 @@ pub struct BalanceUpdateResp { pub account_id: AccountId, pub sub_account_id: SubAccountId, pub coin_id: TokenId, - pub old_balance: BigUintSerdeWrapper, - pub new_balance: BigUintSerdeWrapper, + pub old_balance: BigIntSerdeWrapper, + pub new_balance: BigIntSerdeWrapper, pub old_nonce: Nonce, pub new_nonce: Nonce, } @@ -206,6 +354,17 @@ pub struct OrderUpdateResp { pub new_tidy_order: ResponseTidyOrder, } +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct PositionUpdateResp { + pub update_id: i32, + pub account_id: AccountId, + pub sub_account_id: SubAccountId, + pub pair_id: PairId, + pub old_position: ResponsePosition, + pub new_position: ResponsePosition, +} + #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] pub struct TxResp { diff --git a/types/src/basic_types/mod.rs b/types/src/basic_types/mod.rs index 788bb410..ee7e5ffe 100644 --- a/types/src/basic_types/mod.rs +++ b/types/src/basic_types/mod.rs @@ -12,9 +12,9 @@ pub use zklink_address::ZkLinkAddress; #[macro_use] mod macros; -pub mod bigunit_wrapper; pub mod bit_convert; pub mod float_convert; +pub mod num_wrapper; pub mod pack; pub(crate) mod pad; pub(crate) mod params; diff --git a/types/src/basic_types/bigunit_wrapper.rs b/types/src/basic_types/num_wrapper.rs similarity index 50% rename from types/src/basic_types/bigunit_wrapper.rs rename to types/src/basic_types/num_wrapper.rs index 54608166..a11f4de2 100644 --- a/types/src/basic_types/bigunit_wrapper.rs +++ b/types/src/basic_types/num_wrapper.rs @@ -1,7 +1,8 @@ +use num::bigint::ToBigInt; use num::{BigInt, BigUint}; use serde::{Deserialize, Serialize}; use std::ops::{Deref, DerefMut}; -use zklink_sdk_utils::serde::BigUintSerdeAsRadix10Str; +use zklink_sdk_utils::serde::{BigIntSerdeAsRadix10Str, BigUintSerdeAsRadix10Str}; #[derive(Clone, Debug, Serialize, Deserialize, Default, Ord, PartialOrd, Eq, PartialEq, Hash)] pub struct BigUintSerdeWrapper(#[serde(with = "BigUintSerdeAsRadix10Str")] pub BigUint); @@ -36,3 +37,38 @@ impl ToString for BigUintSerdeWrapper { self.0.to_string() } } + +#[derive(Clone, Debug, Serialize, Deserialize, Default, Ord, PartialOrd, Eq, PartialEq, Hash)] +pub struct BigIntSerdeWrapper(#[serde(with = "BigIntSerdeAsRadix10Str")] pub BigInt); + +impl From for BigIntSerdeWrapper { + fn from(uint: BigUint) -> BigIntSerdeWrapper { + BigIntSerdeWrapper(uint.to_bigint().unwrap()) + } +} + +impl From for BigIntSerdeWrapper { + fn from(big_int: BigInt) -> BigIntSerdeWrapper { + BigIntSerdeWrapper(big_int) + } +} + +impl Deref for BigIntSerdeWrapper { + type Target = BigInt; + + fn deref(&self) -> &BigInt { + &self.0 + } +} + +impl DerefMut for BigIntSerdeWrapper { + fn deref_mut(&mut self) -> &mut BigInt { + &mut self.0 + } +} + +impl ToString for BigIntSerdeWrapper { + fn to_string(&self) -> String { + self.0.to_string() + } +} diff --git a/types/src/lib.rs b/types/src/lib.rs index fa700c3d..7c18a3aa 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -1,5 +1,4 @@ pub mod basic_types; -pub mod contract; pub mod error; pub mod signatures; pub mod tx_builder; @@ -8,12 +7,15 @@ pub mod utils; pub mod prelude { pub use super::basic_types::{ - bigunit_wrapper::BigUintSerdeWrapper, bit_convert::BitConvert, - float_convert::FloatConversions, pad::pad_front, tx_hash::TxHash, - zklink_address::ZkLinkAddress, AccountId, BlockNumber, ChainId, EthBlockId, GetBytes, - MarginId, Nonce, PairId, PriorityOpId, SlotId, SubAccountId, TimeStamp, TokenId, + bit_convert::BitConvert, + float_convert::FloatConversions, + num_wrapper::{BigIntSerdeWrapper, BigUintSerdeWrapper}, + pad::pad_front, + tx_hash::TxHash, + zklink_address::ZkLinkAddress, + AccountId, BlockNumber, ChainId, EthBlockId, GetBytes, MarginId, Nonce, PairId, + PriorityOpId, SlotId, SubAccountId, TimeStamp, TokenId, }; - pub use super::contract::*; pub use super::error::TypeError; pub use super::signatures::{TxLayer1Signature, TxSignature}; pub use super::tx_builder::*; @@ -21,6 +23,7 @@ pub mod prelude { pub use super::tx_type::ToZklinkTx; pub use super::tx_type::{ change_pubkey::{ChangePubKey, ChangePubKeyAuthData, Create2Data}, + contract::*, deposit::Deposit, exit_info::ExitInfo, forced_exit::ForcedExit, diff --git a/types/src/tx_builder.rs b/types/src/tx_builder.rs index 916be572..c14ab169 100644 --- a/types/src/tx_builder.rs +++ b/types/src/tx_builder.rs @@ -1,14 +1,12 @@ use crate::basic_types::{ AccountId, ChainId, Nonce, SubAccountId, TimeStamp, TokenId, ZkLinkAddress, }; -use crate::tx_type::order_matching::Order; - -use crate::contract::prices::{ContractPrice, SpotPriceInfo}; use crate::prelude::{ AutoDeleveraging, ChangePubKey, ChangePubKeyAuthData, Contract, ContractMatching, Deposit, - ForcedExit, FullExit, Funding, Liquidation, OraclePrices, OrderMatching, PairId, Parameter, - SlotId, Transfer, UpdateGlobalVar, Withdraw, + ForcedExit, FullExit, Funding, Liquidation, OraclePrices, Order, OrderMatching, PairId, + Parameter, SlotId, Transfer, UpdateGlobalVar, Withdraw, }; +use crate::tx_type::contract::prices::{ContractPrice, SpotPriceInfo}; use crate::tx_type::exit_info::ExitInfo; use cfg_if::cfg_if; use num::BigUint; @@ -364,9 +362,9 @@ pub struct ContractBuilder { pub price: BigUint, pub direction: bool, /// 100 means 1%, max is 2.56% - pub maker_fee_ratio: u8, + pub maker_fee_rate: u8, /// 100 means 1%, max is 2.56% - pub taker_fee_ratio: u8, + pub taker_fee_rate: u8, pub has_subsidy: bool, } @@ -381,7 +379,7 @@ impl ContractBuilder { size: self.size, price: self.price, direction: self.direction as u8, - fee_rates: [self.maker_fee_ratio, self.taker_fee_ratio], + fee_rates: [self.maker_fee_rate, self.taker_fee_rate], has_subsidy: self.has_subsidy as u8, signature: Default::default(), } diff --git a/types/src/tx_type/change_pubkey.rs b/types/src/tx_type/change_pubkey.rs index 2c1ae805..8e2ebd09 100644 --- a/types/src/tx_type/change_pubkey.rs +++ b/types/src/tx_type/change_pubkey.rs @@ -177,14 +177,8 @@ impl ZkSignatureTrait for ChangePubKey { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } diff --git a/types/src/contract/auto_deleveraging.rs b/types/src/tx_type/contract/auto_deleveraging.rs similarity index 92% rename from types/src/contract/auto_deleveraging.rs rename to types/src/tx_type/contract/auto_deleveraging.rs index 6a60c02e..c81231e9 100644 --- a/types/src/contract/auto_deleveraging.rs +++ b/types/src/tx_type/contract/auto_deleveraging.rs @@ -1,7 +1,7 @@ +use super::prices::OraclePrices; use crate::basic_types::pack::{pack_fee_amount, pack_token_amount}; use crate::basic_types::pad::pad_front; use crate::basic_types::{AccountId, GetBytes, Nonce, PairId, SubAccountId, TokenId}; -use crate::contract::prices::OraclePrices; use crate::params::{PRICE_BIT_WIDTH, SIGNED_AUTO_DELEVERAGING_BIT_WIDTH}; use crate::prelude::validator::*; #[cfg(feature = "ffi")] @@ -89,13 +89,8 @@ impl ZkSignatureTrait for AutoDeleveraging { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } diff --git a/types/src/contract/contract_matching.rs b/types/src/tx_type/contract/contract_matching.rs similarity index 92% rename from types/src/contract/contract_matching.rs rename to types/src/tx_type/contract/contract_matching.rs index f167e9b0..b35f6b64 100644 --- a/types/src/contract/contract_matching.rs +++ b/types/src/tx_type/contract/contract_matching.rs @@ -84,14 +84,8 @@ impl ZkSignatureTrait for ContractMatching { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } @@ -174,13 +168,8 @@ impl ZkSignatureTrait for Contract { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } diff --git a/types/src/contract/funding.rs b/types/src/tx_type/contract/funding.rs similarity index 94% rename from types/src/contract/funding.rs rename to types/src/tx_type/contract/funding.rs index 2736ed5e..29f52e78 100644 --- a/types/src/contract/funding.rs +++ b/types/src/tx_type/contract/funding.rs @@ -117,12 +117,7 @@ impl ZkSignatureTrait for Funding { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } diff --git a/types/src/contract/liquidation.rs b/types/src/tx_type/contract/liquidation.rs similarity index 90% rename from types/src/contract/liquidation.rs rename to types/src/tx_type/contract/liquidation.rs index ee823973..28a83224 100644 --- a/types/src/contract/liquidation.rs +++ b/types/src/tx_type/contract/liquidation.rs @@ -1,6 +1,6 @@ +use super::prices::OraclePrices; use crate::basic_types::pack::pack_fee_amount; use crate::basic_types::{AccountId, GetBytes, Nonce, SubAccountId, TokenId}; -use crate::contract::prices::OraclePrices; use crate::params::SIGNED_LIQUIDATION_BIT_WIDTH; use crate::prelude::validator::*; #[cfg(feature = "ffi")] @@ -77,12 +77,7 @@ impl ZkSignatureTrait for Liquidation { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } diff --git a/types/src/contract/mod.rs b/types/src/tx_type/contract/mod.rs similarity index 92% rename from types/src/contract/mod.rs rename to types/src/tx_type/contract/mod.rs index 794e11b6..78470a7a 100644 --- a/types/src/contract/mod.rs +++ b/types/src/tx_type/contract/mod.rs @@ -3,7 +3,7 @@ mod contract_matching; mod funding; mod liquidation; pub mod prices; -mod update_global_var; // TODO: move to super directory +mod update_global_var; pub use auto_deleveraging::AutoDeleveraging; pub use contract_matching::{Contract, ContractMatching}; diff --git a/types/src/contract/prices.rs b/types/src/tx_type/contract/prices.rs similarity index 100% rename from types/src/contract/prices.rs rename to types/src/tx_type/contract/prices.rs diff --git a/types/src/contract/update_global_var.rs b/types/src/tx_type/contract/update_global_var.rs similarity index 99% rename from types/src/contract/update_global_var.rs rename to types/src/tx_type/contract/update_global_var.rs index 904c88ad..55a0e5c4 100644 --- a/types/src/contract/update_global_var.rs +++ b/types/src/tx_type/contract/update_global_var.rs @@ -1,5 +1,5 @@ +use super::funding::FundingRate; use crate::basic_types::{AccountId, ChainId, GetBytes, MarginId, PairId, SubAccountId, TokenId}; -use crate::contract::funding::FundingRate; use crate::prelude::validator::*; #[cfg(feature = "ffi")] use crate::tx_builder::UpdateGlobalVarBuilder; diff --git a/types/src/tx_type/exit_info.rs b/types/src/tx_type/exit_info.rs index fdd2f24f..3a0ee872 100644 --- a/types/src/tx_type/exit_info.rs +++ b/types/src/tx_type/exit_info.rs @@ -58,14 +58,8 @@ impl ZkSignatureTrait for ExitInfo { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } diff --git a/types/src/tx_type/forced_exit.rs b/types/src/tx_type/forced_exit.rs index ef0bdc37..a791f97c 100644 --- a/types/src/tx_type/forced_exit.rs +++ b/types/src/tx_type/forced_exit.rs @@ -104,14 +104,8 @@ impl ZkSignatureTrait for ForcedExit { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } diff --git a/types/src/tx_type/mod.rs b/types/src/tx_type/mod.rs index a64dc69d..eec227bb 100644 --- a/types/src/tx_type/mod.rs +++ b/types/src/tx_type/mod.rs @@ -17,10 +17,12 @@ use std::sync::Arc; use zklink_sdk_signers::zklink_signer::error::ZkSignerError; use zklink_sdk_signers::zklink_signer::pk_signer::{sha256_bytes, ZkLinkSigner}; use zklink_sdk_signers::zklink_signer::signature::ZkLinkSignature; +use zklink_sdk_signers::zklink_signer::PubKeyHash; pub mod validator; pub mod change_pubkey; +pub mod contract; pub mod deposit; pub mod exit_info; pub mod forced_exit; @@ -154,9 +156,23 @@ pub trait ZkSignatureTrait: TxTrait { fn set_signature(&mut self, signature: ZkLinkSignature); #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature; + fn get_signature(&self) -> ZkLinkSignature { + self.signature().clone() + } + + fn signature(&self) -> &ZkLinkSignature; + + fn verify_signature(&self) -> Option { + let signature = self.signature(); + signature + .verify_musig(&self.get_bytes()) + .then(|| signature.pub_key.public_key_hash()) + } - fn is_signature_valid(&self) -> bool; + fn is_signature_valid(&self) -> bool { + let bytes = self.get_bytes(); + self.signature().verify_musig(&bytes) + } fn sign(&mut self, signer: &ZkLinkSigner) -> Result<(), ZkSignerError> { let bytes = self.get_bytes(); diff --git a/types/src/tx_type/order_matching.rs b/types/src/tx_type/order_matching.rs index 8b3bb09d..8513c43d 100644 --- a/types/src/tx_type/order_matching.rs +++ b/types/src/tx_type/order_matching.rs @@ -72,8 +72,8 @@ impl Order { price: BigUint, is_sell: bool, has_subsidy: bool, - maker_fee_ratio: u8, - taker_fee_ratio: u8, + maker_fee_rate: u8, + taker_fee_rate: u8, signature: Option, ) -> Self { Self { @@ -87,7 +87,7 @@ impl Order { price, is_sell: u8::from(is_sell), has_subsidy: u8::from(has_subsidy), - fee_rates: [maker_fee_ratio, taker_fee_ratio], + fee_rates: [maker_fee_rate, taker_fee_rate], signature: signature.unwrap_or_default(), } } @@ -162,14 +162,8 @@ impl ZkSignatureTrait for Order { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } #[cfg(feature = "ffi")] @@ -347,14 +341,8 @@ impl ZkSignatureTrait for OrderMatching { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } diff --git a/types/src/tx_type/transfer.rs b/types/src/tx_type/transfer.rs index c9f4d671..14230b52 100644 --- a/types/src/tx_type/transfer.rs +++ b/types/src/tx_type/transfer.rs @@ -16,7 +16,6 @@ use std::sync::Arc; use validator::Validate; use zklink_sdk_signers::eth_signer::pk_signer::EthSigner; use zklink_sdk_signers::zklink_signer::error::ZkSignerError; -use zklink_sdk_signers::zklink_signer::pubkey_hash::PubKeyHash; use zklink_sdk_signers::zklink_signer::signature::ZkLinkSignature; use zklink_sdk_utils::serde::BigUintSerdeAsRadix10Str; @@ -64,14 +63,6 @@ impl Transfer { builder.build() } - /// Restores the `PubKeyHash` from the transaction signature. - pub fn verify_signature(&self) -> Option { - match self.signature.verify_musig(&self.get_bytes()) { - ret if ret => Some(self.signature.pub_key.public_key_hash()), - _ => None, - } - } - /// Get the first part of the message we expect to be signed by Ethereum account key. /// The only difference is the missing `nonce` since it's added at the end of the transactions /// batch message. @@ -150,13 +141,8 @@ impl ZkSignatureTrait for Transfer { self.signature = signature } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - - fn is_signature_valid(&self) -> bool { - self.signature.verify_musig(&self.get_bytes()) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } @@ -198,10 +184,10 @@ mod test { #[test] fn test_verify_signature() { let private_key_str = "0xbe725250b123a39dab5b7579334d5888987c72a58f4508062545fe6e08ca94f4"; - let signature = "0x7b173e25e484eed3461091430f81b2a5bd7ae792f69701dcb073cb903f8125107ecbe23c307d18007ee43090940a4a43bd02bdcda206ad695f745c2f0a64f4ac4c4c8beb9ed9cbdd0e523e75ffc7dedd0281da4946bb37fa26a04283bd480a04"; - let public_key_str = "0x7b173e25e484eed3461091430f81b2a5bd7ae792f69701dcb073cb903f812510"; let ts = 1693472232; let eth_signature = "0x1f11707e54773e059bc38aa73526fe2b51af9b89a77df731af7bcc429750d0317727a857efda5d79232eb5f9a66ed60a79aad2195d4de1375f5021c0db041b221b"; + let signature = "0x7b173e25e484eed3461091430f81b2a5bd7ae792f69701dcb073cb903f8125107ecbe23c307d18007ee43090940a4a43bd02bdcda206ad695f745c2f0a64f4ac4c4c8beb9ed9cbdd0e523e75ffc7dedd0281da4946bb37fa26a04283bd480a04"; + let public_key_str = "0x7b173e25e484eed3461091430f81b2a5bd7ae792f69701dcb073cb903f812510"; let address = ZkLinkAddress::from_str("0xAFAFf3aD1a0425D792432D9eCD1c3e26Ef2C42E9").unwrap(); let builder = TransferBuilder { @@ -215,12 +201,14 @@ mod test { nonce: Nonce(1), timestamp: ts.into(), }; - let mut tx = builder.build(); + //check l2 signature + let mut tx = builder.build(); tx.signature = ZkLinkSignature::from_hex(signature).unwrap(); let recover_pubkey_hash = tx.verify_signature().unwrap(); let pubkey = PackedPublicKey::from_hex(public_key_str).unwrap(); let pubkey_hash = pubkey.public_key_hash(); + assert_eq!(pubkey_hash, recover_pubkey_hash); //check l1 signature let l1_signature = PackedEthSignature::from_hex(eth_signature).unwrap(); @@ -229,7 +217,6 @@ mod test { let recover_address = l1_signature.signature_recover_signer(&message).unwrap(); let private_key = EthSigner::try_from(private_key_str).unwrap(); let address = private_key.get_address(); - assert_eq!(pubkey_hash, recover_pubkey_hash); assert_eq!(address, recover_address); } } diff --git a/types/src/tx_type/withdraw.rs b/types/src/tx_type/withdraw.rs index 60fbaaf8..b8386d79 100644 --- a/types/src/tx_type/withdraw.rs +++ b/types/src/tx_type/withdraw.rs @@ -18,7 +18,6 @@ use crate::params::TOKEN_MAX_PRECISION; use crate::prelude::WithdrawBuilder; use crate::tx_type::validator::*; use crate::tx_type::{ethereum_sign_message_part, TxTrait, ZkSignatureTrait}; -use zklink_sdk_signers::zklink_signer::pubkey_hash::PubKeyHash; /// `Withdraw` transaction performs a withdrawal of funds from zklink account to L1 account. #[derive(Debug, Clone, Default, Serialize, Deserialize, Validate)] @@ -76,14 +75,6 @@ impl Withdraw { builder.build() } - /// Restores the `PubKeyHash` from the transaction signature. - pub fn verify_signature(&self) -> Option { - match self.signature.verify_musig(&self.get_bytes()) { - ret if ret => Some(self.signature.pub_key.public_key_hash()), - _ => None, - } - } - /// Get the first part of the message we expect to be signed by Ethereum account key. /// The only difference is the missing `nonce` since it's added at the end of the transactions /// batch message. @@ -165,14 +156,8 @@ impl ZkSignatureTrait for Withdraw { self.signature = signature; } - #[cfg(feature = "ffi")] - fn signature(&self) -> ZkLinkSignature { - self.signature.clone() - } - - fn is_signature_valid(&self) -> bool { - let bytes = self.get_bytes(); - self.signature.verify_musig(&bytes) + fn signature(&self) -> &ZkLinkSignature { + &self.signature } } diff --git a/utils/src/serde.rs b/utils/src/serde.rs index eecdcad0..7f8f9be0 100644 --- a/utils/src/serde.rs +++ b/utils/src/serde.rs @@ -1,4 +1,4 @@ -use num::BigUint; +use num::{BigInt, BigUint}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use std::str::FromStr; /// Trait for specifying prefix for bytes to hex serialization @@ -120,3 +120,28 @@ impl BigUintSerdeAsRadix10Str { Ok(num) } } + +/// Used to serialize BigInt as radix 10 string. +#[derive(Clone, Debug)] +pub struct BigIntSerdeAsRadix10Str; + +impl BigIntSerdeAsRadix10Str { + pub fn serialize(val: &BigInt, serializer: S) -> Result + where + S: Serializer, + { + let s = val.to_string(); + serializer.serialize_str(&s) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + use serde::de::Error; + let s = String::deserialize(deserializer)?; + let num = + BigInt::from_str(&s).map_err(|_| Error::custom("Invalid string type of big int"))?; + Ok(num) + } +}