A Python SDK for wallet transfers through the Payelink Payment API. This SDK provides a simple and intuitive interface for transferring funds between wallets.
- Simple and intuitive API
- Synchronous and asynchronous support
- Type-safe with Pydantic models
- Automatic retry logic with exponential backoff
- HTTP client (httpx)
- Comprehensive error handling
- Payment-specific error types
- Wallet transfer functionality
pip install payelink-agent-payOr using uv:
uv add payelink-agent-payCreate a .env file in your project root:
PAYELINK_KEY=your-api-key-hereThen initialize the client without providing the API key:
from payelink_agent_pay import PaymentClient, WalletTransferRequest
# Initialize the client (API key loaded from PAYELINK_KEY in .env)
client = PaymentClient()
# Transfer funds between wallets
transfer_request = WalletTransferRequest(
from_wallet_key="wal_yZnDhmBMxx4",
to_wallet_key="wal_tPS-Nxnh-hc",
value="12",
)
# Execute the transfer
transfer = client.wallet_transfer(transfer_request)
print(f"Transfer successful: {transfer.success}")
print(f"Transaction Hash: {transfer.data.transaction_hash}")
print(f"Chain: {transfer.data.chain}")
print(f"Network: {transfer.data.network}")from payelink_agent_pay import PaymentClient, WalletTransferRequest
# Initialize the client with explicit API key
client = PaymentClient(api_key="your-api-key")
# Transfer funds between wallets
transfer_request = WalletTransferRequest(
from_wallet_key="wal_yZnDhmBMxx4",
to_wallet_key="wal_tPS-Nxnh-hc",
value="12",
)
# Execute the transfer
transfer = client.wallet_transfer(transfer_request)
print(f"Transfer successful: {transfer.success}")
print(f"Transaction Hash: {transfer.data.transaction_hash}")
print(f"Chain: {transfer.data.chain}")
print(f"Network: {transfer.data.network}")from payelink_agent_pay import PaymentClient, WalletTransferRequest
# API key loaded from PAYELINK_KEY in .env file
client = PaymentClient()from payelink_agent_pay import PaymentClient, WalletTransferRequest
client = PaymentClient(api_key="your-api-key")transfer_request = WalletTransferRequest( from_wallet_key="wal_yZnDhmBMxx4", to_wallet_key="wal_tPS-Nxnh-hc", value="12", )
try: transfer = client.wallet_transfer(transfer_request) if transfer.success: print(f"Transaction Hash: {transfer.data.transaction_hash}") print(f"From: {transfer.data.from_address}") print(f"To: {transfer.data.to_address}") print(f"Value: {transfer.data.value}") print(f"Chain: {transfer.data.chain}") print(f"Network: {transfer.data.network}") print(f"Message: {transfer.message}") except Exception as e: print(f"Transfer failed: {e}")
### Using Context Manager
```python
# The client can be used as a context manager for automatic cleanup
# API key can be loaded from .env or provided explicitly
with PaymentClient() as client: # or PaymentClient(api_key="your-api-key")
transfer_request = WalletTransferRequest(
from_wallet_key="wal_yZnDhmBMxx4",
to_wallet_key="wal_tPS-Nxnh-hc",
value="12",
)
transfer = client.wallet_transfer(transfer_request)
# Client is automatically closed when exiting the context
The SDK provides full async support through AsyncPaymentClient for concurrent operations and better performance in async applications.
import asyncio
from payelink_agent_pay import AsyncPaymentClient, WalletTransferRequest
async def main():
# Initialize the async client (API key loaded from PAYELINK_KEY in .env)
async with AsyncPaymentClient() as client:
transfer_request = WalletTransferRequest(
from_wallet_key="wal_yZnDhmBMxx4",
to_wallet_key="wal_tPS-Nxnh-hc",
value="12",
)
# Execute the transfer asynchronously
transfer = await client.wallet_transfer(transfer_request)
print(f"Transfer successful: {transfer.success}")
print(f"Transaction Hash: {transfer.data.transaction_hash}")
# Run the async function
asyncio.run(main())import asyncio
from payelink_agent_pay import AsyncPaymentClient, WalletTransferRequest
async def main():
async with AsyncPaymentClient(api_key="your-api-key") as client:
transfer_request = WalletTransferRequest(
from_wallet_key="wal_yZnDhmBMxx4",
to_wallet_key="wal_tPS-Nxnh-hc",
value="12",
)
transfer = await client.wallet_transfer(transfer_request)
print(f"Transaction Hash: {transfer.data.transaction_hash}")
asyncio.run(main())import asyncio
from payelink_agent_pay import AsyncPaymentClient, WalletTransferRequest
async def transfer_funds(client: AsyncPaymentClient, from_wallet: str, to_wallet: str, amount: str):
"""Transfer funds between wallets."""
request = WalletTransferRequest(
from_wallet_key=from_wallet,
to_wallet_key=to_wallet,
value=amount,
)
return await client.wallet_transfer(request)
async def main():
async with AsyncPaymentClient() as client:
# Execute multiple transfers concurrently
transfers = await asyncio.gather(
transfer_funds(client, "wal_yZnDhmBMxx4", "wal_tPS-Nxnh-hc", "10"),
transfer_funds(client, "wal_abc123", "wal_def456", "20"),
transfer_funds(client, "wal_xyz789", "wal_uvw012", "15"),
)
for transfer in transfers:
print(f"Transfer successful: {transfer.data.transaction_hash}")
asyncio.run(main())import asyncio
from payelink_agent_pay import (
AsyncPaymentClient,
WalletTransferRequest,
InsufficientFundsError,
PaymentValidationError,
PaymentAPIError,
)
async def main():
async with AsyncPaymentClient() as client:
transfer_request = WalletTransferRequest(
from_wallet_key="wal_yZnDhmBMxx4",
to_wallet_key="wal_tPS-Nxnh-hc",
value="12",
)
try:
transfer = await client.wallet_transfer(transfer_request)
print(f"Transfer successful: {transfer.data.transaction_hash}")
except InsufficientFundsError as e:
print("Insufficient funds for this transfer")
except PaymentValidationError as e:
print("Transfer request validation failed")
except PaymentAPIError as e:
print(f"API error: {e.message} (Status: {e.status_code})")
asyncio.run(main())The SDK supports two ways to provide your API key:
-
Environment Variable (Recommended): Create a
.envfile in your project root:PAYELINK_KEY=your-api-key-here
Then initialize the client without the
api_keyparameter:client = PaymentClient()
-
Explicit Parameter: Pass the API key directly:
client = PaymentClient(api_key="your-api-key")
Note: If you provide both, the explicit api_key parameter takes precedence.
You can customize the client behavior for both sync and async clients:
Synchronous Client:
client = PaymentClient(
api_key="your-api-key", # Optional if PAYELINK_KEY is in .env
base_url="http://127.0.0.1:8000/v1", # Optional
timeout=30.0, # Request timeout in seconds
max_retries=3, # Maximum retry attempts
retry_delay=1.0, # Delay between retries (seconds)
verify_ssl=True, # SSL certificate verification
)Asynchronous Client:
async_client = AsyncPaymentClient(
api_key="your-api-key", # Optional if PAYELINK_KEY is in .env
base_url="http://127.0.0.1:8000/v1", # Optional
timeout=30.0, # Request timeout in seconds
max_retries=3, # Maximum retry attempts
retry_delay=1.0, # Delay between retries (seconds)
verify_ssl=True, # SSL certificate verification
)The SDK provides specific error types for different scenarios:
from payelink_agent_pay import (
PaymentClient,
InsufficientFundsError,
PaymentValidationError,
PaymentAPIError,
)
client = PaymentClient(api_key="your-api-key")
try:
transfer = client.wallet_transfer(transfer_request)
except InsufficientFundsError as e:
print("Insufficient funds for this transfer")
except PaymentValidationError as e:
print("Transfer request validation failed")
except PaymentAPIError as e:
print(f"API error: {e.message} (Status: {e.status_code})")WalletTransferRequest(
from_wallet_key: str, # Required: Source wallet key
to_wallet_key: str, # Required: Destination wallet key
value: str, # Required: Transfer amount as string
)WalletTransferResponse(
success: bool, # Whether the transfer was successful
data: WalletTransferData, # Transaction details
message: str, # Response message
)WalletTransferData(
transaction_hash: str, # Transaction hash (mapped from transactionHash)
chain: str, # Blockchain chain name
from_address: str, # Source wallet address
to_address: str, # Destination wallet address
value: str, # Transfer amount
network: str, # Network type (testnet/mainnet)
)wallet_transfer(request: WalletTransferRequest) -> WalletTransferResponseclose() -> None
async wallet_transfer(request: WalletTransferRequest) -> WalletTransferResponseasync close() -> None
Both clients support context manager protocol:
PaymentClient:with PaymentClient() as client: ...AsyncPaymentClient:async with AsyncPaymentClient() as client: ...
- Python >= 3.13
- httpx >= 0.24.0
- pydantic >= 2.0.0
# Clone the repository
git clone https://github.com/payelink/payelink-agent-pay-sdk.git
cd payelink-agent-pay-sdk
# Install dependencies
uv sync
# Run tests (when available)
uv run pytestuv buildFor information on how to publish this package to PyPI, see PUBLISHING.md.
MIT License - see LICENSE file for details.
For issues, questions, or contributions, please visit:
- GitHub Issues: https://github.com/payelink/payelink-agent-pay-sdk/issues
- Documentation: https://github.com/payelink/payelink-agent-pay-sdk#readme
- Added async support with
AsyncPaymentClient - Async context manager support
- Concurrent transfer operations support
- Initial release of Payelink Agent Pay SDK
- Wallet transfer functionality
- Comprehensive error handling
- Type-safe models with Pydantic