polynode 0.7.3

Rust SDK for the PolyNode API — real-time Polymarket data
Documentation
//! Compilation + runtime test for every public type in the trading module.
//! Run: cargo run --features trading --example test_trading_types

use polynode::trading::{
    // Core trader
    PolyNodeTrader, TraderConfig,
    // Signer
    PrivateKeySigner, TradingSigner,
    // Onboarding functions
    derive_safe_address, derive_proxy_address, derive_funder_address,
    // Cosigner
    build_l2_headers,
    // Types
    SignatureType, OrderSide, OrderType, OrderParams,
    ClobCredentials, ReadyStatus, LinkResult, WalletInfo, WalletExport,
    ApprovalStatus, UsdcApprovals, CtfApprovals, BalanceInfo,
    OrderResult, CancelResult, OpenOrder,
    MarketMeta, OrderHistoryRow, HistoryParams, StoredCredentials,
    CosignerRequest, Eip712Payload,
    // Sqlite backend
    TradingSqliteBackend,
};
use std::collections::HashMap;

fn main() {
    println!("=== Trading Module Type Test ===\n");

    // 1. Generate a wallet
    let (private_key, address) = PolyNodeTrader::generate_wallet();
    println!("[generate_wallet]");
    println!("  private_key: {}", private_key);
    println!("  address:     {}", address);
    println!();

    // 2. Create PrivateKeySigner from generated key
    let signer = PrivateKeySigner::from_hex(&private_key).expect("signer from generated key");
    println!("[PrivateKeySigner::from_hex]");
    println!("  address: {:?}", signer.address());
    println!();

    // 3. TraderConfig with defaults
    let config = TraderConfig::default();
    println!("[TraderConfig::default()]");
    println!("  polynode_key:            \"{}\"", config.polynode_key);
    println!("  db_path:                 \"{}\"", config.db_path);
    println!("  cosigner_url:            \"{}\"", config.cosigner_url);
    println!("  fallback_direct:         {}", config.fallback_direct);
    println!("  default_signature_type:  {:?}", config.default_signature_type);
    println!("  rpc_url:                 \"{}\"", config.rpc_url);
    println!();

    // 4. Create PolyNodeTrader
    let config2 = TraderConfig {
        polynode_key: "pn_live_test_example".into(),
        db_path: "/tmp/test_trading_types.db".into(),
        ..Default::default()
    };
    let _trader = PolyNodeTrader::new(config2).expect("create trader");
    println!("[PolyNodeTrader::new] OK");
    println!();

    // 5. Derive Safe and Proxy addresses from a known EOA
    //    Using Vitalik's address as a well-known reference
    let known_eoa: alloy_primitives::Address =
        "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045".parse().unwrap();
    let safe_addr = derive_safe_address(known_eoa);
    let proxy_addr = derive_proxy_address(known_eoa);
    let funder_eoa = derive_funder_address(known_eoa, SignatureType::Eoa);
    let funder_safe = derive_funder_address(known_eoa, SignatureType::PolyGnosisSafe);
    let funder_proxy = derive_funder_address(known_eoa, SignatureType::PolyProxy);

    println!("[derive addresses for 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045]");
    println!("  derive_safe_address:   {:?}", safe_addr);
    println!("  derive_proxy_address:  {:?}", proxy_addr);
    println!("  funder (Eoa):          {:?}", funder_eoa);
    println!("  funder (GnosisSafe):   {:?}", funder_safe);
    println!("  funder (PolyProxy):    {:?}", funder_proxy);
    println!();

    // Also derive for the freshly generated wallet
    let gen_eoa: alloy_primitives::Address = address.parse().unwrap();
    let gen_safe = derive_safe_address(gen_eoa);
    let gen_proxy = derive_proxy_address(gen_eoa);
    println!("[derive addresses for generated wallet {}]", address);
    println!("  derive_safe_address:   {:?}", gen_safe);
    println!("  derive_proxy_address:  {:?}", gen_proxy);
    println!();

    // 6. Build L2 headers with dummy credentials
    let headers = build_l2_headers(
        "test-api-key-abc123",
        "dGVzdC1hcGktc2VjcmV0LXh5ejc4OQ==",  // base64("test-api-secret-xyz789")
        "test-passphrase",
        "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
        "POST",
        "/order",
        Some(r#"{"order":{"tokenId":"123"}}"#),
    );
    println!("[build_l2_headers]");
    for (k, v) in headers.iter() {
        println!("  {}: {}", k, v);
    }
    println!();

    // 7. Instantiate all remaining public types to prove they compile
    println!("[type instantiation checks]");

    let _sig_type = SignatureType::Eoa;
    let _sig_type2 = SignatureType::PolyProxy;
    let _sig_type3 = SignatureType::PolyGnosisSafe;
    println!("  SignatureType:       Eoa={}, PolyProxy={}, PolyGnosisSafe={}",
        SignatureType::Eoa.as_u8(),
        SignatureType::PolyProxy.as_u8(),
        SignatureType::PolyGnosisSafe.as_u8());

    let _order_side_buy = OrderSide::Buy;
    let _order_side_sell = OrderSide::Sell;
    println!("  OrderSide:           Buy={}, Sell={}", OrderSide::Buy, OrderSide::Sell);

    let _ot_gtc = OrderType::GTC;
    let _ot_gtd = OrderType::GTD;
    let _ot_fok = OrderType::FOK;
    let _ot_fak = OrderType::FAK;
    println!("  OrderType:           GTC={}, GTD={}, FOK={}, FAK={}",
        OrderType::GTC, OrderType::GTD, OrderType::FOK, OrderType::FAK);

    let _params = OrderParams {
        token_id: "12345".into(),
        side: OrderSide::Buy,
        price: 0.55,
        size: 100.0,
        order_type: OrderType::GTC,
        expiration: None,
        post_only: false,
    };
    println!("  OrderParams:         OK (default + explicit)");

    let _creds = ClobCredentials {
        api_key: "key".into(),
        api_secret: "secret".into(),
        api_passphrase: "pass".into(),
    };
    println!("  ClobCredentials:     OK");

    let _meta = MarketMeta {
        token_id: "abc".into(),
        tick_size: "0.01".into(),
        fee_rate_bps: 0,
        neg_risk: false,
        fetched_at: 0.0,
    };
    println!("  MarketMeta:          OK");

    let _history_params = HistoryParams::default();
    println!("  HistoryParams:       OK (default)");

    let _cosigner_req = CosignerRequest {
        method: "POST".into(),
        path: "/order".into(),
        body: Some("{}".into()),
        headers: HashMap::new(),
    };
    println!("  CosignerRequest:     OK");

    let _eip712 = Eip712Payload {
        domain: serde_json::json!({}),
        types: serde_json::json!({}),
        primary_type: "Order".into(),
        message: serde_json::json!({}),
    };
    println!("  Eip712Payload:       OK");

    let _stored = StoredCredentials {
        wallet_address: "0x123".into(),
        funder_address: Some("0x456".into()),
        api_key: "k".into(),
        api_secret: "s".into(),
        api_passphrase: "p".into(),
        signature_type: SignatureType::PolyGnosisSafe,
        safe_deployed: false,
        approvals_set: false,
        created_at: 0.0,
        updated_at: 0.0,
    };
    println!("  StoredCredentials:   OK");

    // Types that are only returned (not constructed by users) — verify they exist
    // by referencing their fields in a type annotation context
    fn _assert_ready_status(s: &ReadyStatus) {
        let _ = (&s.wallet, &s.funder_address, &s.signature_type, &s.safe_deployed,
                 &s.approvals_set, &s.credentials_stored, &s.credentials, &s.actions);
    }
    fn _assert_link_result(s: &LinkResult) {
        let _ = (&s.wallet, &s.funder_address, &s.signature_type, &s.credentials);
    }
    fn _assert_wallet_info(s: &WalletInfo) {
        let _ = (&s.wallet, &s.funder_address, &s.signature_type, &s.credentials, &s.created_at);
    }
    fn _assert_wallet_export(s: &WalletExport) {
        let _ = (&s.wallet, &s.funder_address, &s.signature_type, &s.credentials,
                 &s.safe_deployed, &s.approvals_set, &s.created_at);
    }
    fn _assert_approval_status(s: &ApprovalStatus) {
        let _ = (&s.funder_address, &s.usdc, &s.ctf, &s.all_approved);
    }
    fn _assert_usdc_approvals(s: &UsdcApprovals) {
        let _ = (&s.ctf_exchange, &s.neg_risk_ctf_exchange, &s.neg_risk_adapter);
    }
    fn _assert_ctf_approvals(s: &CtfApprovals) {
        let _ = (&s.ctf_exchange, &s.neg_risk_ctf_exchange, &s.neg_risk_adapter);
    }
    fn _assert_balance_info(s: &BalanceInfo) {
        let _ = (&s.funder_address, &s.usdc, &s.usdc_raw, &s.matic);
    }
    fn _assert_order_result(s: &OrderResult) {
        let _ = (&s.success, &s.order_id, &s.status, &s.error, &s.making_amount, &s.taking_amount);
    }
    fn _assert_cancel_result(s: &CancelResult) {
        let _ = (&s.canceled, &s.not_canceled);
    }
    fn _assert_open_order(s: &OpenOrder) {
        let _ = (&s.id, &s.market, &s.asset_id, &s.side, &s.price,
                 &s.original_size, &s.size_matched, &s.status, &s.created_at, &s.order_type);
    }
    fn _assert_order_history_row(s: &OrderHistoryRow) {
        let _ = (&s.id, &s.wallet_address, &s.order_id, &s.token_id, &s.side,
                 &s.price, &s.size, &s.order_type, &s.status, &s.error_msg,
                 &s.response_json, &s.created_at);
    }
    println!("  ReadyStatus:         OK (field access verified)");
    println!("  LinkResult:          OK (field access verified)");
    println!("  WalletInfo:          OK (field access verified)");
    println!("  WalletExport:        OK (field access verified)");
    println!("  ApprovalStatus:      OK (field access verified)");
    println!("  UsdcApprovals:       OK (field access verified)");
    println!("  CtfApprovals:        OK (field access verified)");
    println!("  BalanceInfo:         OK (field access verified)");
    println!("  OrderResult:         OK (field access verified)");
    println!("  CancelResult:        OK (field access verified)");
    println!("  OpenOrder:           OK (field access verified)");
    println!("  OrderHistoryRow:     OK (field access verified)");

    // TradingSqliteBackend — just verify the type exists
    let _: fn(&str) -> polynode::Result<TradingSqliteBackend> = TradingSqliteBackend::open;
    println!("  TradingSqliteBackend: OK (type reference verified)");

    println!("\n=== All types compiled and instantiated successfully ===");
}