mppi-protocol 0.1.2__tar.gz → 0.1.4__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 (64) hide show
  1. mppi_protocol-0.1.4/PKG-INFO +114 -0
  2. mppi_protocol-0.1.4/README.md +99 -0
  3. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/pyproject.toml +1 -1
  4. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/capabilities.py +36 -0
  5. mppi_protocol-0.1.4/src/mppi_protocol/chain.py +1809 -0
  6. mppi_protocol-0.1.4/src/mppi_protocol/circle.py +1089 -0
  7. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/contract.py +10 -0
  8. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/discovery.py +9 -3
  9. mppi_protocol-0.1.4/src/mppi_protocol/follower.py +623 -0
  10. mppi_protocol-0.1.4/src/mppi_protocol/http.py +295 -0
  11. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/local_state.py +28 -2
  12. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/operations.py +31 -11
  13. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/signing.py +49 -0
  14. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/types.py +10 -1
  15. mppi_protocol-0.1.4/tests/test_chain.py +1973 -0
  16. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_checkpoint.py +31 -0
  17. mppi_protocol-0.1.4/tests/test_circle.py +1649 -0
  18. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_circle_activation.py +26 -41
  19. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_deployment.py +9 -0
  20. mppi_protocol-0.1.4/tests/test_follower.py +1031 -0
  21. mppi_protocol-0.1.4/tests/test_funding_check.py +221 -0
  22. mppi_protocol-0.1.4/tests/test_http_transport.py +694 -0
  23. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_operations.py +33 -0
  24. mppi_protocol-0.1.2/PKG-INFO +0 -41
  25. mppi_protocol-0.1.2/README.md +0 -26
  26. mppi_protocol-0.1.2/src/mppi_protocol/chain.py +0 -835
  27. mppi_protocol-0.1.2/src/mppi_protocol/circle.py +0 -749
  28. mppi_protocol-0.1.2/src/mppi_protocol/follower.py +0 -323
  29. mppi_protocol-0.1.2/src/mppi_protocol/http.py +0 -126
  30. mppi_protocol-0.1.2/tests/test_chain.py +0 -1058
  31. mppi_protocol-0.1.2/tests/test_circle.py +0 -618
  32. mppi_protocol-0.1.2/tests/test_follower.py +0 -358
  33. mppi_protocol-0.1.2/tests/test_http_transport.py +0 -298
  34. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/.gitignore +0 -0
  35. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/LICENSE +0 -0
  36. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi/__init__.py +0 -0
  37. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi/py.typed +0 -0
  38. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi/v1/__init__.py +0 -0
  39. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi/v1/mppi_pb2.py +0 -0
  40. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi/v1/mppi_pb2.pyi +0 -0
  41. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi/v1/mppi_pb2_grpc.py +0 -0
  42. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/__init__.py +0 -0
  43. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/_observers.py +0 -0
  44. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/accounting.py +0 -0
  45. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/amounts.py +0 -0
  46. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/catalog.py +0 -0
  47. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/contract_abi.json +0 -0
  48. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/deployment.py +0 -0
  49. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/errors.py +0 -0
  50. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/py.typed +0 -0
  51. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/registry.py +0 -0
  52. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/src/mppi_protocol/wire.py +0 -0
  53. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_accounting.py +0 -0
  54. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_amounts.py +0 -0
  55. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_catalog.py +0 -0
  56. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_contract_calls.py +0 -0
  57. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_discovery_validation.py +0 -0
  58. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_fixture_schema.py +0 -0
  59. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_observers.py +0 -0
  60. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_registry.py +0 -0
  61. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_runtime_wire.py +0 -0
  62. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_signing.py +0 -0
  63. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_signing_vectors.py +0 -0
  64. {mppi_protocol-0.1.2 → mppi_protocol-0.1.4}/tests/test_value_types.py +0 -0
@@ -0,0 +1,114 @@
1
+ Metadata-Version: 2.5
2
+ Name: mppi-protocol
3
+ Version: 0.1.4
4
+ Summary: Shared MPPI wire bindings and exact payment primitives
5
+ License-Expression: Apache-2.0
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: eth-abi==6.0.0
9
+ Requires-Dist: eth-account==0.14.0
10
+ Requires-Dist: googleapis-common-protos==1.75.4
11
+ Requires-Dist: grpcio==1.84.0
12
+ Requires-Dist: protobuf==7.36.2
13
+ Requires-Dist: pycryptodome==3.23.0
14
+ Description-Content-Type: text/markdown
15
+
16
+ # MPPI Python protocol support
17
+
18
+ Internal shared distribution for the agent and provider SDKs. It contains the
19
+ generated `mppi.v1` wire bindings and `mppi_protocol` exact payment primitives.
20
+ It is not another role SDK.
21
+
22
+ The implementation validates catalogs and report transitions, computes exact
23
+ amounts, signs and verifies fixed-session proofs, prepares contract calls and
24
+ checks canonical receipt evidence. Version `0.1.1` also supplies shared discovery
25
+ validation and the Circle Agent Wallet adapter used by both Python roles.
26
+ Version `0.1.4`, used by `mppi-agent` 0.1.6 and `mppi-provider` 0.2.0, adds:
27
+
28
+ - `ChainFollower.unwatch_session`, which stops reading a session and drops the
29
+ block that proved it;
30
+ - `ChainFollower.follow(funding=(agent_id, wallet))` and `unwatch_funding`: each
31
+ refresh also reads the registry's funding wallet for that agent id and the
32
+ wallet's code (`ChainSnapshot.funding`, a `FundingState`) at no extra round
33
+ trip, and `ChainReader.funding_signature` checks a funding signature at that
34
+ block in one;
35
+ - `ChainReader.opening_transaction`, one `eth_getLogs` naming the transaction
36
+ of a session's `SessionOpened`, a lead to prove by its receipt;
37
+ - `ChainFollower.confirm(..., observation)`: a refresh behind the block that
38
+ proved a confirmed state is lag (`ChainLagError`), not a contradiction. Once
39
+ refreshes have stayed behind it for longer than `max_age_ms`,
40
+ `confirmed_readiness` reports that session `STATE_UNAVAILABLE` until one
41
+ reaches it;
42
+ - `TransportError.retry_after`. A transient read is repeated after a random
43
+ share of its wait and after any `Retry-After` that fits the existing bound,
44
+ and a batch repeats only its refused entries;
45
+ - `CircleAgentWallet.retire(operation_refs=..., at=...)` and `near_capacity`.
46
+ A journal record keeps its call's digest instead of the call, and only the
47
+ 16 MiB bound limits the journal; `retire` marks records, in the journal,
48
+ with the time from which they are forgotten once they hold a transaction
49
+ hash. A failed command's error names the CLI's listed error code and an
50
+ unknown result carries its cause. An execute checks the CLI and wallet first
51
+ unless a check began within 60 seconds, and after any failed command the next
52
+ execute or signature checks again. The journal's lock is held only while the
53
+ journal is read or replaced, never across a Circle command; within one
54
+ process the adapter runs one operation at a time, CLI commands included. An
55
+ execute or reconcile waits for the lock up to `timeout_seconds`, and one that
56
+ cannot then
57
+ record Circle's answer returns `UNKNOWN` with its transaction id and hash,
58
+ written into the journal at the next journal step; a failed save keeps them
59
+ in memory and does not fail that step. A reconcile withdraws a
60
+ record's retirement mark. An execute refused for an invalid reference, or
61
+ once the journal shows no record of its reference, raises
62
+ `CircleNotSubmittedError`;
63
+ - local records wait up to one second for a lock that a spawned child process
64
+ still holds, or as long as `Checkpoint(..., lock_wait=...)` gives;
65
+ - `ChainFollower.watch_session`: watches that wait behind a refresh are read
66
+ together by the next one, so many sessions watched at once, as a provider's
67
+ recoveries at startup watch theirs, take a few refreshes rather than one each;
68
+ - a snapshot splits its views across Multicall3 calls of at most 512 views, each
69
+ anchored to the snapshot's block, and `HttpJsonRpc` keeps each request within
70
+ 1 MiB, so a large watch set takes more round trips instead of failing every
71
+ refresh; a backend that still has not imported a block (-32014) once the
72
+ repeats are spent is `ChainLagError`.
73
+
74
+ Every interface change is additive. One behaviour narrows: `HttpTransport.request`
75
+ refuses a request body over 1 MiB before sending it, as the Rust transport does.
76
+ One exception changes: for an invalid reference, or a call for another network
77
+ or over 60 KiB, `CircleAgentWallet.execute` raises `CircleNotSubmittedError`,
78
+ which is not a `ValidationError`, where `0.1.3` raised `ValidationError`.
79
+ Earlier releases refuse a Circle journal this one has saved, so do not
80
+ downgrade over it.
81
+ Version `0.1.3`, used by `mppi-agent` 0.1.4, 0.1.4.1 and 0.1.5, keeps HTTP connections
82
+ alive and sends a step's reads as one JSON-RPC batch (`HttpJsonRpc.call_many`),
83
+ and treats a read timeout as transient. It adds:
84
+
85
+ - `ChainReader.latest`, a one-request snapshot through Multicall3, and the
86
+ batched steps `observe` and `session_at`; on final networks
87
+ (`DeploymentProfile.instant_finality`) receipts alone prove operations;
88
+ - `ChainReader.funding`, which checks a funding signature as USDC does;
89
+ - `ChainFollower.follow`, `refresh_at`, `confirm`, `confirmed_readiness` and
90
+ `on_refresh_failure`, for requests that read no chain;
91
+ - `NotSubmittedError` and `OperationResult.cause`.
92
+
93
+ Three changes are not additive. `OpeningEvidence` and `ClosingEvidence` carry the
94
+ proving `observation` instead of a `Block`, and `ChainReader.agent_wallet` takes
95
+ that observation. The Circle adapter pins no account code:
96
+ `CircleAgentWallet(chain=..., address=..., checkpoint_path=...)` replaces the
97
+ `wallet` and `implementation` pins, and its journal is format 2 (format 1 still
98
+ loads).
99
+ Version `0.1.2`, used by `mppi-agent` 0.1.3, adds bounded repeats of transient
100
+ read-only JSON-RPC calls, lag-tolerant chain following
101
+ (`ChainLagError`, `last_refresh_failure`), `HookError.detail` and
102
+ `TransportError.transient`, and accepts checkpoint format 2; every change is
103
+ additive.
104
+ These building blocks do not authorize inference or store provider state.
105
+
106
+ See [the SDK interfaces](../../docs/sdk-interfaces.md) for the implemented surface
107
+ and runtime integration boundaries.
108
+
109
+ The [runtime reference](../../docs/python-runtime.md) describes the implemented
110
+ trust boundaries, dependency adapters and evidence limitations.
111
+
112
+ ## License
113
+
114
+ Copyright 2026 MPPI contributors. Licensed under the [Apache License, Version 2.0](LICENSE).
@@ -0,0 +1,99 @@
1
+ # MPPI Python protocol support
2
+
3
+ Internal shared distribution for the agent and provider SDKs. It contains the
4
+ generated `mppi.v1` wire bindings and `mppi_protocol` exact payment primitives.
5
+ It is not another role SDK.
6
+
7
+ The implementation validates catalogs and report transitions, computes exact
8
+ amounts, signs and verifies fixed-session proofs, prepares contract calls and
9
+ checks canonical receipt evidence. Version `0.1.1` also supplies shared discovery
10
+ validation and the Circle Agent Wallet adapter used by both Python roles.
11
+ Version `0.1.4`, used by `mppi-agent` 0.1.6 and `mppi-provider` 0.2.0, adds:
12
+
13
+ - `ChainFollower.unwatch_session`, which stops reading a session and drops the
14
+ block that proved it;
15
+ - `ChainFollower.follow(funding=(agent_id, wallet))` and `unwatch_funding`: each
16
+ refresh also reads the registry's funding wallet for that agent id and the
17
+ wallet's code (`ChainSnapshot.funding`, a `FundingState`) at no extra round
18
+ trip, and `ChainReader.funding_signature` checks a funding signature at that
19
+ block in one;
20
+ - `ChainReader.opening_transaction`, one `eth_getLogs` naming the transaction
21
+ of a session's `SessionOpened`, a lead to prove by its receipt;
22
+ - `ChainFollower.confirm(..., observation)`: a refresh behind the block that
23
+ proved a confirmed state is lag (`ChainLagError`), not a contradiction. Once
24
+ refreshes have stayed behind it for longer than `max_age_ms`,
25
+ `confirmed_readiness` reports that session `STATE_UNAVAILABLE` until one
26
+ reaches it;
27
+ - `TransportError.retry_after`. A transient read is repeated after a random
28
+ share of its wait and after any `Retry-After` that fits the existing bound,
29
+ and a batch repeats only its refused entries;
30
+ - `CircleAgentWallet.retire(operation_refs=..., at=...)` and `near_capacity`.
31
+ A journal record keeps its call's digest instead of the call, and only the
32
+ 16 MiB bound limits the journal; `retire` marks records, in the journal,
33
+ with the time from which they are forgotten once they hold a transaction
34
+ hash. A failed command's error names the CLI's listed error code and an
35
+ unknown result carries its cause. An execute checks the CLI and wallet first
36
+ unless a check began within 60 seconds, and after any failed command the next
37
+ execute or signature checks again. The journal's lock is held only while the
38
+ journal is read or replaced, never across a Circle command; within one
39
+ process the adapter runs one operation at a time, CLI commands included. An
40
+ execute or reconcile waits for the lock up to `timeout_seconds`, and one that
41
+ cannot then
42
+ record Circle's answer returns `UNKNOWN` with its transaction id and hash,
43
+ written into the journal at the next journal step; a failed save keeps them
44
+ in memory and does not fail that step. A reconcile withdraws a
45
+ record's retirement mark. An execute refused for an invalid reference, or
46
+ once the journal shows no record of its reference, raises
47
+ `CircleNotSubmittedError`;
48
+ - local records wait up to one second for a lock that a spawned child process
49
+ still holds, or as long as `Checkpoint(..., lock_wait=...)` gives;
50
+ - `ChainFollower.watch_session`: watches that wait behind a refresh are read
51
+ together by the next one, so many sessions watched at once, as a provider's
52
+ recoveries at startup watch theirs, take a few refreshes rather than one each;
53
+ - a snapshot splits its views across Multicall3 calls of at most 512 views, each
54
+ anchored to the snapshot's block, and `HttpJsonRpc` keeps each request within
55
+ 1 MiB, so a large watch set takes more round trips instead of failing every
56
+ refresh; a backend that still has not imported a block (-32014) once the
57
+ repeats are spent is `ChainLagError`.
58
+
59
+ Every interface change is additive. One behaviour narrows: `HttpTransport.request`
60
+ refuses a request body over 1 MiB before sending it, as the Rust transport does.
61
+ One exception changes: for an invalid reference, or a call for another network
62
+ or over 60 KiB, `CircleAgentWallet.execute` raises `CircleNotSubmittedError`,
63
+ which is not a `ValidationError`, where `0.1.3` raised `ValidationError`.
64
+ Earlier releases refuse a Circle journal this one has saved, so do not
65
+ downgrade over it.
66
+ Version `0.1.3`, used by `mppi-agent` 0.1.4, 0.1.4.1 and 0.1.5, keeps HTTP connections
67
+ alive and sends a step's reads as one JSON-RPC batch (`HttpJsonRpc.call_many`),
68
+ and treats a read timeout as transient. It adds:
69
+
70
+ - `ChainReader.latest`, a one-request snapshot through Multicall3, and the
71
+ batched steps `observe` and `session_at`; on final networks
72
+ (`DeploymentProfile.instant_finality`) receipts alone prove operations;
73
+ - `ChainReader.funding`, which checks a funding signature as USDC does;
74
+ - `ChainFollower.follow`, `refresh_at`, `confirm`, `confirmed_readiness` and
75
+ `on_refresh_failure`, for requests that read no chain;
76
+ - `NotSubmittedError` and `OperationResult.cause`.
77
+
78
+ Three changes are not additive. `OpeningEvidence` and `ClosingEvidence` carry the
79
+ proving `observation` instead of a `Block`, and `ChainReader.agent_wallet` takes
80
+ that observation. The Circle adapter pins no account code:
81
+ `CircleAgentWallet(chain=..., address=..., checkpoint_path=...)` replaces the
82
+ `wallet` and `implementation` pins, and its journal is format 2 (format 1 still
83
+ loads).
84
+ Version `0.1.2`, used by `mppi-agent` 0.1.3, adds bounded repeats of transient
85
+ read-only JSON-RPC calls, lag-tolerant chain following
86
+ (`ChainLagError`, `last_refresh_failure`), `HookError.detail` and
87
+ `TransportError.transient`, and accepts checkpoint format 2; every change is
88
+ additive.
89
+ These building blocks do not authorize inference or store provider state.
90
+
91
+ See [the SDK interfaces](../../docs/sdk-interfaces.md) for the implemented surface
92
+ and runtime integration boundaries.
93
+
94
+ The [runtime reference](../../docs/python-runtime.md) describes the implemented
95
+ trust boundaries, dependency adapters and evidence limitations.
96
+
97
+ ## License
98
+
99
+ Copyright 2026 MPPI contributors. Licensed under the [Apache License, Version 2.0](LICENSE).
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "mppi-protocol"
7
- version = "0.1.2"
7
+ version = "0.1.4"
8
8
  license = "Apache-2.0"
9
9
  license-files = ["LICENSE"]
10
10
  description = "Shared MPPI wire bindings and exact payment primitives"
@@ -51,7 +51,27 @@ class FundingAuthorization:
51
51
  )
52
52
 
53
53
 
54
+ class NotSubmittedError(RuntimeError):
55
+ """A wallet adapter's own durable record proves the call never reached the
56
+ wallet service: nothing was submitted and the reference binds nothing, so
57
+ it may be sent again, with this call or another.
58
+
59
+ Raise it only with that proof. Any other failure leaves the outcome unknown.
60
+ """
61
+
62
+
54
63
  class TransactionWallet(Protocol):
64
+ """A wallet adapter's transactions. ``execute`` sends ``call`` once from
65
+ ``address`` with zero native value and durably binds ``operation_ref`` to
66
+ it first; ``reconcile`` reports that same submission and never sends.
67
+
68
+ The runtimes may call ``execute`` and ``reconcile`` for different
69
+ operations, or the same one, at once, from several threads (a recovery
70
+ reads before taking the runtime's locks), so an adapter serializes access
71
+ to its own records, as ``CircleAgentWallet`` does.
72
+ Every requirement is in docs/sdk-interfaces.md, Wallet requirements.
73
+ """
74
+
55
75
  @property
56
76
  def address(self) -> bytes: ...
57
77
 
@@ -61,6 +81,22 @@ class TransactionWallet(Protocol):
61
81
 
62
82
 
63
83
  class FundingWallet(TransactionWallet, Protocol):
84
+ """An agent's funding wallet from any provider, behind a thin adapter.
85
+
86
+ ``sign_funding_authorization`` returns bytes USDC accepts for exactly that
87
+ authorization from ``address``: an ECDSA signature for an account without
88
+ code, or bytes its ERC-1271 isValidSignature accepts. Before submitting
89
+ an opening, the agent checks them and that its ERC-8004 agent id binds
90
+ ``address``. No wallet implementation or version is pinned.
91
+
92
+ A wallet whose service creates the signature when it executes declares an
93
+ optional ``signs_at_execute = True``: ``sign_funding_authorization`` then
94
+ returns a placeholder that ``execute`` replaces. The agent neither verifies
95
+ nor simulates the placeholder; it still checks the agent-id binding, and
96
+ USDC verifies the real signature on chain.
97
+ Every requirement is in docs/sdk-interfaces.md, Wallet requirements.
98
+ """
99
+
64
100
  def sign_funding_authorization(self, authorization: FundingAuthorization) -> bytes: ...
65
101
 
66
102