Compare commits

..
Author SHA1 Message Date
Aleka Cheung 348047baca explicit override 2024-01-29 11:51:16 -05:00
Aleka Cheung 9fbcc240bb downgrade follow-redirects 2024-01-29 11:36:32 -05:00
12 changed files with 72 additions and 282 deletions
+6 -1
View File
@@ -155,5 +155,10 @@
"vitest": "^0.32.2",
"w3name": "^1.0.8",
"web3.storage": "^4.5.4"
},
"pnpm": {
"overrides": {
"follow-redirects": "1.15.3"
}
}
}
}
+12 -19
View File
@@ -1,8 +1,7 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
overrides:
follow-redirects: 1.15.3
dependencies:
'@0xsquid/sdk':
@@ -7476,7 +7475,7 @@ packages:
/axios@0.21.4:
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
dependencies:
follow-redirects: 1.15.5
follow-redirects: 1.15.3
transitivePeerDependencies:
- debug
dev: false
@@ -7484,7 +7483,7 @@ packages:
/axios@0.27.2:
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
dependencies:
follow-redirects: 1.15.2
follow-redirects: 1.15.3
form-data: 4.0.0
transitivePeerDependencies:
- debug
@@ -7493,7 +7492,7 @@ packages:
/axios@1.1.3:
resolution: {integrity: sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==}
dependencies:
follow-redirects: 1.15.5
follow-redirects: 1.15.3
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
@@ -7503,7 +7502,7 @@ packages:
/axios@1.6.5:
resolution: {integrity: sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==}
dependencies:
follow-redirects: 1.15.5
follow-redirects: 1.15.3
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
@@ -9526,18 +9525,8 @@ packages:
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
dev: true
/follow-redirects@1.15.2:
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
dev: false
/follow-redirects@1.15.5:
resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==}
/follow-redirects@1.15.3:
resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
@@ -14920,3 +14909,7 @@ packages:
/zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
dev: true
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
-8
View File
@@ -1,8 +0,0 @@
[
{
"name": "coinbase",
"label": "Coinbase",
"icon": "/exchanges/coinbase.png",
"depositType": "noble"
}
]
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

+2 -3
View File
@@ -11,7 +11,6 @@ type ElementProps = {
};
type StyleProps = {
className?: string;
hasLogo?: boolean;
size?: number;
};
@@ -19,7 +18,7 @@ type StyleProps = {
const DARK_LOGO_MARK_URL = '/logos/logo-mark-dark.svg';
const LIGHT_LOGO_MARK_URL = '/logos/logo-mark-light.svg';
export const QrCode = ({ className, value, hasLogo, size = 300 }: ElementProps & StyleProps) => {
export const QrCode = ({ value, hasLogo, size = 300 }: ElementProps & StyleProps) => {
const ref = useRef<HTMLDivElement>(null);
const appTheme: AppTheme = useSelector(getAppTheme);
@@ -75,7 +74,7 @@ export const QrCode = ({ className, value, hasLogo, size = 300 }: ElementProps &
}
}, [appTheme, hasLogo]);
return <Styled.QrCode className={className} ref={ref} />;
return <Styled.QrCode ref={ref} />;
};
const Styled: Record<string, AnyStyledComponent> = {};
-4
View File
@@ -8,7 +8,6 @@ import { Button, type ButtonStateConfig, type ButtonProps } from '@/components/B
type ElementProps = {
timeoutInSeconds: number;
slotFinal?: ReactNode;
} & ButtonProps;
export type TimeoutButtonProps = ElementProps;
@@ -16,7 +15,6 @@ export type TimeoutButtonProps = ElementProps;
export const TimeoutButton = ({
children,
timeoutInSeconds,
slotFinal,
...otherProps
}: TimeoutButtonProps) => {
const [timeoutDeadline] = useState(Date.now() + timeoutInSeconds * 1000);
@@ -25,8 +23,6 @@ export const TimeoutButton = ({
const secondsLeft = Math.max(0, (timeoutDeadline - now) / 1000);
if (slotFinal && secondsLeft <= 0) return slotFinal;
return (
<Button
{...otherProps}
-8
View File
@@ -161,7 +161,6 @@ const useAccountsContext = () => {
// dYdX wallet / onboarding state
const [localDydxWallet, setLocalDydxWallet] = useState<LocalWallet>();
const [localNobleWallet, setLocalNobleWallet] = useState<LocalWallet>();
const [hdKey, setHdKey] = useState<PrivateInformation>();
const dydxAccounts = useMemo(() => localDydxWallet?.accounts, [localDydxWallet]);
@@ -171,11 +170,6 @@ const useAccountsContext = () => {
[localDydxWallet]
);
const nobleAddress = useMemo(
() => localNobleWallet?.address,
[localNobleWallet]
);
const setWalletFromEvmSignature = async (signature: string) => {
const { wallet, mnemonic, privateKey, publicKey } = await getWalletFromEvmSignature({
signature,
@@ -257,7 +251,6 @@ const useAccountsContext = () => {
if (hdKey?.mnemonic) {
const nobleWallet = await LocalWallet.fromMnemonic(hdKey.mnemonic, NOBLE_BECH32_PREFIX);
abacusStateManager.setNobleWallet(nobleWallet);
setLocalNobleWallet(nobleWallet);
}
};
setNobleWallet();
@@ -356,7 +349,6 @@ const useAccountsContext = () => {
localDydxWallet,
dydxAccounts,
dydxAddress,
nobleAddress,
// Onboarding state
saveHasAcknowledgedTerms,
-4
View File
@@ -26,10 +26,6 @@ class TestFlags {
get addressOverride():string {
return this.queryParams.address;
}
get showCEXDepositOption() {
return !!this.queryParams.cexdeposit;
}
}
export const testFlags = new TestFlags();
@@ -3,7 +3,6 @@ import { shallowEqual, useSelector } from 'react-redux';
import { TransferType } from '@/constants/abacus';
import { STRING_KEYS } from '@/constants/localization';
import { useStringGetter } from '@/hooks';
import { SearchSelectMenu } from '@/components/SearchSelectMenu';
@@ -13,78 +12,45 @@ import { popoverMixins } from '@/styles/popoverMixins';
import { getTransferInputs } from '@/state/inputsSelectors';
import { isTruthy } from '@/lib/isTruthy';
import { testFlags } from '@/lib/testFlags';
type ElementProps = {
label?: string;
selectedExchange?: string;
selectedChain?: string;
onSelect: (name: string, type: 'chain' | 'exchange') => void;
onSelectChain: (chain: string) => void;
};
export const SourceSelectMenu = ({
label,
selectedExchange,
selectedChain,
onSelect,
}: ElementProps) => {
export const ChainSelectMenu = ({ label, selectedChain, onSelectChain }: ElementProps) => {
const stringGetter = useStringGetter();
const { type, depositOptions, withdrawalOptions, resources } =
useSelector(getTransferInputs, shallowEqual) || {};
const chains =
(type === TransferType.deposit ? depositOptions : withdrawalOptions)?.chains?.toArray() || [];
const exchanges =
(type === TransferType.deposit ? depositOptions : withdrawalOptions)?.exchanges?.toArray() ||
[];
const chainItems = Object.values(chains).map((chain) => ({
value: chain.type,
label: chain.stringKey,
onSelect: () => {
onSelect(chain.type, 'chain');
onSelectChain(chain.type);
},
slotBefore: <Styled.Img src={chain.iconUrl} alt="" />,
}));
const exchangeItems = Object.values(exchanges).map((exchange) => ({
value: exchange.type,
label: exchange.string,
onSelect: () => {
onSelect(exchange.type, 'exchange');
},
slotBefore: <Styled.Img src={exchange.iconUrl} alt="" />,
}));
const selectedChainOption = chains.find((item) => item.type === selectedChain);
const selectedExchangeOption = exchanges.find((item) => item.type === selectedExchange);
const selectedOption = chains.find((item) => item.type === selectedChain);
return (
<SearchSelectMenu
items={[
exchangeItems.length > 0 && testFlags.showCEXDepositOption && {
group: 'exchanges',
groupLabel: stringGetter({ key: STRING_KEYS.EXCHANGES }),
items: exchangeItems,
},
chainItems.length > 0 && {
{
group: 'chains',
groupLabel: stringGetter({ key: STRING_KEYS.CHAINS }),
items: chainItems,
},
].filter(isTruthy)}
]}
label={label || (type === TransferType.deposit ? 'Source' : 'Destination')}
>
<Styled.ChainRow>
{selectedChainOption ? (
{selectedChain ? (
<>
<Styled.Img src={selectedChainOption.iconUrl} alt="" /> {selectedChainOption.stringKey}
</>
) : selectedExchangeOption ? (
<>
<Styled.Img src={selectedExchangeOption.iconUrl} alt="" />{' '}
{selectedExchangeOption.string}
<Styled.Img src={selectedOption?.iconUrl} alt="" /> {selectedOption?.stringKey}
</>
) : (
stringGetter({ key: STRING_KEYS.SELECT_CHAIN })
@@ -17,6 +17,7 @@ import type { EvmAddress } from '@/constants/wallets';
import { useAccounts, useDebounce, useStringGetter, useSelectedNetwork } from '@/hooks';
import { useAccountBalance, CHAIN_DEFAULT_TOKEN_ADDRESS } from '@/hooks/useAccountBalance';
import { useLocalNotifications } from '@/hooks/useLocalNotifications';
import { useWalletConnection } from '@/hooks/useWalletConnection';
import { layoutMixins } from '@/styles/layoutMixins';
import { formMixins } from '@/styles/formMixins';
@@ -40,11 +41,10 @@ import { getNobleChainId, NATIVE_TOKEN_ADDRESS } from '@/lib/squid';
import { log } from '@/lib/telemetry';
import { parseWalletError } from '@/lib/wallet';
import { SourceSelectMenu } from './SourceSelectMenu';
import { ChainSelectMenu } from './ChainSelectMenu';
import { TokenSelectMenu } from './TokenSelectMenu';
import { DepositButtonAndReceipt } from './DepositForm/DepositButtonAndReceipt';
import { NobleDeposit } from '../NobleDeposit';
type DepositFormProps = {
onDeposit?: () => void;
@@ -57,14 +57,13 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
const [isLoading, setIsLoading] = useState(false);
const { selectedNetwork } = useSelectedNetwork();
const { evmAddress, signerWagmi, publicClientWagmi, nobleAddress } = useAccounts();
const { evmAddress, signerWagmi, publicClientWagmi } = useAccounts();
const { addTransferNotification } = useLocalNotifications();
const {
requestPayload,
token,
exchange,
chain: chainIdStr,
resources,
summary,
@@ -130,21 +129,14 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
if (error) onError?.();
}, [error]);
const onSelectChain = useCallback((name: string, type: 'chain' | 'exchange') => {
if (name) {
const onSelectChain = useCallback((chain: string) => {
if (chain) {
abacusStateManager.clearTransferInputValues();
abacusStateManager.setTransferValue({
field: TransferInputField.chain,
value: chain,
});
setFromAmount('');
if (type === 'chain') {
abacusStateManager.setTransferValue({
field: TransferInputField.chain,
value: name,
});
} else {
abacusStateManager.setTransferValue({
field: TransferInputField.exchange,
value: name,
});
}
}
}, []);
@@ -377,49 +369,39 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
return (
<Styled.Form onSubmit={onSubmit}>
<SourceSelectMenu
selectedChain={chainIdStr || undefined}
selectedExchange={exchange || undefined}
onSelect={onSelectChain}
/>
{exchange && nobleAddress ? (
<NobleDeposit />
) : (
<>
<TokenSelectMenu selectedToken={sourceToken || undefined} onSelectToken={onSelectToken} />
<Styled.WithDetailsReceipt side="bottom" detailItems={amountInputReceipt}>
<FormInput
type={InputType.Number}
onChange={onChangeAmount}
label={stringGetter({ key: STRING_KEYS.AMOUNT })}
value={fromAmount}
slotRight={
<Styled.FormInputButton size={ButtonSize.XSmall} onClick={onClickMax}>
{stringGetter({ key: STRING_KEYS.MAX })}
</Styled.FormInputButton>
}
/>
</Styled.WithDetailsReceipt>
{errorMessage && <AlertMessage type={AlertType.Error}>{errorMessage}</AlertMessage>}
{requireUserActionInWallet && (
<AlertMessage type={AlertType.Warning}>
{stringGetter({ key: STRING_KEYS.CHECK_WALLET_FOR_REQUEST })}
</AlertMessage>
)}
<Styled.Footer>
<DepositButtonAndReceipt
isDisabled={isDisabled}
isLoading={isLoading}
chainId={chainId || undefined}
setSlippage={onSetSlippage}
slippage={slippage}
sourceToken={sourceToken || undefined}
setRequireUserActionInWallet={setRequireUserActionInWallet}
setError={setError}
/>
</Styled.Footer>
</>
<ChainSelectMenu selectedChain={chainIdStr || undefined} onSelectChain={onSelectChain} />
<TokenSelectMenu selectedToken={sourceToken || undefined} onSelectToken={onSelectToken} />
<Styled.WithDetailsReceipt side="bottom" detailItems={amountInputReceipt}>
<FormInput
type={InputType.Number}
onChange={onChangeAmount}
label={stringGetter({ key: STRING_KEYS.AMOUNT })}
value={fromAmount}
slotRight={
<Styled.FormInputButton size={ButtonSize.XSmall} onClick={onClickMax}>
{stringGetter({ key: STRING_KEYS.MAX })}
</Styled.FormInputButton>
}
/>
</Styled.WithDetailsReceipt>
{errorMessage && <AlertMessage type={AlertType.Error}>{errorMessage}</AlertMessage>}
{requireUserActionInWallet && (
<AlertMessage type={AlertType.Warning}>
{stringGetter({ key: STRING_KEYS.CHECK_WALLET_FOR_REQUEST })}
</AlertMessage>
)}
<Styled.Footer>
<DepositButtonAndReceipt
isDisabled={isDisabled}
isLoading={isLoading}
chainId={chainId || undefined}
setSlippage={onSetSlippage}
slippage={slippage}
sourceToken={sourceToken || undefined}
setRequireUserActionInWallet={setRequireUserActionInWallet}
setError={setError}
/>
</Styled.Footer>
</Styled.Form>
);
};
@@ -38,7 +38,7 @@ import { Tag } from '@/components/Tag';
import { WithDetailsReceipt } from '@/components/WithDetailsReceipt';
import { Icon, IconName } from '@/components/Icon';
import { SourceSelectMenu } from '@/views/forms/AccountManagementForms/SourceSelectMenu';
import { ChainSelectMenu } from '@/views/forms/AccountManagementForms/ChainSelectMenu';
import { getSubaccount } from '@/state/accountSelectors';
import { getTransferInputs } from '@/state/inputsSelectors';
@@ -374,10 +374,10 @@ export const WithdrawForm = () => {
</span>
}
/>
<SourceSelectMenu
<ChainSelectMenu
label={stringGetter({ key: STRING_KEYS.NETWORK })}
selectedChain={chainIdStr || undefined}
onSelect={onSelectChain}
onSelectChain={onSelectChain}
/>
</Styled.DestinationRow>
<TokenSelectMenu selectedToken={toToken || undefined} onSelectToken={onSelectToken} />
-131
View File
@@ -1,131 +0,0 @@
import { useState } from 'react';
import styled, { type AnyStyledComponent } from 'styled-components';
import { OpacityToken } from '@/constants/styles/base';
import { STRING_KEYS } from '@/constants/localization';
import { layoutMixins } from '@/styles/layoutMixins';
import { useAccounts, useStringGetter } from '@/hooks';
import { CopyButton } from '@/components/CopyButton';
import { QrCode } from '@/components/QrCode';
import { Checkbox } from '@/components/Checkbox';
import { Icon, IconName } from '@/components/Icon';
import { TimeoutButton } from '@/components/TimeoutButton';
import { WithDetailsReceipt } from '@/components/WithDetailsReceipt';
import { WithReceipt } from '@/components/WithReceipt';
import { generateFadedColorVariant } from '@/lib/styles';
export const NobleDeposit = () => {
const [hasAcknowledged, setHasAcknowledged] = useState(false);
const stringGetter = useStringGetter();
const { nobleAddress } = useAccounts();
return (
<>
<WithDetailsReceipt
side="bottom"
detailItems={[
{
key: 'nobleAddress',
label: stringGetter({ key: STRING_KEYS.NOBLE_ADDRESS }),
value: nobleAddress,
},
]}
>
<Styled.QrCodeContainer>
<Styled.QrCode size={432} value={nobleAddress || ''} />
</Styled.QrCodeContainer>
</WithDetailsReceipt>
<Styled.WaitingSpan>
<Styled.CautionIconContainer>
<Icon iconName={IconName.CautionCircleStroked} />
</Styled.CautionIconContainer>
<p>{stringGetter({ key: STRING_KEYS.NOBLE_WARNING })}</p>
</Styled.WaitingSpan>
<Styled.WithReceipt
slotReceipt={
<Styled.CheckboxContainer>
<Checkbox
checked={hasAcknowledged}
onCheckedChange={setHasAcknowledged}
id="acknowledge-secret-phase-risk"
label={stringGetter({
key: STRING_KEYS.NOBLE_ACKNOWLEDGEMENT,
})}
/>
</Styled.CheckboxContainer>
}
>
<TimeoutButton
timeoutInSeconds={8}
slotFinal={<CopyButton state={{ isDisabled: !hasAcknowledged }} value={nobleAddress} />}
/>
</Styled.WithReceipt>
</>
);
};
const Styled: Record<string, AnyStyledComponent> = {};
Styled.WaitingSpan = styled.span`
${layoutMixins.row}
gap: 1rem;
color: var(--color-text-1);
`;
Styled.WithReceipt = styled(WithReceipt)`
--withReceipt-backgroundColor: var(--color-layer-2);
`;
Styled.QrCodeContainer = styled.div`
display: flex;
justify-content: center;
padding: 0.5rem;
background-color: var(--color-layer-2);
border-radius: 0.5rem;
`;
Styled.QrCode = styled(QrCode)`
max-height: 20rem;
width: fit-content;
svg {
max-height: 20rem;
}
`;
Styled.CheckboxContainer = styled.div`
padding: 1rem;
color: var(--color-text-0);
`;
Styled.CautionIconContainer = styled.div`
${layoutMixins.stack}
min-width: 2.5rem;
height: 2.5rem;
align-items: center;
border-radius: 50%;
overflow: hidden;
color: var(--color-warning);
svg {
width: 1.125em;
height: 1.125em;
justify-self: center;
}
&:before {
content: '';
width: 2.5rem;
height: 2.5rem;
background-color: ${({ theme }) =>
generateFadedColorVariant(theme.warning, OpacityToken.Opacity16)};
}
`;