我正在尝试验证从用户那里获得的输入文本是否是有效的 Solana 地址。
根据 web3.js 文档,方法 .isOnCurve() 可以做到这一点:
https://solana-labs.github.io/solana-web3.js/classes/PublicKey.html#isOnCurve
我已经设法让它与这段代码一起工作:
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')
}
}
但是当我传递
let pubkey = new PublicKey(address)
一个与solana地址不相似的字符串时,它会抛出异常Error: Invalid public key input
(PublikKey需要一个 PublicKeyInitData: number | string | Buffer | Uint8Array | number[] | PublicKeyData
)
这就是为什么我必须将其放入 try-catch 块中。
还有其他(更好)的方法来实现这一目标吗?看起来很丑...
PublicKey.isOnCurve()
上时,
ed25519 curve
才返回 true,此类地址是从 Keypair
生成的,并且对于偏离曲线的地址(例如来自 PublicKey.findProgramAddress()
的派生地址)返回 false,尽管它们可以是有效的公钥。
const owner = new PublicKey("DS2tt4BX7YwCw7yrDNwbAdnYrxjeCPeGJbHmZEYC8RTb");
console.log(PublicKey.isOnCurve(owner.toBytes())); // true
console.log(PublicKey.isOnCurve(owner.toString())); // true
const ownerPda = PublicKey.findProgramAddressSync(
[owner.toBuffer()],
new PublicKey("worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth"),
)[0];
console.log(PublicKey.isOnCurve(ownerPda.toString())); // false
console.log(PublicKey.isOnCurve([owner, 18])); // false
const RAY_MINT = new PublicKey("4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R");
console.log(PublicKey.isOnCurve(new PublicKey(RAY_MINT))); // true
console.log(PublicKey.isOnCurve("fasddfasevase")); // throws error
要验证 Solana 公钥可能是钱包地址,您应该像您一样使用
isOnCurve()
和 PublicKey
构造函数。
抛出的错误是有道理的。如果地址不是公钥,则应该无法实例化。
也许 @solana/web3.js 可能有另一个原生功能,可以在将来为您验证钱包地址。
您不必仅使用连接来验证钱包地址。最小的工作示例应该是这样的:
import { PublicKey } from '@solana/web3.js'
const address = new PublicKey("8B9wLUXGFQQJ6VpzhDMpmHxByAvQBXhwSsZUwjLz971x");
console.log(PublicKey.isOnCurve(address));
我正在尝试做同样的事情(验证 solana 钱包地址)并且对我有用。
如果公钥具有有效的格式,则 isOnCurve 返回 true,但我认为这不足以验证钱包地址,因为我测试了来自 devnet 和 mainnet-beta 的一些公钥并且曾经返回 true (不关心环境)除非我使用了无效的密钥。这是来自devnet的公钥,你可以尝试用它来测试:
8B9wLUXGFQQJ6VpzhDMpmHxByAvQBXhwSsZUwjLz971x
我的代码如下所示:
var connection = new web3.Connection(
web3.clusterApiUrl('devote'),
'confirmed',
);
const publicKey = new web3.PublicKey("8B9wLUXGFQQJ6VpzhDMpmHxByAvQBXhwSsZUwjLz971x");
console.log(await web3.PublicKey.isOnCurve(publicKey))
应该打印 true
isOnCurve
需要
Uint8Array
格式的 publicKey 参数。因此,您必须执行
publicKey.toBytes()
才能获取公钥的字节数组表示形式。
const validateSolanaAddress = async (addr: string) => {
let publicKey: PublicKey;
try {
publicKey = new PublicKey(addr);
return await PublicKey.isOnCurve(publicKey.toBytes());
} catch (err) {
return false;
}
};
import { Connection, LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js";
const suppliedPublicKey = process.argv[2];
if (!suppliedPublicKey) {
throw new Error("Provide a public key to check the balance of!");
} else {
console.log(PublicKey.isOnCurve(suppliedPublicKey));
}
const connection = new Connection("https://api.mainnet.solana.com", "confirmed");
const publicKey = new PublicKey(suppliedPublicKey);
const balanceInLamports = await connection.getBalance(publicKey);
const balanceInSOL = balanceInLamports / LAMPORTS_PER_SOL;
console.log(
`✅ Finished! The balance for the wallet at address ${publicKey} is ${balanceInSOL}!`
);