Skip to content

Commit

Permalink
feat(wallet-ui): connect to keplr with smart wallet (#5744)
Browse files Browse the repository at this point in the history
* feat(wallet-ui): connect to keplr with smart wallet

* fix: more robust equality check
  • Loading branch information
samsiegart authored Jul 10, 2022
1 parent abd0946 commit 3482e0d
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 14 deletions.
24 changes: 22 additions & 2 deletions packages/wallet/ui/src/components/ConnectionSettingsDialog.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from 'react';
import { useMemo, useState } from 'react';
import { v4 as uuid } from 'uuid';
import { makeStyles } from '@mui/styles';
import Autocomplete from '@mui/material/Autocomplete';
Expand All @@ -17,6 +17,7 @@ import DialogActions from '@mui/material/DialogActions';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import InputLabel from '@mui/material/InputLabel';
import { deepEquals } from '../util/DeepEquals';

import { withApplicationContext } from '../contexts/Application';
import {
Expand Down Expand Up @@ -106,6 +107,7 @@ const ConnectionSettingsDialog = ({
setConnectionConfig,
allConnectionConfigs,
setAllConnectionConfigs,
tryKeplrConnect,
}) => {
const classes = useStyles();
const smartConnectionHrefs = allConnectionConfigs
Expand Down Expand Up @@ -172,7 +174,23 @@ const ConnectionSettingsDialog = ({
errors.add(Errors.INVALID_ACCESS_TOKEN);
}

const hasChanges = useMemo(
() => !deepEquals(config, connectionConfig),
[config, connectionConfig],
);

const saveAndClose = () => {
if (
!hasChanges &&
config.smartConnectionMethod === SmartConnectionMethod.KEPLR
) {
// Allow the user to force another retry to connect to Keplr without
// reloading the page.
tryKeplrConnect();
onClose();
return;
}

if (config) {
if (config.accessToken) {
maybeSave('accessToken', config.accessToken);
Expand Down Expand Up @@ -365,7 +383,8 @@ const ConnectionSettingsDialog = ({
onClick={saveAndClose}
disabled={
errors.size > 0 ||
JSON.stringify(config) === JSON.stringify(connectionConfig)
(!hasChanges &&
config.smartConnectionMethod !== SmartConnectionMethod.KEPLR)
}
>
{currentTab === Tabs.SMART
Expand All @@ -383,4 +402,5 @@ export default withApplicationContext(ConnectionSettingsDialog, context => ({
setConnectionConfig: context.setConnectionConfig,
allConnectionConfigs: context.allConnectionConfigs,
setAllConnectionConfigs: context.setAllConnectionConfigs,
tryKeplrConnect: context.tryKeplrConnect,
}));
24 changes: 18 additions & 6 deletions packages/wallet/ui/src/components/SmartWalletConnection.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { makeFollower, makeLeader, makeCastingSpec } from '@agoric/casting';

import React, { useEffect, useState } from 'react';
import Snackbar from '@mui/material/Snackbar';
import MuiAlert from '@mui/material/Alert';

import { observeIterator } from '@agoric/notifier';

import { withApplicationContext } from '../contexts/Application';
import {
makeBackendFromWalletBridge,
makeWalletBridgeFromFollower,
} from '../util/WalletBackendAdapter';
import { SmartConnectionMethod } from '../util/connections';

const Alert = React.forwardRef(function Alert({ children, ...props }, ref) {
return (
Expand All @@ -24,6 +24,7 @@ const SmartWalletConnection = ({
setConnectionState,
setBackend,
setBackendErrorHandler,
keplrConnection,
}) => {
const [snackbarMessages, setSnackbarMessages] = useState([]);
setConnectionState('connecting');
Expand All @@ -48,21 +49,31 @@ const SmartWalletConnection = ({
};

useEffect(() => {
if (!connectionConfig) {
if (
!connectionConfig ||
(connectionConfig.smartConnectionMethod === SmartConnectionMethod.KEPLR &&
!keplrConnection)
) {
return undefined;
}

let cancelIterator;
const follow = async () => {
const { url, publicAddress } = connectionConfig;
const { href, smartConnectionMethod } = connectionConfig;
let publicAddress;
if (smartConnectionMethod === SmartConnectionMethod.KEPLR) {
publicAddress = keplrConnection.address;
} else {
publicAddress = connectionConfig.publicAddress;
}

const backendError = e => {
showError('Error in wallet backend', e);
setBackend(null);
setConnectionState('error');
};

const leader = makeLeader(url);
const leader = makeLeader(href);
const follower = makeFollower(
makeCastingSpec(`:published.wallet.${publicAddress}`),
leader,
Expand Down Expand Up @@ -92,7 +103,7 @@ const SmartWalletConnection = ({
cancelIterator && cancelIterator();
cancelIterator = undefined;
};
}, [connectionConfig]);
}, [connectionConfig, keplrConnection]);

return (
<div>
Expand All @@ -114,4 +125,5 @@ export default withApplicationContext(SmartWalletConnection, context => ({
setConnectionState: context.setConnectionState,
setBackend: context.setBackend,
setBackendErrorHandler: context.setBackendErrorHandler,
keplrConnection: context.keplrConnection,
}));
19 changes: 19 additions & 0 deletions packages/wallet/ui/src/contexts/Provider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import { ApplicationContext, ConnectionStatus } from './Application';
import {
ConnectionConfigType,
DEFAULT_CONNECTION_CONFIGS,
SmartConnectionMethod,
} from '../util/connections';
import { maybeLoad, maybeSave } from '../util/storage';
import { suggestChain } from '../util/SuggestChain';

const useDebugLogging = (state, watch) => {
useEffect(() => console.log(state), watch);
Expand Down Expand Up @@ -144,6 +146,15 @@ const Provider = ({ children }) => {
const [connectionStatus, setConnectionStatus] = useState(
wantConnection ? 'connecting' : 'disconnected',
);
const [keplrConnection, setKeplrConnection] = useState(null);

const tryKeplrConnect = async () => {
const [cosmjs, address] = await suggestChain(connectionConfig.href);
setKeplrConnection({
cosmjs,
address,
});
};

useEffect(() => {
if (!connectionComponent) {
Expand Down Expand Up @@ -187,6 +198,12 @@ const Provider = ({ children }) => {
}
}
maybeSave('userConnectionConfigs', updatedConnectionConfigs);

if (
connectionConfig?.smartConnectionMethod === SmartConnectionMethod.KEPLR
) {
tryKeplrConnect();
}
}, [connectionConfig]);

const backendSetters = new Map([
Expand Down Expand Up @@ -366,6 +383,8 @@ const Provider = ({ children }) => {
connectionStatus,
backendErrorHandler,
setBackendErrorHandler,
keplrConnection,
tryKeplrConnect,
};

useDebugLogging(state, [
Expand Down
22 changes: 22 additions & 0 deletions packages/wallet/ui/src/util/DeepEquals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export const deepEquals = (a, b) => {
if (a === b) {
return true;
}
if (a instanceof Date && b instanceof Date) {
return a.getTime() === b.getTime();
}
if (!a || !b || (typeof a !== 'object' && typeof b !== 'object')) {
return a === b;
}
if (a === null || a === undefined || b === null || b === undefined) {
return false;
}
if (a.prototype !== b.prototype) {
return false;
}
const keys = Object.keys(a);
if (keys.length !== Object.keys(b).length) {
return false;
}
return keys.every(k => deepEquals(a[k], b[k]));
};
8 changes: 2 additions & 6 deletions packages/wallet/ui/src/util/SuggestChain.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { SigningStargateClient } from '@cosmjs/stargate';

export const NETWORK_CONFIGS = [
['https://main.agoric.net/network-config', 'Agoric Mainnet'],
['https://testnet.agoric.net/network-config', 'Agoric Testnet'],
];

export const AGORIC_COIN_TYPE = 564;
export const COSMOS_COIN_TYPE = 118;

Expand Down Expand Up @@ -94,6 +89,7 @@ export async function suggestChain(networkConfig, caption = undefined) {
'enjoy!',
);
*/
const accounts = await offlineSigner.getAccounts();

return cosmJS;
return [cosmJS, accounts[0]?.address];
}

0 comments on commit 3482e0d

Please # to comment.