agent0-sdk 0.31__tar.gz → 1.0.0__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.
- agent0_sdk-1.0.0/MANIFEST.in +10 -0
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/PKG-INFO +21 -7
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/README.md +19 -5
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/__init__.py +1 -1
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/agent.py +172 -30
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/contracts.py +93 -58
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/feedback_manager.py +90 -161
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/indexer.py +54 -26
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/models.py +6 -19
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/oasf_validator.py +1 -1
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/sdk.py +31 -16
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/subgraph_client.py +34 -15
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/web3_client.py +184 -17
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk.egg-info/PKG-INFO +21 -7
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk.egg-info/SOURCES.txt +2 -15
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/pyproject.toml +2 -2
- agent0_sdk-0.31/tests/__init__.py +0 -1
- agent0_sdk-0.31/tests/config.py +0 -46
- agent0_sdk-0.31/tests/conftest.py +0 -22
- agent0_sdk-0.31/tests/discover_test_data.py +0 -445
- agent0_sdk-0.31/tests/test_feedback.py +0 -417
- agent0_sdk-0.31/tests/test_models.py +0 -224
- agent0_sdk-0.31/tests/test_multi_chain.py +0 -588
- agent0_sdk-0.31/tests/test_oasf_management.py +0 -404
- agent0_sdk-0.31/tests/test_real_public_servers.py +0 -103
- agent0_sdk-0.31/tests/test_registration.py +0 -267
- agent0_sdk-0.31/tests/test_registrationIpfs.py +0 -227
- agent0_sdk-0.31/tests/test_sdk.py +0 -240
- agent0_sdk-0.31/tests/test_search.py +0 -415
- agent0_sdk-0.31/tests/test_transfer.py +0 -255
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/LICENSE +0 -0
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/endpoint_crawler.py +0 -0
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/core/ipfs_client.py +0 -0
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/taxonomies/all_domains.json +0 -0
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk/taxonomies/all_skills.json +0 -0
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk.egg-info/dependency_links.txt +0 -0
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk.egg-info/requires.txt +0 -0
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/agent0_sdk.egg-info/top_level.txt +0 -0
- {agent0_sdk-0.31 → agent0_sdk-1.0.0}/setup.cfg +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent0-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Python SDK for agent portability, discovery and trust based on ERC-8004
|
|
5
|
-
Author-email: Marco De Rossi <marco
|
|
5
|
+
Author-email: Marco De Rossi <marco@ag0.xyz>
|
|
6
6
|
License: MIT License
|
|
7
7
|
|
|
8
8
|
Copyright (c) 2025 Marco De Rossi
|
|
@@ -152,12 +152,15 @@ agent.setENS("myagent.eth")
|
|
|
152
152
|
|
|
153
153
|
# Add OASF skills and domains (standardized taxonomies)
|
|
154
154
|
agent.addSkill("data_engineering/data_transformation_pipeline", validate_oasf=True)
|
|
155
|
-
agent.addSkill("natural_language_processing/summarization", validate_oasf=True)
|
|
155
|
+
agent.addSkill("natural_language_processing/natural_language_generation/summarization", validate_oasf=True)
|
|
156
156
|
agent.addDomain("finance_and_business/investment_services", validate_oasf=True)
|
|
157
|
-
agent.addDomain("technology/data_science", validate_oasf=True)
|
|
157
|
+
agent.addDomain("technology/data_science/data_science", validate_oasf=True)
|
|
158
158
|
|
|
159
159
|
# Configure wallet and trust
|
|
160
|
-
|
|
160
|
+
# Note: agentWallet is an on-chain verified attribute. setAgentWallet() is on-chain only.
|
|
161
|
+
# EOAs: the NEW wallet must sign an EIP-712 message. If you pass new_wallet_signer, the SDK will
|
|
162
|
+
# build + sign the typed data automatically.
|
|
163
|
+
# If the current SDK signer address matches the new wallet, it can auto-sign without new_wallet_signer.
|
|
161
164
|
agent.setTrust(reputation=True, cryptoEconomic=True)
|
|
162
165
|
|
|
163
166
|
# Add metadata and set status
|
|
@@ -168,6 +171,16 @@ agent.setActive(True)
|
|
|
168
171
|
agent.registerIPFS()
|
|
169
172
|
print(f"Agent registered: {agent.agentId}") # e.g., "11155111:123"
|
|
170
173
|
print(f"Agent URI: {agent.agentURI}") # e.g., "ipfs://Qm..."
|
|
174
|
+
|
|
175
|
+
# (Optional) Change the agent wallet after registration
|
|
176
|
+
# - On mint/registration, `agentWallet` defaults to the current owner address.
|
|
177
|
+
# - Call this only if you want a DIFFERENT wallet (or after a transfer, since the wallet resets to zero).
|
|
178
|
+
# - Transaction is sent by the SDK signer (agent owner), but the signature must be produced by the NEW wallet.
|
|
179
|
+
agent.setAgentWallet(
|
|
180
|
+
"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
|
|
181
|
+
chainId=11155111,
|
|
182
|
+
new_wallet_signer=os.getenv("NEW_WALLET_PRIVATE_KEY"),
|
|
183
|
+
)
|
|
171
184
|
```
|
|
172
185
|
|
|
173
186
|
### 3. Load and Edit Agent
|
|
@@ -213,7 +226,8 @@ agent_summary = sdk.getAgent("11155111:123")
|
|
|
213
226
|
feedback_file = sdk.prepareFeedback(
|
|
214
227
|
agentId="11155111:123",
|
|
215
228
|
score=85, # 0-100 (mandatory)
|
|
216
|
-
tags=["data_analyst", "finance"], # Optional
|
|
229
|
+
tags=["data_analyst", "finance"], # Optional: tags are now strings (not bytes32)
|
|
230
|
+
endpoint="https://example.com/endpoint", # Optional: endpoint URI associated with feedback
|
|
217
231
|
capability="tools", # Optional: MCP capability
|
|
218
232
|
name="code_generation", # Optional: MCP tool name
|
|
219
233
|
skill="python" # Optional: A2A skill
|
|
@@ -307,7 +321,7 @@ OASF skills and domains appear in your agent's registration file:
|
|
|
307
321
|
],
|
|
308
322
|
"domains": [
|
|
309
323
|
"finance_and_business/investment_services",
|
|
310
|
-
"technology/data_science"
|
|
324
|
+
"technology/data_science/data_science"
|
|
311
325
|
]
|
|
312
326
|
}
|
|
313
327
|
]
|
|
@@ -82,12 +82,15 @@ agent.setENS("myagent.eth")
|
|
|
82
82
|
|
|
83
83
|
# Add OASF skills and domains (standardized taxonomies)
|
|
84
84
|
agent.addSkill("data_engineering/data_transformation_pipeline", validate_oasf=True)
|
|
85
|
-
agent.addSkill("natural_language_processing/summarization", validate_oasf=True)
|
|
85
|
+
agent.addSkill("natural_language_processing/natural_language_generation/summarization", validate_oasf=True)
|
|
86
86
|
agent.addDomain("finance_and_business/investment_services", validate_oasf=True)
|
|
87
|
-
agent.addDomain("technology/data_science", validate_oasf=True)
|
|
87
|
+
agent.addDomain("technology/data_science/data_science", validate_oasf=True)
|
|
88
88
|
|
|
89
89
|
# Configure wallet and trust
|
|
90
|
-
|
|
90
|
+
# Note: agentWallet is an on-chain verified attribute. setAgentWallet() is on-chain only.
|
|
91
|
+
# EOAs: the NEW wallet must sign an EIP-712 message. If you pass new_wallet_signer, the SDK will
|
|
92
|
+
# build + sign the typed data automatically.
|
|
93
|
+
# If the current SDK signer address matches the new wallet, it can auto-sign without new_wallet_signer.
|
|
91
94
|
agent.setTrust(reputation=True, cryptoEconomic=True)
|
|
92
95
|
|
|
93
96
|
# Add metadata and set status
|
|
@@ -98,6 +101,16 @@ agent.setActive(True)
|
|
|
98
101
|
agent.registerIPFS()
|
|
99
102
|
print(f"Agent registered: {agent.agentId}") # e.g., "11155111:123"
|
|
100
103
|
print(f"Agent URI: {agent.agentURI}") # e.g., "ipfs://Qm..."
|
|
104
|
+
|
|
105
|
+
# (Optional) Change the agent wallet after registration
|
|
106
|
+
# - On mint/registration, `agentWallet` defaults to the current owner address.
|
|
107
|
+
# - Call this only if you want a DIFFERENT wallet (or after a transfer, since the wallet resets to zero).
|
|
108
|
+
# - Transaction is sent by the SDK signer (agent owner), but the signature must be produced by the NEW wallet.
|
|
109
|
+
agent.setAgentWallet(
|
|
110
|
+
"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
|
|
111
|
+
chainId=11155111,
|
|
112
|
+
new_wallet_signer=os.getenv("NEW_WALLET_PRIVATE_KEY"),
|
|
113
|
+
)
|
|
101
114
|
```
|
|
102
115
|
|
|
103
116
|
### 3. Load and Edit Agent
|
|
@@ -143,7 +156,8 @@ agent_summary = sdk.getAgent("11155111:123")
|
|
|
143
156
|
feedback_file = sdk.prepareFeedback(
|
|
144
157
|
agentId="11155111:123",
|
|
145
158
|
score=85, # 0-100 (mandatory)
|
|
146
|
-
tags=["data_analyst", "finance"], # Optional
|
|
159
|
+
tags=["data_analyst", "finance"], # Optional: tags are now strings (not bytes32)
|
|
160
|
+
endpoint="https://example.com/endpoint", # Optional: endpoint URI associated with feedback
|
|
147
161
|
capability="tools", # Optional: MCP capability
|
|
148
162
|
name="code_generation", # Optional: MCP tool name
|
|
149
163
|
skill="python" # Optional: A2A skill
|
|
@@ -237,7 +251,7 @@ OASF skills and domains appear in your agent's registration file:
|
|
|
237
251
|
],
|
|
238
252
|
"domains": [
|
|
239
253
|
"finance_and_business/investment_services",
|
|
240
|
-
"technology/data_science"
|
|
254
|
+
"technology/data_science/data_science"
|
|
241
255
|
]
|
|
242
256
|
}
|
|
243
257
|
]
|
|
@@ -176,16 +176,14 @@ class Agent:
|
|
|
176
176
|
return self.registration_file
|
|
177
177
|
|
|
178
178
|
def _collectMetadataForRegistration(self) -> List[Dict[str, Any]]:
|
|
179
|
-
"""Collect all metadata entries for registration.
|
|
179
|
+
"""Collect all metadata entries for registration.
|
|
180
|
+
|
|
181
|
+
Note: agentWallet is now a reserved metadata key and cannot be set via setMetadata().
|
|
182
|
+
It must be set separately using setAgentWallet() with EIP-712 signature verification.
|
|
183
|
+
"""
|
|
180
184
|
metadata_entries = []
|
|
181
185
|
|
|
182
|
-
#
|
|
183
|
-
if self.walletAddress:
|
|
184
|
-
addr_bytes = bytes.fromhex(self.walletAddress[2:]) # Remove '0x' prefix
|
|
185
|
-
metadata_entries.append({
|
|
186
|
-
"key": "agentWallet",
|
|
187
|
-
"value": addr_bytes
|
|
188
|
-
})
|
|
186
|
+
# Note: agentWallet is no longer set via metadata - it's now reserved and managed via setAgentWallet()
|
|
189
187
|
|
|
190
188
|
# Add ENS name metadata
|
|
191
189
|
if self.ensEndpoint:
|
|
@@ -339,7 +337,7 @@ class Agent:
|
|
|
339
337
|
Add a skill to the OASF endpoint.
|
|
340
338
|
|
|
341
339
|
Args:
|
|
342
|
-
slug: The skill slug to add (e.g., "natural_language_processing/summarization")
|
|
340
|
+
slug: The skill slug to add (e.g., "natural_language_processing/natural_language_generation/summarization")
|
|
343
341
|
validate_oasf: If True, validate the slug against the OASF taxonomy (default: False)
|
|
344
342
|
|
|
345
343
|
Returns:
|
|
@@ -492,20 +490,55 @@ class Agent:
|
|
|
492
490
|
self.registration_file.updatedAt = int(time.time())
|
|
493
491
|
return self
|
|
494
492
|
|
|
495
|
-
def setAgentWallet(
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
493
|
+
def setAgentWallet(
|
|
494
|
+
self,
|
|
495
|
+
new_wallet: Address,
|
|
496
|
+
chainId: Optional[int] = None,
|
|
497
|
+
*,
|
|
498
|
+
new_wallet_signer: Optional[Union[str, Any]] = None,
|
|
499
|
+
deadline: Optional[int] = None,
|
|
500
|
+
signature: Optional[bytes] = None,
|
|
501
|
+
) -> 'Agent':
|
|
502
|
+
"""Set agent wallet address on-chain (ERC-8004 agentWallet).
|
|
503
|
+
|
|
504
|
+
This method is **on-chain only**. The `agentWallet` is a verified attribute and must be set via
|
|
505
|
+
the IdentityRegistry `setAgentWallet` function.
|
|
506
|
+
|
|
507
|
+
EOAs: provide `new_wallet_signer` (private key string or eth-account account) OR ensure the SDK
|
|
508
|
+
signer address matches `new_wallet` so the SDK can auto-sign.\n
|
|
509
|
+
Contract wallets (ERC-1271): provide `signature` bytes produced by the wallet’s signing mechanism.
|
|
510
|
+
The SDK will build the correct EIP-712 typed data internally, but cannot produce the wallet signature.
|
|
511
|
+
|
|
512
|
+
Args:
|
|
513
|
+
new_wallet: New wallet address (must be controlled by the signer that produces the signature)
|
|
514
|
+
chainId: Optional local bookkeeping for registration file (walletChainId). Defaults to agent chain.
|
|
515
|
+
new_wallet_signer: EOA signer used to sign the EIP-712 message (private key string or eth-account account)
|
|
516
|
+
deadline: Signature deadline timestamp. Defaults to now+60s (must be <= now+5min per contract).
|
|
517
|
+
signature: Raw signature bytes (intended for ERC-1271 / external signing only)
|
|
518
|
+
"""
|
|
519
|
+
# Breaking/clean: this API is only meaningful for already-registered agents.
|
|
520
|
+
if not self.agentId:
|
|
521
|
+
raise ValueError(
|
|
522
|
+
"Cannot set agent wallet before the agent is registered on-chain. "
|
|
523
|
+
"Call agent.register(...) / agent.registerIPFS() first to obtain agentId."
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
addr = new_wallet
|
|
527
|
+
|
|
528
|
+
if not addr:
|
|
529
|
+
raise ValueError("Wallet address cannot be empty. Use a non-zero address.")
|
|
507
530
|
|
|
508
|
-
#
|
|
531
|
+
# Validate address format
|
|
532
|
+
if not addr.startswith("0x") or len(addr) != 42:
|
|
533
|
+
raise ValueError(f"Invalid Ethereum address format: {addr}. Must be 42 characters starting with '0x'")
|
|
534
|
+
|
|
535
|
+
# Validate hexadecimal characters
|
|
536
|
+
try:
|
|
537
|
+
int(addr[2:], 16)
|
|
538
|
+
except ValueError:
|
|
539
|
+
raise ValueError(f"Invalid hexadecimal characters in address: {addr}")
|
|
540
|
+
|
|
541
|
+
# Determine chain ID to use (local bookkeeping)
|
|
509
542
|
if chainId is None:
|
|
510
543
|
# Extract chain ID from agentId if available, otherwise use SDK's chain ID
|
|
511
544
|
if self.agentId and ":" in self.agentId:
|
|
@@ -516,14 +549,104 @@ class Agent:
|
|
|
516
549
|
else:
|
|
517
550
|
chainId = self.sdk.chainId # Use SDK's chain ID as fallback
|
|
518
551
|
|
|
519
|
-
#
|
|
520
|
-
if
|
|
521
|
-
|
|
552
|
+
# Parse agent ID
|
|
553
|
+
agent_id_int = int(self.agentId.split(":")[-1]) if ":" in self.agentId else int(self.agentId)
|
|
554
|
+
|
|
555
|
+
# Check if wallet is already set to this address (skip if same)
|
|
556
|
+
try:
|
|
557
|
+
current_wallet = self.sdk.web3_client.call_contract(
|
|
558
|
+
self.sdk.identity_registry,
|
|
559
|
+
"getAgentWallet",
|
|
560
|
+
agent_id_int
|
|
561
|
+
)
|
|
562
|
+
if current_wallet and current_wallet.lower() == addr.lower():
|
|
563
|
+
logger.debug(f"Agent wallet is already set to {addr}, skipping on-chain update")
|
|
564
|
+
# Still update local registration file
|
|
565
|
+
self.registration_file.walletAddress = addr
|
|
566
|
+
self.registration_file.walletChainId = chainId
|
|
567
|
+
self.registration_file.updatedAt = int(time.time())
|
|
568
|
+
return self
|
|
569
|
+
except Exception as e:
|
|
570
|
+
logger.debug(f"Could not check current agent wallet: {e}, proceeding with update")
|
|
571
|
+
|
|
572
|
+
# Set deadline (default to 60 seconds from now; contract max is now+5min)
|
|
573
|
+
if deadline is None:
|
|
574
|
+
deadline = int(time.time()) + 60
|
|
575
|
+
|
|
576
|
+
# Resolve typed data + signature
|
|
577
|
+
identity_registry_address = self.sdk.identity_registry.address
|
|
578
|
+
owner_address = self.sdk.web3_client.call_contract(self.sdk.identity_registry, "ownerOf", agent_id_int)
|
|
579
|
+
|
|
580
|
+
full_message = self.sdk.web3_client.build_agent_wallet_set_typed_data(
|
|
581
|
+
agent_id=agent_id_int,
|
|
582
|
+
new_wallet=addr,
|
|
583
|
+
owner=owner_address,
|
|
584
|
+
deadline=deadline,
|
|
585
|
+
verifying_contract=identity_registry_address,
|
|
586
|
+
chain_id=self.sdk.web3_client.chain_id,
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
if signature is None:
|
|
590
|
+
# EOA signing paths
|
|
591
|
+
if new_wallet_signer is not None:
|
|
592
|
+
# Validate signer address matches addr (fail fast)
|
|
593
|
+
try:
|
|
594
|
+
from eth_account import Account as _Account
|
|
595
|
+
if isinstance(new_wallet_signer, str):
|
|
596
|
+
signer_addr = _Account.from_key(new_wallet_signer).address
|
|
597
|
+
else:
|
|
598
|
+
signer_addr = getattr(new_wallet_signer, "address", None)
|
|
599
|
+
except Exception:
|
|
600
|
+
signer_addr = getattr(new_wallet_signer, "address", None)
|
|
601
|
+
|
|
602
|
+
if not signer_addr or signer_addr.lower() != addr.lower():
|
|
603
|
+
raise ValueError(
|
|
604
|
+
f"new_wallet_signer address ({signer_addr}) does not match new_wallet ({addr})."
|
|
605
|
+
)
|
|
606
|
+
|
|
607
|
+
signature = self.sdk.web3_client.sign_typed_data(full_message, new_wallet_signer) # type: ignore[arg-type]
|
|
608
|
+
else:
|
|
609
|
+
# Auto-sign only if SDK signer == new wallet
|
|
610
|
+
current_address = self.sdk.web3_client.account.address if self.sdk.web3_client.account else None
|
|
611
|
+
if current_address and current_address.lower() == addr.lower():
|
|
612
|
+
signature = self.sdk.web3_client.sign_typed_data(full_message, self.sdk.web3_client.account)
|
|
613
|
+
else:
|
|
614
|
+
raise ValueError(
|
|
615
|
+
f"New wallet must sign. Provide new_wallet_signer (EOA) or signature (ERC-1271/external). "
|
|
616
|
+
f"SDK signer is {current_address}, new_wallet is {addr}."
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
# Optional: verify recover matches addr for EOA signatures
|
|
620
|
+
recovered = self.sdk.web3_client.w3.eth.account.recover_message(
|
|
621
|
+
__import__("eth_account.messages").messages.encode_typed_data(full_message=full_message),
|
|
622
|
+
signature=signature,
|
|
623
|
+
)
|
|
624
|
+
if recovered.lower() != addr.lower():
|
|
625
|
+
raise ValueError(f"Signature verification failed: recovered {recovered} but expected {addr}")
|
|
626
|
+
|
|
627
|
+
# Call setAgentWallet on the contract
|
|
628
|
+
try:
|
|
629
|
+
txHash = self.sdk.web3_client.transact_contract(
|
|
630
|
+
self.sdk.identity_registry,
|
|
631
|
+
"setAgentWallet",
|
|
632
|
+
agent_id_int,
|
|
633
|
+
addr,
|
|
634
|
+
deadline,
|
|
635
|
+
signature
|
|
636
|
+
)
|
|
637
|
+
|
|
638
|
+
# Wait for transaction
|
|
639
|
+
receipt = self.sdk.web3_client.wait_for_transaction(txHash)
|
|
640
|
+
logger.debug(f"Agent wallet set on-chain: {txHash}")
|
|
641
|
+
|
|
642
|
+
except Exception as e:
|
|
643
|
+
raise ValueError(f"Failed to set agent wallet on-chain: {e}")
|
|
522
644
|
|
|
523
645
|
# Update local registration file
|
|
524
646
|
self.registration_file.walletAddress = addr
|
|
525
647
|
self.registration_file.walletChainId = chainId
|
|
526
648
|
self.registration_file.updatedAt = int(time.time())
|
|
649
|
+
self._last_registered_wallet = addr
|
|
527
650
|
|
|
528
651
|
return self
|
|
529
652
|
|
|
@@ -636,7 +759,7 @@ class Agent:
|
|
|
636
759
|
agentId = int(self.agentId.split(":")[-1])
|
|
637
760
|
txHash = self.sdk.web3_client.transact_contract(
|
|
638
761
|
self.sdk.identity_registry,
|
|
639
|
-
"
|
|
762
|
+
"setAgentURI",
|
|
640
763
|
agentId,
|
|
641
764
|
f"ipfs://{ipfsCid}"
|
|
642
765
|
)
|
|
@@ -673,7 +796,7 @@ class Agent:
|
|
|
673
796
|
agentId = int(self.agentId.split(":")[-1])
|
|
674
797
|
txHash = self.sdk.web3_client.transact_contract(
|
|
675
798
|
self.sdk.identity_registry,
|
|
676
|
-
"
|
|
799
|
+
"setAgentURI",
|
|
677
800
|
agentId,
|
|
678
801
|
f"ipfs://{ipfsCid}"
|
|
679
802
|
)
|
|
@@ -715,7 +838,7 @@ class Agent:
|
|
|
715
838
|
txHash = self.sdk.web3_client.transact_contract(
|
|
716
839
|
self.sdk.identity_registry,
|
|
717
840
|
"register",
|
|
718
|
-
"", # Empty
|
|
841
|
+
"", # Empty agentURI for now
|
|
719
842
|
metadata_entries
|
|
720
843
|
)
|
|
721
844
|
|
|
@@ -820,7 +943,7 @@ class Agent:
|
|
|
820
943
|
agentId = int(self.registration_file.agentId.split(":")[-1])
|
|
821
944
|
txHash = self.sdk.web3_client.transact_contract(
|
|
822
945
|
self.sdk.identity_registry,
|
|
823
|
-
"
|
|
946
|
+
"setAgentURI",
|
|
824
947
|
agentId,
|
|
825
948
|
agentURI
|
|
826
949
|
)
|
|
@@ -846,7 +969,12 @@ class Agent:
|
|
|
846
969
|
approve_operator: bool = False,
|
|
847
970
|
idem: Optional[IdemKey] = None,
|
|
848
971
|
) -> Dict[str, Any]:
|
|
849
|
-
"""Transfer agent ownership.
|
|
972
|
+
"""Transfer agent ownership.
|
|
973
|
+
|
|
974
|
+
Note: When an agent is transferred, the agentWallet is automatically reset
|
|
975
|
+
to the zero address on-chain. The new owner must call setAgentWallet() to
|
|
976
|
+
set a new wallet address with EIP-712 signature verification.
|
|
977
|
+
"""
|
|
850
978
|
if not self.registration_file.agentId:
|
|
851
979
|
raise ValueError("Agent must be registered before transferring")
|
|
852
980
|
|
|
@@ -863,6 +991,11 @@ class Agent:
|
|
|
863
991
|
|
|
864
992
|
receipt = self.sdk.web3_client.wait_for_transaction(txHash)
|
|
865
993
|
|
|
994
|
+
# Note: agentWallet will be reset to zero address by the contract
|
|
995
|
+
# Update local state to reflect this
|
|
996
|
+
self.registration_file.walletAddress = None
|
|
997
|
+
self._last_registered_wallet = None
|
|
998
|
+
|
|
866
999
|
return {
|
|
867
1000
|
"txHash": txHash,
|
|
868
1001
|
"agentId": self.registration_file.agentId,
|
|
@@ -907,6 +1040,10 @@ class Agent:
|
|
|
907
1040
|
|
|
908
1041
|
Only the current owner can transfer the agent.
|
|
909
1042
|
|
|
1043
|
+
Note: When an agent is transferred, the agentWallet is automatically reset
|
|
1044
|
+
to the zero address on-chain. The new owner must call setAgentWallet() to
|
|
1045
|
+
set a new wallet address with EIP-712 signature verification.
|
|
1046
|
+
|
|
910
1047
|
Args:
|
|
911
1048
|
newOwnerAddress: Ethereum address of the new owner
|
|
912
1049
|
|
|
@@ -964,6 +1101,11 @@ class Agent:
|
|
|
964
1101
|
|
|
965
1102
|
logger.debug(f"Agent {self.registration_file.agentId} successfully transferred to {checksum_address}")
|
|
966
1103
|
|
|
1104
|
+
# Note: agentWallet will be reset to zero address by the contract
|
|
1105
|
+
# Update local state to reflect this
|
|
1106
|
+
self.registration_file.walletAddress = None
|
|
1107
|
+
self._last_registered_wallet = None
|
|
1108
|
+
|
|
967
1109
|
return {"txHash": txHash, "from": currentOwner, "to": checksum_address, "agentId": self.registration_file.agentId}
|
|
968
1110
|
|
|
969
1111
|
def activate(self, idem: Optional[IdemKey] = None) -> RegistrationFile:
|