import { AccountID , ChainID } from 'caip' ; import { RemoteSigner } from '@taquito/remote-signer' ; import { BlockchainHandler } from '../blockchain-handler' ; import { LinkProof , tezos } from '@ceramicnetwork/blockchain-utils-linking' ; import fetch from 'cross-fetch' ; import * as uint8arrays from 'uint8arrays' ; export const ADDRESS_NOT_FOUND_ERROR = new Error ( `Address not found on the Tezos blockchain` ) ; export const PUBLIC_KEY_NOT_PUBLISHED_ERROR = new Error ( `Public key not published to the Tezos blockchain` ) ; const { TEZOS_NAMESPACE , TEZOS_CHAIN_REF } = tezos ; const FAKE_API_ENDPOINT = 'https://fake-api.example.com' ; param { string } text returns { string } function encodeMessage ( text ) { const michelinePrefix = '05' ; const stringPrefix = '01' ; const len = ( '0000000' + text . length . toString ( 16 ) ) . slice ( - 8 ) ; text = uint8arrays . toString ( uint8arrays . fromString ( text , 'utf-8' ) , 'hex' ) ; return michelinePrefix + stringPrefix + len + text ; } param { string } address returns { ( ) => Promise < string > } throws throws function publicKeyFinder ( address ) { const request = fetch ( `https://api.tzstats.com/explorer/account/${ address }` ) . catch ( ( e ) => { throw ADDRESS_NOT_FOUND_ERROR ; } ) ; return async ( ) : Promise < string > => { const response = await request ; const json = await response . json ( ) ; const result = json ?. pubkey ; if ( result ) { return result ; } else { throw PUBLIC_KEY_NOT_PUBLISHED_ERROR ; } } ; } export async function validateLink ( proof ) { const account = AccountID . parse ( proof . account ) ; const chainId = new ChainID ( account . chainId ) ; if ( chainId . reference !== TEZOS_CHAIN_REF ) { return null ; } const msg = encodeMessage ( proof . message ) ; const verifier = new RemoteSigner ( account . address , FAKE_API_ENDPOINT ) ; verifier . publicKey = publicKeyFinder ( account . address ) ; try { const is_sig_valid = await verifier . verify ( msg , proof . signature ) ; return is_sig_valid ? proof : null ; } catch ( ignored ) { return null ; } } const Handler = { namespace : TEZOS_NAMESPACE , validateLink , } ; export default Handler ;