|  | 
| 1 | 1 | use alloy::{primitives::Address, signers::local::PrivateKeySigner}; | 
| 2 | 2 | use hyperliquid_rust_sdk::{BaseUrl, ClientLimit, ClientOrder, ClientOrderRequest, ExchangeClient}; | 
| 3 | 3 | use log::info; | 
| 4 |  | -use serde_json::json; | 
| 5 | 4 | 
 | 
| 6 | 5 | fn setup_multi_sig_wallets() -> Vec<PrivateKeySigner> { | 
|  | 6 | +    // These are example private keys - in production, these would be the authorized | 
|  | 7 | +    // user wallets that have permission to sign for the multi-sig account | 
| 7 | 8 |     let wallets = vec![ | 
| 8 | 9 |         "0x1234567890123456789012345678901234567890123456789012345678901234", | 
| 9 | 10 |         "0x2345678901234567890123456789012345678901234567890123456789012345", | 
| @@ -37,58 +38,85 @@ async fn main() { | 
| 37 | 38 | 
 | 
| 38 | 39 |     let (address, exchange_client) = setup_exchange_client().await; | 
| 39 | 40 | 
 | 
|  | 41 | +    // Set up the multi-sig wallets that are authorized to sign for the multi-sig user | 
|  | 42 | +    // Each wallet must belong to a user that has been added as an authorized signer | 
|  | 43 | +    let multi_sig_wallets = setup_multi_sig_wallets(); | 
|  | 44 | + | 
|  | 45 | +    // The outer signer is required to be an authorized user or an agent of the | 
|  | 46 | +    // authorized user of the multi-sig user. | 
|  | 47 | + | 
|  | 48 | +    // Address of the multi-sig user that the action will be executed for | 
|  | 49 | +    // Executing the action requires at least the specified threshold of signatures | 
|  | 50 | +    // required for that multi-sig user | 
| 40 | 51 |     let multi_sig_user: Address = "0x0000000000000000000000000000000000000005" | 
| 41 | 52 |         .parse() | 
| 42 | 53 |         .unwrap(); | 
| 43 | 54 | 
 | 
| 44 |  | -    let timestamp = chrono::Utc::now().timestamp_millis() as u64; | 
| 45 |  | - | 
| 46 |  | -    let action = json!({ | 
| 47 |  | -        "type": "order", | 
| 48 |  | -        "orders": [{ | 
| 49 |  | -            "a": 0, // ETH asset index | 
| 50 |  | -            "b": true, | 
| 51 |  | -            "p": "1800", | 
| 52 |  | -            "s": "0.01", | 
| 53 |  | -            "r": false, | 
| 54 |  | -            "t": {"limit": {"tif": "Gtc"}} | 
| 55 |  | -        }], | 
| 56 |  | -        "grouping": "na", | 
| 57 |  | -    }); | 
| 58 |  | - | 
| 59 |  | -    let typed_order = ClientOrderRequest { | 
| 60 |  | -        asset: "ETH".to_string(), | 
| 61 |  | -        is_buy: true, | 
| 62 |  | -        reduce_only: false, | 
| 63 |  | -        limit_px: 1800.0, | 
| 64 |  | -        sz: 0.01, | 
| 65 |  | -        cloid: None, | 
| 66 |  | -        order_type: ClientOrder::Limit(ClientLimit { | 
| 67 |  | -            tif: "Gtc".to_string(), | 
| 68 |  | -        }), | 
| 69 |  | -    }; | 
| 70 |  | - | 
| 71 |  | -    info!("Multi-sig user: {}", multi_sig_user); | 
|  | 55 | +    info!("=== Multi-Sig Order Example ==="); | 
|  | 56 | +    info!("Multi-sig user address: {}", multi_sig_user); | 
| 72 | 57 |     info!("Outer signer (current wallet): {}", address); | 
| 73 | 58 |     info!( | 
| 74 | 59 |         "Exchange client connected to: {:?}", | 
| 75 | 60 |         exchange_client.http_client.base_url | 
| 76 | 61 |     ); | 
| 77 |  | -    info!("Action: {}", action); | 
| 78 |  | -    info!("Typed order: {:?}", typed_order); | 
| 79 |  | -    info!("Timestamp: {}", timestamp); | 
| 80 |  | - | 
| 81 |  | -    let multi_sig_wallets = setup_multi_sig_wallets(); | 
| 82 | 62 |     info!( | 
| 83 |  | -        "Multi-sig wallets: {:?}", | 
|  | 63 | +        "Authorized wallets ({} total): {:?}", | 
|  | 64 | +        multi_sig_wallets.len(), | 
| 84 | 65 |         multi_sig_wallets | 
| 85 | 66 |             .iter() | 
| 86 | 67 |             .map(|w| w.address()) | 
| 87 | 68 |             .collect::<Vec<_>>() | 
| 88 | 69 |     ); | 
| 89 | 70 | 
 | 
| 90 |  | -    info!("Multi-sig order functionality is not yet implemented in the Rust SDK"); | 
| 91 |  | -    info!("This example shows the structure and parameters that would be used:"); | 
|  | 71 | +    // Define the multi-sig inner action - in this case, placing an order | 
|  | 72 | +    // This matches the Python example: asset index 4, buy, price 1100, size 0.2 | 
|  | 73 | +    let order = ClientOrderRequest { | 
|  | 74 | +        asset: "ETH".to_string(), // Asset index 4 in Python corresponds to ETH | 
|  | 75 | +        is_buy: true, | 
|  | 76 | +        reduce_only: false, | 
|  | 77 | +        limit_px: 1100.0, | 
|  | 78 | +        sz: 0.2, | 
|  | 79 | +        cloid: None, | 
|  | 80 | +        order_type: ClientOrder::Limit(ClientLimit { | 
|  | 81 | +            tif: "Gtc".to_string(), | 
|  | 82 | +        }), | 
|  | 83 | +    }; | 
|  | 84 | + | 
|  | 85 | +    info!(""); | 
|  | 86 | +    info!("Order details: {:?}", order); | 
|  | 87 | +    info!("Executing multi-sig order..."); | 
|  | 88 | +    info!( | 
|  | 89 | +        "Collecting signatures from {} authorized wallets...", | 
|  | 90 | +        multi_sig_wallets.len() | 
|  | 91 | +    ); | 
|  | 92 | + | 
|  | 93 | +    // Execute the multi-sig order | 
|  | 94 | +    // This will collect signatures from all provided wallets and submit them together | 
|  | 95 | +    // The action will only succeed if enough valid signatures are provided (>= threshold) | 
|  | 96 | +    match exchange_client | 
|  | 97 | +        .multi_sig_order(multi_sig_user, order, &multi_sig_wallets) | 
|  | 98 | +        .await | 
|  | 99 | +    { | 
|  | 100 | +        Ok(response) => { | 
|  | 101 | +            info!("✓ Multi-sig order placed successfully!"); | 
|  | 102 | +            info!("Response: {:?}", response); | 
|  | 103 | +        } | 
|  | 104 | +        Err(e) => { | 
|  | 105 | +            info!("✗ Multi-sig order failed: {}", e); | 
|  | 106 | +            info!(""); | 
|  | 107 | +            info!("This is expected if:"); | 
|  | 108 | +            info!("  • The multi-sig user is not properly configured"); | 
|  | 109 | +            info!("  • The provided wallets are not authorized signers"); | 
|  | 110 | +            info!("  • Not enough signatures provided to meet threshold"); | 
|  | 111 | +            info!(""); | 
|  | 112 | +            info!("To use in production:"); | 
|  | 113 | +            info!("  1. Convert a user to multi-sig: convert_to_multi_sig()"); | 
|  | 114 | +            info!("  2. Add authorized addresses: update_multi_sig_addresses()"); | 
|  | 115 | +            info!("  3. Use those authorized wallets to sign transactions"); | 
|  | 116 | +            info!("  4. Ensure you provide >= threshold number of valid signatures"); | 
|  | 117 | +        } | 
|  | 118 | +    } | 
| 92 | 119 | 
 | 
| 93 |  | -    info!("Example completed successfully - multi-sig order parameters validated"); | 
|  | 120 | +    info!(""); | 
|  | 121 | +    info!("Example completed"); | 
| 94 | 122 | } | 
0 commit comments