Skip to content

Commit

Permalink
✨ feat: improve sdk connect flow (#99)
Browse files Browse the repository at this point in the history
  • Loading branch information
rustin01 authored Aug 7, 2024
1 parent 2e59a56 commit e522b1f
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 34 deletions.
25 changes: 9 additions & 16 deletions apps/wallet/src/stores/rpc.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { RPC } from '@mixer/postmessage-rpc'
import { AccountsChangedRequest, ChainChangedRequest, ClientExposeRPCMethod, ConnectResponse, GetBalanceRequest, GetBalanceResponse, HibitIdAssetType, HibitIdChainId, HibitIdExposeRPCMethod, RPC_SERVICE_NAME, SignMessageRequest, SignMessageResponse, TransferRequest, TransferResponse, WalletAccount, BridgePromise } from "@deland-labs/hibit-id-sdk"
import { AccountsChangedRequest, ChainChangedRequest, ClientExposeRPCMethod, GetBalanceRequest, GetBalanceResponse, HibitIdAssetType, HibitIdChainId, HibitIdExposeRPCMethod, RPC_SERVICE_NAME, SignMessageRequest, SignMessageResponse, TransferRequest, TransferResponse, WalletAccount } from "@deland-labs/hibit-id-sdk"
import hibitIdSession from './session';
import { makeAutoObservable } from 'mobx';
import { AssetInfo } from '../utils/chain/chain-wallets/types';
Expand All @@ -10,7 +10,6 @@ import { getChainByChainId } from '../utils/chain';

class RPCManager {
private _rpc: RPC | null = null
private _connectPromise: BridgePromise<ConnectResponse> | null = null

constructor() {
makeAutoObservable(this)
Expand Down Expand Up @@ -48,7 +47,7 @@ class RPCManager {
}

public notifyClose = () => {
this._connectPromise?.reject('User manually closed')
this.notifyConnected(null)
console.debug('[wallet notify close]')
this._rpc?.call(ClientExposeRPCMethod.CLOSE, {})
}
Expand All @@ -58,6 +57,11 @@ class RPCManager {
this._rpc?.call(ClientExposeRPCMethod.IFRAME_READY, {})
}

public notifyConnected = (account: WalletAccount | null) => {
console.debug('[wallet notify Connected]')
this._rpc?.call(ClientExposeRPCMethod.CONNECTED, account || {})
}

public notifyLoginChanged = (isLogin: boolean, sub?: string) => {
console.debug('[wallet notify login changed]', { isLogin, sub })
this._rpc?.call(ClientExposeRPCMethod.LOGIN_CHANGED, { isLogin, sub })
Expand All @@ -73,14 +77,6 @@ class RPCManager {
this._rpc?.call(ClientExposeRPCMethod.ACCOUNTS_CHANGED, { account } as AccountsChangedRequest)
}

public resolveConnect = (response: ConnectResponse) => {
this._connectPromise?.resolve(response)
}

public rejectConnect = (error: string) => {
this._connectPromise?.reject(error)
}

private onRpcGetAccount = async (): Promise<WalletAccount> => {
console.debug('[wallet on GetAccount]')
this.checkInit()
Expand All @@ -102,23 +98,20 @@ class RPCManager {
}
}

private onRpcConnect = async (input: ConnectRequest): Promise<ConnectResponse> => {
private onRpcConnect = async (input: ConnectRequest): Promise<void> => {
console.debug('[wallet on Connect]', { input })
const chainInfo = getChainByChainId(ChainId.fromString(input.chainId))
if (!chainInfo) {
throw new Error('Chain not supported')
}
this._connectPromise = new BridgePromise()
if (hibitIdSession.wallet) {
if (!hibitIdSession.chainInfo.chainId.equals(chainInfo.chainId)) {
await hibitIdSession.switchChain(chainInfo)
}
this.resolveConnect(await hibitIdSession.wallet.getAccount())
this.notifyConnected(await hibitIdSession.wallet.getAccount())
} else {
hibitIdSession.setChainInfo(chainInfo)
}
const res = await this._connectPromise.promise
return res
}

private onRpcGetBalance = async ({ assetType, chainId: hibitIdChainId, contractAddress, decimalPlaces }: GetBalanceRequest): Promise<GetBalanceResponse> => {
Expand Down
10 changes: 5 additions & 5 deletions apps/wallet/src/stores/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ export class HibitIdSession {

public setChainInfo = (chainInfo: ChainInfo) => {
this.chainInfo = chainInfo
localStorage.setItem(SESSION_CONFIG_KEY, JSON.stringify({
lastChainId: chainInfo.chainId.toString(),
} as SessionConfig))
}

public getValidAddress = async () => {
Expand All @@ -108,11 +111,11 @@ export class HibitIdSession {
console.log('[session connected]', this._account)

if (RUNTIME_ENV === RuntimeEnv.SDK) {
rpcManager.resolveConnect(await this.wallet.getAccount())
rpcManager.notifyConnected(await this.wallet.getAccount())
}
} catch (e) {
if (RUNTIME_ENV === RuntimeEnv.SDK && !(e instanceof HibitIDError && e.code === HibitIDErrorCode.INVALID_PASSWORD)) {
rpcManager.rejectConnect(e instanceof Error ? e.message : JSON.stringify(e))
rpcManager.notifyConnected(null)
}
throw e
}
Expand Down Expand Up @@ -194,9 +197,6 @@ export class HibitIdSession {
if (!wallet) {
throw new Error('Unsupported chain')
}
localStorage.setItem(SESSION_CONFIG_KEY, JSON.stringify({
lastChainId: chainInfo.chainId.toString(),
} as SessionConfig))
return wallet
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/lib/enums.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export enum ClientExposeRPCMethod {
CLOSE = 'close',
CONNECTED = 'connected',
IFRAME_READY = 'iframeReady',
LOGIN_CHANGED = 'loginChanged',
CHAIN_CHANGED = 'chainChanged',
Expand Down
3 changes: 1 addition & 2 deletions packages/sdk/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ export interface ConnectRequest {
chainId: HibitIdChainId
}

export interface ConnectResponse extends WalletAccount {
}
export interface ConnectedRequest extends WalletAccount {}

export interface SignMessageRequest {
message: string
Expand Down
31 changes: 20 additions & 11 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, ConnectResponse, GetBalanceRequest, GetBalanceResponse, HibitEnv, HibitIdEventHandlerMap, HibitIdPage, LoginChangedRequest, SignMessageResponse, TransferRequest, TransferResponse, WalletAccount } from './types';
import { AccountsChangedRequest, BridgePromise, ChainChangedRequest, ChainInfo, ConnectedRequest, GetBalanceRequest, GetBalanceResponse, HibitEnv, HibitIdEventHandlerMap, HibitIdPage, LoginChangedRequest, SignMessageResponse, TransferRequest, TransferResponse, WalletAccount } from './types';
import { ClientExposeRPCMethod, HibitIdChainId, HibitIdExposeRPCMethod } from './enums';
import { clamp } from './utils';

Expand All @@ -15,6 +15,7 @@ export class HibitIdWallet {
private _controller: HibitIdController | null = null
private _iframe: HibitIdIframe | null = null
private _iframeReadyPromise = new BridgePromise<boolean>()
private _connectPromise: BridgePromise<WalletAccount> | null = null
private _eventHandlers: {
accountsChanged: Array<HibitIdEventHandlerMap['accountsChanged']>
chainChanged: Array<HibitIdEventHandlerMap['chainChanged']>
Expand Down Expand Up @@ -56,21 +57,23 @@ export class HibitIdWallet {
this.showIframe()
}
console.debug('[sdk call Connect]', { chainId })
const res = await this._rpc!.call<ConnectResponse>(HibitIdExposeRPCMethod.CONNECT, {
this._connectPromise = new BridgePromise<WalletAccount>()
this._rpc!.call(HibitIdExposeRPCMethod.CONNECT, {
chainId,
})
if (!res) {
throw new Error('No response from wallet')
}
const res = await this._connectPromise?.promise
this._iframe!.hide()
this._controller?.setOpen(false)
this._connected = true
console.debug('[sdk connected]')

return {
address: res.address,
publicKey: res.publicKey,
if (res?.address) {
this._connected = true
console.debug('[sdk connected]')

return {
address: res.address,
publicKey: res.publicKey,
}
}
throw new Error('User manually canceled')
} catch (e) {
throw new Error(`Connect failed: ${e instanceof Error ? e.message : e}`)
}
Expand Down Expand Up @@ -197,6 +200,7 @@ export class HibitIdWallet {
// origin: 'example.com',
});
rpc.expose(ClientExposeRPCMethod.CLOSE, this.onRpcClose);
rpc.expose(ClientExposeRPCMethod.CONNECTED, this.onRpcConnected);
rpc.expose(ClientExposeRPCMethod.IFRAME_READY, this.onRpcIframeReady);
rpc.expose(ClientExposeRPCMethod.LOGIN_CHANGED, this.onRpcLoginChanged);
rpc.expose(ClientExposeRPCMethod.CHAIN_CHANGED, this.onRpcChainChanged);
Expand Down Expand Up @@ -285,4 +289,9 @@ export class HibitIdWallet {
console.debug('[sdk on IframeReady]')
this._iframeReadyPromise.resolve(true)
}

private onRpcConnected = (input: ConnectedRequest) => {
console.debug('[sdk on Connected]')
this._connectPromise?.resolve(input)
}
}

0 comments on commit e522b1f

Please sign in to comment.