9

I was hoping if anyone could point me in the right direction... I am trying to add the "wallet connect" extension (e.g. sollet / phantom) functionality to my website but I have no idea where to start. Metamask has a good explanation / examples of how to do it but I am not sure Solana is the same?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
jeeberjoe
  • 91
  • 1
  • 1
  • 2

3 Answers3

10

You can use https://github.com/project-serum/sol-wallet-adapter for Sollet Web or Sollet Extension

For phantom wallet, documentations are here https://docs.phantom.app/integrating/establishing-a-connection

Please note that one major difference between EVM wallets such as metamask is that most EVM wallets will also handle sending the transaction onchain where as Solana wallets only handle signing the transaction and the sending is done by the application.

Below is an example of how to integrate with Sollet and Phantom

import { Connection, SystemProgram, Transaction, clusterApiUrl } from '@solana/web3.js';
import Wallet from '@project-serum/sol-wallet-adapter';

let provider = 'https://www.sollet.io';

// For sollet extension use
// provider = window.sollet

let wallet = new Wallet(provider);
wallet.on('connect', publicKey => console.log('Connected to ' + publicKey.toBase58()));
wallet.on('disconnect', () => console.log('Disconnected'));
await wallet.connect();

// Sending a transaction
let connection = new Connection(clusterApiUrl('devnet'));

let transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: wallet.publicKey,
    toPubkey: wallet.publicKey,
    lamports: 100,
  })
);
let { blockhash } = await connection.getRecentBlockhash();
transaction.recentBlockhash = blockhash;
transaction.feePayer = wallet.publicKey;
let signed = await wallet.signTransaction(transaction);
let txid = await connection.sendRawTransaction(signed.serialize());
await connection.confirmTransaction(txid);

// Phantom Wallet
window.solana.connect();
window.solana.on("connect", () => console.log("connected!"))

console.log(window.solana.publicKey);

The Solana team have also written an extensive library to integrate with a bunch of existing wallets on Solana - https://github.com/solana-labs/wallet-adapter

Ryan M
  • 18,333
  • 31
  • 67
  • 74
yangli-io
  • 16,760
  • 8
  • 37
  • 47
2

Using Phantom

<html>
  <head>
    <script src="https://unpkg.com/@solana/web3.js@latest/lib/index.iife.js"></script>
  </head>
  <body>
    <script>

    const getProvider = async () => {
        if ("solana" in window) {
          
          await window.solana.connect(); // opens wallet to connect to

          const provider = window.solana;
          if (provider.isPhantom) {
            console.log("Is Phantom installed?  ", provider.isPhantom);
            return provider;
          }
        } else {
          document.write('Install https://www.phantom.app/');
        }
      };

      window.onload = () => {

        getProvider().then(provider => {
          console.log('key', provider.publicKey.toString())
        })
        .catch(function(error){
          console.log(error)
        });

      }
    </script>
  </body>
</html>
Vikram
  • 187
  • 9
0

Phantom Wallet implementation for login (note: this is on testnet)

<div class="container-fluid text-center mt-5">
    <div class="d-flex justify-content-center mt-5">
        <button id="login-button" onclick="phantomLogin()" class="btn btn-dark">Login with Phantom Wallet</button>
    </div>
        
    <div class="d-flex justify-content-center mt-5">
        <div class="public-key" style="display: none"></div>
    </div>
        
    <div class="d-flex justify-content-center mt-5">
        <div class="sol-balance" style="display: none">
        
        </div>
    </div>
</div>

jQuery:

     async function phantomLogin() {
        const isPhantomInstalled = window.solana && window.solana.isPhantom;
        if (!isPhantomInstalled) {
            alert("Phantom browser extension is not detected!");
        } else {
            try {
                const resp = await window.solana.connect();
                connectAccountAnimation(resp.publicKey.toString());
            } catch (err) {
                console.log("User rejected request");
                console.log(err);
            }
        }
    }

    async function connectAccountAnimation(publicKey) {
        $('#login-button').hide();
        let publicKeyDiv = $('.public-key').html('<b>Account:</b> '+publicKey).show();
        showBalance();
    }

    async function showBalance(){
        let provider = window.solana;
        let connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl('testnet'), 'confirmed');
        connection.getBalance(provider.publicKey).then(function (value) {
            let solBalanceDiv = $('.sol-balance').html('<b>Balance:</b> ' + (value/1000000000) + ' SOL').show();
        });
    }

    try {
        window.onload = () => {
            const isPhantomInstalled = window.solana && window.solana.isPhantom;
            if (isPhantomInstalled) {
                window.solana.connect({onlyIfTrusted: true})
                    .then(({publicKey}) => {
                        connectAccountAnimation(publicKey.toString());
                    })
                    .catch(() => {
                        console.log("Not connected");
                    })
            }

        }
    } catch (err) {
        console.log(err);
    }

Also don't forget to include the script inside your head tag

<script src="https://unpkg.com/@solana/web3.js@latest/lib/index.iife.min.js"></script>
Brane
  • 3,257
  • 2
  • 42
  • 53