add current key selector, fix revoke token/disconnect

This commit is contained in:
Matthew Russell 2022-02-22 21:05:39 -08:00
parent fba3101753
commit 59d0beebe2
8 changed files with 95 additions and 58 deletions

View File

@ -1,7 +1,7 @@
import { Callout, Button } from '@vegaprotocol/ui-toolkit';
export function Index() {
const vegaWallet = useVegaWallet();
const { publicKey, publicKeys, selectPublicKey } = useVegaWallet();
return (
<div className="m-24 ">
<Callout
@ -17,7 +17,23 @@ export function Index() {
</Button>
</div>
</Callout>
<pre>{JSON.stringify(vegaWallet, null, 2)}</pre>
<h1>Vega wallet</h1>
{publicKey && <p>Current: {publicKey.pub}</p>}
{publicKeys?.length && (
<select
name="change-key"
value={publicKey?.pub}
onChange={(e) => selectPublicKey(e.target.value)}
>
{publicKeys.map((pk) => (
<option key={pk.pub} value={pk.pub}>
{pk.name} ({pk.pub})
</option>
))}
</select>
)}
<h2>Public keys</h2>
<pre>{JSON.stringify(publicKeys, null, 2)}</pre>
</div>
);
}

View File

@ -42,7 +42,6 @@ export function VegaConnectDialog({
{selectedConnector instanceof RestConnector ? (
<RestConnectorForm
connector={selectedConnector}
setDialogOpen={setDialogOpen}
onAuthenticate={() => {
connectAndClose(selectedConnector);
}}
@ -57,19 +56,7 @@ export function VegaConnectDialog({
}}
>
{Object.entries(connectors).map(([key, connector]) => (
<button
key={key}
onClick={() => {
setSelectedConnector(connector);
// if (key === 'rest') {
// // show form so that we can get an authentication token before 'connecting'
// setIsRestConnector(true);
// } else {
// connect(connector);
// setDialogOpen(false);
// }
}}
>
<button key={key} onClick={() => setSelectedConnector(connector)}>
{key} provider
</button>
))}

View File

@ -20,27 +20,6 @@ export class RestConnector implements VegaConnector {
authMethods: {
bearer: `Bearer ${LocalStorage.getItem('vega_wallet_token')}`,
},
promiseMiddleware: [
{
pre: async (requestContext) => {
const headers = requestContext.getHeaders();
if (
'Authorization' in headers &&
headers['Authorization'] === 'Bearer null'
) {
console.log('first login: getting and setting auth header');
requestContext.setHeaderParam(
'Authorization',
`Bearer ${LocalStorage.getItem('vega_wallet_token')}`
);
}
return requestContext;
},
post: async (requestContext) => {
return requestContext;
},
},
],
});
this.service = new DefaultApi(this.apiConfig);
}
@ -57,12 +36,28 @@ export class RestConnector implements VegaConnector {
}
async connect() {
const res = await this.service.keysGet();
const res = await this.service.keysGet(
// Needs token passed in in case its the users first session and there was no
// token stored
createConfiguration({
authMethods: {
bearer: `Bearer ${LocalStorage.getItem('vega_wallet_token')}`,
},
})
);
return res.keys;
}
async disconnect() {
await this.service.authTokenDelete();
await this.service.authTokenDelete(
// Needs token passed in in case its the users first session and there was no
// token stored
createConfiguration({
authMethods: {
bearer: `Bearer ${LocalStorage.getItem('vega_wallet_token')}`,
},
})
);
LocalStorage.removeItem('vega_wallet_token');
}
}

View File

@ -2,11 +2,27 @@ import { VegaKey } from '@vegaprotocol/vegawallet-service-api-client';
import { createContext } from 'react';
import { VegaConnector } from './connectors';
interface VegaWalletContextShape {
publicKey: VegaKey | null;
publicKeys: VegaKey[] | null;
export interface VegaKeyExtended extends VegaKey {
name: string;
}
export interface VegaWalletContextShape {
/** The current select public key */
publicKey: VegaKeyExtended | null;
/** Public keys stored in users wallet */
publicKeys: VegaKeyExtended[] | null;
/** Calls connect on the supplied connector, storing the returned keys */
connect: (connector: VegaConnector) => Promise<void>;
/** Disconnects from the connector and clears public key state */
disconnect: () => Promise<void>;
/** Sets the current selected public key */
selectPublicKey: (publicKey: string) => void;
/** Reference to the connector */
connector: VegaConnector | null;
}

View File

@ -1,5 +1,5 @@
import { VegaKey } from '@vegaprotocol/vegawallet-service-api-client';
import { ReactNode, useCallback, useMemo, useRef, useState } from 'react';
import { VegaKeyExtended, VegaWalletContextShape } from '.';
import { VegaConnector } from './connectors';
import { VegaWalletContext } from './context';
@ -8,16 +8,23 @@ interface VegaWalletProviderProps {
}
export const VegaWalletProvider = ({ children }: VegaWalletProviderProps) => {
const [publicKey, setPublicKey] = useState<VegaKey | null>(null);
const [publicKeys, setPublicKeys] = useState<VegaKey[] | null>(null);
const [publicKey, setPublicKey] = useState<VegaKeyExtended | null>(null);
const [publicKeys, setPublicKeys] = useState<VegaKeyExtended[] | null>(null);
const connector = useRef<VegaConnector | null>(null);
const connect = useCallback(async (c: VegaConnector) => {
connector.current = c;
try {
const res = await c.connect();
setPublicKeys(res);
setPublicKey(res[0]);
const res = await connector.current.connect();
const publicKeysWithName = res.map((pk) => {
const nameMeta = pk.meta?.find((m) => m.key === 'name');
return {
...pk,
name: nameMeta?.value ? nameMeta.value : 'None',
};
});
setPublicKeys(publicKeysWithName);
setPublicKey(publicKeysWithName[0]);
} catch (err) {
console.log('connect failed');
}
@ -34,15 +41,33 @@ export const VegaWalletProvider = ({ children }: VegaWalletProviderProps) => {
}
}, []);
const contextValue = useMemo(() => {
const selectPublicKey = useCallback(
(key: string) => {
if (!publicKeys || !publicKeys.length) {
return;
}
const selectedKey = publicKeys.find((k) => k.pub === key);
if (!selectedKey) {
throw new Error('Public key doesnt exist');
}
setPublicKey(selectedKey);
},
[publicKeys]
);
const contextValue = useMemo<VegaWalletContextShape>(() => {
return {
publicKey,
publicKeys,
selectPublicKey,
connect,
disconnect,
connector: connector.current,
};
}, [publicKey, publicKeys, connect, disconnect, connector]);
}, [publicKey, publicKeys, selectPublicKey, connect, disconnect, connector]);
return (
<VegaWalletContext.Provider value={contextValue}>

View File

@ -8,13 +8,11 @@ interface FormFields {
interface RestConnectorFormProps {
connector: RestConnector;
setDialogOpen: (isOpen: boolean) => void;
onAuthenticate: () => void;
}
export function RestConnectorForm({
connector,
setDialogOpen,
onAuthenticate,
}: RestConnectorFormProps) {
const {
@ -41,7 +39,7 @@ export function RestConnectorForm({
}
return (
<form onSubmit={handleSubmit(onSubmit)} className="vega-wallet-form">
<form onSubmit={handleSubmit(onSubmit)}>
<div style={{ marginBottom: 10 }}>
<input
{...register('wallet', { required: 'Required' })}

View File

@ -24,7 +24,7 @@
"autoprefixer": "^10.4.2",
"classnames": "^2.3.1",
"@radix-ui/react-dialog": "^0.1.5",
"@vegaprotocol/vegawallet-service-api-client": "^0.3.0",
"@vegaprotocol/vegawallet-service-api-client": "^0.4.1",
"core-js": "^3.6.5",
"env-cmd": "^10.1.0",
"graphql": "^15.7.2",

View File

@ -5221,10 +5221,10 @@
"@typescript-eslint/types" "5.10.2"
eslint-visitor-keys "^3.0.0"
"@vegaprotocol/vegawallet-service-api-client@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@vegaprotocol/vegawallet-service-api-client/-/vegawallet-service-api-client-0.3.0.tgz#93ef25f94a2fb3280928053eceed945d00bb0a3a"
integrity sha512-JQHdKI/B6hvnqdXQpWi+zsU2tiJJzkNaZE/aOFFbrdl9gUooF94piDzc5PPBx3YO4NA7mWKwaf4VqRckzjVKXw==
"@vegaprotocol/vegawallet-service-api-client@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@vegaprotocol/vegawallet-service-api-client/-/vegawallet-service-api-client-0.4.1.tgz#182a15ad49652d33a6db2eb55fa934bc71855cc4"
integrity sha512-c8TtLZTcGg2wQs30hyyTGNMH02cg8KcLymegWVxSQ9Id3M4SrdUVOlPoaGpKxjmUVUtQLoY/0+wtAJQVZBErmw==
dependencies:
es6-promise "^4.2.4"
url-parse "^1.4.3"