@@ -7,9 +7,11 @@ import { CHAIN_NAMESPACES } from "@web3auth/no-modal";
77import { ref , watch } from " vue" ;
88
99const BASE_SEPOLIA_CHAIN_ID = " 0x14a34" ; // 84532
10+ const SOLANA_DEVNET_CHAIN_ID = " 0x67" ; // 103
11+ const SOLANA_DEVNET_CAIP_CHAIN_ID = ` solana:${Number (SOLANA_DEVNET_CHAIN_ID )} ` ;
1012const DEFAULT_X402_URL = import .meta .env .VITE_APP_X402_TEST_CONTENT_URL || " https://x402.org/protected" ;
1113
12- const { isConnected } = useWeb3Auth ();
14+ const { isConnected, connection, web3Auth } = useWeb3Auth ();
1315const { chainId, chainNamespace } = useChain ();
1416const { mutateAsync : switchChainAsync } = useSwitchChain ();
1517const { fetchWithPayment } = useX402Fetch ();
@@ -21,6 +23,7 @@ const url = ref(DEFAULT_X402_URL);
2123const fetchLoading = ref (false );
2224
2325const isOnBaseSepolia = ref (false );
26+ const isOnSolanaDevnet = ref (false );
2427
2528const parseConsoleBody = (text : string ) => {
2629 try {
@@ -31,9 +34,10 @@ const parseConsoleBody = (text: string) => {
3134};
3235
3336watch (
34- chainId ,
35- (id ) => {
36- isOnBaseSepolia .value = id ?.toLowerCase () === BASE_SEPOLIA_CHAIN_ID .toLowerCase ();
37+ [chainId , chainNamespace ],
38+ ([id , namespace ]) => {
39+ isOnBaseSepolia .value = namespace === CHAIN_NAMESPACES .EIP155 && id ?.toLowerCase () === BASE_SEPOLIA_CHAIN_ID .toLowerCase ();
40+ isOnSolanaDevnet .value = namespace === CHAIN_NAMESPACES .SOLANA && id ?.toLowerCase () === SOLANA_DEVNET_CHAIN_ID .toLowerCase ();
3741 },
3842 { immediate: true }
3943);
@@ -49,6 +53,28 @@ const onSwitchToBaseSepolia = async () => {
4953 }
5054};
5155
56+ const onSwitchToSolanaDevnet = async () => {
57+ fetchLoading .value = true ;
58+ try {
59+ const provider = connection .value ?.ethereumProvider ;
60+
61+ if (provider ?.request ) {
62+ await provider .request ({
63+ method: " wallet_switchChain" ,
64+ params: { chainId: SOLANA_DEVNET_CAIP_CHAIN_ID },
65+ });
66+ return ;
67+ }
68+
69+ if (! web3Auth .value ) throw new Error (" Web3Auth is not ready" );
70+ await web3Auth .value .switchChain ({ chainId: SOLANA_DEVNET_CHAIN_ID });
71+ } catch (err ) {
72+ emit (" print-to-console" , " x402 network error" , err instanceof Error ? err .message : String (err ));
73+ } finally {
74+ fetchLoading .value = false ;
75+ }
76+ };
77+
5278const onFetchWithPayment = async () => {
5379 fetchLoading .value = true ;
5480 try {
@@ -75,7 +101,6 @@ const onFetchWithPayment = async () => {
75101 <Card class =" px-4 py-4 gap-4 h-auto" :shadow =" false" >
76102 <div class =" mb-3 text-xl font-bold leading-tight text-left" >x402 Payment Fetch</div >
77103
78- <!-- Status badges -->
79104 <div class =" flex flex-wrap gap-2 mb-3 text-xs" >
80105 <span class =" px-2 py-1 rounded-full font-medium" :class =" isConnected ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-600'" >
81106 {{ isConnected ? "Connected" : "Not connected" }}
@@ -91,16 +116,26 @@ const onFetchWithPayment = async () => {
91116 >
92117 {{ isOnBaseSepolia ? "Base Sepolia" : "Not on Base Sepolia" }}
93118 </span >
119+ <span
120+ v-if =" chainNamespace === CHAIN_NAMESPACES.SOLANA"
121+ class =" px-2 py-1 rounded-full font-medium"
122+ :class =" isOnSolanaDevnet ? 'bg-blue-100 text-blue-700' : 'bg-yellow-100 text-yellow-700'"
123+ >
124+ {{ isOnSolanaDevnet ? "Solana Devnet" : "Not on Solana Devnet" }}
125+ </span >
94126 </div >
95127
96- <!-- Switch chain -->
97128 <div v-if =" isConnected && chainNamespace === CHAIN_NAMESPACES.EIP155" class =" mb-3" >
98129 <Button block size =" xs" pill :loading =" fetchLoading" :disabled =" isOnBaseSepolia" @click =" onSwitchToBaseSepolia" >
99130 {{ isOnBaseSepolia ? "Already on Base Sepolia" : "Switch to Base Sepolia" }}
100131 </Button >
101132 </div >
133+ <div v-if =" isConnected && chainNamespace === CHAIN_NAMESPACES.SOLANA" class =" mb-3" >
134+ <Button block size =" xs" pill :loading =" fetchLoading" :disabled =" isOnSolanaDevnet" @click =" onSwitchToSolanaDevnet" >
135+ {{ isOnSolanaDevnet ? "Already on Solana Devnet" : "Switch to Solana Devnet" }}
136+ </Button >
137+ </div >
102138
103- <!-- URL input -->
104139 <div class =" mb-3" >
105140 <label class =" block mb-1 text-xs font-medium text-gray-600" >Endpoint URL</label >
106141 <input
@@ -111,7 +146,6 @@ const onFetchWithPayment = async () => {
111146 />
112147 </div >
113148
114- <!-- Fetch button -->
115149 <Button block size =" xs" pill :loading =" fetchLoading" :disabled =" !isConnected" class =" mb-3" @click =" onFetchWithPayment" >Fetch with Payment</Button >
116150 </Card >
117151</template >
0 commit comments