From 2f25ab9e4245a2d6a40905cd6f0405723ec620eb Mon Sep 17 00:00:00 2001 From: ChenWei Date: Fri, 27 Sep 2024 16:31:54 +0800 Subject: [PATCH 01/15] feat: auth login&logout&islogin optimize --- xterio-auth/README.md | 14 +++++++++---- xterio-auth/src/modules/XterAuth.ts | 21 ++++++++----------- .../XterAuthModal/XertAuthModalStore.ts | 2 +- xterio-auth/src/utils/const.ts | 3 ++- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/xterio-auth/README.md b/xterio-auth/README.md index eb5ae5b..3d71a8b 100644 --- a/xterio-auth/README.md +++ b/xterio-auth/README.md @@ -26,7 +26,7 @@ unsubscribe() //unsubscribe //or -XterEventEmiter.unsubscribe()//unsubscribe +XterEventEmiter.unsubscribe()//unsubscribe all account event //3. SignIn XterioAuth.login() @@ -95,9 +95,15 @@ XterioAuth.logout() ``` #### `getIdToken()` -check whether the idToken is valid. If the idToken is invalid, empty string is returned, else the idToken. +check whether the idToken is valid. If the idToken is invalid, empty string is returned, else the non-empty str. ```ts -await XterioAuth.getIdToken() //string +XterioAuth.getIdToken() //Promise +``` + +#### `isLogin()` +depend user is login to xterio +```ts +XterioAuth.isLogin() //Promise ``` #### `getUserInfo(p:Function)` @@ -130,7 +136,7 @@ await XterioAuth.openPage(PageType.nft, OpenPageMode.iframeUri, { ``` ### 4.2 Property -#### `isLogin` +#### `isLogin` (`deprecated`) whether to log in ```ts XterioAuth.isLogin //boolean diff --git a/xterio-auth/src/modules/XterAuth.ts b/xterio-auth/src/modules/XterAuth.ts index 7e3bd91..a8a94a5 100644 --- a/xterio-auth/src/modules/XterAuth.ts +++ b/xterio-auth/src/modules/XterAuth.ts @@ -11,9 +11,6 @@ import { decode } from 'js-base64' import { openPage } from './XterPage' export class XterioAuth { - static get isLogin() { - return !!XterioAuthUserInfoManager.userInfo?.uuid - } static get userinfo() { return XterioAuthUserInfoManager.userInfo } @@ -92,8 +89,13 @@ export class XterioAuth { } static async getIdToken() { + /// idtoken not expired or refreshed if the promise return non-empty string return await this.checkToken('getIdToken') } + static async isLogin() { + const _token = await this.getIdToken() + return !!_token + } static async init(config: Partial, env?: Env) { const { @@ -138,7 +140,7 @@ export class XterioAuth { }) XterEventEmiter.subscribe(() => { //req expired logic - this.clearData() + this.logout() }, XTERIO_EVENTS.Expired) // init XterAuthLoginModal @@ -161,6 +163,7 @@ export class XterioAuth { XLog.debug('logout success') this.clearData() XterAuthModal?.instance?.store?.logout() + XterEventEmiter.emit(XTERIO_EVENTS.LOGOUT) } static async login(mode?: LoginType) { if (!XterioAuthInfo.config) { @@ -176,14 +179,8 @@ export class XterioAuth { qs.stringify({ client_id, redirect_uri, response_type, scope, mode, logout }) } - if (XterioAuth.isLogin) { - //logined, callback the account info - XLog.debug('already logined.') - XterEventEmiter.emit(XTERIO_EVENTS.ACCOUNT, XterioAuthUserInfoManager.userInfo) - return - } - if (XterioAuth.isVaildIdToken) { - //idtoken not expired + const _islogin = await XterioAuth.isLogin() + if (_islogin) { XLog.debug('get userinfo') return XterioAuthService.getUserInfo() } diff --git a/xterio-auth/src/modules/XterAuthModal/XertAuthModalStore.ts b/xterio-auth/src/modules/XterAuthModal/XertAuthModalStore.ts index a2b2fee..217e011 100644 --- a/xterio-auth/src/modules/XterAuthModal/XertAuthModalStore.ts +++ b/xterio-auth/src/modules/XterAuthModal/XertAuthModalStore.ts @@ -103,7 +103,7 @@ export class XterAuthModalStore extends ModalObservable { private async refreshUserInfo() { XterEventEmiter.subscribe((res: IUserInfo) => { this.userState.userInfo = res - this.userState.isLogin = XterioAuth.isLogin + this.userState.isLogin = !!res.uuid }) /* const { refreshToken, idToken } = this.tokenManager diff --git a/xterio-auth/src/utils/const.ts b/xterio-auth/src/utils/const.ts index 9904262..ec1c6ee 100644 --- a/xterio-auth/src/utils/const.ts +++ b/xterio-auth/src/utils/const.ts @@ -27,7 +27,8 @@ export const XTERIO_EVENTS = { LOGIN: 'xter_auth_login_success', ACCOUNT: 'xter_auth_response_userinfo', REQ_ACCOUNT: 'xter_auth_request_userinfo', - Expired: 'xter_auth_req_expired' + Expired: 'xter_auth_req_expired', + LOGOUT: 'xter_auth_logout' } export const XTERIO_CONST = { LOGIN_TYPE: 'xter_auth_login_type', From cfb9b41c41b1be8fbe3ad3e497df8754ee85a687 Mon Sep 17 00:00:00 2001 From: ChenWei Date: Sun, 29 Sep 2024 11:12:43 +0800 Subject: [PATCH 02/15] =?UTF-8?q?feat:=20auth=20page=20=E5=9C=B0=E5=9D=80?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xterio-auth/src/interfaces/loginInfo.ts | 6 ++++++ xterio-auth/src/modules/XterPage.ts | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/xterio-auth/src/interfaces/loginInfo.ts b/xterio-auth/src/interfaces/loginInfo.ts index ef6e600..4bbb909 100644 --- a/xterio-auth/src/interfaces/loginInfo.ts +++ b/xterio-auth/src/interfaces/loginInfo.ts @@ -124,8 +124,14 @@ export enum PageType { wallet = 'wallet' } export interface PageOptionParam { + /** asset page */ active?: 'ingame' | 'onchain' + /** nft page */ keyword?: string + /** nft page */ collection?: string + /** nft page */ features?: { k: string; initValues: (number | string)[]; type?: string }[] + /** platform os type */ + platform?: 'pc' | 'mobile' } diff --git a/xterio-auth/src/modules/XterPage.ts b/xterio-auth/src/modules/XterPage.ts index 1560647..308bf76 100644 --- a/xterio-auth/src/modules/XterPage.ts +++ b/xterio-auth/src/modules/XterPage.ts @@ -28,7 +28,17 @@ const getOtac = async () => { } export const openPage = async (page: PageType, mode?: OpenPageMode, options?: PageOptionParam) => { - const { active = 'ingame', keyword, collection, features } = options || {} + const { active = 'ingame', keyword, collection, features, platform } = options || {} + const isMobile = platform === 'mobile' + let _p: Record = { + hide_wallet_entrance: true, + hide_account_entrance: true, + hide_menu_entrance: true, + hide_sign_out: true, + hide_footer: true, + disable_logo_click: true + } + const _type = mode || OpenPageMode.alert const app_id = XterioAuthInfo.config?.app_id || '' if (!app_id) { @@ -37,12 +47,14 @@ export const openPage = async (page: PageType, mode?: OpenPageMode, options?: Pa const basePage = XterioAuthInfo.pageURL let uri = '' if (page === PageType.asset) { + _p = { ..._p, hide_game_select: true, hide_game_tokens: true } uri = `${basePage}/asset?source=1&app_id=${app_id}&active=${active}` } else if (page === PageType.account) { uri = `${basePage}/settings?source=1` } else if (page === PageType.wallet) { uri = `${basePage}/settings?source=1&tab=wallet` } else if (page === PageType.nft) { + _p = { ..._p, hide_game_filter: true } let query: Record = { source: 1, app_id } if (collection) { query = { ...query, collection } @@ -56,6 +68,9 @@ export const openPage = async (page: PageType, mode?: OpenPageMode, options?: Pa uri = `${basePage}/marketplace?${qs.stringify(query)}` } + if (isMobile) { + uri += `&${qs.stringify(_p)}` + } const otac = await getOtac() if (otac) { uri += `&_otac=${otac}` From 78314dc878a87cd494e19dfae94cf3d4fddd4d45 Mon Sep 17 00:00:00 2001 From: ChenWei Date: Mon, 30 Sep 2024 11:23:25 +0800 Subject: [PATCH 03/15] =?UTF-8?q?feat:=20auth=20=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xterio-auth/index.html | 1 + xterio-auth/src/main.ts | 4 +- xterio-auth/src/modules/XterAuth.ts | 58 +++++++++++++++++++++------- xterio-auth/src/modules/XterCache.ts | 14 ++++--- xterio-auth/src/utils/timer.ts | 18 +++++++++ 5 files changed, 76 insertions(+), 19 deletions(-) create mode 100644 xterio-auth/src/utils/timer.ts diff --git a/xterio-auth/index.html b/xterio-auth/index.html index 367c5bc..4a151a6 100644 --- a/xterio-auth/index.html +++ b/xterio-auth/index.html @@ -22,6 +22,7 @@

Hello, Webpack!

+
是否登录
默认登录
邮箱登录
小程序登录
diff --git a/xterio-auth/src/main.ts b/xterio-auth/src/main.ts index 930e323..34cb1d8 100644 --- a/xterio-auth/src/main.ts +++ b/xterio-auth/src/main.ts @@ -41,7 +41,9 @@ const changePage = () => { el.innerText = currentPageName } } - +addClick('isLogin', () => { + alert(XterioAuth.isLogin) +}) addClick('login', () => { XterioAuth.login() }) diff --git a/xterio-auth/src/modules/XterAuth.ts b/xterio-auth/src/modules/XterAuth.ts index afd9d2c..e90e849 100644 --- a/xterio-auth/src/modules/XterAuth.ts +++ b/xterio-auth/src/modules/XterAuth.ts @@ -9,11 +9,29 @@ import qs from 'query-string' import { XterioCache } from './XterCache' import { decode } from 'js-base64' import { openPage } from './XterPage' +import { XTimeOut } from 'utils/timer' export class XterioAuth { + private static _timer?: XTimeOut static get userinfo() { return XterioAuthUserInfoManager.userInfo } + private static setTokenTimer(duration: number) { + // const duration = 10000 + if (duration < 0) return + if (!this._timer) { + this._timer = new XTimeOut() + } + this._timer.addTimeout(() => { + const refreshToken = XterioAuthTokensManager.refreshToken + this.isLogin = false + XLog.info('the token timer, reset isLogin:', false) + if (refreshToken) { + XLog.info('the token timer, refresh token again') + this.checkToken('tokenTimer') + } + }, duration) + } private static get isVaildIdToken() { const id_token = XterioAuthTokensManager.idToken @@ -29,6 +47,7 @@ export class XterioAuth { try { const { aud, exp = 0, sub } = JSON.parse(decode(payload)) as Payload + this.setTokenTimer((exp - 60) * 1000 - Date.now()) const isExpire = !aud || Date.now() > (exp - 60) * 1000 return !isExpire } catch (error) { @@ -37,20 +56,30 @@ export class XterioAuth { } } + private static _islogin: boolean = this.isVaildIdToken + private static set isLogin(f: boolean) { + this._islogin = f + } + static get isLogin() { + return this._islogin + } + private static async checkToken(_flag: string = 'init') { const _tokens = XterioCache.tokens if (_tokens) { XterioAuthTokensManager.setTokens(_tokens) } const refresh_token = XterioAuthTokensManager.refreshToken - if (!XterioAuth.isVaildIdToken && refresh_token) { - //req tokens by refresh + let isvalid = XterioAuth.isVaildIdToken + if (!isvalid && refresh_token) { + // token invalid, req tokens by refresh XLog.info('refresh tokens') const res = await XterioAuthService.refreshTokenService(refresh_token) XterioAuthTokensManager.setTokens({ refresh_token, id_token: res.id_token, access_token: res.access_token }) + //again check + isvalid = XterioAuth.isVaildIdToken } - - const isvalid = XterioAuth.isVaildIdToken + this.isLogin = isvalid XLog.info('check the tokens valid status:', isvalid) if (!isvalid) { XLog.info('clear cache data') @@ -93,10 +122,6 @@ export class XterioAuth { /// idtoken not expired or refreshed if the promise return non-empty string return await this.checkToken('getIdToken') } - static async isLogin() { - const _token = await this.getIdToken() - return !!_token - } static async init(config: Partial, env?: Env) { const { @@ -134,14 +159,22 @@ export class XterioAuth { qs.stringify({ client_id, redirect_uri, response_type, scope, mode, logout }) XterioAuthInfo.config = _config + XLog.debug('auth initial') + this._timer = new XTimeOut() + XterEventEmiter.clear() XterEventEmiter.subscribe((info: IUserInfo) => { XLog.debug('the userinfo callback count=', XterioAuthInfo.onAccount.length) XterioAuthInfo.onAccount.map((f) => f(info)) }) XterEventEmiter.subscribe(() => { - //req expired logic - this.logout() + //req expired logic, + //TODO: + XLog.debug('req 401, refresh token') + XterioCache.deleteTokens(XTERIO_CONST.ID_TOKEN) + XterioAuthTokensManager.setTokens(XterioCache.tokens) + this.checkToken() + XterEventEmiter.emit(XTERIO_EVENTS.LOGOUT) }, XTERIO_EVENTS.Expired) // init XterAuthLoginModal @@ -155,6 +188,7 @@ export class XterioAuth { }) } private static clearData() { + this.isLogin = false XterioCache.deleteTokens() XterioCache.deleteUserInfo() XterioAuthTokensManager.removeTokens() @@ -179,9 +213,7 @@ export class XterioAuth { `/account/v1/oauth2/authorize?` + qs.stringify({ client_id, redirect_uri, response_type, scope, mode, logout }) } - - const _islogin = await XterioAuth.isLogin() - if (_islogin) { + if (this.isLogin) { XLog.debug('get userinfo') return XterioAuthService.getUserInfo() } diff --git a/xterio-auth/src/modules/XterCache.ts b/xterio-auth/src/modules/XterCache.ts index b930f78..2c4b166 100644 --- a/xterio-auth/src/modules/XterCache.ts +++ b/xterio-auth/src/modules/XterCache.ts @@ -16,7 +16,7 @@ export class XterioCache { Cookies.set(XTERIO_CONST.ID_TOKEN, id_token, { expires: 1 }) Cookies.set(XTERIO_CONST.REFRESH_TOKEN, refresh_token) } - static get tokens(): ITokenRes | undefined { + static get tokens(): ITokenRes { const _t: ITokenRes = { access_token: Cookies.get(XTERIO_CONST.ACCESS_TOKEN) || '', id_token: Cookies.get(XTERIO_CONST.ID_TOKEN) || '', @@ -24,10 +24,14 @@ export class XterioCache { } return _t } - static deleteTokens() { - Cookies.remove(XTERIO_CONST.ACCESS_TOKEN) - Cookies.remove(XTERIO_CONST.REFRESH_TOKEN) - Cookies.remove(XTERIO_CONST.ID_TOKEN) + static deleteTokens(key?: string) { + if (key) { + Cookies.remove(key) + } else { + Cookies.remove(XTERIO_CONST.ACCESS_TOKEN) + Cookies.remove(XTERIO_CONST.REFRESH_TOKEN) + Cookies.remove(XTERIO_CONST.ID_TOKEN) + } } static set userInfo(value: IUserInfo) { diff --git a/xterio-auth/src/utils/timer.ts b/xterio-auth/src/utils/timer.ts new file mode 100644 index 0000000..497817c --- /dev/null +++ b/xterio-auth/src/utils/timer.ts @@ -0,0 +1,18 @@ +import { XLog } from './logger' + +export class XTimeOut { + private _timer?: NodeJS.Timeout + addTimeout(callback: () => void, timeout: number) { + this.removeTimeout() + XLog.info('the timer init') + this._timer = setTimeout(() => { + callback() + }, timeout) + } + removeTimeout() { + if (this._timer) { + XLog.info('the timer clear') + clearTimeout(this._timer) + } + } +} From 25e698e3da067c280752c45eca6758777779ba0b Mon Sep 17 00:00:00 2001 From: ChenWei Date: Mon, 30 Sep 2024 18:05:31 +0800 Subject: [PATCH 04/15] =?UTF-8?q?feat:=20=E8=A7=A3=E8=80=A6auth&wallet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xterio-auth/src/modules/XterAuth.ts | 36 ++++++++++--------- xterio-auth/src/modules/XterAuthInfo.ts | 4 +++ xterio-auth/src/utils/const.ts | 3 +- xterio-auth/src/utils/timer.ts | 35 ++++++++++++++++-- xterio-wallet/src/App.tsx | 46 +++++++++++++----------- xterio-wallet/src/contexts/index.tsx | 48 +++++-------------------- 6 files changed, 93 insertions(+), 79 deletions(-) diff --git a/xterio-auth/src/modules/XterAuth.ts b/xterio-auth/src/modules/XterAuth.ts index e90e849..ecf2adf 100644 --- a/xterio-auth/src/modules/XterAuth.ts +++ b/xterio-auth/src/modules/XterAuth.ts @@ -9,20 +9,16 @@ import qs from 'query-string' import { XterioCache } from './XterCache' import { decode } from 'js-base64' import { openPage } from './XterPage' -import { XTimeOut } from 'utils/timer' +import { LoadingState, XTimeOut } from 'utils/timer' export class XterioAuth { - private static _timer?: XTimeOut static get userinfo() { return XterioAuthUserInfoManager.userInfo } private static setTokenTimer(duration: number) { // const duration = 10000 if (duration < 0) return - if (!this._timer) { - this._timer = new XTimeOut() - } - this._timer.addTimeout(() => { + XTimeOut.getInstance().addTimeout(() => { const refreshToken = XterioAuthTokensManager.refreshToken this.isLogin = false XLog.info('the token timer, reset isLogin:', false) @@ -63,6 +59,9 @@ export class XterioAuth { static get isLogin() { return this._islogin } + static resetIsLogin() { + this.isLogin = this.isVaildIdToken + } private static async checkToken(_flag: string = 'init') { const _tokens = XterioCache.tokens @@ -79,7 +78,7 @@ export class XterioAuth { //again check isvalid = XterioAuth.isVaildIdToken } - this.isLogin = isvalid + // this.isLogin = isvalid XLog.info('check the tokens valid status:', isvalid) if (!isvalid) { XLog.info('clear cache data') @@ -160,21 +159,26 @@ export class XterioAuth { XterioAuthInfo.config = _config XLog.debug('auth initial') - this._timer = new XTimeOut() - XterEventEmiter.clear() + // XterEventEmiter.clear() + XterEventEmiter.subscribe(() => { + this.resetIsLogin() + }, XTERIO_EVENTS.REFRESH_IS_LOGIN) + XterEventEmiter.subscribe((info: IUserInfo) => { XLog.debug('the userinfo callback count=', XterioAuthInfo.onAccount.length) XterioAuthInfo.onAccount.map((f) => f(info)) }) - XterEventEmiter.subscribe(() => { + + XterEventEmiter.subscribe(async () => { //req expired logic, - //TODO: - XLog.debug('req 401, refresh token') - XterioCache.deleteTokens(XTERIO_CONST.ID_TOKEN) - XterioAuthTokensManager.setTokens(XterioCache.tokens) - this.checkToken() - XterEventEmiter.emit(XTERIO_EVENTS.LOGOUT) + LoadingState.getInstance().execute(async () => { + XLog.debug('req 401, refresh token') + XterEventEmiter.emit(XTERIO_EVENTS.LOGOUT) + XterioCache.deleteTokens(XTERIO_CONST.ID_TOKEN) + XterioAuthTokensManager.setTokens(XterioCache.tokens) + await this.checkToken() + }) }, XTERIO_EVENTS.Expired) // init XterAuthLoginModal diff --git a/xterio-auth/src/modules/XterAuthInfo.ts b/xterio-auth/src/modules/XterAuthInfo.ts index 7ffab16..0ff2a8c 100644 --- a/xterio-auth/src/modules/XterAuthInfo.ts +++ b/xterio-auth/src/modules/XterAuthInfo.ts @@ -1,6 +1,8 @@ import type { Env, ISSoTokensParams, ITokenRes, IUserInfo } from 'interfaces/loginInfo' import { LoginType } from 'interfaces/loginInfo' import { XterioCache } from './XterCache' +import { XterEventEmiter } from './XterEventEmitter' +import { XTERIO_EVENTS } from 'utils' export class XterioAuthInfo { /** client id */ @@ -34,6 +36,8 @@ export class XterioAuthTokensManager { const { id_token = '', access_token = '', refresh_token = '' } = value || {} XterioAuthInfo.tokens = { id_token, access_token, refresh_token } XterioCache.tokens = value + //变更tokens,刷新islogin + XterEventEmiter.emit(XTERIO_EVENTS.REFRESH_IS_LOGIN) } static removeTokens() { XterioAuthInfo.tokens = undefined diff --git a/xterio-auth/src/utils/const.ts b/xterio-auth/src/utils/const.ts index ec1c6ee..e60a705 100644 --- a/xterio-auth/src/utils/const.ts +++ b/xterio-auth/src/utils/const.ts @@ -28,7 +28,8 @@ export const XTERIO_EVENTS = { ACCOUNT: 'xter_auth_response_userinfo', REQ_ACCOUNT: 'xter_auth_request_userinfo', Expired: 'xter_auth_req_expired', - LOGOUT: 'xter_auth_logout' + LOGOUT: 'xter_auth_logout', + REFRESH_IS_LOGIN: 'xter_auth_refresh_is_login' } export const XTERIO_CONST = { LOGIN_TYPE: 'xter_auth_login_type', diff --git a/xterio-auth/src/utils/timer.ts b/xterio-auth/src/utils/timer.ts index 497817c..a6d952d 100644 --- a/xterio-auth/src/utils/timer.ts +++ b/xterio-auth/src/utils/timer.ts @@ -1,18 +1,47 @@ import { XLog } from './logger' -export class XTimeOut { +class Singleton { + private static instances: { [key: string]: any } = {} + constructor() { + // + } + static getInstance(this: new () => T): T { + const className = this.name + if (!Singleton.instances[className]) { + Singleton.instances[className] = new this() + } + return Singleton.instances[className] + } +} + +export class XTimeOut extends Singleton { private _timer?: NodeJS.Timeout addTimeout(callback: () => void, timeout: number) { this.removeTimeout() - XLog.info('the timer init') + XLog.debug('the timer init') this._timer = setTimeout(() => { callback() }, timeout) } removeTimeout() { if (this._timer) { - XLog.info('the timer clear') + XLog.debug('the timer clear') clearTimeout(this._timer) } } } +// XTimeOut.getInstance().addTimeout(() => { }, 2000) + +export class LoadingState extends Singleton { + private isLoading: boolean = false + + async execute(action: () => void | Promise) { + if (this.isLoading) return + this.isLoading = true + try { + await action() + } finally { + this.isLoading = false + } + } +} diff --git a/xterio-wallet/src/App.tsx b/xterio-wallet/src/App.tsx index 304babc..64b2dcd 100644 --- a/xterio-wallet/src/App.tsx +++ b/xterio-wallet/src/App.tsx @@ -1,9 +1,9 @@ import './App.css' import { useXterioTransaction, useXterioWalletContext } from './index' -import { useState } from 'react' +import { useEffect, useState } from 'react' import { Contract, ContractInterface, ethers } from 'ethers' import { ERC20_ABI } from './common/abi' -import { LoginType } from '@xterio-sdk/auth' +import { IUserInfo, LoginType, XterEventEmiter, XTERIO_EVENTS, XterioAuth } from '@xterio-sdk/auth' /** * 区分区块链网络的名称,平台前后端统一定义的枚举类型 @@ -69,19 +69,8 @@ export const getContract = (network: NETWORK_NAME, contractAddress: string, abi: } function App() { - const { - userinfo, - isLogin, - login, - logout, - aaAddress, - isConnect, - disconnectWallet, - openWallet, - obtainWallet, - connectWallet, - signMessage - } = useXterioWalletContext() + const { aaAddress, isConnect, disconnectWallet, openWallet, obtainWallet, connectWallet, signMessage } = + useXterioWalletContext() const contractAddress = '0x12065F0d03cd1Bd280565069164F9E803c2DA988' const abi = ERC20_ABI @@ -120,17 +109,34 @@ function App() { } } + const [userinfo, setUserInfo] = useState({}) + useEffect(() => { + console.log('[xtest] ---- add listener') + const unsubscribeInfo = XterEventEmiter.subscribe((res: IUserInfo) => { + setUserInfo(res) + }, XTERIO_EVENTS.ACCOUNT) + + const unsubscribe = XterEventEmiter.subscribe(() => { + setUserInfo({}) + }, XTERIO_EVENTS.LOGOUT) + return () => { + console.log('[xtest] ---- remove listener') + unsubscribeInfo?.() + unsubscribe?.() + } + }, []) + return ( <>

Xterio SDK

xterio auth sdk
-

是否登录: {isLogin ? 'true' : 'false'}

+

是否登录: {XterioAuth.isLogin ? 'true' : 'false'}

用户信息: {userinfo ? JSON.stringify(userinfo) : ''}

- - - - + + + +
xterio wallet sdk
diff --git a/xterio-wallet/src/contexts/index.tsx b/xterio-wallet/src/contexts/index.tsx index d9e3fe2..0845c7e 100644 --- a/xterio-wallet/src/contexts/index.tsx +++ b/xterio-wallet/src/contexts/index.tsx @@ -1,12 +1,5 @@ import { createContext, PropsWithChildren, useCallback, useContext, useEffect, useRef, useState } from 'react' -import { - IUserInfo, - LoginType, - XterEventEmiter, - XTERIO_EVENTS, - XterioAuth, - XterioAuthTokensManager -} from '@xterio-sdk/auth' +import { IUserInfo, XterEventEmiter, XTERIO_EVENTS, XterioAuth, XterioAuthTokensManager } from '@xterio-sdk/auth' import { AuthCoreContextProvider, getAuthCoreModalOptions, usePnWallet } from './pnWallet' import { PnWalletModal } from 'src/templates/PnWalletModal' import { createRoot } from 'react-dom/client' @@ -25,10 +18,7 @@ const initState = { obtainWallet: () => {} } interface IWalletContextState extends Pick { - userinfo: IUserInfo | undefined - isLogin: boolean - login(mode?: LoginType): Promise - logout(): Promise + isLoaded: boolean aaAddress: string isConnect: boolean openWallet(): void @@ -54,8 +44,7 @@ const WalletContextProvider: React.FC() const [aaAddress, setAaAddress] = useState('') - const [userinfo, setUserInfo] = useState(XterioAuth.userinfo) - const [isLogin, setIsLogin] = useState(XterioAuth.isLogin) + const [isLoaded, setIsLoaded] = useState(false) const { getWalletIFrame, @@ -79,7 +68,7 @@ const WalletContextProvider: React.FC { - if (!isLogin) { + if (!XterioAuth.isLogin) { XLog.info('please login first') return } @@ -120,7 +109,7 @@ const WalletContextProvider: React.FC { @@ -170,27 +159,12 @@ const WalletContextProvider: React.FC { - await XterioAuth.login(mode) - }, []) - - const logout = useCallback(async () => { - await disconnectWallet() - await XterioAuth.logout() - setUserInfo(undefined) - setIsLogin(false) - setAaAddress('') - }, [disconnectWallet]) - const initLogic = useCallback( async (info?: IUserInfo) => { const _addr = info?.wallet?.find((i) => i.source === 2)?.address || '' - const _islogin = !!info?.uuid - setUserInfo(info) - setIsLogin(_islogin) setAaAddress(_addr) - if (_islogin && _addr && !isPnLoginedRef.current) { + if (XterioAuth.isLogin && _addr && !isPnLoginedRef.current) { XLog.debug('init logic, reconnect wallet') await connectWallet() } @@ -214,11 +188,10 @@ const WalletContextProvider: React.FC { //request token expired, clear state data XLog.info('emiter req expired') - setUserInfo(undefined) - setIsLogin(false) setAaAddress('') disconnectWallet() - }, XTERIO_EVENTS.Expired) + }, XTERIO_EVENTS.LOGOUT) + setIsLoaded(true) return () => { if (mounted) { unsubscribe?.() @@ -229,10 +202,7 @@ const WalletContextProvider: React.FC Date: Fri, 11 Oct 2024 16:24:39 +0800 Subject: [PATCH 05/15] feat: xterauth example update --- examples/example-auth-react/src/App.tsx | 23 +++++- examples/example-auth-vue/src/App.vue | 13 +++- examples/example-auth/index.html | 40 ++++++++-- examples/example-auth/src/index.js | 97 ++++++++++++++++++------- xterio-auth/README.md | 8 +- xterio-auth/index.html | 31 ++++---- xterio-auth/src/main.ts | 2 +- xterio-auth/src/modules/XterPage.ts | 5 +- xterio-auth/vite.config.mts | 9 +++ 9 files changed, 165 insertions(+), 63 deletions(-) diff --git a/examples/example-auth-react/src/App.tsx b/examples/example-auth-react/src/App.tsx index 0bc1743..0837968 100644 --- a/examples/example-auth-react/src/App.tsx +++ b/examples/example-auth-react/src/App.tsx @@ -3,10 +3,18 @@ import reactLogo from './assets/react.svg' import viteLogo from '/vite.svg' import './App.css' -import { IUserInfo, LoginType, OpenPageMode, PageType, XterEventEmiter, XterioAuth } from '@xterio-sdk/auth' +import { + IUserInfo, + LoginType, + OpenPageMode, + PageType, + XterEventEmiter, + XTERIO_EVENTS, + XterioAuth +} from '@xterio-sdk/auth' function App() { - const [userinfo, setUserinfo] = useState('') + const [userinfo, setUserinfo] = useState('') const [isLogin, setIsLogin] = useState(XterioAuth.isLogin) const [currentPage, setCurrentPage] = useState(PageType.asset) @@ -17,8 +25,17 @@ function App() { setUserinfo(JSON.stringify(res)) setIsLogin(XterioAuth.isLogin) }) + + //退出登录刷新本地islogin跟userinfo状态 + const logout_unsub = XterEventEmiter.subscribe(() => { + console.log('logout auth, and deal page state data') + setIsLogin(XterioAuth.isLogin) + setUserinfo(JSON.stringify(XterioAuth.userinfo)) + }, XTERIO_EVENTS.LOGOUT) + return () => { unsubscribe?.() + logout_unsub?.() } }, []) @@ -27,8 +44,6 @@ function App() { } const logout = () => { XterioAuth.logout() - setUserinfo('') - setIsLogin(XterioAuth.isLogin) } const openPage = async (_t: OpenPageMode) => { const res = await XterioAuth.openPage(currentPage, _t) diff --git a/examples/example-auth-vue/src/App.vue b/examples/example-auth-vue/src/App.vue index aafece0..a50d190 100644 --- a/examples/example-auth-vue/src/App.vue +++ b/examples/example-auth-vue/src/App.vue @@ -1,13 +1,14 @@ diff --git a/examples/example-auth/src/index.js b/examples/example-auth/src/index.js index 618342c..6958303 100644 --- a/examples/example-auth/src/index.js +++ b/examples/example-auth/src/index.js @@ -1,44 +1,91 @@ import '@xterio-sdk/auth/style/main.css' //方式1,先授权,再登录 -import { XterioAuth, XterEventEmiter, Env, LoginType } from '@xterio-sdk/auth' +import { XterioAuth, XterEventEmiter, Env, LoginType, PageType, OpenPageMode } from '@xterio-sdk/auth' console.log('initial') const redirect_uri = 'http://localhost:3000/' const client_id = '4gsmgur6gkp8u9ps8dlco3k7eo' const client_secret = 'ABC23' -const app_id = '' +const app_id = 'apiautotest' //4gsmgur6gkp8u9ps8dlco3k7eo, 4gsmgur6gkp8u9ps8dlco3aaaa -XterioAuth.init({ client_id, client_secret, redirect_uri }, Env.Dev) +XterioAuth.init({ client_id, client_secret, redirect_uri, app_id }, Env.Dev) XterEventEmiter.subscribe((info) => { console.log('emit userinfo=', info) - p.innerText = JSON.stringify(info) + updateInfo(info) }) -const btn = document.getElementById('login') -const logoutBtn = document.getElementById('logout') -const emailBtn = document.getElementById('email') -const miniBtn = document.getElementById('login_mini') const p = document.getElementById('userinfo') - -if (miniBtn) { - miniBtn.onclick = () => { - // XterioAuth. - XterioAuth.login(LoginType.Mini) - } -} -if (btn) { - btn.onclick = () => { - XterioAuth.login() +const updateInfo = (info) => { + if (p) { + p.innerText = JSON.stringify(info) } } -if (emailBtn) { - emailBtn.onclick = () => { - XterioAuth.login(LoginType.Email) +const addClick = (id, callback) => { + const btn = document.getElementById(id) + if (btn) { + btn.onclick = () => { + callback() + } } } -if (logoutBtn) { - logoutBtn.onclick = () => { - XterioAuth.logout() - p.innerText = '' +addClick('login', () => { + XterioAuth.login() +}) +addClick('login_email', () => { + XterioAuth.login(LoginType.Email) +}) +addClick('login_mini', () => { + XterioAuth.login(LoginType.Mini) +}) +addClick('logout', () => { + XterioAuth.logout() + updateInfo({}) +}) +addClick('isLogin', () => { + alert(XterioAuth.isLogin) +}) +addClick('getIdToken', async () => { + const id_token = await XterioAuth.getIdToken() + alert(id_token) +}) + +let currentPageName = PageType.asset +const changePage = () => { + const el = document.getElementById('current-page') + if (el) { + el.innerText = currentPageName } } +addClick('openAsset', () => { + XterioAuth.openPage(currentPageName) +}) +addClick('openAsset-new', () => { + XterioAuth.openPage(currentPageName, OpenPageMode.page) +}) +addClick('openAsset-dom', async () => { + const dom = await XterioAuth.openPage(currentPageName, OpenPageMode.iframeDom) + console.log('dom=', dom) + alert(dom) +}) +addClick('openAsset-uri', async () => { + const uri = await XterioAuth.openPage(currentPageName, OpenPageMode.iframeUri) + console.log('uri=', uri) + alert(uri) +}) +addClick('page-asset', () => { + currentPageName = PageType.asset + changePage() +}) +addClick('page-account', () => { + currentPageName = PageType.account + changePage() +}) +addClick('page-wallet', () => { + currentPageName = PageType.wallet + changePage() +}) +addClick('page-nft', () => { + currentPageName = PageType.nft + changePage() +}) +changePage() diff --git a/xterio-auth/README.md b/xterio-auth/README.md index 3d71a8b..e974b59 100644 --- a/xterio-auth/README.md +++ b/xterio-auth/README.md @@ -100,12 +100,6 @@ check whether the idToken is valid. If the idToken is invalid, empty string is r XterioAuth.getIdToken() //Promise ``` -#### `isLogin()` -depend user is login to xterio -```ts -XterioAuth.isLogin() //Promise -``` - #### `getUserInfo(p:Function)` get userinfo with callback ```ts @@ -136,7 +130,7 @@ await XterioAuth.openPage(PageType.nft, OpenPageMode.iframeUri, { ``` ### 4.2 Property -#### `isLogin` (`deprecated`) +#### `isLogin` whether to log in ```ts XterioAuth.isLogin //boolean diff --git a/xterio-auth/index.html b/xterio-auth/index.html index 4a151a6..010de13 100644 --- a/xterio-auth/index.html +++ b/xterio-auth/index.html @@ -13,6 +13,9 @@ margin-right: 10px; margin-bottom: 10px; cursor: pointer; + width: 100px; + height: 40px; + background-color: red; } } @@ -22,28 +25,28 @@

Hello, Webpack!

-
是否登录
-
默认登录
-
邮箱登录
-
小程序登录
-
退出登录
-
IdToken
+
是否登录
+
默认登录
+
邮箱登录
+
小程序登录
+
退出登录
+
IdToken
用户信息

设置要打开的页面:

-
资产页
-
账户页
-
钱包页
-
nft页
+
资产页
+
账户页
+
钱包页
+
nft页
-
打开页面(弹框)
-
打开页面(新页)
-
打开页面(dom)
-
打开页面(uri)
+
打开页面(弹框)
+
打开页面(新页)
+
打开页面(dom)
+
打开页面(uri)
diff --git a/xterio-auth/src/main.ts b/xterio-auth/src/main.ts index 91d1365..fd077a9 100644 --- a/xterio-auth/src/main.ts +++ b/xterio-auth/src/main.ts @@ -1,5 +1,5 @@ import { OpenPageMode, PageType } from 'interfaces/loginInfo' -import { Env, IUserInfo, LoginType, XterEventEmiter, XTERIO_EVENTS, XterioAuth } from './index' +import { Env, IUserInfo, LoginType, XterioAuth } from './index' import './styles/main.scss' const p = document.getElementById('userinfo') diff --git a/xterio-auth/src/modules/XterPage.ts b/xterio-auth/src/modules/XterPage.ts index 1560647..5b3c1c5 100644 --- a/xterio-auth/src/modules/XterPage.ts +++ b/xterio-auth/src/modules/XterPage.ts @@ -1,5 +1,5 @@ import { OpenPageMode, PageOptionParam, PageType } from 'interfaces/loginInfo' -import { XterioAuthInfo, XterioAuthTokensManager } from './XterAuthInfo' +import { XterioAuthInfo } from './XterAuthInfo' import { XLog } from 'utils/logger' import qs from 'query-string' import { getIframe } from 'utils/dom' @@ -7,8 +7,7 @@ import { XterioAuth } from './XterAuth' import { XterioAuthService } from './AuthService' const getOtac = async () => { - const idToken = await XterioAuth.getIdToken() - if (idToken) { + if (XterioAuth.isLogin) { // User is logged in or the login token is expiring soon if (!XterioAuthInfo?.otac) { const otac = await XterioAuthService.getOtacByTokens() diff --git a/xterio-auth/vite.config.mts b/xterio-auth/vite.config.mts index be42f41..92b0b79 100644 --- a/xterio-auth/vite.config.mts +++ b/xterio-auth/vite.config.mts @@ -27,6 +27,15 @@ export default defineConfig(({ command, mode }) => { const minify = mode === 'production' return { + css: { + preprocessorOptions: { + //pro: Deprecation Warning: The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0 + //fix: https://stackoverflow.com/questions/68147471/how-to-set-sassoptions-in-vite/78997875#78997875 + scss: { + api: 'modern-compiler' + } + } + }, //插件配置 plugins: [ tsconfigPaths(), From eaaa36cfd3177df0018f75c10fa24db18015ac43 Mon Sep 17 00:00:00 2001 From: ChenWei Date: Fri, 11 Oct 2024 17:23:02 +0800 Subject: [PATCH 06/15] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96wallet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/example-auth-react/src/App.tsx | 2 ++ xterio-auth/src/modules/XterAuth.ts | 2 +- xterio-wallet/src/App.tsx | 9 +++++---- xterio-wallet/src/contexts/index.tsx | 16 +++++++++------- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/examples/example-auth-react/src/App.tsx b/examples/example-auth-react/src/App.tsx index 0837968..88780bf 100644 --- a/examples/example-auth-react/src/App.tsx +++ b/examples/example-auth-react/src/App.tsx @@ -15,6 +15,7 @@ import { function App() { const [userinfo, setUserinfo] = useState('') + //这种形式记录不够准确,比如登录态中途变更时,该页面无法及时获悉。所以对于需要判断登录的操作,直接调用XterioAuth.isLogin即可 const [isLogin, setIsLogin] = useState(XterioAuth.isLogin) const [currentPage, setCurrentPage] = useState(PageType.asset) @@ -70,6 +71,7 @@ function App() {

是否登录: {isLogin ? 'true' : 'false'}

用户信息: {userinfo}

+ diff --git a/xterio-auth/src/modules/XterAuth.ts b/xterio-auth/src/modules/XterAuth.ts index 0c21a9d..bdfcdc5 100644 --- a/xterio-auth/src/modules/XterAuth.ts +++ b/xterio-auth/src/modules/XterAuth.ts @@ -77,8 +77,8 @@ export class XterioAuth { //again check isvalid = this.isVaildIdToken } - this.setIsLogin(isvalid) XLog.info('check token and the idToken isvalid=', isvalid) + this.setIsLogin(isvalid) if (!isvalid) { XLog.info('clear cache data') this.clearData() diff --git a/xterio-wallet/src/App.tsx b/xterio-wallet/src/App.tsx index 64b2dcd..9d81ab5 100644 --- a/xterio-wallet/src/App.tsx +++ b/xterio-wallet/src/App.tsx @@ -112,17 +112,17 @@ function App() { const [userinfo, setUserInfo] = useState({}) useEffect(() => { console.log('[xtest] ---- add listener') - const unsubscribeInfo = XterEventEmiter.subscribe((res: IUserInfo) => { + const unsubscribe_Info = XterEventEmiter.subscribe((res: IUserInfo) => { setUserInfo(res) }, XTERIO_EVENTS.ACCOUNT) - const unsubscribe = XterEventEmiter.subscribe(() => { + const unsubscribe_logout = XterEventEmiter.subscribe(() => { setUserInfo({}) }, XTERIO_EVENTS.LOGOUT) return () => { console.log('[xtest] ---- remove listener') - unsubscribeInfo?.() - unsubscribe?.() + unsubscribe_Info?.() + unsubscribe_logout?.() } }, []) @@ -133,6 +133,7 @@ function App() {

是否登录: {XterioAuth.isLogin ? 'true' : 'false'}

用户信息: {userinfo ? JSON.stringify(userinfo) : ''}

+ diff --git a/xterio-wallet/src/contexts/index.tsx b/xterio-wallet/src/contexts/index.tsx index 0845c7e..dc54b7b 100644 --- a/xterio-wallet/src/contexts/index.tsx +++ b/xterio-wallet/src/contexts/index.tsx @@ -18,7 +18,6 @@ const initState = { obtainWallet: () => {} } interface IWalletContextState extends Pick { - isLoaded: boolean aaAddress: string isConnect: boolean openWallet(): void @@ -44,7 +43,6 @@ const WalletContextProvider: React.FC() const [aaAddress, setAaAddress] = useState('') - const [isLoaded, setIsLoaded] = useState(false) const { getWalletIFrame, @@ -173,6 +171,7 @@ const WalletContextProvider: React.FC { + //init if (mounted) return setMounted(true) setLogLevel(rest?.logLevel || 1) @@ -185,16 +184,20 @@ const WalletContextProvider: React.FC { //request token expired, clear state data - XLog.info('emiter req expired') + XLog.info('emiter logout') setAaAddress('') disconnectWallet() }, XTERIO_EVENTS.LOGOUT) - setIsLoaded(true) + return () => { if (mounted) { - unsubscribe?.() + XLog.debug('remove listens') + unsubscribe_logout?.() } } }, [disconnectWallet, enableAuthInit, env, initLogic, mounted, rest]) @@ -202,7 +205,6 @@ const WalletContextProvider: React.FC Date: Fri, 11 Oct 2024 17:37:16 +0800 Subject: [PATCH 07/15] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20wallet=20&?= =?UTF-8?q?=20example?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/example-wallet-react/src/App.tsx | 53 +++++++++++++---------- xterio-wallet/README.md | 32 ++++++++++---- xterio-wallet/src/contexts/index.tsx | 4 ++ 3 files changed, 57 insertions(+), 32 deletions(-) diff --git a/examples/example-wallet-react/src/App.tsx b/examples/example-wallet-react/src/App.tsx index de8df9f..e55230c 100644 --- a/examples/example-wallet-react/src/App.tsx +++ b/examples/example-wallet-react/src/App.tsx @@ -1,25 +1,14 @@ -import { useState } from 'react' +import { useEffect, useState } from 'react' import './App.css' import { ERC20_ABI } from './abi' import { getContract, NETWORK_NAME } from './common' import { useXterioWalletContext, useXterioTransaction } from '@xterio-sdk/wallet' -import { LoginType } from '@xterio-sdk/auth' +import { IUserInfo, LoginType, XterEventEmiter, XTERIO_EVENTS, XterioAuth } from '@xterio-sdk/auth' function App() { - const { - userinfo, - isLogin, - login, - logout, - aaAddress, - isConnect, - disconnectWallet, - openWallet, - obtainWallet, - connectWallet, - signMessage - } = useXterioWalletContext() + const { aaAddress, isConnect, disconnectWallet, openWallet, obtainWallet, connectWallet, signMessage } = + useXterioWalletContext() const contractAddress = '0x12065F0d03cd1Bd280565069164F9E803c2DA988' const abi = ERC20_ABI @@ -50,17 +39,35 @@ function App() { await sendUserOperation?.(tx) } + const [userinfo, setUserInfo] = useState({}) + useEffect(() => { + console.log('[xtest] ---- add listener') + const unsubscribe_Info = XterEventEmiter.subscribe((res: IUserInfo) => { + setUserInfo(res) + }, XTERIO_EVENTS.ACCOUNT) + + const unsubscribe_logout = XterEventEmiter.subscribe(() => { + setUserInfo({}) + }, XTERIO_EVENTS.LOGOUT) + return () => { + console.log('[xtest] ---- remove listener') + unsubscribe_Info?.() + unsubscribe_logout?.() + } + }, []) + return ( <>

Xterio SDK

xterio auth sdk
-

是否登录: {isLogin ? 'true' : 'false'}

+

是否登录: {XterioAuth.isLogin ? 'true' : 'false'}

用户信息: {userinfo ? JSON.stringify(userinfo) : ''}

- - - - + + + + +
xterio wallet sdk
@@ -68,9 +75,9 @@ function App() {
pn aa wallet address: {aaAddress}
pn aa wallet connected status: {isConnect ? 'true' : 'false'}
- - - + + +
xterio wallet transaction
diff --git a/xterio-wallet/README.md b/xterio-wallet/README.md index c288301..d7367c0 100644 --- a/xterio-wallet/README.md +++ b/xterio-wallet/README.md @@ -65,10 +65,6 @@ import { LoginType } from '@xterio-sdk/auth' function App() { const { - userinfo, - isLogin, - login, - logout, aaAddress, isConnect, disconnectWallet, @@ -105,17 +101,35 @@ function App() { await sendUserOperation?.(tx) } + const [userinfo, setUserInfo] = useState({}) + useEffect(() => { + console.log('[xtest] ---- add listener') + const unsubscribe_Info = XterEventEmiter.subscribe((res: IUserInfo) => { + setUserInfo(res) + }, XTERIO_EVENTS.ACCOUNT) + + const unsubscribe_logout = XterEventEmiter.subscribe(() => { + setUserInfo({}) + }, XTERIO_EVENTS.LOGOUT) + return () => { + console.log('[xtest] ---- remove listener') + unsubscribe_Info?.() + unsubscribe_logout?.() + } + }, []) + return ( <>

Xterio SDK

xterio auth
-

isLogin: {isLogin ? 'true' : 'false'}

+

isLogin: {XterioAuth.isLogin ? 'true' : 'false'}

userinfo: {userinfo ? JSON.stringify(userinfo) : ''}

- - - - + + + + +
xterio wallet
diff --git a/xterio-wallet/src/contexts/index.tsx b/xterio-wallet/src/contexts/index.tsx index dc54b7b..b8722d5 100644 --- a/xterio-wallet/src/contexts/index.tsx +++ b/xterio-wallet/src/contexts/index.tsx @@ -112,6 +112,10 @@ const WalletContextProvider: React.FC { XLog.debug('connect wallet') + if (!XterioAuth.isLogin) { + XLog.info('please login first') + return + } if (isPnLoginedRef.current) { XLog.info('connected') return From 49154bb4b5304d155fe7295d434895175d698e48 Mon Sep 17 00:00:00 2001 From: ChenWei Date: Fri, 11 Oct 2024 19:01:13 +0800 Subject: [PATCH 08/15] =?UTF-8?q?feat:=20pn=E5=B7=B2=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E5=B9=B6aa=E5=9C=B0=E5=9D=80=E4=B8=8D=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E6=97=B6=E6=96=AD=E5=BC=80=E9=87=8D=E8=BF=9E=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xterio-wallet/src/contexts/index.tsx | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/xterio-wallet/src/contexts/index.tsx b/xterio-wallet/src/contexts/index.tsx index b8722d5..88c1385 100644 --- a/xterio-wallet/src/contexts/index.tsx +++ b/xterio-wallet/src/contexts/index.tsx @@ -116,10 +116,6 @@ const WalletContextProvider: React.FC { const _addr = info?.wallet?.find((i) => i.source === 2)?.address || '' setAaAddress(_addr) + const _uuid = info?.uuid + const pn_jwt_id = _p?.jwt_id - if (XterioAuth.isLogin && _addr && !isPnLoginedRef.current) { - XLog.debug('init logic, reconnect wallet') - await connectWallet() + if (XterioAuth.isLogin && _addr) { + XLog.debug('init logic', isPnLoginedRef.current, _uuid, pn_jwt_id) + if (!isPnLoginedRef.current) { + XLog.debug('init logic, reconnect wallet') + await connectWallet() + } else if (_uuid && pn_jwt_id && !pn_jwt_id.endsWith(_uuid)) { + XLog.debug('init logic, aa address not equal, disconnect and reconnect') + await disconnectWallet() + await connectWallet() + } } }, - [connectWallet] + [_p?.jwt_id, connectWallet, disconnectWallet] ) useEffect(() => { From 11a52469d24bceb7401055eb3921a33f44231e9d Mon Sep 17 00:00:00 2001 From: ChenWei Date: Sat, 12 Oct 2024 10:35:17 +0800 Subject: [PATCH 09/15] =?UTF-8?q?feat:=20idtoken=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E6=B8=85=E9=99=A4=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xterio-auth/src/modules/XterAuth.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/xterio-auth/src/modules/XterAuth.ts b/xterio-auth/src/modules/XterAuth.ts index bdfcdc5..53c4132 100644 --- a/xterio-auth/src/modules/XterAuth.ts +++ b/xterio-auth/src/modules/XterAuth.ts @@ -22,6 +22,7 @@ export class XterioAuth { //idToken expired logic const refreshToken = XterioAuthTokensManager.refreshToken this.setIsLogin(false) + XterioCache.deleteTokens(XTERIO_CONST.ID_TOKEN) XLog.info('the token timer, reset isLogin:', false) if (refreshToken) { XLog.info('the token timer, refresh token again') From 6c02c41f21053057bbfc9749cdc30638efa83503 Mon Sep 17 00:00:00 2001 From: ChenWei Date: Mon, 14 Oct 2024 14:42:54 +0800 Subject: [PATCH 10/15] =?UTF-8?q?feat:=20=E5=AE=9A=E5=88=B6=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=AE=8C=E5=96=84=E8=A1=A5=E5=85=85ui+style+close?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xterio-auth/README.md | 38 ++++++++ xterio-auth/src/interfaces/loginInfo.ts | 26 ++++- xterio-auth/src/main.ts | 5 +- xterio-auth/src/modules/XterPage.ts | 58 +++++++---- xterio-auth/src/styles/main.scss | 6 +- xterio-auth/src/ui/svg-icon/index.ts | 15 +-- xterio-auth/src/utils/dom.ts | 123 ++++++++++++++++++++++-- 7 files changed, 227 insertions(+), 44 deletions(-) diff --git a/xterio-auth/README.md b/xterio-auth/README.md index e974b59..295186e 100644 --- a/xterio-auth/README.md +++ b/xterio-auth/README.md @@ -207,4 +207,42 @@ export enum PageType { } ``` +### `PageOptionParam` +```ts +export interface PageOptionParam { + /** asset page */ + active?: 'ingame' | 'onchain' + /** nft page */ + keyword?: string + /** nft page */ + collection?: string + /** nft page */ + features?: { k: string; initValues: (number | string)[]; type?: string }[] + /** whether hide wallet entry */ + hide_wallet_entrance?: boolean + /** whether hide account */ + hide_account_entrance?: boolean + /** whether hide top nav menu */ + hide_menu_entrance?: boolean + /** whether hide logout btn */ + hide_sign_out?: boolean + /** whether hide footer */ + hide_footer?: boolean + /** whether disable logo click event */ + disable_logo_click?: boolean + /** whether hide game select, only asset page */ + hide_game_select?: boolean + /** whether hide game tokens, only asset page */ + hide_game_tokens?: boolean + /** whether hide game filter, only nft page */ + hide_game_filter?: boolean + /** set alert configs */ + alertConfig?: { + placement: 'left' | 'right' | 'center' //default: 'right' + style: Partial //default: { width: '400px', height: '100%' } + } +} +``` + + diff --git a/xterio-auth/src/interfaces/loginInfo.ts b/xterio-auth/src/interfaces/loginInfo.ts index 4bbb909..5f9c922 100644 --- a/xterio-auth/src/interfaces/loginInfo.ts +++ b/xterio-auth/src/interfaces/loginInfo.ts @@ -123,6 +123,7 @@ export enum PageType { account = 'account', wallet = 'wallet' } + export interface PageOptionParam { /** asset page */ active?: 'ingame' | 'onchain' @@ -132,6 +133,27 @@ export interface PageOptionParam { collection?: string /** nft page */ features?: { k: string; initValues: (number | string)[]; type?: string }[] - /** platform os type */ - platform?: 'pc' | 'mobile' + /** whether hide wallet entry */ + hide_wallet_entrance?: boolean + /** whether hide account */ + hide_account_entrance?: boolean + /** whether hide top nav menu */ + hide_menu_entrance?: boolean + /** whether hide logout btn */ + hide_sign_out?: boolean + /** whether hide footer */ + hide_footer?: boolean + /** whether disable logo click event */ + disable_logo_click?: boolean + /** whether hide game select, only asset page */ + hide_game_select?: boolean + /** whether hide game tokens, only asset page */ + hide_game_tokens?: boolean + /** whether hide game filter, only nft page */ + hide_game_filter?: boolean + /** set alert configs */ + alertConfig?: { + placement: 'left' | 'right' | 'center' + style: Partial + } } diff --git a/xterio-auth/src/main.ts b/xterio-auth/src/main.ts index fd077a9..098f8be 100644 --- a/xterio-auth/src/main.ts +++ b/xterio-auth/src/main.ts @@ -76,7 +76,10 @@ addClick('openAsset-dom', async () => { alert(dom) }) addClick('openAsset-uri', async () => { - const uri = await XterioAuth.openPage(currentPageName, OpenPageMode.iframeUri) + const uri = await XterioAuth.openPage(currentPageName, OpenPageMode.iframeUri, { + hide_account_entrance: true, + hide_footer: true + }) console.log('uri=', uri) alert(uri) }) diff --git a/xterio-auth/src/modules/XterPage.ts b/xterio-auth/src/modules/XterPage.ts index 9fb1f8d..06e23f7 100644 --- a/xterio-auth/src/modules/XterPage.ts +++ b/xterio-auth/src/modules/XterPage.ts @@ -2,11 +2,20 @@ import { OpenPageMode, PageOptionParam, PageType } from 'interfaces/loginInfo' import { XterioAuthInfo } from './XterAuthInfo' import { XLog } from 'utils/logger' import qs from 'query-string' -import { getIframe } from 'utils/dom' +import { addCssText, convertStyleToArray, getDiv, getIframe } from 'utils/dom' import { XterioAuth } from './XterAuth' import { XterioAuthService } from './AuthService' +import { iconContentMap } from 'ui/svg-icon' const getOtac = async () => { + //tip: otac invalid when used once + if (XterioAuth.isLogin) { + const otac = await XterioAuthService.getOtacByTokens() + return otac || '' + } + return '' + + /* if (XterioAuth.isLogin) { // User is logged in or the login token is expiring soon if (!XterioAuthInfo?.otac) { @@ -24,20 +33,11 @@ const getOtac = async () => { } } return XterioAuthInfo?.otac || '' + */ } export const openPage = async (page: PageType, mode?: OpenPageMode, options?: PageOptionParam) => { - const { active = 'ingame', keyword, collection, features, platform } = options || {} - const isMobile = platform === 'mobile' - let _p: Record = { - hide_wallet_entrance: true, - hide_account_entrance: true, - hide_menu_entrance: true, - hide_sign_out: true, - hide_footer: true, - disable_logo_click: true - } - + const { active = 'ingame', keyword, collection, features, alertConfig, ...rest } = options || {} const _type = mode || OpenPageMode.alert const app_id = XterioAuthInfo.config?.app_id || '' if (!app_id) { @@ -46,14 +46,12 @@ export const openPage = async (page: PageType, mode?: OpenPageMode, options?: Pa const basePage = XterioAuthInfo.pageURL let uri = '' if (page === PageType.asset) { - _p = { ..._p, hide_game_select: true, hide_game_tokens: true } uri = `${basePage}/asset?source=1&app_id=${app_id}&active=${active}` } else if (page === PageType.account) { uri = `${basePage}/settings?source=1` } else if (page === PageType.wallet) { uri = `${basePage}/settings?source=1&tab=wallet` } else if (page === PageType.nft) { - _p = { ..._p, hide_game_filter: true } let query: Record = { source: 1, app_id } if (collection) { query = { ...query, collection } @@ -67,8 +65,8 @@ export const openPage = async (page: PageType, mode?: OpenPageMode, options?: Pa uri = `${basePage}/marketplace?${qs.stringify(query)}` } - if (isMobile) { - uri += `&${qs.stringify(_p)}` + if (rest) { + uri += `&${qs.stringify(rest)}` } const otac = await getOtac() if (otac) { @@ -80,13 +78,37 @@ export const openPage = async (page: PageType, mode?: OpenPageMode, options?: Pa return uri } if (_type === OpenPageMode.iframeDom) { - return getIframe(uri).querySelector('iframe') + const { iframe } = getIframe(uri) + return iframe } if (_type === OpenPageMode.alert) { - document.body.appendChild(getIframe(uri)) + const { iframeDiv, shadow } = getIframe(uri) + updateElementStyle(iframeDiv, alertConfig) + const { element: closeDiv, remove: unsubscribe } = getDiv('close-icon pointer', () => { + shadow.remove() + unsubscribe?.() + }) + addCssText(closeDiv, `position:absolute;top:16px;left:16px;`) + closeDiv.innerHTML = iconContentMap['icon-close-iframe'] + iframeDiv.appendChild(closeDiv) + document.body.appendChild(shadow) return } if (_type === OpenPageMode.page) { location.href = uri } } + +const updateElementStyle = (ele: HTMLElement, config: PageOptionParam['alertConfig']) => { + const { placement = 'right', style = { width: '100%', height: '100%' } } = config || {} + const _styArr = [] + //style中优先级 > placement + _styArr.push('margin-top', `calc((100% - ${style.height}) / 2)`) + if (placement === 'right') { + _styArr.push('margin-left', `calc(100% - ${style.width})`) + } else if (placement === 'center') { + _styArr.push('margin-left', `calc((100% - ${style.width}) / 2)`) + } + _styArr.push(...convertStyleToArray(style)) + addCssText(ele, ..._styArr) +} diff --git a/xterio-auth/src/styles/main.scss b/xterio-auth/src/styles/main.scss index 9a6602c..c1d1bae 100644 --- a/xterio-auth/src/styles/main.scss +++ b/xterio-auth/src/styles/main.scss @@ -28,11 +28,7 @@ z-index: 1000; } - &-modal-container-iframe { - height: 100%; - width: 100%; - max-width: 400px; - margin: auto; + &-modal-container-iframe { z-index: 1010; position: relative; } diff --git a/xterio-auth/src/ui/svg-icon/index.ts b/xterio-auth/src/ui/svg-icon/index.ts index df30bf7..81ef30d 100644 --- a/xterio-auth/src/ui/svg-icon/index.ts +++ b/xterio-auth/src/ui/svg-icon/index.ts @@ -1,17 +1,8 @@ -const iconContentMap = { +export const iconContentMap = { 'icon-close': ``, 'icon-show': ``, - 'icon-hide': `` -} - -const getCssText = (...args: any[]): string => { - let _css: string = '' - for (let i = 0; i < Math.floor(args.length / 2); i++) { - const key = args[i * 2] - const val = args[i * 2 + 1] - _css += `${key}: ${val};` - } - return _css + 'icon-hide': ``, + 'icon-close-iframe': `` } export const generateSVGIcon = ( diff --git a/xterio-auth/src/utils/dom.ts b/xterio-auth/src/utils/dom.ts index 0059d3e..b405223 100644 --- a/xterio-auth/src/utils/dom.ts +++ b/xterio-auth/src/utils/dom.ts @@ -1,11 +1,121 @@ -export const getCssName = (name: string) => { - const a = name.split(' ').reduce((prev, cur) => prev + `xterioauth-${cur} `, '') +/** + * 给class统一加前缀 + * example: getCssName('iframe div') => xterioauth-iframe xterioauth-div + * @param name + * @returns string + */ +export const getCssName = (name: string, prefix: string = 'xterioauth') => { + const a = name.split(' ').reduce((prev, cur) => prev + `${prefix}-${cur} `, '') return a } -const getDiv = (cssName: string, callback?: () => void) => { - const div = document.createElement('div') - div.className = getCssName(cssName) +/** + * dom元素,添加指定 class + * example: addClass(ele, 'iframe div') + * @param ele 目标元素 + * @param classNames 类名,以空格隔开 + */ +export const addClass = (ele: HTMLElement, classNames: string) => { + const _names = classNames.split(' ').filter(Boolean) + if (ele.classList) { + _names.forEach((_c: string) => { + ele.classList.add(_c) + }) + } else { + const classes = ele.className.split(' ') + _names.forEach((_c: string) => { + if (classes.indexOf(_c) === -1) { + classes.push(_c) + } + }) + ele.className = classes.join(' ') + } +} + +/** + * dom元素,移除指定 class + * example: removeClass(ele, 'iframe div') + * @param ele 目标元素 + * @param classNames 类名,以空格隔开 + */ +export const removeClass = (ele: HTMLElement, classNames: string) => { + const _names = classNames.split(' ').filter(Boolean) + if (ele.classList) { + _names.forEach((_c: string) => { + ele.classList.remove(_c) + }) + } else { + const classes = ele.className.split(' ') + _names.forEach((_c: string) => { + const index = classes.indexOf(_c) + if (index !== -1) { + classes.splice(index, 1) + } + }) + ele.className = classes.join(' ') + } +} + +/** + * 将给定参数转换成cssText形式 + * example: generateCssText('width', '200px', 'height', '200px', ...) + * @param args any[] + * @returns string + */ +export const generateCssText = (...args: any[]): string => { + let _css: string = '' + for (let i = 0; i < Math.floor(args.length / 2); i++) { + //转换一下,对于marginTop => margin-top + const key = args[i * 2].replace(/[A-Z]/g, (m: string) => `-${m.toLowerCase()}`) + const val = args[i * 2 + 1] + _css += `${key}: ${val};` + } + return _css +} + +/** + * dom元素,设置样式 + * example1. addCssText(ele, `position:absolute;top:16px;left:16px;`) + * example2. addCssText(ele, 'width', '200px', ...) + * @param ele dom元素 + * @param args 系列参数 + */ +export const addCssText = (ele: HTMLElement, ...args: any[]) => { + const isCssStr = args.length === 1 && typeof args?.[0] === 'string' && args?.[0].indexOf(':') !== -1 + if (isCssStr) { + ele.style.cssText = ele.style.cssText + args?.[0] + } else { + // console.log('dddd', generateCssText(...args)) + ele.style.cssText = ele.style.cssText + generateCssText(...args) + } +} + +/** + * 将Style对象样式转成数组形式[propertyName, propertyValue, ...] + * example: convertStyleToArray({width: '200px', marginTop:'20px'}) + * @param sty {width: '200px', marginTop:'20px'} + * @returns ['width', '200px', 'marginTop', '20px'] + */ +export const convertStyleToArray = (sty: Partial) => { + const _arr = [] + for (const key in sty) { + _arr.push(key, sty[key]) + } + return _arr +} + +/** + * 创建一个dom元素,并返回该dom元素对象,如果可点击再补充返回移除点击事件的监听函数 + * example1: getDiv('test') + * example2: getDiv('test', ()=> {}) + * example3: getDiv('test', undefined, 'span') + * @param cssName 指定类名 + * @param callback 点击事件 + * @returns {dom元素,移除点击监听函数?} + */ +export const getDiv = (cssName: string, callback?: () => void, tagName: string = 'div') => { + const div = document.createElement(tagName) + addClass(div, getCssName(cssName)) if (callback) { const clickHandler = (e: Event) => { callback?.() @@ -21,6 +131,7 @@ const getDiv = (cssName: string, callback?: () => void) => { return { element: div } } +//创建全局iframe弹框 export const getIframe = (url: string) => { const { element: shadow } = getDiv('modal-shadow') const { element: bg, remove } = getDiv('modal-bg pointer', () => { @@ -37,5 +148,5 @@ export const getIframe = (url: string) => { iframe.frameBorder = '0' iframe.src = url div.appendChild(iframe) - return shadow + return { shadow, iframe, iframeDiv: div } } From 144442be3653e883a28e16f983ab196c6205d129 Mon Sep 17 00:00:00 2001 From: ChenWei Date: Mon, 14 Oct 2024 14:53:11 +0800 Subject: [PATCH 11/15] =?UTF-8?q?feat:=20=E5=AE=9A=E5=88=B6=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=96=B0=E5=A2=9E=E9=85=8D=E7=BD=AEshowCloseIcon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xterio-auth/src/interfaces/loginInfo.ts | 1 + xterio-auth/src/modules/XterPage.ts | 28 +++++++++++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/xterio-auth/src/interfaces/loginInfo.ts b/xterio-auth/src/interfaces/loginInfo.ts index 5f9c922..ba9bcf8 100644 --- a/xterio-auth/src/interfaces/loginInfo.ts +++ b/xterio-auth/src/interfaces/loginInfo.ts @@ -155,5 +155,6 @@ export interface PageOptionParam { alertConfig?: { placement: 'left' | 'right' | 'center' style: Partial + showCloseIcon?: boolean } } diff --git a/xterio-auth/src/modules/XterPage.ts b/xterio-auth/src/modules/XterPage.ts index 06e23f7..8f8f86a 100644 --- a/xterio-auth/src/modules/XterPage.ts +++ b/xterio-auth/src/modules/XterPage.ts @@ -81,9 +81,19 @@ export const openPage = async (page: PageType, mode?: OpenPageMode, options?: Pa const { iframe } = getIframe(uri) return iframe } + if (_type === OpenPageMode.page) { + location.href = uri + } if (_type === OpenPageMode.alert) { - const { iframeDiv, shadow } = getIframe(uri) - updateElementStyle(iframeDiv, alertConfig) + alertIframeLogic(uri, alertConfig) + return + } +} + +const alertIframeLogic = (uri: string, config: PageOptionParam['alertConfig']) => { + const { placement = 'right', style = { width: '100%', height: '100%' }, showCloseIcon = true } = config || {} + const { iframeDiv, shadow } = getIframe(uri) + if (showCloseIcon) { const { element: closeDiv, remove: unsubscribe } = getDiv('close-icon pointer', () => { shadow.remove() unsubscribe?.() @@ -91,18 +101,10 @@ export const openPage = async (page: PageType, mode?: OpenPageMode, options?: Pa addCssText(closeDiv, `position:absolute;top:16px;left:16px;`) closeDiv.innerHTML = iconContentMap['icon-close-iframe'] iframeDiv.appendChild(closeDiv) - document.body.appendChild(shadow) - return - } - if (_type === OpenPageMode.page) { - location.href = uri } -} - -const updateElementStyle = (ele: HTMLElement, config: PageOptionParam['alertConfig']) => { - const { placement = 'right', style = { width: '100%', height: '100%' } } = config || {} + document.body.appendChild(shadow) + //update style, style > placement const _styArr = [] - //style中优先级 > placement _styArr.push('margin-top', `calc((100% - ${style.height}) / 2)`) if (placement === 'right') { _styArr.push('margin-left', `calc(100% - ${style.width})`) @@ -110,5 +112,5 @@ const updateElementStyle = (ele: HTMLElement, config: PageOptionParam['alertConf _styArr.push('margin-left', `calc((100% - ${style.width}) / 2)`) } _styArr.push(...convertStyleToArray(style)) - addCssText(ele, ..._styArr) + addCssText(iframeDiv, ..._styArr) } From e4e4c74a3c754c191674bc746faffcec6ef2e8eb Mon Sep 17 00:00:00 2001 From: ChenWei Date: Mon, 14 Oct 2024 16:37:22 +0800 Subject: [PATCH 12/15] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96publish?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sh/publish.ts | 118 +++++++++++++++++++++++++++++---------- xterio-auth/README.md | 1 + xterio-auth/RELEASE.md | 0 xterio-wallet/RELEASE.md | 0 4 files changed, 88 insertions(+), 31 deletions(-) create mode 100644 xterio-auth/RELEASE.md create mode 100644 xterio-wallet/RELEASE.md diff --git a/sh/publish.ts b/sh/publish.ts index a2f920e..6c18d81 100644 --- a/sh/publish.ts +++ b/sh/publish.ts @@ -1,8 +1,10 @@ import chalk from 'chalk' import consola from 'consola' -import { emptyDir, ensureDir, readJSONSync, writeJSONSync } from 'fs-extra' +import { appendFileSync, readFileSync, readJSONSync, writeJSONSync } from 'fs-extra' import { pathAuth, pathWallet, pathAuthJson, pathWalletJson, pathSh, pathRoot } from './paths' import { run } from './run' +import * as readline from 'readline' +import { resolve } from 'path' const AuthJsonData = readJSONSync(pathAuthJson, { encoding: 'utf-8' }) const WalletJsonData = readJSONSync(pathWalletJson, { encoding: 'utf-8' }) @@ -14,50 +16,104 @@ consola.info('_flag=', chalk.blue(_flag), _version) async function init() { const isExecuteAuth = !_flag || _flag === 'auth' const isExecuteWallet = !_flag || _flag === 'wallet' + if (isExecuteAuth) { + await publishAuth() + } + if (isExecuteWallet) { + await publishWallet() + } +} + +const publishAuth = async () => { let authVersion = AuthJsonData.version + if (_version) { + authVersion = _version + AuthJsonData.version = _version + writeJSONSync(pathAuthJson, AuthJsonData, { encoding: 'utf-8', spaces: 2 }) + } + await run(`pnpm run build:auth`, pathRoot) + + const result = await run('npm publish', pathAuth) + if (result !== 0) { + consola.error(chalk.red('auth publish failed.')) + return + } + // publish success + updateReleaseDoc(authVersion) + await commitVersionFile('auth', authVersion) + await run(`bash release.sh auth ${authVersion}`, pathSh) + return authVersion +} + +const publishWallet = async () => { let walletVersion = WalletJsonData.version + if (_version) { + walletVersion = _version + WalletJsonData.version = _version + writeJSONSync(pathWalletJson, WalletJsonData, { encoding: 'utf-8', spaces: 2 }) + } + await run(`pnpm run build:wallet`, pathRoot) + changeWalletPackageJson('publish') - if (isExecuteAuth) { - if (_version) { - authVersion = _version - AuthJsonData.version = _version - writeJSONSync(pathAuthJson, AuthJsonData, { encoding: 'utf-8', spaces: 2 }) - await commitVersionFile('auth', _version) - await run(`pnpm run build:auth`, pathRoot) - } - await run('npm publish', pathAuth) - // publish success, commit all change content and push release lock. - await run(`bash release.sh auth ${authVersion}`, pathSh) + const result = await run('npm publish', pathWallet) + if (result !== 0) { + consola.error(chalk.red('wallet publish failed.')) + changeWalletPackageJson('reset') + return } + // publish success + updateReleaseDoc(walletVersion) + await run(`bash release.sh wallet ${walletVersion}`, pathSh) + changeWalletPackageJson('reset') + await commitVersionFile('wallet', walletVersion) +} - if (isExecuteWallet) { - if (_version) { - walletVersion = _version - WalletJsonData.version = _version - writeJSONSync(pathWalletJson, WalletJsonData, { encoding: 'utf-8', spaces: 2 }) - await commitVersionFile('wallet', _version) - await run(`pnpm run build:wallet`, pathRoot) - } - //tip: change package.json content - //remove dep, add peer +const changeWalletPackageJson = (flag: string) => { + const authVersion = AuthJsonData.version + if (flag === 'publish') { WalletJsonData.peerDependencies['@xterio-sdk/auth'] = '^' + authVersion.split('.').slice(0, 2).join('.') delete WalletJsonData.dependencies['@xterio-sdk/auth'] writeJSONSync(pathWalletJson, WalletJsonData, { encoding: 'utf-8', spaces: 2 }) - await run('npm publish', pathWallet) - await run(`bash release.sh wallet ${walletVersion}`, pathSh) - await reset() + } else { + WalletJsonData.peerDependencies['@xterio-sdk/auth'] = 'workspace:^' + WalletJsonData.dependencies['@xterio-sdk/auth'] = 'workspace:^' + writeJSONSync(pathWalletJson, WalletJsonData, { encoding: 'utf-8', spaces: 2 }) } } + const commitVersionFile = async (_f: string, _v: string) => { const path = _f === 'auth' ? pathAuth : pathWallet await run(`git push origin main`) - await run(`git add package.json && git commit -m "feat: npm pkg(${_f}) publish(${_v})"`, path) + await run(`git add . && git commit -m "feat: npm pkg(${_f}) publish(${_v})"`, path) await run(`git push origin main`) } -const reset = () => { - WalletJsonData.peerDependencies['@xterio-sdk/auth'] = 'workspace:^' - WalletJsonData.dependencies['@xterio-sdk/auth'] = 'workspace:^' - writeJSONSync(pathWalletJson, WalletJsonData, { encoding: 'utf-8', spaces: 2 }) + +const updateReleaseDoc = async (v: string) => { + const docPath = resolve(pathAuth, 'RELEASE.md') + const data = readFileSync(docPath, 'utf-8') + const pattern = new RegExp(`# ${v.replace(/\./g, '\\.')}(\\s|$)`) + if (!pattern.test(data)) { + appendFileSync(docPath, `\n# ${v}\n`) + appendFileSync(docPath, lines.map((i) => `- ${i} \n`).join('')) + } } -init() +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}) +const lines: string[] = [] +consola.info(chalk.blue('Please enter some message for this publish.\n')) +const promptForInput = () => { + rl.question('', (line: string) => { + if (line === '') { + rl.close() + init() + } else { + lines.push(line) + promptForInput() + } + }) +} +promptForInput() +// init() diff --git a/xterio-auth/README.md b/xterio-auth/README.md index 295186e..0965ac4 100644 --- a/xterio-auth/README.md +++ b/xterio-auth/README.md @@ -240,6 +240,7 @@ export interface PageOptionParam { alertConfig?: { placement: 'left' | 'right' | 'center' //default: 'right' style: Partial //default: { width: '400px', height: '100%' } + showCloseIcon?: boolean } } ``` diff --git a/xterio-auth/RELEASE.md b/xterio-auth/RELEASE.md new file mode 100644 index 0000000..e69de29 diff --git a/xterio-wallet/RELEASE.md b/xterio-wallet/RELEASE.md new file mode 100644 index 0000000..e69de29 From f11224e50b1389ae01ac9ae278ed71258cb4b2f0 Mon Sep 17 00:00:00 2001 From: ChenWei Date: Tue, 15 Oct 2024 14:40:55 +0800 Subject: [PATCH 13/15] =?UTF-8?q?feat:=20wallet=20=E4=BA=A4=E6=98=93?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xterio-wallet/README.md | 6 +-- xterio-wallet/src/App.tsx | 19 +++++++-- xterio-wallet/src/contexts/pnTransaction.ts | 45 +++++++++++---------- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/xterio-wallet/README.md b/xterio-wallet/README.md index d7367c0..b2ba6f6 100644 --- a/xterio-wallet/README.md +++ b/xterio-wallet/README.md @@ -208,14 +208,14 @@ aa wallet connection status #### `state` transaction status -#### `sendTransaction({gasLimit,txValue}, ...args)` +#### `sendTransaction(...args:any[], tx?:Transaction)` send a transaction ```ts -await sendTransaction?.({ gasLimit: '', txValue:'' }, toAddr, amount) +await sendTransaction?.(toAddr, amount, {value:'', gasLimit:''}) ``` -#### `sendUserOperation(transaction|transaction[])` +#### `sendUserOperation(tx: Transaction|Transaction[])` send a transaction ```ts diff --git a/xterio-wallet/src/App.tsx b/xterio-wallet/src/App.tsx index 9d81ab5..0989174 100644 --- a/xterio-wallet/src/App.tsx +++ b/xterio-wallet/src/App.tsx @@ -84,9 +84,10 @@ function App() { const toAddr = '0xF4Ae736B14a7B5FDb803172B242074D6DFe655bb' const amount = '0x0de0b6b3a7640000' try { - await sendTransaction?.({ gasLimit: '0x90de' }, toAddr, amount) - } catch (err) { - console.log('ddd', err) + await sendTransaction?.(toAddr, amount, { gasLimit: '0x90de' }) + // await sendTransaction?.({ gasLimit: '0x90de' }, toAddr, amount) + } catch (err: any) { + console.log('ddd', err, err?.message) } } @@ -126,6 +127,18 @@ function App() { } }, []) + useEffect(() => { + const status = state.status + console.log('status=', status) + if (status === 'Mining' || status === 'PendingSignature') { + console.log('trade ing') + } else if (status === 'Success') { + console.log('trade success') + } else if (status === 'Exception' || status === 'Fail') { + console.log('trade failed') + } + }, [state.status]) + return ( <>

Xterio SDK

diff --git a/xterio-wallet/src/contexts/pnTransaction.ts b/xterio-wallet/src/contexts/pnTransaction.ts index d07eea0..6ed0ec6 100644 --- a/xterio-wallet/src/contexts/pnTransaction.ts +++ b/xterio-wallet/src/contexts/pnTransaction.ts @@ -6,7 +6,6 @@ import type { Falsy, LogDescription, Params, - TransactionOptions, TransactionReceipt, TransactionResponse, TransactionState, @@ -18,10 +17,11 @@ import { useXterioWalletContext } from '.' import { XLog } from 'src/common/utils/logger' export interface IPnTransactionState> { - sendTransaction( - { gasLimit, txValue }: Partial>, - ...args: Params - ): Promise + // sendTransaction( + // { gasLimit, txValue }: Partial>, + // ...args: Params + // ): Promise + sendTransaction(...args: [...Params, Transaction?]): Promise sendUserOperation(tx: Transaction | Transaction[]): Promise state: TransactionStatus resetState(): void @@ -119,16 +119,16 @@ export const useXterioTransaction = ) => { + async (...args: [...Params, Transaction?]) => { if (!contract || !functionName) { throw new Error(`contract null or undefined`) } const numberOfArgs = contract.interface.getFunction(functionName).inputs.length - const hasOpts = args.length > numberOfArgs if (args.length !== numberOfArgs && args.length !== numberOfArgs + 1) { throw new Error(`Invalid number of arguments for function "${functionName}".`) } - const opts = hasOpts ? args[args.length - 1] : undefined + const hasOpts = args.length > numberOfArgs + const opts = hasOpts ? (args[args.length - 1] as Transaction) : undefined const modifiedArgs = hasOpts ? args.slice(0, args.length - 1) : args if (!pnAA) { @@ -143,8 +143,9 @@ export const useXterioTransaction = >, - ...args: Params - ): Promise => { - // disable feeData - const txArgs = [...args, { gasLimit, value: txValue }] as Params - return send(...txArgs) - }, - [send] - ) + // const customSend = useCallback( + // async ( + // { txValue }: Partial>, + // ...args: Params + // ): Promise => { + // // disable feeData + // const txArgs = [...args, { value: txValue }] as Params + // return send(...txArgs) + // }, + // [send] + // ) const sendUserOperation = useCallback( async (tx: Transaction | Transaction[]) => { @@ -224,5 +225,5 @@ export const useXterioTransaction = Date: Tue, 15 Oct 2024 15:14:07 +0800 Subject: [PATCH 14/15] =?UTF-8?q?fix:=20wallet=20=E5=BD=93=E4=B8=8A?= =?UTF-8?q?=E6=AC=A1=E7=94=A8=E6=88=B7pn=E6=9C=AA=E6=96=AD=E5=BC=80?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5,=E5=BD=93=E5=89=8D=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=97=A0aa=E5=9C=B0=E5=9D=80=E6=97=B6?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91(=E6=96=AD=E5=BC=80?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xterio-wallet/src/contexts/index.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/xterio-wallet/src/contexts/index.tsx b/xterio-wallet/src/contexts/index.tsx index 88c1385..af2509b 100644 --- a/xterio-wallet/src/contexts/index.tsx +++ b/xterio-wallet/src/contexts/index.tsx @@ -164,6 +164,10 @@ const WalletContextProvider: React.FC Date: Tue, 15 Oct 2024 15:47:47 +0800 Subject: [PATCH 15/15] feat: npm pkg(auth) publish(0.0.11) --- xterio-auth/RELEASE.md | 6 ++++++ xterio-auth/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/xterio-auth/RELEASE.md b/xterio-auth/RELEASE.md index e69de29..6e2c61a 100644 --- a/xterio-auth/RELEASE.md +++ b/xterio-auth/RELEASE.md @@ -0,0 +1,6 @@ + +# 0.0.11 +- 1. 用户数据解耦&优化 +- 2. isLogin 变更逻辑处理 +- 3. idToken 刷新处理 +- 4. 定制页面UI&样式配置参数增加 diff --git a/xterio-auth/package.json b/xterio-auth/package.json index 3d2411b..7e3b3e6 100644 --- a/xterio-auth/package.json +++ b/xterio-auth/package.json @@ -1,6 +1,6 @@ { "name": "@xterio-sdk/auth", - "version": "0.0.10", + "version": "0.0.11", "description": "xterio-auth", "author": "xterio platform", "license": "ISC",