ワンクリックで
add-sdk-mutation
// Add a new blockchain mutation to @ecency/sdk and wire it up in the web app
// Add a new blockchain mutation to @ecency/sdk and wire it up in the web app
Add a new feature to the Ecency web app following established patterns
Add a new query to @ecency/sdk or the web app with React Query integration
Review code changes for bugs, patterns violations, and common pitfalls in the vision-next codebase
Debug common issues in the vision-next Hive web app with known solutions and investigation patterns
| name | add-sdk-mutation |
| description | Add a new blockchain mutation to @ecency/sdk and wire it up in the web app |
| argument-hint | ["operation-name"] |
| disable-model-invocation | true |
Create a new Hive blockchain mutation in @ecency/sdk and wire it into the web app.
All blockchain mutations live in @ecency/sdk and follow a 3-layer architecture:
@ecency/sdk (platform-agnostic mutation hook)
↓ wrapped by
apps/web/src/api/sdk-mutations/ (web-specific wrapper adding auth adapter)
↓ used by
apps/web/src/api/mutations/ (app-specific orchestration: optimistic updates, error handling)
↓ used by
Feature components
Location: packages/sdk/src/modules/<domain>/mutations/use-<operation>.ts
Use an existing mutation as a reference. Key patterns:
import { useBroadcastMutation, AuthorityLevel } from "@/modules/core/mutations/use-broadcast-mutation";
import { AuthContextV2 } from "@/modules/core/types/auth";
export function use<Operation>(username?: string, auth?: AuthContextV2) {
return useBroadcastMutation(
["<operation-key>"],
async (args: { /* mutation params */ }) => {
// Build and return the Hive operation(s)
return [
[
"<hive_operation_name>",
{
// operation fields
}
]
];
},
username,
auth,
{
authorityLevel: AuthorityLevel.POSTING, // or ACTIVE for transfers/delegations
// onSuccess, onMutate, onError for cache management
}
);
}
Authority levels:
POSTING — votes, comments, reblogs, follows, community rolesACTIVE — transfers, delegations, power up/down, account updatesOWNER — password changes (rare)Reference files to study:
packages/sdk/src/modules/posts/mutations/use-vote.tspackages/sdk/src/modules/posts/mutations/use-reblog.tspackages/sdk/src/modules/posts/mutations/use-comment.tsAdd the export to the module's index.ts:
// packages/sdk/src/modules/<domain>/index.ts
export * from "./mutations/use-<operation>";
Verify it's re-exported from the SDK root via the module chain.
Location: packages/sdk/src/modules/core/query-keys.ts
// Add to the relevant domain namespace
static <domain> = {
_prefix: ["<domain>"] as const,
<operation>: (param: string) => [...QueryKeys.<domain>._prefix, "<operation>", param] as const,
};
Location: apps/web/src/api/sdk-mutations/use-<operation>-mutation.ts
Every web wrapper follows this exact pattern:
import { use<Operation> } from "@ecency/sdk";
import { useActiveAccount } from "@/core/global-store/modules/authentication";
import { createWebBroadcastAdapter } from "@/providers/sdk";
export function use<Operation>Mutation() {
const { activeUser } = useActiveAccount();
const adapter = createWebBroadcastAdapter();
return use<Operation>(activeUser?.username, { adapter });
}
Add the export to apps/web/src/api/sdk-mutations/index.ts.
# Rebuild SDK so web app sees the changes
pnpm --filter @ecency/sdk build
# Run SDK tests
pnpm --filter @ecency/sdk test
# Run web tests
pnpm --filter @ecency/web test
showAuthUpgradeUI handles this automatically via useBroadcastMutation