Skip to content

Commit

Permalink
promt switch network only before transaction signing
Browse files Browse the repository at this point in the history
  • Loading branch information
Viterbo authored and donnyquixotic committed Feb 4, 2024
1 parent ccccbe5 commit 259baa5
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 34 deletions.
62 changes: 61 additions & 1 deletion src/antelope/mocks/AccountStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
// Mocking AccountStore -----------------------------------
// useAccountStore().getAccount(this.label).account as addressString;
import { EVMAuthenticator } from 'src/antelope/wallets';
import { addressString } from 'src/antelope/types';
import { AntelopeError, addressString } from 'src/antelope/types';
import { CURRENT_CONTEXT, EVMChainSettings, createTraceFunction, useChainStore } from 'src/antelope/mocks';
import { BigNumber } from 'ethers'; 'src/antelope/mocks/FeedbackStore';
import { getAntelope } from 'src/antelope/mocks/AntelopeConfig';
import { useFeedbackStore } from 'src/antelope/mocks';
import { EvmABI, EvmFunctionParam, Label, TransactionResponse } from 'src/antelope/types';
import { subscribeForTransactionReceipt } from 'src/antelope/wallets/utils/trx-utils';

export const errorToString = (error: unknown) =>
getAntelope().config.errorToStringHandler(error);

export interface AccountModel {
label: typeof CURRENT_CONTEXT;
isNative: boolean;
Expand Down Expand Up @@ -98,6 +101,10 @@ class AccountStore {
const funcname = 'signCustomTransaction';
this.trace(funcname, label, contract, abi, parameters, value?.toString());

if (! await this.assertNetworkConnection(label)) {
throw new AntelopeError('antelope.evm.error_switch_chain_rejected');
}

try {
useFeedbackStore().setLoading(funcname);
const account = this.loggedAccount as EvmAccountModel;
Expand Down Expand Up @@ -130,6 +137,59 @@ class AccountStore {
}
}

async isConnectedToCorrectNetwork(label: string): Promise<boolean> {
this.trace('isConnectedToCorrectNetwork', label);
try {
useFeedbackStore().setLoading('account.isConnectedToCorrectNetwork');
const authenticator = useAccountStore().getAccount(label)?.authenticator as EVMAuthenticator;
return authenticator.isConnectedToCorrectChain();
} catch (error) {
console.error('Error: ', errorToString(error));
return Promise.resolve(false);
} finally {
useFeedbackStore().unsetLoading('account.isConnectedToCorrectNetwork');
}
}

async assertNetworkConnection(label: string): Promise<boolean> {
if (!await useAccountStore().isConnectedToCorrectNetwork(label)) {
return new Promise<boolean>((resolve) => {
const ant = getAntelope();
const authenticator = useAccountStore().loggedAccount.authenticator as EVMAuthenticator;
const networkName = useChainStore().loggedChain.settings.getDisplay();
const errorMessage = ant.config.localizationHandler('evm_wallet.incorrect_network', { networkName });
let userClickedSwitch = false;
ant.config.notifyFailureWithAction(errorMessage, {
label: ant.config.localizationHandler('evm_wallet.switch'),
handler: async () => {
userClickedSwitch = true;
try {
await authenticator.ensureCorrectChain();
if (!await useAccountStore().isConnectedToCorrectNetwork(label)) {
resolve(false);
} else {
resolve(true);
}
} catch (error) {
const message = (error as Error).message;
if (message === 'antelope.evm.error_switch_chain_rejected') {
ant.config.notifyNeutralMessageHandler(message);
}
resolve(false);
}
},
onDismiss: () => {
if (!userClickedSwitch) {
resolve(false);
}
},
});
});
} else {
return true;
}
}

}

const accountStore = new AccountStore();
Expand Down
33 changes: 0 additions & 33 deletions src/antelope/mocks/EVMStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import { ethers } from 'ethers';
import { EVMAuthenticator, InjectedProviderAuth } from 'src/antelope/wallets';
import { createTraceFunction } from 'src/antelope/mocks/FeedbackStore';
import { getAntelope } from 'src/antelope/mocks/AntelopeConfig';
import { EVMChainSettings, useChainStore, useFeedbackStore, useAccountStore } from 'src/antelope/mocks';
import { AntelopeError, EthereumProvider, ExceptionError } from 'src/antelope/types';
import { RpcEndpoint } from 'universal-authenticator-library';
Expand All @@ -21,7 +20,6 @@ class EVMStore {
this.trace('initInjectedProvider', authenticator.getName(), [authenticator.getProvider()]);
const provider: EthereumProvider | null = authenticator.getProvider();
const evm = useEVMStore();
const ant = getAntelope();

if (provider && !provider.__initialized) {
this.trace('initInjectedProvider', authenticator.getName(), 'initializing provider');
Expand All @@ -36,37 +34,6 @@ class EVMStore {
}
}

// this handler activates only when the user comes back from switching to the wrong network on the wallet
// It checks if the user is on the correct network and if not, it shows a notification with a button to switch
const checkNetworkHandler = async () => {
window.removeEventListener('focus', checkNetworkHandler);
if (useAccountStore().loggedAccount) {
const authenticator = useAccountStore().loggedAccount.authenticator as EVMAuthenticator;
if (await authenticator.isConnectedToCorrectChain()) {
evm.trace('checkNetworkHandler', 'correct network');
} else {
const networkName = useChainStore().loggedChain.settings.getDisplay();
const errorMessage = ant.config.localizationHandler('evm_wallet.incorrect_network', { networkName });
const label = ant.config.localizationHandler('evm_wallet.switch');
ant.config.notifyFailureWithAction(errorMessage, {
label,
handler: () => {
authenticator.ensureCorrectChain();
},
});
}
}
};

provider.on('chainChanged', (value) => {
const newNetwork = value as string;
evm.trace('provider.chainChanged', newNetwork);
window.removeEventListener('focus', checkNetworkHandler);
if (useAccountStore().loggedAccount) {
window.addEventListener('focus', checkNetworkHandler);
}
});

provider.on('accountsChanged', async (value) => {
const accounts = value as string[];
const network = useChainStore().currentChain.settings.getNetwork();
Expand Down
3 changes: 3 additions & 0 deletions src/assets/icon--warning.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions src/boot/errorHandling.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class NotificationAction {
this.label = payload.label;
this.class = payload.class;
this.handler = payload.handler;
this.onDismiss = payload.onDismiss;
this.iconRight = payload.iconRight;
this.color = payload.color;
}
Expand All @@ -68,6 +69,7 @@ const crossIcon = require('src/assets/icon--cross.svg');
const infoIcon = require('src/assets/icon--info.svg');
const checkIcon = require('src/assets/icon--check.svg');
const discoIcon = require('src/assets/icon--disconnected.svg');
const warningIcon = require('src/assets/icon--warning.svg');

const html = `
<div class="c-notify__container c-notify__container--{type} c-notify__container--{random}">
Expand Down Expand Up @@ -142,11 +144,14 @@ const notifyMessage = function(type, icon, title, message, payload, remember = '
class: 'c-notify__action-btn c-notify__action-btn--hide',
};

let onDismiss = null;

// adding buttons
if (typeof payload === 'string' && type === 'success') {
actions.push(link_btn);
} else if (typeof payload === 'object' && payload instanceof NotificationAction) {
actions.push(action_btn);
onDismiss = payload.onDismiss;
} else if (typeof payload === 'object' && type === 'error') {
actions.push(details_btn);
} else {
Expand Down Expand Up @@ -206,6 +211,7 @@ const notifyMessage = function(type, icon, title, message, payload, remember = '
html: true,
classes: 'c-notify',
actions,
onDismiss,
});
};

Expand Down Expand Up @@ -258,6 +264,16 @@ const notifyFailureWithAction = function(message, payload) {
);
};

const notifyWarningWithAction = function(message, payload) {
return notifyMessage.bind(this)(
'error',
warningIcon,
this.$t('notification.warning_title').toUpperCase(),
message,
new NotificationAction(payload),
);
};

const notifyDisconnected = function() {
return notifyMessage.bind(this)(
'error',
Expand Down Expand Up @@ -332,6 +348,7 @@ export default boot(({ app, store }) => {
app.config.globalProperties.$notifySuccessCopy = notifySuccessCopy.bind(store);
app.config.globalProperties.$notifyFailure = notifyFailure.bind(store);
app.config.globalProperties.$notifyFailureWithAction = notifyFailureWithAction.bind(store);
app.config.globalProperties.$notifyWarningWithAction = notifyWarningWithAction.bind(store);
app.config.globalProperties.$notifyDisconnected = notifyDisconnected.bind(store);
app.config.globalProperties.$notifyNeutralMessage = notifyNeutralMessage.bind(store);
app.config.globalProperties.$notifyRememberInfo = notifyRememberInfo.bind(store);
Expand All @@ -340,6 +357,7 @@ export default boot(({ app, store }) => {
store['$notifySuccessCopy'] = app.config.globalProperties.$notifySuccessCopy;
store['$notifyFailure'] = app.config.globalProperties.$notifyFailure;
store['$notifyFailureWithAction'] = app.config.globalProperties.$notifyFailureWithAction;
store['$notifyWarningWithAction'] = app.config.globalProperties.$notifyWarningWithAction;
store['$notifyDisconnected'] = app.config.globalProperties.$notifyDisconnected;
store['$notifyNeutralMessage'] = app.config.globalProperties.$notifyNeutralMessage;
store['$notifyRememberInfo'] = app.config.globalProperties.$notifyRememberInfo;
Expand Down

0 comments on commit 259baa5

Please sign in to comment.