flare-fdc
v0.1.0
Published
Client for Flare's Data Connector (FDC). Turn an XRPL payment — or a proven non-payment — into a Merkle proof an on-chain verifier accepts, with the indexer-lag retry already handled.
Maintainers
Readme
flare-fdc
A small client for Flare's Data Connector — the protocol that lets a smart contract trustlessly learn that something happened on another chain.
npm install flare-fdc ethersThe FDC is powerful and the flow is fiddly: encode a request against a verifier
server, submit it to FdcHub with the right fee, work out which voting round
carried it, then poll a data-availability endpoint until validators finalize a
Merkle proof. Four steps, two HTTP services, and a voting-round clock.
This package is that flow, extracted from a project that settles real value on it.
Prove a payment happened
import { ethers } from "ethers";
import { Fdc, COSTON2 } from "flare-fdc";
const signer = new ethers.Wallet(PRIVATE_KEY, provider);
const fdc = new Fdc(COSTON2);
// 0x-prefixed 32-byte XRPL transaction hash
const proof = await fdc.proveXrplPayment(signer, xrplTxHash);
// `proof` is abi-encoded IPayment.Proof — hand it straight to your verifier
await escrow.release(escrowId, proof, enclaveSignature);Prove a payment never happened
The FDC's most distinctive capability, and the reason this package exists.
An on-chain timeout proves only that time passed. It cannot tell you whether the payer never paid or whether your relayer simply missed the payment. The FDC can prove, with validator consensus, that no payment carrying a given reference exists on the source chain — a statement no single chain can make about another.
const proof = await fdc.proveXrplNonPayment(signer, {
minimalBlockNumber: 19338965,
deadlineBlockNumber: 19339025,
deadlineTimestamp: 1784932560,
destinationAddressHash, // bytes32
amount: "1", // drops
standardPaymentReference, // bytes32
});
await escrow.refundWithProof(escrowId, proof);That turns a refund from an assumption into something provable.
The retry that matters
Flare's XRPL indexer runs 30–90 seconds behind the ledger. Call
prepareRequest immediately after broadcasting and it fails with "transaction
does not exist" — which reads like your transaction was rejected, when in fact
it simply hasn't been indexed yet.
Three consecutive attestation rounds failed this way during development before the cause was clear. This client retries transient responses automatically and only throws on genuine rejections, so you never have to learn this the way we did.
Tune it if your source chain behaves differently:
const fdc = new Fdc(COSTON2, {
prepare: { attempts: 20, delayMs: 15_000 }, // indexer-lag retry
proof: { attempts: 30, delayMs: 10_000 }, // waiting for finalization
apiKey: process.env.FDC_API_KEY,
});Timing
FDC finality is consensus, not a lookup:
| Step | Duration |
|---|---|
| Indexer lag before prepareRequest succeeds | 30–90s |
| Voting round | ~90s |
| Proof retrieval | ~30s |
| Total | ~4 minutes |
Design your UX around this. It is not a limitation to engineer away — it is what makes the proof worth something.
Lower-level API
The end-to-end helpers are built from parts you can use directly for other attestation types:
const request = await fdc.prepareRequest(path, body); // step 1
const { roundId } = await fdc.submitRequest(signer, request); // step 2
const proof = await fdc.fetchProof(roundId, request); // steps 3–4
const bytes = fdc.encodeProof(MY_PROOF_TYPE, proof);
fdc.roundIdFor(timestamp); // round arithmeticNetworks
COSTON2 ships as a preset because it is the network this has been exercised
on. Mainnet presets are deliberately absent rather than guessed — publishing
an address that has never been used is worse than asking you to supply one:
const fdc = new Fdc({
chainId: 14,
fdcHub: "0x…",
fdcRequestFeeConfigurations: "0x…",
verifierBase: "https://…",
daLayerProofUrl: "https://…",
firstVotingRoundStartTs: 1658430000,
votingEpochDurationSeconds: 90,
});Resolve addresses through Flare's ContractRegistry where you can; it is
authoritative and survives redeployments.
Where this comes from
Extracted from Flint, which settles FXRP against FDC proofs on Coston2 — including a live refund proven by non-occurrence.
MIT.
