Skip to main content

A Python package for interfacing with Dhali

Project description

Package Tests Release

dhali-py

A Python library for managing payment channels (XRPL & Ethereum) and generating auth tokens (i.e., payment-claims) for use with Dhali APIs.

Includes support for Machine-to-Machine (M2M) payments using seamless off-chain claims.


Installation

pip install dhali-py

Quick Start: Machine-to-Machine Payments

1. XRPL

All signing is performed locally using xrpl-py.

from dhali.dhali_channel_manager import DhaliChannelManager, ChannelNotFound
from dhali.config_utils import get_available_dhali_currencies
from xrpl.wallet import Wallet
from xrpl.clients import JsonRpcClient

seed    = "sXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
wallet  = Wallet.from_secret(seed=seed)
rpc_client = JsonRpcClient("https://testnet.xrpl-labs.com/")

currencies = get_available_dhali_currencies()
# Select the correct currency from the list
xrpl_testnet = next(c for c in currencies if c.network == "XRPL.TESTNET" and c.code == "XRP")

# Use the Factory to get an XRPL Manager
manager = DhaliChannelManager.xrpl(
    wallet=wallet, 
    rpc_client=rpc_client, 
    currency=xrpl_testnet
)

# Generate a claim (Base64 encoded)
try:
    claim = manager.get_auth_token()
except ChannelNotFound:
    manager.deposit(1_000_000)          # deposit 1 XRP
    claim = manager.get_auth_token()    # 🔑 regenerate after deposit
print("XRPL Claim:", claim)

2. Ethereum (EVM)

Supports Ethereum, Sepolia, Holesky, etc. Requires eth-account and web3.py.

from dhali.dhali_channel_manager import DhaliChannelManager, ChannelNotFound
from dhali.config_utils import get_available_dhali_currencies
from eth_account import Account
from web3 import Web3

# 1. Setup Account & Provider
private_key = "0x..."
account = Account.from_key(private_key)
w3 = Web3(Web3.HTTPProvider("https://ethereum-sepolia.publicnode.com"))

# 2. Fetch Available Currencies
currencies = get_available_dhali_currencies()
sepolia_rlusd = next(c for c in currencies if c.network == "SEPOLIA" and c.code == "RLUSD") # or "USDC"

# 3. Instantiate Manager with Dynamic Config
manager = DhaliChannelManager.evm(
    account=account,
    w3=w3,
    currency=sepolia_rlusd
)

# 4. Generate EIP-712 Signed Claim
amount = int(0.1 * 10**sepolia_rlusd.scale) # 0.1 RLUSD

try:
    claim = manager.get_auth_token() 
except ChannelNotFound:
    manager.deposit(amount)
    claim = manager.get_auth_token(amount=amount) 
print("EVM Claim:", claim)

Usage in API Calls

Once you have the claim string, include it in your API request query parameters or headers as required by the Dhali Gateway.

import requests

url = f"https://xrplcluster.dhali.io?payment-claim={claim}"
response = requests.post(url, json={"data": "..."})

if response.status_code == 402:
    print("Payment Required: Channel may need topping up.")

Standardized x402 Payments

For APIs that follow the x402 standard, you must wrap your auth token (claim) with the payment requirement (retrieved from the payment-required header of a 402 response).

from dhali import wrap_as_x402_payment_payload

# 1. Get your claim as usual
claim = manager.get_auth_token()

# 2. Get the payment requirement from the 'payment-required' header of a 402 response
payment_requirement = response.headers.get("payment-required") 

# 3. Wrap into an x402 payload
x402_payload = wrap_as_x402_payment_payload(claim, payment_requirement)

# 4. Use 'x402_payload' in the 'Payment' header

Asset Management (for Providers)

To receive off-chain payments, you can use the DhaliAssetManager to create and update your off-chain address.

1. Create an Asset

This generates an Asset ID (UUID).

XRPL Setup

from xrpl.wallet import Wallet
wallet = Wallet.from_seed("s...") # Your XRPL seed

EVM Setup

from eth_account import Account
account = Account.from_key("0x...") # Your private key

Initialization & Creation

from dhali import DhaliAssetManager, WalletDescriptor, Currency
import asyncio

async def main():
    # For XRPL
    manager = DhaliAssetManager.xrpl(wallet)
    wallet_descriptor = WalletDescriptor(wallet.classic_address, "XRPL.TESTNET")
    
    # OR For EVM
    # manager = DhaliAssetManager.evm(account)
    # wallet_descriptor = WalletDescriptor(account.address, "SEPOLIA")

    currency = Currency("XRPL.TESTNET", "XRP", 6)

    # Create the asset
    result = await manager.create_asset(wallet_descriptor, currency)
    print("Your new Asset ID:", result['uuid'])

asyncio.run(main())

Once created, your asset is represented by an off-chain facilitator address:
https://x402.api.dhali.io/<uuid>

This facilitator is used for protocol-level concerns like verification and settlement, while your actual service requests are sent to your Resource Server.

2. Update an Asset

You can update your asset's metadata (name, rates, etc.) at any time.

from dhali import AssetUpdates

async def main():
    updates = AssetUpdates(
        name="My Optimized AI API",
        earning_rate=100,            # 100 drops per request
        earning_type="per_request"   # or "per_second"
    )

    result = await manager.update_asset(asset_id, wallet_descriptor, updates)
    print("Asset updated successfully")

Classes

DhaliChannelManager (Factory)

  • xrpl(wallet, rpc_client, currency, http_client=None, public_config=None) -> DhaliXrplChannelManager
  • evm(account, w3, currency, http_client=None, public_config=None) -> DhaliEthChannelManager

get_available_dhali_currencies()

Fetches current Dhali configuration and returns a list of currencies:

[
    Currency(network="SEPOLIA", code="USDC", scale=6, token_address="..."),
    ...
]

Here’s a clean, minimal addition you can append near the end of the README (for example, just before the “Classes” section or after it):


Async Workflows

Currently, dhali-py provides a synchronous interface for managing payment channels and generating claims.

If you would like to see native async/await support (e.g., async workflows using asyncio, async Web3 providers, or async XRPL clients), please drop us a message and let us know. Community feedback helps us prioritise features 🚀


Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dhali_py-3.1.1.tar.gz (26.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dhali_py-3.1.1-py3-none-any.whl (20.6 kB view details)

Uploaded Python 3

File details

Details for the file dhali_py-3.1.1.tar.gz.

File metadata

  • Download URL: dhali_py-3.1.1.tar.gz
  • Upload date:
  • Size: 26.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dhali_py-3.1.1.tar.gz
Algorithm Hash digest
SHA256 b529819ccf4b0112b7c6b02f8245da4bf940f9f35226418339c499c0d1120f8f
MD5 9d458a1e14d9f91cbfb473b7e1dd87e1
BLAKE2b-256 7aef9f53c5d3f82bb7b49e29be57b974b468e528c399733bce88ffd0e5ab9da8

See more details on using hashes here.

File details

Details for the file dhali_py-3.1.1-py3-none-any.whl.

File metadata

  • Download URL: dhali_py-3.1.1-py3-none-any.whl
  • Upload date:
  • Size: 20.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dhali_py-3.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f8f5130949feb5723b1a7819c6c4324e5d4d1931197630f4e8186a7701d71ef7
MD5 10b66f69739a1727a35d83f108a59231
BLAKE2b-256 3a19833cfc608a17ff972b879af53748c85837b6318def4dabdad6d998291ed4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page