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'));
|
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);
|
expect(defaultProps.setDialogOpen).toHaveBeenCalledWith(false);
|
||||||
});
|
});
|
||||||
@ -117,7 +150,7 @@ it('Unsuccessful connection using rest auth form', async () => {
|
|||||||
fireEvent.submit(screen.getByTestId('rest-connector-form'));
|
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(
|
expect(screen.getByTestId('form-error')).toHaveTextContent(
|
||||||
'Something went wrong'
|
'Something went wrong'
|
||||||
@ -135,7 +168,7 @@ it('Unsuccessful connection using rest auth form', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(screen.getByTestId('form-error')).toHaveTextContent(
|
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
|
// Reject eg non 200 results
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import type { Configuration } from '@vegaprotocol/vegawallet-service-api-client';
|
import type { Configuration } from '@vegaprotocol/vegawallet-service-api-client';
|
||||||
import {
|
import {
|
||||||
createConfiguration,
|
createConfiguration,
|
||||||
|
ServerConfiguration,
|
||||||
DefaultApi,
|
DefaultApi,
|
||||||
} from '@vegaprotocol/vegawallet-service-api-client';
|
} from '@vegaprotocol/vegawallet-service-api-client';
|
||||||
import { LocalStorage } from '@vegaprotocol/react-helpers';
|
import { LocalStorage } from '@vegaprotocol/react-helpers';
|
||||||
@ -39,13 +40,26 @@ export class RestConnector implements VegaConnector {
|
|||||||
this.service = new DefaultApi(this.apiConfig);
|
this.service = new DefaultApi(this.apiConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
async authenticate(params: { wallet: string; passphrase: string }) {
|
async authenticate(
|
||||||
|
url: string,
|
||||||
|
params: {
|
||||||
|
wallet: string;
|
||||||
|
passphrase: string;
|
||||||
|
}
|
||||||
|
) {
|
||||||
try {
|
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
|
// Renew service instance with default bearer authMethod now that we have the token
|
||||||
this.service = new DefaultApi(
|
this.service = new DefaultApi(
|
||||||
createConfiguration({
|
createConfiguration({
|
||||||
|
baseServer: new ServerConfiguration<Record<string, never>>(url, {}),
|
||||||
authMethods: {
|
authMethods: {
|
||||||
bearer: `Bearer ${res.token}`,
|
bearer: `Bearer ${res.token}`,
|
||||||
},
|
},
|
||||||
|
@ -43,7 +43,6 @@ export const VegaWalletProvider = ({ children }: VegaWalletProviderProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setKeypairs(publicKeysWithName);
|
setKeypairs(publicKeysWithName);
|
||||||
|
|
||||||
if (publicKey === null) {
|
if (publicKey === null) {
|
||||||
setPublicKey(publicKeysWithName[0].pub);
|
setPublicKey(publicKeysWithName[0].pub);
|
||||||
}
|
}
|
||||||
@ -60,6 +59,7 @@ export const VegaWalletProvider = ({ children }: VegaWalletProviderProps) => {
|
|||||||
try {
|
try {
|
||||||
await connector.current?.disconnect();
|
await connector.current?.disconnect();
|
||||||
setKeypairs(null);
|
setKeypairs(null);
|
||||||
|
setPublicKey(null);
|
||||||
connector.current = null;
|
connector.current = null;
|
||||||
LocalStorage.removeItem(WALLET_KEY);
|
LocalStorage.removeItem(WALLET_KEY);
|
||||||
return true;
|
return true;
|
||||||
|
@ -5,6 +5,7 @@ import { useForm } from 'react-hook-form';
|
|||||||
import type { RestConnector } from '.';
|
import type { RestConnector } from '.';
|
||||||
|
|
||||||
interface FormFields {
|
interface FormFields {
|
||||||
|
url: string;
|
||||||
wallet: string;
|
wallet: string;
|
||||||
passphrase: string;
|
passphrase: string;
|
||||||
}
|
}
|
||||||
@ -14,6 +15,8 @@ interface RestConnectorFormProps {
|
|||||||
onAuthenticate: () => void;
|
onAuthenticate: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VEGA_DEFAULT_URL = 'http://localhost:1789/api/v1';
|
||||||
|
|
||||||
export function RestConnectorForm({
|
export function RestConnectorForm({
|
||||||
connector,
|
connector,
|
||||||
onAuthenticate,
|
onAuthenticate,
|
||||||
@ -24,12 +27,16 @@ export function RestConnectorForm({
|
|||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
} = useForm<FormFields>();
|
} = useForm<FormFields>({
|
||||||
|
defaultValues: {
|
||||||
|
url: VEGA_DEFAULT_URL,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
async function onSubmit(fields: FormFields) {
|
async function onSubmit(fields: FormFields) {
|
||||||
try {
|
try {
|
||||||
setError('');
|
setError('');
|
||||||
const res = await connector.authenticate({
|
const res = await connector.authenticate(fields.url, {
|
||||||
wallet: fields.wallet,
|
wallet: fields.wallet,
|
||||||
passphrase: fields.passphrase,
|
passphrase: fields.passphrase,
|
||||||
});
|
});
|
||||||
@ -41,7 +48,7 @@ export function RestConnectorForm({
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof TypeError) {
|
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) {
|
} else if (err instanceof Error) {
|
||||||
setError(t('Authentication failed'));
|
setError(t('Authentication failed'));
|
||||||
} else {
|
} else {
|
||||||
@ -52,6 +59,18 @@ export function RestConnectorForm({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onSubmit)} data-testid="rest-connector-form">
|
<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">
|
<FormGroup label={t('Wallet')} labelFor="wallet">
|
||||||
<Input
|
<Input
|
||||||
{...register('wallet', { required: t('Required') })}
|
{...register('wallet', { required: t('Required') })}
|
||||||
|
Loading…
Reference in New Issue
Block a user