generated from MetaMask/template-snap-monorepo
-
-
Notifications
You must be signed in to change notification settings - Fork 3
feat: add AGENTS.md project guide for agents #272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,298 @@ | ||
| # AGENTS.md - snap-7715-permissions Project Guide | ||
|
|
||
| This document provides agents with essential information for working on the snap-7715-permissions monorepo. | ||
|
|
||
| ## Project Overview | ||
|
|
||
| This is a monorepo implementing ERC-7715 permissions for MetaMask Snaps. It contains: | ||
|
|
||
| - **@metamask/permissions-kernel-snap** - Kernel snap for managing permissions | ||
| - **@metamask/gator-permissions-snap** - DeleGator permissions snap | ||
| - **Shared utilities and types** - Common code across snaps | ||
| - **Development/test site** - Local testing environment | ||
|
|
||
| ## Technology Stack | ||
|
|
||
| - **Node Version**: 20.x or 22.x (see `.nvmrc`) | ||
| - **Package Manager**: Yarn 4.10.1 with workspaces | ||
| - **Language**: TypeScript 5.8.3 (strict mode) | ||
| - **Testing**: Jest with @metamask/snaps-jest | ||
| - **Linting**: ESLint 9 with MetaMask configs | ||
| - **Formatting**: Prettier 3.6.2 | ||
| - **Runtime**: MetaMask Snaps | ||
|
|
||
| ## Build Commands | ||
|
|
||
| ```bash | ||
| # Install dependencies | ||
| yarn install | ||
|
|
||
| # Full setup with snap submodules | ||
| yarn prepare:snap | ||
|
|
||
| # Build all packages | ||
| yarn build | ||
|
|
||
| # Build and pack for distribution | ||
| yarn build:pack | ||
| ``` | ||
|
|
||
| ## Development Commands | ||
|
|
||
| ```bash | ||
| # Start development servers | ||
| yarn start | ||
| # Access at http://localhost:8000/ | ||
| # Snaps: | ||
| # - permissions-kernel-snap: local:http://localhost:8081 | ||
| # - gator-permissions-snap: local:http://localhost:8082 | ||
|
|
||
| # Run tests | ||
| yarn test | ||
|
|
||
| # Watch mode for tests | ||
| yarn test --watch | ||
|
|
||
| # Linting | ||
| yarn lint # Run all linters | ||
| yarn lint:eslint # ESLint only | ||
| yarn lint:fix # Fix linting issues | ||
| yarn lint:misc # Check markdown, JSON, etc. | ||
|
|
||
| # Update and validate changelogs | ||
| yarn changelog:update | ||
| yarn changelog:validate | ||
| ``` | ||
|
|
||
| ## Code Style and Standards | ||
|
|
||
| ### Formatting Requirements | ||
|
|
||
| - **Prettier** automatically formats code with: | ||
| - Single quotes (') | ||
| - 2-space indentation | ||
| - Trailing commas throughout | ||
| - Quote props as-needed | ||
|
|
||
| All code must be formatted before committing. Linting will catch violations. | ||
|
|
||
| ### TypeScript Strictness | ||
|
|
||
| - `strict: true` enabled - full type checking | ||
| - `exactOptionalPropertyTypes: true` - no undefined on optional properties | ||
| - `noUncheckedIndexedAccess: true` - require null checks on indexed access | ||
| - Target: ES2020, Module: Node16 | ||
|
|
||
| ### ESLint Rules | ||
|
|
||
| Key rules enforced: | ||
| - No `console.log` in production code | ||
| - No unused variables | ||
| - No untyped `any` without `@ts-expect-error` | ||
| - Imports must be properly sorted | ||
| - JSDoc comments required for public APIs | ||
|
|
||
| ## Testing Standards | ||
|
|
||
| - **Test files**: Use `*.test.ts` or `*.spec.ts` suffixes | ||
| - **Structure**: Co-located with source or in `test/` directories | ||
| - **Framework**: Jest with @metamask/snaps-jest | ||
| - **Pattern**: Arrange-Act-Assert | ||
| - **Coverage**: Test happy paths AND error cases | ||
| - **Mocking**: Mock external dependencies (no real HTTP calls) | ||
|
|
||
| Example: | ||
| ```typescript | ||
| describe('parsePermission', () => { | ||
| it('should parse valid permission objects', () => { | ||
mj-kiwi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const input = { name: 'test', args: [] }; | ||
| const result = parsePermission(input); | ||
| expect(result).toEqual({ name: 'test', args: [] }); | ||
| }); | ||
|
|
||
| it('should throw on invalid input', () => { | ||
| expect(() => parsePermission({ name: '', args: [] })).toThrow(); | ||
| }); | ||
| }); | ||
| ``` | ||
|
|
||
| ## Error Handling | ||
|
|
||
| - Use MetaMask SDK error types: `InternalError`, `InvalidParamsError`, etc. | ||
| - Always provide meaningful error messages with context | ||
| - Never silently fail - log or throw on unexpected conditions | ||
| - Validate all inputs, especially at snap RPC boundaries | ||
|
|
||
| Example: | ||
| ```typescript | ||
| if (!snapId) { | ||
| throw new InternalError('Snap ID is required'); | ||
| } | ||
| ``` | ||
|
|
||
| ## Type Design | ||
|
|
||
| - Declare types explicitly for all public APIs | ||
| - Use discriminated unions for complex variants | ||
| - Avoid `any` - use `unknown` and narrow types | ||
| - Leverage `const` assertions for literal types | ||
|
|
||
| Example: | ||
| ```typescript | ||
| // Good: Discriminated union | ||
| type Result = | ||
| | { success: true; data: string } | ||
| | { success: false; error: Error }; | ||
|
|
||
| // Bad: Optional properties without discrimination | ||
| type Result = { | ||
| success: boolean; | ||
| data?: string; | ||
| error?: Error; | ||
| }; | ||
| ``` | ||
mj-kiwi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ## Snap Development Guidelines | ||
|
|
||
| ### Entry Points | ||
|
|
||
| - Single entry point per snap (e.g., `src/index.ts`) | ||
| - Export `onRpcRequest` handler and optional `onInstall`, `onUpdate`, etc. | ||
| - Use snap manifest (`snap.manifest.ts`) for metadata | ||
|
|
||
| ### RPC Handler Pattern | ||
|
|
||
| ```typescript | ||
| export const onRpcRequest: OnRpcRequestHandler = async (request) => { | ||
| const { method, params } = request; | ||
|
|
||
| switch (method) { | ||
| case 'method1': | ||
| return handleMethod1(params); | ||
| case 'method2': | ||
| return handleMethod2(params); | ||
| default: | ||
| throw new InvalidParamsError(`Unknown method: ${method}`); | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| ### State Management | ||
|
|
||
| - Use `snap.request()` with `snap_manageState` for persistence | ||
| - State must be JSON-serializable | ||
| - Keep state minimal - only store what's necessary | ||
| - Always validate state when retrieving it | ||
|
|
||
| ## Environment Variables | ||
|
|
||
| All packages throw build-time errors if required env vars are missing. Check `.env.example` in each package. | ||
|
|
||
| Common variables: | ||
| - `SNAP_ENV` - Environment (development/production) | ||
| - `KERNEL_SNAP_ID` - Snap ID of permissions kernel snap | ||
| - `STORE_PERMISSIONS_ENABLED` - Feature flag for storage ("true"/"false") | ||
|
|
||
| ## Git Workflow | ||
|
|
||
| ### Commit Messages | ||
|
|
||
| Follow the style from recent commits: | ||
| - Present tense ("add feature" not "added feature") | ||
| - Reference issues when relevant (#123) | ||
| - Keep first line under 72 characters | ||
|
|
||
| Example: `fix: update intro permission control message for clarity (#269)` | ||
|
|
||
| ### Branches | ||
|
|
||
| - Feature branches: `feat/feature-name` | ||
| - Bug fix branches: `fix/issue-name` | ||
| - Always create a PR for review | ||
|
|
||
| ### PR Guidelines | ||
|
|
||
| 1. **Clear description** - Explain what and why (not just what) | ||
| 2. **Link issues** - Reference related issues (#123) | ||
| 3. **Test coverage** - Include tests for all new code | ||
| 4. **Documentation** - Update docs if behavior changes | ||
| 5. **CI passes** - All linting and tests must pass | ||
|
|
||
| ## Dependency Management | ||
|
|
||
| - Add dependencies with `yarn add` in the appropriate workspace package | ||
| - Prefer existing dependencies in shared packages | ||
| - Avoid duplication across workspaces | ||
| - Check root `package.json` `resolutions` for pinned versions | ||
| - Scripts are disabled by default for security; use `lavamoat.allowScripts` | ||
|
|
||
| ## Security Considerations | ||
|
|
||
| 1. **No hardcoded secrets** - Use environment variables | ||
| 2. **Validate all inputs** - Especially RPC parameters | ||
| 3. **Minimize permissions** - Request only necessary snap permissions | ||
| 4. **No arbitrary code execution** - Don't use `eval` or `Function` | ||
| 5. **Sanitize logs** - Never log sensitive data | ||
|
|
||
| ## Code Comments | ||
|
|
||
| - Write comments explaining **why**, not **what** | ||
| - Use JSDoc for public APIs | ||
| - Keep comments up-to-date with code | ||
|
|
||
| Good example: | ||
| ```typescript | ||
| // Filter out archived accounts to show only active users | ||
| const activeAccounts = accounts.filter(a => !a.archived); | ||
| ``` | ||
|
|
||
| Bad example: | ||
| ```typescript | ||
| const name = user.name; // Get the user's name | ||
| ``` | ||
|
|
||
| ## Performance Guidelines | ||
|
|
||
| 1. **Minimize state size** - Snap state persists to storage | ||
| 2. **Cache appropriately** - Use in-memory cache for RPC responses | ||
mj-kiwi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 3. **Lazy load dependencies** - Don't import unused modules | ||
| 4. **Efficient serialization** - Keep JSON payloads small | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Build Errors | ||
| - Verify environment variables are set correctly | ||
| - Check Node version matches `.nvmrc` | ||
| - Clear yarn cache: `yarn cache clean` | ||
| - Rebuild: `yarn build` | ||
|
|
||
| ### Test Failures | ||
| - Ensure snaps are built before testing | ||
| - Check test environment variables are configured | ||
| - Run specific test: `yarn test --testNamePattern="test name"` | ||
|
|
||
| ### Snap Loading Issues | ||
| - Verify localhost ports (8081, 8082) are available | ||
| - Check Flask version is 12.14.2+ | ||
| - Clear Flask cache in settings | ||
| - Validate snap manifest is correct | ||
|
|
||
| ## Key Files and Directories | ||
|
|
||
| - `AGENTS.md` - This file - project guidelines for agents | ||
| - `CONTRIBUTING.md` - Contribution guidelines | ||
| - `README.md` - Project overview | ||
| - `packages/*/src/index.ts` - Snap entry points | ||
| - `packages/*/snap.manifest.ts` - Snap metadata | ||
| - `tsconfig.json` - TypeScript configuration (strict mode) | ||
| - `.prettierrc.js` - Prettier formatting rules | ||
| - `.eslintrc.js` - ESLint configuration | ||
| - `yarn.lock` - Dependency lockfile | ||
|
|
||
| ## References | ||
|
|
||
| - [ERC-7715 Specification](https://eip.tools/eip/7715) | ||
| - [ERC-7710 Specification](https://eip.tools/eip/7710) | ||
| - [MetaMask Snaps Docs](https://docs.metamask.io/snaps/) | ||
| - [MetaMask Snaps Repository](https://github.com/MetaMask/snaps) | ||
| - [Delegation Framework](https://github.com/MetaMask/delegation-framework) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.