paynode-sdk-python 2.2.0__py3-none-any.whl → 2.2.1__py3-none-any.whl

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.
paynode_sdk/client.py CHANGED
@@ -17,7 +17,7 @@ logger = logging.getLogger("paynode_sdk.client")
17
17
 
18
18
  class PayNodeAgentClient:
19
19
  """
20
- The main PayNode Client for AI Agents (v2.2.0).
20
+ The main PayNode Client for AI Agents (v2.2.1).
21
21
  Automatically handles the x402 'Payment Required' handshake.
22
22
  Supports RPC redundancy, EIP-2612 Permit, and EIP-3009 Authorization.
23
23
  """
@@ -111,12 +111,19 @@ class PayNodeAgentClient:
111
111
  except Exception as e:
112
112
  logger.debug(f"⚠️ [PayNode-PY] Failed to parse 402 JSON body: {e}")
113
113
 
114
- if not body and b64_required:
114
+ header_body = None
115
+ if b64_required:
115
116
  try:
116
- body = json.loads(base64.b64decode(b64_required).decode())
117
+ header_body = json.loads(base64.b64decode(b64_required).decode())
117
118
  except Exception as e:
118
119
  logger.warning(f"❌ [PayNode-PY] Failed to decode PAYMENT-REQUIRED header: {e}")
119
120
 
121
+ if not body and header_body:
122
+ body = header_body
123
+ elif body and header_body and not body.get('x402Version'):
124
+ # Robustness: Merge header info into body if body is missing critical bits
125
+ body.update({k: v for k, v in header_body.items() if k not in body})
126
+
120
127
  if body and body.get('x402Version') == 2:
121
128
  logger.info("🚀 [PayNode-PY] x402 v2 detected. Handling autonomous payment...")
122
129
  if order_id and not body.get('orderId'): body['orderId'] = order_id
@@ -217,7 +224,7 @@ class PayNodeAgentClient:
217
224
  },
218
225
  "payload": payload_data,
219
226
  "_paynode": {
220
- "version": "2.2.0",
227
+ "version": "2.2.1",
221
228
  "type": ptype,
222
229
  "orderId": order_id
223
230
  }
@@ -248,7 +255,12 @@ class PayNodeAgentClient:
248
255
  settle_header = response.headers.get('PAYMENT-RESPONSE') or response.headers.get('X-PAYMENT-RESPONSE')
249
256
  if settle_header:
250
257
  try:
251
- settle_data = json.loads(base64.b64decode(settle_header).decode())
258
+ settle_header_str = settle_header.strip()
259
+ if settle_header_str.startswith('{'):
260
+ decoded = settle_header_str
261
+ else:
262
+ decoded = base64.b64decode(settle_header).decode()
263
+ settle_data = json.loads(decoded)
252
264
  if settle_data.get('success'):
253
265
  logger.info(f"✅ [PayNode-PY] Settlement confirmed: {settle_data.get('transaction')}")
254
266
  else:
paynode_sdk/middleware.py CHANGED
@@ -88,14 +88,14 @@ class PayNodeMiddleware(BaseHTTPMiddleware):
88
88
  p_type = parsed.get('_paynode', {}).get('type') or inferred_type
89
89
 
90
90
  unified_payload = {
91
- "version": "2.2.0",
91
+ "version": "2.2.1",
92
92
  "type": p_type,
93
93
  "orderId": internal_order_id,
94
94
  "router": parsed.get('accepted', {}).get('router'),
95
95
  "payload": parsed.get('payload')
96
96
  }
97
97
  order_id = internal_order_id
98
- elif parsed.get('version') == "2.2.0":
98
+ elif isinstance(parsed.get('version'), str) and parsed.get('version').startswith(("2.3", "2.2")):
99
99
  # Legacy PayNode format
100
100
  unified_payload = parsed
101
101
  if 'orderId' in unified_payload:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: paynode-sdk-python
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: PayNode Protocol Python SDK for AI Agents
5
5
  Author-email: PayNodeLabs <contact@paynode.dev>
6
6
  License: MIT
@@ -25,7 +25,7 @@ Dynamic: license-file
25
25
  [![Official Documentation](https://img.shields.io/badge/Docs-docs.paynode.dev-00ff88?style=for-the-badge&logo=readthedocs)](https://docs.paynode.dev)
26
26
  [![PyPI Version](https://img.shields.io/pypi/v/paynode-sdk-python.svg?style=for-the-badge)](https://pypi.org/project/paynode-sdk-python/)
27
27
 
28
- The official Python SDK for the **PayNode Protocol (v2.2.0)**. PayNode allows autonomous AI Agents to seamlessly pay for APIs and computational resources using USDC on Base L2, utilizing the standardized HTTP 402 protocol with support for both on-chain receipts and off-chain signatures (EIP-3009).
28
+ The official Python SDK for the **PayNode Protocol (v2.2.1)**. PayNode allows autonomous AI Agents to seamlessly pay for APIs and computational resources using USDC on Base L2, utilizing the standardized HTTP 402 protocol with support for both on-chain receipts and off-chain signatures (EIP-3009).
29
29
 
30
30
  ## 📖 Read the Docs
31
31
 
@@ -56,7 +56,7 @@ response = agent.request_gate("https://api.merchant.com/premium-data", method="P
56
56
  print(response.json())
57
57
  ```
58
58
 
59
- ### Key Features (v2.2.0)
59
+ ### Key Features (v2.2.1)
60
60
  - **EIP-3009 Support**: Sign payments off-chain using `TransferWithAuthorization`, allowing for gasless or relayer-mediated settlement.
61
61
  - **X402 V2 Protocol**: JSON-based handshake for more structured and machine-readable payment instructions.
62
62
  - **Dual Flow**: Automatic fallback to V1 (on-chain receipts) for legacy merchant support.
@@ -1,13 +1,13 @@
1
1
  paynode_sdk/__init__.py,sha256=dDP3qUvuhpyeUcCRRIeaHMifaYPE_p6IwZjcmaHgAHU,1187
2
- paynode_sdk/client.py,sha256=QMCm7y0bltBqToZvHl5VRjEmF7rlpF9SWpa1Wei5WHg,19543
2
+ paynode_sdk/client.py,sha256=ZL-Q67OjbnAnyUaGwd_IrScsHYfkVVdPccbRXL4xL04,20136
3
3
  paynode_sdk/constants.py,sha256=MaFiVkzD7pahM9Wn29Qgb9i5hvOafKpndJ8U4QylpWA,6346
4
4
  paynode_sdk/errors.py,sha256=dpPXm-e0dHKOYkY87-DCB5LBf79hqPwUAaz9JmTomms,1965
5
5
  paynode_sdk/idempotency.py,sha256=IOdyv8STj97EDGlwpGQnGE7K_NHRMmULvLTNTaglnB8,2450
6
- paynode_sdk/middleware.py,sha256=plyoRmPft0r2WPuKyewYLW2V9HonhsHMTiDC7_ZYy3s,9604
6
+ paynode_sdk/middleware.py,sha256=HkZoo3H4zpUCPw7uE6cCt4b9Zx_A1d7g3h7pYyLBx88,9663
7
7
  paynode_sdk/verifier.py,sha256=AKy-OVwVKhShisycIywglHYgMBX1hhXFuj2zitK1EAE,14974
8
8
  paynode_sdk/webhook.py,sha256=ngP0Az_-20gPVeHPzeaXuy1_AK1TTqqsmP-HCpAWEEM,8317
9
- paynode_sdk_python-2.2.0.dist-info/licenses/LICENSE,sha256=U8RjGlEBtXN6PA-qN_N3Uh60jyu3qe26ZBmgt-LAHc4,1069
10
- paynode_sdk_python-2.2.0.dist-info/METADATA,sha256=_n_jc3qWb3ZjKtA3dRUwzDNtsSqzhrLwaF58WIZKMHo,3835
11
- paynode_sdk_python-2.2.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
12
- paynode_sdk_python-2.2.0.dist-info/top_level.txt,sha256=c6Skc1Xx-9O-JJ7sHghLW8Kyn4hyJoVPUawH1Mu8iTU,12
13
- paynode_sdk_python-2.2.0.dist-info/RECORD,,
9
+ paynode_sdk_python-2.2.1.dist-info/licenses/LICENSE,sha256=U8RjGlEBtXN6PA-qN_N3Uh60jyu3qe26ZBmgt-LAHc4,1069
10
+ paynode_sdk_python-2.2.1.dist-info/METADATA,sha256=LThVm20jSReaQ4BHbYyh_spVZEGsbKFcwnxmZBnAjkQ,3835
11
+ paynode_sdk_python-2.2.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
12
+ paynode_sdk_python-2.2.1.dist-info/top_level.txt,sha256=c6Skc1Xx-9O-JJ7sHghLW8Kyn4hyJoVPUawH1Mu8iTU,12
13
+ paynode_sdk_python-2.2.1.dist-info/RECORD,,