UNPKG

@nucypher/shared

Version:

## [`nucypher/taco-web`](../../README.md)

142 lines 5.32 kB
import { CapsuleFrag, EncryptedThresholdDecryptionResponse, PublicKey, } from '@nucypher/nucypher-core'; import axios, { HttpStatusCode, } from 'axios'; import qs from 'qs'; import { fromBase64, fromHexString, toBase64, toHexString } from './utils'; const defaultPorterUri = { mainnet: 'https://porter.nucypher.io', tapir: 'https://porter-tapir.nucypher.io', lynx: 'https://porter-lynx.nucypher.io', }; const porterUriSource = 'https://raw.githubusercontent.com/nucypher/nucypher-porter/main/porter_instances.json'; export const domains = { DEVNET: 'lynx', TESTNET: 'tapir', MAINNET: 'mainnet', }; export const getPorterUri = async (domain) => { return (await getPorterUris(domain))[0]; }; export const getPorterUris = async (domain) => { const fullList = []; const uri = defaultPorterUri[domain]; if (!uri) { throw new Error(`No default Porter URI found for domain: ${domain}`); } fullList.push(uri); const urisFromSource = await getPorterUrisFromSource(domain); fullList.push(...urisFromSource); return fullList; }; export const getPorterUrisFromSource = async (domain) => { const source = porterUriSource; if (!source) { return []; } try { const resp = await axios.get(porterUriSource, { responseType: 'blob', }); const uris = JSON.parse(resp.data); return uris[domain]; } catch (e) { return []; } }; export class PorterClient { porterUrls; constructor(porterUris) { if (porterUris instanceof Array) { this.porterUrls = porterUris.map((uri) => new URL(uri)); } else { this.porterUrls = [new URL(porterUris)]; } } async tryAndCall(config) { let resp; let lastError = undefined; for (const porterUrl of this.porterUrls) { const localConfig = { ...config, baseURL: porterUrl.toString() }; try { resp = await axios.request(localConfig); if (resp.status === HttpStatusCode.Ok) { return resp; } } catch (e) { lastError = e; continue; } } if (lastError) { throw lastError; } throw new Error(`Porter returned bad response: ${resp.status} - ${resp.data}`); } async getUrsulas(quantity, excludeUrsulas = [], includeUrsulas = []) { const params = { quantity, exclude_ursulas: excludeUrsulas, include_ursulas: includeUrsulas, }; const resp = await this.tryAndCall({ url: '/get_ursulas', method: 'get', params: params, paramsSerializer: (params) => { return qs.stringify(params, { arrayFormat: 'comma' }); }, }); return resp.data.result.ursulas.map((u) => ({ checksumAddress: u.checksum_address, uri: u.uri, encryptingKey: PublicKey.fromCompressedBytes(fromHexString(u.encrypting_key)), })); } async retrieveCFrags(treasureMap, retrievalKits, aliceVerifyingKey, bobEncryptingKey, bobVerifyingKey, conditionContextJSON = undefined) { const data = { treasure_map: toBase64(treasureMap.toBytes()), retrieval_kits: retrievalKits.map((rk) => toBase64(rk.toBytes())), alice_verifying_key: toHexString(aliceVerifyingKey.toCompressedBytes()), bob_encrypting_key: toHexString(bobEncryptingKey.toCompressedBytes()), bob_verifying_key: toHexString(bobVerifyingKey.toCompressedBytes()), context: conditionContextJSON, }; const resp = await this.tryAndCall({ url: '/retrieve_cfrags', method: 'post', data: data, }); return resp.data.result.retrieval_results.map(({ cfrags, errors }) => { const parsed = Object.keys(cfrags).map((address) => [ address, CapsuleFrag.fromBytes(fromBase64(cfrags[address])), ]); const cFrags = Object.fromEntries(parsed); return { cFrags, errors }; }); } async tacoDecrypt(encryptedRequests, threshold) { const data = { encrypted_decryption_requests: Object.fromEntries(Object.entries(encryptedRequests).map(([ursula, encryptedRequest]) => [ ursula, toBase64(encryptedRequest.toBytes()), ])), threshold, }; const resp = await this.tryAndCall({ url: '/decrypt', method: 'post', data: data, }); const { encrypted_decryption_responses, errors } = resp.data.result.decryption_results; const decryptionResponses = Object.entries(encrypted_decryption_responses).map(([address, encryptedResponseBase64]) => { const encryptedResponse = EncryptedThresholdDecryptionResponse.fromBytes(fromBase64(encryptedResponseBase64)); return [address, encryptedResponse]; }); const encryptedResponses = Object.fromEntries(decryptionResponses); return { encryptedResponses, errors }; } } //# sourceMappingURL=porter.js.map