Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
`x10.clients.stream.StreamClient` (same interface, renamed to match the `RestApiClient` naming convention).
- `UserClient` replaced by `OnboardingClient`, which accepts an account address and a sign-message callback instead of a raw L1 private key.
- `onboard_subaccount` error handling has changed. Previously, it silently recovered an existing sub-account (HTTP 409) by fetching it from `get_accounts()`. Now it raises `ValidationError` on conflict. Handle duplicates explicitly if you relied on the automatic recovery.
- Signing-related modules have been extracted from `x10.perpetual` into a dedicated `x10.signing` package. The old paths no longer exist — there are no backwards-compatible re-exports.
- Fixes https://github.com/x10xchange/python_sdk/issues/99.

---
Expand Down
2 changes: 1 addition & 1 deletion examples/cases/advanced/load_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from x10.clients.stream import StreamClient
from x10.models.market import MarketModel
from x10.models.order import OrderSide
from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object

LOGGER = logging.getLogger()
MARKET_NAME = BTC_USD_MARKET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
init_env,
)
from x10.models.order import OrderSide, TimeInForce
from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object

LOGGER = logging.getLogger()
MARKET_NAME = BTC_USD_MARKET
Expand Down
2 changes: 1 addition & 1 deletion examples/cases/createorder/create_conditional_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
OrderType,
TimeInForce,
)
from x10.perpetual.order_object import OrderConditionalTriggerParam, create_order_object
from x10.signing.order_object import OrderConditionalTriggerParam, create_order_object

LOGGER = logging.getLogger()
MARKET_NAME = BTC_USD_MARKET
Expand Down
2 changes: 1 addition & 1 deletion examples/cases/createorder/create_limit_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
get_adjust_price_by_pct,
)
from x10.models.order import OrderSide, TimeInForce
from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object

LOGGER = logging.getLogger()
MARKET_NAME = BTC_USD_MARKET
Expand Down
2 changes: 1 addition & 1 deletion examples/cases/createorder/create_market_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from examples.utils import BTC_USD_MARKET, create_rest_client
from x10.models.order import OrderSide, OrderType, TimeInForce
from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object
from x10.utils.order import get_price_with_slippage

LOGGER = logging.getLogger()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
OrderTriggerPriceType,
TimeInForce,
)
from x10.perpetual.order_object import OrderTpslTriggerParam, create_order_object
from x10.signing.order_object import OrderTpslTriggerParam, create_order_object

LOGGER = logging.getLogger()
MARKET_NAME = BTC_USD_MARKET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
OrderTriggerPriceType,
TimeInForce,
)
from x10.perpetual.order_object import OrderTpslTriggerParam, create_order_object
from x10.signing.order_object import OrderTpslTriggerParam, create_order_object

LOGGER = logging.getLogger()
MARKET_NAME = BTC_USD_MARKET
Expand Down
2 changes: 1 addition & 1 deletion examples/cases/tpsl/create_partial_tpsl_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
OrderType,
TimeInForce,
)
from x10.perpetual.order_object import OrderTpslTriggerParam, create_order_object
from x10.signing.order_object import OrderTpslTriggerParam, create_order_object

LOGGER = logging.getLogger()
MARKET_NAME = BTC_USD_MARKET
Expand Down
2 changes: 1 addition & 1 deletion examples/cases/tpsl/create_position_tpsl_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
OrderType,
TimeInForce,
)
from x10.perpetual.order_object import OrderTpslTriggerParam, create_order_object
from x10.signing.order_object import OrderTpslTriggerParam, create_order_object

LOGGER = logging.getLogger()
MARKET_NAME = BTC_USD_MARKET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ async def test_create_buy_limit_order_settlement_data(
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.config import MAINNET_CONFIG
from x10.perpetual.limit_order_object_settlement import create_order_settlement_data
from x10.signing.limit_order_object_settlement import (
create_limit_order_settlement_data,
)

trading_account = create_trading_account()
collateral_asset = get_asset_usd()
vault_asset = get_asset_xvs()

settlement, quote_amount_human, base_amount_human = create_order_settlement_data(
settlement, quote_amount_human, base_amount_human = create_limit_order_settlement_data(
quote_amount=Decimal("10"),
base_amount=Decimal("7"),
position_id=trading_account.vault,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
async def test_create_buy_order(mocker: MockerFixture, create_trading_account, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import (
from x10.signing.order_object import (
OrderConditionalTriggerParam,
create_order_object,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ async def test_create_sell_order_with_default_expiration(
freezer = freeze_time("2024-01-05 01:08:56.860694")
frozen_time = freezer.start()

from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object

frozen_time.move_to("2024-01-05 01:08:57")
trading_account = create_trading_account()
Expand Down Expand Up @@ -84,7 +84,7 @@ async def test_create_sell_order_with_default_expiration(
async def test_create_sell_order(mocker: MockerFixture, create_trading_account, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object

trading_account = create_trading_account()
btc_usd_market = create_btc_usd_market()
Expand Down Expand Up @@ -142,7 +142,7 @@ async def test_create_sell_order(mocker: MockerFixture, create_trading_account,
async def test_create_buy_order(mocker: MockerFixture, create_trading_account, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object

trading_account = create_trading_account()
btc_usd_market = create_btc_usd_market()
Expand Down Expand Up @@ -200,7 +200,7 @@ async def test_create_buy_order(mocker: MockerFixture, create_trading_account, c
async def test_create_buy_order_with_order_tpsl(mocker: MockerFixture, create_trading_account, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import OrderTpslTriggerParam, create_order_object
from x10.signing.order_object import OrderTpslTriggerParam, create_order_object

trading_account = create_trading_account()
btc_usd_market = create_btc_usd_market()
Expand Down Expand Up @@ -309,7 +309,7 @@ async def test_create_buy_order_with_position_tpsl(
):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import OrderTpslTriggerParam, create_order_object
from x10.signing.order_object import OrderTpslTriggerParam, create_order_object

trading_account = create_trading_account()
btc_usd_market = create_btc_usd_market()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
async def test_create_sell_order(mocker: MockerFixture, create_trading_account, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object

trading_account = create_trading_account()
btc_usd_market = create_btc_usd_market()
Expand Down Expand Up @@ -87,7 +87,7 @@ async def test_create_sell_order(mocker: MockerFixture, create_trading_account,
async def test_create_buy_order(mocker: MockerFixture, create_trading_account, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object

trading_account = create_trading_account()
btc_usd_market = create_btc_usd_market()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
async def test_cancel_previous_order(mocker: MockerFixture, create_trading_account, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object

trading_account = create_trading_account()
btc_usd_market = create_btc_usd_market()
Expand Down Expand Up @@ -48,7 +48,7 @@ async def test_cancel_previous_order(mocker: MockerFixture, create_trading_accou
async def test_external_order_id(mocker: MockerFixture, create_trading_account, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object

trading_account = create_trading_account()
btc_usd_market = create_btc_usd_market()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
async def test_create_buy_partial_tpsl_order(mocker: MockerFixture, create_trading_account, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import OrderTpslTriggerParam, create_order_object
from x10.signing.order_object import OrderTpslTriggerParam, create_order_object

trading_account = create_trading_account()
btc_usd_market = create_btc_usd_market()
Expand Down Expand Up @@ -119,7 +119,7 @@ async def test_create_buy_partial_tpsl_order(mocker: MockerFixture, create_tradi
async def test_create_buy_position_tpsl_order(mocker: MockerFixture, create_trading_account, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.order_object import OrderTpslTriggerParam, create_order_object
from x10.signing.order_object import OrderTpslTriggerParam, create_order_object

trading_account = create_trading_account()
btc_usd_market = create_btc_usd_market()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
async def test_create_transfer(mocker: MockerFixture, create_trading_account, create_accounts, create_btc_usd_market):
mocker.patch("x10.utils.nonce.generate_nonce", return_value=FROZEN_NONCE)

from x10.perpetual.transfer_object import create_transfer_object
from x10.signing.transfer_object import create_transfer_object

trading_account = create_trading_account()
accounts = create_accounts()
Expand Down
19 changes: 19 additions & 0 deletions tests/utils/test_date.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
from datetime import datetime

from freezegun import freeze_time
from hamcrest import assert_that, equal_to, raises

from x10.utils.date import to_epoch_millis


@freeze_time("2024-01-05 01:08:56.860694")
def test_utc_now():
from x10.utils.date import utc_now

expected_dt = datetime.fromisoformat("2024-01-05 01:08:56.860694+00:00")
assert_that(utc_now(), equal_to(expected_dt))


def test_convert_datetime_to_epoch_millis():
dt = datetime.fromisoformat("2024-01-08 11:35:20.447+00:00")

Expand All @@ -17,3 +26,13 @@ def test_throw_on_non_utc_timezone():

assert_that(lambda: to_epoch_millis(dt1), raises(AssertionError, "`value` must be in UTC")) # type: ignore[misc]
assert_that(lambda: to_epoch_millis(dt2), raises(AssertionError, "`value` must be in UTC")) # type: ignore[misc]


@freeze_time("2024-01-05 01:08:56.860694")
def test_calc_settlement_expiration():
from x10.utils.date import calc_settlement_expiration

custom_dt = datetime.fromisoformat("2024-01-08 11:35:20.447+00:00")

assert_that(calc_settlement_expiration(10), equal_to(1705280937))
assert_that(calc_settlement_expiration(10, custom_dt), equal_to(1705577721))
4 changes: 2 additions & 2 deletions x10/clients/rest/modules/account_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
from x10.models.position import PositionHistoryModel, PositionModel, PositionSide
from x10.models.trade import AccountTradeModel, TradeType
from x10.models.transfer import TransferResponseModel
from x10.perpetual.transfer_object import create_transfer_object
from x10.perpetual.withdrawal_object import create_withdrawal_object
from x10.signing.transfer_object import create_transfer_object
from x10.signing.withdrawal_object import create_withdrawal_object
from x10.utils.http import (
WrappedApiResponseModel,
send_get_request,
Expand Down
6 changes: 3 additions & 3 deletions x10/clients/rest/modules/vault_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from x10.core.stark_account import StarkPerpetualAccount
from x10.errors import ApiError, ValidationError
from x10.models.vault import DepositRequestModel, WithdrawRequestModel
from x10.perpetual.limit_order_object_settlement import create_order_settlement_data
from x10.signing.limit_order_object_settlement import create_limit_order_settlement_data
from x10.utils.http import send_post_request

# Protects from an error on shares pricing fluctuations.
Expand Down Expand Up @@ -64,7 +64,7 @@ async def deposit_to_vault(self, *, collateral_amount: Decimal) -> None:
vault_asset.precision,
)

settlement, collateral_amount_human, shares_amount_human = create_order_settlement_data(
settlement, collateral_amount_human, shares_amount_human = create_limit_order_settlement_data(
quote_amount=collateral_amount,
base_amount=vault_shares_expected,
position_id=position_id,
Expand Down Expand Up @@ -116,7 +116,7 @@ async def withdraw_from_vault(self, *, shares_amount: Decimal) -> None:
vault_asset.precision,
)

settlement, collateral_amount_human, shares_amount_human = create_order_settlement_data(
settlement, collateral_amount_human, shares_amount_human = create_limit_order_settlement_data(
quote_amount=collateral_amount_expected,
base_amount=shares_amount,
position_id=position_id,
Expand Down
2 changes: 1 addition & 1 deletion x10/clients/rest/rest_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
SelfTradeProtectionLevel,
TimeInForce,
)
from x10.perpetual.order_object import OrderTpslTriggerParam, create_order_object
from x10.signing.order_object import OrderTpslTriggerParam, create_order_object
from x10.utils.date import utc_now
from x10.utils.http import WrappedApiResponseModel
from x10.utils.log import get_logger
Expand Down
2 changes: 1 addition & 1 deletion x10/perpetual/simple_client/simple_trading_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
OrderType,
TimeInForce,
)
from x10.perpetual.order_object import create_order_object
from x10.signing.order_object import create_order_object


def condition_to_awaitable(condition: asyncio.Condition) -> Awaitable:
Expand Down
Empty file added x10/signing/__init__.py
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
from x10.models.asset import Asset, AssetModel
from x10.models.base import SettlementSignatureModel
from x10.models.order import LimitOrderSettlementModel
from x10.perpetual.order_object_settlement import (
calculate_order_settlement_expiration,
from x10.signing.order_object_settlement import (
SETTLEMENT_EXPIRATION_BUFFER_DAYS,
hash_limit_order,
)
from x10.utils.date import utc_now
from x10.utils.date import calc_settlement_expiration, utc_now
from x10.utils.nonce import generate_nonce


def create_order_settlement_data(
def create_limit_order_settlement_data(
*,
quote_amount,
base_amount,
Expand Down Expand Up @@ -62,7 +62,7 @@ def create_order_settlement_data(
base_asset_id=int(base_asset.settlement_external_id, 16),
quote_asset_id=int(quote_asset.settlement_external_id, 16),
fee_asset_id=int(quote_asset.settlement_external_id, 16),
expiration_timestamp=calculate_order_settlement_expiration(expire_time),
expiration_timestamp=calc_settlement_expiration(SETTLEMENT_EXPIRATION_BUFFER_DAYS, expire_time),
nonce=nonce,
receiver_position_id=position_id,
sender_position_id=position_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
SelfTradeProtectionLevel,
TimeInForce,
)
from x10.perpetual.order_object_settlement import (
from x10.signing.order_object_settlement import (
SettlementDataCtx,
create_order_settlement_data,
)
Expand Down
Loading
Loading