paybot-sdk (Python port)
Python port of paybot-sdk. Mirror of the TypeScript SDK in ../../src/.
Status: runtime (0.1.0). Type surface, network config, HTTP transport, all client REST methods, EIP-3009 signing (
PayBotClient.pay()real-mode path), and webhook signature verification are implemented and tested. The signed payload and the webhook signature are byte-for-byte compatible with the TS SDK.
Install
pip install paybot-sdk
Or with the signing extras (required for pay() in real mode):
pip install paybot-sdk[signing]
Quick start (mock mode)
import asyncio
from paybot_sdk import PayBotClient, PayBotConfig, PaymentRequest
async def main():
client = PayBotClient(PayBotConfig(
api_key="pb_test_...",
bot_id="my-bot",
))
await client.register()
balance = await client.balance()
print(balance)
asyncio.run(main())
What's implemented
| File | Mirror of TS | Status |
|---|---|---|
paybot_sdk/types.py |
src/types.ts |
✅ Full type surface as @dataclass |
paybot_sdk/networks.py |
src/networks.ts |
✅ Full (chain IDs, USDC addresses, EIP-712 domains, EIP-3009 types) |
paybot_sdk/errors.py |
src/errors.ts |
✅ Full (PayBotApiError, get_error_message) |
paybot_sdk/crypto.py |
src/crypto.ts |
✅ Full (generate_eip3009_nonce via secrets.token_hex) |
paybot_sdk/client.py |
src/client.ts |
✅ Full — all REST methods + real-mode EIP-3009 signing in _sign_payload() |
paybot_sdk/webhook.py |
src/webhook.ts |
✅ Full (verify_webhook_signature, HMAC-SHA256, replay guard) |
paybot_sdk/__init__.py |
src/index.ts |
✅ Full exports |
paybot_sdk/middleware.py |
src/middleware.ts |
❌ Not yet ported |
paybot_sdk/x402_handler.py |
src/x402-handler.ts |
❌ Not yet ported |
Working today:
register(), balance(), history(), set_limits(), health(),
commission_summary(), commission_ledger(), create_api_key(),
list_api_keys(), revoke_api_key(), real-mode pay() (EIP-3009 signing),
and verify_webhook_signature(). Mock mode (no wallet_private_key) and real
mode both mirror the TS SDK wire contract.
Not yet ported:
middleware.pyx402_handler.py
Webhook verification
from paybot_sdk import verify_webhook_signature
ok = verify_webhook_signature(
payload=request_body, # str or bytes — the raw body
signature=headers["Paybot-Signature"], # "t=<unix_ts>,v1=<hex>"
secret="whsec_...",
tolerance=300, # replay window in seconds
)
The signing string is f"{t}.{payload}" and the header format is
t=<unix_ts>,v1=<hmac_sha256_hex>, identical to the TS
verifyWebhookSignature, so a server-signed webhook verifies in either runtime.
Notes
- Snake-case naming. TS uses
botId,walletPrivateKey. Python convention isbot_id,wallet_private_key. Wire format on the HTTP boundary is still camelCase (matches the TS server contract). Worth confirming this is the right boundary placement. PayBotConfigas dataclass vs. kwargs. CurrentlyPayBotConfigis a dataclass that gets passed in. Could also exposePayBotClient(api_key=..., bot_id=...)directly. Open to either; let me know which matches the SDK's intended ergonomics.- Async-first vs. sync wrapper. Right now everything is
async def. The TS SDK is also async-first (promise-based). If the consumer use cases include sync agents (LangChain old-style), a thinpaybot_sdk.syncwrapper is easy to add. Worth deciding now so the public API doesn't drift. _to_base_units. String-based conversion to avoid float drift. Matches the TS path; worth verifying no precision corner cases I missed.
Test plan
cd packages/python
pip install -e ".[signing,test]"
pytest
The test suite (in tests/) covers:
- Type surface (every dataclass constructable from valid inputs)
PayBotClient.__init__validation (api_key required, bot_id required, facilitator_url URL, wallet_private_key 0x-prefix)_to_base_unitscorner cases (zero, no decimal, exact decimal, more decimals than scale)generate_eip3009_nonceshape (0x-prefixed, 66 chars)NETWORKSparity withsrc/networks.ts(chain IDs, USDC addresses)- EIP-3009 signing (
test_signing.py): TS wire shape, signer-address recovery round-trip, unsupported-network + missing-key errors, deterministic-given-nonce structure - Real-mode
pay()verify→settle flow (respx-mocked HTTP) - Webhook verification (
test_webhook.py): valid/tampered/expired/future/malformed-header cases + thef"{t}.{payload}"cross-language signing contract
Metadata
Release files for paybot-sdk 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| paybot_sdk-0.2.0.tar.gz | 73.0 kB | Without provenance | Details for paybot_sdk-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| paybot_sdk-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for paybot_sdk-0.2.0-py3-none-any.whl |
Total release size: 125.5 kB
Release files / paybot_sdk-0.2.0.tar.gz
| Download URL | paybot_sdk-0.2.0.tar.gz |
|---|---|
| Size | 73.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2d37101b6679c1c360e0879e7409e709ccd8bcc2f1ddea4d9d76f8fb53a0d47f
|
|
BLAKE2b-256 checksum How to use checksums |
45a639564030dc0fc71c359519beae0c05c7f3d61b32819b97cfeaae59519181
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Release files / paybot_sdk-0.2.0-py3-none-any.whl
| Download URL | paybot_sdk-0.2.0-py3-none-any.whl |
|---|---|
| Size | 52.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ef051b7b774dd5ecb767302b6d66dc96d865e571c3e43d9ff2955c37e4412fa9
|
|
BLAKE2b-256 checksum How to use checksums |
985af3f9eff2528c04ebd1504be56731a52cbd772157f894d4fc8bb104d9e764
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Security for paybot-sdk 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.