Verifica indirizzo

Inviare fondi a un indirizzo errato può comportare una perdita permanente. La verifica dell'indirizzo garantisce che tu e i tuoi utenti inviate solo a indirizzi in grado di ricevere e accedere correttamente ai fondi. Se gestisci un exchange, si consiglia di eseguire questi controlli e di far verificare l'indirizzo all'utente prima dell'invio.

La validazione dipende da ciò che si invia:

  • I token SPL sono in parte auto-protetti. Il Token Program rifiuta un trasferimento i cui account non corrispondono al mint previsto, quindi un trasferimento di token indirizzato erroneamente fallisce senza perdita di fondi. La maggior parte di questa pagina riguarda l'invio di token SPL.
  • SOL nativo non dispone di tale protezione. Un trasferimento tramite System Program ha successo in qualsiasi account, quindi un destinatario errato blocca permanentemente i SOL. Vedi Invio di SOL nativo.

Vedi Come funzionano i pagamenti su Solana per i concetti fondamentali sui pagamenti.

Comprendere gli indirizzi Solana

Gli account Solana hanno due tipi di indirizzi: on-curve e off-curve.

Indirizzi On-Curve

Gli indirizzi standard sono le chiavi pubbliche dei keypair Ed25519. Questi indirizzi:

  • Hanno una chiave privata corrispondente in grado di firmare le transazioni
  • Vengono utilizzati come indirizzi di wallet

Indirizzi Off-Curve (PDA)

I Program Derived Address sono derivati deterministicamente da un ID di programma e da seed. Questi indirizzi:

  • Non hanno una chiave privata corrispondente
  • Possono essere firmati solo dal programma da cui l'indirizzo è stato derivato

I wallet controllati da programmi, comunemente noti come smart wallet o smart account, hanno indirizzi off-curve. Questa guida utilizza il termine "smart wallet" in tutto il documento.

Tipi di account nei pagamenti

Usa l'indirizzo per recuperare un account dalla rete, controlla il proprietario del programma e il tipo di account per determinare come gestire l'indirizzo.

Sapere se un indirizzo è on-curve o off-curve non indica il tipo di account, il programma che lo possiede, né se esiste un account a quell'indirizzo. È necessario recuperare l'account dalla rete per determinare questi dettagli.

System Program Accounts (Portafogli)

Gli account di proprietà del System Program sono portafogli standard. Per inviare token SPL a un portafoglio, è necessario derivare e utilizzare il suo Associated Token Account (ATA).

Dopo aver derivato l'indirizzo ATA, verifica se il token account esiste onchain. Se l'ATA non esiste, puoi includere un'istruzione per creare il token account del destinatario nella stessa transazione del trasferimento. Tuttavia, questo richiede il pagamento del rent per il nuovo token account. Poiché il destinatario è il proprietario dell'ATA, il SOL pagato per il rent non può essere recuperato dal mittente.

Gli account di sistema possono esistere off-curve. Se il tuo utente desidera inviare token a un indirizzo off-curve, si consiglia di invitare l'utente a verificare che intenda davvero inviare fondi a uno smart wallet.

Senza adeguate misure di sicurezza, il finanziamento della creazione degli ATA può essere sfruttato a scopo malevolo. Un utente malintenzionato potrebbe richiedere un trasferimento, far creare il proprio ATA a tue spese, chiudere l'ATA per recuperare il rent SOL e ripetere l'operazione.

Token Accounts

I token account sono di proprietà del Token Program o del Token-2022 Program e contengono i saldi dei token. Se l'indirizzo che ricevi è di proprietà di un token program, dovresti verificare che l'account sia un token account (e non un mint account) e che corrisponda al mint account del token atteso prima di procedere all'invio.

I Token Programs verificano automaticamente che entrambi i token account coinvolti in un trasferimento contengano token dello stesso mint. Se la verifica fallisce, la transazione viene rifiutata e nessun fondo viene perso.

Mint Accounts

I mint account tracciano la fornitura di token e i metadati di un token specifico. I mint account sono anch'essi di proprietà dei Token Program, ma non sono destinatari validi per i trasferimenti di token. Il tentativo di inviare token a un indirizzo mint comporta il fallimento della transazione, ma nessun fondo viene perso.

Altri Account

Gli account di proprietà di altri programmi sono validi, ma sono regolati dalle regole di autorità stabilite dal rispettivo programma proprietario. Si consiglia di invitare l'utente a verificare che intenda inviare fondi a uno smart wallet.

Invio di SOL nativo

La classificazione sopra indicata determina dove possono essere inviati i token SPL. Il SOL nativo è più restrittivo: l'unico destinatario sicuro è un portafoglio System Program (o un indirizzo non finanziato sulla curva che ne diventa uno).

Un trasferimento tramite System Program aggiunge lamport a qualsiasi account, inclusi mint, token account, program account e PDA. I lamport possono essere prelevati solo dal programma proprietario dell'account, quindi inviare SOL a un destinatario errato può comportare la perdita permanente dei fondi.

A differenza di un trasferimento di token SPL, la transazione non fallisce quando il destinatario è un indirizzo inatteso.

Quando si invia SOL nativo, è accettabile solo un risultato IS_WALLET. IS_TOKEN_ACCOUNT non lo è: un token account contiene token SPL e il SOL inviato lì è fuori dal controllo del mittente.

Questo è un modo comune in cui il SOL viene perso: un utente incolla l'indirizzo mint di un token (o un indirizzo di programma) in un prelievo SOL. Il trasferimento va a buon fine e il SOL è irrecuperabile. Classificare sempre il destinatario prima di firmare un trasferimento SOL.

Flusso di Verifica

Il diagramma seguente mostra un albero decisionale di riferimento per la validazione di un indirizzo:

Address Verification Flow

Recupera account

Utilizza l'indirizzo per recuperare i dettagli dell'account dalla rete.

Account inesistente

Se non esiste alcun account a questo indirizzo, verifica se l'indirizzo è on-curve o off-curve:

  • Off-curve (PDA): Richiedi una verifica esplicita del destinatario prima di creare un ATA o inviare token SPL. In assenza di un account esistente, non è possibile determinare dall'indirizzo soltanto quale programma ha derivato questo PDA o se il programma del destinatario può accedere al suo ATA.

  • On-curve: Si tratta di un indirizzo wallet valido (chiave pubblica) che non è ancora stato finanziato. Deriva l'ATA, verifica se esiste e invia i token. Devi prendere una decisione di policy se finanziare la creazione dell'ATA qualora non esistesse.

Account esistente

Se esiste un account, verifica quale programma ne è proprietario:

  • System Program: Si tratta di un wallet standard. Deriva l'ATA, verifica se esiste e invia i token. Devi prendere una decisione di policy se finanziare la creazione dell'ATA qualora non esistesse.

  • Token Program / Token-2022: Verifica che l'account sia un token account (non un mint account) e che contenga il token (mint) che intendi inviare. Se valido, invia i token direttamente a questo indirizzo. Se si tratta di un mint account o di un token account per un mint diverso, rifiuta l'indirizzo.

  • Altro Programma: Programmi come i wallet multisig sono proprietari accettabili di token account. Richiedi all'utente di confermare che intende inviare a uno smart wallet.

    Alcuni smart wallet comuni:

Demo

L'esempio seguente mostra solo la logica di validazione dell'indirizzo. Si tratta di codice di riferimento a scopo illustrativo.

La demo non mostra come derivare un ATA o costruire una transazione per inviare token. Consulta la documentazione sul token account e sul trasferimento di token per esempi di codice.

La demo seguente utilizza tre possibili risultati:

RisultatoSignificatoAzione
IS_WALLETIndirizzo wallet validoDeriva e invia all'associated token account
IS_TOKEN_ACCOUNTToken account validoInvia i token direttamente a questo indirizzo
USER_VERIFICATIONL'indirizzo richiede la conferma del destinatarioRichiedi una revisione esplicita prima di inviare token SPL o finanziare un ATA
REJECTIndirizzo non validoNon inviare

Mappa quindi ogni risultato all'accettabilità per singolo asset con canReceiveNativeSol (solo wallet) e canReceiveSplToken (wallet o token account). Un risultato USER_VERIFICATION non viene accettato automaticamente; la tua applicazione dovrebbe far confermare all'utente le proprie intenzioni prima di inviare token SPL. Un token account restituisce IS_TOKEN_ACCOUNT, quindi può ricevere token SPL ma non SOL nativo — la distinzione che impedisce che SOL venga bloccato.

Demo
/**
* Validates an input address and classifies it as a wallet, token account,
* address requiring recipient verification, or invalid.
*
* @param inputAddress - The address to validate
* @param rpc - Optional RPC client (defaults to mainnet)
* @returns Classification result:
* - IS_WALLET: Valid wallet address
* - IS_TOKEN_ACCOUNT: Valid token account
* - USER_VERIFICATION: Require explicit review before sending SPL tokens
* - REJECT: Invalid address for transfers
*/
export async function validateAddress(
inputAddress: Address,
rpc: Rpc<GetAccountInfoApi> = defaultRpc
): Promise<ValidationResult> {
const account = await fetchJsonParsedAccount(rpc, inputAddress);
// Log the account data for demo
console.log("\nAccount:", account);
// Account doesn't exist onchain
if (!account.exists) {
// An unfunded PDA may belong to a smart wallet, but the address
// alone cannot prove that its program can access a newly-created ATA.
if (isOffCurveAddress(inputAddress)) {
return {
type: "USER_VERIFICATION",
reason:
"Unfunded PDA: confirm the recipient is using a smart wallet and controls this address"
};
}
// On-curve = valid keypair address, treat as unfunded wallet
return { type: "IS_WALLET" };
}
// Account exists, check program owner
const owner = account.programAddress;
// A System Program account can be a standard wallet or an off-curve smart
// wallet. Require verification before automatically sending to the
// latter.
if (owner === SYSTEM_PROGRAM) {
if (isOffCurveAddress(inputAddress)) {
return {
type: "USER_VERIFICATION",
reason:
"Off-curve System Program account: confirm recipient is using a smart wallet"
};
}
return { type: "IS_WALLET" };
}
// Token Program or Token-2022, check if token account
if (owner === TOKEN_PROGRAM || owner === TOKEN_2022_PROGRAM) {
const accountType = (
account.data as { parsedAccountMeta?: { type?: string } }
).parsedAccountMeta?.type;
if (accountType === "account") {
return { type: "IS_TOKEN_ACCOUNT" };
}
// Reject if not a token account (mint account)
return {
type: "REJECT",
reason: "Not a token account"
};
}
// An account owned by another program can be a smart wallet.
return {
type: "USER_VERIFICATION",
reason:
"Program-owned account: confirm the recipient is using a smart wallet"
};
}
/**
* Native SOL is only safe to send to a wallet. Any other account locks it.
*/
function canReceiveNativeSol(result: ValidationResult): boolean {
return result.type === "IS_WALLET";
}
/**
* SPL tokens can go to a wallet (via its ATA) or directly to a token account.
*/
function canReceiveSplToken(result: ValidationResult): boolean {
return result.type === "IS_WALLET" || result.type === "IS_TOKEN_ACCOUNT";
}
// =============================================================================
// Examples
// =============================================================================
Console
Click to execute the code.

Is this page helpful?

Indice dei contenuti

Modifica pagina
© 2026 Solana Foundation. Tutti i diritti riservati.