Skip to content

Commit

Permalink
fix: wallet connect reconnect (#2610)
Browse files Browse the repository at this point in the history
  • Loading branch information
Asmadek authored Nov 11, 2024
1 parent 1b29836 commit cfecc26
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 57 deletions.
97 changes: 49 additions & 48 deletions src/renderer/entities/walletConnect/model/wallet-connect-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,51 @@ const $uri = createStore<string>('').reset(disconnectCurrentSessionStarted);
const $accounts = createStore<string[]>([]).reset(reset);
const $pairings = createStore<PairingTypes.Struct[]>([]).reset(reset);

const createClientFx = createEffect(async (): Promise<Client | undefined> => {
return Client.init({
logger: DEFAULT_LOGGER,
relayUrl: DEFAULT_RELAY_URL,
projectId: DEFAULT_PROJECT_ID,
metadata: DEFAULT_APP_METADATA,
});
});

type InitConnectResult = {
uri?: string;
approval: () => Promise<SessionTypes.Struct>;
};
const initConnectFx = createEffect(({ client, chains, pairing }: InitConnectParams): Promise<InitConnectResult> => {
const optionalNamespaces = {
polkadot: {
chains,
methods: [DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_TRANSACTION],
events: [DEFAULT_POLKADOT_EVENTS.CHAIN_CHANGED, DEFAULT_POLKADOT_EVENTS.ACCOUNTS_CHANGED],
},
};

return client.connect({ pairingTopic: pairing?.topic, optionalNamespaces });
});

type ConnectParams = {
client: Client;
approval: () => Promise<unknown>;
onConnect?: () => void;
};
type ConnectResult = {
pairings: PairingTypes.Struct[];
session: SessionTypes.Struct;
};
const connectFx = createEffect(async ({ client, approval }: ConnectParams): Promise<ConnectResult | undefined> => {
const session = await approval();

console.log('Established session:', session);

return {
pairings: client.pairing.getAll({ active: true }),
session: session as SessionTypes.Struct,
};
});

const extendSessionsFx = createEffect((client: Client) => {
const sessions = client.session.getAll();

Expand Down Expand Up @@ -134,15 +179,6 @@ const sessionTopicUpdatedFx = createEffect(
},
);

const createClientFx = createEffect(async (): Promise<Client | undefined> => {
return Client.init({
logger: DEFAULT_LOGGER,
relayUrl: DEFAULT_RELAY_URL,
projectId: DEFAULT_PROJECT_ID,
metadata: DEFAULT_APP_METADATA,
});
});

const removePairingFx = createEffect(async ({ client, topic }: { client: Client; topic: string }): Promise<void> => {
const reason = getSdkError('USER_DISCONNECTED');

Expand Down Expand Up @@ -171,42 +207,6 @@ const updateWcAccountsFx = createEffect(
},
);

type InitConnectResult = {
uri?: string;
approval: () => Promise<SessionTypes.Struct>;
};
const initConnectFx = createEffect(({ client, chains, pairing }: InitConnectParams): Promise<InitConnectResult> => {
const optionalNamespaces = {
polkadot: {
chains,
methods: [DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_TRANSACTION],
events: [DEFAULT_POLKADOT_EVENTS.CHAIN_CHANGED, DEFAULT_POLKADOT_EVENTS.ACCOUNTS_CHANGED],
},
};

return client.connect({ pairingTopic: pairing?.topic, optionalNamespaces });
});

type ConnectParams = {
client: Client;
approval: () => Promise<unknown>;
onConnect?: () => void;
};
type ConnectResult = {
pairings: PairingTypes.Struct[];
session: SessionTypes.Struct;
};
const connectFx = createEffect(async ({ client, approval }: ConnectParams): Promise<ConnectResult | undefined> => {
const session = await approval();

console.log('Established session:', session);

return {
pairings: client.pairing.getAll({ active: true }),
session: session as SessionTypes.Struct,
};
});

type DisconnectParams = {
client: Client;
session: SessionTypes.Struct;
Expand Down Expand Up @@ -348,15 +348,15 @@ sample({
sample({
clock: disconnectCurrentSessionStarted,
source: $session,
filter: (session: SessionTypes.Struct | null): session is SessionTypes.Struct => session !== null,
fn: (session) => session.topic,
filter: (session) => nonNullable(session),
fn: (session) => session!.topic,
target: disconnectStarted,
});

sample({
clock: disconnectStarted,
source: $client,
filter: (client, sessionTopic) => Boolean(client?.session.get(sessionTopic)),
filter: (client, sessionTopic) => nonNullable(client?.session.get(sessionTopic)),
fn: (client, sessionTopic) => ({
client: client!,
session: client!.session.get(sessionTopic)!,
Expand Down Expand Up @@ -461,6 +461,7 @@ export const walletConnectModel = {
connectionRejected,
currentSessionTopicUpdated,
sessionTopicUpdated,
sessionTopicUpdateFailed: sessionTopicUpdatedFx.fail,
sessionTopicUpdateDone: sessionTopicUpdatedFx.doneData,
accountsUpdated,
accountsUpdateDone: updateWcAccountsFx.doneData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const operationSignUtils = {
isReconnectingStep,
isConnectedStep,
isRejectedStep,
isFailedStep,
isReadyToReconnectStep,
isTopicExist,
transformEcdsaSignature,
Expand All @@ -30,6 +31,10 @@ function isReadyToReconnectStep(step: ReconnectStep): boolean {
return step === ReconnectStep.READY_TO_RECONNECT;
}

function isFailedStep(step: ReconnectStep): boolean {
return step === ReconnectStep.FAILED;
}

function isTopicExist(session?: SessionTypes.Struct | null): boolean {
return Boolean(session?.topic);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const enum ReconnectStep {
READY_TO_RECONNECT,
RECONNECTING,
REJECTED,
FAILED,
SUCCESS,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const $isStatusShown = combine(
operationSignUtils.isReconnectingStep(reconnectStep) ||
operationSignUtils.isConnectedStep(reconnectStep) ||
operationSignUtils.isRejectedStep(reconnectStep) ||
operationSignUtils.isFailedStep(reconnectStep) ||
isSigningRejected
);
},
Expand Down Expand Up @@ -95,6 +96,14 @@ sample({
target: walletConnectModel.events.connect,
});

sample({
clock: [walletConnectModel.events.initConnectFailed, walletConnectModel.events.sessionTopicUpdateFailed],
source: $reconnectStep,
filter: (step) => step === ReconnectStep.RECONNECTING,
fn: () => ReconnectStep.FAILED,
target: $reconnectStep,
});

sample({
clock: walletConnectModel.events.connected,
source: {
Expand All @@ -118,7 +127,8 @@ sample({

sample({
clock: combineEvents({
events: [reconnectStarted, walletConnectModel.events.sessionTopicUpdateDone, walletConnectModel.events.connected],
events: [walletConnectModel.events.sessionTopicUpdateDone],
reset: reconnectStarted,
}),
source: {
signer: operationSignModel.$signer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,18 @@ export const WalletConnect = ({ apis, signingPayloads, validateBalance, onGoBack
};
}

if (operationSignUtils.isFailedStep(reconnectStep)) {
return {
title: t('operation.walletConnect.failedTitle'),
description: t('operation.walletConnect.failedDescription'),
content: <Animation variant="error" />,
onClose: () => {
signWcModel.events.reconnectAborted();
onGoBack();
},
};
}

if (isSigningRejected) {
return {
title: t('operation.walletConnect.rejected'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createEvent, createStore, sample } from 'effector';
import { walletConnectModel } from '@/entities/walletConnect';
import { Step } from '../lib/constants';

const $step = createStore(Step.CLOSED).reset([walletConnectModel.events.disconnectCurrentSessionStarted]);
const $step = createStore(Step.CLOSED).reset(walletConnectModel.events.disconnectCurrentSessionStarted);

const onboardingStarted = createEvent();

Expand Down
6 changes: 4 additions & 2 deletions src/renderer/shared/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,8 @@
"title": "{ walletName } is not connected"
},
"rejected": "Rejected",
"failedTitle": "Something went wrong",
"failedDescription": "Please try again later or create a new wallet",
"signTitle_one": "Confirm the operation on your { walletName } app",
"signTitle_other": "Confirm { count } operations on your { walletName } app",
"tryAgainButton": "Try again"
Expand Down Expand Up @@ -1682,8 +1684,8 @@
"refreshButton": "Refresh",
"rejectDescription": "The operation was successfully canceled",
"rejectTitle": "Rejected",
"failedDescription": "Something went wrong",
"failedTitle": "Failed"
"failedDescription": "Please try again later or create a new wallet",
"failedTitle": "Something went wrong"
}
},
"wallets": {
Expand Down
15 changes: 10 additions & 5 deletions src/renderer/widgets/WalletDetails/model/wc-details-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ sample({
wallet: walletSelectModel.$walletForDetails,
session: walletConnectModel.$session,
},
filter: ({ step, wallet, session }) =>
step === ReconnectStep.RECONNECTING && Boolean(wallet) && Boolean(session?.topic),
filter: ({ step, wallet, session }) => {
return step === ReconnectStep.RECONNECTING && Boolean(wallet) && Boolean(session?.topic);
},
fn: ({ wallet, session }) => ({
accounts: wallet!.accounts,
topic: session!.topic,
Expand All @@ -67,7 +68,8 @@ sample({

sample({
clock: combineEvents({
events: [reconnectStarted, walletConnectModel.events.sessionTopicUpdateDone, walletConnectModel.events.connected],
events: [walletConnectModel.events.sessionTopicUpdateDone],
reset: reconnectStarted,
}),
source: {
wallet: walletSelectModel.$walletForDetails,
Expand All @@ -77,10 +79,13 @@ sample({
filter: ({ wallet }) => Boolean(wallet),
fn: ({ wallet, newAccounts, chains }) => {
const updatedAccounts: WcAccount[] = [];
const chainIds = Object.keys(chains);

for (const newAccount of newAccounts) {
const [_, chainId, address] = newAccount.split(':');
const chain = chains[chainId as ChainId];

const fullChainId = chainIds.find((chain) => chain.includes(chainId));
const chain = fullChainId && chains[fullChainId as ChainId];

if (!chain) continue;

Expand All @@ -106,7 +111,7 @@ sample({
});

sample({
clock: walletConnectModel.events.initConnectFailed,
clock: [walletConnectModel.events.initConnectFailed, walletConnectModel.events.sessionTopicUpdateFailed],
source: $reconnectStep,
filter: (step) => step === ReconnectStep.RECONNECTING,
fn: () => ReconnectStep.FAILED,
Expand Down

0 comments on commit cfecc26

Please sign in to comment.