Building composable payment rails on Zama: what we learned about PaymentIntents and Protocol Registries

“The Protocol Registry addresses a crucial problem: how do you let external developers build on top of confidential payment rails without requiring them to understand FHE?”
Submitted as part of the Zama Season 3 Builder Track.

What we built: the PaymentIntent pattern

A PaymentIntent is a simple idea: separate the declaration of a payment from its execution.

When a user calls createPaymentIntent(), they encrypt the amount once in the browser using the Zama SDK, commit the encrypted handle to an on-chain record, and specify the recipient, routing mode, and expiry window. That is the declaration. The handle lives on-chain. The plaintext never leaves the browser.

Later; perhaps hours later, perhaps triggered by an external condition executeIntent() runs. It can be called by the original sender, or by any protocol that has been registered in the Protocol Registry. The executing party does not need the plaintext amount. They pass the intentId, and the Gate retrieves the encrypted handle it stored at creation time, runs the sanction and balance guards in FHE, and dispatches the payment.

This unlocks something that is not possible in normal ERC-20 land: a payroll system executing on behalf of a user without the user being present, where the amount is never exposed to the payroll system, the chain, or any observer. The declaration happens once. Execution happens when conditions are met. The two are fully decoupled.

The Protocol Registry: composability without FHE expertise

The Protocol Registry addresses a harder problem: how do you let external developers build on top of confidential payment rails without requiring them to understand FHE?

Any registered protocol can call routeFromProtocol(from, to, encryptedAmount, routingMode) on the Gate. The protocol passes an encrypted handle either one it received from the user’s createPaymentIntent call, or one it holds transiently via an ACL grant but it never needs to decrypt anything, generate proofs, or interact with the Zama SDK directly. The Gate handles sanction filtering, balance gating, and dispatch. The protocol is just a conduit.

Registration is admin-gated: registerProtocol(address, description) is an owner-only call, and revocation is immediate. This means ecosystem composability does not require open access, you can whitelist the protocols you trust and revoke instantly if something goes wrong.

The practical implication: a lending protocol, an automated payroll service, or a streaming payment system can integrate with ConfidentialFlow and route confidential payments without the protocol itself holding or processing any plaintext financial data. The FHE complexity stays inside the Gate.

What’s next

The contracts are deployed on Sepolia. You can explore them on Etherscan:

  • ConfidentialPaymentGate: 0x78e9683ab9A62C8A1F12a72E05e209111f7bec40

  • ConfidentialYieldVault: 0xEC9dC67572704d219bfd03ED8Be0f4231f659a18

  • ConfidentialVestingModule: 0xCB9b04eaab3D3CBb29CA1dCEA666543D53e9d190

  • FlowRegistry: 0xA55A0E3CE8d613E090580eB1f797579b192376E0

If you are building a protocol that wants to route confidential payments without handling FHE directly, a lending protocol, an automated settlement system, a payroll service, reach out. The Protocol Registry is open to integrations. The interface is four parameters and a bytes32 return. The FHE stays inside the Gate.

We will post the GitHub and a live demo once the frontend deployment is finalized.