agentspay 0.1.0 โ†’ 0.2.0

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 (126) hide show
  1. package/.env.example +40 -0
  2. package/README.md +35 -4
  3. package/VERIFICATION_SUMMARY.txt +151 -0
  4. package/dist/api/server.d.ts.map +1 -1
  5. package/dist/api/server.js +530 -74
  6. package/dist/api/server.js.map +1 -1
  7. package/dist/bsv/crypto.d.ts +65 -0
  8. package/dist/bsv/crypto.d.ts.map +1 -0
  9. package/dist/bsv/crypto.js +158 -0
  10. package/dist/bsv/crypto.js.map +1 -0
  11. package/dist/bsv/mnee.d.ts +88 -0
  12. package/dist/bsv/mnee.d.ts.map +1 -0
  13. package/dist/bsv/mnee.js +173 -0
  14. package/dist/bsv/mnee.js.map +1 -0
  15. package/dist/bsv/opreturn.d.ts +22 -0
  16. package/dist/bsv/opreturn.d.ts.map +1 -0
  17. package/dist/bsv/opreturn.js +117 -0
  18. package/dist/bsv/opreturn.js.map +1 -0
  19. package/dist/bsv/whatsonchain.d.ts +46 -0
  20. package/dist/bsv/whatsonchain.d.ts.map +1 -0
  21. package/dist/bsv/whatsonchain.js +98 -0
  22. package/dist/bsv/whatsonchain.js.map +1 -0
  23. package/dist/config.d.ts +38 -0
  24. package/dist/config.d.ts.map +1 -0
  25. package/dist/config.js +85 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/currency/currency.d.ts +70 -0
  28. package/dist/currency/currency.d.ts.map +1 -0
  29. package/dist/currency/currency.js +137 -0
  30. package/dist/currency/currency.js.map +1 -0
  31. package/dist/disputes/dispute.d.ts +50 -0
  32. package/dist/disputes/dispute.d.ts.map +1 -0
  33. package/dist/disputes/dispute.js +162 -0
  34. package/dist/disputes/dispute.js.map +1 -0
  35. package/dist/docs/openapi.yaml +1079 -0
  36. package/dist/docs/swagger.d.ts +12 -0
  37. package/dist/docs/swagger.d.ts.map +1 -0
  38. package/dist/docs/swagger.js +104 -0
  39. package/dist/docs/swagger.js.map +1 -0
  40. package/dist/middleware/auth.d.ts +20 -0
  41. package/dist/middleware/auth.d.ts.map +1 -0
  42. package/dist/middleware/auth.js +32 -0
  43. package/dist/middleware/auth.js.map +1 -0
  44. package/dist/middleware/rateLimit.d.ts +25 -0
  45. package/dist/middleware/rateLimit.d.ts.map +1 -0
  46. package/dist/middleware/rateLimit.js +61 -0
  47. package/dist/middleware/rateLimit.js.map +1 -0
  48. package/dist/payment/payment.d.ts +79 -9
  49. package/dist/payment/payment.d.ts.map +1 -1
  50. package/dist/payment/payment.js +387 -47
  51. package/dist/payment/payment.js.map +1 -1
  52. package/dist/registry/db.d.ts.map +1 -1
  53. package/dist/registry/db.js +110 -3
  54. package/dist/registry/db.js.map +1 -1
  55. package/dist/registry/registry.d.ts +1 -1
  56. package/dist/registry/registry.d.ts.map +1 -1
  57. package/dist/registry/registry.js +12 -4
  58. package/dist/registry/registry.js.map +1 -1
  59. package/dist/types/index.d.ts +34 -0
  60. package/dist/types/index.d.ts.map +1 -1
  61. package/dist/types/index.js.map +1 -1
  62. package/dist/utils/validation.d.ts +27 -0
  63. package/dist/utils/validation.d.ts.map +1 -0
  64. package/dist/utils/validation.js +164 -0
  65. package/dist/utils/validation.js.map +1 -0
  66. package/dist/verification/receipt.d.ts +42 -0
  67. package/dist/verification/receipt.d.ts.map +1 -0
  68. package/dist/verification/receipt.js +10 -0
  69. package/dist/verification/receipt.js.map +1 -0
  70. package/dist/verification/verification.d.ts +41 -0
  71. package/dist/verification/verification.d.ts.map +1 -0
  72. package/dist/verification/verification.js +217 -0
  73. package/dist/verification/verification.js.map +1 -0
  74. package/dist/wallet/providerManager.d.ts +32 -0
  75. package/dist/wallet/providerManager.d.ts.map +1 -0
  76. package/dist/wallet/providerManager.js +118 -0
  77. package/dist/wallet/providerManager.js.map +1 -0
  78. package/dist/wallet/providers/handcash.d.ts +22 -0
  79. package/dist/wallet/providers/handcash.d.ts.map +1 -0
  80. package/dist/wallet/providers/handcash.js +214 -0
  81. package/dist/wallet/providers/handcash.js.map +1 -0
  82. package/dist/wallet/providers/internal.d.ts +15 -0
  83. package/dist/wallet/providers/internal.d.ts.map +1 -0
  84. package/dist/wallet/providers/internal.js +208 -0
  85. package/dist/wallet/providers/internal.js.map +1 -0
  86. package/dist/wallet/providers/types.d.ts +50 -0
  87. package/dist/wallet/providers/types.d.ts.map +1 -0
  88. package/dist/wallet/providers/types.js +6 -0
  89. package/dist/wallet/providers/types.js.map +1 -0
  90. package/dist/wallet/providers/yours.d.ts +18 -0
  91. package/dist/wallet/providers/yours.d.ts.map +1 -0
  92. package/dist/wallet/providers/yours.js +122 -0
  93. package/dist/wallet/providers/yours.js.map +1 -0
  94. package/dist/wallet/wallet.d.ts +52 -5
  95. package/dist/wallet/wallet.d.ts.map +1 -1
  96. package/dist/wallet/wallet.js +223 -34
  97. package/dist/wallet/wallet.js.map +1 -1
  98. package/dist/webhooks/delivery.d.ts +37 -0
  99. package/dist/webhooks/delivery.d.ts.map +1 -0
  100. package/dist/webhooks/delivery.js +182 -0
  101. package/dist/webhooks/delivery.js.map +1 -0
  102. package/dist/webhooks/webhook.d.ts +85 -0
  103. package/dist/webhooks/webhook.d.ts.map +1 -0
  104. package/dist/webhooks/webhook.js +271 -0
  105. package/dist/webhooks/webhook.js.map +1 -0
  106. package/package.json +74 -54
  107. package/sdk-python/LICENSE +21 -0
  108. package/sdk-python/MANIFEST.in +9 -0
  109. package/sdk-python/README.md +372 -0
  110. package/sdk-python/agentspay/__init__.py +97 -0
  111. package/sdk-python/agentspay/client.py +256 -0
  112. package/sdk-python/agentspay/disputes.py +174 -0
  113. package/sdk-python/agentspay/exceptions.py +53 -0
  114. package/sdk-python/agentspay/payments.py +169 -0
  115. package/sdk-python/agentspay/services.py +198 -0
  116. package/sdk-python/agentspay/types.py +154 -0
  117. package/sdk-python/agentspay/wallet.py +113 -0
  118. package/sdk-python/agentspay/webhooks.py +195 -0
  119. package/sdk-python/examples/consumer.py +147 -0
  120. package/sdk-python/examples/provider.py +116 -0
  121. package/sdk-python/pyproject.toml +61 -0
  122. package/sdk-python/setup.py +53 -0
  123. package/sdk-python/tests/test_client.py +221 -0
  124. package/test-addr.js +29 -0
  125. package/test-mnee-simple.js +51 -0
  126. package/test-mnee.js +47 -0
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ AgentPay Consumer Example
4
+
5
+ This example shows how to:
6
+ 1. Create a wallet
7
+ 2. Search for services
8
+ 3. Execute a service
9
+ 4. Handle disputes if needed
10
+ """
11
+
12
+ from agentspay import AgentPayClient
13
+ import json
14
+
15
+ # Initialize client
16
+ client = AgentPayClient(
17
+ base_url="http://localhost:3100",
18
+ # api_key="your-api-key" # Optional API key
19
+ )
20
+
21
+ # Step 1: Create a wallet (or use existing one)
22
+ print("Creating wallet...")
23
+ wallet = client.create_wallet()
24
+ print(f"โœ“ Wallet created: {wallet.id}")
25
+ print(f" Address: {wallet.address}")
26
+
27
+ # Check balance
28
+ balance_bsv = client.get_balance(wallet.id, currency="BSV")
29
+ balance_mnee = client.get_balance(wallet.id, currency="MNEE")
30
+ print(f" Balance: {balance_bsv} satoshis (BSV), {balance_mnee} cents (MNEE)")
31
+
32
+ # Step 2: Search for services
33
+ print("\n" + "="*60)
34
+ print("Searching for NLP services...")
35
+ print("="*60)
36
+
37
+ services = client.search_services(
38
+ keyword="nlp",
39
+ category="nlp",
40
+ max_price=5000, # Max 5000 satoshis
41
+ limit=5
42
+ )
43
+
44
+ if not services:
45
+ print("No services found. Make sure there are registered services.")
46
+ exit(1)
47
+
48
+ print(f"\nFound {len(services)} services:\n")
49
+ for i, service in enumerate(services, 1):
50
+ print(f"{i}. {service.name}")
51
+ print(f" Description: {service.description}")
52
+ print(f" Price: {service.price} satoshis ({service.currency})")
53
+ print(f" Category: {service.category}")
54
+ print(f" Provider: {service.agent_id}")
55
+
56
+ # Check provider reputation
57
+ try:
58
+ reputation = client.get_reputation(service.agent_id)
59
+ print(f" Rating: {reputation.rating}/5 ({reputation.total_jobs} jobs, "
60
+ f"{reputation.success_rate * 100:.1f}% success)")
61
+ except:
62
+ print(f" Rating: No reputation data")
63
+ print()
64
+
65
+ # Step 3: Execute a service
66
+ print("="*60)
67
+ print("Executing the first service...")
68
+ print("="*60)
69
+
70
+ selected_service = services[0]
71
+ print(f"\nService: {selected_service.name}")
72
+ print(f"Price: {selected_service.price} satoshis")
73
+
74
+ # Execute with input data
75
+ try:
76
+ result = client.execute(
77
+ service_id=selected_service.id,
78
+ buyer_wallet_id=wallet.id,
79
+ input_data={
80
+ "text": "AgentPay is a decentralized marketplace for AI agent services. "
81
+ "It enables autonomous agents to discover, execute, and pay for "
82
+ "services using Bitcoin SV."
83
+ }
84
+ )
85
+
86
+ print(f"\nโœ“ Execution successful!")
87
+ print(f" Payment ID: {result.payment_id}")
88
+ print(f" Execution Time: {result.execution_time_ms}ms")
89
+ print(f" Status: {result.status}")
90
+
91
+ # Show output
92
+ print(f"\n Output:")
93
+ print(json.dumps(result.output, indent=4))
94
+
95
+ # Show receipt (cryptographic proof)
96
+ if result.receipt:
97
+ print(f"\n Receipt ID: {result.receipt.id}")
98
+ print(f" Input Hash: {result.receipt.input_hash}")
99
+ print(f" Output Hash: {result.receipt.output_hash}")
100
+ print(f" Receipt Hash: {result.receipt.receipt_hash}")
101
+ print(f" Provider Signature: {result.receipt.provider_signature[:32]}...")
102
+
103
+ # Show payment details
104
+ if result.payment:
105
+ payment = result.payment
106
+ print(f"\n Payment Status: {payment.status}")
107
+ print(f" Amount: {payment.amount} satoshis")
108
+ print(f" Platform Fee: {payment.platform_fee} satoshis")
109
+ if payment.tx_id:
110
+ print(f" Transaction ID: {payment.tx_id}")
111
+
112
+ except Exception as e:
113
+ print(f"\nโœ— Execution failed: {e}")
114
+ exit(1)
115
+
116
+ # Step 4: Example of opening a dispute (if needed)
117
+ print("\n" + "="*60)
118
+ print("Dispute Example (not executing, just showing API)")
119
+ print("="*60)
120
+ print("""
121
+ # If the output is not satisfactory, you can open a dispute:
122
+
123
+ dispute = client.open_dispute(
124
+ payment_id=result.payment_id,
125
+ reason="Output quality does not meet expectations",
126
+ evidence="Expected sentiment analysis but got only keywords. "
127
+ "Screenshots: https://imgur.com/abc123"
128
+ )
129
+
130
+ # Add more evidence later if needed
131
+ client.add_dispute_evidence(
132
+ dispute_id=dispute.id,
133
+ evidence="Additional evidence: server logs showing incorrect processing"
134
+ )
135
+
136
+ # Check dispute status
137
+ dispute_status = client.get_dispute(dispute.id)
138
+ print(f"Dispute status: {dispute_status.status}")
139
+ print(f"Resolution: {dispute_status.resolution}")
140
+ """)
141
+
142
+ print("\n" + "="*60)
143
+ print("Transaction Complete!")
144
+ print("="*60)
145
+ print(f"\nPayment ID: {result.payment_id}")
146
+ print("You can use this payment ID to track the transaction,")
147
+ print("open disputes, or retrieve the receipt at any time.")
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ AgentPay Provider Example
4
+
5
+ This example shows how to:
6
+ 1. Create a wallet
7
+ 2. Register a service
8
+ 3. Handle incoming execution requests (conceptual)
9
+ """
10
+
11
+ from agentspay import AgentPayClient
12
+
13
+ # Initialize client
14
+ client = AgentPayClient(
15
+ base_url="http://localhost:3100",
16
+ # api_key="your-api-key" # Optional API key
17
+ )
18
+
19
+ # Step 1: Create a wallet for your agent
20
+ print("Creating wallet...")
21
+ wallet = client.create_wallet()
22
+ print(f"โœ“ Wallet created: {wallet.id}")
23
+ print(f" Address: {wallet.address}")
24
+ print(f" Public Key: {wallet.public_key}")
25
+
26
+ # Step 2: Register a service
27
+ print("\nRegistering service...")
28
+ service = client.register_service(
29
+ agent_id=wallet.id,
30
+ name="TextAnalyzer",
31
+ description="Advanced NLP text analysis service",
32
+ price=1000, # 1000 satoshis per execution
33
+ currency="BSV", # or "MNEE"
34
+ endpoint="https://my-agent.com/api/analyze",
35
+ category="nlp",
36
+ method="POST",
37
+ timeout=30, # 30 seconds max execution time
38
+ dispute_window=30, # 30 minutes dispute window
39
+ input_schema={
40
+ "type": "object",
41
+ "properties": {
42
+ "text": {"type": "string"}
43
+ },
44
+ "required": ["text"]
45
+ }
46
+ )
47
+
48
+ print(f"โœ“ Service registered: {service.id}")
49
+ print(f" Name: {service.name}")
50
+ print(f" Price: {service.price} satoshis")
51
+ print(f" Category: {service.category}")
52
+ print(f" Endpoint: {service.endpoint}")
53
+
54
+ # Step 3: Check reputation (if you have previous transactions)
55
+ try:
56
+ reputation = client.get_reputation(wallet.id)
57
+ print(f"\nReputation:")
58
+ print(f" Rating: {reputation.rating}/5")
59
+ print(f" Success Rate: {reputation.success_rate * 100:.1f}%")
60
+ print(f" Total Jobs: {reputation.total_jobs}")
61
+ except Exception as e:
62
+ print(f"\nNo reputation data yet: {e}")
63
+
64
+ # Step 4: Set up webhook to receive notifications
65
+ print("\nRegistering webhook...")
66
+ try:
67
+ webhook = client.register_webhook(
68
+ url="https://my-agent.com/webhooks/agentpay",
69
+ events=[
70
+ "payment.escrowed", # When payment is held in escrow
71
+ "payment.released", # When payment is released to you
72
+ "dispute.opened", # When a dispute is opened
73
+ "service.executed" # When your service is executed
74
+ ]
75
+ )
76
+ print(f"โœ“ Webhook registered: {webhook.id}")
77
+ print(f" URL: {webhook.url}")
78
+ print(f" Events: {', '.join(webhook.events)}")
79
+ except Exception as e:
80
+ print(f"โœ— Webhook registration failed: {e}")
81
+
82
+ print("\n" + "="*60)
83
+ print("Your service is now live on AgentPay!")
84
+ print("="*60)
85
+ print(f"\nService ID: {service.id}")
86
+ print(f"Wallet ID: {wallet.id}")
87
+ print("\nConsumers can now discover and execute your service.")
88
+ print("Make sure your endpoint is accessible and handles POST requests.")
89
+
90
+ # Example: What your endpoint should implement
91
+ print("\n" + "-"*60)
92
+ print("Your service endpoint should implement:")
93
+ print("-"*60)
94
+ print("""
95
+ POST /api/analyze
96
+ Content-Type: application/json
97
+
98
+ {
99
+ "executionId": "exec_123...",
100
+ "paymentId": "pay_456...",
101
+ "input": {
102
+ "text": "Sample text to analyze"
103
+ }
104
+ }
105
+
106
+ Response:
107
+ {
108
+ "status": "success",
109
+ "output": {
110
+ "sentiment": "positive",
111
+ "keywords": ["sample", "text", "analyze"],
112
+ "language": "en"
113
+ },
114
+ "executionTimeMs": 245
115
+ }
116
+ """)
@@ -0,0 +1,61 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "agentspay"
7
+ version = "0.2.0"
8
+ description = "Python SDK for AgentPay - AI agent service marketplace with cryptocurrency payments"
9
+ readme = "README.md"
10
+ authors = [
11
+ {name = "AgentsPay", email = "contact@agentspay.io"}
12
+ ]
13
+ license = {text = "MIT"}
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.8",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Software Development :: Libraries :: Python Modules",
25
+ "Topic :: Internet :: WWW/HTTP",
26
+ "Topic :: Office/Business :: Financial",
27
+ ]
28
+ keywords = ["agentpay", "ai", "agents", "cryptocurrency", "bsv", "bitcoin", "payments", "marketplace"]
29
+ requires-python = ">=3.8"
30
+ dependencies = [
31
+ "requests>=2.28.0",
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ dev = [
36
+ "pytest>=7.0.0",
37
+ "pytest-cov>=4.0.0",
38
+ "black>=23.0.0",
39
+ "mypy>=1.0.0",
40
+ "ruff>=0.0.260",
41
+ ]
42
+
43
+ [project.urls]
44
+ Homepage = "https://github.com/agentspay/agentspay"
45
+ Documentation = "https://docs.agentspay.io"
46
+ Repository = "https://github.com/agentspay/agentspay"
47
+ Issues = "https://github.com/agentspay/agentspay/issues"
48
+
49
+ [tool.setuptools.packages.find]
50
+ where = ["."]
51
+ include = ["agentspay*"]
52
+
53
+ [tool.black]
54
+ line-length = 100
55
+ target-version = ['py38', 'py39', 'py310', 'py311']
56
+
57
+ [tool.mypy]
58
+ python_version = "3.8"
59
+ warn_return_any = true
60
+ warn_unused_configs = true
61
+ disallow_untyped_defs = false
@@ -0,0 +1,53 @@
1
+ """Setup script for agentspay package"""
2
+
3
+ from setuptools import setup, find_packages
4
+
5
+ # Read the long description from README.md
6
+ with open("README.md", "r", encoding="utf-8") as fh:
7
+ long_description = fh.read()
8
+
9
+ setup(
10
+ name="agentspay",
11
+ version="0.2.0",
12
+ author="AgentsPay",
13
+ author_email="contact@agentspay.io",
14
+ description="Python SDK for AgentPay - AI agent service marketplace with cryptocurrency payments",
15
+ long_description=long_description,
16
+ long_description_content_type="text/markdown",
17
+ url="https://github.com/agentspay/agentspay",
18
+ project_urls={
19
+ "Bug Tracker": "https://github.com/agentspay/agentspay/issues",
20
+ "Documentation": "https://docs.agentspay.io",
21
+ "Source Code": "https://github.com/agentspay/agentspay",
22
+ },
23
+ packages=find_packages(exclude=["tests", "tests.*", "examples", "examples.*"]),
24
+ classifiers=[
25
+ "Development Status :: 4 - Beta",
26
+ "Intended Audience :: Developers",
27
+ "License :: OSI Approved :: MIT License",
28
+ "Operating System :: OS Independent",
29
+ "Programming Language :: Python :: 3",
30
+ "Programming Language :: Python :: 3.8",
31
+ "Programming Language :: Python :: 3.9",
32
+ "Programming Language :: Python :: 3.10",
33
+ "Programming Language :: Python :: 3.11",
34
+ "Programming Language :: Python :: 3.12",
35
+ "Topic :: Software Development :: Libraries :: Python Modules",
36
+ "Topic :: Internet :: WWW/HTTP",
37
+ "Topic :: Office/Business :: Financial",
38
+ ],
39
+ python_requires=">=3.8",
40
+ install_requires=[
41
+ "requests>=2.28.0",
42
+ ],
43
+ extras_require={
44
+ "dev": [
45
+ "pytest>=7.0.0",
46
+ "pytest-cov>=4.0.0",
47
+ "black>=23.0.0",
48
+ "mypy>=1.0.0",
49
+ "ruff>=0.0.260",
50
+ ],
51
+ },
52
+ keywords="agentpay ai agents cryptocurrency bsv bitcoin payments marketplace",
53
+ )
@@ -0,0 +1,221 @@
1
+ """Tests for AgentPay SDK"""
2
+
3
+ import pytest
4
+ from unittest.mock import Mock, patch
5
+ from agentspay import AgentPayClient
6
+ from agentspay.exceptions import WalletError, ServiceError, ExecutionError
7
+
8
+
9
+ class TestAgentPayClient:
10
+ """Test suite for AgentPayClient"""
11
+
12
+ def test_client_initialization(self):
13
+ """Test client initializes with correct defaults"""
14
+ client = AgentPayClient()
15
+ assert client.base_url == "http://localhost:3100"
16
+ assert client.api_key is None
17
+
18
+ client_with_key = AgentPayClient(
19
+ base_url="https://api.agentspay.io",
20
+ api_key="test-key"
21
+ )
22
+ assert client_with_key.base_url == "https://api.agentspay.io"
23
+ assert client_with_key.api_key == "test-key"
24
+
25
+ @patch('agentspay.wallet.requests.post')
26
+ def test_create_wallet(self, mock_post):
27
+ """Test wallet creation"""
28
+ # Mock API response
29
+ mock_response = Mock()
30
+ mock_response.json.return_value = {
31
+ "wallet": {
32
+ "id": "wallet_123",
33
+ "publicKey": "pub_key_abc",
34
+ "address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
35
+ "createdAt": "2026-02-14T12:00:00Z",
36
+ "balance": 100000,
37
+ "balanceMnee": 5000
38
+ }
39
+ }
40
+ mock_response.raise_for_status = Mock()
41
+ mock_post.return_value = mock_response
42
+
43
+ # Test
44
+ client = AgentPayClient()
45
+ wallet = client.create_wallet()
46
+
47
+ assert wallet.id == "wallet_123"
48
+ assert wallet.public_key == "pub_key_abc"
49
+ assert wallet.address == "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
50
+ assert wallet.balance == 100000
51
+ assert wallet.balance_mnee == 5000
52
+
53
+ @patch('agentspay.wallet.requests.get')
54
+ def test_get_wallet(self, mock_get):
55
+ """Test getting wallet by ID"""
56
+ # Mock API response
57
+ mock_response = Mock()
58
+ mock_response.json.return_value = {
59
+ "wallet": {
60
+ "id": "wallet_123",
61
+ "publicKey": "pub_key_abc",
62
+ "address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
63
+ "createdAt": "2026-02-14T12:00:00Z",
64
+ "balance": 50000
65
+ }
66
+ }
67
+ mock_response.raise_for_status = Mock()
68
+ mock_get.return_value = mock_response
69
+
70
+ # Test
71
+ client = AgentPayClient()
72
+ wallet = client.get_wallet("wallet_123")
73
+
74
+ assert wallet.id == "wallet_123"
75
+ assert wallet.balance == 50000
76
+
77
+ @patch('agentspay.services.requests.post')
78
+ def test_register_service(self, mock_post):
79
+ """Test service registration"""
80
+ # Mock API response
81
+ mock_response = Mock()
82
+ mock_response.json.return_value = {
83
+ "service": {
84
+ "id": "service_456",
85
+ "agentId": "wallet_123",
86
+ "name": "TextAnalyzer",
87
+ "description": "NLP service",
88
+ "category": "nlp",
89
+ "price": 1000,
90
+ "currency": "BSV",
91
+ "endpoint": "https://agent.com/analyze",
92
+ "method": "POST",
93
+ "active": True,
94
+ "timeout": 30,
95
+ "disputeWindow": 30,
96
+ "createdAt": "2026-02-14T12:00:00Z",
97
+ "updatedAt": "2026-02-14T12:00:00Z"
98
+ }
99
+ }
100
+ mock_response.raise_for_status = Mock()
101
+ mock_post.return_value = mock_response
102
+
103
+ # Test
104
+ client = AgentPayClient()
105
+ service = client.register_service(
106
+ agent_id="wallet_123",
107
+ name="TextAnalyzer",
108
+ description="NLP service",
109
+ price=1000,
110
+ currency="BSV",
111
+ endpoint="https://agent.com/analyze",
112
+ category="nlp"
113
+ )
114
+
115
+ assert service.id == "service_456"
116
+ assert service.name == "TextAnalyzer"
117
+ assert service.price == 1000
118
+ assert service.currency == "BSV"
119
+ assert service.active is True
120
+
121
+ @patch('agentspay.services.requests.get')
122
+ def test_search_services(self, mock_get):
123
+ """Test searching for services"""
124
+ # Mock API response
125
+ mock_response = Mock()
126
+ mock_response.json.return_value = {
127
+ "services": [
128
+ {
129
+ "id": "service_1",
130
+ "agentId": "wallet_1",
131
+ "name": "Service 1",
132
+ "description": "Test service",
133
+ "category": "nlp",
134
+ "price": 500,
135
+ "currency": "BSV",
136
+ "endpoint": "https://agent.com/1",
137
+ "method": "POST",
138
+ "active": True,
139
+ "timeout": 30,
140
+ "disputeWindow": 30,
141
+ "createdAt": "2026-02-14T12:00:00Z",
142
+ "updatedAt": "2026-02-14T12:00:00Z"
143
+ }
144
+ ]
145
+ }
146
+ mock_response.raise_for_status = Mock()
147
+ mock_get.return_value = mock_response
148
+
149
+ # Test
150
+ client = AgentPayClient()
151
+ services = client.search_services(keyword="nlp", max_price=1000)
152
+
153
+ assert len(services) == 1
154
+ assert services[0].id == "service_1"
155
+ assert services[0].category == "nlp"
156
+
157
+ @patch('agentspay.payments.requests.post')
158
+ def test_execute_service(self, mock_post):
159
+ """Test service execution"""
160
+ # Mock API response
161
+ mock_response = Mock()
162
+ mock_response.json.return_value = {
163
+ "paymentId": "payment_789",
164
+ "serviceId": "service_456",
165
+ "output": {
166
+ "result": "success",
167
+ "data": "analyzed"
168
+ },
169
+ "executionTimeMs": 250,
170
+ "status": "success"
171
+ }
172
+ mock_response.raise_for_status = Mock()
173
+ mock_post.return_value = mock_response
174
+
175
+ # Test
176
+ client = AgentPayClient()
177
+ result = client.execute(
178
+ service_id="service_456",
179
+ buyer_wallet_id="wallet_123",
180
+ input_data={"text": "Test"}
181
+ )
182
+
183
+ assert result.payment_id == "payment_789"
184
+ assert result.service_id == "service_456"
185
+ assert result.status == "success"
186
+ assert result.execution_time_ms == 250
187
+ assert result.output["result"] == "success"
188
+
189
+
190
+ class TestExceptions:
191
+ """Test SDK exceptions"""
192
+
193
+ @patch('agentspay.wallet.requests.post')
194
+ def test_wallet_error(self, mock_post):
195
+ """Test WalletError is raised on API failure"""
196
+ mock_post.side_effect = Exception("Network error")
197
+
198
+ client = AgentPayClient()
199
+ with pytest.raises(WalletError):
200
+ client.create_wallet()
201
+
202
+ @patch('agentspay.services.requests.post')
203
+ def test_service_error(self, mock_post):
204
+ """Test ServiceError is raised on API failure"""
205
+ mock_post.side_effect = Exception("API error")
206
+
207
+ client = AgentPayClient()
208
+ with pytest.raises(ServiceError):
209
+ client.register_service(
210
+ agent_id="wallet_123",
211
+ name="Test",
212
+ description="Test",
213
+ price=100,
214
+ currency="BSV",
215
+ endpoint="https://test.com",
216
+ category="test"
217
+ )
218
+
219
+
220
+ if __name__ == "__main__":
221
+ pytest.main([__file__, "-v"])
package/test-addr.js ADDED
@@ -0,0 +1,29 @@
1
+ const { PrivateKey, Hash, Utils } = require('@bsv/sdk')
2
+ const crypto = require('crypto')
3
+
4
+ const pk = PrivateKey.fromRandom()
5
+ const pub = pk.toPublicKey()
6
+
7
+ // Mainnet
8
+ console.log('Mainnet:', pub.toAddress())
9
+
10
+ // Testnet - manual P2PKH with 0x6f prefix
11
+ const pubEncoded = pub.encode(true)
12
+ const hash160 = Hash.hash160(pubEncoded)
13
+ const prefix = Uint8Array.from([0x6f])
14
+ const payload = new Uint8Array(prefix.length + hash160.length)
15
+ payload.set(prefix, 0)
16
+ payload.set(hash160, prefix.length)
17
+ const checksum = Hash.hash256(payload).slice(0, 4)
18
+ const full = new Uint8Array(payload.length + checksum.length)
19
+ full.set(payload, 0)
20
+ full.set(checksum, payload.length)
21
+ console.log('Testnet:', Utils.toBase58(full))
22
+ console.log('WIF:', pk.toWif())
23
+
24
+ // Also check toAddress with network param
25
+ try {
26
+ console.log('toAddress testnet:', pub.toAddress('testnet'))
27
+ } catch(e) {
28
+ console.log('toAddress testnet not supported:', e.message)
29
+ }
@@ -0,0 +1,51 @@
1
+ // Simple MNEE test without database
2
+ const { CurrencyManager } = require('./dist/currency/currency')
3
+
4
+ async function test() {
5
+ console.log('๐Ÿงช Testing MNEE Currency Manager\n')
6
+
7
+ console.log('โœ… Currency Configuration:')
8
+ console.log(' BSV:', JSON.stringify(CurrencyManager.getConfig('BSV'), null, 2))
9
+ console.log(' MNEE:', JSON.stringify(CurrencyManager.getConfig('MNEE'), null, 2))
10
+
11
+ console.log('\nโœ… Amount Validation:')
12
+ console.log(' 1000 sats (BSV):', CurrencyManager.validateAmount(1000, 'BSV'))
13
+ console.log(' 150 cents (MNEE):', CurrencyManager.validateAmount(150, 'MNEE'))
14
+ console.log(' -10 cents (MNEE):', CurrencyManager.validateAmount(-10, 'MNEE'))
15
+ console.log(' 0.5 cents (MNEE):', CurrencyManager.validateAmount(0.5, 'MNEE'))
16
+
17
+ console.log('\nโœ… Formatting:')
18
+ console.log(' 50000000 sats โ†’', CurrencyManager.format(50000000, 'BSV'))
19
+ console.log(' 1000 sats โ†’', CurrencyManager.format(1000, 'BSV'))
20
+ console.log(' 150 cents โ†’', CurrencyManager.format(150, 'MNEE'))
21
+ console.log(' 5000 cents โ†’', CurrencyManager.format(5000, 'MNEE'))
22
+ console.log(' 1 cent โ†’', CurrencyManager.format(1, 'MNEE'))
23
+
24
+ console.log('\nโœ… Fee Calculation (2%):')
25
+ console.log(' 10000 sats BSV fee:', CurrencyManager.calculateFee(10000, 'BSV'), 'sats')
26
+ console.log(' 1000 cents MNEE fee:', CurrencyManager.calculateFee(1000, 'MNEE'), 'cents ($0.20)')
27
+ console.log(' 100 cents MNEE fee:', CurrencyManager.calculateFee(100, 'MNEE'), 'cents ($0.02)')
28
+ console.log(' 10 cents MNEE fee:', CurrencyManager.calculateFee(10, 'MNEE'), 'cents (min 1 cent)')
29
+
30
+ console.log('\nโœ… Parsing:')
31
+ console.log(' "1.50 MNEE" โ†’', CurrencyManager.parse('1.50 MNEE', 'MNEE'), 'cents')
32
+ console.log(' "0.00001 BSV" โ†’', CurrencyManager.parse('0.00001 BSV', 'BSV'), 'sats')
33
+ console.log(' "100.00" MNEE โ†’', CurrencyManager.parse('100.00', 'MNEE'), 'cents')
34
+
35
+ console.log('\nโœ… Conversion Rates:')
36
+ const bsvToMnee = await CurrencyManager.getConversionRate('BSV', 'MNEE')
37
+ const mneeToBsv = await CurrencyManager.getConversionRate('MNEE', 'BSV')
38
+ console.log(' 1 sat =', bsvToMnee.rate.toFixed(6), 'MNEE cents')
39
+ console.log(' 1 MNEE cent =', mneeToBsv.rate.toFixed(2), 'sats')
40
+ console.log(' Source:', bsvToMnee.source)
41
+
42
+ console.log('\nโœ… Conversion Examples:')
43
+ const satsToCents = await CurrencyManager.convert(10000, 'BSV', 'MNEE')
44
+ console.log(' 10000 sats โ‰ˆ', satsToCents, 'cents ($' + (satsToCents/100).toFixed(2) + ')')
45
+ const centsToSats = await CurrencyManager.convert(100, 'MNEE', 'BSV')
46
+ console.log(' 100 cents ($1) โ‰ˆ', centsToSats, 'sats')
47
+
48
+ console.log('\n๐ŸŽ‰ All currency manager tests passed!')
49
+ }
50
+
51
+ test().catch(console.error)