Developer guide

Costs and platform accounts

7 min read

Two different numbers describe the money an operation moved, and reading one as the other is how a transfer gets reported as free while the platform spends real ETH on it.

  • What the user was charged travels in the quote's fee breakdown, in the asset being transferred. Under a sponsored policy its network component is legitimately 0.
  • What the operation cost on chain travels in networkCost, in the chain's native unit, and names the account that paid it.

The first is a price. The second is an expense, and it belongs to the deployment.

What an operation cost

networkCost has two shapes, discriminated by measured, because "this cost nothing" and "nobody measured this" are different claims:

FieldWhenWhat it says
measured: true + totalNativeBaseUnitsThe execution path can read the costWei on EVM, satoshi on Bitcoin, lovelace on Cardano
paidByWith measured: truepaymaster, relayer or user
paidByAddressWith measured: trueThe account whose balance actually dropped
gasUsed, effectiveGasPriceWeiGas-metered chainsThe decomposition of the total
measured: false + reasonThe path cannot measure itWhy there is no figure, so it is never read as free

paidBy: "user" is not a fallback, it is Bitcoin and Cardano. On a UTXO chain the network fee comes out of the sender's own inputs and no third party can pay it without taking part in the transaction. There is nothing to sponsor there, so nothing is posted as sponsorship — and the figure is read from the transaction that settled, not from the quote that predicted it.

In one currency, and whose it was

An operation spends in three currencies at once: the chain's native coin for the gas, the asset being moved for the fees charged on it, and the money a commercial fee was negotiated in. Adding them is the only way to answer what the operation cost each party, and the platform is the party that holds the rates. So the platform converts.

FieldWhereWhat it carries
networkCost.usdWith measured: trueThe network cost valued in USD
fees.borneByUserUsdIn the fee breakdownWhat the user was charged, valued
fees.borneByPartnerUsdIn the fee breakdownWhat the Partner absorbed, valued

All three are a UsdValue: the amount plus the QuotedPrice that produced it — rate, source and the instant it was read. The conversion is frozen when the cost is measured, so the same operation answers the same figure on every read. An asset this deployment holds a rate for is converted; one it holds no rate for stays in its own unit, stated as such.

Two rules decide whose cost it was. Gas belongs to the account that paid it: the user's when it came out of their own inputs, and otherwise whoever funds the lane that sponsored it — lane on the operation. A partner lane is a cost of the Partner; a sandbox lane is a cost of the deployment running the public demo. Fees are split by borneByUser and borneByPartner.

One transaction per network, named

An operation can settle on more than one network: a send split across networks runs one transfer per source network, and a cross-chain settlement one per side. Three fields report that, and each one answers a different question:

FieldWhat it holds
transactionsEvery transaction with the network it settled on, and its explorer link where the deployment publishes one
transactionHashThe first transaction, on one network. It has always meant one transaction and it still does
transactionHashesThe same hashes as a flat list, in the same order, without the network

Reconcile against transactions. Attributing a flat list of hashes to networks by guessing is what that field exists to stop.

The accounts that make "the user does not pay gas" true

GET /v1/system/platform-accounts reports them per chain, and every figure is read from the chain at call time: a stale funding number is worse than none, because it gets acted on.

RoleWhat it isWhat running dry looks like
relayerBroadcasts transactions and pays for them on the direct pathTransfers stop being submitted
operational_validatorThe operational authority on the accountAuthorized operations stop being signed
paymasterSponsors gas on the ERC-4337 pathEvery sponsored operation reverts at validation
entry_pointThe ERC-4337 contract the operations go through
faucetSigns test-balance grants, and only ever outside productionTest funding stops, transfers keep working
fee_collectionWhere a Partner's collected fees are swept toRevenue accrues with nowhere to settle

The Paymaster is read at the EntryPoint, not at its own address. entryPointDepositWei is what pays for sponsored gas; entryPointStakeWei and entryPointStaked are what let it be used at all. A Paymaster holding funds it never deposited cannot sponsor anything, which is why the two figures are reported separately and never added together.

Every account that has automatic remediation also reports lowWatermarkWei and belowLowWatermark — the same threshold the maintenance loop acts on, not a second one for display. A chain whose adapter has no such accounts answers available: false with a reason, rather than being left out of the list: nothing configured and nobody asked are different states.

The revenue side of the same report

A fee that is only readable in the ledger is a fee nobody checks. The fee_collection entry is therefore reported like any other platform account, and carries two things the others do not:

  • partnerId — the account belongs to a Partner rather than to the deployment, and there is one entry per Partner per chain, resolved exactly as a sweep of that chain resolves it. Summing the list gives the revenue once.
  • accrued — what the ledger booked to that account and a sweep has not moved onto its address yet, per asset. It is stated as unswept rather than as a balance: the gap between the two is what a sweep closes, and the two disagreeing is the reconciliation signal.

The collection address is configuration of the Partner and is rotatable without a deployment. See Fees, ledger and reconciliation for how a fee is accrued, swept and rotated.

Where to read it

  • The Operation carries networkCost and transactions, through the API and the official SDK.
  • GET /v1/system/platform-accounts carries the accounts, and needs the operations scope.
  • The Sandbox on this site shows both panels next to the user's own balance, because the platform's economics and the user's are read on the same screen.

Capabilities in this area

This area covers the capabilities below. The Roadmap states the current availability of each one.

  • What an operation cost, and which account paid it — The cost on chain, in the network's own unit, with the account that paid it named: the Paymaster, the relayer, or the sender out of their own inputs on a UTXO chain. A path that cannot measure the cost says so, and never reports zero in its place.

  • One transaction per network, named — An operation that settled on several networks — a send split across them, a cross-chain settlement — reports each transaction with the network it settled on and its explorer link. Attributing a flat list of hashes to networks was guesswork before.

  • The funding accounts, read from the chain — The relayer, the operational validator, the Paymaster with its EntryPoint deposit and stake, the EntryPoint and the test-funding account, per network, with the balance each one has at the moment of the call. An account running dry is otherwise indistinguishable from a malfunction.

  • The revenue side in the same report — Each Partner's collection account, once per network, with what has accrued to it and has not been swept onto its address yet, per asset. The gap between the two is what a sweep closes, and the two disagreeing is the reconciliation signal.

  • Who bore each fee, totalled per period — A fee paid out of the user's balance and one the Partner absorbed are different money with different consequences. Reporting the split per operation and adding it up per period is what turns them into two figures instead of one.