1+ import { Express } from "express" ;
2+ import fetch from "node-fetch" ;
3+ import { VersionedTransaction , PublicKey , Connection } from "@solana/web3.js" ;
4+
5+ // Define the token metadata
6+ const GBUX_TOKEN_ADDRESS = "55TpSoMNxbfsNJ9U1dQoo9H3dRtDmjBZVMcKqvU2nray" ;
7+ const SOLANA_RPC_ENDPOINT = "https://api.mainnet-beta.solana.com" ; // Use a more reliable endpoint in production
8+
9+ // Solana connection instance
10+ /**
11+ * GBUX-Solana Integration Routes
12+ * Created by: Racalvin The Pirate King
13+ * Studio: Grudge Studio
14+ * Project: Nexus Nemesis - Web3 Trading Card Game
15+ */
16+
17+ const connection = new Connection ( SOLANA_RPC_ENDPOINT ) ;
18+
19+ export function registerGBuXSolanaRoutes ( app : Express ) {
20+
21+ // Endpoint to verify a user's GBuX balance on Solana
22+ app . get ( "/api/solana/gbux/verify/:address" , async ( req , res ) => {
23+ try {
24+ const { address } = req . params ;
25+
26+ // Validate Solana address format
27+ if ( ! address || address . length !== 44 ) {
28+ return res . status ( 400 ) . json ( { success : false , message : "Invalid Solana address format" } ) ;
29+ }
30+
31+ // Create a Solana public key from address
32+ let publicKey : PublicKey ;
33+ try {
34+ publicKey = new PublicKey ( address ) ;
35+ } catch ( error ) {
36+ return res . status ( 400 ) . json ( { success : false , message : "Invalid Solana address" } ) ;
37+ }
38+
39+ // Verify the balance using Solscan API first (they have better token metadata)
40+ try {
41+ const solscanResponse = await fetch ( `https://public-api.solscan.io/account/tokens?account=${ address } ` , {
42+ headers : {
43+ 'Accept' : 'application/json'
44+ }
45+ } ) ;
46+
47+ if ( solscanResponse . ok ) {
48+ const tokens = await solscanResponse . json ( ) ;
49+
50+ // Find GBuX token in the user's tokens
51+ const gbuxToken = tokens . find ( ( token : any ) => token . tokenAddress === GBUX_TOKEN_ADDRESS ) ;
52+
53+ if ( gbuxToken ) {
54+ // Convert from token amount to human-readable amount
55+ const tokenBalance = parseFloat ( gbuxToken . tokenAmount . amount ) / Math . pow ( 10 , gbuxToken . tokenAmount . decimals ) ;
56+ return res . json ( {
57+ success : true ,
58+ address,
59+ balance : tokenBalance . toString ( ) ,
60+ verified : true ,
61+ source : "solscan"
62+ } ) ;
63+ }
64+ }
65+ } catch ( solscanError ) {
66+ console . error ( "Solscan API error:" , solscanError ) ;
67+ // We'll fall back to the Solana RPC directly if Solscan fails
68+ }
69+
70+ // Fallback to Solana RPC API
71+ try {
72+ // Get token accounts owned by this address
73+ const tokenAccounts = await connection . getParsedTokenAccountsByOwner (
74+ publicKey ,
75+ { programId : new PublicKey ( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" ) } // Token program ID
76+ ) ;
77+
78+ // Find GBuX token account
79+ const gbuxAccount = tokenAccounts . value . find (
80+ ( account ) => account . account . data . parsed . info . mint === GBUX_TOKEN_ADDRESS
81+ ) ;
82+
83+ if ( gbuxAccount ) {
84+ const balance = gbuxAccount . account . data . parsed . info . tokenAmount . uiAmount ;
85+ return res . json ( {
86+ success : true ,
87+ address,
88+ balance : balance . toString ( ) ,
89+ verified : true ,
90+ source : "solana_rpc"
91+ } ) ;
92+ } else {
93+ // User has no GBuX tokens
94+ return res . json ( {
95+ success : true ,
96+ address,
97+ balance : "0" ,
98+ verified : true ,
99+ source : "solana_rpc"
100+ } ) ;
101+ }
102+ } catch ( rpcError ) {
103+ console . error ( "Solana RPC error:" , rpcError ) ;
104+ return res . status ( 500 ) . json ( { success : false , message : "Failed to verify token balance" } ) ;
105+ }
106+ } catch ( error ) {
107+ console . error ( "Error verifying GBuX balance:" , error ) ;
108+ return res . status ( 500 ) . json ( { success : false , message : "Internal server error" } ) ;
109+ }
110+ } ) ;
111+
112+ // Endpoint to get token information
113+ app . get ( "/api/solana/gbux/info" , async ( req , res ) => {
114+ try {
115+ // Try to get token info from Solscan
116+ const response = await fetch ( `https://public-api.solscan.io/token/meta?tokenAddress=${ GBUX_TOKEN_ADDRESS } ` , {
117+ headers : {
118+ 'Accept' : 'application/json'
119+ }
120+ } ) ;
121+
122+ if ( response . ok ) {
123+ const tokenInfo = await response . json ( ) ;
124+ return res . json ( {
125+ success : true ,
126+ tokenInfo
127+ } ) ;
128+ } else {
129+ // Basic info if API fails
130+ return res . json ( {
131+ success : true ,
132+ tokenInfo : {
133+ symbol : "GBuX" ,
134+ name : "GBuX" ,
135+ address : GBUX_TOKEN_ADDRESS ,
136+ decimals : 9 ,
137+ icon : "" ,
138+ description : "GBuX is the in-game currency for Nexus Nemesis"
139+ }
140+ } ) ;
141+ }
142+ } catch ( error ) {
143+ console . error ( "Error fetching GBuX token info:" , error ) ;
144+ return res . status ( 500 ) . json ( { success : false , message : "Failed to fetch token information" } ) ;
145+ }
146+ } ) ;
147+
148+ // Endpoint to get recent GBuX token holders (top 20)
149+ app . get ( "/api/solana/gbux/holders" , async ( req , res ) => {
150+ try {
151+ const response = await fetch ( `https://public-api.solscan.io/token/holders?tokenAddress=${ GBUX_TOKEN_ADDRESS } &limit=20&offset=0` , {
152+ headers : {
153+ 'Accept' : 'application/json'
154+ }
155+ } ) ;
156+
157+ if ( response . ok ) {
158+ const holdersData = await response . json ( ) ;
159+ return res . json ( {
160+ success : true ,
161+ holders : holdersData . data
162+ } ) ;
163+ } else {
164+ return res . status ( response . status ) . json ( { success : false , message : "Failed to fetch token holders" } ) ;
165+ }
166+ } catch ( error ) {
167+ console . error ( "Error fetching GBuX holders:" , error ) ;
168+ return res . status ( 500 ) . json ( { success : false , message : "Internal server error" } ) ;
169+ }
170+ } ) ;
171+ }
0 commit comments