Feat/hosted wallet (#668)
* feat: add ability to set custom wallet URL * fix: wallet state not adequately cleared on disconnect * chore: don't bother to set a prop only to overwrite it * fix: use correct URL for error message * chore: remove autofocus as per comment * chore: correct url
This commit is contained in:
parent
0473412487
commit
8e276d9933
@ -92,7 +92,40 @@ it('Successful connection using rest auth form', async () => {
|
||||
fireEvent.submit(screen.getByTestId('rest-connector-form'));
|
||||
});
|
||||
|
||||
expect(spy).toHaveBeenCalledWith(fields);
|
||||
expect(spy).toHaveBeenCalledWith('http://localhost:1789/api/v1', fields);
|
||||
|
||||
expect(defaultProps.setDialogOpen).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it('Successful connection using custom url', async () => {
|
||||
const spy = jest
|
||||
.spyOn(defaultProps.connectors['rest'] as RestConnector, 'authenticate')
|
||||
.mockImplementation(() => Promise.resolve({ success: true, error: null }));
|
||||
|
||||
render(generateJSX({ dialogOpen: true }));
|
||||
// Switches to rest form
|
||||
fireEvent.click(screen.getByText('rest provider'));
|
||||
|
||||
// Client side validation
|
||||
fireEvent.submit(screen.getByTestId('rest-connector-form'));
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
await waitFor(() => {
|
||||
expect(screen.getAllByText('Required')).toHaveLength(2);
|
||||
});
|
||||
|
||||
// Set custom URL
|
||||
fireEvent.change(screen.getByLabelText('Url'), {
|
||||
target: { value: 'localhost:1234' },
|
||||
});
|
||||
|
||||
const fields = fillInForm();
|
||||
|
||||
// Wait for auth method to be called
|
||||
await act(async () => {
|
||||
fireEvent.submit(screen.getByTestId('rest-connector-form'));
|
||||
});
|
||||
|
||||
expect(spy).toHaveBeenCalledWith('localhost:1234', fields);
|
||||
|
||||
expect(defaultProps.setDialogOpen).toHaveBeenCalledWith(false);
|
||||
});
|
||||
@ -117,7 +150,7 @@ it('Unsuccessful connection using rest auth form', async () => {
|
||||
fireEvent.submit(screen.getByTestId('rest-connector-form'));
|
||||
});
|
||||
|
||||
expect(spy).toHaveBeenCalledWith(fields);
|
||||
expect(spy).toHaveBeenCalledWith('http://localhost:1789/api/v1', fields);
|
||||
|
||||
expect(screen.getByTestId('form-error')).toHaveTextContent(
|
||||
'Something went wrong'
|
||||
@ -135,7 +168,7 @@ it('Unsuccessful connection using rest auth form', async () => {
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('form-error')).toHaveTextContent(
|
||||
'Wallet not running at http://localhost:1789'
|
||||
'Wallet not running at http://localhost:1789/api/v1'
|
||||
);
|
||||
|
||||
// Reject eg non 200 results
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { Configuration } from '@vegaprotocol/vegawallet-service-api-client';
|
||||
import {
|
||||
createConfiguration,
|
||||
ServerConfiguration,
|
||||
DefaultApi,
|
||||
} from '@vegaprotocol/vegawallet-service-api-client';
|
||||
import { LocalStorage } from '@vegaprotocol/react-helpers';
|
||||
@ -39,13 +40,26 @@ export class RestConnector implements VegaConnector {
|
||||
this.service = new DefaultApi(this.apiConfig);
|
||||
}
|
||||
|
||||
async authenticate(params: { wallet: string; passphrase: string }) {
|
||||
async authenticate(
|
||||
url: string,
|
||||
params: {
|
||||
wallet: string;
|
||||
passphrase: string;
|
||||
}
|
||||
) {
|
||||
try {
|
||||
const res = await this.service.authTokenPost(params);
|
||||
const service = new DefaultApi(
|
||||
createConfiguration({
|
||||
baseServer: new ServerConfiguration<Record<string, never>>(url, {}),
|
||||
})
|
||||
);
|
||||
|
||||
const res = await service.authTokenPost(params);
|
||||
|
||||
// Renew service instance with default bearer authMethod now that we have the token
|
||||
this.service = new DefaultApi(
|
||||
createConfiguration({
|
||||
baseServer: new ServerConfiguration<Record<string, never>>(url, {}),
|
||||
authMethods: {
|
||||
bearer: `Bearer ${res.token}`,
|
||||
},
|
||||
|
@ -43,7 +43,6 @@ export const VegaWalletProvider = ({ children }: VegaWalletProviderProps) => {
|
||||
});
|
||||
|
||||
setKeypairs(publicKeysWithName);
|
||||
|
||||
if (publicKey === null) {
|
||||
setPublicKey(publicKeysWithName[0].pub);
|
||||
}
|
||||
@ -60,6 +59,7 @@ export const VegaWalletProvider = ({ children }: VegaWalletProviderProps) => {
|
||||
try {
|
||||
await connector.current?.disconnect();
|
||||
setKeypairs(null);
|
||||
setPublicKey(null);
|
||||
connector.current = null;
|
||||
LocalStorage.removeItem(WALLET_KEY);
|
||||
return true;
|
||||
|
@ -5,6 +5,7 @@ import { useForm } from 'react-hook-form';
|
||||
import type { RestConnector } from '.';
|
||||
|
||||
interface FormFields {
|
||||
url: string;
|
||||
wallet: string;
|
||||
passphrase: string;
|
||||
}
|
||||
@ -14,6 +15,8 @@ interface RestConnectorFormProps {
|
||||
onAuthenticate: () => void;
|
||||
}
|
||||
|
||||
const VEGA_DEFAULT_URL = 'http://localhost:1789/api/v1';
|
||||
|
||||
export function RestConnectorForm({
|
||||
connector,
|
||||
onAuthenticate,
|
||||
@ -24,12 +27,16 @@ export function RestConnectorForm({
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<FormFields>();
|
||||
} = useForm<FormFields>({
|
||||
defaultValues: {
|
||||
url: VEGA_DEFAULT_URL,
|
||||
},
|
||||
});
|
||||
|
||||
async function onSubmit(fields: FormFields) {
|
||||
try {
|
||||
setError('');
|
||||
const res = await connector.authenticate({
|
||||
const res = await connector.authenticate(fields.url, {
|
||||
wallet: fields.wallet,
|
||||
passphrase: fields.passphrase,
|
||||
});
|
||||
@ -41,7 +48,7 @@ export function RestConnectorForm({
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof TypeError) {
|
||||
setError(t('Wallet not running at http://localhost:1789'));
|
||||
setError(t(`Wallet not running at ${fields.url}`));
|
||||
} else if (err instanceof Error) {
|
||||
setError(t('Authentication failed'));
|
||||
} else {
|
||||
@ -52,6 +59,18 @@ export function RestConnectorForm({
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} data-testid="rest-connector-form">
|
||||
<FormGroup label={t('Url')} labelFor="url">
|
||||
<Input
|
||||
{...register('url', { required: t('Required') })}
|
||||
id="url"
|
||||
type="text"
|
||||
/>
|
||||
{errors.url?.message && (
|
||||
<InputError intent="danger" className="mt-4">
|
||||
{errors.url.message}
|
||||
</InputError>
|
||||
)}
|
||||
</FormGroup>
|
||||
<FormGroup label={t('Wallet')} labelFor="wallet">
|
||||
<Input
|
||||
{...register('wallet', { required: t('Required') })}
|
||||
|
Loading…
Reference in New Issue
Block a user