Skip to content

Commit

Permalink
feat: auth req 401 + wallet config
Browse files Browse the repository at this point in the history
  • Loading branch information
chenweigh committed Sep 23, 2024
1 parent ee3a1ea commit 3fee9d5
Show file tree
Hide file tree
Showing 16 changed files with 149 additions and 52 deletions.
2 changes: 1 addition & 1 deletion examples/example-wallet-react/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function App() {
<div className="card">
<div>pn aa wallet address: {aaAddress}</div>
<div>pn aa wallet connected status: {isConnect ? 'true' : 'false'}</div>
<button onClick={connectWallet}>AA钱包连接</button>
<button onClick={() => connectWallet()}>AA钱包连接</button>
<button onClick={disconnectWallet}>AA钱包断开连接</button>
<button onClick={obtainWallet}>AA钱包领取</button>
<button onClick={openWallet}>打开AA钱包</button>
Expand Down
10 changes: 7 additions & 3 deletions sh/publish.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import chalk from 'chalk'
import consola from 'consola'
import { emptyDir, ensureDir, readJSONSync, writeJSONSync } from 'fs-extra'
import { pathAuth, pathWallet, pathAuthJson, pathWalletJson, pathSh } from './paths'
import { pathAuth, pathWallet, pathAuthJson, pathWalletJson, pathSh, pathRoot } from './paths'
import { run } from './run'

const AuthJsonData = readJSONSync(pathAuthJson, { encoding: 'utf-8' })
Expand All @@ -14,14 +14,16 @@ consola.info('_flag=', chalk.blue(_flag), _version)
async function init() {
const isExecuteAuth = !_flag || _flag === 'auth'
const isExecuteWallet = !_flag || _flag === 'wallet'
const authVersion = _version || AuthJsonData.version
const walletVersion = _version || WalletJsonData.version
let authVersion = AuthJsonData.version
let walletVersion = WalletJsonData.version

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.
Expand All @@ -30,9 +32,11 @@ async function init() {

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
WalletJsonData.dependencies['@xterio-sdk/auth'] = '^' + authVersion
Expand Down
4 changes: 4 additions & 0 deletions xterio-auth/src/modules/XterAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ export class XterioAuth {
log('the userinfo callback count=', XterioAuthInfo.onAccount.length)
XterioAuthInfo.onAccount.map((f) => f(info))
})
XterEventEmiter.subscribe(() => {
//req expired logic
this.clearData()
}, XTERIO_EVENTS.Expired)

// init XterAuthLoginModal
// must init before async function
Expand Down
3 changes: 2 additions & 1 deletion xterio-auth/src/utils/const.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export const XTERIO_EVENTS = {
LOGIN: 'xter_auth_login_success',
ACCOUNT: 'xter_auth_response_userinfo',
REQ_ACCOUNT: 'xter_auth_request_userinfo'
REQ_ACCOUNT: 'xter_auth_request_userinfo',
Expired: 'xter_auth_req_expired'
}
export const XTERIO_CONST = {
LOGIN_TYPE: 'xter_auth_login_type',
Expand Down
8 changes: 3 additions & 5 deletions xterio-auth/src/utils/fetchers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@ import { IResponse } from './interfaces'
import { XterioAuthInfo, XterioAuthTokensManager, XterioAuthUserInfoManager } from 'modules/XterAuthInfo'
import { getPackageVersion, randomNonceStr } from 'utils/logger'
import { XterioCache } from 'modules/XterCache'
import { XterEventEmiter } from 'modules/XterEventEmitter'
import { XTERIO_EVENTS } from 'utils/const'

async function resolveResp<T>(resp: Response): Promise<T> {
const res: IResponse<T> = await resp.json()
if (res.err_code != 0) {
if (resp.status === 401 && res.err_code === 91001) {
// TOAST.noti('error', 'Your session has expired, please sign in again.')
// loginEvent.emit('Expired')
XterioCache.deleteTokens()
XterioCache.deleteUserInfo()
XterioAuthTokensManager.removeTokens()
XterioAuthUserInfoManager.removeUserInfo()
XterEventEmiter.emit(XTERIO_EVENTS.Expired)
} else if (resp.status === 429) {
// TOAST.noti('error', 'Operating too frequently, please try again later.')
}
Expand Down
1 change: 1 addition & 0 deletions xterio-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@particle-network/aa": "2.0.1",
"@particle-network/auth-core": "2.0.2",
"@particle-network/authkit": "2.0.2",
"@particle-network/thresh-sig": "^0.7.8",
"@xterio-sdk/auth": "workspace:^",
"ethers": "^5.7.2",
"react": "^18.3.1",
Expand Down
23 changes: 16 additions & 7 deletions xterio-wallet/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,19 @@ function App() {
const contractAddress = '0x12065F0d03cd1Bd280565069164F9E803c2DA988'
const abi = ERC20_ABI
const erc20 = getContract(NETWORK_NAME.SEPOLIA, contractAddress, abi)
const { sendTransaction, sendUserOperation } = useXterioTransaction(erc20, 'transfer')
const { sendTransaction, sendUserOperation, state } = useXterioTransaction(erc20, 'transfer')

const [signedMsg, setSignedMsg] = useState('')

const test1 = async () => {
//方式1: sendTransaction,useXterioTransaction 必须传contract跟functionName
const toAddr = '0xF4Ae736B14a7B5FDb803172B242074D6DFe655bb'
const amount = '0x0de0b6b3a7640000'
await sendTransaction?.({ gasLimit: '0x90de' }, toAddr, amount)
try {
await sendTransaction?.({ gasLimit: '0x90de' }, toAddr, amount)
} catch (err) {
console.log('ddd', err)
}
}

const test2 = async () => {
Expand All @@ -109,7 +113,11 @@ function App() {
to: contractAddress,
data: erc20.interface.encodeFunctionData('transfer', [toAddr, amount])
}
await sendUserOperation?.(tx)
try {
await sendUserOperation?.(tx)
} catch (err) {
console.log('ddd', err)
}
}

return (
Expand All @@ -129,10 +137,10 @@ function App() {
<div className="card">
<div>pn aa wallet address: {aaAddress}</div>
<div>pn aa wallet connected status: {isConnect ? 'true' : 'false'}</div>
<button onClick={connectWallet}>AA钱包连接</button>
<button onClick={disconnectWallet}>AA钱包断开连接</button>
<button onClick={obtainWallet}>AA钱包领取</button>
<button onClick={openWallet}>打开AA钱包</button>
<button onClick={() => connectWallet()}>AA钱包连接</button>
<button onClick={() => disconnectWallet()}>AA钱包断开连接</button>
<button onClick={() => obtainWallet()}>AA钱包领取</button>
<button onClick={() => openWallet()}>打开AA钱包</button>
</div>
<div>xterio wallet transaction</div>
<div className="card">
Expand All @@ -145,6 +153,7 @@ function App() {
>
签名message
</button>
<div>转账进度:{state.status}</div>
<button onClick={test1}>转账</button>
<button onClick={test2}>转账2</button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion xterio-wallet/src/common/utils/const.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Env } from '@xterio-sdk/auth'

type EnvItemType = {
export type EnvItemType = {
PN_CHAIN_ID: string | number
PN_PROJECT_ID: string
PN_CLIENT_KEY: string
Expand Down
64 changes: 53 additions & 11 deletions xterio-wallet/src/contexts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { createContext, PropsWithChildren, useCallback, useContext, useEffect, useState } from 'react'
import { IUserInfo, LoginType, XterioAuth, XterioAuthTokensManager } from '@xterio-sdk/auth'
import { createContext, PropsWithChildren, useCallback, useContext, useEffect, useRef, useState } from 'react'
import {
IUserInfo,
LoginType,
XterEventEmiter,
XTERIO_CONST,
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'
import { log } from 'src/common/utils'
import { XterioWalletService } from 'src/modules/WalletService'
import { IPnWalletState, IXterioWalletContextProps } from 'src/interfaces/types'
import { IUseConfigState, useConfig } from './useConfig'
import { SmartAccount } from '@particle-network/aa'

const initState = {
aaAddress: '',
Expand All @@ -26,6 +36,8 @@ interface IWalletContextState extends Pick<IPnWalletState, 'signMessage' | 'sign
connectWallet(chainId?: number): void
disconnectWallet(): void
obtainWallet(): void
pnAA?: SmartAccount
envConfig?: IUseConfigState
}

const WalletContext = createContext<IWalletContextState>(initState as IWalletContextState)
Expand All @@ -35,8 +47,12 @@ const WalletContextProvider: React.FC<PropsWithChildren<IXterioWalletContextProp
env,
enableAuthInit = true,
showOpenWalletIcon = false,
pn_app_id,
transactionMode,
...rest
}) => {
const envConfig = useConfig(env, pn_app_id, transactionMode)

const [mounted, setMounted] = useState<boolean>()
const [aaAddress, setAaAddress] = useState('')
const [userinfo, setUserInfo] = useState<IUserInfo | undefined>(XterioAuth.userinfo)
Expand All @@ -52,10 +68,16 @@ const WalletContextProvider: React.FC<PropsWithChildren<IXterioWalletContextProp
pnUserInfo: _p,
isLogin: isPnLogin,
signMessage,
signTypedData
} = usePnWallet(aaAddress, env)
signTypedData,
pnAA
} = usePnWallet(envConfig, aaAddress)

const [walletHtmlRoot, setWalletHtmlRoot] = useState<HTMLDivElement>()
const isPnLoginedRef = useRef(isPnLogin)

useEffect(() => {
isPnLoginedRef.current = isPnLogin
}, [isPnLogin])

const obtainWallet = useCallback(async () => {
if (!isLogin) {
Expand All @@ -68,7 +90,7 @@ const WalletContextProvider: React.FC<PropsWithChildren<IXterioWalletContextProp
}
log('have no aa address, go to obtain')
let pnUserInfo = _p
if (!isPnLogin) {
if (!isPnLoginedRef.current) {
pnUserInfo = await connectPnEoA()
}
const { token = '', uuid = '' } = pnUserInfo || {}
Expand All @@ -92,16 +114,21 @@ const WalletContextProvider: React.FC<PropsWithChildren<IXterioWalletContextProp
wallet_version: version
})
if (!error) {
//refresh userinfo
await XterioWalletService.getUserInfo()
log('An Xterio Wallet has been created for your account. You can also pair your own wallet.')
} else {
log('Failed to create the Xterio Wallet.')
}
}, [_p, aaAddress, connectPnAA, connectPnEoA, isLogin, isPnLogin])
}, [_p, aaAddress, connectPnAA, connectPnEoA, isLogin])

const connectWallet = useCallback(
async (chainId?: number) => {
log('connect wallet')
if (isPnLoginedRef.current) {
log('connected')
return
}
await connectPnEoAAndAA(XterioAuthTokensManager.idToken, chainId)
},
[connectPnEoAAndAA]
Expand Down Expand Up @@ -163,12 +190,12 @@ const WalletContextProvider: React.FC<PropsWithChildren<IXterioWalletContextProp
setIsLogin(_islogin)
setAaAddress(_addr)

if (_islogin && _addr && !isPnLogin) {
if (_islogin && _addr && !isPnLoginedRef.current) {
log('init logic, reconnect wallet')
await connectWallet()
}
},
[connectWallet, isPnLogin]
[connectWallet]
)

useEffect(() => {
Expand All @@ -183,6 +210,18 @@ const WalletContextProvider: React.FC<PropsWithChildren<IXterioWalletContextProp
log('emiter auth userinfo=', info)
initLogic(info)
})
const unsubscribe = XterEventEmiter.subscribe(() => {
//request token expired, clear state data
log('emiter req expired')
setUserInfo(undefined)
setIsLogin(false)
setAaAddress('')
}, XTERIO_EVENTS.Expired)
return () => {
if (mounted) {
unsubscribe?.()
}
}
}, [enableAuthInit, env, initLogic, mounted, rest])

return (
Expand All @@ -200,7 +239,9 @@ const WalletContextProvider: React.FC<PropsWithChildren<IXterioWalletContextProp
disconnectWallet,
signMessage,
signTypedData,
switchChain
switchChain,
pnAA,
envConfig
}}
>
{children}
Expand All @@ -214,9 +255,10 @@ const WalletContextProvider: React.FC<PropsWithChildren<IXterioWalletContextProp
}

export const XterioWalletProvider: React.FC<PropsWithChildren<IXterioWalletContextProps>> = (props) => {
const { env } = props
const { env, pn_app_id } = props
const envConfig = useConfig(env, pn_app_id)
return (
<AuthCoreContextProvider options={getAuthCoreModalOptions(env)}>
<AuthCoreContextProvider options={getAuthCoreModalOptions(envConfig)}>
<WalletContextProvider {...props}></WalletContextProvider>
</AuthCoreContextProvider>
)
Expand Down
Loading

0 comments on commit 3fee9d5

Please sign in to comment.