Búsqueda de sitios web

typescript - ¿Cómo puedo validar una dirección de billetera de Solana con web3js?


Estoy intentando validar que el texto de entrada que recibo de un usuario sea una dirección de Solana válida.

Según la documentación de web3.js, el método .isOnCurve() hace eso:

https://solana-labs.github.io/solana-web3.js/classes/PublicKey.html#isOnCurve

He logrado hacerlo funcionar con este código:

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')
  }
}

Pero cuando paso let pubkey=new PublicKey(address) una cadena que no es similar a una dirección de Solana, lanza la excepción Error: Invalid public key input (PublicKey espera un PublicKeyInitData: number | string | Buffer | Uint8Array | number[] | PublicKeyData)

Es por eso que tuve que ponerlo en un bloque try-catch.

¿Hay alguna otra manera (mejor) de lograr esto? Se ve feo...

Respuesta #1

PublicKey.isOnCurve() devuelve true solo si la dirección está en la curva ed25519; tales direcciones se generan a partir de Keypair y devuelve false para direcciones fuera de la curva, como las direcciones derivadas de PublicKey.findProgramAddress(), aunque pueden ser claves públicas válidas.

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

Respuesta #2

Para validar que una clave pública de Solana puede ser una dirección de cartera, debes usar tanto isOnCurve() como el constructor PublicKey tal como lo estás haciendo.

El error que se produce tiene sentido. Si la dirección no es una clave pública, no debería poder ser instanciada.

Quizás en el futuro podría crearse otra función nativa en @solana/web3.js que se encargue de validar las direcciones de las billeteras por ti.

Artículos relacionados