Skip to content

docs: run the agent-wallet lifecycle from Python#123

Merged
MicBun merged 1 commit into
mainfrom
docs/maa-lifecycle-example
Jun 18, 2026
Merged

docs: run the agent-wallet lifecycle from Python#123
MicBun merged 1 commit into
mainfrom
docs/maa-lifecycle-example

Conversation

@MicBun

@MicBun MicBun commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

resolves: https://github.com/truflation/website/issues/4165

The Modular Agent Address (MAA / "agent wallet") feature is code-complete across the SDKs, but nothing exercised the whole lifecycle from Python against a live node. This adds a runnable example that does, plus the small amount of SDK support it needs to drive every step.

Example — examples/maa_lifecycle_example/

main.py walks the full lifecycle against a node where maa_exec is active (testnet from height 6523123), mirroring the node oracle tests/streams/maa/data_agent_test.go:

  • a restricted agent registers an immutable rule;
  • an unrestricted owner joins it to derive the wallet (the MAA) and funds it;
  • the agent runs create_streams + insert_records as the MAA — proving @caller is rewritten (the stream is owned by the MAA, not the agent key) and that fees debit the MAA's own escrow;
  • the agent's attempt to withdraw is rejected and the escrow is unchanged;
  • the owner withdraws the remainder, paying the agent its commission;
  • rule / allow-list / instance / audit events are read back.

It also cross-checks the chain-returned rule_id and MAA address against offline derivation. Configuration is via environment variables; README.md documents them and what success looks like.

SDK support the example needs

Driving the lifecycle surfaced that execute_agent_action could not pass NUMERIC arguments — JSON has no decimal type and the node does not coerce text to NUMERIC (it compares precision/scale exactly) — and nested integer arrays were mis-encoded. This PR adds:

  • MAANumericArg(value, precision, scale) (exported) — wraps a NUMERIC argument so the binding rebuilds a precision/scale-exact decimal across the JSON boundary (e.g. maa_withdraw's $amount NUMERIC(78,0), insert_records' $value NUMERIC(36,18)[]);
  • recursive argument decoding in bindings/maa.go so nested integers (e.g. insert_records' INT8[] event times) reach the node as integers, not floats;
  • TNClient.maa_get_balance(maa, bridge) — reads an agent wallet's escrow balance (the address is passed as BYTEA, which the generic call_procedure helper cannot do).

Tests

  • bindings/maa_decode_test.go — Go unit tests for the decode round-trip (nested ints, scalar + array numeric markers, error cases).
  • tests/test_maa_exec.py — extended with marker serialization, nested arrays, and validation (13 tests total).

Both are pure-unit (no node required). The gopy bindings were rebuilt.

Status

The example is dry-validated offline (argument shapes match the on-chain action signatures). Running it against testnet needs funded agent + owner keys, the gateway provider URL, and the testnet bridge namespace — all documented in the README.

Summary by CodeRabbit

  • New Features

    • Read agent wallet escrow balances on specified bridges.
    • Support precision-exact numeric arguments in agent actions using the new MAANumericArg type.
  • Documentation

    • Added end-to-end agent wallet lifecycle example with comprehensive setup guide.
  • Tests

    • Added unit tests for numeric argument handling and encoding.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Adds MAANumericArg, a precision/scale-exact NUMERIC argument marker, to the Python SDK and corresponding typed-argument decoding in the Go binding's decodeMAAArgs. Introduces MAAGetBalance/maa_get_balance on both sides for escrow balance reads. Ships unit tests for both layers and a new end-to-end MAA lifecycle smoke test with README.

Changes

MAA Numeric Argument Encoding and Balance Read

Layer / File(s) Summary
MAANumericArg marker class and Python serialization
src/trufnetwork_sdk_py/client.py, src/trufnetwork_sdk_py/__init__.py
Defines MAANumericArg with validated value/precision/scale and a {"__tn_type__":"numeric",...} JSON representation; updates _maa_exec_args to use a custom default hook encoding MAANumericArg and rejecting non-native objects; re-exports MAANumericArg from the package __all__.
Go decodeMAAArgs typed-argument pipeline
bindings/maa.go
Adds maaTypeKey constant and kwilTypes import; refactors decodeMAAArgs into a recursive pipeline that normalizes JSON numbers to int64/float64, reconstructs "numeric" markers as *types.Decimal via ParseDecimalExplicit, and range-checks precision/scale as uint16.
MAAGetBalance / maa_get_balance read method
bindings/maa.go, src/trufnetwork_sdk_py/client.py
Adds Go MAAGetBalance calling the maa_get_balance view procedure with (maaAddress, bridge); adds Python TNClient.maa_get_balance returning "0" when no escrow row is found.
Go decodeMAAArgs unit tests
bindings/maa_decode_test.go
Tests empty input, top-level scalars (int64/bool/nil/string), nested-array int64 regression, scalar and array-nested numeric marker decoding with exact Precision()/Scale() assertions, and negative cases for malformed/unsupported markers.
Python MAANumericArg serialization unit tests
tests/test_maa_exec.py
Validates MAANumericArg JSON encoding, nested array serialization, integer-backed construction, and constructor validation errors for invalid precision/scale.
MAA lifecycle smoke test and README
examples/maa_lifecycle_example/main.py, examples/maa_lifecycle_example/README.md
End-to-end Python script exercising rule creation, MAA derivation/registration, escrow funding, allowed inner actions, agent withdrawal rejection, owner withdrawal with commission, and on-chain state readback; README covers identities, environment variables, MAANumericArg usage, and success criteria.

Sequence Diagram(s)

sequenceDiagram
  rect rgba(173, 216, 230, 0.5)
    note over Caller,Go Binding: Numeric arg round-trip
    Caller->>TNClient.execute_agent_action: args with MAANumericArg(value, precision, scale)
    TNClient.execute_agent_action->>_maa_exec_args: args list
    _maa_exec_args->>_maa_json_default: json.dumps default hook
    _maa_json_default-->>_maa_exec_args: {"__tn_type__":"numeric","value":v,"precision":p,"scale":s}
    _maa_exec_args-->>Go Binding: JSON string via CGo
  end
  rect rgba(144, 238, 144, 0.5)
    note over Go Binding,KwilTypes: Go-side reconstruction
    Go Binding->>decodeMAAArgs: JSON array string
    decodeMAAArgs->>decodeMAAArgs: recursive array walk + maaTypeKey detection
    decodeMAAArgs->>ParseDecimalExplicit: value, precision, scale (uint16)
    ParseDecimalExplicit-->>decodeMAAArgs: *types.Decimal
    decodeMAAArgs-->>Go Binding: []any with *types.Decimal args
  end
  rect rgba(255, 223, 186, 0.5)
    note over TNClient,Go Binding: Balance read
    TNClient->>maa_get_balance: maa_address, bridge
    maa_get_balance->>MAAGetBalance: []byte, string
    MAAGetBalance-->>maa_get_balance: JSON {column_names, values}
    maa_get_balance-->>TNClient: balance string or "0"
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • trufnetwork/sdk-py#122: Introduced the initial maa_exec binding and shallow JSON number decoding in decodeMAAArgs — directly extended by this PR's typed "numeric" marker reconstruction.

Poem

🐇 A number's not just digits, you see,
It carries precision and scale with glee!
__tn_type__: numeric marks the spot,
The Go side rebuilds — no precision lost.
The escrow fills, the owner withdraws right,
The agent's blocked — the rabbit hops with delight! 🎉

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'docs: run the agent-wallet lifecycle from Python' is vague and incomplete. While a Python example is added, the PR's substance is primarily SDK enhancements (MAANumericArg, recursive arg decoding, maa_get_balance) that enable the example, making the title misleading about the PR's actual scope and intent. Revise the title to reflect the primary changes: e.g., 'feat: add MAANumericArg and MAA lifecycle example' or 'feat: SDK enhancements for agent-wallet execution and escrow balance queries'.
Docstring Coverage ⚠️ Warning Docstring coverage is 61.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/maa-lifecycle-example

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@holdex

holdex Bot commented Jun 18, 2026

Copy link
Copy Markdown

Time Submission Status

Member # Time Running Total Status Last Update
MicBun 4h ✅ Submitted Jun 18, 2026, 7:06 PM

Submit or update total time with:

@holdex pr submit-time 2h

Add time on top of previous submission with:

@holdex pr add-time 1h30m

See available commands to help comply with our Guidelines.

@MicBun MicBun self-assigned this Jun 18, 2026
@MicBun

MicBun commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

@holdex pr submit-time 4h

@MicBun
MicBun merged commit fbef9ad into main Jun 18, 2026
5 of 6 checks passed
@MicBun
MicBun deleted the docs/maa-lifecycle-example branch June 18, 2026 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant