Skip to content

Commit

Permalink
Surface Tx error properly (#464)
Browse files Browse the repository at this point in the history
* pass error

keep the UI classes unchanged

* make error param optional

* revert ui changes

* define error code on

* cleanup

* revert ts-ignore changes - will address them on a separate pr

* fix:prettier

* error response

* Revert "error response"

This reverts commit 2ba022d.

* define TransactionError

* backward compatibility

* define WalletUIError

* any => unknown

* lint

* restricting param type
  • Loading branch information
bangtoven authored Apr 26, 2022
1 parent 7ef5ef6 commit aff47cc
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 67 deletions.
22 changes: 11 additions & 11 deletions src/provider/WalletSDKUI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,8 @@ export class WalletSDKUI implements WalletUI {
this.linkFlow.setConnectDisabled(connectDisabled);
}

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
addEthereumChain(options: {
onCancel: () => void;
addEthereumChain(_options: {
onCancel: (error?: Error) => void;
onApprove: () => void;
chainId: string;
rpcUrls: string[];
Expand All @@ -76,7 +74,7 @@ export class WalletSDKUI implements WalletUI {
}

watchAsset(_options: {
onCancel: () => void;
onCancel: (error?: Error) => void;
onApprove: () => void;
type: string;
address: string;
Expand All @@ -88,14 +86,16 @@ export class WalletSDKUI implements WalletUI {
}

switchEthereumChain(_options: {
onCancel: () => void;
onCancel: (error?: Error) => void;
onApprove: () => void;
chainId: string;
}) {
// no-op
}

requestEthereumAccounts(options: { onCancel: () => void }): void {
requestEthereumAccounts(options: {
onCancel: (error?: Error) => void;
}): void {
this.linkFlow.open({ onCancel: options.onCancel });
}

Expand All @@ -106,23 +106,23 @@ export class WalletSDKUI implements WalletUI {
signEthereumMessage(_: {
request: SignEthereumMessageRequest;
onSuccess: (response: SignEthereumMessageResponse) => void;
onCancel: () => void;
onCancel: (error?: Error) => void;
}): void {
// No-op
}

signEthereumTransaction(_: {
request: SignEthereumTransactionRequest;
onSuccess: (response: SignEthereumTransactionResponse) => void;
onCancel: () => void;
onCancel: (error?: Error) => void;
}): void {
// No-op
}

submitEthereumTransaction(_: {
request: SubmitEthereumTransactionRequest;
onSuccess: (response: SubmitEthereumTransactionResponse) => void;
onCancel: () => void;
onCancel: (error?: Error) => void;
}): void {
// No-op
}
Expand All @@ -136,7 +136,7 @@ export class WalletSDKUI implements WalletUI {

showConnecting(options: {
isUnlinkedErrorState?: boolean;
onCancel: () => void;
onCancel: (error?: Error) => void;
onResetConnection: () => void;
}): () => void {
let snackbarProps: SnackbarInstanceProps;
Expand Down
16 changes: 8 additions & 8 deletions src/provider/WalletUI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ export interface WalletUI {
*
*/
requestEthereumAccounts(options: {
onCancel: () => void;
onCancel: (error?: Error) => void;
onAccounts?: (accounts: [AddressString]) => void;
}): void;

addEthereumChain(options: {
onCancel: () => void;
onCancel: (error?: Error) => void;
onApprove: (rpcUrl: string) => void;
chainId: string;
rpcUrls: string[];
Expand All @@ -52,7 +52,7 @@ export interface WalletUI {
}): void;

watchAsset(options: {
onCancel: () => void;
onCancel: (error?: Error) => void;
onApprove: () => void;
type: string;
address: string;
Expand All @@ -63,27 +63,27 @@ export interface WalletUI {
}): void;

switchEthereumChain(options: {
onCancel: () => void;
onCancel: (error?: Error) => void;
onApprove: (rpcUrl: string) => void;
chainId: string;
}): void;

signEthereumMessage(options: {
request: SignEthereumMessageRequest;
onSuccess: (response: SignEthereumMessageResponse) => void;
onCancel: () => void;
onCancel: (error?: Error) => void;
}): void;

signEthereumTransaction(options: {
request: SignEthereumTransactionRequest;
onSuccess: (response: SignEthereumTransactionResponse) => void;
onCancel: () => void;
onCancel: (error?: Error) => void;
}): void;

submitEthereumTransaction(options: {
request: SubmitEthereumTransactionRequest;
onSuccess: (response: SubmitEthereumTransactionResponse) => void;
onCancel: () => void;
onCancel: (error?: Error) => void;
}): void;

ethereumAddressFromSignedMessage(options: {
Expand All @@ -105,7 +105,7 @@ export interface WalletUI {
*/
showConnecting(options: {
isUnlinkedErrorState?: boolean;
onCancel: () => void;
onCancel: (error?: Error) => void;
onResetConnection: () => void;
}): () => void;

Expand Down
12 changes: 12 additions & 0 deletions src/provider/WalletUIError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export class WalletUIError extends Error {
private constructor(readonly message: string, readonly errorCode?: number) {
super(message);
}

static UserRejectedRequest = new WalletUIError("User rejected request");

static SwitchEthereumChainUnsupportedChainId = new WalletUIError(
"Unsupported chainId",
4902
);
}
92 changes: 45 additions & 47 deletions src/relay/WalletSDKRelay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { ServerMessageEvent } from "../connection/ServerMessage";
import { WalletSDKConnection } from "../connection/WalletSDKConnection";
import { ScopedLocalStorage } from "../lib/ScopedLocalStorage";
import { WalletUI, WalletUIOptions } from "../provider/WalletUI";
import { WalletUIError } from "../provider/WalletUIError";
import { AddressString, IntNumber, RegExpString } from "../types";
import {
bigIntStringFromBN,
Expand Down Expand Up @@ -547,14 +548,9 @@ export class WalletSDKRelay extends WalletSDKRelayAbstract {
let hideSnackbarItem: (() => void) | null = null;
const id = randomBytesHex(8);

const cancel = () => {
const cancel = (error?: Error) => {
this.publishWeb3RequestCanceledEvent(id);
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
id,
response: ErrorResponse(request.method, "User rejected request")
})
);
this.handleErrorResponse(id, request.method, error);
hideSnackbarItem?.();
};

Expand Down Expand Up @@ -721,6 +717,24 @@ export class WalletSDKRelay extends WalletSDKRelayAbstract {
this.invokeCallback(message);
}

private handleErrorResponse(
id: string,
method: Web3Method,
error?: Error,
errorCode?: number
) {
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
id,
response: ErrorResponse(
method,
(error ?? WalletUIError.UserRejectedRequest).message,
errorCode
)
})
);
}

private invokeCallback(message: Web3ResponseMessage) {
const callback = this.relayEventManager.callbacks.get(message.id);
if (callback) {
Expand All @@ -741,14 +755,9 @@ export class WalletSDKRelay extends WalletSDKRelayAbstract {
const hideSnackbarItem: (() => void) | null = null;
const id = randomBytesHex(8);

const cancel = () => {
const cancel = (error?: Error) => {
this.publishWeb3RequestCanceledEvent(id);
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
id,
response: ErrorResponse(request.method, "User rejected request")
})
);
this.handleErrorResponse(id, request.method, error);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
hideSnackbarItem?.();
Expand Down Expand Up @@ -837,14 +846,9 @@ export class WalletSDKRelay extends WalletSDKRelayAbstract {
let hideSnackbarItem: (() => void) | null = null;
const id = randomBytesHex(8);

const cancel = () => {
const cancel = (error?: Error) => {
this.publishWeb3RequestCanceledEvent(id);
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
id,
response: ErrorResponse(request.method, "User rejected request")
})
);
this.handleErrorResponse(id, request.method, error);
hideSnackbarItem?.();
};

Expand All @@ -866,7 +870,7 @@ export class WalletSDKRelay extends WalletSDKRelayAbstract {
resolve(response as WatchAssetResponse);
});

const _cancel = () => {
const _cancel = (_error?: Error) => {
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
id,
Expand Down Expand Up @@ -932,14 +936,9 @@ export class WalletSDKRelay extends WalletSDKRelayAbstract {
let hideSnackbarItem: (() => void) | null = null;
const id = randomBytesHex(8);

const cancel = () => {
const cancel = (error?: Error) => {
this.publishWeb3RequestCanceledEvent(id);
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
id,
response: ErrorResponse(request.method, "User rejected request")
})
);
this.handleErrorResponse(id, request.method, error);
hideSnackbarItem?.();
};

Expand All @@ -961,7 +960,7 @@ export class WalletSDKRelay extends WalletSDKRelayAbstract {
resolve(response as AddEthereumChainResponse);
});

const _cancel = () => {
const _cancel = (_error?: Error) => {
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
id,
Expand Down Expand Up @@ -1016,14 +1015,9 @@ export class WalletSDKRelay extends WalletSDKRelayAbstract {
let hideSnackbarItem: (() => void) | null = null;
const id = randomBytesHex(8);

const cancel = () => {
const cancel = (error?: Error) => {
this.publishWeb3RequestCanceledEvent(id);
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
id,
response: ErrorResponse(request.method, "User rejected request")
})
);
this.handleErrorResponse(id, request.method, error);
hideSnackbarItem?.();
};

Expand Down Expand Up @@ -1054,18 +1048,27 @@ export class WalletSDKRelay extends WalletSDKRelayAbstract {
resolve(response as SwitchEthereumChainResponse);
});

const _cancel = (errorCode?: number) => {
if (errorCode) {
const _cancel = (error?: Error | number) => {
if (typeof error === "number") {
// backward compatibility
const errorCode: number = error;
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
id,
response: ErrorResponse(
Web3Method.switchEthereumChain,
"unsupported chainId",
WalletUIError.SwitchEthereumChainUnsupportedChainId.message,
errorCode
)
})
);
} else if (error instanceof WalletUIError) {
this.handleErrorResponse(
id,
Web3Method.switchEthereumChain,
error,
error.errorCode
);
} else {
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
Expand Down Expand Up @@ -1115,13 +1118,8 @@ export class WalletSDKRelay extends WalletSDKRelayAbstract {
}

private sendRequestStandalone<T extends Web3Request>(id: string, request: T) {
const _cancel = () => {
this.handleWeb3ResponseMessage(
Web3ResponseMessage({
id,
response: ErrorResponse(request.method, "User rejected request")
})
);
const _cancel = (error?: Error) => {
this.handleErrorResponse(id, request.method, error);
};

const onSuccess = (
Expand Down
2 changes: 1 addition & 1 deletion src/relay/WalletSDKRelayAbstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const APP_VERSION_KEY = "AppVersion";

export type CancelablePromise<T> = {
promise: Promise<T>;
cancel: () => void;
cancel: (error?: Error) => void;
};

export abstract class WalletSDKRelayAbstract {
Expand Down

0 comments on commit aff47cc

Please sign in to comment.