Skip to main content

Python SDK for the remit.md universal AI payment protocol

Project description

remit.md Python SDK

Universal payment protocol for AI agents — Python client library.

CI PyPI

Installation

pip install remitmd

With framework integrations:

pip install remitmd[langchain]    # LangChain tools
pip install remitmd[crewai]       # CrewAI tools
pip install remitmd[autogen]      # AutoGen tools
pip install remitmd[openai-agents]  # OpenAI Agents tools

Quickstart

from remitmd import Wallet

# From environment variables (REMITMD_KEY, REMITMD_CHAIN)
wallet = Wallet.from_env()

# Or with explicit key
wallet = Wallet(private_key="0x...", chain="base")

# Send 1.50 USDC
tx = await wallet.pay_direct("0xRecipient...", 1.50, memo="inference fee")
print(tx.tx_hash)

Permits (Gasless USDC Approval)

Every payment that moves USDC requires on-chain approval. Use sign_usdc_permit() to sign an EIP-2612 permit off-chain — no gas, no approve transaction.

contracts = await wallet.get_contracts()

# sign_usdc_permit(spender, value, deadline, nonce)
# value is in USDC base units (6 decimals): $5.00 = 5_000_000
permit = await wallet.sign_usdc_permit(
    spender=contracts["router"],
    value=5_000_000,
    deadline=9999999999,
    nonce=0,
)

# Use the permit with any payment method
tx = await wallet.pay_direct("0xRecipient...", 5.00, permit=permit)

The spender must match the contract handling the payment:

  • Direct payment: contracts["router"]
  • Escrow: contracts["escrow"]
  • Tab: contracts["tab"]
  • Stream: contracts["stream"]
  • Bounty: contracts["bounty"]
  • Deposit: contracts["deposit"]

Payment Models

Direct Payment

permit = await wallet.sign_usdc_permit(contracts["router"], 5_000_000, 9999999999, 0)
tx = await wallet.pay_direct("0xRecipient...", 5.00, memo="AI task", permit=permit)

Escrow

from remitmd import Invoice

invoice = Invoice(to="0xContractor...", amount=100.00, memo="Code review")
escrow = await wallet.pay(invoice)

# Work happens...
await wallet.release_escrow(escrow.id)   # pay the contractor
# or
await wallet.cancel_escrow(escrow.id)    # refund yourself

Metered Tab (off-chain billing)

tab = await wallet.open_tab("0xProvider...", limit=50.0, per_unit=0.003)

# Hundreds of off-chain debits — zero gas, instant
# (provider calls debit on their side)

# One on-chain settlement when done
await wallet.close_tab(tab.id)

Payment Stream

stream = await wallet.open_stream("0xWorker...", rate=0.001)
# Worker receives 0.001 USDC/second

await wallet.close_stream(stream.id)

Bounty

bounty = await wallet.post_bounty(
    amount=25.0,
    task="Summarise top 10 EIPs of 2025",
    deadline=1700000000,
)

# Any agent can submit work; you decide the winner
await wallet.award_bounty(bounty.id, "0xWinner...")

Security Deposit

deposit = await wallet.place_deposit("0xCounterpart...", amount=100.0, expires=86400)

Testing with MockRemit

MockRemit gives you a zero-network, zero-latency test double. No API key needed.

import pytest
from remitmd import MockRemit

@pytest.fixture
def wallet():
    mock = MockRemit()
    return mock.wallet("0xAgent...")

async def test_agent_pays(wallet):
    mock = wallet._mock  # access the underlying mock
    tx = await wallet.pay_direct("0xProvider...", 0.003)
    assert mock.was_paid("0xProvider...", 0.003)

All Methods

# Contract discovery (cached per session)
contracts = await wallet.get_contracts()                     # dict

# Permits (gasless USDC approval)
permit = await wallet.sign_usdc_permit(                      # PermitSignature
    spender, value, deadline, nonce, usdc_address=None)

# Direct payment
await wallet.pay_direct(to, amount, memo="", permit=None)    # Transaction

# Escrow
await wallet.pay(invoice, permit=None)                       # Escrow
await wallet.claim_start(invoice_id)                         # Escrow
await wallet.submit_evidence(invoice_id, uri)                # Escrow
await wallet.release_escrow(invoice_id)                      # Escrow
await wallet.release_milestone(invoice_id, index)            # Escrow
await wallet.cancel_escrow(invoice_id)                       # Escrow

# Tabs
await wallet.open_tab(to, limit, per_unit, expires=86400, permit=None)  # Tab
await wallet.close_tab(tab_id, final_amount=0, provider_sig="0x")      # Tab
await wallet.charge_tab(tab_id, amount, cumulative, call_count, provider_sig)  # TabCharge

# Tab provider (signing charges)
sig = await wallet.sign_tab_charge(tab_contract, tab_id, total_charged, call_count)  # str

# Streams
await wallet.open_stream(to, rate, max_total, permit=None)   # Stream
await wallet.close_stream(stream_id)                         # Transaction

# Bounties
await wallet.post_bounty(amount, task, deadline, max_attempts=10, permit=None)  # Bounty
await wallet.submit_bounty(bounty_id, evidence_hash, evidence_uri=None)         # dict
await wallet.award_bounty(bounty_id, submission_id)          # Bounty

# Deposits
await wallet.place_deposit(to, amount, expires, permit=None) # Deposit
await wallet.return_deposit(deposit_id)                      # Transaction

# Status & analytics
await wallet.status()                                        # WalletStatus

# Webhooks
await wallet.register_webhook(url, events, chains=None)      # Webhook

# Operator links
await wallet.create_fund_link()                              # LinkResponse
await wallet.create_withdraw_link()                          # LinkResponse

# Testnet
await wallet.mint(amount)                                    # dict {tx_hash, balance}

# x402 (HTTP 402 auto-pay)
response, payment = await wallet.x402_fetch(url, max_auto_pay_usdc=0.10)

Error Handling

All errors are RemitError with machine-readable codes and actionable details:

from remitmd import RemitError

try:
    await wallet.pay_direct("0xRecipient...", 100.00)
except RemitError as e:
    print(e.code)     # "INSUFFICIENT_BALANCE"
    print(e.message)  # "Insufficient USDC balance: have $5.00, need $100.00"
    # Enriched errors include details with actual numbers:
    # e.details = {"required": "100.00", "available": "5.00",
    #              "required_units": 100000000, "available_units": 5000000}

Chains

Wallet(private_key=key, chain="base")          # Base mainnet (default)
Wallet(private_key=key, chain="base-sepolia")  # Base Sepolia testnet

License

MIT — see LICENSE

Documentation · Protocol Spec · GitHub

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

remitmd-0.1.2.tar.gz (51.8 kB view details)

Uploaded Source

Built Distribution

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

remitmd-0.1.2-py3-none-any.whl (44.8 kB view details)

Uploaded Python 3

File details

Details for the file remitmd-0.1.2.tar.gz.

File metadata

  • Download URL: remitmd-0.1.2.tar.gz
  • Upload date:
  • Size: 51.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for remitmd-0.1.2.tar.gz
Algorithm Hash digest
SHA256 2355329622c7f31f8f78d80ab2f73ef612b630fcf7c5526bf4880c000e139884
MD5 80590d2dd1cc492c15f63cf4730cb0d4
BLAKE2b-256 e7cbce3b48e26eb43400d14a318cd25e1916031332e1762c1baec8ade5975878

See more details on using hashes here.

Provenance

The following attestation bundles were made for remitmd-0.1.2.tar.gz:

Publisher: publish.yml on remit-md/sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file remitmd-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: remitmd-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 44.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for remitmd-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 58dc59ba37d2a5be9361b15d9f287a0fa0d6751f4a6b43bfe19ca3bc6ef2e287
MD5 bfcde410cc94582a6852befdec1ea67d
BLAKE2b-256 da025c2dcaf23f46e47d72168584bbd1e2d9f6bcafc11dec43e95a41f06b947f

See more details on using hashes here.

Provenance

The following attestation bundles were made for remitmd-0.1.2-py3-none-any.whl:

Publisher: publish.yml on remit-md/sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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