Skip to content

Commit

Permalink
Merge pull request #886 from QuickSwap/dev2
Browse files Browse the repository at this point in the history
merge dev to master
  • Loading branch information
sameepsi authored Jun 29, 2023
2 parents bebc109 + a26a0f5 commit c11e553
Show file tree
Hide file tree
Showing 13 changed files with 583 additions and 296 deletions.
384 changes: 201 additions & 183 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"private": true,
"devDependencies": {
"@ethersproject/experimental": "^5.4.0",
"@orbs-network/twap-ui": "0.7.x",
"@orbs-network/twap-ui-quickswap": "0.7.x",
"@reduxjs/toolkit": "^1.3.5",
"@types/d3": "^6.7.1",
"@types/jest": "^25.2.1",
Expand Down Expand Up @@ -32,7 +34,6 @@
"@web3-react/metamask": "^8.2.0",
"@web3-react/network": "^8.2.0",
"@web3-react/types": "^8.2.0",
"@web3-react/walletconnect": "^8.2.0",
"ajv": "^6.12.3",
"cids": "^1.1.9",
"copy-to-clipboard": "^3.2.0",
Expand Down Expand Up @@ -70,9 +71,7 @@
"serve": "^11.3.2",
"source-map-explorer": "^2.5.2",
"start-server-and-test": "^1.11.0",
"typescript": "^4.1.2",
"@orbs-network/twap-ui": "0.7.x",
"@orbs-network/twap-ui-quickswap": "0.7.x"
"typescript": "^4.1.2"
},
"resolutions": {
"yargs-parser": "^13.1.2",
Expand Down Expand Up @@ -134,6 +133,8 @@
"@material-ui/lab": "^4.0.0-alpha.60",
"@paraswap/sdk": "^5.6.0-alpha.6",
"@venly/web3-provider": "3.1.0-develop.0",
"@walletconnect/ethereum-provider": "^2.8.5",
"@walletconnect/modal": "^2.5.4",
"apexcharts": "3.32.1",
"i18next-http-backend": "^1.4.1",
"numbro": "^2.3.5",
Expand Down
2 changes: 0 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ import 'slick-carousel/slick/slick-theme.css';
import './i18n';
import { mainTheme } from './theme';
import Background from 'layouts/Background';
import GasUpdater from 'state/application/gasUpdater';
import { RedirectExternal } from 'components/RedirectExternal/RedirectExternal';
import NotFound404Page from 'pages/NotFound404Page';

Expand Down Expand Up @@ -98,7 +97,6 @@ function Updaters() {
<SyrupUpdater />
<AnalyticsUpdater />
<AdsUpdater />
<GasUpdater />
</>
);
}
Expand Down
24 changes: 12 additions & 12 deletions src/components/StakeModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ export function FarmModal({
farmHandler(
selectedNFT,
{
pool: pool.id,
rewardToken: rewardToken.id,
bonusRewardToken: bonusRewardToken.id,
pool: pool?.id,
rewardToken: rewardToken?.id,
bonusRewardToken: bonusRewardToken?.id,
startTime,
endTime,
},
Expand All @@ -235,9 +235,9 @@ export function FarmModal({
[
farmHandler,
selectedNFT,
pool.id,
rewardToken.id,
bonusRewardToken.id,
pool,
rewardToken,
bonusRewardToken,
startTime,
endTime,
selectedTier,
Expand Down Expand Up @@ -268,31 +268,31 @@ export function FarmModal({
+_balance >=
+formatUnits(
BigNumber.from(tokenAmountForTier1),
multiplierToken.decimals,
multiplierToken?.decimals,
)
);
case tokenAmountForTier2:
return (
+_balance >=
+formatUnits(
BigNumber.from(tokenAmountForTier2),
multiplierToken.decimals,
multiplierToken?.decimals,
)
);
case tokenAmountForTier3:
return (
+_balance >=
+formatUnits(
BigNumber.from(tokenAmountForTier3),
multiplierToken.decimals,
multiplierToken?.decimals,
)
);
default:
return true;
}
}, [
balance,
multiplierToken.decimals,
multiplierToken?.decimals,
selectedTier,
tokenAmountForTier1,
tokenAmountForTier2,
Expand Down Expand Up @@ -375,7 +375,7 @@ export function FarmModal({
</Box>
) : positionsForPoolLoading ? (
<Box
className='flex justify-center items-center'
className='flex items-center justify-center'
width='100%'
height='400px'
>
Expand Down Expand Up @@ -418,7 +418,7 @@ export function FarmModal({
<p>{t('noNFTForPool')}</p>
</Box>
<p>{t('takePartinFarmNeedTo')}</p>
<Box mt={1} className='flex justify-center items-center'>
<Box mt={1} className='flex items-center justify-center'>
<NavLink
className='v3-stake-liquidity-link'
to={linkToProviding}
Expand Down
211 changes: 192 additions & 19 deletions src/connectors/WalletConnect.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,200 @@
import {
WalletConnect,
WalletConnectConstructorArgs,
} from '@web3-react/walletconnect';
import { rpcMap } from 'constants/providers';
import WalletConnectProvider from '@walletconnect/ethereum-provider';
import { Actions, ProviderRpcError, Connector } from '@web3-react/types';
import EventEmitter3 from 'eventemitter3';

import { getBestUrlMap, getChainsWithDefault } from './utils';

export const URI_AVAILABLE = 'URI_AVAILABLE';
const DEFAULT_TIMEOUT = 5000;

/**
* Options to configure the WalletConnect provider.
* For the full list of options, see {@link https://docs.walletconnect.com/2.0/javascript/providers/ethereum#initialization WalletConnect documentation}.
*/
export type WalletConnectOptions = Omit<
Parameters<typeof WalletConnectProvider.init>[0],
'rpcMap'
> & {
/**
* Map of chainIds to rpc url(s). If multiple urls are provided, the first one that responds
* within a given timeout will be used. Note that multiple urls are not supported by WalletConnect by default.
* That's why we extend its options with our own `rpcMap` (@see getBestUrlMap).
*/
rpcMap?: { [chainId: number]: string | string[] };
};

/**
* Options to configure the WalletConnect connector.
*/
export interface WalletConnectConstructorArgs {
actions: Actions;
/** Options to pass to `@walletconnect/ethereum-provider`. */
options: WalletConnectOptions;
/** The chainId to connect to in activate if one is not provided. */
defaultChainId?: number;
/**
* @param timeout - Timeout, in milliseconds, after which to treat network calls to urls as failed when selecting
* online urls.
*/
timeout?: number;
/**
* @param onError - Handler to report errors thrown from WalletConnect.
*/
onError?: (error: Error) => void;
}

export class WalletConnect extends Connector {
/** {@inheritdoc Connector.provider} */
public provider?: WalletConnectProvider;
public readonly events = new EventEmitter3();

private readonly options: Omit<WalletConnectOptions, 'rpcMap' | 'chains'>;

private readonly rpcMap?: Record<number, string | string[]>;
private readonly chains: number[];
private readonly defaultChainId?: number;
private readonly timeout: number;

private eagerConnection?: Promise<WalletConnectProvider>;

export class WalletConnectPopup extends WalletConnect {
constructor({
actions,
options,
defaultChainId,
timeout = DEFAULT_TIMEOUT,
onError,
qrcode = true,
qrcodeModalOptions,
}: Omit<WalletConnectConstructorArgs, 'options'> & {
qrcode?: boolean;
qrcodeModalOptions?: any;
}) {
super({
actions,
options: { qrcode, rpc: rpcMap, qrcodeModalOptions },
onError,
});
}: WalletConnectConstructorArgs) {
super(actions, onError);

const { rpcMap, chains, ...rest } = options;

this.options = rest;
this.chains = chains;
this.defaultChainId = defaultChainId;
this.rpcMap = rpcMap;
this.timeout = timeout;
}

private disconnectListener = (error: ProviderRpcError) => {
this.actions.resetState();
if (error) this.onError?.(error);
};

private chainChangedListener = (chainId: string): void => {
this.actions.update({ chainId: Number.parseInt(chainId, 16) });
};

private accountsChangedListener = (accounts: string[]): void => {
this.actions.update({ accounts });
};

private URIListener = (uri: string): void => {
this.events.emit(URI_AVAILABLE, uri);
};

private isomorphicInitialize(
desiredChainId: number | undefined = this.defaultChainId,
): Promise<WalletConnectProvider> {
if (this.eagerConnection) return this.eagerConnection;

const rpcMap = this.rpcMap
? getBestUrlMap(this.rpcMap, this.timeout)
: undefined;
const chains = desiredChainId
? getChainsWithDefault(this.chains, desiredChainId)
: this.chains;

return (this.eagerConnection = import(
'@walletconnect/ethereum-provider'
).then(async (ethProviderModule) => {
const provider = (this.provider = await ethProviderModule.default.init({
...this.options,
chains,
rpcMap: await rpcMap,
}));

return provider
.on('disconnect', this.disconnectListener)
.on('chainChanged', this.chainChangedListener)
.on('accountsChanged', this.accountsChangedListener)
.on('display_uri', this.URIListener);
}));
}

/** {@inheritdoc Connector.connectEagerly} */
public async connectEagerly(): Promise<void> {
const cancelActivation = this.actions.startActivation();

try {
const provider = await this.isomorphicInitialize();
// WalletConnect automatically persists and restores active sessions
if (!provider.session) {
throw new Error('No active session found. Connect your wallet first.');
}
this.actions.update({
accounts: provider.accounts,
chainId: provider.chainId,
});
} catch (error) {
await this.deactivate();
cancelActivation();
throw error;
}
}

/**
* @param desiredChainId - The desired chainId to connect to.
*/
public async activate(desiredChainId?: number): Promise<void> {
const provider = await this.isomorphicInitialize(desiredChainId);

if (provider.session) {
if (!desiredChainId || desiredChainId === provider.chainId) return;
// WalletConnect exposes connected accounts, not chains: `eip155:${chainId}:${address}`
const isConnectedToDesiredChain = provider.session.namespaces.eip155.accounts.some(
(account) => account.startsWith(`eip155:${desiredChainId}:`),
);
if (!isConnectedToDesiredChain) {
if (this.options.optionalChains?.includes(desiredChainId)) {
throw new Error(
`Cannot activate an optional chain (${desiredChainId}), as the wallet is not connected to it.\n\tYou should handle this error in application code, as there is no guarantee that a wallet is connected to a chain configured in "optionalChains".`,
);
}
throw new Error(
`Unknown chain (${desiredChainId}). Make sure to include any chains you might connect to in the "chains" or "optionalChains" parameters when initializing WalletConnect.`,
);
}
return provider.request<void>({
method: 'wallet_switchEthereumChain',
params: [{ chainId: `0x${desiredChainId.toString(16)}` }],
});
}

const cancelActivation = this.actions.startActivation();

try {
await provider.enable();
this.actions.update({
chainId: provider.chainId,
accounts: provider.accounts,
});
} catch (error) {
await this.deactivate();
cancelActivation();
throw error;
}
}

activate(chainId?: number) {
return super.activate(chainId);
/** {@inheritdoc Connector.deactivate} */
public async deactivate(): Promise<void> {
this.provider
?.removeListener('disconnect', this.disconnectListener)
.removeListener('chainChanged', this.chainChangedListener)
.removeListener('accountsChanged', this.accountsChangedListener)
.removeListener('display_uri', this.URIListener)
.disconnect();
this.provider = undefined;
this.eagerConnection = undefined;
this.actions.resetState();
}
}
32 changes: 32 additions & 0 deletions src/connectors/WalletConnectPopup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { SUPPORTED_CHAINIDS } from 'constants/index';
import { WalletConnect, WalletConnectConstructorArgs } from './WalletConnect';
import { rpcMap } from 'constants/providers';
import { QrModalOptions } from '@walletconnect/ethereum-provider/dist/types/EthereumProvider';

export class WalletConnectPopup extends WalletConnect {
constructor({
actions,
onError,
qrcode = true,
qrModalOptions,
}: Omit<WalletConnectConstructorArgs, 'options'> & {
qrcode?: boolean;
qrModalOptions?: QrModalOptions;
}) {
super({
actions,
options: {
showQrModal: qrcode,
chains: [1],
optionalChains: SUPPORTED_CHAINIDS,
projectId: 'a6cc11517a10f6f12953fd67b1eb67e7',
qrModalOptions,
},
onError,
});
}

activate(chainId?: number) {
return super.activate(chainId);
}
}
Loading

0 comments on commit c11e553

Please sign in to comment.