From b1d6a7c466a81974e98ef73faf17b0bf40e5f407 Mon Sep 17 00:00:00 2001
From: Piotr Roslaniec
Date: Thu, 29 Jun 2023 11:06:23 +0200
Subject: [PATCH] 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 | 9 +++----
8 files changed, 73 insertions(+), 51 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 ffe284939..1d3ffcb7d 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 a887004a0..66c2cbca8 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().slice(0, 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 61574df95..545e9abee 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().slice(0, 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 9792e6b6a..87154d021 100644
--- a/test/utils.ts
+++ b/test/utils.ts
@@ -59,13 +59,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 => {
@@ -75,12 +75,11 @@ 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 = (
- secretKeyBytes: Uint8Array,
+ secretKeyBytes = SecretKey.random().toBEBytes(),
blockNumber?: number,
blockTimestamp?: number
): ethers.providers.Web3Provider => {