@nucypher/shared
Version:
## [`nucypher/taco-web`](../../README.md)
142 lines • 5.32 kB
JavaScript
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