Frontend Integration with @solana/web3.js

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Frontend Integration with @solana/web3.js
Simple
~2-3 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Solana Frontend Integration with @solana/web3.js

Solana frontend is not EVM. There's no ethers.js, no useContractRead. The account model, wallets via Wallet Adapter, deserialization via Borsh — everything is different. The main trap for developers with EVM background is trying to apply the same patterns. It doesn't work.

Wallet Connection: Wallet Adapter

@solana/wallet-adapter is the standard way to connect Phantom, Solflare, Backpack, and other wallets:

// providers.tsx
import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react'
import { WalletModalProvider } from '@solana/wallet-adapter-react-ui'
import { PhantomWalletAdapter, SolflareWalletAdapter } from '@solana/wallet-adapter-wallets'
import { clusterApiUrl } from '@solana/web3.js'

const wallets = [new PhantomWalletAdapter(), new SolflareWalletAdapter()]
const endpoint = clusterApiUrl('mainnet-beta') // or your RPC

export function SolanaProviders({ children }: { children: React.ReactNode }) {
  return (
    <ConnectionProvider endpoint={endpoint}>
      <WalletProvider wallets={wallets} autoConnect>
        <WalletModalProvider>
          {children}
        </WalletModalProvider>
      </WalletProvider>
    </ConnectionProvider>
  )
}

Importing styles is mandatory: import '@solana/wallet-adapter-react-ui/styles.css'. Without it, the connection modal won't display correctly.

Reading Data from the Blockchain

Connection from @solana/web3.js is similar to PublicClient in viem. Key methods:

import { Connection, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js'

const connection = new Connection(
  process.env.NEXT_PUBLIC_RPC_URL!,
  'confirmed' // commitment level: processed | confirmed | finalized
)

// SOL balance
const balance = await connection.getBalance(new PublicKey(address))
const solBalance = balance / LAMPORTS_PER_SOL

// Account information (program account data)
const accountInfo = await connection.getAccountInfo(new PublicKey(address))

Commitment levels — an important detail often overlooked. processed — fastest, but the transaction might revert. confirmed — confirmed by ~66% stake. finalized — irreversible. For UI typically confirmed, for financial operations — finalized.

Working with SPL Tokens

Most dApps work with SPL tokens, not native SOL. You need @solana/spl-token:

import { getAssociatedTokenAddress, getAccount } from '@solana/spl-token'
import { PublicKey } from '@solana/web3.js'

// Address of the user's token account
const tokenAccount = await getAssociatedTokenAddress(
  new PublicKey(mintAddress),  // token mint address
  new PublicKey(walletAddress) // owner wallet
)

// Balance
try {
  const account = await getAccount(connection, tokenAccount)
  const balance = Number(account.amount) / 10 ** decimals
} catch (e) {
  // TokenAccountNotFoundError — account not created, balance is 0
}

Nuance: token account might not exist if the user has never held this token. This isn't an error — it's just a balance of 0. You need to handle TokenAccountNotFoundError.

Sending Transactions

import { useWallet } from '@solana/wallet-adapter-react'
import { Transaction, SystemProgram, LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js'

const { publicKey, sendTransaction } = useWallet()

const handleSend = async () => {
  if (!publicKey) return
  
  const { blockhash, lastValidBlockHeight } = 
    await connection.getLatestBlockhash()
  
  const transaction = new Transaction().add(
    SystemProgram.transfer({
      fromPubkey: publicKey,
      toPubkey: new PublicKey(recipient),
      lamports: amount * LAMPORTS_PER_SOL,
    })
  )
  transaction.recentBlockhash = blockhash
  transaction.feePayer = publicKey

  const signature = await sendTransaction(transaction, connection)
  
  // Wait for confirmation
  await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight })
}

sendTransaction from the wallet adapter automatically requests the user's wallet signature.

RPC and Rate Limits

The public clusterApiUrl('mainnet-beta') is only for development — it's heavily rate-limited. For production: Helius, QuickNode, Alchemy (Solana), or your own node. Helius is especially convenient — it provides enhanced API with transaction parsing and webhooks for on-chain events.

Integration takes 2–3 days: setting up wallet adapter, connecting to RPC, basic read/write operations, and handling typical errors (insufficient funds, blockhash expired, simulation failed).