Integrate Abstraxn Smart Wallets into your Next.js application
Now that you’ve set up your provider configuration, it’s time to integrate Abstraxn Smart Wallets into your Next.js application.

Using the Connect Button

The ConnectButton component is a ready-to-use button that triggers the onboarding modal:
"use client";

import { ConnectButton } from "@abstraxn/signer-react";

export default function Home() {
  return (
    <div>
      <h1>Welcome to My App</h1>
      <ConnectButton
        connectText="Connect Wallet"
        connectedText="Connected"
        showAddress={true}
        size="lg"
      />
    </div>
  );
}

Using Hooks

You can use the provided hooks to access wallet state and functionality:
"use client";

import { useIsConnected, useAddress, useAbstraxnWallet } from "@abstraxn/signer-react";

export function WalletInfo() {
  const isConnected = useIsConnected();
  const address = useAddress();
  const { disconnect, loading } = useAbstraxnWallet();

  if (!isConnected) {
    return <p>Not connected</p>;
  }

  return (
    <div>
      <p>Connected: {address}</p>
      <button onClick={disconnect} disabled={loading}>
        Disconnect
      </button>
    </div>
  );
}

Sending Transactions

For embedded-wallet EVM transactions, use: usePrepareRawTxn -> useSignAndSendTxn -> useWaitForTxnReceipt
"use client";

import { useState } from "react";
import {
  usePrepareRawTxn,
  useSignAndSendTxn,
  useWaitForTxnReceipt,
  usePublicClient,
  useEstimateGas,
  useGetGasPrice,
  useIsConnected,
  useAddress,
} from "@abstraxn/signer-react";
import { polygonAmoy } from "viem/chains";
import { parseEther } from "viem";

export function SendTransaction() {
  const address = useAddress();
  const isConnected = useIsConnected();
  const { publicClient } = usePublicClient(
    polygonAmoy,
    "https://rpc-amoy.polygon.technology"
  );
  const { prepareRawTxn } = usePrepareRawTxn(publicClient);
  const { signAndSendTxn } = useSignAndSendTxn(publicClient);
  const { waitForTxnReceipt } = useWaitForTxnReceipt(publicClient);
  const { estimateGas } = useEstimateGas(publicClient);
  const { getGasPrice } = useGetGasPrice(publicClient);
  const [loading, setLoading] = useState(false);
  const [txHash, setTxHash] = useState<`0x${string}` | null>(null);

  const handleSend = async () => {
    if (!isConnected || !address) {
      alert("Please connect your wallet first");
      return;
    }

    setLoading(true);
    try {
      const rawTx = await prepareRawTxn({
        from: address as `0x${string}`,
        to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
        value: parseEther("0.001"),
      });

      const { gasLimit } = await estimateGas({
        account: address as `0x${string}`,
        to: rawTx.to,
        data: rawTx.data,
        value: rawTx.value,
      });
      const fees = await getGasPrice();

      const result = await signAndSendTxn({
        from: address as `0x${string}`,
        ...rawTx,
        gas: {
          gasLimit,
          maxFeePerGas: fees.maxFeePerGas,
          maxPriorityFeePerGas: fees.maxPriorityFeePerGas,
          gasPrice: fees.gasPrice,
        },
      });

      setTxHash(result.hash as `0x${string}`);
      await waitForTxnReceipt({
        hash: result.hash as `0x${string}`,
        confirmations: 1,
      });
    } catch (error) {
      console.error("Transaction failed:", error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <button onClick={handleSend} disabled={!isConnected || loading}>
        {loading ? "Sending..." : "Send Transaction"}
      </button>
      {txHash && <p>Last tx hash: {txHash}</p>}
    </div>
  );
}

Alternative: Using Hook to Trigger Onboarding

You can also trigger the onboarding modal programmatically using the showOnboarding method:
"use client";

import { useAbstraxnWallet } from "@abstraxn/signer-react";

export function CustomConnectButton() {
  const { showOnboarding, loading } = useAbstraxnWallet();

  return (
    <button onClick={showOnboarding} disabled={loading}>
      {loading ? "Connecting..." : "Connect Wallet"}
    </button>
  );
}

Complete Example

Here’s a complete example combining all the pieces:
"use client";

import { useState } from "react";
import { 
  ConnectButton, 
  useIsConnected,
  useAddress,
  useAbstraxnWallet,
  usePublicClient,
  usePrepareRawTxn,
  useSignAndSendTxn,
  useWaitForTxnReceipt
} from "@abstraxn/signer-react";
import { polygonAmoy } from "viem/chains";
import { parseEther } from "viem";

export default function Home() {
  const isConnected = useIsConnected();
  const address = useAddress();
  const { disconnect } = useAbstraxnWallet();
  const { publicClient } = usePublicClient(
    polygonAmoy,
    "https://rpc-amoy.polygon.technology"
  );
  const { prepareRawTxn } = usePrepareRawTxn(publicClient);
  const { signAndSendTxn } = useSignAndSendTxn(publicClient);
  const { waitForTxnReceipt } = useWaitForTxnReceipt(publicClient);
  const [loading, setLoading] = useState(false);
  const [txHash, setTxHash] = useState<string | null>(null);

  const handleSend = async () => {
    if (!isConnected || !address) {
      alert("Please connect your wallet first");
      return;
    }

    setLoading(true);
    try {
      const rawTx = await prepareRawTxn({
        from: address as `0x${string}`,
        to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
        value: parseEther("0.001"),
      });

      const result = await signAndSendTxn({
        from: address as `0x${string}`,
        ...rawTx,
      });
      await waitForTxnReceipt({
        hash: result.hash as `0x${string}`,
        confirmations: 1,
      });

      setTxHash(result.hash);
      alert(`Transaction sent! Hash: ${result.hash}`);
    } catch (error) {
      console.error(error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <h1>My Abstraxn App</h1>
      <ConnectButton />
      
      {isConnected && (
        <div>
          <p>Address: {address}</p>
          <button onClick={handleSend} disabled={loading}>
            {loading ? "Sending..." : "Send 0.001 ETH"}
          </button>
          <button onClick={disconnect}>Disconnect</button>
          {txHash && <p>Tx Hash: {txHash}</p>}
        </div>
      )}
    </div>
  );
}

Next Steps