Skip to content

Commit e3b42d3

Browse files
committed
Create solana-pay.mdx
1 parent 73882bf commit e3b42d3

File tree

1 file changed

+367
-0
lines changed

1 file changed

+367
-0
lines changed

src/pages/guides/solana-pay.mdx

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
---
2+
title: Integrate Solana Pay with Web3Auth
3+
image: "guides/guides-banners/solana.png"
4+
description:
5+
Learn how to integrate Solana Pay QR code payments with Web3Auth embedded wallets in your React
6+
application.
7+
type: guide
8+
tags: [plug and play, web, solana, solana pay, react, ed25519]
9+
date: January 15, 2025
10+
author: Web3Auth Team
11+
---
12+
13+
import SEO from "@site/src/components/SEO";
14+
import TabItem from "@theme/TabItem";
15+
import Tabs from "@theme/Tabs";
16+
17+
<SEO
18+
title="Integrate Solana Pay with Web3Auth"
19+
description="Learn how to integrate Solana Pay QR code payments with Web3Auth embedded wallets in your React application."
20+
image="https://web3auth.io/docs/guides/guides-banners/multi.png"
21+
slug="/guides/solana-pay"
22+
/>
23+
24+
In this guide, we'll explore how to integrate Web3Auth's embedded wallets with Solana Pay to create
25+
a seamless payment experience for your users. By combining Web3Auth's familiar Web2-like social
26+
logins with Solana Pay's QR code functionality, you can enable users to make payments directly from
27+
their Web3Auth-powered embedded wallet.
28+
29+
As an overview, this integration allows users to:
30+
31+
- Log in using familiar Web2 social providers (Google, Apple, etc.)
32+
- Generate Solana Pay QR codes for transactions
33+
- Make payments using their Web3Auth embedded wallet
34+
35+
For those who want to skip straight to the code, you can find the complete implementation examples
36+
in our
37+
[GitHub repository](https://github.com/Web3Auth/web3auth-examples/tree/main/other/solana-pay-example).
38+
39+
## How to set up Web3Auth Dashboard
40+
41+
If you haven't already, sign up on the Web3Auth platform. It is free and gives you access to the
42+
Web3Auth's base plan. After the basic setup, explore other features and functionalities offered by
43+
the Web3Auth Dashboard. It includes custom verifiers, whitelabeling, analytics, and more. Head to
44+
[Web3Auth's documentation](/docs/dashboard) page for detailed instructions on setting up the
45+
Web3Auth Dashboard.
46+
47+
## Prerequisites and Setup
48+
49+
Before diving into the code, ensure you have the necessary libraries installed and your Web3Auth
50+
project configured.
51+
52+
### Installation
53+
54+
You'll need the following libraries in your project:
55+
56+
- **`@solana/pay`**: The core Solana Pay protocol library.
57+
- **`bignumber.js`**: For accurate handling of large numbers, especially when dealing with token
58+
amounts.
59+
- **`@solana/web3.js`**: For interacting with the Solana blockchain, such as fetching balances or
60+
constructing transactions.
61+
62+
```bash npm2yarn
63+
npm install @solana/pay bignumber.js @solana/web3.js
64+
```
65+
66+
### Dashboard Configuration
67+
68+
Web3Auth's embedded wallets enable users to log in using familiar Web2 social logins by using Shamir
69+
Secret Sharing (MPC) to ensure the wallet key is distributed and non-custodial.
70+
71+
1. **Create a Project**: Go to the [Web3Auth dashboard](https://dashboard.web3auth.io/) and create a
72+
new project.
73+
2. **Copy Client ID**: Once created, copy your Client ID from the dashboard. This ID is crucial for
74+
initializing the Web3Auth SDK.
75+
3. **Enable Solana Chain**: In the dashboard, navigate to "Chains and Network" and enable Solana,
76+
Solana Devnet and Solana Testnet. Ensure all the RPC URLs are configured.
77+
78+
## Integrating Web3Auth in React
79+
80+
Once you have set up the Web3Auth Dashboard and created a new project, it's time to integrate
81+
Web3Auth in your React application. For the implementation, we'll use the
82+
[`@web3auth/modal`](https://www.npmjs.com/package/@web3auth/modal) SDK. This SDK facilitates
83+
integration with Web3Auth, allowing you to easily manage embedded wallets in your React application.
84+
85+
### Initialize Web3Auth Provider
86+
87+
Wrap your application components with a `Web3AuthProvider` to configure Web3Auth with your
88+
`Client ID`.
89+
90+
```typescript title="src/main.tsx"
91+
import "./index.css";
92+
93+
import ReactDOM from "react-dom/client";
94+
// focus-start
95+
import { Web3AuthProvider } from "@web3auth/modal/react";
96+
import web3AuthContextConfig from "./web3authContext";
97+
// focus-end
98+
import App from "./App";
99+
100+
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
101+
// focus-start
102+
<Web3AuthProvider config={web3AuthContextConfig}>
103+
<App />
104+
</Web3AuthProvider>
105+
// focus-end
106+
);
107+
```
108+
109+
```typescript title="src/web3authContext.tsx"
110+
import { WEB3AUTH_NETWORK } from "@web3auth/modal";
111+
import { type Web3AuthContextConfig } from "@web3auth/modal/react";
112+
113+
// Dashboard Registration
114+
const clientId =
115+
"BFcLTVqWlTSpBBaELDPSz4_LFgG8Nf8hEltPlf3QeUG_88GDrQSw82fSjjYj5x4F3ys3ghMq8-InU7Azx7NbFSs"; // get from https://dashboard.web3auth.io
116+
117+
// focus-start
118+
// Instantiate SDK
119+
const web3AuthContextConfig: Web3AuthContextConfig = {
120+
web3AuthOptions: {
121+
clientId,
122+
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_DEVNET,
123+
},
124+
};
125+
// focus-end
126+
127+
export default web3AuthContextConfig;
128+
```
129+
130+
### Accessing Wallet Information & Fetching User Balance
131+
132+
Once Web3Auth is initialized, you can access wallet information and user details through the
133+
[Web3Auth Solana hooks](/docs/sdk/web/react/solana-hooks/).
134+
135+
```typescript title="src/components/getBalance.tsx"
136+
// focus-next-line
137+
import { useSolanaWallet } from "@web3auth/modal/react/solana";
138+
import {
139+
LAMPORTS_PER_SOL,
140+
PublicKey,
141+
} from "@solana/web3.js";
142+
import { useEffect, useState } from "react";
143+
144+
export function Balance() {
145+
// focus-next-line
146+
const { accounts, connection } = useSolanaWallet();
147+
const [balance, setBalance] = useState<number | null>(null);
148+
const [isLoading, setIsLoading] = useState(false);
149+
const [error, setError] = useState<string | null>(null);
150+
151+
const fetchBalance = async () => {
152+
if (connection && accounts && accounts.length > 0) {
153+
try {
154+
setIsLoading(true);
155+
setError(null);
156+
// focus-start
157+
const publicKey = new PublicKey(accounts[0]);
158+
const balance = await connection.getBalance(publicKey);
159+
// focus-end
160+
setBalance(balance);
161+
} catch (err) {
162+
setError(err instanceof Error ? err.message : "Unknown error");
163+
} finally {
164+
setIsLoading(false);
165+
}
166+
}
167+
};
168+
169+
useEffect(() => {
170+
fetchBalance();
171+
}, [connection, accounts]);
172+
173+
return (
174+
<div>
175+
<h2>Balance</h2>
176+
<div>
177+
{balance !== null && `${balance / LAMPORTS_PER_SOL} SOL`}
178+
</div>
179+
{isLoading && <span className="loading">Loading...</span>}
180+
{error && <span className="error">Error: {error}</span>}
181+
<button onClick={fetchBalance} type="submit" className="card">
182+
Fetch Balance
183+
</button>
184+
</div>
185+
)
186+
}
187+
```
188+
189+
## Integrating Solana Pay
190+
191+
Solana Pay enables the generation of transaction requests, typically as QR codes, for direct
192+
payments from Solana wallets. This section will show you how to create and display Solana Pay QR
193+
codes for payments.
194+
195+
### Required Imports
196+
197+
Ensure you import the necessary components from the installed libraries:
198+
199+
```typescript
200+
// focus-start
201+
import { createQR } from "@solana/pay";
202+
import { Keypair, PublicKey } from "@solana/web3.js";
203+
import BigNumber from "bignumber.js";
204+
import { useSolanaWallet } from "@web3auth/modal/react/solana";
205+
// focus-end
206+
```
207+
208+
### Generating the Payment Request QR Code
209+
210+
The core of Solana Pay integration involves creating a payment request URL and then rendering it as
211+
a QR code. Here's what you need to define:
212+
213+
- **Recipient and Amount**: Define the `recipient` (a `PublicKey` of the merchant/receiver) and the
214+
`amount` (a `BigNumber` representing the payment value, e.g., 0.001 SOL).
215+
- **Reference**: Generate a unique `reference` for the payment. This acts as a unique identifier for
216+
the transaction.
217+
- **Optional Fields**: Include `label`, `message`, and `memo` for enhanced user experience.
218+
219+
Here's how to implement a Solana Pay QR code generator component:
220+
221+
```typescript title="src/components/solanaPay.tsx"
222+
import { Keypair, PublicKey } from "@solana/web3.js";
223+
import { createQR, encodeURL } from "@solana/pay";
224+
import BigNumber from "bignumber.js";
225+
import { useEffect, useRef, useState } from "react";
226+
import { createPortal } from "react-dom";
227+
import { useSolanaWallet } from "@web3auth/modal/react/solana";
228+
229+
export function SolanaPay() {
230+
const { accounts } = useSolanaWallet();
231+
const [isLoading, setIsLoading] = useState(false);
232+
const [error, setError] = useState<string | null>(null);
233+
const [amountToSend, setAmountToSend] = useState(0);
234+
const [showModal, setShowModal] = useState(false);
235+
const [qrUrl, setQrUrl] = useState<string>("");
236+
const qrRef = useRef<HTMLDivElement>(null);
237+
238+
const generateQrCode = () => {
239+
try {
240+
if (!accounts?.[0]) {
241+
setError("No wallet connected");
242+
return;
243+
}
244+
245+
setIsLoading(true);
246+
setError(null);
247+
// focus-start
248+
// set the parameter of the transfer
249+
const recipient = new PublicKey(accounts?.[0]!);
250+
const amount = new BigNumber(amountToSend);
251+
// reference should be a unique ID for the payment
252+
const reference = new Keypair().publicKey;
253+
// Label and message are optional. They will be shown in wallets when users scan it but won't show on chain
254+
const label = "MetaMask Embedded Wallet x Solana Pay Demo";
255+
const message = "Thanks for Trying Solana Pay!";
256+
// memo is optional and will be included in the onchain transaction
257+
const memo = "Thanks for Trying Solana Pay!";
258+
// create the URL
259+
const url = encodeURL({
260+
recipient,
261+
amount,
262+
reference,
263+
label,
264+
message,
265+
memo,
266+
});
267+
268+
setQrUrl(url.toString());
269+
// focus-end
270+
setShowModal(true);
271+
} catch (err) {
272+
setError(err instanceof Error ? err.message : "Failed to generate QR code");
273+
} finally {
274+
setIsLoading(false);
275+
}
276+
};
277+
// Generate QR code when modal opens and URL is available
278+
useEffect(() => {
279+
if (showModal && qrUrl && qrRef.current) {
280+
qrRef.current.innerHTML = "";
281+
try {
282+
const qr = createQR(qrUrl, 300, "white");
283+
qr.append(qrRef.current);
284+
} catch (err) {
285+
setError("Failed to create QR code");
286+
}
287+
}
288+
}, [showModal, qrUrl]);
289+
290+
const closeModal = () => {
291+
setShowModal(false);
292+
setQrUrl("");
293+
setError(null);
294+
};
295+
296+
return (
297+
<>
298+
<div>
299+
<h2>Solana Pay QR</h2>
300+
<div className="flex flex-col items-center gap-4">
301+
<input
302+
type="number"
303+
placeholder="Enter SOL amount"
304+
onChange={(e) => setAmountToSend(Number(e.target.value))}
305+
className="px-4 py-2 border rounded-lg text-black"
306+
step="0.01"
307+
min="0"
308+
/>
309+
<button
310+
onClick={generateQrCode}
311+
className="px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600"
312+
disabled={isLoading || amountToSend <= 0}
313+
>
314+
{isLoading ? "Generating..." : "Generate Payment QR"}
315+
</button>
316+
317+
{/* Error Display */}
318+
{error && !showModal && (
319+
<div className="text-red-500 text-sm mt-2">
320+
Error: {error}
321+
</div>
322+
)}
323+
</div>
324+
</div>
325+
...
326+
```
327+
328+
## Testing and Best Practices
329+
330+
### Development Environment
331+
332+
- **DevNet for Testing**: Always develop and test on DevNet or TestNet. You can use the
333+
[Solana Faucet](https://faucet.solana.com/) to get test SOL for your new account.
334+
- **Environment Variables**: Store your Web3Auth Client ID and other sensitive configuration in
335+
environment variables.
336+
337+
### User Experience
338+
339+
- **User Interface**: For better user experience, display the QR code within a modal or a dedicated
340+
confirmation page, providing clear messages to the user.
341+
- **Loading States**: Implement proper loading states while generating QR codes and processing
342+
transactions.
343+
- **Error Handling**: Provide clear error messages when transactions fail or when the user's wallet
344+
doesn't have sufficient balance.
345+
346+
### Production Considerations
347+
348+
- **Tracking Payments**: For production, implement a server-side solution to track the unique
349+
payment `reference` and poll for transaction confirmation using websockets. This allows you to
350+
update your application's state and perform reconciliation in your database.
351+
- **Production RPCs**: For scalable production usage, use dedicated Solana RPC services from
352+
providers like QuickNode, as public RPCs may have rate limits.
353+
- **Security**: Validate all payment parameters server-side before processing transactions.
354+
355+
## Conclusion
356+
357+
This guide demonstrates how to integrate Web3Auth's embedded wallets with Solana Pay to create a
358+
seamless payment experience. By combining Web3Auth's familiar Web2-like social logins with Solana
359+
Pay's QR code functionality, you can enable users to make payments directly from their
360+
Web3Auth-powered embedded wallet.
361+
362+
The integration provides a smooth, familiar experience for your users while leveraging the power of
363+
the Solana blockchain for fast and low-cost transactions.
364+
365+
If you are interested in learning more about Web3Auth, please check out our
366+
[documentation for Web SDK](http://localhost:3000/docs/sdk/web/react) or explore our
367+
[Solana Pay integration example](https://github.com/Web3Auth/web3auth-examples/blob/main/other/solana-pay-example).

0 commit comments

Comments
 (0)