Skip to content

Commit

Permalink
Merge pull request #4534 from leather-wallet/release/abandon
Browse files Browse the repository at this point in the history
release: abandon
  • Loading branch information
fbwoolf authored Nov 17, 2023
2 parents 0db71d6 + ad056f2 commit d040331
Show file tree
Hide file tree
Showing 26 changed files with 181 additions and 132 deletions.
12 changes: 11 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const avoidWindowOpenMsg = 'Use `openInNewTab` helper';
const avoidFetchMsg = 'Use `axios` instead for consistency with the rest of the project';

module.exports = {
parser: '@typescript-eslint/parser',
Expand Down Expand Up @@ -34,7 +35,11 @@ module.exports = {
ignoreReadBeforeAssign: false,
},
],
'no-restricted-globals': ['error', { name: 'open', message: avoidWindowOpenMsg }],
'no-restricted-globals': [
'error',
{ name: 'open', message: avoidWindowOpenMsg },
{ name: 'fetch', message: avoidFetchMsg },
],
'no-restricted-properties': [
'error',
{
Expand All @@ -52,6 +57,11 @@ module.exports = {
property: 'close',
message: 'Use `closeWindow` utility helper',
},
{
object: 'window',
property: 'fetch',
message: avoidFetchMsg,
},
],
'@typescript-eslint/no-floating-promises': ['warn'],
'@typescript-eslint/no-unnecessary-type-assertion': ['warn'],
Expand Down
44 changes: 44 additions & 0 deletions src/app/common/api/fetch-wrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import axios from 'axios';

import { HIRO_API_KEY } from '@shared/constants';

const leatherHeaders: HeadersInit = {
'x-leather-version': VERSION,
'x-hiro-api-key': HIRO_API_KEY,
};

/**
* @deprecated Use `axios` directly instead
*/
export function wrappedFetch(input: RequestInfo, init: RequestInit = {}) {
const initHeaders = init.headers || {};
// eslint-disable-next-line no-restricted-globals
return fetch(input, {
credentials: 'omit',
...init,
headers: { ...initHeaders, ...leatherHeaders },
});
}

export async function fetchWithTimeout(
input: RequestInfo,
init: RequestInit & { timeout?: number } = {}
) {
const { timeout = 8000, ...options } = init;

const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);

const response = await wrappedFetch(input, {

Check warning on line 32 in src/app/common/api/fetch-wrapper.ts

View workflow job for this annotation

GitHub Actions / lint-eslint

'wrappedFetch' is deprecated. Use `axios` directly instead
...options,
signal: controller.signal,
});
clearTimeout(id);

return response;
}

axios.interceptors.request.use(config => {
if (config.url?.includes('hiro.so')) config.headers['x-hiro-api-key'] = HIRO_API_KEY;
return config;
});
31 changes: 0 additions & 31 deletions src/app/common/api/wrapped-fetch.ts

This file was deleted.

6 changes: 0 additions & 6 deletions src/app/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
import { toUnicode } from 'punycode';

import { BitcoinNetworkModes, KEBAB_REGEX } from '@shared/constants';
import { logger } from '@shared/logger';
import type { Blockchains } from '@shared/models/blockchain.model';

export function createNullArrayOfLength(length: number) {
Expand Down Expand Up @@ -264,11 +263,6 @@ export function whenStacksChainId(chainId: ChainID) {
return <T>(chainIdMap: WhenStacksChainIdMap<T>): T => chainIdMap[chainId];
}

export function logAndThrow(msg: string, args: any[] = []) {
logger.error(msg, ...args);
throw new Error(msg);
}

export const parseIfValidPunycode = (s: string) => {
try {
return toUnicode(s);
Expand Down
99 changes: 61 additions & 38 deletions src/app/components/request-password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { LeatherButton } from '@app/components/button/button';

import { ErrorLabel } from './error-label';
import { buildEnterKeyEvent } from './link';
import { TwoColumnLayout } from './secret-key/two-column.layout';

const waitingMessages: WaitingMessages = {
'2': 'Verifying password…',
Expand Down Expand Up @@ -51,43 +52,65 @@ export function RequestPassword({ title, caption, onSuccess }: RequestPasswordPr
}, [analytics, startWaitingMessage, stopWaitingMessage, unlockWallet, password, onSuccess]);

return (
<Stack
pb={['space.05', 'unset']}
px={['space.05', 'space.04']}
gap="space.05"
textAlign={['center', 'center']}
margin="auto"
>
<styled.h1 textStyle={['heading.03', 'heading.02']}>{title}</styled.h1>
<styled.p textStyle="body.02">{(isRunning && waitingMessage) || caption}</styled.p>
<Stack gap="space.04">
<Input
autoFocus
_focus={{ border: `2px solid ${token('colors.accent.text-primary')}` }}
borderRadius="10px"
data-testid={SettingsSelectors.EnterPasswordInput}
height="64px"
isDisabled={isRunning}
onChange={(e: FormEvent<HTMLInputElement>) => {
setError('');
setPassword(e.currentTarget.value);
}}
onKeyUp={buildEnterKeyEvent(submit)}
placeholder="Enter your password"
type="password"
value={password}
width="100%"
/>
{error && <ErrorLabel>{error}</ErrorLabel>}
</Stack>
<LeatherButton
data-testid={SettingsSelectors.UnlockWalletBtn}
disabled={isRunning || !!error}
aria-busy={isRunning}
onClick={submit}
>
Continue
</LeatherButton>
</Stack>
<>
<TwoColumnLayout
leftColumn={
<>
<styled.h1
textStyle={['heading.03', 'heading.03', 'heading.03', 'display.02']}
mt="space.00"
mb="space.06"
>
{title}
</styled.h1>
<styled.p textStyle={['label.01', 'heading.05']} mb="space.06">
{(isRunning && waitingMessage) || caption}
</styled.p>
</>
}
rightColumn={
<>
<styled.h2
textStyle="heading.03"
mt="space.02"
mb="space.04"
hideBelow="sm"
textAlign="center"
>
Your password
</styled.h2>
<Stack gap="space.04" alignItems="center">
<Input
autoFocus
_focus={{ border: `2px solid ${token('colors.accent.text-primary')}` }}
borderRadius="10px"
data-testid={SettingsSelectors.EnterPasswordInput}
height="64px"
isDisabled={isRunning}
onChange={(e: FormEvent<HTMLInputElement>) => {
setError('');
setPassword(e.currentTarget.value);
}}
onKeyUp={buildEnterKeyEvent(submit)}
placeholder="Enter your password"
type="password"
value={password}
width="100%"
/>
{error && <ErrorLabel>{error}</ErrorLabel>}
</Stack>
<LeatherButton
data-testid={SettingsSelectors.UnlockWalletBtn}
disabled={isRunning || !!error}
aria-busy={isRunning}
onClick={submit}
mt="space.08"
>
Continue
</LeatherButton>
</>
}
/>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { Inscription } from './inscription';
interface OrdinalsProps {
setIsLoadingMore: (isLoading: boolean) => void;
}

export function Ordinals({ setIsLoadingMore }: OrdinalsProps) {
const query = useGetInscriptionsInfiniteQuery();
const pages = query.data?.pages;
Expand Down
5 changes: 3 additions & 2 deletions src/app/pages/sign-out-confirm/sign-out-confirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ export function SignOutConfirmDrawer() {
return (
<SignOutConfirmLayout
onUserDeleteWallet={() => {
navigate(RouteUrls.Onboarding);
void signOut();
void signOut().finally(() => {
navigate(RouteUrls.Onboarding);
});
}}
onUserSafelyReturnToHomepage={() => navigate(backgroundLocation ?? '..')}
/>
Expand Down
5 changes: 2 additions & 3 deletions src/app/pages/unlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { closeWindow } from '@shared/utils';
import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { isFullPageMode, isPopupMode } from '@app/common/utils';
import { openIndexPageInNewTab } from '@app/common/utils/open-in-new-tab';
import { CenteredPageContainer } from '@app/components/centered-page-container';
import { Header } from '@app/components/header';
import { RequestPassword } from '@app/components/request-password';
import { useNewBrandApprover } from '@app/store/settings/settings.selectors';
Expand All @@ -35,7 +34,7 @@ export function Unlock() {
const handleSuccess = () => navigate(RouteUrls.Home);

return (
<CenteredPageContainer>
<>
{/* Hide the logo when user hasn't consented yet */}
{!hasApprovedNewBrand && (
<Box position="fixed" w="200px" h="60px" background="brown.2" top={0} left={0} />
Expand All @@ -47,6 +46,6 @@ export function Unlock() {
onSuccess={handleSuccess}
/>
<Outlet />
</CenteredPageContainer>
</>
);
}
15 changes: 9 additions & 6 deletions src/app/pages/view-secret-key/view-secret-key.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Outlet, useNavigate } from 'react-router-dom';

import { RouteUrls } from '@shared/route-urls';

Expand Down Expand Up @@ -35,10 +35,13 @@ export function ViewSecretKey() {
}

return (
<RequestPassword
title="View Secret Key"
caption="Enter the password you set on this device"
onSuccess={() => setShowSecretKey(true)}
/>
<>
<RequestPassword
title="View Secret Key"
caption="Enter the password you set on this device"
onSuccess={() => setShowSecretKey(true)}
/>
<Outlet />
</>
);
}
8 changes: 7 additions & 1 deletion src/app/query/bitcoin/bitcoin-client.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import axios from 'axios';

import { fetchData } from '../utils';

class Configuration {
Expand Down Expand Up @@ -112,10 +114,14 @@ class TransactionsApi {
constructor(public configuration: Configuration) {}

async getBitcoinTransaction(txid: string) {
return fetch(`${this.configuration.baseUrl}/tx/${txid}`).then(res => res.json());
const resp = await axios.get(`${this.configuration.baseUrl}/tx/${txid}`);
return resp.data;
}

async broadcastTransaction(tx: string) {
// TODO: refactor to use `axios`
// https://github.com/leather-wallet/extension/issues/4521
// eslint-disable-next-line no-restricted-globals
return fetch(`${this.configuration.baseUrl}/tx`, {
method: 'POST',
body: tx,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ export async function sendAcceptedBitcoinContractOfferToProtocolWallet(
acceptedBitcoinContractOffer: string,
counterpartyWalletURL: string
) {
// TODO: refactor to use `axios`
// https://github.com/leather-wallet/extension/issues/4521
// eslint-disable-next-line no-restricted-globals
const response = await fetch(`${counterpartyWalletURL}/offer/accept`, {
method: 'put',
body: JSON.stringify({
Expand Down
12 changes: 5 additions & 7 deletions src/app/query/bitcoin/ordinals/brc20/brc20-tokens.query.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useCallback, useEffect } from 'react';

import { useInfiniteQuery } from '@tanstack/react-query';
import axios from 'axios';

import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { createNumArrayOfRange } from '@app/common/utils';
Expand Down Expand Up @@ -36,16 +37,13 @@ interface Brc20TokenTicker {
}

async function fetchTickerData(ticker: string): Promise<Brc20TokenTicker[]> {
const res = await fetch(`https://brc20api.bestinslot.xyz/v1/get_brc20_ticker/${ticker}`);
if (!res.ok) throw new Error('Failed to fetch BRC-20 token ticker data');
return res.json();
const res = await axios.get(`https://brc20api.bestinslot.xyz/v1/get_brc20_ticker/${ticker}`);
return res.data;
}

async function fetchBrc20TokensByAddress(address: string): Promise<Brc20Token[]> {
const res = await fetch(`https://brc20api.bestinslot.xyz/v1/get_brc20_balance/${address}`);

if (!res.ok) throw new Error('Failed to fetch BRC-20 token balances');
const tokensData = await res.json();
const res = await axios.get(`https://brc20api.bestinslot.xyz/v1/get_brc20_balance/${address}`);
const tokensData = res.data;

const tickerPromises = tokensData.map((token: Brc20TokenResponse) => {
return fetchTickerData(token.tick);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';

import { QueryPrefixes } from '@app/query/query-prefixes';

async function getInscriptionTextContent(src: string) {
const res = await fetch(src);
if (!res.ok) throw new Error('Failed to fetch ordinal text content');
return res.text();
const res = await axios.get(src, { responseType: 'text' });
return res.data;
}

export function useInscriptionTextContentQuery(contentSrc: string) {
Expand Down
Loading

0 comments on commit d040331

Please sign in to comment.