Wallets and payments
Each robot holds its own keys, encrypted on disk. Send USDC with one service call. Payments survive dropped connections and restarts without paying twice.
ros2 run robopay_core robopay wallet create
Each robot gets its own wallet, behind ordinary ROS 2 services and actions.
Works from any ROS 2 client: rclpy, rclcpp, or the command line.
Every payment is written to disk before it is sent. A dropped connection never pays twice.
MIT-licensed. No accounts, no platform fees.
The toolkit
Settlement layer
Machines need money they can actually hold: stable, digital, programmable. Every payment settles in USDC, a dollar stablecoin issued by Circle, on Base, a low-cost network. A drone leaving San Francisco can pay a charging pad in San Jose with no bank account in sight.
Each robot runs its own wallet. It holds a balance, pays, invoices and signs on its own, while you set the spending limits it cannot exceed.
A card payment passes through the payer’s bank, a processor, a scheme and the payee’s bank. Every hop needs an account, an approval and a business day. A stablecoin payment has none of that: the payer signs, the network settles, the payee holds the money. That is the part that lets a machine pay a machine.
A wallet is a keypair, generated on the robot and stored encrypted on its disk. Nothing to open, nobody to ask for permission.
To send value, the robot signs a transaction with its private key. That signature is the authorisation: it cannot be forged, and no intermediary has to approve it.
The signed transaction goes to a public ledger. It confirms in seconds and the balance moves for good: no chargebacks, no month-end reconciliation.
Everything settles in USDC, a dollar stablecoin, so a fleet’s balance does not drift while it works.
from rclpy.node import Node
from std_msgs.msg import Bool
from robopay_core.client import EscrowClient
HUB, COURIER = "0xHub...", "0xCourier..."
class Hub(Node):
def __init__(self):
super().__init__("hub")
self.escrow = EscrowClient(self)
# lock 5 USDC for the courier, refunded if not released in 30 min
self.job = self.escrow.open(
payer=HUB, payee=COURIER,
amount="5.00", timeout_seconds=1800,
)
self.create_subscription(
Bool, "/parcel/scanned", self.on_scan, 10)
def on_scan(self, msg):
if msg.data and self.job.escrow_id: # parcel is physically here
self.escrow.sign(self.job.escrow_id, role="payer")
# funds release once the courier has signed too
Escrow
Lock the payment before the job starts. When both robots agree the work is done, they sign and the funds release. If the deadline passes first, the money goes back to the payer, automatically. What counts as done is up to your sensors.
Safe by default
Early release. Tested end to end on mainnet with real funds, not yet production-ready.
Good to know
Yes. robopay is MIT-licensed and runs on your own robots. There are no accounts and no platform fees. The only cost is the network fee on each payment, a fraction of a cent on Base, paid from a small amount of ETH in the robot’s wallet.
Anything running ROS 2. It is tested on Humble and Jazzy. Everything is exposed as standard ROS 2 services, actions and topics, so nodes written with rclpy or rclcpp, or the ros2 command line, can use it. The helper library is Python.
No. If you can write a ROS 2 node, you have what you need. robopay handles keys, fees, signing and confirmation. You can start on the free Base Sepolia testnet before using real money.
No. Each robot’s wallet holds USDC directly and can receive and send it without a bank or card processor. You fund the wallet and set the limits it works within.
Keys are generated on the robot and encrypted on disk with a passphrase. They never leave the payment node: other nodes only ever see addresses and signatures. While the node runs, the unlocked key is in its memory, so treat the robot like any machine holding money. Scoped session keys that limit what a key can do are on the roadmap.
Yes. Per-payment and per-time-window caps are on by default and enforced at the point of signing, so no other node can bypass them. Incoming invoices never pay on their own: your code decides.
Not yet. robopay is an early release. It has been tested end to end on Base mainnet with real funds, but its interfaces may still change and the escrow contract has not had an external audit. Start on testnet and keep amounts small.