Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:add dapp-connected-management #1509

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/components/src/Icon/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ import CollectionOutline from './react/outline/Collection';
import ColorSwatchOutline from './react/outline/ColorSwatch';
import CompassOutline from './react/outline/Compass';
import ConnectOutline from './react/outline/Connect';
import ConnectOffOutline from './react/outline/ConnectOff';
import CreditCardOutline from './react/outline/CreditCard';
import CubeOutline from './react/outline/Cube';
import CubeTransparentOutline from './react/outline/CubeTransparent';
Expand Down Expand Up @@ -613,6 +614,7 @@ export type ICON_NAMES =
| 'ColorSwatchOutline'
| 'CompassOutline'
| 'ConnectOutline'
| 'ConnectOffOutline'
| 'CreditCardOutline'
| 'CubeOutline'
| 'CubeTransparentOutline'
Expand Down Expand Up @@ -1139,6 +1141,7 @@ export default {
ColorSwatchOutline,
CompassOutline,
ConnectOutline,
ConnectOffOutline,
CreditCardOutline,
CubeOutline,
CubeTransparentOutline,
Expand Down
22 changes: 22 additions & 0 deletions packages/components/src/Icon/react/illus/WalletconnectLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react';
import Svg, { SvgProps, G, Path, Defs, ClipPath } from 'react-native-svg';

function SvgWalletconnectLogo(props: SvgProps) {
return (
<Svg viewBox="0 0 20 20" fill="none" {...props}>
<G clipPath="url(#walletconnect-logo_svg__clip0_1296_23279)">
<Path
d="M4.097 6.395c3.262-3.193 8.55-3.193 11.811 0l.393.384a.403.403 0 010 .579l-1.343 1.314a.212.212 0 01-.295 0l-.54-.529c-2.276-2.227-5.965-2.227-8.24 0l-.579.567a.212.212 0 01-.295 0L3.666 7.395a.403.403 0 010-.578l.431-.422zm14.588 2.719l1.195 1.17a.403.403 0 010 .578l-5.388 5.276a.424.424 0 01-.591 0l-3.825-3.744a.106.106 0 00-.147 0l-3.825 3.744a.424.424 0 01-.59 0l-5.39-5.276a.403.403 0 010-.578l1.196-1.17a.424.424 0 01.59 0l3.825 3.744c.04.04.107.04.148 0l3.824-3.744a.424.424 0 01.59 0l3.825 3.744c.041.04.107.04.148 0l3.825-3.744a.424.424 0 01.59 0z"
fill="#3B99FC"
/>
</G>
<Defs>
<ClipPath id="walletconnect-logo_svg__clip0_1296_23279">
<Path fill="#fff" d="M0 0h20v20H0z" />
</ClipPath>
</Defs>
</Svg>
);
}

export default SvgWalletconnectLogo;
3 changes: 2 additions & 1 deletion packages/components/src/Icon/react/illus/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ export { default as NftPeg } from './NftPeg'
export { default as StarBadge } from './StarBadge'
export { default as TxStatusFailureCircle } from './TxStatusFailureCircle'
export { default as TxStatusSuccessCircle } from './TxStatusSuccessCircle'
export { default as TxStatusWarningCircle } from './TxStatusWarningCircle'
export { default as TxStatusWarningCircle } from './TxStatusWarningCircle'
export { default as WalletconnectLogo } from './WalletconnectLogo'
loatheb marked this conversation as resolved.
Show resolved Hide resolved
17 changes: 17 additions & 0 deletions packages/components/src/Icon/react/outline/ConnectOff.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as React from 'react';
import Svg, { SvgProps, Path } from 'react-native-svg';

function SvgConnectOff(props: SvgProps) {
return (
<Svg viewBox="0 0 24 24" fill="none" {...props}>
<Path
d="M10 16H7a4 4 0 01-1.5-7.71M15 12h-1M3 5l15 15M14 8h3a4 4 0 011.938 7.5"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
/>
</Svg>
);
}

export default SvgConnectOff;
1 change: 1 addition & 0 deletions packages/components/src/Icon/react/outline/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export { default as Cog } from './Cog'
export { default as Collection } from './Collection'
export { default as ColorSwatch } from './ColorSwatch'
export { default as Compass } from './Compass'
export { default as ConnectOff } from './ConnectOff'
export { default as Connect } from './Connect'
export { default as CreditCard } from './CreditCard'
export { default as CubeTransparent } from './CubeTransparent'
Expand Down
11 changes: 11 additions & 0 deletions packages/components/svg/illus/walletconnect-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions packages/components/svg/outline/connect-off.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ class ProviderApiWalletConnect extends WalletConnectClientForWallet {
({ connector }: IWalletConnectClientEventDestroy) => {
if (connector) {
this.removeConnectedAccounts(connector);
// passively disconnects the walletConnect, does not perform connector.killsession() in _destroyConnector,so here close session
this.backgroundApi.serviceDapp.closeWalletConnectedSession(
connector.session,
);
}
},
);
Expand Down
42 changes: 42 additions & 0 deletions packages/kit/src/background/services/ServiceDapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import { SendRoutes } from '@onekeyhq/kit/src/views/Send/types';
import platformEnv from '@onekeyhq/shared/src/platformEnv';

import { ModalRoutes, RootRoutes } from '../../routes/routesEnum';
import {
closeWalletConnectSession,
updateWalletConnectSession,
} from '../../store/reducers/walletConnectSession';
import { backgroundClass, backgroundMethod } from '../decorators';
import { IDappSourceInfo } from '../IBackgroundApi';
import {
Expand All @@ -32,6 +36,8 @@ import {

import ServiceBase from './ServiceBase';

import type { IWalletConnectSession } from '@walletconnect/types';

type CommonRequestParams = {
request: IJsBridgeMessagePayload;
};
Expand Down Expand Up @@ -82,6 +88,42 @@ class ServiceDapp extends ServiceBase {
this.backgroundApi.dispatch(dappRemoveSiteConnections(payload));
}

@backgroundMethod()
updateWalletConnectedSession(session: IWalletConnectSession) {
this.backgroundApi.dispatch(updateWalletConnectSession(session));
}

@backgroundMethod()
closeWalletConnectedSession(session: IWalletConnectSession | null) {
this.backgroundApi.dispatch(closeWalletConnectSession(session));
}

@backgroundMethod()
async cancellConnectedSite(payload: DappSiteConnection): Promise<void> {
// check walletConnect
if (
this.backgroundApi.walletConnect.connector &&
this.backgroundApi.walletConnect.connector.peerMeta?.url ===
payload.site.origin
) {
this.backgroundApi.walletConnect.disconnect();
} else {
this.removeConnectedAccounts({
ezailWang marked this conversation as resolved.
Show resolved Hide resolved
origin: payload.site.origin,
networkImpl: payload.networkImpl,
addresses: [payload.address],
});
}
await this.backgroundApi.serviceAccount.notifyAccountsChanged();
}

@backgroundMethod()
manuallyAddInpageCannected(request: CommonRequestParams['request']) {
ezailWang marked this conversation as resolved.
Show resolved Hide resolved
if (request.origin) {
this.openConnectionModal(request);
}
}

// TODO to decorator @permissionRequired()
authorizedRequired(request: IJsBridgeMessagePayload) {
if (!this.isDappAuthorized(request)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import * as cryptoLib from '@walletconnect/iso-crypto';
import SocketTransport from '@walletconnect/socket-transport';
import { toLower } from 'lodash';

import backgroundApiProxy from '../../background/instance/backgroundApiProxy';
import {
closeWalletConnectSession,
updateWalletConnectSession,
} from '../../store/reducers/walletConnectSession';

import {
WALLET_CONNECT_BRIDGE,
WALLET_CONNECT_PROTOCOL,
Expand All @@ -15,7 +21,10 @@ import {

import type { WalletConnectSessionStorage } from './WalletConnectSessionStorage';
import type {
ICreateSessionOptions,
IPushServerOptions,
ISessionError,
ISessionStatus,
IWalletConnectOptions,
} from '@walletconnect/types';

Expand Down Expand Up @@ -112,6 +121,30 @@ export class OneKeyWalletConnector extends Connector {
}
}

override async createSession(
opts?: ICreateSessionOptions | undefined,
): Promise<void> {
await super.createSession(opts);
backgroundApiProxy.serviceDapp.updateWalletConnectedSession(this.session);
ezailWang marked this conversation as resolved.
Show resolved Hide resolved
}

override approveSession(sessionStatus: ISessionStatus): void {
super.approveSession(sessionStatus);
backgroundApiProxy.serviceDapp.updateWalletConnectedSession(this.session);
}

override updateSession(sessionStatus: ISessionStatus): void {
super.updateSession(sessionStatus);
backgroundApiProxy.serviceDapp.updateWalletConnectedSession(this.session);
}

override async killSession(
sessionError?: ISessionError | undefined,
): Promise<void> {
await super.killSession(sessionError);
backgroundApiProxy.serviceDapp.closeWalletConnectedSession(this.session);
}

once(event: string, listener: (...args: any[]) => void) {
let executed = false;
const listenerOnce = (...args: any[]) => {
Expand Down
40 changes: 40 additions & 0 deletions packages/kit/src/routes/Modal/ManageConnectSites.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';

import { useIsVerticalLayout } from '@onekeyhq/components';
import ConnectedSites from '@onekeyhq/kit/src/views/ManageConnectedSites/ConnectedSites';
import {
ManageConnectedSitesRoutes,
ManageConnectedSitesRoutesParams,
} from '@onekeyhq/kit/src/views/ManageConnectedSites/types';

import createStackNavigator from './createStackNavigator';

const ManageConnectedSitesNavigator =
createStackNavigator<ManageConnectedSitesRoutesParams>();
const modelRoutes = [
{
name: ManageConnectedSitesRoutes.ManageConnectedSitesModel,
component: ConnectedSites,
},
];

const ManageConnectedSitesModalStack = () => {
const isVerticalLayout = useIsVerticalLayout();
return (
<ManageConnectedSitesNavigator.Navigator
screenOptions={{
headerShown: false,
animationEnabled: !!isVerticalLayout,
}}
>
{modelRoutes.map((route) => (
<ManageConnectedSitesNavigator.Screen
key={route.name}
name={route.name}
component={route.component}
/>
))}
</ManageConnectedSitesNavigator.Navigator>
);
};
export default ManageConnectedSitesModalStack;
5 changes: 5 additions & 0 deletions packages/kit/src/routes/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import HardwareOnekeyResetModal from './HardwareOnekeyLiteReset';
import HardwareUpdateModal from './HardwareUpdate';
import HistoryRequestModal from './HistoryRequest';
import ImportBackupPassword from './ImportBackupPassword';
import ManageConnectedSitesModal from './ManageConnectSites';
import ManageNetworkModal from './ManageNetwork';
import { ManagerAccountModalStack as ManagerAccountModal } from './ManagerAccount';
import { ManagerWalletModalStack as ManagerWalletModal } from './ManagerWallet';
Expand Down Expand Up @@ -153,6 +154,10 @@ const modalStackScreenList = [
name: ModalRoutes.Staking,
component: StakingModal,
},
{
name: ModalRoutes.ManageConnectedSites,
component: ManageConnectedSitesModal,
},
];

const ModalStack = createStackNavigator<ModalRoutesParams>();
Expand Down
1 change: 1 addition & 0 deletions packages/kit/src/routes/Modal/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ export type { FiatPayModalRoutesParams } from './FiatPay';
export type { AddressBookRoutesParams } from '../../views/AddressBook/routes';
export type { ImportBackupPasswordRoutesParams } from './ImportBackupPassword';
export type { StakingRoutesParams } from '../../views/Staking/typing';
export type { ManageConnectedSitesRoutesParams } from '../../views/ManageConnectedSites/types';
1 change: 1 addition & 0 deletions packages/kit/src/routes/routesEnum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export enum ModalRoutes {
ManagerWallet = 'ManagerWallet',
ManagerAccount = 'ManagerAccount',
WalletViewMnemonics = 'WalletViewMnemonics',
ManageConnectedSites = 'ManageConnectedSites',
// Found screens with the same name nested inside one another. Check:
// modal > Send, modal > Send > Send
Send = 'Send',
Expand Down
1 change: 1 addition & 0 deletions packages/kit/src/routes/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export type ModalRoutesParams = {
[ModalRoutes.AddressBook]: NavigatorScreenParams<SubModalRoutesParams.AddressBookRoutesParams>;
[ModalRoutes.ImportBackupPassword]: NavigatorScreenParams<SubModalRoutesParams.ImportBackupPasswordRoutesParams>;
[ModalRoutes.Staking]: NavigatorScreenParams<SubModalRoutesParams.StakingRoutesParams>;
[ModalRoutes.ManageConnectedSites]: NavigatorScreenParams<SubModalRoutesParams.ManageConnectedSitesRoutesParams>;
};
/** Modal */

Expand Down
2 changes: 2 additions & 0 deletions packages/kit/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import statusReducer from './reducers/status';
import swapReducer from './reducers/swap';
import swapTransactionsReducer from './reducers/swapTransactions';
import tokensReducer from './reducers/tokens';
import walletConnectSessionReducer from './reducers/walletConnectSession';

const allReducers = combineReducers({
autoUpdate: autoUpdateReducer,
Expand All @@ -68,6 +69,7 @@ const allReducers = combineReducers({
accountSelector: reducerAccountSelector.reducer,
staking: stakingReducer,
nft: nftReducer,
walletConnectSession: walletConnectSessionReducer,
});

function rootReducer(reducers: Reducer, initialState = {}): any {
Expand Down
36 changes: 36 additions & 0 deletions packages/kit/src/store/reducers/walletConnectSession.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { PayloadAction, createSlice } from '@reduxjs/toolkit';

import type { IWalletConnectSession } from '@walletconnect/types';

export type Session = {
session: IWalletConnectSession | null;
};

const initialState: Session = {
session: null,
};

export const sessionSlice = createSlice({
name: 'connectSession',
initialState,
reducers: {
updateWalletConnectSession(
state,
action: PayloadAction<IWalletConnectSession>,
) {
state.session = { ...action.payload };
},
closeWalletConnectSession(
state,
action: PayloadAction<IWalletConnectSession | null>,
) {
if (!action.payload || !action.payload.connected) {
state.session = null;
}
},
},
});

export const { updateWalletConnectSession, closeWalletConnectSession } =
sessionSlice.actions;
export default sessionSlice.reducer;
Loading