ostium-python-sdk 2.0.21__tar.gz → 3.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/PKG-INFO +38 -1
  2. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/abi/trading_abi.py +29 -60
  3. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/ostium.py +156 -9
  4. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk.egg-info/PKG-INFO +38 -1
  5. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk.egg-info/SOURCES.txt +2 -0
  6. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/setup.py +1 -1
  7. ostium_python_sdk-3.0.0/tests/disabled_test_builder_fee.py +250 -0
  8. ostium_python_sdk-3.0.0/tests/disabled_test_close_trade.py +544 -0
  9. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/MANIFEST.in +0 -0
  10. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/README.md +0 -0
  11. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/__init__.py +0 -0
  12. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/abi/__init__.py +0 -0
  13. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/abi/faucet_testnet_abi.py +0 -0
  14. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/abi/pairs_info_abi.py +0 -0
  15. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/abi/pairs_storage_abi.py +0 -0
  16. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/abi/trading_storage_abi.py +0 -0
  17. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/abi/usdc_abi.py +0 -0
  18. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/abi/vault_abi.py +0 -0
  19. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/balance.py +0 -0
  20. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/config.py +0 -0
  21. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/constants.py +0 -0
  22. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/exceptions.py +0 -0
  23. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/faucet.py +0 -0
  24. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/formulae.py +0 -0
  25. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/formulae_wrapper.py +0 -0
  26. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/price.py +0 -0
  27. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/scscript/__init__.py +0 -0
  28. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/scscript/funding.py +0 -0
  29. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/scscript/pairinfos.py +0 -0
  30. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/sdk.py +0 -0
  31. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/subgraph.py +0 -0
  32. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk/utils.py +0 -0
  33. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk.egg-info/dependency_links.txt +0 -0
  34. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk.egg-info/requires.txt +0 -0
  35. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/ostium_python_sdk.egg-info/top_level.txt +0 -0
  36. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/pyproject.toml +0 -0
  37. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/requirements-dev.txt +0 -0
  38. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/requirements.txt +0 -0
  39. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/setup.cfg +0 -0
  40. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/__init__.py +0 -0
  41. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/conftest.py +0 -0
  42. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/disabled_test_funding.py +0 -0
  43. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/disabled_test_slippage.py +0 -0
  44. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_current_total_profit_p.py +0 -0
  45. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_current_total_profit_raw.py +0 -0
  46. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_current_trade_profit_p.py +0 -0
  47. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_current_trade_profit_raw.py +0 -0
  48. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_get_opening_fee.py +0 -0
  49. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_get_pending_acc_funding_fees.py +0 -0
  50. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_get_price_impact.py +0 -0
  51. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_get_trade_funding_fee.py +0 -0
  52. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_get_trade_rollover_fee.py +0 -0
  53. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_get_trade_value.py +0 -0
  54. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_max_leverage.py +0 -0
  55. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_overnight_max_leverage.py +0 -0
  56. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_remove_collateral_from_leverage.py +0 -0
  57. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_remove_collateral_with_collateral.py +0 -0
  58. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_target_funding_rate.py +0 -0
  59. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_top_up_with_collateral.py +0 -0
  60. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_top_up_with_leverage.py +0 -0
  61. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_trade_get_sl_price.py +0 -0
  62. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_trade_get_tp_price.py +0 -0
  63. {ostium_python_sdk-2.0.21 → ostium_python_sdk-3.0.0}/tests/test_trade_liquidation_price.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ostium-python-sdk
3
- Version: 2.0.21
3
+ Version: 3.0.0
4
4
  Summary: A python based SDK developed for interacting with Ostium, a leveraged trading application for trading currencies, commodities, indices, crypto and more.
5
5
  Home-page: https://github.com/0xOstium/ostium-python-sdk
6
6
  Author: ami@ostium.io
@@ -540,6 +540,43 @@ All notable changes to the Ostium Python SDK will be documented in this file.
540
540
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
541
541
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
542
542
 
543
+ ## [3.0.0] - 2025-10-15
544
+
545
+ ### Breaking Changes
546
+ - **IMPORTANT**: Updated to support new Ostium Protocol contract upgrade
547
+ - `perform_trade()` now includes BuilderFee parameter in contract calls
548
+ - `close_trade()` now requires `market_price` parameter and includes slippage protection
549
+
550
+ ### Added
551
+ - Builder fee support in `perform_trade()` via optional `builder_address` and `builder_fee` parameters
552
+ - Market price parameter in `close_trade()` for accurate slippage calculation
553
+ - Automatic slippage protection when closing trades
554
+ - New `close_timeout()` method to handle timed out close market orders (retry or cancel)
555
+ - New `open_market_timeout()` method to execute timed out open market orders
556
+ - New test suite for builder fee functionality
557
+
558
+ ### Changed
559
+ - `close_trade()` signature now requires `market_price` as third parameter
560
+ - Contract calls now use updated ABI with BuilderFee struct for `openTrade`
561
+ - Contract calls now use updated ABI with market price and slippage for `closeTradeMarket`
562
+
563
+ ### Migration Guide
564
+ - For `perform_trade()`: No changes needed if not using builder fees (defaults to zero)
565
+ - For `close_trade()`: Must now provide current market price as third parameter
566
+ ```python
567
+ # Old: sdk.ostium.close_trade(pair_id, trade_index, close_percentage)
568
+ # New: sdk.ostium.close_trade(pair_id, trade_index, market_price, close_percentage)
569
+ ```
570
+ - New timeout handling methods for managing timed out orders:
571
+ ```python
572
+ # Handle a timed out close order
573
+ sdk.ostium.close_timeout(order_id, retry=True) # Retry the close
574
+ sdk.ostium.close_timeout(order_id, retry=False) # Cancel the close
575
+
576
+ # Execute a timed out open order
577
+ sdk.ostium.open_market_timeout(order_id) # Execute the open trade
578
+ ```
579
+
543
580
  ## [2.0.18] - 2025-06-23
544
581
 
545
582
  - Add delegate support for cancel_limit_order
@@ -30,6 +30,11 @@ trading_abi = [
30
30
  "name": "AlreadyMarketClosed",
31
31
  "type": "error"
32
32
  },
33
+ {
34
+ "inputs": [],
35
+ "name": "BelowFees",
36
+ "type": "error"
37
+ },
33
38
  {
34
39
  "inputs": [],
35
40
  "name": "BelowMinLevPos",
@@ -1429,11 +1434,6 @@ trading_abi = [
1429
1434
  },
1430
1435
  {
1431
1436
  "inputs": [
1432
- {
1433
- "internalType": "address",
1434
- "name": "trader",
1435
- "type": "address"
1436
- },
1437
1437
  {
1438
1438
  "internalType": "uint16",
1439
1439
  "name": "pairIndex",
@@ -1444,68 +1444,20 @@ trading_abi = [
1444
1444
  "name": "index",
1445
1445
  "type": "uint8"
1446
1446
  },
1447
- {
1448
- "internalType": "enum IOstiumTradingStorage.LimitOrder",
1449
- "name": "orderType",
1450
- "type": "uint8"
1451
- }
1452
- ],
1453
- "name": "checkNoPendingTrigger",
1454
- "outputs": [
1455
- {
1456
- "internalType": "bool",
1457
- "name": "",
1458
- "type": "bool"
1459
- }
1460
- ],
1461
- "stateMutability": "view",
1462
- "type": "function"
1463
- },
1464
- {
1465
- "inputs": [
1466
- {
1467
- "internalType": "address",
1468
- "name": "trader",
1469
- "type": "address"
1470
- },
1471
1447
  {
1472
1448
  "internalType": "uint16",
1473
- "name": "pairIndex",
1474
- "type": "uint16"
1475
- },
1476
- {
1477
- "internalType": "uint8",
1478
- "name": "index",
1479
- "type": "uint8"
1480
- }
1481
- ],
1482
- "name": "checkNoPendingTriggers",
1483
- "outputs": [
1484
- {
1485
- "internalType": "bool",
1486
- "name": "",
1487
- "type": "bool"
1488
- }
1489
- ],
1490
- "stateMutability": "view",
1491
- "type": "function"
1492
- },
1493
- {
1494
- "inputs": [
1495
- {
1496
- "internalType": "uint16",
1497
- "name": "pairIndex",
1449
+ "name": "closePercentage",
1498
1450
  "type": "uint16"
1499
1451
  },
1500
1452
  {
1501
- "internalType": "uint8",
1502
- "name": "index",
1503
- "type": "uint8"
1453
+ "internalType": "uint192",
1454
+ "name": "marketPrice",
1455
+ "type": "uint192"
1504
1456
  },
1505
1457
  {
1506
- "internalType": "uint16",
1507
- "name": "closePercentage",
1508
- "type": "uint16"
1458
+ "internalType": "uint32",
1459
+ "name": "slippageP",
1460
+ "type": "uint32"
1509
1461
  }
1510
1462
  ],
1511
1463
  "name": "closeTradeMarket",
@@ -1754,6 +1706,23 @@ trading_abi = [
1754
1706
  "name": "t",
1755
1707
  "type": "tuple"
1756
1708
  },
1709
+ {
1710
+ "components": [
1711
+ {
1712
+ "internalType": "address",
1713
+ "name": "builder",
1714
+ "type": "address"
1715
+ },
1716
+ {
1717
+ "internalType": "uint32",
1718
+ "name": "builderFee",
1719
+ "type": "uint32"
1720
+ }
1721
+ ],
1722
+ "internalType": "struct IOstiumTradingStorage.BuilderFee",
1723
+ "name": "bf",
1724
+ "type": "tuple"
1725
+ },
1757
1726
  {
1758
1727
  "internalType": "enum IOstiumTradingStorage.OpenOrderType",
1759
1728
  "name": "orderType",
@@ -1,3 +1,4 @@
1
+ import decimal
1
2
  import traceback
2
3
  import asyncio
3
4
  from decimal import Decimal
@@ -130,6 +131,27 @@ class Ostium:
130
131
  raise Exception('Invalid order type')
131
132
 
132
133
  slippage = int(self.slippage_percentage * PRECISION_2)
134
+
135
+ # Create BuilderFee struct with default values (zero address and zero fee)
136
+ # Can be customized if builder fees are needed in the future
137
+ builder_fee = {
138
+ 'builder': '0x0000000000000000000000000000000000000000', # Zero address
139
+ 'builderFee': 0 # Zero fee
140
+ }
141
+
142
+ # Check if custom builder fee is provided in trade_params
143
+ if 'builder_address' in trade_params and 'builder_fee' in trade_params:
144
+
145
+ if not self.web3.is_address(trade_params['builder_address']):
146
+ raise Exception('Invalid builder address format')
147
+
148
+ if trade_params['builder_fee'] > 0.5:
149
+ raise Exception('Builder fee too high: Max 0.5 (0.5%)')
150
+
151
+ builder_fee = {
152
+ 'builder': trade_params['builder_address'],
153
+ 'builderFee': convert_to_scaled_integer(trade_params['builder_fee'], precision=4, scale=6)
154
+ }
133
155
 
134
156
  if self.use_delegation and 'trader_address' in trade_params:
135
157
  # Use delegatedAction when delegation is enabled
@@ -138,9 +160,9 @@ class Ostium:
138
160
  f"Using delegatedAction to trade on behalf of {trader_address}")
139
161
 
140
162
  # The correct way to encode the function call in Web3.py
141
- # Create the function object for openTrade
163
+ # Create the function object for openTrade with BuilderFee parameter
142
164
  open_trade_func = self.ostium_trading_contract.functions.openTrade(
143
- trade, order_type, slippage
165
+ trade, builder_fee, order_type, slippage
144
166
  )
145
167
 
146
168
  # Get the encoded data for the openTrade function call
@@ -152,9 +174,9 @@ class Ostium:
152
174
  trader_address, inner_encoded_data
153
175
  ).build_transaction({'from': account.address})
154
176
  else:
155
- # Standard direct function call (no delegation)
177
+ # Standard direct function call (no delegation) with BuilderFee parameter
156
178
  trade_tx = self.ostium_trading_contract.functions.openTrade(
157
- trade, order_type, slippage
179
+ trade, builder_fee, order_type, slippage
158
180
  ).build_transaction({'from': account.address})
159
181
 
160
182
  trade_tx['nonce'] = self.get_nonce(account.address)
@@ -241,13 +263,14 @@ class Ostium:
241
263
  raise Exception(
242
264
  f'{reason_string}\n\n{suggestion}' if suggestion != None else reason_string)
243
265
 
244
- def close_trade(self, pair_id, trade_index, close_percentage=100, trader_address=None):
266
+ def close_trade(self, pair_id, trade_index, market_price, close_percentage=100, trader_address=None):
245
267
  """
246
268
  Close a trade partially or completely
247
269
 
248
270
  Args:
249
271
  pair_id: The ID of the trading pair
250
272
  trade_index: The index of the trade
273
+ market_price: The current market price for the trade
251
274
  close_percentage: The percentage of the position to close (1-100, default: 100)
252
275
  trader_address: Optional address of the trader if different from the account (for delegation)
253
276
 
@@ -258,15 +281,22 @@ class Ostium:
258
281
  account = self._get_account()
259
282
 
260
283
  close_percentage = to_base_units(close_percentage, decimals=2)
284
+
285
+ # Convert market price to the correct format (uint192)
286
+ market_price_scaled = convert_to_scaled_integer(market_price)
287
+
288
+ # Calculate slippage using the same percentage as for opening trades
289
+ slippage = int(self.slippage_percentage * PRECISION_2)
261
290
 
262
291
  if self.use_delegation and trader_address:
263
292
  self.log(
264
293
  f"Using delegatedAction to close trade on behalf of {trader_address}")
265
294
 
266
295
  # The correct way to encode the function call in Web3.py
267
- # Create the function object for closeTradeMarket
296
+ # Create the function object for closeTradeMarket with new parameters
268
297
  close_trade_func = self.ostium_trading_contract.functions.closeTradeMarket(
269
- int(pair_id), int(trade_index), int(close_percentage)
298
+ int(pair_id), int(trade_index), int(close_percentage),
299
+ market_price_scaled, slippage
270
300
  )
271
301
 
272
302
  # Get the encoded data for the closeTradeMarket function call
@@ -278,9 +308,10 @@ class Ostium:
278
308
  trader_address, inner_encoded_data
279
309
  ).build_transaction({'from': account.address})
280
310
  else:
281
- # Standard direct function call (no delegation)
311
+ # Standard direct function call (no delegation) with new parameters
282
312
  trade_tx = self.ostium_trading_contract.functions.closeTradeMarket(
283
- int(pair_id), int(trade_index), int(close_percentage)
313
+ int(pair_id), int(trade_index), int(close_percentage),
314
+ market_price_scaled, slippage
284
315
  ).build_transaction({'from': account.address})
285
316
 
286
317
  trade_tx['nonce'] = self.get_nonce(account.address)
@@ -314,6 +345,122 @@ class Ostium:
314
345
  'order_id': order_id
315
346
  }
316
347
 
348
+ def close_market_timeout(self, order_id, retry=False, trader_address=None):
349
+ """
350
+ Close a trade that has timed out in the market
351
+
352
+ Args:
353
+ order_id: The ID of the order that has timed out
354
+ retry: Whether to retry the close operation (True) or cancel it (False)
355
+ trader_address: Optional address of the trader if different from the account (for delegation)
356
+
357
+ Returns:
358
+ A dictionary containing the transaction receipt
359
+ """
360
+ self.log(f"Closing market timeout for order {order_id}, retry={retry}")
361
+ account = self._get_account()
362
+
363
+ try:
364
+ if self.use_delegation and trader_address:
365
+ self.log(
366
+ f"Using delegatedAction to close market timeout on behalf of {trader_address}")
367
+
368
+ close_market_timeout_func = self.ostium_trading_contract.functions.closeTradeMarketTimeout(
369
+ int(order_id), bool(retry)
370
+ )
371
+
372
+ inner_encoded_data = close_market_timeout_func.build_transaction({'gas': 0})['data']
373
+
374
+ tx = self.ostium_trading_contract.functions.delegatedAction(
375
+ trader_address, inner_encoded_data
376
+ ).build_transaction({'from': account.address})
377
+ else:
378
+ tx = self.ostium_trading_contract.functions.closeTradeMarketTimeout(
379
+ int(order_id), bool(retry)
380
+ ).build_transaction({'from': account.address})
381
+
382
+ tx['nonce'] = self.get_nonce(account.address)
383
+
384
+ signed_tx = self.web3.eth.account.sign_transaction(
385
+ tx, private_key=self.private_key)
386
+ tx_hash = self.web3.eth.send_raw_transaction(
387
+ signed_tx.raw_transaction)
388
+ self.log(f"Close Market Timeout TX Hash: {tx_hash.hex()}")
389
+
390
+ receipt = self.web3.eth.wait_for_transaction_receipt(tx_hash)
391
+ self.log(f"Close Market Timeout successful for order {order_id}")
392
+
393
+ return {
394
+ 'receipt': receipt,
395
+ 'order_id': order_id,
396
+ 'retry': retry
397
+ }
398
+
399
+ except Exception as e:
400
+ reason_string, suggestion = fromErrorCodeToMessage(
401
+ e, verbose=self.verbose)
402
+ print(
403
+ f"An error ({str(e)}) occurred during close market timeout - parsed as {reason_string}")
404
+ raise Exception(
405
+ f'{reason_string}\n\n{suggestion}' if suggestion != None else reason_string)
406
+
407
+ def open_market_timeout(self, order_id, trader_address=None):
408
+ """
409
+ Open/execute a trade that has timed out in the market
410
+
411
+ Args:
412
+ order_id: The ID of the order that has timed out
413
+ trader_address: Optional address of the trader if different from the account (for delegation)
414
+
415
+ Returns:
416
+ A dictionary containing the transaction receipt
417
+ """
418
+ self.log(f"Opening market timeout for order {order_id}")
419
+ account = self._get_account()
420
+
421
+ try:
422
+ if self.use_delegation and trader_address:
423
+ self.log(
424
+ f"Using delegatedAction to open market timeout on behalf of {trader_address}")
425
+
426
+ open_timeout_func = self.ostium_trading_contract.functions.openTradeMarketTimeout(
427
+ int(order_id)
428
+ )
429
+
430
+ inner_encoded_data = open_timeout_func.build_transaction({'gas': 0})['data']
431
+
432
+ tx = self.ostium_trading_contract.functions.delegatedAction(
433
+ trader_address, inner_encoded_data
434
+ ).build_transaction({'from': account.address})
435
+ else:
436
+ tx = self.ostium_trading_contract.functions.openTradeMarketTimeout(
437
+ int(order_id)
438
+ ).build_transaction({'from': account.address})
439
+
440
+ tx['nonce'] = self.get_nonce(account.address)
441
+
442
+ signed_tx = self.web3.eth.account.sign_transaction(
443
+ tx, private_key=self.private_key)
444
+ tx_hash = self.web3.eth.send_raw_transaction(
445
+ signed_tx.raw_transaction)
446
+ self.log(f"Open Market Timeout TX Hash: {tx_hash.hex()}")
447
+
448
+ receipt = self.web3.eth.wait_for_transaction_receipt(tx_hash)
449
+ self.log(f"Open Market Timeout successful for order {order_id}")
450
+
451
+ return {
452
+ 'receipt': receipt,
453
+ 'order_id': order_id
454
+ }
455
+
456
+ except Exception as e:
457
+ reason_string, suggestion = fromErrorCodeToMessage(
458
+ e, verbose=self.verbose)
459
+ print(
460
+ f"An error ({str(e)}) occurred during open market timeout - parsed as {reason_string}")
461
+ raise Exception(
462
+ f'{reason_string}\n\n{suggestion}' if suggestion != None else reason_string)
463
+
317
464
  def remove_collateral(self, pair_id, trade_index, remove_amount):
318
465
  self.log(
319
466
  f"Remove collateral for trade for pair {pair_id}, index {trade_index}: {remove_amount} USDC")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ostium-python-sdk
3
- Version: 2.0.21
3
+ Version: 3.0.0
4
4
  Summary: A python based SDK developed for interacting with Ostium, a leveraged trading application for trading currencies, commodities, indices, crypto and more.
5
5
  Home-page: https://github.com/0xOstium/ostium-python-sdk
6
6
  Author: ami@ostium.io
@@ -540,6 +540,43 @@ All notable changes to the Ostium Python SDK will be documented in this file.
540
540
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
541
541
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
542
542
 
543
+ ## [3.0.0] - 2025-10-15
544
+
545
+ ### Breaking Changes
546
+ - **IMPORTANT**: Updated to support new Ostium Protocol contract upgrade
547
+ - `perform_trade()` now includes BuilderFee parameter in contract calls
548
+ - `close_trade()` now requires `market_price` parameter and includes slippage protection
549
+
550
+ ### Added
551
+ - Builder fee support in `perform_trade()` via optional `builder_address` and `builder_fee` parameters
552
+ - Market price parameter in `close_trade()` for accurate slippage calculation
553
+ - Automatic slippage protection when closing trades
554
+ - New `close_timeout()` method to handle timed out close market orders (retry or cancel)
555
+ - New `open_market_timeout()` method to execute timed out open market orders
556
+ - New test suite for builder fee functionality
557
+
558
+ ### Changed
559
+ - `close_trade()` signature now requires `market_price` as third parameter
560
+ - Contract calls now use updated ABI with BuilderFee struct for `openTrade`
561
+ - Contract calls now use updated ABI with market price and slippage for `closeTradeMarket`
562
+
563
+ ### Migration Guide
564
+ - For `perform_trade()`: No changes needed if not using builder fees (defaults to zero)
565
+ - For `close_trade()`: Must now provide current market price as third parameter
566
+ ```python
567
+ # Old: sdk.ostium.close_trade(pair_id, trade_index, close_percentage)
568
+ # New: sdk.ostium.close_trade(pair_id, trade_index, market_price, close_percentage)
569
+ ```
570
+ - New timeout handling methods for managing timed out orders:
571
+ ```python
572
+ # Handle a timed out close order
573
+ sdk.ostium.close_timeout(order_id, retry=True) # Retry the close
574
+ sdk.ostium.close_timeout(order_id, retry=False) # Cancel the close
575
+
576
+ # Execute a timed out open order
577
+ sdk.ostium.open_market_timeout(order_id) # Execute the open trade
578
+ ```
579
+
543
580
  ## [2.0.18] - 2025-06-23
544
581
 
545
582
  - Add delegate support for cancel_limit_order
@@ -35,6 +35,8 @@ ostium_python_sdk/scscript/funding.py
35
35
  ostium_python_sdk/scscript/pairinfos.py
36
36
  tests/__init__.py
37
37
  tests/conftest.py
38
+ tests/disabled_test_builder_fee.py
39
+ tests/disabled_test_close_trade.py
38
40
  tests/disabled_test_funding.py
39
41
  tests/disabled_test_slippage.py
40
42
  tests/test_current_total_profit_p.py
@@ -22,7 +22,7 @@ if changelog_path.exists():
22
22
 
23
23
  setup(
24
24
  name="ostium-python-sdk",
25
- version="2.0.21",
25
+ version="3.0.0",
26
26
  packages=find_packages(),
27
27
  install_requires=read_requirements('requirements.txt'),
28
28
  extras_require={