Built for developers,
by developers.
On most chains the payer holds the asset in one token and pays gas in another, and sending an ERC-20 needs a separate approval first: two wallet confirmations, and the second one is where crypto checkouts lose people. On Arc, USDC is the gas. No approve(), no permit(), nothing extra to hold. One confirmation, start to finish.
Atomic settlement
The payment does not go wallet-to-wallet. It goes through the router, which does two things in the same transaction: it splits off the 0.5% fee and forwards the rest to you, and it emits a receipt carrying your link’s ID. If you do not get paid, no fee is collected. The two cannot come apart.
Simple primitive
You do not need any of this to get paid; create a link and send it. But if you want payments inside your own product, it is a single call: pass the link ID and the destination address, and the router handles the split and the receipt. A background service watches the chain for those receipts and turns them into dashboard rows, emails and Telegram alerts.
// Execute a native USDC payment on Arc
async function processPayment(linkId, merchantAddress) {
/*
* The pay() function is non-custodial and
* atomic. No separate approval required.
*/
const tx = await leyline.pay(
linkId,
merchantAddress,
{ gasLimit: 210000, priority: 'high' }
);
return tx.wait();
}The router contract holds a zero balance at the end of every transaction.
This is the single most important decision in the project. Because we never hold funds, we are software rather than a payment processor, which keeps us out of money-transmitter licensing and means we cannot lose your money or freeze it. There is a test in the codebase asserting the router’s balance is zero. That test is the claim.