Overview
SubWallet Extension follows an open contribution model where individuals making significant and valuable contributions are given commit access to contribute as they see fit. The project operates more like an open wiki than a standard guarded open source project.Ground Rules
There are a few basic ground rules for all contributors (including maintainers):1. No Force Pushes
Never use--force pushes or modify the Git history in any way. If you need to rebase, ensure you do it in your own repository.
2. Use Feature Branches
All ongoing work must be done in non-master branches, prefixed with a short name moniker:3. All Changes Require Pull Requests
All modifications must be made in a pull request to solicit feedback from other contributors. Direct commits to master are not allowed.4. Wait for CI to Pass
A pull request must not be merged until CI has finished successfully.Getting Started
Prerequisites
Before you begin contributing, make sure you have:- Node.js and Yarn installed
- A code editor with ESLint support configured
- Familiarity with the project structure
Project Architecture
SubWallet Extension is forked from polkadot-js/extension and follows a specific architecture: Background Environment- Compiled from
packages/extension-koni/src/background.ts - Handles messages from extension pages and Chrome tabs via Chrome API Message Passing
- Saves all state to store and persists to Chrome storage
- Runs cronjobs
popup.html: Main page that opens when clicking the extension iconportfolio.html: More complex views like dashboard and transactions
- Scripts injected into Chrome tabs
Key Packages
- extension-base: Main features for background, API calls, data persistence, and inject scripts
- extension-koni-base: Custom package extending extension-base
- extension-koni-ui: UI components for the extension popup
- extension-koni: Main entry point with injection and background processing logic
- extension-chains: Chain definitions and metadata
- extension-dapp: Wrapper for dapp integration
- extension-inject: Wrapper for extension injection
- extension-compat-metamask: MetaMask compatibility layer
Development Workflow
Adding a New API
- Navigate to
packages/extension-koni-base/src/api - Add a new file based on the API type
- Simple APIs can be defined as functions; complex APIs should be defined as objects
Adding a Store
Stores persist data into local storage and are defined inpackages/extension-koni-base/src/store:
- BaseStore: Basic functions for Chrome local storage persistence
- SubscribableStore: Extends BaseStore with RxJS subject for subscriptions
Adding Message Handlers
SubWallet uses message passing to communicate between Background, Extensions, and Chrome Tabs:- Define request type in
KoniRequestSignaturesinterface:
- Type name starting with
pri(extension) orpub(tabs) - Request type
- Response type
- Subscription param type (optional)
- Add handler in
KoniExtensionorKoniTabsofextension-koni-base - Add caller in
messaging.tsofextension-koni-ui
Adding Cronjobs
Cronjobs are defined inpackages/extension-koni-base/src/cron:
- Create a separate file for related cron actions
- Define the cronjob in the
initmethod of classKoniCron
UI Development
SubWallet Extension UI is built with ReactJS: Structure:assets/: Images and resourcescomponents/: Common componentshooks/: Global function hooksi18n/: Internationalizationstores/: Redux stores with React hookspartials/: Header componentsutil/: Utility methodsmessaging.ts: Background communication
- Define store reducers and state using
createSlice - Map reducers to root store in
index.ts
Testing
SubWallet uses Jest for testing:- Create test files with the naming pattern
filename.spec.ts - Run tests with
yarn test - Ensure all tests pass before submitting a PR
Before You Commit
Code Validation
Run the linter before every commit:Run Tests
Important Notes
SubWallet aims to add more features while maintaining the ability to rebase the polkadot-js origin at any time.