Merge pull request #4080 from hirosystems/release/rainy-monday

Release/rainy monday
This commit is contained in:
Fara Woolf
2023-07-31 11:40:57 -05:00
committed by GitHub
43 changed files with 305 additions and 245 deletions

View File

@@ -3,7 +3,7 @@ LABEL maintainer="ux@blockstack.com"
ARG NODE_VERSION=12
ENV MINIFY_PRODUCTION_BUILD=true
ENV EXT_ENV="prod"
ENV WALLET_ENVIRONMENT="production"
ENV NODE_VERSION=${NODE_VERSION}
WORKDIR /src

View File

@@ -5,17 +5,17 @@
"version": "6.1.0",
"author": "Hiro Systems PBC",
"scripts": {
"dev": "cross-env NODE_ENV=development concurrently --raw \"node webpack/dev-server.js\" \"redux-devtools --hostname=localhost --port=8000\"",
"dev": "cross-env WALLET_ENVIRONMENT=development 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 NODE_ENV=production EXT_ENV=prod webpack --config webpack/webpack.config.prod.js",
"build:analyze": "cross-env ANALYZE=true NODE_ENV=production EXT_ENV=prod webpack --config webpack/webpack.config.prod.js",
"build:dev": "cross-env NODE_ENV=development EXT_ENV=development webpack --config webpack/webpack.config.dev.js",
"build:ext:test": "cross-env NODE_ENV=production TEST_ENV=true EXT_ENV=prod webpack --config webpack/webpack.config.prod.js",
"build:ext:test:watch": "cross-env NODE_ENV=production TEST_ENV=true EXT_ENV=prod webpack --config webpack/webpack.config.prod.js --watch",
"build:test-app": "cross-env NODE_ENV=production EXT_ENV=prod webpack --config ./test-app/webpack/webpack.config.prod.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:dev": "cross-env WALLET_ENVIRONMENT=development webpack --config webpack/webpack.config.dev.js",
"build:ext:test": "cross-env WALLET_ENVIRONMENT=production TEST_ENV=true webpack --config webpack/webpack.config.prod.js",
"build:ext:test:watch": "cross-env WALLET_ENVIRONMENT=production TEST_ENV=true webpack --config webpack/webpack.config.prod.js --watch",
"build:test-app": "cross-env WALLET_ENVIRONMENT=production webpack --config ./test-app/webpack/webpack.config.prod.js",
"build:test": "concurrently 'yarn build:ext:test' 'yarn build:test-app'",
"build:test-api": "concurrently 'yarn build:ext:test' 'yarn build:test-app'",
"build:test:watch": "cross-env NODE_ENV=test EXT_ENV=watch webpack --config webpack/webpack.config.prod.js",
"build:test:watch": "cross-env WALLET_ENVIRONMENT=testing webpack --config webpack/webpack.config.prod.js",
"clean": "rm -rf ./dist",
"clean:all": "rm -rf ./dist && rm -rf ./coverage && rm -rf ./node_modules",
"lint": "concurrently -g 'yarn lint:prettier' 'yarn lint:unused-exports' 'yarn lint:deps' 'yarn lint:remote-wallet-config' 'yarn lint:eslint' 'yarn lint:filename'",
@@ -28,15 +28,15 @@
"lint:remote-wallet-config": "npx ajv-cli validate -s config/wallet-config.schema.json -d config/wallet-config.json",
"lint:deps": "dependency-cruise --config .dependency-cruiser.js \"src/**/*.{ts,tsx}\"",
"prod:ext": "yarn build",
"prod:analyze": "cross-env NODE_ENV=production ANALYZE=true webpack -p",
"prod:analyze": "cross-env WALLET_ENVIRONMENT=production ANALYZE=true webpack -p",
"test:integration": "jest --config=./jest.integration.config.js --verbose=true --runInBand --testPathPattern=./tests-legacy/integration/*",
"test:integration:ci": "jest --config=./jest.integration.config.js --testPathPattern=./tests-legacy/integration/*",
"test:integration-api": "jest --config=./jest.integration.config.js --verbose=true --runInBand --testPathPattern=./tests-legacy/test-api/*",
"test:integration-api:ci": "jest --config=./jest.integration.config.js --testPathPattern=./tests-legacy/test-api/*",
"test:unit": "vitest run",
"test": "NODE_ENV=test jest --verbose=true",
"test:coverage": "NODE_ENV=test jest --collect-coverage",
"test:watch": "NODE_ENV=test jest --watch",
"test": "WALLET_ENVIRONMENT=testing jest --verbose=true",
"test:coverage": "WALLET_ENVIRONMENT=testing jest --collect-coverage",
"test:watch": "WALLET_ENVIRONMENT=testing jest --watch",
"typecheck": "tsc --noEmit"
},
"license": "MIT",
@@ -161,10 +161,10 @@
"@stacks/ui-utils": "7.5.0",
"@stacks/wallet-sdk": "6.5.4",
"@styled-system/theme-get": "5.1.2",
"@tanstack/query-sync-storage-persister": "4.29.19",
"@tanstack/react-query": "4.29.19",
"@tanstack/react-query-devtools": "4.29.19",
"@tanstack/react-query-persist-client": "4.29.19",
"@tanstack/query-sync-storage-persister": "4.32.0",
"@tanstack/react-query": "4.32.0",
"@tanstack/react-query-devtools": "4.32.0",
"@tanstack/react-query-persist-client": "4.32.0",
"@tippyjs/react": "4.2.6",
"@typescript-eslint/eslint-plugin": "5.60.1",
"@vkontakte/vk-qr": "2.0.13",
@@ -231,7 +231,7 @@
"@babel/core": "7.22.5",
"@babel/preset-react": "7.22.5",
"@babel/preset-typescript": "7.22.5",
"@btckit/types": "0.0.18",
"@btckit/types": "0.0.19",
"@emotion/babel-plugin": "11.11.0",
"@emotion/babel-preset-css-prop": "11.11.0",
"@emotion/cache": "11.11.0",
@@ -247,7 +247,7 @@
"@stacks/stacks-blockchain-api-types": "6.3.4",
"@swc-node/jest": "1.5.6",
"@swc/core": "1.3.32",
"@trivago/prettier-plugin-sort-imports": "4.1.1",
"@trivago/prettier-plugin-sort-imports": "4.2.0",
"@types/argon2-browser": "1.18.1",
"@types/chroma-js": "2.1.4",
"@types/chrome": "0.0.236",

View File

@@ -3,9 +3,9 @@
*/
const deepMerge = require('deepmerge');
const IS_DEV = process.env.NODE_ENV === 'development';
const IS_DEV = process.env.WALLET_ENVIRONMENT === 'development';
const NODE_ENV = process.env.NODE_ENV ?? 'development';
const WALLET_ENVIRONMENT = process.env.WALLET_ENVIRONMENT ?? 'development';
const PREVIEW_RELEASE = process.env.PREVIEW_RELEASE;
@@ -78,13 +78,13 @@ const manifest = {
},
host_permissions: ['*://*/*'],
content_security_policy: {
extension_pages: contentSecurityPolicyEnvironment[NODE_ENV],
extension_pages: contentSecurityPolicyEnvironment[WALLET_ENVIRONMENT],
},
web_accessible_resources: [{ resources: ['inpage.js'], matches: ['*://*/*'] }],
action: {
default_title: 'Stacks',
default_popup: 'popup.html',
default_icon: defaultIconEnvironment[NODE_ENV],
default_icon: defaultIconEnvironment[WALLET_ENVIRONMENT],
},
options_ui: {
page: 'index.html',
@@ -128,7 +128,7 @@ function generateManifest(packageVersion) {
manifest,
releaseEnvironmentConfig,
browserConfig,
environmentIcons[NODE_ENV],
environmentIcons[WALLET_ENVIRONMENT],
]);
}

View File

@@ -1,8 +1,7 @@
import { useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import * as btc from '@scure/btc-signer';
import { AllowedSighashTypes } from '@shared/rpc/methods/sign-psbt';
import { ensureArray, undefinedIfLengthZero } from '@shared/utils';
import { useRejectIfLedgerWallet } from '@app/common/rpc-helpers';
@@ -23,7 +22,7 @@ export function usePsbtRequestSearchParams() {
() => ({
appName: payload?.appDetails?.name,
allowedSighash: payload?.allowedSighash
? undefinedIfLengthZero(payload.allowedSighash.map(h => Number(h)) as btc.SignatureHash[])
? undefinedIfLengthZero(payload.allowedSighash.map(h => Number(h)) as AllowedSighashTypes[])
: undefined,
origin,
payload,
@@ -54,7 +53,7 @@ export function useRpcSignPsbtParams() {
requestId,
psbtHex,
allowedSighash: undefinedIfLengthZero(
allowedSighash.map(h => Number(h)) as btc.SignatureHash[]
allowedSighash.map(h => Number(h)) as AllowedSighashTypes[]
),
signAtIndex: undefinedIfLengthZero(ensureArray(signAtIndex).map(h => Number(h))),
};

View File

@@ -1,12 +1,12 @@
import { FullPageLoadingSpinner } from '@app/components/loading-spinner';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
interface HomeLoaderProps {
children(data: StacksAccount): React.JSX.Element;
interface CurrentStacksAccountLoaderProps {
children(data: StacksAccount): React.ReactNode;
}
export function HomeLoader({ children }: HomeLoaderProps) {
export function CurrentStacksAccountLoader({ children }: CurrentStacksAccountLoaderProps) {
const currentAccount = useCurrentStacksAccount();
if (!currentAccount) return <FullPageLoadingSpinner />;
if (!currentAccount) return null;
return children(currentAccount);
}

View File

@@ -1,59 +1,31 @@
import { useOutletContext } from 'react-router-dom';
import { Outlet } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import { Box, Stack, Text } from '@stacks/ui';
import { Box, Stack } from '@stacks/ui';
import { HomePageSelectorsLegacy } from '@tests-legacy/page-objects/home.selectors';
import { LEDGER_BITCOIN_ENABLED } from '@shared/environment';
import { useBtcAssetBalance } from '@app/common/hooks/balance/btc/use-btc-balance';
import { useStxBalance } from '@app/common/hooks/balance/stx/use-stx-balance';
import { ftDecimals } from '@app/common/stacks-utils';
import { useWalletType } from '@app/common/use-wallet-type';
import { Brc20TokensLoader } from '@app/components/brc20-tokens-loader';
import { CryptoCurrencyAssetItem } from '@app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item';
import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar';
import { BtcIcon } from '@app/components/icons/btc-icon';
import { LoadingSpinner } from '@app/components/loading-spinner';
import { Caption } from '@app/components/typography';
import { useStacksFungibleTokenAssetBalancesAnchoredWithMetadata } from '@app/query/stacks/balance/stacks-ft-balances.hooks';
import { CurrentStacksAccountLoader } from '@app/components/stacks-account-loader';
import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { Collectibles } from '../collectibles/collectibles';
import { PendingBrc20TransferList } from '../pending-brc-20-transfers/pending-brc-20-transfers';
import { BitcoinFungibleTokenAssetList } from './components/bitcoin-fungible-tokens-asset-list';
import { StacksFungibleTokenAssetList } from './components/stacks-fungible-token-asset-list';
import { StacksBalanceItem } from './components/stacks-balance-item';
interface BalancesListContextState {
address: string;
}
export function BalancesList(): React.JSX.Element {
const { address } = useOutletContext<BalancesListContextState>();
const stacksFtAssetBalances = useStacksFungibleTokenAssetBalancesAnchoredWithMetadata(address);
export function AssetsList() {
const btcAddress = useCurrentAccountNativeSegwitAddressIndexZero();
const {
stxEffectiveBalance,
stxEffectiveUsdBalance,
stxLockedBalance,
stxUsdLockedBalance,
isLoading,
} = useStxBalance();
const { btcAvailableAssetBalance, btcAvailableUsdBalance } = useBtcAssetBalance(btcAddress);
const { whenWallet } = useWalletType();
const navigate = useNavigate();
// Better handle loading state
if (isLoading) return <LoadingSpinner />;
const stxAdditionalBalanceInfo = stxLockedBalance?.amount.isGreaterThan(0) ? (
<Text>({ftDecimals(stxLockedBalance.amount, stxLockedBalance.decimals || 0)} locked)</Text>
) : undefined;
const stxAdditionalUsdBalanceInfo = stxLockedBalance?.amount.isGreaterThan(0) ? (
<Caption ml="4px">({stxUsdLockedBalance} locked)</Caption>
) : undefined;
return (
<Stack pb="extra-loose" spacing="loose" data-testid={HomePageSelectorsLegacy.BalancesList}>
{/* Temporary duplication during Ledger Bitcoin feature dev */}
@@ -78,15 +50,11 @@ export function BalancesList(): React.JSX.Element {
/>
) : null,
})}
<CryptoCurrencyAssetItem
assetBalance={stxEffectiveBalance}
usdBalance={stxEffectiveUsdBalance}
address={address}
additionalBalanceInfo={stxAdditionalBalanceInfo}
additionalUsdBalanceInfo={stxAdditionalUsdBalanceInfo}
icon={<StxAvatar />}
/>
<StacksFungibleTokenAssetList assetBalances={stacksFtAssetBalances} />
<CurrentStacksAccountLoader>
{account => <StacksBalanceItem account={account} />}
</CurrentStacksAccountLoader>
{whenWallet({
software: (
<Brc20TokensLoader>
@@ -95,8 +63,12 @@ export function BalancesList(): React.JSX.Element {
),
ledger: null,
})}
<PendingBrc20TransferList />
<Collectibles />
<Outlet />
</Stack>
);
}

View File

@@ -0,0 +1,45 @@
import { Text } from '@stacks/ui';
import { useStxBalance } from '@app/common/hooks/balance/stx/use-stx-balance';
import { ftDecimals } from '@app/common/stacks-utils';
import { CryptoCurrencyAssetItem } from '@app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item';
import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar';
import { Caption } from '@app/components/typography';
import { useStacksFungibleTokenAssetBalancesAnchoredWithMetadata } from '@app/query/stacks/balance/stacks-ft-balances.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
import { StacksFungibleTokenAssetList } from './stacks-fungible-token-asset-list';
interface StacksBalanceItemProps {
account: StacksAccount;
}
export function StacksBalanceItem({ account }: StacksBalanceItemProps) {
const stacksFtAssetBalances = useStacksFungibleTokenAssetBalancesAnchoredWithMetadata(
account.address
);
const { stxEffectiveBalance, stxEffectiveUsdBalance, stxLockedBalance, stxUsdLockedBalance } =
useStxBalance();
const stxAdditionalBalanceInfo = stxLockedBalance?.amount.isGreaterThan(0) ? (
<Text>({ftDecimals(stxLockedBalance.amount, stxLockedBalance.decimals || 0)} locked)</Text>
) : undefined;
const stxAdditionalUsdBalanceInfo = stxLockedBalance?.amount.isGreaterThan(0) ? (
<Caption ml="4px">({stxUsdLockedBalance} locked)</Caption>
) : undefined;
return (
<>
<CryptoCurrencyAssetItem
assetBalance={stxEffectiveBalance}
usdBalance={stxEffectiveUsdBalance}
address={account.address}
additionalBalanceInfo={stxAdditionalBalanceInfo}
additionalUsdBalanceInfo={stxAdditionalUsdBalanceInfo}
icon={<StxAvatar />}
/>
<StacksFungibleTokenAssetList assetBalances={stacksFtAssetBalances} />
</>
);
}

View File

@@ -6,6 +6,7 @@ import { useQueryClient } from '@tanstack/react-query';
import { RouteUrls } from '@shared/route-urls';
import { useWalletType } from '@app/common/use-wallet-type';
import { CurrentStacksAccountLoader } from '@app/components/stacks-account-loader';
import { useConfigNftMetadataEnabled } from '@app/query/common/remote-config/remote-config.query';
import { AddCollectible } from './components/add-collectible';
@@ -44,7 +45,11 @@ export function Collectibles() {
ledger: null,
})}
{isNftMetadataEnabled ? <StacksCryptoAssets /> : null}
{isNftMetadataEnabled && (
<CurrentStacksAccountLoader>
{account => <StacksCryptoAssets account={account} />}
</CurrentStacksAccountLoader>
)}
{whenWallet({
software: (

View File

@@ -3,14 +3,18 @@ import { useEffect } from 'react';
import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { parseIfValidPunycode } from '@app/common/utils';
import { useCurrentAccountNames } from '@app/query/stacks/bns/bns.hooks';
import { useNonFungibleTokensMetadata } from '@app/query/stacks/tokens/non-fungible-tokens/non-fungible-token-metadata.hooks';
import { useStacksNonFungibleTokensMetadata } from '@app/query/stacks/tokens/non-fungible-tokens/non-fungible-token-metadata.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
import { StacksBnsName } from './stacks-bns-name';
import { StacksNonFungibleTokens } from './stacks-non-fungible-tokens';
export function StacksCryptoAssets() {
interface StacksCryptoAssetsProps {
account: StacksAccount;
}
export function StacksCryptoAssets({ account }: StacksCryptoAssetsProps) {
const { data: names = [] } = useCurrentAccountNames();
const stacksNftsMetadataResp = useNonFungibleTokensMetadata();
const stacksNftsMetadataResp = useStacksNonFungibleTokensMetadata(account);
const analytics = useAnalytics();
useEffect(() => {

View File

@@ -6,7 +6,7 @@ import { bitcoinNetworkModeToCoreNetworkMode } from '@shared/crypto/bitcoin/bitc
import { LedgerRequestKeysContext } from '@app/features/ledger/generic-flows/request-keys/ledger-request-keys.context';
import { useLedgerNavigate } from '@app/features/ledger/hooks/use-ledger-navigate';
import { useActionCancellableByUser } from '@app/features/ledger/utils/stacks-ledger-utils';
import { bitcoinKeySlice } from '@app/store/ledger/bitcoin-key.slice';
import { bitcoinKeysSlice } from '@app/store/ledger/bitcoin-key.slice';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';
import { ledgerRequestKeysRoutes } from '../../generic-flows/request-keys/ledger-request-keys-route-generator';
@@ -46,7 +46,7 @@ function LedgerRequestBitcoinKeys() {
ledgerNavigate.toDeviceBusyStep(`Requesting Bitcoin Taproot address (${index - 4}…5)`);
},
});
dispatch(bitcoinKeySlice.actions.addBitcoinKeys(keys));
dispatch(bitcoinKeysSlice.actions.addBitcoinKeys(keys));
},
});

View File

@@ -1,5 +1,7 @@
import * as btc from '@scure/btc-signer';
import { AllowedSighashTypes } from '@shared/rpc/methods/sign-psbt';
import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentAccountTaprootIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/taproot-account.hooks';
@@ -14,7 +16,7 @@ import { PsbtRequestFee } from './components/psbt-request-fee';
import { PsbtRequestRaw } from './components/psbt-request-raw';
interface PsbtRequestDetailsProps {
allowedSighash?: btc.SignatureHash[];
allowedSighash?: AllowedSighashTypes[];
indexesToSign?: number[];
psbtRaw?: RawPsbt;
psbtTxInputs: btc.TransactionInput[];

View File

@@ -8,6 +8,7 @@ import {
getBtcSignerLibNetworkConfigByMode,
} from '@shared/crypto/bitcoin/bitcoin.network';
import { getAddressFromOutScript } from '@shared/crypto/bitcoin/bitcoin.utils';
import { AllowedSighashTypes } from '@shared/rpc/methods/sign-psbt';
import { ensureArray, isDefined, isUndefined } from '@shared/utils';
import { useOrdinalsAwareUtxoQueries } from '@app/query/bitcoin/ordinals/ordinals-aware-utxo.query';
@@ -44,7 +45,7 @@ function getInputValue(index: number, input: btc.TransactionInput) {
}
interface UseParsedInputsArgs {
allowedSighash?: btc.SignatureHash[];
allowedSighash?: AllowedSighashTypes[];
inputs: btc.TransactionInput[];
indexesToSign?: number[];
}

View File

@@ -2,6 +2,8 @@ import { useCallback } from 'react';
import * as btc from '@scure/btc-signer';
import { AllowedSighashTypes } from '@shared/rpc/methods/sign-psbt';
import { subtractMoney } from '@app/common/money/calculate-money';
import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentAccountTaprootIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/taproot-account.hooks';
@@ -13,7 +15,7 @@ import { usePsbtInscriptions } from './use-psbt-inscriptions';
import { usePsbtTotals } from './use-psbt-totals';
interface UseParsedPsbtArgs {
allowedSighash?: btc.SignatureHash[];
allowedSighash?: AllowedSighashTypes[];
inputs: btc.TransactionInput[];
indexesToSign?: number[];
outputs: btc.TransactionOutput[];

View File

@@ -4,6 +4,7 @@ import { hexToBytes } from '@noble/hashes/utils';
import * as btc from '@scure/btc-signer';
import { logger } from '@shared/logger';
import { AllowedSighashTypes } from '@shared/rpc/methods/sign-psbt';
import { isString, isUndefined } from '@shared/utils';
import { useCurrentAccountNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
@@ -12,7 +13,7 @@ import { useCurrentAccountTaprootSigner } from '@app/store/accounts/blockchain/b
export type RawPsbt = ReturnType<typeof btc.RawPSBTV0.decode>;
interface SignPsbtArgs {
allowedSighash?: btc.SignatureHash[];
allowedSighash?: AllowedSighashTypes[];
inputs: btc.TransactionInput[];
indexesToSign?: number[];
tx: btc.Transaction;
@@ -39,7 +40,7 @@ export function usePsbtSigner() {
// If type taproot, and the tapInternalKey is missing, assume it should
// be the account publicKey
if (taprootSigner && witnessOutputScript?.type === 'tr' && !input.tapInternalKey) {
input.tapInternalKey = taprootSigner.payment.tapInternalKey;
tx.updateInput(idx, { ...input, tapInternalKey: taprootSigner.payment.tapInternalKey });
}
try {

View File

@@ -4,6 +4,7 @@ import { useNavigate } from 'react-router-dom';
import * as btc from '@scure/btc-signer';
import { RouteUrls } from '@shared/route-urls';
import { AllowedSighashTypes } from '@shared/rpc/methods/sign-psbt';
import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { PopupHeader } from '@app/features/current-account/popup-header';
@@ -36,7 +37,7 @@ function getPsbtTxOutputs(psbtTx: btc.Transaction) {
}
interface PsbtSignerProps {
allowedSighash?: btc.SignatureHash[];
allowedSighash?: AllowedSighashTypes[];
indexesToSign?: number[];
name?: string;
origin: string;

View File

@@ -6,7 +6,7 @@ import { SuggestedFirstStepStatus, SuggestedFirstSteps } from '@shared/models/on
import { useGetAnchoredAccountBalanceListQuery } from '@app/query/stacks/balance/stx-balance.query';
import { useAllAccountsNonFungibleTokenHoldingsTotal } from '@app/query/stacks/tokens/non-fungible-tokens/non-fungible-token-holdings.hooks';
import { useGetNonFungibleTokenHoldingsQuery } from '@app/query/stacks/tokens/non-fungible-tokens/non-fungible-token-holdings.query';
import useGetNonFungibleTokenHoldingsQuery from '@app/query/stacks/tokens/non-fungible-tokens/non-fungible-token-holdings.query';
import {
useCurrentStacksAccount,
useStacksAccounts,
@@ -34,10 +34,10 @@ export function useSuggestedFirstSteps() {
const stepsStatus = useSuggestedFirstStepsStatus();
const { data: nonFungibleTokenHoldings } = useGetNonFungibleTokenHoldingsQuery(
currentAccount?.address
currentAccount?.address!
);
const firstFiveAccounts = accounts?.slice(0, 5);
const firstFiveAccounts = accounts?.slice(0, 5) ?? [];
const accountsAvailableStxBalance = useAllAccountsAvailableStxBalance(firstFiveAccounts);
const accountsNonFungibleTokenHoldings =
useAllAccountsNonFungibleTokenHoldingsTotal(firstFiveAccounts);

View File

@@ -10,7 +10,7 @@ import { LoadingSpinner } from '@app/components/loading-spinner';
import { Tabs } from '@app/components/tabs';
interface HomeTabsProps extends StackProps {
children: React.JSX.Element;
children: React.ReactNode;
}
// TODO #4013: Abstract this to generic RouteTab once choose-fee-tab updated
export function HomeTabs({ children }: HomeTabsProps) {

View File

@@ -10,22 +10,16 @@ import { Header } from '@app/components/header';
import { InAppMessages } from '@app/features/hiro-messages/in-app-messages';
import { SuggestedFirstSteps } from '@app/features/suggested-first-steps/suggested-first-steps';
import { HomeActions } from '@app/pages/home/components/home-actions';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { CurrentAccount } from './components/account-area';
import { HomeTabs } from './components/home-tabs';
import { HomeLayout } from './components/home.layout';
import { HomeLoader } from './home.loader';
export function Home() {
return <HomeLoader>{account => <HomeContainer account={account} />}</HomeLoader>;
}
interface HomeContainerProps {
account: StacksAccount;
}
function HomeContainer({ account }: HomeContainerProps) {
const { decodedAuthRequest } = useOnboardingState();
const stacksAccount = useCurrentStacksAccount();
const navigate = useNavigate();
useTrackFirstDeposit();
@@ -47,7 +41,7 @@ function HomeContainer({ account }: HomeContainerProps) {
actions={<HomeActions />}
>
<HomeTabs>
<Outlet context={{ address: account.address }} />
<Outlet context={{ address: stacksAccount?.address }} />
</HomeTabs>
</HomeLayout>
);

View File

@@ -1,13 +1,17 @@
import { useNavigate } from 'react-router-dom';
import { RpcErrorCode } from '@btckit/types';
import * as btc from '@scure/btc-signer';
import { bytesToHex } from '@stacks/common';
import { RouteUrls } from '@shared/route-urls';
import { makeRpcErrorResponse, makeRpcSuccessResponse } from '@shared/rpc/rpc-methods';
import { useRpcSignPsbtParams } from '@app/common/psbt/use-psbt-request-params';
import { usePsbtSigner } from '@app/features/psbt-signer/hooks/use-psbt-signer';
export function useRpcSignPsbt() {
const navigate = useNavigate();
const { origin, tabId, requestId, psbtHex, allowedSighash, signAtIndex } = useRpcSignPsbtParams();
const { signPsbt, getPsbtAsTransaction } = usePsbtSigner();
@@ -21,7 +25,13 @@ export function useRpcSignPsbt() {
onSignPsbt(inputs: btc.TransactionInput[]) {
const tx = getPsbtAsTransaction(psbtHex);
signPsbt({ allowedSighash, indexesToSign: signAtIndex, inputs, tx });
try {
signPsbt({ allowedSighash, indexesToSign: signAtIndex, inputs, tx });
} catch (e) {
return navigate(RouteUrls.RequestError, {
state: { message: e instanceof Error ? e.message : '', title: 'Failed to sign' },
});
}
const psbt = tx.toPSBT();

View File

@@ -28,6 +28,7 @@ function ContractCallDetailsSuspense() {
px="base-loose"
py="extra-loose"
spacing="loose"
width="100%"
>
<Title as="h2" fontWeight="500">
Function and arguments

View File

@@ -13,6 +13,7 @@ export enum QueryPrefixes {
InscriptionFromTxid = 'inscription-from-txid',
InscriptionsFromApiInfiniteQuery = 'inscriptions-from-api-infinite-query',
GetNftMetadata = 'get-nft-metadata',
GetNftHoldings = 'get-nft-holdings',
StampCollection = 'stamp-collection',
StampsByAddress = 'stamps-by-address',

View File

@@ -2,42 +2,21 @@ import { useMemo } from 'react';
import BigNumber from 'bignumber.js';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
import {
useGetNonFungibleTokenHoldingsListQuery,
useGetNonFungibleTokenHoldingsQuery,
} from './non-fungible-token-holdings.query';
import { useGetNonFungibleTokenHoldingsListQuery } from './non-fungible-token-holdings.query';
export function useAllAccountsNonFungibleTokenHoldingsTotal(accounts?: StacksAccount[]) {
const accountsNftHoldings = useGetNonFungibleTokenHoldingsListQuery(accounts);
export function useAllAccountsNonFungibleTokenHoldingsTotal(accounts: StacksAccount[]) {
const accountsNftHoldings = useGetNonFungibleTokenHoldingsListQuery(
accounts.map(account => account.address)
);
return useMemo(
() =>
accountsNftHoldings.reduce((acc, nftHoldings) => {
return acc.plus(nftHoldings.data?.total || 0);
}, new BigNumber(0)),
accountsNftHoldings.reduce(
(acc, nftHoldings) => acc.plus(nftHoldings.data?.total || 0),
new BigNumber(0)
),
[accountsNftHoldings]
);
}
interface NonFungibleTokenHoldingListResult {
asset_identifier: string;
value: {
hex: string;
repr: string;
};
block_height: number;
tx_id: string;
}
export function useAccountNonFungibleTokenHoldings() {
const currentAccount = useCurrentStacksAccount();
const { data: nonFungibleTokenHoldings } = useGetNonFungibleTokenHoldingsQuery(
currentAccount?.address
);
return (nonFungibleTokenHoldings?.results as NonFungibleTokenHoldingListResult[]) ?? [];
}

View File

@@ -1,9 +1,10 @@
import { NonFungibleTokenHoldingsList } from '@stacks/blockchain-api-client';
import { useQueries, useQuery } from '@tanstack/react-query';
import { AppUseQueryConfig } from '@app/query/query-config';
import { logger } from '@shared/logger';
import { Paginated } from '@shared/models/api-types';
import { QueryPrefixes } from '@app/query/query-prefixes';
import { StacksClient } from '@app/query/stacks/stacks-client';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
import { useStacksClientUnanchored } from '@app/store/common/api-clients.hooks';
import { useCurrentNetworkState } from '@app/store/networks/networks.hooks';
@@ -11,54 +12,64 @@ import { RateLimiter, useHiroApiRateLimiter } from '../../rate-limiter';
const staleTime = 15 * 60 * 1000; // 15 min
const queryOptions = {
cacheTime: staleTime,
staleTime,
} as const;
interface NonFungibleTokenHoldingListResult {
asset_identifier: string;
value: {
hex: string;
repr: string;
};
block_height: number;
tx_id: string;
}
const queryOptions = { cacheTime: staleTime, staleTime, refetchhOnFocus: false } as const;
type FetchNonFungibleTokenHoldingsResp = Paginated<NonFungibleTokenHoldingListResult[]>;
function fetchNonFungibleTokenHoldings(client: StacksClient, limiter: RateLimiter) {
return async (address?: string) => {
return async (address: string) => {
if (!address) return;
await limiter.removeTokens(1);
return client.nonFungibleTokensApi.getNftHoldings({
principal: address,
limit: 50,
}) as Promise<NonFungibleTokenHoldingsList>;
}) as unknown as Promise<FetchNonFungibleTokenHoldingsResp>;
};
}
type FetchNonFungibleTokenHoldingsResp = Awaited<
ReturnType<ReturnType<typeof fetchNonFungibleTokenHoldings>>
>;
function makeNonFungibleTokenHoldingsQuery(
address: string,
network: string,
client: StacksClient,
limiter: RateLimiter
) {
if (address === '') logger.warn('No address passed to ' + QueryPrefixes.GetNftHoldings);
return {
enabled: !!address,
queryKey: [QueryPrefixes.GetNftHoldings, address, network],
queryFn: () => fetchNonFungibleTokenHoldings(client, limiter)(address),
...queryOptions,
};
}
export function useGetNonFungibleTokenHoldingsQuery<
T extends unknown = FetchNonFungibleTokenHoldingsResp
>(address?: string, options?: AppUseQueryConfig<FetchNonFungibleTokenHoldingsResp, T>) {
export default function useGetNonFungibleTokenHoldingsQuery(address: string) {
const client = useStacksClientUnanchored();
const network = useCurrentNetworkState();
const limiter = useHiroApiRateLimiter();
return useQuery({
queryKey: ['get-nft-holdings', address, network.chain.stacks.url],
queryFn: () => fetchNonFungibleTokenHoldings(client, limiter)(address),
...queryOptions,
...options,
});
return useQuery(
makeNonFungibleTokenHoldingsQuery(address, network.chain.stacks.url, client, limiter)
);
}
export function useGetNonFungibleTokenHoldingsListQuery<
T extends unknown = FetchNonFungibleTokenHoldingsResp
>(accounts?: StacksAccount[], options?: AppUseQueryConfig<FetchNonFungibleTokenHoldingsResp, T>) {
export function useGetNonFungibleTokenHoldingsListQuery(addresses: string[]) {
const client = useStacksClientUnanchored();
const network = useCurrentNetworkState();
const limiter = useHiroApiRateLimiter();
return useQueries({
queries: (accounts ?? []).map(account => ({
queryKey: ['get-nft-holdings', account.address, network.chain.stacks.url],
queryFn: () => fetchNonFungibleTokenHoldings(client, limiter)(account.address),
...queryOptions,
...options,
})),
queries: addresses.map(address =>
makeNonFungibleTokenHoldingsQuery(address, network.chain.stacks.url, client, limiter)
),
});
}

View File

@@ -1,10 +1,12 @@
import { useMemo } from 'react';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
import { isNftAsset } from '../token-metadata.utils';
import { useGetNonFungibleTokenMetadataListQuery } from './non-fungible-token-metadata.query';
export function useNonFungibleTokensMetadata() {
const respList = useGetNonFungibleTokenMetadataListQuery();
export function useStacksNonFungibleTokensMetadata(account: StacksAccount) {
const respList = useGetNonFungibleTokenMetadataListQuery(account);
return useMemo(
() =>

View File

@@ -3,12 +3,13 @@ import { UseQueryResult, useQueries } from '@tanstack/react-query';
import { pullContractIdFromIdentity } from '@app/common/utils';
import { QueryPrefixes } from '@app/query/query-prefixes';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
import { useTokenMetadataClient } from '@app/store/common/api-clients.hooks';
import { RateLimiter, useHiroApiRateLimiter } from '../../rate-limiter';
import { TokenMetadataClient } from '../../token-metadata-client';
import { NftAssetResponse } from '../token-metadata.utils';
import { useAccountNonFungibleTokenHoldings } from './non-fungible-token-holdings.hooks';
import useGetNonFungibleTokenHoldingsQuery from './non-fungible-token-holdings.query';
const queryOptions = {
refetchOnWindowFocus: true,
@@ -28,13 +29,15 @@ function fetchNonFungibleTokenMetadata(client: TokenMetadataClient, limiter: Rat
};
}
export function useGetNonFungibleTokenMetadataListQuery(): UseQueryResult<NftAssetResponse>[] {
export function useGetNonFungibleTokenMetadataListQuery(
account: StacksAccount
): UseQueryResult<NftAssetResponse>[] {
const client = useTokenMetadataClient();
const limiter = useHiroApiRateLimiter();
const nftHoldings = useAccountNonFungibleTokenHoldings();
const nftHoldings = useGetNonFungibleTokenHoldingsQuery(account.address);
return useQueries({
queries: nftHoldings.map(nft => {
queries: (nftHoldings.data?.results ?? []).map(nft => {
const principal = pullContractIdFromIdentity(nft.asset_identifier);
const tokenId = getTokenId(nft.value.hex);

View File

@@ -12,7 +12,7 @@ import { RouteUrls } from '@shared/route-urls';
import { BroadcastErrorDrawer } from '@app/components/broadcast-error-drawer/broadcast-error-drawer';
import { LoadingSpinner } from '@app/components/loading-spinner';
import { ActivityList } from '@app/features/activity-list/activity-list';
import { BalancesList } from '@app/features/balances-list/balances-list';
import { AssetsList } from '@app/features/asset-list/asset-list';
import { Container } from '@app/features/container/container';
import { EditNonceDrawer } from '@app/features/edit-nonce-drawer/edit-nonce-drawer';
import { IncreaseBtcFeeDrawer } from '@app/features/increase-fee-drawer/increase-btc-fee-drawer';
@@ -186,7 +186,7 @@ function useAppRoutes() {
</AccountGate>
}
>
<Route index element={<BalancesList />} />
<Route index element={<AssetsList />} />
<Route path={RouteUrls.Activity} element={<ActivityList />} />
{requestBitcoinKeysRoutes}

View File

@@ -11,6 +11,7 @@ import {
} from '@shared/crypto/bitcoin/bitcoin.utils';
import { getTaprootAddressIndexDerivationPath } from '@shared/crypto/bitcoin/p2tr-address-gen';
import { getNativeSegwitAddressIndexDerivationPath } from '@shared/crypto/bitcoin/p2wpkh-address-gen';
import { AllowedSighashTypes } from '@shared/rpc/methods/sign-psbt';
interface Signer<Payment> {
network: BitcoinNetworkModes;
@@ -20,7 +21,7 @@ interface Signer<Payment> {
address: string;
publicKey: Uint8Array;
sign(tx: btc.Transaction): void;
signIndex(tx: btc.Transaction, index: number, allowedSighash?: btc.SignatureHash[]): void;
signIndex(tx: btc.Transaction, index: number, allowedSighash?: AllowedSighashTypes[]): void;
}
interface MakeBitcoinSignerArgs {
@@ -29,7 +30,7 @@ interface MakeBitcoinSignerArgs {
derivationPath: string;
paymentFn(keychain: HDKey, network: BitcoinNetworkModes): any;
signFn(tx: btc.Transaction): void;
signAtIndexFn(tx: btc.Transaction, index: number, allowedSighash?: btc.SignatureHash[]): void;
signAtIndexFn(tx: btc.Transaction, index: number, allowedSighash?: AllowedSighashTypes[]): void;
}
function makeBitcoinSigner<T extends MakeBitcoinSignerArgs>(args: T) {
const { derivationPath, keychain, network, paymentFn, signFn, signAtIndexFn } = args;
@@ -89,7 +90,8 @@ export function bitcoinAddressIndexSignerFactory<T extends BitcoinAddressIndexSi
tx.sign(addressIndexKeychain.privateKey);
},
signAtIndexFn(tx: btc.Transaction, index: number, allowedSighash?: btc.SignatureHash[]) {
// TODO: Revisit allowedSighash type if/when fixed in btc-signer
signAtIndexFn(tx: btc.Transaction, index: number, allowedSighash?: number[]) {
if (!addressIndexKeychain.privateKey)
throw new Error('Unable to sign transaction, no private key found');

View File

@@ -15,7 +15,6 @@ import {
} from 'redux-persist';
import { PersistPartial } from 'redux-persist/es/persistReducer';
import { IS_DEV_ENV } from '@shared/environment';
import { persistConfig } from '@shared/storage/redux-pesist';
import { analyticsSlice } from './analytics/analytics.slice';
@@ -23,7 +22,7 @@ import { appPermissionsSlice } from './app-permissions/app-permissions.slice';
import { stxChainSlice } from './chains/stx-chain.slice';
import { inMemoryKeySlice } from './in-memory-key/in-memory-key.slice';
import { keySlice } from './keys/key.slice';
import { bitcoinKeySlice } from './ledger/bitcoin-key.slice';
import { bitcoinKeysSlice } from './ledger/bitcoin-key.slice';
import { networksSlice } from './networks/networks.slice';
import { onboardingSlice } from './onboarding/onboarding.slice';
import { ordinalsSlice } from './ordinals/ordinals.slice';
@@ -38,7 +37,7 @@ export interface RootState {
stx: ReturnType<typeof stxChainSlice.reducer>;
};
ledger: {
bitcoin: ReturnType<typeof bitcoinKeySlice.reducer>;
bitcoin: ReturnType<typeof bitcoinKeysSlice.reducer>;
};
ordinals: ReturnType<typeof ordinalsSlice.reducer>;
inMemoryKeys: ReturnType<typeof inMemoryKeySlice.reducer>;
@@ -56,7 +55,7 @@ const appReducer = combineReducers({
stx: stxChainSlice.reducer,
}),
ledger: combineReducers({
bitcoin: bitcoinKeySlice.reducer,
bitcoin: bitcoinKeysSlice.reducer,
}),
ordinals: ordinalsSlice.reducer,
inMemoryKeys: inMemoryKeySlice.reducer,
@@ -84,16 +83,17 @@ export const store = configureStore({
}),
broadcastActionTypeToOtherFramesMiddleware,
],
enhancers: IS_DEV_ENV
? [
devToolsEnhancer({
hostname: 'localhost',
port: 8000,
realtime: true,
suppressConnectErrors: false,
}),
]
: undefined,
enhancers:
process.env.WALLET_ENVIRONMENT === 'development'
? [
devToolsEnhancer({
hostname: 'localhost',
port: 8000,
realtime: true,
suppressConnectErrors: false,
}),
]
: undefined,
});
export const persistor = persistStore(store);

View File

@@ -40,5 +40,10 @@ export const keySlice = createSlice({
signOut(state) {
keyAdapter.removeOne(state, defaultKeyId);
},
debugKillStacks(state) {
if (state.entities.default?.type !== 'ledger') return;
state.entities.default.publicKeys = [];
},
},
});

View File

@@ -11,8 +11,8 @@ interface PersistedBitcoinKeys extends BitcoinLedgerAccountDetails {
const bitcoinKeyAdapter = createEntityAdapter<PersistedBitcoinKeys>();
export const bitcoinKeySlice = createSlice({
name: 'bitcoinKeys',
export const bitcoinKeysSlice = createSlice({
name: 'bitcoinsKeys',
initialState: bitcoinKeyAdapter.getInitialState(),
reducers: {
addBitcoinKeys(state, { payload }: PayloadAction<BitcoinLedgerAccountDetails[]>) {

View File

@@ -128,9 +128,12 @@ document.addEventListener(DomEventName.psbtRequest, ((event: PsbtRequestEvent) =
});
}) as EventListener);
window.addEventListener('load', () => {
function addHiroWalletToPage() {
const inpage = document.createElement('script');
inpage.src = chrome.runtime.getURL('inpage.js');
inpage.id = 'stacks-wallet-provider';
inpage.id = 'hiro-wallet-provider';
document.body.appendChild(inpage);
});
}
// Don't block thread to add Hiro Wallet to page
requestAnimationFrame(() => addHiroWalletToPage());

View File

@@ -0,0 +1,6 @@
export interface Paginated<T> {
limit: number;
offset: number;
total: number;
results: T;
}

View File

@@ -6,7 +6,6 @@ declare module '*.svg' {
export default src;
}
declare const EXT_ENV: string;
declare const VERSION: string;
interface QrOptions {

View File

@@ -1,14 +1,14 @@
import { DefineRpcMethod, RpcRequest, RpcResponse } from '@btckit/types';
import { AllowAdditionaProperties } from '@btckit/types/dist/types/utils';
import { AllowAdditionalProperties } from '@btckit/types/dist/types/utils';
interface BitcoinContractResponseParams extends AllowAdditionaProperties {
interface BitcoinContractResponseParams extends AllowAdditionalProperties {
bitcoinContractOffer: string;
counterpartyWalletURL: string;
counterpartyWalletName: string;
counterpartyWalletIcon: string;
}
interface BitcoinContractResponseBody extends AllowAdditionaProperties {
interface BitcoinContractResponseBody extends AllowAdditionalProperties {
contractId: string;
action: string;
txId?: string;

View File

@@ -1,4 +1,4 @@
import { DefineRpcMethod, RpcRequest, RpcResponse } from '@btckit/types';
import { DefineRpcMethod, RpcRequest, RpcResponse, SignatureHash } from '@btckit/types';
import * as btc from '@scure/btc-signer';
import * as yup from 'yup';
@@ -12,9 +12,21 @@ import {
validateRpcParams,
} from './validation.utils';
// TODO: Revisit allowedSighash type if/when fixed in btc-signer
export type AllowedSighashTypes = SignatureHash | btc.SignatureHash;
const rpcSignPsbtParamsSchema = yup.object().shape({
account: accountSchema,
allowedSighash: yup.array().of(yup.mixed().oneOf(Object.values(btc.SignatureHash))),
allowedSighash: yup
.array()
.of(
yup
.mixed()
.oneOf([
...Object.values(SignatureHash).filter(Number.isInteger),
...Object.values(btc.SignatureHash).filter(Number.isInteger),
])
),
hex: yup.string().required(),
network: yup.string().oneOf(Object.values(WalletDefaultNetworkConfigurationIds)),
signAtIndex: yup.mixed<number | number[]>().test(testIsNumberOrArrayOfNumbers),

View File

@@ -139,6 +139,7 @@ function buildTestTaprootPsbtRequestWithIndex(pubKey: Uint8Array): PsbtRequestOp
tx.addInput({
index: 0,
txid: '4f4cc7cb40b04978bd7704798dc1adf55b58196cef616b0fac8181965abc4726',
// tapInternalKey: payment.tapInternalKey,
witnessUtxo: {
amount: BigInt(1000),
script: payment.script,

View File

@@ -37,13 +37,12 @@ const BRANCH = getBranch();
const SRC_ROOT_PATH = path.join(__dirname, '../', 'src');
const DIST_ROOT_PATH = path.join(__dirname, '../', 'dist');
const NODE_ENV = process.env.NODE_ENV || 'development';
const WALLET_ENVIRONMENT = process.env.WALLET_ENVIRONMENT || 'development';
const WEB_BROWSER = process.env.WEB_BROWSER ? process.env.WEB_BROWSER : 'chrome';
const IS_DEV = NODE_ENV === 'development';
const IS_DEV = WALLET_ENVIRONMENT === 'development';
const IS_PROD = !IS_DEV;
const ANALYZE_BUNDLE = process.env.ANALYZE === 'true';
const EXT_ENV = process.env.EXT_ENV || 'web';
const speedMeasurePlugin = new SpeedMeasurePlugin({
disable: !ANALYZE_BUNDLE,
@@ -90,7 +89,7 @@ const config = {
path: DIST_ROOT_PATH,
chunkFilename: !IS_DEV ? '[name].[contenthash:8].chunk.js' : IS_DEV && '[name].chunk.js',
filename: () => {
if (EXT_ENV === 'prod' || IS_DEV) {
if (WALLET_ENVIRONMENT === 'production' || IS_DEV) {
return '[name].js';
}
return '[name].[contenthash:8].js';
@@ -172,7 +171,7 @@ const config = {
],
}),
new webpack.DefinePlugin({
NODE_ENV: JSON.stringify(NODE_ENV),
WALLET_ENVIRONMENT: JSON.stringify(WALLET_ENVIRONMENT),
WEB_BROWSER: JSON.stringify(WEB_BROWSER),
VERSION: JSON.stringify(VERSION),
COMMIT_SHA: JSON.stringify(COMMIT_SHA),

View File

@@ -7,7 +7,7 @@ config.optimization = {
...config.optimization,
flagIncludedChunks: false,
concatenateModules: false,
minimize: process.env.NODE_ENV !== 'test',
minimize: process.env.WALLET_ENVIRONMENT !== 'testing',
moduleIds: 'deterministic',
splitChunks: {
hidePathInfo: false,

View File

@@ -3,7 +3,7 @@ const WebpackDevServer = require('webpack-dev-server');
const webpack = require('webpack');
const path = require('path');
const NODE_ENV = process.env.NODE_ENV;
const WALLET_ENVIRONMENT = process.env.WALLET_ENVIRONMENT;
const HOST = 'localhost';
const PORT = process.env.PORT || '8080';
@@ -53,7 +53,7 @@ const server = new WebpackDevServer(
compiler
);
if (NODE_ENV === 'development' && module.hot) {
if (WALLET_ENVIRONMENT === 'development' && module.hot) {
module.hot.accept();
}

View File

@@ -17,12 +17,12 @@ const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const SRC_ROOT_PATH = path.join(__dirname, '../', 'src');
const DIST_ROOT_PATH = path.join(__dirname, '../', 'dist');
const NODE_ENV = process.env.NODE_ENV || 'development';
const WALLET_ENVIRONMENT = process.env.WALLET_ENVIRONMENT || 'development';
const ANALYZE_BUNDLE = process.env.ANALYZE === 'true';
const IS_PUBLISHING = !!process.env.IS_PUBLISHING;
const BRANCH = process.env.GITHUB_REF;
const IS_DEV = NODE_ENV === 'development';
const IS_DEV = WALLET_ENVIRONMENT === 'development';
const IS_PROD = !IS_DEV;
const MAIN_BRANCH = 'refs/heads/main';

View File

@@ -926,10 +926,10 @@
sha.js "^2.4.11"
smart-buffer "^4.1.0"
"@btckit/types@0.0.18":
version "0.0.18"
resolved "https://registry.yarnpkg.com/@btckit/types/-/types-0.0.18.tgz#48bd0b564a9c14bf0c670b0834131e5054c20d69"
integrity sha512-2b/Ny4rZ+TbGW59xiV/PvXRP1cnF40874t12OzeVKa/BghxBFazEayDHce9YtPTkxQ4ilQkmeNrS67FWK4OsGA==
"@btckit/types@0.0.19":
version "0.0.19"
resolved "https://registry.yarnpkg.com/@btckit/types/-/types-0.0.19.tgz#8454326b669d3b029094d3d20026fdc6e6c72319"
integrity sha512-APoOfYSg9SRR4CMXL606IDtpgh+ZD3kS/+iY0BkUALD6HvXo2pVw20L5YYIc+HrgMcF6WN0TH7TXdVs+Vu+kww==
"@coinbase/cbpay-js@1.0.2":
version "1.0.2"
@@ -5519,47 +5519,47 @@
dependencies:
remove-accents "0.4.2"
"@tanstack/query-core@4.29.19":
version "4.29.19"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.29.19.tgz#49ccbd0606633d1e55baf3b91ab7cc7aef411b1d"
integrity sha512-uPe1DukeIpIHpQi6UzIgBcXsjjsDaLnc7hF+zLBKnaUlh7jFE/A+P8t4cU4VzKPMFB/C970n/9SxtpO5hmIRgw==
"@tanstack/query-core@4.32.0":
version "4.32.0"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.32.0.tgz#e0f4a830283612430450c13badd353766423f523"
integrity sha512-ei4IYwL2kmlKSlCw9WgvV7PpXi0MiswVwfQRxawhJA690zWO3dU49igaQ/UMTl+Jy9jj9dK5IKAYvbX7kUvviQ==
"@tanstack/query-persist-client-core@4.29.19":
version "4.29.19"
resolved "https://registry.yarnpkg.com/@tanstack/query-persist-client-core/-/query-persist-client-core-4.29.19.tgz#c0cd03eca74d33e5aa40c95cadd5585620ff2320"
integrity sha512-rr6p3xwEZCz3cEDZsj3QGePf6PG44WxRUGQVcm2JFPZOq9TkG/0i5+hQ3STiHm1Fj6qwCH8xIi62L8kG0zRj/Q==
"@tanstack/query-persist-client-core@4.32.0":
version "4.32.0"
resolved "https://registry.yarnpkg.com/@tanstack/query-persist-client-core/-/query-persist-client-core-4.32.0.tgz#8ab8670555b777fcc7cfde0581b42d28b6164933"
integrity sha512-TUIArpiZJqLsYEPmg2LsZD+uJknrAHXWSaoCROFniDS0TqExe4KkjQ2gt+XTBwzxlOEN52R+l98k+oS/u94ogg==
dependencies:
"@tanstack/query-core" "4.29.19"
"@tanstack/query-core" "4.32.0"
"@tanstack/query-sync-storage-persister@4.29.19":
version "4.29.19"
resolved "https://registry.yarnpkg.com/@tanstack/query-sync-storage-persister/-/query-sync-storage-persister-4.29.19.tgz#292d33cdc9b38b11127f2f07b1935a73039cbba4"
integrity sha512-B3wDl3D3YBFTlY2yeXecEh4NEG/8Hr8pqsxnWJijRwBqvOKlqD4bUgk5kl5nbn1mShD2vnQ+yvH900/11X29Zw==
"@tanstack/query-sync-storage-persister@4.32.0":
version "4.32.0"
resolved "https://registry.yarnpkg.com/@tanstack/query-sync-storage-persister/-/query-sync-storage-persister-4.32.0.tgz#7c33266d9e0c45eb0ec309467066c20940d57052"
integrity sha512-DJuHgyHmmzjamC1hjs5BB1fScqMXuk/rOYrcmSLOd3U/tceAK0PqZOJzzd2Zt0bwtJQ8hatKqks7MqiLAvAPQw==
dependencies:
"@tanstack/query-persist-client-core" "4.29.19"
"@tanstack/query-persist-client-core" "4.32.0"
"@tanstack/react-query-devtools@4.29.19":
version "4.29.19"
resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-4.29.19.tgz#b6f337c91313388d3f04c890449005d7bb355322"
integrity sha512-rL2xqTPr+7gJvVGwyq8E8CWqqw950N4lZ6ffJeNX0qqymKHxHW1FM6nZaYt7Aufs/bXH0m1L9Sj3kDGQbp0rwg==
"@tanstack/react-query-devtools@4.32.0":
version "4.32.0"
resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-4.32.0.tgz#7d0ba1bcf7a7470c4f405229e212923bcc0f3323"
integrity sha512-rOmWqzKzRmQrQULV5Ova2FGEEPT76FZA3hz8T+LFkvp3ehw9ugSZ1BosgRJ7AFCeir+5pcNvFwILy4pDK8HpRw==
dependencies:
"@tanstack/match-sorter-utils" "^8.7.0"
superjson "^1.10.0"
use-sync-external-store "^1.2.0"
"@tanstack/react-query-persist-client@4.29.19":
version "4.29.19"
resolved "https://registry.yarnpkg.com/@tanstack/react-query-persist-client/-/react-query-persist-client-4.29.19.tgz#27b24ec5c8983894d6f23450e2f922d07f47706f"
integrity sha512-LfcasTosdnI9K66HTP0Rk72Ypza3tCgrcF9bc2qFlKsBleYOYo8bz7/GiiOHj1SQH4GRQlKB+P4+/it+qlJg4g==
"@tanstack/react-query-persist-client@4.32.0":
version "4.32.0"
resolved "https://registry.yarnpkg.com/@tanstack/react-query-persist-client/-/react-query-persist-client-4.32.0.tgz#6840a73042ca7708e793e6ec0acb1f49bc275d9a"
integrity sha512-2H1Fuw02uoW2U4kAexV3rmSjyOWunaWAoMgRybULu/TbEGh00c6p4yon/nQM81TAbf4M66Aa7nU0vqipY0VJXQ==
dependencies:
"@tanstack/query-persist-client-core" "4.29.19"
"@tanstack/query-persist-client-core" "4.32.0"
"@tanstack/react-query@4.29.19":
version "4.29.19"
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.29.19.tgz#6ba187f2d0ea36ae83ff1f67068f53c88ce7b228"
integrity sha512-XiTIOHHQ5Cw1WUlHaD4fmVUMhoWjuNJlAeJGq7eM4BraI5z7y8WkZO+NR8PSuRnQGblpuVdjClQbDFtwxTtTUw==
"@tanstack/react-query@4.32.0":
version "4.32.0"
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.32.0.tgz#701b45b149cfd4b54a68705f9100973db3ba5d5d"
integrity sha512-B8WUMcByYAH9500ENejDCATOmEZhqjtS9wsfiQ3BNa+s+yAynY8SESI8WWHhSqUmjd0pmCSFRP6BOUGSda3QXA==
dependencies:
"@tanstack/query-core" "4.29.19"
"@tanstack/query-core" "4.32.0"
use-sync-external-store "^1.2.0"
"@tippyjs/react@4.2.6", "@tippyjs/react@^4.2.4":
@@ -5579,10 +5579,10 @@
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
"@trivago/prettier-plugin-sort-imports@4.1.1":
version "4.1.1"
resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.1.1.tgz#71c3c1ae770c3738b6fc85710714844477574ffd"
integrity sha512-dQ2r2uzNr1x6pJsuh/8x0IRA3CBUB+pWEW3J/7N98axqt7SQSm+2fy0FLNXvXGg77xEDC7KHxJlHfLYyi7PDcw==
"@trivago/prettier-plugin-sort-imports@4.2.0":
version "4.2.0"
resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.2.0.tgz#b240366f9e2bda8e14edb18b14ea084e0ec25968"
integrity sha512-YBepjbt+ZNBVmN3ev1amQH3lWCmHyt5qTbLCp/syXJRu/Kw2koXh44qayB1gMRxcL/gV8egmjN5xWSrYyfUtyw==
dependencies:
"@babel/generator" "7.17.7"
"@babel/parser" "^7.20.5"