Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions packages/neuron-ui/src/services/remote/apiMethodWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// TODO: use error code
interface SuccessFromController {
status: 1
result: any
Expand All @@ -12,6 +11,7 @@ interface FailureFromController {
meta?: { [key: string]: string }
}
}

export type ControllerResponse = SuccessFromController | FailureFromController

export const RemoteNotLoadError = {
Expand All @@ -22,15 +22,7 @@ export const RemoteNotLoadError = {
}

export const apiMethodWrapper = <T = any>(
callControllerMethod: (
controller: any
) => (
params: T
) => Promise<{
status: any
result: any
message: { code?: number; content?: string; meta?: { [key: string]: string } }
}>
callControllerMethod: (controller: any) => (params: T) => Promise<string>
) => async (realParams: T): Promise<ControllerResponse> => {
if (!window.remote) {
return RemoteNotLoadError
Expand All @@ -44,7 +36,16 @@ export const apiMethodWrapper = <T = any>(
},
}
}
const res = await callControllerMethod(controller)(realParams)

const res: SuccessFromController | FailureFromController = await callControllerMethod(controller)(realParams)
.then(stringifiedRes => (stringifiedRes ? JSON.parse(stringifiedRes) : stringifiedRes))
.catch(() => ({
status: 0,
message: {
content: 'Invalid response format',
},
}))

if (process.env.NODE_ENV === 'development' && window.localStorage.getItem('log-response')) {
console.group('api controller')
console.info(JSON.stringify(res, null, 2))
Expand Down
70 changes: 37 additions & 33 deletions packages/neuron-wallet/src/controllers/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import WalletsService from 'services/wallets'
import SkipDataAndType from 'services/settings/skip-data-and-type'
import { ConnectionStatusSubject } from 'models/subjects/node'
import { SystemScriptSubject } from 'models/subjects/system-script'
import { CatchControllerError } from 'decorators/errors'
import { MapApiResponse } from 'decorators'
import { ResponseCode } from 'utils/const'
import { TransactionWithoutHash } from 'types/cell-types'

Expand All @@ -27,7 +27,9 @@ import { TransactionWithoutHash } from 'types/cell-types'
*/
export default class ApiController {
// App
public static loadInitData = async () => {

@MapApiResponse
public static async loadInitData() {
const walletsService = WalletsService.getInstance()
const networksService = NetworksService.getInstance()
const [
Expand Down Expand Up @@ -114,69 +116,71 @@ export default class ApiController {
return { status: ResponseCode.Success, result: initState }
}

public static handleViewError = (error: string) => {
@MapApiResponse
public static handleViewError(error: string) {
if (env.isDevMode) {
console.error(error)
}
}

@MapApiResponse
public static async contextMenu(params: { type: string; id: string }) {
return popContextMenu(params)
}

// Wallets

@CatchControllerError
@MapApiResponse
public static async getAllWallets() {
return WalletsController.getAll()
}

@CatchControllerError
@MapApiResponse
public static async getCurrentWallet() {
return WalletsController.getCurrent()
}

@CatchControllerError
public static async importMnemonic(params: { name: string, password: string, mnemonic: string }) {
@MapApiResponse
public static async importMnemonic(params: { name: string; password: string; mnemonic: string }) {
return WalletsController.importMnemonic(params)
}

@CatchControllerError
public static async importKeystore(params: { name: string, password: string, keystorePath: string }) {
@MapApiResponse
public static async importKeystore(params: { name: string; password: string; keystorePath: string }) {
return WalletsController.importKeystore(params)
}

@CatchControllerError
public static async createWallet(params: { name: string, password: string, mnemonic: string }) {
@MapApiResponse
public static async createWallet(params: { name: string; password: string; mnemonic: string }) {
return WalletsController.create(params)
}

@CatchControllerError
public static async updateWallet(params: { id: string, password: string, name: string, newPassword?: string }) {
WalletsController.update(params)
@MapApiResponse
public static async updateWallet(params: { id: string; password: string; name: string; newPassword?: string }) {
return WalletsController.update(params)
}

@CatchControllerError
@MapApiResponse
public static async deleteWallet({ id = '', password = '' }) {
return WalletsController.delete({ id, password })
}

@CatchControllerError
@MapApiResponse
public static async backupWallet({ id = '', password = '' }) {
return WalletsController.backup({ id, password })
}

@CatchControllerError
@MapApiResponse
public static async setCurrentWallet(id: string) {
return WalletsController.activate(id)
}

@CatchControllerError
@MapApiResponse
public static async getAddressesByWalletID(id: string) {
return WalletsController.getAllAddresses(id)
}

@CatchControllerError
@MapApiResponse
public static async sendCapacity(params: {
id: string
walletID: string
Expand All @@ -191,17 +195,17 @@ export default class ApiController {
return WalletsController.sendCapacity(params)
}

@CatchControllerError
@MapApiResponse
public static async sendTx(params: {
walletID: string
tx: TransactionWithoutHash,
tx: TransactionWithoutHash
password: string
description?: string
}) {
return WalletsController.sendTx(params)
}

@CatchControllerError
@MapApiResponse
public static async generateTx(params: {
walletID: string
items: {
Expand All @@ -214,12 +218,12 @@ export default class ApiController {
return WalletsController.generateTx(params)
}

@CatchControllerError
@MapApiResponse
public static async computeCycles(params: { walletID: string; capacities: string }) {
return WalletsController.computeCycles(params)
}

@CatchControllerError
@MapApiResponse
public static async updateAddressDescription(params: {
walletID: string
address: string
Expand All @@ -230,46 +234,46 @@ export default class ApiController {

// Networks

@CatchControllerError
@MapApiResponse
public static async getAllNetworks() {
return NetworksController.getAll()
}

@CatchControllerError
@MapApiResponse
public static async createNetwork({ name, remote, type = NetworkType.Normal, chain = 'ckb' }: Network) {
return NetworksController.create({ name, remote, type, chain })
}

@CatchControllerError
@MapApiResponse
public static async updateNetwork(id: NetworkID, options: Partial<Network>) {
return NetworksController.update(id, options)
}

@CatchControllerError
@MapApiResponse
public static async getCurrentNetworkID() {
return NetworksController.currentID()
}

@CatchControllerError
@MapApiResponse
public static async setCurrentNetowrk(id: NetworkID) {
return NetworksController.activate(id)
}

// Transactions

@CatchControllerError
@MapApiResponse
public static async getTransactionList(
params: Controller.Params.TransactionsByKeywords,
) {
return TransactionsController.getAllByKeywords(params)
}

@CatchControllerError
@MapApiResponse
public static async getTransaction(walletID: string, hash: string) {
return TransactionsController.get(walletID, hash)
}

@CatchControllerError
@MapApiResponse
public static async updateTransactionDescription(params: { hash: string; description: string }) {
return TransactionsController.updateDescription(params)
}
Expand All @@ -280,7 +284,7 @@ export default class ApiController {

// Misc

@CatchControllerError
@MapApiResponse
public static async updateSkipDataAndType(skip: boolean) {
return SkipDataAndTypeController.update(skip)
}
Expand Down
6 changes: 3 additions & 3 deletions packages/neuron-wallet/src/decorators/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import errorDecorators from './errors'
import mappers from './mappers'
import validatorDecorators from './validators'

export const { CatchControllerError } = errorDecorators
export const { MapApiResponse } = mappers
export const { Validate, Password, Required } = validatorDecorators

export default {
...errorDecorators,
...mappers,
...validatorDecorators,
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@ import logger from 'utils/logger'

const NODE_DISCONNECTED_CODE = 104

export const CatchControllerError = (target: any, name: string, descriptor: PropertyDescriptor) => {
export const MapApiResponse = (target: any, name: string, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value
return {
...descriptor,
async value(...args: any[]) {
async value(...args: any[]): Promise<any> {
try {
return await originalMethod(...args)
const res = await originalMethod(...args)
return JSON.stringify(res)
} catch (err) {
logger.error(`${target.name}.${name}:`, err)
if (err.code === 'ECONNREFUSED') {
err.code = NODE_DISCONNECTED_CODE
}
return {
const res = {
status: err.code || ResponseCode.Fail,
message: typeof err.message === 'string' ? { content: err.message } : err.message,
}
return JSON.stringify(res)
}
},
}
}

export default {
CatchControllerError,
}
export default { MapApiResponse }