如何使用 web3js 验证 Solana 钱包地址?

问题描述 投票:0回答:6

我正在尝试验证从用户那里获得的输入文本是否是有效的 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 块中。

还有其他(更好)的方法来实现这一目标吗?看起来很丑...

typescript web3js solana
6个回答
8
投票
仅当地址位于

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

4
投票

要验证 Solana 公钥可能是钱包地址,您应该像您一样使用

isOnCurve()
PublicKey
构造函数。

抛出的错误是有道理的。如果地址不是公钥,则应该无法实例化。

也许 @solana/web3.js 可能有另一个原生功能,可以在将来为您验证钱包地址。


2
投票

您不必仅使用连接来验证钱包地址。最小的工作示例应该是这样的:

import { PublicKey } from '@solana/web3.js'

const address = new PublicKey("8B9wLUXGFQQJ6VpzhDMpmHxByAvQBXhwSsZUwjLz971x");
console.log(PublicKey.isOnCurve(address));

1
投票

我正在尝试做同样的事情(验证 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


    


1
投票

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; } };
    

0
投票
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}!` );
    
© www.soinside.com 2019 - 2024. All rights reserved.