talis-cli 0.3.0__tar.gz → 0.3.1__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 (74) hide show
  1. {talis_cli-0.3.0 → talis_cli-0.3.1}/PKG-INFO +1 -1
  2. {talis_cli-0.3.0 → talis_cli-0.3.1}/pyproject.toml +1 -1
  3. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/api.py +12 -6
  4. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/fund.py +6 -1
  5. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis_cli.egg-info/PKG-INFO +1 -1
  6. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis_cli.egg-info/SOURCES.txt +1 -0
  7. talis_cli-0.3.1/tests/test_fund_deposit.py +46 -0
  8. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_mcp_backtest.py +13 -1
  9. {talis_cli-0.3.0 → talis_cli-0.3.1}/README.md +0 -0
  10. {talis_cli-0.3.0 → talis_cli-0.3.1}/setup.cfg +0 -0
  11. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/__init__.py +0 -0
  12. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/_eip55.py +0 -0
  13. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/cli.py +0 -0
  14. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/__init__.py +0 -0
  15. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/_shared.py +0 -0
  16. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/auth.py +0 -0
  17. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/brief.py +0 -0
  18. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/chat.py +0 -0
  19. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/guide.py +0 -0
  20. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/history.py +0 -0
  21. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/mcp_server.py +0 -0
  22. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/notifications.py +0 -0
  23. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/outcome.py +0 -0
  24. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/portfolio.py +0 -0
  25. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/research.py +0 -0
  26. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/snapshot.py +0 -0
  27. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/strategies.py +0 -0
  28. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/test_tenant.py +0 -0
  29. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/trade.py +0 -0
  30. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/wait.py +0 -0
  31. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/commands/withdraw.py +0 -0
  32. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/config.py +0 -0
  33. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/output.py +0 -0
  34. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/paper.py +0 -0
  35. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/spot.py +0 -0
  36. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis/symbols.py +0 -0
  37. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis_cli.egg-info/dependency_links.txt +0 -0
  38. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis_cli.egg-info/entry_points.txt +0 -0
  39. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis_cli.egg-info/requires.txt +0 -0
  40. {talis_cli-0.3.0 → talis_cli-0.3.1}/talis_cli.egg-info/top_level.txt +0 -0
  41. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_api.py +0 -0
  42. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_api_key_auth.py +0 -0
  43. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_brief.py +0 -0
  44. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_chat.py +0 -0
  45. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_commands.py +0 -0
  46. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_config.py +0 -0
  47. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_confirm_prompt.py +0 -0
  48. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_eip55.py +0 -0
  49. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_guide.py +0 -0
  50. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_history.py +0 -0
  51. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_login_flow.py +0 -0
  52. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_loopback_login.py +0 -0
  53. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_mcp.py +0 -0
  54. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_mcp_balance_contract.py +0 -0
  55. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_mcp_docstring_contract.py +0 -0
  56. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_mcp_mode_contract.py +0 -0
  57. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_mcp_sdk_compat.py +0 -0
  58. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_mcp_session_expiry.py +0 -0
  59. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_mcp_strategy_tools.py +0 -0
  60. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_non_interactive_auth.py +0 -0
  61. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_notifications.py +0 -0
  62. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_outcome.py +0 -0
  63. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_paper_mode.py +0 -0
  64. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_research.py +0 -0
  65. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_session_autorenew.py +0 -0
  66. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_signup.py +0 -0
  67. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_snapshot_diff.py +0 -0
  68. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_spot.py +0 -0
  69. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_spot_gateway_first.py +0 -0
  70. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_strategies_create.py +0 -0
  71. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_test_tenant.py +0 -0
  72. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_version_sync.py +0 -0
  73. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_wait.py +0 -0
  74. {talis_cli-0.3.0 → talis_cli-0.3.1}/tests/test_withdraw.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: talis-cli
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: Command-line client for the Talis trading platform. Sign in via device flow, manage sessions, view portfolio, place orders.
5
5
  Author: Talis
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "talis-cli"
3
- version = "0.3.0"
3
+ version = "0.3.1"
4
4
  description = "Command-line client for the Talis trading platform. Sign in via device flow, manage sessions, view portfolio, place orders."
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -27,6 +27,9 @@ import httpx
27
27
 
28
28
  from . import config
29
29
 
30
+ #: Full path of the control plane's candle route (router prefix included).
31
+ CANDLES_PATH = "/market/candles"
32
+
30
33
  DEFAULT_TIMEOUT = httpx.Timeout(connect=10.0, read=30.0, write=30.0, pool=10.0)
31
34
 
32
35
  REQUEST_ID_HEADER = "X-Request-Id"
@@ -493,16 +496,19 @@ class Client:
493
496
 
494
497
  def get_candles(self, *, symbol: str, interval: str = "1h", limit: int = 500,
495
498
  exchange: str | None = None) -> dict:
496
- """Historical candles from the control plane (``GET /candles``).
497
-
498
- Returns ``{"candles": [{t,o,h,l,c,v}, ...], "symbol", "interval"}`` —
499
- abbreviated OHLCV keys, newest last. The backtester wants the full
500
- names; ``backtest_candles`` in the MCP layer does that mapping.
499
+ """Historical candles from the control plane (``GET /market/candles``).
500
+
501
+ The market router is mounted under ``/market`` (engine/api/routes/
502
+ market.py ``APIRouter(prefix="/market")``); 0.3.0 called ``/candles``
503
+ and 404'd on production — pinned by ``test_candles_path_matches_the_
504
+ engine_router``. Returns ``{"candles": [{t,o,h,l,c,v}, ...], "symbol",
505
+ "interval"}`` — abbreviated OHLCV keys, newest last. The backtester
506
+ wants the full names; ``backtest_candles`` in the MCP layer maps them.
501
507
  """
502
508
  params: dict[str, Any] = {"symbol": symbol, "interval": interval, "limit": limit}
503
509
  if exchange:
504
510
  params["exchange"] = exchange
505
- return self._request("GET", "/candles", params=params)
511
+ return self._request("GET", CANDLES_PATH, params=params)
506
512
 
507
513
  def create_backtest(self, *, body: dict) -> dict:
508
514
  """Submit a backtest (``POST /backtests``). Returns ``{backtest_id, status}``."""
@@ -46,7 +46,12 @@ def deposit(
46
46
  output.error(f"could not get deposit addresses: {exc.detail}")
47
47
  raise typer.Exit(code=1)
48
48
 
49
- evm = uda.get("evm_addr") or uda.get("evm_address") or ""
49
+ # The control plane names the EVM Unified Deposit Address `deposit_addr`
50
+ # (verified live 2026-09-06: {"deposit_addr", "solana_addr",
51
+ # "btc_addr_segwit", ...}); the older keys stay as fallbacks. Without
52
+ # `deposit_addr` the EVM row — the rail most users fund from — was blank.
53
+ evm = (uda.get("deposit_addr") or uda.get("evm_addr")
54
+ or uda.get("evm_address") or "")
50
55
  sol = uda.get("solana_addr") or ""
51
56
  btc = uda.get("btc_addr_segwit") or uda.get("btc_addr") or ""
52
57
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: talis-cli
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: Command-line client for the Talis trading platform. Sign in via device flow, manage sessions, view portfolio, place orders.
5
5
  Author: Talis
6
6
  License-Expression: Apache-2.0
@@ -42,6 +42,7 @@ tests/test_commands.py
42
42
  tests/test_config.py
43
43
  tests/test_confirm_prompt.py
44
44
  tests/test_eip55.py
45
+ tests/test_fund_deposit.py
45
46
  tests/test_guide.py
46
47
  tests/test_history.py
47
48
  tests/test_login_flow.py
@@ -0,0 +1,46 @@
1
+ """`talis deposit` must show the EVM address the control plane actually returns.
2
+
3
+ Live shape of ``POST /deposits/uda`` (2026-09-06): ``deposit_addr`` (EVM),
4
+ ``solana_addr``, ``btc_addr_segwit``, ``recipient_addr``, ``to_chain_id``,
5
+ ``to_token_address``. 0.3.0 looked for ``evm_addr``/``evm_address`` only and
6
+ printed an empty EVM row — on the rail most users fund from.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import json
11
+
12
+ import httpx
13
+ import respx
14
+ from typer.testing import CliRunner
15
+
16
+ from talis.cli import app
17
+
18
+ BASE = "http://api.test"
19
+ LIVE_SHAPE = {
20
+ "deposit_addr": "0xaFCD8Ebc0000000000000000000000000000dEaD",
21
+ "solana_addr": "2LNv8tS1c7000000000000000000000000000000000",
22
+ "btc_addr_segwit": "bc1q0ma0xp000000000000000000000000000000",
23
+ "recipient_addr": "0x62ec8F9100000000000000000000000000000000",
24
+ "to_chain_id": "1337",
25
+ "to_token_address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
26
+ }
27
+
28
+
29
+ @respx.mock
30
+ def test_deposit_json_includes_the_evm_address_from_deposit_addr(stored_creds):
31
+ respx.post(f"{BASE}/deposits/uda").mock(return_value=httpx.Response(200, json=LIVE_SHAPE))
32
+ result = CliRunner().invoke(app, ["deposit", "--json"])
33
+ assert result.exit_code == 0, result.output
34
+ out = json.loads(result.stdout)
35
+ assert out["evm"] == LIVE_SHAPE["deposit_addr"]
36
+ assert out["solana"] == LIVE_SHAPE["solana_addr"]
37
+ assert out["bitcoin"] == LIVE_SHAPE["btc_addr_segwit"]
38
+
39
+
40
+ @respx.mock
41
+ def test_deposit_still_accepts_the_older_evm_key(stored_creds):
42
+ respx.post(f"{BASE}/deposits/uda").mock(
43
+ return_value=httpx.Response(200, json={"evm_addr": "0x1111111111111111111111111111111111111111"}))
44
+ result = CliRunner().invoke(app, ["deposit", "--json"])
45
+ assert result.exit_code == 0, result.output
46
+ assert json.loads(result.stdout)["evm"] == "0x1111111111111111111111111111111111111111"
@@ -40,7 +40,7 @@ def _routes(valid=True, statuses=("RUNNING", "COMPLETED")):
40
40
  respx.post(f"{BASE}/strategies/validate").mock(
41
41
  return_value=httpx.Response(200, json={"valid": valid, "errors": [] if valid else ["bad trigger"],
42
42
  "human_readable_summary": "x"}))
43
- respx.get(f"{BASE}/candles").mock(
43
+ respx.get(f"{BASE}/market/candles").mock(
44
44
  return_value=httpx.Response(200, json={"candles": CANDLES, "symbol": "X", "interval": "1h"}))
45
45
  submit = respx.post(f"{BASE}/backtests").mock(
46
46
  return_value=httpx.Response(200, json={"backtest_id": "bt_1", "status": "RUNNING"}))
@@ -107,3 +107,15 @@ def test_backtest_is_registered_and_read_only():
107
107
  import inspect
108
108
  assert "paper" not in inspect.signature(mcp_server.backtest).parameters
109
109
  assert "confirm_real_money" not in inspect.signature(mcp_server.backtest).parameters
110
+
111
+
112
+ def test_candles_path_matches_the_engine_router():
113
+ """Non-tautological pin: the CLI's candle path must equal the ENGINE's real
114
+ mounted path (router prefix + route path). 0.3.0 shipped "/candles" and
115
+ 404'd on production because the respx tests only mirrored the CLI's own
116
+ assumption. Skips where the engine package is not importable (CLI-only CI)."""
117
+ market = pytest.importorskip("engine.api.routes.market")
118
+ from talis import api as talis_api
119
+ # APIRoute.path already carries the router prefix ("/market/candles").
120
+ real = {r.path for r in market.router.routes if getattr(r, "path", None)}
121
+ assert talis_api.CANDLES_PATH in real, (talis_api.CANDLES_PATH, sorted(real))
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes