diff --git a/src/models/wallets.ts b/src/models/wallets.ts index 7799d24..d59effb 100644 --- a/src/models/wallets.ts +++ b/src/models/wallets.ts @@ -15,6 +15,7 @@ export interface LumWalletModel { deposits: AggregatedDepositModel[]; prizes: PrizeModel[]; totalPrizesWon: { [denom: string]: number }; + isLedger: boolean; } export interface OtherWalletModel { diff --git a/src/pages/Deposit/Deposit.tsx b/src/pages/Deposit/Deposit.tsx index 394b574..97b6cb7 100644 --- a/src/pages/Deposit/Deposit.tsx +++ b/src/pages/Deposit/Deposit.tsx @@ -13,7 +13,7 @@ import cosmonautWithRocket from 'assets/lotties/cosmonaut_with_rocket.json'; import Assets from 'assets'; import { Button, Card, Lottie, Modal, PurpleBackgroundImage, Steps } from 'components'; -import { FirebaseConstants, NavigationConstants } from 'constant'; +import { FirebaseConstants, NavigationConstants, WalletProvider } from 'constant'; import { useColorScheme, usePrevious, useVisibilityState } from 'hooks'; import { PoolModel } from 'models'; import { DenomsUtils, Firebase, I18n, NumbersUtils, WalletUtils, WalletProvidersUtils } from 'utils'; @@ -82,39 +82,43 @@ const Deposit = () => { }, walletClient: { enable: async (chainIds) => { - const autoConnectProvider = WalletUtils.getAutoconnectProvider(); - if (autoConnectProvider) { - const providerFunctions = WalletProvidersUtils.getProviderFunctions(autoConnectProvider); + const autoConnectProvider = WalletUtils.getAutoconnectProvider() || WalletProvider.Keplr; - for (const chainId of chainIds) { - await providerFunctions.enable(chainId); - } + const providerFunctions = WalletProvidersUtils.getProviderFunctions(autoConnectProvider); + + if (!providerFunctions) { + return; + } + + for (const chainId of chainIds) { + await providerFunctions.enable(chainId); } }, getKey: async (chainId) => { - const autoConnectProvider = WalletUtils.getAutoconnectProvider(); - if (autoConnectProvider) { - const providerFunctions = WalletProvidersUtils.getProviderFunctions(autoConnectProvider); - - return await providerFunctions.getKey(chainId); + const autoConnectProvider = WalletUtils.getAutoconnectProvider() || WalletProvider.Keplr; + + const providerFunctions = WalletProvidersUtils.getProviderFunctions(autoConnectProvider); + + if (!providerFunctions) { + return { + address: new Uint8Array(), + pubKey: new Uint8Array(), + name: '', + algo: '', + isNanoLedger: false, + bech32Address: '', + }; } - return { - address: new Uint8Array(), - pubKey: new Uint8Array(), - name: '', - algo: '', - isNanoLedger: false, - bech32Address: '', - }; + return await providerFunctions.getKey(chainId); }, getOfflineSigner: (chainId) => { - const autoConnectProvider = WalletUtils.getAutoconnectProvider(); + const autoConnectProvider = WalletUtils.getAutoconnectProvider() || WalletProvider.Keplr; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const providerFunctions = WalletProvidersUtils.getProviderFunctions(autoConnectProvider!); + const providerFunctions = WalletProvidersUtils.getProviderFunctions(autoConnectProvider); - return providerFunctions.getOfflineSigner(chainId); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return providerFunctions!.getOfflineSigner(chainId); }, }, }; @@ -855,6 +859,7 @@ const Deposit = () => { } const isShareStep = currentStep >= steps.length; + const showSwapCard = otherWallet && process.env.NODE_ENV !== 'test'; return ( <> @@ -864,7 +869,7 @@ const Deposit = () => {

- {otherWallet && process.env.NODE_ENV !== 'test' ? ( + {showSwapCard ? (
{I18n.t('deposit.swapHint.content')}
@@ -909,7 +914,7 @@ const Deposit = () => { />
) : null} - +
diff --git a/src/pages/MySavings/MySavings.tsx b/src/pages/MySavings/MySavings.tsx index be912f8..2f2bf4e 100644 --- a/src/pages/MySavings/MySavings.tsx +++ b/src/pages/MySavings/MySavings.tsx @@ -534,7 +534,7 @@ const MySavings = () => { balances={balances || []} isLoading={isTransferring} /> - +
); diff --git a/src/pages/MySavings/components/Modals/Claim/Claim.tsx b/src/pages/MySavings/components/Modals/Claim/Claim.tsx index 0e48c36..925c882 100644 --- a/src/pages/MySavings/components/Modals/Claim/Claim.tsx +++ b/src/pages/MySavings/components/Modals/Claim/Claim.tsx @@ -22,6 +22,7 @@ interface Props { prizes: PrizeModel[]; prices: { [key: string]: number }; pools: PoolModel[]; + limit: number; } type ShareInfos = { hash: string; amount: LumTypes.Coin[]; tvl: string; poolId: string; compounded: boolean }; @@ -122,7 +123,7 @@ const ShareClaim = ({ infos, prices, modalRef, onTwitterShare }: { infos: ShareI ); }; -const Claim = ({ prizes, prices, pools }: Props) => { +const Claim = ({ prizes, prices, pools, limit }: Props) => { const [blockedCompound, setBlockedCompound] = useState(false); const [claimOnly, setClaimOnly] = useState(false); const [currentStep, setCurrentStep] = useState(0); @@ -150,8 +151,7 @@ const Claim = ({ prizes, prices, pools }: Props) => { Firebase.logEvent(FirebaseConstants.ANALYTICS_EVENTS.JUST_CLAIMED_CONFIRMED); } - const LIMIT = 6; - const batchCount = Math.ceil(prizes.length / LIMIT); + const batchCount = Math.ceil(prizes.length / limit); setBatchTotal(batchCount); setCurrentStep(currentStep + 1); @@ -160,11 +160,9 @@ const Claim = ({ prizes, prices, pools }: Props) => { setBatch(batch); }; - const payload = { prizes, batch, batchTotal: batchCount, onBatchComplete }; - const action = compound ? dispatch.wallet.claimAndCompoundPrizes : dispatch.wallet.claimPrizes; - const res = await action(payload); + const res = await action({ prizes, batch, batchTotal: batchCount, limit, onBatchComplete }); if (!res || (res && res.error)) { setCurrentStep(currentStep); diff --git a/src/redux/models/wallet.ts b/src/redux/models/wallet.ts index b71fa54..9a0cbb2 100644 --- a/src/redux/models/wallet.ts +++ b/src/redux/models/wallet.ts @@ -9,6 +9,10 @@ import { LumWalletModel, OtherWalletModel, PoolModel, PrizeModel, TransactionMod import { RootModel } from '.'; import { LumApi } from 'api'; +type SignInLumPayload = LumWallet & { + isLedger: boolean; +}; + interface IbcTransferPayload { fromAddress: string; toAddress: string; @@ -51,6 +55,7 @@ interface ClaimPrizesPayload { prizes: PrizeModel[]; batchTotal: number; batch: number; + limit: number; onBatchComplete: (batch: number) => void; } @@ -89,7 +94,7 @@ export const wallet = createModel()({ prizesMutex: false, } as WalletState, reducers: { - signInLum(state, payload: LumWallet): WalletState { + signInLum(state, payload: SignInLumPayload): WalletState { return { ...state, lumWallet: { @@ -104,6 +109,7 @@ export const wallet = createModel()({ deposits: [], prizes: [], totalPrizesWon: {}, + isLedger: !!payload.isLedger, }, }; }, @@ -249,10 +255,16 @@ export const wallet = createModel()({ if (provider === WalletProvider.Cosmostation) { await WalletProvidersUtils.requestCosmostationAccount(chainId); } + const lumOfflineSigner = await providerFunctions.getOfflineSigner(chainId); const lumWallet = await LumWalletFactory.fromOfflineSigner(lumOfflineSigner); + if (lumWallet) { - dispatch.wallet.signInLum(lumWallet); + const { isNanoLedger } = await providerFunctions.getKey(chainId); + + const wallet = Object.assign(lumWallet, { isLedger: isNanoLedger }); + + dispatch.wallet.signInLum(wallet); WalletUtils.storeAutoconnectKey(provider); @@ -773,8 +785,6 @@ export const wallet = createModel()({ let prizesToClaim = [...prizes]; - const LIMIT = 6; - const toastId = ToastUtils.showLoadingToast({ content: I18n.t(batchTotal > 1 ? 'pending.claimPrize' : 'pending.claimPrize', { count: 1, total: batchTotal }) }); let lastBatch = 0; @@ -795,7 +805,7 @@ export const wallet = createModel()({ }); } - const toClaim = prizesToClaim.slice(0, LIMIT); + const toClaim = prizesToClaim.slice(0, payload.limit); result = await LumClient.claimPrizes(lumWallet.innerWallet, toClaim); diff --git a/src/tests/app.test.tsx b/src/tests/app.test.tsx index 958ab56..dfa90ec 100644 --- a/src/tests/app.test.tsx +++ b/src/tests/app.test.tsx @@ -143,8 +143,9 @@ describe('App', () => { it('render the My Savings Page without crashing', async () => { // Log in using a test wallet to enable My Savings page const testWallet = await LumWalletFactory.fromMnemonic(testMnemonic); + const wallet = Object.assign(testWallet, { isLedger: false }); - store.dispatch.wallet.signInLum(testWallet); + store.dispatch.wallet.signInLum(wallet); // Render My Savings page renderWithRematchStore( @@ -188,10 +189,11 @@ describe('App', () => { expect(transferBtn.parentElement).toBeDisabled(); const testWallet = await LumWalletFactory.fromMnemonic(testMnemonic); + const wallet = Object.assign(testWallet, { isLedger: false }); // Fake log in to enable the transfer button act(() => { - store.dispatch.wallet.signInLum(testWallet); + store.dispatch.wallet.signInLum(wallet); store.dispatch.wallet.setOtherWalletData({ denom: 'atom', balances: [], diff --git a/src/utils/walletProviders.ts b/src/utils/walletProviders.ts index 6ac7022..e5e231e 100644 --- a/src/utils/walletProviders.ts +++ b/src/utils/walletProviders.ts @@ -20,7 +20,15 @@ export const isAnyWalletInstalled = (): boolean => { return isCosmostationInstalled() || isKeplrInstalled(); }; +const isProviderInstalled = (provider: WalletProvider) => { + return provider === WalletProvider.Cosmostation ? isCosmostationInstalled() : isKeplrInstalled(); +}; + export const getProviderFunctions = (provider: WalletProvider) => { + if (!isProviderInstalled(provider)) { + return null; + } + return { enable: (chainId: string) => { if (provider === WalletProvider.Cosmostation) { @@ -29,11 +37,11 @@ export const getProviderFunctions = (provider: WalletProvider) => { const keplrProvider = provider === WalletProvider.Keplr ? window.keplr : window.leap; - if (keplrProvider) { - return keplrProvider.enable(chainId); + if (!keplrProvider) { + throw new Error(I18n.t('errors.walletProvider.notInstalled', { provider })); } - throw new Error(I18n.t('errors.walletProvider.notInstalled', { provider })); + return keplrProvider.enable(chainId); }, getOfflineSigner: (chainId: string) => { if (provider === WalletProvider.Cosmostation) { @@ -46,27 +54,15 @@ export const getProviderFunctions = (provider: WalletProvider) => { const keplrProvider = provider === WalletProvider.Keplr ? window.keplr : window.leap; - if (keplrProvider) { - return keplrProvider.getOfflineSignerAuto(chainId); + if (!keplrProvider) { + throw new Error(I18n.t('errors.walletProvider.notInstalled', { provider })); } - throw new Error(I18n.t('errors.walletProvider.notInstalled', { provider })); + return keplrProvider.getOfflineSignerAuto(chainId); }, getKey: async (chainId: string): Promise => { if (provider === WalletProvider.Cosmostation) { - if (isCosmostationInstalled()) { - const account = await requestCosmostationAccount(chainId); - - return { - address: LumUtils.fromBech32(account.address).data, - bech32Address: account.address, - name: account.name, - algo: 'secp256k1', - isNanoLedger: account.isLedger, - pubKey: account.publicKey, - isKeystone: false, - }; - } else { + if (!isCosmostationInstalled()) { return { address: new Uint8Array(), pubKey: new Uint8Array(), @@ -77,23 +73,34 @@ export const getProviderFunctions = (provider: WalletProvider) => { bech32Address: '', }; } - } else { - const keplrProvider = provider === WalletProvider.Keplr ? window.keplr : window.leap; + const account = await requestCosmostationAccount(chainId); + + return { + address: LumUtils.fromBech32(account.address).data, + bech32Address: account.address, + name: account.name, + algo: 'secp256k1', + isNanoLedger: account.isLedger, + pubKey: account.publicKey, + isKeystone: false, + }; + } - if (keplrProvider) { - return await keplrProvider.getKey(chainId); - } else { - return { - address: new Uint8Array(), - pubKey: new Uint8Array(), - name: '', - algo: '', - isNanoLedger: false, - isKeystone: false, - bech32Address: '', - }; - } + const keplrProvider = provider === WalletProvider.Keplr ? window.keplr : window.leap; + + if (!keplrProvider) { + return { + address: new Uint8Array(), + pubKey: new Uint8Array(), + name: '', + algo: '', + isNanoLedger: false, + isKeystone: false, + bech32Address: '', + }; } + + return await keplrProvider.getKey(chainId); }, }; };