Metadata-Version: 2.4
Name: naturalpay
Version: 0.1.2
Summary: Natural Payments SDK
Keywords: payments,ai,agents,mcp,llm
Author: Natural
Author-email: Natural <walt@natural.co>
License-Expression: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: fastmcp>=2,<3
Requires-Dist: httpx>=0.28.1
Requires-Dist: pydantic>=2.12.5
Requires-Dist: pytest>=8.0 ; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24 ; extra == 'dev'
Requires-Dist: pytest-cov>=4.0 ; extra == 'dev'
Requires-Dist: ruff>=0.8.0 ; extra == 'dev'
Requires-Dist: mypy>=1.13.0 ; extra == 'dev'
Requires-Dist: twine>=5.0 ; extra == 'dev'
Requires-Dist: pre-commit>=4.0 ; extra == 'dev'
Requires-Python: >=3.12
Project-URL: Homepage, https://natural.co
Project-URL: Documentation, https://docs.natural.co
Project-URL: Repository, https://github.com/naturalpay/naturalpay-python
Provides-Extra: dev
Description-Content-Type: text/markdown

# Natural Payments Python SDK

Official Python SDK for Natural Payments - AI agent payment infrastructure.

## Installation

```bash
pip install naturalpay
# or
uv add naturalpay
```

## Quick Start

```python
from naturalpay import NaturalClient

client = NaturalClient(api_key="sk_ntl_sandbox_xxx")

# Create a payment
payment = await client.payments.create(
    agent_id="agt_123",
    instance_id="instance_456",
    amount=5000,
    customer_party_id="pty_456",
    recipient="alice@example.com",
    memo="Payment for consulting",
    idempotency_key="unique-key-for-this-payment",
)

print(f"Payment created: {payment.transaction_id}")

# Check balance
balance = await client.wallet.balance()
print(f"Available: ${balance.available_usd}")
```

### Sync Client

```python
from naturalpay import NaturalClientSync

client = NaturalClientSync(api_key="sk_ntl_sandbox_xxx")
payment = client.payments.create(
    agent_id="agt_123",
    instance_id="instance_456",
    amount=5000,
    customer_party_id="pty_456",
    recipient="alice@example.com",
    memo="Payment for consulting",
    idempotency_key="unique-key-for-this-payment",
)
```

## Configuration

### Environment Variables

- `NATURAL_API_KEY` - Your API key (starts with `sk_ntl_dev_` or `sk_ntl_prod_`)
- `NATURAL_SERVER_URL` - API base URL (default: `https://api.natural.co`)

### Client Options

```python
client = NaturalClient(
    api_key="sk_ntl_dev_xxx",             # API key
    base_url="https://api.natural.co",  # Custom base URL
    timeout=30.0,                     # Request timeout in seconds
)
```

## Resources

### Payments

```python
# Create a payment
payment = await client.payments.create(
    agent_id="agt_123",
    amount=10000,
    customer_party_id="pty_456",
    recipient="alice@example.com",  # email, phone, or party ID (pty_xxx)
    memo="Payment description",
    idempotency_key="unique-key-for-this-payment",
    instance_id="instance_789",  # required when agent_id is provided
)

```

### Wallet

```python
# Get wallet balance
balance = await client.wallet.balance()

# Withdraw funds
withdrawal = await client.wallet.withdraw(
    amount=50000,
    external_funding_source_id="efs_xxx",
    idempotency_key="wd_unique_key",
)
```

### Transactions

```python
from naturalpay import TransactionTypeFilter

# List all transactions
transactions = await client.transactions.list(
    limit=100,
    agent_id="agt_123",
    instance_id="instance_789",  # required when agent_id is provided
)

# List only transfers
transfers = await client.transactions.list(
    transaction_type=TransactionTypeFilter.TRANSFER,
)

# List only payments
payments = await client.transactions.list(
    transaction_type=TransactionTypeFilter.PAYMENT,
)
```

### Agents

```python
# List agents
agents = await client.agents.list(status="ACTIVE", limit=50)

# Create an agent
agent = await client.agents.create(
    name="Shopping Assistant",
    description="Handles shopping tasks",
)

# Update an agent
updated = await client.agents.update(
    "agt_xxx",
    name="Updated Name",
    status="REVOKED",
)

# Delete an agent
await client.agents.delete("agt_xxx")
```

### Delegations

```python
# List agent delegations
delegations = await client.delegations.list(limit=50)

# Get delegation details
delegation = await client.delegations.get("adl_xxx")
```

### Customers

```python
# List customers who have delegated to you
customers = await client.customers.list(limit=50)
```

## MCP Integration

The SDK includes a thin MCP proxy that connects AI agents to the hosted Natural MCP server.

### CLI Usage

```bash
# Using uvx (recommended)
uvx naturalpay mcp serve

# Or using python module
python -m naturalpay mcp serve

# With explicit options
uvx naturalpay mcp serve --api-key sk_ntl_sandbox_xxx --mcp-url https://mcp.natural.co
```

### Claude Desktop / Cursor Config

```json
{
  "mcpServers": {
    "natural": {
      "command": "uvx",
      "args": ["naturalpay", "mcp", "serve"],
      "env": { "NATURAL_API_KEY": "sk_ntl_..." }
    }
  }
}
```

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `NATURAL_API_KEY` | (required) | API key |
| `NATURAL_MCP_URL` | `https://mcp.natural.co` | MCP server endpoint |

### Internal Dev (local MCP server)

```bash
NATURAL_MCP_URL=http://localhost:8080 uvx naturalpay mcp serve
```

## Error Handling

```python
from naturalpay import (
    NaturalError,
    AuthenticationError,
    InvalidRequestError,
    PaymentError,
    InsufficientFundsError,
    RecipientNotFoundError,
    RateLimitError,
    ServerError,
)

try:
    await client.payments.create(...)
except AuthenticationError:
    # Handle authentication issues (401)
    ...
except InsufficientFundsError:
    # Handle insufficient balance
    ...
except RecipientNotFoundError:
    # Handle invalid recipient
    ...
except RateLimitError as e:
    # Handle rate limiting (429)
    print(f"Retry after: {e.retry_after}s")
except ServerError:
    # Handle server errors (5xx)
    ...
except NaturalError as e:
    # Handle other API errors
    print(f"Error: {e.message}, Code: {e.code}")
```

## Type Support

This SDK uses Pydantic models and provides full type definitions:

```python
from naturalpay import (
    AccountBalance,
    Transaction,
    TransactionTypeFilter,
    TransactionListResponse,
    Agent,
    AgentDelegation,
    WithdrawResponse,
)
```

## Documentation

- [API Reference](https://docs.natural.co)
- [Examples](https://github.com/naturalpay/natural-examples)

## License

MIT
