Skip to Content
DocsFlowsClaim flow

Claim flow

Recipients never touch raw merkle proofs unless you want them to. Sync exposes hosted claim pages, embeddable widgets, and a JS helper so you can keep users inside your product while we take care of proof delivery, wrap/unwrap steps, and subsidized gas.

Sequence

  1. Fetch proof. The client calls GET /sync/distributions/:id/proof?wallet=<pubkey> (or uses the SDK helper). We return { amount, index, merkleProof[], tokenMint }.
  2. Construct claim tx. Our API builds the newClaim instruction, wraps Token-2022 mints if necessary, and quotes the claim subsidy (~$0.50).
  3. User signs once. @fractalshq/auth-react keeps the SIWS session fresh so we can reuse the wallet signature context.
  4. Submission + receipt. We submit the tx, surface status, and log the claim against the cohort for analytics.

Token-2022 handling

  • If the mint is Token-2022-only, Sync uses @fractalshq/token2022-wrapper to wrap the tokens during distribution funding and unwrap them after each claim.
  • Claims include an extra unwrap/burn instruction so the recipient still lands with plain SPL tokens in their ATA.
  • The wrapper rent and execution costs are included in the subsidized claim fee—users only approve one transaction.

Error surface

  • Bad proof / wrong index → we render “Invalid proof” with debugging info for admins (hash mismatch, already claimed).
  • Vesting window not open → we mirror the contract error plus human copy (“check back after 12:00 UTC”).
  • Out of funds → we block further claims, notify the distributor, and suggest funding or clawback.
  • Token account missing → we create the recipient ATA inside the same transaction if they don’t already have one.

SDK helper (draft)

import { useSyncClaims } from "@fractalshq/sync/react"; import { useTxAuth } from "@fractalshq/auth-react"; const { fetchClaimTx } = useSyncClaims(); const { signAndSend } = useTxAuth(); async function claim({ distributionId }) { const { transaction, expectedAmount } = await fetchClaimTx({ distributionId, }); await signAndSend(transaction); console.log(`Claimed ${expectedAmount} tokens`); }
  • fetchClaimTx calls the Sync API, which validates eligibility, generates the claim instruction, attaches the Token-2022 unwrap (when needed), and returns a ready-to-sign transaction.
  • Claims are close to ~$0.50 USD so end-users don’t worry about SOL balances; we settle the difference via monthly invoicing.

Self-serve widget

If you prefer zero-code, drop in the iframe/widget variant:

<SyncClaimWidget distributionId="dist_23" wallet={wallet} />

It handles auth, polls status, and emits events (onClaimed, onError) so you can refresh UI counts.

Last updated on