Civic Docs
Civic Auth
Civic Auth
  • 🔏Civic Auth
  • Integration
    • React
    • Next.JS
    • Node.JS
      • Express
      • Hono
      • Fastify
    • Other OIDC / OAuth 2.0-Compliant Environments
    • FAQs
    • Error Codes
    • Bring Your App to Production
  • Web3
    • Embedded Wallets
    • Ethereum / EVM
    • Solana
Powered by GitBook
On this page
  • Creating a Wallet
  • The useUser hook and UserContext Object
  • Using the Wallet
  • Sending a transaction
  • Checking the balance
  • Using the Wallet with the Solana Wallet Adapter
  • A Full Example

Was this helpful?

  1. Web3

Solana

PreviousEthereum / EVM

Last updated 4 days ago

Was this helpful?

Early Access

The Civic Auth Solana API is subject to change as we continue to develop and refine our solution.

Creating a Wallet

When a new user logs in, they do not yet have a Web3 wallet by default. You can create a wallet for them by calling the createWallet function on the user object.

Currently, we don't support connecting users' existing self-custodial wallets. This is coming soon.

Right now, we only support embedded wallets, which are generated on behalf of the user by our non-custodial wallet partner. Neither Civic nor your app ever has access to the wallets' private keys.

Here’s a basic example:

Complete examples can be found on Github:

  • Vite: and

  • NextJS and

  • If you're using the Solana wallet adapter with NextJS <15.3 and webpack, see

import { userHasWallet } from "@civic/auth-web3";
import { useUser } from "@civic/auth-web3/react";

export const afterLogin = async () => {
  const userContext = await useUser();

  if (userContext.user && !userHasWallet(userContext)) {
    await userContext.createWallet();
  }
};

The useUser hook and UserContext Object

If the user has a wallet,

type ExistingWeb3UserContext = UserContext & {
  solana: {
    address: string // the base58 public key of the embedded wallet
    wallet: Wallet // a Solana Wallet object
  } 
}

If the user does not yet have a wallet:

type NewWeb3UserContext = UserContext & {
  createWallet: () => Promise<void>;
  walletCreationInProgress: boolean;
} 

An easy way to distinguish between the two is to use the userHasWallet type guard.

if (userHasWallet(userContext)) {
  user.solana.wallet; // user has a wallet
} else {
  user.createWallet();// user does not have a wallet
}

Using the Wallet

Sending a transaction

const connection = new Connection(/* your rpc endpoint */);  
const { publicKey, sendTransaction } = user.sol.wallet;

const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: publicKey,
    toPubkey: new PublicKey(recipient),
    lamports: 1000000,
  })
);
const signature = await sendTransaction(transaction, connection);

Checking the balance

const connection = new Connection(/* your rpc endpoint */);
const { publicKey } = user.solana.wallet;
const balance = await connection.getBalance(publicKey);

Using the Wallet with the Solana Wallet Adapter

Use with Webpack in NextJS

When using the Solana Wallet Adapter with Webpack (default in NextJS <15.3), add the following flag in your next.config.ts or next.config.mjs file, passed into the createCIvicAuthPlugin function:

createCivicAuthPlugin({
  clientId: '<your civic auth client ID>',
  // ensures Civic's Wallet Adapter integration works with Webpack:
  enableSolanaWalletAdapter: true, 
});

Set up the Solana Wallet Adapter as shown below:

export const Providers: FC = () => {
    const endpoint = "YOUR RPC ENDPOINT";
    return (
        <ConnectionProvider endpoint={endpoint}>
            <WalletProvider wallets={[]} autoConnect>
                <WalletModalProvider>
                    <CivicAuthProvider clientId="YOUR CLIENT ID">
                        <WalletMultiButton />
                        { /* Your app's components go here */ }
                    </CivicAuthProvider>
                </WalletModalProvider>
            </WalletProvider>
        </ConnectionProvider>
    );
};

A Full Example

See below for a full minimal example of a Solana Adapter app using Civic Auth for an embedded wallet.

import { ConnectionProvider, WalletProvider, useWallet, useConnection } from "@solana/wallet-adapter-react";
import { WalletModalProvider} from "@solana/wallet-adapter-react-ui";
import { CivicAuthProvider } from "@civic/auth-web3/react";

// Wrap the content with the necessary providers to give access to hooks: solana wallet adapter & civic auth provider
const App = () => {
    const endpoint = "YOUR RPC ENDPOINT";
    return (
        <ConnectionProvider endpoint={endpoint}>
            <WalletProvider wallets={[]} autoConnect>
                <WalletModalProvider>
                    <CivicAuthProvider clientId="YOUR CLIENT ID">
                      <WalletMultiButton />
                      <AppContent/>
                    </CivicAuthProvider>
                </WalletModalProvider>
            </WalletProvider>
        </ConnectionProvider>
    );
};

// A simple hook to get the wallet's balance in lamports
const useBalance = () => {
  const [balance, setBalance] = useState<number>();
  // The Solana Wallet Adapter hooks
  const { connection } = useConnection();
  const { publicKey } = useWallet();

  if (publicKey) {
    connection.getBalance(publicKey).then(setBalance);
  }

  return balance;
};

// Separate component for the app content that needs access to hooks
const AppContent = () => {
  // Get the Solana wallet balance
  const balance = useBalance();
  // Get the Solana address
  const { publicKey } = useWallet();

  return (
    <>
      {publicKey && (
        <div>
          <p>Wallet address: {publicKey.toString()}</p>
          <p>Balance: {balance ? `${balance / 1e9} SOL` : "Loading..."}</p>
        </div>
      )}
    </>
  );
};

export default App;

The useUser hook returns a user context object that provides access to the base library's in the 'user' field, and adds some Web3 specific fields. The returned object has different types depending on these cases:

The wallet object follows the interface used by .

The Civic Auth Web3 SDK uses the to expose the embedded wallet to React frontends. This allows you to use familiar hooks such as useWallet and useConnection to interact with the wallet.

Make sure to follow the steps described (React) and (Next.Js) to get started with the Solana Wallet Adapter.

The Civic Auth Web3 SDK follows the , meaning that the Solana Wallet Adapter will automatically discover the embedded wallet.

The above shows a minimal React example. Follow the integration to set up the CivicAuthProvider according to your framework.

with Solana wallet adapter
without Solana wallet adapter
with Solana wallet adapter
without Solana wallet adapter
this example
Solana's Wallet Adapter
Solana Wallet Adapter
here
here
wallet standard
steps
user object