add vega wallet manager component and re add current single pubkey to provider state

This commit is contained in:
Matthew Russell 2022-02-23 16:03:59 -08:00
parent 84af6177ad
commit e92e708cf1
3 changed files with 60 additions and 73 deletions

View File

@ -6,11 +6,7 @@ import { Connectors, rest } from '../lib/connectors';
import { LocalStorage } from '@vegaprotocol/storage';
export function Index() {
// Get keys from vega wallet immediately
useEagerConnect();
const { publicKeys } = useVegaWallet();
const { publicKey, onSelect } = useCurrentVegaKey();
const { keypair, keypairs, selectPublicKey } = useVegaWallet();
return (
<div className="m-24 ">
@ -28,14 +24,17 @@ export function Index() {
</div>
</Callout>
<h1>Vega wallet</h1>
{publicKey && <p>Current: {publicKey.pub}</p>}
{publicKeys?.length && (
{keypair && <p>Current: {keypair.pub}</p>}
{keypairs?.length && (
<select
name="change-key"
value={publicKey?.pub}
onChange={(e) => onSelect(e.target.value)}
defaultValue="none"
onChange={(e) => selectPublicKey(e.target.value)}
>
{publicKeys.map((pk) => (
<option value="none" disabled={true}>
Please select
</option>
{keypairs.map((pk) => (
<option key={pk.pub} value={pk.pub}>
{pk.name} ({pk.pub})
</option>
@ -44,64 +43,9 @@ export function Index() {
)}
<hr />
<h2>Public keys</h2>
<pre>{JSON.stringify(publicKeys, null, 2)}</pre>
<pre>{JSON.stringify(keypairs, null, 2)}</pre>
</div>
);
}
export default Index;
function useEagerConnect() {
const { connect } = useVegaWallet();
useEffect(() => {
const cfg = LocalStorage.getItem('vega_wallet');
const cfgObj = JSON.parse(cfg);
// No stored config, user has never connected or manually cleared storage
if (!cfgObj || !cfgObj.connector) {
return;
}
const connector = Connectors[cfgObj.connector];
// Developer hasn't provided this connector
if (!connector) {
throw new Error(`Connector ${cfgObj?.connector} not configured`);
}
connect(Connectors[cfgObj.connector]);
}, [connect]);
}
function useCurrentVegaKey(): {
publicKey: VegaKeyExtended | null;
onSelect: (pk: string) => void;
} {
const { publicKeys } = useVegaWallet();
const [pk, setPk] = useState<string | null>(() =>
LocalStorage.getItem('vega_selected_publickey')
);
const publicKey = useMemo(() => {
if (!publicKeys?.length) return null;
const found = publicKeys.find((x) => x.pub === pk);
if (found) {
return found;
}
return null;
}, [pk, publicKeys]);
// on public key change set to localStorage
useEffect(() => {
LocalStorage.setItem('vega_selected_publickey', pk);
}, [pk]);
return {
publicKey,
onSelect: setPk,
};
}

View File

@ -7,8 +7,11 @@ export interface VegaKeyExtended extends VegaKey {
}
export interface VegaWalletContextShape {
/** The current select public key */
keypair: VegaKeyExtended | null;
/** Public keys stored in users wallet */
publicKeys: VegaKeyExtended[] | null;
keypairs: VegaKeyExtended[] | null;
/** Calls connect on the supplied connector, storing the returned keys */
connect: (connector: VegaConnector) => Promise<void>;
@ -16,6 +19,9 @@ export interface VegaWalletContextShape {
/** 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,4 +1,12 @@
import { ReactNode, useCallback, useMemo, useRef, useState } from 'react';
import { LocalStorage } from '@vegaprotocol/storage';
import {
ReactNode,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { VegaKeyExtended, VegaWalletContextShape } from '.';
import { VegaConnector } from './connectors';
import { VegaWalletContext } from './context';
@ -8,7 +16,16 @@ interface VegaWalletProviderProps {
}
export const VegaWalletProvider = ({ children }: VegaWalletProviderProps) => {
const [publicKeys, setPublicKeys] = useState<VegaKeyExtended[] | null>(null);
// Current selected publicKey, default with value from local storage
const [publicKey, setPublicKey] = useState<string | null>(() => {
const pk = LocalStorage.getItem('vega_selected_publickey');
return pk ? pk : null;
});
// Keypair objects retrieved from the connector
const [keypairs, setKeypairs] = useState<VegaKeyExtended[] | null>(null);
// Reference to the current connector instance
const connector = useRef<VegaConnector | null>(null);
const connect = useCallback(async (c: VegaConnector) => {
@ -28,7 +45,7 @@ export const VegaWalletProvider = ({ children }: VegaWalletProviderProps) => {
name: nameMeta?.value ? nameMeta.value : 'None',
};
});
setPublicKeys(publicKeysWithName);
setKeypairs(publicKeysWithName);
} catch (err) {
console.error(err);
}
@ -37,21 +54,41 @@ export const VegaWalletProvider = ({ children }: VegaWalletProviderProps) => {
const disconnect = useCallback(async () => {
try {
await connector.current?.disconnect();
setPublicKeys(null);
setKeypairs(null);
connector.current = null;
} catch (err) {
console.error(err);
}
}, []);
// Current selected keypair derived from publicKey state
const keypair = useMemo(() => {
const found = keypairs?.find((x) => x.pub === publicKey);
if (found) {
return found;
}
return null;
}, [publicKey, keypairs]);
// Whenever selected public key changes store it
useEffect(() => {
if (publicKey) {
LocalStorage.setItem('vega_selected_publickey', publicKey);
}
}, [publicKey]);
const contextValue = useMemo<VegaWalletContextShape>(() => {
return {
publicKeys,
keypair,
keypairs,
selectPublicKey: setPublicKey,
connect,
disconnect,
connector: connector.current,
};
}, [publicKeys, connect, disconnect, connector]);
}, [keypair, keypairs, setPublicKey, connect, disconnect, connector]);
return (
<VegaWalletContext.Provider value={contextValue}>