From 77a0fbb89b6fae297935109553d7131b538f5a13 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Fri, 30 Jun 2023 13:15:54 +0200 Subject: [PATCH 01/17] feat! add ritual initialization --- src/agents/coordinator.ts | 72 +++++++++++++++++-- src/characters/cbd-recipient.ts | 6 +- src/dkg.ts | 115 ++++++++++++++++++++++++------- src/sdk/strategy/cbd-strategy.ts | 12 ++-- test/unit/cbd-strategy.test.ts | 2 +- test/utils.ts | 67 +++++++++++------- 6 files changed, 210 insertions(+), 64 deletions(-) diff --git a/src/agents/coordinator.ts b/src/agents/coordinator.ts index 264e4ea50..ccab3cf26 100644 --- a/src/agents/coordinator.ts +++ b/src/agents/coordinator.ts @@ -1,4 +1,4 @@ -import { SessionStaticKey } from '@nucypher/nucypher-core'; +import { SessionStaticKey, Transcript } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; import { @@ -6,9 +6,10 @@ import { Coordinator__factory, } from '../../types/ethers-contracts'; import { BLS12381 } from '../../types/ethers-contracts/Coordinator'; +import { ChecksumAddress } from '../types'; import { fromHexString } from '../utils'; -import { getContract } from './contracts'; +import { DEFAULT_WAIT_N_CONFIRMATIONS, getContract } from './contracts'; export interface CoordinatorRitual { initiator: string; @@ -24,12 +25,22 @@ export interface CoordinatorRitual { export type DkgParticipant = { provider: string; aggregated: boolean; + transcript: Transcript; decryptionRequestStaticKey: SessionStaticKey; }; +export enum DkgRitualState { + NON_INITIATED, + AWAITING_TRANSCRIPTS, + AWAITING_AGGREGATIONS, + TIMEOUT, + INVALID, + FINALIZED, +} + export class DkgCoordinatorAgent { public static async getParticipants( - provider: ethers.providers.Provider, + provider: ethers.providers.Web3Provider, ritualId: number ): Promise { const Coordinator = await this.connectReadOnly(provider); @@ -39,6 +50,7 @@ export class DkgCoordinatorAgent { return { provider: participant.provider, aggregated: participant.aggregated, + transcript: Transcript.fromBytes(fromHexString(participant.transcript)), decryptionRequestStaticKey: SessionStaticKey.fromBytes( fromHexString(participant.decryptionRequestStaticKey) ), @@ -46,20 +58,68 @@ export class DkgCoordinatorAgent { }); } + public static async initializeRitual( + provider: ethers.providers.Web3Provider, + providers: ChecksumAddress[] + ): Promise { + const Coordinator = await this.connectReadWrite(provider); + const tx = await Coordinator.initiateRitual(providers); + const txReceipt = await tx.wait(DEFAULT_WAIT_N_CONFIRMATIONS); + const [ritualStartEvent] = txReceipt.events ?? []; + if (!ritualStartEvent) { + throw new Error('Ritual start event not found'); + } + return ritualStartEvent.args?.ritualId.toNumber(); + } + public static async getRitual( - provider: ethers.providers.Provider, + provider: ethers.providers.Web3Provider, ritualId: number ): Promise { const Coordinator = await this.connectReadOnly(provider); return Coordinator.rituals(ritualId); } - private static async connectReadOnly(provider: ethers.providers.Provider) { + public static async getRitualState( + provider: ethers.providers.Web3Provider, + ritualId: number + ): Promise { + const Coordinator = await this.connectReadOnly(provider); + return await Coordinator.getRitualState(ritualId); + } + + public static async onRitualEndEvent( + provider: ethers.providers.Web3Provider, + ritualId: number, + callback: (successful: boolean) => void + ): Promise { + const Coordinator = await this.connectReadOnly(provider); + // We leave `initiator` undefined because we don't care who the initiator is + // We leave `successful` undefined because we don't care if the ritual was successful + const eventFilter = Coordinator.filters.EndRitual( + ritualId, + undefined, + undefined + ); + Coordinator.once(eventFilter, (_ritualId, _initiator, successful) => { + callback(successful); + }); + } + + private static async connectReadOnly( + provider: ethers.providers.Web3Provider + ) { return await this.connect(provider); } + private static async connectReadWrite( + web3Provider: ethers.providers.Web3Provider + ) { + return await this.connect(web3Provider, web3Provider.getSigner()); + } + private static async connect( - provider: ethers.providers.Provider, + provider: ethers.providers.Web3Provider, signer?: ethers.providers.JsonRpcSigner ): Promise { const network = await provider.getNetwork(); diff --git a/src/characters/cbd-recipient.ts b/src/characters/cbd-recipient.ts index cef8d360c..1b9d38021 100644 --- a/src/characters/cbd-recipient.ts +++ b/src/characters/cbd-recipient.ts @@ -43,7 +43,7 @@ export class CbdTDecDecrypter { return new CbdTDecDecrypter( new Porter(porterUri), dkgRitual.id, - dkgRitual.threshold + dkgRitual.dkgParams.threshold ); } @@ -75,7 +75,7 @@ export class CbdTDecDecrypter { public async retrieve( provider: ethers.providers.Web3Provider, conditionExpr: ConditionExpression, - variant: number, + variant: FerveoVariant, ciphertext: Ciphertext ): Promise { const dkgParticipants = await DkgCoordinatorAgent.getParticipants( @@ -141,7 +141,7 @@ export class CbdTDecDecrypter { private makeDecryptionRequests( ritualId: number, - variant: number, + variant: FerveoVariant, ciphertext: Ciphertext, conditionExpr: ConditionExpression, contextStr: string, diff --git a/src/dkg.ts b/src/dkg.ts index f0ee81e41..36693cc47 100644 --- a/src/dkg.ts +++ b/src/dkg.ts @@ -8,8 +8,9 @@ import { } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; -import { DkgCoordinatorAgent } from './agents/coordinator'; -import { bytesEquals, fromHexString } from './utils'; +import { DkgCoordinatorAgent, DkgRitualState } from './agents/coordinator'; +import { ChecksumAddress } from './types'; +import { bytesEquals, fromHexString, objectEquals } from './utils'; // TODO: Expose from @nucypher/nucypher-core export enum FerveoVariant { @@ -45,33 +46,47 @@ export function getCombineDecryptionSharesFunction( } } +export type DkgRitualParameters = { + sharesNum: number; + threshold: number; +}; + export interface DkgRitualJSON { id: number; dkgPublicKey: Uint8Array; - threshold: number; + dkgParams: DkgRitualParameters; + state: DkgRitualState; } export class DkgRitual { constructor( public readonly id: number, public readonly dkgPublicKey: DkgPublicKey, - public readonly threshold: number + public readonly dkgParams: DkgRitualParameters, + public readonly state: DkgRitualState ) {} public toObj(): DkgRitualJSON { return { id: this.id, dkgPublicKey: this.dkgPublicKey.toBytes(), - threshold: this.threshold, + dkgParams: this.dkgParams, + state: this.state, }; } public static fromObj({ id, dkgPublicKey, - threshold, + dkgParams, + state, }: DkgRitualJSON): DkgRitual { - return new DkgRitual(id, DkgPublicKey.fromBytes(dkgPublicKey), threshold); + return new DkgRitual( + id, + DkgPublicKey.fromBytes(dkgPublicKey), + dkgParams, + state + ); } public equals(other: DkgRitual): boolean { @@ -79,31 +94,85 @@ export class DkgRitual { this.id === other.id && // TODO: Replace with `equals` after https://github.com/nucypher/nucypher-core/issues/56 is fixed bytesEquals(this.dkgPublicKey.toBytes(), other.dkgPublicKey.toBytes()) && - this.threshold === other.threshold + objectEquals(this.dkgParams, other.dkgParams) && + this.state === other.state ); } } +// TODO: Currently, we're assuming that the threshold is always `floor(sharesNum / 2) + 1`. +// https://github.com/nucypher/nucypher/issues/3095 +const assumedThreshold = (sharesNum: number): number => + Math.floor(sharesNum / 2) + 1; + export class DkgClient { - constructor(private readonly provider: ethers.providers.Web3Provider) {} - - // TODO: Update API: Replace with getExistingRitual and support ritualId in Strategy - public async initializeRitual(ritualParams: { - shares: number; - threshold: number; - }): Promise { - const ritualId = 2; - const ritual = await DkgCoordinatorAgent.getRitual(this.provider, ritualId); + public static async initializeRitual( + web3Provider: ethers.providers.Web3Provider, + ursulas: ChecksumAddress[], + waitUntilEnd = false + ): Promise { + const ritualId = await DkgCoordinatorAgent.initializeRitual( + web3Provider, + ursulas + ); + + if (waitUntilEnd) { + const isSuccessful = await DkgClient.waitUntilRitualEnd( + web3Provider, + ritualId + ); + if (!isSuccessful) { + const ritualState = await DkgCoordinatorAgent.getRitualState( + web3Provider, + ritualId + ); + throw new Error( + `Ritual initialization failed. Ritual id ${ritualId} is in state ${ritualState}` + ); + } + } + + return this.getExistingRitual(web3Provider, ritualId); + } + + private static waitUntilRitualEnd = async ( + web3Provider: ethers.providers.Web3Provider, + ritualId: number + ): Promise => { + return new Promise((resolve, reject) => { + const callback = (successful: boolean) => { + if (successful) { + resolve(true); + } else { + reject(); + } + }; + DkgCoordinatorAgent.onRitualEndEvent(web3Provider, ritualId, callback); + }); + }; + + public static async getExistingRitual( + web3Provider: ethers.providers.Web3Provider, + ritualId: number + ): Promise { + const ritualState = await DkgCoordinatorAgent.getRitualState( + web3Provider, + ritualId + ); + const ritual = await DkgCoordinatorAgent.getRitual(web3Provider, ritualId); const dkgPkBytes = new Uint8Array([ ...fromHexString(ritual.publicKey.word0), ...fromHexString(ritual.publicKey.word1), ]); - - return { - id: ritualId, - dkgPublicKey: DkgPublicKey.fromBytes(dkgPkBytes), - threshold: ritualParams.threshold, - } as DkgRitual; + return new DkgRitual( + ritualId, + DkgPublicKey.fromBytes(dkgPkBytes), + { + sharesNum: ritual.dkgSize, + threshold: assumedThreshold(ritual.dkgSize), + }, + ritualState + ); } // TODO: Without Validator public key in Coordinator, we cannot verify the diff --git a/src/sdk/strategy/cbd-strategy.ts b/src/sdk/strategy/cbd-strategy.ts index 0632eeaef..2b6887371 100644 --- a/src/sdk/strategy/cbd-strategy.ts +++ b/src/sdk/strategy/cbd-strategy.ts @@ -30,14 +30,12 @@ export class CbdStrategy { } public async deploy( - provider: ethers.providers.Web3Provider + web3Provider: ethers.providers.Web3Provider ): Promise { - const dkgRitualParams = { - threshold: this.cohort.configuration.threshold, - shares: this.cohort.configuration.shares, - }; - const dkgClient = new DkgClient(provider); - const dkgRitual = await dkgClient.initializeRitual(dkgRitualParams); + const dkgRitual = await DkgClient.initializeRitual( + web3Provider, + this.cohort.ursulaAddresses + ); return DeployedCbdStrategy.create(this.cohort, dkgRitual); } diff --git a/test/unit/cbd-strategy.test.ts b/test/unit/cbd-strategy.test.ts index 36a8f216b..752f774d4 100644 --- a/test/unit/cbd-strategy.test.ts +++ b/test/unit/cbd-strategy.test.ts @@ -50,7 +50,7 @@ async function makeDeployedCbdStrategy() { const strategy = await makeCbdStrategy(); const mockedDkg = fakeDkgFlow(variant, 0, 4, 4); - const mockedDkgRitual = fakeDkgRitual(mockedDkg, mockedDkg.threshold); + const mockedDkgRitual = fakeDkgRitual(mockedDkg); const web3Provider = fakeWeb3Provider(aliceSecretKey.toBEBytes()); const getUrsulasSpy = mockGetUrsulas(ursulas); const initializeRitualSpy = mockInitializeRitual(mockedDkgRitual); diff --git a/test/utils.ts b/test/utils.ts index 46dce7df5..71ae54bd0 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,13 +1,24 @@ -// Disabling some of the eslint rules for conveninence. +// Disabling some of the eslint rules for convenience. /* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { Block } from '@ethersproject/providers'; import { + AggregatedTranscript, Capsule, CapsuleFrag, + Ciphertext, + combineDecryptionSharesPrecomputed, + combineDecryptionSharesSimple, + DecryptionSharePrecomputed, + DecryptionShareSimple, + decryptWithSharedSecret, + Dkg, EncryptedThresholdDecryptionResponse, EncryptedTreasureMap, + EthereumAddress, ferveoEncrypt, + Keypair, PublicKey, reencrypt, SecretKey, @@ -15,30 +26,22 @@ import { SessionStaticKey, SessionStaticSecret, ThresholdDecryptionResponse, - VerifiedCapsuleFrag, - VerifiedKeyFrag, -} from '@nucypher/nucypher-core'; -import { - AggregatedTranscript, - Ciphertext, - combineDecryptionSharesPrecomputed, - combineDecryptionSharesSimple, - DecryptionSharePrecomputed, - DecryptionShareSimple, - decryptWithSharedSecret, - Dkg, - EthereumAddress, - Keypair, Transcript, Validator, ValidatorMessage, + VerifiedCapsuleFrag, + VerifiedKeyFrag, } from '@nucypher/nucypher-core'; import axios from 'axios'; import { ethers, providers, Wallet } from 'ethers'; import { keccak256 } from 'ethers/lib/utils'; import { Alice, Bob, Cohort, Configuration, RemoteBob } from '../src'; -import { DkgCoordinatorAgent, DkgParticipant } from '../src/agents/coordinator'; +import { + DkgCoordinatorAgent, + DkgParticipant, + DkgRitualState, +} from '../src/agents/coordinator'; import { CbdTDecDecrypter } from '../src/characters/cbd-recipient'; import { CbdDecryptResult, @@ -496,16 +499,26 @@ export const mockRandomSessionStaticSecret = (secret: SessionStaticSecret) => { export const fakeRitualId = 0; -export const fakeDkgRitual = (ritual: { dkg: Dkg }, threshold: number) => { - return new DkgRitual(fakeRitualId, ritual.dkg.publicKey(), threshold); +export const fakeDkgRitual = (ritual: { + dkg: Dkg; + sharesNum: number; + threshold: number; +}) => { + return new DkgRitual( + fakeRitualId, + ritual.dkg.publicKey(), + { + sharesNum: ritual.sharesNum, + threshold: ritual.threshold, + }, + DkgRitualState.FINALIZED + ); }; -export const mockInitializeRitual = (fakeRitual: unknown) => { - return jest - .spyOn(DkgClient.prototype as any, 'initializeRitual') - .mockImplementation(() => { - return Promise.resolve(fakeRitual); - }); +export const mockInitializeRitual = (dkgRitual: DkgRitual) => { + return jest.spyOn(DkgClient, 'initializeRitual').mockImplementation(() => { + return Promise.resolve(dkgRitual); + }); }; export const makeCohort = async (ursulas: Ursula[]) => { @@ -519,3 +532,9 @@ export const makeCohort = async (ursulas: Ursula[]) => { expect(getUrsulasSpy).toHaveBeenCalled(); return cohort; }; + +export const mockGetRitualState = (state = DkgRitualState.FINALIZED) => { + return jest + .spyOn(DkgCoordinatorAgent, 'getRitualState') + .mockImplementation((_provider, _ritualId) => Promise.resolve(state)); +}; From 81c3c8840203ffbd1b989a935a42f1c5014cfe6a Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Tue, 11 Jul 2023 15:37:48 +0200 Subject: [PATCH 02/17] add feedback from live testing --- src/agents/coordinator.ts | 2 +- src/dkg.ts | 6 +++--- src/policies/policy.ts | 5 +++++ src/sdk/cohort.ts | 9 +++++++++ src/sdk/strategy/cbd-strategy.ts | 19 ++++++++++++++----- test/acceptance/alice-grants.test.ts | 2 +- test/acceptance/delay-enact.test.ts | 2 +- test/docs/cbd.test.ts | 4 ++-- test/integration/pre.test.ts | 2 +- test/unit/cbd-strategy.test.ts | 8 ++++++-- test/unit/cohort.test.ts | 2 +- test/unit/pre-strategy.test.ts | 2 +- test/utils.ts | 17 ++++++++++++----- 13 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/agents/coordinator.ts b/src/agents/coordinator.ts index ccab3cf26..ca1e41f17 100644 --- a/src/agents/coordinator.ts +++ b/src/agents/coordinator.ts @@ -69,7 +69,7 @@ export class DkgCoordinatorAgent { if (!ritualStartEvent) { throw new Error('Ritual start event not found'); } - return ritualStartEvent.args?.ritualId.toNumber(); + return ritualStartEvent.args?.ritualId; } public static async getRitual( diff --git a/src/dkg.ts b/src/dkg.ts index 36693cc47..310709440 100644 --- a/src/dkg.ts +++ b/src/dkg.ts @@ -110,10 +110,10 @@ export class DkgClient { web3Provider: ethers.providers.Web3Provider, ursulas: ChecksumAddress[], waitUntilEnd = false - ): Promise { + ): Promise { const ritualId = await DkgCoordinatorAgent.initializeRitual( web3Provider, - ursulas + ursulas.sort() ); if (waitUntilEnd) { @@ -132,7 +132,7 @@ export class DkgClient { } } - return this.getExistingRitual(web3Provider, ritualId); + return ritualId; } private static waitUntilRitualEnd = async ( diff --git a/src/policies/policy.ts b/src/policies/policy.ts index 1ccca6a90..b17d6b81f 100644 --- a/src/policies/policy.ts +++ b/src/policies/policy.ts @@ -118,6 +118,11 @@ export class BlockchainPolicy { public async generatePreEnactedPolicy( ursulas: readonly Ursula[] ): Promise { + if (ursulas.length != this.verifiedKFrags.length) { + throw new Error( + `Number of ursulas must match number of verified kFrags: ${this.verifiedKFrags.length}` + ); + } const treasureMap = this.makeTreasureMap(ursulas, this.verifiedKFrags); const encryptedTreasureMap = this.encryptTreasureMap(treasureMap); // const revocationKit = new RevocationKit(treasureMap, this.publisher.signer); diff --git a/src/sdk/cohort.ts b/src/sdk/cohort.ts index 8571f3816..070027186 100644 --- a/src/sdk/cohort.ts +++ b/src/sdk/cohort.ts @@ -26,6 +26,15 @@ export class Cohort { include: string[] = [], exclude: string[] = [] ) { + if (configuration.threshold > configuration.shares) { + throw new Error('Threshold cannot be greater than the number of shares'); + } + // TODO: Remove this limitation after `nucypher-core@0.11.0` deployment + const isMultipleOf2 = (n: number) => n % 2 === 0; + if (!isMultipleOf2(configuration.shares)) { + throw new Error('Number of shares must be a multiple of 2'); + } + const porter = new Porter(configuration.porterUri); const ursulas = await porter.getUrsulas( configuration.shares, diff --git a/src/sdk/strategy/cbd-strategy.ts b/src/sdk/strategy/cbd-strategy.ts index 2b6887371..dbc2a6766 100644 --- a/src/sdk/strategy/cbd-strategy.ts +++ b/src/sdk/strategy/cbd-strategy.ts @@ -30,12 +30,21 @@ export class CbdStrategy { } public async deploy( - web3Provider: ethers.providers.Web3Provider + web3Provider: ethers.providers.Web3Provider, + ritualId?: number ): Promise { - const dkgRitual = await DkgClient.initializeRitual( - web3Provider, - this.cohort.ursulaAddresses - ); + if (ritualId === undefined) { + ritualId = await DkgClient.initializeRitual( + web3Provider, + this.cohort.ursulaAddresses, + true + ); + } + if (ritualId === undefined) { + // Given that we just initialized the ritual, this should never happen + throw new Error('Ritual ID is undefined'); + } + const dkgRitual = await DkgClient.getExistingRitual(web3Provider, ritualId); return DeployedCbdStrategy.create(this.cohort, dkgRitual); } diff --git a/test/acceptance/alice-grants.test.ts b/test/acceptance/alice-grants.test.ts index a5fce2365..5460d43b3 100644 --- a/test/acceptance/alice-grants.test.ts +++ b/test/acceptance/alice-grants.test.ts @@ -31,7 +31,7 @@ describe('story: alice shares message with bob through policy', () => { const shares = 3; const startDate = new Date(); const endDate = new Date(Date.now() + 60 * 1000); - const mockedUrsulas = fakeUrsulas().slice(0, shares); + const mockedUrsulas = fakeUrsulas(shares); // Intermediate variables used for mocking let encryptedTreasureMap: EncryptedTreasureMap; diff --git a/test/acceptance/delay-enact.test.ts b/test/acceptance/delay-enact.test.ts index 61574df95..857e0e9f0 100644 --- a/test/acceptance/delay-enact.test.ts +++ b/test/acceptance/delay-enact.test.ts @@ -14,7 +14,7 @@ describe('story: alice1 creates a policy but alice2 enacts it', () => { const shares = 3; const startDate = new Date(); const endDate = new Date(Date.now() + 60 * 1000); // 60s later - const mockedUrsulas = fakeUrsulas().slice(0, shares); + const mockedUrsulas = fakeUrsulas(shares); const label = 'fake-data-label'; it('alice generates a new policy', async () => { diff --git a/test/docs/cbd.test.ts b/test/docs/cbd.test.ts index cac579632..7538ba827 100644 --- a/test/docs/cbd.test.ts +++ b/test/docs/cbd.test.ts @@ -61,8 +61,8 @@ describe('Get Started (CBD PoC)', () => { // 2. Build a Cohort const config = { - threshold: 3, - shares: 5, + threshold: 2, + shares: 4, porterUri: 'https://porter-tapir.nucypher.community', }; const newCohort = await Cohort.create(config); diff --git a/test/integration/pre.test.ts b/test/integration/pre.test.ts index e3087e16c..6546228f5 100644 --- a/test/integration/pre.test.ts +++ b/test/integration/pre.test.ts @@ -15,7 +15,7 @@ describe('proxy reencryption', () => { const plaintext = toBytes('plaintext-message'); const threshold = 2; const shares = 3; - const ursulas = fakeUrsulas().slice(0, shares); + const ursulas = fakeUrsulas(shares); const label = 'fake-data-label'; const alice = fakeAlice(); const bob = fakeBob(); diff --git a/test/unit/cbd-strategy.test.ts b/test/unit/cbd-strategy.test.ts index 752f774d4..120888bf7 100644 --- a/test/unit/cbd-strategy.test.ts +++ b/test/unit/cbd-strategy.test.ts @@ -14,6 +14,7 @@ import { fakeWeb3Provider, makeCohort, mockCbdDecrypt, + mockGetExistingRitual, mockGetParticipants, mockGetUrsulas, mockInitializeRitual, @@ -36,8 +37,9 @@ const ownsNFT = new ERC721Ownership({ chain: 5, }); const conditionExpr = new ConditionExpression(ownsNFT); -const ursulas = fakeUrsulas().slice(0, 3); +const ursulas = fakeUrsulas(); const variant = FerveoVariant.Precomputed; +const ritualId = 0; const makeCbdStrategy = async () => { const cohort = await makeCohort(ursulas); @@ -53,11 +55,13 @@ async function makeDeployedCbdStrategy() { const mockedDkgRitual = fakeDkgRitual(mockedDkg); const web3Provider = fakeWeb3Provider(aliceSecretKey.toBEBytes()); const getUrsulasSpy = mockGetUrsulas(ursulas); - const initializeRitualSpy = mockInitializeRitual(mockedDkgRitual); + const initializeRitualSpy = mockInitializeRitual(ritualId); + const getExistingRitualSpy = mockGetExistingRitual(mockedDkgRitual); const deployedStrategy = await strategy.deploy(web3Provider); expect(getUrsulasSpy).toHaveBeenCalled(); expect(initializeRitualSpy).toHaveBeenCalled(); + expect(getExistingRitualSpy).toHaveBeenCalled(); return { mockedDkg, deployedStrategy }; } diff --git a/test/unit/cohort.test.ts b/test/unit/cohort.test.ts index 40ab18ee8..e041bcad8 100644 --- a/test/unit/cohort.test.ts +++ b/test/unit/cohort.test.ts @@ -2,7 +2,7 @@ import { Cohort } from '../../src'; import { fakeUrsulas, makeCohort } from '../utils'; describe('Cohort', () => { - const mockedUrsulas = fakeUrsulas().slice(0, 3); + const mockedUrsulas = fakeUrsulas(); it('creates a Cohort', async () => { const cohort = await makeCohort(mockedUrsulas); diff --git a/test/unit/pre-strategy.test.ts b/test/unit/pre-strategy.test.ts index 9fa599a22..6a5e6d2f3 100644 --- a/test/unit/pre-strategy.test.ts +++ b/test/unit/pre-strategy.test.ts @@ -38,7 +38,7 @@ const ownsNFT = new ERC721Ownership({ chain: 5, }); const conditionExpr = new ConditionExpression(ownsNFT); -const mockedUrsulas = fakeUrsulas().slice(0, 3); +const mockedUrsulas = fakeUrsulas(); const makePreStrategy = async () => { const cohort = await makeCohort(mockedUrsulas); diff --git a/test/utils.ts b/test/utils.ts index 71ae54bd0..7cafbae10 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -113,11 +113,12 @@ const genChecksumAddress = (i: number) => '0x' + '0'.repeat(40 - i.toString(16).length) + i.toString(16); const genEthAddr = (i: number) => EthereumAddress.fromString(genChecksumAddress(i)); -export const fakeUrsulas = (): readonly Ursula[] => - [0, 1, 2, 3, 4].map((i: number) => ({ +export const fakeUrsulas = (n = 4): Ursula[] => + // 0...n-1 + Array.from(Array(n).keys()).map((i: number) => ({ encryptingKey: SecretKey.random().publicKey(), checksumAddress: genChecksumAddress(i).toLowerCase(), - uri: 'https://example.a.com:9151', + uri: `https://example.${i}.com:9151`, })); export const mockGetUrsulas = (ursulas: readonly Ursula[]) => { @@ -515,8 +516,14 @@ export const fakeDkgRitual = (ritual: { ); }; -export const mockInitializeRitual = (dkgRitual: DkgRitual) => { +export const mockInitializeRitual = (ritualId: number) => { return jest.spyOn(DkgClient, 'initializeRitual').mockImplementation(() => { + return Promise.resolve(ritualId); + }); +}; + +export const mockGetExistingRitual = (dkgRitual: DkgRitual) => { + return jest.spyOn(DkgClient, 'getExistingRitual').mockImplementation(() => { return Promise.resolve(dkgRitual); }); }; @@ -525,7 +532,7 @@ export const makeCohort = async (ursulas: Ursula[]) => { const getUrsulasSpy = mockGetUrsulas(ursulas); const config = { threshold: 2, - shares: 3, + shares: ursulas.length, porterUri: 'https://_this.should.crash', }; const cohort = await Cohort.create(config); From baeb6a9545734baf1af4ab68b017c39d8d0f8330 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Thu, 13 Jul 2023 14:00:28 +0200 Subject: [PATCH 03/17] chore(deps): update to nucypher-core@0.11.0 --- package.json | 2 +- src/characters/cbd-recipient.ts | 26 +- src/dkg.ts | 33 +-- src/index.ts | 2 +- test/unit/cbd-strategy.test.ts | 5 +- test/utils.ts | 25 +- yarn.lock | 460 +++++++++++++++----------------- 7 files changed, 273 insertions(+), 280 deletions(-) diff --git a/package.json b/package.json index 66c131599..b2764235b 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "prebuild": "yarn typechain" }, "dependencies": { - "@nucypher/nucypher-core": "^0.10.0", + "@nucypher/nucypher-core": "file:../nucypher-core/nucypher-core-wasm/pkg", "axios": "^0.21.1", "deep-equal": "^2.2.1", "ethers": "^5.4.1", diff --git a/src/characters/cbd-recipient.ts b/src/characters/cbd-recipient.ts index 1b9d38021..a85836571 100644 --- a/src/characters/cbd-recipient.ts +++ b/src/characters/cbd-recipient.ts @@ -6,17 +6,21 @@ import { decryptWithSharedSecret, EncryptedThresholdDecryptionRequest, EncryptedThresholdDecryptionResponse, + FerveoVariant, SessionSharedSecret, SessionStaticSecret, ThresholdDecryptionRequest, } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; -import { DkgCoordinatorAgent, DkgParticipant } from '../agents/coordinator'; +import { + DkgCoordinatorAgent, + DkgParticipant, + DkgRitualState, +} from '../agents/coordinator'; import { ConditionExpression } from '../conditions'; import { DkgRitual, - FerveoVariant, getCombineDecryptionSharesFunction, getVariantClass, } from '../dkg'; @@ -73,16 +77,26 @@ export class CbdTDecDecrypter { // Retrieve decryption shares public async retrieve( - provider: ethers.providers.Web3Provider, + web3Provider: ethers.providers.Web3Provider, conditionExpr: ConditionExpression, variant: FerveoVariant, ciphertext: Ciphertext ): Promise { + const ritualState = await DkgCoordinatorAgent.getRitualState( + web3Provider, + this.ritualId + ); + if (ritualState !== DkgRitualState.FINALIZED) { + throw new Error( + `Ritual with id ${this.ritualId} is not finalized. Ritual state is ${ritualState}.` + ); + } + const dkgParticipants = await DkgCoordinatorAgent.getParticipants( - provider, + web3Provider, this.ritualId ); - const contextStr = await conditionExpr.buildContext(provider).toJson(); + const contextStr = await conditionExpr.buildContext(web3Provider).toJson(); const { sharedSecrets, encryptedRequests } = this.makeDecryptionRequests( this.ritualId, variant, @@ -115,7 +129,7 @@ export class CbdTDecDecrypter { private makeDecryptionShares( encryptedResponses: Record, sessionSharedSecret: Record, - variant: number, + variant: FerveoVariant, expectedRitualId: number ) { const decryptedResponses = Object.entries(encryptedResponses).map( diff --git a/src/dkg.ts b/src/dkg.ts index 310709440..f5def34ec 100644 --- a/src/dkg.ts +++ b/src/dkg.ts @@ -4,6 +4,7 @@ import { DecryptionSharePrecomputed, DecryptionShareSimple, DkgPublicKey, + FerveoVariant, SharedSecret, } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; @@ -12,22 +13,15 @@ import { DkgCoordinatorAgent, DkgRitualState } from './agents/coordinator'; import { ChecksumAddress } from './types'; import { bytesEquals, fromHexString, objectEquals } from './utils'; -// TODO: Expose from @nucypher/nucypher-core -export enum FerveoVariant { - Simple = 0, - Precomputed = 1, -} - export function getVariantClass( variant: FerveoVariant ): typeof DecryptionShareSimple | typeof DecryptionSharePrecomputed { - switch (variant) { - case FerveoVariant.Simple: - return DecryptionShareSimple; - case FerveoVariant.Precomputed: - return DecryptionSharePrecomputed; - default: - throw new Error(`Invalid FerveoVariant: ${variant}`); + if (variant.equals(FerveoVariant.simple)) { + return DecryptionShareSimple; + } else if (variant.equals(FerveoVariant.precomputed)) { + return DecryptionSharePrecomputed; + } else { + throw new Error(`Invalid FerveoVariant: ${variant}`); } } @@ -36,13 +30,12 @@ export function getCombineDecryptionSharesFunction( ): ( shares: DecryptionShareSimple[] | DecryptionSharePrecomputed[] ) => SharedSecret { - switch (variant) { - case FerveoVariant.Simple: - return combineDecryptionSharesSimple; - case FerveoVariant.Precomputed: - return combineDecryptionSharesPrecomputed; - default: - throw new Error(`Invalid FerveoVariant: ${variant}`); + if (variant.equals(FerveoVariant.simple)) { + return combineDecryptionSharesSimple; + } else if (variant.equals(FerveoVariant.precomputed)) { + return combineDecryptionSharesPrecomputed; + } else { + throw new Error(`Invalid FerveoVariant: ${variant}`); } } diff --git a/src/index.ts b/src/index.ts index b8caa482b..0b3e89136 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,7 +29,7 @@ import * as conditions from './conditions'; export { conditions, CustomContextParam }; // DKG -export { FerveoVariant } from './dkg'; +export { FerveoVariant } from '@nucypher/nucypher-core'; // SDK export { Cohort } from './sdk/cohort'; diff --git a/test/unit/cbd-strategy.test.ts b/test/unit/cbd-strategy.test.ts index 120888bf7..7a6ad30ff 100644 --- a/test/unit/cbd-strategy.test.ts +++ b/test/unit/cbd-strategy.test.ts @@ -16,6 +16,7 @@ import { mockCbdDecrypt, mockGetExistingRitual, mockGetParticipants, + mockGetRitualState, mockGetUrsulas, mockInitializeRitual, mockRandomSessionStaticSecret, @@ -38,7 +39,7 @@ const ownsNFT = new ERC721Ownership({ }); const conditionExpr = new ConditionExpression(ownsNFT); const ursulas = fakeUrsulas(); -const variant = FerveoVariant.Precomputed; +const variant = FerveoVariant.precomputed; const ritualId = 0; const makeCbdStrategy = async () => { @@ -131,6 +132,7 @@ describe('CbdDeployedStrategy', () => { const getParticipantsSpy = mockGetParticipants(participants); const getUrsulasSpy = mockGetUrsulas(ursulas); const sessionKeySpy = mockRandomSessionStaticSecret(requesterSessionKey); + const getRitualStateSpy = mockGetRitualState(); const decryptedMessage = await deployedStrategy.decrypter.retrieveAndDecrypt( @@ -142,6 +144,7 @@ describe('CbdDeployedStrategy', () => { expect(getUrsulasSpy).toHaveBeenCalled(); expect(getParticipantsSpy).toHaveBeenCalled(); expect(sessionKeySpy).toHaveBeenCalled(); + expect(getRitualStateSpy).toHaveBeenCalled(); expect(decryptSpy).toHaveBeenCalled(); expect(decryptedMessage).toEqual(toBytes(message)); }); diff --git a/test/utils.ts b/test/utils.ts index 7cafbae10..b4095fbe8 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -18,6 +18,7 @@ import { EncryptedTreasureMap, EthereumAddress, ferveoEncrypt, + FerveoVariant, Keypair, PublicKey, reencrypt, @@ -50,7 +51,7 @@ import { RetrieveCFragsResult, Ursula, } from '../src/characters/porter'; -import { DkgClient, DkgRitual, FerveoVariant } from '../src/dkg'; +import { DkgClient, DkgRitual } from '../src/dkg'; import { BlockchainPolicy, PreEnactedPolicy } from '../src/policies/policy'; import { ChecksumAddress } from '../src/types'; import { toBytes, toHexString, zip } from '../src/utils'; @@ -218,14 +219,14 @@ export const mockDetectEthereumProvider = () => { }; export const fakeDkgFlow = ( - variant: FerveoVariant | FerveoVariant.Precomputed, + variant: FerveoVariant, ritualId: number, sharesNum: number, threshold: number ) => { if ( - variant !== FerveoVariant.Simple && - variant !== FerveoVariant.Precomputed + !variant.equals(FerveoVariant.simple) && + !variant.equals(FerveoVariant.precomputed) ) { throw new Error(`Invalid variant: ${variant}`); } @@ -322,20 +323,22 @@ export const fakeTDecFlow = ({ } let decryptionShare; - if (variant === FerveoVariant.Precomputed) { + if (variant.equals(FerveoVariant.precomputed)) { decryptionShare = aggregate.createDecryptionSharePrecomputed( dkg, ciphertext, aad, keypair ); - } else { + } else if (variant.equals(FerveoVariant.simple)) { decryptionShare = aggregate.createDecryptionShareSimple( dkg, ciphertext, aad, keypair ); + } else { + throw new Error(`Invalid variant: ${variant}`); } decryptionShares.push(decryptionShare); }); @@ -344,10 +347,12 @@ export const fakeTDecFlow = ({ // This part is in the client API let sharedSecret; - if (variant === FerveoVariant.Precomputed) { + if (variant.equals(FerveoVariant.precomputed)) { sharedSecret = combineDecryptionSharesPrecomputed(decryptionShares); - } else { + } else if (variant.equals(FerveoVariant.simple)) { sharedSecret = combineDecryptionSharesSimple(decryptionShares); + } else { + throw new Error(`Invalid variant: ${variant}`); } // The client should have access to the public parameters of the DKG @@ -402,7 +407,7 @@ export const fakeCoordinatorRitual = ( publicKeyHash: string; totalAggregations: number; } => { - const ritual = fakeDkgTDecFlowE2e(FerveoVariant.Precomputed); + const ritual = fakeDkgTDecFlowE2e(FerveoVariant.precomputed); const dkgPkBytes = ritual.dkg.publicKey().toBytes(); return { id: ritualId, @@ -424,7 +429,7 @@ export const fakeCoordinatorRitual = ( export const fakeDkgParticipants = ( ritualId: number, - variant = FerveoVariant.Precomputed + variant = FerveoVariant.precomputed ): { participants: DkgParticipant[]; participantSecrets: Record; diff --git a/yarn.lock b/yarn.lock index 567b36b42..4ae086ba6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + "@ampproject/remapping@^2.2.0": version "2.2.1" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" @@ -24,36 +29,36 @@ dependencies: "@babel/highlight" "^7.22.5" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.5.tgz#b1f6c86a02d85d2dd3368a2b67c09add8cd0c255" - integrity sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA== +"@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.18.10", "@babel/core@^7.7.2", "@babel/core@^7.8.0": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.5.tgz#d67d9747ecf26ee7ecd3ebae1ee22225fe902a89" - integrity sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.9.tgz#bd96492c68822198f33e8a256061da3cf391f58f" + integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.5" - "@babel/helper-compilation-targets" "^7.22.5" - "@babel/helper-module-transforms" "^7.22.5" - "@babel/helpers" "^7.22.5" - "@babel/parser" "^7.22.5" + "@babel/generator" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.6" + "@babel/parser" "^7.22.7" "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" + "@babel/traverse" "^7.22.8" "@babel/types" "^7.22.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.2" - semver "^6.3.0" + semver "^6.3.1" -"@babel/generator@^7.22.5", "@babel/generator@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.5.tgz#1e7bf768688acfb05cf30b2369ef855e82d984f7" - integrity sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA== +"@babel/generator@^7.22.7", "@babel/generator@^7.22.9", "@babel/generator@^7.7.2": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" + integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== dependencies: "@babel/types" "^7.22.5" "@jridgewell/gen-mapping" "^0.3.2" @@ -74,52 +79,51 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz#fc7319fc54c5e2fa14b2909cf3c5fd3046813e02" - integrity sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw== +"@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" + integrity sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw== dependencies: - "@babel/compat-data" "^7.22.5" + "@babel/compat-data" "^7.22.9" "@babel/helper-validator-option" "^7.22.5" - browserslist "^4.21.3" + browserslist "^4.21.9" lru-cache "^5.1.1" - semver "^6.3.0" + semver "^6.3.1" "@babel/helper-create-class-features-plugin@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz#2192a1970ece4685fbff85b48da2c32fcb130b7c" - integrity sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz#c36ea240bb3348f942f08b0fbe28d6d979fab236" + integrity sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-function-name" "^7.22.5" "@babel/helper-member-expression-to-functions" "^7.22.5" "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" - semver "^6.3.0" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.5.tgz#bb2bf0debfe39b831986a4efbf4066586819c6e4" - integrity sha512-1VpEFOIbMRaXyDeUwUfmTIxExLwQ+zkW+Bh5zXpApA3oQedBx9v/updixWxnx/bZpKw7u8VxWjb/qWpIcmPq8A== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" + integrity sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" regexpu-core "^5.3.1" - semver "^6.3.0" + semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.0.tgz#487053f103110f25b9755c5980e031e93ced24d8" - integrity sha512-RnanLx5ETe6aybRi1cO/edaRH+bNYWaryCEmjDDYyNr4wnSzyOp8T0dWipmqVHKEY3AbVKUom50AKSlj1zmKbg== +"@babel/helper-define-polyfill-provider@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.1.tgz#af1429c4a83ac316a6a8c2cc8ff45cb5d2998d3a" + integrity sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A== dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" debug "^4.1.1" lodash.debounce "^4.0.8" resolve "^1.14.2" - semver "^6.1.2" "@babel/helper-environment-visitor@^7.22.5": version "7.22.5" @@ -155,19 +159,16 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-module-transforms@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz#0f65daa0716961b6e96b164034e737f60a80d2ef" - integrity sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw== +"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== dependencies: "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-module-imports" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" "@babel/helper-validator-identifier" "^7.22.5" - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" - "@babel/types" "^7.22.5" "@babel/helper-optimise-call-expression@^7.22.5": version "7.22.5" @@ -176,32 +177,28 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== "@babel/helper-remap-async-to-generator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz#14a38141a7bf2165ad38da61d61cf27b43015da2" - integrity sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82" + integrity sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-wrap-function" "^7.22.5" - "@babel/types" "^7.22.5" + "@babel/helper-wrap-function" "^7.22.9" -"@babel/helper-replace-supers@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz#71bc5fb348856dea9fdc4eafd7e2e49f585145dc" - integrity sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg== +"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz#cbdc27d6d8d18cd22c81ae4293765a5d9afd0779" + integrity sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg== dependencies: "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-member-expression-to-functions" "^7.22.5" "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" - "@babel/types" "^7.22.5" "@babel/helper-simple-access@^7.22.5": version "7.22.5" @@ -217,10 +214,10 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-split-export-declaration@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz#88cf11050edb95ed08d596f7a044462189127a08" - integrity sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ== +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== dependencies: "@babel/types" "^7.22.5" @@ -239,23 +236,22 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== -"@babel/helper-wrap-function@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz#44d205af19ed8d872b4eefb0d2fa65f45eb34f06" - integrity sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw== +"@babel/helper-wrap-function@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz#189937248c45b0182c1dcf32f3444ca153944cb9" + integrity sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q== dependencies: "@babel/helper-function-name" "^7.22.5" "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/helpers@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.5.tgz#74bb4373eb390d1ceed74a15ef97767e63120820" - integrity sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q== +"@babel/helpers@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.6.tgz#8e61d3395a4f0c5a8060f309fb008200969b5ecd" + integrity sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA== dependencies: "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" + "@babel/traverse" "^7.22.6" "@babel/types" "^7.22.5" "@babel/highlight@^7.10.4", "@babel/highlight@^7.22.5": @@ -267,10 +263,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea" - integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5", "@babel/parser@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" + integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": version "7.22.5" @@ -449,10 +445,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-async-generator-functions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.5.tgz#7336356d23380eda9a56314974f053a020dab0c3" - integrity sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg== +"@babel/plugin-transform-async-generator-functions@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz#053e76c0a903b72b573cb1ab7d6882174d460a1b" + integrity sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg== dependencies: "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" @@ -499,19 +495,19 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-transform-classes@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.5.tgz#635d4e98da741fad814984639f4c0149eb0135e1" - integrity sha512-2edQhLfibpWpsVBx2n/GKOz6JdGQvLruZQfGr9l1qes2KQaWswjBzhQF7UDUZMNaMMQeYnQzxwOMPsbYF7wqPQ== +"@babel/plugin-transform-classes@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz#e04d7d804ed5b8501311293d1a0e6d43e94c3363" + integrity sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.6" "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-function-name" "^7.22.5" "@babel/helper-optimise-call-expression" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-replace-supers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.22.5": @@ -707,10 +703,10 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-optional-chaining@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.5.tgz#1003762b9c14295501beb41be72426736bedd1e0" - integrity sha512-AconbMKOMkyG+xCng2JogMCDcqW8wedQAqpVIL4cOSescZ7+iW8utC6YDZLMCSUIReEA733gzRSaOSXMAt/4WQ== +"@babel/plugin-transform-optional-chaining@^7.22.5", "@babel/plugin-transform-optional-chaining@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz#4bacfe37001fe1901117672875e931d439811564" + integrity sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" @@ -831,12 +827,12 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-env@^7.15.6": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.5.tgz#3da66078b181f3d62512c51cf7014392c511504e" - integrity sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.9.tgz#57f17108eb5dfd4c5c25a44c1977eba1df310ac7" + integrity sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g== dependencies: - "@babel/compat-data" "^7.22.5" - "@babel/helper-compilation-targets" "^7.22.5" + "@babel/compat-data" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-option" "^7.22.5" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.5" @@ -861,13 +857,13 @@ "@babel/plugin-syntax-top-level-await" "^7.14.5" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" "@babel/plugin-transform-arrow-functions" "^7.22.5" - "@babel/plugin-transform-async-generator-functions" "^7.22.5" + "@babel/plugin-transform-async-generator-functions" "^7.22.7" "@babel/plugin-transform-async-to-generator" "^7.22.5" "@babel/plugin-transform-block-scoped-functions" "^7.22.5" "@babel/plugin-transform-block-scoping" "^7.22.5" "@babel/plugin-transform-class-properties" "^7.22.5" "@babel/plugin-transform-class-static-block" "^7.22.5" - "@babel/plugin-transform-classes" "^7.22.5" + "@babel/plugin-transform-classes" "^7.22.6" "@babel/plugin-transform-computed-properties" "^7.22.5" "@babel/plugin-transform-destructuring" "^7.22.5" "@babel/plugin-transform-dotall-regex" "^7.22.5" @@ -892,7 +888,7 @@ "@babel/plugin-transform-object-rest-spread" "^7.22.5" "@babel/plugin-transform-object-super" "^7.22.5" "@babel/plugin-transform-optional-catch-binding" "^7.22.5" - "@babel/plugin-transform-optional-chaining" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.6" "@babel/plugin-transform-parameters" "^7.22.5" "@babel/plugin-transform-private-methods" "^7.22.5" "@babel/plugin-transform-private-property-in-object" "^7.22.5" @@ -910,11 +906,11 @@ "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" "@babel/preset-modules" "^0.1.5" "@babel/types" "^7.22.5" - babel-plugin-polyfill-corejs2 "^0.4.3" - babel-plugin-polyfill-corejs3 "^0.8.1" - babel-plugin-polyfill-regenerator "^0.5.0" - core-js-compat "^3.30.2" - semver "^6.3.0" + babel-plugin-polyfill-corejs2 "^0.4.4" + babel-plugin-polyfill-corejs3 "^0.8.2" + babel-plugin-polyfill-regenerator "^0.5.1" + core-js-compat "^3.31.0" + semver "^6.3.1" "@babel/preset-modules@^0.1.5": version "0.1.5" @@ -933,9 +929,9 @@ integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== "@babel/runtime@^7.8.4": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec" - integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA== + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== dependencies: regenerator-runtime "^0.13.11" @@ -948,18 +944,18 @@ "@babel/parser" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/traverse@^7.22.5", "@babel/traverse@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1" - integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ== +"@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8", "@babel/traverse@^7.7.2": + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" + integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== dependencies: "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.5" + "@babel/generator" "^7.22.7" "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-function-name" "^7.22.5" "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" - "@babel/parser" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.7" "@babel/types" "^7.22.5" debug "^4.1.0" globals "^11.1.0" @@ -1671,6 +1667,11 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@nicolo-ribaudo/semver-v6@^6.3.3": + version "6.3.3" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz#ea6d23ade78a325f7a52750aab1526b02b628c29" + integrity sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1692,10 +1693,8 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nucypher/nucypher-core@^0.10.0": +"@nucypher/nucypher-core@file:../nucypher-core/nucypher-core-wasm/pkg": version "0.10.0" - resolved "https://registry.yarnpkg.com/@nucypher/nucypher-core/-/nucypher-core-0.10.0.tgz#95ba3805fa0c01510e9e012d65b735e97bd6ff08" - integrity sha512-7ZbFIZbAIO8UU++0tGhZEP8z1m4Vj5b/4+c9opBXXK88GZ7DFjdNWeTJWOCwLK3fMSpQJcUmkkqfsUd+PfGa9A== "@sideway/address@^4.1.3": version "4.1.4" @@ -1867,9 +1866,9 @@ integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== "@types/node@*": - version "20.3.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.2.tgz#fa6a90f2600e052a03c18b8cb3fd83dd4e599898" - integrity sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw== + version "20.4.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" + integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -2027,9 +2026,9 @@ acorn@^7.1.1, acorn@^7.4.0: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.2.4, acorn@^8.4.1: - version "8.9.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" - integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== add-stream@^1.0.0: version "1.0.0" @@ -2274,29 +2273,29 @@ babel-plugin-jest-hoist@^27.5.1: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-plugin-polyfill-corejs2@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.3.tgz#75044d90ba5043a5fb559ac98496f62f3eb668fd" - integrity sha512-bM3gHc337Dta490gg+/AseNB9L4YLHxq1nGKZZSHbhXv4aTYU2MD2cjza1Ru4S6975YLTaL1K8uJf6ukJhhmtw== +babel-plugin-polyfill-corejs2@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz#9f9a0e1cd9d645cc246a5e094db5c3aa913ccd2b" + integrity sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.4.0" - semver "^6.1.1" + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.1" + "@nicolo-ribaudo/semver-v6" "^6.3.3" -babel-plugin-polyfill-corejs3@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.1.tgz#39248263c38191f0d226f928d666e6db1b4b3a8a" - integrity sha512-ikFrZITKg1xH6pLND8zT14UPgjKHiGLqex7rGEZCH2EvhsneJaJPemmpQaIZV5AL03II+lXylw3UmddDK8RU5Q== +babel-plugin-polyfill-corejs3@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.2.tgz#d406c5738d298cd9c66f64a94cf8d5904ce4cc5e" + integrity sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ== dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.0" - core-js-compat "^3.30.1" + "@babel/helper-define-polyfill-provider" "^0.4.1" + core-js-compat "^3.31.0" -babel-plugin-polyfill-regenerator@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.0.tgz#e7344d88d9ef18a3c47ded99362ae4a757609380" - integrity sha512-hDJtKjMLVa7Z+LwnTCxoDLQj6wdc+B8dun7ayF2fYieI6OzfuvcLMB32ihJZ4UhCBwNYGl5bg/x/P9cMdnkc2g== +babel-plugin-polyfill-regenerator@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.1.tgz#ace7a5eced6dff7d5060c335c52064778216afd3" + integrity sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.0" + "@babel/helper-define-polyfill-provider" "^0.4.1" babel-preset-current-node-syntax@^1.0.0: version "1.0.1" @@ -2390,7 +2389,7 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.21.3, browserslist@^4.21.5: +browserslist@^4.21.9: version "4.21.9" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== @@ -2465,9 +2464,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001503: - version "1.0.30001508" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz#4461bbc895c692a96da399639cc1e146e7302a33" - integrity sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw== + version "1.0.30001515" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001515.tgz#418aefeed9d024cd3129bfae0ccc782d4cb8f12b" + integrity sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA== chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" @@ -2543,9 +2542,9 @@ co@^4.6.0: integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== color-convert@^1.9.0: version "1.9.3" @@ -2824,12 +2823,12 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== -core-js-compat@^3.30.1, core-js-compat@^3.30.2: - version "3.31.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.0.tgz#4030847c0766cc0e803dcdfb30055d7ef2064bf1" - integrity sha512-hM7YCu1cU6Opx7MXNu0NuumM0ezNeAeRKadixyiQELWY3vT3De9S4J5ZBMraWV2vZnrE1Cirl0GtFtDtMUXzPw== +core-js-compat@^3.31.0: + version "3.31.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.1.tgz#5084ad1a46858df50ff89ace152441a63ba7aae0" + integrity sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA== dependencies: - browserslist "^4.21.5" + browserslist "^4.21.9" core-util-is@~1.0.0: version "1.0.3" @@ -2964,14 +2963,14 @@ dedent@0.7.0, dedent@^0.7.0: integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== deep-equal@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.1.tgz#c72ab22f3a7d3503a4ca87dde976fe9978816739" - integrity sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ== + version "2.2.2" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.2.tgz#9b2635da569a13ba8e1cc159c2f744071b115daa" + integrity sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA== dependencies: array-buffer-byte-length "^1.0.0" call-bind "^1.0.2" es-get-iterator "^1.1.3" - get-intrinsic "^1.2.0" + get-intrinsic "^1.2.1" is-arguments "^1.1.1" is-array-buffer "^3.0.2" is-date-object "^1.0.5" @@ -2992,7 +2991,7 @@ deep-extend@~0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@^0.1.3, deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== @@ -3096,9 +3095,9 @@ dotgitignore@^2.1.0: minimatch "^3.0.4" electron-to-chromium@^1.4.431: - version "1.4.441" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.441.tgz#94dd9c1cbf081d83f032a4f1cd9f787e21fc24ce" - integrity sha512-LlCgQ8zgYZPymf5H4aE9itwiIWH4YlCiv1HFLmmcBeFYi5E+3eaIFnjHzYtcFQbaKfAW+CqZ9pgxo33DZuoqPg== + version "1.4.459" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.459.tgz#25a23370f4ae8aaa8f77aaf00133aa4994f4148e" + integrity sha512-XXRS5NFv8nCrBL74Rm3qhJjA2VCsRFx0OjHKBMPI0otij56aun8UWiKTDABmd5/7GTR021pA4wivs+Ri6XCElg== elliptic@6.5.4: version "6.5.4" @@ -3143,9 +3142,9 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" - integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== + version "1.21.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.3.tgz#8aaa0ffc080e8a6fef6ace72631dc1ec5d47bf94" + integrity sha512-ZU4miiY1j3sGPFLJ34VJXEqhpmL+HGByCinGHv4HC+Fxl2fI2Z4yR6tl0mORnDr6PA8eihWo4LmSWDbvhALckg== dependencies: array-buffer-byte-length "^1.0.0" available-typed-arrays "^1.0.5" @@ -3153,7 +3152,7 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.2.0" + get-intrinsic "^1.2.1" get-symbol-description "^1.0.0" globalthis "^1.0.3" gopd "^1.0.1" @@ -3173,14 +3172,15 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: object-inspect "^1.12.3" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" + regexp.prototype.flags "^1.5.0" safe-regex-test "^1.0.0" string.prototype.trim "^1.2.7" string.prototype.trimend "^1.0.6" string.prototype.trimstart "^1.0.6" + typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" + which-typed-array "^1.1.10" es-get-iterator@^1.1.3: version "1.1.3" @@ -3243,14 +3243,13 @@ escape-string-regexp@^4.0.0: integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== dependencies: esprima "^4.0.1" estraverse "^5.2.0" esutils "^2.0.2" - optionator "^0.8.1" optionalDependencies: source-map "~0.6.1" @@ -3515,9 +3514,9 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + version "3.3.0" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.0.tgz#7c40cb491e1e2ed5664749e87bfb516dbe8727c0" + integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -3530,7 +3529,7 @@ fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== @@ -3770,7 +3769,7 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== @@ -5091,14 +5090,6 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -5438,9 +5429,9 @@ node-int64@^0.4.0: integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== node-releases@^2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" - integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" @@ -5490,9 +5481,9 @@ npm-run-path@^4.0.1: path-key "^3.0.0" nwsapi@^2.2.0: - version "2.2.5" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.5.tgz#a52744c61b3889dd44b0a158687add39b8d935e2" - integrity sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ== + version "2.2.7" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" + integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== object-assign@^4.0.1: version "4.1.1" @@ -5569,29 +5560,17 @@ open@^7.0.3: is-docker "^2.0.0" is-wsl "^2.1.1" -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" ora@^5.4.1: version "5.4.1" @@ -5808,11 +5787,6 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== - prettier@^2.1.1, prettier@^2.1.2: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" @@ -5997,7 +5971,7 @@ regenerator-transform@^0.15.1: dependencies: "@babel/runtime" "^7.8.4" -regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: +regexp.prototype.flags@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== @@ -6167,21 +6141,21 @@ scrypt-js@3.0.1: integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== "semver@2 || 3 || 4 || 5", semver@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@7.x, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.5.2: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== shebang-command@^1.2.0: version "1.2.0" @@ -6756,13 +6730,6 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== - dependencies: - prelude-ls "~1.1.2" - type-detect@4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -6814,6 +6781,17 @@ typechain@^7.0.0: ts-command-line-args "^2.2.0" ts-essentials "^7.0.1" +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + typed-array-length@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" @@ -6852,9 +6830,9 @@ typedoc@^0.22.11: shiki "^0.10.1" "typescript@^4.6.4 || ^5.0.0": - version "5.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" - integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== typescript@^4.7.0: version "4.9.5" @@ -7074,10 +7052,10 @@ which-collection@^1.0.1: is-weakmap "^2.0.1" is-weakset "^2.0.1" -which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== +which-typed-array@^1.1.10, which-typed-array@^1.1.9: + version "1.1.10" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.10.tgz#74baa2789991905c2076abb317103b866c64e69e" + integrity sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA== dependencies: available-typed-arrays "^1.0.5" call-bind "^1.0.2" @@ -7100,7 +7078,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -word-wrap@^1.0.3, word-wrap@^1.2.3, word-wrap@~1.2.3: +word-wrap@^1.0.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== From b351e8829c4db9fccbbbba5f852688d06beb1816 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Wed, 28 Jun 2023 13:54:17 +0200 Subject: [PATCH 04/17] simplify cohort-strategy relationship --- src/characters/cbd-recipient.ts | 16 ++++----- src/characters/pre-recipient.ts | 18 +++++----- src/index.ts | 2 +- src/policies/policy.ts | 15 ++------- src/sdk/cohort.ts | 57 ++++++++------------------------ src/sdk/strategy/cbd-strategy.ts | 30 +++++++++++------ src/sdk/strategy/pre-strategy.ts | 33 ++++++++++-------- test/docs/cbd.test.ts | 11 +++--- test/unit/cbd-strategy.test.ts | 6 ++-- test/unit/pre-strategy.test.ts | 8 ++--- test/utils.ts | 13 +++----- 11 files changed, 90 insertions(+), 119 deletions(-) diff --git a/src/characters/cbd-recipient.ts b/src/characters/cbd-recipient.ts index a85836571..d86e24185 100644 --- a/src/characters/cbd-recipient.ts +++ b/src/characters/cbd-recipient.ts @@ -28,13 +28,13 @@ import { fromJSON, toJSON } from '../utils'; import { Porter } from './porter'; -export type CbdTDecDecrypterJSON = { +export type ThresholdDecrypterJSON = { porterUri: string; ritualId: number; threshold: number; }; -export class CbdTDecDecrypter { +export class ThresholdDecrypter { // private readonly verifyingKey: Keyring; private constructor( @@ -44,7 +44,7 @@ export class CbdTDecDecrypter { ) {} public static create(porterUri: string, dkgRitual: DkgRitual) { - return new CbdTDecDecrypter( + return new ThresholdDecrypter( new Porter(porterUri), dkgRitual.id, dkgRitual.dkgParams.threshold @@ -207,7 +207,7 @@ export class CbdTDecDecrypter { return SessionStaticSecret.random(); } - public toObj(): CbdTDecDecrypterJSON { + public toObj(): ThresholdDecrypterJSON { return { porterUri: this.porter.porterUrl.toString(), ritualId: this.ritualId, @@ -223,15 +223,15 @@ export class CbdTDecDecrypter { porterUri, ritualId, threshold, - }: CbdTDecDecrypterJSON) { - return new CbdTDecDecrypter(new Porter(porterUri), ritualId, threshold); + }: ThresholdDecrypterJSON) { + return new ThresholdDecrypter(new Porter(porterUri), ritualId, threshold); } public static fromJSON(json: string) { - return CbdTDecDecrypter.fromObj(fromJSON(json)); + return ThresholdDecrypter.fromObj(fromJSON(json)); } - public equals(other: CbdTDecDecrypter): boolean { + public equals(other: ThresholdDecrypter): boolean { return ( this.porter.porterUrl.toString() === other.porter.porterUrl.toString() ); diff --git a/src/characters/pre-recipient.ts b/src/characters/pre-recipient.ts index 329d9c627..c51edfb8b 100644 --- a/src/characters/pre-recipient.ts +++ b/src/characters/pre-recipient.ts @@ -16,7 +16,7 @@ import { base64ToU8Receiver, bytesEquals, toJSON, zip } from '../utils'; import { Porter } from './porter'; -export type PreTDecDecrypterJSON = { +export type PreDecrypterJSON = { porterUri: string; policyEncryptingKeyBytes: Uint8Array; encryptedTreasureMapBytes: Uint8Array; @@ -24,7 +24,7 @@ export type PreTDecDecrypterJSON = { bobSecretKeyBytes: Uint8Array; }; -export class PreTDecDecrypter { +export class PreDecrypter { // private readonly verifyingKey: Keyring; constructor( @@ -41,8 +41,8 @@ export class PreTDecDecrypter { policyEncryptingKey: PublicKey, publisherVerifyingKey: PublicKey, encryptedTreasureMap: EncryptedTreasureMap - ): PreTDecDecrypter { - return new PreTDecDecrypter( + ): PreDecrypter { + return new PreDecrypter( new Porter(porterUri), new Keyring(secretKey), policyEncryptingKey, @@ -149,7 +149,7 @@ export class PreTDecDecrypter { }); } - public toObj(): PreTDecDecrypterJSON { + public toObj(): PreDecrypterJSON { return { porterUri: this.porter.porterUrl.toString(), policyEncryptingKeyBytes: this.policyEncryptingKey.toCompressedBytes(), @@ -170,8 +170,8 @@ export class PreTDecDecrypter { encryptedTreasureMapBytes, publisherVerifyingKeyBytes, bobSecretKeyBytes, - }: PreTDecDecrypterJSON) { - return new PreTDecDecrypter( + }: PreDecrypterJSON) { + return new PreDecrypter( new Porter(porterUri), new Keyring(SecretKey.fromBEBytes(bobSecretKeyBytes)), PublicKey.fromCompressedBytes(policyEncryptingKeyBytes), @@ -182,10 +182,10 @@ export class PreTDecDecrypter { public static fromJSON(json: string) { const config = JSON.parse(json, base64ToU8Receiver); - return PreTDecDecrypter.fromObj(config); + return PreDecrypter.fromObj(config); } - public equals(other: PreTDecDecrypter): boolean { + public equals(other: PreDecrypter): boolean { return ( this.porter.porterUrl.toString() === other.porter.porterUrl.toString() && this.policyEncryptingKey.equals(other.policyEncryptingKey) && diff --git a/src/index.ts b/src/index.ts index 0b3e89136..d190f58ca 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,7 +2,7 @@ export { Alice } from './characters/alice'; export { Bob, RemoteBob } from './characters/bob'; export { Enrico } from './characters/enrico'; -export { PreTDecDecrypter } from './characters/pre-recipient'; +export { PreDecrypter } from './characters/pre-recipient'; export { Porter } from './characters/porter'; // Policies diff --git a/src/policies/policy.ts b/src/policies/policy.ts index b17d6b81f..6e8c5c87f 100644 --- a/src/policies/policy.ts +++ b/src/policies/policy.ts @@ -28,15 +28,6 @@ export type EnactedPolicy = { type IPreEnactedPolicy = Omit; -export type EnactedPolicyJSON = Omit< - EnactedPolicy, - 'policyKey' | 'encryptedTreasureMap' | 'id' -> & { - policyKey: Uint8Array; - id: Uint8Array; - encryptedTreasureMap: Uint8Array; -}; - export class PreEnactedPolicy implements IPreEnactedPolicy { constructor( public readonly id: HRAC, @@ -143,18 +134,18 @@ export class BlockchainPolicy { ursulas: readonly Ursula[], verifiedKFrags: readonly VerifiedKeyFrag[] ): TreasureMap { - const assigned_kfrags: [Address, [PublicKey, VerifiedKeyFrag]][] = []; + const assignedKFrags: [Address, [PublicKey, VerifiedKeyFrag]][] = []; zip(ursulas, verifiedKFrags).forEach(([ursula, kFrag]) => { const ursulaAddress = new Address( toCanonicalAddress(ursula.checksumAddress) ); - assigned_kfrags.push([ursulaAddress, [ursula.encryptingKey, kFrag]]); + assignedKFrags.push([ursulaAddress, [ursula.encryptingKey, kFrag]]); }); return new TreasureMap( this.publisher.signer, this.hrac, this.delegatingKey, - assigned_kfrags, + assignedKFrags, this.threshold ); } diff --git a/src/sdk/cohort.ts b/src/sdk/cohort.ts index 070027186..697f7cb8a 100644 --- a/src/sdk/cohort.ts +++ b/src/sdk/cohort.ts @@ -2,50 +2,33 @@ import { Porter } from '../characters/porter'; import { ChecksumAddress } from '../types'; import { objectEquals } from '../utils'; -export type CohortConfiguration = { - readonly threshold: number; - readonly shares: number; - readonly porterUri: string; -}; - export type CohortJSON = { ursulaAddresses: ChecksumAddress[]; - threshold: number; - shares: number; porterUri: string; }; export class Cohort { private constructor( - public ursulaAddresses: ChecksumAddress[], - public readonly configuration: CohortConfiguration + public readonly ursulaAddresses: ChecksumAddress[], + public readonly porterUri: string ) {} public static async create( - configuration: CohortConfiguration, + porterUri: string, + numUrsulas: number, include: string[] = [], exclude: string[] = [] ) { - if (configuration.threshold > configuration.shares) { - throw new Error('Threshold cannot be greater than the number of shares'); - } - // TODO: Remove this limitation after `nucypher-core@0.11.0` deployment - const isMultipleOf2 = (n: number) => n % 2 === 0; - if (!isMultipleOf2(configuration.shares)) { - throw new Error('Number of shares must be a multiple of 2'); - } - - const porter = new Porter(configuration.porterUri); - const ursulas = await porter.getUrsulas( - configuration.shares, - exclude, - include.splice(0, configuration.shares) - ); + const porter = new Porter(porterUri); + const ursulas = await porter.getUrsulas(numUrsulas, exclude, include); const ursulaAddresses = ursulas.map((ursula) => ursula.checksumAddress); - return new Cohort(ursulaAddresses, configuration); + return new Cohort(ursulaAddresses, porterUri); } - public get shares(): number { + public static fromUrsulas(ursulas: ChecksumAddress[], porterUri: string) { + return new Cohort(ursulas, porterUri); + } + public get numUrsulas(): number { return this.ursulaAddresses.length; } @@ -58,26 +41,14 @@ export class Cohort { return Cohort.fromObj(config); } - public static fromObj({ - ursulaAddresses, - threshold, - shares, - porterUri, - }: CohortJSON) { - const config = { - threshold: threshold, - shares: shares, - porterUri: porterUri, - }; - return new Cohort(ursulaAddresses, config); + public static fromObj({ ursulaAddresses, porterUri }: CohortJSON) { + return new Cohort(ursulaAddresses, porterUri); } public toObj(): CohortJSON { return { ursulaAddresses: this.ursulaAddresses, - threshold: this.configuration.threshold, - shares: this.configuration.shares, - porterUri: this.configuration.porterUri, + porterUri: this.porterUri, }; } diff --git a/src/sdk/strategy/cbd-strategy.ts b/src/sdk/strategy/cbd-strategy.ts index dbc2a6766..9228284f3 100644 --- a/src/sdk/strategy/cbd-strategy.ts +++ b/src/sdk/strategy/cbd-strategy.ts @@ -3,8 +3,8 @@ import { ethers } from 'ethers'; import { bytesEqual } from '../../../test/utils'; import { - CbdTDecDecrypter, - CbdTDecDecrypterJSON, + ThresholdDecrypter, + ThresholdDecrypterJSON, } from '../../characters/cbd-recipient'; import { Enrico } from '../../characters/enrico'; import { ConditionExpression, ConditionExpressionJSON } from '../../conditions'; @@ -18,7 +18,7 @@ export type CbdStrategyJSON = { }; export type DeployedStrategyJSON = { - decrypter: CbdTDecDecrypterJSON; + decrypter: ThresholdDecrypterJSON; dkgPublicKey: Uint8Array; }; @@ -45,7 +45,7 @@ export class CbdStrategy { throw new Error('Ritual ID is undefined'); } const dkgRitual = await DkgClient.getExistingRitual(web3Provider, ritualId); - return DeployedCbdStrategy.create(this.cohort, dkgRitual); + return DeployedCbdStrategy.create(dkgRitual, this.cohort.porterUri); } public static fromJSON(json: string) { @@ -73,18 +73,26 @@ export class CbdStrategy { export class DeployedCbdStrategy { private constructor( - public readonly decrypter: CbdTDecDecrypter, + public readonly decrypter: ThresholdDecrypter, public readonly dkgPublicKey: DkgPublicKey ) {} - public static create(cohort: Cohort, dkgRitual: DkgRitual) { - const decrypter = CbdTDecDecrypter.create( - cohort.configuration.porterUri, - dkgRitual - ); + public static create(dkgRitual: DkgRitual, porterUri: string) { + const decrypter = ThresholdDecrypter.create(porterUri, dkgRitual); return new DeployedCbdStrategy(decrypter, dkgRitual.dkgPublicKey); } + // TODO: This is analogous to create() above, is it useful? + public static async fromRitualId( + provider: ethers.providers.Web3Provider, + porterUri: string, + ritualId: number + ): Promise { + const dkgClient = new DkgClient(provider); + const dkgRitual = await dkgClient.getExistingRitual(ritualId); + return DeployedCbdStrategy.create(dkgRitual, porterUri); + } + public makeEncrypter(conditionExpr: ConditionExpression): Enrico { return new Enrico(this.dkgPublicKey, undefined, conditionExpr); } @@ -100,7 +108,7 @@ export class DeployedCbdStrategy { private static fromObj({ decrypter, dkgPublicKey }: DeployedStrategyJSON) { return new DeployedCbdStrategy( - CbdTDecDecrypter.fromObj(decrypter), + ThresholdDecrypter.fromObj(decrypter), DkgPublicKey.fromBytes(dkgPublicKey) ); } diff --git a/src/sdk/strategy/pre-strategy.ts b/src/sdk/strategy/pre-strategy.ts index acc6d997f..01b8f96ac 100644 --- a/src/sdk/strategy/pre-strategy.ts +++ b/src/sdk/strategy/pre-strategy.ts @@ -4,10 +4,7 @@ import { ethers } from 'ethers'; import { Alice } from '../../characters/alice'; import { Bob } from '../../characters/bob'; import { Enrico } from '../../characters/enrico'; -import { - PreTDecDecrypter, - PreTDecDecrypterJSON, -} from '../../characters/pre-recipient'; +import { PreDecrypter, PreDecrypterJSON } from '../../characters/pre-recipient'; import { ConditionExpression } from '../../conditions'; import { EnactedPolicy } from '../../policies/policy'; import { base64ToU8Receiver, bytesEquals, toJSON } from '../../utils'; @@ -23,7 +20,7 @@ export type PreStrategyJSON = { export type DeployedPreStrategyJSON = { cohortConfig: CohortJSON; - decrypterJSON: PreTDecDecrypterJSON; + decrypterJSON: PreDecrypterJSON; policyKeyBytes: Uint8Array; }; @@ -65,10 +62,20 @@ export class PreStrategy { } public async deploy( + provider: ethers.providers.Web3Provider, label: string, - provider: ethers.providers.Web3Provider + threshold?: number, + shares?: number ): Promise { - const porterUri = this.cohort.configuration.porterUri; + shares = shares || this.cohort.numUrsulas; + threshold = threshold || Math.floor(shares / 2) + 1; + if (shares > this.cohort.numUrsulas) { + throw new Error( + `Threshold ${threshold} cannot be greater than the number of Ursulas in the cohort ${this.cohort.numUrsulas}` + ); + } + + const porterUri = this.cohort.porterUri; const configuration = { porterUri }; const alice = Alice.fromSecretKey( configuration, @@ -79,8 +86,8 @@ export class PreStrategy { const policyParams = { bob, label, - threshold: this.cohort.configuration.threshold, - shares: this.cohort.configuration.shares, + threshold, + shares, startDate: this.startDate, endDate: this.endDate, }; @@ -146,7 +153,7 @@ export class PreStrategy { export class DeployedPreStrategy { private constructor( public readonly cohort: Cohort, - public readonly decrypter: PreTDecDecrypter, + public readonly decrypter: PreDecrypter, public readonly policyKey: PublicKey ) {} @@ -155,8 +162,8 @@ export class DeployedPreStrategy { policy: EnactedPolicy, bobSecretKey: SecretKey ) { - const decrypter = PreTDecDecrypter.create( - cohort.configuration.porterUri, + const decrypter = PreDecrypter.create( + cohort.porterUri, bobSecretKey, policy.policyKey, policy.aliceVerifyingKey, @@ -184,7 +191,7 @@ export class DeployedPreStrategy { policyKeyBytes, }: DeployedPreStrategyJSON) { const cohort = Cohort.fromObj(cohortConfig); - const decrypter = PreTDecDecrypter.fromObj(decrypterJSON); + const decrypter = PreDecrypter.fromObj(decrypterJSON); const policyKey = PublicKey.fromCompressedBytes(policyKeyBytes); return new DeployedPreStrategy(cohort, decrypter, policyKey); } diff --git a/test/docs/cbd.test.ts b/test/docs/cbd.test.ts index 7538ba827..217a45ca0 100644 --- a/test/docs/cbd.test.ts +++ b/test/docs/cbd.test.ts @@ -60,12 +60,9 @@ describe('Get Started (CBD PoC)', () => { // // 2. Build a Cohort - const config = { - threshold: 2, - shares: 4, - porterUri: 'https://porter-tapir.nucypher.community', - }; - const newCohort = await Cohort.create(config); + const porterUri = 'https://porter-tapir.nucypher.community'; + const numUrsulas = 5; + const newCohort = await Cohort.create(porterUri, numUrsulas); // 3. Specify default conditions const NFTOwnership = new ERC721Ownership({ @@ -86,7 +83,7 @@ describe('Get Started (CBD PoC)', () => { const mumbai = providers.getNetwork(80001); const web3Provider = new providers.Web3Provider(MMprovider, mumbai); - const newDeployed = await newStrategy.deploy('test', web3Provider); + const newDeployed = await newStrategy.deploy(web3Provider, 'test'); // 5. Encrypt the plaintext & update conditions const NFTBalanceConfig = { diff --git a/test/unit/cbd-strategy.test.ts b/test/unit/cbd-strategy.test.ts index 7a6ad30ff..4526e70f1 100644 --- a/test/unit/cbd-strategy.test.ts +++ b/test/unit/cbd-strategy.test.ts @@ -3,7 +3,7 @@ import { SecretKey, SessionStaticSecret } from '@nucypher/nucypher-core'; import { conditions } from '../../src'; import { FerveoVariant } from '../../src'; import { CbdStrategy, DeployedCbdStrategy } from '../../src'; -import { CbdTDecDecrypter } from '../../src/characters/cbd-recipient'; +import { ThresholdDecrypter } from '../../src/characters/cbd-recipient'; import { toBytes } from '../../src/utils'; import { fakeDkgFlow, @@ -170,14 +170,14 @@ describe('CbdTDecDecrypter', () => { it('serializes to a plain object', async () => { const { deployedStrategy } = await makeDeployedCbdStrategy(); const configObj = deployedStrategy.decrypter.toObj(); - const fromObj = CbdTDecDecrypter.fromObj(configObj); + const fromObj = ThresholdDecrypter.fromObj(configObj); expect(fromObj.equals(deployedStrategy.decrypter)).toBeTruthy(); }); it('serializes to a JSON', async () => { const { deployedStrategy } = await makeDeployedCbdStrategy(); const configJSON = deployedStrategy.decrypter.toJSON(); - const fromJSON = CbdTDecDecrypter.fromJSON(configJSON); + const fromJSON = ThresholdDecrypter.fromJSON(configJSON); expect(fromJSON.equals(deployedStrategy.decrypter)).toBeTruthy(); }); }); diff --git a/test/unit/pre-strategy.test.ts b/test/unit/pre-strategy.test.ts index 6a5e6d2f3..2c801b291 100644 --- a/test/unit/pre-strategy.test.ts +++ b/test/unit/pre-strategy.test.ts @@ -3,8 +3,8 @@ import { SecretKey, VerifiedKeyFrag } from '@nucypher/nucypher-core'; import { conditions, DeployedPreStrategy, + PreDecrypter, PreStrategy, - PreTDecDecrypter, } from '../../src'; import { Ursula } from '../../src/characters/porter'; import { toBytes } from '../../src/utils'; @@ -54,7 +54,7 @@ const makeDeployedPreStrategy = async () => { const makeTreasureMapSpy = mockMakeTreasureMap(); const encryptTreasureMapSpy = mockEncryptTreasureMap(); - const deployedStrategy = await strategy.deploy('test', aliceProvider); + const deployedStrategy = await strategy.deploy(aliceProvider, 'test'); expect(generateKFragsSpy).toHaveBeenCalled(); expect(publishToBlockchainSpy).toHaveBeenCalled(); @@ -155,14 +155,14 @@ describe('PreTDecDecrypter', () => { it('serializes to a plain object', async () => { const { deployedStrategy } = await makeDeployedPreStrategy(); const asObj = deployedStrategy.decrypter.toObj(); - const fromJson = PreTDecDecrypter.fromObj(asObj); + const fromJson = PreDecrypter.fromObj(asObj); expect(fromJson.equals(deployedStrategy.decrypter)).toBeTruthy(); }); it('serializes to JSON', async () => { const { deployedStrategy } = await makeDeployedPreStrategy(); const asJson = deployedStrategy.decrypter.toJSON(); - const fromJson = PreTDecDecrypter.fromJSON(asJson); + const fromJson = PreDecrypter.fromJSON(asJson); expect(fromJson.equals(deployedStrategy.decrypter)).toBeTruthy(); }); }); diff --git a/test/utils.ts b/test/utils.ts index b4095fbe8..f32f6bf78 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -43,7 +43,7 @@ import { DkgParticipant, DkgRitualState, } from '../src/agents/coordinator'; -import { CbdTDecDecrypter } from '../src/characters/cbd-recipient'; +import { ThresholdDecrypter } from '../src/characters/cbd-recipient'; import { CbdDecryptResult, GetUrsulasResult, @@ -499,7 +499,7 @@ export const mockCbdDecrypt = ( export const mockRandomSessionStaticSecret = (secret: SessionStaticSecret) => { return jest - .spyOn(CbdTDecDecrypter.prototype as any, 'makeSessionKey') + .spyOn(ThresholdDecrypter.prototype as any, 'makeSessionKey') .mockImplementation(() => secret); }; @@ -535,12 +535,9 @@ export const mockGetExistingRitual = (dkgRitual: DkgRitual) => { export const makeCohort = async (ursulas: Ursula[]) => { const getUrsulasSpy = mockGetUrsulas(ursulas); - const config = { - threshold: 2, - shares: ursulas.length, - porterUri: 'https://_this.should.crash', - }; - const cohort = await Cohort.create(config); + const porterUri = 'https://_this.should.crash'; + const numUrsulas = ursulas.length; + const cohort = await Cohort.create(porterUri, numUrsulas); expect(getUrsulasSpy).toHaveBeenCalled(); return cohort; }; From 2c108550e7f17096eb26ee03dea2b14b8fecfd64 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Thu, 29 Jun 2023 10:15:43 +0200 Subject: [PATCH 05/17] feat!: replaced configuration with raw porter uri --- src/characters/alice.ts | 9 ++++----- src/characters/bob.ts | 12 ++++-------- src/config.ts | 31 +++++++++---------------------- src/index.ts | 3 +-- src/sdk/strategy/pre-strategy.ts | 9 ++------- test/utils.ts | 10 ++++------ 6 files changed, 24 insertions(+), 50 deletions(-) diff --git a/src/characters/alice.ts b/src/characters/alice.ts index 417213b64..e1361989a 100644 --- a/src/characters/alice.ts +++ b/src/characters/alice.ts @@ -6,7 +6,6 @@ import { } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; -import { Configuration } from '../config'; import { Keyring } from '../keyring'; import { BlockchainPolicy, @@ -24,11 +23,11 @@ export class Alice { private readonly keyring: Keyring; private constructor( - config: Configuration, + porterUri: string, secretKey: SecretKey, public readonly web3Provider: ethers.providers.Web3Provider ) { - this.porter = new Porter(config.porterUri); + this.porter = new Porter(porterUri); this.keyring = new Keyring(secretKey); } @@ -41,11 +40,11 @@ export class Alice { } public static fromSecretKey( - config: Configuration, + porterUri: string, secretKey: SecretKey, web3Provider: ethers.providers.Web3Provider ): Alice { - return new Alice(config, secretKey, web3Provider); + return new Alice(porterUri, secretKey, web3Provider); } public getPolicyEncryptingKeyFromLabel(label: string): PublicKey { diff --git a/src/characters/bob.ts b/src/characters/bob.ts index 1ee8606af..2a5533c85 100644 --- a/src/characters/bob.ts +++ b/src/characters/bob.ts @@ -6,7 +6,6 @@ import { Signer, } from '@nucypher/nucypher-core'; -import { Configuration } from '../config'; import { Keyring } from '../keyring'; import { PolicyMessageKit } from '../kits/message'; import { RetrievalResult } from '../kits/retrieval'; @@ -40,8 +39,8 @@ export class Bob { private readonly porter: Porter; private readonly keyring: Keyring; - constructor(config: Configuration, secretKey: SecretKey) { - this.porter = new Porter(config.porterUri); + constructor(porterUri: string, secretKey: SecretKey) { + this.porter = new Porter(porterUri); this.keyring = new Keyring(secretKey); } @@ -57,11 +56,8 @@ export class Bob { return this.keyring.signer; } - public static fromSecretKey( - config: Configuration, - secretKey: SecretKey - ): Bob { - return new Bob(config, secretKey); + public static fromSecretKey(porterUri: string, secretKey: SecretKey): Bob { + return new Bob(porterUri, secretKey); } public decrypt(messageKit: MessageKit | PolicyMessageKit): Uint8Array { diff --git a/src/config.ts b/src/config.ts index 1b59d0c4e..b75f975e4 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,29 +1,16 @@ import { ChainId } from './types'; -export type Configuration = { - readonly porterUri: string; +const PORTER_URIS: { readonly [key in ChainId]: string } = { + // TODO: Make sure these are correct + [ChainId.POLYGON]: 'https://porter.nucypher.community', + [ChainId.MUMBAI]: 'https://porter-tapir.nucypher.community', + [ChainId.GOERLI]: 'https://porter-tapir.nucypher.community', + [ChainId.MAINNET]: 'https://porter.nucypher.io/', }; -const CONFIGS: { readonly [key in ChainId]: Configuration } = { - [ChainId.POLYGON]: { - porterUri: 'https://porter.nucypher.community', - }, - [ChainId.MUMBAI]: { - porterUri: 'https://porter-tapir.nucypher.community', - }, - [ChainId.GOERLI]: { - // TODO: Confirm this is correct - porterUri: 'https://porter-tapir.nucypher.community', - }, - [ChainId.MAINNET]: { - // TODO: Confirm this is correct - porterUri: 'https://porter.nucypher.io/', - }, -}; - -export const defaultConfiguration = (chainId: number): Configuration => { +export const defaultPorterUri = (chainId: number): string => { if (!Object.values(ChainId).includes(chainId)) { - throw new Error(`No default configuration found for chainId: ${chainId}`); + throw new Error(`No default Porter URI found for chainId: ${chainId}`); } - return CONFIGS[chainId as ChainId]; + return PORTER_URIS[chainId as ChainId]; }; diff --git a/src/index.ts b/src/index.ts index d190f58ca..a817b68f4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,8 +16,7 @@ export { PreEnactedPolicy } from './policies/policy'; export { Keyring } from './keyring'; // Configuration -export type { Configuration } from './config'; -export { defaultConfiguration } from './config'; +export { defaultPorterUri } from './config'; // Kits export { PolicyMessageKit } from './kits/message'; diff --git a/src/sdk/strategy/pre-strategy.ts b/src/sdk/strategy/pre-strategy.ts index 01b8f96ac..d7ab66253 100644 --- a/src/sdk/strategy/pre-strategy.ts +++ b/src/sdk/strategy/pre-strategy.ts @@ -76,13 +76,8 @@ export class PreStrategy { } const porterUri = this.cohort.porterUri; - const configuration = { porterUri }; - const alice = Alice.fromSecretKey( - configuration, - this.aliceSecretKey, - provider - ); - const bob = new Bob(configuration, this.bobSecretKey); + const alice = Alice.fromSecretKey(porterUri, this.aliceSecretKey, provider); + const bob = new Bob(porterUri, this.bobSecretKey); const policyParams = { bob, label, diff --git a/test/utils.ts b/test/utils.ts index f32f6bf78..86d735f19 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -37,7 +37,7 @@ import axios from 'axios'; import { ethers, providers, Wallet } from 'ethers'; import { keccak256 } from 'ethers/lib/utils'; -import { Alice, Bob, Cohort, Configuration, RemoteBob } from '../src'; +import { Alice, Bob, Cohort, RemoteBob } from '../src'; import { DkgCoordinatorAgent, DkgParticipant, @@ -63,15 +63,13 @@ export const bytesEqual = (first: Uint8Array, second: Uint8Array): boolean => export const fromBytes = (bytes: Uint8Array): string => new TextDecoder().decode(bytes); -const mockConfig: Configuration = { - porterUri: 'https://_this_should_crash.com/', -}; +const porterUri = 'https://_this_should_crash.com/'; export const fakeBob = (): Bob => { const secretKey = SecretKey.fromBEBytes( toBytes('fake-secret-key-32-bytes-bob-xxx') ); - return Bob.fromSecretKey(mockConfig, secretKey); + return Bob.fromSecretKey(porterUri, secretKey); }; export const fakeRemoteBob = (): RemoteBob => { @@ -82,7 +80,7 @@ export const fakeRemoteBob = (): RemoteBob => { export const fakeAlice = (aliceKey = 'fake-secret-key-32-bytes-alice-x') => { const secretKey = SecretKey.fromBEBytes(toBytes(aliceKey)); const provider = fakeWeb3Provider(secretKey.toBEBytes()); - return Alice.fromSecretKey(mockConfig, secretKey, provider); + return Alice.fromSecretKey(porterUri, secretKey, provider); }; export const fakeWeb3Provider = ( From 61c780d17dba45ba1f7c78a58e679d3ce39a67ae Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Thu, 29 Jun 2023 10:22:32 +0200 Subject: [PATCH 06/17] feat!: porter uris are based on networks, not chain ids --- src/config.ts | 20 ++++++++++---------- src/index.ts | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/config.ts b/src/config.ts index b75f975e4..af7698644 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,16 +1,16 @@ -import { ChainId } from './types'; +type Network = 'mainnet' | 'tapir' | 'oryx' | 'lynx'; -const PORTER_URIS: { readonly [key in ChainId]: string } = { +const PORTER_URIS: Record = { // TODO: Make sure these are correct - [ChainId.POLYGON]: 'https://porter.nucypher.community', - [ChainId.MUMBAI]: 'https://porter-tapir.nucypher.community', - [ChainId.GOERLI]: 'https://porter-tapir.nucypher.community', - [ChainId.MAINNET]: 'https://porter.nucypher.io/', + mainnet: 'https://porter.nucypher.community', + tapir: 'https://porter-tapir.nucypher.community', + oryx: 'https://porter-oryx.nucypher.community', + lynx: 'https://porter-lynx.nucypher.community', }; -export const defaultPorterUri = (chainId: number): string => { - if (!Object.values(ChainId).includes(chainId)) { - throw new Error(`No default Porter URI found for chainId: ${chainId}`); +export const getPorterUri = (network: Network): string => { + if (!Object.values(PORTER_URIS).includes(network)) { + throw new Error(`No default Porter URI found for network: ${network}`); } - return PORTER_URIS[chainId as ChainId]; + return PORTER_URIS[network]; }; diff --git a/src/index.ts b/src/index.ts index a817b68f4..006042f55 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,7 +16,7 @@ export { PreEnactedPolicy } from './policies/policy'; export { Keyring } from './keyring'; // Configuration -export { defaultPorterUri } from './config'; +export { getPorterUri } from './config'; // Kits export { PolicyMessageKit } from './kits/message'; From e443d61a7721288aa4688ba73d0dd74f2fd8c3fb Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Thu, 29 Jun 2023 10:29:47 +0200 Subject: [PATCH 07/17] feat! porter is not a character; renamed to porter client --- src/characters/alice.ts | 6 +++--- src/characters/bob.ts | 7 +++---- src/characters/cbd-recipient.ts | 13 ++++++++----- src/characters/pre-recipient.ts | 9 ++++----- src/index.ts | 2 +- src/policies/policy.ts | 2 +- src/{characters => }/porter.ts | 2 +- src/sdk/cohort.ts | 4 ++-- test/acceptance/alice-grants.test.ts | 2 +- test/docs/cbd.test.ts | 2 +- test/unit/pre-strategy.test.ts | 2 +- test/utils.ts | 18 ++++++++++-------- 12 files changed, 36 insertions(+), 33 deletions(-) rename src/{characters => }/porter.ts (99%) diff --git a/src/characters/alice.ts b/src/characters/alice.ts index e1361989a..fa640f668 100644 --- a/src/characters/alice.ts +++ b/src/characters/alice.ts @@ -13,13 +13,13 @@ import { EnactedPolicy, PreEnactedPolicy, } from '../policies/policy'; +import { PorterClient } from '../porter'; import { ChecksumAddress } from '../types'; import { RemoteBob } from './bob'; -import { Porter } from './porter'; export class Alice { - private readonly porter: Porter; + private readonly porter: PorterClient; private readonly keyring: Keyring; private constructor( @@ -27,7 +27,7 @@ export class Alice { secretKey: SecretKey, public readonly web3Provider: ethers.providers.Web3Provider ) { - this.porter = new Porter(porterUri); + this.porter = new PorterClient(porterUri); this.keyring = new Keyring(secretKey); } diff --git a/src/characters/bob.ts b/src/characters/bob.ts index 2a5533c85..c08a351c6 100644 --- a/src/characters/bob.ts +++ b/src/characters/bob.ts @@ -9,10 +9,9 @@ import { import { Keyring } from '../keyring'; import { PolicyMessageKit } from '../kits/message'; import { RetrievalResult } from '../kits/retrieval'; +import { PorterClient } from '../porter'; import { zip } from '../utils'; -import { Porter } from './porter'; - export class RemoteBob { private constructor( public readonly decryptingKey: PublicKey, @@ -36,11 +35,11 @@ export class RemoteBob { } export class Bob { - private readonly porter: Porter; + private readonly porter: PorterClient; private readonly keyring: Keyring; constructor(porterUri: string, secretKey: SecretKey) { - this.porter = new Porter(porterUri); + this.porter = new PorterClient(porterUri); this.keyring = new Keyring(secretKey); } diff --git a/src/characters/cbd-recipient.ts b/src/characters/cbd-recipient.ts index d86e24185..68ad97b8a 100644 --- a/src/characters/cbd-recipient.ts +++ b/src/characters/cbd-recipient.ts @@ -24,10 +24,9 @@ import { getCombineDecryptionSharesFunction, getVariantClass, } from '../dkg'; +import { PorterClient } from '../porter'; import { fromJSON, toJSON } from '../utils'; -import { Porter } from './porter'; - export type ThresholdDecrypterJSON = { porterUri: string; ritualId: number; @@ -38,14 +37,14 @@ export class ThresholdDecrypter { // private readonly verifyingKey: Keyring; private constructor( - private readonly porter: Porter, + private readonly porter: PorterClient, private readonly ritualId: number, private readonly threshold: number ) {} public static create(porterUri: string, dkgRitual: DkgRitual) { return new ThresholdDecrypter( - new Porter(porterUri), + new PorterClient(porterUri), dkgRitual.id, dkgRitual.dkgParams.threshold ); @@ -224,7 +223,11 @@ export class ThresholdDecrypter { ritualId, threshold, }: ThresholdDecrypterJSON) { - return new ThresholdDecrypter(new Porter(porterUri), ritualId, threshold); + return new ThresholdDecrypter( + new PorterClient(porterUri), + ritualId, + threshold + ); } public static fromJSON(json: string) { diff --git a/src/characters/pre-recipient.ts b/src/characters/pre-recipient.ts index c51edfb8b..2082bbd6a 100644 --- a/src/characters/pre-recipient.ts +++ b/src/characters/pre-recipient.ts @@ -12,10 +12,9 @@ import { ConditionContext, ConditionExpression } from '../conditions'; import { Keyring } from '../keyring'; import { PolicyMessageKit } from '../kits/message'; import { RetrievalResult } from '../kits/retrieval'; +import { PorterClient } from '../porter'; import { base64ToU8Receiver, bytesEquals, toJSON, zip } from '../utils'; -import { Porter } from './porter'; - export type PreDecrypterJSON = { porterUri: string; policyEncryptingKeyBytes: Uint8Array; @@ -28,7 +27,7 @@ export class PreDecrypter { // private readonly verifyingKey: Keyring; constructor( - private readonly porter: Porter, + private readonly porter: PorterClient, private readonly keyring: Keyring, private readonly policyEncryptingKey: PublicKey, private readonly publisherVerifyingKey: PublicKey, @@ -43,7 +42,7 @@ export class PreDecrypter { encryptedTreasureMap: EncryptedTreasureMap ): PreDecrypter { return new PreDecrypter( - new Porter(porterUri), + new PorterClient(porterUri), new Keyring(secretKey), policyEncryptingKey, publisherVerifyingKey, @@ -172,7 +171,7 @@ export class PreDecrypter { bobSecretKeyBytes, }: PreDecrypterJSON) { return new PreDecrypter( - new Porter(porterUri), + new PorterClient(porterUri), new Keyring(SecretKey.fromBEBytes(bobSecretKeyBytes)), PublicKey.fromCompressedBytes(policyEncryptingKeyBytes), PublicKey.fromCompressedBytes(publisherVerifyingKeyBytes), diff --git a/src/index.ts b/src/index.ts index 006042f55..53c61690f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ export { Alice } from './characters/alice'; export { Bob, RemoteBob } from './characters/bob'; export { Enrico } from './characters/enrico'; export { PreDecrypter } from './characters/pre-recipient'; -export { Porter } from './characters/porter'; +export { PorterClient } from './porter'; // Policies export type { diff --git a/src/policies/policy.ts b/src/policies/policy.ts index 6e8c5c87f..14c030c43 100644 --- a/src/policies/policy.ts +++ b/src/policies/policy.ts @@ -10,7 +10,7 @@ import { import { PreSubscriptionManagerAgent } from '../agents/subscription-manager'; import { Alice } from '../characters/alice'; import { RemoteBob } from '../characters/bob'; -import { Ursula } from '../characters/porter'; +import { Ursula } from '../porter'; import { toBytes, toEpoch, zip } from '../utils'; import { toCanonicalAddress } from '../web3'; diff --git a/src/characters/porter.ts b/src/porter.ts similarity index 99% rename from src/characters/porter.ts rename to src/porter.ts index 2a3ef1d6a..f15e8ee0c 100644 --- a/src/characters/porter.ts +++ b/src/porter.ts @@ -96,7 +96,7 @@ export type CbdDecryptResult = { errors: Record; }; -export class Porter { +export class PorterClient { readonly porterUrl: URL; constructor(porterUri: string) { diff --git a/src/sdk/cohort.ts b/src/sdk/cohort.ts index 697f7cb8a..d377a6a4b 100644 --- a/src/sdk/cohort.ts +++ b/src/sdk/cohort.ts @@ -1,4 +1,4 @@ -import { Porter } from '../characters/porter'; +import { PorterClient } from '../porter'; import { ChecksumAddress } from '../types'; import { objectEquals } from '../utils'; @@ -19,7 +19,7 @@ export class Cohort { include: string[] = [], exclude: string[] = [] ) { - const porter = new Porter(porterUri); + const porter = new PorterClient(porterUri); const ursulas = await porter.getUrsulas(numUrsulas, exclude, include); const ursulaAddresses = ursulas.map((ursula) => ursula.checksumAddress); return new Cohort(ursulaAddresses, porterUri); diff --git a/test/acceptance/alice-grants.test.ts b/test/acceptance/alice-grants.test.ts index 5460d43b3..9c16822b8 100644 --- a/test/acceptance/alice-grants.test.ts +++ b/test/acceptance/alice-grants.test.ts @@ -6,7 +6,7 @@ import { } from '@nucypher/nucypher-core'; import { EnactedPolicy, Enrico, MessageKit } from '../../src'; -import { Ursula } from '../../src/characters/porter'; +import { Ursula } from '../../src/porter'; import { ChecksumAddress } from '../../src/types'; import { toBytes } from '../../src/utils'; import { diff --git a/test/docs/cbd.test.ts b/test/docs/cbd.test.ts index 217a45ca0..cffde9aac 100644 --- a/test/docs/cbd.test.ts +++ b/test/docs/cbd.test.ts @@ -2,7 +2,7 @@ import { MessageKit, VerifiedKeyFrag } from '@nucypher/nucypher-core'; import { providers } from 'ethers'; import { Cohort, conditions, PreStrategy, SecretKey } from '../../src'; -import { Ursula } from '../../src/characters/porter'; +import { Ursula } from '../../src/porter'; import { toBytes } from '../../src/utils'; import { fakeUrsulas, diff --git a/test/unit/pre-strategy.test.ts b/test/unit/pre-strategy.test.ts index 2c801b291..6217f3b06 100644 --- a/test/unit/pre-strategy.test.ts +++ b/test/unit/pre-strategy.test.ts @@ -6,7 +6,7 @@ import { PreDecrypter, PreStrategy, } from '../../src'; -import { Ursula } from '../../src/characters/porter'; +import { Ursula } from '../../src/porter'; import { toBytes } from '../../src/utils'; import { fakeUrsulas, diff --git a/test/utils.ts b/test/utils.ts index 86d735f19..965857508 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -44,15 +44,15 @@ import { DkgRitualState, } from '../src/agents/coordinator'; import { ThresholdDecrypter } from '../src/characters/cbd-recipient'; +import { DkgClient, DkgRitual, FerveoVariant } from '../src/dkg'; +import { BlockchainPolicy, PreEnactedPolicy } from '../src/policies/policy'; import { CbdDecryptResult, GetUrsulasResult, - Porter, + PorterClient, RetrieveCFragsResult, Ursula, -} from '../src/characters/porter'; -import { DkgClient, DkgRitual } from '../src/dkg'; -import { BlockchainPolicy, PreEnactedPolicy } from '../src/policies/policy'; +} from '../src/porter'; import { ChecksumAddress } from '../src/types'; import { toBytes, toHexString, zip } from '../src/utils'; @@ -166,7 +166,7 @@ export const mockRetrieveCFragsRequest = ( ) => { const results = fakeCFragResponse(ursulas, verifiedKFrags, capsule); return jest - .spyOn(Porter.prototype, 'retrieveCFrags') + .spyOn(PorterClient.prototype, 'retrieveCFrags') .mockImplementation(() => { return Promise.resolve(results); }); @@ -490,9 +490,11 @@ export const mockCbdDecrypt = ( encryptedResponses, errors, }; - return jest.spyOn(Porter.prototype, 'cbdDecrypt').mockImplementation(() => { - return Promise.resolve(result); - }); + return jest + .spyOn(PorterClient.prototype, 'cbdDecrypt') + .mockImplementation(() => { + return Promise.resolve(result); + }); }; export const mockRandomSessionStaticSecret = (secret: SessionStaticSecret) => { From 8c519c0538121a73da0a6fae4cf34d278267f2ae Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Wed, 2 Aug 2023 10:27:10 +0200 Subject: [PATCH 08/17] use released nucypher-core@0.11.0 package --- package.json | 2 +- yarn.lock | 323 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 206 insertions(+), 119 deletions(-) diff --git a/package.json b/package.json index b2764235b..1c965c118 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "prebuild": "yarn typechain" }, "dependencies": { - "@nucypher/nucypher-core": "file:../nucypher-core/nucypher-core-wasm/pkg", + "@nucypher/nucypher-core": "^0.11.0", "axios": "^0.21.1", "deep-equal": "^2.2.1", "ethers": "^5.4.1", diff --git a/yarn.lock b/yarn.lock index 4ae086ba6..4e46e2b5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -114,10 +114,10 @@ regexpu-core "^5.3.1" semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.1.tgz#af1429c4a83ac316a6a8c2cc8ff45cb5d2998d3a" - integrity sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A== +"@babel/helper-define-polyfill-provider@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz#82c825cadeeeee7aad237618ebbe8fa1710015d7" + integrity sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw== dependencies: "@babel/helper-compilation-targets" "^7.22.6" "@babel/helper-plugin-utils" "^7.22.5" @@ -913,9 +913,9 @@ semver "^6.3.1" "@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" - integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + version "0.1.6" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6.tgz#31bcdd8f19538437339d17af00d177d854d9d458" + integrity sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" @@ -974,10 +974,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@commitlint/config-validator@^17.4.4": - version "17.4.4" - resolved "https://registry.yarnpkg.com/@commitlint/config-validator/-/config-validator-17.4.4.tgz#d0742705719559a101d2ee49c0c514044af6d64d" - integrity sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg== +"@commitlint/config-validator@^17.6.7": + version "17.6.7" + resolved "https://registry.yarnpkg.com/@commitlint/config-validator/-/config-validator-17.6.7.tgz#c664d42a1ecf5040a3bb0843845150f55734df41" + integrity sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ== dependencies: "@commitlint/types" "^17.4.4" ajv "^8.11.0" @@ -988,13 +988,13 @@ integrity sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA== "@commitlint/load@>6.1.1": - version "17.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-17.5.0.tgz#be45dbbb50aaf5eb7e8e940e1e0d6171d1426bab" - integrity sha512-l+4W8Sx4CD5rYFsrhHH8HP01/8jEP7kKf33Xlx2Uk2out/UKoKPYMOIRcDH5ppT8UXLMV+x6Wm5osdRKKgaD1Q== + version "17.6.7" + resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-17.6.7.tgz#c63b18ca8942a8fc095ec7a7ff7aa52f3854f6ba" + integrity sha512-QZ2rJTbX55BQdYrCm/p6+hh/pFBgC9nTJxfsrK6xRPe2thiQzHN0AQDBqBwAirn6gIkHrjIbCbtAE6kiDYLjrw== dependencies: - "@commitlint/config-validator" "^17.4.4" + "@commitlint/config-validator" "^17.6.7" "@commitlint/execute-rule" "^17.4.0" - "@commitlint/resolve-extends" "^17.4.4" + "@commitlint/resolve-extends" "^17.6.7" "@commitlint/types" "^17.4.4" "@types/node" "*" chalk "^4.1.0" @@ -1007,12 +1007,12 @@ ts-node "^10.8.1" typescript "^4.6.4 || ^5.0.0" -"@commitlint/resolve-extends@^17.4.4": - version "17.4.4" - resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-17.4.4.tgz#8f931467dea8c43b9fe38373e303f7c220de6fdc" - integrity sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A== +"@commitlint/resolve-extends@^17.6.7": + version "17.6.7" + resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz#9c53a4601c96ab2dd20b90fb35c988639307735d" + integrity sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg== dependencies: - "@commitlint/config-validator" "^17.4.4" + "@commitlint/config-validator" "^17.6.7" "@commitlint/types" "^17.4.4" import-fresh "^3.0.0" lodash.mergewith "^4.6.2" @@ -1667,11 +1667,6 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@nicolo-ribaudo/semver-v6@^6.3.3": - version "6.3.3" - resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz#ea6d23ade78a325f7a52750aab1526b02b628c29" - integrity sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg== - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1693,8 +1688,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nucypher/nucypher-core@file:../nucypher-core/nucypher-core-wasm/pkg": - version "0.10.0" +"@nucypher/nucypher-core@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@nucypher/nucypher-core/-/nucypher-core-0.11.0.tgz#696663586d0dd70eacfd433a75adc045fba7c24f" + integrity sha512-vr44+Vo1xKH17MHW+bQtm/fzEejVcZ9grSbHVS+KqkTytKbWb8ulX3Uc5AI0gli1FxwNwM5UbfqGE2IRai0dfQ== "@sideway/address@^4.1.3": version "4.1.4" @@ -1866,9 +1863,9 @@ integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== "@types/node@*": - version "20.4.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" - integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== + version "20.4.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.5.tgz#9dc0a5cb1ccce4f7a731660935ab70b9c00a5d69" + integrity sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -2179,6 +2176,17 @@ array-uniq@^1.0.1: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== +array.prototype.findlastindex@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz#bc229aef98f6bd0533a2bc61ff95209875526c9b" + integrity sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.1.3" + array.prototype.flat@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" @@ -2199,6 +2207,18 @@ array.prototype.flatmap@^1.3.1: es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" +arraybuffer.prototype.slice@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" + integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -2274,28 +2294,28 @@ babel-plugin-jest-hoist@^27.5.1: "@types/babel__traverse" "^7.0.6" babel-plugin-polyfill-corejs2@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz#9f9a0e1cd9d645cc246a5e094db5c3aa913ccd2b" - integrity sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA== + version "0.4.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz#8097b4cb4af5b64a1d11332b6fb72ef5e64a054c" + integrity sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg== dependencies: "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.4.1" - "@nicolo-ribaudo/semver-v6" "^6.3.3" + "@babel/helper-define-polyfill-provider" "^0.4.2" + semver "^6.3.1" babel-plugin-polyfill-corejs3@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.2.tgz#d406c5738d298cd9c66f64a94cf8d5904ce4cc5e" - integrity sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ== + version "0.8.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz#b4f719d0ad9bb8e0c23e3e630c0c8ec6dd7a1c52" + integrity sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA== dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.1" + "@babel/helper-define-polyfill-provider" "^0.4.2" core-js-compat "^3.31.0" babel-plugin-polyfill-regenerator@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.1.tgz#ace7a5eced6dff7d5060c335c52064778216afd3" - integrity sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw== + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz#80d0f3e1098c080c8b5a65f41e9427af692dc326" + integrity sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA== dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.1" + "@babel/helper-define-polyfill-provider" "^0.4.2" babel-preset-current-node-syntax@^1.0.0: version "1.0.1" @@ -2390,13 +2410,13 @@ browser-process-hrtime@^1.0.0: integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== browserslist@^4.21.9: - version "4.21.9" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" - integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== + version "4.21.10" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" + integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== dependencies: - caniuse-lite "^1.0.30001503" - electron-to-chromium "^1.4.431" - node-releases "^2.0.12" + caniuse-lite "^1.0.30001517" + electron-to-chromium "^1.4.477" + node-releases "^2.0.13" update-browserslist-db "^1.0.11" bs-logger@0.x: @@ -2463,10 +2483,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001503: - version "1.0.30001515" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001515.tgz#418aefeed9d024cd3129bfae0ccc782d4cb8f12b" - integrity sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA== +caniuse-lite@^1.0.30001517: + version "1.0.30001518" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001518.tgz#b3ca93904cb4699c01218246c4d77a71dbe97150" + integrity sha512-rup09/e3I0BKjncL+FesTayKtPrdwKhUufQFd3riFw1hHg8JmIFoInYfB102cFcY/pPgGmdyl/iy+jgiDi2vdA== chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" @@ -2824,9 +2844,9 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== core-js-compat@^3.31.0: - version "3.31.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.1.tgz#5084ad1a46858df50ff89ace152441a63ba7aae0" - integrity sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA== + version "3.32.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.0.tgz#f41574b6893ab15ddb0ac1693681bd56c8550a90" + integrity sha512-7a9a3D1k4UCVKnLhrgALyFcP7YCsLOQIxPd0dKjf/6GuPcgyiGP70ewWdCGrSK7evyhymi0qO4EqCmSJofDeYw== dependencies: browserslist "^4.21.9" @@ -2836,9 +2856,9 @@ core-util-is@~1.0.0: integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cosmiconfig-typescript-loader@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz#c4259ce474c9df0f32274ed162c0447c951ef073" - integrity sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q== + version "4.4.0" + resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz#f3feae459ea090f131df5474ce4b1222912319f9" + integrity sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw== cosmiconfig@^8.0.0: version "8.2.0" @@ -3094,10 +3114,10 @@ dotgitignore@^2.1.0: find-up "^3.0.0" minimatch "^3.0.4" -electron-to-chromium@^1.4.431: - version "1.4.459" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.459.tgz#25a23370f4ae8aaa8f77aaf00133aa4994f4148e" - integrity sha512-XXRS5NFv8nCrBL74Rm3qhJjA2VCsRFx0OjHKBMPI0otij56aun8UWiKTDABmd5/7GTR021pA4wivs+Ri6XCElg== +electron-to-chromium@^1.4.477: + version "1.4.480" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.480.tgz#40e32849ca50bc23ce29c1516c5adb3fddac919d" + integrity sha512-IXTgg+bITkQv/FLP9FjX6f9KFCs5hQWeh5uNSKxB9mqYj/JXhHDbu+ekS43LVvbkL3eW6/oZy4+r9Om6lan1Uw== elliptic@6.5.4: version "6.5.4" @@ -3128,11 +3148,12 @@ emoji-regex@^8.0.0: integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== dependencies: ansi-colors "^4.1.1" + strip-ansi "^6.0.1" error-ex@^1.3.1: version "1.3.2" @@ -3141,12 +3162,13 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.3.tgz#8aaa0ffc080e8a6fef6ace72631dc1ec5d47bf94" - integrity sha512-ZU4miiY1j3sGPFLJ34VJXEqhpmL+HGByCinGHv4HC+Fxl2fI2Z4yR6tl0mORnDr6PA8eihWo4LmSWDbvhALckg== +es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: + version "1.22.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" + integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== dependencies: array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.1" available-typed-arrays "^1.0.5" call-bind "^1.0.2" es-set-tostringtag "^2.0.1" @@ -3173,10 +3195,13 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: object-keys "^1.1.1" object.assign "^4.1.4" regexp.prototype.flags "^1.5.0" + safe-array-concat "^1.0.0" safe-regex-test "^1.0.0" string.prototype.trim "^1.2.7" string.prototype.trimend "^1.0.6" string.prototype.trimstart "^1.0.6" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" @@ -3269,7 +3294,7 @@ eslint-import-resolver-node@^0.3.7: is-core-module "^2.11.0" resolve "^1.22.1" -eslint-module-utils@^2.7.4: +eslint-module-utils@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== @@ -3285,25 +3310,28 @@ eslint-plugin-eslint-comments@^3.2.0: ignore "^5.0.5" eslint-plugin-import@^2.22.0: - version "2.27.5" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" - integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== + version "2.28.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.28.0.tgz#8d66d6925117b06c4018d491ae84469eb3cb1005" + integrity sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q== dependencies: array-includes "^3.1.6" + array.prototype.findlastindex "^1.2.2" array.prototype.flat "^1.3.1" array.prototype.flatmap "^1.3.1" debug "^3.2.7" doctrine "^2.1.0" eslint-import-resolver-node "^0.3.7" - eslint-module-utils "^2.7.4" + eslint-module-utils "^2.8.0" has "^1.0.3" - is-core-module "^2.11.0" + is-core-module "^2.12.1" is-glob "^4.0.3" minimatch "^3.1.2" + object.fromentries "^2.0.6" + object.groupby "^1.0.0" object.values "^1.1.6" - resolve "^1.22.1" - semver "^6.3.0" - tsconfig-paths "^3.14.1" + resolve "^1.22.3" + semver "^6.3.1" + tsconfig-paths "^3.14.2" eslint-scope@^5.1.1: version "5.1.1" @@ -3514,9 +3542,9 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.2.9: - version "3.3.0" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.0.tgz#7c40cb491e1e2ed5664749e87bfb516dbe8727c0" - integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA== + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -3976,12 +4004,12 @@ graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== dependencies: minimist "^1.2.5" - neo-async "^2.6.0" + neo-async "^2.6.2" source-map "^0.6.1" wordwrap "^1.0.0" optionalDependencies: @@ -4251,7 +4279,7 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.11.0, is-core-module@^2.5.0: +is-core-module@^2.11.0, is-core-module@^2.12.0, is-core-module@^2.12.1, is-core-module@^2.5.0: version "2.12.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== @@ -4381,15 +4409,11 @@ is-text-path@^1.0.1: text-extensions "^1.0.0" is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" + which-typed-array "^1.1.11" is-typedarray@^1.0.0: version "1.0.0" @@ -4470,12 +4494,12 @@ istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: semver "^6.3.0" istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" + make-dir "^4.0.0" supports-color "^7.1.0" istanbul-lib-source-maps@^4.0.0: @@ -4488,9 +4512,9 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.1.3: - version "3.1.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" - integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -5229,6 +5253,13 @@ make-dir@^3.0.0, make-dir@^3.0.2: dependencies: semver "^6.0.0" +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + make-error@1.x, make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" @@ -5413,7 +5444,7 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -neo-async@^2.6.0: +neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -5428,7 +5459,7 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.12: +node-releases@^2.0.13: version "2.0.13" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== @@ -5518,6 +5549,25 @@ object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" +object.fromentries@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" + integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.groupby@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.0.tgz#cb29259cf90f37e7bac6437686c1ea8c916d12a9" + integrity sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.21.2" + get-intrinsic "^1.2.1" + object.values@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" @@ -6065,6 +6115,15 @@ resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.1: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.22.3: + version "1.22.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.3.tgz#4b4055349ffb962600972da1fdc33c46a4eb3283" + integrity sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw== + dependencies: + is-core-module "^2.12.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" @@ -6104,6 +6163,16 @@ rxjs@^7.5.5: dependencies: tslib "^2.1.0" +safe-array-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" + integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -6145,7 +6214,7 @@ scrypt-js@3.0.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@7.x, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.5.2: +semver@7.x, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.5.2, semver@^7.5.3: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -6696,7 +6765,7 @@ ts-unused-exports@^8.0.0: chalk "^4.0.0" tsconfig-paths "^3.9.0" -tsconfig-paths@^3.14.1, tsconfig-paths@^3.9.0: +tsconfig-paths@^3.14.2, tsconfig-paths@^3.9.0: version "3.14.2" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== @@ -6712,9 +6781,9 @@ tslib@^1.8.1: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.1.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" - integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== + version "2.6.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" + integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== tsutils@^3.21.0: version "3.21.0" @@ -6781,6 +6850,25 @@ typechain@^7.0.0: ts-command-line-args "^2.2.0" ts-essentials "^7.0.1" +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + typed-array-byte-offset@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" @@ -7052,17 +7140,16 @@ which-collection@^1.0.1: is-weakmap "^2.0.1" is-weakset "^2.0.1" -which-typed-array@^1.1.10, which-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.10.tgz#74baa2789991905c2076abb317103b866c64e69e" - integrity sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA== +which-typed-array@^1.1.10, which-typed-array@^1.1.11, which-typed-array@^1.1.9: + version "1.1.11" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" + integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== dependencies: available-typed-arrays "^1.0.5" call-bind "^1.0.2" for-each "^0.3.3" gopd "^1.0.1" has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" which@^1.2.14, which@^1.2.9: version "1.3.1" @@ -7079,9 +7166,9 @@ which@^2.0.1: isexe "^2.0.0" word-wrap@^1.0.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== wordwrap@^1.0.0: version "1.0.0" From e5c8c0277dd73159c7df0cc7b666e8ed92d17da6 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Thu, 29 Jun 2023 11:06:23 +0200 Subject: [PATCH 09/17] feat! remove porter uri and web3 provider from character constructors --- src/characters/alice.ts | 40 +++++++++++++--------------- src/config.ts | 3 ++- src/policies/policy.ts | 24 +++++++++++------ src/sdk/strategy/pre-strategy.ts | 17 +++++++----- test/acceptance/alice-grants.test.ts | 5 +++- test/acceptance/delay-enact.test.ts | 16 ++++++----- test/docs/cbd.test.ts | 10 +++++-- test/utils.ts | 7 +++-- 8 files changed, 72 insertions(+), 50 deletions(-) diff --git a/src/characters/alice.ts b/src/characters/alice.ts index fa640f668..dfe06d02f 100644 --- a/src/characters/alice.ts +++ b/src/characters/alice.ts @@ -19,15 +19,9 @@ import { ChecksumAddress } from '../types'; import { RemoteBob } from './bob'; export class Alice { - private readonly porter: PorterClient; private readonly keyring: Keyring; - private constructor( - porterUri: string, - secretKey: SecretKey, - public readonly web3Provider: ethers.providers.Web3Provider - ) { - this.porter = new PorterClient(porterUri); + private constructor(secretKey: SecretKey) { this.keyring = new Keyring(secretKey); } @@ -39,12 +33,8 @@ export class Alice { return this.keyring.signer; } - public static fromSecretKey( - porterUri: string, - secretKey: SecretKey, - web3Provider: ethers.providers.Web3Provider - ): Alice { - return new Alice(porterUri, secretKey, web3Provider); + public static fromSecretKey(secretKey: SecretKey): Alice { + return new Alice(secretKey); } public getPolicyEncryptingKeyFromLabel(label: string): PublicKey { @@ -52,30 +42,36 @@ export class Alice { } public async grant( + web3Provider: ethers.providers.Web3Provider, + porterUri: string, policyParameters: BlockchainPolicyParameters, includeUrsulas?: readonly ChecksumAddress[], excludeUrsulas?: readonly ChecksumAddress[] ): Promise { - const ursulas = await this.porter.getUrsulas( + const porter = new PorterClient(porterUri); + const ursulas = await porter.getUrsulas( policyParameters.shares, excludeUrsulas, includeUrsulas ); - const policy = await this.createPolicy(policyParameters); - return await policy.enact(ursulas); + const policy = await this.createPolicy(web3Provider, policyParameters); + return await policy.enact(web3Provider, ursulas); } public async generatePreEnactedPolicy( + web3Provider: ethers.providers.Web3Provider, + porterUri: string, policyParameters: BlockchainPolicyParameters, includeUrsulas?: readonly ChecksumAddress[], excludeUrsulas?: readonly ChecksumAddress[] ): Promise { - const ursulas = await this.porter.getUrsulas( + const porter = new PorterClient(porterUri); + const ursulas = await porter.getUrsulas( policyParameters.shares, excludeUrsulas, includeUrsulas ); - const policy = await this.createPolicy(policyParameters); + const policy = await this.createPolicy(web3Provider, policyParameters); return await policy.generatePreEnactedPolicy(ursulas); } @@ -98,10 +94,11 @@ export class Alice { } private async createPolicy( + web3Provider: ethers.providers.Web3Provider, rawParameters: BlockchainPolicyParameters ): Promise { const { bob, label, threshold, shares, startDate, endDate } = - await this.validatePolicyParameters(rawParameters); + await this.validatePolicyParameters(web3Provider, rawParameters); const { delegatingKey, verifiedKFrags } = this.generateKFrags( bob, label, @@ -122,6 +119,7 @@ export class Alice { } private async validatePolicyParameters( + web3Provider: ethers.providers.Web3Provider, rawParams: BlockchainPolicyParameters ): Promise { const startDate = rawParams.startDate ?? new Date(); @@ -143,8 +141,8 @@ export class Alice { ); } - const blockNumber = await this.web3Provider.getBlockNumber(); - const block = await this.web3Provider.getBlock(blockNumber); + const blockNumber = await web3Provider.getBlockNumber(); + const block = await web3Provider.getBlock(blockNumber); const blockTime = new Date(block.timestamp * 1000); if (endDate < blockTime) { throw new Error( diff --git a/src/config.ts b/src/config.ts index af7698644..4ffd252a6 100644 --- a/src/config.ts +++ b/src/config.ts @@ -9,7 +9,8 @@ const PORTER_URIS: Record = { }; export const getPorterUri = (network: Network): string => { - if (!Object.values(PORTER_URIS).includes(network)) { + const uri = PORTER_URIS[network]; + if (!uri) { throw new Error(`No default Porter URI found for network: ${network}`); } return PORTER_URIS[network]; diff --git a/src/policies/policy.ts b/src/policies/policy.ts index 14c030c43..00c62003a 100644 --- a/src/policies/policy.ts +++ b/src/policies/policy.ts @@ -6,6 +6,7 @@ import { TreasureMap, VerifiedKeyFrag, } from '@nucypher/nucypher-core'; +import { ethers } from 'ethers'; import { PreSubscriptionManagerAgent } from '../agents/subscription-manager'; import { Alice } from '../characters/alice'; @@ -40,26 +41,30 @@ export class PreEnactedPolicy implements IPreEnactedPolicy { public readonly endTimestamp: Date ) {} - public async enact(publisher: Alice): Promise { - const txHash = await this.publish(publisher); + public async enact( + web3Provider: ethers.providers.Web3Provider + ): Promise { + const txHash = await this.publish(web3Provider); return { ...this, txHash, }; } - private async publish(publisher: Alice): Promise { + private async publish( + web3Provider: ethers.providers.Web3Provider + ): Promise { const startTimestamp = toEpoch(this.startTimestamp); const endTimestamp = toEpoch(this.endTimestamp); - const ownerAddress = await publisher.web3Provider.getSigner().getAddress(); + const ownerAddress = await web3Provider.getSigner().getAddress(); const value = await PreSubscriptionManagerAgent.getPolicyCost( - publisher.web3Provider, + web3Provider, this.size, startTimestamp, endTimestamp ); const tx = await PreSubscriptionManagerAgent.createPolicy( - publisher.web3Provider, + web3Provider, value, this.id.toBytes(), this.size, @@ -101,9 +106,12 @@ export class BlockchainPolicy { ); } - public async enact(ursulas: readonly Ursula[]): Promise { + public async enact( + web3Provider: ethers.providers.Web3Provider, + ursulas: readonly Ursula[] + ): Promise { const preEnacted = await this.generatePreEnactedPolicy(ursulas); - return await preEnacted.enact(this.publisher); + return await preEnacted.enact(web3Provider); } public async generatePreEnactedPolicy( diff --git a/src/sdk/strategy/pre-strategy.ts b/src/sdk/strategy/pre-strategy.ts index d7ab66253..f6695973b 100644 --- a/src/sdk/strategy/pre-strategy.ts +++ b/src/sdk/strategy/pre-strategy.ts @@ -62,13 +62,11 @@ export class PreStrategy { } public async deploy( - provider: ethers.providers.Web3Provider, + web3Provider: ethers.providers.Web3Provider, label: string, - threshold?: number, - shares?: number + threshold = Math.floor(this.cohort.numUrsulas / 2) + 1, + shares = this.cohort.numUrsulas ): Promise { - shares = shares || this.cohort.numUrsulas; - threshold = threshold || Math.floor(shares / 2) + 1; if (shares > this.cohort.numUrsulas) { throw new Error( `Threshold ${threshold} cannot be greater than the number of Ursulas in the cohort ${this.cohort.numUrsulas}` @@ -76,7 +74,7 @@ export class PreStrategy { } const porterUri = this.cohort.porterUri; - const alice = Alice.fromSecretKey(porterUri, this.aliceSecretKey, provider); + const alice = Alice.fromSecretKey(this.aliceSecretKey); const bob = new Bob(porterUri, this.bobSecretKey); const policyParams = { bob, @@ -86,7 +84,12 @@ export class PreStrategy { startDate: this.startDate, endDate: this.endDate, }; - const policy = await alice.grant(policyParams, this.cohort.ursulaAddresses); + const policy = await alice.grant( + web3Provider, + porterUri, + policyParams, + this.cohort.ursulaAddresses + ); return DeployedPreStrategy.create(this.cohort, policy, this.bobSecretKey); } diff --git a/test/acceptance/alice-grants.test.ts b/test/acceptance/alice-grants.test.ts index 9c16822b8..868194ff2 100644 --- a/test/acceptance/alice-grants.test.ts +++ b/test/acceptance/alice-grants.test.ts @@ -13,8 +13,10 @@ import { bytesEqual, fakeAlice, fakeBob, + fakePorterUri, fakeRemoteBob, fakeUrsulas, + fakeWeb3Provider, fromBytes, mockEncryptTreasureMap, mockGenerateKFrags, @@ -32,6 +34,7 @@ describe('story: alice shares message with bob through policy', () => { const startDate = new Date(); const endDate = new Date(Date.now() + 60 * 1000); const mockedUrsulas = fakeUrsulas(shares); + const web3Provider = fakeWeb3Provider(); // Intermediate variables used for mocking let encryptedTreasureMap: EncryptedTreasureMap; @@ -62,7 +65,7 @@ describe('story: alice shares message with bob through policy', () => { startDate, endDate, }; - policy = await alice.grant(policyParams); + policy = await alice.grant(web3Provider, fakePorterUri, policyParams); expect( bytesEqual( diff --git a/test/acceptance/delay-enact.test.ts b/test/acceptance/delay-enact.test.ts index 857e0e9f0..ac0183072 100644 --- a/test/acceptance/delay-enact.test.ts +++ b/test/acceptance/delay-enact.test.ts @@ -1,21 +1,24 @@ import { bytesEqual, fakeAlice, + fakePorterUri, fakeRemoteBob, fakeUrsulas, + fakeWeb3Provider, mockEncryptTreasureMap, mockGenerateKFrags, mockGetUrsulas, mockPublishToBlockchain, } from '../utils'; -describe('story: alice1 creates a policy but alice2 enacts it', () => { +describe('story: alice creates a policy but someone else enacts it', () => { const threshold = 2; const shares = 3; const startDate = new Date(); const endDate = new Date(Date.now() + 60 * 1000); // 60s later const mockedUrsulas = fakeUrsulas(shares); const label = 'fake-data-label'; + const web3Provider = fakeWeb3Provider(); it('alice generates a new policy', async () => { const getUrsulasSpy = mockGetUrsulas(mockedUrsulas); @@ -23,8 +26,7 @@ describe('story: alice1 creates a policy but alice2 enacts it', () => { const publishToBlockchainSpy = mockPublishToBlockchain(); const encryptTreasureMapSpy = mockEncryptTreasureMap(); - const alice1 = fakeAlice('fake-secret-key-32-bytes-alice-1'); - const alice2 = fakeAlice('fake-secret-key-32-bytes-alice-2'); + const alice = fakeAlice('fake-secret-key-32-bytes-alice-1'); const bob = fakeRemoteBob(); const policyParams = { bob, @@ -35,18 +37,20 @@ describe('story: alice1 creates a policy but alice2 enacts it', () => { endDate, }; - const preEnactedPolicy = await alice1.generatePreEnactedPolicy( + const preEnactedPolicy = await alice.generatePreEnactedPolicy( + web3Provider, + fakePorterUri, policyParams ); expect( bytesEqual( preEnactedPolicy.aliceVerifyingKey.toCompressedBytes(), - alice1.verifyingKey.toCompressedBytes() + alice.verifyingKey.toCompressedBytes() ) ).toBeTruthy(); expect(preEnactedPolicy.label).toBe(label); - const enacted = await preEnactedPolicy.enact(alice2); + const enacted = await preEnactedPolicy.enact(web3Provider); expect(enacted.txHash).toBeDefined(); expect(getUrsulasSpy).toHaveBeenCalled(); diff --git a/test/docs/cbd.test.ts b/test/docs/cbd.test.ts index cffde9aac..e657827c7 100644 --- a/test/docs/cbd.test.ts +++ b/test/docs/cbd.test.ts @@ -1,7 +1,13 @@ import { MessageKit, VerifiedKeyFrag } from '@nucypher/nucypher-core'; import { providers } from 'ethers'; -import { Cohort, conditions, PreStrategy, SecretKey } from '../../src'; +import { + Cohort, + conditions, + getPorterUri, + PreStrategy, + SecretKey, +} from '../../src'; import { Ursula } from '../../src/porter'; import { toBytes } from '../../src/utils'; import { @@ -60,7 +66,7 @@ describe('Get Started (CBD PoC)', () => { // // 2. Build a Cohort - const porterUri = 'https://porter-tapir.nucypher.community'; + const porterUri = getPorterUri('tapir'); const numUrsulas = 5; const newCohort = await Cohort.create(porterUri, numUrsulas); diff --git a/test/utils.ts b/test/utils.ts index 965857508..04b2cd634 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -63,13 +63,13 @@ export const bytesEqual = (first: Uint8Array, second: Uint8Array): boolean => export const fromBytes = (bytes: Uint8Array): string => new TextDecoder().decode(bytes); -const porterUri = 'https://_this_should_crash.com/'; +export const fakePorterUri = 'https://_this_should_crash.com/'; export const fakeBob = (): Bob => { const secretKey = SecretKey.fromBEBytes( toBytes('fake-secret-key-32-bytes-bob-xxx') ); - return Bob.fromSecretKey(porterUri, secretKey); + return Bob.fromSecretKey(fakePorterUri, secretKey); }; export const fakeRemoteBob = (): RemoteBob => { @@ -79,8 +79,7 @@ export const fakeRemoteBob = (): RemoteBob => { export const fakeAlice = (aliceKey = 'fake-secret-key-32-bytes-alice-x') => { const secretKey = SecretKey.fromBEBytes(toBytes(aliceKey)); - const provider = fakeWeb3Provider(secretKey.toBEBytes()); - return Alice.fromSecretKey(porterUri, secretKey, provider); + return Alice.fromSecretKey(secretKey); }; export const fakeWeb3Provider = ( From aaf2f36560e045b145455ade890d4522a7b8921e Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Thu, 29 Jun 2023 18:53:41 +0200 Subject: [PATCH 10/17] apply pr suggestions --- src/characters/bob.ts | 14 ++++++---- src/config.ts | 17 ----------- src/dkg.ts | 42 +++++++++++++++------------- src/index.ts | 4 +-- src/porter.ts | 18 ++++++++++++ src/sdk/strategy/pre-strategy.ts | 2 +- test/acceptance/alice-grants.test.ts | 1 + test/unit/pre-strategy.test.ts | 2 +- test/utils.ts | 2 +- 9 files changed, 54 insertions(+), 48 deletions(-) delete mode 100644 src/config.ts diff --git a/src/characters/bob.ts b/src/characters/bob.ts index c08a351c6..1959c77da 100644 --- a/src/characters/bob.ts +++ b/src/characters/bob.ts @@ -35,11 +35,9 @@ export class RemoteBob { } export class Bob { - private readonly porter: PorterClient; private readonly keyring: Keyring; - constructor(porterUri: string, secretKey: SecretKey) { - this.porter = new PorterClient(porterUri); + constructor(secretKey: SecretKey) { this.keyring = new Keyring(secretKey); } @@ -55,8 +53,8 @@ export class Bob { return this.keyring.signer; } - public static fromSecretKey(porterUri: string, secretKey: SecretKey): Bob { - return new Bob(porterUri, secretKey); + public static fromSecretKey(secretKey: SecretKey): Bob { + return new Bob(secretKey); } public decrypt(messageKit: MessageKit | PolicyMessageKit): Uint8Array { @@ -64,12 +62,14 @@ export class Bob { } public async retrieveAndDecrypt( + porterUri: string, policyEncryptingKey: PublicKey, publisherVerifyingKey: PublicKey, messageKits: readonly MessageKit[], encryptedTreasureMap: EncryptedTreasureMap ): Promise { const policyMessageKits = await this.retrieve( + porterUri, policyEncryptingKey, publisherVerifyingKey, messageKits, @@ -98,6 +98,7 @@ export class Bob { } public async retrieve( + porterUri: string, policyEncryptingKey: PublicKey, publisherVerifyingKey: PublicKey, messageKits: readonly MessageKit[], @@ -117,7 +118,8 @@ export class Bob { ); const retrievalKits = policyMessageKits.map((pk) => pk.asRetrievalKit()); - const retrieveCFragsResponses = await this.porter.retrieveCFrags( + const porter = new PorterClient(porterUri); + const retrieveCFragsResponses = await porter.retrieveCFrags( treasureMap, retrievalKits, publisherVerifyingKey, diff --git a/src/config.ts b/src/config.ts deleted file mode 100644 index 4ffd252a6..000000000 --- a/src/config.ts +++ /dev/null @@ -1,17 +0,0 @@ -type Network = 'mainnet' | 'tapir' | 'oryx' | 'lynx'; - -const PORTER_URIS: Record = { - // TODO: Make sure these are correct - mainnet: 'https://porter.nucypher.community', - tapir: 'https://porter-tapir.nucypher.community', - oryx: 'https://porter-oryx.nucypher.community', - lynx: 'https://porter-lynx.nucypher.community', -}; - -export const getPorterUri = (network: Network): string => { - const uri = PORTER_URIS[network]; - if (!uri) { - throw new Error(`No default Porter URI found for network: ${network}`); - } - return PORTER_URIS[network]; -}; diff --git a/src/dkg.ts b/src/dkg.ts index f5def34ec..651b14a36 100644 --- a/src/dkg.ts +++ b/src/dkg.ts @@ -14,7 +14,7 @@ import { ChecksumAddress } from './types'; import { bytesEquals, fromHexString, objectEquals } from './utils'; export function getVariantClass( - variant: FerveoVariant + variant: FerveoVariant, ): typeof DecryptionShareSimple | typeof DecryptionSharePrecomputed { if (variant.equals(FerveoVariant.simple)) { return DecryptionShareSimple; @@ -26,9 +26,9 @@ export function getVariantClass( } export function getCombineDecryptionSharesFunction( - variant: FerveoVariant + variant: FerveoVariant, ): ( - shares: DecryptionShareSimple[] | DecryptionSharePrecomputed[] + shares: DecryptionShareSimple[] | DecryptionSharePrecomputed[], ) => SharedSecret { if (variant.equals(FerveoVariant.simple)) { return combineDecryptionSharesSimple; @@ -56,8 +56,9 @@ export class DkgRitual { public readonly id: number, public readonly dkgPublicKey: DkgPublicKey, public readonly dkgParams: DkgRitualParameters, - public readonly state: DkgRitualState - ) {} + public readonly state: DkgRitualState, + ) { + } public toObj(): DkgRitualJSON { return { @@ -69,16 +70,16 @@ export class DkgRitual { } public static fromObj({ - id, - dkgPublicKey, - dkgParams, - state, - }: DkgRitualJSON): DkgRitual { + id, + dkgPublicKey, + dkgParams, + state, + }: DkgRitualJSON): DkgRitual { return new DkgRitual( id, DkgPublicKey.fromBytes(dkgPublicKey), dkgParams, - state + state, ); } @@ -102,25 +103,25 @@ export class DkgClient { public static async initializeRitual( web3Provider: ethers.providers.Web3Provider, ursulas: ChecksumAddress[], - waitUntilEnd = false + waitUntilEnd = false, ): Promise { const ritualId = await DkgCoordinatorAgent.initializeRitual( web3Provider, - ursulas.sort() + ursulas.sort(), ); if (waitUntilEnd) { const isSuccessful = await DkgClient.waitUntilRitualEnd( web3Provider, - ritualId + ritualId, ); if (!isSuccessful) { const ritualState = await DkgCoordinatorAgent.getRitualState( web3Provider, - ritualId + ritualId, ); throw new Error( - `Ritual initialization failed. Ritual id ${ritualId} is in state ${ritualState}` + `Ritual initialization failed. Ritual id ${ritualId} is in state ${ritualState}`, ); } } @@ -130,7 +131,7 @@ export class DkgClient { private static waitUntilRitualEnd = async ( web3Provider: ethers.providers.Web3Provider, - ritualId: number + ritualId: number, ): Promise => { return new Promise((resolve, reject) => { const callback = (successful: boolean) => { @@ -146,11 +147,11 @@ export class DkgClient { public static async getExistingRitual( web3Provider: ethers.providers.Web3Provider, - ritualId: number + ritualId: number, ): Promise { const ritualState = await DkgCoordinatorAgent.getRitualState( web3Provider, - ritualId + ritualId, ); const ritual = await DkgCoordinatorAgent.getRitual(web3Provider, ritualId); const dkgPkBytes = new Uint8Array([ @@ -164,10 +165,11 @@ export class DkgClient { sharesNum: ritual.dkgSize, threshold: assumedThreshold(ritual.dkgSize), }, - ritualState + ritualState, ); } + // TODO: Without Validator public key in Coordinator, we cannot verify the // transcript. We need to add it to the Coordinator (nucypher-contracts #77). // public async verifyRitual(ritualId: number): Promise { diff --git a/src/index.ts b/src/index.ts index 53c61690f..0045b30bc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,8 +15,8 @@ export { PreEnactedPolicy } from './policies/policy'; // Keyring export { Keyring } from './keyring'; -// Configuration -export { getPorterUri } from './config'; +// Porter +export { getPorterUri } from './porter'; // Kits export { PolicyMessageKit } from './kits/message'; diff --git a/src/porter.ts b/src/porter.ts index f15e8ee0c..08ae446b7 100644 --- a/src/porter.ts +++ b/src/porter.ts @@ -12,6 +12,24 @@ import qs from 'qs'; import { Base64EncodedBytes, ChecksumAddress, HexEncodedBytes } from '../types'; import { fromBase64, fromHexString, toBase64, toHexString } from '../utils'; +type Network = 'mainnet' | 'tapir' | 'oryx' | 'lynx'; + +const PORTER_URIS: Record = { + // TODO: Make sure these are correct + mainnet: 'https://porter.nucypher.community', + tapir: 'https://porter-tapir.nucypher.community', + oryx: 'https://porter-oryx.nucypher.community', + lynx: 'https://porter-lynx.nucypher.community', +}; + +export const getPorterUri = (network: Network): string => { + const uri = PORTER_URIS[network]; + if (!uri) { + throw new Error(`No default Porter URI found for network: ${network}`); + } + return PORTER_URIS[network]; +}; + // /get_ursulas export type Ursula = { diff --git a/src/sdk/strategy/pre-strategy.ts b/src/sdk/strategy/pre-strategy.ts index f6695973b..0ef97681d 100644 --- a/src/sdk/strategy/pre-strategy.ts +++ b/src/sdk/strategy/pre-strategy.ts @@ -75,7 +75,7 @@ export class PreStrategy { const porterUri = this.cohort.porterUri; const alice = Alice.fromSecretKey(this.aliceSecretKey); - const bob = new Bob(porterUri, this.bobSecretKey); + const bob = new Bob(this.bobSecretKey); const policyParams = { bob, label, diff --git a/test/acceptance/alice-grants.test.ts b/test/acceptance/alice-grants.test.ts index 868194ff2..9600e7582 100644 --- a/test/acceptance/alice-grants.test.ts +++ b/test/acceptance/alice-grants.test.ts @@ -107,6 +107,7 @@ describe('story: alice shares message with bob through policy', () => { ); const retrievedMessage = await bob.retrieveAndDecrypt( + fakePorterUri, policyEncryptingKey, aliceVerifyingKey, [encryptedMessage], diff --git a/test/unit/pre-strategy.test.ts b/test/unit/pre-strategy.test.ts index 6217f3b06..daee95dae 100644 --- a/test/unit/pre-strategy.test.ts +++ b/test/unit/pre-strategy.test.ts @@ -151,7 +151,7 @@ describe('PreDeployedStrategy', () => { }); }); -describe('PreTDecDecrypter', () => { +describe('PreDecrypter', () => { it('serializes to a plain object', async () => { const { deployedStrategy } = await makeDeployedPreStrategy(); const asObj = deployedStrategy.decrypter.toObj(); diff --git a/test/utils.ts b/test/utils.ts index 04b2cd634..c6cd1e4ff 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -69,7 +69,7 @@ export const fakeBob = (): Bob => { const secretKey = SecretKey.fromBEBytes( toBytes('fake-secret-key-32-bytes-bob-xxx') ); - return Bob.fromSecretKey(fakePorterUri, secretKey); + return Bob.fromSecretKey(secretKey); }; export const fakeRemoteBob = (): RemoteBob => { From e8c247be3177ad7ef16bad3e4dc97e0a3c626f66 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Fri, 30 Jun 2023 13:58:02 +0200 Subject: [PATCH 11/17] refactor: simplify equals method in protocol objects --- src/characters/pre-recipient.ts | 18 +++++++----------- src/conditions/condition-expr.ts | 8 ++++---- src/sdk/strategy/cbd-strategy.ts | 9 ++++----- src/sdk/strategy/pre-strategy.ts | 26 +++++++++++++------------- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/characters/pre-recipient.ts b/src/characters/pre-recipient.ts index 2082bbd6a..f3ae24f5a 100644 --- a/src/characters/pre-recipient.ts +++ b/src/characters/pre-recipient.ts @@ -13,7 +13,7 @@ import { Keyring } from '../keyring'; import { PolicyMessageKit } from '../kits/message'; import { RetrievalResult } from '../kits/retrieval'; import { PorterClient } from '../porter'; -import { base64ToU8Receiver, bytesEquals, toJSON, zip } from '../utils'; +import { base64ToU8Receiver, toJSON, zip } from '../utils'; export type PreDecrypterJSON = { porterUri: string; @@ -185,15 +185,11 @@ export class PreDecrypter { } public equals(other: PreDecrypter): boolean { - return ( - this.porter.porterUrl.toString() === other.porter.porterUrl.toString() && - this.policyEncryptingKey.equals(other.policyEncryptingKey) && - // TODO: Replace with `equals` after https://github.com/nucypher/nucypher-core/issues/56 is fixed - bytesEquals( - this.encryptedTreasureMap.toBytes(), - other.encryptedTreasureMap.toBytes() - ) && - this.publisherVerifyingKey.equals(other.publisherVerifyingKey) - ); + return [ + this.porter.porterUrl.toString() === other.porter.porterUrl.toString(), + this.policyEncryptingKey.equals(other.policyEncryptingKey), + this.encryptedTreasureMap.equals(other.encryptedTreasureMap), + this.publisherVerifyingKey.equals(other.publisherVerifyingKey), + ].every(Boolean); } } diff --git a/src/conditions/condition-expr.ts b/src/conditions/condition-expr.ts index 5cc032c5e..61c446e53 100644 --- a/src/conditions/condition-expr.ts +++ b/src/conditions/condition-expr.ts @@ -95,9 +95,9 @@ export class ConditionExpression { } public equals(other: ConditionExpression): boolean { - return ( - this.version === other.version && - objectEquals(this.condition.toObj(), other.condition.toObj()) - ); + return [ + this.version === other.version, + objectEquals(this.condition.toObj(), other.condition.toObj()), + ].every(Boolean); } } diff --git a/src/sdk/strategy/cbd-strategy.ts b/src/sdk/strategy/cbd-strategy.ts index 9228284f3..5248677a0 100644 --- a/src/sdk/strategy/cbd-strategy.ts +++ b/src/sdk/strategy/cbd-strategy.ts @@ -1,7 +1,6 @@ import { DkgPublicKey } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; -import { bytesEqual } from '../../../test/utils'; import { ThresholdDecrypter, ThresholdDecrypterJSON, @@ -121,9 +120,9 @@ export class DeployedCbdStrategy { } public equals(other: DeployedCbdStrategy) { - return ( - this.decrypter.equals(other.decrypter) && - bytesEqual(this.dkgPublicKey.toBytes(), other.dkgPublicKey.toBytes()) - ); + return [ + this.decrypter.equals(other.decrypter), + this.dkgPublicKey.equals(other.dkgPublicKey), + ].every(Boolean); } } diff --git a/src/sdk/strategy/pre-strategy.ts b/src/sdk/strategy/pre-strategy.ts index 0ef97681d..51d883cea 100644 --- a/src/sdk/strategy/pre-strategy.ts +++ b/src/sdk/strategy/pre-strategy.ts @@ -131,20 +131,20 @@ export class PreStrategy { } public equals(other: PreStrategy) { - return ( - this.cohort.equals(other.cohort) && - // TODO: Replace with `equals` after https://github.com/nucypher/nucypher-core/issues/56 is fixed + return [ + this.cohort.equals(other.cohort), + // TODO: Replace with `equals` after https://github.com/nucypher/rust-umbral/pull/125 is released bytesEquals( this.aliceSecretKey.toBEBytes(), other.aliceSecretKey.toBEBytes() - ) && + ), bytesEquals( this.bobSecretKey.toBEBytes(), other.bobSecretKey.toBEBytes() - ) && - this.startDate.toString() === other.startDate.toString() && - this.endDate.toString() === other.endDate.toString() - ); + ), + this.startDate.toString() === other.startDate.toString(), + this.endDate.toString() === other.endDate.toString(), + ].every(Boolean); } } @@ -203,10 +203,10 @@ export class DeployedPreStrategy { } public equals(other: DeployedPreStrategy) { - return ( - this.cohort.equals(other.cohort) && - this.decrypter.equals(other.decrypter) && - this.policyKey.equals(other.policyKey) - ); + return [ + this.cohort.equals(other.cohort), + this.decrypter.equals(other.decrypter), + this.policyKey.equals(other.policyKey), + ].every(Boolean); } } From 5e4a6a5c99dea9cfdb59e2f8f0e246dfa3575310 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Wed, 5 Jul 2023 13:51:09 +0200 Subject: [PATCH 12/17] apply pr suggestions --- src/porter.ts | 1 - test/unit/cbd-strategy.test.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/porter.ts b/src/porter.ts index 08ae446b7..aea9f668f 100644 --- a/src/porter.ts +++ b/src/porter.ts @@ -15,7 +15,6 @@ import { fromBase64, fromHexString, toBase64, toHexString } from '../utils'; type Network = 'mainnet' | 'tapir' | 'oryx' | 'lynx'; const PORTER_URIS: Record = { - // TODO: Make sure these are correct mainnet: 'https://porter.nucypher.community', tapir: 'https://porter-tapir.nucypher.community', oryx: 'https://porter-oryx.nucypher.community', diff --git a/test/unit/cbd-strategy.test.ts b/test/unit/cbd-strategy.test.ts index 4526e70f1..b580673c3 100644 --- a/test/unit/cbd-strategy.test.ts +++ b/test/unit/cbd-strategy.test.ts @@ -166,7 +166,7 @@ describe('CbdDeployedStrategy', () => { }); }); -describe('CbdTDecDecrypter', () => { +describe('ThresholdDecrypter', () => { it('serializes to a plain object', async () => { const { deployedStrategy } = await makeDeployedCbdStrategy(); const configObj = deployedStrategy.decrypter.toObj(); From e8be006637a4c95fe24ef3fbcfedb2f6c13c3dec Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Wed, 2 Aug 2023 10:56:10 +0200 Subject: [PATCH 13/17] fix after rebase --- src/dkg.ts | 57 +++++++++++++++----------------- src/porter.ts | 4 +-- src/sdk/strategy/cbd-strategy.ts | 3 +- src/sdk/strategy/pre-strategy.ts | 13 ++------ test/utils.ts | 2 +- 5 files changed, 34 insertions(+), 45 deletions(-) diff --git a/src/dkg.ts b/src/dkg.ts index 651b14a36..a728b7a59 100644 --- a/src/dkg.ts +++ b/src/dkg.ts @@ -11,10 +11,10 @@ import { ethers } from 'ethers'; import { DkgCoordinatorAgent, DkgRitualState } from './agents/coordinator'; import { ChecksumAddress } from './types'; -import { bytesEquals, fromHexString, objectEquals } from './utils'; +import { fromHexString, objectEquals } from './utils'; export function getVariantClass( - variant: FerveoVariant, + variant: FerveoVariant ): typeof DecryptionShareSimple | typeof DecryptionSharePrecomputed { if (variant.equals(FerveoVariant.simple)) { return DecryptionShareSimple; @@ -26,9 +26,9 @@ export function getVariantClass( } export function getCombineDecryptionSharesFunction( - variant: FerveoVariant, + variant: FerveoVariant ): ( - shares: DecryptionShareSimple[] | DecryptionSharePrecomputed[], + shares: DecryptionShareSimple[] | DecryptionSharePrecomputed[] ) => SharedSecret { if (variant.equals(FerveoVariant.simple)) { return combineDecryptionSharesSimple; @@ -56,9 +56,8 @@ export class DkgRitual { public readonly id: number, public readonly dkgPublicKey: DkgPublicKey, public readonly dkgParams: DkgRitualParameters, - public readonly state: DkgRitualState, - ) { - } + public readonly state: DkgRitualState + ) {} public toObj(): DkgRitualJSON { return { @@ -70,27 +69,26 @@ export class DkgRitual { } public static fromObj({ - id, - dkgPublicKey, - dkgParams, - state, - }: DkgRitualJSON): DkgRitual { + id, + dkgPublicKey, + dkgParams, + state, + }: DkgRitualJSON): DkgRitual { return new DkgRitual( id, DkgPublicKey.fromBytes(dkgPublicKey), dkgParams, - state, + state ); } public equals(other: DkgRitual): boolean { - return ( - this.id === other.id && - // TODO: Replace with `equals` after https://github.com/nucypher/nucypher-core/issues/56 is fixed - bytesEquals(this.dkgPublicKey.toBytes(), other.dkgPublicKey.toBytes()) && - objectEquals(this.dkgParams, other.dkgParams) && - this.state === other.state - ); + return [ + this.id === other.id, + this.dkgPublicKey.equals(other.dkgPublicKey), + objectEquals(this.dkgParams, other.dkgParams), + this.state === other.state, + ].every(Boolean); } } @@ -103,25 +101,25 @@ export class DkgClient { public static async initializeRitual( web3Provider: ethers.providers.Web3Provider, ursulas: ChecksumAddress[], - waitUntilEnd = false, + waitUntilEnd = false ): Promise { const ritualId = await DkgCoordinatorAgent.initializeRitual( web3Provider, - ursulas.sort(), + ursulas.sort() ); if (waitUntilEnd) { const isSuccessful = await DkgClient.waitUntilRitualEnd( web3Provider, - ritualId, + ritualId ); if (!isSuccessful) { const ritualState = await DkgCoordinatorAgent.getRitualState( web3Provider, - ritualId, + ritualId ); throw new Error( - `Ritual initialization failed. Ritual id ${ritualId} is in state ${ritualState}`, + `Ritual initialization failed. Ritual id ${ritualId} is in state ${ritualState}` ); } } @@ -131,7 +129,7 @@ export class DkgClient { private static waitUntilRitualEnd = async ( web3Provider: ethers.providers.Web3Provider, - ritualId: number, + ritualId: number ): Promise => { return new Promise((resolve, reject) => { const callback = (successful: boolean) => { @@ -147,11 +145,11 @@ export class DkgClient { public static async getExistingRitual( web3Provider: ethers.providers.Web3Provider, - ritualId: number, + ritualId: number ): Promise { const ritualState = await DkgCoordinatorAgent.getRitualState( web3Provider, - ritualId, + ritualId ); const ritual = await DkgCoordinatorAgent.getRitual(web3Provider, ritualId); const dkgPkBytes = new Uint8Array([ @@ -165,11 +163,10 @@ export class DkgClient { sharesNum: ritual.dkgSize, threshold: assumedThreshold(ritual.dkgSize), }, - ritualState, + ritualState ); } - // TODO: Without Validator public key in Coordinator, we cannot verify the // transcript. We need to add it to the Coordinator (nucypher-contracts #77). // public async verifyRitual(ritualId: number): Promise { diff --git a/src/porter.ts b/src/porter.ts index aea9f668f..f222f2e25 100644 --- a/src/porter.ts +++ b/src/porter.ts @@ -9,8 +9,8 @@ import { import axios, { AxiosResponse } from 'axios'; import qs from 'qs'; -import { Base64EncodedBytes, ChecksumAddress, HexEncodedBytes } from '../types'; -import { fromBase64, fromHexString, toBase64, toHexString } from '../utils'; +import { Base64EncodedBytes, ChecksumAddress, HexEncodedBytes } from './types'; +import { fromBase64, fromHexString, toBase64, toHexString } from './utils'; type Network = 'mainnet' | 'tapir' | 'oryx' | 'lynx'; diff --git a/src/sdk/strategy/cbd-strategy.ts b/src/sdk/strategy/cbd-strategy.ts index 5248677a0..1002e9989 100644 --- a/src/sdk/strategy/cbd-strategy.ts +++ b/src/sdk/strategy/cbd-strategy.ts @@ -87,8 +87,7 @@ export class DeployedCbdStrategy { porterUri: string, ritualId: number ): Promise { - const dkgClient = new DkgClient(provider); - const dkgRitual = await dkgClient.getExistingRitual(ritualId); + const dkgRitual = await DkgClient.getExistingRitual(provider, ritualId); return DeployedCbdStrategy.create(dkgRitual, porterUri); } diff --git a/src/sdk/strategy/pre-strategy.ts b/src/sdk/strategy/pre-strategy.ts index 51d883cea..267f0480d 100644 --- a/src/sdk/strategy/pre-strategy.ts +++ b/src/sdk/strategy/pre-strategy.ts @@ -7,7 +7,7 @@ import { Enrico } from '../../characters/enrico'; import { PreDecrypter, PreDecrypterJSON } from '../../characters/pre-recipient'; import { ConditionExpression } from '../../conditions'; import { EnactedPolicy } from '../../policies/policy'; -import { base64ToU8Receiver, bytesEquals, toJSON } from '../../utils'; +import { base64ToU8Receiver, toJSON } from '../../utils'; import { Cohort, CohortJSON } from '../cohort'; export type PreStrategyJSON = { @@ -133,15 +133,8 @@ export class PreStrategy { public equals(other: PreStrategy) { return [ this.cohort.equals(other.cohort), - // TODO: Replace with `equals` after https://github.com/nucypher/rust-umbral/pull/125 is released - bytesEquals( - this.aliceSecretKey.toBEBytes(), - other.aliceSecretKey.toBEBytes() - ), - bytesEquals( - this.bobSecretKey.toBEBytes(), - other.bobSecretKey.toBEBytes() - ), + this.aliceSecretKey.equals(other.aliceSecretKey), + this.bobSecretKey.equals(other.bobSecretKey), this.startDate.toString() === other.startDate.toString(), this.endDate.toString() === other.endDate.toString(), ].every(Boolean); diff --git a/test/utils.ts b/test/utils.ts index c6cd1e4ff..b9b76db06 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -44,7 +44,7 @@ import { DkgRitualState, } from '../src/agents/coordinator'; import { ThresholdDecrypter } from '../src/characters/cbd-recipient'; -import { DkgClient, DkgRitual, FerveoVariant } from '../src/dkg'; +import { DkgClient, DkgRitual } from '../src/dkg'; import { BlockchainPolicy, PreEnactedPolicy } from '../src/policies/policy'; import { CbdDecryptResult, From 6f4cc7a6e5dd005cfb0705d8caf866f1e5b42843 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Wed, 2 Aug 2023 14:48:08 +0200 Subject: [PATCH 14/17] chore(release): 1.0.0-alpha.2 --- CHANGELOG.md | 14 ++++++++++++++ package.json | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbafcf0f7..4a2525c83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.0.0-alpha.2](https://github.com/nucypher/nucypher-ts/compare/v1.0.0-alpha.1...v1.0.0-alpha.2) (2023-08-02) + + +### ⚠ BREAKING CHANGES + +* porter uris are based on networks, not chain ids +* replaced configuration with raw porter uri + +### Features + +* implement local ritual verificaiton ([39241c0](https://github.com/nucypher/nucypher-ts/commit/39241c0cacc2b29bf11a5f4c88a6d53bb8ea4375)) +* porter uris are based on networks, not chain ids ([d911481](https://github.com/nucypher/nucypher-ts/commit/d911481d0f1b8f80e022b2c32de5aaa53607a2f9)) +* replaced configuration with raw porter uri ([fcd7fc0](https://github.com/nucypher/nucypher-ts/commit/fcd7fc0cb505b71a6e709ae37c1c53f9b2261f53)) + ## [1.0.0-alpha.1](https://github.com/nucypher/nucypher-ts/compare/v1.0.0-alpha.0...v1.0.0-alpha.1) (2023-07-10) diff --git a/package.json b/package.json index 1c965c118..aed3608a2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@nucypher/nucypher-ts", "author": "Piotr Roslaniec ", - "version": "1.0.0-alpha.1", + "version": "1.0.0-alpha.2", "license": "GPL-3.0-only", "repository": { "type": "git", From a4a956f9b4a45d64888f86ad0a80186a26d60103 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Thu, 29 Jun 2023 12:52:40 +0200 Subject: [PATCH 15/17] feat: implement local ritual verificaiton --- src/agents/coordinator.ts | 1 + src/agents/subscription-manager.ts | 8 ++-- src/characters/cbd-recipient.ts | 11 +++++ src/dkg.ts | 70 +++++++++++++++++++++--------- test/unit/cbd-strategy.test.ts | 4 ++ test/utils.ts | 6 +++ 6 files changed, 77 insertions(+), 23 deletions(-) diff --git a/src/agents/coordinator.ts b/src/agents/coordinator.ts index ca1e41f17..a30deb191 100644 --- a/src/agents/coordinator.ts +++ b/src/agents/coordinator.ts @@ -25,6 +25,7 @@ export interface CoordinatorRitual { export type DkgParticipant = { provider: string; aggregated: boolean; + // TODO: How do I get the transcript from the Coordinator? transcript: Transcript; decryptionRequestStaticKey: SessionStaticKey; }; diff --git a/src/agents/subscription-manager.ts b/src/agents/subscription-manager.ts index ac8a5a3c5..f997508c8 100644 --- a/src/agents/subscription-manager.ts +++ b/src/agents/subscription-manager.ts @@ -48,7 +48,7 @@ export class PreSubscriptionManagerAgent { } public static async getPolicyCost( - provider: ethers.providers.Provider, + provider: ethers.providers.Web3Provider, size: number, startTimestamp: number, endTimestamp: number @@ -61,7 +61,9 @@ export class PreSubscriptionManagerAgent { ); } - private static async connectReadOnly(provider: ethers.providers.Provider) { + private static async connectReadOnly( + provider: ethers.providers.Web3Provider + ) { return await this.connect(provider); } @@ -72,7 +74,7 @@ export class PreSubscriptionManagerAgent { } private static async connect( - provider: ethers.providers.Provider, + provider: ethers.providers.Web3Provider, signer?: ethers.providers.JsonRpcSigner ): Promise { const network = await provider.getNetwork(); diff --git a/src/characters/cbd-recipient.ts b/src/characters/cbd-recipient.ts index 68ad97b8a..17af50e8b 100644 --- a/src/characters/cbd-recipient.ts +++ b/src/characters/cbd-recipient.ts @@ -20,6 +20,7 @@ import { } from '../agents/coordinator'; import { ConditionExpression } from '../conditions'; import { + DkgClient, DkgRitual, getCombineDecryptionSharesFunction, getVariantClass, @@ -91,6 +92,16 @@ export class ThresholdDecrypter { ); } + const isLocallyVerified = await DkgClient.verifyRitual( + web3Provider, + this.ritualId + ); + if (!isLocallyVerified) { + throw new Error( + `Ritual with id ${this.ritualId} has failed local verification.` + ); + } + const dkgParticipants = await DkgCoordinatorAgent.getParticipants( web3Provider, this.ritualId diff --git a/src/dkg.ts b/src/dkg.ts index a728b7a59..749dae96f 100644 --- a/src/dkg.ts +++ b/src/dkg.ts @@ -1,11 +1,16 @@ import { + AggregatedTranscript, combineDecryptionSharesPrecomputed, combineDecryptionSharesSimple, DecryptionSharePrecomputed, DecryptionShareSimple, DkgPublicKey, + EthereumAddress, + FerveoPublicKey, FerveoVariant, SharedSecret, + Validator, + ValidatorMessage, } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; @@ -97,6 +102,21 @@ export class DkgRitual { const assumedThreshold = (sharesNum: number): number => Math.floor(sharesNum / 2) + 1; +// TODO: Without Validator public key in Coordinator, we cannot verify the +// transcript. We need to add it to the Coordinator (nucypher-contracts #77). +const participantPublicKeys: Record = { + '0x210eeAC07542F815ebB6FD6689637D8cA2689392': FerveoPublicKey.fromBytes( + fromHexString( + 'ace9d7567b26dafc512b2303cfdaa872850c62b100078ddeaabf8408c7308b3a43dfeb88375c21ef63230fb4008ce7e908764463c6765e556f9b03009eb1757d179eaa26bf875332807cc070d62a385ed2e66e09f4f4766451da12779a09036e' + ) + ), + '0xb15d5A4e2be34f4bE154A1b08a94Ab920FfD8A41': FerveoPublicKey.fromBytes( + fromHexString( + '8b373fdb6b43e9dca028bd603c2bf90f0e008ec83ff217a8d7bc006b585570e6ab1ce761bad0e21c1aed1363286145f61134ed0ab53f4ebaa05036396c57f6e587f33d49667c1003cd03b71ad651b09dd4791bc631eaef93f1b313bbee7bd63a' + ) + ), +}; + export class DkgClient { public static async initializeRitual( web3Provider: ethers.providers.Web3Provider, @@ -167,24 +187,34 @@ export class DkgClient { ); } - // TODO: Without Validator public key in Coordinator, we cannot verify the - // transcript. We need to add it to the Coordinator (nucypher-contracts #77). - // public async verifyRitual(ritualId: number): Promise { - // const ritual = await DkgCoordinatorAgent.getRitual(this.provider, ritualId); - // const participants = await DkgCoordinatorAgent.getParticipants( - // this.provider, - // ritualId - // ); - // - // const validatorMessages = participants.map((p) => { - // const validatorAddress = EthereumAddress.fromString(p.provider); - // const publicKey = FerveoPublicKey.fromBytes(fromHexString(p.???)); - // const validator = new Validator(validatorAddress, publicKey); - // const transcript = Transcript.fromBytes(fromHexString(p.transcript)); - // return new ValidatorMessage(validator, transcript); - // }); - // const aggregate = new AggregatedTranscript(validatorMessages); - // - // return aggregate.verify(ritual.dkgSize, validatorMessages); - // } + public static async verifyRitual( + web3Provider: ethers.providers.Web3Provider, + ritualId: number + ): Promise { + const ritual = await DkgCoordinatorAgent.getRitual(web3Provider, ritualId); + const participants = await DkgCoordinatorAgent.getParticipants( + web3Provider, + ritualId + ); + + // TODO: Does this check make sense here? Or do we delegate it to the Coordinator contract? + // for (const p of participants) { + // // Not every participant has submitted a transcript + // if (!p.aggregated) { + // return false; + // } + // } + + const validatorMessages = participants.map((p) => { + const validatorAddress = EthereumAddress.fromString(p.provider); + // TODO: Replace with real keys + // const publicKey = FerveoPublicKey.fromBytes(fromHexString(p.???)); + const publicKey = participantPublicKeys[p.provider]; + const validator = new Validator(validatorAddress, publicKey); + return new ValidatorMessage(validator, p.transcript); + }); + const aggregate = new AggregatedTranscript(validatorMessages); + + return aggregate.verify(ritual.dkgSize, validatorMessages); + } } diff --git a/test/unit/cbd-strategy.test.ts b/test/unit/cbd-strategy.test.ts index b580673c3..fe19d0350 100644 --- a/test/unit/cbd-strategy.test.ts +++ b/test/unit/cbd-strategy.test.ts @@ -20,6 +20,7 @@ import { mockGetUrsulas, mockInitializeRitual, mockRandomSessionStaticSecret, + mockVerifyRitual, } from '../utils'; import { aliceSecretKeyBytes } from './testVariables'; @@ -133,6 +134,7 @@ describe('CbdDeployedStrategy', () => { const getUrsulasSpy = mockGetUrsulas(ursulas); const sessionKeySpy = mockRandomSessionStaticSecret(requesterSessionKey); const getRitualStateSpy = mockGetRitualState(); + const verifyRitualSpy = mockVerifyRitual(); const decryptedMessage = await deployedStrategy.decrypter.retrieveAndDecrypt( @@ -141,6 +143,8 @@ describe('CbdDeployedStrategy', () => { variant, ciphertext ); + expect(getRitualStateSpy).toHaveBeenCalled(); + expect(verifyRitualSpy).toHaveBeenCalled(); expect(getUrsulasSpy).toHaveBeenCalled(); expect(getParticipantsSpy).toHaveBeenCalled(); expect(sessionKeySpy).toHaveBeenCalled(); diff --git a/test/utils.ts b/test/utils.ts index b9b76db06..f33791cec 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -546,3 +546,9 @@ export const mockGetRitualState = (state = DkgRitualState.FINALIZED) => { .spyOn(DkgCoordinatorAgent, 'getRitualState') .mockImplementation((_provider, _ritualId) => Promise.resolve(state)); }; + +export const mockVerifyRitual = (isValid = true) => { + return jest + .spyOn(DkgClient, 'verifyRitual') + .mockImplementation((_provider, _ritualId) => Promise.resolve(isValid)); +}; From 9e42bee8898dce80fb8af2db802bfca22dad407f Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Thu, 29 Jun 2023 15:15:44 +0200 Subject: [PATCH 16/17] test local verification --- src/dkg.ts | 40 +++++++++++++--------- test/integration/dkg-client.test.ts | 52 +++++++++++++++++++++++------ test/utils.ts | 11 ++++++ 3 files changed, 76 insertions(+), 27 deletions(-) diff --git a/src/dkg.ts b/src/dkg.ts index 749dae96f..7481f65ce 100644 --- a/src/dkg.ts +++ b/src/dkg.ts @@ -102,21 +102,6 @@ export class DkgRitual { const assumedThreshold = (sharesNum: number): number => Math.floor(sharesNum / 2) + 1; -// TODO: Without Validator public key in Coordinator, we cannot verify the -// transcript. We need to add it to the Coordinator (nucypher-contracts #77). -const participantPublicKeys: Record = { - '0x210eeAC07542F815ebB6FD6689637D8cA2689392': FerveoPublicKey.fromBytes( - fromHexString( - 'ace9d7567b26dafc512b2303cfdaa872850c62b100078ddeaabf8408c7308b3a43dfeb88375c21ef63230fb4008ce7e908764463c6765e556f9b03009eb1757d179eaa26bf875332807cc070d62a385ed2e66e09f4f4766451da12779a09036e' - ) - ), - '0xb15d5A4e2be34f4bE154A1b08a94Ab920FfD8A41': FerveoPublicKey.fromBytes( - fromHexString( - '8b373fdb6b43e9dca028bd603c2bf90f0e008ec83ff217a8d7bc006b585570e6ab1ce761bad0e21c1aed1363286145f61134ed0ab53f4ebaa05036396c57f6e587f33d49667c1003cd03b71ad651b09dd4791bc631eaef93f1b313bbee7bd63a' - ) - ), -}; - export class DkgClient { public static async initializeRitual( web3Provider: ethers.providers.Web3Provider, @@ -209,7 +194,7 @@ export class DkgClient { const validatorAddress = EthereumAddress.fromString(p.provider); // TODO: Replace with real keys // const publicKey = FerveoPublicKey.fromBytes(fromHexString(p.???)); - const publicKey = participantPublicKeys[p.provider]; + const publicKey = DkgClient.getParticipantPublicKey(p.provider); const validator = new Validator(validatorAddress, publicKey); return new ValidatorMessage(validator, p.transcript); }); @@ -217,4 +202,27 @@ export class DkgClient { return aggregate.verify(ritual.dkgSize, validatorMessages); } + + public static getParticipantPublicKey = (address: string) => { + // TODO: Without Validator public key in Coordinator, we cannot verify the + // transcript. We need to add it to the Coordinator (nucypher-contracts #77). + const participantPublicKeys: Record = { + '0x210eeAC07542F815ebB6FD6689637D8cA2689392': FerveoPublicKey.fromBytes( + fromHexString( + 'ace9d7567b26dafc512b2303cfdaa872850c62b100078ddeaabf8408c7308b3a43dfeb88375c21ef63230fb4008ce7e908764463c6765e556f9b03009eb1757d179eaa26bf875332807cc070d62a385ed2e66e09f4f4766451da12779a09036e' + ) + ), + '0xb15d5A4e2be34f4bE154A1b08a94Ab920FfD8A41': FerveoPublicKey.fromBytes( + fromHexString( + '8b373fdb6b43e9dca028bd603c2bf90f0e008ec83ff217a8d7bc006b585570e6ab1ce761bad0e21c1aed1363286145f61134ed0ab53f4ebaa05036396c57f6e587f33d49667c1003cd03b71ad651b09dd4791bc631eaef93f1b313bbee7bd63a' + ) + ), + }; + + const publicKey = participantPublicKeys[address]; + if (!publicKey) { + throw new Error(`No public key for participant: ${address}`); + } + return publicKey; + }; } diff --git a/test/integration/dkg-client.test.ts b/test/integration/dkg-client.test.ts index acb8337b6..ff2150465 100644 --- a/test/integration/dkg-client.test.ts +++ b/test/integration/dkg-client.test.ts @@ -1,18 +1,22 @@ import { SecretKey } from '@nucypher/nucypher-core'; import { DkgCoordinatorAgent } from '../../src/agents/coordinator'; +import { DkgClient } from '../../src/dkg'; import { fakeCoordinatorRitual, fakeDkgParticipants, fakeRitualId, fakeWeb3Provider, + mockGetParticipantPublicKey, mockGetParticipants, + mockVerifyRitual, } from '../utils'; jest.mock('../../src/agents/coordinator', () => ({ DkgCoordinatorAgent: { getRitual: () => Promise.resolve(fakeCoordinatorRitual(fakeRitualId)), - getParticipants: () => Promise.resolve(fakeDkgParticipants(fakeRitualId)), + getParticipants: () => + Promise.resolve(fakeDkgParticipants(fakeRitualId).participants), }, })); @@ -42,13 +46,39 @@ describe('DkgCoordinatorAgent', () => { }); }); -// TODO: Fix this test after the DkgClient.verifyRitual() method is implemented -// describe('DkgClient', () => { -// it('verifies the dkg ritual', async () => { -// const provider = fakeWeb3Provider(SecretKey.random().toBEBytes()); -// -// const dkgClient = new DkgClient(provider); -// const isValid = await dkgClient.verifyRitual(fakeRitualId); -// expect(isValid).toBeTruthy(); -// }); -// }); +describe('DkgClient', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('verifies the dkg ritual', async () => { + const provider = fakeWeb3Provider(SecretKey.random().toBEBytes()); + const verifyRitualSpy = mockVerifyRitual(); + + const isValid = await DkgClient.verifyRitual(provider, fakeRitualId); + expect(isValid).toBeTruthy(); + expect(verifyRitualSpy).toHaveBeenCalled(); + }); + + it('rejects on missing participant pk', async () => { + const provider = fakeWeb3Provider(SecretKey.random().toBEBytes()); + + await expect(async () => + DkgClient.verifyRitual(provider, fakeRitualId) + ).rejects.toThrow( + 'No public key for participant: 0x0000000000000000000000000000000000000000' + ); + }); + + it('rejects on bad participant pk', async () => { + const provider = fakeWeb3Provider(SecretKey.random().toBEBytes()); + const getParticipantPublicKeysSpy = mockGetParticipantPublicKey(); + + await expect(async () => + DkgClient.verifyRitual(provider, fakeRitualId) + ).rejects.toThrow( + "Transcript aggregate doesn't match the received PVSS instances" + ); + expect(getParticipantPublicKeysSpy).toHaveBeenCalled(); + }); +}); diff --git a/test/utils.ts b/test/utils.ts index f33791cec..76749cf58 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -18,6 +18,7 @@ import { EncryptedTreasureMap, EthereumAddress, ferveoEncrypt, + FerveoPublicKey, FerveoVariant, Keypair, PublicKey, @@ -552,3 +553,13 @@ export const mockVerifyRitual = (isValid = true) => { .spyOn(DkgClient, 'verifyRitual') .mockImplementation((_provider, _ritualId) => Promise.resolve(isValid)); }; + +export const mockGetParticipantPublicKey = (pk = fakeFerveoPublicKey()) => { + return jest + .spyOn(DkgClient, 'getParticipantPublicKey') + .mockImplementation((_address) => pk); +}; + +export const fakeFerveoPublicKey = (): FerveoPublicKey => { + return Keypair.random().publicKey; +}; From 43d45f07a0535fe4c162afd6301da2cee3e11039 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Thu, 29 Jun 2023 18:02:22 +0200 Subject: [PATCH 17/17] apply pr suggestions --- src/agents/coordinator.ts | 1 - src/characters/cbd-recipient.ts | 25 +++++++++++++++---------- src/dkg.ts | 8 -------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/agents/coordinator.ts b/src/agents/coordinator.ts index a30deb191..ca1e41f17 100644 --- a/src/agents/coordinator.ts +++ b/src/agents/coordinator.ts @@ -25,7 +25,6 @@ export interface CoordinatorRitual { export type DkgParticipant = { provider: string; aggregated: boolean; - // TODO: How do I get the transcript from the Coordinator? transcript: Transcript; decryptionRequestStaticKey: SessionStaticKey; }; diff --git a/src/characters/cbd-recipient.ts b/src/characters/cbd-recipient.ts index 17af50e8b..47136da84 100644 --- a/src/characters/cbd-recipient.ts +++ b/src/characters/cbd-recipient.ts @@ -56,13 +56,15 @@ export class ThresholdDecrypter { provider: ethers.providers.Web3Provider, conditionExpr: ConditionExpression, variant: FerveoVariant, - ciphertext: Ciphertext + ciphertext: Ciphertext, + verifyRitual = true ): Promise { const decryptionShares = await this.retrieve( provider, conditionExpr, variant, - ciphertext + ciphertext, + verifyRitual ); const combineDecryptionSharesFn = @@ -80,7 +82,8 @@ export class ThresholdDecrypter { web3Provider: ethers.providers.Web3Provider, conditionExpr: ConditionExpression, variant: FerveoVariant, - ciphertext: Ciphertext + ciphertext: Ciphertext, + verifyRitual = true ): Promise { const ritualState = await DkgCoordinatorAgent.getRitualState( web3Provider, @@ -92,14 +95,16 @@ export class ThresholdDecrypter { ); } - const isLocallyVerified = await DkgClient.verifyRitual( - web3Provider, - this.ritualId - ); - if (!isLocallyVerified) { - throw new Error( - `Ritual with id ${this.ritualId} has failed local verification.` + if (verifyRitual) { + const isLocallyVerified = await DkgClient.verifyRitual( + web3Provider, + this.ritualId ); + if (!isLocallyVerified) { + throw new Error( + `Ritual with id ${this.ritualId} has failed local verification.` + ); + } } const dkgParticipants = await DkgCoordinatorAgent.getParticipants( diff --git a/src/dkg.ts b/src/dkg.ts index 7481f65ce..661d23a3d 100644 --- a/src/dkg.ts +++ b/src/dkg.ts @@ -182,14 +182,6 @@ export class DkgClient { ritualId ); - // TODO: Does this check make sense here? Or do we delegate it to the Coordinator contract? - // for (const p of participants) { - // // Not every participant has submitted a transcript - // if (!p.aggregated) { - // return false; - // } - // } - const validatorMessages = participants.map((p) => { const validatorAddress = EthereumAddress.fromString(p.provider); // TODO: Replace with real keys