Integrate Abstraxn Smart Wallets into your Next.js applicationNow 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
TheConnectButton 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 theshowOnboarding 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
- Learn about customizing the UI
- Learn how to enable MFA
- Explore Solana support
- Explore authentication methods
- Check out more in the Wallets Guide