'How can I validate a Solana wallet address with web3js?
I'm trying to validate that the input text I get from a user is a valid Solana address.
According to the web3.js documentation, the method .isOnCurve() does that:
https://solana-labs.github.io/solana-web3.js/classes/PublicKey.html#isOnCurve
I've managed to make it work with this code:
import {PublicKey} from '@solana/web3.js'
function validateSolAddress(address:string){
try {
let pubkey = new PublicKey(address)
let isSolana = PublicKey.isOnCurve(pubkey.toBuffer())
return isSolana
} catch (error) {
return false
}
}
function modalSubmit(modal: any){
const firstResponse = modal.getTextInputValue(walletQuestFields.modal.componentsList[0].id)
let isSolAddress = validateSolAddress(firstResponse)
if (isSolAddress) {
console.log('The address is valid')
}else{
console.log('The address is NOT valid')
}
}
But when I pass let pubkey = new PublicKey(address) a string that is not similar to a solana address, it throws the exception Error: Invalid public key input (PublikKey expects a PublicKeyInitData: number | string | Buffer | Uint8Array | number[] | PublicKeyData)
That is why I had to out it into a try-catch block.
Is there any other (better) way to achieve this? It looks ugly...
Solution 1:[1]
To validate a Solana public key may be a wallet address, you should both use isOnCurve() and the PublicKey constructor like you are doing.
The error thrown makes sense. If the address is not a public key, it should not be able to be instantiated.
Perhaps there could be another function made native to @solana/web3.js that takes care of validating wallet addresses for you in the future.
Solution 2:[2]
I'm trying to do the same (validate a solana wallet address) and works for me.
isOnCurve return true if the public key has a valid format, but I think this is not sufficient for verify a wallet address because I'm tested some public keys from devnet and mainnet-beta and ever return true (without care about the env) unless I used invalid key.
This is a public key from devnet, you can try with this to test:
8B9wLUXGFQQJ6VpzhDMpmHxByAvQBXhwSsZUwjLz971x
My code looks like:
var connection = new web3.Connection(
web3.clusterApiUrl('devote'),
'confirmed',
);
const publicKey = new web3.PublicKey("8B9wLUXGFQQJ6VpzhDMpmHxByAvQBXhwSsZUwjLz971x");
console.log(await web3.PublicKey.isOnCurve(publicKey))
Should print true
Solution 3:[3]
isOnCurve expects a Uint8Array format for publicKey argument. So you must do publicKey.toBytes() to get byte array representation of the publicKey.
const validateSolanaAddress = async (addr: string) => {
let publicKey: PublicKey;
try {
publicKey = new PublicKey(addr);
return await PublicKey.isOnCurve(publicKey.toBytes());
} catch (err) {
return false;
}
};
Solution 4:[4]
You don't have to use Connection only to validate wallet address. A minimum working example should be something like this:
import { PublicKey } from '@solana/web3.js'
const address = new PublicKey("8B9wLUXGFQQJ6VpzhDMpmHxByAvQBXhwSsZUwjLz971x");
console.log(PublicKey.isOnCurve(address));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jacob Creech |
| Solution 2 | Vicente Guerra Hernández |
| Solution 3 | Sanjay |
| Solution 4 | Tyler2P |
