├── .env.development ├── .env.production ├── .eslintignore ├── .eslintrc.cjs ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug-report.yml │ ├── config.yml │ ├── feature-request.yml │ └── question.yml └── workflows │ ├── deploy-demo.yml │ └── publish-to-npm.yml ├── .gitignore ├── .npmignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── Makefile ├── README.md ├── assets ├── vue.png └── wc.png ├── env.d.ts ├── examples ├── issues │ └── 15-elevenliu123456 │ │ ├── .gitignore │ │ ├── .prettierrc │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── public │ │ └── vite.svg │ │ ├── src │ │ ├── App.vue │ │ ├── main.ts │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ ├── vite.config.ts │ │ └── yarn.lock ├── vite │ ├── .gitignore │ ├── .prettierrc │ ├── README.md │ ├── index.html │ ├── package.json │ ├── public │ │ └── vite.svg │ ├── src │ │ ├── App.vue │ │ ├── main.ts │ │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ ├── vite.config.ts │ └── yarn.lock └── vue-cli-service │ ├── .gitignore │ ├── .prettierrc │ ├── README.md │ ├── babel.config.js │ ├── jsconfig.json │ ├── package.json │ ├── public │ └── index.html │ ├── src │ ├── App.vue │ └── main.js │ ├── vue.config.js │ └── yarn.lock ├── index.html ├── lib ├── account.ts ├── actions │ ├── asset.ts │ ├── balance.ts │ ├── block.ts │ ├── contract.ts │ ├── event.ts │ ├── gas.ts │ ├── index.ts │ ├── message.ts │ ├── multicall.ts │ ├── token.ts │ └── transaction.ts ├── chain.ts ├── enums.ts ├── event.ts ├── index.ts ├── log.ts ├── options.ts ├── plugin.ts ├── types.ts ├── utils │ └── abi │ │ ├── erc20.abi.ts │ │ ├── index.ts │ │ └── multicall.abi.ts ├── wc.ts └── web3Modal.ts ├── package.json ├── src ├── App.vue └── main.ts ├── tsconfig.json ├── vite.demo.config.ts ├── vite.lib.config.ts └── yarn.lock /.env.development: -------------------------------------------------------------------------------- 1 | VITE_G_ID= 2 | -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | VITE_G_ID=G-WTCZT7WPNW 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | examples -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require('@rushstack/eslint-patch/modern-module-resolution') 3 | 4 | module.exports = { 5 | root: true, 6 | extends: [ 7 | 'plugin:vue/vue3-essential', 8 | 'eslint:recommended', 9 | '@vue/eslint-config-typescript', 10 | '@vue/eslint-config-prettier/skip-formatting' 11 | ], 12 | parserOptions: { 13 | ecmaVersion: 'latest' 14 | }, 15 | rules: { 16 | 'vue/multi-word-component-names': 'off' 17 | }, 18 | ignorePatterns: ['dist/**/*', 'demo/**/*', 'examples/**/*'] 19 | } 20 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://www.buymeacoffee.com/kolirt -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: 🐞 Bug report 2 | description: Create a report to help us improve vue-web3-auth. 3 | title: '[Bug]: ' 4 | labels: [bug, v2] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Before reporting a bug, please make sure that you have read through our [documentation](https://github.com/kolirt/vue-web3-auth?tab=readme-ov-file#web3-authentication-for-vue3-apps-based-on-walletconnect-web3modal-v2-and-wagmi) and existing [issues](https://github.com/kolirt/vue-web3-auth/issues). 10 | - type: input 11 | id: version 12 | attributes: 13 | label: Version 14 | placeholder: v2.1.0 15 | validations: 16 | required: true 17 | - type: textarea 18 | id: configuration 19 | attributes: 20 | label: Package configuration 21 | description: Show how you configured the package. You can check how to configure the package [here](https://github.com/kolirt/vue-web3-auth?tab=readme-ov-file#configuration). 22 | placeholder: | 23 | createWeb3Auth({ 24 | projectId: '', // remove your projectId 25 | chains: [Chains.bsc, Chains.mainnet, Chains.polygon] 26 | }) 27 | validations: 28 | required: true 29 | - type: textarea 30 | id: steps-to-reproduce 31 | attributes: 32 | label: Steps to reproduce 33 | description: | 34 | How do you trigger this bug? Please walk us through it step by step. 35 | Note that you can use [Markdown](https://guides.github.com/features/mastering-markdown/) to format lists and code. 36 | placeholder: Steps to reproduce 37 | validations: 38 | required: true 39 | - type: textarea 40 | id: bug-description 41 | attributes: 42 | label: Describe the bug 43 | description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks! 44 | placeholder: Bug description 45 | validations: 46 | required: true 47 | - type: textarea 48 | id: screenshots 49 | attributes: 50 | label: Context & Screenshots (if applicable) 51 | description: | 52 | If applicable, provide any additional context or screenshots of the bug. 53 | You can drag and drop images here to add them to the issue. 54 | - type: textarea 55 | id: logs 56 | attributes: 57 | label: Logs 58 | description: | 59 | Optional if provided reproduction. Please try not to insert an image but copy paste the log text. 60 | render: shell-script 61 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 📖 Documentation 4 | url: https://github.com/kolirt/vue-web3-auth?tab=readme-ov-file#web3-authentication-for-vue3-apps-based-on-walletconnect-web3modal-v2-and-wagmi 5 | about: Check the documentation for guides and examples. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: 🚀 Feature request 2 | description: Suggest a feature that will improve vue-web3-auth. 3 | title: '[Feature]: ' 4 | labels: [feature request, v2] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thank you for taking the time to fill out this feature request! 10 | - type: textarea 11 | id: feature-description 12 | attributes: 13 | label: Describe the feature 14 | description: A clear and concise description of what you think would be a helpful addition to vue-web3-auth, including the possible use cases and alternatives you have considered. If you have a working prototype or module that implements it, please include a link. 15 | placeholder: Feature description 16 | validations: 17 | required: true 18 | - type: checkboxes 19 | id: additional-info 20 | attributes: 21 | label: Additional information 22 | description: Additional information that helps us decide how to proceed. 23 | options: 24 | - label: I intend to submit a PR for this feature. 25 | - label: I have already implemented and/or tested this feature. 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.yml: -------------------------------------------------------------------------------- 1 | name: 💬 Question 2 | description: Ask a question about the vue-web3-auth. 3 | title: '[Question]: ' 4 | labels: [question, v2] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Before asking a question, please make sure that you have read through our [documentation](https://github.com/kolirt/vue-web3-auth?tab=readme-ov-file#web3-authentication-for-vue3-apps-based-on-walletconnect-web3modal-v2-and-wagmi) and existing [issues](https://github.com/kolirt/vue-web3-auth/issues). 10 | - type: input 11 | id: version 12 | attributes: 13 | label: Package version 14 | description: | 15 | Leave blank if you have not yet configured the package and have not used it. 16 | placeholder: v2.1.0 17 | - type: textarea 18 | id: configuration 19 | attributes: 20 | label: Package configuration 21 | description: | 22 | Show how you configured the package. You can check how to configure the package [here](https://github.com/kolirt/vue-web3-auth?tab=readme-ov-file#configuration). 23 | Leave blank if you have not yet configured the package and have not used it. 24 | placeholder: | 25 | createWeb3Auth({ 26 | projectId: '', // remove your projectId 27 | chains: [Chains.bsc, Chains.mainnet, Chains.polygon] 28 | }) 29 | - type: textarea 30 | id: description 31 | attributes: 32 | label: Description 33 | validations: 34 | required: true 35 | -------------------------------------------------------------------------------- /.github/workflows/deploy-demo.yml: -------------------------------------------------------------------------------- 1 | name: 📝 deploy demo 2 | 3 | on: 4 | push: 5 | branches: 6 | - v2 7 | paths: 8 | - src/** 9 | workflow_dispatch: 10 | 11 | permissions: 12 | contents: read 13 | pages: write 14 | id-token: write 15 | 16 | concurrency: 17 | group: 'pages' 18 | cancel-in-progress: false 19 | 20 | jobs: 21 | deploy: 22 | name: 🚀 Deploy 23 | environment: 24 | name: github-pages 25 | url: ${{ steps.deployment.outputs.page_url }} 26 | runs-on: ubuntu-latest 27 | steps: 28 | - name: 📚 Checkout 29 | uses: actions/checkout@v3 30 | - name: 🟢 Node 31 | uses: actions/setup-node@v3 32 | with: 33 | node-version: 18 34 | registry-url: 'https://registry.npmjs.org' 35 | - name: 🕵 Yarn install 36 | uses: borales/actions-yarn@v4 37 | with: 38 | cmd: install 39 | - name: 🏗 Build 40 | uses: borales/actions-yarn@v4 41 | with: 42 | cmd: build-demo 43 | - name: Setup Pages 44 | uses: actions/configure-pages@v3 45 | - name: Upload artifact 46 | uses: actions/upload-pages-artifact@v1 47 | with: 48 | path: './demo' 49 | - name: 🚀 Deploy to GitHub Pages 50 | id: deployment 51 | uses: actions/deploy-pages@v2 52 | -------------------------------------------------------------------------------- /.github/workflows/publish-to-npm.yml: -------------------------------------------------------------------------------- 1 | name: 🚀 publish to npm 2 | 3 | on: 4 | release: 5 | types: [ published ] 6 | 7 | permissions: 8 | id-token: write 9 | 10 | jobs: 11 | release: 12 | name: 🚀 Release 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: 📚 Checkout 16 | uses: actions/checkout@v3 17 | - name: 🟢 Node 18 | uses: actions/setup-node@v3 19 | with: 20 | node-version: 18 21 | registry-url: 'https://registry.npmjs.org' 22 | - name: 🕵 Yarn install 23 | uses: borales/actions-yarn@v4 24 | with: 25 | cmd: install 26 | - name: 🏗 Build 27 | uses: borales/actions-yarn@v4 28 | with: 29 | cmd: build-lib 30 | - name: 🚀 Publish 31 | run: npm publish --provenance --access public 32 | env: 33 | NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}} 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | demo 15 | coverage 16 | *.local 17 | 18 | /cypress/videos/ 19 | /cypress/screenshots/ 20 | 21 | # Editor directories and files 22 | .vscode/* 23 | !.vscode/extensions.json 24 | .idea 25 | *.suo 26 | *.ntvs* 27 | *.njsproj 28 | *.sln 29 | *.sw? 30 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .github 2 | demo 3 | lib 4 | src 5 | .gitignore 6 | env.d.ts 7 | index.html 8 | Makefile 9 | tsconfig* 10 | yarn.lock 11 | vite.* 12 | .env -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | examples -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "trailingComma": "none", 4 | "tabWidth": 2, 5 | "printWidth": 120, 6 | "semi": false, 7 | "singleQuote": true, 8 | "endOfLine": "auto", 9 | "plugins": ["prettier-plugin-organize-imports", "prettier-plugin-organize-attributes"], 10 | "attributeGroups": [ 11 | "^ref", 12 | "^v-if", 13 | "^v-else", 14 | "^v-show", 15 | "^v-for", 16 | "^:?is$", 17 | "^@", 18 | "^:", 19 | "$DEFAULT", 20 | "^aria-", 21 | "^:?key$" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 kolirt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | dev: 2 | yarn dev-demo 3 | format: 4 | yarn format 5 | check: 6 | yarn type-check && yarn lint 7 | build: 8 | yarn build-lib && yarn build-demo 9 | build-demo: 10 | yarn build-demo 11 | build-lib: 12 | yarn build-lib 13 | preview: 14 | yarn preview-demo 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | Vue logo 3 | Wallet connect logo 4 |
5 | 6 |

Vue web3 auth

7 | 8 |

Web3 authentication for Vue3 apps based on WalletConnect Web3Modal v2 and wagmi

9 | 10 |
11 | vue-version 12 | 13 | npm bundle size 14 | 15 | 16 | npm-version 17 | 18 | licence 19 |
20 | 21 |

22 | 23 | 24 |

25 | 26 | Simple WalletConnect Web3Modal v2 integration package for Vue3 apps. 27 | 28 | ### Versions 29 | 30 | | package version | web3modal | 31 | | -------------------------------------------------------- | -------------------------------------------------------- | 32 | | [2.x.x](https://github.com/kolirt/vue-web3-auth/tree/v2) | [v2](https://github.com/reown-com/appkit/tree/V2) | 33 | 34 | ### Table of Contents 35 | 36 | - [Versions](#versions) 37 | - [Getting started](#getting-started) 38 | - [Installation](#installation) 39 | - [Setup](#setup) 40 | - [Configuration](#configuration) 41 | - [Custom chain](#custom-chain) 42 | - [Custom rpc provider](#custom-rpc-provider) 43 | - [Usage](#usage) 44 | - [Basic usage](#basic-usage) 45 | - [Info about the user's connected wallet and wallet type](#info-about-the-users-connected-wallet-and-wallet-type) 46 | - [Connect wallet button](#connect-wallet-button) 47 | - [Switch chain](#switch-chain) 48 | - [Select chain via Web3Modal](#select-chain-via-web3modal) 49 | - [FetchGasPrice](#fetchgasprice) 50 | - [FetchBlockNumber](#fetchblocknumber) 51 | - [FetchTransaction](#fetchtransaction) 52 | - [FetchTransactionReceipt](#fetchtransactionreceipt) 53 | - [PrepareSendTransaction](#preparesendtransaction) 54 | - [SendTransaction](#sendtransaction) 55 | - [WaitForTransaction](#waitfortransaction) 56 | - [SignMessage](#signmessage) 57 | - [Multicall](#multicall) 58 | - [FetchBalance](#fetchbalance) 59 | - [FetchToken](#fetchtoken) 60 | - [ReadContract](#readcontract) 61 | - [WriteContract](#writecontract) 62 | - [EstimateWriteContractGas](#estimatewritecontractgas) 63 | - [ParseEvents](#parseevents) 64 | - [WatchContractEvent](#watchcontractevent) 65 | - [WatchAsset](#watchasset) 66 | - [Composable](#composable) 67 | - [UseFetchBalance](#usefetchbalance) 68 | - [Demo](#demo) 69 | - [Example](#example) 70 | - [Faq](#faq) 71 | - [License](#license) 72 | - [Other packages](#other-packages) 73 | 74 | 75 | Buy Me A Coffee 76 | 77 | 78 | # Getting started 79 | 80 | ## Installation 81 | 82 | Use yarn or npm to install the package `@kolirt/vue-web3-auth`. 83 | 84 | ```bash 85 | npm install --save @kolirt/vue-web3-auth 86 | 87 | yarn add @kolirt/vue-web3-auth 88 | ``` 89 | 90 | ## Setup 91 | 92 | ### Configuration 93 | 94 | Add dependencies to your `main.js`: 95 | 96 | ```javascript 97 | import { createApp } from 'vue' 98 | import { Chains, createWeb3Auth } from '@kolirt/vue-web3-auth' 99 | 100 | const app = createApp({...}) 101 | 102 | app.use(createWeb3Auth({ 103 | projectId: '', // generate here https://cloud.walletconnect.com/ and turn on 'Supports Sign v2' 104 | chains: [ 105 | Chains.bsc, 106 | Chains.mainnet, 107 | Chains.polygon 108 | ] 109 | })) 110 | 111 | app.mount('#app') 112 | ``` 113 | 114 | ### Custom chain 115 | 116 | ```ts 117 | import { type Chain } from '@kolirt/vue-web3-auth' 118 | 119 | const bsc: Chain = { 120 | id: 56, 121 | name: 'BNB Smart Chain', 122 | network: 'bsc', 123 | nativeCurrency: { 124 | decimals: 18, 125 | name: 'BNB', 126 | symbol: 'BNB' 127 | }, 128 | rpcUrls: { 129 | default: { 130 | http: ['https://rpc.ankr.com/bsc'], 131 | webSocket: ['wss://bsc-ws-node.nariox.org:443'] 132 | }, 133 | public: { 134 | http: ['https://rpc.ankr.com/bsc'], 135 | webSocket: ['wss://bsc-ws-node.nariox.org:443'] 136 | } 137 | }, 138 | blockExplorers: { 139 | etherscan: { 140 | name: 'BscScan', 141 | url: 'https://bscscan.com' 142 | }, 143 | default: { 144 | name: 'BscScan', 145 | url: 'https://bscscan.com' 146 | } 147 | }, 148 | contracts: { 149 | multicall3: { 150 | address: '0xca11bde05977b3631167028862be2a173976ca11', 151 | blockCreated: 15921452 152 | } 153 | } 154 | } 155 | ``` 156 | 157 | ### Custom rpc provider 158 | 159 | By default, the package uses the walletconnect rpc provider. If you want to use a custom rpc from the chain, you can set the `enableCustomProvider` option to `true`. 160 | 161 | ```ts 162 | app.use(createWeb3Auth({ 163 | enableCustomProvider: true 164 | }) 165 | ``` 166 | 167 | # Usage 168 | 169 | ## Basic usage 170 | 171 | ### Info about the user's connected wallet and wallet type 172 | 173 | ```ts 174 | import { account } from '@kolirt/vue-web3-auth' 175 | 176 | account.connected // if connected 177 | account.address // current account address 178 | account.shortAddress // current account address with 3 dots 179 | account.wallet.id // current wallet id 180 | account.wallet.name // current wallet name 181 | ``` 182 | 183 | ### Connect wallet button 184 | 185 | ```vue 186 | 189 | 190 | 199 | ``````` 200 | 201 | ### Switch chain 202 | To switch the chain, you need to add it during [configuration](#configuration). 203 | 204 | ```vue 205 | 208 | 209 | 212 | ``` 213 | 214 | ### Select chain via Web3Modal 215 | 216 | ```vue 217 | 220 | 221 | 224 | ``` 225 | 226 | ### FetchGasPrice 227 | 228 | ```ts 229 | import { fetchGasPrice } from '@kolirt/vue-web3-auth' 230 | 231 | const data = await fetchGasPrice() 232 | 233 | /** 234 | * Result in data 235 | * 236 | * { 237 | * formatted: { 238 | * gasPrice: '3' 239 | * }, 240 | * gasPrice: 3000000000n 241 | * } 242 | */ 243 | ``` 244 | 245 | ### FetchBlockNumber 246 | 247 | ```ts 248 | import { fetchBlockNumber } from '@kolirt/vue-web3-auth' 249 | 250 | const data = await fetchBlockNumber() 251 | 252 | /** 253 | * Result in data 254 | * 255 | * 29288229n 256 | */ 257 | ``` 258 | 259 | ### FetchTransaction 260 | 261 | ```ts 262 | import { fetchTransaction } from '@kolirt/vue-web3-auth' 263 | 264 | const transaction = await fetchTransaction({ 265 | hash: '0x7ed8dc64f54ae43f4d53173e95aa929c52de44ec5cea8c28246989914ed7f4fb' 266 | }) 267 | ``` 268 | 269 | ### FetchTransactionReceipt 270 | 271 | ```ts 272 | import { fetchTransactionReceipt } from '@kolirt/vue-web3-auth' 273 | 274 | const transactionReceipt = await fetchTransactionReceipt({ 275 | hash: '0x7ed8dc64f54ae43f4d53173e95aa929c52de44ec5cea8c28246989914ed7f4fb' 276 | }) 277 | ``` 278 | 279 | ### PrepareSendTransaction 280 | 281 | ```ts 282 | import { prepareSendTransaction } from '@kolirt/vue-web3-auth' 283 | 284 | const preparedTxn = await prepareSendTransaction({ 285 | to: '0x2D4C407BBe49438ED859fe965b140dcF1aaB71a9', 286 | value: 1n 287 | }) 288 | ``` 289 | 290 | ### SendTransaction 291 | 292 | ```ts 293 | import { sendTransaction } from '@kolirt/vue-web3-auth' 294 | 295 | const txn = await sendTransaction({ 296 | to: '0x2D4C407BBe49438ED859fe965b140dcF1aaB71a9', 297 | value: 1n 298 | }) 299 | ``` 300 | 301 | ### WaitForTransaction 302 | 303 | ```ts 304 | import { waitForTransaction } from '@kolirt/vue-web3-auth' 305 | 306 | const transactionReceipt = await waitForTransaction({ 307 | hash: '0x7ed8dc64f54ae43f4d53173e95aa929c52de44ec5cea8c28246989914ed7f4fb', 308 | }) 309 | ``` 310 | 311 | ### SignMessage 312 | 313 | ```ts 314 | import { signMessage } from '@kolirt/vue-web3-auth' 315 | 316 | const signature = await signMessage('test message') 317 | ``` 318 | 319 | ### Multicall 320 | 321 | ```ts 322 | import { chain, multicall, multicallABI } from '@kolirt/vue-web3-auth' 323 | 324 | let data = await multicall({ 325 | calls: [ 326 | { 327 | abi: multicallABI, 328 | contractAddress: chain.value.contracts.multicall3.address, 329 | calls: [ 330 | ['getEthBalance', ['0x2D4C407BBe49438ED859fe965b140dcF1aaB71a9']], 331 | ['getEthBalance', ['0x295e26495CEF6F69dFA69911d9D8e4F3bBadB89B']], 332 | ['getEthBalance', ['0x2465176C461AfB316ebc773C61fAEe85A6515DAA']] 333 | ] 334 | } 335 | ] 336 | }) 337 | 338 | /** 339 | * Result in data 340 | * 341 | * [ 342 | * {result: 1908669631824871303n, status: "success"}, 343 | * {result: 133515691552422277n, status: "success"}, 344 | * {result: 2080909582708869960n, status: "success"} 345 | * ] 346 | */ 347 | ``` 348 | 349 | ### FetchBalance 350 | 351 | ```ts 352 | import { fetchBalance } from '@kolirt/vue-web3-auth' 353 | 354 | let bnbBalance = await fetchBalance({ 355 | address: '0x2D4C407BBe49438ED859fe965b140dcF1aaB71a9' 356 | }) 357 | 358 | /** 359 | * Result in bnbBalance 360 | * 361 | * { 362 | * decimals: 18, 363 | * formatted: '1.908669631824871303', 364 | * symbol: 'BNB', 365 | * value: 1908669631824871303n 366 | * } 367 | */ 368 | 369 | let tokenBalance = await fetchBalance({ 370 | address: '0x2D4C407BBe49438ED859fe965b140dcF1aaB71a9', 371 | token: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c' 372 | }) 373 | 374 | /** 375 | * Result in tokenBalance 376 | * 377 | * { 378 | * decimals: 18, 379 | * formatted: '0', 380 | * symbol: 'WBNB', 381 | * value: 0n 382 | * } 383 | */ 384 | ``` 385 | 386 | ### FetchToken 387 | 388 | ```ts 389 | import { fetchToken } from '@kolirt/vue-web3-auth' 390 | 391 | let data = await fetchToken({ 392 | address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c' 393 | }) 394 | 395 | /** 396 | * Result in data 397 | * 398 | * { 399 | * address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', 400 | * decimals: 18, 401 | * name: 'Wrapped BNB', 402 | * symbol: 'WBNB', 403 | * totalSupply: { 404 | * formatted: '2538454.736169014001284694', 405 | * value: 2538454736169014001284694n 406 | * } 407 | * } 408 | */ 409 | ``` 410 | 411 | ### ReadContract 412 | 413 | ```ts 414 | import { erc20ABI, readContract } from '@kolirt/vue-web3-auth' 415 | 416 | let data = await readContract({ 417 | address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', // wbnb on bsc 418 | abi: erc20ABI, 419 | functionName: 'balanceOf', 420 | args: ['0x36696169c63e42cd08ce11f5deebbcebae652050'] 421 | }) 422 | 423 | /** 424 | * Result in data 425 | * 426 | * 107109316688516684525777n 427 | */ 428 | ``` 429 | 430 | ### WriteContract 431 | 432 | ```ts 433 | import { erc20ABI, writeContract } from '@kolirt/vue-web3-auth' 434 | 435 | await writeContract({ 436 | abi: erc20ABI, 437 | address: '0x55d398326f99059fF775485246999027B3197955', 438 | functionName: 'approve', 439 | args: ['0x685B1ded8013785d6623CC18D214320b6Bb64759', 100] 440 | }).then(async (data) => { 441 | console.log('hash', data.hash) 442 | 443 | await data.wait() 444 | 445 | console.log('transaction successfully') 446 | }) 447 | ``` 448 | 449 | ### EstimateWriteContractGas 450 | 451 | ```ts 452 | import { erc20ABI, estimateWriteContractGas } from '@kolirt/vue-web3-auth' 453 | 454 | const gas = await estimateWriteContractGas({ 455 | abi: erc20ABI, 456 | address: '0x55d398326f99059fF775485246999027B3197955', 457 | functionName: 'approve', 458 | args: ['0x685B1ded8013785d6623CC18D214320b6Bb64759', 100] 459 | }).catch((e) => {}) 460 | ``` 461 | 462 | ### ParseEvents 463 | 464 | ```ts 465 | import { erc20ABI, fetchTransactionReceipt, parseEvents } from '@kolirt/vue-web3-auth' 466 | 467 | const transactionReceipt = await fetchTransactionReceipt({ 468 | hash: '0x2a328737e94bb243b1ff64792ae68cd6c179797dc1de1e092c96137f0d3404c3' 469 | }) 470 | 471 | const events = parseEvents({ abi: erc20ABI }, transactionReceipt) 472 | /** 473 | * Result in events 474 | * 475 | * [ 476 | * { 477 | * args: { 478 | * owner: '0xaA916B4a4cDbEFC045fa24542673F500a11F5413', 479 | * spender: '0x023963f7e755bE4F743047183d1F49C31E84AEa4', 480 | * value: 1000000000000000000n 481 | * }, 482 | * eventName: 'Approval' 483 | * } 484 | * ] 485 | */ 486 | ``` 487 | 488 | ### WatchContractEvent 489 | 490 | ```ts 491 | import { erc20ABI, watchContractEvent } from '@kolirt/vue-web3-auth' 492 | 493 | const unwatch = watchContractEvent( 494 | { 495 | address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', 496 | abi: erc20ABI, 497 | eventName: 'Transfer' 498 | }, 499 | (log) => { 500 | console.log(log) 501 | } 502 | ) 503 | ``` 504 | 505 | ### WatchAsset 506 | 507 | ```ts 508 | import { watchAsset } from '@kolirt/vue-web3-auth' 509 | 510 | const result = watchAsset({ 511 | address: '0x6b175474e89094c44da98b954eedeac495271d0f', 512 | decimals: 18, 513 | symbol: 'DAI' 514 | }) 515 | ``` 516 | 517 | ## Composable 518 | 519 | ### UseFetchBalance 520 | 521 | ```ts 522 | import { useFetchBalance } from '@kolirt/vue-web3-auth' 523 | 524 | // use `fetch` for manual init when `disableAutoFetch` is `true` 525 | const { loaded, fetching, data, fetch, reload, disableAutoReload } = useFetchBalance( 526 | { 527 | address: '0x2D4C407BBe49438ED859fe965b140dcF1aaB71a9' 528 | }, 529 | { 530 | disableAutoFetch: false, 531 | autoReloadTime: 30000, 532 | disableAutoReload: false 533 | } 534 | ) 535 | ``` 536 | 537 | # Demo 538 | 539 | [Demo here](https://kolirt.github.io/vue-web3-auth/) 540 | 541 | # Example 542 | 543 | [Example here](https://github.com/kolirt/vue-web3-auth/tree/v2/examples) 544 | 545 | # FAQ 546 | 547 | Check closed [issues](https://github.com/kolirt/vue-web3-auth/issues) to get answers for most asked questions. 548 | 549 | # License 550 | 551 | [MIT](https://github.com/kolirt/vue-web3-auth/tree/v2/LICENSE) 552 | 553 | # Other packages 554 | 555 | Check out my other projects on my [GitHub profile](https://github.com/kolirt). 556 | -------------------------------------------------------------------------------- /assets/vue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kolirt/vue-web3-auth/8ec752113cb4fc879823ce1da57590227579af34/assets/vue.png -------------------------------------------------------------------------------- /assets/wc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kolirt/vue-web3-auth/8ec752113cb4fc879823ce1da57590227579af34/assets/wc.png -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import type { DefineComponent } from 'vue' 3 | const component: DefineComponent<{}, {}, any> 4 | export default component 5 | } 6 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "trailingComma": "none", 4 | "tabWidth": 2, 5 | "printWidth": 120, 6 | "semi": false, 7 | "singleQuote": true, 8 | "endOfLine": "auto", 9 | "plugins": ["prettier-plugin-organize-imports", "prettier-plugin-organize-attributes"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + TypeScript + Vite 2 | 3 | This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 ` 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vue-tsc && vite build", 9 | "preview": "vite preview", 10 | "format": "prettier --write \"**/*.{ts,js,cjs,vue,json,prettierrc}\"" 11 | }, 12 | "dependencies": { 13 | "@kolirt/vue-web3-auth": "^2", 14 | "bootstrap": "^5.3.2", 15 | "vue": "^3.3.8" 16 | }, 17 | "devDependencies": { 18 | "@vitejs/plugin-vue": "^4.5.0", 19 | "prettier": "^3.2.5", 20 | "prettier-plugin-organize-attributes": "^1.0.0", 21 | "prettier-plugin-organize-imports": "^3.2.4", 22 | "typescript": "^5.2.2", 23 | "vite": "^5.0.0", 24 | "vue-tsc": "^1.8.22" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/src/App.vue: -------------------------------------------------------------------------------- 1 | 93 | 94 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/src/main.ts: -------------------------------------------------------------------------------- 1 | import App from './App.vue' 2 | 3 | import { Chains, createWeb3Auth } from '@kolirt/vue-web3-auth' 4 | import 'bootstrap/dist/css/bootstrap.min.css' 5 | import { createApp } from 'vue' 6 | 7 | const app = createApp(App) 8 | 9 | app.use( 10 | createWeb3Auth({ 11 | projectId: '3c5c8069ff37304cc62e07ae8cb592a8', // generate here https://cloud.walletconnect.com/ and turn on 'Supports Sign v2' 12 | logEnabled: true, 13 | chains: [ 14 | Chains.bsc, 15 | Chains.mainnet, 16 | Chains.polygon, 17 | Chains.avalanche, 18 | Chains.polygonMumbai, 19 | Chains.sepolia, 20 | Chains.linea, 21 | Chains.bscTestnet 22 | ] 23 | }) 24 | ) 25 | 26 | app.mount('#app') 27 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | const component: DefineComponent<{}, {}, any> 6 | export default component 7 | } 8 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "preserve", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/issues/15-elevenliu123456/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | import { defineConfig } from 'vite' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [vue()] 7 | }) 8 | -------------------------------------------------------------------------------- /examples/vite/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /examples/vite/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "trailingComma": "none", 4 | "tabWidth": 2, 5 | "printWidth": 120, 6 | "semi": false, 7 | "singleQuote": true, 8 | "endOfLine": "auto", 9 | "plugins": ["prettier-plugin-organize-imports", "prettier-plugin-organize-attributes"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/vite/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + TypeScript + Vite 2 | 3 | This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 ` 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vue-tsc && vite build", 9 | "preview": "vite preview", 10 | "type-check": "vue-tsc --noEmit -p tsconfig.json --composite false", 11 | "format": "prettier --write \"**/*.{ts,js,cjs,vue,json,prettierrc}\"" 12 | }, 13 | "dependencies": { 14 | "@kolirt/vue-web3-auth": "^2.3.4", 15 | "bootstrap": "^5.3.2", 16 | "vue": "^3.3.8" 17 | }, 18 | "devDependencies": { 19 | "@vitejs/plugin-vue": "^4.5.0", 20 | "prettier": "^3.2.5", 21 | "prettier-plugin-organize-attributes": "^1.0.0", 22 | "prettier-plugin-organize-imports": "^3.2.4", 23 | "typescript": "^5.2.2", 24 | "vite": "^5.0.0", 25 | "vue-tsc": "^1.8.22" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/vite/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/vite/src/App.vue: -------------------------------------------------------------------------------- 1 | 86 | 87 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /examples/vite/src/main.ts: -------------------------------------------------------------------------------- 1 | import App from './App.vue' 2 | 3 | import { Chains, createWeb3Auth } from '@kolirt/vue-web3-auth' 4 | import 'bootstrap/dist/css/bootstrap.min.css' 5 | import { createApp } from 'vue' 6 | 7 | const app = createApp(App) 8 | 9 | app.use( 10 | createWeb3Auth({ 11 | projectId: '', // generate here https://cloud.walletconnect.com/ and turn on 'Supports Sign v2' 12 | chains: [Chains.bsc, Chains.mainnet, Chains.polygon] 13 | }) 14 | ) 15 | 16 | app.mount('#app') 17 | -------------------------------------------------------------------------------- /examples/vite/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | const component: DefineComponent<{}, {}, any> 6 | export default component 7 | } 8 | -------------------------------------------------------------------------------- /examples/vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "preserve", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /examples/vite/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/vite/vite.config.ts: -------------------------------------------------------------------------------- 1 | import vue from '@vitejs/plugin-vue' 2 | import { defineConfig } from 'vite' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [vue()] 7 | }) 8 | -------------------------------------------------------------------------------- /examples/vue-cli-service/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /examples/vue-cli-service/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "trailingComma": "none", 4 | "tabWidth": 2, 5 | "printWidth": 120, 6 | "semi": false, 7 | "singleQuote": true, 8 | "endOfLine": "auto", 9 | "plugins": ["prettier-plugin-organize-imports", "prettier-plugin-organize-attributes"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/vue-cli-service/README.md: -------------------------------------------------------------------------------- 1 | # hello-world 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | yarn lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /examples/vue-cli-service/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@vue/cli-plugin-babel/preset'] 3 | } 4 | -------------------------------------------------------------------------------- /examples/vue-cli-service/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "baseUrl": "./", 6 | "moduleResolution": "node", 7 | "paths": { 8 | "@/*": ["src/*"] 9 | }, 10 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/vue-cli-service/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-cli-service", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "format": "prettier --write \"**/*.{ts,js,cjs,vue,json,prettierrc}\"" 10 | }, 11 | "dependencies": { 12 | "@kolirt/vue-web3-auth": "^2.3.4", 13 | "bootstrap": "^5.3.2", 14 | "core-js": "^3.8.3", 15 | "vue": "^3.2.13" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.12.16", 19 | "@babel/eslint-parser": "^7.12.16", 20 | "@vue/cli-plugin-babel": "~5.0.0", 21 | "@vue/cli-plugin-eslint": "~5.0.0", 22 | "@vue/cli-service": "~5.0.0", 23 | "eslint": "^7.32.0", 24 | "eslint-plugin-vue": "^8.0.3", 25 | "prettier": "^3.2.5", 26 | "prettier-plugin-organize-attributes": "^1.0.0", 27 | "prettier-plugin-organize-imports": "^3.2.4" 28 | }, 29 | "eslintConfig": { 30 | "root": true, 31 | "env": { 32 | "node": true 33 | }, 34 | "extends": [ 35 | "plugin:vue/vue3-essential", 36 | "eslint:recommended" 37 | ], 38 | "parserOptions": { 39 | "parser": "@babel/eslint-parser" 40 | }, 41 | "rules": {} 42 | }, 43 | "browserslist": [ 44 | "> 1%", 45 | "last 2 versions", 46 | "not dead", 47 | "not ie 11" 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /examples/vue-cli-service/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/vue-cli-service/src/App.vue: -------------------------------------------------------------------------------- 1 | 85 | 86 | 196 | -------------------------------------------------------------------------------- /examples/vue-cli-service/src/main.js: -------------------------------------------------------------------------------- 1 | import { Chains, createWeb3Auth } from '@kolirt/vue-web3-auth' 2 | import 'bootstrap/dist/css/bootstrap.min.css' 3 | import { createApp } from 'vue' 4 | 5 | import App from './App.vue' 6 | 7 | const app = createApp(App) 8 | 9 | app.use( 10 | createWeb3Auth({ 11 | projectId: '', // generate here https://cloud.walletconnect.com/ and turn on 'Supports Sign v2' 12 | chains: [Chains.bsc, Chains.mainnet, Chains.polygon] 13 | }) 14 | ) 15 | 16 | app.mount('#app') 17 | -------------------------------------------------------------------------------- /examples/vue-cli-service/vue.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('@vue/cli-service') 2 | module.exports = defineConfig({ 3 | transpileDependencies: true 4 | }) 5 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | vue-web3-auth 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /lib/account.ts: -------------------------------------------------------------------------------- 1 | import { disconnect as masterDisconnect } from '@wagmi/core' 2 | import { reactive, readonly, watchEffect } from 'vue' 3 | 4 | import { state as optionsState } from './options' 5 | import type { AccountState, Chain, ConnectedAccount } from './types' 6 | import { init } from './wc' 7 | import { web3Modal } from './web3Modal' 8 | 9 | export const state = reactive({ 10 | bufferAccount: null, 11 | currentAccount: null 12 | }) 13 | 14 | const accountState = reactive({ 15 | connected: false, 16 | address: undefined, 17 | shortAddress: undefined, 18 | wallet: { 19 | id: undefined, 20 | name: undefined 21 | } 22 | }) 23 | 24 | export const account = readonly(accountState) 25 | 26 | export async function disconnect() { 27 | await masterDisconnect() 28 | } 29 | 30 | export async function connect(chain?: Chain) { 31 | if (!web3Modal.value) init() 32 | 33 | if (chain instanceof Event) chain = optionsState.chains[0] 34 | web3Modal.value?.setDefaultChain(chain || optionsState.chains[0]) 35 | 36 | await web3Modal.value?.openModal({ 37 | route: 'ConnectWallet' 38 | }) 39 | } 40 | 41 | export async function accountDetails() { 42 | if (!web3Modal.value) init() 43 | 44 | await web3Modal.value?.openModal({ 45 | route: 'Account' 46 | }) 47 | } 48 | 49 | export function shortAddressFilter(value = '') { 50 | return `${value.slice(0, 5)}...${value.slice(-4)}` 51 | } 52 | 53 | watchEffect(() => { 54 | if (state.currentAccount) { 55 | accountState.connected = true 56 | accountState.address = state.currentAccount.address 57 | accountState.shortAddress = shortAddressFilter(state.currentAccount.address) 58 | accountState.wallet.id = state.currentAccount.connector?.id 59 | accountState.wallet.name = state.currentAccount.connector?.name 60 | } else { 61 | accountState.connected = false 62 | accountState.address = undefined 63 | accountState.shortAddress = undefined 64 | accountState.wallet.id = undefined 65 | accountState.wallet.name = undefined 66 | } 67 | }) 68 | -------------------------------------------------------------------------------- /lib/actions/asset.ts: -------------------------------------------------------------------------------- 1 | import { getWalletClient } from '@wagmi/core' 2 | 3 | import { chain } from '../chain' 4 | import type { WatchAsset } from '../types' 5 | 6 | export async function watchAsset(options: WatchAsset) { 7 | const walletClient = await getWalletClient({ chainId: options.chainId || chain.value.id }) 8 | 9 | if (walletClient) { 10 | return await walletClient.watchAsset({ 11 | type: 'ERC20', 12 | options: { 13 | address: options.address, 14 | symbol: options.symbol, 15 | decimals: options.decimals, 16 | image: options.image 17 | } 18 | }) 19 | } 20 | 21 | return false 22 | } 23 | -------------------------------------------------------------------------------- /lib/actions/balance.ts: -------------------------------------------------------------------------------- 1 | import type { FetchBalanceResult } from '@wagmi/core' 2 | import { fetchBalance as masterFetchBalance } from '@wagmi/core' 3 | import { reactive, ref, watch } from 'vue' 4 | 5 | import { chain } from '../chain' 6 | import type { FetchBalance, FetchBalanceOptions } from '../types' 7 | 8 | export function fetchBalance(data: FetchBalance) { 9 | return masterFetchBalance({ 10 | chainId: data.chainId || chain.value.id, 11 | address: data.address, 12 | token: data.token, 13 | formatUnits: data.formatUnits 14 | }) 15 | } 16 | 17 | export function useFetchBalance(params: FetchBalance, options?: FetchBalanceOptions) { 18 | const loaded = ref(false) 19 | const fetching = ref(false) 20 | const data = reactive({ 21 | decimals: 0, 22 | formatted: '', 23 | symbol: '', 24 | value: 0n 25 | }) 26 | 27 | let timeoutHandler: number 28 | let updateHandler: number 29 | let currentChain = params.chainId || chain.value.id 30 | const fetchOptions: FetchBalanceOptions = { 31 | disableAutoFetch: options?.disableAutoFetch || false, 32 | autoReloadTime: options?.autoReloadTime || 30000, 33 | disableAutoReload: options?.disableAutoReload || false 34 | } 35 | 36 | async function fetch() { 37 | if (!fetching.value || !loaded.value) { 38 | fetching.value = true 39 | 40 | await fetchBalance(params) 41 | .then((fetchData) => { 42 | if (fetchData.value !== data.value || !loaded.value) { 43 | data.decimals = fetchData.decimals 44 | data.formatted = fetchData.formatted 45 | data.symbol = fetchData.symbol 46 | data.value = fetchData.value 47 | } 48 | }) 49 | .finally(() => { 50 | loaded.value = true 51 | fetching.value = false 52 | 53 | runTimeout() 54 | }) 55 | } 56 | } 57 | 58 | function reload() { 59 | clearTimeout(timeoutHandler) 60 | return fetch() 61 | } 62 | 63 | function disableAutoReload() { 64 | fetchOptions.disableAutoReload = true 65 | } 66 | 67 | function runTimeout() { 68 | if (fetchOptions.disableAutoReload !== true) { 69 | // @ts-ignore 70 | timeoutHandler = setTimeout(reload, fetchOptions.autoReloadTime || 30000) 71 | } 72 | } 73 | 74 | function resetData() { 75 | loaded.value = false 76 | data.decimals = 0 77 | data.formatted = '' 78 | data.symbol = '' 79 | data.value = 0n 80 | } 81 | 82 | function update() { 83 | clearTimeout(updateHandler) 84 | currentChain = chain.value.id 85 | resetData() 86 | reload() 87 | } 88 | 89 | if (fetchOptions.disableAutoFetch !== true) { 90 | fetch() 91 | } 92 | 93 | if (params.chainId === undefined) { 94 | watch( 95 | () => chain.value.id, 96 | (newChainId) => { 97 | if (newChainId !== currentChain) { 98 | // @ts-ignore 99 | updateHandler = setTimeout(update) 100 | } 101 | } 102 | ) 103 | } 104 | 105 | return { 106 | loaded, 107 | fetching, 108 | data, 109 | fetch, 110 | reload, 111 | disableAutoReload 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /lib/actions/block.ts: -------------------------------------------------------------------------------- 1 | import { fetchBlockNumber as masterFetchBlockNumber } from '@wagmi/core' 2 | 3 | import { chain } from '../chain' 4 | import type { FetchBlockNumber } from '../types' 5 | 6 | export function fetchBlockNumber(data?: FetchBlockNumber) { 7 | return masterFetchBlockNumber({ 8 | chainId: data?.chainId || chain.value.id 9 | }) 10 | } 11 | -------------------------------------------------------------------------------- /lib/actions/contract.ts: -------------------------------------------------------------------------------- 1 | import type { WaitForTransactionResult } from '@wagmi/core' 2 | import { 3 | getPublicClient, 4 | readContract as masterReadContract, 5 | writeContract as masterWriteContract, 6 | waitForTransaction 7 | } from '@wagmi/core' 8 | 9 | import { account } from '../account' 10 | import { chain } from '../chain' 11 | import type { ReadContract, WriteContract } from '../types' 12 | 13 | export async function readContract(data: ReadContract) { 14 | return masterReadContract({ 15 | chainId: data.chainId || chain.value.id, 16 | address: data.address, 17 | abi: data.abi, 18 | functionName: data.functionName, 19 | args: data.args || [], 20 | account: data.account || account.address, 21 | blockNumber: data.blockNumber, 22 | blockTag: data.blockTag 23 | }) 24 | } 25 | 26 | export async function writeContract(data: WriteContract) { 27 | const { hash } = await masterWriteContract({ 28 | chainId: data.chainId || chain.value.id, 29 | address: data.address, 30 | abi: data.abi, 31 | functionName: data.functionName, 32 | args: data.args || [], 33 | account: data.account || account.address, 34 | gas: data.gas, 35 | gasPrice: data.gasPrice, 36 | maxFeePerGas: data.maxFeePerGas, 37 | maxPriorityFeePerGas: data.maxPriorityFeePerGas, 38 | nonce: data.nonce, 39 | value: data.value 40 | }) 41 | 42 | function wait() { 43 | return waitForTransaction({ 44 | chainId: data.chainId || chain.value.id, 45 | hash, 46 | confirmations: data.confirmations || 1 47 | }) 48 | } 49 | 50 | return { 51 | hash, 52 | wait 53 | } as { hash: `0x${string}`; wait: () => Promise } 54 | } 55 | 56 | export async function estimateWriteContractGas(data: WriteContract) { 57 | const publicClient = getPublicClient({ chainId: data.chainId || chain.value.id }) 58 | 59 | return await publicClient.estimateContractGas({ 60 | address: data.address, 61 | abi: data.abi, 62 | functionName: data.functionName, 63 | args: data.args || [], 64 | // @ts-ignore 65 | account: data.account || account.address, 66 | gasPrice: data.gasPrice, 67 | maxFeePerGas: data.maxFeePerGas, 68 | maxPriorityFeePerGas: data.maxPriorityFeePerGas, 69 | nonce: data.nonce, 70 | value: data.value 71 | }) 72 | } 73 | -------------------------------------------------------------------------------- /lib/actions/event.ts: -------------------------------------------------------------------------------- 1 | import { watchContractEvent as masterWatchContractEvent } from '@wagmi/core' 2 | import type { TransactionReceipt } from 'viem/types/transaction' 3 | import { decodeEventLog } from 'viem/utils' 4 | 5 | import { chain } from '../chain' 6 | import type { DecodedEvent, ParseEvents, WatchContractEvent } from '../types' 7 | 8 | export function parseEvents(data: ParseEvents, transactionReceipt: TransactionReceipt) { 9 | const result: DecodedEvent[] = [] 10 | 11 | transactionReceipt.logs.forEach((log) => { 12 | try { 13 | result.push( 14 | decodeEventLog({ 15 | abi: data.abi, 16 | topics: log.topics, 17 | data: log.data 18 | }) 19 | ) 20 | } catch (e) { 21 | /* empty */ 22 | } 23 | }) 24 | 25 | return result 26 | } 27 | 28 | export function watchContractEvent(data: WatchContractEvent, callback: (log: any) => void) { 29 | return masterWatchContractEvent( 30 | { 31 | chainId: data?.chainId || chain.value.id, 32 | address: data.address, 33 | abi: data.abi, 34 | eventName: data.eventName 35 | }, 36 | callback 37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /lib/actions/gas.ts: -------------------------------------------------------------------------------- 1 | import { fetchFeeData as masterFetchFeeData } from '@wagmi/core' 2 | 3 | import { chain } from '../chain' 4 | import type { FetchFeeData } from '../types' 5 | 6 | export function fetchGasPrice(data?: FetchFeeData) { 7 | return masterFetchFeeData({ 8 | chainId: data?.chainId || chain.value.id, 9 | formatUnits: data?.formatUnits 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /lib/actions/index.ts: -------------------------------------------------------------------------------- 1 | export { watchAsset } from './asset' 2 | export { fetchBalance, useFetchBalance } from './balance' 3 | export { fetchBlockNumber } from './block' 4 | export { estimateWriteContractGas, readContract, writeContract } from './contract' 5 | export { parseEvents, watchContractEvent } from './event' 6 | export { fetchGasPrice } from './gas' 7 | export { signMessage } from './message' 8 | export { multicall } from './multicall' 9 | export { fetchToken } from './token' 10 | export { 11 | fetchTransaction, 12 | fetchTransactionReceipt, 13 | prepareSendTransaction, 14 | sendTransaction, 15 | waitForTransaction 16 | } from './transaction' 17 | -------------------------------------------------------------------------------- /lib/actions/message.ts: -------------------------------------------------------------------------------- 1 | import { signMessage as masterSignMessage } from '@wagmi/core' 2 | 3 | export function signMessage(message: string) { 4 | return masterSignMessage({ 5 | message 6 | }) 7 | } 8 | -------------------------------------------------------------------------------- /lib/actions/multicall.ts: -------------------------------------------------------------------------------- 1 | import { multicall as masterMulticall, type MulticallResult } from '@wagmi/core' 2 | import { type MulticallParameters } from 'viem/actions' 3 | import { type ContractFunctionConfig } from 'viem/types/contract' 4 | 5 | import type { MulticallArgs } from '../types' 6 | 7 | export async function multicall( 8 | params: MulticallArgs 9 | ): Promise> { 10 | // @ts-ignore 11 | const contracts: TContracts = [] as TContracts 12 | 13 | params.calls.forEach((item) => { 14 | item.calls.forEach(([functionName, args]) => { 15 | contracts.push({ 16 | address: item.contractAddress, 17 | abi: item.abi, 18 | functionName, 19 | args 20 | }) 21 | }) 22 | }) 23 | 24 | return await masterMulticall({ 25 | chainId: params.chainId, 26 | contracts: contracts as MulticallParameters['contracts'], 27 | multicallAddress: params.multicallAddress, 28 | blockTag: params.blockTag, 29 | blockNumber: params.blockNumber, 30 | batchSize: params.batchSize, 31 | allowFailure: params.allowFailure 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /lib/actions/token.ts: -------------------------------------------------------------------------------- 1 | import { fetchToken as masterFetchToken } from '@wagmi/core' 2 | 3 | import { chain } from '../chain' 4 | import type { FetchToken } from '../types' 5 | 6 | export function fetchToken(data: FetchToken) { 7 | return masterFetchToken({ 8 | chainId: data.chainId || chain.value.id, 9 | address: data.address, 10 | formatUnits: data.formatUnits 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /lib/actions/transaction.ts: -------------------------------------------------------------------------------- 1 | import { 2 | getPublicClient, 3 | fetchTransaction as masterFetchTransaction, 4 | prepareSendTransaction as masterPrepareSendTransaction, 5 | sendTransaction as masterSendTransaction, 6 | waitForTransaction as masterWaitForTransaction 7 | } from '@wagmi/core' 8 | 9 | import { chain } from '../chain' 10 | import type { 11 | FetchTransaction, 12 | FetchTransactionReceipt, 13 | PrepareSendTransaction, 14 | SendTransaction, 15 | WaitTransaction 16 | } from '../types' 17 | 18 | export function fetchTransaction(data: FetchTransaction) { 19 | return masterFetchTransaction({ 20 | chainId: data.chainId || chain.value.id, 21 | hash: data.hash 22 | }) 23 | } 24 | 25 | export function fetchTransactionReceipt(data: FetchTransactionReceipt) { 26 | const publicClient = getPublicClient({ chainId: data.chainId || chain.value.id }) 27 | 28 | return publicClient.getTransactionReceipt({ 29 | hash: data.hash 30 | }) 31 | } 32 | 33 | export function prepareSendTransaction(data: PrepareSendTransaction) { 34 | return masterPrepareSendTransaction({ 35 | chainId: data.chainId || chain.value.id, 36 | ...data 37 | }) 38 | } 39 | 40 | export function sendTransaction(data: SendTransaction) { 41 | return masterSendTransaction({ 42 | chainId: data.chainId || chain.value.id, 43 | ...data 44 | }) 45 | } 46 | 47 | export function waitForTransaction(data: WaitTransaction) { 48 | return masterWaitForTransaction({ 49 | chainId: data.chainId || chain.value.id, 50 | ...data 51 | }) 52 | } 53 | -------------------------------------------------------------------------------- /lib/chain.ts: -------------------------------------------------------------------------------- 1 | import { computed, reactive, watch } from 'vue' 2 | 3 | import { state as optionsState } from './options' 4 | import type { Chain, ChainState } from './types' 5 | import { init, state as wcState } from './wc' 6 | import { web3Modal } from './web3Modal' 7 | 8 | export const state = reactive({ 9 | bufferChain: null, 10 | currentChain: null 11 | }) 12 | 13 | export const chain = computed(() => { 14 | return state.currentChain ? state.currentChain : optionsState.chains[0] 15 | }) 16 | 17 | export function getAvailableChains(): Chain[] { 18 | return optionsState.chains 19 | } 20 | 21 | export function switchChain(newChain: Chain) { 22 | return new Promise((resolve, reject) => { 23 | if (!web3Modal.value) init() 24 | 25 | const unwatch = watch( 26 | () => chain.value, 27 | (changedChain) => { 28 | unwatch() 29 | if (changedChain.id === newChain.id) { 30 | resolve(changedChain) 31 | } else { 32 | reject(new Error('Chain switch failed')) 33 | } 34 | } 35 | ) 36 | 37 | wcState.client?.switchNetwork({ chainId: newChain.id }).catch((e) => { 38 | reject(e) 39 | }) 40 | }) 41 | } 42 | 43 | export async function selectChain() { 44 | if (!web3Modal.value) init() 45 | 46 | await web3Modal.value?.openModal({ 47 | route: 'SelectNetwork' 48 | }) 49 | } 50 | -------------------------------------------------------------------------------- /lib/enums.ts: -------------------------------------------------------------------------------- 1 | export enum Events { 2 | Connected = 'connected', 3 | Disconnected = 'disconnect', 4 | ChainSwitched = 'chain_switched', 5 | UnknownChain = 'unknown_chain', 6 | ModalStateChanged = 'modal_state_changed' 7 | } 8 | -------------------------------------------------------------------------------- /lib/event.ts: -------------------------------------------------------------------------------- 1 | import EventBus from 'js-event-bus' 2 | 3 | import { state as accountState } from './account' 4 | import { state as chainState } from './chain' 5 | import { Events } from './enums' 6 | import { $log } from './log' 7 | import { state as optionsState } from './options' 8 | 9 | const eventBus = new EventBus() 10 | 11 | export function $emit(event: Events, ...args: any[]) { 12 | if (event === Events.Connected || event === Events.Disconnected) { 13 | chainState.currentChain = chainState.bufferChain 14 | accountState.currentAccount = accountState.bufferAccount 15 | } else if (event === Events.ChainSwitched) { 16 | chainState.currentChain = chainState.bufferChain 17 | } 18 | 19 | setTimeout(eventBus.emit, 0, event, null, ...args) 20 | } 21 | 22 | export function $on(event: Events, callback: (...args: any) => void) { 23 | eventBus.on(event, callback) 24 | if (optionsState.logEnabled) { 25 | $log(`Subscribe for ${event} event.`) 26 | } 27 | } 28 | 29 | export function $off(event: Events, callback: (...args: any) => void) { 30 | eventBus.detach(event, callback) 31 | if (optionsState.logEnabled) { 32 | $log(`Unsubscribe for ${event} event.`) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/index.ts: -------------------------------------------------------------------------------- 1 | import * as Chains from '@wagmi/core/chains' 2 | 3 | export { account, accountDetails, connect, disconnect, shortAddressFilter } from './account' 4 | export * from './actions' 5 | export { chain, getAvailableChains, selectChain, switchChain } from './chain' 6 | export { Events } from './enums' 7 | export { $off, $on } from './event' 8 | export { createWeb3Auth } from './plugin' 9 | export type { Chain, MulticallArgs, MulticallContract, Options } from './types' 10 | export * from './utils/abi' 11 | export { init } from './wc' 12 | export { Chains } 13 | -------------------------------------------------------------------------------- /lib/log.ts: -------------------------------------------------------------------------------- 1 | import { state as optionsState } from './options' 2 | 3 | export function $log(...args: any[]) { 4 | if (optionsState.logEnabled) { 5 | console.log('[WC]', ...args) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/options.ts: -------------------------------------------------------------------------------- 1 | import { mainnet } from 'viem/chains' 2 | import { reactive } from 'vue' 3 | 4 | import type { Options } from './types' 5 | 6 | export const state = reactive({ 7 | autoInit: true, 8 | projectId: '', 9 | chains: [mainnet], 10 | autoConnect: true, 11 | disconnectUnknownChain: true, 12 | reconnectToChain: true, 13 | logEnabled: false, 14 | enableCustomProvider: false, 15 | web3modalOptions: { 16 | themeMode: 'light', 17 | themeVariables: {} 18 | } 19 | }) 20 | 21 | export function setOptions(newOptions: Options | {}): void { 22 | if ('autoInit' in newOptions) state.autoInit = newOptions.autoInit 23 | if ('projectId' in newOptions) state.projectId = newOptions.projectId 24 | if ('chains' in newOptions) state.chains = newOptions.chains 25 | if ('autoConnect' in newOptions) state.autoConnect = newOptions.autoConnect 26 | if ('disconnectUnknownChain' in newOptions) state.disconnectUnknownChain = newOptions.disconnectUnknownChain 27 | if ('reconnectToChain' in newOptions) state.reconnectToChain = newOptions.reconnectToChain 28 | if ('logEnabled' in newOptions) state.logEnabled = newOptions.logEnabled 29 | if ('enableCustomProvider' in newOptions) state.enableCustomProvider = newOptions.enableCustomProvider 30 | 31 | // @ts-ignore 32 | if ('web3modalOptions' in newOptions) { 33 | // @ts-ignore 34 | if ('themeMode' in newOptions.web3modalOptions) { 35 | // @ts-ignore 36 | state.web3modalOptions.themeMode = newOptions.web3modalOptions.themeMode 37 | } 38 | 39 | // @ts-ignore 40 | if ('themeVariables' in newOptions.web3modalOptions) { 41 | // @ts-ignore 42 | state.web3modalOptions.themeVariables = newOptions.web3modalOptions.themeVariables 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/plugin.ts: -------------------------------------------------------------------------------- 1 | import type { Plugin } from 'vue' 2 | 3 | import { state as optionsState, setOptions } from './options' 4 | import type { Options } from './types' 5 | import { init } from './wc' 6 | 7 | export function createWeb3Auth(options: Options): Plugin { 8 | return { 9 | install() { 10 | setOptions(options) 11 | if (optionsState.autoInit) { 12 | init() 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/types.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | Chain, 3 | GetAccountResult, 4 | PrepareSendTransactionArgs, 5 | SendTransactionArgs, 6 | Unit, 7 | WaitForTransactionArgs 8 | } from '@wagmi/core' 9 | import type { ConfigCtrlState, ThemeCtrlState } from '@web3modal/core' 10 | import type { EthereumClient } from '@web3modal/ethereum' 11 | import type { WatchAssetParams } from 'viem/types/eip1193' 12 | 13 | type BlockTag = 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' 14 | 15 | export type Options = { 16 | /** 17 | * if true, plugin WalletConnect will init automatically 18 | */ 19 | autoInit?: boolean 20 | /** 21 | * generate here https://cloud.walletconnect.com/ and turn on 'Supports Sign v2' 22 | */ 23 | projectId: string 24 | chains: Chain[] 25 | /** 26 | * if true, wc will auto connect if was connected previously 27 | */ 28 | autoConnect?: boolean 29 | /** 30 | * when selected unknown chain, account will disconnect 31 | */ 32 | disconnectUnknownChain?: boolean 33 | /** 34 | * when chain changed account will disconnect then connect again. when true, event "chain_switched" isn't available 35 | */ 36 | reconnectToChain?: boolean 37 | logEnabled?: boolean 38 | /** 39 | * if true, the w3m provider will be disabled and a custom rpc based on the rpc from the chain configuration will be activated 40 | */ 41 | enableCustomProvider?: boolean 42 | web3modalOptions?: Pick< 43 | ConfigCtrlState, 44 | | 'mobileWallets' 45 | | 'desktopWallets' 46 | | 'walletImages' 47 | | 'chainImages' 48 | | 'tokenImages' 49 | | 'tokenContracts' 50 | | 'explorerRecommendedWalletIds' 51 | | 'explorerExcludedWalletIds' 52 | | 'termsOfServiceUrl' 53 | | 'privacyPolicyUrl' 54 | > & 55 | ThemeCtrlState 56 | } 57 | 58 | export type { Chain } 59 | 60 | export type ConnectedAccount = { 61 | connected: boolean 62 | address?: `0x${string}` 63 | shortAddress?: string 64 | wallet: { 65 | id?: string 66 | name?: string 67 | } 68 | } 69 | 70 | export type BufferChain = Chain & { unsupported?: boolean } 71 | 72 | export type ChainState = { 73 | bufferChain: BufferChain | null 74 | currentChain: BufferChain | null 75 | } 76 | 77 | export type WcState = { 78 | client: EthereumClient | null 79 | } 80 | 81 | export type AccountState = { 82 | bufferAccount: GetAccountResult | null 83 | currentAccount: GetAccountResult | null 84 | } 85 | 86 | export type MulticallContract = { 87 | abi: any 88 | contractAddress: `0x${string}` 89 | calls: [string, Array?][] 90 | } 91 | 92 | export type MulticallArgs = { 93 | chainId?: number 94 | calls: MulticallContract[] 95 | multicallAddress?: `0x${string}` 96 | batchSize?: number 97 | allowFailure?: TAllowFailure 98 | } & ( 99 | | { 100 | blockNumber?: bigint 101 | blockTag?: never 102 | } 103 | | { 104 | blockNumber?: never 105 | blockTag?: BlockTag 106 | } 107 | ) 108 | 109 | export type ReadContract = { 110 | chainId?: number 111 | address: `0x${string}` 112 | abi: any 113 | functionName: string 114 | args?: any[] 115 | account?: `0x${string}` 116 | blockNumber?: bigint 117 | blockTag?: BlockTag 118 | } 119 | 120 | export type WriteContract = { 121 | chainId?: number 122 | address: `0x${string}` 123 | abi: any 124 | functionName: string 125 | args?: any[] 126 | account?: `0x${string}` 127 | gas?: bigint 128 | gasPrice?: bigint 129 | maxFeePerGas?: bigint 130 | maxPriorityFeePerGas?: bigint 131 | nonce?: number 132 | value?: bigint 133 | confirmations?: number 134 | } 135 | 136 | export type ParseEvents = { 137 | abi: any 138 | } 139 | 140 | export type DecodedEvent = { 141 | eventName: string 142 | args: any 143 | } 144 | 145 | export type WatchContractEvent = { 146 | chainId?: number 147 | address: `0x${string}` | `0x${string}`[] 148 | abi: any 149 | eventName: string 150 | } 151 | 152 | export type FetchBalance = { 153 | chainId?: number 154 | address: `0x${string}` 155 | formatUnits?: Unit 156 | token?: `0x${string}` 157 | } 158 | 159 | export type WatchAsset = { 160 | chainId?: number 161 | } & WatchAssetParams['options'] 162 | 163 | export type FetchBalanceOptions = { 164 | disableAutoFetch?: boolean 165 | autoReloadTime?: number 166 | disableAutoReload?: boolean 167 | } 168 | 169 | export type FetchToken = { 170 | chainId?: number 171 | address: `0x${string}` 172 | formatUnits?: Unit 173 | } 174 | 175 | export type FetchFeeData = { 176 | chainId?: number 177 | formatUnits?: Unit 178 | } 179 | 180 | export type FetchBlockNumber = { 181 | chainId?: number 182 | } 183 | 184 | export type FetchTransaction = { 185 | chainId?: number 186 | hash: `0x${string}` 187 | } 188 | 189 | export type FetchTransactionReceipt = { 190 | chainId?: number 191 | hash: `0x${string}` 192 | } 193 | 194 | export type PrepareSendTransaction = Omit & { 195 | value?: bigint 196 | } 197 | 198 | export type SendTransaction = SendTransactionArgs & { 199 | value?: bigint 200 | } 201 | 202 | export type WaitTransaction = WaitForTransactionArgs 203 | -------------------------------------------------------------------------------- /lib/utils/abi/erc20.abi.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | inputs: [ 4 | { internalType: 'string', name: 'name_', type: 'string' }, 5 | { 6 | internalType: 'string', 7 | name: 'symbol_', 8 | type: 'string' 9 | }, 10 | { internalType: 'uint8', name: 'decimals_', type: 'uint8' }, 11 | { 12 | internalType: 'uint256', 13 | name: 'initialBalance_', 14 | type: 'uint256' 15 | }, 16 | { internalType: 'address payable', name: 'feeReceiver_', type: 'address' } 17 | ], 18 | stateMutability: 'payable', 19 | type: 'constructor' 20 | }, 21 | { 22 | anonymous: false, 23 | inputs: [ 24 | { indexed: true, internalType: 'address', name: 'owner', type: 'address' }, 25 | { 26 | indexed: true, 27 | internalType: 'address', 28 | name: 'spender', 29 | type: 'address' 30 | }, 31 | { indexed: false, internalType: 'uint256', name: 'value', type: 'uint256' } 32 | ], 33 | name: 'Approval', 34 | type: 'event' 35 | }, 36 | { 37 | anonymous: false, 38 | inputs: [ 39 | { indexed: true, internalType: 'address', name: 'from', type: 'address' }, 40 | { 41 | indexed: true, 42 | internalType: 'address', 43 | name: 'to', 44 | type: 'address' 45 | }, 46 | { indexed: false, internalType: 'uint256', name: 'value', type: 'uint256' } 47 | ], 48 | name: 'Transfer', 49 | type: 'event' 50 | }, 51 | { 52 | inputs: [ 53 | { internalType: 'address', name: 'owner', type: 'address' }, 54 | { 55 | internalType: 'address', 56 | name: 'spender', 57 | type: 'address' 58 | } 59 | ], 60 | name: 'allowance', 61 | outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], 62 | stateMutability: 'view', 63 | type: 'function' 64 | }, 65 | { 66 | inputs: [ 67 | { internalType: 'address', name: 'spender', type: 'address' }, 68 | { 69 | internalType: 'uint256', 70 | name: 'amount', 71 | type: 'uint256' 72 | } 73 | ], 74 | name: 'approve', 75 | outputs: [{ internalType: 'bool', name: '', type: 'bool' }], 76 | stateMutability: 'nonpayable', 77 | type: 'function' 78 | }, 79 | { 80 | inputs: [{ internalType: 'address', name: 'account', type: 'address' }], 81 | name: 'balanceOf', 82 | outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], 83 | stateMutability: 'view', 84 | type: 'function' 85 | }, 86 | { 87 | inputs: [], 88 | name: 'decimals', 89 | outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }], 90 | stateMutability: 'view', 91 | type: 'function' 92 | }, 93 | { 94 | inputs: [ 95 | { internalType: 'address', name: 'spender', type: 'address' }, 96 | { 97 | internalType: 'uint256', 98 | name: 'subtractedValue', 99 | type: 'uint256' 100 | } 101 | ], 102 | name: 'decreaseAllowance', 103 | outputs: [{ internalType: 'bool', name: '', type: 'bool' }], 104 | stateMutability: 'nonpayable', 105 | type: 'function' 106 | }, 107 | { 108 | inputs: [ 109 | { internalType: 'address', name: 'spender', type: 'address' }, 110 | { 111 | internalType: 'uint256', 112 | name: 'addedValue', 113 | type: 'uint256' 114 | } 115 | ], 116 | name: 'increaseAllowance', 117 | outputs: [{ internalType: 'bool', name: '', type: 'bool' }], 118 | stateMutability: 'nonpayable', 119 | type: 'function' 120 | }, 121 | { 122 | inputs: [], 123 | name: 'name', 124 | outputs: [{ internalType: 'string', name: '', type: 'string' }], 125 | stateMutability: 'view', 126 | type: 'function' 127 | }, 128 | { 129 | inputs: [], 130 | name: 'symbol', 131 | outputs: [{ internalType: 'string', name: '', type: 'string' }], 132 | stateMutability: 'view', 133 | type: 'function' 134 | }, 135 | { 136 | inputs: [], 137 | name: 'totalSupply', 138 | outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], 139 | stateMutability: 'view', 140 | type: 'function' 141 | }, 142 | { 143 | inputs: [ 144 | { internalType: 'address', name: 'recipient', type: 'address' }, 145 | { 146 | internalType: 'uint256', 147 | name: 'amount', 148 | type: 'uint256' 149 | } 150 | ], 151 | name: 'transfer', 152 | outputs: [{ internalType: 'bool', name: '', type: 'bool' }], 153 | stateMutability: 'nonpayable', 154 | type: 'function' 155 | }, 156 | { 157 | inputs: [ 158 | { internalType: 'address', name: 'sender', type: 'address' }, 159 | { 160 | internalType: 'address', 161 | name: 'recipient', 162 | type: 'address' 163 | }, 164 | { internalType: 'uint256', name: 'amount', type: 'uint256' } 165 | ], 166 | name: 'transferFrom', 167 | outputs: [{ internalType: 'bool', name: '', type: 'bool' }], 168 | stateMutability: 'nonpayable', 169 | type: 'function' 170 | } 171 | ] 172 | -------------------------------------------------------------------------------- /lib/utils/abi/index.ts: -------------------------------------------------------------------------------- 1 | import erc20ABI from './erc20.abi' 2 | import multicallABI from './multicall.abi' 3 | 4 | export { erc20ABI, multicallABI } 5 | -------------------------------------------------------------------------------- /lib/utils/abi/multicall.abi.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | inputs: [ 4 | { 5 | components: [ 6 | { 7 | internalType: 'address', 8 | name: 'target', 9 | type: 'address' 10 | }, 11 | { 12 | internalType: 'bytes', 13 | name: 'callData', 14 | type: 'bytes' 15 | } 16 | ], 17 | internalType: 'struct Multicall.Call[]', 18 | name: 'calls', 19 | type: 'tuple[]' 20 | } 21 | ], 22 | name: 'aggregate', 23 | outputs: [ 24 | { 25 | internalType: 'uint256', 26 | name: 'blockNumber', 27 | type: 'uint256' 28 | }, 29 | { 30 | internalType: 'bytes[]', 31 | name: 'returnData', 32 | type: 'bytes[]' 33 | } 34 | ], 35 | stateMutability: 'nonpayable', 36 | type: 'function' 37 | }, 38 | { 39 | inputs: [ 40 | { 41 | internalType: 'uint256', 42 | name: 'blockNumber', 43 | type: 'uint256' 44 | } 45 | ], 46 | name: 'getBlockHash', 47 | outputs: [ 48 | { 49 | internalType: 'bytes32', 50 | name: 'blockHash', 51 | type: 'bytes32' 52 | } 53 | ], 54 | stateMutability: 'view', 55 | type: 'function' 56 | }, 57 | { 58 | inputs: [], 59 | name: 'getCurrentBlockCoinbase', 60 | outputs: [ 61 | { 62 | internalType: 'address', 63 | name: 'coinbase', 64 | type: 'address' 65 | } 66 | ], 67 | stateMutability: 'view', 68 | type: 'function' 69 | }, 70 | { 71 | inputs: [], 72 | name: 'getCurrentBlockDifficulty', 73 | outputs: [ 74 | { 75 | internalType: 'uint256', 76 | name: 'difficulty', 77 | type: 'uint256' 78 | } 79 | ], 80 | stateMutability: 'view', 81 | type: 'function' 82 | }, 83 | { 84 | inputs: [], 85 | name: 'getCurrentBlockGasLimit', 86 | outputs: [ 87 | { 88 | internalType: 'uint256', 89 | name: 'gaslimit', 90 | type: 'uint256' 91 | } 92 | ], 93 | stateMutability: 'view', 94 | type: 'function' 95 | }, 96 | { 97 | inputs: [], 98 | name: 'getCurrentBlockTimestamp', 99 | outputs: [ 100 | { 101 | internalType: 'uint256', 102 | name: 'timestamp', 103 | type: 'uint256' 104 | } 105 | ], 106 | stateMutability: 'view', 107 | type: 'function' 108 | }, 109 | { 110 | inputs: [ 111 | { 112 | internalType: 'address', 113 | name: 'addr', 114 | type: 'address' 115 | } 116 | ], 117 | name: 'getEthBalance', 118 | outputs: [ 119 | { 120 | internalType: 'uint256', 121 | name: 'balance', 122 | type: 'uint256' 123 | } 124 | ], 125 | stateMutability: 'view', 126 | type: 'function' 127 | }, 128 | { 129 | inputs: [], 130 | name: 'getLastBlockHash', 131 | outputs: [ 132 | { 133 | internalType: 'bytes32', 134 | name: 'blockHash', 135 | type: 'bytes32' 136 | } 137 | ], 138 | stateMutability: 'view', 139 | type: 'function' 140 | } 141 | ] 142 | -------------------------------------------------------------------------------- /lib/wc.ts: -------------------------------------------------------------------------------- 1 | import { configureChains, createConfig, watchAccount, watchNetwork, type GetNetworkResult } from '@wagmi/core' 2 | import { EthereumClient, w3mConnectors, w3mProvider } from '@web3modal/ethereum' 3 | import { reactive, toRaw, watch } from 'vue' 4 | import { publicProvider } from 'wagmi/providers/public' 5 | 6 | import { state as accountState, disconnect } from './account' 7 | import { state as chainState } from './chain' 8 | import { Events } from './enums' 9 | import { $emit } from './event' 10 | import { $log } from './log' 11 | import { state as optionsState } from './options' 12 | import type { BufferChain, WcState } from './types' 13 | import { initWeb3Modal, web3Modal } from './web3Modal' 14 | 15 | let onChangeHandler: any 16 | export const state = reactive({ 17 | client: null 18 | }) 19 | 20 | function toLowerCase(text: any) { 21 | return String(text).toLowerCase() 22 | } 23 | 24 | async function onChange( 25 | [newBufferAccount, newBufferChain]: [any, BufferChain], 26 | [prevBufferAccount, prevBufferChain]: [any, BufferChain] 27 | ) { 28 | if ( 29 | optionsState.disconnectUnknownChain && 30 | ((!prevBufferAccount && optionsState.disconnectUnknownChain) || prevBufferAccount) && 31 | newBufferChain && 32 | !optionsState.chains.some((item) => item.id === newBufferChain.id) 33 | ) { 34 | await disconnect() 35 | if (prevBufferChain) { 36 | $emit(Events.Disconnected) 37 | $log(`account ${newBufferAccount.address} disconnected from ${toLowerCase(prevBufferChain.name)} chain.`) 38 | } 39 | 40 | $emit(Events.UnknownChain, { chain: newBufferChain }) 41 | $log('switched to unsupported chain.') 42 | 43 | return 44 | } 45 | 46 | if (prevBufferAccount?.address !== newBufferAccount?.address && !prevBufferChain?.unsupported) { 47 | if (prevBufferAccount) { 48 | $emit(Events.Disconnected) 49 | $log(`account ${prevBufferAccount.address} disconnected from ${toLowerCase(prevBufferChain.name)} chain.`) 50 | } 51 | 52 | if (newBufferAccount) { 53 | $emit(Events.Connected, { chain: chainState.bufferChain, account: accountState.bufferAccount }) 54 | $log(`account ${newBufferAccount.address} connected to ${toLowerCase(newBufferChain.name)} chain.`) 55 | } 56 | } 57 | 58 | if (prevBufferChain && newBufferChain && prevBufferChain.id !== newBufferChain.id) { 59 | if (optionsState.reconnectToChain) { 60 | $emit(Events.Disconnected) 61 | $log(`account ${prevBufferAccount.address} disconnected from ${toLowerCase(prevBufferChain.name)} chain.`) 62 | 63 | $emit(Events.Connected, { chain: chainState.bufferChain, account: accountState.bufferAccount }) 64 | $log(`account ${newBufferAccount.address} connected to ${toLowerCase(newBufferChain.name)} chain.`) 65 | } else { 66 | $emit(Events.ChainSwitched, { chain: newBufferChain }) 67 | $log(`account ${newBufferAccount.address} switched to ${toLowerCase(newBufferChain.name)} chain.`) 68 | } 69 | } 70 | } 71 | 72 | function emitOnChange( 73 | [newBufferAccount, newBufferChain]: [any, BufferChain], 74 | [prevBufferAccount, prevBufferChain]: [any, BufferChain] 75 | ) { 76 | clearTimeout(onChangeHandler) 77 | onChangeHandler = setTimeout(onChange, 200, [newBufferAccount, newBufferChain], [prevBufferAccount, prevBufferChain]) 78 | } 79 | 80 | export function init() { 81 | if (web3Modal.value) return 82 | 83 | const chains = toRaw(optionsState.chains) 84 | const providers = [] 85 | 86 | if (optionsState.enableCustomProvider) { 87 | providers.push(publicProvider()) 88 | } else { 89 | providers.push(w3mProvider({ projectId: optionsState.projectId })) 90 | } 91 | 92 | const { publicClient, webSocketPublicClient } = configureChains(chains, providers) 93 | 94 | const wagmiConfig = createConfig({ 95 | autoConnect: optionsState.autoConnect, 96 | connectors: w3mConnectors({ 97 | projectId: optionsState.projectId, 98 | chains: chains 99 | }), 100 | publicClient, 101 | webSocketPublicClient 102 | }) 103 | 104 | watchNetwork((data: GetNetworkResult) => { 105 | if (data.chain?.unsupported) { 106 | data.chain.name = 'Unsupported' 107 | } 108 | chainState.bufferChain = data.chain || null 109 | }) 110 | watchAccount((data) => { 111 | accountState.bufferAccount = data.address ? data : null 112 | }) 113 | 114 | // @ts-ignore 115 | watch([() => accountState.bufferAccount, () => chainState.bufferChain], emitOnChange) 116 | 117 | const client = new EthereumClient(wagmiConfig, chains) 118 | state.client = client 119 | initWeb3Modal(client) 120 | } 121 | -------------------------------------------------------------------------------- /lib/web3Modal.ts: -------------------------------------------------------------------------------- 1 | import type { ModalCtrlState, ThemeCtrlState } from '@web3modal/core/dist/_types/src/types/controllerTypes' 2 | import { type EthereumClient } from '@web3modal/ethereum' 3 | import { Web3Modal } from '@web3modal/html' 4 | import { ref, type Ref } from 'vue' 5 | 6 | import { Events } from './enums' 7 | import { $emit } from './event' 8 | import { state as optionsState, setOptions } from './options' 9 | 10 | export const web3Modal: Ref = ref(null) 11 | 12 | export function setTheme(web3modalOptions: ThemeCtrlState) { 13 | setOptions({ web3modalOptions }) 14 | 15 | web3Modal.value?.setTheme({ 16 | themeMode: optionsState.web3modalOptions?.themeMode, 17 | themeVariables: optionsState.web3modalOptions?.themeVariables 18 | }) 19 | } 20 | 21 | export function initWeb3Modal(ethereumClient: EthereumClient) { 22 | web3Modal.value = new Web3Modal( 23 | { 24 | projectId: optionsState.projectId, 25 | ...(optionsState?.web3modalOptions || {}) 26 | }, 27 | ethereumClient 28 | ) 29 | 30 | web3Modal.value?.subscribeModal(({ open }: ModalCtrlState) => { 31 | $emit(Events.ModalStateChanged, open) 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kolirt/vue-web3-auth", 3 | "version": "2.3.4", 4 | "type": "module", 5 | "description": "Web3 authentication for Vue3 apps based on WalletConnect Web3Modal v2", 6 | "author": "kolirt", 7 | "private": false, 8 | "license": "MIT", 9 | "keywords": [ 10 | "vue", 11 | "vue3", 12 | "vuejs", 13 | "web3", 14 | "web3vue", 15 | "vueweb3", 16 | "metamask", 17 | "ethereum", 18 | "wallet", 19 | "walletconnect", 20 | "dapp", 21 | "web3modal", 22 | "web3modalvue", 23 | "crypto", 24 | "web3auth", 25 | "wagmi", 26 | "viem", 27 | "ethers" 28 | ], 29 | "scripts": { 30 | "build-lib": "run-p type-check build-only-lib", 31 | "build-only-lib": "vite build -c vite.lib.config.ts", 32 | "dev-demo": "vite serve -c vite.demo.config.ts", 33 | "build-demo": "vite build -c vite.demo.config.ts", 34 | "preview-demo": "vite preview -c vite.demo.config.ts", 35 | "type-check": "vue-tsc --noEmit -p tsconfig.json --composite false", 36 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore --ignore-path .eslintignore", 37 | "format": "prettier --write \"**/*.{ts,js,cjs,vue,json,prettierrc}\"" 38 | }, 39 | "pre-commit": [ 40 | "lint", 41 | "type-check" 42 | ], 43 | "files": [ 44 | "dist" 45 | ], 46 | "typings": "./dist/vue-web3-auth.d.ts", 47 | "main": "./dist/vue-web3-auth.umd.cjs", 48 | "module": "./dist/vue-web3-auth.js", 49 | "exports": { 50 | ".": { 51 | "types": "./dist/vue-web3-auth.d.ts", 52 | "import": "./dist/vue-web3-auth.js", 53 | "require": "./dist/vue-web3-auth.umd.cjs" 54 | }, 55 | "./package.json": "./package.json" 56 | }, 57 | "repository": { 58 | "type": "git", 59 | "url": "https://github.com/kolirt/vue-web3-auth" 60 | }, 61 | "bugs": { 62 | "url": "https://github.com/kolirt/vue-web3-auth/issues" 63 | }, 64 | "homepage": "https://github.com/kolirt/vue-web3-auth#readme", 65 | "peerDependencies": { 66 | "vue": ">=3" 67 | }, 68 | "dependencies": { 69 | "@wagmi/core": "1.4.13", 70 | "@web3modal/ethereum": "2.7.1", 71 | "@web3modal/html": "2.7.1", 72 | "js-event-bus": "1.1.1", 73 | "viem": "1.21.4", 74 | "wagmi": "1.4.13" 75 | }, 76 | "devDependencies": { 77 | "vue": "^3.3.2", 78 | "bootstrap": "5.3.0", 79 | "@rushstack/eslint-patch": "^1.2.0", 80 | "@tsconfig/node18": "^2.0.1", 81 | "@types/node": "^18.16.8", 82 | "@vitejs/plugin-vue": "^4.2.3", 83 | "@vue/eslint-config-prettier": "^8.0.0", 84 | "@vue/eslint-config-typescript": "^11.0.3", 85 | "@vue/tsconfig": "^0.4.0", 86 | "eslint": "^8.39.0", 87 | "eslint-plugin-vue": "^9.11.0", 88 | "npm-run-all": "^4.1.5", 89 | "pre-commit": "^1.2.2", 90 | "prettier": "^3.2.5", 91 | "prettier-plugin-organize-attributes": "^1.0.0", 92 | "prettier-plugin-organize-imports": "^3.2.4", 93 | "typescript": "~5.0.4", 94 | "vite": "^4.3.5", 95 | "vite-plugin-dts": "^2.3.0", 96 | "vite-plugin-eslint": "^1.8.1", 97 | "vue-tsc": "^1.6.4" 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 108 | 109 | 232 | 233 | 234 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import App from './App.vue' 2 | 3 | import 'bootstrap/dist/css/bootstrap.min.css' 4 | import { createApp } from 'vue' 5 | 6 | import { Chains, createWeb3Auth } from '../lib' 7 | 8 | const app = createApp(App) 9 | 10 | app.use( 11 | createWeb3Auth({ 12 | autoInit: true, 13 | projectId: '57a3047717eb3ab7e00969b66dfbbed8', 14 | chains: [Chains.bsc, Chains.mainnet, Chains.polygon], 15 | autoConnect: true, 16 | disconnectUnknownChain: true, 17 | reconnectToChain: true, 18 | logEnabled: true, 19 | enableCustomProvider: true, 20 | web3modalOptions: { 21 | themeMode: 'light', 22 | themeVariables: { 23 | '--w3m-accent-color': '#0d6efd', 24 | '--w3m-background-color': '#0d6efd', 25 | '--w3m-background-border-radius': '0.375rem', 26 | '--w3m-container-border-radius': '0.375rem', 27 | '--w3m-wallet-icon-border-radius': '0.375rem', 28 | '--w3m-wallet-icon-large-border-radius': '0.375rem', 29 | '--w3m-wallet-icon-small-border-radius': '0.375rem', 30 | '--w3m-input-border-radius': '0.375rem', 31 | '--w3m-notification-border-radius': '0.375rem', 32 | '--w3m-button-border-radius': '0.375rem', 33 | '--w3m-secondary-button-border-radius': '0.375rem', 34 | '--w3m-icon-button-border-radius': '0.375rem', 35 | '--w3m-button-hover-highlight-border-radius': '0.375rem' 36 | } 37 | } 38 | }) 39 | ) 40 | 41 | app.mount('#app') 42 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNEXT", 4 | "module": "esnext", 5 | "lib": ["ESNext", "DOM"], 6 | "jsx": "preserve", 7 | "jsxFactory": "h", 8 | "strict": true, 9 | "moduleResolution": "node", 10 | "allowSyntheticDefaultImports": true, 11 | "verbatimModuleSyntax": true, 12 | "esModuleInterop": true, 13 | "skipLibCheck": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "resolveJsonModule": true 16 | }, 17 | "exclude": ["test", "demo", "node_modules", "examples"] 18 | } 19 | -------------------------------------------------------------------------------- /vite.demo.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import vue from '@vitejs/plugin-vue' 4 | import { resolve } from 'path' 5 | import { defineConfig } from 'vite' 6 | 7 | export default defineConfig({ 8 | base: '/vue-web3-auth/', 9 | plugins: [vue()], 10 | resolve: { 11 | alias: { 12 | // @ts-ignore 13 | '@': fileURLToPath(new URL('./src', import.meta.url)), 14 | lib: fileURLToPath(new URL('./lib', import.meta.url)) 15 | } 16 | }, 17 | build: { 18 | outDir: resolve(__dirname, './demo'), 19 | emptyOutDir: true 20 | } 21 | }) 22 | -------------------------------------------------------------------------------- /vite.lib.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { defineConfig } from 'vite' 3 | import dts from 'vite-plugin-dts' 4 | import eslint from 'vite-plugin-eslint' 5 | import pkg from './package.json' 6 | 7 | export default defineConfig({ 8 | plugins: [ 9 | dts({ 10 | tsConfigFilePath: './tsconfig.json', 11 | rollupTypes: true 12 | }), 13 | eslint() 14 | ], 15 | build: { 16 | lib: { 17 | name: 'vue-web3-auth', 18 | formats: ['es', 'umd'], 19 | entry: resolve(__dirname, 'lib/index.ts'), 20 | fileName: 'vue-web3-auth' 21 | }, 22 | emptyOutDir: true, 23 | rollupOptions: { 24 | external: Object.keys({ ...pkg.dependencies, ...pkg.devDependencies }), 25 | output: { 26 | globals: { 27 | ...(() => { 28 | const obj: Record = {} 29 | Object.keys({ ...pkg.dependencies, ...pkg.devDependencies }).forEach((key) => { 30 | obj[key] = key 31 | }) 32 | return obj 33 | })() 34 | } 35 | } 36 | } 37 | } 38 | }) 39 | --------------------------------------------------------------------------------