Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat: improve rpc error return #120

Merged
merged 1 commit into from
Aug 14, 2024
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
157 changes: 111 additions & 46 deletions apps/wallet/src/stores/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { makeAutoObservable } from 'mobx';
import { AssetInfo, ChainWallet } from '../utils/chain/chain-wallets/types';
import { Chain, ChainAssetType, ChainId, ChainInfo, ChainNetwork, DecimalPlaces } from '../utils/basicTypes';
import BigNumber from 'bignumber.js';
import { ConnectRequest, SwitchChainRequest } from '../../../../packages/sdk/dist/lib/types';
import { ConnectRequest, GetAccountResponse, GetChainInfoResponse, SwitchChainRequest } from '../../../../packages/sdk/dist/lib/types';
import { getChainByChainId } from '../utils/chain';
import authManager from '../utils/auth';
import { prOidc } from '../utils/oidc';
Expand Down Expand Up @@ -57,7 +57,7 @@ class RPCManager {
}

public setWallet = (wallet: ChainWallet) => {
console.debug('[wallet set wallet]', wallet)
console.debug('[wallet set wallet]')
this._wallet = wallet
}

Expand Down Expand Up @@ -103,24 +103,69 @@ class RPCManager {
sessionStorage.removeItem(ACTIVE_DISCONNECT_STORAGE_KEY)
}

private onRpcGetAccount = async (): Promise<WalletAccount> => {
private onRpcGetAccount = async (): Promise<GetAccountResponse> => {
console.debug('[wallet on GetAccount]')
this.checkInit()
return await this._wallet!.getAccount()
try {
this.checkInit()
const account = await this._wallet!.getAccount()
return {
success: true,
data: account
}
} catch (e: any) {
return {
success: false,
errMsg: e.message || String(e)
}
}
}

private onRpcGetChainInfo = async () => {
private onRpcGetChainInfo = async (): Promise<GetChainInfoResponse> => {
console.debug('[wallet on GetChainInfo]')
this.checkInit()
return this._wallet!.chainInfo
try {
this.checkInit()
const info = this._wallet!.chainInfo
return {
success: true,
data: {
chainInfo: {
chainId: {
type: Number(info.chainId.type.value),
network: Number(info.chainId.network.value)
},
name: info.name,
fullName: info.fullName,
nativeAssetSymbol: info.nativeAssetSymbol,
nativeAssetDecimals: info.nativeAssetDecimals,
explorer: info.explorer,
rpcUrls: info.rpcUrls,
}
}
}
} catch (e: any) {
return {
success: false,
errMsg: e.message || String(e)
}
}
}

private onRpcSignMessage = async (input: SignMessageRequest): Promise<SignMessageResponse> => {
console.debug('[wallet on SignMessage]', { input })
this.checkInit()
const signature = await this._wallet!.signMessage(input.message)
return {
signature
try {
this.checkInit()
const signature = await this._wallet!.signMessage(input.message)
return {
success: true,
data: {
signature
}
}
} catch (e: any) {
return {
success: false,
errMsg: e.message || String(e)
}
}
}

Expand All @@ -143,23 +188,33 @@ class RPCManager {

private onRpcGetBalance = async ({ assetType, chainId: hibitIdChainId, contractAddress, decimalPlaces }: GetBalanceRequest): Promise<GetBalanceResponse> => {
console.debug('[wallet on GetBalance]', { assetType, chainId: hibitIdChainId, contractAddress, decimalPlaces })
this.checkInit()
if (!contractAddress && typeof assetType !== 'undefined' && assetType !== HibitIdAssetType.Native) {
throw new Error('Contract address is required for non-native assets')
}
const address = (await this._wallet!.getAccount()).address
const chainId = hibitIdChainId ? this.mapChainId(hibitIdChainId) : this._wallet!.chainInfo.chainId
const decimal = decimalPlaces ?? this._wallet!.chainInfo.nativeAssetDecimals
const assetInfo: AssetInfo = {
chainAssetType: assetType ? this.mapAssetType(assetType) : ChainAssetType.Native,
chain: chainId.type,
chainNetwork: chainId.network,
contractAddress: contractAddress || '',
decimalPlaces: new DecimalPlaces(decimal)
}
const balance = await this._wallet!.balanceOf(address, assetInfo)
return {
balance: balance.shiftedBy(decimal).toString()
try {
this.checkInit()
if (!contractAddress && typeof assetType !== 'undefined' && assetType !== HibitIdAssetType.Native) {
throw new Error('Contract address is required for non-native assets')
}
const address = (await this._wallet!.getAccount()).address
const chainId = hibitIdChainId ? this.mapChainId(hibitIdChainId) : this._wallet!.chainInfo.chainId
const decimal = decimalPlaces ?? this._wallet!.chainInfo.nativeAssetDecimals
const assetInfo: AssetInfo = {
chainAssetType: assetType ? this.mapAssetType(assetType) : ChainAssetType.Native,
chain: chainId.type,
chainNetwork: chainId.network,
contractAddress: contractAddress || '',
decimalPlaces: new DecimalPlaces(decimal)
}
const balance = await this._wallet!.balanceOf(address, assetInfo)
return {
success: true,
data: {
balance: balance.shiftedBy(decimal).toString()
}
}
} catch (e: any) {
return {
success: false,
errMsg: e.message || String(e)
}
}
}

Expand All @@ -172,23 +227,33 @@ class RPCManager {
decimalPlaces
}: TransferRequest): Promise<TransferResponse> => {
console.debug('[wallet on Transfer]', { toAddress, amount, assetType, chainId: hibitIdChainId, contractAddress, decimalPlaces })
this.checkInit()
if (typeof assetType !== 'undefined' && assetType !== HibitIdAssetType.Native && (!contractAddress || !decimalPlaces )) {
throw new Error('Contract address and decimal is required for non-native assets')
}
const chainId = hibitIdChainId ? this.mapChainId(hibitIdChainId) : this._wallet!.chainInfo.chainId
const decimal = decimalPlaces ?? this._wallet!.chainInfo.nativeAssetDecimals
const amountBn = new BigNumber(amount).shiftedBy(-decimal)
const assetInfo: AssetInfo = {
chainAssetType: assetType ? this.mapAssetType(assetType) : ChainAssetType.Native,
chain: chainId.type,
chainNetwork: chainId.network,
contractAddress: contractAddress || '',
decimalPlaces: new DecimalPlaces(decimal)
}
const txHash = await this._wallet!.transfer(toAddress, amountBn, assetInfo)
return {
txHash
try {
this.checkInit()
if (typeof assetType !== 'undefined' && assetType !== HibitIdAssetType.Native && (!contractAddress || !decimalPlaces )) {
throw new Error('Contract address and decimal is required for non-native assets')
}
const chainId = hibitIdChainId ? this.mapChainId(hibitIdChainId) : this._wallet!.chainInfo.chainId
const decimal = decimalPlaces ?? this._wallet!.chainInfo.nativeAssetDecimals
const amountBn = new BigNumber(amount).shiftedBy(-decimal)
const assetInfo: AssetInfo = {
chainAssetType: assetType ? this.mapAssetType(assetType) : ChainAssetType.Native,
chain: chainId.type,
chainNetwork: chainId.network,
contractAddress: contractAddress || '',
decimalPlaces: new DecimalPlaces(decimal)
}
const txHash = await this._wallet!.transfer(toAddress, amountBn, assetInfo)
return {
success: true,
data: {
txHash
}
}
} catch (e: any) {
return {
success: false,
errMsg: e.message || String(e)
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions packages/sdk/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export type {
WalletAccount,
ConnectRequest,
ConnectedRequest,
GetAccountResponse,
GetChainInfoResponse,
SignMessageRequest,
SignMessageResponse,
GetBalanceRequest,
Expand Down
28 changes: 17 additions & 11 deletions packages/sdk/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ export interface WalletAccount {
publicKey?: string
}

export type RpcBaseResponse<T> = {
success: false
errMsg: string
} | {
success: true
data: T
}

export interface ConnectRequest {
chainId: HibitIdChainId
}
Expand All @@ -66,9 +74,9 @@ export interface SignMessageRequest {
message: string
}

export interface SignMessageResponse {
export type SignMessageResponse = RpcBaseResponse<{
signature: string
}
}>

export interface GetBalanceRequest {
assetType?: HibitIdAssetType
Expand All @@ -77,9 +85,9 @@ export interface GetBalanceRequest {
decimalPlaces?: number
}

export interface GetBalanceResponse {
export type GetBalanceResponse = RpcBaseResponse<{
balance: string // in minimal unit (like wei for eth)
}
}>

export interface TransferRequest {
toAddress: string
Expand All @@ -90,17 +98,15 @@ export interface TransferRequest {
decimalPlaces?: number
}

export interface TransferResponse {
export type TransferResponse = RpcBaseResponse<{
txHash: string
}
}>

export interface GetAddressResponse {
address: string
}
export type GetAccountResponse = RpcBaseResponse<WalletAccount>

export interface GetChainInfoResponse {
export type GetChainInfoResponse = RpcBaseResponse<{
chainInfo: ChainInfo
}
}>

export interface ChainChangedRequest {
chainId: HibitIdChainId
Expand Down
59 changes: 36 additions & 23 deletions packages/sdk/src/lib/wallet.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RPC } from '@mixer/postmessage-rpc';
import { RPC_SERVICE_NAME } from './constants';
import { HibitIdController, HibitIdIframe } from './dom';
import { AccountsChangedRequest, BridgePromise, ChainChangedRequest, ChainInfo, ConnectedRequest, GetBalanceRequest, GetBalanceResponse, HibitIdEventHandlerMap, HibitIdWalletOptions, LoginChangedRequest, SignMessageResponse, TransferRequest, TransferResponse, WalletAccount } from './types';
import { AccountsChangedRequest, BridgePromise, ChainChangedRequest, ChainInfo, ConnectedRequest, GetAccountResponse, GetBalanceRequest, GetBalanceResponse, GetChainInfoResponse, HibitIdEventHandlerMap, HibitIdWalletOptions, LoginChangedRequest, SignMessageResponse, TransferRequest, TransferResponse, WalletAccount } from './types';
import { ClientExposeRPCMethod, HibitIdChainId, HibitIdExposeRPCMethod } from './enums';
import { clamp } from './utils';

Expand Down Expand Up @@ -84,61 +84,74 @@ export class HibitIdWallet {
}
}

public getAccount = async () => {
public getAccount = async (): Promise<WalletAccount> => {
console.debug('[sdk call GetAccount]')
this.assertConnected()
return await this._rpc?.call<WalletAccount>(HibitIdExposeRPCMethod.GET_ACCOUNT, {})
try {
const res = await this._rpc?.call<GetAccountResponse>(HibitIdExposeRPCMethod.GET_ACCOUNT, {})
if (!res?.success) {
throw new Error(res?.errMsg)
}
return res.data
} catch (e: any) {
throw new Error(`Get account failed: ${this.getRpcErrorMessage(e)}`)
}
}

public getChainInfo = async () => {
public getChainInfo = async (): Promise<ChainInfo> => {
console.debug('[sdk call GetChainInfo]')
this.assertConnected()
const info = await this._rpc?.call<any>(HibitIdExposeRPCMethod.GET_CHAIN_INFO, {})
return {
chainId: {
type: Number(info.chainId.type.value),
network: Number(info.chainId.network.value)
},
name: info.name,
fullName: info.fullName,
nativeAssetSymbol: info.nativeAssetSymbol,
nativeAssetDecimals: info.nativeAssetDecimals,
explorer: info.explorer,
rpcUrls: info.rpcUrls,
} as ChainInfo
try {
const res = await this._rpc?.call<GetChainInfoResponse>(HibitIdExposeRPCMethod.GET_CHAIN_INFO, {})
if (!res?.success) {
throw new Error(res?.errMsg)
}
return res.data.chainInfo
} catch (e: any) {
throw new Error(`Get chainInfo failed: ${this.getRpcErrorMessage(e)}`)
}
}

public signMessage = async (message: string) => {
public signMessage = async (message: string): Promise<string> => {
console.debug('[sdk call SignMessage]', { message })
this.assertConnected()
try {
const res = await this._rpc?.call<SignMessageResponse>(HibitIdExposeRPCMethod.SIGN_MESSAGE, {
message,
})
return res?.signature ?? null
if (!res?.success) {
throw new Error(res?.errMsg)
}
return res.data.signature ?? null
} catch (e: any) {
throw new Error(`Sign message failed: ${this.getRpcErrorMessage(e)}`)
}
}

public getBalance = async (option?: GetBalanceRequest) => {
public getBalance = async (option?: GetBalanceRequest): Promise<string> => {
const request: GetBalanceRequest = option || {}
console.debug('[sdk call GetBalance]', { request })
this.assertConnected()
try {
const res = await this._rpc?.call<GetBalanceResponse>(HibitIdExposeRPCMethod.GET_BALANCE, request)
return res?.balance ?? null
if (!res?.success) {
throw new Error(res?.errMsg)
}
return res.data.balance ?? null
} catch (e: any) {
throw new Error(`Get balance failed: ${this.getRpcErrorMessage(e)}`)
}
}

public transfer = async (option: TransferRequest) => {
public transfer = async (option: TransferRequest): Promise<string> => {
console.debug('[sdk call Transfer]', { option })
this.assertConnected()
try {
const res = await this._rpc?.call<TransferResponse>(HibitIdExposeRPCMethod.TRANSFER, option)
return res?.txHash ?? null
if (!res?.success) {
throw new Error(res?.errMsg)
}
return res.data.txHash ?? null
} catch (e: any) {
console.error(e, JSON.stringify(e))
throw new Error(`Transfer failed: ${this.getRpcErrorMessage(e)}`)
Expand Down
Loading