Writes, reviews, and polishes @rhinestone/sdk changesets. Use when adding release notes, editing .changeset/*.md files, preparing SDK releases, or reviewing changelog wording.
日本語の概要は準備中です。原文の説明を表示しています。
Design guidance for changing the @rhinestone/sdk public surface so it is safe, intuitive, and pleasant to integrate. Use when adding, renaming, or changing public exports, types, account/action APIs, config objects, error classes, or defaults in sdk/src.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
You are changing the public surface of @rhinestone/sdk. Every public type,
name, default, and error message is something an integrator must learn,
remember, or get right. Design so they have to do less of all three.
This skill is about designing the surface well. The mechanics of what counts
as public and how to ship it (viem types, subpath exports, JSDoc→reference
regen, changesets) live in sdk/CLAUDE.md and the changesets skill — use
them; don't relitigate them here.
The diff touches the public surface: src/index.ts re-exports, subpath exports,
exported types/interfaces, account or action APIs, public config objects, error
classes, or default values. Skip for internal-only changes.
Model mutually-exclusive options as a discriminated union, not optional fields
guarded by a runtime throw. If a consumer can construct an invalid object,
they eventually will. A union teaches the rule in autocomplete; a runtime check
teaches it only when it throws.
// Good — same-chain carries `chain`, cross-chain carries `targetChain`.
// You cannot construct one with both.
interface SameChainTransaction { chain: Chain; /* ... */ }
interface CrossChainEvmTransaction { targetChain: Chain; sourceChains?: Chain[] }
type Transaction = SameChainTransaction | CrossChainTransaction
// A tuple can even encode "omit `amount` and you may pass exactly one":
type TokenRequests = [TokenRequestWithoutAmount] | TokenRequestWithAmount[]
// Bad — one flat shape plus a runtime guard the consumer discovers by hitting it.
interface Transaction { chain?: Chain; targetChain?: Chain /* set exactly one */ }
if (tx.chain && tx.targetChain) throw new Error('cannot set both')
any/asKeep the surface precisely typed with generics, satisfies, and literal types so
type-checking does the consumer's work for them. A cast in a public signature
hands a runtime bug to the integrator.
// Good — the ABI gates which sugar fields are even allowed. `spendingLimit` is
// `never` unless the function is ERC-20 transfer-like, so passing it on
// `vault.deposit` is a compile error, not a silently-dropped field.
type SpendingLimitField<TFn extends AbiFunction> =
IsERC20TransferLike<TFn> extends true
? { spendingLimit?: { token: Address; amount: bigint } }
: { spendingLimit?: never }
// Bad — accept it always, ignore it at runtime. Silent drops are the worst DX:
// no error, wrong behavior.
type PermissionFunctionConfig = { spendingLimit?: { token: Address; amount: bigint } }
Names should say what they do and read like the rest of the SDK. Give a config
shape a named exported type rather than an inline anonymous object so it appears
in autocomplete and the reference site. Then add JSDoc on every public symbol —
one line on what it's for, plus @param/@returns/@throws where non-obvious.
Mark unstable APIs with the experimental_ prefix.
The minimal call should be minimal. Anything you can infer or default, default — don't make the consumer pass it. Reserve required arguments for what only the consumer can know; advanced knobs are optional and additive.
// Good — `true` covers the common case; reach for the object only when you need
// per-category control.
type Sponsorship = boolean | { gas: boolean; bridging: boolean; swaps: boolean }
When a failure is genuinely runtime (network, orchestrator, async execution),
throw a typed error class exported from /errors with an isXError guard — not
a bare throw new Error('string'). The message must be actionable: what went
wrong, the offending value, and what to do — addressed to an integrator who can't
see SDK internals. A fix-hint must name a real, current public export; a
wrong name is worse than no name. No leaked file names or internal jargon.
// Good — typed, catchable, and the message says what / why / how to fix.
throw new Eip7702InitSignatureRequiredError()
// "EIP-7702 initialization signature is required for 7702 accounts ...
// Use `signEip7702InitData()` to generate it."
// Bad — opaque and uncatchable: no guard, not exported, no fix hint.
throw new Error('Validator not available')
A new API should feel like the existing ones: the prepare → sign → submit → waitForExecution pipeline shape, viem types for addresses/chains/hex, the
subpath layout, async naming. Surprising-but-clever loses to
boring-and-predictable.
throw have been a type? If so, make it a type.any/as in a public signature? Remove it.scripts/reference/manifest.ts./errors with a guard and an
actionable message.changesets); bun run typecheck passes.まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Writes, reviews, and polishes @rhinestone/sdk changesets. Use when adding release notes, editing .changeset/*.md files, preparing SDK releases, or reviewing changelog wording.
日本語の概要は準備中です。原文の説明を表示しています。
How to write JSDoc on @rhinestone/sdk public symbols, which is autogenerated into the published SDK Reference. Use when adding or editing doc comments on entry points, the account instance, actions, or utils in sdk/src.
日本語の概要は準備中です。原文の説明を表示しています。
Promotes @rhinestone/sdk v3 from main to release and publishes it to npm @latest. Use when a main → release "Release" PR is open, a changeset has to reach @latest, or a release PR is stuck BEHIND or unapproved.
日本語の概要は準備中です。原文の説明を表示しています。