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.0.tar.gz (24.6 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.0-py3-none-any.whl (20.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: dhali_py-3.1.0.tar.gz
  • Upload date:
  • Size: 24.6 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.0.tar.gz
Algorithm Hash digest
SHA256 23a0a859b9e5ffcd040efcc11eb8bb103500486d78823aae4c04a3c84d790fff
MD5 11c93d496801226157daf276c3653505
BLAKE2b-256 a15762ec9c6b13394a599ea027b1345cd47feb1fa4f6962b7e28a2a6fd7f612e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: dhali_py-3.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.2 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a514704dfb470f800f367d0ae8bc8425abde7ec6c18d276f7ca18a5577ac52e2
MD5 f4c2fff04c13352e6c603cda73fb938d
BLAKE2b-256 ba5628e0cde62492c1517c4f2625b982bea8680c2983b1e864a6a7c2136a5e71

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