Vincent is a monorepo that contains multiple projects for the Vincent Agent Wallet system, a decentralized permission management framework designed to allow third-party applications to request users for permission to execute transactions on their behalf.
The repository is managed with Nx and pnpm. The monorepo structure allows for sharing code between projects while maintaining separation of concerns.
/packages: Contains all the projects in the monorepo
The Vincent system consists of several key components:
- app-dashboard: A Vite React app where users interact with the Vincent system, allowing them to create apps with their abilities and policies, update versions, manage delegatee addresses, and more.
- app-sdk: A TypeScript SDK that exposes useful abilities to interact with Vincent systems in web or Node.js environments.
- contracts-sdk: Solidity contracts that create and manage the blockchain contracts needed to enforce user-to-app delegation, record policy parameters, and store Vincent apps' onchain data.
- registry-sdk: REST API for an offchain service increasing the available info that Vincent apps can show to their users, offering discoverability and auditability services.
- policy-spending-limit: A policy that can be attached to abilities to avoid them spending more than a user-defined limit in a specific period of time.
- ability-erc20-approval: An ability to send ERC20 approve/allowance transactions from a Vincent app on behalf of the delegator.
- ability-erc20-transfer: An ability to send ERC20 transfer transactions from a Vincent app on behalf of the delegator.
- ability-sdk: An SDK exposing utilities to develop Vincent abilities and policies.
- ability-aave: An ability to interact with Aave protocol from a Vincent app on behalf of the delegator.
- ability-debridge: An ability to utilize cross-chain bridging through Debridge from a Vincent app on behalf of the delegator.
- ability-transaction-signer: An ability to sign transactions from a Vincent app on behalf of the delegator.
- ability-uniswap-swap: An ability to trigger swaps on Uniswap from a Vincent app on behalf of the delegator.
- ability-morpho: An ability to operate on Morpho vaults from a Vincent app on behalf of the delegator.
- policy-contract-whitelist: A policy that restricts interactions to a predefined set of whitelisted contract addresses.
- policy-send-counter: A policy that limits the number of transactions that can be sent within a specific time period.
- mcp-sdk: A Model Context Protocol Wrapper that converts any Vincent app into an MCP server that can be connected to any LLM client to provide it with Vincent abilities.
- mcp: An MCP runner
- Node.js (v20.11.1 or later)
- pnpm (v10.7.0)
-
Clone the repository:
git clone https://github.com/LIT-Protocol/Vincent.git cd Vincent -
Ensure pnpm is available:
corepack enable -
Install dependencies:
pnpm install
-
Build all projects:
pnpm build
- Build all projects:
pnpm build - Test all projects:
pnpm test - Lint all projects:
pnpm lint - Format code:
pnpm format - Start the dashboard in development mode:
pnpm dev:dashboard - Build the dashboard for production:
pnpm build:dashboard - Start the dashboard in production mode:
pnpm start:dashboard - Generate SDK documentation:
pnpm start:docs - Install contract dependencies:
pnpm install:contracts - Build contracts:
pnpm build:contracts - Clean the repository:
pnpm clean
Each project has its own README.md and CONTRIBUTING.md files with project-specific instructions. Please refer to these files for detailed information about developing for a specific project.
- Use Nx-specific configuration files (e.g.,
project.json,eslint.config.js,nx.json) for project and tool configuration. Avoid duplicating configuration inpackage.jsonif it can be placed in a dedicated file. - Place all new configuration in the appropriate Nx or tool-specific file, not in
package.json. - Use Nx CLI and Nx plugins for all build, test, lint, and release tasks. Prefer Nx targets over custom scripts in
package.json. - Use Nx for dependency graph management, affected commands, and workspace orchestration.
- Use Nx-native environment variable loading and validation (e.g., with
@t3-oss/env-coreand Zod schemas) in both Node and browser projects. - Keep environment variable validation and loading in a single file per project (e.g.,
src/env.tsorsrc/config/env.ts). - Use Nx dependency constraints and enforce module boundaries via
eslint.config.js. - Use Nx plugins for TypeScript, Jest, and ESLint as configured in
nx.json. - Use Nx's affected commands for efficient CI and local workflows.
- Use
.env.exampleas a template for required environment variables. - Validate all environment variables at runtime using Zod schemas.
- For Node projects, use
process.env; for browser projects, useimport.meta.envwith a prefix (e.g.,VITE_). - Never commit secrets or real
.envfiles.
- Follow the DRY (Don't Repeat Yourself) principle.
- Design files, classes, and modules with a single responsibility.
- Separate model, view, and controller logic (MVC) or follow a hexagonal/clean architecture where possible.
- Keep code simple and maintainable ("Keep It Simple, Stupid" - KISS).
- Write modular, composable, and testable code.
- Document complex logic and public APIs using standards such as Typedoc.
- Use strong typing and avoid
any(preferunknownif necessary). - Write comprehensive unit and integration tests.
- Use ESLint and Prettier for code quality, and respect the shared
eslint.config.js. - Use project-specific
CONTRIBUTING.mdandREADME.mdfor details unique to each package. - Favor hexagonal (ports and adapters) or clean architecture for new modules.
- Separate business logic from infrastructure and UI.
- Use dependency injection and inversion of control where appropriate.
- Design for testability and future extensibility.
- Follow the TypeScript coding standards and use proper typing
- Write clean, readable, and maintainable code
- Document your code with comments and JSDoc when necessary
- Write unit tests for your code
- Use ESLint and Prettier for code formatting and linting
- Fork the repository
- Create a feature branch from
main - Make your changes
- Run tests and ensure they pass
- Submit a pull request to the
mainbranch
- Ensure your code follows the coding standards
- Update documentation if necessary
- Include tests for new features or bug fixes
- Link any related issues in your pull request description
- Create a version plan with
nx release plandescribing your changes and indicating the needed version bump for each project - Request a review from a maintainer
Follow the Conventional Commits specification for your commit messages:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Types include:
feat: A new featurefix: A bug fixdocs: Documentation changesstyle: Changes that do not affect the meaning of the coderefactor: Code changes that neither fix a bug nor add a featureperf: Performance improvementstest: Adding or fixing testschore: Changes to the build process or auxiliary abilities
To release a prerelease version of a specific package for testing:
- Version the package with a prerelease identifier:
# For an alpha release
pnpm nx release version --projects=<package-name> --specifier=prerelease --preid=alpha
# Example: Release e2e-test-utils as alpha
pnpm nx release version --projects=e2e-test-utils --specifier=prerelease --preid=alphaNote: Nx will automatically bump patch versions of dependent packages when you version a package. This is expected behavior. If you don't want to publish those dependent packages, simply revert the unwanted version changes after the command completes (e.g., git checkout -- packages/apps/*/package.json), keeping only your target package's version change.
- Publish the prerelease version with a dist-tag:
# Publish with alpha tag (users must explicitly install @alpha)
pnpm nx release publish --projects=<package-name> --tag=alpha --otp=YOUR_OTP
# Example: Publish e2e-test-utils alpha
pnpm nx release publish --projects=e2e-test-utils --tag=alpha --otp=YOUR_OTPCurrently, packages/apps/registry-backend specifies version numbers for the local Vincent packages it depends on, this was a temporary fix to allow for deployment. However, it disrupts the release process so the specified versions need to be converted to workspace:* references.
- Checkout a new branch called
release/YYYY-MM-DD - Update the following in
packages/apps/registry-backend/package.json:
"@lit-protocol/vincent-ability-relay-link": "workspace:*",
"@lit-protocol/vincent-app-sdk": "workspace:*",
"@lit-protocol/vincent-contracts-sdk": "workspace:*",
"@lit-protocol/vincent-registry-sdk": "workspace:*",- Run
pnpm clean && pnpm i && pnpm build - Commit generated files and
pnpm-lock.yamlwith the commit message:chore: pnpm i && pnpm build - Run
pnpm nx release --skip-publish --dry-runand verify the output is expected - Run
pnpm nx release --skip-publishto consume the version plans, bump the version in thepackage.jsonfiles, and generate theCHANGELOG.mdfiles for each package - Run the following to publish the packages, excluding the
registry-sdkpackage:
Make sure to replace YOUR_OTP with your one-time password.
pnpm nx release publish -p \
ability-aave \
ability-aerodrome-swap \
ability-debridge \
ability-erc20-approval \
ability-erc20-transfer \
ability-evm-transaction-signer \
ability-hyperliquid \
ability-morpho \
ability-relay-link \
# ability-sol-transaction-signer \
ability-uniswap-swap \
mcp-server \
policy-contract-whitelist \
policy-send-counter \
policy-spending-limit \
registry-backend \
ability-sdk \
app-sdk \
contracts-sdk \
e2e-test-utils \
mcp-sdk \
# wrapped-keys \
--otp=YOUR_OTP- Publish the Abilities and Policies to IPFS:
pnpx nx run-many --target=action:only:deploy --all - Revert the changes made to
packages/apps/registry-backend/package.jsonin step 2: replaceworkspace:*with the new version numbers for each Vincent dependency package after step 6 - Run
pnpm clean && pnpm i && pnpm build - Commit the
pnpm-lock.yaml, push your changes, and push the generated git tags withgit push --tags - Open a PR against the
mainbranch from yourrelease/YYYY-MM-DDbranch
This repository is structured as a monorepo with multiple projects, each with its own documentation. When working with AI-powered editors like Cursor, GitHub Copilot, or other AI assistants, please note:
-
Root Context: When working at the repository root, AI editors should consider all documentation files (README.md, CONTRIBUTING.md) at the root level to understand the overall project structure and contribution guidelines.
-
Project-Specific Context: When working within a specific project directory (e.g.,
/packages/sdk/), AI editors should prioritize the project-specific documentation (README.md, CONTRIBUTING.md) in that directory, while still being aware of the root context.
- Root
/README.md: Overview of the entire Vincent system - Root
/CONTRIBUTING.md: General contribution guidelines for all projects - Project-specific
/packages/<project>/README.md: Detailed information about a specific project - Project-specific
/packages/<project>/CONTRIBUTING.md: Project-specific contribution guidelines
AI editors should:
- First load the project-specific documentation when working in a project directory
- Supplement with root documentation for overall context
- Consider relationships between projects as described in the root documentation
This approach ensures that AI editors provide relevant, project-specific assistance while maintaining awareness of the broader system architecture.
This project is licensed under the MIT License - see the LICENSE file for details.