Skip to content

Commit

Permalink
draft migration from ethers to viem
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-roslaniec committed Aug 24, 2023
1 parent a98cee4 commit 3796355
Show file tree
Hide file tree
Showing 26 changed files with 773 additions and 514 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
"ethers": "^5.4.1",
"joi": "^17.7.0",
"qs": "^6.10.1",
"semver": "^7.5.2"
"semver": "^7.5.2",
"viem": "^1.6.7"
},
"devDependencies": {
"@babel/core": "^7.18.10",
Expand Down Expand Up @@ -88,7 +89,7 @@
"typechain": "^7.0.0",
"typedoc": "^0.22.11",
"typedoc-plugin-missing-exports": "^0.22.6",
"typescript": "^4.7.0"
"typescript": "^5.0.4"
},
"files": [
"build/main",
Expand Down
9 changes: 6 additions & 3 deletions src/agents/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ const CONTRACTS: { readonly [key in ChainId]: Contracts } = {
[ChainId.MAINNET]: MAINNET,
};

export const getContract = (
chainId: number,
contract: keyof Contracts
export const getContractOrFail = (
contract: keyof Contracts,
chainId?: number
): ChecksumAddress => {
if (!chainId) {
throw new Error('No chainId provided');
}
if (!Object.values(ChainId).includes(chainId)) {
throw new Error(`No contracts found for chainId: ${chainId}`);
}
Expand Down
61 changes: 31 additions & 30 deletions src/agents/coordinator.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { SessionStaticKey } from '@nucypher/nucypher-core';
import { ethers } from 'ethers';
import { PublicClient, WalletClient } from 'viem';

import {
Coordinator,
Coordinator__factory,
} from '../../types/ethers-contracts';
import { Coordinator__factory } from '../../types/ethers-contracts';
import { BLS12381 } from '../../types/ethers-contracts/Coordinator';
import { ChecksumAddress } from '../types';
import { fromHexString } from '../utils';
import { publicClientToProvider, walletClientToSigner } from '../viem';

import { DEFAULT_WAIT_N_CONFIRMATIONS, getContract } from './contracts';
import { DEFAULT_WAIT_N_CONFIRMATIONS, getContractOrFail } from './contracts';

export interface CoordinatorRitual {
initiator: string;
Expand Down Expand Up @@ -39,10 +37,10 @@ export enum DkgRitualState {

export class DkgCoordinatorAgent {
public static async getParticipants(
provider: ethers.providers.Provider,
publicClient: PublicClient,
ritualId: number
): Promise<DkgParticipant[]> {
const Coordinator = await this.connectReadOnly(provider);
const Coordinator = await this.connectReadOnly(publicClient);
const participants = await Coordinator.getParticipants(ritualId);

return participants.map((participant) => {
Expand All @@ -57,10 +55,10 @@ export class DkgCoordinatorAgent {
}

public static async initializeRitual(
provider: ethers.providers.Web3Provider,
walletClient: WalletClient,
providers: ChecksumAddress[]
): Promise<number> {
const Coordinator = await this.connectReadWrite(provider);
const Coordinator = await this.connectReadWrite(walletClient);
const tx = await Coordinator.initiateRitual(providers);
const txReceipt = await tx.wait(DEFAULT_WAIT_N_CONFIRMATIONS);
const [ritualStartEvent] = txReceipt.events ?? [];
Expand All @@ -71,23 +69,23 @@ export class DkgCoordinatorAgent {
}

public static async getRitual(
provider: ethers.providers.Provider,
publicClient: PublicClient,
ritualId: number
): Promise<CoordinatorRitual> {
const Coordinator = await this.connectReadOnly(provider);
const Coordinator = await this.connectReadOnly(publicClient);
return Coordinator.rituals(ritualId);
}

public static async getRitualState(
provider: ethers.providers.Web3Provider,
publicClient: PublicClient,
ritualId: number
): Promise<DkgRitualState> {
const Coordinator = await this.connectReadOnly(provider);
const Coordinator = await this.connectReadOnly(publicClient);
return await Coordinator.getRitualState(ritualId);
}

public static async onRitualEndEvent(
provider: ethers.providers.Web3Provider,
provider: PublicClient,
ritualId: number,
callback: (successful: boolean) => void
): Promise<void> {
Expand All @@ -104,22 +102,25 @@ export class DkgCoordinatorAgent {
});
}

private static async connectReadOnly(provider: ethers.providers.Provider) {
return await this.connect(provider);
}

private static async connectReadWrite(
web3Provider: ethers.providers.Web3Provider
) {
return await this.connect(web3Provider, web3Provider.getSigner());
private static async connectReadOnly(publicClient: PublicClient) {
const contractAddress = getContractOrFail(
'COORDINATOR',
publicClient.chain?.id
);
return Coordinator__factory.connect(
contractAddress,
publicClientToProvider(publicClient)
);
}

private static async connect(
provider: ethers.providers.Provider,
signer?: ethers.providers.JsonRpcSigner
): Promise<Coordinator> {
const network = await provider.getNetwork();
const contractAddress = getContract(network.chainId, 'COORDINATOR');
return Coordinator__factory.connect(contractAddress, signer ?? provider);
private static async connectReadWrite(walletClient: WalletClient) {
const contractAddress = getContractOrFail(
'COORDINATOR',
walletClient.chain?.id
);
return Coordinator__factory.connect(
contractAddress,
walletClientToSigner(walletClient)
);
}
}
55 changes: 23 additions & 32 deletions src/agents/subscription-manager.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
import {
BigNumber,
ContractTransaction,
ethers,
utils as ethersUtils,
} from 'ethers';
import { BigNumber, ContractTransaction, utils as ethersUtils } from 'ethers';
import { PublicClient, WalletClient } from 'viem';

import {
SubscriptionManager,
SubscriptionManager__factory,
} from '../../types/ethers-contracts';
import { SubscriptionManager__factory } from '../../types/ethers-contracts';
import { ChecksumAddress } from '../types';
import { publicClientToProvider, walletClientToSigner } from '../viem';

import { DEFAULT_WAIT_N_CONFIRMATIONS, getContract } from './contracts';
import { DEFAULT_WAIT_N_CONFIRMATIONS, getContractOrFail } from './contracts';

export class PreSubscriptionManagerAgent {
public static async createPolicy(
web3Provider: ethers.providers.Web3Provider,
walletClient: WalletClient,
valueInWei: BigNumber,
policyId: Uint8Array,
size: number,
startTimestamp: number,
endTimestamp: number,
ownerAddress: ChecksumAddress
): Promise<ContractTransaction> {
const SubscriptionManager = await this.connectReadWrite(web3Provider);
const SubscriptionManager = await this.connectReadWrite(walletClient);
const overrides = {
value: valueInWei.toString(),
};
Expand All @@ -48,41 +42,38 @@ export class PreSubscriptionManagerAgent {
}

public static async getPolicyCost(
provider: ethers.providers.Provider,
publicClient: PublicClient,
size: number,
startTimestamp: number,
endTimestamp: number
): Promise<BigNumber> {
const SubscriptionManager = await this.connectReadOnly(provider);
const SubscriptionManager = await this.connectReadOnly(publicClient);
return await SubscriptionManager.getPolicyCost(
size,
startTimestamp,
endTimestamp
);
}

private static async connectReadOnly(provider: ethers.providers.Provider) {
return await this.connect(provider);
}

private static async connectReadWrite(
web3Provider: ethers.providers.Web3Provider
) {
return await this.connect(web3Provider, web3Provider.getSigner());
private static async connectReadOnly(publicClient: PublicClient) {
const contractAddress = getContractOrFail(
'COORDINATOR',
publicClient.chain?.id
);
return SubscriptionManager__factory.connect(
contractAddress,
publicClientToProvider(publicClient)
);
}

private static async connect(
provider: ethers.providers.Provider,
signer?: ethers.providers.JsonRpcSigner
): Promise<SubscriptionManager> {
const network = await provider.getNetwork();
const contractAddress = getContract(
network.chainId,
'SUBSCRIPTION_MANAGER'
private static async connectReadWrite(walletClient: WalletClient) {
const contractAddress = getContractOrFail(
'COORDINATOR',
walletClient.chain?.id
);
return SubscriptionManager__factory.connect(
contractAddress,
signer ?? provider
walletClientToSigner(walletClient)
);
}
}
27 changes: 15 additions & 12 deletions src/characters/alice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
Signer,
VerifiedKeyFrag,
} from '@nucypher/nucypher-core';
import { ethers } from 'ethers';
import { PublicClient, WalletClient } from 'viem';
import { getBlock, getBlockNumber } from 'viem/actions';

import { Keyring } from '../keyring';
import {
Expand All @@ -15,6 +16,7 @@ import {
} from '../policies/policy';
import { PorterClient } from '../porter';
import { ChecksumAddress } from '../types';
import { toPublicClient } from '../viem';

import { RemoteBob } from './bob';

Expand Down Expand Up @@ -42,7 +44,7 @@ export class Alice {
}

public async grant(
web3Provider: ethers.providers.Web3Provider,
walletClient: WalletClient,
porterUri: string,
policyParameters: BlockchainPolicyParameters,
includeUrsulas?: readonly ChecksumAddress[],
Expand All @@ -54,12 +56,12 @@ export class Alice {
excludeUrsulas,
includeUrsulas
);
const policy = await this.createPolicy(web3Provider, policyParameters);
return await policy.enact(web3Provider, ursulas);
const policy = await this.createPolicy(walletClient, policyParameters);
return await policy.enact(walletClient, ursulas);
}

public async generatePreEnactedPolicy(
web3Provider: ethers.providers.Web3Provider,
walletClient: WalletClient,
porterUri: string,
policyParameters: BlockchainPolicyParameters,
includeUrsulas?: readonly ChecksumAddress[],
Expand All @@ -71,7 +73,7 @@ export class Alice {
excludeUrsulas,
includeUrsulas
);
const policy = await this.createPolicy(web3Provider, policyParameters);
const policy = await this.createPolicy(walletClient, policyParameters);
return await policy.generatePreEnactedPolicy(ursulas);
}

Expand All @@ -94,11 +96,12 @@ export class Alice {
}

private async createPolicy(
web3Provider: ethers.providers.Web3Provider,
walletClient: WalletClient,
rawParameters: BlockchainPolicyParameters
): Promise<BlockchainPolicy> {
const publicClient = toPublicClient(walletClient);
const { bob, label, threshold, shares, startDate, endDate } =
await this.validatePolicyParameters(web3Provider, rawParameters);
await this.validatePolicyParameters(publicClient, rawParameters);
const { delegatingKey, verifiedKFrags } = this.generateKFrags(
bob,
label,
Expand All @@ -119,7 +122,7 @@ export class Alice {
}

private async validatePolicyParameters(
web3Provider: ethers.providers.Web3Provider,
publicClient: PublicClient,
rawParams: BlockchainPolicyParameters
): Promise<BlockchainPolicyParameters> {
const startDate = rawParams.startDate ?? new Date();
Expand All @@ -141,9 +144,9 @@ export class Alice {
);
}

const blockNumber = await web3Provider.getBlockNumber();
const block = await web3Provider.getBlock(blockNumber);
const blockTime = new Date(block.timestamp * 1000);
const blockNumber = await getBlockNumber(publicClient);
const block = await getBlock(publicClient, { blockNumber });
const blockTime = new Date(Number(block.timestamp) * 1000);
if (endDate < blockTime) {
throw new Error(
`End date must be in the future, ${endDate} is earlier than block time ${blockTime}).`
Expand Down
14 changes: 8 additions & 6 deletions src/characters/cbd-recipient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import {
SessionStaticSecret,
ThresholdDecryptionRequest,
} from '@nucypher/nucypher-core';
import { ethers } from 'ethers';
import { WalletClient } from 'viem';

import { DkgCoordinatorAgent, DkgParticipant } from '../agents/coordinator';
import { ConditionExpression } from '../conditions';
import { DkgRitual } from '../dkg';
import { PorterClient } from '../porter';
import { fromJSON, toJSON } from '../utils';
import { toPublicClient } from '../viem';

export type ThresholdDecrypterJSON = {
porterUri: string;
Expand All @@ -44,12 +45,12 @@ export class ThresholdDecrypter {

// Retrieve and decrypt ciphertext using provider and condition expression
public async retrieveAndDecrypt(
provider: ethers.providers.Web3Provider,
walletClient: WalletClient,
conditionExpr: ConditionExpression,
ciphertext: Ciphertext
): Promise<Uint8Array> {
const decryptionShares = await this.retrieve(
provider,
walletClient,
conditionExpr,
ciphertext
);
Expand All @@ -64,15 +65,16 @@ export class ThresholdDecrypter {

// Retrieve decryption shares
public async retrieve(
provider: ethers.providers.Web3Provider,
walletClient: WalletClient,
conditionExpr: ConditionExpression,
ciphertext: Ciphertext
): Promise<DecryptionShareSimple[]> {
const publicClient = toPublicClient(walletClient);
const dkgParticipants = await DkgCoordinatorAgent.getParticipants(
provider,
publicClient,
this.ritualId
);
const contextStr = await conditionExpr.buildContext(provider).toJson();
const contextStr = await conditionExpr.buildContext(walletClient).toJson();
const { sharedSecrets, encryptedRequests } = this.makeDecryptionRequests(
this.ritualId,
ciphertext,
Expand Down
Loading

1 comment on commit 3796355

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundled size for the package is listed below:

build/main/src/characters: 78.13 KB
build/main/src/kits: 19.53 KB
build/main/src/conditions/context: 42.97 KB
build/main/src/conditions/predefined: 19.53 KB
build/main/src/conditions/base: 54.69 KB
build/main/src/conditions: 156.25 KB
build/main/src/agents: 39.06 KB
build/main/src/sdk/strategy: 35.16 KB
build/main/src/sdk: 46.88 KB
build/main/src/policies: 19.53 KB
build/main/src: 460.94 KB
build/main/types/ethers-contracts/factories: 82.03 KB
build/main/types/ethers-contracts: 152.34 KB
build/main/types: 156.25 KB
build/main: 714.84 KB
build/module/src/characters: 78.13 KB
build/module/src/kits: 19.53 KB
build/module/src/conditions/context: 42.97 KB
build/module/src/conditions/predefined: 19.53 KB
build/module/src/conditions/base: 54.69 KB
build/module/src/conditions: 156.25 KB
build/module/src/agents: 39.06 KB
build/module/src/sdk/strategy: 31.25 KB
build/module/src/sdk: 42.97 KB
build/module/src/policies: 19.53 KB
build/module/src: 453.13 KB
build/module/types/ethers-contracts/factories: 82.03 KB
build/module/types/ethers-contracts: 152.34 KB
build/module/types: 156.25 KB
build/module: 707.03 KB
build: 1.39 MB

Please sign in to comment.