# Query Demo

This example demonstrates the current factory APIs in `@ic-reactor/react`
against live ledger canisters:

- `createSuspenseQuery` for static method wrappers
- `createSuspenseQueryFactory` for runtime arguments
- `createMutation` for updates and invalidation
- `DisplayReactor` for UI-friendly string values

## Links

[Open in StackBlitz](https://stackblitz.com/github/b3pay/ic-reactor/tree/main/examples/query-demo?embed=1&theme=dark&file=src/reactor.ts)
  [View on GitHub](https://github.com/b3pay/ic-reactor/tree/main/examples/query-demo)
## Live Preview

<iframe
  src="https://stackblitz.com/github/b3pay/ic-reactor/tree/main/examples/query-demo?embed=1&theme=dark&file=src/reactor.ts&view=preview"
  style="width: 100%; height: 600px; border: 0; border-radius: 8px; overflow: hidden;"
  title="IC Reactor Query Demo"
  allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
  sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
/>

## Key Code

```ts
// An excerpt of src/reactor.ts: the demo also sets up ckBTC and ckETH the same
// way, and formats each token's balance with a `formatBalance` helper
import {
  createMutation,
  createSuspenseQuery,
  createSuspenseQueryFactory,
  defineDisplayReactor,
  formatTokenAmount,
} from "@ic-reactor/react"
import { ledgerIdlFactory, type Ledger } from "./declarations/ledger"

export const { reactor: icpReactor } = defineDisplayReactor<Ledger>({
  name: "icp",
  canisterId: "ryjl3-tyaaa-aaaaa-aaaba-cai",
  idlFactory: ledgerIdlFactory,
  agentOptions: { host: "https://ic0.app" },
})

export const icpNameQuery = createSuspenseQuery(icpReactor, {
  functionName: "icrc1_name",
})

// The balance is e8s as text: formatTokenAmount shifts it by the decimals
export const getIcpBalance = createSuspenseQueryFactory(icpReactor, {
  functionName: "icrc1_balance_of",
  refetchInterval: 5 * 1000, // 5 seconds
  select: (balance) => `${formatTokenAmount(balance, 8)} ICP`,
})

export const icpTransferMutation = createMutation(icpReactor, {
  functionName: "icrc1_transfer",
  // Every ICP balance getIcpBalance has returned, whatever the account: a
  // transfer changes the sender's and the recipient's
  invalidateQueries: [getIcpBalance],
})
```

**Tip:** The example points at mainnet ICP ecosystem ledgers, so it is a good reference
  for reusable query and mutation composition without depending on a local
  replica.