WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 3c30e3f

Browse files
committed
fix serialization format in UsdClassTransfer
1 parent 5aca1a0 commit 3c30e3f

File tree

2 files changed

+45
-24
lines changed

2 files changed

+45
-24
lines changed

src/exchange/actions.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,30 @@ impl Eip712 for SpotSend {
186186

187187
#[derive(Serialize, Deserialize, Debug, Clone)]
188188
#[serde(rename_all = "camelCase")]
189-
pub struct SpotUser {
190-
pub class_transfer: ClassTransfer,
189+
pub struct UsdClassTransfer {
190+
#[serde(serialize_with = "serialize_hex")]
191+
pub signature_chain_id: u64,
192+
pub hyperliquid_chain: String,
193+
pub amount: String,
194+
pub to_perp: bool,
195+
pub nonce: u64,
191196
}
192197

193-
#[derive(Serialize, Deserialize, Debug, Clone)]
194-
#[serde(rename_all = "camelCase")]
195-
pub struct ClassTransfer {
196-
pub usdc: u64,
197-
pub to_perp: bool,
198+
impl Eip712 for UsdClassTransfer {
199+
fn domain(&self) -> Eip712Domain {
200+
eip_712_domain(self.signature_chain_id)
201+
}
202+
203+
fn struct_hash(&self) -> B256 {
204+
let items = (
205+
keccak256("HyperliquidTransaction:UsdClassTransfer(string hyperliquidChain,string amount,bool toPerp,uint64 nonce)"),
206+
keccak256(&self.hyperliquid_chain),
207+
keccak256(&self.amount),
208+
self.to_perp,
209+
&self.nonce,
210+
);
211+
keccak256(items.abi_encode())
212+
}
198213
}
199214

200215
#[derive(Serialize, Deserialize, Debug, Clone)]

src/exchange/exchange_client.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
actions::{
1414
ApproveAgent, ApproveBuilderFee, BulkCancel, BulkModify, BulkOrder, ClaimRewards,
1515
EvmUserModify, ScheduleCancel, SetReferrer, UpdateIsolatedMargin, UpdateLeverage,
16-
UsdSend,
16+
UsdClassTransfer, UsdSend,
1717
},
1818
cancel::{CancelRequest, CancelRequestCloid, ClientCancelRequestCloid},
1919
modify::{ClientModifyRequest, ModifyRequest},
@@ -26,8 +26,7 @@ use crate::{
2626
prelude::*,
2727
req::HttpClient,
2828
signature::{sign_l1_action, sign_typed_data},
29-
BaseUrl, BulkCancelCloid, ClassTransfer, Error, ExchangeResponseStatus, SpotSend, SpotUser,
30-
VaultTransfer, Withdraw3,
29+
BaseUrl, BulkCancelCloid, Error, ExchangeResponseStatus, SpotSend, VaultTransfer, Withdraw3,
3130
};
3231

3332
#[derive(Debug)]
@@ -57,6 +56,8 @@ struct ExchangePayload {
5756
#[serde(serialize_with = "serialize_sig")]
5857
signature: Signature,
5958
nonce: u64,
59+
#[serde(skip_serializing_if = "Option::is_none")]
60+
// TODO: check if skip is needed
6061
vault_address: Option<Address>,
6162
}
6263

@@ -73,14 +74,14 @@ pub enum Actions {
7374
BatchModify(BulkModify),
7475
ApproveAgent(ApproveAgent),
7576
Withdraw3(Withdraw3),
76-
SpotUser(SpotUser),
7777
VaultTransfer(VaultTransfer),
7878
SpotSend(SpotSend),
7979
SetReferrer(SetReferrer),
8080
ApproveBuilderFee(ApproveBuilderFee),
8181
EvmUserModify(EvmUserModify),
8282
ScheduleCancel(ScheduleCancel),
8383
ClaimRewards(ClaimRewards),
84+
UsdClassTransfer(UsdClassTransfer),
8485
}
8586

8687
impl Actions {
@@ -217,25 +218,30 @@ impl ExchangeClient {
217218

218219
pub async fn class_transfer(
219220
&self,
220-
usdc: f64,
221+
usd_amount: f64,
221222
to_perp: bool,
222223
wallet: Option<&PrivateKeySigner>,
223224
) -> Result<ExchangeResponseStatus> {
224-
// payload expects usdc without decimals
225-
let usdc = (usdc * 1e6).round() as u64;
226225
let wallet = wallet.unwrap_or(&self.wallet);
226+
let hyperliquid_chain = if self.http_client.is_mainnet() {
227+
"Mainnet".to_string()
228+
} else {
229+
"Testnet".to_string()
230+
};
227231

228-
let timestamp = next_nonce();
229-
230-
let action = Actions::SpotUser(SpotUser {
231-
class_transfer: ClassTransfer { usdc, to_perp },
232-
});
233-
let connection_id = action.hash(timestamp, self.vault_address)?;
234-
let action = serde_json::to_value(&action).map_err(|e| Error::JsonParse(e.to_string()))?;
235-
let is_mainnet = self.http_client.is_mainnet();
236-
let signature = sign_l1_action(wallet, connection_id, is_mainnet)?;
232+
let nonce = next_nonce();
233+
let payload = UsdClassTransfer {
234+
signature_chain_id: 421614,
235+
hyperliquid_chain,
236+
amount: format!("{}", usd_amount),
237+
to_perp,
238+
nonce,
239+
};
240+
let signature = sign_typed_data(&payload, wallet)?;
241+
let action = serde_json::to_value(Actions::UsdClassTransfer(payload))
242+
.map_err(|e| Error::JsonParse(e.to_string()))?;
237243

238-
self.post(action, signature, timestamp).await
244+
self.post(action, signature, nonce).await
239245
}
240246

241247
pub async fn vault_transfer(

0 commit comments

Comments
 (0)