[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-sui-frontend-apps":3,"mdc--d40abd-key":42,"related-org-sui-frontend-apps":2494,"related-repo-sui-frontend-apps":2655},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":31,"repoUrl":32,"updatedAt":33,"license":34,"forks":35,"topics":36,"repo":37,"sourceUrl":40,"mdContent":41},"frontend-apps","build Sui dApps with dapp-kit","Sui frontend \u002F dApp development with @mysten\u002Fdapp-kit-react (React) and @mysten\u002Fdapp-kit-core (Vue, vanilla JS, Svelte, Web Components, other frameworks). Use when building browser apps that connect Sui wallets, query on-chain state, or submit transactions. Covers wallet connection, network switching, transaction execution, query patterns with TanStack React Query, and the specific pitfalls of browser + wallet + async-indexer environments. Pair with the `sui-sdks` skill for @mysten\u002Fsui Transaction construction patterns and the `ptbs` skill for PTB semantics.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"sui","Sui (Mysten Labs)","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fsui.png","MystenLabs",[13,17,19,22,25,28],{"name":14,"slug":15,"type":16},"React","react","tag",{"name":18,"slug":8,"type":16},"Sui",{"name":20,"slug":21,"type":16},"Vue","vue",{"name":23,"slug":24,"type":16},"Svelte","svelte",{"name":26,"slug":27,"type":16},"Web3","web3",{"name":29,"slug":30,"type":16},"Frontend","frontend",9,"https:\u002F\u002Fgithub.com\u002FMystenLabs\u002Fskills","2026-08-01T05:44:28.958473",null,2,[],{"repoUrl":32,"stars":31,"forks":35,"topics":38,"description":39},[],"Sui development skills maintained by Mysten Labs","https:\u002F\u002Fgithub.com\u002FMystenLabs\u002Fskills\u002Ftree\u002FHEAD\u002Ffrontend-apps","---\nname: frontend-apps\ndescription: >\n  Sui frontend \u002F dApp development with @mysten\u002Fdapp-kit-react (React) and\n  @mysten\u002Fdapp-kit-core (Vue, vanilla JS, Svelte, Web Components, other\n  frameworks). Use when\n  building browser apps that connect Sui wallets, query on-chain state, or\n  submit transactions. Covers wallet connection, network switching, transaction\n  execution, query patterns with TanStack React Query, and the specific\n  pitfalls of browser + wallet + async-indexer environments. Pair with the\n  `sui-sdks` skill for @mysten\u002Fsui Transaction construction patterns and the\n  `ptbs` skill for PTB semantics.\n---\n\n# Sui Frontend \u002F dApp Kit\n\n> **MCP tool:** When available in your environment, also query the Sui documentation MCP server (`https:\u002F\u002Fsui.mcp.kapa.ai`) for up-to-date answers. Use it for verification and for details not covered by these reference files.\n\nBrowser Sui apps fail for a consistent set of reasons:\n\n1. **Wrong package.** `@mysten\u002Fdapp-kit` (no suffix) is the legacy JSON-RPC-only package — **deprecated**. New code uses `@mysten\u002Fdapp-kit-react` or `@mysten\u002Fdapp-kit-core`.\n2. **Wrong client.** dApp Kit takes a `SuiGrpcClient` (recommended) in `createDAppKit`'s `createClient`. Do not pass `SuiJsonRpcClient` — JSON-RPC is deprecated.\n3. **Old provider stack.** Code often tries the v1 pattern: `QueryClientProvider` → `SuiClientProvider` → `WalletProvider`. That's gone. New pattern: `createDAppKit` factory + `DAppKitProvider` (or a non-React equivalent).\n4. **Dead hooks.** `useSuiClientQuery`, `useSuiClientInfiniteQuery`, `useSignAndExecuteTransaction` (mutation hook), `useConnectWallet`, `useDisconnectWallet`, `useSuiClient`, `useSuiClientContext` — **removed**. Replaced by `useCurrentClient` \u002F `useCurrentNetwork` \u002F `useDAppKit()` (imperative methods) + your own TanStack Query wrappers.\n5. **Skipping `waitForTransaction` between execute and refetch.** Fullnodes index transactions asynchronously — invalidating TanStack caches immediately after `signAndExecuteTransaction` refetches stale data.\n6. **Building PTBs in app code with `tx.build()` before handing to the wallet.** Defeats the wallet's gas selection. Always pass the `Transaction` instance (or `tx.serialize()`) to the wallet.\n\nAll patterns in this skill are derived from:\n- https:\u002F\u002Fsdk.mystenlabs.com\u002Fdapp-kit (landing)\n- https:\u002F\u002Fsdk.mystenlabs.com\u002Fdapp-kit\u002Fgetting-started\u002Freact\n- https:\u002F\u002Fsdk.mystenlabs.com\u002Fdapp-kit\u002Fgetting-started\u002Fnext-js\n- https:\u002F\u002Fsdk.mystenlabs.com\u002Fdapp-kit\u002Fgetting-started\u002Fvue\n- https:\u002F\u002Fdocs.sui.io\u002Fstandards\u002Fwallet-standard\n\nIf unsure about any API, fetch from the relevant page — do not extrapolate from the legacy `@mysten\u002Fdapp-kit` or the pre-v2 hook surface. Many outdated tutorials exist.\n\n---\n\n## Reference files\n\n### setup — Install, factory, provider\n**Path:** `setup.md`\n**Load when:** starting a new dApp project, scaffolding React\u002FNext.js\u002FVue setup, or migrating from the old three-provider pattern. Covers package choice, `createDAppKit({ networks, createClient })`, `DAppKitProvider` (React), and the `declare module` TypeScript augmentation.\n\n### react — React hooks & patterns\n**Path:** `react.md`\n**Load when:** writing React components. Covers every current hook (`useCurrentAccount`, `useCurrentWallet`, `useCurrentNetwork`, `useCurrentClient`, `useDAppKit`, `useWallets`, `useWalletConnection`), standard components (`ConnectButton`), and wallet-gated UI idioms.\n\n### non-react — Vue, vanilla JS, Web Components\n**Path:** `non-react.md`\n**Load when:** building Vue \u002F Svelte \u002F vanilla JS dApps. Covers `@mysten\u002Fdapp-kit-core`, nanostores reactive state (`dAppKit.stores.$connection` etc.), Web Components registration, Vue bindings via `@nanostores\u002Fvue`.\n\n### queries — TanStack Query patterns\n**Path:** `queries.md`\n**Load when:** fetching on-chain data (balances, owned objects, coins, dynamic fields, transactions) in a dApp. Covers `useQuery` + `useCurrentClient`, `useInfiniteQuery` for paginated results, `enabled` guards, and cache invalidation after writes.\n\n### transactions — Signing and executing\n**Path:** `transactions.md`\n**Load when:** submitting any transaction from a dApp. Covers `dAppKit.signAndExecuteTransaction`, the `$kind`-based result discriminant, `signTransaction` (wallet signs but doesn't execute — for sponsored flows), `signPersonalMessage`, the `waitForTransaction` + `invalidateQueries` sequence, and common wallet UX failures.\n\n### limitations — What frontends can't or shouldn't do\n**Path:** `limitations.md`\n**Load when:** a user is designing something that feels like it crosses a browser-environment boundary. Covers: no backend-only features (gas station internals, validator keys), browser\u002FSSR caveats, auto-connect reliability, and the \"don't put secrets in the browser\" rules.\n\n## Routing guide\n\n| Task | Load |\n|------|------|\n| New React dApp from scratch | setup + react + queries + transactions |\n| New Vue \u002F vanilla \u002F Svelte dApp | setup + non-react |\n| \"How do I connect a wallet?\" | react (or non-react) |\n| \"How do I query a balance \u002F owned objects?\" | queries |\n| \"How do I send a transaction?\" | transactions + (sui-sdks for PTB construction) |\n| Sponsored tx flow | transactions (front-end side) + ptbs (PTB side) |\n| Migrating from `@mysten\u002Fdapp-kit` (no suffix) | setup + limitations + all as needed |\n| Why is my UI stale after a tx? | transactions + queries |\n| Dealing with SSR \u002F Next.js | setup + limitations |\n| Full code review of a dApp | **all reference files** + the code-review checklist below |\n| \"Review this code\" \u002F \"what's wrong with this snippet\" | the code-review checklist below + relevant reference files |\n\n## Skill Content\n\n### Key concepts\n\n- **Two packages, one API.** `@mysten\u002Fdapp-kit-react` wraps `@mysten\u002Fdapp-kit-core`. `createDAppKit` exists in both; actions (`signAndExecuteTransaction`, `signTransaction`, `switchNetwork`, `connectWallet`, `disconnectWallet`) are identical. What differs is how you read reactive state: React uses hooks; non-React reads nanostores stores.\n- **One instance, many networks.** `createDAppKit({ networks: [...], createClient })` creates one dApp Kit instance that knows about multiple networks. `dAppKit.switchNetwork(name)` changes the active one. The `createClient` factory is called once per network, lazily.\n- **gRPC by default.** The new dApp Kit is built for `SuiGrpcClient`. JSON-RPC is deprecated; use `SuiGrpcClient` in `createClient`.\n- **Wallets are browser-only.** Wallet detection uses `window.navigator.wallets` and CustomEvents. Any component that touches wallet state must be client-side rendered. In Next.js \u002F SSR frameworks this means `'use client'` on wallet-aware components.\n- **The wallet owns gas.** Apps build the `Transaction` and pass it to the wallet. The wallet picks gas coins, sets budget (via dry-run), and signs. Never call `tx.build()` + pass bytes unless it's a sponsored flow — see `transactions.md`.\n- **Fullnodes are eventually consistent.** `signAndExecuteTransaction` returns a digest before the data is queryable. Always `waitForTransaction` before refetching.\n\n### Rules\n\n1. **Use `@mysten\u002Fdapp-kit-react` or `@mysten\u002Fdapp-kit-core`** — never the bare `@mysten\u002Fdapp-kit` in new code. That package is JSON-RPC-only and deprecated.\n2. **Use `SuiGrpcClient` in `createClient`.** Not `SuiClient` — `SuiClient` is removed in v2; use `SuiGrpcClient` from `@mysten\u002Fsui\u002Fgrpc`.\n3. **Use `createDAppKit` + `DAppKitProvider`.** Not the three-provider stack (`QueryClientProvider` + `SuiClientProvider` + `WalletProvider`). You still wrap with `QueryClientProvider` if you use TanStack Query for data fetching, but dApp Kit itself doesn't need it.\n4. **Include the `declare module` TypeScript augmentation** so hooks get proper types without passing the instance manually.\n5. **Do not use the removed hooks.** `useSuiClientQuery` \u002F `useSuiClientInfiniteQuery` \u002F `useSuiClientContext` \u002F `useSuiClient` \u002F `useSignAndExecuteTransaction` (mutation hook) \u002F `useConnectWallet` \u002F `useDisconnectWallet` — gone. Use `useCurrentClient` + `useQuery`\u002F`useInfiniteQuery` + `useDAppKit()` imperative methods.\n6. **Null-check the current account.** `useCurrentAccount()` returns `null` before connection. Always `if (!account) return` \u002F gate with `enabled: !!account` in queries.\n7. **`waitForTransaction` before cache invalidation.** `await client.waitForTransaction({ digest: result.Transaction.digest })` then `queryClient.invalidateQueries(...)`. Reversing this fetches stale data.\n8. **Pass the `Transaction` instance (or `tx.serialize()`) to the wallet, not `await tx.build(...)` bytes.** The wallet needs to own gas selection. Exception: sponsored flows that use `tx.build({ client, onlyTransactionKind: true })` — see `ptbs` skill.\n9. **Check `result.$kind === 'FailedTransaction'` (or `result.FailedTransaction`).** Don't assume success. Don't use v1's `result.effects?.status?.status`.\n10. **Wallet-gated UI must client-render.** SSR without a client-side guard renders wallet buttons before wallets are detectable. Use `'use client'` \u002F dynamic imports \u002F effect-based hydration.\n11. **Vue: `useStore` returns a Vue ref — use `.value` in script code.** `const connection = useStore(dAppKit.stores.$connection)` returns a ref. Access state as `connection.value.account` in `\u003Cscript setup>`. Vue auto-unwraps refs in templates, but always show the `.value` pattern in script examples.\n\n### Code-review checklist\n\nWhen the user asks you to review a code snippet, do not stop at the first 2–3 issues you spot. Walk this checklist explicitly and call out **every** match. Browser Sui code typically has 5–10 issues stacked in a single component because it was copied from a v1 tutorial.\n\n**Imports \u002F packages**\n- `@mysten\u002Fsui.js` (anywhere) — frozen v1 package; replace with `@mysten\u002Fsui`.\n- `@mysten\u002Fdapp-kit` (no suffix) — deprecated JSON-RPC-only package; replace with `@mysten\u002Fdapp-kit-react` (React) or `@mysten\u002Fdapp-kit-core` (other frameworks).\n- `import { ConnectButton } from '@mysten\u002Fdapp-kit-react'` — wrong path; `ConnectButton` and `ConnectModal` are exported from `@mysten\u002Fdapp-kit-react\u002Fui`. Using the wrong path causes a silent white screen.\n- `import { SuiClient }` — `SuiClient` is removed in v2 — use `SuiGrpcClient` from `@mysten\u002Fsui\u002Fgrpc` (or `useCurrentClient()` inside components).\n- `import { TransactionBlock }` — renamed to `Transaction` in v2.\n\n**Removed hooks (any of these = bug)**\n- `useSuiClientQuery`, `useSuiClientInfiniteQuery`, `useSuiClientContext`, `useSuiClient` — replace with `useCurrentClient()` + TanStack `useQuery` \u002F `useInfiniteQuery`.\n- `useSignAndExecuteTransaction` (mutation hook) — replace with `useDAppKit().signAndExecuteTransaction(...)` called imperatively in event handlers.\n- `useConnectWallet`, `useDisconnectWallet` — replace with `useDAppKit().connectWallet()` \u002F `disconnectWallet()`.\n\n**Provider stack**\n- `SuiClientProvider` + `WalletProvider` (the v1 three-provider stack) — replace with `createDAppKit(...)` + `\u003CDAppKitProvider>`. `QueryClientProvider` from TanStack is still allowed.\n\n**Client construction inside components**\n- `new SuiClient(...)` \u002F `new SuiGrpcClient(...)` inside a component body — breaks network switching and re-creates a client per render. Use `useCurrentClient()`.\n- Missing `enabled: !!account` on queries that need a connected wallet — fires on undefined owner and errors.\n\n**Transaction construction**\n- `tx.pure(value)` (untyped) — replace with the typed helper matching the Move type: `tx.pure.u64(n)`, `tx.pure.address(addr)`, `tx.pure.string(s)`, etc.\n- `tx.build()` before handing to the wallet — defeats wallet gas selection. Pass the `Transaction` instance (or `tx.serialize()`).\n\n**Execute \u002F wait \u002F status**\n- `signAndExecuteTransactionBlock(...)` (v1 method) — replace with `signAndExecuteTransaction(...)`.\n- `{ transactionBlock: tx }` parameter shape — replace with `{ transaction: tx }`.\n- `result.effects?.status?.status === 'success'` — v1 shape; replace with `result.$kind !== 'FailedTransaction'` (or check `result.FailedTransaction`).\n- `result.digest` direct access — on success the digest is at `result.Transaction.digest`; on failure there's no digest.\n- Cache invalidation immediately after execute — must `await client.waitForTransaction({ digest })` first, then `queryClient.invalidateQueries(...)`.\n\n**SSR \u002F Next.js**\n- Wallet-aware component without `'use client'` — wallet detection uses browser-only APIs.\n\nAfter walking the list, count the distinct issues you found. If it's fewer than 5 on a typical multi-line snippet pulled from an outdated tutorial, re-read the snippet — you almost certainly missed something.\n\n### Common mistakes\n\n- **Using `@tanstack\u002Freact-query`'s `useQuery` without `enabled: !!account`** for queries that require a connected wallet. The query fires with undefined owner and errors.\n- **Returning a `Transaction` from a React-Query `queryFn`.** Transactions aren't queries — use them in mutations or event handlers via `useDAppKit()`.\n- **`dAppKit.signAndExecuteTransaction({ transactionBlock: tx })`.** It's `{ transaction: tx }` in the new API.\n- **Reading `result.digest` directly.** On success the digest is at `result.Transaction.digest`. On failure there's no digest — check `result.FailedTransaction` first.\n- **Invalidating queries before `waitForTransaction`.** Classic stale-UI bug. Always wait first.\n- **Calling `new SuiGrpcClient(...)` inside components.** Breaks network switching. Use `useCurrentClient()`.\n- **Instantiating `SuinsClient` \u002F `DeepBookClient` directly.** Use `client.$extend(suins(), deepbook({ address }))` on the client returned from `createClient`.\n- **Leaving `autoConnect: true` with a confusing UX.** Auto-reconnect restores the last wallet on load. If the app handles permissions\u002Fnonces, account for the async nature of that restore (pending \u002F reconnecting states).\n- **Hardcoding testnet \u002F mainnet URLs in multiple places.** Keep them in a single `GRPC_URLS` map keyed by network name and reference from `createClient`.\n- **Using wallet-standard APIs directly.** dApp Kit wraps the wallet standard — don't call `window.navigator.wallets` yourself; use `useWallets()` \u002F `dAppKit.stores.$wallets`.\n- **Storing private keys or secrets in the browser.** Never. dApps sign via wallets; backends hold keys.\n",{"data":43,"body":44},{"name":4,"description":6},{"type":45,"children":46},"root",[47,56,81,86,373,378,431,443,447,454,461,505,511,587,593,635,641,691,697,762,768,788,794,977,983,989,1197,1203,1649,1655,1667,1675,1809,1817,1914,1922,1962,1970,2009,2017,2075,2083,2185,2193,2208,2213,2219],{"type":48,"tag":49,"props":50,"children":52},"element","h1",{"id":51},"sui-frontend-dapp-kit",[53],{"type":54,"value":55},"text","Sui Frontend \u002F dApp Kit",{"type":48,"tag":57,"props":58,"children":59},"blockquote",{},[60],{"type":48,"tag":61,"props":62,"children":63},"p",{},[64,70,72,79],{"type":48,"tag":65,"props":66,"children":67},"strong",{},[68],{"type":54,"value":69},"MCP tool:",{"type":54,"value":71}," When available in your environment, also query the Sui documentation MCP server (",{"type":48,"tag":73,"props":74,"children":76},"code",{"className":75},[],[77],{"type":54,"value":78},"https:\u002F\u002Fsui.mcp.kapa.ai",{"type":54,"value":80},") for up-to-date answers. Use it for verification and for details not covered by these reference files.",{"type":48,"tag":61,"props":82,"children":83},{},[84],{"type":54,"value":85},"Browser Sui apps fail for a consistent set of reasons:",{"type":48,"tag":87,"props":88,"children":89},"ol",{},[90,132,174,222,313,339],{"type":48,"tag":91,"props":92,"children":93},"li",{},[94,99,101,107,109,114,116,122,124,130],{"type":48,"tag":65,"props":95,"children":96},{},[97],{"type":54,"value":98},"Wrong package.",{"type":54,"value":100}," ",{"type":48,"tag":73,"props":102,"children":104},{"className":103},[],[105],{"type":54,"value":106},"@mysten\u002Fdapp-kit",{"type":54,"value":108}," (no suffix) is the legacy JSON-RPC-only package — ",{"type":48,"tag":65,"props":110,"children":111},{},[112],{"type":54,"value":113},"deprecated",{"type":54,"value":115},". New code uses ",{"type":48,"tag":73,"props":117,"children":119},{"className":118},[],[120],{"type":54,"value":121},"@mysten\u002Fdapp-kit-react",{"type":54,"value":123}," or ",{"type":48,"tag":73,"props":125,"children":127},{"className":126},[],[128],{"type":54,"value":129},"@mysten\u002Fdapp-kit-core",{"type":54,"value":131},".",{"type":48,"tag":91,"props":133,"children":134},{},[135,140,142,148,150,156,158,164,166,172],{"type":48,"tag":65,"props":136,"children":137},{},[138],{"type":54,"value":139},"Wrong client.",{"type":54,"value":141}," dApp Kit takes a ",{"type":48,"tag":73,"props":143,"children":145},{"className":144},[],[146],{"type":54,"value":147},"SuiGrpcClient",{"type":54,"value":149}," (recommended) in ",{"type":48,"tag":73,"props":151,"children":153},{"className":152},[],[154],{"type":54,"value":155},"createDAppKit",{"type":54,"value":157},"'s ",{"type":48,"tag":73,"props":159,"children":161},{"className":160},[],[162],{"type":54,"value":163},"createClient",{"type":54,"value":165},". Do not pass ",{"type":48,"tag":73,"props":167,"children":169},{"className":168},[],[170],{"type":54,"value":171},"SuiJsonRpcClient",{"type":54,"value":173}," — JSON-RPC is deprecated.",{"type":48,"tag":91,"props":175,"children":176},{},[177,182,184,190,192,198,199,205,207,212,214,220],{"type":48,"tag":65,"props":178,"children":179},{},[180],{"type":54,"value":181},"Old provider stack.",{"type":54,"value":183}," Code often tries the v1 pattern: ",{"type":48,"tag":73,"props":185,"children":187},{"className":186},[],[188],{"type":54,"value":189},"QueryClientProvider",{"type":54,"value":191}," → ",{"type":48,"tag":73,"props":193,"children":195},{"className":194},[],[196],{"type":54,"value":197},"SuiClientProvider",{"type":54,"value":191},{"type":48,"tag":73,"props":200,"children":202},{"className":201},[],[203],{"type":54,"value":204},"WalletProvider",{"type":54,"value":206},". That's gone. New pattern: ",{"type":48,"tag":73,"props":208,"children":210},{"className":209},[],[211],{"type":54,"value":155},{"type":54,"value":213}," factory + ",{"type":48,"tag":73,"props":215,"children":217},{"className":216},[],[218],{"type":54,"value":219},"DAppKitProvider",{"type":54,"value":221}," (or a non-React equivalent).",{"type":48,"tag":91,"props":223,"children":224},{},[225,230,231,237,239,245,246,252,254,260,261,267,268,274,275,281,283,288,290,296,298,304,305,311],{"type":48,"tag":65,"props":226,"children":227},{},[228],{"type":54,"value":229},"Dead hooks.",{"type":54,"value":100},{"type":48,"tag":73,"props":232,"children":234},{"className":233},[],[235],{"type":54,"value":236},"useSuiClientQuery",{"type":54,"value":238},", ",{"type":48,"tag":73,"props":240,"children":242},{"className":241},[],[243],{"type":54,"value":244},"useSuiClientInfiniteQuery",{"type":54,"value":238},{"type":48,"tag":73,"props":247,"children":249},{"className":248},[],[250],{"type":54,"value":251},"useSignAndExecuteTransaction",{"type":54,"value":253}," (mutation hook), ",{"type":48,"tag":73,"props":255,"children":257},{"className":256},[],[258],{"type":54,"value":259},"useConnectWallet",{"type":54,"value":238},{"type":48,"tag":73,"props":262,"children":264},{"className":263},[],[265],{"type":54,"value":266},"useDisconnectWallet",{"type":54,"value":238},{"type":48,"tag":73,"props":269,"children":271},{"className":270},[],[272],{"type":54,"value":273},"useSuiClient",{"type":54,"value":238},{"type":48,"tag":73,"props":276,"children":278},{"className":277},[],[279],{"type":54,"value":280},"useSuiClientContext",{"type":54,"value":282}," — ",{"type":48,"tag":65,"props":284,"children":285},{},[286],{"type":54,"value":287},"removed",{"type":54,"value":289},". Replaced by ",{"type":48,"tag":73,"props":291,"children":293},{"className":292},[],[294],{"type":54,"value":295},"useCurrentClient",{"type":54,"value":297}," \u002F ",{"type":48,"tag":73,"props":299,"children":301},{"className":300},[],[302],{"type":54,"value":303},"useCurrentNetwork",{"type":54,"value":297},{"type":48,"tag":73,"props":306,"children":308},{"className":307},[],[309],{"type":54,"value":310},"useDAppKit()",{"type":54,"value":312}," (imperative methods) + your own TanStack Query wrappers.",{"type":48,"tag":91,"props":314,"children":315},{},[316,329,331,337],{"type":48,"tag":65,"props":317,"children":318},{},[319,321,327],{"type":54,"value":320},"Skipping ",{"type":48,"tag":73,"props":322,"children":324},{"className":323},[],[325],{"type":54,"value":326},"waitForTransaction",{"type":54,"value":328}," between execute and refetch.",{"type":54,"value":330}," Fullnodes index transactions asynchronously — invalidating TanStack caches immediately after ",{"type":48,"tag":73,"props":332,"children":334},{"className":333},[],[335],{"type":54,"value":336},"signAndExecuteTransaction",{"type":54,"value":338}," refetches stale data.",{"type":48,"tag":91,"props":340,"children":341},{},[342,355,357,363,365,371],{"type":48,"tag":65,"props":343,"children":344},{},[345,347,353],{"type":54,"value":346},"Building PTBs in app code with ",{"type":48,"tag":73,"props":348,"children":350},{"className":349},[],[351],{"type":54,"value":352},"tx.build()",{"type":54,"value":354}," before handing to the wallet.",{"type":54,"value":356}," Defeats the wallet's gas selection. Always pass the ",{"type":48,"tag":73,"props":358,"children":360},{"className":359},[],[361],{"type":54,"value":362},"Transaction",{"type":54,"value":364}," instance (or ",{"type":48,"tag":73,"props":366,"children":368},{"className":367},[],[369],{"type":54,"value":370},"tx.serialize()",{"type":54,"value":372},") to the wallet.",{"type":48,"tag":61,"props":374,"children":375},{},[376],{"type":54,"value":377},"All patterns in this skill are derived from:",{"type":48,"tag":379,"props":380,"children":381},"ul",{},[382,395,404,413,422],{"type":48,"tag":91,"props":383,"children":384},{},[385,393],{"type":48,"tag":386,"props":387,"children":391},"a",{"href":388,"rel":389},"https:\u002F\u002Fsdk.mystenlabs.com\u002Fdapp-kit",[390],"nofollow",[392],{"type":54,"value":388},{"type":54,"value":394}," (landing)",{"type":48,"tag":91,"props":396,"children":397},{},[398],{"type":48,"tag":386,"props":399,"children":402},{"href":400,"rel":401},"https:\u002F\u002Fsdk.mystenlabs.com\u002Fdapp-kit\u002Fgetting-started\u002Freact",[390],[403],{"type":54,"value":400},{"type":48,"tag":91,"props":405,"children":406},{},[407],{"type":48,"tag":386,"props":408,"children":411},{"href":409,"rel":410},"https:\u002F\u002Fsdk.mystenlabs.com\u002Fdapp-kit\u002Fgetting-started\u002Fnext-js",[390],[412],{"type":54,"value":409},{"type":48,"tag":91,"props":414,"children":415},{},[416],{"type":48,"tag":386,"props":417,"children":420},{"href":418,"rel":419},"https:\u002F\u002Fsdk.mystenlabs.com\u002Fdapp-kit\u002Fgetting-started\u002Fvue",[390],[421],{"type":54,"value":418},{"type":48,"tag":91,"props":423,"children":424},{},[425],{"type":48,"tag":386,"props":426,"children":429},{"href":427,"rel":428},"https:\u002F\u002Fdocs.sui.io\u002Fstandards\u002Fwallet-standard",[390],[430],{"type":54,"value":427},{"type":48,"tag":61,"props":432,"children":433},{},[434,436,441],{"type":54,"value":435},"If unsure about any API, fetch from the relevant page — do not extrapolate from the legacy ",{"type":48,"tag":73,"props":437,"children":439},{"className":438},[],[440],{"type":54,"value":106},{"type":54,"value":442}," or the pre-v2 hook surface. Many outdated tutorials exist.",{"type":48,"tag":444,"props":445,"children":446},"hr",{},[],{"type":48,"tag":448,"props":449,"children":451},"h2",{"id":450},"reference-files",[452],{"type":54,"value":453},"Reference files",{"type":48,"tag":455,"props":456,"children":458},"h3",{"id":457},"setup-install-factory-provider",[459],{"type":54,"value":460},"setup — Install, factory, provider",{"type":48,"tag":61,"props":462,"children":463},{},[464,469,470,476,481,483,489,490,495,497,503],{"type":48,"tag":65,"props":465,"children":466},{},[467],{"type":54,"value":468},"Path:",{"type":54,"value":100},{"type":48,"tag":73,"props":471,"children":473},{"className":472},[],[474],{"type":54,"value":475},"setup.md",{"type":48,"tag":65,"props":477,"children":478},{},[479],{"type":54,"value":480},"Load when:",{"type":54,"value":482}," starting a new dApp project, scaffolding React\u002FNext.js\u002FVue setup, or migrating from the old three-provider pattern. Covers package choice, ",{"type":48,"tag":73,"props":484,"children":486},{"className":485},[],[487],{"type":54,"value":488},"createDAppKit({ networks, createClient })",{"type":54,"value":238},{"type":48,"tag":73,"props":491,"children":493},{"className":492},[],[494],{"type":54,"value":219},{"type":54,"value":496}," (React), and the ",{"type":48,"tag":73,"props":498,"children":500},{"className":499},[],[501],{"type":54,"value":502},"declare module",{"type":54,"value":504}," TypeScript augmentation.",{"type":48,"tag":455,"props":506,"children":508},{"id":507},"react-react-hooks-patterns",[509],{"type":54,"value":510},"react — React hooks & patterns",{"type":48,"tag":61,"props":512,"children":513},{},[514,518,519,525,529,531,537,538,544,545,550,551,556,557,563,564,570,571,577,579,585],{"type":48,"tag":65,"props":515,"children":516},{},[517],{"type":54,"value":468},{"type":54,"value":100},{"type":48,"tag":73,"props":520,"children":522},{"className":521},[],[523],{"type":54,"value":524},"react.md",{"type":48,"tag":65,"props":526,"children":527},{},[528],{"type":54,"value":480},{"type":54,"value":530}," writing React components. Covers every current hook (",{"type":48,"tag":73,"props":532,"children":534},{"className":533},[],[535],{"type":54,"value":536},"useCurrentAccount",{"type":54,"value":238},{"type":48,"tag":73,"props":539,"children":541},{"className":540},[],[542],{"type":54,"value":543},"useCurrentWallet",{"type":54,"value":238},{"type":48,"tag":73,"props":546,"children":548},{"className":547},[],[549],{"type":54,"value":303},{"type":54,"value":238},{"type":48,"tag":73,"props":552,"children":554},{"className":553},[],[555],{"type":54,"value":295},{"type":54,"value":238},{"type":48,"tag":73,"props":558,"children":560},{"className":559},[],[561],{"type":54,"value":562},"useDAppKit",{"type":54,"value":238},{"type":48,"tag":73,"props":565,"children":567},{"className":566},[],[568],{"type":54,"value":569},"useWallets",{"type":54,"value":238},{"type":48,"tag":73,"props":572,"children":574},{"className":573},[],[575],{"type":54,"value":576},"useWalletConnection",{"type":54,"value":578},"), standard components (",{"type":48,"tag":73,"props":580,"children":582},{"className":581},[],[583],{"type":54,"value":584},"ConnectButton",{"type":54,"value":586},"), and wallet-gated UI idioms.",{"type":48,"tag":455,"props":588,"children":590},{"id":589},"non-react-vue-vanilla-js-web-components",[591],{"type":54,"value":592},"non-react — Vue, vanilla JS, Web Components",{"type":48,"tag":61,"props":594,"children":595},{},[596,600,601,607,611,613,618,620,626,628,634],{"type":48,"tag":65,"props":597,"children":598},{},[599],{"type":54,"value":468},{"type":54,"value":100},{"type":48,"tag":73,"props":602,"children":604},{"className":603},[],[605],{"type":54,"value":606},"non-react.md",{"type":48,"tag":65,"props":608,"children":609},{},[610],{"type":54,"value":480},{"type":54,"value":612}," building Vue \u002F Svelte \u002F vanilla JS dApps. Covers ",{"type":48,"tag":73,"props":614,"children":616},{"className":615},[],[617],{"type":54,"value":129},{"type":54,"value":619},", nanostores reactive state (",{"type":48,"tag":73,"props":621,"children":623},{"className":622},[],[624],{"type":54,"value":625},"dAppKit.stores.$connection",{"type":54,"value":627}," etc.), Web Components registration, Vue bindings via ",{"type":48,"tag":73,"props":629,"children":631},{"className":630},[],[632],{"type":54,"value":633},"@nanostores\u002Fvue",{"type":54,"value":131},{"type":48,"tag":455,"props":636,"children":638},{"id":637},"queries-tanstack-query-patterns",[639],{"type":54,"value":640},"queries — TanStack Query patterns",{"type":48,"tag":61,"props":642,"children":643},{},[644,648,649,655,659,661,667,669,674,675,681,683,689],{"type":48,"tag":65,"props":645,"children":646},{},[647],{"type":54,"value":468},{"type":54,"value":100},{"type":48,"tag":73,"props":650,"children":652},{"className":651},[],[653],{"type":54,"value":654},"queries.md",{"type":48,"tag":65,"props":656,"children":657},{},[658],{"type":54,"value":480},{"type":54,"value":660}," fetching on-chain data (balances, owned objects, coins, dynamic fields, transactions) in a dApp. Covers ",{"type":48,"tag":73,"props":662,"children":664},{"className":663},[],[665],{"type":54,"value":666},"useQuery",{"type":54,"value":668}," + ",{"type":48,"tag":73,"props":670,"children":672},{"className":671},[],[673],{"type":54,"value":295},{"type":54,"value":238},{"type":48,"tag":73,"props":676,"children":678},{"className":677},[],[679],{"type":54,"value":680},"useInfiniteQuery",{"type":54,"value":682}," for paginated results, ",{"type":48,"tag":73,"props":684,"children":686},{"className":685},[],[687],{"type":54,"value":688},"enabled",{"type":54,"value":690}," guards, and cache invalidation after writes.",{"type":48,"tag":455,"props":692,"children":694},{"id":693},"transactions-signing-and-executing",[695],{"type":54,"value":696},"transactions — Signing and executing",{"type":48,"tag":61,"props":698,"children":699},{},[700,704,705,711,715,717,723,725,731,733,739,741,747,748,753,754,760],{"type":48,"tag":65,"props":701,"children":702},{},[703],{"type":54,"value":468},{"type":54,"value":100},{"type":48,"tag":73,"props":706,"children":708},{"className":707},[],[709],{"type":54,"value":710},"transactions.md",{"type":48,"tag":65,"props":712,"children":713},{},[714],{"type":54,"value":480},{"type":54,"value":716}," submitting any transaction from a dApp. Covers ",{"type":48,"tag":73,"props":718,"children":720},{"className":719},[],[721],{"type":54,"value":722},"dAppKit.signAndExecuteTransaction",{"type":54,"value":724},", the ",{"type":48,"tag":73,"props":726,"children":728},{"className":727},[],[729],{"type":54,"value":730},"$kind",{"type":54,"value":732},"-based result discriminant, ",{"type":48,"tag":73,"props":734,"children":736},{"className":735},[],[737],{"type":54,"value":738},"signTransaction",{"type":54,"value":740}," (wallet signs but doesn't execute — for sponsored flows), ",{"type":48,"tag":73,"props":742,"children":744},{"className":743},[],[745],{"type":54,"value":746},"signPersonalMessage",{"type":54,"value":724},{"type":48,"tag":73,"props":749,"children":751},{"className":750},[],[752],{"type":54,"value":326},{"type":54,"value":668},{"type":48,"tag":73,"props":755,"children":757},{"className":756},[],[758],{"type":54,"value":759},"invalidateQueries",{"type":54,"value":761}," sequence, and common wallet UX failures.",{"type":48,"tag":455,"props":763,"children":765},{"id":764},"limitations-what-frontends-cant-or-shouldnt-do",[766],{"type":54,"value":767},"limitations — What frontends can't or shouldn't do",{"type":48,"tag":61,"props":769,"children":770},{},[771,775,776,782,786],{"type":48,"tag":65,"props":772,"children":773},{},[774],{"type":54,"value":468},{"type":54,"value":100},{"type":48,"tag":73,"props":777,"children":779},{"className":778},[],[780],{"type":54,"value":781},"limitations.md",{"type":48,"tag":65,"props":783,"children":784},{},[785],{"type":54,"value":480},{"type":54,"value":787}," a user is designing something that feels like it crosses a browser-environment boundary. Covers: no backend-only features (gas station internals, validator keys), browser\u002FSSR caveats, auto-connect reliability, and the \"don't put secrets in the browser\" rules.",{"type":48,"tag":448,"props":789,"children":791},{"id":790},"routing-guide",[792],{"type":54,"value":793},"Routing guide",{"type":48,"tag":795,"props":796,"children":797},"table",{},[798,817],{"type":48,"tag":799,"props":800,"children":801},"thead",{},[802],{"type":48,"tag":803,"props":804,"children":805},"tr",{},[806,812],{"type":48,"tag":807,"props":808,"children":809},"th",{},[810],{"type":54,"value":811},"Task",{"type":48,"tag":807,"props":813,"children":814},{},[815],{"type":54,"value":816},"Load",{"type":48,"tag":818,"props":819,"children":820},"tbody",{},[821,835,848,861,874,887,900,920,933,946,964],{"type":48,"tag":803,"props":822,"children":823},{},[824,830],{"type":48,"tag":825,"props":826,"children":827},"td",{},[828],{"type":54,"value":829},"New React dApp from scratch",{"type":48,"tag":825,"props":831,"children":832},{},[833],{"type":54,"value":834},"setup + react + queries + transactions",{"type":48,"tag":803,"props":836,"children":837},{},[838,843],{"type":48,"tag":825,"props":839,"children":840},{},[841],{"type":54,"value":842},"New Vue \u002F vanilla \u002F Svelte dApp",{"type":48,"tag":825,"props":844,"children":845},{},[846],{"type":54,"value":847},"setup + non-react",{"type":48,"tag":803,"props":849,"children":850},{},[851,856],{"type":48,"tag":825,"props":852,"children":853},{},[854],{"type":54,"value":855},"\"How do I connect a wallet?\"",{"type":48,"tag":825,"props":857,"children":858},{},[859],{"type":54,"value":860},"react (or non-react)",{"type":48,"tag":803,"props":862,"children":863},{},[864,869],{"type":48,"tag":825,"props":865,"children":866},{},[867],{"type":54,"value":868},"\"How do I query a balance \u002F owned objects?\"",{"type":48,"tag":825,"props":870,"children":871},{},[872],{"type":54,"value":873},"queries",{"type":48,"tag":803,"props":875,"children":876},{},[877,882],{"type":48,"tag":825,"props":878,"children":879},{},[880],{"type":54,"value":881},"\"How do I send a transaction?\"",{"type":48,"tag":825,"props":883,"children":884},{},[885],{"type":54,"value":886},"transactions + (sui-sdks for PTB construction)",{"type":48,"tag":803,"props":888,"children":889},{},[890,895],{"type":48,"tag":825,"props":891,"children":892},{},[893],{"type":54,"value":894},"Sponsored tx flow",{"type":48,"tag":825,"props":896,"children":897},{},[898],{"type":54,"value":899},"transactions (front-end side) + ptbs (PTB side)",{"type":48,"tag":803,"props":901,"children":902},{},[903,915],{"type":48,"tag":825,"props":904,"children":905},{},[906,908,913],{"type":54,"value":907},"Migrating from ",{"type":48,"tag":73,"props":909,"children":911},{"className":910},[],[912],{"type":54,"value":106},{"type":54,"value":914}," (no suffix)",{"type":48,"tag":825,"props":916,"children":917},{},[918],{"type":54,"value":919},"setup + limitations + all as needed",{"type":48,"tag":803,"props":921,"children":922},{},[923,928],{"type":48,"tag":825,"props":924,"children":925},{},[926],{"type":54,"value":927},"Why is my UI stale after a tx?",{"type":48,"tag":825,"props":929,"children":930},{},[931],{"type":54,"value":932},"transactions + queries",{"type":48,"tag":803,"props":934,"children":935},{},[936,941],{"type":48,"tag":825,"props":937,"children":938},{},[939],{"type":54,"value":940},"Dealing with SSR \u002F Next.js",{"type":48,"tag":825,"props":942,"children":943},{},[944],{"type":54,"value":945},"setup + limitations",{"type":48,"tag":803,"props":947,"children":948},{},[949,954],{"type":48,"tag":825,"props":950,"children":951},{},[952],{"type":54,"value":953},"Full code review of a dApp",{"type":48,"tag":825,"props":955,"children":956},{},[957,962],{"type":48,"tag":65,"props":958,"children":959},{},[960],{"type":54,"value":961},"all reference files",{"type":54,"value":963}," + the code-review checklist below",{"type":48,"tag":803,"props":965,"children":966},{},[967,972],{"type":48,"tag":825,"props":968,"children":969},{},[970],{"type":54,"value":971},"\"Review this code\" \u002F \"what's wrong with this snippet\"",{"type":48,"tag":825,"props":973,"children":974},{},[975],{"type":54,"value":976},"the code-review checklist below + relevant reference files",{"type":48,"tag":448,"props":978,"children":980},{"id":979},"skill-content",[981],{"type":54,"value":982},"Skill Content",{"type":48,"tag":455,"props":984,"children":986},{"id":985},"key-concepts",[987],{"type":54,"value":988},"Key concepts",{"type":48,"tag":379,"props":990,"children":991},{},[992,1056,1088,1118,1144,1174],{"type":48,"tag":91,"props":993,"children":994},{},[995,1000,1001,1006,1008,1013,1015,1020,1022,1027,1028,1033,1034,1040,1041,1047,1048,1054],{"type":48,"tag":65,"props":996,"children":997},{},[998],{"type":54,"value":999},"Two packages, one API.",{"type":54,"value":100},{"type":48,"tag":73,"props":1002,"children":1004},{"className":1003},[],[1005],{"type":54,"value":121},{"type":54,"value":1007}," wraps ",{"type":48,"tag":73,"props":1009,"children":1011},{"className":1010},[],[1012],{"type":54,"value":129},{"type":54,"value":1014},". ",{"type":48,"tag":73,"props":1016,"children":1018},{"className":1017},[],[1019],{"type":54,"value":155},{"type":54,"value":1021}," exists in both; actions (",{"type":48,"tag":73,"props":1023,"children":1025},{"className":1024},[],[1026],{"type":54,"value":336},{"type":54,"value":238},{"type":48,"tag":73,"props":1029,"children":1031},{"className":1030},[],[1032],{"type":54,"value":738},{"type":54,"value":238},{"type":48,"tag":73,"props":1035,"children":1037},{"className":1036},[],[1038],{"type":54,"value":1039},"switchNetwork",{"type":54,"value":238},{"type":48,"tag":73,"props":1042,"children":1044},{"className":1043},[],[1045],{"type":54,"value":1046},"connectWallet",{"type":54,"value":238},{"type":48,"tag":73,"props":1049,"children":1051},{"className":1050},[],[1052],{"type":54,"value":1053},"disconnectWallet",{"type":54,"value":1055},") are identical. What differs is how you read reactive state: React uses hooks; non-React reads nanostores stores.",{"type":48,"tag":91,"props":1057,"children":1058},{},[1059,1064,1065,1071,1073,1079,1081,1086],{"type":48,"tag":65,"props":1060,"children":1061},{},[1062],{"type":54,"value":1063},"One instance, many networks.",{"type":54,"value":100},{"type":48,"tag":73,"props":1066,"children":1068},{"className":1067},[],[1069],{"type":54,"value":1070},"createDAppKit({ networks: [...], createClient })",{"type":54,"value":1072}," creates one dApp Kit instance that knows about multiple networks. ",{"type":48,"tag":73,"props":1074,"children":1076},{"className":1075},[],[1077],{"type":54,"value":1078},"dAppKit.switchNetwork(name)",{"type":54,"value":1080}," changes the active one. The ",{"type":48,"tag":73,"props":1082,"children":1084},{"className":1083},[],[1085],{"type":54,"value":163},{"type":54,"value":1087}," factory is called once per network, lazily.",{"type":48,"tag":91,"props":1089,"children":1090},{},[1091,1096,1098,1103,1105,1110,1112,1117],{"type":48,"tag":65,"props":1092,"children":1093},{},[1094],{"type":54,"value":1095},"gRPC by default.",{"type":54,"value":1097}," The new dApp Kit is built for ",{"type":48,"tag":73,"props":1099,"children":1101},{"className":1100},[],[1102],{"type":54,"value":147},{"type":54,"value":1104},". JSON-RPC is deprecated; use ",{"type":48,"tag":73,"props":1106,"children":1108},{"className":1107},[],[1109],{"type":54,"value":147},{"type":54,"value":1111}," in ",{"type":48,"tag":73,"props":1113,"children":1115},{"className":1114},[],[1116],{"type":54,"value":163},{"type":54,"value":131},{"type":48,"tag":91,"props":1119,"children":1120},{},[1121,1126,1128,1134,1136,1142],{"type":48,"tag":65,"props":1122,"children":1123},{},[1124],{"type":54,"value":1125},"Wallets are browser-only.",{"type":54,"value":1127}," Wallet detection uses ",{"type":48,"tag":73,"props":1129,"children":1131},{"className":1130},[],[1132],{"type":54,"value":1133},"window.navigator.wallets",{"type":54,"value":1135}," and CustomEvents. Any component that touches wallet state must be client-side rendered. In Next.js \u002F SSR frameworks this means ",{"type":48,"tag":73,"props":1137,"children":1139},{"className":1138},[],[1140],{"type":54,"value":1141},"'use client'",{"type":54,"value":1143}," on wallet-aware components.",{"type":48,"tag":91,"props":1145,"children":1146},{},[1147,1152,1154,1159,1161,1166,1168,1173],{"type":48,"tag":65,"props":1148,"children":1149},{},[1150],{"type":54,"value":1151},"The wallet owns gas.",{"type":54,"value":1153}," Apps build the ",{"type":48,"tag":73,"props":1155,"children":1157},{"className":1156},[],[1158],{"type":54,"value":362},{"type":54,"value":1160}," and pass it to the wallet. The wallet picks gas coins, sets budget (via dry-run), and signs. Never call ",{"type":48,"tag":73,"props":1162,"children":1164},{"className":1163},[],[1165],{"type":54,"value":352},{"type":54,"value":1167}," + pass bytes unless it's a sponsored flow — see ",{"type":48,"tag":73,"props":1169,"children":1171},{"className":1170},[],[1172],{"type":54,"value":710},{"type":54,"value":131},{"type":48,"tag":91,"props":1175,"children":1176},{},[1177,1182,1183,1188,1190,1195],{"type":48,"tag":65,"props":1178,"children":1179},{},[1180],{"type":54,"value":1181},"Fullnodes are eventually consistent.",{"type":54,"value":100},{"type":48,"tag":73,"props":1184,"children":1186},{"className":1185},[],[1187],{"type":54,"value":336},{"type":54,"value":1189}," returns a digest before the data is queryable. Always ",{"type":48,"tag":73,"props":1191,"children":1193},{"className":1192},[],[1194],{"type":54,"value":326},{"type":54,"value":1196}," before refetching.",{"type":48,"tag":455,"props":1198,"children":1200},{"id":1199},"rules",[1201],{"type":54,"value":1202},"Rules",{"type":48,"tag":87,"props":1204,"children":1205},{},[1206,1234,1283,1330,1347,1426,1467,1497,1544,1577,1594],{"type":48,"tag":91,"props":1207,"children":1208},{},[1209,1225,1227,1232],{"type":48,"tag":65,"props":1210,"children":1211},{},[1212,1214,1219,1220],{"type":54,"value":1213},"Use ",{"type":48,"tag":73,"props":1215,"children":1217},{"className":1216},[],[1218],{"type":54,"value":121},{"type":54,"value":123},{"type":48,"tag":73,"props":1221,"children":1223},{"className":1222},[],[1224],{"type":54,"value":129},{"type":54,"value":1226}," — never the bare ",{"type":48,"tag":73,"props":1228,"children":1230},{"className":1229},[],[1231],{"type":54,"value":106},{"type":54,"value":1233}," in new code. That package is JSON-RPC-only and deprecated.",{"type":48,"tag":91,"props":1235,"children":1236},{},[1237,1253,1255,1261,1262,1267,1269,1274,1276,1282],{"type":48,"tag":65,"props":1238,"children":1239},{},[1240,1241,1246,1247,1252],{"type":54,"value":1213},{"type":48,"tag":73,"props":1242,"children":1244},{"className":1243},[],[1245],{"type":54,"value":147},{"type":54,"value":1111},{"type":48,"tag":73,"props":1248,"children":1250},{"className":1249},[],[1251],{"type":54,"value":163},{"type":54,"value":131},{"type":54,"value":1254}," Not ",{"type":48,"tag":73,"props":1256,"children":1258},{"className":1257},[],[1259],{"type":54,"value":1260},"SuiClient",{"type":54,"value":282},{"type":48,"tag":73,"props":1263,"children":1265},{"className":1264},[],[1266],{"type":54,"value":1260},{"type":54,"value":1268}," is removed in v2; use ",{"type":48,"tag":73,"props":1270,"children":1272},{"className":1271},[],[1273],{"type":54,"value":147},{"type":54,"value":1275}," from ",{"type":48,"tag":73,"props":1277,"children":1279},{"className":1278},[],[1280],{"type":54,"value":1281},"@mysten\u002Fsui\u002Fgrpc",{"type":54,"value":131},{"type":48,"tag":91,"props":1284,"children":1285},{},[1286,1302,1304,1309,1310,1315,1316,1321,1323,1328],{"type":48,"tag":65,"props":1287,"children":1288},{},[1289,1290,1295,1296,1301],{"type":54,"value":1213},{"type":48,"tag":73,"props":1291,"children":1293},{"className":1292},[],[1294],{"type":54,"value":155},{"type":54,"value":668},{"type":48,"tag":73,"props":1297,"children":1299},{"className":1298},[],[1300],{"type":54,"value":219},{"type":54,"value":131},{"type":54,"value":1303}," Not the three-provider stack (",{"type":48,"tag":73,"props":1305,"children":1307},{"className":1306},[],[1308],{"type":54,"value":189},{"type":54,"value":668},{"type":48,"tag":73,"props":1311,"children":1313},{"className":1312},[],[1314],{"type":54,"value":197},{"type":54,"value":668},{"type":48,"tag":73,"props":1317,"children":1319},{"className":1318},[],[1320],{"type":54,"value":204},{"type":54,"value":1322},"). You still wrap with ",{"type":48,"tag":73,"props":1324,"children":1326},{"className":1325},[],[1327],{"type":54,"value":189},{"type":54,"value":1329}," if you use TanStack Query for data fetching, but dApp Kit itself doesn't need it.",{"type":48,"tag":91,"props":1331,"children":1332},{},[1333,1345],{"type":48,"tag":65,"props":1334,"children":1335},{},[1336,1338,1343],{"type":54,"value":1337},"Include the ",{"type":48,"tag":73,"props":1339,"children":1341},{"className":1340},[],[1342],{"type":54,"value":502},{"type":54,"value":1344}," TypeScript augmentation",{"type":54,"value":1346}," so hooks get proper types without passing the instance manually.",{"type":48,"tag":91,"props":1348,"children":1349},{},[1350,1355,1356,1361,1362,1367,1368,1373,1374,1379,1380,1385,1387,1392,1393,1398,1400,1405,1406,1411,1413,1418,1419,1424],{"type":48,"tag":65,"props":1351,"children":1352},{},[1353],{"type":54,"value":1354},"Do not use the removed hooks.",{"type":54,"value":100},{"type":48,"tag":73,"props":1357,"children":1359},{"className":1358},[],[1360],{"type":54,"value":236},{"type":54,"value":297},{"type":48,"tag":73,"props":1363,"children":1365},{"className":1364},[],[1366],{"type":54,"value":244},{"type":54,"value":297},{"type":48,"tag":73,"props":1369,"children":1371},{"className":1370},[],[1372],{"type":54,"value":280},{"type":54,"value":297},{"type":48,"tag":73,"props":1375,"children":1377},{"className":1376},[],[1378],{"type":54,"value":273},{"type":54,"value":297},{"type":48,"tag":73,"props":1381,"children":1383},{"className":1382},[],[1384],{"type":54,"value":251},{"type":54,"value":1386}," (mutation hook) \u002F ",{"type":48,"tag":73,"props":1388,"children":1390},{"className":1389},[],[1391],{"type":54,"value":259},{"type":54,"value":297},{"type":48,"tag":73,"props":1394,"children":1396},{"className":1395},[],[1397],{"type":54,"value":266},{"type":54,"value":1399}," — gone. Use ",{"type":48,"tag":73,"props":1401,"children":1403},{"className":1402},[],[1404],{"type":54,"value":295},{"type":54,"value":668},{"type":48,"tag":73,"props":1407,"children":1409},{"className":1408},[],[1410],{"type":54,"value":666},{"type":54,"value":1412},"\u002F",{"type":48,"tag":73,"props":1414,"children":1416},{"className":1415},[],[1417],{"type":54,"value":680},{"type":54,"value":668},{"type":48,"tag":73,"props":1420,"children":1422},{"className":1421},[],[1423],{"type":54,"value":310},{"type":54,"value":1425}," imperative methods.",{"type":48,"tag":91,"props":1427,"children":1428},{},[1429,1434,1435,1441,1443,1449,1451,1457,1459,1465],{"type":48,"tag":65,"props":1430,"children":1431},{},[1432],{"type":54,"value":1433},"Null-check the current account.",{"type":54,"value":100},{"type":48,"tag":73,"props":1436,"children":1438},{"className":1437},[],[1439],{"type":54,"value":1440},"useCurrentAccount()",{"type":54,"value":1442}," returns ",{"type":48,"tag":73,"props":1444,"children":1446},{"className":1445},[],[1447],{"type":54,"value":1448},"null",{"type":54,"value":1450}," before connection. Always ",{"type":48,"tag":73,"props":1452,"children":1454},{"className":1453},[],[1455],{"type":54,"value":1456},"if (!account) return",{"type":54,"value":1458}," \u002F gate with ",{"type":48,"tag":73,"props":1460,"children":1462},{"className":1461},[],[1463],{"type":54,"value":1464},"enabled: !!account",{"type":54,"value":1466}," in queries.",{"type":48,"tag":91,"props":1468,"children":1469},{},[1470,1480,1481,1487,1489,1495],{"type":48,"tag":65,"props":1471,"children":1472},{},[1473,1478],{"type":48,"tag":73,"props":1474,"children":1476},{"className":1475},[],[1477],{"type":54,"value":326},{"type":54,"value":1479}," before cache invalidation.",{"type":54,"value":100},{"type":48,"tag":73,"props":1482,"children":1484},{"className":1483},[],[1485],{"type":54,"value":1486},"await client.waitForTransaction({ digest: result.Transaction.digest })",{"type":54,"value":1488}," then ",{"type":48,"tag":73,"props":1490,"children":1492},{"className":1491},[],[1493],{"type":54,"value":1494},"queryClient.invalidateQueries(...)",{"type":54,"value":1496},". Reversing this fetches stale data.",{"type":48,"tag":91,"props":1498,"children":1499},{},[1500,1526,1528,1534,1536,1542],{"type":48,"tag":65,"props":1501,"children":1502},{},[1503,1505,1510,1511,1516,1518,1524],{"type":54,"value":1504},"Pass the ",{"type":48,"tag":73,"props":1506,"children":1508},{"className":1507},[],[1509],{"type":54,"value":362},{"type":54,"value":364},{"type":48,"tag":73,"props":1512,"children":1514},{"className":1513},[],[1515],{"type":54,"value":370},{"type":54,"value":1517},") to the wallet, not ",{"type":48,"tag":73,"props":1519,"children":1521},{"className":1520},[],[1522],{"type":54,"value":1523},"await tx.build(...)",{"type":54,"value":1525}," bytes.",{"type":54,"value":1527}," The wallet needs to own gas selection. Exception: sponsored flows that use ",{"type":48,"tag":73,"props":1529,"children":1531},{"className":1530},[],[1532],{"type":54,"value":1533},"tx.build({ client, onlyTransactionKind: true })",{"type":54,"value":1535}," — see ",{"type":48,"tag":73,"props":1537,"children":1539},{"className":1538},[],[1540],{"type":54,"value":1541},"ptbs",{"type":54,"value":1543}," skill.",{"type":48,"tag":91,"props":1545,"children":1546},{},[1547,1568,1570,1576],{"type":48,"tag":65,"props":1548,"children":1549},{},[1550,1552,1558,1560,1566],{"type":54,"value":1551},"Check ",{"type":48,"tag":73,"props":1553,"children":1555},{"className":1554},[],[1556],{"type":54,"value":1557},"result.$kind === 'FailedTransaction'",{"type":54,"value":1559}," (or ",{"type":48,"tag":73,"props":1561,"children":1563},{"className":1562},[],[1564],{"type":54,"value":1565},"result.FailedTransaction",{"type":54,"value":1567},").",{"type":54,"value":1569}," Don't assume success. Don't use v1's ",{"type":48,"tag":73,"props":1571,"children":1573},{"className":1572},[],[1574],{"type":54,"value":1575},"result.effects?.status?.status",{"type":54,"value":131},{"type":48,"tag":91,"props":1578,"children":1579},{},[1580,1585,1587,1592],{"type":48,"tag":65,"props":1581,"children":1582},{},[1583],{"type":54,"value":1584},"Wallet-gated UI must client-render.",{"type":54,"value":1586}," SSR without a client-side guard renders wallet buttons before wallets are detectable. Use ",{"type":48,"tag":73,"props":1588,"children":1590},{"className":1589},[],[1591],{"type":54,"value":1141},{"type":54,"value":1593}," \u002F dynamic imports \u002F effect-based hydration.",{"type":48,"tag":91,"props":1595,"children":1596},{},[1597,1618,1619,1625,1627,1633,1634,1640,1642,1647],{"type":48,"tag":65,"props":1598,"children":1599},{},[1600,1602,1608,1610,1616],{"type":54,"value":1601},"Vue: ",{"type":48,"tag":73,"props":1603,"children":1605},{"className":1604},[],[1606],{"type":54,"value":1607},"useStore",{"type":54,"value":1609}," returns a Vue ref — use ",{"type":48,"tag":73,"props":1611,"children":1613},{"className":1612},[],[1614],{"type":54,"value":1615},".value",{"type":54,"value":1617}," in script code.",{"type":54,"value":100},{"type":48,"tag":73,"props":1620,"children":1622},{"className":1621},[],[1623],{"type":54,"value":1624},"const connection = useStore(dAppKit.stores.$connection)",{"type":54,"value":1626}," returns a ref. Access state as ",{"type":48,"tag":73,"props":1628,"children":1630},{"className":1629},[],[1631],{"type":54,"value":1632},"connection.value.account",{"type":54,"value":1111},{"type":48,"tag":73,"props":1635,"children":1637},{"className":1636},[],[1638],{"type":54,"value":1639},"\u003Cscript setup>",{"type":54,"value":1641},". Vue auto-unwraps refs in templates, but always show the ",{"type":48,"tag":73,"props":1643,"children":1645},{"className":1644},[],[1646],{"type":54,"value":1615},{"type":54,"value":1648}," pattern in script examples.",{"type":48,"tag":455,"props":1650,"children":1652},{"id":1651},"code-review-checklist",[1653],{"type":54,"value":1654},"Code-review checklist",{"type":48,"tag":61,"props":1656,"children":1657},{},[1658,1660,1665],{"type":54,"value":1659},"When the user asks you to review a code snippet, do not stop at the first 2–3 issues you spot. Walk this checklist explicitly and call out ",{"type":48,"tag":65,"props":1661,"children":1662},{},[1663],{"type":54,"value":1664},"every",{"type":54,"value":1666}," match. Browser Sui code typically has 5–10 issues stacked in a single component because it was copied from a v1 tutorial.",{"type":48,"tag":61,"props":1668,"children":1669},{},[1670],{"type":48,"tag":65,"props":1671,"children":1672},{},[1673],{"type":54,"value":1674},"Imports \u002F packages",{"type":48,"tag":379,"props":1676,"children":1677},{},[1678,1696,1720,1754,1791],{"type":48,"tag":91,"props":1679,"children":1680},{},[1681,1687,1689,1695],{"type":48,"tag":73,"props":1682,"children":1684},{"className":1683},[],[1685],{"type":54,"value":1686},"@mysten\u002Fsui.js",{"type":54,"value":1688}," (anywhere) — frozen v1 package; replace with ",{"type":48,"tag":73,"props":1690,"children":1692},{"className":1691},[],[1693],{"type":54,"value":1694},"@mysten\u002Fsui",{"type":54,"value":131},{"type":48,"tag":91,"props":1697,"children":1698},{},[1699,1704,1706,1711,1713,1718],{"type":48,"tag":73,"props":1700,"children":1702},{"className":1701},[],[1703],{"type":54,"value":106},{"type":54,"value":1705}," (no suffix) — deprecated JSON-RPC-only package; replace with ",{"type":48,"tag":73,"props":1707,"children":1709},{"className":1708},[],[1710],{"type":54,"value":121},{"type":54,"value":1712}," (React) or ",{"type":48,"tag":73,"props":1714,"children":1716},{"className":1715},[],[1717],{"type":54,"value":129},{"type":54,"value":1719}," (other frameworks).",{"type":48,"tag":91,"props":1721,"children":1722},{},[1723,1729,1731,1736,1738,1744,1746,1752],{"type":48,"tag":73,"props":1724,"children":1726},{"className":1725},[],[1727],{"type":54,"value":1728},"import { ConnectButton } from '@mysten\u002Fdapp-kit-react'",{"type":54,"value":1730}," — wrong path; ",{"type":48,"tag":73,"props":1732,"children":1734},{"className":1733},[],[1735],{"type":54,"value":584},{"type":54,"value":1737}," and ",{"type":48,"tag":73,"props":1739,"children":1741},{"className":1740},[],[1742],{"type":54,"value":1743},"ConnectModal",{"type":54,"value":1745}," are exported from ",{"type":48,"tag":73,"props":1747,"children":1749},{"className":1748},[],[1750],{"type":54,"value":1751},"@mysten\u002Fdapp-kit-react\u002Fui",{"type":54,"value":1753},". Using the wrong path causes a silent white screen.",{"type":48,"tag":91,"props":1755,"children":1756},{},[1757,1763,1764,1769,1771,1776,1777,1782,1783,1789],{"type":48,"tag":73,"props":1758,"children":1760},{"className":1759},[],[1761],{"type":54,"value":1762},"import { SuiClient }",{"type":54,"value":282},{"type":48,"tag":73,"props":1765,"children":1767},{"className":1766},[],[1768],{"type":54,"value":1260},{"type":54,"value":1770}," is removed in v2 — use ",{"type":48,"tag":73,"props":1772,"children":1774},{"className":1773},[],[1775],{"type":54,"value":147},{"type":54,"value":1275},{"type":48,"tag":73,"props":1778,"children":1780},{"className":1779},[],[1781],{"type":54,"value":1281},{"type":54,"value":1559},{"type":48,"tag":73,"props":1784,"children":1786},{"className":1785},[],[1787],{"type":54,"value":1788},"useCurrentClient()",{"type":54,"value":1790}," inside components).",{"type":48,"tag":91,"props":1792,"children":1793},{},[1794,1800,1802,1807],{"type":48,"tag":73,"props":1795,"children":1797},{"className":1796},[],[1798],{"type":54,"value":1799},"import { TransactionBlock }",{"type":54,"value":1801}," — renamed to ",{"type":48,"tag":73,"props":1803,"children":1805},{"className":1804},[],[1806],{"type":54,"value":362},{"type":54,"value":1808}," in v2.",{"type":48,"tag":61,"props":1810,"children":1811},{},[1812],{"type":48,"tag":65,"props":1813,"children":1814},{},[1815],{"type":54,"value":1816},"Removed hooks (any of these = bug)",{"type":48,"tag":379,"props":1818,"children":1819},{},[1820,1867,1885],{"type":48,"tag":91,"props":1821,"children":1822},{},[1823,1828,1829,1834,1835,1840,1841,1846,1848,1853,1855,1860,1861,1866],{"type":48,"tag":73,"props":1824,"children":1826},{"className":1825},[],[1827],{"type":54,"value":236},{"type":54,"value":238},{"type":48,"tag":73,"props":1830,"children":1832},{"className":1831},[],[1833],{"type":54,"value":244},{"type":54,"value":238},{"type":48,"tag":73,"props":1836,"children":1838},{"className":1837},[],[1839],{"type":54,"value":280},{"type":54,"value":238},{"type":48,"tag":73,"props":1842,"children":1844},{"className":1843},[],[1845],{"type":54,"value":273},{"type":54,"value":1847}," — replace with ",{"type":48,"tag":73,"props":1849,"children":1851},{"className":1850},[],[1852],{"type":54,"value":1788},{"type":54,"value":1854}," + TanStack ",{"type":48,"tag":73,"props":1856,"children":1858},{"className":1857},[],[1859],{"type":54,"value":666},{"type":54,"value":297},{"type":48,"tag":73,"props":1862,"children":1864},{"className":1863},[],[1865],{"type":54,"value":680},{"type":54,"value":131},{"type":48,"tag":91,"props":1868,"children":1869},{},[1870,1875,1877,1883],{"type":48,"tag":73,"props":1871,"children":1873},{"className":1872},[],[1874],{"type":54,"value":251},{"type":54,"value":1876}," (mutation hook) — replace with ",{"type":48,"tag":73,"props":1878,"children":1880},{"className":1879},[],[1881],{"type":54,"value":1882},"useDAppKit().signAndExecuteTransaction(...)",{"type":54,"value":1884}," called imperatively in event handlers.",{"type":48,"tag":91,"props":1886,"children":1887},{},[1888,1893,1894,1899,1900,1906,1907,1913],{"type":48,"tag":73,"props":1889,"children":1891},{"className":1890},[],[1892],{"type":54,"value":259},{"type":54,"value":238},{"type":48,"tag":73,"props":1895,"children":1897},{"className":1896},[],[1898],{"type":54,"value":266},{"type":54,"value":1847},{"type":48,"tag":73,"props":1901,"children":1903},{"className":1902},[],[1904],{"type":54,"value":1905},"useDAppKit().connectWallet()",{"type":54,"value":297},{"type":48,"tag":73,"props":1908,"children":1910},{"className":1909},[],[1911],{"type":54,"value":1912},"disconnectWallet()",{"type":54,"value":131},{"type":48,"tag":61,"props":1915,"children":1916},{},[1917],{"type":48,"tag":65,"props":1918,"children":1919},{},[1920],{"type":54,"value":1921},"Provider stack",{"type":48,"tag":379,"props":1923,"children":1924},{},[1925],{"type":48,"tag":91,"props":1926,"children":1927},{},[1928,1933,1934,1939,1941,1947,1948,1954,1955,1960],{"type":48,"tag":73,"props":1929,"children":1931},{"className":1930},[],[1932],{"type":54,"value":197},{"type":54,"value":668},{"type":48,"tag":73,"props":1935,"children":1937},{"className":1936},[],[1938],{"type":54,"value":204},{"type":54,"value":1940}," (the v1 three-provider stack) — replace with ",{"type":48,"tag":73,"props":1942,"children":1944},{"className":1943},[],[1945],{"type":54,"value":1946},"createDAppKit(...)",{"type":54,"value":668},{"type":48,"tag":73,"props":1949,"children":1951},{"className":1950},[],[1952],{"type":54,"value":1953},"\u003CDAppKitProvider>",{"type":54,"value":1014},{"type":48,"tag":73,"props":1956,"children":1958},{"className":1957},[],[1959],{"type":54,"value":189},{"type":54,"value":1961}," from TanStack is still allowed.",{"type":48,"tag":61,"props":1963,"children":1964},{},[1965],{"type":48,"tag":65,"props":1966,"children":1967},{},[1968],{"type":54,"value":1969},"Client construction inside components",{"type":48,"tag":379,"props":1971,"children":1972},{},[1973,1997],{"type":48,"tag":91,"props":1974,"children":1975},{},[1976,1982,1983,1989,1991,1996],{"type":48,"tag":73,"props":1977,"children":1979},{"className":1978},[],[1980],{"type":54,"value":1981},"new SuiClient(...)",{"type":54,"value":297},{"type":48,"tag":73,"props":1984,"children":1986},{"className":1985},[],[1987],{"type":54,"value":1988},"new SuiGrpcClient(...)",{"type":54,"value":1990}," inside a component body — breaks network switching and re-creates a client per render. Use ",{"type":48,"tag":73,"props":1992,"children":1994},{"className":1993},[],[1995],{"type":54,"value":1788},{"type":54,"value":131},{"type":48,"tag":91,"props":1998,"children":1999},{},[2000,2002,2007],{"type":54,"value":2001},"Missing ",{"type":48,"tag":73,"props":2003,"children":2005},{"className":2004},[],[2006],{"type":54,"value":1464},{"type":54,"value":2008}," on queries that need a connected wallet — fires on undefined owner and errors.",{"type":48,"tag":61,"props":2010,"children":2011},{},[2012],{"type":48,"tag":65,"props":2013,"children":2014},{},[2015],{"type":54,"value":2016},"Transaction construction",{"type":48,"tag":379,"props":2018,"children":2019},{},[2020,2053],{"type":48,"tag":91,"props":2021,"children":2022},{},[2023,2029,2031,2037,2038,2044,2045,2051],{"type":48,"tag":73,"props":2024,"children":2026},{"className":2025},[],[2027],{"type":54,"value":2028},"tx.pure(value)",{"type":54,"value":2030}," (untyped) — replace with the typed helper matching the Move type: ",{"type":48,"tag":73,"props":2032,"children":2034},{"className":2033},[],[2035],{"type":54,"value":2036},"tx.pure.u64(n)",{"type":54,"value":238},{"type":48,"tag":73,"props":2039,"children":2041},{"className":2040},[],[2042],{"type":54,"value":2043},"tx.pure.address(addr)",{"type":54,"value":238},{"type":48,"tag":73,"props":2046,"children":2048},{"className":2047},[],[2049],{"type":54,"value":2050},"tx.pure.string(s)",{"type":54,"value":2052},", etc.",{"type":48,"tag":91,"props":2054,"children":2055},{},[2056,2061,2063,2068,2069,2074],{"type":48,"tag":73,"props":2057,"children":2059},{"className":2058},[],[2060],{"type":54,"value":352},{"type":54,"value":2062}," before handing to the wallet — defeats wallet gas selection. Pass the ",{"type":48,"tag":73,"props":2064,"children":2066},{"className":2065},[],[2067],{"type":54,"value":362},{"type":54,"value":364},{"type":48,"tag":73,"props":2070,"children":2072},{"className":2071},[],[2073],{"type":54,"value":370},{"type":54,"value":1567},{"type":48,"tag":61,"props":2076,"children":2077},{},[2078],{"type":48,"tag":65,"props":2079,"children":2080},{},[2081],{"type":54,"value":2082},"Execute \u002F wait \u002F status",{"type":48,"tag":379,"props":2084,"children":2085},{},[2086,2104,2122,2147,2166],{"type":48,"tag":91,"props":2087,"children":2088},{},[2089,2095,2097,2103],{"type":48,"tag":73,"props":2090,"children":2092},{"className":2091},[],[2093],{"type":54,"value":2094},"signAndExecuteTransactionBlock(...)",{"type":54,"value":2096}," (v1 method) — replace with ",{"type":48,"tag":73,"props":2098,"children":2100},{"className":2099},[],[2101],{"type":54,"value":2102},"signAndExecuteTransaction(...)",{"type":54,"value":131},{"type":48,"tag":91,"props":2105,"children":2106},{},[2107,2113,2115,2121],{"type":48,"tag":73,"props":2108,"children":2110},{"className":2109},[],[2111],{"type":54,"value":2112},"{ transactionBlock: tx }",{"type":54,"value":2114}," parameter shape — replace with ",{"type":48,"tag":73,"props":2116,"children":2118},{"className":2117},[],[2119],{"type":54,"value":2120},"{ transaction: tx }",{"type":54,"value":131},{"type":48,"tag":91,"props":2123,"children":2124},{},[2125,2131,2133,2139,2141,2146],{"type":48,"tag":73,"props":2126,"children":2128},{"className":2127},[],[2129],{"type":54,"value":2130},"result.effects?.status?.status === 'success'",{"type":54,"value":2132}," — v1 shape; replace with ",{"type":48,"tag":73,"props":2134,"children":2136},{"className":2135},[],[2137],{"type":54,"value":2138},"result.$kind !== 'FailedTransaction'",{"type":54,"value":2140}," (or check ",{"type":48,"tag":73,"props":2142,"children":2144},{"className":2143},[],[2145],{"type":54,"value":1565},{"type":54,"value":1567},{"type":48,"tag":91,"props":2148,"children":2149},{},[2150,2156,2158,2164],{"type":48,"tag":73,"props":2151,"children":2153},{"className":2152},[],[2154],{"type":54,"value":2155},"result.digest",{"type":54,"value":2157}," direct access — on success the digest is at ",{"type":48,"tag":73,"props":2159,"children":2161},{"className":2160},[],[2162],{"type":54,"value":2163},"result.Transaction.digest",{"type":54,"value":2165},"; on failure there's no digest.",{"type":48,"tag":91,"props":2167,"children":2168},{},[2169,2171,2177,2179,2184],{"type":54,"value":2170},"Cache invalidation immediately after execute — must ",{"type":48,"tag":73,"props":2172,"children":2174},{"className":2173},[],[2175],{"type":54,"value":2176},"await client.waitForTransaction({ digest })",{"type":54,"value":2178}," first, then ",{"type":48,"tag":73,"props":2180,"children":2182},{"className":2181},[],[2183],{"type":54,"value":1494},{"type":54,"value":131},{"type":48,"tag":61,"props":2186,"children":2187},{},[2188],{"type":48,"tag":65,"props":2189,"children":2190},{},[2191],{"type":54,"value":2192},"SSR \u002F Next.js",{"type":48,"tag":379,"props":2194,"children":2195},{},[2196],{"type":48,"tag":91,"props":2197,"children":2198},{},[2199,2201,2206],{"type":54,"value":2200},"Wallet-aware component without ",{"type":48,"tag":73,"props":2202,"children":2204},{"className":2203},[],[2205],{"type":54,"value":1141},{"type":54,"value":2207}," — wallet detection uses browser-only APIs.",{"type":48,"tag":61,"props":2209,"children":2210},{},[2211],{"type":54,"value":2212},"After walking the list, count the distinct issues you found. If it's fewer than 5 on a typical multi-line snippet pulled from an outdated tutorial, re-read the snippet — you almost certainly missed something.",{"type":48,"tag":455,"props":2214,"children":2216},{"id":2215},"common-mistakes",[2217],{"type":54,"value":2218},"Common mistakes",{"type":48,"tag":379,"props":2220,"children":2221},{},[2222,2251,2281,2303,2334,2350,2373,2411,2429,2453,2484],{"type":48,"tag":91,"props":2223,"children":2224},{},[2225,2249],{"type":48,"tag":65,"props":2226,"children":2227},{},[2228,2230,2236,2237,2242,2244],{"type":54,"value":2229},"Using ",{"type":48,"tag":73,"props":2231,"children":2233},{"className":2232},[],[2234],{"type":54,"value":2235},"@tanstack\u002Freact-query",{"type":54,"value":157},{"type":48,"tag":73,"props":2238,"children":2240},{"className":2239},[],[2241],{"type":54,"value":666},{"type":54,"value":2243}," without ",{"type":48,"tag":73,"props":2245,"children":2247},{"className":2246},[],[2248],{"type":54,"value":1464},{"type":54,"value":2250}," for queries that require a connected wallet. The query fires with undefined owner and errors.",{"type":48,"tag":91,"props":2252,"children":2253},{},[2254,2273,2275,2280],{"type":48,"tag":65,"props":2255,"children":2256},{},[2257,2259,2264,2266,2272],{"type":54,"value":2258},"Returning a ",{"type":48,"tag":73,"props":2260,"children":2262},{"className":2261},[],[2263],{"type":54,"value":362},{"type":54,"value":2265}," from a React-Query ",{"type":48,"tag":73,"props":2267,"children":2269},{"className":2268},[],[2270],{"type":54,"value":2271},"queryFn",{"type":54,"value":131},{"type":54,"value":2274}," Transactions aren't queries — use them in mutations or event handlers via ",{"type":48,"tag":73,"props":2276,"children":2278},{"className":2277},[],[2279],{"type":54,"value":310},{"type":54,"value":131},{"type":48,"tag":91,"props":2282,"children":2283},{},[2284,2294,2296,2301],{"type":48,"tag":65,"props":2285,"children":2286},{},[2287,2293],{"type":48,"tag":73,"props":2288,"children":2290},{"className":2289},[],[2291],{"type":54,"value":2292},"dAppKit.signAndExecuteTransaction({ transactionBlock: tx })",{"type":54,"value":131},{"type":54,"value":2295}," It's ",{"type":48,"tag":73,"props":2297,"children":2299},{"className":2298},[],[2300],{"type":54,"value":2120},{"type":54,"value":2302}," in the new API.",{"type":48,"tag":91,"props":2304,"children":2305},{},[2306,2318,2320,2325,2327,2332],{"type":48,"tag":65,"props":2307,"children":2308},{},[2309,2311,2316],{"type":54,"value":2310},"Reading ",{"type":48,"tag":73,"props":2312,"children":2314},{"className":2313},[],[2315],{"type":54,"value":2155},{"type":54,"value":2317}," directly.",{"type":54,"value":2319}," On success the digest is at ",{"type":48,"tag":73,"props":2321,"children":2323},{"className":2322},[],[2324],{"type":54,"value":2163},{"type":54,"value":2326},". On failure there's no digest — check ",{"type":48,"tag":73,"props":2328,"children":2330},{"className":2329},[],[2331],{"type":54,"value":1565},{"type":54,"value":2333}," first.",{"type":48,"tag":91,"props":2335,"children":2336},{},[2337,2348],{"type":48,"tag":65,"props":2338,"children":2339},{},[2340,2342,2347],{"type":54,"value":2341},"Invalidating queries before ",{"type":48,"tag":73,"props":2343,"children":2345},{"className":2344},[],[2346],{"type":54,"value":326},{"type":54,"value":131},{"type":54,"value":2349}," Classic stale-UI bug. Always wait first.",{"type":48,"tag":91,"props":2351,"children":2352},{},[2353,2365,2367,2372],{"type":48,"tag":65,"props":2354,"children":2355},{},[2356,2358,2363],{"type":54,"value":2357},"Calling ",{"type":48,"tag":73,"props":2359,"children":2361},{"className":2360},[],[2362],{"type":54,"value":1988},{"type":54,"value":2364}," inside components.",{"type":54,"value":2366}," Breaks network switching. Use ",{"type":48,"tag":73,"props":2368,"children":2370},{"className":2369},[],[2371],{"type":54,"value":1788},{"type":54,"value":131},{"type":48,"tag":91,"props":2374,"children":2375},{},[2376,2395,2397,2403,2405,2410],{"type":48,"tag":65,"props":2377,"children":2378},{},[2379,2381,2387,2388,2394],{"type":54,"value":2380},"Instantiating ",{"type":48,"tag":73,"props":2382,"children":2384},{"className":2383},[],[2385],{"type":54,"value":2386},"SuinsClient",{"type":54,"value":297},{"type":48,"tag":73,"props":2389,"children":2391},{"className":2390},[],[2392],{"type":54,"value":2393},"DeepBookClient",{"type":54,"value":2317},{"type":54,"value":2396}," Use ",{"type":48,"tag":73,"props":2398,"children":2400},{"className":2399},[],[2401],{"type":54,"value":2402},"client.$extend(suins(), deepbook({ address }))",{"type":54,"value":2404}," on the client returned from ",{"type":48,"tag":73,"props":2406,"children":2408},{"className":2407},[],[2409],{"type":54,"value":163},{"type":54,"value":131},{"type":48,"tag":91,"props":2412,"children":2413},{},[2414,2427],{"type":48,"tag":65,"props":2415,"children":2416},{},[2417,2419,2425],{"type":54,"value":2418},"Leaving ",{"type":48,"tag":73,"props":2420,"children":2422},{"className":2421},[],[2423],{"type":54,"value":2424},"autoConnect: true",{"type":54,"value":2426}," with a confusing UX.",{"type":54,"value":2428}," Auto-reconnect restores the last wallet on load. If the app handles permissions\u002Fnonces, account for the async nature of that restore (pending \u002F reconnecting states).",{"type":48,"tag":91,"props":2430,"children":2431},{},[2432,2437,2439,2445,2447,2452],{"type":48,"tag":65,"props":2433,"children":2434},{},[2435],{"type":54,"value":2436},"Hardcoding testnet \u002F mainnet URLs in multiple places.",{"type":54,"value":2438}," Keep them in a single ",{"type":48,"tag":73,"props":2440,"children":2442},{"className":2441},[],[2443],{"type":54,"value":2444},"GRPC_URLS",{"type":54,"value":2446}," map keyed by network name and reference from ",{"type":48,"tag":73,"props":2448,"children":2450},{"className":2449},[],[2451],{"type":54,"value":163},{"type":54,"value":131},{"type":48,"tag":91,"props":2454,"children":2455},{},[2456,2461,2463,2468,2470,2476,2477,2483],{"type":48,"tag":65,"props":2457,"children":2458},{},[2459],{"type":54,"value":2460},"Using wallet-standard APIs directly.",{"type":54,"value":2462}," dApp Kit wraps the wallet standard — don't call ",{"type":48,"tag":73,"props":2464,"children":2466},{"className":2465},[],[2467],{"type":54,"value":1133},{"type":54,"value":2469}," yourself; use ",{"type":48,"tag":73,"props":2471,"children":2473},{"className":2472},[],[2474],{"type":54,"value":2475},"useWallets()",{"type":54,"value":297},{"type":48,"tag":73,"props":2478,"children":2480},{"className":2479},[],[2481],{"type":54,"value":2482},"dAppKit.stores.$wallets",{"type":54,"value":131},{"type":48,"tag":91,"props":2485,"children":2486},{},[2487,2492],{"type":48,"tag":65,"props":2488,"children":2489},{},[2490],{"type":54,"value":2491},"Storing private keys or secrets in the browser.",{"type":54,"value":2493}," Never. dApps sign via wallets; backends hold keys.",{"items":2495,"total":2654},[2496,2512,2523,2533,2550,2568,2580,2593,2602,2614,2625,2641],{"slug":2497,"name":2497,"fn":2498,"description":2499,"org":2500,"tags":2501,"stars":2509,"repoUrl":2510,"updatedAt":2511},"move-bytecode-comprehension","analyze and disassemble Move bytecode","Use when reading or reasoning about compiled Move bytecode or `sui move disassemble` output. Mental model for the binary format, what survives compilation (and what's lost), and how to read disassembly soundly. Trigger on \"what does this package do?\", \"read this .mv module\", \"interpret this disassembly\", or whenever an analysis needs to interpret bytecode faithfully.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2502,2505,2508],{"name":2503,"slug":2504,"type":16},"Code Analysis","code-analysis",{"name":2506,"slug":2507,"type":16},"Engineering","engineering",{"name":18,"slug":8,"type":16},7724,"https:\u002F\u002Fgithub.com\u002FMystenLabs\u002Fsui","2026-07-16T05:59:32.904886",{"slug":2513,"name":2513,"fn":2514,"description":2515,"org":2516,"tags":2517,"stars":2509,"repoUrl":2510,"updatedAt":2522},"official-sui-skills","access official Sui development resources","Pointer to the official Mysten Labs skills for building on Sui — language fundamentals, object model, PTBs, SDKs, publishing, upgrades, frontend integration, accessing on-chain data. Maintained upstream at github.com\u002FMystenLabs\u002Fskills; pinned to the same ref the audit catalog derives from (see maintenance\u002FUPSTREAMS.md). Trigger on \"build a contract\", \"publish a package\", \"upgrade a module or package\", \"use the TypeScript SDK\", \"write a PTB\", \"set up a Sui client\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2518,2521],{"name":2519,"slug":2520,"type":16},"Documentation","documentation",{"name":18,"slug":8,"type":16},"2026-07-16T06:00:59.641382",{"slug":2524,"name":2524,"fn":2525,"description":2526,"org":2527,"tags":2528,"stars":2509,"repoUrl":2510,"updatedAt":2532},"sui-and-move-tools","disassemble Sui Move bytecode","Use to get bytecode for a deployed Sui package and produce a disassembled working view. One GraphQL call fetches every module's raw bytecode bytes; `sui move disassemble` (already on the system, running `sui prompt`) produces `.asm` files for analysis. Trigger on \"fetch this package's bytecode\", \"get me the .mv for package X\", \"disassemble this package\", or \"I need to read a deployed Sui package\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2529,2530,2531],{"name":2503,"slug":2504,"type":16},{"name":2506,"slug":2507,"type":16},{"name":18,"slug":8,"type":16},"2026-07-16T06:02:25.3633",{"slug":2534,"name":2534,"fn":2535,"description":2536,"org":2537,"tags":2538,"stars":2509,"repoUrl":2510,"updatedAt":2549},"sui-move-security-review","audit Sui Move smart contracts","Use when auditing, reviewing, or hunting for vulnerabilities in Move code on Sui. Applies equally to source code (.move files) and to disassembly of compiled bytecode (on-chain packages). A checklist of invariants whose VIOLATION causes exploitable bugs: access control & capabilities, struct abilities & type safety, object lifecycle & ownership, shared-object and PTB attack surface, dynamic fields & collections, arithmetic & coins, init\u002FOTW\u002Fpackage upgrades, hot-potato composability, time & on-chain randomness, and test-only code leakage. Trigger on \"audit this Move code\", \"find vulnerabilities in this Sui contract\", \"security review\", \"is this package safe?\", \"I suspect there's a bug in X\", \"something is wrong with this contract\", or when reasoning about whether a Move function can be abused.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2539,2542,2545,2548],{"name":2540,"slug":2541,"type":16},"Code Review","code-review",{"name":2543,"slug":2544,"type":16},"Security","security",{"name":2546,"slug":2547,"type":16},"Smart Contracts","smart-contracts",{"name":18,"slug":8,"type":16},"2026-07-16T06:02:55.691149",{"slug":2551,"name":2551,"fn":2552,"description":2553,"org":2554,"tags":2555,"stars":2565,"repoUrl":2566,"updatedAt":2567},"memwal","integrate Walrus Memory SDK","Walrus Memory SDK — portable agent memory that works across apps, sessions, and workflows.\n\nUse when users say:\n- \"add memory to my app\"\n- \"portable agent memory\"\n- \"integrate Walrus Memory\"\n- \"AI agent memory\"\n- \"memory across agents\"\n- \"Walrus memory storage\"\n- \"setup Walrus Memory\"\n- \"recall memories\"\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2556,2559,2562],{"name":2557,"slug":2558,"type":16},"Agents","agents",{"name":2560,"slug":2561,"type":16},"Memory","memory",{"name":2563,"slug":2564,"type":16},"SDK","sdk",57,"https:\u002F\u002Fgithub.com\u002FMystenLabs\u002FMemWal","2026-07-16T06:02:39.838395",{"slug":2569,"name":2569,"fn":2570,"description":2571,"org":2572,"tags":2573,"stars":31,"repoUrl":32,"updatedAt":2579},"accessing-data","read data from the Sui network","How to read data from the Sui network. Use when choosing or implementing a data access strategy — queries for on-chain state, indexing pipelines, historical lookups, event subscriptions, cross-chain reads, or off-chain blob storage. Covers the two live Sui APIs (gRPC and GraphQL RPC), the Archival Store, the General-Purpose Indexer, the `sui-indexer-alt` custom indexing framework, and Walrus for off-chain blobs.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2574,2577,2578],{"name":2575,"slug":2576,"type":16},"Data Analysis","data-analysis",{"name":18,"slug":8,"type":16},{"name":26,"slug":27,"type":16},"2026-08-01T05:44:32.775598",{"slug":2581,"name":2581,"fn":2582,"description":2583,"org":2584,"tags":2585,"stars":31,"repoUrl":32,"updatedAt":2592},"composable-move-functions","design composable Sui Move functions","Use when writing Move functions on Sui, especially public APIs. Applies to function visibility (public vs entry), parameter ordering, and return patterns. Use whenever designing function signatures or deciding whether functions should transfer objects or return them.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2586,2589,2590,2591],{"name":2587,"slug":2588,"type":16},"API Development","api-development",{"name":2546,"slug":2547,"type":16},{"name":18,"slug":8,"type":16},{"name":26,"slug":27,"type":16},"2026-07-16T06:02:49.198495",{"slug":4,"name":4,"fn":5,"description":6,"org":2594,"tags":2595,"stars":31,"repoUrl":32,"updatedAt":33},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2596,2597,2598,2599,2600,2601],{"name":29,"slug":30,"type":16},{"name":14,"slug":15,"type":16},{"name":18,"slug":8,"type":16},{"name":23,"slug":24,"type":16},{"name":20,"slug":21,"type":16},{"name":26,"slug":27,"type":16},{"slug":2603,"name":2603,"fn":2604,"description":2605,"org":2606,"tags":2607,"stars":31,"repoUrl":32,"updatedAt":2613},"generate-sui-agent-config","generate configuration files for Sui projects","Generate a CLAUDE.md or AGENT.md configuration file for Sui projects. Use when setting up a new Sui project, when user mentions \"CLAUDE.md\", \"AGENT.md\", \"agent config\", or when working on a Sui project that does not already have a CLAUDE.md or AGENT.md in the project root.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2608,2611,2612],{"name":2609,"slug":2610,"type":16},"Configuration","configuration",{"name":2519,"slug":2520,"type":16},{"name":18,"slug":8,"type":16},"2026-07-16T06:00:59.981056",{"slug":2615,"name":2615,"fn":2616,"description":2617,"org":2618,"tags":2619,"stars":31,"repoUrl":32,"updatedAt":2624},"modern-move-syntax","write Move 2024 edition code for Sui","Use when writing Move code on Sui to ensure 2024 edition syntax is used. Applies to method calls, string literals, vector operations, option handling, loops, and struct unpacking. Use whenever writing Move code to avoid legacy function-call syntax patterns.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2620,2621,2622,2623],{"name":2506,"slug":2507,"type":16},{"name":2546,"slug":2547,"type":16},{"name":18,"slug":8,"type":16},{"name":26,"slug":27,"type":16},"2026-07-16T06:02:43.277596",{"slug":2626,"name":2626,"fn":2627,"description":2628,"org":2629,"tags":2630,"stars":31,"repoUrl":32,"updatedAt":2640},"move-unit-testing","write unit tests for Sui Move contracts","Use when writing unit tests for Move smart contracts on Sui. Applies to test function naming, assertions, test attributes, context usage, and cleanup patterns. Use whenever user asks to write tests, add tests, or test a Move module.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2631,2634,2635,2636,2639],{"name":2632,"slug":2633,"type":16},"QA","qa",{"name":2546,"slug":2547,"type":16},{"name":18,"slug":8,"type":16},{"name":2637,"slug":2638,"type":16},"Testing","testing",{"name":26,"slug":27,"type":16},"2026-08-01T05:44:30.788585",{"slug":2642,"name":2642,"fn":2643,"description":2644,"org":2645,"tags":2646,"stars":31,"repoUrl":32,"updatedAt":2653},"naming-conventions","apply Sui Move naming conventions","Use when writing or reviewing Move smart contracts on Sui. Applies to naming structs, error constants, regular constants, events, getter functions, capability types, hot potato types, and dynamic field keys. Use whenever creating new types, functions, or constants in Move code.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2647,2650,2651,2652],{"name":2648,"slug":2649,"type":16},"Best Practices","best-practices",{"name":2546,"slug":2547,"type":16},{"name":18,"slug":8,"type":16},{"name":26,"slug":27,"type":16},"2026-07-16T06:02:48.830052",37,{"items":2656,"total":2707},[2657,2663,2670,2679,2685,2692,2700],{"slug":2569,"name":2569,"fn":2570,"description":2571,"org":2658,"tags":2659,"stars":31,"repoUrl":32,"updatedAt":2579},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2660,2661,2662],{"name":2575,"slug":2576,"type":16},{"name":18,"slug":8,"type":16},{"name":26,"slug":27,"type":16},{"slug":2581,"name":2581,"fn":2582,"description":2583,"org":2664,"tags":2665,"stars":31,"repoUrl":32,"updatedAt":2592},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2666,2667,2668,2669],{"name":2587,"slug":2588,"type":16},{"name":2546,"slug":2547,"type":16},{"name":18,"slug":8,"type":16},{"name":26,"slug":27,"type":16},{"slug":4,"name":4,"fn":5,"description":6,"org":2671,"tags":2672,"stars":31,"repoUrl":32,"updatedAt":33},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2673,2674,2675,2676,2677,2678],{"name":29,"slug":30,"type":16},{"name":14,"slug":15,"type":16},{"name":18,"slug":8,"type":16},{"name":23,"slug":24,"type":16},{"name":20,"slug":21,"type":16},{"name":26,"slug":27,"type":16},{"slug":2603,"name":2603,"fn":2604,"description":2605,"org":2680,"tags":2681,"stars":31,"repoUrl":32,"updatedAt":2613},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2682,2683,2684],{"name":2609,"slug":2610,"type":16},{"name":2519,"slug":2520,"type":16},{"name":18,"slug":8,"type":16},{"slug":2615,"name":2615,"fn":2616,"description":2617,"org":2686,"tags":2687,"stars":31,"repoUrl":32,"updatedAt":2624},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2688,2689,2690,2691],{"name":2506,"slug":2507,"type":16},{"name":2546,"slug":2547,"type":16},{"name":18,"slug":8,"type":16},{"name":26,"slug":27,"type":16},{"slug":2626,"name":2626,"fn":2627,"description":2628,"org":2693,"tags":2694,"stars":31,"repoUrl":32,"updatedAt":2640},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2695,2696,2697,2698,2699],{"name":2632,"slug":2633,"type":16},{"name":2546,"slug":2547,"type":16},{"name":18,"slug":8,"type":16},{"name":2637,"slug":2638,"type":16},{"name":26,"slug":27,"type":16},{"slug":2642,"name":2642,"fn":2643,"description":2644,"org":2701,"tags":2702,"stars":31,"repoUrl":32,"updatedAt":2653},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2703,2704,2705,2706],{"name":2648,"slug":2649,"type":16},{"name":2546,"slug":2547,"type":16},{"name":18,"slug":8,"type":16},{"name":26,"slug":27,"type":16},20]