Client operations
Every field on the client is an intent-builder sub-client: an entry captures what to do (client.deposit.of(...)), a route pin narrows how (.selfFunded()), and a terminal does it (.send(), .approve(), .action()).
Settlement is cycle-based. Core nets each participant’s obligations for a clearing cycle into a single net-debit or net-credit committed to an on-chain Merkle root. Participants settle by fetching their prepared clearing action (contract address, amount, and Merkle proof) from core, then calling the ClearingHouse. cycleId is core’s text cycle id (cycle_id_text in clearing proofs and actions, "{asset}:{period_start}"); core does not resolve the on-chain bytes32 id in this path.
Deposits and withdrawals
Deposit collateral, then sign a payment:approve() returns undefined when the existing allowance is already
sufficient. A deposit with a missing allowance is refused with a typed
Erc20AllowanceRequiredError before any gas is spent.Payment guarantees
The payer signs a payment; the recipient redeems it for the operator’s receipt and verifies it:client.payment methods
newPayment(recipient, amount, asset?)— a payment payload scoped to the asset’s active settlement cycle.signRequest(payload)— sign the payload as the payer, returning aPaymentRequest.issueGuarantee(request)— redeem a signed request for the operator’sGuaranteeReceipt.verifyGuarantee(receipt)— check the receipt was signed by the operator signer core publishes, and return theGuaranteeit attests.listReceived()— payments guaranteed to the signer as a recipient.checkpointActiveCycle(asset?)/checkpointCycle(asset, cycleId)— sign and submit a checkpoint (see Checkpoints).
Verification is offline. A service that never builds a
Client can run the
same check with verifyGuaranteeReceipt(receipt, guaranteeRegistryDomain(chainId, guaranteeRegistryAddress), guaranteeSigner),
taking the three values from core’s public parameters.Settling a cleared cycle
The debtor pays what they owe; the creditor claims what they are owed. Terms always come from core’s prepared action — the caller only names which cycle.Gasless routes
With afacilitatorUrl configured, deposits, withdrawals, and settlement can run without the
signer paying gas: the signer produces an EIP-712 authorization and the facilitator submits it at
its own expense. Every route credits the authorization’s signer — the choice only changes who
pays — and the receipt’s route field reports which one ran.
Native ETH has no gasless deposit route — no authorization scheme covers it —
and native-asset debits cannot be pulled by signature. Both self-fund.
client.deposit.isGaslessAvailable() reports whether a facilitator is
configured at all. A rejection surfaces as FacilitatorRejectedError
carrying the facilitator’s snake_case reason (such as rate_limited) as
code; an OutcomeUnknownError means the facilitator
may already have submitted — do not blindly retry it.Balances
client.account.stablecoinPosition(token) reports a stablecoin pool position: the principal and yield split, plus the pool’s share accounting — userShares, totalUserShares, protocolShares, poolShares, poolAssets, and the strategy backing the pool (the zero address while its assets sit idle).
Building payments
Build payments withclient.payment.newPayment. A payment is scoped to the asset’s active settlement cycle, which it reads from core, so it cannot be built offline. It is stamped by core’s clock rather than this machine’s, gets a random uint256 reqId, and a random salt that blinds the recipient. The asset defaults to the zero address, which represents native ETH.
signRequest signs it as an EIP-712 PaymentAuthorization under the ClearingHouse domain, through the signer’s signTypedData:
Validated guarantees
A payer can agree that a guarantee only becomes payable once an external validator approves it, by attaching aValidationRequirement to the payload before signing. The requirement is bound into the salted recipient commitment the payer signs:
extra.validation on the payment requirements and is attached automatically.
Checkpoints
A checkpoint is the payer’s signed running total of its payments in a cycle. Core caps how many guarantees a payer may hold past its latest checkpoint; past the cap, issuance is refused with aCheckpointRequiredError. Only the payer can sign its checkpoint, so run these on the payer’s client.
CheckpointMismatchError because the batch moved while it was being signed. cycleId here is the on-chain bytes32 id, not the text id settlement takes.
Core’s batch is checked before it is signed: every payment must be one the
payer signed, in this cycle and asset, past the previous checkpoint, and
counted once. A batch that fails those checks throws
UntrustedCheckpointBatchError rather than being signed, since signing it
could inflate what the payer can be charged on default.Transaction receipt options
On-chain terminals accept an optional finalwaitOptions argument to override receipt polling: { timeout?, pollingInterval?, gas? }.
Next steps
X402 flow
Sign payment headers for
402-protected HTTP resources.Payment middleware
Charge for a route with
@4mica/x402’s Express middleware.Error handling
Catch and distinguish 4Mica SDK errors.