SKILL.md
Update GraphQL Schema
Updates the SDK's GraphQL schema and related types from an API server instance.
Usage
/schema-update local # Download from local server
/schema-update staging # Download from staging server
/schema-update # Will prompt for server choice
Checklist
You MUST use TodoWrite to create a todo for EACH step below. Mark each complete only after verification.
Download Schema
- Determine server source (from argument or ask user):
localorstaging - Run schema download from
packages/graphql:
- Local: pnpm gql:download:local - Staging: pnpm gql:download:staging
- Run
pnpm gql:generate:introspectionto generate GraphQL documents
Update Documents
- Cross-reference
packages/graphql/schema.graphqlwith existing GQL documents - Add missing fields to existing fragments
- Introduce new fragments if necessary
- If new queries or mutations exist in schema, ask user if they should be added
Check for New Enums
- Search for new
enumdefinitions inpackages/graphql/schema.graphql - For each new enum:
- Add enum definition to packages/graphql/src/enums.ts with JSDoc comments - Import the enum type in packages/graphql/src/graphql.ts - Add scalar binding in graphql config (alphabetically ordered)
- Note: Do NOT create separate type exports for enums - the enum definition serves as both value and type
Export Input Types
- Check for new input types in schema
- Common types (used across multiple queries): export from
packages/graphql/src/inputs.ts - Query-specific types: colocate with corresponding query files (permits.ts, transactions.ts, swaps.ts, user.ts, reserve.ts, hub.ts, misc.ts)
- Use pattern:
export type InputName = ReturnType<typeof graphql.scalar<'InputName'>>; - Exclude fork-related input types unless explicitly needed
- Ensure scalar bindings exist in
graphql.tsfor all input types
Update URQL Cache Configuration
Update packages/client/src/cache.ts to handle new/removed types:
Keys Section
- Add new types with
idfield: Type thedataparameter with the fragment type from@aave/graphqland returndata.id.
``typescript NewTypeName: (data: NewTypeName) => data.id, ``
- Add ephemeral types (value objects without stable identity): Return
nullto disable normalization
``typescript NewValueObject: () => null, ``
- Remove deleted types: Remove any types that no longer exist in the schema
- When unsure: If you're uncertain whether it needs normalization, ask the user
Resolvers Section
Add field transformers for enhanced client-side types:
- DateTime fields: Transform to JavaScript
Dateobjects
``typescript TypeName: { dateField: transformToDate, // for non-nullable DateTime nullableDateField: transformToNullableDate, // for nullable DateTime }, ``
- BigDecimal fields: Transform to
BigDecimalclass instances
``typescript TypeName: { decimalField: transformToBigDecimal, // for non-nullable BigDecimal nullableDecimalField: transformToNullableBigDecimal, // for nullable BigDecimal }, ``
- BigInt fields: Transform to native BigInt
``typescript TypeName: { bigIntField: transformToBigInt, }, ``
Common Patterns
- Activity types (
*Activity) typically havetimestamp: DateTime!→ usetransformToDate - Types with
createdAt: DateTime(nullable) → usetransformToNullableDate - Types with
createdAt: DateTime!(non-nullable) → usetransformToDate - Health factor types have nullable
BigDecimalfields → usetransformToNullableBigDecimal
Update Wrapped-Native Transform Lists
When new object types are added to the schema, evaluate whether they belong in packages/client/src/displayTransform.ts:
- For each new object type, ask: does it represent a protocol reserve context (i.e. its
Erc20Tokendescendants are reserve assets like WETH that should display as ETH)?
- If yes → add to WRAPPEDNATIVETRANSFORM_ALLOWLIST
- Does it represent a user wallet balance or reward payout that could appear nested inside a reserve context but should NOT be transformed?
- If yes → add to WRAPPEDNATIVETRANSFORM_BLOCKLIST
- If uncertain, ask the user — don't silently skip
Note: Types in neither list are transparent — they inherit the transform context from their parent. Only add a type when it needs to change the context (turn it on or off).
Validate
IMPORTANT: Do not mark the schema update complete until build and all tests pass.
- Run
pnpm checkfrompackages/graphqlto verify document integrity - Run
pnpm buildto ensure TypeScript compilation succeeds
- If build fails, fix the errors and re-run pnpm build - Repeat until build succeeds with zero errors
- Run
pnpm test --runto verify tests pass
- If tests fail, analyze failures, fix the code, and re-run tests - If the fix was in a sub-package compared to where the tests failed, re-run pnpm build first - Repeat until all tests pass
- Run
pnpm lint:fixto format code - Confirm both build and tests pass before marking complete
Code Patterns
Enum Definition (enums.ts)
/**
* Description of what this enum represents.
*/
export enum EnumName {
/**
* Description of this value
*/
VALUE_ONE = 'VALUE_ONE',
/**
* Description of this value
*/
VALUE_TWO = 'VALUE_TWO',
}
Scalar Binding (graphql.ts)
// Add to imports
import type { ..., EnumName } from './enums';
// Add to scalars config (alphabetically)
scalars: {
...
EnumName: EnumName,
...
}
Input Type Export
export type InputName = ReturnType<typeof graphql.scalar<'InputName'>>;
Stop Conditions
| Condition | Action |
|---|---|
| Schema download fails | Check if server is running, verify URL |
pnpm check fails |
Fix document errors before proceeding |
| Build fails | Fix TypeScript errors, re-run build until it passes |
| Tests fail | Investigate and fix failing tests, re-run until all pass |
Never mark the schema update as complete while build errors or test failures exist. The iterative fix-and-verify loop is mandatory.
Common Mistakes
- Creating type exports for enums - Enums are both values and types; don't use
ReturnType<typeof graphql.scalar<'EnumName'>> - Adding new queries/mutations without being asked - Only update existing documents unless explicitly requested
- Forgetting scalar bindings - Every input type needs a corresponding entry in
graphql.ts - Non-alphabetical ordering - Scalar bindings should be alphabetically ordered
- Missing JSDoc comments - All enums should have documentation
- Forgetting cache.ts updates - New types need keys configuration; types with DateTime/BigDecimal/BigInt need resolvers
- Wrong nullable transformer - Use
transformToNullableDate/transformToNullableBigDecimalfor nullable fields, non-nullable variants for required fields - Missing type imports in cache.ts - Add imports for any new types used in the keys section
- Marking complete with failing build/tests - Always run
pnpm buildandpnpm test --runand fix all errors before marking complete - Skipping the wrapped-native transform evaluation - Every new object type must be checked against
WRAPPEDNATIVETRANSFORMALLOWLIST/WRAPPEDNATIVETRANSFORMBLOCKLISTindisplayTransform.ts; silently omitting it can cause wrong token display