diff --git a/.github/workflows/nym-wallet-storybook.yml b/.github/workflows/nym-wallet-storybook.yml
new file mode 100644
index 0000000000..b7930ed200
--- /dev/null
+++ b/.github/workflows/nym-wallet-storybook.yml
@@ -0,0 +1,55 @@
+name: Nym Wallet Storybook
+
+on:
+ push:
+ paths:
+ - 'nym-wallet/**'
+
+jobs:
+ build:
+ runs-on: custom-runner-linux
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install rsync
+ run: sudo apt-get install rsync
+ - uses: rlespinasse/github-slug-action@v3.x
+ - uses: actions/setup-node@v2
+ with:
+ node-version: '16'
+ - name: Setup yarn
+ run: npm install -g yarn
+ - name: Build dependencies
+ run: yarn && yarn build
+ - name: Build storybook
+ run: yarn storybook:build
+ working-directory: ./nym-wallet
+ - name: Deploy branch to CI www (storybook)
+ continue-on-error: true
+ uses: easingthemes/ssh-deploy@main
+ env:
+ SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
+ ARGS: "-rltgoDzvO --delete"
+ SOURCE: "nym-wallet/storybook-static/"
+ REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
+ REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
+ TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/wallet-${{ env.GITHUB_REF_SLUG }}
+ EXCLUDE: "/dist/, /node_modules/"
+ - name: Keybase - Node Install
+ run: npm install
+ working-directory: .github/workflows/support-files
+ - name: Keybase - Send Notification
+ env:
+ NYM_NOTIFICATION_KIND: nym-wallet
+ NYM_PROJECT_NAME: "nym-wallet"
+ NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
+ NYM_CI_WWW_LOCATION: "wallet-${{ env.GITHUB_REF_SLUG }}"
+ GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
+ GIT_BRANCH: "${GITHUB_REF##*/}"
+ KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
+ KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
+ KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
+ KEYBASE_NYM_CHANNEL: "ci-nym-wallet"
+ IS_SUCCESS: "${{ job.status == 'success' }}"
+ uses: docker://keybaseio/client:stable-node
+ with:
+ args: .github/workflows/support-files/notifications/entry_point.sh
diff --git a/.github/workflows/support-files/notifications/send_message.js b/.github/workflows/support-files/notifications/send_message.js
index fa95444192..eacd5af1ed 100644
--- a/.github/workflows/support-files/notifications/send_message.js
+++ b/.github/workflows/support-files/notifications/send_message.js
@@ -3,7 +3,7 @@ require('dotenv').config();
const Bot = require('keybase-bot');
let context = {
- kinds: ['ts-packages', 'network-explorer', 'nightly'],
+ kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly'],
};
/**
diff --git a/.github/workflows/support-files/nym-wallet/index.js b/.github/workflows/support-files/nym-wallet/index.js
new file mode 100644
index 0000000000..be74285c12
--- /dev/null
+++ b/.github/workflows/support-files/nym-wallet/index.js
@@ -0,0 +1,29 @@
+const Handlebars = require('handlebars');
+const fs = require('fs');
+const path = require('path');
+
+async function addToContextAndValidate(context) {
+ if (!context.env.NYM_CI_WWW_LOCATION) {
+ throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
+ }
+ if (!context.env.NYM_CI_WWW_BASE) {
+ throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
+ }
+}
+
+async function getMessageBody(context) {
+ const source = fs
+ .readFileSync(
+ context.env.IS_SUCCESS === 'true'
+ ? path.resolve(__dirname, 'templates', 'success')
+ : path.resolve(__dirname, 'templates', 'failure'),
+ )
+ .toString();
+ const template = Handlebars.compile(source);
+ return template(context);
+}
+
+module.exports = {
+ addToContextAndValidate,
+ getMessageBody,
+};
diff --git a/.github/workflows/support-files/nym-wallet/templates/failure b/.github/workflows/support-files/nym-wallet/templates/failure
new file mode 100644
index 0000000000..adc2896ace
--- /dev/null
+++ b/.github/workflows/support-files/nym-wallet/templates/failure
@@ -0,0 +1,11 @@
+🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
+> :rocket: {{ env.NYM_PROJECT_NAME }}
+> 🔴 **FAILURE** :cry:
+> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
+> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
+> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
+
+Commit message:
+```
+{{ env.GIT_COMMIT_MESSAGE }}
+```
diff --git a/.github/workflows/support-files/nym-wallet/templates/success b/.github/workflows/support-files/nym-wallet/templates/success
new file mode 100644
index 0000000000..826f75e977
--- /dev/null
+++ b/.github/workflows/support-files/nym-wallet/templates/success
@@ -0,0 +1,15 @@
+🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
+> :rocket: {{ env.NYM_PROJECT_NAME }}
+> ✅ **SUCCESS**
+
+> ➡️➡️➡️➡️➡️ **View output:**
+> `storybook`: https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }}
+
+> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
+> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
+> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
+
+Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
+```
+{{ env.GIT_COMMIT_MESSAGE }}
+```
diff --git a/nym-wallet/.storybook/main.js b/nym-wallet/.storybook/main.js
new file mode 100644
index 0000000000..db6de0998f
--- /dev/null
+++ b/nym-wallet/.storybook/main.js
@@ -0,0 +1,57 @@
+/* eslint-disable no-param-reassign */
+const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
+const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
+
+module.exports = {
+ stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
+ addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-interactions'],
+ framework: '@storybook/react',
+ core: {
+ builder: 'webpack5',
+ },
+ // webpackFinal: async (config, { configType }) => {
+ // // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
+ // // You can change the configuration based on that.
+ // // 'PRODUCTION' is used when building the static version of storybook.
+ webpackFinal: async (config) => {
+ config.module.rules.forEach((rule) => {
+ // look for SVG import rule and replace
+ // NOTE: the rule before modification is /\.(svg|ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/
+ if (rule.test?.toString().includes('svg')) {
+ rule.test = /\.(ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/;
+ }
+ });
+
+ // handle asset loading with this
+ config.module.rules.unshift({
+ test: /\.svg(\?.*)?$/i,
+ issuer: /\.[jt]sx?$/,
+ use: ['@svgr/webpack'],
+ });
+
+ config.resolve.extensions = ['.tsx', '.ts', '.js'];
+ config.resolve.plugins = [new TsconfigPathsPlugin()];
+
+ config.plugins.push(new ForkTsCheckerWebpackPlugin({
+ typescript: {
+ mode: 'write-references',
+ diagnosticOptions: {
+ semantic: true,
+ syntactic: true,
+ },
+ },
+ }));
+
+ if (!config.resolve.alias) {
+ config.resolve.alias = {};
+ }
+
+ config.resolve.alias['@tauri-apps/api'] = `${__dirname}/mocks/tauri`;
+
+ // Return the altered config
+ return config;
+ },
+ features: {
+ emotionAlias: false,
+ },
+};
diff --git a/nym-wallet/.storybook/mocks/tauri/index.js b/nym-wallet/.storybook/mocks/tauri/index.js
new file mode 100644
index 0000000000..1288b5215f
--- /dev/null
+++ b/nym-wallet/.storybook/mocks/tauri/index.js
@@ -0,0 +1,13 @@
+/**
+ * This is a mock for Tauri's API package (@tauri-apps/api), to prevent stories from being excluded, because they either use
+ * or import dependencies that use Tauri.
+ */
+
+module.exports = {
+ invoke: (operation) => {
+ console.error(`Tauri cannot be used in Storybook. The operation requested was "${operation}". You can add mock responses to "nym_wallet/.storybook/mocks/tauri.js" if you need. The default response is "void".`);
+ return new Promise((resolve, reject) => {
+ reject(new Error(`Tauri operation ${operation} not available in storybook.`));
+ });
+ },
+}
\ No newline at end of file
diff --git a/nym-wallet/.storybook/mocks/tauri/window.js b/nym-wallet/.storybook/mocks/tauri/window.js
new file mode 100644
index 0000000000..9f0afeeebd
--- /dev/null
+++ b/nym-wallet/.storybook/mocks/tauri/window.js
@@ -0,0 +1,10 @@
+/**
+ * This is a mock for Tauri's API package (@tauri-apps/api/window), to prevent stories from being excluded, because they either use
+ * or import dependencies that use Tauri.
+ */
+
+module.exports = {
+ appWindow: {
+ maximize: () => undefined,
+ }
+}
diff --git a/nym-wallet/.storybook/preview.js b/nym-wallet/.storybook/preview.js
new file mode 100644
index 0000000000..73ab87b2dd
--- /dev/null
+++ b/nym-wallet/.storybook/preview.js
@@ -0,0 +1,19 @@
+import { NymWalletThemeWithMode } from '../src/theme/NymWalletTheme';
+
+export const parameters = {
+ actions: { argTypesRegex: "^on[A-Z].*" },
+ controls: {
+ matchers: {
+ color: /(background|color)$/i,
+ date: /Date$/,
+ },
+ },
+}
+
+const withThemeProvider = (Story, context) => (
+