bridgenode-cli 0.1.1__tar.gz → 0.1.2__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.
@@ -0,0 +1,16 @@
1
+ MIT No Attribution
2
+
3
+ Copyright 2026 BridgeNode
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this
6
+ software and associated documentation files (the "Software"), to deal in the Software
7
+ without restriction, including without limitation the rights to use, copy, modify,
8
+ merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
12
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
13
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
14
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
15
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
16
+ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,30 +1,40 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bridgenode-cli
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: BridgeNode CLI — AI inference with x402 payment on Solana USDC. No API keys.
5
5
  Author-email: BridgeNode <eli.BNx@proton.me>
6
- License-Expression: MIT
6
+ License-Expression: MIT-0
7
7
  Project-URL: Homepage, https://bridgenode.cc
8
8
  Project-URL: Repository, https://github.com/applefanaimail-blip/bridgenode-llm
9
9
  Project-URL: Documentation, https://bridgenode.cc/llms.txt
10
- Keywords: x402,solana,usdc,ai,llm,cli,agents,payment,bridgenode
10
+ Keywords: x402,solana,usdc,ai,llm,cli,agents,payment,bridgenode,openai-compatible,chat,inference,micropayments
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
15
16
  Classifier: Programming Language :: Python :: 3.11
16
17
  Classifier: Programming Language :: Python :: 3.12
17
18
  Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
18
20
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Classifier: Typing :: Typed
19
22
  Requires-Python: >=3.11
20
23
  Description-Content-Type: text/markdown
24
+ License-File: LICENSE
21
25
  Requires-Dist: bridgenode-llm>=0.1.0
22
26
  Provides-Extra: dev
23
27
  Requires-Dist: pytest>=9.1.1; extra == "dev"
28
+ Dynamic: license-file
24
29
 
25
30
  # bridgenode-cli
26
31
 
27
- BridgeNode CLI — AI inference without API keys. Payment: **Solana USDC via x402** (automatic handshake, fee sponsorship — no SOL needed).
32
+ [![PyPI version](https://img.shields.io/pypi/v/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
33
+ [![Downloads](https://img.shields.io/pypi/dm/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
34
+ [![License: MIT-0](https://img.shields.io/badge/License-MIT--0-yellow.svg)](https://opensource.org/license/mit-0/)
35
+ [![Python versions](https://img.shields.io/pypi/pyversions/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
36
+
37
+ BridgeNode CLI — AI inference without API keys. Pay per request with **Solana USDC via x402**. The payment handshake is fully automatic, and fees are sponsored — no SOL needed.
28
38
 
29
39
  ## Installation
30
40
 
@@ -32,16 +42,22 @@ BridgeNode CLI — AI inference without API keys. Payment: **Solana USDC via x40
32
42
  pip install bridgenode-cli
33
43
  ```
34
44
 
45
+ Or install the full toolkit (SDK + CLI):
46
+
47
+ ```bash
48
+ pip install bridgenode
49
+ ```
50
+
35
51
  ## Usage
36
52
 
37
53
  ```bash
38
- # Single chat completion (x402 handshake hidden, §4.1)
54
+ # Single chat completion (payment handshake fully automatic)
39
55
  bridgenode chat "Hello!" --model deepseek-v4-flash
40
56
 
41
- # Smart routing (§5.1/§5.8): auto / eco / premium
57
+ # Smart routing: auto / eco / premium
42
58
  bridgenode chat "Analyze this code" --mode auto
43
59
 
44
- # Model list + prices (§5.2) — no payment
60
+ # Model list + prices (no payment)
45
61
  bridgenode models
46
62
  ```
47
63
 
@@ -51,11 +67,11 @@ bridgenode models
51
67
  |---|---|
52
68
  | `--model` | Explicit model id (see `bridgenode models`) |
53
69
  | `--mode` | `auto` / `eco` / `premium` (smart routing) |
54
- | `--max-tokens` | Max output tokens (billing upfront, §4.2) |
70
+ | `--max-tokens` | Max output tokens (billed upfront) |
55
71
  | `--base-url` | Base URL (default: `BRIDGENODE_BASE_URL` / https://bridgenode.cc/v1) |
56
72
  | `--max-per-call` / `--daily-cap` | Spending policy (fail-closed) |
57
73
 
58
- ## .env
74
+ ## Configuration (.env)
59
75
 
60
76
  ```bash
61
77
  # Required — your Solana wallet private key (base58)
@@ -65,15 +81,17 @@ BRIDGENODE_WALLET_KEY=...
65
81
 
66
82
  ## Security
67
83
 
68
- - **Receipt verification (Free-Riding protection):** after 200, `PAYMENT-RESPONSE` is verified — invalid receipt → error.
84
+ - **Receipt verification:** every response receipt is verified — invalid receipt → error.
69
85
  - **Spending policy (fail-closed):** max USD per call / per day — checked BEFORE signing.
70
86
 
71
87
  ## Requirements
72
88
 
73
89
  - Python ≥ 3.11
74
- - Solana wallet with USDC ATA (rent — agent's responsibility, §3.3)
90
+ - A Solana wallet with a USDC token account (ATA)
75
91
 
76
92
  ## Links
77
93
 
78
94
  - Website: https://bridgenode.cc
79
- - Protocol: x402 V2 (docs.x402.org)
95
+ - Models & prices: https://bridgenode.cc/v1/models
96
+ - Documentation: https://bridgenode.cc/llms.txt
97
+ - Protocol: x402 V2 (https://docs.x402.org)
@@ -0,0 +1,68 @@
1
+ # bridgenode-cli
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
4
+ [![Downloads](https://img.shields.io/pypi/dm/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
5
+ [![License: MIT-0](https://img.shields.io/badge/License-MIT--0-yellow.svg)](https://opensource.org/license/mit-0/)
6
+ [![Python versions](https://img.shields.io/pypi/pyversions/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
7
+
8
+ BridgeNode CLI — AI inference without API keys. Pay per request with **Solana USDC via x402**. The payment handshake is fully automatic, and fees are sponsored — no SOL needed.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pip install bridgenode-cli
14
+ ```
15
+
16
+ Or install the full toolkit (SDK + CLI):
17
+
18
+ ```bash
19
+ pip install bridgenode
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ```bash
25
+ # Single chat completion (payment handshake fully automatic)
26
+ bridgenode chat "Hello!" --model deepseek-v4-flash
27
+
28
+ # Smart routing: auto / eco / premium
29
+ bridgenode chat "Analyze this code" --mode auto
30
+
31
+ # Model list + prices (no payment)
32
+ bridgenode models
33
+ ```
34
+
35
+ ## Options
36
+
37
+ | Option | Description |
38
+ |---|---|
39
+ | `--model` | Explicit model id (see `bridgenode models`) |
40
+ | `--mode` | `auto` / `eco` / `premium` (smart routing) |
41
+ | `--max-tokens` | Max output tokens (billed upfront) |
42
+ | `--base-url` | Base URL (default: `BRIDGENODE_BASE_URL` / https://bridgenode.cc/v1) |
43
+ | `--max-per-call` / `--daily-cap` | Spending policy (fail-closed) |
44
+
45
+ ## Configuration (.env)
46
+
47
+ ```bash
48
+ # Required — your Solana wallet private key (base58)
49
+ BRIDGENODE_WALLET_KEY=...
50
+ # Optional: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
51
+ ```
52
+
53
+ ## Security
54
+
55
+ - **Receipt verification:** every response receipt is verified — invalid receipt → error.
56
+ - **Spending policy (fail-closed):** max USD per call / per day — checked BEFORE signing.
57
+
58
+ ## Requirements
59
+
60
+ - Python ≥ 3.11
61
+ - A Solana wallet with a USDC token account (ATA)
62
+
63
+ ## Links
64
+
65
+ - Website: https://bridgenode.cc
66
+ - Models & prices: https://bridgenode.cc/v1/models
67
+ - Documentation: https://bridgenode.cc/llms.txt
68
+ - Protocol: x402 V2 (https://docs.x402.org)
File without changes
@@ -1,30 +1,40 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bridgenode-cli
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: BridgeNode CLI — AI inference with x402 payment on Solana USDC. No API keys.
5
5
  Author-email: BridgeNode <eli.BNx@proton.me>
6
- License-Expression: MIT
6
+ License-Expression: MIT-0
7
7
  Project-URL: Homepage, https://bridgenode.cc
8
8
  Project-URL: Repository, https://github.com/applefanaimail-blip/bridgenode-llm
9
9
  Project-URL: Documentation, https://bridgenode.cc/llms.txt
10
- Keywords: x402,solana,usdc,ai,llm,cli,agents,payment,bridgenode
10
+ Keywords: x402,solana,usdc,ai,llm,cli,agents,payment,bridgenode,openai-compatible,chat,inference,micropayments
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
15
16
  Classifier: Programming Language :: Python :: 3.11
16
17
  Classifier: Programming Language :: Python :: 3.12
17
18
  Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
18
20
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Classifier: Typing :: Typed
19
22
  Requires-Python: >=3.11
20
23
  Description-Content-Type: text/markdown
24
+ License-File: LICENSE
21
25
  Requires-Dist: bridgenode-llm>=0.1.0
22
26
  Provides-Extra: dev
23
27
  Requires-Dist: pytest>=9.1.1; extra == "dev"
28
+ Dynamic: license-file
24
29
 
25
30
  # bridgenode-cli
26
31
 
27
- BridgeNode CLI — AI inference without API keys. Payment: **Solana USDC via x402** (automatic handshake, fee sponsorship — no SOL needed).
32
+ [![PyPI version](https://img.shields.io/pypi/v/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
33
+ [![Downloads](https://img.shields.io/pypi/dm/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
34
+ [![License: MIT-0](https://img.shields.io/badge/License-MIT--0-yellow.svg)](https://opensource.org/license/mit-0/)
35
+ [![Python versions](https://img.shields.io/pypi/pyversions/bridgenode-cli.svg)](https://pypi.org/project/bridgenode-cli/)
36
+
37
+ BridgeNode CLI — AI inference without API keys. Pay per request with **Solana USDC via x402**. The payment handshake is fully automatic, and fees are sponsored — no SOL needed.
28
38
 
29
39
  ## Installation
30
40
 
@@ -32,16 +42,22 @@ BridgeNode CLI — AI inference without API keys. Payment: **Solana USDC via x40
32
42
  pip install bridgenode-cli
33
43
  ```
34
44
 
45
+ Or install the full toolkit (SDK + CLI):
46
+
47
+ ```bash
48
+ pip install bridgenode
49
+ ```
50
+
35
51
  ## Usage
36
52
 
37
53
  ```bash
38
- # Single chat completion (x402 handshake hidden, §4.1)
54
+ # Single chat completion (payment handshake fully automatic)
39
55
  bridgenode chat "Hello!" --model deepseek-v4-flash
40
56
 
41
- # Smart routing (§5.1/§5.8): auto / eco / premium
57
+ # Smart routing: auto / eco / premium
42
58
  bridgenode chat "Analyze this code" --mode auto
43
59
 
44
- # Model list + prices (§5.2) — no payment
60
+ # Model list + prices (no payment)
45
61
  bridgenode models
46
62
  ```
47
63
 
@@ -51,11 +67,11 @@ bridgenode models
51
67
  |---|---|
52
68
  | `--model` | Explicit model id (see `bridgenode models`) |
53
69
  | `--mode` | `auto` / `eco` / `premium` (smart routing) |
54
- | `--max-tokens` | Max output tokens (billing upfront, §4.2) |
70
+ | `--max-tokens` | Max output tokens (billed upfront) |
55
71
  | `--base-url` | Base URL (default: `BRIDGENODE_BASE_URL` / https://bridgenode.cc/v1) |
56
72
  | `--max-per-call` / `--daily-cap` | Spending policy (fail-closed) |
57
73
 
58
- ## .env
74
+ ## Configuration (.env)
59
75
 
60
76
  ```bash
61
77
  # Required — your Solana wallet private key (base58)
@@ -65,15 +81,17 @@ BRIDGENODE_WALLET_KEY=...
65
81
 
66
82
  ## Security
67
83
 
68
- - **Receipt verification (Free-Riding protection):** after 200, `PAYMENT-RESPONSE` is verified — invalid receipt → error.
84
+ - **Receipt verification:** every response receipt is verified — invalid receipt → error.
69
85
  - **Spending policy (fail-closed):** max USD per call / per day — checked BEFORE signing.
70
86
 
71
87
  ## Requirements
72
88
 
73
89
  - Python ≥ 3.11
74
- - Solana wallet with USDC ATA (rent — agent's responsibility, §3.3)
90
+ - A Solana wallet with a USDC token account (ATA)
75
91
 
76
92
  ## Links
77
93
 
78
94
  - Website: https://bridgenode.cc
79
- - Protocol: x402 V2 (docs.x402.org)
95
+ - Models & prices: https://bridgenode.cc/v1/models
96
+ - Documentation: https://bridgenode.cc/llms.txt
97
+ - Protocol: x402 V2 (https://docs.x402.org)
@@ -1,7 +1,9 @@
1
+ LICENSE
1
2
  README.md
2
3
  pyproject.toml
3
4
  bridgenode_cli/__init__.py
4
5
  bridgenode_cli/main.py
6
+ bridgenode_cli/py.typed
5
7
  bridgenode_cli.egg-info/PKG-INFO
6
8
  bridgenode_cli.egg-info/SOURCES.txt
7
9
  bridgenode_cli.egg-info/dependency_links.txt
@@ -1,23 +1,27 @@
1
1
  [project]
2
2
  name = "bridgenode-cli"
3
- version = "0.1.1"
3
+ version = "0.1.2"
4
4
  description = "BridgeNode CLI — AI inference with x402 payment on Solana USDC. No API keys."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
7
- license = "MIT"
7
+ license = "MIT-0"
8
+ license-files = ["LICENSE"]
8
9
  authors = [
9
10
  { name = "BridgeNode", email = "eli.BNx@proton.me" },
10
11
  ]
11
- keywords = ["x402", "solana", "usdc", "ai", "llm", "cli", "agents", "payment", "bridgenode"]
12
+ keywords = ["x402", "solana", "usdc", "ai", "llm", "cli", "agents", "payment", "bridgenode", "openai-compatible", "chat", "inference", "micropayments"]
12
13
  classifiers = [
13
14
  "Development Status :: 4 - Beta",
14
15
  "Intended Audience :: Developers",
15
16
  "Operating System :: OS Independent",
16
17
  "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3 :: Only",
17
19
  "Programming Language :: Python :: 3.11",
18
20
  "Programming Language :: Python :: 3.12",
19
21
  "Programming Language :: Python :: 3.13",
22
+ "Programming Language :: Python :: 3.14",
20
23
  "Topic :: Scientific/Engineering :: Artificial Intelligence",
24
+ "Typing :: Typed",
21
25
  ]
22
26
  dependencies = [
23
27
  "bridgenode-llm>=0.1.0",
@@ -42,3 +46,6 @@ build-backend = "setuptools.build_meta"
42
46
 
43
47
  [tool.setuptools.packages.find]
44
48
  include = ["bridgenode_cli*"]
49
+
50
+ [tool.setuptools.package-data]
51
+ bridgenode_cli = ["py.typed"]
@@ -1,7 +1,7 @@
1
- """test_cli.py — bridgenode CLI testai (fix.md 4.4 ž1).
1
+ """test_cli.py — bridgenode CLI tests (fix.md 4.4 z1).
2
2
 
3
- Tikrina komandų išvedimą ir argumentų perdavimą su mock'intu LLMClient
4
- (jokio tinklo, jokio mokėjimo). Pilnas mock-402 kelias — 4.4 ž2.
3
+ Checks command output and argument passing with a mocked LLMClient
4
+ (no network, no payment). Full mock-402 path — 4.4 z2.
5
5
  """
6
6
 
7
7
  from __future__ import annotations
@@ -12,13 +12,13 @@ import pytest
12
12
 
13
13
  from bridgenode_llm import BridgenodeError
14
14
 
15
- # ⚠️ import bridgenode_cli.main as cli NEVEIKIA: __init__ `from .main import main`
16
- # shadow'ina submodulį — cli tampa funkcija. Naudojam importlib.
15
+ # ⚠️ import bridgenode_cli.main as cli DOES NOT WORK: __init__ `from .main import main`
16
+ # shadows the submodule — cli becomes a function. We use importlib.
17
17
  cli = importlib.import_module("bridgenode_cli.main")
18
18
 
19
19
 
20
20
  class FakeClient:
21
- """LLMClient pakaitalas — fiksuoja kvietimus, grąžina fiktyvius atsakymus."""
21
+ """LLMClient stand-in — records calls, returns fake responses."""
22
22
 
23
23
  def __init__(self, **kwargs):
24
24
  self.kwargs = kwargs
@@ -30,7 +30,7 @@ class FakeClient:
30
30
  "id": "cmpl-1",
31
31
  "object": "chat.completion",
32
32
  "choices": [{"index": 0,
33
- "message": {"role": "assistant", "content": "Labas!"},
33
+ "message": {"role": "assistant", "content": "Hello!"},
34
34
  "finish_reason": "stop"}],
35
35
  }
36
36
 
@@ -48,7 +48,7 @@ def test_chat_prints_content(fake_client, capsys):
48
48
  rc = cli.main(["chat", "Labas pasauli", "--model", "deepseek-v4-flash"])
49
49
  assert rc == 0
50
50
  out = capsys.readouterr().out
51
- assert "Labas!" in out
51
+ assert "Hello!" in out
52
52
  assert fake_client.chat_calls[0][0] == "deepseek-v4-flash"
53
53
  assert fake_client.chat_calls[0][1] == [
54
54
  {"role": "user", "content": "Labas pasauli"}]
@@ -63,7 +63,7 @@ def test_chat_mode_passed(fake_client, capsys):
63
63
 
64
64
 
65
65
  def test_chat_model_and_mode(fake_client):
66
- """§5.1: abu perduodami — konfliktą sprendžia serveris (model laimi)."""
66
+ """§5.1: both are passed through — the server resolves the conflict (model wins)."""
67
67
  rc = cli.main(["chat", "hi", "--model", "deepseek-v4-flash",
68
68
  "--mode", "premium"])
69
69
  assert rc == 0
@@ -83,7 +83,7 @@ def test_chat_requires_model_or_mode(fake_client, capsys):
83
83
  rc = cli.main(["chat", "hi"])
84
84
  assert rc == 2
85
85
  assert "model or --mode" in capsys.readouterr().err
86
- assert fake_client.chat_calls == [] # jokio kvietimo — klaida prieš SDK
86
+ assert fake_client.chat_calls == [] # no call — error before SDK
87
87
 
88
88
 
89
89
  def test_chat_error_exit_1(fake_client, monkeypatch, capsys):
@@ -147,10 +147,10 @@ def test_missing_prompt_exits_2(capsys):
147
147
 
148
148
 
149
149
  def test_client_kwargs_wired(monkeypatch):
150
- """CLI argumentai → LLMClient kwargs (timeout'ai, spending policy).
150
+ """CLI arguments → LLMClient kwargs (timeouts, spending policy).
151
151
 
152
- Globalios parinktys (--base-url ir kt.) — PRIEŠ subkomandą (argparse).
153
- Tikrinama per `chat` (models komanda SDK nenaudoja — tiesioginis HTTP, §5.2).
152
+ Global options (--base-url etc.) — BEFORE the subcommand (argparse).
153
+ Checked via `chat` (the models command does not use the SDK — direct HTTP, §5.2).
154
154
  """
155
155
  captured: dict = {}
156
156
 
@@ -1,9 +1,9 @@
1
- """test_cli_integration.py — CLI → realus SDK kelias su mock 402 (fix.md 4.4 ž2).
1
+ """test_cli_integration.py — CLI → real SDK path with mock 402 (fix.md 4.4 z2).
2
2
 
3
- Pilnas x402 handshake per tikrą `bridgenode_llm` SDK: CLI `chat` → 402
4
- (PAYMENT-REQUIRED) → dalinis TX → PAYMENT-SIGNATURE → 200 + validus
5
- PAYMENT-RESPONSE kvitas (fee payer pasirašo MŪSŲ TX žinutę). RPC (mint
6
- metadata) mock'inta. Jokio realaus tinklo, jokio realaus mokėjimo.
3
+ Full x402 handshake through the real `bridgenode_llm` SDK: CLI `chat` → 402
4
+ (PAYMENT-REQUIRED) → partial TX → PAYMENT-SIGNATURE → 200 + valid
5
+ PAYMENT-RESPONSE receipt (fee payer signs OUR TX message). RPC (mint
6
+ metadata) mocked. No real network, no real payment.
7
7
  """
8
8
 
9
9
  from __future__ import annotations
@@ -81,7 +81,7 @@ def _envelope(pay_to: str, fee_payer: str, amount: str = "2000") -> dict:
81
81
 
82
82
  def _receipt_header(payment_header: str, fee_payer_kp: Keypair,
83
83
  client_wallet: str, amount: str = "2000") -> str:
84
- """Validus PAYMENT-RESPONSE kvitas: fee payer pasirašo MŪSŲ TX žinutę."""
84
+ """Valid PAYMENT-RESPONSE receipt: fee payer signs OUR TX message."""
85
85
  payload = PaymentPayload.model_validate_json(base64.b64decode(payment_header))
86
86
  tx = VersionedTransaction.from_bytes(
87
87
  base64.b64decode(payload.payload["transaction"]))
@@ -105,7 +105,7 @@ def _openai_response() -> dict:
105
105
  "created": 1,
106
106
  "model": "deepseek-v4-flash",
107
107
  "choices": [{"index": 0,
108
- "message": {"role": "assistant", "content": "Labas!"},
108
+ "message": {"role": "assistant", "content": "Hello!"},
109
109
  "finish_reason": "stop"}],
110
110
  "usage": {"prompt_tokens": 10, "completion_tokens": 5, "total_tokens": 15},
111
111
  }
@@ -113,7 +113,7 @@ def _openai_response() -> dict:
113
113
 
114
114
  @pytest.fixture(autouse=True)
115
115
  def _mock_mint_metadata(monkeypatch):
116
- """Mint metadata be RPC (SDK scheme reikalauja, testai be tinklo)."""
116
+ """Mint metadata without RPC (the SDK scheme requires it, tests without network)."""
117
117
  def fake(client, network, mint, cache):
118
118
  return MintMetadata(decimals=6, token_program=Pubkey.from_string(TOKEN_PROGRAM))
119
119
  monkeypatch.setattr(
@@ -122,7 +122,7 @@ def _mock_mint_metadata(monkeypatch):
122
122
 
123
123
  @pytest.fixture()
124
124
  def _mock_http(monkeypatch):
125
- """httpx.Client → MockTransport (visi SDK request'ai per mock serverį)."""
125
+ """httpx.Client → MockTransport (all SDK requests through the mock server)."""
126
126
  real_client = httpx.Client
127
127
  state: dict = {"transport": None}
128
128
 
@@ -135,7 +135,7 @@ def _mock_http(monkeypatch):
135
135
 
136
136
 
137
137
  def _install_server(state: dict, fee_kp: Keypair, client_wallet: str):
138
- """Mock serveris: 402 → validus kvitas → 200. Grąžina (handler, seen)."""
138
+ """Mock server: 402 → valid receipt → 200. Returns (handler, seen)."""
139
139
  seen: list[dict] = []
140
140
 
141
141
  def handler(request: httpx.Request) -> httpx.Response:
@@ -163,10 +163,10 @@ def _install_server(state: dict, fee_kp: Keypair, client_wallet: str):
163
163
  return seen
164
164
 
165
165
 
166
- # ── chat: pilnas x402 handshake per realų SDK ────────────────────────────────
166
+ # ── chat: full x402 handshake through the real SDK ────────────────────────────────
167
167
 
168
168
  def test_cli_chat_full_handshake(monkeypatch, _mock_http, capsys):
169
- """CLI chat → realus SDK: 402 → TX → PAYMENT-SIGNATURE → 200 + kvitas."""
169
+ """CLI chat → real SDK: 402 → TX → PAYMENT-SIGNATURE → 200 + receipt."""
170
170
  fee_kp = Keypair()
171
171
  client_kp = Keypair()
172
172
  seen = _install_server(_mock_http, fee_kp, str(client_kp.pubkey()))
@@ -176,7 +176,7 @@ def test_cli_chat_full_handshake(monkeypatch, _mock_http, capsys):
176
176
  "chat", "Labas pasauli", "--model", "deepseek-v4-flash"])
177
177
 
178
178
  assert rc == 0
179
- assert "Labas!" in capsys.readouterr().out
179
+ assert "Hello!" in capsys.readouterr().out
180
180
  assert len(seen) == 2
181
181
  assert seen[0]["has_payment"] is False
182
182
  assert seen[1]["has_payment"] is True
@@ -185,7 +185,7 @@ def test_cli_chat_full_handshake(monkeypatch, _mock_http, capsys):
185
185
 
186
186
 
187
187
  def test_cli_chat_mode_auto(monkeypatch, _mock_http, capsys):
188
- """CLI --mode auto → SDK mode perduodamas (smart routing §5.1)."""
188
+ """CLI --mode auto → SDK mode is passed through (smart routing §5.1)."""
189
189
  fee_kp = Keypair()
190
190
  client_kp = Keypair()
191
191
  seen = _install_server(_mock_http, fee_kp, str(client_kp.pubkey()))
@@ -198,13 +198,13 @@ def test_cli_chat_mode_auto(monkeypatch, _mock_http, capsys):
198
198
 
199
199
 
200
200
  def test_cli_chat_kvitas_verify_fail(monkeypatch, _mock_http, capsys):
201
- """Suklastotas kvitas → CLI error (exit 1) — Free-Riding apsauga veikia."""
201
+ """Forged receipt → CLI error (exit 1) — Free-Riding protection works."""
202
202
  fee_kp = Keypair()
203
203
  client_kp = Keypair()
204
204
  fake_kp = Keypair()
205
205
  seen = _install_server(_mock_http, fee_kp, str(client_kp.pubkey()))
206
206
 
207
- # Perrašom kvitą po serverio atsakymo — netikras parašas (kito rakto)
207
+ # Rewrite the receipt after the server response — fake signature (of another key)
208
208
  original = _mock_http["transport"].handler
209
209
 
210
210
  def tampered(request: httpx.Request) -> httpx.Response:
@@ -215,7 +215,7 @@ def test_cli_chat_kvitas_verify_fail(monkeypatch, _mock_http, capsys):
215
215
  tx = VersionedTransaction.from_bytes(
216
216
  base64.b64decode(payload.payload["transaction"]))
217
217
  msg = bytes([0x80]) + bytes(tx.message)
218
- fake_sig = fake_kp.sign_message(msg) # ne fee payer'io raktas
218
+ fake_sig = fake_kp.sign_message(msg) # not the fee payer's key
219
219
  settle = SettleResponse(
220
220
  success=True, transaction=str(fake_sig), network=NETWORK,
221
221
  payer=str(client_kp.pubkey()), amount="2000")
@@ -233,7 +233,7 @@ def test_cli_chat_kvitas_verify_fail(monkeypatch, _mock_http, capsys):
233
233
  assert "does not match our TX" in capsys.readouterr().err
234
234
 
235
235
 
236
- # ── models: be mokėjimo (§5.2) ───────────────────────────────────────────────
236
+ # ── models: without payment (§5.2) ───────────────────────────────────────────────
237
237
 
238
238
  def test_cli_models_integration(monkeypatch, capsys):
239
239
  import httpx
@@ -249,7 +249,7 @@ def test_cli_models_integration(monkeypatch, capsys):
249
249
  "context_window": 131072, "max_output_tokens": 32768},
250
250
  ]})
251
251
 
252
- # models — tiesioginis HTTP (be SDK, §5.2 viešas endpointas)
252
+ # models — direct HTTP (no SDK, §5.2 public endpoint)
253
253
  monkeypatch.setattr(httpx, "get", fake_get)
254
254
  rc = cli.main(["--base-url", API_BASE, "models"])
255
255
  assert rc == 0
@@ -1,55 +0,0 @@
1
- # bridgenode-cli
2
-
3
- BridgeNode CLI — AI inference without API keys. Payment: **Solana USDC via x402** (automatic handshake, fee sponsorship — no SOL needed).
4
-
5
- ## Installation
6
-
7
- ```bash
8
- pip install bridgenode-cli
9
- ```
10
-
11
- ## Usage
12
-
13
- ```bash
14
- # Single chat completion (x402 handshake hidden, §4.1)
15
- bridgenode chat "Hello!" --model deepseek-v4-flash
16
-
17
- # Smart routing (§5.1/§5.8): auto / eco / premium
18
- bridgenode chat "Analyze this code" --mode auto
19
-
20
- # Model list + prices (§5.2) — no payment
21
- bridgenode models
22
- ```
23
-
24
- ## Options
25
-
26
- | Option | Description |
27
- |---|---|
28
- | `--model` | Explicit model id (see `bridgenode models`) |
29
- | `--mode` | `auto` / `eco` / `premium` (smart routing) |
30
- | `--max-tokens` | Max output tokens (billing upfront, §4.2) |
31
- | `--base-url` | Base URL (default: `BRIDGENODE_BASE_URL` / https://bridgenode.cc/v1) |
32
- | `--max-per-call` / `--daily-cap` | Spending policy (fail-closed) |
33
-
34
- ## .env
35
-
36
- ```bash
37
- # Required — your Solana wallet private key (base58)
38
- BRIDGENODE_WALLET_KEY=...
39
- # Optional: BRIDGENODE_BASE_URL, BRIDGENODE_MAX_PER_CALL, BRIDGENODE_DAILY_CAP
40
- ```
41
-
42
- ## Security
43
-
44
- - **Receipt verification (Free-Riding protection):** after 200, `PAYMENT-RESPONSE` is verified — invalid receipt → error.
45
- - **Spending policy (fail-closed):** max USD per call / per day — checked BEFORE signing.
46
-
47
- ## Requirements
48
-
49
- - Python ≥ 3.11
50
- - Solana wallet with USDC ATA (rent — agent's responsibility, §3.3)
51
-
52
- ## Links
53
-
54
- - Website: https://bridgenode.cc
55
- - Protocol: x402 V2 (docs.x402.org)
File without changes