@broxus/evm-connect 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/cjs/components/EvmConnectButton/index.js +3 -2
  2. package/dist/cjs/components/EvmConnectDialog/index.js +5 -5
  3. package/dist/cjs/components/EvmProvidersDispatcher/ConnectionRequest/index.js +12 -12
  4. package/dist/cjs/components/EvmProvidersDispatcher/index.js +2 -1
  5. package/dist/cjs/context/EvmWalletProvidersContext.d.ts +3 -4
  6. package/dist/cjs/context/EvmWalletProvidersContext.js +17 -16
  7. package/dist/cjs/context/EvmWalletServiceContext.d.ts +2 -1
  8. package/dist/cjs/context/EvmWalletServiceContext.js +4 -2
  9. package/dist/cjs/main.d.ts +1 -0
  10. package/dist/cjs/main.js +3 -0
  11. package/dist/cjs/services/EvmWalletService.d.ts +2 -2
  12. package/dist/cjs/services/EvmWalletService.js +9 -0
  13. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  14. package/dist/cjs/types.d.ts +7 -0
  15. package/dist/esm/components/EvmConnectButton/index.js +4 -3
  16. package/dist/esm/components/EvmConnectDialog/index.js +5 -5
  17. package/dist/esm/components/EvmProvidersDispatcher/ConnectionRequest/index.js +12 -12
  18. package/dist/esm/components/EvmProvidersDispatcher/index.js +3 -2
  19. package/dist/esm/context/EvmWalletProvidersContext.d.ts +3 -4
  20. package/dist/esm/context/EvmWalletProvidersContext.js +17 -16
  21. package/dist/esm/context/EvmWalletServiceContext.d.ts +2 -1
  22. package/dist/esm/context/EvmWalletServiceContext.js +4 -2
  23. package/dist/esm/main.d.ts +1 -0
  24. package/dist/esm/main.js +1 -0
  25. package/dist/esm/services/EvmWalletService.d.ts +2 -2
  26. package/dist/esm/services/EvmWalletService.js +9 -0
  27. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  28. package/dist/esm/types.d.ts +7 -0
  29. package/dist/style.min.css +1 -0
  30. package/package.json +9 -4
@@ -1,5 +1,11 @@
1
+ import { type NetworkConfigBase } from '@broxus/js-core';
1
2
  import { type EIP1193Provider, type MetaMaskProvider, type Web3APISpec, type Web3BaseProvider, type Web3EthExecutionAPI } from 'web3-types';
2
3
  import { type EthereumConnector } from './core';
4
+ type EvmBasedNetwork = 'evm';
5
+ export interface EvmNetworkConfig extends NetworkConfigBase<string> {
6
+ transactionType?: string | string[];
7
+ type: EvmBasedNetwork;
8
+ }
3
9
  export type SupportedProviders<API extends Web3APISpec = Web3EthExecutionAPI> = EIP1193Provider<API> | Web3BaseProvider<API> | MetaMaskProvider<API>;
4
10
  export declare enum ConnectionType {
5
11
  INJECTED = "INJECTED",
@@ -45,3 +51,4 @@ export interface EvmWalletProviderConfig {
45
51
  };
46
52
  isRecent?: boolean;
47
53
  }
54
+ export {};
@@ -2,10 +2,11 @@ import { Button } from '@broxus/react-uikit';
2
2
  import { observer } from 'mobx-react-lite';
3
3
  import * as React from 'react';
4
4
  import { EvmConnectDialog } from '../../components/EvmConnectDialog';
5
- import { EvmWalletProvidersProvider, useEvmWalletService } from '../../context';
5
+ import { EvmWalletProvidersContext, EvmWalletProvidersProvider, useEvmWalletService } from '../../context';
6
6
  export const EvmConnectButton = observer((props) => {
7
7
  const walletService = useEvmWalletService();
8
- const { agreementsNote, children, className, disabled, popupClassName, popupType, shape, size, standalone, type = 'primary', onClose, onConnect, onOpen, } = props;
8
+ const walletProviders = React.useContext(EvmWalletProvidersContext);
9
+ const { children, className, disabled, popupClassName, popupType, shape, size, standalone, type = 'primary', onClose, onConnect, onOpen, } = props;
9
10
  const [isModalShown, setModalVisibility] = React.useState(false);
10
11
  const connect = React.useCallback(async () => {
11
12
  setModalVisibility(false);
@@ -21,6 +22,6 @@ export const EvmConnectButton = observer((props) => {
21
22
  }, [onOpen]);
22
23
  return (React.createElement(React.Fragment, null,
23
24
  React.createElement(Button, { "aria-disabled": walletService.isInitializing || walletService.isConnecting, disabled: disabled === undefined ? walletService.isInitializing || walletService.isConnecting : disabled, className: className, shape: shape, size: size, type: type, onClick: standalone ? connect : open }, children),
24
- !standalone && (React.createElement(EvmWalletProvidersProvider, { agreementsNote: agreementsNote, providers: walletService.providers, onConnected: close },
25
+ !standalone && (React.createElement(EvmWalletProvidersProvider, { agreementsNote: walletProviders?.agreementsNote, onConnect: close },
25
26
  React.createElement(EvmConnectDialog, { className: popupClassName, open: isModalShown, type: popupType, onClose: close })))));
26
27
  });
@@ -10,15 +10,15 @@ import messages from '../../intl';
10
10
  import './index.css';
11
11
  export const EvmConnectDialog = observer(({ className, open, type, onClose }) => {
12
12
  const intl = useIntl();
13
- const { agreementsNote, connectingProvider, reset } = useEvmWalletProviders();
13
+ const walletProviders = useEvmWalletProviders();
14
14
  const onClosed = () => {
15
- reset();
15
+ walletProviders.reset();
16
16
  };
17
17
  const close = () => {
18
18
  onClose?.();
19
19
  };
20
20
  if (type === 'drawer') {
21
- return (React.createElement(Drawer, { className: className, destroyOnClose: true, keyboard: !connectingProvider, maskClosable: !connectingProvider, motion: {
21
+ return (React.createElement(Drawer, { className: className, destroyOnClose: true, keyboard: !walletProviders.connectingProvider, maskClosable: !walletProviders.connectingProvider, motion: {
22
22
  motionLeave: true,
23
23
  removeOnLeave: true,
24
24
  // eslint-disable-next-line sort-keys
@@ -29,8 +29,8 @@ export const EvmConnectDialog = observer(({ className, open, type, onClose }) =>
29
29
  React.createElement(Component, { className: "uk-drawer-title" }, intl.formatMessage(messages.EVM_CONNECT_DISPATCHER_POPUP_TITLE))),
30
30
  React.createElement("div", { className: "uk-drawer-body" },
31
31
  React.createElement(EvmProvidersDispatcher, null)),
32
- React.createElement(Text, { align: "center", className: "uk-drawer-footer uk-margin-top", component: "footer", kind: "meta" }, agreementsNote || intl.formatMessage(messages.EVM_CONNECT_AGREEMENTS_NOTE))));
32
+ React.createElement(Text, { align: "center", className: "uk-drawer-footer uk-margin-top", component: "footer", kind: "meta" }, walletProviders.agreementsNote || intl.formatMessage(messages.EVM_CONNECT_AGREEMENTS_NOTE))));
33
33
  }
34
- return (React.createElement(Modal, { centered: true, className: classNames('evm-connect-modal', className), closeIcon: React.createElement(Close, { kind: "modal", ratio: 0.9, onClick: close }), destroyOnClose: true, footer: (React.createElement(Text, { align: "center", component: "div", kind: "meta" }, agreementsNote || intl.formatMessage(messages.EVM_CONNECT_AGREEMENTS_NOTE))), keyboard: !connectingProvider, maskClosable: !connectingProvider, title: intl.formatMessage(messages.EVM_CONNECT_DISPATCHER_POPUP_TITLE), visible: open, width: 380, onClose: close, onClosed: onClosed },
34
+ return (React.createElement(Modal, { centered: true, className: classNames('evm-connect-modal', className), closeIcon: React.createElement(Close, { kind: "modal", ratio: 0.9, onClick: close }), destroyOnClose: true, footer: (React.createElement(Text, { align: "center", component: "div", kind: "meta" }, walletProviders.agreementsNote || intl.formatMessage(messages.EVM_CONNECT_AGREEMENTS_NOTE))), keyboard: !walletProviders.connectingProvider, maskClosable: !walletProviders.connectingProvider, title: intl.formatMessage(messages.EVM_CONNECT_DISPATCHER_POPUP_TITLE), visible: open, width: 380, onClose: close, onClosed: onClosed },
35
35
  React.createElement(EvmProvidersDispatcher, null)));
36
36
  });
@@ -8,28 +8,28 @@ import messages from '../../../intl';
8
8
  import './index.css';
9
9
  export function ConnectionRequest() {
10
10
  const intl = useIntl();
11
- const { connect, connectingProvider, error, reset } = useEvmWalletProviders();
11
+ const walletProviders = useEvmWalletProviders();
12
12
  const tryAgain = async () => {
13
- if (connectingProvider) {
14
- await connect(connectingProvider);
13
+ if (walletProviders.connectingProvider) {
14
+ await walletProviders.connect(walletProviders.connectingProvider);
15
15
  }
16
16
  };
17
17
  return (React.createElement("div", { className: "evm-connect-connection-request" },
18
- React.createElement(Button, { className: "evm-connect-connection-request-back-button uk-position-top-left", type: "text", onClick: reset },
18
+ React.createElement(Button, { className: "evm-connect-connection-request-back-button uk-position-top-left", type: "text", onClick: walletProviders.reset },
19
19
  React.createElement(Icon, { icon: "arrowLeft", ratio: 0.9 })),
20
20
  React.createElement(Grid, { childWidth: 1, gap: "collapse" },
21
- connectingProvider?.info.icon && (React.createElement(Text, { align: "center", className: classNames('uk-margin-top', {
22
- 'uk-margin-bottom': connectingProvider?.info.description,
23
- 'uk-margin-medium-bottom': !connectingProvider?.info.description,
21
+ walletProviders.connectingProvider?.info.icon && (React.createElement(Text, { align: "center", className: classNames('uk-margin-top', {
22
+ 'uk-margin-bottom': walletProviders.connectingProvider?.info.description,
23
+ 'uk-margin-medium-bottom': !walletProviders.connectingProvider?.info.description,
24
24
  }) },
25
- React.createElement("img", { src: connectingProvider.info.icon, alt: connectingProvider.info.name, height: 60, width: 60 }))),
26
- connectingProvider?.info.description && (React.createElement(Text, { align: "center", className: "uk-margin-medium-bottom", component: "div", kind: "meta" }, connectingProvider.info.description)),
27
- !error ? (React.createElement(Text, { align: "center" },
25
+ React.createElement("img", { src: walletProviders.connectingProvider.info.icon, alt: walletProviders.connectingProvider.info.name, height: 60, width: 60 }))),
26
+ walletProviders.connectingProvider?.info.description && (React.createElement(Text, { align: "center", className: "uk-margin-medium-bottom", component: "div", kind: "meta" }, walletProviders.connectingProvider.info.description)),
27
+ !walletProviders.error ? (React.createElement(Text, { align: "center" },
28
28
  React.createElement("h4", { className: "evm-connect-connection-request-title" }, intl.formatMessage(messages.EVM_CONNECT_DISPATCHER_POPUP_REQUEST_TITLE, {
29
- title: connectingProvider?.info.name ?? 'wallet',
29
+ title: walletProviders.connectingProvider?.info.name ?? 'wallet',
30
30
  })),
31
31
  React.createElement("div", null, intl.formatMessage(messages.EVM_CONNECT_DISPATCHER_POPUP_REQUEST_NOTE)))) : (React.createElement(Text, { align: "center" },
32
32
  React.createElement("h4", { className: "evm-connect-connection-request-title uk-text-danger" }, intl.formatMessage(messages.EVM_CONNECT_DISPATCHER_POPUP_REQUEST_FAILED_TITLE)),
33
- React.createElement("div", { className: "uk-margin-small-bottom" }, error.message ? (React.createElement(Text, { color: "danger" }, error.message)) : intl.formatMessage(messages.EVM_CONNECT_DISPATCHER_POPUP_REQUEST_FAILED_NOTE)),
33
+ React.createElement("div", { className: "uk-margin-small-bottom" }, walletProviders.error.message ? (React.createElement(Text, { color: "danger" }, walletProviders.error.message)) : intl.formatMessage(messages.EVM_CONNECT_DISPATCHER_POPUP_REQUEST_FAILED_NOTE)),
34
34
  React.createElement(Button, { className: "evm-connect-connection-request-button", type: "default", onClick: tryAgain }, intl.formatMessage(messages.EVM_CONNECT_DISPATCHER_POPUP_REQUEST_TRY_AGAIN_BTN_TEXT)))))));
35
35
  }
@@ -3,12 +3,13 @@ import { observer } from 'mobx-react-lite';
3
3
  import * as React from 'react';
4
4
  import { ConnectionRequest } from '../../components/EvmProvidersDispatcher/ConnectionRequest';
5
5
  import { ProviderButton } from '../../components/EvmProvidersDispatcher/ProviderButton';
6
- import { useEvmWalletProviders } from '../../context';
6
+ import { useEvmWalletProviders, useEvmWalletService } from '../../context';
7
7
  import { useOrderedConnections } from '../../hooks';
8
8
  import './index.css';
9
9
  export const EvmProvidersDispatcher = observer(() => {
10
+ const walletService = useEvmWalletService();
10
11
  const walletProviders = useEvmWalletProviders();
11
- const orderedProviders = useOrderedConnections(walletProviders.providers ?? []);
12
+ const orderedProviders = useOrderedConnections(walletService.providers ?? []);
12
13
  const dispatcher = React.useRef(null);
13
14
  const content = React.useRef(null);
14
15
  React.useLayoutEffect(() => {
@@ -1,20 +1,19 @@
1
1
  import * as React from 'react';
2
+ import { type EthereumConnector } from '../core';
2
3
  import { type EvmWalletProviderConfig } from '../types';
3
4
  export interface EvmWalletProvidersContextConsumer {
4
5
  agreementsNote?: React.ReactNode;
5
6
  connect: (providerConfig: EvmWalletProviderConfig) => Promise<void>;
6
7
  connectingProvider?: EvmWalletProviderConfig | null;
7
8
  error?: Error | null;
8
- providers?: Readonly<EvmWalletProviderConfig[]>;
9
9
  reset: VoidFunction;
10
10
  }
11
11
  export declare const EvmWalletProvidersContext: React.Context<EvmWalletProvidersContextConsumer | null>;
12
12
  export declare function useEvmWalletProviders(): EvmWalletProvidersContextConsumer;
13
13
  export type EvmWalletProvidersProviderProps = React.PropsWithChildren<{
14
14
  agreementsNote?: React.ReactNode;
15
- providers?: Readonly<EvmWalletProviderConfig[]>;
16
- onConnected?: VoidFunction;
15
+ onConnect?: (connector?: EthereumConnector) => Promise<void> | void;
17
16
  }>;
18
- export declare const EvmWalletProvidersProvider: ((props: EvmWalletProvidersProviderProps) => React.JSX.Element) & {
17
+ export declare const EvmWalletProvidersProvider: (({ agreementsNote, children, onConnect }: EvmWalletProvidersProviderProps) => React.JSX.Element) & {
19
18
  displayName: string;
20
19
  };
@@ -8,10 +8,9 @@ export const EvmWalletProvidersContext = React.createContext(null);
8
8
  export function useEvmWalletProviders() {
9
9
  return useContext(EvmWalletProvidersContext);
10
10
  }
11
- export const EvmWalletProvidersProvider = observer((props) => {
11
+ export const EvmWalletProvidersProvider = observer(({ agreementsNote, children, onConnect }) => {
12
12
  const walletService = useEvmWalletService();
13
13
  const [recentMeta, setRecentMeta] = useRecentConnectionMeta();
14
- const { agreementsNote, children, providers = walletService.providers } = props;
15
14
  const [error, setError] = React.useState(null);
16
15
  const [connectingProvider, setConnectingProvider] = React.useState(null);
17
16
  const connect = React.useCallback(async (providerConfig) => {
@@ -23,20 +22,23 @@ export const EvmWalletProvidersProvider = observer((props) => {
23
22
  ? walletService.networks.find(network => network.chainId === recentMeta.chainId) ?? 1
24
23
  : 1;
25
24
  debug(`Try to activate ${providerConfig.info.name} connection with chain`, typeof chainParams === 'number' ? chainParams : chainParams.chainId);
26
- await providerConfig.connector?.connect(typeof chainParams === 'number' ? chainParams : {
27
- blockExplorerUrls: [chainParams.explorer.baseUrl],
28
- chainId: Number(chainParams.chainId),
29
- chainName: chainParams.name,
30
- nativeCurrency: {
31
- decimals: 18,
32
- name: chainParams.currency.name,
33
- symbol: chainParams.currency.symbol,
34
- },
35
- rpcUrls: [chainParams.rpcUrl],
36
- });
25
+ await providerConfig.connector?.connect(typeof chainParams === 'number'
26
+ ? chainParams
27
+ : {
28
+ blockExplorerUrls: [chainParams.explorer.baseUrl],
29
+ chainId: Number(chainParams.chainId),
30
+ chainName: chainParams.name,
31
+ nativeCurrency: {
32
+ decimals: 18,
33
+ name: chainParams.currency.name,
34
+ symbol: chainParams.currency.symbol,
35
+ },
36
+ rpcUrls: [chainParams.rpcUrl],
37
+ });
37
38
  if (providerConfig.id !== walletService.providerId) {
38
39
  await prevConnector?.disconnect(true);
39
40
  }
41
+ await onConnect?.(providerConfig.connector);
40
42
  setRecentMeta({
41
43
  chainId: providerConfig.connector.chainId?.toString(),
42
44
  disconnected: false,
@@ -48,7 +50,7 @@ export const EvmWalletProvidersProvider = observer((props) => {
48
50
  catch (e) {
49
51
  setError(e);
50
52
  }
51
- }, [recentMeta, setRecentMeta, walletService]);
53
+ }, [onConnect, recentMeta?.chainId, setRecentMeta, walletService]);
52
54
  const reset = React.useCallback(() => {
53
55
  setError(null);
54
56
  setConnectingProvider(null);
@@ -58,9 +60,8 @@ export const EvmWalletProvidersProvider = observer((props) => {
58
60
  connect,
59
61
  connectingProvider,
60
62
  error,
61
- providers,
62
63
  reset,
63
- }), [agreementsNote, connect, connectingProvider, error, providers, reset]);
64
+ }), [agreementsNote, connect, connectingProvider, error, reset]);
64
65
  return React.createElement(EvmWalletProvidersContext.Provider, { value: context }, children);
65
66
  });
66
67
  if (process.env.NODE_ENV !== 'production') {
@@ -3,8 +3,9 @@ import { EvmWalletService, type EvmWalletServiceCtorParams } from '../services';
3
3
  export declare const EvmWalletServiceContext: React.Context<EvmWalletService | null>;
4
4
  export declare function useEvmWalletService(): EvmWalletService;
5
5
  type EvmWalletProviderProps = React.PropsWithChildren<{
6
+ agreementsNote?: React.ReactNode;
6
7
  params?: EvmWalletServiceCtorParams;
7
8
  wallet?: EvmWalletService;
8
9
  }>;
9
- export declare const EvmWalletServiceProvider: React.MemoExoticComponent<({ children, params, wallet, }: EvmWalletProviderProps) => React.JSX.Element>;
10
+ export declare const EvmWalletServiceProvider: React.MemoExoticComponent<({ agreementsNote, children, params, wallet, }: EvmWalletProviderProps) => React.JSX.Element>;
10
11
  export {};
@@ -1,13 +1,14 @@
1
1
  import { useContext } from '@broxus/react-uikit';
2
2
  import { reaction } from 'mobx';
3
3
  import * as React from 'react';
4
+ import { EvmWalletProvidersProvider } from '../context/EvmWalletProvidersContext';
4
5
  import { getRecentConnectionMeta, useRecentConnectionMeta } from '../hooks';
5
6
  import { EvmWalletService } from '../services';
6
7
  export const EvmWalletServiceContext = React.createContext(null);
7
8
  export function useEvmWalletService() {
8
9
  return useContext(EvmWalletServiceContext);
9
10
  }
10
- export const EvmWalletServiceProvider = React.memo(({ children, params, wallet, }) => {
11
+ export const EvmWalletServiceProvider = React.memo(({ agreementsNote, children, params, wallet, }) => {
11
12
  const [, setRecentMeta] = useRecentConnectionMeta();
12
13
  const context = React.useMemo(() => {
13
14
  if (wallet instanceof EvmWalletService) {
@@ -21,7 +22,8 @@ export const EvmWalletServiceProvider = React.memo(({ children, params, wallet,
21
22
  setRecentMeta({ ...recentMeta, chainId: chainId.toString() });
22
23
  }
23
24
  }, { delay: 10, fireImmediately: context.isReady }), [context, setRecentMeta]);
24
- return React.createElement(EvmWalletServiceContext.Provider, { value: context }, children);
25
+ return (React.createElement(EvmWalletServiceContext.Provider, { value: context },
26
+ React.createElement(EvmWalletProvidersProvider, { agreementsNote: agreementsNote }, children)));
25
27
  });
26
28
  if (process.env.NODE_ENV !== 'production') {
27
29
  EvmWalletServiceContext.displayName = 'EvmWalletServiceContext';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ import './main.scss';
@@ -1,9 +1,8 @@
1
- import { type EvmNetworkConfig } from '@broxus/js-bridge-essentials';
2
1
  import { AbstractStore, type NativeCurrency } from '@broxus/js-core';
3
2
  import { type IReactionDisposer } from 'mobx';
4
3
  import Web3 from 'web3';
5
4
  import { type EthereumConnector } from '../core';
6
- import { type AddEthereumChainParams, type EvmWalletProviderConfig } from '../types';
5
+ import { type AddEthereumChainParams, type EvmNetworkConfig, type EvmWalletProviderConfig, type WatchAssetParameters } from '../types';
7
6
  export interface EvmWalletServiceCtorParams {
8
7
  defaultNetworkId?: number;
9
8
  /**
@@ -43,6 +42,7 @@ export declare class EvmWalletService extends AbstractStore<EvmWalletServiceData
43
42
  * @returns {Promise<void>}
44
43
  */
45
44
  switchNetwork(chainIdOrParams: number | AddEthereumChainParams): Promise<void>;
45
+ watchAsset(params: WatchAssetParameters): Promise<true | undefined>;
46
46
  /**
47
47
  * Define current provider connector
48
48
  * @returns {EthereumConnector|undefined}
@@ -73,6 +73,9 @@ export class EvmWalletService extends AbstractStore {
73
73
  async switchNetwork(chainIdOrParams) {
74
74
  await this.connector?.switchNetwork(chainIdOrParams);
75
75
  }
76
+ async watchAsset(params) {
77
+ return this.connector?.watchAsset(params);
78
+ }
76
79
  /**
77
80
  * Define current provider connector
78
81
  * @returns {EthereumConnector|undefined}
@@ -304,6 +307,12 @@ __decorate([
304
307
  __metadata("design:paramtypes", [Object]),
305
308
  __metadata("design:returntype", Promise)
306
309
  ], EvmWalletService.prototype, "switchNetwork", null);
310
+ __decorate([
311
+ action.bound,
312
+ __metadata("design:type", Function),
313
+ __metadata("design:paramtypes", [Object]),
314
+ __metadata("design:returntype", Promise)
315
+ ], EvmWalletService.prototype, "watchAsset", null);
307
316
  __decorate([
308
317
  computed,
309
318
  __metadata("design:type", Object),