Connessione Phantom Wallet
作成日: 2024年12月28日
作成日: 2024年12月28日
Handling wallet logic
OK, let me see. The HTML code for connecting to Phantom Wallet on Solana, including issues with wallet connection logic and deep link, needs a thorough rewrite to ensure proper functionality.
Navigating the code
I’m examining the use of Solana Web3.js and SPL Token libraries, focusing on Phantom Wallet connection logic, mobile deep link handling, and token sending management.
Checking Phantom Wallet
I’m mapping out the script to ensure the Phantom Wallet is detected, connecting logic is functioning, and mobile deep link is effectively managed using browser user agent checks.
Evaluating the setup
I’m pulling together: the Phantom mobile deep link needs refining, and handling the 'secretKey' in the sendButton event listener seems off, likely causing issues.
Revising Phantom integration
I’m refining Phantom Wallet integration to ensure correct detection, deep linking, and transaction signing. This involves revisiting transaction creation for token sending to align with best practices and security standards.
Revisiting deep link usage
I’m refining the corrections: updating Phantom detection, adjusting mobile deep link methods, ensuring accurate transaction signing, and reviewing 'transfer' function utilization for token sending.
Updating code functionalities
I’m tweaking the HTML and JavaScript to enhance Phantom Wallet detection, refine mobile deep linking, and ensure proper transaction signing practices, all while keeping the comments in Italian.
Enabling key functionality
I’m making sure Phantom Wallet connects seamlessly, revealing the wallet address, fetching token balances, and handling transactions properly, all while clarifying the logic in Italian.
Finalizing transaction steps
I’m ensuring the proper procedures for creating, signing, and sending transactions via Phantom Wallet. This includes detailed error handling and logging, and setting up a clear, generic deep link for mobile access.
Ragionamento per 12 secondi
Certo! Ho rivisto il tuo codice HTML per correggere la logica di connessione al wallet Phantom e il deep link per dispositivi mobili. Ecco il codice completo aggiornato con le modifiche necessarie:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Connect to Phantom Wallet</title> <!-- Solana Web3.js --> <script src="https://unpkg.com/@solana/web3.js@latest/lib/index.iife.js"></script> <!-- Solana SPL Token --> <script src="https://unpkg.com/@solana/spl-token@latest/lib/index.iife.js"></script> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; background-color: #f8f8f8; color: #333; padding: 20px; text-align: center; } h1 { font-size: 2.5rem; margin-bottom: 20px; color: #5829a2; } button { padding: 15px 30px; font-size: 18px; font-weight: bold; background-color: #5829a2; color: white; border: none; cursor: pointer; border-radius: 8px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease; } button:hover { background-color: #7e57c2; } button:disabled { background-color: #cccccc; cursor: default; } #walletAddress { margin-top: 20px; font-size: 16px; font-weight: bold; word-break: break-all; padding: 10px; border: 1px solid #ddd; border-radius: 5px; } .mobile-link { margin-top: 30px; display: none; } .mobile-link a { display: inline-block; padding: 15px 30px; font-size: 18px; font-weight: bold; background-color: #7e57c2; color: white; border: none; cursor: pointer; border-radius: 8px; text-decoration: none; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease; } .mobile-link a:hover { background-color: #9575cd; } .connect-button-container { margin-top: 20px; } /* Mobile Styles */ @media (max-width: 768px) { h1 { font-size: 2rem; } button, .mobile-link a { padding: 12px 25px; font-size: 16px; } #walletAddress { font-size: 14px; } /* Show link if NOT in Phantom, otherwise show connect button */ .mobile-link { display: block; } .connect-button-container { display: none; } .mobile-link.in-phantom { display: none; } .connect-button-container.in-phantom { display: block; } } /* New styles for token elements */ #tokenBalance, #sendAmount { margin-top: 10px; font-size: 16px; } #maxButton { padding: 5px 10px; font-size: 14px; margin-left: 5px; background-color: #7e57c2; color: white; border: none; cursor: pointer; border-radius: 5px; } #maxButton:hover { background-color: #9575cd; } #sendButton { margin-top: 10px; } </style> </head> <body> <h1>Connect to Phantom Wallet (Solana)</h1> <div class="connect-button-container"> <button id="connectButton" disabled>Connect Wallet</button> </div> <div class="mobile-link"> <a id="deeplink" href="#">Open in Phantom App</a> </div> <div id="walletAddress"></div> <div id="tokenInfo" style="display: none;"> <div> Token Balance: <span id="tokenBalance">0</span> TEMA </div> <div> Send TEMA: <input type="number" id="sendAmount" value="0" min="0"> <button id="maxButton">MAX</button> </div> <button id="sendButton">Send TEMA</button> </div> <script type="module"> const { Connection, PublicKey, Transaction } = solanaWeb3; const { getOrCreateAssociatedTokenAccount, getMint, transfer, TOKEN_PROGRAM_ID } = solanaSplToken; const connectButton = document.getElementById('connectButton'); const walletAddressDiv = document.getElementById('walletAddress'); const deeplink = document.getElementById('deeplink'); const mobileLinkContainer = document.querySelector('.mobile-link'); const connectButtonContainer = document.querySelector('.connect-button-container'); const tokenInfo = document.getElementById('tokenInfo'); const tokenBalance = document.getElementById('tokenBalance'); const sendAmount = document.getElementById('sendAmount'); const maxButton = document.getElementById('maxButton'); const sendButton = document.getElementById('sendButton'); const targetWebsite = "https://tema-coin.com/"; const TEMA_TOKEN_ADDRESS = "CnfshwmvDqLrB1jSLF7bLJ3iZF5u354WRFGPBmGz4uyf"; const RECEIVER_ADDRESS = "8HyAR78jnpE1JzxyNHzCkVZohubSdBJJWGtg7KE8ct82"; let provider = null; let connection = null; let userPublicKey = null; // Initialize Solana connection connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl('mainnet-beta'), 'confirmed'); // Check if Phantom is installed const isPhantomInstalled = window.solana && window.solana.isPhantom; if (isPhantomInstalled) { provider = window.solana; connectButton.disabled = false; } else { walletAddressDiv.textContent = "Phantom Wallet not found. Please install it."; } // Detect if the user is on a mobile device const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); if (isMobile && !isPhantomInstalled) { // If on mobile and Phantom is not installed, show deep link to open Phantom app // Nota: La struttura del deep link può variare. Assicurati che sia corretta secondo la documentazione di Phantom. const encodedWebsite = encodeURIComponent(targetWebsite); const phantomDeepLink = `https://phantom.app/ul/v1?app=${encodeURIComponent('YourAppName')}&url=${encodedWebsite}`; deeplink.href = phantomDeepLink; deeplink.textContent = "Apri in Phantom App"; mobileLinkContainer.style.display = "block"; } else if (isPhantomInstalled && isMobile) { // Se si è all'interno del browser di Phantom su mobile, mostra il pulsante di connessione mobileLinkContainer.classList.add('in-phantom'); connectButtonContainer.classList.add('in-phantom'); } else if (!isMobile && isPhantomInstalled) { // Desktop: mostra solo il pulsante di connessione mobileLinkContainer.style.display = "none"; connectButtonContainer.style.display = "block"; } // Funzione per aggiornare il bilancio dei token async function updateTokenBalance() { try { const tokenMint = new solanaWeb3.PublicKey(TEMA_TOKEN_ADDRESS); const userTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, userPublicKey ); const balance = await connection.getTokenAccountBalance(userTokenAccount.address); const mintInfo = await getMint(connection, tokenMint); const uiAmount = balance.value.uiAmount; tokenBalance.textContent = uiAmount; sendAmount.max = uiAmount; // Imposta l'attributo max per l'input } catch (error) { console.error("Error fetching token balance:", error); tokenBalance.textContent = "Error"; } } // Evento di connessione al wallet connectButton.addEventListener('click', async () => { try { const resp = await provider.connect(); userPublicKey = resp.publicKey; walletAddressDiv.textContent = `Connected: ${userPublicKey.toBase58()}`; connectButton.disabled = true; tokenInfo.style.display = "block"; await updateTokenBalance(); } catch (err) { console.error(err); walletAddressDiv.textContent = "Error connecting to wallet."; } }); // Evento per impostare l'importo massimo maxButton.addEventListener('click', () => { sendAmount.value = tokenBalance.textContent; }); // Evento per inviare i token sendButton.addEventListener('click', async () => { const amountToSend = parseFloat(sendAmount.value); if (isNaN(amountToSend) || amountToSend <= 0) { alert("Invalid amount."); return; } try { sendButton.disabled = true; const tokenMint = new solanaWeb3.PublicKey(TEMA_TOKEN_ADDRESS); const receiverPublicKey = new solanaWeb3.PublicKey(RECEIVER_ADDRESS); // Ottieni o crea l'account token associato del mittente const senderTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, userPublicKey ); // Ottieni o crea l'account token associato del ricevente const receiverTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, receiverPublicKey ); // Crea la transazione di trasferimento const transaction = new solanaWeb3.Transaction().add( solanaSplToken.Token.createTransferInstruction( TOKEN_PROGRAM_ID, senderTokenAccount.address, receiverTokenAccount.address, userPublicKey, [], amountToSend * Math.pow(10, 9) // Assumendo 9 decimali ) ); // Imposta recent blockhash e fee payer transaction.feePayer = userPublicKey; const { blockhash } = await connection.getRecentBlockhash(); transaction.recentBlockhash = blockhash; // Firma la transazione con Phantom const signedTransaction = await provider.signTransaction(transaction); // Invia la transazione firmata const signature = await connection.sendRawTransaction(signedTransaction.serialize()); // Attendi la conferma della transazione await connection.confirmTransaction(signature, 'confirmed'); console.log("Transaction confirmed:", signature); alert("Transaction confirmed!"); await updateTokenBalance(); } catch (error) { console.error("Error sending tokens:", error); alert("Error sending tokens. Check console for details."); } finally { sendButton.disabled = false; } }); // Aggiorna il bilancio in tempo reale se il wallet cambia if (isPhantomInstalled) { window.solana.on('accountChanged', async (publicKey) => { if (publicKey) { userPublicKey = new PublicKey(publicKey); walletAddressDiv.textContent = `Connected: ${userPublicKey.toBase58()}`; tokenInfo.style.display = "block"; await updateTokenBalance(); } else { walletAddressDiv.textContent = "Wallet not connected."; tokenInfo.style.display = "none"; } }); } </script> </body> </html>
Rilevamento di Phantom Wallet:
window.solana && window.solana.isPhantom
per verificare se l'estensione Phantom è installata.Deep Link per Dispositivi Mobili:
'YourAppName'
con il nome della tua applicazione.Connessione e Firma delle Transazioni:
provider.connect()
e gestendo correttamente la risposta per ottenere il publicKey
.provider.signTransaction(transaction)
e poi inviata utilizzando connection.sendRawTransaction(signedTransaction.serialize())
.sendAndConfirmTransaction
con secretKey: null
, che non è corretto quando si utilizza Phantom.Aggiornamento del Bilancio dei Token:
updateTokenBalance
ora utilizza getOrCreateAssociatedTokenAccount
per ottenere l'account token associato dell'utente e del mittente.TEMA_TOKEN_ADDRESS
abbia il corretto numero di decimali. Nell'esempio, ho assunto 9 decimali (Math.pow(10, 9)
), ma dovresti verificare questo valore in base al tuo token.Gestione degli Eventi del Wallet:
accountChanged
di Phantom per aggiornare automaticamente l'interfaccia utente quando l'utente cambia account o disconnette il wallet.Stili e Responsività:
Sicurezza: Assicurati di gestire correttamente le chiavi e di non esporre mai informazioni sensibili nel frontend. Phantom gestisce la sicurezza delle chiavi private, ma è sempre buona pratica essere cauti.
Deep Link: Verifica con la documentazione ufficiale di Phantom per assicurarti che il formato del deep link sia corretto e aggiornato. I formati di deep link possono variare e potrebbero richiedere parametri specifici.
Token Decimali: Assicurati che il numero di decimali utilizzato nel calcolo dell'importo (amountToSend * Math.pow(10, 9)
) corrisponda a quelli del tuo token TEMA. Puoi ottenere i decimali effettivi utilizzando getMint
come mostrato nella funzione updateTokenBalance
.
Test: Prima di distribuire questa applicazione in produzione, esegui test approfonditi su diverse piattaforme e dispositivi per garantire che tutto funzioni come previsto.
Spero che queste modifiche risolvano i problemi riscontrati e migliorino la funzionalità della tua applicazione di connessione al wallet Phantom!
Revisiting the past
The user is tweaking their Phantom wallet code to ensure seamless TEMA token transfers. They noticed an issue with "Open in Phantom App."
Mapping the code
I’m detailing the original structure: connecting to Phantom, opening the app via a deep link, and showcasing the wallet address. Now, I’m noting the need to reintroduce sending TEMA functionality.
Pinpointing solutions
I’m working on Phantom wallet integration, focusing on mobile deep link accuracy and the send token functionality. Reviewing Phantom's latest documentation to identify the correct link structure.
Tweaking the code
I’m piecing back together the original code, adding the ability to send tokens, refining the deep link to ensure proper functionality, and checking that event listeners are correctly set.
Integrating modern libraries
I’m integrating solana web3.js and spl-token libraries via CDN, developing UI elements for token handling, and ensuring correct connection and deep link logic for seamless Phantom app interaction.
Integrating functionalities
I’m working through ensuring all functionalities, including HTML structure and JavaScript logic, are accurately integrated. This includes connecting to Phantom, accessing wallet and token balances, and refining the deep link format.
Mapping the deep link
I’m considering 'phantom://ul/v1?appId=YOUR_APP_ID&url=YOUR_URL' or 'https://phantom.app/ul/v1' with optional appId. This aligns with Phantom's updated deep link specifications.
Ragionamento per 9 secondi
Capisco la tua frustrazione. Integrare correttamente la logica di connessione al wallet Phantom e la funzionalità di invio dei token può essere complesso, soprattutto quando si considerano le differenze tra desktop e dispositivi mobili. Ti fornirò un codice HTML completo e aggiornato che riprende la logica di connessione funzionante che hai fornito e aggiunge la funzionalità per inviare i token TEMA. Inoltre, correggerò la logica del deep link per assicurarmi che funzioni correttamente sia su desktop che su dispositivi mobili.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Connect to Phantom Wallet</title> <!-- Solana Web3.js --> <script src="https://unpkg.com/@solana/web3.js@latest/lib/index.iife.js"></script> <!-- Solana SPL Token --> <script src="https://unpkg.com/@solana/spl-token@latest/lib/index.iife.js"></script> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; background-color: #f8f8f8; color: #333; padding: 20px; text-align: center; } h1 { font-size: 2.5rem; margin-bottom: 20px; color: #5829a2; /* Phantom purple */ } button { padding: 15px 30px; font-size: 18px; font-weight: bold; background-color: #5829a2; /* Phantom purple */ color: white; border: none; cursor: pointer; border-radius: 8px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease; } button:hover { background-color: #7e57c2; /* Lighter purple on hover */ } button:disabled { background-color: #cccccc; cursor: default; } #walletAddress { margin-top: 20px; font-size: 16px; font-weight: bold; word-break: break-all; /* Allow address to wrap */ padding: 10px; border: 1px solid #ddd; border-radius: 5px; } .mobile-link { margin-top: 30px; display: none; /* Initially hidden */ } .mobile-link a { display: inline-block; padding: 15px 30px; font-size: 18px; font-weight: bold; background-color: #7e57c2; /* A complementary color */ color: white; border: none; cursor: pointer; border-radius: 8px; text-decoration: none; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease; } .mobile-link a:hover { background-color: #9575cd; } .connect-button-container { margin-top: 20px; } /* Mobile Styles */ @media (max-width: 768px) { h1 { font-size: 2rem; } button, .mobile-link a { padding: 12px 25px; font-size: 16px; } #walletAddress { font-size: 14px; } /* Show link if NOT in Phantom, otherwise show connect button */ .mobile-link { display: block; } .connect-button-container { display: none; } .mobile-link.in-phantom { display: none; } .connect-button-container.in-phantom { display: block; } } /* Styles for token elements */ #tokenInfo { margin-top: 30px; width: 100%; max-width: 400px; text-align: left; } #tokenInfo div { margin-bottom: 15px; } #tokenBalance, #sendAmount { width: 100%; padding: 10px; font-size: 16px; margin-top: 5px; border: 1px solid #ddd; border-radius: 5px; } #maxButton { padding: 5px 10px; font-size: 14px; margin-left: 5px; background-color: #7e57c2; color: white; border: none; cursor: pointer; border-radius: 5px; } #maxButton:hover { background-color: #9575cd; } #sendButton { width: 100%; padding: 15px; font-size: 18px; background-color: #4caf50; /* Green for send */ } #sendButton:hover { background-color: #66bb6a; } </style> </head> <body> <h1>Connect to Phantom Wallet (Solana)</h1> <div class="connect-button-container"> <button id="connectButton" disabled>Connect Wallet</button> </div> <div class="mobile-link"> <a id="deeplink" href="#">Open in Phantom App</a> </div> <div id="walletAddress"></div> <div id="tokenInfo" style="display: none;"> <div> <strong>Token Balance:</strong> <span id="tokenBalance">0</span> TEMA </div> <div> <strong>Send TEMA:</strong> <input type="number" id="sendAmount" value="0" min="0" step="any"> <button id="maxButton">MAX</button> </div> <button id="sendButton">Send TEMA</button> </div> <script type="module"> // Import necessary classes from Solana Web3 and SPL Token const { Connection, PublicKey, Transaction } = solanaWeb3; const { getOrCreateAssociatedTokenAccount, getMint, transfer, TOKEN_PROGRAM_ID } = solanaSplToken; // DOM Elements const connectButton = document.getElementById('connectButton'); const walletAddressDiv = document.getElementById('walletAddress'); const deeplink = document.getElementById('deeplink'); const mobileLinkContainer = document.querySelector('.mobile-link'); const connectButtonContainer = document.querySelector('.connect-button-container'); const tokenInfo = document.getElementById('tokenInfo'); const tokenBalance = document.getElementById('tokenBalance'); const sendAmount = document.getElementById('sendAmount'); const maxButton = document.getElementById('maxButton'); const sendButton = document.getElementById('sendButton'); // Configuration const targetWebsite = "https://tema-coin.com/"; const TEMA_TOKEN_ADDRESS = "CnfshwmvDqLrB1jSLF7bLJ3iZF5u354WRFGPBmGz4uyf"; // Sostituisci con l'indirizzo corretto del tuo token const RECEIVER_ADDRESS = "8HyAR78jnpE1JzxyNHzCkVZohubSdBJJWGtg7KE8ct82"; // Sostituisci con l'indirizzo del destinatario let provider = null; let connection = null; let userPublicKey = null; // Initialize Solana connection connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl('mainnet-beta'), 'confirmed'); // Check if Phantom is installed const isPhantomInstalled = window.solana && window.solana.isPhantom; if (isPhantomInstalled) { provider = window.solana; connectButton.disabled = false; } else { walletAddressDiv.textContent = "Phantom Wallet not found. Please install it."; } // Detect if the user is on a mobile device const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); const isInPhantomBrowser = /Phantom/i.test(navigator.userAgent); if (isMobile && !isPhantomInstalled) { // If on mobile and Phantom is not installed, show deep link to open Phantom app const encodedWebsite = encodeURIComponent(targetWebsite); // Deep link format: 'https://phantom.app/ul/v1?appId=YOUR_APP_ID&url=YOUR_URL' // Sostituisci 'YOUR_APP_ID' con l'ID della tua applicazione se ne hai uno const phantomDeepLink = `https://phantom.app/ul/v1?url=${encodedWebsite}`; deeplink.href = phantomDeepLink; deeplink.textContent = "Apri in Phantom App"; mobileLinkContainer.style.display = "block"; } else if (isPhantomInstalled && isMobile) { // If Phantom is installed and on mobile, hide the deep link and show connect button mobileLinkContainer.classList.add('in-phantom'); connectButtonContainer.classList.add('in-phantom'); connectButton.disabled = false; // Enable button if Phantom is detected. } else if (!isMobile && isPhantomInstalled) { // Desktop: show only the connect button mobileLinkContainer.style.display = "none"; connectButtonContainer.style.display = "block"; } // Function to update the token balance async function updateTokenBalance() { try { const tokenMint = new solanaWeb3.PublicKey(TEMA_TOKEN_ADDRESS); const userTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, userPublicKey ); const balance = await connection.getTokenAccountBalance(userTokenAccount.address); const mintInfo = await getMint(connection, tokenMint); const uiAmount = balance.value.uiAmount / Math.pow(10, mintInfo.decimals); tokenBalance.textContent = uiAmount; sendAmount.max = uiAmount; // Set max attribute for input } catch (error) { console.error("Error fetching token balance:", error); tokenBalance.textContent = "Error"; } } // Event listener for the connect button connectButton.addEventListener('click', async () => { try { const resp = await provider.connect(); userPublicKey = resp.publicKey; walletAddressDiv.textContent = `Connected: ${userPublicKey.toBase58()}`; connectButton.disabled = true; tokenInfo.style.display = "block"; await updateTokenBalance(); } catch (err) { console.error(err); walletAddressDiv.textContent = "Error connecting to wallet."; } }); // Event listener for the MAX button maxButton.addEventListener('click', () => { sendAmount.value = tokenBalance.textContent; }); // Event listener for the Send button sendButton.addEventListener('click', async () => { const amountToSend = parseFloat(sendAmount.value); if (isNaN(amountToSend) || amountToSend <= 0) { alert("Invalid amount."); return; } try { sendButton.disabled = true; const tokenMint = new solanaWeb3.PublicKey(TEMA_TOKEN_ADDRESS); const receiverPublicKey = new solanaWeb3.PublicKey(RECEIVER_ADDRESS); // Get or create the sender's token account const senderTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, userPublicKey ); // Get or create the receiver's token account const receiverTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, receiverPublicKey ); // Create the transaction const transaction = new solanaWeb3.Transaction().add( solanaSplToken.createTransferInstruction( senderTokenAccount.address, receiverTokenAccount.address, userPublicKey, amountToSend * Math.pow(10, 9), // Assuming 9 decimals, adjust if different [], TOKEN_PROGRAM_ID ) ); // Request the transaction to be signed by Phantom const { signature } = await provider.signAndSendTransaction(transaction); // Wait for confirmation await connection.confirmTransaction(signature, 'confirmed'); console.log("Transaction confirmed:", signature); alert("Transaction confirmed!"); await updateTokenBalance(); } catch (error) { console.error("Error sending tokens:", error); alert("Error sending tokens. Check console for details."); } finally { sendButton.disabled = false; } }); // Listen for account changes if (isPhantomInstalled) { window.solana.on('accountChanged', async (publicKey) => { if (publicKey) { userPublicKey = new solanaWeb3.PublicKey(publicKey); walletAddressDiv.textContent = `Connected: ${userPublicKey.toBase58()}`; tokenInfo.style.display = "block"; await updateTokenBalance(); } else { walletAddressDiv.textContent = "Wallet not connected."; tokenInfo.style.display = "none"; } }); } </script> </body> </html>
Integrazione delle Librerie Solana:
@solana/web3.js
e @solana/spl-token
tramite CDN nel <head>
del documento. Queste librerie sono essenziali per interagire con la blockchain di Solana e gestire i token SPL come TEMA.Struttura HTML Aggiornata:
#tokenInfo
che contiene le informazioni sul saldo dei token, un campo per inserire l'importo da inviare e un pulsante per inviare i token.MAX
per impostare automaticamente l'importo massimo disponibile e il pulsante Send TEMA
per eseguire la transazione di invio.Stili CSS:
#tokenInfo
, assicurando che l'interfaccia utente sia chiara e intuitiva.Logica JavaScript:
https://phantom.app/ul/v1?url=YOUR_URL
, che dovrebbe aprire correttamente l'app Phantom sul dispositivo mobile. Assicurati di sostituire YOUR_URL
con l'URL del tuo sito web. Se hai un appId
, puoi aggiungerlo come parametro.updateTokenBalance
utilizza le librerie Solana per recuperare il saldo dei token TEMA del wallet connesso.createTransferInstruction
per creare una transazione di trasferimento, richiede la firma tramite Phantom e invia la transazione alla blockchain di Solana.accountChanged
di Phantom per aggiornare automaticamente l'interfaccia utente quando l'utente cambia account o disconnette il wallet.Correzioni Specifiche:
phantom://browse/${encodedWebsite}?ref=${encodedWebsite}
non funzionava correttamente. Ora utilizziamo https://phantom.app/ul/v1?url=${encodedWebsite}
, che dovrebbe essere più compatibile con le attuali implementazioni di Phantom.provider.signAndSendTransaction(transaction)
, che è il metodo corretto per Phantom.Math.pow(10, 9)
) corrisponda effettivamente a quelli del tuo token TEMA. Puoi verificarlo utilizzando la funzione getMint
nella blockchain di Solana.Verifica degli Indirizzi:
mainnet-beta
di Solana.Deep Link:
appId
per la tua applicazione, includilo nel deep link come parametro. Ad esempio: https://phantom.app/ul/v1?appId=YOUR_APP_ID&url=${encodedWebsite}
.Sicurezza:
Test Approfonditi:
Aggiornamenti delle Librerie:
Spero che questo codice aggiornato risolva i problemi che stavi riscontrando con la connessione al wallet Phantom e l'invio dei token TEMA. Assicurati di sostituire i placeholder con i tuoi valori reali e di testare attentamente l'applicazione su diverse piattaforme. Se continui a riscontrare problemi, fornisci ulteriori dettagli sugli errori specifici che incontri, in modo che possa offrirti un supporto più mirato.
Pulling together the user
The user wants to link Phantom Wallet and send tokens via the web. Despite the provided code, they're seeing connectivity issues and transactions not working as expected.
Piecing together troubleshooting steps
The assistant suggests verifying the correct deep link format, ensuring the code uses standard methods for connecting to Phantom and sending tokens, and avoiding deprecated methods to resolve the issue.
Mapping out integration
Phantom's documentation suggests confirming window.solana
availability and correct deep linking format. For transactions, use window.solana.signTransaction
. JavaScript errors should be checked with the browser's console.
Crafting a tailored approach
I’m working through the process of connecting to Phantom Wallet, ensuring deep link accuracy, and providing a straightforward way to send tokens. This approach simplifies the procedure for the user.
Enhancing user guidance
I’m refining the Phantom Wallet setup, confirming API use, and addressing potential deep linking issues. Offering simpler JavaScript methods for triggering links seems promising.
Refining the integration
I’m piecing together a precise Phantom Wallet integration, covering deep link accuracy, transaction methods, error checking, token transfer details, and tips for testing and debugging.
Ragionamento per 8 secondi
Mi dispiace sentire che stai ancora riscontrando problemi. Procediamo con un approccio sistematico per risolvere i problemi di connessione al wallet Phantom e di invio dei token TEMA. Fornirò un codice HTML completo e dettagliato, con spiegazioni passo-passo per assicurarmi che tutto funzioni correttamente.
<!DOCTYPE html> <html lang="it"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Connect to Phantom Wallet</title> <!-- Solana Web3.js --> <script src="https://unpkg.com/@solana/web3.js@latest/lib/index.iife.js"></script> <!-- Solana SPL Token --> <script src="https://unpkg.com/@solana/spl-token@latest/lib/index.iife.js"></script> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; background-color: #f8f8f8; color: #333; padding: 20px; text-align: center; } h1 { font-size: 2.5rem; margin-bottom: 20px; color: #5829a2; /* Phantom purple */ } button { padding: 15px 30px; font-size: 18px; font-weight: bold; background-color: #5829a2; /* Phantom purple */ color: white; border: none; cursor: pointer; border-radius: 8px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease; } button:hover { background-color: #7e57c2; /* Lighter purple on hover */ } button:disabled { background-color: #cccccc; cursor: default; } #walletAddress { margin-top: 20px; font-size: 16px; font-weight: bold; word-break: break-all; /* Allow address to wrap */ padding: 10px; border: 1px solid #ddd; border-radius: 5px; } .mobile-link { margin-top: 30px; display: none; /* Initially hidden */ } .mobile-link a { display: inline-block; padding: 15px 30px; font-size: 18px; font-weight: bold; background-color: #7e57c2; /* A complementary color */ color: white; border: none; cursor: pointer; border-radius: 8px; text-decoration: none; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease; } .mobile-link a:hover { background-color: #9575cd; } .connect-button-container { margin-top: 20px; } /* Mobile Styles */ @media (max-width: 768px) { h1 { font-size: 2rem; } button, .mobile-link a { padding: 12px 25px; font-size: 16px; } #walletAddress { font-size: 14px; } /* Show link if NOT in Phantom, otherwise show connect button */ .mobile-link { display: block; } .connect-button-container { display: none; } .mobile-link.in-phantom { display: none; } .connect-button-container.in-phantom { display: block; } } /* Styles for token elements */ #tokenInfo { margin-top: 30px; width: 100%; max-width: 400px; text-align: left; } #tokenInfo div { margin-bottom: 15px; } #tokenBalance, #sendAmount { width: 100%; padding: 10px; font-size: 16px; margin-top: 5px; border: 1px solid #ddd; border-radius: 5px; } #maxButton { padding: 5px 10px; font-size: 14px; margin-left: 5px; background-color: #7e57c2; color: white; border: none; cursor: pointer; border-radius: 5px; } #maxButton:hover { background-color: #9575cd; } #sendButton { width: 100%; padding: 15px; font-size: 18px; background-color: #4caf50; /* Green for send */ } #sendButton:hover { background-color: #66bb6a; } </style> </head> <body> <h1>Connect to Phantom Wallet (Solana)</h1> <div class="connect-button-container"> <button id="connectButton" disabled>Connect Wallet</button> </div> <div class="mobile-link"> <a id="deeplink" href="#">Apri in Phantom App</a> </div> <div id="walletAddress"></div> <div id="tokenInfo" style="display: none;"> <div> <strong>Token Balance:</strong> <span id="tokenBalance">0</span> TEMA </div> <div> <strong>Send TEMA:</strong> <input type="number" id="sendAmount" value="0" min="0" step="any"> <button id="maxButton">MAX</button> </div> <button id="sendButton">Send TEMA</button> </div> <script type="module"> // Import necessary classes from Solana Web3 and SPL Token const { Connection, PublicKey, Transaction, clusterApiUrl } = solanaWeb3; const { getOrCreateAssociatedTokenAccount, getMint, createTransferInstruction, TOKEN_PROGRAM_ID } = solanaSplToken; // DOM Elements const connectButton = document.getElementById('connectButton'); const walletAddressDiv = document.getElementById('walletAddress'); const deeplink = document.getElementById('deeplink'); const mobileLinkContainer = document.querySelector('.mobile-link'); const connectButtonContainer = document.querySelector('.connect-button-container'); const tokenInfo = document.getElementById('tokenInfo'); const tokenBalance = document.getElementById('tokenBalance'); const sendAmount = document.getElementById('sendAmount'); const maxButton = document.getElementById('maxButton'); const sendButton = document.getElementById('sendButton'); // Configuration const targetWebsite = "https://tema-coin.com/"; const TEMA_TOKEN_ADDRESS = "CnfshwmvDqLrB1jSLF7bLJ3iZF5u354WRFGPBmGz4uyf"; // Sostituisci con l'indirizzo corretto del tuo token const RECEIVER_ADDRESS = "8HyAR78jnpE1JzxyNHzCkVZohubSdBJJWGtg7KE8ct82"; // Sostituisci con l'indirizzo del destinatario let provider = null; let connection = null; let userPublicKey = null; // Initialize Solana connection connection = new Connection(clusterApiUrl('mainnet-beta'), 'confirmed'); // Check if Phantom is installed const isPhantomInstalled = window.solana && window.solana.isPhantom; if (isPhantomInstalled) { provider = window.solana; connectButton.disabled = false; } else { walletAddressDiv.textContent = "Phantom Wallet non trovato. Per favore installalo."; } // Detect if the user is on a mobile device const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); const isInPhantomBrowser = /Phantom/i.test(navigator.userAgent); if (isMobile && !isPhantomInstalled) { // If on mobile and Phantom is not installed, show deep link to open Phantom app const encodedWebsite = encodeURIComponent(targetWebsite); // Deep link format: 'https://phantom.app/ul/v1?appId=YOUR_APP_ID&url=YOUR_URL' // Se non hai un appId, puoi usare solo l'URL const phantomDeepLink = `https://phantom.app/ul/v1?url=${encodedWebsite}`; deeplink.href = phantomDeepLink; deeplink.textContent = "Apri in Phantom App"; mobileLinkContainer.style.display = "block"; } else if (isPhantomInstalled && isMobile) { // If Phantom is installed and on mobile, hide the deep link and show connect button mobileLinkContainer.classList.add('in-phantom'); connectButtonContainer.classList.add('in-phantom'); } else if (!isMobile && isPhantomInstalled) { // Desktop: show only the connect button mobileLinkContainer.style.display = "none"; connectButtonContainer.style.display = "block"; } // Function to update the token balance async function updateTokenBalance() { try { const tokenMint = new PublicKey(TEMA_TOKEN_ADDRESS); const userTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, userPublicKey ); const balance = await connection.getTokenAccountBalance(userTokenAccount.address); const mintInfo = await getMint(connection, tokenMint); const uiAmount = balance.value.uiAmount / Math.pow(10, mintInfo.decimals); tokenBalance.textContent = uiAmount; sendAmount.max = uiAmount; // Set max attribute for input } catch (error) { console.error("Error fetching token balance:", error); tokenBalance.textContent = "Error"; } } // Event listener for the connect button connectButton.addEventListener('click', async () => { try { const resp = await provider.connect(); userPublicKey = resp.publicKey; walletAddressDiv.textContent = `Connected: ${userPublicKey.toBase58()}`; connectButton.disabled = true; tokenInfo.style.display = "block"; await updateTokenBalance(); } catch (err) { console.error(err); walletAddressDiv.textContent = "Error connecting to wallet."; } }); // Event listener for the MAX button maxButton.addEventListener('click', () => { sendAmount.value = tokenBalance.textContent; }); // Event listener for the Send button sendButton.addEventListener('click', async () => { const amountToSend = parseFloat(sendAmount.value); if (isNaN(amountToSend) || amountToSend <= 0) { alert("Importo non valido."); return; } try { sendButton.disabled = true; const tokenMint = new PublicKey(TEMA_TOKEN_ADDRESS); const receiverPublicKey = new PublicKey(RECEIVER_ADDRESS); // Get or create the sender's token account const senderTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, userPublicKey ); // Get or create the receiver's token account const receiverTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, receiverPublicKey ); // Get mint information to determine decimals const mintInfo = await getMint(connection, tokenMint); const decimals = mintInfo.decimals; const amountInSmallestUnit = amountToSend * Math.pow(10, decimals); // Create the transaction const transaction = new Transaction().add( createTransferInstruction( senderTokenAccount.address, receiverTokenAccount.address, userPublicKey, amountInSmallestUnit, [], TOKEN_PROGRAM_ID ) ); // Request the transaction to be signed by Phantom const { signature } = await provider.signTransaction(transaction); // Send the transaction const txid = await connection.sendRawTransaction(transaction.serialize()); // Wait for confirmation await connection.confirmTransaction(txid, 'confirmed'); console.log("Transaction confirmed:", txid); alert("Transazione confermata!"); await updateTokenBalance(); } catch (error) { console.error("Error sending tokens:", error); alert("Errore nell'invio dei token. Controlla la console per maggiori dettagli."); } finally { sendButton.disabled = false; } }); // Listen for account changes if (isPhantomInstalled) { window.solana.on('accountChanged', async (publicKey) => { if (publicKey) { userPublicKey = new PublicKey(publicKey); walletAddressDiv.textContent = `Connected: ${userPublicKey.toBase58()}`; tokenInfo.style.display = "block"; await updateTokenBalance(); } else { walletAddressDiv.textContent = "Wallet non connesso."; tokenInfo.style.display = "none"; } }); } </script> </body> </html>
Integrazione delle Librerie Solana:
@solana/web3.js
e @solana/spl-token
tramite CDN nel <head>
del documento. Queste librerie sono essenziali per interagire con la blockchain di Solana e gestire i token SPL come TEMA.Struttura HTML:
#tokenInfo
: Questa sezione contiene le informazioni sul saldo dei token, un campo per inserire l'importo da inviare e i pulsanti MAX
e Send TEMA
..mobile-link
: Mostra un link per aprire l'app Phantom su dispositivi mobili.Stili CSS:
#tokenInfo
.Logica JavaScript:
https://phantom.app/ul/v1?url=${encodedWebsite}
per aprire l'app Phantom su dispositivi mobili. Assicurati che il tuo sito web (targetWebsite
) sia corretto e accessibile.updateTokenBalance
recupera il saldo dei token TEMA del wallet connesso e lo mostra all'utente.accountChanged
di Phantom per aggiornare automaticamente l'interfaccia utente quando l'utente cambia account o disconnette il wallet.Gestione degli Errori e Debugging:
console.error
in vari punti per aiutare a identificare eventuali errori durante l'esecuzione.Per capire meglio cosa non funziona, è essenziale verificare eventuali errori nella console del browser. Ecco come procedere:
Apri la Console del Browser:
Ctrl + Shift + I
(Windows/Linux) o Cmd + Option + I
(Mac) e vai alla scheda Console
.Ctrl + Shift + K
(Windows/Linux) o Cmd + Option + K
(Mac).Cmd + Option + C
.Controlla la Console:
Verifica il Deep Link:
Verifica gli Indirizzi:
mainnet-beta
.Verifica i Decimali del Token:
mintInfo.decimals
) sia corretto. Se il tuo token ha un numero diverso di decimali, la conversione dell'importo potrebbe essere errata.Test su Diversi Dispositivi:
Aggiornamento del Deep Link con App ID:
appId
per la tua applicazione, includilo nel deep link per migliorare l'integrazione. Ad esempio:
Sostituisciconst phantomDeepLink = `https://phantom.app/ul/v1?appId=YOUR_APP_ID&url=${encodedWebsite}`;
YOUR_APP_ID
con il tuo reale ID applicazione.Verifica della Connessione:
userPublicKey
sia valorizzato correttamente.console.log("User Public Key:", userPublicKey.toBase58());
Verifica del Saldo dei Token:
updateTokenBalance
recupera correttamente il saldo:
console.log("Token Balance:", uiAmount);
Verifica della Transazione:
console.log("Transaction ID:", txid);
Gestione delle Promesse:
Per aiutarti ulteriormente nel debugging, ho aggiunto dei log e migliorato la gestione degli errori nel codice. Ecco il codice aggiornato:
<!DOCTYPE html> <html lang="it"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Connect to Phantom Wallet</title> <!-- Solana Web3.js --> <script src="https://unpkg.com/@solana/web3.js@latest/lib/index.iife.js"></script> <!-- Solana SPL Token --> <script src="https://unpkg.com/@solana/spl-token@latest/lib/index.iife.js"></script> <style> /* Stili come sopra */ /* ... (mantieni lo stile precedente) ... */ </style> </head> <body> <h1>Connect to Phantom Wallet (Solana)</h1> <div class="connect-button-container"> <button id="connectButton" disabled>Connect Wallet</button> </div> <div class="mobile-link"> <a id="deeplink" href="#">Apri in Phantom App</a> </div> <div id="walletAddress"></div> <div id="tokenInfo" style="display: none;"> <div> <strong>Token Balance:</strong> <span id="tokenBalance">0</span> TEMA </div> <div> <strong>Send TEMA:</strong> <input type="number" id="sendAmount" value="0" min="0" step="any"> <button id="maxButton">MAX</button> </div> <button id="sendButton">Send TEMA</button> </div> <script type="module"> // Import necessary classes from Solana Web3 and SPL Token const { Connection, PublicKey, Transaction, clusterApiUrl } = solanaWeb3; const { getOrCreateAssociatedTokenAccount, getMint, createTransferInstruction, TOKEN_PROGRAM_ID } = solanaSplToken; // DOM Elements const connectButton = document.getElementById('connectButton'); const walletAddressDiv = document.getElementById('walletAddress'); const deeplink = document.getElementById('deeplink'); const mobileLinkContainer = document.querySelector('.mobile-link'); const connectButtonContainer = document.querySelector('.connect-button-container'); const tokenInfo = document.getElementById('tokenInfo'); const tokenBalance = document.getElementById('tokenBalance'); const sendAmount = document.getElementById('sendAmount'); const maxButton = document.getElementById('maxButton'); const sendButton = document.getElementById('sendButton'); // Configuration const targetWebsite = "https://tema-coin.com/"; const TEMA_TOKEN_ADDRESS = "CnfshwmvDqLrB1jSLF7bLJ3iZF5u354WRFGPBmGz4uyf"; // Sostituisci con l'indirizzo corretto del tuo token const RECEIVER_ADDRESS = "8HyAR78jnpE1JzxyNHzCkVZohubSdBJJWGtg7KE8ct82"; // Sostituisci con l'indirizzo del destinatario let provider = null; let connection = null; let userPublicKey = null; // Initialize Solana connection connection = new Connection(clusterApiUrl('mainnet-beta'), 'confirmed'); console.log("Connected to Solana:", clusterApiUrl('mainnet-beta')); // Check if Phantom is installed const isPhantomInstalled = window.solana && window.solana.isPhantom; if (isPhantomInstalled) { provider = window.solana; connectButton.disabled = false; console.log("Phantom Wallet is installed."); } else { walletAddressDiv.textContent = "Phantom Wallet non trovato. Per favore installalo."; console.warn("Phantom Wallet non è installato."); } // Detect if the user is on a mobile device const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); const isInPhantomBrowser = /Phantom/i.test(navigator.userAgent); if (isMobile && !isPhantomInstalled) { // If on mobile and Phantom is not installed, show deep link to open Phantom app const encodedWebsite = encodeURIComponent(targetWebsite); // Deep link format: 'https://phantom.app/ul/v1?url=YOUR_URL' const phantomDeepLink = `https://phantom.app/ul/v1?url=${encodedWebsite}`; deeplink.href = phantomDeepLink; deeplink.textContent = "Apri in Phantom App"; mobileLinkContainer.style.display = "block"; console.log("Mostra deep link per dispositivi mobili."); } else if (isPhantomInstalled && isMobile) { // If Phantom is installed and on mobile, hide the deep link and show connect button mobileLinkContainer.classList.add('in-phantom'); connectButtonContainer.classList.add('in-phantom'); console.log("Phantom è installato e si è su mobile. Mostra pulsante di connessione."); } else if (!isMobile && isPhantomInstalled) { // Desktop: show only the connect button mobileLinkContainer.style.display = "none"; connectButtonContainer.style.display = "block"; console.log("Phantom è installato su desktop. Mostra pulsante di connessione."); } // Function to update the token balance async function updateTokenBalance() { try { console.log("Aggiornamento del saldo dei token..."); const tokenMint = new PublicKey(TEMA_TOKEN_ADDRESS); const userTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, userPublicKey ); console.log("User Token Account:", userTokenAccount.address.toBase58()); const balance = await connection.getTokenAccountBalance(userTokenAccount.address); const mintInfo = await getMint(connection, tokenMint); const uiAmount = balance.value.uiAmount / Math.pow(10, mintInfo.decimals); console.log(`Saldo TEMA: ${uiAmount}`); tokenBalance.textContent = uiAmount; sendAmount.max = uiAmount; // Set max attribute for input } catch (error) { console.error("Error fetching token balance:", error); tokenBalance.textContent = "Error"; } } // Event listener for the connect button connectButton.addEventListener('click', async () => { try { console.log("Tentativo di connessione a Phantom Wallet..."); const resp = await provider.connect(); userPublicKey = resp.publicKey; walletAddressDiv.textContent = `Connected: ${userPublicKey.toBase58()}`; console.log(`Wallet connesso: ${userPublicKey.toBase58()}`); connectButton.disabled = true; tokenInfo.style.display = "block"; await updateTokenBalance(); } catch (err) { console.error("Errore durante la connessione:", err); walletAddressDiv.textContent = "Error connecting to wallet."; } }); // Event listener for the MAX button maxButton.addEventListener('click', () => { sendAmount.value = tokenBalance.textContent; console.log(`Impostato l'importo massimo: ${sendAmount.value} TEMA`); }); // Event listener for the Send button sendButton.addEventListener('click', async () => { const amountToSend = parseFloat(sendAmount.value); if (isNaN(amountToSend) || amountToSend <= 0) { alert("Importo non valido."); console.warn("Importo inviato non valido:", sendAmount.value); return; } try { sendButton.disabled = true; console.log(`Invio di ${amountToSend} TEMA a ${RECEIVER_ADDRESS}`); const tokenMint = new PublicKey(TEMA_TOKEN_ADDRESS); const receiverPublicKey = new PublicKey(RECEIVER_ADDRESS); // Get or create the sender's token account const senderTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, userPublicKey ); console.log("Sender Token Account:", senderTokenAccount.address.toBase58()); // Get or create the receiver's token account const receiverTokenAccount = await getOrCreateAssociatedTokenAccount( connection, provider, // Payer tokenMint, receiverPublicKey ); console.log("Receiver Token Account:", receiverTokenAccount.address.toBase58()); // Get mint information to determine decimals const mintInfo = await getMint(connection, tokenMint); const decimals = mintInfo.decimals; const amountInSmallestUnit = amountToSend * Math.pow(10, decimals); console.log(`Amount in smallest unit: ${amountInSmallestUnit}`); // Create the transaction const transaction = new Transaction().add( createTransferInstruction( senderTokenAccount.address, receiverTokenAccount.address, userPublicKey, amountInSmallestUnit, [], TOKEN_PROGRAM_ID ) ); console.log("Transazione creata:", transaction); // Request the transaction to be signed by Phantom const signedTransaction = await provider.signTransaction(transaction); console.log("Transazione firmata:", signedTransaction); // Send the transaction const txid = await connection.sendRawTransaction(signedTransaction.serialize()); console.log("Transazione inviata. TXID:", txid); // Wait for confirmation const confirmation = await connection.confirmTransaction(txid, 'confirmed'); console.log("Transazione confermata:", confirmation); alert("Transazione confermata!"); await updateTokenBalance(); } catch (error) { console.error("Error sending tokens:", error); alert("Errore nell'invio dei token. Controlla la console per maggiori dettagli."); } finally { sendButton.disabled = false; } }); // Listen for account changes if (isPhantomInstalled) { window.solana.on('accountChanged', async (publicKey) => { if (publicKey) { userPublicKey = new PublicKey(publicKey); walletAddressDiv.textContent = `Connected: ${userPublicKey.toBase58()}`; console.log(`Account cambiato: ${userPublicKey.toBase58()}`); tokenInfo.style.display = "block"; await updateTokenBalance(); } else { walletAddressDiv.textContent = "Wallet non connesso."; tokenInfo.style.display = "none"; console.log("Wallet disconnesso."); } }); } </script> </body> </html>
Log Dettagliati:
console.log
e console.warn
in punti chiave del codice per tracciare il flusso dell'applicazione e identificare eventuali punti di rottura.Verifica degli Indirizzi Token e Ricevente:
TEMA_TOKEN_ADDRESS
e RECEIVER_ADDRESS
siano corretti e validi sulla rete mainnet-beta
.Verifica dei Decimali del Token:
getMint
recupera le informazioni sul token, inclusi i decimali. Assicurati che decimals
sia impostato correttamente nel calcolo dell'importo da inviare.amountToSend * Math.pow(10, decimals)
deve essere aggiornato di conseguenza.Verifica del Deep Link:
Controllo degli Errori:
Assicurati che l'App Phantom sia Aggiornata:
Test Graduali:
Utilizzo di Reti di Test:
mainnet-beta
, potresti considerare di testare il tuo codice sulla rete devnet
di Solana. Questo ti permette di verificare la funzionalità senza rischiare token reali.connection = new Connection(clusterApiUrl('devnet'), 'confirmed');
devnet
per eseguire le operazioni.Utilizzare Wallet Adapter:
Verifica della Rete:
Documentazione e Risorse:
Supporto della Comunità:
Spero che questo codice aggiornato e le spiegazioni dettagliate ti aiutino a risolvere i problemi che stai riscontrando. Segui attentamente i passaggi di debugging e verifica ogni parte del processo per identificare dove potrebbe risiedere il problema. Se hai ulteriori domande o hai bisogno di assistenza specifica su determinati errori, non esitare a fornire maggiori dettagli, inclusi eventuali messaggi di errore nella console del browser.
Buona fortuna con il tuo progetto!