Skip to content

Commit

Permalink
Merge pull request #4341 from leather-wallet/release/tuesday
Browse files Browse the repository at this point in the history
Release/tuesday
  • Loading branch information
kyranjamie authored Oct 11, 2023
2 parents f99755e + 917a00b commit a073802
Show file tree
Hide file tree
Showing 74 changed files with 1,059 additions and 226 deletions.
15 changes: 15 additions & 0 deletions .dependency-cruiser.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ module.exports = {
path: '^(domain|constants|sys|_linklist|_stream_wrap)$',
},
},
// Overriding from recommended set
{
name: 'not-to-unresolvable',
comment:
"This module depends on a module that cannot be found ('resolved to disk'). " +
"If it's an npm module: add it to your package.json. In all other cases you " +
'likely already know what to do.',
severity: 'error',
from: {},
to: {
// Depcruiser fails on some legitimate type imports, so allowing them there
dependencyTypesNot: ['type-only'],
couldNotResolve: true,
},
},
{
name: 'no-orphans',
severity: 'error',
Expand Down
85 changes: 31 additions & 54 deletions .github/workflows/build-extension.yml
Original file line number Diff line number Diff line change
@@ -1,94 +1,71 @@
name: PR Extensions builds
on: [pull_request, workflow_dispatch]

env:
COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
MOONPAY_API_KEY: ${{ secrets.MOONPAY_API_KEY }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SEGMENT_WRITE_KEY: ${{ secrets.SEGMENT_WRITE_KEY_STAGING }}
TRANSAK_API_KEY: ${{ secrets.TRANSAK_API_KEY }}
WALLET_ENVIRONMENT: feature

jobs:
pre-run:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@ad6cb1b847ffb509a69b745b6ee2f1d14dfe14b8
uses: styfle/cancel-workflow-action@main
with:
access_token: ${{ github.token }}

update-pull-request-body:
name: Add links to built extensions
set-in-progress-message:
if: github.repository == 'leather-wallet/extension' && github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
needs:
- pre-run
steps:
- uses: kyranjamie/[email protected]
with:
header: '> Try out this version of Leather — [download extension builds](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}).'
header: '> _Building Leather…_'
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

build_chrome_extension:
name: Build debug Chrome extension
build:
name: build-${{ matrix.target }}-extension
runs-on: ubuntu-latest
needs:
- pre-run
strategy:
matrix:
target: [chromium, firefox]
env:
WALLET_ENVIRONMENT: feature
TARGET_BROWSER: ${{ matrix.target }}
COINBASE_APP_ID: ${{ secrets.COINBASE_APP_ID }}
MOONPAY_API_KEY: ${{ secrets.MOONPAY_API_KEY }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SEGMENT_WRITE_KEY: ${{ secrets.SEGMENT_WRITE_KEY_STAGING }}
TRANSAK_API_KEY: ${{ secrets.TRANSAK_API_KEY }}
PR_NUMBER: ${{ github.event.number }}
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
steps:
- uses: actions/checkout@v4

- uses: actions/cache@v3
id: cache-node-modules
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**/package.json') }}
ref: ${{ github.event.pull_request.head.sha }}

- uses: ./.github/actions/provision

- name: Add SHORT_SHA env property with commit short sha
run: echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV

- name: Build project
run: yarn build

- name: Build extension
run: sh build-ext.sh

- uses: actions/upload-artifact@v3
name: Upload Chrome Extension Zip
name: Upload ${{ matrix.target }} Extension Zip
with:
name: stacks-wallet-chromium
path: leather-chromium.zip
name: leather-${{ matrix.target }}-${{ env.SHORT_SHA }}
path: dist

build_firefox:
name: Build debug Firefox extension
set-download-link:
if: github.repository == 'leather-wallet/extension' && github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
needs:
- pre-run
env:
TARGET_BROWSER: firefox
- build
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}

- uses: actions/cache@v3
id: cache-node-modules
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**/package.json') }}

- uses: ./.github/actions/provision

- name: Build project
run: yarn build

- name: Build extension
run: sh build-ext.sh

- name: Rename file
run: mv leather-chromium.zip leather-firefox.zip

- uses: actions/upload-artifact@v3
- uses: kyranjamie/[email protected]
with:
name: stacks-wallet-firefox
path: leather-firefox.zip
header: '> Try out this version of Leather — [download extension builds](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}).'
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/publish-extensions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@ad6cb1b847ffb509a69b745b6ee2f1d14dfe14b8
uses: styfle/cancel-workflow-action@main
with:
access_token: ${{ github.token }}

Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"version": "6.9.2",
"author": "Hiro Systems PBC",
"scripts": {
"dev": "cross-env WALLET_ENVIRONMENT=development concurrently --raw \"node webpack/dev-server.js\" \"redux-devtools --hostname=localhost --port=8000\"",
"dev": "concurrently --raw \"node webpack/dev-server.js\" \"redux-devtools --hostname=localhost --port=8000\"",
"dev:test-app": "webpack serve --config test-app/webpack/webpack.config.dev.js",
"build": "cross-env WALLET_ENVIRONMENT=production webpack --config webpack/webpack.config.prod.js",
"build:analyze": "cross-env ANALYZE=true WALLET_ENVIRONMENT=production webpack --config webpack/webpack.config.prod.js",
"build": "webpack --config webpack/webpack.config.prod.js",
"build:analyze": "cross-env ANALYZE=true webpack --config webpack/webpack.config.prod.js",
"build:dev": "cross-env WALLET_ENVIRONMENT=development webpack --config webpack/webpack.config.dev.js",
"build:ext:test": "cross-env WALLET_ENVIRONMENT=testing webpack --config webpack/webpack.config.prod.js",
"build:ext:test:watch": "cross-env WALLET_ENVIRONMENT=testing webpack --config webpack/webpack.config.prod.js --watch",
Expand Down Expand Up @@ -128,6 +128,7 @@
"@ledgerhq/hw-transport-webusb": "6.27.19",
"@noble/hashes": "1.3.2",
"@noble/secp256k1": "2.0.0",
"@octokit/types": "12.0.0",
"@radix-ui/colors": "2.1.0",
"@radix-ui/react-accessible-icon": "1.0.3",
"@radix-ui/react-switch": "1.0.3",
Expand Down Expand Up @@ -289,7 +290,7 @@
"cross-env": "7.0.3",
"crypto-browserify": "3.12.0",
"deepmerge": "4.3.1",
"dependency-cruiser": "14.1.0",
"dependency-cruiser": "14.1.1",
"dotenv-webpack": "8.0.1",
"esbuild": "0.19.4",
"esbuild-loader": "4.0.2",
Expand Down
11 changes: 4 additions & 7 deletions scripts/generate-manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
*/
const deepMerge = require('deepmerge');

const IS_DEV = process.env.WALLET_ENVIRONMENT === 'development';
// Manifest can only be prod or dev
const WALLET_ENVIRONMENT =
process.env.WALLET_ENVIRONMENT === 'production' ? 'production' : 'development';

const WALLET_ENVIRONMENT = process.env.WALLET_ENVIRONMENT ?? 'development';
const IS_DEV = WALLET_ENVIRONMENT === 'development';

const PREVIEW_RELEASE = process.env.PREVIEW_RELEASE;

Expand All @@ -20,9 +22,6 @@ function generateImageAssetUrlsWithSuffix(suffix = '') {
}

const environmentIcons = {
testing: {
icons: generateImageAssetUrlsWithSuffix(PREVIEW_RELEASE ? '-preview' : ''),
},
development: {
icons: generateImageAssetUrlsWithSuffix('-dev'),
},
Expand All @@ -32,14 +31,12 @@ const environmentIcons = {
};

const contentSecurityPolicyEnvironment = {
testing: `default-src 'none'; connect-src *; style-src 'unsafe-inline'; img-src 'self' data: https:; script-src 'self' 'wasm-unsafe-eval'; object-src 'none'; frame-src 'none'; frame-ancestors 'none';`,
development:
"script-src 'self' 'wasm-unsafe-eval'; object-src 'self'; frame-src 'none'; frame-ancestors 'none';",
production: `default-src 'none'; connect-src *; style-src 'unsafe-inline'; img-src 'self' data: https:; script-src 'self' 'wasm-unsafe-eval'; object-src 'none'; frame-src 'none'; frame-ancestors 'none';`,
};

const defaultIconEnvironment = {
testing: 'assets/connect-logo/Stacks128w.png',
development: 'assets/connect-logo/Stacks128w-dev.png',
production: 'assets/connect-logo/Stacks128w.png',
};
Expand Down
63 changes: 63 additions & 0 deletions src/app/components/app-version.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useMemo } from 'react';
import { forwardRef } from 'react';

import { HTMLStyledProps, styled } from 'leather-styles/jsx';

import { BRANCH_NAME, COMMIT_SHA } from '@shared/environment';

import { openInNewTab } from '@app/common/utils/open-in-new-tab';
import { useIsLatestPullRequestBuild } from '@app/query/common/outdated-pr/outdated-pr.query';

import { Tooltip } from './tooltip';

interface AppVersionLabelProps extends HTMLStyledProps<'span'> {
isLatestVersion: boolean;
}
const AppVersionLabel = forwardRef<HTMLSpanElement, AppVersionLabelProps>(
({ children, isLatestVersion, ...props }: AppVersionLabelProps, ref) => (
<styled.span
ref={ref}
textStyle="mono"
fontSize="10px"
marginRight="10px"
mb="-4px"
ml="tight"
opacity={0.5}
textDecoration={isLatestVersion ? 'none' : 'line-through'}
{...props}
>
{children}
</styled.span>
)
);

export function AppVersion() {
const { pullRequestLink, isLatestBuild } = useIsLatestPullRequestBuild();

const version = useMemo(() => {
switch (process.env.WALLET_ENVIRONMENT) {
case 'development':
return `dev@${BRANCH_NAME}`;
case 'feature':
return `${BRANCH_NAME}#${COMMIT_SHA?.slice(0, 8)}`;
default:
return `v${VERSION}`;
}
}, []);

if (!isLatestBuild && process.env.WALLET_ENVIRONMENT === 'feature') {
return (
<Tooltip label="Outdated PR build, download the latest version">
<AppVersionLabel
isLatestVersion={false}
cursor="pointer"
onClick={() => openInNewTab(pullRequestLink ?? '')}
>
{version}
</AppVersionLabel>
</Tooltip>
);
}

return <AppVersionLabel isLatestVersion>{version}</AppVersionLabel>;
}
5 changes: 4 additions & 1 deletion src/app/components/fees-row/components/custom-fee-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ interface CustomFeeFieldProps extends StackProps {
feeCurrencySymbol: CryptoCurrencies;
lowFeeEstimate: StacksFeeEstimate;
setFieldWarning(value: string): void;
disableFeeSelection?: boolean;
}
export function CustomFeeField(props: CustomFeeFieldProps) {
const { feeCurrencySymbol, lowFeeEstimate, setFieldWarning, ...rest } = props;
const { feeCurrencySymbol, lowFeeEstimate, setFieldWarning, disableFeeSelection, ...rest } =
props;
const [field, meta, helpers] = useField('fee');

const checkFieldWarning = useCallback(
Expand Down Expand Up @@ -52,6 +54,7 @@ export function CustomFeeField(props: CustomFeeFieldProps) {
display="block"
height="32px"
name="fee"
isDisabled={disableFeeSelection}
onChange={(evt: FormEvent<HTMLInputElement>) => {
helpers.setValue(evt.currentTarget.value);

Check warning on line 59 in src/app/components/fees-row/components/custom-fee-field.tsx

View workflow job for this annotation

GitHub Actions / lint-eslint

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
// Separating warning check from field validations
Expand Down
7 changes: 4 additions & 3 deletions src/app/components/fees-row/components/fee-estimate-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ interface FeeEstimateItemProps {
isVisible?: boolean;
onSelectItem(index: number): void;
selectedItem: number;
disableFeeSelection?: boolean;
}
export function FeeEstimateItem(props: FeeEstimateItemProps) {
const { index, isVisible, onSelectItem, selectedItem } = props;
const { index, isVisible, onSelectItem, selectedItem, disableFeeSelection } = props;

const selectedIcon = useMemo(() => {
const isSelected = index === selectedItem;
Expand All @@ -29,13 +30,13 @@ export function FeeEstimateItem(props: FeeEstimateItemProps) {
isInline
mb="0px !important"
minWidth="100px"
onClick={() => onSelectItem(index)}
onClick={() => !disableFeeSelection && onSelectItem(index)}
p="tight"
>
<Text fontSize={1} fontWeight={500} ml="2px">
{labels[index]}
</Text>
{isVisible ? selectedIcon : <FiChevronDown />}
{!disableFeeSelection && (isVisible ? selectedIcon : <FiChevronDown />)}
</Stack>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@ interface FeeEstimateSelectLayoutProps {
isVisible: boolean;
onSetIsSelectVisible(value: boolean): void;
selectedItem: number;
disableFeeSelection?: boolean;
}
export function FeeEstimateSelectLayout(props: FeeEstimateSelectLayoutProps) {
const { children, isVisible, onSetIsSelectVisible, selectedItem } = props;
const { children, isVisible, onSetIsSelectVisible, selectedItem, disableFeeSelection } = props;
const ref = useRef<HTMLDivElement | null>(null);

useOnClickOutside(ref, () => onSetIsSelectVisible(false));

return (
<>
<Stack _hover={{ cursor: 'pointer' }}>
<Stack _hover={{ cursor: disableFeeSelection ? 'default' : 'pointer' }}>
<FeeEstimateItem
disableFeeSelection={disableFeeSelection}
index={selectedItem}
onSelectItem={() => onSetIsSelectVisible(true)}
selectedItem={FeeTypes.Middle}
Expand Down
13 changes: 11 additions & 2 deletions src/app/components/fees-row/components/fee-estimate-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,22 @@ interface FeeEstimateSelectProps {
onSetIsSelectVisible(value: boolean): void;
selectedItem: number;
allowCustom: boolean;
disableFeeSelection?: boolean;
}
export function FeeEstimateSelect(props: FeeEstimateSelectProps) {
const { isVisible, estimate, onSelectItem, onSetIsSelectVisible, selectedItem, allowCustom } =
props;
const {
isVisible,
estimate,
onSelectItem,
onSetIsSelectVisible,
selectedItem,
allowCustom,
disableFeeSelection,
} = props;

return (
<FeeEstimateSelectLayout
disableFeeSelection={disableFeeSelection}
isVisible={isVisible}
onSetIsSelectVisible={onSetIsSelectVisible}
selectedItem={selectedItem}
Expand Down
Loading

0 comments on commit a073802

Please sign in to comment.