# @fractalshq/sync

Fractals Sync is the all-in-one SDK for the distribution platform. The default `@fractalshq/sync` export points to v2, and v1 is still available via explicit subpaths.

```
@fractalshq/sync          // default v2 surface (claims + tx build only)
@fractalshq/sync/v2       // public v2 surface (claims + tx build only)
@fractalshq/sync/v2/core  // v2 core helpers (build tx + list claims)
@fractalshq/sync/v2/react // v2 React hooks (useClaims, useClaimTransaction)
@fractalshq/sync/v1/core     // shared types + helpers (pure TS)
@fractalshq/sync/v1/server   // Node/Next client that talks to /api/v1
@fractalshq/sync/v1/react    // hooks that assume AuthProvider + wallet context
@fractalshq/sync/v1/widgets  // drop-in UI with its own provider stack
```

Legacy v1 aliases (mapped to v1): `@fractalshq/sync/core`, `@fractalshq/sync/server`, `@fractalshq/sync/react`, `@fractalshq/sync/widgets`.

## Layout

```
packages/sync/
├── src/
│   ├── v1/
│   │   ├── core/      // typed constants, schemas, memo builders
│   │   ├── server/    // moved from @fractalshq/distribution-server
│   │   ├── react/     // hooks + helpers (will absorb old distribution-client work)
│   │   └── widgets/   // claim panels, buttons, etc.
│   └── v2/            // public v2 API surface (claims + tx build)
└── package.json   // exports map for subpaths
```

## V2 (public claims surface)

V2 is intentionally tiny and public-facing. It only exposes:

- `GET /api/v2/claims?wallet=<pubkey>` (claimable + claimed)
- `POST /api/v2/claims/[id]/create-transaction` (build claim tx)

### Core usage

```ts
import { listClaims, buildClaimTransaction } from "@fractalshq/sync/v2/core";

const claims = await listClaims(wallet);
const tx = await buildClaimTransaction({
  distributionId,
  claimant: wallet,
});
```

### React usage

```tsx
import { useClaims, useClaimTransaction } from "@fractalshq/sync/v2/react";

const claimsQuery = useClaims(wallet);
const buildTx = useClaimTransaction();
buildTx.mutateAsync({ distributionId, claimant: wallet });
```

### UI-only flow (bring your own signer)

V2 is build-only: it returns a transaction payload and you wire signing/sending yourself.
Show the signature optimistically, then rely on eventual consistency for history.

```tsx
import { useClaimTransaction } from "@fractalshq/sync/v2/react";

const buildTx = useClaimTransaction();

async function handleClaim(item: { distributorId: string }, wallet: string) {
  const payload = await buildTx.mutateAsync({
    distributionId: item.distributorId,
    claimant: wallet,
  });

  // App-owned: build a Transaction from payload.transaction (base64) or payload.instructions.
  const tx = buildTransactionFromPayload(payload);
  const signed = await signTransaction(tx);
  const signature = await connection.sendRawTransaction(signed.serialize());

  // UI-owned: optimistic link + pending state until the next refresh.
  setOptimisticSignature(signature);
}
```

Notes:
- Default base path is `https://sync.fractals.fun/api/v2` (override via `NEXT_PUBLIC_SYNC_V2_PATH`).
- For other environments, set `NEXT_PUBLIC_SYNC_V2_PATH` to an absolute `/api/v2` base URL.
- V2 requests are `credentials: "omit"` for public CORS mode.
- If `wallet` is omitted, `useClaims` falls back to the Solana wallet adapter context (`@solana/wallet-adapter-react`).

See `docs/distro-sdk.md` and `docs/distribution-sdk-auth-facts.md` for the full design notes / TODOs.
