UNPKG

@stacks/auth

Version:

Authentication for Stacks apps.

82 lines (75 loc) 2.76 kB
import { NetworkClientParam, clientFromNetwork, networkFrom } from '@stacks/network'; import { resolveZoneFileToProfile } from '@stacks/profile'; export interface ProfileLookupOptions { username: string; zoneFileLookupURL?: string; } /** * Look up a user profile by blockstack ID * * @param {string} username - The Blockstack ID of the profile to look up * @param {string} [zoneFileLookupURL=null] - The URL * to use for zonefile lookup. If falsey, lookupProfile will use the * blockstack.js [[getNameInfo]] function. * @returns {Promise} that resolves to a profile object */ export function lookupProfile( options: ProfileLookupOptions & NetworkClientParam ): Promise<Record<string, any>> { if (!options.username) { return Promise.reject(new Error('No username provided')); } const network = networkFrom(options.network ?? 'mainnet'); const client = Object.assign({}, clientFromNetwork(network), options.client); let lookupPromise; if (options.zoneFileLookupURL) { const url = `${options.zoneFileLookupURL.replace(/\/$/, '')}/${options.username}`; lookupPromise = client.fetch(url).then(response => response.json()); } else { lookupPromise = getNameInfo({ name: options.username }); } return lookupPromise.then((responseJSON: any) => { if (responseJSON.hasOwnProperty('zonefile') && responseJSON.hasOwnProperty('address')) { return resolveZoneFileToProfile({ zoneFile: responseJSON.zonefile, publicKeyOrAddress: responseJSON.address, client, }); } else { throw new Error( 'Invalid zonefile lookup response: did not contain `address`' + ' or `zonefile` field' ); } }); } export function getNameInfo( opts: { /** Fully qualified name */ name: string; } & NetworkClientParam ) { const network = networkFrom(opts.network ?? 'mainnet'); const client = Object.assign({}, clientFromNetwork(network), opts.client); const nameLookupURL = `${client.baseUrl}/v1/names/${opts.name}`; return client .fetch(nameLookupURL) .then((resp: any) => { if (resp.status === 404) { throw new Error('Name not found'); } else if (resp.status !== 200) { throw new Error(`Bad response status: ${resp.status}`); } else { return resp.json(); } }) .then((nameInfo: any) => { // the returned address _should_ be in the correct network --- // stacks node gets into trouble because it tries to coerce back to mainnet // and the regtest transaction generation libraries want to use testnet addresses if (nameInfo.address) { return Object.assign({}, nameInfo, { address: nameInfo.address }); } else { return nameInfo; } }); }