Skip to content

Commit

Permalink
fix(bridge-ui): selecting chain was not informing of errors (#13712)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Wang <[email protected]>
  • Loading branch information
jscriptcoder and dantaik authored May 13, 2023
1 parent 523f95b commit 5d29c6d
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 53 deletions.
2 changes: 2 additions & 0 deletions packages/bridge-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@babel/preset-env": "^7.16.0",
"@sveltejs/vite-plugin-svelte": "^1.0.1",
"@tsconfig/svelte": "^3.0.0",
"@types/debug": "^4.1.7",
"@types/eslint": "^8.2.1",
"@types/estree": "^0.0.50",
"@types/jest": "^27.0.2",
Expand Down Expand Up @@ -75,6 +76,7 @@
"@wagmi/core": "^0.8.0",
"axios": "^1.2.0",
"buffer": "^6.0.3",
"debug": "^4.3.4",
"ethers": "^5.7.1",
"identicon.js": "^2.3.3",
"svelte-i18n": "^3.5.1",
Expand Down
41 changes: 18 additions & 23 deletions packages/bridge-ui/src/components/ChainDropdown.svelte
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
<script lang="ts">
import { fromChain, toChain } from '../store/chain';
import type { Chain } from '../domain/chain';
import { ethers } from 'ethers';
import { signer } from '../store/signer';
import { switchNetwork } from '@wagmi/core';
import { fromChain } from '../store/chain';
import { ChevronDown, ExclamationTriangle } from 'svelte-heros-v2';
import { mainnetChain, taikoChain } from '../chain/chains';
import { selectChain } from '../utils/selectChain';
import type { Chain } from '../domain/chain';
import { errorToast, successToast } from './Toast.svelte';
import { signer } from '../store/signer';
const changeChain = async (chain: Chain) => {
await switchNetwork({
chainId: chain.id,
});
const provider = new ethers.providers.Web3Provider(window.ethereum, 'any');
await provider.send('eth_requestAccounts', []);
const switchChains = async (chain: Chain) => {
if (!$signer) {
errorToast('Please connect your wallet');
return;
}
fromChain.set(chain);
if (chain === mainnetChain) {
toChain.set(taikoChain);
} else {
toChain.set(mainnetChain);
try {
await selectChain(chain);
successToast('Successfully changed chain');
} catch (e) {
console.error(e);
errorToast('Error switching chain');
}
signer.set(provider.getSigner());
};
</script>

Expand Down Expand Up @@ -50,19 +49,15 @@
<li>
<button
class="flex items-center px-2 py-4 hover:bg-dark-5 rounded-xl justify-around"
on:click={async () => {
await changeChain(mainnetChain);
}}>
on:click={() => switchChains(mainnetChain)}>
<svelte:component this={mainnetChain.icon} height={24} />
<span class="pl-1.5 text-left flex-1">{mainnetChain.name}</span>
</button>
</li>
<li>
<button
class="flex items-center px-2 py-4 hover:bg-dark-5 rounded-xl justify-around"
on:click={async () => {
await changeChain(taikoChain);
}}>
on:click={() => switchChains(taikoChain)}>
<svelte:component this={taikoChain.icon} height={24} />
<span class="pl-1.5 text-left flex-1">{taikoChain.name}</span>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import { tokenVaults } from '../../vault/tokenVaults';
import { isOnCorrectChain } from '../../utils/isOnCorrectChain';
import Button from '../buttons/Button.svelte';
import { switchChainAndSetSigner } from '../../utils/switchChainAndSetSigner';
import { selectChain } from '../../utils/selectChain';
import type { NoticeOpenArgs } from '../../domain/modal';
export let transaction: BridgeTransaction;
Expand Down Expand Up @@ -81,7 +81,7 @@
// to the right network.
if ($fromChain.id !== bridgeTx.toChainId) {
const chain = chains[bridgeTx.toChainId];
await switchChainAndSetSigner(chain);
await selectChain(chain);
}
// confirm after switch chain that it worked.
Expand Down Expand Up @@ -133,7 +133,7 @@
loading = true;
if (txFromChain.id !== bridgeTx.fromChainId) {
const chain = chains[bridgeTx.fromChainId];
await switchChainAndSetSigner(chain);
await selectChain(chain);
}
// confirm after switch chain that it worked.
Expand Down
19 changes: 4 additions & 15 deletions packages/bridge-ui/src/components/form/SelectChain.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,20 @@
import { ArrowRight } from 'svelte-heros-v2';
import { fromChain, toChain } from '../../store/chain';
import { signer } from '../../store/signer';
import { ethers } from 'ethers';
import { mainnetChain, taikoChain } from '../../chain/chains';
import { errorToast, successToast } from '../Toast.svelte';
import { selectChain } from '../../utils/selectChain';
const toggleChains = async () => {
if (!$signer) {
errorToast('Please connect your wallet');
return;
}
try {
const chain = $fromChain === mainnetChain ? taikoChain : mainnetChain;
await switchNetwork({
chainId: chain.id,
});
const provider = new ethers.providers.Web3Provider(
window.ethereum,
'any',
);
await provider.send('eth_requestAccounts', []);
fromChain.set(chain);
toChain.set(chain === mainnetChain ? taikoChain : mainnetChain);
const chain = $fromChain === mainnetChain ? taikoChain : mainnetChain;
signer.set(provider.getSigner());
try {
await selectChain(chain);
successToast('Successfully changed chain');
} catch (e) {
console.error(e);
Expand Down
2 changes: 1 addition & 1 deletion packages/bridge-ui/src/proof/ProofService.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BigNumber, ethers } from 'ethers';
import { ethers } from 'ethers';
import type { EthGetProofResponse } from '../domain/proof';
import { ProofService } from './ProofService';

Expand Down
5 changes: 5 additions & 0 deletions packages/bridge-ui/src/utils/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import debug from 'debug';

export function getLogger(namesapce: string) {
return debug(`bridge:${namesapce}`);
}
74 changes: 74 additions & 0 deletions packages/bridge-ui/src/utils/selectChain.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { switchNetwork } from '@wagmi/core';
import { Signer, ethers } from 'ethers';
import { fromChain, toChain } from '../store/chain';
import { signer } from '../store/signer';
import { mainnetChain, taikoChain } from '../chain/chains';
import { selectChain } from './selectChain';

jest.mock('../constants/envVars');

jest.mock('@wagmi/core', () => ({
switchNetwork: jest.fn(),
}));

jest.mock('ethers', () => {
const Web3Provider = jest.fn();
Web3Provider.prototype = {
getSigner: jest.fn(),
send: jest.fn(),
};
return {
ethers: {
providers: {
Web3Provider,
},
},
};
});

jest.mock('../store/chain', () => ({
fromChain: {
set: jest.fn(),
},
toChain: {
set: jest.fn(),
},
}));

jest.mock('../store/signer', () => ({
signer: {
set: jest.fn(),
},
}));

describe('selectChain', () => {
it('should select chain', async () => {
const mockSigner = {} as ethers.providers.JsonRpcSigner;
jest
.mocked(ethers.providers.Web3Provider.prototype.getSigner)
.mockReturnValue(mockSigner);

await selectChain(mainnetChain);

expect(switchNetwork).toHaveBeenCalledWith({ chainId: mainnetChain.id });
expect(fromChain.set).toHaveBeenCalledWith(mainnetChain);
expect(toChain.set).toHaveBeenCalledWith(taikoChain);
expect(signer.set).toHaveBeenCalled();

expect(ethers.providers.Web3Provider.prototype.send).toHaveBeenCalledWith(
'eth_requestAccounts',
[],
);

expect(
ethers.providers.Web3Provider.prototype.getSigner,
).toHaveBeenCalled();

expect(signer.set).toHaveBeenCalledWith(mockSigner);

// Select the other chain now
await selectChain(taikoChain);

expect(switchNetwork).toHaveBeenCalledWith({ chainId: taikoChain.id });
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { fetchSigner, switchNetwork } from '@wagmi/core';
import { switchNetwork } from '@wagmi/core';
import { ethers } from 'ethers';
import { fromChain, toChain } from '../store/chain';
import type { Chain } from '../domain/chain';
import { mainnetChain, taikoChain } from '../chain/chains';
import { signer } from '../store/signer';
import { getLogger } from '../utils/logger';

export async function switchChainAndSetSigner(chain: Chain) {
const log = getLogger('selectChain');

export async function selectChain(chain: Chain) {
const chainId = chain.id;

await switchNetwork({ chainId });
Expand All @@ -14,7 +17,11 @@ export async function switchChainAndSetSigner(chain: Chain) {
globalThis.ethereum,
'any',
);
await provider.send('eth_requestAccounts', []);

// Requires requesting permission to connect users accounts
const accounts = await provider.send('eth_requestAccounts', []);

log('accounts', accounts);

fromChain.set(chain);
if (chain.id === mainnetChain.id) {
Expand All @@ -23,7 +30,9 @@ export async function switchChainAndSetSigner(chain: Chain) {
toChain.set(mainnetChain);
}

const wagmiSigner = await fetchSigner({ chainId });
const _signer = provider.getSigner();

log('signer', _signer);

signer.set(wagmiSigner);
signer.set(_signer);
}
Loading

0 comments on commit 5d29c6d

Please sign in to comment.