A programmable clearing layer for humans, applications and autonomous agents. Merchants price in their own currency and settle in a stablecoin; the payer brings any supported asset. Every settlement is a transaction you can open on a block explorer.
A coffee roaster in Singapore prices a bag at SGD 25 and wants to sell worldwide. A customer in Berlin wants to pay in EURC. An agent wants to pay for one API call and has never heard of an account.
To sell to either of them today, the merchant has to become an infrastructure team:
accept crypto → pick a chain, hold a wallet, fund it with gas
→ watch a rate that moves while the customer decides
→ swap, hope the pool is deep enough, eat the slippage
→ reconcile a balance nobody can explain
One clearing layer between the two. The merchant's number is locked first, and everything else is derived from it.
merchant prices SGD 25, in their own currency
payer holds ETH, EURC, USDC, or another configured asset
Mayarin locks the merchant's stablecoin settlement minimum
merchant receives exactly the configured settlement amount
The merchant never sees a chain, a gas token, or a slippage setting. An autonomous agent is a payer class, not a product line — it reaches the same clearing engine, ledger and merchant as a person at a checkout, and is given one thing to sign.
1 INTENT the merchant states a price and a settlement asset
2 LOCK the quote engine freezes the settlement minimum
3 PAY contract call, deposit transfer, or one signed x402 authorization
4 CONFIRM the receipt is read back off the chain and matched
5 RECORD clearing transition + balanced ledger postings, one DB transaction
↓
merchant paid ──► exactly the invoice, or the payment does not advance
A submitted transaction is never proof of payment, and a webhook only wakes the engine — the chain is the truth.
Ports and adapters: a domain package never imports a concrete adapter.
apps/api/src/container.ts is the only file that knows which implementations run.
flowchart TB
Payer["Human checkout · Application (SDK) · AI agent (x402)"]
subgraph Edge["apps/* — Hono + Zod"]
API["Payment Intents · Commerce · x402 · Webhooks"]
Worker["chain-worker — watcher, indexer, executor"]
end
subgraph Core["packages/core/* — pure domain, zero I/O"]
Intent["payment-intent"] --> Quote["quote + liquidity"] --> Clearing["clearing"] --> Ledger["ledger"]
Chain["chain"] -- recordAssetReceived --> Clearing
end
subgraph Adapters["packages/providers/* + packages/db"]
EVM["evm · viem"]
Swap["uniswap · 0x · lifi"]
Oracle["pyth · chainlink"]
DB["Drizzle + Postgres"]
end
Payer --> Edge --> Core
Core -. ports .-> Adapters
Three execution paths, chosen per payment:
| Path | The payer does | Advances on |
|---|---|---|
| Contract | Calls PaymentRouter with a signed order |
A PaymentCompleted log past confirmation depth |
| Deposit-match | Sends a transfer to a unique per-intent address | A confirmed deposit matched to the intent |
| x402 | Signs one EIP-3009 authorization | The receipt read back and matched |
Full detail: Architecture · Clearing Engine · Agent payments.
Any Mayarin-gated endpoint becomes payable per call by an agent that has never registered, holds no
API key, and never sees a checkout page. It gets a 402 with machine-readable terms, signs one
EIP-3009 authorization for an exact amount, and gets the
resource.
agent calls endpoint → 402 + terms
agent signs → one EIP-3009 authorization, exact amount
Mayarin settles → receipt read back and matched, ledger posted
agent gets → the resource
An agent that does not hold the merchant's asset still pays. The swap is priced backwards from the invoice — exact-output, so the merchant gets exactly the invoice or the swap reverts:
authorization payer → operator the agent's asset, exactly what it signed for
swap operator → pool exact-output, bounded by the authorization
pool → merchant exactly the invoice
surplus what the pool did not need, owed back to the payer
Current boundaries: exact scheme only, EVM only, and the broadcaster pays gas. Full detail in
docs/x402.md.
Live on Polygon, Base, BNB Smart Chain and Arbitrum One. The three contracts below sit at the same address on all four chains, and every router configuration change goes through a timelock (48 h delay) controlled by a multisig. Settlement is in the chain's stablecoin.
| Contract | Address |
|---|---|
PaymentRouter |
0x8F90e9ad0120dd03352a2bC01BdF302447Fb2537 |
TimelockController |
0xBFc95Af1706Aa271F0207575CfF31cC32Ad7656f |
DepositForwarderFactory |
0x0dc52ff8d7d82d1c43827640de024da88c14224b |
Open them on Polygonscan, Basescan, BscScan or Arbiscan. Ethereum mainnet is not deployed yet. Solana will be deployed soon.
The sandbox for integrations: nothing here moves real money.
Arbitrum Sepolia:
| Contract | Address |
|---|---|
PaymentRouter |
0xEe7c5B5a9eeAf667A6EFb217A8a77534C873f7a9 |
EscrowFactoryV2 |
0xB14EEab74d84F900132632ff9dAcDe26C5043cad |
DepositForwarderFactory |
0x4b96e74b963efa7ab7d7497854fc87220bd092c4 |
PayoutBatcher |
0x78f0c40e1aa5a63dd71e58334586461eb3eb6312 |
Other chains:
| Chain | PaymentRouter |
DepositForwarderFactory |
|---|---|---|
| Base Sepolia | 0xee7c5b5a… |
0x69c72C51… |
| Ethereum Sepolia | 0xE54E800b… |
0xCa83514c… |
| Arc Testnet | 0xee7c5b5a… |
0x04cd74e7… |
EscrowFactoryV2 and PayoutBatcher sit at the same addresses on these three chains too.
Solana Devnet: a native Anchor port of the router,
5raasGCxqaEvGsvQ1PvGxRB1JYnA7Y3L4LfjRCfkNJ4f,
with the same invariants as the EVM contract (a backend-authorized order, a non-replayable intent,
the merchant paid exactly min_out - fee). Payers bring SOL or any SPL token, swapped through
Orca Whirlpool. Source in packages/contracts/solana-payment-router.
| Price in your own currency | USD, EUR, SGD and more — settle in a stablecoin |
| Payer brings any supported asset | exact-output swaps priced backwards from the invoice |
| Money is never a float | bigint minor units end to end, double-entry ledger |
| Agents pay per call | x402 — no account, no API key, one signature |
| Commerce out of the box | catalog, payment links, invoices, hosted checkout, dashboard, SDK |
| Embedded checkout | one <mayarin-checkout> element or a React PayButton puts the checkout on your own page, Stripe-style |
| Stealth deposit addresses | a one-time address per payment, derived from an HD key and deployed only when funds arrive, so the payer never sees your wallet |
| Buyer protection | on-chain escrow: bonded disputes, an arbiter, auto-release |
| Recurring and bulk | subscriptions, and batch payouts in one transaction |
| Anyone can check | every settlement is a transaction on a public block explorer |
Requires Bun 1.4+, Node 22.12+, and Docker.
git clone https://github.com/playriglabs/mayarin.git
cd mayarin
bun run setup # install, write .env, start Postgres, migrate
bun run dev:all # core API + chain worker + dashboard + checkoutimport { createMayarin } from "@mayarin/sdk";
const mayarin = createMayarin({
baseUrl: "https://api.mayarin.xyz", // https://api-testnet.mayarin.xyz for the sandbox
secretKey: process.env.MAYARIN_SECRET_KEY ?? "",
});
const link = await mayarin.commerce.paymentLinks.create(
{
kind: "fixed",
merchant: {
id: "merchant_123",
name: "Melati Coffee",
city: "Singapore",
countryCode: "SG",
},
amount: { amount: "25.00", asset: "SGD" },
},
{ idempotencyKey: "order-4711" },
);Commands, conventions and tests: AGENT.md. Design record: docs/.
API reference: docs.mayarin.xyz.
mayarin.xyz — live on mainnet (Polygon, Base, BNB Smart Chain and Arbitrum One), with a testnet sandbox and Solana on devnet beside it: clearing core, double-entry ledger, contract and deposit execution, oracle-guarded quotes, commerce and hosted checkout, merchant dashboard, SDK, agent payments, buyer-protection escrow, subscriptions and batch payouts.
Not done, and not pretended otherwise:
- Fiat rails (QRIS, bank transfer) and the off-ramp are later phases.
- Ethereum mainnet is not deployed yet, and Solana mainnet is coming soon.
- Testnet pool depth is not market depth; the oracle deviation guard is widened on testnet.
Apache License 2.0 — copyright 2026 Playrig Labs. Solidity sources under
packages/contracts/payment-router stay MIT.
