diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 8bb95cb..cf2b9ad 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -custom: ['https://arbiscan.io/address/0x9D75F4EbcB8e7669E59dcc27CBadC698E0F77187#internaltx'] +custom: ['https://arbiscan.io/address/0x9D75F4EbcB8e7669E59dcc27CBadC698E0F77187#internaltx', 'https://explorer.gitcoin.co/#/round/424/0xd4cc0dd193c7dc1d665ae244ce12d7fab337a008/0xd4cc0dd193c7dc1d665ae244ce12d7fab337a008-75'] diff --git a/README.md b/README.md index 8db52d1..41a9a1b 100644 --- a/README.md +++ b/README.md @@ -26,153 +26,55 @@

-## Documentation +# Vue Dapp -- v1: Work in progress, see [Discussion#141](https://github.com/vu3th/vue-dapp/discussions/141) - - -Brief versions and functionalities are as follows: - -- v0.12.x: Add bitget wallet -- v0.11.x: Uses ethers v5 with WalletConnect dependencies update. -- v0.10.x: Uses ethers v6 and supports WalletConnect v2. -- v0.9.x: Uses ethers v5 and supports WalletConnect v2. -- Before v0.8.x: Uses ethers v5 and does not support WalletConnect v2. +Vue Dapp v1 is working in progress, see [Discussion#141](https://github.com/vu3th/vue-dapp/discussions/141). I would probably release a stable version by the end of 2023. I recommend keeping an eye on [vue3-dapp-starter](https://github.com/vu3th/vue3-dapp-starter) and [nuxt-dapp](https://github.com/vu3th/nuxt-dapp), as it strives to maintain a development-friendly version whenever possible. -Please be cautious when using the documentation below, as it has not been updated for some time. -- [Documentation (v0.9.x)](https://vue-dapp-docs.netlify.app/) -- [Migrating to v0.5.x ~ v0.9.x](https://vue-dapp-docs.netlify.app/migration) +## Monorepo Architecture -## Packages +library -| Package | Description | +| Name | Description | | ----------------------- | ------------------------------------------------- | | @vue-dapp/core | useWalletStore, connector, utils, and metamask... | | @vue-dapp/vd-board | Vue components for connecting wallet | | @vue-dapp/walletconnect | WalletConnect integration | -| @vue-dapp/legacy | vue-dapp version below v1 | -| @vue-dapp/docs | documentation | -| @vue-dapp/app | Nuxt 3 demo for v1 | -| @vue-dapp/demo | Vue 3 demo for @vue-dapp/legacy | +app -## Installation (below v0.10.x) +| Name | Description | +| -------------- | ------------------ | +| @vue-dapp/app | Nuxt 3 demo for v1 | +| @vue-dapp/docs | documentation | -```bash -yarn add ethers vue-dapp -``` +legacy -If you want to support more wallet providers not only MetaMask, you should install respective packages to enable the dynamic import. +| Name | Description | +| ---------------- | ----------------------------- | +| @vue-dapp/legacy | vue-dapp version below v1 | +| @vue-dapp/demo | Vue demo for @vue-dapp/legacy | -- Support WalletConnect -```bash -yarn add @walletconnect/web3-provider -``` -- Support Coinbase Wallet -```bash -yarn add @coinbase/wallet-sdk -``` +## Installation -- Support Gnosis Safe ```bash -yarn add @gnosis.pm/safe-apps-provider @gnosis.pm/safe-apps-sdk +yarn add @vue-dapp/core @vue-dapp/vd-board ``` -## Quick Start - -Step 1. Add plugin to your app: - -```javascript -import { VueDapp } from "vue-dapp"; -const app = createApp(App); -app.use(VueDapp); -app.mount("#app"); -``` +If you want to support more wallet providers not only MetaMask, you should install respective packages. -Step 2. By default, VueDapp includes `Mainnet` and `Goerli` networks, but you can extend it to include other networks: - -```javascript -app.use(VueDapp, { - autoConnect: true, // Automatically connect MetaMask wallet when the page is loaded - networks: { - 80001: { - chainId: ethers.utils.hexValue(80001), - blockExplorerUrls: ['https://mumbai.polygonscan.com/'], - chainName: 'Mumbai', - rpcUrls: ['https://rpc-mumbai.maticvigil.com/'], - nativeCurrency: { - name: 'Mumbai', - decimals: 18, - symbol: 'MATIC', - }, - }, - 42161: { - ... - }, - }, -}); - -``` -For more examples please check: -https://github.com/wagmi-dev/wagmi/blob/main/packages/core/src/constants/chains.ts - - -Step 3. Add `` to your `App.vue` and add a button to open the board: - -```vue - - -``` - -Step 4. Construct your connectors and use composable functions in your scripts: - -```js -import { - MetaMaskConnector, - WalletConnectConnector, - CoinbaseWalletConnector, - useBoard, -} from "vue-dapp"; - -setup() { - const { open } = useBoard(); - const infuraId = ""; - const connectors = [ - new MetaMaskConnector({ - appUrl: "http://localhost:3000", - }), - new WalletConnectConnector({ - qrcode: true, - rpc: { - 1: `https://mainnet.infura.io/v3/${infuraId}`, - 4: `https://rinkeby.infura.io/v3/${infuraId}`, - }, - }), - new CoinbaseWalletConnector({ - appName: "Vue Dapp", - jsonRpcUrl: `https://mainnet.infura.io/v3/${infuraId}`, - }), - ]; - return { - connectors, - open, - }; -} +### WalletConnect +```bash +yarn add @vue-dapp/walletconnect ``` -Take a look at [Configurations](https://vue-dapp-docs.netlify.app/configurations) for more informations about Vue CLI, Vite, and Nuxt3 configurations. - -To see the demo code, check it out [here](https://github.com/vu3th/vue-dapp/blob/main/demo/src/App.vue). - ## Support 🙏 -Gitcoin Grants 18: https://explorer.gitcoin.co/#/round/10/0x8de918f0163b2021839a8d84954dd7e8e151326d/0x8de918f0163b2021839a8d84954dd7e8e151326d-43 +Gitcoin Grants 19: https://explorer.gitcoin.co/#/round/424/0xd4cc0dd193c7dc1d665ae244ce12d7fab337a008/0xd4cc0dd193c7dc1d665ae244ce12d7fab337a008-75 ## MIT license Copyright (c) 2021-present, Johnson Chen ([@chnejohnson](https://twitter.com/chnejohnson)) - diff --git a/app/components/Web3Provider.vue b/app/components/Web3Provider.vue index a1c35b4..07d63f6 100644 --- a/app/components/Web3Provider.vue +++ b/app/components/Web3Provider.vue @@ -6,37 +6,42 @@ import { ethers } from 'ethers' import { MetaMaskConnector, useWalletStore } from '@vue-dapp/core' import { WalletConnectConnector } from '@vue-dapp/walletconnect' import { Board } from '@vue-dapp/vd-board' +import '@vue-dapp/vd-board/dist/style.css' const dappStore = useDappStore() const { isConnected, user } = storeToRefs(dappStore) -const { onActivated, onChanged, onDeactivated } = useWalletStore() +const { onActivated, onChanged, onDeactivated, setDumb } = useWalletStore() +setDumb(false) -onActivated(async ({ address, provider }) => { +onActivated(async ({ address, provider, chainId }) => { + console.log('onActivated') const ethersProvider = new ethers.BrowserProvider(provider) const signer = await ethersProvider.getSigner() - const network = await ethersProvider.getNetwork() dappStore.setUser({ address, signer, - chainId: Number(network.chainId), + chainId, }) }) -onChanged(async ({ address, provider }) => { +onChanged(async ({ address, provider, chainId }) => { + console.log('onChanged') + const ethersProvider = new ethers.BrowserProvider(provider) const signer = await ethersProvider.getSigner() - const network = await ethersProvider.getNetwork() dappStore.setUser({ address, signer, - chainId: Number(network.chainId), + chainId, }) }) onDeactivated(() => { + console.log('onDeactivated') + dappStore.resetUser() }) @@ -93,6 +98,7 @@ watch(isConnected, () => { diff --git a/app/components/wallet/UserStatus.vue b/app/components/wallet/UserStatus.vue index e0e055c..89e5c3c 100644 --- a/app/components/wallet/UserStatus.vue +++ b/app/components/wallet/UserStatus.vue @@ -8,7 +8,7 @@ import { useBoardStore } from '@vue-dapp/vd-board' const { open } = useBoardStore() const { disconnect } = useWalletStore() -const { connector, status, address, isConnected } = storeToRefs(useWalletStore()) +const { connector, status, address, isConnected, dumb } = storeToRefs(useWalletStore()) const dappStore = useDappStore() const { isNetworkUnmatched } = storeToRefs(dappStore) diff --git a/app/nuxt.config.ts b/app/nuxt.config.ts index 30bdc58..0a7bbf3 100644 --- a/app/nuxt.config.ts +++ b/app/nuxt.config.ts @@ -1,5 +1,3 @@ -import { nodePolyfills } from 'vite-plugin-node-polyfills' - // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ devtools: { enabled: true }, @@ -59,7 +57,4 @@ export default defineNuxtConfig({ ], }, }, - vite: { - plugins: [nodePolyfills()], - }, }) diff --git a/app/package.json b/app/package.json index 840fe24..26ef1ea 100644 --- a/app/package.json +++ b/app/package.json @@ -17,8 +17,6 @@ "@vue-dapp/walletconnect": "workspace:^", "@vueuse/core": "^10.5.0", "@vueuse/nuxt": "^10.5.0", - "@walletconnect/ethereum-provider": "^2.10.2", - "@walletconnect/modal": "^2.6.2", "copy-to-clipboard": "^3.3.3", "ethers": "6.8.0", "nuxt-icon": "^0.5.0", @@ -36,7 +34,6 @@ "postcss": "^8.4.20", "postcss-custom-properties": "^13.3.2", "sass": "^1.69.3", - "vite-plugin-node-polyfills": "^0.15.0", "vue": "^3.3.4", "vue-router": "^4.2.5" } diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index 79b086c..600603d 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -18,12 +18,12 @@ module.exports = { repo: 'chnejohnson/vue-dapp', nav: [ { - text: 'v0.7.1', + text: 'v1.0.0-alpha', link: 'https://github.com/vu3th/vue-dapp/releases', }, { text: 'Demo', - link: 'https://vuedapp.vercel.app/', + link: 'https://vue-dapp.vercel.app/', }, ], sidebar: [ @@ -34,66 +34,26 @@ module.exports = { text: 'Getting Started', link: '/', }, + // { + // text: 'Migrating to v1', + // link: '/migration', + // }, { - text: 'Migrating to v0.5.x', - link: '/migration', - }, - { - text: 'Configurations', - link: '/configurations', + text: 'Examples', + link: '/examples', }, { text: 'Contributing', link: '/contributing', }, - { - text: 'Resources', - link: '/resources', - }, ], }, { text: 'API', items: [ { - text: 'Plugin Options', - link: '/api/plugin-options', - }, - { - text: 'Components', - link: '/api/components', - }, - { - text: 'Connectors', - link: '/api/connectors', - }, - { - text: 'Constants', - link: '/api/constants', - }, - { - text: 'Directives', - link: '/api/directives', - }, - { - text: 'useWallet', - link: '/api/use-wallet', - }, - { - text: 'useEthers', - link: '/api/use-ethers', - }, - { - text: 'useEthersHooks', - link: '/api/use-ethers-hooks', - }, - { - text: 'useMulticall', - link: '/api/use-multicall', - }, - { - text: 'Utilities', - link: '/api/utilities', + text: '@vue-dapp/vd-board', + link: '/api/vd-board.md', }, ], }, diff --git a/docs/api/components.md b/docs/api/components.md deleted file mode 100644 index a869212..0000000 --- a/docs/api/components.md +++ /dev/null @@ -1,28 +0,0 @@ -# Components - -- `` - for wallet board. -- `` - for a simple modal. - -[source code](https://github.com/vu3th/vue-dapp/tree/main/src/components) - -## vd-board - -### Usage -```vue - - - -``` - -### Props - -- `dark`: boolean, defaults: false - When set to true, the board will be set to dark mode. -- `connectors`: Connectors[], defaults: [] - An array of [Connectors](/api/connectors.html) that defines the wallet options on board. -- `autoConnectErrorHandler`: Function, default: () => void - catch error when a auto-connect error occurs. -- `connectErrorHandler`: Function, default: () => void - catch error when a connect error occurs. -### Slots - -- `connecting` - Provide a custom content when connecting wallet. -- `loading` - Provide a custom content when loading data. diff --git a/docs/api/connectors.md b/docs/api/connectors.md deleted file mode 100644 index f9b9193..0000000 --- a/docs/api/connectors.md +++ /dev/null @@ -1,245 +0,0 @@ -# Connectors - -[source code](https://github.com/vu3th/vue-dapp/tree/main/src/connectors) - -## Connector Interface - -```ts -declare abstract class Connector { - abstract readonly name: string; - readonly options: Options; - constructor(options: Options); - abstract connect(): Promise>; - abstract getProvider(): Promise; - abstract disconnect(): Promise; - abstract onDisconnect(handler: (...args: any[]) => any): void; - abstract onAccountsChanged(handler: (accounts: string[]) => any): void; - abstract onChainChanged(handler: (chainId: number) => any): void; - switchChain?(chainId: number): Promise; -} -declare type ConnectorData = { - account: string; - provider: Provider; -}; -``` - -## MetaMaskConnector - -The MetaMaskConnector supports connecting with MetaMask. -* Docs: https://docs.metamask.io/guide/ethereum-provider.html -* JSON RPC API: https://metamask.github.io/api-playground/api-documentation - -### Usage -```ts -const connector = new MetaMaskConnector({ - appUrl: 'http://localhost:3000', -}), -``` - -### Configuration -- `appUrl` (optional): Add deep link to MetaMask wallet on mobile device, see https://github.com/vu3th/vue-dapp/pull/29 - - -### Types -```ts -/** - * MetaMask - * Docs: https://docs.metamask.io/guide/ethereum-provider.html - * JSON RPC API: https://metamask.github.io/api-playground/api-documentation - */ -interface MetaMaskProvider extends MetaMaskEthereumProvider { - isMetaMask: boolean; - providers?: MetaMaskProvider[]; - isConnected: () => boolean; - request: (request: { - method: string; - params?: any[] | undefined; - }) => Promise; - selectedAddress: string; -} -/** - * source: @metamask/detect-provider - * https://github.com/MetaMask/detect-provider/blob/main/src/index.ts - */ -interface MetaMaskEthereumProvider { - isMetaMask?: boolean; - once(eventName: string | symbol, listener: (...args: any[]) => void): this; - on(eventName: string | symbol, listener: (...args: any[]) => void): this; - off(eventName: string | symbol, listener: (...args: any[]) => void): this; - addListener(eventName: string | symbol, listener: (...args: any[]) => void): this; - removeListener(eventName: string | symbol, listener: (...args: any[]) => void): this; - removeAllListeners(event?: string | symbol): this; -} -interface Window { - ethereum?: MetaMaskProvider; -} -declare type MetaMaskConnectorOptions = { - appUrl?: string; -}; -declare class MetaMaskConnector extends Connector { - #private; - readonly name = "metaMask"; - constructor(options?: MetaMaskConnectorOptions); - static checkConnection(): Promise; - connect(): Promise<{ - account: any; - provider: MetaMaskProvider; - }>; - getProvider(): Promise; - /** - * MetaMask do not support programmatic disconnect. - * @see https://github.com/MetaMask/metamask-extension/issues/10353 - */ - disconnect(): Promise; - /** - * @note MetaMask disconnect event would be triggered when the specific chain changed (like L2 network), - * and will not be triggered when a user clicked disconnect in wallet... - */ - onDisconnect(handler: (error: ProviderRpcError) => void): void; - onAccountsChanged(handler: (accounts: string[]) => void): void; - onChainChanged(handler: (chainId: number) => void): void; - switchChain(chainId: number): Promise; - addChain(networkDetails: AddEthereumChainParameter): Promise; -} -interface AddEthereumChainParameter { - chainId: string; - chainName: string; - nativeCurrency: { - name?: string; - symbol: string; - decimals: number; - }; - rpcUrls: string[]; - blockExplorerUrls?: string[]; - iconUrls?: string[]; -} -``` -## WalletConnectConnector -The WalletConnectConnector supports connecting with WalletConnect. - -For more details, see WalletConnect v1.0 docs -* Docs: https://docs.walletconnect.com/quick-start/dapps/web3-provider -* Test Wallet: https://test.walletconnect.org/ -* Source: https://github.com/WalletConnect/walletconnect-monorepo/blob/v1.0/packages/providers/web3-provider/src/index.ts - -### Usage -```ts -const connector = new WalletConnectConnector({ - qrcode: true, - rpc: { - 1: `https://mainnet.infura.io/v3/${infuraId}`, - 4: `https://rinkeby.infura.io/v3/${infuraId}`, - }, -}) -``` - -### Types -```ts -/** - * WalletConnect v1.0 \ - * Docs: https://docs.walletconnect.com/quick-start/dapps/web3-provider \ - * Test Wallet: https://test.walletconnect.org/ \ - * Source: https://github.com/WalletConnect/walletconnect-monorepo/blob/v1.0/packages/providers/web3-provider/src/index.ts - */ -interface IWalletConnectProvider extends WalletConnectProvider { -} -declare type WalletConnectOptions = ConstructorParameters[0]; -declare class WalletConnectConnector extends Connector { - #private; - readonly name = "walletConnect"; - constructor(options: WalletConnectOptions); - connect(): Promise<{ - account: string; - provider: WalletConnectProvider; - }>; - getProvider(): Promise; - disconnect(): Promise; - onDisconnect(handler: (code: number, reason: string) => void): void; - onAccountsChanged(handler: (accounts: string[]) => void): void; - onChainChanged(handler: (chainId: number) => void): void; - /** - * @error Not support for WalletConnect v1.0 - */ - switchChain(chainId: number): Promise; -} -``` - - -## Coinbase Wallet -The CoinbaseWalletConnector supports connecting with Coinbase Wallet using the [Coinbase Wallet SDK](https://docs.cloud.coinbase.com/wallet-sdk/docs/) - -### Usage -```ts -const connector = new CoinbaseWalletConnector({ - appName: 'Vue Dapp', - jsonRpcUrl: `https://mainnet.infura.io/v3/${infuraId}`, -}) -``` - -### Types -```ts -/** - * Coinbase Wallet SDK - * Docs: https://docs.cloud.coinbase.com/wallet-sdk/docs/ - */ -interface ICoinbaseWalletProvider extends CoinbaseWalletProvider { -} -declare type CoinbaseWalletConnectorOptions = CoinbaseWalletSDKOptions & { - jsonRpcUrl: string; - chainId?: number; -}; -declare class CoinbaseWalletConnector extends Connector { - #private; - readonly name = "coinbaseWallet"; - constructor(options: CoinbaseWalletConnectorOptions); - connect(): Promise<{ - account: string; - provider: CoinbaseWalletProvider; - }>; - getProvider(): Promise; - disconnect(): Promise; - /** - * @note CoinbaseWallet will reload page if it disconnected by wallet app. - * @todo experiment with the browser extension - */ - onDisconnect(handler: () => void): void; - onAccountsChanged(handler: (accounts: string[]) => void): void; - onChainChanged(handler: (chainId: number) => void): void; - /** - * @todo: add addChain() - */ - switchChain(chainId: number): Promise; -} -``` - -## Gnosis Safe -The SafeConnector supports running your Dapp inside the [Safe App](https://gnosis-safe.io/app/) with [Safe Apps SDK](https://docs.gnosis-safe.io/build/sdks) - -### Usage -```ts -const safe = new SafeConnector() -``` - - -### Types -```ts -declare const isServer: boolean; -declare const isIframe: boolean; -declare const isNotSafeApp: () => boolean; -declare class SafeConnector extends Connector { - #private; - readonly name = "safe"; - ready: boolean; - constructor(options?: Opts); - connect(): Promise<{ - account: string; - provider: SafeAppProvider; - }>; - getProvider(): Promise; - isSafeApp(): Promise; - disconnect(): Promise; - onDisconnect(handler: (error: ProviderRpcError) => void): void; - onAccountsChanged(handler: (accounts: string[]) => void): void; - onChainChanged(handler: (chainId: number) => void): void; -} -``` \ No newline at end of file diff --git a/docs/api/constants.md b/docs/api/constants.md deleted file mode 100644 index 517f8db..0000000 --- a/docs/api/constants.md +++ /dev/null @@ -1,52 +0,0 @@ -# Constants - -[source code](https://github.com/vu3th/vue-dapp/blob/main/src/constants/chainId.ts) - -## ChainId - -```ts -export enum ChainId { - Mainnet = 1, - Goerli = 5, -} -``` - -## CHAIN_NAMES -```ts -export const CHAIN_NAMES = { - [ChainId.Mainnet]: 'Mainnet', - [ChainId.Goerli]: 'Goerli', -} -``` - -## NETWORK_DETAILS - -```ts -export const NETWORK_DETAILS: { [key: number]: AddEthereumChainParameter } = { - [ChainId.Mainnet]: { - chainId: '0x' + ChainId.Mainnet.toString(16), - chainName: 'Mainnet', - rpcUrls: [ - 'https://cloudflare-eth.com', - 'https://rpc.ankr.com/eth', - 'https://main-rpc.linkpool.io', - ], - blockExplorerUrls: ['https://etherscan.io'], - nativeCurrency: { - symbol: 'ETH', - decimals: 18, - }, - }, - - [ChainId.Goerli]: { - chainId: '0x' + ChainId.Goerli.toString(16), - chainName: 'Goerli', - rpcUrls: ['https://goerli.optimism.io'], - blockExplorerUrls: ['https://goerli.etherscan.io'], - nativeCurrency: { - symbol: 'ETH', - decimals: 18, - }, - }, -} -``` \ No newline at end of file diff --git a/docs/api/directives.md b/docs/api/directives.md deleted file mode 100644 index f0167f9..0000000 --- a/docs/api/directives.md +++ /dev/null @@ -1,5 +0,0 @@ -# Directives - -- `v-click-outside` - -[source code](https://github.com/vu3th/vue-dapp/blob/main/src/directive.ts) diff --git a/docs/api/plugin-options.md b/docs/api/plugin-options.md deleted file mode 100644 index 1702001..0000000 --- a/docs/api/plugin-options.md +++ /dev/null @@ -1,57 +0,0 @@ -# Plugin Options - -- All properties in Plugin Options are optional - -## Types -```ts -type PluginOptions = { - autoConnect: boolean; - persistDisconnect?: boolean; - networks: { - [key: number]: AddEthereumChainParameter; - }; -}; -``` - -## autoConnect -- Default: false -- If set up to true, will trigger auto-connect when the page load - -## persistDisconnect -- Only take effect when autoConnect is true -- Default to true when autoConnect is true -- If set up to false, the page would trigger auto-connect even if user clicked disconnect button and refreshed the page - -## networks -[TBD] - -## Example -```ts -app.use(VueDapp, { - autoConnect: true, - networks: { - 80001: { - chainId: ethers.utils.hexValue(80001), - blockExplorerUrls: ['https://mumbai.polygonscan.com/'], - chainName: 'Mumbai', - rpcUrls: ['https://rpc-mumbai.maticvigil.com/'], - nativeCurrency: { - name: 'Mumbai', - decimals: 18, - symbol: 'MATIC', - }, - }, - 42161: { - chainId: ethers.utils.hexValue(42161), - blockExplorerUrls: ['https://arbiscan.io'], - chainName: 'Arbitrum One', - rpcUrls: ['https://arb1.arbitrum.io/rpc'], - nativeCurrency: { - name: 'Arbitrum', - symbol: 'ETH', - decimals: 18, - }, - }, - }, -}) -``` diff --git a/docs/api/use-ethers-hooks.md b/docs/api/use-ethers-hooks.md deleted file mode 100644 index c5d7bea..0000000 --- a/docs/api/use-ethers-hooks.md +++ /dev/null @@ -1,49 +0,0 @@ -# useEthersHooks - -Hook for watching provider from `useEthers` as follows: - -- `onActivated` - subscribe event when giving the provider. -- `onDeactivated` - subscribe event when removing the provider. -- `onChanged` - subscribe event when updating the provider. - -[source code](https://github.com/vu3th/vue-dapp/blob/main/src/composables/useEthersHooks.ts) - -## Usage - -```ts -const { onActivated, onDeactivated, onChanged } = useEthersHooks() - -onActivated(({ provider, address }) => { - call(provider, '0x6B175474E89094C44Da98b954EedeAC495271d0F', address) -}) - -onDeactivated(() => { - console.log('deactivated') -}) - -onChanged(() => { - console.log('change') -}) -``` -## Return Value -```ts -{ - onActivated: (hook: OnActivatedHook) => OnActivatedHook; - onChanged: (hook: OnChangedHook) => OnChangedHook; - onDeactivated: (hook: OnDeactivatedHook) => OnDeactivatedHook; -} -``` - -## Types -```ts -declare type EthersHooksContext = { - provider: Web3Provider - signer: Signer - network: Network - address: string - balance: bigint -} -declare type OnActivatedHook = (context: EthersHooksContext) => void -declare type OnChangedHook = (context: EthersHooksContext) => void -declare type OnDeactivatedHook = () => void -``` diff --git a/docs/api/use-ethers.md b/docs/api/use-ethers.md deleted file mode 100644 index c9efa78..0000000 --- a/docs/api/use-ethers.md +++ /dev/null @@ -1,44 +0,0 @@ -# useEthers - -Hook for accessing the connected wallet by ethers - -[source code](https://github.com/vu3th/vue-dapp/blob/main/src/composables/useEthers.ts) - -## Usage -```ts -const { address, balance, chainId, isActivated } = useEthers() - -onActivated(() => { - ... -}) - -return { - address, - balance -} -``` - -## Return Value -```typescript -{ - isActivated: Ref; - provider: Ref; - signer: Ref; - network: Ref<{ - name: string; - chainId: number; - ensAddress?: string | undefined; - _defaultProvider?: ((providers: any, options?: any) => any) | undefined; - } | null>; - address: Ref; - dnsAlias: Ref; - balance: Ref; - availableNetworks: Ref<{ - [key: number]: AddEthereumChainParameter; - }>; - chainId: vue.ComputedRef; - activate: typeof activate; - deactivate: () => void; - lookupDNS: typeof lookupDNS; -} -``` \ No newline at end of file diff --git a/docs/api/use-multicall.md b/docs/api/use-multicall.md deleted file mode 100644 index da04b20..0000000 --- a/docs/api/use-multicall.md +++ /dev/null @@ -1,79 +0,0 @@ -# useMulticall - -Hook for using [Multicall2](https://github.com/makerdao/multicall/blob/master/src/Multicall2.sol) -- `multicall` - contract of [Multicall2](https://github.com/makerdao/multicall/blob/master/src/Multicall2.sol) -- `blockNumber` -- `results` - return value depending on type `ContractCall[]` -- `call` - call `tryBlockAndAggregate` on [Multicall2](https://github.com/makerdao/multicall/blob/master/src/Multicall2.sol) - -[source code](https://github.com/vu3th/vue-dapp/blob/main/src/composables/useMulticall.ts) - -## Usage -```ts -const calls: ContractCall[] = [ - { - interface: ERC20Interface, - address: '', - method: 'name', - }, - { - interface: ERC20Interface, - address: '', - method: 'totalSupply', - }, - { - interface: ERC20Interface, - address: '', - method: 'decimals', - }, - { - interface: ERC20Interface, - address: '', - method: 'symbol', - }, - { - interface: ERC20Interface, - address: '', - method: 'balanceOf', - args: [], - }, -] - -const { call, results } = useMulticall(provider) - -await call(calls) - -const [ - [_name], - [_totalSupply], - [_decimals], - [_symbol], - { balance: _balance }, -] = results.value - -name.value = _name -totalSupply.value = _totalSupply -decimals.value = _decimals -symbol.value = _symbol -balance.value = (_balance as BigNumber).toBigInt() - -``` - -## Types -```ts -declare type ContractCall = { - interface: ContractInterface; - address: string; - method: string; - args?: any[]; -}; -declare function useMulticall(provider: Web3Provider | JsonRpcProvider): { - multicall: Multicall2; - blockNumber: vue_demi.Ref; - results: vue_demi.Ref<{ - [x: string]: any; - [x: number]: any; - }[]>; - call: (contractCalls: ContractCall[]) => Promise; -}; -``` diff --git a/docs/api/use-wallet.md b/docs/api/use-wallet.md deleted file mode 100644 index 66750c2..0000000 --- a/docs/api/use-wallet.md +++ /dev/null @@ -1,72 +0,0 @@ -# useWallet - -Hook for accessing the connected wallet. - -[source code](https://github.com/vu3th/vue-dapp/blob/main/src/composables/useWallet.ts) - -## Usage - -```ts -const { wallet, disconnect, onDisconnect, onAccountsChanged, onChainChanged } = useWallet() - -onDisconnect(() => { - console.log('disconnect') -}) - -onAccountsChanged(() => { - console.log('accounts changed') -}) - -onChainChanged((chainId: any) => { - console.log('chain changed', chainId) -}) - -return { - wallet -} -``` - -## Return Value -```typescript -{ - wallet: { - connector: { - readonly name: string; - readonly options: any; - connect: () => Promise>>; - getProvider: () => Promise; - disconnect: () => Promise; - onDisconnect: (handler: (...args: any[]) => any) => void; - onAccountsChanged: (handler: (accounts: string[]) => any) => void; - onChainChanged: (handler: (chainId: number) => any) => void; - switchChain?: ((chainId: number) => Promise) | undefined; - } | null; - provider: { - isMetaMask?: boolean | undefined; - isStatus?: boolean | undefined; - host?: string | undefined; - path?: string | undefined; - sendAsync?: ((request: { - method: string; - params?: any[] | undefined; - }, callback: (error: any, response: any) => void) => void) | undefined; - send?: ((request: { - method: string; - params?: any[] | undefined; - }, callback: (error: any, response: any) => void) => void) | undefined; - request?: ((request: { - method: string; - params?: any[] | undefined; - }) => Promise) | undefined; - } | null; - error: string; - status: ConnectionStatus; - }; - connectWith: (connector: Connector) => Promise; - disconnect: () => Promise; - autoConnect: (connectors: Connector[]) => Promise; - onDisconnect: (callback: OnDisconnectCallback) => void; - onAccountsChanged: (callback: OnAccountsChangedCallback) => void; - onChainChanged: (callback: OnChainChangedCallback) => void; -} -``` \ No newline at end of file diff --git a/docs/api/utilities.md b/docs/api/utilities.md deleted file mode 100644 index a22ef78..0000000 --- a/docs/api/utilities.md +++ /dev/null @@ -1,17 +0,0 @@ -# Utilities - -[source code](https://github.com/vu3th/vue-dapp/tree/main/src/utils) - -## Types - -```ts -declare function shortenAddress(address: string): string; -declare function displayEther(balance: BigNumber | bigint, fixed?: number): string; -declare function displayChainName(chainId: number): string; -declare function normalizeChainId(chainId: string | number): number; - -declare function checkInfuraId(infuraId: string): Promise; -declare function checkChainId(chainId: number): boolean; -``` - -[source code](https://github.com/vu3th/vue-dapp/tree/main/src/utils) \ No newline at end of file diff --git a/docs/api/vd-board.md b/docs/api/vd-board.md new file mode 100644 index 0000000..2591a94 --- /dev/null +++ b/docs/api/vd-board.md @@ -0,0 +1,38 @@ +# @vue-dapp/vd-board + +### Usage + +script +```ts +import { Board } from '@vue-dapp/vd-board' +import '@vue-dapp/vd-board/dist/style.css' + +const connectors = [ + new MetaMaskConnector() +] + +function connectErrorHandler(err: any) { + console.error('ConnectError', err) +} +function autoConnectErrorHandler(err: any) { + console.error('AutoConnectError', err) +} +``` + +template +```vue + +``` + +### Props + +- `dark`: boolean, defaults: false - When set to true, the board will be set to dark mode. +- `connectors`: Connectors[], defaults: [] +- `autoConnectErrorHandler`: Function, default: () => void - catch error when a auto-connect error occurs. +- `connectErrorHandler`: Function, default: () => void - catch error when a connect error occurs. \ No newline at end of file diff --git a/docs/configurations.md b/docs/configurations.md deleted file mode 100644 index 089a8e9..0000000 --- a/docs/configurations.md +++ /dev/null @@ -1,127 +0,0 @@ -# Configurations - -## Vue CLI - -- Example: [vuecli + vue-dapp starter](https://github.com/chnejohnson/vue3-dapp-starter/tree/vuecli) - -If you're using [Vue CLI](https://cli.vuejs.org/guide/creating-a-project.html), you have to install [node-polyfill-webpack-plugin](https://www.npmjs.com/package/node-polyfill-webpack-plugin) and add the plugin in `vue.config.js` as follows. - -```js -const { defineConfig } = require("@vue/cli-service"); -const NodePolyfillPlugin = require("node-polyfill-webpack-plugin"); - -module.exports = defineConfig({ - transpileDependencies: true, - configureWebpack: { - plugins: [new NodePolyfillPlugin()], - }, -}); -``` - -## Vite - -- Example: [vue3-dapp-starter](https://github.com/chnejohnson/vue3-dapp-starter) - -If you're using [Vite](https://vitejs.dev/), you should have the following settings in `vite.config.ts`: - - -```ts -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import rollupPolyfillNode from 'rollup-plugin-polyfill-node' -import nodeStdlibBrowser from 'node-stdlib-browser' - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [vue()], - resolve: { - // Enable polyfill node used in development to prevent from vite's browser compatibility warning - alias: { ...nodeStdlibBrowser }, - }, - optimizeDeps: { - // Enable polyfill node used in development, refer to https://github.com/sodatea/vite-plugin-node-stdlib-browser/blob/b17f417597c313ecd52c3e420ba8fc33bcbdae20/index.cjs#L17 - esbuildOptions: { - inject: [require.resolve('node-stdlib-browser/helpers/esbuild/shim')], - }, - }, - build: { - rollupOptions: { - plugins: [ - // Enable rollup polyfills plugin used in production bundling, refer to https://stackoverflow.com/a/72440811/10752354 - rollupPolyfillNode(), - ], - }, - commonjsOptions: { - transformMixedEsModules: true, // Enable @walletconnect/web3-provider which has some code in CommonJS - }, - }, -}) -``` - -:::info -Refer to [issue#20](https://github.com/vu3th/vue-dapp/issues/20) -::: - -## Nuxt3 - -- Example: [nuxt3 + vue-dapp starter](https://github.com/chnejohnson/vue3-dapp-starter/tree/nuxt3) - -If you're using [Nuxt3](https://v3.nuxtjs.org/), you should have following dependencies and `nuxt.config.js`. - -```json -"dependencies": { - "@nuxt/webpack-builder": "^3.0.0-rc.1", - "assert": "^2.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "url": "^0.11.0", - "vue-dapp": "^0.5.2" -}, -"devDependencies": { - "buffer": "^6.0.3", - "nuxt": "3.0.0-rc.1", - "process": "^0.11.10", - "vue-demi": "^0.12.5" -} -``` - -nuxt.config.js - -```js -import { defineNuxtConfig } from 'nuxt' -const webpack = require('webpack') - -// https://v3.nuxtjs.org/api/configuration/nuxt.config -export default defineNuxtConfig({ - builder: 'webpack', - hooks: { - 'webpack:config'(configs) { - configs[0].resolve.fallback = { - assert: require.resolve('assert/'), - stream: require.resolve('stream-browserify'), - http: require.resolve('stream-http'), - https: require.resolve('https-browserify'), - os: require.resolve('os-browserify/browser'), - url: require.resolve('url/'), - } - configs[0].plugins.push( - new webpack.ProvidePlugin({ - process: 'process/browser', - }), - ) - configs[0].plugins.push( - new webpack.ProvidePlugin({ - Buffer: ['buffer', 'Buffer'], - }), - ) - }, - }, -}) - -``` - -:::info -Refer to [issue#33](https://github.com/vu3th/vue-dapp/issues/33) -::: diff --git a/docs/contributing.md b/docs/contributing.md index e44a6ce..fd3516e 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,29 +1,3 @@ -# Contributing +# Contributing & Development Tips -Thanks for being interested in contributing to this project! - -Just submit your changes via pull request and I will review them before merging. - -If you are making a fix on the project, you can use the `main` branch and send a pull request. - -If you are adding a new features, please create a new branch with a name describing your feature (`my-new-feature`), push to your branch and then submit a pull request. - -## Development - -Clone this repo to your local machine and install the dependencies. - -```bash -yarn install -``` - -To run the demo, add `.env` for using your infura ID, and run: - -```bash -yarn dev -``` - -To run the docs: - -```bash -yarn dev:docs -``` +- You have to use `pnpm`, and run `pnpm install` in the root directory. diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 0000000..1e54ebb --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,4 @@ +# Examples + +- [vue3-dapp-starter](https://github.com/vu3th/vue3-dapp-starter) +- [nuxt-dapp](https://github.com/vu3th/nuxt-dapp) diff --git a/docs/index.md b/docs/index.md index 217702d..7a42122 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,114 +1,52 @@ -# Getting Started +# Vue Dapp -## Installation +Vue Dapp v1 is working in progress, see [Discussion#141](https://github.com/vu3th/vue-dapp/discussions/141). I would probably release a stable version by the end of 2023. -```bash -yarn add ethers vue-dapp -``` +I recommend keeping an eye on [vue3-dapp-starter](https://github.com/vu3th/vue3-dapp-starter) and [nuxt-dapp](https://github.com/vu3th/nuxt-dapp), as it strives to maintain a development-friendly version whenever possible. -If you want to support more wallet providers not only MetaMask, you should install respective packages to enable the dynamic import. -- Support WalletConnect -```bash -yarn add @walletconnect/web3-provider -``` +## Monorepo Architecture -- Support Coinbase Wallet -```bash -yarn add @coinbase/wallet-sdk -``` - -- Support Gnosis Safe -```bash -yarn add @gnosis.pm/safe-apps-provider @gnosis.pm/safe-apps-sdk -``` +library -## Quick Start +| Name | Description | +| ----------------------- | ------------------------------------------------- | +| @vue-dapp/core | useWalletStore, connector, utils, and metamask... | +| @vue-dapp/vd-board | Vue components for connecting wallet | +| @vue-dapp/walletconnect | WalletConnect integration | -Step 1. Add plugin to your app: +app -```javascript -import { VueDapp } from "vue-dapp"; +| Name | Description | +| -------------- | ------------------ | +| @vue-dapp/app | Nuxt 3 demo for v1 | +| @vue-dapp/docs | documentation | -const app = createApp(App); -app.use(VueDapp); -app.mount("#app"); -``` +legacy -Step 2. By default, VueDapp includes `Mainnet` and `Goerli` networks, but you can extend it to include other networks: - -```javascript -app.use(VueDapp, { - autoConnect: true, // Automatically connect MetaMask wallet when the page is loaded - networks: { - 80001: { - chainId: ethers.utils.hexValue(80001), - blockExplorerUrls: ['https://mumbai.polygonscan.com/'], - chainName: 'Mumbai', - rpcUrls: ['https://rpc-mumbai.maticvigil.com/'], - nativeCurrency: { - name: 'Mumbai', - decimals: 18, - symbol: 'MATIC', - }, - }, - 42161: { - ... - }, - }, -}); +| Name | Description | +| ---------------- | ----------------------------- | +| @vue-dapp/legacy | vue-dapp version below v1 | +| @vue-dapp/demo | Vue demo for @vue-dapp/legacy | -``` -For more examples please check: -https://github.com/wagmi-dev/wagmi/blob/main/packages/core/src/constants/chains.ts +## Installation -Step 3. Add `` to your `App.vue` and add a button to open the board: +```bash +yarn add @vue-dapp/core @vue-dapp/vd-board +``` -```vue +If you want to support more wallet providers not only MetaMask, you should install respective packages. - - +### WalletConnect +```bash +yarn add @vue-dapp/walletconnect ``` -Step 4. Construct your connectors and use composable functions in your scripts: - -```js -import { - MetaMaskConnector, - WalletConnectConnector, - CoinbaseWalletConnector, - useBoard, -} from "vue-dapp"; - -setup() -{ - const { open } = useBoard(); - const infuraId = ""; - const connectors = [ - new MetaMaskConnector({ - appUrl: "http://localhost:3000", - }), - new WalletConnectConnector({ - qrcode: true, - rpc: { - 1: `https://mainnet.infura.io/v3/${infuraId}`, - 4: `https://rinkeby.infura.io/v3/${infuraId}`, - }, - }), - new CoinbaseWalletConnector({ - appName: "Vue Dapp", - jsonRpcUrl: `https://mainnet.infura.io/v3/${infuraId}`, - }), - ]; - return { - connectors, - open, - }; -} -``` +## Support 🙏 + +Gitcoin Grants 19: https://explorer.gitcoin.co/#/round/424/0xd4cc0dd193c7dc1d665ae244ce12d7fab337a008/0xd4cc0dd193c7dc1d665ae244ce12d7fab337a008-75 -Take a look at [Configurations](https://vue-dapp-docs.netlify.app/configurations) for more informations about Vue CLI, -Vite, and Nuxt3 configurations. +## MIT license -To see the demo code, check it out [here](https://github.com/vu3th/vue-dapp/blob/main/demo/src/App.vue). +Copyright (c) 2021-present, Johnson Chen ([@chnejohnson](https://twitter.com/chnejohnson)) diff --git a/docs/migration.md b/docs/migration.md index 63c102c..ba182ec 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -1,64 +1,3 @@ -# Migrating to v0.5.x +# Migrating to v1 -If you are coming from an earlier version of vue-dapp, in order to update to versions above 0.5.x, you will need to make sure to update the following code. - -## Breaking changes - -- You have to construct your connectors and configure third-party providers as your wallet options on board. -- Pass your connectors to `` -- You don't need to add plugin options anymore. - -### Before - -```ts -// main.ts -app.use(VueDapp, { - infuraId: '...', - appName: '...', - appUrl: '...', -}) -``` - -App.vue -```vue -