Technical Documentation

Technical Specifications

Complete technical details about the x4pay-core payment system implementation, including Bluetooth (BLE) protocol specifications, ESP32 memory management, payment verification process, and mobile app integration patterns.

Bluetooth (BLE) Protocol

Service & Characteristics

Service UUID: 6e400002-b5a3-f393-e0a9-e50e24dcca9e
TX Characteristic: 6e400003-b5a3-f393-e0a9-e50e24dcca9e
RX Characteristic: 6e400004-b5a3-f393-e0a9-e50e24dcca9e
Protocol: Nordic UART Service (NUS)

Connection Parameters

MTU Size: 150 bytes (set in code)
Connection Interval: 7.5ms - 4000ms
Advertising Interval: 100ms
Range: ~10 meters (Class 2)

Data Transfer Protocol

1. Device Advertisement

ESP32 advertises with device name containing payment info:

Device Name Format: "x402-[DEVICE_NAME]"
Advertisement Data: Service UUID + Device Name
Scan Response: Additional device info if needed

2. Connection Handshake

APP: Scans for devices with Nordic UART service UUID
APP: Connects to device via GATT
APP: Discovers services and characteristics
APP: Subscribes to TX characteristic for notifications
ESP32: Sends payment requirements JSON via TX characteristic

3. Payment Requirements JSON

{
  "network": "base-sepolia",
  "payTo": "0xa78eD39F695615315458Bb066ac9a5F28Dfd65FE",
  "maxAmountRequired": "1000000",
  "logoURL": "https://example.com/logo.jpg",
  "description": "Coffee machine payment",
  "options": ["Espresso", "Americano", "Latte"],
  "dynamicPricing": true,
  "recurring": {
    "enabled": true,
    "intervalSeconds": 30
  }
}

4. Payment Response

APP: User selects options and confirms payment in wallet
APP: Signs transaction with private key (PIN-protected)
APP: Sends payment payload JSON via RX characteristic

5. Payment Payload JSON

{
  "network": "base-sepolia",
  "from": "0x742d35Cc6C3C0532925a3b8D345A2E5E0E2F",
  "to": "0xa78eD39F695615315458Bb066ac9a5F28Dfd65FE",
  "amount": "1500000",
  "signature": "0x1c2b4d...",
  "nonce": 42,
  "selectedOptions": ["Latte"],
  "timestamp": 1729814400
}

ESP32 Memory Management

Memory Usage

X402-Aurdino: ~15KB program memory
X402-BLE-Aurdino: ~45KB program memory
RAM Usage: ~8KB during operation
JSON Buffer: 2KB allocated

Optimization Features

Stack monitoring with overflow detection
Dynamic memory allocation for JSON
Automatic garbage collection
RTOS task management

Multi-threading Architecture

X402-BLE-Aurdino uses FreeRTOS tasks for concurrent operation:

Task Structure

BLE Task: Handles Bluetooth connections (Priority 2)
Payment Task: Processes payment verification (Priority 3)
Main Task: User code execution (Priority 1)
Watchdog Task: System monitoring (Priority 4)

Synchronization

Mutex locks for shared resources
Queue-based message passing
Semaphore signaling for events
Atomic operations for counters

Code Example: Task Creation

void X402Ble::begin() {
  // Set active instance for worker callbacks
  s_active = this;
  NimBLEDevice::init(device_name_.c_str());
  NimBLEDevice::setDeviceName(device_name_.c_str());
  NimBLEDevice::setPower(ESP_PWR_LVL_P7);
  NimBLEDevice::setSecurityAuth(false, false, false);
  NimBLEDevice::setMTU(150);

  // Start payment verification worker with large stack on core 1
  PaymentVerifyWorker::begin(/*stackBytes=*/8192, /*prio=*/3, /*core=*/1);

  pServer = NimBLEDevice::createServer();
  pServer->setCallbacks(new ServerCallbacks());

  pService = pServer->createService(SERVICE_UUID);
}

Mobile App Connection Process

React Native Implementation

1. BLE Manager: Uses react-native-ble-plx library
2. Device Scanning: Filters by Nordic UART service UUID
3. Auto-connect: Connects to strongest signal device
4. Service Discovery: Discovers payment service characteristics
5. Data Exchange: Subscribes to notifications, sends payments

Key Code: Device Connection

// Scan for devices
const scanForDevices = () => {
  bleManager.startDeviceScan(
    [NORDIC_UART_SERVICE_UUID],
    { allowDuplicates: false },
    (error, device) => {
      if (device?.name?.startsWith('x402-')) {
        bleManager.stopDeviceScan();
        connectToDevice(device);
      }
    }
  );
};

// Connect and setup
const connectToDevice = async (device) => {
  const connected = await device.connect();
  await connected.discoverAllServicesAndCharacteristics();
  
  // Subscribe to TX characteristic for incoming data
  connected.monitorCharacteristicForService(
    NORDIC_UART_SERVICE_UUID,
    TX_CHARACTERISTIC_UUID,
    (error, characteristic) => {
      const data = JSON.parse(base64Decode(characteristic.value));
      handlePaymentRequirements(data);
    }
  );
};

Web App Implementation

1. Web Bluetooth API: navigator.bluetooth in Chrome/Edge
2. Service Filter: Requests access to Nordic UART service
3. GATT Connection: Connects via Bluetooth GATT protocol
4. Characteristic Access: Reads/writes to TX/RX characteristics

Key Code: Web Bluetooth

const connectToDevice = async () => {
  const device = await navigator.bluetooth.requestDevice({
    filters: [{ services: ['6e400002-b5a3-f393-e0a9-e50e24dcca9e'] }]
  });
  
  const server = await device.gatt.connect();
  const service = await server.getPrimaryService('6e400002-b5a3-f393-e0a9-e50e24dcca9e');
  
  // Get characteristics
  const txCharacteristic = await service.getCharacteristic('6e400003-b5a3-f393-e0a9-e50e24dcca9e');
  const rxCharacteristic = await service.getCharacteristic('6e400004-b5a3-f393-e0a9-e50e24dcca9e');
  
  // Listen for data from device
  await txCharacteristic.startNotifications();
  txCharacteristic.addEventListener('characteristicvaluechanged', (event) => {
    const data = new TextDecoder().decode(event.target.value);
    handlePaymentRequirements(JSON.parse(data));
  });
};

Payment Verification Process

x402 Facilitator API

Endpoint: https://x402-facilitator-a02bb8e9e6b3.herokuapp.com/verify
Method: POST with JSON payload
Response: Transaction hash or error
Timeout: 30 seconds maximum

Verification Steps

1. ESP32 receives payment payload from app via Bluetooth (BLE)
2. Device validates payload format and required fields
3. ESP32 sends HTTPS POST to x402 facilitator API over WiFi
4. Facilitator validates signature and submits transaction to blockchain
5. Facilitator returns transaction hash to ESP32
6. ESP32 executes payment callback (e.g., dispense coffee)

Code Example: Payment Verification

bool verifyPayment(const PaymentPayload &decodedSignedPayload, const String &paymentRequirements, const String &customHeaders) {
  // Make API call using utility function
  HttpResponse response = makePaymentApiCall("verify", decodedSignedPayload, paymentRequirements, customHeaders);
  
  if (response.success && response.statusCode > 0) {
    // Parse response manually for transaction hash
    String txHash = extractJsonValue(response.body, "transactionHash");
    if (txHash.length() > 0) {
      Serial.println("Payment verified: " + txHash);
      return true;
    }
  }
  
  return false;
}

Security & Privacy

Mobile App Security

Private keys encrypted with PIN
Biometric authentication support
Secure element storage (Android)
Transaction signing happens locally

ESP32 Security

No private keys stored on device
Payment verification via external API
WiFi credentials in encrypted flash
Bluetooth (BLE) pairing not required

Data Privacy

No personal information stored on ESP32
Payment amounts and addresses are public (blockchain)
Bluetooth (BLE) connections are not logged
Device can operate without internet (offline mode)

Supported Blockchain Networks

Mainnet Networks

Base (base)
Polygon (polygon)
Avalanche (avalanche)
IoTeX (iotex)
Sei (sei)
Peaq (peaq)

Testnet Networks

Base Sepolia (base-sepolia)
Polygon Mumbai (polygon-mumbai)
Avalanche Fuji (avalanche-fuji)
IoTeX Testnet (iotex-testnet)

Token Support

USDC (primary)
Native gas tokens
Custom ERC-20 tokens
Micro-amounts (1 wei precision)

Performance Metrics

Connection Times

BLE Discovery: 1-3 seconds
GATT Connection: 0.5-2 seconds
Service Discovery: 0.5-1 seconds
Total Connect Time: 2-6 seconds

Payment Processing

Data Transfer: 100-500ms
API Verification: 2-10 seconds
Blockchain Confirm: 5-60 seconds
Total Payment: 10-70 seconds

Throughput Limits

Concurrent Connections: 1 per ESP32 (BLE limitation)
Payments per Hour: ~60 (limited by API rate limits)
Data Rate: ~10KB/s over Bluetooth (BLE)
Range: 10 meters line-of-sight