{"id":26562868,"url":"https://github.com/aelfproject/aelf-web-login","last_synced_at":"2025-03-22T15:29:04.965Z","repository":{"id":239900846,"uuid":"640747053","full_name":"AElfProject/aelf-web-login","owner":"AElfProject","description":"Modular React wallet collection and components for aelf applications.","archived":false,"fork":false,"pushed_at":"2025-02-13T15:52:05.000Z","size":58010,"stargazers_count":2,"open_issues_count":14,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-10T03:04:28.498Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://aelf-web-login.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AElfProject.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-15T03:24:43.000Z","updated_at":"2025-01-22T06:49:34.000Z","dependencies_parsed_at":"2024-07-22T10:12:36.343Z","dependency_job_id":"4f7e48d6-582d-4932-aec0-d9be5094ca6e","html_url":"https://github.com/AElfProject/aelf-web-login","commit_stats":null,"previous_names":["aelf-devops/aelf-web-login"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AElfProject%2Faelf-web-login","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AElfProject%2Faelf-web-login/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AElfProject%2Faelf-web-login/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AElfProject%2Faelf-web-login/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AElfProject","download_url":"https://codeload.github.com/AElfProject/aelf-web-login/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244977661,"owners_count":20541707,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-22T15:29:04.208Z","updated_at":"2025-03-22T15:29:04.958Z","avatar_url":"https://github.com/AElfProject.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction\n\n**aelf-web-login**: Modular React wallet collection and components for aelf applications.\n\n**website**: \u003chttps://aelf-web-login.vercel.app/\u003e\n\n\u003cp\u003e\n  \u003ca href=\"https://nodejs.org/download/\"\u003e\n    \u003cimg alt=\"Node version\" src=\"https://img.shields.io/node/v/aelf-web-login.svg\"\u003e\n  \u003c/a\u003e\n  \u003cimg alt=\"NPM\" src=\"https://img.shields.io/npm/l/aelf-web-login\"\u003e\n  \u003ca href=\"http://commitizen.github.io/cz-cli/\"\u003e\u003cimg alt=\"Commitizen friendly\" src=\"https://img.shields.io/badge/commitizen-friendly-brightgreen.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/AElfProject/aelf-web-login/actions/workflows/publish.yml\"\u003e\n    \u003cimg alt=\"coverage\" src=\"https://github.com/AElfProject/aelf-web-login/actions/workflows/publish.yml/badge.svg\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n| package | Tests | Coverage |\n| --- | --- | --- |\n| @aelf-web-login/utils | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/aelf-web-login/feature/badge-json/master-utils-test-results.json) | [![Coverage](https://aelfproject.github.io/aelf-web-login/coverage-utils/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions) |\n| @aelf-web-login/base | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/aelf-web-login/feature/badge-json/master-base-test-results.json) | [![Coverage](https://aelfproject.github.io/aelf-web-login/coverage-base/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions) |\n| @aelf-web-login/bridge | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/aelf-web-login/feature/badge-json/master-bridge-test-results.json) | [![Coverage](https://aelfproject.github.io/aelf-web-login/coverage-bridge/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions) |\n| @aelf-web-login/react | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/aelf-web-login/feature/badge-json/master-react-test-results.json) | [![Coverage](https://aelfproject.github.io/aelf-web-login/coverage-react/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions) |\n\n# Install\n\n```sh\nyarn add @aelf-web-login/wallet-adapter-night-elf @aelf-web-login/wallet-adapter-portkey-aa @aelf-web-login/wallet-adapter-portkey-discover @aelf-web-login/wallet-adapter-react @aelf-web-login/wallet-adapter-base @aelf-web-login/wallet-adapter-bridge @aelf-web-login/utils @portkey/did-ui-react\n```\n\nThen the `package.json` will be like this\n\n```json\n\"dependencies\": {\n    \"@aelf-web-login/wallet-adapter-night-elf\": \"^0.1.7\",\n    \"@aelf-web-login/wallet-adapter-portkey-aa\": \"^0.1.7\",\n    \"@aelf-web-login/wallet-adapter-portkey-discover\": \"^0.1.7\",\n    \"@aelf-web-login/wallet-adapter-react\": \"^0.1.7\",\n    \"@aelf-web-login/wallet-adapter-base\": \"^0.1.7\",\n    \"@aelf-web-login/wallet-adapter-bridge\": \"^0.1.7\",\n    \"@aelf-web-login/utils\": \"^0.1.7\",\n    \"@portkey/did-ui-react\": \"^2.13.2\",\n}\n```\n\n# Config\n\n1. Import `PortkeyDiscoverWallet`, `PortkeyAAWallet` and `NightElfWallet` and generate instance\n2. Create `didConfig` (internal invoke: `ConfigProvider.setGlobalConfig(didConfig)`)\n3. Create `baseConfig` for `SignIn` component\n4. Create `wallets` by wallet instance\n5. Combine them into a whole as `config`\n\n```ts\nimport { PortkeyDiscoverWallet } from '@aelf-web-login/wallet-adapter-portkey-discover';\nimport { PortkeyAAWallet } from '@aelf-web-login/wallet-adapter-portkey-aa';\nimport { NightElfWallet } from '@aelf-web-login/wallet-adapter-night-elf';\nimport { IConfigProps } from '@aelf-web-login/wallet-adapter-bridge';\nimport { TChainId, SignInDesignEnum, NetworkEnum } from '@aelf-web-login/wallet-adapter-base';\n\nconst APP_NAME = 'explorer.aelf.io';\nconst WEBSITE_ICON = 'https://explorer.aelf.io/favicon.main.ico';\nconst CHAIN_ID = 'AELF' as TChainId;\nconst NETWORK_TYPE = NetworkEnum.TESTNET;\nconst RPC_SERVER_AELF = 'https://aelf-test-node.aelf.io';\nconst RPC_SERVER_TDVV = 'https://tdvv-public-node.aelf.io';\nconst RPC_SERVER_TDVW = 'https://tdvw-test-node.aelf.io';\nconst GRAPHQL_SERVER =\n  'https://dapp-aa-portkey-test.portkey.finance/aefinder-v2/api/app/graphql/portkey';\nconst CONNECT_SERVER = 'https://auth-aa-portkey-test.portkey.finance';\nconst SERVICE_SERVER = 'https://aa-portkey-test.portkey.finance';\nconst TELEGRAM_BOT_ID = 'xx';\nconst didConfig = {\n  graphQLUrl: GRAPHQL_SERVER,\n  connectUrl: CONNECT_SERVER,\n  serviceUrl: SERVICE_SERVER,\n  requestDefaults: {\n    baseURL: SERVICE_SERVER,\n    timeout: 30000,\n  },\n  socialLogin: {\n    Portkey: {\n      websiteName: APP_NAME,\n      websiteIcon: WEBSITE_ICON,\n    },\n    Telegram: {\n      botId: TELEGRAM_BOT_ID,\n    },\n  },\n  // customNetworkType: NETWORK_TYPE === 'TESTNET' ? 'offline' : 'online',\n  // loginConfig: {\n  //   loginMethodsOrder: [ \"Email\",  \"Google\" , \"Apple\" ,  \"Scan\"]\n  // }\n};\n\nconst baseConfig = {\n  // ConfirmLogoutDialog: CustomizedConfirmLogoutDialog,\n  // SignInComponent: SignInProxy,\n  // defaultPin: '111111',\n  // PortkeyProviderProps: {\n  //   theme: 'light' as any,\n  // },\n  // omitTelegramScript: false,\n  // cancelAutoLoginInTelegram: false,\n  enableAcceleration: false,\n  networkType: NETWORK_TYPE,\n  showVconsole: false,\n  chainId: CHAIN_ID,\n  keyboard: true,\n  noCommonBaseModal: false,\n  design: SignInDesignEnum.CryptoDesign, // \"SocialDesign\" | \"CryptoDesign\" | \"Web2Design\"\n  titleForSocialDesign: 'Crypto wallet',\n  iconSrcForSocialDesign: 'url or base64',\n};\n\nconst wallets = [\n  new PortkeyAAWallet({\n    appName: APP_NAME,\n    chainId: CHAIN_ID,\n    autoShowUnlock: true,\n    noNeedForConfirm: false,\n  }),\n  new PortkeyDiscoverWallet({\n    networkType: NETWORK_TYPE,\n    chainId: CHAIN_ID,\n    autoRequestAccount: true, // If set to true, please contact Portkey to add whitelist @Rachel\n    autoLogoutOnDisconnected: true,\n    autoLogoutOnNetworkMismatch: true,\n    autoLogoutOnAccountMismatch: true,\n    autoLogoutOnChainMismatch: true,\n  }),\n  new NightElfWallet({\n    chainId: CHAIN_ID,\n    appName: APP_NAME,\n    connectEagerly: true,\n    defaultRpcUrl: RPC_SERVER_AELF,\n    nodes: {\n      AELF: {\n        chainId: 'AELF',\n        rpcUrl: RPC_SERVER_AELF,\n      },\n      tDVW: {\n        chainId: 'tDVW',\n        rpcUrl: RPC_SERVER_TDVW,\n      },\n      tDVV: {\n        chainId: 'tDVV',\n        rpcUrl: RPC_SERVER_TDVV,\n      },\n    },\n  }),\n];\n\nconst config: IConfigProps = {\n  didConfig,\n  baseConfig,\n  wallets,\n};\n```\n\n_IConfigProps Clarifications_\n\n```ts\nimport { GlobalConfigProps } from '@portkey/did-ui-react/dist/_types/src/components/config-provider/types';\nimport { SignInProps, ISignIn, PortkeyProvider } from '@portkey/did-ui-react';\nimport { WalletAdapter } from '@aelf-web-login/wallet-adapter-base';\n\ninterface IConfirmLogoutDialogProps {\n  title: string;\n  subTitle: string[];\n  okTxt: string;\n  cancelTxt: string;\n  visible: boolean;\n  onOk: () =\u003e void;\n  onCancel: () =\u003e void;\n  width: number;\n  mobileWidth: number;\n}\n\ninterface IConfigProps {\n  didConfig: GlobalConfigProps;\n  baseConfig: IBaseConfig;\n  wallets: WalletAdapter[];\n}\ninterface IBaseConfig {\n  networkType: NetworkEnum;\n  chainId: TChainId;\n  keyboard?: boolean;\n  design?: SignInDesignEnum;\n  iconSrcForSocialDesign?: string;\n  titleForSocialDesign?: string;\n  noCommonBaseModal?: boolean;\n  showVconsole?: boolean;\n  SignInComponent?: React.FC\u003cSignInProps \u0026 RefAttributes\u003cISignIn\u003e\u003e;\n  PortkeyProviderProps?: Partial\u003cOmit\u003cReact.ComponentProps\u003ctypeof PortkeyProvider\u003e, 'children'\u003e\u003e;\n  ConfirmLogoutDialog?: React.FC\u003cPartial\u003cIConfirmLogoutDialogProps\u003e\u003e;\n}\n```\n\n# Usage\n\n1. Import `WebLoginProvider`, `init` and `useConnectWallet`\n2. invoke `init` with upper config as params\n3. pass the return value `bridgeAPI` to `WebLoginProvider`\n4. use `useConnectWallet` to consume `bridgeAPI`\n\n```tsx\nimport { WebLoginProvider, init, useConnectWallet } from '@aelf-web-login/wallet-adapter-react';\n\nconst App = () =\u003e {\n  const bridgeAPI = init(config); // upper config\n  return (\n    \u003cWebLoginProvider bridgeAPI={bridgeAPI}\u003e\n      \u003cDemo /\u003e\n    \u003c/WebLoginProvider\u003e\n  );\n};\nconst Demo = () =\u003e {\n  const {\n    connectWallet,\n    disConnectWallet,\n    walletInfo,\n    lock,\n    isLocking,\n    isConnected,\n    loginError,\n    walletType,\n    getAccountByChainId,\n    getWalletSyncIsCompleted,\n    getSignature,\n    callSendMethod,\n    callViewMethod,\n  } = useConnectWallet();\n};\n```\n\n# API\n\n## connectWallet\n\n```ts\nconnectWallet: () =\u003e Promise\u003cTWalletInfo\u003e;\n```\n\n\u003e Connect wallet and return walletInfo\n\n```tsx\nimport { Button } from 'aelf-design';\n\nconst Demo = () =\u003e {\n  const { connectWallet } = useConnectWallet();\n  const onConnectBtnClickHandler = async () =\u003e {\n    try {\n      const rs = await connectWallet();\n    } catch (e: any) {\n      console.log(e.message);\n    }\n  };\n  return \u003cButton onClick={onConnectBtnClickHandler}\u003econnect\u003c/Button\u003e;\n};\n```\n\n## disConnectWallet\n\n```ts\ndisConnectWallet: () =\u003e Promise\u003cvoid\u003e;\n```\n\n\u003e Disconnect wallet\n\n```tsx\nimport { Button } from 'aelf-design';\n\nconst Demo = () =\u003e {\n  const { disConnectWallet } = useConnectWallet();\n  const onDisConnectBtnClickHandler = () =\u003e {\n    disConnectWallet();\n  };\n  return \u003cButton onClick={onDisConnectBtnClickHandler}\u003edisConnect\u003c/Button\u003e;\n};\n```\n\n## lock\n\n```ts\nlock: () =\u003e void\n```\n\n\u003e Lock wallet, only portkeyAA wallet take effect\n\n```tsx\nimport { Button } from 'aelf-design';\n\nconst Demo = () =\u003e {\n  const { lock } = useConnectWallet();\n  return \u003cButton onClick={lock}\u003elock\u003c/Button\u003e;\n};\n```\n\n## getAccountByChainId\n\n```ts\ngetAccountByChainId: (chainId: TChainId) =\u003e Promise\u003cstring\u003e;\n```\n\n\u003e Get account address of designative chainId\n\n```tsx\nimport { Button } from 'aelf-design';\n\nconst Demo = () =\u003e {\n    const { getAccountByChainId } = useConnectWallet();\n\n    const getAelfAccountHandler = async() =\u003e {\n        const address = await getAccountByChainId('AELF')\n        console.log(address)\n    }\n    const getTdvwAccountHandler = async() =\u003e {\n        const address = await getAccountByChainId('tDVW')\n        console.log(address)\n    }\n    return (\n        \u003cButton onClick={getAelfAccountHandler}\u003eaccount-AELF\u003c/Button\u003e\n        \u003cButton onClick={getTdvwAccountHandler}\u003eaccount-tDVW\u003c/Button\u003e\n    )\n}\n```\n\n## getWalletSyncIsCompleted\n\n```ts\ngetWalletSyncIsCompleted: (chainId: TChainId) =\u003e Promise\u003cstring | boolean\u003e;\n```\n\n\u003e Return account address of designative chainId if sync is competed, otherwise return false\n\n```tsx\nimport { Button } from 'aelf-design';\n\nconst Demo = () =\u003e {\n    const { getWalletSyncIsCompleted } = useConnectWallet();\n\n    const getAelfSyncIsCompletedHandler = async() =\u003e {\n        const address = await getWalletSyncIsCompleted('AELF')\n        console.log(address)\n    }\n    const getTdvwSyncIsCompletedHandler = async() =\u003e {\n        const address = await getWalletSyncIsCompleted('tDVW')\n        console.log(address)\n    }\n    return (\n        \u003cButton onClick={getAelfSyncIsCompletedHandler}\u003esync-AELF\u003c/Button\u003e\n        \u003cButton onClick={getTdvwSyncIsCompletedHandler}\u003esync-tDVW\u003c/Button\u003e\n    )\n}\n```\n\n## getSignature\n\n```ts\nconst getSignature: (\n  params: TSignatureParams,\n) =\u003e Promise\u003c{ error: number; errorMessage: string; signature: string; from: string } | null\u003e;\n```\n\n\u003e Get signature message\n\n```tsx\nimport { Button, Input } from 'aelf-design';\n\ntype TSignatureParams = {\n  appName: string;\n  address: string;\n  signInfo: string;\n  hexToBeSign?: string;\n};\n\nconst Demo = () =\u003e {\n    const { getSignature } = useConnectWallet();\n    const [signInfo, setSignInfo] = useState('');\n    const [signedMessage, setSignedMessage] = useState('');\n\n    const signHandler = async () =\u003e {\n      const sign = await getSignature({\n        signInfo,\n        appName: '',\n        address: '',\n      });\n      setSignedMessage(sign.signature);\n    };\n\n    return (\n        div\u003e\n          \u003cdiv\u003e\n            \u003cButton onClick={signHandler}\u003e\n              Sign\n            \u003c/Button\u003e\n            \u003cInput value={signInfo} onChange={(e) =\u003e setSignInfo(e.target.value)} /\u003e\n            \u003cdiv\u003e{signedMessage}\u003c/div\u003e\n          \u003c/div\u003e\n        \u003c/div\u003e\n    )\n}\n```\n\n## callSendMethod\n\n```ts\ncallSendMethod: \u003cT, R\u003e(props: ICallContractParams\u003cT\u003e) =\u003e Promise\u003cR\u003e;\n```\n\n\u003e Call contract's send method\n\n```tsx\nimport { Button } from 'aelf-design';\n\ninterface ICallContractParams\u003cT\u003e {\n  contractAddress: string;\n  methodName: string;\n  args: T;\n  chainId?: TChainId;\n  sendOptions?: SendOptions;\n}\n\nconst Demo = () =\u003e {\n  const { callSendMethod } = useConnectWallet();\n  const [result, setResult] = useState({});\n\n  const onApproveHandler = async () =\u003e {\n    const res = await callSendMethod({\n      chainId: 'tDVW',\n      contractAddress: 'JRmBduh4nXWi1aXgdUsj5gJrzeZb2LxmrAbf7W99faZSvoAaE',\n      methodName: 'Approve',\n      args: {\n        symbol: 'ELF',\n        spender: 'JRmBduh4nXWi1aXgdUsj5gJrzeZb2LxmrAbf7W99faZSvoAaE',\n        amount: '100000000',\n      },\n    });\n    setResult(res);\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cButton onClick={onApproveHandler}\u003eApprove in tDVW\u003c/Button\u003e\n      \u003cdiv\u003e\n        \u003ch4\u003eResult\u003c/h4\u003e\n        \u003cpre className=\"result\"\u003e{JSON.stringify(result, null, '  ')}\u003c/pre\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n## callViewMethod\n\n```ts\ncallViewMethod: \u003cT, R\u003e(props: ICallContractParams\u003cT\u003e) =\u003e Promise\u003cR\u003e;\n```\n\n\u003e Call contract's view method\n\n```tsx\nimport { Button } from 'aelf-design';\n\ninterface ICallContractParams\u003cT\u003e {\n  contractAddress: string;\n  methodName: string;\n  args: T;\n  chainId?: TChainId;\n  sendOptions?: SendOptions; // only send method use, ignore in view method\n}\n\nconst Demo = () =\u003e {\n  const { callViewMethod, getAccountByChainId } = useConnectWallet();\n  const [result, setResult] = useState({});\n\n  const onGetBalanceHandler = async () =\u003e {\n    const res = await callViewMethod({\n      chainId: 'tDVW',\n      contractAddress: 'ASh2Wt7nSEmYqnGxPPzp4pnVDU4uhj1XW9Se5VeZcX2UDdyjx',\n      methodName: 'GetBalance',\n      args: {\n        symbol: 'ELF',\n        owner: await getAccountByChainId('tDVW'),\n      },\n    });\n    setResult(res);\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cButton onClick={onGetBalanceHandler}\u003eGetBalance in tDVW\u003c/Button\u003e\n      \u003cdiv\u003e\n        \u003ch4\u003eResult\u003c/h4\u003e\n        \u003cpre className=\"result\"\u003e{JSON.stringify(result, null, '  ')}\u003c/pre\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n## walletInfo\n\n```ts\nconst walletInfo: TWalletInfo;\n```\n\n\u003e Wallet information after connecting wallet, can import `TWalletInfo` from `@aelf-web-login/wallet-adapter-base`\n\n```tsx\ntype TWalletInfo =\n  | {\n      name?: string;\n      address: string;\n      extraInfo?: {\n        [key: string]: any;\n      };\n    }\n  | undefined;\n\n  // walletInfo returned by nightElf\n  {\n    name,\n    address,\n    extraInfo: {\n      publicKey,\n      nightElfInfo: {\n        name,\n        appPermission,\n        defaultAElfBridge: bridge,\n        aelfBridges: bridges,\n        nodes,\n      },\n    },\n  }\n\n  // walletInfo returned by portkeyAA\n  import { DIDWalletInfo } from '@portkey/did-ui-react';\n  {\n    name,\n    address,\n    extraInfo: {\n      publicKey,\n      portkeyInfo: {\n        ...DIDWalletInfo\n        accounts: {\n          [chainId]: didWalletInfo.caInfo?.caAddress,\n        },\n        nickName,\n      },\n    },\n  }\n\n  // walletInfo returned by portkeyDiscover\n  import type { Accounts, IPortkeyProvider } from '@portkey/provider-types';\n  {\n    address,\n    extraInfo: {\n      accounts: Accounts,\n      nickName,\n      provider: IPortkeyProvider,\n    },\n  }\n\nconst Demo = () =\u003e {\n    const { walletInfo } = useConnectWallet();\n    console.log(walletInfo)\n    return null\n}\n```\n\n## walletType\n\n```ts\nconst walletType: WalletTypeEnum;\n```\n\n\u003e The currently connected wallet type, can import `WalletTypeEnum` from `@aelf-web-login/wallet-adapter-base`\n\n```tsx\nenum WalletTypeEnum {\n  unknown = 'Unknown',\n  elf = 'NightElf',\n  aa = 'PortkeyAA',\n  discover = 'PortkeyDiscover',\n}\n\nconst Demo = () =\u003e {\n  const { walletType } = useConnectWallet();\n  console.log(walletType);\n  return null;\n};\n```\n\n## isLocking\n\n```ts\nconst isLocking: boolean;\n```\n\n\u003e indicate whether the current state is locked, only portkeyAA wallet take effect, other wallets always return false\n\n```tsx\nimport { Button } from 'aelf-design';\n\nconst Demo = () =\u003e {\n  const { isLocking } = useConnectWallet();\n\n  return \u003cButton\u003e{isLocking ? 'unlock' : 'connect'}\u003c/Button\u003e;\n};\n```\n\n## isConnected\n\n```ts\nconst isConnected: boolean;\n```\n\n\u003e indicate whether the current state is connected\n\n```tsx\nimport { Button } from 'aelf-design';\n\nconst Demo = () =\u003e {\n  const { isConnected } = useConnectWallet();\n\n  return (\n    \u003cdiv\u003e\n      \u003cButton disabled={isConnected}\u003econnect\u003c/Button\u003e\n      \u003cButton disabled={!isConnected}\u003edisConnect\u003c/Button\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n## loginError\n\n```ts\nconst loginError: TWalletError | null;\n```\n\n\u003e indicate are there any errors during the login/logout/unlock process\n\n```tsx\ntype TWalletError = {\n  name: string;\n  code: number;\n  message: string;\n  nativeError?: any;\n};\n\nconst Demo = () =\u003e {\n  const { loginError } = useConnectWallet();\n\n  useEffect(() =\u003e {\n    if (!loginError) {\n      return;\n    }\n    console.log(loginError.message);\n  }, [loginError]);\n\n  return null;\n};\n```\n\n# Development\n\n1. Install dependencies in the project root directory\n\n```sh\npnpm install\n```\n\n2. cd to demo directory and execute dev command\n\n```sh\ncd packages/starter\npnpm dev\n```\n\nOR directly filter workspace package `pnpm --filter \"@aelf-web-login/doc-site\" dev`\n\n# Publish\n\n1. Upgrade the version numbers of each sub package\n2. execute release command in the project root directory\n\n```sh\npnpm release\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faelfproject%2Faelf-web-login","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faelfproject%2Faelf-web-login","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faelfproject%2Faelf-web-login/lists"}