feat: derive, register, and read agent wallets#121
Conversation
|
Warning Review limit reached
More reviews will be available in 16 minutes and 1 second. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (13)
📝 WalkthroughWalkthroughThis PR implements a complete Modular Agent Addresses (MAA) feature for agent-wallet operations. It adds off-chain cryptographic utilities for rule hash and address derivation, Go bindings for on-chain transaction/read execution, Python SDK methods orchestrating these layers, package-level exports, and comprehensive unit tests validating correctness. ChangesModular Agent Addresses (Migration 048)
Sequence DiagramsequenceDiagram
participant App
participant TNClient
participant Utils
participant GoBindings
participant OnChainProcedure
App->>TNClient: maa_create_rule(fee_mode, namespaces, ...)
TNClient->>Utils: compute_rules_hash(...)
Utils-->>TNClient: rules_hash
TNClient->>Utils: derive_rule_id(restricted, rules_hash, salt)
Utils-->>TNClient: rule_id
TNClient->>GoBindings: MAACreateRule(rule_id, ...)
GoBindings->>OnChainProcedure: call maa_create_rule
OnChainProcedure-->>GoBindings: tx_hash
GoBindings-->>TNClient: tx_hash
TNClient-->>App: MAACreateRuleResult { tx_hash, rule_id }
App->>TNClient: join_agent_address(rule_id)
TNClient->>Utils: derive_maa_address(unrestricted, restricted, rule_id)
Utils-->>TNClient: maa_address
TNClient->>GoBindings: MAAJoin(rule_id)
GoBindings->>OnChainProcedure: call maa_join
OnChainProcedure-->>GoBindings: tx_hash
GoBindings-->>TNClient: tx_hash
TNClient-->>App: MAAJoinResult { tx_hash, maa_address }
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/trufnetwork_sdk_py/utils.py (1)
103-103: 💤 Low valueConsider adding
strict=Truetozip()for defensive consistency.The length validation on line 78 already guarantees equal-length lists, so this is not a bug. However, adding
strict=Trueprovides an explicit contract and catches any future refactoring that might bypass the validation.♻️ Suggested change
- for ns, act, bh in zip(ns_list, act_list, bh_list): + for ns, act, bh in zip(ns_list, act_list, bh_list, strict=True):🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/trufnetwork_sdk_py/utils.py` at line 103, The loop using zip over ns_list, act_list, bh_list should be made defensive by enabling strict mode: update the zip call inside the function containing the line "for ns, act, bh in zip(ns_list, act_list, bh_list)" to use zip(..., strict=True) so any future length mismatch raises immediately; locate the loop in utils.py (the function that iterates ns_list/act_list/bh_list) and add the strict=True argument to the zip invocation.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@bindings/maa.go`:
- Around line 44-45: MAACreateRule currently strips only the lowercase "0x"
prefix before hex.DecodeString which causes uppercase "0X"-prefixed hashes to
fail; update MAACreateRule to normalize both prefix variants by removing either
"0x" or "0X" (e.g., test HasPrefix for both and strip the first two chars or
call TrimPrefix for both variants) before calling hex.DecodeString so the
decoded, derr := hex.DecodeString(...) call succeeds for uppercase-prefixed
inputs.
In `@src/trufnetwork_sdk_py/client.py`:
- Around line 3658-3663: The _maa_rows function currently uses zip(cols, row)
which silently truncates when a row's length doesn't match cols; update
_maa_rows to validate shapes first: after parsing cols and vals, iterate rows
and for each row check len(row) == len(cols) and if not raise a clear ValueError
(or custom exception) including the function name, row index, expected column
count, actual row length and the offending row content, otherwise build the dict
with dict(zip(cols, row)); this ensures mismatched row/column shapes fail fast
instead of producing corrupted dicts.
---
Nitpick comments:
In `@src/trufnetwork_sdk_py/utils.py`:
- Line 103: The loop using zip over ns_list, act_list, bh_list should be made
defensive by enabling strict mode: update the zip call inside the function
containing the line "for ns, act, bh in zip(ns_list, act_list, bh_list)" to use
zip(..., strict=True) so any future length mismatch raises immediately; locate
the loop in utils.py (the function that iterates ns_list/act_list/bh_list) and
add the strict=True argument to the zip invocation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 74537601-cc4b-4339-bc23-e1137068e96b
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (6)
bindings/maa.gopyproject.tomlsrc/trufnetwork_sdk_py/__init__.pysrc/trufnetwork_sdk_py/client.pysrc/trufnetwork_sdk_py/utils.pytests/test_maa.py
Time Submission Status
Submit or update total time with: Add time on top of previous submission with: See available commands to help comply with our Guidelines. |
|
@holdex pr submit-time 4h |
resolves: https://github.com/truflation/website/issues/4085
Adds Modular Agent Address (MAA) support to the Python SDK so developers can build and operate agent wallets entirely from the client.
What this enables
Pieces
src/trufnetwork_sdk_py/utils.py— pure derivation:compute_rules_hash→derive_rule_id→derive_maa_address/derive_maa_address_hex. Byte-exact mirror of the node precompiles and the Go/JS SDKs (eth_hash keccak256, frozenRULES_PREIMAGElayout, last-write-wins dedup, canonical bytewise sort).src/trufnetwork_sdk_py/client.py—TNClientmethods over the on-chain actions:maa_create_rule,join_agent_address, and the read getters (maa_get_rule,maa_get_allowed_actions,maa_get_instance,maa_list_by_restricted,maa_list_by_unrestricted,maa_list_instances_by_rule,maa_get_events,maa_is_known), plus result/row TypedDicts.bindings/maa.go— gopy bindings that submit the rule actions and return reads as JSON{column_names, values}(no gopyinterface{}conversion).pyproject.toml— addseth-hash[pycryptodome]for keccak.Tests
tests/test_maa.py) asserting the frozen golden vectors A/B byte-for-byte, plus canonicalization (order-independence, last-write-wins dedup), the dedup-key no-collision invariant, and input validation. No network required.The golden vectors are identical across the node and all three SDKs — a one-byte mismatch would derive a different wallet and send funds astray, so they are kept in lockstep.
Summary by CodeRabbit
New Features
Tests