What is FlowPay?
ETHGlobal NYC 2026FlowPay is an intent-based cross-chain payment engine. You describe a payment in plain language — who, how much, in what token, and why — and FlowPay parses the intent, resolves names, builds a cross-chain route, executes settlement on Hedera, and records a permanent audit trail.
No wallet switching. No chain selection. No gas guessing. One sentence.
Example intent
"Send 200 USDC from María to Juan in Mexico for rent" → Parsed by Google Gemini 2.0 Flash → Juan resolved via ENS (juan.eth) or demo registry → Cross-chain route built by LI.FI Composer SDK → Settled on Hedera (< 3s, $0.001) → Audit record written to HCS topic 0.0.9217982
Quickstart
Run FlowPay locally in under 5 minutes.
Clone & install
git clone https://github.com/riesgopais/flowpay cd flowpay npm install
Configure environment
cp .env.example .env.local # Fill in GOOGLE_API_KEY, HEDERA_ACCOUNT_ID, # HEDERA_PRIVATE_KEY, LIFI_API_KEY
Run dev server
npm run dev # Open http://localhost:3000
GOOGLE_API_KEY is absent, the fallback regex parser activates automatically. The demo still works without any API keys for basic testing.Payment pipeline
Every payment goes through four sequential steps, streamed in real time via Server-Sent Events.
Intent parsing — Google Gemini
Gemini 2.0 Flash parses the plain language input using Structured Outputs (responseMimeType: application/json + responseSchema). Returns a fully typed PaymentIntent object. The hybrid parser checks a keyword fast-path first — Gemini is only called for ambiguous intents.
Route building — LI.FI Composer
LI.FI Composer SDK builds an atomic cross-chain EVM flow. Same token → direct transfer. Different tokens → swap via aggregator. Returns a compiled transactionRequest ready for wallet signing.
Settlement — Hedera HBAR
A native HBAR TransferTransaction executes on Hedera Testnet from the relayer account. 0.001 HBAR for EVM token payments, up to 1 HBAR for HBAR-native payments. Finality in < 3 seconds.
Audit record — Hedera HCS
A TopicMessageSubmitTransaction writes the full payment intent to HCS topic 0.0.9217982. Includes status: SUCCESS | ROUTING_FAILED | PAYMENT_FAILED. HCS only writes SUCCESS after the HBAR payment confirms — atomicity guaranteed.
Hybrid intent parser
FlowPay uses a two-stage parser to minimize latency and API costs while maintaining accuracy.
⚡ Keyword engine
Deterministic regex parser. Returns HIGH confidence when intent contains an explicit amount + token + known recipient. No AI call. Instant response.
When to use: "Send 100 USDC to Sofia for rent"
🤖 Gemini 2.0 Flash
Called only when the keyword engine returns LOW confidence: missing amount, ambiguous phrasing, complex multi-clause sentences, or unknown constructs.
When to use: "Maybe send some funds to my friend in Mexico"
Name resolution & ENS
NewFlowPay resolves human names to wallet addresses in two stages, in order:
14 hardcoded names (ES + EN) with testnet EVM and Hedera addresses. Instant — no network call.
If name not in registry, resolves via viem.getEnsAddress(). Accepts "vitalik" (auto-appends .eth) and "nick.eth" (explicit). Returns null if not found → 422.
Resolution examples
"Send 100 USDC to Sofia" → registry → 0x742d35… (instant) "Send 100 USDC to vitalik" → ENS lookup → vitalik.eth → 0xd8dA6B… "Send 100 USDC to nick.eth" → ENS lookup → nick.eth → 0xb8c2C8… "Send 100 USDC to Roberto" → registry miss → ENS miss → 422
ETHEREUM_RPC_URL is set for production use, or the default Cloudflare public endpoint will be used (may rate-limit under heavy traffic).HCS atomicity
The audit record on Hedera Consensus Service reflects actual payment outcome — never a false positive.
SUCCESSWritten only after the HBAR TransferTransaction confirms on-chain.ROUTING_FAILEDWritten if LI.FI Composer fails to build or compile the cross-chain flow.PAYMENT_FAILEDWritten if the HBAR transfer itself fails after routing succeeded.POST /api/parse
Parses a natural language intent and returns a structured preview for user confirmation. Does not execute any blockchain transaction.
Request
{
"intent": "Send 100 USDC to Sofia for rent"
}Response (200)
{
"amount": 100,
"fromToken": "USDC",
"toToken": "USDC",
"recipientAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"hederaRecipient": "0.0.98",
"senderName": null,
"recipientName": "Sofia",
"memo": "rent",
"humanSummary": "Send 100 USDC to Sofia for rent",
"error": null,
"_parsedBy": "keyword",
"warnings": ["Sending to Sofia's registered testnet address"],
"resolvedAddressLabel": "Resolved from demo registry"
}errorNon-null when intent cannot be processed: unsupported token, invalid amount, ambiguous input._parsedBy"keyword" when the fast-path engine resolved it. "gemini" when AI was invoked. "fallback" when no API key is present.warnings[]Array of AI assumption warnings shown to the user before confirmation: defaulted amount, defaulted token, ENS/registry resolution notice.resolvedAddressLabelHuman-readable source of address resolution: "Resolved via ENS (sofia.eth)" or "Resolved from demo registry".400 for empty or missing intent. Unsupported tokens (BTC, SOL, XRP…) return 200 with error field set, not a 4xx — the frontend reads the field to show the error in-context.POST /api/pay-stream
Executes a payment and streams real-time progress via Server-Sent Events. Each event corresponds to an actual backend step completing — no fake delays.
Request
{
"intent": "Send 100 USDC to Sofia for rent",
"senderAddress": "0x..." // optional — enables on-chain wallet signing
}SSE stream
data: {"type":"step","index":0} // Gemini parsed
data: {"type":"step","index":1} // LI.FI route built
data: {"type":"step","index":2} // HBAR settlement executed
data: {"type":"step","index":3} // HCS audit record written
data: {
"type": "done",
"data": {
"success": true,
"parsed": { "humanSummary": "...", "amount": 100, ... },
"lifi": { "flowBuilt": true, "steps": [...], "compiled": true },
"hcs": { "topicId": "0.0.9217982", "sequenceNumber": "42",
"explorerUrl": "https://hashscan.io/testnet/topic/0.0.9217982" },
"payment": { "transactionId": "0.0.9185784@1749812345.000000000",
"amount": "0.001 HBAR",
"explorerUrl": "https://hashscan.io/testnet/transaction/..." }
}
}
// On error:
data: {"type":"error","error":"STAGING_LIQUIDITY_DRY",
"message":"Staging liquidity pool dry — try matching tokens (USDC→USDC).",
"status":500}400Empty or missing intent.422Unsupported token · amount ≤ 0 · unknown name with no explicit address.500 ROUTING_FAILEDLI.FI Composer failed to build or compile the route. HCS records ROUTING_FAILED.500 PAYMENT_FAILEDHBAR transfer failed. HCS records PAYMENT_FAILED.AbortController. If no SSE event arrives for 25s, the request is aborted and the user sees Network congestion detected — please retry.Google Gemini 2.0 Flash
Used as the NL parsing layer. Called only when the keyword engine returns low confidence.
Modelgemini-2.0-flash via @google/generative-aiStructured OutputsresponseMimeType: 'application/json' + responseSchema. No prompt engineering for JSON format — the schema enforces structure.Single-token ruleIf user mentions one token, both fromToken and toToken are set to that token. No invented swap.Fallbackregex-based fallbackParse() activates when GOOGLE_API_KEY is absent. Demo-safe.LI.FI Composer SDK
Builds atomic cross-chain EVM payment flows. ETHGlobal staging endpoint.
Endpointethglobal-composer.li.quest (ETHGlobal-specific staging)toWei()Handles decimals: USDC/USDT=6, ETH/WETH/DAI=18, WBTC=8.Staging limitsPools can be dry for cross-token swaps. Use matching tokens (USDC→USDC) for reliable demo runs.Hedera HCS + HBAR
Zero Solidity. All Hedera interaction via native @hashgraph/sdk.
HCS Topic0.0.9217982 — public, immutable, verifiable on Hashscan.HBAR operator0.0.9185784 — the FlowPay relayer account. Pays all transaction fees.Settlement amount0.001 HBAR for EVM token payments (settlement signal). Up to 1 HBAR for HBAR-native payments.Finality< 3 seconds. Fixed USD fee ~$0.001. No variable gas.ENS via viem
ENS resolution runs on Ethereum mainnet via viem.getEnsAddress().
RPCConfigurable via ETHEREUM_RPC_URL. Defaults to https://cloudflare-eth.com.normalize()viem/ens normalize() applied before lookup — handles unicode names correctly.Auto-suffixPlain names auto-append .eth. "vitalik" → resolves as "vitalik.eth".Production pathSwap hardcoded registry for full ENS + Hedera Name Service lookup.Supported tokens
Use cases
Remittances
Send money home to family in plain language. No exchange account, no FX margin, no wire delays.
Freelance payroll
Pay global contractors in their preferred token. One sentence, cross-chain, permanent audit record.
School fees
International tuition without wire transfers or 3–5% conversion margins.
DAO payouts
Coordinate multi-chain treasury distributions with a tamper-proof audit trail on HCS.
AI agent payments
Autonomous agents can execute payments via a single API call. Intent in → settlement out.
B2B invoicing
Enterprise-to-enterprise cross-border payments with immutable proof of execution.
FAQ
Is this using real funds?
No. FlowPay runs on Hedera Testnet. HBAR transferred has no real monetary value. LI.FI routes are compiled but the wallet signing step is optional and not submitted to mainnet in the demo flow.
Why does FlowPay use Gemini instead of other AI models?
Gemini 2.0 Flash offers Structured Outputs (responseMimeType + responseSchema) which enforces a typed PaymentIntent without prompt engineering for JSON formatting. This is more reliable than asking any model to "return JSON". Also: ETHGlobal Google Cloud track.
What is the keyword engine and when does it skip Gemini?
lib/keyword-parser.ts runs first on every intent. If it finds an explicit amount + token + known recipient (registry name or 0x address), it returns HIGH confidence and the result is used directly. Gemini is never called. For ambiguous or incomplete intents, the keyword engine returns LOW confidence and Gemini handles it.
How does ENS resolution work?
lib/resolver.ts checks the mock registry first (instant). If the name is not found there, it calls viem.getEnsAddress() on Ethereum mainnet. Plain names like "vitalik" are auto-suffixed to "vitalik.eth". If ENS also returns null, the API returns 422 and the UI shows an address input field.
What happens if LI.FI staging has no liquidity?
The SSE stream emits { type: "error", error: "STAGING_LIQUIDITY_DRY" } with a human-readable message suggesting the user try matching tokens (USDC→USDC instead of ETH→USDC). The HCS record is written as ROUTING_FAILED.
Can I run this with my own Hedera account?
Yes. Clone the repo, fill in HEDERA_ACCOUNT_ID and HEDERA_PRIVATE_KEY (ECDSA) in .env.local, and run npm run dev. Leave HEDERA_TOPIC_ID blank on first run — a new HCS topic is auto-created.
What does "No Solidity" mean?
FlowPay uses Hedera's native @hashgraph/sdk for everything: TransferTransaction for HBAR, TopicMessageSubmitTransaction for HCS. No EVM bytecode, no compiled contracts, no Solidity.