Skip to content

Navigation Menu

Sign in
Sign up

Repository files navigation

Harbor

A guaranteed-settlement layer for FXRP redemptions on Flare β€” now with a destination-tag redemption lane.

πŸ† Built for the Flare Summer Signal hackathon. Project submission (BUIDL): dorahacks.io/buidl/46944 .

License TypeScript Node.js pnpm Next.js Solidity Flare Coston2

Harbor sits between an FXRP redeemer and the agent that owes them XRP, ensuring that missed payments automatically trigger FAssets default recovery. Because it never custodies funds, recovered collateral is always paid directly to you.

Live demo harbor-web-olive.vercel.app
Backend API api-production-6f3ec.up.railway.app
Walkthrough β–Ά Watch the new demo video on YouTube

Harbor β€” FXRP redemption console on Flare Coston2

β–Ά Watch the demo video β€” redeem β†’ watch XRPL β†’ settle, or prove non-payment β†’ execute default β†’ recover collateral.

Note: High-res video assets are also available in the repository at assets/loom/video.mp4 (90-second walkthrough) and assets/demo/harbor-demo.mp4 (2-minute product demo).

Features

  • Non-custodial by construction: Harbor acts as the nominated executor. You redeem directly on the AssetManager, so default collateral is paid to you.
  • Two Redemption Lanes:
    • Standard (redeemAmount): Uses the ReferencedPaymentNonexistence proof and HarborRedeemer.executeDefault.
    • Redeem-by-tag (redeemWithTag): For XRPL destinations requiring a tag. Uses the XRP-native XRPPaymentNonexistence proof and HarborRedeemer.executeXrpDefault. (Tag 0 is valid; an empty input uses the standard lane. Automatically disabled if redeemWithTagSupported() is false).
  • No agent selection: FAssets handles agent assignment via FIFO.
  • Permissionless self-recovery: Anyone can complete a stuck default directly from the UI using the pre-built FDC proof bytes.
  • Heuristic reliability scoring: Ranks agents (agent-reliability-mvp-v1) based on fulfillment, speed, availability, and FTSOv2 collateral ratios. Purely informational analytics.
  • Fast XRPL settlement observer: Validates netUnderlyingUBA (valueUBA - feeUBA) and destination tags directly from the ledger.
  • Durable indexing: FAssets indexer recovers events across RPC gaps via a persisted cursor.
  • Zero-config local dev: Everything boots in "mock mode" with local defaults.

Architecture & Lifecycle

Harbor is a Next.js 14 / Node.js 22 pnpm monorepo. The core system operates on the Flare Coston2 testnet.

flowchart LR
 R["Redeemer"] -->|"redeemAmount / redeemWithTag"| AM["FXRP AssetManager"]
 AM -->|"Redemption(WithTag)Requested"| IDX["Indexer"]
 AG["Agent"] -->|"pays XRP (with tag if WITH_TAG)"| XRPL[("XRP Ledger")]
 OBS["XRPL Observer"] -->|"validates payment"| XRPL
 KEEP{"Keeper"} -->|"watch window"| OBS
 KEEP -->|"expired: prove non-payment"| FDC[("Flare Data Connector")]
 FDC -->|"Merkle proof"| KEEP
 KEEP -->|"execute(Xrp)Default"| HR["HarborRedeemer"]
 HR -->|"forward default"| AM
 AM -->|"collateral"| R
Loading

Comprehensive Sequence (Settlement & Recovery)

sequenceDiagram
 autonumber
 actor R as Redeemer / UI
 participant AM as FXRP AssetManager
 participant AG as FAsset Agent
 participant XRPL as XRP Ledger
 participant OBS as XRPL Observer
 participant KEEP as Keeper
 participant API as Read API
 participant FDC as Flare Data Connector
 participant DA as DA Layer
 participant HR as HarborRedeemer
 R->>AM: redeemAmount / redeemWithTag (nominate HarborRedeemer)
 AM-->>API: RedemptionRequested / RedemptionWithTagRequested
 Note over KEEP: status REQUESTED β†’ WATCHING
 AG->>XRPL: pay net underlying XRP (with tag if WITH_TAG)
 loop poll window
 OBS->>XRPL: read agent address
 end
 OBS->>OBS: validate destination, reference, net amount, window, tag
 alt Agent Pays (Settlement)
 OBS-->>API: write settlement receipt
 KEEP->>API: read valid observation
 Note over KEEP: status β†’ SETTLED
 R->>API: GET /redemptions/:id
 else Window Expires (Default Recovery)
 Note over KEEP: window expired, no valid payment β†’ WINDOW_EXPIRED
 alt STANDARD Lane
 KEEP->>FDC: submit ReferencedPaymentNonexistence request
 else WITH_TAG Lane
 KEEP->>FDC: submit XRPPaymentNonexistence request
 end
 Note over KEEP: status β†’ REQUEST_PROOF
 KEEP->>FDC: track voting round to finalization
 KEEP->>DA: retrieve response + Merkle proof
 Note over KEEP: status β†’ PROOF_READY
 alt Keeper Submits Default
 alt STANDARD Lane
 KEEP->>HR: executeDefault(proof, requestId)
 HR->>AM: redemptionPaymentDefault(proof, requestId)
 else WITH_TAG Lane
 KEEP->>HR: executeXrpDefault(proof, requestId)
 HR->>AM: xrpRedemptionPaymentDefault(proof, requestId)
 end
 else Permissionless Self-Recovery (Keeper Offline)
 R->>API: GET /redemptions/:id (fdcProofs[])
 R->>HR: executeDefault / executeXrpDefault (proof, id)
 HR->>AM: redemptionPaymentDefault / xrpRedemptionPaymentDefault
 end
 AM-->>R: collateral to recorded redeemer
 AM-->>HR: return executor fee
 HR-->>KEEP: forward fee to caller
 Note over KEEP: status β†’ DEFAULT_SUBMITTED β†’ RECOVERED
 end
Loading

Keeper State Machine

The keeper evaluates requests deterministically. Front-running it via self-recovery is harmless.

stateDiagram-v2
 [*] --> REQUESTED
 REQUESTED --> WATCHING: window open
 WATCHING --> SETTLED: valid XRPL payment observed
 REQUESTED --> WINDOW_EXPIRED: window already passed
 WATCHING --> WINDOW_EXPIRED: window passed, no payment
 WINDOW_EXPIRED --> REQUEST_PROOF: submit FDC request
 REQUEST_PROOF --> PROOF_READY: voting round finalized
 PROOF_READY --> DEFAULT_SUBMITTED: execute(Xrp)Default sent
 DEFAULT_SUBMITTED --> RECOVERED: default confirmed on-chain
 PROOF_READY --> RECOVERED: default confirmed (front-run harmless)
 SETTLED --> [*]
 RECOVERED --> [*]
 REQUESTED --> FAILED
 WATCHING --> FAILED
 WINDOW_EXPIRED --> FAILED
 REQUEST_PROOF --> FAILED
 PROOF_READY --> FAILED
 DEFAULT_SUBMITTED --> FAILED
 FAILED --> [*]
Loading

Agent Reliability Scoring

Formula (agent-reliability-mvp-v1) clamped to [0, 100]:

fulfillment (≀ 45) = fulfillment_rate Β· 45 (22.5 if no history)
settlement_time (≀ 15) = based on average settlement seconds (fast ≀ 1h, slow β‰₯ 24h)
availability (≀ 20) = from published availability + free lots
collateral (≀ 20) = from agent's collateral ratio (floor 120% ... full 200%)
default_penalty (≀ 20) = min(defaults Β· 5, 20) (subtracted)

Scores are heuristic and never influence the protocol's FIFO agent assignment. Identity data (name, icon) is parsed directly from AgentOwnerRegistry.

Build on Harbor

Public, GET-only API providing read-only access to reliability and settlement status:

  • GET /agents?asset=FXRP β€” Heuristic agent leaderboard
  • GET /redemptions/:id β€” Evidence-based timeline

Drop-in Integrations:

  • integration/harbor-widget.html: Zero-dependency embeddable leaderboard.
  • integration/HarborAgentReliability.tsx: Configurable React component.
  • See integration/INTEGRATION.md for full field definitions.

Getting Started (Development)

Requires Node.js 22+, pnpm 10, and Foundry (for contract checks).

pnpm install
cp .env.example .env
pnpm --filter @harbor/api dev # Starts API on :3001
pnpm --filter @harbor/web dev # Starts Next.js console on :3000
pnpm check # Format, typecheck, forge test

Component Toggles (Backend)

Configured via .env defaults:

  • HARBOR_RUN_API (on)
  • HARBOR_RUN_MIGRATIONS (on)
  • HARBOR_RUN_INDEXER, HARBOR_RUN_XRPL_OBSERVER, HARBOR_RUN_AGENT_REFRESH, HARBOR_RUN_KEEPER (off)

Tests

  • Foundry (Contracts): pnpm check:contracts (3 suites)
  • API (node:test): pnpm test in @harbor/api (16 suites)
  • Web (Vitest): pnpm test in @harbor/web (19 suites)
  • E2E (Playwright): pnpm test:e2e in @harbor/web (7 suites)
  • Live Coston2 E2E: Located in test/e2e (harbor-e2e.ts, harbor-tag-e2e.ts)

On-chain Deployment (Coston2)

HarborRedeemer requires Solidity 0.8.25 and exposes a secure receive() hook, executeDefault, and executeXrpDefault to forward the respective proofs and refund fees. It resolves AssetManagerFXRP on initialization.

# Broadcast deployment
RPC_URL_COSTON2=... DEPLOYER_PRIVATE_KEY=... KEEPER_EXECUTOR_ADDRESS=... pnpm deploy:harbor:coston2
# Regen ABIs
pnpm protocol:generate-harbor-abi

Deployed Addresses:

  • HarborRedeemer: 0x82f39361FFb1a438e4EBF8025efa06e4511b02b5
  • FXRP AssetManager: 0xc1Ca88b937d0b528842F95d5731ffB586f4fbDFA
  • FXRP Token (FTestXRP): 0x0b6A3645c240605887a5532109323A3E12273dc7

License

Licensed under Apache 2.0.

About

Guaranteed-settlement layer, heuristic agent reputation, and non-custodial automated default recovery for FXRP redemptions on Flare (FAssets).

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /