Payments & transfers

Implement SOL payment flows using AICW wallets

AICW supports SOL transfers from the wallet PDA with on-chain decision logging. Use this for payments, refunds, betting payouts, or any agent-initiated fund movement.

Transfer instruction: ai_transfer

ParameterTypeDescription
recipientPubkeyDestination Solana address
amountu64 (lamports)Transfer amount (1 SOL = 1,000,000,000 lamports)
reasoning_hash[u8; 32]SHA-256 of full reasoning text
summaryStringShort description stored on-chain

Prerequisites for transfer

  • Will must be active (updated_by_ai = true)
  • Wallet must be alive (not past death_timeout)
  • PDA must have sufficient balance (amount + rent-exempt minimum)
  • Agent pubkey must have SOL for transaction fee

Payment flow example

Complete payment flow with validation:

Python
import hashlib

def make_payment(recipient, amount_sol, reason):
    wallet_state = get_wallet_state()
    if not wallet_state["is_alive"]:
        raise Exception("Wallet is dead — cannot transfer")

    available = wallet_state["balance"] - RENT_EXEMPT_MINIMUM
    amount_lamports = int(amount_sol * 1_000_000_000)
    if amount_lamports > available:
        raise Exception(f"Insufficient balance: {available} < {amount_lamports}")

    reasoning_hash = hashlib.sha256(reason.encode()).hexdigest()

    result = ai_transfer(
        recipient=recipient,
        amount_lamports=amount_lamports,
        reasoning_hash=reasoning_hash,
        summary=reason[:64],
    )

    save_to_db(tx_sig=result, full_reasoning=reason)
    return result

Rejection flow: ai_reject

When your agent decides NOT to fulfill a transfer request, log the rejection on-chain:

Python
result = ai_reject(
    requester=requesting_address,
    requested_amount=requested_lamports,
    reason="Amount exceeds daily limit",
)

Best practices

  • Always check wallet liveness before attempting transfers
  • Implement amount caps in your business logic layer, not just on-chain
  • Use recipient allowlists for automated transfers
  • Store full reasoning text in a database, submit only the hash on-chain
  • Handle the case where a transfer partially fails (fee paid but transfer reverted)