|
@@ -1,10 +1,10 @@
|
|
|
use std::str::FromStr;
|
|
use std::str::FromStr;
|
|
|
-use chrono::Utc;
|
|
|
|
|
-use anyhow::{anyhow, bail, Result};
|
|
|
|
|
|
|
+use chrono::{Duration, Timelike, Utc};
|
|
|
|
|
+use anyhow::{anyhow, bail, Context, Result};
|
|
|
use reqwest::Client;
|
|
use reqwest::Client;
|
|
|
use reqwest::header::HeaderMap;
|
|
use reqwest::header::HeaderMap;
|
|
|
use rust_decimal::Decimal;
|
|
use rust_decimal::Decimal;
|
|
|
-use rust_decimal::prelude::FromPrimitive;
|
|
|
|
|
|
|
+use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
|
|
|
use rust_decimal_macros::dec;
|
|
use rust_decimal_macros::dec;
|
|
|
use serde_json::{json, Value};
|
|
use serde_json::{json, Value};
|
|
|
use starknet::core::types::Felt;
|
|
use starknet::core::types::Felt;
|
|
@@ -154,6 +154,20 @@ impl ExtendedRestClient {
|
|
|
pub async fn post_order(&mut self, order_type: &str, side: &str, qty: &str, price: &str) -> Result<Response> {
|
|
pub async fn post_order(&mut self, order_type: &str, side: &str, qty: &str, price: &str) -> Result<Response> {
|
|
|
let account = self.account.clone().ok_or_else(|| anyhow!("请将账户传入再进行下单操作"))?;
|
|
let account = self.account.clone().ok_or_else(|| anyhow!("请将账户传入再进行下单操作"))?;
|
|
|
|
|
|
|
|
|
|
+ // 时间戳处理
|
|
|
|
|
+ // 1. 获取当前时间,并增加 14 天的缓冲期
|
|
|
|
|
+ let now = Utc::now();
|
|
|
|
|
+ let expire_time_with_buffer = now + Duration::days(14);
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 向上取整到秒
|
|
|
|
|
+ // 先截断到秒,如果原始时间在截断之后,说明有纳秒部分,需要再加一秒
|
|
|
|
|
+ let mut expire_time_rounded = expire_time_with_buffer.with_nanosecond(0).unwrap();
|
|
|
|
|
+ if expire_time_with_buffer > expire_time_rounded {
|
|
|
|
|
+ expire_time_rounded += Duration::seconds(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 3. 获取 Unix 时间戳 (秒)
|
|
|
|
|
+ let expire_time_as_seconds = expire_time_rounded.timestamp();
|
|
|
|
|
+
|
|
|
// 需要传给extended的参数整理
|
|
// 需要传给extended的参数整理
|
|
|
let id = Uuid::new_v4().to_string();
|
|
let id = Uuid::new_v4().to_string();
|
|
|
let market = self.market.as_str();
|
|
let market = self.market.as_str();
|
|
@@ -162,7 +176,7 @@ impl ExtendedRestClient {
|
|
|
// qty
|
|
// qty
|
|
|
// price
|
|
// price
|
|
|
let time_in_force = "GTT";
|
|
let time_in_force = "GTT";
|
|
|
- let expiry_epoch_millis = Utc::now().timestamp_millis() + (60 * 60 * 1000);
|
|
|
|
|
|
|
+ let expiry_epoch_millis = expire_time_rounded.timestamp_millis();
|
|
|
let nonce_u32: u32 = rand::random();
|
|
let nonce_u32: u32 = rand::random();
|
|
|
let nonce = nonce_u32.to_string();
|
|
let nonce = nonce_u32.to_string();
|
|
|
let self_trade_protection_level = "ACCOUNT";
|
|
let self_trade_protection_level = "ACCOUNT";
|
|
@@ -211,12 +225,18 @@ impl ExtendedRestClient {
|
|
|
// 其余参数
|
|
// 其余参数
|
|
|
let position_id = format!("{}", account.vault_number);
|
|
let position_id = format!("{}", account.vault_number);
|
|
|
let base_asset_id_hex = l2_config.get("syntheticId").unwrap().as_str().unwrap().to_string();
|
|
let base_asset_id_hex = l2_config.get("syntheticId").unwrap().as_str().unwrap().to_string();
|
|
|
- let base_amount = stark_synthetic_amount.to_string();
|
|
|
|
|
|
|
+ let base_amount = stark_synthetic_amount.to_i64()
|
|
|
|
|
+ .context("stark_synthetic_amount 无法转换为 i64")?
|
|
|
|
|
+ .to_string();
|
|
|
let quote_asset_id_hex = l2_config.get("collateralId").unwrap().as_str().unwrap().to_string();
|
|
let quote_asset_id_hex = l2_config.get("collateralId").unwrap().as_str().unwrap().to_string();
|
|
|
- let quote_amount = stark_collateral_amount.to_string();
|
|
|
|
|
|
|
+ let quote_amount = stark_collateral_amount.to_i64()
|
|
|
|
|
+ .context("stark_collateral_amount 无法转换为 i64")?
|
|
|
|
|
+ .to_string();
|
|
|
let fee_asset_id_hex = l2_config.get("collateralId").unwrap().as_str().unwrap().to_string();
|
|
let fee_asset_id_hex = l2_config.get("collateralId").unwrap().as_str().unwrap().to_string();
|
|
|
- let fee_amount = stark_fee_part.to_string();
|
|
|
|
|
- let expiration = format!("{}", (expiry_epoch_millis / 1000) as u64);
|
|
|
|
|
|
|
+ let fee_amount = stark_fee_part.to_u64() // Fee 通常是正数
|
|
|
|
|
+ .context("stark_fee_part 无法转换为 u64")?
|
|
|
|
|
+ .to_string();
|
|
|
|
|
+ let expiration = expire_time_as_seconds.to_string();
|
|
|
let salt = nonce.clone();
|
|
let salt = nonce.clone();
|
|
|
let user_public_key_hex = account.stark_public_key.clone();
|
|
let user_public_key_hex = account.stark_public_key.clone();
|
|
|
let domain_name = "Perpetuals".to_string();
|
|
let domain_name = "Perpetuals".to_string();
|
|
@@ -491,6 +511,7 @@ mod tests {
|
|
|
async fn test_create_order() {
|
|
async fn test_create_order() {
|
|
|
let _guard = setup_logging().unwrap();
|
|
let _guard = setup_logging().unwrap();
|
|
|
let mut client = get_client().await;
|
|
let mut client = get_client().await;
|
|
|
|
|
+ info!("{}", serde_json::to_string_pretty(&client.market_info).unwrap());
|
|
|
let response_result = client.post_order("LIMIT", "BUY", "0.0001", "100000").await;
|
|
let response_result = client.post_order("LIMIT", "BUY", "0.0001", "100000").await;
|
|
|
|
|
|
|
|
match response_result {
|
|
match response_result {
|