Search code examples
javascriptvue.jsvuejs3solanasolana-web3js

How to detect when DOM has been updated by solana-wallets-vue with Vue3?


solana-wallets-vue is the VueJS version of solana-wallet. It added a button to connect your browser wallet.

This works, and connects a wallet, but right after connecting the wallet I need to know what the wallet address (public key) is.

Using all of Vue3's life cycle hooks, I can only determine what the wallet address is if I refresh, and it will then show up in onMounted

Their component is added like so

<!-- ? Wallet Connect -->
<wallet-multi-button dark></wallet-multi-button>

This is the markup that is injected into the app with their component

<div class="swv-dark">
  <button class="swv-button swv-button-trigger"> Select Wallet </button>
</div>

After I connect my Solana wallet, the markup will change like so, but no Vue Lifecycle event triggers:

<div class="swv-dark">
  <div class="swv-dropdown">
    <button
      class="swv-button swv-button-trigger"
      aria-expanded="false"
      title="DqabcUFkt9UvV9wDEtK59nySRPhy71n3JuFkCcw854vL"
      style="pointer-events: auto;"
    >
      <i class="swv-button-icon">
        <img src="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjM0IiB3aWR0aD0iMzQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI" alt="Phantom icon">
      </i>
      <p>Dqab..54vL</p>
    </button>
    <ul aria-label="dropdown-list" class="swv-dropdown-list" role="menu">
      <li class="swv-dropdown-list-item" role="menuitem">Copy address</li>
      <li class="swv-dropdown-list-item" role="menuitem"> Change wallet </li>
      <li class="swv-dropdown-list-item" role="menuitem"> Disconnect </li>
    </ul>
  </div>
</div>

In the onMounted LifeCycle, I am able to see the wallet address / public, but again only if I refresh:

onMounted(async () => {
  console.log('onMounted')
  const { publicKey, sendTransaction } = useWallet()
  
  if (publicKey && publicKey.value) {
    console.log('publicKey', publicKey.value.toBase58())
  }
})

Solution

  • Used watch to be able to accomplish this task.

    Doc: https://vuejs.org/guide/essentials/watchers.html#basic-example

    Real world example: https://www.netlify.com/blog/2021/01/29/deep-dive-into-the-vue-composition-apis-watch-method/

    import { ref, computed, watch } from 'vue'
    
    const connectedWallet = computed(() => {
      const { publicKey, sendTransaction } = useWallet()
    
      if (publicKey && publicKey.value) {
        return publicKey.value.toBase58()
      }
    })
    

    This watches for the change when you use the solana-wallet connect

    watch(connectedWallet, async (currentValue) => {
      console.log('currentValue', currentValue)
    })