Solana Component
Here we learn how to sign in to any application using Solana
Let's add the imports that we will need for our Solana component to function
Edit Solana.tsx
import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { WalletDisconnectButton, WalletModalProvider, WalletMultiButton } from "@solana/wallet-adapter-react-ui";
import { Payload as SIWPayload, SIWWeb3 } from "@web3auth/sign-in-with-web3";
import bs58 from "bs58";
import React, { useState } from "react";
import Swal from "sweetalert2";
import styles from "../public/css/solana.module.css";
import SolanaLogo from "../public/solana-logo.png";
const Solana: React.FC = () => {
return <></>;
};
export default Solana;
Define the variables that we require
...
const Solana: React.FC = () => {
const { connection } = useConnection();
// if you use anchor, use the anchor hook instead
// const wallet = useAnchorWallet();
// const walletAddress = wallet?.publicKey.toString();
let walletAddress = "";
const wallet = useWallet();
if (wallet.connected && wallet.publicKey) {
walletAddress = wallet.publicKey.toString()
}
const { publicKey, signMessage } = useWallet();
const [siwsMessage, setSiwsMessage] = useState<SIWWeb3|null>();
const [nonce, setNonce] = useState("");
const [sign, setSignature] = useState("");
// Domain and origin
const domain = window.location.host;
const origin = window.location.origin;
let statement = "Sign in with Solana to the app.";
}
If you look at our App.tsx
. It has the following code
{
chain == "solana" && (
<ConnectionProvider endpoint={endpoint}>
<WalletProvider wallets={wallets}>
<WalletModalProvider>
<Solana />
</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>
);
}
We are using the wallet providers from @solana/wallet-adapter-react
So we don't need to write additional code to connect the wallet to the
application.
Now we need to write the function that creates the SIWWeb3 Message and perform the signing
const Solana: React.FC = () => {
...
...
// Generate a message for signing
// The nonce is generated on the server side
function createSolanaMessage() {
const payload = new SIWPayload();
payload.domain = domain;
payload.uri = origin;
payload.address = publicKey!.toString();
payload.statement = statement;
payload.version = "1";
payload.chainId = 1;
const header = { t : "sip99" };
const network = "solana";
let message = new SIWWeb3({ header, payload, network });
// we need the nonce for verification so getting it in a global variable
setNonce(message.payload.nonce);
setSiwsMessage(message);
const messageText = message.prepareMessage();
const messageEncoded = new TextEncoder().encode(messageText);
signMessage!(messageEncoded).then(resp => setSignature(
bs58.encode(resp)));
}
}
Now we have all the functions that we need. Let's add the jsx code and render the application frontend.
const Solana: React.FC = () => {
...
...
return (
<>
{wallet.connected &&
sign == "" &&
<span>
<p className={styles.center}>Sign Transaction</p>
<input className={styles.publicKey} type="text" id="publicKey" value={walletAddress} />
</span>
}
{
wallet.connected != true &&
sign=="" &&
<div>
<div className={styles.logowrapper}>
<img className={styles.solanalogo} src={SolanaLogo} />
</div>
<p className={styles.sign}>Sign in With Solana</p>
</div>
}
{wallet.connected &&
sign == "" &&
<div>
<button className={styles.web3auth} id='w3aBtn' onClick={createSolanaMessage}>Sign-in with Solana</button>
<WalletDisconnectButton className={styles.walletButton} />
</div>
}
{wallet.connected != true &&
sign == "" &&
<WalletModalProvider >
<WalletMultiButton className={styles.walletButton} />
</WalletModalProvider>
}
{
sign &&
<>
<p className={styles.center}>Verify Signature</p>
<input className={styles.signature} type="text" id="signature" value={sign} onChange={ e=> setSignature(e.target.value)} />
<button className={styles.web3auth} id='verify' onClick={e => {
const signature = {
t: "sip99",
s: sign
}
const payload = siwsMessage!.payload;
siwsMessage!.verify(payload, signature).then(resp => {
if (resp.success == true) {
Swal.fire("Success","Signature Verified","success")
} else {
Swal.fire("Error",resp.error!.type,"error")
}
});
}}>Verify</button>
<button className={styles.web3auth} id='verify' onClick={e => {
setSiwsMessage(null);
setNonce("");
setSignature("")
}}>Back to Wallet</button>
</>
}
</>
);
}
Full code available here
Let's run the application now :-
npm start
Let's add that the Starkware component