Skip to content

Commit 76a1c79

Browse files
Copilot0xrinegade
andcommitted
Replace Solana wallet with Swig wallet implementation
Co-authored-by: 0xrinegade <[email protected]>
1 parent de6b153 commit 76a1c79

18 files changed

+9560
-17126
lines changed

package-lock.json

Lines changed: 8661 additions & 16420 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@
4242
"@coral-xyz/anchor-cli": "^0.31.2",
4343
"@project-serum/anchor": "^0.26.0",
4444
"@solana/spl-token": "^0.4.13",
45-
"@solana/wallet-adapter-base": "0.9.27",
46-
"@solana/wallet-adapter-react": "0.15.39",
47-
"@solana/wallet-adapter-react-ui": "0.9.39",
48-
"@solana/wallet-adapter-wallets": "0.19.37",
4945
"@solana/web3.js": "1.98.2",
46+
"@getpara/web-sdk": "^1.11.0",
47+
"@swig-wallet/classic": "0.2.0-beta.4",
48+
"@swig-wallet/coder": "0.2.0-beta.2",
49+
"@noble/curves": "^1.3.0",
50+
"@noble/hashes": "^1.3.3",
5051
"ajv": "^8.17.1",
5152
"browserify-zlib": "^0.2.0",
5253
"buffer": "^6.0.3",

src/App.js

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,8 @@
11
import React, { useMemo, useState, useEffect } from 'react';
22
import Image from 'next/image';
3-
import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react';
4-
import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
5-
import {
6-
PhantomWalletAdapter,
7-
} from '@solana/wallet-adapter-wallets';
8-
import {
9-
WalletModalProvider,
10-
WalletDisconnectButton,
11-
WalletMultiButton
12-
} from '@solana/wallet-adapter-react-ui';
133
import { clusterApiUrl } from '@solana/web3.js';
144

155
// Import styles
16-
import '@solana/wallet-adapter-react-ui/styles.css';
176
import './styles/guided-workflow.css';
187
import './styles/wallet-connection-guide.css';
198

@@ -27,8 +16,9 @@ import { UserProfile } from './components/UserProfile';
2716
import TradingGuidedWorkflow from './components/guided-workflow/TradingGuidedWorkflow';
2817
import ErrorBoundary from './components/ErrorBoundary';
2918

30-
// Import wallet safety utilities
31-
import { SafeWalletProvider, useSafeWallet } from './contexts/WalletContextProvider';
19+
// Import Swig wallet utilities
20+
import { SwigWalletProvider, useSwigWallet } from './contexts/SwigWalletProvider';
21+
import { SwigWalletButton } from './components/SwigWalletButton';
3222
import { initializeWalletConflictPrevention } from './utils/walletConflictPrevention';
3323
import { createConnection, getNetworkConnection } from './utils/rpcConnection';
3424

@@ -89,10 +79,10 @@ const SVM_NETWORKS = {
8979
}
9080
};
9181

92-
// Inner component that can use the wallet hook
82+
// Inner component that can use the Swig wallet hook
9383
const AppContent = () => {
94-
// Use safe wallet context instead of direct wallet adapter
95-
const wallet = useSafeWallet();
84+
// Use Swig wallet context instead of Solana wallet adapter
85+
const wallet = useSwigWallet();
9686

9787
// State for selected network
9888
const [selectedNetwork, setSelectedNetwork] = useState('solana');
@@ -134,7 +124,7 @@ const AppContent = () => {
134124
setActiveTab(tab);
135125
};
136126

137-
// Status indicator for wallet connection
127+
// Status indicator for Swig wallet connection
138128
const renderWalletStatus = () => {
139129
if (wallet.error) {
140130
return (
@@ -258,7 +248,7 @@ const AppContent = () => {
258248
}>
259249
<div className="wallet-wrapper">
260250
{renderWalletStatus()}
261-
<WalletMultiButton />
251+
<SwigWalletButton />
262252
{wallet.error && (
263253
<button
264254
className="wallet-retry-button"
@@ -416,14 +406,6 @@ const AppContent = () => {
416406
};
417407

418408
const App = () => {
419-
// Set up wallet adapters - updated for latest wallet adapter versions
420-
const wallets = useMemo(
421-
() => [
422-
new PhantomWalletAdapter(),
423-
],
424-
[]
425-
);
426-
427409
// Define network for connection provider
428410
const network = SVM_NETWORKS['solana'];
429411

@@ -452,15 +434,9 @@ const App = () => {
452434
</div>
453435
</div>
454436
}>
455-
<ConnectionProvider endpoint={network.endpoint} config={network.connectionConfig} connection={connection}>
456-
<WalletProvider wallets={wallets} autoConnect>
457-
<SafeWalletProvider>
458-
<WalletModalProvider>
459-
<AppContent />
460-
</WalletModalProvider>
461-
</SafeWalletProvider>
462-
</WalletProvider>
463-
</ConnectionProvider>
437+
<SwigWalletProvider>
438+
<AppContent />
439+
</SwigWalletProvider>
464440
</ErrorBoundary>
465441
);
466442
};

src/client/para.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Para SDK Client Configuration
3+
*
4+
* This module initializes the Para SDK client for OAuth authentication
5+
* and wallet management functionality.
6+
*/
7+
8+
import { Environment, ParaWeb } from '@getpara/web-sdk';
9+
10+
// Para API key - in production, this should be set via environment variables
11+
const API_KEY = process.env.NEXT_PUBLIC_PARA_API_KEY || process.env.PARA_API_KEY;
12+
13+
if (!API_KEY) {
14+
console.warn('Para API key not found. Please set NEXT_PUBLIC_PARA_API_KEY in your environment variables.');
15+
// For development, we'll create a mock client
16+
}
17+
18+
/**
19+
* Para Web SDK client instance
20+
* Uses Beta environment by default
21+
*/
22+
export const para = API_KEY
23+
? new ParaWeb(Environment.BETA, API_KEY)
24+
: {
25+
// Mock client for development when API key is not available
26+
isFullyLoggedIn: () => Promise.resolve(false),
27+
getWallets: () => Promise.resolve({}),
28+
logout: () => Promise.resolve(),
29+
getFarcasterConnectURL: () => Promise.resolve(''),
30+
waitForFarcasterStatus: () => Promise.resolve({ userExists: false, username: '' }),
31+
initiateUserLogin: () => Promise.resolve(''),
32+
getSetUpBiometricsURL: () => Promise.resolve(''),
33+
waitForLoginAndSetup: () => Promise.resolve({}),
34+
waitForPasskeyAndCreateWallet: () => Promise.resolve({}),
35+
getOAuthURL: () => Promise.resolve(''),
36+
waitForOAuth: () => Promise.resolve({ email: '', userExists: false }),
37+
createWallet: () => Promise.resolve({}),
38+
findWalletByAddress: () => Promise.resolve(null),
39+
signMessage: () => Promise.resolve({ signature: '' })
40+
};
41+
42+
export default para;

src/components/ConnectWalletPrompt.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState } from 'react';
2-
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
2+
import { SwigWalletButton } from './SwigWalletButton';
33
import { Tooltip } from './common';
44
import WalletConnectionGuide from './WalletConnectionGuide';
55

@@ -60,7 +60,7 @@ const ConnectWalletPrompt = ({
6060
</div>
6161
<p>{displayMessage}</p>
6262
<div className="wallet-connect-actions">
63-
<WalletMultiButton />
63+
<SwigWalletButton />
6464
<button
6565
className="guided-connection-button"
6666
onClick={handleShowGuide}

src/components/Layout.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React, { useContext, useState, useEffect } from 'react';
22
import Head from 'next/head';
33
import Image from 'next/image';
4-
import { WalletMultiButton, WalletDisconnectButton } from '@solana/wallet-adapter-react-ui';
5-
import { useSafeWallet } from '@/contexts/WalletContextProvider';
4+
import { SwigWalletButton } from './SwigWalletButton';
5+
import { useSwigWallet } from '@/contexts/SwigWalletProvider';
66
import { createLogger } from '@/utils/logger';
77

88
// Import context
@@ -28,7 +28,7 @@ export default function Layout({ children, title = 'OpenSVM P2P Exchange' }) {
2828
networks
2929
} = useContext(AppContext);
3030

31-
const { connected, publicKey } = useSafeWallet();
31+
const { connected, publicKey } = useSwigWallet();
3232
const [showOnboarding, setShowOnboarding] = useState(false);
3333
const [currentLocale, setCurrentLocale] = useState('en');
3434

@@ -199,15 +199,10 @@ export default function Layout({ children, title = 'OpenSVM P2P Exchange' }) {
199199
</span>
200200
)}
201201

202-
{/* Wallet connection button */}
203-
{!connected && (
204-
<div className="header-wallet-container">
205-
<WalletMultiButton />
206-
</div>
207-
)}
208-
209-
{/* Disconnect button for connected users */}
210-
{connected && <WalletDisconnectButton />}
202+
{/* Swig wallet connection button */}
203+
<div className="header-wallet-container">
204+
<SwigWalletButton />
205+
</div>
211206
</div>
212207
</div>
213208
</header>

src/components/OAuthButtons.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* OAuth Authentication Buttons Component
3+
*
4+
* Provides OAuth login options for Swig wallet authentication
5+
*/
6+
7+
import React from 'react';
8+
import { OAuthMethod } from '@getpara/web-sdk';
9+
10+
/**
11+
* OAuth authentication buttons component
12+
* @param {Object} props - Component props
13+
* @param {Function} props.onSelect - Callback when OAuth method is selected
14+
* @param {boolean} props.isLoading - Loading state
15+
*/
16+
export const OAuthButtons = ({ onSelect, isLoading = false }) => {
17+
const oauthMethods = [
18+
{
19+
method: OAuthMethod.GOOGLE,
20+
name: 'Google',
21+
icon: '🔍',
22+
color: 'bg-blue-500 hover:bg-blue-600',
23+
},
24+
{
25+
method: OAuthMethod.APPLE,
26+
name: 'Apple',
27+
icon: '🍎',
28+
color: 'bg-gray-800 hover:bg-gray-900',
29+
},
30+
{
31+
method: OAuthMethod.FARCASTER,
32+
name: 'Farcaster',
33+
icon: '🟣',
34+
color: 'bg-purple-500 hover:bg-purple-600',
35+
},
36+
];
37+
38+
if (isLoading) {
39+
return (
40+
<div className="flex justify-center items-center p-4">
41+
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
42+
<span className="ml-2 text-gray-600">Authenticating...</span>
43+
</div>
44+
);
45+
}
46+
47+
return (
48+
<div className="flex flex-col gap-3 w-full max-w-sm">
49+
<h3 className="text-lg font-semibold text-center mb-2">Sign in to continue</h3>
50+
{oauthMethods.map(({ method, name, icon, color }) => (
51+
<button
52+
key={method}
53+
onClick={() => onSelect(method)}
54+
className={`flex items-center justify-center gap-3 px-4 py-3 rounded-lg text-white font-medium transition-colors ${color} disabled:opacity-50 disabled:cursor-not-allowed`}
55+
disabled={isLoading}
56+
>
57+
<span className="text-xl">{icon}</span>
58+
<span>Continue with {name}</span>
59+
</button>
60+
))}
61+
<div className="text-xs text-gray-500 text-center mt-2">
62+
By continuing, you agree to our Terms of Service and Privacy Policy
63+
</div>
64+
</div>
65+
);
66+
};
67+
68+
export default OAuthButtons;

src/components/OfferCreation.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { useState, useContext } from 'react';
2-
import { useConnection } from '@solana/wallet-adapter-react';
32
import { SystemProgram, Keypair, LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js';
43
// Import BN from @coral-xyz/anchor as a fallback for @project-serum/anchor
54
import { BN } from '@coral-xyz/anchor';
@@ -12,7 +11,7 @@ import {
1211
ConfirmationDialog
1312
} from './common';
1413

15-
import { useSafeWallet } from '../contexts/WalletContextProvider';
14+
import { useSwigWallet } from '../contexts/SwigWalletProvider';
1615
import { useActionDebounce, useInputValidation } from '../hooks/useActionDebounce';
1716
import { validateSolAmount, validateFiatAmount, validateMarketRate } from '../utils/validation';
1817
import { createLogger } from '../utils/logger';
@@ -29,8 +28,9 @@ import DemoIndicator from './DemoIndicator';
2928
const logger = createLogger('OfferCreation');
3029

3130
const OfferCreation = ({ onStartGuidedWorkflow }) => {
32-
const wallet = useSafeWallet();
33-
const { connection } = useConnection();
31+
const wallet = useSwigWallet();
32+
// For Swig wallet, we'll get connection from the wallet context
33+
const connection = wallet.getConnection ? wallet.getConnection() : null;
3434
const { program, network } = useContext(AppContext);
3535

3636
const [solAmount, setSolAmount] = useState('');

src/components/OnboardingModal.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import React, { useState, useEffect } from 'react';
2-
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
3-
import { useWallet } from '@solana/wallet-adapter-react';
2+
import { SwigWalletButton } from './SwigWalletButton';
3+
import { useSwigWallet } from '../contexts/SwigWalletProvider';
44
import LanguageSelector from './LanguageSelector';
55
import { createUserRewardsAccount, hasUserRewardsAccount } from '../utils/rewardTransactions';
66
import { REWARD_CONSTANTS, UI_CONFIG } from '../constants/rewardConstants';
77

88
const OnboardingModal = ({ isOpen, onComplete, onSkip }) => {
9-
const { publicKey, connected, wallet } = useWallet();
9+
const { publicKey, connected, wallet } = useSwigWallet();
1010
const [currentStep, setCurrentStep] = useState(0);
1111
const [isVisible, setIsVisible] = useState(false);
1212
const [selectedLanguage, setSelectedLanguage] = useState('en');
@@ -178,7 +178,7 @@ const OnboardingModal = ({ isOpen, onComplete, onSkip }) => {
178178
</div>
179179
</div>
180180
<div className="wallet-connect-section">
181-
<WalletMultiButton />
181+
<SwigWalletButton />
182182
</div>
183183
</div>
184184
)

src/components/RewardDashboard.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState, useEffect, useCallback } from 'react';
2-
import { useWallet } from '@solana/wallet-adapter-react';
2+
import { useSwigWallet } from '../contexts/SwigWalletProvider';
33
import { fetchCompleteRewardData, clearUserCache } from '../utils/rewardQueries';
44
import {
55
claimRewards,
@@ -22,7 +22,7 @@ import {
2222
} from '../constants/rewardConstants';
2323

2424
const RewardDashboard = () => {
25-
const { publicKey, connected, wallet } = useWallet();
25+
const { publicKey, connected, wallet } = useSwigWallet();
2626
const autoClaimManager = useAutoClaimManager(wallet, null); // connection would be passed in real implementation
2727
const [rewards, setRewards] = useState(DEFAULT_REWARD_DATA.userRewards);
2828
const [rewardToken, setRewardToken] = useState(DEFAULT_REWARD_DATA.rewardToken);

0 commit comments

Comments
 (0)