Task/Remove vegawallet service api client (#916)
* chore: remove generated vegawallet client code and implement in rest connector * feat: add zod validation * feat: handle specific auth/token delete case * feat: make withdraw dialog match vega tx dialog * fix: response stub to be right shape, add content type to requests * chore: revert unrelated classname change
This commit is contained in:
parent
76efc3f68b
commit
4269060c9c
@ -1,2 +1 @@
|
||||
export { VoteDetails } from './vote-details';
|
||||
export { VOTE_VALUE_MAP } from './vote-types';
|
||||
|
@ -2,8 +2,7 @@ import { captureException, captureMessage } from '@sentry/minimal';
|
||||
import * as React from 'react';
|
||||
|
||||
import { VoteValue } from '../../../../__generated__/globalTypes';
|
||||
import { VOTE_VALUE_MAP } from './vote-types';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet, VegaWalletVoteValue } from '@vegaprotocol/wallet';
|
||||
|
||||
export type Vote = {
|
||||
value: VoteValue;
|
||||
@ -101,7 +100,7 @@ export function useUserVote(
|
||||
pubKey: keypair.pub,
|
||||
propagate: true,
|
||||
voteSubmission: {
|
||||
value: VOTE_VALUE_MAP[value],
|
||||
value: VegaWalletVoteValue[value],
|
||||
proposalId,
|
||||
},
|
||||
};
|
||||
|
@ -1,6 +0,0 @@
|
||||
import { VoteValue } from '../../../../__generated__/globalTypes';
|
||||
|
||||
export const VOTE_VALUE_MAP = {
|
||||
[VoteValue.Yes]: 'VALUE_YES',
|
||||
[VoteValue.No]: 'VALUE_NO',
|
||||
} as const;
|
@ -5,8 +5,8 @@ import { useTranslation } from 'react-i18next';
|
||||
import { useAppState } from '../../contexts/app-state/app-state-context';
|
||||
import { BigNumber } from '../../lib/bignumber';
|
||||
import { removeDecimal } from '../../lib/decimals';
|
||||
import type { UndelegateSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import type { UndelegateSubmissionBody } from '@vegaprotocol/vegawallet-service-api-client';
|
||||
|
||||
interface PendingStakeProps {
|
||||
pendingAmount: BigNumber;
|
||||
|
@ -26,11 +26,11 @@ import {
|
||||
Radio,
|
||||
RadioGroup,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import type {
|
||||
DelegateSubmissionBody,
|
||||
UndelegateSubmissionBody,
|
||||
} from '@vegaprotocol/vegawallet-service-api-client';
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
|
||||
export const PARTY_DELEGATIONS_QUERY = gql`
|
||||
query PartyDelegations($partyId: ID!) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { TransactionResponse } from '@vegaprotocol/vegawallet-service-api-client';
|
||||
import type { TransactionResponse } from '@vegaprotocol/wallet';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
declare global {
|
||||
@ -17,7 +17,10 @@ export function addMockVegaWalletCommands() {
|
||||
'mockVegaCommandSync',
|
||||
(override?: PartialDeep<TransactionResponse>) => {
|
||||
const defaultTransactionResponse = {
|
||||
txId: 'tx-id',
|
||||
txHash: 'tx-hash',
|
||||
sentAt: new Date().toISOString(),
|
||||
receivedAt: new Date().toISOString(),
|
||||
tx: {
|
||||
input_data:
|
||||
'CPe6vpiqsPqxDBDC1w7KPkoKQGE4Y2M0NjUwMjhiMGY4OTM4YTYzZTEzNDViYzM2ODc3ZWRmODg4MjNmOWU0ZmI4ZDRlN2VkMmFlMzAwNzA3ZTMYASABKAM4Ag==',
|
||||
@ -28,7 +31,7 @@ export function addMockVegaWalletCommands() {
|
||||
version: 1,
|
||||
},
|
||||
From: {
|
||||
PubKey: Cypress.env('vegaPublicKey'),
|
||||
PubKey: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
},
|
||||
version: 2,
|
||||
pow: {
|
||||
|
@ -51,14 +51,11 @@ export const useOrderEdit = (order: OrderFields | null) => {
|
||||
orderAmendment: {
|
||||
orderId: order.id,
|
||||
marketId: order.market.id,
|
||||
// @ts-ignore fix me please!
|
||||
price: {
|
||||
value: removeDecimal(args.price, order.market.decimalPlaces),
|
||||
},
|
||||
timeInForce: VegaWalletOrderTimeInForce[order.timeInForce],
|
||||
// @ts-ignore fix me please!
|
||||
sizeDelta: 0,
|
||||
// @ts-ignore fix me please!
|
||||
expiresAt: order.expiresAt
|
||||
? {
|
||||
value: toNanoSeconds(new Date(order.expiresAt)), // Wallet expects timestamp in nanoseconds
|
||||
|
@ -1,43 +1,80 @@
|
||||
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';
|
||||
import { WALLET_CONFIG } from '../storage-keys';
|
||||
import type { VegaConnector } from './vega-connector';
|
||||
import type { TransactionSubmission } from '../wallet-types';
|
||||
import { z } from 'zod';
|
||||
|
||||
// Perhaps there should be a default ConnectorConfig that others can extend off. Do all connectors
|
||||
// need to use local storage, I don't think so...
|
||||
interface RestConnectorConfig {
|
||||
token: string | null;
|
||||
connector: 'rest';
|
||||
url: string | null;
|
||||
}
|
||||
|
||||
type Endpoint = 'auth/token' | 'command/sync' | 'keys';
|
||||
|
||||
export const AuthTokenSchema = z.object({
|
||||
token: z.string(),
|
||||
});
|
||||
|
||||
export const TransactionResponseSchema = z.object({
|
||||
txId: z.string(),
|
||||
txHash: z.string(),
|
||||
tx: z.object({
|
||||
From: z.object({
|
||||
PubKey: z.string(),
|
||||
}),
|
||||
input_data: z.string(),
|
||||
pow: z.object({
|
||||
tid: z.string(),
|
||||
nonce: z.number(),
|
||||
}),
|
||||
signature: z.object({
|
||||
algo: z.string(),
|
||||
value: z.string(),
|
||||
version: z.number(),
|
||||
}),
|
||||
}),
|
||||
sentAt: z.string(),
|
||||
receivedAt: z.string(),
|
||||
});
|
||||
|
||||
export const GetKeysSchema = z.object({
|
||||
keys: z.array(
|
||||
z.object({
|
||||
algorithm: z.object({
|
||||
name: z.string(),
|
||||
version: z.number(),
|
||||
}),
|
||||
index: z.number(),
|
||||
meta: z.array(
|
||||
z.object({
|
||||
key: z.string(),
|
||||
value: z.string(),
|
||||
})
|
||||
),
|
||||
pub: z.string(),
|
||||
tainted: z.boolean(),
|
||||
})
|
||||
),
|
||||
});
|
||||
|
||||
/**
|
||||
* Connector for using the Vega Wallet Service rest api, requires authentication to get a session token
|
||||
*/
|
||||
export class RestConnector implements VegaConnector {
|
||||
configKey = WALLET_CONFIG;
|
||||
apiConfig: Configuration;
|
||||
service: DefaultApi;
|
||||
description = 'Connects using REST to a running Vega wallet service';
|
||||
url: string | null = null;
|
||||
token: string | null = null;
|
||||
|
||||
constructor() {
|
||||
const cfg = this.getConfig();
|
||||
|
||||
// If theres a stored auth token create api config with bearer authMethod
|
||||
this.apiConfig = cfg?.token
|
||||
? createConfiguration({
|
||||
authMethods: {
|
||||
bearer: `Bearer ${cfg.token}`,
|
||||
},
|
||||
})
|
||||
: createConfiguration();
|
||||
|
||||
this.service = new DefaultApi(this.apiConfig);
|
||||
if (cfg) {
|
||||
this.token = cfg.token;
|
||||
this.url = cfg.url;
|
||||
}
|
||||
}
|
||||
|
||||
async authenticate(
|
||||
@ -48,26 +85,22 @@ export class RestConnector implements VegaConnector {
|
||||
}
|
||||
) {
|
||||
try {
|
||||
const service = new DefaultApi(
|
||||
createConfiguration({
|
||||
baseServer: new ServerConfiguration<Record<string, never>>(url, {}),
|
||||
})
|
||||
);
|
||||
this.url = url;
|
||||
|
||||
const res = await service.authTokenPost(params);
|
||||
const res = await this.request('auth/token', {
|
||||
method: 'post',
|
||||
body: JSON.stringify(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}`,
|
||||
},
|
||||
})
|
||||
);
|
||||
const data = AuthTokenSchema.parse(res.data);
|
||||
|
||||
// Store the token, and other things for later
|
||||
this.setConfig({ connector: 'rest', token: res.token });
|
||||
this.setConfig({
|
||||
connector: 'rest',
|
||||
token: data.token,
|
||||
url: this.url,
|
||||
});
|
||||
this.token = data.token;
|
||||
|
||||
return { success: true, error: null };
|
||||
} catch (err) {
|
||||
@ -77,10 +110,17 @@ export class RestConnector implements VegaConnector {
|
||||
|
||||
async connect() {
|
||||
try {
|
||||
const res = await this.service.keysGet();
|
||||
return res.keys;
|
||||
const res = await this.request('keys', {
|
||||
method: 'get',
|
||||
headers: {
|
||||
authorization: `Bearer ${this.token}`,
|
||||
},
|
||||
});
|
||||
|
||||
const data = GetKeysSchema.parse(res.data);
|
||||
|
||||
return data.keys;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
// keysGet failed, its likely that the session has expired so remove the token from storage
|
||||
this.clearConfig();
|
||||
return null;
|
||||
@ -89,7 +129,12 @@ export class RestConnector implements VegaConnector {
|
||||
|
||||
async disconnect() {
|
||||
try {
|
||||
await this.service.authTokenDelete();
|
||||
await this.request('auth/token', {
|
||||
method: 'delete',
|
||||
headers: {
|
||||
authorization: `Bearer ${this.token}`,
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
} finally {
|
||||
@ -101,28 +146,26 @@ export class RestConnector implements VegaConnector {
|
||||
|
||||
async sendTx(body: TransactionSubmission) {
|
||||
try {
|
||||
const res = await this.service.commandSyncPost(body);
|
||||
return res;
|
||||
const res = await this.request('command/sync', {
|
||||
method: 'post',
|
||||
body: JSON.stringify(body),
|
||||
headers: {
|
||||
authorization: `Bearer ${this.token}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (res.status === 401) {
|
||||
// User rejected
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = TransactionResponseSchema.parse(res.data);
|
||||
|
||||
return data;
|
||||
} catch (err) {
|
||||
return this.handleSendTxError(err);
|
||||
}
|
||||
}
|
||||
|
||||
private handleSendTxError(err: unknown) {
|
||||
const unexpectedError = { error: 'Something went wrong' };
|
||||
|
||||
if (isServiceError(err)) {
|
||||
if (err.code === 401) {
|
||||
return { error: 'User rejected' };
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(err.body ?? '');
|
||||
} catch {
|
||||
return unexpectedError;
|
||||
}
|
||||
} else {
|
||||
return unexpectedError;
|
||||
return {
|
||||
error: 'Failed to fetch',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,18 +189,29 @@ export class RestConnector implements VegaConnector {
|
||||
private clearConfig() {
|
||||
LocalStorage.removeItem(this.configKey);
|
||||
}
|
||||
}
|
||||
|
||||
interface ServiceError {
|
||||
code: number;
|
||||
body: string | undefined;
|
||||
headers: object;
|
||||
}
|
||||
private async request(endpoint: Endpoint, options: RequestInit) {
|
||||
const fetchResult = await fetch(`${this.url}/${endpoint}`, {
|
||||
...options,
|
||||
headers: {
|
||||
...options.headers,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
export const isServiceError = (err: unknown): err is ServiceError => {
|
||||
// Some responses don't contain body object
|
||||
if (typeof err === 'object' && err !== null && 'code' in err) {
|
||||
return true;
|
||||
// auth/token delete doesnt return json
|
||||
if (endpoint === 'auth/token' && options.method === 'delete') {
|
||||
const textResult = await fetchResult.text();
|
||||
return {
|
||||
status: fetchResult.status,
|
||||
data: textResult,
|
||||
};
|
||||
} else {
|
||||
const jsonResult = await fetchResult.json();
|
||||
return {
|
||||
status: fetchResult.status,
|
||||
data: jsonResult,
|
||||
};
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import type { VegaKey } from '../wallet-types';
|
||||
import type {
|
||||
VegaKey,
|
||||
TransactionSubmission,
|
||||
TransactionResponse,
|
||||
} from '@vegaprotocol/vegawallet-service-api-client';
|
||||
import type { TransactionSubmission } from '../wallet-types';
|
||||
} from '../wallet-types';
|
||||
|
||||
type ErrorResponse =
|
||||
| {
|
||||
|
@ -1,18 +1,10 @@
|
||||
import type {
|
||||
VegaKey,
|
||||
TransactionResponse,
|
||||
} from '@vegaprotocol/vegawallet-service-api-client';
|
||||
import type { TransactionError, VegaKey } from './wallet-types';
|
||||
import { createContext } from 'react';
|
||||
import type { VegaConnector } from './connectors';
|
||||
import type { TransactionSubmission } from './wallet-types';
|
||||
|
||||
export type SendTxError =
|
||||
| {
|
||||
error: string;
|
||||
}
|
||||
| {
|
||||
errors: object;
|
||||
};
|
||||
import type {
|
||||
TransactionSubmission,
|
||||
TransactionResponse,
|
||||
} from './wallet-types';
|
||||
|
||||
export interface VegaKeyExtended extends VegaKey {
|
||||
name: string;
|
||||
@ -40,7 +32,7 @@ export interface VegaWalletContextShape {
|
||||
/** Send a transaction to the network, only order submissions for now */
|
||||
sendTx: (
|
||||
tx: TransactionSubmission
|
||||
) => Promise<TransactionResponse | SendTxError> | null;
|
||||
) => Promise<TransactionResponse | TransactionError> | null;
|
||||
}
|
||||
|
||||
export const VegaWalletContext = createContext<
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { act, fireEvent, render, screen } from '@testing-library/react';
|
||||
import type { VegaKey } from '@vegaprotocol/vegawallet-service-api-client';
|
||||
import type { VegaKey } from './wallet-types';
|
||||
import { RestConnector } from './connectors';
|
||||
import { useVegaWallet } from './use-vega-wallet';
|
||||
import { VegaWalletProvider } from './provider';
|
||||
|
@ -3,7 +3,7 @@ import type { VegaWalletContextShape } from './context';
|
||||
import { VegaWalletContext } from './context';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useVegaTransaction, VegaTxStatus } from './use-vega-transaction';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/vegawallet-service-api-client';
|
||||
import type { OrderSubmissionBody } from './wallet-types';
|
||||
|
||||
const defaultWalletContext = {
|
||||
keypair: null,
|
||||
|
@ -1,8 +1,7 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import type { TransactionSubmission } from './wallet-types';
|
||||
import type { TransactionError, TransactionSubmission } from './wallet-types';
|
||||
import { useVegaWallet } from './use-vega-wallet';
|
||||
import type { SendTxError } from './context';
|
||||
import { VegaTransactionDialog } from './vega-transaction-dialog';
|
||||
import type { Intent } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
@ -23,7 +22,7 @@ export enum VegaTxStatus {
|
||||
|
||||
export interface VegaTxState {
|
||||
status: VegaTxStatus;
|
||||
error: object | null;
|
||||
error: TransactionError | null;
|
||||
txHash: string | null;
|
||||
signature: string | null;
|
||||
dialogOpen: boolean;
|
||||
@ -49,7 +48,7 @@ export const useVegaTransaction = () => {
|
||||
}, []);
|
||||
|
||||
const handleError = useCallback(
|
||||
(error: SendTxError) => {
|
||||
(error: TransactionError) => {
|
||||
setTransaction({ error, status: VegaTxStatus.Error });
|
||||
},
|
||||
[setTransaction]
|
||||
@ -76,23 +75,23 @@ export const useVegaTransaction = () => {
|
||||
const res = await sendTx(tx);
|
||||
|
||||
if (res === null) {
|
||||
setTransaction({ status: VegaTxStatus.Default });
|
||||
return null;
|
||||
// User rejected
|
||||
reset();
|
||||
return;
|
||||
}
|
||||
if ('errors' in res) {
|
||||
|
||||
if (isError(res)) {
|
||||
handleError(res);
|
||||
} else if ('error' in res) {
|
||||
if (res.error === 'User rejected') {
|
||||
reset();
|
||||
} else {
|
||||
handleError(res);
|
||||
}
|
||||
} else if (res.tx?.signature?.value && res.txHash) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (res.tx?.signature?.value && res.txHash) {
|
||||
setTransaction({
|
||||
status: VegaTxStatus.Pending,
|
||||
txHash: res.txHash,
|
||||
signature: res.tx.signature.value,
|
||||
});
|
||||
|
||||
return {
|
||||
signature: res.tx.signature?.value,
|
||||
};
|
||||
@ -125,3 +124,14 @@ export const useVegaTransaction = () => {
|
||||
TransactionDialog,
|
||||
};
|
||||
};
|
||||
|
||||
const isError = (error: unknown): error is TransactionError => {
|
||||
if (
|
||||
error !== null &&
|
||||
typeof error === 'object' &&
|
||||
('error' in error || 'errors' in error)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
@ -57,7 +57,7 @@ describe('VegaTransactionDialog', () => {
|
||||
{...props}
|
||||
transaction={{
|
||||
...props.transaction,
|
||||
error: { message: 'rejected' },
|
||||
error: { error: 'rejected' },
|
||||
status: VegaTxStatus.Error,
|
||||
}}
|
||||
/>
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import get from 'lodash/get';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Dialog, Icon, Intent, Loader } from '@vegaprotocol/ui-toolkit';
|
||||
import type { ReactNode } from 'react';
|
||||
@ -71,16 +70,18 @@ export const VegaDialog = ({ transaction }: VegaDialogProps) => {
|
||||
}
|
||||
|
||||
if (transaction.status === VegaTxStatus.Error) {
|
||||
return (
|
||||
<div data-testid={transaction.status}>
|
||||
{transaction.error && (
|
||||
<pre className="text-ui break-all whitespace-pre-wrap">
|
||||
{get(transaction.error, 'error') ??
|
||||
JSON.stringify(transaction.error, null, 2)}
|
||||
</pre>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
let content = null;
|
||||
|
||||
if (transaction.error) {
|
||||
if ('errors' in transaction.error) {
|
||||
content = transaction.error.errors['*'].map((e) => <p>{e}</p>);
|
||||
} else if ('error' in transaction.error) {
|
||||
content = <p>{transaction.error.error}</p>;
|
||||
} else {
|
||||
content = <p>{t('Something went wrong')}</p>;
|
||||
}
|
||||
}
|
||||
return <div data-testid={transaction.status}>{content}</div>;
|
||||
}
|
||||
|
||||
if (transaction.status === VegaTxStatus.Pending) {
|
||||
|
@ -1,12 +1,88 @@
|
||||
import type {
|
||||
DelegateSubmissionBody,
|
||||
OrderCancellationBody,
|
||||
OrderSubmissionBody,
|
||||
UndelegateSubmissionBody,
|
||||
VoteSubmissionBody,
|
||||
WithdrawSubmissionBody,
|
||||
OrderAmendmentBody,
|
||||
} from '@vegaprotocol/vegawallet-service-api-client';
|
||||
import type { z } from 'zod';
|
||||
import type { GetKeysSchema, TransactionResponseSchema } from './connectors';
|
||||
import type { IterableElement } from 'type-fest';
|
||||
|
||||
interface BaseTransaction {
|
||||
pubKey: string;
|
||||
propagate: boolean;
|
||||
}
|
||||
|
||||
export interface DelegateSubmissionBody extends BaseTransaction {
|
||||
delegateSubmission: {
|
||||
nodeId: string;
|
||||
amount: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface UndelegateSubmissionBody extends BaseTransaction {
|
||||
undelegateSubmission: {
|
||||
nodeId: string;
|
||||
amount: string;
|
||||
method: 'METHOD_NOW' | 'METHOD_AT_END_OF_EPOCH';
|
||||
};
|
||||
}
|
||||
|
||||
export interface OrderSubmissionBody extends BaseTransaction {
|
||||
orderSubmission: {
|
||||
marketId: string;
|
||||
reference?: string;
|
||||
type: VegaWalletOrderType;
|
||||
side: VegaWalletOrderSide;
|
||||
timeInForce: VegaWalletOrderTimeInForce;
|
||||
size: string;
|
||||
price?: string;
|
||||
expiresAt?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface OrderCancellationBody extends BaseTransaction {
|
||||
orderCancellation: {
|
||||
orderId: string;
|
||||
marketId: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface OrderAmendmentBody extends BaseTransaction {
|
||||
orderAmendment: {
|
||||
marketId: string;
|
||||
orderId: string;
|
||||
reference?: string;
|
||||
timeInForce: VegaWalletOrderTimeInForce;
|
||||
sizeDelta?: number;
|
||||
// Note this is soon changing to price?: string
|
||||
price?: {
|
||||
value: string;
|
||||
};
|
||||
// Note this is soon changing to expiresAt?: number
|
||||
expiresAt?: {
|
||||
value: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface VoteSubmissionBody extends BaseTransaction {
|
||||
voteSubmission: {
|
||||
value: VegaWalletVoteValue;
|
||||
proposalId: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface WithdrawSubmissionBody extends BaseTransaction {
|
||||
withdrawSubmission: {
|
||||
amount: string;
|
||||
asset: string;
|
||||
ext: {
|
||||
erc20: {
|
||||
receiverAddress: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export enum VegaWalletVoteValue {
|
||||
Yes = 'VALUE_YES',
|
||||
No = 'VALUE_NO',
|
||||
}
|
||||
|
||||
export enum VegaWalletOrderType {
|
||||
Market = 'TYPE_MARKET',
|
||||
@ -36,3 +112,17 @@ export type TransactionSubmission =
|
||||
| DelegateSubmissionBody
|
||||
| UndelegateSubmissionBody
|
||||
| OrderAmendmentBody;
|
||||
|
||||
export type TransactionResponse = z.infer<typeof TransactionResponseSchema>;
|
||||
export type GetKeysResponse = z.infer<typeof GetKeysSchema>;
|
||||
export type VegaKey = IterableElement<GetKeysResponse['keys']>;
|
||||
|
||||
export type TransactionError =
|
||||
| {
|
||||
errors: {
|
||||
'*': string[];
|
||||
};
|
||||
}
|
||||
| {
|
||||
error: string;
|
||||
};
|
||||
|
@ -69,6 +69,18 @@ const getProps = (
|
||||
ethTx: EthTxState,
|
||||
ethUrl: string
|
||||
) => {
|
||||
const renderVegaTxError = () => {
|
||||
if (vegaTx.error) {
|
||||
if ('errors' in vegaTx.error) {
|
||||
return vegaTx.error.errors['*'].map((e) => <p>{e}</p>);
|
||||
} else if ('error' in vegaTx.error) {
|
||||
return <p>{vegaTx.error.error}</p>;
|
||||
} else {
|
||||
return <p>{t('Something went wrong')}</p>;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const vegaTxPropsMap: Record<VegaTxStatus, DialogProps> = {
|
||||
[VegaTxStatus.Default]: {
|
||||
title: '',
|
||||
@ -80,15 +92,7 @@ const getProps = (
|
||||
title: t('Withdrawal transaction failed'),
|
||||
icon: <Icon name="warning-sign" size={20} />,
|
||||
intent: Intent.Danger,
|
||||
children: (
|
||||
<Step>
|
||||
{vegaTx.error && (
|
||||
<pre className="text-ui break-all whitespace-pre-wrap">
|
||||
{JSON.stringify(vegaTx.error, null, 2)}
|
||||
</pre>
|
||||
)}
|
||||
</Step>
|
||||
),
|
||||
children: <Step>{renderVegaTxError()}</Step>,
|
||||
},
|
||||
[VegaTxStatus.Requested]: {
|
||||
title: t('Confirm withdrawal'),
|
||||
|
@ -30,7 +30,6 @@
|
||||
"@sentry/react": "^6.19.2",
|
||||
"@sentry/tracing": "^6.19.2",
|
||||
"@testing-library/user-event": "^14.2.1",
|
||||
"@vegaprotocol/vegawallet-service-api-client": "0.4.15",
|
||||
"@walletconnect/ethereum-provider": "^1.7.5",
|
||||
"@web3-react/core": "8.0.20-beta.0",
|
||||
"@web3-react/metamask": "8.0.16-beta.0",
|
||||
|
32
yarn.lock
32
yarn.lock
@ -6693,15 +6693,6 @@
|
||||
"@typescript-eslint/types" "5.22.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
|
||||
"@vegaprotocol/vegawallet-service-api-client@0.4.15":
|
||||
version "0.4.15"
|
||||
resolved "https://registry.yarnpkg.com/@vegaprotocol/vegawallet-service-api-client/-/vegawallet-service-api-client-0.4.15.tgz#b303fec121b9b334a678161a6f66b360aeed5f0d"
|
||||
integrity sha512-YwJkUgFvFqpA1xPYQ30ILGddgzjwD9lclsu1GvwK2AUX/8e3iUcXyr37wLd/t8mDZ7P3Zb2AsuLJP8uZ6E1GHQ==
|
||||
dependencies:
|
||||
es6-promise "^4.2.4"
|
||||
url-parse "^1.4.3"
|
||||
whatwg-fetch "^3.0.0"
|
||||
|
||||
"@walletconnect/browser-utils@^1.7.7":
|
||||
version "1.7.7"
|
||||
resolved "https://registry.yarnpkg.com/@walletconnect/browser-utils/-/browser-utils-1.7.7.tgz#4ae0db1ddf49be179ea556af842db3b7afce973d"
|
||||
@ -11543,11 +11534,6 @@ es6-object-assign@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c"
|
||||
integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=
|
||||
|
||||
es6-promise@^4.2.4:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||
|
||||
es6-shim@^0.35.5:
|
||||
version "0.35.6"
|
||||
resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.6.tgz#d10578301a83af2de58b9eadb7c2c9945f7388a0"
|
||||
@ -18378,11 +18364,6 @@ querystring@^0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd"
|
||||
integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==
|
||||
|
||||
querystringify@^2.1.1:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
|
||||
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
|
||||
|
||||
queue-microtask@^1.2.2:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
@ -21666,14 +21647,6 @@ url-loader@^4.1.1:
|
||||
mime-types "^2.1.27"
|
||||
schema-utils "^3.0.0"
|
||||
|
||||
url-parse@^1.4.3:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
|
||||
integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
|
||||
dependencies:
|
||||
querystringify "^2.1.1"
|
||||
requires-port "^1.0.0"
|
||||
|
||||
url@^0.11.0, url@~0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
|
||||
@ -22293,11 +22266,6 @@ whatwg-encoding@^2.0.0:
|
||||
dependencies:
|
||||
iconv-lite "0.6.3"
|
||||
|
||||
whatwg-fetch@^3.0.0:
|
||||
version "3.6.2"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c"
|
||||
integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==
|
||||
|
||||
whatwg-mimetype@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
||||
|
Loading…
Reference in New Issue
Block a user