Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b5e353e
Revert "remove SendAsset payload_multi_sig_user & outer_signer"
luca992 Nov 10, 2025
fb71f22
add back outer_signer and payload_multi_sig_user to SendAsset but do …
luca992 Nov 10, 2025
4acc577
lowercase destinations
luca992 Nov 10, 2025
6abff7b
lowercase payload addresses
luca992 Nov 10, 2025
d1fe9e2
try signature_chain_id: "0x1"
luca992 Nov 11, 2025
9145271
set fixed nonce for debugging
luca992 Nov 11, 2025
4451ce2
log action_without_type
luca992 Nov 11, 2025
6960c72
serde_json enable preserve_order
luca992 Nov 11, 2025
8c46664
preserve map order when removing from action
luca992 Nov 11, 2025
1180276
insert type at the start of the action
luca992 Nov 11, 2025
11a489a
Revert "set fixed nonce for debugging"
luca992 Nov 11, 2025
3b03853
Revert "try signature_chain_id: "0x1""
luca992 Nov 11, 2025
5d81c38
Revert "log action_without_type"
luca992 Nov 11, 2025
d5ad466
Reapply "try signature_chain_id: "0x1""
luca992 Nov 11, 2025
b79d86a
debug with hardcoded nonce
luca992 Nov 11, 2025
c45b036
Reapply "log action_without_type"
luca992 Nov 11, 2025
97d4d1f
log hex
luca992 Nov 11, 2025
9351159
Prevent serializing actions to value before needed
luca992 Nov 11, 2025
c660e12
Revert "debug with hardcoded nonce"
luca992 Nov 11, 2025
3c72658
serialize Signature r & s to strings
luca992 Nov 11, 2025
700679d
Reapply "debug with hardcoded nonce"
luca992 Nov 11, 2025
97303d3
MultiSigEnvelope use the signature_chain_id from the MultiSigAction
luca992 Nov 11, 2025
48b33bd
Revert "Reapply "debug with hardcoded nonce""
luca992 Nov 11, 2025
2bc8732
revert debug print
luca992 Nov 11, 2025
5ef467f
revert adding preserve_order serde_json feature
luca992 Nov 11, 2025
81b6f51
Revert "revert adding preserve_order serde_json feature"
luca992 Nov 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ repository = "https://github.com/hyperliquid-dex/hyperliquid-rust-sdk"

[dependencies]
alloy = { version = "1.0", default-features = false, features = [
"dyn-abi",
"sol-types",
"signer-local",
"dyn-abi",
"sol-types",
"signer-local",
] }
chrono = "0.4.26"
env_logger = "0.11.8"
Expand All @@ -24,9 +24,9 @@ lazy_static = "1.0"
log = "0.4.19"
reqwest = "0.12.19"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_json = { version = "1.0", features = ["preserve_order"] }
rmp-serde = "1.0"
thiserror = "2.0"
tokio = { version = "1.0", features = ["full"] }
tokio-tungstenite = { version = "0.20.0", features = ["native-tls"] }
tokio-tungstenite = { version = "0.28.0", features = ["native-tls"] }
uuid = { version = "1.0", features = ["v4"] }
5 changes: 3 additions & 2 deletions src/bin/multi_sig_order_signature_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn demonstrate_order_signature_collection() -> Result<()> {

// Create the order action
// All signers must create the exact same action
let action = serde_json::json!({
let action = serde_json::from_value(serde_json::json!({
"type": "order",
"orders": [{
"a": 0, // asset index (0 = BTC)
Expand All @@ -48,7 +48,8 @@ fn demonstrate_order_signature_collection() -> Result<()> {
"t": {"limit": {"tif": "Gtc"}}
}],
"grouping": "na"
});
}))
.unwrap();

info!("Order action:");
info!("{}\n", serde_json::to_string_pretty(&action)?);
Expand Down
20 changes: 16 additions & 4 deletions src/bin/multi_sig_signature_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
/// Usage:
/// cargo run --bin multi_sig_signature_collection
use alloy::signers::{local::PrivateKeySigner, Signature};
use hyperliquid_rust_sdk::{sign_multi_sig_user_signed_action_single, SendAsset};
use hyperliquid_rust_sdk::{
sign_multi_sig_user_signed_action_single, MultiSigExtension, SendAsset,
};
use log::info;
use std::str::FromStr;

Expand Down Expand Up @@ -54,7 +56,7 @@ fn demonstrate_signature_collection() -> Result<()> {
info!("Signer 2 address: {}", signer2_wallet.address());

// Both signers create the same SendAsset action
let send_asset = create_send_asset(destination, amount, nonce);
let send_asset = create_send_asset(multi_sig_user, outer_signer, destination, amount, nonce);

// Signer 1 signs
let sig1 = sign_multi_sig_user_signed_action_single(&signer1_wallet, &send_asset)?;
Expand Down Expand Up @@ -115,17 +117,27 @@ fn demonstrate_signature_collection() -> Result<()> {
}

/// Create a SendAsset action - must be identical for all signers
fn create_send_asset(destination: &str, amount: &str, nonce: u64) -> SendAsset {
fn create_send_asset(
multi_sig_user: alloy::primitives::Address,
outer_signer: alloy::primitives::Address,
destination: &str,
amount: &str,
nonce: u64,
) -> SendAsset {
SendAsset {
signature_chain_id: 421614,
hyperliquid_chain: "Testnet".to_string(),
destination: destination.to_string(),
destination: destination.to_lowercase(),
source_dex: "".to_string(),
destination_dex: "".to_string(),
token: "USDC".to_string(),
amount: amount.to_string(),
from_sub_account: "".to_string(),
nonce,
multi_sig_ext: Some(MultiSigExtension {
payload_multi_sig_user: format!("{:#x}", multi_sig_user).to_lowercase(),
outer_signer: format!("{:#x}", outer_signer).to_lowercase(),
}),
}
}

Expand Down
32 changes: 30 additions & 2 deletions src/exchange/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ where
s.serialize_str(&format!("0x{val:x}"))
}

#[derive(Debug, Clone, Deserialize)]
pub struct MultiSigExtension {
pub payload_multi_sig_user: String,
pub outer_signer: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UsdSend {
Expand Down Expand Up @@ -210,6 +216,8 @@ pub struct SendAsset {
pub amount: String,
pub from_sub_account: String,
pub nonce: u64,
#[serde(skip)]
pub multi_sig_ext: Option<MultiSigExtension>,
}

impl Eip712 for SendAsset {
Expand All @@ -218,7 +226,26 @@ impl Eip712 for SendAsset {
}

fn struct_hash(&self) -> B256 {
let items = (
if let Some(multi_sig_ext) = &self.multi_sig_ext {
let multi_sig_user: Address = multi_sig_ext.payload_multi_sig_user.parse().unwrap();
let outer_signer: Address = multi_sig_ext.outer_signer.parse().unwrap();

let items = (
keccak256("HyperliquidTransaction:SendAsset(string hyperliquidChain,address payloadMultiSigUser,address outerSigner,string destination,string sourceDex,string destinationDex,string token,string amount,string fromSubAccount,uint64 nonce)"),
keccak256(&self.hyperliquid_chain),
multi_sig_user,
outer_signer,
keccak256(&self.destination),
keccak256(&self.source_dex),
keccak256(&self.destination_dex),
keccak256(&self.token),
keccak256(&self.amount),
keccak256(&self.from_sub_account),
&self.nonce,
);
keccak256(items.abi_encode())
} else {
let items = (
keccak256("HyperliquidTransaction:SendAsset(string hyperliquidChain,string destination,string sourceDex,string destinationDex,string token,string amount,string fromSubAccount,uint64 nonce)"),
keccak256(&self.hyperliquid_chain),
keccak256(&self.destination),
Expand All @@ -229,7 +256,8 @@ impl Eip712 for SendAsset {
keccak256(&self.from_sub_account),
&self.nonce,
);
keccak256(items.abi_encode())
keccak256(items.abi_encode())
}
}
}

Expand Down
Loading