Skip to content

Development

Peter Mai edited this page Jul 1, 2022 · 6 revisions

Development Guide

Add API

  • API is defined in folder packages/extension-koni-base/src/api
    • Add new files depending on types of API
    • Simple API can be defined in Function, more complicated API should be defined in Object.

Add store

Store is used to persist data into local storage. Store is defined in folder packages/extension-koni-base/src/store

  • Store class should extend class BaseStore or SubscribableStore and overwrite class prefix call via constructor.
    • BaseStore includes basic functions that are persisted in Chrome local storage.
    • SubscribableStore extends BaseStore, includes rxjs subject and can be subscribed with method getSubject(). This subject is triggered every time data is set.
    export default class PriceStore extends SubscribableStore<PriceJson> {
      constructor () {
        super(EXTENSION_PREFIX ? `${EXTENSION_PREFIX}price` : null);
      }
    }
  • Defined in class KoniState and called by KoniExtension, KoniTabs or KoniCron.
    export default class KoniState extends State {
      private readonly priceStore = new PriceStore();
      private priceStoreReady = false;
    
      public setPrice (priceData: PriceJson, callback?: (priceData: PriceJson) => void): void {
        ...
      }
    
      public getPrice (update: (value: PriceJson) => void): void {
        ...
      }
      
      public subscribePrice () {
        return this.priceStore.getSubject();
      }
    }

Add message handle

Subwallet extension uses message passing concept via browser API to interact between Background - Extension - Chrome Tabs.

  • Extension or Chrome Tabs send a message with ID and type to Background.
  • Background handles message by ID, type and response data.
  • There are 2 message types:
    • One time message: Extension or Chrome Tabs will send message request and listen to response. Listener will be deleted after response has been received.
    • Subscription message: Same as one time message but listener continues to receive data util window is closed.
  • Steps to add new message handle:
    • Add request type:
      • New request type must be defined in interface KoniRequestSignatures
        export interface KoniRequestSignatures {
          'pri(price.getPrice)': [RequestPrice, PriceJson] // Message type from extension
          'pri(price.getSubscription)': [RequestSubscribePrice, boolean, PriceJson] // Message type from extension with subscription
          'pub(utils.getRandom)': [RandomTestRequest, number] // Message type from Tabs
        }
      • Every message type must includ:
        • Type name like pri(price.getPrice). Message type from extension must start with pri, message type from Tabs must start with pub.
        • Request type like RequestPrice
        • Response type like PriceJson
        • Subscription param type (optional) like PriceJson
    • Add handle (Background):
      • Add new case in function handle of KoniExtension or KoniTabs of package extension-koni-base
    • Add caller (Extension, Chrome Tabs):
      • Add new function in file messaging.ts of package extension-koni-ui to send request and handle received data.

Add cron

Cronjob is defined in folder packages/extension-koni-base/src/cron.

  • Group of cron actions should be defined in a separate file in this folder.
  • Defining new cronjob in method init of class KoniCron

Develop UI

  • SubWallet extension UI is built with ReactJS.
  • Popup: Main extension page shows up when users click on extension icon in browser extension list.
  • Portfolio (Coming soon): Display more complicated view like dashboard, transaction, etc...
  • Other folders:
    • assets: images, resources of extensions
    • components: common components used in extension pages
    • hooks: public hook for global function
    • i18n: internationalization
    • stores: redux stores generate with react hook
    • partials: header components
    • util: utilities methods
    • messaging.ts: send to background and handle return message.

Add new redux store

  • Subwallet extension uses redux-tookit to generate store.
  • Define redux store reducers and states in a separate file by method createSlice in redux toolkit.
  • Map reducer into root store in file index.ts.

Add new message caller

Read "Add message handle"

Auto validate

Extension auto validates code with eslint. Please set up eslint in editor and run yarn lint before committing code.

Write test

SubWallet runs test with jest. To test all code just run yarn test

  • Create new file with name filename.spec.ts to write test.
  • Some special test file that use localtest and not fit with global test should be name in format ignore-filename.spec.ts.

Auto build with Github action

  • Versioning:
    • Dev version: Trigger any push on koni-dev or any pull request to koni-dev. Build with be named by last commit message on discord depend on config in github action.
    • Beta version: Any time push code to master with out change manual change version in main package.json file. Version will auto increase by add x.y.z-0 if current version is x.y.z or change to x.y.z-(n+1) if current versoin is x.y.z-n
    • Stable version:
      • Manual change version in main file package.json from x.y.z-n to x.y.z
      • Update CHANGELOG.md include version name
      • Build release with be push as draft in Github release.
Clone this wiki locally