diff --git a/demos/taco-demo/package.json b/demos/taco-demo/package.json index 3a10f4a1d..62450e6aa 100644 --- a/demos/taco-demo/package.json +++ b/demos/taco-demo/package.json @@ -21,7 +21,8 @@ "react": "^18.2.0", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", - "react-spinners": "^0.13.6" + "react-spinners": "^0.13.6", + "viem": "^1.19.9" }, "devDependencies": { "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", diff --git a/demos/taco-nft-demo/package.json b/demos/taco-nft-demo/package.json index f970ff03b..1cd8a06cf 100644 --- a/demos/taco-nft-demo/package.json +++ b/demos/taco-nft-demo/package.json @@ -21,7 +21,8 @@ "react": "^18.2.0", "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", - "react-spinners": "^0.13.6" + "react-spinners": "^0.13.6", + "viem": "^1.19.9" }, "devDependencies": { "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", diff --git a/examples/pre/nextjs/package.json b/examples/pre/nextjs/package.json index eaa1c5dcb..aa65d9f89 100644 --- a/examples/pre/nextjs/package.json +++ b/examples/pre/nextjs/package.json @@ -11,14 +11,17 @@ }, "dependencies": { "@nucypher/pre": "workspace:*", + "ethers": "^5.7.2", + "next": "14.0.3", + "react": "18.2.0", + "react-dom": "18.2.0", + "viem": "^1.19.9" + }, + "devDependencies": { "@types/node": "20.6.3", "@types/react": "18.2.37", "@types/react-dom": "18.2.14", "eslint": "8.53.0", - "eslint-config-next": "14.0.2", - "ethers": "^5.7.2", - "next": "14.0.3", - "react": "18.2.0", - "react-dom": "18.2.0" + "eslint-config-next": "14.0.2" } } diff --git a/examples/pre/nodejs/package.json b/examples/pre/nodejs/package.json index 35a479f94..d25175642 100644 --- a/examples/pre/nodejs/package.json +++ b/examples/pre/nodejs/package.json @@ -11,7 +11,10 @@ }, "dependencies": { "@nucypher/pre": "workspace:*", - "dotenv": "^16.3.1", - "ethers": "^5.7.2" + "ethers": "^5.7.2", + "viem": "^1.19.9" + }, + "devDependencies": { + "dotenv": "^16.3.1" } } diff --git a/examples/pre/react/package.json b/examples/pre/react/package.json index ee1ec43fd..63b981842 100644 --- a/examples/pre/react/package.json +++ b/examples/pre/react/package.json @@ -26,7 +26,8 @@ "@nucypher/pre": "workspace:*", "react": "^18.2.0", "react-dom": "^18.2.0", - "ethers": "^5.7.2" + "ethers": "^5.7.2", + "viem": "^1.19.9" }, "devDependencies": { "@types/node": "^16.18.50", diff --git a/examples/pre/webpack-5/package.json b/examples/pre/webpack-5/package.json index 14a0f6413..c78ef84d2 100644 --- a/examples/pre/webpack-5/package.json +++ b/examples/pre/webpack-5/package.json @@ -12,7 +12,8 @@ "type-check": "tsc" }, "dependencies": { - "@nucypher/pre": "workspace:*" + "@nucypher/pre": "workspace:*", + "viem": "^1.19.9" }, "devDependencies": { "copy-webpack-plugin": "^11.0.0", diff --git a/examples/taco/nextjs/package.json b/examples/taco/nextjs/package.json index bb2601d8b..82595f8ac 100644 --- a/examples/taco/nextjs/package.json +++ b/examples/taco/nextjs/package.json @@ -12,15 +12,17 @@ "dependencies": { "@nucypher/shared": "workspace:*", "@nucypher/taco": "workspace:*", - "@types/node": "20.6.3", - "@types/react": "18.2.37", - "@types/react-dom": "18.2.14", - "eslint": "8.53.0", - "eslint-config-next": "14.0.2", "ethers": "^5.7.2", "next": "14.0.3", "react": "18.2.0", "react-dom": "18.2.0", - "typescript": "5.2.2" + "viem": "^1.19.9" + }, + "devDependencies": { + "@types/node": "20.6.3", + "@types/react": "18.2.37", + "@types/react-dom": "18.2.14", + "eslint": "8.53.0", + "eslint-config-next": "14.0.2" } } diff --git a/examples/taco/nextjs/src/hooks/useTaco.ts b/examples/taco/nextjs/src/hooks/useTaco.ts index be78a7bb5..b1b795837 100644 --- a/examples/taco/nextjs/src/hooks/useTaco.ts +++ b/examples/taco/nextjs/src/hooks/useTaco.ts @@ -17,7 +17,7 @@ export default function useTaco({ }: { ritualId: number; domain: Domain; - provider: ethers.providers.Provider | undefined; + publicClient: PublicClient | undefined; }) { const [isInit, setIsInit] = useState(false); diff --git a/examples/taco/nodejs/package.json b/examples/taco/nodejs/package.json index ecf9cdb3b..d222fc8c9 100644 --- a/examples/taco/nodejs/package.json +++ b/examples/taco/nodejs/package.json @@ -11,7 +11,10 @@ }, "dependencies": { "@nucypher/taco": "workspace:*", - "dotenv": "^16.3.1", - "ethers": "^5.7.2" + "ethers": "^5.7.2", + "viem": "^1.19.9" + }, + "devDependencies": { + "dotenv": "^16.3.1" } } diff --git a/examples/taco/react/package.json b/examples/taco/react/package.json index f291ff05d..6dceee30f 100644 --- a/examples/taco/react/package.json +++ b/examples/taco/react/package.json @@ -25,16 +25,15 @@ "dependencies": { "@nucypher/shared": "workspace:*", "@nucypher/taco": "workspace:*", + "ethers": "^5.7.2", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "viem": "^1.19.9" }, "devDependencies": { "@types/node": "^16.18.50", "@types/react": "^18.2.37", "@types/react-dom": "^18.2.14", "react-scripts": "^5.0.1" - }, - "peerDependencies": { - "ethers": "^5.7.2" } } diff --git a/examples/taco/react/src/hooks/useTaco.ts b/examples/taco/react/src/hooks/useTaco.ts index ed7732eb6..3c123c9d7 100644 --- a/examples/taco/react/src/hooks/useTaco.ts +++ b/examples/taco/react/src/hooks/useTaco.ts @@ -17,7 +17,7 @@ export default function useTaco({ }: { ritualId: number; domain: Domain; - provider: ethers.providers.Provider | undefined; + publicClient: PublicClient | undefined; }) { const [isInit, setIsInit] = useState(false); diff --git a/examples/taco/webpack-5/package.json b/examples/taco/webpack-5/package.json index 8a2cf997b..2a4a3c35b 100644 --- a/examples/taco/webpack-5/package.json +++ b/examples/taco/webpack-5/package.json @@ -12,7 +12,9 @@ "type-check": "tsc" }, "dependencies": { - "@nucypher/taco": "workspace:*" + "@nucypher/taco": "workspace:*", + "viem": "^1.19.9", + "ethers": "^5.7.2" }, "devDependencies": { "copy-webpack-plugin": "^11.0.0", @@ -20,8 +22,5 @@ "webpack": "^5.4.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.7.4" - }, - "peerDependencies": { - "ethers": "^5.7.2" } } diff --git a/packages/pre/package.json b/packages/pre/package.json index 82b475a75..28de16fb0 100644 --- a/packages/pre/package.json +++ b/packages/pre/package.json @@ -40,7 +40,8 @@ "dependencies": { "@nucypher/nucypher-core": "^0.13.0-alpha.1", "@nucypher/shared": "workspace:*", - "ethers": "^5.7.2" + "ethers": "^5.7.2", + "viem": "^1.19.9" }, "devDependencies": { "@nucypher/test-utils": "workspace:*" diff --git a/packages/pre/src/characters/alice.ts b/packages/pre/src/characters/alice.ts index 45082af1d..1278b4943 100644 --- a/packages/pre/src/characters/alice.ts +++ b/packages/pre/src/characters/alice.ts @@ -4,8 +4,14 @@ import { Signer, VerifiedKeyFrag, } from '@nucypher/nucypher-core'; -import { ChecksumAddress, Domain, PorterClient } from '@nucypher/shared'; -import { ethers } from 'ethers'; +import { + ChecksumAddress, + Domain, + PorterClient, + toPublicClient, +} from '@nucypher/shared'; +import { PublicClient, WalletClient } from 'viem'; +import { getBlock, getBlockNumber } from 'viem/actions'; import { Keyring } from '../keyring'; import { @@ -41,8 +47,7 @@ export class Alice { } public async grant( - provider: ethers.providers.Provider, - signer: ethers.Signer, + walletClient: WalletClient, domain: Domain, porterUri: string, policyParameters: BlockchainPolicyParameters, @@ -55,12 +60,12 @@ export class Alice { excludeUrsulas, includeUrsulas, ); - const policy = await this.createPolicy(provider, policyParameters); - return await policy.enact(provider, signer, domain, ursulas); + const policy = await this.createPolicy(walletClient, policyParameters); + return await policy.enact(walletClient, domain, ursulas); } public async generatePreEnactedPolicy( - provider: ethers.providers.Provider, + walletClient: WalletClient, porterUri: string, policyParameters: BlockchainPolicyParameters, includeUrsulas?: readonly ChecksumAddress[], @@ -72,7 +77,7 @@ export class Alice { excludeUrsulas, includeUrsulas, ); - const policy = await this.createPolicy(provider, policyParameters); + const policy = await this.createPolicy(walletClient, policyParameters); return await policy.generatePreEnactedPolicy(ursulas); } @@ -95,11 +100,12 @@ export class Alice { } private async createPolicy( - provider: ethers.providers.Provider, + walletClient: WalletClient, rawParameters: BlockchainPolicyParameters, ): Promise { + const publicClient = toPublicClient(walletClient); const { bob, label, threshold, shares, startDate, endDate } = - await this.validatePolicyParameters(provider, rawParameters); + await this.validatePolicyParameters(publicClient, rawParameters); const { delegatingKey, verifiedKFrags } = this.generateKFrags( bob, label, @@ -120,7 +126,7 @@ export class Alice { } private async validatePolicyParameters( - provider: ethers.providers.Provider, + publicClient: PublicClient, rawParams: BlockchainPolicyParameters, ): Promise { const startDate = rawParams.startDate ?? new Date(); @@ -142,9 +148,9 @@ export class Alice { ); } - const blockNumber = await provider.getBlockNumber(); - const block = await provider.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}).`, diff --git a/packages/pre/src/policy.ts b/packages/pre/src/policy.ts index 0f593b1e4..301164ca4 100644 --- a/packages/pre/src/policy.ts +++ b/packages/pre/src/policy.ts @@ -13,10 +13,11 @@ import { toBytes, toCanonicalAddress, toEpoch, + toPublicClient, Ursula, zip, } from '@nucypher/shared'; -import { ethers } from 'ethers'; +import { WalletClient } from 'viem'; import { Alice, RemoteBob } from './characters'; @@ -47,11 +48,10 @@ export class PreEnactedPolicy implements IPreEnactedPolicy { ) {} public async enact( - provider: ethers.providers.Provider, - signer: ethers.Signer, + walletClient: WalletClient, domain: Domain, ): Promise { - const txHash = await this.publish(provider, signer, domain); + const txHash = await this.publish(walletClient, domain); return { ...this, txHash, @@ -59,23 +59,25 @@ export class PreEnactedPolicy implements IPreEnactedPolicy { } private async publish( - provider: ethers.providers.Provider, - signer: ethers.Signer, + walletClient: WalletClient, domain: Domain, ): Promise { + const publicClient = toPublicClient(walletClient); const startTimestamp = toEpoch(this.startTimestamp); const endTimestamp = toEpoch(this.endTimestamp); - const ownerAddress = await signer.getAddress(); + const ownerAddress = await walletClient.account?.address; + if (!ownerAddress) { + throw new Error('No account set'); + } const value = await PreSubscriptionManagerAgent.getPolicyCost( - provider, + publicClient, domain, this.size, startTimestamp, endTimestamp, ); const tx = await PreSubscriptionManagerAgent.createPolicy( - provider, - signer, + walletClient, domain, value, this.id.toBytes(), @@ -119,13 +121,12 @@ export class BlockchainPolicy { } public async enact( - provider: ethers.providers.Provider, - signer: ethers.Signer, + walletClient: WalletClient, domain: Domain, ursulas: readonly Ursula[], ): Promise { const preEnacted = await this.generatePreEnactedPolicy(ursulas); - return await preEnacted.enact(provider, signer, domain); + return await preEnacted.enact(walletClient, domain); } public async generatePreEnactedPolicy( diff --git a/packages/pre/test/acceptance/alice-grants.test.ts b/packages/pre/test/acceptance/alice-grants.test.ts index d5f02c487..9cb51db1a 100644 --- a/packages/pre/test/acceptance/alice-grants.test.ts +++ b/packages/pre/test/acceptance/alice-grants.test.ts @@ -9,9 +9,8 @@ import { ChecksumAddress, domains, initialize, Ursula } from '@nucypher/shared'; import { bytesEqual, fakePorterUri, - fakeProvider, - fakeSigner, fakeUrsulas, + fakeWalletClient, fromBytes, mockGetUrsulas, mockRetrieveCFragsRequest, @@ -71,8 +70,7 @@ describe('story: alice shares message with bob through policy', () => { endDate, }; policy = await alice.grant( - fakeProvider(), - fakeSigner(), + fakeWalletClient, domains.DEV, fakePorterUri, policyParams, diff --git a/packages/pre/test/acceptance/delay-enact.test.ts b/packages/pre/test/acceptance/delay-enact.test.ts index efdb9f946..ad9403d00 100644 --- a/packages/pre/test/acceptance/delay-enact.test.ts +++ b/packages/pre/test/acceptance/delay-enact.test.ts @@ -1,9 +1,8 @@ import { bytesEqual, fakePorterUri, - fakeProvider, - fakeSigner, fakeUrsulas, + fakeWalletClient, mockGetUrsulas, } from '@nucypher/test-utils'; import { beforeAll, describe, expect, it } from 'vitest'; @@ -30,7 +29,6 @@ describe('story: alice creates a policy but someone else enacts it', () => { }); it('alice generates a new policy', async () => { - const provider = fakeProvider(); const getUrsulasSpy = mockGetUrsulas(fakeUrsulas(shares)); const generateKFragsSpy = mockGenerateKFrags(); const publishToBlockchainSpy = mockPublishToBlockchain(); @@ -47,7 +45,7 @@ describe('story: alice creates a policy but someone else enacts it', () => { }; const preEnactedPolicy = await alice.generatePreEnactedPolicy( - provider, + fakeWalletClient, fakePorterUri, policyParams, ); @@ -60,8 +58,7 @@ describe('story: alice creates a policy but someone else enacts it', () => { expect(preEnactedPolicy.label).toBe(label); const enacted = await preEnactedPolicy.enact( - provider, - fakeSigner(), + fakeWalletClient, domains.DEV, ); expect(enacted.txHash).toBeDefined(); diff --git a/packages/shared/package.json b/packages/shared/package.json index bd36e52b2..11644605a 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -47,7 +47,8 @@ "axios": "^1.6.2", "deep-equal": "^2.2.1", "ethers": "^5.7.2", - "qs": "^6.10.1" + "qs": "^6.10.1", + "viem": "^1.19.9" }, "devDependencies": { "@typechain/ethers-v5": "^11.1.2", diff --git a/packages/shared/src/contracts/agents/coordinator.ts b/packages/shared/src/contracts/agents/coordinator.ts index 71721cc6e..111109cbe 100644 --- a/packages/shared/src/contracts/agents/coordinator.ts +++ b/packages/shared/src/contracts/agents/coordinator.ts @@ -4,11 +4,13 @@ import { SessionStaticKey, ThresholdMessageKit, } from '@nucypher/nucypher-core'; -import { BigNumberish, ethers } from 'ethers'; +import { BigNumberish } from 'ethers'; +import { PublicClient, WalletClient } from 'viem'; import { Domain } from '../../porter'; import { ChecksumAddress } from '../../types'; import { fromHexString } from '../../utils'; +import { publicClientToProvider, walletClientToSigner } from '../../viem'; import { DEFAULT_WAIT_N_CONFIRMATIONS } from '../const'; import { Coordinator__factory } from '../ethers-typechain'; import { BLS12381, Coordinator } from '../ethers-typechain/Coordinator'; @@ -46,11 +48,11 @@ export enum DkgRitualState { export class DkgCoordinatorAgent { public static async getParticipants( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, ritualId: number, ): Promise { - const coordinator = await this.connectReadOnly(provider, domain); + const coordinator = await this.connectReadOnly(publicClient, domain); const participants = await coordinator.getParticipants(ritualId); return participants.map((participant) => { @@ -65,15 +67,14 @@ export class DkgCoordinatorAgent { } public static async initializeRitual( - provider: ethers.providers.Provider, - signer: ethers.Signer, + walletClient: WalletClient, domain: Domain, providers: ChecksumAddress[], authority: string, duration: BigNumberish, accessController: string, ): Promise { - const coordinator = await this.connectReadWrite(provider, domain, signer); + const coordinator = await this.connectReadWrite(walletClient, domain); const tx = await coordinator.initiateRitual( providers, authority, @@ -89,30 +90,30 @@ export class DkgCoordinatorAgent { } public static async getRitual( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, ritualId: number, ): Promise { - const coordinator = await this.connectReadOnly(provider, domain); + const coordinator = await this.connectReadOnly(publicClient, domain); return await coordinator.rituals(ritualId); } public static async getRitualState( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, ritualId: number, ): Promise { - const coordinator = await this.connectReadOnly(provider, domain); + const coordinator = await this.connectReadOnly(publicClient, domain); return await coordinator.getRitualState(ritualId); } public static async onRitualEndEvent( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, ritualId: number, callback: (successful: boolean) => void, ): Promise { - const coordinator = await this.connectReadOnly(provider, domain); + const coordinator = await this.connectReadOnly(publicClient, domain); // 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); @@ -122,11 +123,11 @@ export class DkgCoordinatorAgent { } public static async getRitualIdFromPublicKey( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, dkgPublicKey: DkgPublicKey, ): Promise { - const coordinator = await this.connectReadOnly(provider, domain); + const coordinator = await this.connectReadOnly(publicClient, domain); const dkgPublicKeyBytes = dkgPublicKey.toBytes(); const pointStruct: BLS12381.G1PointStruct = { word0: dkgPublicKeyBytes.slice(0, 32), @@ -136,12 +137,12 @@ export class DkgCoordinatorAgent { } public static async isEncryptionAuthorized( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, ritualId: number, thresholdMessageKit: ThresholdMessageKit, ): Promise { - const coordinator = await this.connectReadOnly(provider, domain); + const coordinator = await this.connectReadOnly(publicClient, domain); return await coordinator.isEncryptionAuthorized( ritualId, thresholdMessageKit.acp.authorization, @@ -150,27 +151,32 @@ export class DkgCoordinatorAgent { } private static async connectReadOnly( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, - ) { - return await this.connect(provider, domain); + ): Promise { + const contractAddress = getContract( + domain, + publicClient.chain!.id, + 'COORDINATOR', + ); + return Coordinator__factory.connect( + contractAddress, + publicClientToProvider(publicClient), + ); } private static async connectReadWrite( - provider: ethers.providers.Provider, - domain: Domain, - signer: ethers.Signer, - ) { - return await this.connect(provider, domain, signer); - } - - private static async connect( - provider: ethers.providers.Provider, + walletClient: WalletClient, domain: Domain, - signer?: ethers.Signer, ): Promise { - const network = await provider.getNetwork(); - const contractAddress = getContract(domain, network.chainId, 'Coordinator'); - return Coordinator__factory.connect(contractAddress, signer ?? provider); + const contractAddress = getContract( + domain, + walletClient.chain!.id, + 'COORDINATOR', + ); + return Coordinator__factory.connect( + contractAddress, + walletClientToSigner(walletClient), + ); } } diff --git a/packages/shared/src/contracts/agents/global-allow-list.ts b/packages/shared/src/contracts/agents/global-allow-list.ts index fc09d5946..63b117043 100644 --- a/packages/shared/src/contracts/agents/global-allow-list.ts +++ b/packages/shared/src/contracts/agents/global-allow-list.ts @@ -1,57 +1,51 @@ import { getContract } from '@nucypher/nucypher-contracts'; -import { ethers } from 'ethers'; +import { PublicClient, WalletClient } from 'viem'; import { Domain } from '../../porter'; import { ChecksumAddress } from '../../types'; +import { publicClientToProvider, walletClientToSigner } from '../../viem'; import { DEFAULT_WAIT_N_CONFIRMATIONS } from '../const'; -import { GlobalAllowList, GlobalAllowList__factory } from '../ethers-typechain'; +import { GlobalAllowList__factory } from '../ethers-typechain'; export class GlobalAllowListAgent { public static async registerEncrypters( - provider: ethers.providers.Provider, - signer: ethers.Signer, + walletClient: WalletClient, domain: Domain, ritualId: number, encrypters: ChecksumAddress[], ): Promise { - const globalAllowList = await this.connectReadWrite( - provider, - domain, - signer, - ); + const globalAllowList = await this.connectReadWrite(walletClient, domain); const tx = await globalAllowList.authorize(ritualId, encrypters); await tx.wait(DEFAULT_WAIT_N_CONFIRMATIONS); } private static async connectReadOnly( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, ) { - return await this.connect(provider, domain); + const contractAddress = getContract( + domain, + publicClient.chain!.id, + 'GlobalAllowList', + ); + return GlobalAllowList__factory.connect( + contractAddress, + publicClientToProvider(publicClient), + ); } private static async connectReadWrite( - provider: ethers.providers.Provider, + walletClient: WalletClient, domain: Domain, - signer: ethers.Signer, ) { - return await this.connect(provider, domain, signer); - } - - private static async connect( - provider: ethers.providers.Provider, - domain: Domain, - signer?: ethers.Signer, - ): Promise { - const network = await provider.getNetwork(); const contractAddress = getContract( domain, - network.chainId, + walletClient.chain!.id, 'GlobalAllowList', ); return GlobalAllowList__factory.connect( contractAddress, - signer ?? provider, + walletClientToSigner(walletClient), ); } } diff --git a/packages/shared/src/contracts/agents/subscription-manager.ts b/packages/shared/src/contracts/agents/subscription-manager.ts index 20f787300..f51d3eba6 100644 --- a/packages/shared/src/contracts/agents/subscription-manager.ts +++ b/packages/shared/src/contracts/agents/subscription-manager.ts @@ -1,23 +1,16 @@ import { getContract } from '@nucypher/nucypher-contracts'; -import { - BigNumber, - ContractTransaction, - ethers, - utils as ethersUtils, -} from 'ethers'; +import { BigNumber, ContractTransaction, utils as ethersUtils } from 'ethers'; +import { PublicClient, WalletClient } from 'viem'; import { Domain } from '../../porter'; import { ChecksumAddress } from '../../types'; +import { publicClientToProvider, walletClientToSigner } from '../../viem'; import { DEFAULT_WAIT_N_CONFIRMATIONS } from '../const'; -import { - SubscriptionManager, - SubscriptionManager__factory, -} from '../ethers-typechain'; +import { SubscriptionManager__factory } from '../ethers-typechain'; export class PreSubscriptionManagerAgent { public static async createPolicy( - provider: ethers.providers.Provider, - signer: ethers.Signer, + walletClient: WalletClient, domain: Domain, valueInWei: BigNumber, policyId: Uint8Array, @@ -27,9 +20,8 @@ export class PreSubscriptionManagerAgent { ownerAddress: ChecksumAddress, ): Promise { const subscriptionManager = await this.connectReadWrite( - provider, + walletClient, domain, - signer, ); const overrides = { value: valueInWei.toString(), @@ -55,13 +47,16 @@ export class PreSubscriptionManagerAgent { } public static async getPolicyCost( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, size: number, startTimestamp: number, endTimestamp: number, ): Promise { - const subscriptionManager = await this.connectReadOnly(provider, domain); + const subscriptionManager = await this.connectReadOnly( + publicClient, + domain, + ); return await subscriptionManager.getPolicyCost( size, startTimestamp, @@ -70,34 +65,32 @@ export class PreSubscriptionManagerAgent { } private static async connectReadOnly( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, ) { - return await this.connect(provider, domain); + const contractAddress = getContract( + domain, + publicClient.chain!.id, + 'COORDINATOR', + ); + return SubscriptionManager__factory.connect( + contractAddress, + publicClientToProvider(publicClient), + ); } private static async connectReadWrite( - provider: ethers.providers.Provider, + walletClient: WalletClient, domain: Domain, - signer: ethers.Signer, ) { - return await this.connect(provider, domain, signer); - } - - private static async connect( - provider: ethers.providers.Provider, - domain: Domain, - signer?: ethers.Signer, - ): Promise { - const network = await provider.getNetwork(); const contractAddress = getContract( domain, - network.chainId, - 'SubscriptionManager', + walletClient.chain!.id, + 'COORDINATOR', ); return SubscriptionManager__factory.connect( contractAddress, - signer ?? provider, + walletClientToSigner(walletClient), ); } } diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 63f08aa5a..a67761818 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -2,6 +2,7 @@ export * from './contracts'; export * from './porter'; export type * from './types'; export * from './utils'; +export * from './viem'; export * from './web3'; // Re-exports diff --git a/packages/shared/src/viem.ts b/packages/shared/src/viem.ts new file mode 100644 index 000000000..eaa7c856b --- /dev/null +++ b/packages/shared/src/viem.ts @@ -0,0 +1,69 @@ +import { providers } from 'ethers'; +import { + createPublicClient, + http, + HttpTransport, + PublicClient, + WalletClient, + webSocket, +} from 'viem'; + +const transportForTransportType = (type: string) => { + switch (type) { + case 'http': + return http(); + case 'webSocket': + return webSocket(); + default: + throw new Error(`Unknown transport type: ${type}`); + } +}; + +export const toPublicClient = (client: WalletClient): PublicClient => + createPublicClient({ + chain: client.chain, + transport: transportForTransportType(client.transport.type), + }); + +// We need to convert from our PublicClient and WalletClient to ethers.js because we +// rely on typechain to generate our typescript bindings for our contracts, and there +// is no support for viem in typechain, so we use our legacy ethers.js bindings instead. + +// Adapted from: https://wagmi.sh/react/ethers-adapters + +export const publicClientToProvider = (publicClient: PublicClient) => { + const { chain, transport } = publicClient; + if (!chain) { + throw new Error('chain is undefined'); + } + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts!.ensRegistry!.address, + }; + if (transport.type === 'fallback') + return new providers.FallbackProvider( + (transport.transports as ReturnType[]).map( + ({ value }) => new providers.JsonRpcProvider(value?.url, network), + ), + ); + return new providers.JsonRpcProvider(transport.url, network); +}; + +export const walletClientToSigner = (walletClient: WalletClient) => { + const { account, chain, transport } = walletClient; + if (!account) { + throw new Error('account is undefined'); + } + if (!chain) { + throw new Error('chain is undefined'); + } + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts!.ensRegistry!.address, + }; + const provider = new providers.Web3Provider(transport, network); + + return provider.getSigner(account.address); +}; diff --git a/packages/taco/package.json b/packages/taco/package.json index 23573d607..708b495af 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -44,15 +44,14 @@ "@nucypher/shared": "^0.1.0-rc.4", "ethers": "^5.7.2", "semver": "^7.5.2", + "viem": "^1.19.9", "zod": "^3.22.4" }, "devDependencies": { + "@nucypher/shared": "workspace:*", "@nucypher/test-utils": "workspace:*", "@types/semver": "^7.5.4" }, - "peerDependencies": { - "@nucypher/shared": "workspace:*" - }, "engines": { "node": ">=18", "pnpm": ">=8.0.0" diff --git a/packages/taco/src/conditions/condition-expr.ts b/packages/taco/src/conditions/condition-expr.ts index da2fa3c95..85b4fb3bb 100644 --- a/packages/taco/src/conditions/condition-expr.ts +++ b/packages/taco/src/conditions/condition-expr.ts @@ -1,7 +1,7 @@ import { Conditions as WASMConditions } from '@nucypher/nucypher-core'; import { toJSON } from '@nucypher/shared'; -import { ethers } from 'ethers'; import { SemVer } from 'semver'; +import { PublicClient, WalletClient } from 'viem'; import { Condition } from './condition'; import { ConditionContext, CustomContextParam } from './context'; @@ -64,15 +64,15 @@ export class ConditionExpression { } public buildContext( - provider: ethers.providers.Provider, + publicClient: PublicClient, customParameters: Record = {}, - signer?: ethers.Signer, + walletClient?: WalletClient, ): ConditionContext { return new ConditionContext( - provider, + publicClient, this.condition, customParameters, - signer, + walletClient, ); } diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 7b528f70e..6dd62369a 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -1,6 +1,6 @@ import { Context, Conditions as WASMConditions } from '@nucypher/nucypher-core'; import { fromJSON, toJSON } from '@nucypher/shared'; -import { ethers } from 'ethers'; +import { PublicClient, WalletClient } from 'viem'; import { CompoundConditionType } from '../compound-condition'; import { Condition, ConditionProps } from '../condition'; @@ -32,15 +32,14 @@ export class ConditionContext { private readonly walletAuthProvider?: WalletAuthenticationProvider; constructor( - private readonly provider: ethers.providers.Provider, + private readonly publicClient: PublicClient, private readonly condition: Condition, public readonly customParameters: Record = {}, - private readonly signer?: ethers.Signer, + public readonly walletClient?: WalletClient, ) { - if (this.signer) { + if (this.walletClient) { this.walletAuthProvider = new WalletAuthenticationProvider( - this.provider, - this.signer, + this.walletClient, ); } this.validate(); @@ -56,7 +55,7 @@ export class ConditionContext { } }); - if (this.condition.requiresSigner() && !this.signer) { + if (this.condition.requiresSigner() && !this.walletClient) { throw new Error(ERR_SIGNER_REQUIRED); } } @@ -162,10 +161,10 @@ export class ConditionContext { params: Record, ): ConditionContext { return new ConditionContext( - this.provider, + this.publicClient, this.condition, params, - this.signer, + this.walletClient, ); } @@ -175,18 +174,16 @@ export class ConditionContext { } public static fromConditions( - provider: ethers.providers.Provider, + publicClient: PublicClient, conditions: WASMConditions, - signer?: ethers.Signer, + walletClient?: WalletClient, customParameters?: Record, ): ConditionContext { - const innerCondition = - ConditionExpression.fromWASMConditions(conditions).condition; return new ConditionContext( - provider, - innerCondition, + publicClient, + ConditionExpression.fromWASMConditions(conditions).condition, customParameters, - signer, + walletClient, ); } } diff --git a/packages/taco/src/conditions/context/providers.ts b/packages/taco/src/conditions/context/providers.ts index 4b6c8f43a..f297961e6 100644 --- a/packages/taco/src/conditions/context/providers.ts +++ b/packages/taco/src/conditions/context/providers.ts @@ -1,8 +1,13 @@ -import type { TypedDataSigner } from '@ethersproject/abstract-signer'; -import { ethers } from 'ethers'; import { utils as ethersUtils } from 'ethers/lib/ethers'; +import { WalletClient } from 'viem'; +import { + getBlock, + getBlockNumber, + requestAddresses, + signTypedData, +} from 'viem/actions'; -import { Eip712TypedData, FormattedTypedData } from '../../web3'; +import { Eip712TypedData } from '../../web3'; export interface TypedSignature { signature: string; @@ -19,13 +24,10 @@ interface ChainData { export class WalletAuthenticationProvider { private walletSignature?: Record; - constructor( - private readonly provider: ethers.providers.Provider, - private readonly signer: ethers.Signer, - ) {} + constructor(private readonly client: WalletClient) {} public async getOrCreateWalletSignature(): Promise { - const address = await this.signer.getAddress(); + const address = await this.getAddress(); const storageKey = `wallet-signature-${address}`; // If we have a signature in localStorage, return it @@ -63,69 +65,61 @@ export class WalletAuthenticationProvider { private async createWalletSignature(): Promise { // Ensure freshness of the signature const { blockNumber, blockHash, chainId } = await this.getChainData(); - const address = await this.signer.getAddress(); + const address = await this.getAddress(); const signatureText = `I'm the owner of address ${address} as of block number ${blockNumber}`; - const salt = ethersUtils.hexlify(ethersUtils.randomBytes(32)); + const salt = ethersUtils.hexlify( + ethersUtils.randomBytes(32), + ) as `0x${string}`; + const [account] = await requestAddresses(this.client); - const typedData: Eip712TypedData = { - types: { - Wallet: [ - { name: 'address', type: 'address' }, - { name: 'signatureText', type: 'string' }, - { name: 'blockNumber', type: 'uint256' }, - { name: 'blockHash', type: 'bytes32' }, - ], - }, - domain: { - name: 'taco', - version: '1', - chainId, - salt, - }, - message: { - address, - signatureText, - blockNumber, - blockHash, - }, + const types = { + Wallet: [ + { name: 'name', type: 'string' }, + { name: 'version', type: 'string' }, + { name: 'chainId', type: 'uint256' }, + { name: 'salt', type: 'bytes32' }, + ], }; - // https://github.com/ethers-io/ethers.js/issues/1431#issuecomment-813950552 - const signature = await ( - this.signer as unknown as TypedDataSigner - )._signTypedData(typedData.domain, typedData.types, typedData.message); - - const formattedTypedData: FormattedTypedData = { - ...typedData, - primaryType: 'Wallet', - types: { - ...typedData.types, - EIP712Domain: [ - { - name: 'name', - type: 'string', - }, - { - name: 'version', - type: 'string', - }, - { - name: 'chainId', - type: 'uint256', - }, - { - name: 'salt', - type: 'bytes32', - }, - ], - }, + const domain = { + name: 'cbd', + version: '1', + chainId, + salt, + }; + const message = { + address, + signatureText, + blockNumber, + blockHash, }; - return { signature, typedData: formattedTypedData, address }; + const typedData = { + account, + types, + primaryType: 'Wallet', + domain, + message, + } as const; + const signature = await signTypedData(this.client, typedData); + + return { signature, typedData, address }; + } + + private async getAddress() { + const [address] = await requestAddresses(this.client); + if (!address) { + throw new Error('No address found'); + } + return address; } private async getChainData(): Promise { - const blockNumber = await this.provider.getBlockNumber(); - const blockHash = (await this.provider.getBlock(blockNumber)).hash; - const chainId = (await this.provider.getNetwork()).chainId; + const blockNumber = Number(await getBlockNumber(this.client)); + const blockHash = (await getBlock(this.client)).hash; + const chainId = this.client.chain?.id; + if (!chainId) { + // TODO: Improve, somehow + throw new Error('Chain ID is not set'); + } return { blockNumber, blockHash, chainId }; } } diff --git a/packages/taco/src/dkg.ts b/packages/taco/src/dkg.ts index 8e6ce50ec..293d85bd7 100644 --- a/packages/taco/src/dkg.ts +++ b/packages/taco/src/dkg.ts @@ -5,8 +5,10 @@ import { DkgRitualState, Domain, fromHexString, + toPublicClient, } from '@nucypher/shared'; -import { BigNumberish, ethers } from 'ethers'; +import { BigNumberish } from 'ethers'; +import { PublicClient, WalletClient } from 'viem'; export interface DkgRitualJSON { id: number; @@ -67,8 +69,7 @@ const ERR_RITUAL_NOT_FINALIZED = (ritualId: number, ritual: DkgRitual) => export class DkgClient { public static async initializeRitual( - provider: ethers.providers.Provider, - signer: ethers.Signer, + walletClient: WalletClient, domain: Domain, ursulas: ChecksumAddress[], authority: string, @@ -76,9 +77,9 @@ export class DkgClient { accessController: string, waitUntilEnd = false, ): Promise { + const publicClient = toPublicClient(walletClient); const ritualId = await DkgCoordinatorAgent.initializeRitual( - provider, - signer, + walletClient, domain, ursulas.sort(), // Contract call requires sorted addresses authority, @@ -88,13 +89,13 @@ export class DkgClient { if (waitUntilEnd) { const isSuccessful = await DkgClient.waitUntilRitualEnd( - provider, + publicClient, domain, ritualId, ); if (!isSuccessful) { const ritualState = await DkgCoordinatorAgent.getRitualState( - provider, + publicClient, domain, ritualId, ); @@ -108,7 +109,7 @@ export class DkgClient { } private static waitUntilRitualEnd = async ( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, ritualId: number, ): Promise => { @@ -121,7 +122,7 @@ export class DkgClient { } }; DkgCoordinatorAgent.onRitualEndEvent( - provider, + publicClient, domain, ritualId, callback, @@ -130,17 +131,17 @@ export class DkgClient { }; public static async getRitual( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, ritualId: number, ): Promise { const ritualState = await DkgCoordinatorAgent.getRitualState( - provider, + publicClient, domain, ritualId, ); const ritual = await DkgCoordinatorAgent.getRitual( - provider, + publicClient, domain, ritualId, ); @@ -158,11 +159,11 @@ export class DkgClient { } public static async getActiveRitual( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, ritualId: number, ): Promise { - const ritual = await DkgClient.getRitual(provider, domain, ritualId); + const ritual = await DkgClient.getRitual(publicClient, domain, ritualId); if (ritual.state !== DkgRitualState.ACTIVE) { throw new Error(ERR_RITUAL_NOT_FINALIZED(ritualId, ritual)); } @@ -172,14 +173,14 @@ 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 ritual = await DkgCoordinatorAgent.getRitual(this.publicClient, ritualId); // const participants = await DkgCoordinatorAgent.getParticipants( - // this.provider, + // this.publicClient, // ritualId // ); // // const validatorMessages = participants.map((p) => { - // const validatorAddress = EthereumAddress.fromString(p.provider); + // const validatorAddress = EthereumAddress.fromString(p.publicClient); // const publicKey = FerveoPublicKey.fromBytes(fromHexString(p.???)); // const validator = new Validator(validatorAddress, publicKey); // const transcript = Transcript.fromBytes(fromHexString(p.transcript)); diff --git a/packages/taco/src/taco.ts b/packages/taco/src/taco.ts index a9d9054b2..837d5effd 100644 --- a/packages/taco/src/taco.ts +++ b/packages/taco/src/taco.ts @@ -13,8 +13,8 @@ import { GlobalAllowListAgent, toBytes, } from '@nucypher/shared'; -import { ethers } from 'ethers'; import { keccak256 } from 'ethers/lib/utils'; +import { PublicClient, WalletClient } from 'viem'; import { Condition, @@ -28,7 +28,7 @@ import { retrieveAndDecrypt } from './tdec'; * Encrypts a message under given conditions using a public key from an active DKG ritual. * * @export - * @param {ethers.providers.Provider} provider - Instance of ethers provider which is used to interact with + * @param {PublicClient} publicClient - Instance of viem's PublicClient which is used to interact with * your selected network. * @param {Domain} domain - Represents the logical network in which the encryption will be performed. * Must match the `ritualId`. @@ -45,12 +45,12 @@ import { retrieveAndDecrypt } from './tdec'; * @throws {Error} If the active DKG Ritual cannot be retrieved an error is thrown. */ export const encrypt = async ( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, message: Uint8Array | string, condition: Condition, ritualId: number, - authSigner: ethers.Signer, + walletClient: WalletClient, // remove ): Promise => { // TODO(#264): Enable ritual initialization // if (ritualId === undefined) { @@ -64,13 +64,17 @@ export const encrypt = async ( // // Given that we just initialized the ritual, this should never happen // throw new Error('Ritual ID is undefined'); // } - const dkgRitual = await DkgClient.getActiveRitual(provider, domain, ritualId); + const dkgRitual = await DkgClient.getActiveRitual( + publicClient, + domain, + ritualId, + ); return await encryptWithPublicKey( message, condition, dkgRitual.dkgPublicKey, - authSigner, + walletClient, ); }; @@ -93,7 +97,7 @@ export const encryptWithPublicKey = async ( message: Uint8Array | string, condition: Condition, dkgPublicKey: DkgPublicKey, - authSigner: ethers.Signer, + walletClient: WalletClient, // remove ): Promise => { if (typeof message === 'string') { message = toBytes(message); @@ -108,7 +112,11 @@ export const encryptWithPublicKey = async ( ); const headerHash = keccak256(ciphertext.header.toBytes()); - const authorization = await authSigner.signMessage(fromHexString(headerHash)); + // TODO: need an account here + const authorization = await walletClient.signMessage({ + account: '0x0', + message: headerHash, + }); const acp = new AccessControlPolicy( authenticatedData, fromHexString(authorization), @@ -121,7 +129,7 @@ export const encryptWithPublicKey = async ( * Decrypts an encrypted message. * * @export - * @param {ethers.providers.Provider} provider - Instance of ethers provider which is used to interact with + * @param {PublicClient} publicClient - Instance of viem's PublicClient which is used to interact with * your selected network. * @param {Domain} domain - Represents the logical network in which the decryption will be performed. * Must match the `ritualId`. @@ -138,11 +146,11 @@ export const encryptWithPublicKey = async ( * an error is thrown. */ export const decrypt = async ( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, messageKit: ThresholdMessageKit, porterUri?: string, - signer?: ethers.Signer, + walletClient?: WalletClient, customParameters?: Record, ): Promise => { if (!porterUri) { @@ -150,19 +158,23 @@ export const decrypt = async ( } const ritualId = await DkgCoordinatorAgent.getRitualIdFromPublicKey( - provider, + publicClient, domain, messageKit.acp.publicKey, ); - const ritual = await DkgClient.getActiveRitual(provider, domain, ritualId); + const ritual = await DkgClient.getActiveRitual( + publicClient, + domain, + ritualId, + ); return retrieveAndDecrypt( - provider, + publicClient, domain, porterUri, messageKit, ritualId, ritual.threshold, - signer, + walletClient, customParameters, ); }; @@ -171,7 +183,7 @@ export const decrypt = async ( * Checks if the encryption from the provided messageKit is authorized for the specified ritual. * * @export - * @param {ethers.providers.Provider} provider - Instance of ethers provider which is used to interact with + * @param {PublicClient} publicClient - Instance of viem's PublicClient which is used to interact with * your selected network. * @param {Domain} domain - The domain which was used to encrypt the network. Must match the `ritualId`. * @param {ThresholdMessageKit} messageKit - The encrypted message kit to be checked. @@ -181,28 +193,26 @@ export const decrypt = async ( * True if authorized, false otherwise */ export const isAuthorized = async ( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, messageKit: ThresholdMessageKit, ritualId: number, ) => DkgCoordinatorAgent.isEncryptionAuthorized( - provider, + publicClient, domain, ritualId, messageKit, ); export const registerEncrypters = async ( - provider: ethers.providers.Provider, - signer: ethers.Signer, + walletClient: WalletClient, domain: Domain, ritualId: number, encrypters: ChecksumAddress[], ): Promise => { await GlobalAllowListAgent.registerEncrypters( - provider, - signer, + walletClient, domain, ritualId, encrypters, diff --git a/packages/taco/src/tdec.ts b/packages/taco/src/tdec.ts index 642506c67..f929322d4 100644 --- a/packages/taco/src/tdec.ts +++ b/packages/taco/src/tdec.ts @@ -22,6 +22,7 @@ import { } from '@nucypher/shared'; import { ethers } from 'ethers'; import { arrayify, keccak256 } from 'ethers/lib/utils'; +import { PublicClient, WalletClient } from 'viem'; import { ConditionContext, @@ -62,23 +63,23 @@ export const encryptMessage = async ( // Retrieve and decrypt ciphertext using provider and condition expression export const retrieveAndDecrypt = async ( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, porterUri: string, thresholdMessageKit: ThresholdMessageKit, ritualId: number, threshold: number, - signer?: ethers.Signer, + walletClient?: WalletClient, customParameters?: Record, ): Promise => { const decryptionShares = await retrieve( - provider, + publicClient, domain, porterUri, thresholdMessageKit, ritualId, threshold, - signer, + walletClient, customParameters, ); const sharedSecret = combineDecryptionSharesSimple(decryptionShares); @@ -87,24 +88,24 @@ export const retrieveAndDecrypt = async ( // Retrieve decryption shares const retrieve = async ( - provider: ethers.providers.Provider, + publicClient: PublicClient, domain: Domain, porterUri: string, thresholdMessageKit: ThresholdMessageKit, ritualId: number, threshold: number, - signer?: ethers.Signer, + walletClient?: WalletClient, customParameters?: Record, ): Promise => { const dkgParticipants = await DkgCoordinatorAgent.getParticipants( - provider, + publicClient, domain, ritualId, ); const wasmContext = await ConditionContext.fromConditions( - provider, + publicClient, thresholdMessageKit.acp.conditions, - signer, + walletClient, customParameters, ).toWASMContext(); const { sharedSecrets, encryptedRequests } = await makeDecryptionRequests( diff --git a/packages/taco/test/conditions/base/contract.test.ts b/packages/taco/test/conditions/base/contract.test.ts index be469ab32..4320a2e6a 100644 --- a/packages/taco/test/conditions/base/contract.test.ts +++ b/packages/taco/test/conditions/base/contract.test.ts @@ -1,5 +1,6 @@ import { initialize } from '@nucypher/nucypher-core'; -import { fakeProvider, fakeSigner } from '@nucypher/test-utils'; +import { fakePublicClient, fakeWalletClient } from '@nucypher/test-utils'; +import { mockViemActions } from '@nucypher/test-utils'; import { beforeAll, describe, expect, it } from 'vitest'; import { @@ -14,6 +15,8 @@ import { contractConditionSchema } from '../../../src/conditions/base/contract'; import { USER_ADDRESS_PARAM } from '../../../src/conditions/const'; import { testContractConditionObj, testFunctionAbi } from '../../test-utils'; +mockViemActions(); + describe('validation', () => { it('accepts on a valid schema', () => { const result = ContractCondition.validate( @@ -174,7 +177,7 @@ describe('supports custom function abi', () => { it('accepts custom function abi with a custom parameter', async () => { const asJson = await conditionExpr - .buildContext(fakeProvider(), {}, fakeSigner()) + .buildContext(fakePublicClient, {}, fakeWalletClient) .withCustomParams(customParams) .toJson(); diff --git a/packages/taco/test/conditions/conditions.test.ts b/packages/taco/test/conditions/conditions.test.ts index 6ad391470..2c59b7736 100644 --- a/packages/taco/test/conditions/conditions.test.ts +++ b/packages/taco/test/conditions/conditions.test.ts @@ -1,11 +1,14 @@ import { ChainId } from '@nucypher/shared'; -import { fakeProvider, fakeSigner } from '@nucypher/test-utils'; +import { fakePublicClient, fakeWalletClient } from '@nucypher/test-utils'; +import { mockViemActions } from '@nucypher/test-utils'; import { beforeAll, describe, expect, it } from 'vitest'; import { initialize } from '../../src'; import { CompoundCondition, ConditionContext } from '../../src/conditions'; import { SUPPORTED_CHAIN_IDS } from '../../src/conditions/const'; +mockViemActions(); + describe('conditions', () => { beforeAll(async () => { await initialize(); @@ -37,10 +40,12 @@ describe('conditions', () => { expect(condition.requiresSigner()).toBeTruthy(); const context = new ConditionContext( - fakeProvider(), + fakePublicClient, condition, - { ':time': 100 }, - fakeSigner(), + { + ':time': 100, + }, + fakeWalletClient, ); expect(context).toBeDefined(); diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index 7704212e8..3426725b2 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -1,6 +1,6 @@ import { initialize } from '@nucypher/nucypher-core'; -import { fakeProvider, fakeSigner } from '@nucypher/test-utils'; -import { ethers } from 'ethers'; +import { fakePublicClient, fakeWalletClient } from '@nucypher/test-utils'; +import { mockViemActions } from '@nucypher/test-utils'; import { beforeAll, describe, expect, it } from 'vitest'; import { toBytes, toHexString } from '../../src'; @@ -22,14 +22,11 @@ import { testRpcConditionObj, } from '../test-utils'; -describe('context', () => { - let provider: ethers.providers.Provider; - let signer: ethers.Signer; +mockViemActions(); +describe('context', () => { beforeAll(async () => { await initialize(); - provider = fakeProvider(); - signer = fakeSigner(); }); describe('serialization', () => { @@ -44,7 +41,7 @@ describe('context', () => { }); const conditionContext = new ConditionExpression( rpcCondition, - ).buildContext(provider, {}, signer); + ).buildContext(fakePublicClient, {}, fakeWalletClient); const asJson = await conditionContext.toJson(); expect(asJson).toBeDefined(); @@ -66,7 +63,11 @@ describe('context', () => { }; const contractCondition = new ContractCondition(contractConditionObj); const conditionExpr = new ConditionExpression(contractCondition); - const context = conditionExpr.buildContext(provider, {}, signer); + const context = conditionExpr.buildContext( + fakePublicClient, + {}, + fakeWalletClient, + ); describe('custom parameters', () => { it('serializes bytes as hex strings', async () => { @@ -133,8 +134,10 @@ describe('context', () => { const condition = new ContractCondition(conditionObj); const conditionExpr = new ConditionExpression(condition); expect(conditionExpr.contextRequiresSigner()).toBe(true); - expect(conditionExpr.buildContext(provider, {}, signer)).toBeDefined(); - expect(() => conditionExpr.buildContext(provider, {})).toThrow( + expect( + conditionExpr.buildContext(fakePublicClient, {}, fakeWalletClient), + ).toBeDefined(); + expect(() => conditionExpr.buildContext(fakePublicClient, {})).toThrow( `Signer required to satisfy ${USER_ADDRESS_PARAM} context variable in condition`, ); }); @@ -153,8 +156,10 @@ describe('context', () => { const condition = new ContractCondition(conditionObj); const conditionExpr = new ConditionExpression(condition); expect(conditionExpr.contextRequiresSigner()).toBe(true); - expect(conditionExpr.buildContext(provider, {}, signer)).toBeDefined(); - expect(() => conditionExpr.buildContext(provider, {})).toThrow( + expect( + conditionExpr.buildContext(fakePublicClient, {}, fakeWalletClient), + ).toBeDefined(); + expect(() => conditionExpr.buildContext(fakePublicClient, {})).toThrow( `Signer required to satisfy ${USER_ADDRESS_PARAM} context variable in condition`, ); }); @@ -166,8 +171,10 @@ describe('context', () => { JSON.stringify(condition.toObj()).includes(USER_ADDRESS_PARAM), ).toBe(false); expect(conditionExpr.contextRequiresSigner()).toBe(false); - expect(conditionExpr.buildContext(provider, {}, signer)).toBeDefined(); - expect(conditionExpr.buildContext(provider, {})).toBeDefined(); + expect( + conditionExpr.buildContext(fakePublicClient, {}, fakeWalletClient), + ).toBeDefined(); + expect(conditionExpr.buildContext(fakePublicClient, {})).toBeDefined(); }); it('rejects on a missing signer', () => { @@ -181,7 +188,9 @@ describe('context', () => { const condition = new ContractCondition(conditionObj); const conditionExpr = new ConditionExpression(condition); expect(conditionExpr.contextRequiresSigner()).toBe(true); - expect(() => conditionExpr.buildContext(provider, {}, undefined)).toThrow( + expect(() => + conditionExpr.buildContext(fakePublicClient, {}, undefined), + ).toThrow( `Signer required to satisfy ${USER_ADDRESS_PARAM} context variable in condition`, ); }); @@ -197,7 +206,9 @@ describe('context', () => { const condition = new ContractCondition(conditionObj); const conditionExpr = new ConditionExpression(condition); expect(conditionExpr.contextRequiresSigner()).toBe(true); - expect(() => conditionExpr.buildContext(provider, {}, undefined)).toThrow( + expect(() => + conditionExpr.buildContext(fakePublicClient, {}, undefined), + ).toThrow( `Signer required to satisfy ${USER_ADDRESS_PARAM} context variable in condition`, ); }); @@ -221,7 +232,7 @@ describe('context', () => { }); const conditionContext = new ConditionExpression( customContractCondition, - ).buildContext(provider, {}, signer); + ).buildContext(fakePublicClient, {}, fakeWalletClient); await expect(async () => conditionContext.toObj()).rejects.toThrow( `Missing custom context parameter(s): ${customParamKey}`, @@ -235,7 +246,7 @@ describe('context', () => { }); const conditionContext = new ConditionExpression( customContractCondition, - ).buildContext(provider, {}, signer); + ).buildContext(fakePublicClient, {}, fakeWalletClient); const asObj = await conditionContext.toObj(); expect(asObj).toBeDefined(); @@ -254,7 +265,7 @@ describe('context', () => { customParameters[customParamKey] = falsyParam; const conditionContext = new ConditionExpression( customContractCondition, - ).buildContext(provider, customParameters, signer); + ).buildContext(fakePublicClient, customParameters, fakeWalletClient); const asObj = await conditionContext.toObj(); expect(asObj).toBeDefined(); diff --git a/packages/taco/test/dkg-client.test.ts b/packages/taco/test/dkg-client.test.ts index e843c5461..379c271d3 100644 --- a/packages/taco/test/dkg-client.test.ts +++ b/packages/taco/test/dkg-client.test.ts @@ -1,5 +1,5 @@ import { DkgCoordinatorAgent } from '@nucypher/shared'; -import { fakeProvider } from '@nucypher/test-utils'; +import { fakePublicClient } from '@nucypher/test-utils'; import { beforeAll, describe, expect, it } from 'vitest'; import { domains, initialize } from '../src'; @@ -17,10 +17,9 @@ describe('DkgCoordinatorAgent', () => { }); it('fetches transcripts from the coordinator', async () => { - const provider = fakeProvider(); const getRitualSpy = mockGetRitual(); const ritual = await DkgCoordinatorAgent.getRitual( - provider, + fakePublicClient, domains.TEST_DOMAIN, fakeRitualId, ); @@ -29,12 +28,11 @@ describe('DkgCoordinatorAgent', () => { }); it('fetches participants from the coordinator', async () => { - const provider = fakeProvider(); const getParticipantsSpy = mockGetParticipants( (await mockDkgParticipants(fakeRitualId)).participants, ); const participants = await DkgCoordinatorAgent.getParticipants( - provider, + fakePublicClient, domains.TEST_DOMAIN, fakeRitualId, ); @@ -48,7 +46,7 @@ describe('DkgCoordinatorAgent', () => { // it('verifies the dkg ritual', async () => { // const provider = fakeWeb3Provider(SecretKey.random().toBEBytes()); // -// const dkgClient = new DkgClient(provider); +// const dkgClient = new DkgClient(fakePublicClient); // const isValid = await dkgClient.verifyRitual(fakeRitualId); // expect(isValid).toBeTruthy(); // }); diff --git a/packages/taco/test/taco.test.ts b/packages/taco/test/taco.test.ts index 398398c7a..606a1172d 100644 --- a/packages/taco/test/taco.test.ts +++ b/packages/taco/test/taco.test.ts @@ -4,15 +4,15 @@ import { SessionStaticSecret, } from '@nucypher/nucypher-core'; import { - aliceSecretKeyBytes, fakeDkgFlow, fakePorterUri, - fakeProvider, - fakeSigner, + fakePublicClient, fakeTDecFlow, + fakeWalletClient, mockGetRitualIdFromPublicKey, mockTacoDecrypt, } from '@nucypher/test-utils'; +import { mockViemActions } from '@nucypher/test-utils'; import { beforeAll, describe, expect, it } from 'vitest'; import * as taco from '../src'; @@ -26,6 +26,8 @@ import { mockMakeSessionKey, } from './test-utils'; +mockViemActions(); + // Shared test variables const message = 'this is a secret'; const ownsNFT = new conditions.ERC721Ownership({ @@ -42,17 +44,15 @@ describe('taco', () => { it('encrypts and decrypts', async () => { const mockedDkg = fakeDkgFlow(FerveoVariant.precomputed, 0, 4, 4); const mockedDkgRitual = fakeDkgRitual(mockedDkg); - const provider = fakeProvider(aliceSecretKeyBytes); - const signer = fakeSigner(aliceSecretKeyBytes); const getFinalizedRitualSpy = mockGetActiveRitual(mockedDkgRitual); const messageKit = await taco.encrypt( - provider, + fakePublicClient, domains.DEV, message, ownsNFT, mockedDkg.ritualId, - signer, + fakeWalletClient, ); expect(getFinalizedRitualSpy).toHaveBeenCalled(); @@ -80,11 +80,11 @@ describe('taco', () => { const getRitualSpy = mockGetActiveRitual(mockedDkgRitual); const decryptedMessage = await taco.decrypt( - provider, + fakePublicClient, domains.DEV, messageKit, fakePorterUri, - signer, + fakeWalletClient, ); expect(getParticipantsSpy).toHaveBeenCalled(); expect(sessionKeySpy).toHaveBeenCalled(); diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 0a48d1635..ffb89159d 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -33,6 +33,7 @@ "@nucypher/shared": "workspace:*", "axios": "^1.6.2", "ethers": "^5.7.2", + "viem": "^1.19.9", "vitest": "^0.34.6" }, "engines": { diff --git a/packages/test-utils/src/utils.ts b/packages/test-utils/src/utils.ts index 858adf68c..365652002 100644 --- a/packages/test-utils/src/utils.ts +++ b/packages/test-utils/src/utils.ts @@ -36,11 +36,14 @@ import { RetrieveCFragsResult, TacoDecryptResult, toHexString, + toPublicClient, Ursula, zip, } from '@nucypher/shared'; import axios from 'axios'; import { ethers, providers, Wallet } from 'ethers'; +import { createWalletClient, http, PublicClient } from 'viem'; +import { polygonMumbai } from 'viem/chains'; import { expect, SpyInstance, vi } from 'vitest'; export const bytesEqual = (first: Uint8Array, second: Uint8Array): boolean => @@ -78,22 +81,12 @@ export const fakeSigner = ( } as unknown as ethers.providers.JsonRpcSigner; }; -export const fakeProvider = ( - secretKeyBytes = SecretKey.random().toBEBytes(), - blockNumber = 1000, - blockTimestamp = 1000, -): ethers.providers.Web3Provider => { - const fakeProvider = makeFakeProvider(blockTimestamp, blockNumber); - const fakeSignerWithProvider = fakeSigner( - secretKeyBytes, - blockNumber, - blockTimestamp, - ); - return { - ...fakeProvider, - getSigner: () => fakeSignerWithProvider, - } as unknown as ethers.providers.Web3Provider; -}; +export const fakeWalletClient = createWalletClient({ + chain: polygonMumbai, + transport: http(), +}); + +export const fakePublicClient: PublicClient = toPublicClient(fakeWalletClient); const genChecksumAddress = (i: number): ChecksumAddress => `0x${'0'.repeat(40 - i.toString(16).length)}${i.toString( @@ -339,3 +332,20 @@ export const mockRetrieveAndDecrypt = ( encryptedMessageKit.capsule, ); }; + +export const mockViemActions = () => + vi.mock('viem/actions', () => ({ + ...vi.importActual('viem/actions'), + getBlock: vi.fn().mockResolvedValue({ + timestamp: 1000, + }), + getBlockNumber: vi.fn().mockResolvedValue(BigInt(1000)), + requestAddresses: vi + .fn() + .mockResolvedValue(['0x1234567890123456789012345678901234567890']), + signTypedData: vi + .fn() + .mockResolvedValue('0x1234567890123456789012345678901234567890'), + signMessage: vi.fn().mockResolvedValue('0x1234567890123456789012345678901234567890'), + getAccounts: vi.fn().mockResolvedValue(['0x1234567890123456789012345678901234567890']), + })); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 35d518e6c..ffab1a639 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -135,6 +135,9 @@ importers: react-spinners: specifier: ^0.13.6 version: 0.13.8(react-dom@18.2.0)(react@18.2.0) + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@4.9.5) devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.5.7 @@ -211,6 +214,9 @@ importers: react-spinners: specifier: ^0.13.6 version: 0.13.8(react-dom@18.2.0)(react@18.2.0) + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@4.9.5) devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.5.7 @@ -260,6 +266,22 @@ importers: '@nucypher/pre': specifier: workspace:* version: link:../../../packages/pre + ethers: + specifier: ^5.7.2 + version: 5.7.2 + next: + specifier: 14.0.3 + version: 14.0.3(react-dom@18.2.0)(react@18.2.0) + react: + specifier: 18.2.0 + version: 18.2.0 + react-dom: + specifier: 18.2.0 + version: 18.2.0(react@18.2.0) + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) + devDependencies: '@types/node': specifier: 20.6.3 version: 20.6.3 @@ -275,30 +297,22 @@ importers: eslint-config-next: specifier: 14.0.2 version: 14.0.2(eslint@8.53.0)(typescript@5.2.2) - ethers: - specifier: ^5.7.2 - version: 5.7.2 - next: - specifier: 14.0.3 - version: 14.0.3(react-dom@18.2.0)(react@18.2.0) - react: - specifier: 18.2.0 - version: 18.2.0 - react-dom: - specifier: 18.2.0 - version: 18.2.0(react@18.2.0) examples/pre/nodejs: dependencies: '@nucypher/pre': specifier: workspace:* version: link:../../../packages/pre - dotenv: - specifier: ^16.3.1 - version: 16.3.1 ethers: specifier: ^5.7.2 version: 5.7.2 + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) + devDependencies: + dotenv: + specifier: ^16.3.1 + version: 16.3.1 examples/pre/react: dependencies: @@ -314,6 +328,9 @@ importers: react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) devDependencies: '@types/node': specifier: ^16.18.50 @@ -333,6 +350,9 @@ importers: '@nucypher/pre': specifier: workspace:* version: link:../../../packages/pre + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) devDependencies: copy-webpack-plugin: specifier: ^11.0.0 @@ -361,6 +381,22 @@ importers: '@nucypher/taco': specifier: workspace:* version: link:../../../packages/taco + ethers: + specifier: ^5.7.2 + version: 5.7.2 + next: + specifier: 14.0.3 + version: 14.0.3(react-dom@18.2.0)(react@18.2.0) + react: + specifier: 18.2.0 + version: 18.2.0 + react-dom: + specifier: 18.2.0 + version: 18.2.0(react@18.2.0) + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) + devDependencies: '@types/node': specifier: 20.6.3 version: 20.6.3 @@ -376,33 +412,22 @@ importers: eslint-config-next: specifier: 14.0.2 version: 14.0.2(eslint@8.53.0)(typescript@5.2.2) - ethers: - specifier: ^5.7.2 - version: 5.7.2 - next: - specifier: 14.0.3 - version: 14.0.3(react-dom@18.2.0)(react@18.2.0) - react: - specifier: 18.2.0 - version: 18.2.0 - react-dom: - specifier: 18.2.0 - version: 18.2.0(react@18.2.0) - typescript: - specifier: 5.2.2 - version: 5.2.2 examples/taco/nodejs: dependencies: '@nucypher/taco': specifier: workspace:* version: link:../../../packages/taco - dotenv: - specifier: ^16.3.1 - version: 16.3.1 ethers: specifier: ^5.7.2 version: 5.7.2 + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) + devDependencies: + dotenv: + specifier: ^16.3.1 + version: 16.3.1 examples/taco/react: dependencies: @@ -421,6 +446,9 @@ importers: react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) devDependencies: '@types/node': specifier: ^16.18.50 @@ -443,6 +471,9 @@ importers: ethers: specifier: ^5.7.2 version: 5.7.2 + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) devDependencies: copy-webpack-plugin: specifier: ^11.0.0 @@ -471,6 +502,9 @@ importers: ethers: specifier: ^5.7.2 version: 5.7.2 + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) devDependencies: '@nucypher/test-utils': specifier: workspace:* @@ -502,6 +536,9 @@ importers: qs: specifier: ^6.10.1 version: 6.11.2 + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) devDependencies: '@typechain/ethers-v5': specifier: ^11.1.2 @@ -542,6 +579,9 @@ importers: semver: specifier: ^7.5.2 version: 7.5.4 + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) zod: specifier: ^3.22.4 version: 3.22.4 @@ -567,6 +607,9 @@ importers: ethers: specifier: ^5.7.2 version: 5.7.2 + viem: + specifier: ^1.19.9 + version: 1.19.9(typescript@5.2.2)(zod@3.22.4) vitest: specifier: ^0.34.6 version: 0.34.6 @@ -576,6 +619,11 @@ packages: /@aashutoshrathi/word-wrap@1.2.6: resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} engines: {node: '>=0.10.0'} + dev: true + + /@adraffy/ens-normalize@1.10.0: + resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} + dev: false /@alloc/quick-lru@5.2.0: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} @@ -2813,10 +2861,12 @@ packages: dependencies: eslint: 8.53.0 eslint-visitor-keys: 3.4.3 + dev: true /@eslint-community/regexpp@4.8.1: resolution: {integrity: sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true /@eslint/eslintrc@2.1.3: resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==} @@ -2833,10 +2883,12 @@ packages: strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color + dev: true /@eslint/js@8.53.0: resolution: {integrity: sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true /@ethersproject/abi@5.7.0: resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} @@ -3132,13 +3184,16 @@ packages: minimatch: 3.1.2 transitivePeerDependencies: - supports-color + dev: true /@humanwhocodes/module-importer@1.0.1: resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} + dev: true /@humanwhocodes/object-schema@2.0.1: resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + dev: true /@hutson/parse-repository-url@3.0.2: resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} @@ -3485,7 +3540,7 @@ packages: resolution: {integrity: sha512-APrYFsXfAhnysycqxHcpg6Y4i7Ukp30GzVSZQRKT3OczbzkqGjt33vNhScmgoOXYBU1CfkwgtXmNxdiwv1jKmg==} dependencies: glob: 7.1.7 - dev: false + dev: true /@next/swc-darwin-arm64@14.0.3: resolution: {integrity: sha512-64JbSvi3nbbcEtyitNn2LEDS/hcleAFpHdykpcnrstITFlzFgB/bW0ER5/SJJwUPj+ZPY+z3e+1jAfcczRLVGw==} @@ -3574,6 +3629,17 @@ packages: eslint-scope: 5.1.1 dev: true + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + dev: false + + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + dev: false + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -3743,6 +3809,26 @@ packages: /@rushstack/eslint-patch@1.4.0: resolution: {integrity: sha512-cEjvTPU32OM9lUFegJagO0mRnIn+rbqrG89vV8/xLnLFX0DoR0r1oy5IlTga71Q7uT3Qus7qm7wgeiMT/+Irlg==} + dev: true + + /@scure/base@1.1.3: + resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} + dev: false + + /@scure/bip32@1.3.2: + resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} + dependencies: + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + dev: false + + /@scure/bip39@1.2.1: + resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} + dependencies: + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + dev: false /@sinclair/typebox@0.24.51: resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} @@ -4085,6 +4171,7 @@ packages: /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true /@types/lodash@4.14.198: resolution: {integrity: sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==} @@ -4133,6 +4220,7 @@ packages: /@types/prop-types@15.7.7: resolution: {integrity: sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog==} + dev: true /@types/q@1.5.6: resolution: {integrity: sha512-IKjZ8RjTSwD4/YG+2gtj7BPFRB/lNbWKTiSj3M7U/TD2B7HfYCxvp2Zz6xA2WIY7pAuL1QOUPw8gQRbUrrq4fQ==} @@ -4154,6 +4242,7 @@ packages: resolution: {integrity: sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==} dependencies: '@types/react': 18.2.37 + dev: true /@types/react@18.2.37: resolution: {integrity: sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==} @@ -4161,6 +4250,7 @@ packages: '@types/prop-types': 15.7.7 '@types/scheduler': 0.16.3 csstype: 3.1.2 + dev: true /@types/resolve@1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} @@ -4173,6 +4263,7 @@ packages: /@types/scheduler@0.16.3: resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} + dev: true /@types/semver@7.5.4: resolution: {integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==} @@ -4342,6 +4433,7 @@ packages: typescript: 5.2.2 transitivePeerDependencies: - supports-color + dev: true /@typescript-eslint/scope-manager@5.62.0: resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} @@ -4365,6 +4457,7 @@ packages: dependencies: '@typescript-eslint/types': 6.7.0 '@typescript-eslint/visitor-keys': 6.7.0 + dev: true /@typescript-eslint/type-utils@5.62.0(eslint@8.53.0)(typescript@5.2.2): resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} @@ -4419,6 +4512,7 @@ packages: /@typescript-eslint/types@6.7.0: resolution: {integrity: sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==} engines: {node: ^16.0.0 || >=18.0.0} + dev: true /@typescript-eslint/typescript-estree@5.62.0(typescript@5.2.2): resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} @@ -4481,6 +4575,7 @@ packages: typescript: 5.2.2 transitivePeerDependencies: - supports-color + dev: true /@typescript-eslint/utils@5.62.0(eslint@8.53.0)(typescript@5.2.2): resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} @@ -4543,9 +4638,11 @@ packages: dependencies: '@typescript-eslint/types': 6.7.0 eslint-visitor-keys: 3.4.3 + dev: true /@ungap/structured-clone@1.2.0: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true /@uniswap/token-lists@1.0.0-beta.33: resolution: {integrity: sha512-JQkXcpRI3jFG8y3/CGC4TS8NkDgcxXaOQuYW8Qdvd6DcDiIyg2vVYCG9igFEzF0G6UvxgHkBKC7cWCgzZNYvQg==} @@ -4770,6 +4867,35 @@ packages: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} dev: true + /abitype@0.9.8(typescript@4.9.5): + resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.19.1 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 4.9.5 + dev: false + + /abitype@0.9.8(typescript@5.2.2)(zod@3.22.4): + resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.19.1 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + dependencies: + typescript: 5.2.2 + zod: 3.22.4 + dev: false + /accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -4797,6 +4923,7 @@ packages: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: acorn: 8.10.0 + dev: true /acorn-walk@7.2.0: resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} @@ -4966,11 +5093,13 @@ packages: /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true /aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} dependencies: dequal: 2.0.3 + dev: true /array-back@3.1.0: resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} @@ -5007,6 +5136,7 @@ packages: es-abstract: 1.22.1 get-intrinsic: 1.2.1 is-string: 1.0.7 + dev: true /array-union@1.0.2: resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} @@ -5033,6 +5163,7 @@ packages: es-abstract: 1.22.1 es-shim-unscopables: 1.0.0 get-intrinsic: 1.2.1 + dev: true /array.prototype.flat@1.3.2: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} @@ -5051,6 +5182,7 @@ packages: define-properties: 1.2.1 es-abstract: 1.22.1 es-shim-unscopables: 1.0.0 + dev: true /array.prototype.reduce@1.0.6: resolution: {integrity: sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==} @@ -5071,6 +5203,7 @@ packages: es-abstract: 1.22.1 es-shim-unscopables: 1.0.0 get-intrinsic: 1.2.1 + dev: true /arraybuffer.prototype.slice@1.0.2: resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} @@ -5097,6 +5230,7 @@ packages: /ast-types-flow@0.0.7: resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} + dev: true /async@3.2.4: resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} @@ -5106,6 +5240,7 @@ packages: resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} dependencies: has-symbols: 1.0.3 + dev: true /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -5138,6 +5273,7 @@ packages: /axe-core@4.8.2: resolution: {integrity: sha512-/dlp0fxyM3R8YW7MFzaHWXrf4zzbr0vaYb23VBFCl83R7nWNPg/yaQw2Dc8jzCMmDVLhSdzH8MjrsuIUuvX+6g==} engines: {node: '>=4'} + dev: true /axios-retry@3.7.0: resolution: {integrity: sha512-ZTnCkJbRtfScvwiRnoVskFAfvU0UG3xNcsjwTR0mawSbIJoothxn67gKsMaNAFHRXJ1RmuLhmZBzvyXi3+9WyQ==} @@ -5159,6 +5295,7 @@ packages: resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} dependencies: dequal: 2.0.3 + dev: true /babel-jest@27.5.1(@babel/core@7.23.0): resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==} @@ -5551,6 +5688,7 @@ packages: /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + dev: true /camel-case@4.1.2: resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} @@ -6481,6 +6619,7 @@ packages: /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + dev: true /csv-generate@3.4.3: resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} @@ -6523,6 +6662,7 @@ packages: /damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + dev: true /dargs@7.0.0: resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} @@ -6561,6 +6701,7 @@ packages: optional: true dependencies: ms: 2.1.3 + dev: true /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -6628,6 +6769,7 @@ packages: /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true /deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} @@ -6680,6 +6822,7 @@ packages: /dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + dev: true /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} @@ -6765,12 +6908,14 @@ packages: engines: {node: '>=0.10.0'} dependencies: esutils: 2.0.3 + dev: true /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} dependencies: esutils: 2.0.3 + dev: true /dom-converter@0.2.0: resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==} @@ -6856,7 +7001,7 @@ packages: /dotenv@16.3.1: resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} engines: {node: '>=12'} - dev: false + dev: true /dotgitignore@2.1.0: resolution: {integrity: sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==} @@ -6922,6 +7067,7 @@ packages: /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true /emojis-list@3.0.0: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} @@ -7045,6 +7191,7 @@ packages: internal-slot: 1.0.5 iterator.prototype: 1.1.2 safe-array-concat: 1.0.1 + dev: true /es-module-lexer@1.3.1: resolution: {integrity: sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==} @@ -7162,6 +7309,7 @@ packages: /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + dev: true /escodegen@1.14.3: resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} @@ -7211,7 +7359,7 @@ packages: transitivePeerDependencies: - eslint-import-resolver-webpack - supports-color - dev: false + dev: true /eslint-config-prettier@9.0.0(eslint@8.53.0): resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==} @@ -7275,6 +7423,7 @@ packages: resolve: 1.22.4 transitivePeerDependencies: - supports-color + dev: true /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.7.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.53.0): resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} @@ -7297,6 +7446,7 @@ packages: - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color + dev: true /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint@8.53.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} @@ -7355,6 +7505,7 @@ packages: eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.7.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0)(eslint@8.53.0) transitivePeerDependencies: - supports-color + dev: true /eslint-plugin-eslint-comments@3.2.0(eslint@8.53.0): resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} @@ -7450,6 +7601,7 @@ packages: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color + dev: true /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0)(eslint@8.53.0)(jest@27.5.1)(typescript@5.2.2): resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==} @@ -7496,6 +7648,7 @@ packages: object.entries: 1.1.7 object.fromentries: 2.0.7 semver: 6.3.1 + dev: true /eslint-plugin-no-only-tests@3.1.0: resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==} @@ -7509,6 +7662,7 @@ packages: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: eslint: 8.53.0 + dev: true /eslint-plugin-react@7.33.2(eslint@8.53.0): resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} @@ -7533,6 +7687,7 @@ packages: resolve: 2.0.0-next.4 semver: 6.3.1 string.prototype.matchall: 4.0.10 + dev: true /eslint-plugin-simple-import-sort@10.0.0(eslint@8.53.0): resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} @@ -7597,6 +7752,7 @@ packages: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 + dev: true /eslint-visitor-keys@2.1.0: resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} @@ -7606,6 +7762,7 @@ packages: /eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true /eslint-webpack-plugin@3.2.0(eslint@8.53.0)(webpack@5.88.2): resolution: {integrity: sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==} @@ -7668,6 +7825,7 @@ packages: text-table: 0.2.0 transitivePeerDependencies: - supports-color + dev: true /espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} @@ -7676,6 +7834,7 @@ packages: acorn: 8.10.0 acorn-jsx: 5.3.2(acorn@8.10.0) eslint-visitor-keys: 3.4.3 + dev: true /esprima@1.2.2: resolution: {integrity: sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==} @@ -7693,6 +7852,7 @@ packages: engines: {node: '>=0.10'} dependencies: estraverse: 5.3.0 + dev: true /esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} @@ -7715,6 +7875,7 @@ packages: /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + dev: true /etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} @@ -7868,6 +8029,7 @@ packages: /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true /fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} @@ -7925,6 +8087,7 @@ packages: engines: {node: ^10.12.0 || >=12.0.0} dependencies: flat-cache: 3.1.0 + dev: true /file-loader@6.2.0(webpack@5.88.2): resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} @@ -8060,9 +8223,11 @@ packages: flatted: 3.2.7 keyv: 4.5.3 rimraf: 3.0.2 + dev: true /flatted@3.2.7: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + dev: true /follow-redirects@1.15.2: resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} @@ -8281,6 +8446,7 @@ packages: resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} dependencies: resolve-pkg-maps: 1.0.0 + dev: true /gh-pages@6.0.0: resolution: {integrity: sha512-FXZWJRsvP/fK2HJGY+Di6FRNHvqFF6gOIELaopDjXXgjeOYSNURcuYwEO/6bwuq6koP5Lnkvnr5GViXzuOB89g==} @@ -8346,6 +8512,7 @@ packages: engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 + dev: true /glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} @@ -8382,6 +8549,7 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 + dev: true /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} @@ -8447,6 +8615,7 @@ packages: engines: {node: '>=8'} dependencies: type-fest: 0.20.2 + dev: true /globalthis@1.0.3: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} @@ -8501,6 +8670,7 @@ packages: /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true /gzip-size@6.0.0: resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} @@ -8806,6 +8976,7 @@ packages: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 + dev: true /import-local@3.1.0: resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} @@ -8818,6 +8989,7 @@ packages: /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + dev: true /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} @@ -8903,6 +9075,7 @@ packages: engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 + dev: true /is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} @@ -8957,6 +9130,7 @@ packages: resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} dependencies: call-bind: 1.0.2 + dev: true /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} @@ -8972,6 +9146,7 @@ packages: engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 + dev: true /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} @@ -9018,6 +9193,7 @@ packages: /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + dev: true /is-plain-obj@1.1.0: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} @@ -9162,6 +9338,14 @@ packages: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} + /isows@1.0.3(ws@8.13.0): + resolution: {integrity: sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==} + peerDependencies: + ws: '*' + dependencies: + ws: 8.13.0 + dev: false + /istanbul-lib-coverage@3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} @@ -9216,6 +9400,7 @@ packages: has-symbols: 1.0.3 reflect.getprototypeof: 1.0.4 set-function-name: 2.0.1 + dev: true /jackspeak@2.3.6: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} @@ -9811,6 +9996,7 @@ packages: hasBin: true dependencies: argparse: 2.0.1 + dev: true /jsdom@16.7.0: resolution: {integrity: sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==} @@ -9866,6 +10052,7 @@ packages: /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true /json-parse-better-errors@1.0.2: resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} @@ -9887,6 +10074,7 @@ packages: /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} @@ -9897,6 +10085,7 @@ packages: hasBin: true dependencies: minimist: 1.2.8 + dev: true /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} @@ -9945,11 +10134,13 @@ packages: array.prototype.flat: 1.3.2 object.assign: 4.1.4 object.values: 1.1.7 + dev: true /keyv@4.5.3: resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==} dependencies: json-buffer: 3.0.1 + dev: true /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} @@ -9971,11 +10162,13 @@ packages: /language-subtag-registry@0.3.22: resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} + dev: true /language-tags@1.0.5: resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==} dependencies: language-subtag-registry: 0.3.22 + dev: true /launch-editor@2.6.0: resolution: {integrity: sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==} @@ -10002,6 +10195,7 @@ packages: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 + dev: true /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} @@ -10404,6 +10598,7 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true /minipass@7.0.4: resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} @@ -10490,6 +10685,7 @@ packages: /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true /negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} @@ -10663,6 +10859,7 @@ packages: call-bind: 1.0.2 define-properties: 1.2.1 es-abstract: 1.22.1 + dev: true /object.fromentries@2.0.7: resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} @@ -10671,6 +10868,7 @@ packages: call-bind: 1.0.2 define-properties: 1.2.1 es-abstract: 1.22.1 + dev: true /object.getownpropertydescriptors@2.1.7: resolution: {integrity: sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g==} @@ -10690,12 +10888,14 @@ packages: define-properties: 1.2.1 es-abstract: 1.22.1 get-intrinsic: 1.2.1 + dev: true /object.hasown@1.1.3: resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==} dependencies: define-properties: 1.2.1 es-abstract: 1.22.1 + dev: true /object.values@1.1.7: resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} @@ -10704,6 +10904,7 @@ packages: call-bind: 1.0.2 define-properties: 1.2.1 es-abstract: 1.22.1 + dev: true /obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} @@ -10759,6 +10960,7 @@ packages: levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 + dev: true /ora@5.4.1: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} @@ -10874,6 +11076,7 @@ packages: engines: {node: '>=6'} dependencies: callsites: 3.1.0 + dev: true /parse-json@4.0.0: resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} @@ -11846,6 +12049,7 @@ packages: /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + dev: true /prettier-plugin-organize-imports@3.2.4(prettier@3.1.0)(typescript@5.2.2): resolution: {integrity: sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==} @@ -12346,6 +12550,7 @@ packages: get-intrinsic: 1.2.1 globalthis: 1.0.3 which-builtin-type: 1.1.3 + dev: true /regenerate-unicode-properties@10.1.1: resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} @@ -12459,6 +12664,7 @@ packages: /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + dev: true /resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} @@ -12476,6 +12682,7 @@ packages: /resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true /resolve-url-loader@4.0.0: resolution: {integrity: sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==} @@ -12516,6 +12723,7 @@ packages: is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + dev: true /restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} @@ -13149,6 +13357,7 @@ packages: regexp.prototype.flags: 1.5.1 set-function-name: 2.0.1 side-channel: 1.0.4 + dev: true /string.prototype.padend@3.1.5: resolution: {integrity: sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==} @@ -13245,6 +13454,7 @@ packages: /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + dev: true /strip-literal@1.3.0: resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} @@ -13509,6 +13719,7 @@ packages: /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true /thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} @@ -13637,6 +13848,7 @@ packages: optional: true dependencies: typescript: 5.2.2 + dev: true /ts-command-line-args@2.5.1: resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} @@ -13719,6 +13931,7 @@ packages: json5: 1.0.2 minimist: 1.2.8 strip-bom: 3.0.0 + dev: true /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -13766,6 +13979,7 @@ packages: engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.2.1 + dev: true /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} @@ -13789,6 +14003,7 @@ packages: /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} + dev: true /type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} @@ -13924,7 +14139,6 @@ packages: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} hasBin: true - dev: true /typescript@5.2.2: resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} @@ -14099,6 +14313,52 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + /viem@1.19.9(typescript@4.9.5): + resolution: {integrity: sha512-Sf9U2x4jU0S/FALqYypcspWOGene0NZyD470oUripNhE0Ta6uOE/OgE4toTDVfRxov8qw0JFinr/wPGxYE3+HQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 0.9.8(typescript@4.9.5) + isows: 1.0.3(ws@8.13.0) + typescript: 4.9.5 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + dev: false + + /viem@1.19.9(typescript@5.2.2)(zod@3.22.4): + resolution: {integrity: sha512-Sf9U2x4jU0S/FALqYypcspWOGene0NZyD470oUripNhE0Ta6uOE/OgE4toTDVfRxov8qw0JFinr/wPGxYE3+HQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 0.9.8(typescript@5.2.2)(zod@3.22.4) + isows: 1.0.3(ws@8.13.0) + typescript: 5.2.2 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + dev: false + /vite-node@0.34.6(@types/node@20.6.3): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} engines: {node: '>=v14.18.0'} @@ -14527,6 +14787,7 @@ packages: which-boxed-primitive: 1.0.2 which-collection: 1.0.1 which-typed-array: 1.1.11 + dev: true /which-collection@1.0.1: resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} @@ -14813,6 +15074,19 @@ packages: utf-8-validate: optional: true + /ws@8.13.0: + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /ws@8.14.2: resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} engines: {node: '>=10.0.0'}