diff --git a/bindings/maa.go b/bindings/maa.go index 0e42c1f..09fb872 100644 --- a/bindings/maa.go +++ b/bindings/maa.go @@ -27,8 +27,19 @@ import ( // declares. The Python side emits this shape; see trufnetwork_sdk_py.client.MAANumericArg. const maaTypeKey = "__tn_type__" -// MAACreateRule submits maa_create_rule (the caller becomes the restricted agent) and returns the tx -// hash. bodyHashesHex is parallel to namespaces/actions; an empty element is an unpinned (NULL) entry. +// maaWriteResult JSON-encodes a write's tx hash together with the address/id the underlying Go SDK +// derives for it, matching the {tx_hash, } shape the Python client reads back. +func maaWriteResult(txHash, key string, raw []byte) (string, error) { + out, err := json.Marshal(map[string]string{"tx_hash": txHash, key: "0x" + hex.EncodeToString(raw)}) + if err != nil { + return "", errors.Wrap(err, "marshal maa write result") + } + return string(out), nil +} + +// MAACreateRule registers an agent-wallet rule (the caller becomes the restricted agent) by delegating +// to the Go SDK's CreateAgentRule, and returns JSON {tx_hash, rule_id} (rule_id 0x-hex, derived by the +// Go SDK). bodyHashesHex is parallel to namespaces/actions; an empty element is an unpinned (NULL) entry. func MAACreateRule( client *tnclient.Client, salt []byte, @@ -39,12 +50,6 @@ func MAACreateRule( actions []string, bodyHashesHex []string, ) (string, error) { - ctx := context.Background() - act, err := client.LoadActions() - if err != nil { - return "", errors.Wrap(err, "load actions") - } - bodyHashes := make([][]byte, len(bodyHashesHex)) for i, h := range bodyHashesHex { if h == "" { @@ -59,27 +64,40 @@ func MAACreateRule( bodyHashes[i] = decoded } - txHash, err := act.ExecuteProcedure(ctx, "maa_create_rule", [][]any{ - {salt, feeMode, feeBps, feeFlat, namespaces, actions, bodyHashes}, + ctx := context.Background() + act, err := client.LoadActions() + if err != nil { + return "", errors.Wrap(err, "load actions") + } + ruleID, txHash, err := act.CreateAgentRule(ctx, types.MAACreateRuleInput{ + Salt: salt, + FeeMode: feeMode, + FeeBps: feeBps, + FeeFlat: feeFlat, + Namespaces: namespaces, + Actions: actions, + BodyHashes: bodyHashes, }) if err != nil { return "", errors.Wrap(err, "maa_create_rule") } - return txHash.String(), nil + return maaWriteResult(txHash, "rule_id", ruleID) } -// MAAJoin submits maa_join (the caller becomes the unrestricted owner/funder) and returns the tx hash. +// MAAJoin joins an existing rule as the unrestricted owner/funder by delegating to the Go SDK's +// JoinAgentAddress (which resolves the rule and derives the wallet), and returns JSON +// {tx_hash, maa_address} (maa_address 0x-hex). func MAAJoin(client *tnclient.Client, ruleID []byte) (string, error) { ctx := context.Background() act, err := client.LoadActions() if err != nil { return "", errors.Wrap(err, "load actions") } - txHash, err := act.ExecuteProcedure(ctx, "maa_join", [][]any{{ruleID}}) + maaAddress, txHash, err := act.JoinAgentAddress(ctx, ruleID) if err != nil { return "", errors.Wrap(err, "maa_join") } - return txHash.String(), nil + return maaWriteResult(txHash, "maa_address", maaAddress) } // MAAExec submits a maa_exec transaction: run one allow-listed inner action AS the agent wallet. The diff --git a/go.mod b/go.mod index 6ef31c3..76541d5 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 github.com/pkg/errors v0.9.1 github.com/trufnetwork/kwil-db/core v0.4.3-0.20260615121733-0d71bd259558 - github.com/trufnetwork/sdk-go v0.7.3-0.20260615130252-00f0a043ec8d + github.com/trufnetwork/sdk-go v0.7.3-0.20260622120135-f266b733466c google.golang.org/genproto v0.0.0-20251111163417-95abcf5c77ba ) diff --git a/go.sum b/go.sum index 7b58e47..783c63a 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,8 @@ github.com/trufnetwork/kwil-db v0.10.3-0.20260615121733-0d71bd259558 h1:I49YGUiU github.com/trufnetwork/kwil-db v0.10.3-0.20260615121733-0d71bd259558/go.mod h1:LiBAC48uZl2B0IiLtD2hpOce7RNfpuDdghVAOc3u1Qo= github.com/trufnetwork/kwil-db/core v0.4.3-0.20260615121733-0d71bd259558 h1:m7a9HITFMXJF22QznIKoAdeiH8eZxWPU8IRzgcyNMo8= github.com/trufnetwork/kwil-db/core v0.4.3-0.20260615121733-0d71bd259558/go.mod h1:HnOsh9+BN13LJCjiH0+XKaJzyjWKf+H9AofFFp90KwQ= -github.com/trufnetwork/sdk-go v0.7.3-0.20260615130252-00f0a043ec8d h1:Qd4vNPoprahvfp+UNNGtgaXUlHwFrgxsWBhMqGQs0Bc= -github.com/trufnetwork/sdk-go v0.7.3-0.20260615130252-00f0a043ec8d/go.mod h1:CivlBpc5RcYwyo8EysoAZWXXfmTtigfkR5VctivwSHc= +github.com/trufnetwork/sdk-go v0.7.3-0.20260622120135-f266b733466c h1:CfoiZyqRH8VCLSQPrm77ntxgQgOfi/b99nGIukQR2eI= +github.com/trufnetwork/sdk-go v0.7.3-0.20260622120135-f266b733466c/go.mod h1:CivlBpc5RcYwyo8EysoAZWXXfmTtigfkR5VctivwSHc= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= diff --git a/src/trufnetwork_sdk_py/client.py b/src/trufnetwork_sdk_py/client.py index c546e5c..e87f09a 100644 --- a/src/trufnetwork_sdk_py/client.py +++ b/src/trufnetwork_sdk_py/client.py @@ -33,7 +33,6 @@ from pydantic import BaseModel -from .utils import compute_rules_hash, derive_maa_address, derive_rule_id T = TypeVar("T") @@ -3495,8 +3494,8 @@ def maa_create_rule( ) -> MAACreateRuleResult: """ Register an agent-wallet rule. The caller (signer) becomes the restricted agent. Returns the - locally-derived rule_id (the handle a funder passes to join_agent_address) and the tx hash. The - rule is immutable once created; no funds move here. + rule_id (the handle a funder passes to join_agent_address; derived by the underlying Go SDK) and + the tx hash. The rule is immutable once created; no funds move here. body_hashes is parallel to namespaces/actions; each element may be bytes, a 0x-hex string, or None (unpinned). salt may be bytes, a 0x-hex string, or None. @@ -3511,44 +3510,35 @@ def maa_create_rule( salt_bytes = self._maa_to_bytes(salt) fee_flat_str = str(fee_flat) if fee_flat is not None else "0" - # Derive the rule_id locally (caller = the restricted agent) so it is known before the tx lands. - restricted = self._maa_to_bytes(truf_sdk.GetCurrentAccount(self.client)) - rules_hash = compute_rules_hash(fee_mode, int(fee_bps), fee_flat_str, ns, acts, body_hashes_hex) - rule_id = derive_rule_id(restricted, rules_hash, salt_bytes) - - tx_hash = truf_sdk.MAACreateRule( - self.client, - go.Slice_byte(list(salt_bytes)), - fee_mode, - int(fee_bps), - fee_flat_str, - go.Slice_string(ns), - go.Slice_string(acts), - go.Slice_string(body_hashes_hex), + result = json.loads( + truf_sdk.MAACreateRule( + self.client, + go.Slice_byte(list(salt_bytes)), + fee_mode, + int(fee_bps), + fee_flat_str, + go.Slice_string(ns), + go.Slice_string(acts), + go.Slice_string(body_hashes_hex), + ) ) if wait: - self.wait_for_tx(tx_hash) - return {"tx_hash": tx_hash, "rule_id": "0x" + rule_id.hex()} + self.wait_for_tx(result["tx_hash"]) + return {"tx_hash": result["tx_hash"], "rule_id": result["rule_id"]} def join_agent_address(self, rule_id: bytes | str, wait: bool = True) -> MAAJoinResult: """ Join an existing rule as the unrestricted owner/funder. The caller (signer) becomes the owner. - Returns the locally-derived MAA address (the wallet to fund) and the tx hash. The rule's - restricted creator is looked up on-chain to derive the address. + Returns the MAA address (the wallet to fund; derived by the underlying Go SDK, which looks up + the rule's restricted creator on-chain) and the tx hash. """ rid = self._maa_to_bytes(rule_id) if len(rid) != 32: raise ValueError(f"rule_id must be 32 bytes, got {len(rid)}") - rule = self.maa_get_rule(rid) - if rule is None: - raise ValueError("unknown rule_id") - unrestricted = self._maa_to_bytes(truf_sdk.GetCurrentAccount(self.client)) - maa_address = derive_maa_address(unrestricted, rule["restricted_addr"], rid) - - tx_hash = truf_sdk.MAAJoin(self.client, go.Slice_byte(list(rid))) + result = json.loads(truf_sdk.MAAJoin(self.client, go.Slice_byte(list(rid)))) if wait: - self.wait_for_tx(tx_hash) - return {"tx_hash": tx_hash, "maa_address": "0x" + maa_address.hex()} + self.wait_for_tx(result["tx_hash"]) + return {"tx_hash": result["tx_hash"], "maa_address": result["maa_address"]} def execute_agent_action( self,