Skip to main content

Integrate Web3Auth MPC CoreKit SDK with the Solana Blockchain in Javascript

To sign the transactions for Solana using MPC CoreKit JS SDK, you can utilize the @toruslabs/tss-frost-lib to instantiate Web3AuthMPCCoreKit with ed25519 KeyType. To support the ed25519 curve Web3Auth internally uses the FROST algorithm to provide the EdDSA sginature using threshold protocols.

This EdDSA signature can be used to submit the transactions on Solana blockchain.

Installation

To interact with the Solana blockchain, you can use @solana/web3.js package with Web3Auth CoreKit SDK along with @toruslabs/tss-frost-lib package.

$ npm install @solana/web3.js
$ npm install @toruslabs/tss-frost-lib

Initializing and instantiating the Web3Auth MPC CoreKit JS SDK

Considering you have already installed the @toruslabs/tss-frost-lib package, let's use the tssLib to create Web3AuthMPCCoreKit instance.

import { Web3AuthMPCCoreKit, WEB3AUTH_NETWORK } from "@web3auth/mpc-core-kit";
import { tssLib } from "@toruslabs/tss-frost-lib";

const coreKitInstance = new Web3AuthMPCCoreKit({
web3AuthClientId: "YOUR_CLIENT_ID",
web3AuthNetwork: WEB3AUTH_NETWORK.MAINNET,
manualSync: true, // This is the recommended approach
tssLib: tssLib,
storage: window.storage,
});

Get User Info

Gives you the user's information received from the ID Token.

const userInfo = coreKitInstance?.getUserInfo();

Get account

Once you have an Web3AuthMPCCoreKit instance, it can be used as along with solana/web3.js package.

To generate the Solana EOA address, you can use the getPubKeyEd25519 method to retrieve the ed25519 curve compatible pubKey. Since solana uses the base58 enocded address, you can simply encode pubKey with base58 to get the user's EOA address.

import { base58 } from "@scure/base";

const address = base58.encode(Uint8Array.from(coreKitInstance.getPubKeyEd25519()));

If you want to verify that the public key is on ed25519 curve, you can create a new PublicKey instance using the generated address. Once you have the PublicKey instance, you can use the isOnCurve static method to verify the curve.

import { PublicKey } from "@solana/web3.js";

const publicKey = new PublicKey(address);

// Returns whether the public is on ed25519 curve
const isValidAddress = PublicKey.isOnCurve(publicKey.toBytes());

Get account balance

To get the user's balance, we can use the Connection.getBalance method, which takes PublicKey as an argument.

import { Connection, LAMPORTS_PER_SOL, PublicKey, clusterApiUrl } from "@solana/web3.js";

try {
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

// Use the publicKey from above
let balanceResponse = await connection.getBalance(publicKey);
const balance = (balanceResponse / LAMPORTS_PER_SOL).toString();
} catch (error) {
// Handle error
}

Sign a message

Signing a message for Solana is pretty straight forward. You can simply use the sign method to generate the EdDSA signature.

const msg = Buffer.from("Welcome to Web3Auth");
const sig = await this.coreKitInstance.sign(msg);

Sign a transaction

To sign a Solana transaction, you can use Transaction class to get a buffer of the transaction data to sign, and add geerated signature to the transaction. The public key must correspond to either the fee payer or a signer account in the transaction instructions.

import {
Connection,
LAMPORTS_PER_SOL,
PublicKey,
clusterApiUrl,
SystemProgram,
Transaction,
} from "@solana/web3.js";

const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

const lamportsToSend = 1_000_000;
const getRecentBlockhash = await this.connection.getLatestBlockhash("confirmed");

const transferTransaction = new Transaction().add(
// Self transfer tokens
SystemProgram.transfer({
fromPubkey: this.publicKey,
toPubkey: this.publicKey,
lamports: lamportsToSend,
}),
);

transferTransaction.recentBlockhash = getRecentBlockhash.blockhash;
transferTransaction.feePayer = this.publicKey;

// Sign the serialize message
const sig = await this.coreKitInstance.sign(transferTransaction.serializeMessage());

// Append the signature to the transaction
transferTransaction.addSignature(this.publicKey, sig);

// Signature of the transaction in wire format which can be broadcasted on Solana chain.
const transferTransactionSignature = transferTransaction.serialize();

To broadcast the signed transaction, you can utilize the Connection.sendRawTransaction method.

// Returns the hash, for connection and transferTransactionSignature, check above
// code snippets
let hash = await connection.sendRawTransaction(transferTransactionSignature);