@@ -2221,66 +2221,100 @@ pub fn parse_balance_with_type(data: &Value, account_type: &str) -> Result<Balan
22212221 }
22222222 }
22232223 "linear" | "future" => {
2224- if let Some ( assets) = data[ "assets" ] . as_array ( ) {
2225- for item in assets {
2226- if let Some ( asset) = item[ "asset" ] . as_str ( ) {
2227- let available_balance =
2228- if let Some ( balance_str) = item[ "availableBalance" ] . as_str ( ) {
2229- balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2230- } else {
2231- item[ "availableBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2232- } ;
2224+ // Handle both array response (from /fapi/v2/balance) and object with assets field
2225+ let assets = if let Some ( arr) = data. as_array ( ) {
2226+ arr. clone ( )
2227+ } else if let Some ( arr) = data[ "assets" ] . as_array ( ) {
2228+ arr. clone ( )
2229+ } else {
2230+ vec ! [ ]
2231+ } ;
22332232
2234- let wallet_balance =
2235- if let Some ( balance_str) = item[ "walletBalance" ] . as_str ( ) {
2236- balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2237- } else {
2238- item[ "walletBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2239- } ;
2233+ for item in & assets {
2234+ if let Some ( asset) = item[ "asset" ] . as_str ( ) {
2235+ let available_balance =
2236+ if let Some ( balance_str) = item[ "availableBalance" ] . as_str ( ) {
2237+ balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2238+ } else {
2239+ item[ "availableBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2240+ } ;
22402241
2241- let used = wallet_balance - available_balance;
2242+ let wallet_balance = if let Some ( balance_str) = item[ "walletBalance" ] . as_str ( ) {
2243+ balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2244+ } else {
2245+ item[ "walletBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2246+ } ;
22422247
2243- balances. insert (
2244- asset. to_string ( ) ,
2245- BalanceEntry {
2246- free : Decimal :: from_f64 ( available_balance) . unwrap_or ( Decimal :: ZERO ) ,
2247- used : Decimal :: from_f64 ( used) . unwrap_or ( Decimal :: ZERO ) ,
2248- total : Decimal :: from_f64 ( wallet_balance) . unwrap_or ( Decimal :: ZERO ) ,
2249- } ,
2250- ) ;
2251- }
2248+ // Also check balance field as fallback
2249+ let wallet_balance = if wallet_balance == 0.0 {
2250+ if let Some ( balance_str) = item[ "balance" ] . as_str ( ) {
2251+ balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2252+ } else {
2253+ item[ "balance" ] . as_f64 ( ) . unwrap_or ( wallet_balance)
2254+ }
2255+ } else {
2256+ wallet_balance
2257+ } ;
2258+
2259+ let used = wallet_balance - available_balance;
2260+
2261+ balances. insert (
2262+ asset. to_string ( ) ,
2263+ BalanceEntry {
2264+ free : Decimal :: from_f64 ( available_balance) . unwrap_or ( Decimal :: ZERO ) ,
2265+ used : Decimal :: from_f64 ( used) . unwrap_or ( Decimal :: ZERO ) ,
2266+ total : Decimal :: from_f64 ( wallet_balance) . unwrap_or ( Decimal :: ZERO ) ,
2267+ } ,
2268+ ) ;
22522269 }
22532270 }
22542271 }
22552272 "inverse" | "delivery" => {
2256- if let Some ( assets) = data[ "assets" ] . as_array ( ) {
2257- for item in assets {
2258- if let Some ( asset) = item[ "asset" ] . as_str ( ) {
2259- let available_balance =
2260- if let Some ( balance_str) = item[ "availableBalance" ] . as_str ( ) {
2261- balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2262- } else {
2263- item[ "availableBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2264- } ;
2273+ // Handle both array response and object with assets field
2274+ let assets = if let Some ( arr) = data. as_array ( ) {
2275+ arr. clone ( )
2276+ } else if let Some ( arr) = data[ "assets" ] . as_array ( ) {
2277+ arr. clone ( )
2278+ } else {
2279+ vec ! [ ]
2280+ } ;
22652281
2266- let wallet_balance =
2267- if let Some ( balance_str) = item[ "walletBalance" ] . as_str ( ) {
2268- balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2269- } else {
2270- item[ "walletBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2271- } ;
2282+ for item in & assets {
2283+ if let Some ( asset) = item[ "asset" ] . as_str ( ) {
2284+ let available_balance =
2285+ if let Some ( balance_str) = item[ "availableBalance" ] . as_str ( ) {
2286+ balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2287+ } else {
2288+ item[ "availableBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2289+ } ;
22722290
2273- let used = wallet_balance - available_balance;
2291+ let wallet_balance = if let Some ( balance_str) = item[ "walletBalance" ] . as_str ( ) {
2292+ balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2293+ } else {
2294+ item[ "walletBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2295+ } ;
22742296
2275- balances. insert (
2276- asset. to_string ( ) ,
2277- BalanceEntry {
2278- free : Decimal :: from_f64 ( available_balance) . unwrap_or ( Decimal :: ZERO ) ,
2279- used : Decimal :: from_f64 ( used) . unwrap_or ( Decimal :: ZERO ) ,
2280- total : Decimal :: from_f64 ( wallet_balance) . unwrap_or ( Decimal :: ZERO ) ,
2281- } ,
2282- ) ;
2283- }
2297+ // Also check balance field as fallback
2298+ let wallet_balance = if wallet_balance == 0.0 {
2299+ if let Some ( balance_str) = item[ "balance" ] . as_str ( ) {
2300+ balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2301+ } else {
2302+ item[ "balance" ] . as_f64 ( ) . unwrap_or ( wallet_balance)
2303+ }
2304+ } else {
2305+ wallet_balance
2306+ } ;
2307+
2308+ let used = wallet_balance - available_balance;
2309+
2310+ balances. insert (
2311+ asset. to_string ( ) ,
2312+ BalanceEntry {
2313+ free : Decimal :: from_f64 ( available_balance) . unwrap_or ( Decimal :: ZERO ) ,
2314+ used : Decimal :: from_f64 ( used) . unwrap_or ( Decimal :: ZERO ) ,
2315+ total : Decimal :: from_f64 ( wallet_balance) . unwrap_or ( Decimal :: ZERO ) ,
2316+ } ,
2317+ ) ;
22842318 }
22852319 }
22862320 }
@@ -2314,6 +2348,81 @@ pub fn parse_balance_with_type(data: &Value, account_type: &str) -> Result<Balan
23142348 }
23152349 }
23162350 }
2351+ "option" => {
2352+ // Options account uses equity and available fields
2353+ if let Some ( asset) = data[ "asset" ] . as_str ( ) {
2354+ let equity = if let Some ( equity_str) = data[ "equity" ] . as_str ( ) {
2355+ equity_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2356+ } else {
2357+ data[ "equity" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2358+ } ;
2359+
2360+ let available = if let Some ( available_str) = data[ "available" ] . as_str ( ) {
2361+ available_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2362+ } else {
2363+ data[ "available" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2364+ } ;
2365+
2366+ let used = equity - available;
2367+
2368+ balances. insert (
2369+ asset. to_string ( ) ,
2370+ BalanceEntry {
2371+ free : Decimal :: from_f64 ( available) . unwrap_or ( Decimal :: ZERO ) ,
2372+ used : Decimal :: from_f64 ( used) . unwrap_or ( Decimal :: ZERO ) ,
2373+ total : Decimal :: from_f64 ( equity) . unwrap_or ( Decimal :: ZERO ) ,
2374+ } ,
2375+ ) ;
2376+ }
2377+ }
2378+ "portfolio" => {
2379+ // Portfolio margin balance - can be array or single object
2380+ let assets = if let Some ( arr) = data. as_array ( ) {
2381+ arr. clone ( )
2382+ } else if data. is_object ( ) {
2383+ vec ! [ data. clone( ) ]
2384+ } else {
2385+ vec ! [ ]
2386+ } ;
2387+
2388+ for item in & assets {
2389+ if let Some ( asset) = item[ "asset" ] . as_str ( ) {
2390+ let total_wallet_balance =
2391+ if let Some ( balance_str) = item[ "totalWalletBalance" ] . as_str ( ) {
2392+ balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2393+ } else {
2394+ item[ "totalWalletBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2395+ } ;
2396+
2397+ let available_balance =
2398+ if let Some ( balance_str) = item[ "availableBalance" ] . as_str ( ) {
2399+ balance_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2400+ } else {
2401+ item[ "availableBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2402+ } ;
2403+
2404+ // Fallback to crossWalletBalance if availableBalance not present
2405+ let free = if available_balance > 0.0 {
2406+ available_balance
2407+ } else if let Some ( cross_str) = item[ "crossWalletBalance" ] . as_str ( ) {
2408+ cross_str. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
2409+ } else {
2410+ item[ "crossWalletBalance" ] . as_f64 ( ) . unwrap_or ( 0.0 )
2411+ } ;
2412+
2413+ let used = total_wallet_balance - free;
2414+
2415+ balances. insert (
2416+ asset. to_string ( ) ,
2417+ BalanceEntry {
2418+ free : Decimal :: from_f64 ( free) . unwrap_or ( Decimal :: ZERO ) ,
2419+ used : Decimal :: from_f64 ( used) . unwrap_or ( Decimal :: ZERO ) ,
2420+ total : Decimal :: from_f64 ( total_wallet_balance) . unwrap_or ( Decimal :: ZERO ) ,
2421+ } ,
2422+ ) ;
2423+ }
2424+ }
2425+ }
23172426 _ => {
23182427 return Err ( Error :: from ( ParseError :: invalid_value (
23192428 "account_type" ,
0 commit comments