Inspiration

Online marketplaces always run into the same trust problem: buyers do not want to pay before goods arrive, and sellers do not want to ship before they are paid. Traditional escrow helps, but it adds delays, fees, and manual overhead. Crypto escrow improves speed, but it is still mostly all-or-nothing: one large payment released at the very end, with no way to reward sellers progressively as they fulfill an order.

We wanted to rethink escrow entirely. Instead of building a better static escrow, we built a smarter one a payment system that understands the real-world lifecycle of shipping and releases funds incrementally as trust is earned.

We also noticed that operating a marketplace payment pipeline creates constant overhead for every participant. Buyers need to track orders and file disputes. Sellers need to confirm labels and monitor payouts. Admins need to spot fraud and watch platform health. Rather than building more dashboards, we built AI agents for each role.

What it does

Flow State is a drop-in payment gateway (@shivanshshrivas/flowstate) that adds blockchain escrow checkout to any e-commerce platform. It ships as an npm package with React components, a Node.js webhook handler, and three AI agents that automate operational workflows for buyers, sellers, and admins.

Core mechanic: Streaming Escrow

When a buyer checks out, funds are locked in a smart contract escrow on the XRPL EVM Sidechain. Instead of releasing the full payment only after delivery, funds are streamed to the seller across five milestones as the shipment progresses.

This creates a trust-aware payout model where sellers are rewarded incrementally for fulfillment, while buyers still retain protection if something goes wrong.

If a dispute is filed:

  • remaining funds are frozen,
  • the order branches into a dispute-resolution flow,
  • the seller gets a 72-hour response window, and
  • if the seller times out, the buyer is automatically refunded.

Three AI agents via Pinata OpenClaw

We built three role-based AI agents, each hosted as an OpenClaw container on Pinata. Every agent has five custom skills pinned to IPFS as folders, and the agent fetches its skill code directly from its IPFS CID at runtime.

BuyerAgent — friendly shopping assistant

Skills:

  • order-status
  • track-shipment
  • file-dispute
  • get-receipt
  • list-my-orders

The BuyerAgent can autonomously help users track orders, retrieve receipts, and file disputes with supporting evidence using live order context.

SellerAgent — operations assistant

Skills:

  • list-orders
  • get-metrics
  • confirm-label
  • respond-dispute
  • get-payouts

The SellerAgent helps sellers manage fulfillment, monitor payouts, and proactively surfaces orders that need action or dispute responses before deadlines are missed.

AdminAgent — platform analyst

Skills:

  • get-analytics
  • list-sellers
  • flagged-sellers
  • webhook-logs
  • gas-report

The AdminAgent leads with metrics, identifies anomalies, and highlights sellers with elevated dispute rates or suspicious platform activity.

Security model for the agents

Each agent is security-hardened with a message prefix in the form:

[SYSTEM_CONTEXT: user_id=<id>, role=<role>]

The model is explicitly instructed to trust only this authoritative context for all skill calls. This prevents prompt injection or social engineering attempts from tricking the agent into accessing another user’s data.

How we built it

Smart contracts

Stack: Solidity, XRPL EVM Sidechain

We built four contracts:

  • FLUSD.sol — an ERC-20 token simulating RLUSD for testnet use
  • EscrowStateMachine.sol — the core finite-state machine and partial-release payout logic
  • DisputeResolver.sol — manages dispute creation, response windows, and outcomes

The contracts were deployed to the XRPL EVM Testnet on chain ID 1449000.

Backend API

Stack: Node.js, TypeScript, PostgreSQL

The backend handles:

  • orders,
  • shipping,
  • disputes,
  • sellers,
  • platform analytics, and
  • the agent proxy endpoint.

We used Shippo sandbox for rate shopping, label generation, and tracking webhooks. We used the Pinata SDK to pin invoices, labels, and dispute evidence to IPFS. Their CIDs are stored in PostgreSQL and referenced in contract events.

Pinata OpenClaw agents

We created 15 skill packages total — 5 per agent — and uploaded them to IPFS as Pinata folders.

Each skill contains:

  • an index.js
  • a SKILL.md

Each skill makes typed HTTP calls to our backend API and passes the caller’s user ID in the X-Caller-User-Id header for audit logging.

Secrets such as:

  • the OpenRouter API key,
  • the Flow State API key, and
  • the backend URL

are stored in Pinata Secrets Vault and injected as environment variables at container runtime.

Model used: nvidia/nemotron-3-nano-30b-a3b via OpenRouter with a 256K context window

Demo store

Stack: Next.js 16, Tailwind CSS v4, RainbowKit, wagmi, Supabase Auth

We built a full e-commerce storefront to demonstrate the complete buyer → seller → admin lifecycle.

Pages include:

  • home / product listing
  • product detail with <PayButton />
  • cart
  • order history
  • order tracking
  • seller dashboard
  • admin dashboard
  • FLUSD/XRP faucet page

Role-based access control is handled through Supabase Auth, with the role stored in user metadata.

Challenges we ran into

Per-user session isolation for agents

Pinata OpenClaw uses a single session key per agent by default, which would have caused all users to share conversation history.

We solved this by having the backend inject a per-user session key in the WebSocket handshake frame using the format:

user:<userId>

This isolated each user’s conversation state and prevented cross-user context leakage.

Streaming payouts with milestone verification

Mapping Shippo webhook statuses such as:

  • pre_transit
  • in_transit
  • delivered

onto our seven contract states required careful handling of:

  • out-of-order events,
  • duplicate webhooks, and
  • Shippo sandbox test tracking numbers.

This was one of the trickiest parts of the whole system because the payment state machine needed to stay deterministic and secure even when external shipping events arrived imperfectly.

RLUSD testnet availability

RLUSD is a real Ripple-issued stablecoin and does not currently have a public testnet faucet.

To keep development moving, we deployed MockRLUSD, our own ERC-20 on XRPL EVM testnet, with a public faucet.

Because the escrow system interacts through the standard ERC-20 interface, moving to real RLUSD on mainnet only requires swapping the token address — no contract logic changes.

Accomplishments that we're proud of

  • Built a complete end-to-end flow from wallet connection → streaming escrow → agent-assisted dispute handling → automatic resolution on XRPL EVM testnet
  • Created 15 IPFS-pinned skill packages with typed API contracts, making each agent capability self-contained, auditable, and modular
  • Designed a strong multi-tenant AI security architecture using SYSTEM_CONTEXT injection, per-user session isolation, and X-Caller-User-Id audit headers
  • Built a genuinely drop-in npm package — our demo store only imports from @/lib/flowstate, making migration to the published package a simple path swap

What we learned

Building AI agents that are both useful and safe requires authorization at every layer.

LLM instruction-following is not a security boundary by itself. Identity and access control have to be enforced in multiple places:

  • at the transport layer through session keys,
  • in the prompt through authoritative system context,
  • and in the API through bearer authentication and user ID audit headers.

Any single layer on its own is insufficient.

We also learned that Pinata’s IPFS infrastructure is a surprisingly natural fit for agent skills. Because each skill is content-addressed by CID, its behavior becomes auditable, immutable, and easy to version.

What's next for Flow State

  • Publish @flowstate/gateway to npm with full TypeScript support
  • Launch a simpler L1-native escrow mode for merchants who do not need multi-milestone payouts
  • Deploy to mainnet — the contracts are already production-ready, so moving from testnet is largely a configuration change

Built With

Share this project:

Updates